-----------------------------------------------------------------------------
-- |
-- Module      :  Miso.CSS.Types
-- Copyright   :  (C) 2016-2026 David M. Johnson
-- License     :  BSD3-style (see the file LICENSE)
-- Maintainer  :  David M. Johnson <code@dmj.io>
-- Stability   :  experimental
-- Portability :  non-portable
--
-- = Overview
--
-- "Miso.CSS.Types" defines the core data types that back the CSS DSL in
-- "Miso.CSS". There are three layers:
--
-- * 'Style' — a single CSS property\/value pair (@(\"color\", \"red\")@).
-- * 'Styles' — one rule block: either a selector rule, a
--   <https://developer.mozilla.org/en-US/docs/Web/CSS/@keyframes \@keyframes>
--   animation, or a
--   <https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries \@media>
--   query.
-- * 'StyleSheet' — an ordered list of 'Styles' rule blocks that together form
--   a complete
--   <https://developer.mozilla.org/en-US/docs/Web/API/StyleSheet stylesheet>.
--
-- In normal usage you never construct these types directly — the smart
-- constructors in "Miso.CSS" (@sheet_@, @selector_@, @keyframes_@, @media_@)
-- build them for you. This module is exported for downstream code that
-- inspects or extends the CSS representation.
--
-- = Type hierarchy
--
-- @
-- 'StyleSheet'          -- rendered to a \<style\> tag
--   └─ ['Styles']       -- one rule block each
--        ├─ 'Styles'    (selector → ['Style'])
--        ├─ 'KeyFrame'  (animation-name → [(stop, ['Style'])])
--        └─ 'Media'     (media-query   → [(selector, ['Style'])])
--
-- 'Style' = ('MisoString', 'MisoString')   -- property, value
-- @
--
-- = See also
--
-- * "Miso.CSS" — smart constructors and property combinators built on these types
-- * "Miso.CSS.Color" — 'Miso.CSS.Color.Color' type used as property values
-----------------------------------------------------------------------------
module Miso.CSS.Types
  ( -- *** Types
    Style
  , Styles (..)
  , StyleSheet (..)
  , TransformFn (..)
  , KeyframeStop (..)
  , MediaRule (..)
  , MediaQuery (..)
  ) where
-----------------------------------------------------------------------------
import Miso.String (MisoString)
-----------------------------------------------------------------------------
-- | Type for a CSS StyleSheet. Internally it maps From CSS selectors to t'Styles'.
--
-- @
-- testSheet :: StyleSheet
-- testSheet =
--    sheet_
--    [ selector_ ".name"
--        [ backgroundColor red
--        , alignContent "top"
--        ]
--    , selector_ "#container"
--        [ backgroundColor blue
--        , alignContent "center"
--        ]
--    , keyframes_ "slide-in"
--      [ from_ [ transforms [ translateX (pct 0) ] ]
--      , at (pct 50)
--        [ backgroundColor red
--        , backgroundSize "10px"
--        ]
--      , to_ [ transforms [ translateX (pct 100) ] ]
--      ]
--    , media_ (screen_ `and_` minWidth_ (px 480))
--      [ rule_ "header" [ height "auto" ]
--      , rule_ "ul"     [ display "block" ]
--      ]
--    ]
-- @
--
newtype StyleSheet = StyleSheet
  { StyleSheet -> [Styles]
getStyleSheet :: [Styles]
  -- ^ Ordered list of CSS rule blocks that make up the stylesheet
  } deriving (StyleSheet -> StyleSheet -> Bool
(StyleSheet -> StyleSheet -> Bool)
-> (StyleSheet -> StyleSheet -> Bool) -> Eq StyleSheet
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: StyleSheet -> StyleSheet -> Bool
== :: StyleSheet -> StyleSheet -> Bool
$c/= :: StyleSheet -> StyleSheet -> Bool
/= :: StyleSheet -> StyleSheet -> Bool
Eq, Int -> StyleSheet -> ShowS
[StyleSheet] -> ShowS
StyleSheet -> String
(Int -> StyleSheet -> ShowS)
-> (StyleSheet -> String)
-> ([StyleSheet] -> ShowS)
-> Show StyleSheet
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> StyleSheet -> ShowS
showsPrec :: Int -> StyleSheet -> ShowS
$cshow :: StyleSheet -> String
show :: StyleSheet -> String
$cshowList :: [StyleSheet] -> ShowS
showList :: [StyleSheet] -> ShowS
Show)
-----------------------------------------------------------------------------
-- | Type for a CSS 'Style'
--
type Style = (MisoString, MisoString)
-----------------------------------------------------------------------------
-- | An individual CSS <https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function transform function>.
-- Construct values with 'translate', 'rotate', 'scale', etc., then combine with 'transforms'.
--
-- @
-- transforms [ translate (px 10) (pct 50), rotate (deg 45), scaleX 1.5 ]
-- @
--
newtype TransformFn = TransformFn
  { TransformFn -> MisoString
renderTransformFn :: MisoString
  -- ^ The serialised CSS transform function string (e.g. @\"rotate(45deg)\"@)
  } deriving (TransformFn -> TransformFn -> Bool
(TransformFn -> TransformFn -> Bool)
-> (TransformFn -> TransformFn -> Bool) -> Eq TransformFn
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: TransformFn -> TransformFn -> Bool
== :: TransformFn -> TransformFn -> Bool
$c/= :: TransformFn -> TransformFn -> Bool
/= :: TransformFn -> TransformFn -> Bool
Eq, Int -> TransformFn -> ShowS
[TransformFn] -> ShowS
TransformFn -> String
(Int -> TransformFn -> ShowS)
-> (TransformFn -> String)
-> ([TransformFn] -> ShowS)
-> Show TransformFn
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> TransformFn -> ShowS
showsPrec :: Int -> TransformFn -> ShowS
$cshow :: TransformFn -> String
show :: TransformFn -> String
$cshowList :: [TransformFn] -> ShowS
showList :: [TransformFn] -> ShowS
Show)
-----------------------------------------------------------------------------
-- | A CSS rule block. One of: a selector rule, a @\@keyframes@ animation, or a @\@media@ query.
data Styles
  = Styles (MisoString, [Style])
  | KeyFrame MisoString [(MisoString, [Style])]
  | Media MisoString [(MisoString, [Style])]
  deriving (Styles -> Styles -> Bool
(Styles -> Styles -> Bool)
-> (Styles -> Styles -> Bool) -> Eq Styles
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Styles -> Styles -> Bool
== :: Styles -> Styles -> Bool
$c/= :: Styles -> Styles -> Bool
/= :: Styles -> Styles -> Bool
Eq, Int -> Styles -> ShowS
[Styles] -> ShowS
Styles -> String
(Int -> Styles -> ShowS)
-> (Styles -> String) -> ([Styles] -> ShowS) -> Show Styles
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Styles -> ShowS
showsPrec :: Int -> Styles -> ShowS
$cshow :: Styles -> String
show :: Styles -> String
$cshowList :: [Styles] -> ShowS
showList :: [Styles] -> ShowS
Show)
-----------------------------------------------------------------------------
-- | A single stop in a '@keyframes' rule. Construct with 'from_', 'to_', or 'at'.
newtype KeyframeStop = KeyframeStop { KeyframeStop -> (MisoString, [Style])
getKeyframeStop :: (MisoString, [Style]) }
  deriving (KeyframeStop -> KeyframeStop -> Bool
(KeyframeStop -> KeyframeStop -> Bool)
-> (KeyframeStop -> KeyframeStop -> Bool) -> Eq KeyframeStop
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: KeyframeStop -> KeyframeStop -> Bool
== :: KeyframeStop -> KeyframeStop -> Bool
$c/= :: KeyframeStop -> KeyframeStop -> Bool
/= :: KeyframeStop -> KeyframeStop -> Bool
Eq, Int -> KeyframeStop -> ShowS
[KeyframeStop] -> ShowS
KeyframeStop -> String
(Int -> KeyframeStop -> ShowS)
-> (KeyframeStop -> String)
-> ([KeyframeStop] -> ShowS)
-> Show KeyframeStop
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> KeyframeStop -> ShowS
showsPrec :: Int -> KeyframeStop -> ShowS
$cshow :: KeyframeStop -> String
show :: KeyframeStop -> String
$cshowList :: [KeyframeStop] -> ShowS
showList :: [KeyframeStop] -> ShowS
Show)
-----------------------------------------------------------------------------
-- | A selector rule inside a '@media' block. Construct with 'rule_'.
newtype MediaRule = MediaRule { MediaRule -> (MisoString, [Style])
getMediaRule :: (MisoString, [Style]) }
  deriving (MediaRule -> MediaRule -> Bool
(MediaRule -> MediaRule -> Bool)
-> (MediaRule -> MediaRule -> Bool) -> Eq MediaRule
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MediaRule -> MediaRule -> Bool
== :: MediaRule -> MediaRule -> Bool
$c/= :: MediaRule -> MediaRule -> Bool
/= :: MediaRule -> MediaRule -> Bool
Eq, Int -> MediaRule -> ShowS
[MediaRule] -> ShowS
MediaRule -> String
(Int -> MediaRule -> ShowS)
-> (MediaRule -> String)
-> ([MediaRule] -> ShowS)
-> Show MediaRule
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MediaRule -> ShowS
showsPrec :: Int -> MediaRule -> ShowS
$cshow :: MediaRule -> String
show :: MediaRule -> String
$cshowList :: [MediaRule] -> ShowS
showList :: [MediaRule] -> ShowS
Show)
-----------------------------------------------------------------------------
-- | A CSS [media query](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries).
-- Construct with 'screen_', 'print_', 'all_', 'minWidth_', etc.,
-- and compose with 'and_', 'or_', 'not_'.
newtype MediaQuery = MediaQuery { MediaQuery -> MisoString
renderMediaQuery :: MisoString }
  deriving (MediaQuery -> MediaQuery -> Bool
(MediaQuery -> MediaQuery -> Bool)
-> (MediaQuery -> MediaQuery -> Bool) -> Eq MediaQuery
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: MediaQuery -> MediaQuery -> Bool
== :: MediaQuery -> MediaQuery -> Bool
$c/= :: MediaQuery -> MediaQuery -> Bool
/= :: MediaQuery -> MediaQuery -> Bool
Eq, Int -> MediaQuery -> ShowS
[MediaQuery] -> ShowS
MediaQuery -> String
(Int -> MediaQuery -> ShowS)
-> (MediaQuery -> String)
-> ([MediaQuery] -> ShowS)
-> Show MediaQuery
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> MediaQuery -> ShowS
showsPrec :: Int -> MediaQuery -> ShowS
$cshow :: MediaQuery -> String
show :: MediaQuery -> String
$cshowList :: [MediaQuery] -> ShowS
showList :: [MediaQuery] -> ShowS
Show)
-----------------------------------------------------------------------------