better examples with grouped choices, batch attr to enable that example

This commit is contained in:
Alex Perkins 2023-02-27 14:11:49 -07:00
parent 1296c8fdcc
commit 05cab4764d
No known key found for this signature in database
GPG Key ID: C7FADD739F72DA0D
4 changed files with 209 additions and 49 deletions

View File

@ -92,21 +92,22 @@ example =
This means that if the starting value is `Nothing` and there is no `defaultDisplayText` This means that if the starting value is `Nothing` and there is no `defaultDisplayText`
then you cannot select the first item in the list without first selecting another one. then you cannot select the first item in the list without first selecting another one.
Use the "choices" selector above to get a feel for what that means. Use the "choices" selector above to get a feel for what that means.
""" |> String.lines """
|> String.lines
|> List.map String.trim |> List.map String.trim
|> String.join " " |> String.join " "
|> Text.markdown |> Text.markdown
] ]
, Text.smallBody , Text.smallBody
[ ("The current value is \"" [ ("The current value is "
++ (case state.selectedValue of ++ (case state.selectedValue of
Just tm -> Just tm ->
"Just '" ++ choosableToString tm ++ "'" "`Just " ++ choosableToCodeString tm ++ "`"
Nothing -> Nothing ->
"`Nothing`" "`Nothing`"
) )
++ "\"." ++ "."
) )
|> Text.markdown |> Text.markdown
] ]
@ -126,7 +127,7 @@ init : State
init = init =
{ control = { control =
Control.record Settings Control.record Settings
|> Control.field "label" (Control.string "Tortilla Selector") |> Control.field "label" (Control.string "Thematically Incoherent Selector")
|> Control.field "attributes" initControls |> Control.field "attributes" initControls
, selectedValue = Nothing , selectedValue = Nothing
} }
@ -141,15 +142,7 @@ type alias Settings =
initControls : Control (List ( String, Select.Attribute Choosable )) initControls : Control (List ( String, Select.Attribute Choosable ))
initControls = initControls =
ControlExtra.list ControlExtra.list
|> ControlExtra.listItem "choices" |> ControlExtra.listItem "choices" initChoices
(Control.map
(\( code, choices ) ->
( "Select.choices choosableToString" ++ code
, Select.choices choosableToString choices
)
)
initChoices
)
|> ControlExtra.optionalListItem "hiddenLabel" |> ControlExtra.optionalListItem "hiddenLabel"
(Control.value ( "Select.hiddenLabel", Select.hiddenLabel )) (Control.value ( "Select.hiddenLabel", Select.hiddenLabel ))
|> ControlExtra.optionalListItem "defaultDisplayText" |> ControlExtra.optionalListItem "defaultDisplayText"
@ -159,7 +152,7 @@ initControls =
, Select.defaultDisplayText str , Select.defaultDisplayText str
) )
) )
(Control.string "Select a tasty tortilla based treat!") (Control.string "Select a tortilla-based treat, a 2020 81kg Olympic Weightlifter, or nothing at all")
) )
|> ControlExtra.optionalListItem "containerCss" |> ControlExtra.optionalListItem "containerCss"
(Control.choice (Control.choice
@ -289,8 +282,8 @@ all81kg2020OlympicWeightlifters =
help [] help []
choosableToString : Choosable -> String choosableToLabel : Choosable -> String
choosableToString tm = choosableToLabel tm =
case tm of case tm of
Tacos -> Tacos ->
"Tacos" "Tacos"
@ -326,41 +319,124 @@ choosableToString tm =
"Harrison Maurus" "Harrison Maurus"
TragicSingleton -> TragicSingleton ->
"Tragic Singleton that cannot be selected" "Tragic Singleton"
toOption : (a -> String) -> a -> { label : String, value : a } choosableToCodeString : Choosable -> String
toOption toString a = choosableToCodeString choosable =
{ label = toString a, value = a } case choosable of
Tacos ->
"Tacos"
Burritos ->
"Burritos"
Enchiladas ->
"Enchiladas"
NixtamalizedCorn ->
"NixtamalizedCorn"
LüXiaojun ->
"LüXiaojun"
ZacaríasBonnat ->
"ZacaríasBonnat"
AntoninoPizzolato ->
"AntoninoPizzolato"
HarrisonMaurus ->
"HarrisonMaurus"
TragicSingleton ->
"TragicSingleton"
toOptionString : (a -> String) -> a -> String texMexLabel : String
toOptionString toString a = texMexLabel =
let "Tex-Mex"
str =
toString a
in
"{ label = \"" ++ str ++ "\", value = \"" ++ str ++ "\" } "
initChoices : Control ( String, List (Choice Choosable) ) weightLifterLabel : String
weightLifterLabel =
"81 kg 2020 Olympic Weightlifters"
toOption : Choosable -> { label : String, value : Choosable }
toOption c =
{ label = choosableToLabel c, value = c }
grouped : List (Select.ChoicesGroup Choosable)
grouped =
[ { label = texMexLabel, choices = List.map toOption allTexMex }
, { label = weightLifterLabel, choices = List.map toOption all81kg2020OlympicWeightlifters }
]
initChoices : Control ( String, Select.Attribute Choosable )
initChoices = initChoices =
let let
toChoice : List Choosable -> Control ( String, List { label : String, value : Choosable } ) toOptionString : Choosable -> String
toChoice choosables = toOptionString c =
( "[" ++ String.join ", " (List.map (toOptionString choosableToString) choosables) ++ "]" "{ value = " ++ choosableToCodeString c ++ ", label = \"" ++ choosableToLabel c ++ "\" } "
, List.map (toOption choosableToString) choosables
)
|> Control.value
toValue : ( String, List Choosable ) -> ( String, Control ( String, List { label : String, value : Choosable } ) ) toChoice : List Choosable -> ( String, List { label : String, value : Choosable } )
toChoice choosables =
( """Select.choices
choosableToLabel
[ """
++ String.join "\n , " (List.map toOptionString choosables)
++ "\n ]"
, List.map toOption choosables
)
toValue : List Choosable -> Control ( String, Select.Attribute Choosable )
toValue = toValue =
Tuple.mapSecond toChoice toChoice >> Tuple.mapSecond (Select.choices choosableToLabel) >> Control.value
toOptionsString : List Choosable -> String
toOptionsString choosables =
"[ "
++ (List.map toOptionString choosables |> String.join "\n , ")
++ "\n ]"
in in
List.map toValue List.map identity
[ ( "Tex-Mex", allTexMex ) [ ( texMexLabel, toValue allTexMex )
, ( "81 Kg 2020 Olympic Weightlifters", all81kg2020OlympicWeightlifters ) , ( "81 Kg 2020 Olympic Weightlifters", toValue all81kg2020OlympicWeightlifters )
, ( "Unselectable list with only one item", [ TragicSingleton ] ) , ( "Grouped Things"
, Control.value <|
( """Select.groupedChoices
choosableToLabel
[ { label = \""""
++ texMexLabel
++ "\"\n , choices = \n "
++ toOptionsString allTexMex
++ """
}
, { label = \""""
++ weightLifterLabel
++ "\"\n , choices = \n "
++ toOptionsString all81kg2020OlympicWeightlifters
++ """
}
]
, Select.choices
choosableToLabel
[ """
++ toOptionString TragicSingleton
++ """ ]"""
, Select.batch
[ Select.groupedChoices choosableToLabel
[ { label = texMexLabel, choices = List.map toOption allTexMex }
, { label = weightLifterLabel, choices = List.map toOption all81kg2020OlympicWeightlifters }
]
, Select.choices choosableToLabel [ toOption TragicSingleton ]
]
)
)
, ( "Unselectable list with only one item", toValue [ TragicSingleton ] )
] ]
|> Control.choice |> Control.choice

View File

@ -1,4 +1,5 @@
Nri.Ui.Block.V3,upgrade to V4 Nri.Ui.Block.V3,upgrade to V4
Nri.Ui.QuestionBox.V2,upgrade to V3 Nri.Ui.QuestionBox.V2,upgrade to V3
Nri.Ui.QuestionBox.V3,upgrade to V4 Nri.Ui.QuestionBox.V3,upgrade to V4
Nri.Ui.Select.V8,upgrade to V9
Nri.Ui.Tabs.V6,upgrade to V7 Nri.Ui.Tabs.V6,upgrade to V7

1 Nri.Ui.Block.V3 upgrade to V4
2 Nri.Ui.QuestionBox.V2 upgrade to V3
3 Nri.Ui.QuestionBox.V3 upgrade to V4
4 Nri.Ui.Select.V8 upgrade to V9
5 Nri.Ui.Tabs.V6 upgrade to V7

View File

@ -9,6 +9,7 @@ module Nri.Ui.Select.V9 exposing
, custom, nriDescription, id, testId , custom, nriDescription, id, testId
, icon , icon
, containerCss, noMargin , containerCss, noMargin
, batch
) )
{-| Build a select input with a label, optional guidance, and error messaging. {-| Build a select input with a label, optional guidance, and error messaging.
@ -43,6 +44,7 @@ module Nri.Ui.Select.V9 exposing
@docs custom, nriDescription, id, testId @docs custom, nriDescription, id, testId
@docs icon @docs icon
@docs containerCss, noMargin @docs containerCss, noMargin
@docs batch
-} -}
@ -112,6 +114,13 @@ errorMessage =
Attribute << InputErrorAndGuidanceInternal.setErrorMessage Attribute << InputErrorAndGuidanceInternal.setErrorMessage
{-| Combine several attributes into one. A nice way to do nothing via batch []
-}
batch : List (Attribute value) -> Attribute value
batch attrs =
List.foldl (\(Attribute update) composition -> composition >> update) identity attrs |> Attribute
{-| A guidance message shows below the input, unless an error message is showing instead. {-| A guidance message shows below the input, unless an error message is showing instead.
-} -}
guidance : String -> Attribute value guidance : String -> Attribute value

