Use same indent level for 'where' clause and code
This commit is contained in:
parent
1c21d4ceba
commit
9a86b1295f
2 changed files with 185 additions and 185 deletions
examples/Components
|
@ -33,53 +33,53 @@ type Input =
|
|||
|
||||
component :: H.Component HH.HTML S.Query' Input Message Aff
|
||||
component = S.component input $ S.defaultSpec
|
||||
{ render = render
|
||||
, handleMessage = handleMessage
|
||||
}
|
||||
{ render = render
|
||||
, handleMessage = handleMessage
|
||||
}
|
||||
where
|
||||
input :: Input -> S.Input State
|
||||
input { items, buttonLabel } =
|
||||
{ inputType: S.Toggle
|
||||
, search: Nothing
|
||||
, debounceTime: Nothing
|
||||
, getItemCount: length <<< _.items
|
||||
, items
|
||||
, buttonLabel
|
||||
, selection: Nothing
|
||||
}
|
||||
input :: Input -> S.Input State
|
||||
input { items, buttonLabel } =
|
||||
{ inputType: S.Toggle
|
||||
, search: Nothing
|
||||
, debounceTime: Nothing
|
||||
, getItemCount: length <<< _.items
|
||||
, items
|
||||
, buttonLabel
|
||||
, selection: Nothing
|
||||
}
|
||||
|
||||
handleMessage :: S.Message -> H.HalogenM (S.State State) S.Action' () Message Aff Unit
|
||||
handleMessage = case _ of
|
||||
S.Selected ix -> do
|
||||
st <- H.get
|
||||
let selection = st.items !! ix
|
||||
H.modify_ _ { selection = selection, visibility = S.Off }
|
||||
H.raise $ SelectionChanged st.selection selection
|
||||
_ -> pure unit
|
||||
handleMessage :: S.Message -> H.HalogenM (S.State State) S.Action' () Message Aff Unit
|
||||
handleMessage = case _ of
|
||||
S.Selected ix -> do
|
||||
st <- H.get
|
||||
let selection = st.items !! ix
|
||||
H.modify_ _ { selection = selection, visibility = S.Off }
|
||||
H.raise $ SelectionChanged st.selection selection
|
||||
_ -> pure unit
|
||||
|
||||
render :: S.State State -> H.ComponentHTML S.Action' () Aff
|
||||
render st =
|
||||
render :: S.State State -> H.ComponentHTML S.Action' () Aff
|
||||
render st =
|
||||
HH.div
|
||||
[ class_ "Dropdown" ]
|
||||
[ renderToggle, renderContainer ]
|
||||
where
|
||||
renderToggle =
|
||||
HH.button
|
||||
( SS.setToggleProps [ class_ "Dropdown__toggle" ] )
|
||||
[ HH.text (fromMaybe st.buttonLabel st.selection) ]
|
||||
|
||||
renderContainer = whenElem (st.visibility == S.On) \_ ->
|
||||
HH.div
|
||||
[ class_ "Dropdown" ]
|
||||
[ renderToggle, renderContainer ]
|
||||
( SS.setContainerProps [ class_ "Dropdown__container" ] )
|
||||
( renderItem `mapWithIndex` st.items )
|
||||
where
|
||||
renderToggle =
|
||||
HH.button
|
||||
( SS.setToggleProps [ class_ "Dropdown__toggle" ] )
|
||||
[ HH.text (fromMaybe st.buttonLabel st.selection) ]
|
||||
|
||||
renderContainer = whenElem (st.visibility == S.On) \_ ->
|
||||
renderItem index item =
|
||||
HH.div
|
||||
( SS.setContainerProps [ class_ "Dropdown__container" ] )
|
||||
( renderItem `mapWithIndex` st.items )
|
||||
where
|
||||
renderItem index item =
|
||||
HH.div
|
||||
( SS.setItemProps index
|
||||
[ classes_
|
||||
[ "Dropdown__item"
|
||||
, "Dropdown__item--highlighted" # guard (st.highlightedIndex == Just index)
|
||||
]
|
||||
]
|
||||
)
|
||||
[ HH.text item ]
|
||||
( SS.setItemProps index
|
||||
[ classes_
|
||||
[ "Dropdown__item"
|
||||
, "Dropdown__item--highlighted" # guard (st.highlightedIndex == Just index)
|
||||
]
|
||||
]
|
||||
)
|
||||
[ HH.text item ]
|
||||
|
|
|
@ -48,161 +48,161 @@ type ChildSlots =
|
|||
|
||||
component :: H.Component HH.HTML (S.Query Query ChildSlots) Unit Message Aff
|
||||
component = S.component (const input) $ S.defaultSpec
|
||||
{ render = render
|
||||
, handleAction = handleAction
|
||||
, handleQuery = handleQuery
|
||||
, handleMessage = handleMessage
|
||||
}
|
||||
{ render = render
|
||||
, handleAction = handleAction
|
||||
, handleQuery = handleQuery
|
||||
, handleMessage = handleMessage
|
||||
}
|
||||
where
|
||||
-- this typeahead will be opaque; users can just use this pre-built
|
||||
-- input instead of the usual select one.
|
||||
input :: S.Input State
|
||||
input =
|
||||
{ inputType: S.Text
|
||||
, debounceTime: Just (Milliseconds 300.0)
|
||||
, search: Nothing
|
||||
, getItemCount: maybe 0 length <<< RD.toMaybe <<< _.available
|
||||
, selections: []
|
||||
, available: RD.NotAsked
|
||||
}
|
||||
-- this typeahead will be opaque; users can just use this pre-built
|
||||
-- input instead of the usual select one.
|
||||
input :: S.Input State
|
||||
input =
|
||||
{ inputType: S.Text
|
||||
, debounceTime: Just (Milliseconds 300.0)
|
||||
, search: Nothing
|
||||
, getItemCount: maybe 0 length <<< RD.toMaybe <<< _.available
|
||||
, selections: []
|
||||
, available: RD.NotAsked
|
||||
}
|
||||
|
||||
handleMessage
|
||||
:: S.Message
|
||||
-> H.HalogenM (S.State State) (S.Action Action) ChildSlots Message Aff Unit
|
||||
handleMessage = case _ of
|
||||
S.Selected ix -> do
|
||||
handleMessage
|
||||
:: S.Message
|
||||
-> H.HalogenM (S.State State) (S.Action Action) ChildSlots Message Aff Unit
|
||||
handleMessage = case _ of
|
||||
S.Selected ix -> do
|
||||
st <- H.get
|
||||
for_ st.available \arr ->
|
||||
for_ (arr !! ix) \item -> do
|
||||
let newSelections = item : st.selections
|
||||
H.modify_ _
|
||||
{ selections = item : st.selections
|
||||
, available = RD.Success (filter (_ /= item) arr)
|
||||
, search = ""
|
||||
}
|
||||
H.raise $ SelectionsChanged newSelections
|
||||
S.Searched str -> do
|
||||
st <- H.get
|
||||
-- we'll use an external api to search locations
|
||||
H.modify_ _ { available = RD.Loading }
|
||||
items <- H.liftAff $ searchLocations str
|
||||
H.modify_ _ { available = items <#> \xs -> difference xs st.selections }
|
||||
_ -> pure unit
|
||||
|
||||
-- You can remove all type signatures except for this one; we need to tell the
|
||||
-- compiler about the `a` type variable. The minimal necessary signature is below.
|
||||
handleQuery :: forall a. Query a -> H.HalogenM _ _ _ _ _ (Maybe a)
|
||||
handleQuery = case _ of
|
||||
GetSelections reply -> do
|
||||
st <- H.get
|
||||
pure $ Just $ reply st.selections
|
||||
|
||||
handleAction
|
||||
:: Action
|
||||
-> H.HalogenM (S.State State) (S.Action Action) ChildSlots Message Aff Unit
|
||||
handleAction = case _ of
|
||||
Remove item -> do
|
||||
st <- H.get
|
||||
let newSelections = filter (_ /= item) st.selections
|
||||
H.modify_ _ { selections = newSelections }
|
||||
H.raise $ ItemRemoved item
|
||||
HandleDropdown msg -> case msg of
|
||||
D.SelectionChanged oldSelection newSelection -> do
|
||||
st <- H.get
|
||||
for_ st.available \arr ->
|
||||
for_ (arr !! ix) \item -> do
|
||||
let newSelections = item : st.selections
|
||||
H.modify_ _
|
||||
{ selections = item : st.selections
|
||||
, available = RD.Success (filter (_ /= item) arr)
|
||||
, search = ""
|
||||
}
|
||||
H.raise $ SelectionsChanged newSelections
|
||||
S.Searched str -> do
|
||||
st <- H.get
|
||||
-- we'll use an external api to search locations
|
||||
H.modify_ _ { available = RD.Loading }
|
||||
items <- H.liftAff $ searchLocations str
|
||||
H.modify_ _ { available = items <#> \xs -> difference xs st.selections }
|
||||
_ -> pure unit
|
||||
let
|
||||
mkLocation str = { name: "User Added: " <> str, population: "1" }
|
||||
newSelections = case oldSelection, newSelection of
|
||||
Nothing, Nothing ->
|
||||
Nothing
|
||||
Nothing, Just str ->
|
||||
Just (mkLocation str : st.selections)
|
||||
Just str, Nothing ->
|
||||
Just (filter (_ /= mkLocation str) st.selections)
|
||||
Just old, Just new ->
|
||||
Just (mkLocation new : (filter (_ /= mkLocation old) st.selections))
|
||||
for_ newSelections \selections ->
|
||||
H.modify_ _ { selections = selections }
|
||||
|
||||
-- You can remove all type signatures except for this one; we need to tell the
|
||||
-- compiler about the `a` type variable. The minimal necessary signature is below.
|
||||
handleQuery :: forall a. Query a -> H.HalogenM _ _ _ _ _ (Maybe a)
|
||||
handleQuery = case _ of
|
||||
GetSelections reply -> do
|
||||
st <- H.get
|
||||
pure $ Just $ reply st.selections
|
||||
render :: S.State State -> H.ComponentHTML (S.Action Action) ChildSlots Aff
|
||||
render st =
|
||||
HH.div
|
||||
[ class_ "Typeahead" ]
|
||||
[ renderSelections, renderInput, renderDropdown, renderContainer ]
|
||||
where
|
||||
hasSelections = length st.selections > 0
|
||||
|
||||
handleAction
|
||||
:: Action
|
||||
-> H.HalogenM (S.State State) (S.Action Action) ChildSlots Message Aff Unit
|
||||
handleAction = case _ of
|
||||
Remove item -> do
|
||||
st <- H.get
|
||||
let newSelections = filter (_ /= item) st.selections
|
||||
H.modify_ _ { selections = newSelections }
|
||||
H.raise $ ItemRemoved item
|
||||
HandleDropdown msg -> case msg of
|
||||
D.SelectionChanged oldSelection newSelection -> do
|
||||
st <- H.get
|
||||
let
|
||||
mkLocation str = { name: "User Added: " <> str, population: "1" }
|
||||
newSelections = case oldSelection, newSelection of
|
||||
Nothing, Nothing ->
|
||||
Nothing
|
||||
Nothing, Just str ->
|
||||
Just (mkLocation str : st.selections)
|
||||
Just str, Nothing ->
|
||||
Just (filter (_ /= mkLocation str) st.selections)
|
||||
Just old, Just new ->
|
||||
Just (mkLocation new : (filter (_ /= mkLocation old) st.selections))
|
||||
for_ newSelections \selections ->
|
||||
H.modify_ _ { selections = selections }
|
||||
|
||||
render :: S.State State -> H.ComponentHTML (S.Action Action) ChildSlots Aff
|
||||
render st =
|
||||
renderSelections = whenElem hasSelections \_ ->
|
||||
HH.div
|
||||
[ class_ "Typeahead" ]
|
||||
[ renderSelections, renderInput, renderDropdown, renderContainer ]
|
||||
[ class_ "Typeahead__selections" ]
|
||||
(renderSelectedItem <$> st.selections)
|
||||
where
|
||||
hasSelections = length st.selections > 0
|
||||
|
||||
renderSelections = whenElem hasSelections \_ ->
|
||||
renderSelectedItem item =
|
||||
HH.div
|
||||
[ class_ "Typeahead__selections" ]
|
||||
(renderSelectedItem <$> st.selections)
|
||||
where
|
||||
renderSelectedItem item =
|
||||
HH.div
|
||||
[ class_ "Typeahead__item--selected Location" ]
|
||||
[ HH.span
|
||||
[ class_ "Location__name" ]
|
||||
[ HH.text item.name ]
|
||||
, closeButton item
|
||||
]
|
||||
[ class_ "Typeahead__item--selected Location" ]
|
||||
[ HH.span
|
||||
[ class_ "Location__name" ]
|
||||
[ HH.text item.name ]
|
||||
, closeButton item
|
||||
]
|
||||
|
||||
closeButton item =
|
||||
HH.span
|
||||
[ class_ "Location__closeButton"
|
||||
, HE.onClick \_ -> Just $ S.Action $ Remove item
|
||||
]
|
||||
[ HH.text "×" ]
|
||||
closeButton item =
|
||||
HH.span
|
||||
[ class_ "Location__closeButton"
|
||||
, HE.onClick \_ -> Just $ S.Action $ Remove item
|
||||
]
|
||||
[ HH.text "×" ]
|
||||
|
||||
renderInput = HH.input $ SS.setInputProps
|
||||
[ classes_
|
||||
[ "Typeahead__input"
|
||||
, "Typeahead__input--selections" # guard hasSelections
|
||||
, "Typeahead__input--active" # guard (st.visibility == S.On)
|
||||
]
|
||||
, HP.placeholder "Type to search..."
|
||||
]
|
||||
renderInput = HH.input $ SS.setInputProps
|
||||
[ classes_
|
||||
[ "Typeahead__input"
|
||||
, "Typeahead__input--selections" # guard hasSelections
|
||||
, "Typeahead__input--active" # guard (st.visibility == S.On)
|
||||
]
|
||||
, HP.placeholder "Type to search..."
|
||||
]
|
||||
|
||||
renderDropdown = whenElem (st.visibility == S.On) \_ ->
|
||||
HH.slot _dropdown unit D.component dropdownInput handler
|
||||
where
|
||||
_dropdown = SProxy :: SProxy "dropdown"
|
||||
handler msg = Just $ S.Action $ HandleDropdown msg
|
||||
dropdownInput = { items: [ "Earth", "Mars" ], buttonLabel: "Human Planets" }
|
||||
renderDropdown = whenElem (st.visibility == S.On) \_ ->
|
||||
HH.slot _dropdown unit D.component dropdownInput handler
|
||||
where
|
||||
_dropdown = SProxy :: SProxy "dropdown"
|
||||
handler msg = Just $ S.Action $ HandleDropdown msg
|
||||
dropdownInput = { items: [ "Earth", "Mars" ], buttonLabel: "Human Planets" }
|
||||
|
||||
renderContainer = whenElem (st.visibility == S.On) \_ ->
|
||||
renderContainer = whenElem (st.visibility == S.On) \_ ->
|
||||
HH.div
|
||||
(SS.setContainerProps
|
||||
[ classes_
|
||||
[ "Typeahead__container"
|
||||
, "Typeahead__container--hasItems" # guard hasItems
|
||||
]
|
||||
]
|
||||
)
|
||||
renderItems
|
||||
where
|
||||
hasItems = maybe false (not <<< null) (RD.toMaybe st.available)
|
||||
renderItems = do
|
||||
let renderMsg msg = [ HH.span_ [ HH.text msg ] ]
|
||||
case st.available of
|
||||
RD.NotAsked -> renderMsg "No search performed..."
|
||||
RD.Loading -> renderMsg "Loading..."
|
||||
RD.Failure e -> renderMsg e
|
||||
RD.Success available
|
||||
| hasItems -> renderItem `mapWithIndex` available
|
||||
| otherwise -> renderMsg "No results found"
|
||||
|
||||
renderItem index { name, population } =
|
||||
HH.div
|
||||
(SS.setContainerProps
|
||||
[ classes_
|
||||
[ "Typeahead__container"
|
||||
, "Typeahead__container--hasItems" # guard hasItems
|
||||
]
|
||||
]
|
||||
)
|
||||
renderItems
|
||||
(SS.setItemProps index [ classes_ [ base, highlight, "Location" ] ])
|
||||
[ HH.span
|
||||
[ class_ "Location__name" ]
|
||||
[ HH.text name ]
|
||||
, HH.span
|
||||
[ class_ "Location__population" ]
|
||||
[ HH.text population ]
|
||||
]
|
||||
where
|
||||
hasItems = maybe false (not <<< null) (RD.toMaybe st.available)
|
||||
renderItems = do
|
||||
let renderMsg msg = [ HH.span_ [ HH.text msg ] ]
|
||||
case st.available of
|
||||
RD.NotAsked -> renderMsg "No search performed..."
|
||||
RD.Loading -> renderMsg "Loading..."
|
||||
RD.Failure e -> renderMsg e
|
||||
RD.Success available
|
||||
| hasItems -> renderItem `mapWithIndex` available
|
||||
| otherwise -> renderMsg "No results found"
|
||||
|
||||
renderItem index { name, population } =
|
||||
HH.div
|
||||
(SS.setItemProps index [ classes_ [ base, highlight, "Location" ] ])
|
||||
[ HH.span
|
||||
[ class_ "Location__name" ]
|
||||
[ HH.text name ]
|
||||
, HH.span
|
||||
[ class_ "Location__population" ]
|
||||
[ HH.text population ]
|
||||
]
|
||||
where
|
||||
base = "Typeahead__item"
|
||||
highlight = "Typeahead__item--highlighted" # guard (st.highlightedIndex == Just index)
|
||||
base = "Typeahead__item"
|
||||
highlight = "Typeahead__item--highlighted" # guard (st.highlightedIndex == Just index)
|
||||
|
||||
|
||||
-- Let's make this typeahead async.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue