Skip to content

Instantly share code, notes, and snippets.

@Gozala
Last active May 8, 2021 10:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Gozala/7f1e3f63f5711756a4d159c13b96cffd to your computer and use it in GitHub Desktop.
Save Gozala/7f1e3f63f5711756a4d159c13b96cffd to your computer and use it in GitHub Desktop.
module Focus exposing (Model, init, update, onFocus, onBlur, focus, blur) where
import Ref
import Native.Focus
import Html
import Html.Attributes
import Html.Events
type alias Model =
{ ref: Ref.Ref
focused: Bool
}
type Msg
= Focus
| Blur
| Focused
| Blured
| Panic FocusError
init : Bool -> Focus
init focused =
{ ref: {}
, focused = focused
}
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
Focus ->
({ model | focused = true} , (Task.perform (always Focused) Panic (focus model.ref))
Blur ->
({ model | focused = false}, (Task.perform (always Blured) Panic (blur model.ref))
Focused _ ->
({ model | focused = true }, Cmd.none)
Blured _ ->
({ model | focused = false }, Cmd.none)
Panic error ->
(model, Cmd.none)
-- No public API for Html.Attributes.map exists, but there's no reason it could not.
onFocus : (Msg -> taggedMsg) -> Html.Attribute taggedMsg
onFocus tag = Html.Attributes.map tag (Html.Events.onFocus Focused)
onBlur : (Msg -> taggedMsg) -> Html.Attribute taggedMsg
onBlur tag = Html.Attributes.map tag (Html.Events.onBlur Focused)
focus : Ref -> Task FocusError a
focus = Native.Focus.focus
blur : Ref -> Task FocusError a
blur = Native.Focus.blur
-- Embedder of `Focus` is expected to use `model.focus.ref, (Focus.onFocus FocusChange), (Focus.onBlur FocusChange)`
-- in the list of attributes
-- MODEL
type alias Model =
{ content : String
, focus: Focus.Model
}
-- UPDATE
type Msg
= FocusChange Focus.Msg
| Change String
update : Msg -> Model -> (Model, Cmd Msg)
update msg model =
case msg of
FocusChange msg ->
let
(focus, cmd) = Focus.update(model.focus, msg)
in
({ model | focus = focus }, (Cmd.map FocusChange cmd))
Change newContent ->
({ model | content = newContent }, Cmd.none)
-- VIEW
view : Model -> Html Msg
view model =
div []
[ input
[ placeholder "Text to reverse"
, onInput Change
, Ref.ref model.focus.ref
, Focus.onFocus FocusChange
, Focus.onBlur FocusChange
]
[]
, div [] [ text (String.reverse model.content) ]
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment