purescript-contrib / purescript-css

A clean, type-safe library for describing, manipulating and rendering CSS
Apache License 2.0
105 stars 39 forks source link

Add animation-play-state to animation #139

Open mikesol opened 2 years ago

mikesol commented 2 years ago

Currently, animation leaves off the last parameter that corresponds to animation-play-state. It would be nice if the API included this as well. I have a forked version where I've incorporated that and it works fine - the code is pasted below. It uses AnimationPlayState for the type and then increases the number of arguments to animation by one.

Would folks be interested in incorporating this into the library?

module CSS.Hack.Animation where

import Prelude

import CSS.Property (class Val, Value, value)
import CSS.String (class IsString, fromString)
import CSS.Stylesheet (CSS, key)
import CSS.Time (Time)
import CSS.Transition (TimingFunction)
import Data.Foldable (for_)
import Data.Tuple.Nested (tuple8)

newtype AnimationDirection = AnimationDirection Value

derive instance eqAnimationDirection :: Eq AnimationDirection
derive instance ordAnimationDirection :: Ord AnimationDirection

instance valAnimationDirection :: Val AnimationDirection where
  value (AnimationDirection v) = v

normalAnimationDirection :: AnimationDirection
normalAnimationDirection = AnimationDirection $ fromString "normal"

alternate :: AnimationDirection
alternate = AnimationDirection $ fromString "alternate"

reverse :: AnimationDirection
reverse = AnimationDirection $ fromString "reverse"

alternateReverse :: AnimationDirection
alternateReverse = AnimationDirection $ fromString "alternate-reverse"

newtype IterationCount = IterationCount Value

derive instance eqIterationCount :: Eq IterationCount
derive instance ordIterationCount :: Ord IterationCount

instance valIterationCount :: Val IterationCount where
  value (IterationCount v) = v

infinite :: IterationCount
infinite = IterationCount $ fromString "infinite"

iterationCount :: Number -> IterationCount
iterationCount = IterationCount <<< value

newtype FillMode = FillMode Value

derive instance eqFillMode :: Eq FillMode
derive instance ordFillMode :: Ord FillMode

instance valFillMode :: Val FillMode where
  value (FillMode v) = v

forwards :: FillMode
forwards = FillMode $ fromString "forwards"

backwards :: FillMode
backwards = FillMode $ fromString "backwards"

data AnimationPlayState = APaused | ARunning | AInitial

instance valAnimationState :: Val AnimationPlayState where
  value = fromString <<< case _ of
    APaused -> "paused"
    ARunning -> "running"
    AInitial -> "initial"

animation :: AnimationName -> Time -> TimingFunction -> Time -> IterationCount -> AnimationDirection -> FillMode -> AnimationPlayState -> CSS
animation p de f du i di fm ps = do
  for_ animationKeys \k ->
    key (fromString k) (tuple8 p de f du i di fm ps)
  where
  animationKeys =
    [ "animation"
    , "-webkit-animation"
    , "-moz-animation"
    , "-o-animation"
    ]

newtype AnimationName = AnimationName Value

derive instance eqAnimationName :: Eq AnimationName
derive instance ordAnimationName :: Ord AnimationName

instance valAnimationName :: Val AnimationName where
  value (AnimationName v) = v

instance isStringAnimationName :: IsString AnimationName where
  fromString = AnimationName <<< fromString
thomashoneyman commented 2 years ago

Yes, it would be good to make sure we're accurately capturing the available arguments for this. Thanks!

mikesol commented 2 years ago

The downside is that it is a breaking change, so when folks upgrade their code wouldn't compile anymore. How would you like to handle that? We could make a new animateWithPlayState function, for example, that takes the additional argument. That wouldn't break anything. Lemme know!

thomashoneyman commented 2 years ago

With breaking changes, we tend to accept the PR but wait to merge it until we're ready for a breaking release. In this case we'd be waiting for a long time because there's no breaking release planned. However, I'm open to animateWithPlayState as well!