Skip to content

Commit 1822dc3

Browse files
committed
feat(toggle): make iOS haptic feedback configurable
1 parent b29e007 commit 1822dc3

File tree

3 files changed

+27
-3
lines changed

3 files changed

+27
-3
lines changed

core/src/components/toggle/test/toggle.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { setMode } from '@stencil/core';
12
import { newSpecPage } from '@stencil/core/testing';
23

34
import { config } from '../../../global/config';
@@ -53,6 +54,21 @@ describe('toggle', () => {
5354
expect(toggle).toHaveShadowPart('handle');
5455
});
5556
});
57+
58+
describe('iOS haptic feedback', () => {
59+
it('should render additional elements when enabled in config', async () => {
60+
setMode(() => 'ios');
61+
const t = await newToggle();
62+
expect(t['hapticEl']).toBeNull();
63+
64+
config.reset({
65+
toggleIOSHapticFeedback: true,
66+
});
67+
68+
const t2 = await newToggle();
69+
expect(t2['hapticEl']).not.toBeNull();
70+
});
71+
});
5672
});
5773

5874
describe('ion-toggle: disabled', () => {

core/src/components/toggle/toggle.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ export class Toggle implements ComponentInterface {
3434
private inputId = `ion-tg-${toggleIds++}`;
3535
private gesture?: Gesture;
3636
private focusEl?: HTMLElement;
37-
private hapticEl?: HTMLElement;
37+
private enableIOSHapticFeedback = config.getBoolean('toggleIOSHapticFeedback', false);
38+
private hapticEl?: HTMLElement | null = null;
3839
private lastDrag = 0;
3940
private inheritedAttributes: Attributes = {};
4041
private toggleTrack?: HTMLElement;
@@ -139,7 +140,7 @@ export class Toggle implements ComponentInterface {
139140
const isNowChecked = !checked;
140141
this.checked = isNowChecked;
141142

142-
if (this.hapticEl) {
143+
if (this.enableIOSHapticFeedback && this.hapticEl) {
143144
this.hapticEl.click();
144145
}
145146

@@ -300,7 +301,7 @@ export class Toggle implements ComponentInterface {
300301
const { inputId } = this;
301302
const mode = getIonMode(this);
302303

303-
if (hapticAvailable() || mode !== 'ios') {
304+
if (!this.enableIOSHapticFeedback || hapticAvailable() || mode !== 'ios') {
304305
return;
305306
}
306307

core/src/utils/config.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,13 @@ export interface IonicConfig {
7171
*/
7272
toggleOnOffLabels?: boolean;
7373

74+
/**
75+
* Whenever changing the toggle state should produce a haptic feedback (slight vibration)
76+
* on iOS in browser and PWA environments. Requires iOS 18 or later.
77+
* Defaults to `false`.
78+
*/
79+
toggleIOSHapticFeedback?: boolean;
80+
7481
/**
7582
* Overrides the default spinner for all `ion-loading` overlays, ie. the ones
7683
* created with `ion-loading-controller`.

0 commit comments

Comments
 (0)