Fix Toggler demo selector and support multiple classes

- Use a data attribute instead of an unknown class in the demo and docs
- Toggle every class from a space separated value
- Say in the docs which element fires the events
This commit is contained in:
codecalm committed 2026-09-29 20:02:28 +02:00
1 parent b9cb13b6b6
commit 5d520bb6f1
4 files changed
+31 -10

No files matched your search

+4 -1
View File
@@ -94,7 +94,10 @@ class Toggler extends BaseComponent {
}
if (attribute === 'class') {
this._element.classList.toggle(String(value))
for (const className of String(value).split(/\s+/).filter(Boolean)) {
this._element.classList.toggle(className)
}
return
}
+16
View File
@@ -46,6 +46,21 @@ describe('Toggler', () => {
expect(togglerEl.classList.contains('bg-warning')).toBe(false)
})
it('should toggle every class from a space separated value', () => {
fixtureEl.innerHTML = '<div class="bg-info" data-bs-toggle="toggler" data-bs-value="bg-warning bg-info"></div>'
const togglerEl = fixtureEl.querySelector<HTMLElement>('[data-bs-toggle="toggler"]')!
const toggler = new Toggler(togglerEl)
toggler.toggle()
expect(togglerEl.classList.contains('bg-warning')).toBe(true)
expect(togglerEl.classList.contains('bg-info')).toBe(false)
toggler.toggle()
expect(togglerEl.classList.contains('bg-warning')).toBe(false)
expect(togglerEl.classList.contains('bg-info')).toBe(true)
})
it('should toggle attribute on the element', () => {
fixtureEl.innerHTML = '<div data-bs-toggle="toggler" data-bs-value="true" data-bs-attribute="hidden"></div>'
@@ -264,6 +279,7 @@ describe('Toggler', () => {
triggerEl.click()
expect(targetEl.classList.contains('active')).toBe(false)
})
it('should work with the data-tblr- prefix', () => {
fixtureEl.innerHTML = ['<button data-tblr-toggle="toggler" data-tblr-target="#target-tblr"></button>', '<div id="target-tblr" data-tblr-value="active"></div>'].join('')
+8 -6
View File
@@ -37,12 +37,12 @@ Use `data-bs-target` to change another element. Put `data-bs-value` on the targe
### Multiple elements
A class selector in `data-bs-target` toggles every matching element. Each one can have its own value.
When the selector in `data-bs-target` matches many elements, Toggler changes every one of them. Each one can have its own value.
<Example>
<button type="button" class="btn mb-3" data-bs-toggle="toggler" data-bs-target=".toggler-target">Toggle all</button>
<div class="toggler-target p-3 mb-2 rounded border" data-bs-value="bg-blue-lt">Toggles bg-blue-lt</div>
<div class="toggler-target p-3 rounded border" data-bs-value="bg-green-lt">Toggles bg-green-lt</div>
<button type="button" class="btn mb-3" data-bs-toggle="toggler" data-bs-target="[data-toggler-demo]">Toggle all</button>
<div class="p-3 mb-2 rounded border" data-toggler-demo data-bs-value="bg-blue-lt">Toggles bg-blue-lt</div>
<div class="p-3 rounded border" data-toggler-demo data-bs-value="bg-green-lt">Toggles bg-green-lt</div>
</Example>
### Toggle an attribute
@@ -63,7 +63,7 @@ You can use the same pattern to toggle `disabled` on a `fieldset` and lock all c
| `data-bs-toggle="toggler"` | Turns the element into a trigger. |
| `data-bs-target` | Optional CSS selector of the element to change. Without it, the trigger changes itself. |
| `data-bs-attribute` | Attribute to toggle. Default is `class`. |
| `data-bs-value` | Class name or attribute value to toggle. Without it, nothing happens. |
| `data-bs-value` | Class name or attribute value to toggle. You can give several class names separated by spaces. Without it, nothing happens. |
### JavaScript
@@ -92,6 +92,8 @@ toggler.toggle()
| `toggle.bs.toggler` | Fires before the change. Call `event.preventDefault()` to stop it. |
| `toggled.bs.toggler` | Fires after the change. |
Both events fire on the element that changes. With `data-bs-target`, this is the target, not the trigger.
```js
document.getElementById('my-element').addEventListener('toggled.bs.toggler', () => {
// do something
@@ -101,5 +103,5 @@ document.getElementById('my-element').addEventListener('toggled.bs.toggler', ()
## Accessibility
- Use a `<button>` as the trigger, so it works with the keyboard.
- Toggler does not change ARIA attributes. If the change shows or hides content, keep `aria-expanded` or `aria-pressed` in sync in a `toggled.bs.toggler` listener, or use [Collapse](/ui/components/accordion) instead.
- Toggler does not change ARIA attributes. If the change shows or hides content, keep `aria-expanded` or `aria-pressed` in sync in a `toggled.bs.toggler` listener, or use [Accordion](/ui/components/accordion) instead.
- A trigger with the `disabled` attribute or the `.disabled` class does nothing.
+3 -3
View File
@@ -48,12 +48,12 @@ const colors = ['blue-lt', 'green-lt', 'orange-lt'] as const
<Card>
<CardBody>
<CardTitle>Multiple elements</CardTitle>
<CardSubtitle>A class selector toggles every match, each with its own value.</CardSubtitle>
<button type="button" class="btn mb-3" data-bs-toggle="toggler" data-bs-target=".toggler-target">Toggle all</button>
<CardSubtitle>A selector with many matches toggles every one, each with its own value.</CardSubtitle>
<button type="button" class="btn mb-3" data-bs-toggle="toggler" data-bs-target="[data-toggler-demo]">Toggle all</button>
<div class="space-y-2">
{
colors.map((color) => (
<div class="toggler-target p-3 rounded border" data-bs-value={`bg-${color}`}>
<div class="p-3 rounded border" data-toggler-demo data-bs-value={`bg-${color}`}>
Toggles <code>bg-{color}</code>
</div>
))