@sproutsocial/seeds-react-tooltip 1.1.20 → 1.1.28
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/.turbo/turbo-build.log +10 -10
- package/CHANGELOG.md +65 -0
- package/dist/esm/index.js +131 -123
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.mts +17 -8
- package/dist/index.d.ts +17 -8
- package/dist/index.js +129 -121
- package/dist/index.js.map +1 -1
- package/package.json +10 -10
- package/src/Tooltip.stories.tsx +125 -0
- package/src/Tooltip.tsx +141 -128
- package/src/TooltipTypes.ts +32 -6
- package/src/__tests__/Tooltip.test.tsx +43 -153
- package/src/__tests__/mapPlacement.test.ts +56 -0
|
@@ -1,32 +1,13 @@
|
|
|
1
|
-
/* eslint-disable testing-library/no-unnecessary-act */
|
|
2
1
|
import React from "react";
|
|
3
2
|
import {
|
|
4
3
|
render,
|
|
5
4
|
screen,
|
|
6
|
-
|
|
7
|
-
act,
|
|
5
|
+
waitFor,
|
|
8
6
|
} from "@sproutsocial/seeds-react-testing-library";
|
|
9
7
|
import Icon from "@sproutsocial/seeds-react-icon";
|
|
10
8
|
import Tooltip from "../Tooltip";
|
|
11
9
|
import Button from "@sproutsocial/seeds-react-button";
|
|
12
10
|
|
|
13
|
-
jest.mock("popper.js", () => {
|
|
14
|
-
const PopperJS = jest.requireActual("popper.js");
|
|
15
|
-
const mockDestroy = jest.fn();
|
|
16
|
-
const mockScheduleUpdate = jest.fn();
|
|
17
|
-
|
|
18
|
-
return class Popper {
|
|
19
|
-
static placements = PopperJS.placements;
|
|
20
|
-
|
|
21
|
-
constructor() {
|
|
22
|
-
return {
|
|
23
|
-
destroy: mockDestroy,
|
|
24
|
-
scheduleUpdate: mockScheduleUpdate,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
};
|
|
28
|
-
});
|
|
29
|
-
|
|
30
11
|
jest.mock("@sproutsocial/seeds-react-portal", () => {
|
|
31
12
|
const Portal = ({ children }: { children: React.ReactNode }) => (
|
|
32
13
|
<div>{children}</div>
|
|
@@ -38,28 +19,21 @@ jest.mock("@sproutsocial/seeds-react-portal", () => {
|
|
|
38
19
|
DisablePortalToBodyContext: Portal.DisablePortalToBodyContext,
|
|
39
20
|
};
|
|
40
21
|
});
|
|
22
|
+
|
|
41
23
|
describe("Tooltip", () => {
|
|
42
24
|
describe("rendering all valid `React.Node`s", () => {
|
|
43
25
|
it("should render string content", async () => {
|
|
44
26
|
const contentText = "hey";
|
|
45
|
-
render(<Tooltip content={contentText}>hi</Tooltip>);
|
|
46
|
-
|
|
47
|
-
act(() => {
|
|
48
|
-
fireEvent.mouseOver(screen.getByText("hi"));
|
|
49
|
-
});
|
|
27
|
+
const { user } = render(<Tooltip content={contentText}>hi</Tooltip>);
|
|
28
|
+
await user.hover(screen.getByText("hi"));
|
|
50
29
|
await screen.findByText(contentText);
|
|
51
30
|
expect(screen.getByText(contentText)).toBeInTheDocument();
|
|
52
|
-
|
|
53
|
-
// TODO
|
|
54
|
-
// await runA11yCheck();
|
|
55
31
|
});
|
|
56
32
|
|
|
57
33
|
it("should render number content", async () => {
|
|
58
34
|
const contentText = 123;
|
|
59
|
-
render(<Tooltip content={contentText}>hi</Tooltip>);
|
|
60
|
-
|
|
61
|
-
fireEvent.mouseOver(screen.getByText("hi"));
|
|
62
|
-
});
|
|
35
|
+
const { user } = render(<Tooltip content={contentText}>hi</Tooltip>);
|
|
36
|
+
await user.hover(screen.getByText("hi"));
|
|
63
37
|
await screen.findByDataQaLabel({
|
|
64
38
|
"popout-isopen": "true",
|
|
65
39
|
});
|
|
@@ -67,10 +41,8 @@ describe("Tooltip", () => {
|
|
|
67
41
|
});
|
|
68
42
|
|
|
69
43
|
it("should render React Element content", async () => {
|
|
70
|
-
render(<Tooltip content={<p>hey</p>}>hi</Tooltip>);
|
|
71
|
-
|
|
72
|
-
fireEvent.mouseOver(screen.getByText("hi"));
|
|
73
|
-
});
|
|
44
|
+
const { user } = render(<Tooltip content={<p>hey</p>}>hi</Tooltip>);
|
|
45
|
+
await user.hover(screen.getByText("hi"));
|
|
74
46
|
await screen.findByDataQaLabel({
|
|
75
47
|
"popout-isopen": "true",
|
|
76
48
|
});
|
|
@@ -78,10 +50,10 @@ describe("Tooltip", () => {
|
|
|
78
50
|
});
|
|
79
51
|
|
|
80
52
|
it("should render $Iterable<string> content", async () => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
53
|
+
const { user } = render(
|
|
54
|
+
<Tooltip content={["hello", "world"]}>hi</Tooltip>
|
|
55
|
+
);
|
|
56
|
+
await user.hover(screen.getByText("hi"));
|
|
85
57
|
await screen.findByText(/hello/i);
|
|
86
58
|
expect(screen.getByText(/hello/i)).toBeInTheDocument();
|
|
87
59
|
await screen.findByText(/world/i);
|
|
@@ -89,14 +61,12 @@ describe("Tooltip", () => {
|
|
|
89
61
|
});
|
|
90
62
|
|
|
91
63
|
it("should render $Iterable<React$Element<any>> content", async () => {
|
|
92
|
-
render(
|
|
64
|
+
const { user } = render(
|
|
93
65
|
<Tooltip content={[<p key="1">hello</p>, <p key="2">world</p>]}>
|
|
94
66
|
hi
|
|
95
67
|
</Tooltip>
|
|
96
68
|
);
|
|
97
|
-
|
|
98
|
-
fireEvent.mouseOver(screen.getByText("hi"));
|
|
99
|
-
});
|
|
69
|
+
await user.hover(screen.getByText("hi"));
|
|
100
70
|
await screen.findByText(/hello/i);
|
|
101
71
|
expect(screen.getByText(/hello/i)).toBeInTheDocument();
|
|
102
72
|
await screen.findByText(/world/i);
|
|
@@ -105,11 +75,8 @@ describe("Tooltip", () => {
|
|
|
105
75
|
|
|
106
76
|
it("should not render null content", async () => {
|
|
107
77
|
expect.assertions(1);
|
|
108
|
-
render(<Tooltip content={null}>hi</Tooltip>);
|
|
109
|
-
|
|
110
|
-
fireEvent.mouseOver(screen.getByText("hi"));
|
|
111
|
-
});
|
|
112
|
-
// @see https://jestjs.io/docs/tutorial-async#rejects
|
|
78
|
+
const { user } = render(<Tooltip content={null}>hi</Tooltip>);
|
|
79
|
+
await user.hover(screen.getByText("hi"));
|
|
113
80
|
await expect(
|
|
114
81
|
screen.findByDataQaLabel({
|
|
115
82
|
"popout-isopen": "true",
|
|
@@ -119,11 +86,8 @@ describe("Tooltip", () => {
|
|
|
119
86
|
|
|
120
87
|
it("should not render undefined content", async () => {
|
|
121
88
|
expect.assertions(1);
|
|
122
|
-
render(<Tooltip content={undefined}>hi</Tooltip>);
|
|
123
|
-
|
|
124
|
-
fireEvent.mouseOver(screen.getByText("hi"));
|
|
125
|
-
});
|
|
126
|
-
// @see https://jestjs.io/docs/tutorial-async#rejects
|
|
89
|
+
const { user } = render(<Tooltip content={undefined}>hi</Tooltip>);
|
|
90
|
+
await user.hover(screen.getByText("hi"));
|
|
127
91
|
await expect(
|
|
128
92
|
screen.findByDataQaLabel({
|
|
129
93
|
"popout-isopen": "true",
|
|
@@ -132,7 +96,7 @@ describe("Tooltip", () => {
|
|
|
132
96
|
});
|
|
133
97
|
|
|
134
98
|
it("should not add aria-expanded to elements without it", async () => {
|
|
135
|
-
render(
|
|
99
|
+
const { user } = render(
|
|
136
100
|
<Tooltip content="hello">
|
|
137
101
|
<Button>hi</Button>
|
|
138
102
|
</Tooltip>
|
|
@@ -140,23 +104,17 @@ describe("Tooltip", () => {
|
|
|
140
104
|
|
|
141
105
|
const button = screen.getByRole("button", { name: "hi" });
|
|
142
106
|
|
|
143
|
-
// Should not have aria-expanded initially
|
|
144
107
|
expect(button).not.toHaveAttribute("aria-expanded");
|
|
145
108
|
|
|
146
|
-
|
|
147
|
-
act(() => {
|
|
148
|
-
fireEvent.mouseOver(button);
|
|
149
|
-
});
|
|
109
|
+
await user.hover(button.closest("[data-qa-tooltip]")!);
|
|
150
110
|
|
|
151
|
-
// Wait for tooltip
|
|
152
111
|
await screen.findByText(/hello/i);
|
|
153
112
|
|
|
154
|
-
// Should still not have aria-expanded (tooltips don't use this attribute)
|
|
155
113
|
expect(button).not.toHaveAttribute("aria-expanded");
|
|
156
114
|
});
|
|
157
115
|
|
|
158
116
|
it("should preserve existing aria-expanded attribute", async () => {
|
|
159
|
-
render(
|
|
117
|
+
const { user } = render(
|
|
160
118
|
<Tooltip content="hello">
|
|
161
119
|
<Button aria-expanded="false">hi</Button>
|
|
162
120
|
</Tooltip>
|
|
@@ -164,18 +122,12 @@ describe("Tooltip", () => {
|
|
|
164
122
|
|
|
165
123
|
const button = screen.getByRole("button", { name: "hi" });
|
|
166
124
|
|
|
167
|
-
// Should preserve the existing aria-expanded value
|
|
168
125
|
expect(button).toHaveAttribute("aria-expanded", "false");
|
|
169
126
|
|
|
170
|
-
|
|
171
|
-
act(() => {
|
|
172
|
-
fireEvent.mouseOver(button);
|
|
173
|
-
});
|
|
127
|
+
await user.hover(button.closest("[data-qa-tooltip]")!);
|
|
174
128
|
|
|
175
|
-
// Wait for tooltip
|
|
176
129
|
await screen.findByText(/hello/i);
|
|
177
130
|
|
|
178
|
-
// Should still preserve aria-expanded="false" (drawer/disclosure pattern)
|
|
179
131
|
expect(button).toHaveAttribute("aria-expanded", "false");
|
|
180
132
|
});
|
|
181
133
|
|
|
@@ -188,13 +140,12 @@ describe("Tooltip", () => {
|
|
|
188
140
|
|
|
189
141
|
const textElement = screen.getByTestId("text-element");
|
|
190
142
|
|
|
191
|
-
// Non-interactive elements should not get aria-expanded
|
|
192
143
|
expect(textElement).not.toHaveAttribute("aria-expanded");
|
|
193
144
|
});
|
|
194
145
|
});
|
|
195
146
|
|
|
196
147
|
it("should render when wrapped around an icon", async () => {
|
|
197
|
-
render(
|
|
148
|
+
const { user } = render(
|
|
198
149
|
<Tooltip content="hey">
|
|
199
150
|
<Icon
|
|
200
151
|
data-testid="icon"
|
|
@@ -203,10 +154,7 @@ describe("Tooltip", () => {
|
|
|
203
154
|
/>
|
|
204
155
|
</Tooltip>
|
|
205
156
|
);
|
|
206
|
-
|
|
207
|
-
act(() => {
|
|
208
|
-
fireEvent.mouseOver(screen.getByTestId("icon"));
|
|
209
|
-
});
|
|
157
|
+
await user.hover(screen.getByTestId("icon").closest("[data-qa-tooltip]")!);
|
|
210
158
|
await expect(
|
|
211
159
|
screen.findByDataQaLabel({
|
|
212
160
|
"popout-isopen": "true",
|
|
@@ -227,7 +175,7 @@ describe("Tooltip", () => {
|
|
|
227
175
|
});
|
|
228
176
|
|
|
229
177
|
it("should have aria-describedby when tooltip is open", async () => {
|
|
230
|
-
render(
|
|
178
|
+
const { user } = render(
|
|
231
179
|
<Tooltip content="Tooltip content">
|
|
232
180
|
<Button data-testid="trigger">Trigger</Button>
|
|
233
181
|
</Tooltip>
|
|
@@ -235,15 +183,10 @@ describe("Tooltip", () => {
|
|
|
235
183
|
|
|
236
184
|
const trigger = screen.getByTestId("trigger");
|
|
237
185
|
|
|
238
|
-
|
|
239
|
-
act(() => {
|
|
240
|
-
fireEvent.mouseOver(trigger);
|
|
241
|
-
});
|
|
186
|
+
await user.hover(trigger.closest("[data-qa-tooltip]")!);
|
|
242
187
|
|
|
243
|
-
// Wait for tooltip to appear
|
|
244
188
|
await screen.findByText("Tooltip content");
|
|
245
189
|
|
|
246
|
-
// Check that aria-describedby is now present
|
|
247
190
|
expect(trigger).toHaveAttribute("aria-describedby");
|
|
248
191
|
const tooltipId = trigger.getAttribute("aria-describedby");
|
|
249
192
|
expect(tooltipId).toBeTruthy();
|
|
@@ -251,7 +194,7 @@ describe("Tooltip", () => {
|
|
|
251
194
|
});
|
|
252
195
|
|
|
253
196
|
it("should remove aria-describedby when tooltip closes", async () => {
|
|
254
|
-
render(
|
|
197
|
+
const { user } = render(
|
|
255
198
|
<Tooltip content="Tooltip content">
|
|
256
199
|
<Button data-testid="trigger">Trigger</Button>
|
|
257
200
|
</Tooltip>
|
|
@@ -259,33 +202,21 @@ describe("Tooltip", () => {
|
|
|
259
202
|
|
|
260
203
|
const trigger = screen.getByTestId("trigger");
|
|
261
204
|
|
|
262
|
-
|
|
263
|
-
act(() => {
|
|
264
|
-
fireEvent.mouseOver(trigger);
|
|
265
|
-
});
|
|
205
|
+
await user.hover(trigger.closest("[data-qa-tooltip]")!);
|
|
266
206
|
|
|
267
|
-
// Wait for tooltip to appear
|
|
268
207
|
await screen.findByText("Tooltip content");
|
|
269
208
|
|
|
270
|
-
// Verify aria-describedby is present
|
|
271
209
|
expect(trigger).toHaveAttribute("aria-describedby");
|
|
272
210
|
|
|
273
|
-
|
|
274
|
-
act(() => {
|
|
275
|
-
fireEvent.mouseOut(trigger);
|
|
276
|
-
});
|
|
211
|
+
await user.unhover(trigger.closest("[data-qa-tooltip]")!);
|
|
277
212
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
213
|
+
await waitFor(() => {
|
|
214
|
+
expect(trigger).not.toHaveAttribute("aria-describedby");
|
|
281
215
|
});
|
|
282
|
-
|
|
283
|
-
// Verify aria-describedby is removed
|
|
284
|
-
expect(trigger).not.toHaveAttribute("aria-describedby");
|
|
285
216
|
});
|
|
286
217
|
|
|
287
218
|
it("should have aria-describedby pointing to element with role='tooltip'", async () => {
|
|
288
|
-
render(
|
|
219
|
+
const { user } = render(
|
|
289
220
|
<Tooltip content="Tooltip content">
|
|
290
221
|
<Button data-testid="trigger">Trigger</Button>
|
|
291
222
|
</Tooltip>
|
|
@@ -293,33 +224,25 @@ describe("Tooltip", () => {
|
|
|
293
224
|
|
|
294
225
|
const trigger = screen.getByTestId("trigger");
|
|
295
226
|
|
|
296
|
-
|
|
297
|
-
act(() => {
|
|
298
|
-
fireEvent.mouseOver(trigger);
|
|
299
|
-
});
|
|
227
|
+
await user.hover(trigger.closest("[data-qa-tooltip]")!);
|
|
300
228
|
|
|
301
|
-
// Wait for tooltip to appear
|
|
302
229
|
const tooltipElement = await screen.findByText("Tooltip content");
|
|
303
230
|
|
|
304
|
-
// Get the aria-describedby value
|
|
305
231
|
const tooltipId = trigger.getAttribute("aria-describedby");
|
|
306
232
|
expect(tooltipId).toBeTruthy();
|
|
307
233
|
|
|
308
|
-
// Find the tooltip by role
|
|
309
234
|
const tooltipByRole = screen.getByRole("tooltip");
|
|
310
235
|
expect(tooltipByRole).toBeInTheDocument();
|
|
311
236
|
|
|
312
|
-
// Verify the ID matches
|
|
313
237
|
expect(tooltipByRole).toHaveAttribute("id", tooltipId);
|
|
314
238
|
|
|
315
|
-
// Verify the tooltip contains the content
|
|
316
239
|
expect(tooltipByRole).toContainElement(tooltipElement);
|
|
317
240
|
});
|
|
318
241
|
});
|
|
319
242
|
|
|
320
243
|
describe("legacyMouseInteraction prop", () => {
|
|
321
244
|
it("should allow hovering over tooltip content when legacyMouseInteraction is true", async () => {
|
|
322
|
-
render(
|
|
245
|
+
const { user } = render(
|
|
323
246
|
<Tooltip content="Tooltip content" legacyMouseInteraction>
|
|
324
247
|
<Button data-testid="trigger">Trigger</Button>
|
|
325
248
|
</Tooltip>
|
|
@@ -327,44 +250,23 @@ describe("Tooltip", () => {
|
|
|
327
250
|
|
|
328
251
|
const trigger = screen.getByTestId("trigger");
|
|
329
252
|
|
|
330
|
-
|
|
331
|
-
act(() => {
|
|
332
|
-
fireEvent.mouseOver(trigger);
|
|
333
|
-
});
|
|
253
|
+
await user.hover(trigger.closest("[data-qa-tooltip]")!);
|
|
334
254
|
|
|
335
|
-
// Wait for tooltip to appear
|
|
336
255
|
const tooltipContent = await screen.findByText("Tooltip content");
|
|
337
256
|
expect(tooltipContent).toBeInTheDocument();
|
|
338
257
|
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
fireEvent.mouseOut(trigger);
|
|
342
|
-
});
|
|
343
|
-
|
|
344
|
-
// Hover over the tooltip content itself
|
|
345
|
-
act(() => {
|
|
346
|
-
fireEvent.mouseEnter(tooltipContent);
|
|
347
|
-
});
|
|
348
|
-
|
|
349
|
-
// Tooltip should remain open
|
|
350
|
-
await act(async () => {
|
|
351
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
352
|
-
});
|
|
353
|
-
expect(tooltipContent).toBeInTheDocument();
|
|
258
|
+
await user.unhover(trigger.closest("[data-qa-tooltip]")!);
|
|
259
|
+
await user.hover(tooltipContent);
|
|
354
260
|
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
fireEvent.mouseLeave(tooltipContent);
|
|
261
|
+
await waitFor(() => {
|
|
262
|
+
expect(tooltipContent).toBeInTheDocument();
|
|
358
263
|
});
|
|
359
264
|
|
|
360
|
-
|
|
361
|
-
await act(async () => {
|
|
362
|
-
await new Promise((resolve) => setTimeout(resolve, 200));
|
|
363
|
-
});
|
|
265
|
+
await user.unhover(tooltipContent);
|
|
364
266
|
});
|
|
365
267
|
|
|
366
268
|
it("should not have mouse handlers on tooltip content when legacyMouseInteraction is false", async () => {
|
|
367
|
-
render(
|
|
269
|
+
const { user } = render(
|
|
368
270
|
<Tooltip content="Tooltip content">
|
|
369
271
|
<Button data-testid="trigger">Trigger</Button>
|
|
370
272
|
</Tooltip>
|
|
@@ -372,24 +274,12 @@ describe("Tooltip", () => {
|
|
|
372
274
|
|
|
373
275
|
const trigger = screen.getByTestId("trigger");
|
|
374
276
|
|
|
375
|
-
|
|
376
|
-
act(() => {
|
|
377
|
-
fireEvent.mouseOver(trigger);
|
|
378
|
-
});
|
|
277
|
+
await user.hover(trigger.closest("[data-qa-tooltip]")!);
|
|
379
278
|
|
|
380
|
-
// Wait for tooltip to appear
|
|
381
279
|
const tooltipContent = await screen.findByText("Tooltip content");
|
|
382
280
|
expect(tooltipContent).toBeInTheDocument();
|
|
383
281
|
|
|
384
|
-
|
|
385
|
-
act(() => {
|
|
386
|
-
fireEvent.mouseOut(trigger);
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
// Without legacyMouseInteraction, tooltip closes immediately (exitDelay: 0)
|
|
390
|
-
await act(async () => {
|
|
391
|
-
await new Promise((resolve) => setTimeout(resolve, 100));
|
|
392
|
-
});
|
|
282
|
+
await user.unhover(trigger.closest("[data-qa-tooltip]")!);
|
|
393
283
|
});
|
|
394
284
|
});
|
|
395
285
|
});
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { mapPlacement } from "../Tooltip";
|
|
2
|
+
|
|
3
|
+
describe("mapPlacement", () => {
|
|
4
|
+
it("maps top placements", () => {
|
|
5
|
+
expect(mapPlacement("top")).toEqual({ side: "top", align: "center" });
|
|
6
|
+
expect(mapPlacement("top-start")).toEqual({ side: "top", align: "start" });
|
|
7
|
+
expect(mapPlacement("top-end")).toEqual({ side: "top", align: "end" });
|
|
8
|
+
});
|
|
9
|
+
|
|
10
|
+
it("maps bottom placements", () => {
|
|
11
|
+
expect(mapPlacement("bottom")).toEqual({ side: "bottom", align: "center" });
|
|
12
|
+
expect(mapPlacement("bottom-start")).toEqual({
|
|
13
|
+
side: "bottom",
|
|
14
|
+
align: "start",
|
|
15
|
+
});
|
|
16
|
+
expect(mapPlacement("bottom-end")).toEqual({
|
|
17
|
+
side: "bottom",
|
|
18
|
+
align: "end",
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
it("maps left placements", () => {
|
|
23
|
+
expect(mapPlacement("left")).toEqual({ side: "left", align: "center" });
|
|
24
|
+
expect(mapPlacement("left-start")).toEqual({
|
|
25
|
+
side: "left",
|
|
26
|
+
align: "start",
|
|
27
|
+
});
|
|
28
|
+
expect(mapPlacement("left-end")).toEqual({ side: "left", align: "end" });
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
it("maps right placements", () => {
|
|
32
|
+
expect(mapPlacement("right")).toEqual({ side: "right", align: "center" });
|
|
33
|
+
expect(mapPlacement("right-start")).toEqual({
|
|
34
|
+
side: "right",
|
|
35
|
+
align: "start",
|
|
36
|
+
});
|
|
37
|
+
expect(mapPlacement("right-end")).toEqual({ side: "right", align: "end" });
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
// `auto*` deliberately anchors to `side: "top"` and relies on base-ui's
|
|
41
|
+
// runtime collision flipping rather than Popper-style best-initial-side
|
|
42
|
+
// selection. This is the documented, intentional behavior — see the
|
|
43
|
+
// changeset and the `placement` prop JSDoc in TooltipTypes.ts.
|
|
44
|
+
it("anchors auto placements to top with align from the suffix", () => {
|
|
45
|
+
expect(mapPlacement("auto")).toEqual({ side: "top", align: "center" });
|
|
46
|
+
expect(mapPlacement("auto-start")).toEqual({
|
|
47
|
+
side: "top",
|
|
48
|
+
align: "start",
|
|
49
|
+
});
|
|
50
|
+
expect(mapPlacement("auto-end")).toEqual({ side: "top", align: "end" });
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
it("falls back to top/center for unknown placements", () => {
|
|
54
|
+
expect(mapPlacement("nonsense")).toEqual({ side: "top", align: "center" });
|
|
55
|
+
});
|
|
56
|
+
});
|