Skip to content

Commit d44cd64

Browse files
authored
feat(react-headless-components-preview): add Popover & positioning (#36006)
1 parent 3d56c39 commit d44cd64

73 files changed

Lines changed: 3798 additions & 0 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"type": "patch",
3+
"comment": "feat: add headless Popover'",
4+
"packageName": "@fluentui/react-headless-components-preview",
5+
"email": "vgenaev@gmail.com",
6+
"dependentChangeType": "patch"
7+
}

packages/react-components/react-headless-components-preview/library/config/tests.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,3 +36,21 @@ if (typeof HTMLDialogElement !== 'undefined') {
3636
};
3737
}
3838
}
39+
40+
// JSDOM does not implement the Popover API yet.
41+
// Provide a minimal test shim so components using showPopover/hidePopover can run in Jest.
42+
if (typeof HTMLElement !== 'undefined') {
43+
const proto = HTMLElement.prototype;
44+
45+
if (!proto.showPopover) {
46+
proto.showPopover = function showPopover() {
47+
/* no-op */
48+
};
49+
}
50+
51+
if (!proto.hidePopover) {
52+
proto.hidePopover = function hidePopover() {
53+
/* no-op */
54+
};
55+
}
56+
}

packages/react-components/react-headless-components-preview/library/docs/popover-spec.md

