mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
fix(segment): clear transform styles on scroll end
This commit is contained in:
@@ -25,12 +25,20 @@ export class SegmentView implements ComponentInterface {
|
||||
/**
|
||||
* Emitted when the segment view is scrolled.
|
||||
*/
|
||||
@Event() ionSegmentViewScroll!: EventEmitter<{ scrollDirection: string; scrollDistancePercentage: number }>;
|
||||
@Event() ionSegmentViewScroll!: EventEmitter<{
|
||||
scrollDirection: string;
|
||||
scrollDistance: number;
|
||||
scrollDistancePercentage: number;
|
||||
}>;
|
||||
|
||||
/**
|
||||
* Emitted when the segment view scroll has ended.
|
||||
*/
|
||||
@Event() ionSegmentViewScrollEnd!: EventEmitter<void>;
|
||||
@Event() ionSegmentViewScrollEnd!: EventEmitter<{ activeContentId: string }>;
|
||||
|
||||
@Event() ionSegmentViewScrollStart!: EventEmitter<void>;
|
||||
|
||||
private activeContentId = '';
|
||||
|
||||
@Listen('scroll')
|
||||
handleScroll(ev: Event) {
|
||||
@@ -53,6 +61,7 @@ export class SegmentView implements ComponentInterface {
|
||||
// Emit the scroll direction and distance
|
||||
this.ionSegmentViewScroll.emit({
|
||||
scrollDirection,
|
||||
scrollDistance,
|
||||
scrollDistancePercentage,
|
||||
});
|
||||
|
||||
@@ -67,12 +76,8 @@ export class SegmentView implements ComponentInterface {
|
||||
return;
|
||||
}
|
||||
|
||||
const segmentButton = this.getSegmentButtonById(segmentContent.id) as HTMLIonSegmentButtonElement;
|
||||
const segment = this.getParentSegment(segmentButton);
|
||||
|
||||
if (segment) {
|
||||
segment.value = segmentButton.value;
|
||||
}
|
||||
// Store the active `ion-segment-content` id so we can emit it when the scroll ends
|
||||
this.activeContentId = segmentContent.id;
|
||||
|
||||
this.resetScrollEndTimeout();
|
||||
}
|
||||
@@ -82,6 +87,8 @@ export class SegmentView implements ComponentInterface {
|
||||
*/
|
||||
@Listen('touchstart')
|
||||
handleScrollStart() {
|
||||
this.ionSegmentViewScrollStart.emit();
|
||||
|
||||
if (this.scrollEndTimeout) {
|
||||
clearTimeout(this.scrollEndTimeout);
|
||||
this.scrollEndTimeout = null;
|
||||
@@ -118,7 +125,7 @@ export class SegmentView implements ComponentInterface {
|
||||
*/
|
||||
private checkForScrollEnd() {
|
||||
if (!this.isTouching) {
|
||||
this.ionSegmentViewScrollEnd.emit();
|
||||
this.ionSegmentViewScrollEnd.emit({ activeContentId: this.activeContentId });
|
||||
this.initialScrollLeft = undefined;
|
||||
}
|
||||
}
|
||||
@@ -149,14 +156,6 @@ export class SegmentView implements ComponentInterface {
|
||||
return Array.from(this.el.querySelectorAll('ion-segment-content:not([disabled])'));
|
||||
}
|
||||
|
||||
private getSegmentButtonById(id: string) {
|
||||
return document.querySelector(`ion-segment-button[content-id="${id}"]`);
|
||||
}
|
||||
|
||||
private getParentSegment(button: Element) {
|
||||
return button.closest('ion-segment');
|
||||
}
|
||||
|
||||
render() {
|
||||
const { disabled } = this;
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ export class Segment implements ComponentInterface {
|
||||
private valueBeforeGesture?: SegmentValue;
|
||||
|
||||
private segmentViewEl?: HTMLIonSegmentViewElement | null = null;
|
||||
private scrolledIndicator?: HTMLDivElement | null = null;
|
||||
|
||||
@Element() el!: HTMLIonSegmentElement;
|
||||
|
||||
@@ -87,7 +88,11 @@ export class Segment implements ComponentInterface {
|
||||
const current = buttons.find((button) => button.value === value);
|
||||
|
||||
if (previous && current) {
|
||||
this.checkButton(previous, current);
|
||||
if (!this.segmentViewEl) {
|
||||
this.checkButton(previous, current);
|
||||
} else {
|
||||
this.setCheckedClasses();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,7 +101,11 @@ export class Segment implements ComponentInterface {
|
||||
* Used by `ion-segment-button` to determine if the button should be checked.
|
||||
*/
|
||||
this.ionSelect.emit({ value });
|
||||
this.scrollActiveButtonIntoView();
|
||||
|
||||
// The scroll listener should handle scrolling the active button into view as needed
|
||||
if (!this.segmentViewEl) {
|
||||
this.scrollActiveButtonIntoView();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -357,10 +366,13 @@ export class Segment implements ComponentInterface {
|
||||
const index = buttons.findIndex((button) => button.value === this.value);
|
||||
const current = buttons[index];
|
||||
const indicatorEl = this.getIndicator(current);
|
||||
this.scrolledIndicator = indicatorEl;
|
||||
|
||||
const { scrollDirection, scrollDistancePercentage } = ev.detail;
|
||||
const { scrollDirection, scrollDistancePercentage, scrollDistance } = ev.detail;
|
||||
|
||||
if (indicatorEl) {
|
||||
console.log('scroll', scrollDistancePercentage, scrollDistance);
|
||||
|
||||
if (indicatorEl && !isNaN(scrollDistancePercentage)) {
|
||||
indicatorEl.style.transition = 'transform 0.3s ease-out';
|
||||
|
||||
const scrollDistance = scrollDistancePercentage * current.getBoundingClientRect().width;
|
||||
@@ -390,6 +402,19 @@ export class Segment implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
@Listen('ionSegmentViewScrollStart', { target: 'body' })
|
||||
onScrollStart() {}
|
||||
|
||||
@Listen('ionSegmentViewScrollEnd', { target: 'body' })
|
||||
onScrollEnd(ev: CustomEvent<{ activeContentId: string }>) {
|
||||
this.value = ev.detail.activeContentId;
|
||||
|
||||
if (this.scrolledIndicator) {
|
||||
this.scrolledIndicator.style.transition = '';
|
||||
this.scrolledIndicator.style.transform = '';
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the related segment view and sets its current content
|
||||
* based on the selected segment button. This method
|
||||
|
||||
Reference in New Issue
Block a user