Skip to content

Commit

Permalink
combobox: clear input on form reset (#940)
Browse files Browse the repository at this point in the history
  • Loading branch information
chaance committed Jul 13, 2022
1 parent b73db04 commit abdf67a
Show file tree
Hide file tree
Showing 3 changed files with 104 additions and 2 deletions.
19 changes: 17 additions & 2 deletions packages/combobox/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,22 @@ export const ComboboxInput = React.forwardRef(
}
}, [controlledValue, handleValueChange, isControlled, value]);

// If a form is reset, we'll need to manually clear the value since we are
// controlling it internally.
React.useEffect(() => {
let form = inputRef.current?.form;
if (!form) return;

function handleReset(event: Event) {
transition(CLEAR, { isControlled });
}

form.addEventListener("reset", handleReset);
return () => {
form?.removeEventListener("reset", handleReset);
};
}, [inputRef, isControlled, transition]);

// [*]... and when controlled, we don't trigger handleValueChange as the
// user types, instead the developer controls it with the normal input
// onChange prop
Expand Down Expand Up @@ -1237,8 +1253,7 @@ function makeHash(str: string) {
return hash;
}
for (let i = 0; i < str.length; i++) {
var char = str.charCodeAt(i);
hash = (hash << 5) - hash + char;
hash = (hash << 5) - hash + str.charCodeAt(i);
hash = hash & hash;
}
return hash;
Expand Down
86 changes: 86 additions & 0 deletions playground/stories/combobox/in-form.example.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import * as React from "react";
import {
Combobox,
ComboboxInput,
ComboboxList,
ComboboxOption,
ComboboxPopover,
} from "@reach/combobox";
import { Alert } from "@reach/alert";
import { useCityMatch } from "./utils";
import "@reach/combobox/styles.css";

let name = "In a form";

function showOpts<R>(
results: R[],
render: (props: { result: R; index: number }) => React.ReactNode
) {
return results.slice(0, 10).map((result, index) => render({ result, index }));
}

function MyCombobox() {
let [term, setTerm] = React.useState("");
let [showAlert, setShowAlert] = React.useState(false);
let results = useCityMatch(term);
let tid = React.useRef(-1);
React.useEffect(() => {
return () => {
// eslint-disable-next-line react-hooks/exhaustive-deps
window.clearTimeout(tid.current);
};
}, []);

return (
<div>
<form
onSubmit={(event) => {
event.preventDefault();
window.clearTimeout(tid.current);
setShowAlert(true);
tid.current = window.setTimeout(() => {
setShowAlert(false);
}, 3000);
}}
>
<label>
<div>Name</div>
<input type="text" name="name" />
</label>
<Combobox as="label">
<div>City</div>
<ComboboxInput
onChange={(event: any) => setTerm(event.target.value)}
autoComplete="off"
autoCorrect="off"
autoSave="off"
/>
{results ? (
<ComboboxPopover portal={false}>
<ComboboxList as="ul">
{showOpts(results, ({ result, index }) => (
<ComboboxOption as="li" key={index} value={result.city} />
))}
</ComboboxList>
</ComboboxPopover>
) : null}
</Combobox>
<div>
<button>Submit</button>
<button type="reset">Reset</button>
</div>
</form>
<hr />
{showAlert ? <Alert>Submitted!</Alert> : null}
</div>
);
}

function Example() {
return <MyCombobox />;
}

Example.storyName = name;
export { Example };

////////////////////////////////////////////////////////////////////////////////
1 change: 1 addition & 0 deletions playground/stories/combobox/index.story.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export { Example as Basic } from "./basic.example";
export { Example as ControlledTs } from "./controlled.example";
export { Example as LotsOfElements } from "./lots-of-elements.example";
export { Example as NoPopover } from "./no-popover.example";
export { Example as InForm } from "./in-form.example";
export { Example as OpenOnFocus } from "./open-on-focus.example";
// export { Example as SimulatedChange } from "./simulated-change.example.js";
export { Example as TokenInput } from "./token-input.example";
Expand Down

0 comments on commit abdf67a

Please sign in to comment.