Py.Cafe

maartenbreddels/

solara-transitions

Using transitions/animations with solara

DocsPricing
  • app.py
  • fade.css
  • requirements.txt
  • transition.vue
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# check out https://solara.dev/ for documentation
# or https://github.com/widgetti/solara/
# And check out https://py.cafe/maartenbreddels for more examples

# based on https://vuejs.org/guide/built-ins/transition
import solara
from pathlib import Path

clicks = solara.reactive(0)


@solara.component_vue("transition.vue")
def Transition(show_first=True, children=[], name="", mode="out-in"):
    pass  # just a dummy function

@solara.component
def Page():
    print("The component render function gets called")
    # change this code, and see the output refresh
    color = "green"
    if clicks.value >= 5:
        color = "red"

    def increment():
        clicks.value += 1
        print("clicks", clicks)  # noqa

    solara.Button(label=f"Clicked: {clicks}", on_click=increment, color=color)
    solara.Style(Path("fade.css"))
    with Transition(show_first=(clicks.value % 2) == 0, name="slide-fade"):
        solara.Success("Even")
        solara.Error("Odd")
transition.vue
1
2
3
4
5
6
<template>
    <Transition :name="name" :mode="mode">
        <jupyter-widget v-if="show_first && children.length > 0" :widget="children[0]" key="first-widget"></jupyter-widget>
        <jupyter-widget v-if="!show_first && children.length > 1" :widget="children[1]" key="second-widget"></jupyter-widget>
    </Transition>
</template>
fade.css
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
/* name="fade" */
.fade-enter-active,
.fade-leave-active {
  transition: opacity 0.5s ease;
}

.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}

/* name="slide-fade" */
.slide-fade-enter-active {
  transition: all 0.3s ease-out;
}

.slide-fade-leave-active {
  transition: all 0.8s cubic-bezier(1, 0.5, 0.8, 1);
}

.slide-fade-enter-from,
.slide-fade-leave-to {
  transform: translateX(20px);
  opacity: 0;
}