@omsimos/react-highlight-popover

A customizable, headless React component for creating popovers on text selection, with zero dependencies.

Contents

Installation

Add the package using your package manager:

npm i @omsimos/react-highlight-popover

Usage

Here's a basic example of how to use the HighlightPopover component:

import { HighlightPopover } from '@omsimos/react-highlight-popover';
 
function App() {
  const renderPopover = ({ selection }) => (
    <div className="bg-white border rounded p-2 shadow-lg select-none">
      You selected: {selection}
    </div>
  );
 
  return (
    <HighlightPopover renderPopover={renderPopover}>
      <p>
        This is a sample text. Try selecting some words to see the popover in action.
      </p>
    </HighlightPopover>
  );
}
 
export default App;

API

HighlightPopover Props

PropTypeDefaultDescription
childrenReact.ReactNode(required)The content where text selection will trigger the popover
renderPopover(props: { position: Position, selection: string }) => React.ReactNode(required)Function to render the popover content
classNamestring''Additional CSS class for the wrapper element
offset{ x?: number, y?: number }{ x: 0, y: 0 }Offset for adjusting popover position
zIndexnumber40The z-index of the popover
alignment'left' | 'center' | 'right''center'Alignment of the popover relative to the selected text
minSelectionLengthnumber1Minimum length of text selection to trigger the popover
onSelectionStart() => voidundefinedCallback fired when text selection starts
onSelectionEnd(selection: string) => voidundefinedCallback fired when text selection ends
onPopoverShow() => voidundefinedCallback fired when the popover is shown
onPopoverHide() => voidundefinedCallback fired when the popover is hidden

useHighlightPopover Hook

The useHighlightPopover hook can be used to access the internal state of the HighlightPopover component. It returns an object with the following properties:

Advanced Example

Here's a more advanced example demonstrating custom styling and event handling:

import { HighlightPopover, useHighlightPopover } from '@omsimos/react-highlight-popover';
 
function CustomPopover() {
  const { currentSelection, setShowPopover } = useHighlightPopover();
  
  return (
    <div className="bg-white border rounded-md p-2 shadow-lg select-none">
      <p>You selected: {currentSelection}</p>
      <button className="font-semibold" onClick={() => setShowPopover(false)}>Close</button>
    </div>
  );
}
 
function App() {
  const handleSelectionStart = () => console.log('Selection started');
  const handleSelectionEnd = (selection) => console.log('Selected:', selection);
  const handlePopoverShow = () => console.log('Popover shown');
  const handlePopoverHide = () => console.log('Popover hidden');
 
  return (
    <HighlightPopover
      renderPopover={() => <CustomPopover />}
      offset={{ x: 0, y: -10 }}
      minSelectionLength={5}
      onSelectionStart={handleSelectionStart}
      onSelectionEnd={handleSelectionEnd}
      onPopoverShow={handlePopoverShow}
      onPopoverHide={handlePopoverHide}
    >
      <p>
        This is a more advanced example. Try selecting at least five characters
        to see the custom popover with a close button.
      </p>
    </HighlightPopover>
  );
}
 
export default App;