-----------------------------------------------------------------------------
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultilineStrings  #-}
{-# LANGUAGE RecordWildCards   #-}
-----------------------------------------------------------------------------
module Miso.UI.Card
  ( -- ** Props
    CardProps (..)
  , defaultCardProps
    -- ** Views
  , card_
  , cardHeader_
  , cardContent_
  , cardFooter_
    -- ** Samples
  , cardUsage
  , cardSample
  , cardCodeSample
  , cardPropsApi
  ) where
-----------------------------------------------------------------------------
import           Miso
import qualified Miso.Html.Element as H
import qualified Miso.Html.Property as P
-----------------------------------------------------------------------------
import           Miso.UI.Button
import           Miso.UI.Input
import           Miso.UI.Label
import           Miso.UI.Types
-----------------------------------------------------------------------------
-- | Props for 'card_'. Title, description and footer nest other views.
data CardProps model action
  = CardProps
  { forall model action.
CardProps model action -> Maybe (View model action)
cardTitle :: Maybe (View model action)
    -- ^ Heading shown in the card header
  , forall model action.
CardProps model action -> Maybe (View model action)
cardDescription :: Maybe (View model action)
    -- ^ Sub-heading shown under the title
  , forall model action.
CardProps model action -> Maybe [View model action]
cardFooter :: Maybe [View model action]
    -- ^ Footer content
  , forall model action. CardProps model action -> [MisoString]
cardFooterClasses :: [MisoString]
  , forall model action. CardProps model action -> [MisoString]
cardClasses :: [MisoString]
    -- ^ Extra classes appended to @div.card@ (e.g. @w-full max-w-sm@)
  , forall model action. CardProps model action -> [Attribute action]
cardAttrs :: [Attribute action]
  }
-----------------------------------------------------------------------------
-- | Smart constructor: bare card
defaultCardProps :: CardProps model action
defaultCardProps :: forall model action. CardProps model action
defaultCardProps
  = CardProps
  { cardTitle :: Maybe (View model action)
cardTitle = Maybe (View model action)
forall a. Maybe a
Nothing
  , cardDescription :: Maybe (View model action)
cardDescription = Maybe (View model action)
forall a. Maybe a
Nothing
  , cardFooter :: Maybe [View model action]
cardFooter = Maybe [View model action]
forall a. Maybe a
Nothing
  , cardFooterClasses :: [MisoString]
cardFooterClasses = []
  , cardClasses :: [MisoString]
cardClasses = []
  , cardAttrs :: [Attribute action]
cardAttrs = []
  }
-----------------------------------------------------------------------------
-- | <https://basecoatui.com/components/card/ Card>, driven by 'CardProps'.
-- Children render inside the card's content section.
card_
  :: CardProps model action
  -> [View model action]
  -> View model action
card_ :: forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps {[MisoString]
[Attribute action]
Maybe [View model action]
Maybe (View model action)
cardTitle :: forall model action.
CardProps model action -> Maybe (View model action)
cardDescription :: forall model action.
CardProps model action -> Maybe (View model action)
cardFooter :: forall model action.
CardProps model action -> Maybe [View model action]
cardFooterClasses :: forall model action. CardProps model action -> [MisoString]
cardClasses :: forall model action. CardProps model action -> [MisoString]
cardAttrs :: forall model action. CardProps model action -> [Attribute action]
cardTitle :: Maybe (View model action)
cardDescription :: Maybe (View model action)
cardFooter :: Maybe [View model action]
cardFooterClasses :: [MisoString]
cardClasses :: [MisoString]
cardAttrs :: [Attribute action]
..} [View model action]
kids =
  [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
    ( [MisoString] -> Attribute action
forall action. [MisoString] -> Attribute action
P.classes_ (MisoString
"card" MisoString -> [MisoString] -> [MisoString]
forall a. a -> [a] -> [a]
: [MisoString]
cardClasses)
    Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: [Attribute action]
cardAttrs
    )
    ([View model action] -> View model action)
-> [View model action] -> View model action
forall a b. (a -> b) -> a -> b
$ [[View model action]] -> [View model action]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
    [ [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
cardHeader_ [] ([View model action] -> View model action)
-> [View model action] -> View model action
forall a b. (a -> b) -> a -> b
$ [[View model action]] -> [View model action]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
        [ [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.h2_ [] [ View model action
t ] | Just View model action
t <- [Maybe (View model action)
cardTitle] ]
        , [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.p_ [] [ View model action
d ] | Just View model action
d <- [Maybe (View model action)
cardDescription] ]
        ]
      | (Bool -> Bool) -> [Bool] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
any Bool -> Bool
forall a. a -> a
id [ Bool
-> (View model action -> Bool) -> Maybe (View model action) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (Bool -> View model action -> Bool
forall a b. a -> b -> a
const Bool
True) Maybe (View model action)
cardTitle
               , Bool
-> (View model action -> Bool) -> Maybe (View model action) -> Bool
forall b a. b -> (a -> b) -> Maybe a -> b
maybe Bool
False (Bool -> View model action -> Bool
forall a b. a -> b -> a
const Bool
True) Maybe (View model action)
cardDescription
               ]
      ]
    , [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
cardContent_ [] [View model action]
kids | Bool -> Bool
not ([View model action] -> Bool
forall a. [a] -> Bool
forall (t :: * -> *) a. Foldable t => t a -> Bool
null [View model action]
kids) ]
    , [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
cardFooter_ [ [MisoString] -> Attribute action
forall action. [MisoString] -> Attribute action
P.classes_ [MisoString]
cardFooterClasses ] [View model action]
f | Just [View model action]
f <- [Maybe [View model action]
cardFooter] ]
    ]
-----------------------------------------------------------------------------
cardHeader_
  :: [Attribute action]
  -> [View model action]
  -> View model action
cardHeader_ :: forall action model.
[Attribute action] -> [View model action] -> View model action
cardHeader_ = [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.header_
-----------------------------------------------------------------------------
cardContent_
  :: [Attribute action]
  -> [View model action]
  -> View model action
cardContent_ :: forall action model.
[Attribute action] -> [View model action] -> View model action
cardContent_ = [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.section_
-----------------------------------------------------------------------------
cardFooter_
  :: [Attribute action]
  -> [View model action]
  -> View model action
cardFooter_ :: forall action model.
[Attribute action] -> [View model action] -> View model action
cardFooter_ = [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.footer_
-----------------------------------------------------------------------------
-- | Compact usage example (source of the kitchen sink "Code" tab)
cardUsage :: View model action
cardUsage :: forall model action. View model action
cardUsage =
  CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps (ZonkAny 0) action
forall model action. CardProps model action
defaultCardProps
  { cardTitle = Just "Login to your account"
  , cardDescription = Just "Enter your details below to login to your account"
  , cardClasses = [ "w-full", "max-w-sm" ]
  , cardFooter = Just
    [ button_ defaultButtonProps { buttonClasses = [ "w-full" ] } [ "Login" ] ]
  }
  [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.form_
    [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"form grid gap-6" ]
    [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
      [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"grid gap-2" ]
      [ LabelProps action -> [View model action] -> View model action
forall action model.
LabelProps action -> [View model action] -> View model action
label_ LabelProps action
forall action. LabelProps action
defaultLabelProps { labelFor = Just "my-email" } [ View model action
"Email" ]
      , InputProps action -> View model action
forall action model. InputProps action -> View model action
input_ InputProps action
forall action. InputProps action
defaultInputProps
        { inputType = "email"
        , inputId = Just "my-email"
        }
      ]
    ]
  ]
-----------------------------------------------------------------------------
cardSample :: View model action
cardSample :: forall model action. View model action
cardSample =
  [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
  [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"flex flex-col gap-4" ]
  [ CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps (ZonkAny 1) action
forall model action. CardProps model action
defaultCardProps
    { cardTitle = Just "Login to your account"
    , cardDescription = Just "Enter your details below to login to your account"
    , cardClasses = [ "w-full", "max-w-sm" ]
    , cardFooter = Just
      [ button_ defaultButtonProps { buttonClasses = [ "w-full" ] } [ "Login" ]
      , button_ defaultButtonProps { buttonVariant = Outline, buttonClasses = [ "w-full" ] }
        [ "Login with Google" ]
      , H.p_ [ P.class_ "mt-4 text-center text-sm" ]
        [ "Don't have an account? "
        , H.a_
          [ P.href_ "#"
          , P.class_ "underline-offset-4 hover:underline"
          ] [ "Sign up" ]
        ]
      ]
    , cardFooterClasses = [ "flex", "flex-col", "items-center", "gap-2" ]
    }
    [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.form_
      [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"form grid gap-6" ]
      [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
        [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"grid gap-2" ]
        [ LabelProps action -> [View model action] -> View model action
forall action model.
LabelProps action -> [View model action] -> View model action
label_ LabelProps action
forall action. LabelProps action
defaultLabelProps { labelFor = Just "demo-card-form-email" } [ View model action
"Email" ]
        , InputProps action -> View model action
forall action model. InputProps action -> View model action
input_ InputProps action
forall action. InputProps action
defaultInputProps
          { inputType = "email"
          , inputId = Just "demo-card-form-email"
          }
        ]
      , [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_ [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"grid gap-2" ]
        [ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_ [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"flex items-center gap-2" ]
          [ LabelProps action -> [View model action] -> View model action
forall action model.
LabelProps action -> [View model action] -> View model action
label_ LabelProps action
forall action. LabelProps action
defaultLabelProps { labelFor = Just "demo-card-form-password" } [ View model action
"Password" ]
          , [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.a_
            [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.href_ MisoString
"#"
            , MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"ml-auto inline-block text-sm underline-offset-4 hover:underline"
            ] [ View model action
"Forgot your password?" ]
          ]
        , InputProps action -> View model action
forall action model. InputProps action -> View model action
input_ InputProps action
forall action. InputProps action
defaultInputProps
          { inputType = "password"
          , inputId = Just "demo-card-form-password"
          }
        ]
      ]
    ]
  , [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
    [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"flex w-full flex-wrap items-start gap-8 md:*:[.card]:basis-1/4" ]
    [ CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps model action
forall model action. CardProps model action
defaultCardProps [ View model action
"Content Only" ]
    , CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps model action
forall model action. CardProps model action
defaultCardProps
      { cardTitle = Just "Header Only"
      , cardDescription = Just "This is a card with a header and a description."
      } []
    , CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps model action
forall model action. CardProps model action
defaultCardProps
      { cardTitle = Just "Header and Content"
      , cardDescription = Just "This is a card with a header and a content."
      }
      [ View model action
"Content only." ]
    , CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps model action
forall model action. CardProps model action
defaultCardProps { cardFooter = Just [ "Footer Only" ] } []
    , CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps (ZonkAny 2) action
forall model action. CardProps model action
defaultCardProps
      { cardTitle = Just "Header + Footer"
      , cardDescription = Just "This is a card with a header and a footer."
      , cardFooter = Just [ "Footer" ]
      } []
    , CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps model action
forall model action. CardProps model action
defaultCardProps { cardFooter = Just [ "Footer" ] } [ View model action
"Content" ]
    , CardProps model action -> [View model action] -> View model action
forall model action.
CardProps model action -> [View model action] -> View model action
card_ CardProps (ZonkAny 3) action
forall model action. CardProps model action
defaultCardProps
      { cardTitle = Just "Header + Content + Footer"
      , cardDescription = Just "This is a card with a header, content and footer."
      , cardFooter = Just [ "Footer" ]
      }
      [ View model action
"Content" ]
    ]
  ]
-----------------------------------------------------------------------------
cardCodeSample :: View model action
cardCodeSample :: forall model action. View model action
cardCodeSample =
  View model action
"""
  -----------------------------------------------------------------------------
  module MyCard (cardUsage) where
  -----------------------------------------------------------------------------
  import           Miso
  import qualified Miso.Html.Element as H
  import qualified Miso.Html.Property as P
  import           Miso.UI.Button
  import           Miso.UI.Input
  import           Miso.UI.Label
  import           Miso.UI.Types
  import           Miso.UI.Card
  -----------------------------------------------------------------------------
  cardUsage :: View model action
  cardUsage =
    card_ defaultCardProps
    { cardTitle = Just "Login to your account"
    , cardDescription = Just "Enter your details below to login to your account"
    , cardClasses = [ "w-full", "max-w-sm" ]
    , cardFooter = Just
      [ button_ defaultButtonProps { buttonClasses = [ "w-full" ] } [ "Login" ] ]
    }
    [ H.form_
      [ P.class_ "form grid gap-6" ]
      [ H.div_
        [ P.class_ "grid gap-2" ]
        [ label_ defaultLabelProps { labelFor = Just "my-email" } [ "Email" ]
        , input_ defaultInputProps
          { inputType = "email"
          , inputId = Just "my-email"
          }
        ]
      ]
    ]
  """
-----------------------------------------------------------------------------
cardPropsApi :: View model action
cardPropsApi :: forall model action. View model action
cardPropsApi =
  View model action
"""
  -- | Props for 'card_'. Title, description and footer nest other views.
  data CardProps model action
    = CardProps
    { cardTitle :: Maybe (View model action)
      -- ^ Heading shown in the card header
    , cardDescription :: Maybe (View model action)
      -- ^ Sub-heading shown under the title
    , cardFooter :: Maybe [View model action]
      -- ^ Footer content
    , cardFooterClasses :: [MisoString]
    , cardClasses :: [MisoString]
      -- ^ Extra classes appended to @div.card@ (e.g. @w-full max-w-sm@)
    , cardAttrs :: [Attribute action]
    }
  -----------------------------------------------------------------------------
  -- | Smart constructor: bare card
  defaultCardProps :: CardProps model action
  defaultCardProps
    = CardProps
    { cardTitle = Nothing
    , cardDescription = Nothing
    , cardFooter = Nothing
    , cardFooterClasses = []
    , cardClasses = []
    , cardAttrs = []
    }
  """
-----------------------------------------------------------------------------