@fluentui/react-positioning 9.0.0-alpha.6 → 9.0.0-alpha.60

Sign up to get free protection for your applications and to get access to all the features.
Files changed (118) hide show
  1. package/CHANGELOG.json +1116 -1
  2. package/CHANGELOG.md +520 -2
  3. package/dist/react-positioning.d.ts +72 -27
  4. package/lib/createVirtualElementFromClick.d.ts +6 -0
  5. package/lib/createVirtualElementFromClick.js +24 -0
  6. package/lib/createVirtualElementFromClick.js.map +1 -0
  7. package/lib/index.d.ts +3 -0
  8. package/lib/index.js +4 -0
  9. package/lib/index.js.map +1 -1
  10. package/lib/tsdoc-metadata.json +1 -1
  11. package/lib/types.d.ts +22 -27
  12. package/lib/types.js +1 -0
  13. package/lib/types.js.map +1 -1
  14. package/lib/usePopper.d.ts +21 -1
  15. package/lib/usePopper.js +67 -29
  16. package/lib/usePopper.js.map +1 -1
  17. package/lib/usePopperMouseTarget.d.ts +11 -0
  18. package/lib/usePopperMouseTarget.js +34 -0
  19. package/lib/usePopperMouseTarget.js.map +1 -0
  20. package/lib/utils/getBasePlacement.d.ts +8 -0
  21. package/lib/utils/getBasePlacement.js +10 -0
  22. package/lib/utils/getBasePlacement.js.map +1 -0
  23. package/lib/utils/getBoundary.d.ts +1 -1
  24. package/lib/utils/getBoundary.js +2 -3
  25. package/lib/utils/getBoundary.js.map +1 -1
  26. package/lib/utils/getReactFiberFromNode.js.map +1 -1
  27. package/lib/utils/getScrollParent.js.map +1 -1
  28. package/lib/utils/index.d.ts +5 -3
  29. package/lib/utils/index.js +5 -3
  30. package/lib/utils/index.js.map +1 -1
  31. package/lib/utils/mergeArrowOffset.d.ts +10 -0
  32. package/lib/utils/mergeArrowOffset.js +37 -0
  33. package/lib/utils/mergeArrowOffset.js.map +1 -0
  34. package/lib/utils/positioningHelper.d.ts +2 -2
  35. package/lib/utils/positioningHelper.js.map +1 -1
  36. package/lib/utils/resolvePositioningShorthand.d.ts +2 -0
  37. package/lib/utils/resolvePositioningShorthand.js +25 -0
  38. package/lib/utils/resolvePositioningShorthand.js.map +1 -0
  39. package/lib/utils/useCallbackRef.js.map +1 -1
  40. package/lib-commonjs/createVirtualElementFromClick.d.ts +6 -0
  41. package/lib-commonjs/createVirtualElementFromClick.js +28 -0
  42. package/lib-commonjs/createVirtualElementFromClick.js.map +1 -0
  43. package/lib-commonjs/index.d.ts +3 -0
  44. package/lib-commonjs/index.js +7 -0
  45. package/lib-commonjs/index.js.map +1 -1
  46. package/lib-commonjs/types.d.ts +22 -27
  47. package/lib-commonjs/types.js.map +1 -1
  48. package/lib-commonjs/usePopper.d.ts +21 -1
  49. package/lib-commonjs/usePopper.js +67 -28
  50. package/lib-commonjs/usePopper.js.map +1 -1
  51. package/lib-commonjs/usePopperMouseTarget.d.ts +11 -0
  52. package/lib-commonjs/usePopperMouseTarget.js +38 -0
  53. package/lib-commonjs/usePopperMouseTarget.js.map +1 -0
  54. package/lib-commonjs/utils/getBasePlacement.d.ts +8 -0
  55. package/lib-commonjs/utils/getBasePlacement.js +14 -0
  56. package/lib-commonjs/utils/getBasePlacement.js.map +1 -0
  57. package/lib-commonjs/utils/getBoundary.d.ts +1 -1
  58. package/lib-commonjs/utils/getBoundary.js +3 -3
  59. package/lib-commonjs/utils/getBoundary.js.map +1 -1
  60. package/lib-commonjs/utils/getReactFiberFromNode.js +1 -0
  61. package/lib-commonjs/utils/getReactFiberFromNode.js.map +1 -1
  62. package/lib-commonjs/utils/getScrollParent.js +5 -2
  63. package/lib-commonjs/utils/getScrollParent.js.map +1 -1
  64. package/lib-commonjs/utils/index.d.ts +5 -3
  65. package/lib-commonjs/utils/index.js +5 -3
  66. package/lib-commonjs/utils/index.js.map +1 -1
  67. package/lib-commonjs/utils/mergeArrowOffset.d.ts +10 -0
  68. package/lib-commonjs/utils/mergeArrowOffset.js +41 -0
  69. package/lib-commonjs/utils/mergeArrowOffset.js.map +1 -0
  70. package/lib-commonjs/utils/positioningHelper.d.ts +2 -2
  71. package/lib-commonjs/utils/positioningHelper.js +5 -2
  72. package/lib-commonjs/utils/positioningHelper.js.map +1 -1
  73. package/lib-commonjs/utils/resolvePositioningShorthand.d.ts +2 -0
  74. package/lib-commonjs/utils/resolvePositioningShorthand.js +29 -0
  75. package/lib-commonjs/utils/resolvePositioningShorthand.js.map +1 -0
  76. package/lib-commonjs/utils/useCallbackRef.js +1 -0
  77. package/lib-commonjs/utils/useCallbackRef.js.map +1 -1
  78. package/package.json +11 -8
  79. package/NOTICE.txt +0 -0
  80. package/config/api-extractor.json +0 -3
  81. package/etc/react-positioning.api.md +0 -69
  82. package/just.config.ts +0 -3
  83. package/lib/utils/isBrowser.d.ts +0 -1
  84. package/lib/utils/isBrowser.js +0 -4
  85. package/lib/utils/isBrowser.js.map +0 -1
  86. package/lib-amd/index.d.ts +0 -2
  87. package/lib-amd/index.js +0 -6
  88. package/lib-amd/index.js.map +0 -1
  89. package/lib-amd/types.d.ts +0 -73
  90. package/lib-amd/types.js +0 -5
  91. package/lib-amd/types.js.map +0 -1
  92. package/lib-amd/usePopper.d.ts +0 -15
  93. package/lib-amd/usePopper.js +0 -280
  94. package/lib-amd/usePopper.js.map +0 -1
  95. package/lib-amd/utils/getBoundary.d.ts +0 -6
  96. package/lib-amd/utils/getBoundary.js +0 -23
  97. package/lib-amd/utils/getBoundary.js.map +0 -1
  98. package/lib-amd/utils/getReactFiberFromNode.d.ts +0 -109
  99. package/lib-amd/utils/getReactFiberFromNode.js +0 -47
  100. package/lib-amd/utils/getReactFiberFromNode.js.map +0 -1
  101. package/lib-amd/utils/getScrollParent.d.ts +0 -12
  102. package/lib-amd/utils/getScrollParent.js +0 -55
  103. package/lib-amd/utils/getScrollParent.js.map +0 -1
  104. package/lib-amd/utils/index.d.ts +0 -6
  105. package/lib-amd/utils/index.js +0 -11
  106. package/lib-amd/utils/index.js.map +0 -1
  107. package/lib-amd/utils/isBrowser.d.ts +0 -1
  108. package/lib-amd/utils/isBrowser.js +0 -8
  109. package/lib-amd/utils/isBrowser.js.map +0 -1
  110. package/lib-amd/utils/positioningHelper.d.ts +0 -7
  111. package/lib-amd/utils/positioningHelper.js +0 -45
  112. package/lib-amd/utils/positioningHelper.js.map +0 -1
  113. package/lib-amd/utils/useCallbackRef.d.ts +0 -19
  114. package/lib-amd/utils/useCallbackRef.js +0 -54
  115. package/lib-amd/utils/useCallbackRef.js.map +0 -1
  116. package/lib-commonjs/utils/isBrowser.d.ts +0 -1
  117. package/lib-commonjs/utils/isBrowser.js +0 -6
  118. package/lib-commonjs/utils/isBrowser.js.map +0 -1
