11module Ocelot.Components.MultiInput.Component
2- ( Output (..)
2+ ( HTMLEvents (..)
3+ , Input
4+ , Output (..)
35 , Query (..)
46 , Slot
57 , component
@@ -25,6 +27,7 @@ import Type.Proxy (Proxy(..))
2527import Web.Event.Event as Web.Event.Event
2628import Web.HTML.HTMLElement as Web.HTML.HTMLElement
2729import Web.UIEvent.KeyboardEvent as Web.UIEvent.KeyboardEvent
30+ import Web.UIEvent.MouseEvent as Web.UIEvent.MouseEvent
2831
2932type Slot = Halogen.Slot Query Output
3033
@@ -58,14 +61,17 @@ data Action
5861 = EditItem Int
5962 | Initialize
6063 | OnBlur Int
64+ | OnFocus Int
6165 | OnInput Int String
6266 | OnKeyDown Int Web.UIEvent.KeyboardEvent.KeyboardEvent
67+ | OnMouseDown Int Web.UIEvent.MouseEvent.MouseEvent
6368 | Receive Input
6469 | RemoveOne Int
6570
6671data Query a
6772 = GetItems (Array String -> a )
6873 | SetItems (Array String ) a
74+ | SelectItem String a
6975
7076-- | * minWidth: minimum width of input box for new item
7177-- | * placeholder: placeholder text in new item input
@@ -81,6 +87,15 @@ type Input =
8187
8288data Output
8389 = ItemsUpdated (Array String ) -- caused by user actions
90+ | ItemRemoved String
91+ | On HTMLEvents
92+
93+ data HTMLEvents
94+ = Blur
95+ | Focus
96+ | KeyDown Web.UIEvent.KeyboardEvent.KeyboardEvent
97+ | MouseDown Web.UIEvent.MouseEvent.MouseEvent
98+ | ValueInput String
8499
85100type ChildSlots =
86101 ( textWidth :: Ocelot.Components.MultiInput.TextWidth.Slot Unit
@@ -155,8 +170,12 @@ handleAction = case _ of
155170 EditItem index -> handleEditItem index
156171 Initialize -> handleInitialize
157172 OnBlur index -> handleOnBlur index
173+ OnFocus index -> handleOnFocus index
158174 OnInput index text -> handleOnInput index text
159175 OnKeyDown index keyboardEvent -> handleOnKeyDown index keyboardEvent
176+ OnMouseDown index mouseEvent -> do
177+ focusItem index
178+ Halogen .raise (On (MouseDown mouseEvent))
160179 Receive input -> handleReceive input
161180 RemoveOne index -> handleRemoveOne index
162181
@@ -172,6 +191,7 @@ handleQuery = case _ of
172191 SetItems items a -> do
173192 handleSetItems items
174193 pure (Just a)
194+ SelectItem text a -> selectItem text $> Just a
175195
176196handleEditItem ::
177197 forall m .
@@ -195,8 +215,8 @@ handleEditItem index = do
195215 $ updateItem index
196216 ( \item -> case item of
197217 Display _ -> Edit { inputBox: { text, width }, previous: text }
198- Edit status -> item
199- New status -> item
218+ Edit _ -> item
219+ New _ -> item
200220 )
201221 Control.Monad.Maybe.Trans .lift
202222 $ focusItem index
@@ -215,6 +235,25 @@ handleOnBlur ::
215235 ComponentM m Unit
216236handleOnBlur index = do
217237 commitEditing index
238+ Halogen .raise (On Blur )
239+
240+ handleOnFocus ::
241+ forall m .
242+ MonadAff m =>
243+ Int ->
244+ ComponentM m Unit
245+ handleOnFocus index = do
246+ old <- Halogen .get
247+ case Data.Array .index old.items index of
248+ Nothing -> pure unit
249+ Just item -> case item of
250+ Display _ -> pure unit
251+ Edit { inputBox: { text } } -> do
252+ Halogen .raise (On (ValueInput text ))
253+ Halogen .raise (On Focus )
254+ New { inputBox: { text }} -> do
255+ Halogen .raise (On (ValueInput text ))
256+ Halogen .raise (On Focus )
218257
219258handleOnInput ::
220259 forall m .
@@ -242,6 +281,7 @@ handleOnInput index text = do
242281 Edit status -> Edit status { inputBox { width = width } }
243282 New status -> New status { inputBox { width = max minWidth width } }
244283 )
284+ Halogen .raise (On (ValueInput text))
245285
246286handleOnKeyDown ::
247287 forall m .
@@ -250,6 +290,7 @@ handleOnKeyDown ::
250290 Web.UIEvent.KeyboardEvent.KeyboardEvent ->
251291 ComponentM m Unit
252292handleOnKeyDown index keyboardEvent = do
293+ Halogen .raise (On (KeyDown keyboardEvent))
253294 case Web.UIEvent.KeyboardEvent .key keyboardEvent of
254295 " Enter" -> do
255296 preventDefault keyboardEvent
@@ -369,7 +410,7 @@ cancelEditing index = do
369410 Display _ -> pure unit
370411 Edit { previous } -> do
371412 void $ updateItem index (\_ -> Display { text: previous })
372- New { inputBox: { text } } -> do
413+ New _ -> do
373414 void $ updateItem index (\_ -> old.new)
374415
375416commitEditing ::
@@ -386,12 +427,13 @@ commitEditing index = do
386427 Control.Monad.Maybe.Trans .lift do
387428 case item of
388429 Display _ -> pure unit
389- Edit { inputBox: { text } }
430+ Edit { inputBox: { text }, previous }
390431 | Data.String .null text -> do
391432 removeItem index
392433 raiseItemUpdated
393434 | otherwise -> do
394435 void $ updateItem index (\_ -> Display { text })
436+ Halogen .raise (ItemRemoved previous)
395437 raiseItemUpdated
396438 New { inputBox: { text } }
397439 | Data.String .null text -> pure unit
@@ -444,14 +486,54 @@ removeItem ::
444486 Int ->
445487 ComponentM m Unit
446488removeItem index = do
447- new <- Halogen .modify \old ->
448- old
449- { items =
450- Data.Array .deleteAt index old.items
451- # fromMaybe old.items
452- }
453- when (Data.Array .null new.items) do
454- appendNewItem
489+ old <- Halogen .get
490+ case Data.Array .index old.items index of
491+ Nothing -> pure unit
492+ Just item -> do
493+ new <-
494+ Halogen .modify
495+ _
496+ { items =
497+ Data.Array .deleteAt index old.items
498+ # fromMaybe old.items
499+ }
500+ case getText item of
501+ Nothing -> pure unit
502+ Just text -> Halogen .raise (ItemRemoved text)
503+ when (Data.Array .null new.items) do
504+ appendNewItem
505+
506+ selectItem ::
507+ forall m .
508+ MonadAff m =>
509+ String ->
510+ ComponentM m Unit
511+ selectItem text = do
512+ old <- Halogen .get
513+ mWidth <- measureTextWidth text
514+ case
515+ {index: _, width: _ }
516+ <$> Data.Array .findIndex isEditable old.items
517+ <*> mWidth
518+ of
519+ Nothing -> pure unit
520+ Just { index, width } -> do
521+ void $ updateItem index
522+ ( \item -> case item of
523+ Display _ -> item
524+ Edit status -> Edit status { inputBox = { width, text } }
525+ New status -> New status { inputBox = { width, text } }
526+ )
527+ commitEditing index
528+ when (isLastIndex index old.items) do
529+ new <- Halogen .get
530+ focusItem (getLastIndex new.items)
531+ where
532+ isEditable :: InputStatus -> Boolean
533+ isEditable = case _ of
534+ Display _ -> false
535+ Edit _ -> true
536+ New _ -> true
455537
456538updateItem ::
457539 forall m .
@@ -554,7 +636,9 @@ renderAutoSizeInput placeholder index new inputBox =
554636 [ Halogen.HTML.Properties .attr (Halogen.HTML.AttrName " style" ) css
555637 , Halogen.HTML.Properties .classes inputClasses
556638 , Halogen.HTML.Events .onBlur \_ -> OnBlur index
639+ , Halogen.HTML.Events .onFocus \_ -> OnFocus index
557640 , Halogen.HTML.Events .onKeyDown (OnKeyDown index)
641+ , Halogen.HTML.Events .onMouseDown (OnMouseDown index)
558642 , Halogen.HTML.Events .onValueInput (OnInput index)
559643 , Halogen.HTML.Properties .placeholder case new of
560644 false -> " "
0 commit comments