Skip to content
This repository was archived by the owner on Mar 4, 2020. It is now read-only.

Commit d9648ed

Browse files
silviuaavramkuzhelov
authored andcommitted
Feat/multi dropdown component (#422)
* first changes picked up from people picker prototype * added state reducer and created test component to refresh items prop * fixed mouse selection and removed downshift selectedItem on multiple * removed label, its style and fixed width * fixed maxWidth, backspace deletion and label for remove button * added the content color list item variable back * added toggle button to the dropdown * added list inside container to fix width issue * added fluid prop changes * added white background on no results list item * added toggle button conditional padding * destructured some props in styles * added more examples and on search change callback * added example with only text items, made content mandatory * reverted header and content optional property * stopped click propagation on label content * changed the var names for input and active * moved downshift to dependencies * added callbacks for generating custom dropdown messages * made the dropdown an autocontrolled component * moved some examples to variations * stop propagation when clicking on label header and image * some typings and applied optional props correctly * fixed the conditional parameters passing * exposed optional prop itemToString * added container styles as classNames * added typings for the rest of the methods * adressed some conformance errors * added isConformant test * added and renamed event handlers * added isconformant test for dropdown * rename onChange methods to make test pass [hack to remove] * refactored ref from slot * updated styles after rebase * moved desc to interface, prop renames, custom a11status * refactored the aria live implementation for add and remove * fixed StatusMessageOptions type issue * addded listRef back with correct implementation * added listRef callback directly * removed comment from test file * commited lock * updated the styles * refactored the refs * fixed list and menu overlapping * added the scroll bar back * renamed the ref providing wrapper * refactored the examples, added placeholder to all * addressed Marija and Sofiya code reviews * moved innerRef prop from Input to Slot * removed onContainerClick prop * removed onBackspaceDelete prop * added shorthands for Label and ListItem in Dropdown * changed some propTypes * shorthanded the input * strings for example, downshift props as handled objects * changes in the descriptions of the api * integrated filtering of options to the component * addressed commonPropTypes changes * renamed onChange to onSelectedChange * added changes to the api description, also code comments * updated the texts for the subcomponents as well * subcomponents as static fields of the dropdown, and some text correction * added image shorthand to list item media + highlighted is active now * fixed UTs * removed the render functions from shorthands * changes related to applying styles * changed the examples to reflect text as being the default item * added additional check for refProvidingWrapper * fixed the inner ref issue accordingly * fixed input styles * removed the aria live strings from the component * remove unnecessary state from examples * addressed code review * removed no items text from component, added to examples * removed unused variables param * remove leftovers from docs, simplify props descriptions * refactor and apply fixes to Dropdown * introduce fixes to DropdownLabel * fix generic parameters of prop types for dropdown components * pass styles to DropdownLabel instead of classes * add fogottent prop to theme styles types * prevent downshift dependency to leak through the public API * fix lint issues * remove duplicated input example * update changelog
1 parent 0cb1b48 commit d9648ed

26 files changed

+1492
-10
lines changed

CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ This project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.htm
3232
### Features
3333
- `Ref` components uses `forwardRef` API by default @layershifter ([#491](https://github.com/stardust-ui/react/pull/491))
3434
- Label Processed Teams icons moved to Stardust theme @kuzhelov ([#574](https://github.com/stardust-ui/react/pull/574))
35+
- Add `Dropdown` component @silviuavram ([#422](https://github.com/stardust-ui/react/pull/422))
3536

3637
### Documentation
3738
- Add `prettier` support throughout the docs @levithomason ([#568](https://github.com/stardust-ui/react/pull/568))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
import * as React from 'react'
2+
import { Dropdown } from '@stardust-ui/react'
3+
4+
const inputItems = [
5+
'Bruce Wayne',
6+
'Natasha Romanoff',
7+
'Steven Strange',
8+
'Alfred Pennyworth',
9+
`Scarlett O'Hara`,
10+
'Imperator Furiosa',
11+
'Bruce Banner',
12+
'Peter Parker',
13+
'Selina Kyle',
14+
]
15+
16+
class DropdownExample extends React.Component {
17+
render() {
18+
return (
19+
<Dropdown
20+
multiple
21+
search
22+
getA11ySelectionMessage={getA11ySelectionMessage}
23+
getA11yStatusMessage={getA11yStatusMessage}
24+
noResultsMessage="We couldn't find any matches."
25+
placeholder="Start typing a name"
26+
items={inputItems}
27+
/>
28+
)
29+
}
30+
}
31+
32+
const getA11ySelectionMessage = {
33+
onAdd: item => `${item} has been selected.`,
34+
onRemove: item => `${item} has been removed.`,
35+
}
36+
37+
const getA11yStatusMessage = ({
38+
isOpen,
39+
itemToString,
40+
previousResultCount,
41+
resultCount,
42+
selectedItem,
43+
}) => {
44+
if (!isOpen) {
45+
return selectedItem ? itemToString(selectedItem) : ''
46+
}
47+
if (!resultCount) {
48+
return 'No results are available.'
49+
}
50+
if (resultCount !== previousResultCount) {
51+
return `${resultCount} result${
52+
resultCount === 1 ? ' is' : 's are'
53+
} available, use up and down arrow keys to navigate. Press Enter key to select.`
54+
}
55+
return ''
56+
}
57+
58+
export default DropdownExample
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import * as React from 'react'
2+
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
3+
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'
4+
5+
const Types = () => (
6+
<ExampleSection title="Types">
7+
<ComponentExample
8+
title="Multiple Search"
9+
description="A dropdown with multiple selection and search."
10+
examplePath="components/Dropdown/Types/DropdownExampleMultipleSearch.shorthand"
11+
/>
12+
</ExampleSection>
13+
)
14+
15+
export default Types
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import * as React from 'react'
2+
import { Dropdown } from '@stardust-ui/react'
3+
4+
const inputItems = [
5+
'Bruce Wayne',
6+
'Natasha Romanoff',
7+
'Steven Strange',
8+
'Alfred Pennyworth',
9+
`Scarlett O'Hara`,
10+
'Imperator Furiosa',
11+
'Bruce Banner',
12+
'Peter Parker',
13+
'Selina Kyle',
14+
]
15+
16+
class DropdownExample extends React.Component {
17+
render() {
18+
return (
19+
<Dropdown
20+
multiple
21+
getA11ySelectionMessage={getA11ySelectionMessage}
22+
getA11yStatusMessage={getA11yStatusMessage}
23+
noResultsMessage="We couldn't find any matches."
24+
search
25+
fluid
26+
placeholder="Start typing a name"
27+
items={inputItems}
28+
/>
29+
)
30+
}
31+
}
32+
33+
const getA11ySelectionMessage = {
34+
onAdd: item => `${item} has been selected.`,
35+
onRemove: item => `${item} has been removed.`,
36+
}
37+
38+
const getA11yStatusMessage = ({
39+
isOpen,
40+
itemToString,
41+
previousResultCount,
42+
resultCount,
43+
selectedItem,
44+
}) => {
45+
if (!isOpen) {
46+
return selectedItem ? itemToString(selectedItem) : ''
47+
}
48+
if (!resultCount) {
49+
return 'No results are available.'
50+
}
51+
if (resultCount !== previousResultCount) {
52+
return `${resultCount} result${
53+
resultCount === 1 ? ' is' : 's are'
54+
} available, use up and down arrow keys to navigate. Press Enter key to select.`
55+
}
56+
return ''
57+
}
58+
59+
export default DropdownExample
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
import * as React from 'react'
2+
import { Dropdown } from '@stardust-ui/react'
3+
4+
const inputItems = [
5+
{
6+
header: 'Bruce Wayne',
7+
image: 'public/images/avatar/small/matt.jpg',
8+
content: 'Software Engineer',
9+
},
10+
{
11+
header: 'Natasha Romanoff',
12+
image: 'public/images/avatar/small/jenny.jpg',
13+
content: 'UX Designer 2',
14+
},
15+
{
16+
header: 'Steven Strange',
17+
image: 'public/images/avatar/small/joe.jpg',
18+
content: 'Principal Software Engineering Manager',
19+
},
20+
{
21+
header: 'Alfred Pennyworth',
22+
image: 'public/images/avatar/small/justen.jpg',
23+
content: 'Technology Consultant',
24+
},
25+
{
26+
header: `Scarlett O'Hara`,
27+
image: 'public/images/avatar/small/laura.jpg',
28+
content: 'Software Engineer 2',
29+
},
30+
{
31+
header: 'Imperator Furiosa',
32+
image: 'public/images/avatar/small/veronika.jpg',
33+
content: 'Boss',
34+
},
35+
{
36+
header: 'Bruce Banner',
37+
image: 'public/images/avatar/small/chris.jpg',
38+
content: 'Senior Computer Scientist',
39+
},
40+
{
41+
header: 'Peter Parker',
42+
image: 'public/images/avatar/small/daniel.jpg',
43+
content: 'Partner Software Engineer',
44+
},
45+
{
46+
header: 'Selina Kyle',
47+
image: 'public/images/avatar/small/ade.jpg',
48+
content: 'Graphic Designer',
49+
},
50+
]
51+
52+
class DropdownExample extends React.Component {
53+
render() {
54+
return (
55+
<Dropdown
56+
multiple
57+
getA11yStatusMessage={getA11yStatusMessage}
58+
search
59+
getA11ySelectionMessage={getA11ySelectionMessage}
60+
noResultsMessage="We couldn't find any matches."
61+
placeholder="Start typing a name"
62+
items={inputItems}
63+
/>
64+
)
65+
}
66+
}
67+
68+
const getA11ySelectionMessage = {
69+
onAdd: item => `${item.header} has been selected.`,
70+
onRemove: item => `${item.header} has been removed.`,
71+
}
72+
73+
const getA11yStatusMessage = ({
74+
isOpen,
75+
itemToString,
76+
previousResultCount,
77+
resultCount,
78+
selectedItem,
79+
}) => {
80+
if (!isOpen) {
81+
return selectedItem ? itemToString(selectedItem) : ''
82+
}
83+
if (!resultCount) {
84+
return 'No results are available.'
85+
}
86+
if (resultCount !== previousResultCount) {
87+
return `${resultCount} result${
88+
resultCount === 1 ? ' is' : 's are'
89+
} available, use up and down arrow keys to navigate. Press Enter key to select.`
90+
}
91+
return ''
92+
}
93+
94+
export default DropdownExample
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import * as React from 'react'
2+
import { Dropdown } from '@stardust-ui/react'
3+
4+
const inputItems = [
5+
'Bruce Wayne',
6+
'Natasha Romanoff',
7+
'Steven Strange',
8+
'Alfred Pennyworth',
9+
`Scarlett O'Hara`,
10+
'Imperator Furiosa',
11+
'Bruce Banner',
12+
'Peter Parker',
13+
'Selina Kyle',
14+
]
15+
16+
class DropdownExample extends React.Component {
17+
render() {
18+
return (
19+
<Dropdown
20+
multiple
21+
getA11yStatusMessage={getA11yStatusMessage}
22+
getA11ySelectionMessage={getA11ySelectionMessage}
23+
noResultsMessage="We couldn't find any matches."
24+
search
25+
placeholder="Start typing a name"
26+
toggleButton
27+
items={inputItems}
28+
/>
29+
)
30+
}
31+
}
32+
33+
const getA11ySelectionMessage = {
34+
onAdd: item => `${item} has been selected.`,
35+
onRemove: item => `${item} has been removed.`,
36+
}
37+
38+
const getA11yStatusMessage = ({
39+
isOpen,
40+
itemToString,
41+
previousResultCount,
42+
resultCount,
43+
selectedItem,
44+
}) => {
45+
if (!isOpen) {
46+
return selectedItem ? itemToString(selectedItem) : ''
47+
}
48+
if (!resultCount) {
49+
return 'No results are available.'
50+
}
51+
if (resultCount !== previousResultCount) {
52+
return `${resultCount} result${
53+
resultCount === 1 ? ' is' : 's are'
54+
} available, use up and down arrow keys to navigate. Press Enter key to select.`
55+
}
56+
return ''
57+
}
58+
59+
export default DropdownExample
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
import React from 'react'
2+
import ComponentExample from 'docs/src/components/ComponentDoc/ComponentExample'
3+
import ExampleSection from 'docs/src/components/ComponentDoc/ExampleSection'
4+
5+
const Variations = () => (
6+
<ExampleSection title="Variations">
7+
<ComponentExample
8+
title="Multiple Search with Image and Content"
9+
description="A multiple search dropdown which items have header, content and image."
10+
examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchImageAndContent.shorthand"
11+
/>
12+
<ComponentExample
13+
title="Multiple Search Fluid"
14+
description="A multiple search dropdown that fits the width of the container."
15+
examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchFluid.shorthand"
16+
/>
17+
<ComponentExample
18+
title="Multiple Search with Toggle Button"
19+
description="A multiple search dropdown with toggle button that shows/hides the items list."
20+
examplePath="components/Dropdown/Variations/DropdownExampleMultipleSearchToggleButton.shorthand"
21+
/>
22+
</ExampleSection>
23+
)
24+
25+
export default Variations
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import * as React from 'react'
2+
import Types from './Types'
3+
import Variations from './Variations'
4+
5+
const DropdownExamples = () => (
6+
<div>
7+
<Types />
8+
<Variations />
9+
</div>
10+
)
11+
12+
export default DropdownExamples

docs/src/examples/components/Input/Variations/InputExampleInputSlot.shorthand.tsx

-7
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,6 @@ const InputExampleInputSlot = () => (
3636
/>
3737
}
3838
/>
39-
40-
<Text content="Wrapped Input with custom element:" />
41-
<Input
42-
placeholder="Search..."
43-
role="presentation"
44-
input={<input placeholder="Placeholder Override..." role="checkbox" style={inputStyles} />}
45-
/>
4639
</Grid>
4740
)
4841

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@
6060
"dependencies": {
6161
"classnames": "^2.2.5",
6262
"color": "^3.1.0",
63+
"downshift": "^3.0.0",
6364
"fela": "^6.1.7",
6465
"fela-plugin-fallback-value": "^5.0.17",
6566
"fela-plugin-placeholder-prefixer": "^5.0.18",

0 commit comments

Comments
 (0)