Update TextArea to latest state in the monolith

This commit is contained in:
Jasper Woudenberg 2018-02-28 15:22:09 -08:00
parent 9987d5f738
commit f4f24f33e8
7 changed files with 650 additions and 74 deletions

View File

@ -0,0 +1,292 @@
module Nri.Ui.CssFlexBoxWithVendorPrefix
exposing
( alignItems
, alignSelf
, baseline
, center
, column
, columnReverse
, displayFlex
, displayInlineFlex
, flexBasis
, flexDirection
, flexEnd
, flexGrow
, flexShrink
, flexStart
, flexWrap
, justifyContent
, nowrap
, row
, rowReverse
, spaceAround
, spaceBetween
, stretch
, wrap
, wrapReverse
)
{-|
@docs displayFlex, displayInlineFlex, flexDirection, justifyContent, alignItems, alignSelf, flexBasis
@docs flexGrow, flexShrink, row, rowReverse, column, columnReverse, flexStart, flexEnd, baseline, stretch, center, spaceBetween, spaceAround, flexWrap, nowrap, wrap, wrapReverse
-}
import Css exposing (Style, batch, property)
{-| -}
displayFlex : Style
displayFlex =
batch
[ property "display" "-webkit-box" -- OLD - iOS 6-, Safari 3.1-6
, property "display" "-moz-box" -- OLD - Firefox 19- (buggy but mostly works)
, property "display" "-ms-flexbox" -- TWEENER - IE 10
, property "display" "-webkit-flex" -- NEW - Chrome
, property "display" "flex" -- NEW, Spec - Opera 12.1, Firefox 20+
]
{-| -}
displayInlineFlex : Style
displayInlineFlex =
batch
[ property "display" "-webkit-inline-box" -- OLD - iOS 6-, Safari 3.1-6
, property "display" "-moz-inline-box" -- OLD - Firefox 19- (buggy but mostly works)
, property "display" "-ms-inline-flexbox" -- TWEENER - IE 10
, property "display" "-webkit-inline-flex" -- NEW - Chrome
, property "display" "inline-flex" -- NEW, Spec - Opera 12.1, Firefox 20+
]
{-| -}
flexDirection : Direction -> Style
flexDirection direction =
addPrefix "flex-direction" <|
case direction of
Row ->
"row"
RowReverse ->
"row-reverse"
Column ->
"column"
ColumnReverse ->
"column-reverse"
type Direction
= Row
| RowReverse
| Column
| ColumnReverse
{-| Direction row.
-}
row : Direction
row =
Row
{-| Direction rowReverse.
-}
rowReverse : Direction
rowReverse =
RowReverse
{-| Direction column.
-}
column : Direction
column =
Column
{-| Direction columnReverse.
-}
columnReverse : Direction
columnReverse =
ColumnReverse
{-| -}
justifyContent : Alignment JustifyContent a -> Style
justifyContent =
addPrefix "justify-content" << alignmentToString
{-| -}
alignItems : Alignment a AlignItems -> Style
alignItems =
addPrefix "align-items" << alignmentToString
{-| -}
alignSelf : Alignment a AlignItems -> Style
alignSelf =
addPrefix "align-self" << alignmentToString
{-| -}
flexBasis : Css.Length compatible units -> Style
flexBasis =
addPrefix "flex-basis" << .value
{-| -}
flexGrow : Float -> Style
flexGrow value =
addPrefix "flex-grow" (toString value)
{-| -}
flexShrink : Float -> Style
flexShrink value =
addPrefix "flex-shrink" (toString value)
{-| -}
flexWrap : Wrap -> Style
flexWrap value =
addPrefix "flex-wrap" <|
case value of
Nowrap ->
"nowrap"
Wrap ->
"wrap"
WrapReverse ->
"wrap-reverse"
type Wrap
= Nowrap
| Wrap
| WrapReverse
{-| flex-wrap nowrap
-}
nowrap : Wrap
nowrap =
Nowrap
{-| flex-wrap wrap
-}
wrap : Wrap
wrap =
Wrap
{-| flex-wrap wrapReverse
-}
wrapReverse : Wrap
wrapReverse =
WrapReverse
type Alignment justify align
= FlexStart justify align
| FlexEnd justify align
| Center justify align
| SpaceBetween justify
| SpaceAround justify
| Baseline align
| Stretch align
alignmentToString : Alignment a b -> String
alignmentToString value =
case value of
FlexStart _ _ ->
"flex-start"
FlexEnd _ _ ->
"flex-end"
Center _ _ ->
"center"
SpaceBetween _ ->
"space-between"
SpaceAround _ ->
"space-around"
Baseline _ ->
"baseline"
Stretch _ ->
"stretch"
type JustifyContent
= JustifyContent
type AlignItems
= AlignItems
{-| align-items/justify-content flexStart
-}
flexStart : Alignment JustifyContent AlignItems
flexStart =
FlexStart JustifyContent AlignItems
{-| align-items/justify-content flexEnd
-}
flexEnd : Alignment JustifyContent AlignItems
flexEnd =
FlexEnd JustifyContent AlignItems
{-| align-items/justify-content center
-}
center : Alignment JustifyContent AlignItems
center =
Center JustifyContent AlignItems
{-| justify-content spaceBetween
-}
spaceBetween : Alignment JustifyContent Never
spaceBetween =
SpaceBetween JustifyContent
{-| justify-content spaceAround
-}
spaceAround : Alignment JustifyContent Never
spaceAround =
SpaceAround JustifyContent
{-| align-items baseline
-}
baseline : Alignment Never AlignItems
baseline =
Baseline AlignItems
{-| align-items stretch
-}
stretch : Alignment Never AlignItems
stretch =
Stretch AlignItems
addPrefix : String -> String -> Style
addPrefix propertyName value =
batch
[ property ("-webkit-" ++ propertyName) value
, property propertyName value
, property ("-ms-" ++ propertyName) value
]

