withastro / roadmap

Ideas, suggestions, and formal RFC proposals for the Astro project.
292 stars 29 forks source link

RFC: Custom client directives #278

Closed matthewp closed 1 year ago

matthewp commented 2 years ago

Summary

Provide an API on top of integrations to allow them to define custom client directives. An example usage would be:

---
import Counter from '../components/Counter.jsx';
---

<Counter client:interaction="hover" />

Links

matthewp commented 2 years ago
igorbt commented 1 year ago

@matthewp , I'm glad to find this great proposal so well defined, I was thinking of something similar these days.

Would it be possible to make DirectiveOptions['value'] to be of any type? I'm not sure if being of type string is a limitation of the current directives implementation or not, but making it possible to pass more structured options to the custom directive would make it more usable and re-usable.

Building on the client:click directive example, maybe I have the "classic" counter component and I want to load and hydrate the component only on click on the buttons. Then I could give it options like this:

<Counter client:click={{
    selector: 'button',
}}/>

where selector is a CSS selector within the element that would trigger it. With the current proposal I cannot reuse the same click directive for several use-cases, I need to keep creating new ones and give them different names / keys.

Then we may even think of a pretty generic client directive like client:interactive that would cover probable 90% of use-cases:

<Counter client:interactive={{
    event: 'click',
    selector: 'button',
    loadingClass: 'loading',
}}/>

What do you think?

wassfila commented 1 year ago

using client directives, always result in a minimal client script, that runs, monitor then event, purpose is to deferr loading more scripts for later. Some directives are good and intuitive, increasing this to become more custom is not far from having code like this, when the dynamic import can be used and conditioned by any needed user logic. This can keeps code clarity over framework magic solutions.

<script>
    const card = await import('./Card')
    card.init_card(".card")
</script>
Princesseuh commented 1 year ago

We've revamped our roadmap process! As such, this proposal goes back to being a Stage 1 proposal (albeit very much more advanced than the average one, so it might go back to Stage 2 and 3 very quickly), so we'll pursue discussion into the GitHub discussion thread: https://github.com/withastro/roadmap/discussions/272