-----------------------------------------------------------------------------
{-# LANGUAGE RecordWildCards #-}
{-# LANGUAGE OverloadedStrings #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  Miso.Native.X.Element.Input.Method
-- Copyright   :  (C) 2016-2026 David M. Johnson
-- License     :  BSD3-style (see the file LICENSE)
-- Maintainer  :  David M. Johnson <code@dmj.io>
-- Stability   :  experimental
-- Portability :  non-portable
----------------------------------------------------------------------------
module Miso.Native.X.Element.Input.Method
  ( -- *** Methods
    focus
  , blur
  , setValue
  , setSelectionRange
  , getValue
    -- *** Types
  , InputValue (..)
  ) where
-----------------------------------------------------------------------------
import Miso hiding (focus, blur, setValue, setSelectionRange)
import Miso.Native.FFI (invokeExec)
-----------------------------------------------------------------------------
-- | Result of calling 'getValue'.
data InputValue
  = InputValue
  { InputValue -> MisoString
value :: MisoString
    -- ^ The current input content
  , InputValue -> Int
selectionStart :: Int
    -- ^ Start position of the selection
  , InputValue -> Int
selectionEnd :: Int
    -- ^ End position of the selection
  , InputValue -> Bool
isComposing :: Bool
    -- ^ Whether the input is mid-composition (IME)
  } deriving (Int -> InputValue -> ShowS
[InputValue] -> ShowS
InputValue -> String
(Int -> InputValue -> ShowS)
-> (InputValue -> String)
-> ([InputValue] -> ShowS)
-> Show InputValue
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> InputValue -> ShowS
showsPrec :: Int -> InputValue -> ShowS
$cshow :: InputValue -> String
show :: InputValue -> String
$cshowList :: [InputValue] -> ShowS
showList :: [InputValue] -> ShowS
Show, InputValue -> InputValue -> Bool
(InputValue -> InputValue -> Bool)
-> (InputValue -> InputValue -> Bool) -> Eq InputValue
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: InputValue -> InputValue -> Bool
== :: InputValue -> InputValue -> Bool
$c/= :: InputValue -> InputValue -> Bool
/= :: InputValue -> InputValue -> Bool
Eq)
-----------------------------------------------------------------------------
instance FromJSVal InputValue where
  fromJSVal :: JSVal -> IO (Maybe InputValue)
fromJSVal JSVal
o = do
    let readProp :: MisoString -> IO b
readProp MisoString
name = JSVal -> IO b
forall a. FromJSVal a => JSVal -> IO a
fromJSValUnchecked (JSVal -> IO b) -> IO JSVal -> IO b
forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< JSVal
o JSVal -> MisoString -> IO JSVal
forall o. ToObject o => o -> MisoString -> IO JSVal
! (MisoString
name :: MisoString)
    value          <- MisoString -> IO MisoString
forall {b}. FromJSVal b => MisoString -> IO b
readProp MisoString
"value"
    selectionStart <- readProp "selectionStart"
    selectionEnd   <- readProp "selectionEnd"
    isComposing    <- readProp "isComposing"
    pure $ Just InputValue {..}
-----------------------------------------------------------------------------
-- | Params object for 'setValue'.
newtype SetValue = SetValue MisoString
-----------------------------------------------------------------------------
instance ToJSVal SetValue where
  toJSVal :: SetValue -> IO JSVal
toJSVal (SetValue MisoString
v) = do
    o <- IO Object
create
    set "value" v o
    toJSVal o
-----------------------------------------------------------------------------
-- | Params object for 'setSelectionRange'.
data SetSelectionRange = SetSelectionRange Int Int
-----------------------------------------------------------------------------
instance ToJSVal SetSelectionRange where
  toJSVal :: SetSelectionRange -> IO JSVal
toJSVal (SetSelectionRange Int
s Int
e) = do
    o <- IO Object
create
    set "selectionStart" s o
    set "selectionEnd" e o
    toJSVal o
-----------------------------------------------------------------------------
-- | https://lynxjs.org/api/elements/built-in/input.html#focus
--
-- Requests focus for the selected \<input\>.
--
-- > focus "#myInput" Focused FocusFailed
--
focus
  :: MisoString
  -> action
  -> (MisoString -> action)
  -> Effect context props model action
focus :: forall action context props model.
MisoString
-> action
-> (MisoString -> action)
-> Effect context props model action
focus MisoString
selector action
action = MisoString
-> MisoString
-> ()
-> (() -> action)
-> (MisoString -> action)
-> Effect context props model action
forall params argument action context props model.
(ToJSVal params, FromJSVal argument) =>
MisoString
-> MisoString
-> params
-> (argument -> action)
-> (MisoString -> action)
-> Effect context props model action
invokeExec MisoString
"focus" MisoString
selector () (\() -> action
action)
-----------------------------------------------------------------------------
-- | https://lynxjs.org/api/elements/built-in/input.html#blur
--
-- Releases focus for the selected \<input\>.
--
-- > blur "#myInput" Blurred BlurFailed
--
blur
  :: MisoString
  -> action
  -> (MisoString -> action)
  -> Effect context props model action
blur :: forall action context props model.
MisoString
-> action
-> (MisoString -> action)
-> Effect context props model action
blur MisoString
selector action
action = MisoString
-> MisoString
-> ()
-> (() -> action)
-> (MisoString -> action)
-> Effect context props model action
forall params argument action context props model.
(ToJSVal params, FromJSVal argument) =>
MisoString
-> MisoString
-> params
-> (argument -> action)
-> (MisoString -> action)
-> Effect context props model action
invokeExec MisoString
"blur" MisoString
selector () (\() -> action
action)
-----------------------------------------------------------------------------
-- | https://lynxjs.org/api/elements/built-in/input.html#setvalue
--
-- Sets the input content of the selected \<input\>.
--
-- > setValue "#myInput" "hello" ValueSet ValueSetFailed
--
setValue
  :: MisoString
  -> MisoString
  -> action
  -> (MisoString -> action)
  -> Effect context props model action
setValue :: forall action context props model.
MisoString
-> MisoString
-> action
-> (MisoString -> action)
-> Effect context props model action
setValue MisoString
selector MisoString
v action
action =
  MisoString
-> MisoString
-> SetValue
-> (() -> action)
-> (MisoString -> action)
-> Effect context props model action
forall params argument action context props model.
(ToJSVal params, FromJSVal argument) =>
MisoString
-> MisoString
-> params
-> (argument -> action)
-> (MisoString -> action)
-> Effect context props model action
invokeExec MisoString
"setValue" MisoString
selector (MisoString -> SetValue
SetValue MisoString
v) (\() -> action
action)
-----------------------------------------------------------------------------
-- | https://lynxjs.org/api/elements/built-in/input.html#setselectionrange
--
-- Sets the selection range of the selected \<input\>.
--
-- > setSelectionRange "#myInput" 0 3 RangeSet RangeSetFailed
--
setSelectionRange
  :: MisoString
  -> Int
  -> Int
  -> action
  -> (MisoString -> action)
  -> Effect context props model action
setSelectionRange :: forall action context props model.
MisoString
-> Int
-> Int
-> action
-> (MisoString -> action)
-> Effect context props model action
setSelectionRange MisoString
selector Int
s Int
e action
action =
  MisoString
-> MisoString
-> SetSelectionRange
-> (() -> action)
-> (MisoString -> action)
-> Effect context props model action
forall params argument action context props model.
(ToJSVal params, FromJSVal argument) =>
MisoString
-> MisoString
-> params
-> (argument -> action)
-> (MisoString -> action)
-> Effect context props model action
invokeExec MisoString
"setSelectionRange" MisoString
selector (Int -> Int -> SetSelectionRange
SetSelectionRange Int
s Int
e) (\() -> action
action)
-----------------------------------------------------------------------------
-- | https://lynxjs.org/api/elements/built-in/input.html#getvalue
--
-- Retrieves the current value (and selection) of the selected \<input\>.
--
-- > getValue "#myInput" GotValue GetValueFailed
--
getValue
  :: MisoString
  -> (InputValue -> action)
  -> (MisoString -> action)
  -> Effect context props model action
getValue :: forall action context props model.
MisoString
-> (InputValue -> action)
-> (MisoString -> action)
-> Effect context props model action
getValue MisoString
selector = MisoString
-> MisoString
-> ()
-> (InputValue -> action)
-> (MisoString -> action)
-> Effect context props model action
forall params argument action context props model.
(ToJSVal params, FromJSVal argument) =>
MisoString
-> MisoString
-> params
-> (argument -> action)
-> (MisoString -> action)
-> Effect context props model action
invokeExec MisoString
"getValue" MisoString
selector ()
-----------------------------------------------------------------------------