fix(segment): move indicator as a percentage of the width on scroll

This commit is contained in:
Brandy Carney
2024-09-25 16:52:37 -04:00
parent bdc6933cf6
commit cbee05e488
6 changed files with 14 additions and 9 deletions

View File

@ -1613,7 +1613,7 @@ ion-segment-content,prop,disabled,boolean,false,false,false
ion-segment-view,shadow ion-segment-view,shadow
ion-segment-view,prop,disabled,boolean,false,false,false ion-segment-view,prop,disabled,boolean,false,false,false
ion-segment-view,method,setContent,setContent(id: string, smoothScroll?: boolean) => Promise<void> ion-segment-view,method,setContent,setContent(id: string, smoothScroll?: boolean) => Promise<void>
ion-segment-view,event,ionSegmentViewScroll,{ scrollDirection: string; scrollDistance: number; },true ion-segment-view,event,ionSegmentViewScroll,{ scrollDirection: string; scrollDistancePercentage: number; },true
ion-segment-view,event,ionSegmentViewScrollEnd,void,true ion-segment-view,event,ionSegmentViewScrollEnd,void,true
ion-select,shadow ion-select,shadow

View File

@ -4442,7 +4442,7 @@ declare global {
new (): HTMLIonSegmentContentElement; new (): HTMLIonSegmentContentElement;
}; };
interface HTMLIonSegmentViewElementEventMap { interface HTMLIonSegmentViewElementEventMap {
"ionSegmentViewScroll": { scrollDirection: string; scrollDistance: number }; "ionSegmentViewScroll": { scrollDirection: string; scrollDistancePercentage: number };
"ionSegmentViewScrollEnd": void; "ionSegmentViewScrollEnd": void;
} }
interface HTMLIonSegmentViewElement extends Components.IonSegmentView, HTMLStencilElement { interface HTMLIonSegmentViewElement extends Components.IonSegmentView, HTMLStencilElement {
@ -7538,7 +7538,7 @@ declare namespace LocalJSX {
/** /**
* Emitted when the segment view is scrolled. * Emitted when the segment view is scrolled.
*/ */
"onIonSegmentViewScroll"?: (event: IonSegmentViewCustomEvent<{ scrollDirection: string; scrollDistance: number }>) => void; "onIonSegmentViewScroll"?: (event: IonSegmentViewCustomEvent<{ scrollDirection: string; scrollDistancePercentage: number }>) => void;
/** /**
* Emitted when the segment view scroll has ended. * Emitted when the segment view scroll has ended.
*/ */

View File

@ -25,7 +25,7 @@ export class SegmentView implements ComponentInterface {
/** /**
* Emitted when the segment view is scrolled. * Emitted when the segment view is scrolled.
*/ */
@Event() ionSegmentViewScroll!: EventEmitter<{ scrollDirection: string; scrollDistance: number }>; @Event() ionSegmentViewScroll!: EventEmitter<{ scrollDirection: string; scrollDistancePercentage: number }>;
/** /**
* Emitted when the segment view scroll has ended. * Emitted when the segment view scroll has ended.
@ -46,12 +46,14 @@ export class SegmentView implements ComponentInterface {
this.previousScrollLeft = scrollLeft; this.previousScrollLeft = scrollLeft;
// Calculate the distance scrolled based on the initial scroll position // Calculate the distance scrolled based on the initial scroll position
// and then transform it to a percentage of the segment view width
const scrollDistance = scrollLeft - initialScrollLeft!; const scrollDistance = scrollLeft - initialScrollLeft!;
const scrollDistancePercentage = Math.abs(scrollDistance) / offsetWidth;
// Emit the scroll direction and distance // Emit the scroll direction and distance
this.ionSegmentViewScroll.emit({ this.ionSegmentViewScroll.emit({
scrollDirection, scrollDirection,
scrollDistance, scrollDistancePercentage,
}); });
const atSnappingPoint = scrollLeft % offsetWidth === 0; const atSnappingPoint = scrollLeft % offsetWidth === 0;

View File

@ -358,11 +358,14 @@ export class Segment implements ComponentInterface {
const current = buttons[index]; const current = buttons[index];
const indicatorEl = this.getIndicator(current); const indicatorEl = this.getIndicator(current);
const { scrollDistance } = ev.detail; const { scrollDirection, scrollDistancePercentage } = ev.detail;
if (indicatorEl) { if (indicatorEl) {
indicatorEl.style.transition = 'transform 0.3s ease-out'; indicatorEl.style.transition = 'transform 0.3s ease-out';
const scrollDistance = scrollDistancePercentage * current.getBoundingClientRect().width;
const transformValue = scrollDirection === 'left' ? -scrollDistance : scrollDistance;
// Calculate total width of buttons to the left of the current button // Calculate total width of buttons to the left of the current button
const totalButtonWidthBefore = buttons const totalButtonWidthBefore = buttons
.slice(0, index) .slice(0, index)
@ -378,7 +381,7 @@ export class Segment implements ComponentInterface {
const maxTransform = totalButtonWidthAfter; const maxTransform = totalButtonWidthAfter;
// Clamp the transform value to ensure it doesn't go out of bounds // Clamp the transform value to ensure it doesn't go out of bounds
const clampedTransform = Math.max(minTransform, Math.min(scrollDistance, maxTransform)); const clampedTransform = Math.max(minTransform, Math.min(transformValue, maxTransform));
// Apply the clamped transform value to the indicator element // Apply the clamped transform value to the indicator element
const transform = `translate3d(${clampedTransform}px, 0, 0)`; const transform = `translate3d(${clampedTransform}px, 0, 0)`;

View File

@ -2052,7 +2052,7 @@ export declare interface IonSegmentView extends Components.IonSegmentView {
/** /**
* Emitted when the segment view is scrolled. * Emitted when the segment view is scrolled.
*/ */
ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistance: number }>>; ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistancePercentage: number }>>;
/** /**
* Emitted when the segment view scroll has ended. * Emitted when the segment view scroll has ended.
*/ */

View File

@ -1891,7 +1891,7 @@ export declare interface IonSegmentView extends Components.IonSegmentView {
/** /**
* Emitted when the segment view is scrolled. * Emitted when the segment view is scrolled.
*/ */
ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistance: number }>>; ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistancePercentage: number }>>;
/** /**
* Emitted when the segment view scroll has ended. * Emitted when the segment view scroll has ended.
*/ */