0.2.0 • Published 5 years ago

@dxworks/dom-utils v0.2.0

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

@dxworks/dom-utils

npm i @dxworks/dom-utils

DX Works' DOM Utility functions and re-export of @dxworks/utils

  • arrayIsEmpty
  • callAll
  • camelCaseToDash
  • compose
  • dashToCamelCase
  • escape
  • unescape
  • get
  • hashString
  • html
  • pipe
  • removeWhiteSpace
  • _throw
  • trueTypeOf
  • ueid

Usage example: import { exportName } from '@dxworks/dom-utils'

Modules

attr()

This utility function is useful for adding, removing, and getting attribute values from an element or list of elements. The function takes a single argument HTMLElement | NodeList and returns back two function get and set. Get will return an array of values for the provided attribute key on the provided element(s). Set will either remove or set and elements the attribute with the provided key on an element. It was inspired by Adam Argyle's blingblingjs.

example get attribute

const buttons = query('button');
const { get } = attr(buttons); 
get('type'); // => [...arrayOfTypeAttributes]

example remove attribute

const [button] = query('.submit-button')
const { set } = attr(button);
set('disabled', null)

example set attribute

const [button] = query('.submit-button')
const { set } = attr(button);
set('disabled') // default is ''
set('type',  'submit')

decorateElement()

This utility function is used to define webcomponents in html. It was forked from code found in this article

Example

In web component registry file

import { decorateElement } '@dxworks/dom-utils';
decorateElement(); 

In html file

<!-- shadow dom web component -->
<decorate-element tag='dx-shadow'>
  <template>
    <style>
      :host {
        color:red;
      }
    </style>
    <span>random</span>
  </template>
</decorate-element>
<dx-shadow></dx-shadow>

Then one could make use of this html template in their js files later like so

const template = ({country}) => html`<form>
  <label>Billing Address</label>
  <${country}-address></${country}-address>
</form>`

const component = base => class extends base {
  connectedCallback(){
    super.connectedCallback();
    fetchTemplateAndStyle(tplPath, cssPath) // would go to service worker for the partials first
    render({context: this, data: { country: 'us' }, template });
  }
}

createLight({
  tag: 'payment-form',
  template,
  component,
})

createLight()

This utility function allows you to define a new custom element with a lightDOM simply and quickly. Component is an optional argument for when you need an imperative api and the custom element lifecycle callbacks.

Example

// Define your element
createLight({
  tag: 'example-component',
  template: () => '<div>example component</div>',
  component: base => class extends base {
    static get observedAttributes() {
        return [/** will be lazy reflected on upgrade **/];
      }
    /** your methods and custom element lifecycle callbacks **/
  },
});

createShadow()

This utility function allows a developer to define a new custom element with a shadowDOM simply and quickly. Component is an optional argument for when you need an imperative api and the custom element lifecycle callbacks.

Any method you add that starts with on will be delegated to the component instances event listener. This removes the need to manually bind events

shadowReset

Every component made with this utility function includes the following shadowReset styles

::-webkit-scrollbar { 
  display: none; 
}
*,
*:before,
*:after {
  box-sizing: border-box;
}
:host {
  contain: content;
}
:host([hidden]), :host(:not(:defined)) { display: none; }

example

// Define your element
createShadow({
 tag: 'pricing-tier',
 style: css`:host { display: block; }`,
 template: () => html`    
    <header>
      <h1>$<slot name="price"></slot></h1>
      <h2><slot name="name"></slot></h2>
    </header>

    <div class="features">
      <slot name="features"></slot>
    </div>
  `,
  mode = 'open', /** @param {string} mode Optional param that defaults to 'open' */
  delegatesFocus = true, /** @param {boolean} delegateFocus Optional param that defaults to undefined */
  component: base => class extends base {
    static get observedAttributes() {
        return [/** will be lazy reflected on upgrade along with their getters and setters being defined **/];
      }
    /** your methods and custom element lifecycle callbacks **/
    connectedCallback() {
      super.connectedCallback();
      const { set } = attr(this);
      set('hidden', '');
      set('aria-hidden', 'true');
    }

    onslotchange() {
      /** listen for slot change events without having to manually wire **/
      const { set } = attr(this);
      const [slot] = query('[name="features"]', this.shadowRoot);
      const show = () => {
        set('aria-hidden', 'false');
        set('hidden', null);
      };
      const hide = () => {
        set('aria-hidden', 'true');
        set('hidden', '');
      };
      slot.assignedNodes().length > 0
        ? show()
        : hide();
    }
  },
});

css() & constructable

Use to create StyleSheets for Custom Elements will return a Constructable StyleSheets in browsers that support the spec or a string in browsers that do not.

example

To check for support

import { constructable } from '@dxworks/dom-utils'
constructable // => will be true if the spec is supported

example

const set = css`
    :host(:not(:last-child)){
      display:none;
    }
    .ExampleOuter {
      grid-template-columns: 1fr 60px;
    }
  `;
const actual = css`
  ${set}
  .ExampleOuter {
    color: white;
  }
  .ExampleInner {
    background-color: blue;
  }
`;

query()

This utility function is useful for querying for a nodeList. The function will return a non-live node list.

example

Default context is document

const [button] = query('button') // default context is document.

example: custom element

Use the custom element as the context for querying it's light dom.

const [button] = query('button', this);

example: shadow dom

Use the custom elements shadowRoot as the context for querying it's shadow dom.

const doSomething = e => {};
const [button] = query('button', this.shadowRoot);

render()

Use this function to render a template into a target element.

example

const body = document.querySelector('body');
render({
  node: body,
  template: (data) => html`<div>${data.text}</div>`,
  data: { text: 'example component' } ,
})
0.2.0

5 years ago

0.1.1

5 years ago

0.1.0

5 years ago