Skip to content

Commit 999fbce

Browse files
committed
Aside: Add support for icon attribute to markdown shorthand.
1 parent 5ff47bc commit 999fbce

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

docs/src/content/docs/guides/authoring-content.md

+14
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,20 @@ Astro helps you build faster websites with [“Islands Architecture”](https://
151151
:::
152152
```
153153

154+
### Custom aside icons
155+
156+
You can specify a custom icon for the aside in curly brackets following the aside type/title, e.g. `:::tip[Did you know?]{icon="heart"}`.
157+
158+
:::tip[Did you know?]{icon="heart"}
159+
Astro helps you build faster websites with [“Islands Architecture”](https://docs.astro.build/en/concepts/islands/).
160+
:::
161+
162+
```md
163+
:::tip[Did you know?]{icon="heart"}
164+
Astro helps you build faster websites with [“Islands Architecture”](https://docs.astro.build/en/concepts/islands/).
165+
:::
166+
```
167+
154168
### More aside types
155169

156170
Caution and danger asides are helpful for drawing a user’s attention to details that may trip them up.

packages/starlight/__tests__/remark-rehype/asides.test.ts

+23
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,29 @@ Some text
103103
);
104104
});
105105

106+
describe('custom icons', () => {
107+
test.each(['note', 'tip', 'caution', 'danger'])('%s with custom label', async (type) => {
108+
const res = await processor.render(`
109+
:::${type}{icon="heart"}
110+
Some text
111+
:::
112+
`);
113+
expect(res.code).includes(
114+
'M20.16 5A6.29 6.29 0 0 0 12 4.36a6.27 6.27 0 0 0-8.16 9.48l6.21 6.22a2.78 2.78 0 0 0 3.9 0l6.21-6.22a6.27 6.27 0 0 0 0-8.84m-1.41 7.46-6.21 6.21a.76.76 0 0 1-1.08 0l-6.21-6.24a4.29 4.29 0 0 1 0-6 4.27 4.27 0 0 1 6 0 1 1 0 0 0 1.42 0 4.27 4.27 0 0 1 6 0 4.29 4.29 0 0 1 .08 6Z'
115+
);
116+
117+
expect(async () =>
118+
processor.render(`
119+
:::${type}{icon="invalid-icon-name"}
120+
Some text
121+
:::
122+
`)
123+
).rejects.toThrowError(
124+
'Failed to parse Markdown file "undefined":\nIcon name should be part of Starlight\'s icon list.'
125+
);
126+
});
127+
});
128+
106129
test('ignores unknown directive variants', async () => {
107130
const res = await processor.render(`
108131
:::unknown

packages/starlight/integrations/asides.ts

+19-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@ import { visit } from 'unist-util-visit';
1717
import type { StarlightConfig } from '../types';
1818
import type { createTranslationSystemFromFs } from '../utils/translations-fs';
1919
import { pathToLocale } from './shared/pathToLocale';
20+
import { Icons } from '../components/Icons';
21+
import { fromHtml } from 'hast-util-from-html';
22+
import type { Element } from 'hast';
23+
import { AstroError } from 'astro/errors';
2024

2125
interface AsidesOptions {
2226
starlightConfig: { locales: StarlightConfig['locales'] };
@@ -150,6 +154,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
150154
return;
151155
}
152156
const variant = node.name;
157+
const attributes = node.attributes;
153158
if (!isAsideVariant(variant)) return;
154159

155160
// remark-directive converts a container’s “label” to a paragraph added as the head of its
@@ -171,6 +176,19 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
171176
node.children.splice(0, 1);
172177
}
173178

179+
let iconPath = iconPaths[variant];
180+
if (attributes) {
181+
if (attributes['icon']) {
182+
const iconName = attributes['icon'] as keyof typeof Icons;
183+
if (!Object.keys(Icons).includes(iconName)) {
184+
throw new AstroError("Icon name should be part of Starlight's icon list.");
185+
}
186+
const { properties } = fromHtml(Icons[iconName], { fragment: true })
187+
.children[0] as Element;
188+
iconPath = [s('path', properties)];
189+
}
190+
}
191+
174192
const aside = h(
175193
'aside',
176194
{
@@ -188,7 +206,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
188206
fill: 'currentColor',
189207
class: 'starlight-aside__icon',
190208
},
191-
iconPaths[variant]
209+
iconPath
192210
),
193211
...titleNode,
194212
]),

0 commit comments

Comments
 (0)