mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-08-18 19:21:34 +08:00
fix(segment): scroll to active segment-button on first load (#28276)
Issue number: resolves #28096 --------- <!-- Please do not submit updates to dependencies unless it fixes an issue. --> <!-- Please try to limit your pull request to one type (bugfix, feature, etc). Submit multiple pull requests if needed. --> ## What is the current behavior? <!-- Please describe the current behavior that you are modifying. --> When a segment button is clicked, the segment will auto-scroll to position the newly active button fully in view. However, this behavior does not occur on first load. This means that when a segment is initialized with a `value` corresponding to an off-screen button, the button will remain off-screen. ## What is the new behavior? <!-- Please describe the behavior or changes that are being added by this PR. --> The same auto-scroll behavior from button click now also occurs on component load. ## Does this introduce a breaking change? - [ ] Yes - [x] No <!-- If this introduces a breaking change, please describe the impact and migration path for existing applications below. --> ## Other information <!-- Any other information that is important to this PR such as screenshots of how the component looks before and after the change. -->
This commit is contained in:
@ -1,6 +1,7 @@
|
||||
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Listen, Prop, State, Watch, h, writeTask } from '@stencil/core';
|
||||
import type { Gesture, GestureDetail } from '@utils/gesture';
|
||||
import { raf } from '@utils/helpers';
|
||||
import { isRTL } from '@utils/rtl';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
@ -83,31 +84,7 @@ export class Segment implements ComponentInterface {
|
||||
* Used by `ion-segment-button` to determine if the button should be checked.
|
||||
*/
|
||||
this.ionSelect.emit({ value });
|
||||
|
||||
if (this.scrollable) {
|
||||
const buttons = this.getButtons();
|
||||
const activeButton = buttons.find((button) => button.value === value);
|
||||
if (activeButton !== undefined) {
|
||||
/**
|
||||
* Scrollable segment buttons should be
|
||||
* centered within the view including
|
||||
* buttons that are partially offscreen.
|
||||
*/
|
||||
activeButton.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
inline: 'center',
|
||||
|
||||
/**
|
||||
* Segment should scroll on the
|
||||
* horizontal axis. `block: 'nearest'`
|
||||
* ensures that the vertical axis
|
||||
* does not scroll if the segment
|
||||
* as a whole is already in view.
|
||||
*/
|
||||
block: 'nearest',
|
||||
});
|
||||
}
|
||||
}
|
||||
this.scrollActiveButtonIntoView();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -163,6 +140,14 @@ export class Segment implements ComponentInterface {
|
||||
async componentDidLoad() {
|
||||
this.setCheckedClasses();
|
||||
|
||||
/**
|
||||
* We need to wait for the buttons to all be rendered
|
||||
* before we can scroll.
|
||||
*/
|
||||
raf(() => {
|
||||
this.scrollActiveButtonIntoView();
|
||||
});
|
||||
|
||||
this.gesture = (await import('../../utils/gesture')).createGesture({
|
||||
el: this.el,
|
||||
gestureName: 'segment',
|
||||
@ -320,6 +305,35 @@ export class Segment implements ComponentInterface {
|
||||
}
|
||||
}
|
||||
|
||||
private scrollActiveButtonIntoView() {
|
||||
const { scrollable, value } = this;
|
||||
|
||||
if (scrollable) {
|
||||
const buttons = this.getButtons();
|
||||
const activeButton = buttons.find((button) => button.value === value);
|
||||
if (activeButton !== undefined) {
|
||||
/**
|
||||
* Scrollable segment buttons should be
|
||||
* centered within the view including
|
||||
* buttons that are partially offscreen.
|
||||
*/
|
||||
activeButton.scrollIntoView({
|
||||
behavior: 'smooth',
|
||||
inline: 'center',
|
||||
|
||||
/**
|
||||
* Segment should scroll on the
|
||||
* horizontal axis. `block: 'nearest'`
|
||||
* ensures that the vertical axis
|
||||
* does not scroll if the segment
|
||||
* as a whole is already in view.
|
||||
*/
|
||||
block: 'nearest',
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private setNextIndex(detail: GestureDetail, isEnd = false) {
|
||||
const rtl = isRTL(this.el);
|
||||
const activated = this.activated;
|
||||
|
Reference in New Issue
Block a user