Skip to content

Commit

Permalink
Add composable for hook management
Browse files Browse the repository at this point in the history
  • Loading branch information
kadiryazici committed Feb 28, 2024
1 parent 7d85547 commit 41ac3ac
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 19 deletions.
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"@tauri-apps/api": "^1.5.3",
"@vueuse/core": "^10.7.2",
"dayjs": "^1.11.10",
"klona": "^2.0.6",
"overlayscrollbars": "^2.5.0",
"overlayscrollbars-vue": "^0.5.7",
"p-all": "^5.0.0",
Expand All @@ -37,6 +38,7 @@
"@tauri-apps/cli": "^1.5.3",
"@types/node": "^20.11.16",
"@vitejs/plugin-vue": "5.0.3",
"@vue/devtools": "^7.0.15",
"async-mutex": "^0.4.1",
"eslint": "^8.56.0",
"eslint-plugin-unicorn": "^51.0.1",
Expand Down
16 changes: 12 additions & 4 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

18 changes: 3 additions & 15 deletions src/components/Popover.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { type InjectionKey, type Ref, inject, onScopeDispose, provide, ref, watc
import { type AlignedPlacement, type ReferenceElement, type Side, Wowerlay, type WowerlayTransitionFn } from 'wowerlay'
import { useEventListener } from '@vueuse/core'
import { useKey } from '../composables/useKey'
import { useCustomHook } from '../composables/useCustomHook'
type PopoverContext = {
visible: Ref<boolean>
Expand Down Expand Up @@ -75,20 +76,7 @@ const handleTransition: WowerlayTransitionFn = (type, { popover }, done) => {
}
}
const popoverVisibleHooks = new Set<(el: ReferenceElement) => void>()
function runPopoverVisibleHooks(el: ReferenceElement) {
for (const cb of popoverVisibleHooks)
cb(el)
}
export function onPopoverVisible(cb: (el: ReferenceElement) => void) {
popoverVisibleHooks.add(cb)
const cleanup = () => popoverVisibleHooks.delete(cb)
onScopeDispose(cleanup)
return cleanup
}
export const [onPopoverVisible, emitPopoverVisible] = useCustomHook<[el: ReferenceElement]>()
</script>

<script lang="ts" setup>
Expand Down Expand Up @@ -140,7 +128,7 @@ watch(visible, (value) => {
setTimeout(() => {
popoverEl.value?.focus()
})
runPopoverVisibleHooks(props.target as ReferenceElement)
emitPopoverVisible(props.target as ReferenceElement)
}
else {
setTimeout(() => lastFocusedElement instanceof HTMLElement && lastFocusedElement.focus())
Expand Down
46 changes: 46 additions & 0 deletions src/composables/useCustomHook.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import { tryOnScopeDispose } from '@vueuse/core'

/**
* @example
* ```ts
* const [onCreate, emitCreate] = useCustomHook<[id: number]>();
* onCreate((id) => console.log('created', id));
* emitCreate(1);
* ```
*/
export function useCustomHook<const T extends readonly unknown[] = []>() {
const hooks = new Set<(...args: T) => void>()

let disposed = false

tryOnScopeDispose(() => {
disposed = true
hooks.clear()
})

function emit(...args: T) {
if (disposed)
return

for (const hook of hooks)
hook(...args)
}

function on(hook: (...args: T) => void) {
if (disposed)
return () => {}

hooks.add(hook)
tryOnScopeDispose(() => hooks.delete(hook))

return () => {
hooks.delete(hook)
}
}

function clear() {
hooks.clear()
}

return [on, emit, clear] as const
}

0 comments on commit 41ac3ac

Please sign in to comment.