11"use client" ;
22
3- import React , { useEffect , useState } from "react" ;
3+ import React , { useEffect , useState , useReducer } from "react" ;
44import { useTranslation } from "./SearchBar" ;
55import { fr } from "../fr" ;
66import { assert } from "tsafe/assert" ;
@@ -17,7 +17,9 @@ export function SearchButton(props: SearchButtonProps) {
1717
1818 const { t } = useTranslation ( ) ;
1919
20- const [ inputValue , setInputValue ] = useState ( "" ) ;
20+ const [ , forceUpdate ] = useReducer ( x => x + 1 , 0 ) ;
21+
22+ const [ getInputValue , setGetInputValue ] = useState ( ( ) => ( ) => "" ) ;
2123
2224 const [ resetInputValue , setResetInputValue ] = useState < ( ) => void > ( ( ) => ( ) => {
2325 /* do nothing */
@@ -29,6 +31,8 @@ export function SearchButton(props: SearchButtonProps) {
2931 const [ isInputFocused , setIsInputFocused ] = useState ( false ) ;
3032
3133 const onClick = useConstCallback ( ( ) => {
34+ const inputValue = getInputValue ( ) ;
35+
3236 if ( inputValue === "" ) {
3337 focusInputElement ( ) ;
3438 return ;
@@ -38,6 +42,8 @@ export function SearchButton(props: SearchButtonProps) {
3842 resetInputValue ( ) ;
3943 } ) ;
4044
45+ const isControlledByUser = onClick_props === undefined ;
46+
4147 useEffect ( ( ) => {
4248 const inputElement = document . getElementById ( searchInputId ) ;
4349
@@ -49,21 +55,40 @@ export function SearchButton(props: SearchButtonProps) {
4955
5056 assert ( is < HTMLInputElement > ( inputElement ) ) ;
5157
52- setInputValue ( inputElement . value ) ;
58+ setGetInputValue ( ( ) => ( ) => inputElement . value ) ;
5359
5460 const cleanups : ( ( ) => void ) [ ] = [ ] ;
5561
5662 inputElement . addEventListener (
5763 "input" ,
5864 ( ( ) => {
59- const callback = ( ) => setInputValue ( inputElement . value ) ;
65+ const callback = ( ) => {
66+ forceUpdate ( ) ;
67+ } ;
6068
6169 cleanups . push ( ( ) => inputElement . removeEventListener ( "input" , callback ) ) ;
6270
6371 return callback ;
6472 } ) ( )
6573 ) ;
6674
75+ inputElement . addEventListener (
76+ "keydown" ,
77+ ( ( ) => {
78+ const callback = ( event : KeyboardEvent ) => {
79+ if ( event . key !== "Escape" ) {
80+ return ;
81+ }
82+
83+ forceUpdate ( ) ;
84+ } ;
85+
86+ cleanups . push ( ( ) => inputElement . removeEventListener ( "keydown" , callback ) ) ;
87+
88+ return callback ;
89+ } ) ( )
90+ ) ;
91+
6792 const resetInputValue = ( ) => {
6893 inputElement . value = "" ;
6994 inputElement . dispatchEvent ( new Event ( "input" ) ) ;
@@ -73,7 +98,7 @@ export function SearchButton(props: SearchButtonProps) {
7398
7499 setFocusInputElement ( ( ) => ( ) => inputElement . focus ( ) ) ;
75100
76- if ( onClick_props === undefined ) {
101+ if ( isControlledByUser ) {
77102 inputElement . addEventListener (
78103 "focus" ,
79104 ( ( ) => {
@@ -95,7 +120,9 @@ export function SearchButton(props: SearchButtonProps) {
95120 return callback ;
96121 } ) ( )
97122 ) ;
98- } else {
123+ }
124+
125+ if ( ! isControlledByUser ) {
99126 inputElement . addEventListener (
100127 "keydown" ,
101128 ( ( ) => {
@@ -136,9 +163,9 @@ export function SearchButton(props: SearchButtonProps) {
136163 return ( ) => {
137164 cleanups . forEach ( cleanup => cleanup ( ) ) ;
138165 } ;
139- } , [ searchInputId , onClick_props ] ) ;
166+ } , [ searchInputId , isControlledByUser ] ) ;
140167
141- if ( onClick_props === undefined && ( isInputFocused || inputValue !== "" ) ) {
168+ if ( onClick_props === undefined && ( isInputFocused || getInputValue ( ) !== "" ) ) {
142169 return null ;
143170 }
144171
0 commit comments