Skip to content

Commit

Permalink
feat: make #dropdown scrollable (this changes the behavior of how to …
Browse files Browse the repository at this point in the history
…navigate with arrow keys, and select with enter or space)
  • Loading branch information
tujoworker committed Apr 10, 2019
1 parent 0453d26 commit f2d5e4d
Show file tree
Hide file tree
Showing 5 changed files with 78 additions and 138 deletions.
54 changes: 31 additions & 23 deletions packages/dnb-ui-lib/src/components/dropdown/Dropdown.js
Original file line number Diff line number Diff line change
Expand Up @@ -172,9 +172,9 @@ export default class Dropdown extends Component {
const opened = Dropdown.parseOpened(props.opened)
this.state = {
_listenForPropChanges: true,
active: -1,
opened,
hidden: !opened,
active_item: props.selected_item,
selected_item: props.selected_item,
_data: props.data || props.children,
data: Dropdown.getData(props)
Expand Down Expand Up @@ -247,25 +247,32 @@ export default class Dropdown extends Component {
return -1
}, -1)
if (itemNumberFound > -1) {
return this._refUl.current.querySelector(
`li:nth-of-type(${itemNumberFound + 1})`
)
return itemNumberFound
// return this._refUl.current.querySelector(
// `li:nth-of-type(${itemNumberFound + 1})`
// )
}

return null
}

