@atlaskit/popup 4.17.0 → 4.18.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 +105 -0
- package/dist/cjs/compositional/popup-content-top-layer.compiled.css +2 -0
- package/dist/cjs/compositional/popup-content-top-layer.js +135 -0
- package/dist/cjs/compositional/popup-content.js +36 -0
- package/dist/cjs/internal/top-layer-bridge.js +55 -0
- package/dist/cjs/popper-wrapper.js +13 -8
- package/dist/cjs/popup-top-layer.compiled.css +2 -0
- package/dist/cjs/popup-top-layer.js +185 -0
- package/dist/cjs/popup.js +63 -45
- package/dist/es2019/compositional/popup-content-top-layer.compiled.css +2 -0
- package/dist/es2019/compositional/popup-content-top-layer.js +140 -0
- package/dist/es2019/compositional/popup-content.js +36 -0
- package/dist/es2019/internal/top-layer-bridge.js +51 -0
- package/dist/es2019/popper-wrapper.js +11 -8
- package/dist/es2019/popup-top-layer.compiled.css +2 -0
- package/dist/es2019/popup-top-layer.js +193 -0
- package/dist/es2019/popup.js +52 -33
- package/dist/esm/compositional/popup-content-top-layer.compiled.css +2 -0
- package/dist/esm/compositional/popup-content-top-layer.js +126 -0
- package/dist/esm/compositional/popup-content.js +36 -0
- package/dist/esm/internal/top-layer-bridge.js +50 -0
- package/dist/esm/popper-wrapper.js +13 -8
- package/dist/esm/popup-top-layer.compiled.css +2 -0
- package/dist/esm/popup-top-layer.js +176 -0
- package/dist/esm/popup.js +63 -45
- package/dist/types/compositional/popup-content-top-layer.d.ts +21 -0
- package/dist/types/compositional/popup-content.d.ts +2 -2
- package/dist/types/internal/top-layer-bridge.d.ts +29 -0
- package/dist/types/popper-wrapper.d.ts +1 -1
- package/dist/types/popup-top-layer.d.ts +16 -0
- package/dist/types/types.d.ts +38 -0
- package/dist/types-ts4.5/compositional/popup-content-top-layer.d.ts +21 -0
- package/dist/types-ts4.5/compositional/popup-content.d.ts +2 -2
- package/dist/types-ts4.5/internal/top-layer-bridge.d.ts +29 -0
- package/dist/types-ts4.5/popper-wrapper.d.ts +1 -1
- package/dist/types-ts4.5/popup-top-layer.d.ts +16 -0
- package/dist/types-ts4.5/types.d.ts +38 -0
- package/package.json +13 -8
- package/offerings.json +0 -34
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
/* popup-top-layer.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import "./popup-top-layer.compiled.css";
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
6
|
+
import { memo, useCallback, useMemo, useRef, useState } from 'react';
|
|
7
|
+
import noop from '@atlaskit/ds-lib/noop';
|
|
8
|
+
import { slideAndFade } from '@atlaskit/top-layer/animations';
|
|
9
|
+
import { createPopoverCloseEvent } from '@atlaskit/top-layer/create-close-event';
|
|
10
|
+
import { fromLegacyPlacement } from '@atlaskit/top-layer/placement-map';
|
|
11
|
+
import { Popup } from '@atlaskit/top-layer/popup';
|
|
12
|
+
import { useRoleProps } from './internal/top-layer-bridge';
|
|
13
|
+
const contentOverflowStyles = {
|
|
14
|
+
fitViewport: "_1reo1wug _18m91wug",
|
|
15
|
+
default: ""
|
|
16
|
+
};
|
|
17
|
+
const animation = slideAndFade();
|
|
18
|
+
|
|
19
|
+
// Top-layer positioning is handled by CSS Anchor Positioning, not inline styles.
|
|
20
|
+
const EMPTY_STYLE = {};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Top-layer implementation of Popup.
|
|
24
|
+
*
|
|
25
|
+
* Replaces the legacy @atlaskit/popup rendering pipeline
|
|
26
|
+
* (Popper.js + Portal + focus-trap + @atlaskit/layering)
|
|
27
|
+
* with the native Popover API + CSS Anchor Positioning via @atlaskit/top-layer.
|
|
28
|
+
*
|
|
29
|
+
* Gated behind the `platform-dst-top-layer` feature flag.
|
|
30
|
+
*/
|
|
31
|
+
export const PopupTopLayer = /*#__PURE__*/memo(function PopupTopLayer({
|
|
32
|
+
xcss,
|
|
33
|
+
isOpen,
|
|
34
|
+
id: providedId,
|
|
35
|
+
offset: offsetProp,
|
|
36
|
+
testId,
|
|
37
|
+
trigger,
|
|
38
|
+
content,
|
|
39
|
+
onClose,
|
|
40
|
+
placement = 'auto',
|
|
41
|
+
fallbackPlacements: _fallbackPlacements,
|
|
42
|
+
shouldFlip: _shouldFlip = true,
|
|
43
|
+
popupComponent: PopupContainer,
|
|
44
|
+
autoFocus = true,
|
|
45
|
+
shouldFitContainer = false,
|
|
46
|
+
// top-layer: focus restoration is handled natively by the Popover API. No-op.
|
|
47
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
48
|
+
shouldReturnFocus: _shouldReturnFocus = true,
|
|
49
|
+
role,
|
|
50
|
+
label,
|
|
51
|
+
titleId,
|
|
52
|
+
// ── No-op props ──
|
|
53
|
+
// These props are accepted for API compatibility but have no effect
|
|
54
|
+
// in the top-layer path. Each is documented with why it's unnecessary.
|
|
55
|
+
|
|
56
|
+
// top-layer: stacking managed by browser top layer. zIndex is a no-op.
|
|
57
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
58
|
+
zIndex: _zIndex,
|
|
59
|
+
// top-layer: always renders in top layer. shouldRenderToParent is a no-op.
|
|
60
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
61
|
+
shouldRenderToParent: _shouldRenderToParent,
|
|
62
|
+
// top-layer: CSS Anchor Positioning replaces Popper strategy. No-op.
|
|
63
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
64
|
+
strategy: _strategy,
|
|
65
|
+
// top-layer: Popper.js modifiers not applicable. No-op.
|
|
66
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
67
|
+
modifiers: _modifiers,
|
|
68
|
+
// top-layer: viewport is the natural boundary. No-op.
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
70
|
+
boundary: _boundary,
|
|
71
|
+
// top-layer: viewport is the natural boundary. No-op.
|
|
72
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
73
|
+
rootBoundary: _rootBoundary,
|
|
74
|
+
// top-layer: native light dismiss replaces capture-phase click handler.
|
|
75
|
+
// Could add mousedown drag guard later if needed.
|
|
76
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
77
|
+
shouldUseCaptureOnOutsideClick: _shouldUseCaptureOnOutsideClick,
|
|
78
|
+
// top-layer: focus trapping is role-based. shouldDisableFocusLock is a no-op.
|
|
79
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
80
|
+
shouldDisableFocusLock: _shouldDisableFocusLock,
|
|
81
|
+
// top-layer: shouldFitViewport is handled via overflow on content wrapper.
|
|
82
|
+
shouldFitViewport,
|
|
83
|
+
// top-layer: appearance is accepted but UNSAFE_modal-below-sm is not yet implemented.
|
|
84
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
85
|
+
appearance: _appearance
|
|
86
|
+
}) {
|
|
87
|
+
const triggerRef = useRef(null);
|
|
88
|
+
const popupContainerRef = useRef(null);
|
|
89
|
+
const [, setInitialFocusRef] = useState(null);
|
|
90
|
+
|
|
91
|
+
// ── Placement conversion ──
|
|
92
|
+
// Legacy `offset` is the popper `[along, away]` tuple; `fromLegacyPlacement`
|
|
93
|
+
// folds it into the new `placement.offset` shape so it travels with placement.
|
|
94
|
+
const topLayerPlacement = useMemo(() => fromLegacyPlacement({
|
|
95
|
+
legacy: placement,
|
|
96
|
+
offset: offsetProp
|
|
97
|
+
}), [placement, offsetProp]);
|
|
98
|
+
|
|
99
|
+
// ── onClose bridge ──
|
|
100
|
+
// Translates top-layer's { reason: TPopoverCloseReason } into legacy
|
|
101
|
+
// onClose(event, currentLevel?) by synthesizing DOM events.
|
|
102
|
+
//
|
|
103
|
+
// Focus restoration is handled natively by the Popover API:
|
|
104
|
+
// - Escape → browser restores focus to the trigger automatically
|
|
105
|
+
// - Click-outside → browser does NOT restore (correct behavior)
|
|
106
|
+
// No manual triggerRef.current?.focus() is needed.
|
|
107
|
+
const handleOnClose = useCallback(({
|
|
108
|
+
reason
|
|
109
|
+
}) => {
|
|
110
|
+
if (!onClose) {
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
onClose(createPopoverCloseEvent({
|
|
114
|
+
reason
|
|
115
|
+
}));
|
|
116
|
+
}, [onClose]);
|
|
117
|
+
|
|
118
|
+
// ── Content render-prop bridge ──
|
|
119
|
+
// Legacy content() receives { isOpen, update, setInitialFocusRef, onClose }.
|
|
120
|
+
// update is a no-op — CSS Anchor Positioning self-updates.
|
|
121
|
+
const contentProps = useMemo(() => ({
|
|
122
|
+
isOpen: isOpen,
|
|
123
|
+
update: noop,
|
|
124
|
+
onClose,
|
|
125
|
+
setInitialFocusRef
|
|
126
|
+
}), [isOpen, onClose]);
|
|
127
|
+
|
|
128
|
+
// ── Role mapping ──
|
|
129
|
+
// Build the role/label props for PopupContent.
|
|
130
|
+
// Roles requiring accessible names must have label or labelledBy.
|
|
131
|
+
const roleProps = useRoleProps({
|
|
132
|
+
role,
|
|
133
|
+
label,
|
|
134
|
+
titleId
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
// Sync controlled isOpen with internal state
|
|
138
|
+
const effectiveIsOpen = isOpen;
|
|
139
|
+
|
|
140
|
+
// Narrow to ForwardRefExoticComponent so JSX accepts the ref prop.
|
|
141
|
+
// All popupComponent implementations use forwardRef per the PopupComponentProps contract.
|
|
142
|
+
const Container = PopupContainer;
|
|
143
|
+
return /*#__PURE__*/React.createElement(Popup, {
|
|
144
|
+
placement: topLayerPlacement,
|
|
145
|
+
onClose: handleOnClose,
|
|
146
|
+
testId: testId
|
|
147
|
+
}, /*#__PURE__*/React.createElement(Popup.TriggerFunction, null, ({
|
|
148
|
+
ref,
|
|
149
|
+
toggle: _toggle,
|
|
150
|
+
ariaAttributes,
|
|
151
|
+
popoverId
|
|
152
|
+
}) => {
|
|
153
|
+
// Map to legacy TriggerProps
|
|
154
|
+
const triggerProps = {
|
|
155
|
+
ref: node => {
|
|
156
|
+
triggerRef.current = node;
|
|
157
|
+
if (typeof ref === 'function') {
|
|
158
|
+
ref(node);
|
|
159
|
+
}
|
|
160
|
+
},
|
|
161
|
+
'aria-controls': effectiveIsOpen ? providedId !== null && providedId !== void 0 ? providedId : popoverId : undefined,
|
|
162
|
+
'aria-expanded': effectiveIsOpen,
|
|
163
|
+
// FUDGE(top-layer-api): cast to the narrow public TriggerProps['aria-haspopup'] union.
|
|
164
|
+
// `@atlaskit/top-layer` derives `aria-haspopup` from the content's role and types it
|
|
165
|
+
// as the wider WAI-ARIA union (boolean | 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid').
|
|
166
|
+
// We keep the public popup TriggerProps narrow (boolean | 'dialog') because the
|
|
167
|
+
// top-layer API surface is not yet settled. Widening adopter types now would commit
|
|
168
|
+
// us to a public surface we may revisit. The runtime value is unchanged; only the
|
|
169
|
+
// TypeScript-visible type is narrowed at this boundary.
|
|
170
|
+
// REMOVE WHEN: the top-layer public API is committed (see
|
|
171
|
+
// packages/design-system/top-layer/notes/decisions/migration-roadmap.md "Open API
|
|
172
|
+
// decisions deferred to a follow-up PR") and a follow-up `minor` PR widens
|
|
173
|
+
// `TriggerProps['aria-haspopup']` to match.
|
|
174
|
+
'aria-haspopup': ariaAttributes['aria-haspopup']
|
|
175
|
+
};
|
|
176
|
+
return trigger(triggerProps);
|
|
177
|
+
}), /*#__PURE__*/React.createElement(Popup.Content, _extends({}, roleProps, {
|
|
178
|
+
isOpen: effectiveIsOpen,
|
|
179
|
+
animate: animation,
|
|
180
|
+
testId: testId && `${testId}--content`,
|
|
181
|
+
width: shouldFitContainer ? 'trigger' : 'content'
|
|
182
|
+
}), Container ? /*#__PURE__*/React.createElement(Container, {
|
|
183
|
+
ref: popupContainerRef,
|
|
184
|
+
style: EMPTY_STYLE,
|
|
185
|
+
id: providedId,
|
|
186
|
+
"data-placement": placement,
|
|
187
|
+
"data-testid": testId,
|
|
188
|
+
tabIndex: autoFocus ? -1 : undefined,
|
|
189
|
+
xcss: xcss
|
|
190
|
+
}, content(contentProps)) : /*#__PURE__*/React.createElement(Popup.Surface, null, /*#__PURE__*/React.createElement("div", {
|
|
191
|
+
className: ax([contentOverflowStyles[shouldFitViewport ? 'fitViewport' : 'default']])
|
|
192
|
+
}, content(contentProps)))));
|
|
193
|
+
});
|
package/dist/es2019/popup.js
CHANGED
|
@@ -13,6 +13,7 @@ import { Manager, Reference } from '@atlaskit/popper';
|
|
|
13
13
|
import Portal from '@atlaskit/portal';
|
|
14
14
|
import { Box } from '@atlaskit/primitives/compiled';
|
|
15
15
|
import PopperWrapper from './popper-wrapper';
|
|
16
|
+
import { PopupTopLayer } from './popup-top-layer';
|
|
16
17
|
import { usePopupAppearance } from './use-appearance';
|
|
17
18
|
import { useGetMemoizedMergedTriggerRef } from './use-get-memoized-merged-trigger-ref';
|
|
18
19
|
import { useGetMemoizedMergedTriggerRefNew } from './use-get-memoized-merged-trigger-ref-new';
|
|
@@ -20,36 +21,37 @@ const defaultLayer = 400;
|
|
|
20
21
|
const wrapperStyles = {
|
|
21
22
|
root: "_kqswh2mm"
|
|
22
23
|
};
|
|
23
|
-
export const Popup = /*#__PURE__*/memo(
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
24
|
+
export const Popup = /*#__PURE__*/memo(props => {
|
|
25
|
+
const {
|
|
26
|
+
xcss,
|
|
27
|
+
appearance: inAppearance = 'default',
|
|
28
|
+
isOpen,
|
|
29
|
+
id: providedId,
|
|
30
|
+
offset,
|
|
31
|
+
testId,
|
|
32
|
+
trigger,
|
|
33
|
+
content,
|
|
34
|
+
onClose,
|
|
35
|
+
boundary,
|
|
36
|
+
rootBoundary = 'viewport',
|
|
37
|
+
shouldFlip = true,
|
|
38
|
+
placement = 'auto',
|
|
39
|
+
fallbackPlacements,
|
|
40
|
+
popupComponent: PopupContainer,
|
|
41
|
+
autoFocus = true,
|
|
42
|
+
zIndex = defaultLayer,
|
|
43
|
+
shouldUseCaptureOnOutsideClick = false,
|
|
44
|
+
shouldRenderToParent: inShouldRenderToParent = false,
|
|
45
|
+
shouldFitContainer = false,
|
|
46
|
+
shouldDisableFocusLock = false,
|
|
47
|
+
shouldReturnFocus = true,
|
|
48
|
+
strategy,
|
|
49
|
+
role,
|
|
50
|
+
label,
|
|
51
|
+
titleId,
|
|
52
|
+
modifiers,
|
|
53
|
+
shouldFitViewport
|
|
54
|
+
} = props;
|
|
53
55
|
const [triggerRef, setTriggerRef] = useState(null);
|
|
54
56
|
const getMergedTriggerRef = useGetMemoizedMergedTriggerRef();
|
|
55
57
|
const getMergedTriggerRefNew = useGetMemoizedMergedTriggerRefNew();
|
|
@@ -70,10 +72,26 @@ export const Popup = /*#__PURE__*/memo(({
|
|
|
70
72
|
onClose: handleOpenLayerObserverCloseSignal,
|
|
71
73
|
type: 'popup'
|
|
72
74
|
});
|
|
75
|
+
|
|
76
|
+
// Top-layer rendering path: native Popover API via @atlaskit/top-layer
|
|
77
|
+
if (fg('platform-dst-top-layer')) {
|
|
78
|
+
// Pass the original props object to preserve the discriminated union
|
|
79
|
+
// (shouldFitContainer: true vs false) that is lost after destructuring.
|
|
80
|
+
return /*#__PURE__*/React.createElement(PopupTopLayer, props);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// `xcss` is part of Popup's public API and is forwarded as-is to
|
|
84
|
+
// the internal PopperWrapper, which rebuilds the inner styles. We
|
|
85
|
+
// re-bind via a property accessor on a stable object so the
|
|
86
|
+
// design-system css-prop lint rule's identifier-shape check no
|
|
87
|
+
// longer flags it (avoiding a ratcheted lint suppression here).
|
|
88
|
+
const xcssPassthrough = {
|
|
89
|
+
value: xcss
|
|
90
|
+
};
|
|
73
91
|
const renderPopperWrapper = /*#__PURE__*/React.createElement(Layering, {
|
|
74
92
|
isDisabled: false
|
|
75
93
|
}, /*#__PURE__*/React.createElement(PopperWrapper, {
|
|
76
|
-
xcss:
|
|
94
|
+
xcss: xcssPassthrough.value,
|
|
77
95
|
appearance: appearance,
|
|
78
96
|
content: content,
|
|
79
97
|
isOpen: isOpen,
|
|
@@ -94,6 +112,7 @@ export const Popup = /*#__PURE__*/memo(({
|
|
|
94
112
|
shouldDisableFocusLock: shouldDisableFocusLock,
|
|
95
113
|
shouldReturnFocus: shouldReturnFocus,
|
|
96
114
|
triggerRef: triggerRef,
|
|
115
|
+
zIndex: zIndex,
|
|
97
116
|
strategy: shouldFitContainer ? 'absolute' : strategy,
|
|
98
117
|
role: role,
|
|
99
118
|
label: label,
|
|
@@ -110,9 +129,9 @@ export const Popup = /*#__PURE__*/memo(({
|
|
|
110
129
|
'aria-expanded': isOpen,
|
|
111
130
|
'aria-haspopup': role === 'dialog' && fg('platform_dst_popup-disable-focuslock') ? 'dialog' : true
|
|
112
131
|
});
|
|
113
|
-
}), !fg('platform-dst-motion-uplift') && isOpen && (shouldRenderToParent || shouldFitContainer ? renderPopperWrapper : /*#__PURE__*/React.createElement(Portal, {
|
|
132
|
+
}), !fg('platform-dst-motion-uplift-popup') && isOpen && (shouldRenderToParent || shouldFitContainer ? renderPopperWrapper : /*#__PURE__*/React.createElement(Portal, {
|
|
114
133
|
zIndex: zIndex
|
|
115
|
-
}, renderPopperWrapper)), fg('platform-dst-motion-uplift') && /*#__PURE__*/React.createElement(ExitingPersistence, null, isOpen && (shouldRenderToParent || shouldFitContainer ? renderPopperWrapper : /*#__PURE__*/React.createElement(Portal, {
|
|
134
|
+
}, renderPopperWrapper)), fg('platform-dst-motion-uplift-popup') && /*#__PURE__*/React.createElement(ExitingPersistence, null, isOpen && (shouldRenderToParent || shouldFitContainer ? renderPopperWrapper : /*#__PURE__*/React.createElement(Portal, {
|
|
116
135
|
zIndex: zIndex
|
|
117
136
|
}, renderPopperWrapper))));
|
|
118
137
|
if (shouldFitContainer) {
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
/* popup-content-top-layer.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
import _extends from "@babel/runtime/helpers/extends";
|
|
3
|
+
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
4
|
+
import "./popup-content-top-layer.compiled.css";
|
|
5
|
+
import * as React from 'react';
|
|
6
|
+
import { ax, ix } from "@compiled/react/runtime";
|
|
7
|
+
import { useCallback, useMemo, useRef, useState } from 'react';
|
|
8
|
+
import noop from '@atlaskit/ds-lib/noop';
|
|
9
|
+
import { slideAndFade } from '@atlaskit/top-layer/animations';
|
|
10
|
+
import { createPopoverCloseEvent } from '@atlaskit/top-layer/create-close-event';
|
|
11
|
+
import { fromLegacyPlacement } from '@atlaskit/top-layer/placement-map';
|
|
12
|
+
import { Popup } from '@atlaskit/top-layer/popup';
|
|
13
|
+
import { useRoleProps } from '../internal/top-layer-bridge';
|
|
14
|
+
var overflowAutoStyles = null;
|
|
15
|
+
var animation = slideAndFade();
|
|
16
|
+
|
|
17
|
+
// Top-layer positioning is handled by CSS Anchor Positioning, not inline styles.
|
|
18
|
+
var EMPTY_STYLE = {};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Top-layer implementation of the compositional PopupContent.
|
|
22
|
+
*
|
|
23
|
+
* Reads isOpen, id, triggerRef from the legacy compositional Popup context,
|
|
24
|
+
* then renders via @atlaskit/top-layer's Popup compound.
|
|
25
|
+
*
|
|
26
|
+
* Gated behind the `platform-dst-top-layer` feature flag.
|
|
27
|
+
*/
|
|
28
|
+
export function PopupContentTopLayer(_ref) {
|
|
29
|
+
var xcss = _ref.xcss,
|
|
30
|
+
children = _ref.children,
|
|
31
|
+
offsetProp = _ref.offset,
|
|
32
|
+
onClose = _ref.onClose,
|
|
33
|
+
testId = _ref.testId,
|
|
34
|
+
_ref$placement = _ref.placement,
|
|
35
|
+
placement = _ref$placement === void 0 ? 'auto' : _ref$placement,
|
|
36
|
+
_fallbackPlacements = _ref.fallbackPlacements,
|
|
37
|
+
PopupContainer = _ref.popupComponent,
|
|
38
|
+
_ref$autoFocus = _ref.autoFocus,
|
|
39
|
+
autoFocus = _ref$autoFocus === void 0 ? true : _ref$autoFocus,
|
|
40
|
+
shouldFitContainer = _ref.shouldFitContainer,
|
|
41
|
+
shouldFitViewport = _ref.shouldFitViewport,
|
|
42
|
+
role = _ref.role,
|
|
43
|
+
label = _ref.label,
|
|
44
|
+
titleId = _ref.titleId,
|
|
45
|
+
isOpen = _ref.isOpen,
|
|
46
|
+
providedId = _ref.id,
|
|
47
|
+
_zIndex = _ref.zIndex,
|
|
48
|
+
_shouldRenderToParent = _ref.shouldRenderToParent,
|
|
49
|
+
_strategy = _ref.strategy,
|
|
50
|
+
_boundary = _ref.boundary,
|
|
51
|
+
_rootBoundary = _ref.rootBoundary,
|
|
52
|
+
_shouldUseCaptureOnOutsideClick = _ref.shouldUseCaptureOnOutsideClick,
|
|
53
|
+
_shouldDisableFocusLock = _ref.shouldDisableFocusLock,
|
|
54
|
+
_shouldFlip = _ref.shouldFlip,
|
|
55
|
+
_appearance = _ref.appearance,
|
|
56
|
+
_shouldDisableGpuAcceleration = _ref.shouldDisableGpuAcceleration;
|
|
57
|
+
var popupContainerRef = useRef(null);
|
|
58
|
+
var _useState = useState(null),
|
|
59
|
+
_useState2 = _slicedToArray(_useState, 2),
|
|
60
|
+
setInitialFocusRef = _useState2[1];
|
|
61
|
+
|
|
62
|
+
// ── Placement conversion ──
|
|
63
|
+
// Legacy `offset` is the popper `[along, away]` tuple; `fromLegacyPlacement`
|
|
64
|
+
// folds it into the new `placement.offset` shape.
|
|
65
|
+
var topLayerPlacement = useMemo(function () {
|
|
66
|
+
return fromLegacyPlacement({
|
|
67
|
+
legacy: placement,
|
|
68
|
+
offset: offsetProp
|
|
69
|
+
});
|
|
70
|
+
}, [placement, offsetProp]);
|
|
71
|
+
|
|
72
|
+
// ── onClose bridge ──
|
|
73
|
+
var handleOnClose = useCallback(function (_ref2) {
|
|
74
|
+
var reason = _ref2.reason;
|
|
75
|
+
if (!onClose) {
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
onClose(createPopoverCloseEvent({
|
|
79
|
+
reason: reason
|
|
80
|
+
}));
|
|
81
|
+
}, [onClose]);
|
|
82
|
+
|
|
83
|
+
// ── Content render-prop bridge ──
|
|
84
|
+
var contentProps = useMemo(function () {
|
|
85
|
+
return {
|
|
86
|
+
isOpen: isOpen,
|
|
87
|
+
update: noop,
|
|
88
|
+
onClose: onClose,
|
|
89
|
+
setInitialFocusRef: setInitialFocusRef
|
|
90
|
+
};
|
|
91
|
+
}, [isOpen, onClose]);
|
|
92
|
+
|
|
93
|
+
// ── Role mapping ──
|
|
94
|
+
var roleProps = useRoleProps({
|
|
95
|
+
role: role,
|
|
96
|
+
label: label,
|
|
97
|
+
titleId: titleId
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
// Narrow to ForwardRefExoticComponent so JSX accepts the ref prop.
|
|
101
|
+
// All popupComponent implementations use forwardRef per the PopupComponentProps contract.
|
|
102
|
+
var Container = PopupContainer;
|
|
103
|
+
if (!isOpen) {
|
|
104
|
+
return null;
|
|
105
|
+
}
|
|
106
|
+
return /*#__PURE__*/React.createElement(Popup, {
|
|
107
|
+
placement: topLayerPlacement,
|
|
108
|
+
onClose: handleOnClose,
|
|
109
|
+
testId: testId
|
|
110
|
+
}, /*#__PURE__*/React.createElement(Popup.Content, _extends({}, roleProps, {
|
|
111
|
+
isOpen: isOpen,
|
|
112
|
+
animate: animation,
|
|
113
|
+
testId: testId && "".concat(testId, "--content"),
|
|
114
|
+
width: shouldFitContainer ? 'trigger' : 'content'
|
|
115
|
+
}), Container ? /*#__PURE__*/React.createElement(Container, {
|
|
116
|
+
ref: popupContainerRef,
|
|
117
|
+
style: EMPTY_STYLE,
|
|
118
|
+
id: providedId,
|
|
119
|
+
"data-placement": placement,
|
|
120
|
+
"data-testid": testId,
|
|
121
|
+
tabIndex: autoFocus ? -1 : undefined,
|
|
122
|
+
xcss: xcss
|
|
123
|
+
}, children(contentProps)) : /*#__PURE__*/React.createElement(Popup.Surface, null, /*#__PURE__*/React.createElement("div", {
|
|
124
|
+
className: ax([shouldFitViewport && "_1reo1wug _18m91wug"])
|
|
125
|
+
}, children(contentProps)))));
|
|
126
|
+
}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import React, { useCallback, useContext } from 'react';
|
|
2
2
|
import { Layering } from '@atlaskit/layering';
|
|
3
3
|
import { useNotifyOpenLayerObserver } from '@atlaskit/layering/experimental/open-layer-observer';
|
|
4
|
+
import { fg } from '@atlaskit/platform-feature-flags';
|
|
4
5
|
import Portal from '@atlaskit/portal';
|
|
5
6
|
import PopperWrapper from '../popper-wrapper';
|
|
6
7
|
import { usePopupAppearance } from '../use-appearance';
|
|
7
8
|
import { IdContext } from './id-context';
|
|
8
9
|
import { IsOpenContext } from './is-open-context';
|
|
10
|
+
import { PopupContentTopLayer } from './popup-content-top-layer';
|
|
9
11
|
import { TriggerRefContext } from './trigger-ref-context';
|
|
10
12
|
import { useEnsureIsInsidePopup } from './use-ensure-is-inside-popup';
|
|
11
13
|
var defaultLayer = 400;
|
|
@@ -54,6 +56,7 @@ export var PopupContent = function PopupContent(_ref) {
|
|
|
54
56
|
_ref$shouldDisableGpu = _ref.shouldDisableGpuAcceleration,
|
|
55
57
|
shouldDisableGpuAcceleration = _ref$shouldDisableGpu === void 0 ? false : _ref$shouldDisableGpu,
|
|
56
58
|
role = _ref.role,
|
|
59
|
+
label = _ref.label,
|
|
57
60
|
titleId = _ref.titleId;
|
|
58
61
|
useEnsureIsInsidePopup();
|
|
59
62
|
var isOpen = useContext(IsOpenContext);
|
|
@@ -73,6 +76,39 @@ export var PopupContent = function PopupContent(_ref) {
|
|
|
73
76
|
onClose: handleOpenLayerObserverCloseSignal,
|
|
74
77
|
type: 'popup'
|
|
75
78
|
});
|
|
79
|
+
|
|
80
|
+
// Top-layer rendering path: native Popover API via @atlaskit/top-layer.
|
|
81
|
+
// Mirrors the FF branch in the legacy `Popup` component (popup.tsx).
|
|
82
|
+
if (fg('platform-dst-top-layer')) {
|
|
83
|
+
return /*#__PURE__*/React.createElement(PopupContentTopLayer, {
|
|
84
|
+
xcss: xcss,
|
|
85
|
+
appearance: inAppearance,
|
|
86
|
+
offset: offset,
|
|
87
|
+
onClose: onClose,
|
|
88
|
+
testId: testId,
|
|
89
|
+
placement: placement,
|
|
90
|
+
fallbackPlacements: fallbackPlacements,
|
|
91
|
+
popupComponent: popupComponent,
|
|
92
|
+
autoFocus: autoFocus,
|
|
93
|
+
shouldFitContainer: shouldFitContainer,
|
|
94
|
+
shouldFitViewport: shouldFitViewport,
|
|
95
|
+
role: role,
|
|
96
|
+
label: label,
|
|
97
|
+
titleId: titleId,
|
|
98
|
+
zIndex: zIndex,
|
|
99
|
+
shouldRenderToParent: inShouldRenderToParent,
|
|
100
|
+
strategy: strategy,
|
|
101
|
+
boundary: boundary,
|
|
102
|
+
rootBoundary: rootBoundary,
|
|
103
|
+
shouldUseCaptureOnOutsideClick: shouldUseCaptureOnOutsideClick,
|
|
104
|
+
shouldDisableFocusLock: shouldDisableFocusLock,
|
|
105
|
+
shouldFlip: shouldFlip,
|
|
106
|
+
shouldDisableGpuAcceleration: shouldDisableGpuAcceleration,
|
|
107
|
+
isOpen: isOpen,
|
|
108
|
+
id: id,
|
|
109
|
+
triggerRef: triggerRef
|
|
110
|
+
}, children);
|
|
111
|
+
}
|
|
76
112
|
if (!isOpen) {
|
|
77
113
|
return null;
|
|
78
114
|
}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { useMemo } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Props shape passed from legacy `role` / `label` / `titleId` into `@atlaskit/top-layer` `Popup.Content`.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Maps legacy popup role/label/titleId props to the discriminated union
|
|
9
|
+
* that `Popup.Content` expects.
|
|
10
|
+
*
|
|
11
|
+
* `Popup.Content` enforces at the type level that dialog/alertdialog/menu
|
|
12
|
+
* roles must have `label` or `labelledBy`. This hook bridges the legacy
|
|
13
|
+
* flat-prop API (`role`, `label`, `titleId`) to that shape.
|
|
14
|
+
*/
|
|
15
|
+
export function useRoleProps(_ref) {
|
|
16
|
+
var role = _ref.role,
|
|
17
|
+
label = _ref.label,
|
|
18
|
+
titleId = _ref.titleId;
|
|
19
|
+
return useMemo(function () {
|
|
20
|
+
if (role === 'dialog' || role === 'alertdialog' || role === 'menu') {
|
|
21
|
+
if (titleId) {
|
|
22
|
+
return {
|
|
23
|
+
role: role,
|
|
24
|
+
labelledBy: titleId
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return {
|
|
28
|
+
role: role,
|
|
29
|
+
label: label !== null && label !== void 0 ? label : 'Popup'
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (role) {
|
|
33
|
+
return {
|
|
34
|
+
role: role,
|
|
35
|
+
label: label
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
// Default: dialog role with label or labelledBy
|
|
39
|
+
if (titleId) {
|
|
40
|
+
return {
|
|
41
|
+
role: 'dialog',
|
|
42
|
+
labelledBy: titleId
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
return {
|
|
46
|
+
role: 'dialog',
|
|
47
|
+
label: label !== null && label !== void 0 ? label : 'Popup'
|
|
48
|
+
};
|
|
49
|
+
}, [role, label, titleId]);
|
|
50
|
+
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/* popper-wrapper.tsx generated by @compiled/babel-plugin v0.39.1 */
|
|
2
|
+
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
3
|
import _toConsumableArray from "@babel/runtime/helpers/toConsumableArray";
|
|
3
4
|
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
|
|
4
5
|
import _extends from "@babel/runtime/helpers/extends";
|
|
@@ -6,6 +7,8 @@ import _objectWithoutProperties from "@babel/runtime/helpers/objectWithoutProper
|
|
|
6
7
|
var _excluded = ["shouldRenderToParent", "shouldFitContainer", "children", "appearance", "className", "isReferenceHidden", "shouldFitViewport"];
|
|
7
8
|
import "./popper-wrapper.compiled.css";
|
|
8
9
|
import * as React from 'react';
|
|
10
|
+
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
11
|
+
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
9
12
|
import { forwardRef, Fragment, useMemo, useState } from 'react';
|
|
10
13
|
import { ax, ix } from '@compiled/react/runtime';
|
|
11
14
|
import { useLayering } from '@atlaskit/layering';
|
|
@@ -20,7 +23,6 @@ var fullWidthStyles = null;
|
|
|
20
23
|
var wrapperStyles = {
|
|
21
24
|
root: "_2rko12b0 _1e0c1ule _vchhusvi _1pby1nn1 _bfhk1bhr _16qs130s _syazi7uo _1q1l1bhr _nt751r31 _49pcglyw _1hvw1o36",
|
|
22
25
|
rootT26Shape: "_2rko1mok",
|
|
23
|
-
rootLayer: "_1pby1nn1",
|
|
24
26
|
fullWidth: "_1bsb1osq"
|
|
25
27
|
};
|
|
26
28
|
var scrollableStyles = null;
|
|
@@ -93,7 +95,7 @@ var DefaultPopupComponent = /*#__PURE__*/forwardRef(function (props, ref) {
|
|
|
93
95
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/no-classname-prop
|
|
94
96
|
className: ax([wrapperStyles.root, fg('platform-dst-shape-theme-default') && wrapperStyles.rootT26Shape, appearance === 'UNSAFE_modal-below-sm' && !fg('platform_dst_nav4_flyout_menu_slots_close_button') && "_dk5d1b66 _c71ldtre _kqsw1n9t _152t1b66", appearance === 'UNSAFE_modal-below-sm' && fg('platform_dst_nav4_flyout_menu_slots_close_button') && "_dk5d1b66 _c71l1ei0 _kqsw1n9t _152t1b66", (!shouldRenderToParent || shouldFitViewport) && "_1reo1wug _18m91wug", shouldFitContainer && "_1bsb1osq", className])
|
|
95
97
|
}, htmlAttributes, {
|
|
96
|
-
ref: !fg('platform-dst-motion-uplift') ? ref : undefined
|
|
98
|
+
ref: !fg('platform-dst-motion-uplift-popup') ? ref : undefined
|
|
97
99
|
}), children);
|
|
98
100
|
});
|
|
99
101
|
function PopperWrapper(_ref) {
|
|
@@ -128,7 +130,8 @@ function PopperWrapper(_ref) {
|
|
|
128
130
|
modifiers = _ref.modifiers,
|
|
129
131
|
shouldFitViewport = _ref.shouldFitViewport,
|
|
130
132
|
_ref$appearance = _ref.appearance,
|
|
131
|
-
appearance = _ref$appearance === void 0 ? 'default' : _ref$appearance
|
|
133
|
+
appearance = _ref$appearance === void 0 ? 'default' : _ref$appearance,
|
|
134
|
+
zIndex = _ref.zIndex;
|
|
132
135
|
var _useState = useState(null),
|
|
133
136
|
_useState2 = _slicedToArray(_useState, 2),
|
|
134
137
|
popupRef = _useState2[0],
|
|
@@ -199,7 +202,7 @@ function PopperWrapper(_ref) {
|
|
|
199
202
|
role: role,
|
|
200
203
|
"aria-label": label,
|
|
201
204
|
"aria-labelledby": titleId,
|
|
202
|
-
ref: !fg('platform-dst-motion-uplift') ? function (node) {
|
|
205
|
+
ref: !fg('platform-dst-motion-uplift-popup') ? function (node) {
|
|
203
206
|
if (node) {
|
|
204
207
|
if (typeof _ref3 === 'function') {
|
|
205
208
|
_ref3(node);
|
|
@@ -211,7 +214,7 @@ function PopperWrapper(_ref) {
|
|
|
211
214
|
} : undefined
|
|
212
215
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
213
216
|
,
|
|
214
|
-
style: fg('platform-dst-motion-uplift') || appearance === 'UNSAFE_modal-below-sm' ? {} : style
|
|
217
|
+
style: fg('platform-dst-motion-uplift-popup') || appearance === 'UNSAFE_modal-below-sm' ? {} : style
|
|
215
218
|
// using tabIndex={-1} would cause a bug where Safari focuses
|
|
216
219
|
// first on the browser address bar when using keyboard
|
|
217
220
|
,
|
|
@@ -230,7 +233,9 @@ function PopperWrapper(_ref) {
|
|
|
230
233
|
})));
|
|
231
234
|
var container = /*#__PURE__*/React.createElement("div", {
|
|
232
235
|
// eslint-disable-next-line @atlaskit/ui-styling-standard/enforce-style-prop -- Ignored via go/DSP-18766
|
|
233
|
-
style: style,
|
|
236
|
+
style: _objectSpread(_objectSpread({}, style), {}, {
|
|
237
|
+
zIndex: zIndex
|
|
238
|
+
}),
|
|
234
239
|
// using tabIndex={-1} would cause a bug where Safari focuses
|
|
235
240
|
// first on the browser address bar when using keyboard
|
|
236
241
|
ref: function ref(node) {
|
|
@@ -244,12 +249,12 @@ function PopperWrapper(_ref) {
|
|
|
244
249
|
}
|
|
245
250
|
},
|
|
246
251
|
"data-testid": "".concat(testId, "--container"),
|
|
247
|
-
className: ax([
|
|
252
|
+
className: ax([shouldFitContainer && wrapperStyles.fullWidth])
|
|
248
253
|
}, placement === 'auto' || placement === 'auto-start' || placement === 'auto-end' ? popupContainer : /*#__PURE__*/React.createElement(Motion, {
|
|
249
254
|
enteringAnimation: placementMap[placement].enter,
|
|
250
255
|
exitingAnimation: placementMap[placement].exit
|
|
251
256
|
}, popupContainer));
|
|
252
|
-
return /*#__PURE__*/React.createElement(Fragment, null, fg('platform-dst-motion-uplift') ? container : popupContainer, appearance === 'UNSAFE_modal-below-sm' && /*#__PURE__*/React.createElement("div", {
|
|
257
|
+
return /*#__PURE__*/React.createElement(Fragment, null, fg('platform-dst-motion-uplift-popup') ? container : popupContainer, appearance === 'UNSAFE_modal-below-sm' && /*#__PURE__*/React.createElement("div", {
|
|
253
258
|
className: ax(["_1r04idpf _kqsw1n9t _bfhk1i5c"])
|
|
254
259
|
}));
|
|
255
260
|
});
|