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

Expose StarlightIcon type #2805

Merged
merged 3 commits into from
Jan 17, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/unlucky-items-notice.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@astrojs/starlight': minor
---

Exposes the [`StarlightIcon`](https://starlight.astro.build/reference/icons/#starlighticon-type) TypeScript type referencing the names of Starlight’s built-in icons.
4 changes: 2 additions & 2 deletions docs/src/components/icons-list.astro
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
import { Icon } from '@astrojs/starlight/components';
import { Icons } from '../../../packages/starlight/components/Icons';
import { Icons, type StarlightIcon } from '../../../packages/starlight/components/Icons';
interface Props {
labels?: {
Expand All @@ -10,7 +10,7 @@ interface Props {
const { copied = 'Copied!' } = Astro.props.labels ?? {};
const icons = Object.keys(Icons) as (keyof typeof Icons)[];
const icons = Object.keys(Icons) as StarlightIcon[];
---

<div class="icons-grid" data-label-copied={copied}>
Expand Down
2 changes: 1 addition & 1 deletion docs/src/content/docs/components/icons.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ The `<Icon>` component accepts the following props:
### `name`

**required**
**type:** `string`
**type:** [`StarlightIcon`](/reference/icons/#starlighticon-type)

The name of the icon to display set to [one of Starlight’s built-in icons](/reference/icons/#all-icons).

Expand Down
6 changes: 3 additions & 3 deletions docs/src/content/docs/components/using-components.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -81,14 +81,14 @@ If these styles conflict with your component’s appearance, set the `not-conten
Use the [`ComponentProps`](https://docs.astro.build/en/guides/typescript/#componentprops-type) type from `astro/types` to reference the `Props` accepted by a component even if they are not exported by the component itself.
This can be helpful when wrapping or extending an existing component.

The following example uses `ComponentProps` to get the type of the props accepted by Starlight’s built-in `Icon` component:
The following example uses `ComponentProps` to get the type of the props accepted by Starlight’s built-in `Badge` component:

```astro
---
// src/components/Example.astro
import type { ComponentProps } from 'astro/types';
import { Icon } from '@astrojs/starlight/components';
import { Badge } from '@astrojs/starlight/components';
type IconProps = ComponentProps<typeof Icon>;
type BadgeProps = ComponentProps<typeof Badge>;
---
```
13 changes: 13 additions & 0 deletions docs/src/content/docs/reference/icons.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,19 @@ Starlight provides a set of built-in icons that you can display in your content
Icons can be displayed using the [`<Icon>`](/components/icons/) component.
They are also often used in other components, such as [cards](/components/cards/) or settings like [hero actions](/reference/frontmatter/#hero).

## `StarlightIcon` type

Use the `StarlightIcon` TypeScript type to reference the names of [Starlight’s built-in icons](#all-icons).

```ts {2} /icon: (StarlightIcon)/
// src/icon.ts
import type { StarlightIcon } from '@astrojs/starlight/types';

function getIconLabel(icon: StarlightIcon) {
//
}
```

## All icons

A list of all available icons is shown below with their associated names. Click an icon to copy its name to your clipboard.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { describe, expect, test } from 'vitest';
import { processFileTree } from '../../user-components/rehype-file-tree';
import { Icons } from '../../components/Icons';
import { Icons, type StarlightIcon } from '../../components/Icons';

describe('validation', () => {
test('throws an error with no content', () => {
Expand Down Expand Up @@ -176,6 +176,6 @@ function extractFileTree(html: string, stripIcons = true) {
return tree;
}

function expectHtmlToIncludeIcon(html: string, icon: (typeof Icons)[keyof typeof Icons]) {
function expectHtmlToIncludeIcon(html: string, icon: (typeof Icons)[StarlightIcon]) {
return expect(extractFileTree(html, false)).toContain(icon.replace('/>', '>'));
}
4 changes: 2 additions & 2 deletions packages/starlight/components/ContentNotice.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
import { Icons } from '../components/Icons';
import type { StarlightIcon } from '../components/Icons';
import Icon from '../user-components/Icon.astro';
interface Props {
icon: keyof typeof Icons;
icon: StarlightIcon;
label: string;
}
Expand Down
2 changes: 2 additions & 0 deletions packages/starlight/components/Icons.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,3 +185,5 @@ export const Icons = {
...BuiltInIcons,
...FileIcons,
};

export type StarlightIcon = keyof typeof Icons;
5 changes: 2 additions & 3 deletions packages/starlight/schemas/hero.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { z } from 'astro/zod';
import type { SchemaContext } from 'astro:content';
import { Icons } from '../components/Icons';
import { Icons, type StarlightIcon } from '../components/Icons';

type IconName = keyof typeof Icons;
const iconNames = Object.keys(Icons) as [IconName, ...IconName[]];
const iconNames = Object.keys(Icons) as [StarlightIcon, ...StarlightIcon[]];

export const HeroSchema = ({ image }: SchemaContext) =>
z.object({
Expand Down
1 change: 1 addition & 0 deletions packages/starlight/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@ export type {
StarlightPlugin,
StarlightUserConfigWithPlugins as StarlightUserConfig,
} from './utils/plugins';
export type { StarlightIcon } from './components/Icons';
4 changes: 2 additions & 2 deletions packages/starlight/user-components/Card.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
import Icon from './Icon.astro';
import type { Icons } from '../components/Icons';
import type { StarlightIcon } from '../components/Icons';
interface Props {
icon?: keyof typeof Icons;
icon?: StarlightIcon;
title: string;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/starlight/user-components/Icon.astro
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
---
import { Icons } from '../components/Icons';
import { Icons, type StarlightIcon } from '../components/Icons';
interface Props {
name: keyof typeof Icons;
name: StarlightIcon;
label?: string;
color?: string;
size?: string;
Expand Down
4 changes: 2 additions & 2 deletions packages/starlight/user-components/LinkButton.astro
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
---
import type { HTMLAttributes } from 'astro/types';
import { Icons } from '../components/Icons';
import type { StarlightIcon } from '../components/Icons';
import Icon from './Icon.astro';

interface Props extends Omit<HTMLAttributes<'a'>, 'href'> {
href: string | URL;
icon?: keyof typeof Icons | undefined;
icon?: StarlightIcon | undefined;
iconPlacement?: 'start' | 'end' | undefined;
variant?: 'primary' | 'secondary' | 'minimal';
}
Expand Down
4 changes: 2 additions & 2 deletions packages/starlight/user-components/TabItem.astro
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
---
import { TabItemTagname } from './rehype-tabs';
import type { Icons } from '../components/Icons';
import type { StarlightIcon } from '../components/Icons';
interface Props {
icon?: keyof typeof Icons;
icon?: StarlightIcon;
label: string;
}
Expand Down
4 changes: 2 additions & 2 deletions packages/starlight/user-components/rehype-file-tree.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { fromHtml } from 'hast-util-from-html';
import { toString } from 'hast-util-to-string';
import { rehype } from 'rehype';
import { CONTINUE, SKIP, visit } from 'unist-util-visit';
import { Icons } from '../components/Icons';
import { Icons, type StarlightIcon } from '../components/Icons';
import { definitions } from './file-tree-icons';

declare module 'vfile' {
Expand Down Expand Up @@ -160,7 +160,7 @@ function getFileIcon(fileName: string) {
const name = getFileIconName(fileName);
if (!name) return defaultFileIcon;
if (name in Icons) {
const path = Icons[name as keyof typeof Icons];
const path = Icons[name as StarlightIcon];
return makeSVGIcon(path);
}
return defaultFileIcon;
Expand Down
6 changes: 3 additions & 3 deletions packages/starlight/user-components/rehype-tabs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@ import type { Element } from 'hast';
import { select } from 'hast-util-select';
import { rehype } from 'rehype';
import { CONTINUE, SKIP, visit } from 'unist-util-visit';
import { Icons } from '../components/Icons';
import type { StarlightIcon } from '../components/Icons';

interface Panel {
panelId: string;
tabId: string;
label: string;
icon?: keyof typeof Icons;
icon?: StarlightIcon;
}

declare module 'vfile' {
Expand Down Expand Up @@ -67,7 +67,7 @@ const tabsProcessor = rehype()
...ids,
label: String(dataLabel),
};
if (dataIcon) panel.icon = String(dataIcon) as keyof typeof Icons;
if (dataIcon) panel.icon = String(dataIcon) as StarlightIcon;
file.data.panels?.push(panel);

// Remove `<TabItem>` props
Expand Down
Loading