From 2ecddd0a58d79d93b359691f46f24b117e622099 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 7 Oct 2021 17:54:35 -0500 Subject: [PATCH 01/12] Implement forward directive --- text/0000-forward-directive.md | 97 ++++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 text/0000-forward-directive.md diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md new file mode 100644 index 0000000..8d27a07 --- /dev/null +++ b/text/0000-forward-directive.md @@ -0,0 +1,97 @@ +- Start Date: 2021-08-07 +- RFC PR: (leave this empty) +- Svelte Issue: (leave this empty) + +# The `forward` directive. + +## Summary + +This RFC proposes a new `forward` directive, which lets you forward directives used on a component instance to a DOM element in said component. This allows you to call directives such as `use`, `transition`, `animation`, etc... on a component declaration. It also allows you to delegate all events to a certain element in a component. + +## Motivation + +At the moment, there are a long list of pitfalls with community-provided component libraries. Designing a "one-size-fits-all" component in svelte can be rather tedious in the current enviornment, notably when dealing with directives. For example, if you wish to forward commonly used events to a reusable +``` + +A [solution](https://github.com/sveltejs/svelte/pull/4599) to this event issue using the `on:*` directive has been proposed. This syntax doesn't come without issues either, as `*` is nonstandard syntax in the scope of HTML events, and it doesn't reach the core limitations of component directives. + +Another common problem that comes up is when working with actions. Components are incapable of utilizing the `use` directive, meaning library authors often need to export a prop like so: +```html + + +
+``` + +While this also is effective in solving the issue, it adds further boilerplate and nonstandard syntax that other developers are forced to work with. Similar problems arise with the `transition` and `animation` directives. + +## Detailed design + +### Forwarding all events to an element + +This example uses the same +``` + +## Forwarding actions and transitions + +The `forward` directive can be similarly used to forward actions and transitions using the native syntax: + +```html + +``` + +Using the above component in parent context would look like this: + +```html + +``` + +### Implementation + +The `forward` directive's syntax would take in the name of the directive to be forwarded. For example, to forward all events using the `on` directive, the corresponding directive would be `forward:on`. + +## How we teach this + +The directive should be taught as a method of using directives such as `use` or `transition` through the parent context of a component. It should be taught as a relatively advanced feature towwards the end of the tutorial, mainly intended for package authors. It wouldn't majorly affect other documentation topics, although it might be worth noting on the [Event Forwarding](https://svelte.dev/tutorial/event-forwarding) topic of the tutorial. + +## Drawbacks + +- There are some directives that could not be forwarded, most notably `bind` and `class`. + +## Alternatives + +- Keep things the way they are. +- Use the `on:*` or the `bubble` directive proposed in [#4599](https://github.com/sveltejs/svelte/pull/4599) could be used as a solution for the event problem. Component authors could continue using nonstandard syntax for delegating other events such as `transition`, `use`, or `animation`. + +## Unresolved questions + +- How should the `bind` directive be implemented in this context? From 095fd0328aa8d3ce22445b20ce0e8365ded86266 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 7 Oct 2021 17:56:15 -0500 Subject: [PATCH 02/12] Fix formatting --- text/0000-forward-directive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 8d27a07..fa085b2 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -10,7 +10,7 @@ This RFC proposes a new `forward` directive, which lets you forward directives u ## Motivation -At the moment, there are a long list of pitfalls with community-provided component libraries. Designing a "one-size-fits-all" component in svelte can be rather tedious in the current enviornment, notably when dealing with directives. For example, if you wish to forward commonly used events to a reusable +``` +This solution has underlying issues: +- Event dispatchers lose the properties of `MouseEvent`. +- This is a lot of boilerplate to perform a simple action. + +Instead of using dispatchers to add side-effects to events, we can extend the forward event to bubble singular event types as well. This could be done like so: + +```html + + + +``` + +This pattern could be similarly applied to actions: + +```html + + + + +``` + +In this example, the `use` directive would be both forwarded to parent context as well as `internalAction` being applied. A possible pitfall would be how the animation API would play into this, as it's unclear how the compiler would deal with multiple animations. + +## Potential Changes with Svelte 4 + +It has been further proposed to completely replace the typical event forwarding syntax in the past for Svelte 4, this additional proposal would also cover that: + +```html + +``` + +would be changed to + +```html + +``` + +This is a breaking change, and likely out-of-scope. From 76a5e70a18a69e8c02ee866c84e668b4306e5f0c Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 7 Oct 2021 18:56:04 -0500 Subject: [PATCH 05/12] Update 0000-forward-directive.md --- text/0000-forward-directive.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 2387516..2b22e8d 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -153,7 +153,7 @@ In this example, the `use` directive would be both forwarded to parent context a ## Potential Changes with Svelte 4 -It has been further proposed to completely replace the typical event forwarding syntax in the past for Svelte 4, this additional proposal would also cover that: +It has been further proposed to completely replace the typical event forwarding syntax in the past for Svelte 4. This additional proposal could also cover that: ```html From f0ee66a53021a5d274a61742c128cb078384bf16 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 7 Oct 2021 19:35:47 -0500 Subject: [PATCH 06/12] Add overview topic for additional proposal --- text/0000-forward-directive.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 2b22e8d..793ef0f 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -81,7 +81,7 @@ The `forward` directive's syntax would take in the name of the directive to be f ## How we teach this -The directive should be taught as a method of using directives such as `use` or `transition` through the parent context of a component. It should be taught as a relatively advanced feature towwards the end of the tutorial, mainly intended for package authors. It wouldn't majorly affect other documentation topics, although it might be worth noting on the [Event Forwarding](https://svelte.dev/tutorial/event-forwarding) topic of the tutorial. +The directive should be taught as a method of using directives such as `use` or `transition` through the parent context of a component. It should be taught as a relatively advanced feature towards the end of the tutorial, mainly intended for package authors. It wouldn't majorly affect other documentation topics, although it might be worth noting on the [Event Forwarding](https://svelte.dev/tutorial/event-forwarding) topic of the tutorial. ## Drawbacks @@ -95,10 +95,12 @@ The directive should be taught as a method of using directives such as `use` or ## Unresolved questions - How should the `bind` directive be implemented in this context? -- How should `forward:on` or `forward:use` interact with existing `on:` or `use` directives? +- How should `forward` interact with existing `on`/`use`/`transition`/etc directives? ## Additional Proposal - `foward` effects and singular event forwarding +This section provides a possible answer to the second unresolved question, as well as a discussion of how `forward` can be integrated into Svelte 4 and onward. + Another common problem that people run into is adding side-effects to forwarded events. Suppose a developer had the aforementioned ` + ``` In this example, the `use` directive would be both forwarded to parent context as well as `internalAction` being applied. A possible pitfall would be how the animation API would play into this, as it's unclear how the compiler would deal with multiple animations. From 8e4c329c425f35266d79916747264c48eb5c49de Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Fri, 8 Oct 2021 17:23:10 -0500 Subject: [PATCH 08/12] Update RFC to match some discussed ideas. --- text/0000-forward-directive.md | 79 ++++++++++------------------------ 1 file changed, 22 insertions(+), 57 deletions(-) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 2be839d..46bbc03 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -59,6 +59,20 @@ This example uses the same ` ``` +This version of the component has an internal click handler that will run along with the forwarded `click` event. + +```html + + + +``` + ## Forwarding actions and transitions The `forward` directive can be similarly used to forward actions and transitions using the native syntax: @@ -75,6 +89,13 @@ Using the above component in parent context would look like this: ``` +Similarly to the `on` forwarding, internal actions and transitions may be used along with the `forward` directive: +``` + +``` + ### Implementation The `forward` directive's syntax would take in the name of the directive to be forwarded. For example, to forward all events using the `on` directive, the corresponding directive would be `forward:on`. @@ -95,63 +116,7 @@ The directive should be taught as a method of using directives such as `use` or ## Unresolved questions - How should the `bind` directive be implemented in this context? -- How should `forward` interact with existing `on`/`use`/`transition`/etc directives? - -## Additional Proposal - `foward` effects and singular event forwarding - -This section provides a possible answer to the second unresolved question, as well as a discussion of how `forward` can be integrated into Svelte 4 and onward. - -Another common problem that people run into is adding side-effects to forwarded events. Suppose a developer had the aforementioned ` -``` -This solution has underlying issues: -- Event dispatchers lose the properties of `MouseEvent`. -- This is a lot of boilerplate to perform a simple action. - -Instead of using dispatchers to add side-effects to events, we can extend the forward event to bubble singular event types as well. This could be done like so: - -```html - - - -``` - -This pattern could be similarly applied to actions: - -```html - - - - -``` - -In this example, the `use` directive would be both forwarded to parent context as well as `internalAction` being applied. A possible pitfall would be how the animation API would play into this, as it's unclear how the compiler would deal with multiple animations. +- How should svelte handle multiple transitions at once? Using an "internal transition" along with forwarding might result in some unexpected behavior. ## Potential Changes with Svelte 4 From a872445e17460151ae1ea8e2598b5b51d517b5df Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Sat, 20 Nov 2021 21:37:02 -0600 Subject: [PATCH 09/12] Remove remaining 3 part directive proposal, update actions example --- text/0000-forward-directive.md | 36 ++++++++++++++-------------------- 1 file changed, 15 insertions(+), 21 deletions(-) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 46bbc03..0be790a 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -39,20 +39,30 @@ A [solution](https://github.com/sveltejs/svelte/pull/4599) to this event issue u Another common problem that comes up is when working with actions. Components are incapable of utilizing the `use` directive, meaning library authors often need to export a prop like so: ```html -
+ +``` + +While this also is effective in solving the issue, it adds further boilerplate and nonstandard syntax that other developers are forced to work with. + +```html + ``` -While this also is effective in solving the issue, it adds further boilerplate and nonstandard syntax that other developers are forced to work with. Similar problems arise with the `transition` and `animation` directives. +Similar problems arise with the `transition` and `animation` directives. ## Detailed design ### Forwarding all events to an element -This example uses the same ` -``` - -would be changed to - -```html - -``` - -This is a breaking change, and likely out-of-scope. From fc05a12e978c6688174d363a828743b1399b61c9 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Thu, 2 Dec 2021 19:54:14 -0600 Subject: [PATCH 10/12] convert to nullish coalescing in custom classes --- text/0000-forward-directive.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 0be790a..5652b73 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -27,7 +27,7 @@ At the moment, there are a long list of pitfalls with community-provided compone on:keypress on:keydown on:keyup - class="button {customClass || ''}" + class="button {customClass ?? ''}" {...$$restProps} > @@ -64,7 +64,7 @@ Similar problems arise with the `transition` and `animation` directives. This example uses the same ` ``` From 0d7901214da22f3f78d7efce2895b04f03e970f3 Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 8 Feb 2022 11:11:43 -0600 Subject: [PATCH 11/12] Update 0000-forward-directive.md --- text/0000-forward-directive.md | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 5652b73..7790b09 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -99,13 +99,15 @@ Using the above component in parent context would look like this: ``` -Similarly to the `on` forwarding, internal actions and transitions may be used along with the `forward` directive: +Similarly to the `on` forwarding, internal actions may be used along with the `forward` directive: ``` - ``` +Note: A transition directive cannot be both forwarded and used internally, since [DOM elements can only have one transition](https://svelte.dev/repl/08236eb2bbc6474bad75d1aee43b2628). + ### Implementation The `forward` directive's syntax would take in the name of the directive to be forwarded. For example, to forward all events using the `on` directive, the corresponding directive would be `forward:on`. @@ -116,7 +118,8 @@ The directive should be taught as a method of using directives such as `use` or ## Drawbacks -- There are some directives that could not be forwarded, most notably `bind` and `class`. +- There are some directives that could not be forwarded, most notably `bind`. +- You cannot combine `forward:transition` and `transition:fn` on the same element, since *[An element can only have one 'transition' directive](https://svelte.dev/repl/08236eb2bbc6474bad75d1aee43b2628)*. ## Alternatives @@ -125,5 +128,5 @@ The directive should be taught as a method of using directives such as `use` or ## Unresolved questions -- How should the `bind` directive be implemented in this context? -- How should svelte handle multiple transitions at once? Using an "internal transition" along with forwarding might result in some unexpected behavior. +- Should the `bind` directive be handled here at all? +- Should there be a syntax to exclude certain types of a directive? e.g. *forward all events except ones with the name "keydown"*. From c2cb09230f8d6a350c000049a3f037607770f34e Mon Sep 17 00:00:00 2001 From: Tropical <42101043+Tropix126@users.noreply.github.com> Date: Tue, 8 Feb 2022 11:15:25 -0600 Subject: [PATCH 12/12] update RFC to accommodate for style directives --- text/0000-forward-directive.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/text/0000-forward-directive.md b/text/0000-forward-directive.md index 7790b09..3f76083 100644 --- a/text/0000-forward-directive.md +++ b/text/0000-forward-directive.md @@ -108,6 +108,27 @@ Similarly to the `on` forwarding, internal actions may be used along with the `f Note: A transition directive cannot be both forwarded and used internally, since [DOM elements can only have one transition](https://svelte.dev/repl/08236eb2bbc6474bad75d1aee43b2628). +## Forwarding Style Directives + +The newly introduced [style](https://svelte.dev/docs#template-syntax-element-directives-style-property) directive can also be forwarded. + +```html + +``` + +Parent: +```html + + + +``` + ### Implementation The `forward` directive's syntax would take in the name of the directive to be forwarded. For example, to forward all events using the `on` directive, the corresponding directive would be `forward:on`.