-
-
Notifications
You must be signed in to change notification settings - Fork 2.7k
feat(onClickOutside): add controls
#4537
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
if (controller) { | ||
return { | ||
stop, | ||
cancel: () => { shouldListen = false }, | ||
fire: (event: Event) => { | ||
shouldListen = true | ||
listener(event) | ||
}, | ||
} | ||
} | ||
|
||
return stop |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the long-term return of the controller should be the default here.
Maybe we can do a backwards-comparable solution for now. Not sure if this is considered hacky or not:
What if we return something like this:
const useXY = ()=>{
const controller /* is actually stop function */ = ()=>{
// stop logic
}
controller.cancel = ()=>{
shouldListen = false
}
controller.stop = ()=>{
// stop logic
}
controller.fire = (event)=>{
shouldListen = true
listener(event)
}
return controller
}
This should allow
const stop = useXY()
stop()
// AND
const {stop, fire, cancel} = useXY()
stop()
// ...
This means that we do not need an extra option.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO the long-term return of the controller should be the default here.
That's what I think too.
This means that we do not need an extra option.
I considered this option but it feels like anti-pattern and look ugly. And more importantly this is a breaking change for types. Without controller, handler
function's first argument receives PointerEvent
type. When controller is enabled it becomes Event. Similar to when detectIframe
enabled, it's FocusEvent | PointerEvent
.
If we decide to pursue controller approach, in next major, we can drop overloads, default to Event (or even Event | undefined
) and significantly simplify types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it feels like anti-pattern and look ugly
I agree with that. But it would ensure that a breaking change can also be a little softer.
If we decide to pursue controller approach, in next major, we can drop overloads, default to Event (or even
Event | undefined
) and significantly simplify types.
When we do, we might consider making sure that all composables return an object. That way we are consistent and future proof.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I considered this option but it feels like anti-pattern and look ugly. And more importantly this is a breaking change for types. Without controller,
handler
function's first argument receivesPointerEvent
type. When controller is enabled it becomes Event. Similar to whendetectIframe
enabled, it'sFocusEvent | PointerEvent
.
Just for reference, the vue 3.5 watcher does exactly this pattern: https://github.com/vuejs/core/blob/7ecd2a22c799d85b0c9857e48d97de5755197e87/packages/reactivity/src/watch.ts#L324-L328. Not to say it is not an anti-pattern.
Partially related: #4548 (comment)
controls
Before submitting the PR, please make sure you do the following
fixes #123
).Description
Gives end users more flexibility over triggering the listener. Technically unlocks fixing issues like #4104 and #3911 on end-user side. IMO after merging this PR we should close this issues and let end-users to decide what to do in their specific situation. I shared my thoughts on these PRs why they are not mergeable and clash with the goals of onClickOutside. This is like a never ending chase game. It's better end-users to handle situation base on their needs.
Additional context