Merge pull request #334 from NoRedInk/tessa/password-supporting-input

Adds V5 of the text input
This commit is contained in:
Tessa 2019-08-06 09:00:54 -07:00 committed by GitHub
commit 816d2900c0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 194 additions and 3 deletions

View File

@ -81,6 +81,7 @@
"Nri.Ui.TextArea.V4", "Nri.Ui.TextArea.V4",
"Nri.Ui.TextInput.V3", "Nri.Ui.TextInput.V3",
"Nri.Ui.TextInput.V4", "Nri.Ui.TextInput.V4",
"Nri.Ui.TextInput.V5",
"Nri.Ui" "Nri.Ui"
], ],
"elm-version": "0.19.0 <= v < 0.20.0", "elm-version": "0.19.0 <= v < 0.20.0",

170
src/Nri/Ui/TextInput/V5.elm Normal file
View File

@ -0,0 +1,170 @@
module Nri.Ui.TextInput.V5 exposing
( Model
, view, writing
, generateId
, number, text, password
)
{-|
# Changes from V4
- adds a password input
@docs Model
@docs view, writing
@docs generateId
## Input types
@docs number, text, password
-}
import Accessibility.Styled.Style as Accessibility
import Css exposing (batch, center, position, px, relative, textAlign)
import Css.Global
import Html.Styled as Html exposing (..)
import Html.Styled.Attributes as Attributes exposing (..)
import Html.Styled.Events as Events exposing (onInput)
import Nri.Ui.Html.Attributes.V2 as Extra
import Nri.Ui.InputStyles.V2 as InputStyles exposing (Theme)
import Nri.Ui.Util exposing (dashify)
{-| -}
type alias Model value msg =
{ label : String
, isInError : Bool
, onInput : value -> msg
, onBlur : Maybe msg
, placeholder : String
, value : value
, autofocus : Bool
, showLabel : Bool
, type_ : InputType value
}
{-| -}
type InputType value
= InputType
{ toString : value -> String
, fromString : String -> value
, fieldType : String
}
{-| An input that allows text entry
-}
text : InputType String
text =
InputType
{ toString = identity
, fromString = identity
, fieldType = "text"
}
{-| An input that allows number entry
-}
number : InputType (Maybe Int)
number =
InputType
{ toString = Maybe.map String.fromInt >> Maybe.withDefault ""
, fromString = String.toInt
, fieldType = "number"
}
{-| An input that allows password entry
-}
password : InputType String
password =
InputType
{ toString = identity
, fromString = identity
, fieldType = "password"
}
{-| -}
view : Model value msg -> Html msg
view model =
view_ InputStyles.Standard model
{-| -}
writing : Model value msg -> Html msg
writing model =
view_ InputStyles.Writing model
view_ : Theme -> Model value msg -> Html msg
view_ theme model =
let
idValue =
generateId model.label
(InputType inputType) =
model.type_
in
div
[ Attributes.css [ position relative ]
]
[ input
[ Attributes.id idValue
, css
[ InputStyles.input theme model.isInError
, if theme == InputStyles.Writing then
Css.Global.withClass "override-sass-styles"
[ textAlign center
, Css.height Css.auto
]
else
Css.Global.withClass "override-sass-styles"
[ Css.height (px 45)
]
]
, placeholder model.placeholder
, value (inputType.toString model.value)
, onInput (inputType.fromString >> model.onInput)
, Maybe.withDefault Extra.none (Maybe.map Events.onBlur model.onBlur)
, autofocus model.autofocus
, type_ inputType.fieldType
, class "override-sass-styles"
, Attributes.attribute "aria-invalid" <|
if model.isInError then
"true"
else
"false"
]
[]
, if model.showLabel then
Html.label
[ for idValue
, css [ InputStyles.label theme model.isInError ]
]
[ Html.text model.label ]
else
Html.label
([ for idValue
, css [ InputStyles.label theme model.isInError ]
]
++ Accessibility.invisible
)
[ Html.text model.label ]
]
{-| Gives you the DOM element id that will be used by a `TextInput.view` with the given label.
This is for use when you need the DOM element id for use in javascript (such as trigger an event to focus a particular text input)
-}
generateId : String -> String
generateId labelText =
"Nri-Ui-TextInput-" ++ dashify labelText

View File

@ -1,26 +1,30 @@
module Examples.TextInput exposing (Msg, State, example, init, update) module Examples.TextInput exposing (Msg, State, example, init, update)
{- \ {-|
@docs Msg, State, example, init, update,
@docs Msg, State, example, init, update
-} -}
import Dict exposing (Dict) import Dict exposing (Dict)
import Html.Styled as Html import Html.Styled as Html
import ModuleExample as ModuleExample exposing (Category(..), ModuleExample) import ModuleExample as ModuleExample exposing (Category(..), ModuleExample)
import Nri.Ui.Heading.V2 as Heading import Nri.Ui.Heading.V2 as Heading
import Nri.Ui.TextInput.V4 as TextInput import Nri.Ui.TextInput.V5 as TextInput
{-| -} {-| -}
type Msg type Msg
= SetTextInput Id String = SetTextInput Id String
| SetNumberInput (Maybe Int) | SetNumberInput (Maybe Int)
| SetPassword String
{-| -} {-| -}
type alias State = type alias State =
{ numberInputValue : Maybe Int { numberInputValue : Maybe Int
, textInputValues : Dict Id String , textInputValues : Dict Id String
, passwordInputValue : String
} }
@ -56,6 +60,18 @@ example parentMessage state =
, showLabel = True , showLabel = True
} }
, Html.br [] [] , Html.br [] []
, TextInput.view
{ label = "Password"
, isInError = False
, placeholder = ""
, value = state.passwordInputValue
, onInput = SetPassword
, onBlur = Nothing
, autofocus = False
, type_ = TextInput.password
, showLabel = True
}
, Html.br [] []
, TextInput.view , TextInput.view
{ label = "Error" { label = "Error"
, isInError = True , isInError = True
@ -149,6 +165,7 @@ init : State
init = init =
{ numberInputValue = Nothing { numberInputValue = Nothing
, textInputValues = Dict.empty , textInputValues = Dict.empty
, passwordInputValue = ""
} }
@ -162,6 +179,9 @@ update msg state =
SetNumberInput numberInputValue -> SetNumberInput numberInputValue ->
( { state | numberInputValue = numberInputValue }, Cmd.none ) ( { state | numberInputValue = numberInputValue }, Cmd.none )
SetPassword password ->
( { state | passwordInputValue = password }, Cmd.none )
-- INTERNAL -- INTERNAL