Skip to content

Commit c499cc4

Browse files
committed
feat!: add disabled and respectDisabledAttribute options
- add disabled option to disable the wave effect on an element - add respectDisabledAttribute option to respect the html disabled attribute on an element BREAKING CHANGE: the disabled attr now disables the wave effect on the element BREAKING CHANGE: removed the ability to disable the wave effect by passing `false` to the directive
1 parent 9aa28ec commit c499cc4

File tree

6 files changed

+70
-23
lines changed

6 files changed

+70
-23
lines changed

README.md

Lines changed: 23 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,10 @@ After installing and registering the plugin, this is all you need to get started
7272
- [easing](#easing)
7373
- [cancellationPeriod](#cancellationperiod)
7474
- [trigger](#trigger)
75+
- [disabled](#disabled)
76+
- [respectDisabledAttribute](#respectdisabledattribute)
7577
- [tagName](#tagname)
7678
- [Using triggers](#using-triggers)
77-
- [Disabling the directive](#disabling-the-directive)
7879
- [Advanced](#advanced)
7980
- [Registering the directive locally](#registering-the-directive-locally)
8081
- [Local registration with Composition API:](#local-registration-with-composition-api)
@@ -519,6 +520,27 @@ export default {
519520

520521
</details>
521522

523+
#### disabled
524+
525+
- **type:** `boolean`
526+
- _default:_ `false`
527+
528+
> Disables the wave effect on the element regardless of [`respectDisabledAttribute`](#respectdisabledattribute).
529+
530+
#### respectDisabledAttribute
531+
532+
- **type:** `boolean`
533+
- _default:_ `true`
534+
535+
> When `true`, the wave effect will be disabled if the html `disabled` attribute is present on the element.
536+
537+
```html
538+
<!-- The wave will *not* appear on this button -->
539+
<button v-wave disabled>Click me!</button>
540+
<!-- The wave *will* appear on this button -->
541+
<button v-wave="{respectDisabledAttribute: false}" disabled>Click me!</button>
542+
```
543+
522544
#### tagName
523545

524546
- **type:** `string`
@@ -552,17 +574,6 @@ In this next example, clicking one of the buttons will activate the wave on the
552574

553575
> Triggers that use an ID support many-to-many relationships. See the grid example on the [example page](https://justintaddei.github.io/v-wave).
554576
555-
### Disabling the directive
556-
557-
If you need to temporarily disable the wave effect, simply pass `false` to the directive.
558-
559-
> Note that v-wave checks for strict `false` equality (`=== false`).
560-
> Using any other _falsely_ value will **not** disable the directive.
561-
562-
```html
563-
<button v-wave="false">Click me!</button>
564-
```
565-
566577
## Advanced
567578

568579
### Registering the directive locally

src/__snapshots__/options.test.ts.snap

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,13 @@ exports[`has documented default options 1`] = `
55
"cancellationPeriod": 75,
66
"color": "currentColor",
77
"directive": "wave",
8+
"disabled": false,
89
"dissolveDuration": 0.15,
910
"duration": 0.4,
1011
"easing": "ease-out",
1112
"finalOpacity": 0.1,
1213
"initialOpacity": 0.2,
14+
"respectDisabledAttribute": true,
1315
"tagName": "div",
1416
"trigger": "auto",
1517
}

src/index.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
1-
import type { App, Directive, DirectiveBinding } from 'vue'
1+
import type { App, Directive } from 'vue'
22
import { DEFAULT_PLUGIN_OPTIONS, IVWaveDirectiveOptions, IVWavePluginOptions } from './options'
33
import { getHooks } from './utils/hookKeys'
44
import { markWaveBoundary } from './utils/markWaveBoundary'
55
import { triggerIsID } from './utils/triggerIsID'
66
import { wave } from './wave'
77

8-
const optionMap = new WeakMap<HTMLElement, Partial<IVWaveDirectiveOptions> | false>()
8+
const optionMap = new WeakMap<HTMLElement, Partial<IVWaveDirectiveOptions>>()
99

1010
interface VWaveInstallObject {
1111
install: (app: any, globalUserOptions: Partial<IVWavePluginOptions>) => void
@@ -37,8 +37,8 @@ const createDirective = (
3737
associatedElements.forEach((el) => wave(event, el, { ...globalOptions, ...optionMap.get(el) }))
3838
}
3939

40-
const waveDirective: Directive = {
41-
[hooks.mounted](el: HTMLElement, { value = {} }: DirectiveBinding<Partial<IVWaveDirectiveOptions> | false>) {
40+
const waveDirective: Directive<HTMLElement, Partial<IVWaveDirectiveOptions>> = {
41+
[hooks.mounted](el, { value = {} }) {
4242
optionMap.set(el, value)
4343

4444
markWaveBoundary(el, (value && value.trigger) ?? globalOptions.trigger)
@@ -58,20 +58,20 @@ const createDirective = (
5858
wave(event, el, options)
5959
})
6060
},
61-
[hooks.updated](el: HTMLElement, { value = {} }: DirectiveBinding<Partial<IVWaveDirectiveOptions> | false>) {
61+
[hooks.updated](el, { value = {} }) {
6262
optionMap.set(el, value)
6363
markWaveBoundary(el, (value && value.trigger) ?? globalOptions.trigger)
6464
},
6565
}
6666

67-
const triggerDirective: Directive = {
68-
[hooks.mounted](el: HTMLElement, { arg: trigger = 'true' }: DirectiveBinding) {
67+
const triggerDirective: Directive<HTMLElement> = {
68+
[hooks.mounted](el, { arg: trigger = 'true' }) {
6969
el.dataset.vWaveTrigger = trigger
7070

7171
if (trigger !== 'true') el.addEventListener('pointerdown', handleTrigger)
7272
},
7373

74-
[hooks.updated](el: HTMLElement, { arg: trigger = 'true' }: DirectiveBinding) {
74+
[hooks.updated](el, { arg: trigger = 'true' }) {
7575
el.dataset.vWaveTrigger = trigger
7676

7777
if (trigger === 'true') el.removeEventListener('pointerdown', handleTrigger)

src/options.ts

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,8 +76,31 @@ interface IVWaveDirectiveOptions {
7676
* Sets the tag name of the element used as the wave container. This is is useful in scenarios where the default `div` may interfere with `:last-of-type` selectors.
7777
*
7878
* @default
79+
* 'div'
7980
*/
8081
tagName: string
82+
83+
/**
84+
* Disables the wave effect on the element.
85+
*
86+
* @default
87+
* false
88+
*/
89+
disabled: boolean
90+
91+
/**
92+
* If `true`, the wave effect will be disabled if the html `disabled` attribute is present on the element.
93+
*
94+
* @example
95+
* ```html
96+
* <!-- The wave will not appear on this button -->
97+
* <button v-wave disabled>Click me!</button>
98+
* ```
99+
*
100+
* @default
101+
* true
102+
*/
103+
respectDisabledAttribute: boolean
81104
}
82105

83106
interface IVWavePluginOptions extends IVWaveDirectiveOptions {
@@ -111,6 +134,8 @@ const DEFAULT_PLUGIN_OPTIONS: IVWavePluginOptions = {
111134
cancellationPeriod: 75,
112135
trigger: 'auto',
113136
tagName: 'div',
137+
disabled: false,
138+
respectDisabledAttribute: true,
114139
}
115140

116141
export { DEFAULT_PLUGIN_OPTIONS, type IVWavePluginOptions, type IVWaveDirectiveOptions }

src/utils/hookKeys.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
import type { App } from 'vue'
22
import { isVue3 } from './isVue3'
33

4-
const getHooks = (app: App | 'vue2' | 'vue3') => {
4+
type v3Hooks = {
5+
mounted: 'mounted'
6+
updated: 'updated'
7+
}
8+
9+
const getHooks = (app: App | 'vue2' | 'vue3'): v3Hooks => {
510
let vue3: boolean
611

712
if (app === 'vue2') vue3 = false
@@ -13,10 +18,10 @@ const getHooks = (app: App | 'vue2' | 'vue3') => {
1318
mounted: 'mounted',
1419
updated: 'updated',
1520
}
16-
: {
21+
: ({
1722
mounted: 'inserted',
1823
updated: 'componentUpdated',
19-
}
24+
} as unknown as v3Hooks)
2025
}
2126

2227
export { getHooks }

src/wave.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ import { getRelativePointer } from './utils/getRelativePointer'
66
import { decrementWaveCount, deleteWaveCount, getWaveCount, incrementWaveCount } from './utils/wave-count'
77

88
const wave = (event: PointerEvent, el: HTMLElement, options: IVWaveDirectiveOptions) => {
9+
if (options.disabled) return
10+
11+
if (options.respectDisabledAttribute && el.hasAttribute('disabled')) return
12+
913
const rect = el.getBoundingClientRect()
1014
const computedStyles = window.getComputedStyle(el)
1115

0 commit comments

Comments
 (0)