sveld 0.23.1 → 0.23.2

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 CHANGED
@@ -413,6 +413,55 @@ export type ComponentProps = {
413
413
  };
414
414
  ```
415
415
 
416
+ #### Optional properties and default values
417
+
418
+ Following JSDoc standards, use square brackets to mark properties as optional. You can also specify default values using the `[propertyName=defaultValue]` syntax.
419
+
420
+ Signature:
421
+
422
+ ```js
423
+ /**
424
+ * @typedef {object} TypeName
425
+ * @property {Type} [optionalProperty] - Optional property description
426
+ * @property {Type} [propertyWithDefault=defaultValue] - Property with default value
427
+ */
428
+ ```
429
+
430
+ Example:
431
+
432
+ ```js
433
+ /**
434
+ * Configuration options for the component
435
+ * @typedef {object} ComponentConfig
436
+ * @property {boolean} enabled - Whether the component is enabled
437
+ * @property {string} theme - The component theme
438
+ * @property {number} [timeout=5000] - Optional timeout in milliseconds
439
+ * @property {boolean} [debug] - Optional debug mode flag
440
+ */
441
+
442
+ /** @type {ComponentConfig} */
443
+ export let config = { enabled: true, theme: "dark" };
444
+ ```
445
+
446
+ Output:
447
+
448
+ ```ts
449
+ export type ComponentConfig = {
450
+ /** Whether the component is enabled */ enabled: boolean;
451
+ /** The component theme */ theme: string;
452
+ /** Optional timeout in milliseconds @default 5000 */ timeout?: number;
453
+ /** Optional debug mode flag */ debug?: boolean;
454
+ };
455
+
456
+ export type ComponentProps = {
457
+ /**
458
+ * Configuration options for the component
459
+ * @default { enabled: true, theme: "dark" }
460
+ */
461
+ config?: ComponentConfig;
462
+ };
463
+ ```
464
+
416
465
  > **Note:** The inline syntax `@typedef {{ name: string }} User` continues to work for backwards compatibility.
417
466
 
418
467
  ### `@slot`
@@ -562,6 +611,54 @@ export default class Component extends SvelteComponentTyped<
562
611
  > {}
563
612
  ```
564
613
 
614
+ #### Optional properties in event details
615
+
616
+ 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.
617
+
618
+ Example:
619
+
620
+ ```js
621
+ /**
622
+ * Snowball event fired when throwing a snowball
623
+ *
624
+ * @event snowball
625
+ * @type {object}
626
+ * @property {boolean} isPacked - Indicates whether the snowball is tightly packed
627
+ * @property {number} speed - The speed of the snowball in mph
628
+ * @property {string} [color] - Optional color of the snowball
629
+ * @property {number} [density=0.9] - Optional density with default value
630
+ */
631
+
632
+ import { createEventDispatcher } from "svelte";
633
+
634
+ const dispatch = createEventDispatcher();
635
+
636
+ function throwSnowball() {
637
+ dispatch("snowball", {
638
+ isPacked: true,
639
+ speed: 50
640
+ });
641
+ }
642
+ ```
643
+
644
+ Output:
645
+
646
+ ```ts
647
+ export default class Component extends SvelteComponentTyped<
648
+ ComponentProps,
649
+ {
650
+ /** Snowball event fired when throwing a snowball */
651
+ snowball: CustomEvent<{
652
+ /** Indicates whether the snowball is tightly packed */ isPacked: boolean;
653
+ /** The speed of the snowball in mph */ speed: number;
654
+ /** Optional color of the snowball */ color?: string;
655
+ /** Optional density with default value @default 0.9 */ density?: number;
656
+ }>;
657
+ },
658
+ Record<string, never>
659
+ > {}
660
+ ```
661
+
565
662
  ### Context API
566
663
 
567
664
  `sveld` automatically generates TypeScript definitions for Svelte's `setContext`/`getContext` API by extracting types from JSDoc annotations on the context values.
@@ -247,7 +247,7 @@ class ComponentParser {
247
247
  currentTypedefDescription = undefined;
248
248
  }
249
249
  };
250
- tags.forEach(({ tag, type: tagType, name, description }) => {
250
+ tags.forEach(({ tag, type: tagType, name, description, optional, default: defaultValue }) => {
251
251
  const type = this.aliasType(tagType);
252
252
  switch (tag) {
253
253
  case "extends":
@@ -284,23 +284,23 @@ class ComponentParser {
284
284
  currentEventType = type;
285
285
  }
286
286
  break;
287
- case "property":
287
+ case "property": {
288
288
  // Collect properties for the current event or typedef
289
+ const propertyData = {
290
+ name,
291
+ type,
292
+ description: description?.replace(/^-\s*/, "").trim(),
293
+ optional: optional || false,
294
+ default: defaultValue,
295
+ };
289
296
  if (currentEventName !== undefined) {
290
- eventProperties.push({
291
- name,
292
- type,
293
- description: description?.replace(/^-\s*/, "").trim(),
294
- });
297
+ eventProperties.push(propertyData);
295
298
  }
296
299
  else if (currentTypedefName !== undefined) {
297
- typedefProperties.push({
298
- name,
299
- type,
300
- description: description?.replace(/^-\s*/, "").trim(),
301
- });
300
+ typedefProperties.push(propertyData);
302
301
  }
303
302
  break;
303
+ }
304
304
  case "typedef": {
305
305
  // Finalize any previous typedef being built
306
306
  finalizeTypedef();
@@ -328,11 +328,20 @@ class ComponentParser {
328
328
  return "null";
329
329
  // Build inline object type with property descriptions as JSDoc comments
330
330
  const props = properties
331
- .map(({ name, type, description }) => {
332
- if (description) {
333
- return `/** ${description} */ ${name}: ${type};`;
331
+ .map(({ name, type, description, optional, default: defaultValue }) => {
332
+ const optionalMarker = optional ? "?" : "";
333
+ let comment = description || "";
334
+ // Add default value to description if present
335
+ if (defaultValue && comment) {
336
+ comment = `${comment} @default ${defaultValue}`;
337
+ }
338
+ else if (defaultValue) {
339
+ comment = `@default ${defaultValue}`;
340
+ }
341
+ if (comment) {
342
+ return `/** ${comment} */ ${name}${optionalMarker}: ${type};`;
334
343
  }
335
- return `${name}: ${type};`;
344
+ return `${name}${optionalMarker}: ${type};`;
336
345
  })
337
346
  .join(" ");
338
347
  return `{ ${props} }`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sveld",
3
- "version": "0.23.1",
3
+ "version": "0.23.2",
4
4
  "license": "Apache-2.0",
5
5
  "description": "Generate TypeScript definitions for your Svelte components.",
6
6
  "main": "./lib/index.js",