{-# LANGUAGE DuplicateRecordFields #-}
{-# OPTIONS_GHC -Wno-missing-role-annotations #-}
{-# OPTIONS_GHC -Wno-term-variable-capture #-}

module Dashi.Components.Checkbox where

import Clay hiding
    ( Color
    , fullWidth
    , label
    , legend
    , name
    , option
    , selected
    , span_
    , type_
    )
import Clay qualified
import Dashi.Components.Icon
    ( Phosphor (CheckSquare, Square)
    , Weight (..)
    , iconContent
    , iconFontFamilyOverride
    , iconStyle
    )
import Dashi.Components.Util (ariaRole_)
import Dashi.Prelude hiding (has, (#), (&), (|>))
import Dashi.Style.Border (BorderColour (..))
import Dashi.Style.Pseudo (pressable)
import Dashi.Style.Tokens
import Dashi.Style.Util
import Data.Coerce (coerce)
import GHC.IsList (fromList)
import Miso.Html.Element (fieldset_, input_, label_, span_)
import Miso.Html.Event qualified as Html
import Miso.Html.Property (checked_, name_, type_)

data Checkbox model action = Checkbox
    { forall model action. Checkbox model action -> MisoString
name :: MisoString
    , forall model action. Checkbox model action -> [View model action]
label :: [View model action]
    , forall model action. Checkbox model action -> Bool
selected :: Bool
    , forall model action. Checkbox model action -> Bool -> action
onChecked :: Bool -> action
    }

instance Widget (Checkbox model action) model action where
    widget' :: [Attribute action] -> Checkbox model action -> View model action
widget' [Attribute action]
attrs Checkbox{Bool
[View model action]
MisoString
Bool -> action
name :: forall model action. Checkbox model action -> MisoString
label :: forall model action. Checkbox model action -> [View model action]
selected :: forall model action. Checkbox model action -> Bool
onChecked :: forall model action. Checkbox model action -> Bool -> action
name :: MisoString
label :: [View model action]
selected :: Bool
onChecked :: Bool -> action
..} =
        [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
label_
            []
            [ [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
input_ ([Attribute action] -> View model action)
-> [Attribute action] -> View model action
forall a b. (a -> b) -> a -> b
$ MisoString -> Attribute action
forall action. MisoString -> Attribute action
type_ MisoString
"checkbox"
                Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: MisoString -> Attribute action
forall action. MisoString -> Attribute action
name_ MisoString
name
                Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: (Checked -> action) -> Attribute action
forall action. (Checked -> action) -> Attribute action
Html.onChecked (Bool -> action
onChecked (Bool -> action) -> (Checked -> Bool) -> Checked -> action
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Checked -> Bool
forall a b. Coercible a b => a -> b
coerce)
                Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: Bool -> Attribute action
forall action. Bool -> Attribute action
checked_ Bool
selected
                Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: [Attribute action]
attrs
            , [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
span_ [] [View model action]
label
            ]
    style :: Css
style = do
        let checkboxOrRadio :: Selector
checkboxOrRadio = Selector
input Selector -> Refinement -> Selector
# [Refinement] -> Refinement
isOneOf [MisoString
"type" MisoString -> MisoString -> Refinement
@= MisoString
"checkbox", MisoString
"type" MisoString -> MisoString -> Refinement
@= MisoString
"radio"]
        Selector
checkboxOrRadio Selector -> Css -> Css
? do
            Css
pressable
            Refinement
before Refinement -> Css -> Css
& do
                Css
iconStyle
                Weight -> Css
iconFontFamilyOverride Weight
Bold
                BorderColour -> Css
forall t. Token t => t -> Css
color' BorderColour
BorderColour
                MisoString -> Time -> TimingFunction -> Time -> Css
transition MisoString
"color" (Double -> Time
sec Double
0.075) TimingFunction
easeInOut Time
0
                Size Percentage -> Css
forall a. Size a -> Css
fontSize (Size Percentage -> Css)
-> (Number -> Size Percentage) -> Number -> Css
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. Number -> Size Percentage
pct (Number -> Css) -> Number -> Css
forall a b. (a -> b) -> a -> b
$ Number
150
                Refinement
checked Refinement -> Css -> Css
& do
                    Weight -> Css
iconFontFamilyOverride Weight
Fill
                    BorderColour -> Css
forall t. Token t => t -> Css
color' BorderColour
BorderFocusedColour
        Selector
forall a. IsString a => a
Clay.label Selector -> Refinement -> Selector
# Selector -> Refinement
has (Selector
self Selector -> Selector -> Selector
|> Selector
checkboxOrRadio) Selector -> Css -> Css
? do
            Css
pressable
            Display -> Css
display Display
flex
            FlexDirection -> Css
flexDirection FlexDirection
row
            AlignItemsValue -> Css
alignItems AlignItemsValue
forall a. Center a => a
center
            SizeToken -> Css
columnGap' SizeToken
XSmall
            Size LengthUnit -> Css
forall a. Size a -> Css
width Size LengthUnit
maxContent
        Selector
input Selector -> Refinement -> Selector
# (MisoString
"type" MisoString -> MisoString -> Refinement
@= MisoString
"checkbox") Selector -> Css -> Css
? do
            SizeToken -> Css
borderRadiusAll' SizeToken
XSmall
            Refinement
before Refinement -> Css -> Css
& Content -> Css
content (Phosphor -> Content
iconContent Phosphor
Square)
            Refinement
checked Refinement -> Refinement -> Refinement
forall a. Semigroup a => a -> a -> a
<> Refinement
before Refinement -> Css -> Css
& Content -> Css
content (Phosphor -> Content
iconContent Phosphor
CheckSquare)

data CheckboxGroup o model action = CheckboxGroup
    { forall o model action. CheckboxGroup o model action -> MisoString
name :: MisoString
    , forall o model action. CheckboxGroup o model action -> [o]
options :: [o]
    , forall o model action.
CheckboxGroup o model action -> o -> [View model action]
label :: o -> [View model action]
    , forall o model action. CheckboxGroup o model action -> o -> Bool
selected :: o -> Bool
    , forall o model action.
CheckboxGroup o model action -> o -> Bool -> action
onChecked :: o -> Bool -> action
    }

instance (Eq a) => Widget (CheckboxGroup a model action) model action where
    widget' :: [Attribute action]
-> CheckboxGroup a model action -> View model action
widget' [Attribute action]
attrs CheckboxGroup{[a]
MisoString
a -> Bool
a -> [View model action]
a -> Bool -> action
name :: forall o model action. CheckboxGroup o model action -> MisoString
options :: forall o model action. CheckboxGroup o model action -> [o]
label :: forall o model action.
CheckboxGroup o model action -> o -> [View model action]
selected :: forall o model action. CheckboxGroup o model action -> o -> Bool
onChecked :: forall o model action.
CheckboxGroup o model action -> o -> Bool -> action
name :: MisoString
options :: [a]
label :: a -> [View model action]
selected :: a -> Bool
onChecked :: a -> Bool -> action
..} =
        [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
fieldset_ [MisoString -> Attribute action
forall action. MisoString -> Attribute action
ariaRole_ MisoString
"group"]
            ([View model action] -> View model action)
-> [View model action] -> View model action
forall a b. (a -> b) -> a -> b
$ [a]
options
            [a] -> (a -> View model action) -> [View model action]
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \a
o ->
                [Attribute action] -> Checkbox model action -> View model action
forall w model action.
Widget w model action =>
[Attribute action] -> w -> View model action
widget'
                    [Attribute action]
attrs
                    Checkbox
                        { MisoString
name :: MisoString
name :: MisoString
name
                        , label :: [View model action]
label = a -> [View model action]
label a
o
                        , selected :: Bool
selected = a -> Bool
selected a
o
                        , onChecked :: Bool -> action
onChecked = a -> Bool -> action
onChecked a
o
                        }

    style :: Css
style = do
        NonEmpty Selector -> Selector
forall a. Semigroup a => NonEmpty a -> a
sconcat ((Selector
self Selector -> Refinement -> Selector
#) (Refinement -> Selector)
-> (MisoString -> Refinement) -> MisoString -> Selector
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall {k} (cat :: k -> k -> *) (b :: k) (c :: k) (a :: k).
Category cat =>
cat b c -> cat a b -> cat a c
. MisoString -> Refinement
ariaRole (MisoString -> Selector)
-> NonEmpty MisoString -> NonEmpty Selector
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [Item (NonEmpty MisoString)] -> NonEmpty MisoString
forall l. IsList l => [Item l] -> l
fromList [Item (NonEmpty MisoString)
MisoString
"group", Item (NonEmpty MisoString)
MisoString
"radiogroup"]) Selector -> Css -> Css
? do
            Display -> Css
display Display
flex
            FlexDirection -> Css
flexDirection FlexDirection
column
            SizeToken -> Css
rowGap' SizeToken
XSmall