@atlaskit/top-layer 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/AGENTS.md +113 -0
  2. package/CHANGELOG.md +7 -0
  3. package/animations/package.json +1 -8
  4. package/dialog/package.json +1 -8
  5. package/dialog-scroll-lock/package.json +1 -8
  6. package/dist/cjs/dialog/dialog-content.js +12 -30
  7. package/dist/cjs/internal/set-style.js +5 -5
  8. package/dist/cjs/internal/slot.js +1 -1
  9. package/dist/cjs/internal/use-anchor-position-at-point.js +8 -8
  10. package/dist/cjs/internal/use-anchor-position.js +19 -40
  11. package/dist/cjs/internal/use-animated-visibility.js +31 -61
  12. package/dist/cjs/internal/use-initial-focus.js +9 -13
  13. package/dist/cjs/internal/use-width-from-anchor.js +6 -6
  14. package/dist/cjs/popover/popover.js +30 -58
  15. package/dist/cjs/popover-surface/popover-surface.js +4 -3
  16. package/dist/cjs/testing/polyfill.js +9 -9
  17. package/dist/cjs/use-simple-light-dismiss/index.js +3 -3
  18. package/dist/es2019/dialog/dialog-content.js +12 -30
  19. package/dist/es2019/internal/set-style.js +5 -5
  20. package/dist/es2019/internal/slot.js +1 -1
  21. package/dist/es2019/internal/use-anchor-position-at-point.js +8 -8
  22. package/dist/es2019/internal/use-anchor-position.js +19 -40
  23. package/dist/es2019/internal/use-animated-visibility.js +31 -61
  24. package/dist/es2019/internal/use-initial-focus.js +9 -13
  25. package/dist/es2019/internal/use-width-from-anchor.js +6 -6
  26. package/dist/es2019/popover/popover.js +30 -58
  27. package/dist/es2019/popover-surface/popover-surface.js +1 -1
  28. package/dist/es2019/testing/polyfill.js +7 -11
  29. package/dist/es2019/use-simple-light-dismiss/index.js +3 -3
  30. package/dist/esm/dialog/dialog-content.js +12 -30
  31. package/dist/esm/internal/set-style.js +5 -5
  32. package/dist/esm/internal/slot.js +1 -1
  33. package/dist/esm/internal/use-anchor-position-at-point.js +8 -8
  34. package/dist/esm/internal/use-anchor-position.js +19 -40
  35. package/dist/esm/internal/use-animated-visibility.js +31 -61
  36. package/dist/esm/internal/use-initial-focus.js +9 -13
  37. package/dist/esm/internal/use-width-from-anchor.js +6 -6
  38. package/dist/esm/popover/popover.js +30 -58
  39. package/dist/esm/popover-surface/popover-surface.js +1 -1
  40. package/dist/esm/testing/polyfill.js +9 -9
  41. package/dist/esm/use-simple-light-dismiss/index.js +3 -3
  42. package/dist/types/internal/set-style.d.ts +2 -2
  43. package/dist/types/internal/slot.d.ts +2 -2
  44. package/dist/types/internal/use-anchor-position-at-point.d.ts +2 -2
  45. package/dist/types/internal/use-anchor-position.d.ts +0 -4
  46. package/dist/types/internal/use-initial-focus.d.ts +1 -1
  47. package/dist/types/popover/types.d.ts +5 -7
  48. package/dist/types/popover-surface/popover-surface.d.ts +2 -2
  49. package/focus/package.json +1 -8
  50. package/get-aria-for-trigger/package.json +1 -8
  51. package/open-layer-observer/package.json +1 -8
  52. package/package.json +1 -1
  53. package/placement-map/package.json +1 -8
  54. package/popover/package.json +1 -8
  55. package/popover-surface/package.json +1 -8
  56. package/testing/polyfill/package.json +1 -8
  57. package/testing/to-be-visible/package.json +1 -8
  58. package/use-anchor-position/package.json +1 -8
  59. package/use-anchor-position-at-point/package.json +1 -8
  60. package/use-arrow-navigation/package.json +1 -8
  61. package/use-popover-id/package.json +1 -8
  62. package/use-simple-light-dismiss/package.json +1 -8
  63. package/use-width-from-anchor/package.json +1 -8
  64. package/dist/types-ts4.5/animations/presets.d.ts +0 -110
  65. package/dist/types-ts4.5/animations/types.d.ts +0 -38
  66. package/dist/types-ts4.5/dialog/create-close-event.d.ts +0 -23
  67. package/dist/types-ts4.5/dialog/dialog-content.d.ts +0 -24
  68. package/dist/types-ts4.5/dialog/index.d.ts +0 -3
  69. package/dist/types-ts4.5/dialog/types.d.ts +0 -126
  70. package/dist/types-ts4.5/dialog-scroll-lock/index.d.ts +0 -40
  71. package/dist/types-ts4.5/entry-points/animations.d.ts +0 -2
  72. package/dist/types-ts4.5/entry-points/dialog-scroll-lock.d.ts +0 -1
  73. package/dist/types-ts4.5/entry-points/dialog.d.ts +0 -2
  74. package/dist/types-ts4.5/entry-points/focus.d.ts +0 -4
  75. package/dist/types-ts4.5/entry-points/get-aria-for-trigger.d.ts +0 -1
  76. package/dist/types-ts4.5/entry-points/open-layer-observer.d.ts +0 -5
  77. package/dist/types-ts4.5/entry-points/placement-map.d.ts +0 -3
  78. package/dist/types-ts4.5/entry-points/popover-surface.d.ts +0 -2
  79. package/dist/types-ts4.5/entry-points/popover.d.ts +0 -2
  80. package/dist/types-ts4.5/entry-points/use-anchor-position-at-point.d.ts +0 -1
  81. package/dist/types-ts4.5/entry-points/use-anchor-position.d.ts +0 -1
  82. package/dist/types-ts4.5/entry-points/use-arrow-navigation.d.ts +0 -3
  83. package/dist/types-ts4.5/entry-points/use-popover-id.d.ts +0 -11
  84. package/dist/types-ts4.5/entry-points/use-simple-light-dismiss.d.ts +0 -2
  85. package/dist/types-ts4.5/entry-points/use-width-from-anchor.d.ts +0 -1
  86. package/dist/types-ts4.5/focus/get-first-focusable.d.ts +0 -8
  87. package/dist/types-ts4.5/focus/get-focusables.d.ts +0 -13
  88. package/dist/types-ts4.5/focus/get-last-focusable.d.ts +0 -8
  89. package/dist/types-ts4.5/focus/get-next-focusable.d.ts +0 -13
  90. package/dist/types-ts4.5/focus/is-in-same-layer.d.ts +0 -8
  91. package/dist/types-ts4.5/focus/is-nested-layer-focused.d.ts +0 -8
  92. package/dist/types-ts4.5/focus/selectors.d.ts +0 -4
  93. package/dist/types-ts4.5/focus/types.d.ts +0 -5
  94. package/dist/types-ts4.5/index.d.ts +0 -0
  95. package/dist/types-ts4.5/internal/anchor-positioning-fallback.d.ts +0 -26
  96. package/dist/types-ts4.5/internal/combine.d.ts +0 -14
  97. package/dist/types-ts4.5/internal/ensure-preset-styles.d.ts +0 -6
  98. package/dist/types-ts4.5/internal/get-aria-for-trigger.d.ts +0 -93
  99. package/dist/types-ts4.5/internal/placement-to-position-area.d.ts +0 -21
  100. package/dist/types-ts4.5/internal/placement-to-try-fallbacks.d.ts +0 -36
  101. package/dist/types-ts4.5/internal/reduced-motion.d.ts +0 -14
  102. package/dist/types-ts4.5/internal/resolve-css-length-to-pixels.d.ts +0 -20
  103. package/dist/types-ts4.5/internal/resolve-css-length.d.ts +0 -8
  104. package/dist/types-ts4.5/internal/resolve-placement.d.ts +0 -58
  105. package/dist/types-ts4.5/internal/role-to-aria-has-popup.d.ts +0 -13
  106. package/dist/types-ts4.5/internal/role-types.d.ts +0 -71
  107. package/dist/types-ts4.5/internal/set-style.d.ts +0 -11
  108. package/dist/types-ts4.5/internal/should-focus-into-popover.d.ts +0 -8
  109. package/dist/types-ts4.5/internal/slot.d.ts +0 -29
  110. package/dist/types-ts4.5/internal/use-anchor-position-at-point.d.ts +0 -67
  111. package/dist/types-ts4.5/internal/use-anchor-position.d.ts +0 -91
  112. package/dist/types-ts4.5/internal/use-animated-visibility.d.ts +0 -109
  113. package/dist/types-ts4.5/internal/use-animation-preset.d.ts +0 -11
  114. package/dist/types-ts4.5/internal/use-focus-wrap.d.ts +0 -25
  115. package/dist/types-ts4.5/internal/use-initial-focus.d.ts +0 -73
  116. package/dist/types-ts4.5/internal/use-preset-styles.d.ts +0 -15
  117. package/dist/types-ts4.5/internal/use-width-from-anchor.d.ts +0 -21
  118. package/dist/types-ts4.5/placement-map/index.d.ts +0 -51
  119. package/dist/types-ts4.5/placement-map/legacy-placements.d.ts +0 -27
  120. package/dist/types-ts4.5/placement-map/placement-mapping.d.ts +0 -13
  121. package/dist/types-ts4.5/popover/create-close-event.d.ts +0 -25
  122. package/dist/types-ts4.5/popover/index.d.ts +0 -3
  123. package/dist/types-ts4.5/popover/popover.d.ts +0 -17
  124. package/dist/types-ts4.5/popover/types.d.ts +0 -193
  125. package/dist/types-ts4.5/popover-surface/index.d.ts +0 -2
  126. package/dist/types-ts4.5/popover-surface/popover-surface.d.ts +0 -21
  127. package/dist/types-ts4.5/testing/polyfill.d.ts +0 -25
  128. package/dist/types-ts4.5/testing/to-be-visible.d.ts +0 -23
  129. package/dist/types-ts4.5/use-arrow-navigation/index.d.ts +0 -3
  130. package/dist/types-ts4.5/use-arrow-navigation/is-at-current-menu-level.d.ts +0 -48
  131. package/dist/types-ts4.5/use-arrow-navigation/use-arrow-navigation.d.ts +0 -102
  132. package/dist/types-ts4.5/use-simple-light-dismiss/index.d.ts +0 -45
