-
-
Notifications
You must be signed in to change notification settings - Fork 4.3k
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: Display directive #14795
base: main
Are you sure you want to change the base?
feat: Display directive #14795
Conversation
|
preview: https://svelte-dev-git-preview-svelte-14795-svelte.vercel.app/ this is an automated message |
|
Wouldn't it be possible for this to be a block? Kinda like a vue v-show directive equivalent? {#show visible}
<p transition:slide>hello world</p>
{/show} |
It could only work by setting the style And yes it's an equivalent to Vue |
I would prefer a block too, it works basically like an
Also I don't think this feature is important enough to deserve its own syntax as we can already do this: <div style:display={visible}></div> Pair that with a getter, a setter and factory pattern to turn it into something like: <script>
const handler = visibility_handler("flex", false); //Create an object with a setter and a getter that switches state between "flex" and "none!important" with an initial value of "none!important" as indicated by the second argument
</script>
`<div style:display={handler.visible}></div>` Which allows you to do things like: handler.toggle();
handler.visible = false; //assignment is captured via its setter. handler.visible getter now returns "none!important"
handler.visible = true; //assignment is captured via its setter. handler.visible now returns "flex" as it was memoized
handler.visible = "inline" //assignment is captured via its setter. The initial "flex" value is overridden
handler.hide();
handler.show(); |
But in order to hide the content, we need an element on which to set => How do you hide that : {#display visible}
Hello World !
{/display}
I known that |
This is really sweet! Hope in some shape or form this can be incorporated. I also wonder if this could be a block, this way it would be intuitive and basically only way to do it, vs if someone used and if block and the directive. I think a block could work with only the top level elements, where every top level element would be affected just like with the regular Components at the top level would NOT be allowed but could be nested inside elements. I think it can also play well with the transition I think it would make sense to use the Please read to the end as this has been more like a discovery journey. <script>
import { fade } from 'svelte/transition';
let signal = $state(true);
</script>
<!-- toggle #if condition -->
<button onclick={() => signal = !signal}>Fade in / out</button>
<!-- short form with functions predefined -->
{#if:transition=[in, out] signal}
<!-- every top element will run through in and out callbacks, components disallowed at the top -->
<div transition:fade>fades in and out</div>
{/if}
<!-- shortest form with a function that returns a tuple with for in and out -->
{#if:transition=display() signal}
<!-- every top element will run through in and out callbacks, components disallowed at the top -->
<div transition:fade>fades in and out</div>
{/if}
<!-- long form inlined functions, in out functions run for every top element -->
{#if:transition=[node => node.removeAttr('style'), node => node.style.display = 'none')] signal}
<!-- every top element will run through in and out callbacks, components disallowed at the top -->
<div transition:fade>fades in and out</div>
{/if} The syntax for {#if:on:transition=[in, out] signal} Svelte could provide a super basic, like above, with svelte provided actions: <script>
import { fade } from 'svelte/transition'
import { display } from 'svelte/transition/actions';
let signal = $state(true);
</script>
{#if:transition=display() signal}
<!-- every top element will run through in and out callbacks, components disallowed at the top -->
<div transition:fade>fades in and out</div>
{/if} SimplificationBut, maybe even simpler, {#if:action=[truthy, falsy]}
{/if} a more fleshed out example, and actually, it probably just makes sense to use the same syntax as for the <script>
import { fade } from 'svelte/transition'
import { display } from 'svelte/transition/actions';
// display or any custom function that has to return a tuple of functions for truthy and falsy
// display() => [(node: HTMLElement) => void, (node: HTMLElement) => void]
// example of what `display` could return: [node => node.removeAttr('style'), node => node.style.display = 'none')]
let signal = $state(true);
</script>
{#if:action:display signal}
<div transition:fade>fades in and out</div>
{/if} And to reiterate:
|
WIP : Another possible solution for #9976
This add a new
#display
directive for DOM elements.This directive will allow to show/hide an element using the Svelte transition API, without destroying it.
=> When visible is "falsy", the element will be hidden using a
display: none !important
.Otherwise it will be show either by removing the display style, or setting the value of
style:display
.Note : I known that
#display={...]
is not usual for directive but I think it's more expressive...In any case we could replace it with something like
svelte:display={...}
It's still a work in progress, and need some works that I can do if the syntax of this PR is accepted...
Before submitting the PR, please make sure you do the following
feat:
,fix:
,chore:
, ordocs:
.packages/svelte/src
, add a changeset (npx changeset
).Tests and linting
pnpm test
and lint the project withpnpm lint