@atlaskit/popup 1.26.0 → 1.27.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/CHANGELOG.md CHANGED
@@ -1,5 +1,22 @@
1
1
  # @atlaskit/popup
2
2
 
3
+ ## 1.27.0
4
+
5
+ ### Minor Changes
6
+
7
+ - [#143323](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/143323)
8
+ [`4fdf6347eb506`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/4fdf6347eb506) -
9
+ Popup and compositional popup now take an xcss prop that can adjust the popup contents padding and
10
+ width.
11
+ - [#143323](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/pull-requests/143323)
12
+ [`4fdf6347eb506`](https://stash.atlassian.com/projects/CONFCLOUD/repos/confluence-frontend/commits/4fdf6347eb506) -
13
+ Popup and compositional popup now have a new appearance prop. Pass it "modal" to enable the popup
14
+ to appear as a modal on small viewports.
15
+
16
+ ### Patch Changes
17
+
18
+ - Updated dependencies
19
+
3
20
  ## 1.26.0
4
21
 
5
22
  ### Minor Changes
@@ -16,6 +16,7 @@ var _popper = require("@atlaskit/popper");
16
16
  var _portal = _interopRequireDefault(require("@atlaskit/portal"));
17
17
  var _constants = require("@atlaskit/theme/constants");
18
18
  var _popperWrapper = _interopRequireDefault(require("../popper-wrapper"));
19
+ var _useAppearance = require("../use-appearance");
19
20
  var _useGetMemoizedMergedTriggerRef = require("../use-get-memoized-merged-trigger-ref");
20
21
  function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
21
22
  function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != _typeof(e) && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
@@ -106,7 +107,10 @@ var defaultLayer = _constants.layers.layer();
106
107
  * It must be a child of the Popup component.
107
108
  */
108
109
  var PopupContent = exports.PopupContent = function PopupContent(_ref4) {
109
- var children = _ref4.children,
110
+ var xcss = _ref4.xcss,
111
+ _ref4$appearance = _ref4.appearance,
112
+ inAppearance = _ref4$appearance === void 0 ? 'default' : _ref4$appearance,
113
+ children = _ref4.children,
110
114
  boundary = _ref4.boundary,
111
115
  offset = _ref4.offset,
112
116
  strategy = _ref4.strategy,
@@ -126,7 +130,7 @@ var PopupContent = exports.PopupContent = function PopupContent(_ref4) {
126
130
  zIndex = _ref4$zIndex === void 0 ? defaultLayer : _ref4$zIndex,
127
131
  _ref4$shouldUseCaptur = _ref4.shouldUseCaptureOnOutsideClick,
128
132
  shouldUseCaptureOnOutsideClick = _ref4$shouldUseCaptur === void 0 ? false : _ref4$shouldUseCaptur,
129
- shouldRenderToParent = _ref4.shouldRenderToParent,
133
+ inShouldRenderToParent = _ref4.shouldRenderToParent,
130
134
  _ref4$shouldDisableFo = _ref4.shouldDisableFocusLock,
131
135
  shouldDisableFocusLock = _ref4$shouldDisableFo === void 0 ? false : _ref4$shouldDisableFo,
132
136
  shouldFitContainer = _ref4.shouldFitContainer,
@@ -135,12 +139,22 @@ var PopupContent = exports.PopupContent = function PopupContent(_ref4) {
135
139
  var isOpen = (0, _react.useContext)(IsOpenContext);
136
140
  var id = (0, _react.useContext)(IdContext);
137
141
  var triggerRef = (0, _react.useContext)(TriggerRefContext);
142
+ var _usePopupAppearance = (0, _useAppearance.usePopupAppearance)({
143
+ appearance: inAppearance,
144
+ shouldRenderToParent: inShouldRenderToParent
145
+ }),
146
+ appearance = _usePopupAppearance.appearance,
147
+ shouldRenderToParent = _usePopupAppearance.shouldRenderToParent;
138
148
  if (!isOpen) {
139
149
  return null;
140
150
  }
141
151
  var popperWrapper = /*#__PURE__*/_react.default.createElement(_layering.UNSAFE_LAYERING, {
142
152
  isDisabled: false
143
- }, /*#__PURE__*/_react.default.createElement(_popperWrapper.default, {
153
+ }, /*#__PURE__*/_react.default.createElement(_popperWrapper.default
154
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
155
+ , {
156
+ xcss: xcss,
157
+ appearance: appearance,
144
158
  content: children,
145
159
  isOpen: isOpen,
146
160
  placement: placement,
@@ -22,20 +22,19 @@ var _tokens = require("@atlaskit/tokens");
22
22
  var _repositionOnUpdate = require("./reposition-on-update");
23
23
  var _useCloseManager = require("./use-close-manager");
24
24
  var _useFocusManager = require("./use-focus-manager");
25
- var _excluded = ["shouldRenderToParent", "shouldFitContainer", "children"];
25
+ var _excluded = ["shouldRenderToParent", "shouldFitContainer", "children", "appearance", "xcss"];
26
26
  var _css;
27
27
  /**
28
28
  * @jsxRuntime classic
29
29
  * @jsx jsx
30
30
  */
31
- var popupFullWidthStyles = (0, _react2.css)({
31
+ var fullWidthStyles = (0, _react2.css)({
32
32
  width: '100%'
33
33
  });
34
- var popupStyles = (0, _react2.css)((_css = {
34
+ var rootStyles = (0, _react2.css)((_css = {
35
35
  display: 'block',
36
36
  boxSizing: 'border-box',
37
37
  zIndex: _constants.layers.layer(),
38
- flex: '1 1 auto',
39
38
  backgroundColor: "var(--ds-surface-overlay, ".concat(_colors.N0, ")"),
40
39
  borderRadius: "var(--ds-border-radius, 3px)",
41
40
  boxShadow: "var(--ds-shadow-overlay, ".concat("0 4px 8px -2px ".concat(_colors.N50A, ", 0 0 1px ").concat(_colors.N60A), ")"),
@@ -46,22 +45,39 @@ var popupStyles = (0, _react2.css)((_css = {
46
45
  }, (0, _defineProperty2.default)(_css, _tokens.CURRENT_SURFACE_CSS_VAR, "var(--ds-surface-overlay, ".concat(_colors.N0, ")")), (0, _defineProperty2.default)(_css, '&:focus', {
47
46
  outline: 'none'
48
47
  }), _css));
49
- var popupOverflowStyles = (0, _react2.css)({
48
+ var scrollableStyles = (0, _react2.css)({
50
49
  overflow: 'auto'
51
50
  });
51
+ var blanketStyles = (0, _react2.css)({
52
+ position: 'fixed',
53
+ inset: 0,
54
+ backgroundColor: "var(--ds-blanket, #091E427D)"
55
+ });
56
+ var modalStyles = (0, _react2.css)({
57
+ maxHeight: '50vh',
58
+ position: 'fixed',
59
+ insetBlockStart: "var(--ds-space-050, 4px)",
60
+ insetInline: "var(--ds-space-050, 4px)"
61
+ });
52
62
  var DefaultPopupComponent = /*#__PURE__*/(0, _react.forwardRef)(function (props, ref) {
53
63
  var shouldRenderToParent = props.shouldRenderToParent,
54
64
  shouldFitContainer = props.shouldFitContainer,
55
65
  children = props.children,
66
+ appearance = props.appearance,
67
+ xcss = props.xcss,
56
68
  htmlAttributes = (0, _objectWithoutProperties2.default)(props, _excluded);
57
69
  return (0, _react2.jsx)("div", (0, _extends2.default)({
58
- css: [popupStyles, !shouldRenderToParent && popupOverflowStyles, shouldFitContainer && popupFullWidthStyles]
70
+ // We suppress this for now as we can't use the Compiled pragma until this module has migrated to Compiled.
71
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @compiled/jsx-pragma
72
+ className: xcss,
73
+ css: [rootStyles, appearance === 'UNSAFE_modal-below-sm' && modalStyles, !shouldRenderToParent && scrollableStyles, shouldFitContainer && fullWidthStyles]
59
74
  }, htmlAttributes, {
60
75
  ref: ref
61
76
  }), children);
62
77
  });
63
78
  function PopperWrapper(_ref) {
64
- var isOpen = _ref.isOpen,
79
+ var xcss = _ref.xcss,
80
+ isOpen = _ref.isOpen,
65
81
  id = _ref.id,
66
82
  offset = _ref.offset,
67
83
  testId = _ref.testId,
@@ -89,7 +105,9 @@ function PopperWrapper(_ref) {
89
105
  label = _ref.label,
90
106
  titleId = _ref.titleId,
91
107
  modifiers = _ref.modifiers,
92
- shouldFitViewport = _ref.shouldFitViewport;
108
+ shouldFitViewport = _ref.shouldFitViewport,
109
+ _ref$appearance = _ref.appearance,
110
+ appearance = _ref$appearance === void 0 ? 'default' : _ref$appearance;
93
111
  var _useState = (0, _react.useState)(null),
94
112
  _useState2 = (0, _slicedToArray2.default)(_useState, 2),
95
113
  popupRef = _useState2[0],
@@ -98,9 +116,7 @@ function PopperWrapper(_ref) {
98
116
  _useState4 = (0, _slicedToArray2.default)(_useState3, 2),
99
117
  initialFocusRef = _useState4[0],
100
118
  setInitialFocusRef = _useState4[1];
101
-
102
- // We have cases where we need to close the Popup on Tab press.
103
- // Example: DropdownMenu
119
+ // We have cases where we need to close the Popup on Tab press, e.g. DropdownMenu
104
120
  var shouldCloseOnTab = shouldRenderToParent && shouldDisableFocusLock;
105
121
  var shouldDisableFocusTrap = role !== 'dialog';
106
122
  (0, _useFocusManager.useFocusManager)({
@@ -147,7 +163,11 @@ function PopperWrapper(_ref) {
147
163
  style = _ref2.style,
148
164
  placement = _ref2.placement,
149
165
  update = _ref2.update;
150
- var popupContainer = (0, _react2.jsx)(PopupContainer, {
166
+ var popupContainer = (0, _react2.jsx)(PopupContainer
167
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
168
+ , {
169
+ xcss: xcss,
170
+ appearance: appearance,
151
171
  id: id,
152
172
  "data-ds--level": currentLevel,
153
173
  "data-placement": placement,
@@ -167,7 +187,7 @@ function PopperWrapper(_ref) {
167
187
  }
168
188
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
169
189
  ,
170
- style: style
190
+ style: appearance === 'UNSAFE_modal-below-sm' ? {} : style
171
191
  // using tabIndex={-1} would cause a bug where Safari focuses
172
192
  // first on the browser address bar when using keyboard
173
193
  ,
@@ -182,7 +202,11 @@ function PopperWrapper(_ref) {
182
202
  onClose: onClose,
183
203
  setInitialFocusRef: setInitialFocusRef
184
204
  })));
185
- return !initialFocusRef && (0, _platformFeatureFlags.fg)('platform-design-system-apply-popup-wrapper-focus') ? (0, _react2.jsx)(_focusRing.default, null, popupContainer) : popupContainer;
205
+ return !initialFocusRef && (0, _platformFeatureFlags.fg)('platform-design-system-apply-popup-wrapper-focus') ? (0, _react2.jsx)(_react.Fragment, null, (0, _react2.jsx)(_focusRing.default, null, popupContainer), appearance === 'UNSAFE_modal-below-sm' && (0, _react2.jsx)("div", {
206
+ css: blanketStyles
207
+ })) : (0, _react2.jsx)(_react.Fragment, null, popupContainer, appearance === 'UNSAFE_modal-below-sm' && (0, _react2.jsx)("div", {
208
+ css: blanketStyles
209
+ }));
186
210
  });
187
211
  }
188
212
 
package/dist/cjs/popup.js CHANGED
@@ -16,6 +16,7 @@ var _portal = _interopRequireDefault(require("@atlaskit/portal"));
16
16
  var _primitives = require("@atlaskit/primitives");
17
17
  var _constants = require("@atlaskit/theme/constants");
18
18
  var _popperWrapper = _interopRequireDefault(require("./popper-wrapper"));
19
+ var _useAppearance = require("./use-appearance");
19
20
  var _useGetMemoizedMergedTriggerRef = require("./use-get-memoized-merged-trigger-ref");
20
21
  var _useGetMemoizedMergedTriggerRefNew = require("./use-get-memoized-merged-trigger-ref-new");
21
22
  /* eslint-disable @repo/internal/react/require-jsdoc */
@@ -31,7 +32,10 @@ var wrapperStyles = (0, _primitives.xcss)({
31
32
  position: 'relative'
32
33
  });
33
34
  var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
34
- var isOpen = _ref.isOpen,
35
+ var xcss = _ref.xcss,
36
+ _ref$appearance = _ref.appearance,
37
+ inAppearance = _ref$appearance === void 0 ? 'default' : _ref$appearance,
38
+ isOpen = _ref.isOpen,
35
39
  providedId = _ref.id,
36
40
  offset = _ref.offset,
37
41
  testId = _ref.testId,
@@ -54,7 +58,7 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
54
58
  _ref$shouldUseCapture = _ref.shouldUseCaptureOnOutsideClick,
55
59
  shouldUseCaptureOnOutsideClick = _ref$shouldUseCapture === void 0 ? false : _ref$shouldUseCapture,
56
60
  _ref$shouldRenderToPa = _ref.shouldRenderToParent,
57
- shouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
61
+ inShouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
58
62
  _ref$shouldFitContain = _ref.shouldFitContainer,
59
63
  shouldFitContainer = _ref$shouldFitContain === void 0 ? false : _ref$shouldFitContain,
60
64
  _ref$shouldDisableFoc = _ref.shouldDisableFocusLock,
@@ -74,10 +78,20 @@ var Popup = exports.Popup = /*#__PURE__*/(0, _react.memo)(function (_ref) {
74
78
  var getMergedTriggerRef = (0, _useGetMemoizedMergedTriggerRef.useGetMemoizedMergedTriggerRef)();
75
79
  var getMergedTriggerRefNew = (0, _useGetMemoizedMergedTriggerRefNew.useGetMemoizedMergedTriggerRefNew)();
76
80
  var generatedId = (0, _reactUid.useId)();
81
+ var _usePopupAppearance = (0, _useAppearance.usePopupAppearance)({
82
+ appearance: inAppearance,
83
+ shouldRenderToParent: inShouldRenderToParent
84
+ }),
85
+ appearance = _usePopupAppearance.appearance,
86
+ shouldRenderToParent = _usePopupAppearance.shouldRenderToParent;
77
87
  var id = providedId || generatedId;
78
88
  var renderPopperWrapper = (0, _react2.jsx)(_layering.UNSAFE_LAYERING, {
79
89
  isDisabled: false
80
- }, (0, _react2.jsx)(_popperWrapper.default, {
90
+ }, (0, _react2.jsx)(_popperWrapper.default
91
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
92
+ , {
93
+ xcss: xcss,
94
+ appearance: appearance,
81
95
  content: content,
82
96
  isOpen: isOpen,
83
97
  placement: placement,
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ Object.defineProperty(exports, "__esModule", {
5
+ value: true
6
+ });
7
+ exports.usePopupAppearance = usePopupAppearance;
8
+ var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray"));
9
+ var _react = require("react");
10
+ var _responsive = require("@atlaskit/primitives/responsive");
11
+ /**
12
+ * **usePopupAppearance()**
13
+ *
14
+ * Abstracts away calculating the appearance for a popup including if it should
15
+ * be portalled or not, this is done to ensure that if the popup needs to render
16
+ * as a modal that it is also forcibly portalled. If it's not portalled when rendering
17
+ * as a modal it will appear below the top bar.
18
+ */
19
+ function usePopupAppearance(_ref) {
20
+ var _appearance = _ref.appearance,
21
+ _shouldRenderToParent = _ref.shouldRenderToParent;
22
+ var mq = (0, _responsive.UNSAFE_useMediaQuery)('below.sm', function (e) {
23
+ setIsSmallViewport(!!e.matches);
24
+ });
25
+ var _useState = (0, _react.useState)(!!(mq !== null && mq !== void 0 && mq.matches)),
26
+ _useState2 = (0, _slicedToArray2.default)(_useState, 2),
27
+ isSmallViewport = _useState2[0],
28
+ setIsSmallViewport = _useState2[1];
29
+ var appearance = _appearance === 'UNSAFE_modal-below-sm' && isSmallViewport ? 'UNSAFE_modal-below-sm' : 'default';
30
+ var shouldRenderToParent = _shouldRenderToParent && appearance === 'default';
31
+ return {
32
+ appearance: appearance,
33
+ shouldRenderToParent: shouldRenderToParent
34
+ };
35
+ }
@@ -7,6 +7,7 @@ import { Manager, Reference } from '@atlaskit/popper';
7
7
  import Portal from '@atlaskit/portal';
8
8
  import { layers } from '@atlaskit/theme/constants';
9
9
  import PopperWrapper from '../popper-wrapper';
10
+ import { usePopupAppearance } from '../use-appearance';
10
11
  import { useGetMemoizedMergedTriggerRef } from '../use-get-memoized-merged-trigger-ref';
11
12
  const IsOpenContext = /*#__PURE__*/createContext(false);
12
13
  const IdContext = /*#__PURE__*/createContext(undefined);
@@ -92,6 +93,8 @@ const defaultLayer = layers.layer();
92
93
  * It must be a child of the Popup component.
93
94
  */
94
95
  export const PopupContent = ({
96
+ xcss,
97
+ appearance: inAppearance = 'default',
95
98
  children,
96
99
  boundary,
97
100
  offset,
@@ -106,7 +109,7 @@ export const PopupContent = ({
106
109
  autoFocus = true,
107
110
  zIndex = defaultLayer,
108
111
  shouldUseCaptureOnOutsideClick = false,
109
- shouldRenderToParent,
112
+ shouldRenderToParent: inShouldRenderToParent,
110
113
  shouldDisableFocusLock = false,
111
114
  shouldFitContainer,
112
115
  shouldFitViewport
@@ -115,12 +118,23 @@ export const PopupContent = ({
115
118
  const isOpen = useContext(IsOpenContext);
116
119
  const id = useContext(IdContext);
117
120
  const triggerRef = useContext(TriggerRefContext);
121
+ const {
122
+ appearance,
123
+ shouldRenderToParent
124
+ } = usePopupAppearance({
125
+ appearance: inAppearance,
126
+ shouldRenderToParent: inShouldRenderToParent
127
+ });
118
128
  if (!isOpen) {
119
129
  return null;
120
130
  }
121
131
  const popperWrapper = /*#__PURE__*/React.createElement(UNSAFE_LAYERING, {
122
132
  isDisabled: false
123
- }, /*#__PURE__*/React.createElement(PopperWrapper, {
133
+ }, /*#__PURE__*/React.createElement(PopperWrapper
134
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
135
+ , {
136
+ xcss: xcss,
137
+ appearance: appearance,
124
138
  content: children,
125
139
  isOpen: isOpen,
126
140
  placement: placement,
@@ -3,7 +3,7 @@ import _extends from "@babel/runtime/helpers/extends";
3
3
  * @jsxRuntime classic
4
4
  * @jsx jsx
5
5
  */
6
- import { forwardRef, useMemo, useState } from 'react';
6
+ import { forwardRef, Fragment, useMemo, useState } from 'react';
7
7
  import { css, jsx } from '@emotion/react';
8
8
  import FocusRing from '@atlaskit/focus-ring';
9
9
  import { UNSAFE_useLayering } from '@atlaskit/layering';
@@ -15,14 +15,13 @@ import { CURRENT_SURFACE_CSS_VAR } from '@atlaskit/tokens';
15
15
  import { RepositionOnUpdate } from './reposition-on-update';
16
16
  import { useCloseManager } from './use-close-manager';
17
17
  import { useFocusManager } from './use-focus-manager';
18
- const popupFullWidthStyles = css({
18
+ const fullWidthStyles = css({
19
19
  width: '100%'
20
20
  });
21
- const popupStyles = css({
21
+ const rootStyles = css({
22
22
  display: 'block',
23
23
  boxSizing: 'border-box',
24
24
  zIndex: layers.layer(),
25
- flex: '1 1 auto',
26
25
  backgroundColor: `var(--ds-surface-overlay, ${N0})`,
27
26
  borderRadius: "var(--ds-border-radius, 3px)",
28
27
  boxShadow: `var(--ds-shadow-overlay, ${`0 4px 8px -2px ${N50A}, 0 0 1px ${N60A}`})`,
@@ -35,23 +34,40 @@ const popupStyles = css({
35
34
  outline: 'none'
36
35
  }
37
36
  });
38
- const popupOverflowStyles = css({
37
+ const scrollableStyles = css({
39
38
  overflow: 'auto'
40
39
  });
40
+ const blanketStyles = css({
41
+ position: 'fixed',
42
+ inset: 0,
43
+ backgroundColor: "var(--ds-blanket, #091E427D)"
44
+ });
45
+ const modalStyles = css({
46
+ maxHeight: '50vh',
47
+ position: 'fixed',
48
+ insetBlockStart: "var(--ds-space-050, 4px)",
49
+ insetInline: "var(--ds-space-050, 4px)"
50
+ });
41
51
  const DefaultPopupComponent = /*#__PURE__*/forwardRef((props, ref) => {
42
52
  const {
43
53
  shouldRenderToParent,
44
54
  shouldFitContainer,
45
55
  children,
56
+ appearance,
57
+ xcss,
46
58
  ...htmlAttributes
47
59
  } = props;
48
60
  return jsx("div", _extends({
49
- css: [popupStyles, !shouldRenderToParent && popupOverflowStyles, shouldFitContainer && popupFullWidthStyles]
61
+ // We suppress this for now as we can't use the Compiled pragma until this module has migrated to Compiled.
62
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @compiled/jsx-pragma
63
+ className: xcss,
64
+ css: [rootStyles, appearance === 'UNSAFE_modal-below-sm' && modalStyles, !shouldRenderToParent && scrollableStyles, shouldFitContainer && fullWidthStyles]
50
65
  }, htmlAttributes, {
51
66
  ref: ref
52
67
  }), children);
53
68
  });
54
69
  function PopperWrapper({
70
+ xcss,
55
71
  isOpen,
56
72
  id,
57
73
  offset,
@@ -77,13 +93,12 @@ function PopperWrapper({
77
93
  label,
78
94
  titleId,
79
95
  modifiers,
80
- shouldFitViewport
96
+ shouldFitViewport,
97
+ appearance = 'default'
81
98
  }) {
82
99
  const [popupRef, setPopupRef] = useState(null);
83
100
  const [initialFocusRef, setInitialFocusRef] = useState(null);
84
-
85
- // We have cases where we need to close the Popup on Tab press.
86
- // Example: DropdownMenu
101
+ // We have cases where we need to close the Popup on Tab press, e.g. DropdownMenu
87
102
  const shouldCloseOnTab = shouldRenderToParent && shouldDisableFocusLock;
88
103
  const shouldDisableFocusTrap = role !== 'dialog';
89
104
  useFocusManager({
@@ -130,7 +145,11 @@ function PopperWrapper({
130
145
  placement,
131
146
  update
132
147
  }) => {
133
- const popupContainer = jsx(PopupContainer, {
148
+ const popupContainer = jsx(PopupContainer
149
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
150
+ , {
151
+ xcss: xcss,
152
+ appearance: appearance,
134
153
  id: id,
135
154
  "data-ds--level": currentLevel,
136
155
  "data-placement": placement,
@@ -150,7 +169,7 @@ function PopperWrapper({
150
169
  }
151
170
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
152
171
  ,
153
- style: style
172
+ style: appearance === 'UNSAFE_modal-below-sm' ? {} : style
154
173
  // using tabIndex={-1} would cause a bug where Safari focuses
155
174
  // first on the browser address bar when using keyboard
156
175
  ,
@@ -165,7 +184,11 @@ function PopperWrapper({
165
184
  onClose,
166
185
  setInitialFocusRef
167
186
  })));
168
- return !initialFocusRef && fg('platform-design-system-apply-popup-wrapper-focus') ? jsx(FocusRing, null, popupContainer) : popupContainer;
187
+ return !initialFocusRef && fg('platform-design-system-apply-popup-wrapper-focus') ? jsx(Fragment, null, jsx(FocusRing, null, popupContainer), appearance === 'UNSAFE_modal-below-sm' && jsx("div", {
188
+ css: blanketStyles
189
+ })) : jsx(Fragment, null, popupContainer, appearance === 'UNSAFE_modal-below-sm' && jsx("div", {
190
+ css: blanketStyles
191
+ }));
169
192
  });
170
193
  }
171
194
 
@@ -15,6 +15,7 @@ import Portal from '@atlaskit/portal';
15
15
  import { Box, xcss } from '@atlaskit/primitives';
16
16
  import { layers } from '@atlaskit/theme/constants';
17
17
  import PopperWrapper from './popper-wrapper';
18
+ import { usePopupAppearance } from './use-appearance';
18
19
  import { useGetMemoizedMergedTriggerRef } from './use-get-memoized-merged-trigger-ref';
19
20
  import { useGetMemoizedMergedTriggerRefNew } from './use-get-memoized-merged-trigger-ref-new';
20
21
  const defaultLayer = layers.layer();
@@ -22,6 +23,8 @@ const wrapperStyles = xcss({
22
23
  position: 'relative'
23
24
  });
24
25
  export const Popup = /*#__PURE__*/memo(({
26
+ xcss,
27
+ appearance: inAppearance = 'default',
25
28
  isOpen,
26
29
  id: providedId,
27
30
  offset,
@@ -38,7 +41,7 @@ export const Popup = /*#__PURE__*/memo(({
38
41
  autoFocus = true,
39
42
  zIndex = defaultLayer,
40
43
  shouldUseCaptureOnOutsideClick = false,
41
- shouldRenderToParent = false,
44
+ shouldRenderToParent: inShouldRenderToParent = false,
42
45
  shouldFitContainer = false,
43
46
  shouldDisableFocusLock = false,
44
47
  shouldReturnFocus = true,
@@ -53,10 +56,21 @@ export const Popup = /*#__PURE__*/memo(({
53
56
  const getMergedTriggerRef = useGetMemoizedMergedTriggerRef();
54
57
  const getMergedTriggerRefNew = useGetMemoizedMergedTriggerRefNew();
55
58
  const generatedId = useId();
59
+ const {
60
+ appearance,
61
+ shouldRenderToParent
62
+ } = usePopupAppearance({
63
+ appearance: inAppearance,
64
+ shouldRenderToParent: inShouldRenderToParent
65
+ });
56
66
  const id = providedId || generatedId;
57
67
  const renderPopperWrapper = jsx(UNSAFE_LAYERING, {
58
68
  isDisabled: false
59
- }, jsx(PopperWrapper, {
69
+ }, jsx(PopperWrapper
70
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
71
+ , {
72
+ xcss: xcss,
73
+ appearance: appearance,
60
74
  content: content,
61
75
  isOpen: isOpen,
62
76
  placement: placement,
@@ -0,0 +1,26 @@
1
+ import { useState } from 'react';
2
+ import { UNSAFE_useMediaQuery as useMediaQuery } from '@atlaskit/primitives/responsive';
3
+
4
+ /**
5
+ * **usePopupAppearance()**
6
+ *
7
+ * Abstracts away calculating the appearance for a popup including if it should
8
+ * be portalled or not, this is done to ensure that if the popup needs to render
9
+ * as a modal that it is also forcibly portalled. If it's not portalled when rendering
10
+ * as a modal it will appear below the top bar.
11
+ */
12
+ export function usePopupAppearance({
13
+ appearance: _appearance,
14
+ shouldRenderToParent: _shouldRenderToParent
15
+ }) {
16
+ const mq = useMediaQuery('below.sm', e => {
17
+ setIsSmallViewport(!!e.matches);
18
+ });
19
+ const [isSmallViewport, setIsSmallViewport] = useState(!!(mq !== null && mq !== void 0 && mq.matches));
20
+ const appearance = _appearance === 'UNSAFE_modal-below-sm' && isSmallViewport ? 'UNSAFE_modal-below-sm' : 'default';
21
+ const shouldRenderToParent = _shouldRenderToParent && appearance === 'default';
22
+ return {
23
+ appearance,
24
+ shouldRenderToParent
25
+ };
26
+ }
@@ -8,6 +8,7 @@ import { Manager, Reference } from '@atlaskit/popper';
8
8
  import Portal from '@atlaskit/portal';
9
9
  import { layers } from '@atlaskit/theme/constants';
10
10
  import PopperWrapper from '../popper-wrapper';
11
+ import { usePopupAppearance } from '../use-appearance';
11
12
  import { useGetMemoizedMergedTriggerRef } from '../use-get-memoized-merged-trigger-ref';
12
13
  var IsOpenContext = /*#__PURE__*/createContext(false);
13
14
  var IdContext = /*#__PURE__*/createContext(undefined);
@@ -96,7 +97,10 @@ var defaultLayer = layers.layer();
96
97
  * It must be a child of the Popup component.
97
98
  */
98
99
  export var PopupContent = function PopupContent(_ref4) {
99
- var children = _ref4.children,
100
+ var xcss = _ref4.xcss,
101
+ _ref4$appearance = _ref4.appearance,
102
+ inAppearance = _ref4$appearance === void 0 ? 'default' : _ref4$appearance,
103
+ children = _ref4.children,
100
104
  boundary = _ref4.boundary,
101
105
  offset = _ref4.offset,
102
106
  strategy = _ref4.strategy,
@@ -116,7 +120,7 @@ export var PopupContent = function PopupContent(_ref4) {
116
120
  zIndex = _ref4$zIndex === void 0 ? defaultLayer : _ref4$zIndex,
117
121
  _ref4$shouldUseCaptur = _ref4.shouldUseCaptureOnOutsideClick,
118
122
  shouldUseCaptureOnOutsideClick = _ref4$shouldUseCaptur === void 0 ? false : _ref4$shouldUseCaptur,
119
- shouldRenderToParent = _ref4.shouldRenderToParent,
123
+ inShouldRenderToParent = _ref4.shouldRenderToParent,
120
124
  _ref4$shouldDisableFo = _ref4.shouldDisableFocusLock,
121
125
  shouldDisableFocusLock = _ref4$shouldDisableFo === void 0 ? false : _ref4$shouldDisableFo,
122
126
  shouldFitContainer = _ref4.shouldFitContainer,
@@ -125,12 +129,22 @@ export var PopupContent = function PopupContent(_ref4) {
125
129
  var isOpen = useContext(IsOpenContext);
126
130
  var id = useContext(IdContext);
127
131
  var triggerRef = useContext(TriggerRefContext);
132
+ var _usePopupAppearance = usePopupAppearance({
133
+ appearance: inAppearance,
134
+ shouldRenderToParent: inShouldRenderToParent
135
+ }),
136
+ appearance = _usePopupAppearance.appearance,
137
+ shouldRenderToParent = _usePopupAppearance.shouldRenderToParent;
128
138
  if (!isOpen) {
129
139
  return null;
130
140
  }
131
141
  var popperWrapper = /*#__PURE__*/React.createElement(UNSAFE_LAYERING, {
132
142
  isDisabled: false
133
- }, /*#__PURE__*/React.createElement(PopperWrapper, {
143
+ }, /*#__PURE__*/React.createElement(PopperWrapper
144
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
145
+ , {
146
+ xcss: xcss,
147
+ appearance: appearance,
134
148
  content: children,
135
149
  isOpen: isOpen,
136
150
  placement: placement,
@@ -3,13 +3,13 @@ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
3
3
  import _extends from "@babel/runtime/helpers/extends";
4
4
  import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProperties";
5
5
  import _defineProperty from "@babel/runtime/helpers/defineProperty";
6
- var _excluded = ["shouldRenderToParent", "shouldFitContainer", "children"];
6
+ var _excluded = ["shouldRenderToParent", "shouldFitContainer", "children", "appearance", "xcss"];
7
7
  var _css;
8
8
  /**
9
9
  * @jsxRuntime classic
10
10
  * @jsx jsx
11
11
  */
12
- import { forwardRef, useMemo, useState } from 'react';
12
+ import { forwardRef, Fragment, useMemo, useState } from 'react';
13
13
  import { css, jsx } from '@emotion/react';
14
14
  import FocusRing from '@atlaskit/focus-ring';
15
15
  import { UNSAFE_useLayering } from '@atlaskit/layering';
@@ -21,14 +21,13 @@ import { CURRENT_SURFACE_CSS_VAR } from '@atlaskit/tokens';
21
21
  import { RepositionOnUpdate } from './reposition-on-update';
22
22
  import { useCloseManager } from './use-close-manager';
23
23
  import { useFocusManager } from './use-focus-manager';
24
- var popupFullWidthStyles = css({
24
+ var fullWidthStyles = css({
25
25
  width: '100%'
26
26
  });
27
- var popupStyles = css((_css = {
27
+ var rootStyles = css((_css = {
28
28
  display: 'block',
29
29
  boxSizing: 'border-box',
30
30
  zIndex: layers.layer(),
31
- flex: '1 1 auto',
32
31
  backgroundColor: "var(--ds-surface-overlay, ".concat(N0, ")"),
33
32
  borderRadius: "var(--ds-border-radius, 3px)",
34
33
  boxShadow: "var(--ds-shadow-overlay, ".concat("0 4px 8px -2px ".concat(N50A, ", 0 0 1px ").concat(N60A), ")"),
@@ -39,22 +38,39 @@ var popupStyles = css((_css = {
39
38
  }, _defineProperty(_css, CURRENT_SURFACE_CSS_VAR, "var(--ds-surface-overlay, ".concat(N0, ")")), _defineProperty(_css, '&:focus', {
40
39
  outline: 'none'
41
40
  }), _css));
42
- var popupOverflowStyles = css({
41
+ var scrollableStyles = css({
43
42
  overflow: 'auto'
44
43
  });
44
+ var blanketStyles = css({
45
+ position: 'fixed',
46
+ inset: 0,
47
+ backgroundColor: "var(--ds-blanket, #091E427D)"
48
+ });
49
+ var modalStyles = css({
50
+ maxHeight: '50vh',
51
+ position: 'fixed',
52
+ insetBlockStart: "var(--ds-space-050, 4px)",
53
+ insetInline: "var(--ds-space-050, 4px)"
54
+ });
45
55
  var DefaultPopupComponent = /*#__PURE__*/forwardRef(function (props, ref) {
46
56
  var shouldRenderToParent = props.shouldRenderToParent,
47
57
  shouldFitContainer = props.shouldFitContainer,
48
58
  children = props.children,
59
+ appearance = props.appearance,
60
+ xcss = props.xcss,
49
61
  htmlAttributes = _objectWithoutProperties(props, _excluded);
50
62
  return jsx("div", _extends({
51
- css: [popupStyles, !shouldRenderToParent && popupOverflowStyles, shouldFitContainer && popupFullWidthStyles]
63
+ // We suppress this for now as we can't use the Compiled pragma until this module has migrated to Compiled.
64
+ // eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop, @compiled/jsx-pragma
65
+ className: xcss,
66
+ css: [rootStyles, appearance === 'UNSAFE_modal-below-sm' && modalStyles, !shouldRenderToParent && scrollableStyles, shouldFitContainer && fullWidthStyles]
52
67
  }, htmlAttributes, {
53
68
  ref: ref
54
69
  }), children);
55
70
  });
56
71
  function PopperWrapper(_ref) {
57
- var isOpen = _ref.isOpen,
72
+ var xcss = _ref.xcss,
73
+ isOpen = _ref.isOpen,
58
74
  id = _ref.id,
59
75
  offset = _ref.offset,
60
76
  testId = _ref.testId,
@@ -82,7 +98,9 @@ function PopperWrapper(_ref) {
82
98
  label = _ref.label,
83
99
  titleId = _ref.titleId,
84
100
  modifiers = _ref.modifiers,
85
- shouldFitViewport = _ref.shouldFitViewport;
101
+ shouldFitViewport = _ref.shouldFitViewport,
102
+ _ref$appearance = _ref.appearance,
103
+ appearance = _ref$appearance === void 0 ? 'default' : _ref$appearance;
86
104
  var _useState = useState(null),
87
105
  _useState2 = _slicedToArray(_useState, 2),
88
106
  popupRef = _useState2[0],
@@ -91,9 +109,7 @@ function PopperWrapper(_ref) {
91
109
  _useState4 = _slicedToArray(_useState3, 2),
92
110
  initialFocusRef = _useState4[0],
93
111
  setInitialFocusRef = _useState4[1];
94
-
95
- // We have cases where we need to close the Popup on Tab press.
96
- // Example: DropdownMenu
112
+ // We have cases where we need to close the Popup on Tab press, e.g. DropdownMenu
97
113
  var shouldCloseOnTab = shouldRenderToParent && shouldDisableFocusLock;
98
114
  var shouldDisableFocusTrap = role !== 'dialog';
99
115
  useFocusManager({
@@ -140,7 +156,11 @@ function PopperWrapper(_ref) {
140
156
  style = _ref2.style,
141
157
  placement = _ref2.placement,
142
158
  update = _ref2.update;
143
- var popupContainer = jsx(PopupContainer, {
159
+ var popupContainer = jsx(PopupContainer
160
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
161
+ , {
162
+ xcss: xcss,
163
+ appearance: appearance,
144
164
  id: id,
145
165
  "data-ds--level": currentLevel,
146
166
  "data-placement": placement,
@@ -160,7 +180,7 @@ function PopperWrapper(_ref) {
160
180
  }
161
181
  // eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
162
182
  ,
163
- style: style
183
+ style: appearance === 'UNSAFE_modal-below-sm' ? {} : style
164
184
  // using tabIndex={-1} would cause a bug where Safari focuses
165
185
  // first on the browser address bar when using keyboard
166
186
  ,
@@ -175,7 +195,11 @@ function PopperWrapper(_ref) {
175
195
  onClose: onClose,
176
196
  setInitialFocusRef: setInitialFocusRef
177
197
  })));
178
- return !initialFocusRef && fg('platform-design-system-apply-popup-wrapper-focus') ? jsx(FocusRing, null, popupContainer) : popupContainer;
198
+ return !initialFocusRef && fg('platform-design-system-apply-popup-wrapper-focus') ? jsx(Fragment, null, jsx(FocusRing, null, popupContainer), appearance === 'UNSAFE_modal-below-sm' && jsx("div", {
199
+ css: blanketStyles
200
+ })) : jsx(Fragment, null, popupContainer, appearance === 'UNSAFE_modal-below-sm' && jsx("div", {
201
+ css: blanketStyles
202
+ }));
179
203
  });
180
204
  }
181
205
 
package/dist/esm/popup.js CHANGED
@@ -16,6 +16,7 @@ import Portal from '@atlaskit/portal';
16
16
  import { Box, xcss } from '@atlaskit/primitives';
17
17
  import { layers } from '@atlaskit/theme/constants';
18
18
  import PopperWrapper from './popper-wrapper';
19
+ import { usePopupAppearance } from './use-appearance';
19
20
  import { useGetMemoizedMergedTriggerRef } from './use-get-memoized-merged-trigger-ref';
20
21
  import { useGetMemoizedMergedTriggerRefNew } from './use-get-memoized-merged-trigger-ref-new';
21
22
  var defaultLayer = layers.layer();
@@ -23,7 +24,10 @@ var wrapperStyles = xcss({
23
24
  position: 'relative'
24
25
  });
25
26
  export var Popup = /*#__PURE__*/memo(function (_ref) {
26
- var isOpen = _ref.isOpen,
27
+ var xcss = _ref.xcss,
28
+ _ref$appearance = _ref.appearance,
29
+ inAppearance = _ref$appearance === void 0 ? 'default' : _ref$appearance,
30
+ isOpen = _ref.isOpen,
27
31
  providedId = _ref.id,
28
32
  offset = _ref.offset,
29
33
  testId = _ref.testId,
@@ -46,7 +50,7 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
46
50
  _ref$shouldUseCapture = _ref.shouldUseCaptureOnOutsideClick,
47
51
  shouldUseCaptureOnOutsideClick = _ref$shouldUseCapture === void 0 ? false : _ref$shouldUseCapture,
48
52
  _ref$shouldRenderToPa = _ref.shouldRenderToParent,
49
- shouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
53
+ inShouldRenderToParent = _ref$shouldRenderToPa === void 0 ? false : _ref$shouldRenderToPa,
50
54
  _ref$shouldFitContain = _ref.shouldFitContainer,
51
55
  shouldFitContainer = _ref$shouldFitContain === void 0 ? false : _ref$shouldFitContain,
52
56
  _ref$shouldDisableFoc = _ref.shouldDisableFocusLock,
@@ -66,10 +70,20 @@ export var Popup = /*#__PURE__*/memo(function (_ref) {
66
70
  var getMergedTriggerRef = useGetMemoizedMergedTriggerRef();
67
71
  var getMergedTriggerRefNew = useGetMemoizedMergedTriggerRefNew();
68
72
  var generatedId = useId();
73
+ var _usePopupAppearance = usePopupAppearance({
74
+ appearance: inAppearance,
75
+ shouldRenderToParent: inShouldRenderToParent
76
+ }),
77
+ appearance = _usePopupAppearance.appearance,
78
+ shouldRenderToParent = _usePopupAppearance.shouldRenderToParent;
69
79
  var id = providedId || generatedId;
70
80
  var renderPopperWrapper = jsx(UNSAFE_LAYERING, {
71
81
  isDisabled: false
72
- }, jsx(PopperWrapper, {
82
+ }, jsx(PopperWrapper
83
+ // eslint-disable-next-line @atlaskit/design-system/consistent-css-prop-usage
84
+ , {
85
+ xcss: xcss,
86
+ appearance: appearance,
73
87
  content: content,
74
88
  isOpen: isOpen,
75
89
  placement: placement,
@@ -0,0 +1,29 @@
1
+ import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
2
+ import { useState } from 'react';
3
+ import { UNSAFE_useMediaQuery as useMediaQuery } from '@atlaskit/primitives/responsive';
4
+
5
+ /**
6
+ * **usePopupAppearance()**
7
+ *
8
+ * Abstracts away calculating the appearance for a popup including if it should
9
+ * be portalled or not, this is done to ensure that if the popup needs to render
10
+ * as a modal that it is also forcibly portalled. If it's not portalled when rendering
11
+ * as a modal it will appear below the top bar.
12
+ */
13
+ export function usePopupAppearance(_ref) {
14
+ var _appearance = _ref.appearance,
15
+ _shouldRenderToParent = _ref.shouldRenderToParent;
16
+ var mq = useMediaQuery('below.sm', function (e) {
17
+ setIsSmallViewport(!!e.matches);
18
+ });
19
+ var _useState = useState(!!(mq !== null && mq !== void 0 && mq.matches)),
20
+ _useState2 = _slicedToArray(_useState, 2),
21
+ isSmallViewport = _useState2[0],
22
+ setIsSmallViewport = _useState2[1];
23
+ var appearance = _appearance === 'UNSAFE_modal-below-sm' && isSmallViewport ? 'UNSAFE_modal-below-sm' : 'default';
24
+ var shouldRenderToParent = _shouldRenderToParent && appearance === 'default';
25
+ return {
26
+ appearance: appearance,
27
+ shouldRenderToParent: shouldRenderToParent
28
+ };
29
+ }
@@ -36,7 +36,7 @@ export type PopupTriggerProps = {
36
36
  * It must be a child of the Popup component.
37
37
  */
38
38
  export declare const PopupTrigger: ({ children }: PopupTriggerProps) => JSX.Element;
39
- type CommonContentPopupProps = Pick<LegacyPopupProps, 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport'> & {
39
+ type CommonContentPopupProps = Pick<LegacyPopupProps, 'xcss' | 'appearance' | 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport'> & {
40
40
  children: (props: ContentProps) => React.ReactNode;
41
41
  };
42
42
  type ShouldFitContainerContentPopupProps = CommonContentPopupProps & {
@@ -55,5 +55,5 @@ export type PopupContentProps = ShouldFitContainerContentPopupProps | StandardPo
55
55
  *
56
56
  * It must be a child of the Popup component.
57
57
  */
58
- export declare const PopupContent: ({ children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, }: PopupContentProps) => JSX.Element | null;
58
+ export declare const PopupContent: ({ xcss, appearance: inAppearance, children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent: inShouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, }: PopupContentProps) => JSX.Element | null;
59
59
  export {};
@@ -1,4 +1,4 @@
1
1
  import { jsx } from '@emotion/react';
2
2
  import { type PopperWrapperProps } from './types';
3
- declare function PopperWrapper({ isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldFitContainer, shouldDisableFocusLock, shouldReturnFocus, strategy, role, label, titleId, modifiers, shouldFitViewport, }: PopperWrapperProps): jsx.JSX.Element;
3
+ declare function PopperWrapper({ xcss, isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldFitContainer, shouldDisableFocusLock, shouldReturnFocus, strategy, role, label, titleId, modifiers, shouldFitViewport, appearance, }: PopperWrapperProps): jsx.JSX.Element;
4
4
  export default PopperWrapper;
@@ -1,4 +1,5 @@
1
1
  import { type ComponentType, type CSSProperties, type Dispatch, type PropsWithChildren, type default as React, type ReactNode, type Ref, type SetStateAction } from 'react';
2
+ import { type StrictXCSSProp } from '@atlaskit/css';
2
3
  import { type Modifier, type Placement, type PopperChildrenProps } from '@atlaskit/popper';
3
4
  export interface TriggerProps {
4
5
  ref: Ref<any>;
@@ -53,6 +54,7 @@ export interface PopupComponentProps {
53
54
  * Style that should be assigned to the root element.
54
55
  */
55
56
  style: CSSProperties;
57
+ xcss?: StrictXCSSProp<'padding' | 'paddingInline' | 'paddingBlock' | 'width', never>;
56
58
  /**
57
59
  * Tab index passed through by the parent popup.
58
60
  */
@@ -69,6 +71,11 @@ export interface PopupComponentProps {
69
71
  * The default is `false`.
70
72
  */
71
73
  shouldFitContainer?: boolean;
74
+ /**
75
+ * The "default" appearance is used for standard popups.
76
+ * The "UNSAFE_modal-below-sm" appearance makes the popup appear as a modal when the viewport is smaller than "sm".
77
+ */
78
+ appearance?: 'default' | 'UNSAFE_modal-below-sm';
72
79
  /**
73
80
  * Use this to set the accessibility role for the popup.
74
81
  * We strongly recommend using only `menu` or `dialog`.
@@ -76,6 +83,12 @@ export interface PopupComponentProps {
76
83
  role?: string;
77
84
  }
78
85
  interface BaseProps {
86
+ /**
87
+ * The "default" appearance is used for standard popups.
88
+ * The "UNSAFE_modal-below-sm" appearance makes the popup appear as a modal when the viewport is smaller than "sm".
89
+ */
90
+ appearance?: 'default' | 'UNSAFE_modal-below-sm';
91
+ xcss?: StrictXCSSProp<'padding' | 'paddingInline' | 'paddingBlock' | 'width', never>;
79
92
  /**
80
93
  * Use this to either show or hide the popup.
81
94
  * When set to `false` the popup will not render anything to the DOM.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * **usePopupAppearance()**
3
+ *
4
+ * Abstracts away calculating the appearance for a popup including if it should
5
+ * be portalled or not, this is done to ensure that if the popup needs to render
6
+ * as a modal that it is also forcibly portalled. If it's not portalled when rendering
7
+ * as a modal it will appear below the top bar.
8
+ */
9
+ export declare function usePopupAppearance({ appearance: _appearance, shouldRenderToParent: _shouldRenderToParent, }: {
10
+ appearance: 'default' | 'UNSAFE_modal-below-sm';
11
+ shouldRenderToParent?: boolean;
12
+ }): {
13
+ appearance: "default" | "UNSAFE_modal-below-sm";
14
+ shouldRenderToParent: boolean | undefined;
15
+ };
@@ -36,7 +36,7 @@ export type PopupTriggerProps = {
36
36
  * It must be a child of the Popup component.
37
37
  */
38
38
  export declare const PopupTrigger: ({ children }: PopupTriggerProps) => JSX.Element;
39
- type CommonContentPopupProps = Pick<LegacyPopupProps, 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport'> & {
39
+ type CommonContentPopupProps = Pick<LegacyPopupProps, 'xcss' | 'appearance' | 'boundary' | 'offset' | 'onClose' | 'testId' | 'placement' | 'fallbackPlacements' | 'popupComponent' | 'shouldFlip' | 'rootBoundary' | 'autoFocus' | 'shouldRenderToParent' | 'shouldUseCaptureOnOutsideClick' | 'shouldDisableFocusLock' | 'strategy' | 'zIndex' | 'shouldFitViewport'> & {
40
40
  children: (props: ContentProps) => React.ReactNode;
41
41
  };
42
42
  type ShouldFitContainerContentPopupProps = CommonContentPopupProps & {
@@ -55,5 +55,5 @@ export type PopupContentProps = ShouldFitContainerContentPopupProps | StandardPo
55
55
  *
56
56
  * It must be a child of the Popup component.
57
57
  */
58
- export declare const PopupContent: ({ children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, }: PopupContentProps) => JSX.Element | null;
58
+ export declare const PopupContent: ({ xcss, appearance: inAppearance, children, boundary, offset, strategy, onClose, testId, rootBoundary, shouldFlip, placement, fallbackPlacements, popupComponent, autoFocus, zIndex, shouldUseCaptureOnOutsideClick, shouldRenderToParent: inShouldRenderToParent, shouldDisableFocusLock, shouldFitContainer, shouldFitViewport, }: PopupContentProps) => JSX.Element | null;
59
59
  export {};
@@ -1,4 +1,4 @@
1
1
  import { jsx } from '@emotion/react';
2
2
  import { type PopperWrapperProps } from './types';
3
- declare function PopperWrapper({ isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldFitContainer, shouldDisableFocusLock, shouldReturnFocus, strategy, role, label, titleId, modifiers, shouldFitViewport, }: PopperWrapperProps): jsx.JSX.Element;
3
+ declare function PopperWrapper({ xcss, isOpen, id, offset, testId, content, fallbackPlacements, onClose, boundary, rootBoundary, shouldFlip, placement, popupComponent: PopupContainer, autoFocus, triggerRef, shouldUseCaptureOnOutsideClick, shouldRenderToParent, shouldFitContainer, shouldDisableFocusLock, shouldReturnFocus, strategy, role, label, titleId, modifiers, shouldFitViewport, appearance, }: PopperWrapperProps): jsx.JSX.Element;
4
4
  export default PopperWrapper;
@@ -1,4 +1,5 @@
1
1
  import { type ComponentType, type CSSProperties, type Dispatch, type PropsWithChildren, type default as React, type ReactNode, type Ref, type SetStateAction } from 'react';
2
+ import { type StrictXCSSProp } from '@atlaskit/css';
2
3
  import { type Modifier, type Placement, type PopperChildrenProps } from '@atlaskit/popper';
3
4
  export interface TriggerProps {
4
5
  ref: Ref<any>;
@@ -53,6 +54,7 @@ export interface PopupComponentProps {
53
54
  * Style that should be assigned to the root element.
54
55
  */
55
56
  style: CSSProperties;
57
+ xcss?: StrictXCSSProp<'padding' | 'paddingInline' | 'paddingBlock' | 'width', never>;
56
58
  /**
57
59
  * Tab index passed through by the parent popup.
58
60
  */
@@ -69,6 +71,11 @@ export interface PopupComponentProps {
69
71
  * The default is `false`.
70
72
  */
71
73
  shouldFitContainer?: boolean;
74
+ /**
75
+ * The "default" appearance is used for standard popups.
76
+ * The "UNSAFE_modal-below-sm" appearance makes the popup appear as a modal when the viewport is smaller than "sm".
77
+ */
78
+ appearance?: 'default' | 'UNSAFE_modal-below-sm';
72
79
  /**
73
80
  * Use this to set the accessibility role for the popup.
74
81
  * We strongly recommend using only `menu` or `dialog`.
@@ -76,6 +83,12 @@ export interface PopupComponentProps {
76
83
  role?: string;
77
84
  }
78
85
  interface BaseProps {
86
+ /**
87
+ * The "default" appearance is used for standard popups.
88
+ * The "UNSAFE_modal-below-sm" appearance makes the popup appear as a modal when the viewport is smaller than "sm".
89
+ */
90
+ appearance?: 'default' | 'UNSAFE_modal-below-sm';
91
+ xcss?: StrictXCSSProp<'padding' | 'paddingInline' | 'paddingBlock' | 'width', never>;
79
92
  /**
80
93
  * Use this to either show or hide the popup.
81
94
  * When set to `false` the popup will not render anything to the DOM.
@@ -0,0 +1,15 @@
1
+ /**
2
+ * **usePopupAppearance()**
3
+ *
4
+ * Abstracts away calculating the appearance for a popup including if it should
5
+ * be portalled or not, this is done to ensure that if the popup needs to render
6
+ * as a modal that it is also forcibly portalled. If it's not portalled when rendering
7
+ * as a modal it will appear below the top bar.
8
+ */
9
+ export declare function usePopupAppearance({ appearance: _appearance, shouldRenderToParent: _shouldRenderToParent, }: {
10
+ appearance: 'default' | 'UNSAFE_modal-below-sm';
11
+ shouldRenderToParent?: boolean;
12
+ }): {
13
+ appearance: "default" | "UNSAFE_modal-below-sm";
14
+ shouldRenderToParent: boolean | undefined;
15
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaskit/popup",
3
- "version": "1.26.0",
3
+ "version": "1.27.0",
4
4
  "description": "A popup displays brief content in an overlay.",
5
5
  "publishConfig": {
6
6
  "registry": "https://registry.npmjs.org/"
@@ -36,13 +36,14 @@
36
36
  }
37
37
  },
38
38
  "dependencies": {
39
- "@atlaskit/ds-lib": "^2.5.0",
39
+ "@atlaskit/css": "^0.5.0",
40
+ "@atlaskit/ds-lib": "^2.6.0",
40
41
  "@atlaskit/focus-ring": "^1.6.0",
41
42
  "@atlaskit/layering": "^0.4.0",
42
43
  "@atlaskit/platform-feature-flags": "^0.3.0",
43
44
  "@atlaskit/popper": "^6.3.0",
44
45
  "@atlaskit/portal": "^4.9.0",
45
- "@atlaskit/primitives": "^12.1.0",
46
+ "@atlaskit/primitives": "^12.2.0",
46
47
  "@atlaskit/theme": "^13.0.0",
47
48
  "@atlaskit/tokens": "^1.60.0",
48
49
  "@babel/runtime": "^7.0.0",
@@ -67,8 +68,10 @@
67
68
  "@atlaskit/toggle": "^13.4.0",
68
69
  "@atlaskit/visual-regression": "*",
69
70
  "@atlassian/feature-flags-test-utils": "*",
71
+ "@compiled/react": "^0.17.3",
70
72
  "@testing-library/dom": "^10.1.0",
71
73
  "@testing-library/react": "^12.1.5",
74
+ "@testing-library/react-hooks": "^8.0.1",
72
75
  "@testing-library/user-event": "^14.4.3",
73
76
  "ast-types": "^0.13.3",
74
77
  "jscodeshift": "^0.13.0",