{"id":13484886,"url":"https://github.com/carbon-design-system/sveld","last_synced_at":"2026-04-08T03:01:00.374Z","repository":{"id":37960740,"uuid":"313380298","full_name":"carbon-design-system/sveld","owner":"carbon-design-system","description":"Generate TypeScript definitions and component documentation for your Svelte components","archived":false,"fork":false,"pushed_at":"2026-03-30T16:24:58.000Z","size":2537,"stargazers_count":443,"open_issues_count":1,"forks_count":22,"subscribers_count":4,"default_branch":"main","last_synced_at":"2026-04-03T03:57:28.965Z","etag":null,"topics":["docgen","documentation","jsdoc","svelte","svelte-component","typescript-definitions"],"latest_commit_sha":null,"homepage":"https://sveld.onrender.com","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/carbon-design-system.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"metonym"}},"created_at":"2020-11-16T17:40:13.000Z","updated_at":"2026-03-30T16:25:03.000Z","dependencies_parsed_at":"2026-04-02T18:02:09.558Z","dependency_job_id":null,"html_url":"https://github.com/carbon-design-system/sveld","commit_stats":{"total_commits":155,"total_committers":12,"mean_commits":"12.916666666666666","dds":0.07741935483870965,"last_synced_commit":"78d3a7950c6f15fbf01d824153668bde44c6f34b"},"previous_names":["ibm/sveld"],"tags_count":98,"template":false,"template_full_name":null,"purl":"pkg:github/carbon-design-system/sveld","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carbon-design-system%2Fsveld","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carbon-design-system%2Fsveld/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carbon-design-system%2Fsveld/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carbon-design-system%2Fsveld/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/carbon-design-system","download_url":"https://codeload.github.com/carbon-design-system/sveld/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/carbon-design-system%2Fsveld/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31537791,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-07T16:28:08.000Z","status":"online","status_checked_at":"2026-04-08T02:00:06.127Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docgen","documentation","jsdoc","svelte","svelte-component","typescript-definitions"],"created_at":"2024-07-31T17:01:37.632Z","updated_at":"2026-04-08T03:01:00.363Z","avatar_url":"https://github.com/carbon-design-system.png","language":"TypeScript","funding_links":["https://github.com/sponsors/metonym"],"categories":["Svelte"],"sub_categories":[],"readme":"# sveld\n\n[![NPM][npm]][npm-url]\n![npm downloads to date](https://img.shields.io/npm/dt/sveld?color=262626\u0026style=for-the-badge)\n\n`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/).\n\nThe 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.\n\n[Carbon Components Svelte](https://github.com/carbon-design-system/carbon-components-svelte) uses this library to auto-generate component types and API metadata.\n\n`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`, `\u003cslot\u003e`, `$$restProps`, …), and Svelte 5 Runes (`$props()`, `$bindable()`, `{@render ...}`, callback props such as `onclick`, …).\n\nFor `lang=\"ts\"` components, `sveld` preserves source-level prop type annotations when possible instead of requiring JSDoc as the primary source of truth. This includes 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.\n\n| Syntax mode          | Supported |\n| :------------------- | :-------: |\n| Svelte 3             |     ✓     |\n| Svelte 4             |     ✓     |\n| Svelte 5 (non-Runes) |     ✓     |\n| Svelte 5 Runes       |     ✓     |\n\n**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.\n\n---\n\nGiven a Svelte component, `sveld` can infer basic prop types to generate TypeScript definitions compatible with the [Svelte Language Server](https://github.com/sveltejs/language-tools):\n\n**Button.svelte**\n\n```svelte\n\u003cscript\u003e\n  export let type = \"button\";\n  export let primary = false;\n\u003c/script\u003e\n\n\u003cbutton {...$$restProps} {type} class:primary on:click\u003e\n  \u003cslot\u003eClick me\u003c/slot\u003e\n\u003c/button\u003e\n```\n\nThe following generated `.d.ts` extends `SvelteComponentTyped`:\n\n**Button.svelte.d.ts**\n\n```ts\nimport { SvelteComponentTyped } from \"svelte\";\nimport type { SvelteHTMLElements } from \"svelte/elements\";\n\ntype $RestProps = SvelteHTMLElements[\"button\"];\n\ntype $Props = {\n  /**\n   * @default \"button\"\n   */\n  type?: string;\n\n  /**\n   * @default false\n   */\n  primary?: boolean;\n\n  [key: `data-${string}`]: unknown;\n};\n\nexport type ButtonProps = Omit\u003c$RestProps, keyof $Props\u003e \u0026 $Props;\n\nexport default class Button extends SvelteComponentTyped\u003c\n  ButtonProps,\n  { click: WindowEventMap[\"click\"] },\n  { default: Record\u003cstring, never\u003e }\n\u003e {}\n```\n\nSometimes, inferring prop types is insufficient.\n\nProp/event/slot types and signatures can be augmented using [JSDoc](https://jsdoc.app/) notations.\n\n```js\n/** @type {\"button\" | \"submit\" | \"reset\"} */\nexport let type = \"button\";\n\n/**\n * Set to `true` to use the primary variant\n */\nexport let primary = false;\n```\n\nThe accompanying JSDoc annotations would generate the following:\n\n```ts\nimport type { SvelteHTMLElements } from \"svelte/elements\";\n\ntype $RestProps = SvelteHTMLElements[\"button\"];\n\ntype $Props = {\n  /**\n   * @default \"button\"\n   */\n  type?: \"button\" | \"submit\" | \"reset\";\n\n  /**\n   * Set to `true` to use the primary variant\n   * @default false\n   */\n  primary?: boolean;\n};\n\nexport type ButtonProps = Omit\u003c$RestProps, keyof $Props\u003e \u0026 $Props;\n\nexport default class Button extends SvelteComponentTyped\u003c\n  ButtonProps,\n  { click: WindowEventMap[\"click\"] },\n  { default: Record\u003cstring, never\u003e }\n\u003e {}\n```\n\n---\n\n## Table of Contents\n\n- [Approach](#approach)\n- [Usage](#usage)\n  - [Installation](#installation)\n  - [Vite](#vite)\n  - [Node.js](#nodejs)\n  - [CLI](#cli)\n  - [Publishing to NPM](#publishing-to-npm)\n- [Available Options](#available-options)\n- [API Reference](#api-reference)\n  - [@type](#type)\n  - [@default](#default)\n  - [@typedef](#typedef)\n  - [@callback](#callback)\n  - [@slot / @snippet](#slot--snippet)\n    - [Svelte 5 Snippet Compatibility](#svelte-5-snippet-compatibility)\n  - [@event](#event)\n  - [Context API](#context-api)\n  - [@restProps](#restprops)\n  - [@extendProps](#extendprops)\n  - [@generics](#generics)\n  - [@component comments](#component-comments)\n  - [Accessor Props](#accessor-props)\n- [Contributing](#contributing)\n- [License](#license)\n\n## Approach\n\n`sveld` uses the Svelte compiler to statically analyze Svelte components exported from a library to generate documentation useful to the end user.\n\nExtracted metadata include:\n\n- props\n- slots\n- forwarded events\n- dispatched events\n- context (setContext/getContext)\n- `$$restProps`\n\nThis library adopts a progressively enhanced approach. Any property type that cannot be inferred (e.g., \"hello\" is a string) falls back to \"any\" to minimize incorrectly typed properties or signatures. To mitigate this, the library author can add JSDoc annotations to specify types that cannot be reliably inferred. This represents a progressively enhanced approach because JSDocs are comments that can be ignored by the compiler.\n\nWhen both TypeScript syntax and JSDoc are present, `sveld` resolves prop types in this order:\n\n1. explicit TypeScript annotation\n2. explicit JSDoc annotation\n3. initializer inference\n4. `any`\n\n`sveld` intentionally stays AST-only. It preserves imported and local type text in generated `.d.ts` output, but it does not perform project-wide semantic resolution with the TypeScript compiler. That means opaque imported whole-object `$props()` types can be preserved in declarations without being fully expanded into JSON metadata.\n\n## Usage\n\n### Installation\n\nInstall `sveld` as a development dependency.\n\n```sh\n# npm\nnpm i -D sveld\n\n# pnpm\npnpm i -D sveld\n\n# Bun\nbun i -D sveld\n\n# Yarn\nyarn add -D sveld\n```\n\n### Vite\n\nImport and add `sveld` as a plugin to your `vite.config.ts`. The plugin only runs during `vite build` (not the dev server).\n\n```ts\n// vite.config.ts\nimport { svelte } from \"@sveltejs/vite-plugin-svelte\";\nimport sveld from \"sveld\";\nimport { defineConfig } from \"vite\";\n\nexport default defineConfig({\n  plugins: [svelte(), sveld()],\n});\n```\n\nSince Vite uses Rollup for production builds, `sveld` also works in Rollup configurations.\n\nBy default, `sveld` will use the `\"svelte\"` field from your `package.json` to determine the entry point. You can override this by specifying an explicit `entry` option:\n\n```js\nsveld({\n  entry: \"src/index.js\",\n});\n```\n\nWhen building the library, TypeScript definitions are emitted to the `types` folder by default.\n\nCustomize the output folder using the `typesOptions.outDir` option.\nUse `typesOptions.printWidth` to control Prettier wrapping for generated `.d.ts` files. The default is `80`.\n\nThe following example emits the output to the `dist` folder:\n\n```diff\nsveld({\n+  typesOptions: {\n+    outDir: 'dist',\n+    printWidth: 80\n+  }\n})\n```\n\n### CLI\n\nThe CLI uses the `\"svelte\"` field from your `package.json` as the entry point:\n\n```sh\nnpx sveld\n```\n\nGenerate documentation in JSON and/or Markdown formats using the following flags:\n\n```sh\nnpx sveld --json --markdown\n```\n\n### Node.js\n\nYou can also use `sveld` programmatically in Node.js. The package is **ESM-only**; `require(\"sveld\")` is not supported. Use `import` or dynamic `import()`.\n\nIf no `input` is specified, `sveld` will infer the entry point based on the `package.json#svelte` field.\n\n```js\nimport { sveld } from \"sveld\";\nimport pkg from \"./package.json\" with { type: \"json\" };\n\nsveld({\n  input: \"./src/index.js\",\n  glob: true,\n  markdown: true,\n  markdownOptions: {\n    onAppend: (type, document, components) =\u003e {\n      if (type === \"h1\")\n        document.append(\n          \"quote\",\n          `${components.size} components exported from ${pkg.name}@${pkg.version}.`,\n        );\n    },\n  },\n  json: true,\n  jsonOptions: {\n    outFile: \"docs/src/COMPONENT_API.json\",\n  },\n});\n```\n\n#### `jsonOptions.outDir`\n\nIf `json` is `true`, a `COMPONENT_API.json` file will be generated at the root of your project. This file contains documentation for all components.\n\nUse the `jsonOptions.outDir` option to specify the folder for individual JSON files to be emitted.\n\n```js\nsveld({\n  json: true,\n  jsonOptions: {\n    // an individual JSON file will be generated for each component API\n    // e.g. \"docs/Button.api.json\"\n    outDir: \"docs\",\n  },\n});\n```\n\n### Publishing to NPM\n\nTypeScript definitions are outputted to the `types` folder by default. Don't forget to include the folder in your `package.json` when publishing the package to NPM.\n\n```diff\n{\n  \"svelte\": \"./src/index.js\",\n  \"main\": \"./lib/index.mjs\",\n+ \"types\": \"./types/index.d.ts\",\n  \"files\": [\n    \"src\",\n    \"lib\",\n+   \"types\",\n  ]\n}\n```\n\n## Available Options\n\n### Plugin Options\n\n- **`entry`** (string, optional): Specify the entry point to uncompiled Svelte source. If not provided, sveld will use the `\"svelte\"` field from `package.json`.\n- **`glob`** (boolean, optional): Enable glob mode to analyze all `*.svelte` files.\n- **`types`** (boolean, optional, default: `true`): Generate TypeScript definitions.\n- **`typesOptions`** (object, optional): Options for TypeScript definition generation, including `outDir`, `preamble`, and `printWidth`.\n- **`json`** (boolean, optional): Generate component documentation in JSON format.\n- **`jsonOptions`** (object, optional): Options for JSON output.\n- **`markdown`** (boolean, optional): Generate component documentation in Markdown format.\n- **`markdownOptions`** (object, optional): Options for Markdown output.\n\nBy default, only TypeScript definitions are generated.\n\nTo generate documentation in Markdown and JSON formats, set `markdown` and `json` to `true`.\n\n```diff\nsveld({\n+  markdown: true,\n+  json: true,\n})\n```\n\n## API Reference\n\n### `reactive`\n\nThe `reactive` field in generated JSON is heuristic metadata. It is not a complete statement of whether a parent may use `bind:prop` in Svelte.\n\n`sveld` marks `reactive: true` when it finds internal evidence that a prop is writable, including:\n\n- the prop is assigned or mutated inside the component\n- the prop is marked bindable in runes mode with `$bindable(...)`\n- the prop is used as the target of `bind:*` on an element or child component\n- wrapper-forwarded bindings such as `bind:value`, `bind:selected`, and `bind:ref`\n\nLocal variables or parameters that shadow a prop name do not count as writes to the exported prop.\n\n`reactive: false` means `sveld` found no such evidence. It does not imply that parent-side `bind:` usage is impossible.\n\nFor stable output, generated `events` arrays are emitted in deterministic sorted order.\n\n### `@type`\n\nWithout a `@type` annotation, `sveld` will infer the primitive type for a prop:\n\n```js\nexport let kind = \"primary\";\n// inferred type: \"string\"\n```\n\nFor template literal default values, `sveld` infers the type as `string`:\n\n```js\nexport let id = `ccs-${Math.random().toString(36)}`;\n// inferred type: \"string\"\n```\n\nUse the `@type` tag to explicitly document the type. In the following example, the `kind` property has an enumerated (enum) type.\n\nFor `lang=\"ts\"` components, prefer native TypeScript annotations when they are already present. `@type` remains useful for JavaScript components, for overriding inferred types, and for cases where the AST cannot recover a more precise type.\n\n**Signature:**\n\n```js\n/**\n * Optional description\n * @type {Type}\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  let {\n    /**\n     * Specify the kind of button\n     * @type {\"primary\" | \"secondary\" | \"tertiary\"}\n     */\n    kind = \"primary\",\n    /**\n     * Specify the Carbon icon to render\n     * @type {typeof import(\"carbon-icons-svelte\").CarbonIcon}\n     */\n    renderIcon = Close20,\n  } = $props();\n\u003c/script\u003e\n```\n\nFor runes components with multiple destructured props, place JSDoc on the individual property you want to document. A declaration-level JSDoc block is only used as a fallback when the destructure exposes a single public prop.\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Specify the kind of button\n   * @type {\"primary\" | \"secondary\" | \"tertiary\"}\n   */\n  export let kind = \"primary\";\n\n  /**\n   * Specify the Carbon icon to render\n   * @type {typeof import(\"carbon-icons-svelte\").CarbonIcon}\n   */\n  export let renderIcon = Close20;\n\u003c/script\u003e\n```\n\n### `@default`\n\nBy default, `sveld` infers the `@default` value from the prop's initializer and includes it in the generated TypeScript definitions:\n\n```svelte\n\u003cscript\u003e\n  export let open = false;\n\u003c/script\u003e\n```\n\n```ts\n/**\n * @default false\n */\nopen?: boolean;\n```\n\nUse the `@default` tag to explicitly document the default value. When an explicit `@default` annotation is provided, `sveld` uses it instead of the inferred value, avoiding duplicate `@default` tags in the output.\n\nThis is useful when the initializer references a variable or expression that is not meaningful to consumers:\n\n```svelte\n\u003cscript\u003e\n  const defaultFilter = () =\u003e true;\n\n  /**\n   * @default () =\u003e true\n   * @type {(item: string, value: string) =\u003e boolean}\n   */\n  export let shouldFilter = defaultFilter;\n\u003c/script\u003e\n```\n\n```ts\n/**\n * @default () =\u003e true\n */\nshouldFilter?: (item: string, value: string) =\u003e boolean;\n```\n\n#### Identifier resolution\n\nWhen a prop's initializer is a variable reference, `sveld` resolves it to the actual value automatically:\n\n```svelte\n\u003cscript\u003e\n  const DEFAULT_SIZE = \"md\";\n\n  /** @type {\"sm\" | \"md\" | \"lg\"} */\n  export let size = DEFAULT_SIZE;\n\u003c/script\u003e\n```\n\n```ts\n/**\n * @default \"md\"\n */\nsize?: \"sm\" | \"md\" | \"lg\";\n```\n\nChained references are also resolved:\n\n```svelte\n\u003cscript\u003e\n  const ACTUAL_VALUE = 42;\n  const ALIAS = ACTUAL_VALUE;\n\n  export let count = ALIAS;\n\u003c/script\u003e\n```\n\n```ts\n/**\n * @default 42\n */\ncount?: number;\n```\n\nResolution follows up to 5 levels of indirection. Beyond that, the last resolved identifier name is used as the default value. If the identifier cannot be resolved (e.g., it is imported from another module), the variable name is used as-is.\n\nWhen an explicit `@default` annotation is provided, it always takes precedence over the resolved value.\n\n### `@typedef`\n\nThe `@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.\n\n**Signature:**\n\n```js\n/**\n * @typedef {Type} TypeName\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @typedef {string} AuthorName\n   * @typedef {{ name?: AuthorName; dob?: string; }} Author\n   */\n\n  let {\n    /** @type {Author} */\n    author = {},\n    /** @type {Author[]} */\n    authors = [],\n  } = $props();\n\u003c/script\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @typedef {string} AuthorName\n   * @typedef {{ name?: AuthorName; dob?: string; }} Author\n   */\n\n  /** @type {Author} */\n  export let author = {};\n\n  /** @type {Author[]} */\n  export let authors = [];\n\u003c/script\u003e\n```\n\n#### Using `@property` for complex typedefs\n\nFor complex object types, use the `@property` tag to document individual properties. This provides better documentation and IDE support with per-property tooltips.\n\n**Signature:**\n\n```js\n/**\n * Type description\n * @typedef {object} TypeName\n * @property {Type} propertyName - Property description\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Represents a user in the system\n   * @typedef {object} User\n   * @property {string} name - The user's full name\n   * @property {string} email - The user's email address\n   * @property {number} age - The user's age in years\n   */\n\n  /** @type {User} */\n  let { user = { name: \"John\", email: \"john@example.com\", age: 30 } } = $props();\n\u003c/script\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Represents a user in the system\n   * @typedef {object} User\n   * @property {string} name - The user's full name\n   * @property {string} email - The user's email address\n   * @property {number} age - The user's age in years\n   */\n\n  /** @type {User} */\n  export let user = { name: \"John\", email: \"john@example.com\", age: 30 };\n\u003c/script\u003e\n```\n\nOutput:\n\n```ts\nexport type User = {\n  /** The user's full name */\n  name: string;\n  /** The user's email address */\n  email: string;\n  /** The user's age in years */\n  age: number;\n};\n\nexport type ComponentProps = {\n  /**\n   * Represents a user in the system\n   * @default { name: \"John\", email: \"john@example.com\", age: 30 }\n   */\n  user?: User;\n};\n```\n\n#### Optional properties and default values\n\nFollowing JSDoc standards, use square brackets to mark properties as optional. You can also specify default values using the `[propertyName=defaultValue]` syntax.\n\n**Signature:**\n\n```js\n/**\n * @typedef {object} TypeName\n * @property {Type} [optionalProperty] - Optional property description\n * @property {Type} [propertyWithDefault=defaultValue] - Property with default value\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Configuration options for the component\n   * @typedef {object} ComponentConfig\n   * @property {boolean} enabled - Whether the component is enabled\n   * @property {string} theme - The component theme\n   * @property {number} [timeout=5000] - Optional timeout in milliseconds\n   * @property {boolean} [debug] - Optional debug mode flag\n   */\n\n  /** @type {ComponentConfig} */\n  let { config = { enabled: true, theme: \"dark\" } } = $props();\n\u003c/script\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Configuration options for the component\n   * @typedef {object} ComponentConfig\n   * @property {boolean} enabled - Whether the component is enabled\n   * @property {string} theme - The component theme\n   * @property {number} [timeout=5000] - Optional timeout in milliseconds\n   * @property {boolean} [debug] - Optional debug mode flag\n   */\n\n  /** @type {ComponentConfig} */\n  export let config = { enabled: true, theme: \"dark\" };\n\u003c/script\u003e\n```\n\nOutput:\n\n```ts\nexport type ComponentConfig = {\n  /** Whether the component is enabled */\n  enabled: boolean;\n  /** The component theme */\n  theme: string;\n  /** Optional timeout in milliseconds @default 5000 */\n  timeout?: number;\n  /** Optional debug mode flag */\n  debug?: boolean;\n};\n\nexport type ComponentProps = {\n  /**\n   * Configuration options for the component\n   * @default { enabled: true, theme: \"dark\" }\n   */\n  config?: ComponentConfig;\n};\n```\n\n\u003e **Note:** The inline syntax `@typedef {{ name: string }} User` continues to work for backwards compatibility.\n\n### `@callback`\n\nThe `@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.\n\nThis is useful for typing callback props without using inline function type syntax.\n\n**Signature:**\n\n```js\n/**\n * Optional description\n * @callback CallbackName\n * @param {Type} paramName - Parameter description\n * @returns {ReturnType}\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Callback fired when the value changes\n   * @callback OnChange\n   * @param {string} value - The new value\n   * @param {number} index - The index of the changed item\n   * @returns {void}\n   */\n\n  /** @type {OnChange} */\n  let { onChange = (value, index) =\u003e {} } = $props();\n\u003c/script\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Callback fired when the value changes\n   * @callback OnChange\n   * @param {string} value - The new value\n   * @param {number} index - The index of the changed item\n   * @returns {void}\n   */\n\n  /** @type {OnChange} */\n  export let onChange = (value, index) =\u003e {};\n\u003c/script\u003e\n```\n\nOutput:\n\n```ts\n/**\n * Callback fired when the value changes\n */\nexport type OnChange = (value: string, index: number) =\u003e void;\n\nexport type ComponentProps = {\n  /**\n   * Callback fired when the value changes\n   */\n  onChange?: OnChange;\n};\n```\n\nCallbacks can be combined with `@typedef` in the same comment block:\n\n```js\n/**\n * @typedef {\"asc\" | \"desc\"} SortDirection\n * @callback SortFn\n * @param {any} a\n * @param {any} b\n * @param {SortDirection} direction\n * @returns {number}\n */\n```\n\nWhen `@returns` is omitted, the return type defaults to `void`. When no `@param` tags are present, the callback is typed as a no-argument function.\n\n### `@slot` / `@snippet`\n\nUse the `@slot` tag for typing component slots. For Svelte 5 runes components, `@snippet` is also supported as an alias. Both are non-standard JSDoc tags.\n\nDescriptions are optional for named slots. Currently, the default slot cannot have a description.\n\n**Signature:**\n\n```js\n/**\n * @slot {Type} slot-name [slot description]\n * @snippet {Type} snippet-name [snippet description]\n */\n\nOmit the `slot-name` to type the default slot.\n\n/**\n * @slot {Type}\n * @snippet {Type}\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @snippet {{ prop: number; doubled: number; }}\n   * @snippet {{}} title\n   * @snippet {{ prop: number }} body - Customize the paragraph text.\n   */\n\n  let { prop = 0, children, title, body } = $props();\n\u003c/script\u003e\n\n\u003ch1\u003e\n  {@render children?.({ prop, doubled: prop * 2 })}\n  {@render title?.()}\n\u003c/h1\u003e\n\n\u003cp\u003e\n  {@render body?.({ prop })}\n\u003c/p\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @slot {{ prop: number; doubled: number; }}\n   * @slot {{}} title\n   * @slot {{ prop: number }} body - Customize the paragraph text.\n   */\n\n  export let prop = 0;\n\u003c/script\u003e\n\n\u003ch1\u003e\n  \u003cslot {prop} doubled={prop * 2} /\u003e\n  \u003cslot name=\"title\" /\u003e\n\u003c/h1\u003e\n\n\u003cp\u003e\n  \u003cslot name=\"body\" {prop} /\u003e\n\u003c/p\u003e\n```\n\n#### Svelte 5 Snippet Compatibility\n\nFor 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.\n\nWhen parsing runes components, `sveld` maps `{@render ...}` calls back into the same slot metadata used for traditional `\u003cslot\u003e` declarations. Reserved snippet props such as `children`, along with named snippet props discovered from `{@render ...}`, are represented through `slots` metadata and generated snippet prop types rather than duplicated in the `props` output.\n\nPositional snippet calls such as `{@render row?.(item, index)}` are preserved as typed props when the prop itself has an explicit type like `Snippet\u003c[Item, number]\u003e`. They are not converted into synthetic slot metadata.\n\nFor slots with props (e.g., `let:prop`), the generated type uses a Snippet-compatible signature:\n\n```ts\nslotName?: (this: void, ...args: [{ prop: PropType }]) =\u003e void;\n```\n\nFor slots without props:\n\n```ts\nslotName?: (this: void) =\u003e void;\n```\n\n**Why this signature?**\n\n- **`this: void`** – Ensures the snippet cannot be called with a `this` context, matching Svelte's internal enforcement that snippets are pure render functions\n- **`...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\u003cT\u003e` type works\n\n**Default slot (`children` prop):**\n\nThe default slot generates an optional `children` snippet prop:\n\n```svelte\n\u003c!-- Component with default slot that passes props --\u003e\n\u003cDropdown {items} selectedId=\"1\"\u003e\n  {#snippet children({ item, index })}\n    \u003cspan\u003e{item.text} (#{index})\u003c/span\u003e\n  {/snippet}\n\u003c/Dropdown\u003e\n```\n\nGenerated types:\n\n```ts\ntype DropdownProps = {\n  items: Item[];\n  selectedId?: string;\n\n  // Default slot as children snippet prop\n  children?: (this: void, ...args: [{ item: Item; index: number }]) =\u003e void;\n};\n```\n\n**Named slots:**\n\n```svelte\n\u003c!-- Using the generated types with Svelte 5 syntax --\u003e\n\u003cDataTable headers={headers} rows={rows}\u003e\n  {#snippet cell({ cell, row })}\n    {#if cell.key === 'actions'}\n      \u003cButton on:click={() =\u003e handleAction(row)}\u003eEdit\u003c/Button\u003e\n    {:else}\n      {cell.value}\n    {/if}\n  {/snippet}\n\u003c/DataTable\u003e\n```\n\nThe generated TypeScript definition includes both the snippet prop and the traditional slot definition:\n\n```ts\ntype DataTableProps\u003cRow\u003e = {\n  // ... other props\n\n  // Snippet prop for Svelte 5 compatibility\n  cell?: (\n    this: void,\n    ...args: [\n      {\n        row: Row;\n        cell: DataTableCell\u003cRow\u003e;\n        rowIndex: number;\n        cellIndex: number;\n      },\n    ]\n  ) =\u003e void;\n\n  // Default slot as children prop\n  children?: (this: void) =\u003e void;\n};\n\nexport default class DataTable\u003cRow\u003e extends SvelteComponentTyped\u003c\n  DataTableProps\u003cRow\u003e,\n  {\n    /* events */\n  },\n  {\n    // Traditional slot definition (Svelte 3/4)\n    default: Record\u003cstring, never\u003e;\n    cell: {\n      row: Row;\n      cell: DataTableCell\u003cRow\u003e;\n      rowIndex: number;\n      cellIndex: number;\n    };\n  }\n\u003e {}\n```\n\n### `@event`\n\nUse the `@event` tag to type dispatched events. An event name is required and a description optional.\n\nIn Svelte 5 runes components, callback props such as `onclick` are treated as component props, not events. The `events` output remains reserved for real dispatched events and legacy forwarded events. If a runes component documents `@event foo` and exposes a matching callback prop like `onfoo` without actually dispatching or forwarding `foo`, `sveld` aliases that documentation onto the callback prop instead of synthesizing an emitted event.\n\nUse `null` as the value if no event detail is provided.\n\n**Signature:**\n\n```js\n/**\n * Optional event description\n * @event {EventDetail} eventname [inline description]\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Fired when a value is saved.\n   * @event {{ id: string }} save\n   */\n  let { onsave } = $props();\n\u003c/script\u003e\n\n\u003cbutton onclick={() =\u003e onsave?.({ id: \"1\" })}\u003eSave\u003c/button\u003e\n```\n\n**Svelte 5 Runes with dispatched events:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @event {{ key: string }} button:key\n   * @event {null} key - Fired when `key` changes.\n   */\n\n  let { key = \"\" } = $props();\n\n  import { createEventDispatcher } from \"svelte\";\n\n  const dispatch = createEventDispatcher();\n\n  $effect(() =\u003e {\n    dispatch(\"button:key\", { key });\n    if (key) dispatch(\"key\");\n  });\n\u003c/script\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @event {{ key: string }} button:key\n   * @event {null} key - Fired when `key` changes.\n   */\n\n  export let key = \"\";\n\n  import { createEventDispatcher } from \"svelte\";\n\n  const dispatch = createEventDispatcher();\n\n  $: dispatch(\"button:key\", { key });\n  $: if (key) dispatch(\"key\");\n\u003c/script\u003e\n```\n\nOutput:\n\n```ts\nexport default class Component extends SvelteComponentTyped\u003c\n  ComponentProps,\n  {\n    \"button:key\": CustomEvent\u003c{ key: string }\u003e;\n    /** Fired when `key` changes. */ key: CustomEvent\u003cnull\u003e;\n  },\n  Record\u003cstring, never\u003e\n\u003e {}\n```\n\n#### Using `@property` for complex event details\n\nFor events with complex object payloads, use the `@property` tag to document individual properties. The main comment description will be used as the event description.\n\n**Signature:**\n\n```js\n/**\n * Event description\n * @event eventname\n * @type {object}\n * @property {Type} propertyName - Property description\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Fired when the user submits the form\n   *\n   * @event submit\n   * @type {object}\n   * @property {string} name - The user's name\n   * @property {string} email - The user's email address\n   * @property {boolean} newsletter - Whether the user opted into the newsletter\n   */\n\n  let { name = \"Jane Doe\", email = \"jane@example.com\", newsletter = true } = $props();\n\n  import { createEventDispatcher } from \"svelte\";\n\n  const dispatch = createEventDispatcher();\n\n  function handleSubmit() {\n    dispatch(\"submit\", { name, email, newsletter });\n  }\n\u003c/script\u003e\n\n\u003cbutton type=\"button\" onclick={handleSubmit}\u003eSubmit\u003c/button\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Fired when the user submits the form\n   *\n   * @event submit\n   * @type {object}\n   * @property {string} name - The user's name\n   * @property {string} email - The user's email address\n   * @property {boolean} newsletter - Whether the user opted into the newsletter\n   */\n\n  export let name = \"Jane Doe\";\n  export let email = \"jane@example.com\";\n  export let newsletter = true;\n\n  import { createEventDispatcher } from \"svelte\";\n\n  const dispatch = createEventDispatcher();\n\n  function handleSubmit() {\n    dispatch(\"submit\", { name, email, newsletter });\n  }\n\u003c/script\u003e\n\n\u003cbutton type=\"button\" on:click={handleSubmit}\u003eSubmit\u003c/button\u003e\n```\n\nOutput:\n\n```ts\nexport default class Component extends SvelteComponentTyped\u003c\n  ComponentProps,\n  {\n    /** Fired when the user submits the form */\n    submit: CustomEvent\u003c{\n      /** The user's name */\n      name: string;\n      /** The user's email address */\n      email: string;\n      /** Whether the user opted into the newsletter */\n      newsletter: boolean;\n    }\u003e;\n  },\n  Record\u003cstring, never\u003e\n\u003e {}\n```\n\n#### Optional properties in event details\n\nJust 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.\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Snowball event fired when throwing a snowball\n   *\n   * @event snowball\n   * @type {object}\n   * @property {boolean} isPacked - Indicates whether the snowball is tightly packed\n   * @property {number} speed - The speed of the snowball in mph\n   * @property {string} [color] - Optional color of the snowball\n   * @property {number} [density=0.9] - Optional density with default value\n   */\n\n  let { speed = 50 } = $props();\n\n  import { createEventDispatcher } from \"svelte\";\n\n  const dispatch = createEventDispatcher();\n\n  function throwSnowball() {\n    dispatch(\"snowball\", {\n      isPacked: true,\n      speed,\n    });\n  }\n\u003c/script\u003e\n\n\u003cbutton type=\"button\" onclick={throwSnowball}\u003eThrow\u003c/button\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * Snowball event fired when throwing a snowball\n   *\n   * @event snowball\n   * @type {object}\n   * @property {boolean} isPacked - Indicates whether the snowball is tightly packed\n   * @property {number} speed - The speed of the snowball in mph\n   * @property {string} [color] - Optional color of the snowball\n   * @property {number} [density=0.9] - Optional density with default value\n   */\n\n  export let speed = 50;\n\n  import { createEventDispatcher } from \"svelte\";\n\n  const dispatch = createEventDispatcher();\n\n  function throwSnowball() {\n    dispatch(\"snowball\", {\n      isPacked: true,\n      speed,\n    });\n  }\n\u003c/script\u003e\n\n\u003cbutton type=\"button\" on:click={throwSnowball}\u003eThrow\u003c/button\u003e\n```\n\nOutput:\n\n```ts\nexport default class Component extends SvelteComponentTyped\u003c\n  ComponentProps,\n  {\n    /** Snowball event fired when throwing a snowball */\n    snowball: CustomEvent\u003c{\n      /** Indicates whether the snowball is tightly packed */\n      isPacked: boolean;\n      /** The speed of the snowball in mph */\n      speed: number;\n      /** Optional color of the snowball */\n      color?: string;\n      /** Optional density with default value @default 0.9 */\n      density?: number;\n    }\u003e;\n  },\n  Record\u003cstring, never\u003e\n\u003e {}\n```\n\n### Context API\n\n`sveld` automatically generates TypeScript definitions for Svelte's `setContext`/`getContext` API by extracting types from JSDoc annotations on the context values.\n\n#### How it works\n\nWhen you use `setContext` in a component, `sveld` will:\n\n1. Detect the `setContext` call\n2. Extract the context key (must be a string literal)\n3. Find JSDoc `@type` annotations on the variables being passed\n4. Generate a TypeScript type export for the context\n\n#### Example\n\n**Modal.svelte**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  import { setContext } from \"svelte\";\n\n  /**\n   * Close the modal\n   * @type {() =\u003e void}\n   */\n  const close = () =\u003e {\n    // Close logic\n  };\n\n  /**\n   * Open the modal with content\n   * @type {(component: any, props?: any) =\u003e void}\n   */\n  const open = (component, props) =\u003e {\n    // Open logic\n  };\n\n  setContext(\"simple-modal\", { open, close });\n\n  let { children } = $props();\n\u003c/script\u003e\n\n\u003cdiv class=\"modal\"\u003e\n  {@render children?.()}\n\u003c/div\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  import { setContext } from \"svelte\";\n\n  /**\n   * Close the modal\n   * @type {() =\u003e void}\n   */\n  const close = () =\u003e {\n    // Close logic\n  };\n\n  /**\n   * Open the modal with content\n   * @type {(component: any, props?: any) =\u003e void}\n   */\n  const open = (component, props) =\u003e {\n    // Open logic\n  };\n\n  setContext(\"simple-modal\", { open, close });\n\u003c/script\u003e\n\n\u003cdiv class=\"modal\"\u003e\n  \u003cslot /\u003e\n\u003c/div\u003e\n```\n\n**Generated TypeScript definition:**\n\n```ts\nexport type SimpleModalContext = {\n  /** Open the modal with content */\n  open: (component: any, props?: any) =\u003e void;\n  /** Close the modal */\n  close: () =\u003e void;\n};\n\nexport type ModalProps = {};\n\nexport default class Modal extends SvelteComponentTyped\u003c\n  ModalProps,\n  Record\u003cstring, any\u003e,\n  { default: Record\u003cstring, never\u003e }\n\u003e {}\n```\n\n**Consumer usage:**\n\n```svelte\n\u003cscript\u003e\n  import { getContext } from 'svelte';\n  import type { SimpleModalContext } from 'modal-library/Modal.svelte';\n\n  // Fully typed with autocomplete!\n  const { close, open } = getContext\u003cSimpleModalContext\u003e('simple-modal');\n\u003c/script\u003e\n\n\u003cbutton on:click={close}\u003eClose\u003c/button\u003e\n```\n\n#### Explicitly typing contexts\n\nThere are several ways to provide type information for contexts:\n\n**Option 1: Inline JSDoc on variables (recommended)**\n\n```svelte\n\u003cscript\u003e\n  import { setContext } from 'svelte';\n\n  /**\n   * @type {() =\u003e void}\n   */\n  const close = () =\u003e {};\n\n  setContext('modal', { close });\n\u003c/script\u003e\n```\n\n**Option 2: Using @typedef for complex types**\n\n```svelte\n\u003cscript\u003e\n  import { setContext } from 'svelte';\n\n  /**\n   * @typedef {object} TabData\n   * @property {string} id\n   * @property {string} label\n   * @property {boolean} [disabled]\n   */\n\n  /**\n   * @type {(tab: TabData) =\u003e void}\n   */\n  const addTab = (tab) =\u003e {};\n\n  setContext('tabs', { addTab });\n\u003c/script\u003e\n```\n\n**Option 3: Referencing imported types**\n\n```svelte\n\u003cscript\u003e\n  import { setContext } from 'svelte';\n\n  /**\n   * @type {typeof import(\"./types\").ModalAPI}\n   */\n  const modalAPI = {\n    open: () =\u003e {},\n    close: () =\u003e {}\n  };\n\n  setContext('modal', modalAPI);\n\u003c/script\u003e\n```\n\n**Option 4: Direct object literal with inline functions**\n\n```svelte\n\u003cscript\u003e\n  import { setContext } from 'svelte';\n\n  // sveld infers basic function signatures\n  setContext('modal', {\n    open: (component, props) =\u003e {}, // Inferred as (arg, arg) =\u003e any\n    close: () =\u003e {}                 // Inferred as () =\u003e any\n  });\n\u003c/script\u003e\n```\n\n\u003e **Note:** For best results, use explicit JSDoc `@type` annotations. Inline functions without annotations will be inferred with generic signatures.\n\n#### Notes\n\n- Context keys must be string literals (dynamic keys are not supported)\n- Variables passed to `setContext` should have JSDoc `@type` annotations for accurate types\n- The generated type name follows the pattern: `{PascalCase}Context`. Separators (hyphens, underscores, dots, colons, slashes, spaces) are stripped and each segment is capitalized:\n  | Context Key | Generated Type Name |\n  | --- | --- |\n  | `\"simple-modal\"` | `SimpleModalContext` |\n  | `\"user_settings\"` | `UserSettingsContext` |\n  | `\"Carbon.Modal\"` | `CarbonModalContext` |\n  | `\"Carbon:Modal\"` | `CarbonModalContext` |\n  | `\"app/modal\"` | `AppModalContext` |\n  | `\"My Context\"` | `MyContextContext` |\n  | `\"Tabs\"` | `TabsContext` |\n- If no type annotation is found, the type defaults to `any` with a warning\n\n### `@restProps`\n\n`sveld` can pick up inline HTML elements that `$$restProps` is forwarded to. However, it cannot infer the underlying element for instantiated components.\n\nYou can use the `@restProps` tag to specify the element tags that `$$restProps` is forwarded to.\n\n**Signature:**\n\n```js\n/**\n * Single element\n * @restProps {tagname}\n *\n * Multiple elements\n * @restProps {tagname-1 | tagname-2 | tagname-3}\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  import Button from \"./Button.svelte\";\n\n  /** @restProps {h1 | button} */\n  let { edit = false, children, ...restProps } = $props();\n\u003c/script\u003e\n\n{#if edit}\n  \u003cButton {...restProps} /\u003e\n{:else}\n  \u003ch1 {...restProps}\u003e\n    {@render children?.()}\n  \u003c/h1\u003e\n{/if}\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /** @restProps {h1 | button} */\n  export let edit = false;\n\n  import Button from \"./Button.svelte\";\n\u003c/script\u003e\n\n{#if edit}\n  \u003cButton {...$$restProps} /\u003e\n{:else}\n  \u003ch1 {...$$restProps}\u003e\u003cslot /\u003e\u003c/h1\u003e\n{/if}\n```\n\n### `@extendProps`\n\nIn some cases, a component may be based on another component. The `@extendProps` tag can be used to extend generated component props.\n\n\u003e **Note:** `@extends` is supported as an alias but `@extendProps` is preferred to avoid conflicts with standard JSDoc `@extends` (used for class inheritance).\n\n**Signature:**\n\n```js\n/**\n * @extendProps {\u003crelative path to component\u003e} ComponentProps\n */\n```\n\n**Example:**\n\n```js\n/** @extendProps {\"./Button.svelte\"} ButtonProps */\n\nexport const secondary = true;\n\nimport Button from \"./Button.svelte\";\n```\n\n### `@generics`\n\nCurrently, to define generics for a Svelte component, you must use [`generics` attribute](https://github.com/dummdidumm/rfcs/blob/bfb14dc56a70ec6ddafebf2242b8e1500e06a032/text/ts-typing-props-slots-events.md#generics) on the script tag. Note that this feature is [experimental](https://svelte.dev/docs/typescript#experimental-advanced-typings) and may change in the future.\n\nHowever, the `generics` attribute only works if using `lang=\"ts\"`; the language server will produce an error if `generics` is used without specifying `lang=\"ts\"`.\n\n```svelte\n\u003c!-- This causes an error because `lang=\"ts\"` must be used. --\u003e\n\u003cscript generics=\"Row extends DataTableRow = any\"\u003e\u003c/script\u003e\n```\n\nBecause `sveld` is designed to support JavaScript-only usage as a baseline, the API design to specify generics uses a custom JSDoc tag `@generics`.\n\n**Signature:**\n\n```js\n/**\n * @generics {GenericParameter} GenericName\n */\n```\n\n**Example:**\n\n```js\n/**\n * @generics {Row extends DataTableRow = any} Row\n */\n```\n\n**Component example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @typedef {{ id: string | number; [key: string]: any; }} DataTableRow\n   * @typedef {Exclude\u003ckeyof Row, \"id\"\u003e} DataTableKey\u003cRow\u003e\n   * @typedef {{ key: DataTableKey\u003cRow\u003e; value: string; }} DataTableHeader\u003cRow=DataTableRow\u003e\n   * @template {DataTableRow} \u003cRow extends DataTableRow = DataTableRow\u003e\n   * @generics {Row extends DataTableRow = DataTableRow} Row\n   */\n\n  let {\n    /** @type {ReadonlyArray\u003cDataTableHeader\u003cRow\u003e\u003e} */\n    headers = [],\n    /** @type {ReadonlyArray\u003cRow\u003e} */\n    rows = [],\n    children,\n  } = $props();\n\u003c/script\u003e\n\n{@render children?.({ headers, rows })}\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @typedef {{ id: string | number; [key: string]: any; }} DataTableRow\n   * @typedef {Exclude\u003ckeyof Row, \"id\"\u003e} DataTableKey\u003cRow\u003e\n   * @typedef {{ key: DataTableKey\u003cRow\u003e; value: string; }} DataTableHeader\u003cRow=DataTableRow\u003e\n   * @template {DataTableRow} \u003cRow extends DataTableRow = DataTableRow\u003e\n   * @generics {Row extends DataTableRow = DataTableRow} Row\n   */\n\n  /** @type {ReadonlyArray\u003cDataTableHeader\u003cRow\u003e\u003e} */\n  export let headers = [];\n\n  /** @type {ReadonlyArray\u003cRow\u003e} */\n  export let rows = [];\n\u003c/script\u003e\n\n\u003cslot {headers} {rows} /\u003e\n```\n\nThe generated TypeScript definition will resemble the following:\n\n```ts\n// Props type includes the full constraint, enabling indexed access types like Row[\"id\"]\nexport type ComponentProps\u003cRow extends DataTableRow = any\u003e = {\n  rows?: ReadonlyArray\u003cRow\u003e;\n};\n\nexport default class Component\u003c\n  Row extends DataTableRow = any,\n\u003e extends SvelteComponentTyped\u003c\n  ComponentProps\u003cRow\u003e,\n  Record\u003cstring, any\u003e,\n  Record\u003cstring, any\u003e\n\u003e {}\n```\n\nFor a parameter list, the name should be comma-separated but not include spaces.\n\n```js\n/**\n * @generics {Param1, Param2} Name1,Name2\n */\n```\n\n```ts\nexport type ComponentProps\u003cParam1, Param2\u003e = { ... };\n\nexport default class Component\u003cParam1, Param2\u003e extends SvelteComponentTyped\u003c\n  ComponentProps\u003cName1, Name2\u003e,\n  Record\u003cstring, any\u003e,\n  Record\u003cstring, any\u003e\n\u003e {}\n```\n\n### `@component` comments\n\nThe Svelte Language Server supports component-level comments through the following syntax: `\u003c!-- @component [comment] --\u003e`.\n\n`sveld` will copy these over to the exported default component in the TypeScript definition.\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003c!-- @component\n@example\n\u003cButton\u003e\n  Text\n\u003c/Button\u003e\n--\u003e\n\u003cscript\u003e\n  let { children } = $props();\n\u003c/script\u003e\n\n\u003cbutton\u003e\n  {@render children?.()}\n\u003c/button\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003c!-- @component\n@example\n\u003cButton\u003e\n  Text\n\u003c/Button\u003e\n--\u003e\n\u003cbutton\u003e\n  \u003cslot /\u003e\n\u003c/button\u003e\n```\n\nOutput:\n\n```ts\n/**\n * @example\n * \u003cButton\u003e\n *   Text\n * \u003c/Button\u003e\n */\nexport default class Button extends SvelteComponentTyped\u003c\n  ButtonProps,\n  Record\u003cstring, any\u003e,\n  { default: Record\u003cstring, never\u003e }\n\u003e {}\n```\n\n### Accessor Props\n\nExported functions and consts become accessor props in generated TypeScript definitions. Use `@type` to document function signatures, or use `@param` and `@returns` (or `@return`) JSDoc tags for richer documentation.\n\nNote that `@type` tag annotations take precedence over `@param`/`@returns` tags.\n\n**Signature:**\n\n```js\n/**\n * Function description\n * @param {Type} paramName - Parameter description\n * @param {Type} [optionalParam] - Optional parameter\n * @returns {ReturnType} Return value description\n */\n```\n\n**Example:**\n\n**Svelte 5 Runes:**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @typedef {object} NotificationData\n   * @property {string} [id] - Optional id for deduplication\n   * @property {\"error\" | \"info\" | \"success\"} [kind]\n   */\n\n  let { children } = $props();\n\n  /**\n   * Add a notification to the queue.\n   * @param {NotificationData} notification\n   * @returns {string} The notification id\n   */\n  export function add(notification) {\n    const id = notification.id ?? \"id\";\n    return id;\n  }\n\n  /**\n   * Remove a notification by id.\n   * @param {string} id\n   * @returns {boolean} True if the notification was found and removed\n   */\n  export function remove(id) {\n    return true;\n  }\n\n  /**\n   * Get notification count.\n   * @returns {number} The number of notifications\n   */\n  export function getCount() {\n    return 0;\n  }\n\u003c/script\u003e\n\n\u003cdiv\u003e\n  {@render children?.()}\n\u003c/div\u003e\n```\n\n**Svelte 3, 4, 5 (non-Runes):**\n\n```svelte\n\u003cscript\u003e\n  /**\n   * @typedef {object} NotificationData\n   * @property {string} [id] - Optional id for deduplication\n   * @property {\"error\" | \"info\" | \"success\"} [kind]\n   */\n\n  /**\n   * Add a notification to the queue.\n   * @param {NotificationData} notification\n   * @returns {string} The notification id\n   */\n  export function add(notification) {\n    const id = notification.id ?? \"id\";\n    return id;\n  }\n\n  /**\n   * Remove a notification by id.\n   * @param {string} id\n   * @returns {boolean} True if the notification was found and removed\n   */\n  export function remove(id) {\n    return true;\n  }\n\n  /**\n   * Get notification count.\n   * @returns {number} The number of notifications\n   */\n  export function getCount() {\n    return 0;\n  }\n\u003c/script\u003e\n```\n\nOutput:\n\n```ts\nexport type NotificationData = {\n  /** Optional id for deduplication */\n  id?: string;\n  kind?: \"error\" | \"info\" | \"success\";\n};\n\nexport type ComponentProps = Record\u003cstring, never\u003e;\n\nexport default class Component extends SvelteComponentTyped\u003c\n  ComponentProps,\n  Record\u003cstring, any\u003e,\n  Record\u003cstring, never\u003e\n\u003e {\n  /**\n   * Add a notification to the queue.\n   */\n  add: (notification: NotificationData) =\u003e string;\n\n  /**\n   * Remove a notification by id.\n   */\n  remove: (id: string) =\u003e boolean;\n\n  /**\n   * Get notification count.\n   */\n  getCount: () =\u003e number;\n}\n```\n\nWhen only `@param` tags are present without `@returns`, the return type defaults to `any`. When only `@returns` is present without `@param`, the function signature is `() =\u003e returnType`.\n\n## Contributing\n\nRefer to the [contributing guidelines](CONTRIBUTING.md).\n\n## License\n\n[Apache-2.0](LICENSE)\n\n[npm]: https://img.shields.io/npm/v/sveld.svg?color=262626\u0026style=for-the-badge\n[npm-url]: https://npmjs.com/package/sveld\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarbon-design-system%2Fsveld","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcarbon-design-system%2Fsveld","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcarbon-design-system%2Fsveld/lists"}