Skip to content

Commit

Permalink
Documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
stephband committed Jul 27, 2024
1 parent 02fd105 commit 9389723
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 58 deletions.
Binary file added assets/logo-v1.pxd
Binary file not shown.
35 changes: 23 additions & 12 deletions element/README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@

## `element()`

Literal wraps the tendrils of the various Custom Elements APIs into a single
`element()` function that aims to make the whole palaver a million times easier.
Literal wraps the mega-splat of the various Custom Elements APIs into a single
`element()` function that aims to make the whole palaver a million times easier
by cleaning up some gotchas, pitfalls and idiosyncrasies en route.

### How it works

Import the `element()` function, define, register and export a custom element.
Like this `<toggle-button>` for example:
Take this `<toggle-button>` definition, for example:

```js
// Import the element() function
Expand All @@ -29,10 +30,9 @@ property `active`. Its shadow DOM is rendered from a literal template which has
access to a `host` object, the element, and renders "on" when `.active` is
`true`, and "off" when `.active` is `false`.

The `active` attribute is a boolean attribute, it can be authored as
`<toggle-button active>`, or set via `.setAttribute()` and `.removeAttribute()`,
or the `.active` property can be set directly. Literal updates the shadow DOM
accordingly on the next animation frame.
```html
<toggle-button active>
```

```js
const toggle = document.querySelector('toggle-button');
Expand All @@ -53,14 +53,25 @@ definitions.
- `"tokens"` - defines a tokens attribute (think `class`) and a string setter / TokenList getter property
- `"src"` - defines a URL attribute that links to a data property (TODO)
- `"module"` - defines a URL attribute that ... (TODO)
- `"data"` - defines a property that exposes Literal's `data` object. This is
useful if you are building a closed system where literal custom elements are
authored inside literal templates, as data can be passed efficiently from
template to custom element.
- `"data"` - defines a property exposing literal's `data` object. Setting this
property to an object changes the data being rendered. Getting this property
returns literal's `data` proxy of the object.

This is useful if you are building a closed system where literal custom elements
are authored inside literal templates, as data can be passed efficiently from
template to custom element shadow DOM by the renderer.

```js
export default element("<show-text>", {
shadow: "<p>${ data.text }</p>"
}, {
data: "data"
});
```

```html
<template is="literal-html">
<p>The light is <toggle-button data="${ data }"></toggle-button></p>
<p>Data has the text "<show-text data="${ data }"><show-text>"</p>
</template>
```

Expand Down
23 changes: 3 additions & 20 deletions element/element.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import create from '../../dom/modules/create.js';
import element, { getInternals } from '../../dom/modules/element.js';
import toPrefetchPromise from '../../dom/modules/element/to-prefetch-promise.js';
import getById from '../modules/dom/get-by-id.js';
import assignDataset from '../modules/dom/assign-dataset.js';
import Literal from '../modules/template.js';
import defineProperty from './property.js';

Expand Down Expand Up @@ -75,24 +76,6 @@ function assignProperty(properties, entry) {
return properties;
}

function parseData(value) {
try {
return JSON.parse(value);
}
catch(e) {
return value;
}
}

function getDataFromDataset(dataset, data) {
const keys = Object.keys(dataset);
const values = Object.values(dataset);

return values
.map(parseData)
.reduce((data, value, i) => (data[keys[i]] = value, data), data);
}

export default function LiteralElement(tag, lifecycle = {}, properties = {}, parameters = {}) {
if (window.DEBUG && typeof src === 'string' && !/^#/.test(src)) {
console.error('TODO: Support external templates?');
Expand Down Expand Up @@ -126,7 +109,7 @@ export default function LiteralElement(tag, lifecycle = {}, properties = {}, par
internals.object = {};

// template, parent, parameters, data, options
const renderer = new Literal(template, this, assign({ host: this, shadow }, parameters), undefined);
const renderer = new Literal(template, this, assign({ host: this, shadow, internals }, parameters), undefined);
shadow.appendChild(renderer.content);

// Call lifecycle.construct()
Expand All @@ -141,7 +124,7 @@ export default function LiteralElement(tag, lifecycle = {}, properties = {}, par
internals.initialised = true;

// Get data found in dataset
getDataFromDataset(this.dataset, internals.object);
assignDataset(internals.object, this.dataset);

// Set internal data to object's observer proxy
internals.data = Data.of(internals.object);
Expand Down
28 changes: 2 additions & 26 deletions literal-html/module.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ make it easy to mix islands of dynamically rendered content into static content.
import noop from '../../fn/modules/noop.js';
import Signal from '../../fn/modules/signal.js';
import element, { getInternals as Internals } from '../../dom/modules/element.js';
import assignDataset from '../modules/dom/assign-dataset.js';
import requestData from '../modules/request-data.js';
import Template from '../modules/template.js';
import { printError } from '../modules/scope/print.js';
Expand All @@ -24,31 +25,6 @@ const onerror = window.DEBUG ?

/* Lifecycle */

function parseData(value) {
// Object or array
return robject.test(value) ? JSON.parse(value) :
// Number
!Number.isNaN(Number(value)) ? Number(value) :
// Boolean
value === 'true' ? true :
value === 'false' ? false :
// String
value ;
}

function getDataFromDataset(dataset) {
const keys = Object.keys(dataset);
const values = Object.values(dataset);

// Do this if you don't want templats to render before they are explicitly
// assigned data
//if (!keys.length) { return; }

return values
.map(parseData)
.reduce((data, value, i) => (data[keys[i]] = value, data), {});
}

// tag, template, lifecycle, properties, log
export default element('<template is="literal-html">', {
construct: function() {
Expand Down Expand Up @@ -83,7 +59,7 @@ export default element('<template is="literal-html">', {

// If src or data was not set use data found in dataset
if (!internals.promise && !internals.pushed) {
internals.data.value = getDataFromDataset(this.dataset);
internals.data.value = assignDataset({}, this.dataset);
}
}
}, {
Expand Down
18 changes: 18 additions & 0 deletions modules/dom/assign-dataset.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@

function parseData(value) {
try {
return JSON.parse(value);
}
catch(e) {
return value;
}
}

export default function assignDataset(object, dataset) {
const keys = Object.keys(dataset);
const values = Object.values(dataset);

return values
.map(parseData)
.reduce((object, value, i) => (object[keys[i]] = value, object), object);
}

0 comments on commit 9389723

Please sign in to comment.