@alpinejs/docs 3.6.1-revision.3 → 3.7.1-revision.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alpinejs/docs",
3
- "version": "3.6.1-revision.3",
3
+ "version": "3.7.1-revision.1",
4
4
  "description": "The documentation for Alpine",
5
5
  "author": "Caleb Porzio",
6
6
  "license": "MIT"
@@ -234,6 +234,14 @@ The above example is a great use case of throttling. Without `.throttle`, the `h
234
234
 
235
235
  > Fun Fact: This exact strategy is used on this very documentation site to update the currently highlighted section in the right sidebar.
236
236
 
237
+ Just like with `.debounce`, you can add a custom duration to your throttled event:
238
+
239
+ ```alpine
240
+ <div @scroll.window.throttle.750ms="handleScroll">...</div>
241
+ ```
242
+
243
+ Now, `handleScroll` will only be called every 750 milliseconds.
244
+
237
245
  <a name="self"></a>
238
246
  ### .self
239
247
 
@@ -0,0 +1,159 @@
1
+ ---
2
+ order: 12
3
+ title: teleport
4
+ description: Send Alpine templates to other parts of the DOM
5
+ graph_image: https://alpinejs.dev/social_teleport.jpg
6
+ ---
7
+
8
+ # x-teleport
9
+
10
+ The `x-teleport` directive allows you to transport part of your Alpine template to another part of the DOM on the page entirely.
11
+
12
+ This is useful for things like modals (especially nesting them), where it's helpful to break out of the z-index of the current Alpine component.
13
+
14
+ > Warning: if you are a [Livewire](https://laravel-livewire.com) user, this functionality does not currently work inside Livewire components. Support for this is on the roadmap.
15
+
16
+ <a name="x-teleport"></a>
17
+ ## x-teleport
18
+
19
+ By attaching `x-teleport` to a `<template>` element, you are telling Alpine to "append" that element to the provided selector.
20
+
21
+ > The `x-template` selector can be any string you would normally pass into something like `document.querySelector`. It will find the first element that matches, be it a tag name (`body`), class name (`.my-class`), ID (`#my-id`), or any other valid CSS selector.
22
+
23
+ [→ Read more about `document.querySelector`](https://developer.mozilla.org/en-US/docs/Web/API/Document/querySelector)
24
+
25
+ Here's a contrived modal example:
26
+
27
+ ```alpine
28
+ <body>
29
+ <div x-data="{ open: false }">
30
+ <button @click="open = ! open">Toggle Modal</button>
31
+
32
+ <template x-teleport="body">
33
+ <div x-show="open">
34
+ Modal contents...
35
+ </div>
36
+ </template>
37
+ </div>
38
+
39
+ <div>Some other content placed AFTER the modal markup.</div>
40
+
41
+ ...
42
+
43
+ </body>
44
+ ```
45
+
46
+ <!-- START_VERBATIM -->
47
+ <div class="demo" x-ref="root" id="modal2">
48
+ <div x-data="{ open: false }">
49
+ <button @click="open = ! open">Toggle Modal</button>
50
+
51
+ <template x-teleport="#modal2">
52
+ <div x-show="open">
53
+ Modal contents...
54
+ </div>
55
+ </template>
56
+
57
+ </div>
58
+
59
+ <div class="py-4">Some other content...</div>
60
+ </div>
61
+ <!-- END_VERBATIM -->
62
+
63
+ Notice how when toggling the modal, the actual modal contents show up AFTER the "Some other content..." element? This is because when Alpine is initializing, it sees `x-teleport="body"` and appends and initializes that element to the provided element selector.
64
+
65
+ <a name="forwarding-events"></a>
66
+ ## Forwarding events
67
+
68
+ Alpine tries its best to make the experience of teleporting seamless. Anything you would normally do in a template, you should be able to do inside an `x-teleport` template. Teleported content can access the normal Alpine scope of the component as well as other features like `$refs`, `$root`, etc...
69
+
70
+ However, native DOM events have no concept of teleportation, so if, for example, you trigger a "click" event from inside a teleported element, that event will bubble up the DOM tree as it normally would.
71
+
72
+ To make this experience more seamless, you can "forward" events by simply registering event listeners on the `<template x-teleport...>` element itself like so:
73
+
74
+ ```alpine
75
+ <div x-data="{ open: false }">
76
+ <button @click="open = ! open">Toggle Modal</button>
77
+
78
+ <template x-teleport="body" @click="open = false">
79
+ <div x-show="open">
80
+ Modal contents...
81
+ (click to close)
82
+ </div>
83
+ </template>
84
+ </div>
85
+ ```
86
+
87
+ <!-- START_VERBATIM -->
88
+ <div class="demo" x-ref="root" id="modal3">
89
+ <div x-data="{ open: false }">
90
+ <button @click="open = ! open">Toggle Modal</button>
91
+
92
+ <template x-teleport="#modal3" @click="open = false">
93
+ <div x-show="open">
94
+ Modal contents...
95
+ <div>(click to close)</div>
96
+ </div>
97
+ </template>
98
+ </div>
99
+ </div>
100
+ <!-- END_VERBATIM -->
101
+
102
+ Notice how we are now able to listen for events dispatched from within the teleported element from outside the `<template>` element itself?
103
+
104
+ Alpine does this by looking for event listeners registered on `<template x-teleport...>` and stops those events from propogating past the live, teleported, DOM element. Then, it creates a copy of that event and re-dispatches it from `<template x-teleport...>`.
105
+
106
+ <a name="nesting"></a>
107
+ ## Nesting
108
+
109
+ Teleporting is especially helpful if you are trying to nest one modal within another. Alpine makes it simple to do so:
110
+
111
+ ```alpine
112
+ <div x-data="{ open: false }">
113
+ <button @click="open = ! open">Toggle Modal</button>
114
+
115
+ <template x-teleport="body">
116
+ <div x-show="open">
117
+ Modal contents...
118
+
119
+ <div x-data="{ open: false }">
120
+ <button @click="open = ! open">Toggle Nested Modal</button>
121
+
122
+ <template x-teleport="body">
123
+ <div x-show="open">
124
+ Nested modal contents...
125
+ </div>
126
+ </template>
127
+ </div>
128
+ </div>
129
+ </template>
130
+ </div>
131
+ ```
132
+
133
+ <!-- START_VERBATIM -->
134
+ <div class="demo" x-ref="root" id="modal4">
135
+ <div x-data="{ open: false }">
136
+ <button @click="open = ! open">Toggle Modal</button>
137
+
138
+ <template x-teleport="#modal4">
139
+ <div x-show="open">
140
+ <div class="py-4">Modal contents...</div>
141
+
142
+ <div x-data="{ open: false }">
143
+ <button @click="open = ! open">Toggle Nested Modal</button>
144
+
145
+ <template x-teleport="#modal4">
146
+ <div class="pt-4" x-show="open">
147
+ Nested modal contents...
148
+ </div>
149
+ </template>
150
+ </div>
151
+ </div>
152
+ </template>
153
+ </div>
154
+
155
+ <template x-teleport-target="modals3"></template>
156
+ </div>
157
+ <!-- END_VERBATIM -->
158
+
159
+ After toggling "on" both modals, they are authored as children, but will be rendered as sibling elements on the page, not within one another.
@@ -138,11 +138,11 @@ For direct control over exactly what goes into your transitions, you can apply C
138
138
  <div
139
139
  x-show="open"
140
140
  x-transition:enter="transition ease-out duration-300"
141
- x-transition:enter-start="opacity-0 transform scale-90"
142
- x-transition:enter-end="opacity-100 transform scale-100"
141
+ x-transition:enter-start="opacity-0 scale-90"
142
+ x-transition:enter-end="opacity-100 scale-100"
143
143
  x-transition:leave="transition ease-in duration-300"
144
- x-transition:leave-start="opacity-100 transform scale-100"
145
- x-transition:leave-end="opacity-0 transform scale-90"
144
+ x-transition:leave-start="opacity-100 scale-100"
145
+ x-transition:leave-end="opacity-0 scale-90"
146
146
  >Hello 👋</div>
147
147
  </div>
148
148
  ```
@@ -33,7 +33,7 @@ This is by far the simplest way to get started with Alpine. Include the followin
33
33
  Notice the `@3.x.x` in the provided CDN link. This will pull the latest version of Alpine version 3. For stability in production, it's recommended that you hardcode the latest version in the CDN link.
34
34
 
35
35
  ```alpine
36
- <script defer src="https://unpkg.com/alpinejs@3.6.1/dist/cdn.min.js"></script>
36
+ <script defer src="https://unpkg.com/alpinejs@3.7.1/dist/cdn.min.js"></script>
37
37
  ```
38
38
 
39
39
  That's it! Alpine is now available for use inside your page.
@@ -35,3 +35,25 @@ When the `<button>` is pressed, `foo.bar` will be set to "bob", and "bob" will b
35
35
  <button @click="open = ! open">Toggle Open</button>
36
36
  </div>
37
37
  ```
38
+
39
+ <a name="deep-watching"></a>
40
+ ### Deep watching
41
+
42
+ `$watch` will automatically watches from changes at any level but you should keep in mind that, when a change is detected, the watcher will return the value of the observed property, not the value of the subproperty that has changed.
43
+
44
+ ```alpine
45
+ <div x-data="{ foo: { bar: 'baz' }}" x-init="$watch('foo', (value, oldValue) => console.log(value, oldValue))">
46
+ <button @click="foo.bar = 'bob'">Update</button>
47
+ </div>
48
+ ```
49
+
50
+ When the `<button>` is pressed, `foo.bar` will be set to "bob", and "{bar: 'bob'} {bar: 'baz'}" will be logged to the console (new and old value).
51
+
52
+ > ⚠️ Changing a property of a "watched" object as a side effect of the `$watch` callback will generate an infinite loop and eventually error.
53
+
54
+ ```alpine
55
+ <!-- 🚫 Infinite loop -->
56
+ <div x-data="{ foo: { bar: 'baz', bob: 'lob' }}" x-init="$watch('foo', value => foo.bob = foo.bar">
57
+ <button @click="foo.bar = 'bob'">Update</button>
58
+ </div>
59
+ ```
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  order: 3
3
3
  title: Trap
4
- description: Easily trap page focus within an element (modals, dialogues, etc...)
4
+ description: Easily trap page focus within an element (modals, dialogs, etc...)
5
5
  graph_image: https://alpinejs.dev/social_trap.jpg
6
6
  ---
7
7
 
@@ -9,7 +9,7 @@ graph_image: https://alpinejs.dev/social_trap.jpg
9
9
 
10
10
  Alpine's Trap plugin allows you to conditionally trap focus inside an element.
11
11
 
12
- This is useful for modals and other dialogue elements.
12
+ This is useful for modals and other dialog elements.
13
13
 
14
14
  <a name="installation"></a>
15
15
  ## Installation
@@ -58,7 +58,7 @@ For example:
58
58
 
59
59
  ```alpine
60
60
  <div x-data="{ open: false }">
61
- <button @click="open = true">Open Dialogue</button>
61
+ <button @click="open = true">Open Dialog</button>
62
62
 
63
63
  <span x-show="open" x-trap="open">
64
64
  <p>...</p>
@@ -67,7 +67,7 @@ For example:
67
67
 
68
68
  <input type="text" placeholder="Some other input...">
69
69
 
70
- <button @click="open = false">Close Dialogue</button>
70
+ <button @click="open = false">Close Dialog</button>
71
71
  </span>
72
72
  </div>
73
73
  ```
@@ -75,12 +75,12 @@ For example:
75
75
  <!-- START_VERBATIM -->
76
76
  <div x-data="{ open: false }" class="demo">
77
77
  <div :class="open && 'opacity-50'">
78
- <button x-on:click="open = true">Open Dialogue</button>
78
+ <button x-on:click="open = true">Open Dialog</button>
79
79
  </div>
80
80
 
81
81
  <div x-show="open" x-trap="open" class="mt-4 space-y-4 p-4 border bg-yellow-100" @keyup.escape.window="open = false">
82
82
  <strong>
83
- <div>Focus is now "trapped" inside this dialogue, meaning you can only click/focus elements within this yellow dialogue. If you press tab repeatedly, the focus will stay within this dialogue, but also be allowed to cycle to the browser's URL bar.</div>
83
+ <div>Focus is now "trapped" inside this dialog, meaning you can only click/focus elements within this yellow dialog. If you press tab repeatedly, the focus will stay within this dialog.</div>
84
84
  </strong>
85
85
 
86
86
  <div>
@@ -92,16 +92,16 @@ For example:
92
92
  </div>
93
93
 
94
94
  <div>
95
- <button @click="open = false">Close Dialogue</button>
95
+ <button @click="open = false">Close Dialog</button>
96
96
  </div>
97
97
  </div>
98
98
  </div>
99
99
  <!-- END_VERBATIM -->
100
100
 
101
101
  <a name="nesting"></a>
102
- ## Nesting dialogues
102
+ ## Nesting dialogs
103
103
 
104
- Sometimes you may want to nest one dialogue inside another. `x-trap` makes this trivial and handles it automatically.
104
+ Sometimes you may want to nest one dialog inside another. `x-trap` makes this trivial and handles it automatically.
105
105
 
106
106
  `x-trap` keeps track of newly "trapped" elements and stores the last actively focused element. Once the element is "untrapped" then the focus will be returned to where it was originally.
107
107
 
@@ -111,24 +111,24 @@ Here is nesting in action:
111
111
 
112
112
  ```alpine
113
113
  <div x-data="{ open: false }">
114
- <button @click="open = true">Open Dialogue</button>
114
+ <button @click="open = true">Open Dialog</button>
115
115
 
116
116
  <span x-show="open" x-trap="open">
117
117
 
118
118
  ...
119
119
 
120
120
  <div x-data="{ open: false }">
121
- <button @click="open = true">Open Nested Dialogue</button>
121
+ <button @click="open = true">Open Nested Dialog</button>
122
122
 
123
123
  <span x-show="open" x-trap="open">
124
124
 
125
125
  ...
126
126
 
127
- <button @click="open = false">Close Nested Dialogue</button>
127
+ <button @click="open = false">Close Nested Dialog</button>
128
128
  </span>
129
129
  </div>
130
130
 
131
- <button @click="open = false">Close Dialogue</button>
131
+ <button @click="open = false">Close Dialog</button>
132
132
  </span>
133
133
  </div>
134
134
  ```
@@ -136,7 +136,7 @@ Here is nesting in action:
136
136
  <!-- START_VERBATIM -->
137
137
  <div x-data="{ open: false }" class="demo">
138
138
  <div :class="open && 'opacity-50'">
139
- <button x-on:click="open = true">Open Dialogue</button>
139
+ <button x-on:click="open = true">Open Dialog</button>
140
140
  </div>
141
141
 
142
142
  <div x-show="open" x-trap="open" class="mt-4 space-y-4 p-4 border bg-yellow-100" @keyup.escape.window="open = false">
@@ -150,12 +150,12 @@ Here is nesting in action:
150
150
 
151
151
  <div x-data="{ open: false }">
152
152
  <div :class="open && 'opacity-50'">
153
- <button x-on:click="open = true">Open Nested Dialogue</button>
153
+ <button x-on:click="open = true">Open Nested Dialog</button>
154
154
  </div>
155
155
 
156
156
  <div x-show="open" x-trap="open" class="mt-4 space-y-4 p-4 border border-gray-500 bg-yellow-200" @keyup.escape.window="open = false">
157
157
  <strong>
158
- <div>Focus is now "trapped" inside this nested dialogue. You cannot focus anything inside the outer dialogue while this is open. If you close this dialogue, focus will be returned to the last known active element.</div>
158
+ <div>Focus is now "trapped" inside this nested dialog. You cannot focus anything inside the outer dialog while this is open. If you close this dialog, focus will be returned to the last known active element.</div>
159
159
  </strong>
160
160
 
161
161
  <div>
@@ -167,13 +167,13 @@ Here is nesting in action:
167
167
  </div>
168
168
 
169
169
  <div>
170
- <button @click="open = false">Close Nested Dialogue</button>
170
+ <button @click="open = false">Close Nested Dialog</button>
171
171
  </div>
172
172
  </div>
173
173
  </div>
174
174
 
175
175
  <div>
176
- <button @click="open = false">Close Dialogue</button>
176
+ <button @click="open = false">Close Dialog</button>
177
177
  </div>
178
178
  </div>
179
179
  </div>
@@ -88,7 +88,7 @@ You can listen for other events as you'd imagine. For example, listening for a `
88
88
 
89
89
  When a `click` event happens, Alpine will call the associated JavaScript expression, `count++` in our case. As you can see, we have direct access to data declared in the `x-data` expression.
90
90
 
91
- > You will often see `@` instead of `x-on`. This is a shorter, friendlier syntax that many prefer. From now on, this documentation will likely use `@` instead of `x-on`.
91
+ > You will often see `@` instead of `x-on:`. This is a shorter, friendlier syntax that many prefer. From now on, this documentation will likely use `@` instead of `x-on:`.
92
92
 
93
93
  [→ Read more about `x-on`](/directives/on)
94
94
 
@@ -1,220 +0,0 @@
1
- ---
2
- order: 6
3
- title: Portal
4
- description: Send Alpine templates to other parts of the DOM
5
- graph_image: https://alpinejs.dev/social_portal.jpg
6
- ---
7
-
8
- # Portal Plugin
9
-
10
- Alpine's Portal plugin allows you to transport part of your Alpine template to another part of the DOM on the page entirely.
11
-
12
- This is useful for things like modals (especially nesting them), where it's helpful to break out of the z-index of the current Alpine component.
13
-
14
- > Note: this plugin is currently in beta while it is being tested in the public. Be warned that it may change before being officially released.
15
-
16
- <a name="installation"></a>
17
- ## Installation
18
-
19
- You can use this plugin by either including it from a `<script>` tag or installing it via NPM:
20
-
21
- ### Via CDN
22
-
23
- You can include the CDN build of this plugin as a `<script>` tag, just make sure to include it BEFORE Alpine's core JS file.
24
-
25
- ```alpine
26
- <!-- Alpine Plugins -->
27
- <script defer src="https://unpkg.com/@alpinejs/portal@3.6.1-beta.0/dist/cdn.min.js"></script>
28
-
29
- <!-- Alpine Core -->
30
- <script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js"></script>
31
- ```
32
-
33
- ### Via NPM
34
-
35
- You can install Portal from NPM for use inside your bundle like so:
36
-
37
- ```shell
38
- npm install @alpinejs/portal
39
- ```
40
-
41
- Then initialize it from your bundle:
42
-
43
- ```js
44
- import Alpine from 'alpinejs'
45
- import portal from '@alpinejs/portal'
46
-
47
- Alpine.plugin(portal)
48
-
49
- ...
50
- ```
51
-
52
- <a name="usage"></a>
53
- ## Usage
54
-
55
- Everytime you use a portal, you will need two different directives: `x-portal` and `x-portal-target`.
56
-
57
- By attaching `x-portal` to a `<template>` element, you are telling Alpine to send that DOM content to another template element that has a matching `x-portal-target` on it.
58
-
59
- Here's a contrived modal example using portals:
60
-
61
- ```alpine
62
- <div x-data="{ open: false }">
63
- <button @click="open = ! open">Toggle Modal</button>
64
-
65
- <template x-portal="modals">
66
- <div x-show="open">
67
- Modal contents...
68
- </div>
69
- </template>
70
-
71
- <div class="py-4">Some other content placed AFTER the modal markup.</div>
72
- </div>
73
-
74
- <template x-portal-target="modals"></template>
75
- ```
76
-
77
- <!-- START_VERBATIM -->
78
- <div class="demo" x-ref="root">
79
- <div x-data="{ open: false }">
80
- <button @click="open = ! open">Toggle Modal</button>
81
-
82
- <template x-portal="modals1">
83
- <div x-show="open">
84
- Modal contents...
85
- </div>
86
- </template>
87
-
88
- <div class="py-4">Some other content...</div>
89
- </div>
90
-
91
- <template x-portal-target="modals1"></template>
92
- </div>
93
- <!-- END_VERBATIM -->
94
-
95
- Notice how when toggling the modal, the actual modal contents show up AFTER the "Some other content..." element? This is because when Alpine is initializing, it sees `x-portal="modals"` and takes that markup out of the page waiting until it finds an element with `x-portal-target="modals"` to insert it into.
96
-
97
- <a name="forwarding-events"></a>
98
- ## Forwarding events
99
-
100
- Alpine tries it's best to make the experience of using portals seemless. Anything you would normally do in a template, you should be able to do inside a portal. Portal content can access the normal Alpine scope of the component as well as other features like `$refs`, `$root`, etc...
101
-
102
- However, native DOM events have no concept of portals, so if, for example, you trigger a "click" event from inside a portal, that event will bubble up the DOM tree as it normally would ignoring the fact that it is within a portal.
103
-
104
- To make this experience more seemless, you can "forward" events by simply registering event listeners on the portal's `<template>` element itself like so:
105
-
106
- ```alpine
107
- <div x-data="{ open: false }">
108
- <button @click="open = ! open">Toggle Modal</button>
109
-
110
- <template x-portal="modals" @click="open = false">
111
- <div x-show="open">
112
- Modal contents...
113
- (click to close)
114
- </div>
115
- </template>
116
- </div>
117
-
118
- <template x-portal-target="modals"></template>
119
- ```
120
-
121
- <!-- START_VERBATIM -->
122
- <div class="demo" x-ref="root">
123
- <div x-data="{ open: false }">
124
- <button @click="open = ! open">Toggle Modal</button>
125
-
126
- <template x-portal="modals2" @click="open = false">
127
- <div x-show="open">
128
- Modal contents...<br>
129
- (click to close)
130
- </div>
131
- </template>
132
- </div>
133
-
134
- <template x-portal-target="modals2"></template>
135
- </div>
136
- <!-- END_VERBATIM -->
137
-
138
- Notice how we are now able to listen for events dispatched from within the portal from outside the portal itself?
139
-
140
- Alpine does this by looking for event listeners registered on `<template x-portal...` and stops those events from propogating past the `<template x-portal-target...` element. Then it creates a copy of that event and re-dispatches it from `<template x-portal`.
141
-
142
- <a name="nesting-portals"></a>
143
- ## Nesting portals
144
-
145
- Portals are especially helpful if you are trying to nest one modal within another. Alpine makes it simple to do so:
146
-
147
- ```alpine
148
- <div x-data="{ open: false }">
149
- <button @click="open = ! open">Toggle Modal</button>
150
-
151
- <template x-portal="modals">
152
- <div x-show="open">
153
- Modal contents...
154
-
155
- <div x-data="{ open: false }">
156
- <button @click="open = ! open">Toggle Nested Modal</button>
157
-
158
- <template x-portal="modals">
159
- <div x-show="open">
160
- Nested modal contents...
161
- </div>
162
- </template>
163
- </div>
164
- </div>
165
- </template>
166
- </div>
167
-
168
- <template x-portal-target="modals"></template>
169
- ```
170
-
171
- <!-- START_VERBATIM -->
172
- <div class="demo" x-ref="root">
173
- <div x-data="{ open: false }">
174
- <button @click="open = ! open">Toggle Modal</button>
175
-
176
- <template x-portal="modals3">
177
- <div x-show="open">
178
- <div class="py-4">Modal contents...</div>
179
-
180
- <div x-data="{ open: false }">
181
- <button @click="open = ! open">Toggle Nested Modal</button>
182
-
183
- <template x-portal="modals3">
184
- <div class="pt-4" x-show="open">
185
- Nested modal contents...
186
- </div>
187
- </template>
188
- </div>
189
- </div>
190
- </template>
191
- </div>
192
-
193
- <template x-portal-target="modals3"></template>
194
- </div>
195
- <!-- END_VERBATIM -->
196
-
197
- After toggling "on" both modals, they are authored as children, but will be rendered as sibling elements on the page, not within one another.
198
-
199
- <a name="multiple-portals"></a>
200
- ## Handling multiple portals
201
-
202
- Suppose you have multiple modals on a page, but a single `<template x-portal-target="modal">` element.
203
-
204
- Alpine automatically appends extra elements with `x-portal="modals"` at the target. No need for any extra syntax:
205
-
206
- ```alpine
207
- <template x-portal="modals">
208
- ...
209
- </template>
210
-
211
- <template x-portal="modals">
212
- ...
213
- </template>
214
-
215
- ...
216
-
217
- <template x-portal-target="modals"></template>
218
- ```
219
-
220
- Now both of these modals will be rendered where `<template x-portal-target="modals">` lives.