mirror of
https://github.com/NoRedInk/noredink-ui.git
synced 2024-11-22 05:42:50 +03:00
Merge pull request #1154 from NoRedInk/perk/hackday-2022-11-04-regexes
use one pattern for generating IDs
This commit is contained in:
commit
4cca69a123
@ -23,6 +23,7 @@ import Html.Styled.Attributes as Attributes
|
||||
import KeyboardSupport exposing (Key(..))
|
||||
import Nri.Ui.Carousel.V1 as Carousel
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Html.Attributes.V2 as Attributes
|
||||
import Task
|
||||
|
||||
|
||||
@ -217,11 +218,11 @@ toCarouselItem : Int -> a -> ( String, Carousel.Item Int msg )
|
||||
toCarouselItem id _ =
|
||||
let
|
||||
idString =
|
||||
String.fromInt id
|
||||
Attributes.safeIdWithPrefix "slide" <| String.fromInt id
|
||||
in
|
||||
( [ "Carousel.buildItem"
|
||||
, " { id = " ++ idString
|
||||
, " , idString = \"" ++ idString ++ "-slide\""
|
||||
, " { id = " ++ String.fromInt id
|
||||
, " , idString = \"" ++ idString ++ "\""
|
||||
, " , controlHtml = Html.text \"" ++ String.fromInt (id + 1) ++ "\""
|
||||
, " , slideHtml = Html.text \"" ++ String.fromInt (id + 1) ++ " slide\""
|
||||
, " }"
|
||||
@ -229,7 +230,7 @@ toCarouselItem id _ =
|
||||
|> String.join "\n "
|
||||
, Carousel.buildItem
|
||||
{ id = id
|
||||
, idString = String.fromInt id ++ "-slide"
|
||||
, idString = idString
|
||||
, controlHtml = Html.text (String.fromInt (id + 1))
|
||||
, slideHtml = Html.text (String.fromInt (id + 1) ++ " slide")
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import Example exposing (Example)
|
||||
import Html.Styled.Attributes as Attributes
|
||||
import Nri.Ui.BreadCrumbs.V2 as BreadCrumbs exposing (BreadCrumbs)
|
||||
import Nri.Ui.Header.V1 as Header
|
||||
import Nri.Ui.Util exposing (dashify)
|
||||
import Nri.Ui.Html.Attributes.V2 exposing (safeIdWithPrefix)
|
||||
import Parser exposing ((|.), (|=), Parser)
|
||||
import Url exposing (Url)
|
||||
|
||||
@ -168,7 +168,7 @@ categoryCrumb category_ =
|
||||
doodadCrumb : BreadCrumbs (Route state msg) -> Example state msg -> BreadCrumbs (Route state msg)
|
||||
doodadCrumb previous example =
|
||||
BreadCrumbs.after previous
|
||||
{ id = "breadcrumbs__" ++ dashify example.name
|
||||
{ id = safeIdWithPrefix "breadcrumbs" example.name
|
||||
, text = Example.fullName example
|
||||
, route = Doodad example
|
||||
}
|
||||
|
@ -65,7 +65,6 @@ import Nri.Ui.FocusRing.V1 as FocusRing
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Html.Attributes.V2 as Extra
|
||||
import Nri.Ui.Svg.V1 exposing (Svg)
|
||||
import Nri.Ui.Util as Util
|
||||
|
||||
|
||||
{-| This disables the input
|
||||
@ -233,7 +232,7 @@ view { label, selected } attributes =
|
||||
specificId
|
||||
|
||||
Nothing ->
|
||||
"checkbox-v7-" ++ Util.safeIdString label
|
||||
Extra.safeIdWithPrefix "checkbox-v7" label
|
||||
|
||||
config_ =
|
||||
{ identifier = idValue
|
||||
|
@ -3,6 +3,7 @@ module Nri.Ui.Html.Attributes.V2 exposing
|
||||
, targetBlank
|
||||
, nriDescription, nriDescriptionSelector
|
||||
, testId
|
||||
, safeIdWithPrefix, safeId
|
||||
)
|
||||
|
||||
{-|
|
||||
@ -21,6 +22,7 @@ This is the new version of Nri.Ui.Html.Attributes.Extra.
|
||||
@docs targetBlank
|
||||
@docs nriDescription, nriDescriptionSelector
|
||||
@docs testId
|
||||
@docs safeIdWithPrefix, safeId
|
||||
|
||||
-}
|
||||
|
||||
@ -29,6 +31,7 @@ import Css.Global
|
||||
import Html.Styled exposing (Attribute)
|
||||
import Html.Styled.Attributes as Attributes
|
||||
import Json.Encode as Encode
|
||||
import Regex exposing (Regex)
|
||||
|
||||
|
||||
{-| Represents an attribute with no semantic meaning, useful for conditionals.
|
||||
@ -103,3 +106,47 @@ nriDescription description =
|
||||
nriDescriptionSelector : String -> List Css.Style -> Css.Global.Snippet
|
||||
nriDescriptionSelector description =
|
||||
Css.Global.selector (String.join "" [ "[data-nri-description=\"", description, "\"]" ])
|
||||
|
||||
|
||||
{-| Prepends a prefix to the result of safeId.
|
||||
-}
|
||||
safeIdWithPrefix : String -> String -> String
|
||||
safeIdWithPrefix prefix string =
|
||||
safeId
|
||||
(prefix
|
||||
++ "-"
|
||||
++ string
|
||||
)
|
||||
|
||||
|
||||
{-| Creates a lowercased string that is safe to use for HTML IDs.
|
||||
Removes all groups of unsafe characters and replaces each group with a dash.
|
||||
prepends "id-" to the result to ensure that the ID starts with a letter. (necessary for CSS selectors including getElementById)
|
||||
See code pen for examples: <https://codepen.io/ap-nri/pen/OJENQLY>
|
||||
-}
|
||||
safeId : String -> String
|
||||
safeId unsafe =
|
||||
let
|
||||
nonAlphaNumUnderscoreHyphenAnywhere : Regex
|
||||
nonAlphaNumUnderscoreHyphenAnywhere =
|
||||
-- any contiguous block of characters that aren't any of
|
||||
-- + ASCII letters
|
||||
-- + numbers
|
||||
-- + underscore
|
||||
-- + the hyphen-minus character commonly called "dash" (seen in between "hyphen" and "minus" on this line)
|
||||
-- This does not need the + at the end; Regex.replace is global by default
|
||||
-- but we pay a penalty for calling the replacement function, so
|
||||
-- calling it once per contiguous group is an easy way to cut down on that.
|
||||
"[^a-zA-Z0-9_-]+"
|
||||
|> Regex.fromString
|
||||
|> Maybe.withDefault Regex.never
|
||||
|
||||
hyphenMinus : any -> String
|
||||
hyphenMinus _ =
|
||||
"-"
|
||||
in
|
||||
"id-"
|
||||
++ Regex.replace
|
||||
nonAlphaNumUnderscoreHyphenAnywhere
|
||||
hyphenMinus
|
||||
unsafe
|
||||
|
@ -53,9 +53,6 @@ import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Html.Attributes.V2 as Extra
|
||||
import Nri.Ui.Pennant.V2 exposing (premiumFlag)
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.Util exposing (removePunctuation)
|
||||
import String exposing (toLower)
|
||||
import String.Extra exposing (dasherize)
|
||||
|
||||
|
||||
{-| Set a custom ID for this checkbox and label. If you don't set this,
|
||||
@ -205,7 +202,7 @@ view { label, onChange } attributes =
|
||||
specificId
|
||||
|
||||
Nothing ->
|
||||
"checkbox-" ++ dasherize (removePunctuation (toLower label))
|
||||
Extra.safeIdWithPrefix "checkbox" label
|
||||
|
||||
isPremium =
|
||||
config.premiumDisplay /= PremiumDisplay.Free
|
||||
|
@ -63,7 +63,6 @@ import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Html.Attributes.V2 as Extra
|
||||
import Nri.Ui.Pennant.V2 as Pennant
|
||||
import Nri.Ui.Svg.V1 exposing (Svg)
|
||||
import Nri.Ui.Util as Util
|
||||
import Svg.Styled as Svg
|
||||
import Svg.Styled.Attributes as SvgAttributes
|
||||
|
||||
@ -277,7 +276,7 @@ view { label, name, value, valueToString, selectedValue } attributes =
|
||||
specificId
|
||||
|
||||
Nothing ->
|
||||
name ++ "-" ++ Util.safeIdString stringValue
|
||||
Extra.safeId (name ++ "-" ++ stringValue)
|
||||
|
||||
isChecked =
|
||||
selectedValue == Just value
|
||||
|
@ -31,9 +31,9 @@ import Nri.Ui.Colors.Extra as ColorsExtra
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.FocusRing.V1 as FocusRing
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Html.Attributes.V2 exposing (safeId)
|
||||
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
|
||||
import Nri.Ui.Tooltip.V3 as Tooltip
|
||||
import Nri.Ui.Util exposing (dashify)
|
||||
import TabsInternal.V2 as TabsInternal
|
||||
|
||||
|
||||
@ -132,7 +132,7 @@ viewRadioGroup config =
|
||||
)
|
||||
|
||||
name =
|
||||
dashify (String.toLower config.legend)
|
||||
safeId config.legend
|
||||
|
||||
legendId =
|
||||
"legend-" ++ name
|
||||
|
@ -59,7 +59,6 @@ import Nri.Ui.CssVendorPrefix.V1 as VendorPrefixed
|
||||
import Nri.Ui.Fonts.V1 as Fonts
|
||||
import Nri.Ui.Html.Attributes.V2 as Extra
|
||||
import Nri.Ui.InputStyles.V4 as InputStyles
|
||||
import Nri.Ui.Util
|
||||
import SolidColor
|
||||
|
||||
|
||||
@ -475,8 +474,8 @@ viewChoice current choice =
|
||||
{-| Pass in the label to generate the default DOM element id used by a `Select.view` with the given label.
|
||||
-}
|
||||
generateId : String -> String
|
||||
generateId x =
|
||||
"nri-select-" ++ Nri.Ui.Util.dashify (Nri.Ui.Util.removePunctuation x)
|
||||
generateId =
|
||||
Extra.safeIdWithPrefix "nri-select"
|
||||
|
||||
|
||||
selectArrowsCss : { config | disabled : Bool } -> Css.Style
|
||||
|
@ -66,7 +66,6 @@ import Nri.Ui.Html.Attributes.V2 as Extra
|
||||
import Nri.Ui.Html.V3 exposing (viewJust)
|
||||
import Nri.Ui.InputStyles.V4 as InputStyles
|
||||
import Nri.Ui.Svg.V1 as Svg exposing (Svg)
|
||||
import Nri.Ui.Util
|
||||
import SolidColor
|
||||
|
||||
|
||||
@ -544,7 +543,7 @@ viewChoice current choice =
|
||||
-}
|
||||
generateId : String -> String
|
||||
generateId x =
|
||||
"nri-select-" ++ String.toLower (Nri.Ui.Util.dashify (Nri.Ui.Util.removePunctuation x))
|
||||
Extra.safeIdWithPrefix "nri-select-" x
|
||||
|
||||
|
||||
selectArrowsCss : { config | disabled : Bool } -> Css.Style
|
||||
|
@ -92,7 +92,6 @@ import InputLabelInternal
|
||||
import Nri.Ui.Colors.V1 as Colors
|
||||
import Nri.Ui.Html.Attributes.V2 as Extra
|
||||
import Nri.Ui.InputStyles.V4 as InputStyles exposing (Theme(..))
|
||||
import Nri.Ui.Util exposing (dashify, removePunctuation)
|
||||
|
||||
|
||||
{-| This is private. The public API only exposes `Attribute`.
|
||||
@ -458,5 +457,5 @@ writingSingleLineHeight =
|
||||
|
||||
{-| -}
|
||||
generateId : String -> String
|
||||
generateId labelText =
|
||||
"nri-ui-text-area-" ++ (dashify <| removePunctuation labelText)
|
||||
generateId =
|
||||
Extra.safeIdWithPrefix "nri-ui-text-area"
|
||||
|
@ -72,7 +72,6 @@ import Nri.Ui.Html.Attributes.V2 as Extra
|
||||
import Nri.Ui.InputStyles.V4 as InputStyles exposing (defaultMarginTop)
|
||||
import Nri.Ui.Svg.V1 as Svg
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
import Nri.Ui.Util exposing (dashify)
|
||||
import Time
|
||||
|
||||
|
||||
@ -982,8 +981,8 @@ view label attributes =
|
||||
This is for use when you need the DOM element id for use in javascript (such as trigger an event to focus a particular text input)
|
||||
-}
|
||||
generateId : String -> String
|
||||
generateId labelText =
|
||||
"Nri-Ui-TextInput-" ++ dashify labelText
|
||||
generateId =
|
||||
Extra.safeIdWithPrefix "Nri-Ui-TextInput"
|
||||
|
||||
|
||||
type alias FloatingContentConfig msg =
|
||||
|
@ -96,7 +96,6 @@ import Nri.Ui.Html.Attributes.V2 as ExtraAttributes
|
||||
import Nri.Ui.MediaQuery.V1 as MediaQuery exposing (mobileBreakpoint, narrowMobileBreakpoint, quizEngineBreakpoint)
|
||||
import Nri.Ui.Shadows.V1 as Shadows
|
||||
import Nri.Ui.UiIcon.V1 as UiIcon
|
||||
import Nri.Ui.Util as Util
|
||||
import Nri.Ui.WhenFocusLeaves.V1 as WhenFocusLeaves
|
||||
|
||||
|
||||
@ -883,7 +882,7 @@ viewToggleTip : { label : String, lastId : Maybe String } -> List (Attribute msg
|
||||
viewToggleTip { label, lastId } attributes_ =
|
||||
let
|
||||
id =
|
||||
Util.safeIdString label
|
||||
ExtraAttributes.safeId label
|
||||
|
||||
triggerId =
|
||||
"tooltip-trigger__" ++ id
|
||||
|
@ -1,89 +0,0 @@
|
||||
module Nri.Ui.Util exposing (dashify, removePunctuation, safeIdString)
|
||||
|
||||
import Regex exposing (Regex)
|
||||
|
||||
|
||||
{-| Convenience method for going from a string with spaces to a string with dashes.
|
||||
-}
|
||||
dashify : String -> String
|
||||
dashify =
|
||||
let
|
||||
regex =
|
||||
Regex.fromString " "
|
||||
|> Maybe.withDefault Regex.never
|
||||
in
|
||||
Regex.replace regex (always "-")
|
||||
|
||||
|
||||
{-| Convenience method for removing punctuation
|
||||
(removes everything that isn't whitespace, alphanumeric, or an underscore).
|
||||
-}
|
||||
removePunctuation : String -> String
|
||||
removePunctuation =
|
||||
let
|
||||
regex =
|
||||
Regex.fromString "[^A-Za-z0-9\\w\\s]"
|
||||
|> Maybe.withDefault Regex.never
|
||||
in
|
||||
Regex.replace regex (always "")
|
||||
|
||||
|
||||
{-| Creates a lowercased string that is safe to use for HTML IDs.
|
||||
Ensures that nonletter characters are cut from the front and replaces bad characters with a dash
|
||||
-}
|
||||
safeIdString : String -> String
|
||||
safeIdString =
|
||||
let
|
||||
nonAlphaAtStart =
|
||||
-- From the start of the string, match the contiguous block of
|
||||
-- not ASCII letters at the start of the String.
|
||||
-- Why [a-zA-Z] and not [A-z]?
|
||||
-- There are punctuation characters in that range: [\]^_` all come after Z and before a
|
||||
"^[^a-zA-Z]+"
|
||||
|
||||
nonAlphaNumUnderscoreHyphenAnywhere =
|
||||
-- any contiguous block of characters that aren't any of
|
||||
-- + ASCII letters
|
||||
-- + numbers
|
||||
-- + underscore
|
||||
-- + the hyphen-minus character commonly called "dash" (seen in between "hyphen" and "minus" on this line)
|
||||
-- This does not need the + at the end; Regex.replace is global by default
|
||||
-- but we pay a penalty for calling the replacement function, so
|
||||
-- calling it once per contiguous group is an easy way to cut down on that.
|
||||
"[^a-zA-Z0-9_-]+"
|
||||
|
||||
anyOfThese strs =
|
||||
"(" ++ String.join "|" strs ++ ")"
|
||||
|
||||
unsafeChar =
|
||||
[ nonAlphaAtStart
|
||||
, nonAlphaNumUnderscoreHyphenAnywhere
|
||||
]
|
||||
|> anyOfThese
|
||||
|> regexFromString
|
||||
|
||||
nonAlphaNumAtEnd =
|
||||
-- any contiguous block of letters that aren't any of
|
||||
-- + ASCII letters
|
||||
-- + numbers
|
||||
regexFromString "[^a-zA-Z0-9]+$"
|
||||
|
||||
collapsePunctuationToOne =
|
||||
regexFromString "[_-]+"
|
||||
in
|
||||
Regex.replace nonAlphaNumAtEnd (always "")
|
||||
>> Regex.replace unsafeChar
|
||||
(\{ index } ->
|
||||
if index == 0 then
|
||||
""
|
||||
|
||||
else
|
||||
"-"
|
||||
)
|
||||
>> Regex.replace collapsePunctuationToOne (always "-")
|
||||
>> String.toLower
|
||||
|
||||
|
||||
regexFromString : String -> Regex
|
||||
regexFromString =
|
||||
Regex.fromString >> Maybe.withDefault Regex.never
|
@ -16,7 +16,6 @@ import Html.Styled.Events as Events
|
||||
import Html.Styled.Keyed as Keyed
|
||||
import Json.Decode
|
||||
import Nri.Ui.Html.Attributes.V2 as AttributesExtra
|
||||
import Nri.Ui.Util exposing (dashify)
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -53,7 +52,7 @@ viewTabs : Config id msg -> Html msg
|
||||
viewTabs config =
|
||||
Html.div
|
||||
[ Role.tabList
|
||||
, Aria.owns (List.map (tabToId << .idString) config.tabs)
|
||||
, Aria.owns (List.map (AttributesExtra.safeId << .idString) config.tabs)
|
||||
, Attributes.css config.tabListStyles
|
||||
]
|
||||
(List.map (viewTab_ config) config.tabs)
|
||||
@ -103,7 +102,7 @@ viewTab_ config tab =
|
||||
, Aria.selected isSelected
|
||||
, Role.tab
|
||||
, Aria.controls [ tabToBodyId tab.idString ]
|
||||
, Attributes.id (tabToId tab.idString)
|
||||
, Attributes.id (AttributesExtra.safeId tab.idString)
|
||||
, Events.onFocus (config.onSelect tab.id)
|
||||
, Events.on "keyup" <|
|
||||
Json.Decode.andThen (keyEvents config tab) Events.keyCode
|
||||
@ -121,7 +120,7 @@ keyEvents { onFocus, tabs } thisTab keyCode =
|
||||
acc
|
||||
|
||||
( True, Nothing ) ->
|
||||
( True, Just (tabToId tab.idString) )
|
||||
( True, Just (AttributesExtra.safeId tab.idString) )
|
||||
|
||||
( False, Nothing ) ->
|
||||
( tab.id == thisTab.id, Nothing )
|
||||
@ -173,7 +172,7 @@ viewTabPanel : Tab id msg -> Bool -> Html msg
|
||||
viewTabPanel tab selected =
|
||||
Html.div
|
||||
([ Role.tabPanel
|
||||
, Aria.labelledBy (tabToId tab.idString)
|
||||
, Aria.labelledBy (AttributesExtra.safeId tab.idString)
|
||||
, Attributes.id (tabToBodyId tab.idString)
|
||||
]
|
||||
++ (if selected then
|
||||
@ -191,16 +190,11 @@ viewTabPanel tab selected =
|
||||
[ tab.panelView ]
|
||||
|
||||
|
||||
tabToId : String -> String
|
||||
tabToId tab =
|
||||
dashify (String.toLower tab)
|
||||
|
||||
|
||||
tabToBodyId : String -> String
|
||||
tabToBodyId tab =
|
||||
"tab-body-" ++ tabToId tab
|
||||
tabToBodyId =
|
||||
AttributesExtra.safeIdWithPrefix "tab-body"
|
||||
|
||||
|
||||
tabToKeyedNode : String -> String
|
||||
tabToKeyedNode tab =
|
||||
"tabs-internal-keyed-node-" ++ tabToId tab
|
||||
tabToKeyedNode =
|
||||
AttributesExtra.safeIdWithPrefix "tabs-internal-keyed-node"
|
||||
|
@ -20,9 +20,8 @@ import Html.Styled.Attributes as Attributes
|
||||
import Html.Styled.Events as Events
|
||||
import Html.Styled.Keyed as Keyed
|
||||
import Nri.Ui.FocusRing.V1 as FocusRing
|
||||
import Nri.Ui.Html.Attributes.V2 as AttributesExtra
|
||||
import Nri.Ui.Html.Attributes.V2 as AttributesExtra exposing (safeId, safeIdWithPrefix)
|
||||
import Nri.Ui.Tooltip.V3 as Tooltip
|
||||
import Nri.Ui.Util exposing (dashify)
|
||||
|
||||
|
||||
{-| -}
|
||||
@ -93,7 +92,7 @@ viewTabs config =
|
||||
Html.div []
|
||||
[ Html.div
|
||||
[ Role.tabList
|
||||
, Aria.owns (List.map (tabToId << .idString) config.tabs)
|
||||
, Aria.owns (List.map (safeId << .idString) config.tabs)
|
||||
]
|
||||
[]
|
||||
, Html.div [ Attributes.css config.tabListStyles ]
|
||||
@ -161,7 +160,7 @@ viewTab_ config index tab =
|
||||
, Aria.selected isSelected
|
||||
, Role.tab
|
||||
, Aria.controls [ tabToBodyId tab.idString ]
|
||||
, Attributes.id (tabToId tab.idString)
|
||||
, Attributes.id (safeId tab.idString)
|
||||
, Key.onKeyUpPreventDefault (keyEvents config tab)
|
||||
]
|
||||
++ (case tab.labelledBy of
|
||||
@ -193,7 +192,7 @@ viewTab_ config index tab =
|
||||
|
||||
( Nothing, tooltipAttributes ) ->
|
||||
Tooltip.view
|
||||
{ id = "tab-tooltip__" ++ tabToId tab.idString
|
||||
{ id = safeIdWithPrefix "tab-tooltip" tab.idString
|
||||
, trigger = \eventHandlers -> buttonOrLink eventHandlers
|
||||
}
|
||||
([ Tooltip.smallPadding
|
||||
@ -209,7 +208,7 @@ keyEvents { focusAndSelect, tabs } thisTab =
|
||||
let
|
||||
onFocus : Tab id msg -> msg
|
||||
onFocus tab =
|
||||
focusAndSelect { select = tab.id, focus = Just (tabToId tab.idString) }
|
||||
focusAndSelect { select = tab.id, focus = Just (safeId tab.idString) }
|
||||
|
||||
findAdjacentTab : Tab id msg -> ( Bool, Maybe msg ) -> ( Bool, Maybe msg )
|
||||
findAdjacentTab tab ( isAdjacentTab, acc ) =
|
||||
@ -265,7 +264,7 @@ viewTabPanel : Tab id msg -> Bool -> Html msg
|
||||
viewTabPanel tab selected =
|
||||
Html.div
|
||||
([ Role.tabPanel
|
||||
, Aria.labelledBy (tabToId tab.idString)
|
||||
, Aria.labelledBy (safeId tab.idString)
|
||||
, Attributes.id (tabToBodyId tab.idString)
|
||||
, Attributes.tabindex 0
|
||||
, Attributes.class FocusRing.customClass
|
||||
@ -287,16 +286,11 @@ viewTabPanel tab selected =
|
||||
[ tab.panelView ]
|
||||
|
||||
|
||||
tabToId : String -> String
|
||||
tabToId tab =
|
||||
dashify (String.toLower tab)
|
||||
|
||||
|
||||
tabToBodyId : String -> String
|
||||
tabToBodyId tab =
|
||||
"tab-body-" ++ tabToId tab
|
||||
tabToBodyId =
|
||||
safeIdWithPrefix "tab-body"
|
||||
|
||||
|
||||
tabToKeyedNode : String -> String
|
||||
tabToKeyedNode tab =
|
||||
"tabs-internal-keyed-node-" ++ tabToId tab
|
||||
tabToKeyedNode =
|
||||
safeIdWithPrefix "tabs-internal-keyed-node"
|
||||
|
29
tests/Spec/Nri/Ui/Html/Attributes.elm
Normal file
29
tests/Spec/Nri/Ui/Html/Attributes.elm
Normal file
@ -0,0 +1,29 @@
|
||||
module Spec.Nri.Ui.Html.Attributes exposing (spec)
|
||||
|
||||
import Expect
|
||||
import Nri.Ui.Html.Attributes.V2 as Attributes
|
||||
import Test exposing (..)
|
||||
|
||||
|
||||
spec : Test
|
||||
spec =
|
||||
describe "Nri.Ui.Html.Attributes"
|
||||
[ describe "safeId transforms strings as expected"
|
||||
[ test "with an apostrophe and multiple spaces" <|
|
||||
\() ->
|
||||
Attributes.safeId "Enable text-to-speech for \t Angela's account"
|
||||
|> Expect.equal "id-Enable-text-to-speech-for-Angela-s-account"
|
||||
, test "lotsa hyphens and dashes" <|
|
||||
\() ->
|
||||
Attributes.safeId "--__--hellO----_______---HOw----___---____--ArE------___You___--__--__Today"
|
||||
|> Expect.equal "id---__--hellO----_______---HOw----___---____--ArE------___You___--__--__Today"
|
||||
]
|
||||
, describe "safeIdWithPrefix"
|
||||
[ test "test everything at once" <|
|
||||
\() ->
|
||||
Attributes.safeIdWithPrefix
|
||||
"000321 ¡¡VERY!! unsafe "
|
||||
"0--__--hellO----___!?[]____---HOw----___---____--ArE------___You___--__--__Today?"
|
||||
|> Expect.equal "id-000321-VERY-unsafe--0--__--hellO----___-____---HOw----___---____--ArE------___You___--__--__Today-"
|
||||
]
|
||||
]
|
@ -16,19 +16,19 @@ spec =
|
||||
ungrouped
|
||||
-- first option is selected automatically
|
||||
|> ensureViewHas
|
||||
[ id "nri-select-cat"
|
||||
[ id "id-nri-select--Cat"
|
||||
, selected True
|
||||
, attribute (Attributes.value "Cat")
|
||||
]
|
||||
|> selectAnimal Dog
|
||||
|> ensureViewHas
|
||||
[ id "nri-select-dog"
|
||||
[ id "id-nri-select--Dog"
|
||||
, selected True
|
||||
, attribute (Attributes.value "Dog")
|
||||
]
|
||||
|> selectAnimal Other
|
||||
|> ensureViewHas
|
||||
[ id "nri-select-my-favorite-animal-is-something-else"
|
||||
[ id "id-nri-select--My-favorite-animal-is-something-else"
|
||||
, selected True
|
||||
, attribute (Attributes.value "My favorite animal is something else")
|
||||
]
|
||||
@ -38,25 +38,25 @@ spec =
|
||||
grouped
|
||||
-- first option is selected automatically
|
||||
|> ensureViewHas
|
||||
[ id "nri-select-cat"
|
||||
[ id "id-nri-select--Cat"
|
||||
, selected True
|
||||
, attribute (Attributes.value "Cat")
|
||||
]
|
||||
|> selectAnimal Dog
|
||||
|> ensureViewHas
|
||||
[ id "nri-select-dog"
|
||||
[ id "id-nri-select--Dog"
|
||||
, selected True
|
||||
, attribute (Attributes.value "Dog")
|
||||
]
|
||||
|> selectAnimal Axolotl
|
||||
|> ensureViewHas
|
||||
[ id "nri-select-axolotl"
|
||||
[ id "id-nri-select--Axolotl"
|
||||
, selected True
|
||||
, attribute (Attributes.value "Axolotl")
|
||||
]
|
||||
|> selectAnimal Other
|
||||
|> ensureViewHas
|
||||
[ id "nri-select-my-favorite-animal-is-something-else"
|
||||
[ id "id-nri-select--My-favorite-animal-is-something-else"
|
||||
, selected True
|
||||
, attribute (Attributes.value "My favorite animal is something else")
|
||||
]
|
||||
|
@ -1,44 +0,0 @@
|
||||
module Spec.Nri.Ui.Util exposing (spec)
|
||||
|
||||
import Expect
|
||||
import Nri.Ui.Util as Util
|
||||
import Test exposing (..)
|
||||
|
||||
|
||||
spec : Test
|
||||
spec =
|
||||
describe "Nri.Ui.Util"
|
||||
[ describe "safeIdString transforms strings as expected"
|
||||
[ test "with a comma" <|
|
||||
\() ->
|
||||
Util.safeIdString "Enable text-to-speech for Angela's account"
|
||||
|> Expect.equal "enable-text-to-speech-for-angela-s-account"
|
||||
, test "removes leading non alpha characters" <|
|
||||
\() ->
|
||||
Util.safeIdString "#@!!232now we are in business__--__"
|
||||
|> Expect.equal "now-we-are-in-business"
|
||||
, test "removes trailing non alphanum characters" <|
|
||||
\() ->
|
||||
Util.safeIdString "#@!!232now we are in business__--__123!!@&*%^ @"
|
||||
|> Expect.equal "now-we-are-in-business-123"
|
||||
, test "hard mode" <|
|
||||
\() ->
|
||||
Util.safeIdString "!@#21something else interesting321$ ... hi"
|
||||
|> Expect.equal "something-else-interesting321-hi"
|
||||
, test "with capital letters" <|
|
||||
\() ->
|
||||
Util.safeIdString "1232!@#%#@JFEKLfds-----SFJK3@#@jj23FDS........''''\"\"***"
|
||||
|> Expect.equal "jfeklfds-sfjk3-jj23fds"
|
||||
, test "lotsa hyphens and dashes" <|
|
||||
\() ->
|
||||
Util.safeIdString "--__--hellO----_______---HOw----___---____--ArE------___You___--__--__Today"
|
||||
|> Expect.equal "hello-how-are-you-today"
|
||||
]
|
||||
, describe "removePunctuation"
|
||||
[ test "A string with some punctuation" <|
|
||||
\() ->
|
||||
Util.removePunctuation
|
||||
"To sleep? Perchance: to dream? “Alas poor ‘Yorick’” but he's not `in` _this_ \"[play]\"."
|
||||
|> Expect.equal "To sleep Perchance to dream Alas poor Yorick but hes not in _this_ play"
|
||||
]
|
||||
]
|
Loading…
Reference in New Issue
Block a user