Lines changed: 314 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
## API Report File for "@fluentui/react-headless-components-preview"
2+
3+
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4+
5+
```ts
6+
7+
import type { ARIAButtonType } from '@fluentui/react-aria';
8+
import type { ComponentProps } from '@fluentui/react-utilities';
9+
import type { ComponentState } from '@fluentui/react-utilities';
10+
import type { ContextSelector } from '@fluentui/react-context-selector';
11+
import type { EventData } from '@fluentui/react-utilities';
12+
import type { EventHandler } from '@fluentui/react-utilities';
13+
import type { ForwardRefComponent } from '@fluentui/react-utilities';
14+
import type { JSXElement } from '@fluentui/react-utilities';
15+
import type { PopoverTriggerChildProps as PopoverTriggerChildProps_2 } from '@fluentui/react-popover';
16+
import { PositioningShorthand } from '@fluentui/react-positioning';
17+
import * as React_2 from 'react';
18+
import type { Slot } from '@fluentui/react-utilities';
19+
import type { TriggerProps } from '@fluentui/react-utilities';
20+
21+
// @public
22+
export type OnOpenChangeData = EventData<string, React_2.SyntheticEvent | Event> & {
23+
open: boolean;
24+
};
25+
26+
// @public
27+
export type OpenPopoverEvents = MouseEvent | TouchEvent | React_2.FocusEvent<HTMLElement> | React_2.KeyboardEvent<HTMLElement> | React_2.MouseEvent<HTMLElement>;
28+
29+
// @public
30+
export const Popover: {
31+
(props: PopoverProps): JSXElement;
32+
displayName: string;
33+
};
34+
35+
// @public
36+
export type PopoverContextValue = Pick<PopoverState, 'open' | 'setOpen' | 'toggleOpen' | 'triggerRef' | 'contentRef' | 'arrowRef' | 'openOnHover' | 'openOnContext' | 'withArrow' | 'surfaceId'> & {
37+
positioning: {
38+
targetRef: React_2.RefCallback<HTMLElement>;
39+
containerRef: React_2.RefCallback<HTMLElement>;
40+
};
41+
};
42+
43+
// @public
44+
export type PopoverProps = {
45+
children: [JSXElement, JSXElement] | JSXElement;
46+
open?: boolean;
47+
defaultOpen?: boolean;
48+
onOpenChange?: EventHandler<OnOpenChangeData>;
49+
openOnHover?: boolean;
50+
openOnContext?: boolean;
51+
mouseLeaveDelay?: number;
52+
positioning?: PositioningShorthand;
53+
withArrow?: boolean;
54+
};
55+
56+
// @public
57+
export type PopoverState = Required<Pick<PopoverProps, 'open'>> & Pick<PopoverProps, 'onOpenChange' | 'openOnContext' | 'openOnHover' | 'withArrow'> & {
58+
setOpen: (e: OpenPopoverEvents, open: boolean) => void;
59+
toggleOpen: (e: OpenPopoverEvents) => void;
60+
triggerRef: React_2.RefObject<HTMLElement | null>;
61+
contentRef: React_2.RefObject<HTMLElement | null>;
62+
arrowRef: React_2.RefObject<HTMLDivElement | null>;
63+
popoverTrigger: React_2.ReactElement | undefined;
64+
popoverSurface: React_2.ReactElement | undefined;
65+
contextTarget: {
66+
x: number;
67+
y: number;
68+
} | undefined;
69+
setContextTarget: (target: {
70+
x: number;
71+
y: number;
72+
} | undefined) => void;
73+
positioning: PositioningReturn;
74+
surfaceId: string;
75+
};
76+
77+
// @public
78+
export const PopoverSurface: ForwardRefComponent<PopoverSurfaceProps>;
79+
80+
// @public (undocumented)
81+
export type PopoverSurfaceProps = ComponentProps<PopoverSurfaceSlots>;
82+
83+
// @public
84+
export type PopoverSurfaceSlots = {
85+
root: Slot<'div'>;
86+
};
87+
88+
// @public (undocumented)
89+
export type PopoverSurfaceState = ComponentState<PopoverSurfaceSlots> & {
90+
withArrow: boolean | undefined;
91+
arrowRef: React_2.RefObject<HTMLDivElement | null>;
92+
'data-open': string;
93+
};
94+
95+
// @public
96+
export const PopoverTrigger: React_2.FC<PopoverTriggerProps>;
97+
98+
// @public
99+
export type PopoverTriggerProps = Omit<TriggerProps<PopoverTriggerChildProps>, 'children'> & {
100+
children: React_2.ReactElement;
101+
disableButtonEnhancement?: boolean;
102+
};
103+
104+
// @public
105+
export type PopoverTriggerState = {
106+
children: React_2.ReactElement | null;
107+
};
108+
109+
// @public
110+
export const renderPopover: (state: PopoverState, contextValues: {
111+
popover: PopoverContextValue;
112+
}) => React_2.ReactElement;
113+
114+
// @public (undocumented)
115+
export const renderPopoverSurface: (state: PopoverSurfaceState) => JSXElement;
116+
117+
// @public
118+
export const renderPopoverTrigger: (state: PopoverTriggerState) => JSXElement | null;
119+
120+
// @public
121+
export const usePopover: (props: PopoverProps) => PopoverState;
122+
123+
// @public
124+
export const usePopoverContext: <T>(selector: ContextSelector<PopoverContextValue, T>) => T;
125+
126+
// @public (undocumented)
127+
export const usePopoverContextValues: (state: PopoverState) => {
128+
popover: PopoverContextValue;
129+
};
130+
131+
// @public
132+
export const usePopoverSurface: (props: PopoverSurfaceProps, ref: React_2.Ref<HTMLDivElement>) => PopoverSurfaceState;
133+
134+
// @public
135+
export const usePopoverTrigger: (props: PopoverTriggerProps) => PopoverTriggerState;
136+
137+
// (No @packageDocumentation comment for this package)
138+
139+
```
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
## API Report File for "@fluentui/react-headless-components-preview"
2+
3+
> Do not edit this file. It is a report generated by [API Extractor](https://api-extractor.com/).
4+
5+
```ts
6+
7+
import { Alignment } from '@fluentui/react-positioning';
8+
import { Position } from '@fluentui/react-positioning';
9+
import { PositioningImperativeRef } from '@fluentui/react-positioning';
10+
import { PositioningProps } from '@fluentui/react-positioning';
11+
import { PositioningShorthand } from '@fluentui/react-positioning';
12+
import { PositioningShorthandValue } from '@fluentui/react-positioning';
13+
import type * as React_2 from 'react';
14+
import { resolvePositioningShorthand } from '@fluentui/react-positioning';
15+
16+
export { Alignment }
17+
18+
// @public (undocumented)
19+
export const ALIGNMENTS: {
20+
readonly start: "start";
21+
readonly center: "center";
22+
readonly end: "end";
23+
};
24+
25+
// @public
26+
export function getPlacementString(position: Position, align: LogicalAlignment): string;
27+
28+
export { Position }
29+
30+
export { PositioningImperativeRef }
31+
32+
export { PositioningProps }
33+
34+
// @public (undocumented)
35+
export type PositioningReturn = {
36+
targetRef: React_2.RefCallback<HTMLElement>;
37+
containerRef: React_2.RefCallback<HTMLElement>;
38+
};
39+
40+
export { PositioningShorthand }
41+
42+
export { PositioningShorthandValue }
43+
44+
// @public (undocumented)
45+
export const POSITIONS: {
46+
readonly above: "above";
47+
readonly below: "below";
48+
readonly before: "before";
49+
readonly after: "after";
50+
};
51+
52+
export { resolvePositioningShorthand }
53+
54+
// @public (undocumented)
55+
export function usePositioning(options: PositioningProps): PositioningReturn;
56+
57+
// (No @packageDocumentation comment for this package)
58+
59+
```

packages/react-components/react-headless-components-preview/library/package.json

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
"license": "MIT",
2020
"dependencies": {
2121
"@fluentui/react-accordion": "^9.11.0",
22+
"@fluentui/react-aria": "^9.17.10",
23+
"@fluentui/keyboard-keys": "^9.0.8",
2224
"@fluentui/react-avatar": "^9.11.1",
2325
"@fluentui/react-badge": "^9.5.2",
2426
"@fluentui/react-button": "^9.9.1",
@@ -35,14 +37,17 @@
3537
"@fluentui/react-link": "^9.8.1",
3638
"@fluentui/react-message-bar": "^9.7.0",
3739
"@fluentui/react-persona": "^9.7.3",
40+
"@fluentui/react-popover": "^9.14.2",
3841
"@fluentui/react-portal": "^9.8.12",
42+
"@fluentui/react-positioning": "^9.22.1",
3943
"@fluentui/react-progress": "^9.5.1",
4044
"@fluentui/react-provider": "^9.22.16",
4145
"@fluentui/react-radio": "^9.6.2",
4246
"@fluentui/react-rating": "^9.4.1",
4347
"@fluentui/react-search": "^9.4.2",
4448
"@fluentui/react-select": "^9.5.1",
4549
"@fluentui/react-shared-contexts": "^9.26.2",
50+
"@fluentui/react-context-selector": "^9.2.15",
4651
"@fluentui/react-skeleton": "^9.7.2",
4752
"@fluentui/react-slider": "^9.6.2",
4853
"@fluentui/react-spinbutton": "^9.6.2",
@@ -146,6 +151,18 @@
146151
"import": "./lib/message-bar.js",
147152
"require": "./lib-commonjs/message-bar.js"
148153
},
154+
"./popover": {
155+
"types": "./dist/popover.d.ts",
156+
"node": "./lib-commonjs/popover.js",
157+
"import": "./lib/popover.js",
158+
"require": "./lib-commonjs/popover.js"
159+
},
160+
"./positioning": {
161+
"types": "./dist/positioning.d.ts",
162+
"node": "./lib-commonjs/positioning.js",
163+
"import": "./lib/positioning.js",
164+
"require": "./lib-commonjs/positioning.js"
165+
},
149166
"./progress-bar": {
150167
"types": "./dist/progress-bar.d.ts",
151168
"node": "./lib-commonjs/progress-bar.js",

0 commit comments

Comments
 (0)