Skip to content

Commit 531e2fa

Browse files
Documentation
1 parent d65af84 commit 531e2fa

File tree

1 file changed

+59
-13
lines changed

1 file changed

+59
-13
lines changed

README.md

+59-13
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,14 @@
1010
[![MIT License](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
1111

1212

13-
A minimalist one-way binding helper.
13+
A minimalist *(⇡ check the install size)* one-way binding helper.
1414

1515
## Usage
1616

17-
### 1. Inject the punybind helper
17+
### 1. Include the punybind helper
1818

1919
```html
20-
<script src="punybind.js"></script>
20+
<script src="https://cdn.jsdelivr.net/npm/punybind/dist/punybind.js"></script>
2121
```
2222

2323
### 2. Define bindings in the HTML
@@ -26,7 +26,6 @@ A minimalist one-way binding helper.
2626
<html>
2727
<head>
2828
<title>TODO list</title>
29-
<script src="punybind.js"></script>
3029
</head>
3130
<body>
3231
<h1>{{ title }}</h1>
@@ -40,8 +39,7 @@ A minimalist one-way binding helper.
4039
</html>
4140
```
4241

43-
Text elements and attribute values can use `{{ }}` syntax.
44-
The special `{{for}}` attribute defines an iteration.
42+
See below for supported syntaxes.
4543

4644
### 3. Bind the section
4745

@@ -52,35 +50,83 @@ const update = await punybind(document.body)
5250
The `update` asynchronous method exposes the following properties :
5351
* `bindingsCount` (number) : The number of bindings detected
5452
* `model` (object) : The reactive model (see below)
53+
* `done` (function) : Returns a promise being fulfilled when the last update completes (see below).
54+
55+
Upon `update` invocation, the returned [promise is fulfilled](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise) when the DOM update is **completed**.
5556

5657
### 4. Update the section by passing a context object
5758

5859
```JavaScript
5960
await update({
6061
title: 'My TODO list',
6162
items: [{
62-
done: false,
63+
done: true,
6364
text: 'Forget about heavy frameworks'
6465
}, {
65-
done: true,
66+
done: false,
6667
text: 'Adopt punybind'
6768
}]
6869
})
6970
```
7071

72+
*Or use the reactive model (see below).*
73+
7174
### 5. Enjoy !
7275

76+
## Supported syntaxes
77+
78+
### Text and attribute binding
79+
80+
Text nodes and attribute values leverage binding using the `{{ expression }}` syntax.
81+
82+
The `expression` is evaluated with the properties of the contextual object.
83+
84+
It is possible to mix static content with computed one but *any* error **clears** the whole value.
85+
86+
### Iterators
87+
88+
Iterators allow the repetition of elements.
89+
90+
An iterator is declared **on** the element to repeat using the special attribute `{{for}}` with the value being either :
91+
* `{{for}}="item of expression"`
92+
* `{{for}}="item, index of expression"`
93+
94+
Where :
95+
* `item` is the contextual property receiving the value of the current iteration (to use in the subsequent bindings),
96+
* `index` is the contextual property receiving the index of the current iteration (0-based),
97+
* `expression` must evaluate to an [iterable object](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Iteration_protocols).
98+
99+
### Conditionals
100+
101+
Conditionals rule the rendering of elements.
102+
103+
They can form an `if` / `elseif` / `else` chain. Their expression must evaluate to a [truthy value](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) to enable rendering.
104+
105+
To work properly, the attributes must be set **on contiguous sibling elements** :
106+
* `{{if}}="expression"` : must be the first element of the chain,
107+
* `{{elseif}}="expression"` : (optional) is evaluated and rendered only if the previous `if` / `elseif` did not evaluate to a truthy value,
108+
* `{{else}}` : (optional) terminates the chain and is rendered only if the previous `if` / `elseif` did not evaluate to a truthy value.
109+
73110
## Reactive model
74111

75112
```JavaScript
76-
const { model } = await punybind(document.body, {
77-
title: 'Hello World !'
113+
const { model, done } = await punybind(document.body, {
114+
title: 'Hello World !',
115+
items: []
78116
})
79117
console.log(model.title) // Hello World !
80-
model.title = 'It works !' // Triggers update
118+
// The following lines of code trigger updates
119+
model.title = 'My TODO list'
120+
model.items.push({
121+
done: false,
122+
text: 'Adopt punybind'
123+
})
124+
await done() // Wait for the DOM update to be completed
81125
```
82126

83127
## Implementation notes
84128

85-
* This implementation is **not** compliant with [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
86-
* For textual values, it is possible to mix static content with computed one but any error clears the whole value.
129+
* The implementation is **not** compliant with [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP).
130+
* **Only** properties coming from the contextual object can be used in evaluated expressions.
131+
* Bound elements are *hidden* under [`template` elements](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/template).
132+
* When any error occurs *(inconsistent binding, invalid syntax)*, the binding **silently** fails.

0 commit comments

Comments
 (0)