@@ -1,10 +1,28 @@
1
1
  import * as PopperJs from '@popperjs/core';
2
- import * as React from 'react';
2
+ import * as React_2 from 'react';
3
3
 
4
4
  export declare type Alignment = 'top' | 'bottom' | 'start' | 'end' | 'center';
5
5
 
6
+ export declare type AutoSize = 'height' | 'height-always' | 'width' | 'width-always' | 'always' | boolean;
7
+
6
8
  export declare type Boundary = PopperJs.Boundary | 'scrollParent' | 'window';
7
9
 
10
+ /**
11
+ * Creates a virtual element based on the position of a click event
12
+ * Can be used as a target for popper in scenarios such as context menus
13
+ */
14
+ export declare function createVirtualElementFromClick(nativeEvent: MouseEvent): PopperVirtualElement;
15
+
16
+ /**
17
+ * Generally when adding an arrow to popper, it's necessary to offset the position of the popper by the
18
+ * height of the arrow. A simple utility to merge a provided offset with an arrow height to return the final offset
19
+ *
20
+ * @param userOffset - The offset provided by the user
21
+ * @param arrowHeight - The height of the arrow in px
22
+ * @returns User offset augmented with arrow height
23
+ */
24
+ export declare function mergeArrowOffset(userOffset: Offset | undefined | null, arrowHeight: number): Offset;
25
+
8
26
  export declare type Offset = OffsetFunction | [number | null | undefined, number | null | undefined];
9
27
 
10
28
  export declare type OffsetFunction = (param: OffsetFunctionParam) => [number | null | undefined, number | null | undefined];
@@ -15,36 +33,42 @@ export declare type OffsetFunctionParam = {
15
33
  placement: PopperJs.Placement;
16
34
  };
17
35
 
