diff --git a/.changeset/silent-steaks-marry.md b/.changeset/silent-steaks-marry.md new file mode 100644 index 000000000..51041d07c --- /dev/null +++ b/.changeset/silent-steaks-marry.md @@ -0,0 +1,5 @@ +--- +'@lion/input-stepper': patch +--- + +fix(input-stepper): make use of prefix and suffix slots diff --git a/packages/input-stepper/src/LionInputStepper.js b/packages/input-stepper/src/LionInputStepper.js index 8eddc12e1..9e760be82 100644 --- a/packages/input-stepper/src/LionInputStepper.js +++ b/packages/input-stepper/src/LionInputStepper.js @@ -34,8 +34,6 @@ export class LionInputStepper extends LionInput { type: Number, reflect: true, }, - __disableIncrementor: { attribute: false }, - __disableDecrementor: { attribute: false }, }; } @@ -50,8 +48,6 @@ export class LionInputStepper extends LionInput { super(); /** @param {string} modelValue */ this.parser = modelValue => parseFloat(modelValue); - this.__disableIncrementor = false; - this.__disableDecrementor = false; this.min = Infinity; this.max = Infinity; this.step = 1; @@ -104,6 +100,15 @@ export class LionInputStepper extends LionInput { } } + // @ts-ignore + get slots() { + return { + ...super.slots, + prefix: () => this.__getDecrementButtonNode(), + suffix: () => this.__getIncrementButtonNode(), + }; + } + /** * Set aria labels and apply validators * @private @@ -150,8 +155,12 @@ export class LionInputStepper extends LionInput { */ __toggleSpinnerButtonsState() { const { min, max } = this.values; - this.__disableIncrementor = this.currentValue >= max && max !== Infinity; - this.__disableDecrementor = this.currentValue <= min && min !== Infinity; + const decrementButton = this.__getSlot('prefix'); + const incrementButton = this.__getSlot('suffix'); + const disableIncrementor = this.currentValue >= max && max !== Infinity; + const disableDecrementor = this.currentValue <= min && min !== Infinity; + decrementButton[disableDecrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); + incrementButton[disableIncrementor ? 'setAttribute' : 'removeAttribute']('disabled', 'true'); this.setAttribute('aria-valuenow', `${this.currentValue}`); this.dispatchEvent( new CustomEvent('user-input-changed', { @@ -160,6 +169,19 @@ export class LionInputStepper extends LionInput { ); } + /** + * Get slotted element + * @param {String} slotName - slot name + * @returns {HTMLButtonElement|Object} + */ + __getSlot(slotName) { + return ( + /** @type {HTMLElement[]} */ (Array.from(this.children)).find( + child => child.slot === slotName, + ) || {} + ); + } + /** * Increment the value based on given step or default step value is 1 * @private @@ -186,6 +208,40 @@ export class LionInputStepper extends LionInput { } } + /** + * Get the increment button node + * @returns {Element|null} + */ + __getIncrementButtonNode() { + const renderParent = document.createElement('div'); + /** @type {typeof LionInputStepper} */ (this.constructor).render( + this._incrementorTemplate(), + renderParent, + { + scopeName: this.localName, + eventContext: this, + }, + ); + return renderParent.firstElementChild; + } + + /** + * Get the decrement button node + * @returns {Element|null} + */ + __getDecrementButtonNode() { + const renderParent = document.createElement('div'); + /** @type {typeof LionInputStepper} */ (this.constructor).render( + this._decrementorTemplate(), + renderParent, + { + scopeName: this.localName, + eventContext: this, + }, + ); + return renderParent.firstElementChild; + } + /** * Toggle +/- buttons on change * @override @@ -196,61 +252,56 @@ export class LionInputStepper extends LionInput { } /** - * Override after template to none - * @override + * Get the decrementor button sign template + * @returns {String|import('lit-element').TemplateResult} */ // eslint-disable-next-line class-methods-use-this - _inputGroupAfterTemplate() { - return html``; + _decrementorSignTemplate() { + return '-'; } /** - * Override before template to none - * @override + * Get the incrementor button sign template + * @returns {String|import('lit-element').TemplateResult} */ // eslint-disable-next-line class-methods-use-this - _inputGroupBeforeTemplate() { - return html``; + _incrementorSignTemplate() { + return '+'; } /** - * Override prefix template for the increment button - * @override + * Get the increment button template + * @returns {import('lit-element').TemplateResult} */ - // eslint-disable-next-line class-methods-use-this - _inputGroupPrefixTemplate() { + _decrementorTemplate() { return html` `; } /** - * Override suffix template for the decrement button and add after slot - * @override + * Get the decrement button template + * @returns {import('lit-element').TemplateResult} */ - // eslint-disable-next-line class-methods-use-this - _inputGroupSuffixTemplate() { + _incrementorTemplate() { return html` - `; } } diff --git a/packages/input-stepper/test/lion-input-stepper.test.js b/packages/input-stepper/test/lion-input-stepper.test.js index ec542dd9e..f50596975 100644 --- a/packages/input-stepper/test/lion-input-stepper.test.js +++ b/packages/input-stepper/test/lion-input-stepper.test.js @@ -24,7 +24,7 @@ describe('', () => { it('should increment the value to 1 on + button click', async () => { const el = await fixture(defaultInputStepper); expect(el.value).to.equal(''); - const incrementButton = el.shadowRoot?.querySelector('[name=increment]'); + const incrementButton = el.querySelector('[slot=suffix]'); incrementButton?.dispatchEvent(new Event('click')); expect(el.value).to.equal('1'); }); @@ -32,8 +32,8 @@ describe('', () => { it('should decrement the value to -1 on - button click', async () => { const el = await fixture(defaultInputStepper); expect(el.value).to.equal(''); - const incrementButton = el.shadowRoot?.querySelector('[name=decrement]'); - incrementButton?.dispatchEvent(new Event('click')); + const decrementButton = el.querySelector('[slot=prefix]'); + decrementButton?.dispatchEvent(new Event('click')); expect(el.value).to.equal('-1'); }); @@ -66,7 +66,7 @@ describe('', () => { it('updates aria-valuenow when stepper is changed', async () => { const el = await fixture(inputStepperWithAttrs); - const incrementButton = el.shadowRoot?.querySelector('[name=increment]'); + const incrementButton = el.querySelector('[slot=suffix]'); incrementButton?.dispatchEvent(new Event('click')); expect(el).to.have.attribute('aria-valuenow', '1'); });