react-text-range 1.0.16 → 1.0.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -8,24 +8,23 @@
8
8
  // ...
9
9
  import { TextContainer, RangeState, ReactTextRange } from "./ReactTextRange";
10
10
 
11
- const MyTextContainer: TextContainer = React.forwardRef(({ children }, ref) =>
12
- <div ref={ref} className="text-2xl text-gray-300 w-80 bg-yellow-100 select-none p-5 whitespace-pre-wrap">
13
- {children}
14
- </div>
11
+ const MyTextContainer: TextContainer = React.forwardRef(({ }, ref) =>
12
+ <div ref={ref} className="text-2xl text-gray-300 w-80 bg-yellow-100 select-none p-5 whitespace-pre-wrap" />
15
13
  );
16
14
 
17
15
  const App: FunctionComponent = () => {
18
- const [myPos, setMyPos] = useState<RangeState>({ left: 23, right: 37 })
16
+ const [myPos, setMyPos] = useState<RangeState>({ left: 23, right: 47 });
17
+
19
18
  return (
20
19
  <div style={{ margin: 20 }}>
21
- <ReactTextRange initLeftPos={23} initRightPos={47}
20
+ <ReactTextRange initLeftPos={myPos.left} initRightPos={myPos.right}
22
21
  Container={MyTextContainer} onChange={setMyPos}
23
22
  handlerWidth={18}
24
- selectionClass='bg-yellow-300 text-black'>{
25
- `Some text
23
+ selectionClass='bg-yellow-300 text-black'
24
+ text={`Some text
26
25
  or even some real good multiline text
27
26
  here and there`}
28
- </ReactTextRange>
27
+ />
29
28
  <div>
30
29
  <span>{myPos?.left}</span>
31
30
  &nbsp;
@@ -8,10 +8,10 @@ export interface RangeState {
8
8
  right: number;
9
9
  }
10
10
  export declare const ReactTextRange: FC<{
11
+ text: string;
11
12
  initLeftPos: number;
12
13
  initRightPos: number;
13
14
  Container: TextContainer;
14
- children: string;
15
15
  onChange: (state: RangeState) => void;
16
16
  props?: React.CSSProperties;
17
17
  className?: string;
@@ -5,7 +5,7 @@ declare global {
5
5
  caretPositionFromPoint: any;
6
6
  }
7
7
  }
8
- export declare const useTextSelectionEditor: (initLeftPos: number, initRightPos: number, leftDrag: boolean, rightDrag: boolean, headClass?: string, selectionClass?: string, tailClass?: string) => [
8
+ export declare const useTextSelectionEditor: (text: string, initLeftPos: number, initRightPos: number, leftDrag: boolean, rightDrag: boolean, headClass?: string, selectionClass?: string, tailClass?: string) => [
9
9
  React.MutableRefObject<HTMLDivElement | null>,
10
10
  HandlerPos | null,
11
11
  HandlerPos | null
package/dist/cjs/index.js CHANGED
@@ -107,7 +107,7 @@ const getNodeAndOffsetFromPoint = (x, y) => {
107
107
  }
108
108
  return null;
109
109
  };
110
- const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag, headClass, selectionClass, tailClass) => {
110
+ const useTextSelectionEditor = (text, initLeftPos, initRightPos, leftDrag, rightDrag, headClass, selectionClass, tailClass) => {
111
111
  // left handler pos
112
112
  const [leftHandler, setLeftHandler] = React.useState(null);
113
113
  const [currentLeftPos, setCurrentLeftPos] = React.useState(initLeftPos);
@@ -120,10 +120,18 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
120
120
  if (textDiv.current) {
121
121
  textDiv.current.style.position = 'relative';
122
122
  }
123
- }, [textDiv]);
123
+ }, [textDiv.current]);
124
124
  // break text into three spans
125
125
  React.useLayoutEffect(() => {
126
126
  var _a, _b, _c;
127
+ if (!textDiv.current)
128
+ return;
129
+ // remove all nodes
130
+ while (textDiv.current.childNodes.length > 0 && textDiv.current.lastChild) {
131
+ textDiv.current.removeChild(textDiv.current.lastChild);
132
+ }
133
+ const textNode = document.createTextNode(text);
134
+ textDiv.current.appendChild(textNode);
127
135
  let textLeftNode = (_a = textDiv.current) === null || _a === void 0 ? void 0 : _a.childNodes[0];
128
136
  if (!textLeftNode || textLeftNode.nodeType !== document.TEXT_NODE || textLeftNode.nodeValue === null) {
129
137
  return;
@@ -159,13 +167,12 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
159
167
  tail.surroundContents(tailSpan);
160
168
  return () => {
161
169
  if (textDiv.current && textDiv.current.childNodes[0]) {
162
- textDiv.current.childNodes[0].nodeValue = textDiv.current.textContent;
163
- while (textDiv.current.childNodes.length > 1 && textDiv.current.lastChild) {
170
+ while (textDiv.current.childNodes.length > 0 && textDiv.current.lastChild) {
164
171
  textDiv.current.removeChild(textDiv.current.lastChild);
165
172
  }
166
173
  }
167
174
  };
168
- }, [textDiv.current]);
175
+ }, [text]);
169
176
  // mouse move handler
170
177
  // left handler
171
178
  const leftMoveHandler = React.useCallback((e) => {
@@ -192,7 +199,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
192
199
  nodeChild3.nodeValue = full.substring(posToSet);
193
200
  setCurrentLeftPos(posToSet);
194
201
  }
195
- }, [currentLeftPos, textDiv.current]);
202
+ }, [currentLeftPos, textDiv.current, text]);
196
203
  React.useLayoutEffect(() => {
197
204
  if (!leftDrag) {
198
205
  document.removeEventListener('mousemove', leftMoveHandler);
@@ -203,7 +210,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
203
210
  return () => {
204
211
  document.removeEventListener('mousemove', leftMoveHandler);
205
212
  };
206
- }, [leftDrag, currentLeftPos, textDiv.current]);
213
+ }, [leftDrag, currentLeftPos, textDiv.current, text]);
207
214
  React.useLayoutEffect(() => {
208
215
  setCurrentLeftPos(initLeftPos);
209
216
  }, [initLeftPos]);
@@ -233,7 +240,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
233
240
  nodeChild5.nodeValue = full.substring(posToSet - currentLeftPos);
234
241
  setCurrentRightPos(posToSet);
235
242
  }
236
- }, [currentLeftPos, currentRightPos, textDiv.current]);
243
+ }, [currentLeftPos, currentRightPos, textDiv.current, text]);
237
244
  React.useLayoutEffect(() => {
238
245
  if (!rightDrag) {
239
246
  document.removeEventListener('mousemove', rightMoveHandler);
@@ -244,7 +251,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
244
251
  return () => {
245
252
  document.removeEventListener('mousemove', rightMoveHandler);
246
253
  };
247
- }, [rightDrag, currentLeftPos, currentRightPos, textDiv.current]);
254
+ }, [rightDrag, currentLeftPos, currentRightPos, textDiv.current, text]);
248
255
  React.useLayoutEffect(() => {
249
256
  setCurrentRightPos(initRightPos);
250
257
  }, [initRightPos]);
@@ -368,10 +375,10 @@ const SelectionHandler = ({ pos, grab, setGrab, left, width, className }) => {
368
375
  : React.createElement(SvgQuoteRight, null)));
369
376
  };
370
377
 
371
- const ReactTextRange = ({ initLeftPos, initRightPos, Container, children, onChange, props, handlerWidth, className, leftHandlerClass, rightHandlerClass, headClass, selectionClass, tailClass, }) => {
378
+ const ReactTextRange = ({ initLeftPos, initRightPos, Container, text, onChange, props, handlerWidth, className, leftHandlerClass, rightHandlerClass, headClass, selectionClass, tailClass, }) => {
372
379
  const [mouseOnLeft, setMouseOnLeft] = React.useState(false);
373
380
  const [mouseOnRight, setMouseOnRight] = React.useState(false);
374
- const [textDiv, leftHandler, rightHandler] = useTextSelectionEditor(initLeftPos, initRightPos, mouseOnLeft, mouseOnRight, headClass, selectionClass, tailClass);
381
+ const [textDiv, leftHandler, rightHandler] = useTextSelectionEditor(text, initLeftPos, initRightPos, mouseOnLeft, mouseOnRight, headClass, selectionClass, tailClass);
375
382
  React.useEffect(() => {
376
383
  if (leftHandler && rightHandler) {
377
384
  onChange({
@@ -381,7 +388,7 @@ const ReactTextRange = ({ initLeftPos, initRightPos, Container, children, onChan
381
388
  }
382
389
  }, [leftHandler, rightHandler]);
383
390
  return (React.createElement("div", { className: className, draggable: false, style: Object.assign({ position: 'relative' }, props) },
384
- React.createElement(Container, { ref: textDiv }, children),
391
+ React.createElement(Container, { ref: textDiv }, text),
385
392
  React.createElement(SelectionHandler, { className: leftHandlerClass, width: handlerWidth, grab: mouseOnLeft, left: true, pos: leftHandler, setGrab: (v) => setMouseOnLeft(v) }),
386
393
  React.createElement(SelectionHandler, { className: rightHandlerClass, width: handlerWidth, grab: mouseOnRight, left: false, pos: rightHandler, setGrab: (v) => setMouseOnRight(v) })));
387
394
  };
@@ -8,10 +8,10 @@ export interface RangeState {
8
8
  right: number;
9
9
  }
10
10
  export declare const ReactTextRange: FC<{
11
+ text: string;
11
12
  initLeftPos: number;
12
13
  initRightPos: number;
13
14
  Container: TextContainer;
14
- children: string;
15
15
  onChange: (state: RangeState) => void;
16
16
  props?: React.CSSProperties;
17
17
  className?: string;
package/dist/esm/index.js CHANGED
@@ -87,7 +87,7 @@ const getNodeAndOffsetFromPoint = (x, y) => {
87
87
  }
88
88
  return null;
89
89
  };
90
- const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag, headClass, selectionClass, tailClass) => {
90
+ const useTextSelectionEditor = (text, initLeftPos, initRightPos, leftDrag, rightDrag, headClass, selectionClass, tailClass) => {
91
91
  // left handler pos
92
92
  const [leftHandler, setLeftHandler] = useState(null);
93
93
  const [currentLeftPos, setCurrentLeftPos] = useState(initLeftPos);
@@ -100,10 +100,18 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
100
100
  if (textDiv.current) {
101
101
  textDiv.current.style.position = 'relative';
102
102
  }
103
- }, [textDiv]);
103
+ }, [textDiv.current]);
104
104
  // break text into three spans
105
105
  useLayoutEffect(() => {
106
106
  var _a, _b, _c;
107
+ if (!textDiv.current)
108
+ return;
109
+ // remove all nodes
110
+ while (textDiv.current.childNodes.length > 0 && textDiv.current.lastChild) {
111
+ textDiv.current.removeChild(textDiv.current.lastChild);
112
+ }
113
+ const textNode = document.createTextNode(text);
114
+ textDiv.current.appendChild(textNode);
107
115
  let textLeftNode = (_a = textDiv.current) === null || _a === void 0 ? void 0 : _a.childNodes[0];
108
116
  if (!textLeftNode || textLeftNode.nodeType !== document.TEXT_NODE || textLeftNode.nodeValue === null) {
109
117
  return;
@@ -139,13 +147,12 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
139
147
  tail.surroundContents(tailSpan);
140
148
  return () => {
141
149
  if (textDiv.current && textDiv.current.childNodes[0]) {
142
- textDiv.current.childNodes[0].nodeValue = textDiv.current.textContent;
143
- while (textDiv.current.childNodes.length > 1 && textDiv.current.lastChild) {
150
+ while (textDiv.current.childNodes.length > 0 && textDiv.current.lastChild) {
144
151
  textDiv.current.removeChild(textDiv.current.lastChild);
145
152
  }
146
153
  }
147
154
  };
148
- }, [textDiv.current]);
155
+ }, [text]);
149
156
  // mouse move handler
150
157
  // left handler
151
158
  const leftMoveHandler = useCallback((e) => {
@@ -172,7 +179,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
172
179
  nodeChild3.nodeValue = full.substring(posToSet);
173
180
  setCurrentLeftPos(posToSet);
174
181
  }
175
- }, [currentLeftPos, textDiv.current]);
182
+ }, [currentLeftPos, textDiv.current, text]);
176
183
  useLayoutEffect(() => {
177
184
  if (!leftDrag) {
178
185
  document.removeEventListener('mousemove', leftMoveHandler);
@@ -183,7 +190,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
183
190
  return () => {
184
191
  document.removeEventListener('mousemove', leftMoveHandler);
185
192
  };
186
- }, [leftDrag, currentLeftPos, textDiv.current]);
193
+ }, [leftDrag, currentLeftPos, textDiv.current, text]);
187
194
  useLayoutEffect(() => {
188
195
  setCurrentLeftPos(initLeftPos);
189
196
  }, [initLeftPos]);
@@ -213,7 +220,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
213
220
  nodeChild5.nodeValue = full.substring(posToSet - currentLeftPos);
214
221
  setCurrentRightPos(posToSet);
215
222
  }
216
- }, [currentLeftPos, currentRightPos, textDiv.current]);
223
+ }, [currentLeftPos, currentRightPos, textDiv.current, text]);
217
224
  useLayoutEffect(() => {
218
225
  if (!rightDrag) {
219
226
  document.removeEventListener('mousemove', rightMoveHandler);
@@ -224,7 +231,7 @@ const useTextSelectionEditor = (initLeftPos, initRightPos, leftDrag, rightDrag,
224
231
  return () => {
225
232
  document.removeEventListener('mousemove', rightMoveHandler);
226
233
  };
227
- }, [rightDrag, currentLeftPos, currentRightPos, textDiv.current]);
234
+ }, [rightDrag, currentLeftPos, currentRightPos, textDiv.current, text]);
228
235
  useLayoutEffect(() => {
229
236
  setCurrentRightPos(initRightPos);
230
237
  }, [initRightPos]);
@@ -348,10 +355,10 @@ const SelectionHandler = ({ pos, grab, setGrab, left, width, className }) => {
348
355
  : React__default.createElement(SvgQuoteRight, null)));
349
356
  };
350
357
 
351
- const ReactTextRange = ({ initLeftPos, initRightPos, Container, children, onChange, props, handlerWidth, className, leftHandlerClass, rightHandlerClass, headClass, selectionClass, tailClass, }) => {
358
+ const ReactTextRange = ({ initLeftPos, initRightPos, Container, text, onChange, props, handlerWidth, className, leftHandlerClass, rightHandlerClass, headClass, selectionClass, tailClass, }) => {
352
359
  const [mouseOnLeft, setMouseOnLeft] = useState(false);
353
360
  const [mouseOnRight, setMouseOnRight] = useState(false);
354
- const [textDiv, leftHandler, rightHandler] = useTextSelectionEditor(initLeftPos, initRightPos, mouseOnLeft, mouseOnRight, headClass, selectionClass, tailClass);
361
+ const [textDiv, leftHandler, rightHandler] = useTextSelectionEditor(text, initLeftPos, initRightPos, mouseOnLeft, mouseOnRight, headClass, selectionClass, tailClass);
355
362
  useEffect(() => {
356
363
  if (leftHandler && rightHandler) {
357
364
  onChange({
@@ -361,7 +368,7 @@ const ReactTextRange = ({ initLeftPos, initRightPos, Container, children, onChan
361
368
  }
362
369
  }, [leftHandler, rightHandler]);
363
370
  return (React__default.createElement("div", { className: className, draggable: false, style: Object.assign({ position: 'relative' }, props) },
364
- React__default.createElement(Container, { ref: textDiv }, children),
371
+ React__default.createElement(Container, { ref: textDiv }, text),
365
372
  React__default.createElement(SelectionHandler, { className: leftHandlerClass, width: handlerWidth, grab: mouseOnLeft, left: true, pos: leftHandler, setGrab: (v) => setMouseOnLeft(v) }),
366
373
  React__default.createElement(SelectionHandler, { className: rightHandlerClass, width: handlerWidth, grab: mouseOnRight, left: false, pos: rightHandler, setGrab: (v) => setMouseOnRight(v) })));
367
374
  };
@@ -5,7 +5,7 @@ declare global {
5
5
  caretPositionFromPoint: any;
6
6
  }
7
7
  }
8
- export declare const useTextSelectionEditor: (initLeftPos: number, initRightPos: number, leftDrag: boolean, rightDrag: boolean, headClass?: string, selectionClass?: string, tailClass?: string) => [
8
+ export declare const useTextSelectionEditor: (text: string, initLeftPos: number, initRightPos: number, leftDrag: boolean, rightDrag: boolean, headClass?: string, selectionClass?: string, tailClass?: string) => [
9
9
  React.MutableRefObject<HTMLDivElement | null>,
10
10
  HandlerPos | null,
11
11
  HandlerPos | null
package/dist/index.d.ts CHANGED
@@ -8,10 +8,10 @@ interface RangeState {
8
8
  right: number;
9
9
  }
10
10
  declare const ReactTextRange: FC<{
11
+ text: string;
11
12
  initLeftPos: number;
12
13
  initRightPos: number;
13
14
  Container: TextContainer;
14
- children: string;
15
15
  onChange: (state: RangeState) => void;
16
16
  props?: React.CSSProperties;
17
17
  className?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "react-text-range",
3
- "version": "1.0.16",
3
+ "version": "1.0.17",
4
4
  "description": "text selection editor for React",
5
5
  "main": "./dist/cjs/index.js",
6
6
  "module": "./dist/esm/index.js",