18
- export declare interface PopperOptions extends PositioningProps {
36
+ declare interface PopperOptions extends PositioningProps {
19
37
  /**
20
38
  * If false, delays Popper's creation.
21
39
  * @default true
22
40
  */
23
41
  enabled?: boolean;
42
+ onStateUpdate?: (state: Partial<PopperJs.State>) => void;
24
43
  /**
25
- * Array of conditions to be met in order to trigger a subsequent render to reposition the elements.
44
+ * Enables the Popper box to position itself in 'fixed' mode (default value is position: 'absolute')
45
+ * @default false
26
46
  */
27
- positioningDependencies?: React.DependencyList;
28
- onStateUpdate?: (state: Partial<PopperJs.State>) => void;
47
+ positionFixed?: boolean;
48
+ /**
49
+ * When the reference element or the viewport is outside viewport allows a popper element to be fully in viewport.
50
+ * "all" enables this behavior for all axis.
51
+ */
52
+ unstable_disableTether?: boolean | 'all';
29
53
  }
30
54
 
31
55
  export declare type PopperRefHandle = {
32
56
  updatePosition: () => void;
33
57
  };
34
58
 
59
+ export declare type PopperVirtualElement = PopperJs.VirtualElement;
60
+
35
61
  export declare type Position = 'above' | 'below' | 'before' | 'after';
36
62
 
37
63
  export declare interface PositioningProps {
38
- /**
39
- * Alignment for the component.
40
- */
64
+ /** Alignment for the component. Only has an effect if used with the @see position option */
41
65
  align?: Alignment;
42
66
  /** The element which will define the boundaries of the popper position for the flip behavior. */
43
67
  flipBoundary?: Boundary;
44
68
  /** The element which will define the boundaries of the popper position for the overflow behavior. */
45
69
  overflowBoundary?: Boundary;
46
70
  /** An imperative handle to Popper methods. */
47
- containerRef?: React.Ref<PopperRefHandle>;
71
+ popperRef?: React_2.Ref<PopperRefHandle>;
48
72
  /**
49
73
  * Position for the component. Position has higher priority than align. If position is vertical ('above' | 'below')
50
74
  * and align is also vertical ('top' | 'bottom') or if both position and align are horizontal ('before' | 'after'
@@ -52,11 +76,6 @@ export declare interface PositioningProps {
52
76
  * then provided value for 'align' will be ignored and 'center' will be used instead.
53
77
  */
54
78
  position?: Position;
55
- /**
56
- * Enables the Popper box to position itself in 'fixed' mode (default value is position: 'absolute')
57
- * @default false
58
- */
59
- positionFixed?: boolean;
60
79
  /**
61
80
  * Lets you displace a popper element from its reference element.
62
81
  * This can be useful if you need to apply some margin between them or if you need to fine tune the
@@ -64,23 +83,39 @@ export declare interface PositioningProps {
64
83
  */
65
84
  offset?: Offset;
66
85
  /**
67
- * When the reference element or the viewport is outside viewport allows a popper element to be fully in viewport.
68
- * "all" enables this behavior for all axis.
86
+ * Defines padding between the corner of the popup element and the arrow.
87
+ * Use to prevent the arrow from overlapping a rounded corner, for example.
69
88
  */
70
- unstable_disableTether?: boolean | 'all';
89
+ arrowPadding?: number;
71
90
  /**
72
- * Disables automatic repositioning of the component; it will always be placed according to the values of `align` and
73
- * `position` props, regardless of the size of the component, the reference element or the viewport.
91
+ * Applies max-height and max-width on popper to fit it within the available space in viewport.
92
+ * true enables this for both width and height when overflow happens.
93
+ * 'always' applies `max-height`/`max-width` regardless of overflow.
94
+ * 'height' applies `max-height` when overflow happens, and 'width' for `max-width`
95
+ * `height-always` applies `max-height` regardless of overflow, and 'width-always' for always applying `max-width`
74
96
  */
75
- unstable_pinned?: boolean;
97
+ autoSize?: AutoSize;
76
98
  /**
77
- * Applies max-height and max-width on popper to fit it within the available space in viewport.
78
- * true enables this for both width and height.
79
- * 'height' applies only `max-height` and 'width' for `max-width`
99
+ * Manual override for popper target. Useful for scenarios where a component accepts user prop to override target
100
+ */
101
+ target?: HTMLElement | PopperVirtualElement | null;
102
+ /**
103
+ * Modifies position and alignment to cover the target
104
+ */
105
+ coverTarget?: boolean;
106
+ /**
107
+ * Disables automatic repositioning of the component; it will always be placed according to the values of `align` and
108
+ * `position` props, regardless of the size of the component, the reference element or the viewport.
80
109
  */
81
- autoSize?: 'height' | 'width' | boolean;
110
+ pinned?: boolean;
82
111
  }
83
112
 
113
+ export declare type PositioningShorthand = PositioningProps | PositioningShorthandValue;
114
+
115
+ export declare type PositioningShorthandValue = 'above' | 'above-start' | 'above-end' | 'below' | 'below-start' | 'below-end' | 'before' | 'before-top' | 'before-bottom' | 'after' | 'after-top' | 'after-bottom';
116
+
117
+ export declare function resolvePositioningShorthand(shorthand: PositioningShorthand | undefined | null): Readonly<PositioningProps>;
118
+
84
119
  /**
85
120
  * Exposes Popper positioning API via React hook. Contains few important differences between an official "react-popper"
86
121
  * package:
@@ -90,9 +125,19 @@ export declare interface PositioningProps {
90
125
  * to avoid focus jumps
91
126
  */
92
127
  export declare function usePopper(options?: PopperOptions): {
93
- targetRef: React.MutableRefObject<any>;
94
- containerRef: React.MutableRefObject<any>;
95
- arrowRef: React.MutableRefObject<any>;
128
+ targetRef: React_2.MutableRefObject<any>;
129
+ containerRef: React_2.MutableRefObject<any>;
130
+ arrowRef: React_2.MutableRefObject<any>;
96
131
  };
97
132
 
133
+ /**
134
+ * A state hook that manages a popper virtual element from mouseevents.
135
+ * Useful for scenarios where a component needs to be positioned by mouse click (e.g. contextmenu)
136
+ * React synthetic events are not persisted by this hook
137
+ *
138
+ * @param initialState - initializes a user provided state similare to useState
139
+ * @returns state and dispatcher for a Popper virtual element that uses native/synthetic mouse events
140
+ */
141
+ export declare const usePopperMouseTarget: (initialState?: PopperJs.VirtualElement | (() => PopperJs.VirtualElement) | undefined) => readonly [PopperJs.VirtualElement | undefined, (event: React_2.MouseEvent | MouseEvent | undefined | null) => void];
142
+
98
143
  export { }
@@ -0,0 +1,6 @@
1
+ import type { PopperVirtualElement } from './types';
2
+ /**
3
+ * Creates a virtual element based on the position of a click event
4
+ * Can be used as a target for popper in scenarios such as context menus
5
+ */
6
+ export declare function createVirtualElementFromClick(nativeEvent: MouseEvent): PopperVirtualElement;
@@ -0,0 +1,24 @@
1
+ /**
2
+ * Creates a virtual element based on the position of a click event
3
+ * Can be used as a target for popper in scenarios such as context menus
4
+ */
5
+ export function createVirtualElementFromClick(nativeEvent) {
6
+ var left = nativeEvent.clientX;
7
+ var top = nativeEvent.clientY;
8
+ var right = left + 1;
9
+ var bottom = top + 1;
10
+ function getBoundingClientRect() {
11
+ return {
12
+ left: left,
13
+ top: top,
14
+ right: right,
15
+ bottom: bottom,
16
+ height: 1,
17
+ width: 1,
18
+ };
19
+ }
20
+ return {
21
+ getBoundingClientRect: getBoundingClientRect,
22
+ };
23
+ }
24
+ //# sourceMappingURL=createVirtualElementFromClick.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"createVirtualElementFromClick.js","sourceRoot":"","sources":["../src/createVirtualElementFromClick.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,UAAU,6BAA6B,CAAC,WAAuB;IACnE,IAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC;IACjC,IAAM,GAAG,GAAG,WAAW,CAAC,OAAO,CAAC;IAChC,IAAM,KAAK,GAAG,IAAI,GAAG,CAAC,CAAC;IACvB,IAAM,MAAM,GAAG,GAAG,GAAG,CAAC,CAAC;IAEvB,SAAS,qBAAqB;QAC5B,OAAO;YACL,IAAI,MAAA;YACJ,GAAG,KAAA;YACH,KAAK,OAAA;YACL,MAAM,QAAA;YAEN,MAAM,EAAE,CAAC;YACT,KAAK,EAAE,CAAC;SACT,CAAC;IACJ,CAAC;IAED,OAAO;QACL,qBAAqB,uBAAA;KACtB,CAAC;AACJ,CAAC"}
package/lib/index.d.ts CHANGED
@@ -1,2 +1,5 @@
1
1
  export * from './usePopper';
2
+ export * from './createVirtualElementFromClick';
3
+ export * from './usePopperMouseTarget';
4
+ export { resolvePositioningShorthand, mergeArrowOffset } from './utils/index';
2
5
  export * from './types';
package/lib/index.js CHANGED
@@ -1,2 +1,6 @@
1
1
  export * from './usePopper';
2
+ export * from './createVirtualElementFromClick';
3
+ export * from './usePopperMouseTarget';
4
+ export { resolvePositioningShorthand, mergeArrowOffset } from './utils/index';
5
+ export * from './types';
2
6
  //# sourceMappingURL=index.js.map
package/lib/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"../src/","sources":["index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC","sourcesContent":["export * from './usePopper';\nexport * from './types';\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,iCAAiC,CAAC;AAChD,cAAc,wBAAwB,CAAC;AACvC,OAAO,EAAE,2BAA2B,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC9E,cAAc,SAAS,CAAC"}
@@ -5,7 +5,7 @@
5
5
  "toolPackages": [
6
6
  {
7
7
  "packageName": "@microsoft/api-extractor",
8
- "packageVersion": "7.7.1"
8
+ "packageVersion": "7.18.1"
9
9
  }
10
10
  ]
11
11
  }
package/lib/types.d.ts CHANGED
@@ -9,21 +9,21 @@ export declare type OffsetFunction = (param: OffsetFunctionParam) => [number | n
9
9
  export declare type Offset = OffsetFunction | [number | null | undefined, number | null | undefined];
10
10
  export declare type Position = 'above' | 'below' | 'before' | 'after';
11
11
  export declare type Alignment = 'top' | 'bottom' | 'start' | 'end' | 'center';
12
+ export declare type AutoSize = 'height' | 'height-always' | 'width' | 'width-always' | 'always' | boolean;
12
13
  export declare type Boundary = PopperJs.Boundary | 'scrollParent' | 'window';
13
14
  export declare type PopperRefHandle = {
14
15
  updatePosition: () => void;
15
16
  };
17
+ export declare type PopperVirtualElement = PopperJs.VirtualElement;
16
18
  export interface PositioningProps {
17
- /**
18
- * Alignment for the component.
19
- */
19
+ /** Alignment for the component. Only has an effect if used with the @see position option */
20
20
  align?: Alignment;
21
21
  /** The element which will define the boundaries of the popper position for the flip behavior. */
22
22
  flipBoundary?: Boundary;
23
23
  /** The element which will define the boundaries of the popper position for the overflow behavior. */
24
24
  overflowBoundary?: Boundary;
25
25
  /** An imperative handle to Popper methods. */
26
- containerRef?: React.Ref<PopperRefHandle>;
26
+ popperRef?: React.Ref<PopperRefHandle>;
27
27
  /**
28
28
  * Position for the component. Position has higher priority than align. If position is vertical ('above' | 'below')
29
29
  * and align is also vertical ('top' | 'bottom') or if both position and align are horizontal ('before' | 'after'
@@ -31,11 +31,6 @@ export interface PositioningProps {
31
31
  * then provided value for 'align' will be ignored and 'center' will be used instead.
32
32
  */
33
33
  position?: Position;
34
- /**
35
- * Enables the Popper box to position itself in 'fixed' mode (default value is position: 'absolute')
36
- * @default false
37
- */
38
- positionFixed?: boolean;
39
34
  /**
40
35
  * Lets you displace a popper element from its reference element.
41
36
  * This can be useful if you need to apply some margin between them or if you need to fine tune the
@@ -43,31 +38,31 @@ export interface PositioningProps {
43
38
  */
44
39
  offset?: Offset;
45
40
  /**
46
- * When the reference element or the viewport is outside viewport allows a popper element to be fully in viewport.
47
- * "all" enables this behavior for all axis.
41
+ * Defines padding between the corner of the popup element and the arrow.
42
+ * Use to prevent the arrow from overlapping a rounded corner, for example.
48
43
  */
49
- unstable_disableTether?: boolean | 'all';
44
+ arrowPadding?: number;
50
45
  /**
51
- * Disables automatic repositioning of the component; it will always be placed according to the values of `align` and
52
- * `position` props, regardless of the size of the component, the reference element or the viewport.
46
+ * Applies max-height and max-width on popper to fit it within the available space in viewport.
47
+ * true enables this for both width and height when overflow happens.
48
+ * 'always' applies `max-height`/`max-width` regardless of overflow.
49
+ * 'height' applies `max-height` when overflow happens, and 'width' for `max-width`
50
+ * `height-always` applies `max-height` regardless of overflow, and 'width-always' for always applying `max-width`
53
51
  */
54
- unstable_pinned?: boolean;
52
+ autoSize?: AutoSize;
55
53
  /**
56
- * Applies max-height and max-width on popper to fit it within the available space in viewport.
57
- * true enables this for both width and height.
58
- * 'height' applies only `max-height` and 'width' for `max-width`
54
+ * Manual override for popper target. Useful for scenarios where a component accepts user prop to override target
59
55
  */
60
- autoSize?: 'height' | 'width' | boolean;
61
- }
62
- export interface PopperOptions extends PositioningProps {
56
+ target?: HTMLElement | PopperVirtualElement | null;
63
57
  /**
64
- * If false, delays Popper's creation.
65
- * @default true
58
+ * Modifies position and alignment to cover the target
66
59
  */
67
- enabled?: boolean;
60
+ coverTarget?: boolean;
68
61
  /**
69
- * Array of conditions to be met in order to trigger a subsequent render to reposition the elements.
62
+ * Disables automatic repositioning of the component; it will always be placed according to the values of `align` and
63
+ * `position` props, regardless of the size of the component, the reference element or the viewport.
70
64
  */
71
- positioningDependencies?: React.DependencyList;
72
- onStateUpdate?: (state: Partial<PopperJs.State>) => void;
65
+ pinned?: boolean;
73
66
  }
67
+ export declare type PositioningShorthandValue = 'above' | 'above-start' | 'above-end' | 'below' | 'below-start' | 'below-end' | 'before' | 'before-top' | 'before-bottom' | 'after' | 'after-top' | 'after-bottom';
68
+ export declare type PositioningShorthand = PositioningProps | PositioningShorthandValue;
package/lib/types.js CHANGED
@@ -1 +1,2 @@
1
+ export {};
1
2
  //# sourceMappingURL=types.js.map
package/lib/types.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"../src/","sources":["types.ts"],"names":[],"mappings":"","sourcesContent":["import * as PopperJs from '@popperjs/core';\nimport * as React from 'react';\n\nexport type OffsetFunctionParam = {\n popper: PopperJs.Rect;\n reference: PopperJs.Rect;\n placement: PopperJs.Placement;\n};\n\nexport type OffsetFunction = (param: OffsetFunctionParam) => [number | null | undefined, number | null | undefined];\n\nexport type Offset = OffsetFunction | [number | null | undefined, number | null | undefined];\n\nexport type Position = 'above' | 'below' | 'before' | 'after';\nexport type Alignment = 'top' | 'bottom' | 'start' | 'end' | 'center';\n\nexport type Boundary = PopperJs.Boundary | 'scrollParent' | 'window';\n\nexport type PopperRefHandle = { updatePosition: () => void };\n\nexport interface PositioningProps {\n /**\n * Alignment for the component.\n */\n align?: Alignment;\n\n /** The element which will define the boundaries of the popper position for the flip behavior. */\n flipBoundary?: Boundary;\n\n /** The element which will define the boundaries of the popper position for the overflow behavior. */\n overflowBoundary?: Boundary;\n\n /** An imperative handle to Popper methods. */\n containerRef?: React.Ref<PopperRefHandle>;\n\n /**\n * Position for the component. Position has higher priority than align. If position is vertical ('above' | 'below')\n * and align is also vertical ('top' | 'bottom') or if both position and align are horizontal ('before' | 'after'\n * and 'start' | 'end' respectively),\n * then provided value for 'align' will be ignored and 'center' will be used instead.\n */\n position?: Position;\n\n /**\n * Enables the Popper box to position itself in 'fixed' mode (default value is position: 'absolute')\n * @default false\n */\n positionFixed?: boolean;\n\n /**\n * Lets you displace a popper element from its reference element.\n * This can be useful if you need to apply some margin between them or if you need to fine tune the\n * position according to some custom logic.\n */\n offset?: Offset;\n\n /**\n * When the reference element or the viewport is outside viewport allows a popper element to be fully in viewport.\n * \"all\" enables this behavior for all axis.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n unstable_disableTether?: boolean | 'all';\n\n /**\n * Disables automatic repositioning of the component; it will always be placed according to the values of `align` and\n * `position` props, regardless of the size of the component, the reference element or the viewport.\n */\n // eslint-disable-next-line @typescript-eslint/naming-convention\n unstable_pinned?: boolean;\n\n /**\n * Applies max-height and max-width on popper to fit it within the available space in viewport.\n * true enables this for both width and height.\n * 'height' applies only `max-height` and 'width' for `max-width`\n */\n autoSize?: 'height' | 'width' | boolean;\n}\n\nexport interface PopperOptions extends PositioningProps {\n /**\n * If false, delays Popper's creation.\n * @default true\n */\n enabled?: boolean;\n\n /**\n * Array of conditions to be met in order to trigger a subsequent render to reposition the elements.\n */\n positioningDependencies?: React.DependencyList;\n\n onStateUpdate?: (state: Partial<PopperJs.State>) => void;\n}\n"]}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -1,5 +1,24 @@
1
+ import * as PopperJs from '@popperjs/core';
1
2
  import * as React from 'react';
2
- import { PopperOptions } from './types';
3
+ import type { PositioningProps } from './types';
4
+ interface PopperOptions extends PositioningProps {
5
+ /**
6
+ * If false, delays Popper's creation.
7
+ * @default true
8
+ */
9
+ enabled?: boolean;
10
+ onStateUpdate?: (state: Partial<PopperJs.State>) => void;
11
+ /**
12
+ * Enables the Popper box to position itself in 'fixed' mode (default value is position: 'absolute')
13
+ * @default false
14
+ */
15
+ positionFixed?: boolean;
16
+ /**
17
+ * When the reference element or the viewport is outside viewport allows a popper element to be fully in viewport.
18
+ * "all" enables this behavior for all axis.
19
+ */
20
+ unstable_disableTether?: boolean | 'all';
21
+ }
3
22
  /**
4
23
  * Exposes Popper positioning API via React hook. Contains few important differences between an official "react-popper"
5
24
  * package:
@@ -13,3 +32,4 @@ export declare function usePopper(options?: PopperOptions): {
13
32
  containerRef: React.MutableRefObject<any>;
14
33
  arrowRef: React.MutableRefObject<any>;
15
34
  };
35
+ export {};
package/lib/usePopper.js CHANGED
@@ -1,6 +1,6 @@
1
- import { useEventCallback, useIsomorphicLayoutEffect, useFirstMount } from '@fluentui/react-utilities';
2
- import { useFluent } from '@fluentui/react-provider';
3
- import { isBrowser, getScrollParent, applyRtlToOffset, getPlacement, getReactFiberFromNode, getBoundary, useCallbackRef, } from './utils/index';
1
+ import { useEventCallback, useIsomorphicLayoutEffect, useFirstMount, canUseDOM } from '@fluentui/react-utilities';
2
+ import { useFluent } from '@fluentui/react-shared-contexts';
3
+ import { getScrollParent, applyRtlToOffset, getPlacement, getReactFiberFromNode, getBoundary, useCallbackRef, getBasePlacement, } from './utils/index';
4
4
  import * as PopperJs from '@popperjs/core';
5
5
  import * as React from 'react';
6
6
  //
@@ -33,11 +33,9 @@ function hasAutofocusFilter(node) {
33
33
  * that can't be resolved properly during an initial rendering.
34
34
  */
35
35
  function usePopperOptions(options, popperOriginalPositionRef) {
36
- var autoSize = options.autoSize, flipBoundary = options.flipBoundary, offset = options.offset, onStateUpdate = options.onStateUpdate, overflowBoundary = options.overflowBoundary,
36
+ var arrowPadding = options.arrowPadding, autoSize = options.autoSize, coverTarget = options.coverTarget, flipBoundary = options.flipBoundary, offset = options.offset, onStateUpdate = options.onStateUpdate, overflowBoundary = options.overflowBoundary,
37
37
  // eslint-disable-next-line @typescript-eslint/naming-convention
38
- unstable_disableTether = options.unstable_disableTether,
39
- // eslint-disable-next-line @typescript-eslint/naming-convention
40
- unstable_pinned = options.unstable_pinned;
38
+ unstable_disableTether = options.unstable_disableTether, pinned = options.pinned;
41
39
  var isRtl = useFluent().dir === 'rtl';
42
40
  var placement = getPlacement(options.align, options.position, isRtl);
43
41
  var strategy = options.positionFixed ? 'fixed' : 'absolute';
@@ -85,12 +83,12 @@ function usePopperOptions(options, popperOriginalPositionRef) {
85
83
  },
86
84
  { name: 'flip', options: { flipVariations: true } },
87
85
  /**
88
- * unstable_pinned disables the flip modifier by setting flip.enabled to false; this
86
+ * pinned disables the flip modifier by setting flip.enabled to false; this
89
87
  * disables automatic repositioning of the popper box; it will always be placed according to
90
88
  * the values of `align` and `position` props, regardless of the size of the component, the
91
89
  * reference element or the viewport.
92
90
  */
93
- unstable_pinned && { name: 'flip', enabled: false },
91
+ pinned && { name: 'flip', enabled: false },
94
92
  /**
95
93
  * When the popper box is placed in the context of a scrollable element, we need to set
96
94
  * preventOverflow.escapeWithReference to true and flip.boundariesElement to 'scrollParent'
@@ -129,12 +127,12 @@ function usePopperOptions(options, popperOriginalPositionRef) {
129
127
  phase: 'afterWrite',
130
128
  fn: handleStateUpdate,
131
129
  },
132
- autoSize && {
130
+ {
133
131
  // Similar code as popper-maxsize-modifier: https://github.com/atomiks/popper.js/blob/master/src/modifiers/maxSize.js
134
132
  // popper-maxsize-modifier only calculates the max sizes.
135
- // This modifier applies the max sizes when overflow is detected
133
+ // This modifier can apply max sizes always, or apply the max sizes only when overflow is detected
136
134
  name: 'applyMaxSize',
137
- enabled: true,
135
+ enabled: !!autoSize,
138
136
  phase: 'beforeWrite',
139
137
  requiresIfExists: ['offset', 'preventOverflow', 'flip'],
140
138
  options: {
@@ -146,13 +144,19 @@ function usePopperOptions(options, popperOriginalPositionRef) {
146
144
  var overflow = PopperJs.detectOverflow(state, modifierOptions);
147
145
  var _b = state.modifiersData.preventOverflow || { x: 0, y: 0 }, x = _b.x, y = _b.y;
148
146
  var _c = state.rects.popper, width = _c.width, height = _c.height;
149
- var basePlacement = state.placement.split('-')[0];
147
+ var basePlacement = getBasePlacement(state.placement);
150
148
  var widthProp = basePlacement === 'left' ? 'left' : 'right';
151
149
  var heightProp = basePlacement === 'top' ? 'top' : 'bottom';
152
- if (overflow[widthProp] > 0 && (autoSize === true || autoSize === 'width')) {
150
+ var applyMaxWidth = autoSize === 'always' ||
151
+ autoSize === 'width-always' ||
152
+ (overflow[widthProp] > 0 && (autoSize === true || autoSize === 'width'));
153
+ var applyMaxHeight = autoSize === 'always' ||
154
+ autoSize === 'height-always' ||
155
+ (overflow[heightProp] > 0 && (autoSize === true || autoSize === 'height'));
156
+ if (applyMaxWidth) {
153
157
  state.styles.popper.maxWidth = width - overflow[widthProp] - x + "px";
154
158
  }
155
- if (overflow[heightProp] > 0 && (autoSize === true || autoSize === 'height')) {
159
+ if (applyMaxHeight) {
156
160
  state.styles.popper.maxHeight = height - overflow[heightProp] - y + "px";
157
161
  }
158
162
  },
@@ -164,7 +168,34 @@ function usePopperOptions(options, popperOriginalPositionRef) {
164
168
  {
165
169
  name: 'arrow',
166
170
  enabled: !!arrow,
167
- options: { element: arrow },
171
+ options: { element: arrow, padding: arrowPadding },
172
+ },
173
+ /**
174
+ * Modifies popper offsets to cover the reference rect, but still keep edge alignment
175
+ */
176
+ {
177
+ name: 'coverTarget',
178
+ enabled: !!coverTarget,
179
+ phase: 'main',
180
+ requiresIfExists: ['offset', 'preventOverflow', 'flip'],
181
+ fn: function (_a) {
182
+ var state = _a.state;
183
+ var basePlacement = getBasePlacement(state.placement);
184
+ switch (basePlacement) {
185
+ case 'bottom':
186
+ state.modifiersData.popperOffsets.y -= state.rects.reference.height;
187
+ break;
188
+ case 'top':
189
+ state.modifiersData.popperOffsets.y += state.rects.reference.height;
190
+ break;
191
+ case 'left':
192
+ state.modifiersData.popperOffsets.x += state.rects.reference.width;
193
+ break;
194
+ case 'right':
195
+ state.modifiersData.popperOffsets.x -= state.rects.reference.width;
196
+ break;
197
+ }
198
+ },
168
199
  },
169
200
  ].filter(Boolean); // filter boolean conditional spreading values
170
201
  var popperOptions = {
@@ -175,14 +206,16 @@ function usePopperOptions(options, popperOriginalPositionRef) {
175
206
  };
176
207
  return popperOptions;
177
208
  }, [
209
+ arrowPadding,
178
210
  autoSize,
211
+ coverTarget,
179
212
  flipBoundary,
180
213
  offsetModifier,
181
214
  overflowBoundary,
182
215
  placement,
183
216
  strategy,
184
217
  unstable_disableTether,
185
- unstable_pinned,
218
+ pinned,
186
219
  // These can be skipped from deps as they will not ever change
187
220
  handleStateUpdate,
188
221
  popperOriginalPositionRef,
@@ -207,10 +240,11 @@ export function usePopper(options) {
207
240
  var _a;
208
241
  (_a = popperInstanceRef.current) === null || _a === void 0 ? void 0 : _a.destroy();
209
242
  popperInstanceRef.current = null;
243
+ var _b = options.target, target = _b === void 0 ? targetRef.current : _b;
210
244
  var popperInstance = null;
211
- if (isBrowser() && enabled) {
212
- if (targetRef.current && containerRef.current) {
213
- popperInstance = PopperJs.createPopper(targetRef.current, containerRef.current, resolvePopperOptions(targetRef.current, containerRef.current, arrowRef.current));
245
+ if (canUseDOM() && enabled) {
246
+ if (target && containerRef.current) {
247
+ popperInstance = PopperJs.createPopper(target, containerRef.current, resolvePopperOptions(target, containerRef.current, arrowRef.current));
214
248
  }
215
249
  }
216
250
  if (popperInstance) {
@@ -221,8 +255,7 @@ export function usePopper(options) {
221
255
  var originalForceUpdate_1 = popperInstance.forceUpdate;
222
256
  popperInstance.isFirstRun = true;
223
257
  popperInstance.forceUpdate = function () {
224
- var _a;
225
- if ((_a = popperInstance) === null || _a === void 0 ? void 0 : _a.isFirstRun) {
258
+ if (popperInstance === null || popperInstance === void 0 ? void 0 : popperInstance.isFirstRun) {
226
259
  popperInstance.state.elements.popper.style.position = popperOriginalPositionRef.current;
227
260
  popperInstance.isFirstRun = false;
228
261
  }
@@ -254,7 +287,7 @@ export function usePopper(options) {
254
287
  var targetRef = useCallbackRef(null, handlePopperUpdate, true);
255
288
  var containerRef = useCallbackRef(null, handlePopperUpdate, true);
256
289
  var arrowRef = useCallbackRef(null, handlePopperUpdate, true);
257
- React.useImperativeHandle(options.containerRef, function () { return ({
290
+ React.useImperativeHandle(options.popperRef, function () { return ({
258
291
  updatePosition: function () {
259
292
  var _a;
260
293
  (_a = popperInstanceRef.current) === null || _a === void 0 ? void 0 : _a.update();
@@ -267,25 +300,30 @@ export function usePopper(options) {
267
300
  (_a = popperInstanceRef.current) === null || _a === void 0 ? void 0 : _a.destroy();
268
301
  popperInstanceRef.current = null;
269
302
  };
270
- }, [options.enabled]);
303
+ }, [handlePopperUpdate, options.enabled, options.target]);
271
304
  useIsomorphicLayoutEffect(function () {
272
305
  var _a;
273
306
  if (!isFirstMount) {
274
- (_a = popperInstanceRef.current) === null || _a === void 0 ? void 0 : _a.setOptions(resolvePopperOptions(targetRef.current, containerRef.current, arrowRef.current));
307
+ (_a = popperInstanceRef.current) === null || _a === void 0 ? void 0 : _a.setOptions(resolvePopperOptions(options.target || targetRef.current, containerRef.current, arrowRef.current));
275
308
  }
276
- }, [resolvePopperOptions]);
309
+ },
310
+ // Missing deps:
311
+ // options.target - The useIsomorphicLayoutEffect before this will create a new popper instance if target changes
312
+ // isFirstMount - Should never change after mount
313
+ // arrowRef, containerRef, targetRef - Stable between renders
314
+ // eslint-disable-next-line react-hooks/exhaustive-deps
315
+ [resolvePopperOptions]);
277
316
  if (process.env.NODE_ENV !== 'production') {
278
317
  // This checked should run only in development mode
279
318
  // eslint-disable-next-line react-hooks/rules-of-hooks
280
319
  React.useEffect(function () {
281
- var _a, _b;
320
+ var _a;
282
321
  if (containerRef.current) {
283
322
  var contentNode = containerRef.current;
284
- // eslint-disable-next-line deprecation/deprecation
285
323
  var treeWalker = (_a = contentNode.ownerDocument) === null || _a === void 0 ? void 0 : _a.createTreeWalker(contentNode, NodeFilter.SHOW_ELEMENT, {
286
324
  acceptNode: hasAutofocusFilter,
287
325
  });
288
- while ((_b = treeWalker) === null || _b === void 0 ? void 0 : _b.nextNode()) {
326
+ while (treeWalker === null || treeWalker === void 0 ? void 0 : treeWalker.nextNode()) {
289
327
  var node = treeWalker.currentNode;
290
328
  // eslint-disable-next-line no-console
291
329
  console.warn('<Popper>:', node);