a tiny atproto handle typeahead web component

Compare changes

Choose any two refs to compare.

+11
README.md
··· 27 27 ActorTypeahead.define("some-other-tag"); 28 28 </script> 29 29 30 + If you're using a bundler, you can install it from npm: 31 + 32 + ```sh 33 + npm install actor-typeahead 34 + ``` 35 + 36 + Then import it somewhere in your JavaScript. It'll auto-register itself. 37 + 38 + ```js 39 + import "actor-typeahead"; 40 + ``` 30 41 31 42 ## Usage 32 43
+10 -25
actor-typeahead.js
··· 55 55 width: 100%; 56 56 height: calc(1.5rem + 6px * 2); 57 57 border-radius: calc(var(--radius-inherited) - var(--padding-menu-inherited)); 58 + cursor: default; 58 59 } 59 60 60 61 .user:hover, ··· 155 156 this.#onkeydown(/** @type {KeyboardEvent} */ (evt)); 156 157 break; 157 158 158 - case "click": 159 - this.#onclick(/** @type {PointerEvent} */ (evt)); 160 - break; 161 - 162 159 case "focusout": 163 160 this.#onfocusout(evt); 164 161 break; ··· 214 211 } 215 212 } 216 213 217 - /** @param {PointerEvent} evt */ 218 - #onclick(evt) { 219 - const button = evt.target?.closest(".user"); 220 - const input = this.querySelector("input"); 221 - if (!input || !button) return; 222 - 223 - input.value = button.dataset.handle; 224 - this.#actors = []; 225 - this.#render(); 226 - } 227 - 228 214 /** @param {InputEvent} evt */ 229 215 async #oninput(evt) { 230 216 const query = evt.target?.value; ··· 278 264 279 265 /** @param {PointerEvent} evt */ 280 266 #onpointerdown(evt) { 281 - const menu = this.#shadow.querySelector(".menu"); 282 - if (!menu) return; 283 - 284 - if (!menu.contains(evt.target)) return; 285 - menu.setPointerCapture(evt.pointerId); 286 267 this.#pressed = true; 287 268 } 288 269 289 270 /** @param {PointerEvent} evt */ 290 271 #onpointerup(evt) { 291 - const menu = this.#shadow.querySelector(".menu"); 292 - if (!menu) return; 272 + this.#pressed = false; 293 273 294 - if (!menu.hasPointerCapture(evt.pointerId)) return; 295 - menu.releasePointerCapture(evt.pointerId); 296 - this.#pressed = false; 297 274 this.querySelector("input")?.focus(); 275 + 276 + const button = evt.target?.closest(".user"); 277 + const input = this.querySelector("input"); 278 + if (!input || !button) return; 279 + 280 + input.value = button.dataset.handle; 281 + this.#actors = []; 282 + this.#render(); 298 283 } 299 284 }
-1
index.html
··· 8 8 <actor-typeahead> 9 9 <input /> 10 10 </actor-typeahead> 11 - <p>more text goes here</p> 12 11 </div> 13 12 </body> 14 13 </html>
+1 -1
package.json
··· 1 1 { 2 2 "name": "actor-typeahead", 3 - "version": "1.0.0", 3 + "version": "0.1.1", 4 4 "description": "", 5 5 "main": "actor-typeahead.js", 6 6 "scripts": {