Skip to content

Commit 4ea5889

Browse files
committed
fix(dueling picklist): Fix accessibility of disabled listboxes
1 parent f4aa65d commit 4ea5889

File tree

2 files changed

+117
-70
lines changed

2 files changed

+117
-70
lines changed

ui/components/dueling-picklist/base/_index.scss

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -33,28 +33,6 @@
3333
margin-top: $spacing-large;
3434
}
3535
}
36-
37-
[aria-disabled="true"] {
38-
background-color: $color-background-input-disabled;
39-
border: 1px solid $color-border-input-disabled;
40-
color: $color-text-input-disabled;
41-
42-
&:hover {
43-
cursor: not-allowed;
44-
}
45-
46-
.slds-listbox__option {
47-
48-
&:hover {
49-
cursor: not-allowed;
50-
background-color: transparent;
51-
}
52-
53-
&:focus {
54-
background-color: transparent;
55-
}
56-
}
57-
}
5836
}
5937

6038
/**
@@ -83,6 +61,28 @@
8361
color: $color-text-button-brand-hover;
8462
}
8563
}
64+
65+
&.slds-is-disabled {
66+
background-color: $color-background-input-disabled;
67+
border-color: $color-border-input-disabled;
68+
color: $color-text-input-disabled;
69+
70+
&:hover {
71+
cursor: not-allowed;
72+
}
73+
74+
.slds-listbox__option {
75+
76+
&:hover {
77+
cursor: not-allowed;
78+
background-color: transparent;
79+
}
80+
81+
&:focus {
82+
background-color: transparent;
83+
}
84+
}
85+
}
8686
}
8787

8888
@include deprecate('4.0.0', 'Use slds-listbox__item instead of slds-picklist__item') {

ui/components/dueling-picklist/base/example.jsx

Lines changed: 95 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -42,52 +42,42 @@ const MultiSelect = props => {
4242
);
4343
};
4444

45-
const MoveButtons = props => (
46-
<div className="slds-dueling-list__column">
47-
<button
48-
className="slds-button slds-button_icon slds-button_icon-container"
49-
title={
50-
'Move Selection ' + (props.direction === 'vertical') ? (
51-
'Up'
52-
) : (
53-
'to ' + props.targetB
54-
)
55-
}
56-
disabled={props.disabled}
57-
>
58-
<SvgIcon
59-
className="slds-button__icon"
60-
sprite="utility"
61-
symbol={props.direction === 'vertical' ? 'up' : 'right'}
62-
/>
63-
<span className="slds-assistive-text">
64-
Move Selection{' '}
65-
{props.direction === 'vertical' ? 'Up' : 'to ' + props.targetB}
66-
</span>
67-
</button>
68-
<button
69-
className="slds-button slds-button_icon slds-button_icon-container"
70-
title={
71-
'Move Selection ' + (props.direction === 'vertical') ? (
72-
'Down'
73-
) : (
74-
'to ' + props.targetA
75-
)
76-
}
77-
disabled={props.disabled}
78-
>
79-
<SvgIcon
80-
className="slds-button__icon"
81-
sprite="utility"
82-
symbol={props.direction === 'vertical' ? 'down' : 'left'}
83-
/>
84-
<span className="slds-assistive-text">
85-
Move Selection{' '}
86-
{props.direction === 'vertical' ? 'Down' : 'to ' + props.targetA}
87-
</span>
88-
</button>
89-
</div>
90-
);
45+
const MoveButtons = props => {
46+
const firstButtonText =
47+
'Move Selection ' +
48+
(props.direction === 'vertical' ? 'Up' : 'to ' + props.targetB);
49+
const secondButtonText =
50+
'Move Selection ' +
51+
(props.direction === 'vertical' ? 'Down' : 'to ' + props.targetA);
52+
return (
53+
<div className="slds-dueling-list__column">
54+
<button
55+
className="slds-button slds-button_icon slds-button_icon-container"
56+
title={firstButtonText}
57+
disabled={props.disabled}
58+
>
59+
<SvgIcon
60+
className="slds-button__icon"
61+
sprite="utility"
62+
symbol={props.direction === 'vertical' ? 'up' : 'right'}
63+
/>
64+
<span className="slds-assistive-text">{firstButtonText}</span>
65+
</button>
66+
<button
67+
className="slds-button slds-button_icon slds-button_icon-container"
68+
title={secondButtonText}
69+
disabled={props.disabled}
70+
>
71+
<SvgIcon
72+
className="slds-button__icon"
73+
sprite="utility"
74+
symbol={props.direction === 'vertical' ? 'down' : 'left'}
75+
/>
76+
<span className="slds-assistive-text">{secondButtonText}</span>
77+
</button>
78+
</div>
79+
);
80+
};
9181

9282
const SelectionGroup = props => {
9383
const groupLabelID = _.uniqueId('label-');
@@ -107,12 +97,15 @@ const SelectionGroup = props => {
10797

10898
const ListBox = props => (
10999
<div
110-
className="slds-dueling-list__options"
100+
className={classNames('slds-dueling-list__options', {
101+
'slds-is-disabled': props.disabled
102+
})}
111103
role="application"
112104
aria-disabled={props.disabled}
113105
>
114106
<ul
115107
aria-describedby="option-drag-label"
108+
aria-disabled={props.disabled}
116109
aria-labelledby={props.ariaLabelledby}
117110
aria-multiselectable="true"
118111
className="slds-listbox slds-listbox_vertical"
@@ -210,6 +203,60 @@ const DefaultSnapShot = {
210203
]
211204
};
212205

206+
const DisabledSnapShot = {
207+
liveRegionText: '',
208+
optionDragLabel:
209+
'Press space bar when on an item, to move it within the list. CMD plus left and right arrow keys, to move items between lists.',
210+
selectionGroups: [
211+
{
212+
label: 'First Category',
213+
options: [
214+
{
215+
text: 'Option 1',
216+
tabIndex: -1,
217+
isSelected: false,
218+
isGrabbed: false
219+
},
220+
{
221+
text: 'Option 2',
222+
tabIndex: -1,
223+
isSelected: false,
224+
isGrabbed: false
225+
},
226+
{
227+
text: 'Option 3',
228+
tabIndex: -1,
229+
isSelected: false,
230+
isGrabbed: false
231+
},
232+
{
233+
text: 'Option 6',
234+
tabIndex: -1,
235+
isSelected: false,
236+
isGrabbed: false
237+
}
238+
]
239+
},
240+
{
241+
label: 'Second Category',
242+
options: [
243+
{
244+
text: 'Option 4',
245+
tabIndex: -1,
246+
isSelected: false,
247+
isGrabbed: false
248+
},
249+
{
250+
text: 'Option 5',
251+
tabIndex: -1,
252+
isSelected: false,
253+
isGrabbed: false
254+
}
255+
]
256+
}
257+
]
258+
};
259+
213260
const RequiredSnapShot = {
214261
liveRegionText: '',
215262
optionDragLabel:
@@ -599,7 +646,7 @@ export let states = [
599646
{
600647
id: 'disabled-dueling-picklist',
601648
label: 'Disabled',
602-
element: <MultiSelect dataSet={DefaultSnapShot} disabled />
649+
element: <MultiSelect dataSet={DisabledSnapShot} disabled />
603650
},
604651
{
605652
id: 'multi-select-selected-item',

0 commit comments

Comments
 (0)