Socket
Socket
Sign inDemoInstall

@lion/switch

Package Overview
Dependencies
Maintainers
1
Versions
132
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@lion/switch - npm Package Compare versions

Comparing version 0.11.2 to 0.12.0

index.d.ts

20

CHANGELOG.md
# Change Log
## 0.12.0
### Minor Changes
- 06123918: Add types for switch package.
### Patch Changes
- 85720654: - prevent toggle of checked state when disabled
- dispatch checked-changed on label click
- Updated dependencies [4b7bea96]
- Updated dependencies [01a798e5]
- Updated dependencies [a31b7217]
- Updated dependencies [85720654]
- Updated dependencies [32202a88]
- Updated dependencies [b9327627]
- Updated dependencies [02145a06]
- @lion/form-core@0.6.2
- @lion/core@0.13.0
## 0.11.2

@@ -4,0 +24,0 @@

6

package.json
{
"name": "@lion/switch",
"version": "0.11.2",
"version": "0.12.0",
"description": "A Switch is used for switching a property or feature on and off",

@@ -36,4 +36,4 @@ "license": "MIT",

"dependencies": {
"@lion/core": "0.12.0",
"@lion/form-core": "0.6.1"
"@lion/core": "0.13.0",
"@lion/form-core": "0.6.2"
},

@@ -40,0 +40,0 @@ "keywords": [

@@ -5,2 +5,3 @@ import { css, html, ScopedElementsMixin } from '@lion/core';

// @ts-expect-error https://github.com/microsoft/TypeScript/issues/40110
export class LionSwitch extends ScopedElementsMixin(ChoiceInputMixin(LionField)) {

@@ -29,6 +30,22 @@ static get styles() {

/**
* Input node here is the lion-switch-button, which is not compatible with LionField _inputNode --> HTMLInputElement
* Therefore we do a full override and typecast to an intersection type that includes LionSwitchButton
* @returns {HTMLInputElement & LionSwitchButton}
*/
get _inputNode() {
return /** @type {HTMLInputElement & LionSwitchButton} */ (Array.from(this.children).find(
el => el.slot === 'input',
));
}
get slots() {
return {
...super.slots,
input: () => document.createElement(this.constructor.getScopedTagName('lion-switch-button')),
input: () =>
document.createElement(
/** @type {typeof LionSwitch} */ (this.constructor).getScopedTagName(
'lion-switch-button',
),
),
};

@@ -56,8 +73,14 @@ }

constructor() {
super();
this.role = 'switch';
this.checked = false;
this.__handleButtonSwitchCheckedChanged = this.__handleButtonSwitchCheckedChanged.bind(this);
}
connectedCallback() {
super.connectedCallback();
this._inputNode.addEventListener(
'checked-changed',
this.__handleButtonSwitchCheckedChanged.bind(this),
);
if (this._inputNode) {
this._inputNode.addEventListener('checked-changed', this.__handleButtonSwitchCheckedChanged);
}
if (this._labelNode) {

@@ -71,2 +94,8 @@ this._labelNode.addEventListener('click', this.__toggleChecked);

disconnectedCallback() {
if (this._inputNode) {
this._inputNode.removeEventListener(
'checked-changed',
this.__handleButtonSwitchCheckedChanged,
);
}
if (this._labelNode) {

@@ -77,2 +106,3 @@ this._labelNode.removeEventListener('click', this.__toggleChecked);

/** @param {import('lit-element').PropertyValues } changedProperties */
updated(changedProperties) {

@@ -87,3 +117,5 @@ super.updated(changedProperties);

// eslint-disable-next-line class-methods-use-this
_isEmpty() {}
_isEmpty() {
return false;
}

@@ -95,5 +127,4 @@ __handleButtonSwitchCheckedChanged() {

_syncButtonSwitch() {
this._inputNode.checked = this.checked;
this._inputNode.disabled = this.disabled;
}
}

@@ -77,5 +77,5 @@ import { html, css, LitElement, DisabledWithTabIndexMixin } from '@lion/core';

this.checked = false;
this.addEventListener('click', this.__handleToggleStateChange);
this.addEventListener('keydown', this.__handleKeydown);
this.addEventListener('keyup', this.__handleKeyup);
this.__toggleChecked = this.__toggleChecked.bind(this);
this.__handleKeydown = this.__handleKeydown.bind(this);
this.__handleKeyup = this.__handleKeyup.bind(this);
}

@@ -86,5 +86,15 @@

this.setAttribute('aria-checked', `${this.checked}`);
this.addEventListener('click', this.__toggleChecked);
this.addEventListener('keydown', this.__handleKeydown);
this.addEventListener('keyup', this.__handleKeyup);
}
__handleToggleStateChange() {
disconnectedCallback() {
super.disconnectedCallback();
this.removeEventListener('click', this.__toggleChecked);
this.removeEventListener('keydown', this.__handleKeydown);
this.removeEventListener('keyup', this.__handleKeyup);
}
__toggleChecked() {
if (this.disabled) {

@@ -96,2 +106,5 @@ return;

this.checked = !this.checked;
}
__checkedStateChange() {
this.dispatchEvent(

@@ -103,4 +116,8 @@ new Event('checked-changed', {

);
this.setAttribute('aria-checked', `${this.checked}`);
}
/**
* @param {KeyboardEvent} e
*/
// eslint-disable-next-line class-methods-use-this

@@ -114,8 +131,12 @@ __handleKeydown(e) {

/**
* @param {KeyboardEvent} e
*/
__handleKeyup(e) {
if ([32 /* space */, 13 /* enter */].indexOf(e.keyCode) !== -1) {
this.__handleToggleStateChange();
this.__toggleChecked();
}
}
/** @param {import('lit-element').PropertyValues } changedProperties */
updated(changedProperties) {

@@ -130,2 +151,4 @@ if (changedProperties.has('disabled')) {

*
* @param {PropertyKey} name
* @param {?} oldValue
* @override

@@ -135,6 +158,6 @@ */

super.requestUpdateInternal(name, oldValue);
if (this.isConnected && name === 'checked') {
this.setAttribute('aria-checked', `${this.checked}`);
if (this.isConnected && name === 'checked' && this.checked !== oldValue) {
this.__checkedStateChange();
}
}
}

@@ -1,6 +0,14 @@

import { expect, fixture, html } from '@open-wc/testing';
import { expect, fixture as _fixture, html } from '@open-wc/testing';
import sinon from 'sinon';
import '../lion-switch-button.js';
/**
* @typedef {import('../src/LionSwitchButton').LionSwitchButton} LionSwitchButton
* @typedef {import('lit-html').TemplateResult} TemplateResult
*/
const fixture = /** @type {(arg: TemplateResult) => Promise<LionSwitchButton>} */ (_fixture);
describe('lion-switch-button', () => {
/** @type {LionSwitchButton} */
let el;

@@ -65,4 +73,4 @@ beforeEach(async () => {

expect(handlerSpy.callCount).to.equal(2);
const checkCall = call => {
expect(call.args).to.have.a.lengthOf(1);
const checkCall = /** @param {import('sinon').SinonSpyCall} call */ call => {
expect(call.args).to.have.lengthOf(1);
const e = call.args[0];

@@ -73,6 +81,23 @@ expect(e).to.be.an.instanceof(Event);

};
checkCall(handlerSpy.getCall(0), true);
checkCall(handlerSpy.getCall(1), false);
checkCall(handlerSpy.getCall(0));
checkCall(handlerSpy.getCall(1));
});
it('should dispatch "checked-changed" event when checked changed', () => {
const handlerSpy = sinon.spy();
el.addEventListener('checked-changed', handlerSpy);
el.checked = true;
el.checked = false;
expect(handlerSpy.callCount).to.equal(2);
const checkCall = /** @param {import('sinon').SinonSpyCall} call */ call => {
expect(call.args).to.have.lengthOf(1);
const e = call.args[0];
expect(e).to.be.an.instanceof(Event);
expect(e.bubbles).to.be.true;
expect(e.composed).to.be.true;
};
checkCall(handlerSpy.getCall(0));
checkCall(handlerSpy.getCall(1));
});
it('should not dispatch "checked-changed" event if disabled', () => {

@@ -105,3 +130,3 @@ const handlerSpy = sinon.spy();

el.setAttribute('checked', true);
el.setAttribute('checked', '');
await el.updateComplete;

@@ -108,0 +133,0 @@ expect(el.getAttribute('aria-checked')).to.equal('true');

@@ -1,4 +0,12 @@

import { expect, fixture, html } from '@open-wc/testing';
import { expect, fixture as _fixture, html } from '@open-wc/testing';
import sinon from 'sinon';
import '../lion-switch.js';
/**
* @typedef {import('../src/LionSwitch').LionSwitch} LionSwitch
* @typedef {import('lit-html').TemplateResult} TemplateResult
*/
const fixture = /** @type {(arg: TemplateResult) => Promise<LionSwitch>} */ (_fixture);
describe('lion-switch', () => {

@@ -18,2 +26,8 @@ it('should have default "input" element', async () => {

it('clicking the label should not toggle the checked state when disabled', async () => {
const el = await fixture(html`<lion-switch disabled label="Enable Setting"></lion-switch>`);
el._labelNode.click();
expect(el.checked).to.be.false;
});
it('should sync its "disabled" state to child button', async () => {

@@ -72,2 +86,30 @@ const el = await fixture(html`<lion-switch disabled></lion-switch>`);

it('should dispatch "checked-changed" event when toggled via button or label', async () => {
const handlerSpy = sinon.spy();
const el = await fixture(html`<lion-switch .choiceValue=${'foo'}></lion-switch>`);
el.addEventListener('checked-changed', handlerSpy);
el._inputNode.click();
el._labelNode.click();
await el.updateComplete;
expect(handlerSpy.callCount).to.equal(2);
const checkCall = /** @param {import('sinon').SinonSpyCall} call */ call => {
expect(call.args).to.have.lengthOf(1);
const e = call.args[0];
expect(e).to.be.an.instanceof(Event);
expect(e.bubbles).to.be.true;
expect(e.composed).to.be.true;
};
checkCall(handlerSpy.getCall(0));
checkCall(handlerSpy.getCall(1));
});
it('should dispatch "checked-changed" event when checked changed', async () => {
const handlerSpy = sinon.spy();
const el = await fixture(html`<lion-switch .choiceValue=${'foo'}></lion-switch>`);
el.addEventListener('checked-changed', handlerSpy);
el.checked = true;
await el.updateComplete;
expect(handlerSpy.callCount).to.equal(1);
});
it('is submitted by default', async () => {

@@ -74,0 +116,0 @@ const el = await fixture(html`<lion-switch></lion-switch>`);

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc