RevealBi / reveal-sdk-wrappers

0 stars 0 forks source link

WebComponents Feedback #2

Open dwilches opened 5 hours ago

dwilches commented 5 hours ago

I'm testing the Beta of Web Components, and the documentation instructs me to use CUSTOM_ELEMENTS_SCHEMA. Using this is something we wouldn't like to do in our app as that makes Angular's compiler to not warn us about legitimate errors, like a typo in a component's name or a component that is outside of the scope of the current module.

Moreover, the documentation says:

Add this schema to your application's module

Which is not really accurate, it should be added to the module from where the users are going to invoke the Reveal web components. In Angular, each module can choose to use CUSTOM_ELEMENTS_SCHEMA, and only in those modules where you allow unknown elements you can use unknown elements (it is not inherited by submodules either).

Instead of instructing your users to use CUSTOM_ELEMENTS_SCHEMA and the defineRevealSdkWrappers() you could encapsulate both in an Angular module, hiding the fact we're using web components as they'll be plain Angular components. This can be done by creating a module called RevealWebComponentsModule, which invokes defineRevealSdkWrappers() and contains CUSTOM_ELEMENTS_SCHEMA. Then your users would import that module in any module they want.

Doing it this way has a second added benefit: if you abstract each web component inside of an Angular component, you'll get full IDE support: contextual documentation for inputs and components, and detection of wrong input/output names or types.

And another added benefit is it allows users to load only the subset of components they want by importing the desired modules (which is a more Angular way of doing it than invoking a global function).

By the way, there is no need to put the <script> tags in the HTML page, that can be lazy-loaded too with: import("./reveal-deps") from the Angular module.

brianlagunas commented 5 hours ago

Just to clarify, you would recommend creating a new package called reveal-sdk-wrappers-angular.

In this package would simply be a module that handles the imports and registrations automatically. So, when a developer imports the module into their application, all the heavy lifting is done automatically.

I like this idea, and is similar to what we do for React.

I do need clarification on one thing you mentioned. You said "if you abstract each web component inside of an Angular component". Do you mean create a native angular component to wrap the existing web components and then duplicate all the properties/methods and bind them to the existing web components? Or is there a different approach you know of?

dwilches commented 4 hours ago

you would recommend creating a new package called reveal-sdk-wrappers-angular.

Yes, I think creating a separate package for the Angular library would make the setup straightforward. This library would depend on reveal-sdk-wrappers but for the end-users it would be a transitive dependency they don't even know about.

Do you mean create a native angular component to wrap the existing web components and then duplicate all the properties/methods and bind them to the existing web components

Yes, exactly that. I don't know of a different approach than duplicating the inputs/outputs. Even when migrating from Angular.js to Angular with the code the Angular team created, us end-users had to duplicate them. From here:

image

brianlagunas commented 3 hours ago

I'm concerned about the maintainability of duplicating the properties and methods. Especially since the RevealView has some nuisances about how certain features are enabled by setting callback functions to properties. It would add quite a bit to my maintenance overhead. Since web components do work natively in Angular, maybe if we improve the guidance around using the web components, it would be a nice balance between maintaining the library and making it easy to use.

Would shipping the RevealWebComponentsModule with just the registrations and CUSTOM_ELEMENTS_SCHEMA be a nice balance? At least this way there is no manual registration needed and it protects your code from the Angular's compiler to not warn us about legitimate errors.

Thougths?

dwilches commented 3 hours ago

duplicating the properties and methods.

Actually only the declarations of inputs and outputs need to be duplicated, not the methods. But yes, each time a new input/output is added on the web-component, you'd need to declare it on the Angular side too.

Would shipping the RevealWebComponentsModule with just the registrations and CUSTOM_ELEMENTS_SCHEMA be a nice balance?

For end-users to use <rv-reveal-view> without CUSTOM_ELEMENTS_SCHEMA in their own modules, they'll need a declaration of what a rv-reveal-view component is, so RevealWebComponentsModule needs to export something with that selector anyways. Unless I'm missing something about the proposed solution.

brianlagunas commented 3 hours ago

Actually only the declarations of inputs and outputs need to be duplicated, not the methods.

If I had a method/function on the web component called exportToPdf() wouldn't I need to get a ref to the web component, and then expose that method/function on the angular wrapper as well?

brianlagunas commented 2 hours ago

Also, one more question...

If we did a native angular wrapper which copies the inputs/outputs, what do you think the name of the selector should be? Since we cannot reuse rv-reveal-view, we would need another name.

brianlagunas commented 2 hours ago

I created a branch where I can play with ideas and possibly support your request. Feel free to review and give your thoughts. I am not an angular dev, but I know enough to be dangerous 😃

https://github.com/RevealBi/reveal-sdk-wrappers/blob/angular/packages/wrappers-angular/src/components/reveal-view/reveal-view.component.ts