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

feat: node.eventListeners/getEventListeners(node) alternative to conditionally render internal elements, when an @Event has listeners. #5538

Open
3 tasks done
antonselukh opened this issue Mar 20, 2024 · 2 comments
Labels
Feature: Want this? Upvote it! This PR or Issue may be a great consideration for a future idea. Resolution: Refine This PR is marked for Jira refinement. We're not working on it - we're talking it through.

Comments

@antonselukh
Copy link

antonselukh commented Mar 20, 2024

Prerequisites

Describe the Feature Request

Add an ability to check whether the @event decorated property has any event listeners/subscribers.
There is currently no way to check if a callback function was assigned to this event prop.

Describe the Use Case

The original idea was to create a resuable component, containing a conditionally-rendered button as part of the component template outside of <slot>. The button needs to have an onClick action, but since it's inside the template, an @event decorator will be used on <Host> and we link onClick handler with action.emit().
But the conditional rendering has to be done with @Prop() hasAction:boolean
<SomeComponent hasAction={true} onAction={handler}/>

Describe Preferred Solution

A preferred solution would be to be able to check if the action has listeners/callback subscribed and based on that, render or hide the button in the template.

Angular offers this soluton using this.click.observers.length > 0

then the result with button would look like: <SomeComponent onAction={handler}/>
without button: <SomeComponent />

Describe Alternatives

An alternative could be a custom attribute added to the <Host> after rendering, e.g. reflect-event="action", which we could access via elementRef.
On the other hand it can be also done via children inside of , but then wiring between internal logic of and will be harder

Chromium Devtools offers node.eventListeners(); and getEventListeners(node), but of course it's not part of native DOM API.

Related Code

No response

Additional Information

No response

@ionitron-bot ionitron-bot bot added the triage label Mar 20, 2024
@christian-bromann christian-bromann self-assigned this Mar 25, 2024
@christian-bromann
Copy link
Member

Thanks for raising the issue @antonselukh. I think it is a perfectly viable request. I sketched a component the way I think you've described it:

import { Component, Fragment, Event, h, EventEmitter, Watch } from '@stencil/core';

@Component({
  tag: 'my-component',
  styleUrl: 'my-component.css',
  shadow: true,
})
export class MyComponent {
  @Event({
    eventName: 'dynamicListener',
    composed: true,
    cancelable: true,
    bubbles: true,
  }) dynamicListener: EventEmitter<HTMLButtonElement>;

  @Watch('dynamicListener')
  watchListenerHandler(newValue: boolean, oldValue: boolean) {
    console.log('The old value of activated is: ', oldValue);
    console.log('The new value of activated is: ', newValue);
  }

  render() {
    const self = this;
    /**
     * fails because Stencil's EventListener currently only provides
     * the following interface: { emit: (data: any) => void }
     */
    const hasListener = this.dynamicListener.observers.length > 0;

    const btn = hasListener
      ? (<button onClick={function () {
        return self.dynamicListener.emit(this)
        }}>
          Hello
        </button>
      )
      : <>not</>
    return <div>click me: {btn}</div>;
  }
}

I will ingest this into our backlog for the team to prioritize.

@christian-bromann christian-bromann added Feature: Want this? Upvote it! This PR or Issue may be a great consideration for a future idea. Resolution: Refine This PR is marked for Jira refinement. We're not working on it - we're talking it through. and removed triage labels Mar 25, 2024
@antonselukh
Copy link
Author

@christian-bromann appreciate it

@christian-bromann christian-bromann removed their assignment Apr 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature: Want this? Upvote it! This PR or Issue may be a great consideration for a future idea. Resolution: Refine This PR is marked for Jira refinement. We're not working on it - we're talking it through.
Projects
None yet
Development

No branches or pull requests

2 participants