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,prop,disabled,boolean,false,false,false
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-select,shadow

View File

@ -4442,7 +4442,7 @@ declare global {
new (): HTMLIonSegmentContentElement;
};
interface HTMLIonSegmentViewElementEventMap {
"ionSegmentViewScroll": { scrollDirection: string; scrollDistance: number };
"ionSegmentViewScroll": { scrollDirection: string; scrollDistancePercentage: number };
"ionSegmentViewScrollEnd": void;
}
interface HTMLIonSegmentViewElement extends Components.IonSegmentView, HTMLStencilElement {
@ -7538,7 +7538,7 @@ declare namespace LocalJSX {
/**
* 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.
*/

View File

@ -25,7 +25,7 @@ export class SegmentView implements ComponentInterface {
/**
* 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.
@ -46,12 +46,14 @@ export class SegmentView implements ComponentInterface {
this.previousScrollLeft = scrollLeft;
// 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 scrollDistancePercentage = Math.abs(scrollDistance) / offsetWidth;
// Emit the scroll direction and distance
this.ionSegmentViewScroll.emit({
scrollDirection,
scrollDistance,
scrollDistancePercentage,
});
const atSnappingPoint = scrollLeft % offsetWidth === 0;

View File

@ -358,11 +358,14 @@ export class Segment implements ComponentInterface {
const current = buttons[index];
const indicatorEl = this.getIndicator(current);
const { scrollDistance } = ev.detail;
const { scrollDirection, scrollDistancePercentage } = ev.detail;
if (indicatorEl) {
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
const totalButtonWidthBefore = buttons
.slice(0, index)
@ -378,7 +381,7 @@ export class Segment implements ComponentInterface {
const maxTransform = totalButtonWidthAfter;
// 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
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.
*/
ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistance: number }>>;
ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistancePercentage: number }>>;
/**
* 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.
*/
ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistance: number }>>;
ionSegmentViewScroll: EventEmitter<CustomEvent<{ scrollDirection: string; scrollDistancePercentage: number }>>;
/**
* Emitted when the segment view scroll has ended.
*/