Skip to content

Commit

Permalink
Merge pull request #3 from insurello/focus
Browse files Browse the repository at this point in the history
Use :focus-visible
  • Loading branch information
lydell authored Feb 6, 2025
2 parents 99d4b26 + a64326d commit 37c4053
Show file tree
Hide file tree
Showing 4 changed files with 65 additions and 7 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,6 @@ Some facts about the fork:

- Based on elm-ui 1.1.7
- Merged Chrome focus fix: https://github.com/mdgriffith/elm-ui/pull/362
- Changed default focus styles from `:focus` to `:focus-visible`.
- Replaced `Element.focused` with `Element.focusedMouseAndKeyboard` (= `:focus`) and `Element.focusedKeyboardOnly` (=
`:focus-visible`).
2 changes: 2 additions & 0 deletions examples/Form.elm
Original file line number Diff line number Diff line change
Expand Up @@ -200,6 +200,8 @@ view model =
, Border.color darkBlue
, paddingXY 32 16
, Border.rounded 3
, Element.focusedMouseAndKeyboard [ Background.color grey ]
, Element.focusedKeyboardOnly [ Background.color red ]

-- , width fill
]
Expand Down
42 changes: 37 additions & 5 deletions src/Element.elm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ module Element exposing
, image
, Color, rgba, rgb, rgb255, rgba255, fromRgb, fromRgb255, toRgb
, above, below, onRight, onLeft, inFront, behindContent
, Attr, Decoration, mouseOver, mouseDown, focused
, Attr, Decoration, mouseOver, mouseDown, focusedMouseAndKeyboard, focusedKeyboardOnly
, Device, DeviceClass(..), Orientation(..), classifyDevice
, modular
, map, mapAttribute
Expand Down Expand Up @@ -182,7 +182,7 @@ This is very useful for things like dropdown menus or tooltips.
# Temporary Styling
@docs Attr, Decoration, mouseOver, mouseDown, focused
@docs Attr, Decoration, mouseOver, mouseDown, focusedMouseAndKeyboard, focusedKeyboardOnly
# Responsiveness
Expand Down Expand Up @@ -1678,9 +1678,41 @@ mouseDown decs =
(Internal.unwrapDecorations decs)


{-| -}
focused : List Decoration -> Attribute msg
focused decs =
{-| This uses `:focus` in CSS. `:focus` applies to anything having focus, regardless of how it was focused:
By clicking with a mouse, by tabbing with a keyboard, or by tapping on a touchscreen.
`focusedMouseAndKeyboard` is not a 100 % accurate name (since it doesn’t mention touch screens or other
input devices), but it’s a simple name that makes things clear enough.
You probably want to use `Element.focusedKeyboardOnly` instead, unless you know that you specifically want
a focus indicator regardless of input device in your case.
This is called `Element.focused` in the original elm-ui.
-}
focusedMouseAndKeyboard : List Decoration -> Attribute msg
focusedMouseAndKeyboard decs =
Internal.StyleClass Flag.focus <|
Internal.PseudoSelector Internal.Focus
(Internal.unwrapDecorations decs)


{-| This uses `:focus-visible` in CSS. `:focus-visible` applies to:
- Elements that were focused with the keyboard.
- Text inputs, regardless of how they were focused. (Because you are expected to use a keyboard there, to type.)
`focusedKeyboardOnly` is not a 100 % accurate name, since it is up to the browser to decide exactly
when it applies, but it’s a simple name that makes things clear enough.
This is the function you probably want to use for focus things. The idea is to display clear focus indicators
for keyboard users, but not for mouse users (who don’t need it) since they are kinda ugly.
This function does not exist in the original elm-ui.
-}
focusedKeyboardOnly : List Decoration -> Attribute msg
focusedKeyboardOnly decs =
Internal.StyleClass Flag.focus <|
Internal.PseudoSelector Internal.FocusVisible
(Internal.unwrapDecorations decs)
25 changes: 23 additions & 2 deletions src/Internal/Model.elm
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,7 @@ type Transformation

type PseudoClass
= Focus
| FocusVisible
| Hover
| Active

Expand Down Expand Up @@ -2217,7 +2218,7 @@ renderFocusStyle :
FocusStyle
-> List Style
renderFocusStyle focus =
[ Style (Internal.Style.dot classes.focusedWithin ++ ":focus-within")
[ Style (Internal.Style.dot classes.focusedWithin ++ ":has(:focus-visible)")
(List.filterMap identity
[ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
, Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
Expand All @@ -2242,7 +2243,7 @@ renderFocusStyle focus =
, Just <| Property "outline" "none"
]
)
, Style ("label" ++ Internal.Style.dot classes.any ++ ":focus .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus")
, Style ("label" ++ Internal.Style.dot classes.any ++ ":focus-visible .focusable, " ++ Internal.Style.dot classes.any ++ ".focusable:focus-visible")
(List.filterMap identity
[ Maybe.map (\color -> Property "border-color" (formatColor color)) focus.borderColor
, Maybe.map (\color -> Property "background-color" (formatColor color)) focus.backgroundColor
Expand Down Expand Up @@ -2655,6 +2656,23 @@ renderStyle options maybePseudo selector props =
++ "\n}"
]

FocusVisible ->
let
renderedProps =
List.foldl (renderProps False) "" props
in
[ selector ++ "-fsv:focus-visible {" ++ renderedProps ++ "\n}"
, ("." ++ classes.any ++ ":focus-visible " ++ selector ++ "-fsv {")
++ renderedProps
++ "\n}"
, (selector ++ "-fsv:has(:focus-visible) {")
++ renderedProps
++ "\n}"
, (".focusable-parent:focus-visible ~ " ++ "." ++ classes.any ++ " " ++ selector ++ "-fsv {")
++ renderedProps
++ "\n}"
]

Active ->
[ selector ++ "-act:active {" ++ List.foldl (renderProps False) "" props ++ "\n}" ]

Expand Down Expand Up @@ -3264,6 +3282,9 @@ getStyleName style =
Focus ->
"fs"

FocusVisible ->
"fsv"

Hover ->
"hv"

Expand Down

0 comments on commit 37c4053

Please sign in to comment.