Skip to content

Commit

Permalink
feat(types)!: use Component type for type definitions (#203)
Browse files Browse the repository at this point in the history
Closes #201
  • Loading branch information
metonym authored Jan 26, 2025
1 parent f8d2f3a commit fa04bd2
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 211 deletions.
23 changes: 23 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,29 @@ You can use `fill` to customize the color or pass any other valid `svg` attribut
<Add aria-label="Add" tabindex={0} />
```

## TypeScript

This library offers TypeScript support for Svelte 4 and Svelte 5.

For Svelte 3 compatibility, use [`carbon-icons-svelte@12.13.0`](https://github.com/carbon-design-system/carbon-icons-svelte/tree/v12.13.0).

For convenience, a `CarbonIconProps` type is exported from the library.

```svelte
<script lang="ts">
import Add from "carbon-icons-svelte/lib/Add.svelte";
import type { CarbonIconProps } from "carbon-icons-svelte";
const props: CarbonIconProps = {
size: 16,
fill: "red",
"data-test": "id",
};
</script>
<Add {...props} />
```

## [Changelog](CHANGELOG.md)

## [Contributing](CONTRIBUTING.md)
Expand Down
32 changes: 11 additions & 21 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,32 +59,22 @@ export const buildIcons = async () => {
await $`mkdir lib`;

let libExport = "";
let definitions = `import type { SvelteComponentTyped } from "svelte";
let definitions = `import type { Component } from "svelte";
import type { SvelteHTMLElements } from "svelte/elements";
type RestProps = SvelteHTMLElements["svg"];
export interface CarbonIconProps extends RestProps {
/**
* Specify the icon size.
* @default 16
*/
size?: 16 | 20 | 24 | 32;
export type CarbonIconProps = SvelteHTMLElements["svg"] & {
/**
* Specify the icon title.
* @default undefined
*/
title?: string;
[key: \`data-\${string}\`]: any;
}
export declare class CarbonIcon extends SvelteComponentTyped<
CarbonIconProps,
Record<string, any>,
{}
> {}\n\n`;
/**
* Specify the icon size.
* @default 16
*/
size?: 16 | 20 | 24 | 32;
}\n\n`;

type Size = "glyph" | "icon";

Expand Down Expand Up @@ -122,7 +112,7 @@ export declare class CarbonIcon extends SvelteComponentTyped<

byModuleName[name] = templateSvg(icon);
libExport += `export { default as ${name} } from "./${name}.svelte";\n`;
definitions += `export declare class ${name} extends CarbonIcon {}\n`;
definitions += `export declare const ${name}: Component<CarbonIconProps>;\n`;

const fileName = `lib/${name}.svelte`;

Expand All @@ -149,8 +139,8 @@ ${definitions}`
`# Icon Index\n
> ${total} icons from ${version}\n
${iconModuleNames
.map((moduleName) => `- ${moduleName.replace(/^\_/, "\\_")}`)
.join("\n")}\n`
.map((moduleName) => `- ${moduleName.replace(/^\_/, "\\_")}`)
.join("\n")}\n`
);

await Bun.write(
Expand Down
35 changes: 0 additions & 35 deletions tests/svelte@3/Icons.svelte

This file was deleted.

116 changes: 0 additions & 116 deletions tests/svelte@3/bun.lock

This file was deleted.

15 changes: 0 additions & 15 deletions tests/svelte@3/package.json

This file was deleted.

16 changes: 0 additions & 16 deletions tests/svelte@3/tsconfig.json

This file was deleted.

23 changes: 19 additions & 4 deletions tests/svelte@4/Icons.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,30 @@
} from "carbon-icons-svelte";
import type { CarbonIconProps } from "carbon-icons-svelte";
import Icon from "carbon-icons-svelte/lib/Accessibility.svelte";
import { mount } from "svelte";
const props: CarbonIconProps = {
// Use the exported `CarbonIconProps` type for typing objects since the
// idiomatic `ComponentProps` utility is not compatible with `Component` in Svelte 4.
const props = {
size: 32,
fill: "red",
};
"data-test": "id",
} satisfies CarbonIconProps;
const icon = new Icon({ target: document.body, props });
// Instead, you can use a const assertion for type safety.
const component_props = {
size: 16,
fill: "red",
"data-test": "id",
} as const;
// @ts-expect-error (Svelte components are no longer classes)
// See https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes
const icon_class = new Icon({ target: document.body, props });
// Instead, use the `mount` function to manually instantiate the component.
mount(Icon, { target: document.body, props: component_props });
$: console.log(icon.$$prop_def);
$: console.log(typeof Assembly);
</script>

Expand Down
27 changes: 23 additions & 4 deletions tests/svelte@5/Icons.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,29 @@
import type { CarbonIconProps } from "carbon-icons-svelte";
import Icon from "carbon-icons-svelte/lib/Accessibility.svelte";
import { mount } from "svelte";
import type { ComponentProps } from "svelte";
const props: CarbonIconProps = {
// You can use the exported `CarbonIconProps` type.
const props = {
size: 32,
fill: "red",
};
"data-test": "id",
} satisfies CarbonIconProps;
const icon = mount(Icon, { target: document.body, props });
// Or, you can use the idiomatic `ComponentProps` utility.
const component_props = {
size: 16,
fill: "red",
"data-test": "id",
} satisfies ComponentProps<typeof Icon>;
// @ts-expect-error (Svelte components are no longer classes)
// See https://svelte.dev/docs/svelte/v5-migration-guide#Components-are-no-longer-classes
const icon_class = new Icon(props);
// Instead, use the `mount` function to manually instantiate the component.
mount(Icon, { target: document.body, props: component_props });
$: console.log(icon.$$prop_def);
$: console.log(typeof Assembly);
</script>

Expand All @@ -33,4 +47,9 @@
<Plan />
<ZSystems />
<BatchJob />

<!--
Note that `svelte:component` is no longer needed in Svelte 5.
https://svelte.dev/docs/svelte/v5-migration-guide#Breaking-changes-in-runes-mode-svelte:component-is-no-longer-necessary
-->
<svelte:component this={Beta} />

0 comments on commit fa04bd2

Please sign in to comment.