select-dom
Version:
Lightweight querySelector/All/closest wrapper that returns an array and optionally throws if elements are not found
179 lines (129 loc) • 4.38 kB
Markdown
# select-dom [![][badge-gzip]][link-npm] [![npm downloads][badge-downloads]][link-npm]
[badge-gzip]: https://img.shields.io/bundlephobia/minzip/select-dom.svg?label=gzipped
[badge-downloads]: https://img.shields.io/npm/dt/select-dom.svg
[link-npm]: https://www.npmjs.com/package/select-dom
> Lightweight `querySelector`/`All`/`closest` wrapper that returns an array and optionally throws if elements are not found
## Install
```bash
npm install select-dom
```
```js
import {
$,
$$,
lastElement,
elementExists,
assertElementExists,
$optional,
$$optional,
lastElementOptional,
$closest,
$closestOptional,
} from 'select-dom';
```
The package also includes an ESLint plugin entry point at `select-dom/eslint-plugin`; [read documentation](#eslint).
## API
**Note:** if a falsy value is passed as `baseElement`, `$`, `$$`, `lastElement` throw `ElementNotFoundError`, while `$optional`, `$$optional`, `lastElementOptional` return `undefined`/`[]` ([bd578b9](https://github.com/fregante/select-dom/commit/bd578b975e35d9f802cb43a900a6d3c83095c76a))
### `$`
### `$optional`
`$` maps to `baseElement.querySelector(selector)`, except it throws `ElementNotFoundError` if no element is found. `$optional` returns `undefined` instead of throwing.
```js
$('.foo a[href=bar]');
// => <Element>
$('.non-existent');
// throws ElementNotFoundError
$optional('.non-existent');
// => undefined
```
### `$$`
### `$$optional`
`$$` maps to `baseElements.querySelectorAll(selector)` and always returns an array. `baseElements` can also be an array of elements to search within. Throws `ElementNotFoundError` if no elements are found. `$$optional` returns `[]` instead of throwing.
```js
$$('.foo');
// => [<Element>, <Element>, <Element>]
$$('.foo', baseElement);
// => [<Element>, <Element>, <Element>]
$$('.foo', [baseElement1, baseElement2]);
// => [<Element>, <Element>, <Element>]
$$('.non-existent');
// throws ElementNotFoundError
$$optional('.non-existent');
// => []
```
### `lastElement`
### `lastElementOptional`
Like `$`/`$optional`, except they return the last matching element instead of the first.
```js
lastElement('.foo');
// => <Element>
lastElement('.non-existent');
// throws ElementNotFoundError
lastElementOptional('.non-existent');
// => undefined
```
### `$closest`
### `$closestOptional`
Like `element.closest(selector)`, except `baseElement` can be any `Node` including text nodes. `$closest` throws `ElementNotFoundError` if not found; `$closestOptional` returns `undefined`.
```js
$closest('button', event.target);
// => <button>
$closest('button', button.firstChild); // text nodes are supported
// => <button>
$closest('.non-existent', element);
// throws ElementNotFoundError
$closestOptional('.non-existent', element);
// => undefined
```
### `elementExists`
Tests the existence of one or more elements. Like `$optional()`, but returns a `boolean`.
```js
elementExists('.foo a[href=bar]');
// => true/false
```
### `assertElementExists`
Like `elementExists()`, but throws `ElementNotFoundError` instead of returning `false`.
```js
assertElementExists('.foo a[href=bar]');
// => void (if element exists)
// => throws ElementNotFoundError (if element doesn't exist)
```
### `countElements`
Counts the number of elements found. Shortcut for `$$optional(selector).length`.
```js
countElements('a');
// => 3
```
## ESLint
`select-dom/eslint-plugin` includes the `select-dom/prefer` rule, which autofixes `.querySelector()`, `.querySelectorAll()`, and `.closest()` calls to the matching `select-dom` helpers.
```js
import selectDom from 'select-dom/eslint-plugin';
export default [
{
plugins: {
'select-dom': selectDom,
},
rules: {
'select-dom/prefer': 'error',
},
},
];
```
By default, the rule reports all supported calls. To keep readability exceptions like `element.firstChild.querySelector(selector)`, enable `allowReadabilityExceptions`.
```js
import selectDom from 'select-dom/eslint-plugin';
export default [
{
plugins: {
'select-dom': selectDom,
},
rules: {
'select-dom/prefer': ['error', {
allowReadabilityExceptions: true,
}],
},
},
];
```
## Related
- [delegate-it](https://github.com/fregante/delegate-it) - DOM event delegation, in <1KB.
- [doma](https://github.com/fregante/doma) - Parse an HTML string into `DocumentFragment` or one `Element`, in a few bytes.