Add 'Find and replace' option to menu on mobile (#6368)
This commit is contained in:
@@ -25,10 +25,18 @@ import { altDisplay, isModKey, metaDisplay } from "~/utils/keyboard";
|
||||
import { useEditor } from "./EditorContext";
|
||||
|
||||
type Props = {
|
||||
open: boolean;
|
||||
onOpen: () => void;
|
||||
onClose: () => void;
|
||||
readOnly?: boolean;
|
||||
};
|
||||
|
||||
export default function FindAndReplace({ readOnly }: Props) {
|
||||
export default function FindAndReplace({
|
||||
readOnly,
|
||||
open,
|
||||
onOpen,
|
||||
onClose,
|
||||
}: Props) {
|
||||
const editor = useEditor();
|
||||
const finalFocusRef = React.useRef<HTMLElement>(
|
||||
editor.view.dom.parentElement
|
||||
@@ -46,6 +54,12 @@ export default function FindAndReplace({ readOnly }: Props) {
|
||||
const popover = usePopoverState();
|
||||
const { show } = popover;
|
||||
|
||||
React.useEffect(() => {
|
||||
if (open) {
|
||||
show();
|
||||
}
|
||||
}, [open]);
|
||||
|
||||
// Hooks for desktop app menu items
|
||||
React.useEffect(() => {
|
||||
if (!Desktop.bridge) {
|
||||
@@ -209,6 +223,7 @@ export default function FindAndReplace({ readOnly }: Props) {
|
||||
|
||||
React.useEffect(() => {
|
||||
if (popover.visible) {
|
||||
onOpen();
|
||||
const startSearchText = selectionRef.current || searchTerm;
|
||||
|
||||
editor.commands.find({
|
||||
@@ -225,6 +240,7 @@ export default function FindAndReplace({ readOnly }: Props) {
|
||||
setSearchTerm(selectionRef.current);
|
||||
}
|
||||
} else {
|
||||
onClose();
|
||||
setShowReplace(false);
|
||||
editor.commands.clearSearch();
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import escapeRegExp from "lodash/escapeRegExp";
|
||||
import { observable } from "mobx";
|
||||
import { Node } from "prosemirror-model";
|
||||
import { Command, Plugin, PluginKey } from "prosemirror-state";
|
||||
import { Decoration, DecorationSet } from "prosemirror-view";
|
||||
@@ -68,6 +69,11 @@ export default class FindAndReplaceExtension extends Extension {
|
||||
* Clear the current search
|
||||
*/
|
||||
clearSearch: () => this.clear(),
|
||||
|
||||
/**
|
||||
* Open the find and replace UI
|
||||
*/
|
||||
openFindAndReplace: () => this.openFindAndReplace(),
|
||||
};
|
||||
}
|
||||
|
||||
@@ -142,6 +148,13 @@ export default class FindAndReplaceExtension extends Extension {
|
||||
};
|
||||
}
|
||||
|
||||
public openFindAndReplace(): Command {
|
||||
return (state, dispatch) => {
|
||||
dispatch?.(state.tr.setMeta(pluginKey, { open: true }));
|
||||
return true;
|
||||
};
|
||||
}
|
||||
|
||||
private get findRegExp() {
|
||||
try {
|
||||
return RegExp(
|
||||
@@ -275,6 +288,9 @@ export default class FindAndReplaceExtension extends Extension {
|
||||
const action = tr.getMeta(pluginKey);
|
||||
|
||||
if (action) {
|
||||
if (action.open) {
|
||||
this.open = true;
|
||||
}
|
||||
return this.createDeco(tr.doc);
|
||||
}
|
||||
|
||||
@@ -295,9 +311,21 @@ export default class FindAndReplaceExtension extends Extension {
|
||||
}
|
||||
|
||||
public widget = ({ readOnly }: WidgetProps) => (
|
||||
<FindAndReplace readOnly={readOnly} />
|
||||
<FindAndReplace
|
||||
readOnly={readOnly}
|
||||
open={this.open}
|
||||
onOpen={() => {
|
||||
this.open = true;
|
||||
}}
|
||||
onClose={() => {
|
||||
this.open = false;
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
||||
@observable
|
||||
private open = false;
|
||||
|
||||
private results: { from: number; to: number }[] = [];
|
||||
private currentResultIndex = 0;
|
||||
private searchTerm = "";
|
||||
|
||||
Reference in New Issue
Block a user