@@ -6,7 +6,8 @@ import Effect (Effect)
66import Effect.Uncurried (EffectFn1)
77import React.Basic (JSX)
88import Yoga.React.DOM.Internal (class IsJSX)
9−import Data.Function.Uncurried (runFn4)
9+import Data.Function.Uncurried (Fn2, mkFn2, runFn4)
10+import Data.String (Pattern(..), contains, toLower)
1011import HeroUI.Types (FieldVariant, fieldVariantToString)
1112import HeroUI.Internal (class CoerceHeroProps, createElementTransformImpl)
1213import HeroUI.Raw as Raw
@@ -78,6 +79,30 @@ autocompletePopover
7879 -> JSX
7980autocompletePopover props kids = runFn4 createElementTransformImpl {} Raw.autocompletePopover props kids
8081
82+-- | Wraps the search `input` + the options collection inside the popover;
83+-- | this is what makes the autocomplete typeable. Pass `filter` to narrow the
84+-- | options as the user types (see `containsFilter` for the common case).
85+type AutocompleteFilterProps r =
86+ ( filter :: Fn2 String String Boolean
87+ , className :: String
88+ | r
89+ )
90+
91+autocompleteFilter
92+ :: forall givenProps nonDataProps kids
93+ . IsJSX kids
94+ => CoerceHeroProps { | givenProps } { | nonDataProps } { | AutocompleteFilterProps () }
95+ => { | givenProps }
96+ -> kids
97+ -> JSX
98+autocompleteFilter props kids = runFn4 createElementTransformImpl {} Raw.autocompleteFilter props kids
99+
100+-- | Case-insensitive substring match — the usual `filter` for `autocompleteFilter`.
101+-- | react-aria calls it as `filter optionTextValue typedInput`; keep an option
102+-- | when what the user typed appears anywhere in its `textValue`.
103+containsFilter :: Fn2 String String Boolean
104+containsFilter = mkFn2 \optionText typed -> contains (Pattern (toLower typed)) (toLower optionText)
105+
81106autocompleteClearButton
82107 :: forall givenProps nonDataProps kids
83108 . IsJSX kids