@render-props/choices
Version:
A state container which provides an interface for making selections from a group of choices. The `Choices` component itself is a context provider which can be used with the `Choice` and `ChoicesConsumer` components for deep-tree selections. It does not ha
204 lines (181 loc) • 7.37 kB
Markdown
# Choices
A state container which provides an interface for making selections from
a group of choices. The `Choices` component itself is a context provider which
can be used with the `Choice` and `ChoicesConsumer` components for deep-tree
selections. It does not have to be used with these components, however.
### Installation
```yarn add @render-props/choices``` or ```npm i @render-props/choices```
### Contents
- [**`Choices`**](#choices)
- This main component which must be used
- [**`Choice`**](#choice)
- This is an optional convenience component for deep-tree selections. It
is a context consumer of `Choices`. It provides the following props to its
child component: `{select, deselect, toggle, isSelected}`
- [**`ChoicesConsumer`**](#choicesconsumer)
- This is the Consumer for the `Choices` Provider which provides an object
as its value with this shape: ```{selections, choices, select, deselect, toggle, setSelections, clearSelections, isSelected, addChoice, deleteChoice, setChoices, clearChoices, isChoice}```
## Usage
```js
import Choices, {Choice} from '@render-props/choices'
const FavoritePets = props => (
<Choices
initialChoices={new Set(['cat', 'dog', 'turtle'])}
initialSelections={new Set(['cat'])}
minChoices={1}
minSelections={1}
maxSelections={2}
onBoundMaxSelections={
function ({selections, select, deselect}) {
selections = Array.from(selections)
deselect(selections.shift())
select(selections.pop())
}
}
>
{PetsControl}
</Choices>
)
const PetsControl = ({
addChoice,
deleteChoice,
setChoices,
clearChoices,
isChoice,
select,
deselect,
setSelections,
clearSelections,
isSelected,
selections,
choices
}) => (
<div style={{borderWidth: 1}}>
<span>
Number of favorites: {selections.size}
</span>
{Array.from(choices).map(pet => (
<Choice key={pet} value={pet}>
{function ({select, deselect, toggle, isSelected}) {
return (
<button
onClick={toggle}
style={
isSelected
? {backgroundColor: 'green'}
: {backgroundColor: 'grey'}
}
>
{pet}
</button>
)
}}
</Choice>
))}
</div>
)
```
____
# Choices
## Props
- `initialChoices {array|set}`
- the initial choices that selections may be made from
- `initialSelections {array|set}`
- the initial selections. These must also be members of `@initialChoices`
- `minChoices {integer}`
- the minimum number of `choices` that should remain in the state
- `maxChoices {integer}`
- the maximum number of `choices` that can be added to the state
- `onBoundMinChoices {function ({choices <array|set>, addChoice <function>, deleteChoice <function>})}`
- called when the minimum bound of `choices` has been reached. Callback should include one
argument for object: `{choices, addChoice, deleteChoice}` where `choices` is the
set of items which triggered the bounding error
- `onBoundMaxChoices {function ({choices <array|set>, addChoice <function>, deleteChoice <function>})}`
- called when the maximum bound of `choices` has been reached. Callback should include one
argument for object: `{choices, addChoice, deleteChoice}` where `choices` is the
set of items which triggered the bounding error
- `onChoicesChange {function (items <array|set>)}`
- called whenever an item is added or removed from the set of `choices`.
Receives one argument for `choices` which reflects the latest state
- `onAddChoice {function (items <array|set>)}`
- called whenever an item is added to the `choices` set. Receives one argument for
`choices` which reflects the latest state.
- `onDeleteChoice {function (items <array|set>)}`
- called whenever an item is removed from the `choices` set. Receives one argument for
`choices` which reflects the latest state
- `minSelections {integer}`
- the minimum number of `selections` that should remain in the state
- `maxSelections {integer}`
- the maximum number of `selections` that can be added to the state
- `onBoundMinSelections {function ({selections <array|set>, select <function>, deselect <function>})}`
- called when the minimum bound of `selections` has been reached. Callback should include one
argument for object: `{selections, select, deselect}` where `selections` is the
set of items which triggered the bounding error
- `onBoundMaxSelections {function ({selections <array|set>, select <function>, deselect <function>})}`
- called when the maximum bound of `selections` has been reached. Callback should include one
argument for object: `{selections, select, deselect}` where `selections` is the
set of items which triggered the bounding error
- `onChange {function (items <array|set>)}`
- called whenever an item is added or removed from the set of `selections`.
Receives one argument for `selections` which reflects the latest state
- `onSelect {function (items <array|set>)}`
- called whenever an item is added to the `selections` set. Receives one argument for
`selections` which reflects the latest state.
- `onDeselect {function (items <array|set>)}`
- called whenever an item is removed from the `selections` set. Receives one argument for
`selections` which reflects the latest state
## Render Props
#### Methods
- `select` `(...items <any choice>)`
- adds one or several selections if they are available in `choices`
- `deselect` `(...items <any selection>)`
- removes one or several `selections`
- `toggle` `(item <any choice>)`
- removes an item if it is in selections, otherwise adds it to selections
- `setSelections` `(items <array|set>)`
- sets `selections` to whatever the value of `@items` is
- `clearSelections` `()`
- clears all selections
- `isSelected` `(item <any>)`
- returns `true` if `@item` is in `selections`
- `addChoice` `(...items <any choice>)`
- adds one or several `choices`
- `deleteChoice` `(...items <any selection>)`
- removes one or several `choices`
- `setChoices` `(items <array|set>)`
- sets `choices` to whatever the value of `@items` is
- `clearChoices` `()`
- clears all choices
- `isChoice` `(item <any>)`
- returns `true` if `@item` is in `choices`
#### State
- `selections {array|set}`
- the selections currently in the state of the component. Is an `Array` if
`initialSelections` was an `Array` and a `Set` if `initialSelections` was
a `Set`
- `choices {array|set}`
- the choices currently in the state of the component. Is an `Array` if
`initialChoices` was an `Array` and a `Set` if `initialChoices` was
a `Set`
_____
# Choice
## Props
- `value`
- the value of the choice from the `Set`/`Array` of choices in the `Choices` component
## Render Props
#### Methods
- `select` `()`
- selects this choice from `choices`
- `deselect` `()`
- deselects this choice from `selections`
- `toggle` `()`
- selects if `isSelected`, otherwise deselects
- `delete` `()`
- deletes this choice from `choices` and `selections`
#### State
- `isSelected {bool>}`
- returns `true` if the prop `value` provided to this component resides in `Choices.selections`
_____
# ChoicesConsumer
## Render Props
See [Choices](#render-props) render props