mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2025-11-10 00:27:41 +08:00
fix(toggle): swipe gesture applies to knob (#27255)
Issue number: resolves #27254
---------
<!-- Please refer to our contributing documentation for any questions on
submitting a pull request, or let us know here if you need any help:
https://ionicframework.com/docs/building/contributing -->
<!-- Some docs updates need to be made in the `ionic-docs` repo, in a
separate PR. See
https://github.com/ionic-team/ionic-framework/blob/main/.github/CONTRIBUTING.md#modifying-documentation
for details. -->
<!-- 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. -->
The swipe gesture is currently applied to the entire `ion-toggle`
element. This was fine for the legacy syntax, but with the modern syntax
it means users can swipe on the label text which is not correct.
## What is the new behavior?
<!-- Please describe the behavior or changes that are being added by
this PR. -->
- The toggle now creates the gesture on the `.toggle-icon` element which
is the container for the knob for both modern and legacy syntaxes.
- Moved `touch-action: none` to the host of the legacy toggle. This was
preventing scrolling from happening on the modern toggle. I double
checked with native iOS and you can scroll when a pointer moves over a
toggle.
The structure of this fix was designed to match what `ion-range` does:
a8749929e0/core/src/components/range/range.tsx (L282-L296)
| Modern | Legacy |
| - | - |
| <video
src="https://user-images.githubusercontent.com/2721089/233431240-11f0c94f-d86b-4975-afd5-e534262a6f16.mov"></video>
| <video
src="https://user-images.githubusercontent.com/2721089/233431275-6c6f7fef-6cc0-4adc-8915-6fd5c3795ade.mov"></video>
|
## 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:
@ -33,7 +33,6 @@
|
|||||||
outline: none;
|
outline: none;
|
||||||
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
touch-action: none;
|
|
||||||
user-select: none;
|
user-select: none;
|
||||||
z-index: $z-index-item-input;
|
z-index: $z-index-item-input;
|
||||||
}
|
}
|
||||||
@ -50,6 +49,8 @@
|
|||||||
|
|
||||||
:host(.legacy-toggle) {
|
:host(.legacy-toggle) {
|
||||||
contain: content;
|
contain: content;
|
||||||
|
|
||||||
|
touch-action: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
:host(.ion-focused) input {
|
:host(.ion-focused) input {
|
||||||
@ -240,8 +241,6 @@ input {
|
|||||||
|
|
||||||
background: var(--track-background);
|
background: var(--track-background);
|
||||||
|
|
||||||
pointer-events: none;
|
|
||||||
|
|
||||||
overflow: inherit;
|
overflow: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -40,6 +40,8 @@ export class Toggle implements ComponentInterface {
|
|||||||
private lastDrag = 0;
|
private lastDrag = 0;
|
||||||
private legacyFormController!: LegacyFormController;
|
private legacyFormController!: LegacyFormController;
|
||||||
private inheritedAttributes: Attributes = {};
|
private inheritedAttributes: Attributes = {};
|
||||||
|
private toggleTrack?: HTMLElement;
|
||||||
|
private didLoad = false;
|
||||||
|
|
||||||
// This flag ensures we log the deprecation warning at most once.
|
// This flag ensures we log the deprecation warning at most once.
|
||||||
private hasLoggedDeprecationWarning = false;
|
private hasLoggedDeprecationWarning = false;
|
||||||
@ -157,23 +159,42 @@ export class Toggle implements ComponentInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async connectedCallback() {
|
async connectedCallback() {
|
||||||
const { el } = this;
|
this.legacyFormController = createLegacyFormController(this.el);
|
||||||
|
|
||||||
this.legacyFormController = createLegacyFormController(el);
|
/**
|
||||||
|
* If we have not yet rendered
|
||||||
this.gesture = (await import('../../utils/gesture')).createGesture({
|
* ion-toggle, then toggleTrack is not defined.
|
||||||
el,
|
* But if we are moving ion-toggle via appendChild,
|
||||||
gestureName: 'toggle',
|
* then toggleTrack will be defined.
|
||||||
gesturePriority: 100,
|
*/
|
||||||
threshold: 5,
|
if (this.didLoad) {
|
||||||
passive: false,
|
this.setupGesture();
|
||||||
onStart: () => this.onStart(),
|
}
|
||||||
onMove: (ev) => this.onMove(ev),
|
}
|
||||||
onEnd: (ev) => this.onEnd(ev),
|
|
||||||
});
|
componentDidLoad() {
|
||||||
this.disabledChanged();
|
this.setupGesture();
|
||||||
|
this.didLoad = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private setupGesture = async () => {
|
||||||
|
const { toggleTrack } = this;
|
||||||
|
|
||||||
|
if (toggleTrack) {
|
||||||
|
this.gesture = (await import('../../utils/gesture')).createGesture({
|
||||||
|
el: toggleTrack,
|
||||||
|
gestureName: 'toggle',
|
||||||
|
gesturePriority: 100,
|
||||||
|
threshold: 5,
|
||||||
|
passive: false,
|
||||||
|
onStart: () => this.onStart(),
|
||||||
|
onMove: (ev) => this.onMove(ev),
|
||||||
|
onEnd: (ev) => this.onEnd(ev),
|
||||||
|
});
|
||||||
|
this.disabledChanged();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
if (this.gesture) {
|
if (this.gesture) {
|
||||||
this.gesture.destroy();
|
this.gesture.destroy();
|
||||||
@ -273,7 +294,7 @@ export class Toggle implements ComponentInterface {
|
|||||||
|
|
||||||
const { enableOnOffLabels, checked } = this;
|
const { enableOnOffLabels, checked } = this;
|
||||||
return (
|
return (
|
||||||
<div class="toggle-icon" part="track">
|
<div class="toggle-icon" part="track" ref={(el) => (this.toggleTrack = el)}>
|
||||||
{/* The iOS on/off labels are rendered outside of .toggle-icon-wrapper,
|
{/* The iOS on/off labels are rendered outside of .toggle-icon-wrapper,
|
||||||
since the wrapper is translated when the handle is interacted with and
|
since the wrapper is translated when the handle is interacted with and
|
||||||
this would move the on/off labels outside of the view box */}
|
this would move the on/off labels outside of the view box */}
|
||||||
|
|||||||
Reference in New Issue
Block a user