Skip to content

Commit

Permalink
Merge pull request #30 from MichaelWest22/patch-1
Browse files Browse the repository at this point in the history
Add apply-parent-classes feature to class-tools
  • Loading branch information
1cg authored Jul 8, 2024
2 parents c5a7374 + 90b1495 commit 03b3018
Show file tree
Hide file tree
Showing 5 changed files with 44 additions and 5 deletions.
7 changes: 6 additions & 1 deletion src/class-tools/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,12 @@ Within a run, a `,` character separates distinct class operations.
A class operation is an operation name `add`, `remove`, or `toggle`, followed by a CSS class name,
optionally followed by a colon `:` and a time delay.

There is also the option to use `apply-parent-classes` or `data-apply-parent-classes` which uses the same format as `classes` but is instead designed for Out of band updates to allow you to manipulate CSS classes of an existing element in the DOM without otherwise knowing or altering its state. Any element with this property will apply classes to its parent and also remove this child element afterwards so should ideally be used as part of a `hx-swap-oob="beforeend: #some-element`.

## Install

```html
<script src="https://unpkg.com/[email protected].0/class-tools.js"></script>
<script src="https://unpkg.com/[email protected].1/class-tools.js"></script>
```

## Usage
Expand All @@ -30,4 +32,7 @@ optionally followed by a colon `:` and a time delay.
class "foo" after 1s -->
<div classes="toggle foo:1s"/> <!-- toggles the class "foo" every 1s -->
</div>
<div hx-swap-oob="beforeend: #my-element"> <!-- adds the class "foo" to my-element for 10s -->
<div hx-ext="class-tools" apply-parent-classes="add foo, remove foo:10s"></div>
</div>
```
8 changes: 7 additions & 1 deletion src/class-tools/class-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,13 @@
if (name === 'htmx:afterProcessNode') {
var elt = evt.detail.elt
maybeProcessClasses(elt)
if (elt.querySelectorAll) {
var classList = elt.getAttribute("apply-parent-classes") || elt.getAttribute("data-apply-parent-classes");
if (classList) {
var parent = elt.parentElement;
parent.removeChild(elt);
parent.setAttribute("classes", classList);
maybeProcessClasses(parent);
} else if (elt.querySelectorAll) {
var children = elt.querySelectorAll('[classes], [data-classes]')
for (var i = 0; i < children.length; i++) {
maybeProcessClasses(children[i])
Expand Down
4 changes: 2 additions & 2 deletions src/class-tools/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion src/class-tools/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "htmx-ext-class-tools",
"main": "class-tools.js",
"version": "2.0.0",
"version": "2.0.1",
"scripts": {
"lint": "eslint test/ext test",
"lint-fix": "eslint test/ext test --fix",
Expand Down
28 changes: 28 additions & 0 deletions src/class-tools/test/ext/class-tools.js
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,34 @@ describe('class-tools extension', function() {
}, 100)
})

it('adds classes to parent properly', function(done) {
var div = make('<div>Click Me!<div hx-ext="class-tools" apply-parent-classes="add c1"></div></div>')
should.equal(div.classList.length, 0)
setTimeout(function() {
should.equal(div.classList.contains('c1'), true)
done()
}, 100)
})

it('removes classes from parent properly', function(done) {
var div = make('<div class="foo bar">Click Me!<div hx-ext="class-tools" apply-parent-classes="remove bar"></div></div>')
should.equal(div.classList.contains('foo'), true)
should.equal(div.classList.contains('bar'), true)
setTimeout(function() {
should.equal(div.classList.contains('foo'), true)
should.equal(div.classList.contains('bar'), false)
done()
}, 100)
})

it('cleans up child with apply-parent-classes properly', function(done) {
var div = make('<div class="foo bar">Click Me!<div id="d2" hx-ext="class-tools" apply-parent-classes="remove bar"></div></div>')
setTimeout(function() {
should.not.exist(byId('d2'))
done()
}, 100)
})

it('extension can be on parent', function(done) {
var div = make('<div hx-ext="class-tools"><div id="d1" classes="add c1">Click Me!</div></div>')
should.equal(div.classList.length, 0)
Expand Down

0 comments on commit 03b3018

Please sign in to comment.