sprae 11.1.3 → 11.2.1
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/core.js +13 -15
- package/dist/sprae.js +8 -10
- package/dist/sprae.js.map +3 -3
- package/dist/sprae.min.js +2 -2
- package/dist/sprae.min.js.map +3 -3
- package/dist/sprae.umd.js +8 -10
- package/dist/sprae.umd.js.map +3 -3
- package/dist/sprae.umd.min.js +2 -2
- package/dist/sprae.umd.min.js.map +3 -3
- package/package.json +1 -1
- package/readme.md +46 -19
package/readme.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
> DOM tree microhydration
|
|
4
4
|
|
|
5
5
|
_Sprae_ is open & minimalistic progressive enhancement framework with _preact-signals_ based reactivity.<br/>
|
|
6
|
-
Perfect for small-scale websites, static pages, landings, prototypes, or
|
|
6
|
+
Perfect for small-scale websites, static pages, landings, prototypes, lightweight UI or as [SSR companion](#JSX).<br/>
|
|
7
7
|
A light and fast alternative to _alpine_, _petite-vue_ etc (see [why](#justification)).
|
|
8
8
|
|
|
9
9
|
## Usage
|
|
@@ -32,17 +32,18 @@ Sprae evaluates `:`-directives and evaporates them, returning reactive state for
|
|
|
32
32
|
UMD version enables sprae via CDN, as CJS, AMD etc.
|
|
33
33
|
|
|
34
34
|
```html
|
|
35
|
-
<!-- `init`
|
|
35
|
+
<!-- `init` autoinits sprae on document with initial state (optional) -->
|
|
36
36
|
<script src="https://cdn.jsdelivr.net/npm/sprae/dist/sprae.umd.js" init="{ user: 'buddy' }"></script>
|
|
37
37
|
|
|
38
38
|
<script>
|
|
39
|
-
window.sprae
|
|
39
|
+
window.sprae; // global standalone
|
|
40
40
|
</script>
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
-
|
|
44
43
|
## Directives
|
|
45
44
|
|
|
45
|
+
Directives can be either `:` or `s-` prefixed, which is identical.
|
|
46
|
+
|
|
46
47
|
#### `:if="condition"`, `:else`
|
|
47
48
|
|
|
48
49
|
Control flow of elements.
|
|
@@ -61,8 +62,7 @@ Control flow of elements.
|
|
|
61
62
|
Multiply element.
|
|
62
63
|
|
|
63
64
|
```html
|
|
64
|
-
|
|
65
|
-
<ul><li :each="item in items" :text="item"/></ul>
|
|
65
|
+
<ul><li :each="item in items" :text="item" /></ul>
|
|
66
66
|
|
|
67
67
|
<!-- cases -->
|
|
68
68
|
<li :each="item, idx in array" />
|
|
@@ -84,7 +84,7 @@ Set text content of an element.
|
|
|
84
84
|
Welcome, <span :text="user.name">Guest</span>.
|
|
85
85
|
|
|
86
86
|
<!-- fragment -->
|
|
87
|
-
Welcome, <template :text="user.name"
|
|
87
|
+
Welcome, <template :text="user.name"><template>.
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
#### `:class="value"`
|
|
@@ -92,11 +92,13 @@ Welcome, <template :text="user.name" />.
|
|
|
92
92
|
Set class value.
|
|
93
93
|
|
|
94
94
|
```html
|
|
95
|
-
|
|
96
|
-
|
|
95
|
+
<div :class="foo"></div>
|
|
96
|
+
|
|
97
|
+
<!-- appends to static class -->
|
|
98
|
+
<div class="bar" :class="baz"></div>
|
|
97
99
|
|
|
98
100
|
<!-- array/object, a-la clsx -->
|
|
99
|
-
<div :class="[foo && '
|
|
101
|
+
<div :class="['foo', bar && 'bar', { baz }]"></div>
|
|
100
102
|
```
|
|
101
103
|
|
|
102
104
|
#### `:style="value"`
|
|
@@ -104,13 +106,15 @@ Set class value.
|
|
|
104
106
|
Set style value.
|
|
105
107
|
|
|
106
108
|
```html
|
|
107
|
-
|
|
109
|
+
<span style="'display: inline-block'"></span>
|
|
110
|
+
|
|
111
|
+
<!-- extends static style -->
|
|
108
112
|
<div style="foo: bar" :style="'bar-baz: qux'">
|
|
109
113
|
|
|
110
114
|
<!-- object -->
|
|
111
115
|
<div :style="{barBaz: 'qux'}"></div>
|
|
112
116
|
|
|
113
|
-
<!-- CSS variable -->
|
|
117
|
+
<!-- set CSS variable -->
|
|
114
118
|
<div :style="{'--bar-baz': qux}"></div>
|
|
115
119
|
```
|
|
116
120
|
|
|
@@ -194,7 +198,7 @@ Attach event(s) listener with optional modifiers.
|
|
|
194
198
|
<input :value="text" :oninput:onchange="e => text = e.target.value">
|
|
195
199
|
|
|
196
200
|
<!-- sequence of events -->
|
|
197
|
-
<button :onfocus..onblur="e => (
|
|
201
|
+
<button :onfocus..onblur="e => (handleFocus(), e => handleBlur())">
|
|
198
202
|
|
|
199
203
|
<!-- modifiers -->
|
|
200
204
|
<button :onclick.throttle-500="handler">Not too often</button>
|
|
@@ -309,9 +313,10 @@ sprae.use({compile: justin}) // set up justin as default compiler
|
|
|
309
313
|
|
|
310
314
|
###### Operators:
|
|
311
315
|
|
|
312
|
-
`++ -- ! - +
|
|
316
|
+
`++ -- ! - + * / % ** && || ??`<br/>
|
|
313
317
|
`= < <= > >= == != === !==`<br/>
|
|
314
|
-
`<< >> & ^ | ~ ?: . ?. [] ()=>{} in
|
|
318
|
+
`<< >> >>> & ^ | ~ ?: . ?. [] ()=>{} in`<br/>
|
|
319
|
+
`= += -= *= /= %= **= &&= ||= ??= ... ,`
|
|
315
320
|
|
|
316
321
|
###### Primitives:
|
|
317
322
|
|
|
@@ -352,7 +357,7 @@ sprae.use({ compile })
|
|
|
352
357
|
|
|
353
358
|
* To prevent [FOUC](https://en.wikipedia.org/wiki/Flash_of_unstyled_content) add `<style>[:each],[:if],[:else] {visibility: hidden}</style>`.
|
|
354
359
|
* Attributes order matters, eg. `<li :each="el in els" :text="el.name"></li>` is not the same as `<li :text="el.name" :each="el in els"></li>`.
|
|
355
|
-
* Invalid self-closing tags like `<a :text="item" />` will cause error. Valid self-closing tags are: `li`, `p`, `dt`, `dd`, `option`, `tr`, `td`, `th`.
|
|
360
|
+
* Invalid self-closing tags like `<a :text="item" />` will cause error. Valid self-closing tags are: `li`, `p`, `dt`, `dd`, `option`, `tr`, `td`, `th`, `input`, `img`, `br`.
|
|
356
361
|
* Properties prefixed with `_` are untracked: `let state = sprae(el, {_x:2}); state._x++; // no effect`.
|
|
357
362
|
* To destroy state and detach sprae handlers, call `element[Symbol.dispose]()`.
|
|
358
363
|
* State getters/setters work as computed effects, eg. `sprae(el, { x:1, get x2(){ return this.x * 2} })`.
|
|
@@ -360,22 +365,26 @@ sprae.use({ compile })
|
|
|
360
365
|
* `event` is not used, `:on*` attributes expect a function with event argument `:onevt="event => handle()"`, see [#46](https://github.com/dy/sprae/issues/46).
|
|
361
366
|
* `key` is not used, `:each` uses direct list mapping instead of DOM diffing.
|
|
362
367
|
* `await` is not supported in attributes, it’s a strong indicator you need to put these methods into state.
|
|
368
|
+
* `:ref` comes after `:if` for mount/unmount events `<div :if="cond" :ref="(init(), ()=>dispose())"></div>`.
|
|
363
369
|
|
|
364
370
|
## Justification
|
|
365
371
|
|
|
366
|
-
Modern frontend stack is obese and unhealthy, like non-organic processed food. There are
|
|
372
|
+
Modern frontend stack is obese and unhealthy, like non-organic processed food. There are healthy alternatives, but:
|
|
367
373
|
|
|
368
374
|
* [Template-parts](https://github.com/dy/template-parts) 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).
|
|
369
375
|
* [Alpine](https://github.com/alpinejs/alpine) / [petite-vue](https://github.com/vuejs/petite-vue) / [lucia](https://github.com/aidenyabi/lucia) escape native HTML quirks, but have excessive API (`:`, `x-`, `{}`, `@`, `$`), tend to [self-encapsulate](https://github.com/alpinejs/alpine/discussions/3223) and not care about size/performance.
|
|
370
376
|
|
|
371
377
|
_Sprae_ holds open & minimalistic philosophy:
|
|
372
378
|
|
|
373
|
-
*
|
|
374
|
-
*
|
|
379
|
+
* Minimal syntax `:`.
|
|
380
|
+
* _Signals_ for reactivity.
|
|
381
|
+
* Pluggable directives, configurable internals.
|
|
375
382
|
* Small, safe & performant.
|
|
376
383
|
* Bits of organic sugar.
|
|
377
384
|
* Aims at making developers happy 🫰
|
|
378
385
|
|
|
386
|
+
> Perfection is not when there is nothing to add, but when there is nothing to take away.
|
|
387
|
+
|
|
379
388
|
<!--
|
|
380
389
|
| | [AlpineJS](https://github.com/alpinejs/alpine) | [Petite-Vue](https://github.com/vuejs/petite-vue) | Sprae |
|
|
381
390
|
|-----------------------|-------------------|-------------------|------------------|
|
|
@@ -445,6 +454,24 @@ npm run results
|
|
|
445
454
|
* [nuejs](https://github.com/nuejs/nuejs)
|
|
446
455
|
-->
|
|
447
456
|
|
|
457
|
+
## JSX
|
|
458
|
+
|
|
459
|
+
Sprae works with JSX via `s-` attributes, eg. Next.js companion for SSR.
|
|
460
|
+
|
|
461
|
+
Next.js server components fail at dynamic UI, like active nav, tabs, sliders etc. That forces into client components, which screws up data fetching, bloats hydration and adds overhead.`<Script>` is heavy and clunky hack. Sprae can offload UI logic to keep server components intact.
|
|
462
|
+
|
|
463
|
+
```jsx
|
|
464
|
+
// app/page.jsx - server component
|
|
465
|
+
export default function Page() {
|
|
466
|
+
return <>
|
|
467
|
+
<nav id="nav">
|
|
468
|
+
<a href="/" s-class="location.path === '/' && 'active'">Home</a>
|
|
469
|
+
<a href="/about" s-class="location.path === '/about' && 'active'">About</a>
|
|
470
|
+
</nav>
|
|
471
|
+
...
|
|
472
|
+
</>
|
|
473
|
+
}
|
|
474
|
+
```
|
|
448
475
|
|
|
449
476
|
## Examples
|
|
450
477
|
|