docusaurus
docusaurus copied to clipboard
Global toggle code wrap button
Have you read the Contributing Guidelines on issues?
- [X] I have read the Contributing Guidelines on issues.
Motivation
Code wrap buttons have been implemented: https://github.com/facebook/docusaurus/pull/7036
The thing is that it is a little cumbersome if this needs to be done on each codeblock individually. This proposal is that this setting will be stored globally to set it to the users needs.
Self-service
- [X] I'd be willing to do some initial work on this proposal myself.
We probably won't add a button (otherwise we need a "user control panel", which may not be a totally bad idea, like how MUI is doing it). But a global option seems worthwhile.
Why would you want to wrap the code? I've almost never wanted to wrap it.
Oh I am sorry. It seems this went sideways. What I meant is when the user toggles one it should toggle all others too (to be clear, I am also not a big fan of wrapping it - but some of our customers are now using the feature as it got shipped with docusaurus).
Basically only this line would be touched: https://github.com/facebook/docusaurus/blob/main/packages/docusaurus-theme-common/src/hooks/useCodeWordWrap.ts#L61
E.g.:
- const [isEnabled, setIsEnabled] = useState(false);
+ const [isEnabled, setIsEnabled] = useLocalstorageState(false);
Oh, I see your point. Would you be happy with a theme option that syncs the wrap state between all code blocks?
Of course that would be ideal.
Others looking for a similar feature:
@jaredcbaum in https://github.com/facebook/docusaurus/discussions/5468#discussioncomment-3264663
@jgoux in https://github.com/facebook/docusaurus/discussions/7769
Please help us decide what should be done so that all of you are satisfied ;)
I would propose a new theme configuration. I think with these everything should be covered:
{
codeBlockOptions: {
// this identifies if the code block should be wrapped or not on the first page load
defaultAppearance: 'default' | 'wrapped'; // default: 'default'
// if the wrap state should be stored globally or not
enableWrapSync: boolean; // default: false
// enables or disables the visual representation of the code wrap
showWrap: boolean; // default: true
};
}
{
codeBlock: {
// Option to show copy button
showCopy: boolean; // default true
// Option to show wrap button
showWrap: boolean; // default true
// Option to control default wrapping
defaultWrap: boolean; // default false;
}
}
IMHO this would be an ideal config setup for code blocks. Since these options would be in docusaurus.config.js
, it can be assumed that these options are global. They could be overridden on a per instance basis by passing options to the CodeBlock component or a per page basis with a frontmatter value.
I like that! The only thing I miss is the localStorage/global sync (which was the origin of this issue).
I noticed in #7769 it was suggested that this could be enabled/forced for a single code block. I have the odd code block where it makes sense to have it forced on, or at least enabled by default.
So this syntax (or similar) would be great for me:
```bash wordWrap=true
...
```
Example: https://docs.snowplow.io/docs/collecting-data/collecting-from-own-applications/javascript-trackers/javascript-tracker/javascript-tracker-v3/tracker-setup/loading/
I could also add some linebreaks 🤷
However, most snippets are far better with word wrap disabled, so I wouldn't really want to change the default for the whole site, or to even remember it page by page.
I'm also looking forward to this feature
+1 vote for this feature
+1 for this. all our code tabs are scrolling. i would really hope for a way that we can enable word wrap on page load.
+1 I need this code block wrapping by default for my Docusaurus site.
+1. We all need this feature.
+1 I need it too
+1 for this feature too!
+1!
We started working on this in https://github.com/facebook/docusaurus/pull/9349, and a few questions arise because there are orthogonal needs
- Should we always sync and persist in localStorage at the same time, or are these different features? IE could we sync the setting between code blocks without persisting the last choice, and vice versa?
- Is sync/persistence opt-in or always enabled?
- Should sync and/or persistence be enabled on a case-by-case basis, similar to how tabs work?
- Do we need both a global site setting, and a code block meta-string param
- If a global and/or meta string value is provided, and a localStorage value exist, what should be the value we use? We have 3 sources available to provide that value and need to figure a rule here.
As you can see, there are still design elements to discuss.
On the technical side, there are also important UX details to consider:
- We need to ensure there's no layout shifts due to the sync when we click on the code wrap button (similar case to tabs we had in the past: the button position shifts and does not stay under user cursor)
- We need to ensure a good React hydration experience. We don't want code blocks to initially appear with scrollbars and then shift to wrapping, producing layout shifts