Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
C
coopwire-hypothesis
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
孙灵跃 Leon Sun
coopwire-hypothesis
Commits
54ecf795
Commit
54ecf795
authored
Jan 19, 2023
by
Lyza Danger Gardner
Committed by
Lyza Gardner
Jan 20, 2023
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Convert `SearchInput` to TS
parent
e418e397
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
34 additions
and
31 deletions
+34
-31
SearchInput.tsx
src/sidebar/components/SearchInput.tsx
+34
-31
No files found.
src/sidebar/components/SearchInput.
js
→
src/sidebar/components/SearchInput.
tsx
View file @
54ecf795
...
@@ -5,6 +5,7 @@ import {
...
@@ -5,6 +5,7 @@ import {
Spinner
,
Spinner
,
}
from
'@hypothesis/frontend-shared/lib/next'
;
}
from
'@hypothesis/frontend-shared/lib/next'
;
import
classnames
from
'classnames'
;
import
classnames
from
'classnames'
;
import
type
{
RefObject
}
from
'preact'
;
import
{
useCallback
,
useRef
,
useState
}
from
'preact/hooks'
;
import
{
useCallback
,
useRef
,
useState
}
from
'preact/hooks'
;
import
{
useShortcut
}
from
'../../shared/shortcut'
;
import
{
useShortcut
}
from
'../../shared/shortcut'
;
...
@@ -20,15 +21,14 @@ import { useSidebarStore } from '../store';
...
@@ -20,15 +21,14 @@ import { useSidebarStore } from '../store';
* (everyone else)
* (everyone else)
* - Restore previous focus when the user presses 'Escape' while the search
* - Restore previous focus when the user presses 'Escape' while the search
* input is focused.
* input is focused.
*
* @param {import('preact').RefObject<HTMLInputElement>} searchInputRef
*/
*/
function
useSearchKeyboardShortcuts
(
searchInputRef
)
{
function
useSearchKeyboardShortcuts
(
const
prevFocusRef
=
searchInputRef
:
RefObject
<
HTMLInputElement
>
/** @type {import('preact').RefObject<HTMLOrSVGElement>} */
(
useRef
());
)
{
const
prevFocusRef
=
useRef
<
HTMLOrSVGElement
|
null
>
(
null
);
const
focusSearch
=
useCallback
(
const
focusSearch
=
useCallback
(
/** @param {KeyboardEvent} event */
event
=>
{
(
event
:
KeyboardEvent
)
=>
{
// When user is in an input field, respond to CMD-/CTRL-K keypresses,
// When user is in an input field, respond to CMD-/CTRL-K keypresses,
// but ignore '/' keypresses
// but ignore '/' keypresses
if
(
if
(
...
@@ -39,12 +39,12 @@ function useSearchKeyboardShortcuts(searchInputRef) {
...
@@ -39,12 +39,12 @@ function useSearchKeyboardShortcuts(searchInputRef) {
)
{
)
{
return
;
return
;
}
}
prevFocusRef
.
current
=
/** @type {HTMLOrSVGElement|null} */
(
prevFocusRef
.
current
=
document
.
activeElement
as
HTMLOrSVGElement
|
null
;
document
.
activeElement
if
(
searchInputRef
.
current
)
{
);
searchInputRef
.
current
?.
focus
();
searchInputRef
.
current
?.
focus
();
event
.
preventDefault
();
event
.
preventDefault
();
event
.
stopPropagation
();
event
.
stopPropagation
();
}
},
},
[
searchInputRef
]
[
searchInputRef
]
);
);
...
@@ -66,15 +66,19 @@ function useSearchKeyboardShortcuts(searchInputRef) {
...
@@ -66,15 +66,19 @@ function useSearchKeyboardShortcuts(searchInputRef) {
useShortcut
(
'escape'
,
restoreFocus
);
useShortcut
(
'escape'
,
restoreFocus
);
}
}
/**
export
type
SearchInputProps
=
{
* @typedef SearchInputProps
/**
* @prop {boolean} [alwaysExpanded] -
* When true, the input field is always shown. If false, the input field is
* If true, the input field is always shown. If false, the input field is only shown
* only shown if the query is non-empty.
* if the query is non-empty.
* @prop {string|null} query - The currently active filter query
* @prop {(value: string) => void} onSearch -
* Callback to invoke when the current filter query changes
*/
*/
alwaysExpanded
?:
boolean
;
/** The currently-active filter query */
query
:
string
|
null
;
/** Callback for when the current filter query changes */
onSearch
:
(
value
:
string
)
=>
void
;
};
/**
/**
* An input field in the top bar for entering a query that filters annotations
* An input field in the top bar for entering a query that filters annotations
...
@@ -84,15 +88,15 @@ function useSearchKeyboardShortcuts(searchInputRef) {
...
@@ -84,15 +88,15 @@ function useSearchKeyboardShortcuts(searchInputRef) {
* This component also renders a eloading spinner to indicate when the client
* This component also renders a eloading spinner to indicate when the client
* is fetching for data from the API or in a "loading" state for any other
* is fetching for data from the API or in a "loading" state for any other
* reason.
* reason.
*
* @param {SearchInputProps} props
*/
*/
export
default
function
SearchInput
({
alwaysExpanded
,
query
,
onSearch
})
{
export
default
function
SearchInput
({
alwaysExpanded
,
query
,
onSearch
,
}:
SearchInputProps
)
{
const
store
=
useSidebarStore
();
const
store
=
useSidebarStore
();
const
isLoading
=
store
.
isLoading
();
const
isLoading
=
store
.
isLoading
();
const
input
=
/** @type {import('preact').RefObject<HTMLInputElement>} */
(
const
input
=
useRef
<
HTMLInputElement
|
null
>
(
null
);
useRef
()
);
useSearchKeyboardShortcuts
(
input
);
useSearchKeyboardShortcuts
(
input
);
// The active filter query from the previous render.
// The active filter query from the previous render.
...
@@ -101,8 +105,7 @@ export default function SearchInput({ alwaysExpanded, query, onSearch }) {
...
@@ -101,8 +105,7 @@ export default function SearchInput({ alwaysExpanded, query, onSearch }) {
// The query that the user is currently typing, but may not yet have applied.
// The query that the user is currently typing, but may not yet have applied.
const
[
pendingQuery
,
setPendingQuery
]
=
useState
(
query
);
const
[
pendingQuery
,
setPendingQuery
]
=
useState
(
query
);
/** @param {Event} e */
const
onSubmit
=
(
e
:
Event
)
=>
{
const
onSubmit
=
e
=>
{
e
.
preventDefault
();
e
.
preventDefault
();
if
(
input
.
current
?.
value
||
prevQuery
)
{
if
(
input
.
current
?.
value
||
prevQuery
)
{
// Don't set an initial empty query, but allow a later empty query to
// Don't set an initial empty query, but allow a later empty query to
...
@@ -176,8 +179,8 @@ export default function SearchInput({ alwaysExpanded, query, onSearch }) {
...
@@ -176,8 +179,8 @@ export default function SearchInput({ alwaysExpanded, query, onSearch }) {
disabled=
{
isLoading
}
disabled=
{
isLoading
}
elementRef=
{
input
}
elementRef=
{
input
}
value=
{
pendingQuery
||
''
}
value=
{
pendingQuery
||
''
}
onInput
=
{
e
=>
onInput=
{
(
e
:
Event
)
=>
setPendingQuery
(
/** @type {HTMLInputElement} */
(
e
.
targe
t
).
value
)
setPendingQuery
(
(
e
.
target
as
HTMLInputElemen
t
).
value
)
}
}
/>
/>
{
!
isLoading
&&
(
{
!
isLoading
&&
(
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment