Skip to main content
.transition(
    type:
        | "opacity" | "slide" | "scale" | "identity" | "blurReplace"
        | { move: "top" | "bottom" | "leading" | "trailing" }
        | { push: "top" | "bottom" | "leading" | "trailing" }
        | { scale: number; anchor?: UnitPoint }
        | { offset: { x?: number; y?: number } }
        | { blurReplace: "downUp" | "upUp" }
        | { asymmetric: { insertion: SimpleTransition; removal: SimpleTransition } }
        | { combined: SimpleTransition[] }
): Component
type
Transition
required
The transition to apply when the component is inserted or removed. Can be a built-in string or a configuration object.Built-in transitions:
  • "opacity" — fades in/out
  • "slide" — slides in from the leading edge and out to the trailing edge
  • "scale" — scales from zero to full size
  • "identity" — no animation (instant)
  • "blurReplace" — cross-fades with a blur effect
Directional transitions:
  • { move: edge } — slides in/out from the specified edge
  • { push: edge } — pushes the old content out as the new content pushes in from the specified edge
Parameterized transitions:
  • { scale: number, anchor?: UnitPoint } — scales from a specific value, optionally around an anchor point
  • { offset: { x?, y? } } — slides in/out by a specific offset
  • { blurReplace: "downUp" | "upUp" } — blur replace with a directional style
Composite transitions:
  • { asymmetric: { insertion, removal } } — different transitions for insertion and removal
  • { combined: [...] } — multiple transitions applied simultaneously

Support

Usage

Opacity (fade)

const body = () => {
    const [isVisible, setIsVisible] = useState(true)
    return VStack([
        Button("Toggle", () => setIsVisible(!isVisible)),
        isVisible ? Text("Hello").transition("opacity") : Empty()
    ])
}

Slide

const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("Sliding text").transition("slide") : Empty()
    ])
}

Scale

const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Circle()
            .frame({ width: 50, height: 50 })
            .foregroundStyle(Color("blue"))
            .transition("scale") : Empty()
    ])
}

Move from edge

const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("From bottom")
            .transition({ move: "bottom" }) : Empty()
    ])
}

Push from edge

const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("Pushed in")
            .transition({ push: "leading" }) : Empty()
    ])
}

Scale with anchor

const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("Scale from top")
            .transition({ scale: 0, anchor: "top" }) : Empty()
    ])
}

Offset transition

const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("Offset")
            .transition({ offset: { x: 100, y: 0 } }) : Empty()
    ])
}

Blur replace

const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("Blur")
            .transition({ blurReplace: "downUp" }) : Empty()
    ])
}

Asymmetric transition

Use a different animation for insertion and removal.
const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("Asymmetric")
            .transition({
                asymmetric: {
                    insertion: "slide",
                    removal: "opacity"
                }
            }) : Empty()
    ])
}

Combined transitions

Apply multiple transitions simultaneously.
const body = () => {
    const [show, setShow] = useState(false)
    return VStack([
        Button("Toggle", () => setShow(!show)),
        show ? Text("Combined")
            .transition({
                combined: ["opacity", "scale"]
            }) : Empty()
    ])
}

Notes

  • Transitions only play when a component is conditionally inserted or removed from the view hierarchy.
  • The "identity" transition can be used to explicitly disable animations on insertion/removal.