sprae 2.8.1 → 2.8.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "sprae",
3
3
  "description": "DOM microhydration.",
4
- "version": "2.8.1",
4
+ "version": "2.8.2",
5
5
  "main": "src/index.js",
6
6
  "module": "src/index.js",
7
7
  "type": "module",
package/r&d.md CHANGED
@@ -343,10 +343,13 @@
343
343
  + can let means to enhance subscript's logs
344
344
  + that "unlimits" returned struct, so that any property can be added/deleted.
345
345
  - doesn't really save from `new (()=>{}).constructor` hack: we gotta substitute objects too.
346
+ ~ Proxy doesn't save from that either
346
347
  + allows easier handle of `:with="a=1,b=2,c=3"` - we just naturally get local variables without messup with global
347
348
  + we can even define locals without `let`...
348
349
  - not having "comfy" compatible JS at hand: cognitive load of whole language "layer" in-between
349
350
  + allows `let a = 1; a;` case instead of `let a = 1; return a;`
351
+ - we can't identify dynamic parts like `x[y]`, whereas signals subscribe dynamically
352
+ ~ we can detect dynamic parts and handle them on proxy
350
353
 
351
354
  -> We can benchmark if updating set of known dependencies is faster than using preact subscriptions.
352
355
  + it seems more logical min-ground to know in advance what we depend on, rather than detect by-call as signals do.
package/readme.md CHANGED
@@ -56,7 +56,7 @@ Control flow of elements.
56
56
 
57
57
  #### `:each="item, index in items"`
58
58
 
59
- Multiply element. `index` value starts from 1. Use `:key` as caching key to avoid rerendering.
59
+ Multiply element. `index` value starts from 1.
60
60
 
61
61
  ```html
62
62
  <ul>
@@ -72,6 +72,9 @@ Multiply element. `index` value starts from 1. Use `:key` as caching key to avoi
72
72
  <li :if="items" :each="item in items" :text="item" />
73
73
  <li :else>Empty list</li>
74
74
 
75
+ <!-- Key items to reuse elements -->
76
+ <li :each="item in items" :key="item.id" :text="item.value" />
77
+
75
78
  <!-- To avoid FOUC -->
76
79
  <style>[:each]{visibility: hidden}</style>
77
80
  ```
@@ -86,7 +89,7 @@ Welcome, <span :text="user.name">Guest</span>.
86
89
 
87
90
  #### `:class="value"`
88
91
 
89
- Set class value from either string, array or object. Extends direct class, rather than replaces.
92
+ Set class value from either string, array or object. Appends existing `class` attribute, if any.
90
93
 
91
94
  ```html
92
95
  <div :class="`foo ${bar}`"></div>
@@ -101,7 +104,7 @@ Set class value from either string, array or object. Extends direct class, rathe
101
104
 
102
105
  #### `:style="value"`
103
106
 
104
- Set style value from object or a string. Extends style.
107
+ Set style value from object or a string. Extends existing `style` attribute, if any.
105
108
 
106
109
  ```html
107
110
  <div :style="foo: bar"></div>
@@ -291,7 +294,7 @@ This way, for example, _@preact/signals_ or _rxjs_ can be connected directly byp
291
294
 
292
295
  <script type="module">
293
296
  import sprae from 'sprae';
294
- import { signals } from '@preact/signals';
297
+ import { signal } from '@preact/signals';
295
298
 
296
299
  // <div id="done">...</div>
297
300
 
@@ -343,7 +346,7 @@ This way, for example, _@preact/signals_ or _rxjs_ can be connected directly byp
343
346
 
344
347
  ## Justification
345
348
 
346
- _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[*](#justification).
349
+ _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.
347
350
 
348
351
  * [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.
349
352
  * [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.
package/src/core.js CHANGED
@@ -24,7 +24,7 @@ export default function sprae(container, values) {
24
24
  if (el.hasAttribute?.(attrName)) {
25
25
  let expr = el.getAttribute(attrName)
26
26
  el.removeAttribute(attrName)
27
- if (!expr) continue
27
+
28
28
  updates.push(primary[name](el, expr, state, name))
29
29
 
30
30
  // stop if element was spraed by directive or skipped (detached)
@@ -39,7 +39,7 @@ export default function sprae(container, values) {
39
39
  if (attr.name[0] !== ':') {i++; continue}
40
40
  el.removeAttribute(attr.name)
41
41
  let expr = attr.value
42
- if (!expr) continue
42
+
43
43
  // multiple attributes like :id:for=""
44
44
  let attrNames = attr.name.slice(1).split(':')
45
45
  for (let attrName of attrNames) {
package/src/directives.js CHANGED
@@ -252,13 +252,12 @@ export default (el, expr, state, name) => {
252
252
 
253
253
  if (!evaluate) return
254
254
 
255
- if (evt) return state => {
256
- let value = evaluate(state)
257
- if (value) {
258
- addListener(el, evt, value)
259
- return () => removeListener(el, evt, value)
260
- }
261
- }
255
+ if (evt) return (state => {
256
+ // we need anonymous callback to enable modifiers like prevent
257
+ let value = evaluate(state) || (()=>{})
258
+ addListener(el, evt, value)
259
+ return () => removeListener(el, evt, value)
260
+ })
262
261
 
263
262
  return state => attr(el, name, evaluate(state))
264
263
  }
package/test/test.js CHANGED
@@ -625,7 +625,7 @@ test('on: keys', e => {
625
625
  })
626
626
 
627
627
  test('on: keys with prevent', e => {
628
- let el = h`<y :onkeydown="e=>log.push(e.key)"><x :ref="x" :onkeydown.enter.stop="e=>1"></x></y>`
628
+ let el = h`<y :onkeydown="e=>log.push(e.key)"><x :ref="x" :onkeydown.enter.stop></x></y>`
629
629
  let state = sprae(el, {log:[]})
630
630
  state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'x', bubbles: true }));
631
631
  state.x.dispatchEvent(new window.KeyboardEvent('keydown', { key: 'Enter', bubbles: true }));