Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@codemirror-toolkit/react

Package Overview
Dependencies
Maintainers
0
Versions
13
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@codemirror-toolkit/react

A small and flexible solution for binding CodeMirror 6 to React

  • 0.7.1
  • latest
  • Source
  • npm
  • Socket score

Version published
Weekly downloads
83
increased by36.07%
Maintainers
0
Weekly downloads
 
Created
Source

@codemirror-toolkit/react

npm (scoped) npm bundle size (scoped) GitHub Workflow Status (with branch) Codecov branch

A small and flexible solution for binding CodeMirror 6 to React.

Instead of providing component with a big amount of props and un-tree-shakable dependencies (like @uiw/react-codemirror), it offers a set of hooks and an optional context provider that can be used to better integrate with your components.

Examples

See codemirror-toolkit#examples.

Installation

# npm
npm install @codemirror-toolkit/react

# Yarn
yarn add @codemirror-toolkit/react

# pnpm
pnpm add @codemirror-toolkit/react

Note that, you also need to install the peer dependencies @codemirror/state and @codemirror/view if you don't use the official all-in-one package codemirror or your package manager doesn't do it automatically.

Migrate from 0.6.0

Migration Guide
  • createCodeMirror is refactored to a core function without hooks. Use create instead for a similar functionality with hooks.

    // v0.6.0
    const { useView, useViewEffect } = createCodeMirror(config)
    
    // v0.7.0
    const { useView, useViewEffect } = create(config)
    
  • Configuration can now be set using setConfig.

    // v0.7.0
    const { setConfig } = create()
    setConfig(config)
    
  • The useContainerRef hook has been replaced with a setContainer function.

    // v0.6.0
    const { useContainerRef } = createCodeMirror(config)
    
    function Editor() {
      const containerRef = useContainerRef()
      return <div ref={containerRef} />
    }
    
    // v0.7.0
    const { setContainer } = create(config)
    
    function Editor() {
      return <div ref={setContainer} />
    }
    
  • useViewEffect now requires the setup function to be memoized or have a stable reference to prevent the effect from firing on every render.

    // v0.6.0
    useViewEffect((view) => {
      // Effect logic
    })
    
    // v0.7.0
    const effect = useCallback((view) => {
      // Effect logic
    }, [/* dependencies */])
    
    useViewEffect(cm, effect)
    
  • createCodeMirrorContext is renamed to createContext and does not provide hooks directly. Use useCodeMirror to access the CodeMirror instance, then use the exported hooks with this instance.

    // v0.6.0
    const { Provider, useView, useViewEffect, useContainerRef } = createCodeMirrorContext()
    
    function Editor() {
      const _view = useView()
      useViewEffect((view) => {
        // Effect logic
      })
    
      const containerRef = useContainerRef()
      return <div ref={containerRef} />
    }
    
    // v0.7.0
    const { Provider, useCodeMirror } = createContext()
    
    import { useView, useViewEffect } from '@codemirror-toolkit/react'
    
    function Editor() {
      const cm = useCodeMirror()
    
      const _view = useView(cm)
      useViewEffect(cm, effect)
    
      return <div ref={cm.setContainer} />
    }
    

Usage

First create an instance with configuration as an object or a factory function:

import { create } from '@codemirror-toolkit/react'

const cm = create((prevState) => ({
  state: prevState, // useful for HMR
  doc: 'Hello World!',
}))

export const {
  getView,
  useView,
  useViewEffect,
  setContainer,
  setConfig,
  subscribe,
} = cm

Then bind your components with a callback ref:

function Editor() {
  return <div ref={setContainer} />
}

Initiate with data from component

Option 1:
import { create } from '@codemirror-toolkit/react'
import { useCallback } from 'react'

const { setContainer, setConfig } = create()

interface Props {
  initialInput: string
}

function Editor({ initialInput }: Props) {
  const ref = useCallback((node: HTMLDivElement | null) => {
    setContainer(node)
    if (node) {
      setConfig({
        doc: initialInput,
      })
    }
  }, [initialInput])
  return <div ref={ref} />
}
Option 2:

Use createContext, see below.

With Context Provider

import { createContext } from '@codemirror-toolkit/react'

const { Provider: CodeMirrorProvider, useCodeMirror } = createContext()

function Editor() {
  const { setContainer } = useCodeMirror()
  return <div ref={setContainer} />
}

interface Props {
  initialInput: string
}

function EditorWrapper({ initialInput }: Props) {
  return (
    <CodeMirrorProvider
      config={{
        doc: initialInput,
      }}>
      <Editor />
    </CodeMirrorProvider>
  )
}

API

🚧 Documentation is WIP.

Common Types

import type { EditorState } from '@codemirror/state'
import type { EditorView, EditorViewConfig } from '@codemirror/view'
import type { EffectCallback } from 'react'

type EditorViewConfigCreator = (prevState: EditorState | undefined) => EditorViewConfig
type CodeMirrorConfig = EditorViewConfig | EditorViewConfigCreator

type ViewChangeHandler = (view: EditorView | null) => void

type ViewContainer = Element | DocumentFragment

interface CodeMirror {
  getView: () => EditorView | null
  subscribe: (onViewChange: ViewChangeHandler) => () => void
  setContainer: (container: ViewContainer | null) => void
  setConfig: (config: CodeMirrorConfig) => void
}

type ViewEffectCleanup = ReturnType<EffectCallback>
type ViewEffectSetup = (view: EditorView) => ViewEffectCleanup

interface CodeMirrorHooks {
  useView: () => EditorView | null
  useViewEffect: (setup: ViewEffectSetup) => void
}

type CodeMirrorWithHooks = CodeMirror & CodeMirrorHooks

createCodeMirror

function createCodeMirror(initialConfig?: CodeMirrorConfig): CodeMirror

create

function create(config?: CodeMirrorConfig): CodeMirrorWithHooks

createContext

import type { FunctionComponent, PropsWithChildren } from 'react'

interface CodeMirrorProps {
  config?: CodeMirrorConfig
}

interface CodeMirrorProviderProps extends PropsWithChildren<CodeMirrorProps> {}

interface CodeMirrorProvider extends FunctionComponent<CodeMirrorProviderProps> {}

interface CodeMirrorContext {
  Provider: CodeMirrorProvider
  useCodeMirror: () => CodeMirror
}

function createContext(): CodeMirrorContext

useView

function useView(cm: CodeMirror): EditorView | null

useViewEffect

function defineViewEffect(setup: ViewEffectSetup): ViewEffectSetup

function useViewEffect(cm: CodeMirror, setup: ViewEffectSetup): void

License

MIT License @ 2022-Present Xuanbo Cheng

Keywords

FAQs

Package last updated on 15 Sep 2024

Did you know?

Socket

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Install

Related posts

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc