Skip to content

Commit

Permalink
feat!: add disabled and respectDisabledAttribute options
Browse files Browse the repository at this point in the history
- add disabled option to disable the wave effect on an element
- add respectDisabledAttribute option to respect the html disabled attribute on an element

Resolves #543

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
  • Loading branch information
justintaddei committed Jun 27, 2024
1 parent 9aa28ec commit 3673f0e
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 23 deletions.
35 changes: 23 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,10 @@ After installing and registering the plugin, this is all you need to get started
- [easing](#easing)
- [cancellationPeriod](#cancellationperiod)
- [trigger](#trigger)
- [disabled](#disabled)
- [respectDisabledAttribute](#respectdisabledattribute)
- [tagName](#tagname)
- [Using triggers](#using-triggers)
- [Disabling the directive](#disabling-the-directive)
- [Advanced](#advanced)
- [Registering the directive locally](#registering-the-directive-locally)
- [Local registration with Composition API:](#local-registration-with-composition-api)
Expand Down Expand Up @@ -519,6 +520,27 @@ export default {

</details>

#### disabled

- **type:** `boolean`
- _default:_ `false`

> Disables the wave effect on the element regardless of [`respectDisabledAttribute`](#respectdisabledattribute).
#### respectDisabledAttribute

- **type:** `boolean`
- _default:_ `true`

> When `true`, the wave effect will be disabled if the html `disabled` attribute is present on the element.
```html
<!-- The wave will *not* appear on this button -->
<button v-wave disabled>Click me!</button>
<!-- The wave *will* appear on this button -->
<button v-wave="{respectDisabledAttribute: false}" disabled>Click me!</button>
```

#### tagName

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

> Triggers that use an ID support many-to-many relationships. See the grid example on the [example page](https://justintaddei.github.io/v-wave).
### Disabling the directive

If you need to temporarily disable the wave effect, simply pass `false` to the directive.

> Note that v-wave checks for strict `false` equality (`=== false`).
> Using any other _falsely_ value will **not** disable the directive.
```html
<button v-wave="false">Click me!</button>
```

## Advanced

### Registering the directive locally
Expand Down
2 changes: 2 additions & 0 deletions src/__snapshots__/options.test.ts.snap
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,13 @@ exports[`has documented default options 1`] = `
"cancellationPeriod": 75,
"color": "currentColor",
"directive": "wave",
"disabled": false,
"dissolveDuration": 0.15,
"duration": 0.4,
"easing": "ease-out",
"finalOpacity": 0.1,
"initialOpacity": 0.2,
"respectDisabledAttribute": true,
"tagName": "div",
"trigger": "auto",
}
Expand Down
16 changes: 8 additions & 8 deletions src/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { App, Directive, DirectiveBinding } from 'vue'
import type { App, Directive } from 'vue'
import { DEFAULT_PLUGIN_OPTIONS, IVWaveDirectiveOptions, IVWavePluginOptions } from './options'
import { getHooks } from './utils/hookKeys'
import { markWaveBoundary } from './utils/markWaveBoundary'
import { triggerIsID } from './utils/triggerIsID'
import { wave } from './wave'

const optionMap = new WeakMap<HTMLElement, Partial<IVWaveDirectiveOptions> | false>()
const optionMap = new WeakMap<HTMLElement, Partial<IVWaveDirectiveOptions>>()

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

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

markWaveBoundary(el, (value && value.trigger) ?? globalOptions.trigger)
Expand All @@ -58,20 +58,20 @@ const createDirective = (
wave(event, el, options)
})
},
[hooks.updated](el: HTMLElement, { value = {} }: DirectiveBinding<Partial<IVWaveDirectiveOptions> | false>) {
[hooks.updated](el, { value = {} }) {
optionMap.set(el, value)
markWaveBoundary(el, (value && value.trigger) ?? globalOptions.trigger)
},
}

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

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

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

if (trigger === 'true') el.removeEventListener('pointerdown', handleTrigger)
Expand Down
25 changes: 25 additions & 0 deletions src/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,31 @@ interface IVWaveDirectiveOptions {
* 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.
*
* @default
* 'div'
*/
tagName: string

/**
* Disables the wave effect on the element.
*
* @default
* false
*/
disabled: boolean

/**
* If `true`, the wave effect will be disabled if the html `disabled` attribute is present on the element.
*
* @example
* ```html
* <!-- The wave will not appear on this button -->
* <button v-wave disabled>Click me!</button>
* ```
*
* @default
* true
*/
respectDisabledAttribute: boolean
}

interface IVWavePluginOptions extends IVWaveDirectiveOptions {
Expand Down Expand Up @@ -111,6 +134,8 @@ const DEFAULT_PLUGIN_OPTIONS: IVWavePluginOptions = {
cancellationPeriod: 75,
trigger: 'auto',
tagName: 'div',
disabled: false,
respectDisabledAttribute: true,
}

export { DEFAULT_PLUGIN_OPTIONS, type IVWavePluginOptions, type IVWaveDirectiveOptions }
11 changes: 8 additions & 3 deletions src/utils/hookKeys.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import type { App } from 'vue'
import { isVue3 } from './isVue3'

const getHooks = (app: App | 'vue2' | 'vue3') => {
type v3Hooks = {
mounted: 'mounted'
updated: 'updated'
}

const getHooks = (app: App | 'vue2' | 'vue3'): v3Hooks => {
let vue3: boolean

if (app === 'vue2') vue3 = false
Expand All @@ -13,10 +18,10 @@ const getHooks = (app: App | 'vue2' | 'vue3') => {
mounted: 'mounted',
updated: 'updated',
}
: {
: ({
mounted: 'inserted',
updated: 'componentUpdated',
}
} as unknown as v3Hooks)
}

export { getHooks }
4 changes: 4 additions & 0 deletions src/wave.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@ import { getRelativePointer } from './utils/getRelativePointer'
import { decrementWaveCount, deleteWaveCount, getWaveCount, incrementWaveCount } from './utils/wave-count'

const wave = (event: PointerEvent, el: HTMLElement, options: IVWaveDirectiveOptions) => {
if (options.disabled) return

if (options.respectDisabledAttribute && el.hasAttribute('disabled')) return

const rect = el.getBoundingClientRect()
const computedStyles = window.getComputedStyle(el)

Expand Down

0 comments on commit 3673f0e

Please sign in to comment.