Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/ragaeeb/dyelight/llms.txt

Use this file to discover all available pages before exploring further.

The DyeLight component is a React textarea with advanced text highlighting capabilities. It supports character-level highlighting using absolute positions, line-level highlighting, automatic height adjustment, and synchronized scrolling between the textarea and highlight overlay.
import { DyeLight } from 'dyelight';
import { useRef, useState } from 'react';
import type { DyeLightRef } from 'dyelight';

function MyEditor() {
  const [code, setCode] = useState('const x = 1;');
  const editorRef = useRef<DyeLightRef>(null);

  const highlights = HighlightBuilder.pattern(
    code,
    /\b(const|let|var)\b/g,
    'keyword-highlight'
  );

  return (
    <DyeLight
      ref={editorRef}
      value={code}
      onChange={setCode}
      highlights={highlights}
      enableAutoResize={true}
      rows={10}
    />
  );
}

Props

value
string
Controlled value of the textarea. When provided, the component operates in controlled mode.
defaultValue
string
Default value for uncontrolled usage. Use this when you want the component to manage its own state.
onChange
(value: string) => void
Callback fired when the textarea value changes. Receives the new value as a string (simplified from the standard React onChange signature).
highlights
CharacterRange[]
Array of character range highlights using absolute positions in the entire text. Each range specifies start/end indices and optional styling.
const highlights = [
  { start: 0, end: 5, className: 'keyword' },
  { start: 10, end: 20, style: { backgroundColor: 'yellow' } }
];
lineHighlights
{ [lineNumber: number]: string }
Line-level highlights mapped by line number (0-based) to CSS color or class name. Supports CSS color values (hex, rgb, named) or CSS class names.
const lineHighlights = {
  0: 'error-line',           // CSS class
  2: '#ffff00',              // Hex color
  5: 'rgb(255, 200, 100)'    // RGB color
};
enableAutoResize
boolean
default:"true"
Enable automatic height adjustment based on content. When enabled, the textarea grows/shrinks to fit its content.
rows
number
default:"4"
Number of visible text lines. Sets the initial height when auto-resize is disabled.
className
string
CSS class name for the textarea element itself.
containerClassName
string
CSS class name for the container wrapper element that holds both the textarea and highlight overlay.
dir
'ltr' | 'rtl'
default:"'ltr'"
Text direction - supports left-to-right (ltr) and right-to-left (rtl) languages.
debug
boolean
default:"false"
Enable debug mode to collect telemetry data. Used for diagnosing synchronization issues and performance problems.
debugMaxEvents
number
default:"1000"
Maximum number of telemetry events to retain in memory when debug mode is enabled.

Additional textarea props

DyeLight extends standard HTML textarea attributes, so you can pass any valid textarea prop:
<DyeLight
  placeholder="Enter code here..."
  disabled={false}
  readOnly={false}
  spellCheck={false}
  autoFocus={true}
  onFocus={() => console.log('focused')}
  onBlur={() => console.log('blurred')}
  style={{ fontFamily: 'monospace', fontSize: '14px' }}
/>

Ref methods

Access these methods by creating a ref with useRef<DyeLightRef>(null) and passing it to the component.
getValue
() => string
Gets the current value of the textarea.
const value = editorRef.current?.getValue();
setValue
(value: string) => void
Sets the value of the textarea programmatically. Triggers auto-resize if enabled.
editorRef.current?.setValue('new code');
focus
() => void
Sets focus to the textarea.
editorRef.current?.focus();
blur
() => void
Removes focus from the textarea.
editorRef.current?.blur();
select
() => void
Selects all text in the textarea.
editorRef.current?.select();
setSelectionRange
(start: number, end: number) => void
Sets the selection range in the textarea using character positions.
// Select characters 10-20
editorRef.current?.setSelectionRange(10, 20);
scrollToPosition
(pos: number, offset?: number, behavior?: ScrollBehavior) => void
Scrolls the character position into view with an optional pixel offset. Uses data-range-start attributes from highlighted spans.
  • pos: Character position to scroll to
  • offset: Pixel offset from top (default: 40)
  • behavior: Scroll behavior - 'auto' or 'smooth' (default: 'auto')
// Scroll to character 100 with smooth animation
editorRef.current?.scrollToPosition(100, 40, 'smooth');
exportForAI
() => string
Exports an AI-optimized debug report as a JSON string. Requires debug mode to be enabled. The report includes value deduplication - large text values are stored once in a valueRegistry and referenced as <REF:value_N> to reduce JSON size.
const report = editorRef.current?.exportForAI();
if (report) {
  await navigator.clipboard.writeText(report);
  console.log('Debug report copied to clipboard');
}

Usage patterns

Controlled component

function ControlledEditor() {
  const [text, setText] = useState('initial value');

  return (
    <DyeLight
      value={text}
      onChange={setText}
      highlights={[{ start: 0, end: 7, className: 'highlight' }]}
    />
  );
}

Uncontrolled component

function UncontrolledEditor() {
  const editorRef = useRef<DyeLightRef>(null);

  const handleSubmit = () => {
    const value = editorRef.current?.getValue();
    console.log('Submitted:', value);
  };

  return (
    <>
      <DyeLight ref={editorRef} defaultValue="initial value" />
      <button onClick={handleSubmit}>Submit</button>
    </>
  );
}

Syntax highlighting

function CodeEditor() {
  const [code, setCode] = useState('function hello() {\n  return "world";\n}');

  const highlights = [
    ...HighlightBuilder.pattern(code, /\b(function|return)\b/g, 'keyword'),
    ...HighlightBuilder.pattern(code, /"[^"]*"/g, 'string'),
    ...HighlightBuilder.pattern(code, /\b[a-zA-Z_][a-zA-Z0-9_]*(?=\()/g, 'function-name')
  ];

  return (
    <DyeLight
      value={code}
      onChange={setCode}
      highlights={highlights}
      style={{ fontFamily: 'monospace' }}
    />
  );
}

Error highlighting with line backgrounds

function EditorWithErrors() {
  const [code, setCode] = useState('line 1\nline 2 with error\nline 3');

  const errorHighlights = HighlightBuilder.characters([
    { index: 13, className: 'error-marker' } // Error at specific position
  ]);

  const lineHighlights = {
    1: 'error-line-background' // Highlight entire line 2
  };

  return (
    <DyeLight
      value={code}
      onChange={setCode}
      highlights={errorHighlights}
      lineHighlights={lineHighlights}
    />
  );
}