Skip to content

Commit

Permalink
Look up text in Chrome after composition ends
Browse files Browse the repository at this point in the history
  • Loading branch information
birtles committed Oct 4, 2019
1 parent a4433ea commit 4b324e7
Showing 1 changed file with 37 additions and 5 deletions.
42 changes: 37 additions & 5 deletions src/components/SearchBox.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,46 @@
import { h, FunctionalComponent } from 'preact';
import { useCallback, useEffect, useRef } from 'preact/hooks';

type Props = {
search?: string;
onUpdateSearch?: (search: string) => void;
};

export const SearchBox: FunctionalComponent<Props> = (props: Props) => {
// InputEvent.isComposing has a different value and different time between
// Firefox and Chrome. See:
//
// https://github.com/w3c/uievents/issues/202
//
// Furthermore, preact doesn't seem to support composition events:
//
// https://github.com/preactjs/preact/issues/1978
//
// But we don't want to update the search until the input has finished so we
// are forced to do a bit of a manual event handling here to detect the end of
// a composition (and avoid updating the result during a composition).
const input = useRef<HTMLInputElement | null>(null);
useEffect(() => {
if (!input.current) {
return;
}
input.current.addEventListener('compositionend', () => {
if (props.onUpdateSearch) {
props.onUpdateSearch(input.current!.value || '');
}
});
}, [input, props.onUpdateSearch]);

// Handle regular input events too (e.g. backspace, paste etc.).
const onInput = useCallback(
(evt: InputEvent) => {
if (props.onUpdateSearch && !evt.isComposing) {
props.onUpdateSearch((evt.target as HTMLInputElement).value || '');
}
},
[props.onUpdateSearch]
);

return (
<nav class="container mx-auto max-w-3xl -mt-half-input-text-2xl-py-6 mb-12 sm:mb-20 px-12">
<input
Expand All @@ -14,11 +49,8 @@ export const SearchBox: FunctionalComponent<Props> = (props: Props) => {
name="q"
placeholder="Search"
value={props.search}
onInput={(evt: InputEvent) => {
if (props.onUpdateSearch && !evt.isComposing) {
props.onUpdateSearch((evt.target as HTMLInputElement).value || '');
}
}}
ref={input}
onInput={onInput}
style={{
backgroundImage:
"url('data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%208%208%22%20fill%3D%22%23B8B2A7%22%3E%3Cpath%20d%3D%22M7.7%207.7a1%201%200%200%201-1.4%200L5.13%206.56a.5.5%200%200%201%200-.68l.01-.02-.4-.41a3%203%200%201%201%20.7-.7l.4.41.01-.02a.5.5%200%200%201%20.69%200L7.71%206.3a1%201%200%200%201%200%201.42zM3%201a2%202%200%201%200%200%204%202%202%200%200%200%200-4z%22%2F%3E%3C%2Fsvg%3E%0A')",
Expand Down

0 comments on commit 4b324e7

Please sign in to comment.