@@ -1,93 +0,0 @@
1
- import { type TAriaHasPopupValue, type TRoleRequiringAccessibleName } from './role-types';
2
- /**
3
- * Roles accepted by `getAriaForTrigger`.
4
- *
5
- * Excludes tooltip-family roles (`tooltip`, `note`, `status`, `alert`, `log`)
6
- * because the correct trigger wiring for those is `aria-describedby`, not
7
- * `aria-haspopup` / `aria-expanded` / `aria-controls`. Use `aria-describedby`
8
- * manually for tooltip triggers.
9
- */
10
- type TAriaForTriggerRole = TRoleRequiringAccessibleName | 'listbox' | 'tree' | 'grid';
11
- type TGetAriaForTriggerOptions = {
12
- /**
13
- * The `role` that will be set on the `<Popover>` element. Used to derive
14
- * the correct `aria-haspopup` value for the trigger.
15
- */
16
- role: TAriaForTriggerRole;
17
- /**
18
- * Whether the popover is currently open. Drives `aria-expanded`.
19
- */
20
- isOpen: boolean;
21
- /**
22
- * The popover identifier - the value returned by `usePopoverId()`,
23
- * passed as `id` to `<Popover>` and referenced here via `aria-controls`.
24
- */
25
- popoverId: string;
26
- };
27
- /**
28
- * Non-undefined subset of `TAriaHasPopupValue`. Every role accepted by
29
- * `getAriaForTrigger` maps to a concrete `aria-haspopup` string, so the
30
- * trigger always receives a defined attribute value.
31
- */
32
- type TAriaHasPopupForTrigger = Exclude<TAriaHasPopupValue, undefined>;
33
- type TAriaForTrigger = {
34
- 'aria-haspopup': TAriaHasPopupForTrigger;
35
- 'aria-expanded': boolean;
36
- /**
37
- * `aria-controls` is `undefined` while the popover is closed, because
38
- * the popover host element is only rendered in the DOM while open. A
39
- * dangling `aria-controls` reference (pointing at a missing ID) is
40
- * tolerated by assistive tech but flagged by some a11y tooling, so
41
- * we leave it unset until the target exists.
42
- */
43
- 'aria-controls': string | undefined;
44
- };
45
- /**
46
- * Returns the ARIA attributes to spread onto a click-activated popover trigger.
47
- *
48
- * Centralises three attributes that are easy to forget or get wrong individually:
49
- *
50
- * - `aria-haspopup` - derived from the popover's role (e.g. `dialog → "dialog"`,
51
- * `menu → "menu"`, `tooltip → undefined`). React omits the attribute when
52
- * the value is `undefined`.
53
- * - `aria-expanded` - reflects the current open state.
54
- * - `aria-controls` - references the popover element by its id, even
55
- * while the popover is closed. The relationship is stable; `aria-expanded`
56
- * carries the current visibility state.
57
- *
58
- * **This function is for click/keyboard-activated popovers only.** For
59
- * hover-driven tooltips, the trigger should use `aria-describedby` instead.
60
- *
61
- * @example
62
- * ```tsx
63
- * import { getAriaForTrigger } from '@atlaskit/top-layer/get-aria-for-trigger';
64
- * import { usePopoverId } from '@atlaskit/top-layer/use-popover-id';
65
- *
66
- * const popoverId = usePopoverId();
67
- * const [isOpen, setIsOpen] = useState(false);
68
- *
69
- * return (
70
- * <>
71
- * <button
72
- * ref={triggerRef}
73
- * onClick={() => setIsOpen((previous) => !previous)}
74
- * {...getAriaForTrigger({ role: 'dialog', isOpen, popoverId })}
75
- * >
76
- * Open
77
- * </button>
78
- * <Popover
79
- * id={popoverId}
80
- * role="dialog"
81
- * label="My dialog"
82
- * isOpen={isOpen}
83
- * triggerRef={triggerRef}
84
- * onClose={() => setIsOpen(false)}
85
- * >
86
- * …
87
- * </Popover>
88
- * </>
89
- * );
90
- * ```
91
- */
92
- export declare function getAriaForTrigger({ role, isOpen, popoverId, }: TGetAriaForTriggerOptions): TAriaForTrigger;
93
- export {};
@@ -1,21 +0,0 @@
1
- import { type TPlacementOptions } from '../internal/resolve-placement';
2
- /**
3
- * Resolves placement options to CSS `position-area` syntax.
4
- *
5
- * The `align` field represents the *visual* alignment:
6
- * - `align: 'start'` means "aligned to the trigger's start edge" (left in LTR for block axis)
7
- * - `align: 'end'` means "aligned to the trigger's end edge"
8
- * - `align: 'center'` means centered (single-axis position-area)
9
- *
10
- * CSS `position-area` uses `span-*` keywords which indicate the *expansion direction*.
11
- * Visual start-alignment requires `span-{cross-axis}-end` (expand toward end = start-aligned).
12
- * This function handles the inversion internally.
13
- *
14
- * @example
15
- * placementToPositionArea({ placement: { axis: 'block', edge: 'end', align: 'center' } }) // → 'block-end'
16
- * placementToPositionArea({ placement: { axis: 'block', edge: 'end', align: 'start' } }) // → 'block-end span-inline-end'
17
- * placementToPositionArea({ placement: { axis: 'block', edge: 'end', align: 'end' } }) // → 'block-end span-inline-start'
18
- */
19
- export declare function placementToPositionArea({ placement }: {
20
- placement: TPlacementOptions;
21
- }): string;
@@ -1,36 +0,0 @@
1
- import { type TPlacementOptions } from '../internal/resolve-placement';
2
- /**
3
- * Returns `position-try-fallbacks` value based on placement.
4
- *
5
- * For centered placements, includes cross-axis aligned position-area
6
- * values so the browser can shift the popover along the cross-axis
7
- * when the centered position would overflow the viewport edge.
8
- *
9
- * Fallback order for centered placements (e.g. `block-end`):
10
- * 1. Same edge, start-aligned (shift for near-edge overflow)
11
- * 2. Same edge, end-aligned (shift for far-edge overflow)
12
- * 3. Flipped edge, centered
13
- * 4. Flipped edge, start-aligned
14
- * 5. Flipped edge, end-aligned
15
- *
16
- * For aligned placements (start/end), includes the same-edge centered
17
- * position as fallbacks so the browser can try centering when the aligned
18
- * position would overflow, before flipping to the opposite edge.
19
- *
20
- * **Why `flip-inline flip-block` (or `flip-block flip-inline`) is included:**
21
- *
22
- * When a popup is in a viewport corner (e.g. inline-end align-end at the
23
- * top-right), flipping only the primary axis (`flip-inline`) moves the popup
24
- * to the left but keeps the same cross-axis span direction (e.g. upward),
25
- * which is still off-screen. The combined keyword `flip-inline flip-block`
26
- * mirrors the popup diagonally. It flips BOTH the position-area AND both
27
- * inline and block margins simultaneously, placing the popup at the
28
- * diagonally opposite corner where there is always space.
29
- *
30
- * Named `position-area` entries (e.g. `inline-start span-block-end`) in
31
- * `position-try-fallbacks` do NOT update margins, so only the `flip-*`
32
- * tactic keywords correctly flip the gap margin along with the position.
33
- */
34
- export declare function placementToTryFallbacks({ placement }: {
35
- placement: TPlacementOptions;
36
- }): string;
@@ -1,14 +0,0 @@
1
- /**
2
- * Returns `true` when the user prefers reduced motion.
3
- *
4
- * Safe for SSR (returns `false` when `window` is unavailable).
5
- *
6
- * The result is cached after the first call via `once`. This avoids
7
- * calling `matchMedia` on every render. The trade-off is that if a user
8
- * toggles the OS reduced-motion setting mid-session, the change will not
9
- * take effect until the next page load. This is acceptable because
10
- * toggling this system-level preference mid-session is extremely rare,
11
- * and a page refresh is a reasonable expectation for system accessibility
12
- * settings to take effect.
13
- */
14
- export declare const prefersReducedMotion: () => boolean;
@@ -1,20 +0,0 @@
1
- /**
2
- * Resolves a CSS length value to a pixel number using a hidden DOM probe.
3
- *
4
- * Used by the JS positioning fallback: consumer offsets can be numbers,
5
- * `${n}px` strings, tokenised `var(--ds-space-100, 8px)` strings, `calc()`
6
- * expressions, viewport units, etc. Parsing arbitrary CSS in JS is fragile
7
- * (and impossible for `calc(var(...))` without a layout context), so we let
8
- * the browser do the math.
9
- *
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
- *
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.
16
- */
17
- export declare function resolveCssLengthToPixels({ value, container, }: {
18
- value: number | string;
19
- container: HTMLElement;
20
- }): number;
@@ -1,8 +0,0 @@
1
- /**
2
- * Normalizes an offset to a CSS length string. Numbers become `${n}px`;
3
- * strings pass through. Apply at the API boundary so internal code only
4
- * deals with strings.
5
- */
6
- export declare function toCssLengthString({ value }: {
7
- value: number | string;
8
- }): string;
@@ -1,58 +0,0 @@
1
- /**
2
- * Cross-axis shift. `value` is a CSS length string (consumer numbers are
3
- * normalized to `${n}px`). `direction` is `'forwards'` (toward end) or
4
- * `'backwards'` (toward start).
5
- */
6
- export type TCrossAxisShiftOffset = {
7
- value: string;
8
- direction: 'forwards' | 'backwards';
9
- };
10
- /**
11
- * Fully-resolved placement (internal). Use `getPlacement` for partial input.
12
- * `offset.gap` and `offset.crossAxisShift.value` are always CSS
13
- * length strings.
14
- */
15
- export type TPlacement = {
16
- axis: 'block' | 'inline';
17
- edge: 'start' | 'end';
18
- align: 'start' | 'center' | 'end';
19
- offset: {
20
- gap: string;
21
- crossAxisShift: {
22
- value: string;
23
- direction: 'forwards' | 'backwards';
24
- };
25
- };
26
- };
27
- /**
28
- * Partial placement options. `offset.gap` and
29
- * `offset.crossAxisShift.value` accept either a number (pixels) or a
30
- * CSS length string (e.g. `token('space.100')`).
31
- *
32
- * The two offset axes are named for clarity at the call site:
33
- * - `gap` - distance away from the trigger along the placement axis
34
- * - `crossAxisShift` - nudge along the trigger edge (perpendicular to the placement axis)
35
- */
36
- export type TPlacementOptions = {
37
- axis?: 'block' | 'inline';
38
- edge?: 'start' | 'end';
39
- align?: 'start' | 'center' | 'end';
40
- offset?: {
41
- gap?: number | string;
42
- crossAxisShift?: {
43
- value?: number | string;
44
- direction?: 'forwards' | 'backwards';
45
- };
46
- };
47
- };
48
- /**
49
- * Resolves a partial placement to its fully-specified form. Number offsets
50
- * are normalized to `${n}px` strings.
51
- *
52
- * Defaults: `axis: 'block'`, `edge: 'end'`, `align: 'center'`,
53
- * `offset.gap: token('space.100', '8px')`,
54
- * `offset.crossAxisShift: { value: '0px', direction: 'forwards' }`.
55
- */
56
- export declare function getPlacement({ placement }: {
57
- placement: TPlacementOptions;
58
- }): TPlacement;
@@ -1,13 +0,0 @@
1
- import type { TAriaHasPopupValue, TRoleRequiringAccessibleName, TRoleWithImplicitName } from './role-types';
2
- /**
3
- * Maps a popover content role to the correct `aria-haspopup` value
4
- * for its trigger element.
5
- *
6
- * Returns `undefined` for roles that are not popups in the ARIA sense
7
- * (`tooltip`, `note`, `status`, `alert`, `log`). Triggers for those roles
8
- * should not announce a popup at all - emitting `aria-haspopup="dialog"`
9
- * on a tooltip trigger would mislead assistive technology.
10
- */
11
- export declare function roleToAriaHasPopup({ role, }: {
12
- role: TRoleRequiringAccessibleName | TRoleWithImplicitName | undefined;
13
- }): TAriaHasPopupValue;
@@ -1,71 +0,0 @@
1
- /**
2
- * Valid values for the `aria-haspopup` attribute.
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.
13
- */
14
- export type TAriaHasPopupValue = 'dialog' | 'menu' | 'listbox' | 'tree' | 'grid' | undefined;
15
- /**
16
- * Roles that require an accessible name (`label` or `labelledBy`) per WCAG 4.1.2.
17
- * Without a name, assistive technology cannot identify these landmarks.
18
- */
19
- export type TRoleRequiringAccessibleName = 'dialog' | 'alertdialog' | 'menu';
20
- /**
21
- * Roles where the accessible name is derived from content or provided externally
22
- * (e.g. a combobox labels its listbox, tooltip content IS the accessible name).
23
- */
24
- export type TRoleWithImplicitName = 'tooltip' | 'listbox' | 'tree' | 'grid' | 'note' | 'status' | 'alert' | 'log';
25
- type TAccessibleNameRequired = {
26
- /**
27
- * Accessible name via `aria-label`.
28
- */
29
- label: string;
30
- labelledBy?: string;
31
- } | {
32
- label?: string;
33
- /**
34
- * Accessible name via `aria-labelledby`.
35
- */
36
- labelledBy: string;
37
- };
38
- type TAccessibleNameOptional = {
39
- label?: string;
40
- labelledBy?: string;
41
- };
42
- /**
43
- * ARIA role props where a role is always required.
44
- *
45
- * Used by `TPopupContentProps`. Popup content must always declare
46
- * its role so assistive technology can identify the layer.
47
- */
48
- export type TAriaRoleRequired = ({
49
- role: TRoleRequiringAccessibleName;
50
- } & TAccessibleNameRequired) | ({
51
- role: TRoleWithImplicitName;
52
- } & TAccessibleNameOptional);
53
- /**
54
- * ARIA role props where a role is optional.
55
- *
56
- * Used by `TPopoverProps`. The low-level primitive allows omitting
57
- * the role for cases where it is set externally or not needed.
58
- */
59
- export type TAriaRoleOptional = ({
60
- role: TRoleRequiringAccessibleName;
61
- } & TAccessibleNameRequired) | ({
62
- role?: TRoleWithImplicitName;
63
- } & TAccessibleNameOptional);
64
- /**
65
- * Returns `true` when the given popover role moves focus into the popover
66
- * on open, and `false` otherwise (including when `role` is `undefined`).
67
- */
68
- export declare function shouldFocusIntoPopover({ role, }: {
69
- role: TRoleRequiringAccessibleName | TRoleWithImplicitName | undefined;
70
- }): boolean;
71
- export {};
@@ -1,11 +0,0 @@
1
- /**
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).
4
- */
5
- export declare function setStyle({ el, styles, }: {
6
- el: HTMLElement;
7
- styles: Array<{
8
- property: string;
9
- value: string;
10
- }>;
11
- }): () => void;
@@ -1,8 +0,0 @@
1
- import type { TRoleRequiringAccessibleName, TRoleWithImplicitName } from './role-types';
2
- /**
3
- * Returns `true` when the given popover role moves focus into the popover
4
- * on open, and `false` otherwise (including when `role` is `undefined`).
5
- */
6
- export declare function shouldFocusIntoPopover({ role, }: {
7
- role: TRoleRequiringAccessibleName | TRoleWithImplicitName | undefined;
8
- }): boolean;
@@ -1,29 +0,0 @@
1
- import { type ForwardRefExoticComponent, type ReactNode, type RefAttributes } from 'react';
2
- /**
3
- * Extra DOM/event props are passed through to the cloned child.
4
- */
5
- export type SlotProps = {
6
- children: ReactNode;
7
- } & Record<string, unknown>;
8
- /**
9
- * Merges props (including ref) onto a single React element child.
10
- *
11
- * A safer alternative to raw `cloneElement` that:
12
- * 1. Guards with `isValidElement` - non-element children (strings,
13
- * fragments, null) are returned as-is instead of crashing.
14
- * 2. Merges refs via `mergeRefs` so both the caller's ref and the
15
- * child's existing ref are honoured.
16
- * 3. Spreads any additional props (ARIA attributes, event handlers, etc.)
17
- * onto the child element.
18
- *
19
- * Event handlers (e.g. `onClick`) are **not** auto-merged - the caller's
20
- * handler replaces the child's. Compose handlers before passing them in.
21
- *
22
- * @example
23
- * ```tsx
24
- * <Slot ref={triggerRef} onClick={handleClick} aria-expanded={isOpen}>
25
- * <button>Open</button>
26
- * </Slot>
27
- * ```
28
- */
29
- export declare const Slot: ForwardRefExoticComponent<SlotProps & RefAttributes<HTMLElement>>;
@@ -1,67 +0,0 @@
1
- import { type RefObject } from 'react';
2
- import { type TPlacementOptions } from './resolve-placement';
3
- /**
4
- * A point in viewport coordinates (CSS pixels) at which the synthetic
5
- * anchor should be placed.
6
- *
7
- * Axis-named (`x`/`y`) rather than edge-named (`left`/`top`) so the
8
- * shape is unambiguous in RTL writing modes — there is no ambiguity
9
- * about whether a coordinate is logical (`inline-start`/`block-start`)
10
- * or physical (`left`/`top`). Viewport coordinates are always
11
- * physical, so we name them with the physical axis labels.
12
- */
13
- export type TAnchorPoint = {
14
- x: number;
15
- y: number;
16
- };
17
- /**
18
- * Positions a popover at a consumer-supplied viewport coordinate using a
19
- * hidden synthetic anchor.
20
- *
21
- * @example
22
- * ```tsx
23
- * function PointPositionedPopover({ popoverRef, placement, mousePos }) {
24
- * useAnchorPositionAtPoint({
25
- * popoverRef,
26
- * placement,
27
- * isEnabled: Boolean(mousePos),
28
- * getPoint: () => {
29
- * if (!mousePos) return null;
30
- * return { x: mousePos.clientX, y: mousePos.clientY };
31
- * },
32
- * });
33
- * return <Popover ref={popoverRef}>...</Popover>;
34
- * }
35
- * ```
36
- */
37
- export declare function useAnchorPositionAtPoint({ popoverRef, placement, getPoint, isEnabled, isOpen, }: {
38
- /**
39
- * Element being positioned. Passed to `useAnchorPosition`.
40
- */
41
- popoverRef: RefObject<HTMLElement | null>;
42
- /**
43
- * Where the popover sits relative to the anchor.
44
- */
45
- placement: TPlacementOptions;
46
- /**
47
- * Lazy callback returning the viewport coordinate to anchor at.
48
- * Called once per activation (every `isEnabled: false → true`
49
- * transition); the result is latched and not re-read.
50
- *
51
- * Return `null` to signal "no point yet" — the hook stays in a
52
- * no-DOM state so another positioning strategy can own the popover.
53
- *
54
- * Read from a ref, so it does not need to be memoized.
55
- */
56
- getPoint: () => TAnchorPoint | null;
57
- /**
58
- * When `false`, the hook is a no-op: no synthetic anchor is created
59
- * and no positioning is applied. Defaults to `true`.
60
- */
61
- isEnabled?: boolean;
62
- /**
63
- * Whether the popover is currently open. Forwarded to the inner
64
- * `useAnchorPosition` so it re-runs across host remount cycles.
65
- */
66
- isOpen: boolean;
67
- }): void;
@@ -1,91 +0,0 @@
1
- /**
2
- * Anchor positioning for top-layer popovers. See
3
- * `notes/architecture/positioning.md` for the full model.
4
- *
5
- * Two runtime paths: CSS Anchor Positioning (modern browsers) and a JS
6
- * fallback that measures the trigger and writes `top`/`left`.
7
- *
8
- * Both paths honour `offset.gap` and `offset.crossAxisShift`. The
9
- * CSS path passes the values through as strings; the JS fallback resolves
10
- * them to pixels via a hidden DOM probe (see `resolveCssLengthToPixels`)
11
- * so tokens, `calc()`, `var()`, etc all work. The JS fallback hides the
12
- * popover with `opacity: 0` until the first measurement completes, so it
13
- * is never painted at the wrong location.
14
- */
15
- import { type RefObject } from 'react';
16
- import { type TPlacementOptions } from '../internal/resolve-placement';
17
- /**
18
- * Hook that positions an element relative to an anchor element using
19
- * CSS Anchor Positioning (with a JS fallback for older browsers).
20
- *
21
- * This hook is the positioning primitive. It has no knowledge of popovers,
22
- * visibility, or animation. Compose it with `Popover` for anchor-positioned
23
- * top-layer content.
24
- *
25
- * When CSS Anchor Positioning is supported, it sets CSS properties
26
- * (`anchor-name`, `position-anchor`, `position-area`, `position-try-fallbacks`)
27
- * directly on the elements via `el.style.setProperty()`.
28
- *
29
- * When not supported, it falls back to JavaScript-based positioning using
30
- * `position: fixed` with measured coordinates, re-running on scroll (capture)
31
- * and resize events.
32
- *
33
- * `placement` may be a fresh inline object on every render: a structural
34
- * comparison is used internally so re-runs are skipped when the resolved
35
- * placement shape is unchanged.
36
- */
37
- export declare function useAnchorPosition({ anchorRef, popoverRef, placement, forceFallbackPositioning, isEnabled, isOpen, }: {
38
- /**
39
- * Element to position relative to.
40
- */
41
- anchorRef: RefObject<HTMLElement | null>;
42
- /**
43
- * Element being positioned (typically a popover).
44
- *
45
- * The popover host may be unmounted between opens (the `Popover`
46
- * primitive unmounts after its exit animation). Pass `isOpen` so the
47
- * positioning effect re-runs against the freshly mounted element on
48
- * the next open. Without it, the effect's bound listeners and styles
49
- * would target the previous (detached) element.
50
- */
51
- popoverRef: RefObject<HTMLElement | null>;
52
- /**
53
- * Where to place the element relative to the anchor.
54
- * `offset.gap` and `offset.crossAxisShift` are part of the
55
- * placement object.
56
- *
57
- * All fields are optional. Omitted fields fall back to:
58
- * - `axis`: `'block'`
59
- * - `edge`: `'end'`
60
- * - `align`: `'center'`
61
- * - `offset.gap`: `token('space.100', '8px')`
62
- * - `offset.crossAxisShift.value`: `'0px'`
63
- * - `offset.crossAxisShift.direction`: `'forwards'`
64
- *
65
- * The full default placement (`{}`) renders the popover centered
66
- * below the trigger with one `space.100` of gap and no cross-axis
67
- * shift.
68
- *
69
- * `offset.gap` and `offset.crossAxisShift.value` accept either a
70
- * number (pixels) or a CSS length string (eg `token('space.200')`).
71
- */
72
- placement?: TPlacementOptions;
73
- /**
74
- * Forces the JavaScript positioning fallback even when the browser
75
- * supports CSS Anchor Positioning. Useful for testing fallback
76
- * behavior in any environment, including production.
77
- */
78
- forceFallbackPositioning?: boolean;
79
- /**
80
- * When `false`, the hook is a no-op and applies no positioning.
81
- * Defaults to `true`.
82
- */
83
- isEnabled?: boolean;
84
- /**
85
- * Whether the popover is currently open. Drives a re-run of the
86
- * positioning effect when the popover host element is unmounted
87
- * and remounted across open cycles, so listeners and styles are
88
- * always wired to the live host element.
89
- */
90
- isOpen: boolean;
91
- }): void;
@@ -1,109 +0,0 @@
1
- import { type RefObject } from 'react';
2
- import { type TAnimationPreset } from '../animations/types';
3
- type TUseAnimatedVisibilityArgs = {
4
- /**
5
- * Whether the element is logically open.
6
- */
7
- isOpen: boolean;
8
- /**
9
- * Animation preset for entry/exit transitions.
10
- * Pass `false` or `undefined` to disable animation.
11
- */
12
- animate: TAnimationPreset | false | undefined;
13
- /**
14
- * Ref to the DOM element that plays the entry/exit transitions.
15
- * Used to listen for `transitionend`.
16
- */
17
- elementRef: RefObject<HTMLElement | null>;
18
- /**
19
- * Called after the entry animation completes (or immediately on open
20
- * when there is no animation or reduced motion is active).
21
- * This includes initial mount with `isOpen=true`.
22
- */
23
- onEnterFinish?: () => void;
24
- /**
25
- * Called after the exit animation completes (or immediately on close
26
- * when there is no animation or reduced motion is active).
27
- */
28
- onExitFinish?: () => void;
29
- };
30
- type TUseAnimatedVisibilityResult = {
31
- /**
32
- * Current visibility phase. See `TPhase` for the full lifecycle.
33
- *
34
- * `phase !== 'closed'` means the host element is mounted and on
35
- * screen, including during animated entry, animated exit, and the
36
- * non-animated close handshake. Use this when you need "the user
37
- * can still see / interact with the element" semantics (e.g. focus
38
- * trapping, listeners that must outlive the exit).
39
- */
40
- phase: TPhase;
41
- /**
42
- * Resolved animation preset (with CSS injected), or `null` if
43
- * animation is disabled.
44
- */
45
- preset: TAnimationPreset | null;
46
- };
47
- /**
48
- * Visibility lifecycle phase shared between `useAnimatedVisibility`,
49
- * `useFocusWrap`, `useInitialFocus`, and the `Popover` / `Dialog`
50
- * components.
51
- *
52
- * - `closed`: host element is unmounted. No DOM presence.
53
- * - `entering`: host element is mounted and the CSS entry transition
54
- * is playing. **Only emitted when animation is enabled.** With
55
- * animation disabled the lifecycle goes directly `closed → open`.
56
- * - `open`: host element is mounted and settled. No transition is
57
- * playing.
58
- * - `exiting`: `isOpen` has flipped to `false` but the host element
59
- * is still mounted. Emitted while the CSS exit transition is playing
60
- * (animation enabled) OR while we wait for the browser's
61
- * `toggle`/`close` event to fire on the still-attached element so
62
- * focus restoration can run (animation disabled).
63
- *
64
- * State machine:
65
- * ```
66
- * animation ON: closed → entering → open → exiting → closed
67
- * animation OFF: closed → open → exiting → closed
68
- * interrupts: entering → exiting (close mid-entry)
69
- * exiting → entering (reopen mid-exit, animated)
70
- * exiting → open (reopen mid-handshake, non-animated)
71
- * ```
72
- *
73
- * `phase !== 'closed'` is the canonical "host is currently in the DOM
74
- * and on screen" predicate.
75
- */
76
- export type TPhase = 'closed' | 'entering' | 'open' | 'exiting';
77
- /**
78
- * Manages the children mount/unmount lifecycle around CSS exit transitions.
79
- *
80
- * Used by both `Popover` and `Dialog` to share the same animation lifecycle
81
- * logic. Those components own their own show/hide mechanisms (showPopover /
82
- * hidePopover vs showModal / close) and event handling - this hook only
83
- * manages the relationship between `isOpen` and when children are rendered.
84
- *
85
- * ## Problem
86
- *
87
- * We want to delay the unmount of children until a CSS exit transition has
88
- * finished playing. If we unmount children the moment `isOpen` becomes
89
- * `false`, the exit animation is never visible - the content just disappears.
90
- *
91
- * ## How it works
92
- *
93
- * The lifecycle is modeled as a `phase` discriminated union (`closed`,
94
- * `entering`, `open`, `exiting`). The host element is rendered while
95
- * `phase !== 'closed'`, so the `exiting` phase keeps the host mounted
96
- * while the CSS exit transition plays (or, with animation disabled,
97
- * while we wait for the browser `toggle` / `close` event to fire on the
98
- * still-attached element):
99
- *
100
- * ```
101
- * isOpen: true ──────────────── false
102
- * phase: open ──────────────── exiting ─── (exit settle) ─── closed
103
- * ```
104
- *
105
- * Every effect dispatches on the single `phase` value instead of a
106
- * cross-product of booleans.
107
- */
108
- export declare function useAnimatedVisibility({ isOpen, animate, elementRef, onEnterFinish, onExitFinish, }: TUseAnimatedVisibilityArgs): TUseAnimatedVisibilityResult;
109
- export {};