{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE MultilineStrings #-}
{-# LANGUAGE RecordWildCards #-}
module Miso.UI.Select
(
SelectProps (..)
, defaultSelectProps
, SelectMenuProps (..)
, defaultSelectMenuProps
, select_
, selectMenu_
, selectOption_
, selectGroup_
, selectUsage
, selectSample
, selectCodeSample
, selectPropsApi
) where
import Miso
import qualified Miso.Html.Element as H
import qualified Miso.Html.Property as P
import Miso.UI.Icons
data SelectProps action
= SelectProps
{ forall action. SelectProps action -> Maybe MisoString
selectId :: Maybe MisoString
, forall action. SelectProps action -> Bool
selectDisabled :: Bool
, forall action. SelectProps action -> [MisoString]
selectClasses :: [MisoString]
, forall action. SelectProps action -> [Attribute action]
selectAttrs :: [Attribute action]
}
defaultSelectProps :: SelectProps action
defaultSelectProps :: forall action. SelectProps action
defaultSelectProps
= SelectProps
{ selectId :: Maybe MisoString
selectId = Maybe MisoString
forall a. Maybe a
Nothing
, selectDisabled :: Bool
selectDisabled = Bool
False
, selectClasses :: [MisoString]
selectClasses = [ MisoString
"w-[180px]" ]
, selectAttrs :: [Attribute action]
selectAttrs = []
}
select_
:: SelectProps action
-> [View model action]
-> View model action
select_ :: forall action model.
SelectProps action -> [View model action] -> View model action
select_ SelectProps {Bool
[MisoString]
[Attribute action]
Maybe MisoString
selectId :: forall action. SelectProps action -> Maybe MisoString
selectDisabled :: forall action. SelectProps action -> Bool
selectClasses :: forall action. SelectProps action -> [MisoString]
selectAttrs :: forall action. SelectProps action -> [Attribute action]
selectId :: Maybe MisoString
selectDisabled :: Bool
selectClasses :: [MisoString]
selectAttrs :: [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.select_
( [[Attribute action]] -> [Attribute action]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ [MisoString] -> Attribute action
forall action. [MisoString] -> Attribute action
P.classes_ (MisoString
"select" MisoString -> [MisoString] -> [MisoString]
forall a. a -> [a] -> [a]
: [MisoString]
selectClasses) ]
, [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ MisoString
i | Just MisoString
i <- [Maybe MisoString
selectId] ]
, [ Attribute action
forall action. Attribute action
P.disabled_ | Bool
selectDisabled ]
, [Attribute action]
selectAttrs
]
) [View model action]
kids
data model action
=
{ :: MisoString
, :: [View model action]
, :: MisoString
, :: Bool
, :: Bool
, :: [MisoString]
, :: [Attribute action]
}
defaultSelectMenuProps :: SelectMenuProps model action
= SelectMenuProps
{ selectMenuId :: MisoString
selectMenuId = MisoString
"select-menu"
, selectMenuLabel :: [View model action]
selectMenuLabel = []
, selectMenuValue :: MisoString
selectMenuValue = MisoString
""
, selectMenuDisabled :: Bool
selectMenuDisabled = Bool
False
, selectMenuScrollable :: Bool
selectMenuScrollable = Bool
False
, selectMenuTriggerClasses :: [MisoString]
selectMenuTriggerClasses = [ MisoString
"w-[180px]" ]
, selectMenuAttrs :: [Attribute action]
selectMenuAttrs = []
}
selectMenu_
:: SelectMenuProps model action
-> [View model action]
-> View model action
SelectMenuProps model action
cfg [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.class_ MisoString
"select"
Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuId SelectMenuProps model action
cfg)
Attribute action -> [Attribute action] -> [Attribute action]
forall a. a -> [a] -> [a]
: SelectMenuProps model action -> [Attribute action]
forall model action.
SelectMenuProps model action -> [Attribute action]
selectMenuAttrs SelectMenuProps model action
cfg
)
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.button_
( [[Attribute action]] -> [Attribute action]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.type_ MisoString
"button"
, [MisoString] -> Attribute action
forall action. [MisoString] -> Attribute action
P.classes_
( MisoString
"btn-outline" MisoString -> [MisoString] -> [MisoString]
forall a. a -> [a] -> [a]
: MisoString
"justify-between" MisoString -> [MisoString] -> [MisoString]
forall a. a -> [a] -> [a]
: MisoString
"font-normal"
MisoString -> [MisoString] -> [MisoString]
forall a. a -> [a] -> [a]
: SelectMenuProps model action -> [MisoString]
forall model action. SelectMenuProps model action -> [MisoString]
selectMenuTriggerClasses SelectMenuProps model action
cfg
)
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuId SelectMenuProps model action
cfg MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-trigger")
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"haspopup" MisoString
"listbox"
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"expanded" MisoString
"false"
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"controls" (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuId SelectMenuProps model action
cfg MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-listbox")
]
, [ Attribute action
forall action. Attribute action
P.disabled_ | SelectMenuProps model action -> Bool
forall model action. SelectMenuProps model action -> Bool
selectMenuDisabled SelectMenuProps model action
cfg ]
]
)
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.span_ [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"truncate" ] (SelectMenuProps model action -> [View model action]
forall model action.
SelectMenuProps model action -> [View model action]
selectMenuLabel SelectMenuProps model action
cfg)
, [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
chevronDownIcon
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"text-muted-foreground opacity-50 shrink-0" ]
]
, [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"hidden" MisoString
"true"
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.data_ MisoString
"popover" MisoString
""
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuId SelectMenuProps model action
cfg MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-popover")
]
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
( [[Attribute action]] -> [Attribute action]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat
[ [ MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"labelledby" (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuId SelectMenuProps model action
cfg MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-trigger")
, MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"orientation" MisoString
"vertical"
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.id_ (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuId SelectMenuProps model action
cfg MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-listbox")
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.role_ MisoString
"listbox"
]
, [ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.class_ MisoString
"scrollbar overflow-y-auto max-h-64" | SelectMenuProps model action -> Bool
forall model action. SelectMenuProps model action -> Bool
selectMenuScrollable SelectMenuProps model action
cfg ]
]
) [View model action]
kids
]
, [Attribute action] -> View model action
forall action model. [Attribute action] -> View model action
H.input_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.type_ MisoString
"hidden"
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.name_ (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuId SelectMenuProps model action
cfg MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> MisoString
"-value")
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.value_ (SelectMenuProps model action -> MisoString
forall model action. SelectMenuProps model action -> MisoString
selectMenuValue SelectMenuProps model action
cfg)
]
]
selectOption_
:: Bool
-> MisoString
-> [View model action]
-> View model action
selectOption_ :: forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
selected MisoString
value [View model action]
kids =
([Attribute action] -> [View model action] -> View model action)
-> [Attribute action]
-> Bool
-> [Attribute action]
-> [View model action]
-> View model action
forall action model.
([Attribute action] -> [View model action] -> View model action)
-> [Attribute action]
-> Bool
-> [Attribute action]
-> [View model action]
-> View model action
optionalAttrs
[Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.div_
[ MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.data_ MisoString
"value" MisoString
value
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.role_ MisoString
"option"
]
Bool
selected
[ MisoString -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"selected" MisoString
"true" ]
[View model action]
kids
selectGroup_
:: MisoString
-> MisoString
-> [View model action]
-> View model action
selectGroup_ :: forall model action.
MisoString
-> MisoString -> [View model action] -> View model action
selectGroup_ MisoString
headingId MisoString
heading [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 -> MisoString -> Attribute action
forall action. MisoString -> MisoString -> Attribute action
P.aria_ MisoString
"labelledby" MisoString
headingId
, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.role_ MisoString
"group"
]
( [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.id_ MisoString
headingId, MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.role_ MisoString
"heading" ] [ MisoString -> View model action
forall model action. MisoString -> View model action
text MisoString
heading ]
View model action -> [View model action] -> [View model action]
forall a. a -> [a] -> [a]
: [View model action]
kids
)
selectUsage :: View model action
selectUsage :: forall model action. View model action
selectUsage =
[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-wrap items-center gap-2" ]
[ SelectProps action -> [View model action] -> View model action
forall action model.
SelectProps action -> [View model action] -> View model action
select_ SelectProps action
forall action. SelectProps action
defaultSelectProps
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.optgroup_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.label_ MisoString
"Fruits" ]
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.option_ [] [ View model action
"Apple" ]
, [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.option_ [] [ View model action
"Banana" ]
]
]
, SelectMenuProps model action
-> [View model action] -> View model action
forall model action.
SelectMenuProps model action
-> [View model action] -> View model action
selectMenu_ SelectMenuProps (ZonkAny 0) action
forall model action. SelectMenuProps model action
defaultSelectMenuProps
{ selectMenuId = "my-select"
, selectMenuLabel = [ "Blueberry" ]
, selectMenuValue = "blueberry"
}
[ Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
False MisoString
"apple" [ View model action
"Apple" ]
, Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
True MisoString
"blueberry" [ View model action
"Blueberry" ]
]
]
selectSample :: View model action
selectSample :: forall model action. View model action
selectSample =
[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" ]
[ [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-wrap items-center gap-2 md:flex-row" ]
[ SelectProps action -> [View model action] -> View model action
forall action model.
SelectProps action -> [View model action] -> View model action
select_ SelectProps action
forall action. SelectProps action
defaultSelectProps
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.optgroup_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.label_ MisoString
"Fruits" ]
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.option_ [] [ View model action
"Apple" ]
, [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.option_ [] [ View model action
"Banana" ]
, [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.option_ [] [ View model action
"Blueberry" ]
]
, [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.optgroup_
[ MisoString -> Attribute action
forall action. MisoString -> Attribute action
P.label_ MisoString
"Grapes" ]
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.option_ [] [ View model action
"Pineapple" ] ]
]
, SelectProps action -> [View model action] -> View model action
forall action model.
SelectProps action -> [View model action] -> View model action
select_ SelectProps action
forall action. SelectProps action
defaultSelectProps { selectDisabled = True }
[ [Attribute action] -> [View model action] -> View model action
forall action model.
[Attribute action] -> [View model action] -> View model action
H.option_ [] [ View model action
"Disabled" ] ]
]
, [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-wrap items-center gap-2 md:flex-row" ]
[ SelectMenuProps model action
-> [View model action] -> View model action
forall model action.
SelectMenuProps model action
-> [View model action] -> View model action
selectMenu_ SelectMenuProps (ZonkAny 1) action
forall model action. SelectMenuProps model action
defaultSelectMenuProps
{ selectMenuId = "select-default"
, selectMenuLabel = [ "Blueberry" ]
, selectMenuValue = "blueberry"
}
[ MisoString
-> MisoString -> [View model action] -> View model action
forall model action.
MisoString
-> MisoString -> [View model action] -> View model action
selectGroup_ MisoString
"group-label-select-default-items-1" MisoString
"Fruits"
[ Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
False MisoString
"apple" [ View model action
"Apple" ]
, Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
False MisoString
"banana" [ View model action
"Banana" ]
, Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
True MisoString
"blueberry" [ View model action
"Blueberry" ]
]
, MisoString
-> MisoString -> [View model action] -> View model action
forall model action.
MisoString
-> MisoString -> [View model action] -> View model action
selectGroup_ MisoString
"group-label-select-default-items-2" MisoString
"Grapes"
[ Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
False MisoString
"pineapple" [ View model action
"Pineapple" ] ]
]
, SelectMenuProps model action
-> [View model action] -> View model action
forall model action.
SelectMenuProps model action
-> [View model action] -> View model action
selectMenu_ SelectMenuProps (ZonkAny 2) action
forall model action. SelectMenuProps model action
defaultSelectMenuProps
{ selectMenuId = "select-scrollbar"
, selectMenuLabel = [ "Item 0" ]
, selectMenuValue = "item-0"
, selectMenuScrollable = True
}
[ Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ (Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== (Int
0 :: Int)) (MisoString
"item-" MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> Int -> MisoString
forall str. ToMisoString str => str -> MisoString
ms Int
i) [ MisoString -> View model action
forall model action. MisoString -> View model action
text (MisoString
"Item " MisoString -> MisoString -> MisoString
forall a. Semigroup a => a -> a -> a
<> Int -> MisoString
forall str. ToMisoString str => str -> MisoString
ms Int
i) ]
| Int
i <- [ Int
0 .. Int
98 ]
]
, SelectMenuProps model action
-> [View model action] -> View model action
forall model action.
SelectMenuProps model action
-> [View model action] -> View model action
selectMenu_ SelectMenuProps (ZonkAny 3) action
forall model action. SelectMenuProps model action
defaultSelectMenuProps
{ selectMenuId = "select-disabled"
, selectMenuLabel = [ "Disabled" ]
, selectMenuValue = "disabled"
, selectMenuDisabled = True
}
[ Bool -> MisoString -> [View model action] -> View model action
forall model action.
Bool -> MisoString -> [View model action] -> View model action
selectOption_ Bool
True MisoString
"disabled" [ View model action
"Disabled" ] ]
]
]
selectCodeSample :: View model action
selectCodeSample :: forall model action. View model action
selectCodeSample =
View model action
"""
-----------------------------------------------------------------------------
module MySelect (selectUsage) where
-----------------------------------------------------------------------------
import Miso
import qualified Miso.Html.Element as H
import qualified Miso.Html.Property as P
import Miso.UI.Icons
import Miso.UI.Select
-----------------------------------------------------------------------------
selectUsage :: View model action
selectUsage =
H.div_
[ P.class_ "flex flex-wrap items-center gap-2" ]
[ select_ defaultSelectProps
[ H.optgroup_
[ P.label_ "Fruits" ]
[ H.option_ [] [ "Apple" ]
, H.option_ [] [ "Banana" ]
]
]
, selectMenu_ defaultSelectMenuProps
{ selectMenuId = "my-select"
, selectMenuLabel = [ "Blueberry" ]
, selectMenuValue = "blueberry"
}
[ selectOption_ False "apple" [ "Apple" ]
, selectOption_ True "blueberry" [ "Blueberry" ]
]
]
"""
selectPropsApi :: View model action
selectPropsApi :: forall model action. View model action
selectPropsApi =
View model action
"""
-- | Props for the native 'select_'
data SelectProps action
= SelectProps
{ selectId :: Maybe MisoString
, selectDisabled :: Bool
, selectClasses :: [MisoString]
-- ^ Extra classes appended to @select@ (e.g. @w-[180px]@)
, selectAttrs :: [Attribute action]
}
-----------------------------------------------------------------------------
-- | Smart constructor for the native select
defaultSelectProps :: SelectProps action
defaultSelectProps
= SelectProps
{ selectId = Nothing
, selectDisabled = False
, selectClasses = [ "w-[180px]" ]
, selectAttrs = []
}
-----------------------------------------------------------------------------
-- | Props for the popover-based 'selectMenu_' (basecoat JS select)
data SelectMenuProps model action
= SelectMenuProps
{ selectMenuId :: MisoString
-- ^ Base id; trigger\\/popover\\/listbox ids are derived from it (required)
, selectMenuLabel :: [View model action]
-- ^ Content of the trigger button (current selection)
, selectMenuValue :: MisoString
-- ^ Currently selected value (kept in a hidden input)
, selectMenuDisabled :: Bool
, selectMenuScrollable :: Bool
-- ^ Constrain the listbox height and scroll (@max-h-64@)
, selectMenuTriggerClasses :: [MisoString]
-- ^ Extra classes for the trigger button
, selectMenuAttrs :: [Attribute action]
}
-----------------------------------------------------------------------------
-- | Smart constructor for the JS select
defaultSelectMenuProps :: SelectMenuProps model action
defaultSelectMenuProps
= SelectMenuProps
{ selectMenuId = "select-menu"
, selectMenuLabel = []
, selectMenuValue = ""
, selectMenuDisabled = False
, selectMenuScrollable = False
, selectMenuTriggerClasses = [ "w-[180px]" ]
, selectMenuAttrs = []
}
"""