prefer-disable-handler
Require a wrapper method (default: disableHandler($event, work)) on configured element/event bindings to prevent double taps while async work runs
- ⭐️ This rule is included in
plugin:@rdlabo/rules/recommendedpreset.
disableHandler (from @rdlabo/ionic-angular-kit) disables the triggering control while an async operation runs and restores it when the Promise settles. Using it on sync work is harmless: the control is briefly disabled and re-enabled, and if no disableable target is found it is a no-op.
Element names, event names, and the wrapper method name are all configurable so the same rule can cover fleet defaults and repo-specific bindings (e.g. (ionComplete)).
Enabling this rule in recommended will flag existing templates that call async work without the wrapper — expect a migration pass when bumping the plugin.
Rule Details
❌ Incorrect (defaults)
<ion-button (click)="vm.save()">Save</ion-button>
<form (submit)="vm.save()"></form>
Also incorrect — wrapper must receive $event and a second work argument:
<ion-button (click)="vm.disableHandler($event)">Save</ion-button>
<ion-button (click)="vm.disableHandler(vm.save())">Save</ion-button>
✅ Correct (defaults)
<ion-button (click)="vm.disableHandler($event, vm.save())">Save</ion-button>
<form (submit)="vm.disableHandler($event, vm.save())"></form>
Allowed without the wrapper (event-only, defaults):
<ion-button (click)="$event.stopPropagation()"></ion-button>
<ion-button (click)="$event.preventDefault()"></ion-button>
Out of scope by default (not listed in targets.elements):
<ion-chip (click)="vm.toggle()"></ion-chip>
<ion-item [button]="true" (click)="vm.open()"></ion-item>
Options
{
method?: string; // default: 'disableHandler'
eventParam?: string; // default: '$event'
targets?: Array<{
events: string[]; // e.g. ['click'], ['submit'], ['ionComplete']
elements?: string[]; // omit / [] = any element for those events
}>;
allowEventMethods?: string[]; // default: ['stopPropagation', 'preventDefault']
}
targets fully replaces the default list (it is not merged). To keep click/submit and add more bindings, re-list the defaults plus your extras.
Defaults
{
method: 'disableHandler',
eventParam: '$event',
targets: [
{ events: ['click'], elements: ['ion-button', 'button'] },
{ events: ['submit'] }, // any element
],
allowEventMethods: ['stopPropagation', 'preventDefault'],
}
Examples
Require a custom wrapper name:
'@rdlabo/rules/prefer-disable-handler': ['error', { method: 'guardClick' }]
Also enforce (ionComplete) on ion-input (re-list default targets):
'@rdlabo/rules/prefer-disable-handler': [
'error',
{
targets: [
{ events: ['click'], elements: ['ion-button', 'button'] },
{ events: ['submit'] },
{ events: ['ionComplete'], elements: ['ion-input'] },
],
},
]