diff --git a/web/src/app.css b/web/src/app.css index 1815a678f..dd75ec25e 100644 --- a/web/src/app.css +++ b/web/src/app.css @@ -532,6 +532,35 @@ html { } } +@utility text-swap { + display: inline-block; + transform: translateY(0); + filter: blur(0); + opacity: 1; + will-change: transform, filter, opacity; + transition: + transform var(--text-swap-dur) var(--text-swap-ease), + filter var(--text-swap-dur) var(--text-swap-ease), + opacity var(--text-swap-dur) var(--text-swap-ease); + + &[data-swap="exit"] { + transform: translateY(calc(var(--text-swap-translate-y) * -1)); + filter: blur(var(--text-swap-blur)); + opacity: 0; + } + + &[data-swap="enter"] { + transform: translateY(var(--text-swap-translate-y)); + filter: blur(var(--text-swap-blur)); + opacity: 0; + transition: none; + } + + @media (prefers-reduced-motion: reduce) { + transition: none; + } +} + @utility bone-pulse { /* fade-in has to be second so it overrides pulse during its 120ms */ animation: @@ -570,6 +599,13 @@ html { } @layer base { + :root { + --text-swap-dur: 150ms; + --text-swap-translate-y: 4px; + --text-swap-blur: 2px; + --text-swap-ease: ease-in-out; + } + @font-face { font-family: "InterVariable"; src: url("/fonts/InterVariable.woff2") format("woff2-variations"); diff --git a/web/src/lib/components/ui/TextSwap.stories.svelte b/web/src/lib/components/ui/TextSwap.stories.svelte new file mode 100644 index 000000000..e03dec990 --- /dev/null +++ b/web/src/lib/components/ui/TextSwap.stories.svelte @@ -0,0 +1,58 @@ + + + + + + {#snippet template(args)} + + + + {/snippet} + + + + {#snippet template()} + + + + + {/snippet} + + + + {#snippet template()} + + + + + {/snippet} + + + + {#snippet template()} +
+ + + + +
+ {/snippet} +
diff --git a/web/src/lib/components/ui/TextSwap.svelte b/web/src/lib/components/ui/TextSwap.svelte new file mode 100644 index 000000000..61ec8d8a7 --- /dev/null +++ b/web/src/lib/components/ui/TextSwap.svelte @@ -0,0 +1,36 @@ + + +{shown}