|
1 | | -# |
| 1 | +# useTextSelection |
| 2 | +Hook to track text selection and its size. |
| 3 | + |
| 4 | +## Usage |
| 5 | + |
| 6 | +```tsx |
| 7 | +export const UseTextSelection = () => { |
| 8 | + const ref = useRef<HTMLDivElement>(null); |
| 9 | + const selection = useTextSelection({ target: ref, onEnd: () => {getSelection()?.removeAllRanges()} }); |
| 10 | + const rectangles = useMemo(() => { |
| 11 | + if (!selection) { |
| 12 | + return null; |
| 13 | + } else { |
| 14 | + const rectangles = []; |
| 15 | + rectangles.push( |
| 16 | + <div |
| 17 | + key="outside-rectangle" |
| 18 | + style={{ |
| 19 | + position: "absolute", |
| 20 | + border: ".5px solid red", |
| 21 | + top: selection.outsideRectangle.top + "px", |
| 22 | + left: selection.outsideRectangle.left + "px", |
| 23 | + width: selection.outsideRectangle.width + "px", |
| 24 | + height: selection.outsideRectangle.height + "px", |
| 25 | + }} |
| 26 | + ></div> |
| 27 | + ); |
| 28 | + selection.innerRectangles.forEach((el, index) => { |
| 29 | + rectangles.push(<div |
| 30 | + key={"inner-rectangle-"+index} |
| 31 | + style={{ |
| 32 | + position: "absolute", |
| 33 | + border: ".5px solid darkcyan", |
| 34 | + top: el.top + "px", |
| 35 | + left: el.left + "px", |
| 36 | + width: el.width + "px", |
| 37 | + height: el.height + "px", |
| 38 | + }} |
| 39 | + ></div>); |
| 40 | + }) |
| 41 | + return rectangles; |
| 42 | + } |
| 43 | + }, [selection]); |
| 44 | + |
| 45 | + return <div style={{ display: "grid", gridTemplateColumns: "50% 50%", columnGap: 15 }}> |
| 46 | + <div ref={ref} style={{ position: "relative", border: "1px solid lightgray" }}> |
| 47 | + <div> |
| 48 | + <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt repudiandae fugit distinctio molestiae excepturi ex qui, impedit iste odit. Explicabo quis reprehenderit voluptates reiciendis nostrum minima autem temporibus sint doloribus</p> |
| 49 | + </div> |
| 50 | + <div> |
| 51 | + <p>Lorem ipsum, dolor sit amet consectetur adipisicing elit. Incidunt repudiandae fugit distinctio molestiae excepturi ex qui, impedit iste odit. Explicabo quis reprehenderit voluptates reiciendis nostrum minima autem temporibus sint doloribus</p> |
| 52 | + </div> |
| 53 | + {rectangles} |
| 54 | + </div> |
| 55 | + <div style={{textAlign: "left", padding: "0 1em", maxHeight: 300, overflow: "auto", border: "1px solid lightgray"}}> |
| 56 | + <p><strong>Selection:</strong></p> |
| 57 | + <pre>{JSON.stringify(selection, null, 2)}</pre> |
| 58 | + </div> |
| 59 | + </div> |
| 60 | +} |
| 61 | +``` |
| 62 | + |
| 63 | +> The component renders a grid with two columns. First column contains _two tag p elements_ with text and secondo column the result of _useTextSelection hook_. |
| 64 | +> |
| 65 | +> _useTextSelection_ is initialized with a _target_ property that has a ref attached to first column div and _onEnd_ property that has a function that clean selection. When text is selected appears colored rectangles with the coordinates returned from hook. |
2 | 66 |
|
3 | 67 |
|
4 | 68 | ## API |
5 | 69 |
|
6 | 70 | ```tsx |
7 | | - const range = document.createRange(); |
| 71 | +useTextSelection ({ target, onStart, onChange, onEnd }: { target?: RefObject<HTMLElement> | HTMLElement, onStart?: (evt: Event) => void, onChange?: (evt: Event) => void, onEnd?: (evt: Event) => void } = {}): TextSelection | null |
8 | 72 | ``` |
9 | 73 |
|
10 | 74 | > ### Params |
11 | 75 | > |
12 | | -> |
| 76 | +> - __param__: _Object_ |
| 77 | +object with selection properties |
| 78 | +> - __param.target?__: _RefObject<HTMLElement> | HTMLElement_ |
| 79 | +element in which allow selection. Default is _document.body_. |
| 80 | +> - __param.onStart?__: _(evt: Event) => void_ |
| 81 | +function to execute when selection starts. |
| 82 | +> - __param.onChange?__: _(evt: Event) => void_ |
| 83 | +function to execute while selection changes. |
| 84 | +> - __param.onEnd?__: _(evt: Event) => void_ |
| 85 | +function to execute while selection ends. |
13 | 86 | > |
14 | 87 |
|
15 | 88 | > ### Returns |
16 | 89 | > |
17 | | -> |
18 | | -> |
| 90 | +> __TextSelection__: object with: _text_: selected text; _direction_: selection direction; _outsideRectangle_: a __DOMRect__ of selection rectangle; _innerRectangles_: list of __DOMRect__ representing the selection slices. |
| 91 | +> - __Object__: |
| 92 | +> - __text__ : _string_ |
| 93 | +> - __direction__ : _"forward"|"backward"_ |
| 94 | +> - __outsideRectangle__ : _DOMRect_ |
| 95 | +> - __innerRectangles__ : _DOMRect[]_ |
19 | 96 | > |
0 commit comments