@ramstack/alpinegear-bound 1.2.3 → 1.2.4
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 +145 -37
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -6,6 +6,10 @@
|
|
|
6
6
|
|
|
7
7
|
This directive allows for two-way binding between input elements and their associated data properties. It works similarly to the binding provided by [Svelte](https://svelte.dev/docs/element-directives#bind-property) and also supports synchronizing values between two `Alpine.js` data properties.
|
|
8
8
|
|
|
9
|
+
> [!Note]
|
|
10
|
+
> This package is part of the **[`@ramstack/alpinegear-main`](https://www.npmjs.com/package/@ramstack/alpinegear-main)** bundle.
|
|
11
|
+
> If you are using the main bundle, you don't need to install this package separately.
|
|
12
|
+
|
|
9
13
|
## Installation
|
|
10
14
|
|
|
11
15
|
### Using CDN
|
|
@@ -16,7 +20,7 @@ To include the CDN version of this plugin, add the following `<script>` tag befo
|
|
|
16
20
|
<script src="https://cdn.jsdelivr.net/npm/@ramstack/alpinegear-bound@1/alpinegear-bound.min.js" defer></script>
|
|
17
21
|
|
|
18
22
|
<!-- alpine.js -->
|
|
19
|
-
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3
|
|
23
|
+
<script src="https://cdn.jsdelivr.net/npm/alpinejs@3/dist/cdn.min.js" defer></script>
|
|
20
24
|
```
|
|
21
25
|
|
|
22
26
|
### Using NPM
|
|
@@ -44,12 +48,13 @@ Let's take the following example:
|
|
|
44
48
|
|
|
45
49
|
```html
|
|
46
50
|
<div x-data="{ name: '' }">
|
|
47
|
-
|
|
48
|
-
|
|
51
|
+
<input x-bound:value="name" />
|
|
52
|
+
Hello <span x-text="name"></span>!
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
<button @click="name = 'John'">Change Name</button>
|
|
51
55
|
</div>
|
|
52
56
|
```
|
|
57
|
+
🚀 [Live demo | Alpine.js x-bound: Basic usage](https://jsfiddle.net/rameel/8cw23y7o/)
|
|
53
58
|
|
|
54
59
|
In this example, we bind the `name` property to the `value` property of the `<input>` element. Since `x-bound` provides two-way binding, any changes to `name` will be reflected in the `<input>` element, as will occur when the `button` is clicked.
|
|
55
60
|
|
|
@@ -76,12 +81,16 @@ In this example, the repetition of the `value` in `x-bound:value="value"` is red
|
|
|
76
81
|
More examples:
|
|
77
82
|
|
|
78
83
|
```html
|
|
79
|
-
<div x-data="{ name: '', text: '', yes: true }">
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
84
|
+
<div x-data="{ name: '', text: '', yes: true, methods: [] }">
|
|
85
|
+
<input &value="name" />
|
|
86
|
+
<textarea &value="text"></textarea>
|
|
87
|
+
<input &checked="yes" type="checkbox" />
|
|
88
|
+
<select &value="methods">
|
|
89
|
+
...
|
|
90
|
+
</select>
|
|
83
91
|
</div>
|
|
84
92
|
```
|
|
93
|
+
🚀 [Live demo | Alpine.js x-bound: Shorthand Syntax](https://jsfiddle.net/rameel/9ys23n4z/)
|
|
85
94
|
|
|
86
95
|
### Binding Numeric Inputs
|
|
87
96
|
|
|
@@ -90,6 +99,7 @@ For `<input>` elements with `type="number"` and `type="range"`, values are autom
|
|
|
90
99
|
```html
|
|
91
100
|
<input &value="number" type="number" />
|
|
92
101
|
```
|
|
102
|
+
🚀 [Live demo | Alpine.js x-bound: Bind Numeric Inputs](https://jsfiddle.net/rameel/e160vsta/)
|
|
93
103
|
|
|
94
104
|
### Binding `<input type="file">`
|
|
95
105
|
|
|
@@ -98,46 +108,68 @@ For `<input>` elements with `type="file"`, the binding is applied to the `files`
|
|
|
98
108
|
```html
|
|
99
109
|
<input &files type="file" accept="image/jpeg" />
|
|
100
110
|
```
|
|
111
|
+
🚀 [Live demo | Alpine.js x-bound: Bind Files](https://jsfiddle.net/rameel/phy2zn0a/)
|
|
101
112
|
|
|
102
|
-
> [!NOTE]
|
|
103
|
-
> The `files` binding is one-way.
|
|
104
113
|
|
|
105
114
|
### Binding `<select>`
|
|
106
115
|
|
|
107
116
|
To bind the value of a `<select>` element, use the `value` property:
|
|
108
117
|
```html
|
|
109
|
-
<
|
|
110
|
-
<
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
</
|
|
118
|
+
<div x-data="{ fruit: '' }">
|
|
119
|
+
<select &value="fruit">
|
|
120
|
+
<option value="" disabled>Select...</option>
|
|
121
|
+
<option>Apple</option>
|
|
122
|
+
<option>Banana</option>
|
|
123
|
+
<option>Orange</option>
|
|
124
|
+
<option>Grape</option>
|
|
125
|
+
<option>Mango</option>
|
|
126
|
+
</select>
|
|
127
|
+
|
|
128
|
+
<p>
|
|
129
|
+
Fruit: <span x-text="fruit"></span>
|
|
130
|
+
</p>
|
|
131
|
+
</div>
|
|
114
132
|
```
|
|
133
|
+
🚀 [Live demo | Alpine.js x-bound: Binding select](https://jsfiddle.net/rameel/fs12bo5m/)
|
|
134
|
+
|
|
115
135
|
|
|
116
136
|
For a `<select multiple>` element, the data property is an array containing the values of the selected options.
|
|
117
137
|
|
|
118
138
|
```html
|
|
119
139
|
<div x-data="{ pets: ['goldfish', 'parrot'] }">
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
140
|
+
<select &value="pets" multiple>
|
|
141
|
+
<option value="cat">Cat</option>
|
|
142
|
+
<option value="goldfish">Goldfish</option>
|
|
143
|
+
<option value="parrot">Parrot</option>
|
|
144
|
+
<option value="spider">Spider</option>
|
|
145
|
+
</select>
|
|
146
|
+
|
|
147
|
+
Pets: <span x-text="pets"></span>
|
|
128
148
|
</div>
|
|
129
149
|
```
|
|
150
|
+
🚀 [Live demo | Alpine.js x-bound: Multiple select](https://jsfiddle.net/rameel/kq0xseo1/)
|
|
151
|
+
|
|
130
152
|
|
|
131
153
|
### Binding `<details>`
|
|
132
154
|
|
|
133
155
|
The directive also allows binding to the `open` property of `<details>` elements:
|
|
134
156
|
|
|
135
157
|
```html
|
|
136
|
-
<
|
|
158
|
+
<div x-data="{ open: true }">
|
|
159
|
+
<details &open>
|
|
137
160
|
<summary>Details</summary>
|
|
138
161
|
<p>Something small enough to escape casual notice.</p>
|
|
139
|
-
</details>
|
|
162
|
+
</details>
|
|
163
|
+
|
|
164
|
+
<p>
|
|
165
|
+
<label>
|
|
166
|
+
<input &checked="open" type="checkbox" />
|
|
167
|
+
Open / Close
|
|
168
|
+
</label>
|
|
169
|
+
</p>
|
|
170
|
+
</div>
|
|
140
171
|
```
|
|
172
|
+
🚀 [Live demo | Alpine.js x-bound: Binding details](https://jsfiddle.net/rameel/fw2bkLqv/)
|
|
141
173
|
|
|
142
174
|
### Binding `<img>` sizes
|
|
143
175
|
|
|
@@ -146,6 +178,7 @@ You can bind the `naturalWidth` and `naturalHeight` properties of an image after
|
|
|
146
178
|
```html
|
|
147
179
|
<img src="..." &naturalWidth="width" &naturalHeight="height" />
|
|
148
180
|
```
|
|
181
|
+
🚀 [Live demo | Alpine.js x-bound: Binding image sizes](https://jsfiddle.net/rameel/q4vb1d0w/)
|
|
149
182
|
|
|
150
183
|
> [!TIP]
|
|
151
184
|
> If you prefer using `kebab-case` for multi-word properties like `naturalWidth`, you can write it as `natural-width`. It will be automatically normalized internally:
|
|
@@ -164,6 +197,18 @@ You can bind the `naturalWidth` and `naturalHeight` properties of an image after
|
|
|
164
197
|
> The `naturalWidth` and `naturalHeight` properties are read-only and reflect the original image dimensions, available after the image has loaded.
|
|
165
198
|
|
|
166
199
|
|
|
200
|
+
### Binding `<video>` sizes
|
|
201
|
+
|
|
202
|
+
You can bind the `videoWidth` and `videoHeight` properties of a video after it loads:
|
|
203
|
+
|
|
204
|
+
```html
|
|
205
|
+
<video &videoWidth="width" &videoHeight="height">
|
|
206
|
+
<source src="..." type="video/mp4">
|
|
207
|
+
</video>
|
|
208
|
+
```
|
|
209
|
+
🚀 [Live demo | Alpine.js x-bound: Binding video sizes](https://jsfiddle.net/rameel/nah2pfcx/)
|
|
210
|
+
|
|
211
|
+
|
|
167
212
|
### Binding `contenteditable` elements
|
|
168
213
|
|
|
169
214
|
For `contenteditable` elements, you can bind the following properties:
|
|
@@ -172,12 +217,15 @@ For `contenteditable` elements, you can bind the following properties:
|
|
|
172
217
|
- [textContent](https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent)
|
|
173
218
|
|
|
174
219
|
```html
|
|
175
|
-
<div &
|
|
220
|
+
<div &innerHtml="html" contenteditable="true"></div>
|
|
176
221
|
```
|
|
222
|
+
🚀 [Live demo | Alpine.js x-bound: Contenteditable bindings](https://jsfiddle.net/rameel/n5sj0rdz/)
|
|
223
|
+
|
|
177
224
|
|
|
178
225
|
### Binding block-level element sizes
|
|
179
226
|
|
|
180
|
-
You can bind to the following properties to get the **width** and **height** of block-level elements
|
|
227
|
+
You can bind to the following properties to get the **width** and **height** of block-level elements,
|
|
228
|
+
measured with a `ResizeObserver`. The values will update whenever the element's size changes:
|
|
181
229
|
|
|
182
230
|
- [clientHeight](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientHeight)
|
|
183
231
|
- [clientWidth](https://developer.mozilla.org/en-US/docs/Web/API/Element/clientWidth)
|
|
@@ -187,36 +235,58 @@ You can bind to the following properties to get the **width** and **height** of
|
|
|
187
235
|
```html
|
|
188
236
|
<div &client-width="width" &client-height="height"></div>
|
|
189
237
|
```
|
|
238
|
+
🚀 [Live demo | Alpine.js x-bound: Binding element dimensions](https://jsfiddle.net/rameel/jc4eu921/)
|
|
190
239
|
|
|
191
240
|
> [!NOTE]
|
|
192
241
|
> These properties are read-only.
|
|
193
242
|
|
|
243
|
+
> [!IMPORTANT]
|
|
244
|
+
> Elements with `display: inline` don't have an explicit width or height (unless they are intrinsically sized, like `<img>` or `<canvas>`). Therefore, a `ResizeObserver` cannot track their size. If you need to observe their size, change their `display` style to something like `inline-block`.
|
|
245
|
+
>
|
|
246
|
+
> Also keep in mind that CSS transforms do not trigger `ResizeObserver` updates.
|
|
247
|
+
|
|
248
|
+
|
|
194
249
|
### Binding group of `<input type="radio">` and `<input type="checkbox">`
|
|
195
250
|
The group of `<input>` elements that should function together can utilize the `group` bound property.
|
|
196
251
|
|
|
197
252
|
```html
|
|
198
253
|
<div x-data="{ pets: ['goldfish', 'parrot'], contact: 'Email' }">
|
|
199
254
|
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
255
|
+
<!-- grouped checkboxes are similar to "select multiple"
|
|
256
|
+
and use an array for selected options -->
|
|
257
|
+
<input &group="pets" type="checkbox" value="cat" />
|
|
258
|
+
<input &group="pets" type="checkbox" value="goldfish" />
|
|
259
|
+
<input &group="pets" type="checkbox" value="parrot" />
|
|
260
|
+
<input &group="pets" type="checkbox" value="spider" />
|
|
206
261
|
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
262
|
+
<!-- grouped radio inputs are mutually exclusive -->
|
|
263
|
+
<input &group="contact" type="radio" value="Email" />
|
|
264
|
+
<input &group="contact" type="radio" value="Phone" />
|
|
265
|
+
<input &group="contact" type="radio" value="Mail" />
|
|
211
266
|
|
|
212
267
|
</div>
|
|
213
268
|
```
|
|
269
|
+
🚀 [Live demo | Alpine.js x-bound: Binding element dimensions](https://jsfiddle.net/rameel/f5jpry7b/)
|
|
270
|
+
|
|
214
271
|
|
|
215
272
|
### Binding `input[type="checkbox"]:indeterminate` property
|
|
216
273
|
The `x-bound` directive supports binding the `indeterminate` property of `<input type="checkbox">` elements,
|
|
217
274
|
allowing you to control the checkbox's indeterminate state (a state where the checkbox is neither checked nor unchecked,
|
|
218
275
|
typically represented visually with a dash or similar indicator).
|
|
219
276
|
|
|
277
|
+
```html
|
|
278
|
+
<div x-data="{ checked: false, indeterminate: true }">
|
|
279
|
+
<input type="checkbox" &checked &indeterminate />
|
|
280
|
+
|
|
281
|
+
<template x-match>
|
|
282
|
+
<span x-case="indeterminate">Waiting...</span>
|
|
283
|
+
<span x-case="checked">Checked</span>
|
|
284
|
+
<span x-default>Unchecked</span>
|
|
285
|
+
</template>
|
|
286
|
+
</div>
|
|
287
|
+
```
|
|
288
|
+
🚀 [Live demo | Alpine.js x-bound: Binding indeterminate](https://jsfiddle.net/rameel/o8ubzac0/)
|
|
289
|
+
|
|
220
290
|
This is useful for scenarios like selecting a subset of items in a list, such as in a table header checkbox:
|
|
221
291
|
```html
|
|
222
292
|
<table>
|
|
@@ -233,6 +303,8 @@ This is useful for scenarios like selecting a subset of items in a list, such as
|
|
|
233
303
|
...
|
|
234
304
|
</table>
|
|
235
305
|
```
|
|
306
|
+
🚀 [Live demo | Alpine.js x-bound: Binding indeterminate (table)](https://jsfiddle.net/rameel/ryvhw3jt/)
|
|
307
|
+
|
|
236
308
|
In this example, the `indeterminate` property of the checkbox is bound to the `isPartialSelected` data property.
|
|
237
309
|
When `isPartialSelected` is `true`, the checkbox will be in the indeterminate state.
|
|
238
310
|
|
|
@@ -252,6 +324,7 @@ The directive also supports synchronizing values between two data properties.
|
|
|
252
324
|
Number: <span x-text="number"></span>
|
|
253
325
|
</div>
|
|
254
326
|
```
|
|
327
|
+
🚀 [Live demo | Alpine.js x-bound: Binding data properties](https://jsfiddle.net/rameel/972qyomn/)
|
|
255
328
|
|
|
256
329
|
In this example, we bind the outer `number` property to the inner `count` property. Since `number` is initially set to `5`, the `count` property is also set to `5` when the binding occurs.
|
|
257
330
|
|
|
@@ -280,6 +353,41 @@ You can find the source code for this plugin on GitHub:
|
|
|
280
353
|
|
|
281
354
|
https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/bound
|
|
282
355
|
|
|
356
|
+
## Related projects
|
|
357
|
+
|
|
358
|
+
**[@ramstack/alpinegear-main](https://www.npmjs.com/package/@ramstack/alpinegear-main)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/main))<br>
|
|
359
|
+
Provides a combined plugin that includes several useful directives.
|
|
360
|
+
This package aggregates multiple individual plugins, offering a convenient all-in-one bundle.
|
|
361
|
+
Included directives: `x-bound`, `x-format`, `x-fragment`, `x-match`, `x-template`, and `x-when`.
|
|
362
|
+
|
|
363
|
+
**[@ramstack/alpinegear-format](https://www.npmjs.com/package/@ramstack/alpinegear-format)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/format))<br>
|
|
364
|
+
Provides the `x-format` directive, which allows you to easily interpolate text using a template syntax similar to what's available in `Vue.js`.
|
|
365
|
+
|
|
366
|
+
**[@ramstack/alpinegear-template](https://www.npmjs.com/package/@ramstack/alpinegear-template)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/template))<br>
|
|
367
|
+
Provides the `x-template` directive, which allows you to define a template once anywhere in the DOM and reference it by its ID.
|
|
368
|
+
|
|
369
|
+
**[@ramstack/alpinegear-fragment](https://www.npmjs.com/package/@ramstack/alpinegear-fragment)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/fragment))<br>
|
|
370
|
+
Provides the `x-fragment` directive, which allows for fragment-like behavior similar to what's available in frameworks
|
|
371
|
+
like `Vue.js` or `React`, where multiple root elements can be grouped together.
|
|
372
|
+
|
|
373
|
+
**[@ramstack/alpinegear-match](https://www.npmjs.com/package/@ramstack/alpinegear-match)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/match))<br>
|
|
374
|
+
Provides the `x-match` directive, which functions similarly to the `switch` statement in many programming languages,
|
|
375
|
+
allowing you to conditionally render elements based on matching cases.
|
|
376
|
+
|
|
377
|
+
**[@ramstack/alpinegear-when](https://www.npmjs.com/package/@ramstack/alpinegear-when)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/when))<br>
|
|
378
|
+
Provides the `x-when` directive, which allows for conditional rendering of elements similar to `x-if`, but supports multiple root elements.
|
|
379
|
+
|
|
380
|
+
**[@ramstack/alpinegear-destroy](https://www.npmjs.com/package/@ramstack/alpinegear-destroy)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/destroy))<br>
|
|
381
|
+
Provides the `x-destroy` directive, which is the opposite of `x-init` and allows you to hook into the cleanup phase
|
|
382
|
+
of any element, running a callback when the element is removed from the DOM.
|
|
383
|
+
|
|
384
|
+
**[@ramstack/alpinegear-hotkey](https://www.npmjs.com/package/@ramstack/alpinegear-hotkey)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/hotkey))<br>
|
|
385
|
+
Provides the `x-hotkey` directive, which allows you to easily handle keyboard shortcuts within your Alpine.js components or application.
|
|
386
|
+
|
|
387
|
+
**[@ramstack/alpinegear-router](https://www.npmjs.com/package/@ramstack/alpinegear-router)** ([README](https://github.com/rameel/ramstack.alpinegear.js/tree/main/src/plugins/router))<br>
|
|
388
|
+
Provides the `x-router` and `x-route` directives, which enable client-side navigation and routing functionality within your Alpine.js application.
|
|
389
|
+
|
|
390
|
+
|
|
283
391
|
## Contributions
|
|
284
392
|
Bug reports and contributions are welcome.
|
|
285
393
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ramstack/alpinegear-bound",
|
|
3
|
-
"version": "1.2.
|
|
3
|
+
"version": "1.2.4",
|
|
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",
|
|
@@ -11,7 +11,10 @@
|
|
|
11
11
|
},
|
|
12
12
|
"keywords": [
|
|
13
13
|
"alpine.js",
|
|
14
|
-
"alpinejs"
|
|
14
|
+
"alpinejs",
|
|
15
|
+
"alpinejs-binding",
|
|
16
|
+
"alpinejs-directive",
|
|
17
|
+
"alpinejs-plugin"
|
|
15
18
|
],
|
|
16
19
|
"main": "alpinegear-bound.js",
|
|
17
20
|
"module": "alpinegear-bound.esm.js"
|