Skip to content

Commit

Permalink
feat: add readonly dropdown (#12430)
Browse files Browse the repository at this point in the history
* feat: add readonly dropdown

* feat: read only multiselect

* fix: make button aria disabled when readonly

* chore: remove unnecessary scss vars

* chore: adjust aria-disabled

* fix: cursor following review

Co-authored-by: kodiakhq[bot] <49736102+kodiakhq[bot]@users.noreply.github.com>
  • Loading branch information
lee-chase and kodiakhq[bot] committed Dec 2, 2022
1 parent 70e2231 commit 776bdf0
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 1 deletion.
3 changes: 3 additions & 0 deletions packages/react/__tests__/__snapshots__/PublicAPI-test.js.snap
Expand Up @@ -2757,6 +2757,9 @@ Map {
"onChange": Object {
"type": "func",
},
"readOnly": Object {
"type": "bool",
},
"renderSelectedItem": Object {
"type": "func",
},
Expand Down
13 changes: 13 additions & 0 deletions packages/react/src/components/Dropdown/Dropdown-test.js
Expand Up @@ -144,6 +144,19 @@ describe('Dropdown', () => {
});
});

it('should respect readOnly prop', () => {
render(<Dropdown {...mockProps} readOnly={true} />);
openMenu(); // menu should not open
assertMenuClosed();

openMenu(); // menu should not open
expect(screen.queryByText('Item 0')).toBeNull();
expect(mockProps.onChange).toHaveBeenCalledTimes(0);
assertMenuClosed();

mockProps.onChange.mockClear();
});

describe('should display initially selected item found in `initialSelectedItem`', () => {
it('using an object type for the `initialSelectedItem` prop', () => {
render(
Expand Down
28 changes: 27 additions & 1 deletion packages/react/src/components/Dropdown/Dropdown.js
Expand Up @@ -56,6 +56,7 @@ const Dropdown = React.forwardRef(function Dropdown(
initialSelectedItem,
selectedItem: controlledSelectedItem,
downshiftProps,
readOnly,
...other
},
ref
Expand Down Expand Up @@ -102,6 +103,7 @@ const Dropdown = React.forwardRef(function Dropdown(
[`${prefix}--dropdown--inline`]: inline,
[`${prefix}--dropdown--disabled`]: disabled,
[`${prefix}--dropdown--light`]: light,
[`${prefix}--dropdown--readonly`]: readOnly,
[`${prefix}--dropdown--${size}`]: size,
[`${prefix}--list-box--up`]: direction === 'top',
}
Expand Down Expand Up @@ -152,6 +154,24 @@ const Dropdown = React.forwardRef(function Dropdown(
setIsFocused(evt.type === 'focus' ? true : false);
};

const readOnlyEventHandlers = readOnly
? {
onClick: (evt) => {
// NOTE: does not prevent click
evt.preventDefault();
// focus on the element as per readonly input behavior
evt.target.focus();
},
onKeyDown: (evt) => {
const selectAccessKeys = ['ArrowDown', 'ArrowUp', ' ', 'Enter'];
// This prevents the select from opening for the above keys
if (selectAccessKeys.includes(evt.key)) {
evt.preventDefault();
}
},
}
: {};

return (
<div className={wrapperClasses} {...other}>
{titleText && (
Expand Down Expand Up @@ -184,9 +204,10 @@ const Dropdown = React.forwardRef(function Dropdown(
type="button"
className={`${prefix}--list-box__field`}
disabled={disabled}
aria-disabled={disabled}
aria-disabled={readOnly ? true : undefined} // aria-disabled to remain focusable
title={selectedItem ? itemToString(selectedItem) : label}
{...toggleButtonProps}
{...readOnlyEventHandlers}
ref={mergeRefs(toggleButtonProps.ref, ref)}>
<span className={`${prefix}--list-box__label`}>
{selectedItem
Expand Down Expand Up @@ -341,6 +362,11 @@ Dropdown.propTypes = {
*/
onChange: PropTypes.func,

/**
* Whether or not the Dropdown is readonly
*/
readOnly: PropTypes.bool,

/**
* An optional callback to render the currently selected item as a react element instead of only
* as a string.
Expand Down
Expand Up @@ -65,6 +65,9 @@ export default {
open: {
table: { disable: true },
},
readOnly: {
control: { type: 'boolean' },
},
title: {
table: { disable: true },
},
Expand Down
15 changes: 15 additions & 0 deletions packages/styles/scss/components/dropdown/_dropdown.scss
Expand Up @@ -473,4 +473,19 @@
.#{$prefix}--list-box__menu-item__selected-icon {
@include high-contrast-mode('icon-fill');
}

// readonly
.#{$prefix}--dropdown--readonly,
.#{$prefix}--dropdown--readonly:hover {
background-color: transparent;
}

.#{$prefix}--dropdown--readonly .#{$prefix}--list-box__field,
.#{$prefix}--dropdown--readonly .#{$prefix}--list-box__menu-icon {
cursor: default;
}

.#{$prefix}--dropdown--readonly .#{$prefix}--list-box__menu-icon svg {
fill: $icon-disabled;
}
}

0 comments on commit 776bdf0

Please sign in to comment.