Skip to content
This repository was archived by the owner on Oct 19, 2021. It is now read-only.

Commit a7c293c

Browse files
authored
fix(DropdownV2): match experimental spec (#2093)
* docs(DropdownV2): add invalid knob * chore: bump carbon-components version * fix(ListBox): add v10 listbox classes * fix(DropdownV2): add disabled form and v10 classes * refactor(ListBox): deprecate `type` prop * feat(DropdownV2): integrate v10 listbox * test: update snapshots and inline variant test * Revert "refactor(ListBox): deprecate `type` prop" This reverts commit 642c01a. * Revert "test: update snapshots and inline variant test" This reverts commit d98db03. * docs(ListBox): add propType * fix(Dropdown): use listbox light and invalid style * docs(DropdownV2): change options list placeholder * fix(Dropdown): remove breaking changes flag * test: update snapshots * chore: bump carbon-components version * chore: bump carbon-components version * chore: bump carbon-components version * chore: bump carbon-components version * fix(ListBoxMenuItem): add conditional for v10 * fix(DropdownV2): add disabled class * fix(DropdownV2): add light class * chore: update snapshots * refactor(ListBoxMenuItem): remove unneeded attrs * chore: bump carbon-components version * refactor(DropdownV2): remove wrapper from v9 * chore: update snapshot
1 parent 4a677b4 commit a7c293c

File tree

9 files changed

+143
-75
lines changed

9 files changed

+143
-75
lines changed
-2.21 MB
Binary file not shown.
2.22 MB
Binary file not shown.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -181,7 +181,7 @@
181181
"babel-plugin-dev-expression": "^0.2.1",
182182
"babel-plugin-react-docgen": "^2.0.0",
183183
"bowser": "^1.6.1",
184-
"carbon-components": "^9.87.2",
184+
"carbon-components": "^9.90.9",
185185
"carbon-icons": "^7.0.5",
186186
"chalk": "^2.3.0",
187187
"cli-table": "^0.3.0",

src/components/DropdownV2/DropdownV2-story.js

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,17 @@ const types = {
4747

4848
const props = () => ({
4949
type: select('Dropdown type (type)', types, 'default'),
50-
label: text('Label (label)', 'Label'),
50+
label: text('Label (label)', 'Dropdown menu options'),
5151
ariaLabel: text('Aria Label (ariaLabel)', 'Dropdown'),
5252
disabled: boolean('Disabled (disabled)', false),
5353
light: boolean('Light variant (light)', false),
5454
titleText: text('Title (titleText)', 'This is not a dropdown title.'),
5555
helperText: text('Helper text (helperText)', 'This is not some helper text.'),
56+
invalid: boolean('Show form validation UI (invalid)', false),
57+
invalidText: text(
58+
'Form validation UI content (invalidText)',
59+
'A valid value is required'
60+
),
5661
});
5762

5863
const itemToElement = item => {

src/components/DropdownV2/DropdownV2.js

Lines changed: 110 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@ import Downshift from 'downshift';
1010
import PropTypes from 'prop-types';
1111
import React from 'react';
1212
import { settings } from 'carbon-components';
13+
import WarningFilled16 from '@carbon/icons-react/lib/warning--filled/16';
1314
import ListBox, { PropTypes as ListBoxPropTypes } from '../ListBox';
15+
import { componentsX } from '../../internal/FeatureFlags';
1416

1517
const { prefix } = settings;
1618

@@ -44,6 +46,21 @@ export default class DropdownV2 extends React.Component {
4446
PropTypes.string,
4547
]),
4648

49+
/**
50+
* Specify whether you want the inline version of this control
51+
*/
52+
inline: PropTypes.bool,
53+
54+
/**
55+
* Specify if the currently selected value is invalid.
56+
*/
57+
invalid: PropTypes.bool,
58+
59+
/**
60+
* Message which is displayed if the value is invalid.
61+
*/
62+
invalidText: PropTypes.string,
63+
4764
/**
4865
* Helper function passed to downshift that allows the library to render a
4966
* given item to a string label. By default, it extracts the `label` field
@@ -130,85 +147,117 @@ export default class DropdownV2 extends React.Component {
130147
type,
131148
initialSelectedItem,
132149
selectedItem,
133-
light,
134150
id,
135151
titleText,
136152
helperText,
153+
light,
154+
invalid,
155+
invalidText,
137156
} = this.props;
138-
const className = cx(`${prefix}--dropdown`, containerClassName, {
139-
[`${prefix}--dropdown--light`]: light,
157+
const inline = type === 'inline';
158+
const className = ({ isOpen }) =>
159+
cx(`${prefix}--dropdown`, containerClassName, {
160+
[`${prefix}--dropdown--invalid`]: invalid,
161+
[`${prefix}--dropdown--open`]: isOpen,
162+
[`${prefix}--dropdown--inline`]: inline,
163+
[`${prefix}--dropdown--disabled`]: disabled,
164+
[`${prefix}--dropdown--light`]: light,
165+
});
166+
const titleClasses = cx(`${prefix}--label`, {
167+
[`${prefix}--label--disabled`]: disabled,
140168
});
141169
const title = titleText ? (
142-
<label htmlFor={id} className={`${prefix}--label`}>
170+
<label htmlFor={id} className={titleClasses}>
143171
{titleText}
144172
</label>
145173
) : null;
174+
const helperClasses = cx(`${prefix}--form__helper-text`, {
175+
[`${prefix}--form__helper-text--disabled`]: disabled,
176+
});
146177
const helper = helperText ? (
147-
<div className={`${prefix}--form__helper-text`}>{helperText}</div>
178+
<div className={helperClasses}>{helperText}</div>
148179
) : null;
180+
const wrapperClasses = cx(
181+
`${prefix}--dropdown__wrapper`,
182+
`${prefix}--list-box__wrapper`,
183+
{
184+
[`${prefix}--dropdown__wrapper--inline`]: inline,
185+
[`${prefix}--list-box__wrapper--inline`]: inline,
186+
[`${prefix}--dropdown__wrapper--inline--invalid`]: inline && invalid,
187+
[`${prefix}--list-box__wrapper--inline--invalid`]: inline && invalid,
188+
}
189+
);
149190

150191
// needs to be Capitalized for react to render it correctly
151192
const ItemToElement = itemToElement;
152193
const Dropdown = (
153-
<Downshift
154-
id={id}
155-
onChange={this.handleOnChange}
156-
itemToString={itemToString}
157-
defaultSelectedItem={initialSelectedItem}
158-
selectedItem={selectedItem}>
159-
{({
160-
isOpen,
161-
itemToString,
162-
selectedItem,
163-
highlightedIndex,
164-
getRootProps,
165-
getButtonProps,
166-
getItemProps,
167-
getLabelProps,
168-
}) => (
169-
<ListBox
170-
type={type}
171-
className={className}
172-
disabled={disabled}
173-
ariaLabel={ariaLabel}
174-
{...getRootProps({ refKey: 'innerRef' })}>
175-
<ListBox.Field {...getButtonProps({ disabled })}>
176-
<span
177-
className={`${prefix}--list-box__label`}
178-
{...getLabelProps()}>
179-
{selectedItem ? itemToString(selectedItem) : label}
180-
</span>
181-
<ListBox.MenuIcon isOpen={isOpen} />
182-
</ListBox.Field>
183-
{isOpen && (
184-
<ListBox.Menu>
185-
{items.map((item, index) => (
186-
<ListBox.MenuItem
187-
key={itemToString(item)}
188-
isActive={selectedItem === item}
189-
isHighlighted={
190-
highlightedIndex === index || selectedItem === item
191-
}
192-
{...getItemProps({ item, index })}>
193-
{itemToElement ? (
194-
<ItemToElement key={itemToString(item)} {...item} />
195-
) : (
196-
itemToString(item)
197-
)}
198-
</ListBox.MenuItem>
199-
))}
200-
</ListBox.Menu>
201-
)}
202-
</ListBox>
203-
)}
204-
</Downshift>
205-
);
206-
return title || helper ? (
207194
<>
208195
{title}
209-
{helper}
210-
{Dropdown}
196+
{!inline && helper}
197+
<Downshift
198+
id={id}
199+
onChange={this.handleOnChange}
200+
itemToString={itemToString}
201+
defaultSelectedItem={initialSelectedItem}
202+
selectedItem={selectedItem}>
203+
{({
204+
isOpen,
205+
itemToString,
206+
selectedItem,
207+
highlightedIndex,
208+
getRootProps,
209+
getButtonProps,
210+
getItemProps,
211+
getLabelProps,
212+
}) => (
213+
<ListBox
214+
type={type}
215+
className={className({ isOpen })}
216+
disabled={disabled}
217+
ariaLabel={ariaLabel}
218+
isOpen={isOpen}
219+
invalid={invalid}
220+
invalidText={invalidText}
221+
{...getRootProps({ refKey: 'innerRef' })}>
222+
{componentsX && invalid && (
223+
<WarningFilled16
224+
className={`${prefix}--list-box__invalid-icon`}
225+
/>
226+
)}
227+
<ListBox.Field {...getButtonProps({ disabled })}>
228+
<span
229+
className={`${prefix}--list-box__label`}
230+
{...getLabelProps()}>
231+
{selectedItem ? itemToString(selectedItem) : label}
232+
</span>
233+
<ListBox.MenuIcon isOpen={isOpen} />
234+
</ListBox.Field>
235+
{isOpen && (
236+
<ListBox.Menu>
237+
{items.map((item, index) => (
238+
<ListBox.MenuItem
239+
key={itemToString(item)}
240+
isActive={selectedItem === item}
241+
isHighlighted={
242+
highlightedIndex === index || selectedItem === item
243+
}
244+
{...getItemProps({ item, index })}>
245+
{itemToElement ? (
246+
<ItemToElement key={itemToString(item)} {...item} />
247+
) : (
248+
itemToString(item)
249+
)}
250+
</ListBox.MenuItem>
251+
))}
252+
</ListBox.Menu>
253+
)}
254+
</ListBox>
255+
)}
256+
</Downshift>
211257
</>
258+
);
259+
return componentsX ? (
260+
<div className={wrapperClasses}>{Dropdown}</div>
212261
) : (
213262
Dropdown
214263
);

src/components/DropdownV2/__snapshots__/DropdownV2-test.js.snap

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ exports[`DropdownV2 should render 1`] = `
6565
className="bx--dropdown"
6666
disabled={false}
6767
innerRef={[Function]}
68+
isOpen={false}
6869
type="default"
6970
>
7071
<div
@@ -235,14 +236,15 @@ exports[`DropdownV2 should render DropdownItem components 1`] = `
235236
>
236237
<ListBox
237238
ariaLabel="Choose an item"
238-
className="bx--dropdown"
239+
className="bx--dropdown bx--dropdown--open"
239240
disabled={false}
240241
innerRef={[Function]}
242+
isOpen={true}
241243
type="default"
242244
>
243245
<div
244246
aria-label="Choose an item"
245-
className="bx--dropdown bx--list-box"
247+
className="bx--dropdown bx--dropdown--open bx--list-box bx--list-box--expanded"
246248
onClick={[Function]}
247249
onKeyDown={[Function]}
248250
role="listbox"
@@ -649,14 +651,15 @@ exports[`DropdownV2 should render custom item components 1`] = `
649651
>
650652
<ListBox
651653
ariaLabel="Choose an item"
652-
className="bx--dropdown"
654+
className="bx--dropdown bx--dropdown--open"
653655
disabled={false}
654656
innerRef={[Function]}
657+
isOpen={true}
655658
type="default"
656659
>
657660
<div
658661
aria-label="Choose an item"
659-
className="bx--dropdown bx--list-box"
662+
className="bx--dropdown bx--dropdown--open bx--list-box bx--list-box--expanded"
660663
onClick={[Function]}
661664
onKeyDown={[Function]}
662665
role="listbox"
@@ -955,14 +958,15 @@ exports[`DropdownV2 should render with strings as items 1`] = `
955958
>
956959
<ListBox
957960
ariaLabel="Choose an item"
958-
className="bx--dropdown"
961+
className="bx--dropdown bx--dropdown--open"
959962
disabled={false}
960963
innerRef={[Function]}
964+
isOpen={true}
961965
type="default"
962966
>
963967
<div
964968
aria-label="Choose an item"
965-
className="bx--dropdown bx--list-box"
969+
className="bx--dropdown bx--dropdown--open bx--list-box bx--list-box--expanded"
966970
onClick={[Function]}
967971
onKeyDown={[Function]}
968972
role="listbox"

src/components/ListBox/ListBox.js

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import ListBoxField from './ListBoxField';
1313
import ListBoxMenu from './ListBoxMenu';
1414
import { ListBoxType } from './ListBoxPropTypes';
1515
import childrenOf from '../../prop-types/childrenOf';
16+
import WarningFilled16 from '@carbon/icons-react/lib/warning--filled/16';
1617

1718
const { prefix } = settings;
1819

@@ -42,6 +43,7 @@ const ListBox = ({
4243
invalidText,
4344
light,
4445
innerTabIndex,
46+
isOpen,
4547
...rest
4648
}) => {
4749
const className = cx({
@@ -50,6 +52,7 @@ const ListBox = ({
5052
[`${prefix}--list-box--inline`]: type === 'inline',
5153
[`${prefix}--list-box--disabled`]: disabled,
5254
[`${prefix}--list-box--light`]: light,
55+
[`${prefix}--list-box--expanded`]: isOpen,
5356
});
5457
return (
5558
<>
@@ -74,7 +77,7 @@ const ListBox = ({
7477
};
7578

7679
ListBox.propTypes = {
77-
children: childrenOf([ListBoxField, ListBoxMenu]),
80+
children: childrenOf([ListBoxField, ListBoxMenu, WarningFilled16]),
7881

7982
/**
8083
* Specify a class name to be applied on the containing list box node

src/components/ListBox/ListBoxMenuItem.js

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import cx from 'classnames';
99
import React from 'react';
1010
import PropTypes from 'prop-types';
1111
import { settings } from 'carbon-components';
12+
import { componentsX } from '../../internal/FeatureFlags';
1213

1314
const { prefix } = settings;
1415

@@ -25,7 +26,13 @@ const ListBoxMenuItem = ({ children, isActive, isHighlighted, ...rest }) => {
2526
});
2627
return (
2728
<div className={className} {...rest}>
28-
{children}
29+
{componentsX ? (
30+
<div className={`${prefix}--list-box__menu-item__option`}>
31+
{children}
32+
</div>
33+
) : (
34+
children
35+
)}
2936
</div>
3037
);
3138
};

yarn.lock

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3195,10 +3195,10 @@ capture-stack-trace@^1.0.0:
31953195
resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.1.tgz#a6c0bbe1f38f3aa0b92238ecb6ff42c344d4135d"
31963196
integrity sha512-mYQLZnx5Qt1JgB1WEiMCf2647plpGeQ2NMR/5L0HNZzGQo4fuSPnK+wjfPnKZV0aiJDgzmWqqkV/g7JD+DW0qw==
31973197

3198-
carbon-components@^9.87.2:
3199-
version "9.87.2"
3200-
resolved "https://registry.yarnpkg.com/carbon-components/-/carbon-components-9.87.2.tgz#20a96389975529526fd990789461cf20595a6273"
3201-
integrity sha512-wUbpYabgaX/rzBVWlKhBzQgO7W/62eFYJ6fnH9ATcz78vqRZy4ptzk1Z5EnyE4CjMOUnCUQrt/VuVSHP88LNtg==
3198+
carbon-components@^9.90.9:
3199+
version "9.90.9"
3200+
resolved "https://registry.yarnpkg.com/carbon-components/-/carbon-components-9.90.9.tgz#3ae43bb29d1ede088c1c683ddc9643bb4feb160e"
3201+
integrity sha512-h7ugDyO0XjHoe6faO1w27OckmLAm2D/As6H9LVTlW8HEFsRiQjhor4v6k3Ihz6cAAeMK7+DM7eYTaKNR/6dOmA==
32023202
dependencies:
32033203
carbon-icons "^7.0.7"
32043204
flatpickr "4.5.7"

0 commit comments

Comments
 (0)