Skip to content

Commit

Permalink
fix: fixes dropdown search design and innovaccer#37
Browse files Browse the repository at this point in the history
  • Loading branch information
riyalohia committed May 29, 2020
1 parent ed4bd9f commit 00b39b0
Show file tree
Hide file tree
Showing 13 changed files with 1,817 additions and 1,753 deletions.
81 changes: 44 additions & 37 deletions core/components/atoms/dropdown/Dropdown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,16 +88,21 @@ export const Dropdown = (props: DropdownProps) => {
value: [],
});

const debounceSearch = debounce(300, (search: string) => {
setSearchTerm(search);
});

const getDropdownOptions = (offset: number, optionsLimit: number, direction: string | undefined) => {
const debounceSearch = React.useCallback(debounce(300, (search: string) => {
renderOptionsFromTop(search);
}), []);

const getDropdownOptions = (
offset: number,
optionsLimit: number,
direction?: string,
search: string = searchTerm
) => {
const bufferedOptionPresent = direction === 'up' && !(offset < 0);
const updatedLimit = direction === 'up' ? (offset < 0 ? optionsLimit : optionsLimit + 1) : optionsLimit;
const updatedOffset = direction === 'up' ? (offset < 0 ? offset + 1 : offset) : offset;

let getPaginatedOptions = async && (direction || searchTerm) ? loadMoreOptions : getOptions;
let getPaginatedOptions = async && (direction || search) ? loadMoreOptions : getOptions;
if (props.options.length < optionsLimit && async && loadMoreOptions) {
getPaginatedOptions = loadMoreOptions;
}
Expand All @@ -107,7 +112,7 @@ export const Dropdown = (props: DropdownProps) => {
if (async && direction === 'down') setLoadingMoreDown(true);
if (getPaginatedOptions === loadMoreOptions && !direction) setLoading(true);

getPaginatedOptions(updatedOffset, updatedLimit, searchTerm, props.options).then((res: any) => {
getPaginatedOptions(updatedOffset, updatedLimit, search, props.options).then((res: any) => {
if (async && direction === 'up') setLoadingMoreUp(false);
if (async && direction === 'down') setLoadingMoreDown(false);
if (getPaginatedOptions === loadMoreOptions && !direction) setLoading(false);
Expand All @@ -116,7 +121,7 @@ export const Dropdown = (props: DropdownProps) => {
const { options: slicedOptions, length } = res;
const len = limit - slicedOptions.length;
const slicedLength = bufferedOptionPresent ? len + 1 : len;
if (!searchTerm && optionsLength !== length) setOptionLength(length);
if (!search && optionsLength !== length) setOptionLength(length);
setSlicedOptionLength(slicedLength);
updateOptionsOnScroll(slicedOptions, updatedOffset, direction, slicedLength, bufferedOptionPresent);
} else {
Expand All @@ -129,11 +134,11 @@ export const Dropdown = (props: DropdownProps) => {
}
};

const renderOptionsFromTop = () => {
const renderOptionsFromTop = (search: string = searchTerm) => {
if (props.options.length > 0) {
const emptyBuffer: Option = { value: '', label: '' };
setBufferedOption(emptyBuffer);
getDropdownOptions(0, limit, undefined);
getDropdownOptions(0, limit, undefined, search);
setTopOffset(0);
setBottomOffset(0);
}
Expand All @@ -145,10 +150,14 @@ export const Dropdown = (props: DropdownProps) => {

React.useEffect(() => {
renderOptionsFromTop();
}, [JSON.stringify(props.options), limit, searchTerm]);
}, [JSON.stringify(props.options), limit]);

React.useEffect(() => {
debounceSearch(searchTerm);
}, [searchTerm]);

const onSearchChange = (search: string) => {
debounceSearch(search);
setSearchTerm(search);
};

const updateOptionsOnScroll = (
Expand Down Expand Up @@ -213,31 +222,29 @@ export const Dropdown = (props: DropdownProps) => {
};

return (
<div>
<DropdownList
listOptions={options}
bufferedOption={bufferedOption}
slicedOptionsLength={slicedOptionLength}
loadingMoreUp={loadingMoreUp}
loadingMoreDown={loadingMoreDown}
loadingOptions={loading}
async={async}
selected={selected}
searchTerm={searchTerm}
onScroll={OnScrollOptions}
topOptionsSliced={topOptionsSliced}
bottomOptionsSliced={bottomOptionsSliced}
limit={limit}
offset={topOffset}
optionsLength={props.options.length}
onSearchChange={onSearchChange}
onChange={onChangeOptions}
onSelectAll={onSelectAll}
setSearchTerm={onSearchChange}
renderOptionsFromTop={renderOptionsFromTop}
{...rest}
/>
</div>
<DropdownList
listOptions={options}
bufferedOption={bufferedOption}
slicedOptionsLength={slicedOptionLength}
loadingMoreUp={loadingMoreUp}
loadingMoreDown={loadingMoreDown}
loadingOptions={loading}
async={async}
selected={selected}
searchTerm={searchTerm}
onScroll={OnScrollOptions}
topOptionsSliced={topOptionsSliced}
bottomOptionsSliced={bottomOptionsSliced}
limit={limit}
offset={topOffset}
optionsLength={props.options.length}
onSearchChange={onSearchChange}
onChange={onChangeOptions}
onSelectAll={onSelectAll}
setSearchTerm={onSearchChange}
renderOptionsFromTop={renderOptionsFromTop}
{...rest}
/>
);
};

Expand Down
14 changes: 12 additions & 2 deletions core/components/atoms/dropdown/__stories__/index.story.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,11 +13,17 @@ export const all = () => {
);

const dropdownAlign = select(
'dropdownAlign',
'Dropdown Alignmnet',
['left', 'right'],
undefined
);

const buttonAppearance = select(
'Button Appearance',
['basic', 'transparent'],
undefined
);

const disabled = boolean('disabled', false);

const menu = boolean('menu', false);
Expand All @@ -38,6 +44,8 @@ export const all = () => {

const placeholder = text('placeholder', 'Select');

const parentCheckboxLabel = text('parentCheckboxLabel', 'Select All');

const inlineLabel = text('inline label', '');

const checkedValuesOffset = number('checked offset', 2);
Expand Down Expand Up @@ -71,6 +79,7 @@ export const all = () => {
const props = {
size,
dropdownAlign,
buttonAppearance,
icon,
placeholder,
inlineLabel,
Expand All @@ -86,6 +95,7 @@ export const all = () => {
limit,
loading,
loadMoreOptions,
parentCheckboxLabel,
options: dropdownOptions,
onChange: onChangeHandler,
style: {
Expand All @@ -105,7 +115,7 @@ export const all = () => {
const customCode = `() => {
const options = [{label: 'Option1',value: 'Option1'},{label: 'Option2',value: 'Option2'},{label: 'Option3',value: 'Option3'},{label: 'Option4',value: 'Option4'},{label: 'Option5',value: 'Option5'},{label: 'Option6',value: 'Option6'},{label: 'Option7',value: 'Option7'},{label: 'Option8',value: 'Option8'},{label: 'Option9',value: 'Option9'},{label: 'Option10',value: 'Option10'}];
return (
<div style={{minHeight: '250px'}}>
<div style={{minHeight: '250px', width: '150px'}}>
<Dropdown
options={options}
placeholder={'Select'}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const align = () => {
{
dropdownAlignments.map((alignment, ind) => {
return (
<div key={ind} style={{ marginRight: '10%' }}>
<div key={ind} style={{ marginRight: '20%' }}>
<Text weight="strong">{alignment.charAt(0).toUpperCase() + alignment.slice(1)}</Text> <br /><br />
<Dropdown dropdownAlign={alignment} options={storyOptions} menu={true} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const async = () => {
{
BooleanValue.map((value, ind) => {
return (
<div key={ind} style={{ marginRight: '10%' }}>
<div key={ind} style={{ marginRight: '10%', width: '128px' }}>
<Text weight="strong">{value ? 'With Async' : 'Without Async'}</Text> <br /><br />
<Dropdown async={value} options={dropdownOptions} loadMoreOptions={loadMoreOptions}/>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const itemStates = () => {
<Dropdown options={iconItems} placeholder={'Select'} />
}
</div>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '128px' }}>
<Text weight="strong">{'Checkboxes'}</Text><br />
{
<Dropdown options={storyOptions.slice(0, 3)} checkboxes={true} placeholder={'Select'} />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,29 @@ import { storyOptions } from '../../utils/Options';

// CSF format story
export const multiOptions = () => {
const style = {
display: 'flex',
'flex-direction': 'column',
alignItems: 'center',
marginRight: '5%',
width: '150px'
};

return (
<div style={{ display: 'flex', minHeight: '300px' }}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', marginRight: '5%' }}>
<div style={style}>
<Text weight="strong">{'With Apply Button'}</Text><br />
{
<Dropdown maxHeight={150} checkboxes={true} showApplyButton={true} options={storyOptions} placeholder={'Select'} />
}
<Dropdown
maxHeight={150}
checkboxes={true}
showApplyButton={true}
options={storyOptions}
placeholder={'Select'}
/>
</div>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center' }}>
<div style={{ display: 'flex', flexDirection: 'column', alignItems: 'center', width: '150px' }}>
<Text weight="strong">{'Without Apply Button'}</Text><br />
{
<Dropdown checkboxes={true} options={storyOptions} placeholder={'Select'} />
}
<Dropdown checkboxes={true} options={storyOptions} placeholder={'Select'} />
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const search = () => {
</div>
<div>
<Text weight="strong">{'No Result'}</Text><br /><br />
<Dropdown search={true} placeholder={'Select'} options={[]} searchResultMessage={'No Result Found'}/>
<Dropdown search={true} placeholder={'Select'} options={[]} searchResultMessage={'No result found'}/>
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import * as React from 'react';
import Dropdown from '../../../Dropdown';
import Text from '@/components/atoms/text';
import { storyOptions } from '../../../utils/Options';
import { ButtonAppearance } from '../../../dropdownList';

// CSF format story
export const appearance = () => {
const appearances: ButtonAppearance[] = ['basic', 'transparent'];

return (
<div style={{ display: 'flex', minHeight: '270px' }}>
{
appearances.map((color, ind) => {
return (
<div style={{ marginRight: '5%' }} key={ind}>
<Text weight="strong">{color.charAt(0).toUpperCase() + color.slice(1)}</Text> <br /><br />
<Dropdown buttonAppearance={color} options={storyOptions} />
</div>
);
})
}
</div>
);
};

export default {
title: 'Atoms|Dropdown/Variants/Button',
component: Dropdown,
parameters: {
docs: {
docPage: {
title: 'Dropdown'
}
}
}
};
Loading

0 comments on commit 00b39b0

Please sign in to comment.