diff --git a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap index 6f7d787cf918..7aaaca309f3a 100644 --- a/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap +++ b/packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap @@ -2236,9 +2236,7 @@ Map { ], "type": "oneOfType", }, - "inline": Object { - "type": "bool", - }, + "inline": [Function], "invalid": Object { "type": "bool", }, @@ -6277,16 +6275,11 @@ Map { }, }, "DropdownSkeleton" => Object { - "defaultProps": Object { - "inline": false, - }, "propTypes": Object { "className": Object { "type": "string", }, - "inline": Object { - "type": "bool", - }, + "inline": [Function], }, }, "FileUploaderSkeleton" => Object { diff --git a/packages/react/src/components/Dropdown/Dropdown-story.js b/packages/react/src/components/Dropdown/Dropdown-story.js index 07372c0fbc6a..a73f30a3dd41 100644 --- a/packages/react/src/components/Dropdown/Dropdown-story.js +++ b/packages/react/src/components/Dropdown/Dropdown-story.js @@ -10,7 +10,7 @@ import { action } from '@storybook/addon-actions'; import { withKnobs, boolean, select, text } from '@storybook/addon-knobs'; import Dropdown from '../Dropdown'; import DropdownSkeleton from './Dropdown.Skeleton'; -import WithState from '../../tools/withState'; +import mdx from './Dropdown.mdx'; const items = [ { @@ -40,15 +40,6 @@ const items = [ }, ]; -const stringItems = [ - 'Option 1', - 'Option 2', - 'Option 3', - 'Lorem, ipsum dolor sit amet consectetur adipisicing elit. Vitae, aliquam. Blanditiis quia nemo enim voluptatibus quos ducimus porro molestiae nesciunt error cumque quaerat, tempore vero unde eum aperiam eligendi repellendus.', - 'Option 5', - 'Option 6', -]; - const sizes = { 'Extra large size (xl)': 'xl', 'Default size': undefined, @@ -68,7 +59,7 @@ const props = () => ({ ariaLabel: text('Aria Label (ariaLabel)', 'Dropdown'), disabled: boolean('Disabled (disabled)', false), light: boolean('Light variant (light)', false), - titleText: text('Title (titleText)', 'This is a dropdown title.'), + titleText: text('Title (titleText)', 'Dropdown label'), helperText: text('Helper text (helperText)', 'This is some helper text.'), invalid: boolean('Show form validation UI (invalid)', false), invalidText: text( @@ -87,13 +78,19 @@ export default { subcomponents: { DropdownSkeleton, }, + docs: { + page: mdx, + }, }, }; export const Default = () => (
(item ? item.text : '')} onChange={action('onChange')} @@ -101,18 +98,12 @@ export const Default = () => (
); -Default.storyName = 'default'; - -Default.parameters = { - info: { - text: 'Dropdown', - }, -}; - export const Inline = () => (
(item ? item.text : '')} @@ -121,70 +112,20 @@ export const Inline = () => (
); -Inline.storyName = 'inline'; - -Inline.parameters = { - info: { - text: 'Dropdown', - }, -}; - -export const ItemsAsStrings = () => ( -
- -
-); - -ItemsAsStrings.storyName = 'items as strings'; - -ItemsAsStrings.parameters = { - info: { - text: 'Rendering an array of strings as `items`', - }, -}; - -export const FullyControlled = () => ( - - {({ state, setState }) => ( -
- (item ? item.text : '')} - onChange={({ selectedItem }) => - setTimeout(() => setState({ selectedItem }), 1000) - } - selectedItem={state.selectedItem} - /> -
- )} -
-); - -FullyControlled.storyName = 'fully controlled'; - -FullyControlled.parameters = { - info: { - text: ` - Sometimes you want to control everything. - `, - }, +export const Playground = () => { + return ( +
+ (item ? item.text : '')} + /> +
+ ); }; export const Skeleton = () => (
-   -
); - -Skeleton.storyName = 'skeleton'; - -Skeleton.parameters = { - info: { - text: ` - Placeholder skeleton state to use when content is loading. - `, - }, -}; diff --git a/packages/react/src/components/Dropdown/Dropdown.Skeleton.js b/packages/react/src/components/Dropdown/Dropdown.Skeleton.js index 880b3f0f128a..4242da178942 100644 --- a/packages/react/src/components/Dropdown/Dropdown.Skeleton.js +++ b/packages/react/src/components/Dropdown/Dropdown.Skeleton.js @@ -9,6 +9,7 @@ import PropTypes from 'prop-types'; import React from 'react'; import cx from 'classnames'; import { settings } from 'carbon-components'; +import deprecate from '../../prop-types/deprecate'; const { prefix } = settings; @@ -39,11 +40,11 @@ DropdownSkeleton.propTypes = { /** * Specify whether you want the inline version of this control */ - inline: PropTypes.bool, -}; - -DropdownSkeleton.defaultProps = { - inline: false, + inline: deprecate( + PropTypes.bool, + `The \`inline\` prop has been deprecated and will + be removed in the next major release. To specify the inline variant of Dropdown, please use the \`type\` prop.` + ), }; export default DropdownSkeleton; diff --git a/packages/react/src/components/Dropdown/Dropdown.js b/packages/react/src/components/Dropdown/Dropdown.js index 7cb2303db5e6..9d79923af581 100644 --- a/packages/react/src/components/Dropdown/Dropdown.js +++ b/packages/react/src/components/Dropdown/Dropdown.js @@ -13,6 +13,7 @@ import PropTypes from 'prop-types'; import { Checkmark16, WarningFilled16 } from '@carbon/icons-react'; import ListBox, { PropTypes as ListBoxPropTypes } from '../ListBox'; import { mapDownshiftProps } from '../../tools/createPropAdapter'; +import deprecate from '../../prop-types/deprecate'; const { prefix } = settings; @@ -232,7 +233,11 @@ Dropdown.propTypes = { /** * Specify whether you want the inline version of this control */ - inline: PropTypes.bool, + inline: deprecate( + PropTypes.bool, + `The \`inline\` prop has been deprecated and will + be removed in the next major release. To specify the inline variant of Dropdown, please use the \`type\` prop.` + ), /** * Specify if the currently selected value is invalid. diff --git a/packages/react/src/components/Dropdown/Dropdown.mdx b/packages/react/src/components/Dropdown/Dropdown.mdx new file mode 100644 index 000000000000..ab387743264d --- /dev/null +++ b/packages/react/src/components/Dropdown/Dropdown.mdx @@ -0,0 +1,294 @@ +import { Story, Props, Source, Preview } from '@storybook/addon-docs/blocks'; +import Dropdown from '../Dropdown'; +import DropdownSkeleton from './Dropdown.Skeleton'; + +# Dropdown + + + + +- [Overview](#overview) + - [Inline dropdown](#inline-dropdown) + - [Skeleton state](#skeleton-state) +- [Component API](#component-api) + - [Dropdown `direction`](#dropdown-direction) + - [Dropdown `downshiftProps`](#dropdown-downshiftprops) + - [Dropdown `initialSelectedItem`](#dropdown-initialselecteditem) + - [Dropdown `itemToElement`](#dropdown-itemtoelement) + - [Dropdown `itemToString`](#dropdown-itemtostring) + - [Dropdown `items`](#dropdown-items) + - [Dropdown `light`](#dropdown-light) + - [Dropdown `selectedItem`](#dropdown-selecteditem) + - [Dropdown `size`](#dropdown-size) + - [Dropdown `titleText`](#dropdown-titletext) + - [Dropdown `type`](#dropdown-type) +- [References](#references) +- [Feedback](#feedback) + + + +## Overview + +Dropdowns present a list of options from which a user can select one option, or +several. A selected option can represent a value in a form, or can be used as an +action to filter or sort existing content. + + + + + +### Inline dropdown + +You can place a `Dropdown` inline with other content by using the `inline` +variant + + + + + +### Skeleton state + +You can use the `DropdownSkeleton` component to render a skeleton variant of a +`Dropdown`. This is useful to display on initial page load or when data needs to +be fetched from an external API. + + + + + +## Component API + + + +### Dropdown `direction` + +When a `Dropdown` is near the bottom of a page, you may want to render the menu +to the top of the screen. To do this, specify `direction="top"` + + (item ? item.text : '')} + label="Select an option..." + direction="top" + id="direction" +/> + +```jsx + +``` + +### Dropdown `downshiftProps` + +Our `Dropdown` component utilizes [Downshift](https://www.downshift-js.com/) +under the hood to help provide complex yet accessible custom dropdown +components. We provide access to the built in Downshift features with this prop. +For more information, checkout the Downshift prop +[documentation](https://www.downshift-js.com/downshift#props-used-in-examples) + +### Dropdown `initialSelectedItem` + +If you want the `Dropdown` to render with a value already selected, but do not +want to fully control the component, you can use `initialSelectedItem`. + +```jsx +const items = ['Option 1', 'Option 2', 'Option 3'] + +; +``` + +### Dropdown `itemToElement` + +The `Dropdown` takes in an `items` array and can then be formatted by +`itemToElement` and `itemToString`. `itemToElement` allows you to wrap each +dropdown item in a custom element. + + + item ? ( + + {item.text} 🔥 + + ) : ( + '' + ) + } + label="Select an option..." + id="item-to-element" +/> + +```jsx + + item ? ( + + {item.text} 🔥 + + ) : ( + '' + ) + } + label="Select an option..." +/> +``` + +### Dropdown `itemToString` + +If the `items` array is not an array of strings, you'll need to use +`itemToString` to grab the text to be used as the `Dropdown` item text. + +```jsx + (item ? item.text : '')} +/> +``` + +### Dropdown `items` + +This is the data that will be rendered as options for the `Dropdown`. If `items` +is simply an array of strings, no further formatting is required. If `items` is +an array of objects, you'll need to pass in an `itemToString` function as well. + +```jsx + + + + (item ? item.text : '')} +/> +``` + +### Dropdown `light` + +In certain circumstances, a `Dropdown` will exist on a container element with +the same background color. To improve contrast, you can use the `light` property +to toggle the light variant of the `Dropdown`. + +```jsx +... +``` + +### Dropdown `selectedItem` + +You can pass a `selectedItem` to the `Dropdown` to set a value on initial load. +Keep in mind, if you set a value the `Dropdown` will become a controlled +component and you will need to handle state management. + +```jsx +const [currentItem, setCurrentItem] = useState(items[4]); +... + (item ? item.text : '')} + onChange={({ selectedItem }) => setCurrentItem(selectedItem)} + selectedItem={currentItem} +/> +``` + +### Dropdown `size` + +There are three sizes of `Dropdown` available: `sm`, `lg` (the default), and +`xl`. + + +
+ +
+ + +```jsx + + + +``` + +### Dropdown `titleText` + +This is the text that will be used as a label for the `Dropdown` + +```jsx + +``` + +### Dropdown `type` + +Sometimes you will need to place a `Dropdown` inline with other content. To do +that, pass in `type="inline"` to the `Dropdown` + + + +```jsx + +``` + +## References + +- [Carbon Usage Guidelines](https://www.carbondesignsystem.com/components/dropdown/usage/) + +## Feedback + +Help us improve this component by providing feedback, asking questions, and +leaving any other comments on +[GitHub](https://github.com/carbon-design-system/carbon/edit/master/packages/react/src/components/Dropdown/Dropdown.mdx).