Skip to content
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

Feature Request: useClickOutside #37

Open
sviripa opened this issue May 2, 2024 · 3 comments
Open

Feature Request: useClickOutside #37

sviripa opened this issue May 2, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request planned The feature/enhancement has been approved and is planned to be implemented.

Comments

@sviripa
Copy link
Contributor

sviripa commented May 2, 2024

Describe the feature in detail (code, mocks, or screenshots encouraged)

A utility function which accepts a reference to an instance of HtmlElement and a callback function and invokes a callback function when the user clicks outside of the given HtmlElement instance.

Here's how I imagine it would look like in action:

<script lang="ts">
  import { useClickOutside } from "runed";

  let container = $state<HTMLElement>();
  
  useClickOutside(container, () => console.log("clicked outside of the container"));
</script>

<div  bind:this={container}>
</div>

Alternatively, it could create a reference inside of useClickOutside and return it to the component to be attached.

<script lang="ts">
  import { useClickOutside } from "runed";
  
  let container = useClickOutside<HTMLElement>(() => console.log("clicked outside of the container"));
</script>

<div  bind:this={container}>
</div>

What type of pull request would this be?

New Feature

Provide relevant links or additional information.

No response

@sviripa sviripa added the enhancement New feature or request label May 2, 2024
@huntabyte
Copy link
Member

huntabyte commented May 2, 2024

Hey there! I think this is a great one to add!

To ensure it works with reactive values and across function boundaries, we'll want it to work like the following examples, one is passing a Getter and the other is passing a Box.

<script lang="ts">
  import { useClickOutside } from "runed";

  let container = $state<HTMLElement>();
  
  useClickOutside(() => container, () => console.log("clicked outside of the container"));
</script>

<div bind:this={container}></div>

or

<script lang="ts">
  import { useClickOutside, box } from "runed";

  const container = box<HTMLElement | null>(null)
  
  useClickOutside(container, () => console.log("clicked outside of the container"));
</script>

<div bind:this={container.value}></div>

--

A good reference point code-wise is the useElementSize, which follows a similar pattern.

We'd also want to include the ability to stop and start this functionality programmatically. It would start by default, and invoking start again wouldn't do anything unless it is stopped.

<script lang="ts">
  import { useClickOutside, box } from "runed";

  const container = box<HTMLElement | null>(null)
  
  const outsideClick = useClickOutside(container, () => console.log("clicked outside of the container"));
</script>

<button onclick={outsideClick.stop}>Stop listening for outside clicks</button>
<button onclick={outsideClick.start}>Start listening again</button>
<div bind:this={container.value}></div>

If you'd like to take a stab at this, feel free!

@sviripa
Copy link
Contributor Author

sviripa commented May 2, 2024

Makes sense to me. I'll work on this

@huntabyte
Copy link
Member

Feel free to submit an early draft PR if you'd like some feedback!

@huntabyte huntabyte changed the title useClickOutside Feature Request: useClickOutside May 2, 2024
@TGlide TGlide added the planned The feature/enhancement has been approved and is planned to be implemented. label May 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request planned The feature/enhancement has been approved and is planned to be implemented.
Projects
None yet
Development

No branches or pull requests

3 participants