1
Fork 0

Remove SProxy reference

This commit is contained in:
prescientmoon 2025-06-09 00:11:33 +02:00
parent 27befa13f2
commit c5b397497a
Signed by: prescientmoon
SSH key fingerprint: SHA256:WFp/cO76nbarETAoQcQXuV+0h7XJsEsOCI0UsyPIy6U
4 changed files with 54 additions and 44 deletions

1
.gitignore vendored
View file

@ -6,6 +6,7 @@ node_modules
# Generated files
.psci
.psc-ide-port
.spago
output
package-lock.json
generated-docs

View file

@ -1,4 +1,7 @@
# Select
# Select
> [!NOTE]
> This fork makes this package work with newer PureScript versions, by removing a stale `SProxy` import. This fork is here for personal use only. Use at your own risk.
[![CircleCI](https://circleci.com/gh/citizennet/purescript-halogen-select/tree/master.svg?style=shield)](https://circleci.com/gh/citizennet/purescript-halogen-select/tree/master)
[![Maintainer: thomashoneyman](https://img.shields.io/badge/maintainer-thomashoneyman-lightgrey.svg)](http://github.com/thomashoneyman)
@ -31,18 +34,17 @@ For more information, try the [official documentation](https://citizennet.github
The library provides essential behaviors for selection user interfaces as a group of Halogen components. But you won't find a single render function in the code. Instead, with the help of a few `setProps` helpers, you can write your HTML rendering however you'd like. You can freely include your own queries and the library will return them to be run. You can even use any data you want from your parent state in your render functions. The library manages user interaction, state, accessibility, and logic; you are responsible for rendering HTML depending on that state.
1. Provide behaviors, not styles
Developers should be able to style and display dropdowns and typeaheads however they would like, rather than be forced to use particular CSS classes or re-implement the component with their HTML. This is accomplished with augmented render functions as described below. We provide the machinery; you provide the HTML and styles.
1. Provide behaviors, not styles
Developers should be able to style and display dropdowns and typeaheads however they would like, rather than be forced to use particular CSS classes or re-implement the component with their HTML. This is accomplished with augmented render functions as described below. We provide the machinery; you provide the HTML and styles.
2. Export the building blocks, not just the end result
Developers should be able to take a core set of behaviors and choose how they would like to handle them in their own version of the component. If you would like the typeahead's functionality but do something fancy with the selected items, you should be able to. Each building block is exported.
2. Export the building blocks, not just the end result
Developers should be able to take a core set of behaviors and choose how they would like to handle them in their own version of the component. If you would like the typeahead's functionality but do something fancy with the selected items, you should be able to. Each building block is exported.
3. Require minimal configuration
Instantiating a typeahead shouldn't require a 50-field configuration record. We require at minimum two things: the data to populate the menu and the HTML to render that data. The rest is taken care of by the component. You are responsible for handling two things: when an item was selected, and when the user has performed a new search. If you want to do even less, you can use one of our default implementations to drop in to your project.
4. Be accessible (Upcoming)
ARIA props and other features necessary for accessibility online should be handled properly without any setup.
3. Require minimal configuration
Instantiating a typeahead shouldn't require a 50-field configuration record. We require at minimum two things: the data to populate the menu and the HTML to render that data. The rest is taken care of by the component. You are responsible for handling two things: when an item was selected, and when the user has performed a new search. If you want to do even less, you can use one of our default implementations to drop in to your project.
4. Be accessible (Upcoming)
ARIA props and other features necessary for accessibility online should be handled properly without any setup.
# Rendering
@ -61,10 +63,8 @@ For example, you can make your container compatible with the component with the
]
```
> Warning: If you provide any of the same events that we use for our behaviors, only yours will trigger, preventing that behavior from being applied. E.g., if you provide your own `HE.onValueInput` event on the element you're applying `setInputProps` to, you will end up overriding our search functionality for that input.
## Inspiration & Thanks
This project drew inspiration from the approach taken by [paypal/downshift](https://github.com/paypal/downshift). Special thanks to [Nathan Faubion](https://github.com/natefaubion) and [Nicholas Scheel](https://github.com/MonoidMusician) for their help.

9
spago.yaml Normal file
View file

@ -0,0 +1,9 @@
package:
name: halogen-select
dependencies:
- halogen
- record
workspace:
packageSet:
registry: 64.10.0
extraPackages: {}

View file

@ -10,7 +10,6 @@ import Prelude
import Control.Monad.Free (liftF)
import Data.Const (Const)
import Data.Maybe (Maybe(..), fromMaybe)
import Data.Symbol (SProxy(..))
import Data.Time.Duration (Milliseconds)
import Data.Traversable (for_, traverse, traverse_)
import Effect.Aff (Fiber, delay, error, forkAff, killFiber)
@ -24,6 +23,7 @@ import Halogen.HTML as HH
import Halogen.Query.ChildQuery (ChildQueryBox)
import Prim.Row as Row
import Record.Builder as Builder
import Type.Prelude (Proxy(..))
import Unsafe.Coerce (unsafeCoerce)
import Web.Event.Event (preventDefault)
import Web.HTML.HTMLElement as HTMLElement
@ -73,6 +73,7 @@ type Slot' = Slot (Const Void) () Void
-- | Represents a way to navigate on `Highlight` events: to the previous
-- | item, next item, or the item at a particular index.
data Target = Prev | Next | Index Int
derive instance eqTarget :: Eq Target
-- | Represents whether the component should display the item container. You
@ -82,6 +83,7 @@ derive instance eqTarget :: Eq Target
-- | render state = if state.visibility == On then renderAll else renderInputOnly
-- | ```
data Visibility = Off | On
derive instance eqVisibility :: Eq Visibility
derive instance ordVisibility :: Ord Visibility
@ -98,7 +100,7 @@ type State st =
, debounceRef :: Maybe (Ref (Maybe Debouncer))
, visibility :: Visibility
, highlightedIndex :: Maybe Int
, getItemCount :: {| st } -> Int
, getItemCount :: { | st } -> Int
| st
}
@ -111,7 +113,7 @@ type Input st =
{ inputType :: InputType
, search :: Maybe String
, debounceTime :: Maybe Milliseconds
, getItemCount :: {| st } -> Int
, getItemCount :: { | st } -> Int
| st
}
@ -126,39 +128,37 @@ type HalogenM st action slots msg m a =
type Spec st query action slots input msg m =
{ -- usual Halogen component spec
render
:: State st
render ::
State st
-> ComponentHTML action slots m
-- handle additional actions provided to the component
, handleAction
:: action
-- handle additional actions provided to the component
, handleAction ::
action
-> HalogenM st action slots msg m Unit
-- handle additional queries provided to the component
, handleQuery
:: forall a
-- handle additional queries provided to the component
, handleQuery ::
forall a
. query a
-> HalogenM st action slots msg m (Maybe a)
-- handle messages emitted by the component; provide H.raise to simply
-- raise the Select messages to the parent.
, handleEvent
:: Event
-- handle messages emitted by the component; provide H.raise to simply
-- raise the Select messages to the parent.
, handleEvent ::
Event
-> HalogenM st action slots msg m Unit
-- optionally handle input on parent re-renders
, receive
:: input
-- optionally handle input on parent re-renders
, receive ::
input
-> Maybe action
-- perform some action when the component initializes.
, initialize
:: Maybe action
-- perform some action when the component initializes.
, initialize :: Maybe action
-- optionally perform some action on initialization. disabled by default.
, finalize
:: Maybe action
-- optionally perform some action on initialization. disabled by default.
, finalize :: Maybe action
}
type Spec' st input m = Spec st (Const Void) Void () input Void m
@ -201,11 +201,11 @@ component mkInput spec = H.mkComponent
initialState = Builder.build pipeline
where
pipeline =
Builder.modify (SProxy :: _ "search") (fromMaybe "")
>>> Builder.modify (SProxy :: _ "debounceTime") (fromMaybe mempty)
>>> Builder.insert (SProxy :: _ "debounceRef") Nothing
>>> Builder.insert (SProxy :: _ "visibility") Off
>>> Builder.insert (SProxy :: _ "highlightedIndex") Nothing
Builder.modify (Proxy :: _ "search") (fromMaybe "")
>>> Builder.modify (Proxy :: _ "debounceTime") (fromMaybe mempty)
>>> Builder.insert (Proxy :: _ "debounceRef") Nothing
>>> Builder.insert (Proxy :: _ "visibility") Off
>>> Builder.insert (Proxy :: _ "highlightedIndex") Nothing
handleQuery
:: forall st query action slots msg m a
@ -244,7 +244,7 @@ handleAction handleAction' handleEvent = case _ of
case st.inputType, ref of
Text, Nothing -> unit <$ do
var <- H.liftAff AVar.empty
var <- H.liftAff AVar.empty
fiber <- H.liftAff $ forkAff do
delay st.debounceTime
AVar.put unit var
@ -319,7 +319,7 @@ handleAction handleAction' handleEvent = case _ of
preventIt
for_ st.highlightedIndex \ix ->
handle $ Select (Index ix) Nothing
otherKey -> pure unit
_ -> pure unit
PreventClick ev ->
H.liftEffect $ preventDefault $ ME.toEvent ev
@ -348,7 +348,7 @@ handleAction handleAction' handleEvent = case _ of
-- we know that the getItemCount function will only touch user fields,
-- and that the state record contains *at least* the user fields, so
-- this saves us from a set of unnecessary record deletions / modifications
userState :: State st -> {| st }
userState :: State st -> { | st }
userState = unsafeCoerce
lastIndex :: State st -> Int