View File

@ -0,0 +1,31 @@
module Nri.Ui.DatePickerConstants exposing (..)
{-|
@docs datePickerTag
@docs dialogTag
@docs footerTag
-}
{-| The class of the entire date picker
-}
datePickerTag : String
datePickerTag =
"date-time-picker"
{-| The class of just the dialog that shows up when you open the datepicker
-}
dialogTag : String
dialogTag =
"date-time-picker-dialog"
{-| The class of the footer in the dialog.
This is where the pretty-printed date is displayed.
-}
footerTag : String
footerTag =
"date-time-picker-footer"

235
src/Nri/Ui/InputStyles.elm Normal file
View File

@ -0,0 +1,235 @@
module Nri.Ui.InputStyles exposing (CssClasses(..), styles)
{-|
@docs styles, CssClasses
-}
import Css exposing (..)
import Css.Foreign exposing (Snippet, adjacentSiblings, children, class, descendants, each, everything, media, selector, withClass)
import Nri.Accessibility
import Nri.Colors exposing (..)
import Nri.Fonts
import Nri.Stylers
import Nri.Ui.AssetPath as AssetPath exposing (Asset)
import Nri.Ui.CssFlexBoxWithVendorPrefix as FlexBox
import Nri.Ui.DatePickerConstants
import Nri.Ui.Styles.V1 as Styles
{-| Classes to be used in Nri Inputs such as Nri.TextInput and Nri.TextArea
-}
type CssClasses
= Container
| InvisibleLabel
| Label
| Input
| IsInError
-- For textarea
| Writing
-- For date picker inputs
| DatePickerContainer
| TimePickerContainer
| CalendarIcon
| Date
-- For searchbar
| SearchBar
| SearchFilterIcon
| IsSearching
namespace : String
namespace =
"Nri-Input-"
{-| -}
styles : Styles.StylesWithAssets Never CssClasses msg (Assets r)
styles =
let
focusedLabelSelector =
-- This selects elements with the Label class that directly follows a focused input, so we can change the label styles on focus
-- Should come out to: ".Nri-Input-Input:focus + .Nri-Input-Label"
"."
++ namespace
++ toString Input
++ ":focus + "
++ "."
++ namespace
++ toString Label
inputStyle =
[ border3 (px 1) solid gray75
, borderRadius (px 8)
, padding2 (px 8) (px 14)
, property "transition" "all 0.1s ease"
, pseudoClass "placeholder"
[ color gray45
]
, Nri.Stylers.makeFont (px 15) gray20
-- fix bootstrap
, display inlineBlock
, verticalAlign top
, marginBottom zero
, lineHeight (px 20)
, marginTop (px 9)
, boxShadow6 inset zero (px 2) zero zero Nri.Colors.gray92
, property "transition" "all 0.4s ease"
, focus
[ borderColor azure
, outline none
, boxShadow6 inset zero (px 2) zero zero Nri.Colors.glacier
]
]
in
Styles.stylesWithAssets namespace <|
\assets ->
[ selector "input"
[ withClass Input
(inputStyle
++ [ height (px 45)
, width (pct 100)
]
)
]
, selector "textarea"
[ withClass Input
(inputStyle
++ [ height (px 100)
, width (pct 100)
]
)
]
, class Container
[ position relative
]
, class InvisibleLabel
[ Nri.Accessibility.invisibleText
]
, class Label
[ backgroundColor Nri.Colors.white
, left (px 10)
, top (px 0)
, padding2 zero (px 5)
, Nri.Stylers.makeFont (px 12) navy
, position absolute
, fontWeight (int 600)
, property "transition" "all 0.4s ease"
]
, class Writing
[ descendants
[ class Input
[ Nri.Fonts.quizFont
, fontSize (px 20)
, lineHeight (px 25)
, minHeight (px 150)
, padding (px 15)
, paddingTop (px 20)
]
, class Label
[ border3 (px 1) solid Nri.Colors.gray75
, borderRadius (px 4)
, Nri.Stylers.makeFont (px 15) Nri.Colors.navy
]
, selector focusedLabelSelector
[ backgroundColor Nri.Colors.azure
, color Nri.Colors.white
, borderColor Nri.Colors.azure
]
]
, withClass IsInError
[ descendants
[ class Label
[ color Nri.Colors.purple
, backgroundColor Nri.Colors.white
, borderColor Nri.Colors.purple
]
, selector focusedLabelSelector
[ backgroundColor Nri.Colors.purple
, color Nri.Colors.white
, borderColor Nri.Colors.purple
]
]
]
]
, class IsInError
[ descendants
[ class Label [ color purple ]
, class Input
[ borderColor purple
, boxShadow6 inset zero (px 2) zero zero Nri.Colors.purpleLight
, focus
[ borderColor purple
, boxShadow6 inset zero (px 2) zero zero Nri.Colors.purpleLight
]
]
]
]
, class DatePickerContainer
[ position relative
, FlexBox.flexGrow 3
, FlexBox.flexBasis (px 128)
]
, class TimePickerContainer
[ marginLeft (px 3)
, position relative
, FlexBox.flexGrow 1
, FlexBox.flexBasis (px 91)
]
, class CalendarIcon
-- Used for date picker
[ position absolute
, backgroundImage (url <| AssetPath.url assets.iconCalendar_svg)
, backgroundRepeat noRepeat
, height (px 25)
, width (px 25)
, top (px 18)
, right (px 5)
, cursor pointer
, property "pointer-events" "none"
]
, class Date
[ FlexBox.flexGrow 1
, position relative
, paddingBottom (px 5)
, FlexBox.displayFlex
]
, selector Nri.Ui.DatePickerConstants.dialogTag
[ backgroundColor Nri.Colors.gray96
]
, selector Nri.Ui.DatePickerConstants.datePickerTag
[ property "min-width" "auto" ]
, class SearchBar
[ descendants
[ class Input
[ margin zero ]
]
]
, class SearchFilterIcon
[ position absolute
, backgroundImage (url <| AssetPath.url assets.icons_searchGray_svg)
, backgroundRepeat noRepeat
, backgroundSize contain
, height (px 20)
, width (px 20)
, top (px 12)
, right (px 10)
, withClass IsSearching
[ backgroundImage (url <| AssetPath.url assets.icons_xBlue_svg)
, cursor pointer
, Css.height (px 14)
, Css.width (px 14)
, top (px 16)
]
]
]
type alias Assets r =
{ r
| iconCalendar_svg : Asset
, icons_searchGray_svg : Asset
, icons_xBlue_svg : Asset
}

