0
Fork 0
mirror of https://github.com/withastro/astro.git synced 2024-12-16 21:46:22 -05:00

Allow Code Component to have custom props and extra class styles (#9960)

* Create simple react element if element has no children

* Fix for when element has text

* add changeset

* Add additionalProps to Code component and ShikiHighlighter.highlight()

* Add changeset

* Create simple react element if element has no children

* Fix for when element has text

* add changeset

* Add additionalProps to Code component and ShikiHighlighter.highlight()

* Add changeset

* reverted accidental changes

* remove unnecessary parts

* Add HTMLAttributes type to additionalProps

* Update .changeset/calm-bags-deliver.md

Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>

* extend HTMLAtts instead

* add suggestions

* feat: address reviews

* chore: remove empty line

* feat: move attributes to options

---------

Co-authored-by: Florian Lefebvre <contact@florian-lefebvre.dev>
Co-authored-by: Emanuele Stoppa <my.burning@gmail.com>
This commit is contained in:
StandardGage 2024-03-08 08:02:53 -05:00 committed by GitHub
parent 01497f2bc2
commit c081adf998
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 24 additions and 4 deletions

View file

@ -0,0 +1,6 @@
---
"@astrojs/markdown-remark": minor
"astro": minor
---
Allows passing any props to the `<Code />` component

View file

@ -9,8 +9,9 @@ import type {
} from 'shiki'; } from 'shiki';
import { bundledLanguages } from 'shiki/langs'; import { bundledLanguages } from 'shiki/langs';
import { getCachedHighlighter } from '../dist/core/shiki.js'; import { getCachedHighlighter } from '../dist/core/shiki.js';
import type { HTMLAttributes } from '../types';
interface Props { interface Props extends Omit<HTMLAttributes<'pre'>, 'lang'> {
/** The code to highlight. Required. */ /** The code to highlight. Required. */
code: string; code: string;
/** /**
@ -58,6 +59,7 @@ const {
themes = {}, themes = {},
wrap = false, wrap = false,
inline = false, inline = false,
...rest
} = Astro.props; } = Astro.props;
// shiki 1.0 compat // shiki 1.0 compat
@ -87,6 +89,7 @@ const highlighter = await getCachedHighlighter({
const html = highlighter.highlight(code, typeof lang === 'string' ? lang : lang.name, { const html = highlighter.highlight(code, typeof lang === 'string' ? lang : lang.name, {
inline, inline,
attributes: rest,
}); });
--- ---

View file

@ -4,7 +4,11 @@ import { visit } from 'unist-util-visit';
import type { ShikiConfig } from './types.js'; import type { ShikiConfig } from './types.js';
export interface ShikiHighlighter { export interface ShikiHighlighter {
highlight(code: string, lang?: string, options?: { inline?: boolean }): string; highlight(
code: string,
lang?: string,
options?: { inline?: boolean; attributes?: Record<string, string> }
): string;
} }
// TODO: Remove this special replacement in Astro 5 // TODO: Remove this special replacement in Astro 5
@ -60,8 +64,15 @@ export async function createShikiHighlighter({
node.tagName = 'code'; node.tagName = 'code';
} }
const classValue = normalizePropAsString(node.properties.class) ?? ''; const { class: attributesClass, style: attributesStyle, ...rest } = options?.attributes ?? {};
const styleValue = normalizePropAsString(node.properties.style) ?? ''; Object.assign(node.properties, rest);
const classValue =
(normalizePropAsString(node.properties.class) ?? '') +
(attributesClass ? ` ${attributesClass}` : '');
const styleValue =
(normalizePropAsString(node.properties.style) ?? '') +
(attributesStyle ? `; ${attributesStyle}` : '');
// Replace "shiki" class naming with "astro-code" // Replace "shiki" class naming with "astro-code"
node.properties.class = classValue.replace(/shiki/g, 'astro-code'); node.properties.class = classValue.replace(/shiki/g, 'astro-code');