@khanacademy/wonder-blocks-tooltip 1.4.5 → 1.4.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +43 -0
- package/dist/components/tooltip-anchor.d.ts +85 -0
- package/dist/components/tooltip-anchor.js.flow +98 -0
- package/dist/components/tooltip-bubble.d.ts +36 -0
- package/dist/components/tooltip-bubble.js.flow +72 -0
- package/dist/components/tooltip-content.d.ts +33 -0
- package/dist/components/tooltip-content.js.flow +44 -0
- package/dist/components/tooltip-popper.d.ts +32 -0
- package/dist/components/tooltip-popper.js.flow +39 -0
- package/dist/components/tooltip-tail.d.ts +57 -0
- package/dist/components/tooltip-tail.js.flow +77 -0
- package/dist/components/tooltip.d.ts +150 -0
- package/dist/components/tooltip.js.flow +159 -0
- package/dist/es/index.js +220 -273
- package/dist/index.d.ts +8 -0
- package/dist/index.js +234 -288
- package/dist/index.js.flow +20 -2
- package/dist/util/active-tracker.d.ts +61 -0
- package/dist/util/active-tracker.js.flow +71 -0
- package/dist/util/constants.d.ts +6 -0
- package/dist/util/constants.js.flow +13 -0
- package/dist/util/ref-tracker.d.ts +16 -0
- package/dist/util/ref-tracker.js.flow +16 -0
- package/dist/util/types.d.ts +11 -0
- package/dist/util/types.js.flow +36 -0
- package/package.json +9 -9
- package/src/components/__tests__/{tooltip-anchor.test.js → tooltip-anchor.test.tsx} +42 -52
- package/src/components/__tests__/{tooltip-bubble.test.js → tooltip-bubble.test.tsx} +5 -5
- package/src/components/__tests__/{tooltip-popper.test.js → tooltip-popper.test.tsx} +16 -13
- package/src/components/__tests__/{tooltip-tail.test.js → tooltip-tail.test.tsx} +7 -6
- package/src/components/__tests__/{tooltip.integration.test.js → tooltip.integration.test.tsx} +1 -2
- package/src/components/__tests__/{tooltip.test.js → tooltip.test.tsx} +11 -9
- package/src/components/{tooltip-anchor.js → tooltip-anchor.tsx} +29 -30
- package/src/components/{tooltip-bubble.js → tooltip-bubble.tsx} +20 -32
- package/src/components/{tooltip-content.js → tooltip-content.tsx} +8 -10
- package/src/components/{tooltip-popper.js → tooltip-popper.tsx} +17 -17
- package/src/components/{tooltip-tail.js → tooltip-tail.tsx} +29 -33
- package/src/components/{tooltip.js → tooltip.tsx} +40 -44
- package/src/index.ts +11 -0
- package/src/util/__tests__/{active-tracker.test.js → active-tracker.test.ts} +2 -3
- package/src/util/__tests__/{ref-tracker.test.js → ref-tracker.test.tsx} +14 -8
- package/src/util/{active-tracker.js → active-tracker.ts} +1 -2
- package/src/util/{constants.js → constants.ts} +0 -1
- package/src/util/{ref-tracker.js → ref-tracker.ts} +14 -7
- package/src/util/types.ts +32 -0
- package/tsconfig.json +16 -0
- package/tsconfig.tsbuildinfo +1 -0
- package/src/components/__docs__/tooltip-content.stories.js +0 -89
- package/src/components/__docs__/tooltip.argtypes.js +0 -15
- package/src/components/__docs__/tooltip.stories.js +0 -335
- package/src/index.js +0 -12
- package/src/util/types.js +0 -29
- /package/src/util/__tests__/__snapshots__/{active-tracker.test.js.snap → active-tracker.test.ts.snap} +0 -0
- /package/src/util/__tests__/__snapshots__/{ref-tracker.test.js.snap → ref-tracker.test.tsx.snap} +0 -0
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import {css, StyleSheet} from "aphrodite";
|
|
4
3
|
|
|
@@ -7,9 +6,9 @@ import {View} from "@khanacademy/wonder-blocks-core";
|
|
|
7
6
|
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
8
7
|
|
|
9
8
|
import type {StyleType} from "@khanacademy/wonder-blocks-core";
|
|
10
|
-
import type {getRefFn, Placement, Offset} from "../util/types
|
|
9
|
+
import type {getRefFn, Placement, Offset} from "../util/types";
|
|
11
10
|
|
|
12
|
-
export type Props = {
|
|
11
|
+
export type Props = {
|
|
13
12
|
/**
|
|
14
13
|
* Whether we should use the default white background color or switch to a
|
|
15
14
|
* different bg color.
|
|
@@ -17,34 +16,31 @@ export type Props = {|
|
|
|
17
16
|
* NOTE: Added to support custom popovers
|
|
18
17
|
* @ignore
|
|
19
18
|
*/
|
|
20
|
-
color:
|
|
21
|
-
|
|
19
|
+
color: keyof typeof Colors;
|
|
22
20
|
/** The offset of the tail indicating where it should be positioned. */
|
|
23
|
-
offset?: Offset
|
|
24
|
-
|
|
21
|
+
offset?: Offset;
|
|
25
22
|
/** The placement of the tail with respect to the tooltip anchor. */
|
|
26
|
-
placement: Placement
|
|
27
|
-
|
|
23
|
+
placement: Placement;
|
|
28
24
|
/** A callback to update the ref of the tail element. */
|
|
29
|
-
updateRef?: getRefFn
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
type DefaultProps = {
|
|
33
|
-
color:
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
type Dimensions = {
|
|
37
|
-
trimlinePoints: [string, string]
|
|
38
|
-
points: [string, string, string]
|
|
39
|
-
height: number
|
|
40
|
-
width: number
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
type FilterPosition = {
|
|
44
|
-
y: string
|
|
45
|
-
x: string
|
|
46
|
-
offsetShadowX: number
|
|
47
|
-
|
|
25
|
+
updateRef?: getRefFn;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
type DefaultProps = {
|
|
29
|
+
color: Props["color"];
|
|
30
|
+
};
|
|
31
|
+
|
|
32
|
+
type Dimensions = {
|
|
33
|
+
trimlinePoints: [string, string];
|
|
34
|
+
points: [string, string, string];
|
|
35
|
+
height: number;
|
|
36
|
+
width: number;
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
type FilterPosition = {
|
|
40
|
+
y: string;
|
|
41
|
+
x: string;
|
|
42
|
+
offsetShadowX: number;
|
|
43
|
+
};
|
|
48
44
|
|
|
49
45
|
// TODO(somewhatabstract): Replace this really basic unique ID work with
|
|
50
46
|
// something SSR-friendly and more robust.
|
|
@@ -136,7 +132,7 @@ export default class TooltipTail extends React.Component<Props> {
|
|
|
136
132
|
}
|
|
137
133
|
}
|
|
138
134
|
|
|
139
|
-
_getFilterPositioning():
|
|
135
|
+
_getFilterPositioning(): FilterPosition | null | undefined {
|
|
140
136
|
const {placement} = this.props;
|
|
141
137
|
switch (placement) {
|
|
142
138
|
case "top":
|
|
@@ -179,7 +175,7 @@ export default class TooltipTail extends React.Component<Props> {
|
|
|
179
175
|
* elsewhere in the document. (The `height` value depends on
|
|
180
176
|
* which way the arrow is turned!)
|
|
181
177
|
*/
|
|
182
|
-
_maybeRenderDropshadow(points: [string, string, string]): React.
|
|
178
|
+
_maybeRenderDropshadow(points: [string, string, string]): React.ReactNode {
|
|
183
179
|
const position = this._getFilterPositioning();
|
|
184
180
|
if (!position) {
|
|
185
181
|
return null;
|
|
@@ -308,7 +304,7 @@ export default class TooltipTail extends React.Component<Props> {
|
|
|
308
304
|
}
|
|
309
305
|
}
|
|
310
306
|
|
|
311
|
-
_getArrowStyle():
|
|
307
|
+
_getArrowStyle(): React.CSSProperties {
|
|
312
308
|
const {placement} = this.props;
|
|
313
309
|
switch (placement) {
|
|
314
310
|
case "top":
|
|
@@ -344,7 +340,7 @@ export default class TooltipTail extends React.Component<Props> {
|
|
|
344
340
|
}
|
|
345
341
|
}
|
|
346
342
|
|
|
347
|
-
_renderArrow(): React.
|
|
343
|
+
_renderArrow(): React.ReactNode {
|
|
348
344
|
const {trimlinePoints, points, height, width} =
|
|
349
345
|
this._calculateDimensionsFromPlacement();
|
|
350
346
|
|
|
@@ -391,7 +387,7 @@ export default class TooltipTail extends React.Component<Props> {
|
|
|
391
387
|
);
|
|
392
388
|
}
|
|
393
389
|
|
|
394
|
-
render(): React.
|
|
390
|
+
render(): React.ReactElement {
|
|
395
391
|
const {offset, placement, updateRef} = this.props;
|
|
396
392
|
return (
|
|
397
393
|
<View
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/**
|
|
3
2
|
* The Tooltip component provides the means to anchor some additional
|
|
4
3
|
* information to some content. The additional information is shown in a
|
|
@@ -23,38 +22,35 @@ import * as ReactDOM from "react-dom";
|
|
|
23
22
|
|
|
24
23
|
import {
|
|
25
24
|
UniqueIDProvider,
|
|
26
|
-
|
|
25
|
+
IIdentifierFactory,
|
|
27
26
|
} from "@khanacademy/wonder-blocks-core";
|
|
28
27
|
import {maybeGetPortalMountedModalHostElement} from "@khanacademy/wonder-blocks-modal";
|
|
29
28
|
import type {Typography} from "@khanacademy/wonder-blocks-typography";
|
|
30
29
|
import type {AriaProps} from "@khanacademy/wonder-blocks-core";
|
|
31
30
|
|
|
32
|
-
import TooltipAnchor from "./tooltip-anchor
|
|
33
|
-
import TooltipBubble from "./tooltip-bubble
|
|
34
|
-
import TooltipContent from "./tooltip-content
|
|
35
|
-
import TooltipPopper from "./tooltip-popper
|
|
36
|
-
import type {Placement} from "../util/types
|
|
37
|
-
|
|
38
|
-
type Props = {|
|
|
39
|
-
...AriaProps,
|
|
31
|
+
import TooltipAnchor from "./tooltip-anchor";
|
|
32
|
+
import TooltipBubble from "./tooltip-bubble";
|
|
33
|
+
import TooltipContent from "./tooltip-content";
|
|
34
|
+
import TooltipPopper from "./tooltip-popper";
|
|
35
|
+
import type {Placement} from "../util/types";
|
|
40
36
|
|
|
37
|
+
type Props = AriaProps & {
|
|
41
38
|
/**
|
|
42
39
|
* The content for anchoring the tooltip.
|
|
43
40
|
* This component will be used to position the tooltip.
|
|
44
41
|
*/
|
|
45
|
-
children: React.
|
|
46
|
-
|
|
42
|
+
children: React.ReactElement<any> | string;
|
|
47
43
|
/**
|
|
48
44
|
* The title of the tooltip.
|
|
49
45
|
* Optional.
|
|
50
46
|
*/
|
|
51
|
-
title?: string | React.
|
|
52
|
-
|
|
47
|
+
title?: string | React.ReactElement<React.ComponentProps<Typography>>;
|
|
53
48
|
/**
|
|
54
49
|
* The content to render in the tooltip.
|
|
55
50
|
*/
|
|
56
|
-
content:
|
|
57
|
-
|
|
51
|
+
content:
|
|
52
|
+
| string
|
|
53
|
+
| React.ReactElement<React.ComponentProps<typeof TooltipContent>>;
|
|
58
54
|
/**
|
|
59
55
|
* The unique identifier to give to the tooltip. Provide this in cases where
|
|
60
56
|
* you want to override the default accessibility solution. This identifier
|
|
@@ -68,8 +64,7 @@ type Props = {|
|
|
|
68
64
|
* to the children with a unique identifier pointing to the tooltip bubble
|
|
69
65
|
* content.
|
|
70
66
|
*/
|
|
71
|
-
id?: string
|
|
72
|
-
|
|
67
|
+
id?: string;
|
|
73
68
|
/**
|
|
74
69
|
* When true, if a tabindex attribute is not already present on the element
|
|
75
70
|
* wrapped by the anchor, the element will be given tabindex=0 to make it
|
|
@@ -88,14 +83,12 @@ type Props = {|
|
|
|
88
83
|
* anchor element, so you may need to implement an additional accessibility
|
|
89
84
|
* solution when overriding anchor focusivity.
|
|
90
85
|
*/
|
|
91
|
-
forceAnchorFocusivity?: boolean
|
|
92
|
-
|
|
86
|
+
forceAnchorFocusivity?: boolean;
|
|
93
87
|
/**
|
|
94
88
|
* Where the tooltip should appear in relation to the anchor element.
|
|
95
89
|
* Defaults to "top".
|
|
96
90
|
*/
|
|
97
|
-
placement: Placement
|
|
98
|
-
|
|
91
|
+
placement: Placement;
|
|
99
92
|
/**
|
|
100
93
|
* Renders the tooltip when true, renders nothing when false.
|
|
101
94
|
*
|
|
@@ -103,33 +96,32 @@ type Props = {|
|
|
|
103
96
|
* parent is responsible for managing the opening/closing of the tooltip
|
|
104
97
|
* when using this prop.
|
|
105
98
|
*/
|
|
106
|
-
opened?: boolean
|
|
107
|
-
|
|
99
|
+
opened?: boolean;
|
|
108
100
|
/**
|
|
109
101
|
* Test ID used for e2e testing.
|
|
110
102
|
*/
|
|
111
|
-
testId?: string
|
|
112
|
-
|
|
103
|
+
testId?: string;
|
|
104
|
+
};
|
|
113
105
|
|
|
114
|
-
type State = {
|
|
106
|
+
type State = {
|
|
115
107
|
/**
|
|
116
108
|
* Whether the tooltip is open by hovering/focusing on the anchor element.
|
|
117
109
|
*/
|
|
118
|
-
active: boolean
|
|
110
|
+
active: boolean;
|
|
119
111
|
/**
|
|
120
112
|
* Whether the tooltip is open by hovering on the tooltip bubble.
|
|
121
113
|
*/
|
|
122
|
-
activeBubble: boolean
|
|
114
|
+
activeBubble: boolean;
|
|
123
115
|
/**
|
|
124
116
|
* The element that activates the tooltip.
|
|
125
117
|
*/
|
|
126
|
-
anchorElement:
|
|
127
|
-
|
|
118
|
+
anchorElement: HTMLElement | null | undefined;
|
|
119
|
+
};
|
|
128
120
|
|
|
129
|
-
type DefaultProps = {
|
|
130
|
-
forceAnchorFocusivity:
|
|
131
|
-
placement:
|
|
132
|
-
|
|
121
|
+
type DefaultProps = {
|
|
122
|
+
forceAnchorFocusivity: Props["forceAnchorFocusivity"];
|
|
123
|
+
placement: Props["placement"];
|
|
124
|
+
};
|
|
133
125
|
|
|
134
126
|
/**
|
|
135
127
|
* Use a tooltip to help describe an on screen object.
|
|
@@ -168,7 +160,7 @@ export default class Tooltip extends React.Component<Props, State> {
|
|
|
168
160
|
static getDerivedStateFromProps(
|
|
169
161
|
props: Props,
|
|
170
162
|
state: State,
|
|
171
|
-
):
|
|
163
|
+
): Partial<State> | null {
|
|
172
164
|
return {
|
|
173
165
|
active:
|
|
174
166
|
typeof props.opened === "boolean" ? props.opened : state.active,
|
|
@@ -180,15 +172,17 @@ export default class Tooltip extends React.Component<Props, State> {
|
|
|
180
172
|
activeBubble: false,
|
|
181
173
|
anchorElement: null,
|
|
182
174
|
};
|
|
183
|
-
static ariaContentId
|
|
175
|
+
static ariaContentId = "aria-content";
|
|
184
176
|
|
|
185
|
-
_updateAnchorElement(ref
|
|
177
|
+
_updateAnchorElement(ref?: Element | null) {
|
|
186
178
|
if (ref && ref !== this.state.anchorElement) {
|
|
187
|
-
this.setState({anchorElement:
|
|
179
|
+
this.setState({anchorElement: ref as HTMLElement});
|
|
188
180
|
}
|
|
189
181
|
}
|
|
190
182
|
|
|
191
|
-
_renderBubbleContent(): React.
|
|
183
|
+
_renderBubbleContent(): React.ReactElement<
|
|
184
|
+
React.ComponentProps<typeof TooltipContent>
|
|
185
|
+
> {
|
|
192
186
|
const {title, content} = this.props;
|
|
193
187
|
if (typeof content === "string") {
|
|
194
188
|
return <TooltipContent title={title}>{content}</TooltipContent>;
|
|
@@ -199,7 +193,7 @@ export default class Tooltip extends React.Component<Props, State> {
|
|
|
199
193
|
}
|
|
200
194
|
}
|
|
201
195
|
|
|
202
|
-
_renderPopper(ids?: IIdentifierFactory): React.
|
|
196
|
+
_renderPopper(ids?: IIdentifierFactory): React.ReactNode {
|
|
203
197
|
const {id} = this.props;
|
|
204
198
|
const bubbleId = ids ? ids.get(Tooltip.ariaContentId) : id;
|
|
205
199
|
if (!bubbleId) {
|
|
@@ -232,7 +226,7 @@ export default class Tooltip extends React.Component<Props, State> {
|
|
|
232
226
|
);
|
|
233
227
|
}
|
|
234
228
|
|
|
235
|
-
_getHost():
|
|
229
|
+
_getHost(): Element | null | undefined {
|
|
236
230
|
const {anchorElement} = this.state;
|
|
237
231
|
|
|
238
232
|
return (
|
|
@@ -241,7 +235,7 @@ export default class Tooltip extends React.Component<Props, State> {
|
|
|
241
235
|
);
|
|
242
236
|
}
|
|
243
237
|
|
|
244
|
-
_renderTooltipAnchor(ids?: IIdentifierFactory): React.
|
|
238
|
+
_renderTooltipAnchor(ids?: IIdentifierFactory): React.ReactNode {
|
|
245
239
|
const {children, forceAnchorFocusivity} = this.props;
|
|
246
240
|
const {active, activeBubble} = this.state;
|
|
247
241
|
|
|
@@ -265,15 +259,17 @@ export default class Tooltip extends React.Component<Props, State> {
|
|
|
265
259
|
);
|
|
266
260
|
}
|
|
267
261
|
|
|
268
|
-
render(): React.
|
|
262
|
+
render(): React.ReactElement {
|
|
269
263
|
const {id} = this.props;
|
|
270
264
|
if (id) {
|
|
271
265
|
// Let's bypass the extra weight of an id provider since we don't
|
|
272
266
|
// need it.
|
|
267
|
+
// @ts-expect-error [FEI-5019] - TS2322 - Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>>'.
|
|
273
268
|
return this._renderTooltipAnchor();
|
|
274
269
|
} else {
|
|
275
270
|
return (
|
|
276
271
|
<UniqueIDProvider scope="tooltip" mockOnFirstRender={true}>
|
|
272
|
+
{/* @ts-expect-error [FEI-5019] - TS2769 - No overload matches this call. */}
|
|
277
273
|
{(ids) => this._renderTooltipAnchor(ids)}
|
|
278
274
|
</UniqueIDProvider>
|
|
279
275
|
);
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type {Placement} from "./util/types";
|
|
2
|
+
import type {PopperElementProps} from "./components/tooltip-bubble";
|
|
3
|
+
|
|
4
|
+
import Tooltip from "./components/tooltip";
|
|
5
|
+
import TooltipContent from "./components/tooltip-content";
|
|
6
|
+
import TooltipPopper from "./components/tooltip-popper";
|
|
7
|
+
import TooltipTail from "./components/tooltip-tail";
|
|
8
|
+
|
|
9
|
+
export {Tooltip as default, TooltipContent, TooltipPopper, TooltipTail};
|
|
10
|
+
|
|
11
|
+
export type {Placement, PopperElementProps};
|
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import type {IActiveTrackerSubscriber} from "../active-tracker.js";
|
|
1
|
+
import ActiveTracker from "../active-tracker";
|
|
2
|
+
import type {IActiveTrackerSubscriber} from "../active-tracker";
|
|
4
3
|
|
|
5
4
|
class MockSubscriber implements IActiveTrackerSubscriber {
|
|
6
5
|
activeStateStolen = jest.fn();
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import * as ReactDOM from "react-dom";
|
|
4
3
|
import {render} from "@testing-library/react";
|
|
5
4
|
import {View} from "@khanacademy/wonder-blocks-core";
|
|
6
5
|
|
|
7
|
-
import RefTracker from "../ref-tracker
|
|
6
|
+
import RefTracker from "../ref-tracker";
|
|
8
7
|
|
|
9
|
-
type CallbackFn = (
|
|
8
|
+
type CallbackFn = (arg1?: HTMLElement | null | undefined) => void;
|
|
10
9
|
|
|
11
10
|
describe("RefTracker", () => {
|
|
12
11
|
describe("#setCallback", () => {
|
|
@@ -24,7 +23,7 @@ describe("RefTracker", () => {
|
|
|
24
23
|
test("called with non-function, throws", () => {
|
|
25
24
|
// Arrange
|
|
26
25
|
const tracker = new RefTracker();
|
|
27
|
-
const targetFn =
|
|
26
|
+
const targetFn = {} as CallbackFn;
|
|
28
27
|
|
|
29
28
|
// Act
|
|
30
29
|
const underTest = () => tracker.setCallback(targetFn);
|
|
@@ -49,7 +48,7 @@ describe("RefTracker", () => {
|
|
|
49
48
|
// Arrange
|
|
50
49
|
const tracker = new RefTracker();
|
|
51
50
|
const targetFn = jest.fn();
|
|
52
|
-
const ref = await new Promise((resolve) => {
|
|
51
|
+
const ref = await new Promise((resolve: any) => {
|
|
53
52
|
const nodes = (
|
|
54
53
|
<View>
|
|
55
54
|
<View ref={resolve} />
|
|
@@ -57,7 +56,9 @@ describe("RefTracker", () => {
|
|
|
57
56
|
);
|
|
58
57
|
render(nodes);
|
|
59
58
|
});
|
|
59
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
|
|
60
60
|
const domNode = ReactDOM.findDOMNode(ref);
|
|
61
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'Element | Component<any, {}, any> | null | undefined'.
|
|
61
62
|
tracker.updateRef(ref);
|
|
62
63
|
|
|
63
64
|
// Act
|
|
@@ -85,7 +86,7 @@ describe("RefTracker", () => {
|
|
|
85
86
|
test("real ref, no callback, no throw", async () => {
|
|
86
87
|
// Arrange
|
|
87
88
|
const tracker = new RefTracker();
|
|
88
|
-
const ref = await new Promise((resolve) => {
|
|
89
|
+
const ref = await new Promise((resolve: any) => {
|
|
89
90
|
const nodes = (
|
|
90
91
|
<View>
|
|
91
92
|
<View ref={resolve} />
|
|
@@ -95,6 +96,7 @@ describe("RefTracker", () => {
|
|
|
95
96
|
});
|
|
96
97
|
|
|
97
98
|
// Act
|
|
99
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'Element | Component<any, {}, any> | null | undefined'.
|
|
98
100
|
const underTest = () => tracker.updateRef(ref);
|
|
99
101
|
|
|
100
102
|
// Assert
|
|
@@ -107,7 +109,7 @@ describe("RefTracker", () => {
|
|
|
107
109
|
const targetFn = jest.fn();
|
|
108
110
|
tracker.setCallback(targetFn);
|
|
109
111
|
|
|
110
|
-
const ref = await new Promise((resolve) => {
|
|
112
|
+
const ref = await new Promise((resolve: any) => {
|
|
111
113
|
const nodes = (
|
|
112
114
|
<View>
|
|
113
115
|
<View ref={resolve} />
|
|
@@ -115,9 +117,11 @@ describe("RefTracker", () => {
|
|
|
115
117
|
);
|
|
116
118
|
render(nodes);
|
|
117
119
|
});
|
|
120
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
|
|
118
121
|
const domNode = ReactDOM.findDOMNode(ref);
|
|
119
122
|
|
|
120
123
|
// Act
|
|
124
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'Element | Component<any, {}, any> | null | undefined'.
|
|
121
125
|
tracker.updateRef(ref);
|
|
122
126
|
|
|
123
127
|
// Assert
|
|
@@ -130,7 +134,7 @@ describe("RefTracker", () => {
|
|
|
130
134
|
const targetFn = jest.fn();
|
|
131
135
|
tracker.setCallback(targetFn);
|
|
132
136
|
|
|
133
|
-
const ref = await new Promise((resolve) => {
|
|
137
|
+
const ref = await new Promise((resolve: any) => {
|
|
134
138
|
const nodes = (
|
|
135
139
|
<View>
|
|
136
140
|
<View ref={resolve} />
|
|
@@ -138,10 +142,12 @@ describe("RefTracker", () => {
|
|
|
138
142
|
);
|
|
139
143
|
render(nodes);
|
|
140
144
|
});
|
|
145
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'Element | Component<any, {}, any> | null | undefined'.
|
|
141
146
|
tracker.updateRef(ref);
|
|
142
147
|
targetFn.mockClear();
|
|
143
148
|
|
|
144
149
|
// Act
|
|
150
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'Element | Component<any, {}, any> | null | undefined'.
|
|
145
151
|
tracker.updateRef(ref);
|
|
146
152
|
|
|
147
153
|
// Assert
|
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
1
|
/**
|
|
4
2
|
* This interface should be implemented by types that are interested in the
|
|
5
3
|
* notifications of active state being stolen. Generally, this would also be
|
|
@@ -39,6 +37,7 @@ export interface IActiveTrackerSubscriber {
|
|
|
39
37
|
*/
|
|
40
38
|
export default class ActiveTracker {
|
|
41
39
|
_subscribers: Array<IActiveTrackerSubscriber> = [];
|
|
40
|
+
// @ts-expect-error [FEI-5019] - TS2564 - Property '_active' has no initializer and is not definitely assigned in the constructor.
|
|
42
41
|
_active: boolean;
|
|
43
42
|
|
|
44
43
|
_getIndex(who: IActiveTrackerSubscriber): number {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/**
|
|
3
2
|
* This is a little helper that we can use to wrap the react-popper reference
|
|
4
3
|
* update methods so that we can convert a regular React ref into a DOM node
|
|
@@ -10,13 +9,18 @@ import * as ReactDOM from "react-dom";
|
|
|
10
9
|
|
|
11
10
|
import type {PopperChildrenProps} from "react-popper";
|
|
12
11
|
|
|
13
|
-
type PopperRef =
|
|
12
|
+
type PopperRef = PopperChildrenProps["ref"];
|
|
14
13
|
|
|
15
14
|
export default class RefTracker {
|
|
16
|
-
_lastRef:
|
|
17
|
-
_targetFn
|
|
15
|
+
_lastRef: HTMLElement | null | undefined;
|
|
16
|
+
// @ts-expect-error [FEI-5019] - TS2564 - Property '_targetFn' has no initializer and is not definitely assigned in the constructor.
|
|
17
|
+
_targetFn: (
|
|
18
|
+
arg1?: HTMLElement | null | undefined,
|
|
19
|
+
) => void | null | undefined;
|
|
18
20
|
|
|
19
|
-
updateRef: (
|
|
21
|
+
updateRef: (
|
|
22
|
+
ref?: React.Component<any> | Element | null | undefined,
|
|
23
|
+
) => void = (ref) => {
|
|
20
24
|
if (ref) {
|
|
21
25
|
// We only want to update the reference if it is
|
|
22
26
|
// actually changed. Otherwise, we can trigger another render that
|
|
@@ -24,17 +28,20 @@ export default class RefTracker {
|
|
|
24
28
|
const domNode = ReactDOM.findDOMNode(ref);
|
|
25
29
|
if (domNode instanceof HTMLElement && domNode !== this._lastRef) {
|
|
26
30
|
this._lastRef = domNode;
|
|
27
|
-
this._targetFn
|
|
31
|
+
this._targetFn?.(domNode);
|
|
28
32
|
}
|
|
29
33
|
}
|
|
30
34
|
};
|
|
31
35
|
|
|
32
|
-
setCallback: (targetFn
|
|
36
|
+
setCallback: (targetFn?: PopperRef | null | undefined) => void = (
|
|
37
|
+
targetFn,
|
|
38
|
+
) => {
|
|
33
39
|
if (this._targetFn !== targetFn) {
|
|
34
40
|
if (targetFn && typeof targetFn !== "function") {
|
|
35
41
|
throw new Error("targetFn must be a function");
|
|
36
42
|
}
|
|
37
43
|
|
|
44
|
+
// @ts-expect-error [FEI-5019] - TS2322 - Type '((instance: any) => void) | null' is not assignable to type '(arg1?: HTMLElement | null | undefined) => void | null | undefined'.
|
|
38
45
|
this._targetFn = targetFn || null;
|
|
39
46
|
if (this._lastRef && this._targetFn) {
|
|
40
47
|
this._targetFn(this._lastRef);
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
|
|
3
|
+
import type {CSSProperties} from "aphrodite";
|
|
4
|
+
|
|
5
|
+
export type getRefFn = (
|
|
6
|
+
arg1?: React.Component<any> | Element | null | undefined,
|
|
7
|
+
) => void;
|
|
8
|
+
|
|
9
|
+
export type Offset = {
|
|
10
|
+
bottom: CSSProperties["bottom"];
|
|
11
|
+
top: CSSProperties["top"];
|
|
12
|
+
left: CSSProperties["left"];
|
|
13
|
+
right: CSSProperties["right"];
|
|
14
|
+
transform: CSSProperties["transform"];
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type Placement =
|
|
18
|
+
| "auto"
|
|
19
|
+
| "auto-start"
|
|
20
|
+
| "auto-end"
|
|
21
|
+
| "top"
|
|
22
|
+
| "top-start"
|
|
23
|
+
| "top-end"
|
|
24
|
+
| "bottom"
|
|
25
|
+
| "bottom-start"
|
|
26
|
+
| "bottom-end"
|
|
27
|
+
| "right"
|
|
28
|
+
| "right-start"
|
|
29
|
+
| "right-end"
|
|
30
|
+
| "left"
|
|
31
|
+
| "left-start"
|
|
32
|
+
| "left-end";
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"exclude": ["dist"],
|
|
3
|
+
"extends": "../tsconfig-shared.json",
|
|
4
|
+
"compilerOptions": {
|
|
5
|
+
"outDir": "./dist",
|
|
6
|
+
"rootDir": "src",
|
|
7
|
+
},
|
|
8
|
+
"references": [
|
|
9
|
+
{"path": "../wonder-blocks-color"},
|
|
10
|
+
{"path": "../wonder-blocks-core"},
|
|
11
|
+
{"path": "../wonder-blocks-layout"},
|
|
12
|
+
{"path": "../wonder-blocks-modal"},
|
|
13
|
+
{"path": "../wonder-blocks-spacing"},
|
|
14
|
+
{"path": "../wonder-blocks-typography"},
|
|
15
|
+
]
|
|
16
|
+
}
|