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

Provide object form of emits from public composables #10775

Closed
yusufkandemir opened this issue Sep 22, 2021 · 2 comments
Closed

Provide object form of emits from public composables #10775

yusufkandemir opened this issue Sep 22, 2021 · 2 comments
Labels
breaking-change Fixes/improvements which are breaking changes and will require a new major version kind/feature 💡

Comments

@yusufkandemir
Copy link
Member

Is your feature request related to a problem? Please describe.
Currently, the only relevant example I could find is useDialogPluginComponent, so I am going to use it in the examples.

If you only use the emits from useDialogPluginComponent, it's not a big problem.

emits: useDialogPluginComponent.emits

However, if you want to add more options to the list, it gets a bit different. If you are fine with the array form, it's easy:

emits: [
  ...useDialogPluginComponent.emits,
  'some-event'
]

But if you want to use the object form for payload validation, better type support, etc. you would need a workaround, something like this:

emits: {
   ...Object.fromEntries(useDialogPluginComponent.emits.map(eventName => [eventName, (...args: unknown[]) => true])),
  'some-event': (x: number) => x > 0,
},

the obvious problem is the complexity. Type support of dialog plugin emits is also another concern. While it's not a really big problem since it's possible to just use the methods returned from useDialogPluginComponent() most of the time, it would be nice to have it.

Describe the solution you'd like
It would be much better if useDialogPluginComponent.emits were defined in the object form. Then we would be able to easily use it like this:

emits: {
   ...useDialogPluginComponent.emits,
  'some-event': (x: number) => x > 0,
},

and have payload validation and type support at the same time.

This would still work, and it will have extra features like payload validation and type support as mentioned earlier:

emits: useDialogPluginComponent.emits,

If someone wants to keep it simple and use the array form, they can use this:

emits: {
   ...Object.keys(useDialogPluginComponent.emits),
  'some-event',
},

which is a much simpler solution compared to the workaround for using array form inside object form.

Describe alternatives you've considered
We might provide the object form in a new property useDialogPluginComponent.emitsObject, along with the old emits property to support both approaches without introducing a breaking change, ship it in v2, then replace it with the approach above in v3.

Additional context
There is a rule called vue/require-emit-validator which enforces the object form to benefit from the nice additions that are explained above. By making the proposed changes, we also make it possible for our users to use that rule while using useDialogPluginComponent.emits along with their own emits.

@yusufkandemir yusufkandemir added kind/feature 💡 breaking-change Fixes/improvements which are breaking changes and will require a new major version labels Sep 22, 2021
@IlCallo
Copy link
Member

IlCallo commented Sep 22, 2021

Here's a small proxy composable which can be used to solve this problem for now, which also expose some helpers to show and hide the dialog

import { useDialogPluginComponent } from 'quasar';

export function useDialog() {
  const dialogComposable = useDialogPluginComponent();

  function show() {
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    dialogComposable.dialogRef.value!.show();
  }

  function hide() {
    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
    dialogComposable.dialogRef.value!.hide();
  }

  return { ...dialogComposable, show, hide };
}

useDialog.emits = useDialogPluginComponent.emits;
useDialog.emitsObject = Object.fromEntries(
  useDialogPluginComponent.emits.map((eventName) => [
    eventName,
    (...args: unknown[]) => !!args,
  ]),
);

@rstoenescu
Copy link
Member

Enhancement will be available in Quasar v2.2.5.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
breaking-change Fixes/improvements which are breaking changes and will require a new major version kind/feature 💡
Projects
None yet
Development

No branches or pull requests

3 participants