@atlaskit/top-layer 4.4.5 → 5.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +41 -0
- package/README.md +13 -4
- package/dist/cjs/dialog/dialog-content.js +2 -0
- package/dist/cjs/entry-points/use-popover-id.js +5 -10
- package/dist/cjs/internal/anchor-positioning/apply-anchor-positioning.js +86 -0
- package/dist/cjs/internal/anchor-positioning/cross-axis-shift-margins.js +34 -0
- package/dist/cjs/internal/anchor-positioning/edge-margin.js +21 -0
- package/dist/cjs/internal/anchor-positioning/fit-margins.js +77 -0
- package/dist/cjs/internal/anchor-positioning/get-existing-anchor-name.js +18 -0
- package/dist/cjs/internal/{placement-to-position-area.js → anchor-positioning/placement-to-position-area.js} +11 -11
- package/dist/cjs/internal/anchor-positioning/placement-to-try-fallbacks.js +95 -0
- package/dist/cjs/internal/anchored-popover-size.js +345 -0
- package/dist/cjs/internal/get-aria-for-trigger.js +7 -13
- package/dist/cjs/internal/{anchor-positioning-fallback.js → javascript-fallback/anchor-positioning-fallback.js} +12 -33
- package/dist/cjs/internal/javascript-fallback/apply-javascript-fallback-positioning.js +297 -0
- package/dist/cjs/internal/javascript-fallback/resolve-css-length-to-pixels.js +90 -0
- package/dist/cjs/internal/javascript-fallback/warn-fallback-failure.js +19 -0
- package/dist/cjs/internal/resolve-placement.js +14 -6
- package/dist/cjs/internal/supports-anchor-positioning.js +17 -0
- package/dist/cjs/internal/supports-anchor-size.js +17 -0
- package/dist/cjs/internal/supports-css-declaration.js +25 -0
- package/dist/cjs/internal/surface-reset.js +5 -0
- package/dist/cjs/internal/use-anchored-popover-at-point.js +124 -0
- package/dist/cjs/internal/use-anchored-popover.js +277 -0
- package/dist/cjs/popover/popover.compiled.css +4 -0
- package/dist/cjs/popover/popover.js +11 -4
- package/dist/cjs/testing/polyfill.js +6 -7
- package/dist/es2019/dialog/dialog-content.js +2 -0
- package/dist/es2019/entry-points/use-popover-id.js +6 -10
- package/dist/es2019/internal/anchor-positioning/apply-anchor-positioning.js +83 -0
- package/dist/es2019/internal/anchor-positioning/cross-axis-shift-margins.js +29 -0
- package/dist/es2019/internal/anchor-positioning/edge-margin.js +18 -0
- package/dist/es2019/internal/anchor-positioning/fit-margins.js +69 -0
- package/dist/es2019/internal/anchor-positioning/get-existing-anchor-name.js +12 -0
- package/dist/es2019/internal/{placement-to-position-area.js → anchor-positioning/placement-to-position-area.js} +9 -9
- package/dist/es2019/internal/anchor-positioning/placement-to-try-fallbacks.js +94 -0
- package/dist/es2019/internal/anchored-popover-size.js +343 -0
- package/dist/es2019/internal/get-aria-for-trigger.js +7 -13
- package/dist/es2019/internal/{anchor-positioning-fallback.js → javascript-fallback/anchor-positioning-fallback.js} +12 -33
- package/dist/es2019/internal/javascript-fallback/apply-javascript-fallback-positioning.js +291 -0
- package/dist/es2019/internal/javascript-fallback/resolve-css-length-to-pixels.js +87 -0
- package/dist/es2019/internal/javascript-fallback/warn-fallback-failure.js +14 -0
- package/dist/es2019/internal/resolve-placement.js +14 -6
- package/dist/es2019/internal/supports-anchor-positioning.js +12 -0
- package/dist/es2019/internal/supports-anchor-size.js +12 -0
- package/dist/es2019/internal/supports-css-declaration.js +20 -0
- package/dist/es2019/internal/surface-reset.js +1 -0
- package/dist/es2019/internal/use-anchored-popover-at-point.js +116 -0
- package/dist/es2019/internal/use-anchored-popover.js +265 -0
- package/dist/es2019/popover/popover.compiled.css +4 -0
- package/dist/es2019/popover/popover.js +11 -4
- package/dist/es2019/testing/polyfill.js +6 -7
- package/dist/esm/dialog/dialog-content.js +2 -0
- package/dist/esm/entry-points/use-popover-id.js +6 -10
- package/dist/esm/internal/anchor-positioning/apply-anchor-positioning.js +80 -0
- package/dist/esm/internal/anchor-positioning/cross-axis-shift-margins.js +28 -0
- package/dist/esm/internal/anchor-positioning/edge-margin.js +15 -0
- package/dist/esm/internal/anchor-positioning/fit-margins.js +71 -0
- package/dist/esm/internal/anchor-positioning/get-existing-anchor-name.js +12 -0
- package/dist/esm/internal/{placement-to-position-area.js → anchor-positioning/placement-to-position-area.js} +11 -12
- package/dist/esm/internal/anchor-positioning/placement-to-try-fallbacks.js +89 -0
- package/dist/esm/internal/anchored-popover-size.js +338 -0
- package/dist/esm/internal/get-aria-for-trigger.js +7 -13
- package/dist/esm/internal/{anchor-positioning-fallback.js → javascript-fallback/anchor-positioning-fallback.js} +12 -33
- package/dist/esm/internal/javascript-fallback/apply-javascript-fallback-positioning.js +290 -0
- package/dist/esm/internal/javascript-fallback/resolve-css-length-to-pixels.js +85 -0
- package/dist/esm/internal/javascript-fallback/warn-fallback-failure.js +13 -0
- package/dist/esm/internal/resolve-placement.js +14 -6
- package/dist/esm/internal/supports-anchor-positioning.js +12 -0
- package/dist/esm/internal/supports-anchor-size.js +12 -0
- package/dist/esm/internal/supports-css-declaration.js +19 -0
- package/dist/esm/internal/surface-reset.js +1 -0
- package/dist/esm/internal/use-anchored-popover-at-point.js +118 -0
- package/dist/esm/internal/use-anchored-popover.js +271 -0
- package/dist/esm/popover/popover.compiled.css +4 -0
- package/dist/esm/popover/popover.js +11 -4
- package/dist/esm/testing/polyfill.js +6 -7
- package/dist/types/entry-points/placement-map.d.ts +2 -2
- package/dist/types/entry-points/use-popover-id.d.ts +3 -7
- package/dist/types/internal/anchor-positioning/apply-anchor-positioning.d.ts +26 -0
- package/dist/types/internal/anchor-positioning/cross-axis-shift-margins.d.ts +19 -0
- package/dist/types/internal/anchor-positioning/edge-margin.d.ts +10 -0
- package/dist/types/internal/anchor-positioning/fit-margins.d.ts +30 -0
- package/dist/types/internal/anchor-positioning/get-existing-anchor-name.d.ts +8 -0
- package/dist/types/internal/{placement-to-position-area.d.ts → anchor-positioning/placement-to-position-area.d.ts} +10 -6
- package/dist/types/internal/anchor-positioning/placement-to-try-fallbacks.d.ts +30 -0
- package/dist/types/internal/anchored-popover-size.d.ts +126 -0
- package/dist/types/internal/get-aria-for-trigger.d.ts +13 -25
- package/dist/types/internal/javascript-fallback/anchor-positioning-fallback.d.ts +36 -0
- package/dist/types/internal/javascript-fallback/apply-javascript-fallback-positioning.d.ts +15 -0
- package/dist/types/internal/javascript-fallback/resolve-css-length-to-pixels.d.ts +20 -0
- package/dist/types/internal/javascript-fallback/warn-fallback-failure.d.ts +7 -0
- package/dist/types/internal/resolve-placement.d.ts +18 -2
- package/dist/types/internal/supports-anchor-positioning.d.ts +5 -0
- package/dist/types/internal/supports-anchor-size.d.ts +5 -0
- package/dist/types/internal/supports-css-declaration.d.ts +11 -0
- package/dist/types/internal/surface-reset.d.ts +25 -0
- package/dist/types/internal/use-anchored-popover-at-point.d.ts +48 -0
- package/dist/types/internal/use-anchored-popover.d.ts +143 -0
- package/dist/types/popover/index.d.ts +2 -1
- package/dist/types/popover/popover.d.ts +1 -1
- package/dist/types/popover/types.d.ts +15 -17
- package/dist/types/testing/polyfill.d.ts +3 -3
- package/package.json +2 -2
- package/use-anchored-popover/package.json +10 -0
- package/use-anchored-popover-at-point/package.json +10 -0
- package/dist/cjs/internal/placement-to-try-fallbacks.js +0 -108
- package/dist/cjs/internal/resolve-css-length-to-pixels.js +0 -104
- package/dist/cjs/internal/use-anchor-position-at-point.js +0 -129
- package/dist/cjs/internal/use-anchor-position.js +0 -501
- package/dist/cjs/internal/use-width-from-anchor.js +0 -124
- package/dist/es2019/internal/placement-to-try-fallbacks.js +0 -108
- package/dist/es2019/internal/resolve-css-length-to-pixels.js +0 -101
- package/dist/es2019/internal/use-anchor-position-at-point.js +0 -124
- package/dist/es2019/internal/use-anchor-position.js +0 -480
- package/dist/es2019/internal/use-width-from-anchor.js +0 -120
- package/dist/esm/internal/placement-to-try-fallbacks.js +0 -103
- package/dist/esm/internal/resolve-css-length-to-pixels.js +0 -98
- package/dist/esm/internal/use-anchor-position-at-point.js +0 -124
- package/dist/esm/internal/use-anchor-position.js +0 -494
- package/dist/esm/internal/use-width-from-anchor.js +0 -118
- package/dist/types/internal/anchor-positioning-fallback.d.ts +0 -51
- package/dist/types/internal/placement-to-try-fallbacks.d.ts +0 -13
- package/dist/types/internal/resolve-css-length-to-pixels.d.ts +0 -20
- package/dist/types/internal/use-anchor-position-at-point.d.ts +0 -67
- package/dist/types/internal/use-anchor-position.d.ts +0 -87
- package/dist/types/internal/use-width-from-anchor.d.ts +0 -19
- package/use-anchor-position/package.json +0 -10
- package/use-anchor-position-at-point/package.json +0 -10
- package/use-width-from-anchor/package.json +0 -10
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { type TPlacement, type TPlacementAxis } from './resolve-placement';
|
|
2
|
+
import { type TStyleDeclaration } from './set-style';
|
|
3
|
+
/**
|
|
4
|
+
* The space kept clear between a popover and the viewport edge. Matches legacy
|
|
5
|
+
* `@atlaskit/popper`'s `preventOverflow` padding of `5`.
|
|
6
|
+
*/
|
|
7
|
+
export declare const VIEWPORT_PADDING = "5px";
|
|
8
|
+
/**
|
|
9
|
+
* The upper bound for the default placement-axis floor while fitting. A capped
|
|
10
|
+
* popover never overflows, so it never flips; this floor makes the margin box
|
|
11
|
+
* overflow a too-small cell so `position-try-fallbacks` fires. A flip driver and
|
|
12
|
+
* nothing else, so the JavaScript fallback, which has no cell to overflow, never
|
|
13
|
+
* writes it. See `getPlacementAxisFloor`.
|
|
14
|
+
*
|
|
15
|
+
* 150px is the value the flip was measured with, not a design constant
|
|
16
|
+
* (`notes/plans/should-fit-viewport.md`). Deliberately not a `space.*` token:
|
|
17
|
+
* theming it would move the flip threshold, and so change which side a popover
|
|
18
|
+
* lands on.
|
|
19
|
+
*/
|
|
20
|
+
export declare const FALLBACK_MINIMUM_MAIN_AXIS_SIZE = "150px";
|
|
21
|
+
/**
|
|
22
|
+
* Which way the POPOVER's inline axis runs; `'vertical'` covers the `vertical-*`
|
|
23
|
+
* and `sideways-*` writing modes. Measured rather than assumed, because every
|
|
24
|
+
* logical property this module writes resolves against the popover's own writing
|
|
25
|
+
* mode, and so must the viewport unit paired with it.
|
|
26
|
+
*/
|
|
27
|
+
export type TPopoverWritingMode = 'horizontal' | 'vertical';
|
|
28
|
+
/**
|
|
29
|
+
* How one axis of an anchored popover is sized. Both axes take these four values
|
|
30
|
+
* under identical rules.
|
|
31
|
+
*
|
|
32
|
+
* - `'content'`: sized by its content. Named after `flex-basis: content`; NOT
|
|
33
|
+
* `'auto'`, whose CSS meaning for a positioned box is shrink-to-fit, the very
|
|
34
|
+
* behaviour rule 4 removes.
|
|
35
|
+
* - `'match-anchor'`: exactly the anchor's size on this axis.
|
|
36
|
+
* - `'min-anchor'`: at least the anchor's size on this axis, free to grow.
|
|
37
|
+
* - `'max-available'`: at most the space between the anchor and the viewport
|
|
38
|
+
* edge, content-sized below that. Capped by the `position-area` cell on the
|
|
39
|
+
* placement axis and by the viewport on the cross axis (a `span-*` cell is
|
|
40
|
+
* narrower than the viewport, so capping to it would wrap content that fits on
|
|
41
|
+
* screen).
|
|
42
|
+
*
|
|
43
|
+
* Four rules apply on top:
|
|
44
|
+
*
|
|
45
|
+
* 1. Fitting one axis fills a `'content'` other axis with `'max-available'` too.
|
|
46
|
+
* An explicit value is never overridden, so caps stay strictly per-axis.
|
|
47
|
+
* 2. Fitting either axis floors the placement axis, because flipping is a
|
|
48
|
+
* whole-popover outcome. See `getPlacementAxisFloor`.
|
|
49
|
+
* 3. The viewport cap is unconditional, so a non-fitting axis still cannot
|
|
50
|
+
* overhang the screen. `'max-available'` and `'content'` are therefore
|
|
51
|
+
* indistinguishable on the cross axis.
|
|
52
|
+
* 4. A non-anchor-relative inline axis gets `inline-size: max-content`. Under
|
|
53
|
+
* `position-area` the containing block is the cell, so a CSS `auto` inline
|
|
54
|
+
* size shrink-to-fits a too-narrow cell and WRAPS into it, never overflowing
|
|
55
|
+
* and so never sliding to the roomier side. The caps still beat it, because a
|
|
56
|
+
* max beats a definite size. Not needed on the block axis, which does not
|
|
57
|
+
* wrap, nor on the JavaScript fallback, whose containing block is the
|
|
58
|
+
* viewport. Consumers opt out with `shouldPreserveInlineSize`.
|
|
59
|
+
*
|
|
60
|
+
* See `notes/decisions/fit-available-space.md`.
|
|
61
|
+
*/
|
|
62
|
+
export type TPopoverAxisSize = 'content' | 'match-anchor' | 'min-anchor' | 'max-available';
|
|
63
|
+
/**
|
|
64
|
+
* Narrowed rather than `string`, so a typo cannot reach `setStyle` as a
|
|
65
|
+
* silently-ignored property name.
|
|
66
|
+
*/
|
|
67
|
+
export type TPopoverSizeProperty = `${TPlacementAxis}-size` | `min-${TPlacementAxis}-size` | `max-${TPlacementAxis}-size`;
|
|
68
|
+
/**
|
|
69
|
+
* The anchor's size along each axis, as a CSS length. `null` when nothing needs
|
|
70
|
+
* it, so the measurement is skipped.
|
|
71
|
+
*
|
|
72
|
+
* The CSS path uses the `self-` keywords, whose axes are the POPOVER's, so each
|
|
73
|
+
* value matches the axis of the property it is set on (`anchor-size(inline)` and
|
|
74
|
+
* `anchor-size(width)` are both silently wrong in a vertical writing mode). The
|
|
75
|
+
* JavaScript fallback uses a measured pixel length, because `anchor-size()` needs
|
|
76
|
+
* a `position-anchor` that path never sets. See
|
|
77
|
+
* `notes/decisions/width-from-anchor-floors.md`.
|
|
78
|
+
*/
|
|
79
|
+
export type TAnchorSizeValues = Record<TPlacementAxis, string | null>;
|
|
80
|
+
/**
|
|
81
|
+
* The whole size recipe for an anchored popover, in one place. Pure, so the truth
|
|
82
|
+
* table is unit-testable without a browser, and every size property on the
|
|
83
|
+
* popover host has exactly one writer.
|
|
84
|
+
*
|
|
85
|
+
* While anything is fitting on the CSS path, the placement-axis floor is never
|
|
86
|
+
* clamped to the CELL cap. Its whole job is to exceed it: overflow detection
|
|
87
|
+
* reads the margin box AFTER the clamp (css-anchor-position-1 §6.5), so
|
|
88
|
+
* `min(floor, cap)` suppresses `position-try-fallbacks` entirely. The cross-axis
|
|
89
|
+
* floor is always clamped, because there it is a size contract rather than a flip
|
|
90
|
+
* driver.
|
|
91
|
+
*
|
|
92
|
+
* See `notes/decisions/fit-available-space.md` for the full recipe and the
|
|
93
|
+
* measured evidence.
|
|
94
|
+
*/
|
|
95
|
+
export declare function getAnchoredPopoverSizeDeclarations({ placement, inlineSize, blockSize, isUsingCssAnchorPositioning, anchorSize, writingMode, shouldPreserveInlineSize, }: {
|
|
96
|
+
/**
|
|
97
|
+
* Supplies the axis, the gap and `minSize`.
|
|
98
|
+
*/
|
|
99
|
+
placement: TPlacement;
|
|
100
|
+
/**
|
|
101
|
+
* The requested size, before rule 1 fills a `'content'` axis.
|
|
102
|
+
*/
|
|
103
|
+
inlineSize: TPopoverAxisSize;
|
|
104
|
+
/**
|
|
105
|
+
* The requested size, before rule 1 fills a `'content'` axis.
|
|
106
|
+
*/
|
|
107
|
+
blockSize: TPopoverAxisSize;
|
|
108
|
+
/**
|
|
109
|
+
* `false` on the JavaScript fallback path, which has no position-area cell, so
|
|
110
|
+
* both axes get the viewport cap and no flip floor is written.
|
|
111
|
+
*/
|
|
112
|
+
isUsingCssAnchorPositioning: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Already resolved for the active path. See `TAnchorSizeValues`.
|
|
115
|
+
*/
|
|
116
|
+
anchorSize: TAnchorSizeValues;
|
|
117
|
+
/**
|
|
118
|
+
* Picks the physical viewport unit for each logical axis. See `viewportUnit`.
|
|
119
|
+
*/
|
|
120
|
+
writingMode: TPopoverWritingMode;
|
|
121
|
+
/**
|
|
122
|
+
* `true` skips rule 4, for an element the consumer owns and may have given a
|
|
123
|
+
* `width` that an inline `max-content` would override.
|
|
124
|
+
*/
|
|
125
|
+
shouldPreserveInlineSize?: boolean;
|
|
126
|
+
}): TStyleDeclaration<TPopoverSizeProperty>[];
|
|
@@ -8,32 +8,20 @@ import { type TRoleRequiringAccessibleName } from './role-types';
|
|
|
8
8
|
* manually for tooltip triggers.
|
|
9
9
|
*/
|
|
10
10
|
type TAriaForTriggerRole = TRoleRequiringAccessibleName | 'listbox' | 'tree' | 'grid';
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
* the explicit string forms, so widening the type would invite consumers to
|
|
21
|
-
* pass `true` and get an `aria-haspopup="true"` serialisation that the
|
|
22
|
-
* runtime no longer emits.
|
|
23
|
-
*/
|
|
24
|
-
type TAriaHasPopupValue = 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | undefined;
|
|
25
|
-
/**
|
|
26
|
-
* Non-undefined subset of `TAriaHasPopupValue`. Every role accepted by
|
|
27
|
-
* `getAriaForTrigger` maps to a concrete `aria-haspopup` string, so the
|
|
28
|
-
* trigger always receives a defined attribute value.
|
|
29
|
-
*/
|
|
30
|
-
type TAriaHasPopupForTrigger = Exclude<TAriaHasPopupValue, undefined>;
|
|
31
|
-
type TGetAriaForTriggerOptions = {
|
|
11
|
+
type TAriaHasPopupByRole = {
|
|
12
|
+
dialog: 'dialog';
|
|
13
|
+
alertdialog: 'dialog';
|
|
14
|
+
menu: 'menu';
|
|
15
|
+
listbox: 'listbox';
|
|
16
|
+
tree: 'tree';
|
|
17
|
+
grid: 'grid';
|
|
18
|
+
};
|
|
19
|
+
type TGetAriaForTriggerOptions<TRole extends TAriaForTriggerRole> = {
|
|
32
20
|
/**
|
|
33
21
|
* The `role` that will be set on the `<Popover>` element. Used to derive
|
|
34
22
|
* the correct `aria-haspopup` value for the trigger.
|
|
35
23
|
*/
|
|
36
|
-
role:
|
|
24
|
+
role: TRole;
|
|
37
25
|
/**
|
|
38
26
|
* Whether the popover is currently open. Drives `aria-expanded`.
|
|
39
27
|
*/
|
|
@@ -44,8 +32,8 @@ type TGetAriaForTriggerOptions = {
|
|
|
44
32
|
*/
|
|
45
33
|
popoverId: string;
|
|
46
34
|
};
|
|
47
|
-
type TAriaForTrigger = {
|
|
48
|
-
'aria-haspopup':
|
|
35
|
+
type TAriaForTrigger<TRole extends TAriaForTriggerRole> = {
|
|
36
|
+
'aria-haspopup': TAriaHasPopupByRole[TRole];
|
|
49
37
|
'aria-expanded': boolean;
|
|
50
38
|
/**
|
|
51
39
|
* `aria-controls` is `undefined` while the popover is closed, because
|
|
@@ -102,5 +90,5 @@ type TAriaForTrigger = {
|
|
|
102
90
|
* );
|
|
103
91
|
* ```
|
|
104
92
|
*/
|
|
105
|
-
export declare function getAriaForTrigger({ role, isOpen, popoverId, }: TGetAriaForTriggerOptions): TAriaForTrigger
|
|
93
|
+
export declare function getAriaForTrigger<TRole extends TAriaForTriggerRole>({ role, isOpen, popoverId, }: TGetAriaForTriggerOptions<TRole>): TAriaForTrigger<TRole>;
|
|
106
94
|
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type TCrossAxisShiftDirection, type TPlacement } from '../resolve-placement';
|
|
2
|
+
/**
|
|
3
|
+
* A viewport-relative position, in pixels. Physical rather than logical
|
|
4
|
+
* because it is written straight to `top` / `left`.
|
|
5
|
+
*/
|
|
6
|
+
type TPosition = {
|
|
7
|
+
top: number;
|
|
8
|
+
left: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* `TCrossAxisShiftOffset` with its CSS length already resolved to pixels. Only
|
|
12
|
+
* this module needs the pixel form, because only this module does arithmetic.
|
|
13
|
+
*/
|
|
14
|
+
type TResolvedCrossAxisShift = {
|
|
15
|
+
value: number;
|
|
16
|
+
direction: TCrossAxisShiftDirection;
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* Computes the popover position from the trigger rect and viewport, flipping to
|
|
20
|
+
* the side with more space when needed.
|
|
21
|
+
*
|
|
22
|
+
* `gap` and `crossAxisShift` arrive already resolved to pixels (see
|
|
23
|
+
* `resolveCssLengthToPixels`), so this stays purely numeric.
|
|
24
|
+
*/
|
|
25
|
+
export declare function computeFallbackPosition({ triggerRect, popoverEl, placement, viewport, gap, crossAxisShift, }: {
|
|
26
|
+
triggerRect: DOMRect;
|
|
27
|
+
popoverEl: HTMLElement;
|
|
28
|
+
placement: TPlacement;
|
|
29
|
+
viewport: {
|
|
30
|
+
width: number;
|
|
31
|
+
height: number;
|
|
32
|
+
};
|
|
33
|
+
gap: number;
|
|
34
|
+
crossAxisShift: TResolvedCrossAxisShift;
|
|
35
|
+
}): TPosition;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { type TPlacement } from '../resolve-placement';
|
|
2
|
+
import { type TStyleDeclaration } from '../set-style';
|
|
3
|
+
/**
|
|
4
|
+
* Positions `popover` against `anchor` from measurements, and keeps it there
|
|
5
|
+
* across opens, scroll and resize. Returns the cleanup.
|
|
6
|
+
*
|
|
7
|
+
* No fit margins on this path: the gap and the cross-axis shift are coordinate
|
|
8
|
+
* deltas here, so writing them as margins too would double-apply them.
|
|
9
|
+
*/
|
|
10
|
+
export declare function applyJavaScriptFallbackPositioning({ anchor, popover, placement, sizeStyles, }: {
|
|
11
|
+
anchor: HTMLElement;
|
|
12
|
+
popover: HTMLElement;
|
|
13
|
+
placement: TPlacement;
|
|
14
|
+
sizeStyles: TStyleDeclaration[];
|
|
15
|
+
}): () => void;
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolves a CSS length value to a pixel number using a hidden DOM probe.
|
|
3
|
+
*
|
|
4
|
+
* Used by the JS positioning fallback, where a consumer offset can be a number, a
|
|
5
|
+
* `${n}px` string, a token, a `calc()` expression, a viewport unit, and so on.
|
|
6
|
+
* Parsing arbitrary CSS in JS is fragile, and impossible for `calc(var(...))`
|
|
7
|
+
* without a layout context, so the browser does the math instead. The probe is
|
|
8
|
+
* appended to `container` so it inherits the popover's containing block, font
|
|
9
|
+
* size and custom-property scope. Anything unmeasurable resolves to `0`.
|
|
10
|
+
*
|
|
11
|
+
* Costs one synchronous style and layout flush per call that reaches the probe.
|
|
12
|
+
* Deliberately NOT memoised: a token can be retargeted by an override on the
|
|
13
|
+
* consumer's wrapper, a viewport unit changes on resize and an `em` on a font
|
|
14
|
+
* change, so no (container, value) cache can be proven fresh. The caller decides
|
|
15
|
+
* when to re-resolve; see `applyJavaScriptFallbackPositioning`.
|
|
16
|
+
*/
|
|
17
|
+
export declare function resolveCssLengthToPixels({ value, container, }: {
|
|
18
|
+
value: number | string;
|
|
19
|
+
container: HTMLElement;
|
|
20
|
+
}): number;
|
|
@@ -17,13 +17,15 @@ export type TPlacementEdge = 'start' | 'end';
|
|
|
17
17
|
export type TPlacementAlign = 'start' | 'center' | 'end';
|
|
18
18
|
/**
|
|
19
19
|
* Fully-resolved placement (internal). Use `resolvePlacement` for partial input.
|
|
20
|
-
* `offset.gap
|
|
21
|
-
*
|
|
20
|
+
* `offset.gap`, `offset.crossAxisShift.value` and `minSize` are always CSS length
|
|
21
|
+
* strings. `minSize` stays `undefined` when unset, so "not specified" and an
|
|
22
|
+
* explicit `0` remain distinguishable.
|
|
22
23
|
*/
|
|
23
24
|
export type TPlacement = {
|
|
24
25
|
axis: TPlacementAxis;
|
|
25
26
|
edge: TPlacementEdge;
|
|
26
27
|
align: TPlacementAlign;
|
|
28
|
+
minSize?: string;
|
|
27
29
|
offset: {
|
|
28
30
|
gap: string;
|
|
29
31
|
crossAxisShift: TCrossAxisShiftOffset;
|
|
@@ -42,6 +44,17 @@ export type TPlacementOptions = {
|
|
|
42
44
|
axis?: TPlacementAxis;
|
|
43
45
|
edge?: TPlacementEdge;
|
|
44
46
|
align?: TPlacementAlign;
|
|
47
|
+
/**
|
|
48
|
+
* The minimum size the popover keeps along the PLACEMENT axis. A number is
|
|
49
|
+
* pixels; a string is any CSS length.
|
|
50
|
+
*
|
|
51
|
+
* Once EITHER axis asks for `'max-available'` the placement axis is floored
|
|
52
|
+
* whether this is set or not, because a cap with no floor stops the popover
|
|
53
|
+
* flipping to a roomier side. This always beats that default floor, and
|
|
54
|
+
* composes with an anchor floor as `max(minSize, anchorSize)` - so `0` caps the
|
|
55
|
+
* popover without letting it move, but does not remove an anchor floor.
|
|
56
|
+
*/
|
|
57
|
+
minSize?: number | string;
|
|
45
58
|
offset?: {
|
|
46
59
|
gap?: number | string;
|
|
47
60
|
crossAxisShift?: {
|
|
@@ -57,6 +70,9 @@ export type TPlacementOptions = {
|
|
|
57
70
|
* Defaults: `axis: 'block'`, `edge: 'end'`, `align: 'center'`,
|
|
58
71
|
* `offset.gap: token('space.100', '8px')`,
|
|
59
72
|
* `offset.crossAxisShift: { value: '0px', direction: 'forwards' }`.
|
|
73
|
+
*
|
|
74
|
+
* `minSize` has no default here: whether it needs one depends on how the popover
|
|
75
|
+
* is sized, which only `useAnchoredPopover` knows.
|
|
60
76
|
*/
|
|
61
77
|
export declare function resolvePlacement({ placement }: {
|
|
62
78
|
placement: TPlacementOptions;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A lazy, cached `CSS.supports(property, value)` probe. Lazy so it is SSR safe
|
|
3
|
+
* and cannot cause a hydration mismatch: nothing is read until the first call,
|
|
4
|
+
* which happens in an effect. Cached because the answer cannot change within a
|
|
5
|
+
* page. `false` wherever `CSS.supports` is missing (SSR, jsdom), so a caller
|
|
6
|
+
* falls back rather than throws.
|
|
7
|
+
*/
|
|
8
|
+
export declare function createCssDeclarationProbe({ property, value, }: {
|
|
9
|
+
property: string;
|
|
10
|
+
value: string;
|
|
11
|
+
}): () => boolean;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { CompiledStyles } from '@compiled/react';
|
|
2
|
+
/**
|
|
3
|
+
* The host surface reset is declared twice, in `popover/popover.tsx` and
|
|
4
|
+
* `dialog/dialog-content.tsx`, because ADS forbids sharing styles across files
|
|
5
|
+
* (`no-exported-styles` / `no-imported-style-values` — Compiled styles are null
|
|
6
|
+
* at runtime). Each copy asserts itself against this type with
|
|
7
|
+
* `TSurfaceResetCheck`, so the compiler fails if either drifts. Change this
|
|
8
|
+
* first, then both copies.
|
|
9
|
+
*/
|
|
10
|
+
export type TSurfaceReset = CompiledStyles<{
|
|
11
|
+
pointerEvents: 'auto';
|
|
12
|
+
whiteSpace: 'normal';
|
|
13
|
+
wordBreak: 'normal';
|
|
14
|
+
overflowWrap: 'normal';
|
|
15
|
+
textAlign: 'start';
|
|
16
|
+
textIndent: '0';
|
|
17
|
+
textTransform: 'none';
|
|
18
|
+
}>;
|
|
19
|
+
type TIsIdentical<A, B> = (<T>() => T extends A ? 1 : 2) extends <T>() => (T extends B ? 1 : 2) ? true : false;
|
|
20
|
+
/**
|
|
21
|
+
* Use as `true satisfies TSurfaceResetCheck<typeof surfaceResetStyles.root>`.
|
|
22
|
+
* Identity rather than assignability, so extra or widened properties also fail.
|
|
23
|
+
*/
|
|
24
|
+
export type TSurfaceResetCheck<TActual> = TIsIdentical<TActual, TSurfaceReset> extends true ? true : 'surfaceResetStyles does not match TSurfaceReset in internal/surface-reset.tsx';
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import { type TAnchoredPopoverOptions } from './use-anchored-popover';
|
|
2
|
+
/**
|
|
3
|
+
* A point in viewport coordinates (CSS pixels). Axis-named rather than
|
|
4
|
+
* edge-named, because viewport coordinates are always physical.
|
|
5
|
+
*/
|
|
6
|
+
export type TAnchorPoint = {
|
|
7
|
+
x: number;
|
|
8
|
+
y: number;
|
|
9
|
+
};
|
|
10
|
+
/**
|
|
11
|
+
* Positions and sizes a popover at a viewport coordinate. Takes every option
|
|
12
|
+
* `useAnchoredPopover` does except `anchorRef`, with the same meaning. One caveat
|
|
13
|
+
* is specific to a point: it has no size, so `'match-anchor'` and `'min-anchor'`
|
|
14
|
+
* resolve to zero against it.
|
|
15
|
+
*
|
|
16
|
+
* A consumer that anchors to an element sometimes and to a point at other times
|
|
17
|
+
* calls BOTH hooks with complementary `isEnabled` values, since a hook cannot be
|
|
18
|
+
* called conditionally. Nothing enforces that; see `isEnabled` on
|
|
19
|
+
* `useAnchoredPopover` for why two enabled hooks on one popover is a bug.
|
|
20
|
+
*
|
|
21
|
+
* @example Anchor at the cursor, falling back to the trigger element
|
|
22
|
+
* ```tsx
|
|
23
|
+
* const shared = { popoverRef, placement, isOpen };
|
|
24
|
+
*
|
|
25
|
+
* useAnchoredPopover({ ...shared, anchorRef: triggerRef, isEnabled: !mousePos });
|
|
26
|
+
* useAnchoredPopoverAtPoint({
|
|
27
|
+
* ...shared,
|
|
28
|
+
* isEnabled: Boolean(mousePos),
|
|
29
|
+
* // Read through a ref: `getPoint` is latched, see below.
|
|
30
|
+
* getPoint: () => mousePosRef.current,
|
|
31
|
+
* });
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare function useAnchoredPopoverAtPoint({ getPoint, isEnabled, ...rest }: {
|
|
35
|
+
/**
|
|
36
|
+
* Returns the viewport coordinate to anchor at, or `null` for "no point yet".
|
|
37
|
+
*
|
|
38
|
+
* Called once per activation and then latched. It is read through a ref, so an
|
|
39
|
+
* inline arrow is fine - but for the same reason it must read any value that can
|
|
40
|
+
* change from a ref rather than closing over it.
|
|
41
|
+
*/
|
|
42
|
+
getPoint: () => TAnchorPoint | null;
|
|
43
|
+
/**
|
|
44
|
+
* `false` means "do not position": nothing is created and no style is written.
|
|
45
|
+
* Also the latch key - `false` -> `true` is what re-reads `getPoint`.
|
|
46
|
+
*/
|
|
47
|
+
isEnabled?: boolean;
|
|
48
|
+
} & Omit<TAnchoredPopoverOptions, 'anchorRef' | 'isEnabled'>): void;
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Positioning AND anchor-relative sizing for top-layer popovers. Anchors an
|
|
3
|
+
* ELEMENT; to anchor a viewport coordinate use `useAnchoredPopoverAtPoint`.
|
|
4
|
+
*
|
|
5
|
+
* Two runtime paths, each a function that applies its styles and returns the
|
|
6
|
+
* cleanup: CSS Anchor Positioning in `./anchor-positioning`, and the JavaScript
|
|
7
|
+
* fallback in `./javascript-fallback`. The path is resolved ONCE, at the top of
|
|
8
|
+
* the hook, and threaded through positioning, sizing and margins.
|
|
9
|
+
*
|
|
10
|
+
* See `notes/architecture/positioning.md` and
|
|
11
|
+
* `notes/decisions/fit-available-space.md`.
|
|
12
|
+
*/
|
|
13
|
+
import { type RefObject } from 'react';
|
|
14
|
+
import { type TPopoverAxisSize } from './anchored-popover-size';
|
|
15
|
+
import { type TPlacementOptions } from './resolve-placement';
|
|
16
|
+
/**
|
|
17
|
+
* Exported so `useAnchoredPopoverAtPoint` can forward the options it does not own.
|
|
18
|
+
*/
|
|
19
|
+
export type TAnchoredPopoverOptions = {
|
|
20
|
+
/**
|
|
21
|
+
* The element to position against. The ref OBJECT must be referentially stable,
|
|
22
|
+
* as the effect depends on it. `.current` may be `null` on the first render.
|
|
23
|
+
*/
|
|
24
|
+
anchorRef: RefObject<HTMLElement | null>;
|
|
25
|
+
/**
|
|
26
|
+
* `false` means "do not position": the hook applies nothing and touches no DOM,
|
|
27
|
+
* so another strategy can own the popover. Defaults to `true`.
|
|
28
|
+
*
|
|
29
|
+
* A disabled hook holds no `setStyle` snapshot, which is what lets a consumer
|
|
30
|
+
* call this AND `useAnchoredPopoverAtPoint` on one popover with COMPLEMENTARY
|
|
31
|
+
* values. Two enabled hooks nest their snapshots, and React unwinds them in
|
|
32
|
+
* commit order rather than write order, so a stale inline value can survive.
|
|
33
|
+
*/
|
|
34
|
+
isEnabled?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Element being positioned. May be unmounted between opens; see `isOpen`.
|
|
37
|
+
*/
|
|
38
|
+
popoverRef: RefObject<HTMLElement | null>;
|
|
39
|
+
/**
|
|
40
|
+
* Where the popover sits relative to the anchor, plus `offset.gap`,
|
|
41
|
+
* `offset.crossAxisShift` and `minSize`. Required, because the sizing rules read
|
|
42
|
+
* the placement axis; individual fields are optional. See `TPlacementOptions`.
|
|
43
|
+
*/
|
|
44
|
+
placement: TPlacementOptions;
|
|
45
|
+
/**
|
|
46
|
+
* Re-runs the effect across open cycles, so styles and listeners follow the live
|
|
47
|
+
* host element through a remount.
|
|
48
|
+
*/
|
|
49
|
+
isOpen: boolean;
|
|
50
|
+
/**
|
|
51
|
+
* How wide the popover is, defaulting to `'content'`: the natural width, so a
|
|
52
|
+
* popover too wide for the space beside its anchor slides to a roomier side
|
|
53
|
+
* rather than wrapping into it. Both axes take the same four values under the
|
|
54
|
+
* same rules - see `TPopoverAxisSize` in `anchored-popover-size.tsx`.
|
|
55
|
+
*/
|
|
56
|
+
inlineSize?: TPopoverAxisSize;
|
|
57
|
+
/**
|
|
58
|
+
* The block-axis twin of `inlineSize`, so `'max-available'` caps the HEIGHT.
|
|
59
|
+
*/
|
|
60
|
+
blockSize?: TPopoverAxisSize;
|
|
61
|
+
/**
|
|
62
|
+
* Leaves `inline-size` to the popover element's own styles, skipping
|
|
63
|
+
* `TPopoverAxisSize` rule 4. For an element the consumer owns and may have given
|
|
64
|
+
* a `width` of its own - `@atlaskit/popper`'s imperative `createPopper` adapter
|
|
65
|
+
* is the case. Everything positioning an unstyled `Popover` host leaves this
|
|
66
|
+
* `false`.
|
|
67
|
+
*/
|
|
68
|
+
shouldPreserveInlineSize?: boolean;
|
|
69
|
+
/**
|
|
70
|
+
* Forces the JavaScript positioning fallback, so it can be exercised in any
|
|
71
|
+
* environment.
|
|
72
|
+
*
|
|
73
|
+
* @internal Testing only. Also switches sizing to measured pixels, because
|
|
74
|
+
* `anchor-size()` has no anchor to resolve against without `position-anchor`.
|
|
75
|
+
*/
|
|
76
|
+
forceFallbackPositioning?: boolean;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Positions and sizes a popover relative to an anchor. Owns every inline style on
|
|
80
|
+
* the popover host: where it goes, how big it is relative to its anchor, and the
|
|
81
|
+
* margins that keep it clear of the anchor and the viewport edge. It knows nothing
|
|
82
|
+
* about visibility or animation - compose it with `Popover`.
|
|
83
|
+
*
|
|
84
|
+
* On modern browsers the browser handles flipping via CSS Anchor Positioning;
|
|
85
|
+
* otherwise it falls back to measured `position: fixed` coordinates, re-run on
|
|
86
|
+
* scroll and resize.
|
|
87
|
+
*
|
|
88
|
+
* `inlineSize` and `blockSize` both default to `'content'`. Two rules are
|
|
89
|
+
* surprising: fitting one axis also fits an axis left on `'content'`, and fitting
|
|
90
|
+
* either axis floors the placement axis. See `TPopoverAxisSize`.
|
|
91
|
+
*
|
|
92
|
+
* **Several React roots on one page.** The `anchor-name` this hook writes to an
|
|
93
|
+
* anchor that has none is minted from `useId()`, like every other id in the design
|
|
94
|
+
* system. `useId()` is unique within a root; across roots it is unique for
|
|
95
|
+
* client-rendered roots but NOT for roots that hydrate the same markup, where it
|
|
96
|
+
* is derived from tree position. Two anchors carrying one name resolve to the last
|
|
97
|
+
* in tree order, so a popover can attach to another root's trigger. A host that
|
|
98
|
+
* hydrates more than one root must give each a distinct `identifierPrefix` (on
|
|
99
|
+
* `hydrateRoot` and the matching server render). That is already required for the
|
|
100
|
+
* popover's own `id`, which `aria-controls` and `popovertarget` point at, and for
|
|
101
|
+
* every `aria-*` id the design system mints. A bundle with two copies of
|
|
102
|
+
* `react-dom` has the same exposure for client-rendered roots.
|
|
103
|
+
*
|
|
104
|
+
* @example Position a popover below its trigger
|
|
105
|
+
* ```tsx
|
|
106
|
+
* const triggerRef = useRef<HTMLButtonElement>(null);
|
|
107
|
+
* const popoverRef = useRef<HTMLDivElement>(null);
|
|
108
|
+
*
|
|
109
|
+
* useAnchoredPopover({
|
|
110
|
+
* anchorRef: triggerRef,
|
|
111
|
+
* popoverRef,
|
|
112
|
+
* placement: { axis: 'block', edge: 'end' },
|
|
113
|
+
* isOpen,
|
|
114
|
+
* });
|
|
115
|
+
* ```
|
|
116
|
+
*
|
|
117
|
+
* @example Match the trigger's width and keep the popover on screen
|
|
118
|
+
* ```tsx
|
|
119
|
+
* // What `<Popup shouldFitContainer shouldFitViewport>` maps to.
|
|
120
|
+
* useAnchoredPopover({
|
|
121
|
+
* anchorRef: triggerRef,
|
|
122
|
+
* popoverRef,
|
|
123
|
+
* placement: { axis: 'block', edge: 'end' },
|
|
124
|
+
* isOpen,
|
|
125
|
+
* inlineSize: 'match-anchor',
|
|
126
|
+
* blockSize: 'max-available',
|
|
127
|
+
* });
|
|
128
|
+
* ```
|
|
129
|
+
*
|
|
130
|
+
* @example Switch to a cursor position mid-mount
|
|
131
|
+
* ```tsx
|
|
132
|
+
* // Complementary `isEnabled`, so exactly one hook owns the popover.
|
|
133
|
+
* const shared = { popoverRef, placement, isOpen };
|
|
134
|
+
*
|
|
135
|
+
* useAnchoredPopover({ ...shared, anchorRef: triggerRef, isEnabled: !mousePos });
|
|
136
|
+
* useAnchoredPopoverAtPoint({
|
|
137
|
+
* ...shared,
|
|
138
|
+
* isEnabled: Boolean(mousePos),
|
|
139
|
+
* getPoint: () => mousePosRef.current,
|
|
140
|
+
* });
|
|
141
|
+
* ```
|
|
142
|
+
*/
|
|
143
|
+
export declare function useAnchoredPopover({ anchorRef, popoverRef, placement, isOpen, isEnabled, inlineSize, blockSize, shouldPreserveInlineSize, forceFallbackPositioning, }: TAnchoredPopoverOptions): void;
|
|
@@ -9,4 +9,5 @@ export { createPopoverCloseEvent } from './create-close-event';
|
|
|
9
9
|
/**
|
|
10
10
|
* @deprecated Import from the generated per-export subpath instead.
|
|
11
11
|
*/
|
|
12
|
-
export type { TPopoverCloseReason, TPopoverProps
|
|
12
|
+
export type { TPopoverCloseReason, TPopoverProps } from './types';
|
|
13
|
+
export type { TPlacementOptions } from '../internal/resolve-placement';
|
|
@@ -6,7 +6,7 @@ import React from 'react';
|
|
|
6
6
|
import { type TPopoverForwardedProps } from './types';
|
|
7
7
|
/**
|
|
8
8
|
* Unopinionated top-layer primitive. Owns visibility and animation only;
|
|
9
|
-
* compose with `
|
|
9
|
+
* compose with `useAnchoredPopover` for positioning and sizing.
|
|
10
10
|
*
|
|
11
11
|
* ### 🔌 Visibility
|
|
12
12
|
*
|
|
@@ -30,6 +30,18 @@ export type TPopoverForwardedProps = TPopoverBaseProps & {
|
|
|
30
30
|
};
|
|
31
31
|
export type { TPlacementOptions };
|
|
32
32
|
type TPopoverBaseProps = {
|
|
33
|
+
/**
|
|
34
|
+
* Pass ONE element. The host is a flex row while open, so that a size cap can
|
|
35
|
+
* reach it (see `useAnchoredPopover`); two element children become two flex
|
|
36
|
+
* items SIDE BY SIDE at half width each. A fragment does not help - its children
|
|
37
|
+
* are the flex items - which is why this is not expressible as a type. It
|
|
38
|
+
* matters most where a consumer's render prop is handed through unwrapped, as
|
|
39
|
+
* `@atlaskit/popper` and `@atlaskit/spotlight` do.
|
|
40
|
+
*
|
|
41
|
+
* The host zeroes that element's `min-inline-size` and `min-block-size` so the
|
|
42
|
+
* cap can shrink a non-scrolling child, at zero specificity, so a minimum the
|
|
43
|
+
* element sets itself wins. See the host styles in `popover.tsx`.
|
|
44
|
+
*/
|
|
33
45
|
children: ReactNode;
|
|
34
46
|
/**
|
|
35
47
|
* Animation styles applied while the popover is entering.
|
|
@@ -100,7 +112,7 @@ type TPopoverBaseProps = {
|
|
|
100
112
|
* properties (like `--ds-popover-tx`, `--ds-popover-ty`) that control the
|
|
101
113
|
* slide direction. Has no effect without `shouldAnimate`.
|
|
102
114
|
*
|
|
103
|
-
* This does NOT control positioning. Use `
|
|
115
|
+
* This does NOT control positioning. Use `useAnchoredPopover` for that.
|
|
104
116
|
*/
|
|
105
117
|
placement?: TPlacementOptions;
|
|
106
118
|
/**
|
|
@@ -125,8 +137,8 @@ type TPopoverBaseProps = {
|
|
|
125
137
|
* Unopinionated top-layer primitive.
|
|
126
138
|
*
|
|
127
139
|
* `Popover` manages only top-layer visibility and animation. It has no
|
|
128
|
-
* knowledge of positioning. For anchor positioning, compose with the
|
|
129
|
-
* `
|
|
140
|
+
* knowledge of positioning. For anchor positioning and sizing, compose with the
|
|
141
|
+
* `useAnchoredPopover` hook separately.
|
|
130
142
|
*
|
|
131
143
|
* Use `Popover` directly for custom trigger lifecycles (hover, timers,
|
|
132
144
|
* external state) or trigger-less UI (flags, toasts). For the common
|
|
@@ -164,17 +176,3 @@ export type TPopoverProps = TPopoverBaseProps & TAriaRoleRequired & ({
|
|
|
164
176
|
mode: 'manual';
|
|
165
177
|
onClose?: never;
|
|
166
178
|
});
|
|
167
|
-
/**
|
|
168
|
-
* The width mode of the popover relative to its anchor element.
|
|
169
|
-
*
|
|
170
|
-
* - `'none'` (default): popover sizes to its content, ignoring the anchor width.
|
|
171
|
-
* - `'match-anchor'`: popover matches the anchor element's width exactly
|
|
172
|
-
* via CSS `inline-size: anchor-size(self-inline)`. Falls back to a
|
|
173
|
-
* one-off measurement of `anchorRef.current.offsetWidth` when CSS
|
|
174
|
-
* Anchor Positioning is not supported.
|
|
175
|
-
* - `'min-anchor'`: popover is at least as wide as the anchor, but
|
|
176
|
-
* can grow wider if content requires it. Uses
|
|
177
|
-
* `min-inline-size: anchor-size(self-inline)`. Falls back to a one-off
|
|
178
|
-
* measurement of the anchor's width.
|
|
179
|
-
*/
|
|
180
|
-
export type TWidthFromAnchorMode = 'none' | 'match-anchor' | 'min-anchor';
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
* - Popover open state tracked via `data-popover-open` (no `:popover-open` in jsdom).
|
|
13
13
|
* - Auto popovers: maintain an open stack, perform light-dismiss on document mousedown
|
|
14
14
|
* outside the open chain, and dismiss the topmost on Escape.
|
|
15
|
-
* - On open, removes any inline `opacity: 0` from the popover element so
|
|
16
|
-
*
|
|
17
|
-
*
|
|
15
|
+
* - On open, removes any inline `opacity: 0` from the popover element, so the
|
|
16
|
+
* JavaScript positioning fallback's `ResizeObserver` reveal is not needed in
|
|
17
|
+
* jsdom, where its non-zero-layout guard can never pass.
|
|
18
18
|
*
|
|
19
19
|
* Companion `toBeVisible` patch lives at `./to-be-visible`.
|
|
20
20
|
*
|