scrollToItem(liElement) {
if (!liElement) {
scrollToItem(active_item) {
if (!(active_item > -1)) {
return
}
this.setState({
active_item,
_listenForPropChanges: false
})
try {
const liElement = this._refUl.current.querySelector(
`li:nth-of-type(${active_item + 1})`
)
const top = liElement.offsetTop
liElement.parentNode.scrollTo({
top,
behavior: 'smooth'
})
liElement.classList.add('dnb-dropdown__option--current')
} catch (e) {
console.log('Dropdown could not scroll into element:', e)
}
Expand All @@ -287,7 +294,6 @@ export default class Dropdown extends Component {
}
onBlurHandler = () => {
this.setState({
active: -1,
opened: false,
_listenForPropChanges: false
})
Expand All @@ -300,25 +306,26 @@ export default class Dropdown extends Component {
}

onKeyDownHandler = e => {
let selected_item = this.state.selected_item
let active_item = this.state.active_item
const total = this.state.data.length - 1

switch (keycode(e)) {
case 'up':
selected_item--
active_item--
e.preventDefault()
break
case 'down':
selected_item++
active_item++
e.preventDefault()
break
case 'enter':
case 'space':
this.selectItem(active_item)
if (this._refInput.current) {
this._refInput.current.blur()
}
dispatchCustomElementEvent(this, 'on_select', {
data: this.getOptionData(selected_item)
data: this.getOptionData(active_item)
})
e.preventDefault()
break
Expand All @@ -336,18 +343,19 @@ export default class Dropdown extends Component {
break
}

if (selected_item < 0) {
selected_item = total
if (active_item < 0) {
active_item = total
}
if (selected_item > total) {
selected_item = 0
if (active_item > total) {
active_item = 0
}

if (selected_item !== this.state.selected_item) {
this.setState({
active: selected_item
})
this.selectItem(selected_item)
if (active_item !== this.state.active_item) {
this.scrollToItem(active_item)
// this.setState({
// active_item,
// _listenForPropChanges: false
// })
}
}

Expand Down Expand Up @@ -401,7 +409,7 @@ export default class Dropdown extends Component {

const id = this._id

const { opened, active, hidden, selected_item } = this.state
const { opened, hidden, active_item, selected_item } = this.state
const showStatus = status && status !== 'error'

const currentOptionData = this.getOptionData(selected_item)
Expand Down Expand Up @@ -513,7 +521,7 @@ export default class Dropdown extends Component {
className: classnames(
'dnb-dropdown__option',
isCurrent && 'dnb-dropdown__option--selected',
i === active && 'dnb-dropdown__option--active'
i === active_item && 'dnb-dropdown__option--focus'
)
}
return (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ exports[`Dropdown component have to match snapshot 1`] = `
</li>
<li
aria-selected={true}
className="dnb-dropdown__option dnb-dropdown__option--selected"
className="dnb-dropdown__option dnb-dropdown__option--selected dnb-dropdown__option--focus"
id="option-dropdown-id-2"
key="dropdown-id2"
role="option"
Expand Down Expand Up @@ -376,23 +376,16 @@ exports[`Dropdown scss have to match default theme snapshot 1`] = `
.dnb-dropdown__option__inner {
padding-right: 2rem;
background-color: var(--dropdown-option-background-color); }
.dnb-dropdown__option--current {
background-color: var(--dropdown-option-background-color--hover); }
.dnb-dropdown__option--current .dnb-dropdown__option__inner {
color: var(--dropdown-option-color--hover);
background-color: var(--dropdown-option-background-color--hover); }
:not([dnb-is-touch]) .dnb-dropdown__option:hover[disabled] {
cursor: not-allowed; }
:not([dnb-is-touch]) .dnb-dropdown__option:hover:not([disabled]) {
background-color: var(--dropdown-option-background-color--hover); }
:not([dnb-is-touch]) .dnb-dropdown__option:hover:not([disabled]) .dnb-dropdown__option__inner {
color: var(--dropdown-option-color--hover);
background-color: var(--dropdown-option-background-color--hover); }
.dnb-dropdown__option--active {
background-color: var(--dropdown-option-background-color--selected); }
.dnb-dropdown__option--active .dnb-dropdown__option__inner {
box-shadow: 0 0 0 2px var(--dropdown-border-color--selected);
border-color: transparent; }
.dnb-dropdown__option--focus .dnb-dropdown__option__inner {
box-shadow: 0 0 0 2px var(--dropdown-border-color--selected);
border-color: transparent; }
.dnb-dropdown__option--selected {
color: var(--dropdown-option-color--selected);
background-color: var(--dropdown-option-background-color--selected);
Expand All @@ -419,11 +412,14 @@ exports[`Dropdown scss have to match default theme snapshot 1`] = `
height: 1rem;
background-size: cover;
background-image: url(data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIxNiIgaGVpZ2h0PSIxNiIgZmlsbD0ibm9uZSI+ICA8cGF0aCAgICBmaWxsPSIjRTlGOEY0IiAgICBkPSJNMyA4LjhhLjc1Ljc1IDAgMSAwLTEuMjIuODZMMyA4Ljc5em0xLjg0IDMuOWwuNjMtLjQxdi0uMDFoLS4wMWwtLjYyLjQyem0xLjcxLjA1bC0uNTktLjQ2di4wMWwuNTkuNDV6bTguNDMtOS40NWEuNzUuNzUgMCAwIDAtMS4xOC0uOTNsMS4xOC45M3pNMS43OCA5LjY2bDIuNDUgMy40OCAxLjIzLS44N0wzIDguOGwtMS4yMy44N3ptMi40NCAzLjQ2Yy4zMi40OC44Ni43OCAxLjQ0LjhsLjA1LTEuNWEuMy4zIDAgMCAxLS4yNC0uMTNsLTEuMjUuODN6bTEuNDQuOGExLjggMS44IDAgMCAwIDEuNDktLjcxbC0xLjItLjlhLjMuMyAwIDAgMS0uMjQuMWwtLjA1IDEuNXptMS40OC0uN2w3Ljg0LTkuOTItMS4xOC0uOTMtNy44NCA5LjkyIDEuMTguOTN6Ii8+PC9zdmc+); }
.dnb-dropdown__option--focus:not(.dnb-dropdown__option--selected) .dnb-dropdown__option__inner {
color: var(--dropdown-option-color--hover);
background-color: var(--dropdown-option-background-color--hover); }
.dnb-dropdown__option:first-of-type,
.dnb-dropdown__option--active:first-of-type .dnb-dropdown__option__inner {
.dnb-dropdown__option--focus:first-of-type .dnb-dropdown__option__inner {
border-radius: var(--dropdown-options-border-radius) var(--dropdown-options-border-radius) 0 0; }
.dnb-dropdown__option:last-of-type,
.dnb-dropdown__option--active:last-of-type .dnb-dropdown__option__inner {
.dnb-dropdown__option--focus:last-of-type .dnb-dropdown__option__inner {
border-radius: 0 0 var(--dropdown-options-border-radius) var(--dropdown-options-border-radius);
border-bottom: none; }
.dnb-dropdown__trigger {
Expand Down Expand Up @@ -821,9 +817,9 @@ exports[`Dropdown scss have to match snapshot 1`] = `
background-color: grey; }
:not([dnb-is-touch]) .dnb-dropdown__option:hover:not([disabled]) .dnb-dropdown__option__inner {
background-color: grey; }
.dnb-dropdown__option--active {
.dnb-dropdown__option--focus {
background-color: grey; }
.dnb-dropdown__option--active .dnb-dropdown__option__inner {
.dnb-dropdown__option--focus .dnb-dropdown__option__inner {
box-shadow: 0 0 0 0.0625rem; }
.dnb-dropdown__option--selected {
background-color: grey; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@
}

// for keyboard usage
&--active {
&--focus {
background-color: grey;
.dnb-dropdown__option__inner {
@include fakeBorder();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,6 @@
background-color: var(--dropdown-option-background-color);
}

&--current {
background-color: var(--dropdown-option-background-color--hover);
.dnb-dropdown__option__inner {
color: var(--dropdown-option-color--hover);
background-color: var(--dropdown-option-background-color--hover);
}
}
@include hover() {
background-color: var(--dropdown-option-background-color--hover);
.dnb-dropdown__option__inner {
Expand All @@ -79,9 +72,8 @@
}
}

// for keyboard usage
&--active {
background-color: var(--dropdown-option-background-color--selected);
// Focus ring arround item. Only for keyboard usage
&--focus {
.dnb-dropdown__option__inner {
@include fakeBorder(var(--dropdown-border-color--selected), 2px);
}
Expand Down Expand Up @@ -124,13 +116,21 @@
}
}

// Focus ring arround item. Only for keyboard usage
&--focus:not(#{&}--selected) {
.dnb-dropdown__option__inner {
color: var(--dropdown-option-color--hover);
background-color: var(--dropdown-option-background-color--hover);
}
}

&:first-of-type,
&--active:first-of-type &__inner {
&--focus:first-of-type &__inner {
border-radius: var(--dropdown-options-border-radius)
var(--dropdown-options-border-radius) 0 0;
}
&:last-of-type,
&--active:last-of-type &__inner {
&--focus:last-of-type &__inner {
border-radius: 0 0 var(--dropdown-options-border-radius)
var(--dropdown-options-border-radius);
border-bottom: none;
Expand Down
110 changes: 23 additions & 87 deletions packages/dnb-ui-lib/stories/componentsStories.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,7 @@ stories.push([
</Box>
<Box>
<Dropdown
data={dropdownData}
data={dropdownDataScrollable}
selected_item={3}
scrollable
label="Label:"
Expand Down Expand Up @@ -543,108 +543,44 @@ const dropdownData = [
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Aparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
selected_value:
'Feriekonto - Kari Nordmann med et kjempelangt etternavnsen',
content: [
'1134.56.78962',
'Feriekonto - Kari Nordmann med et kjempelangt etternavnsen'
]
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
},
selected_value: 'Oppussing - Ole Nordmann',
content: ['1534.96.48901', 'Oppussing - Ole Nordmann']
}
]
const dropdownDataScrollable = [
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
selected_value: 'AA',
content: 'A'
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
content: ['1234.56.78902', 'B']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
selected_value: 'CC',
content: ['1134.56.78962', 'C']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
selected_value: 'DD',
content: ['1534.96.48901', 'D']
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
content: 'E'
},
{
content: ['1234.56.78902', 'Sparekonto - Ole Nordmann']
content: ['F', 'F', 'F', 'F', 'F']
},
{
selected_value:
'Feriekonto - Kari Nordmann med et kjempelangt etternavnsen',
content: [
'1134.56.78962',
'Feriekonto - Kari Nordmann med et kjempelangt etternavnsen'
]
content: 'G'
},
{
selected_value: 'Oppussing - Ole Nordmann',
content: ['1534.96.48901', 'Oppussing - Ole Nordmann']
content: 'H'
}
]

0 comments on commit f2d5e4d

Please sign in to comment.