@atlaskit/top-layer 0.9.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 +26 -0
- package/README.md +5 -1
- package/dialog/create-close-event/package.json +17 -0
- package/dist/cjs/animations/presets.js +7 -4
- package/dist/cjs/arrow/index.js +131 -0
- package/dist/cjs/arrow/types.js +5 -0
- package/dist/cjs/dialog/dialog-content.js +11 -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 +71 -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 +107 -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 -111
- package/dist/cjs/placement-map/legacy-placements.js +113 -0
- package/dist/cjs/popover/popover.js +14 -12
- package/dist/cjs/popup/popup-content.js +19 -13
- 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 +26 -10
- package/dist/es2019/animations/presets.js +6 -3
- package/dist/es2019/arrow/index.js +269 -0
- package/dist/es2019/arrow/types.js +1 -0
- package/dist/es2019/dialog/dialog-content.js +11 -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 +56 -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 +95 -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 -109
- package/dist/es2019/placement-map/legacy-placements.js +107 -0
- package/dist/es2019/popover/popover.js +14 -11
- package/dist/es2019/popup/popup-content.js +20 -14
- 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 +26 -10
- package/dist/esm/animations/presets.js +6 -3
- package/dist/esm/arrow/index.js +124 -0
- package/dist/esm/arrow/types.js +1 -0
- package/dist/esm/dialog/dialog-content.js +11 -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 +70 -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 +108 -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 -109
- package/dist/esm/placement-map/legacy-placements.js +107 -0
- package/dist/esm/popover/popover.js +14 -12
- package/dist/esm/popup/popup-content.js +20 -14
- 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 +26 -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 +17 -17
- 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 +17 -17
- 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 +1 -1
- package/popover/create-close-event/package.json +17 -0
|
@@ -3,23 +3,21 @@ import { type TAnimationPreset } from '../animations/types';
|
|
|
3
3
|
/**
|
|
4
4
|
* Close reasons produced by the Dialog primitive.
|
|
5
5
|
*
|
|
6
|
-
* - `'escape'
|
|
7
|
-
* - `'overlay-click'
|
|
6
|
+
* - `'escape'`: user pressed Escape (native `cancel` event on `<dialog>`).
|
|
7
|
+
* - `'overlay-click'`: user clicked the backdrop / overlay area.
|
|
8
8
|
*
|
|
9
9
|
* Consumer-initiated ("programmatic") close is not a reason the primitive
|
|
10
|
-
* produces
|
|
10
|
+
* produces. The consumer simply sets `isOpen={false}`.
|
|
11
11
|
*/
|
|
12
12
|
export type TDialogCloseReason = 'escape' | 'overlay-click';
|
|
13
13
|
/**
|
|
14
|
-
* Props
|
|
14
|
+
* Props shared across `TDialogProps` variants.
|
|
15
15
|
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* background, border-radius, or layout. Consumers (e.g. `@atlaskit/modal-dialog`)
|
|
20
|
-
* provide their own visual styling.
|
|
16
|
+
* The accessible-name requirement (one of `label` or `labelledBy`) is encoded
|
|
17
|
+
* in the discriminated union below - WCAG 4.1.2 violations are caught at
|
|
18
|
+
* compile time instead of in production audit reports.
|
|
21
19
|
*/
|
|
22
|
-
|
|
20
|
+
type TDialogBaseProps = {
|
|
23
21
|
children: ReactNode;
|
|
24
22
|
/**
|
|
25
23
|
* Whether the dialog is open.
|
|
@@ -28,13 +26,13 @@ export type TDialogProps = {
|
|
|
28
26
|
* - `false`: calls `close()`. When an `animate` preset is provided, the exit
|
|
29
27
|
* animation plays (via `allow-discrete`) before the dialog becomes logically closed.
|
|
30
28
|
*
|
|
31
|
-
* The element stays mounted in the DOM
|
|
29
|
+
* The element stays mounted in the DOM. Visibility is controlled declaratively.
|
|
32
30
|
*/
|
|
33
31
|
isOpen: boolean;
|
|
34
32
|
/**
|
|
35
33
|
* Called when the user triggers close via Escape or backdrop click.
|
|
36
34
|
*
|
|
37
|
-
* The dialog does **not** close itself
|
|
35
|
+
* The dialog does **not** close itself. The consumer decides whether to
|
|
38
36
|
* set `isOpen={false}` (e.g. gate by reason).
|
|
39
37
|
*/
|
|
40
38
|
onClose: (args: {
|
|
@@ -61,32 +59,60 @@ export type TDialogProps = {
|
|
|
61
59
|
* HTML `id` attribute for the `<dialog>` element.
|
|
62
60
|
*/
|
|
63
61
|
id?: string;
|
|
62
|
+
/**
|
|
63
|
+
* When true, the `::backdrop` pseudo-element is rendered transparent.
|
|
64
|
+
*
|
|
65
|
+
* Useful for stacked dialogs where only the foreground dialog should
|
|
66
|
+
* show a visible backdrop, or when the consumer wants no overlay.
|
|
67
|
+
*/
|
|
68
|
+
shouldHideBackdrop?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Called after the exit animation completes (or immediately on close when
|
|
71
|
+
* there is no animation or reduced motion is active).
|
|
72
|
+
*
|
|
73
|
+
* Use this for external lifecycle coordination, e.g. firing an
|
|
74
|
+
* `onCloseComplete` callback or notifying ExitingPersistence.
|
|
75
|
+
*/
|
|
76
|
+
onExitFinish?: () => void;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Props for the `Dialog` primitive.
|
|
80
|
+
*
|
|
81
|
+
* Low-level wrapper around the native `<dialog>` element.
|
|
82
|
+
* Manages visibility (`showModal()` / `close()`), animation, Escape handling,
|
|
83
|
+
* and backdrop-click detection. Has no visual opinions - no width, height,
|
|
84
|
+
* background, border-radius, or layout. Consumers (e.g. `@atlaskit/modal-dialog`)
|
|
85
|
+
* provide their own visual styling.
|
|
86
|
+
*
|
|
87
|
+
* Discriminated on the accessible-name source: at least one of `label`
|
|
88
|
+
* (aria-label) or `labelledBy` (aria-labelledby) must be provided. This
|
|
89
|
+
* enforces WCAG 4.1.2 at the type level - an unlabelled dialog landmark
|
|
90
|
+
* is not constructible. Mirrors the pattern used by `TPopupContentProps`.
|
|
91
|
+
*/
|
|
92
|
+
export type TDialogProps = TDialogBaseProps & ({
|
|
64
93
|
/**
|
|
65
94
|
* Accessible label (`aria-label`).
|
|
66
95
|
*
|
|
67
96
|
* When provided, `aria-labelledby` is not set.
|
|
68
97
|
* Use when there is no visible title element to reference.
|
|
69
98
|
*/
|
|
70
|
-
label
|
|
99
|
+
label: string;
|
|
71
100
|
/**
|
|
72
101
|
* ID of the element that labels the dialog (`aria-labelledby`).
|
|
73
102
|
*
|
|
74
103
|
* Ignored when `label` is provided.
|
|
75
104
|
*/
|
|
76
105
|
labelledBy?: string;
|
|
106
|
+
} | {
|
|
77
107
|
/**
|
|
78
|
-
*
|
|
108
|
+
* Accessible label (`aria-label`).
|
|
79
109
|
*
|
|
80
|
-
*
|
|
81
|
-
* show a visible backdrop, or when the consumer wants no overlay.
|
|
110
|
+
* Optional when `labelledBy` is provided.
|
|
82
111
|
*/
|
|
83
|
-
|
|
112
|
+
label?: string;
|
|
84
113
|
/**
|
|
85
|
-
*
|
|
86
|
-
* there is no animation or reduced motion is active).
|
|
87
|
-
*
|
|
88
|
-
* Use this for external lifecycle coordination — e.g. firing an
|
|
89
|
-
* `onCloseComplete` callback or notifying ExitingPersistence.
|
|
114
|
+
* ID of the element that labels the dialog (`aria-labelledby`).
|
|
90
115
|
*/
|
|
91
|
-
|
|
92
|
-
};
|
|
116
|
+
labelledBy: string;
|
|
117
|
+
});
|
|
118
|
+
export {};
|
|
@@ -1,3 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @deprecated Combined entry-point retained for backwards-compatibility.
|
|
3
|
+
* Prefer the disjoint subpaths so that bundle analysis attributes the cost
|
|
4
|
+
* to the right consumer:
|
|
5
|
+
* - `@atlaskit/top-layer/dialog/create-close-event` for `createCloseEvent`
|
|
6
|
+
* - `@atlaskit/top-layer/popover/create-close-event` for `createPopoverCloseEvent`
|
|
7
|
+
*/
|
|
1
8
|
export { createCloseEvent } from '../dialog';
|
|
2
9
|
export { createPopoverCloseEvent } from '../popover/create-close-event';
|
|
3
10
|
export type { TDialogCloseReason } from '../dialog';
|
|
@@ -1,2 +1,3 @@
|
|
|
1
|
-
export { fromLegacyPlacement
|
|
1
|
+
export { fromLegacyPlacement } from '../placement-map';
|
|
2
|
+
export { LEGACY_PLACEMENTS } from '../placement-map/legacy-placements';
|
|
2
3
|
export type { TLegacyPlacement, TPlacementOptions } from '../placement-map';
|
|
@@ -9,6 +9,14 @@
|
|
|
9
9
|
* All public functions accept an optional `filter` callback to further
|
|
10
10
|
* restrict which focusable elements are included.
|
|
11
11
|
*/
|
|
12
|
+
/**
|
|
13
|
+
* Returns `true` when `document.activeElement` is inside a nested top-layer
|
|
14
|
+
* descendant of `container` (a `[popover]`, `<dialog>`, `[role="dialog"]` or
|
|
15
|
+
* `[role="alertdialog"]` that is itself a descendant of `container`).
|
|
16
|
+
*/
|
|
17
|
+
export declare function isNestedLayerFocused({ container }: {
|
|
18
|
+
container: HTMLElement;
|
|
19
|
+
}): boolean;
|
|
12
20
|
/**
|
|
13
21
|
* An optional callback to restrict which focusable elements are included.
|
|
14
22
|
* Return `true` to include the element, `false` to skip it.
|
|
@@ -8,13 +8,11 @@
|
|
|
8
8
|
* the browser do the math.
|
|
9
9
|
*
|
|
10
10
|
* The probe is appended to `container` so it inherits the same containing
|
|
11
|
-
* block, font size, and custom-property scope as the popover.
|
|
12
|
-
* because it accepts any CSS length, including negative `calc()` results
|
|
13
|
-
* (negative widths are clamped to 0 — see note below).
|
|
11
|
+
* block, font size, and custom-property scope as the popover.
|
|
14
12
|
*
|
|
15
|
-
* Cost: one synchronous reflow
|
|
16
|
-
*
|
|
17
|
-
*
|
|
13
|
+
* Cost: one synchronous reflow on first cacheable resolution per
|
|
14
|
+
* (container, value) pair, then a `WeakMap` lookup. Resolutions involving
|
|
15
|
+
* `var(` are intentionally not cached.
|
|
18
16
|
*/
|
|
19
17
|
export declare function resolveCssLengthToPixels({ value, container, }: {
|
|
20
18
|
value: number | string;
|
|
@@ -1,8 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Valid values for the `aria-haspopup` attribute.
|
|
3
|
-
*
|
|
3
|
+
*
|
|
4
|
+
* Derived from the HTML spec - maps popover roles to what the trigger
|
|
5
|
+
* announces. `undefined` means the attribute is omitted entirely (used for
|
|
6
|
+
* non-popup roles like `tooltip`/`status`/`alert`/`note`/`log` where
|
|
7
|
+
* `aria-haspopup` would be misleading).
|
|
8
|
+
*
|
|
9
|
+
* `true` is intentionally NOT in the union - the runtime only ever produces
|
|
10
|
+
* the explicit string forms, so widening the type would invite consumers to
|
|
11
|
+
* pass `true` and get an `aria-haspopup="true"` serialisation that the
|
|
12
|
+
* runtime no longer emits.
|
|
4
13
|
*/
|
|
5
|
-
export type TAriaHasPopupValue = 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' |
|
|
14
|
+
export type TAriaHasPopupValue = 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | undefined;
|
|
6
15
|
/**
|
|
7
16
|
* Roles that require an accessible name (`label` or `labelledBy`) per WCAG 4.1.2.
|
|
8
17
|
* Without a name, assistive technology cannot identify these landmarks.
|
|
@@ -33,7 +42,7 @@ type TAccessibleNameOptional = {
|
|
|
33
42
|
/**
|
|
34
43
|
* ARIA role props where a role is always required.
|
|
35
44
|
*
|
|
36
|
-
* Used by `TPopupContentProps
|
|
45
|
+
* Used by `TPopupContentProps`. Popup content must always declare
|
|
37
46
|
* its role so assistive technology can identify the layer.
|
|
38
47
|
*/
|
|
39
48
|
export type TAriaRoleRequired = ({
|
|
@@ -44,7 +53,7 @@ export type TAriaRoleRequired = ({
|
|
|
44
53
|
/**
|
|
45
54
|
* ARIA role props where a role is optional.
|
|
46
55
|
*
|
|
47
|
-
* Used by `TPopoverProps
|
|
56
|
+
* Used by `TPopoverProps`. The low-level primitive allows omitting
|
|
48
57
|
* the role for cases where it is set externally or not needed.
|
|
49
58
|
*/
|
|
50
59
|
export type TAriaRoleOptional = ({
|
|
@@ -55,8 +64,20 @@ export type TAriaRoleOptional = ({
|
|
|
55
64
|
/**
|
|
56
65
|
* Maps a popover content role to the correct `aria-haspopup` value
|
|
57
66
|
* for its trigger element.
|
|
67
|
+
*
|
|
68
|
+
* Returns `undefined` for roles that are not popups in the ARIA sense
|
|
69
|
+
* (`tooltip`, `note`, `status`, `alert`, `log`). Triggers for those roles
|
|
70
|
+
* should not announce a popup at all - emitting `aria-haspopup="dialog"`
|
|
71
|
+
* on a tooltip trigger would mislead assistive technology.
|
|
58
72
|
*/
|
|
59
73
|
export declare function roleToAriaHasPopup({ role, }: {
|
|
60
74
|
role: TRoleRequiringAccessibleName | TRoleWithImplicitName | undefined;
|
|
61
75
|
}): TAriaHasPopupValue;
|
|
76
|
+
/**
|
|
77
|
+
* Returns `true` when the given popover role moves focus into the popover
|
|
78
|
+
* on open, and `false` otherwise (including when `role` is `undefined`).
|
|
79
|
+
*/
|
|
80
|
+
export declare function shouldFocusIntoPopover({ role, }: {
|
|
81
|
+
role: TRoleRequiringAccessibleName | TRoleWithImplicitName | undefined;
|
|
82
|
+
}): boolean;
|
|
62
83
|
export {};
|
|
@@ -1,23 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Sets inline styles on an element and returns a cleanup function
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
* Uses `style.setProperty()` / `style.removeProperty()` so that
|
|
6
|
-
* hyphenated CSS property names (e.g. `position-area`, `anchor-name`)
|
|
7
|
-
* work correctly. These newer properties do not have camelCase
|
|
8
|
-
* mappings in `CSSStyleDeclaration` yet.
|
|
9
|
-
*
|
|
10
|
-
* @example
|
|
11
|
-
* ```ts
|
|
12
|
-
* const cleanup = setStyle({ el: popover, styles: [
|
|
13
|
-
* { property: 'position-anchor', value: '--my-anchor' },
|
|
14
|
-
* { property: 'position-area', value: 'block-end' },
|
|
15
|
-
* { property: 'margin', value: '0' },
|
|
16
|
-
* ] });
|
|
17
|
-
*
|
|
18
|
-
* // Later: removes all three properties
|
|
19
|
-
* cleanup();
|
|
20
|
-
* ```
|
|
2
|
+
* Sets inline styles on an element and returns a cleanup function that
|
|
3
|
+
* restores the prior inline values (so we do not stomp consumer styles).
|
|
21
4
|
*/
|
|
22
5
|
export declare function setStyle({ el, styles, }: {
|
|
23
6
|
el: HTMLElement;
|
|
@@ -14,7 +14,6 @@
|
|
|
14
14
|
*/
|
|
15
15
|
import { type RefObject } from 'react';
|
|
16
16
|
import { type TPlacementOptions } from '../internal/resolve-placement';
|
|
17
|
-
export { getPlacement } from './resolve-placement';
|
|
18
17
|
/**
|
|
19
18
|
* Resolves placement options to CSS `position-area` syntax.
|
|
20
19
|
*
|
|
@@ -59,7 +58,7 @@ export declare function placementToPositionArea({ placement }: {
|
|
|
59
58
|
* top-right), flipping only the primary axis (`flip-inline`) moves the popup
|
|
60
59
|
* to the left but keeps the same cross-axis span direction (e.g. upward),
|
|
61
60
|
* which is still off-screen. The combined keyword `flip-inline flip-block`
|
|
62
|
-
* mirrors the popup diagonally
|
|
61
|
+
* mirrors the popup diagonally. It flips BOTH the position-area AND both
|
|
63
62
|
* inline and block margins simultaneously, placing the popup at the
|
|
64
63
|
* diagonally opposite corner where there is always space.
|
|
65
64
|
*
|
|
@@ -74,7 +73,7 @@ export declare function placementToTryFallbacks({ placement }: {
|
|
|
74
73
|
* Hook that positions an element relative to an anchor element using
|
|
75
74
|
* CSS Anchor Positioning (with a JS fallback for older browsers).
|
|
76
75
|
*
|
|
77
|
-
* This hook is the positioning primitive
|
|
76
|
+
* This hook is the positioning primitive. It has no knowledge of popovers,
|
|
78
77
|
* visibility, or animation. Compose it with `Popover` for anchor-positioned
|
|
79
78
|
* top-layer content.
|
|
80
79
|
*
|
|
@@ -2,14 +2,15 @@ import { type RefObject } from 'react';
|
|
|
2
2
|
/**
|
|
3
3
|
* Moves focus into a popover element when it opens, based on its ARIA role.
|
|
4
4
|
*
|
|
5
|
-
*
|
|
5
|
+
* Follows the WAI-ARIA APG initial-focus patterns for each role:
|
|
6
6
|
* - `dialog` / `alertdialog` → focus first focusable (or `[autofocus]`)
|
|
7
7
|
* - `menu` → focus first menu item
|
|
8
8
|
* - `listbox` → focus selected or first option
|
|
9
|
-
* - `tooltip` / no role → no focus movement
|
|
9
|
+
* - `tooltip` / no role → no focus movement (focus must remain on trigger;
|
|
10
|
+
* moving focus into the tooltip would dismiss it)
|
|
10
11
|
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
12
|
+
* Role is taken from the typed `role` prop - this is the consumer's contract
|
|
13
|
+
* and is not subject to drift from a directly-mutated DOM attribute.
|
|
13
14
|
*
|
|
14
15
|
* Always call this hook unconditionally. Focus is only moved when `isOpen`
|
|
15
16
|
* transitions to `true` and the role requires it.
|
|
@@ -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,22 +41,8 @@ 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?: [along: number, away: number];
|
|
56
47
|
}): TPlacementOptions;
|
|
57
|
-
|
|
58
|
-
* The full mapping record, exposed for consumers that need to iterate or introspect.
|
|
59
|
-
*/
|
|
60
|
-
export { placementMapping };
|
|
61
|
-
export type { TPlacementOptions };
|
|
48
|
+
export type { TLegacyPlacement, TPlacementOptions };
|
|
@@ -0,0 +1,21 @@
|
|
|
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 ["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"];
|
|
10
|
+
export type TLegacyPlacement = (typeof LEGACY_PLACEMENTS)[number];
|
|
11
|
+
/**
|
|
12
|
+
* The full mapping record. Internal - use `fromLegacyPlacement` from the
|
|
13
|
+
* public entry-point so the offset-tuple translation is applied consistently.
|
|
14
|
+
*
|
|
15
|
+
* Note: `auto`, `auto-start`, `auto-end` map to `block-end` placements. This
|
|
16
|
+
* is a reduction in expressiveness vs Popper.js (which picked the best
|
|
17
|
+
* placement at runtime). CSS `position-try-fallbacks` flips at the edge but
|
|
18
|
+
* the initial placement is fixed. Migration consumers who relied on Popper's
|
|
19
|
+
* dynamic auto-flip should pick an explicit placement instead.
|
|
20
|
+
*/
|
|
21
|
+
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,7 +1,7 @@
|
|
|
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
7
|
* The reason a popover was closed.
|
|
@@ -31,13 +31,6 @@ export type TPopoverForwardedProps = TPopoverBaseProps & {
|
|
|
31
31
|
label?: string;
|
|
32
32
|
labelledBy?: string;
|
|
33
33
|
};
|
|
34
|
-
/**
|
|
35
|
-
* Alias for TPopoverForwardedProps.
|
|
36
|
-
*
|
|
37
|
-
* Used internally by PopupContent to forward props to Popover without
|
|
38
|
-
* re-proving the discriminated union at each call site.
|
|
39
|
-
*/
|
|
40
|
-
export type TPopoverInternalProps = TPopoverForwardedProps;
|
|
41
34
|
type TPopoverBaseProps = {
|
|
42
35
|
children: ReactNode;
|
|
43
36
|
/**
|
|
@@ -70,12 +63,12 @@ type TPopoverBaseProps = {
|
|
|
70
63
|
* animation plays (via `allow-discrete`) before the popover becomes logically closed.
|
|
71
64
|
* Otherwise hides instantly.
|
|
72
65
|
*
|
|
73
|
-
* 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
|
|
74
67
|
* conditionally render it. Visibility is driven by this prop.
|
|
75
68
|
*
|
|
76
69
|
* **Important:** For `mode="auto"` popovers, the browser can dismiss the popover
|
|
77
70
|
* via light dismiss (Escape, click outside) independently of this prop. When that
|
|
78
|
-
* happens, `onClose` is called
|
|
71
|
+
* happens, `onClose` is called and the consumer should respond by setting `isOpen`
|
|
79
72
|
* to `false`. If `isOpen` remains `true` after a browser dismiss, the DOM and
|
|
80
73
|
* React state will be out of sync (the popover will be hidden despite `isOpen={true}`).
|
|
81
74
|
*/
|
|
@@ -109,14 +102,14 @@ type TPopoverBaseProps = {
|
|
|
109
102
|
* called to set CSS custom properties (like `--ds-popover-tx`, `--ds-popover-ty`)
|
|
110
103
|
* that control the slide direction. Has no effect without `animate`.
|
|
111
104
|
*
|
|
112
|
-
* This does NOT control positioning
|
|
105
|
+
* This does NOT control positioning. Use `useAnchorPosition` for that.
|
|
113
106
|
*/
|
|
114
107
|
placement?: TPlacementOptions;
|
|
115
108
|
/**
|
|
116
109
|
* Called after the exit animation completes (or immediately on close when
|
|
117
110
|
* there is no animation or reduced motion is active).
|
|
118
111
|
*
|
|
119
|
-
* Use this for external lifecycle coordination
|
|
112
|
+
* Use this for external lifecycle coordination, e.g. notifying a manager
|
|
120
113
|
* that the hide sequence is finished, or firing an `onCloseComplete` callback.
|
|
121
114
|
*/
|
|
122
115
|
onExitFinish?: () => void;
|
|
@@ -124,7 +117,7 @@ type TPopoverBaseProps = {
|
|
|
124
117
|
/**
|
|
125
118
|
* Unopinionated top-layer primitive.
|
|
126
119
|
*
|
|
127
|
-
* `Popover` manages only top-layer visibility and animation
|
|
120
|
+
* `Popover` manages only top-layer visibility and animation. It has no
|
|
128
121
|
* knowledge of positioning. For anchor positioning, compose with the
|
|
129
122
|
* `useAnchorPosition` hook separately.
|
|
130
123
|
*
|
|
@@ -135,22 +128,29 @@ type TPopoverBaseProps = {
|
|
|
135
128
|
* Dismiss behavior:
|
|
136
129
|
* - `'auto'` (default): Escape to close, click-outside to close, focus restoration,
|
|
137
130
|
* automatic nesting, mutual exclusivity.
|
|
138
|
-
* - `'hint'`: ephemeral UI (e.g. tooltips) that
|
|
139
|
-
* 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.
|
|
140
136
|
* - `'manual'`: no light dismiss. Consumer controls show/hide entirely. Only
|
|
141
137
|
* appropriate for persistent UI (e.g. flags, banners).
|
|
142
138
|
*/
|
|
143
|
-
export type TPopoverProps = TPopoverBaseProps &
|
|
139
|
+
export type TPopoverProps = TPopoverBaseProps & TAriaRoleRequired & ({
|
|
144
140
|
mode?: 'auto' | 'hint';
|
|
145
141
|
/**
|
|
146
142
|
* Called when the popover is dismissed via light dismiss
|
|
147
143
|
* (Escape, click outside).
|
|
148
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
|
+
*
|
|
149
149
|
* The `reason` field indicates how the dismiss occurred:
|
|
150
150
|
* - `'escape'`: the user pressed the Escape key.
|
|
151
151
|
* - `'light-dismiss'`: the user clicked outside (or another auto-dismiss).
|
|
152
152
|
*/
|
|
153
|
-
onClose
|
|
153
|
+
onClose: (args: {
|
|
154
154
|
reason: TPopoverCloseReason;
|
|
155
155
|
}) => void;
|
|
156
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
|
*
|