From 41854309894fbd590d60c59d4cc9f4e0d454d1b5 Mon Sep 17 00:00:00 2001 From: Ahmad Alfy Date: Thu, 8 Feb 2024 22:17:54 +0200 Subject: [PATCH 1/6] locale: add Arabic translation (#1852) --- src/translations/ar.ts | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/translations/ar.ts diff --git a/src/translations/ar.ts b/src/translations/ar.ts new file mode 100644 index 00000000..96352368 --- /dev/null +++ b/src/translations/ar.ts @@ -0,0 +1,41 @@ +import { registerTranslation } from '@shoelace-style/localize'; +import type { Translation } from '../utilities/localize.js'; + +const translation: Translation = { + $code: 'ar', + $name: 'العربية', + $dir: 'rtl', + + carousel: 'كاروسيل', + clearEntry: 'حذف الخيارات', + close: 'اغلاق', + copied: 'تم النسخ', + copy: 'نسخ', + currentValue: 'القيمة الحالية', + error: 'خطأ', + goToSlide: (slide, count) => `عرض شريحة رقم ${slide} من ${count}`, + hidePassword: 'اخفاء كلمة المرور', + loading: 'جاري التحميل', + nextSlide: 'الشريحة التالية', + numOptionsSelected: num => { + if (num === 0) return 'لم يتم تحديد أي خيارات'; + if (num === 1) return 'تم تحديد خيار واحد'; + if (num === 2) return 'تم تحديد خياران'; + if (num > 2 && num < 11) return `تم تحديد ${num} خيارات`; + return `تم تحديد ${num} خيار`; + }, + previousSlide: 'الشريحة السابقة', + progress: 'مقدار التقدم', + remove: 'حذف', + resize: 'تغيير الحجم', + scrollToEnd: 'الانتقال الى النهاية', + scrollToStart: 'الانتقال الى البداية', + selectAColorFromTheScreen: 'اختر لون من الشاشة', + showPassword: 'عرض كلمة المرور', + slideNum: slide => `شريحة ${slide}`, + toggleColorFormat: 'تغيير صيغة عرض اللون' +}; + +registerTranslation(translation); + +export default translation; From a36bbe2fc4c41837d8d54aeaf1c05dbe114d47a4 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Thu, 8 Feb 2024 15:19:51 -0500 Subject: [PATCH 2/6] update changelog --- docs/pages/resources/changelog.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 7e935588..f73b90bf 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -14,12 +14,13 @@ New versions of Shoelace are released as-needed and generally occur when a criti ## Next +- Added the Arabic translation [#1852] +- Added help text to `` +- Added help text to `` [#1800] - Fixed a bug in `` that caused HTML tags to be included in `getTextLabel()` ## 2.13.1 -- Added help text to `` -- Added help text to `` [#1800] - Fixed a bug where the safe triangle was always visible when selecting nested `` elements [#1835] ## 2.13.0 From dafb35c6e210193a9ca31efddc3429ba2bb66be3 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Thu, 8 Feb 2024 15:20:18 -0500 Subject: [PATCH 3/6] update changelog --- docs/pages/resources/changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index f73b90bf..4c753b7e 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -15,7 +15,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti ## Next - Added the Arabic translation [#1852] -- Added help text to `` +- Added help text to `` [#1860] - Added help text to `` [#1800] - Fixed a bug in `` that caused HTML tags to be included in `getTextLabel()` From 7e38e93ab2e5099b815555c93f0daeae2d11fcb2 Mon Sep 17 00:00:00 2001 From: Alessandro Date: Fri, 9 Feb 2024 15:28:45 +0100 Subject: [PATCH 4/6] fix(carousel): remove check for scrolling (#1862) --- src/components/carousel/carousel.component.ts | 17 ++--- src/components/carousel/carousel.test.ts | 67 +++++++++++++------ 2 files changed, 51 insertions(+), 33 deletions(-) diff --git a/src/components/carousel/carousel.component.ts b/src/components/carousel/carousel.component.ts index 5e186fc9..34d097ea 100644 --- a/src/components/carousel/carousel.component.ts +++ b/src/components/carousel/carousel.component.ts @@ -476,7 +476,7 @@ export default class SlCarousel extends ShoelaceElement { this.scrollToSlide(nextSlide, prefersReducedMotion() ? 'auto' : behavior); } - private async scrollToSlide(slide: HTMLElement, behavior: ScrollBehavior = 'smooth') { + private scrollToSlide(slide: HTMLElement, behavior: ScrollBehavior = 'smooth') { const scrollContainer = this.scrollContainer; const scrollContainerRect = scrollContainer.getBoundingClientRect(); const nextSlideRect = slide.getBoundingClientRect(); @@ -484,16 +484,11 @@ export default class SlCarousel extends ShoelaceElement { const nextLeft = nextSlideRect.left - scrollContainerRect.left; const nextTop = nextSlideRect.top - scrollContainerRect.top; - // If the slide is already in view, don't need to scroll - if (nextLeft !== scrollContainer.scrollLeft || nextTop !== scrollContainer.scrollTop) { - scrollContainer.scrollTo({ - left: nextLeft + scrollContainer.scrollLeft, - top: nextTop + scrollContainer.scrollTop, - behavior - }); - - await waitForEvent(scrollContainer, 'scrollend'); - } + scrollContainer.scrollTo({ + left: nextLeft + scrollContainer.scrollLeft, + top: nextTop + scrollContainer.scrollTop, + behavior + }); } render() { diff --git a/src/components/carousel/carousel.test.ts b/src/components/carousel/carousel.test.ts index 42d693a7..01cfc8d1 100644 --- a/src/components/carousel/carousel.test.ts +++ b/src/components/carousel/carousel.test.ts @@ -1,6 +1,6 @@ import '../../../dist/shoelace.js'; import { clickOnElement, dragElement, moveMouseOnElement } from '../../internal/test.js'; -import { expect, fixture, html, oneEvent } from '@open-wc/testing'; +import { expect, fixture, html, nextFrame, oneEvent } from '@open-wc/testing'; import { map } from 'lit/directives/map.js'; import { range } from 'lit/directives/range.js'; import { resetMouse } from '@web/test-runner-commands'; @@ -8,10 +8,16 @@ import sinon from 'sinon'; import type SlCarousel from './carousel.js'; describe('', () => { + const sandbox = sinon.createSandbox(); + afterEach(async () => { await resetMouse(); }); + afterEach(() => { + sandbox.restore(); + }); + it('should render a carousel with default configuration', async () => { // Arrange const el = await fixture(html` @@ -34,15 +40,11 @@ describe('', () => { let clock: sinon.SinonFakeTimers; beforeEach(() => { - clock = sinon.useFakeTimers({ + clock = sandbox.useFakeTimers({ now: new Date() }); }); - afterEach(() => { - clock.restore(); - }); - it('should scroll forwards every `autoplay-interval` milliseconds', async () => { // Arrange const el = await fixture(html` @@ -52,7 +54,7 @@ describe('', () => { Node 3 `); - sinon.stub(el, 'next'); + sandbox.stub(el, 'next'); await el.updateComplete; @@ -73,7 +75,7 @@ describe('', () => { Node 3 `); - sinon.stub(el, 'next'); + sandbox.stub(el, 'next'); await el.updateComplete; @@ -96,7 +98,7 @@ describe('', () => { Node 3 `); - sinon.stub(el, 'next'); + sandbox.stub(el, 'next'); await el.updateComplete; @@ -183,7 +185,7 @@ describe('', () => { Node 3 `); - sinon.stub(el, 'goToSlide'); + sandbox.stub(el, 'goToSlide'); await el.updateComplete; // Act @@ -473,7 +475,7 @@ describe('', () => { `); const nextButton: HTMLElement = el.shadowRoot!.querySelector('.carousel__navigation-button--next')!; - sinon.stub(el, 'next'); + sandbox.stub(el, 'next'); await el.updateComplete; @@ -496,7 +498,7 @@ describe('', () => { `); const nextButton: HTMLElement = el.shadowRoot!.querySelector('.carousel__navigation-button--next')!; - sinon.stub(el, 'next'); + sandbox.stub(el, 'next'); el.goToSlide(2, 'auto'); await oneEvent(el.scrollContainer, 'scrollend'); @@ -560,7 +562,7 @@ describe('', () => { await el.updateComplete; const previousButton: HTMLElement = el.shadowRoot!.querySelector('.carousel__navigation-button--previous')!; - sinon.stub(el, 'previous'); + sandbox.stub(el, 'previous'); await el.updateComplete; @@ -584,7 +586,7 @@ describe('', () => { `); const previousButton: HTMLElement = el.shadowRoot!.querySelector('.carousel__navigation-button--previous')!; - sinon.stub(el, 'previous'); + sandbox.stub(el, 'previous'); await el.updateComplete; // Act @@ -632,19 +634,27 @@ describe('', () => { it('should scroll the carousel to the next slide', async () => { // Arrange const el = await fixture(html` - + Node 1 Node 2 Node 3 `); - sinon.stub(el, 'goToSlide'); - await el.updateComplete; + sandbox.spy(el, 'goToSlide'); + const expectedCarouselItem: HTMLElement = el.querySelector('sl-carousel-item:nth-child(2)')!; // Act el.next(); + await oneEvent(el.scrollContainer, 'scrollend'); + await el.updateComplete; - expect(el.goToSlide).to.have.been.calledWith(2); + const containerRect = el.scrollContainer.getBoundingClientRect(); + const itemRect = expectedCarouselItem.getBoundingClientRect(); + + // Assert + expect(el.goToSlide).to.have.been.calledWith(1); + expect(itemRect.top).to.be.equal(containerRect.top); + expect(itemRect.left).to.be.equal(containerRect.left); }); }); @@ -652,19 +662,32 @@ describe('', () => { it('should scroll the carousel to the previous slide', async () => { // Arrange const el = await fixture(html` - + Node 1 Node 2 Node 3 `); - sinon.stub(el, 'goToSlide'); - await el.updateComplete; + const expectedCarouselItem: HTMLElement = el.querySelector('sl-carousel-item:nth-child(1)')!; + + el.goToSlide(1); + + await oneEvent(el.scrollContainer, 'scrollend'); + await nextFrame(); + + sandbox.spy(el, 'goToSlide'); // Act el.previous(); + await oneEvent(el.scrollContainer, 'scrollend'); - expect(el.goToSlide).to.have.been.calledWith(-2); + const containerRect = el.scrollContainer.getBoundingClientRect(); + const itemRect = expectedCarouselItem.getBoundingClientRect(); + + // Assert + expect(el.goToSlide).to.have.been.calledWith(0); + expect(itemRect.top).to.be.equal(containerRect.top); + expect(itemRect.left).to.be.equal(containerRect.left); }); }); From 9ee161769602259bb77fbeeff9db7a6471874d18 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Fri, 9 Feb 2024 09:33:14 -0500 Subject: [PATCH 5/6] update changelog --- docs/pages/resources/changelog.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/pages/resources/changelog.md b/docs/pages/resources/changelog.md index 4c753b7e..44fceb02 100644 --- a/docs/pages/resources/changelog.md +++ b/docs/pages/resources/changelog.md @@ -18,6 +18,7 @@ New versions of Shoelace are released as-needed and generally occur when a criti - Added help text to `` [#1860] - Added help text to `` [#1800] - Fixed a bug in `` that caused HTML tags to be included in `getTextLabel()` +- Fixed a bug in `` that caused slides to not switch correctly [#1862] ## 2.13.1 From 775f30107f91d89e01ae06f7064965a80da4f660 Mon Sep 17 00:00:00 2001 From: Cory LaViska Date: Fri, 9 Feb 2024 09:57:54 -0500 Subject: [PATCH 6/6] fix help text a11y --- src/components/checkbox/checkbox.component.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/components/checkbox/checkbox.component.ts b/src/components/checkbox/checkbox.component.ts index f4479c9c..98f13847 100644 --- a/src/components/checkbox/checkbox.component.ts +++ b/src/components/checkbox/checkbox.component.ts @@ -227,6 +227,7 @@ export default class SlCheckbox extends ShoelaceElement implements ShoelaceFormC .disabled=${this.disabled} .required=${this.required} aria-checked=${this.checked ? 'true' : 'false'} + aria-describedby="help-text" @click=${this.handleClick} @input=${this.handleInput} @invalid=${this.handleInvalid}