Created
August 9, 2021 23:03
-
-
Save vmarcosp/1969e6377f43ded8982a51d77b487a3e to your computer and use it in GitHub Desktop.
Simple bindings for framer-motion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module Elements = { | |
type motionElement | |
type t = [#div | #section] | |
@module("React") | |
external createElement: (motionElement, 'props, React.element) => React.element = "createElement" | |
@module("framer-motion") @scope("motion") | |
external div: motionElement = "div" | |
@module("framer-motion") @scope("motion") | |
external section: motionElement = "section" | |
let make = (element: t, props, children) => | |
createElement( | |
switch element { | |
| #div => div | |
| #section => section | |
}, | |
props, | |
children, | |
) | |
} | |
module Animate = { | |
type identity | |
type initial = [#hidden | #visible] | |
type controlStatus = [#visible | #hidden] | |
type controls = {start: (. controlStatus) => unit} | |
type variants<'a> = {..} as 'a | |
type t = [#controlled(controls) | #visible | #hidden] | |
let identity = v => | |
switch v { | |
| #controlled(value) => Obj.magic(value) | |
| value => Obj.magic(value) | |
} | |
let fromOption = Belt.Option.map(_, identity) | |
} | |
module Element = { | |
@deriving(abstract) | |
type motionProps<'a> = { | |
@optional initial: Animate.initial, | |
@optional variants: Animate.variants<'a>, | |
@optional animate: Animate.identity, | |
} | |
external toObject: 'a => {..} = "%identity" | |
@react.component | |
let make = ( | |
/** | |
* Framer Motion Props | |
*/ | |
~initial=?, | |
~variants=?, | |
~animate: option<Animate.t>=?, | |
~element: Elements.t=#div, | |
/** | |
* DOM props | |
*/ | |
~onClick=?, | |
~children, | |
) => { | |
Elements.make( | |
element, | |
Js.Obj.assign( | |
motionProps(~initial?, ~animate=?animate->Animate.fromOption, ~variants?, ())->toObject, | |
ReactDOM.domProps(~onClick?, ())->toObject, | |
), | |
children, | |
) | |
} | |
} | |
module Hooks = { | |
@module("framer-motion") | |
external useAnimation: unit => Animate.controls = "useAnimation" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment