Skip to content

Commit da7a1b7

Browse files
committed
Aside: Add support for icon attribute to markdown shorthand.
1 parent 2ee71dc commit da7a1b7

File tree

3 files changed

+56
-1
lines changed

3 files changed

+56
-1
lines changed

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

Lines changed: 14 additions & 0 deletions
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

Lines changed: 23 additions & 0 deletions
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

Lines changed: 19 additions & 1 deletion
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'] };
@@ -160,6 +164,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
160164
return;
161165
}
162166
const variant = node.name;
167+
const attributes = node.attributes;
163168
if (!isAsideVariant(variant)) return;
164169

165170
// remark-directive converts a container’s “label” to a paragraph added as the head of its
@@ -181,6 +186,19 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
181186
node.children.splice(0, 1);
182187
}
183188

189+
let iconPath = iconPaths[variant];
190+
if (attributes) {
191+
if (attributes['icon']) {
192+
const iconName = attributes['icon'] as keyof typeof Icons;
193+
if (!Object.keys(Icons).includes(iconName)) {
194+
throw new AstroError("Icon name should be part of Starlight's icon list.");
195+
}
196+
const { properties } = fromHtml(Icons[iconName], { fragment: true })
197+
.children[0] as Element;
198+
iconPath = [s('path', properties)];
199+
}
200+
}
201+
184202
const aside = h(
185203
'aside',
186204
{
@@ -198,7 +216,7 @@ function remarkAsides(options: AsidesOptions): Plugin<[], Root> {
198216
fill: 'currentColor',
199217
class: 'starlight-aside__icon',
200218
},
201-
iconPaths[variant]
219+
iconPath
202220
),
203221
...titleNode,
204222
]),

0 commit comments

Comments
 (0)