@mortenbrudvik/waveui 0.11.0 → 0.12.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/README.md +97 -2
- package/dist/components/button/Link.cjs +1 -1
- package/dist/components/button/Link.cjs.map +1 -1
- package/dist/components/button/Link.mjs +4 -4
- package/dist/components/data-display/AvatarGroup.cjs +1 -1
- package/dist/components/data-display/AvatarGroup.cjs.map +1 -1
- package/dist/components/data-display/AvatarGroup.mjs +10 -10
- package/dist/components/data-display/InfoButton.cjs +1 -1
- package/dist/components/data-display/InfoButton.cjs.map +1 -1
- package/dist/components/data-display/InfoButton.mjs +12 -12
- package/dist/components/feedback/Toaster.cjs +1 -1
- package/dist/components/feedback/Toaster.cjs.map +1 -1
- package/dist/components/feedback/Toaster.mjs +235 -235
- package/dist/components/feedback/Toaster.mjs.map +1 -1
- package/dist/components/input/Combobox.cjs +1 -1
- package/dist/components/input/Combobox.cjs.map +1 -1
- package/dist/components/input/Combobox.mjs +176 -175
- package/dist/components/input/Combobox.mjs.map +1 -1
- package/dist/components/input/DatePicker.cjs +1 -1
- package/dist/components/input/DatePicker.cjs.map +1 -1
- package/dist/components/input/DatePicker.mjs +188 -187
- package/dist/components/input/DatePicker.mjs.map +1 -1
- package/dist/components/input/Dropdown.cjs +1 -1
- package/dist/components/input/Dropdown.cjs.map +1 -1
- package/dist/components/input/Dropdown.mjs +41 -40
- package/dist/components/input/Dropdown.mjs.map +1 -1
- package/dist/components/input/Option.cjs +1 -1
- package/dist/components/input/Option.cjs.map +1 -1
- package/dist/components/input/Option.mjs +89 -87
- package/dist/components/input/Option.mjs.map +1 -1
- package/dist/components/input/TagPicker.root.cjs +1 -1
- package/dist/components/input/TagPicker.root.cjs.map +1 -1
- package/dist/components/input/TagPicker.root.mjs +136 -135
- package/dist/components/input/TagPicker.root.mjs.map +1 -1
- package/dist/components/input/TimePicker.cjs +1 -1
- package/dist/components/input/TimePicker.cjs.map +1 -1
- package/dist/components/input/TimePicker.mjs +156 -154
- package/dist/components/input/TimePicker.mjs.map +1 -1
- package/dist/components/navigation/Menu.popover.cjs +1 -1
- package/dist/components/navigation/Menu.popover.cjs.map +1 -1
- package/dist/components/navigation/Menu.popover.mjs +137 -127
- package/dist/components/navigation/Menu.popover.mjs.map +1 -1
- package/dist/components/navigation/Menu.root.cjs +1 -1
- package/dist/components/navigation/Menu.root.cjs.map +1 -1
- package/dist/components/navigation/Menu.root.mjs +4 -4
- package/dist/components/overlays/Dialog.cjs +1 -1
- package/dist/components/overlays/Dialog.cjs.map +1 -1
- package/dist/components/overlays/Dialog.mjs +123 -123
- package/dist/components/overlays/Dialog.mjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.cjs +1 -1
- package/dist/components/overlays/Drawer.panel.cjs.map +1 -1
- package/dist/components/overlays/Drawer.panel.mjs +12 -12
- package/dist/components/overlays/Drawer.panel.mjs.map +1 -1
- package/dist/components/overlays/Popover.cjs +1 -1
- package/dist/components/overlays/Popover.cjs.map +1 -1
- package/dist/components/overlays/Popover.mjs +173 -162
- package/dist/components/overlays/Popover.mjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.cjs +1 -1
- package/dist/components/overlays/TeachingPopover.cjs.map +1 -1
- package/dist/components/overlays/TeachingPopover.mjs +96 -91
- package/dist/components/overlays/TeachingPopover.mjs.map +1 -1
- package/dist/components/overlays/Tooltip.cjs +1 -1
- package/dist/components/overlays/Tooltip.cjs.map +1 -1
- package/dist/components/overlays/Tooltip.mjs +47 -47
- package/dist/components/overlays/Tooltip.mjs.map +1 -1
- package/dist/components/portal/Portal.cjs +1 -1
- package/dist/components/portal/Portal.cjs.map +1 -1
- package/dist/components/portal/Portal.mjs +5 -5
- package/dist/components/table/DataGrid.cjs +1 -1
- package/dist/components/table/DataGrid.cjs.map +1 -1
- package/dist/components/table/DataGrid.mjs +1 -1
- package/dist/hooks/useDismiss.cjs.map +1 -1
- package/dist/hooks/useDismiss.mjs.map +1 -1
- package/dist/hooks/useFocusTrap.cjs.map +1 -1
- package/dist/hooks/useFocusTrap.mjs.map +1 -1
- package/dist/hooks/useFocusVisible.cjs +2 -0
- package/dist/hooks/useFocusVisible.cjs.map +1 -0
- package/dist/hooks/useFocusVisible.mjs +49 -0
- package/dist/hooks/useFocusVisible.mjs.map +1 -0
- package/dist/hooks/useFocusableGroup.cjs +2 -0
- package/dist/hooks/useFocusableGroup.cjs.map +1 -0
- package/dist/hooks/useFocusableGroup.mjs +70 -0
- package/dist/hooks/useFocusableGroup.mjs.map +1 -0
- package/dist/hooks/useModalLayer.cjs +1 -1
- package/dist/hooks/useModalLayer.cjs.map +1 -1
- package/dist/hooks/useModalLayer.mjs +4 -4
- package/dist/hooks/useModalOpen.cjs +2 -0
- package/dist/hooks/useModalOpen.cjs.map +1 -0
- package/dist/hooks/useModalOpen.mjs +14 -0
- package/dist/hooks/useModalOpen.mjs.map +1 -0
- package/dist/hooks/usePopupPosition.cjs +1 -1
- package/dist/hooks/usePopupPosition.cjs.map +1 -1
- package/dist/hooks/usePopupPosition.mjs +82 -53
- package/dist/hooks/usePopupPosition.mjs.map +1 -1
- package/dist/hooks/useResolvedTarget.cjs +2 -0
- package/dist/hooks/useResolvedTarget.cjs.map +1 -0
- package/dist/hooks/useResolvedTarget.mjs +37 -0
- package/dist/hooks/useResolvedTarget.mjs.map +1 -0
- package/dist/hooks/useRovingGrid.cjs +1 -1
- package/dist/hooks/useRovingGrid.cjs.map +1 -1
- package/dist/hooks/useRovingGrid.mjs +8 -57
- package/dist/hooks/useRovingGrid.mjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.cjs +1 -1
- package/dist/hooks/useRovingTabIndex.cjs.map +1 -1
- package/dist/hooks/useRovingTabIndex.mjs +142 -107
- package/dist/hooks/useRovingTabIndex.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +814 -18
- package/dist/index.d.ts +814 -18
- package/dist/index.mjs +120 -108
- package/dist/lib/layers.cjs +1 -1
- package/dist/lib/layers.cjs.map +1 -1
- package/dist/lib/layers.mjs +112 -109
- package/dist/lib/layers.mjs.map +1 -1
- package/dist/styles.css +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -2345,6 +2345,13 @@ export declare interface ComboboxProps<M extends boolean = false> extends Omit<R
|
|
|
2345
2345
|
* listbox keeps its size.
|
|
2346
2346
|
*/
|
|
2347
2347
|
size?: CoreSize;
|
|
2348
|
+
/**
|
|
2349
|
+
* Advanced positioning of the popup (Fluent's `positioning`): `offset`, `fitViewport`,
|
|
2350
|
+
* `matchReferenceWidth` and `fallbackPlacements` (tried in order when the requested side has no
|
|
2351
|
+
* room). The popup opens below the field.
|
|
2352
|
+
* @default `{ matchReferenceWidth: true, fitViewport: true }`
|
|
2353
|
+
*/
|
|
2354
|
+
positioning?: PopupPositioningOptions;
|
|
2348
2355
|
/**
|
|
2349
2356
|
* Look of the field: `outline` (a full border), `underline` (a bottom stroke only),
|
|
2350
2357
|
* `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible
|
|
@@ -3239,6 +3246,13 @@ export declare interface DatePickerProps extends Omit<React_2.HTMLAttributes<HTM
|
|
|
3239
3246
|
* calendar keeps its size.
|
|
3240
3247
|
*/
|
|
3241
3248
|
size?: CoreSize;
|
|
3249
|
+
/**
|
|
3250
|
+
* Advanced positioning of the popup (Fluent's `positioning`): `offset`, `fitViewport`,
|
|
3251
|
+
* `matchReferenceWidth` and `fallbackPlacements` (tried in order when the requested side has no
|
|
3252
|
+
* room). The popup opens below the field.
|
|
3253
|
+
* @default `{}`: the calendar opens 4px below the field
|
|
3254
|
+
*/
|
|
3255
|
+
positioning?: PopupPositioningOptions;
|
|
3242
3256
|
/**
|
|
3243
3257
|
* Look of the field: `outline` (a full border), `underline` (a bottom stroke only),
|
|
3244
3258
|
* `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible
|
|
@@ -3799,6 +3813,23 @@ export declare interface DialogTriggerRenderProps extends React_2.HTMLAttributes
|
|
|
3799
3813
|
ref: React_2.RefCallback<HTMLElement>;
|
|
3800
3814
|
}
|
|
3801
3815
|
|
|
3816
|
+
/** Returned by {@link useDismiss}. */
|
|
3817
|
+
export declare interface DismissLayer {
|
|
3818
|
+
/** The layer's id: pass it to `Portal layerId` or `DismissLayerProvider` around the surface. */
|
|
3819
|
+
layerId: string;
|
|
3820
|
+
/** Whether the layer is currently the topmost open layer (read at call time). */
|
|
3821
|
+
isTopmost(): boolean;
|
|
3822
|
+
}
|
|
3823
|
+
|
|
3824
|
+
/**
|
|
3825
|
+
* Makes `layerId` the parent layer of everything rendered inside (`Portal layerId` does this for
|
|
3826
|
+
* its children automatically).
|
|
3827
|
+
*/
|
|
3828
|
+
export declare function DismissLayerProvider(props: {
|
|
3829
|
+
layerId: string;
|
|
3830
|
+
children: React_2.ReactNode;
|
|
3831
|
+
}): React_2.ReactElement;
|
|
3832
|
+
|
|
3802
3833
|
/** Why a popup layer is dismissed: Escape, a press outside it, or focus moving outside it. */
|
|
3803
3834
|
export declare type DismissReason = 'escape' | 'outside-press' | 'focus-outside';
|
|
3804
3835
|
|
|
@@ -4697,6 +4728,13 @@ export declare interface DropdownProps<M extends boolean = false> extends Omit<R
|
|
|
4697
4728
|
* listbox keeps its size; the multi-select value text and clear button follow it.
|
|
4698
4729
|
*/
|
|
4699
4730
|
size?: CoreSize;
|
|
4731
|
+
/**
|
|
4732
|
+
* Advanced positioning of the popup (Fluent's `positioning`): `offset`, `fitViewport`,
|
|
4733
|
+
* `matchReferenceWidth` and `fallbackPlacements` (tried in order when the requested side has no
|
|
4734
|
+
* room). The popup opens below the field.
|
|
4735
|
+
* @default `{ matchReferenceWidth: true, fitViewport: true }`
|
|
4736
|
+
*/
|
|
4737
|
+
positioning?: PopupPositioningOptions;
|
|
4700
4738
|
/**
|
|
4701
4739
|
* Look of the field: `outline` (a full border), `underline` (a bottom stroke only),
|
|
4702
4740
|
* `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible
|
|
@@ -5190,12 +5228,54 @@ export declare interface FlexOwnProps {
|
|
|
5190
5228
|
*/
|
|
5191
5229
|
export declare type FlexProps<C extends React_2.ElementType = 'div'> = PolymorphicProps<C, FlexOwnProps>;
|
|
5192
5230
|
|
|
5231
|
+
/** Props to spread onto the group element (compose its handlers with your own). */
|
|
5232
|
+
export declare interface FocusableGroupProps {
|
|
5233
|
+
/** The group is itself focusable. */
|
|
5234
|
+
tabIndex: 0;
|
|
5235
|
+
onKeyDown: React_2.KeyboardEventHandler<HTMLElement>;
|
|
5236
|
+
onFocusCapture: React_2.FocusEventHandler<HTMLElement>;
|
|
5237
|
+
/** Marks the element as a group: nested groups own their own contents. */
|
|
5238
|
+
'data-focusable-group': '';
|
|
5239
|
+
}
|
|
5240
|
+
|
|
5241
|
+
/** How Tab and Enter treat the elements inside a focusable group. */
|
|
5242
|
+
export declare type FocusableGroupTabBehavior = 'unlimited' | 'limited' | 'limited-trap-focus';
|
|
5243
|
+
|
|
5193
5244
|
/**
|
|
5194
5245
|
* How the keyboard reaches the items of a set: `'tab'`, every item is a Tab stop and the arrow
|
|
5195
5246
|
* keys do nothing; `'arrow'`, the set is one Tab stop and the arrow keys move between its items.
|
|
5196
5247
|
*/
|
|
5197
5248
|
export declare type FocusMode = 'tab' | 'arrow';
|
|
5198
5249
|
|
|
5250
|
+
/** Focus-visible ring for focusable controls (C-FOCUS). */
|
|
5251
|
+
export declare const focusRing = "focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-ring";
|
|
5252
|
+
|
|
5253
|
+
/** Focus-visible ring drawn inside the element: cells, rows, list and menu items. */
|
|
5254
|
+
export declare const focusRingInset = "focus-visible:outline-2 focus-visible:-outline-offset-2 focus-visible:outline-ring";
|
|
5255
|
+
|
|
5256
|
+
/** The first tabbable element inside `container`, or `null`. */
|
|
5257
|
+
export declare function getFirstTabbable(container: Element, options?: {
|
|
5258
|
+
includeContainer?: boolean;
|
|
5259
|
+
}): HTMLElement | null;
|
|
5260
|
+
|
|
5261
|
+
/** The last tabbable element inside `container`, or `null`. */
|
|
5262
|
+
export declare function getLastTabbable(container: Element, options?: {
|
|
5263
|
+
includeContainer?: boolean;
|
|
5264
|
+
}): HTMLElement | null;
|
|
5265
|
+
|
|
5266
|
+
/**
|
|
5267
|
+
* The tabbable elements inside `container` in sequential focus order: positive `tabindex` first
|
|
5268
|
+
* (ascending), then `tabindex=0` / natively tabbable elements in document order. Named radio
|
|
5269
|
+
* groups follow {@link isTabbable}, so the result depends on where focus currently is: when focus
|
|
5270
|
+
* is on a radio, the rest of its group is left out, which makes the focused radio the last entry
|
|
5271
|
+
* when its group ends the container (the element a focus trap wraps from).
|
|
5272
|
+
*
|
|
5273
|
+
* @param options.includeContainer Also consider `container` itself.
|
|
5274
|
+
*/
|
|
5275
|
+
export declare function getTabbableElements(container: Element, options?: {
|
|
5276
|
+
includeContainer?: boolean;
|
|
5277
|
+
}): HTMLElement[];
|
|
5278
|
+
|
|
5199
5279
|
/**
|
|
5200
5280
|
* The classes that select a theme's tokens: `'wave-light'`, `'wave-dark dark'` or
|
|
5201
5281
|
* `'wave-high-contrast high-contrast'`. Unknown values fall back to the light classes. Safe to call
|
|
@@ -5246,6 +5326,13 @@ export declare const gridClassNames: {
|
|
|
5246
5326
|
readonly root: "wave-grid";
|
|
5247
5327
|
};
|
|
5248
5328
|
|
|
5329
|
+
/** Handlers {@link useGridNavigation} needs on the grid element (compose them with the consumer's). */
|
|
5330
|
+
export declare interface GridNavigationHandlers {
|
|
5331
|
+
onKeyDown: React_2.KeyboardEventHandler<HTMLTableElement>;
|
|
5332
|
+
onFocus: React_2.FocusEventHandler<HTMLTableElement>;
|
|
5333
|
+
onBlur: React_2.FocusEventHandler<HTMLTableElement>;
|
|
5334
|
+
}
|
|
5335
|
+
|
|
5249
5336
|
/**
|
|
5250
5337
|
* The Grid's own props (the XOwnProps rule of `PolymorphicProps`: component-specific props only).
|
|
5251
5338
|
* Every other prop comes from the rendered element (`as`).
|
|
@@ -5339,6 +5426,13 @@ export declare interface HamburgerProps extends React_2.ButtonHTMLAttributes<HTM
|
|
|
5339
5426
|
ref?: React_2.Ref<HTMLButtonElement>;
|
|
5340
5427
|
}
|
|
5341
5428
|
|
|
5429
|
+
/**
|
|
5430
|
+
* Whether a modal surface is open now: a layer of kind `'modal'` (a Dialog, an overlay Drawer, an
|
|
5431
|
+
* alert, the DatePicker's calendar, or your own `useDismiss({ kind: 'modal' })`). A non-modal
|
|
5432
|
+
* surface is no modal. Server-safe: `false` when no layer is registered, as on the server.
|
|
5433
|
+
*/
|
|
5434
|
+
export declare function hasOpenModal(): boolean;
|
|
5435
|
+
|
|
5342
5436
|
/** Level of a heading element, `<h1>` … `<h6>`. */
|
|
5343
5437
|
export declare type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6;
|
|
5344
5438
|
|
|
@@ -5732,6 +5826,20 @@ export declare interface InputErrorMessageProps extends React_2.HTMLAttributes<H
|
|
|
5732
5826
|
[dataAttribute: `data-${string}`]: unknown;
|
|
5733
5827
|
}
|
|
5734
5828
|
|
|
5829
|
+
/**
|
|
5830
|
+
* Focus indicator of text-entry controls: a 2px primary bottom border. `focus:outline-hidden`
|
|
5831
|
+
* removes the outline while focused but — unlike `outline-none` — keeps a visible outline in
|
|
5832
|
+
* forced-colors mode, where the border colour change is not perceivable. (Scoped to `:focus` so
|
|
5833
|
+
* unfocused inputs do not show that outline in forced colors.)
|
|
5834
|
+
*/
|
|
5835
|
+
export declare const inputFocus = "focus:outline-hidden focus:border-b-2 focus:border-b-primary";
|
|
5836
|
+
|
|
5837
|
+
/**
|
|
5838
|
+
* Wrapper form of {@link inputFocus} for inputs rendered inside a styled wrapper (slots,
|
|
5839
|
+
* SearchBox, TagPicker). Put `focus:outline-hidden` on the inner control.
|
|
5840
|
+
*/
|
|
5841
|
+
export declare const inputFocusWithin = "focus-within:border-b-2 focus-within:border-b-primary";
|
|
5842
|
+
|
|
5735
5843
|
/** Properties for the Input component. */
|
|
5736
5844
|
export declare interface InputProps extends Omit<React_2.InputHTMLAttributes<HTMLInputElement>, 'size'> {
|
|
5737
5845
|
/**
|
|
@@ -6035,6 +6143,16 @@ export declare interface LabelProps extends React_2.LabelHTMLAttributes<HTMLLabe
|
|
|
6035
6143
|
ref?: React_2.Ref<HTMLLabelElement>;
|
|
6036
6144
|
}
|
|
6037
6145
|
|
|
6146
|
+
/**
|
|
6147
|
+
* What kind of surface a layer is. `modal` marks dialog-like surfaces (focus-restore validation and
|
|
6148
|
+
* modal isolation look for them); a modal blocks presses and Escape for the layers below it only
|
|
6149
|
+
* while its page isolation is active ({@link registerLayerIsolation}). `dialog` marks a non-modal
|
|
6150
|
+
* Dialog or Drawer: it shields nothing (no isolation), takes Escape only from inside its tree
|
|
6151
|
+
* (`escape: 'inside'`), and the Toaster moves out of its way; focus-restore validation and modal
|
|
6152
|
+
* isolation do not count it.
|
|
6153
|
+
*/
|
|
6154
|
+
export declare type LayerKind = 'modal' | 'dialog' | 'popover' | 'menu' | 'listbox' | 'tooltip' | 'toast';
|
|
6155
|
+
|
|
6038
6156
|
/**
|
|
6039
6157
|
* A hyperlink with Fluent link styling. Renders an `<a>` by default; `as` renders a router link
|
|
6040
6158
|
* (`<Link as={RouterLink} to="/">`) or a `<button>` styled as a link (`type="button"` by default).
|
|
@@ -6834,7 +6952,7 @@ export declare const Menu: {
|
|
|
6834
6952
|
displayName: string;
|
|
6835
6953
|
};
|
|
6836
6954
|
Popover: {
|
|
6837
|
-
({ side, align, offset, target, children, className, style, onKeyDown, onKeyDownCapture, onFocus, onPointerEnter, onPointerLeave, onPointerMove, onContextMenu, ref, ...rest }: MenuPopoverProps): JSX.Element | null;
|
|
6955
|
+
({ side, align, offset, target: targetProp, positioning, children, className, style, onKeyDown, onKeyDownCapture, onFocus, onPointerEnter, onPointerLeave, onPointerMove, onContextMenu, ref, ...rest }: MenuPopoverProps): JSX.Element | null;
|
|
6838
6956
|
displayName: string;
|
|
6839
6957
|
};
|
|
6840
6958
|
ItemCheckbox: {
|
|
@@ -7305,7 +7423,7 @@ export declare interface MenuItemSwitchProps extends MenuItemProps, MenuItemSele
|
|
|
7305
7423
|
* Also exported as `MenuPopover` (import the flat name from React Server Components).
|
|
7306
7424
|
*/
|
|
7307
7425
|
export declare const MenuPopover: {
|
|
7308
|
-
({ side, align, offset, target, children, className, style, onKeyDown, onKeyDownCapture, onFocus, onPointerEnter, onPointerLeave, onPointerMove, onContextMenu, ref, ...rest }: MenuPopoverProps): React_2.JSX.Element | null;
|
|
7426
|
+
({ side, align, offset, target: targetProp, positioning, children, className, style, onKeyDown, onKeyDownCapture, onFocus, onPointerEnter, onPointerLeave, onPointerMove, onContextMenu, ref, ...rest }: MenuPopoverProps): React_2.JSX.Element | null;
|
|
7309
7427
|
displayName: string;
|
|
7310
7428
|
};
|
|
7311
7429
|
|
|
@@ -7331,11 +7449,18 @@ export declare interface MenuPopoverProps extends Omit<React_2.HTMLAttributes<HT
|
|
|
7331
7449
|
* with a `target` needs no trigger; name it with `aria-label`, and give a toggle button you use
|
|
7332
7450
|
* as the target `aria-haspopup="menu"` and `aria-expanded` yourself (the menu's `id` is
|
|
7333
7451
|
* generated, so the toggle cannot point `aria-controls` at it). A press on a target element
|
|
7334
|
-
* does not close the menu. Hold the element in state
|
|
7335
|
-
*
|
|
7452
|
+
* does not close the menu. Hold the element in state, or pass a ref object (read after
|
|
7453
|
+
* each render of the menu). A menu opened by `openOnContext` is placed at
|
|
7336
7454
|
* the gesture instead.
|
|
7337
7455
|
*/
|
|
7338
|
-
target?:
|
|
7456
|
+
target?: PopupTargetInput;
|
|
7457
|
+
/**
|
|
7458
|
+
* Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`,
|
|
7459
|
+
* `fallbackPlacements` and `target` (used when the `target` prop is not set). `side` and `align`
|
|
7460
|
+
* stay separate props, and the `offset` prop wins over `positioning.offset`.
|
|
7461
|
+
* @default `{ fitViewport: true }`
|
|
7462
|
+
*/
|
|
7463
|
+
positioning?: PopupPositioning;
|
|
7339
7464
|
/** Menu items and dividers. */
|
|
7340
7465
|
children: React_2.ReactNode;
|
|
7341
7466
|
/**
|
|
@@ -7798,6 +7923,22 @@ export declare interface MessageBarTitleProps extends React_2.HTMLAttributes<HTM
|
|
|
7798
7923
|
ref?: React_2.Ref<HTMLSpanElement>;
|
|
7799
7924
|
}
|
|
7800
7925
|
|
|
7926
|
+
/**
|
|
7927
|
+
* Props that mark an app-owned region (a notification area, a live status bar) so that WaveUI's
|
|
7928
|
+
* modal surfaces leave it usable. Spread them on the region's element: `<div {...modalAllowProps}>`.
|
|
7929
|
+
* Over an open Dialog or Drawer the region
|
|
7930
|
+
*
|
|
7931
|
+
* - counts as inside every dismiss layer, so a press in it closes nothing;
|
|
7932
|
+
* - has its tabbable elements in the Tab cycle of every focus trap;
|
|
7933
|
+
* - is never made `inert` by the modal's page isolation.
|
|
7934
|
+
*
|
|
7935
|
+
* The attribute it sets, `data-wave-focus-trap-allow`, is the one the Toaster's own region
|
|
7936
|
+
* carries, and it is a stable contract.
|
|
7937
|
+
*/
|
|
7938
|
+
export declare const modalAllowProps: {
|
|
7939
|
+
readonly 'data-wave-focus-trap-allow': "";
|
|
7940
|
+
};
|
|
7941
|
+
|
|
7801
7942
|
/**
|
|
7802
7943
|
* Why a Dialog or Drawer asks to open or close: `trigger` (its Trigger part), `close` (a
|
|
7803
7944
|
* `.Close` part), `close-button` (the built-in Close button), `escape`, `outside-press` (the
|
|
@@ -9159,7 +9300,7 @@ export declare type PolymorphicProps<C extends React_2.ElementType, OwnProps> =
|
|
|
9159
9300
|
* </Popover>
|
|
9160
9301
|
*/
|
|
9161
9302
|
export declare const Popover: {
|
|
9162
|
-
({ open: openProp, defaultOpen, onOpenChange, side, align, ignoreOutsideRefs, openOnHover, openDelay, closeDelay, openOnContext, target, children, }: PopoverProps): React_2.JSX.Element;
|
|
9303
|
+
({ open: openProp, defaultOpen, onOpenChange, side, align, ignoreOutsideRefs, openOnHover, openDelay, closeDelay, openOnContext, target: targetProp, positioning, children, }: PopoverProps): React_2.JSX.Element;
|
|
9163
9304
|
displayName: string;
|
|
9164
9305
|
} & {
|
|
9165
9306
|
Trigger: {
|
|
@@ -9316,10 +9457,18 @@ export declare interface PopoverProps {
|
|
|
9316
9457
|
* `aria-labelledby`, and give a toggle button you use as the target `aria-haspopup="dialog"`,
|
|
9317
9458
|
* `aria-expanded` and `aria-controls` yourself. A press on a target element does not close the
|
|
9318
9459
|
* popover, and Tab from it enters the content when there is no trigger. Hold the element in
|
|
9319
|
-
* state
|
|
9460
|
+
* state, or pass a ref object (read after each render of the popover, so an element that attaches without it rendering is noticed on its next render). A popover
|
|
9320
9461
|
* opened by `openOnContext` is placed at the gesture instead.
|
|
9321
9462
|
*/
|
|
9322
|
-
target?:
|
|
9463
|
+
target?: PopupTargetInput;
|
|
9464
|
+
/**
|
|
9465
|
+
* Advanced positioning (Fluent's `positioning`): `offset` (px from the anchor), `fitViewport`
|
|
9466
|
+
* (limit the content to the space the viewport leaves; Fluent's `autoSize`), `matchReferenceWidth`,
|
|
9467
|
+
* `fallbackPlacements` (tried in order when the requested side has no room) and `target` (used
|
|
9468
|
+
* when the `target` prop is not set). `side` and `align` stay separate props.
|
|
9469
|
+
* @default `{ offset: 8 }`
|
|
9470
|
+
*/
|
|
9471
|
+
positioning?: PopupPositioning;
|
|
9323
9472
|
/** `Popover.Trigger` and `Popover.Content`. */
|
|
9324
9473
|
children: React_2.ReactNode;
|
|
9325
9474
|
}
|
|
@@ -9404,6 +9553,39 @@ export declare interface PopoverTriggerProps extends Omit<React_2.HTMLAttributes
|
|
|
9404
9553
|
/** Alignment of a popup along the anchor's edge. */
|
|
9405
9554
|
export declare type PopupAlign = 'start' | 'center' | 'end';
|
|
9406
9555
|
|
|
9556
|
+
/** A placement for `PopupPositioning.fallbackPlacements`: a side, and optionally an alignment on it. */
|
|
9557
|
+
export declare interface PopupPlacement {
|
|
9558
|
+
/** Side of the anchor. `start` and `end` follow the writing direction. */
|
|
9559
|
+
side: PopupSide;
|
|
9560
|
+
/** Alignment along that side. @default the surface's own `align` */
|
|
9561
|
+
align?: PopupAlign;
|
|
9562
|
+
}
|
|
9563
|
+
|
|
9564
|
+
/**
|
|
9565
|
+
* The advanced positioning options of a popup (the `positioning` prop; Fluent's `positioning`).
|
|
9566
|
+
* `side` and `align` stay separate props of each component, so every option has one source.
|
|
9567
|
+
*/
|
|
9568
|
+
export declare interface PopupPositioning {
|
|
9569
|
+
/** Distance from the anchor in px. @default the component's own (Popover 8, Tooltip 8, TeachingPopover 12, listboxes 4) */
|
|
9570
|
+
offset?: number;
|
|
9571
|
+
/**
|
|
9572
|
+
* Limit the surface to the space the viewport leaves (Fluent's `autoSize`). Popover also scrolls
|
|
9573
|
+
* its content inside its border; the other surfaces only limit their size (their own lists and
|
|
9574
|
+
* grids scroll as they always did).
|
|
9575
|
+
* @default the component's own
|
|
9576
|
+
*/
|
|
9577
|
+
fitViewport?: boolean;
|
|
9578
|
+
/** Make the surface as wide as its anchor. @default the component's own */
|
|
9579
|
+
matchReferenceWidth?: boolean;
|
|
9580
|
+
/** Placements to try, in order, when the requested side has no room; replaces the opposite side. */
|
|
9581
|
+
fallbackPlacements?: readonly PopupPlacement[];
|
|
9582
|
+
/** Position against this instead of the trigger. */
|
|
9583
|
+
target?: PopupTargetInput;
|
|
9584
|
+
}
|
|
9585
|
+
|
|
9586
|
+
/** {@link PopupPositioning} without `target`: the options of a popup that has no `target` prop. */
|
|
9587
|
+
export declare type PopupPositioningOptions = Omit<PopupPositioning, 'target'>;
|
|
9588
|
+
|
|
9407
9589
|
/** A rectangle in viewport coordinates, as `getBoundingClientRect()` returns it (a `DOMRect` is one). */
|
|
9408
9590
|
export declare interface PopupRect {
|
|
9409
9591
|
x: number;
|
|
@@ -9423,12 +9605,20 @@ export declare interface PopupRect {
|
|
|
9423
9605
|
export declare type PopupSide = 'top' | 'bottom' | 'start' | 'end' | 'left' | 'right';
|
|
9424
9606
|
|
|
9425
9607
|
/**
|
|
9426
|
-
* Where a popup is placed instead of next to its trigger (`Menu.Popover
|
|
9427
|
-
* an element held in state, or a `VirtualElement`.
|
|
9428
|
-
*
|
|
9608
|
+
* Where a popup is placed instead of next to its trigger (`Menu.Popover`, `Popover` and
|
|
9609
|
+
* `TeachingPopover` `target`): an element held in state, or a `VirtualElement`. Those components
|
|
9610
|
+
* also take a ref object (`PopupPositioning['target']`).
|
|
9429
9611
|
*/
|
|
9430
9612
|
export declare type PopupTarget = HTMLElement | VirtualElement | null;
|
|
9431
9613
|
|
|
9614
|
+
/**
|
|
9615
|
+
* What a popup's `target` prop accepts: a {@link PopupTarget}, or a ref object (an element that
|
|
9616
|
+
* attaches without the popup rendering is read after each render of the popup).
|
|
9617
|
+
*/
|
|
9618
|
+
export declare type PopupTargetInput = PopupTarget | {
|
|
9619
|
+
readonly current: HTMLElement | null;
|
|
9620
|
+
};
|
|
9621
|
+
|
|
9432
9622
|
/**
|
|
9433
9623
|
* Renders its children into `document.body` (or the WaveProvider `portalContainer`), wrapped in a
|
|
9434
9624
|
* `<div class="wave-portal …">` that carries the provider's theme classes, direction and font, so
|
|
@@ -9485,6 +9675,16 @@ export declare interface PortalProps {
|
|
|
9485
9675
|
ref?: React_2.Ref<HTMLDivElement>;
|
|
9486
9676
|
}
|
|
9487
9677
|
|
|
9678
|
+
/** What {@link UsePopupPositionOptions.onPositioned} receives. */
|
|
9679
|
+
export declare interface PositionedInfo {
|
|
9680
|
+
/** Final placement after flipping, e.g. `'top-start'`. */
|
|
9681
|
+
placement: string;
|
|
9682
|
+
/** Final physical side after flipping. */
|
|
9683
|
+
side: 'top' | 'bottom' | 'left' | 'right';
|
|
9684
|
+
/** Always `true`: the callback runs once a position exists. */
|
|
9685
|
+
isPositioned: boolean;
|
|
9686
|
+
}
|
|
9687
|
+
|
|
9488
9688
|
/**
|
|
9489
9689
|
* Shows and hides its child with CSS enter and exit motion: the child stays mounted while its exit
|
|
9490
9690
|
* motion runs, `inert` and marked `data-presence="exiting"`, and unmounts when it ends (at once
|
|
@@ -12839,6 +13039,13 @@ export declare interface TagPickerProps extends Omit<React_2.HTMLAttributes<HTML
|
|
|
12839
13039
|
* option list keeps its size.
|
|
12840
13040
|
*/
|
|
12841
13041
|
size?: TagPickerSize;
|
|
13042
|
+
/**
|
|
13043
|
+
* Advanced positioning of the popup (Fluent's `positioning`): `offset`, `fitViewport`,
|
|
13044
|
+
* `matchReferenceWidth` and `fallbackPlacements` (tried in order when the requested side has no
|
|
13045
|
+
* room). The popup opens below the field.
|
|
13046
|
+
* @default `{ matchReferenceWidth: true, fitViewport: true }`
|
|
13047
|
+
*/
|
|
13048
|
+
positioning?: PopupPositioningOptions;
|
|
12842
13049
|
/**
|
|
12843
13050
|
* Look of the field: `outline` (a full border), `underline` (a bottom stroke only),
|
|
12844
13051
|
* `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible
|
|
@@ -12974,7 +13181,9 @@ export declare type TagSize = Extract<Size, 'extra-small' | 'small' | 'medium'>;
|
|
|
12974
13181
|
* - With `target`, the popover is portaled and positioned next to that element with a beak (it
|
|
12975
13182
|
* inherits the surface colors); it stays hidden while the target is `null`, not positioned yet or
|
|
12976
13183
|
* no longer mounted (a ref target is read after each render of the popover; see `target`).
|
|
12977
|
-
* - With `target
|
|
13184
|
+
* - With a `VirtualElement` target there is no element to follow: the popover keeps the place of
|
|
13185
|
+
* its portal in the keyboard order.
|
|
13186
|
+
* - With an element or ref `target`, the keyboard order treats the popover as if it followed the target: Tab past
|
|
12978
13187
|
* its last button continues after the target, Shift+Tab from its first button (or from the
|
|
12979
13188
|
* popover itself) returns to the target (for a target outside the Tab order, to the last control
|
|
12980
13189
|
* inside it, else to the control before it), Tab from there enters the popover, and Shift+Tab
|
|
@@ -12986,7 +13195,7 @@ export declare type TagSize = Extract<Size, 'extra-small' | 'small' | 'medium'>;
|
|
|
12986
13195
|
* it.
|
|
12987
13196
|
*/
|
|
12988
13197
|
export declare const TeachingPopover: {
|
|
12989
|
-
({ steps, activeStep: activeStepProp, defaultActiveStep, currentStep, defaultCurrentStep, onStepChange, onDismiss, open: openProp, defaultOpen, onOpenChange, closeLabel, labels, target, side, align, className, style, onKeyDown, ref, ...rest }: TeachingPopoverProps): React_2.JSX.Element | null;
|
|
13198
|
+
({ steps, activeStep: activeStepProp, defaultActiveStep, currentStep, defaultCurrentStep, onStepChange, onDismiss, open: openProp, defaultOpen, onOpenChange, closeLabel, labels, target: targetProp, positioning, side, align, className, style, onKeyDown, ref, ...rest }: TeachingPopoverProps): React_2.JSX.Element | null;
|
|
12990
13199
|
displayName: string;
|
|
12991
13200
|
};
|
|
12992
13201
|
|
|
@@ -13071,7 +13280,8 @@ export declare interface TeachingPopoverProps extends React_2.HTMLAttributes<HTM
|
|
|
13071
13280
|
*/
|
|
13072
13281
|
labels?: TeachingPopoverLabels;
|
|
13073
13282
|
/**
|
|
13074
|
-
* The element the popover points at (a ref
|
|
13283
|
+
* The element the popover points at (a ref, the element, or a `VirtualElement`: a rectangle such as a
|
|
13284
|
+
* point; an inline object is fine). When given, the popover is
|
|
13075
13285
|
* rendered in a portal, positioned next to it with a beak, and flips or shifts to stay in view;
|
|
13076
13286
|
* without it (`undefined`) the popover renders inline where it is placed (0.4 behaviour).
|
|
13077
13287
|
* While the target is `null` or has not been positioned against yet (an element held in state
|
|
@@ -13092,7 +13302,7 @@ export declare interface TeachingPopoverProps extends React_2.HTMLAttributes<HTM
|
|
|
13092
13302
|
* attached hides the popover right after that commit. Pass the element held in state when the
|
|
13093
13303
|
* target can mount or unmount without the popover re-rendering.
|
|
13094
13304
|
*/
|
|
13095
|
-
target?: React_2.RefObject<HTMLElement | null> | HTMLElement | null;
|
|
13305
|
+
target?: React_2.RefObject<HTMLElement | null> | HTMLElement | VirtualElement | null;
|
|
13096
13306
|
/** Side of the `target` to open on; `start`/`end` follow the writing direction.
|
|
13097
13307
|
* @default 'bottom'
|
|
13098
13308
|
*/
|
|
@@ -13101,6 +13311,13 @@ export declare interface TeachingPopoverProps extends React_2.HTMLAttributes<HTM
|
|
|
13101
13311
|
* @default 'center'
|
|
13102
13312
|
*/
|
|
13103
13313
|
align?: PopupAlign;
|
|
13314
|
+
/**
|
|
13315
|
+
* Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`,
|
|
13316
|
+
* `fallbackPlacements` and `target` (used when the `target` prop is not set). `side` and `align`
|
|
13317
|
+
* stay separate props.
|
|
13318
|
+
* @default `{ offset: 12 }`
|
|
13319
|
+
*/
|
|
13320
|
+
positioning?: PopupPositioning;
|
|
13104
13321
|
/** Ref to the popover surface (`role="dialog"`). */
|
|
13105
13322
|
ref?: React_2.Ref<HTMLDivElement>;
|
|
13106
13323
|
}
|
|
@@ -13390,6 +13607,13 @@ export declare interface TimePickerProps extends Omit<React_2.HTMLAttributes<HTM
|
|
|
13390
13607
|
* list keeps its size.
|
|
13391
13608
|
*/
|
|
13392
13609
|
size?: CoreSize;
|
|
13610
|
+
/**
|
|
13611
|
+
* Advanced positioning of the popup (Fluent's `positioning`): `offset`, `fitViewport`,
|
|
13612
|
+
* `matchReferenceWidth` and `fallbackPlacements` (tried in order when the requested side has no
|
|
13613
|
+
* room). The popup opens below the field.
|
|
13614
|
+
* @default `{ matchReferenceWidth: true, fitViewport: true }`
|
|
13615
|
+
*/
|
|
13616
|
+
positioning?: PopupPositioningOptions;
|
|
13393
13617
|
/**
|
|
13394
13618
|
* Look of the field: `outline` (a full border), `underline` (a bottom stroke only),
|
|
13395
13619
|
* `filled-darker` or `filled-lighter` (a fill without a visible stroke: give the field a visible
|
|
@@ -14319,7 +14543,7 @@ export declare interface ToolbarToggleButtonProps extends Omit<ToggleButtonProps
|
|
|
14319
14543
|
* </Menu>
|
|
14320
14544
|
*/
|
|
14321
14545
|
export declare const Tooltip: {
|
|
14322
|
-
({ content, appearance: appearanceProp, variant, openDelay: openDelayProp, closeDelay, delay, open: openProp, defaultOpen, onOpenChange, relationship, side, align, children, className, onMouseEnter, onMouseLeave, onFocus, onBlur, ref, ...rest }: TooltipProps): React_2.JSX.Element;
|
|
14546
|
+
({ content, appearance: appearanceProp, variant, openDelay: openDelayProp, closeDelay, delay, open: openProp, defaultOpen, onOpenChange, relationship, side, align, positioning, children, className, onMouseEnter, onMouseLeave, onFocus, onBlur, ref, ...rest }: TooltipProps): React_2.JSX.Element;
|
|
14323
14547
|
displayName: string;
|
|
14324
14548
|
};
|
|
14325
14549
|
|
|
@@ -14395,6 +14619,13 @@ export declare interface TooltipProps extends Omit<React_2.HTMLAttributes<HTMLSp
|
|
|
14395
14619
|
* @default 'center'
|
|
14396
14620
|
*/
|
|
14397
14621
|
align?: PopupAlign;
|
|
14622
|
+
/**
|
|
14623
|
+
* Advanced positioning (Fluent's `positioning`): `offset`, `fitViewport`, `matchReferenceWidth`
|
|
14624
|
+
* and `fallbackPlacements`. `side` and `align` stay separate props. The hover bridge across the
|
|
14625
|
+
* gap covers the default 8px, so a larger `offset` leaves a gap the pointer cannot cross.
|
|
14626
|
+
* @default `{ offset: 8 }`
|
|
14627
|
+
*/
|
|
14628
|
+
positioning?: PopupPositioningOptions;
|
|
14398
14629
|
/**
|
|
14399
14630
|
* A single element that triggers the tooltip on hover and focus: it receives the
|
|
14400
14631
|
* `aria-describedby`/`aria-labelledby`, plus any `id` and `aria-*` props given to the Tooltip
|
|
@@ -14817,6 +15048,82 @@ export declare function useAnnounce(): (message: string, politeness?: Politeness
|
|
|
14817
15048
|
*/
|
|
14818
15049
|
export declare function useControllable<T>(controlledValue: T | undefined, defaultValue: T, onChange?: (value: T) => void): [value: T, setValue: SetValue<T>, isControlled: boolean];
|
|
14819
15050
|
|
|
15051
|
+
/**
|
|
15052
|
+
* Registers an open overlay surface as a **dismiss layer** in the shared layer stack and closes it
|
|
15053
|
+
* on Escape, outside presses and (optionally) focus leaving it — with correct nesting:
|
|
15054
|
+
*
|
|
15055
|
+
* - **Escape** (document `keydown`, bubble phase) is routed by focus location: the innermost layer
|
|
15056
|
+
* whose tree contains the event target or the focused element is the scope, and the topmost
|
|
15057
|
+
* escape-enabled layer of that scope's subtree handles it — so a tooltip or popover opened from
|
|
15058
|
+
* the focused dialog closes before the dialog, while an unrelated layer opened later does not
|
|
15059
|
+
* steal the key. With no escape-enabled layer there, an escape-enabled ancestor handles it; when
|
|
15060
|
+
* no layer contains the focus (or none of those takes Escape), the global topmost
|
|
15061
|
+
* escape-enabled one. Layers stacked below the topmost **isolating** modal (a Dialog/Drawer
|
|
15062
|
+
* whose `useModalIsolation` is active — its ancestors and older siblings) never take Escape, so
|
|
15063
|
+
* a modal that ignores Escape blocks it whether it is nested in a dialog or opened beside it.
|
|
15064
|
+
* A layer with `escape: 'inside'` (a non-modal Dialog or Drawer) takes Escape only while the
|
|
15065
|
+
* event target or the focused element is in its tree, so an Escape typed on the page leaves it
|
|
15066
|
+
* open and goes to the layers below it.
|
|
15067
|
+
* The handler calls `preventDefault()`. Events whose default is already prevented (an inner
|
|
15068
|
+
* widget consumed Escape) and IME composition events are ignored.
|
|
15069
|
+
* - **Outside press**: on `pointerdown` (capture) every open layer whose tree does not contain the
|
|
15070
|
+
* target is recorded; on the following `click` each recorded layer whose tree still does not
|
|
15071
|
+
* contain the click target is dismissed (children first). A drag from inside to outside never
|
|
15072
|
+
* dismisses, clicks inside nested portaled layers count as inside, a popup opened by the same
|
|
15073
|
+
* click survives, and an external toggle works. Layers stacked below the topmost isolating modal
|
|
15074
|
+
* are inert and never dismissed by presses on that modal or its backdrop; a `kind: 'modal'`
|
|
15075
|
+
* layer without isolation (the DatePicker calendar) shields nothing, so a page click closes it
|
|
15076
|
+
* and the layers around it. The pending press survives modifier keys (Shift/Ctrl+click) and
|
|
15077
|
+
* ends on Enter/Space, on `pointercancel`, or when no click follows a mouse `pointerup` in the
|
|
15078
|
+
* same task; touch and pen presses are kept until their click, which the browser dispatches
|
|
15079
|
+
* from a separate tap gesture.
|
|
15080
|
+
* - **Focus outside** (`focusOutside: true`): dismisses when focus moves outside the layer's tree.
|
|
15081
|
+
* That is decided in a microtask, once the current commit has run: an `autoFocus` field of a
|
|
15082
|
+
* popover, dialog or plain portal opened inside the layer gets focus before that surface's
|
|
15083
|
+
* portal and layer register, and keeps the layer open. Focus that is back inside the tree by
|
|
15084
|
+
* then keeps it open too.
|
|
15085
|
+
*
|
|
15086
|
+
* A layer's tree is its `refs`, the portal wrappers rendered inside it, its descendant layers and
|
|
15087
|
+
* the `[data-wave-focus-trap-allow]` regions (toasts). Parentage follows the React tree: wrap the surface in
|
|
15088
|
+
* `Portal layerId={layerId}` (or {@link DismissLayerProvider}) so layers opened inside it become
|
|
15089
|
+
* its children.
|
|
15090
|
+
*
|
|
15091
|
+
* @example
|
|
15092
|
+
* const { layerId } = useDismiss({ open, onDismiss: () => setOpen(false), refs: [surfaceRef, triggerRef], anchorRef: triggerRef });
|
|
15093
|
+
* return open && <Portal layerId={layerId}><div ref={surfaceRef}>…</div></Portal>;
|
|
15094
|
+
*/
|
|
15095
|
+
export declare function useDismiss(options: UseDismissOptions): DismissLayer;
|
|
15096
|
+
|
|
15097
|
+
/** Options of {@link useDismiss}. */
|
|
15098
|
+
export declare interface UseDismissOptions {
|
|
15099
|
+
/** Whether the layer is open; the layer is registered only while `true`. */
|
|
15100
|
+
open: boolean;
|
|
15101
|
+
/** Called when the layer should close (the component sets its `open` state to `false`). */
|
|
15102
|
+
onDismiss: (reason: DismissReason, event: Event) => void;
|
|
15103
|
+
/**
|
|
15104
|
+
* Elements that belong to the layer: the content surface, the trigger/anchor and any extra
|
|
15105
|
+
* targets that must not count as "outside" (read at event time).
|
|
15106
|
+
*/
|
|
15107
|
+
refs: ReadonlyArray<React_2.RefObject<HTMLElement | null>>;
|
|
15108
|
+
/** The trigger; focus traps leave a descendant layer through it (Tab → the element after it). */
|
|
15109
|
+
anchorRef?: React_2.RefObject<HTMLElement | null>;
|
|
15110
|
+
/** @default 'popover' */
|
|
15111
|
+
kind?: LayerKind;
|
|
15112
|
+
/**
|
|
15113
|
+
* Whether Escape dismisses the layer: always (`true`), never (`false`), or only while the key's
|
|
15114
|
+
* target or the focused element is in the layer's tree (`'inside'`).
|
|
15115
|
+
* @default true
|
|
15116
|
+
*/
|
|
15117
|
+
escape?: boolean | 'inside';
|
|
15118
|
+
/**
|
|
15119
|
+
* Whether a press outside the layer's tree dismisses it. A predicate receives the `pointerdown`
|
|
15120
|
+
* event; returning `false` ignores that press. @default true
|
|
15121
|
+
*/
|
|
15122
|
+
outsidePress?: boolean | ((event: PointerEvent | MouseEvent) => boolean);
|
|
15123
|
+
/** Whether focus moving outside the layer's tree dismisses it (listboxes). @default false */
|
|
15124
|
+
focusOutside?: boolean;
|
|
15125
|
+
}
|
|
15126
|
+
|
|
14820
15127
|
/**
|
|
14821
15128
|
* Returns a callback with a stable identity that always invokes the latest `fn` passed to the hook.
|
|
14822
15129
|
* Use it for handlers read by effects or passed to memoised children, so neither re-runs when the
|
|
@@ -14891,6 +15198,172 @@ export declare interface UseFieldControlOptions {
|
|
|
14891
15198
|
nativeRequired?: boolean;
|
|
14892
15199
|
}
|
|
14893
15200
|
|
|
15201
|
+
/**
|
|
15202
|
+
* A focusable group (Fluent's `useFocusableGroup`, tabster's groupper): one tab stop that holds
|
|
15203
|
+
* several focusable elements, so a long list of rich rows does not cost a Tab press per control.
|
|
15204
|
+
* With `tabBehavior: 'limited'` or `'limited-trap-focus'`, Tab skips the elements inside while focus
|
|
15205
|
+
* is on the group element itself, and Shift+Tab from outside lands on the group element instead of
|
|
15206
|
+
* its last element; Enter or F2 enters the group, and Escape leaves it. A group is entered while
|
|
15207
|
+
* focus is on an element inside it, however it got there (a click, a popup returning focus, a
|
|
15208
|
+
* script). No tabindex is rewritten: components with their own tab stops (Toolbar, TabList) work
|
|
15209
|
+
* inside a group. A key from a popup portaled out of the group, a key that belongs to a nested
|
|
15210
|
+
* group and a key an inner element already handled (`preventDefault()`, as an input consuming
|
|
15211
|
+
* Escape does) are left alone.
|
|
15212
|
+
*
|
|
15213
|
+
* @example
|
|
15214
|
+
* const { groupProps } = useFocusableGroup({ tabBehavior: 'limited' });
|
|
15215
|
+
* <li role="group" aria-label="Message" {...groupProps}>
|
|
15216
|
+
* <button>Reply</button> <button>Forward</button>
|
|
15217
|
+
* </li>
|
|
15218
|
+
*/
|
|
15219
|
+
export declare function useFocusableGroup(options?: UseFocusableGroupOptions): UseFocusableGroupResult;
|
|
15220
|
+
|
|
15221
|
+
/** Options of {@link useFocusableGroup}. */
|
|
15222
|
+
export declare interface UseFocusableGroupOptions {
|
|
15223
|
+
/**
|
|
15224
|
+
* How the group treats the elements inside it (Fluent's `tabBehavior`):
|
|
15225
|
+
*
|
|
15226
|
+
* - `'unlimited'`: the group is one more tab stop and the elements inside it stay reachable by
|
|
15227
|
+
* Tab; no key is intercepted.
|
|
15228
|
+
* - `'limited'`: the group is one tab stop, in both directions. Enter or F2 on it moves focus to
|
|
15229
|
+
* its first tabbable element, Tab and Shift+Tab then move between the elements inside, Tab
|
|
15230
|
+
* past the last one leaves the group, and Escape returns focus to the group.
|
|
15231
|
+
* - `'limited-trap-focus'`: as `'limited'`, but Tab past the last element wraps to the first and
|
|
15232
|
+
* Shift+Tab before the first wraps to the last, until Escape.
|
|
15233
|
+
*
|
|
15234
|
+
* @default 'unlimited'
|
|
15235
|
+
*/
|
|
15236
|
+
tabBehavior?: FocusableGroupTabBehavior;
|
|
15237
|
+
}
|
|
15238
|
+
|
|
15239
|
+
/** Result of {@link useFocusableGroup}. */
|
|
15240
|
+
export declare interface UseFocusableGroupResult {
|
|
15241
|
+
/** Spread onto the group element. */
|
|
15242
|
+
groupProps: FocusableGroupProps;
|
|
15243
|
+
}
|
|
15244
|
+
|
|
15245
|
+
/**
|
|
15246
|
+
* Keeps keyboard focus inside `container` while `enabled` (modal dialogs, drawers, the DatePicker
|
|
15247
|
+
* calendar). Element-based: pass the surface held in state via a callback ref, so the trap starts
|
|
15248
|
+
* when the element appears.
|
|
15249
|
+
*
|
|
15250
|
+
* - **Initial focus** runs synchronously in the commit in which the container appears (no
|
|
15251
|
+
* `requestAnimationFrame`), and does nothing when focus is already inside (an `autoFocus`
|
|
15252
|
+
* element wins).
|
|
15253
|
+
* - **Tab / Shift+Tab** are handled by a document bubble-phase `keydown` listener that ignores
|
|
15254
|
+
* events whose default is already prevented, so a React handler inside (a menu closing on Tab, a
|
|
15255
|
+
* grid) can take the key first. Focus wraps at the edges, and from the container itself or a
|
|
15256
|
+
* non-tabbable element it continues in document order. Tabbable elements are computed on every
|
|
15257
|
+
* keydown (content may change; radio-group stops depend on focus), never cached.
|
|
15258
|
+
* - Tabbables inside `[data-wave-focus-trap-allow]` regions (the Toaster viewport) join the cycle.
|
|
15259
|
+
* - **Descendant layers** (a popover or menu opened from inside, identified through `layerId`):
|
|
15260
|
+
* Tab moves natively inside them; leaving one moves focus to the element after its anchor
|
|
15261
|
+
* (Shift+Tab: the anchor itself). Inside a plain `<Portal>` rendered in the surface (no layer,
|
|
15262
|
+
* no anchor) Tab is native too; leaving it wraps to the first (Shift+Tab: last) element. A
|
|
15263
|
+
* layer's trigger (its anchor, or an element around it such as a tooltip's wrapper) belongs to
|
|
15264
|
+
* the region it sits in, so Tab from an open info button or a button showing its tooltip moves
|
|
15265
|
+
* on as from any other element of that portal or popover.
|
|
15266
|
+
* - Focus that lands outside (not in the container, an allowed region or a descendant layer)
|
|
15267
|
+
* returns to the last focused element inside, also when that outside element loses it again
|
|
15268
|
+
* (removed or blurred, leaving focus on `<body>`). That is decided in a microtask, once the
|
|
15269
|
+
* current commit has run: an `autoFocus` element of a surface opened above the trap (a nested or
|
|
15270
|
+
* stacked dialog, a popover opened from the surface) gets focus before that surface's layer and
|
|
15271
|
+
* trap exist, and keeps it. The layer's own `refs` (its trigger, outside the container) are
|
|
15272
|
+
* outside: opening from the focused trigger still moves focus in, and focus moving back onto
|
|
15273
|
+
* the trigger is returned. Focus pulled out again while it is being returned (another focus
|
|
15274
|
+
* trap on the page) is left there.
|
|
15275
|
+
* - Traps form a stack (shared through the global registry): only the topmost acts.
|
|
15276
|
+
*/
|
|
15277
|
+
export declare function useFocusTrap(container: HTMLElement | null, options: UseFocusTrapOptions): void;
|
|
15278
|
+
|
|
15279
|
+
/** Options of {@link useFocusTrap}. */
|
|
15280
|
+
export declare interface UseFocusTrapOptions {
|
|
15281
|
+
/** Whether the trap is active. */
|
|
15282
|
+
enabled: boolean;
|
|
15283
|
+
/**
|
|
15284
|
+
* The surface's dismiss layer; focus inside its descendant layers (portaled popovers opened from
|
|
15285
|
+
* inside) is allowed. The layer's own `refs` outside the container (its trigger) are not.
|
|
15286
|
+
*/
|
|
15287
|
+
layerId?: string;
|
|
15288
|
+
/**
|
|
15289
|
+
* What to focus when the trap starts, unless focus is already inside (an `autoFocus` element
|
|
15290
|
+
* wins). @default 'first' (the first tabbable element, else the container)
|
|
15291
|
+
*/
|
|
15292
|
+
initialFocus?: React_2.RefObject<HTMLElement | null> | 'first' | 'container' | (() => HTMLElement | null);
|
|
15293
|
+
/** Regions outside the container whose tabbables join the Tab cycle. @default '[data-wave-focus-trap-allow]' (the regions marked with `modalAllowProps`) */
|
|
15294
|
+
allowOutsideSelector?: string;
|
|
15295
|
+
}
|
|
15296
|
+
|
|
15297
|
+
/**
|
|
15298
|
+
* Whether the page is in keyboard-navigation mode: `true` after the last input was a key press
|
|
15299
|
+
* (any key but a lone modifier), `false` after a pointer or touch press and before any input. For
|
|
15300
|
+
* logic that needs the mode in script, such as showing a focus cue in a widget that draws its own;
|
|
15301
|
+
* plain focus rings should keep using the `focus-visible` variant. One set of document listeners
|
|
15302
|
+
* serves every caller and goes away with the last one. `false` on the server and during
|
|
15303
|
+
* hydration.
|
|
15304
|
+
*
|
|
15305
|
+
* @example
|
|
15306
|
+
* const keyboard = useFocusVisible();
|
|
15307
|
+
* return <div data-keyboard={keyboard ? '' : undefined}>…</div>;
|
|
15308
|
+
*/
|
|
15309
|
+
export declare function useFocusVisible(): boolean;
|
|
15310
|
+
|
|
15311
|
+
/**
|
|
15312
|
+
* Grid keyboard model of the APG Grid pattern for a `<table role="grid">` (DataGrid).
|
|
15313
|
+
*
|
|
15314
|
+
* - **One tab stop.** Exactly one cell of the grid is in the tab order (initially the first cell).
|
|
15315
|
+
* Its focus target is its only focusable widget when that widget is not a text-entry control
|
|
15316
|
+
* (a checkbox, a sort button, a link); otherwise — no widget, several widgets, a text-entry
|
|
15317
|
+
* control or a nested composite — the cell itself. An unchecked radio whose named group has a
|
|
15318
|
+
* checked radio is not a target either (browsers skip it in the Tab order), so its cell is.
|
|
15319
|
+
* Every other cell and every widget inside a cell gets `tabindex="-1"`. Rows are never focusable.
|
|
15320
|
+
* When a widget becomes the target of the focused cell (Space on the cell checks its radio), the
|
|
15321
|
+
* cell keeps focus and the tab stop (removing its `tabindex` would blur it) while its target stays
|
|
15322
|
+
* at `tabindex="-1"`; the target takes the tab stop once the cell is blurred.
|
|
15323
|
+
* - **Navigation mode** (focus on a cell or on its target widget): ArrowLeft/ArrowRight (the
|
|
15324
|
+
* previous/next cell of the row, mirrored in RTL), ArrowUp/ArrowDown, Home/End (first/last cell
|
|
15325
|
+
* of the row), Ctrl+Home/Ctrl+End (first cell of the grid / last cell of the last row) and
|
|
15326
|
+
* PageUp/PageDown ({@link UseGridNavigationOptions.pageSize} rows) move focus between cells.
|
|
15327
|
+
* ArrowUp/ArrowDown and PageUp/PageDown keep the visual column (`colSpan` and `rowSpan` counted,
|
|
15328
|
+
* so a grouped header works), clamped to a shorter row. Space and Enter on a target widget reach
|
|
15329
|
+
* the widget.
|
|
15330
|
+
* - **Interaction mode**: Enter or F2 on a cell that is its own target moves focus into its first
|
|
15331
|
+
* widget; clicking a widget that is not the cell's target (a text input) enters it too. The
|
|
15332
|
+
* grid keys are then ignored, so the arrow keys move the caret, and Tab moves between the cell's
|
|
15333
|
+
* widgets. Escape returns focus to the cell. Leaving the grid ends interaction mode.
|
|
15334
|
+
* - **Nested composites** (an element with `data-roving-container` or role toolbar, radiogroup,
|
|
15335
|
+
* listbox, grid, treegrid, tablist, menu, menubar or tree) count as one widget that uses the arrow
|
|
15336
|
+
* keys: its cell takes focus, and Enter/F2 enters the composite at its own tab stop. The grid never
|
|
15337
|
+
* writes `tabindex` on or inside a composite (the composite manages its own), so a composite
|
|
15338
|
+
* keeps its own Tab stop — the same documented limitation as `useRovingTabIndex`.
|
|
15339
|
+
*
|
|
15340
|
+
* Keys are ignored when the event's default was prevented (a widget that handled the key, a
|
|
15341
|
+
* consumer handler), or with Alt/Meta held. The tab indexes are written to the DOM (layout effect
|
|
15342
|
+
* plus a `MutationObserver`), so rows and widgets added later are covered without a re-render. Focus
|
|
15343
|
+
* moves re-sync only the cells involved, the observer only the cells that changed, and the grid's
|
|
15344
|
+
* own `tabindex` writes do not trigger a re-sync.
|
|
15345
|
+
*
|
|
15346
|
+
* Internal to the table package.
|
|
15347
|
+
*/
|
|
15348
|
+
export declare function useGridNavigation(options?: UseGridNavigationOptions): UseGridNavigationResult;
|
|
15349
|
+
|
|
15350
|
+
/** Options of {@link useGridNavigation}. */
|
|
15351
|
+
export declare interface UseGridNavigationOptions {
|
|
15352
|
+
/**
|
|
15353
|
+
* How many rows PageUp and PageDown move focus.
|
|
15354
|
+
* @default 10
|
|
15355
|
+
*/
|
|
15356
|
+
pageSize?: number;
|
|
15357
|
+
}
|
|
15358
|
+
|
|
15359
|
+
/** Result of {@link useGridNavigation}. */
|
|
15360
|
+
export declare interface UseGridNavigationResult {
|
|
15361
|
+
/** Callback ref for the `<table role="grid">` element. Stable identity. */
|
|
15362
|
+
gridRef: React_2.RefCallback<HTMLTableElement>;
|
|
15363
|
+
/** Keyboard and focus handlers for the grid element. Stable identities. */
|
|
15364
|
+
gridProps: GridNavigationHandlers;
|
|
15365
|
+
}
|
|
15366
|
+
|
|
14894
15367
|
/**
|
|
14895
15368
|
* Generates a stable, SSR-safe unique id, optionally with a prefix. Wraps React's `useId` so every
|
|
14896
15369
|
* component builds DOM ids the same way (C-IDS).
|
|
@@ -14906,6 +15379,26 @@ export declare interface UseFieldControlOptions {
|
|
|
14906
15379
|
*/
|
|
14907
15380
|
export declare function useId(prefix?: string): string;
|
|
14908
15381
|
|
|
15382
|
+
/**
|
|
15383
|
+
* The trap's initial focus without the trap (a non-modal Dialog or Drawer, which moves focus in
|
|
15384
|
+
* when it opens but does not keep it there): in the layout phase of the commit in which
|
|
15385
|
+
* `enabled && container` becomes true, does nothing when focus is already inside the container or
|
|
15386
|
+
* one of the layer's descendant layers (an `autoFocus` element wins), else focuses
|
|
15387
|
+
* `initialFocus` (default: the first tabbable element), else the container. `useFocusTrap` runs
|
|
15388
|
+
* the same code when it starts. It adds no listener.
|
|
15389
|
+
*/
|
|
15390
|
+
export declare function useInitialFocus(container: HTMLElement | null, options: UseInitialFocusOptions): void;
|
|
15391
|
+
|
|
15392
|
+
/** Options of {@link useInitialFocus}. */
|
|
15393
|
+
export declare interface UseInitialFocusOptions {
|
|
15394
|
+
/** Whether the surface is open: focus moves in when it becomes `true` with a container. */
|
|
15395
|
+
enabled: boolean;
|
|
15396
|
+
/** The surface's dismiss layer: focus already in one of its descendant layers stays there. */
|
|
15397
|
+
layerId?: string;
|
|
15398
|
+
/** What to focus first. @default 'first' (the first tabbable element, else the container) */
|
|
15399
|
+
initialFocus?: UseFocusTrapOptions['initialFocus'];
|
|
15400
|
+
}
|
|
15401
|
+
|
|
14909
15402
|
/**
|
|
14910
15403
|
* `false` on the server and during hydration, `true` in every other client render — including the
|
|
14911
15404
|
* first render of a component mounted on the client, so no second commit is needed.
|
|
@@ -15241,6 +15734,11 @@ export declare interface UseListboxPopupOptions {
|
|
|
15241
15734
|
* `setReference` too (merged into its ref), which places the surface against it.
|
|
15242
15735
|
*/
|
|
15243
15736
|
anchorRef: React_2.RefObject<HTMLElement | null>;
|
|
15737
|
+
/**
|
|
15738
|
+
* Advanced positioning: `offset`, `fitViewport`, `matchReferenceWidth` and `fallbackPlacements`.
|
|
15739
|
+
* @default `{ matchReferenceWidth: true, fitViewport: true }`
|
|
15740
|
+
*/
|
|
15741
|
+
positioning?: PopupPositioningOptions;
|
|
15244
15742
|
}
|
|
15245
15743
|
|
|
15246
15744
|
/**
|
|
@@ -15358,6 +15856,84 @@ export declare interface UseListboxResult {
|
|
|
15358
15856
|
*/
|
|
15359
15857
|
export declare function useMergedRefs<T>(...refs: Array<React_2.Ref<T> | undefined | null>): React_2.RefCallback<T>;
|
|
15360
15858
|
|
|
15859
|
+
/**
|
|
15860
|
+
* Everything a modal surface (Dialog, Drawer) needs, composed in the order that works:
|
|
15861
|
+
*
|
|
15862
|
+
* 1. `useDismiss({ kind: 'modal' })` — Escape and outside presses (the backdrop is outside the
|
|
15863
|
+
* content surface, so a click on it dismisses; a drag from the content does not).
|
|
15864
|
+
* 2. `useFocusTrap` — initial focus, Tab cycle incl. toasts and descendant layers.
|
|
15865
|
+
* 3. `useModalIsolation` — the rest of the page is `inert` (instead of `aria-modal`).
|
|
15866
|
+
* 4. `useScrollLock` — ref-counted page scroll lock.
|
|
15867
|
+
* 5. `useRestoreFocus` — the opener (or `triggerRef`/`finalFocusRef`) gets focus back.
|
|
15868
|
+
*
|
|
15869
|
+
* On close the trap is released before the isolation is lifted, and the isolation is lifted
|
|
15870
|
+
* before focus is restored (an inert opener cannot take focus). Wrap the surface in
|
|
15871
|
+
* `Portal layerId={layerId}` so layers opened inside the modal become its descendants.
|
|
15872
|
+
*
|
|
15873
|
+
* `modalType: 'alert'` composes the same with `outsidePress: false`. `modalType: 'non-modal'`
|
|
15874
|
+
* registers a `dialog` layer (Escape only from inside its tree, no outside press, no focus-outside
|
|
15875
|
+
* dismissal), keeps the trap, the isolation and the scroll lock off, moves focus in on open with
|
|
15876
|
+
* the trap's initial-focus rule (`useInitialFocus`) and restores focus only when it is inside the
|
|
15877
|
+
* surface (or in a layer opened from it) at close, or was lost to `<body>` from there. Every hook
|
|
15878
|
+
* is always called and keys on `open`: a `modalType` that changes while open applies at once (the
|
|
15879
|
+
* trap, isolation and lock follow). It leaves focus inside the surface where it is; focus outside
|
|
15880
|
+
* it moves in, as on open: a switch to `modal` or `alert` starts the trap (the page turns inert),
|
|
15881
|
+
* and a switch to `non-modal` runs the initial focus (focus in the toast region, which a trap lets
|
|
15882
|
+
* in, moves into the surface). The Tab order of a non-modal surface (its place after the opener)
|
|
15883
|
+
* is the component's.
|
|
15884
|
+
*
|
|
15885
|
+
* A surface that mounts through the presence core (Dialog, Drawer) passes its open state as
|
|
15886
|
+
* `open`, never its mount (`isMounted`), and its element as `container` also while it is mounted
|
|
15887
|
+
* closed: the layer, the trap, the isolation and the scroll lock end and focus is restored in the
|
|
15888
|
+
* commit that closes it, while the element still runs its exit motion (`inert`) or stays mounted
|
|
15889
|
+
* (`hidden`, with `unmountOnClose={false}`); the next open starts them again with the same
|
|
15890
|
+
* element.
|
|
15891
|
+
*/
|
|
15892
|
+
export declare function useModalLayer(options: UseModalLayerOptions): DismissLayer;
|
|
15893
|
+
|
|
15894
|
+
/**
|
|
15895
|
+
* Options of {@link useModalLayer}: `useDismiss` options (the kind follows `modalType`) plus focus.
|
|
15896
|
+
*/
|
|
15897
|
+
export declare interface UseModalLayerOptions extends Omit<UseDismissOptions, 'kind'> {
|
|
15898
|
+
/** The modal surface, held in state via a callback ref. */
|
|
15899
|
+
container: HTMLElement | null;
|
|
15900
|
+
/**
|
|
15901
|
+
* `modal` (default) and `alert` register a `modal` layer, trap focus, isolate the page, lock its
|
|
15902
|
+
* scroll and restore focus (an `alert` layer ignores outside presses); `non-modal` registers a
|
|
15903
|
+
* `dialog` layer (`escape: 'inside'`, no outside press, no focus-outside), traps, isolates and
|
|
15904
|
+
* locks nothing, moves focus in on open with the trap's initial-focus rule and restores focus only
|
|
15905
|
+
* from inside (`requireFocusInside`).
|
|
15906
|
+
* @default 'modal'
|
|
15907
|
+
*/
|
|
15908
|
+
modalType?: ModalType;
|
|
15909
|
+
/** What the focus trap (or a non-modal surface's initial focus) focuses first. @default 'first' */
|
|
15910
|
+
initialFocus?: UseFocusTrapOptions['initialFocus'];
|
|
15911
|
+
/** The trigger: preferred focus-restore target. */
|
|
15912
|
+
triggerRef?: React_2.RefObject<HTMLElement | null>;
|
|
15913
|
+
/** Consumer override for the focus-restore target. */
|
|
15914
|
+
finalFocusRef?: React_2.RefObject<HTMLElement | null>;
|
|
15915
|
+
}
|
|
15916
|
+
|
|
15917
|
+
/**
|
|
15918
|
+
* Whether a modal surface is open (a Dialog, an overlay Drawer, an alert, the DatePicker's calendar, or your
|
|
15919
|
+
* own `useDismiss({ kind: 'modal' })` layer): `true` from the
|
|
15920
|
+
* commit that opens it to the commit that closes it, not until its exit motion ends. A non-modal
|
|
15921
|
+
* Dialog or Drawer, a Popover or a Menu is no modal. `false` on the server and during hydration.
|
|
15922
|
+
*
|
|
15923
|
+
* Use it to hold back app behavior the modal should own, such as global keyboard shortcuts, instead
|
|
15924
|
+
* of guessing from the page's `inert` attributes.
|
|
15925
|
+
*
|
|
15926
|
+
* @example
|
|
15927
|
+
* const modalOpen = useModalOpen();
|
|
15928
|
+
* useEffect(() => {
|
|
15929
|
+
* if (modalOpen) return;
|
|
15930
|
+
* const onKey = (event: KeyboardEvent) => { if (event.key === '/') focusSearch(); };
|
|
15931
|
+
* document.addEventListener('keydown', onKey);
|
|
15932
|
+
* return () => document.removeEventListener('keydown', onKey);
|
|
15933
|
+
* }, [modalOpen]);
|
|
15934
|
+
*/
|
|
15935
|
+
export declare function useModalOpen(): boolean;
|
|
15936
|
+
|
|
15361
15937
|
/**
|
|
15362
15938
|
* The items an {@link Overflow} currently hides: their `itemId`s in DOM order and their count. Use
|
|
15363
15939
|
* it in the component that `overflowButton` renders to list the hidden items in a menu. Must be
|
|
@@ -15373,6 +15949,117 @@ export declare interface UseOverflowMenuResult {
|
|
|
15373
15949
|
count: number;
|
|
15374
15950
|
}
|
|
15375
15951
|
|
|
15952
|
+
/**
|
|
15953
|
+
* Positions a popup surface next to its anchor with `@floating-ui/react-dom` (Tooltip, Popover,
|
|
15954
|
+
* Menu, listboxes, the DatePicker calendar, TeachingPopover): `offset`, `flip`, `shift`, optional
|
|
15955
|
+
* `size` (reference width / available space as CSS variables) and `arrow`. `flip`, `shift` and
|
|
15956
|
+
* `size` keep the same viewport padding, taken from the `shift` option (8px by default). Logical
|
|
15957
|
+
* `start`/`end` sides follow `useDirection()` (the WaveProvider `dir`, else the document
|
|
15958
|
+
* direction), and so does start/end alignment.
|
|
15959
|
+
*
|
|
15960
|
+
* Positions update only while `open` (`autoUpdate` on scroll/resize; element resizes and layout
|
|
15961
|
+
* shifts only where `ResizeObserver`/`IntersectionObserver` exist). Spread `floatingProps` onto the
|
|
15962
|
+
* surface: `data-side`/`data-align` expose the final placement for styling (C-CLASS).
|
|
15963
|
+
*
|
|
15964
|
+
* The anchor is an element or a `VirtualElement` (a rectangle such as the pointer position; a new
|
|
15965
|
+
* object on every render is fine); give it a `contextElement` so scrolling its containers updates
|
|
15966
|
+
* the position. A virtual anchor reaches floating-ui through one stable proxy that reads the latest
|
|
15967
|
+
* object: a new object only recomputes the position (which renders only when the position
|
|
15968
|
+
* changes), and a new proxy is made only when the `contextElement` changes.
|
|
15969
|
+
*
|
|
15970
|
+
* Destructure the result: `eslint-plugin-react-hooks` (`react-hooks/refs`) treats an object
|
|
15971
|
+
* whose member is passed to a `ref` prop as a ref, and then rejects reading its other members
|
|
15972
|
+
* during render.
|
|
15973
|
+
*
|
|
15974
|
+
* @example
|
|
15975
|
+
* const { setReference, setFloating, floatingProps } = usePopupPosition({ open, side: 'bottom' });
|
|
15976
|
+
* <button ref={setReference} />
|
|
15977
|
+
* {open && <Portal><div ref={setFloating} {...floatingProps} /></Portal>}
|
|
15978
|
+
*/
|
|
15979
|
+
export declare function usePopupPosition(options: UsePopupPositionOptions): UsePopupPositionResult;
|
|
15980
|
+
|
|
15981
|
+
/** Options of {@link usePopupPosition}. */
|
|
15982
|
+
export declare interface UsePopupPositionOptions {
|
|
15983
|
+
/** Whether the popup is open; positions are kept up to date only while `true`. */
|
|
15984
|
+
open: boolean;
|
|
15985
|
+
/** Side of the anchor. `start`/`end` follow the writing direction. @default 'bottom' */
|
|
15986
|
+
side?: PopupSide;
|
|
15987
|
+
/** Alignment along that side. @default 'start' */
|
|
15988
|
+
align?: PopupAlign;
|
|
15989
|
+
/** Distance from the anchor in px. @default 4 (tooltips use 8) */
|
|
15990
|
+
offset?: number;
|
|
15991
|
+
/** Flip to the opposite side when there is not enough room. @default true */
|
|
15992
|
+
flip?: boolean;
|
|
15993
|
+
/**
|
|
15994
|
+
* Shift along the side to stay inside the viewport. Its padding is also the viewport padding of
|
|
15995
|
+
* `flip` and of `size` (`fitViewport`, `matchReferenceWidth`): `true` means 8px, and `false`
|
|
15996
|
+
* lets the popup flip only once it touches the viewport edge and grow right up to it. With
|
|
15997
|
+
* `crossAxis: true` it also shifts across the side, over the anchor, when neither side has room
|
|
15998
|
+
* after `flip` (submenus), and `fitViewport` then offers the whole viewport in that direction.
|
|
15999
|
+
* @default { padding: 8 }
|
|
16000
|
+
*/
|
|
16001
|
+
shift?: boolean | {
|
|
16002
|
+
padding: number;
|
|
16003
|
+
crossAxis?: boolean;
|
|
16004
|
+
};
|
|
16005
|
+
/** Make the surface as wide as the anchor (listboxes). @default false */
|
|
16006
|
+
matchReferenceWidth?: boolean;
|
|
16007
|
+
/** Limit the surface to the available space (`max-width`/`max-height`). @default false */
|
|
16008
|
+
fitViewport?: boolean;
|
|
16009
|
+
/** An arrow (beak) element inside the surface, positioned through `arrowStyles`. */
|
|
16010
|
+
arrowRef?: React_2.RefObject<HTMLElement | null>;
|
|
16011
|
+
/** CSS positioning strategy. @default 'fixed' */
|
|
16012
|
+
strategy?: 'absolute' | 'fixed';
|
|
16013
|
+
/**
|
|
16014
|
+
* Placements to try, in order, when the requested side has no room, instead of only the opposite
|
|
16015
|
+
* side. Ignored with `flip: false`. An omitted `align` is the hook's own `align`.
|
|
16016
|
+
*/
|
|
16017
|
+
fallbackPlacements?: readonly PopupPlacement[];
|
|
16018
|
+
/**
|
|
16019
|
+
* Hide the surface (`visibility: hidden`: its layout is unaffected, but its content cannot take
|
|
16020
|
+
* focus, so a surface that holds focus loses it) while the anchor is scrolled out of view or
|
|
16021
|
+
* clipped away. @default false
|
|
16022
|
+
*/
|
|
16023
|
+
hideWhenDetached?: boolean;
|
|
16024
|
+
/**
|
|
16025
|
+
* Called after the surface is positioned, and again whenever the final placement changes (a flip,
|
|
16026
|
+
* a fallback): not on every scroll or resize recompute. It runs from an effect, never during
|
|
16027
|
+
* render, and not while closed.
|
|
16028
|
+
*/
|
|
16029
|
+
onPositioned?: (info: PositionedInfo) => void;
|
|
16030
|
+
}
|
|
16031
|
+
|
|
16032
|
+
/** Returned by {@link usePopupPosition}. */
|
|
16033
|
+
export declare interface UsePopupPositionResult {
|
|
16034
|
+
/**
|
|
16035
|
+
* Sets the anchor: a ref callback for the anchor (trigger) element, or a call from a layout
|
|
16036
|
+
* effect or an event. The anchor is an element or a `VirtualElement` (a rectangle such as the
|
|
16037
|
+
* pointer position; a new object on every render is fine); give it a `contextElement` so
|
|
16038
|
+
* scrolling its containers updates the position.
|
|
16039
|
+
*/
|
|
16040
|
+
setReference(el: HTMLElement | VirtualElement | null): void;
|
|
16041
|
+
/** Ref callback for the popup surface. */
|
|
16042
|
+
setFloating(el: HTMLElement | null): void;
|
|
16043
|
+
/** Position styles for the surface (also in `floatingProps.style`). */
|
|
16044
|
+
floatingStyles: React_2.CSSProperties;
|
|
16045
|
+
/** Position styles for the arrow element. */
|
|
16046
|
+
arrowStyles: React_2.CSSProperties;
|
|
16047
|
+
/** Final placement after flipping, e.g. `'top-start'`. */
|
|
16048
|
+
placement: string;
|
|
16049
|
+
/** Final physical side after flipping. */
|
|
16050
|
+
side: 'top' | 'bottom' | 'left' | 'right';
|
|
16051
|
+
/** Whether a position has been computed since the popup opened. */
|
|
16052
|
+
isPositioned: boolean;
|
|
16053
|
+
/** Recomputes the position now, for a change floating-ui cannot observe. A no-op while closed. */
|
|
16054
|
+
update(): void;
|
|
16055
|
+
/** Spread onto the surface: `data-side`, `data-align` and the position style. */
|
|
16056
|
+
floatingProps: {
|
|
16057
|
+
'data-side': string;
|
|
16058
|
+
'data-align': string;
|
|
16059
|
+
style: React_2.CSSProperties;
|
|
16060
|
+
};
|
|
16061
|
+
}
|
|
16062
|
+
|
|
15376
16063
|
/**
|
|
15377
16064
|
* Mounts and unmounts an element with CSS enter and exit motion. Style the phases with
|
|
15378
16065
|
* `data-presence` variants, e.g. `transition-opacity duration-wave-normal
|
|
@@ -15454,6 +16141,102 @@ export declare interface UsePresenceResult {
|
|
|
15454
16141
|
presenceProps: PresenceAttributes;
|
|
15455
16142
|
}
|
|
15456
16143
|
|
|
16144
|
+
/**
|
|
16145
|
+
* Returns focus to where it came from when a surface closes (dialogs, drawers, popovers, menus,
|
|
16146
|
+
* the DatePicker calendar, TeachingPopover).
|
|
16147
|
+
*
|
|
16148
|
+
* - **Capture**: when `enabled` flips to `true`, the opener is captured in an insertion effect —
|
|
16149
|
+
* before React applies `autoFocus` inside the new surface — preferring `triggerRef.current` and
|
|
16150
|
+
* ignoring `<body>` and elements inside `container`. When that finds nothing (a surface that
|
|
16151
|
+
* mounts open, before the refs of its commit are attached), it is captured again in the layout
|
|
16152
|
+
* phase of the same commit. Its place in the document and the triggers of the overlays it sits
|
|
16153
|
+
* in are recorded with it. When focus is already on `<body>` because
|
|
16154
|
+
* the focused element was removed earlier in the same commit (a menu item in a popover that
|
|
16155
|
+
* closes as the dialog it opens appears, the popover coming first in the tree), a document
|
|
16156
|
+
* focus tracker supplies that element with its recorded place and overlay triggers. The tracker
|
|
16157
|
+
* runs while any instance of the hook is mounted, and it forgets an element the user moved focus
|
|
16158
|
+
* away from on purpose.
|
|
16159
|
+
* - **Restore** when `enabled` flips to `false` (layout phase) and when the component unmounts
|
|
16160
|
+
* while enabled. The unmount restore runs in a microtask and is cancelled if the same instance
|
|
16161
|
+
* mounts again, so React StrictMode's simulated unmount does not pull focus out of a surface
|
|
16162
|
+
* that just opened.
|
|
16163
|
+
* - **Targets**, first valid wins:
|
|
16164
|
+
* 1. `finalFocusRef` → the captured opener → `triggerRef` → `fallback()`.
|
|
16165
|
+
* 2. When the opener was removed or cannot take focus, its replacement, nearest first: the
|
|
16166
|
+
* tabbable element next to where it was (in the innermost surviving ancestor that holds one,
|
|
16167
|
+
* the next one — the next row's action after a delete — else the previous one; then the same
|
|
16168
|
+
* one level up), else the trigger of the overlay it was in (a menu item's menu button), else
|
|
16169
|
+
* the element next to that trigger. When the surface is rendered inside another open layer
|
|
16170
|
+
* (its parent layer, from `DismissLayerContext`: a confirm Dialog in a Drawer's content),
|
|
16171
|
+
* only the replacements inside that layer's tree are tried here.
|
|
16172
|
+
* 3. The parent layer's surface, then the replacements outside the parent layer.
|
|
16173
|
+
* 4. The surface of the modal layer that stays open.
|
|
16174
|
+
*
|
|
16175
|
+
* So a confirm Dialog rendered in a Drawer's content and one rendered next to the Drawer both
|
|
16176
|
+
* return focus to the adjacent row, not to the Drawer's panel. A target is valid when it is
|
|
16177
|
+
* connected, focusable, not inside `[inert]` or `[aria-hidden="true"]`, and not cut off behind
|
|
16178
|
+
* another open modal layer — so focus never lands on the inert page behind a Drawer that stays
|
|
16179
|
+
* open, and is not dropped on `<body>` while a valid target exists. Focus uses `preventScroll`.
|
|
16180
|
+
* - `onlyIfFocusInside` (popovers): restores only when focus is inside the surface or was lost to
|
|
16181
|
+
* `<body>`.
|
|
16182
|
+
* - `requireFocusInside` (surfaces that do not trap focus: a non-modal Dialog or Drawer, an inline
|
|
16183
|
+
* Drawer): restores only when focus is inside the surface or in a layer opened from it (a
|
|
16184
|
+
* descendant layer of `layerId`, or a layer anchored inside the surface), or was lost to
|
|
16185
|
+
* `<body>` from an element in either; a close from code while focus is on `<body>` or on the
|
|
16186
|
+
* page moves nothing.
|
|
16187
|
+
* - `isHoverClose`: a close by the hover intent restores only when focus is inside the surface, so
|
|
16188
|
+
* a hover close never moves focus from `<body>` or from where the user put it. The same holds for
|
|
16189
|
+
* a surface opened from inside one that closes by hover (a submenu, a hover card in a hover
|
|
16190
|
+
* card): every mounted instance is known to the others through the focus tracker's record.
|
|
16191
|
+
*/
|
|
16192
|
+
export declare function useRestoreFocus(options: UseRestoreFocusOptions): void;
|
|
16193
|
+
|
|
16194
|
+
/** Options of {@link useRestoreFocus}. */
|
|
16195
|
+
export declare interface UseRestoreFocusOptions {
|
|
16196
|
+
/** `true` while the surface is open. */
|
|
16197
|
+
enabled: boolean;
|
|
16198
|
+
/** The layer surface: opener candidates inside it are ignored. */
|
|
16199
|
+
container?: HTMLElement | null;
|
|
16200
|
+
/** The trigger: preferred restore target. */
|
|
16201
|
+
triggerRef?: React_2.RefObject<HTMLElement | null>;
|
|
16202
|
+
/** Consumer override: focused first when valid. */
|
|
16203
|
+
finalFocusRef?: React_2.RefObject<HTMLElement | null>;
|
|
16204
|
+
/** Used when neither the override, the opener nor the trigger can take focus. */
|
|
16205
|
+
fallback?: () => HTMLElement | null;
|
|
16206
|
+
/**
|
|
16207
|
+
* Popovers: restore only when focus was inside the surface (or lost to `<body>`) at close, so a
|
|
16208
|
+
* click that moved focus elsewhere is respected. @default false
|
|
16209
|
+
*/
|
|
16210
|
+
onlyIfFocusInside?: boolean;
|
|
16211
|
+
/**
|
|
16212
|
+
* Read when the surface closes, or unmounts while open: `true` when the hover intent closed it
|
|
16213
|
+
* (Popover and Menu `openOnHover`, a submenu closing by hover). A hover close never moves focus:
|
|
16214
|
+
* it restores only while focus is inside the surface, so focus on `<body>` (where a hover-opened
|
|
16215
|
+
* surface leaves it) or elsewhere stays where it is. A surface opened from inside one that closes
|
|
16216
|
+
* by hover (its opener, else its trigger, lies in that surface: a submenu, a hover card in a
|
|
16217
|
+
* hover card, at any depth) is taken along, and its close counts as a hover close too. Every
|
|
16218
|
+
* other close keeps the rules above.
|
|
16219
|
+
*/
|
|
16220
|
+
isHoverClose?: () => boolean;
|
|
16221
|
+
/**
|
|
16222
|
+
* Surfaces that do not trap focus (a non-modal Dialog or Drawer, an inline Drawer): restore only
|
|
16223
|
+
* when focus is inside the surface at close, or was lost to `<body>` from an element inside it
|
|
16224
|
+
* (removed, or made unable to take focus). Focus elsewhere, or on `<body>` for another reason
|
|
16225
|
+
* (nothing had focus, a press on a spot that takes no focus, a close from code), stays where it
|
|
16226
|
+
* is. Wins over `onlyIfFocusInside`. Focus in a layer opened from the surface (a Popover or a
|
|
16227
|
+
* confirm Dialog, portaled outside it) counts as inside: a descendant layer of `layerId`, or a
|
|
16228
|
+
* layer anchored to an element inside the surface; so does focus lost to `<body>` from one.
|
|
16229
|
+
* @default false
|
|
16230
|
+
*/
|
|
16231
|
+
requireFocusInside?: boolean;
|
|
16232
|
+
/**
|
|
16233
|
+
* The surface's own dismiss layer, with `requireFocusInside`: focus in one of its descendant
|
|
16234
|
+
* layers counts as inside the surface, also after the surface's layer has unregistered (in the
|
|
16235
|
+
* commit that closes it).
|
|
16236
|
+
*/
|
|
16237
|
+
layerId?: string;
|
|
16238
|
+
}
|
|
16239
|
+
|
|
15457
16240
|
/**
|
|
15458
16241
|
* Implements the WAI-ARIA roving tabindex pattern for composite widgets: one item holds the tab
|
|
15459
16242
|
* stop (`tabIndex=0`, all others `-1`), arrow keys move focus between items, Home/End jump to the
|
|
@@ -15542,10 +16325,23 @@ export declare interface UseRovingTabIndexOptions {
|
|
|
15542
16325
|
items?: readonly string[];
|
|
15543
16326
|
/**
|
|
15544
16327
|
* Arrow key axis: `'horizontal'` uses Left/Right (mirrored in RTL), `'vertical'` uses Up/Down,
|
|
15545
|
-
* `'both'` uses all four.
|
|
16328
|
+
* `'both'` uses all four, in the DOM order of the items.
|
|
16329
|
+
*
|
|
16330
|
+
* `'grid'` is a two-dimensional grid: Left/Right move through the cells in reading order across
|
|
16331
|
+
* rows (mirrored in RTL); Up/Down go to the cell at the same index in the previous or next row,
|
|
16332
|
+
* else to the nearest enabled cell of that row (the earlier one on a tie), skipping rows without
|
|
16333
|
+
* an enabled cell, and stop at the first and last row; Home/End go to the first and last enabled
|
|
16334
|
+
* cell of the row, Ctrl+Home/End of the grid (whatever `homeEndKeys` says). Rows are the
|
|
16335
|
+
* `role="row"` elements inside the container, else groups of `columns` items in DOM order. Without
|
|
16336
|
+
* either, `'grid'` acts as `'both'` and a development warning says so.
|
|
15546
16337
|
* @default 'horizontal'
|
|
15547
16338
|
*/
|
|
15548
|
-
orientation?: 'horizontal' | 'vertical' | 'both';
|
|
16339
|
+
orientation?: 'horizontal' | 'vertical' | 'both' | 'grid';
|
|
16340
|
+
/**
|
|
16341
|
+
* With `orientation: 'grid'` and no `role="row"` elements: the number of cells per row. The last
|
|
16342
|
+
* row may be shorter.
|
|
16343
|
+
*/
|
|
16344
|
+
columns?: number;
|
|
15549
16345
|
/**
|
|
15550
16346
|
* Whether arrow keys wrap around at the ends.
|
|
15551
16347
|
* @default true
|