@ramstack/alpinegear-bound 1.1.0 → 1.2.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/README.md +27 -0
- package/alpinegear-bound.esm.js +22 -9
- package/alpinegear-bound.esm.min.js +1 -1
- package/alpinegear-bound.js +22 -9
- package/alpinegear-bound.min.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -212,6 +212,33 @@ The group of `<input>` elements that should function together can utilize the `g
|
|
|
212
212
|
</div>
|
|
213
213
|
```
|
|
214
214
|
|
|
215
|
+
### Binding `input[type="checkbox"]:indeterminate` property
|
|
216
|
+
The `x-bound` directive supports binding the `indeterminate` property of `<input type="checkbox">` elements,
|
|
217
|
+
allowing you to control the checkbox's indeterminate state (a state where the checkbox is neither checked nor unchecked,
|
|
218
|
+
typically represented visually with a dash or similar indicator).
|
|
219
|
+
|
|
220
|
+
This is useful for scenarios like selecting a subset of items in a list, such as in a table header checkbox:
|
|
221
|
+
```html
|
|
222
|
+
<table>
|
|
223
|
+
<thead>
|
|
224
|
+
<tr>
|
|
225
|
+
<th>
|
|
226
|
+
<input type="checkbox"
|
|
227
|
+
&indeterminate="isPartialSelected"
|
|
228
|
+
&checked="isAllSelected" />
|
|
229
|
+
</th>
|
|
230
|
+
<th>Value</th>
|
|
231
|
+
</tr>
|
|
232
|
+
</thead>
|
|
233
|
+
...
|
|
234
|
+
</table>
|
|
235
|
+
```
|
|
236
|
+
In this example, the `indeterminate` property of the checkbox is bound to the `isPartialSelected` data property.
|
|
237
|
+
When `isPartialSelected` is `true`, the checkbox will be in the indeterminate state.
|
|
238
|
+
|
|
239
|
+
> [!NOTE]
|
|
240
|
+
> The `indeterminate` binding is one-way. Changes to the indeterminate property in the DOM (e.g., via user interaction or JavaScript) do not update the bound data property.
|
|
241
|
+
|
|
215
242
|
### Binding `Alpine` data properties
|
|
216
243
|
|
|
217
244
|
The directive also supports synchronizing values between two data properties.
|
package/alpinegear-bound.esm.js
CHANGED
|
@@ -38,10 +38,10 @@ function has_setter(value) {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
const key = Symbol();
|
|
41
|
-
let
|
|
41
|
+
let observer;
|
|
42
42
|
|
|
43
43
|
function observe_resize(el, listener) {
|
|
44
|
-
|
|
44
|
+
observer ??= new ResizeObserver(entries => {
|
|
45
45
|
for (const e of entries) {
|
|
46
46
|
for (const callback of e.target[key]?.values() ?? []) {
|
|
47
47
|
callback(e);
|
|
@@ -52,19 +52,19 @@ function observe_resize(el, listener) {
|
|
|
52
52
|
el[key] ??= new Set();
|
|
53
53
|
el[key].add(listener);
|
|
54
54
|
|
|
55
|
-
|
|
55
|
+
observer.observe(el);
|
|
56
56
|
|
|
57
57
|
return () => {
|
|
58
58
|
el[key].delete(listener);
|
|
59
59
|
|
|
60
60
|
if (!el[key].size) {
|
|
61
|
-
|
|
61
|
+
observer.unobserve(el);
|
|
62
62
|
el[key] = null;
|
|
63
63
|
}
|
|
64
64
|
};
|
|
65
65
|
}
|
|
66
66
|
|
|
67
|
-
const warn = (...args) => console.warn("
|
|
67
|
+
const warn = (...args) => console.warn("alpinegear.js:", ...args);
|
|
68
68
|
const is_array = Array.isArray;
|
|
69
69
|
const is_nullish = value => value === null || value === undefined;
|
|
70
70
|
const is_checkable_input = el => el.type === "checkbox" || el.type === "radio";
|
|
@@ -141,6 +141,7 @@ const canonical_names = create_map(
|
|
|
141
141
|
"videoHeight,videoWidth," +
|
|
142
142
|
"naturalHeight,naturalWidth," +
|
|
143
143
|
"clientHeight,clientWidth,offsetHeight,offsetWidth," +
|
|
144
|
+
"indeterminate," +
|
|
144
145
|
"open," +
|
|
145
146
|
"group");
|
|
146
147
|
|
|
@@ -217,6 +218,10 @@ function plugin({ directive, entangle, evaluateLater, mapAttributes, mutateDom,
|
|
|
217
218
|
process_dimensions();
|
|
218
219
|
break;
|
|
219
220
|
|
|
221
|
+
case "indeterminate":
|
|
222
|
+
process_indeterminate();
|
|
223
|
+
break;
|
|
224
|
+
|
|
220
225
|
case "open":
|
|
221
226
|
process_details();
|
|
222
227
|
break;
|
|
@@ -247,12 +252,12 @@ function plugin({ directive, entangle, evaluateLater, mapAttributes, mutateDom,
|
|
|
247
252
|
|
|
248
253
|
const source = {
|
|
249
254
|
get: create_getter(evaluateLater, source_el, expression),
|
|
250
|
-
set: create_setter(evaluateLater, source_el, expression)
|
|
255
|
+
set: create_setter(evaluateLater, source_el, expression)
|
|
251
256
|
};
|
|
252
257
|
|
|
253
258
|
const target = {
|
|
254
259
|
get: create_getter(evaluateLater, el, value),
|
|
255
|
-
set: create_setter(evaluateLater, el, value)
|
|
260
|
+
set: create_setter(evaluateLater, el, value)
|
|
256
261
|
};
|
|
257
262
|
|
|
258
263
|
switch (modifier) {
|
|
@@ -290,14 +295,14 @@ function plugin({ directive, entangle, evaluateLater, mapAttributes, mutateDom,
|
|
|
290
295
|
|
|
291
296
|
|
|
292
297
|
|
|
293
|
-
|
|
298
|
+
setTimeout(() => {
|
|
294
299
|
|
|
295
300
|
|
|
296
301
|
is_nullish(get_value()) && update_variable();
|
|
297
302
|
|
|
298
303
|
effect(() => apply_select_values(el, as_array(get_value() ?? [])));
|
|
299
304
|
cleanup(listen(el, "change", () => set_value(collect_selected_values(el))));
|
|
300
|
-
});
|
|
305
|
+
}, 0);
|
|
301
306
|
|
|
302
307
|
processed = true;
|
|
303
308
|
break;
|
|
@@ -312,6 +317,14 @@ function plugin({ directive, entangle, evaluateLater, mapAttributes, mutateDom,
|
|
|
312
317
|
}
|
|
313
318
|
}
|
|
314
319
|
|
|
320
|
+
function process_indeterminate() {
|
|
321
|
+
if (el.type === "checkbox") {
|
|
322
|
+
is_nullish(get_value()) && update_variable();
|
|
323
|
+
effect(update_property);
|
|
324
|
+
processed = true;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
|
|
315
328
|
function process_files() {
|
|
316
329
|
if (el.type === "file") {
|
|
317
330
|
cleanup(listen(el, "input", update_variable));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
function e(e,...t){const n=e(...t);return()=>{let e;return n(
|
|
1
|
+
function e(e,...t){const n=e(...t);return()=>{let e;return n(t=>e=t),t=e,"function"==typeof t?.get?e.get():e;var t}}function t(e,...t){const n=e(...t);t[t.length-1]=`${t.at(-1)} = __val`;const i=e(...t);return e=>{let t;n(e=>t=e),function(e){return"function"==typeof e?.set}(t)?t.set(e):i(()=>{},{scope:{__val:e}})}}const n=Symbol();let i;const a=(...e)=>console.warn("alpinegear.js:",...e),r=Array.isArray,o=e=>null==e,c=e=>"checkbox"===e.type||"radio"===e.type,s=e=>r(e)?e:[e],u=(e,t)=>e==t,l=(e,t)=>e.findIndex(e=>e==t),d=(e,t)=>e.includes(t),p=(e,t,n,i)=>(e.addEventListener(t,n,i),()=>e.removeEventListener(t,n,i)),f=e=>"object"==typeof e?JSON.parse(JSON.stringify(e)):e;function v(e,t,n=null){const{effect:i,release:a}=Alpine;let r,o,c=!1;const s=i(()=>{r=e(),c||(n?.deep&&JSON.stringify(r),o=r),(c||(n?.immediate??1))&&setTimeout(()=>{t(r,o),o=r},0),c=!0});return()=>a(s)}const h=new Map("value,checked,files,innerHTML,innerText,textContent,videoHeight,videoWidth,naturalHeight,naturalWidth,clientHeight,clientWidth,offsetHeight,offsetWidth,indeterminate,open,group".split(",").map(e=>[e.trim().toLowerCase(),e.trim()]));function b({directive:b,entangle:g,evaluateLater:m,mapAttributes:k,mutateDom:x,prefixed:y}){k(e=>({name:e.name.replace(/^&/,y("bound:")),value:e.value})),b("bound",(b,{expression:k,value:y,modifiers:T},{effect:w,cleanup:E})=>{if(!y)return void a("x-bound directive expects the presence of a bound property name");const H=b.tagName.toUpperCase();k=k?.trim();const _=h.get(y.trim().replace("-","").toLowerCase());k||=_;const L=e(m,b,k),S=t(m,b,k),W=()=>u(b[_],L())||x(()=>b[_]=L()),A=()=>S((e=>"number"===e.type||"range"===e.type)(b)?function(e){return""===e?null:+e}(b[_]):b[_]);let C;switch(_){case"value":!function(){switch(H){case"INPUT":case"TEXTAREA":o(L())&&A(),w(W),E(p(b,"input",A)),C=!0;break;case"SELECT":setTimeout(()=>{o(L())&&A(),w(()=>function(e,t){for(const n of e.options)n.selected=l(t,n.value)>=0}(b,s(L()??[]))),E(p(b,"change",()=>S(function(e){return e.multiple?[...e.selectedOptions].map(e=>e.value):e.value}(b))))},0),C=!0}}();break;case"checked":c(b)&&(w(W),E(p(b,"change",A)),C=!0);break;case"files":"file"===b.type&&(E(p(b,"input",A)),C=!0);break;case"innerHTML":case"innerText":case"textContent":"true"===b.contentEditable&&(o(L())&&A(),w(W),E(p(b,"input",A)),C=!0);break;case"videoHeight":case"videoWidth":N("VIDEO","resize");break;case"naturalHeight":case"naturalWidth":N("IMG","load");break;case"clientHeight":case"clientWidth":case"offsetHeight":case"offsetWidth":E(function(e,t){return i??=new ResizeObserver(e=>{for(const t of e)for(const e of t.target[n]?.values()??[])e(t)}),e[n]??=new Set,e[n].add(t),i.observe(e),()=>{e[n].delete(t),e[n].size||(i.unobserve(e),e[n]=null)}}(b,A)),C=!0;break;case"indeterminate":"checkbox"===b.type&&(o(L())&&A(),w(W),C=!0);break;case"open":"DETAILS"===H&&(o(L())&&A(),w(W),E(p(b,"toggle",A)),C=!0);break;case"group":c(b)&&(b.name||x(()=>b.name=k),w(()=>x(()=>function(e,t){e.checked=r(t)?l(t,e.value)>=0:u(e.value,t)}(b,L()??[]))),E(p(b,"input",()=>S(function(e,t){if("radio"===e.type)return e.value;t=s(t);const n=l(t,e.value);return e.checked?n>=0||t.push(e.value):n>=0&&t.splice(n,1),t}(b,L())))),C=!0)}if(!C){const n=d(T,"in")?"in":d(T,"out")?"out":"inout",i=k===y?((e,t)=>{for(;e&&!t(e);)e=(e._x_teleportBack??e).parentElement;return e})(b.parentNode,e=>e._x_dataStack):b;if(!b._x_dataStack)return void a("x-bound directive requires the presence of the x-data directive to bind component properties");if(!i)return void a(`x-bound directive cannot find the parent scope where the '${y}' property is defined`);const r={get:e(m,i,k),set:t(m,i,k)},o={get:e(m,b,y),set:t(m,b,y)};switch(n){case"in":E(v(()=>r.get(),e=>o.set(f(e))));break;case"out":E(v(()=>o.get(),e=>r.set(f(e))));break;default:E(g(r,o))}}function N(e,t){H===e&&(A(),E(p(b,t,A)),C=!0)}})}export{b as bound};
|
package/alpinegear-bound.js
CHANGED
|
@@ -41,10 +41,10 @@
|
|
|
41
41
|
}
|
|
42
42
|
|
|
43
43
|
const key = Symbol();
|
|
44
|
-
let
|
|
44
|
+
let observer;
|
|
45
45
|
|
|
46
46
|
function observe_resize(el, listener) {
|
|
47
|
-
|
|
47
|
+
observer ??= new ResizeObserver(entries => {
|
|
48
48
|
for (const e of entries) {
|
|
49
49
|
for (const callback of e.target[key]?.values() ?? []) {
|
|
50
50
|
callback(e);
|
|
@@ -55,19 +55,19 @@
|
|
|
55
55
|
el[key] ??= new Set();
|
|
56
56
|
el[key].add(listener);
|
|
57
57
|
|
|
58
|
-
|
|
58
|
+
observer.observe(el);
|
|
59
59
|
|
|
60
60
|
return () => {
|
|
61
61
|
el[key].delete(listener);
|
|
62
62
|
|
|
63
63
|
if (!el[key].size) {
|
|
64
|
-
|
|
64
|
+
observer.unobserve(el);
|
|
65
65
|
el[key] = null;
|
|
66
66
|
}
|
|
67
67
|
};
|
|
68
68
|
}
|
|
69
69
|
|
|
70
|
-
const warn = (...args) => console.warn("
|
|
70
|
+
const warn = (...args) => console.warn("alpinegear.js:", ...args);
|
|
71
71
|
const is_array = Array.isArray;
|
|
72
72
|
const is_nullish = value => value === null || value === undefined;
|
|
73
73
|
const is_checkable_input = el => el.type === "checkbox" || el.type === "radio";
|
|
@@ -144,6 +144,7 @@
|
|
|
144
144
|
"videoHeight,videoWidth," +
|
|
145
145
|
"naturalHeight,naturalWidth," +
|
|
146
146
|
"clientHeight,clientWidth,offsetHeight,offsetWidth," +
|
|
147
|
+
"indeterminate," +
|
|
147
148
|
"open," +
|
|
148
149
|
"group");
|
|
149
150
|
|
|
@@ -220,6 +221,10 @@
|
|
|
220
221
|
process_dimensions();
|
|
221
222
|
break;
|
|
222
223
|
|
|
224
|
+
case "indeterminate":
|
|
225
|
+
process_indeterminate();
|
|
226
|
+
break;
|
|
227
|
+
|
|
223
228
|
case "open":
|
|
224
229
|
process_details();
|
|
225
230
|
break;
|
|
@@ -250,12 +255,12 @@
|
|
|
250
255
|
|
|
251
256
|
const source = {
|
|
252
257
|
get: create_getter(evaluateLater, source_el, expression),
|
|
253
|
-
set: create_setter(evaluateLater, source_el, expression)
|
|
258
|
+
set: create_setter(evaluateLater, source_el, expression)
|
|
254
259
|
};
|
|
255
260
|
|
|
256
261
|
const target = {
|
|
257
262
|
get: create_getter(evaluateLater, el, value),
|
|
258
|
-
set: create_setter(evaluateLater, el, value)
|
|
263
|
+
set: create_setter(evaluateLater, el, value)
|
|
259
264
|
};
|
|
260
265
|
|
|
261
266
|
switch (modifier) {
|
|
@@ -293,14 +298,14 @@
|
|
|
293
298
|
|
|
294
299
|
|
|
295
300
|
|
|
296
|
-
|
|
301
|
+
setTimeout(() => {
|
|
297
302
|
|
|
298
303
|
|
|
299
304
|
is_nullish(get_value()) && update_variable();
|
|
300
305
|
|
|
301
306
|
effect(() => apply_select_values(el, as_array(get_value() ?? [])));
|
|
302
307
|
cleanup(listen(el, "change", () => set_value(collect_selected_values(el))));
|
|
303
|
-
});
|
|
308
|
+
}, 0);
|
|
304
309
|
|
|
305
310
|
processed = true;
|
|
306
311
|
break;
|
|
@@ -315,6 +320,14 @@
|
|
|
315
320
|
}
|
|
316
321
|
}
|
|
317
322
|
|
|
323
|
+
function process_indeterminate() {
|
|
324
|
+
if (el.type === "checkbox") {
|
|
325
|
+
is_nullish(get_value()) && update_variable();
|
|
326
|
+
effect(update_property);
|
|
327
|
+
processed = true;
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
|
|
318
331
|
function process_files() {
|
|
319
332
|
if (el.type === "file") {
|
|
320
333
|
cleanup(listen(el, "input", update_variable));
|
package/alpinegear-bound.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
!function(){"use strict";function e(e,...t){const n=e(...t);return()=>{let e;return n(
|
|
1
|
+
!function(){"use strict";function e(e,...t){const n=e(...t);return()=>{let e;return n(t=>e=t),t=e,"function"==typeof t?.get?e.get():e;var t}}function t(e,...t){const n=e(...t);t[t.length-1]=`${t.at(-1)} = __val`;const i=e(...t);return e=>{let t;n(e=>t=e),function(e){return"function"==typeof e?.set}(t)?t.set(e):i(()=>{},{scope:{__val:e}})}}const n=Symbol();let i;const a=(...e)=>console.warn("alpinegear.js:",...e),r=Array.isArray,o=e=>null==e,c=e=>"checkbox"===e.type||"radio"===e.type,s=e=>r(e)?e:[e],u=(e,t)=>e==t,l=(e,t)=>e.findIndex(e=>e==t),d=(e,t)=>e.includes(t),p=(e,t,n,i)=>(e.addEventListener(t,n,i),()=>e.removeEventListener(t,n,i)),f=e=>"object"==typeof e?JSON.parse(JSON.stringify(e)):e;function v(e,t,n=null){const{effect:i,release:a}=Alpine;let r,o,c=!1;const s=i(()=>{r=e(),c||(n?.deep&&JSON.stringify(r),o=r),(c||(n?.immediate??1))&&setTimeout(()=>{t(r,o),o=r},0),c=!0});return()=>a(s)}const h=new Map("value,checked,files,innerHTML,innerText,textContent,videoHeight,videoWidth,naturalHeight,naturalWidth,clientHeight,clientWidth,offsetHeight,offsetWidth,indeterminate,open,group".split(",").map(e=>[e.trim().toLowerCase(),e.trim()]));function g({directive:g,entangle:b,evaluateLater:m,mapAttributes:k,mutateDom:x,prefixed:y}){k(e=>({name:e.name.replace(/^&/,y("bound:")),value:e.value})),g("bound",(g,{expression:k,value:y,modifiers:E},{effect:T,cleanup:w})=>{if(!y)return void a("x-bound directive expects the presence of a bound property name");const H=g.tagName.toUpperCase();k=k?.trim();const L=h.get(y.trim().replace("-","").toLowerCase());k||=L;const _=e(m,g,k),S=t(m,g,k),A=()=>u(g[L],_())||x(()=>g[L]=_()),W=()=>S((e=>"number"===e.type||"range"===e.type)(g)?function(e){return""===e?null:+e}(g[L]):g[L]);let C;switch(L){case"value":!function(){switch(H){case"INPUT":case"TEXTAREA":o(_())&&W(),T(A),w(p(g,"input",W)),C=!0;break;case"SELECT":setTimeout(()=>{o(_())&&W(),T(()=>function(e,t){for(const n of e.options)n.selected=l(t,n.value)>=0}(g,s(_()??[]))),w(p(g,"change",()=>S(function(e){return e.multiple?[...e.selectedOptions].map(e=>e.value):e.value}(g))))},0),C=!0}}();break;case"checked":c(g)&&(T(A),w(p(g,"change",W)),C=!0);break;case"files":"file"===g.type&&(w(p(g,"input",W)),C=!0);break;case"innerHTML":case"innerText":case"textContent":"true"===g.contentEditable&&(o(_())&&W(),T(A),w(p(g,"input",W)),C=!0);break;case"videoHeight":case"videoWidth":N("VIDEO","resize");break;case"naturalHeight":case"naturalWidth":N("IMG","load");break;case"clientHeight":case"clientWidth":case"offsetHeight":case"offsetWidth":w(function(e,t){return i??=new ResizeObserver(e=>{for(const t of e)for(const e of t.target[n]?.values()??[])e(t)}),e[n]??=new Set,e[n].add(t),i.observe(e),()=>{e[n].delete(t),e[n].size||(i.unobserve(e),e[n]=null)}}(g,W)),C=!0;break;case"indeterminate":"checkbox"===g.type&&(o(_())&&W(),T(A),C=!0);break;case"open":"DETAILS"===H&&(o(_())&&W(),T(A),w(p(g,"toggle",W)),C=!0);break;case"group":c(g)&&(g.name||x(()=>g.name=k),T(()=>x(()=>function(e,t){e.checked=r(t)?l(t,e.value)>=0:u(e.value,t)}(g,_()??[]))),w(p(g,"input",()=>S(function(e,t){if("radio"===e.type)return e.value;t=s(t);const n=l(t,e.value);return e.checked?n>=0||t.push(e.value):n>=0&&t.splice(n,1),t}(g,_())))),C=!0)}if(!C){const n=d(E,"in")?"in":d(E,"out")?"out":"inout",i=k===y?((e,t)=>{for(;e&&!t(e);)e=(e._x_teleportBack??e).parentElement;return e})(g.parentNode,e=>e._x_dataStack):g;if(!g._x_dataStack)return void a("x-bound directive requires the presence of the x-data directive to bind component properties");if(!i)return void a(`x-bound directive cannot find the parent scope where the '${y}' property is defined`);const r={get:e(m,i,k),set:t(m,i,k)},o={get:e(m,g,y),set:t(m,g,y)};switch(n){case"in":w(v(()=>r.get(),e=>o.set(f(e))));break;case"out":w(v(()=>o.get(),e=>r.set(f(e))));break;default:w(b(r,o))}}function N(e,t){H===e&&(W(),w(p(g,t,W)),C=!0)}})}document.addEventListener("alpine:init",()=>{Alpine.plugin(g)})}();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ramstack/alpinegear-bound",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.2.0",
|
|
4
4
|
"description": "@ramstack/alpinegear-bound provides the 'x-bound' Alpine.js directive, which allows for two-way binding of input elements and their associated data properties.",
|
|
5
5
|
"author": "Rameel Burhan",
|
|
6
6
|
"license": "MIT",
|