Skip to content

Commit

Permalink
chore: update richtext editor to hooks (pinterest#1127)
Browse files Browse the repository at this point in the history
* chore: update richtext editor to hooks

* update snapshot
  • Loading branch information
czgu authored and aidenprice committed Jan 3, 2024
1 parent b4d822d commit 8d4acab
Show file tree
Hide file tree
Showing 7 changed files with 683 additions and 628 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ exports[`matches enzyme snapshots matches snapshot 1`] = `
<div
className="editor-wrapper"
>
<RichTextEditor
<ForwardRef
readOnly={true}
value="test"
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ import { IDataCellMetaBase } from 'const/datadoc';
import { SearchAndReplaceContext } from 'context/searchAndReplace';
import { useDebounceState } from 'hooks/redux/useDebounceState';
import { KeyMap, matchKeyMap } from 'lib/utils/keyboard';
import { RichTextEditor } from 'ui/RichTextEditor/RichTextEditor';
import {
IRichTextEditorHandles,
RichTextEditor,
} from 'ui/RichTextEditor/RichTextEditor';

import './DataDocTextCell.scss';

Expand Down Expand Up @@ -51,7 +54,7 @@ export const DataDocTextCell = React.memo<IProps>(
}) => {
const searchContext = useContext(SearchAndReplaceContext);
const [focused, setFocused] = useState(false);
const editorRef = useRef<RichTextEditor>(null);
const editorRef = useRef<IRichTextEditorHandles>(null);

const onChangeContext = useCallback(
(newContext: DraftJs.ContentState) => {
Expand Down Expand Up @@ -168,7 +171,7 @@ export const DataDocTextCell = React.memo<IProps>(
/>
<DraftJsSearchHighlighter
searchContext={searchContext}
editor={editorRef.current}
editorRef={editorRef}
cellId={cellId}
/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ import scrollIntoView from 'smooth-scroll-into-view-if-needed';
import { makeSearchHighlightDecorator } from 'components/SearchAndReplace/SearchHighlightDecorator';
import { ISearchAndReplaceContextType } from 'context/searchAndReplace';
import { LinkDecorator } from 'lib/richtext';
import { RichTextEditor } from 'ui/RichTextEditor/RichTextEditor';
import type { IRichTextEditorHandles } from 'ui/RichTextEditor/RichTextEditor';

export const DraftJsSearchHighlighter: React.FC<{
editor: RichTextEditor;
editorRef: React.MutableRefObject<IRichTextEditorHandles>;
cellId: number;
searchContext: ISearchAndReplaceContextType;
}> = ({ editor, cellId, searchContext }) => {
}> = ({ editorRef, cellId, searchContext }) => {
const {
searchState: {
searchResults,
Expand All @@ -23,23 +23,26 @@ export const DraftJsSearchHighlighter: React.FC<{
} = searchContext;

const shouldHighlight = useMemo(
() => editor && searchResults.some((r) => r.cellId === cellId),
[searchResults, cellId, editor]
() =>
editorRef.current && searchResults.some((r) => r.cellId === cellId),
[searchResults, cellId, editorRef]
);
useEffect(() => {
if (editor) {
if (editorRef.current) {
const decorators = [LinkDecorator];
if (shouldHighlight) {
decorators.push(
makeSearchHighlightDecorator(searchString, searchOptions)
);
}

editor.editorState = DraftJs.EditorState.set(editor.editorState, {
decorator: new DraftJs.CompositeDecorator(decorators),
});
editorRef.current.setEditorState(
DraftJs.EditorState.set(editorRef.current.getEditorState(), {
decorator: new DraftJs.CompositeDecorator(decorators),
})
);
}
}, [shouldHighlight, editor, searchString, searchOptions]);
}, [shouldHighlight, editorRef, searchString, searchOptions]);

// jump to item
const currentSearchItem = useMemo(() => {
Expand All @@ -51,7 +54,7 @@ export const DraftJsSearchHighlighter: React.FC<{
}, [currentSearchResultIndex, cellId, searchResults]);

useEffect(() => {
if (currentSearchItem && editor) {
if (currentSearchItem && editorRef.current) {
// editor.focus();
const selectionState: DraftJs.SelectionState =
new DraftJs.SelectionState({
Expand All @@ -62,17 +65,19 @@ export const DraftJsSearchHighlighter: React.FC<{
hasFocus: false,
isBackward: false,
});
editor.editorState = DraftJs.EditorState.forceSelection(
editor.editorState,
selectionState
editorRef.current.setEditorState(
DraftJs.EditorState.forceSelection(
editorRef.current.getEditorState(),
selectionState
)
);
setTimeout(() => {
// Known issues: Pressing enter too fast
// would cause the enter to be applied to the draft js
// rich text editor, so setting a force blur after 50ms
// to prevent the editor to be accidentally edited
const element = window.getSelection().focusNode.parentElement;
editor.draftJSEditor?.blur();
editorRef.current.getDraftJsEditor()?.blur();

setTimeout(() => {
// The DataDoc scrolls to the cell (sometimes its lazy loaded)
Expand Down
12 changes: 9 additions & 3 deletions querybook/webapp/hooks/useStateWithRef.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,15 @@ export function useStateWithRef<T>(initialVal: T | (() => T)) {
const [state, _setState] = useState<T>(initialVal);
const ref = useRef(state);

const setState = useCallback((newState: T) => {
_setState(newState);
ref.current = newState;
const setState = useCallback((newState: T | ((old: T) => T)) => {
_setState((old) => {
const newVal =
typeof newState === 'function'
? (newState as (old: T) => T)(old)
: newState;
ref.current = newVal;
return newVal;
});
}, []);

return [state, setState, ref] as const;
Expand Down
7 changes: 5 additions & 2 deletions querybook/webapp/ui/EditableTextField/EditableTextField.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@ import React, { useCallback } from 'react';

import { AsyncButton } from 'ui/AsyncButton/AsyncButton';
import { Button, TextButton } from 'ui/Button/Button';
import { RichTextEditor } from 'ui/RichTextEditor/RichTextEditor';
import {
IRichTextEditorHandles,
RichTextEditor,
} from 'ui/RichTextEditor/RichTextEditor';

import './EditableTextField.scss';

Expand All @@ -20,7 +23,7 @@ export const EditableTextField: React.FunctionComponent<
IEditableTextFieldProps
> = ({ value, onSave, className, placeholder, readonly = false }) => {
const [editMode, setEditMode] = React.useState(false);
const editorRef = React.useRef<RichTextEditor>(null);
const editorRef = React.useRef<IRichTextEditorHandles>(null);

const toggleEditMode = useCallback(
() =>
Expand Down
Loading

0 comments on commit 8d4acab

Please sign in to comment.