mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-12-29 16:44:41 +03:00
Extract Nri.Select
from the monolith
This commit is contained in:
parent
115819c2a3
commit
bffaae0e3f
87
src/Nri/Ui/Select/V1.elm
Normal file
87
src/Nri/Ui/Select/V1.elm
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
module Nri.Ui.Select.V1
|
||||||
|
exposing
|
||||||
|
( Config
|
||||||
|
, customView
|
||||||
|
, view
|
||||||
|
)
|
||||||
|
|
||||||
|
{-| Build a select input.
|
||||||
|
|
||||||
|
|
||||||
|
# Configure
|
||||||
|
|
||||||
|
@docs Config
|
||||||
|
|
||||||
|
|
||||||
|
# Render
|
||||||
|
|
||||||
|
@docs view, customView
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Dict
|
||||||
|
import Html exposing (..)
|
||||||
|
import Html.Attributes exposing (..)
|
||||||
|
import Html.Events exposing (..)
|
||||||
|
import Json.Decode exposing (Decoder, andThen, succeed)
|
||||||
|
import Nri.Ui.Util
|
||||||
|
|
||||||
|
|
||||||
|
{-| Select-specific Choice.Config
|
||||||
|
-}
|
||||||
|
type alias Config a =
|
||||||
|
{ choices : List { label : String, value : a }
|
||||||
|
, current : a
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| TODO: move this to View.Extra
|
||||||
|
-}
|
||||||
|
niceId : String -> a -> String
|
||||||
|
niceId prefix x =
|
||||||
|
x
|
||||||
|
|> toString
|
||||||
|
|> Nri.Ui.Util.removePunctuation
|
||||||
|
|> Nri.Ui.Util.dashify
|
||||||
|
|> (++) (prefix ++ "-")
|
||||||
|
|
||||||
|
|
||||||
|
{-| A normal select dropdown
|
||||||
|
-}
|
||||||
|
view : Config a -> Html a
|
||||||
|
view config =
|
||||||
|
customView [] config
|
||||||
|
|
||||||
|
|
||||||
|
{-| A select dropdown with custom attributes.
|
||||||
|
This should be phased out as the new Select style is implemented,
|
||||||
|
all pages should use the new, consistent style.
|
||||||
|
-}
|
||||||
|
customView : List (Html.Attribute a) -> Config a -> Html a
|
||||||
|
customView attributes config =
|
||||||
|
let
|
||||||
|
valueLookup =
|
||||||
|
-- TODO: probably worth using Lazy here, since choices won't change often
|
||||||
|
config.choices
|
||||||
|
|> List.map (\x -> ( niceId "nri-select" x.value, x.value ))
|
||||||
|
|> Dict.fromList
|
||||||
|
|
||||||
|
decodeValue string =
|
||||||
|
Dict.get string valueLookup
|
||||||
|
|> Maybe.map Json.Decode.succeed
|
||||||
|
|> Maybe.withDefault (Json.Decode.fail ("Nri.Select: could not decode the value: " ++ toString string ++ "\nexpected one of: " ++ toString (Dict.keys valueLookup)))
|
||||||
|
|
||||||
|
onSelectHandler =
|
||||||
|
on "change" (targetValue |> andThen decodeValue)
|
||||||
|
|
||||||
|
viewChoice choice =
|
||||||
|
Html.option
|
||||||
|
[ Html.Attributes.id (niceId "nri-select" choice.value)
|
||||||
|
, Html.Attributes.value (niceId "nri-select" choice.value)
|
||||||
|
, Html.Attributes.selected (choice.value == config.current)
|
||||||
|
]
|
||||||
|
[ Html.text choice.label ]
|
||||||
|
in
|
||||||
|
config.choices
|
||||||
|
|> List.map viewChoice
|
||||||
|
|> Html.select (onSelectHandler :: attributes)
|
74
styleguide-app/Examples/Select.elm
Normal file
74
styleguide-app/Examples/Select.elm
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
module Examples.Select
|
||||||
|
exposing
|
||||||
|
( Msg
|
||||||
|
, State
|
||||||
|
, Value
|
||||||
|
, example
|
||||||
|
, init
|
||||||
|
, update
|
||||||
|
)
|
||||||
|
|
||||||
|
{-|
|
||||||
|
|
||||||
|
@docs Msg
|
||||||
|
@docs State
|
||||||
|
@docs Value
|
||||||
|
@docs example
|
||||||
|
@docs init
|
||||||
|
@docs update
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Html
|
||||||
|
import ModuleExample exposing (Category(..), ModuleExample)
|
||||||
|
import Nri.Ui.Select.V1
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
type alias Value =
|
||||||
|
String
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
type Msg
|
||||||
|
= ConsoleLog String
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
type alias State value =
|
||||||
|
Nri.Ui.Select.V1.Config value
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
example : (Msg -> msg) -> State Value -> ModuleExample msg
|
||||||
|
example parentMessage state =
|
||||||
|
{ filename = "ui/src/Nri/Select.elm"
|
||||||
|
, category = Inputs
|
||||||
|
, content =
|
||||||
|
[ Html.map (parentMessage << ConsoleLog) (Nri.Ui.Select.V1.view state)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
init : State Value
|
||||||
|
init =
|
||||||
|
{ current = ""
|
||||||
|
, choices =
|
||||||
|
[ { label = "Tacos", value = "Tacos" }
|
||||||
|
, { label = "Burritos", value = "Burritos" }
|
||||||
|
, { label = "Enchiladas", value = "Enchiladas" }
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
update : Msg -> State Value -> ( State Value, Cmd Msg )
|
||||||
|
update msg state =
|
||||||
|
case msg of
|
||||||
|
ConsoleLog message ->
|
||||||
|
let
|
||||||
|
_ =
|
||||||
|
Debug.log "SelectExample" message
|
||||||
|
in
|
||||||
|
( state, Cmd.none )
|
@ -6,6 +6,7 @@ import Examples.Colors
|
|||||||
import Examples.Fonts
|
import Examples.Fonts
|
||||||
import Examples.Icon
|
import Examples.Icon
|
||||||
import Examples.SegmentedControl
|
import Examples.SegmentedControl
|
||||||
|
import Examples.Select
|
||||||
import Examples.Text
|
import Examples.Text
|
||||||
import Examples.Text.Writing
|
import Examples.Text.Writing
|
||||||
import Examples.TextArea as TextAreaExample
|
import Examples.TextArea as TextAreaExample
|
||||||
@ -23,6 +24,7 @@ import String.Extra
|
|||||||
|
|
||||||
type alias ModuleStates =
|
type alias ModuleStates =
|
||||||
{ segmentedControlState : Examples.SegmentedControl.State
|
{ segmentedControlState : Examples.SegmentedControl.State
|
||||||
|
, selectState : Examples.Select.State Examples.Select.Value
|
||||||
, textAreaExampleState : TextAreaExample.State
|
, textAreaExampleState : TextAreaExample.State
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,12 +32,14 @@ type alias ModuleStates =
|
|||||||
init : ModuleStates
|
init : ModuleStates
|
||||||
init =
|
init =
|
||||||
{ segmentedControlState = Examples.SegmentedControl.init
|
{ segmentedControlState = Examples.SegmentedControl.init
|
||||||
|
, selectState = Examples.Select.init
|
||||||
, textAreaExampleState = TextAreaExample.init
|
, textAreaExampleState = TextAreaExample.init
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
= SegmentedControlMsg Examples.SegmentedControl.Msg
|
= SegmentedControlMsg Examples.SegmentedControl.Msg
|
||||||
|
| SelectMsg Examples.Select.Msg
|
||||||
| ShowItWorked String String
|
| ShowItWorked String String
|
||||||
| TextAreaExampleMsg TextAreaExample.Msg
|
| TextAreaExampleMsg TextAreaExample.Msg
|
||||||
| NoOp
|
| NoOp
|
||||||
@ -53,6 +57,15 @@ update msg moduleStates =
|
|||||||
, Cmd.map SegmentedControlMsg cmd
|
, Cmd.map SegmentedControlMsg cmd
|
||||||
)
|
)
|
||||||
|
|
||||||
|
SelectMsg msg ->
|
||||||
|
let
|
||||||
|
( selectState, cmd ) =
|
||||||
|
Examples.Select.update msg moduleStates.selectState
|
||||||
|
in
|
||||||
|
( { moduleStates | selectState = selectState }
|
||||||
|
, Cmd.map SelectMsg cmd
|
||||||
|
)
|
||||||
|
|
||||||
ShowItWorked group message ->
|
ShowItWorked group message ->
|
||||||
let
|
let
|
||||||
_ =
|
_ =
|
||||||
@ -95,6 +108,7 @@ nriThemedModules : ModuleStates -> List (ModuleExample Msg)
|
|||||||
nriThemedModules model =
|
nriThemedModules model =
|
||||||
[ Examples.Icon.example
|
[ Examples.Icon.example
|
||||||
, Examples.SegmentedControl.example SegmentedControlMsg model.segmentedControlState
|
, Examples.SegmentedControl.example SegmentedControlMsg model.segmentedControlState
|
||||||
|
, Examples.Select.example SelectMsg model.selectState
|
||||||
, Examples.Text.example
|
, Examples.Text.example
|
||||||
, Examples.Text.Writing.example
|
, Examples.Text.Writing.example
|
||||||
, Examples.Fonts.example
|
, Examples.Fonts.example
|
||||||
|
Loading…
Reference in New Issue
Block a user