Skip to content

Commit

Permalink
export StripesOverlayWrapper and document its existence, and usage
Browse files Browse the repository at this point in the history
  • Loading branch information
JohnC-80 committed Oct 3, 2024
1 parent 20c4778 commit c4250f2
Show file tree
Hide file tree
Showing 9 changed files with 43 additions and 11 deletions.
19 changes: 19 additions & 0 deletions guides/UIModuleLayout.stories.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -42,3 +42,22 @@ class LayoutExample extends React.Component {
export default LayoutExample;
```

## Portals

Another detail of the stripes UI is that we render a special lement that 'overlay' components such as Dropdowns or Datepicker's Calendar control can render into if the controls run the risk of
Being overlapped. This feature should **only** be used when overlapping is possible since it does involve rendering interactive elements/sending focus to other parts of the DOM.
Each of these components implements a `usePortal` prop that will render its menu to the overlay elements. We also export a `<StripesOverlayWrapper>` that will automatically apply
the `usePortal` behavior to nested overlay components. `<Modal>` and `<MultiColumnList>` components build in a `<StripesOverlayWrapper>` by default.

Basic Usage:

```
{/* usePortal is necessary for individual components outside of a StripesOverlayWrapper */}
<Datepicker usePortal />
<StripesOverlayWrapper>
{/* usePortal isn't necessary here */}
<ListOfOverlayComponents />
</StripesOverlayWrapper>
```
2 changes: 1 addition & 1 deletion index.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ export {
currenciesByNumber,
currenciesOptions
} from './util/currencies';

export { default as StripesOverlayWrapper } from './util/StripesOverlayWrapper';
export {
default as countries,
countriesByCode,
Expand Down
2 changes: 1 addition & 1 deletion lib/Datepicker/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ Name | type | description | default | required
`timeZone` | string | Overrides the time zone provided by context. | "UTC" | false
`useFocus` | bool | if set to false, component relies solely on clicking the calendar icon to toggle appearance of calendar. | true | false
`useInput` | bool | tells the Datepicker that it is being used under react-final-form, so it can modify its behaviour accodingly. **This is necessary when used with react-final-form** or the Datepicker will not work. | false | false
`usePortal` | bool | if true, the Datepicker will render itself to a React-Portal (the `#OverlayContainer` div) this avoids haveing the Datepicker cutoff by overflow. | false | false
`usePortal` | bool | if true, the Datepicker will render itself to a React-Portal (the `#OverlayContainer` div) this avoids haveing the Datepicker cutoff by overflow. Given the container of this component, `usePortal` may not be required. See [portals documentation](https://folio-org.github.io/stripes-components/iframe.html?viewMode=docs&id=guides-ui-layout--docs#portals) for guidance. | false | false
`value` | string | date to be displayed in the textfield. In forms, this is supplied by the initialValues prop supplied to the form | "" | false

<!-- dateFormat | string | system formatting for date. [Moment.js formats](https://momentjs.com/docs/#/displaying/format/) are supported | "MM/DD/YYYY" | false-->
Expand Down
6 changes: 3 additions & 3 deletions lib/Modal/WrappingElement.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
import PropTypes from 'prop-types';
import * as focusTrap from 'focus-trap';
import { listen } from '../../util/listen';
import StripesOverlayContext from '../../util/StripesOverlayContext';
import StripesOverlayWrapper from '../../util/StripesOverlayWrapper';
import { OVERLAY_CONTAINER_SELECTOR } from '../../util/consts';
import calloutCSS from '../Callout/Callout.css';
import overlayCSS from '../Popper/Popper.css';
Expand Down Expand Up @@ -155,9 +155,9 @@ const WrappingElement = forwardRef(({
ref={wrappingElementRef}
{...rest}
>
<StripesOverlayContext.Provider value={{ usePortal: true }}>
<StripesOverlayWrapper>
{children}
</StripesOverlayContext.Provider>
</StripesOverlayWrapper>
</WrappingElementComponent>
);
});
Expand Down
6 changes: 3 additions & 3 deletions lib/MultiColumnList/MCLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ import memoizeOne from 'memoize-one';

import Icon from '../Icon';
import EmptyMessage from '../EmptyMessage';
import StripesOverlayContext from '../../util/StripesOverlayContext';
import StripesOverlayWrapper from '../../util/StripesOverlayWrapper';
import { HotKeys } from '../HotKeys';
import SRStatus from '../SRStatus';
import css from './MCLRenderer.css';
Expand Down Expand Up @@ -1936,7 +1936,7 @@ class MCLRenderer extends React.Component {
: css.mclRowContainer;

return (
<StripesOverlayContext.Provider value={{ usePortal: true }}>
<StripesOverlayWrapper>
<HotKeys handlers={this.handlers} attach={this.shortcutsRef} noWrapper>
<div className={css.mclContainer} ref={this.shortcutsRef} style={this.getOuterElementStyle()}>
<SRStatus ref={this.status} />
Expand Down Expand Up @@ -2019,7 +2019,7 @@ class MCLRenderer extends React.Component {
}
</div>
</HotKeys>
</StripesOverlayContext.Provider>
</StripesOverlayWrapper>
);
}
}
Expand Down
2 changes: 1 addition & 1 deletion lib/MultiSelection/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Name | type | description | default | required
`onRemove` | func | Event handler specifically called when an item is removed from the selection. The removed item is passed to the handler. | |
`placeholder` | string | Rendered as a placeholder for the control when no value is present. | |
`showLoading` | bool | Should render loading indicator on the field | |
`usePortal` | bool | If `true`, option list will render to the `div[#OverlayContainer]` element in the FOLIO UI. | |
`usePortal` | bool | If `true`, option list will render to the `div[#OverlayContainer]` element in the FOLIO UI. Given the container of this component, `usePortal` may not be required. See [portals documentation](https://folio-org.github.io/stripes-components/iframe.html?viewMode=docs&id=guides-ui-layout--docs#portals) for guidance. | |
`value` | array | Array of selected objects. | |
`valueFormatter` | func | Render function that accepts an object with keys for the option. The function is called to display values in the selected values list. If the prop is missing, `formatter` will be used instead. | |
`ariaLabelledBy` | string | Used for applying an accessible label if no `label` prop is provided | |
Expand Down
2 changes: 1 addition & 1 deletion lib/Selection/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ Name | type | description | default | required
`useValidStyle` | bool | if true, "success" styles will be applied to control if it contains a valid value `onBlur` (using redux-form validation.) | false |
`autoFocus` | bool | If this prop is `true`, control will automatically focus on mount | |
`popper` | object | Used to adjust placement of options list overlay via underlying Popper component. [See `<Popper>` props](../Popper/readme.md) | | false |
`usePortal` | bool | If `true`, option list will render to the `div[#OverlayContainer]` element in the FOLIO UI. | |
`usePortal` | bool | If `true`, option list will render to the `div[#OverlayContainer]` element in the FOLIO UI. Given the container of this component, `usePortal` may not be required. See [portals documentation](https://folio-org.github.io/stripes-components/iframe.html?viewMode=docs&id=guides-ui-layout--docs#portals) for guidance. | |

## Labeling
Like other form controls in stripes-components, `<Selection>` abides by standard conventions for labeling props if alternatives to `label` (visible label with the control) are required... `aria-label` and `aria-labelledby` are useful for this. See [Accessiblity for developers documentation](https://github.com/folio-org/stripes-components/blob/master/guides/AccessibilityDevPrimer.stories.mdx#labeling) for more details about which to choose.
Expand Down
2 changes: 1 addition & 1 deletion lib/Timepicker/readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ Name | type | description | default | required
`timeZone` | string | Overrides the time zone provided by context. | "UTC" | false
`timeFormat` | string | String to override default time format according to locale | | false
`useInput` | bool | If true - Outputs the value as it is displayed in the input. | false |
`usePortal` | bool | if true, the Timepicker will render itself to a React-Portal (the `#OverlayContainer` div) this avoids haveing the Timepicker cutoff by overflow. | false | false
`usePortal` | bool | if true, the Timepicker will render itself to a React-Portal (the `#OverlayContainer` div) this avoids haveing the Timepicker cutoff by overflow. Given the container of this component, `usePortal` may not be required. See [portals documentation](https://folio-org.github.io/stripes-components/iframe.html?viewMode=docs&id=guides-ui-layout--docs#portals) for guidance. | false | false
`value` | string | time to be displayed in the visible input. | | false


Expand Down
13 changes: 13 additions & 0 deletions util/StripesOverlayWrapper.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import StripesOverlayContext from './StripesOverlayContext';

/** UI modules can import `StripesOverlayWrapper` to wrap component trees where
* usage of the `usePortal` prop will be prevalent among children.
<StripesOverlayWrapper>
<ListOfOverlayComponentsLikeDatepickerSelectionEtc />
</StripesOverlayWrapper>
*/
export default ({ children }) => (
<StripesOverlayContext.Provider value={{ usePortal: true }}>
{children}
</StripesOverlayContext.Provider>
);

0 comments on commit c4250f2

Please sign in to comment.