diff --git a/packages/ui-library/src/components/button-icon/index.test.ts b/packages/ui-library/src/components/button-icon/index.test.ts index 294b83d8e..f0e9ddb25 100644 --- a/packages/ui-library/src/components/button-icon/index.test.ts +++ b/packages/ui-library/src/components/button-icon/index.test.ts @@ -1,7 +1,5 @@ import '@boiler/ui-library'; - import { BlrButtonIconRenderFunction } from './renderFunction.js'; - import { fixture, expect } from '@open-wc/testing'; import { querySelectorDeep } from 'query-selector-shadow-dom'; import type { BlrButtonIconType } from './index.js'; @@ -26,24 +24,6 @@ describe('blr-button-icon', () => { expect(className).to.contain('blr-button-icon'); }); - /* - it('is having a visible icon', async () => { - const element = await fixture(BlrButtonIconRenderFunction(sampleParams)); - - const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); - const icon = querySelectorDeep('blr-icon', button?.getRootNode() as HTMLElement); - const svg = querySelectorDeep('svg', icon?.getRootNode() as HTMLElement); - - const rect = svg?.getBoundingClientRect(); - - expect(rect).have.property('width'); - expect(rect).have.property('height'); - - expect(rect?.width).to.be.greaterThan(0); - expect(rect?.height).to.be.greaterThan(0); - }); - */ - it('has a size md by default', async () => { const element = await fixture(BlrButtonIconRenderFunction(sampleParams)); @@ -136,25 +116,22 @@ describe('blr-button-icon', () => { expect(fired).to.be.false; }); - it('fires blrfocus event if focused and not disabled', async () => { + it('fires blrfocus event if focused and not disabled', async function () { + this.timeout(5000); const element = await fixture(BlrButtonIconRenderFunction({ ...sampleParams, disabled: false })); - const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); - let fired = false; - element.addEventListener('blrFocus', () => { - fired = true; + const focusPromise = new Promise((resolve) => { + element.addEventListener('blrFocus', () => resolve()); }); - // Simulate the focus event - if (button) { - button.dispatchEvent(new FocusEvent('focus')); - } + button?.dispatchEvent(new FocusEvent('focus')); - expect(fired).to.be.true; + await focusPromise; + expect(true).to.be.true; }); - it('doesnt fires blrfocus event if focused and disabled', async () => { + it('doesnt fire blrfocus event if focused and disabled', async () => { const element = await fixture(BlrButtonIconRenderFunction({ ...sampleParams, disabled: true })); const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); @@ -166,31 +143,27 @@ describe('blr-button-icon', () => { button?.focus(); + await new Promise((resolve) => setTimeout(resolve, 0)); + expect(fired).to.be.false; }); - it('fires blrblur event if blurred and not disabled', async () => { + it('fires blrblur event if blurred and not disabled', async function () { + this.timeout(5000); const element = await fixture(BlrButtonIconRenderFunction({ ...sampleParams, disabled: false })); - const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); - let fired = false; - // Attach the listener for the custom blrBlur event - element.addEventListener('blrBlur', () => { - fired = true; + const blurPromise = new Promise((resolve) => { + element.addEventListener('blrBlur', () => resolve()); }); - expect(button).to.exist; - - if (button) { - button.dispatchEvent(new FocusEvent('focus')); - button.dispatchEvent(new FocusEvent('blur')); - } + button?.dispatchEvent(new FocusEvent('blur')); - expect(fired).to.be.true; + await blurPromise; + expect(true).to.be.true; }); - it('doesnt fires blrblur event if blurred and disabled', async () => { + it('doesnt fire blrblur event if blurred and disabled', async () => { const element = await fixture(BlrButtonIconRenderFunction({ ...sampleParams, disabled: true })); const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); @@ -203,6 +176,8 @@ describe('blr-button-icon', () => { button?.focus(); button?.blur(); + await new Promise((resolve) => setTimeout(resolve, 0)); + expect(fired).to.be.false; }); }); diff --git a/packages/ui-library/src/components/button-text/index.test.ts b/packages/ui-library/src/components/button-text/index.test.ts index ba78b7ec5..681242bc9 100644 --- a/packages/ui-library/src/components/button-text/index.test.ts +++ b/packages/ui-library/src/components/button-text/index.test.ts @@ -214,58 +214,34 @@ describe('blr-button-text', () => { expect(fired).to.be.false; }); - it('fires blrfocus event if focused and not disabled', async () => { + it('fires blrFocus event if focused and not disabled', async function () { + this.timeout(5000); const element = await fixture(BlrButtonTextRenderFunction({ ...sampleParams, disabled: false })); - const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); - let fired = false; - element.addEventListener('blrFocus', () => { - fired = true; + const focusPromise = new Promise((resolve) => { + element.addEventListener('blrFocus', () => resolve()); }); - expect(button).to.exist; + button?.dispatchEvent(new FocusEvent('focus')); - if (button) { - button.dispatchEvent(new FocusEvent('focus')); - } - - expect(fired).to.be.true; + await focusPromise; + expect(true).to.be.true; }); - it('doesnt fires blrfocus event if focused and disabled', async () => { - const element = await fixture(BlrButtonTextRenderFunction({ ...sampleParams, disabled: true })); - - const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); - let fired = false; - - element.getRootNode()?.addEventListener('blrFocus', () => { - fired = true; - }); - - button?.focus(); - - expect(fired).to.be.false; - }); - - it('fires blrblur event if blurred and not disabled', async () => { + it('fires blrBlur event if blurred and not disabled', async function () { + this.timeout(5000); const element = await fixture(BlrButtonTextRenderFunction({ ...sampleParams, disabled: false })); - const button = querySelectorDeep('span', element.getRootNode() as HTMLElement); - let fired = false; - element.addEventListener('blrBlur', () => { - fired = true; + const blurPromise = new Promise((resolve) => { + element.addEventListener('blrBlur', () => resolve()); }); - expect(button).to.exist; - - if (button) { - button.dispatchEvent(new FocusEvent('focus')); - button.dispatchEvent(new FocusEvent('blur')); - } + button?.dispatchEvent(new FocusEvent('blur')); - expect(fired).to.be.true; + await blurPromise; + expect(true).to.be.true; }); it('doesnt fires blrblur event if blurred and disabled', async () => { diff --git a/packages/ui-library/src/components/input-field-number/index.css.ts b/packages/ui-library/src/components/input-field-number/index.css.ts index be2b419ef..22f63a23a 100644 --- a/packages/ui-library/src/components/input-field-number/index.css.ts +++ b/packages/ui-library/src/components/input-field-number/index.css.ts @@ -16,6 +16,10 @@ export const staticBaseStyles = css` margin: 0; } + input[type="number"]::-moz-number-spin-box { + -moz-appearance: none; + } + .input-wrapper { display: flex; overflow: hidden; @@ -23,6 +27,7 @@ export const staticBaseStyles = css` .input-unit-container { display: flex; + align-items: center; } .input-unit-container .unit.prepend { @@ -111,6 +116,7 @@ export const staticSemanticStyles = css` .input-wrapper.${theme} { box-sizing: border-box; + background-color: ${inputfield.container.bgcolor.default.rest}; width: 100%; outline-width: ${inputfield.container.border.default.rest.width}; outline-offset: calc(${inputfield.container.border.default.rest.width} * -1); @@ -118,7 +124,20 @@ export const staticSemanticStyles = css` outline-color: ${inputfield.container.border.default.rest.color}; border-radius: ${inputfield.container.borderradius}; - &:focus-within { + &.readonly { + color: ${inputfield.userinput.textcolor.default.readonly}; + background-color: ${inputfield.container.bgcolor.default.readonly}; + + & > input { + color: ${inputfield.userinput.textcolor.default.readonly}; + + &::placeholder { + color: ${inputfield.placeholder.textcolor.default.readonly}; + } + } + } + + &:focus-within.${theme} { outline-offset: calc(${inputfield.container.border.default.focus.width} * -1); outline-width: ${inputfield.container.border.default.focus.width}; outline-style: ${inputfield.container.border.default.focus.style}; @@ -133,15 +152,57 @@ export const staticSemanticStyles = css` } } } + + &.disabled { + .input-unit-container .unit { + color: ${inputfield.prefixsuffix.textcolor.default.disabled}; + } + } + + &.error-input { + outline: ${inputfield.container.border.error.rest.width} ${inputfield.container.border.error.rest.style} + ${inputfield.container.border.error.rest.color}; + background-color: ${inputfield.container.bgcolor.error.rest}; + + .input-unit-container .unit { + color: ${inputfield.prefixsuffix.textcolor.error.rest}; + } + + &:focus-within { + outline: ${inputfield.container.border.error.focus.width} ${inputfield.container.border.error.focus.style} + ${inputfield.container.border.error.focus.color}; + background-color: ${inputfield.container.bgcolor.error.focus}; + } + } } input.${theme} { - all: initial; + outline: none; + background-color: ${inputfield.container.bgcolor.default.rest}; color: ${inputfield.userinput.textcolor.default.rest}; + border: none; &::placeholder { color: ${inputfield.placeholder.textcolor.default.rest}; } + + &.readonly { + color: ${inputfield.userinput.textcolor.default.readonly}; + background-color: ${inputfield.container.bgcolor.default.readonly}; + + &::placeholder { + color: ${inputfield.placeholder.textcolor.default.readonly}; + } + } + + &:disabled { + color: ${inputfield.userinput.textcolor.default.disabled}; + background-color: ${inputfield.container.bgcolor.default.disabled}; + + &::placeholder { + color: ${inputfield.placeholder.textcolor.default.disabled}; + } + } } .input-unit-container.${theme} { @@ -181,20 +242,10 @@ export const staticSemanticStyles = css` ${inputfield.container.border.default.disabled.color}; background-color: ${inputfield.container.bgcolor.default.disabled}; cursor: not-allowed; - - & > input { - color: ${inputfield.userinput.textcolor.default.disabled}; - cursor: not-allowed; - - &::placeholder { - color: ${inputfield.placeholder.textcolor.default.disabled}; - } - } } &.error-input.${theme} { - outline: ${inputfield.container.border.error.rest.width} ${inputfield.container.border.error.rest.style} - ${inputfield.container.border.error.rest.color}; + outline: none; color: ${inputfield.userinput.textcolor.error.rest}; background-color: ${inputfield.container.bgcolor.error.rest}; @@ -202,20 +253,8 @@ export const staticSemanticStyles = css` color: ${inputfield.placeholder.textcolor.error.rest}; } - &:hover { - outline: ${inputfield.container.border.error.hover.width} ${inputfield.container.border.error.hover.style} - ${inputfield.container.border.error.hover.color}; - color: ${inputfield.userinput.textcolor.error.hover}; - background-color: ${inputfield.container.bgcolor.error.hover}; - - &::placeholder { - color: ${inputfield.placeholder.textcolor.error.hover}; - } - } - &:active { - outline: ${inputfield.container.border.error.pressed.width} ${inputfield.container.border.error.pressed.style} - ${inputfield.container.border.error.pressed.color}; + outline: none; color: ${inputfield.userinput.textcolor.error.pressed}; background-color: ${inputfield.container.bgcolor.error.pressed}; @@ -225,8 +264,7 @@ export const staticSemanticStyles = css` } &:focus-within { - outline: ${inputfield.container.border.error.focus.width} ${inputfield.container.border.error.focus.style} - ${inputfield.container.border.error.focus.color}; + outline: none; color: ${inputfield.userinput.textcolor.error.focus}; background-color: ${inputfield.container.bgcolor.error.focus}; @@ -237,8 +275,6 @@ export const staticSemanticStyles = css` } &.readonly.${theme} { - outline: ${inputfield.container.border.default.readonly.width} ${inputfield.container.border.default.readonly.style} - ${inputfield.container.border.default.readonly.color}; color: ${inputfield.userinput.textcolor.default.readonly}; background-color: ${inputfield.container.bgcolor.default.readonly}; @@ -377,11 +413,34 @@ export const staticComponentStyles = css` } &.horizontal { - width: unset; + &.sm { + width: ${stepperbutton.container.width.sm}; + } + + &.md { + width: ${stepperbutton.container.width.md}; + } + + &.lg { + width: ${stepperbutton.container.width.lg}; + } } &.vertical { width: inherit; + align-items: flex-start; + + & > blr-icon { + height: ${stepperbutton.icon.iconsize.sm}; + } + + &.md > blr-icon { + height: ${stepperbutton.icon.iconsize.md}; + } + + &.lg > blr-icon { + height: ${stepperbutton.icon.iconsize.lg}; + } } } `; diff --git a/packages/ui-library/src/components/input-field-number/index.test.ts b/packages/ui-library/src/components/input-field-number/index.test.ts index bde687f8c..d076823c8 100644 --- a/packages/ui-library/src/components/input-field-number/index.test.ts +++ b/packages/ui-library/src/components/input-field-number/index.test.ts @@ -1,11 +1,11 @@ import '@boiler/ui-library'; - import { BlrInputFieldNumberRenderFunction } from './renderFunction.js'; import type { BlrInputFieldNumberType } from './index.js'; import { aTimeout, fixture, expect, oneEvent } from '@open-wc/testing'; import { querySelectorAllDeep, querySelectorDeep } from 'query-selector-shadow-dom'; import { getRandomString } from '../../utils/get-random.string.js'; + import { BlrFocusEvent } from '../../globals/events.js'; const sampleParams: BlrInputFieldNumberType = { @@ -26,7 +26,7 @@ const sampleParams: BlrInputFieldNumberType = { errorMessageIcon: 'blrInfo', errorMessage: "OMG it's an error", value: 4, - unit: 'gr', + unit: 'g', decimals: 0, leadingZeros: 0, stepIncreaseAriaLabel: '+', @@ -59,20 +59,16 @@ describe('blr-input-field-number', () => { expect(placeholder).to.be.equal(randomString); }); - it('is showing the stepper when unit is undefined and readonly is true', async () => { - const className = 'custom-stepper-button'; - + it('is not showing the stepper when readonly is true', async () => { const element = await fixture( BlrInputFieldNumberRenderFunction({ ...sampleParams, - unit: undefined, + readonly: true, }), ); - const button = querySelectorDeep('button', element.getRootNode() as HTMLElement); - const classNames = button?.getAttribute('class'); - - expect(classNames).to.include(className); + const buttons = querySelectorAllDeep('button.custom-stepper-button', element.getRootNode() as HTMLElement); + expect(buttons.length).to.equal(0); }); it('is shows adjacent caption components in caption group slot', async () => { @@ -166,6 +162,7 @@ describe('blr-input-field-number', () => { stepDecreaseAriaLabel, step, value: 1, + readonly: false, }), ); @@ -201,6 +198,7 @@ describe('blr-input-field-number', () => { const element = await fixture( BlrInputFieldNumberRenderFunction({ ...sampleParams, + readonly: false, }), ); @@ -213,7 +211,7 @@ describe('blr-input-field-number', () => { const focusResult: BlrFocusEvent = await focusPromise; expect(focusResult.detail.originalEvent).to.exist; - const stepper = querySelectorDeep('button', element.getRootNode() as HTMLElement); + const stepper = querySelectorDeep('button.custom-stepper-button', element.getRootNode() as HTMLElement); if (!stepper) throw new Error('Stepper button not found'); const blurEvent = new Event('blur', { bubbles: true }); diff --git a/packages/ui-library/src/components/input-field-number/index.ts b/packages/ui-library/src/components/input-field-number/index.ts index 1d3b1b0c2..db684ed9a 100644 --- a/packages/ui-library/src/components/input-field-number/index.ts +++ b/packages/ui-library/src/components/input-field-number/index.ts @@ -164,6 +164,7 @@ export class BlrInputFieldNumber extends LitElementCustom { const buttonClass = classMap({ 'custom-stepper-button': true, [iconSizeVariant]: true, + [this.sizeVariant]: true, [this.stepperVariant]: true, [this.theme]: this.theme, }); @@ -235,8 +236,10 @@ export class BlrInputFieldNumber extends LitElementCustom { if (this.sizeVariant) { const inputClasses = classMap({ [this.sizeVariant]: this.sizeVariant, - prepend: this.unitPosition === 'prefix', - suffix: this.unitPosition === 'suffix', + 'prepend': this.unitPosition === 'prefix', + 'suffix': this.unitPosition === 'suffix', + 'readonly': this.readonly || false, + 'error-input': this.hasError || false, [this.theme]: this.theme, }); @@ -335,7 +338,7 @@ export class BlrInputFieldNumber extends LitElementCustom { ? html`
${this.unit}
` : nothing} - ${this.renderMode()} + ${!this.readonly ? this.renderMode() : nothing}