@khanacademy/wonder-blocks-tooltip 1.4.6 → 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 +29 -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} +30 -40
- package/src/components/__tests__/{tooltip-bubble.test.js → tooltip-bubble.test.tsx} +4 -4
- package/src/components/__tests__/{tooltip-popper.test.js → tooltip-popper.test.tsx} +15 -12
- package/src/components/__tests__/{tooltip-tail.test.js → tooltip-tail.test.tsx} +5 -4
- package/src/components/__tests__/{tooltip.integration.test.js → tooltip.integration.test.tsx} +0 -1
- package/src/components/__tests__/{tooltip.test.js → tooltip.test.tsx} +10 -8
- package/src/components/{tooltip-anchor.js → tooltip-anchor.tsx} +26 -27
- package/src/components/{tooltip-bubble.js → tooltip-bubble.tsx} +18 -30
- package/src/components/{tooltip-content.js → tooltip-content.tsx} +8 -10
- package/src/components/{tooltip-popper.js → tooltip-popper.tsx} +14 -14
- package/src/components/{tooltip-tail.js → tooltip-tail.tsx} +28 -32
- package/src/components/{tooltip.js → tooltip.tsx} +35 -39
- package/src/{index.js → index.ts} +0 -1
- package/src/util/__tests__/{active-tracker.test.js → active-tracker.test.ts} +0 -1
- package/src/util/__tests__/{ref-tracker.test.js → ref-tracker.test.tsx} +13 -7
- 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/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 {render} from "@testing-library/react";
|
|
4
3
|
|
|
@@ -10,7 +9,7 @@ describe("TooltipTail", () => {
|
|
|
10
9
|
describe("#render", () => {
|
|
11
10
|
test("unknown placement, throws", () => {
|
|
12
11
|
// Arrange
|
|
13
|
-
const fakePlacement =
|
|
12
|
+
const fakePlacement = "notaplacement" as Placement;
|
|
14
13
|
const nodes = <TooltipTail placement={fakePlacement} />;
|
|
15
14
|
|
|
16
15
|
// Act
|
|
@@ -25,10 +24,12 @@ describe("TooltipTail", () => {
|
|
|
25
24
|
test("known placement, does not throw", () => {
|
|
26
25
|
// Arrange
|
|
27
26
|
const testPoints = ["top", "right", "bottom", "left"];
|
|
28
|
-
const makeNode = (p) => <TooltipTail placement={p} />;
|
|
27
|
+
const makeNode = (p: any) => <TooltipTail placement={p} />;
|
|
29
28
|
|
|
30
29
|
// Act
|
|
31
|
-
const testees = testPoints.map(
|
|
30
|
+
const testees = testPoints.map(
|
|
31
|
+
(tp: any) => () => render(makeNode(tp)),
|
|
32
|
+
);
|
|
32
33
|
|
|
33
34
|
// Assert
|
|
34
35
|
for (const testee of testees) {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import * as ReactDOM from "react-dom";
|
|
4
3
|
import {render, screen} from "@testing-library/react";
|
|
@@ -14,7 +13,7 @@ jest.mock("@khanacademy/wonder-blocks-core", () => {
|
|
|
14
13
|
// We want all of Core to be the regular thing except for UniqueIDProvider
|
|
15
14
|
return {
|
|
16
15
|
...Core,
|
|
17
|
-
UniqueIDProvider: (props) =>
|
|
16
|
+
UniqueIDProvider: (props: any) =>
|
|
18
17
|
// NOTE(kevinb): We aren't actually access the DOM here. The logic
|
|
19
18
|
// used by this lint rule to determine DOM access could be more
|
|
20
19
|
// precise.
|
|
@@ -221,7 +220,7 @@ describe("Tooltip", () => {
|
|
|
221
220
|
<View>Anchor</View>
|
|
222
221
|
</View>
|
|
223
222
|
);
|
|
224
|
-
const ref = await new Promise((resolve) => {
|
|
223
|
+
const ref = await new Promise((resolve: any) => {
|
|
225
224
|
render(
|
|
226
225
|
<View>
|
|
227
226
|
<Tooltip ref={resolve} content="Content">
|
|
@@ -232,7 +231,8 @@ describe("Tooltip", () => {
|
|
|
232
231
|
});
|
|
233
232
|
|
|
234
233
|
// Act
|
|
235
|
-
|
|
234
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
|
|
235
|
+
const result = ReactDOM.findDOMNode(ref) as any;
|
|
236
236
|
|
|
237
237
|
// Assert
|
|
238
238
|
expect(result).toBeInstanceOf(HTMLDivElement);
|
|
@@ -248,7 +248,7 @@ describe("Tooltip", () => {
|
|
|
248
248
|
<View>Anchor</View>
|
|
249
249
|
</View>
|
|
250
250
|
);
|
|
251
|
-
const ref = await new Promise((resolve) => {
|
|
251
|
+
const ref = await new Promise((resolve: any) => {
|
|
252
252
|
render(
|
|
253
253
|
<View>
|
|
254
254
|
<Tooltip
|
|
@@ -261,7 +261,8 @@ describe("Tooltip", () => {
|
|
|
261
261
|
</View>,
|
|
262
262
|
);
|
|
263
263
|
});
|
|
264
|
-
|
|
264
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
|
|
265
|
+
const node = ReactDOM.findDOMNode(ref) as any;
|
|
265
266
|
|
|
266
267
|
// Act
|
|
267
268
|
const result = node.getAttribute("aria-describedby");
|
|
@@ -277,7 +278,7 @@ describe("Tooltip", () => {
|
|
|
277
278
|
<View>Anchor</View>
|
|
278
279
|
</View>
|
|
279
280
|
);
|
|
280
|
-
const ref = await new Promise((resolve) => {
|
|
281
|
+
const ref = await new Promise((resolve: any) => {
|
|
281
282
|
render(
|
|
282
283
|
<View>
|
|
283
284
|
<Tooltip ref={resolve} content="Content">
|
|
@@ -286,7 +287,8 @@ describe("Tooltip", () => {
|
|
|
286
287
|
</View>,
|
|
287
288
|
);
|
|
288
289
|
});
|
|
289
|
-
|
|
290
|
+
// @ts-expect-error [FEI-5019] - TS2345 - Argument of type 'unknown' is not assignable to parameter of type 'ReactInstance | null | undefined'.
|
|
291
|
+
const node = ReactDOM.findDOMNode(ref) as any;
|
|
290
292
|
|
|
291
293
|
// Act
|
|
292
294
|
const result = node.getAttribute("aria-describedby");
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/**
|
|
3
2
|
* This component turns the given content into an accessible anchor for
|
|
4
3
|
* positioning and displaying tooltips.
|
|
@@ -17,7 +16,7 @@ import {
|
|
|
17
16
|
|
|
18
17
|
import type {IActiveTrackerSubscriber} from "../util/active-tracker";
|
|
19
18
|
|
|
20
|
-
type Props = {
|
|
19
|
+
type Props = {
|
|
21
20
|
/**
|
|
22
21
|
* The content for anchoring the tooltip.
|
|
23
22
|
* This element will be used to position the tooltip.
|
|
@@ -25,15 +24,13 @@ type Props = {|
|
|
|
25
24
|
* We allow children to be a string so that we can add tooltips to
|
|
26
25
|
* words within a large block of text easily.
|
|
27
26
|
*/
|
|
28
|
-
children: React.
|
|
29
|
-
|
|
27
|
+
children: React.ReactElement<any> | string;
|
|
30
28
|
/**
|
|
31
29
|
* Callback to be invoked when the anchored content is mounted.
|
|
32
30
|
* This provides a reference to the anchored content, which can then be
|
|
33
31
|
* used for calculating tooltip bubble positioning.
|
|
34
32
|
*/
|
|
35
|
-
anchorRef: (
|
|
36
|
-
|
|
33
|
+
anchorRef: (arg1?: Element | null | undefined) => unknown;
|
|
37
34
|
/**
|
|
38
35
|
* When true, if a tabindex attribute is not already present on the element
|
|
39
36
|
* wrapped by the anchor, the element will be given tabindex=0 to make it
|
|
@@ -48,30 +45,28 @@ type Props = {|
|
|
|
48
45
|
* be accessible via keyboard in all circumstances where the tooltip would
|
|
49
46
|
* appear using the mouse, so verify those use-cases.
|
|
50
47
|
*/
|
|
51
|
-
forceAnchorFocusivity?: boolean
|
|
52
|
-
|
|
48
|
+
forceAnchorFocusivity?: boolean;
|
|
53
49
|
/**
|
|
54
50
|
* Callback to pass active state back to Tooltip.
|
|
55
51
|
*
|
|
56
52
|
* `active` will be true whenever the anchor is hovered or focused and false
|
|
57
53
|
* otherwise.
|
|
58
54
|
*/
|
|
59
|
-
onActiveChanged: (active: boolean) =>
|
|
60
|
-
|
|
55
|
+
onActiveChanged: (active: boolean) => unknown;
|
|
61
56
|
/**
|
|
62
57
|
* Optional unique id factory.
|
|
63
58
|
*/
|
|
64
|
-
ids?: IIdentifierFactory
|
|
65
|
-
|
|
59
|
+
ids?: IIdentifierFactory;
|
|
60
|
+
};
|
|
66
61
|
|
|
67
|
-
type DefaultProps = {
|
|
68
|
-
forceAnchorFocusivity:
|
|
69
|
-
|
|
62
|
+
type DefaultProps = {
|
|
63
|
+
forceAnchorFocusivity: Props["forceAnchorFocusivity"];
|
|
64
|
+
};
|
|
70
65
|
|
|
71
|
-
type State = {
|
|
66
|
+
type State = {
|
|
72
67
|
/** Is the anchor active or not? */
|
|
73
|
-
active: boolean
|
|
74
|
-
|
|
68
|
+
active: boolean;
|
|
69
|
+
};
|
|
75
70
|
|
|
76
71
|
const TRACKER = new ActiveTracker();
|
|
77
72
|
|
|
@@ -79,13 +74,15 @@ export default class TooltipAnchor
|
|
|
79
74
|
extends React.Component<Props, State>
|
|
80
75
|
implements IActiveTrackerSubscriber
|
|
81
76
|
{
|
|
82
|
-
_weSetFocusivity:
|
|
83
|
-
_anchorNode:
|
|
77
|
+
_weSetFocusivity: boolean | null | undefined;
|
|
78
|
+
_anchorNode: Element | null | undefined;
|
|
84
79
|
_focused: boolean;
|
|
85
80
|
_hovered: boolean;
|
|
81
|
+
// @ts-expect-error [FEI-5019] - TS2564 - Property '_stolenFromUs' has no initializer and is not definitely assigned in the constructor.
|
|
86
82
|
_stolenFromUs: boolean;
|
|
87
|
-
_unsubscribeFromTracker
|
|
88
|
-
|
|
83
|
+
// @ts-expect-error [FEI-5019] - TS2564 - Property '_unsubscribeFromTracker' has no initializer and is not definitely assigned in the constructor.
|
|
84
|
+
_unsubscribeFromTracker: () => void | null | undefined;
|
|
85
|
+
_timeoutID: number | null | undefined;
|
|
89
86
|
|
|
90
87
|
static defaultProps: DefaultProps = {
|
|
91
88
|
forceAnchorFocusivity: true,
|
|
@@ -104,7 +101,7 @@ export default class TooltipAnchor
|
|
|
104
101
|
componentDidMount() {
|
|
105
102
|
const anchorNode = ReactDOM.findDOMNode(this);
|
|
106
103
|
|
|
107
|
-
// This should never happen, but we have this check here to make
|
|
104
|
+
// This should never happen, but we have this check here to make TypeScript
|
|
108
105
|
// happy and ensure that if this does happen, we'll know about it.
|
|
109
106
|
if (anchorNode instanceof Text) {
|
|
110
107
|
throw new Error(
|
|
@@ -165,7 +162,7 @@ export default class TooltipAnchor
|
|
|
165
162
|
}
|
|
166
163
|
}
|
|
167
164
|
|
|
168
|
-
static ariaContentId
|
|
165
|
+
static ariaContentId = "aria-content";
|
|
169
166
|
|
|
170
167
|
activeStateStolen: () => void = () => {
|
|
171
168
|
// Something wants the active state.
|
|
@@ -257,6 +254,7 @@ export default class TooltipAnchor
|
|
|
257
254
|
const delay = active
|
|
258
255
|
? TooltipAppearanceDelay
|
|
259
256
|
: TooltipDisappearanceDelay;
|
|
257
|
+
// @ts-expect-error [FEI-5019] - TS2322 - Type 'Timeout' is not assignable to type 'number'.
|
|
260
258
|
this._timeoutID = setTimeout(() => {
|
|
261
259
|
this._timeoutID = null;
|
|
262
260
|
this._setActiveState(active, true);
|
|
@@ -301,7 +299,7 @@ export default class TooltipAnchor
|
|
|
301
299
|
}
|
|
302
300
|
};
|
|
303
301
|
|
|
304
|
-
_renderAnchorableChildren(): React.
|
|
302
|
+
_renderAnchorableChildren(): React.ReactElement<any> {
|
|
305
303
|
const {children} = this.props;
|
|
306
304
|
return typeof children === "string" ? (
|
|
307
305
|
<WBText>{children}</WBText>
|
|
@@ -310,7 +308,7 @@ export default class TooltipAnchor
|
|
|
310
308
|
);
|
|
311
309
|
}
|
|
312
310
|
|
|
313
|
-
_renderAccessibleChildren(ids: IIdentifierFactory): React.
|
|
311
|
+
_renderAccessibleChildren(ids: IIdentifierFactory): React.ReactNode {
|
|
314
312
|
const anchorableChildren = this._renderAnchorableChildren();
|
|
315
313
|
|
|
316
314
|
return React.cloneElement(anchorableChildren, {
|
|
@@ -318,12 +316,13 @@ export default class TooltipAnchor
|
|
|
318
316
|
});
|
|
319
317
|
}
|
|
320
318
|
|
|
321
|
-
render(): React.
|
|
319
|
+
render(): React.ReactElement {
|
|
322
320
|
// We need to make sure we can anchor on our content.
|
|
323
321
|
// If the content is just a string, we wrap it in a Text element
|
|
324
322
|
// so as not to affect styling or layout but still have an element
|
|
325
323
|
// to anchor to.
|
|
326
324
|
if (this.props.ids) {
|
|
325
|
+
// @ts-expect-error [FEI-5019] - TS2322 - Type 'ReactNode' is not assignable to type 'ReactElement<any, string | JSXElementConstructor<any>>'.
|
|
327
326
|
return this._renderAccessibleChildren(this.props.ids);
|
|
328
327
|
}
|
|
329
328
|
return this._renderAnchorableChildren();
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import {StyleSheet} from "aphrodite";
|
|
3
2
|
import * as React from "react";
|
|
4
3
|
import Colors from "@khanacademy/wonder-blocks-color";
|
|
@@ -6,48 +5,37 @@ import {View} from "@khanacademy/wonder-blocks-core";
|
|
|
6
5
|
import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
7
6
|
|
|
8
7
|
import type {StyleType} from "@khanacademy/wonder-blocks-core";
|
|
9
|
-
import
|
|
8
|
+
import TooltipContent from "./tooltip-content";
|
|
10
9
|
import TooltipTail from "./tooltip-tail";
|
|
11
10
|
|
|
12
11
|
import type {getRefFn, Offset, Placement} from "../util/types";
|
|
13
12
|
|
|
14
|
-
export type PopperElementProps = {
|
|
13
|
+
export type PopperElementProps = {
|
|
15
14
|
/** The placement of the bubble with respect to the anchor. */
|
|
16
|
-
placement: Placement
|
|
17
|
-
|
|
15
|
+
placement: Placement;
|
|
18
16
|
/** Whether the bubble is out of bounds or not. */
|
|
19
|
-
isReferenceHidden?:
|
|
20
|
-
|
|
17
|
+
isReferenceHidden?: boolean | null | undefined;
|
|
21
18
|
/** A callback for updating the ref of the bubble itself. */
|
|
22
|
-
updateBubbleRef?: getRefFn
|
|
23
|
-
|
|
19
|
+
updateBubbleRef?: getRefFn;
|
|
24
20
|
/** A callback for updating the ref of the bubble's tail. */
|
|
25
|
-
updateTailRef?: getRefFn
|
|
26
|
-
|
|
21
|
+
updateTailRef?: getRefFn;
|
|
27
22
|
/** Where the tail is to be rendered. */
|
|
28
|
-
tailOffset?: Offset
|
|
29
|
-
|
|
23
|
+
tailOffset?: Offset;
|
|
30
24
|
/** Additional styles to be applied by the bubble. */
|
|
31
|
-
style?: StyleType
|
|
32
|
-
|
|
25
|
+
style?: StyleType;
|
|
26
|
+
};
|
|
33
27
|
|
|
34
|
-
export type Props = {
|
|
28
|
+
export type Props = {
|
|
35
29
|
/** The unique identifier for this component. */
|
|
36
|
-
id: string
|
|
37
|
-
|
|
30
|
+
id: string;
|
|
38
31
|
/** The `TooltipContent` element that will be rendered in the bubble. */
|
|
39
|
-
children: React.
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
// TODO(somewhatabstract): Update react-docgen to support spread operators
|
|
44
|
-
// (v3 beta introduces this)
|
|
45
|
-
...PopperElementProps,
|
|
46
|
-
|};
|
|
32
|
+
children: React.ReactElement<React.ComponentProps<typeof TooltipContent>>;
|
|
33
|
+
onActiveChanged: (active: boolean) => unknown;
|
|
34
|
+
} & PopperElementProps; // (v3 beta introduces this) // TODO(somewhatabstract): Update react-docgen to support spread operators
|
|
47
35
|
|
|
48
|
-
type State = {
|
|
49
|
-
active: boolean
|
|
50
|
-
|
|
36
|
+
type State = {
|
|
37
|
+
active: boolean;
|
|
38
|
+
};
|
|
51
39
|
|
|
52
40
|
export default class TooltipBubble extends React.Component<Props, State> {
|
|
53
41
|
state: State = {
|
|
@@ -67,7 +55,7 @@ export default class TooltipBubble extends React.Component<Props, State> {
|
|
|
67
55
|
this.props.onActiveChanged(false);
|
|
68
56
|
};
|
|
69
57
|
|
|
70
|
-
render(): React.
|
|
58
|
+
render(): React.ReactElement {
|
|
71
59
|
const {
|
|
72
60
|
id,
|
|
73
61
|
children,
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import {StyleSheet} from "aphrodite";
|
|
4
3
|
|
|
@@ -9,21 +8,20 @@ import {HeadingSmall, LabelMedium} from "@khanacademy/wonder-blocks-typography";
|
|
|
9
8
|
|
|
10
9
|
import type {Typography} from "@khanacademy/wonder-blocks-typography";
|
|
11
10
|
|
|
12
|
-
type Props = {
|
|
11
|
+
type Props = {
|
|
13
12
|
/**
|
|
14
13
|
* The title for the tooltip content.
|
|
15
14
|
* Optional.
|
|
16
15
|
*/
|
|
17
|
-
title?: string | React.
|
|
18
|
-
|
|
16
|
+
title?: string | React.ReactElement<React.ComponentProps<Typography>>;
|
|
19
17
|
/**
|
|
20
18
|
* The main content for a tooltip.
|
|
21
19
|
*/
|
|
22
20
|
children:
|
|
23
21
|
| string
|
|
24
|
-
| React.
|
|
25
|
-
| Array<React.
|
|
26
|
-
|
|
22
|
+
| React.ReactElement<React.ComponentProps<Typography>>
|
|
23
|
+
| Array<React.ReactElement<React.ComponentProps<Typography>>>;
|
|
24
|
+
};
|
|
27
25
|
|
|
28
26
|
/**
|
|
29
27
|
* This component is used to provide the content that is to be rendered in the
|
|
@@ -40,7 +38,7 @@ type Props = {|
|
|
|
40
38
|
* ```
|
|
41
39
|
*/
|
|
42
40
|
export default class TooltipContent extends React.Component<Props> {
|
|
43
|
-
_renderTitle(): React.
|
|
41
|
+
_renderTitle(): React.ReactNode {
|
|
44
42
|
const {title} = this.props;
|
|
45
43
|
if (title) {
|
|
46
44
|
if (typeof title === "string") {
|
|
@@ -52,7 +50,7 @@ export default class TooltipContent extends React.Component<Props> {
|
|
|
52
50
|
return null;
|
|
53
51
|
}
|
|
54
52
|
|
|
55
|
-
_renderChildren(): React.
|
|
53
|
+
_renderChildren(): React.ReactNode {
|
|
56
54
|
const {children} = this.props;
|
|
57
55
|
if (typeof children === "string") {
|
|
58
56
|
return <LabelMedium>{children}</LabelMedium>;
|
|
@@ -61,7 +59,7 @@ export default class TooltipContent extends React.Component<Props> {
|
|
|
61
59
|
}
|
|
62
60
|
}
|
|
63
61
|
|
|
64
|
-
render(): React.
|
|
62
|
+
render(): React.ReactElement {
|
|
65
63
|
const title = this._renderTitle();
|
|
66
64
|
const children = this._renderChildren();
|
|
67
65
|
const containerStyle = title ? styles.withTitle : styles.withoutTitle;
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
/**
|
|
3
2
|
* This component is a light wrapper for react-popper, allowing us to position
|
|
4
3
|
* and control the tooltip bubble location and visibility as we need.
|
|
@@ -11,30 +10,30 @@ import RefTracker from "../util/ref-tracker";
|
|
|
11
10
|
import type {Placement} from "../util/types";
|
|
12
11
|
import type {PopperElementProps} from "./tooltip-bubble";
|
|
13
12
|
|
|
14
|
-
type Props = {
|
|
13
|
+
type Props = {
|
|
15
14
|
/**
|
|
16
15
|
* This uses the children-as-a-function approach, mirroring react-popper's
|
|
17
16
|
* implementation.
|
|
18
17
|
*
|
|
19
18
|
* TODO(WB-624): figure out to only allow TooltipBubble and PopoverDialog
|
|
20
19
|
*/
|
|
21
|
-
children: (PopperElementProps) => React.
|
|
22
|
-
|
|
20
|
+
children: (arg1: PopperElementProps) => React.ReactElement<any>;
|
|
23
21
|
/**
|
|
24
22
|
* The element that anchors the tooltip bubble.
|
|
25
23
|
* This is used to position the bubble.
|
|
26
24
|
*/
|
|
27
|
-
anchorElement:
|
|
28
|
-
|
|
25
|
+
anchorElement: HTMLElement | null | undefined;
|
|
29
26
|
/** Where should the bubble try to go with respect to its anchor. */
|
|
30
|
-
placement: Placement
|
|
31
|
-
|
|
27
|
+
placement: Placement;
|
|
28
|
+
};
|
|
32
29
|
|
|
33
30
|
export default class TooltipPopper extends React.Component<Props> {
|
|
34
31
|
_bubbleRefTracker: RefTracker = new RefTracker();
|
|
35
32
|
_tailRefTracker: RefTracker = new RefTracker();
|
|
36
33
|
|
|
37
|
-
_renderPositionedContent(
|
|
34
|
+
_renderPositionedContent(
|
|
35
|
+
popperProps: PopperChildrenProps,
|
|
36
|
+
): React.ReactNode {
|
|
38
37
|
const {children} = this.props;
|
|
39
38
|
|
|
40
39
|
// We'll hide some complexity from the children here and ensure
|
|
@@ -42,7 +41,7 @@ export default class TooltipPopper extends React.Component<Props> {
|
|
|
42
41
|
const placement: Placement =
|
|
43
42
|
// We know that popperProps.placement will only be one of our
|
|
44
43
|
// supported values, so just cast it.
|
|
45
|
-
(popperProps.placement
|
|
44
|
+
(popperProps.placement as any) || this.props.placement;
|
|
46
45
|
|
|
47
46
|
// Just in case the callbacks have changed, let's update our reference
|
|
48
47
|
// trackers.
|
|
@@ -55,8 +54,8 @@ export default class TooltipPopper extends React.Component<Props> {
|
|
|
55
54
|
placement,
|
|
56
55
|
style: {
|
|
57
56
|
// NOTE(jeresig): We can't just use `popperProps.style` here
|
|
58
|
-
// as the
|
|
59
|
-
// (as it doesn't camelCase props). So we just copy over the
|
|
57
|
+
// as the TypeScript type doesn't match Aphrodite's CSS TypeScript
|
|
58
|
+
// props (as it doesn't camelCase props). So we just copy over the
|
|
60
59
|
// props that we need, instead.
|
|
61
60
|
top: popperProps.style.top,
|
|
62
61
|
left: popperProps.style.left,
|
|
@@ -75,14 +74,15 @@ export default class TooltipPopper extends React.Component<Props> {
|
|
|
75
74
|
},
|
|
76
75
|
updateTailRef: this._tailRefTracker.updateRef,
|
|
77
76
|
isReferenceHidden: popperProps.isReferenceHidden,
|
|
78
|
-
};
|
|
77
|
+
} as const;
|
|
79
78
|
return children(bubbleProps);
|
|
80
79
|
}
|
|
81
80
|
|
|
82
|
-
render(): React.
|
|
81
|
+
render(): React.ReactElement {
|
|
83
82
|
const {anchorElement, placement} = this.props;
|
|
84
83
|
return (
|
|
85
84
|
<Popper
|
|
85
|
+
// @ts-expect-error [FEI-5019] - TS2769 - No overload matches this call.
|
|
86
86
|
referenceElement={anchorElement}
|
|
87
87
|
strategy="fixed"
|
|
88
88
|
placement={placement}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
1
|
import * as React from "react";
|
|
3
2
|
import {css, StyleSheet} from "aphrodite";
|
|
4
3
|
|
|
@@ -9,7 +8,7 @@ import Spacing from "@khanacademy/wonder-blocks-spacing";
|
|
|
9
8
|
import type {StyleType} from "@khanacademy/wonder-blocks-core";
|
|
10
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
|