Merge remote-tracking branch 'origin/master' into bat/focus-ring

This commit is contained in:
Tessa Kelly 2022-08-16 11:58:17 -07:00
commit 93f3f86a17
54 changed files with 817 additions and 124 deletions

1
bors.toml Normal file
View File

@ -0,0 +1 @@
status = ["tests"]

View File

@ -1,4 +1,5 @@
Nri.Ui.Accordion.V1,upgrade to V3
Nri.Ui.Checkbox.V5,upgrade to V6
Nri.Ui.Heading.V2,upgrade to V3
Nri.Ui.Menu.V1,upgrade to V3
Nri.Ui.SideNav.V3,upgrade to V4

1 Nri.Ui.Accordion.V1 upgrade to V3
2 Nri.Ui.Checkbox.V5 upgrade to V6
3 Nri.Ui.Heading.V2 upgrade to V3
4 Nri.Ui.Menu.V1 upgrade to V3
5 Nri.Ui.SideNav.V3 upgrade to V4

View File

@ -3,7 +3,7 @@
"name": "NoRedInk/noredink-ui",
"summary": "UI Widgets we use at NRI",
"license": "BSD-3-Clause",
"version": "17.2.0",
"version": "17.5.0",
"exposed-modules": [
"Nri.Ui",
"Nri.Ui.Accordion.V1",
@ -15,6 +15,7 @@
"Nri.Ui.Button.V10",
"Nri.Ui.Carousel.V1",
"Nri.Ui.Checkbox.V5",
"Nri.Ui.Checkbox.V6",
"Nri.Ui.ClickableSvg.V2",
"Nri.Ui.ClickableText.V3",
"Nri.Ui.Container.V2",
@ -85,7 +86,7 @@
"elm-community/string-extra": "4.0.1 <= v < 5.0.0",
"pablohirafuji/elm-markdown": "2.0.5 <= v < 3.0.0",
"rtfeldman/elm-css": "17.0.1 <= v < 18.0.0",
"tesk9/accessible-html-with-css": "3.0.0 <= v < 4.0.0",
"tesk9/accessible-html-with-css": "3.1.0 <= v < 4.0.0",
"tesk9/palette": "3.0.1 <= v < 4.0.0"
},
"test-dependencies": {

View File

@ -42,6 +42,9 @@ hint = 'upgrade to V3'
hint = 'upgrade to V10'
usages = ['styleguide-app/../src/Nri/Ui/SlideModal/V2.elm']
[forbidden."Nri.Ui.Checkbox.V5"]
hint = 'upgrade to V6'
[forbidden."Nri.Ui.ClickableSvg.V1"]
hint = 'upgrade to V2'
usages = ['styleguide-app/Examples/Tooltip.elm']

View File

@ -109,17 +109,15 @@ describe("UI tests", function () {
const modalProcessing = async (name, location) => {
await goTo(name, location);
await forAllOptions("Theme", async (option) => {
await page.click("#launch-modal");
await page.waitForSelector('[role="dialog"]');
await percySnapshot(page, `${name} - ${option}`);
await page.click("#launch-modal");
await page.waitForSelector('[role="dialog"]');
await percySnapshot(page, `${name} - info`);
axe = await new AxePuppeteer(page).analyze();
axe = await new AxePuppeteer(page).analyze();
await page.click('[aria-label="Close modal"]');
await page.click('[aria-label="Close modal"]');
handleAxeResults(`${name} - ${option}`, axe);
});
handleAxeResults(`${name} - info`, axe);
};
const pageProcessing = async (name, location) => {

333
src/Nri/Ui/Checkbox/V6.elm Normal file
View File

@ -0,0 +1,333 @@
module Nri.Ui.Checkbox.V6 exposing
( Model, Theme(..), IsSelected(..)
, view, viewWithLabel
, selectedFromBool
, viewIcon, checkboxLockOnInside
)
{-|
# Patch changes
- Use Nri.Ui.Svg.V1 rather than a custom Icon type specific to this module
- Make the filter ids within the svg unique (now the id depends on the checkbox identifier)
- Explicitly box-sizing content-box on the label (<https://github.com/NoRedInk/NoRedInk/pull/30886#issuecomment-737854831>)
# Changes from V5:
- Adds `containerCss`
- Adds `enabledLabelCss`
- Adds `disabledLabelCss`
@docs Model, Theme, IsSelected
@docs view, viewWithLabel
@docs selectedFromBool
@docs viewIcon, checkboxLockOnInside
-}
import Accessibility.Styled as Html
import Accessibility.Styled.Aria as Aria
import Accessibility.Styled.Style
import CheckboxIcons
import Css exposing (..)
import Css.Global
import Html.Styled
import Html.Styled.Attributes as Attributes exposing (css)
import Html.Styled.Events as Events
import Json.Decode
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Fonts.V1 as Fonts
import Nri.Ui.Svg.V1 exposing (Svg)
{-| -}
type alias Model msg =
{ identifier : String
, label : String
, setterMsg : Bool -> msg
, selected : IsSelected
, disabled : Bool
, theme : Theme
, containerCss : List Css.Style
, enabledLabelCss : List Css.Style
, disabledLabelCss : List Css.Style
}
{-|
= Selected -- Checked (rendered with a checkmark)
| NotSelected -- Not Checked (rendered blank)
| PartiallySelected -- Indeterminate (rendered dash)
-}
type IsSelected
= Selected
| NotSelected
| PartiallySelected
{-| -}
type Theme
= Square
| Locked
{-| If your selectedness is always selected or not selected,
you will likely store that state as a `Bool` in your model.
`selectedFromBool` lets you easily convert that into an `IsSelected` value
for use with `Nri.Ui.Checkbox`.
-}
selectedFromBool : Bool -> IsSelected
selectedFromBool isSelected =
case isSelected of
True ->
Selected
False ->
NotSelected
selectedToMaybe : IsSelected -> Maybe Bool
selectedToMaybe selected =
case selected of
Selected ->
Just True
NotSelected ->
Just False
PartiallySelected ->
Nothing
{-| Shows a checkbox (the label is only used for accessibility hints)
-}
view : Model msg -> Html.Html msg
view model =
buildCheckbox model
(\label ->
Html.span Accessibility.Styled.Style.invisible
[ Html.text label ]
)
{-| Shows a checkbox and its label text
-}
viewWithLabel : Model msg -> Html.Html msg
viewWithLabel model =
buildCheckbox model <|
\label -> Html.span [] [ Html.text label ]
buildCheckbox : Model msg -> (String -> Html.Html msg) -> Html.Html msg
buildCheckbox model labelView =
checkboxContainer model
[ viewCheckbox model
, case model.theme of
Square ->
let
icon =
case model.selected of
Selected ->
CheckboxIcons.checked model.identifier
NotSelected ->
CheckboxIcons.unchecked model.identifier
PartiallySelected ->
CheckboxIcons.checkedPartially model.identifier
in
if model.disabled then
viewDisabledLabel model labelView icon
else
viewEnabledLabel model labelView icon
Locked ->
if model.disabled then
viewDisabledLabel model labelView (checkboxLockOnInside model.identifier)
else
viewEnabledLabel model labelView (checkboxLockOnInside model.identifier)
]
checkboxContainer : { a | identifier : String, containerCss : List Style } -> List (Html.Html msg) -> Html.Html msg
checkboxContainer model =
Html.Styled.span
[ css
[ display block
, height inherit
, position relative
, marginLeft (px -4)
, pseudoClass "focus-within"
[ Css.Global.descendants
[ Css.Global.class "checkbox-icon-container"
[ borderColor (rgb 0 95 204)
]
]
]
, Css.Global.descendants
[ Css.Global.input [ position absolute, top (calc (pct 50) minus (px 10)), left (px 10) ]
]
, Css.batch model.containerCss
]
, Attributes.id (model.identifier ++ "-container")
, Events.stopPropagationOn "click" (Json.Decode.fail "stop click propagation")
]
viewCheckbox :
{ a
| identifier : String
, setterMsg : Bool -> msg
, selected : IsSelected
, disabled : Bool
}
-> Html.Html msg
viewCheckbox model =
Html.checkbox model.identifier
(selectedToMaybe model.selected)
[ Attributes.id model.identifier
, if model.disabled then
Aria.disabled True
else
Events.onCheck (\_ -> onCheck model)
]
viewEnabledLabel :
{ a
| identifier : String
, setterMsg : Bool -> msg
, selected : IsSelected
, label : String
, enabledLabelCss : List Style
}
-> (String -> Html.Html msg)
-> Svg
-> Html.Html msg
viewEnabledLabel model labelView icon =
Html.Styled.label
[ Attributes.for model.identifier
, labelClass model.selected
, css
[ positioning
, textStyle
, cursor pointer
, Css.batch model.enabledLabelCss
]
]
[ viewIcon [] icon
, labelView model.label
]
onCheck : { a | setterMsg : Bool -> msg, selected : IsSelected } -> msg
onCheck model =
selectedToMaybe model.selected
|> Maybe.withDefault False
|> not
|> model.setterMsg
viewDisabledLabel :
{ a | identifier : String, selected : IsSelected, label : String, disabledLabelCss : List Style }
-> (String -> Html.Html msg)
-> Svg
-> Html.Html msg
viewDisabledLabel model labelView icon =
Html.Styled.label
[ Attributes.for model.identifier
, labelClass model.selected
, css
[ positioning
, textStyle
, outline none
, cursor auto
, Css.batch model.disabledLabelCss
]
]
[ viewIcon [ opacity (num 0.4) ] icon
, labelView model.label
]
labelClass : IsSelected -> Html.Styled.Attribute msg
labelClass isSelected =
case isSelected of
Selected ->
toClassList [ "Label", "Checked" ]
NotSelected ->
toClassList [ "Label", "Unchecked" ]
PartiallySelected ->
toClassList [ "Label", "Indeterminate" ]
toClassList : List String -> Html.Styled.Attribute msg
toClassList =
List.map (\a -> ( "checkbox-V5__" ++ a, True )) >> Attributes.classList
positioning : Style
positioning =
batch
[ display inlineBlock
, padding4 (px 13) zero (px 13) (px 40)
, position relative
]
textStyle : Style
textStyle =
batch
[ Fonts.baseFont
, fontSize (px 15)
, fontWeight (int 600)
, color Colors.navy
]
{-| -}
viewIcon : List Style -> Svg -> Html.Html msg
viewIcon styles icon =
Html.div
[ css
[ position absolute
, left zero
, top (calc (pct 50) minus (px 18))
, border3 (px 2) solid transparent
, padding (px 2)
, borderRadius (px 3)
, height (Css.px 27)
, boxSizing contentBox
]
, Attributes.class "checkbox-icon-container"
]
[ Html.div
[ css
[ display inlineBlock
, backgroundColor Colors.white
, height (Css.px 27)
, borderRadius (px 4)
]
]
[ Nri.Ui.Svg.V1.toHtml (Nri.Ui.Svg.V1.withCss styles icon)
]
]
{-| -}
checkboxLockOnInside : String -> Svg
checkboxLockOnInside =
CheckboxIcons.lockOnInside

View File

@ -28,8 +28,8 @@ type alias FocusTrap msg =
toAttribute : FocusTrap msg -> Html.Attribute msg
toAttribute { firstId, lastId, focus } =
WhenFocusLeaves.toAttribute
{ firstId = firstId
, lastId = lastId
{ firstId = Debug.log "firstId" firstId
, lastId = Debug.log "lastId " lastId
, -- if the user tabs back while on the first id,
-- we want to wrap around to the last id.
tabBackAction = focus lastId

View File

@ -192,7 +192,6 @@ type alias Customizations msg =
{-| `top` headings are Colors.navy and have:
font-size: 30px
line-height: 38px
font-weight: 700
By default.
@ -203,14 +202,12 @@ top =
(css << headingStyles)
{ color = Colors.navy
, size = 30
, lineHeight = 38
}
{-| `subhead` headings are Colors.navy and have:
font-size: 20px
line-height: 26px
font-weight: 700
By default.
@ -221,14 +218,12 @@ subhead =
(css << headingStyles)
{ color = Colors.navy
, size = 20
, lineHeight = 26
}
{-| `small` headings are Colors.gray20 and have:
font-size: 16px
line-height: 21px
font-weight: 700
By default.
@ -243,14 +238,12 @@ small =
:: headingStyles
{ color = Colors.gray20
, size = 16
, lineHeight = 21
}
)
headingStyles :
{ color : Color
, lineHeight : Float
, size : Float
}
-> List Css.Style
@ -258,7 +251,7 @@ headingStyles config =
[ Fonts.baseFont
, fontSize (px config.size)
, color config.color
, lineHeight (px config.lineHeight)
, lineHeight (num 1.2)
, fontWeight (int 700)
, padding zero
, textAlign left

View File

@ -1,5 +1,5 @@
module Nri.Ui.Logo.V1 exposing
( noredink
( noredink, noredinkMonochrome
, clever, cleverC, cleverLibrary
, googleClassroom, googleG
, canvas
@ -11,7 +11,7 @@ module Nri.Ui.Logo.V1 exposing
{-|
@docs noredink
@docs noredink, noredinkMonochrome
@docs clever, cleverC, cleverLibrary
@docs googleClassroom, googleG
@docs canvas
@ -40,23 +40,48 @@ noredink =
]
[ Svg.path
[ Attributes.fill (toCssString Colors.red)
, Attributes.d "M4.29 6.03v2.048h.065c.943-1.723 2.568-2.503 4.453-2.503 2.795 0 4.453 1.527 4.453 4.972v12.97H8.776v-12.06c0-1.755-.586-2.437-1.918-2.437-1.528 0-2.373.943-2.373 2.892v11.604H0V6.03h4.29zM22.559 20.916c1.82 0 2.404-1.788 2.404-6.143 0-4.355-.584-6.143-2.404-6.143-2.21 0-2.405 2.568-2.405 6.143 0 3.575.195 6.143 2.405 6.143zm0-15.341c5.395-.098 6.89 3.12 6.89 9.198 0 5.98-1.755 9.198-6.89 9.198-5.396.098-6.89-3.12-6.89-9.198 0-5.98 1.754-9.198 6.89-9.198z"
, Attributes.d noD
]
[]
, Svg.path
[ Attributes.fill "#333"
, Attributes.d "M32.246 6.257h1.95v2.698h.065c.748-1.918 2.34-3.088 4.356-3.088.227 0 .455.033.682.098v1.95a4.878 4.878 0 0 0-.942-.097c-2.145 0-4.16 1.56-4.16 4.907v10.791h-1.95V6.257zM49.994 13.342c-.065-4.29-1.268-5.85-3.673-5.85-2.405 0-3.608 1.56-3.673 5.85h7.346zm1.918 4.454c-.293 3.672-2.308 6.11-5.558 6.11-3.64 0-5.786-2.535-5.786-9.035 0-5.981 2.145-9.004 5.948-9.004 3.836 0 5.558 2.633 5.558 8.386v.715h-9.426v.813c0 4.972 1.755 6.5 3.673 6.5 2.048 0 3.315-1.463 3.64-4.485h1.95zM60.266 22.28c1.983 0 3.77-1.007 3.77-7.41 0-6.37-1.787-7.378-3.77-7.378-1.95 0-3.77 1.008-3.77 7.379 0 6.402 1.82 7.41 3.77 7.41zm3.965-1.624h-.065c-.52 1.983-2.177 3.25-4.225 3.25-3.802 0-5.525-3.055-5.525-9.035 0-5.948 1.723-9.004 5.525-9.004 2.145 0 3.608 1.17 4.03 2.99h.065V.31h1.95v23.206h-1.755v-2.86z"
, Attributes.d redD
]
[]
, Svg.path
[ Attributes.fill (toCssString Colors.red)
, Attributes.d "M69.336 6.03h4.486v17.486h-4.486V6.03zm0-5.981h4.486v3.835h-4.486V.05zM76.975 6.03h4.29v2.048h.065c.944-1.723 2.568-2.503 4.453-2.503 2.795 0 4.453 1.527 4.453 4.972v12.97H85.75v-12.06c0-1.755-.585-2.437-1.917-2.437-1.527 0-2.373.943-2.373 2.892v11.604h-4.485V6.03zM97.876.31v12.253h.065l4.518-6.533h4.94l-5.037 6.89 5.785 10.596h-4.94l-3.739-7.183-1.592 2.08v5.103H93.39V.31z"
, Attributes.d inkD
]
[]
]
]
{-| -}
noredinkMonochrome : Nri.Ui.Svg.V1.Svg
noredinkMonochrome =
Nri.Ui.Svg.V1.init "0 0 109 24"
[ Svg.path [ Attributes.d noD ] []
, Svg.path [ Attributes.d redD ] []
, Svg.path [ Attributes.d inkD ] []
]
noD : String
noD =
"M4.29 6.03v2.048h.065c.943-1.723 2.568-2.503 4.453-2.503 2.795 0 4.453 1.527 4.453 4.972v12.97H8.776v-12.06c0-1.755-.586-2.437-1.918-2.437-1.528 0-2.373.943-2.373 2.892v11.604H0V6.03h4.29zM22.559 20.916c1.82 0 2.404-1.788 2.404-6.143 0-4.355-.584-6.143-2.404-6.143-2.21 0-2.405 2.568-2.405 6.143 0 3.575.195 6.143 2.405 6.143zm0-15.341c5.395-.098 6.89 3.12 6.89 9.198 0 5.98-1.755 9.198-6.89 9.198-5.396.098-6.89-3.12-6.89-9.198 0-5.98 1.754-9.198 6.89-9.198z"
redD : String
redD =
"M32.246 6.257h1.95v2.698h.065c.748-1.918 2.34-3.088 4.356-3.088.227 0 .455.033.682.098v1.95a4.878 4.878 0 0 0-.942-.097c-2.145 0-4.16 1.56-4.16 4.907v10.791h-1.95V6.257zM49.994 13.342c-.065-4.29-1.268-5.85-3.673-5.85-2.405 0-3.608 1.56-3.673 5.85h7.346zm1.918 4.454c-.293 3.672-2.308 6.11-5.558 6.11-3.64 0-5.786-2.535-5.786-9.035 0-5.981 2.145-9.004 5.948-9.004 3.836 0 5.558 2.633 5.558 8.386v.715h-9.426v.813c0 4.972 1.755 6.5 3.673 6.5 2.048 0 3.315-1.463 3.64-4.485h1.95zM60.266 22.28c1.983 0 3.77-1.007 3.77-7.41 0-6.37-1.787-7.378-3.77-7.378-1.95 0-3.77 1.008-3.77 7.379 0 6.402 1.82 7.41 3.77 7.41zm3.965-1.624h-.065c-.52 1.983-2.177 3.25-4.225 3.25-3.802 0-5.525-3.055-5.525-9.035 0-5.948 1.723-9.004 5.525-9.004 2.145 0 3.608 1.17 4.03 2.99h.065V.31h1.95v23.206h-1.755v-2.86z"
inkD : String
inkD =
"M69.336 6.03h4.486v17.486h-4.486V6.03zm0-5.981h4.486v3.835h-4.486V.05zM76.975 6.03h4.29v2.048h.065c.944-1.723 2.568-2.503 4.453-2.503 2.795 0 4.453 1.527 4.453 4.972v12.97H85.75v-12.06c0-1.755-.585-2.437-1.917-2.437-1.527 0-2.373.943-2.373 2.892v11.604h-4.485V6.03zM97.876.31v12.253h.065l4.518-6.533h4.94l-5.037 6.89 5.785 10.596h-4.94l-3.739-7.183-1.592 2.08v5.103H93.39V.31z"
{-| -}
facebook : Nri.Ui.Svg.V1.Svg
facebook =

View File

@ -611,7 +611,6 @@ viewCustom config =
AttributesExtra.none
, Aria.labelledBy config.buttonId
, Attributes.id config.menuId
, Aria.hidden (not config.isOpen)
, css
[ Maybe.map (\w -> Css.width (Css.px (toFloat w))) config.menuWidth
|> Maybe.withDefault (Css.batch [])

View File

@ -519,7 +519,7 @@ view config attrsList model =
|> Root.div
(List.concat
[ [ FocusTrap.toAttribute config.focusTrap ]
, [ Attrs.css [ Css.position Css.relative, Css.zIndex (Css.int 1) ] ]
, [ Attrs.css [ Css.position Css.relative, Css.zIndex (Css.int 100) ] ]
]
)
@ -733,7 +733,6 @@ viewCloseButton closeModal =
, Css.right Css.zero
-- make appear above lesson content
, Css.zIndex (Css.int 10)
, Css.backgroundColor (rgba 255 255 255 0.5)
, Css.borderRadius (pct 50)

View File

@ -203,13 +203,17 @@ view : Config msg -> Html msg
view config =
viewContainer
[ viewEmoji [ Html.text config.emoji ]
, Heading.h1 [ Heading.plaintext config.title ]
, Heading.h1
[ Heading.plaintext config.title
, Heading.css [ Css.textAlign Css.center ]
]
, Text.mediumBody
[ Text.plaintext config.subtitle
, Text.css
[ Css.fontSize (Css.px 20)
, Css.color Colors.gray45
, Css.marginBottom Css.zero
, Css.textAlign Css.center
]
]
, viewButton

View File

@ -5,6 +5,9 @@ module Nri.Ui.PremiumCheckbox.V8 exposing
, Attribute
, disabled, enabled
, id
, setCheckboxContainerCss
, setCheckboxEnabledLabelCss
, setCheckboxDisabledLabelCss
)
{-| Changes from V7:
@ -12,6 +15,7 @@ module Nri.Ui.PremiumCheckbox.V8 exposing
- Use PremiumDisplay instead of PremiumLevel
- Rename showPennant to onLockedClick
- Fix clicking on locked checkbox to send a onLockedClick
- Exposes checkbox custom styling
@docs view
@ -29,13 +33,20 @@ module Nri.Ui.PremiumCheckbox.V8 exposing
@docs disabled, enabled
@docs id
### Custom CSS
@docs setCheckboxContainerCss
@docs setCheckboxEnabledLabelCss
@docs setCheckboxDisabledLabelCss
-}
import Accessibility.Styled as Html exposing (Html)
import Css exposing (..)
import Html.Styled.Attributes as Attributes exposing (class, css)
import Html.Styled.Events as Events
import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.Checkbox.V6 as Checkbox
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Data.PremiumDisplay as PremiumDisplay exposing (PremiumDisplay)
import Nri.Ui.Fonts.V1 as Fonts
@ -93,6 +104,27 @@ setSelectionStatus status =
Attribute (\config -> { config | selected = status })
{-| Set custom CSS for the checkbox container
-}
setCheckboxContainerCss : List Css.Style -> Attribute msg
setCheckboxContainerCss checkboxContainerCss =
Attribute <| \config -> { config | checkboxContainerCss = checkboxContainerCss }
{-| Set custom CSS for the enabled checkbox label
-}
setCheckboxEnabledLabelCss : List Css.Style -> Attribute msg
setCheckboxEnabledLabelCss checkboxEnabledLabelCss =
Attribute <| \config -> { config | checkboxEnabledLabelCss = checkboxEnabledLabelCss }
{-| Set custom CSS for the disabled checkbox label
-}
setCheckboxDisabledLabelCss : List Css.Style -> Attribute msg
setCheckboxDisabledLabelCss checkboxDisabledLabelCss =
Attribute <| \config -> { config | checkboxDisabledLabelCss = checkboxDisabledLabelCss }
{-| -}
selected : Bool -> Attribute msg
selected isSelected =
@ -125,6 +157,9 @@ type alias Config msg =
, containerCss : List Css.Style
, selected : Checkbox.IsSelected
, onLockedMsg : Maybe msg
, checkboxContainerCss : List Css.Style
, checkboxEnabledLabelCss : List Css.Style
, checkboxDisabledLabelCss : List Css.Style
}
@ -139,6 +174,9 @@ emptyConfig =
]
, selected = Checkbox.NotSelected
, onLockedMsg = Nothing
, checkboxContainerCss = []
, checkboxEnabledLabelCss = []
, checkboxDisabledLabelCss = []
}
@ -203,6 +241,9 @@ view { label, onChange } attributes =
else
Checkbox.Square
, containerCss = config.checkboxContainerCss
, enabledLabelCss = config.checkboxEnabledLabelCss
, disabledLabelCss = config.checkboxDisabledLabelCss
}
]

View File

@ -329,7 +329,11 @@ view { label, name, value, valueToString, selectedValue } attributes =
Nothing ->
Extra.none
, class "Nri-RadioButton-HiddenRadioInput"
, Aria.describedBy disclosureIds
, if List.length disclosureIds > 0 then
Aria.describedBy disclosureIds
else
Extra.none
, css
[ position absolute
, top (pct 50)

View File

@ -5,7 +5,7 @@ module Nri.Ui.Select.V8 exposing
, value
, Attribute, defaultDisplayText
, hiddenLabel, visibleLabel
, errorIf, errorMessage, guidance
, disabled, loading, errorIf, errorMessage, guidance
, custom, nriDescription, id, testId
, containerCss, noMargin
)
@ -37,7 +37,7 @@ module Nri.Ui.Select.V8 exposing
@docs Attribute, defaultDisplayText
@docs hiddenLabel, visibleLabel
@docs errorIf, errorMessage, guidance
@docs disabled, loading, errorIf, errorMessage, guidance
@docs custom, nriDescription, id, testId
@docs containerCss, noMargin
@ -84,6 +84,20 @@ errorIf =
Attribute << InputErrorAndGuidanceInternal.setErrorIf
{-| Disables the input
-}
disabled : Attribute value
disabled =
Attribute (\config -> { config | disabled = True })
{-| Use this while the form the input is a part of is being submitted.
-}
loading : Attribute value
loading =
Attribute (\config -> { config | loading = True })
{-| If `Just`, the field will be highlighted as having a validation error,
and the given error message will be shown.
-}
@ -221,6 +235,8 @@ type alias Config value =
, valueToString : Maybe (value -> String)
, defaultDisplayText : Maybe String
, error : ErrorState
, disabled : Bool
, loading : Bool
, guidance : Guidance
, hideLabel : Bool
, noMarginTop : Bool
@ -238,6 +254,8 @@ defaultConfig =
, valueToString = Nothing
, defaultDisplayText = Nothing
, error = InputErrorAndGuidanceInternal.noError
, disabled = False
, loading = False
, guidance = InputErrorAndGuidanceInternal.noGuidance
, hideLabel = False
, noMarginTop = False
@ -258,10 +276,22 @@ view label attributes =
id_ =
Maybe.withDefault (generateId label) config.id
( opacity, disabled_ ) =
case ( config.disabled, config.loading ) of
( False, False ) ->
( Css.num 1, False )
( False, True ) ->
( Css.num 0.5, True )
( True, _ ) ->
( Css.num 0.4, True )
in
Html.div
[ css
([ Css.position Css.relative
, Css.opacity opacity
, if config.noMarginTop then
Css.batch []
@ -271,13 +301,7 @@ view label attributes =
++ config.containerCss
)
]
[ InputLabelInternal.view
{ for = id_
, label = label
, theme = InputStyles.Standard
}
config
, viewSelect
[ viewSelect
{ choices = config.choices
, optgroups = config.optgroups
, current = config.value
@ -286,7 +310,14 @@ view label attributes =
, valueToString = config.valueToString
, defaultDisplayText = config.defaultDisplayText
, isInError = isInError_
, disabled = disabled_
}
, InputLabelInternal.view
{ for = id_
, label = label
, theme = InputStyles.Standard
}
config
, InputErrorAndGuidanceInternal.view id_ config
]
@ -299,6 +330,7 @@ viewSelect :
, valueToString : Maybe (a -> String)
, defaultDisplayText : Maybe String
, isInError : Bool
, disabled : Bool
, custom : List (Html.Attribute Never)
}
-> Html a
@ -400,7 +432,13 @@ viewSelect config =
, Css.whiteSpace Css.noWrap
-- Interaction
, Css.cursor Css.pointer
, Css.cursor
(if config.disabled then
Css.default
else
Css.pointer
)
-- Size and spacing
, Css.height (Css.px 45)
@ -413,6 +451,7 @@ viewSelect config =
]
(onSelectHandler
:: Attributes.id config.id
:: Attributes.disabled config.disabled
:: List.map (Attributes.map never) config.custom
)

View File

@ -19,6 +19,7 @@ module Nri.Ui.Switch.V2 exposing
- REQUIRE label and id always
- Move custom attributes to the container
- change disabled to take a bool (which I think is the slighty more common pattern)
- Adds `role="switch"`
@docs view
@ -34,6 +35,7 @@ module Nri.Ui.Switch.V2 exposing
import Accessibility.Styled as Html exposing (Html)
import Accessibility.Styled.Aria as Aria
import Accessibility.Styled.Role as Role
import Css exposing (Color, Style)
import Css.Global as Global
import Html.Styled.Attributes as Attributes
@ -215,6 +217,7 @@ viewCheckbox config =
Html.checkbox config.id
(Just config.selected)
[ Attributes.id config.id
, Role.switch
, Attributes.css
[ Css.position Css.absolute
, Css.top (Css.px 10)

View File

@ -1,5 +1,5 @@
module Nri.Ui.UiIcon.V1 exposing
( seeMore, openClose, download, sort, gear, flipper, hamburger
( seeMore, openClose, download, sort, gear, flipper, hamburger, kebab
, archive, unarchive
, playInCircle, pauseInCircle, stopInCircle
, play, skip
@ -27,6 +27,7 @@ module Nri.Ui.UiIcon.V1 exposing
, openQuotationMark, closeQuotationMark
, microscope, scale
, openInNewTab, sync
, apple, briefcase
, school, highSchool, company, homeSchool, graduateCap
, flagUs, globe
, info
@ -34,7 +35,7 @@ module Nri.Ui.UiIcon.V1 exposing
{-| How to add new icons: <https://paper.dropbox.com/doc/How-to-create-a-new-SVG-icon-for-use-in-Elm--Ay9uhSLfGUAix0ERIiJ0Dm8dAg-8WNqtARdr4EgjmYEHPeYD>
@docs seeMore, openClose, download, sort, gear, flipper, hamburger
@docs seeMore, openClose, download, sort, gear, flipper, hamburger, kebab
@docs archive, unarchive
@docs playInCircle, pauseInCircle, stopInCircle
@docs play, skip
@ -62,6 +63,7 @@ module Nri.Ui.UiIcon.V1 exposing
@docs openQuotationMark, closeQuotationMark
@docs microscope, scale
@docs openInNewTab, sync
@docs apple, briefcase
@docs school, highSchool, company, homeSchool, graduateCap
@docs flagUs, globe
@docs info
@ -525,14 +527,23 @@ arrowPointingRight =
{-| -}
sortArrow : Nri.Ui.Svg.V1.Svg
sortArrow =
Nri.Ui.Svg.V1.init "0 0 8 6"
[ Svg.polygon [ Attributes.points "0 6 4 0 8 6 0 6" ] [] ]
Nri.Ui.Svg.V1.init "0 0 92 71"
[ Svg.path
[ Attributes.d "M50.1602515,2.24037721 L90.817666,63.226499 C92.3494283,65.5241425 91.728559,68.6284892 89.4309155,70.1602515 C88.6095779,70.7078099 87.6445395,71 86.6574145,71 L5.34258546,71 C2.58116171,71 0.342585459,68.7614237 0.342585459,66 C0.342585459,65.0128751 0.634775596,64.0478366 1.18233399,63.226499 L41.8397485,2.24037721 C43.3715108,-0.0572662357 46.4758575,-0.678135579 48.773501,0.853626717 C49.3227624,1.21980101 49.7940772,1.69111577 50.1602515,2.24037721 Z"
]
[]
]
{-| -}
sortArrowDown : Nri.Ui.Svg.V1.Svg
sortArrowDown =
Nri.Ui.Svg.V1.withCustom [ Attributes.transform "rotate(180)" ] sortArrow
Nri.Ui.Svg.V1.init "0 0 92 71"
[ Svg.path
[ Attributes.d "M41.83975,68.759623 L1.182335,7.7735 C-0.3494263,5.47586 0.2714386,2.37151 2.569084,0.83975 C3.390419,0.29219 4.355461,0 5.342583,0 L86.65741,0 C89.41884,0 91.65741,2.23858 91.65741,5 C91.65741,5.98712 91.36522,6.95216 90.81767,7.7735 L50.16025,68.759623 C48.62849,71.0572662 45.52414,71.6781356 43.2265,70.1463732 C42.67724,69.780199 42.20592,69.308884 41.83975,68.759623 Z"
]
[]
]
{-| -}
@ -954,6 +965,34 @@ hamburger =
]
{-| -}
kebab : Nri.Ui.Svg.V1.Svg
kebab =
Nri.Ui.Svg.V1.init "0 0 100 100"
[ Svg.circle
[ Attributes.cx "50"
, Attributes.cy "13.7"
, Attributes.r "12"
, Attributes.fill "currentcolor"
]
[]
, Svg.circle
[ Attributes.cx "50"
, Attributes.cy "50"
, Attributes.r "12"
, Attributes.fill "currentcolor"
]
[]
, Svg.circle
[ Attributes.cx "50"
, Attributes.cy "86.3"
, Attributes.r "12"
, Attributes.fill "currentcolor"
]
[]
]
{-| -}
equals : Nri.Ui.Svg.V1.Svg
equals =
@ -1397,7 +1436,7 @@ checklistComplete =
{-| -}
openBook : Nri.Ui.Svg.V1.Svg
openBook =
Nri.Ui.Svg.V1.init "0 0 16 13"
Nri.Ui.Svg.V1.init "0 0 15 12"
[ Svg.g [ Attributes.transform "translate(0.256349, 0.281480)" ]
[ Svg.path [ Attributes.d "M5.97967784,7.68594033 L6.3357413,7.774016 L6.3357413,8.297421 C4.90871699,7.91726562 3.51632767,7.87765319 2.08989378,8.17910991 L1.7325363,8.26158 L1.7325363,7.737499 C3.16515353,7.37982238 4.55798757,7.36210421 5.97967784,7.68594033 L5.97967784,7.68594033 Z" ] []
, Svg.path [ Attributes.d "M5.97967784,6.20834789 L6.3357413,6.296302 L6.3357413,6.820381 C4.90871699,6.43960069 3.51632767,6.40051534 2.08989378,6.70152673 L1.7325363,6.783864 L1.7325363,6.26046 C3.16515353,5.90153631 4.55798757,5.88487164 5.97967784,6.20834789 L5.97967784,6.20834789 Z" ] []
@ -1883,3 +1922,66 @@ graduateCap =
]
]
]
{-| -}
apple : Nri.Ui.Svg.V1.Svg
apple =
Nri.Ui.Svg.V1.init "0 0 88 89"
[ Svg.g
[ Attributes.stroke "none"
, Attributes.strokeWidth "1"
, Attributes.fill "none"
, Attributes.fillRule "evenodd"
]
[ Svg.g
[ Attributes.transform "translate(-30.100000, -105.000000)"
, Attributes.fill "currentcolor"
, Attributes.fillRule "nonzero"
]
[ Svg.g
[ Attributes.transform "translate(30.972117, 105.800000)"
]
[ Svg.path
[ Attributes.d "M79.8396503,26.20726 C76.3787503,20.89476 70.9060503,17.22286 64.6836503,16.02726 C58.4570503,14.83586 52.0156503,16.22648 46.8356503,19.88276 C46.4801803,20.08979 46.1051803,20.26557 45.7145503,20.4062 L45.7145503,15.625 C45.7106443,11.4844 44.0622503,7.5117 41.1325503,4.582 C38.2028503,1.6523 34.2302503,0.0039 30.0895503,8.8817842e-16 C28.3629503,8.8817842e-16 26.9645503,1.3984 26.9645503,3.125 C26.9645503,4.8516 28.3629503,6.25 30.0895503,6.25 C35.2653503,6.25 39.4645503,10.4492 39.4645503,15.625 L39.4645503,19.8906 C34.4489503,16.4961 28.3395503,15.1094 22.3515503,16.0078 C15.9179503,17.1484 10.2265503,20.8633 6.59355033,26.2968 C0.792750325,35.1054 -1.29314967,45.8478 0.784950325,56.1878 C3.92945033,74.2658 17.0859503,87.4998 31.0899503,87.4998 C32.2891503,87.4998 33.4883503,87.402144 34.6758503,87.20683 C37.1094503,86.80449 39.4649503,86.00373 41.6406503,84.83573 C42.6758503,84.26932 43.9297503,84.26932 44.9648503,84.83573 C47.0898503,85.96073 49.3867503,86.73413 51.7617503,87.12483 C67.0317503,89.65213 82.2387503,75.72683 85.6487503,56.11283 C87.7346503,45.76883 85.6448443,35.01883 79.8401503,26.20683 L79.8396503,26.20726 Z M68.9016503,37.80526 C68.3743103,38.18026 67.7414503,38.38338 67.0969503,38.38338 C66.0813503,38.38338 65.1321503,37.89119 64.5461503,37.06698 C63.7531803,35.77398 62.4953503,34.82868 61.0344503,34.42638 C59.3274503,34.14513 58.1711503,32.53968 58.4524503,30.83658 C58.7297903,29.12958 60.3391503,27.97328 62.0422503,28.25458 C65.1750503,28.88349 67.9211503,30.75068 69.6516503,33.43818 C70.1360303,34.11396 70.3313403,34.95768 70.1946203,35.77798 C70.0540003,36.6022 69.5930603,37.33268 68.9134203,37.81318 L68.9016503,37.80526 Z"
]
[]
]
]
]
]
{-| -}
briefcase : Nri.Ui.Svg.V1.Svg
briefcase =
Nri.Ui.Svg.V1.init "0 0 89 82"
[ Svg.g
[ Attributes.stroke "none"
, Attributes.strokeWidth "1"
, Attributes.fill "none"
, Attributes.fillRule "evenodd"
]
[ Svg.g
[ Attributes.transform "translate(0.900000, 0.000000)"
, Attributes.fill "currentcolor"
, Attributes.fillRule "nonzero"
]
[ Svg.g
[]
[ Svg.path
[ Attributes.d "M27.1245,43.7495041 L34.3745,43.7495041 C34.3745,40.2964 37.1714,37.4995 40.6245,37.4995 L46.8745,37.4995 C48.5307,37.4995 50.1206,38.15966 51.2925,39.3315 C52.4644,40.50334 53.1245,42.0932 53.1245,43.7495041 L60.3745,43.7495041 C66.7612,43.753406 72.8275,40.9643 76.9835,36.1128 L87.3975,23.9648 C86.87797,19.2304 82.8858,15.6406 78.1241,15.625 L65.6241,15.625 L65.6241,9.375 C65.6241,4.1992 61.4249,3.55271368e-15 56.2491,3.55271368e-15 L31.2491,3.55271368e-15 C26.0733,3.55271368e-15 21.8741,4.1992 21.8741,9.375 L21.8741,15.625 L9.3741,15.625 C4.6124,15.640625 0.6202,19.2305 0.1007,23.9648 L10.5147,36.1128 C14.6709,40.9644 20.7377,43.7534 27.1237,43.7495041 L27.1245,43.7495041 Z M28.12446,9.3745 C28.12446,7.6479 29.5229,6.2495 31.2495,6.2495 L56.2495,6.2495 C57.07762,6.2495 57.8745,6.57762 58.4604,7.16356 C59.04634,7.7495 59.37446,8.54636 59.37446,9.37446 L59.37446,15.62446 L28.12446,15.62446 L28.12446,9.3745 Z"
]
[]
, Svg.path
[ Attributes.d "M81.7295,40.1795 C76.3897,46.4139 68.5845,50.0037 60.3745,49.9998 L53.1245,49.9998 C53.1245,51.656 52.46434,53.2459 51.2925,54.4178 C50.12066,55.5897 48.5308,56.2498 46.8745,56.2498 L40.6245,56.2498 C37.1714,56.2498 34.3745,53.4529 34.3745,49.9998 L27.1245,49.9998 C18.9136,50.003706 11.1085,46.4139 5.7695,40.1795 L0,33.4373 L0,71.8753 C0,77.0511 4.1992,81.2503 9.375,81.2503 L78.125,81.2503 C83.3008,81.2503 87.5,77.0511 87.5,71.8753 L87.5,33.4373 L81.7295,40.1795 Z"
]
[]
, Svg.polygon
[ Attributes.points "40.6245 43.7455 46.8745 43.7455 46.8745 49.9994 40.6245 49.9994"
]
[]
]
]
]
]

View File

@ -7,7 +7,7 @@ module Nri.Ui.WhenFocusLeaves.V1 exposing (toAttribute, toDecoder)
-}
import Accessibility.Styled as Html
import Accessibility.Styled.Key as Key
import Html.Styled.Events exposing (preventDefaultOn)
import Json.Decode as Decode exposing (Decoder)
@ -28,7 +28,8 @@ toAttribute :
}
-> Html.Attribute msg
toAttribute config =
Key.onKeyDown [ toDecoder config ]
preventDefaultOn "keydown"
(Decode.map (\msg -> ( msg, True )) (toDecoder config))
{-| Use this decoder to add a focus watcher to an HTML element and define

View File

@ -119,7 +119,8 @@ viewTab_ config index tab =
Nothing ->
-- This is for a non-SPA view
( Html.button
, [ Events.onClick (config.focusAndSelect { select = tab.id, focus = Nothing })
, [ Attributes.type_ "button"
, Events.onClick (config.focusAndSelect { select = tab.id, focus = Nothing })
]
)
@ -246,16 +247,15 @@ viewTabPanel tab selected =
([ Role.tabPanel
, Aria.labelledBy (tabToId tab.idString)
, Attributes.id (tabToBodyId tab.idString)
, Attributes.tabindex 0
]
++ (if selected then
[ Aria.hidden False
, Attributes.tabindex 0
[ -- Used as selector for test queries
Attributes.attribute "data-selected" "true"
]
else
[ Attributes.css [ Css.display Css.none ]
, Aria.hidden True
, Attributes.tabindex -1
]
)
)

View File

@ -40,7 +40,7 @@ view :
, update : Control a -> msg
, settings : Control a
, mainType : String
, extraImports : List String
, extraCode : List String
, toExampleCode : a -> List { sectionName : String, code : String }
}
-> Html msg
@ -74,7 +74,7 @@ view config =
viewExampleCode :
(EllieLink.SectionExample -> Html msg)
-> { component | name : String, version : Int, mainType : String, extraImports : List String }
-> { component | name : String, version : Int, mainType : String, extraCode : List String }
-> List { sectionName : String, code : String }
-> Html msg
viewExampleCode ellieLink component values =
@ -97,7 +97,7 @@ viewExampleCode ellieLink component values =
, name = component.name
, sectionName = example.sectionName
, mainType = component.mainType
, extraImports = component.extraImports
, extraCode = component.extraCode
, code = example.code
}
, code

View File

@ -17,7 +17,7 @@ type alias SectionExample =
, fullModuleName : String
, sectionName : String
, mainType : String
, extraImports : List String
, extraCode : List String
, code : String
}
@ -80,7 +80,7 @@ generateElmExampleModule config example =
, "import Nri.Ui.UiIcon.V1 as UiIcon"
, "import Nri.Ui.Svg.V1 as Svg"
, "import " ++ example.fullModuleName ++ " as " ++ example.name
, String.join "\n" example.extraImports
, String.join "\n" example.extraCode
, ""
, ""
]

View File

@ -104,7 +104,7 @@ view ellieLinkConfig model =
, update = UpdateControls
, settings = model.settings
, mainType = "RootHtml.Html String"
, extraImports =
, extraCode =
[ "import Nri.Ui.DisclosureIndicator.V2 as DisclosureIndicator"
, "import Nri.Ui.Svg.V1 as Svg"
]

View File

@ -151,7 +151,7 @@ view ellieLinkConfig state =
, update = SetAttributes
, settings = state
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\{ copy, attributes } ->
[ { sectionName = "Balloon"

View File

@ -68,7 +68,7 @@ example =
, update = UpdateControl
, settings = state
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode = \settings -> [ { sectionName = moduleName ++ ".view", code = viewExampleCode settings } ]
}
, section [ css [ Css.margin2 (Css.px 20) Css.zero ] ]

View File

@ -209,7 +209,7 @@ viewButtonExamples ellieLinkConfig state =
, update = SetDebugControlsState
, settings = state.debugControlsState
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\{ label, attributes } ->
let

View File

@ -185,7 +185,7 @@ example =
, update = SetSettings
, settings = model.settings
, mainType = "RootHtml.Html { select : Int, focus : Maybe String }"
, extraImports = []
, extraCode = []
, toExampleCode =
\_ ->
let

View File

@ -13,7 +13,7 @@ import Example exposing (Example)
import Html.Styled as Html exposing (..)
import Html.Styled.Attributes exposing (css)
import KeyboardSupport exposing (Key(..))
import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.Checkbox.V6 as Checkbox
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Data.PremiumDisplay as PremiumDisplay
import Nri.Ui.Fonts.V1 as Fonts
@ -39,7 +39,7 @@ type alias State =
example : Example State Msg
example =
{ name = "Checkbox"
, version = 5
, version = 6
, state = init
, update = update
, subscriptions = \_ -> Sub.none
@ -53,6 +53,8 @@ example =
, viewMultilineCheckboxes state
, Heading.h2 [ Heading.plaintext "Premium Checkboxes" ]
, viewPremiumCheckboxes state
, viewCustomStyledCheckbox state
, viewCustomStyledPremiumCheckboxes state
]
, categories = [ Inputs ]
, keyboardSupport =
@ -128,6 +130,9 @@ viewInteractableCheckbox id state =
, selected = isSelected id state
, disabled = False
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
@ -140,6 +145,9 @@ viewIndeterminateCheckbox id state =
, selected = Checkbox.PartiallySelected
, disabled = True
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
@ -152,6 +160,9 @@ viewLockedOnInsideCheckbox id state =
, selected = Checkbox.NotSelected
, disabled = True
, theme = Checkbox.Locked
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
@ -164,6 +175,9 @@ viewDisabledCheckbox id state =
, selected = isSelected id state
, disabled = True
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
@ -183,6 +197,9 @@ viewMultilineCheckboxes state =
, selected = isSelected id state
, disabled = False
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
, Checkbox.viewWithLabel
{ identifier = "fake-partially-selected"
@ -191,6 +208,9 @@ viewMultilineCheckboxes state =
, selected = Checkbox.PartiallySelected
, disabled = True
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
, Checkbox.viewWithLabel
{ identifier = "fake-not-selected-locked"
@ -199,6 +219,9 @@ viewMultilineCheckboxes state =
, selected = Checkbox.NotSelected
, disabled = True
, theme = Checkbox.Locked
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
, Checkbox.viewWithLabel
{ identifier = "fake-not-selected-square"
@ -207,6 +230,9 @@ viewMultilineCheckboxes state =
, selected = Checkbox.NotSelected
, disabled = True
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
]
@ -241,6 +267,47 @@ viewPremiumCheckboxes state =
]
viewCustomStyledCheckbox : State -> Html Msg
viewCustomStyledCheckbox state =
Html.section
[ css [ Css.width (Css.px 500) ] ]
[ Heading.h2 [ Heading.plaintext "Custom-styled Checkboxes" ]
, let
id =
"styleguide-checkbox-custom-style"
in
Checkbox.viewWithLabel
{ identifier = id
, label = "This is a custom-styled Checkbox"
, setterMsg = ToggleCheck id
, selected = isSelected id state
, disabled = False
, theme = Checkbox.Square
, containerCss = [ Css.backgroundColor Colors.navy ]
, enabledLabelCss = [ Css.color Colors.white ]
, disabledLabelCss = []
}
]
viewCustomStyledPremiumCheckboxes : State -> Html Msg
viewCustomStyledPremiumCheckboxes state =
Html.section
[ css [ Css.width (Css.px 500) ] ]
[ Heading.h2 [ Heading.plaintext "Custom-styled Premium Checkboxes" ]
, PremiumCheckbox.view
{ label = "This is a custom-styled Premium Checkbox"
, onChange = ToggleCheck "premium-custom"
}
[ PremiumCheckbox.premium PremiumDisplay.PremiumUnlocked
, PremiumCheckbox.onLockedClick NoOp
, PremiumCheckbox.selected (Set.member "premium-custom" state.isChecked)
, PremiumCheckbox.setCheckboxContainerCss [ Css.backgroundColor Colors.navy ]
, PremiumCheckbox.setCheckboxEnabledLabelCss [ Css.color Colors.white ]
]
]
type alias Id =
String

View File

@ -65,7 +65,7 @@ example =
, update = SetControls
, settings = state.settings
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\{ label, icon, attributes } ->
let

View File

@ -143,7 +143,7 @@ viewExamples ellieLinkConfig (State control) =
, update = SetState
, settings = control
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\{ label, attributes } ->
let

View File

@ -58,7 +58,7 @@ example =
, update = UpdateControl
, settings = state.settings
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\settings -> [ { sectionName = "TODO", code = "TODO" } ]
}

View File

@ -59,7 +59,7 @@ example =
, update = UpdateControl
, settings = state.control
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\settings ->
let

View File

@ -59,7 +59,7 @@ example =
, update = UpdateSettings
, settings = state.settings
, mainType = "RootHtml.Html msg"
, extraImports = [ "import Nri.Ui.Svg.V1 as Svg" ]
, extraCode = [ "import Nri.Ui.Svg.V1 as Svg" ]
, toExampleCode =
\settings ->
let

View File

@ -63,7 +63,7 @@ example =
, update = UpdateControl
, settings = state.control
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\settings ->
let

View File

@ -21,7 +21,7 @@ import Example exposing (Example)
import Html.Styled as Html exposing (Html)
import Html.Styled.Attributes as Attributes exposing (css)
import Html.Styled.Events as Events
import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.Checkbox.V6 as Checkbox
import Nri.Ui.Colors.Extra exposing (fromCssColor, toCssColor)
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V3 as Heading
@ -167,6 +167,9 @@ viewSettings { showIconName } =
, selected = Checkbox.selectedFromBool showIconName
, disabled = False
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
@ -306,6 +309,9 @@ viewSingularExampleSettings groups state =
, selected = Checkbox.selectedFromBool state.showBorder
, disabled = False
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
, Html.label []
[ Html.text "Color: "

View File

@ -58,6 +58,13 @@ all =
, Css.margin (Css.px 4)
]
)
, ( "noredinkMonochrome"
, Logo.noredinkMonochrome
, [ Css.height (Css.px 25)
, Css.width (Css.px 100)
, Css.margin (Css.px 4)
]
)
]
)
, ( "Social Media"

View File

@ -139,7 +139,7 @@ view ellieLinkConfig state =
, update = UpdateControls
, settings = state.settings
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\settings ->
let

View File

@ -158,7 +158,7 @@ example =
, update = UpdateControl
, settings = state.control
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\settings ->
let

View File

@ -10,6 +10,8 @@ import Accessibility.Styled exposing (Html, div, text)
import Accessibility.Styled.Key as Key
import Browser.Dom as Dom
import Category exposing (Category(..))
import Code
import CommonControls
import Css exposing (..)
import Debug.Control as Control exposing (Control)
import Debug.Control.View as ControlView
@ -45,9 +47,9 @@ init =
type alias ViewSettings =
{ title : String
, titleVisibility : Modal.Attribute
, theme : Modal.Attribute
, customCss : Modal.Attribute
, titleVisibility : Maybe ( String, Modal.Attribute )
, theme : Maybe ( String, Modal.Attribute )
, customCss : Maybe ( String, Modal.Attribute )
, showX : Bool
, showContinue : Bool
, showSecondary : Bool
@ -60,9 +62,9 @@ initViewSettings : Control ViewSettings
initViewSettings =
Control.record ViewSettings
|> Control.field "Modal title" (Control.string "Modal Title")
|> Control.field "Title visibility" controlTitleVisibility
|> Control.field "Theme" controlTheme
|> Control.field "Custom css" controlCss
|> Control.field "Title visibility" (Control.maybe False controlTitleVisibility)
|> Control.field "Theme" (Control.maybe False controlTheme)
|> Control.field "Custom css" (Control.maybe False controlCss)
|> Control.field "X button" (Control.bool True)
|> Control.field "Continue button" (Control.bool True)
|> Control.field "Close button" (Control.bool True)
@ -77,30 +79,28 @@ initViewSettings =
)
controlTitleVisibility : Control Modal.Attribute
controlTitleVisibility : Control ( String, Modal.Attribute )
controlTitleVisibility =
Control.choice
[ ( "showTitle", Control.value Modal.showTitle )
, ( "hideTitle", Control.value Modal.hideTitle )
CommonControls.choice moduleName
[ ( "hideTitle", Modal.hideTitle )
, ( "showTitle", Modal.showTitle )
]
controlTheme : Control Modal.Attribute
controlTheme : Control ( String, Modal.Attribute )
controlTheme =
Control.choice
[ ( "info", Control.value Modal.info )
, ( "warning", Control.value Modal.warning )
CommonControls.choice moduleName
[ ( "warning", Modal.warning )
, ( "info", Modal.info )
]
controlCss : Control Modal.Attribute
controlCss : Control ( String, Modal.Attribute )
controlCss =
Control.map Modal.css <|
Control.choice
[ ( "[]", Control.value [] )
, ( "[ Css.borderRadius Css.zero ]", Control.value [ Css.borderRadius Css.zero ] )
, ( "[ Css.width (Css.px 900) ]", Control.value [ Css.width (Css.px 900) ] )
]
CommonControls.choice moduleName
[ ( "css [ Css.borderRadius Css.zero ]", Modal.css [ Css.borderRadius Css.zero ] )
, ( "css [ Css.width (Css.px 900) ]", Modal.css [ Css.width (Css.px 900) ] )
]
moduleName : String
@ -190,9 +190,60 @@ example =
, version = version
, update = UpdateSettings
, settings = state.settings
, mainType = "RootHtml.Html ModalMsg"
, extraImports = []
, toExampleCode = \_ -> []
, mainType = "RootHtml.Html Msg"
, extraCode = [ "type Msg = ModalMsg Modal.Msg | Focus String" ]
, toExampleCode =
\_ ->
let
code =
[ "Modal.view"
, "\n\t{ title = " ++ Code.string settings.title
, "\n\t, wrapMsg = ModalMsg"
, "\n\t, content = [] -- The body of the modal goes in here"
, "\n\t-- Use elements with Button.modal and ClickableText.modal for standardized footer elements"
, "\n\t-- Remember to add an id to the first and final focusable element!"
, "\n\t, footer = [] "
, "\n\t, focusTrap ="
, "\n\t\t{ focus = Focus"
, "\n\t\t, firstId = "
++ (if settings.showX then
Code.string Modal.closeButtonId
else if settings.showContinue then
Code.string continueButtonId
else
Code.string closeClickableTextId
)
, "\n\t\t, lastId ="
++ (if settings.showSecondary then
Code.string closeClickableTextId
else if settings.showContinue then
Code.string continueButtonId
else
Code.string Modal.closeButtonId
)
, "\n\t\t}"
, "\n\t}"
, [ if settings.showX then
Just "Modal.closeButton"
else
Nothing
, Maybe.map Tuple.first settings.titleVisibility
, Maybe.map Tuple.first settings.theme
, Maybe.map Tuple.first settings.customCss
]
|> List.filterMap identity
|> ControlView.codeFromListSimple
, "\n\t-- you should use the actual state, NEVER hardcode it open like this:"
, "\n\t(Modal.open { startFocusOn = \"\", returnFocusTo = \"\"} |> Tuple.first)"
]
|> String.join ""
in
[ { sectionName = "Example", code = code } ]
}
, launchModalButton settings
, Modal.view
@ -234,18 +285,16 @@ example =
Modal.closeButtonId
}
}
(if settings.showX then
[ Modal.closeButton
, settings.titleVisibility
, settings.theme
, settings.customCss
]
([ if settings.showX then
Just Modal.closeButton
else
[ settings.titleVisibility
, settings.theme
, settings.customCss
]
else
Nothing
, Maybe.map Tuple.second settings.titleVisibility
, Maybe.map Tuple.second settings.theme
, Maybe.map Tuple.second settings.customCss
]
|> List.filterMap identity
)
state.state
]

View File

@ -101,7 +101,7 @@ example =
, update = UpdateSettings
, settings = model
, mainType = "RootHtml.Html ()"
, extraImports = [ "import Http" ]
, extraCode = [ "import Http" ]
, toExampleCode =
\{ page, recoveryText } ->
[ { sectionName = "Example"

View File

@ -117,7 +117,7 @@ view ellieLinkConfig state =
, update = SetSelectionSettings
, settings = state.selectionSettings
, mainType = "Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\_ ->
[ { sectionName = "Example"

View File

@ -70,7 +70,7 @@ example =
, update = ChangeOptions
, settings = state.optionsControl
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\settings ->
[ { sectionName = "view"

View File

@ -63,7 +63,7 @@ example =
, update = UpdateSettings
, settings = state
, mainType = "Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\_ ->
[ { sectionName = "Example"
@ -179,6 +179,10 @@ initControls =
<|
Control.string "The right item must be selected."
)
|> ControlExtra.optionalListItem "disabled"
(Control.value ( "Select.disabled", Select.disabled ))
|> ControlExtra.optionalListItem "loading"
(Control.value ( "Select.loading", Select.loading ))
initChoices : Control ( String, List (Choice String) )

View File

@ -89,7 +89,7 @@ view ellieLinkConfig state =
, update = SetControls
, settings = state.settings
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\{ navAttributes, entries } ->
[ { sectionName = "View"

View File

@ -41,7 +41,7 @@ type alias State =
example : Example State Msg
example =
{ name = "SortableTable"
, version = 2
, version = 3
, categories = [ Layout ]
, keyboardSupport = []
, state = init

View File

@ -57,7 +57,7 @@ example =
, update = UpdateSettings
, settings = state.settings
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\{ label, attributes } ->
[ { sectionName = "Example"

View File

@ -83,7 +83,7 @@ example =
, update = UpdateControl
, settings = state
, mainType = "RootHtml.Html msg"
, extraImports = [ "import Nri.Ui.Button.V10 as Button" ]
, extraCode = [ "import Nri.Ui.Button.V10 as Button" ]
, toExampleCode =
\settings ->
let

View File

@ -115,7 +115,7 @@ example =
, update = SetSettings
, settings = model.settings
, mainType = "RootHtml.Html { select : Int, focus : Maybe String }"
, extraImports = [ "import Nri.Ui.Tooltip.V3 as Tooltip" ]
, extraCode = [ "import Nri.Ui.Tooltip.V3 as Tooltip" ]
, toExampleCode =
\_ ->
let

View File

@ -59,7 +59,7 @@ example =
, update = UpdateControl
, settings = state.control
, mainType = "RootHtml.Html msg"
, extraImports = []
, extraCode = []
, toExampleCode =
\settings ->
let

View File

@ -12,7 +12,7 @@ import Dict exposing (Dict)
import Example exposing (Example)
import Html.Styled as Html
import Html.Styled.Attributes as Attributes exposing (css)
import Nri.Ui.Checkbox.V5 as Checkbox
import Nri.Ui.Checkbox.V6 as Checkbox
import Nri.Ui.Colors.V1 as Colors
import Nri.Ui.Heading.V3 as Heading
import Nri.Ui.InputStyles.V3 as InputStyles exposing (Theme(..))
@ -80,6 +80,9 @@ example =
, selected = state.showLabel
, disabled = False
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
, Checkbox.viewWithLabel
{ identifier = "textarea-autoresize"
@ -88,6 +91,9 @@ example =
, selected = state.autoResize
, disabled = False
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
, Checkbox.viewWithLabel
{ identifier = "textarea-isInError"
@ -96,6 +102,9 @@ example =
, selected = state.isInError
, disabled = False
, theme = Checkbox.Square
, containerCss = []
, enabledLabelCss = []
, disabledLabelCss = []
}
]
, TextArea.view

View File

@ -59,7 +59,7 @@ example =
, update = UpdateControl
, settings = state.control
, mainType = "Html msg"
, extraImports = []
, extraCode = []
, toExampleCode = \_ -> []
}
, Heading.h2 [ Heading.plaintext "Example" ]

View File

@ -472,7 +472,7 @@ viewCustomizableExample ellieLinkConfig controlSettings =
, update = SetControl
, settings = controlSettings
, mainType = "RootHtml.Html msg"
, extraImports = [ "import Nri.Ui.ClickableSvg.V2 as ClickableSvg" ]
, extraCode = [ "import Nri.Ui.ClickableSvg.V2 as ClickableSvg" ]
, toExampleCode =
\controls ->
[ { sectionName = "Example"

View File

@ -59,6 +59,7 @@ all =
, ( "sort", UiIcon.sort, [] )
, ( "gear", UiIcon.gear, [] )
, ( "hamburger", UiIcon.hamburger, [] )
, ( "kebab", UiIcon.kebab, [] )
]
)
, ( "Archive & Unarchive"
@ -114,6 +115,8 @@ all =
, ( "class", UiIcon.class, [] )
, ( "leaderboard", UiIcon.leaderboard, [] )
, ( "graduateCap", UiIcon.graduateCap, [] )
, ( "apple", UiIcon.apple, [] )
, ( "briefcase", UiIcon.briefcase, [] )
]
)
, ( "Time"

View File

@ -25,7 +25,7 @@
"pablohirafuji/elm-markdown": "2.0.5",
"rtfeldman/elm-css": "17.0.5",
"rtfeldman/elm-sorter-experiment": "2.1.1",
"tesk9/accessible-html-with-css": "3.0.0",
"tesk9/accessible-html-with-css": "3.1.0",
"tesk9/palette": "3.0.1",
"wernerdegroot/listzipper": "4.0.0"
},

View File

@ -11,6 +11,7 @@
"Nri.Ui.Button.V10",
"Nri.Ui.Carousel.V1",
"Nri.Ui.Checkbox.V5",
"Nri.Ui.Checkbox.V6",
"Nri.Ui.ClickableSvg.V2",
"Nri.Ui.ClickableText.V3",
"Nri.Ui.Container.V2",