From 822c311a0ae7ef65fe8b5e0dce40b919a42b8769 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Loi=CC=88c=20Correnson?= <loic.correnson@cea.fr> Date: Thu, 26 Nov 2020 09:55:42 +0100 Subject: [PATCH] [dome] trigger search field on Edit > Find (Cmd+F) --- ivette/src/dome/src/main/menubar.ts | 10 ++++++++++ ivette/src/dome/src/renderer/dome.tsx | 17 +++++++++++++---- ivette/src/dome/src/renderer/frame/toolbars.tsx | 12 +++++++++--- 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/ivette/src/dome/src/main/menubar.ts b/ivette/src/dome/src/main/menubar.ts index 292cfffe70f..b8db69299ff 100644 --- a/ivette/src/dome/src/main/menubar.ts +++ b/ivette/src/dome/src/main/menubar.ts @@ -162,6 +162,16 @@ const editMenuItems: MenuSpec = [ accelerator: 'CmdOrCtrl+A', role: 'selectAll', }, + Separator, + { + label: 'Find', + accelerator: 'CmdOrCtrl+F', + click: ( + _item: Electron.MenuItem, + window: Electron.BrowserWindow, + _evt: Electron.KeyboardEvent, + ) => window.webContents.send('dome.ipc.find'), + }, ]; // -------------------------------------------------------------------------- diff --git a/ivette/src/dome/src/renderer/dome.tsx b/ivette/src/dome/src/renderer/dome.tsx index dda75f74670..b1e1d879afc 100644 --- a/ivette/src/dome/src/renderer/dome.tsx +++ b/ivette/src/dome/src/renderer/dome.tsx @@ -98,13 +98,17 @@ export class Event<A = void> { } +/** Custom React Hook on event. */ export function useEvent<A>( - evt: Event<A>, + evt: undefined | null | Event<A>, callback: (arg: A) => void, ) { return React.useEffect(() => { - evt.on(callback); - return () => evt.off(callback); + if (evt) { + evt.on(callback); + return () => evt.off(callback); + } + return undefined; }); } @@ -126,9 +130,14 @@ export const update = new Event('dome.update'); It is emitted when the entire window is reloaded. */ export const reload = new Event('dome.reload'); - ipcRenderer.on('dome.ipc.reload', () => reload.emit()); +/** + Dome « Find » event. Trigered by [Cmd+F] and [Edit > Find] menu. + */ +export const find = new Event('dome.find'); +ipcRenderer.on('dome.ipc.find', () => find.emit()); + /** Command-line arguments event handler. */ export function onCommand( job: (argv: string[], workingDir: string) => void, diff --git a/ivette/src/dome/src/renderer/frame/toolbars.tsx b/ivette/src/dome/src/renderer/frame/toolbars.tsx index bb923b4baf2..e61e95841ea 100644 --- a/ivette/src/dome/src/renderer/frame/toolbars.tsx +++ b/ivette/src/dome/src/renderer/frame/toolbars.tsx @@ -8,6 +8,7 @@ */ import React from 'react'; +import { Event, useEvent, find } from 'dome'; import { debounce } from 'lodash'; import { SVG } from 'dome/controls/icons'; import { Label } from 'dome/controls/labels'; @@ -221,17 +222,24 @@ export interface SearchFieldProps<A> { onSearch?: (pattern: string, suggestions: A[]) => void; /** Suggestions Callback. */ onLookup?: (pattern: string) => Promise<Suggestion<A>[]>; + /** Triggering Event (defaults to [[Dome.find]]). */ + event?: null | Event<void>; } /** Search Bar. */ export function SearchField<A>(props: SearchFieldProps<A>) { - const { onLookup } = props; + const { onLookup, event = find } = props; const inputRef = React.useRef<HTMLInputElement | null>(null); + const blur = () => inputRef.current?.blur(); + const focus = () => inputRef.current?.focus(); const [value, setValue] = React.useState(''); const [items, setItems] = React.useState<Suggestion<A>[]>([]); + // Find event trigger + useEvent(event, focus); + // Lookup trigger const triggerLookup = React.useCallback(debounce((pattern: string) => { if (onLookup) onLookup(pattern).then(setItems).catch(); @@ -243,8 +251,6 @@ export function SearchField<A>(props: SearchFieldProps<A>) { setItems([]); }; - const blur = () => inputRef.current?.blur(); - // Key Events const onKeyUp = (evt: React.KeyboardEvent) => { if (evt.key === 'Escape') blur(); -- GitLab