mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2025-01-07 06:56:53 +03:00
Merge branch 'master' into tessa/add-svg-button
This commit is contained in:
commit
03d99a583d
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -1 +1 @@
|
|||||||
styleguide-app/assets/images/** filter=lfs diff=lfs merge=lfs -text
|
lib/noredink-ui/styleguide-app/assets/images/** filter=lfs diff=lfs merge=lfs -text
|
||||||
|
@ -19,6 +19,7 @@ before_install:
|
|||||||
make && make install;
|
make && make install;
|
||||||
cd ..;
|
cd ..;
|
||||||
fi
|
fi
|
||||||
|
cd lib/noredink-ui
|
||||||
|
|
||||||
install:
|
install:
|
||||||
- travis_retry $TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2 make -B setup
|
- travis_retry $TRAVIS_BUILD_DIR/sysconfcpus/bin/sysconfcpus -n 2 make -B setup
|
||||||
|
0
.gitignore → lib/noredink-ui/.gitignore
vendored
0
.gitignore → lib/noredink-ui/.gitignore
vendored
@ -3,7 +3,7 @@
|
|||||||
"name": "NoRedInk/noredink-ui",
|
"name": "NoRedInk/noredink-ui",
|
||||||
"summary": "UI Widgets we use at NRI",
|
"summary": "UI Widgets we use at NRI",
|
||||||
"license": "BSD-3-Clause",
|
"license": "BSD-3-Clause",
|
||||||
"version": "7.17.0",
|
"version": "7.21.0",
|
||||||
"exposed-modules": [
|
"exposed-modules": [
|
||||||
"Nri.Ui",
|
"Nri.Ui",
|
||||||
"Nri.Ui.Accordion.V1",
|
"Nri.Ui.Accordion.V1",
|
||||||
@ -24,6 +24,7 @@
|
|||||||
"Nri.Ui.Button.V7",
|
"Nri.Ui.Button.V7",
|
||||||
"Nri.Ui.Button.V8",
|
"Nri.Ui.Button.V8",
|
||||||
"Nri.Ui.Button.V9",
|
"Nri.Ui.Button.V9",
|
||||||
|
"Nri.Ui.Button.V10",
|
||||||
"Nri.Ui.Callout.V1",
|
"Nri.Ui.Callout.V1",
|
||||||
"Nri.Ui.Checkbox.V3",
|
"Nri.Ui.Checkbox.V3",
|
||||||
"Nri.Ui.Checkbox.V4",
|
"Nri.Ui.Checkbox.V4",
|
||||||
@ -73,6 +74,7 @@
|
|||||||
"Nri.Ui.SegmentedControl.V8",
|
"Nri.Ui.SegmentedControl.V8",
|
||||||
"Nri.Ui.Select.V5",
|
"Nri.Ui.Select.V5",
|
||||||
"Nri.Ui.Select.V6",
|
"Nri.Ui.Select.V6",
|
||||||
|
"Nri.Ui.Select.V7",
|
||||||
"Nri.Ui.Slide.V1",
|
"Nri.Ui.Slide.V1",
|
||||||
"Nri.Ui.SlideModal.V1",
|
"Nri.Ui.SlideModal.V1",
|
||||||
"Nri.Ui.SlideModal.V2",
|
"Nri.Ui.SlideModal.V2",
|
@ -4,6 +4,11 @@ module Nri.Ui.BannerAlert.V6 exposing (alert, error, neutral, success)
|
|||||||
|
|
||||||
@docs alert, error, neutral, success
|
@docs alert, error, neutral, success
|
||||||
|
|
||||||
|
|
||||||
|
# Post-release patches
|
||||||
|
|
||||||
|
- adjusts link styles
|
||||||
|
|
||||||
Changes from V5:
|
Changes from V5:
|
||||||
|
|
||||||
- takes HTML rather than BannerContent
|
- takes HTML rather than BannerContent
|
||||||
@ -341,5 +346,14 @@ notification =
|
|||||||
, Css.lineHeight (Css.px 27)
|
, Css.lineHeight (Css.px 27)
|
||||||
, Css.maxWidth (Css.px 600)
|
, Css.maxWidth (Css.px 600)
|
||||||
, Nri.Ui.Fonts.V1.baseFont
|
, Nri.Ui.Fonts.V1.baseFont
|
||||||
|
, Css.Global.descendants
|
||||||
|
[ Css.Global.a
|
||||||
|
[ Css.textDecoration Css.none
|
||||||
|
, Css.color Colors.azure
|
||||||
|
, Css.borderBottom3 (Css.px 1) Css.solid Colors.azure
|
||||||
|
, Css.visited
|
||||||
|
[ Css.color Colors.azure ]
|
||||||
|
]
|
||||||
|
]
|
||||||
]
|
]
|
||||||
[]
|
[]
|
967
lib/noredink-ui/src/Nri/Ui/Button/V10.elm
Normal file
967
lib/noredink-ui/src/Nri/Ui/Button/V10.elm
Normal file
@ -0,0 +1,967 @@
|
|||||||
|
module Nri.Ui.Button.V10 exposing
|
||||||
|
( button, link
|
||||||
|
, Attribute
|
||||||
|
, icon, custom, css
|
||||||
|
, onClick
|
||||||
|
, href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
|
||||||
|
, small, medium, large
|
||||||
|
, exactWidth, unboundedWidth, fillContainerWidth
|
||||||
|
, primary, secondary, danger, premium
|
||||||
|
, enabled, unfulfilled, disabled, error, loading, success
|
||||||
|
, delete
|
||||||
|
, toggleButton
|
||||||
|
)
|
||||||
|
|
||||||
|
{-|
|
||||||
|
|
||||||
|
|
||||||
|
# Changes from V9:
|
||||||
|
|
||||||
|
- Explicitly zeroes out all margin
|
||||||
|
- adds `css` helper
|
||||||
|
|
||||||
|
|
||||||
|
# Create a button or link
|
||||||
|
|
||||||
|
@docs button, link
|
||||||
|
@docs Attribute
|
||||||
|
@docs icon, custom, css
|
||||||
|
|
||||||
|
|
||||||
|
## Behavior
|
||||||
|
|
||||||
|
@docs onClick
|
||||||
|
@docs href, linkSpa, linkExternal, linkWithMethod, linkWithTracking, linkExternalWithTracking
|
||||||
|
|
||||||
|
|
||||||
|
## Sizing
|
||||||
|
|
||||||
|
@docs small, medium, large
|
||||||
|
@docs exactWidth, unboundedWidth, fillContainerWidth
|
||||||
|
|
||||||
|
|
||||||
|
## Change the color scheme
|
||||||
|
|
||||||
|
@docs primary, secondary, danger, premium
|
||||||
|
|
||||||
|
|
||||||
|
## Change the state (buttons only)
|
||||||
|
|
||||||
|
@docs enabled, unfulfilled, disabled, error, loading, success
|
||||||
|
|
||||||
|
|
||||||
|
# Commonly-used buttons
|
||||||
|
|
||||||
|
@docs delete
|
||||||
|
@docs toggleButton
|
||||||
|
|
||||||
|
-}
|
||||||
|
|
||||||
|
import Accessibility.Styled as Html exposing (Html)
|
||||||
|
import Accessibility.Styled.Role as Role
|
||||||
|
import Accessibility.Styled.Widget as Widget
|
||||||
|
import AttributeExtras exposing (targetBlank)
|
||||||
|
import Css exposing (Style)
|
||||||
|
import Css.Global
|
||||||
|
import EventExtras.Styled as EventExtras
|
||||||
|
import Html.Styled as Styled
|
||||||
|
import Html.Styled.Attributes as Attributes
|
||||||
|
import Html.Styled.Events as Events
|
||||||
|
import Json.Decode
|
||||||
|
import Markdown.Block
|
||||||
|
import Markdown.Inline
|
||||||
|
import Nri.Ui
|
||||||
|
import Nri.Ui.AssetPath as AssetPath exposing (Asset)
|
||||||
|
import Nri.Ui.Colors.Extra as ColorsExtra
|
||||||
|
import Nri.Ui.Colors.V1 as Colors
|
||||||
|
import Nri.Ui.Fonts.V1
|
||||||
|
import Nri.Ui.Html.Attributes.V2 as AttributesExtra
|
||||||
|
import Nri.Ui.Svg.V1 as NriSvg exposing (Svg)
|
||||||
|
import Svg
|
||||||
|
import Svg.Attributes
|
||||||
|
|
||||||
|
|
||||||
|
styledName : String -> String
|
||||||
|
styledName suffix =
|
||||||
|
"Nri-Ui-Button-V10-" ++ suffix
|
||||||
|
|
||||||
|
|
||||||
|
{-|
|
||||||
|
|
||||||
|
Button.button "My great button!"
|
||||||
|
[ Button.onClick ()
|
||||||
|
, Button.enabled
|
||||||
|
]
|
||||||
|
|
||||||
|
By default, the button is enabled, Medium sized, with primary colors, and an unbounded width.
|
||||||
|
|
||||||
|
-}
|
||||||
|
button : String -> List (Attribute msg) -> Html msg
|
||||||
|
button name attributes =
|
||||||
|
(label name :: attributes)
|
||||||
|
|> List.foldl (\(Attribute attribute) b -> attribute b) build
|
||||||
|
|> renderButton
|
||||||
|
|
||||||
|
|
||||||
|
{-|
|
||||||
|
|
||||||
|
Button.link "My great link!"
|
||||||
|
[ Button.href "My href"
|
||||||
|
, Button.secondary
|
||||||
|
]
|
||||||
|
|
||||||
|
By default, the link is Medium sized, with primary colors, and an unbounded width.
|
||||||
|
|
||||||
|
-}
|
||||||
|
link : String -> List (Attribute msg) -> Html msg
|
||||||
|
link name attributes =
|
||||||
|
(label name :: attributes)
|
||||||
|
|> List.foldl (\(Attribute attribute) l -> attribute l) build
|
||||||
|
|> renderLink
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
label : String -> Attribute msg
|
||||||
|
label label_ =
|
||||||
|
set (\attributes -> { attributes | label = label_ })
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
icon : Svg -> Attribute msg
|
||||||
|
icon icon_ =
|
||||||
|
set (\attributes -> { attributes | icon = Just icon_ })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Use this helper to add custom attributes.
|
||||||
|
|
||||||
|
Do NOT use this helper to add css styles, as they may not be applied the way
|
||||||
|
you want/expect if underlying Button styles change.
|
||||||
|
Instead, please use the `css` helper.
|
||||||
|
|
||||||
|
-}
|
||||||
|
custom : List (Html.Attribute msg) -> Attribute msg
|
||||||
|
custom attributes =
|
||||||
|
set
|
||||||
|
(\config ->
|
||||||
|
{ config
|
||||||
|
| customAttributes = List.append config.customAttributes attributes
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
css : List Style -> Attribute msg
|
||||||
|
css styles =
|
||||||
|
set
|
||||||
|
(\config ->
|
||||||
|
{ config
|
||||||
|
| customStyles = List.append config.customStyles styles
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- LINKING, CLICKING, and TRACKING BEHAVIOR
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
onClick : msg -> Attribute msg
|
||||||
|
onClick msg =
|
||||||
|
set (\attributes -> { attributes | onClick = Just msg })
|
||||||
|
|
||||||
|
|
||||||
|
type Link
|
||||||
|
= Default
|
||||||
|
| WithTracking
|
||||||
|
| SinglePageApp
|
||||||
|
| WithMethod String
|
||||||
|
| External
|
||||||
|
| ExternalWithTracking
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
href : String -> Attribute msg
|
||||||
|
href url =
|
||||||
|
set (\attributes -> { attributes | url = url })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Use this link for routing within a single page app.
|
||||||
|
|
||||||
|
This will make a normal <a> tag, but change the Events.onClick behavior to avoid reloading the page.
|
||||||
|
|
||||||
|
See <https://github.com/elm-lang/html/issues/110> for details on this implementation.
|
||||||
|
|
||||||
|
-}
|
||||||
|
linkSpa : String -> Attribute msg
|
||||||
|
linkSpa url =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes
|
||||||
|
| linkType = SinglePageApp
|
||||||
|
, url = url
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Wrap some text so it looks like a button, but actually is wrapped in an anchor to
|
||||||
|
some url, and it's an HTTP request (Rails includes JS to make this use the given HTTP method)
|
||||||
|
-}
|
||||||
|
linkWithMethod : { method : String, url : String } -> Attribute msg
|
||||||
|
linkWithMethod { method, url } =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes
|
||||||
|
| linkType = WithMethod method
|
||||||
|
, url = url
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Wrap some text so it looks like a button, but actually is wrapped in an anchor to some url.
|
||||||
|
This should only take in messages that result in a Msg that triggers Analytics.trackAndRedirect.
|
||||||
|
For buttons that trigger other effects on the page, please use Nri.Button.button instead.
|
||||||
|
-}
|
||||||
|
linkWithTracking : { track : msg, url : String } -> Attribute msg
|
||||||
|
linkWithTracking { track, url } =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes
|
||||||
|
| linkType = WithTracking
|
||||||
|
, url = url
|
||||||
|
, onClick = Just track
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Wrap some text so it looks like a button, but actually is wrapped in an anchor to
|
||||||
|
some url and have it open to an external site
|
||||||
|
-}
|
||||||
|
linkExternal : String -> Attribute msg
|
||||||
|
linkExternal url =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes
|
||||||
|
| linkType = External
|
||||||
|
, url = url
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| Wrap some text so it looks like a button, but actually is wrapped in an anchor to some url and have it open to an external site.
|
||||||
|
-}
|
||||||
|
linkExternalWithTracking : { track : msg, url : String } -> Attribute msg
|
||||||
|
linkExternalWithTracking { track, url } =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes
|
||||||
|
| linkType = ExternalWithTracking
|
||||||
|
, url = url
|
||||||
|
, onClick = Just track
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- BUTTON SIZING
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
small : Attribute msg
|
||||||
|
small =
|
||||||
|
set (\attributes -> { attributes | size = Small })
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
medium : Attribute msg
|
||||||
|
medium =
|
||||||
|
set (\attributes -> { attributes | size = Medium })
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
large : Attribute msg
|
||||||
|
large =
|
||||||
|
set (\attributes -> { attributes | size = Large })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- BUTTON WIDTH
|
||||||
|
|
||||||
|
|
||||||
|
type ButtonWidth
|
||||||
|
= WidthExact Int
|
||||||
|
| WidthUnbounded
|
||||||
|
| WidthFillContainer
|
||||||
|
|
||||||
|
|
||||||
|
{-| Sizes for buttons and links that have button classes
|
||||||
|
-}
|
||||||
|
type ButtonSize
|
||||||
|
= Small
|
||||||
|
| Medium
|
||||||
|
| Large
|
||||||
|
|
||||||
|
|
||||||
|
{-| Define a size in `px` for the button's total width.
|
||||||
|
-}
|
||||||
|
exactWidth : Int -> Attribute msg
|
||||||
|
exactWidth inPx =
|
||||||
|
set (\attributes -> { attributes | width = WidthExact inPx })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Leave the maxiumum width unbounded (there is a minimum width).
|
||||||
|
-}
|
||||||
|
unboundedWidth : Attribute msg
|
||||||
|
unboundedWidth =
|
||||||
|
set (\attributes -> { attributes | width = WidthUnbounded })
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
fillContainerWidth : Attribute msg
|
||||||
|
fillContainerWidth =
|
||||||
|
set (\attributes -> { attributes | width = WidthFillContainer })
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- COLOR SCHEMES
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
primary : Attribute msg
|
||||||
|
primary =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes | style = primaryColors }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
secondary : Attribute msg
|
||||||
|
secondary =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes | style = secondaryColors }
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
danger : Attribute msg
|
||||||
|
danger =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes
|
||||||
|
| style =
|
||||||
|
{ background = Colors.red
|
||||||
|
, hover = Colors.redDark
|
||||||
|
, text = Colors.white
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.redDark
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
premium : Attribute msg
|
||||||
|
premium =
|
||||||
|
set
|
||||||
|
(\attributes ->
|
||||||
|
{ attributes
|
||||||
|
| style =
|
||||||
|
{ background = Colors.yellow
|
||||||
|
, hover = Colors.ochre
|
||||||
|
, text = Colors.navy
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.ochre
|
||||||
|
}
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- BUTTON STATE
|
||||||
|
|
||||||
|
|
||||||
|
type ButtonState
|
||||||
|
= Enabled
|
||||||
|
| Unfulfilled
|
||||||
|
| Disabled
|
||||||
|
| Error
|
||||||
|
| Loading
|
||||||
|
| Success
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
enabled : Attribute msg
|
||||||
|
enabled =
|
||||||
|
set (\attributes -> { attributes | state = Enabled })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Shows inactive styles.
|
||||||
|
-}
|
||||||
|
unfulfilled : Attribute msg
|
||||||
|
unfulfilled =
|
||||||
|
set (\attributes -> { attributes | state = Unfulfilled })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Shows inactive styling. If a button, this attribute will disable it.
|
||||||
|
-}
|
||||||
|
disabled : Attribute msg
|
||||||
|
disabled =
|
||||||
|
set (\attributes -> { attributes | state = Disabled })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Shows error styling. If a button, this attribute will disable it.
|
||||||
|
-}
|
||||||
|
error : Attribute msg
|
||||||
|
error =
|
||||||
|
set (\attributes -> { attributes | state = Error })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Shows loading styling. If a button, this attribute will disable it.
|
||||||
|
-}
|
||||||
|
loading : Attribute msg
|
||||||
|
loading =
|
||||||
|
set (\attributes -> { attributes | state = Loading })
|
||||||
|
|
||||||
|
|
||||||
|
{-| Shows success styling. If a button, this attribute will disable it.
|
||||||
|
-}
|
||||||
|
success : Attribute msg
|
||||||
|
success =
|
||||||
|
set (\attributes -> { attributes | state = Success })
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
type Attribute msg
|
||||||
|
= Attribute (ButtonOrLink msg -> ButtonOrLink msg)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- INTERNALS
|
||||||
|
|
||||||
|
|
||||||
|
set :
|
||||||
|
(ButtonOrLinkAttributes msg -> ButtonOrLinkAttributes msg)
|
||||||
|
-> Attribute msg
|
||||||
|
set with =
|
||||||
|
Attribute (\(ButtonOrLink config) -> ButtonOrLink (with config))
|
||||||
|
|
||||||
|
|
||||||
|
build : ButtonOrLink msg
|
||||||
|
build =
|
||||||
|
ButtonOrLink
|
||||||
|
{ onClick = Nothing
|
||||||
|
, url = "#"
|
||||||
|
, linkType = Default
|
||||||
|
, size = Medium
|
||||||
|
, style = primaryColors
|
||||||
|
, width = WidthUnbounded
|
||||||
|
, label = ""
|
||||||
|
, state = Enabled
|
||||||
|
, icon = Nothing
|
||||||
|
, customAttributes = []
|
||||||
|
, customStyles = []
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
type ButtonOrLink msg
|
||||||
|
= ButtonOrLink (ButtonOrLinkAttributes msg)
|
||||||
|
|
||||||
|
|
||||||
|
type alias ButtonOrLinkAttributes msg =
|
||||||
|
{ onClick : Maybe msg
|
||||||
|
, url : String
|
||||||
|
, linkType : Link
|
||||||
|
, size : ButtonSize
|
||||||
|
, style : ColorPalette
|
||||||
|
, width : ButtonWidth
|
||||||
|
, label : String
|
||||||
|
, state : ButtonState
|
||||||
|
, icon : Maybe Svg
|
||||||
|
, customAttributes : List (Html.Attribute msg)
|
||||||
|
, customStyles : List Style
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
renderButton : ButtonOrLink msg -> Html msg
|
||||||
|
renderButton ((ButtonOrLink config) as button_) =
|
||||||
|
let
|
||||||
|
buttonStyle_ =
|
||||||
|
getColorPalette button_
|
||||||
|
|
||||||
|
isDisabled =
|
||||||
|
case config.state of
|
||||||
|
Enabled ->
|
||||||
|
False
|
||||||
|
|
||||||
|
Disabled ->
|
||||||
|
True
|
||||||
|
|
||||||
|
Error ->
|
||||||
|
True
|
||||||
|
|
||||||
|
Unfulfilled ->
|
||||||
|
False
|
||||||
|
|
||||||
|
Loading ->
|
||||||
|
True
|
||||||
|
|
||||||
|
Success ->
|
||||||
|
True
|
||||||
|
in
|
||||||
|
Nri.Ui.styled Html.button
|
||||||
|
(styledName "customButton")
|
||||||
|
[ buttonStyles config.size config.width buttonStyle_ config.customStyles ]
|
||||||
|
((Maybe.map Events.onClick config.onClick
|
||||||
|
|> Maybe.withDefault AttributesExtra.none
|
||||||
|
)
|
||||||
|
:: Attributes.disabled isDisabled
|
||||||
|
:: Attributes.type_ "button"
|
||||||
|
:: config.customAttributes
|
||||||
|
)
|
||||||
|
[ viewLabel config.icon config.label ]
|
||||||
|
|
||||||
|
|
||||||
|
renderLink : ButtonOrLink msg -> Html msg
|
||||||
|
renderLink ((ButtonOrLink config) as link_) =
|
||||||
|
let
|
||||||
|
colorPalette =
|
||||||
|
getColorPalette link_
|
||||||
|
|
||||||
|
linkBase linkFunctionName extraAttrs =
|
||||||
|
Nri.Ui.styled Styled.a
|
||||||
|
(styledName linkFunctionName)
|
||||||
|
[ buttonStyles config.size config.width colorPalette config.customStyles ]
|
||||||
|
(Attributes.href config.url :: extraAttrs)
|
||||||
|
[ viewLabel config.icon config.label ]
|
||||||
|
in
|
||||||
|
case config.linkType of
|
||||||
|
Default ->
|
||||||
|
linkBase "link"
|
||||||
|
(Attributes.target "_self" :: config.customAttributes)
|
||||||
|
|
||||||
|
SinglePageApp ->
|
||||||
|
linkBase "linkSpa"
|
||||||
|
((Maybe.map EventExtras.onClickPreventDefaultForLinkWithHref config.onClick
|
||||||
|
|> Maybe.withDefault AttributesExtra.none
|
||||||
|
)
|
||||||
|
:: config.customAttributes
|
||||||
|
)
|
||||||
|
|
||||||
|
WithMethod method ->
|
||||||
|
linkBase "linkWithMethod"
|
||||||
|
(Attributes.attribute "data-method" method
|
||||||
|
:: config.customAttributes
|
||||||
|
)
|
||||||
|
|
||||||
|
WithTracking ->
|
||||||
|
linkBase
|
||||||
|
"linkWithTracking"
|
||||||
|
((Maybe.map
|
||||||
|
(\msg ->
|
||||||
|
Events.preventDefaultOn "click"
|
||||||
|
(Json.Decode.succeed ( msg, True ))
|
||||||
|
)
|
||||||
|
config.onClick
|
||||||
|
|> Maybe.withDefault AttributesExtra.none
|
||||||
|
)
|
||||||
|
:: config.customAttributes
|
||||||
|
)
|
||||||
|
|
||||||
|
External ->
|
||||||
|
linkBase "linkExternal"
|
||||||
|
(targetBlank ++ config.customAttributes)
|
||||||
|
|
||||||
|
ExternalWithTracking ->
|
||||||
|
linkBase "linkExternalWithTracking"
|
||||||
|
(List.concat
|
||||||
|
[ targetBlank
|
||||||
|
, config.onClick
|
||||||
|
|> Maybe.map
|
||||||
|
(\onClickMsg ->
|
||||||
|
[ Events.onClick onClickMsg
|
||||||
|
, Events.on "auxclick" (Json.Decode.succeed onClickMsg)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|> Maybe.withDefault []
|
||||||
|
, config.customAttributes
|
||||||
|
]
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- DELETE BUTTON
|
||||||
|
|
||||||
|
|
||||||
|
{-| A delete button (blue X)
|
||||||
|
-}
|
||||||
|
delete : { label : String, onClick : msg } -> Html msg
|
||||||
|
delete config =
|
||||||
|
Nri.Ui.styled Html.button
|
||||||
|
(styledName "delete")
|
||||||
|
[ Css.display Css.inlineBlock
|
||||||
|
, Css.backgroundRepeat Css.noRepeat
|
||||||
|
, Css.backgroundColor Css.transparent
|
||||||
|
, Css.backgroundPosition Css.center
|
||||||
|
, Css.backgroundSize Css.contain
|
||||||
|
, Css.border Css.zero
|
||||||
|
, Css.width (Css.px 15)
|
||||||
|
, Css.height (Css.px 15)
|
||||||
|
, Css.padding Css.zero
|
||||||
|
, Css.margin2 Css.zero (Css.px 6)
|
||||||
|
, Css.cursor Css.pointer
|
||||||
|
, Css.color Colors.azure
|
||||||
|
]
|
||||||
|
[ Events.onClick config.onClick
|
||||||
|
, Attributes.type_ "button"
|
||||||
|
, -- reference: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Labeling_buttons
|
||||||
|
Widget.label config.label
|
||||||
|
]
|
||||||
|
[ Svg.svg [ Svg.Attributes.viewBox "0 0 25 25" ]
|
||||||
|
[ Svg.title [] [ Styled.toUnstyled (Styled.text "Delete") ]
|
||||||
|
, Svg.path
|
||||||
|
[ Svg.Attributes.fill "#146aff" -- TODO: this should be azure, but css colors aren't extractable afaik
|
||||||
|
, Svg.Attributes.d "M1.067 6.015c-1.423-1.422-1.423-3.526 0-4.948 1.422-1.423 3.526-1.423 4.948 0l6.371 6.37 6.371-6.37c1.422-1.423 3.783-1.423 5.176 0 1.423 1.422 1.423 3.782 0 5.176l-6.37 6.37 6.37 6.372c1.423 1.422 1.423 3.526 0 4.948-1.422 1.423-3.526 1.423-4.948 0l-6.371-6.37-6.371 6.37c-1.422 1.423-3.783 1.423-5.176 0-1.423-1.422-1.423-3.782 0-5.176l6.37-6.143-6.37-6.599z"
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
|> Styled.fromUnstyled
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- TOGGLE BUTTON
|
||||||
|
|
||||||
|
|
||||||
|
{-| A button that can be toggled into a pressed state and back again.
|
||||||
|
-}
|
||||||
|
toggleButton :
|
||||||
|
{ label : String
|
||||||
|
, onSelect : msg
|
||||||
|
, onDeselect : msg
|
||||||
|
, pressed : Bool
|
||||||
|
}
|
||||||
|
-> Html msg
|
||||||
|
toggleButton config =
|
||||||
|
let
|
||||||
|
toggledStyles =
|
||||||
|
if config.pressed then
|
||||||
|
Css.batch
|
||||||
|
[ Css.color Colors.gray20
|
||||||
|
, Css.backgroundColor Colors.glacier
|
||||||
|
, Css.boxShadow5 Css.inset Css.zero (Css.px 3) Css.zero (ColorsExtra.withAlpha 0.2 Colors.gray20)
|
||||||
|
, Css.border3 (Css.px 1) Css.solid Colors.azure
|
||||||
|
, Css.fontWeight Css.bold
|
||||||
|
]
|
||||||
|
|
||||||
|
else
|
||||||
|
Css.batch
|
||||||
|
[]
|
||||||
|
in
|
||||||
|
Nri.Ui.styled Html.button
|
||||||
|
(styledName "toggleButton")
|
||||||
|
[ buttonStyles Medium WidthUnbounded secondaryColors []
|
||||||
|
, toggledStyles
|
||||||
|
]
|
||||||
|
[ Events.onClick
|
||||||
|
(if config.pressed then
|
||||||
|
config.onDeselect
|
||||||
|
|
||||||
|
else
|
||||||
|
config.onSelect
|
||||||
|
)
|
||||||
|
, Widget.pressed <| Just config.pressed
|
||||||
|
|
||||||
|
-- reference: https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA/ARIA_Techniques/Using_the_button_role#Labeling_buttons
|
||||||
|
, Role.button
|
||||||
|
|
||||||
|
-- Note: setting type: 'button' removes the default behavior of submit
|
||||||
|
-- equivalent to preventDefaultBehavior = false
|
||||||
|
-- https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button#attr-name
|
||||||
|
, Attributes.type_ "button"
|
||||||
|
]
|
||||||
|
[ viewLabel Nothing config.label ]
|
||||||
|
|
||||||
|
|
||||||
|
buttonStyles : ButtonSize -> ButtonWidth -> ColorPalette -> List Style -> Style
|
||||||
|
buttonStyles size width colors customStyles =
|
||||||
|
Css.batch
|
||||||
|
[ buttonStyle
|
||||||
|
, sizeStyle size width
|
||||||
|
, colorStyle colors
|
||||||
|
, Css.batch customStyles
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
viewLabel : Maybe Svg -> String -> Html msg
|
||||||
|
viewLabel maybeSvg label_ =
|
||||||
|
Nri.Ui.styled Html.span
|
||||||
|
"button-label-span"
|
||||||
|
[ Css.overflow Css.hidden -- Keep scrollbars out of our button
|
||||||
|
, Css.overflowWrap Css.breakWord -- Ensure that words that exceed the button width break instead of disappearing
|
||||||
|
, Css.padding2 (Css.px 2) Css.zero -- Without a bit of bottom padding, text that extends below the baseline, like "g" gets cut off
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
(case maybeSvg of
|
||||||
|
Nothing ->
|
||||||
|
renderMarkdown label_
|
||||||
|
|
||||||
|
Just svg ->
|
||||||
|
NriSvg.toHtml svg :: renderMarkdown label_
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
renderMarkdown : String -> List (Html msg)
|
||||||
|
renderMarkdown markdown =
|
||||||
|
case Markdown.Block.parse Nothing markdown of
|
||||||
|
-- It seems to be always first wrapped in a `Paragraph` and never directly a `PlainInline`
|
||||||
|
[ Markdown.Block.Paragraph _ inlines ] ->
|
||||||
|
List.map (Markdown.Inline.toHtml >> Styled.fromUnstyled) inlines
|
||||||
|
|
||||||
|
_ ->
|
||||||
|
[ Html.text markdown ]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- STYLES
|
||||||
|
|
||||||
|
|
||||||
|
buttonStyle : Style
|
||||||
|
buttonStyle =
|
||||||
|
Css.batch
|
||||||
|
[ Css.cursor Css.pointer
|
||||||
|
, -- Specifying the font can and should go away after bootstrap is removed from application.css
|
||||||
|
Nri.Ui.Fonts.V1.baseFont
|
||||||
|
, Css.textOverflow Css.ellipsis
|
||||||
|
, Css.overflow Css.hidden
|
||||||
|
, Css.textDecoration Css.none
|
||||||
|
, Css.backgroundImage Css.none
|
||||||
|
, Css.textShadow Css.none
|
||||||
|
, Css.property "transition" "background-color 0.2s, color 0.2s, box-shadow 0.2s, border 0.2s, border-width 0s"
|
||||||
|
, Css.boxShadow Css.none
|
||||||
|
, Css.border Css.zero
|
||||||
|
, Css.margin Css.zero
|
||||||
|
, Css.hover [ Css.textDecoration Css.none ]
|
||||||
|
, Css.disabled [ Css.cursor Css.notAllowed ]
|
||||||
|
, Css.display Css.inlineFlex
|
||||||
|
, Css.alignItems Css.center
|
||||||
|
, Css.justifyContent Css.center
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-- COLORS
|
||||||
|
|
||||||
|
|
||||||
|
type alias ColorPalette =
|
||||||
|
{ background : Css.Color
|
||||||
|
, hover : Css.Color
|
||||||
|
, text : Css.Color
|
||||||
|
, border : Maybe Css.Color
|
||||||
|
, shadow : Css.Color
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
primaryColors : ColorPalette
|
||||||
|
primaryColors =
|
||||||
|
{ background = Colors.azure
|
||||||
|
, hover = Colors.azureDark
|
||||||
|
, text = Colors.white
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.azureDark
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
secondaryColors : ColorPalette
|
||||||
|
secondaryColors =
|
||||||
|
{ background = Colors.white
|
||||||
|
, hover = Colors.glacier
|
||||||
|
, text = Colors.azure
|
||||||
|
, border = Just <| Colors.azure
|
||||||
|
, shadow = Colors.azure
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getColorPalette : ButtonOrLink msg -> ColorPalette
|
||||||
|
getColorPalette (ButtonOrLink config) =
|
||||||
|
case config.state of
|
||||||
|
Enabled ->
|
||||||
|
config.style
|
||||||
|
|
||||||
|
Disabled ->
|
||||||
|
{ background = Colors.gray92
|
||||||
|
, hover = Colors.gray92
|
||||||
|
, text = Colors.gray45
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.gray92
|
||||||
|
}
|
||||||
|
|
||||||
|
Error ->
|
||||||
|
{ background = Colors.purple
|
||||||
|
, hover = Colors.purple
|
||||||
|
, text = Colors.white
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.purple
|
||||||
|
}
|
||||||
|
|
||||||
|
Unfulfilled ->
|
||||||
|
{ background = Colors.gray92
|
||||||
|
, hover = Colors.gray92
|
||||||
|
, text = Colors.gray45
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.gray92
|
||||||
|
}
|
||||||
|
|
||||||
|
Loading ->
|
||||||
|
{ background = Colors.glacier
|
||||||
|
, hover = Colors.glacier
|
||||||
|
, text = Colors.navy
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.glacier
|
||||||
|
}
|
||||||
|
|
||||||
|
Success ->
|
||||||
|
{ background = Colors.greenDark
|
||||||
|
, hover = Colors.greenDark
|
||||||
|
, text = Colors.white
|
||||||
|
, border = Nothing
|
||||||
|
, shadow = Colors.greenDark
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
colorStyle : ColorPalette -> Style
|
||||||
|
colorStyle colorPalette =
|
||||||
|
Css.batch
|
||||||
|
[ Css.color colorPalette.text
|
||||||
|
, Css.backgroundColor colorPalette.background
|
||||||
|
, Css.fontWeight (Css.int 700)
|
||||||
|
, Css.textAlign Css.center
|
||||||
|
, case colorPalette.border of
|
||||||
|
Nothing ->
|
||||||
|
Css.borderStyle Css.none
|
||||||
|
|
||||||
|
Just color ->
|
||||||
|
Css.batch
|
||||||
|
[ Css.borderColor color
|
||||||
|
, Css.borderStyle Css.solid
|
||||||
|
]
|
||||||
|
, Css.borderBottomStyle Css.solid
|
||||||
|
, Css.borderBottomColor colorPalette.shadow
|
||||||
|
, Css.fontStyle Css.normal
|
||||||
|
, Css.hover
|
||||||
|
[ Css.color colorPalette.text
|
||||||
|
, Css.backgroundColor colorPalette.hover
|
||||||
|
, Css.disabled [ Css.backgroundColor colorPalette.background ]
|
||||||
|
]
|
||||||
|
, Css.visited [ Css.color colorPalette.text ]
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
sizeStyle : ButtonSize -> ButtonWidth -> Style
|
||||||
|
sizeStyle size width =
|
||||||
|
let
|
||||||
|
config =
|
||||||
|
case size of
|
||||||
|
Small ->
|
||||||
|
{ fontSize = 15
|
||||||
|
, height = 36
|
||||||
|
, imageHeight = 15
|
||||||
|
, shadowHeight = 2
|
||||||
|
, minWidth = 75
|
||||||
|
}
|
||||||
|
|
||||||
|
Medium ->
|
||||||
|
{ fontSize = 17
|
||||||
|
, height = 45
|
||||||
|
, imageHeight = 15
|
||||||
|
, shadowHeight = 3
|
||||||
|
, minWidth = 100
|
||||||
|
}
|
||||||
|
|
||||||
|
Large ->
|
||||||
|
{ fontSize = 20
|
||||||
|
, height = 56
|
||||||
|
, imageHeight = 20
|
||||||
|
, shadowHeight = 4
|
||||||
|
, minWidth = 200
|
||||||
|
}
|
||||||
|
|
||||||
|
sizingAttributes =
|
||||||
|
let
|
||||||
|
verticalPaddingPx =
|
||||||
|
2
|
||||||
|
in
|
||||||
|
[ Css.minHeight (Css.px config.height)
|
||||||
|
, Css.paddingTop (Css.px verticalPaddingPx)
|
||||||
|
, Css.paddingBottom (Css.px verticalPaddingPx)
|
||||||
|
]
|
||||||
|
|
||||||
|
widthAttributes =
|
||||||
|
case width of
|
||||||
|
WidthExact pxWidth ->
|
||||||
|
[ Css.maxWidth (Css.pct 100)
|
||||||
|
, Css.width (Css.px <| toFloat pxWidth)
|
||||||
|
, Css.paddingRight (Css.px 4)
|
||||||
|
, Css.paddingLeft (Css.px 4)
|
||||||
|
]
|
||||||
|
|
||||||
|
WidthUnbounded ->
|
||||||
|
[ Css.paddingLeft (Css.px 16)
|
||||||
|
, Css.paddingRight (Css.px 16)
|
||||||
|
, Css.minWidth (Css.px config.minWidth)
|
||||||
|
]
|
||||||
|
|
||||||
|
WidthFillContainer ->
|
||||||
|
[ Css.paddingLeft (Css.px 16)
|
||||||
|
, Css.paddingRight (Css.px 16)
|
||||||
|
, Css.minWidth (Css.px config.minWidth)
|
||||||
|
, Css.width (Css.pct 100)
|
||||||
|
]
|
||||||
|
|
||||||
|
lineHeightPx =
|
||||||
|
case size of
|
||||||
|
Small ->
|
||||||
|
15
|
||||||
|
|
||||||
|
Medium ->
|
||||||
|
19
|
||||||
|
|
||||||
|
Large ->
|
||||||
|
22
|
||||||
|
in
|
||||||
|
Css.batch
|
||||||
|
[ Css.fontSize (Css.px config.fontSize)
|
||||||
|
, Css.borderRadius (Css.px 8)
|
||||||
|
, Css.lineHeight (Css.px lineHeightPx)
|
||||||
|
, Css.boxSizing Css.borderBox
|
||||||
|
, Css.borderWidth (Css.px 1)
|
||||||
|
, Css.borderBottomWidth (Css.px config.shadowHeight)
|
||||||
|
, Css.batch sizingAttributes
|
||||||
|
, Css.batch widthAttributes
|
||||||
|
, Css.Global.descendants
|
||||||
|
[ Css.Global.img
|
||||||
|
[ Css.height (Css.px config.imageHeight)
|
||||||
|
, Css.marginRight (Css.px <| config.imageHeight / 6)
|
||||||
|
, Css.position Css.relative
|
||||||
|
, Css.bottom (Css.px 2)
|
||||||
|
, Css.verticalAlign Css.middle
|
||||||
|
]
|
||||||
|
, Css.Global.svg
|
||||||
|
[ Css.height (Css.px config.imageHeight) |> Css.important
|
||||||
|
, Css.width (Css.px config.imageHeight) |> Css.important
|
||||||
|
, Css.marginRight (Css.px <| config.imageHeight / 6)
|
||||||
|
, Css.position Css.relative
|
||||||
|
, Css.bottom (Css.px 2)
|
||||||
|
, Css.verticalAlign Css.middle
|
||||||
|
]
|
||||||
|
, Css.Global.svg
|
||||||
|
[ Css.important <| Css.height (Css.px config.imageHeight)
|
||||||
|
, Css.important <| Css.width Css.auto
|
||||||
|
, Css.maxWidth (Css.px (config.imageHeight * 1.25))
|
||||||
|
, Css.paddingRight (Css.px <| config.imageHeight / 6)
|
||||||
|
, Css.position Css.relative
|
||||||
|
, Css.bottom (Css.px 2)
|
||||||
|
, Css.verticalAlign Css.middle
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
@ -557,9 +557,14 @@ renderLink ((ButtonOrLink config) as link_) =
|
|||||||
linkBase "linkExternalWithTracking"
|
linkBase "linkExternalWithTracking"
|
||||||
(List.concat
|
(List.concat
|
||||||
[ targetBlank
|
[ targetBlank
|
||||||
, [ Maybe.map EventExtras.onClickForLinkWithHref config.onClick
|
, config.onClick
|
||||||
|> Maybe.withDefault AttributesExtra.none
|
|> Maybe.map
|
||||||
|
(\onClickMsg ->
|
||||||
|
[ Events.onClick onClickMsg
|
||||||
|
, Events.on "auxclick" (Json.Decode.succeed onClickMsg)
|
||||||
]
|
]
|
||||||
|
)
|
||||||
|
|> Maybe.withDefault []
|
||||||
, config.customAttributes
|
, config.customAttributes
|
||||||
]
|
]
|
||||||
)
|
)
|
@ -5,12 +5,18 @@ module Nri.Ui.ClickableText.V3 exposing
|
|||||||
, small, medium, large
|
, small, medium, large
|
||||||
, href, onClick
|
, href, onClick
|
||||||
, icon
|
, icon
|
||||||
, custom
|
, custom, css
|
||||||
)
|
)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
|
|
||||||
|
# Post-release patches
|
||||||
|
|
||||||
|
- adds `css` helper
|
||||||
|
- add bottom border on hover instead of text decoration
|
||||||
|
|
||||||
|
|
||||||
# Changes from V2
|
# Changes from V2
|
||||||
|
|
||||||
- Changes API to be attributes-based rather than config-based
|
- Changes API to be attributes-based rather than config-based
|
||||||
@ -43,11 +49,11 @@ HTML `<a>` elements and are created here with `*Link` functions.
|
|||||||
@docs small, medium, large
|
@docs small, medium, large
|
||||||
@docs href, onClick
|
@docs href, onClick
|
||||||
@docs icon
|
@docs icon
|
||||||
@docs custom
|
@docs custom, css
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
import Css
|
import Css exposing (Style)
|
||||||
import Html.Styled as Html exposing (..)
|
import Html.Styled as Html exposing (..)
|
||||||
import Html.Styled.Attributes as Attributes
|
import Html.Styled.Attributes as Attributes
|
||||||
import Html.Styled.Events as Events
|
import Html.Styled.Events as Events
|
||||||
@ -93,7 +99,13 @@ icon icon_ =
|
|||||||
set (\attributes -> { attributes | icon = Just icon_ })
|
set (\attributes -> { attributes | icon = Just icon_ })
|
||||||
|
|
||||||
|
|
||||||
{-| -}
|
{-| Use this helper to add custom attributes.
|
||||||
|
|
||||||
|
Do NOT use this helper to add css styles, as they may not be applied the way
|
||||||
|
you want/expect if underlying Button styles change.
|
||||||
|
Instead, please use the `css` helper.
|
||||||
|
|
||||||
|
-}
|
||||||
custom : List (Html.Attribute msg) -> Attribute msg
|
custom : List (Html.Attribute msg) -> Attribute msg
|
||||||
custom attributes =
|
custom attributes =
|
||||||
set
|
set
|
||||||
@ -104,6 +116,17 @@ custom attributes =
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
css : List Style -> Attribute msg
|
||||||
|
css styles =
|
||||||
|
set
|
||||||
|
(\config ->
|
||||||
|
{ config
|
||||||
|
| customStyles = List.append config.customStyles styles
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
{-| -}
|
{-| -}
|
||||||
onClick : msg -> Attribute msg
|
onClick : msg -> Attribute msg
|
||||||
onClick msg =
|
onClick msg =
|
||||||
@ -130,7 +153,7 @@ button label_ attributes =
|
|||||||
in
|
in
|
||||||
Nri.Ui.styled Html.button
|
Nri.Ui.styled Html.button
|
||||||
(dataDescriptor "button")
|
(dataDescriptor "button")
|
||||||
clickableTextStyles
|
(clickableTextStyles ++ config.customStyles)
|
||||||
((Maybe.map Events.onClick config.onClick
|
((Maybe.map Events.onClick config.onClick
|
||||||
|> Maybe.withDefault AttributesExtra.none
|
|> Maybe.withDefault AttributesExtra.none
|
||||||
)
|
)
|
||||||
@ -153,7 +176,7 @@ link label_ attributes =
|
|||||||
in
|
in
|
||||||
Nri.Ui.styled Html.a
|
Nri.Ui.styled Html.a
|
||||||
(dataDescriptor "link")
|
(dataDescriptor "link")
|
||||||
clickableTextStyles
|
(clickableTextStyles ++ config.customStyles)
|
||||||
(Attributes.href config.url :: config.customAttributes)
|
(Attributes.href config.url :: config.customAttributes)
|
||||||
[ viewContent config ]
|
[ viewContent config ]
|
||||||
|
|
||||||
@ -215,7 +238,8 @@ clickableTextStyles =
|
|||||||
, Css.textAlign Css.left
|
, Css.textAlign Css.left
|
||||||
, Css.borderStyle Css.none
|
, Css.borderStyle Css.none
|
||||||
, Css.textDecoration Css.none
|
, Css.textDecoration Css.none
|
||||||
, Css.hover [ Css.textDecoration Css.underline ]
|
, Css.borderBottom3 (Css.px 1) Css.solid Css.transparent
|
||||||
|
, Css.hover [ Css.textDecoration Css.none, Css.borderBottom3 (Css.px 1) Css.solid Colors.azure ]
|
||||||
, Css.padding Css.zero
|
, Css.padding Css.zero
|
||||||
, Css.display Css.inlineBlock
|
, Css.display Css.inlineBlock
|
||||||
, Css.verticalAlign Css.textBottom
|
, Css.verticalAlign Css.textBottom
|
||||||
@ -251,6 +275,7 @@ type alias ClickableTextAttributes msg =
|
|||||||
, onClick : Maybe msg
|
, onClick : Maybe msg
|
||||||
, url : String
|
, url : String
|
||||||
, customAttributes : List (Html.Attribute msg)
|
, customAttributes : List (Html.Attribute msg)
|
||||||
|
, customStyles : List Style
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -262,6 +287,7 @@ defaults =
|
|||||||
, label = ""
|
, label = ""
|
||||||
, icon = Nothing
|
, icon = Nothing
|
||||||
, customAttributes = []
|
, customAttributes = []
|
||||||
|
, customStyles = []
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -35,7 +35,7 @@ label theme inError =
|
|||||||
batch
|
batch
|
||||||
[ backgroundColor white
|
[ backgroundColor white
|
||||||
, left (px 10)
|
, left (px 10)
|
||||||
, top (px 0)
|
, top (px 1)
|
||||||
, fontSize (px 12)
|
, fontSize (px 12)
|
||||||
, Nri.Ui.Fonts.V1.baseFont
|
, Nri.Ui.Fonts.V1.baseFont
|
||||||
, position absolute
|
, position absolute
|
||||||
@ -109,21 +109,21 @@ input theme isInError =
|
|||||||
, verticalAlign top
|
, verticalAlign top
|
||||||
, marginBottom zero
|
, marginBottom zero
|
||||||
, marginTop (px 9)
|
, marginTop (px 9)
|
||||||
, boxShadow6 inset zero (px 2) zero zero gray92
|
, boxShadow6 inset zero (px 3) zero zero gray92
|
||||||
, property "transition" "all 0.4s ease"
|
, property "transition" "all 0.4s ease"
|
||||||
, boxSizing borderBox
|
, boxSizing borderBox
|
||||||
, focus
|
, focus
|
||||||
[ borderColor azure
|
[ borderColor azure
|
||||||
, outline none
|
, outline none
|
||||||
, boxShadow6 inset zero (px 2) zero zero glacier
|
, boxShadow6 inset zero (px 3) zero zero glacier
|
||||||
]
|
]
|
||||||
, if isInError then
|
, if isInError then
|
||||||
batch
|
batch
|
||||||
[ borderColor purple
|
[ borderColor purple
|
||||||
, boxShadow6 inset zero (px 2) zero zero purpleLight
|
, boxShadow6 inset zero (px 3) zero zero purpleLight
|
||||||
, focus
|
, focus
|
||||||
[ borderColor purple
|
[ borderColor purple
|
||||||
, boxShadow6 inset zero (px 2) zero zero purpleLight
|
, boxShadow6 inset zero (px 3) zero zero purpleLight
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
|
||||||
@ -137,7 +137,7 @@ input theme isInError =
|
|||||||
Standard ->
|
Standard ->
|
||||||
batch
|
batch
|
||||||
[ sharedStyles
|
[ sharedStyles
|
||||||
, padding2 inputPaddingVertical (px 14)
|
, padding2 inputPaddingVertical (px 15)
|
||||||
, fontSize (px 15)
|
, fontSize (px 15)
|
||||||
, Nri.Ui.Fonts.V1.baseFont
|
, Nri.Ui.Fonts.V1.baseFont
|
||||||
]
|
]
|
||||||
@ -173,7 +173,7 @@ input theme isInError =
|
|||||||
ContentCreation ->
|
ContentCreation ->
|
||||||
batch
|
batch
|
||||||
[ sharedStyles
|
[ sharedStyles
|
||||||
, padding2 inputPaddingVertical (px 14)
|
, padding2 inputPaddingVertical (px 15)
|
||||||
, fontSize (px 15)
|
, fontSize (px 15)
|
||||||
, Nri.Ui.Fonts.V1.baseFont
|
, Nri.Ui.Fonts.V1.baseFont
|
||||||
]
|
]
|
@ -1,12 +1,12 @@
|
|||||||
module Nri.Ui.Logo.V1 exposing
|
module Nri.Ui.Logo.V1 exposing
|
||||||
( noredink
|
( noredink
|
||||||
, facebook, twitter, clever
|
, facebook, twitter, clever, googleClassroom
|
||||||
)
|
)
|
||||||
|
|
||||||
{-|
|
{-|
|
||||||
|
|
||||||
@docs noredink
|
@docs noredink
|
||||||
@docs facebook, twitter, clever
|
@docs facebook, twitter, clever, googleClassroom
|
||||||
|
|
||||||
-}
|
-}
|
||||||
|
|
||||||
@ -101,3 +101,38 @@ twitter =
|
|||||||
[]
|
[]
|
||||||
]
|
]
|
||||||
|> Nri.Ui.Svg.V1.fromHtml
|
|> Nri.Ui.Svg.V1.fromHtml
|
||||||
|
|
||||||
|
|
||||||
|
{-| -}
|
||||||
|
googleClassroom : Nri.Ui.Svg.V1.Svg
|
||||||
|
googleClassroom =
|
||||||
|
Svg.svg
|
||||||
|
[ Attributes.width "100%"
|
||||||
|
, Attributes.height "100%"
|
||||||
|
, Attributes.fill "currentcolor"
|
||||||
|
, Attributes.viewBox "0 0 20 20"
|
||||||
|
]
|
||||||
|
[ Svg.g
|
||||||
|
[ Attributes.stroke "none"
|
||||||
|
, Attributes.strokeWidth "1"
|
||||||
|
, Attributes.fill "none"
|
||||||
|
, Attributes.fillRule "evenodd"
|
||||||
|
]
|
||||||
|
[ Svg.g [ Attributes.transform "translate(-302.000000, -217.000000)" ]
|
||||||
|
[ Svg.g [ Attributes.transform "translate(66.000000, 207.000000)" ]
|
||||||
|
[ Svg.g [ Attributes.transform "translate(224.000000, 0.000000)" ]
|
||||||
|
[ Svg.image
|
||||||
|
[ Attributes.x "12"
|
||||||
|
, Attributes.y "10"
|
||||||
|
, Attributes.width "20"
|
||||||
|
, Attributes.height "20"
|
||||||
|
, Attributes.xlinkHref
|
||||||
|
"data:image/png;base64,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"
|
||||||
|
]
|
||||||
|
[]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
]
|
||||||
|
|> Nri.Ui.Svg.V1.fromHtml
|
@ -14,7 +14,7 @@ module Nri.Ui.Modal.V6 exposing
|
|||||||
These changes have required major API changes. Be sure to wire up subscriptions!
|
These changes have required major API changes. Be sure to wire up subscriptions!
|
||||||
|
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Nri.Ui.Button.V9 as Button
|
import Nri.Ui.Button.V10 as Button
|
||||||
import Nri.Ui.Modal.V6 as Modal
|
import Nri.Ui.Modal.V6 as Modal
|
||||||
|
|
||||||
type Msg
|
type Msg
|
@ -17,7 +17,7 @@ module Nri.Ui.Modal.V7 exposing
|
|||||||
|
|
||||||
```
|
```
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Nri.Ui.Button.V9 as Button
|
import Nri.Ui.Button.V10 as Button
|
||||||
import Nri.Ui.Modal.V7 as Modal
|
import Nri.Ui.Modal.V7 as Modal
|
||||||
|
|
||||||
type Msg
|
type Msg
|
@ -18,7 +18,7 @@ module Nri.Ui.Modal.V8 exposing
|
|||||||
|
|
||||||
```
|
```
|
||||||
import Html.Styled exposing (..)
|
import Html.Styled exposing (..)
|
||||||
import Nri.Ui.Button.V9 as Button
|
import Nri.Ui.Button.V10 as Button
|
||||||
import Nri.Ui.Modal.V8 as Modal
|
import Nri.Ui.Modal.V8 as Modal
|
||||||
|
|
||||||
type Msg
|
type Msg
|
||||||
@ -441,7 +441,7 @@ closeButton wrapMsg focusableElementAttrs =
|
|||||||
-- make the hitspace extend all the way to the corner
|
-- make the hitspace extend all the way to the corner
|
||||||
, Css.width (Css.px 40)
|
, Css.width (Css.px 40)
|
||||||
, Css.height (Css.px 40)
|
, Css.height (Css.px 40)
|
||||||
, Css.padding4 (Css.px 20) (Css.px 20) (Css.px 2) Css.zero
|
, Css.padding4 (Css.px 20) (Css.px 20) Css.zero Css.zero
|
||||||
|
|
||||||
-- apply button styles
|
-- apply button styles
|
||||||
, Css.borderWidth Css.zero
|
, Css.borderWidth Css.zero
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user