Skip to content

Commit 0f2d565

Browse files
author
Tanner Reits
committed
fix(segment): programmatic value setting, force value to exist
1 parent d13cd2e commit 0f2d565

File tree

2 files changed

+37
-20
lines changed

2 files changed

+37
-20
lines changed

core/src/components/segment-view/segment-view.tsx

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,13 @@ export class SegmentView implements ComponentInterface {
2323
@Prop() disabled = false;
2424

2525
/**
26+
* @internal
27+
*
2628
* If `true`, the segment view is scrollable.
2729
* If `false`, pointer events will be disabled. This is to prevent issues with
2830
* quickly scrolling after interacting with a segment button.
2931
*/
30-
@State() isManualScroll = true;
32+
@State() isManualScroll?: boolean;
3133

3234
/**
3335
* Emitted when the segment view is scrolled.
@@ -48,7 +50,7 @@ export class SegmentView implements ComponentInterface {
4850

4951
this.ionSegmentViewScroll.emit({
5052
scrollRatio,
51-
isManualScroll: this.isManualScroll,
53+
isManualScroll: this.isManualScroll ?? true,
5254
});
5355

5456
// Reset the timeout to check for scroll end
@@ -101,7 +103,7 @@ export class SegmentView implements ComponentInterface {
101103
// the user is not touching the segment view
102104
if (!this.isTouching) {
103105
this.ionSegmentViewScrollEnd.emit();
104-
this.isManualScroll = true;
106+
this.isManualScroll = undefined;
105107
}
106108
}
107109

@@ -123,6 +125,7 @@ export class SegmentView implements ComponentInterface {
123125
if (index === -1) return;
124126

125127
this.isManualScroll = false;
128+
this.resetScrollEndTimeout();
126129

127130
const contentWidth = this.el.offsetWidth;
128131
this.el.scrollTo({
@@ -143,7 +146,7 @@ export class SegmentView implements ComponentInterface {
143146
<Host
144147
class={{
145148
'segment-view-disabled': disabled,
146-
'segment-view-scroll-disabled': !isManualScroll,
149+
'segment-view-scroll-disabled': isManualScroll === false,
147150
}}
148151
>
149152
<slot></slot>

core/src/components/segment/segment.tsx

Lines changed: 30 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,13 @@ export class Segment implements ComponentInterface {
3131
private segmentViewEl?: HTMLIonSegmentViewElement | null = null;
3232
private lastNextIndex?: number;
3333

34+
/**
35+
* Whether to update the segment view, if exists, when the value changes.
36+
* This behavior is enabled by default, but is set false when scrolling content views
37+
* since we don't want to "double scroll" the segment view.
38+
*/
39+
private triggerScrollOnValueChange?: boolean;
40+
3441
@Element() el!: HTMLIonSegmentElement;
3542

3643
@State() activated = false;
@@ -83,6 +90,12 @@ export class Segment implements ComponentInterface {
8390

8491
@Watch('value')
8592
protected valueChanged(value: SegmentValue | undefined, oldValue?: SegmentValue | undefined) {
93+
// Force a value to exist if we're using a segment view
94+
if (this.segmentViewEl && value === undefined) {
95+
this.value = this.getButtons()[0].value;
96+
return;
97+
}
98+
8699
if (oldValue !== undefined && value !== undefined) {
87100
const buttons = this.getButtons();
88101
const previous = buttons.find((button) => button.value === oldValue);
@@ -91,10 +104,12 @@ export class Segment implements ComponentInterface {
91104
if (previous && current) {
92105
if (!this.segmentViewEl) {
93106
this.checkButton(previous, current);
94-
} else {
95-
this.setCheckedClasses();
107+
} else if (this.triggerScrollOnValueChange !== false) {
108+
this.updateSegmentView();
96109
}
97110
}
111+
} else if (value !== undefined && oldValue === undefined && this.segmentViewEl) {
112+
this.updateSegmentView();
98113
}
99114

100115
/**
@@ -106,13 +121,9 @@ export class Segment implements ComponentInterface {
106121
// The scroll listener should handle scrolling the active button into view as needed
107122
if (!this.segmentViewEl) {
108123
this.scrollActiveButtonIntoView();
109-
} else {
110-
const activeButton = this.getButtons().find((button) => button.value === value);
111-
112-
if (activeButton?.contentId) {
113-
this.segmentViewEl.setContent(activeButton.contentId);
114-
}
115124
}
125+
126+
this.triggerScrollOnValueChange = undefined;
116127
}
117128

118129
/**
@@ -391,17 +402,18 @@ export class Segment implements ComponentInterface {
391402
const buttons = this.getButtons();
392403

393404
// If no buttons are found or there is no value set then do nothing
394-
if (!buttons.length || this.value === undefined) return;
405+
if (!buttons.length) return;
395406

396407
const index = buttons.findIndex((button) => button.value === this.value);
397408
const current = buttons[index];
398409

399-
const next = Math.round(scrollRatio * (buttons.length - 1));
410+
const nextIndex = Math.round(scrollRatio * (buttons.length - 1));
400411

401-
if (this.lastNextIndex === undefined || this.lastNextIndex !== next) {
402-
this.lastNextIndex = next;
412+
if (this.lastNextIndex === undefined || this.lastNextIndex !== nextIndex) {
413+
this.lastNextIndex = nextIndex;
414+
this.triggerScrollOnValueChange = false;
403415

404-
this.checkButton(current, buttons[next]);
416+
this.checkButton(current, buttons[nextIndex]);
405417
this.emitValueChange();
406418
}
407419
}
@@ -424,8 +436,7 @@ export class Segment implements ComponentInterface {
424436
return;
425437
}
426438

427-
const content = document.getElementById(button.contentId);
428-
const segmentView = content?.closest('ion-segment-view');
439+
const segmentView = this.segmentViewEl;
429440

430441
if (segmentView) {
431442
segmentView.setContent(button.contentId, smoothScroll);
@@ -600,7 +611,10 @@ export class Segment implements ComponentInterface {
600611

601612
if (this.segmentViewEl) {
602613
this.updateSegmentView();
603-
current.scrollIntoView();
614+
615+
if (this.scrollable && previous) {
616+
this.checkButton(previous, current);
617+
}
604618
} else if (this.scrollable || !this.swipeGesture) {
605619
if (previous) {
606620
this.checkButton(previous, current);

0 commit comments

Comments
 (0)