Skip to content

Commit

Permalink
feat: add menuIsOpen prop to select inputs (#2639)
Browse files Browse the repository at this point in the history
* feat: add menuIsOpen prop to basic select input

* fix: generate readme

* feat: add support for the async select input

* feat: add menuIsOpen support to search select input

* fix: test case typo, clean up code and add changeset

* test: revert select input menuIsOpen prop code

* fix: adapt on cr requests and trim code and change changeset message

* Update .changeset/polite-bags-collect.md

Co-authored-by: Yemitan Isaiah Olurotimi <[email protected]>

* Delete .changeset/kind-moons-drive.md

* fix: change changeset text

---------

Co-authored-by: Lucas Grahn <[email protected]>
Co-authored-by: Yemitan Isaiah Olurotimi <[email protected]>
Co-authored-by: Carlos Cortizas <[email protected]>
  • Loading branch information
4 people authored Nov 17, 2023
1 parent 36ab2f4 commit c752724
Show file tree
Hide file tree
Showing 16 changed files with 91 additions and 19 deletions.
7 changes: 7 additions & 0 deletions .changeset/polite-bags-collect.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
---
'@commercetools-uikit/search-select-input': minor
'@commercetools-uikit/async-select-input': minor
'@commercetools-uikit/select-input': minor
---

We introduced a new (_boolean_) property (**menuIsOpen**) to Select Inputs components which allows to control the dropdown visibility.
19 changes: 9 additions & 10 deletions packages/components/avatar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,6 @@ const Example = () => (
firstName="John"
lastName="Doe"
size="s"
color="accent"
/>
);

Expand All @@ -47,12 +46,12 @@ export default Example;

## Properties

| Props | Type | Required | Default | Description |
| --------------- | ----------------------------------------------------------------------------- | :------: | ---------- | --------------------------------------- |
| `firstName` | `string` | | `''` | The first name of the user. |
| `lastName` | `string` | | `''` | The last name of the user. |
| `gravatarHash` | `string` || | The hashed string of the user gravatar. |
| `isHighlighted` | `boolean` | | `false` | Enhances the appearance of the avatar. |
| `size` | `union`<br/>Possible values:<br/>`'s' , 'm' , 'l'` | | `'s'` | The size of the rendered avatar. |
| `color` | `union`<br/>Possible values:<br/>`'accent' , 'purple' , 'turquoise', 'brown'` | | `'accent'` | The color of the rendered avatar. |
| `icon` | `ReactElement` | | | an `<Icon />` component |
| Props | Type | Required | Default | Description |
| --------------- | ------------------------------------------------------------------------------ | :------: | ---------- | --------------------------------------- |
| `firstName` | `string` | | `''` | The first name of the user. |
| `lastName` | `string` | | `''` | The last name of the user. |
| `gravatarHash` | `string` || | The hashed string of the user gravatar. |
| `isHighlighted` | `boolean` | | `false` | Enhances the appearance of the avatar. |
| `size` | `union`<br/>Possible values:<br/>`'s' , 'm' , 'l'` | | `'s'` | The size of the rendered avatar. |
| `color` | `union`<br/>Possible values:<br/>`'accent' , 'purple' , 'turquoise' , 'brown'` | | `'accent'` | The color of the avatar. |
| `icon` | `ReactElement` | | | an <Icon /> component |
1 change: 1 addition & 0 deletions packages/components/inputs/async-select-input/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ export default Example;
| `isOptionDisabled` | `AsyncProps['isOptionDisabled']` | | | Override the built-in logic to detect whether an option is disabled&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `isMulti` | `AsyncProps['isMulti']` | | | Support multiple selected options&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `isSearchable` | `AsyncProps['isSearchable']` | | `true` | Whether to enable search functionality&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuIsOpen` | `AsyncProps['menuIsOpen']` | | | Can be used to enforce the select input to be opened&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `maxMenuHeight` | `AsyncProps['maxMenuHeight']` | | | Maximum height of the menu before scrolling&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuPortalTarget` | `AsyncProps['menuPortalTarget']` | | | Dom element to portal the select menu to&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuPortalZIndex` | `number` | | `1` | z-index value for the menu portal&#xA;<br>&#xA;Use in conjunction with `menuPortalTarget` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,26 @@ it('should have focus automatically when isAutofocussed is passed', async () =>
expect(await findByLabelText('Fruit')).toHaveFocus();
});

it('should have an open menu if menuIsOpen is true', async () => {
const { findByLabelText, getByText } = renderInput({
menuIsOpen: true,
});
const input = await findByLabelText('Fruit');

expect(getByText('Mango')).toBeInTheDocument();
});

it('should not have an open menu if menuIsOpen is true and isReadOnly is true', async () => {
const { findByLabelText, queryByText } = renderInput({
menuIsOpen: true,
isReadOnly: true,
});

const input = await findByLabelText('Fruit');

expect(queryByText('Mango')).not.toBeInTheDocument();
});

it('should call onFocus when the input is focused', async () => {
const onFocus = jest.fn();
const { findByLabelText } = renderInput({ onFocus });
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class SelectStory extends Component {
static displayName = 'SelectStory';
render() {
const isMulti = boolean('isMulti', false);
const menuIsOpen = boolean('menuIsOpen', false);
const defaultOptions = boolean('defaultOptions', true)
? colourOptions
: false;
Expand Down Expand Up @@ -97,6 +98,7 @@ class SelectStory extends Component {
isDisabled={boolean('isDisabled', false)}
isReadOnly={boolean('isReadOnly', false)}
isMulti={isMulti}
menuIsOpen={menuIsOpen}
isSearchable={boolean('isSearchable', true)}
maxMenuHeight={number('maxMenuHeight', 220)}
closeMenuOnSelect={boolean('closeMenuOnSelect', true)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,12 @@ export type TAsyncSelectInputProps = {
* [Props from React select was used](https://react-select.com/props)
*/
isSearchable?: ReactSelectAsyncProps['isSearchable'];
/**
* Can be used to enforce the select input to be opened
* <br>
* [Props from React select was used](https://react-select.com/props)
*/
menuIsOpen?: ReactSelectAsyncProps['menuIsOpen'];
/**
* Maximum height of the menu before scrolling
* <br>
Expand Down Expand Up @@ -370,7 +376,7 @@ const AsyncSelectInput = (props: TAsyncSelectInputProps) => {
...props.components,
} as ReactSelectAsyncProps['components']
}
menuIsOpen={props.isReadOnly ? false : undefined}
menuIsOpen={props.isReadOnly ? false : props.menuIsOpen}
styles={
createSelectStyles({
hasWarning: props.hasWarning,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,11 @@ npm --save install @commercetools-uikit/localized-rich-text-input
Additionally install the peer dependencies (if not present)

```
yarn add react react-intl
yarn add react react-dom react-intl
```

```
npm --save install react react-intl
npm --save install react react-dom react-intl
```

## Usage
Expand Down
4 changes: 2 additions & 2 deletions packages/components/inputs/rich-text-input/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ npm --save install @commercetools-uikit/rich-text-input
Additionally install the peer dependencies (if not present)

```
yarn add react react-intl
yarn add react react-dom react-intl
```

```
npm --save install react react-intl
npm --save install react react-dom react-intl
```

## Usage
Expand Down
1 change: 1 addition & 0 deletions packages/components/inputs/search-select-input/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ export default Example;
| `isMulti` | `AsyncProps['isMulti']` | | | Support multiple selected options&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `isAutofocussed` | `boolean` | | | Focus the control when it is mounted. Renamed autoFocus of react-select |
| `noOptionsMessage` | `AsyncProps['noOptionsMessage']` | | | Can be used to render a custom value when there are no options (either because of no search results, or all options have been used, or there were none in the first place). Gets called with `{ inputValue: String }`. `inputValue` will be an empty string when no search text is present.&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuIsOpen` | `AsyncProps['menuIsOpen']` | | | Can be used to enforce the select input to be opened&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `maxMenuHeight` | `AsyncProps['maxMenuHeight']` | | `220` | Maximum height of the menu before scrolling&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuPortalTarget` | `AsyncProps['menuPortalTarget']` | | | Dom element to portal the select menu to&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuPortalZIndex` | `number` | | `1` | z-index value for the menu portal&#xA;<br>&#xA;Use in conjunction with `menuPortalTarget` |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ class SearchSelectInputStory extends Component {
static displayName = 'SearchSelectInputStory';
render() {
const isMulti = boolean('isMulti', false);
const menuIsOpen = boolean('menuIsOpen', false);
const noOptionsMessage = text(
'No options message',
'No matches found for your search term'
Expand Down Expand Up @@ -100,6 +101,7 @@ class SearchSelectInputStory extends Component {
isMulti={isMulti}
noOptionsMessage={() => noOptionsMessage}
loadingMessage={loadingMessage}
menuIsOpen={menuIsOpen}
maxMenuHeight={number('maxMenuHeight', 220)}
closeMenuOnSelect={boolean('closeMenuOnSelect', true)}
name={text('name', 'form-field-name')}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,12 @@ export type TSearchSelectInputProps = {
* [Props from React select was used](https://react-select.com/props)
*/
noOptionsMessage?: ReactSelectAsyncProps['noOptionsMessage'];
/**
* Can be used to enforce the select input to be opened
* <br>
* [Props from React select was used](https://react-select.com/props)
*/
menuIsOpen?: ReactSelectAsyncProps['menuIsOpen'];
/**
* Maximum height of the menu before scrolling
* <br>
Expand Down
1 change: 1 addition & 0 deletions packages/components/inputs/select-input/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ export default Example;
| `isOptionDisabled` | `ReactSelectProps['isOptionDisabled']` | | | Override the built-in logic to detect whether an option is disabled&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `isMulti` | `ReactSelectProps['isMulti']` | | | Support multiple selected options&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `isSearchable` | `ReactSelectProps['isSearchable']` | | | Whether to enable search functionality&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuIsOpen` | `ReactSelectProps['menuIsOpen']` | | | Can be used to enforce the select input to be opened&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `maxMenuHeight` | `ReactSelectProps['maxMenuHeight']` | | `220` | Maximum height of the menu before scrolling&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuPortalTarget` | `ReactSelectProps['menuPortalTarget']` | | | Dom element to portal the select menu to&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuPortalZIndex` | `number` | | `1` | z-index value for the menu portal&#xA;<br>&#xA;Use in conjunction with `menuPortalTarget` |
Expand Down
20 changes: 20 additions & 0 deletions packages/components/inputs/select-input/src/select-input.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,26 @@ it('should have focus automatically when isAutofocussed is passed', () => {
expect(getByLabelText('Fruit')).toHaveFocus();
});

it('should have an open menu if menuIsOpen is true', () => {
const { getByLabelText, getByText } = renderInput({
menuIsOpen: true,
});
const input = getByLabelText('Fruit');

expect(getByText('Mango')).toBeInTheDocument();
});

it('should not have an open menu if menuIsOpen is true and isReadOnly is true', () => {
const { getByLabelText, queryByText } = renderInput({
menuIsOpen: true,
isReadOnly: true,
});

const input = getByLabelText('Fruit');

expect(queryByText('Mango')).not.toBeInTheDocument();
});

it('should call onFocus when the input is focused', () => {
const onFocus = jest.fn();
const { getByLabelText } = renderInput({ onFocus });
Expand Down
Loading

1 comment on commit c752724

@vercel
Copy link

@vercel vercel bot commented on c752724 Nov 17, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.