Skip to content

Commit

Permalink
Allow Code Component to have custom props and extra class styles (#9960)
Browse files Browse the repository at this point in the history
* 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>
  • Loading branch information
3 people committed Mar 8, 2024
1 parent 01497f2 commit c081adf
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 4 deletions.
6 changes: 6 additions & 0 deletions .changeset/calm-bags-deliver.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
---
"@astrojs/markdown-remark": minor
"astro": minor
---

Allows passing any props to the `<Code />` component
5 changes: 4 additions & 1 deletion packages/astro/components/Code.astro
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@ import type {
} from 'shiki';
import { bundledLanguages } from 'shiki/langs';
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. */
code: string;
/**
Expand Down Expand Up @@ -58,6 +59,7 @@ const {
themes = {},
wrap = false,
inline = false,
...rest
} = Astro.props;
// shiki 1.0 compat
Expand Down Expand Up @@ -87,6 +89,7 @@ const highlighter = await getCachedHighlighter({
const html = highlighter.highlight(code, typeof lang === 'string' ? lang : lang.name, {
inline,
attributes: rest,
});
---

Expand Down
17 changes: 14 additions & 3 deletions packages/markdown/remark/src/shiki.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,11 @@ import { visit } from 'unist-util-visit';
import type { ShikiConfig } from './types.js';

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
Expand Down Expand Up @@ -60,8 +64,15 @@ export async function createShikiHighlighter({
node.tagName = 'code';
}

const classValue = normalizePropAsString(node.properties.class) ?? '';
const styleValue = normalizePropAsString(node.properties.style) ?? '';
const { class: attributesClass, style: attributesStyle, ...rest } = options?.attributes ?? {};
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"
node.properties.class = classValue.replace(/shiki/g, 'astro-code');
Expand Down

0 comments on commit c081adf

Please sign in to comment.