View File

@ -11,9 +11,9 @@ import Test.Html.Selector exposing (..)
spec : Test spec : Test
spec = spec =
describe "Nri.Ui.Select.V9" describe "Nri.Ui.Select.V9"
[ test "allows selection" <| [ test "allows selection when no grouping and default value" <|
\() -> \() ->
start ungrouped
-- first option is selected automatically -- first option is selected automatically
|> ensureViewHas |> ensureViewHas
[ id "nri-select-cat" [ id "nri-select-cat"
@ -33,11 +33,39 @@ spec =
, attribute (Attributes.value "My favorite animal is something else") , attribute (Attributes.value "My favorite animal is something else")
] ]
|> done |> done
, test "allows selection when grouping" <|
\() ->
grouped
-- first option is selected automatically
|> ensureViewHas
[ id "nri-select-cat"
, selected True
, attribute (Attributes.value "Cat")
]
|> selectAnimal Dog
|> ensureViewHas
[ id "nri-select-dog"
, selected True
, attribute (Attributes.value "Dog")
]
|> selectAnimal Axolotl
|> ensureViewHas
[ id "nri-select-axolotl"
, selected True
, attribute (Attributes.value "Axolotl")
]
|> selectAnimal Other
|> ensureViewHas
[ id "nri-select-my-favorite-animal-is-something-else"
, selected True
, attribute (Attributes.value "My favorite animal is something else")
]
|> done
] ]
start : ProgramTest Model Msg () ungrouped : ProgramTest Model Msg ()
start = ungrouped =
ProgramTest.createSandbox ProgramTest.createSandbox
{ init = { favoriteAnimal = Nothing } { init = { favoriteAnimal = Nothing }
, update = update , update = update
@ -51,7 +79,7 @@ start =
, value = animal , value = animal
} }
) )
allAnimals (mammals ++ amphibians ++ [ Other ])
) )
, Select.value model.favoriteAnimal , Select.value model.favoriteAnimal
, Select.id selectId , Select.id selectId
@ -62,6 +90,35 @@ start =
|> ProgramTest.start () |> ProgramTest.start ()
grouped : ProgramTest Model Msg ()
grouped =
let
toOption =
\animal ->
{ label = toString animal
, value = animal
}
in
ProgramTest.createSandbox
{ init = { favoriteAnimal = Nothing }
, update = update
, view =
\model ->
Select.view "Favorite type of animal even slimy ones"
[ Select.choices toString [ toOption Other ]
, Select.groupedChoices toString
[ { label = "Mammals", choices = List.map toOption mammals }
, { label = "Amphibians", choices = List.map toOption amphibians }
]
, Select.value model.favoriteAnimal
, Select.id selectId
]
|> Html.Styled.map SelectFavorite
|> Html.Styled.toUnstyled
}
|> ProgramTest.start ()
selectAnimal : Animal -> ProgramTest a b c -> ProgramTest a b c selectAnimal : Animal -> ProgramTest a b c -> ProgramTest a b c
selectAnimal animal = selectAnimal animal =
selectOption selectId "Favorite type of animal" (toString animal) (toString animal) selectOption selectId "Favorite type of animal" (toString animal) (toString animal)
@ -72,15 +129,23 @@ selectId =
"favorite-animal-selector" "favorite-animal-selector"
allAnimals : List Animal mammals : List Animal
allAnimals = mammals =
[ Cat, Dog, Pig, Other ] [ Cat, Dog, Pig ]
amphibians : List Animal
amphibians =
[ Axolotl, Toad, Frog ]
type Animal type Animal
= Cat = Cat
| Dog | Dog
| Pig | Pig
| Axolotl
| Toad
| Frog
| Other | Other
@ -96,6 +161,15 @@ toString animal =
Pig -> Pig ->
"Pig" "Pig"
Axolotl ->
"Axolotl"
Toad ->
"Toad"
Frog ->
"Frog"
Other -> Other ->
"My favorite animal is something else" "My favorite animal is something else"