View File

@ -17,7 +17,6 @@ module Nri.Ui.Styles.V1 exposing (Keyframe, Styles, StylesWithAssets, keyframes,
-}
import Css
import Css.Foreign exposing (Snippet, children, descendants, everything, selector)
import DEPRECATED.Css.File exposing (Stylesheet, compile, stylesheet)
import DEPRECATED.Css.Namespace

View File

@ -43,7 +43,6 @@ Modifying strings to display nicely:
import Css exposing (..)
import Css.Foreign exposing (Snippet, children, descendants, everything, selector)
import Css.Helpers exposing (identifierToString)
import DEPRECATED.Css.File exposing (Stylesheet, compile, stylesheet)
import Html exposing (..)
import Nri.Colors exposing (..)
import Nri.Stylers exposing (makeFont)

View File

@ -1,61 +1,108 @@
module Nri.Ui.TextArea.V1 exposing (styles, view)
module Nri.Ui.TextArea.V1
exposing
( Model
, generateId
, view
, writing
)
{-|
## The Nri styleguide-specified textarea with overlapping label
@docs view, styles
@docs view, writing, Model, generateId
-}
import Css exposing (..)
import Css.Foreign exposing (Snippet, children, descendants, everything, selector)
import DEPRECATED.Css.File exposing (Stylesheet, compile, stylesheet)
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (onInput)
import Nri.Accessibility exposing (invisibleText)
import Nri.Colors exposing (..)
import Nri.Colors.Extra exposing (withAlpha)
import Nri.Stylers
import Nri.Ui.Styles.V1
import Nri.Ui.InputStyles exposing (CssClasses(..), styles)
import Nri.Ui.Util exposing (dashify, removePunctuation)
{-| -}
type alias Model msg =
{ value : String
, autofocus : Bool
, onInput : String -> msg
, isInError : Bool
, autoResize : Bool
, placeholder : String
, label : String
, showLabel : Bool
, id : String
}
{-| -}
view : Model msg -> Html msg
view model =
div
[ styles.classList
[ ( Container, True )
]
]
[ Html.textarea
view_ DefaultStyle model
{-| Used for Writing Cycles
-}
writing : Model msg -> Html msg
writing model =
view_ WritingStyle model
type TextAreaStyle
= DefaultStyle
| WritingStyle
{-| -}
view_ : TextAreaStyle -> Model msg -> Html msg
view_ textAreaStyle model =
let
showWritingClass =
textAreaStyle == WritingStyle
sharedAttributes =
[ onInput model.onInput
, Html.Attributes.id model.id
, styles.classList
[ ( IsInError, model.isInError )
, ( TextArea, True )
]
, Html.Attributes.id (generateId model.label)
, styles.class [ Input ]
, autofocus model.autofocus
, placeholder model.placeholder
, attribute "data-gramm" "false" -- disables grammarly to prevent https://github.com/NoRedInk/NoRedInk/issues/14859
]
[ Html.text model.value ]
in
div
[ styles.classList
[ ( Container, True )
, ( IsInError, model.isInError )
, ( Writing, showWritingClass )
]
]
[ if model.autoResize then
{- NOTES:
The autoresize-textarea element is implemented to pass information applied to itself to an internal
textarea element that it inserts into the DOM automatically. Maintaing this behavior may require some
changes on your part, as listed below.
- When adding an Html.Attribute that is a _property_, you must edit Nri/TextArea.js to ensure that a getter and setter
are set up to properly reflect the property to the actual textarea element that autoresize-textarea creates
- When adding a new listener from Html.Events, you must edit Nri/TextArea.js to ensure that a listener is set up on
the textarea that will trigger this event on the autoresize-textarea element itself. See AutoresizeTextArea.prototype._onInput
and AutoresizeTextArea.prototype.connectedCallback for an example pertaining to the `input` event
- When adding a new Html.Attribute that is an _attribute_, you don't have to do anything. All attributes are
automatically reflected onto the textarea element via AutoresizeTextArea.prototype.attributeChangedCallback
-}
Html.node "autoresize-textarea"
(sharedAttributes
++ [ -- setting the default value via a text node doesn't play well with the custom element,
-- but we'll be able to switch to the regular value property in 0.19 anyway
defaultValue model.value
]
)
[]
else
Html.textarea sharedAttributes
[ Html.text model.value ]
, Html.label
[ for model.id
[ for (generateId model.label)
, styles.classList
[ ( InvisibleLabel, not model.showLabel )
, ( Label, True )
@ -65,52 +112,7 @@ view model =
]
type CssClass
= InvisibleLabel
| Label
| Container
| IsInError
| TextArea
{-| -}
styles : Nri.Ui.Styles.V1.Styles Never CssClass msg
styles =
Nri.Ui.Styles.V1.styles "Nri-Ui-Textarea-"
[ Css.Foreign.class Container
[ position relative
, paddingTop (px 7)
]
, Css.Foreign.class InvisibleLabel
[ Nri.Accessibility.invisibleText
]
, Css.Foreign.class Label
[ backgroundColor Nri.Colors.white
, left (px 10)
, top (px 0)
, padding2 (px 2) (px 5)
, position absolute
, Nri.Stylers.makeFont (Css.px 11) Nri.Colors.gray45
, border3 (px 1) solid Nri.Colors.gray75
, borderRadius (px 3)
]
, Css.Foreign.class TextArea
[ boxShadow5 inset zero (px 1) (px 1) (withAlpha 0.2 gray20)
, position relative
, resize vertical
, Nri.Stylers.makeFont (Css.px 13) Nri.Colors.gray20
, border3 (px 1) solid Nri.Colors.gray75
, borderRadius (px 8)
, padding2 (px 12) (px 15)
, Css.height (px 100)
, Css.width (pct 100)
, Css.property "transition" "all 0.1s ease"
, focus
[ borderColor Nri.Colors.turquoise -- TODO: swap for new styleguide color
, outline none
]
, Css.Foreign.withClass IsInError
[ borderColor purple
]
]
]
generateId : String -> String
generateId labelText =
"nri-text-area-" ++ (dashify <| removePunctuation labelText)

18
src/Nri/Ui/Util.elm Normal file
View File

@ -0,0 +1,18 @@
module Nri.Ui.Util exposing (dashify, removePunctuation)
import Regex
{-| Convenience method for going from a string with spaces to a string with dashes.
-}
dashify : String -> String
dashify =
Regex.replace Regex.All (Regex.regex " ") (always "-")
{-| Convenience method for removing punctuation
(removes everything that isn't whitespace or alphanumeric).
-}
removePunctuation : String -> String
removePunctuation =
Regex.replace Regex.All (Regex.regex "[^A-z0-9\\w\\s]") (always "")