Skip to content

Commit

Permalink
Antoine: <SearchInput/> - return dynamic <form/> element
Browse files Browse the repository at this point in the history
  • Loading branch information
lakesare committed Jun 14, 2024
1 parent 7dccd0e commit dea7e51
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 20 deletions.
1 change: 1 addition & 0 deletions packages/@uppy/provider-views/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"dependencies": {
"@uppy/utils": "workspace:^",
"classnames": "^2.2.6",
"nanoid": "^5.0.0",
"p-queue": "^8.0.0",
"preact": "^10.5.13"
},
Expand Down
53 changes: 33 additions & 20 deletions packages/@uppy/provider-views/src/SearchInput.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { h } from 'preact'
import type { ChangeEvent } from 'preact/compat'
import { useEffect, useState, useCallback } from 'preact/hooks'
import { type ChangeEvent } from 'preact/compat'
import { nanoid } from 'nanoid/non-secure'

type Props = {
searchString: string
Expand Down Expand Up @@ -30,35 +32,46 @@ function SearchInput({
showButton = false,
buttonLabel = '',
}: Props) {
const onSubmitFromInput = (
e: h.JSX.TargetedKeyboardEvent<HTMLInputElement>,
) => {
if (e.key === 'Enter' || e.keyCode === 13) {
submitSearchString()
}
}

const onSubmitFromButton = () => {
submitSearchString()
}

const onInput = (e: ChangeEvent) => {
setSearchString((e.target as HTMLInputElement).value)
}

const submit = useCallback(
(ev: Event) => {
ev.preventDefault()
submitSearchString()
},
[submitSearchString],
)

// We do this to avoid nested <form>s
// (See https://github.com/transloadit/uppy/pull/5050#discussion_r1640392516)
const [form] = useState(() => {
const formEl = document.createElement('form')
formEl.setAttribute('tabindex', '-1')
formEl.id = nanoid()
return formEl
})

useEffect(() => {
document.body.appendChild(form)
form.addEventListener('submit', submit)
return () => {
form.removeEventListener('submit', submit)
document.body.removeChild(form)
}
}, [form, submit])

return (
// Notice we intentionally do not use the <form/> tag here,
// because we're trying to avoid the "nested <form/> tags" issue
// (see github.com/transloadit/uppy/pull/5050#discussion_r1638260456)
<section className={wrapperClassName} role="search">
<section className={wrapperClassName}>
<input
className={`uppy-u-reset ${inputClassName}`}
type="search"
aria-label={inputLabel}
placeholder={inputLabel}
value={searchString}
onInput={onInput}
onKeyDown={onSubmitFromInput}
form={form.id}
data-uppy-super-focusable
/>
{!showButton && (
Expand Down Expand Up @@ -96,8 +109,8 @@ function SearchInput({
{showButton && (
<button
className="uppy-u-reset uppy-c-btn uppy-c-btn-primary uppy-SearchProvider-searchButton"
type="button"
onClick={onSubmitFromButton}
type="submit"
form={form.id}
>
{buttonLabel}
</button>
Expand Down
1 change: 1 addition & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -8879,6 +8879,7 @@ __metadata:
dependencies:
"@uppy/utils": "workspace:^"
classnames: "npm:^2.2.6"
nanoid: "npm:^5.0.0"
p-queue: "npm:^8.0.0"
preact: "npm:^10.5.13"
vitest: "npm:^1.6.0"
Expand Down

0 comments on commit dea7e51

Please sign in to comment.