Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Virtualize dropdown options list #284

Merged
merged 21 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
e6aad39
Prevent generating duplicate cities
dawsonbooth Aug 9, 2021
80ce173
Show value in `onSelect` action
dawsonbooth Aug 9, 2021
0004a9b
Fix placeholder for `Icons` story
dawsonbooth Aug 9, 2021
805ed04
feat(dropdown): virtualize options list for better performance of lon…
dawsonbooth Aug 9, 2021
3981619
Merge branch 'master' into 184-virtual-dropdown
dawsonbooth Aug 9, 2021
37802f2
#184 Fix keyboard navigation
dawsonbooth Aug 10, 2021
a66adf5
#184 Set `initialItemCount` to pass tests
dawsonbooth Aug 10, 2021
059d4fe
Fix duplicate options prevention
dawsonbooth Aug 10, 2021
8727658
#184 Only virtualize options when DOM is available
dawsonbooth Aug 11, 2021
c0167d5
Fix dropdown stories style and performance
dawsonbooth Aug 11, 2021
449bf70
#184 Modify number of options to render initially
dawsonbooth Aug 11, 2021
cfa9fca
#184 Remember scroll position after close
dawsonbooth Aug 11, 2021
e32d398
#184 Remove virtualization if less than max height
dawsonbooth Aug 12, 2021
f79835e
#184 Adjust naming for nested elements on keypress
dawsonbooth Aug 12, 2021
823cb18
Improve city option item variable naming
dawsonbooth Aug 12, 2021
2aa71d2
Improve performance of city option generation
dawsonbooth Aug 12, 2021
004ed15
#184 Add state for whether to virtualize options
dawsonbooth Aug 12, 2021
ffe6cb3
#184 Refactor keypress handler and nested scroller
dawsonbooth Aug 12, 2021
31fcd45
#184 Remember scroll position for non-virtual list
dawsonbooth Aug 12, 2021
11e7cd4
#184 Remove extra timeout and document navigation
dawsonbooth Aug 12, 2021
2c9c7a0
#184 Add open/close timeout to improve performance
dawsonbooth Aug 12, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@
"nanoid": "^3.1.20",
"polished": "^4.1.1",
"react-portal": "^4.2.1",
"react-virtuoso": "^1.10.5",
"src": "^1.1.2"
},
"peerDependencies": {
Expand Down
45 changes: 32 additions & 13 deletions src/components/Dropdown/Dropdown.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState } from 'react';
import React, { useState, useEffect } from 'react';

import { Story, Meta } from '@storybook/react';
import { address } from 'faker';
Expand All @@ -11,33 +11,49 @@ import Label from '../Label';
import { colors } from '../../index';

const generateCityList = (amount: number): OptionProps[] => {
const finalData = [];
const citySet = new Set<string>();
const cityOptions: OptionProps[] = [];

for (let i = 0; i < amount; i += 1) {
const item = address.city();
finalData.push({
id: item.toLowerCase(),
optionValue: item,
let city = address.city();
while (citySet.has(city)) {
city = address.city();
}
citySet.add(city);
cityOptions.push({
id: city.toLowerCase(),
optionValue: city,
});
}

return finalData;
return cityOptions;
};
const cities = generateCityList(50);

type BasicProps = DropdownProps & { clearable: boolean };
type BasicProps = DropdownProps & { clearable: boolean; numCities: number };

export const Basic: Story<BasicProps> = ({ clearable, onClear, onSelect }: BasicProps) => {
export const Basic: Story<BasicProps> = ({
clearable,
numCities,
onClear,
onSelect,
...args
}: BasicProps) => {
const [cities, setCities] = useState<OptionProps[]>([]);
const [values, setValues] = useState<(string | number)[] | undefined>();

useEffect(() => {
setCities(generateCityList(numCities));
}, [numCities]);

return (
<Label labelText="City" htmlFor="cities-list">
<Dropdown
{...args}
name="cities-list"
onClear={clearable ? onClear : undefined}
onSelect={(selected?: Array<string | number>) => {
setValues(selected);
return onSelect();
return onSelect(selected);
}}
options={cities}
values={values}
Expand All @@ -55,6 +71,8 @@ Basic.args = {
variant: variants.fill,
optionsVariant: variants.outline,
valueVariant: variants.text,
numCities: 200,
virtualizeOptions: true,
};

const teaOptions = [
Expand Down Expand Up @@ -98,7 +116,7 @@ const teaOptions = [
},
];

export const Icons: Story = args => {
export const Icons: Story<DropdownProps> = ({ onSelect, ...args }: DropdownProps) => {
const [values, setValues] = useState<(string | number)[] | undefined>();
return (
<Label labelText="How strong do you like your tea?" htmlFor="tea-rank">
Expand All @@ -107,7 +125,7 @@ export const Icons: Story = args => {
name="tea-rank"
onSelect={(selected?: Array<string | number>) => {
setValues(selected);
return args.onSelect();
return onSelect(selected);
}}
options={teaOptions}
values={values}
Expand All @@ -117,6 +135,7 @@ export const Icons: Story = args => {
};
Icons.args = {
...Basic.args,
placeholder: 'Choose a rating...',
aVileBroker marked this conversation as resolved.
Show resolved Hide resolved
color: '#0A7700',
elevation: 1,
};
Expand Down
Loading