Skip to content

Commit

Permalink
feat: Button Toggle: Add ability for consumers to handle toggling pre…
Browse files Browse the repository at this point in the history
…ssed state (#5154)

* feat: Button Toggle: Add ability to wait for a promise to resolve before toggling

* feedback: add update function instead of promise

* add documentation and tests, update demo title
  • Loading branch information
margaree authored Nov 14, 2024
1 parent 85b6221 commit 9d8a9c3
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 3 deletions.
20 changes: 17 additions & 3 deletions components/button/button-toggle.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { css, html, LitElement } from 'lit';

/**
* A button container component for button toggles.
* @fires d2l-button-toggle-before-change - Dispatched before pressed state is updated. Can be canceled to allow the consumer to handle toggling pressed state. This is useful if something needs to happen prior to the pressed state being toggled.
*/
class ButtonToggle extends LitElement {

Expand Down Expand Up @@ -79,9 +80,16 @@ class ButtonToggle extends LitElement {
}

async _handleClick(pressed) {
this.pressed = pressed;
await this.updateComplete;
this.focus();
const beforeToggleEvent = new CustomEvent('d2l-button-toggle-before-change', {
detail: {
update: (newPressed) => this._updatePressedState(newPressed)
},
cancelable: true
});
this.dispatchEvent(beforeToggleEvent);
if (beforeToggleEvent.defaultPrevented) return;

this._updatePressedState(pressed);
}

_handleNotPressedClick() {
Expand All @@ -92,6 +100,12 @@ class ButtonToggle extends LitElement {
this._handleClick(false);
}

async _updatePressedState(newPressed) {
this.pressed = newPressed;
await this.updateComplete;
this.focus();
}

}

customElements.define('d2l-button-toggle', ButtonToggle);
20 changes: 20 additions & 0 deletions components/button/demo/button-toggle.html
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,26 @@ <h2>Toggle Button (disabled)</h2>
</template>
</d2l-demo-snippet>

<h2>Toggle Button (with consumer specifying when to toggle)</h2>

<d2l-demo-snippet>
<template>
<d2l-button-toggle id="toggle-button-icon-promise-delay">
<d2l-button-icon slot="not-pressed" icon="tier1:pin-hollow" text="Unpinned, click to pin."></d2l-button-icon>
<d2l-button-icon slot="pressed" icon="tier1:pin-filled" text="Pinned, click to unpin."></d2l-button-icon>
</d2l-button-toggle>
<script>
document.querySelector('#toggle-button-icon-promise-delay').addEventListener('d2l-button-toggle-before-change', e => {
e.preventDefault();
setTimeout(() => {
e.detail.update(!e.target.pressed);
}, 2000);
});
document.querySelector('#toggle-button-icon-promise-delay').addEventListener('d2l-button-toggle-change', e => console.log(e));
</script>
</template>
</d2l-demo-snippet>

</d2l-demo-page>

</body>
Expand Down
31 changes: 31 additions & 0 deletions components/button/test/button-toggle.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -63,4 +63,35 @@ describe('d2l-button-toggle', () => {

});

describe('consumer manages state', () => {

let el;
beforeEach(async() => {
el = await fixture(html`
<d2l-button-toggle>
<d2l-button-icon slot="not-pressed" icon="tier1:pin-hollow" text="Unpinned, click to pin."></d2l-button-icon>
<d2l-button-icon slot="pressed" icon="tier1:pin-filled" text="Pinned, click to unpin."></d2l-button-icon>
</d2l-button-toggle>
`);
});

it('click with no state management', async() => {
el.addEventListener('d2l-button-toggle-before-change', (e) => {
e.preventDefault();
});
await clickElem(el.querySelector('[slot="not-pressed"]'));
expect(el.pressed).to.equal(false);
});

it('click once with state management', async() => {
el.addEventListener('d2l-button-toggle-before-change', (e) => {
e.preventDefault();
e.detail.update(!e.target.pressed);
});
clickElem(el.querySelector('[slot="not-pressed"]'));
const e = await oneEvent(el, 'd2l-button-toggle-change');
expect(e.target.pressed).to.equal(true);
});
});

});

0 comments on commit 9d8a9c3

Please sign in to comment.