Very basic usage
Plain text suggestions, no styling
import Suggest from "solid-suggest";
const items = ["Apple", "Banana", "Cherry", "Date", "Elderberry", "Fig", "Grape", "Honeydew", "Kiwi", "Lemon"];
function Example() {
const [selected, setSelected] = createSignal("none");
return (
<>
<p>Selected: {selected()}</p>
<Suggest
renderSuggestion={item => item}
onQuery={query =>
items.filter(item =>
item.toLowerCase().includes(query.toLowerCase())
)
}
onSelect={setSelected}
/>
</>
)
}
Realistic usage
Objects as suggestions, with styling
JSX
import Suggest from "solid-suggest";
const items = [
{ name: "Eiffel Tower", kind: "Monument", rating: 5 },
{ name: "Great Wall of China", kind: "Historical Site", rating: 5 },
{ name: "Statue of Liberty", kind: "Monument", rating: 3 },
// ...more items...
];
function renderSearchItem(item) {
return
`${item.name} - ${item.kind} (${Array(item.rating).fill("★").join("")})`;
}
function Example() {
const [selected, setSelected] = createSignal("none");
return (
<>
<p>Selected: {selected()}</p>
<Suggest
renderSuggestion={renderSearchItem}
onQuery={query =>
items.filter(
item =>
item.name.toLowerCase().includes(query.toLowerCase()) ||
item.kind.toLowerCase().includes(query.toLowerCase())
)
}
onSelect={item => setSelected(item.name)}
placeholder="Search historical sites"
/>
</>
);
}
CSS
.s-sug-container {
width: 25em;
position: relative;
input {
width: 100%;
}
ul {
display: flex;
flex-direction: column;
max-height: 20em;
width: 100%;
margin: 0.25em 0 0;
padding: 0.25em 0 0 0;
position: absolute;
top: 1lh;
left: 0;
list-style: none;
box-shadow: lightgray 0 0.25em 0.5em;
background-color: #fff;
border-radius: 5px;
overflow-y: scroll;
li {
padding: 0.25em;
&[data-staged="true"] {
background-color: var(--accent);
}
}
}
}
Upside-down suggestions, debounce
Arrow keys reversed, CSS to reverse UI elements, 500ms debounce
JSX
// Same as above, but with these changes
<Suggest
// ...
reverseKeyInput={true}
debounceMs={500} // Debounce input by 500ms
placeholder="Search Overwatch heroes"
/>
CSS
/* Same as above, but with these changes */
.s-sug-container {
display: flex;
flex-direction: column-reverse;
ul {
flex-direction: column-reverse;
margin: 0 0 0.25em;
bottom: 1lh; /* top not set */
left: 0;
}
}
/* Plus, styles on the container to intentionally leave room */
General tips
Q. How do I supply suggestions to solid-suggest?
Using onQuery. solid-suggest relies on your application to track what suggestions should render at any time. onQuery is invoked at initial render and every time the user's query updates.
Q. Does solid-suggest come with any styling?
No. This is a completely headless library that gives you the bones of a suggestions dropdown. This includes semantic DOM elements, handling of mouse and keyboard input, and SolidJS reactivity. All styling is provided by the developer-user of solid-suggest.
Q. Any styling recommendations?
Yes. At minimum, developers will likely want to:
- Set
list-style: noneon the suggestionsul, and remove any default padding. position: relativeon the top level container, andposition: absoluteon the suggestionsul, along withtop,bottometc. positioning styles to fit your needs. This will allow the dropdown to overlap neighboring elements.
Q. How can I hide the dropdown until user input?
Supply solid-suggest with an onQuery that returns an empty array when the user's query is blank, like the following examples. Note how this leaves room for a lot of custom behavior.
const onQuery = query => query ? /* compute suggestions */ : [];
return (
...
<Suggest ... onQuery={onQuery} ... />
...
);
function onQuery(query) {
if (!query) return [];
/* else, compute and return suggestions */
}
return (
...
<Suggest ... onQuery={onQuery} ... />
...
);
Q. Can I fetch search suggestions from network calls?
Sure! solid-suggest doesn't provide network fetch as a built-in feature, but you can do whatever you want in your onQuery implementation. Consider supplying a debounceMs prop to delay onQuery triggers after user input, reducing network calls.