Skip to content

Commit

Permalink
feat: add renderDropdown prop to react-dropdown
Browse files Browse the repository at this point in the history
This property allows to define a custom rendering logic for the dropdown component.
  • Loading branch information
FezVrasta committed Apr 2, 2019
1 parent eca439c commit de5a528
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 18 deletions.
4 changes: 2 additions & 2 deletions packages/react-dropdown/src/__mocks__/DropdownWrapper.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
*/
// @flow

import React from 'react';
import * as React from 'react';
import Dropdown from '../index';

type State = {
Expand All @@ -33,10 +33,10 @@ class DropdownWrapper extends React.Component<Props, State> {
render() {
return (
<Dropdown
items={this.props.items}
defaultIsOpen={true}
selectedItems={this.state.selectedItems}
onChange={this.handleChange}
{...this.props}
>
{({ getInputProps }) => <input {...getInputProps()} />}
</Dropdown>
Expand Down
39 changes: 23 additions & 16 deletions packages/react-dropdown/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,12 +59,15 @@ type Props = {
Array<DropdownSelectedItem>,
MultiControllerStateAndHelpers
) => void,
renderDropdown?: ({ dropdown: React.Node }) => React.Node,
};

const DropdownContainer = styled.div`
display: inline-block;
`;

const defaultRenderDropdown = ({ dropdown }) => dropdown;

/** @visibleName Usage example */
const Dropdown = ({
filterFn = filterItems,
Expand All @@ -84,6 +87,7 @@ const Dropdown = ({
onChange,
onSelect,
highlight = false,
renderDropdown = defaultRenderDropdown,
...props
}: Props) => {
if (defaultSelectedItems != null && selectedItems != null) {
Expand Down Expand Up @@ -156,22 +160,25 @@ const Dropdown = ({
})
}
</Reference>
{isOpen && (
<DropdownList
ref={ref}
style={style}
twoColumn={twoColumn}
items={items}
categories={categories}
inputValue={inputValue}
getItemProps={getItemProps}
useFilter={useFilter}
filterFn={filterFn}
highlightedIndex={highlightedIndex}
selectedItems={selectedItems}
highlight={highlight}
/>
)}
{isOpen &&
renderDropdown({
dropdown: (
<DropdownList
ref={ref}
style={style}
twoColumn={twoColumn}
items={items}
categories={categories}
inputValue={inputValue}
getItemProps={getItemProps}
useFilter={useFilter}
filterFn={filterFn}
highlightedIndex={highlightedIndex}
selectedItems={selectedItems}
highlight={highlight}
/>
),
})}
</DevFragment>
)}
</Popper>
Expand Down
36 changes: 36 additions & 0 deletions packages/react-dropdown/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,3 +156,39 @@ const items = [
)}
</Dropdown>;
```

#### Dropdown with custom render function:

```js
const ReactDOM = require('react-dom');

const items = [
{ id: 1, label: 'Alaska airlines' },
{ id: 2, label: 'Allegiant Air' },
{ id: 3, label: 'American Airlines' },
{ id: 4, label: 'Delta Air Lines' },
{ id: 5, label: 'Frontier Airlines' },
{ id: 6, label: 'Hawaiian Airlines' },
{ id: 7, label: 'JetBlue Airways' },
{ id: 8, label: 'Southwest Airlines' },
{ id: 9, label: 'Spirit Airlines' },
{ id: 10, label: 'Sun Country Airlines' },
{ id: 11, label: 'United Airlines' },
];
<Dropdown
items={items}
useFilter={true}
highlight={true}
renderDropdown={({ dropdown }) =>
ReactDOM.createPortal(dropdown, document.querySelector('#rsg-root'))
}
>
{({ getInputProps }) => (
<InputText
style={{ width: 300 }}
placeholder="Type the word 'airlines' to see highlights..."
{...getInputProps()}
/>
)}
</Dropdown>;
```
15 changes: 15 additions & 0 deletions packages/react-dropdown/src/index.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -750,3 +750,18 @@ it('empty selected items should result in empty string input value ', () => {
.props().value
).toBe(11);
});

it('custom renderDropdown function should render', () => {
const wrapper = mount(
<DropdownWrapper
initialSelectedItems={[]}
items={[{ id: 11, label: 'asd' }]}
defaultIsOpen={true}
renderDropdown={({ dropdown }) => <div id="foobar">{dropdown}</div>}
/>
);

expect(wrapper.find('#foobar')).toHaveLength(1);

expect(wrapper.find('ul li').hostNodes().length > 0).toBe(true);
});

0 comments on commit de5a528

Please sign in to comment.