Skip to content

Commit

Permalink
Merge pull request #85 from perimetre/7.6.0
Browse files Browse the repository at this point in the history
7.6.0
  • Loading branch information
AssisrMatheus authored Aug 22, 2022
2 parents 65fc2bf + 3574dd3 commit 7f7a62f
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 14 deletions.
6 changes: 6 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

### Fixed

## [7.6.0] 2022-08-22

### Changes

- Additional props passed down to `AutocompleteInput` now get forwarded to the underlying input field

## [7.5.0] 2022-08-19

### Added
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@perimetre/ui",
"description": "A component library made by @perimetre",
"version": "7.5.0",
"version": "7.6.0",
"repository": {
"type": "git",
"url": "git+https://github.com/perimetre/ui.git"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,13 @@ const ControlledTemplate: Story<AutocompleteInputProps<{ id: number; label: stri
options={options}
itemToString={(item) => (item ? item.label : '')}
filterItem={(item, inputValue) => item.label.toLowerCase().includes(inputValue.toLowerCase())}
selectedItem={state}
selectedItem={state || null}
onItemToggle={(item) => setState(item || undefined)}
onChange={(e) => {
if (e.target.value === '') {
setState(undefined);
}
}}
/>
);
};
Expand Down
73 changes: 61 additions & 12 deletions src/components/AutocompleteInput/index.tsx
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
// We turn off unused variables because in here. "props" are passed down to the input. But the react <input> element doesn't expect the same props as downshift. So we have to destructure them but not use it
/* eslint-disable @typescript-eslint/no-unused-vars */
import classnames from 'classnames';
import Downshift, { ControllerStateAndHelpers } from 'downshift';
import { debounce } from 'lodash';
Expand Down Expand Up @@ -78,6 +80,10 @@ export type AutocompleteInputProps<Item> =
* The render function used to render the dropdown item
*/
renderItem?: (item: Item, isSelected: boolean, isHighlighted: boolean) => React.ReactNode;
/**
* The render function used to render the blank slate
*/
renderBlankState?: (selectItem: (item: Item) => void) => React.ReactNode;
/**
* The component classname
*/
Expand All @@ -103,17 +109,18 @@ type DownshiftAutocompleteContentProps<Item> = ControllerStateAndHelpers<Item> &
*
* @param props the react component props
* @param props.options The options that should be displayed in the dropdown
// * @param props.initialSelectedItem The initial selected item
// * @param props.displayRegardlessIfSearching Whether or not should always show the result list regardless if the user is searching or not.
// * @param props.onItemToggle A callback that is called every time the user selects or unselects an item
// * @param props.defaultValue The input defaultValue property
* @param props.initialSelectedItem The initial selected item
* @param props.displayRegardlessIfSearching Whether or not should always show the result list regardless if the user is searching or not.
* @param props.onItemToggle A callback that is called every time the user selects or unselects an item
* @param props.defaultValue The input defaultValue property
* @param props.ignoreFilter Whether or not the options should be filtered based on user's input
* @param props.filterItem Predicate to modify the items on display, for example, filter based on the value
* @param props.itemToString Method used to convert the object item into the string that is shown on the dropdown
* @param props.label The text that should be placed in the input's label
* @param props.translations A translation object to override existing translations
* @param props.renderButtons The render function used to render the option buttons
* @param props.renderItem The render function used to render the dropdown item
* @param props.renderBlankState The render function used to render the blank slate
* @param props.className The component classname
* @param props.fetchMore A callback for when the input changes so more items can be loaded
* @param props.shouldFetchOnInit Whether or not the options should be fetched on init
Expand All @@ -126,15 +133,32 @@ type DownshiftAutocompleteContentProps<Item> = ControllerStateAndHelpers<Item> &
* @param props.inputValue Downshift inputValue
* @param props.highlightedIndex Downshift highlightedIndex
* @param props.toggleMenu Downshift toggleMenu
* @param props.initialSelectedItem The item to already start selected if any
* @param props.clearItems Clear the list of items
* @param props.clearSelection Clear the currently selected item
* @param props.openMenu Open the dropdown
* @param props.closeMenu Close the dropdown
* @param props.getRootProps Method used to get props for the autocomplete wrapper
* @param props.getToggleButtonProps Method used to get props for the toggle button
* @param props.id The input id if any
* @param props.reset Reset the entire state
* @param props.selectHighlightedItem Select the currently highlighted item
* @param props.selectItem Select an item
* @param props.selectItemAtIndex Select the item from the index
* @param props.selectedItem The currently selected item
* @param props.setHighlightedIndex Set the index of what should be highlighted
* @param props.setItemCount Set the number of items the array currently has
* @param props.setState Set the entire downshift state
* @param props.unsetItemCount Reset the number of items the array currently has
*/
const DownshiftAutocompleteContent = <Item extends { id: string | number }>({
// Autocomplete props
options,
// initialSelectedItem,
// displayRegardlessIfSearching,
initialSelectedItem,
displayRegardlessIfSearching,
// displayRegardlessIfFocused,
// onItemToggle,
// defaultValue,
onItemToggle,
defaultValue,
ignoreFilter,
filterItem,
itemToString,
Expand All @@ -146,6 +170,7 @@ const DownshiftAutocompleteContent = <Item extends { id: string | number }>({
fetchMore,
shouldFetchOnInit,
loading,
renderBlankState,

// Downshift props
getInputProps,
Expand All @@ -155,8 +180,26 @@ const DownshiftAutocompleteContent = <Item extends { id: string | number }>({
isOpen,
inputValue,
highlightedIndex,
toggleMenu
}: DownshiftAutocompleteContentProps<Item>) => {
toggleMenu,
clearItems,
clearSelection,
closeMenu,
getRootProps,
getToggleButtonProps,
openMenu,
reset,
selectHighlightedItem,
selectItem,
selectItemAtIndex,
selectedItem,
setHighlightedIndex,
setItemCount,
setState,
unsetItemCount,

...props
}: DownshiftAutocompleteContentProps<Item> &
React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>) => {
// I use ref instead of state for this, because I don't want it to trigger an effect or re-render.
// I could simply not use it on the deps array, BUT then the value wouldn't be up to date inside the effect scope
const isFetchingRef = useRef(false);
Expand Down Expand Up @@ -213,7 +256,10 @@ const DownshiftAutocompleteContent = <Item extends { id: string | number }>({
{/* Render the combo container for the input and the results */}
<div className="pui-dropdown-input-container">
<input
{...getInputProps({ className: classnames('pui-text-input', className) })}
{...getInputProps({
className: classnames('pui-text-input', className),
...props
})}
onClick={() => !isOpen && toggleMenu()}
/>
{/* <button aria-label={'toggle menu'} className="p-2" type="button" {...getToggleButtonProps()}></button> */}
Expand Down Expand Up @@ -270,6 +316,8 @@ const DownshiftAutocompleteContent = <Item extends { id: string | number }>({
</li>
);
})
) : renderBlankState ? (
renderBlankState(selectItem)
) : (
<li className="pui-flex-center flex-col text-pui-paragraph-300">
<AttentionIcon className="my-2" />
Expand Down Expand Up @@ -311,7 +359,8 @@ const DownshiftAutocompleteContent = <Item extends { id: string | number }>({
* @param props.loading Whether the options are loading
*/
export const AutocompleteInput = <Item extends { id: string | number } = { id: string | number }>(
props: AutocompleteInputProps<Item>
props: AutocompleteInputProps<Item> &
React.DetailedHTMLProps<React.InputHTMLAttributes<HTMLInputElement>, HTMLInputElement>
) => {
const {
itemToString,
Expand Down

0 comments on commit 7f7a62f

Please sign in to comment.