diff --git a/src/uix/eidos/components/button/button.css b/src/uix/eidos/components/button/button.css index cb29beb18..ff5aef2a8 100644 --- a/src/uix/eidos/components/button/button.css +++ b/src/uix/eidos/components/button/button.css @@ -401,8 +401,13 @@ /* ── Inline SVG icons inherit color + sizing ──────────────────────────── */ +[data-button] :is(.eidos-button-icon, [data-button-icon]) { + pointer-events: none; +} + [data-button] :is(svg, [data-svg], [data-icon]) { inline-size: var(--_button-icon-size); block-size: var(--_button-icon-size); flex-shrink: 0; + pointer-events: none; } diff --git a/src/uix/soma/components/carousel/carousel-provider.svelte.test.ts b/src/uix/soma/components/carousel/carousel-provider.svelte.test.ts index a886f471c..d2108eb9c 100644 --- a/src/uix/soma/components/carousel/carousel-provider.svelte.test.ts +++ b/src/uix/soma/components/carousel/carousel-provider.svelte.test.ts @@ -189,6 +189,51 @@ describe('CarouselProvider', () => { dom.dispose(); }); + it('treats trigger and indicator clicks as user interactions for autoplay', () => { + const { dom } = installSomaHarness(); + const root = document.createElement('section'); + const groupEl = document.createElement('div'); + const indicatorEl = document.createElement('button'); + markItems(groupEl, 3); + root.append(groupEl, indicatorEl); + document.body.appendChild(root); + const opts = carouselOpts(root); + opts.autoplay.current = true; + opts.stopOnInteraction.current = true; + + const { result, cleanup } = withEffectRoot(() => { + const provider = CarouselProvider.create(opts); + vi.spyOn(CarouselProvider, 'require').mockReturnValue(provider); + provider.itemGroupRef = groupEl; + const next = CarouselNextTriggerProvider.create({ + id: state('carousel-next'), + ref: state(document.createElement('button')), + ariaLabel: state(undefined) + }); + const indicator = CarouselIndicatorProvider.create({ + id: state('carousel-indicator-2'), + ref: state(indicatorEl), + index: state(2), + ariaLabel: state(undefined) + }); + return { provider, next, indicator }; + }); + + expect(result.provider.isPlaying).toBe(true); + result.next.onclick({ currentTarget: document.createElement('button') } as never); + expect(opts.value.current).toBe(1); + expect(result.provider.isPlaying).toBe(false); + + result.provider.reset(); + expect(result.provider.isPlaying).toBe(true); + result.indicator.onclick({ currentTarget: indicatorEl } as never); + expect(opts.value.current).toBe(2); + expect(result.provider.isPlaying).toBe(false); + + cleanup(); + dom.dispose(); + }); + it('exposes viewport, item group, item and indicator props', () => { const { dom } = installSomaHarness(); const root = document.createElement('section'); diff --git a/src/uix/soma/components/carousel/carousel-provider.svelte.ts b/src/uix/soma/components/carousel/carousel-provider.svelte.ts index e64fc5b06..fe4b49bc7 100644 --- a/src/uix/soma/components/carousel/carousel-provider.svelte.ts +++ b/src/uix/soma/components/carousel/carousel-provider.svelte.ts @@ -632,7 +632,7 @@ export class CarouselPrevTriggerProvider { readonly onclick = (_e: SomaMouseEvent) => { if (this.isDisabled) return; - this.provider.prev(); + this.provider.scrollPrev(); }; readonly props = $derived.by(() => @@ -675,7 +675,7 @@ export class CarouselNextTriggerProvider { readonly onclick = (_e: SomaMouseEvent) => { if (this.isDisabled) return; - this.provider.next(); + this.provider.scrollNext(); }; readonly props = $derived.by(() => @@ -758,7 +758,7 @@ export class CarouselIndicatorProvider { readonly onclick = (_e: SomaMouseEvent) => { if (this.provider.isDisabled) return; - this.provider.goto(this.opts.index.current); + this.provider.scrollTo(this.opts.index.current); }; readonly props = $derived.by(() =>