solid-suggest

Maintained by Antriksh Yadav. Contribute on GitHub.

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)}
      />
    </>
  );
}
        
        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
/>
        
        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:

  1. Set list-style: none on the suggestions ul, and remove any default padding.
  2. position: relative on the top level container, and position: absolute on the suggestions ul, along with top, bottom etc. positioning styles to fit your needs. This will allow the dropdown to overlap neighboring elements.
Everything else is really up to you. You can see some other recommendations above. Feel free to use them as they are, or customize to fit your branding.

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.