1.0.1 ā€¢ Published 5 years ago

pipe-dom v1.0.1

Weekly downloads
2
License
MIT
Repository
github
Last release
5 years ago

Welcome to pipe-dom šŸ‘‹

npm version License: MIT Twitter: JamesDiGioia Build Status

DOM manipulation with the F#-style pipeline operator

Install

pipe-dom is intended to be used with the F#-style pipeline operator.

npm install --save pipe-dom @babel/core @babel/plugin-proposal-pipeline-operator

Configure your .babelrc:

{
  "plugins": [["@babel/proposal-pipeline-operator", { "proposal": "fsharp" }]]
}

Philosophy

  • Experimental: This library is intended to be used in combination with the pipeline operator, a Stage 1 proposal. Because that proposal is experimental & in flux, this library will be too, as we want to be able to adjust the API of the library to align with pipeline best practices. This library will follow semver in doing so, but breaking changes are possible, if not likely. This will change if the pipeline operator is accepted.
  • Modern Browsers: While we aim to normalize API differences across modern browsers, we are not going to support old browsers (cough IE11 cough). We will use modern DOM API methods internally. If your target browsers do not support those methods, they should be polyfilled by the consumer, but because of the experimental nature of the library, we don't foresee this being a problem. This also could change if the pipeline operator is accepted.
  • Expansive: While the initial release has a small API surface, any useful methods are welcome to be added. Because it exports functions, the library is tree-shakeable, which means extra methods have little to no impact on consumer bundle size.
  • Arrays Everywhere: queryAll returns an array rather than a NodeList, and the map implementation will returns an array. This is a cleanest primitive to target and work with. NodeLists are to be avoided.
  • Impure: This is not inteded to be a functional library, but a fluent one a la jQuery. Because we're dealing with the DOM, Nodes will be mutated. This can produce some weird behavior, like this:

    queryAll('.some-class') |> map(append(someNode));

    This will result in someNode attached to the last element in the list, as the reference to someNode remains the same across all iterations. Appending each time will move someNode to the next element in the list. If you want to create a new node on every iteration, try this:

    queryAll('.some-class') |> map(append(el => el |> append(createNode())));

API

query

function query(selector: string): Node;

Query for a single element by the given selector.

Example

query('.my-class');

queryAll

function queryAll(selector: string): Node[];

Query for an array of elements by the given selector.

Example

queryAll('.my-class');

map

function map<T, V>(callback: (element: T) => V): (target: T[]) => V[];

A curried map function to use with an array of Nodes.

Example

queryAll('.my-class')
  |> map(x => {
    console.log(x);
    return x;
  });

append

function append(...element: Node[]): (target: Node) => target;

Append Nodes as the last children to the given Node.

Example

query('ul') |> append(document.createElement('li'));

prepend

function prepend(...element: Node): (target: Node) => target;

Append Nodes as the first child to the given Node.

Example

query('ul') |> prepend(document.createElement('li'));

insertBefore

function insertBefore(
  relative: Node,
  ...inserting: Node[]
): (target: Node) => target;

Insert Nodes before relative child of target Node.

Example

query('ul') |> insertBefore(query('li.first'), document.createElement('li'));

insertAfter

function insertAfter(
  relative: Node,
  ...inserting: Node[]
): (target: Node) => target;

Insert Nodes after relative child of target Node.

Example

query('ul') |> insertAfter(query('li.first'), document.createElement('li'));

replace

function replace(oldChild: Node, newChild: Node): (target: Node) => target;

Replace an existing child Node with a new child Node for the target Node.

Example

query('ul') |> replace(query('li.first'), document.createElement('li'));

remove

function remove(child: Node): (target: Node) => target;

Remove a child Node from a given Node.

Example

query('ul') |> remove(query('li.first'));

contains

function container(contained: Node): (target: Node) => boolean;

Determines whether one Node is contained in another Node.

Example

query('ul') |> contains(query('li.first'));

setAttribute

function setAttribute(name: string, value: string): (target: Node) => target;

Sets the attribute to a given value on the target Node.

Example

query('input') |> setAttribute('name', 'username');

getAttribute

function getAttribute(name: string): (target: Node) => string;

Get an attribute from the target Node.

Example

query('input') |> getAttribute('value');

addClass

function addClass(className: string): (target: Node) => target;

Adds a class to a target Node.

Example

query('input') |> addClass('error');

removeClass

function removeClass(className: string): (target: Node) => target;

Removes a class from a target Node.

Example

query('.my-class') |> removeClass('my-class');

toggleClass

function toggleClass(
  className: string,
  toggle?: boolean
): (target: Node) => target;

Toggles a class on a target Node. If toggle is provided, class will be in provided state (on for true, off for false). If toggle not provided, class state will be swapped from current (added if missing, removed if present).

Example

query('.my-class') |> toggleClass('my-class', false);
query('.my-class') |> toggleClass('my-class', true);
query('.my-class') |> toggleClass('my-class');

on

interface Options {
  capture?: boolean;
  once?: boolean;
  passive?: boolean;
}

function on(
  event: string,
  handler: (e: Event) => void,
  options?: Options | boolean
): (target: Node) => target;

Adds an event listener to the target Node.

Example

query('button') |> on('click', e => console.log(e));

off

interface Options {
  capture?: boolean;
  once?: boolean;
  passive?: boolean;
}

function off(
  event: string,
  handler: (e: Event) => void,
  options?: Options | boolean
): (target: Node) => target;

Removes an event listener from the target Node.

Example

const handler = e => console.log(e);
query('button') |> off('click', handler);

Author

šŸ‘¤ James DiGioia jamesorodig@gmail.com (http://jamesdigioia.com)

šŸ¤ Contributing

Contributions, issues and feature requests are welcome!Feel free to check issues page.

Run tests

npm test

Show your support

Give a ā­ļø if this project helped you!

šŸ“ License

Copyright Ā© 2019 James DiGioia <jamesorodig@gmail.com> (http://jamesdigioia.com). This project is MIT licensed.