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

Dispatch cancelable events with createEventDispatcher #4623

Closed
Oreilles opened this issue Apr 1, 2020 · 8 comments · Fixed by #7064
Closed

Dispatch cancelable events with createEventDispatcher #4623

Oreilles opened this issue Apr 1, 2020 · 8 comments · Fixed by #7064

Comments

@Oreilles
Copy link

Oreilles commented Apr 1, 2020

From the docs:

Component events created with createEventDispatcher create a CustomEvent. These events do not bubble and are not cancellable with event.preventDefault().

I understand why they couldn't bubble, but is there any reason why cancelable event aren't allowed ? It would only require adding one line in createEventDispatcher declaration (from /src/runtime/internal/lifecycle.ts)

export function createEventDispatcher() {
	const component = get_current_component();

	return (type: string, detail?: any): boolean => {
		const callbacks = component.$$.callbacks[type];

		if (callbacks) {
			const event = custom_event(type, detail);
			callbacks.slice().forEach(fn => {
				fn.call(component, event);
			});
			
			// Just add this line
			return !event.defaultPrevented
		}
	};
}

and a slightly different signature for custom_event (from /src/runtime/internal/dom.ts)

export function custom_event<T=any>(type: string, detail?: T, cancelable?: boolean){}
// or anything else
@hackape
Copy link
Contributor

hackape commented Jan 20, 2021

I for one support this proposal. Non-bubble is alright, but banning cancellable seems pointless. If allow to cancel, this opens up possibility for some meaningful use cases.

For example, a Tabs component.

<script lang='ts'>
export let selectedTabKey
export let tabs: { key: string; name: string }[] = []

const selectTab = (tabKey: string) => {
  const success = dispatch('selectTab', tabKey)
  if (success) {
    selectedTabKey = tabKey
  }
}
</script>

<div class='tab-bar'>
{#each tabs as tab (tab.key)}
  <div class="tab" on:click={() => selectTab(tab.key)}>{tab.name}</div>
{/each}
</div>

<div class="content">
  <slot {selectedTabKey} />
</div>

If custom event is cancelable, this opens up a way for parent component to communicate to child component the intention that "I wanna take over control of your behavior".

@hackape
Copy link
Contributor

hackape commented Jan 20, 2021

My two cent to add: I prefer the dispatch() function to return the custom event object instead of just a boolean. That would provide even more flexibility.

@sethjeffery
Copy link

sethjeffery commented Jan 26, 2021

Just ran into this missing feature when trying to build a Dropdown component. Would be great to be able to allow the containing component to cancel an event. I am hoping to see functionality like the following:

<script>
  let showDropdown = false;

  function handleClickButton() {
    const event = dispatch('open');
    if(!event.defaultPrevented()) {
      showDropdown = true;
    }
  }

  function handleClickOutside() {
    const event = dispatch('close');
    if(!event.defaultPrevented()) {
      showDropdown = false;
    }
  }
</script>

@stale
Copy link

stale bot commented Jun 26, 2021

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@PuruVJ
Copy link
Collaborator

PuruVJ commented Dec 25, 2021

Any chance of this landing anytime soon? Would help us library authors a lot, until then we're stuck with React style onCustomEvent rather than svelte style on:custom-event

@bluwy
Copy link
Member

bluwy commented Dec 28, 2021

The internal custom_event function seems to support bubbles a while ago after this issue was created, so it makes sense for me for it to support cancelable as well. Made #7064 which supports both cancelable and bubbles option in the third argument of dispatch

@krisgardiner
Copy link

Any chance we can get #7064 merged? We're also looking forward to getting this feature.

@Conduitry
Copy link
Member

This is supported now in 3.48.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

9 participants