Skip to content

Commit

Permalink
Merge pull request #52 from akash4393/master
Browse files Browse the repository at this point in the history
Added support for custom input render method
  • Loading branch information
koolamusic authored Jul 14, 2021
2 parents b700276 + 2b0c826 commit 2db12f8
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 46 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@ export default function App() {
| hideToggleButton | boolean | | Hide the toggle button |
| disableCreateItem | boolean | | Disable the "create new" list Item. Default is `false` |
| createItemRenderer | Function | | Custom Function that can either return a JSX Element or String, in order to control how the create new item within the Dropdown is rendered. The input value is passed as the first function parameter, Example: ``` (value) => `Create ${value}` ``` |
| renderCustomInput | Function | | Custom function to render input from outside chakra-ui-autocomplete. Receives input props for the input element and toggleButtonProps for the toggle button. Can use this to render chakra-ui's ```<InputGroup>```. Example: ```(inputProps) => (<InputGroup><InputLeftElement pointerEvents="none" children={<PhoneIcon color="gray.300" />} /><Input {...inputProps} /></InputGroup>)```

## Todo

Expand Down
134 changes: 88 additions & 46 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,15 @@ import matchSorter from 'match-sorter'
import Highlighter from 'react-highlight-words'
import useDeepCompareEffect from 'react-use/lib/useDeepCompareEffect'
import { FormLabel, FormLabelProps } from '@chakra-ui/form-control'
import { Text, Stack, Box, BoxProps, List, ListItem, ListIcon } from '@chakra-ui/layout'
import {
Text,
Stack,
Box,
BoxProps,
List,
ListItem,
ListIcon
} from '@chakra-ui/layout'
import { Button, ButtonProps } from '@chakra-ui/button'
import { Input, InputProps } from '@chakra-ui/input'
import { IconProps, CheckCircleIcon, ArrowDownIcon } from '@chakra-ui/icons'
Expand Down Expand Up @@ -40,10 +48,11 @@ export interface CUIAutoCompleteProps<T extends Item>
selectedIconProps?: Omit<IconProps, 'name'> & {
icon: IconProps['name'] | React.ComponentType
}
icon?: ComponentWithAs<"svg", IconProps>
icon?: ComponentWithAs<'svg', IconProps>
hideToggleButton?: boolean
createItemRenderer?: (value: string) => string | JSX.Element
disableCreateItem?: boolean
renderCustomInput?: (inputProps: any, toggleButtonProps: any) => JSX.Element
}

function defaultOptionFilterFunc<T>(items: T[], inputValue: string) {
Expand All @@ -59,7 +68,7 @@ function defaultCreateItemRenderer(value: string) {
</Box>
</Text>
)
}
}

export const CUIAutoComplete = <T extends Item>(
props: CUIAutoCompleteProps<T>
Expand All @@ -83,6 +92,7 @@ export const CUIAutoComplete = <T extends Item>(
hideToggleButton = false,
disableCreateItem = false,
createItemRenderer = defaultCreateItemRenderer,
renderCustomInput,
...downshiftProps
} = props

Expand Down Expand Up @@ -195,7 +205,13 @@ export const CUIAutoComplete = <T extends Item>(
setInputItems([{ label: `${inputValue}`, value: inputValue }])
setHighlightedIndex(0)
}
}, [inputItems, setIsCreating, setHighlightedIndex, inputValue, disableCreateItem])
}, [
inputItems,
setIsCreating,
setHighlightedIndex,
inputValue,
disableCreateItem
])

useDeepCompareEffect(() => {
setInputItems(items)
Expand All @@ -208,7 +224,9 @@ export const CUIAutoComplete = <T extends Item>(

return (
<Stack>
<FormLabel {...{...getLabelProps({}), ...labelStyleProps}}>{label}</FormLabel>
<FormLabel {...{ ...getLabelProps({}), ...labelStyleProps }}>
{label}
</FormLabel>

{/* ---------Stack with Selected Menu Tags above the Input Box--------- */}
{selectedItems && (
Expand Down Expand Up @@ -236,25 +254,49 @@ export const CUIAutoComplete = <T extends Item>(

{/* -----------Section that renders the input element ----------------- */}
<Stack isInline {...getComboboxProps()}>
<Input
{...inputStyleProps}
{...getInputProps(
getDropdownProps({
placeholder,
onClick: isOpen ? () => { } : openMenu,
onFocus: isOpen ? () => { } : openMenu,
ref: disclosureRef
})
)}
/>
{!hideToggleButton && (
<Button
{...toggleButtonStyleProps}
{...getToggleButtonProps()}
aria-label='toggle menu'
>
<ArrowDownIcon />
</Button>
{renderCustomInput ? (
renderCustomInput(
{
...inputStyleProps,
...getInputProps(
getDropdownProps({
placeholder,
onClick: isOpen ? () => {} : openMenu,
onFocus: isOpen ? () => {} : openMenu,
ref: disclosureRef
})
)
},
{
...toggleButtonStyleProps,
...getToggleButtonProps(),
ariaLabel: 'toggle menu',
hideToggleButton
}
)
) : (
<>
<Input
{...inputStyleProps}
{...getInputProps(
getDropdownProps({
placeholder,
onClick: isOpen ? () => {} : openMenu,
onFocus: isOpen ? () => {} : openMenu,
ref: disclosureRef
})
)}
/>
{!hideToggleButton && (
<Button
{...toggleButtonStyleProps}
{...getToggleButtonProps()}
aria-label='toggle menu'
>
<ArrowDownIcon />
</Button>
)}
</>
)}
</Stack>
{/* -----------Section that renders the input element ----------------- */}
Expand Down Expand Up @@ -283,29 +325,29 @@ export const CUIAutoComplete = <T extends Item>(
{isCreating ? (
createItemRenderer(item.label)
) : (
<Box display='inline-flex' alignItems='center'>
{selectedItemValues.includes(item.value) && (
<ListIcon
as={icon || CheckCircleIcon}
color='green.500'
role='img'
display='inline'
aria-label='Selected'
{...selectedIconProps}
/>
)}
<Box display='inline-flex' alignItems='center'>
{selectedItemValues.includes(item.value) && (
<ListIcon
as={icon || CheckCircleIcon}
color='green.500'
role='img'
display='inline'
aria-label='Selected'
{...selectedIconProps}
/>
)}

{itemRenderer ? (
itemRenderer(item)
) : (
<Highlighter
autoEscape
searchWords={[inputValue || '']}
textToHighlight={defaultItemRenderer(item)}
/>
)}
</Box>
)}
{itemRenderer ? (
itemRenderer(item)
) : (
<Highlighter
autoEscape
searchWords={[inputValue || '']}
textToHighlight={defaultItemRenderer(item)}
/>
)}
</Box>
)}
</ListItem>
))}
</List>
Expand Down

0 comments on commit 2db12f8

Please sign in to comment.