I'm trying to use a custom input and I've copied the example from the RBT Rendering example. My main goals are to add a test-id to the input, to remove the hint, and to use a custom component for the input. For some reason, when I select an option from the menu, it does not appear in my custom input like in the example. It's clearly set into state as it disappears from the available options. Do I need to wrap something else around my Form.Control
input?
Here's a working sandbox, but to avoid link-rot, I'll paste the component code below as well.
<Typeahead
id={`${testIdPrefix}-medal`}
labelKey="medal"
multiple
placeholder="Choose up to 2"
options={[
{ medal: "Gold" },
{ medal: "Silver" },
{ medal: "Bronze" },
{ medal: "Tin" }
]}
selected={multiSelections}
onChange={(selections) => setMultiSelections(selections.slice(-2))}
renderInput={({ inputRef, referenceElementRef, ...inputProps }) => (
<Form.Control
test-id={`${testIdPrefix}-medal`}
{...inputProps}
ref={(node) => {
inputRef(node);
referenceElementRef(node);
}}
/>
)}
renderToken={(option, { onRemove }, index) => (
<Token
key={index}
onRemove={onRemove}
option={option}
className="medal-token"
>
{`${option.medal}`}
</Token>
)}
/>
To reproduce:
Note: this also happens without the custom Token
but I included it in case that's relevant to the solution. (I need the solution to work with a custom token.)
Yes, multiple={true}
is the issue. renderToken
is a hook into the built-in multi-selection component to customize token rendering, but won't be called if you use renderInput
. In that case, you need to handle rendering the selections as tokens yourself.
As a quick example/test, you should be able to simply render the selections below your input in renderInput
:
renderInput={({ inputRef, referenceElementRef, onRemove, selected ...inputProps }) => (
<>
<Form.Control
test-id={`${testIdPrefix}-medal`}
{...inputProps}
ref={(node) => {
inputRef(node);
referenceElementRef(node);
}}
/>
{selected.map((option, idx) => (
<Token
key={idx}
onRemove={onRemove}
option={option}
className="medal-token"
>
{option.medal}
</Token>
))}
</>
)}