|
3 | 3 | A simple library to query the DOM from your Astro components. |
4 | 4 |
|
5 | 5 | ```astro |
6 | | -<button data-target={$('btn')}>Click me</button> |
| 6 | +<RootElement> |
| 7 | + <button data-target="btn">Click me</button> |
| 8 | +</RootElement> |
7 | 9 |
|
8 | 10 | <script> |
9 | | - $.ready(() => { |
| 11 | + RootElement.ready(($) => { |
10 | 12 | $('btn').addEventListener('click', () => { |
11 | 13 | console.log("It's like JQuery but not!"); |
12 | 14 | }); |
13 | 15 | }); |
14 | 16 | </script> |
15 | 17 | ``` |
16 | 18 |
|
17 | | -## Installation |
18 | | - |
19 | | -Simple stack query is an Astro integration. You can install using the `astro add` CLI: |
20 | | - |
21 | | -```bash |
22 | | -astro add simple-stack-query |
23 | | -``` |
24 | | - |
25 | | -To install this integration manually, follow the [manual installation instructions](https://docs.astro.build/en/guides/integrations-guide/#manual-installation) |
26 | | - |
27 | | -## Global `$` selector |
28 | | - |
29 | | -The `$` is globally available to define targets from your server template, and to query those targets from your client script. |
30 | | - |
31 | | -Selectors should be applied to the `data-target` attribute. All selectors are scoped based on the component you're in, so we recommend the simplest name you can use: |
32 | | - |
33 | | -```astro |
34 | | -<button data-target={$('btn')}> |
35 | | -<!--data-target="btn-4SzN_OBB"--> |
36 | | -``` |
37 | | - |
38 | | -Then, use the same `$()` function from your client script to select that element. The query result will be a plain [`HTMLElement`](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement). No, it's not a JQuery object. We just used `$` for the nostalgia 😉 |
39 | | - |
40 | | -```ts |
41 | | -$('btn').addEventListener(() => { /* ... */ }); |
42 | | -``` |
43 | | - |
44 | | -You can also pass an `HTMLElement` or `SVGElement` type to access specific properties. For example, use `$<HTMLInputElement>()` to access `.value`: |
45 | | - |
46 | | -```ts |
47 | | -$<HTMLInputElement>('input').value = ''; |
48 | | -``` |
49 | | - |
50 | | -### `$.optional()` selector |
51 | | - |
52 | | -`$()` throws when no matching element is found. To handle undefined values, use `$.optional()`: |
53 | | - |
54 | | -```astro |
55 | | ---- |
56 | | -const promoActive = Astro.url.searchParams.has('promo'); |
57 | | ---- |
58 | | -
|
59 | | -{promoActive && <p data-target={$('banner')}>Buy my thing</p>} |
60 | | -
|
61 | | -<script> |
62 | | - $.ready(() => { |
63 | | - $.optional('banner')?.addEventListener('mouseover', () => { |
64 | | - console.log("They're about to buy it omg"); |
65 | | - }); |
66 | | - }); |
67 | | -</script> |
68 | | -``` |
69 | | - |
70 | | -### `$.all()` selector |
71 | | - |
72 | | -You may want to select multiple targets with the same name. Use `$.all()` to query for an array of results: |
73 | | - |
74 | | -```astro |
75 | | ---- |
76 | | -const links = ["wtw.dev", "bholmes.dev"]; |
77 | | ---- |
78 | | -
|
79 | | -{links.map(link => ( |
80 | | - <a href={link} data-target={$('link')}>{link}</a> |
81 | | -))} |
82 | | -
|
83 | | -<script> |
84 | | - $.ready(() => { |
85 | | - $.all('link').forEach(linkElement => { /* ... */ }); |
86 | | - }); |
87 | | -</script> |
88 | | -``` |
89 | | - |
90 | | -## `$.ready()` function |
91 | | - |
92 | | -All `$` queries should be nested in a `$.ready()` block. `$.ready()` will rerun on every page [when view transitions are enabled.](https://docs.astro.build/en/guides/view-transitions/) |
93 | | - |
94 | | -```astro |
95 | | -<script> |
96 | | - $.ready(() => { |
97 | | - // ✅ Query code that should run on every navigation |
98 | | - $('element').textContent = 'hey'; |
99 | | - }) |
100 | | -
|
101 | | - // ✅ Global code that should only run once |
102 | | - class MyElement extends HTMLElement { /* ... */} |
103 | | - customElements.define('my-element', MyElement); |
104 | | -</script> |
105 | | -``` |
106 | | - |
107 | | -### 🙋♂️ `$.ready()` isn't running for me |
108 | | - |
109 | | -`$.ready()` runs when `data-target` is used by your component. This heuristic keeps simple query performant and ensures scripts run at the right time when view transitions are applied. |
110 | | - |
111 | | -If `data-target` is applied conditionally, or not at all, the `$.ready()` block may not run. You can apply a `data-target` selector anywhere in your component to resolve the issue: |
112 | | - |
113 | | -```astro |
114 | | -<div data-target={$('container')}> |
115 | | -<!--...--> |
116 | | -</div> |
117 | | -``` |
| 19 | +📚 Visit [the docs](https://simple-stack.dev/query) for more information and usage examples. |
0 commit comments