Skip to content
7 changes: 7 additions & 0 deletions core/src/components/segment-view/segment-view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,13 @@ export class SegmentView implements ComponentInterface {
handleScroll(ev: Event) {
const { scrollLeft, scrollWidth, clientWidth } = ev.target as HTMLElement;
const max = scrollWidth - clientWidth;
// When only one content item is present max is 0 — skip to avoid NaN/Infinity scrollRatio.
// Still reset the timeout so isManualScroll isn't cleared prematurely if setContent
// started the timer and a stray scroll event arrives on a non-overflowing element.
if (max <= 0) {
this.resetScrollEndTimeout();
return;
}
const scrollRatio = (isRTL(this.el) ? -1 : 1) * (scrollLeft / max);

this.ionSegmentViewScroll.emit({
Expand Down
31 changes: 31 additions & 0 deletions core/src/components/segment-view/test/basic/segment-view.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,37 @@ configs({ modes: ['md'] }).forEach(({ title, config }) => {
await expect(segmentButton).toHaveClass(/segment-button-checked/);
});

test('should not emit ionSegmentViewScroll with NaN or Infinity scrollRatio when only one content item is present', async ({
page,
}) => {
await page.setContent(
`
<ion-segment value="only">
<ion-segment-button content-id="only" value="only">
<ion-label>Only</ion-label>
</ion-segment-button>
</ion-segment>
<ion-segment-view>
<ion-segment-content id="only">Only</ion-segment-content>
</ion-segment-view>
`,
config
);

const ionSegmentViewScroll = await page.spyOnEvent('ionSegmentViewScroll');

// Programmatically dispatch a scroll event on the segment-view host element
// to simulate what the browser fires when scrollLeft changes.
await page.locator('ion-segment-view').evaluate((el: HTMLElement) => {
el.dispatchEvent(new Event('scroll', { bubbles: true }));
});

await page.waitForChanges();

// The max === 0 guard should prevent ionSegmentViewScroll from firing entirely.
expect(ionSegmentViewScroll).not.toHaveReceivedEvent();
});

test('should set correct segment button as checked and show correct content when programmatically setting the segment value', async ({
page,
}) => {
Expand Down
Loading