Skip to content

Commit 7d0fe32

Browse files
authored
Merge branch 'dev' into temp-C
2 parents 11f56a6 + 9e58b2c commit 7d0fe32

File tree

2 files changed

+51
-12
lines changed

2 files changed

+51
-12
lines changed

β€Žclient/src/components/Mom/Block/index.tsxβ€Ž

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,11 @@ function Block({ id, onKeyDown, index }: BlockProps) {
2828
remoteDeleteCRDT,
2929
} = useCRDT();
3030

31-
const { offsetRef, setOffset, clearOffset, offsetHandlers } = useOffset();
32-
3331
const blockRef = useRef<HTMLParagraphElement>(null);
3432

33+
const { offsetRef, setOffset, clearOffset, offsetHandlers } =
34+
useOffset(blockRef);
35+
3536
// λ‘œμ»¬μ—μ„œ μΌμ–΄λ‚˜λŠ” μž‘μ„± - μ‚½μž…κ³Ό μ‚­μ œ μ—°μ‚°
3637
const onInput: React.FormEventHandler = (e) => {
3738
setOffset();
@@ -159,6 +160,13 @@ function Block({ id, onKeyDown, index }: BlockProps) {
159160
e.preventDefault();
160161
};
161162

163+
const onKeyDownComposite: React.KeyboardEventHandler<HTMLParagraphElement> = (
164+
e,
165+
) => {
166+
offsetHandlers.onKeyDown(e);
167+
onKeyDown(e);
168+
};
169+
162170
return (
163171
<p
164172
ref={blockRef}
@@ -167,7 +175,7 @@ function Block({ id, onKeyDown, index }: BlockProps) {
167175
onInput={onInput}
168176
onCompositionEnd={onCompositionEnd}
169177
{...offsetHandlers}
170-
onKeyDown={onKeyDown}
178+
onKeyDown={onKeyDownComposite}
171179
onPaste={onPaste}
172180
suppressContentEditableWarning={true}
173181
>

β€Žclient/src/hooks/useOffset.tsxβ€Ž

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,66 @@
1-
import { useRef } from 'react';
1+
import React, { useRef } from 'react';
22

3-
export function useOffset() {
3+
export function useOffset(blockRef: React.RefObject<HTMLParagraphElement>) {
44
const offsetRef = useRef<number | null>(null);
55

6-
const setOffset = () => {
6+
const setOffset = (offset = 0) => {
7+
if (!blockRef.current) return;
8+
79
const selection = window.getSelection();
810

911
if (selection?.rangeCount) {
1012
const range = selection.getRangeAt(0);
1113

12-
offsetRef.current = range.startOffset;
14+
const preCaretRange = range.cloneRange();
15+
preCaretRange.selectNodeContents(
16+
blockRef.current as HTMLParagraphElement,
17+
);
18+
preCaretRange.setEnd(range.endContainer, range.endOffset);
19+
const maxOffset = preCaretRange.toString().length;
20+
21+
const nextOffset = range.startOffset + offset;
22+
23+
offsetRef.current = Math.min(maxOffset, Math.max(0, nextOffset));
1324
}
1425
};
1526

1627
const clearOffset = () => {
1728
offsetRef.current = null;
1829
};
1930

31+
// keydown μ΄λ²€νŠΈλŠ” ν‚€ μž…λ ₯의 λ‚΄μš© 반영 이전에 λ°œμƒ
32+
const onKeyDown: React.KeyboardEventHandler = (e) => {
33+
const ARROW_LEFT = 'ArrowLeft';
34+
const ARROW_RIGHT = 'ArrowRight';
35+
36+
switch (e.nativeEvent.key) {
37+
case ARROW_LEFT:
38+
setOffset(-1);
39+
return;
40+
case ARROW_RIGHT:
41+
setOffset(1);
42+
return;
43+
}
44+
};
45+
46+
// μœ„ μ•„λž˜ λ°©ν–₯ν‚€ 이동은 ν•Έλ“€λ§ν•˜μ§€ μ•ŠμŒ
2047
const onKeyUp: React.KeyboardEventHandler = (e) => {
21-
const arrowKeys = ['ArrowRight', 'ArrowLeft', 'ArrowDown', 'ArrowUp'];
48+
const ARROW_DOWN = 'ArrowDown';
49+
const ARROW_UP = 'ArrowUp';
2250

23-
if (arrowKeys.includes(e.nativeEvent.key)) {
51+
if ([ARROW_DOWN, ARROW_UP].includes(e.nativeEvent.key)) {
2452
setOffset();
2553
}
2654
};
2755

2856
const offsetHandlers = {
29-
onFocus: setOffset,
30-
onClick: setOffset,
57+
onFocus:
58+
setOffset as unknown as React.FocusEventHandler<HTMLParagraphElement>,
59+
onClick:
60+
setOffset as unknown as React.MouseEventHandler<HTMLParagraphElement>,
3161
onBlur: clearOffset,
32-
onKeyUp: onKeyUp,
62+
onKeyDown,
63+
onKeyUp,
3364
};
3465

3566
return {

0 commit comments

Comments
Β (0)