From ce39ac975531dc4c20589836e2759733fcb466cc Mon Sep 17 00:00:00 2001 From: boygao1992 Date: Tue, 12 Oct 2021 13:16:10 -0400 Subject: [PATCH 1/3] loosen `renderSearchDropdown` from `Maybe` to any `Foldable` We need a multi-select version of `renderToolbarSearchDropdown` which returns `Array` instead of `Maybe`. `renderToolbarSearchDropdown` depends on `renderSearchDropdown` so we start from here. --- src/Typeahead.purs | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/Typeahead.purs b/src/Typeahead.purs index 2aa33112..374ca98b 100644 --- a/src/Typeahead.purs +++ b/src/Typeahead.purs @@ -68,7 +68,6 @@ import Data.Foldable as Data.Foldable import Data.Fuzzy as Data.Fuzzy import Data.Maybe (Maybe(..)) import Data.Maybe as Data.Maybe -import Data.Newtype as Data.Newtype import Data.Rational ((%)) import Data.String as Data.String import Data.Time.Duration as Data.Time.Duration @@ -914,12 +913,13 @@ renderMultiInput input renderContainer st = ] renderSearchDropdown - :: ∀ action item m + :: ∀ action f item m . Eq item + => Data.Foldable.Foldable f => String -> Halogen.HTML.PlainHTML -> (Data.Fuzzy.Fuzzy item -> Halogen.HTML.PlainHTML) - -> CompositeComponentRender action Maybe item m + -> CompositeComponentRender action f item m renderSearchDropdown resetLabel label renderFuzzy st = Halogen.HTML.label [ Ocelot.HTML.Properties.css "relative" ] @@ -934,12 +934,14 @@ renderSearchDropdown resetLabel label renderFuzzy st = [ Ocelot.Block.ItemContainer.dropdownContainer [ renderInput, renderReset ] renderFuzzy - ((==) st.selected <<< Just <<< _.original <<< Data.Newtype.unwrap) + isSelected st.fuzzyItems st.highlightedIndex ] ] where + isSelected :: Data.Fuzzy.Fuzzy item -> Boolean + isSelected (Data.Fuzzy.Fuzzy { original }) = Data.Foldable.elem original st.selected renderInput = Halogen.HTML.div [ Ocelot.HTML.Properties.css "m-4 border-b-2 border-blue-88 pb-2 flex" ] @@ -954,7 +956,7 @@ renderSearchDropdown resetLabel label renderFuzzy st = [ Halogen.HTML.Events.onClick \_ -> Select.Action $ RemoveAll ] [ Halogen.HTML.text resetLabel ] - ( Data.Maybe.isNothing st.selected ) + ( Data.Foldable.null st.selected ) false renderSingle From af04dd4963ed1499dfa35296be1c544a10f04113 Mon Sep 17 00:00:00 2001 From: boygao1992 Date: Tue, 12 Oct 2021 14:43:29 -0400 Subject: [PATCH 2/3] give user full control over text rendering We used to take a default label String and a text render function for a single selection with `Maybe` in `renderToolbarSearchDropdown`. Now we want to support multiple selections with `Array`, the presentation of text as a summary of selections could vary depending on different situations, e.g. a comma separated list of all selections, or the count of selections, etc. so we let users to provide the render function instead of making a decision for them. --- src/Interfaces/Typeahead/Interface.purs | 6 ++-- src/Typeahead.purs | 12 ++++---- ui-guide/Components/Typeaheads.purs | 37 ++++++++++++++++++++++++- 3 files changed, 46 insertions(+), 9 deletions(-) diff --git a/src/Interfaces/Typeahead/Interface.purs b/src/Interfaces/Typeahead/Interface.purs index 73a299be..9f178fac 100644 --- a/src/Interfaces/Typeahead/Interface.purs +++ b/src/Interfaces/Typeahead/Interface.purs @@ -300,8 +300,10 @@ searchDropdownInputToToolbarSingleInput r = , disabled: false , render: renderToolbarSearchDropdown r.placeholder - r.resetLabel - renderLabel + ( case _ of + Nothing -> HH.text r.resetLabel + Just x -> renderLabel x + ) renderFuzzy } where diff --git a/src/Typeahead.purs b/src/Typeahead.purs index 374ca98b..6d4a0f9a 100644 --- a/src/Typeahead.purs +++ b/src/Typeahead.purs @@ -1015,14 +1015,14 @@ renderSingle iprops renderItem renderContainer st = showSelected = Data.Maybe.isJust st.selected && st.visibility == Select.Off renderToolbarSearchDropdown - :: ∀ action item m + :: ∀ action f item m . Eq item + => Data.Foldable.Foldable f => String - -> String - -> (item -> Halogen.HTML.PlainHTML) + -> (f item -> Halogen.HTML.PlainHTML) -> (Data.Fuzzy.Fuzzy item -> Halogen.HTML.PlainHTML) - -> CompositeComponentRender action Maybe item m -renderToolbarSearchDropdown defaultLabel resetLabel renderItem renderFuzzy st = + -> CompositeComponentRender action f item m +renderToolbarSearchDropdown resetLabel renderText renderFuzzy st = renderSearchDropdown resetLabel label renderFuzzy st where label = Ocelot.Block.ItemContainer.dropdownButton @@ -1032,7 +1032,7 @@ renderToolbarSearchDropdown defaultLabel resetLabel renderItem renderFuzzy st = : Ocelot.Block.Button.buttonMainClasses <> Ocelot.Block.Button.buttonClearClasses ] - [ Data.Maybe.maybe (Halogen.HTML.text defaultLabel) (Halogen.HTML.fromPlainHTML <<< renderItem) st.selected ] + [ (Halogen.HTML.fromPlainHTML <<< renderText) st.selected ] replaceSelected :: forall action f item m diff --git a/ui-guide/Components/Typeaheads.purs b/ui-guide/Components/Typeaheads.purs index 64ee1085..581005f8 100644 --- a/ui-guide/Components/Typeaheads.purs +++ b/ui-guide/Components/Typeaheads.purs @@ -4,6 +4,7 @@ import Prelude import Control.Parallel as Control.Parallel import Data.Array (head, take) +import Data.Array as Data.Array import Data.Maybe (Maybe(..)) import Data.Newtype (unwrap) import Effect.Aff.Class (class MonadAff) @@ -647,8 +648,42 @@ cnDocumentationBlocks = , disabled: false , render: TA.renderToolbarSearchDropdown "All Locations" + ( case _ of + Nothing -> HH.text "All Locations" + Just (Async.Location x) -> HH.text x.name + ) + (HH.span_ <<< IC.boldMatches "name") + } + ] + ] + , content + [ Card.card + [ HP.class_ $ HH.ClassName "flex-1" ] + [ HH.h3 + [ HP.classes Format.captionClasses ] + [ HH.text "Multi - Searchable Dropdown in a Toolbar (e.g. for filtering)" ] + , HH.slot_ _multiLocation 11 + ( TA.component + { runSelect: Data.Array.cons + , runRemove: Data.Array.filter <<< (/=) + , runFilterFuzzy: identity + , runFilterItems: const + } + ) + { items: NotAsked + , insertable: TA.NotInsertable + , keepOpen: true + , debounceTime: Nothing + , async: Nothing + , itemToObject: Async.locationToObject + , disabled: false + , render: TA.renderToolbarSearchDropdown "All Locations" - (HH.text <<< _.name <<< unwrap) + ( case _ of + [] -> HH.text "All Locations" + [ Async.Location x ] -> HH.text x.name + xs -> HH.text (show (Data.Array.length xs) <> " Locations Selected") + ) (HH.span_ <<< IC.boldMatches "name") } ] From a2b9a47d3f041f1526ef5636b7dbd7d49635d911 Mon Sep 17 00:00:00 2001 From: boygao1992 Date: Tue, 12 Oct 2021 15:49:40 -0400 Subject: [PATCH 3/3] bump major version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 485fa66f..6eec92c2 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "purescript-ocelot", - "version": "0.32.1", + "version": "0.33.0", "private": true, "scripts": { "build-all": "make build",