solid-suggest 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/README.md +94 -0
- package/dist/basic.css +3 -0
- package/dist/index.cjs +123 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.js +121 -0
- package/dist/index.js.map +1 -0
- package/package.json +59 -0
package/LICENSE
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
Copyright 2025 Antriksh Yadav
|
2
|
+
|
3
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
4
|
+
|
5
|
+
THE SOFTWARE IS PROVIDED “AS IS” AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
@@ -0,0 +1,94 @@
|
|
1
|
+
# solid-suggest
|
2
|
+
|
3
|
+
solid-suggest is a UI component for SolidJS developers that renders a text input with dropdown suggestions. It can be used in scenarios such as search suggestions or results triggered by text input.
|
4
|
+
|
5
|
+
It's a *super* simple library without many batteries included. See following sections for what it can and can't do for you.
|
6
|
+
|
7
|
+
**Because of its simplicity, I also expect it to be usable even without updates for years.**
|
8
|
+
|
9
|
+
## Quickstart
|
10
|
+
|
11
|
+
Install from the npm registry using `npm` or your favorite alternate package manager (yarn, pnpm).
|
12
|
+
|
13
|
+
```
|
14
|
+
npm install solid-suggest --save
|
15
|
+
```
|
16
|
+
|
17
|
+
Import into your SolidJS project.
|
18
|
+
|
19
|
+
```
|
20
|
+
import Suggest from "solid-suggest";
|
21
|
+
|
22
|
+
const items = [
|
23
|
+
{ name: "Scout", class: "Offense" },
|
24
|
+
{ name: "Medic", class: "Support" },
|
25
|
+
{ name: "Heavy", class: "Defense" }
|
26
|
+
];
|
27
|
+
|
28
|
+
<Suggest
|
29
|
+
renderSuggestion={item => `${item.name} (${item.class})`}
|
30
|
+
onQuery={query =>
|
31
|
+
items.filter(
|
32
|
+
item =>
|
33
|
+
item.name.toLowerCase().includes(query.toLowerCase()) ||
|
34
|
+
item.class.toLowerCase().includes(query.toLowerCase())
|
35
|
+
)
|
36
|
+
}
|
37
|
+
onSelect={item => setSelected(item.name)}
|
38
|
+
/>
|
39
|
+
```
|
40
|
+
|
41
|
+
See more [in the docs](https://antrikshy.com/solid-suggest).
|
42
|
+
|
43
|
+
## What it Does
|
44
|
+
|
45
|
+
Exposes two main interfaces as functions that you implement:
|
46
|
+
|
47
|
+
1. `onQuery` - solid-suggest runs it on initial render and on each user input change. For solid-suggest, your implementation answers the question "what suggestions should solid-suggest show in the current state?"
|
48
|
+
2. `onSelect` - solid-suggest invokes this to emit the user's selection to your code.
|
49
|
+
|
50
|
+
All this library does is provide JavaScript/TypeScript bones for a suggestions dropdown so that you don't have to clutter your application with the required internal states, keyboard and mouse handling, etc.
|
51
|
+
|
52
|
+
- Supports objects as suggestions (not just strings), with support for custom rendering of each suggestion.
|
53
|
+
- Supports optional debouncing of user input via the `debounceMs` prop (in milliseconds). If not set or zero, input is not debounced.
|
54
|
+
- Styling is still supplied by you.
|
55
|
+
|
56
|
+
Some more questions are answered [in the docs](https://antrikshy.com/solid-suggest).
|
57
|
+
|
58
|
+
## What it Doesn't Do
|
59
|
+
|
60
|
+
1. Come with *any* styling. solid-suggest is a **headless** library that completely relies on the you to style. This way, it fully integrates with any branding and design system.
|
61
|
+
2. Provide built-in network fetch capabilities. You are free to make network calls this in their `onQuery` implementations. Consider supplying a `debounceMs` value to reduce network calls.
|
62
|
+
3. Wash your car.
|
63
|
+
|
64
|
+
Some more questions are answered [in the docs](https://antrikshy.com/solid-suggest).
|
65
|
+
|
66
|
+
## Docs + Recommendations
|
67
|
+
|
68
|
+
Find [documentation and tips here](https://antrikshy.com/solid-suggest).
|
69
|
+
|
70
|
+
## Development
|
71
|
+
|
72
|
+
```
|
73
|
+
npm install
|
74
|
+
```
|
75
|
+
|
76
|
+
... before anything else.
|
77
|
+
|
78
|
+
```
|
79
|
+
npm run devOnly
|
80
|
+
```
|
81
|
+
|
82
|
+
... runs a continuous watcher for changes to *library code* that transpiles TypeScript to a dist/ dir at project top level.
|
83
|
+
|
84
|
+
```
|
85
|
+
npm run devDemo
|
86
|
+
```
|
87
|
+
|
88
|
+
... runs a local server that you can use to see and iterate on the demo page at http://localhost:8000/docs/index.htm. This is a basic HTML page that imports some libraries from CDNs. Hot reload/replacement is not enabled, so it needs manual refreshing.
|
89
|
+
|
90
|
+
```
|
91
|
+
npm run devWithDemo
|
92
|
+
```
|
93
|
+
|
94
|
+
... runs both of the above at the same time.
|
package/dist/basic.css
ADDED
package/dist/index.cjs
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
'use strict';
|
2
|
+
|
3
|
+
var web = require('solid-js/web');
|
4
|
+
var solidJs = require('solid-js');
|
5
|
+
|
6
|
+
var _tmpl$ = /*#__PURE__*/web.template(`<div class=s-sug-container role=combobox aria-haspopup=listbox><input type=search class=s-sug-search aria-autocomplete=list>`),
|
7
|
+
_tmpl$2 = /*#__PURE__*/web.template(`<ul class=s-sug-suggestions role=listbox>`),
|
8
|
+
_tmpl$3 = /*#__PURE__*/web.template(`<li class=s-sug-suggestion role=option>`);
|
9
|
+
function Suggest(props) {
|
10
|
+
// Basic signals for component state
|
11
|
+
const [query, setQuery] = solidJs.createSignal('');
|
12
|
+
const [staged, setStaged] = solidJs.createSignal(null);
|
13
|
+
// Internal signal for user input, separate from query to handle optional debounce
|
14
|
+
const [debouncedQuery, setDebouncedQuery] = solidJs.createSignal('');
|
15
|
+
// Just a variable to store debounce timeout, if applicable
|
16
|
+
let debounceTimeout = null;
|
17
|
+
const suggestions = solidJs.createMemo(() => props.onQuery(debouncedQuery()));
|
18
|
+
const numSuggestions = solidJs.createMemo(() => suggestions().length);
|
19
|
+
function handleInput(e) {
|
20
|
+
const value = e.currentTarget.value;
|
21
|
+
setQuery(value);
|
22
|
+
if (typeof props.debounceMs === 'number' && props.debounceMs > 0) {
|
23
|
+
if (debounceTimeout) clearTimeout(debounceTimeout);
|
24
|
+
debounceTimeout = setTimeout(() => {
|
25
|
+
setDebouncedQuery(value);
|
26
|
+
}, props.debounceMs);
|
27
|
+
} else {
|
28
|
+
setDebouncedQuery(value);
|
29
|
+
}
|
30
|
+
}
|
31
|
+
function stageSuggestion(index) {
|
32
|
+
setStaged(index);
|
33
|
+
}
|
34
|
+
function stageNextSuggestion() {
|
35
|
+
setStaged(s => {
|
36
|
+
if (suggestions().length === 0) return null;
|
37
|
+
const current = s ?? -1;
|
38
|
+
return (current + 1) % numSuggestions();
|
39
|
+
});
|
40
|
+
}
|
41
|
+
function stagePrevSuggestion() {
|
42
|
+
setStaged(s => {
|
43
|
+
if (numSuggestions() === 0) return null;
|
44
|
+
const current = s ?? 0;
|
45
|
+
return (current - 1 + numSuggestions()) % numSuggestions();
|
46
|
+
});
|
47
|
+
}
|
48
|
+
function selectStagedSuggestion() {
|
49
|
+
const index = staged();
|
50
|
+
if (index !== null) {
|
51
|
+
props.onSelect(suggestions()[index]);
|
52
|
+
reset();
|
53
|
+
}
|
54
|
+
}
|
55
|
+
function reset() {
|
56
|
+
setQuery('');
|
57
|
+
setDebouncedQuery('');
|
58
|
+
setStaged(null);
|
59
|
+
if (debounceTimeout) clearTimeout(debounceTimeout);
|
60
|
+
}
|
61
|
+
// Handles special input for suggestion behavior
|
62
|
+
function handleKeyDown(e) {
|
63
|
+
const keyInputReversed = props.reverseKeyInput ?? false;
|
64
|
+
if (e.key === 'ArrowDown') {
|
65
|
+
e.preventDefault();
|
66
|
+
if (keyInputReversed) {
|
67
|
+
stagePrevSuggestion();
|
68
|
+
} else {
|
69
|
+
stageNextSuggestion();
|
70
|
+
}
|
71
|
+
} else if (e.key === 'ArrowUp') {
|
72
|
+
e.preventDefault();
|
73
|
+
if (keyInputReversed) {
|
74
|
+
stageNextSuggestion();
|
75
|
+
} else {
|
76
|
+
stagePrevSuggestion();
|
77
|
+
}
|
78
|
+
} else if (e.key === 'Enter') {
|
79
|
+
e.preventDefault();
|
80
|
+
selectStagedSuggestion();
|
81
|
+
} else if (e.key === 'Escape') {
|
82
|
+
e.preventDefault();
|
83
|
+
reset();
|
84
|
+
}
|
85
|
+
// else -> propagates up to allow input
|
86
|
+
}
|
87
|
+
return (() => {
|
88
|
+
var _el$ = _tmpl$(),
|
89
|
+
_el$2 = _el$.firstChild;
|
90
|
+
web.addEventListener(_el$2, "keydown", handleKeyDown);
|
91
|
+
web.addEventListener(_el$2, "input", handleInput);
|
92
|
+
web.insert(_el$, (() => {
|
93
|
+
var _c$ = web.memo(() => numSuggestions() > 0);
|
94
|
+
return () => _c$() && (() => {
|
95
|
+
var _el$3 = _tmpl$2();
|
96
|
+
web.insert(_el$3, () => suggestions().map((s, i) => (() => {
|
97
|
+
var _el$4 = _tmpl$3();
|
98
|
+
web.addEventListener(_el$4, "click", selectStagedSuggestion);
|
99
|
+
web.addEventListener(_el$4, "mouseenter", () => stageSuggestion(i));
|
100
|
+
web.insert(_el$4, () => props.renderSuggestion(s));
|
101
|
+
web.effect(_p$ => {
|
102
|
+
var _v$ = staged() === i,
|
103
|
+
_v$2 = staged() === i ? 'true' : 'false';
|
104
|
+
_v$ !== _p$.e && web.setAttribute(_el$4, "data-staged", _p$.e = _v$);
|
105
|
+
_v$2 !== _p$.t && web.setAttribute(_el$4, "aria-selected", _p$.t = _v$2);
|
106
|
+
return _p$;
|
107
|
+
}, {
|
108
|
+
e: undefined,
|
109
|
+
t: undefined
|
110
|
+
});
|
111
|
+
return _el$4;
|
112
|
+
})()));
|
113
|
+
return _el$3;
|
114
|
+
})();
|
115
|
+
})(), null);
|
116
|
+
web.effect(() => web.setAttribute(_el$, "aria-expanded", numSuggestions() > 0));
|
117
|
+
web.effect(() => _el$2.value = query());
|
118
|
+
return _el$;
|
119
|
+
})();
|
120
|
+
}
|
121
|
+
|
122
|
+
module.exports = Suggest;
|
123
|
+
//# sourceMappingURL=index.cjs.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.cjs","sources":["../src/index.tsx"],"sourcesContent":["import { createMemo, createSignal } from 'solid-js'\n\nexport interface SuggestProps<T = string> {\n onQuery: (query: string) => T[], // Suggestions assumed ordered by client\n onSelect: (suggestion: T) => void,\n renderSuggestion: (suggestion: T) => HTMLElement,\n reverseKeyInput?: boolean,\n debounceMs?: number, // Debounce period in milliseconds\n}\n\nexport default function Suggest(props: SuggestProps) {\n // Basic signals for component state\n const [query, setQuery] = createSignal('');\n const [staged, setStaged] = createSignal<number | null>(null);\n // Internal signal for user input, separate from query to handle optional debounce\n const [debouncedQuery, setDebouncedQuery] = createSignal('');\n\n // Just a variable to store debounce timeout, if applicable\n let debounceTimeout: ReturnType<typeof setTimeout> | null = null;\n\n const suggestions = createMemo(() => props.onQuery(debouncedQuery()));\n const numSuggestions = createMemo(() => suggestions().length);\n\n function handleInput(e: Event) {\n const value = (e.currentTarget as HTMLInputElement).value;\n setQuery(value);\n if (typeof props.debounceMs === 'number' && props.debounceMs > 0) {\n if (debounceTimeout) clearTimeout(debounceTimeout);\n debounceTimeout = setTimeout(() => {\n setDebouncedQuery(value);\n }, props.debounceMs);\n } else {\n setDebouncedQuery(value);\n }\n }\n\n function stageSuggestion(index: number) {\n setStaged(index);\n }\n\n function stageNextSuggestion() {\n setStaged(s => {\n if (suggestions().length === 0) return null;\n const current = s ?? -1;\n return (current + 1) % numSuggestions();\n });\n };\n\n function stagePrevSuggestion() {\n setStaged(s => {\n if (numSuggestions() === 0) return null;\n const current = s ?? 0;\n return (current - 1 + numSuggestions()) % numSuggestions();\n });\n };\n\n function selectStagedSuggestion() {\n const index = staged()\n if (index !== null) {\n props.onSelect(suggestions()[index]);\n reset();\n }\n }\n\n function reset() {\n setQuery('');\n setDebouncedQuery('');\n setStaged(null);\n if (debounceTimeout) clearTimeout(debounceTimeout);\n }\n\n // Handles special input for suggestion behavior\n function handleKeyDown(e: KeyboardEvent) {\n const keyInputReversed = props.reverseKeyInput ?? false;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (keyInputReversed) {\n stagePrevSuggestion();\n } else {\n stageNextSuggestion();\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (keyInputReversed) {\n stageNextSuggestion();\n } else {\n stagePrevSuggestion();\n }\n } else if (e.key === 'Enter') {\n e.preventDefault();\n selectStagedSuggestion();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n reset();\n }\n // else -> propagates up to allow input\n }\n\n return <div\n class='s-sug-container'\n role='combobox'\n aria-expanded={numSuggestions() > 0}\n aria-haspopup='listbox'\n >\n <input\n type='search'\n class='s-sug-search'\n value={query()}\n on:input={handleInput}\n on:keydown={handleKeyDown}\n aria-autocomplete='list'\n />\n {numSuggestions() > 0 &&\n <ul class='s-sug-suggestions' role='listbox'>\n {suggestions().map((s, i) => (\n <li\n class='s-sug-suggestion'\n data-staged={staged() === i}\n role='option'\n on:mouseenter={() => stageSuggestion(i)}\n on:click={selectStagedSuggestion}\n aria-selected={staged() === i ? 'true' : 'false'}\n >\n {props.renderSuggestion(s)}\n </li>)\n )}\n </ul>\n }\n </div>\n}\n"],"names":["Suggest","props","query","setQuery","createSignal","staged","setStaged","debouncedQuery","setDebouncedQuery","debounceTimeout","suggestions","createMemo","onQuery","numSuggestions","length","handleInput","e","value","currentTarget","debounceMs","clearTimeout","setTimeout","stageSuggestion","index","stageNextSuggestion","s","current","stagePrevSuggestion","selectStagedSuggestion","onSelect","reset","handleKeyDown","keyInputReversed","reverseKeyInput","key","preventDefault","_el$","_tmpl$","_el$2","firstChild","_$addEventListener","_$insert","_c$","_$memo","_el$3","_tmpl$2","map","i","_el$4","_tmpl$3","renderSuggestion","_$effect","_p$","_v$","_v$2","_$setAttribute","t","undefined"],"mappings":";;;;;;;;AAUwB,SAAAA,OAAOA,CAACC,KAAmB,EAAA;AACjD;EACA,MAAM,CAACC,KAAK,EAAEC,QAAQ,CAAC,GAAGC,oBAAY,CAAC,EAAE,CAAC;EAC1C,MAAM,CAACC,MAAM,EAAEC,SAAS,CAAC,GAAGF,oBAAY,CAAgB,IAAI,CAAC;AAC7D;EACA,MAAM,CAACG,cAAc,EAAEC,iBAAiB,CAAC,GAAGJ,oBAAY,CAAC,EAAE,CAAC;AAE5D;EACA,IAAIK,eAAe,GAAyC,IAAI;AAEhE,EAAA,MAAMC,WAAW,GAAGC,kBAAU,CAAC,MAAMV,KAAK,CAACW,OAAO,CAACL,cAAc,EAAE,CAAC,CAAC;EACrE,MAAMM,cAAc,GAAGF,kBAAU,CAAC,MAAMD,WAAW,EAAE,CAACI,MAAM,CAAC;EAE7D,SAASC,WAAWA,CAACC,CAAQ,EAAA;AAC3B,IAAA,MAAMC,KAAK,GAAID,CAAC,CAACE,aAAkC,CAACD,KAAK;IACzDd,QAAQ,CAACc,KAAK,CAAC;AACf,IAAA,IAAI,OAAOhB,KAAK,CAACkB,UAAU,KAAK,QAAQ,IAAIlB,KAAK,CAACkB,UAAU,GAAG,CAAC,EAAE;AAChE,MAAA,IAAIV,eAAe,EAAEW,YAAY,CAACX,eAAe,CAAC;MAClDA,eAAe,GAAGY,UAAU,CAAC,MAAK;QAChCb,iBAAiB,CAACS,KAAK,CAAC;AAC1B,OAAC,EAAEhB,KAAK,CAACkB,UAAU,CAAC;AACtB,KAAC,MAAM;MACLX,iBAAiB,CAACS,KAAK,CAAC;AAC1B;AACF;EAEA,SAASK,eAAeA,CAACC,KAAa,EAAA;IACpCjB,SAAS,CAACiB,KAAK,CAAC;AAClB;EAEA,SAASC,mBAAmBA,GAAA;IAC1BlB,SAAS,CAACmB,CAAC,IAAG;MACZ,IAAIf,WAAW,EAAE,CAACI,MAAM,KAAK,CAAC,EAAE,OAAO,IAAI;AAC3C,MAAA,MAAMY,OAAO,GAAGD,CAAC,IAAI,EAAE;AACvB,MAAA,OAAO,CAACC,OAAO,GAAG,CAAC,IAAIb,cAAc,EAAE;AACzC,KAAC,CAAC;AACJ;EAEA,SAASc,mBAAmBA,GAAA;IAC1BrB,SAAS,CAACmB,CAAC,IAAG;AACZ,MAAA,IAAIZ,cAAc,EAAE,KAAK,CAAC,EAAE,OAAO,IAAI;AACvC,MAAA,MAAMa,OAAO,GAAGD,CAAC,IAAI,CAAC;MACtB,OAAO,CAACC,OAAO,GAAG,CAAC,GAAGb,cAAc,EAAE,IAAIA,cAAc,EAAE;AAC5D,KAAC,CAAC;AACJ;EAEA,SAASe,sBAAsBA,GAAA;AAC7B,IAAA,MAAML,KAAK,GAAGlB,MAAM,EAAE;IACtB,IAAIkB,KAAK,KAAK,IAAI,EAAE;MAClBtB,KAAK,CAAC4B,QAAQ,CAACnB,WAAW,EAAE,CAACa,KAAK,CAAC,CAAC;AACpCO,MAAAA,KAAK,EAAE;AACT;AACF;EAEA,SAASA,KAAKA,GAAA;IACZ3B,QAAQ,CAAC,EAAE,CAAC;IACZK,iBAAiB,CAAC,EAAE,CAAC;IACrBF,SAAS,CAAC,IAAI,CAAC;AACf,IAAA,IAAIG,eAAe,EAAEW,YAAY,CAACX,eAAe,CAAC;AACpD;AAEA;EACA,SAASsB,aAAaA,CAACf,CAAgB,EAAA;AACrC,IAAA,MAAMgB,gBAAgB,GAAG/B,KAAK,CAACgC,eAAe,IAAI,KAAK;AACvD,IAAA,IAAIjB,CAAC,CAACkB,GAAG,KAAK,WAAW,EAAE;MACzBlB,CAAC,CAACmB,cAAc,EAAE;AAClB,MAAA,IAAIH,gBAAgB,EAAE;AACpBL,QAAAA,mBAAmB,EAAE;AACvB,OAAC,MAAM;AACLH,QAAAA,mBAAmB,EAAE;AACvB;AACF,KAAC,MAAM,IAAIR,CAAC,CAACkB,GAAG,KAAK,SAAS,EAAE;MAC9BlB,CAAC,CAACmB,cAAc,EAAE;AAClB,MAAA,IAAIH,gBAAgB,EAAE;AACpBR,QAAAA,mBAAmB,EAAE;AACvB,OAAC,MAAM;AACLG,QAAAA,mBAAmB,EAAE;AACvB;AACF,KAAC,MAAM,IAAIX,CAAC,CAACkB,GAAG,KAAK,OAAO,EAAE;MAC5BlB,CAAC,CAACmB,cAAc,EAAE;AAClBP,MAAAA,sBAAsB,EAAE;AAC1B,KAAC,MAAM,IAAIZ,CAAC,CAACkB,GAAG,KAAK,QAAQ,EAAE;MAC7BlB,CAAC,CAACmB,cAAc,EAAE;AAClBL,MAAAA,KAAK,EAAE;AACT;AACA;AACF;AAEA,EAAA,OAAA,CAAA,MAAA;IAAA,IAAAM,IAAA,GAAAC,MAAA,EAAA;MAAAC,KAAA,GAAAF,IAAA,CAAAG,UAAA;IAAAC,oBAAA,CAAAF,KAAA,EAAA,SAAA,EAWgBP,aAAa,CAAA;IAAAS,oBAAA,CAAAF,KAAA,EAAA,OAAA,EADfvB,WAAW,CAAA;AAAA0B,IAAAA,UAAA,CAAAL,IAAA,EAAA,CAAA,MAAA;MAAA,IAAAM,GAAA,GAAAC,QAAA,CAAA,MAItB9B,cAAc,EAAE,GAAG,CAAC,CAAA;AAAA,MAAA,OAAA,MAApB6B,GAAA,EAAA,IAAA,CAAA,MAAA;QAAA,IAAAE,KAAA,GAAAC,OAAA,EAAA;AAAAJ,QAAAA,UAAA,CAAAG,KAAA,EAEIlC,MAAAA,WAAW,EAAE,CAACoC,GAAG,CAAC,CAACrB,CAAC,EAAEsB,CAAC,KAAA,CAAA,MAAA;UAAA,IAAAC,KAAA,GAAAC,OAAA,EAAA;UAAAT,oBAAA,CAAAQ,KAAA,EAAA,OAAA,EAMVpB,sBAAsB,CAAA;AAAAY,UAAAA,oBAAA,CAAAQ,KAAA,EAAA,YAAA,EADjB,MAAM1B,eAAe,CAACyB,CAAC,CAAC,CAAA;UAAAN,UAAA,CAAAO,KAAA,EAItC/C,MAAAA,KAAK,CAACiD,gBAAgB,CAACzB,CAAC,CAAC,CAAA;AAAA0B,UAAAA,UAAA,CAAAC,GAAA,IAAA;AAAA,YAAA,IAAAC,GAAA,GANbhD,MAAM,EAAE,KAAK0C,CAAC;cAAAO,IAAA,GAIZjD,MAAM,EAAE,KAAK0C,CAAC,GAAG,MAAM,GAAG,OAAO;AAAAM,YAAAA,GAAA,KAAAD,GAAA,CAAApC,CAAA,IAAAuC,gBAAA,CAAAP,KAAA,EAAAI,aAAAA,EAAAA,GAAA,CAAApC,CAAA,GAAAqC,GAAA,CAAA;AAAAC,YAAAA,IAAA,KAAAF,GAAA,CAAAI,CAAA,IAAAD,gBAAA,CAAAP,KAAA,EAAAI,eAAAA,EAAAA,GAAA,CAAAI,CAAA,GAAAF,IAAA,CAAA;AAAA,YAAA,OAAAF,GAAA;AAAA,WAAA,EAAA;AAAApC,YAAAA,CAAA,EAAAyC,SAAA;AAAAD,YAAAA,CAAA,EAAAC;AAAA,WAAA,CAAA;AAAA,UAAA,OAAAT,KAAA;AAAA,SAAA,GAG5C,CACP,CAAA;AAAA,QAAA,OAAAJ,KAAA;OAEL,GAAA;AAAA,KAAA,GAAA,EAAA,IAAA,CAAA;IAAAO,UAAA,CAAA,MAAAI,gBAAA,CAAAnB,IAAA,mBA1BevB,cAAc,EAAE,GAAG,CAAC,CAAA,CAAA;AAAAsC,IAAAA,UAAA,OAAAb,KAAA,CAAArB,KAAA,GAM1Bf,KAAK,EAAE,CAAA;AAAA,IAAA,OAAAkC,IAAA;AAAA,GAAA,GAAA;AAsBpB;;;;"}
|
package/dist/index.d.ts
ADDED
@@ -0,0 +1,8 @@
|
|
1
|
+
export interface SuggestProps<T = string> {
|
2
|
+
onQuery: (query: string) => T[];
|
3
|
+
onSelect: (suggestion: T) => void;
|
4
|
+
renderSuggestion: (suggestion: T) => HTMLElement;
|
5
|
+
reverseKeyInput?: boolean;
|
6
|
+
debounceMs?: number;
|
7
|
+
}
|
8
|
+
export default function Suggest(props: SuggestProps): import("solid-js").JSX.Element;
|
package/dist/index.js
ADDED
@@ -0,0 +1,121 @@
|
|
1
|
+
import { template, addEventListener, insert, memo, effect, setAttribute } from 'solid-js/web';
|
2
|
+
import { createSignal, createMemo } from 'solid-js';
|
3
|
+
|
4
|
+
var _tmpl$ = /*#__PURE__*/template(`<div class=s-sug-container role=combobox aria-haspopup=listbox><input type=search class=s-sug-search aria-autocomplete=list>`),
|
5
|
+
_tmpl$2 = /*#__PURE__*/template(`<ul class=s-sug-suggestions role=listbox>`),
|
6
|
+
_tmpl$3 = /*#__PURE__*/template(`<li class=s-sug-suggestion role=option>`);
|
7
|
+
function Suggest(props) {
|
8
|
+
// Basic signals for component state
|
9
|
+
const [query, setQuery] = createSignal('');
|
10
|
+
const [staged, setStaged] = createSignal(null);
|
11
|
+
// Internal signal for user input, separate from query to handle optional debounce
|
12
|
+
const [debouncedQuery, setDebouncedQuery] = createSignal('');
|
13
|
+
// Just a variable to store debounce timeout, if applicable
|
14
|
+
let debounceTimeout = null;
|
15
|
+
const suggestions = createMemo(() => props.onQuery(debouncedQuery()));
|
16
|
+
const numSuggestions = createMemo(() => suggestions().length);
|
17
|
+
function handleInput(e) {
|
18
|
+
const value = e.currentTarget.value;
|
19
|
+
setQuery(value);
|
20
|
+
if (typeof props.debounceMs === 'number' && props.debounceMs > 0) {
|
21
|
+
if (debounceTimeout) clearTimeout(debounceTimeout);
|
22
|
+
debounceTimeout = setTimeout(() => {
|
23
|
+
setDebouncedQuery(value);
|
24
|
+
}, props.debounceMs);
|
25
|
+
} else {
|
26
|
+
setDebouncedQuery(value);
|
27
|
+
}
|
28
|
+
}
|
29
|
+
function stageSuggestion(index) {
|
30
|
+
setStaged(index);
|
31
|
+
}
|
32
|
+
function stageNextSuggestion() {
|
33
|
+
setStaged(s => {
|
34
|
+
if (suggestions().length === 0) return null;
|
35
|
+
const current = s ?? -1;
|
36
|
+
return (current + 1) % numSuggestions();
|
37
|
+
});
|
38
|
+
}
|
39
|
+
function stagePrevSuggestion() {
|
40
|
+
setStaged(s => {
|
41
|
+
if (numSuggestions() === 0) return null;
|
42
|
+
const current = s ?? 0;
|
43
|
+
return (current - 1 + numSuggestions()) % numSuggestions();
|
44
|
+
});
|
45
|
+
}
|
46
|
+
function selectStagedSuggestion() {
|
47
|
+
const index = staged();
|
48
|
+
if (index !== null) {
|
49
|
+
props.onSelect(suggestions()[index]);
|
50
|
+
reset();
|
51
|
+
}
|
52
|
+
}
|
53
|
+
function reset() {
|
54
|
+
setQuery('');
|
55
|
+
setDebouncedQuery('');
|
56
|
+
setStaged(null);
|
57
|
+
if (debounceTimeout) clearTimeout(debounceTimeout);
|
58
|
+
}
|
59
|
+
// Handles special input for suggestion behavior
|
60
|
+
function handleKeyDown(e) {
|
61
|
+
const keyInputReversed = props.reverseKeyInput ?? false;
|
62
|
+
if (e.key === 'ArrowDown') {
|
63
|
+
e.preventDefault();
|
64
|
+
if (keyInputReversed) {
|
65
|
+
stagePrevSuggestion();
|
66
|
+
} else {
|
67
|
+
stageNextSuggestion();
|
68
|
+
}
|
69
|
+
} else if (e.key === 'ArrowUp') {
|
70
|
+
e.preventDefault();
|
71
|
+
if (keyInputReversed) {
|
72
|
+
stageNextSuggestion();
|
73
|
+
} else {
|
74
|
+
stagePrevSuggestion();
|
75
|
+
}
|
76
|
+
} else if (e.key === 'Enter') {
|
77
|
+
e.preventDefault();
|
78
|
+
selectStagedSuggestion();
|
79
|
+
} else if (e.key === 'Escape') {
|
80
|
+
e.preventDefault();
|
81
|
+
reset();
|
82
|
+
}
|
83
|
+
// else -> propagates up to allow input
|
84
|
+
}
|
85
|
+
return (() => {
|
86
|
+
var _el$ = _tmpl$(),
|
87
|
+
_el$2 = _el$.firstChild;
|
88
|
+
addEventListener(_el$2, "keydown", handleKeyDown);
|
89
|
+
addEventListener(_el$2, "input", handleInput);
|
90
|
+
insert(_el$, (() => {
|
91
|
+
var _c$ = memo(() => numSuggestions() > 0);
|
92
|
+
return () => _c$() && (() => {
|
93
|
+
var _el$3 = _tmpl$2();
|
94
|
+
insert(_el$3, () => suggestions().map((s, i) => (() => {
|
95
|
+
var _el$4 = _tmpl$3();
|
96
|
+
addEventListener(_el$4, "click", selectStagedSuggestion);
|
97
|
+
addEventListener(_el$4, "mouseenter", () => stageSuggestion(i));
|
98
|
+
insert(_el$4, () => props.renderSuggestion(s));
|
99
|
+
effect(_p$ => {
|
100
|
+
var _v$ = staged() === i,
|
101
|
+
_v$2 = staged() === i ? 'true' : 'false';
|
102
|
+
_v$ !== _p$.e && setAttribute(_el$4, "data-staged", _p$.e = _v$);
|
103
|
+
_v$2 !== _p$.t && setAttribute(_el$4, "aria-selected", _p$.t = _v$2);
|
104
|
+
return _p$;
|
105
|
+
}, {
|
106
|
+
e: undefined,
|
107
|
+
t: undefined
|
108
|
+
});
|
109
|
+
return _el$4;
|
110
|
+
})()));
|
111
|
+
return _el$3;
|
112
|
+
})();
|
113
|
+
})(), null);
|
114
|
+
effect(() => setAttribute(_el$, "aria-expanded", numSuggestions() > 0));
|
115
|
+
effect(() => _el$2.value = query());
|
116
|
+
return _el$;
|
117
|
+
})();
|
118
|
+
}
|
119
|
+
|
120
|
+
export { Suggest as default };
|
121
|
+
//# sourceMappingURL=index.js.map
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.tsx"],"sourcesContent":["import { createMemo, createSignal } from 'solid-js'\n\nexport interface SuggestProps<T = string> {\n onQuery: (query: string) => T[], // Suggestions assumed ordered by client\n onSelect: (suggestion: T) => void,\n renderSuggestion: (suggestion: T) => HTMLElement,\n reverseKeyInput?: boolean,\n debounceMs?: number, // Debounce period in milliseconds\n}\n\nexport default function Suggest(props: SuggestProps) {\n // Basic signals for component state\n const [query, setQuery] = createSignal('');\n const [staged, setStaged] = createSignal<number | null>(null);\n // Internal signal for user input, separate from query to handle optional debounce\n const [debouncedQuery, setDebouncedQuery] = createSignal('');\n\n // Just a variable to store debounce timeout, if applicable\n let debounceTimeout: ReturnType<typeof setTimeout> | null = null;\n\n const suggestions = createMemo(() => props.onQuery(debouncedQuery()));\n const numSuggestions = createMemo(() => suggestions().length);\n\n function handleInput(e: Event) {\n const value = (e.currentTarget as HTMLInputElement).value;\n setQuery(value);\n if (typeof props.debounceMs === 'number' && props.debounceMs > 0) {\n if (debounceTimeout) clearTimeout(debounceTimeout);\n debounceTimeout = setTimeout(() => {\n setDebouncedQuery(value);\n }, props.debounceMs);\n } else {\n setDebouncedQuery(value);\n }\n }\n\n function stageSuggestion(index: number) {\n setStaged(index);\n }\n\n function stageNextSuggestion() {\n setStaged(s => {\n if (suggestions().length === 0) return null;\n const current = s ?? -1;\n return (current + 1) % numSuggestions();\n });\n };\n\n function stagePrevSuggestion() {\n setStaged(s => {\n if (numSuggestions() === 0) return null;\n const current = s ?? 0;\n return (current - 1 + numSuggestions()) % numSuggestions();\n });\n };\n\n function selectStagedSuggestion() {\n const index = staged()\n if (index !== null) {\n props.onSelect(suggestions()[index]);\n reset();\n }\n }\n\n function reset() {\n setQuery('');\n setDebouncedQuery('');\n setStaged(null);\n if (debounceTimeout) clearTimeout(debounceTimeout);\n }\n\n // Handles special input for suggestion behavior\n function handleKeyDown(e: KeyboardEvent) {\n const keyInputReversed = props.reverseKeyInput ?? false;\n if (e.key === 'ArrowDown') {\n e.preventDefault();\n if (keyInputReversed) {\n stagePrevSuggestion();\n } else {\n stageNextSuggestion();\n }\n } else if (e.key === 'ArrowUp') {\n e.preventDefault();\n if (keyInputReversed) {\n stageNextSuggestion();\n } else {\n stagePrevSuggestion();\n }\n } else if (e.key === 'Enter') {\n e.preventDefault();\n selectStagedSuggestion();\n } else if (e.key === 'Escape') {\n e.preventDefault();\n reset();\n }\n // else -> propagates up to allow input\n }\n\n return <div\n class='s-sug-container'\n role='combobox'\n aria-expanded={numSuggestions() > 0}\n aria-haspopup='listbox'\n >\n <input\n type='search'\n class='s-sug-search'\n value={query()}\n on:input={handleInput}\n on:keydown={handleKeyDown}\n aria-autocomplete='list'\n />\n {numSuggestions() > 0 &&\n <ul class='s-sug-suggestions' role='listbox'>\n {suggestions().map((s, i) => (\n <li\n class='s-sug-suggestion'\n data-staged={staged() === i}\n role='option'\n on:mouseenter={() => stageSuggestion(i)}\n on:click={selectStagedSuggestion}\n aria-selected={staged() === i ? 'true' : 'false'}\n >\n {props.renderSuggestion(s)}\n </li>)\n )}\n </ul>\n }\n </div>\n}\n"],"names":["Suggest","props","query","setQuery","createSignal","staged","setStaged","debouncedQuery","setDebouncedQuery","debounceTimeout","suggestions","createMemo","onQuery","numSuggestions","length","handleInput","e","value","currentTarget","debounceMs","clearTimeout","setTimeout","stageSuggestion","index","stageNextSuggestion","s","current","stagePrevSuggestion","selectStagedSuggestion","onSelect","reset","handleKeyDown","keyInputReversed","reverseKeyInput","key","preventDefault","_el$","_tmpl$","_el$2","firstChild","_$addEventListener","_$insert","_c$","_$memo","_el$3","_tmpl$2","map","i","_el$4","_tmpl$3","renderSuggestion","_$effect","_p$","_v$","_v$2","_$setAttribute","t","undefined"],"mappings":"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"}
|
package/package.json
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
{
|
2
|
+
"name": "solid-suggest",
|
3
|
+
"version": "1.1.0",
|
4
|
+
"description": "Headless search suggestion dropdown UI library for SolidJS",
|
5
|
+
"homepage": "https://antrikshy.com/solid-suggest",
|
6
|
+
"repository": {
|
7
|
+
"type": "git",
|
8
|
+
"url": "https://github.com/Antrikshy/solid-suggest.git"
|
9
|
+
},
|
10
|
+
"bugs": {
|
11
|
+
"url": "https://github.com/Antrikshy/solid-suggest/issues"
|
12
|
+
},
|
13
|
+
"keywords": [
|
14
|
+
"solidjs",
|
15
|
+
"search",
|
16
|
+
"suggestions",
|
17
|
+
"dropdown",
|
18
|
+
"autocomplete",
|
19
|
+
"ui"
|
20
|
+
],
|
21
|
+
"author": "Antriksh Yadav",
|
22
|
+
"license": "ISC",
|
23
|
+
"type": "module",
|
24
|
+
"main": "./dist/main.cjs",
|
25
|
+
"module": "./dist/main.js",
|
26
|
+
"types": "./dist/main.d.ts",
|
27
|
+
"exports": {
|
28
|
+
".": {
|
29
|
+
"import": "./dist/main.js",
|
30
|
+
"require": "./dist/main.cjs",
|
31
|
+
"types": "./dist/main.d.ts"
|
32
|
+
}
|
33
|
+
},
|
34
|
+
"files": [
|
35
|
+
"dist"
|
36
|
+
],
|
37
|
+
"scripts": {
|
38
|
+
"build": "rollup -c",
|
39
|
+
"devOnly": "rollup -c -w",
|
40
|
+
"devDemo": "npx http-server -p 8000",
|
41
|
+
"devWithDemo": "concurrently \"npm:devOnly\" \"npm:devDemo\"",
|
42
|
+
"prepublishOnly": "npm run build"
|
43
|
+
},
|
44
|
+
"peerDependencies": {
|
45
|
+
"solid-js": "^1.9.x"
|
46
|
+
},
|
47
|
+
"devDependencies": {
|
48
|
+
"@babel/core": "^7.27.4",
|
49
|
+
"@babel/preset-typescript": "^7.27.1",
|
50
|
+
"@rollup/plugin-babel": "^6.0.4",
|
51
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
52
|
+
"babel-preset-solid": "^1.9.6",
|
53
|
+
"concurrently": "^9.2.0",
|
54
|
+
"rollup": "^4.42.0",
|
55
|
+
"solid-js": "^1.9.7",
|
56
|
+
"tslib": "^2.8.1",
|
57
|
+
"typescript": "^5.8.3"
|
58
|
+
}
|
59
|
+
}
|