Skip to content

Commit

Permalink
feat(select): new keyboard accessible select component (#3669)
Browse files Browse the repository at this point in the history
  • Loading branch information
josephmcg authored and JustZacca committed Jun 22, 2022
1 parent 05548d5 commit cf331bf
Show file tree
Hide file tree
Showing 21 changed files with 375 additions and 363 deletions.
14 changes: 14 additions & 0 deletions assets/styles/base.less
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,20 @@ body {
*:active {
outline: none;
}
* {
&::-webkit-scrollbar {
width: @scroll-bar-size;
}
&::-webkit-scrollbar-track {
background: transparent;
}
&::-webkit-scrollbar-thumb {
background: @flair-color;
&:extend(.round-corners);
}
scrollbar-width: thin;
scrollbar-color: @flair-color transparent;
}

code {
&:extend(.background-semitransparent-lighter);
Expand Down
11 changes: 11 additions & 0 deletions assets/styles/framework/ui.less
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,14 @@
-ms-user-select: none;
user-select: none;
}

// hide from view, but not from screenreaders https://www.a11yproject.com/posts/how-to-hide-content/
.hidden {
width: 1px;
height: 1px;
overflow: hidden;
position: absolute;
white-space: nowrap;
clip: rect(0 0 0 0);
clip-path: inset(50%);
}
20 changes: 0 additions & 20 deletions components/interactables/Select/README.md

This file was deleted.

91 changes: 56 additions & 35 deletions components/interactables/Select/Select.html
Original file line number Diff line number Diff line change
@@ -1,40 +1,61 @@
<div
:class="{'select': true, [`is-${type}`]: true, [`is-${size}`]: true, 'is-full-width': fullWidth, 'disabled': disabled}"
v-click-outside="() => open = false"
>
<div
:class="{'custom-select': true, open, up, down: !up}"
data-cy="custom-select"
<div class="listbox" :value="value" ref="listbox">
<span
:id="`${label}-label`"
:class="{ hidden : !showLabel }"
class="listbox-label"
>
<div
v-if="colorSupport"
class="selected"
data-cy="custom-select-value"
@click="toggleOpen()"
{{ label }}
</span>
<select
v-if="$device.isMobile"
class="mobile-select"
:value="value"
:disabled="disabled"
@change="$emit('input', $event.target.value)"
>
<option
v-for="(option, index) in options"
:key="`${label}-option-${index}`"
:aria-selected="option.value === value"
:value="option.value"
>
{{ option.text }}
</option>
</select>
<div v-else class="list-container" v-click-outside="hideListbox">
<button
:id="`${label}-button-label`"
:disabled="disabled"
:aria-labelledby="`${label}-label ${label}-button-label`"
type="button"
aria-haspopup="listbox"
@click="toggleListbox"
@keydown="checkShow"
ref="button"
>
{{ getSelectLabelColor }}
</div>
<div
v-else
class="selected"
data-cy="custom-select-value"
@click="toggleOpen()"
{{ value ? selectedOptionLabel : placeholder }}
</button>
<ul
v-show="!listboxHidden"
:aria-labelledby="`${label}-label`"
:aria-activedescendant="value"
tabindex="-1"
role="listbox"
@keydown="checkKeyDown"
@click="checkClickItem"
ref="list"
>
{{ getSelectLabel }}
</div>
<div class="items">
<UiSimpleScroll scrollMode="vertical" scrollShow="scroll">
<div
v-for="(option, i) of options"
:key="i"
:disabled="option.disabled"
@click="change(option)"
class="option"
:style="colorSupport ? 'background:' + renderBgGradient(option) : ''"
>
<span data-cy="custom-select-option-text">{{ option.text }}</span>
</div>
</UiSimpleScroll>
</div>
<li
v-for="(option, index) in options"
:key="`${label}-option-${index}`"
:aria-selected="option.value === value"
:data-value="option.value"
:style="option.color ? 'background:' + option.color : ''"
role="option"
ref="options"
>
{{ option.text }}
</li>
</ul>
</div>
</div>
136 changes: 53 additions & 83 deletions components/interactables/Select/Select.less
Original file line number Diff line number Diff line change
@@ -1,94 +1,64 @@
.is-full-width {
&:extend(.full-width);
select {
&:extend(.full-width);
.listbox {
display: flex;
flex-direction: column;
.listbox-label {
font-family: @secondary-font;
font-size: 12px;
text-transform: uppercase;
padding-bottom: @xlight-spacing;
display: inline-block;
}
}

.is-primary {
.custom-select {
.selected {
&::after,
&::before {
border-color: @secondary-text;
}
border: none;
outline: none;
}
.list-container {
width: fit-content;
}
}

.custom-select {
.selected {
height: @select-height;
line-height: @select-height;
border-radius: 4rem;
padding-left: @normal-spacing;
padding-right: @normal-spacing * 2;
cursor: pointer;
&:extend(.no-select);
max-width: @full;
}
.items {
&:extend(.background-semitransparent-dark);
&:extend(.round-corners);
&:extend(.bordered);
&:extend(.blur);
min-width: 8rem;
position: absolute;
display: none;
color: #fff;
overflow: hidden;
max-width: @full;
left: 0;
right: 0;
button,
select {
min-width: 150px;
font-size: 0.75rem;
text-align: left;
position: relative;
border-radius: 4rem;
padding: @light-spacing 2.5rem @light-spacing @normal-spacing;

&:extend(.second-layer);
margin-top: @light-spacing;
.option {
height: @normal-spacing * 2;
line-height: @normal-spacing * 2;
padding: 0 @light-spacing;
cursor: pointer;
max-width: @full;
text-overflow: ellipsis;
white-space: nowrap;
overflow: hidden;
&:extend(.no-select);
&[disabled] {
opacity: 0.5;
}
&:hover {
&:extend(.background-semitransparent-lighter);
}
}
}
&.open {
.items {
display: block;
}
}
&.up {
.items {
bottom: 30px;
}
}
&.down {
.items {
top: 30px;
}
color: @white;
background: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="white" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><polyline points="6 9 12 15 18 9"></polyline></svg>')
no-repeat right 13px center @flair-color;
box-shadow: 0 5px 14px -5px @flair-color;
border: none;

&:extend(.ellipsis);
&:disabled {
box-shadow: 0 5px 14px -5px @gray;
background-color: @gray;
cursor: not-allowed;
}
position: relative;
height: @select-height;
text-align: left;
outline: none;
}

.disabled {
.custom-select {
.selected {
box-shadow: 0 5px 14px -5px @gray;
background: @gray;
}
select {
-moz-appearance: none;
-webkit-appearance: none;
appearance: none;
}
ul {
min-width: 150px;
max-height: 325px;
overflow-y: auto;
position: absolute;
margin-top: @xlight-spacing;
margin-top: @xlight-spacing;
&:extend(.background-dark-gradient);
&:extend(.fifth-layer);
}
li {
display: block;
padding: @light-spacing @xlarge-spacing @light-spacing @normal-spacing;
position: relative;
&:focus,
&:hover,
&[aria-selected='true'] {
&:extend(.background-semitransparent-lighter);
}
}
Loading

0 comments on commit cf331bf

Please sign in to comment.