From b96b9e08c1e130dc9f22f7eb033acb2abeb0c56e Mon Sep 17 00:00:00 2001 From: Tobias Date: Thu, 11 Apr 2019 12:44:10 +0200 Subject: [PATCH] feat: add direction prop to #dropdown so the dropdown can show the options opening from the top --- .../dropdown/dropdown-properties.md | 17 ++++----- .../src/components/dropdown/Dropdown.js | 24 ++++++++++--- .../__snapshots__/Dropdown.test.js.snap | 35 +++++++++++++------ .../components/dropdown/style/_dropdown.scss | 25 +++++++++++-- .../style/themes/dnb-dropdown-theme-ui.scss | 20 ++++++----- 5 files changed, 86 insertions(+), 35 deletions(-) diff --git a/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md b/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md index 67c740914bf..9d74eeb2538 100644 --- a/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md +++ b/packages/dnb-design-system-portal/src/pages/uilib/components/dropdown/dropdown-properties.md @@ -4,14 +4,15 @@ draft: true import { Data } from 'Pages/uilib/components/dropdown/Examples' -| Properties | Description | -| --------------- | ----------------------------------------------------------------------------------------------------------------------------- | -| `data` | _(mandatory)_ the data we want to fill the list with. Provide the data as a json string or data array structure. | -| `selected_item` | _(optional)_ a number as a string or integer, defines the active item in the data array. The default value is the first item. | -| `icon` | _(optional)_ name of icon to be included in the dropdown. | -| `icon_position` | _(optional)_ position of icon inside the dropdown. Set to `left` or `right`. Defaults to `right` if not set. | -| `disabled` | _(optional)_ to disable/enable the dropdown without using the `attribute` property. | -| `id` | _(optional)_ the `id` of the input. | +| Properties | Description | +| --------------- | ------------------------------------------------------------------------------------------------------------------------------------- | +| `data` | _(mandatory)_ the data we want to fill the list with. Provide the data as a json string or data array structure. | +| `selected_item` | _(optional)_ a number as a string or integer, defines the active item in the data array. The default value is the first item. | +| `icon` | _(optional)_ name of icon to be included in the dropdown. | +| `icon_position` | _(optional)_ position of icon inside the dropdown. Set to `left` or `right`. Defaults to `right` if not set. | +| `disabled` | _(optional)_ to disable/enable the dropdown without using the `attribute` property. | +| `direction` | _(optional)_ defines the direction of how the dropdown shows the options. Can be `top` or `bottom`. Defaults to `auto`. | +| `scrollable` | _(optional)_ defines if the dropdown options should be scrollable (the `max-height` is set by default to `50vh`). Defaults to `true`. | ## Data structure diff --git a/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js b/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js index 2cc07f6684e..a3ead6184f6 100644 --- a/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js +++ b/packages/dnb-ui-lib/src/components/dropdown/Dropdown.js @@ -35,6 +35,7 @@ export const propTypes = { status_state: PropTypes.string, status_animation: PropTypes.string, scrollable: PropTypes.bool, + direction: PropTypes.oneOf(['auto', 'top', 'bottom']), no_animation: PropTypes.bool, data: PropTypes.oneOfType([ PropTypes.string, @@ -79,7 +80,8 @@ export const defaultProps = { status: null, status_state: 'error', status_animation: null, - scrollable: false, + scrollable: true, + direction: 'auto', no_animation: false, data: null, selected_item: 0, @@ -337,6 +339,15 @@ export default class Dropdown extends Component { } } + selectItemHandler = e => { + const selected_item = parseFloat( + e.currentTarget.getAttribute('data-item') + ) + if (selected_item > -1) { + this.selectItem(selected_item, { fireSelectEvent: true }) + } + } + selectItem = (selected_item, { fireSelectEvent } = {}) => { if (this.state.selected_item !== selected_item) { dispatchCustomElementEvent(this, 'on_change', { @@ -345,6 +356,7 @@ export default class Dropdown extends Component { } this.setState({ selected_item, + active_item: selected_item, _listenForPropChanges: false }) if (fireSelectEvent) { @@ -372,6 +384,7 @@ export default class Dropdown extends Component { status_state, status_animation, scrollable, + direction, no_animation, className, class: _className, @@ -395,6 +408,7 @@ export default class Dropdown extends Component { const classes = classnames( 'dnb-dropdown', icon_position && `dnb-dropdown--icon-position-${icon_position}`, + direction === 'bottom' && `dnb-dropdown--direction-bottom`, scrollable && 'dnb-dropdown--scroll', opened && 'dnb-dropdown--opened', hidden && 'dnb-dropdown--hidden', @@ -490,7 +504,6 @@ export default class Dropdown extends Component { -
    {this.state.data.map((dataItem, i) => { const isCurrent = i === parseFloat(selected_item) @@ -509,9 +522,9 @@ export default class Dropdown extends Component { - this.selectItem(i, { fireSelectEvent: true }) - } + data-item={i} + onTouchStart={this.selectItemHandler} + onMouseDown={this.selectItemHandler} role="button" tabIndex="-1" > @@ -533,6 +546,7 @@ export default class Dropdown extends Component { ) })}
+
diff --git a/packages/dnb-ui-lib/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap b/packages/dnb-ui-lib/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap index 4f826795ec3..8a9b2876418 100644 --- a/packages/dnb-ui-lib/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap +++ b/packages/dnb-ui-lib/src/components/dropdown/__tests__/__snapshots__/Dropdown.test.js.snap @@ -38,6 +38,7 @@ exports[`Dropdown component have to match snapshot 1`] = ` }, ] } + direction="'auto'" disabled="disabled" icon="icon" icon_position="icon_position" @@ -137,9 +138,6 @@ exports[`Dropdown component have to match snapshot 1`] = ` -
+