@atlaskit/top-layer 0.8.0 → 0.10.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 +41 -0
- package/README.md +5 -1
- package/dialog/create-close-event/package.json +17 -0
- package/dist/cjs/animations/presets.js +11 -4
- package/dist/cjs/arrow/index.js +131 -0
- package/dist/cjs/arrow/types.js +5 -0
- package/dist/cjs/dialog/dialog-content.js +23 -6
- package/dist/cjs/entry-points/dialog/create-close-event.js +12 -0
- package/dist/cjs/entry-points/placement-map.js +6 -5
- package/dist/cjs/entry-points/popover/create-close-event.js +12 -0
- package/dist/cjs/focus/focus.js +73 -19
- package/dist/cjs/index.js +3 -4
- package/dist/cjs/internal/resolve-css-length-to-pixels.js +61 -10
- package/dist/cjs/internal/role-types.js +40 -9
- package/dist/cjs/internal/set-style.js +23 -25
- package/dist/cjs/internal/use-anchor-position.js +109 -68
- package/dist/cjs/internal/use-focus-wrap.js +13 -2
- package/dist/cjs/internal/use-initial-focus.js +31 -10
- package/dist/cjs/placement-map/index.js +9 -110
- package/dist/cjs/placement-map/legacy-placements.js +113 -0
- package/dist/cjs/popover/popover.js +44 -11
- package/dist/cjs/popup/popup-content.js +19 -13
- package/dist/cjs/popup/popup-context.js +2 -0
- package/dist/cjs/popup/popup-surface.js +6 -0
- package/dist/cjs/popup/popup-trigger-function.js +1 -1
- package/dist/cjs/popup/popup-trigger.js +17 -37
- package/dist/cjs/popup/popup.js +21 -10
- package/dist/cjs/use-arrow-navigation/use-arrow-navigation.js +27 -10
- package/dist/es2019/animations/presets.js +10 -3
- package/dist/es2019/arrow/index.js +269 -0
- package/dist/es2019/arrow/types.js +1 -0
- package/dist/es2019/dialog/dialog-content.js +23 -6
- package/dist/es2019/entry-points/create-close-event.js +7 -0
- package/dist/es2019/entry-points/dialog/create-close-event.js +1 -0
- package/dist/es2019/entry-points/placement-map.js +2 -1
- package/dist/es2019/entry-points/popover/create-close-event.js +1 -0
- package/dist/es2019/focus/focus.js +58 -7
- package/dist/es2019/index.js +3 -4
- package/dist/es2019/internal/resolve-css-length-to-pixels.js +60 -7
- package/dist/es2019/internal/role-types.js +40 -9
- package/dist/es2019/internal/set-style.js +19 -22
- package/dist/es2019/internal/use-anchor-position.js +97 -54
- package/dist/es2019/internal/use-focus-wrap.js +14 -3
- package/dist/es2019/internal/use-initial-focus.js +32 -11
- package/dist/es2019/placement-map/index.js +8 -108
- package/dist/es2019/placement-map/legacy-placements.js +107 -0
- package/dist/es2019/popover/popover.js +44 -10
- package/dist/es2019/popup/popup-content.js +20 -14
- package/dist/es2019/popup/popup-context.js +2 -0
- package/dist/es2019/popup/popup-surface.js +6 -0
- package/dist/es2019/popup/popup-trigger-function.js +1 -1
- package/dist/es2019/popup/popup-trigger.js +17 -37
- package/dist/es2019/popup/popup.js +20 -9
- package/dist/es2019/use-arrow-navigation/use-arrow-navigation.js +27 -10
- package/dist/esm/animations/presets.js +10 -3
- package/dist/esm/arrow/index.js +124 -0
- package/dist/esm/arrow/types.js +1 -0
- package/dist/esm/dialog/dialog-content.js +23 -6
- package/dist/esm/entry-points/create-close-event.js +7 -0
- package/dist/esm/entry-points/dialog/create-close-event.js +1 -0
- package/dist/esm/entry-points/placement-map.js +2 -1
- package/dist/esm/entry-points/popover/create-close-event.js +1 -0
- package/dist/esm/focus/focus.js +72 -19
- package/dist/esm/index.js +3 -4
- package/dist/esm/internal/resolve-css-length-to-pixels.js +61 -10
- package/dist/esm/internal/role-types.js +39 -9
- package/dist/esm/internal/set-style.js +23 -25
- package/dist/esm/internal/use-anchor-position.js +110 -64
- package/dist/esm/internal/use-focus-wrap.js +14 -3
- package/dist/esm/internal/use-initial-focus.js +32 -11
- package/dist/esm/placement-map/index.js +8 -108
- package/dist/esm/placement-map/legacy-placements.js +107 -0
- package/dist/esm/popover/popover.js +44 -11
- package/dist/esm/popup/popup-content.js +20 -14
- package/dist/esm/popup/popup-context.js +2 -0
- package/dist/esm/popup/popup-surface.js +6 -0
- package/dist/esm/popup/popup-trigger-function.js +1 -1
- package/dist/esm/popup/popup-trigger.js +17 -37
- package/dist/esm/popup/popup.js +21 -10
- package/dist/esm/use-arrow-navigation/use-arrow-navigation.js +27 -10
- package/dist/types/arrow/index.d.ts +24 -0
- package/dist/types/arrow/types.d.ts +29 -0
- package/dist/types/dialog/dialog-content.d.ts +5 -1
- package/dist/types/dialog/types.d.ts +50 -24
- package/dist/types/entry-points/create-close-event.d.ts +7 -0
- package/dist/types/entry-points/dialog/create-close-event.d.ts +2 -0
- package/dist/types/entry-points/placement-map.d.ts +2 -1
- package/dist/types/entry-points/popover/create-close-event.d.ts +2 -0
- package/dist/types/focus/focus.d.ts +8 -0
- package/dist/types/internal/resolve-css-length-to-pixels.d.ts +4 -6
- package/dist/types/internal/role-types.d.ts +25 -4
- package/dist/types/internal/set-style.d.ts +2 -19
- package/dist/types/internal/use-anchor-position.d.ts +2 -3
- package/dist/types/internal/use-initial-focus.d.ts +5 -4
- package/dist/types/placement-map/index.d.ts +8 -21
- package/dist/types/placement-map/legacy-placements.d.ts +21 -0
- package/dist/types/popover/popover.d.ts +1 -1
- package/dist/types/popover/types.d.ts +20 -19
- package/dist/types/popup/popup-surface.d.ts +6 -0
- package/dist/types/popup/popup-trigger-function.d.ts +10 -6
- package/dist/types/popup/popup-trigger.d.ts +8 -17
- package/dist/types/popup/popup.d.ts +2 -2
- package/dist/types/popup/types.d.ts +68 -22
- package/dist/types/use-arrow-navigation/use-arrow-navigation.d.ts +19 -5
- package/dist/types-ts4.5/arrow/index.d.ts +24 -0
- package/dist/types-ts4.5/arrow/types.d.ts +29 -0
- package/dist/types-ts4.5/dialog/dialog-content.d.ts +5 -1
- package/dist/types-ts4.5/dialog/types.d.ts +50 -24
- package/dist/types-ts4.5/entry-points/create-close-event.d.ts +7 -0
- package/dist/types-ts4.5/entry-points/dialog/create-close-event.d.ts +2 -0
- package/dist/types-ts4.5/entry-points/placement-map.d.ts +2 -1
- package/dist/types-ts4.5/entry-points/popover/create-close-event.d.ts +2 -0
- package/dist/types-ts4.5/focus/focus.d.ts +8 -0
- package/dist/types-ts4.5/internal/resolve-css-length-to-pixels.d.ts +4 -6
- package/dist/types-ts4.5/internal/role-types.d.ts +25 -4
- package/dist/types-ts4.5/internal/set-style.d.ts +2 -19
- package/dist/types-ts4.5/internal/use-anchor-position.d.ts +2 -3
- package/dist/types-ts4.5/internal/use-initial-focus.d.ts +5 -4
- package/dist/types-ts4.5/placement-map/index.d.ts +8 -21
- package/dist/types-ts4.5/placement-map/legacy-placements.d.ts +39 -0
- package/dist/types-ts4.5/popover/popover.d.ts +1 -1
- package/dist/types-ts4.5/popover/types.d.ts +20 -19
- package/dist/types-ts4.5/popup/popup-surface.d.ts +6 -0
- package/dist/types-ts4.5/popup/popup-trigger-function.d.ts +10 -6
- package/dist/types-ts4.5/popup/popup-trigger.d.ts +8 -17
- package/dist/types-ts4.5/popup/popup.d.ts +2 -2
- package/dist/types-ts4.5/popup/types.d.ts +68 -22
- package/dist/types-ts4.5/use-arrow-navigation/use-arrow-navigation.d.ts +19 -5
- package/package.json +3 -1
- package/popover/create-close-event/package.json +17 -0
|
@@ -1,9 +1,5 @@
|
|
|
1
1
|
import { type TPlacementOptions } from '../internal/resolve-placement';
|
|
2
|
-
|
|
3
|
-
* Legacy Popper.js placement values (used by `@atlaskit/popper`, `@atlaskit/popup`,
|
|
4
|
-
* `@atlaskit/tooltip`, etc.).
|
|
5
|
-
*/
|
|
6
|
-
export type TLegacyPlacement = 'auto' | 'auto-start' | 'auto-end' | 'top' | 'top-start' | 'top-center' | 'top-end' | 'bottom' | 'bottom-start' | 'bottom-center' | 'bottom-end' | 'right' | 'right-start' | 'right-end' | 'left' | 'left-start' | 'left-end';
|
|
2
|
+
import { type TLegacyPlacement } from './legacy-placements';
|
|
7
3
|
/**
|
|
8
4
|
* Maps legacy Popper.js placement values to the new object-based
|
|
9
5
|
* `Placement` values used by `@atlaskit/top-layer/popover`.
|
|
@@ -14,9 +10,11 @@ export type TLegacyPlacement = 'auto' | 'auto-start' | 'auto-end' | 'top' | 'top
|
|
|
14
10
|
* | ------------------- | --------------------------------------------------- |
|
|
15
11
|
* | `top` | `{ axis: 'block', edge: 'start', align: 'center' }` |
|
|
16
12
|
* | `top-start` | `{ axis: 'block', edge: 'start', align: 'start' }` |
|
|
13
|
+
* | `top-center` | `{ axis: 'block', edge: 'start', align: 'center' }` |
|
|
17
14
|
* | `top-end` | `{ axis: 'block', edge: 'start', align: 'end' }` |
|
|
18
15
|
* | `bottom` | `{ axis: 'block', edge: 'end', align: 'center' }` |
|
|
19
16
|
* | `bottom-start` | `{ axis: 'block', edge: 'end', align: 'start' }` |
|
|
17
|
+
* | `bottom-center` | `{ axis: 'block', edge: 'end', align: 'center' }` |
|
|
20
18
|
* | `bottom-end` | `{ axis: 'block', edge: 'end', align: 'end' }` |
|
|
21
19
|
* | `right` | `{ axis: 'inline', edge: 'end', align: 'center' }` |
|
|
22
20
|
* | `right-start` | `{ axis: 'inline', edge: 'end', align: 'start' }` |
|
|
@@ -28,7 +26,10 @@ export type TLegacyPlacement = 'auto' | 'auto-start' | 'auto-end' | 'top' | 'top
|
|
|
28
26
|
* | `auto-start` | `{ axis: 'block', edge: 'end', align: 'start' }` |
|
|
29
27
|
* | `auto-end` | `{ axis: 'block', edge: 'end', align: 'end' }` |
|
|
30
28
|
*
|
|
31
|
-
*
|
|
29
|
+
* `auto*` is mapped to `block-end` (a reduction in expressiveness vs Popper's
|
|
30
|
+
* runtime auto-flip). CSS `position-try-fallbacks` provides flipping at the
|
|
31
|
+
* edge - but the initial placement is fixed. If migrating away from Popper's
|
|
32
|
+
* dynamic auto, prefer an explicit placement.
|
|
32
33
|
*
|
|
33
34
|
* @example
|
|
34
35
|
* ```ts
|
|
@@ -40,16 +41,6 @@ export type TLegacyPlacement = 'auto' | 'auto-start' | 'auto-end' | 'top' | 'top
|
|
|
40
41
|
* // newPlacement === { axis: 'block', edge: 'end', align: 'start' }
|
|
41
42
|
* ```
|
|
42
43
|
*/
|
|
43
|
-
declare const placementMapping: Record<TLegacyPlacement, TPlacementOptions>;
|
|
44
|
-
/**
|
|
45
|
-
* Convert a legacy Popper.js placement to the new `position-area`-based Placement.
|
|
46
|
-
* Optional `offset` is the legacy Popper `[along, away]` tuple (also known as
|
|
47
|
-
* `[skidding, distance]`); negative `along` becomes `direction: 'backwards'`.
|
|
48
|
-
*
|
|
49
|
-
* The tuple keeps the historical popper names so call sites that already pass
|
|
50
|
-
* `[along, away]` migrate without thinking; the new internal field names
|
|
51
|
-
* (`gap` / `crossAxisShift`) are produced inside this adapter.
|
|
52
|
-
*/
|
|
53
44
|
export declare function fromLegacyPlacement({ legacy, offset, }: {
|
|
54
45
|
legacy: TLegacyPlacement;
|
|
55
46
|
offset?: [
|
|
@@ -57,8 +48,4 @@ export declare function fromLegacyPlacement({ legacy, offset, }: {
|
|
|
57
48
|
away: number
|
|
58
49
|
];
|
|
59
50
|
}): TPlacementOptions;
|
|
60
|
-
|
|
61
|
-
* The full mapping record, exposed for consumers that need to iterate or introspect.
|
|
62
|
-
*/
|
|
63
|
-
export { placementMapping };
|
|
64
|
-
export type { TPlacementOptions };
|
|
51
|
+
export type { TLegacyPlacement, TPlacementOptions };
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { type TPlacementOptions } from '../internal/resolve-placement';
|
|
2
|
+
/**
|
|
3
|
+
* Legacy Popper.js placement values (used by `@atlaskit/popper`,
|
|
4
|
+
* `@atlaskit/popup`, `@atlaskit/tooltip`, etc.). Re-exported from
|
|
5
|
+
* `@atlaskit/top-layer/placement-map` for migration consumers that need
|
|
6
|
+
* to enumerate every placement (e.g. for a settings dropdown). New code
|
|
7
|
+
* should use the object-based `TPlacementOptions` directly.
|
|
8
|
+
*/
|
|
9
|
+
export declare const LEGACY_PLACEMENTS: readonly [
|
|
10
|
+
"auto",
|
|
11
|
+
"auto-start",
|
|
12
|
+
"auto-end",
|
|
13
|
+
"top",
|
|
14
|
+
"top-start",
|
|
15
|
+
"top-center",
|
|
16
|
+
"top-end",
|
|
17
|
+
"bottom",
|
|
18
|
+
"bottom-start",
|
|
19
|
+
"bottom-center",
|
|
20
|
+
"bottom-end",
|
|
21
|
+
"right",
|
|
22
|
+
"right-start",
|
|
23
|
+
"right-end",
|
|
24
|
+
"left",
|
|
25
|
+
"left-start",
|
|
26
|
+
"left-end"
|
|
27
|
+
];
|
|
28
|
+
export type TLegacyPlacement = (typeof LEGACY_PLACEMENTS)[number];
|
|
29
|
+
/**
|
|
30
|
+
* The full mapping record. Internal - use `fromLegacyPlacement` from the
|
|
31
|
+
* public entry-point so the offset-tuple translation is applied consistently.
|
|
32
|
+
*
|
|
33
|
+
* Note: `auto`, `auto-start`, `auto-end` map to `block-end` placements. This
|
|
34
|
+
* is a reduction in expressiveness vs Popper.js (which picked the best
|
|
35
|
+
* placement at runtime). CSS `position-try-fallbacks` flips at the edge but
|
|
36
|
+
* the initial placement is fixed. Migration consumers who relied on Popper's
|
|
37
|
+
* dynamic auto-flip should pick an explicit placement instead.
|
|
38
|
+
*/
|
|
39
|
+
export declare const placementMapping: Record<TLegacyPlacement, TPlacementOptions>;
|
|
@@ -18,7 +18,7 @@ import { type TPopoverForwardedProps } from './types';
|
|
|
18
18
|
*
|
|
19
19
|
* For `mode="auto"`, the browser can dismiss the popover via light dismiss
|
|
20
20
|
* (Escape, click outside). When that happens, `onClose` is called and the
|
|
21
|
-
* consumer must set `isOpen` to `false`. The DOM owns the dismiss
|
|
21
|
+
* consumer must set `isOpen` to `false`. The DOM owns the dismiss; React
|
|
22
22
|
* must follow.
|
|
23
23
|
*/
|
|
24
24
|
export declare const Popover: React.ForwardRefExoticComponent<TPopoverForwardedProps & React.RefAttributes<HTMLDivElement>>;
|
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
import { type StrictXCSSProp } from '@atlaskit/css';
|
|
3
3
|
import { type TAnimationPreset } from '../animations/types';
|
|
4
|
-
import { type
|
|
4
|
+
import { type TAriaRoleRequired, type TRoleRequiringAccessibleName, type TRoleWithImplicitName } from '../internal/role-types';
|
|
5
5
|
import { type TPlacementOptions } from '../popup/types';
|
|
6
6
|
/**
|
|
7
|
-
* The reason a popover was
|
|
7
|
+
* The reason a popover was closed.
|
|
8
8
|
*
|
|
9
9
|
* - `'escape'`: The user pressed the Escape key.
|
|
10
10
|
* - `'light-dismiss'`: The user clicked outside the popover (or the browser
|
|
11
11
|
* dismissed it for another auto-mode reason).
|
|
12
|
+
* - `'programmatic'`: The popover was closed programmatically.
|
|
12
13
|
*/
|
|
13
|
-
export type TPopoverCloseReason = 'escape' | 'light-dismiss';
|
|
14
|
+
export type TPopoverCloseReason = 'escape' | 'light-dismiss' | 'programmatic';
|
|
14
15
|
/**
|
|
15
16
|
* Flat (non-discriminated) props accepted by the Popover component internally.
|
|
16
17
|
*
|
|
@@ -30,13 +31,6 @@ export type TPopoverForwardedProps = TPopoverBaseProps & {
|
|
|
30
31
|
label?: string;
|
|
31
32
|
labelledBy?: string;
|
|
32
33
|
};
|
|
33
|
-
/**
|
|
34
|
-
* Alias for TPopoverForwardedProps.
|
|
35
|
-
*
|
|
36
|
-
* Used internally by PopupContent to forward props to Popover without
|
|
37
|
-
* re-proving the discriminated union at each call site.
|
|
38
|
-
*/
|
|
39
|
-
export type TPopoverInternalProps = TPopoverForwardedProps;
|
|
40
34
|
type TPopoverBaseProps = {
|
|
41
35
|
children: ReactNode;
|
|
42
36
|
/**
|
|
@@ -69,12 +63,12 @@ type TPopoverBaseProps = {
|
|
|
69
63
|
* animation plays (via `allow-discrete`) before the popover becomes logically closed.
|
|
70
64
|
* Otherwise hides instantly.
|
|
71
65
|
*
|
|
72
|
-
* The element stays mounted in the DOM at all times
|
|
66
|
+
* The element stays mounted in the DOM at all times. The consumer does not
|
|
73
67
|
* conditionally render it. Visibility is driven by this prop.
|
|
74
68
|
*
|
|
75
69
|
* **Important:** For `mode="auto"` popovers, the browser can dismiss the popover
|
|
76
70
|
* via light dismiss (Escape, click outside) independently of this prop. When that
|
|
77
|
-
* happens, `onClose` is called
|
|
71
|
+
* happens, `onClose` is called and the consumer should respond by setting `isOpen`
|
|
78
72
|
* to `false`. If `isOpen` remains `true` after a browser dismiss, the DOM and
|
|
79
73
|
* React state will be out of sync (the popover will be hidden despite `isOpen={true}`).
|
|
80
74
|
*/
|
|
@@ -108,14 +102,14 @@ type TPopoverBaseProps = {
|
|
|
108
102
|
* called to set CSS custom properties (like `--ds-popover-tx`, `--ds-popover-ty`)
|
|
109
103
|
* that control the slide direction. Has no effect without `animate`.
|
|
110
104
|
*
|
|
111
|
-
* This does NOT control positioning
|
|
105
|
+
* This does NOT control positioning. Use `useAnchorPosition` for that.
|
|
112
106
|
*/
|
|
113
107
|
placement?: TPlacementOptions;
|
|
114
108
|
/**
|
|
115
109
|
* Called after the exit animation completes (or immediately on close when
|
|
116
110
|
* there is no animation or reduced motion is active).
|
|
117
111
|
*
|
|
118
|
-
* Use this for external lifecycle coordination
|
|
112
|
+
* Use this for external lifecycle coordination, e.g. notifying a manager
|
|
119
113
|
* that the hide sequence is finished, or firing an `onCloseComplete` callback.
|
|
120
114
|
*/
|
|
121
115
|
onExitFinish?: () => void;
|
|
@@ -123,7 +117,7 @@ type TPopoverBaseProps = {
|
|
|
123
117
|
/**
|
|
124
118
|
* Unopinionated top-layer primitive.
|
|
125
119
|
*
|
|
126
|
-
* `Popover` manages only top-layer visibility and animation
|
|
120
|
+
* `Popover` manages only top-layer visibility and animation. It has no
|
|
127
121
|
* knowledge of positioning. For anchor positioning, compose with the
|
|
128
122
|
* `useAnchorPosition` hook separately.
|
|
129
123
|
*
|
|
@@ -134,22 +128,29 @@ type TPopoverBaseProps = {
|
|
|
134
128
|
* Dismiss behavior:
|
|
135
129
|
* - `'auto'` (default): Escape to close, click-outside to close, focus restoration,
|
|
136
130
|
* automatic nesting, mutual exclusivity.
|
|
137
|
-
* - `'hint'`: ephemeral UI (e.g. tooltips) that
|
|
138
|
-
* Falls back to `
|
|
131
|
+
* - `'hint'`: ephemeral UI (e.g. tooltips) that does not close other `auto`
|
|
132
|
+
* popovers. Falls back silently to `auto` semantics in browsers without
|
|
133
|
+
* `popover='hint'` support, meaning the hint will close any other `auto`
|
|
134
|
+
* popovers in those browsers. If cross-browser uniformity matters more
|
|
135
|
+
* than the no-close behaviour, pass `auto` explicitly.
|
|
139
136
|
* - `'manual'`: no light dismiss. Consumer controls show/hide entirely. Only
|
|
140
137
|
* appropriate for persistent UI (e.g. flags, banners).
|
|
141
138
|
*/
|
|
142
|
-
export type TPopoverProps = TPopoverBaseProps &
|
|
139
|
+
export type TPopoverProps = TPopoverBaseProps & TAriaRoleRequired & ({
|
|
143
140
|
mode?: 'auto' | 'hint';
|
|
144
141
|
/**
|
|
145
142
|
* Called when the popover is dismissed via light dismiss
|
|
146
143
|
* (Escape, click outside).
|
|
147
144
|
*
|
|
145
|
+
* Required for `auto` and `hint` modes - without it, browser
|
|
146
|
+
* dismissals leave the consumer's `isOpen` stuck at `true` while
|
|
147
|
+
* the DOM is hidden, producing a stale-open state.
|
|
148
|
+
*
|
|
148
149
|
* The `reason` field indicates how the dismiss occurred:
|
|
149
150
|
* - `'escape'`: the user pressed the Escape key.
|
|
150
151
|
* - `'light-dismiss'`: the user clicked outside (or another auto-dismiss).
|
|
151
152
|
*/
|
|
152
|
-
onClose
|
|
153
|
+
onClose: (args: {
|
|
153
154
|
reason: TPopoverCloseReason;
|
|
154
155
|
}) => void;
|
|
155
156
|
} | {
|
|
@@ -12,5 +12,11 @@ import { type TPopupSurfaceProps } from './types';
|
|
|
12
12
|
* should use `Popup.Content` without wrapping in `PopupSurface`.
|
|
13
13
|
*
|
|
14
14
|
* Exposed as `Popup.Surface` on the compound component.
|
|
15
|
+
*
|
|
16
|
+
* **Presentational primitive - `children`-only by design.** This component
|
|
17
|
+
* intentionally exposes no `style`, `className`, `xcss`, `id`, or `ref`
|
|
18
|
+
* props. If you need any of those, render your own wrapper element inside
|
|
19
|
+
* `Popup.Content` instead - `PopupSurface` is the no-config "give me the
|
|
20
|
+
* default ADS overlay look" surface, nothing more.
|
|
15
21
|
*/
|
|
16
22
|
export declare function PopupSurface({ children }: TPopupSurfaceProps): React.ReactElement;
|
|
@@ -38,10 +38,14 @@ export type TTriggerFunctionRenderProps = {
|
|
|
38
38
|
*
|
|
39
39
|
* **Note on `aria-haspopup`:** When the content's role maps to a specific
|
|
40
40
|
* popup type (`'menu'`, `'dialog'`, `'listbox'`, etc.), the corresponding
|
|
41
|
-
* string value is
|
|
42
|
-
*
|
|
43
|
-
*
|
|
44
|
-
*
|
|
41
|
+
* string value is emitted. For non-popup roles (`tooltip`, `note`,
|
|
42
|
+
* `status`, `alert`, `log`) the value is `undefined`, so React drops the
|
|
43
|
+
* attribute entirely - these triggers should not announce a popup.
|
|
44
|
+
*
|
|
45
|
+
* The value type (`TAriaHasPopupValue`) is internal and may narrow further
|
|
46
|
+
* in future minor versions. Do **not** extract it via `Parameters<…>`.
|
|
47
|
+
* Spread `ariaAttributes` directly onto the trigger; do not destructure
|
|
48
|
+
* and re-type.
|
|
45
49
|
*/
|
|
46
50
|
ariaAttributes: {
|
|
47
51
|
'aria-expanded': boolean;
|
|
@@ -53,7 +57,7 @@ type TPopupTriggerFunctionProps = {
|
|
|
53
57
|
/**
|
|
54
58
|
* Render-prop function that receives trigger props.
|
|
55
59
|
*
|
|
56
|
-
* Unlike `Popup.Trigger`, this does not use `cloneElement
|
|
60
|
+
* Unlike `Popup.Trigger`, this does not use `cloneElement`. The consumer
|
|
57
61
|
* is responsible for spreading ref, ARIA attributes, and attaching `toggle`
|
|
58
62
|
* to the appropriate event(s).
|
|
59
63
|
*
|
|
@@ -77,7 +81,7 @@ type TPopupTriggerFunctionProps = {
|
|
|
77
81
|
/**
|
|
78
82
|
* Render-prop alternative to `Popup.Trigger`.
|
|
79
83
|
*
|
|
80
|
-
* Use when you need full control over the trigger element
|
|
84
|
+
* Use when you need full control over the trigger element. For example,
|
|
81
85
|
* to compose your own trigger with custom event handlers, wrap a third-party
|
|
82
86
|
* component, or build a trigger from multiple elements.
|
|
83
87
|
*
|
|
@@ -1,23 +1,14 @@
|
|
|
1
1
|
import { type ReactNode } from 'react';
|
|
2
2
|
import { type TPopupTriggerProps } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* Wraps
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* Wraps a single trigger element via `cloneElement`. Attaches aria
|
|
5
|
+
* attributes, the toggle handler, and the anchor-name. `aria-haspopup`
|
|
6
|
+
* is derived from `Popup.Content`'s role via context.
|
|
7
7
|
*
|
|
8
|
-
*
|
|
9
|
-
* (
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
* **Limitation:** Uses `cloneElement` internally (via `Slot`), which is
|
|
14
|
-
* incompatible with Compiled's `css` prop on the direct child element.
|
|
15
|
-
* The `@jsx jsx` pragma transforms the child before `cloneElement` can
|
|
16
|
-
* inject `onClick` and `ref` onto the DOM node, preventing the popover
|
|
17
|
-
* from opening.
|
|
18
|
-
*
|
|
19
|
-
* If you need Compiled `css` on the trigger, use `Popup.TriggerFunction`
|
|
20
|
-
* instead - it hands you raw props via a render-prop and avoids
|
|
21
|
-
* `cloneElement` entirely.
|
|
8
|
+
* Child constraints: must be a single ref-forwarding element. The child's
|
|
9
|
+
* `onClick` is composed (runs after); other event handlers are NOT.
|
|
10
|
+
* Children using Compiled's `css` prop swallow injected props - use
|
|
11
|
+
* `Popup.TriggerFunction` for these cases or any time you need handler
|
|
12
|
+
* composition.
|
|
22
13
|
*/
|
|
23
14
|
export declare function PopupTrigger({ children }: TPopupTriggerProps): ReactNode;
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { type TPopupProps } from './types';
|
|
3
3
|
/**
|
|
4
|
-
* Popup compound
|
|
4
|
+
* Popup compound: trigger + popover content.
|
|
5
5
|
*
|
|
6
6
|
* Use when a button opens anchored content (dropdown, menu, dialog).
|
|
7
|
-
* The browser manages visibility via `togglePopover()
|
|
7
|
+
* The browser manages visibility via `togglePopover()`; the consumer
|
|
8
8
|
* never manages `isOpen`. For custom trigger lifecycles (hover, timers,
|
|
9
9
|
* external state), use `Popover` directly instead.
|
|
10
10
|
*
|
|
@@ -25,26 +25,27 @@ import { type TPopoverCloseReason, type TWidthFromAnchorMode } from '../popover/
|
|
|
25
25
|
* ```
|
|
26
26
|
*/
|
|
27
27
|
export { type TPlacementOptions } from '../internal/resolve-placement';
|
|
28
|
-
|
|
28
|
+
/**
|
|
29
|
+
* Props shared across all `Popup` modes.
|
|
30
|
+
*
|
|
31
|
+
* Mode-specific behaviour for `onClose` is encoded in the discriminated
|
|
32
|
+
* union below: `'auto'` and `'hint'` modes accept an `onClose` handler
|
|
33
|
+
* (called on light dismiss); `'manual'` mode forbids it (no light dismiss
|
|
34
|
+
* exists, so a handler would be dead code).
|
|
35
|
+
*/
|
|
36
|
+
type TPopupBaseProps = {
|
|
29
37
|
/**
|
|
30
38
|
* Position of the popup relative to the trigger. Only the Popup compound uses
|
|
31
39
|
* placement; the low-level Popover primitive does not.
|
|
40
|
+
*
|
|
41
|
+
* Defaults to `{}` which means "below the trigger, centered, with a
|
|
42
|
+
* `space.100` token gap".
|
|
32
43
|
*/
|
|
33
|
-
placement
|
|
44
|
+
placement?: TPlacementOptions;
|
|
34
45
|
/**
|
|
35
46
|
* Must contain `Popup.Trigger` and `Popup.Content`.
|
|
36
47
|
*/
|
|
37
48
|
children: ReactNode;
|
|
38
|
-
/**
|
|
39
|
-
* Called when the popup is dismissed via light dismiss.
|
|
40
|
-
*
|
|
41
|
-
* The `reason` field indicates how the dismiss occurred:
|
|
42
|
-
* - `'escape'`: the user pressed the Escape key.
|
|
43
|
-
* - `'light-dismiss'`: the user clicked outside (or another auto-dismiss).
|
|
44
|
-
*/
|
|
45
|
-
onClose: (args: {
|
|
46
|
-
reason: TPopoverCloseReason;
|
|
47
|
-
}) => void;
|
|
48
49
|
/**
|
|
49
50
|
* Called when the popup's open state changes.
|
|
50
51
|
*
|
|
@@ -67,14 +68,6 @@ export type TPopupProps = {
|
|
|
67
68
|
isOpen: boolean;
|
|
68
69
|
element: HTMLDivElement;
|
|
69
70
|
}) => void;
|
|
70
|
-
/**
|
|
71
|
-
* Native popover attribute value. Default is `'auto'`.
|
|
72
|
-
*
|
|
73
|
-
* - `'auto'`: light dismiss (Escape, click-outside). Only one `popover="auto"` can be open at a time; opening another closes the previous.
|
|
74
|
-
* - `'hint'`: allows ephemeral UI (e.g. tooltips) to open without closing other `popover="auto"` popovers. Falls back to `popover="auto"` when unsupported.
|
|
75
|
-
* - `'manual'`: no light dismiss; the consumer controls show/hide entirely. Escape and click-outside do not close the popover.
|
|
76
|
-
*/
|
|
77
|
-
mode?: 'auto' | 'hint' | 'manual';
|
|
78
71
|
/**
|
|
79
72
|
* Test ID applied to the popup content element.
|
|
80
73
|
*/
|
|
@@ -86,6 +79,49 @@ export type TPopupProps = {
|
|
|
86
79
|
*/
|
|
87
80
|
forceFallbackPositioning?: boolean;
|
|
88
81
|
};
|
|
82
|
+
/**
|
|
83
|
+
* Props for the `Popup` compound.
|
|
84
|
+
*
|
|
85
|
+
* Discriminated on `mode`:
|
|
86
|
+
* - `'auto'` (default) and `'hint'`: light dismiss is enabled; `onClose` is
|
|
87
|
+
* optional and is called when the browser dismisses the popover.
|
|
88
|
+
* - `'manual'`: no light dismiss; `onClose` is `never` since the consumer
|
|
89
|
+
* owns show/hide entirely and there is no dismiss event to handle.
|
|
90
|
+
*/
|
|
91
|
+
export type TPopupProps = TPopupBaseProps & ({
|
|
92
|
+
/**
|
|
93
|
+
* Native popover attribute value. Default is `'auto'`.
|
|
94
|
+
*
|
|
95
|
+
* - `'auto'`: light dismiss (Escape, click-outside). Only one
|
|
96
|
+
* `popover="auto"` can be open at a time; opening another closes
|
|
97
|
+
* the previous.
|
|
98
|
+
* - `'hint'`: allows ephemeral UI (e.g. tooltips) to open without
|
|
99
|
+
* closing other `popover="auto"` popovers. Falls back to
|
|
100
|
+
* `popover="auto"` when unsupported.
|
|
101
|
+
*/
|
|
102
|
+
mode?: 'auto' | 'hint';
|
|
103
|
+
/**
|
|
104
|
+
* Called when the popup is dismissed via light dismiss.
|
|
105
|
+
*
|
|
106
|
+
* The `reason` field indicates how the dismiss occurred:
|
|
107
|
+
* - `'escape'`: the user pressed the Escape key.
|
|
108
|
+
* - `'light-dismiss'`: the user clicked outside (or another auto-dismiss).
|
|
109
|
+
*/
|
|
110
|
+
onClose?: (args: {
|
|
111
|
+
reason: TPopoverCloseReason;
|
|
112
|
+
}) => void;
|
|
113
|
+
} | {
|
|
114
|
+
/**
|
|
115
|
+
* `'manual'`: no light dismiss; the consumer controls show/hide
|
|
116
|
+
* entirely. Escape and click-outside do not close the popover.
|
|
117
|
+
*/
|
|
118
|
+
mode: 'manual';
|
|
119
|
+
/**
|
|
120
|
+
* Manual mode has no dismiss event, so `onClose` is forbidden.
|
|
121
|
+
* The consumer owns show/hide via their own state.
|
|
122
|
+
*/
|
|
123
|
+
onClose?: never;
|
|
124
|
+
});
|
|
89
125
|
export type TPopupTriggerProps = {
|
|
90
126
|
/**
|
|
91
127
|
* The trigger element. Must accept a ref.
|
|
@@ -105,7 +141,7 @@ export type TPopupRole = TRoleRequiringAccessibleName | TRoleWithImplicitName;
|
|
|
105
141
|
*
|
|
106
142
|
* When used standalone (e.g. tooltip, spotlight), the consumer must provide `isOpen`
|
|
107
143
|
* to control visibility. If `animate` is provided, `isOpen` is required at the type
|
|
108
|
-
* level
|
|
144
|
+
* level. This ensures exit animations always have a controlled lifecycle.
|
|
109
145
|
*/
|
|
110
146
|
type TPopupContentBaseProps = {
|
|
111
147
|
children: ReactNode;
|
|
@@ -113,6 +149,16 @@ type TPopupContentBaseProps = {
|
|
|
113
149
|
* Ref to the underlying `<div popover>` element.
|
|
114
150
|
*/
|
|
115
151
|
ref?: Ref<HTMLDivElement>;
|
|
152
|
+
/**
|
|
153
|
+
* HTML `id` attribute for the popover element.
|
|
154
|
+
*
|
|
155
|
+
* Provide this when using `Popup.Content` standalone (outside the
|
|
156
|
+
* `<Popup>` compound). The consumer is responsible for wiring
|
|
157
|
+
* `aria-controls` on their own trigger to this same id. Inside the
|
|
158
|
+
* `<Popup>` compound, the id flows from context - passing it here is
|
|
159
|
+
* unnecessary.
|
|
160
|
+
*/
|
|
161
|
+
id?: string;
|
|
116
162
|
/**
|
|
117
163
|
* Controls the width of the popover relative to its anchor element.
|
|
118
164
|
*
|
|
@@ -197,7 +243,7 @@ type TPopupContentBaseProps = {
|
|
|
197
243
|
* Inside the `<Popup>` compound, `isOpen` is provided automatically via context
|
|
198
244
|
* (the browser manages state through `togglePopover()`).
|
|
199
245
|
*
|
|
200
|
-
* For standalone usage, provide `isOpen` to control visibility
|
|
246
|
+
* For standalone usage, provide `isOpen` to control visibility, especially
|
|
201
247
|
* when `animate` is set, so the exit animation lifecycle works correctly.
|
|
202
248
|
*
|
|
203
249
|
* @example
|
|
@@ -2,16 +2,16 @@ import { type RefObject } from 'react';
|
|
|
2
2
|
import { type TFocusableFilter } from '../focus';
|
|
3
3
|
/**
|
|
4
4
|
* Returns true if the element belongs to the current menu level of the
|
|
5
|
-
* container
|
|
5
|
+
* container, i.e. it is NOT inside a nested `role="menu"` sub-container.
|
|
6
6
|
*
|
|
7
7
|
* Uses `element.closest('[role="menu"]')` to determine the nearest menu
|
|
8
8
|
* scope. If the nearest scope is the container's own `role="menu"` element,
|
|
9
|
-
* the element belongs to this level. If it
|
|
9
|
+
* the element belongs to this level. If it is a different (nested) menu,
|
|
10
10
|
* the element belongs to a child level and should be excluded.
|
|
11
11
|
*
|
|
12
12
|
* Supports two container patterns:
|
|
13
13
|
*
|
|
14
|
-
* **1. Container has `role="menu"` directly** (preferred
|
|
14
|
+
* **1. Container has `role="menu"` directly** (preferred, used by avatar-group):
|
|
15
15
|
* ```
|
|
16
16
|
* <div ref={containerRef} role="menu">
|
|
17
17
|
* <button role="menuitem" /> ← isAtCurrentMenuLevel → true
|
|
@@ -23,7 +23,7 @@ import { type TFocusableFilter } from '../focus';
|
|
|
23
23
|
* Uses the simple check: `element.closest('[role="menu"]') === container`
|
|
24
24
|
*
|
|
25
25
|
* **2. Container is a wrapper without `role="menu"`** (used by dropdown-menu,
|
|
26
|
-
* where `MenuGroup` owns `role="menu"` but
|
|
26
|
+
* where `MenuGroup` owns `role="menu"` but does not accept a ref):
|
|
27
27
|
* ```
|
|
28
28
|
* <div ref={containerRef}> ← wrapper (no role="menu")
|
|
29
29
|
* <MenuGroup role="menu">
|
|
@@ -48,6 +48,20 @@ import { type TFocusableFilter } from '../focus';
|
|
|
48
48
|
* belong to a nested menu.
|
|
49
49
|
*/
|
|
50
50
|
export declare function isAtCurrentMenuLevel(element: Element, container: HTMLElement): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Args for `useArrowNavigation`.
|
|
53
|
+
*
|
|
54
|
+
* Keyboard contract:
|
|
55
|
+
* - `ArrowDown` / `ArrowUp` move within the current menu level.
|
|
56
|
+
* - `Home` / `End` jump to first / last.
|
|
57
|
+
* - `ArrowRight` / `ArrowLeft` opens / closes nested submenus.
|
|
58
|
+
* - `Tab` / `Shift+Tab` dismiss the menu (matching the ARIA APG menu pattern,
|
|
59
|
+
* plus Radix UI / Headless UI / React Aria / Floating UI conventions).
|
|
60
|
+
* Symmetric in both directions: there is no special-case for the last
|
|
61
|
+
* item that lets Tab leave the menu without dismissing it.
|
|
62
|
+
* - `Page Up` / `Page Down`: NOT handled - extend via your own listener if
|
|
63
|
+
* your menu needs page-style scrolling.
|
|
64
|
+
*/
|
|
51
65
|
export type TUseArrowNavigationArgs = {
|
|
52
66
|
/**
|
|
53
67
|
* Ref to the container element that holds the focusable items.
|
|
@@ -89,7 +103,7 @@ export type TUseArrowNavigationArgs = {
|
|
|
89
103
|
* When provided, only elements that pass the filter will be focused.
|
|
90
104
|
*
|
|
91
105
|
* The filter is also used as a guard on the currently focused element:
|
|
92
|
-
* if the focused element
|
|
106
|
+
* if the focused element does not pass the filter, the handler bails out.
|
|
93
107
|
* This prevents parent menu handlers from acting on events that belong
|
|
94
108
|
* to a nested menu.
|
|
95
109
|
*
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaskit/top-layer",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Low-level layering primitives based on popover and dialog",
|
|
5
5
|
"homepage": "https://atlassian.design/components/top-layer",
|
|
6
6
|
"repository": "https://bitbucket.org/atlassian/atlassian-frontend-mirror",
|
|
@@ -63,6 +63,8 @@
|
|
|
63
63
|
"@testing-library/jest-dom": "^6.4.5",
|
|
64
64
|
"@testing-library/react": "^16.3.0",
|
|
65
65
|
"@types/raf-schd": "^4.0.1",
|
|
66
|
+
"react": "^19.0.0",
|
|
67
|
+
"react-dom": "^19.0.0",
|
|
66
68
|
"tiny-invariant": "^1.2.0"
|
|
67
69
|
},
|
|
68
70
|
"techstack": {
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@atlaskit/top-layer/popover/create-close-event",
|
|
3
|
+
"main": "../../dist/cjs/entry-points/popover/create-close-event.js",
|
|
4
|
+
"module": "../../dist/esm/entry-points/popover/create-close-event.js",
|
|
5
|
+
"module:es2019": "../../dist/es2019/entry-points/popover/create-close-event.js",
|
|
6
|
+
"sideEffects": [
|
|
7
|
+
"*.compiled.css"
|
|
8
|
+
],
|
|
9
|
+
"types": "../../dist/types/entry-points/popover/create-close-event.d.ts",
|
|
10
|
+
"typesVersions": {
|
|
11
|
+
">=4.5 <5.9": {
|
|
12
|
+
"*": [
|
|
13
|
+
"../../dist/types-ts4.5/entry-points/popover/create-close-event.d.ts"
|
|
14
|
+
]
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
}
|