@react-spectrum/overlays 3.7.1 → 4.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Modal.tsx CHANGED
@@ -10,41 +10,35 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import {AriaModalOverlayProps, useModalOverlay} from '@react-aria/overlays';
13
14
  import {classNames, useDOMRef, useStyleProps} from '@react-spectrum/utils';
14
- import {DOMRef} from '@react-types/shared';
15
- import {mergeProps, useViewportSize} from '@react-aria/utils';
16
- import {ModalProps} from '@react-types/overlays';
15
+ import {DOMRef, StyleProps} from '@react-types/shared';
17
16
  import modalStyles from '@adobe/spectrum-css-temp/components/modal/vars.css';
18
17
  import {Overlay} from './Overlay';
18
+ import {OverlayProps} from '@react-types/overlays';
19
+ import {OverlayTriggerState} from '@react-stately/overlays';
19
20
  import overrideStyles from './overlays.css';
20
- import React, {forwardRef, HTMLAttributes, ReactNode, RefObject} from 'react';
21
+ import React, {forwardRef, ReactNode, RefObject} from 'react';
21
22
  import {Underlay} from './Underlay';
22
- import {useModal, useOverlay, usePreventScroll} from '@react-aria/overlays';
23
+ import {useViewportSize} from '@react-aria/utils';
23
24
 
