au-text-highlight
Version:
3行代码实现划词相关功能、关键字高亮、选区检测等功能。附带React版本划词popover组件。专为解决划词翻译,划词评论,web文本高亮等这类需求!目前再探索完善。
376 lines (313 loc) • 10.5 kB
Markdown
# au-text-highlight
**[中文](README.md) | English**
Official version v1.1.51 released
Implement text selection, keyword highlighting, and selection detection in 3 lines of code. Includes React popover components for text selection!
## Project Overview
In modern web applications, features like text highlighting, selection translation, and keyword search are becoming increasingly common. This module provides a complete solution including:
- 🎯 **Text Selection Detection** - Precisely capture user-selected text positions
- 🌈 **Smart Highlighting** - Automatically highlight specified text areas with custom styling
- 💬 **Selection Popover** - React popover component that appears after text selection
- 🔧 **Highly Customizable** - Support for complete customization of styles, behaviors, and interactions
- 📝 **Keyword Matching** - Efficiently match keyword positions in text
## Installation
```bash
npm install au-text-highlight
```
## Core Features
### 1. Keyword Matching & Position Extraction
Extract precise positions of keywords in text, supporting single keywords or keyword arrays.
```javascript
import { auExtractText } from 'au-text-highlight'
// Single keyword matching
const result1 = auExtractText({
text: 'GPT is an amazing AI technology, GPT is changing the world',
keywords: 'GPT'
})
// Returns: [
// { keyword: 'GPT', start: 0, end: 3 },
// { keyword: 'GPT', start: 33, end: 36 }
// ]
// Multiple keywords matching
const result2 = auExtractText({
text: 'JavaScript and TypeScript are both great languages',
keywords: ['JavaScript', 'TypeScript']
})
// Returns: [
// { keyword: 'JavaScript', start: 0, end: 10 },
// { keyword: 'TypeScript', start: 15, end: 25 }
// ]
```
### 2. Text Selection Detection
Get position information of user-selected text for subsequent highlighting or other operations.
```javascript
import { getSelectionRange, getSelectionRangeContent } from 'au-text-highlight'
// Get start and end positions of selection
const containerElement = document.getElementById('text-container')
const [startIndex, endIndex] = getSelectionRange(containerElement)
// Get selection content and Selection object
const { content, section } = getSelectionRangeContent()
console.log('Selected text:', content)
```
### 3. Text Highlighting
Automatically highlight text based on position information, with support for custom styles and unique identifiers.
```javascript
import { sectionRangeHighlight } from 'au-text-highlight'
const containerElement = document.getElementById('text-container')
// Basic highlighting
sectionRangeHighlight(containerElement, [
{ start: 0, end: 5 },
{ start: 10, end: 15 }
])
// Highlighting with unique identifiers (for future operations)
sectionRangeHighlight(containerElement, [
{ start: 0, end: 5, gid: 'highlight-1' },
{ start: 10, end: 15, gid: 'highlight-2' }
])
```
**Highlighting Style Details:**
- Highlighted elements are wrapped with `<span>` tags
- Default class name: `word_comment_mark`
- Includes accessibility attributes: `role="text"` and `aria-label="highlighted content"`
- Supports setting unique IDs via gid parameter for future deletion or modification
**Custom Highlighting Styles:**
```css
.word_comment_mark {
background-color: #ffeb3b;
padding: 2px 4px;
border-radius: 3px;
border: 1px solid #ffc107;
}
/* Or use ID selectors for specific highlights */
#highlight-1 {
background-color: #e3f2fd;
border: 1px solid #2196f3;
}
```
## React Components
### 1. AuSelectionPopover Component
React version of text selection popover component with fully customizable content.
```tsx
import React from 'react'
import { ReactAuSelectionPopover } from 'au-text-highlight'
function MyComponent() {
const handleShow = (position) => {
console.log('Selected text:', position.text)
}
const handleHide = () => {
console.log('Popover hidden')
}
return (
<div>
<div id="text-container">
Select any text here to see the custom action panel.
</div>
<ReactAuSelectionPopover
distance={10}
container={document.getElementById('text-container')}
onShow={handleShow}
onHide={handleHide}
className="my-popover"
style={{
backgroundColor: 'white',
border: '1px solid #e5e7eb',
borderRadius: '8px',
boxShadow: '0 4px 6px rgba(0, 0, 0, 0.1)',
padding: '12px'
}}
>
<div>
<button onClick={() => alert('Translate feature')}>🌐 Translate</button>
<button onClick={() => alert('Search feature')}>🔍 Search</button>
<button onClick={() => alert('Copy feature')}>📋 Copy</button>
</div>
</ReactAuSelectionPopover>
</div>
)
}
```
**AuSelectionPopover Props:**
- `children`: React.ReactNode - Popover content (required)
- `distance`: number - Distance from popover to selection, default 10px
- `className`: string - Custom CSS class name
- `style`: React.CSSProperties - Custom styles
- `container`: HTMLElement - Container element for limiting text selection detection
- `onShow`: (position) => void - Callback when popover is shown
- `onHide`: () => void - Callback when popover is hidden
- `disabled`: boolean - Whether to disable popover, default false
- `portal`: boolean - Whether to use Portal rendering, default true
- `zIndex`: number - Popover z-index, default 9999
### 2. useTextSelection Hook
React Hook for text selection detection.
```tsx
import React from 'react'
import { useTextSelection } from 'au-text-highlight'
function MyComponent() {
const { selection, isSelecting, clearSelection } = useTextSelection({
delay: 100,
container: document.getElementById('text-container')
})
React.useEffect(() => {
if (selection) {
console.log('Selected text:', selection.text)
console.log('Position info:', selection.x, selection.y)
}
}, [selection])
return (
<div>
<div id="text-container">
Select text here, console will output selection info.
</div>
<div>
Status:
{' '}
{isSelecting ? 'Selecting' : 'Not selecting'}
{selection && (
<p>
Selected:
{selection.text}
</p>
)}
<button onClick={clearSelection}>Clear Selection</button>
</div>
</div>
)
}
```
**useTextSelection Parameters:**
- `delay`: number - Selection detection delay time, default 100ms
- `container`: HTMLElement - Container element for limiting detection scope
**useTextSelection Return Values:**
- `selection`: TriggerPosition | null - Current selection information
- `isSelecting`: boolean - Whether text is being selected
- `clearSelection`: () => void - Clear current selection
- `getTriggerPosition`: () => TriggerPosition | null - Manually get selection position
## Complete Examples
### Comprehensive Usage Example
```javascript
import {
auExtractText,
getSelectionRange,
sectionRangeHighlight
} from 'au-text-highlight'
// 1. Search and highlight keywords
function highlightKeywords(containerElement, keywords) {
const text = containerElement.textContent
const matches = auExtractText({ text, keywords })
// Highlight all matched keywords
const positions = matches.map((match, index) => ({
start: match.start,
end: match.end,
gid: `keyword-${index}`
}))
sectionRangeHighlight(containerElement, positions)
}
// 2. User selection highlighting
function highlightUserSelection(containerElement) {
const [start, end] = getSelectionRange(containerElement)
sectionRangeHighlight(containerElement, [
{ start, end, gid: 'user-selection' }
])
}
// Usage example
const container = document.getElementById('article')
highlightKeywords(container, ['JavaScript', 'React', 'TypeScript'])
```
### Complete React Example
```tsx
import React, { useRef, useState } from 'react'
import {
ReactAuSelectionPopover,
auExtractText,
sectionRangeHighlight
} from 'au-text-highlight'
function TextHighlightDemo() {
const [selectedText, setSelectedText] = useState('')
const containerRef = useRef<HTMLDivElement>(null)
const handleShow = (position) => {
setSelectedText(position.text)
}
const handleTranslate = () => {
alert(`Translate: ${selectedText}`)
}
const handleHighlight = () => {
if (containerRef.current) {
const text = containerRef.current.textContent
const matches = auExtractText({ text, keywords: selectedText })
const positions = matches.map((match, index) => ({
start: match.start,
end: match.end,
gid: `highlight-${index}`
}))
sectionRangeHighlight(containerRef.current, positions)
}
}
return (
<div>
<div ref={containerRef} className="text-content">
This is demonstration text. Select any text to see the action menu,
you can translate the selected text or highlight all similar words on the page.
</div>
<ReactAuSelectionPopover
container={containerRef.current}
onShow={handleShow}
style={{
backgroundColor: 'white',
border: '1px solid #ccc',
borderRadius: '6px',
padding: '8px',
boxShadow: '0 2px 10px rgba(0,0,0,0.1)'
}}
>
<div className="popover-content">
<button onClick={handleTranslate}>🌐 Translate</button>
<button onClick={handleHighlight}>🎨 Highlight Similar Words</button>
</div>
</ReactAuSelectionPopover>
</div>
)
}
```
## TypeScript Definitions
```typescript
// Basic configuration
interface DeafultConfig {
text: string
keywords: string | string[]
}
// Position information
interface TriggerPosition {
text: string
x: number
y: number
width: number
height: number
}
// Highlight position
interface HighlightPosition {
start: number
end: number
gid?: string
}
// Match result
interface MatchResult {
keyword: string
start: number
end: number
}
```
## Version Changelog
- v1.1.0
- Official release with comprehensive documentation
- Complete solution for text selection, commenting, and selection features
- Added React popover component that appears after user text selection
## Advanced Features
More features coming soon, stay tuned for updates!
## Browser Compatibility
- Chrome 60+
- Firefox 55+
- Safari 12+
- Edge 79+
## Contributing
Issues and Pull Requests are welcome! If you have great ideas or find bugs, feel free to contribute.
## License
MIT License