fix(segment): only emit ionChange when user releases pointer from screen (#20495)

fixes #20500
fixes #20257
This commit is contained in:
Liam DeBeasi
2020-02-18 15:11:28 -05:00
committed by GitHub
parent 7a461c59c5
commit 4d50064764
5 changed files with 38 additions and 10 deletions

View File

@ -12,6 +12,13 @@ export class ValueAccessor implements ControlValueAccessor {
constructor(protected el: ElementRef) {} constructor(protected el: ElementRef) {}
writeValue(value: any) { writeValue(value: any) {
/**
* TODO for Ionic 6:
* Change `value == null ? '' : value;`
* to `value`. This was a fix for IE9, but IE9
* is no longer supported; however, this change
* is potentially a breaking change
*/
this.el.nativeElement.value = this.lastValue = value == null ? '' : value; this.el.nativeElement.value = this.lastValue = value == null ? '' : value;
setIonicClasses(this.el); setIonicClasses(this.el);
} }

View File

@ -5209,7 +5209,7 @@ declare namespace LocalJSX {
*/ */
'mode'?: "ios" | "md"; 'mode'?: "ios" | "md";
/** /**
* Emitted when the value property has changed. * Emitted when the value property has changed and any dragging pointer has been released from `ion-segment`.
*/ */
'onIonChange'?: (event: CustomEvent<SegmentChangeEventDetail>) => void; 'onIonChange'?: (event: CustomEvent<SegmentChangeEventDetail>) => void;
/** /**

View File

@ -49,14 +49,14 @@ export class SegmentButton implements ComponentInterface, ButtonInterface {
const segmentEl = this.segmentEl = this.el.closest('ion-segment'); const segmentEl = this.segmentEl = this.el.closest('ion-segment');
if (segmentEl) { if (segmentEl) {
this.updateState(); this.updateState();
segmentEl.addEventListener('ionChange', this.updateState); segmentEl.addEventListener('ionSelect', this.updateState);
} }
} }
disconnectedCallback() { disconnectedCallback() {
const segmentEl = this.segmentEl; const segmentEl = this.segmentEl;
if (segmentEl) { if (segmentEl) {
segmentEl.removeEventListener('ionChange', this.updateState); segmentEl.removeEventListener('ionSelect', this.updateState);
this.segmentEl = null; this.segmentEl = null;
} }
} }

View File

@ -450,8 +450,8 @@ export const SegmentExample: React.FC = () => (
## Events ## Events
| Event | Description | Type | | Event | Description | Type |
| ----------- | -------------------------------------------- | --------------------------------------- | | ----------- | ---------------------------------------------------------------------------------------------------------- | --------------------------------------- |
| `ionChange` | Emitted when the value property has changed. | `CustomEvent<SegmentChangeEventDetail>` | | `ionChange` | Emitted when the value property has changed and any dragging pointer has been released from `ion-segment`. | `CustomEvent<SegmentChangeEventDetail>` |
## CSS Custom Properties ## CSS Custom Properties

View File

@ -23,6 +23,9 @@ export class Segment implements ComponentInterface {
private didInit = false; private didInit = false;
private checked?: HTMLIonSegmentButtonElement; private checked?: HTMLIonSegmentButtonElement;
// Value to be emitted when gesture ends
private valueAfterGesture?: any;
@Element() el!: HTMLIonSegmentElement; @Element() el!: HTMLIonSegmentElement;
@State() activated = false; @State() activated = false;
@ -52,17 +55,29 @@ export class Segment implements ComponentInterface {
@Prop({ mutable: true }) value?: string | null; @Prop({ mutable: true }) value?: string | null;
@Watch('value') @Watch('value')
protected valueChanged(value: string | undefined) { protected valueChanged(value: string | undefined, oldValue: string | undefined | null) {
if (this.didInit) { this.ionSelect.emit({ value });
if (oldValue !== '' || this.didInit) {
if (!this.activated) {
this.ionChange.emit({ value }); this.ionChange.emit({ value });
} else {
this.valueAfterGesture = value;
}
} }
} }
/** /**
* Emitted when the value property has changed. * Emitted when the value property has changed and any
* dragging pointer has been released from `ion-segment`.
*/ */
@Event() ionChange!: EventEmitter<SegmentChangeEventDetail>; @Event() ionChange!: EventEmitter<SegmentChangeEventDetail>;
/**
* Emitted when user has dragged over a new button
* @internal
*/
@Event() ionSelect!: EventEmitter<SegmentChangeEventDetail>;
/** /**
* Emitted when the styles change. * Emitted when the styles change.
* @internal * @internal
@ -134,6 +149,12 @@ export class Segment implements ComponentInterface {
if (checkedValidButton) { if (checkedValidButton) {
this.addRipple(detail); this.addRipple(detail);
} }
const value = this.valueAfterGesture;
if (value !== undefined) {
this.ionChange.emit({ value });
this.valueAfterGesture = undefined;
}
} }
private getButtons() { private getButtons() {