mirror of
https://github.com/archtechx/wire-replace.git
synced 2025-12-11 23:24:03 +00:00
Initial commit
This commit is contained in:
commit
edbfe280eb
8 changed files with 181 additions and 0 deletions
17
.github/workflows/publish.yaml
vendored
Normal file
17
.github/workflows/publish.yaml
vendored
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
name: Publish Node.js package
|
||||
on:
|
||||
release:
|
||||
types: [created]
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- uses: actions/setup-node@v1
|
||||
with:
|
||||
node-version: '12.x'
|
||||
registry-url: 'https://registry.npmjs.org'
|
||||
- run: npm install
|
||||
- run: npm publish
|
||||
env:
|
||||
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
|
||||
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
/node_modules
|
||||
/dist
|
||||
package-lock.json
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
|
|
@ -0,0 +1,21 @@
|
|||
MIT License
|
||||
|
||||
Copyright (c) 2020 Samuel Štancl
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
80
README.md
Normal file
80
README.md
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
# wire-replace
|
||||
|
||||
This package adds a new directive to Livewire: `wire:replace`. The directive is useful for solving DOM diffing issues.
|
||||
|
||||
For example, if you have the following template:
|
||||
|
||||
```html
|
||||
<div>
|
||||
Showing
|
||||
<span class="font-medium">{{ $paginator->firstItem() }}</span>
|
||||
to
|
||||
<span class="font-medium">{{ $paginator->lastItem() }}</span>
|
||||
of
|
||||
<span class="font-medium">{{ $paginator->total() }}</span>
|
||||
results
|
||||
</div>
|
||||
```
|
||||
|
||||
The numbers will eventually merge into a single value if you update the component's data a few times.
|
||||
|
||||
To solve this, you'd wrap all of those free-floating strings in `<span>`s. And sure, it would work here.
|
||||
|
||||
But:
|
||||
- it's ugly
|
||||
- it won't work in situations where you display template that you don't have control over (translated templates, rich text added by users, ...)
|
||||
|
||||
## Usage
|
||||
|
||||
This package adds two extremely simple directives: `wire:replace` and `wire:replace.self`. Simply use them on elements that you want fully replaced.
|
||||
|
||||
You can think if this directive as the opposite of `wire:ignore`. `wire:ignore` tells Livewire to **never** replace the element, and `wire:replace` tells Livewire to **always** replace the elemenet.
|
||||
|
||||
To tell Livewire that the element's children should always be replaced:
|
||||
```html
|
||||
<div wire:replace>
|
||||
Showing
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
To tell Livewire that **the element itself plus its children** should always be replaced:
|
||||
```html
|
||||
<div wire:replace.self>
|
||||
Showing
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
## Installation
|
||||
|
||||
### npm dependency
|
||||
Install the package:
|
||||
```
|
||||
npm install --dev leanadmin@wire-replace
|
||||
```
|
||||
|
||||
Register the directive in your `app.js` file:
|
||||
|
||||
```js
|
||||
import wire_replace from '@leanadmin/wire-replace';
|
||||
|
||||
window.Livewire.hook(...wire_replace);
|
||||
```
|
||||
|
||||
### CDN
|
||||
|
||||
Simply include the JS file in your layout (**after Livewire's scripts**) and the directive will automatically register itself.
|
||||
```html
|
||||
@livewireScripts
|
||||
|
||||
<script src="https://unpkg.com/@leanadmin/wire-replace@0.1.0/"></script>
|
||||
```
|
||||
|
||||
## Performance
|
||||
|
||||
Livewire doesn't expose its internal morphdom class which would allow us to just tell morphdom to stop diffing the current tree if when it encounters an element with a `wire:replace` attribute.
|
||||
|
||||
So instead, we hook into Livewire's `element.updating` event and we replace the target element fully with the new element, before Livewire/morphdom can attempt more intelligent diffs.
|
||||
|
||||
This is likely less performant than hooking into morphdom's events, but in most cases it won't matter. The main use case of this package is small bits of templates where Livewire can't figure things out itself and `wire:key` doesn't help. And for that, it works completely smoothly.
|
||||
3
cdn/wire_replace.js
Normal file
3
cdn/wire_replace.js
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
import wire_replace from '../index';
|
||||
|
||||
window.Livewire.hook(...wire_replace);
|
||||
18
index.js
Normal file
18
index.js
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
/**
|
||||
* Add wire:replace functionality to Livewire.
|
||||
*
|
||||
* When wire:replace is applied to an element, the element's children will *always* be fully replaced rather than intelligently DOM-diffed.
|
||||
* When wire:replace.self is applied to an element, the element itself (plus all of its children) will be
|
||||
*/
|
||||
|
||||
export default ['element.updating', (from, to) => {
|
||||
let attributes = Object.values(from.attributes);
|
||||
|
||||
if (attributes.filter(attribute => attribute.name === 'wire:replace').length) {
|
||||
from.innerHTML = to.innerHTML;
|
||||
}
|
||||
|
||||
if (attributes.filter(attribute => attribute.name === 'wire:replace.self').length) {
|
||||
from.outerHTML = to.outerHTML;
|
||||
}
|
||||
}];
|
||||
35
package.json
Normal file
35
package.json
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
{
|
||||
"name": "@leanadmin/wire-replace",
|
||||
"version": "0.1.0",
|
||||
"description": "wire:replace directive for Livewire",
|
||||
"main": "index.js",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/LeanAdmin/wire-replace.git"
|
||||
},
|
||||
"files": [
|
||||
"index.js",
|
||||
"dist/wire_replace.js"
|
||||
],
|
||||
"scripts": {
|
||||
"build": "npx mix",
|
||||
"prepublishOnly": "npm build"
|
||||
},
|
||||
"keywords": [
|
||||
"livewire"
|
||||
],
|
||||
"author": "Samuel Štancl <samuel.stancl@gmail.com>",
|
||||
"license": "MIT",
|
||||
"bugs": {
|
||||
"url": "https://github.com/LeanAdmin/wire-replace/issues"
|
||||
},
|
||||
"homepage": "https://github.com/LeanAdmin/wire-replace#readme",
|
||||
"devDependencies": {
|
||||
"laravel-mix": "^6.0.6",
|
||||
"postcss": "^8.2.2"
|
||||
},
|
||||
"dependencies": {
|
||||
"json": "^10.0.0",
|
||||
"node-jq": "^1.11.3"
|
||||
}
|
||||
}
|
||||
4
webpack.mix.js
Normal file
4
webpack.mix.js
Normal file
|
|
@ -0,0 +1,4 @@
|
|||
let mix = require('laravel-mix');
|
||||
|
||||
mix.setPublicPath('dist')
|
||||
.js('cdn/wire_replace.js', 'dist');
|
||||
Loading…
Add table
Add a link
Reference in a new issue