From 9eed635fa46f54224216c93de9e5c96bdd340898 Mon Sep 17 00:00:00 2001 From: Margaree Peacocke Date: Tue, 12 Nov 2024 10:12:39 -0500 Subject: [PATCH] feat: button toggle: Allow consumer to control pressed state (#5143) * feat: button toggle: Allow consumer to control pressed state * code review feedback: use an event approach instead * add vdiffs * code review feedback: add unit tests instead of vdiff tests. fix wca * code review feedback: fix up tests * test tweak: await clickElem instead --- components/button/button-toggle.js | 16 +++++++-- components/button/demo/button-toggle.html | 24 ++++++++++++++ components/button/test/button-toggle.test.js | 35 ++++++++++++++++++++ 3 files changed, 73 insertions(+), 2 deletions(-) diff --git a/components/button/button-toggle.js b/components/button/button-toggle.js index ae81c4f9a6..4aee8f32a3 100644 --- a/components/button/button-toggle.js +++ b/components/button/button-toggle.js @@ -2,6 +2,7 @@ import { css, html, LitElement } from 'lit'; /** * A button container component for button toggles. + * @fires click - Internal event */ class ButtonToggle extends LitElement { @@ -78,17 +79,28 @@ class ButtonToggle extends LitElement { elem.focus(); } + _clickCancelled(e) { + e.stopPropagation(); + const customClick = new CustomEvent('click', { + cancelable: true + }); + e.target.dispatchEvent(customClick); + return customClick.defaultPrevented; + } + async _handleClick(pressed) { this.pressed = pressed; await this.updateComplete; this.focus(); } - _handleNotPressedClick() { + _handleNotPressedClick(e) { + if (this._clickCancelled(e)) return; this._handleClick(true); } - _handlePressedClick() { + _handlePressedClick(e) { + if (this._clickCancelled(e)) return; this._handleClick(false); } diff --git a/components/button/demo/button-toggle.html b/components/button/demo/button-toggle.html index cef6079c49..19518be2a5 100644 --- a/components/button/demo/button-toggle.html +++ b/components/button/demo/button-toggle.html @@ -54,6 +54,30 @@

Toggle Button (disabled)

+

Toggle Button (consumer manages state)

+ + + + + diff --git a/components/button/test/button-toggle.test.js b/components/button/test/button-toggle.test.js index 9b3a12e6fb..101639feda 100644 --- a/components/button/test/button-toggle.test.js +++ b/components/button/test/button-toggle.test.js @@ -63,4 +63,39 @@ describe('d2l-button-toggle', () => { }); + describe('consumer manages state', () => { + + let el; + beforeEach(async() => { + el = await fixture(html` + + + + + `); + }); + + it('click with no state management', async() => { + el.querySelectorAll('d2l-button-icon') + .forEach(b => b.addEventListener('click', e => e.preventDefault())); + await clickElem(el.querySelector('[slot="not-pressed"]')); + expect(el.pressed).to.equal(false); + }); + + it('click once with state management', async() => { + const buttonIcons = el.querySelectorAll('d2l-button-icon'); + buttonIcons[0].addEventListener('click', (e) => { + e.preventDefault(); + el.pressed = true; + }); + buttonIcons[1].addEventListener('click', (e) => { + e.preventDefault(); + el.pressed = false; + }); + clickElem(el.querySelector('[slot="not-pressed"]')); + const e = await oneEvent(el, 'd2l-button-toggle-change'); + expect(e.target.pressed).to.equal(true); + }); + }); + });