Liseré

A lightweight and composable React component for selecting and highlighting text.


Installation

Install the package via npm, yarn, or your package manager of choice.

pnpm add lisere

# Basic Usage

Select any part of this text. A default highlight will be applied as soon as the selection is valid.

This component allows you to easily add text highlighting functionality to your React applications. Simply select any text in this paragraph and it will be highlighted automatically. The component is highly customizable and supports various selection modes, styling options, and event callbacks.

1<TextHighlighter2  onTextHighlighted={(selection: TextSelection) => {3    setHighlights(prev => [...prev, selection.text]);4  }}5>6  <p>Your content here...</p>7</TextHighlighter>

# Custom Styling

Choose different highlight styles and see how they apply to new selections.

This paragraph demonstrates custom styling options. Select any text to see how the chosen style is applied. You can customize highlights using CSS classes, inline styles, or a combination of both. The styling system is flexible and allows for complex visual effects.

1<TextHighlighter2  highlightStyle={{3    style: {4      background: 'linear-gradient(45deg, #f3e8ff, #faf5ff)',5      color: '#431407',6      padding: '2px',7      borderRadius: '8px',8      boxShadow: '0 0 0 1px rgba(126,34,206,0.1), 0 1px 2px -1px rgb(126,34,206), 0 1px 4px -2px rgba(126,34,206,0.1), 0 4px 8px -4px rgba(126,34,206,0.1)',9      cursor: 'crosshair',10    }11  }}12>13  <p>Your content here...</p>14</TextHighlighter>

# Selection Boundary Modes

Compare cursor-based vs word-based selection boundaries. Try selecting partial words in each mode.

Try selecting parts of words like "demonstrat" from "demonstration" or "bound" from "boundaries". In cursor mode, you'll highlight exactly what you select. In word mode, the selection will expand to include complete words. This feature is particularly useful for applications like text annotation tools where you want consistent highlighting behavior.

1<TextHighlighter2  selectionBoundary="cursor"3>4  <p>Your content here...</p>5</TextHighlighter>

# Custom Render Props

Use render props to completely customize how highlights are displayed.

This example shows how to use custom render props to create unique highlight styles. The highlights here have a gradient background, a sparkle emoji, and a tooltip showing the highlighted text. You can create any custom UI for your highlights using this approach.

1<TextHighlighter2  renderHighlight={({3    children,4    selection,5  }: {6    children: React.ReactNode;7    selection: TextSelection;8  }) => (9    <span10      title={`Highlighted: "${selection.text}"`}11      style={{12        background: 'linear-gradient(45deg, #f3e8ff, #faf5ff)',13        color: '#431407',14        padding: '2px',15        borderRadius: '8px',16        boxShadow: '0 0 0 1px rgba(126,34,206,0.1), 0 1px 2px -1px rgb(126,34,206), 0 1px 4px -2px rgba(126,34,206,0.1), 0 4px 8px -4px rgba(126,34,206,0.1)',17        cursor: 'crosshair',18      }}19    >20      {children} 🍒21    </span>22  )}23>24  <p>Your content here...</p>25</TextHighlighter>

# Custom Selection UI

Add custom UI that appears when text is selected, allowing users to confirm or cancel highlighting. Note that the text is highlighted immediately when selected, and the UI allows you to confirm or cancel the highlight.

Select any text in this paragraph to see the custom selection UI in action. The text will be highlighted immediately, and a popup will appear asking if you want to keep the highlight. Click "Yes" to confirm or "No" to remove it. This is useful for applications where you want to show immediate feedback while still allowing user confirmation.

1<TextHighlighter2  renderSelectionUI={({3  selection,4  modifyHighlight,5  onClose,6}: {7  selection: TextSelection;8  modifyHighlight: (highlight: TextSelection, cancel: boolean) => void;9  onClose: () => void;10}) => (11    <div className="selection-popup">12      <span>Highlight "{selection.text}"?</span>13      <button onClick={() => modifyHighlight?.(selection, false)}>14        Yes15      </button>16      <button onClick={() => modifyHighlight?.(selection, true)}>17        No18      </button>19      <button onClick={onClose}>20        Cancel21      </button>22    </div>23  )}24>25  <p>Your content here...</p>26</TextHighlighter>

# Pre-selected Content

Highlight specific text automatically when the component mounts. Useful for displaying saved highlights or annotations.

This paragraph has some pre-selected text that gets highlighted automatically when the component loads.

1<TextHighlighter2  selectedContent={[3    { text: 'important', startOffset: 0, endOffset: 9 },4    { text: 'keyword', startOffset: 0, endOffset: 7 }5  ]}6>7  <p>Your content with important keywords here...</p>8</TextHighlighter>

# Remove Highlight on Click

Enable the toggle below to remove highlights when you click on them.

This demo shows how to remove highlights by clicking on them. First, select some text to highlight it. Then, if the toggle is enabled, click on any highlighted text to remove it. This is useful for creating interactive annotation systems where users can easily remove highlights they no longer need.

1<TextHighlighter2  removeHighlightOnClick={true}3  onTextHighlighted={(selection: TextSelection) => {4    console.log('Highlighted:', selection.text)5  }}6  onHighlightRemoved={(selection: TextSelection) => {7    console.log('Removed:', selection.text)8  }}9>10  <p>Your content here...</p>11</TextHighlighter>

# useTextHighlighter Hook

Use the hook for more control over highlighting behavior.

This demonstration shows how to use the useTextHighlighter hook for more advanced control. You can programmatically highlight text, change colors dynamically, clear highlights, and get the current text selection. The hook provides a more flexible API for complex use cases where you need fine-grained control over the highlighting behavior.

1  const { highlights, highlightText, clearHighlights } = useTextHighlighter({2    containerRef,3    highlightStyle: { style: { backgroundColor: "default" } },4    onTextHighlighted: (selection: TextSelection) => {5      console.log("Highlighted:", selection.text);6    },7  });8

# Utility Functions

Use the exported utility functions for direct DOM manipulation and advanced highlighting scenarios.

This example demonstrates direct utility function usage. You can manually highlight specific text using the search input above, or select text with your mouse to test the selection utilities. The utility functions provide low-level control over highlighting behavior for advanced use cases.


1import {2  highlightRange,3  removeHighlight,4  findTextInElement,5  clearSelection,6  isValidSelection7} from 'lisere'89// Manual highlighting10const container = document.getElementById('content')11const ranges = findTextInElement(container, 'search term')12ranges.forEach(range => {13  const highlight = highlightRange(range, 'span', {14    className: 'manual-highlight',15    style: { backgroundColor: 'yellow' }16  })17})1819// Get current selection20const selection = window.getSelection()21if (selection && selection.rangeCount > 0 && !selection.isCollapsed) {22  const range = selection.getRangeAt(0)23  const text = range.toString().trim()24  if (text) {25    console.log('Selected text:', text)26  }27}2829// Remove highlight30const highlightElement = document.querySelector('.highlight')31if (highlightElement) {32  removeHighlight(highlightElement)33}3435// Clear selection36clearSelection()37window.getSelection()?.removeAllRanges()3839// Validate selection40const selection = window.getSelection()41if (selection && selection.rangeCount > 0 && !selection.isCollapsed) {42  const range = selection.getRangeAt(0)43  const text = range.toString().trim()44  const isInContainer = container.contains(range.commonAncestorContainer)45  console.log('Selection valid:', isInContainer && text.length > 0)46}
Current Selection:
No text selected