Closed XIYO closed 1 month ago
Light and dark themes are not suitable for environments without JavaScript. If additional styling is needed, custom styles will eventually have to be written.
Why? Styling with CSS doesn't require JavaScript at all.
And you can use @media (prefers-color-scheme: dark)
to implement dark mode support without JavaScript.
Also, I think your "Additional context" isn't quite related to your issue:
If you use Shiki to highlight Markdown/MDX code blocks, why don't use parseMetaString
from Rehype Shiki to parse meta string and add these properties? (e.g. title
)
Properties in the meta object will be added to pre
element via data attributes and you can handle that with a custom pre
component, or using CSS.
/**
* Custom meta string values
*/
const metaValues = [
{
name: 'title',
regex: /title="(?<value>[^"]*)"/,
},
];
export const rehypeCodeDefaultOptions: RehypeCodeOptions = {
parseMetaString(meta) {
const map: Record<string, string> = {};
for (const value of metaValues) {
const result = value.regex.exec(meta);
if (result) {
map[value.name] = result[1];
}
}
return map;
},
};
It seems that my initial explanation was a bit complex. To clarify:
I believe it would be better to give users the option to choose inline styles for code, as it provides more flexibility.
Currently, it’s possible to make everything work purely with CSS by creating a theme.json
file where you can input values like "breadcrumb.background": "light-dark(#282A36, #181818)"
. This way, a single theme can support both light and dark modes, potentially being referred to as dracula-light-dark
.
Consider this design:
<figure>
<div>index.js</div>
<pre><code>~~</code></pre>
<figcaption>caption</figcaption>
</figure>
When writing code, there are times when you need a title or some element that indicates which file the code belongs to. However, if you want the style to share the same color as <pre>
, you would need to declare the CSS separately, using the background color value from the JSON file where the Shiki theme is set.
But if both the code style and the decorative style are declared in an external CSS file (using classes), you can avoid the mistake of forgetting to update the decorative style when changing the Shiki theme.
The final result can still be designed to appear as intended, but I’ve created this issue because I believe it would be helpful to have the option to output styles as classes. If this suggestion doesn’t align with the project’s direction, please feel free to disregard it.
As I’m not a native English speaker, I used GPT to translate my message. If anything is unclear or seems off, please let me know, and I will revise it to be more specific and clear.
Guess you're just looking for:
Same as above, add title
to the data attributes of pre
with parseMetaString
:
/**
* Custom meta string values
*/
const metaValues = [
{
name: 'title',
regex: /title="(?<value>[^"]*)"/,
},
];
export const rehypeCodeDefaultOptions: RehypeCodeOptions = {
parseMetaString(meta) {
const map: Record<string, string> = {};
for (const value of metaValues) {
const result = value.regex.exec(meta);
if (result) {
map[value.name] = result[1];
}
}
return map;
},
};
So it's up to you on how to handle the output hast tree.
With React/Vue, you can use hast-util-to-jsx-runtime to render a custom code block component by overriding pre
. It can read the props from pre
which solved your problem.
With MDX.js, you can simply override the pre
element on MDX components same as using hast-util-to-jsx-runtime
.
If you want a full example, I built a codeblock for my projects. You can basically see all props are passed to CodeBlock
and handled by itself.
If you only need HTML, maybe a Rehype plugin or Shiki transformer will be required to transform the hast tree. But TLDR; Personally, I would just suggest to use MDX, vanilla React, and Vue
Since I'm using a translation tool, the meaning might be slightly altered. I strive to convey the content in a straightforward manner, but if the context seems off, please let me know, and I will rephrase it to better communicate my intention.
First of all, thank you for taking an interest in my issue and for your response.
Here’s what I initially intended:
class:none
, I expected that classes would be added to the output (or that styling could be controlled externally).js data-title="hi"
value is used in the code block’s meta, it would output as <pre data-title="hi">
.The intention behind point 1 was to control styling externally rather than using inline styles. As for point 2, based on the overall response, it seems that this functionality is already possible, and I was able to achieve the desired result after reading your reply (though I did need to write additional styles, which increased the management points, either by creating a shiki.css
or adding code to the existing root styles).
The overall intention of my question was to ask for a feature that allows styling to be managed through a single point by using class-based styling instead of inline styles.
Thank you for reading.
P.S. Since I don’t fully understand how Shiki works internally, I might be making an incorrect request. If my explanation is unclear, I would be happy to illustrate it with diagrams. If my issue is out of line with the direction Shiki is heading, please feel free to close it at any time.
When using the value class:none, I expected that classes would be added to the output (or that styling could be controlled externally).
You can enable dual themes for this, pass defaultColor: false
and themes: { light: theme }
.
Check https://github.com/shikijs/shiki/issues/742
This makes Shiki to add CSS variables instead of inline styles, you can do further styling with it.
Although it wasn't exactly what I initially requested, I found a way to control the styles from a single CSS file, as mentioned in this documentation: https://shiki.style/guide/theme-colors#css-variables-theme (though it’s not an official feature 🥲).
Thank you for taking the time to respond. Wishing you a great day!
Clear and concise description of the problem
Light and dark themes are not suitable for environments without JavaScript. If additional styling is needed, custom styles will eventually have to be written.
Suggested solution
When using
theme: none
, Shiki does not apply inline styles, so it’s necessary to create classes for Shiki. You can then solve styling issues by directly importing the necessary styles:Alternative
highlightjs
Additional context
Hello,
I find Shiki's transform functionality incredibly impressive. However, after using it, I noticed a few areas that could benefit from improvement:
This brings me to the following idea:
I’ve always felt that a title is necessary for code blocks.
For instance, with syntax like:
When transformed, it could output something like:
This would make it easier to implement such features. Currently, managing styling is difficult due to the need for dual styling.
Although creating classes for
theme: none
to output seems beyond my current capabilities, I am able to contribute by addingdata-set
viatransform
.Validations
Contributes