offline docs
This commit is contained in:
229
offline-docs/alpinejs/directives/bind.md
Normal file
229
offline-docs/alpinejs/directives/bind.md
Normal file
@@ -0,0 +1,229 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-bind](/directives/bind)
|
||||
|
||||
`x-bind` allows you to set HTML attributes on elements based on the result of JavaScript expressions.
|
||||
|
||||
For example, here's a component where we will use `x-bind` to set the placeholder value of an input.
|
||||
|
||||
```
|
||||
<div x-data="{ placeholder: 'Type here...' }">
|
||||
|
||||
|
||||
n<input type="text" x-bind:placeholder="placeholder">
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
### [Shorthand syntax](#shorthand-syntax)
|
||||
|
||||
If `x-bind:` is too verbose for your liking, you can use the shorthand: `:`. For example, here is the same input element as above, but refactored to use the shorthand syntax.
|
||||
|
||||
```
|
||||
<input type="text" :placeholder="placeholder">
|
||||
```
|
||||
|
||||
> Despite not being included in the above snippet, `x-bind` cannot be used if no parent element has `x-data` defined. [→ Read more about `x-data`](/directives/data)
|
||||
|
||||
### [Binding classes](#binding-classes)
|
||||
|
||||
`x-bind` is most often useful for setting specific classes on an element based on your Alpine state.
|
||||
|
||||
Here's a simple example of a simple dropdown toggle, but instead of using `x-show`, we'll use a "hidden" class to toggle an element.
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button x-on:click="open = ! open">Toggle Dropdown</button>
|
||||
|
||||
|
||||
n<div :class="open ? '' : 'hidden'">
|
||||
|
||||
|
||||
nDropdown Contents...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Now, when `open` is `false`, the "hidden" class will be added to the dropdown.
|
||||
|
||||
#### [Shorthand conditionals](#shorthand-conditionals)
|
||||
|
||||
In cases like these, if you prefer a less verbose syntax you can use JavaScript's short-circuit evaluation instead of standard conditionals:
|
||||
|
||||
```
|
||||
<div :class="show ? '' : 'hidden'">
|
||||
|
||||
|
||||
n<!-- Is equivalent to: -->
|
||||
|
||||
|
||||
n<div :class="show || 'hidden'">
|
||||
```
|
||||
|
||||
The inverse is also available to you. Suppose instead of `open`, we use a variable with the opposite value: `closed`.
|
||||
|
||||
```
|
||||
<div :class="closed ? 'hidden' : ''">
|
||||
|
||||
|
||||
n<!-- Is equivalent to: -->
|
||||
|
||||
|
||||
n<div :class="closed && 'hidden'">
|
||||
```
|
||||
|
||||
#### [Class object syntax](#class-object-syntax)
|
||||
|
||||
Alpine offers an additional syntax for toggling classes if you prefer. By passing a JavaScript object where the classes are the keys and booleans are the values, Alpine will know which classes to apply and which to remove. For example:
|
||||
|
||||
```
|
||||
<div :class="{ 'hidden': ! show }">
|
||||
```
|
||||
|
||||
This technique offers a unique advantage to other methods. When using object-syntax, Alpine will NOT preserve original classes applied to an element's `class` attribute.
|
||||
|
||||
For example, if you wanted to apply the "hidden" class to an element before Alpine loads, AND use Alpine to toggle its existence you can only achieve that behavior using object-syntax:
|
||||
|
||||
```
|
||||
<div class="hidden" :class="{ 'hidden': ! show }">
|
||||
```
|
||||
|
||||
In case that confused you, let's dig deeper into how Alpine handles `x-bind:class` differently than other attributes.
|
||||
|
||||
#### [Special behavior](#special-behavior)
|
||||
|
||||
`x-bind:class` behaves differently than other attributes under the hood.
|
||||
|
||||
Consider the following case.
|
||||
|
||||
```
|
||||
<div class="opacity-50" :class="hide && 'hidden'">
|
||||
```
|
||||
|
||||
If "class" were any other attribute, the `:class` binding would overwrite any existing class attribute, causing `opacity-50` to be overwritten by either `hidden` or `''`.
|
||||
|
||||
However, Alpine treats `class` bindings differently. It's smart enough to preserve existing classes on an element.
|
||||
|
||||
For example, if `hide` is true, the above example will result in the following DOM element:
|
||||
|
||||
```
|
||||
<div class="opacity-50 hidden">
|
||||
```
|
||||
|
||||
If `hide` is false, the DOM element will look like:
|
||||
|
||||
```
|
||||
<div class="opacity-50">
|
||||
```
|
||||
|
||||
This behavior should be invisible and intuitive to most users, but it is worth mentioning explicitly for the inquiring developer or any special cases that might crop up.
|
||||
|
||||
### [Binding styles](#binding-styles)
|
||||
|
||||
Similar to the special syntax for binding classes with JavaScript objects, Alpine also offers an object-based syntax for binding `style` attributes.
|
||||
|
||||
Just like the class objects, this syntax is entirely optional. Only use it if it affords you some advantage.
|
||||
|
||||
```
|
||||
<div :style="{ color: 'red', display: 'flex' }">
|
||||
|
||||
|
||||
n<!-- Will render: -->
|
||||
|
||||
|
||||
n<div style="color: red; display: flex;" ...>
|
||||
```
|
||||
|
||||
Conditional inline styling is possible using expressions just like with x-bind:class. Short circuit operators can be used here as well by using a styles object as the second operand.
|
||||
|
||||
```
|
||||
<div x-bind:style="true && { color: 'red' }">
|
||||
|
||||
|
||||
n<!-- Will render: -->
|
||||
|
||||
|
||||
n<div style="color: red;">
|
||||
```
|
||||
|
||||
One advantage of this approach is being able to mix it in with existing styles on an element:
|
||||
|
||||
```
|
||||
<div style="padding: 1rem;" :style="{ color: 'red', display: 'flex' }">
|
||||
|
||||
|
||||
n<!-- Will render: -->
|
||||
|
||||
|
||||
n<div style="padding: 1rem; color: red; display: flex;" ...>
|
||||
```
|
||||
|
||||
And like most expressions in Alpine, you can always use the result of a JavaScript expression as the reference:
|
||||
|
||||
```
|
||||
<div x-data="{ styles: { color: 'red', display: 'flex' }}">
|
||||
|
||||
|
||||
n<div :style="styles">
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n<!-- Will render: -->
|
||||
|
||||
|
||||
n<div ...>
|
||||
|
||||
|
||||
n<div style="color: red; display: flex;" ...>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
### [Binding Alpine Directives Directly](#bind-directives)
|
||||
|
||||
`x-bind` allows you to bind an object of directives to an element.
|
||||
|
||||
For example, you can use it to dynamically bind a directive like `@click`:
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button :@click="open = ! open">Toggle Dropdown</button>
|
||||
|
||||
|
||||
n<div x-show="open">
|
||||
|
||||
|
||||
nDropdown Contents...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
In this example, `:click` is bound to the `open` variable. When you click the button, it will toggle the value of `open`.
|
||||
|
||||
This feature can also be used with the shorthand syntax:
|
||||
|
||||
```
|
||||
<button :@click="open = ! open">Toggle Dropdown</button>
|
||||
```
|
||||
|
||||
[→ Read more about `x-on`](/directives/on)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
51
offline-docs/alpinejs/directives/cloak.md
Normal file
51
offline-docs/alpinejs/directives/cloak.md
Normal file
@@ -0,0 +1,51 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-cloak](/directives/cloak)
|
||||
|
||||
Sometimes, when you're using AlpineJS for a part of your template, there is a "blip" where you might see your uninitialized template after the page loads, but before Alpine loads.
|
||||
|
||||
`x-cloak` addresses this scenario by hiding the element it's attached to until Alpine is fully loaded on the page.
|
||||
|
||||
For `x-cloak` to work however, you must add the following CSS to the page.
|
||||
|
||||
```
|
||||
[x-cloak] { display: none !important; }
|
||||
```
|
||||
|
||||
The following example will hide the `<span>` tag until its `x-show` is specifically set to true, preventing any "blip" of the hidden element onto screen as Alpine loads.
|
||||
|
||||
```
|
||||
<span x-cloak x-show="false">This will not 'blip' onto screen at any point</span>
|
||||
```
|
||||
|
||||
`x-cloak` doesn't just work on elements hidden by `x-show` or `x-if`: it also ensures that elements containing data are hidden until the data is correctly set. The following example will hide the `<span>` tag until Alpine has set its text content to the `message` property.
|
||||
|
||||
```
|
||||
<span x-cloak x-text="message"></span>
|
||||
```
|
||||
|
||||
When Alpine loads on the page, it removes all `x-cloak` property from the element, which also removes the `display: none;` applied by CSS, therefore showing the element.
|
||||
|
||||
## Alternative to global syntax
|
||||
|
||||
If you'd like to achieve this same behavior, but avoid having to include a global style, you can use the following cool, but admittedly odd trick:
|
||||
|
||||
```
|
||||
<template x-if="true">
|
||||
|
||||
|
||||
n<span x-text="message"></span>
|
||||
|
||||
|
||||
n</template>
|
||||
```
|
||||
|
||||
This will achieve the same goal as `x-cloak` by just leveraging the way `x-if` works.
|
||||
|
||||
Because `<template>` elements are "hidden" in browsers by default, you won't see the `<span>` until Alpine has had a chance to render the `x-if="true"` and show it.
|
||||
|
||||
Again, this solution is not for everyone, but it's worth mentioning for special cases.
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
254
offline-docs/alpinejs/directives/data.md
Normal file
254
offline-docs/alpinejs/directives/data.md
Normal file
@@ -0,0 +1,254 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-data](/directives/data)
|
||||
|
||||
Everything in Alpine starts with the `x-data` directive.
|
||||
|
||||
`x-data` defines a chunk of HTML as an Alpine component and provides the reactive data for that component to reference.
|
||||
|
||||
Here's an example of a contrived dropdown component:
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button @click="open = ! open">Toggle Content</button>
|
||||
|
||||
|
||||
n<div x-show="open">
|
||||
|
||||
|
||||
nContent...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Don't worry about the other directives in this example (`@click` and `x-show`), we'll get to those in a bit. For now, let's focus on `x-data`.
|
||||
|
||||
### [Scope](#scope)
|
||||
|
||||
Properties defined in an `x-data` directive are available to all element children. Even ones inside other, nested `x-data` components.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
<div x-data="{ foo: 'bar' }">
|
||||
|
||||
|
||||
n<span x-text="foo"><!-- Will output: "bar" --></span>
|
||||
|
||||
|
||||
n<div x-data="{ bar: 'baz' }">
|
||||
|
||||
|
||||
n<span x-text="foo"><!-- Will output: "bar" --></span>
|
||||
|
||||
|
||||
n<div x-data="{ foo: 'bob' }">
|
||||
|
||||
|
||||
n<span x-text="foo"><!-- Will output: "bob" --></span>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
### [Methods](#methods)
|
||||
|
||||
Because `x-data` is evaluated as a normal JavaScript object, in addition to state, you can store methods and even getters.
|
||||
|
||||
For example, let's extract the "Toggle Content" behavior into a method on `x-data`.
|
||||
|
||||
```
|
||||
<div x-data="{ open: false, toggle() { this.open = ! this.open } }">
|
||||
|
||||
|
||||
n<button @click="toggle()">Toggle Content</button>
|
||||
|
||||
|
||||
n<div x-show="open">
|
||||
|
||||
|
||||
nContent...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Notice the added `toggle() { this.open = ! this.open }` method on `x-data`. This method can now be called from anywhere inside the component.
|
||||
|
||||
You'll also notice the usage of `this.` to access state on the object itself. This is because Alpine evaluates this data object like any standard JavaScript object with a `this` context.
|
||||
|
||||
If you prefer, you can leave the calling parenthesis off of the `toggle` method completely. For example:
|
||||
|
||||
```
|
||||
<!-- Before -->
|
||||
|
||||
|
||||
n<button @click="toggle()">...</button>
|
||||
|
||||
|
||||
n<!-- After -->
|
||||
|
||||
|
||||
n<button @click="toggle">...</button>
|
||||
```
|
||||
|
||||
### [Getters](#getters)
|
||||
|
||||
JavaScript [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get) are handy when the sole purpose of a method is to return data based on other state.
|
||||
|
||||
Think of them like "computed properties" (although, they are not cached like Vue's computed properties).
|
||||
|
||||
Let's refactor our component to use a getter called `isOpen` instead of accessing `open` directly.
|
||||
|
||||
```
|
||||
<div x-data="{
|
||||
|
||||
|
||||
nopen: false,
|
||||
|
||||
|
||||
nget isOpen() { return this.open },
|
||||
|
||||
|
||||
ntoggle() { this.open = ! this.open },
|
||||
|
||||
|
||||
n}">
|
||||
|
||||
|
||||
n<button @click="toggle()">Toggle Content</button>
|
||||
|
||||
|
||||
n<div x-show="isOpen">
|
||||
|
||||
|
||||
nContent...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Notice the "Content" now depends on the `isOpen` getter instead of the `open` property directly.
|
||||
|
||||
In this case there is no tangible benefit. But in some cases, getters are helpful for providing a more expressive syntax in your components.
|
||||
|
||||
### [Data-less components](#data-less-components)
|
||||
|
||||
Occasionally, you want to create an Alpine component, but you don't need any data.
|
||||
|
||||
In these cases, you can always pass in an empty object.
|
||||
|
||||
```
|
||||
<div x-data="{}">
|
||||
```
|
||||
|
||||
However, if you wish, you can also eliminate the attribute value entirely if it looks better to you.
|
||||
|
||||
```
|
||||
<div x-data>
|
||||
```
|
||||
|
||||
### [Single-element components](#single-element-components)
|
||||
|
||||
Sometimes you may only have a single element inside your Alpine component, like the following:
|
||||
|
||||
```
|
||||
<div x-data="{ open: true }">
|
||||
|
||||
|
||||
n<button @click="open = false" x-show="open">Hide Me</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
In these cases, you can declare `x-data` directly on that single element:
|
||||
|
||||
```
|
||||
<button x-data="{ open: true }" @click="open = false" x-show="open">
|
||||
|
||||
|
||||
nHide Me
|
||||
|
||||
|
||||
n</button>
|
||||
```
|
||||
|
||||
### [Re-usable Data](#re-usable-data)
|
||||
|
||||
If you find yourself duplicating the contents of `x-data`, or you find the inline syntax verbose, you can extract the `x-data` object out to a dedicated component using `Alpine.data`.
|
||||
|
||||
Here's a quick example:
|
||||
|
||||
```
|
||||
<div x-data="dropdown">
|
||||
|
||||
|
||||
n<button @click="toggle">Toggle Content</button>
|
||||
|
||||
|
||||
n<div x-show="open">
|
||||
|
||||
|
||||
nContent...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n<script>
|
||||
|
||||
|
||||
ndocument.addEventListener('alpine:init', () => {
|
||||
|
||||
|
||||
nAlpine.data('dropdown', () => ({
|
||||
|
||||
|
||||
nopen: false,
|
||||
|
||||
|
||||
ntoggle() {
|
||||
|
||||
|
||||
nthis.open = ! this.open
|
||||
|
||||
|
||||
n},
|
||||
|
||||
|
||||
n}))
|
||||
|
||||
|
||||
n})
|
||||
|
||||
|
||||
n</script>
|
||||
```
|
||||
|
||||
[→ Read more about `Alpine.data(...)`](/globals/alpine-data)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
25
offline-docs/alpinejs/directives/effect.md
Normal file
25
offline-docs/alpinejs/directives/effect.md
Normal file
@@ -0,0 +1,25 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-effect](/directives/effect)
|
||||
|
||||
`x-effect` is a useful directive for re-evaluating an expression when one of its dependencies change. You can think of it as a watcher where you don't have to specify what property to watch, it will watch all properties used within it.
|
||||
|
||||
If this definition is confusing for you, that's ok. It's better explained through an example:
|
||||
|
||||
```
|
||||
<div x-data="{ label: 'Hello' }" x-effect="console.log(label)">
|
||||
|
||||
|
||||
n<button @click="label += ' World!'">Change Message</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
When this component is loaded, the `x-effect` expression will be run and "Hello" will be logged into the console.
|
||||
|
||||
Because Alpine knows about any property references contained within `x-effect`, when the button is clicked and `label` is changed, the effect will be re-triggered and "Hello World!" will be logged to the console.
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
181
offline-docs/alpinejs/directives/for.md
Normal file
181
offline-docs/alpinejs/directives/for.md
Normal file
@@ -0,0 +1,181 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-for](/directives/for)
|
||||
|
||||
Alpine's `x-for` directive allows you to create DOM elements by iterating through a list. Here's a simple example of using it to create a list of colors based on an array.
|
||||
|
||||
```
|
||||
<ul x-data="{ colors: ['Red', 'Orange', 'Yellow'] }">
|
||||
|
||||
|
||||
n<template x-for="color in colors">
|
||||
|
||||
|
||||
n<li x-text="color"></li>
|
||||
|
||||
|
||||
n</template>
|
||||
|
||||
|
||||
n</ul>
|
||||
```
|
||||
|
||||
You may also pass objects to `x-for`.
|
||||
|
||||
```
|
||||
<ul x-data="{ car: { make: 'Jeep', model: 'Grand Cherokee', color: 'Black' } }">
|
||||
|
||||
|
||||
n<template x-for="(value, index) in car">
|
||||
|
||||
|
||||
n<li>
|
||||
|
||||
|
||||
n<span x-text="index"></span>: <span x-text="value"></span>
|
||||
|
||||
|
||||
n</li>
|
||||
|
||||
|
||||
n</template>
|
||||
|
||||
|
||||
n</ul>
|
||||
```
|
||||
|
||||
There are two rules worth noting about `x-for`:
|
||||
|
||||
> `x-for` MUST be declared on a `<template>` element.
|
||||
> That `<template>` element MUST contain only one root element
|
||||
|
||||
### [Keys](#keys)
|
||||
|
||||
It is important to specify unique keys for each `x-for` iteration if you are going to be re-ordering items. Without dynamic keys, Alpine may have a hard time keeping track of what re-orders and will cause odd side-effects.
|
||||
|
||||
```
|
||||
<ul x-data="{ colors: [
|
||||
|
||||
|
||||
n{ id: 1, label: 'Red' },
|
||||
|
||||
|
||||
n{ id: 2, label: 'Orange' },
|
||||
|
||||
|
||||
n{ id: 3, label: 'Yellow' },
|
||||
|
||||
|
||||
n]}">
|
||||
|
||||
|
||||
n<template x-for="color in colors" :key="color.id">
|
||||
|
||||
|
||||
n<li x-text="color.label"></li>
|
||||
|
||||
|
||||
n</template>
|
||||
|
||||
|
||||
n</ul>
|
||||
```
|
||||
|
||||
Now if the colors are added, removed, re-ordered, or their "id"s change, Alpine will preserve or destroy the iterated `<li>`elements accordingly.
|
||||
|
||||
### [Accessing indexes](#accessing-indexes)
|
||||
|
||||
If you need to access the index of each item in the iteration, you can do so using the `([item], [index]) in [items]` syntax like so:
|
||||
|
||||
```
|
||||
<ul x-data="{ colors: ['Red', 'Orange', 'Yellow'] }">
|
||||
|
||||
|
||||
n<template x-for="(color, index) in colors">
|
||||
|
||||
|
||||
n<li>
|
||||
|
||||
|
||||
n<span x-text="index + ': '"></span>
|
||||
|
||||
|
||||
n<span x-text="color"></span>
|
||||
|
||||
|
||||
n</li>
|
||||
|
||||
|
||||
n</template>
|
||||
|
||||
|
||||
n</ul>
|
||||
```
|
||||
|
||||
You can also access the index inside a dynamic `:key` expression.
|
||||
|
||||
```
|
||||
<template x-for="(color, index) in colors" :key="index">
|
||||
```
|
||||
|
||||
### [Iterating over a range](#iterating-over-a-range)
|
||||
|
||||
If you need to simply loop `n` number of times, rather than iterate through an array, Alpine offers a short syntax.
|
||||
|
||||
```
|
||||
<ul>
|
||||
|
||||
|
||||
n<template x-for="i in 10">
|
||||
|
||||
|
||||
n<li x-text="i"></li>
|
||||
|
||||
|
||||
n</template>
|
||||
|
||||
|
||||
n</ul>
|
||||
```
|
||||
|
||||
`i` in this case can be named anything you like.
|
||||
|
||||
> Despite not being included in the above snippet, `x-for` cannot be used if no parent element has `x-data` defined. [→ Read more about `x-data`](/directives/data)
|
||||
|
||||
### [Contents of a `<template>`](#contents-of-a-template)
|
||||
|
||||
As mentioned above, an `<template>` tag must contain only one root element.
|
||||
|
||||
For example, the following code will not work:
|
||||
|
||||
```
|
||||
<template x-for="color in colors">
|
||||
|
||||
|
||||
n<span>The next color is </span><span x-text="color">
|
||||
|
||||
|
||||
n</template>
|
||||
```
|
||||
|
||||
but this code will work:
|
||||
|
||||
```
|
||||
<template x-for="color in colors">
|
||||
|
||||
|
||||
n<p>
|
||||
|
||||
|
||||
n<span>The next color is </span><span x-text="color">
|
||||
|
||||
|
||||
n</p>
|
||||
|
||||
|
||||
n</template>
|
||||
```
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
28
offline-docs/alpinejs/directives/html.md
Normal file
28
offline-docs/alpinejs/directives/html.md
Normal file
@@ -0,0 +1,28 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-html](/directives/html)
|
||||
|
||||
`x-html` sets the "innerHTML" property of an element to the result of a given expression.
|
||||
|
||||
> ⚠️ Only use on trusted content and never on user-provided content. ⚠️
|
||||
> Dynamically rendering HTML from third parties can easily lead to XSS vulnerabilities.
|
||||
|
||||
Here's a basic example of using `x-html` to display a user's username.
|
||||
|
||||
```
|
||||
<div x-data="{ username: '<strong>calebporzio</strong>' }">
|
||||
|
||||
|
||||
nUsername: <span x-html="username"></span>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Username:
|
||||
|
||||
Now the `<span>` tag's inner HTML will be set to "**calebporzio**".
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
29
offline-docs/alpinejs/directives/if.md
Normal file
29
offline-docs/alpinejs/directives/if.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-if](/directives/if)
|
||||
|
||||
`x-if` is used for toggling elements on the page, similarly to `x-show`, however it completely adds and removes the element it's applied to rather than just changing its CSS display property to "none".
|
||||
|
||||
Because of this difference in behavior, `x-if` should not be applied directly to the element, but instead to a `<template>` tag that encloses the element. This way, Alpine can keep a record of the element once it's removed from the page.
|
||||
|
||||
```
|
||||
<template x-if="open">
|
||||
|
||||
|
||||
n<div>Contents...</div>
|
||||
|
||||
|
||||
n</template>
|
||||
```
|
||||
|
||||
> Despite not being included in the above snippet, `x-if` cannot be used if no parent element has `x-data` defined. [→ Read more about `x-data`](/directives/data)
|
||||
|
||||
## Caveats
|
||||
|
||||
Unlike `x-show`, `x-if`, does NOT support transitioning toggles with `x-transition`.
|
||||
|
||||
`<template>` tags can only contain one root element.
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
29
offline-docs/alpinejs/directives/ignore.md
Normal file
29
offline-docs/alpinejs/directives/ignore.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-ignore](/directives/ignore)
|
||||
|
||||
By default, Alpine will crawl and initialize the entire DOM tree of an element containing `x-init` or `x-data`.
|
||||
|
||||
If for some reason, you don't want Alpine to touch a specific section of your HTML, you can prevent it from doing so using `x-ignore`.
|
||||
|
||||
```
|
||||
<div x-data="{ label: 'From Alpine' }">
|
||||
|
||||
|
||||
n<div x-ignore>
|
||||
|
||||
|
||||
n<span x-text="label"></span>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
In the above example, the `<span>` tag will not contain "From Alpine" because we told Alpine to ignore the contents of the `div` completely.
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
126
offline-docs/alpinejs/directives/init.md
Normal file
126
offline-docs/alpinejs/directives/init.md
Normal file
@@ -0,0 +1,126 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-init](/directives/init)
|
||||
|
||||
The `x-init` directive allows you to hook into the initialization phase of any element in Alpine.
|
||||
|
||||
```
|
||||
<div x-init="console.log('I\'m being initialized!')"></div>
|
||||
```
|
||||
|
||||
In the above example, "I'm being initialized!" will be output in the console before it makes further DOM updates.
|
||||
|
||||
Consider another example where `x-init` is used to fetch some JSON and store it in `x-data` before the component is processed.
|
||||
|
||||
```
|
||||
<div
|
||||
|
||||
x-data="{ posts: [] }"
|
||||
|
||||
x-init="posts = await (await fetch('/posts')).json()"
|
||||
|
||||
>...</div>
|
||||
```
|
||||
|
||||
### [$nextTick](#next-tick)
|
||||
|
||||
Sometimes, you want to wait until after Alpine has completely finished rendering to execute some code.
|
||||
|
||||
This would be something like `useEffect(..., [])` in react, or `mount` in Vue.
|
||||
|
||||
By using Alpine's internal `$nextTick` magic, you can make this happen.
|
||||
|
||||
```
|
||||
<div x-init="$nextTick(() => { ... })"></div>
|
||||
```
|
||||
|
||||
### [Standalone `x-init`](#standalone-x-init)
|
||||
|
||||
You can add `x-init` to any elements inside or outside an `x-data` HTML block. For example:
|
||||
|
||||
```
|
||||
<div x-data>
|
||||
|
||||
|
||||
n<span x-init="console.log('I can initialize')"></span>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n<span x-init="console.log('I can initialize too')"></span>
|
||||
```
|
||||
|
||||
### [Auto-evaluate init() method](#auto-evaluate-init-method)
|
||||
|
||||
If the `x-data` object of a component contains an `init()` method, it will be called automatically. For example:
|
||||
|
||||
```
|
||||
<div x-data="{"
|
||||
|
||||
|
||||
ninit() {
|
||||
|
||||
|
||||
nconsole.log('I am called automatically')
|
||||
|
||||
|
||||
n}
|
||||
|
||||
|
||||
n}"
|
||||
|
||||
>...
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
This is also the case for components that were registered using the `Alpine.data()` syntax.
|
||||
|
||||
```
|
||||
Alpine.data('dropdown', () => ({
|
||||
|
||||
|
||||
ninit() {
|
||||
|
||||
|
||||
nconsole.log('I will get evaluated when initializing each "dropdown" component.')
|
||||
|
||||
|
||||
n},
|
||||
|
||||
|
||||
n}))
|
||||
```
|
||||
|
||||
If you have both an `x-data` object containing an `init()` method and an `x-init` directive, the `x-data` method will be called before the directive.
|
||||
|
||||
```
|
||||
<div
|
||||
|
||||
x-data="{"
|
||||
|
||||
|
||||
ninit() {
|
||||
|
||||
|
||||
nconsole.log('I am called first')
|
||||
|
||||
|
||||
n}
|
||||
|
||||
|
||||
n}"
|
||||
|
||||
x-init="console.log('I am called second')"
|
||||
|
||||
>
|
||||
|
||||
...
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
275
offline-docs/alpinejs/directives/model.md
Normal file
275
offline-docs/alpinejs/directives/model.md
Normal file
@@ -0,0 +1,275 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-model](/directives/model)
|
||||
|
||||
`x-model` allows you to bind the value of an input element to Alpine data.
|
||||
|
||||
Here's a simple example of using `x-model` to bind the value of a text field to a piece of data in Alpine.
|
||||
|
||||
```
|
||||
<div x-data="{ message: '' }">
|
||||
|
||||
|
||||
n<input type="text" x-model="message">
|
||||
|
||||
|
||||
n<span x-text="message"></span>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Now as the user types into the text field, the `message` will be reflected in the `<span>` tag.
|
||||
|
||||
`x-model` is two-way bound, meaning it both "sets" and "gets". In addition to changing data, if the data itself changes, the element will reflect the change.
|
||||
|
||||
We can use the same example as above but this time, we'll add a button to change the value of the `message` property.
|
||||
|
||||
```
|
||||
<div x-data="{ message: '' }">
|
||||
|
||||
|
||||
n<input type="text" x-model="message">
|
||||
|
||||
|
||||
n<button x-on:click="message = 'changed'">Change Message</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Now when the `<button>` is clicked, the input element's value will instantly be updated to "changed".
|
||||
|
||||
`x-model` works with the following input elements:
|
||||
|
||||
* `<input type="text">`
|
||||
* `<textarea>`
|
||||
* `<input type="checkbox">`
|
||||
* `<input type="radio">`
|
||||
* `<select>`
|
||||
* `<input type="range">`
|
||||
|
||||
### [Text inputs](#text-inputs)
|
||||
|
||||
```
|
||||
<input type="text" x-model="message">
|
||||
|
||||
|
||||
n<span x-text="message"></span>
|
||||
```
|
||||
|
||||
> Despite not being included in the above snippet, `x-model` cannot be used if no parent element has `x-data` defined. [→ Read more about `x-data`](/directives/data)
|
||||
|
||||
### [Textarea inputs](#textarea-inputs)
|
||||
|
||||
```
|
||||
<textarea x-model="message"></textarea>
|
||||
|
||||
|
||||
n<span x-text="message"></span>
|
||||
```
|
||||
|
||||
### [Checkbox inputs](#checkbox-inputs)
|
||||
|
||||
#### [Single checkbox with boolean](#single-checkbox-with-boolean)
|
||||
|
||||
```
|
||||
<input type="checkbox" id="checkbox" x-model="show">
|
||||
|
||||
|
||||
n<label for="checkbox" x-text="show"></label>
|
||||
```
|
||||
|
||||
#### [Multiple checkboxes bound to array](#multiple-checkboxes-bound-to-array)
|
||||
|
||||
```
|
||||
<input type="checkbox" value="red" x-model="colors">
|
||||
|
||||
|
||||
n<input type="checkbox" value="orange" x-model="colors">
|
||||
|
||||
|
||||
n<input type="checkbox" value="yellow" x-model="colors">
|
||||
|
||||
|
||||
nColors: <span x-text="colors"></span>
|
||||
```
|
||||
|
||||
Colors:
|
||||
|
||||
### [Radio inputs](#radio-inputs)
|
||||
|
||||
```
|
||||
<input type="radio" value="yes" x-model="answer">
|
||||
|
||||
|
||||
n<input type="radio" value="no" x-model="answer">
|
||||
|
||||
|
||||
nAnswer: <span x-text="answer"></span>
|
||||
```
|
||||
|
||||
Answer:
|
||||
|
||||
### [Select inputs](#select-inputs)
|
||||
|
||||
#### [Single select](#single-select)
|
||||
|
||||
```
|
||||
<select x-model="color">
|
||||
|
||||
|
||||
n<option>Red</option>
|
||||
|
||||
|
||||
n<option>Orange</option>
|
||||
|
||||
|
||||
n<option>Yellow</option>
|
||||
|
||||
|
||||
n</select>
|
||||
|
||||
|
||||
nColor: <span x-text="color"></span>
|
||||
```
|
||||
|
||||
Color:
|
||||
|
||||
#### [Single select with placeholder](#single-select-with-placeholder)
|
||||
|
||||
```
|
||||
<select x-model="color">
|
||||
|
||||
|
||||
n<option value="" disabled>Select A Color</option>
|
||||
|
||||
|
||||
n<option>Red</option>
|
||||
|
||||
|
||||
n<option>Orange</option>
|
||||
|
||||
|
||||
n<option>Yellow</option>
|
||||
|
||||
|
||||
n</select>
|
||||
|
||||
|
||||
nColor: <span x-text="color"></span>
|
||||
```
|
||||
|
||||
Color:
|
||||
|
||||
#### [Multiple select](#multiple-select)
|
||||
|
||||
```
|
||||
<select x-model="color" multiple>
|
||||
|
||||
|
||||
n<option>Red</option>
|
||||
|
||||
|
||||
n<option>Orange</option>
|
||||
|
||||
|
||||
n<option>Yellow</option>
|
||||
|
||||
|
||||
n</select>
|
||||
|
||||
|
||||
nColors: <span x-text="color"></span>
|
||||
```
|
||||
|
||||
Color:
|
||||
|
||||
#### [Dynamically populated Select Options](#dynamically-populated-select-options)
|
||||
|
||||
```
|
||||
<select x-model="color">
|
||||
|
||||
|
||||
n<template x-for="color in ['Red', 'Orange', 'Yellow']">
|
||||
|
||||
|
||||
n<option x-text="color"></option>
|
||||
|
||||
|
||||
n</template>
|
||||
|
||||
|
||||
n</select>
|
||||
|
||||
|
||||
nColor: <span x-text="color"></span>
|
||||
```
|
||||
|
||||
Color:
|
||||
|
||||
### [Range inputs](#range-inputs)
|
||||
|
||||
```
|
||||
<input type="range" x-model="range" min="0" max="1" step="0.1">
|
||||
|
||||
|
||||
n<span x-text="range"></span>
|
||||
```
|
||||
|
||||
### [Modifiers](#modifiers)
|
||||
|
||||
#### [`.lazy`](#lazy)
|
||||
|
||||
On text inputs, by default, `x-model` updates the property on every keystroke. By adding the `.lazy` modifier, you can force an `x-model` input to only update the property when user focuses away from the input element.
|
||||
|
||||
This is handy for things like real-time form-validation where you might not want to show an input validation error until the user "tabs" away from a field.
|
||||
|
||||
```
|
||||
<input type="text" x-model.lazy="username">
|
||||
|
||||
|
||||
n<span x-show="username.length > 20">The username is too long.</span>
|
||||
```
|
||||
|
||||
#### [`.number`](#number)
|
||||
|
||||
By default, any data stored in a property via `x-model` is stored as a string. To force Alpine to store the value as a JavaScript number, add the `.number` modifier.
|
||||
|
||||
```
|
||||
<input type="text" x-model.number="age">
|
||||
|
||||
|
||||
n<span x-text="typeof age"></span>
|
||||
```
|
||||
|
||||
#### [`.boolean`](#boolean)
|
||||
|
||||
By default, any data stored in a property via `x-model` is stored as a string. To force Alpine to store the value as a JavaScript boolean, add the `.boolean` modifier. Both integers (1/0) and strings (true/false) are valid boolean values.
|
||||
|
||||
```
|
||||
<select x-model.boolean="isActive">
|
||||
|
||||
|
||||
n<option value="true">Yes</option>
|
||||
|
||||
|
||||
n<option value="false">No</option>
|
||||
|
||||
|
||||
n</select>
|
||||
|
||||
|
||||
n<span x-text="typeof isActive"></span>
|
||||
```
|
||||
|
||||
#### [`.debounce`](#debounce)
|
||||
|
||||
By adding `.debounce` to `x-model`, you can easily debounce the updating of bound input.
|
||||
|
||||
This is useful for things like real-time search inputs that fetch new data from the server every time the search property changes.
|
||||
|
||||
```
|
||||
<input type="text" x-model.
|
||||
383
offline-docs/alpinejs/directives/on.md
Normal file
383
offline-docs/alpinejs/directives/on.md
Normal file
@@ -0,0 +1,383 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-on](/directives/on)
|
||||
|
||||
`x-on` allows you to easily run code on dispatched DOM events.
|
||||
|
||||
Here's an example of simple button that shows an alert when clicked.
|
||||
|
||||
```
|
||||
<button x-on:click="alert('Hello World!')">Say Hi</button>
|
||||
```
|
||||
|
||||
> `x-on` can only listen for events with lower case names, as HTML attributes are case-insensitive. Writing `x-on:CLICK` will listen for an event named `click`. If you need to listen for a custom event with a camelCase name, you can use the [`.camel` helper](#camel) to work around this limitation. Alternatively, you can use [`x-bind`](about:/directives/bind#bind-directives) to attach an `x-on` directive to an element in javascript code (where case will be preserved).
|
||||
|
||||
### [Shorthand syntax](#shorthand-syntax)
|
||||
|
||||
If `x-on:` is too verbose for your tastes, you can use the shorthand syntax: `@`.
|
||||
|
||||
Here's the same component as above, but using the shorthand syntax instead:
|
||||
|
||||
```
|
||||
<button @click="alert('Hello World!')">Say Hi</button>
|
||||
```
|
||||
|
||||
> Despite not being included in the above snippet, `x-on` cannot be used if no parent element has `x-data` defined. [→ Read more about `x-data`](/directives/data)
|
||||
|
||||
### [The event object](#the-event-object)
|
||||
|
||||
If you wish to access the native JavaScript event object from your expression, you can use Alpine's magic `$event` property.
|
||||
|
||||
```
|
||||
<button @click="alert($event.target.getAttribute('message'))" message="Hello World">Say Hi</button>
|
||||
```
|
||||
|
||||
In addition, Alpine also passes the event object to any methods referenced without trailing parenthesis. For example:
|
||||
|
||||
```
|
||||
<button @click="handleClick">...</button>
|
||||
|
||||
|
||||
<script>
|
||||
|
||||
|
||||
function handleClick(e) {
|
||||
|
||||
|
||||
// Now you can access the event object (e) directly
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
```
|
||||
|
||||
### [Keyboard events](#keyboard-events)
|
||||
|
||||
Alpine makes it easy to listen for `keydown` and `keyup` events on specific keys.
|
||||
|
||||
Here's an example of listening for the `Enter` key inside an input element.
|
||||
|
||||
```
|
||||
<input type="text" @keyup.enter="alert('Submitted!')">
|
||||
```
|
||||
|
||||
You can also chain these key modifiers to achieve more complex listeners.
|
||||
|
||||
Here's a listener that runs when the `Shift` key is held and `Enter` is pressed, but not when `Enter` is pressed alone.
|
||||
|
||||
```
|
||||
<input type="text" @keyup.shift.enter="alert('Submitted!')">
|
||||
```
|
||||
|
||||
You can directly use any valid key names exposed via [`KeyboardEvent.key`](https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/key/Key_Values) as modifiers by converting them to kebab-case.
|
||||
|
||||
```
|
||||
<input type="text" @keyup.page-down="alert('Submitted!')">
|
||||
```
|
||||
|
||||
For easy reference, here is a list of common keys you may want to listen for.
|
||||
|
||||
| Modifier | Keyboard Key |
|
||||
| --- | --- |
|
||||
| `.shift` | Shift |
|
||||
| `.enter` | Enter |
|
||||
| `.space` | Space |
|
||||
| `.ctrl` | Ctrl |
|
||||
| `.cmd` | Cmd |
|
||||
| `.meta` | Cmd on Mac, Windows key on Windows |
|
||||
| `.alt` | Alt |
|
||||
| `.up` `.down` `.left` `.right` | Up/Down/Left/Right arrows |
|
||||
| `.escape` | Escape |
|
||||
| `.tab` | Tab |
|
||||
| `.caps-lock` | Caps Lock |
|
||||
| `.equal` | Equal, `=` |
|
||||
| `.period` | Period, `.` |
|
||||
| `.comma` | Comma, `,` |
|
||||
| `.slash` | Forward Slash, `/` |
|
||||
|
||||
### [Mouse events](#mouse-events)
|
||||
|
||||
Like the above Keyboard Events, Alpine allows the use of some key modifiers for handling `click` events.
|
||||
|
||||
| Modifier | Event Key |
|
||||
| --- | --- |
|
||||
| `.shift` | shiftKey |
|
||||
| `.ctrl` | ctrlKey |
|
||||
| `.cmd` | metaKey |
|
||||
| `.meta` | metaKey |
|
||||
| `.alt` | altKey |
|
||||
|
||||
These work on `click`, `auxclick`, `context` and `dblclick` events, and even `mouseover`, `mousemove`, `mouseenter`, `mouseleave`, `mouseout`, `mouseup` and `mousedown`.
|
||||
|
||||
Here's an example of a button that changes behaviour when the `Shift` key is held down.
|
||||
|
||||
```
|
||||
<button type="button"
|
||||
|
||||
|
||||
click="message = 'selected'"
|
||||
|
||||
click.shift="message = 'added to selection'">
|
||||
|
||||
@mousemove.shift="message = 'add to selection'"
|
||||
|
||||
@mouseout="message = 'select'"
|
||||
|
||||
x-text="message"></button>
|
||||
```
|
||||
|
||||
> Note: Normal click events with some modifiers (like `ctrl`) will automatically become `contextmenu` events in most browsers. Similarly, `right-click` events will trigger a `contextmenu` event, but will also trigger an `auxclick` event if the `contextmenu` event is prevented.
|
||||
|
||||
### [Custom events](#custom-events)
|
||||
|
||||
Alpine event listeners are a wrapper for native DOM event listeners. Therefore, they can listen for ANY DOM event, including custom events.
|
||||
|
||||
Here's an example of a component that dispatches a custom DOM event and listens for it as well.
|
||||
|
||||
```
|
||||
<div x-data @foo="alert('Button Was Clicked!')">
|
||||
|
||||
|
||||
<button @click="$event.target.dispatchEvent(new CustomEvent('foo', { bubbles: true }))">...</button>
|
||||
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
When the button is clicked, the `@foo` listener will be called.
|
||||
|
||||
Because the `.dispatchEvent` API is verbose, Alpine offers a `$dispatch` helper to simplify things.
|
||||
|
||||
Here's the same component re-written with the `$dispatch` magic property.
|
||||
|
||||
```
|
||||
<div x-data @foo="alert('Button Was Clicked!')">
|
||||
|
||||
|
||||
<button @click="$dispatch('foo')">...</button>
|
||||
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
[→ Read more about `$dispatch`](/magics/dispatch)
|
||||
|
||||
### [Modifiers](#modifiers)
|
||||
|
||||
Alpine offers a number of directive modifiers to customize the behavior of your event listeners.
|
||||
|
||||
#### [.prevent](#prevent)
|
||||
|
||||
`.prevent` is the equivalent of calling `.preventDefault()` inside a listener on the browser event object.
|
||||
|
||||
```
|
||||
<form @submit.prevent="console.log('submitted')" action="/foo">
|
||||
|
||||
|
||||
<button>Submit</button>
|
||||
|
||||
|
||||
</form>
|
||||
```
|
||||
|
||||
In the above example, with the `.prevent`, clicking the button will NOT submit the form to the `/foo` endpoint. Instead, Alpine's listener will handle it and "prevent" the event from being handled any further.
|
||||
|
||||
#### [.stop](#stop)
|
||||
|
||||
Similar to `.prevent`, `.stop` is the equivalent of calling `.stopPropagation()` inside a listener on the browser event object.
|
||||
|
||||
```
|
||||
<div @click="console.log('I will not get logged')">
|
||||
|
||||
|
||||
<button @click.stop>Click Me</button>
|
||||
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
In the above example, clicking the button WON'T log the message. This is because we are stopping the propagation of the event immediately and not allowing it to "bubble" up to the `<div>` with the `@click` listener on it.
|
||||
|
||||
#### [.outside](#outside)
|
||||
|
||||
`.outside` is a convenience helper for listening for a click outside of the element it is attached to. Here's a simple dropdown component example to demonstrate:
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
<button @click="open = ! open">Toggle</button>
|
||||
|
||||
|
||||
<div x-show="open" @click.outside="open = false">
|
||||
|
||||
|
||||
Contents...
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
In the above example, after showing the dropdown contents by clicking the "Toggle" button, you can close the dropdown by clicking anywhere on the page outside the content.
|
||||
|
||||
This is because `.outside` is listening for clicks that DON'T originate from the element it's registered on.
|
||||
|
||||
> It's worth noting that the `.outside` expression will only be evaluated when the element it's registered on is visible on the page. Otherwise, there would be nasty race conditions where clicking the "Toggle" button would also fire the `@click.outside` handler when it is not visible.
|
||||
|
||||
#### [.window](#window)
|
||||
|
||||
When the `.window` modifier is present, Alpine will register the event listener on the root `window` object on the page instead of the element itself.
|
||||
|
||||
```
|
||||
<div @keyup.escape.window="...">...</div>
|
||||
```
|
||||
|
||||
The above snippet will listen for the "escape" key to be pressed ANYWHERE on the page.
|
||||
|
||||
Adding `.window` to listeners is extremely useful for these sorts of cases where a small part of your markup is concerned with events that take place on the entire page.
|
||||
|
||||
#### [.document](#document)
|
||||
|
||||
`.document` works similarly to `.window` only it registers listeners on the `document` global, instead of the `window` global.
|
||||
|
||||
#### [.once](#once)
|
||||
|
||||
By adding `.once` to a listener, you are ensuring that the handler is only called ONCE.
|
||||
|
||||
```
|
||||
<button @click.once="console.log('I will only log once')">...</button>
|
||||
```
|
||||
|
||||
#### [.debounce](#debounce)
|
||||
|
||||
Sometimes it is useful to "debounce" an event handler so that it only is called after a certain period of inactivity (250 milliseconds by default).
|
||||
|
||||
For example if you have a search field that fires network requests as the user types into it, adding a debounce will prevent the network requests from firing on every single keystroke.
|
||||
|
||||
```
|
||||
<input @input.debounce="fetchResults">
|
||||
```
|
||||
|
||||
Now, instead of calling `fetchResults` after every keystroke, `fetchResults` will only be called after 250 milliseconds of no keystrokes.
|
||||
|
||||
If you wish to lengthen or shorten the debounce time, you can do so by trailing a duration after the `.debounce` modifier like so:
|
||||
|
||||
```
|
||||
<input @input.debounce.500ms="fetchResults">
|
||||
```
|
||||
|
||||
Now, `fetchResults` will only be called after 500 milliseconds of inactivity.
|
||||
|
||||
#### [.throttle](#throttle)
|
||||
|
||||
`.throttle` is similar to `.debounce` except it will release a handler call every 250 milliseconds instead of deferring it indefinitely.
|
||||
|
||||
This is useful for cases where there may be repeated and prolonged event firing and using `.debounce` won't work because you want to still handle the event every so often.
|
||||
|
||||
For example:
|
||||
|
||||
```
|
||||
<div @scroll.window.throttle="handleScroll">...</div>
|
||||
```
|
||||
|
||||
The above example is a great use case of throttling. Without `.throttle`, the `handleScroll` method would be fired hundreds of times as the user scrolls down a page. This can really slow down a site. By adding `.throttle`, we are ensuring that `handleScroll` only gets called every 250 milliseconds.
|
||||
|
||||
> Fun Fact: This exact strategy is used on this very documentation site to update the currently highlighted section in the right sidebar.
|
||||
|
||||
Just like with `.debounce`, you can add a custom duration to your throttled event:
|
||||
|
||||
```
|
||||
<div @scroll.window.throttle.750ms="handleScroll">...</div>
|
||||
```
|
||||
|
||||
Now, `handleScroll` will only be called every 750 milliseconds.
|
||||
|
||||
#### [.self](#self)
|
||||
|
||||
By adding `.self` to an event listener, you are ensuring that the event originated on the element it is declared on, and not from a child element.
|
||||
|
||||
```
|
||||
<button @click.self="handleClick">
|
||||
|
||||
|
||||
Click Me
|
||||
|
||||
|
||||
<img src="...">
|
||||
|
||||
|
||||
</button>
|
||||
```
|
||||
|
||||
In the above example, we have an `<img>` tag inside the `<button>` tag. Normally, any click originating within the `<button>` element (like on `<img>` for example), would be picked up by a `@click` listener on the button.
|
||||
|
||||
However, in this case, because we've added a `.self`, only clicking the button itself will call `handleClick`. Only clicks originating on the `<img>` element will not be handled.
|
||||
|
||||
#### [.camel](#camel)
|
||||
|
||||
```
|
||||
<div @custom-event.camel="handleCustomEvent">
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
Sometimes you may want to listen for camelCased events such as `customEvent` in our example. Because camelCasing inside HTML attributes is not supported, adding the `.camel` modifier is necessary for Alpine to camelCase the event name internally.
|
||||
|
||||
By adding `.camel` in the above example, Alpine is now listening for `customEvent` instead of `custom-event`.
|
||||
|
||||
#### [.dot](#dot)
|
||||
|
||||
```
|
||||
<div @custom-event.dot="handleCustomEvent">
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
Similar to the `.camelCase` modifier there may be situations where you want to listen for events that have dots in their name (like `custom.event`). Since dots within the event name are reserved by Alpine you need to write them with dashes and add the `.dot` modifier.
|
||||
|
||||
In the code example above `custom-event.dot` will correspond to the event name `custom.event`.
|
||||
|
||||
#### [.passive](#passive)
|
||||
|
||||
Browsers optimize scrolling on pages to be fast and smooth even when JavaScript is being executed on the page. However, improperly implemented touch and wheel listeners can block this optimization and cause poor site performance.
|
||||
|
||||
If you are listening for touch events, it's important to add `.passive` to your listeners to not block scroll performance.
|
||||
|
||||
```
|
||||
<div @touchstart.passive="...">...</div>
|
||||
```
|
||||
|
||||
[→ Read more about passive listeners](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#improving_scrolling_performance_with_passive_listeners)
|
||||
|
||||
#### .capture
|
||||
|
||||
Add this modifier if you want to execute this listener in the event's capturing phase, e.g. before the event bubbles from the target element up the DOM.
|
||||
|
||||
```
|
||||
<div @click.capture="console.log('I will log first')">
|
||||
|
||||
|
||||
<button @click="console.log('I will log second')"></button>
|
||||
|
||||
|
||||
</div>
|
||||
```
|
||||
|
||||
[→ Read more about the capturing and bubbling phase of events](https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#usecapture)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
23
offline-docs/alpinejs/directives/ref.md
Normal file
23
offline-docs/alpinejs/directives/ref.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-ref](/directives/ref)
|
||||
|
||||
`x-ref` in combination with `$refs` is a useful utility for easily accessing DOM elements directly. It's most useful as a replacement for APIs like `getElementById` and `querySelector`.
|
||||
|
||||
```
|
||||
<button @click="$refs.text.remove()">Remove Text</button>
|
||||
|
||||
<span x-ref="text">Hello 👋</span>
|
||||
```
|
||||
|
||||
Hello 👋
|
||||
|
||||
> Despite not being included in the above snippet, `x-ref` cannot be used if no parent element has `x-data` defined. [→ Read more about `x-data`](/directives/data)
|
||||
|
||||
[← x-ignore](/directives/ignore)
|
||||
|
||||
[x-cloak →](/directives/cloak)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
82
offline-docs/alpinejs/directives/show.md
Normal file
82
offline-docs/alpinejs/directives/show.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-show](/directives/show)
|
||||
|
||||
`x-show` is one of the most useful and powerful directives in Alpine. It provides an expressive way to show and hide DOM elements.
|
||||
|
||||
Here's an example of a simple dropdown component using `x-show`.
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button x-on:click="open = ! open">Toggle Dropdown</button>
|
||||
|
||||
|
||||
n<div x-show="open">
|
||||
|
||||
|
||||
nDropdown Contents...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
When the "Toggle Dropdown" button is clicked, the dropdown will show and hide accordingly.
|
||||
|
||||
> If the "default" state of an `x-show` on page load is "false", you may want to use `x-cloak` on the page to avoid "page flicker" (The effect that happens when the browser renders your content before Alpine is finished initializing and hiding it.) You can learn more about `x-cloak` in its documentation.
|
||||
|
||||
### [With transitions](#with-transitions)
|
||||
|
||||
If you want to apply smooth transitions to the `x-show` behavior, you can use it in conjunction with `x-transition`. You can learn more about that directive [here](/directives/transition), but here's a quick example of the same component as above, just with transitions applied.
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button x-on:click="open = ! open">Toggle Dropdown</button>
|
||||
|
||||
|
||||
n<div x-show="open" x-transition>
|
||||
|
||||
|
||||
nDropdown Contents...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
### [Using the important modifier](#using-the-important-modifier)
|
||||
|
||||
Sometimes you need to apply a little more force to actually hide an element. In cases where a CSS selector applies the `display` property with the `!important` flag, it will take precedence over the inline style set by Alpine.
|
||||
|
||||
In these cases you may use the `.important` modifier to set the inline style to `display: none !important`.
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button x-on:click="open = ! open">Toggle Dropdown</button>
|
||||
|
||||
|
||||
n<div x-show.important="open">
|
||||
|
||||
|
||||
nDropdown Contents...
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
29
offline-docs/alpinejs/directives/text.md
Normal file
29
offline-docs/alpinejs/directives/text.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-text](/directives/text)
|
||||
|
||||
`x-text` sets the text content of an element to the result of a given expression.
|
||||
|
||||
Here's a basic example of using `x-text` to display a user's username.
|
||||
|
||||
```
|
||||
<div x-data="{ username: 'calebporzio' }">
|
||||
|
||||
|
||||
nUsername: <strong x-text="username"></strong>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Username:
|
||||
|
||||
Now the `<strong>` tag's inner text content will be set to "calebporzio".
|
||||
|
||||
[← x-on](/directives/on)
|
||||
|
||||
[x-html →](/directives/html)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
189
offline-docs/alpinejs/directives/transition.md
Normal file
189
offline-docs/alpinejs/directives/transition.md
Normal file
@@ -0,0 +1,189 @@
|
||||
# Alpine.js Documentation - Directives
|
||||
|
||||
Alpine directives are attributes that you can add to HTML elements to give them special behavior.
|
||||
|
||||
## [x-transition](/directives/transition)
|
||||
|
||||
Alpine provides a robust transitions utility out of the box. With a few `x-transition` directives, you can create smooth transitions between when an element is shown or hidden.
|
||||
|
||||
There are two primary ways to handle transitions in Alpine:
|
||||
|
||||
* [The Transition Helper](#the-transition-helper)
|
||||
* [Applying CSS Classes](#applying-css-classes)
|
||||
|
||||
### [The transition helper](#the-transition-helper)
|
||||
|
||||
The simplest way to achieve a transition using Alpine is by adding `x-transition` to an element with `x-show` on it. For example:
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button @click="open = ! open">Toggle</button>
|
||||
|
||||
|
||||
n<div x-show="open" x-transition>
|
||||
|
||||
|
||||
nHello 👋
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Hello 👋
|
||||
|
||||
As you can see, by default, `x-transition` applies pleasant transition defaults to fade and scale the revealing element.
|
||||
|
||||
You can override these defaults with modifiers attached to `x-transition`. Let's take a look at those.
|
||||
|
||||
#### [Customizing duration](#customizing-duration)
|
||||
|
||||
Initially, the duration is set to be 150 milliseconds when entering, and 75 milliseconds when leaving.
|
||||
|
||||
You can configure the duration you want for a transition with the `.duration` modifier:
|
||||
|
||||
```
|
||||
<div ... x-transition.duration.500ms>
|
||||
```
|
||||
|
||||
The above `<div>` will transition for 500 milliseconds when entering, and 500 milliseconds when leaving.
|
||||
|
||||
If you wish to customize the durations specifically for entering and leaving, you can do that like so:
|
||||
|
||||
```
|
||||
<div ...
|
||||
|
||||
|
||||
nx-transition:enter.duration.500ms
|
||||
|
||||
|
||||
nx-transition:leave.duration.400ms
|
||||
|
||||
|
||||
n>
|
||||
```
|
||||
|
||||
> Despite not being included in the above snippet, `x-transition` cannot be used if no parent element has `x-data` defined. [→ Read more about `x-data`](/directives/data)
|
||||
|
||||
#### [Customizing delay](#customizing-delay)
|
||||
|
||||
You can delay a transition using the `.delay` modifier like so:
|
||||
|
||||
```
|
||||
<div ... x-transition.delay.50ms>
|
||||
```
|
||||
|
||||
The above example will delay the transition and in and out of the element by 50 milliseconds.
|
||||
|
||||
#### [Customizing opacity](#customizing-opacity)
|
||||
|
||||
By default, Alpine's `x-transition` applies both a scale and opacity transition to achieve a "fade" effect.
|
||||
|
||||
If you wish to only apply the opacity transition (no scale), you can accomplish that like so:
|
||||
|
||||
```
|
||||
<div ... x-transition.opacity>
|
||||
```
|
||||
|
||||
#### [Customizing scale](#customizing-scale)
|
||||
|
||||
Similar to the `.opacity` modifier, you can configure `x-transition` to ONLY scale (and not transition opacity as well) like so:
|
||||
|
||||
```
|
||||
<div ... x-transition.scale>
|
||||
```
|
||||
|
||||
The `.scale` modifier also offers the ability to configure its scale values AND its origin values:
|
||||
|
||||
```
|
||||
<div ... x-transition.scale.80>
|
||||
```
|
||||
|
||||
The above snippet will scale the element up and down by 80%.
|
||||
|
||||
Again, you may customize these values separately for enter and leaving transitions like so:
|
||||
|
||||
```
|
||||
<div ...
|
||||
|
||||
|
||||
nx-transition:enter.scale.80
|
||||
|
||||
|
||||
nx-transition:leave.scale.90
|
||||
|
||||
|
||||
n>
|
||||
```
|
||||
|
||||
To customize the origin of the scale transition, you can use the `.origin` modifier:
|
||||
|
||||
```
|
||||
<div ... x-transition.scale.origin.top>
|
||||
```
|
||||
|
||||
Now the scale will be applied using the top of the element as the origin, instead of the center by default.
|
||||
|
||||
Like you may have guessed, the possible values for this customization are: `top`, `bottom`, `left`, and `right`.
|
||||
|
||||
If you wish, you can also combine two origin values. For example, if you want the origin of the scale to be "top right", you can use: `.origin.top.right` as the modifier.
|
||||
|
||||
### [Applying CSS classes](#applying-css-classes)
|
||||
|
||||
For direct control over exactly what goes into your transitions, you can apply CSS classes at different stages of the transition.
|
||||
|
||||
> The following examples use [TailwindCSS](https://tailwindcss.com/docs/transition-property) utility classes.
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }">
|
||||
|
||||
|
||||
n<button @click="open = ! open">Toggle</button>
|
||||
|
||||
|
||||
n<div
|
||||
|
||||
|
||||
nx-show="open"
|
||||
|
||||
|
||||
nx-transition:enter="transition ease-out duration-300"
|
||||
|
||||
|
||||
nx-transition:enter-start="opacity-0 scale-90"
|
||||
|
||||
|
||||
nx-transition:enter-end="opacity-100 scale-100"
|
||||
|
||||
|
||||
nx-transition:leave="transition ease-in duration-300"
|
||||
|
||||
|
||||
nx-transition:leave-start="opacity-100 scale-100"
|
||||
|
||||
|
||||
nx-transition:leave-end="opacity-0 scale-90"
|
||||
|
||||
|
||||
n>Hello 👋</div>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Hello 👋
|
||||
|
||||
| Directive | Description |
|
||||
| --- | --- |
|
||||
| `:enter` | Applied during the entire entering phase. |
|
||||
| `:enter-start` | Added before element is inserted, removed one frame after element is inserted. |
|
||||
| `:enter-end` | Added one frame after element is inserted (at the same time `enter-start` is removed), removed when transition/animation finishes. |
|
||||
| `:leave` | Applied during the entire leaving phase. |
|
||||
| `:leave-start` | Added immediately when a leaving transition is triggered, removed after one frame. |
|
||||
| `:leave-end` | Added one frame after a leaving transition is triggered (at the same time `leave-start` is removed), removed when the transition/animation finishes. |
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
78
offline-docs/alpinejs/essentials/data.md
Normal file
78
offline-docs/alpinejs/essentials/data.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Alpine.js Documentation - Essentials
|
||||
|
||||
There are 2 ways to include Alpine into your project:
|
||||
|
||||
* Including it from a `<script>` tag
|
||||
* Importing it as a module
|
||||
|
||||
Either is perfectly valid. It all depends on the project's needs and the developer's taste.
|
||||
|
||||
## [From a script tag](#from-a-script-tag)
|
||||
|
||||
This is by far the simplest way to get started with Alpine. Include the following `<script>` tag in the head of your HTML page.
|
||||
|
||||
```
|
||||
<html>
|
||||
|
||||
|
||||
n<head>
|
||||
|
||||
|
||||
n...
|
||||
|
||||
|
||||
n<script defer src="https://cdn.jsdelivr.net/npm/[email\(protected\)]/dist/cdn.min.js"></script>
|
||||
|
||||
|
||||
n</head>
|
||||
|
||||
|
||||
n...
|
||||
|
||||
|
||||
n</html>
|
||||
```
|
||||
|
||||
> Don't forget the "defer" attribute in the `<script>` tag.
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/[email\(protected\)]/dist/cdn.min.js"></script>
|
||||
```
|
||||
|
||||
That's it! Alpine is now available for use inside your page.
|
||||
|
||||
Note that you will still need to define a component with `x-data` in order for any Alpine.js attributes to work. See <https://github.com/alpinejs/alpine/discussions/3805> for more information.
|
||||
|
||||
## [As a module](#as-a-module)
|
||||
|
||||
If you prefer the more robust approach, you can install Alpine via NPM and import it into a bundle.
|
||||
|
||||
Run the following command to install it.
|
||||
|
||||
```
|
||||
npm install alpinejs
|
||||
```
|
||||
|
||||
Now import Alpine into your bundle and initialize it like so:
|
||||
|
||||
```
|
||||
import Alpine from 'alpinejs'
|
||||
|
||||
|
||||
nwindow.Alpine = Alpine
|
||||
|
||||
|
||||
nAlpine.start()
|
||||
```
|
||||
|
||||
> The `window.Alpine = Alpine` bit is optional, but is nice to have for freedom and flexibility. Like when tinkering with Alpine from the devtools for example.
|
||||
|
||||
> If you imported Alpine into a bundle, you have to make sure you are registering any extension code IN BETWEEN when you import the `Alpine` global object, and when you initialize Alpine by calling `Alpine.start()`.
|
||||
|
||||
> Ensure that `Alpine.start()` is only called once per page. Calling it more than once will result in multiple "instances" of Alpine running at the same time.
|
||||
|
||||
[→ Read more about extending Alpine](/advanced/extending)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
78
offline-docs/alpinejs/essentials/getting-started.md
Normal file
78
offline-docs/alpinejs/essentials/getting-started.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Alpine.js Documentation - Essentials
|
||||
|
||||
There are 2 ways to include Alpine into your project:
|
||||
|
||||
* Including it from a `<script>` tag
|
||||
* Importing it as a module
|
||||
|
||||
Either is perfectly valid. It all depends on the project's needs and the developer's taste.
|
||||
|
||||
## [From a script tag](#from-a-script-tag)
|
||||
|
||||
This is by far the simplest way to get started with Alpine. Include the following `<script>` tag in the head of your HTML page.
|
||||
|
||||
```
|
||||
<html>
|
||||
|
||||
|
||||
n<head>
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/[email\(protected\)]/dist/cdn.min.js"></script>
|
||||
|
||||
|
||||
</head>
|
||||
|
||||
|
||||
...
|
||||
|
||||
|
||||
</html>
|
||||
```
|
||||
|
||||
> Don't forget the "defer" attribute in the `<script>` tag.
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/[email\(protected\)]/dist/cdn.min.js"></script>
|
||||
```
|
||||
|
||||
That's it! Alpine is now available for use inside your page.
|
||||
|
||||
Note that you will still need to define a component with `x-data` in order for any Alpine.js attributes to work. See <https://github.com/alpinejs/alpine/discussions/3805> for more information.
|
||||
|
||||
## [As a module](#as-a-module)
|
||||
|
||||
If you prefer the more robust approach, you can install Alpine via NPM and import it into a bundle.
|
||||
|
||||
Run the following command to install it.
|
||||
|
||||
```
|
||||
npm install alpinejs
|
||||
```
|
||||
|
||||
Now import Alpine into your bundle and initialize it like so:
|
||||
|
||||
```
|
||||
import Alpine from 'alpinejs'
|
||||
|
||||
|
||||
nwindow.Alpine = Alpine
|
||||
|
||||
|
||||
nAlpine.start()
|
||||
```
|
||||
|
||||
> The `window.Alpine = Alpine` bit is optional, but is nice to have for freedom and flexibility. Like when tinkering with Alpine from the devtools for example.
|
||||
|
||||
> If you imported Alpine into a bundle, you have to make sure you are registering any extension code IN BETWEEN when you import the `Alpine` global object, and when you initialize Alpine by calling `Alpine.start()`.
|
||||
|
||||
> Ensure that `Alpine.start()` is only called once per page. Calling it more than once will result in multiple "instances" of Alpine running at the same time.
|
||||
|
||||
[→ Read more about extending Alpine](/advanced/extending)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
78
offline-docs/alpinejs/essentials/reactivity.md
Normal file
78
offline-docs/alpinejs/essentials/reactivity.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Alpine.js Documentation - Essentials
|
||||
|
||||
There are 2 ways to include Alpine into your project:
|
||||
|
||||
* Including it from a `<script>` tag
|
||||
* Importing it as a module
|
||||
|
||||
Either is perfectly valid. It all depends on the project's needs and the developer's taste.
|
||||
|
||||
## [From a script tag](#from-a-script-tag)
|
||||
|
||||
This is by far the simplest way to get started with Alpine. Include the following `<script>` tag in the head of your HTML page.
|
||||
|
||||
```
|
||||
<html>
|
||||
|
||||
|
||||
n<head>
|
||||
|
||||
|
||||
n...
|
||||
|
||||
|
||||
n<script defer src="https://cdn.jsdelivr.net/npm/[email\(protected\)]/dist/cdn.min.js"></script>
|
||||
|
||||
|
||||
n</head>
|
||||
|
||||
|
||||
n...
|
||||
|
||||
|
||||
n</html>
|
||||
```
|
||||
|
||||
> Don't forget the "defer" attribute in the `<script>` tag.
|
||||
|
||||
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.
|
||||
|
||||
```
|
||||
<script defer src="https://cdn.jsdelivr.net/npm/[email\(protected\)]/dist/cdn.min.js"></script>
|
||||
```
|
||||
|
||||
That's it! Alpine is now available for use inside your page.
|
||||
|
||||
Note that you will still need to define a component with `x-data` in order for any Alpine.js attributes to work. See <https://github.com/alpinejs/alpine/discussions/3805> for more information.
|
||||
|
||||
## [As a module](#as-a-module)
|
||||
|
||||
If you prefer the more robust approach, you can install Alpine via NPM and import it into a bundle.
|
||||
|
||||
Run the following command to install it.
|
||||
|
||||
```
|
||||
npm install alpinejs
|
||||
```
|
||||
|
||||
Now import Alpine into your bundle and initialize it like so:
|
||||
|
||||
```
|
||||
import Alpine from 'alpinejs'
|
||||
|
||||
|
||||
nwindow.Alpine = Alpine
|
||||
|
||||
|
||||
nAlpine.start()
|
||||
```
|
||||
|
||||
> The `window.Alpine = Alpine` bit is optional, but is nice to have for freedom and flexibility. Like when tinkering with Alpine from the devtools for example.
|
||||
|
||||
> If you imported Alpine into a bundle, you have to make sure you are registering any extension code IN BETWEEN when you import the `Alpine` global object, and when you initialize Alpine by calling `Alpine.start()`.
|
||||
|
||||
> Ensure that `Alpine.start()` is only called once per page. Calling it more than once will result in multiple "instances" of Alpine running at the same time.
|
||||
|
||||
[→ Read more about extending Alpine](/advanced/extending)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
146
offline-docs/alpinejs/magics/dispatch.md
Normal file
146
offline-docs/alpinejs/magics/dispatch.md
Normal file
@@ -0,0 +1,146 @@
|
||||
# Alpine.js Documentation - Magics
|
||||
|
||||
Magics are special properties that are available inside Alpine expressions. They provide convenient access to common functionality.
|
||||
|
||||
## [$dispatch](/magics/dispatch)
|
||||
|
||||
`$dispatch` is a helpful shortcut for dispatching browser events.
|
||||
|
||||
```
|
||||
<div @notify="alert('Hello World!')">
|
||||
|
||||
|
||||
n<button @click="$dispatch('notify')">
|
||||
|
||||
|
||||
nNotify
|
||||
|
||||
|
||||
n</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
You can also pass data along with the dispatched event if you wish. This data will be accessible as the `.detail` property of the event:
|
||||
|
||||
```
|
||||
<div @notify="alert($event.detail.message)">
|
||||
|
||||
|
||||
n<button @click="$dispatch('notify', { message: 'Hello World!' })">
|
||||
|
||||
|
||||
nNotify
|
||||
|
||||
|
||||
n</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Under the hood, `$dispatch` is a wrapper for the more verbose API: `element.dispatchEvent(new CustomEvent(...))`
|
||||
|
||||
**Note on event propagation**
|
||||
|
||||
Notice that, because of [event bubbling](https://en.wikipedia.org/wiki/Event_bubbling), when you need to capture events dispatched from nodes that are under the same nesting hierarchy, you'll need to use the [`.window`](https://github.com/alpinejs/alpine#x-on) modifier:
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
<!-- 🚫 Won't work -->
|
||||
|
||||
|
||||
n<div x-data>
|
||||
|
||||
|
||||
n<span @notify="..."></span>
|
||||
|
||||
|
||||
n<button @click="$dispatch('notify')">Notify</button>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n<!-- ✅ Will work (because of .window) -->
|
||||
|
||||
|
||||
n<div x-data>
|
||||
|
||||
|
||||
n<span @notify.window="..."></span>
|
||||
|
||||
|
||||
n<button @click="$dispatch('notify')">Notify</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
> The first example won't work because when `notify` is dispatched, it'll propagate to its common ancestor, the `div`, not its sibling, the `<span>`. The second example will work because the sibling is listening for `notify` at the `window` level, which the custom event will eventually bubble up to.
|
||||
|
||||
### [Dispatching to other components](#dispatching-to-components)
|
||||
|
||||
You can also take advantage of the previous technique to make your components talk to each other:
|
||||
|
||||
**Example:**
|
||||
|
||||
```
|
||||
<div
|
||||
|
||||
|
||||
nx-data="{ title: 'Hello' }"
|
||||
|
||||
|
||||
n@set-title.window="title = $event.detail"
|
||||
|
||||
|
||||
n>
|
||||
|
||||
|
||||
nh1 x-text="title"></h1>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n<div x-data>
|
||||
|
||||
|
||||
n<button @click="$dispatch('set-title', 'Hello World!')">Click me</button>
|
||||
|
||||
|
||||
n</div>
|
||||
|
||||
|
||||
n<!-- When clicked, the content of the h1 will set to "Hello World!. -->
|
||||
```
|
||||
|
||||
### [Dispatching to x-model](#dispatching-to-x-model)
|
||||
|
||||
You can also use `$dispatch()` to trigger data updates for `x-model` data bindings. For example:
|
||||
|
||||
```
|
||||
<div x-data="{ title: 'Hello' }">
|
||||
|
||||
|
||||
n<span x-model="title">
|
||||
|
||||
|
||||
n<button @click="$dispatch('input', 'Hello World!')">Click me</button>
|
||||
|
||||
|
||||
n<!-- After the button is pressed, `x-model` will catch the bubbling "input" event, and update title. -->
|
||||
|
||||
|
||||
n</span>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
This opens up the door for making custom input components whose value can be set via `x-model`.
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
17
offline-docs/alpinejs/magics/el.md
Normal file
17
offline-docs/alpinejs/magics/el.md
Normal file
@@ -0,0 +1,17 @@
|
||||
# Alpine.js Documentation - Magics
|
||||
|
||||
Magics are special properties that are available inside Alpine expressions. They provide convenient access to common functionality.
|
||||
|
||||
## [$el](/magics/el)
|
||||
|
||||
`$el` is a magic property that can be used to retrieve the current DOM node.
|
||||
|
||||
```
|
||||
<button @click="$el.innerHTML = 'Hello World!'">Replace me with "Hello World!"</button>
|
||||
```
|
||||
|
||||
[← x-id](/directives/id)
|
||||
|
||||
[$refs →](/magics/refs)
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
79
offline-docs/alpinejs/magics/watch.md
Normal file
79
offline-docs/alpinejs/magics/watch.md
Normal file
@@ -0,0 +1,79 @@
|
||||
# Alpine.js Documentation - Magics
|
||||
|
||||
Magics are special properties that are available inside Alpine expressions. They provide convenient access to common functionality.
|
||||
|
||||
## [$watch](/magics/watch)
|
||||
|
||||
You can "watch" a component property using the `$watch` magic method. For example:
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }" x-init="$watch('open', value => console.log(value))">
|
||||
|
||||
|
||||
n<button @click="open = ! open">Toggle Open</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
In the above example, when the button is pressed and `open` is changed, the provided callback will fire and `console.log` the new value:
|
||||
|
||||
You can watch deeply nested properties using "dot" notation
|
||||
|
||||
```
|
||||
<div x-data="{ foo: { bar: 'baz' }}" x-init="$watch('foo.bar', value => console.log(value))">
|
||||
|
||||
|
||||
n<button @click="foo.bar = 'bob'">Toggle Open</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
When the `<button>` is pressed, `foo.bar` will be set to "bob", and "bob" will be logged to the console.
|
||||
|
||||
### [Getting the "old" value](#getting-the-old-value)
|
||||
|
||||
`$watch` keeps track of the previous value of the property being watched, You can access it using the optional second argument to the callback like so:
|
||||
|
||||
```
|
||||
<div x-data="{ open: false }" x-init="$watch('open', (value, oldValue) => console.log(value, oldValue))">
|
||||
|
||||
|
||||
n<button @click="open = ! open">Toggle Open</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
### [Deep watching](#deep-watching)
|
||||
|
||||
`$watch` 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.
|
||||
|
||||
```
|
||||
<div x-data="{ foo: { bar: 'baz' }}" x-init="$watch('foo', (value, oldValue) => console.log(value, oldValue))">
|
||||
|
||||
|
||||
n<button @click="foo.bar = 'bob'">Update</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
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).
|
||||
|
||||
> ⚠️ Changing a property of a "watched" object as a side effect of the `$watch` callback will generate an infinite loop and eventually error.
|
||||
|
||||
```
|
||||
<!-- 🚫 Infinite loop -->
|
||||
|
||||
<div x-data="{ foo: { bar: 'baz', bob: 'lob' }}" x-init="$watch('foo', value => foo.bob = foo.bar)">
|
||||
|
||||
|
||||
n<button @click="foo.bar = 'bob'">Update</button>
|
||||
|
||||
|
||||
n</div>
|
||||
```
|
||||
|
||||
Code highlighting provided by [Torchlight](https://torchlight.dev/)
|
||||
Reference in New Issue
Block a user