Skip to content

Commit e274e36

Browse files
authored
Merge pull request #49 from github/data-targets
Use `data-targets` for `@targets`.
2 parents 2769369 + a36d0f9 commit e274e36

5 files changed

Lines changed: 31 additions & 17 deletions

File tree

docs/_guide/anti-patterns.md

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -250,15 +250,15 @@ class UserFilter {
250250
<user-list>
251251
<label><input type="checkbox"
252252
data-action="change:user-list.filter"
253-
data-target="user-list.filters"
253+
data-targets="user-list.filters"
254254
data-filter="all">Show all</label>
255255
<label><input type="checkbox"
256256
data-action="change:user-list.filter"
257-
data-target="user-list.filters"
257+
data-targets="user-list.filters"
258258
data-filter="new">New Users</label>
259259
<label><input type="checkbox"
260260
data-action="change:user-list.filter"
261-
data-target="user-list.filters"
261+
data-targets="user-list.filters"
262262
data-filter="admin">Admins</label>
263263
<!-- ... --->
264264
</user-filter>
@@ -290,15 +290,16 @@ class UserFilter {
290290
<user-filter>
291291
<label><input type="checkbox"
292292
data-action="change:user-list.filter"
293-
data-target="user-list.filters user-list.allFilter"
293+
data-target="user-list.allFilter"
294+
data-targets="user-list.filters"
294295
data-filter="all">Show all</label>
295296
<label><input type="checkbox"
296297
data-action="change:user-list.filter"
297-
data-target="user-list.filters"
298+
data-targets="user-list.filters"
298299
data-filter="new">New Users</label>
299300
<label><input type="checkbox"
300301
data-action="change:user-list.filter"
301-
data-target="user-list.filters"
302+
data-targets="user-list.filters"
302303
data-filter="admin">Admins</label>
303304
<!-- ... --->
304305
</user-filter>

docs/_guide/conventions.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,3 +35,7 @@ Be careful not to go too short! We'd recommend avoiding contracting words such a
3535
### Method names should describe what they do
3636

3737
A good method name, much like a good class name, describes what it does, not how it was invoked. While methods can be given any name, names like `onClick` are best avoided, overly generic names like `toggle` should also be avoided. Just like class names it is a good idea to ask "how" and "what", so for example `showAdmins`, `filterUsers`, `updateURL`.
38+
39+
### `@target` should use singular naming, while `@targets` should use plural
40+
41+
To help differentiate the two `@target`/`@targets` decorators, the properties should be named with respective to their cardinality. That is to say, if you're using an `@target` decorator, then the name should be singular (e.g. `user`, `field`) while the `@targets` decorator should be coupled with plural property names (e.g. `users`, `fields`).

docs/_guide/targets.md

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ chapter: 5
33
subtitle: Querying Descendants
44
---
55

6-
One of the three [core patterns](/guide/introduction#three-core-concepts-observe-listen-query) is Querying. In Catalyst, Targets are the preferred way to query. Targets use `querySelectorAll` under the hood, but in a way that makes it a lot simpler to work with.
6+
One of the three [core patterns](/guide/introduction#three-core-concepts-observe-listen-query) is Querying. In Catalyst, Targets are the preferred way to query. Targets use `querySelector` under the hood, but in a way that makes it a lot simpler to work with.
77

88
Catalyst Components are really just Web Components, so you could simply use `querySelector` or `querySelectorAll` to select descendants of the element. Targets avoid some of the problems of `querySelector`; they provide a more consistent interface, avoid coupling CSS classes or HTML tag names to JS, and they handle subtle issues like nested components. Targets are also a little more ergonomic to reuse in a class. We'd recommend using Targets over `querySelector` wherever you can.
99

@@ -61,25 +61,25 @@ The target syntax follows a pattern of `controller.target`.
6161
</span>
6262
<div class="p-3">
6363

64-
Remember! There are two decorators available, `@target` which fetches only one element, and `@targets` which fetches multiple. This is the only difference, but it's an important one.
64+
Remember! There are two decorators available, `@target` which fetches only one `data-target` element, and `@targets` which fetches multiple `data-targets` elements!
6565

6666
</div>
6767
</div>
6868

69-
The `@target` decorator will only ever return _one_ element, just like `querySelector`. If you want to get multiple Targets, you need the `@targets` decorator which works almost identically, but it'll return an _array_ of elements. To put this into types: `@target` returns `Element|undefined` while `@targets` returns `Array<Element>`
69+
The `@target` decorator will only ever return _one_ element, just like `querySelector`. If you want to get multiple Targets, you need the `@targets` decorator which works almost the same, but returns an Array of elements, and it searches the `data-targets` attribute (not `data-target`).
7070

7171
Elements can be referenced as multiple targets, and targets may be referenced multiple times within the HTML:
7272

7373
```html
7474
<team-members>
7575
<user-list>
76-
<user-settings data-target="user-list.user">
77-
<input type="checkbox" data-target="team-members.read user-settings.read">
78-
<input type="checkbox" data-target="team-members.write user-settings.write">
76+
<user-settings data-targets="user-list.users">
77+
<input type="checkbox" data-targets="team-members.reads user-settings.reads">
78+
<input type="checkbox" data-targets="team-members.writes user-settings.writes">
7979
</user-settings>
80-
<user-settings data-target="user-list.user">
81-
<input type="checkbox" data-target="team-members.read user-settings.read">
82-
<input type="checkbox" data-target="team-members.write user-settings.write">
80+
<user-settings data-targets="user-list.users">
81+
<input type="checkbox" data-targets="team-members.reads user-settings.reads">
82+
<input type="checkbox" data-targets="team-members.writes user-settings.writes">
8383
</user-settings>
8484
</user-list>
8585
</team-members>
@@ -112,6 +112,15 @@ class UserListElement extends HTMLElement {
112112
}
113113
```
114114

115+
### Target Vs Targets
116+
117+
To clarify the difference between `@target` and `@targets` here is a handy table:
118+
119+
| Decorator | Equivalent Native Method | Selector | Returns |
120+
|:-----------|:-------------------------|:-------------------|:-----------------|
121+
| `@target` | `querySelector` | `data-target="*"` | `Element` |
122+
| `@targets` | `querySelectorAll` | `data-targets="*"` | `Array<Element>` |
123+
115124
### What about without Decorators?
116125

117126
If you're using decorators, then the `@target` and `@targets` decorators will turn the decorated properties into getters.

src/findtarget.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export function findTarget(controller: HTMLElement, name: string): Element | und
2020
export function findTargets(controller: HTMLElement, name: string): Element[] {
2121
const tag = controller.tagName.toLowerCase()
2222
const targets = []
23-
for (const el of controller.querySelectorAll(`[data-target~="${tag}.${name}"]`)) {
23+
for (const el of controller.querySelectorAll(`[data-targets~="${tag}.${name}"]`)) {
2424
if (el.closest(tag) === controller) targets.push(el)
2525
}
2626
return targets

test/findtarget.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ describe('findTargets', () => {
8787
chai.spy.on(instance, 'querySelectorAll', () => [])
8888
findTargets(instance, 'foo')
8989
expect(instance.querySelectorAll).to.have.been.called.once.with.exactly(
90-
'[data-target~="find-target-test-element.foo"]'
90+
'[data-targets~="find-target-test-element.foo"]'
9191
)
9292
})
9393

0 commit comments

Comments
 (0)