From e76a1dc1f6412e7542ca705dfd2e48203e4849bd Mon Sep 17 00:00:00 2001 From: Konnor Rogers Date: Wed, 1 Nov 2023 16:49:24 -0400 Subject: [PATCH] fix no translation error (#8) * fix no translation error * prettier --- docs/pages/resources/changelog.md | 5 ++ .../color-picker/color-picker.component.ts | 44 ++++++++++++------ .../color-picker/color-picker.test.ts | 46 ++++++++++++++++--- src/internal/test.ts | 8 +++- src/utilities/localize.ts | 14 ++++-- 5 files changed, 94 insertions(+), 23 deletions(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 7b2a730cd..74a1406df 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -20,6 +20,11 @@ New versions of Web Awesome are released as-needed and generally occur when a cr - Removed `default` from `` and made `neutral` the new default - Removed the `circle` modifier from `` because button's no longer have a set height +## Next + +- Fixed a bug with bundled components using CDN builds not having translations on initial connect [#1696] +- Fixed a bug where the `"sl-change"` event would always fire simultaneously with `"sl-input"` event in ``. The `` event now only fires when a user stops dragging a slider or stops dragging on the color canvas. [#1689] + ## 2.11.2 - Fixed a bug in `` component that caused an error to be thrown when rendered with Lit [#1684] diff --git a/src/components/color-picker/color-picker.component.ts b/src/components/color-picker/color-picker.component.ts index ea5093da1..39c4aeecc 100644 --- a/src/components/color-picker/color-picker.component.ts +++ b/src/components/color-picker/color-picker.component.ts @@ -243,7 +243,8 @@ export default class WaColorPicker extends WebAwesomeElement implements WebAweso const container = this.shadowRoot!.querySelector('.color-picker__slider.color-picker__alpha')!; const handle = container.querySelector('.color-picker__slider-handle')!; const { width } = container.getBoundingClientRect(); - let oldValue = this.value; + let initialValue = this.value; + let currentValue = this.value; handle.focus(); event.preventDefault(); @@ -253,12 +254,17 @@ export default class WaColorPicker extends WebAwesomeElement implements WebAweso this.alpha = clamp((x / width) * 100, 0, 100); this.syncValues(); - if (this.value !== oldValue) { - oldValue = this.value; - this.emit('wa-change'); + if (this.value !== currentValue) { + currentValue = this.value; this.emit('wa-input'); } }, + onStop: () => { + if (this.value !== initialValue) { + initialValue = this.value; + this.emit('wa-change'); + } + }, initialEvent: event }); } @@ -267,7 +273,8 @@ export default class WaColorPicker extends WebAwesomeElement implements WebAweso const container = this.shadowRoot!.querySelector('.color-picker__slider.color-picker__hue')!; const handle = container.querySelector('.color-picker__slider-handle')!; const { width } = container.getBoundingClientRect(); - let oldValue = this.value; + let initialValue = this.value; + let currentValue = this.value; handle.focus(); event.preventDefault(); @@ -277,12 +284,17 @@ export default class WaColorPicker extends WebAwesomeElement implements WebAweso this.hue = clamp((x / width) * 360, 0, 360); this.syncValues(); - if (this.value !== oldValue) { - oldValue = this.value; - this.emit('wa-change'); + if (this.value !== currentValue) { + currentValue = this.value; this.emit('wa-input'); } }, + onStop: () => { + if (this.value !== initialValue) { + initialValue = this.value; + this.emit('wa-change'); + } + }, initialEvent: event }); } @@ -291,7 +303,8 @@ export default class WaColorPicker extends WebAwesomeElement implements WebAweso const grid = this.shadowRoot!.querySelector('.color-picker__grid')!; const handle = grid.querySelector('.color-picker__grid-handle')!; const { width, height } = grid.getBoundingClientRect(); - let oldValue = this.value; + let initialValue = this.value; + let currentValue = this.value; handle.focus(); event.preventDefault(); @@ -304,13 +317,18 @@ export default class WaColorPicker extends WebAwesomeElement implements WebAweso this.brightness = clamp(100 - (y / height) * 100, 0, 100); this.syncValues(); - if (this.value !== oldValue) { - oldValue = this.value; - this.emit('wa-change'); + if (this.value !== currentValue) { + currentValue = this.value; this.emit('wa-input'); } }, - onStop: () => (this.isDraggingGridHandle = false), + onStop: () => { + this.isDraggingGridHandle = false; + if (this.value !== initialValue) { + initialValue = this.value; + this.emit('wa-change'); + } + }, initialEvent: event }); } diff --git a/src/components/color-picker/color-picker.test.ts b/src/components/color-picker/color-picker.test.ts index d5c258be3..158d49018 100644 --- a/src/components/color-picker/color-picker.test.ts +++ b/src/components/color-picker/color-picker.test.ts @@ -1,6 +1,6 @@ import '../../../dist/webawesome.js'; import { aTimeout, expect, fixture, html, oneEvent } from '@open-wc/testing'; -import { clickOnElement } from '../../internal/test.js'; +import { clickOnElement, dragElement } from '../../internal/test.js'; import { runFormControlBaseTests } from '../../internal/test/form-control-base-tests.js'; import { sendKeys } from '@web/test-runner-commands'; import { serialize } from '../../utilities/form.js'; @@ -31,11 +31,21 @@ describe('', () => { await clickOnElement(trigger); // open the dropdown await aTimeout(200); // wait for the dropdown to open - await clickOnElement(grid); // click on the grid await el.updateComplete; + // Simulate a drag event. "sl-change" should not fire until we stop dragging. + await dragElement(grid, 2, 0, { + afterMouseDown: () => { + expect(changeHandler).to.have.not.been.called; + expect(inputHandler).to.have.been.calledOnce; + }, + afterMouseMove: () => { + expect(inputHandler).to.have.been.calledTwice; + } + }); + expect(changeHandler).to.have.been.calledOnce; - expect(inputHandler).to.have.been.calledOnce; + expect(inputHandler).to.have.been.calledTwice; }); it('should emit wa-change and wa-input when the hue slider is moved', async () => { @@ -50,10 +60,23 @@ describe('', () => { await clickOnElement(trigger); // open the dropdown await aTimeout(200); // wait for the dropdown to open - await clickOnElement(slider); // click on the hue slider + + // Simulate a drag event. "wa-change" should not fire until we stop dragging. + await dragElement(slider, 20, 0, { + afterMouseDown: () => { + expect(changeHandler).to.have.not.been.called; + expect(inputHandler).to.have.been.calledOnce; + }, + afterMouseMove: () => { + // It's not twice because you can't change the hue of white! + expect(inputHandler).to.have.been.calledOnce; + } + }); + await el.updateComplete; expect(changeHandler).to.have.been.calledOnce; + // It's not twice because you can't change the hue of white! expect(inputHandler).to.have.been.calledOnce; }); @@ -69,11 +92,22 @@ describe('', () => { await clickOnElement(trigger); // open the dropdown await aTimeout(200); // wait for the dropdown to open - await clickOnElement(slider); // click on the opacity slider + + // Simulate a drag event. "wa-change" should not fire until we stop dragging. + await dragElement(slider, 2, 0, { + afterMouseDown: () => { + expect(changeHandler).to.have.not.been.called; + expect(inputHandler).to.have.been.calledOnce; + }, + afterMouseMove: () => { + expect(inputHandler).to.have.been.calledTwice; + } + }); + await el.updateComplete; expect(changeHandler).to.have.been.calledOnce; - expect(inputHandler).to.have.been.calledOnce; + expect(inputHandler).to.have.been.calledTwice; }); it('should emit wa-change and wa-input when toggling the format', async () => { diff --git a/src/internal/test.ts b/src/internal/test.ts index 607753fcd..b85257c47 100644 --- a/src/internal/test.ts +++ b/src/internal/test.ts @@ -73,11 +73,17 @@ export async function dragElement( /** The horizontal distance to drag in pixels */ deltaX = 0, /** The vertical distance to drag in pixels */ - deltaY = 0 + deltaY = 0, + callbacks: { + afterMouseDown?: () => void | Promise; + afterMouseMove?: () => void | Promise; + } = {} ): Promise { await moveMouseOnElement(el); await sendMouse({ type: 'down' }); + await callbacks.afterMouseDown?.(); const { clickX, clickY } = determineMousePosition(el, 'center', deltaX, deltaY); await sendMouse({ type: 'move', position: [clickX, clickY] }); + await callbacks.afterMouseMove?.(); await sendMouse({ type: 'up' }); } diff --git a/src/utilities/localize.ts b/src/utilities/localize.ts index 9f22282eb..ccaf4e50d 100644 --- a/src/utilities/localize.ts +++ b/src/utilities/localize.ts @@ -1,9 +1,17 @@ -import '../translations/en.js'; -import { LocalizeController as DefaultLocalizationController } from '@shoelace-style/localize'; // Register English as the default/fallback language +import { LocalizeController as DefaultLocalizationController, registerTranslation } from '@shoelace-style/localize'; +import en from '../translations/en.js'; // Register English as the default/fallback language import type { Translation as DefaultTranslation } from '@shoelace-style/localize'; // Extend the controller and apply our own translation interface for better typings -export class LocalizeController extends DefaultLocalizationController {} +export class LocalizeController extends DefaultLocalizationController { + // Technicallly '../translations/en.js' is supposed to work via side-effects. However, by some mystery sometimes the + // translations don't get bundled as expected resulting in `no translation found` errors. + // This is basically some extra assurance that our translations get registered prior to our localizer connecting in a component + // and we don't rely on implicit import ordering. + static { + registerTranslation(en); + } +} // Export functions from the localize lib so we have one central place to import them from export { registerTranslation } from '@shoelace-style/localize';