bright

repository·main·Indexed 23 days ago

https://github.com/code-hike/bright

A component-based code highlighting library designed for server-side environments like Next.js server components. It provides a suite of components including Code, BrightCode, Root, and Pre for rendering highlighted code blocks, along with support for custom themes, extensions, and diff views.

Tokens
3.9K
Snippets
9
Records
29
Agent score
81%

What's inside bright

  1. Use the Tabs component to create multi-language code blocks

    main

    The Tabs component allows you to group multiple code blocks under a single tabbed interface. This is useful for showing the same logic implemented in different languages or different file versions.

    To use it, wrap your code blocks within the <Tabs> component. Each code block inside the component will be treated as a separate tab. You can specify the tab title (e.g., the filename) using a comment at the top of the code block, such as // title filename.ext for JavaScript or # title filename.ext for Python.

    import { Tabs } from "./tabs"
    
    <Tabs>
    
    ```js
    // title foo.js
    function lorem(ipsum, dolor = 1) {
      const sit = ipsum == null ? 0 : ipsum.sit
      dolor = sit - amet(dolor)
      return dolor
    }
    # title bar.py
    def dolor_sit_amet(consectetur, adipiscing):
        if consectetur == "Lorem"
            print("Pellentesque habitant.")
        else:
            print("Suspendisse potenti.")

    </Tabs>

  2. Use the Code component in a Server Component

    main

    Bright is designed to be used within server components (for example, in Next.js app/page.js). Import the Code component and provide the lang prop to specify the programming language, followed by the code content as children.

    Docs: https://bright.codehike.org

    import { Code } from "bright"
    
    export default function Page() {
      return <Code lang="py">print("hello brightness")</Code>
    }
  3. Use the Diff component to show code changes

    main

    The <Diff> component allows you to display multiple code blocks as a comparison (diff). By wrapping several code blocks within a single <Diff> component, you can visually highlight the differences between them. This is useful for showing code evolutions, refactors, or bug fixes.

    import { Diff } from "./diff"
    
    <Diff>
    
    ```js
    function lorem(ipsum, dolor = 1) {
      const sit = ipsum == null ? 0 : ipsum.sit
      dolor = sit - amet(dolor)
      return dolor
    }
    function lorem(ipsum, dolor = 1) {
      const sit = 0
      dolor = sit - amet(dolor)
      dolor *= 2
      return dolor
    }

    </Diff>

  4. Understand CodeProps and BrightProps

    main

    Bright uses two primary property interfaces to manage the state of code blocks:

    1. CodeProps: The initial configuration passed to a component. It includes theme, lang, code, mode, extensions, annotations, and styling options like className and codeClassName.
    2. BrightProps: The properties available after the highlighting process has occurred. This includes computed data such as colors (derived from the theme), lines, and lineCount. This is the interface used by annotation components to access the processed state of the code.
  5. Use annotations in code blocks

    main

    You can apply annotations to specific ranges of code using comment-style syntax. This is useful for highlighting specific lines, marking text with colors, or injecting interactive elements.

    Common patterns include:

    • Marking ranges: // mark[start:end] color or /// mark[start:end] color.
    • Injecting values: /// number[start:end] to render an input or similar component.
    • Setting titles: // title filename.js to pass a filename to the component.
    /// mark[3:10] red
    console.log(1)
    /// number[11:12]
    const x = 20
  6. Extend Code component with custom extensions

    main

    You can customize how bright handles specific annotations by assigning an object to Code.extensions. This allows you to define custom behavior for different types of annotations (like mark, number, or title) using React components or functions that modify highlight properties.

    Supported extension types include:

    • Annotation types (e.g., mark): Provide a component that receives children and a query.
    • Value types (e.g., number): Provide a component that receives children and the raw content.
    • Lifecycle hooks (e.g., title): Provide functions like beforeHighlight to modify the properties passed to the highlighter.
    import { Code } from "bright"
    
    Code.extensions = {
      mark: {
        InlineAnnotation: ({ children, query }) => (
          <mark style={{ background: query }}>{children}</mark>
        ),
        MultilineAnnotation: ({ children, query }) => (
          <mark style={{ background: query }}>{children}</mark>
        ),
      },
      number: ({ children, content }) => (
        <input defaultValue={content} type="number" min={0} max={99} />
      ),
      title: {
        beforeHighlight: (props, query) => ({
          ...props,
          title: query,
        }),
      },
    }
    
    const myCode = `
    // mark[3:10] red
    console.log(1)
    // mark
    const x = 20
    `
    
    export default function Page() {
      return <Code lang="js">{myCode}</Code>
    }
  7. Use the Code component for syntax highlighting

    main

    The Code component is the primary entrypoint for rendering highlighted code blocks. It supports several usage patterns, including direct props, children as strings, and MDX-style integration. It automatically handles language detection and supports annotations and extensions.

    Usage Patterns:

    1. Direct Props: Pass code and lang directly.

      <Code code="console.log('hello')" lang="js" />
    2. Children as String: Pass the code block as children.

      <Code lang="js">console.log('hello')</Code>
    3. MDX Integration: Works with standard MDX code blocks by parsing className (e.g., language-js).

      <Code>
        <code className="language-js">console.log('hello')</code>
      </Code>
    4. Multiple Code Blocks (Tabs/Sub-props): You can pass multiple code elements as children to create complex structures like tabs.

    Themes: By default, Code.theme is set to "dark-plus". You can provide a DoubleTheme to support light/dark mode switching via a lightSelector.

  8. Render code blocks with BrightCode

    main
    The BrightCode component is the primary entrypoint for rendering highlighted code blocks. It is an asynchronous component that performs syntax highlighting and processes annotations before rendering the code within a Root component. It accepts CodeProps which include the code string, the language (lang), and an optional theme and annotations.
  9. Transform code tokens and lines

    main

    Bright exports utility functions to help manipulate code content at the token or line level, which is useful when building custom components or extensions.

    • tokensToContent: Converts tokens into content.
    • tokensToTokenList: Converts tokens into a token list.
    • linesToContent: Converts lines into content.
  10. Use the Root component for custom Bright rendering

    main
    If you have already processed your code through the highlighting engine (e.g., via @code-hike/lighter), you can use the Root component to render the UI. Root handles the container styling, theme application via data-bright-theme and data-bright-mode attributes, and manages the layout for the TitleBar and the Pre component.