sprae 3.0.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +5 -3
- package/r&d.md +6 -0
- package/readme.md +55 -82
- package/sprae.auto.js +617 -0
- package/sprae.auto.min.js +1 -0
- package/sprae.js +20 -33
- package/sprae.min.js +1 -1
- package/src/core.js +2 -6
- package/src/directives.js +5 -22
- package/src/index.js +1 -5
- package/src/state.js +13 -10
- package/test/dom.js +78 -22
- package/test/index.html +6 -1
- package/test/state.js +34 -12
- package/todo.md +7 -5
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sprae",
|
|
3
3
|
"description": "DOM microhydration.",
|
|
4
|
-
"version": "
|
|
4
|
+
"version": "4.0.0",
|
|
5
5
|
"main": "src/index.js",
|
|
6
6
|
"module": "src/index.js",
|
|
7
7
|
"type": "module",
|
|
@@ -23,9 +23,11 @@
|
|
|
23
23
|
},
|
|
24
24
|
"scripts": {
|
|
25
25
|
"test": "node -r ./test/register.cjs test/test.js",
|
|
26
|
-
"build": "
|
|
26
|
+
"build": "npm run build-esm && npm run build-iife && npm run min",
|
|
27
|
+
"build-esm": "esbuild --bundle ./src/index.js --outfile=sprae.js --format=esm",
|
|
28
|
+
"build-iife": "esbuild --bundle ./src/index.js --outfile=sprae.auto.js --format=iife",
|
|
27
29
|
"watch": "esbuild --bundle ./src/index.js --outfile=sprae.js --format=esm --sourcemap --watch",
|
|
28
|
-
"min": "terser sprae.js -o sprae.min.js --module -c passes=3 -m"
|
|
30
|
+
"min": "terser sprae.js -o sprae.min.js --module -c passes=3 -m && terser sprae.auto.js -o sprae.auto.min.js --module -c passes=3 -m"
|
|
29
31
|
},
|
|
30
32
|
"repository": {
|
|
31
33
|
"type": "git",
|
package/r&d.md
CHANGED
|
@@ -474,6 +474,7 @@
|
|
|
474
474
|
* [ ] x.raf="abc" - run regularly?
|
|
475
475
|
* [ ] x.watch-a-b-c - update by change of any of the deps
|
|
476
476
|
* [ ] :x.always - update by _any_ dep change
|
|
477
|
+
* [ ] :class.active="active"
|
|
477
478
|
|
|
478
479
|
## [x] Writing props on elements (like ones in :each) -> nah, just use `:x="this.x=abc"`
|
|
479
480
|
|
|
@@ -526,3 +527,8 @@
|
|
|
526
527
|
|
|
527
528
|
1. :use="ref-id"
|
|
528
529
|
2. :
|
|
530
|
+
|
|
531
|
+
## [x] Remove non-essential directives -> yep, less API friction
|
|
532
|
+
* :aria - can be defined via plain attributes
|
|
533
|
+
* :data - confusable with :scope, doesn't provide much value, can be used as `:data-x=""` etc
|
|
534
|
+
* :={} - what's the meaning? Can be replaced with multiple attributes, no? No: no easy way to spread attributes.
|
package/readme.md
CHANGED
|
@@ -1,11 +1,35 @@
|
|
|
1
1
|
# ∴ spræ [](https://github.com/dy/sprae/actions/workflows/node.js.yml) [](https://bundlephobia.com/result?p=sprae) [](https://npmjs.org/sprae)
|
|
2
2
|
|
|
3
|
-
> DOM microhydration with `:` attributes
|
|
3
|
+
> DOM microhydration with `:` attributes.
|
|
4
4
|
|
|
5
|
+
_Sprae_ is tiny progressive enhancement lib, a minimal essential alternative to [alpine](https://github.com/alpinejs/alpine), [petite-vue](https://github.com/vuejs/petite-vue) or [template-parts](https://github.com/github/template-parts) with improved ergonomics. It enables simple markup logic without external scripts. Perfect for small websites or prototypes.
|
|
5
6
|
|
|
6
|
-
##
|
|
7
|
+
## Install
|
|
7
8
|
|
|
8
|
-
|
|
9
|
+
To autoinit on document, include [`sprae.auto.js`](./sprae.auto.js):
|
|
10
|
+
|
|
11
|
+
```html
|
|
12
|
+
<!-- <script src="https://cdn.jsdelivr.net/npm/sprae/sprae.auto.js" defer></script> -->
|
|
13
|
+
<script src="./path/to/sprae.auto.js" defer></script>
|
|
14
|
+
|
|
15
|
+
<div :scope="{foo:'bar'}">
|
|
16
|
+
<span :text="foo"></span>
|
|
17
|
+
</div>
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
To use as module, import [`sprae.js`](./sprae.js):
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<script type="module">
|
|
24
|
+
// import sprae from 'https://cdn.jsdelivr.net/npm/sprae/sprae.js';
|
|
25
|
+
import sprae from './path/to/sprae.js';
|
|
26
|
+
sprae(el, {foo: 'bar'});
|
|
27
|
+
</script>
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
## Use
|
|
31
|
+
|
|
32
|
+
Sprae evaluates attributes starting with `:`:
|
|
9
33
|
|
|
10
34
|
```html
|
|
11
35
|
<div id="container" :if="user">
|
|
@@ -20,30 +44,28 @@ Sprae defines attributes starting with `:` as directives:
|
|
|
20
44
|
</script>
|
|
21
45
|
```
|
|
22
46
|
|
|
23
|
-
* `sprae` initializes subtree with data and immediately evaporates `:` attrs.
|
|
24
|
-
* `state`
|
|
25
|
-
* To batch-update multiple properties `sprae` can be run repeatedly as: `sprae(container, newValues)`
|
|
47
|
+
* `sprae` initializes container's subtree with data and immediately evaporates `:` attrs.
|
|
48
|
+
* `state` object reflects current values, changing any props rerenders subtree next tick.
|
|
26
49
|
|
|
27
|
-
<!--
|
|
28
|
-
<details>
|
|
29
|
-
<summary><strong>Autoinit</strong></summary>
|
|
30
50
|
|
|
31
|
-
|
|
51
|
+
## Attributes
|
|
32
52
|
|
|
33
|
-
|
|
34
|
-
<script src="./sprae.js" defer init="{ count: 0 }"></script>
|
|
53
|
+
#### `:scope="data"`
|
|
35
54
|
|
|
36
|
-
|
|
37
|
-
<button :on="{ click: e => count++ }">inc</button>
|
|
38
|
-
```
|
|
55
|
+
Define or extend data scope for a subtree.
|
|
39
56
|
|
|
40
|
-
|
|
41
|
-
|
|
57
|
+
```html
|
|
58
|
+
<!-- Inline data -->
|
|
59
|
+
<x :scope="{ foo: 'bar' }" :text="foo"></x>
|
|
42
60
|
|
|
43
|
-
|
|
44
|
-
|
|
61
|
+
<!-- External data -->
|
|
62
|
+
<y :scope="data"></y>
|
|
45
63
|
|
|
46
|
-
|
|
64
|
+
<!-- Extend scope -->
|
|
65
|
+
<x :scope="{ foo: 'bar' }">
|
|
66
|
+
<y :scope="{ baz: 'qux' }" :text="foo + baz"></y>
|
|
67
|
+
</x>
|
|
68
|
+
```
|
|
47
69
|
|
|
48
70
|
#### `:if="condition"`, `:else`
|
|
49
71
|
|
|
@@ -90,17 +112,17 @@ Welcome, <span :text="user.name">Guest</span>.
|
|
|
90
112
|
|
|
91
113
|
#### `:class="value"`
|
|
92
114
|
|
|
93
|
-
Set class value from either string, array or object.
|
|
115
|
+
Set class value from either string, array or object. Extends existing `class` attribute, if any.
|
|
94
116
|
|
|
95
117
|
```html
|
|
96
118
|
<div :class="`foo ${bar}`"></div>
|
|
97
|
-
<div :class="['foo', 'bar']"></div>
|
|
98
|
-
<div :class="{foo: true, bar: false}"></div>
|
|
99
119
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
<div class="
|
|
103
|
-
|
|
120
|
+
<!-- extend existing class -->
|
|
121
|
+
<div class="foo" :class="`bar`"></div>
|
|
122
|
+
<!-- <div class="foo bar"></div> -->
|
|
123
|
+
|
|
124
|
+
<!-- object with values -->
|
|
125
|
+
<div :class="{foo:true, bar: false}"></div>
|
|
104
126
|
```
|
|
105
127
|
|
|
106
128
|
#### `:style="value"`
|
|
@@ -183,54 +205,10 @@ Add event listeners.
|
|
|
183
205
|
* `.ctrl-<key>, .alt-<key>, .meta-<key>, .shift-<key>` – key combinations, eg. `.ctrl-alt-delete` or `.meta-x`.
|
|
184
206
|
* `.*` – any other modifier has no effect, but allows binding multiple handlers to same event (like jQuery event classes).
|
|
185
207
|
|
|
186
|
-
#### `:data="values"`
|
|
187
|
-
|
|
188
|
-
Set [data-*](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/data-*) attributes. CamelCase is converted to dash-case.
|
|
189
|
-
|
|
190
|
-
```html
|
|
191
|
-
<input :data="{foo: 1, barBaz: true}" />
|
|
192
|
-
<!--
|
|
193
|
-
<input data-foo="1" data-bar-baz="true" />
|
|
194
|
-
-->
|
|
195
|
-
```
|
|
196
|
-
|
|
197
|
-
#### `:aria="values"`
|
|
198
|
-
|
|
199
|
-
Set [aria-role](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) attributes. Boolean values are stringified.
|
|
200
|
-
|
|
201
|
-
```html
|
|
202
|
-
<input role="combobox" :aria="{
|
|
203
|
-
controls: 'joketypes',
|
|
204
|
-
autocomplete: 'list',
|
|
205
|
-
expanded: false,
|
|
206
|
-
activeOption: 'item1',
|
|
207
|
-
activedescendant: ''
|
|
208
|
-
}" />
|
|
209
|
-
<!--
|
|
210
|
-
<input role="combobox" aria-controls="joketypes" aria-autocomplete="list" aria-expanded="false" aria-active-option="item1" aria-activedescendant="">
|
|
211
|
-
-->
|
|
212
|
-
```
|
|
213
|
-
|
|
214
|
-
#### `:with="data"`
|
|
215
|
-
|
|
216
|
-
Define variables for a subtree fragment scope.
|
|
217
|
-
|
|
218
|
-
```html
|
|
219
|
-
<!-- Inline data -->
|
|
220
|
-
<x :with="{ foo: 'bar' }" :text="foo"></x>
|
|
221
|
-
|
|
222
|
-
<!-- External data -->
|
|
223
|
-
<y :with="data"></y>
|
|
224
|
-
|
|
225
|
-
<!-- Transparency -->
|
|
226
|
-
<x :with="{ foo: 'bar' }">
|
|
227
|
-
<y :with="{ baz: 'qux' }" :text="foo + baz"></y>
|
|
228
|
-
</x>
|
|
229
|
-
```
|
|
230
208
|
|
|
231
209
|
#### `:ref="id"`
|
|
232
210
|
|
|
233
|
-
Expose element to data scope with the `id`:
|
|
211
|
+
Expose element to current data scope with the `id`:
|
|
234
212
|
|
|
235
213
|
```html
|
|
236
214
|
<!-- single item -->
|
|
@@ -254,28 +232,24 @@ Expose element to data scope with the `id`:
|
|
|
254
232
|
|
|
255
233
|
## Sandbox
|
|
256
234
|
|
|
257
|
-
Expressions are sandboxed, ie. have no access to global or window.
|
|
258
|
-
|
|
235
|
+
Expressions are sandboxed, ie. have no access to global or window (since sprae can be run in server environment).
|
|
259
236
|
Default sandbox provides: _Array_, _Object_, _Number_, _String_, _Boolean_, _Date_, _console_.
|
|
260
|
-
|
|
261
|
-
Sandbox can be extended via `Object.assign(sprae.globals, { BigInt, window, document })` etc.
|
|
237
|
+
Sandbox can be extended as `Object.assign(sprae.globals, { BigInt, window, document })` etc.
|
|
262
238
|
|
|
263
239
|
## Examples
|
|
264
240
|
|
|
265
241
|
* TODO MVC: [demo](https://dy.github.io/sprae/examples/todomvc), [code](https://github.com/dy/sprae/blob/main/examples/todomvc.html)
|
|
266
|
-
*
|
|
242
|
+
* Wavearea: [demo](https://dy.github.io/wavearea?src=//cdn.freesound.org/previews/586/586281_2332564-lq.mp3), [code](https://github.com/dy/wavearea)
|
|
267
243
|
|
|
268
244
|
## Justification
|
|
269
245
|
|
|
270
|
-
_Sprae_ is lightweight essential alternative to [alpine](https://github.com/alpinejs/alpine), [petite-vue](https://github.com/vuejs/petite-vue), [templize](https://github.com/dy/templize) or JSX with better ergonomics.
|
|
271
|
-
|
|
272
246
|
* [Template-parts](https://github.com/dy/template-parts) / [templize](https://github.com/dy/templize) is progressive, but is stuck with native HTML quirks ([parsing table](https://github.com/github/template-parts/issues/24), [svg attributes](https://github.com/github/template-parts/issues/25), [liquid syntax](https://shopify.github.io/liquid/tags/template/#raw) conflict etc). Also ergonomics of `attr="{{}}"` is inferior to `:attr=""` since it creates flash of uninitialized values.
|
|
273
247
|
* [Alpine](https://github.com/alpinejs/alpine) / [vue](https://github.com/vuejs/petite-vue) / [lit](https://github.com/lit/lit/tree/main/packages/lit-html) escapes native HTML quirks, but the syntax is a bit scattered: `:attr`, `v-*`,`x-*`, `@evt`, `{{}}` can be expressed with single convention. Besides, functionality is too broad and can be reduced to essence: perfection is when there's nothing to take away, not add. Also they tend to [self-encapsulate](https://github.com/alpinejs/alpine/discussions/3223), making interop hard.
|
|
274
248
|
* React/[preact](https://ghub.io/preact) does the job wiring up JS to HTML, but with an extreme of migrating HTML to JSX and enforcing SPA, which is not organic for HTML. Also it doesn't support reactive fields (needs render call).
|
|
275
249
|
|
|
276
|
-
_Sprae_ takes convention of _templize directives_ (_alpine_/_vue_ attrs) and builds upon [_@preact/signals_](https://ghub.io/@preact/signals).
|
|
250
|
+
_Sprae_ takes convention of _templize directives_ (_alpine_/_vue_ attrs) and builds upon <del>[_@preact/signals_](https://ghub.io/@preact/signals)</del> simple reacti.
|
|
277
251
|
|
|
278
|
-
* It doesn't break static html markup.
|
|
252
|
+
* It doesn't break or modify initial static html markup.
|
|
279
253
|
* It falls back to element content if uninitialized.
|
|
280
254
|
* It doesn't enforce SPA nor JSX.
|
|
281
255
|
* It enables island hydration.
|
|
@@ -284,7 +258,6 @@ _Sprae_ takes convention of _templize directives_ (_alpine_/_vue_ attrs) and bui
|
|
|
284
258
|
* Input data may contain [signals](https://ghub.io/@preact/signals) or [reactive values](https://ghub.io/sube).
|
|
285
259
|
* Elements / data API is open and enable easy interop.
|
|
286
260
|
|
|
287
|
-
|
|
288
261
|
It is reminiscent of [XSLT](https://www.w3schools.com/xml/xsl_intro.asp), considered a [buried treasure](https://github.com/bahrus/be-restated) by web-connoisseurs.
|
|
289
262
|
|
|
290
263
|
|