Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use the SvelteComponent interface for typing components #412

Closed
wants to merge 1 commit into from

Conversation

metonym
Copy link
Collaborator

@metonym metonym commented Nov 25, 2020

Currently, component TypeScript definitions in this library mock the internal Svelte component API so that it is readable by the Svelte Language Server. This practice is discouraged because properties like $$prop_def and $$slot_def are intended to be private.

Released in version 3.30, Svelte supports components definitions that use the typed SvelteComponent interface. Refer to the accepted RFC for more info.

The new SvelteComponent interface provides a nice API to type props, events, and slots through generic parameters.

Before (discouraged)

/// <reference types="svelte" />
import { AccordionSkeletonProps } from "./AccordionSkeleton";

export interface AccordionProps extends AccordionSkeletonProps {
  /**
   * Specify alignment of accordion item chevron icon
   * @default "end"
   */
  align?: "start" | "end";

  /**
   * Specify the size of the accordion
   */
  size?: "sm" | "xl";

  /**
   * Set to `true` to disable the accordion
   * @default false
   */
  disabled?: boolean;

  /**
   * Set to `true` to display the skeleton state
   * @default false
   */
  skeleton?: boolean;
}

export default class Accordion {
  $$prop_def: AccordionProps;
  $$slot_def: {
    default: {};
  };

  $on(eventname: "click", cb: (event: WindowEventMap["click"]) => void): () => void;
  $on(eventname: "mouseover", cb: (event: WindowEventMap["mouseover"]) => void): () => void;
  $on(eventname: "mouseenter", cb: (event: WindowEventMap["mouseenter"]) => void): () => void;
  $on(eventname: "mouseleave", cb: (event: WindowEventMap["mouseleave"]) => void): () => void;
  $on(eventname: string, cb: (event: Event) => void): () => void;
}

After

/// <reference types="svelte" />
import { SvelteComponent } from "svelte";
import { AccordionSkeletonProps } from "./AccordionSkeleton";

export interface AccordionProps extends AccordionSkeletonProps {
  /**
   * Specify alignment of accordion item chevron icon
   * @default "end"
   */
  align?: "start" | "end";

  /**
   * Specify the size of the accordion
   */
  size?: "sm" | "xl";

  /**
   * Set to `true` to disable the accordion
   * @default false
   */
  disabled?: boolean;

  /**
   * Set to `true` to display the skeleton state
   * @default false
   */
  skeleton?: boolean;
}

export default class Accordion extends SvelteComponent<
  AccordionProps,
  {
    click: WindowEventMap["click"];
    mouseover: WindowEventMap["mouseover"];
    mouseenter: WindowEventMap["mouseenter"];
    mouseleave: WindowEventMap["mouseleave"];
  },
  { default: {} }
> {}

Breaking Changes

Although there are no API changes, TypeScript users will need Svelte version 3.30 or greater.

@vercel
Copy link

vercel bot commented Nov 25, 2020

This pull request is being automatically deployed with Vercel (learn more).
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: https://vercel.com/carbon-svelte/carbon-components-svelte/9rv75azae
✅ Preview: https://carbon-components-svelte-git-typed-svelte-interface.carbon-svelte.vercel.app

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

1 participant