mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-11-05 00:29:17 +03:00
Merge pull request #419 from NoRedInk/tessa/add-width-label-helpers
Tessa/add width label helpers
This commit is contained in:
commit
42d3c57a8a
@ -1,42 +1,102 @@
|
||||
module Nri.Ui.Svg.V1 exposing
|
||||
( Svg
|
||||
, withColor
|
||||
, withColor, withLabel, withWidth, withHeight
|
||||
, fromHtml, toHtml
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
@docs Svg
|
||||
@docs withColor
|
||||
@docs withColor, withLabel, withWidth, withHeight
|
||||
@docs fromHtml, toHtml
|
||||
|
||||
-}
|
||||
|
||||
import Accessibility.Styled.Widget as Widget
|
||||
import Css exposing (Color)
|
||||
import Html.Styled as Html exposing (Html)
|
||||
import Html.Styled.Attributes as Attributes
|
||||
|
||||
|
||||
{-| -}
|
||||
{-| Opaque type describing a non-interactable Html element.
|
||||
-}
|
||||
type Svg
|
||||
= Svg (Html Never)
|
||||
|
||||
|
||||
{-| -}
|
||||
withColor : Color -> Svg -> Svg
|
||||
withColor color (Svg svg) =
|
||||
Svg (Html.span [ Attributes.css [ Css.color color ] ] [ svg ])
|
||||
= Svg
|
||||
{ icon : Html Never
|
||||
, color : Maybe Color
|
||||
, width : Maybe Css.Px
|
||||
, height : Maybe Css.Px
|
||||
, label : Maybe String
|
||||
}
|
||||
|
||||
|
||||
{-| Tag html as being an svg.
|
||||
-}
|
||||
fromHtml : Html Never -> Svg
|
||||
fromHtml =
|
||||
fromHtml icon =
|
||||
Svg
|
||||
{ icon = icon
|
||||
, color = Nothing
|
||||
, height = Nothing
|
||||
, width = Nothing
|
||||
, label = Nothing
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
withColor : Color -> Svg -> Svg
|
||||
withColor color (Svg record) =
|
||||
Svg { record | color = Just color }
|
||||
|
||||
|
||||
{-| Add a string aria-label property to the element.
|
||||
|
||||
See [Using the aria-label attribute](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_aria-label_attribute) for
|
||||
guidelines of when and how to use this attribute.
|
||||
|
||||
-}
|
||||
withLabel : String -> Svg -> Svg
|
||||
withLabel label (Svg record) =
|
||||
Svg { record | label = Just label }
|
||||
|
||||
|
||||
{-| -}
|
||||
withWidth : Css.Px -> Svg -> Svg
|
||||
withWidth width (Svg record) =
|
||||
Svg { record | width = Just width }
|
||||
|
||||
|
||||
{-| -}
|
||||
withHeight : Css.Px -> Svg -> Svg
|
||||
withHeight height (Svg record) =
|
||||
Svg { record | height = Just height }
|
||||
|
||||
|
||||
{-| Render an svg.
|
||||
-}
|
||||
toHtml : Svg -> Html msg
|
||||
toHtml (Svg svg) =
|
||||
Html.map never svg
|
||||
toHtml (Svg record) =
|
||||
let
|
||||
css =
|
||||
List.filterMap identity
|
||||
[ Maybe.map Css.color record.color
|
||||
, Maybe.map Css.width record.width
|
||||
, Maybe.map Css.height record.height
|
||||
]
|
||||
|
||||
attributes =
|
||||
List.filterMap identity
|
||||
[ if List.isEmpty css then
|
||||
Nothing
|
||||
|
||||
else
|
||||
Just (Attributes.css (Css.display Css.inlineBlock :: css))
|
||||
, Maybe.map Widget.label record.label
|
||||
]
|
||||
in
|
||||
case attributes of
|
||||
[] ->
|
||||
Html.map never record.icon
|
||||
|
||||
_ ->
|
||||
Html.div attributes [ Html.map never record.icon ]
|
||||
|
195
styleguide-app/Examples/Svg.elm
Normal file
195
styleguide-app/Examples/Svg.elm
Normal file
@ -0,0 +1,195 @@
|
||||
module Examples.Svg exposing
|
||||
( Msg
|
||||
, State
|
||||
, example
|
||||
, init
|
||||
, update
|
||||
)
|
||||
|
||||
{-|
|
||||
|
||||
@docs Msg
|
||||
@docs State
|
||||
@docs example
|
||||
@docs init
|
||||
@docs update
|
||||
|
||||
-}
|
||||
|
||||
import Color exposing (Color)
|
||||
import Css
|
||||
import Examples.IconExamples as IconExamples
|
||||
import Html.Styled as Html
|
||||
import Html.Styled.Attributes as Attributes
|
||||
import Html.Styled.Events as Events
|
||||
import ModuleExample exposing (Category(..), ModuleExample)
|
||||
import Nri.Ui.Colors.Extra exposing (fromCssColor, toCssColor)
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Heading.V2 as Heading
|
||||
import Nri.Ui.Select.V6 as Select
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
|
||||
|
||||
{-| -}
|
||||
example : (Msg -> msg) -> State -> ModuleExample msg
|
||||
example parentMessage state =
|
||||
{ name = "Nri.Ui.Svg.V1"
|
||||
, category = Icons
|
||||
, content =
|
||||
[ viewSettings state
|
||||
|> Html.map parentMessage
|
||||
, viewResults state
|
||||
]
|
||||
}
|
||||
|
||||
|
||||
viewSettings : State -> Html.Html Msg
|
||||
viewSettings state =
|
||||
Html.div
|
||||
[ Attributes.css
|
||||
[ Css.displayFlex
|
||||
, Css.justifyContent Css.spaceBetween
|
||||
]
|
||||
]
|
||||
[ Html.label []
|
||||
[ Html.text "Color: "
|
||||
, Html.input
|
||||
[ Attributes.type_ "color"
|
||||
, Attributes.value (Color.toHex state.color)
|
||||
, Events.onInput (SetColor << Color.fromHex)
|
||||
]
|
||||
[]
|
||||
]
|
||||
, Html.label []
|
||||
[ Html.text "Width: "
|
||||
, Html.input
|
||||
[ Attributes.type_ "range"
|
||||
, Attributes.min "0"
|
||||
, Attributes.max "200"
|
||||
, Attributes.value (String.fromFloat state.width)
|
||||
, Events.onInput (SetWidth << String.toFloat)
|
||||
]
|
||||
[]
|
||||
]
|
||||
, Html.label []
|
||||
[ Html.text "Height: "
|
||||
, Html.input
|
||||
[ Attributes.type_ "range"
|
||||
, Attributes.min "0"
|
||||
, Attributes.max "200"
|
||||
, Attributes.value (String.fromFloat state.height)
|
||||
, Events.onInput (SetHeight << String.toFloat)
|
||||
]
|
||||
[]
|
||||
]
|
||||
, Html.label []
|
||||
[ Html.text "Aria-label: "
|
||||
, Html.input
|
||||
[ Attributes.value state.label
|
||||
, Events.onInput SetLabel
|
||||
]
|
||||
[]
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
viewResults : State -> Html.Html msg
|
||||
viewResults state =
|
||||
let
|
||||
( red, green, blue ) =
|
||||
Color.toRGB state.color
|
||||
in
|
||||
Html.div [ Attributes.css [ Css.displayFlex ] ]
|
||||
[ Html.pre
|
||||
[ Attributes.css
|
||||
[ Css.width (Css.px 400)
|
||||
, Css.marginRight (Css.px 20)
|
||||
]
|
||||
]
|
||||
[ [ "color : Css.Color"
|
||||
, "color ="
|
||||
, " Css.rgb " ++ String.fromFloat red ++ " " ++ String.fromFloat green ++ " " ++ String.fromFloat blue
|
||||
, ""
|
||||
, ""
|
||||
, "renderedSvg : Svg "
|
||||
, "renderedSvg = "
|
||||
, " UiIcon.newspaper"
|
||||
, " |> Svg.withColor color"
|
||||
, " |> Svg.withWidth (Css.px " ++ String.fromFloat state.width ++ ")"
|
||||
, " |> Svg.withHeight (Css.px " ++ String.fromFloat state.height ++ ")"
|
||||
, " |> Svg.withLabel \"" ++ state.label ++ "\""
|
||||
, " |> Svg.toHtml"
|
||||
]
|
||||
|> String.join "\n"
|
||||
|> Html.text
|
||||
]
|
||||
, Html.div
|
||||
[ Attributes.css
|
||||
[ Css.backgroundColor Colors.gray92
|
||||
, Css.flexGrow (Css.int 2)
|
||||
]
|
||||
]
|
||||
[ UiIcon.newspaper
|
||||
|> Svg.withColor (toCssColor state.color)
|
||||
|> Svg.withWidth (Css.px state.width)
|
||||
|> Svg.withHeight (Css.px state.height)
|
||||
|> Svg.withLabel state.label
|
||||
|> Svg.toHtml
|
||||
]
|
||||
]
|
||||
|
||||
|
||||
{-| -}
|
||||
type alias State =
|
||||
{ color : Color
|
||||
, width : Float
|
||||
, height : Float
|
||||
, label : String
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
init : State
|
||||
init =
|
||||
{ color = fromCssColor Colors.blue
|
||||
, width = 30
|
||||
, height = 30
|
||||
, label = "Newspaper"
|
||||
}
|
||||
|
||||
|
||||
{-| -}
|
||||
type Msg
|
||||
= SetColor (Result String Color)
|
||||
| SetWidth (Maybe Float)
|
||||
| SetHeight (Maybe Float)
|
||||
| SetLabel String
|
||||
|
||||
|
||||
{-| -}
|
||||
update : Msg -> State -> ( State, Cmd Msg )
|
||||
update msg state =
|
||||
case msg of
|
||||
SetColor (Ok color) ->
|
||||
( { state | color = color }
|
||||
, Cmd.none
|
||||
)
|
||||
|
||||
SetColor (Err err) ->
|
||||
( state, Cmd.none )
|
||||
|
||||
SetWidth (Just width) ->
|
||||
( { state | width = width }, Cmd.none )
|
||||
|
||||
SetWidth Nothing ->
|
||||
( state, Cmd.none )
|
||||
|
||||
SetHeight (Just height) ->
|
||||
( { state | height = height }, Cmd.none )
|
||||
|
||||
SetHeight Nothing ->
|
||||
( state, Cmd.none )
|
||||
|
||||
SetLabel label ->
|
||||
( { state | label = label }, Cmd.none )
|
@ -24,6 +24,7 @@ import Examples.Select
|
||||
import Examples.Slide
|
||||
import Examples.SlideModal
|
||||
import Examples.SortableTable
|
||||
import Examples.Svg
|
||||
import Examples.Table
|
||||
import Examples.Tabs
|
||||
import Examples.Text
|
||||
@ -55,6 +56,7 @@ type alias ModuleStates =
|
||||
, slideModalExampleState : Examples.SlideModal.State
|
||||
, slideExampleState : Examples.Slide.State
|
||||
, sortableTableState : Examples.SortableTable.State
|
||||
, svgState : Examples.Svg.State
|
||||
, tabsExampleState : Examples.Tabs.Tab
|
||||
, tooltipExampleState : Examples.Tooltip.State
|
||||
}
|
||||
@ -78,6 +80,7 @@ init =
|
||||
, slideModalExampleState = Examples.SlideModal.init
|
||||
, slideExampleState = Examples.Slide.init
|
||||
, sortableTableState = Examples.SortableTable.init
|
||||
, svgState = Examples.Svg.init
|
||||
, tabsExampleState = Examples.Tabs.First
|
||||
, tooltipExampleState = Examples.Tooltip.init
|
||||
}
|
||||
@ -101,6 +104,7 @@ type Msg
|
||||
| SlideModalExampleMsg Examples.SlideModal.Msg
|
||||
| SlideExampleMsg Examples.Slide.Msg
|
||||
| SortableTableMsg Examples.SortableTable.Msg
|
||||
| SvgMsg Examples.Svg.Msg
|
||||
| TabsExampleMsg Examples.Tabs.Tab
|
||||
| TooltipExampleMsg Examples.Tooltip.Msg
|
||||
| NoOp
|
||||
@ -184,6 +188,15 @@ update outsideMsg moduleStates =
|
||||
in
|
||||
( moduleStates, Cmd.none )
|
||||
|
||||
SvgMsg msg ->
|
||||
let
|
||||
( svgState, cmd ) =
|
||||
Examples.Svg.update msg moduleStates.svgState
|
||||
in
|
||||
( { moduleStates | svgState = svgState }
|
||||
, Cmd.map SvgMsg cmd
|
||||
)
|
||||
|
||||
TableExampleMsg msg ->
|
||||
let
|
||||
( tableExampleState, cmd ) =
|
||||
@ -321,6 +334,7 @@ nriThemedModules model =
|
||||
, Examples.Slide.example SlideExampleMsg model.slideExampleState
|
||||
, Examples.SlideModal.example SlideModalExampleMsg model.slideModalExampleState
|
||||
, Examples.SortableTable.example SortableTableMsg model.sortableTableState
|
||||
, Examples.Svg.example SvgMsg model.svgState
|
||||
, Examples.Table.example TableExampleMsg model.tableExampleState
|
||||
, Examples.Tabs.example TabsExampleMsg model.tabsExampleState
|
||||
, Examples.Text.example
|
||||
|
Loading…
Reference in New Issue
Block a user