Hyperbole encourages using the
atomic-css package to factor styles with haskell functions. Here is how we might create reusable header and btn styles:
import Web.Atomic.CSS
import Web.Hyperbole
example = do
col $ do
el ~ h3 $ "My Page"
el ~ btn $ "Hover Me"
where
header = bold
h1 = header . fontSize 32
h2 = header . fontSize 24
h3 = header . fontSize 18
btn =
pad 10 . border 1 . pointer . hover (bold . border 2)
Note how we use hover to provide immediate feedback to the user without talking to the server
If an update changes the transition property of a view, it will automatically animate with CSS Transitions, avoiding having the server compute animation frames.
viewSmall :: View Animate ()
viewSmall = do
col ~ gap 10 . transition 300 (Width 200) $ do
el "Small"
button Expand "Expand" ~ btn
viewBig :: View Animate ()
viewBig =
col ~ gap 10 . transition 300 (Width 400) $ do
el "Expanded"
button Collapse "Collapse" ~ btn
viewLoaders :: Text -> View Loader ()
viewLoaders status = do
col ~ gap 10 $ do
row ~ gap 10 . whenLoading flexRow . display None $ do
loadingBars
el "Loading..."
el ~ whenLoading (display None) $ text status
button LoadSlow ~ btn . whenLoading (opacity 0.5) $ "Load Slow"
You can opt-out of Atomic CSS and use external classes with class_
page :: (Hyperbole :> es) => Page es '[Items]
page = do
pure $ do
-- you can choose to include a stylesheet only on pages
-- that use it or load it globally in your document function
stylesheet "external.css"
hyper Items $ itemsView "one"
itemsView :: Text -> View Items ()
itemsView sel = do
el @ class_ "parent" $ do
item "one"
item "two"
item "three"
item "four"
item "five"
where
selected i =
if sel == i
then class_ "selected"
else id
item i =
-- the class_ attribute MERGES classes if you set it more than once
button (Select i) @ class_ "item" . selected i $ text i