@dxworks/dom-utils v0.2.0
@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' } ,
})