code-hike / bright Goto Github PK
View Code? Open in Web Editor NEWReact Server Component for syntax highlighting
Home Page: https://bright.codehike.org
React Server Component for syntax highlighting
Home Page: https://bright.codehike.org
Looking at the codehike docs, I see that it supports adding the language and the filename to codeblocks https://codehike.org/docs/codeblocks#filename.
I was digging around trying to figure out how bright parses what is passed into the codeblock and got stumped.
I took the example from https://github.com/code-hike/bright/blob/main/web/app/test-mdx/mdx-demo.mdx#L17-L20 and changed it to be js web/shine.js
. Then I tried to discover the entry point into everything, which to the best I could figure out was Code
(https://github.com/code-hike/bright/blob/main/lib/src/index.tsx#L26). However, when printing out the componentProps
in Code
I got
what are componentProps? {
children: {
'$$typeof': Symbol(react.element),
type: 'code',
key: null,
ref: null,
props: {
className: 'language-js',
children: 'let hello = "hello brightness"\nconsole.log(hello, "my old friend")\n'
},
_owner: null,
_store: {}
}
}
Thus I'm assuming that this parsing is happening outside of this library, perhaps in @mdx-js/react
?
Totally willing to continue working on this and potentially submit a PR (if it is possible) if I could get some help on what the next step would be.
Without using plugins we only get the language from the metastring. But what if we use the language to pass options?
```js(title=foo.js,lineNumbers=true,whatever=14)
const lorem = "ipsum"
```
Hello!
When I have whitespace with a normal <Code>
block like so:
<Code>{`
┌───────┐
│0|0|1|0│ 2 (media)
└───────┘
┌───────┐
│0|1|0|0│ 4 (productivity)
└───────┘
`;}</Code>
the leadering/trailing whitespace is preserved no problem.
But if I use <Code>
in Markdown it goes down this code path and the code whitespace is trimmed. Any idea why this .trim()
happens in this code path? Doesn't seem like it should ever make sense to trim whitespace in the code?
I can submit a PR to remove it and add tests if that makes sense?
Is there a way to use CSS variables in the theme definition?
Say I have a code sample like so
# focus(1)
aws configure
AWS Access Key ID [****************e53q]: <<yourAccessKey>>
AWS Secret Access Key [****************bbxq]: <<yourSecretKey>>
Default region name [us-east-1]:
Default output format [None]:
I have a copy button for the code snippet, but I don't want it to include # focus(1)
when it's copied. Is there function in bright to remove comments used for annotation?
Thanks
Maybe add an optional fallback with the right background and foreground until the code is highlighted.
<Suspense fallback={<Fallback {...props}/>}>
<Code {...props}/>
</Suspense>
../../node_modules/@code-hike/lighter/dist/browser.esm.mjs:16:24
Module not found: Can't resolve 'https'
https://nextjs.org/docs/messages/module-not-found
Import trace for requested module:
../../node_modules/bright/dist/index.mjs
I haven't had time to put together a demo to easily replicate. I will try to do this if it would be helpful, but thought I should just submit this issue to put it on your radar as soon as possible nonetheless.
Some Node.js APIs other than the ones listed above are not supported. For example, you can't read or write to the filesystem
https://vercel.com/docs/concepts/functions/edge-functions/edge-runtime#unsupported-apis
(Https is not listed)
I want to format the code using the Prettier API. I am using Next.js Server Component. I am trying to implement it within the beforeHighlight function in the extensions hook. However, the issue arises because the Prettier format function returns a promise, whereas beforeHighlight does not expect a promise.
How can I resolve this problem? I prefer not to place the Prettier logic in the client component. Can anyone please assist me with this?
Isn't nice if somehow beforeHighlight function resolve the promise, then the problem would be solved very easily.
I wanted to reduce the padding for <pre>
, this didn't work for me
<Code
{...props}
extensions={[
{
name: "pre",
Pre: (props: BrightProps) => (
<Code.Pre style={{ border : "5px solid red" }} className="my-32 ring-8" {...props} />
),
},
]}
/>
Also this
<Code
{...props}
name: "pre",
Pre={(props: BrightProps) => (
<Code.Pre style={{ border : "5px solid red" }} className="my-32 ring-8" {...props} />
)}
/>
Usage:
<Code>
<div>asd</div>
</Code>
Tested in Next.js 13.4.14 Server Component
Errors:
- error TypeError: Cannot read properties of undefined (reading 'children')
at eval (../bright/lib/src/index.tsx:179:53)
at Array.map (<anonymous>)
at parseChildren (../bright/lib/src/index.tsx:176:88)
at Code (../bright/lib/src/index.tsx:34:31)
at stringify (<anonymous>)
digest: "1512087678"
203 | const codeProps = c.props?.children?.props
204 | return {
> 205 | code: trimTrailingNewline(codeProps.children),
| ^
206 | ...getLanguageAndTitle(codeProps.className),
207 | }
208 | })
this error is using bright/src not bright/dist
Tried DefinitelyTyped/DefinitelyTyped#65003, but we need to wait for microsoft/TypeScript#51328 (TypeScript 5.1 will make Promise<ReactNode>
a valid return type for components)
Can support for autolink
be added to bright
like it is in codehike
(code-hike/codehike#356)?
Just out of curiosity,
Did you create all-grammars by yourself or is it a collection that you took from some other source ?
https://github.com/code-hike/bright/blob/main/packages/bright/src/all-grammars.js
Hello there. I like this library and the docs site is great.
I'm trying to use this in a next.js site using getStaticProps
but it doesn't seem to work.
'server-only' cannot be imported from a Client Component module. It should only be used from a Server Component.
Is there a reason this wouldn't work when a static next site is being generated? Previously I was using rehype/remark which is all "server-side" JS and it works fine via getStaticProps
Is there something special going on with the renderer or could it be used 1 off during builds inside a getStaticProps
function
Thanks.
I have a use case where some code examples need to be rendered server-side and others client-side.
It would be nice if I could use the same package for both.
can you for example i want to document any react component
i pass it as state with it import and everything ,
it return me the full code of it utisliation and example usage "the user shold enter it"
Thanks for this amazingly easy to use library!
I'm having one issue which is that themes don't seem to work when I give them custom names. I'm trying to use this with Next.js.
mdx-components.tsx:
// ❌ doesn't work ❌
Code.theme = {
"eighties": "dracula", // and corresponding data-theme="eighties"
"nineties": "solarized-light",
};
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
pre: Code,
};
}
But if I use dark/light it works fine:
mdx-components.tsx:
// ✅ works ✅
Code.theme = {
dark: "dracula", // and corresponding data-theme="dark"
light: "solarized-light",
};
export function useMDXComponents(components: MDXComponents): MDXComponents {
return {
...components,
pre: Code,
};
}
If I try the former and not the latter, I don't get theming (my code blocks have a dark background and light text with no syntax highlighting).
Is this expected and I'm just misunderstanding the docs?
Hey there!
Is it possible to highlight/focus/mark a line of text using Bright? I see the annotations
and extensions
config options but I'm having trouble understand how they're supposed to work.
Usage:
<Code>
Hello <span className="bg-red">world</span>
</Code>
I just want to highlight code. And rest is custom component how to do that ?
Add support for:
```foo.js
const x = 1
```
Should be the same as:
<Code lang="js" title="foo.js">const x = 1</Code>
I'm using bright in a project where dark mode is done by adding the "dark" or "light" class to the html, but bright isn't following the project's theme. At the moment it only works if I add a data-theme.
Hey, Thank you for the great package! We're using Bright in Waku and we stumbled upon a bug with autoprefixer where the inline styles get prefixed and React on the client side will have a mismatch error.
What renders in the server with no prefixing. This is also the client's result.
<style>
[data-bright-theme] ::selection { background-color: var(--selection-background) }
</style>
Server, but after prefixing.
<style>
[data-bright-theme] ::-moz-selection { background-color: var(--selection-background) }
[data-bright-theme] ::selection { background-color: var(--selection-background) }
</style>
For us, the temporary solution was to disable autoprefixer for the official website. dai-shi/waku#426
What can be done in bright itself, is using control comments https://github.com/postcss/autoprefixer?tab=readme-ov-file#control-comments and disabling autoprefixing for that specific inline style.
Curious how people are handling long lines
Monaco top, Bright bottom here:
Standard line wrapping acts as predicted:
Monaco wraps these as a new line if they don't fit the current line
Overflow-scroll on the container is an option, though would be a better option if line numbers could be made sticky
I don't know how the docs are styled so I'm just going to suggest the improvement here.
Instead of the current docs for "Custom Theme":
Code.theme = {
name: "myTheme"
}
It might be helpful to mention that you import the theme and pass that in, instead of a theme name, e.g.:
import myCustomTheme from "my-custom-theme.json";
Code.theme = myCustomTheme;
Customizing the lightSelector
config option is the only way to switch between light/dark mode, right?
There's no way to make the switch happen automatically with prefers-color-scheme
, right? To just use the OS setting?
I'm currently using Markdoc to pregenerate markdown on the server. I'm curious if I could use this library to process my code blocks. Would it be possible to get a sample of calling the library outside of JSX?
Here's a repro of the issue: https://codesandbox.io/p/sandbox/2spsii?file=%2Fapp%2Fmdx%2F%5Bslug%5D%2Fpage.tsx%3A10%2C19
(click the link when it's opened)
Error:
Error: This module cannot be imported from a Client Component module. It should only be used from a Server Component.
The problem appears to be that the Bright component doesn't work when dynamically imported from a server component. It thinks it is in a client component even though it isn't.
My code works fine without Bright. I can dynamically import the mdx component from my server component.
className
bug (fixed in v0.7.1)I'm encountering a problem with next-mdx-remote/rsc
when I don't have a language specified in my codeblocks.
The failure is here because className
is not defined:
Line 183 in 1bae07b
Some console.logs have shown me there is no className
if no language is passed.
There's also a type error with next-mdx-remote
's components["pre"]
type and the Code
type from this lib (separate from the element being a promise/RSC):
Type bug with next-mdx-remote:
(property) pre?: keyof JSX.IntrinsicElements | Component<DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>> | undefined
Type 'CodeComponent' is not assignable to type 'keyof IntrinsicElements | Component<DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>> | undefined'.
Type 'CodeComponent' is not assignable to type 'FunctionComponent<DetailedHTMLProps<HTMLAttributes<HTMLPreElement>, HTMLPreElement>>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'ClassAttributes<HTMLPreElement> & HTMLAttributes<HTMLPreElement>' is missing the following properties from type '{ style?: CSSProperties | undefined; title?: string | undefined; Pre: (brightProps: { code: string; style?: CSSProperties | undefined; title?: string | undefined; ... 17 more ...; subProps?: Partial<...>[] | undefined; }) => Element; ... 14 more ...; code?: string | undefined; }': Pre, Root, TitleBarContent, Tab, and 4 more.
I'm not sure on the correct types, but something seems off here and I feel like JSX.Element
or ReactNode
and utils like React.PropsWithChildren
should be used. I'll open a PR soon with a quick fix for my problem. I guess another alternative is default the lang to plaintext
(and add support for that to the relevant upstream)
This line of code have bug when I debug, the codeProps print result is undefined.
May be the correct code like this, I don't know why get children's props, the children is string actually in my case
const codeProps = c.props?.children?.props ?? c.props
Is it usable with remix js ?
Following the instructions from https://bright.codehike.org/
import { Code } from "bright"
// You need this file to use MDX in server components
// Learn more from the Next.js docs
export function useMDXComponents(components) {
return { ...components, pre: Code }
}
I set this up and it is working great. I have .mdx
files where I'll do
here is some text `some_file_name.txt` some text
and it renders the HTML as <p>here is some text<code>some_file_name.txt</code> some text</p>
. I was trying to figure out how to change the styling of the <code>
tags. I followed the Next Mdx guide and did something simple like
code: ({children}) => <div>{children}</div>,
This breaks when bright
has been imported. When bright
is no imported, it works as expected (albeit looking quite weird).
Some related issues seem to be
code:
The error I see
Unhandled Runtime Error
Error: Cannot read properties of undefined (reading 'children')
Call Stack
children
node_modules/bright/dist/index.mjs (516:44)
Array.map
<anonymous>
map
node_modules/bright/dist/index.mjs (512:54)
I am using https://github.com/code-hike/bright/releases/tag/bright%400.8.4
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.