Skip to content

Commit

Permalink
Change from select()/select.all() to $()/$$() (#22)
Browse files Browse the repository at this point in the history
  • Loading branch information
fregante authored Oct 20, 2023
1 parent 824620e commit 1ca2b13
Show file tree
Hide file tree
Showing 4 changed files with 56 additions and 62 deletions.
34 changes: 16 additions & 18 deletions index.test-d.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,35 @@
import {expectType} from 'tsd';
import select from './index.js';
import {$, $$, elementExists, lastElement} from './index.js';

// `select-dom` defaults to HTMLElement where possible because it's the most common use case, even if technically this should not be HTMLElement.

/**
* SELECT
*/
expectType<HTMLElement | undefined>(select('.wow'));
expectType<HTMLAnchorElement | undefined>(select('a.wow'));

expectType<HTMLBaseElement | undefined>(select('base'));

expectType<SVGGElement | undefined>(select('g'));
expectType<HTMLElement | undefined>($('.wow'));
expectType<HTMLAnchorElement | undefined>($('a.wow'));
expectType<HTMLBaseElement | undefined>($('base'));
expectType<SVGGElement | undefined>($('g'));

/**
* LAST
*/
expectType<HTMLElement | undefined>(select.last('.wow'));
expectType<HTMLAnchorElement | undefined>(select.last('a.wow'));
expectType<HTMLBaseElement | undefined>(select.last('base'));
expectType<SVGGElement | undefined>(select.last('g'));
expectType<HTMLElement | undefined>(lastElement('.wow'));
expectType<HTMLAnchorElement | undefined>(lastElement('a.wow'));
expectType<HTMLBaseElement | undefined>(lastElement('base'));
expectType<SVGGElement | undefined>(lastElement('g'));

/**
* EXISTS
*/
expectType<boolean>(select.exists('.wow'));
expectType<boolean>(select.exists('base'));
expectType<boolean>(select.exists('g'));
expectType<boolean>(elementExists('.wow'));
expectType<boolean>(elementExists('base'));
expectType<boolean>(elementExists('g'));

/**
* ALL
*/
expectType<HTMLElement[]>(select.all('.wow'));
expectType<HTMLBaseElement[]>(select.all('base'));
expectType<SVGGElement[]>(select.all('g'));
expectType<HTMLAnchorElement[]>(select.all('a.wow'));
expectType<HTMLElement[]>($$('.wow'));
expectType<HTMLBaseElement[]>($$('base'));
expectType<SVGGElement[]>($$('g'));
expectType<HTMLAnchorElement[]>($$('a.wow'));
26 changes: 11 additions & 15 deletions index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@ function isQueryable(object: BaseElements): object is ParentNode {
* @param [baseElement] The element to look inside of
* @return The element found, if any
*/
function select<Selector extends string, Selected extends Element = ParseSelector<Selector, HTMLElement>>(
function $<Selector extends string, Selected extends Element = ParseSelector<Selector, HTMLElement>>(
selectors: Selector | Selector[],
baseElement?: ParentNode
): Selected | undefined;
function select<Selected extends Element = HTMLElement>(
function $<Selected extends Element = HTMLElement>(
selectors: string | string[],
baseElement?: ParentNode
): Selected | undefined;
function select<Selected extends Element>(
function $<Selected extends Element>(
selectors: string | string[],
baseElement?: ParentNode,
): Selected | undefined {
Expand All @@ -40,15 +40,15 @@ function select<Selected extends Element>(
* @param [baseElement] The element to look inside of
* @return The element found, if any
*/
function selectLast<Selector extends string, Selected extends Element = ParseSelector<Selector, HTMLElement>>(
function lastElement<Selector extends string, Selected extends Element = ParseSelector<Selector, HTMLElement>>(
selectors: Selector | Selector[],
baseElement?: ParentNode
): Selected | undefined;
function selectLast<Selected extends Element = HTMLElement>(
function lastElement<Selected extends Element = HTMLElement>(
selectors: string | string[],
baseElement?: ParentNode
): Selected | undefined;
function selectLast<Selected extends Element>(
function lastElement<Selected extends Element>(
selectors: string | string[],
baseElement?: ParentNode,
): Selected | undefined {
Expand All @@ -67,7 +67,7 @@ function selectLast<Selected extends Element>(
* @param [baseElement] The element to look inside of
* @return Whether it's been found
*/
function selectExists(
function elementExists(
selectors: string | string[],
baseElement?: ParentNode,
): boolean {
Expand All @@ -84,15 +84,15 @@ function selectExists(
* @param [baseElements] The element or list of elements to look inside of
* @return An array of elements found
*/
function selectAll<Selector extends string, Selected extends Element = ParseSelector<Selector, HTMLElement>>(
function $$<Selector extends string, Selected extends Element = ParseSelector<Selector, HTMLElement>>(
selectors: Selector | Selector[],
baseElements?: BaseElements
): Selected[];
function selectAll<Selected extends Element = HTMLElement>(
function $$<Selected extends Element = HTMLElement>(
selectors: string | string[],
baseElements?: BaseElements
): Selected[];
function selectAll<Selected extends Element>(
function $$<Selected extends Element>(
selectors: string | string[],
baseElements?: BaseElements,
): Selected[] {
Expand All @@ -117,8 +117,4 @@ function selectAll<Selected extends Element>(
return [...elements]; // Convert to array
}

select.last = selectLast;
select.exists = selectExists;
select.all = selectAll;

export default select;
export {$, $$, lastElement, elementExists};
30 changes: 15 additions & 15 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,59 +16,59 @@ npm install select-dom

```js
// This module is only offered as a ES Module
import select from 'select-dom';
import {$, $$, lastElement, elementExists} from 'select-dom';
```

## API

**Note:** if a falsy value is passed as `baseElement`, you'll always get an empty result ([bd578b9](https://github.com/fregante/select-dom/commit/bd578b975e35d9f802cb43a900a6d3c83095c76a))

### `select(selector[, baseElement = document])`
### `$(selector[, baseElement = document])`

Maps to `baseElement.querySelector(selector)`, except it returns `undefined` if it's not found

```js
select('.foo a[href=bar]');
$('.foo a[href=bar]');
// => <Element>

select('.foo a[href=bar]', baseElement);
$('.foo a[href=bar]', baseElement);
// => <Element>

select('.non-existent', baseElement);
$('.non-existent', baseElement);
// => undefined
```

### `select.last(selector[, baseElement = document])`
### `lastElement(selector[, baseElement = document])`

Like `select()`, except that it returns the last matching item on the page instead of the first one.
Like `$()`, except that it returns the last matching item on the page instead of the first one.

### `select.exists(selector[, baseElement = document])`
### `elementExists(selector[, baseElement = document])`

Tests the existence of one or more elements matching the selector. It's like `select()`, except it returns a `boolean`.
Tests the existence of one or more elements matching the selector. It's like `$()`, except it returns a `boolean`.

```js
select.exists('.foo a[href=bar]');
elementExists('.foo a[href=bar]');
// => true/false

select.exists('.foo a[href=bar]', baseElement);
elementExists('.foo a[href=bar]', baseElement);
// => true/false
```

### `select.all(selector[, baseElements = document])`
### `$$(selector[, baseElements = document])`

Maps to `baseElements.querySelectorAll(selector)` plus:

- it always returns an array
- `baseElements` can be a list of elements to query

```js
select.all('.foo');
$$('.foo');
// => [<Element>, <Element>, <Element>]

select.all('.foo', baseElement);
$$('.foo', baseElement);
// => [<Element>, <Element>, <Element>]

select.all('.foo', [baseElement1, baseElement2]);
$$('.foo', [baseElement1, baseElement2]);
// => [<Element>, <Element>, <Element>]
// This is similar to jQuery([baseElement1, baseElement2]).find('.foo')
```
Expand Down
28 changes: 14 additions & 14 deletions test.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import test from 'tape';
import select from './index.js';
import {$, $$, lastElement, elementExists} from './index.js';

document.body.innerHTML = `
<ul>
Expand All @@ -17,69 +17,69 @@ test('selects one element', t => {
t.plan(1);

const li = document.querySelector('ul li');
t.equal(select('ul li'), li);
t.equal($('ul li'), li);
});

test('selects one element within an ancestor', t => {
t.plan(1);

const li = document.querySelector('ul li');
t.equal(select('li', select('ul')), li);
t.equal($('li', $('ul')), li);
});

test('selects the last element', t => {
t.plan(1);

const li = [...document.querySelectorAll('ul li')].pop();
t.equal(select.last('ul li'), li);
t.equal(lastElement('ul li'), li);
});

test('selects the last element within an ancestor', t => {
t.plan(1);

const li = [...document.querySelectorAll('ul li')].pop();
t.equal(select.last('li', select.last('ul')), li);
t.equal(lastElement('li', lastElement('ul')), li);
});

test('tests existence of one element', t => {
t.plan(2);

t.true(select.exists('ul li'));
t.false(select.exists('lololol'));
t.true(elementExists('ul li'));
t.false(elementExists('lololol'));
});

test('tests existence of one element within an ancestor', t => {
t.plan(3);

t.true(select.exists('li', select('ul')));
t.false(select.exists('ul', select('li')));
t.false(select.exists('ul', select('lololol')));
t.true(elementExists('li', $('ul')));
t.false(elementExists('ul', $('li')));
t.false(elementExists('ul', $('lololol')));
});

test('selects all elements', t => {
t.plan(1);

const li = document.querySelectorAll('ul li');
t.deepEqual(select.all('ul li'), [...li]);
t.deepEqual($$('ul li'), [...li]);
});

test('selects all elements within an ancestor', t => {
t.plan(1);

const li = document.querySelector('ul').querySelectorAll('ul li');
t.deepEqual(select.all('li', select('ul')), [...li]);
t.deepEqual($$('li', $('ul')), [...li]);
});

test('selects all elements within an array of ancestors', t => {
t.plan(1);

const li = document.querySelectorAll('ul li');
t.deepEqual(select.all('li', select.all('ul')), [...li]);
t.deepEqual($$('li', $$('ul')), [...li]);
});

test('selects all elements within an array of ancestors without duplicates', t => {
t.plan(1);

const li = document.querySelector('ul').querySelectorAll('li');
t.deepEqual(select.all('li', [select('ul'), select('ul')]), [...li]);
t.deepEqual($$('li', [$('ul'), $('ul')]), [...li]);
});

0 comments on commit 1ca2b13

Please sign in to comment.