Skip to content

Commit

Permalink
docs: menuPortalZIndex docs improvements (#2484)
Browse files Browse the repository at this point in the history
* docs: make menuPortalZIndex docs more explicit

* refactor: copy implementation to all stories

* refactor: warn when menuPortalZIndex used without menuPortalTarget

* chore: add changeset

* refactor: change and externalize implementation of warning

* refactor: dry

* refactor: dry part 2

* chore: rename

* chore: rename
  • Loading branch information
kark authored Apr 13, 2023
1 parent 26830d8 commit 75da6b8
Show file tree
Hide file tree
Showing 47 changed files with 723 additions and 479 deletions.
19 changes: 19 additions & 0 deletions .changeset/strong-spoons-provide.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
'@commercetools-uikit/async-creatable-select-field': patch
'@commercetools-uikit/async-creatable-select-input': patch
'@commercetools-uikit/selectable-search-input': patch
'@commercetools-uikit/creatable-select-field': patch
'@commercetools-uikit/creatable-select-input': patch
'@commercetools-uikit/search-select-field': patch
'@commercetools-uikit/search-select-input': patch
'@commercetools-uikit/async-select-field': patch
'@commercetools-uikit/async-select-input': patch
'@commercetools-uikit/select-field': patch
'@commercetools-uikit/select-input': patch
'@commercetools-uikit/select-utils': patch
'@commercetools-uikit/money-field': patch
'@commercetools-uikit/money-input': patch
---

Improve docs regarding the use of `menuPortalZIndex` prop.
Warn when `menuPortalZIndex` is used without setting `menuPortalTarget`.
1 change: 1 addition & 0 deletions docs/.storybook/decorators/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export { default as FormikBox } from './formik-box';
export { default as Section } from './section';
export { default as NeighbouringStackingContext } from './neighbouring-stacking-context';
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './neighbouring-stacking-context';
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import Card from '@commercetools-uikit/card';
import styled from '@emotion/styled';
import { boolean } from '@storybook/addon-knobs/react';

const StackingContext = styled.div`
width: 300px;
height: 50px;
position: relative;
z-index: 2;
`;

const NeighbouringStackingContext = () => {
const isActive = boolean(
'menuPortalZIndex-show-neighbouring-stacking-context',
false
);
return (
isActive && (
<StackingContext>
<Card theme="dark">
Stacking context with <code>z-index: 2</code>
</Card>
</StackingContext>
)
);
};

export default NeighbouringStackingContext;
21 changes: 21 additions & 0 deletions docs/.storybook/utils/add-menu-portal-props.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { select } from '@storybook/addon-knobs/react';

const getMenuPortalTargetValue = (menuPortalTarget) => {
if (menuPortalTarget === 'document.body') {
return document.body;
}
return undefined;
};

export const addMenuPortalProps = () => {
const menuPortalZIndex = select('menuPortalZIndex', [1, 2, 3], 1);
const menuPortalTarget = select(
'menuPortalTarget',
['undefined', 'document.body'],
'undefined'
);
return {
menuPortalZIndex,
menuPortalTarget: getMenuPortalTargetValue(menuPortalTarget),
};
};
1 change: 1 addition & 0 deletions docs/.storybook/utils/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { addMenuPortalProps } from './add-menu-portal-props';
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ export default Example;
| `hasWarning` | `boolean` | | | Indicates the input field has a warning |
| `maxMenuHeight` | `AsyncCreatableProps['maxMenuHeight']` | | | Maximum height of the menu before scrolling&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `menuPortalTarget` | `AsyncCreatableProps['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` | | | z-index value for the menu portal |
| `menuPortalZIndex` | `number` | | | z-index value for the menu portal&#xA;<br>&#xA;Use in conjunction with `menuPortalTarget` |
| `menuShouldBlockScroll` | `AsyncCreatableProps['menuShouldBlockScroll']` | | | whether the menu should block scroll while open&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `name` | `AsyncCreatableProps['name']` | | | Name of the HTML Input (optional - without this, no input will be rendered)&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `noOptionsMessage` | `AsyncCreatableProps['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).&#xA;<br/>&#xA;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) |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,10 @@ import {
number,
} from '@storybook/addon-knobs/react';
import Constraints from '@commercetools-uikit/constraints';
import Spacings from '@commercetools-uikit/spacings';
import Section from '../../../../../docs/.storybook/decorators/section';
import NeighbouringStackingContext from '../../../../../docs/.storybook/decorators/neighbouring-stacking-context';
import { addMenuPortalProps } from '../../../../../docs/.storybook/utils';
import * as icons from '../../../icons';
import Readme from '../README.md';
import AsyncCreatableSelectField from './async-creatable-select-field';
Expand Down Expand Up @@ -109,75 +112,79 @@ storiesOf('Components|Fields/SelectFields', module)
key={isMulti}
defaultValue={isMulti ? [] : undefined}
render={(value, onChange) => (
<AsyncCreatableSelectField
horizontalConstraint={select(
'horizontalConstraint',
Constraints.getAcceptedMaxPropValues(3),
7
)}
errors={object('errors', { missing: true, customError: true })}
renderError={(key) => {
switch (key) {
case 'customError':
return 'A custom error.';
default:
return null;
<Spacings.Stack scale="m">
<AsyncCreatableSelectField
horizontalConstraint={select(
'horizontalConstraint',
Constraints.getAcceptedMaxPropValues(3),
7
)}
errors={object('errors', { missing: true, customError: true })}
renderError={(key) => {
switch (key) {
case 'customError':
return 'A custom error.';
default:
return null;
}
}}
isRequired={boolean('isRequired', false)}
touched={boolean('touched', false)}
aria-label={text('aria-label', '')}
aria-labelledby={text('aria-labelledby', '')}
backspaceRemovesValue={boolean('backspaceRemovesValue', true)}
containerId={text('containerId', '')}
id={id || undefined}
name={name}
value={value}
onChange={(event) => {
action('onChange')(event);
onChange(event.target.value);
}}
onBlur={action('onBlur')}
onFocus={action('onFocus')}
onInputChange={action('onInputChange')}
isAutofocussed={boolean('isAutofocussed', false)}
isDisabled={boolean('isDisabled', false)}
isReadOnly={boolean('isReadOnly', false)}
isMulti={isMulti}
hasWarning={boolean('hasWarning', false)}
placeholder={text('placeholder', 'Select...')}
title={text('title', 'Favourite animal')}
maxMenuHeight={number('maxMenuHeight', 220)}
isSearchable={boolean('isSearchable', false)}
isClearable={boolean('isClearable', false)}
tabIndex={text('tabIndex', '0')}
tabSelectsValue={boolean('tabSelectsValue', true)}
// Async props
defaultOptions={defaultOptions}
loadOptions={loadOptions}
cacheOptions={boolean('cacheOptions', false)}
// Creatable props
allowCreateWhileLoading={boolean(
'allowCreateWhileLoading',
false
)}
createOptionPosition={select(
'createOptionPosition',
['first', 'last'],
'last'
)}
// FieldLabel
hint={hint}
description={text('description', '')}
onInfoButtonClick={
boolean('show info button', false)
? action('onInfoButtonClick')
: undefined
}
}}
isRequired={boolean('isRequired', false)}
touched={boolean('touched', false)}
aria-label={text('aria-label', '')}
aria-labelledby={text('aria-labelledby', '')}
backspaceRemovesValue={boolean('backspaceRemovesValue', true)}
containerId={text('containerId', '')}
id={id || undefined}
name={name}
value={value}
onChange={(event) => {
action('onChange')(event);
onChange(event.target.value);
}}
onBlur={action('onBlur')}
onFocus={action('onFocus')}
onInputChange={action('onInputChange')}
isAutofocussed={boolean('isAutofocussed', false)}
isDisabled={boolean('isDisabled', false)}
isReadOnly={boolean('isReadOnly', false)}
isMulti={isMulti}
hasWarning={boolean('hasWarning', false)}
placeholder={text('placeholder', 'Select...')}
title={text('title', 'Favourite animal')}
maxMenuHeight={number('maxMenuHeight', 220)}
isSearchable={boolean('isSearchable', false)}
isClearable={boolean('isClearable', false)}
tabIndex={text('tabIndex', '0')}
tabSelectsValue={boolean('tabSelectsValue', true)}
// Async props
defaultOptions={defaultOptions}
loadOptions={loadOptions}
cacheOptions={boolean('cacheOptions', false)}
// Creatable props
allowCreateWhileLoading={boolean(
'allowCreateWhileLoading',
false
)}
createOptionPosition={select(
'createOptionPosition',
['first', 'last'],
'last'
)}
// FieldLabel
hint={hint}
description={text('description', '')}
onInfoButtonClick={
boolean('show info button', false)
? action('onInfoButtonClick')
: undefined
}
hintIcon={hintIcon}
badge={text('badge', '')}
iconLeft={iconLeft ? createElement(iconLeft) : undefined}
/>
hintIcon={hintIcon}
badge={text('badge', '')}
iconLeft={iconLeft ? createElement(iconLeft) : undefined}
{...addMenuPortalProps()}
/>
<NeighbouringStackingContext />
</Spacings.Stack>
)}
/>
</Section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ export type TAsyncCreatableSelectFieldProps = {
menuPortalTarget?: ReactSelectAsyncCreatableProps['menuPortalTarget'];
/**
* z-index value for the menu portal
* <br>
* Use in conjunction with `menuPortalTarget`
*/
menuPortalZIndex?: number;
/**
Expand Down
2 changes: 1 addition & 1 deletion packages/components/fields/async-select-field/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ export default Example;
| `hasWarning` | `boolean` | | | Indicates the input field has a warning |
| `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` | | | z-index value for the menu portal |
| `menuPortalZIndex` | `number` | | | z-index value for the menu portal&#xA;<br>&#xA;Use in conjunction with `menuPortalTarget` |
| `menuShouldBlockScroll` | `AsyncProps['menuShouldBlockScroll']` | | | whether the menu should block scroll while open&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `name` | `AsyncProps['name']` | | | Name of the HTML Input (optional - without this, no input will be rendered)&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
| `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).&#xA;<br>&#xA;[Props from React select was used](https://react-select.com/props) |
Expand Down
Loading

1 comment on commit 75da6b8

@vercel
Copy link

@vercel vercel bot commented on 75da6b8 Apr 13, 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.