diff --git a/.changeset/fix-confetti-target-options.md b/.changeset/fix-confetti-target-options.md new file mode 100644 index 000000000..f0a55b8cb --- /dev/null +++ b/.changeset/fix-confetti-target-options.md @@ -0,0 +1,6 @@ +--- +"@tabler/core": patch +"@tabler/docs": patch +--- + +Fixed Confetti ignoring the trigger's `data-bs-*` options when `data-bs-target` points elsewhere. diff --git a/core/js/src/confetti.ts b/core/js/src/confetti.ts index 6da6056f7..8ae25b1e3 100644 --- a/core/js/src/confetti.ts +++ b/core/js/src/confetti.ts @@ -7,6 +7,7 @@ import BaseComponent from './bootstrap/base-component' import EventHandler from './bootstrap/dom/event-handler' +import Manipulator from './bootstrap/dom/manipulator' import SelectorEngine from './bootstrap/dom/selector-engine' import { isDisabled } from './bootstrap/util/index' import type { ComponentConfig as BaseConfig, ElementSelector } from './bootstrap/types' @@ -432,7 +433,16 @@ EventHandler.on(document, EVENT_CLICK_DATA_API, SELECTOR_DATA_TOGGLE, function ( } const target = SelectorEngine.getElementFromSelector(this) || this - const instance = Confetti.getOrCreateInstance(target) as Confetti + const config = Manipulator.getDataAttributes(this) + const instance = Confetti.getOrCreateInstance(target, config) as Confetti + + // The instance lives on the target and keeps the config it was created + // with, so re-read the trigger's options on every click; several triggers + // can then share one target with their own look. + if (target !== this) { + instance._config = instance._getConfig(config) as ComponentConfig + } + instance.burst() }) diff --git a/core/js/tests/unit/confetti.spec.ts b/core/js/tests/unit/confetti.spec.ts index 61d4e87d1..9cb73615b 100644 --- a/core/js/tests/unit/confetti.spec.ts +++ b/core/js/tests/unit/confetti.spec.ts @@ -171,6 +171,33 @@ describe('Confetti', () => { expect(Confetti.getInstance(fixtureEl.querySelector('a')!)).toBeNull() }) + it('should read options from the trigger even when data-bs-target points elsewhere', () => { + fixtureEl.innerHTML = '
' + reduceMotion(true) + + button().click() + + const instance = Confetti.getInstance(fixtureEl.querySelector('#order')!) as Confetti + expect(instance).not.toBeNull() + expect(instance._config.count).toBe(5) + expect(instance._config.colors).toEqual(['#f00']) + }) + + it("should apply each trigger's own options when several share a target", () => { + fixtureEl.innerHTML = '' + reduceMotion(true) + const target = fixtureEl.querySelector('#order')! + + fixtureEl.querySelector