24
- interface ModalWrapperProps extends HTMLAttributes<HTMLElement> {
25
+ interface ModalProps extends AriaModalOverlayProps, StyleProps, OverlayProps {
25
26
  children: ReactNode,
26
- isOpen?: boolean,
27
- onClose?: () => void,
28
- type?: 'modal' | 'fullscreen' | 'fullscreenTakeover',
29
- overlayProps: HTMLAttributes<HTMLElement>
27
+ state: OverlayTriggerState,
28
+ type?: 'modal' | 'fullscreen' | 'fullscreenTakeover'
29
+ }
30
+
31
+ interface ModalWrapperProps extends ModalProps {
32
+ isOpen?: boolean
30
33
  }
31
34
 
32
35
  function Modal(props: ModalProps, ref: DOMRef<HTMLDivElement>) {
33
- let {children, onClose, type, ...otherProps} = props;
36
+ let {children, state, ...otherProps} = props;
34
37
  let domRef = useDOMRef(ref);
35
- let {styleProps} = useStyleProps(props);
36
-
37
- let {overlayProps, underlayProps} = useOverlay(props, domRef);
38
38
 
39
39
  return (
40
- <Overlay {...otherProps}>
41
- <Underlay {...underlayProps} />
42
- <ModalWrapper
43
- {...styleProps}
44
- onClose={onClose}
45
- type={type}
46
- ref={domRef}
47
- overlayProps={overlayProps}>
40
+ <Overlay {...otherProps} isOpen={state.isOpen}>
41
+ <ModalWrapper {...props} ref={domRef}>
48
42
  {children}
49
43
  </ModalWrapper>
50
44
  </Overlay>
@@ -57,12 +51,11 @@ let typeMap = {
57
51
  };
58
52
 
59
53
  let ModalWrapper = forwardRef(function (props: ModalWrapperProps, ref: RefObject<HTMLDivElement>) {
60
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
61
- let {children, isOpen, type, overlayProps, ...otherProps} = props;
54
+ let {type, children, state, isOpen} = props;
62
55
  let typeVariant = typeMap[type];
56
+ let {styleProps} = useStyleProps(props);
63
57
 
64
- usePreventScroll();
65
- let {modalProps} = useModal();
58
+ let {modalProps, underlayProps} = useModalOverlay(props, state, ref);
66
59
 
67
60
  let wrapperClassName = classNames(
68
61
  modalStyles,
@@ -86,7 +79,7 @@ let ModalWrapper = forwardRef(function (props: ModalWrapperProps, ref: RefObject
86
79
  'react-spectrum-Modal'
87
80
  ),
88
81
  {[`spectrum-Modal--${typeVariant}`]: typeVariant},
89
- otherProps.className
82
+ styleProps.className
90
83
  );
91
84
 
92
85
  let viewport = useViewportSize();
@@ -95,15 +88,19 @@ let ModalWrapper = forwardRef(function (props: ModalWrapperProps, ref: RefObject
95
88
  };
96
89
 
97
90
  return (
98
- <div className={wrapperClassName} style={style}>
99
- <div
100
- {...mergeProps(otherProps, overlayProps, modalProps)}
101
- ref={ref}
102
- className={modalClassName}
103
- data-testid="modal">
104
- {children}
91
+ <>
92
+ <Underlay {...underlayProps} isOpen={isOpen} />
93
+ <div className={wrapperClassName} style={style}>
94
+ <div
95
+ {...styleProps}
96
+ {...modalProps}
97
+ ref={ref}
98
+ className={modalClassName}
99
+ data-testid="modal">
100
+ {children}
101
+ </div>
105
102
  </div>
106
- </div>
103
+ </>
107
104
  );
108
105
  });
109
106
 
package/src/Overlay.tsx CHANGED
@@ -15,7 +15,7 @@ import {OpenTransition} from './OpenTransition';
15
15
  import {OverlayProps} from '@react-types/overlays';
16
16
  import {Provider} from '@react-spectrum/provider';
17
17
  import React, {useCallback, useState} from 'react';
18
- import ReactDOM from 'react-dom';
18
+ import {Overlay as ReactAriaOverlay} from '@react-aria/overlays';
19
19
 
20
20
  function Overlay(props: OverlayProps, ref: DOMRef<HTMLDivElement>) {
21
21
  let {children, isOpen, container, onEnter, onEntering, onEntered, onExit, onExiting, onExited} = props;
@@ -42,23 +42,23 @@ function Overlay(props: OverlayProps, ref: DOMRef<HTMLDivElement>) {
42
42
  return null;
43
43
  }
44
44
 
45
- let contents = (
46
- <Provider ref={ref} UNSAFE_style={{background: 'transparent', isolation: 'isolate'}}>
47
- <OpenTransition
48
- in={isOpen}
49
- appear
50
- onExit={onExit}
51
- onExiting={onExiting}
52
- onExited={handleExited}
53
- onEnter={onEnter}
54
- onEntering={onEntering}
55
- onEntered={handleEntered}>
56
- {children}
57
- </OpenTransition>
58
- </Provider>
45
+ return (
46
+ <ReactAriaOverlay portalContainer={container}>
47
+ <Provider ref={ref} UNSAFE_style={{background: 'transparent', isolation: 'isolate'}} isDisabled={false}>
48
+ <OpenTransition
49
+ in={isOpen}
50
+ appear
51
+ onExit={onExit}
52
+ onExiting={onExiting}
53
+ onExited={handleExited}
54
+ onEnter={onEnter}
55
+ onEntering={onEntering}
56
+ onEntered={handleEntered}>
57
+ {children}
58
+ </OpenTransition>
59
+ </Provider>
60
+ </ReactAriaOverlay>
59
61
  );
60
-
61
- return ReactDOM.createPortal(contents, container || document.body);
62
62
  }
63
63
 
64
64
  let _Overlay = React.forwardRef(Overlay);
package/src/Popover.tsx CHANGED
@@ -10,27 +10,25 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import {AriaPopoverProps, DismissButton, usePopover} from '@react-aria/overlays';
13
14
  import {classNames, useDOMRef, useStyleProps} from '@react-spectrum/utils';
14
- import {DOMRef} from '@react-types/shared';
15
- import {mergeProps, useLayoutEffect} from '@react-aria/utils';
15
+ import {DOMRef, StyleProps} from '@react-types/shared';
16
16
  import {Overlay} from './Overlay';
17
+ import {OverlayTriggerState} from '@react-stately/overlays';
17
18
  import overrideStyles from './overlays.css';
18
- import {PlacementAxis, PopoverProps} from '@react-types/overlays';
19
- import React, {forwardRef, HTMLAttributes, ReactNode, RefObject, useRef, useState} from 'react';
19
+ import React, {forwardRef, ReactNode, RefObject, useRef, useState} from 'react';
20
20
  import styles from '@adobe/spectrum-css-temp/components/popover/vars.css';
21
- import {useModal, useOverlay} from '@react-aria/overlays';
21
+ import {Underlay} from './Underlay';
22
+ import {useLayoutEffect} from '@react-aria/utils';
22
23
 
23
- interface PopoverWrapperProps extends HTMLAttributes<HTMLElement> {
24
+ interface PopoverProps extends Omit<AriaPopoverProps, 'popoverRef' | 'maxHeight'>, StyleProps {
24
25
  children: ReactNode,
25
- placement?: PlacementAxis,
26
- arrowProps?: HTMLAttributes<HTMLElement>,
27
26
  hideArrow?: boolean,
28
- isOpen?: boolean,
29
- onClose?: () => void,
30
- shouldCloseOnBlur?: boolean,
31
- isKeyboardDismissDisabled?: boolean,
32
- isNonModal?: boolean,
33
- isDismissable?: boolean
27
+ state: OverlayTriggerState
28
+ }
29
+
30
+ interface PopoverWrapperProps extends PopoverProps {
31
+ isOpen?: boolean
34
32
  }
35
33
 
36
34
  /**
@@ -50,32 +48,14 @@ let arrowPlacement = {
50
48
  function Popover(props: PopoverProps, ref: DOMRef<HTMLDivElement>) {
51
49
  let {
52
50
  children,
53
- placement,
54
- arrowProps,
55
- onClose,
56
- shouldCloseOnBlur,
57
- hideArrow,
58
- isKeyboardDismissDisabled,
59
- isNonModal,
60
- isDismissable = true,
51
+ state,
61
52
  ...otherProps
62
53
  } = props;
63
54
  let domRef = useDOMRef(ref);
64
- let {styleProps} = useStyleProps(props);
65
55
 
66
56
  return (
67
- <Overlay {...otherProps}>
68
- <PopoverWrapper
69
- {...styleProps}
70
- ref={domRef}
71
- placement={placement}
72
- arrowProps={arrowProps}
73
- onClose={onClose}
74
- shouldCloseOnBlur={shouldCloseOnBlur}
75
- isKeyboardDismissDisabled={isKeyboardDismissDisabled}
76
- hideArrow={hideArrow}
77
- isNonModal={isNonModal}
78
- isDismissable={isDismissable}>
57
+ <Overlay {...otherProps} isOpen={state.isOpen}>
58
+ <PopoverWrapper ref={domRef} {...props}>
79
59
  {children}
80
60
  </PopoverWrapper>
81
61
  </Overlay>
@@ -85,52 +65,57 @@ function Popover(props: PopoverProps, ref: DOMRef<HTMLDivElement>) {
85
65
  const PopoverWrapper = forwardRef((props: PopoverWrapperProps, ref: RefObject<HTMLDivElement>) => {
86
66
  let {
87
67
  children,
88
- placement = 'bottom',
89
- arrowProps,
90
68
  isOpen,
91
69
  hideArrow,
92
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
93
- shouldCloseOnBlur,
94
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
95
- isKeyboardDismissDisabled,
96
70
  isNonModal,
97
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
98
- isDismissable,
99
- ...otherProps
71
+ state
100
72
  } = props;
101
- let {overlayProps} = useOverlay({...props, isDismissable: isDismissable && isOpen}, ref);
102
- let {modalProps} = useModal({
103
- isDisabled: isNonModal
104
- });
73
+ let {styleProps} = useStyleProps(props);
74
+
75
+ let {popoverProps, arrowProps, underlayProps, placement} = usePopover({
76
+ ...props,
77
+ popoverRef: ref,
78
+ maxHeight: null
79
+ }, state);
105
80
 
106
81
  return (
107
- <div
108
- {...mergeProps(otherProps, overlayProps, modalProps)}
109
- ref={ref}
110
- className={
111
- classNames(
112
- styles,
113
- 'spectrum-Popover',
114
- `spectrum-Popover--${placement}`,
115
- {
116
- 'spectrum-Popover--withTip': !hideArrow,
117
- 'is-open': isOpen
118
- },
82
+ <>
83
+ {!isNonModal && <Underlay isTransparent {...underlayProps} isOpen={isOpen} /> }
84
+ <div
85
+ {...styleProps}
86
+ {...popoverProps}
87
+ style={{
88
+ ...styleProps.style,
89
+ ...popoverProps.style
90
+ }}
91
+ ref={ref}
92
+ className={
119
93
  classNames(
120
- overrideStyles,
94
+ styles,
121
95
  'spectrum-Popover',
122
- 'react-spectrum-Popover'
123
- ),
124
- otherProps.className
125
- )
126
- }
127
- role="presentation"
128
- data-testid="popover">
129
- {children}
130
- {hideArrow ? null : (
131
- <Arrow arrowProps={arrowProps} direction={arrowPlacement[placement]} />
132
- )}
133
- </div>
96
+ `spectrum-Popover--${placement}`,
97
+ {
98
+ 'spectrum-Popover--withTip': !hideArrow,
99
+ 'is-open': isOpen
100
+ },
101
+ classNames(
102
+ overrideStyles,
103
+ 'spectrum-Popover',
104
+ 'react-spectrum-Popover'
105
+ ),
106
+ styleProps.className
107
+ )
108
+ }
109
+ role="presentation"
110
+ data-testid="popover">
111
+ {!isNonModal && <DismissButton onDismiss={state.close} />}
112
+ {children}
113
+ {hideArrow ? null : (
114
+ <Arrow arrowProps={arrowProps} direction={arrowPlacement[placement]} />
115
+ )}
116
+ <DismissButton onDismiss={state.close} />
117
+ </div>
118
+ </>
134
119
  );
135
120
  });
136
121
 
package/src/Tray.tsx CHANGED
@@ -10,43 +10,35 @@
10
10
  * governing permissions and limitations under the License.
11
11
  */
12
12
 
13
+ import {AriaModalOverlayProps, DismissButton, useModalOverlay} from '@react-aria/overlays';
13
14
  import {classNames, useDOMRef, useStyleProps} from '@react-spectrum/utils';
14
- import {DOMRef} from '@react-types/shared';
15
- import {mergeProps, useViewportSize} from '@react-aria/utils';
15
+ import {DOMRef, StyleProps} from '@react-types/shared';
16
16
  import {Overlay} from './Overlay';
17
+ import {OverlayProps} from '@react-types/overlays';
18
+ import {OverlayTriggerState} from '@react-stately/overlays';
17
19
  import overrideStyles from './overlays.css';
18
- import React, {forwardRef, HTMLAttributes, ReactNode, RefObject} from 'react';
19
- import {TrayProps} from '@react-types/overlays';
20
+ import React, {forwardRef, ReactNode, RefObject} from 'react';
20
21
  import trayStyles from '@adobe/spectrum-css-temp/components/tray/vars.css';
21
22
  import {Underlay} from './Underlay';
22
- import {useModal, useOverlay, usePreventScroll} from '@react-aria/overlays';
23
+ import {useViewportSize} from '@react-aria/utils';
23
24
 
24
- interface TrayWrapperProps extends HTMLAttributes<HTMLElement> {
25
+ interface TrayProps extends AriaModalOverlayProps, StyleProps, OverlayProps {
25
26
  children: ReactNode,
26
- isOpen?: boolean,
27
- onClose?: () => void,
28
- isFixedHeight?: boolean,
29
- isNonModal?: boolean,
30
- overlayProps: HTMLAttributes<HTMLElement>
27
+ state: OverlayTriggerState,
28
+ isFixedHeight?: boolean
29
+ }
30
+
31
+ interface TrayWrapperProps extends TrayProps {
32
+ isOpen?: boolean
31
33
  }
32
34
 
33
35
  function Tray(props: TrayProps, ref: DOMRef<HTMLDivElement>) {
34
- let {children, onClose, isFixedHeight, isNonModal, ...otherProps} = props;
36
+ let {children, state, ...otherProps} = props;
35
37
  let domRef = useDOMRef(ref);
36
- let {styleProps} = useStyleProps(props);
37
-
38
- let {overlayProps, underlayProps} = useOverlay({...props, isDismissable: true}, domRef);
39
38
 
40
39
  return (
41
- <Overlay {...otherProps}>
42
- <Underlay {...underlayProps} />
43
- <TrayWrapper
44
- {...styleProps}
45
- onClose={onClose}
46
- ref={domRef}
47
- overlayProps={overlayProps}
48
- isFixedHeight={isFixedHeight}
49
- isNonModal={isNonModal}>
40
+ <Overlay {...otherProps} isOpen={state.isOpen}>
41
+ <TrayWrapper {...props} ref={domRef}>
50
42
  {children}
51
43
  </TrayWrapper>
52
44
  </Overlay>
@@ -58,14 +50,14 @@ let TrayWrapper = forwardRef(function (props: TrayWrapperProps, ref: RefObject<H
58
50
  children,
59
51
  isOpen,
60
52
  isFixedHeight,
61
- isNonModal,
62
- overlayProps,
63
- ...otherProps
53
+ state
64
54
  } = props;
65
- usePreventScroll();
66
- let {modalProps} = useModal({
67
- isDisabled: isNonModal
68
- });
55
+ let {styleProps} = useStyleProps(props);
56
+
57
+ let {modalProps, underlayProps} = useModalOverlay({
58
+ ...props,
59
+ isDismissable: true
60
+ }, state, ref);
69
61
 
70
62
  // We need to measure the window's height in JS rather than using percentages in CSS
71
63
  // so that contents (e.g. menu) can inherit the max-height properly. Using percentages
@@ -96,22 +88,25 @@ let TrayWrapper = forwardRef(function (props: TrayWrapperProps, ref: RefObject<H
96
88
  'spectrum-Tray',
97
89
  'react-spectrum-Tray'
98
90
  ),
99
- otherProps.className
91
+ styleProps.className
100
92
  );
101
93
 
102
- let domProps = mergeProps(otherProps, overlayProps);
103
-
104
94
  return (
105
- <div className={wrapperClassName} style={wrapperStyle}>
106
- <div
107
- {...domProps}
108
- {...modalProps}
109
- className={className}
110
- ref={ref}
111
- data-testid="tray">
112
- {children}
95
+ <>
96
+ <Underlay {...underlayProps} isOpen={isOpen} />
97
+ <div className={wrapperClassName} style={wrapperStyle}>
98
+ <div
99
+ {...styleProps}
100
+ {...modalProps}
101
+ className={className}
102
+ ref={ref}
103
+ data-testid="tray">
104
+ <DismissButton onDismiss={state.close} />
105
+ {children}
106
+ <DismissButton onDismiss={state.close} />
107
+ </div>
113
108
  </div>
114
- </div>
109
+ </>
115
110
  );
116
111
  });
117
112
 
package/src/Underlay.tsx CHANGED
@@ -15,11 +15,12 @@ import React from 'react';
15
15
  import underlayStyles from '@adobe/spectrum-css-temp/components/underlay/vars.css';
16
16
 
17
17
  interface UnderlayProps {
18
- isOpen?: boolean
18
+ isOpen?: boolean,
19
+ isTransparent?: boolean
19
20
  }
20
21
 
21
- export function Underlay({isOpen}: UnderlayProps) {
22
+ export function Underlay({isOpen, isTransparent}: UnderlayProps) {
22
23
  return (
23
- <div className={classNames(underlayStyles, 'spectrum-Underlay', {'is-open': isOpen})} />
24
+ <div className={classNames(underlayStyles, 'spectrum-Underlay', {'is-open': isOpen, 'spectrum-Underlay--transparent': isTransparent})} />
24
25
  );
25
26
  }