Partas.Solid.Motion
This binding as it currently stands, binds the solid-motionone library, and also binds the animate function from motion.
Solid-MotionOne Binding
See the docs for usage.
When using examples from motion/react you should be aware that solid-motionone uses different property/attribute names.
As an example, in the transition attribute, instead of times for keyframes, you use the offset property. See the keyframes example at the bottom of the page.
Differences
The Motion component specific properties provide two signatures, the original name such as initial which takes a Feliz style list
of props to provide type safety and completion for all CSS style props, or a -JSX suffixed name such as initialJSX which injects
the JSX language so you can write the value in JSX directly.
Lanayx discovered these injections only work with project reference, not when packaged and used from NuGet; an issue was submitted and he was informed that the next 2025 Rider version should have this patched.
For the general css properties such as animate and initial, you use the MotionStyle qualifier to access the properties in Feliz style.
For transition, you use the MotionTransition qualifier, which will provide type safety by enforcing values to use the AnimationOptions pojo (when you are assigning a value to a CSS property in the transition attribute)
Motion Binding
See the docs for usage.
Only the
animatefunction is bound at the moment.
Example Usage
[<Erase>]type WordRotate() = inherit div() interface OptionKeys [<Erase>] member val words: string[] = unbox null with get,set [<Erase>] member val duration: int = unbox null with get,set [<SolidTypeComponentAttribute>] member props.constructor = props.duration <- 2500 // set a default duration if none is set let index,setIndex = createSignal(0) createEffect( fun () -> let interval = setInterval (fun () -> setIndex.Invoke(fun prevIndex -> (prevIndex + 1) % (props.words.Length))) props.duration onCleanup(fun () -> clearInterval(interval)) ) Presence(exitBeforeEnter = true) { Show(when' = !!(index() + 1), keyed = true) { Motion( initial = [ MotionStyle.opacity 0 MotionStyle.y -50 ], animate = [ MotionStyle.opacity 1 MotionStyle.y 0 ], exit = [ MotionStyle.opacity 0 MotionStyle.y 50 ], transition = [ MotionTransition.duration 0.25 MotionTransition.easing Easing.EaseOut ] ).spread props { props.words[index()] } } }[<SolidComponent>]let WordRotateExample () = div() { WordRotate(style = "font-size: 4rem", words = [| "Word" ; "Rotate" |]) }Example of Keyframes
[<SolidComponent>]let KeyframeExample () = let inline percent value = $"{value}%%" Motion.div( animate = [ MotionStyle.scale !^[|1;2;2;1;1|] MotionStyle.rotate !^[|0;0;180;180;0|] MotionStyle.borderRadius !^[|percent 0; percent 0; percent 50; percent 50; percent 0|] ], transition = [ MotionTransition.duration 2 MotionTransition.easing Easing.EaseInOut MotionTransition.offset [|0.;0.2;0.5;0.8;1|] MotionTransition.repeat JS.Infinity MotionTransition.endDelay 1. ], style="width: 100px; height: 100px; background-color: green" )Experimental Computation Expression helpers
As a side note, remember that the createEffect and related functions which take void functions can use the Experimental
computation expressions:
createEffect( fun () -> let interval = setInterval (fun () -> setIndex.Invoke(fun prevIndex -> (prevIndex + 1) % (props.words.Length))) props.duration onCleanup(fun () -> clearInterval(interval)))effect { let interval = setInterval (fun _ -> setIndex.Invoke(fun prevIndex -> (prevIndex + 1) % props.words.Length))) props.duration cleanup { clearInterval(interval) }}Language Injection
If fixed, you could also use the JSX suffixed properties and have JSX language injection in IntelliJ IDEs when using the Motion components:
Presence(exitBeforeEnter = true) { Show(when' = !!(index() + 1), keyed = true) { Motion( initialJSX = "{ opacity: 0, y: -50 }", animateJSX = "{ opacity: 1, y: 0 }", exitJSX = "{ opacity: 0, y: 50 }", transitionJSX = "{ duration: 0.25, easing: 'ease-out' }" ).spread props { props.words[index()] } }}You'll know if it's fixed because you'll receive injected IDE suggestions for most HTML properties that take string enums like dir on normal HTML Elements.
Last updated: 7/11/25, 1:35 AM