@ssaprt/tooltip 1.0.0

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/dist/index.js ADDED
@@ -0,0 +1,2364 @@
1
+ "use client";
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ Tooltip: () => Tooltip,
25
+ TooltipProvider: () => TooltipProvider
26
+ });
27
+ module.exports = __toCommonJS(index_exports);
28
+
29
+ // src/components/Tooltip.tsx
30
+ var import_react4 = require("react");
31
+ var import_react_dom = require("react-dom");
32
+
33
+ // src/config/presets.ts
34
+ var animations = {
35
+ soft: {
36
+ show: "fade",
37
+ hide: "fade",
38
+ speed: "160ms",
39
+ easing: "ease-in-out"
40
+ },
41
+ slide: {
42
+ show: "slide",
43
+ hide: "fade",
44
+ speed: "160ms",
45
+ easing: "ease-out"
46
+ },
47
+ pop: {
48
+ show: "scale",
49
+ hide: "scale",
50
+ speed: "170ms",
51
+ easing: "cubic-bezier(0.22, 1, 0.36, 1)"
52
+ },
53
+ bounce: {
54
+ show: "bounce",
55
+ hide: "scale",
56
+ speed: "240ms",
57
+ easing: "cubic-bezier(0.34, 1.56, 0.64, 1)"
58
+ },
59
+ flip: {
60
+ show: "flip",
61
+ hide: "fade",
62
+ speed: "210ms",
63
+ easing: "cubic-bezier(0.22, 1, 0.36, 1)"
64
+ },
65
+ blur: {
66
+ show: "blur",
67
+ hide: "blur",
68
+ speed: "200ms",
69
+ easing: "ease-out"
70
+ },
71
+ zoom: {
72
+ show: "zoom",
73
+ hide: "zoom",
74
+ speed: "170ms",
75
+ easing: "ease-out"
76
+ },
77
+ snap: {
78
+ show: "zoom",
79
+ hide: "fade",
80
+ speed: "110ms",
81
+ easing: "steps(4, end)"
82
+ },
83
+ instant: {
84
+ show: "none",
85
+ hide: "none",
86
+ speed: "1ms",
87
+ easing: "linear"
88
+ }
89
+ };
90
+ var createTheme = ({
91
+ background,
92
+ color,
93
+ fontFamily = "Inter, Arial, sans-serif",
94
+ fontSize = "12px",
95
+ fontWeight = 500,
96
+ fontStyle,
97
+ lineHeight = 1.4,
98
+ borderRadius = "7px",
99
+ border,
100
+ filter,
101
+ padding = "7px 12px",
102
+ letterSpacing,
103
+ textShadow,
104
+ textTransform,
105
+ textAlign = "center",
106
+ backdropFilter,
107
+ arrowSize = "7px",
108
+ arrowWidth = "14px",
109
+ animation = animations.slide,
110
+ style
111
+ }) => {
112
+ return {
113
+ body: {
114
+ background,
115
+ filter,
116
+ style: {
117
+ color,
118
+ fontFamily,
119
+ fontSize,
120
+ fontWeight,
121
+ fontStyle,
122
+ lineHeight,
123
+ borderRadius,
124
+ border,
125
+ padding,
126
+ letterSpacing,
127
+ textShadow,
128
+ textTransform,
129
+ textAlign,
130
+ backdropFilter,
131
+ WebkitBackdropFilter: backdropFilter,
132
+ ...style
133
+ }
134
+ },
135
+ arrow: {
136
+ size: arrowSize,
137
+ width: arrowWidth
138
+ },
139
+ animation
140
+ };
141
+ };
142
+ var presets = {
143
+ primary: createTheme({
144
+ background: "linear-gradient(135deg, #2563eb, #1d4ed8)",
145
+ color: "#ffffff",
146
+ filter: "drop-shadow(0 7px 12px rgba(37, 99, 235, 0.38))",
147
+ border: "1px solid rgba(255, 255, 255, 0.18)",
148
+ borderRadius: "8px"
149
+ }),
150
+ secondary: createTheme({
151
+ background: "linear-gradient(135deg, #64748b, #475569)",
152
+ color: "#ffffff",
153
+ filter: "drop-shadow(0 7px 12px rgba(15, 23, 42, 0.3))",
154
+ border: "1px solid rgba(255, 255, 255, 0.15)",
155
+ animation: animations.soft
156
+ }),
157
+ dark: createTheme({
158
+ background: "linear-gradient(145deg, #18181b, #09090b)",
159
+ color: "#fafafa",
160
+ border: "1px solid #3f3f46",
161
+ borderRadius: "10px",
162
+ filter: "drop-shadow(0 11px 18px rgba(0, 0, 0, 0.56))",
163
+ animation: animations.pop
164
+ }),
165
+ light: createTheme({
166
+ background: "linear-gradient(145deg, #ffffff, #f4f4f5)",
167
+ color: "#18181b",
168
+ border: "1px solid #d4d4d8",
169
+ borderRadius: "10px",
170
+ filter: "drop-shadow(0 9px 15px rgba(15, 23, 42, 0.18))",
171
+ animation: animations.soft
172
+ }),
173
+ comic: createTheme({
174
+ background: "#fde047",
175
+ color: "#18181b",
176
+ fontFamily: "Comic Sans MS, Comic Sans, cursive",
177
+ fontSize: "13px",
178
+ fontWeight: 700,
179
+ border: "3px solid #18181b",
180
+ borderRadius: "12px",
181
+ filter: "drop-shadow(5px 5px 0 #18181b)",
182
+ padding: "8px 14px",
183
+ textTransform: "uppercase",
184
+ arrowSize: "9px",
185
+ arrowWidth: "20px",
186
+ animation: animations.bounce
187
+ }),
188
+ manga: createTheme({
189
+ background: "radial-gradient(circle at 2px 2px, rgba(0, 0, 0, 0.2) 1px, transparent 1.5px) 0 0 / 6px 6px, #ffffff",
190
+ color: "#000000",
191
+ fontFamily: "Impact, Haettenschweiler, Arial Narrow Bold, sans-serif",
192
+ fontSize: "13px",
193
+ fontWeight: 900,
194
+ border: "3px solid #000000",
195
+ borderRadius: "18px 5px 18px 5px",
196
+ filter: "drop-shadow(4px 4px 0 #000000)",
197
+ padding: "9px 15px",
198
+ letterSpacing: "0.04em",
199
+ textTransform: "uppercase",
200
+ arrowSize: "11px",
201
+ arrowWidth: "17px",
202
+ animation: animations.snap
203
+ }),
204
+ newspaper: createTheme({
205
+ background: "repeating-linear-gradient(0deg, rgba(68, 64, 60, 0.035) 0, rgba(68, 64, 60, 0.035) 1px, transparent 1px, transparent 4px), #f5f0e6",
206
+ color: "#292524",
207
+ fontFamily: "Times New Roman, Times, serif",
208
+ fontSize: "13px",
209
+ fontWeight: 600,
210
+ border: "2px solid #44403c",
211
+ borderRadius: "1px",
212
+ filter: "drop-shadow(3px 4px 0 rgba(68, 64, 60, 0.28))",
213
+ padding: "9px 15px",
214
+ letterSpacing: "0.02em",
215
+ textAlign: "left",
216
+ arrowSize: "8px",
217
+ arrowWidth: "18px",
218
+ animation: animations.soft,
219
+ style: {
220
+ fontVariantCaps: "small-caps"
221
+ }
222
+ }),
223
+ stickyNote: createTheme({
224
+ background: "linear-gradient(145deg, #fff7a8 0%, #fde96b 70%, #e9cc42 100%)",
225
+ color: "#4a3c00",
226
+ fontFamily: "Comic Sans MS, cursive",
227
+ fontSize: "13px",
228
+ fontWeight: 600,
229
+ border: "1px solid #d6b936",
230
+ borderRadius: "3px 14px 5px 11px",
231
+ filter: "drop-shadow(3px 6px 5px rgba(78, 65, 0, 0.28))",
232
+ padding: "10px 15px",
233
+ textAlign: "left",
234
+ arrowSize: "8px",
235
+ arrowWidth: "19px",
236
+ animation: animations.pop
237
+ }),
238
+ blueprint: createTheme({
239
+ background: "linear-gradient(rgba(147, 197, 253, 0.15) 1px, transparent 1px), linear-gradient(90deg, rgba(147, 197, 253, 0.15) 1px, transparent 1px), #0c4a6e",
240
+ color: "#e0f2fe",
241
+ fontFamily: "Courier New, Consolas, monospace",
242
+ fontSize: "12px",
243
+ fontWeight: 600,
244
+ border: "2px dashed #7dd3fc",
245
+ borderRadius: "2px",
246
+ filter: "drop-shadow(0 0 7px rgba(56, 189, 248, 0.45))",
247
+ padding: "9px 13px",
248
+ letterSpacing: "0.05em",
249
+ textAlign: "left",
250
+ arrowSize: "8px",
251
+ arrowWidth: "16px",
252
+ animation: animations.flip,
253
+ style: {
254
+ backgroundSize: "12px 12px"
255
+ }
256
+ }),
257
+ terminal: createTheme({
258
+ background: "linear-gradient(180deg, #020617, #000000)",
259
+ color: "#22c55e",
260
+ fontFamily: "Consolas, Monaco, Courier New, monospace",
261
+ fontSize: "12px",
262
+ fontWeight: 600,
263
+ border: "1px solid #22c55e",
264
+ borderRadius: "3px",
265
+ filter: "drop-shadow(0 0 5px rgba(34, 197, 94, 0.65))",
266
+ padding: "8px 12px",
267
+ letterSpacing: "0.035em",
268
+ textShadow: "0 0 5px rgba(34, 197, 94, 0.9)",
269
+ textAlign: "left",
270
+ arrowSize: "7px",
271
+ arrowWidth: "13px",
272
+ animation: animations.instant
273
+ }),
274
+ crt: createTheme({
275
+ background: "repeating-linear-gradient(0deg, rgba(34, 197, 94, 0.08) 0, rgba(34, 197, 94, 0.08) 1px, transparent 1px, transparent 3px), radial-gradient(circle at center, #07150b, #000000)",
276
+ color: "#86efac",
277
+ fontFamily: "Lucida Console, Monaco, monospace",
278
+ fontSize: "12px",
279
+ fontWeight: 600,
280
+ border: "2px solid #166534",
281
+ borderRadius: "18px",
282
+ filter: "drop-shadow(0 0 8px rgba(34, 197, 94, 0.5)) drop-shadow(0 0 18px rgba(34, 197, 94, 0.18))",
283
+ padding: "10px 15px",
284
+ textShadow: "0 0 6px rgba(134, 239, 172, 0.85)",
285
+ arrowSize: "8px",
286
+ arrowWidth: "18px",
287
+ animation: animations.blur
288
+ }),
289
+ pixel: createTheme({
290
+ background: "linear-gradient(135deg, #4c1d95 25%, #581c87 25%, #581c87 50%, #4c1d95 50%, #4c1d95 75%, #581c87 75%) 0 0 / 8px 8px",
291
+ color: "#fef08a",
292
+ fontFamily: "Press Start 2P, Courier New, monospace",
293
+ fontSize: "10px",
294
+ fontWeight: 700,
295
+ lineHeight: 1.7,
296
+ border: "4px solid #fef08a",
297
+ borderRadius: "0px",
298
+ filter: "drop-shadow(6px 6px 0 #18181b)",
299
+ padding: "10px 14px",
300
+ letterSpacing: "0.03em",
301
+ textShadow: "2px 2px 0 #18181b",
302
+ textTransform: "uppercase",
303
+ arrowSize: "10px",
304
+ arrowWidth: "18px",
305
+ animation: animations.snap
306
+ }),
307
+ arcade: createTheme({
308
+ background: "radial-gradient(circle at 20% 0%, rgba(34, 211, 238, 0.45), transparent 38%), radial-gradient(circle at 90% 100%, rgba(236, 72, 153, 0.55), transparent 45%), #150629",
309
+ color: "#ffffff",
310
+ fontFamily: "Arial Black, Impact, sans-serif",
311
+ fontSize: "12px",
312
+ fontWeight: 900,
313
+ border: "2px solid #22d3ee",
314
+ borderRadius: "12px",
315
+ filter: "drop-shadow(3px 3px 0 #ec4899) drop-shadow(-3px -3px 0 #22d3ee)",
316
+ padding: "9px 15px",
317
+ letterSpacing: "0.07em",
318
+ textShadow: "0 0 6px #22d3ee",
319
+ textTransform: "uppercase",
320
+ arrowSize: "9px",
321
+ arrowWidth: "18px",
322
+ animation: animations.bounce
323
+ }),
324
+ cyberpunk: createTheme({
325
+ background: "repeating-linear-gradient(135deg, rgba(0, 0, 0, 0.12) 0, rgba(0, 0, 0, 0.12) 5px, transparent 5px, transparent 10px), linear-gradient(135deg, #fde047, #facc15)",
326
+ color: "#18181b",
327
+ fontFamily: "Impact, Arial Black, sans-serif",
328
+ fontSize: "12px",
329
+ fontWeight: 900,
330
+ border: "2px solid #22d3ee",
331
+ borderRadius: "1px 12px 1px 12px",
332
+ filter: "drop-shadow(5px 5px 0 #ec4899) drop-shadow(-2px -2px 0 #22d3ee)",
333
+ padding: "9px 15px",
334
+ letterSpacing: "0.08em",
335
+ textTransform: "uppercase",
336
+ arrowSize: "10px",
337
+ arrowWidth: "21px",
338
+ animation: animations.flip
339
+ }),
340
+ synthwave: createTheme({
341
+ background: "linear-gradient(180deg, rgba(15, 23, 42, 0.2), rgba(15, 23, 42, 0.75)), linear-gradient(135deg, #7c3aed, #db2777)",
342
+ color: "#fdf4ff",
343
+ fontFamily: "Trebuchet MS, Arial, sans-serif",
344
+ fontSize: "12px",
345
+ fontWeight: 700,
346
+ border: "2px solid #67e8f9",
347
+ borderRadius: "16px 3px 16px 3px",
348
+ filter: "drop-shadow(0 0 7px #ec4899) drop-shadow(0 0 14px rgba(103, 232, 249, 0.5))",
349
+ padding: "9px 15px",
350
+ letterSpacing: "0.07em",
351
+ textShadow: "0 0 6px rgba(255, 255, 255, 0.7)",
352
+ textTransform: "uppercase",
353
+ arrowSize: "9px",
354
+ arrowWidth: "20px",
355
+ animation: animations.zoom
356
+ }),
357
+ vaporwave: createTheme({
358
+ background: "linear-gradient(135deg, rgba(255, 255, 255, 0.2), transparent 50%), linear-gradient(135deg, #67e8f9, #f0abfc 52%, #f9a8d4)",
359
+ color: "#4c1d95",
360
+ fontFamily: "Arial Rounded MT Bold, Arial, sans-serif",
361
+ fontSize: "12px",
362
+ fontWeight: 700,
363
+ border: "2px solid #ffffff",
364
+ borderRadius: "18px",
365
+ filter: "drop-shadow(5px 6px 0 rgba(124, 58, 237, 0.42))",
366
+ padding: "9px 16px",
367
+ letterSpacing: "0.06em",
368
+ textShadow: "1px 1px 0 rgba(255, 255, 255, 0.8)",
369
+ textTransform: "uppercase",
370
+ arrowSize: "9px",
371
+ arrowWidth: "21px",
372
+ animation: animations.bounce
373
+ }),
374
+ hologram: createTheme({
375
+ background: "linear-gradient(115deg, rgba(34, 211, 238, 0.42), rgba(168, 85, 247, 0.35), rgba(236, 72, 153, 0.35), rgba(34, 211, 238, 0.42)), rgba(8, 47, 73, 0.72)",
376
+ color: "#ecfeff",
377
+ fontFamily: "Segoe UI, Arial, sans-serif",
378
+ fontSize: "12px",
379
+ fontWeight: 600,
380
+ border: "1px solid rgba(165, 243, 252, 0.75)",
381
+ borderRadius: "14px",
382
+ filter: "drop-shadow(0 0 7px rgba(34, 211, 238, 0.75)) drop-shadow(0 0 16px rgba(168, 85, 247, 0.4))",
383
+ padding: "9px 15px",
384
+ letterSpacing: "0.06em",
385
+ backdropFilter: "blur(8px)",
386
+ arrowSize: "8px",
387
+ arrowWidth: "18px",
388
+ animation: animations.blur
389
+ }),
390
+ glass: createTheme({
391
+ background: "linear-gradient(135deg, rgba(255, 255, 255, 0.22), rgba(255, 255, 255, 0.07)), rgba(15, 23, 42, 0.68)",
392
+ color: "#f8fafc",
393
+ border: "1px solid rgba(255, 255, 255, 0.34)",
394
+ borderRadius: "16px",
395
+ filter: "drop-shadow(0 12px 20px rgba(15, 23, 42, 0.38))",
396
+ padding: "9px 15px",
397
+ backdropFilter: "blur(16px)",
398
+ arrowSize: "8px",
399
+ arrowWidth: "18px",
400
+ animation: animations.blur
401
+ }),
402
+ frost: createTheme({
403
+ background: "radial-gradient(circle at 15% 20%, rgba(255, 255, 255, 0.85), transparent 35%), linear-gradient(135deg, rgba(224, 242, 254, 0.92), rgba(186, 230, 253, 0.72))",
404
+ color: "#075985",
405
+ fontWeight: 600,
406
+ border: "1px solid rgba(125, 211, 252, 0.9)",
407
+ borderRadius: "18px",
408
+ filter: "drop-shadow(0 8px 15px rgba(14, 116, 144, 0.24))",
409
+ padding: "9px 15px",
410
+ textShadow: "0 1px 0 rgba(255, 255, 255, 0.8)",
411
+ backdropFilter: "blur(14px)",
412
+ arrowSize: "8px",
413
+ arrowWidth: "19px",
414
+ animation: animations.blur
415
+ }),
416
+ clay: createTheme({
417
+ background: "linear-gradient(145deg, #f3d5bc, #d9a77d)",
418
+ color: "#5b2d16",
419
+ fontFamily: "Arial Rounded MT Bold, Arial, sans-serif",
420
+ fontSize: "12px",
421
+ fontWeight: 700,
422
+ border: "1px solid #c78f63",
423
+ borderRadius: "24px",
424
+ filter: "drop-shadow(7px 9px 10px rgba(91, 45, 22, 0.28)) drop-shadow(-3px -3px 5px rgba(255, 242, 229, 0.72))",
425
+ padding: "10px 17px",
426
+ arrowSize: "9px",
427
+ arrowWidth: "22px",
428
+ animation: animations.pop
429
+ }),
430
+ bubblegum: createTheme({
431
+ background: "radial-gradient(circle at 25% 15%, rgba(255, 255, 255, 0.55), transparent 28%), linear-gradient(135deg, #f9a8d4, #f472b6)",
432
+ color: "#831843",
433
+ fontFamily: "Arial Rounded MT Bold, Arial, sans-serif",
434
+ fontSize: "12px",
435
+ fontWeight: 700,
436
+ border: "2px solid #fdf2f8",
437
+ borderRadius: "999px",
438
+ filter: "drop-shadow(0 8px 12px rgba(219, 39, 119, 0.34))",
439
+ padding: "9px 18px",
440
+ textShadow: "0 1px 0 rgba(255, 255, 255, 0.8)",
441
+ arrowSize: "9px",
442
+ arrowWidth: "22px",
443
+ animation: animations.bounce
444
+ }),
445
+ candy: createTheme({
446
+ background: "repeating-linear-gradient(135deg, #ffffff 0, #ffffff 8px, #ef4444 8px, #ef4444 16px)",
447
+ color: "#991b1b",
448
+ fontFamily: "Arial Rounded MT Bold, Arial, sans-serif",
449
+ fontSize: "12px",
450
+ fontWeight: 900,
451
+ border: "3px solid #991b1b",
452
+ borderRadius: "16px",
453
+ filter: "drop-shadow(4px 5px 0 rgba(127, 29, 29, 0.5))",
454
+ padding: "9px 16px",
455
+ textShadow: "1px 1px 0 #ffffff, -1px -1px 0 #ffffff",
456
+ textTransform: "uppercase",
457
+ arrowSize: "10px",
458
+ arrowWidth: "22px",
459
+ animation: animations.bounce
460
+ }),
461
+ watermelon: createTheme({
462
+ background: "radial-gradient(ellipse at 22% 30%, #111827 0 2px, transparent 3px), radial-gradient(ellipse at 72% 68%, #111827 0 2px, transparent 3px), linear-gradient(180deg, #fb7185 0%, #f43f5e 72%, #f8fafc 72%, #f8fafc 82%, #22c55e 82%)",
463
+ color: "#4c0519",
464
+ fontFamily: "Trebuchet MS, sans-serif",
465
+ fontSize: "12px",
466
+ fontWeight: 800,
467
+ border: "2px solid #166534",
468
+ borderRadius: "20px 20px 8px 8px",
469
+ filter: "drop-shadow(0 8px 11px rgba(22, 101, 52, 0.32))",
470
+ padding: "9px 16px 12px",
471
+ arrowSize: "9px",
472
+ arrowWidth: "22px",
473
+ animation: animations.pop
474
+ }),
475
+ lemon: createTheme({
476
+ background: "radial-gradient(circle at 25% 25%, rgba(255, 255, 255, 0.65), transparent 22%), linear-gradient(135deg, #fef08a, #facc15)",
477
+ color: "#713f12",
478
+ fontFamily: "Arial Rounded MT Bold, Arial, sans-serif",
479
+ fontSize: "12px",
480
+ fontWeight: 800,
481
+ border: "2px dotted #a16207",
482
+ borderRadius: "999px",
483
+ filter: "drop-shadow(0 7px 10px rgba(202, 138, 4, 0.32))",
484
+ padding: "8px 17px",
485
+ arrowSize: "9px",
486
+ arrowWidth: "22px",
487
+ animation: animations.bounce
488
+ }),
489
+ lava: createTheme({
490
+ background: "radial-gradient(circle at 18% 20%, #facc15 0, #f97316 8%, transparent 22%), radial-gradient(circle at 78% 70%, #ef4444 0, #7f1d1d 18%, transparent 34%), linear-gradient(135deg, #450a0a, #09090b)",
491
+ color: "#fef3c7",
492
+ fontFamily: "Impact, Arial Black, sans-serif",
493
+ fontSize: "12px",
494
+ fontWeight: 800,
495
+ border: "2px solid #f97316",
496
+ borderRadius: "14px 4px 18px 6px",
497
+ filter: "drop-shadow(0 0 7px rgba(249, 115, 22, 0.8)) drop-shadow(0 8px 15px rgba(69, 10, 10, 0.6))",
498
+ padding: "9px 15px",
499
+ letterSpacing: "0.04em",
500
+ textShadow: "0 0 5px rgba(253, 186, 116, 0.8)",
501
+ textTransform: "uppercase",
502
+ arrowSize: "10px",
503
+ arrowWidth: "19px",
504
+ animation: animations.zoom
505
+ }),
506
+ ember: createTheme({
507
+ background: "radial-gradient(circle at 15% 40%, rgba(251, 146, 60, 0.72), transparent 22%), radial-gradient(circle at 75% 20%, rgba(239, 68, 68, 0.48), transparent 25%), #291208",
508
+ color: "#fed7aa",
509
+ fontFamily: "Georgia, serif",
510
+ fontSize: "13px",
511
+ fontWeight: 600,
512
+ border: "1px solid #c2410c",
513
+ borderRadius: "8px 18px 8px 18px",
514
+ filter: "drop-shadow(0 0 7px rgba(234, 88, 12, 0.5))",
515
+ padding: "9px 15px",
516
+ textShadow: "0 0 4px rgba(251, 146, 60, 0.7)",
517
+ arrowSize: "9px",
518
+ arrowWidth: "18px",
519
+ animation: animations.blur
520
+ }),
521
+ toxic: createTheme({
522
+ background: "repeating-linear-gradient(135deg, rgba(0, 0, 0, 0.17) 0, rgba(0, 0, 0, 0.17) 5px, transparent 5px, transparent 10px), #a3e635",
523
+ color: "#1a2e05",
524
+ fontFamily: "Arial Black, Impact, sans-serif",
525
+ fontSize: "12px",
526
+ fontWeight: 900,
527
+ border: "3px solid #1a2e05",
528
+ borderRadius: "2px 12px 2px 12px",
529
+ filter: "drop-shadow(4px 5px 0 #365314)",
530
+ padding: "9px 14px",
531
+ letterSpacing: "0.08em",
532
+ textTransform: "uppercase",
533
+ arrowSize: "10px",
534
+ arrowWidth: "20px",
535
+ animation: animations.snap
536
+ }),
537
+ radioactive: createTheme({
538
+ background: "conic-gradient(from 45deg at 50% 50%, #facc15 0 12.5%, #18181b 12.5% 25%, #facc15 25% 37.5%, #18181b 37.5% 50%, #facc15 50% 62.5%, #18181b 62.5% 75%, #facc15 75% 87.5%, #18181b 87.5%)",
539
+ color: "#ffffff",
540
+ fontFamily: "Arial Black, sans-serif",
541
+ fontSize: "12px",
542
+ fontWeight: 900,
543
+ border: "3px solid #000000",
544
+ borderRadius: "50%",
545
+ filter: "drop-shadow(0 0 8px rgba(250, 204, 21, 0.7))",
546
+ padding: "13px 18px",
547
+ letterSpacing: "0.05em",
548
+ textShadow: "2px 2px 0 #000000, -1px -1px 0 #000000",
549
+ textTransform: "uppercase",
550
+ arrowSize: "11px",
551
+ arrowWidth: "21px",
552
+ animation: animations.zoom
553
+ }),
554
+ hazard: createTheme({
555
+ background: "repeating-linear-gradient(135deg, #f97316 0, #f97316 10px, #18181b 10px, #18181b 20px)",
556
+ color: "#ffffff",
557
+ fontFamily: "Arial Black, Impact, sans-serif",
558
+ fontSize: "12px",
559
+ fontWeight: 900,
560
+ border: "3px solid #18181b",
561
+ borderRadius: "4px",
562
+ filter: "drop-shadow(5px 5px 0 rgba(24, 24, 27, 0.6))",
563
+ padding: "9px 15px",
564
+ textShadow: "2px 2px 0 #18181b, -1px -1px 0 #18181b",
565
+ textTransform: "uppercase",
566
+ arrowSize: "10px",
567
+ arrowWidth: "20px",
568
+ animation: animations.snap
569
+ }),
570
+ policeTape: createTheme({
571
+ background: "repeating-linear-gradient(135deg, #f8fafc 0, #f8fafc 11px, #2563eb 11px, #2563eb 22px)",
572
+ color: "#172554",
573
+ fontFamily: "Arial Narrow, Arial, sans-serif",
574
+ fontSize: "12px",
575
+ fontWeight: 900,
576
+ border: "3px solid #1e3a8a",
577
+ borderRadius: "1px",
578
+ filter: "drop-shadow(4px 5px 0 rgba(30, 58, 138, 0.42))",
579
+ padding: "8px 15px",
580
+ letterSpacing: "0.1em",
581
+ textShadow: "1px 1px 0 #ffffff, -1px -1px 0 #ffffff",
582
+ textTransform: "uppercase",
583
+ arrowSize: "9px",
584
+ arrowWidth: "20px",
585
+ animation: animations.slide
586
+ }),
587
+ construction: createTheme({
588
+ background: "repeating-linear-gradient(90deg, rgba(255, 255, 255, 0.045) 0, rgba(255, 255, 255, 0.045) 1px, transparent 1px, transparent 7px), linear-gradient(135deg, #52525b, #27272a)",
589
+ color: "#fed7aa",
590
+ fontFamily: "DIN Condensed, Arial Narrow, sans-serif",
591
+ fontSize: "12px",
592
+ fontWeight: 800,
593
+ border: "3px dashed #f97316",
594
+ borderRadius: "3px",
595
+ filter: "drop-shadow(5px 6px 0 rgba(24, 24, 27, 0.52))",
596
+ padding: "9px 15px",
597
+ letterSpacing: "0.07em",
598
+ textTransform: "uppercase",
599
+ arrowSize: "10px",
600
+ arrowWidth: "20px",
601
+ animation: animations.flip
602
+ }),
603
+ parchment: createTheme({
604
+ background: "radial-gradient(circle at 12% 20%, rgba(120, 83, 36, 0.12), transparent 20%), radial-gradient(circle at 82% 70%, rgba(120, 83, 36, 0.16), transparent 25%), linear-gradient(135deg, #f5deb3, #e7c78e)",
605
+ color: "#5b3716",
606
+ fontFamily: "Garamond, Georgia, serif",
607
+ fontSize: "14px",
608
+ fontWeight: 600,
609
+ border: "2px solid #9a6b32",
610
+ borderRadius: "14px 3px 12px 5px",
611
+ filter: "drop-shadow(4px 6px 5px rgba(91, 55, 22, 0.3))",
612
+ padding: "10px 16px",
613
+ textAlign: "left",
614
+ arrowSize: "9px",
615
+ arrowWidth: "20px",
616
+ animation: animations.soft
617
+ }),
618
+ pirateMap: createTheme({
619
+ background: "radial-gradient(circle at 75% 25%, transparent 0 6px, rgba(127, 29, 29, 0.55) 7px 8px, transparent 9px), repeating-radial-gradient(circle at 15% 85%, rgba(120, 83, 36, 0.08) 0 2px, transparent 2px 9px), #e7c78e",
620
+ color: "#422006",
621
+ fontFamily: "Papyrus, Harrington, Georgia, serif",
622
+ fontSize: "13px",
623
+ fontWeight: 700,
624
+ border: "2px dashed #78350f",
625
+ borderRadius: "5px 17px 7px 12px",
626
+ filter: "drop-shadow(4px 7px 5px rgba(66, 32, 6, 0.36))",
627
+ padding: "10px 16px",
628
+ letterSpacing: "0.025em",
629
+ textAlign: "left",
630
+ arrowSize: "10px",
631
+ arrowWidth: "19px",
632
+ animation: animations.flip
633
+ }),
634
+ royal: createTheme({
635
+ background: "radial-gradient(circle at 50% -20%, rgba(250, 204, 21, 0.5), transparent 46%), linear-gradient(135deg, #581c87, #2e1065)",
636
+ color: "#fef3c7",
637
+ fontFamily: "Palatino Linotype, Book Antiqua, serif",
638
+ fontSize: "13px",
639
+ fontWeight: 700,
640
+ border: "2px solid #facc15",
641
+ borderRadius: "6px 20px 6px 20px",
642
+ filter: "drop-shadow(0 8px 14px rgba(46, 16, 101, 0.55)) drop-shadow(0 0 5px rgba(250, 204, 21, 0.4))",
643
+ padding: "10px 17px",
644
+ letterSpacing: "0.05em",
645
+ textShadow: "0 1px 2px rgba(0, 0, 0, 0.7)",
646
+ arrowSize: "10px",
647
+ arrowWidth: "21px",
648
+ animation: animations.flip,
649
+ style: {
650
+ fontVariantCaps: "small-caps"
651
+ }
652
+ }),
653
+ noir: createTheme({
654
+ background: "linear-gradient(115deg, #000000 0%, #27272a 48%, #09090b 52%, #000000 100%)",
655
+ color: "#ffffff",
656
+ fontFamily: "Helvetica Neue, Arial, sans-serif",
657
+ fontSize: "12px",
658
+ fontWeight: 700,
659
+ border: "1px solid #a1a1aa",
660
+ borderRadius: "0px",
661
+ filter: "drop-shadow(7px 9px 0 rgba(0, 0, 0, 0.6))",
662
+ padding: "9px 15px",
663
+ letterSpacing: "0.12em",
664
+ textTransform: "uppercase",
665
+ arrowSize: "9px",
666
+ arrowWidth: "16px",
667
+ animation: animations.soft
668
+ }),
669
+ detective: createTheme({
670
+ background: "repeating-linear-gradient(0deg, rgba(68, 64, 60, 0.05) 0, rgba(68, 64, 60, 0.05) 1px, transparent 1px, transparent 5px), #d6c29f",
671
+ color: "#292524",
672
+ fontFamily: "Courier New, monospace",
673
+ fontSize: "12px",
674
+ fontWeight: 700,
675
+ border: "2px solid #57534e",
676
+ borderRadius: "2px",
677
+ filter: "drop-shadow(5px 7px 0 rgba(68, 64, 60, 0.34))",
678
+ padding: "10px 15px",
679
+ letterSpacing: "0.04em",
680
+ textAlign: "left",
681
+ arrowSize: "8px",
682
+ arrowWidth: "17px",
683
+ animation: animations.slide
684
+ }),
685
+ dossier: createTheme({
686
+ background: "linear-gradient(90deg, rgba(127, 29, 29, 0.15) 0 4px, transparent 4px), repeating-linear-gradient(0deg, transparent 0 14px, rgba(120, 83, 36, 0.13) 14px 15px), #e7d7b5",
687
+ color: "#3f2d1d",
688
+ fontFamily: "Courier New, monospace",
689
+ fontSize: "11px",
690
+ fontWeight: 800,
691
+ border: "2px solid #92400e",
692
+ borderRadius: "1px 8px 1px 8px",
693
+ filter: "drop-shadow(5px 7px 0 rgba(120, 53, 15, 0.35))",
694
+ padding: "11px 16px",
695
+ letterSpacing: "0.08em",
696
+ textTransform: "uppercase",
697
+ textAlign: "left",
698
+ arrowSize: "8px",
699
+ arrowWidth: "17px",
700
+ animation: animations.snap
701
+ }),
702
+ medical: createTheme({
703
+ background: "linear-gradient(90deg, transparent 44%, rgba(14, 165, 233, 0.08) 44% 56%, transparent 56%), linear-gradient(0deg, transparent 44%, rgba(14, 165, 233, 0.08) 44% 56%, transparent 56%), #f8fafc",
704
+ color: "#075985",
705
+ fontFamily: "Arial, Helvetica, sans-serif",
706
+ fontSize: "12px",
707
+ fontWeight: 700,
708
+ border: "2px solid #38bdf8",
709
+ borderRadius: "10px",
710
+ filter: "drop-shadow(0 8px 12px rgba(14, 165, 233, 0.2))",
711
+ padding: "9px 15px",
712
+ arrowSize: "8px",
713
+ arrowWidth: "18px",
714
+ animation: animations.soft
715
+ }),
716
+ laboratory: createTheme({
717
+ background: "linear-gradient(rgba(34, 211, 238, 0.09) 1px, transparent 1px), linear-gradient(90deg, rgba(34, 211, 238, 0.09) 1px, transparent 1px), linear-gradient(135deg, #082f49, #0f172a)",
718
+ color: "#a5f3fc",
719
+ fontFamily: "Roboto Mono, Consolas, monospace",
720
+ fontSize: "11px",
721
+ fontWeight: 600,
722
+ border: "1px solid #22d3ee",
723
+ borderRadius: "7px",
724
+ filter: "drop-shadow(0 0 7px rgba(34, 211, 238, 0.45))",
725
+ padding: "9px 14px",
726
+ letterSpacing: "0.04em",
727
+ textAlign: "left",
728
+ arrowSize: "8px",
729
+ arrowWidth: "16px",
730
+ animation: animations.blur,
731
+ style: {
732
+ backgroundSize: "10px 10px"
733
+ }
734
+ }),
735
+ circuit: createTheme({
736
+ background: "linear-gradient(90deg, transparent 48%, rgba(34, 197, 94, 0.2) 48% 52%, transparent 52%) 0 0 / 18px 18px, linear-gradient(0deg, transparent 48%, rgba(34, 197, 94, 0.2) 48% 52%, transparent 52%) 0 0 / 18px 18px, radial-gradient(circle at 9px 9px, #22c55e 0 1.5px, transparent 2px) 0 0 / 18px 18px, #052e16",
737
+ color: "#bbf7d0",
738
+ fontFamily: "Consolas, monospace",
739
+ fontSize: "11px",
740
+ fontWeight: 700,
741
+ border: "2px solid #22c55e",
742
+ borderRadius: "5px",
743
+ filter: "drop-shadow(0 0 7px rgba(34, 197, 94, 0.55))",
744
+ padding: "9px 14px",
745
+ letterSpacing: "0.05em",
746
+ textShadow: "0 0 4px rgba(34, 197, 94, 0.75)",
747
+ arrowSize: "8px",
748
+ arrowWidth: "16px",
749
+ animation: animations.snap
750
+ }),
751
+ galaxy: createTheme({
752
+ background: "radial-gradient(circle at 12% 25%, #ffffff 0 1px, transparent 1.5px), radial-gradient(circle at 76% 18%, #c4b5fd 0 1px, transparent 1.5px), radial-gradient(circle at 63% 78%, #ffffff 0 1.2px, transparent 1.8px), radial-gradient(circle at 28% 72%, rgba(236, 72, 153, 0.55), transparent 22%), radial-gradient(circle at 70% 20%, rgba(99, 102, 241, 0.55), transparent 32%), #09051f",
753
+ color: "#f5f3ff",
754
+ fontFamily: "Trebuchet MS, sans-serif",
755
+ fontSize: "12px",
756
+ fontWeight: 600,
757
+ border: "1px solid #8b5cf6",
758
+ borderRadius: "18px",
759
+ filter: "drop-shadow(0 0 9px rgba(139, 92, 246, 0.62)) drop-shadow(0 9px 16px rgba(9, 5, 31, 0.6))",
760
+ padding: "10px 16px",
761
+ textShadow: "0 0 5px rgba(196, 181, 253, 0.8)",
762
+ arrowSize: "9px",
763
+ arrowWidth: "20px",
764
+ animation: animations.blur
765
+ }),
766
+ aurora: createTheme({
767
+ background: "radial-gradient(ellipse at 15% 0%, rgba(45, 212, 191, 0.85), transparent 45%), radial-gradient(ellipse at 90% 100%, rgba(217, 70, 239, 0.72), transparent 50%), linear-gradient(135deg, #0f172a, #312e81)",
768
+ color: "#f0fdfa",
769
+ fontFamily: "Segoe UI, Arial, sans-serif",
770
+ fontSize: "12px",
771
+ fontWeight: 600,
772
+ border: "1px solid rgba(153, 246, 228, 0.6)",
773
+ borderRadius: "20px 8px 20px 8px",
774
+ filter: "drop-shadow(0 10px 17px rgba(49, 46, 129, 0.48))",
775
+ padding: "10px 16px",
776
+ backdropFilter: "blur(8px)",
777
+ arrowSize: "9px",
778
+ arrowWidth: "21px",
779
+ animation: animations.blur
780
+ }),
781
+ oceanDepths: createTheme({
782
+ background: "radial-gradient(circle at 20% 10%, rgba(34, 211, 238, 0.32), transparent 32%), radial-gradient(circle at 80% 90%, rgba(14, 116, 144, 0.42), transparent 36%), linear-gradient(160deg, #083344, #020617)",
783
+ color: "#cffafe",
784
+ fontFamily: "Trebuchet MS, sans-serif",
785
+ fontSize: "12px",
786
+ fontWeight: 600,
787
+ border: "1px solid #0e7490",
788
+ borderRadius: "4px 20px 4px 20px",
789
+ filter: "drop-shadow(0 10px 16px rgba(2, 6, 23, 0.56)) drop-shadow(0 0 6px rgba(34, 211, 238, 0.3))",
790
+ padding: "10px 16px",
791
+ arrowSize: "10px",
792
+ arrowWidth: "19px",
793
+ animation: animations.slide
794
+ }),
795
+ coralReef: createTheme({
796
+ background: "radial-gradient(circle at 15% 100%, rgba(251, 113, 133, 0.75), transparent 30%), radial-gradient(circle at 90% 0%, rgba(45, 212, 191, 0.72), transparent 34%), linear-gradient(135deg, #0e7490, #155e75)",
797
+ color: "#fff7ed",
798
+ fontFamily: "Trebuchet MS, sans-serif",
799
+ fontSize: "12px",
800
+ fontWeight: 700,
801
+ border: "2px solid #fdba74",
802
+ borderRadius: "18px 8px 14px 5px",
803
+ filter: "drop-shadow(0 9px 14px rgba(14, 116, 144, 0.4))",
804
+ padding: "9px 16px",
805
+ textShadow: "0 1px 2px rgba(12, 74, 110, 0.8)",
806
+ arrowSize: "9px",
807
+ arrowWidth: "21px",
808
+ animation: animations.bounce
809
+ }),
810
+ forest: createTheme({
811
+ background: "radial-gradient(ellipse at 20% 20%, rgba(74, 222, 128, 0.18), transparent 30%), repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.025) 0 2px, transparent 2px 7px), linear-gradient(135deg, #14532d, #052e16)",
812
+ color: "#dcfce7",
813
+ fontFamily: "Georgia, serif",
814
+ fontSize: "13px",
815
+ fontWeight: 600,
816
+ border: "2px solid #4d7c0f",
817
+ borderRadius: "13px 4px 17px 6px",
818
+ filter: "drop-shadow(0 9px 14px rgba(5, 46, 22, 0.5))",
819
+ padding: "9px 16px",
820
+ arrowSize: "9px",
821
+ arrowWidth: "19px",
822
+ animation: animations.slide
823
+ }),
824
+ moss: createTheme({
825
+ background: "radial-gradient(circle at 20% 30%, rgba(190, 242, 100, 0.16) 0 3px, transparent 4px), radial-gradient(circle at 72% 65%, rgba(132, 204, 22, 0.14) 0 4px, transparent 5px), linear-gradient(135deg, #3f6212, #1a2e05)",
826
+ color: "#ecfccb",
827
+ fontFamily: "Palatino Linotype, serif",
828
+ fontSize: "13px",
829
+ fontWeight: 600,
830
+ border: "2px dotted #84cc16",
831
+ borderRadius: "18px 7px 14px 10px",
832
+ filter: "drop-shadow(0 8px 13px rgba(26, 46, 5, 0.5))",
833
+ padding: "10px 16px",
834
+ arrowSize: "9px",
835
+ arrowWidth: "20px",
836
+ animation: animations.blur
837
+ }),
838
+ desert: createTheme({
839
+ background: "radial-gradient(ellipse at 20% 120%, #f59e0b 0 35%, transparent 36%), radial-gradient(ellipse at 85% 110%, #d97706 0 40%, transparent 41%), linear-gradient(180deg, #fde68a, #fbbf24)",
840
+ color: "#78350f",
841
+ fontFamily: "Georgia, serif",
842
+ fontSize: "13px",
843
+ fontWeight: 700,
844
+ border: "2px solid #b45309",
845
+ borderRadius: "22px 22px 7px 7px",
846
+ filter: "drop-shadow(0 9px 13px rgba(180, 83, 9, 0.32))",
847
+ padding: "10px 16px",
848
+ arrowSize: "9px",
849
+ arrowWidth: "21px",
850
+ animation: animations.soft
851
+ }),
852
+ snow: createTheme({
853
+ background: "radial-gradient(circle at 15% 25%, #ffffff 0 2px, transparent 2.5px), radial-gradient(circle at 75% 65%, #ffffff 0 1.5px, transparent 2px), linear-gradient(135deg, #e0f2fe, #bae6fd)",
854
+ color: "#0c4a6e",
855
+ fontFamily: "Helvetica Neue, Arial, sans-serif",
856
+ fontSize: "12px",
857
+ fontWeight: 600,
858
+ border: "2px solid #ffffff",
859
+ borderRadius: "20px",
860
+ filter: "drop-shadow(0 8px 13px rgba(14, 116, 144, 0.22))",
861
+ padding: "10px 16px",
862
+ textShadow: "0 1px 0 rgba(255, 255, 255, 0.9)",
863
+ arrowSize: "9px",
864
+ arrowWidth: "20px",
865
+ animation: animations.blur
866
+ }),
867
+ chrome: createTheme({
868
+ background: "linear-gradient(180deg, #ffffff 0%, #a1a1aa 18%, #f4f4f5 38%, #52525b 52%, #d4d4d8 72%, #71717a 100%)",
869
+ color: "#18181b",
870
+ fontFamily: "Arial Black, sans-serif",
871
+ fontSize: "12px",
872
+ fontWeight: 900,
873
+ border: "2px solid #27272a",
874
+ borderRadius: "10px",
875
+ filter: "drop-shadow(0 8px 12px rgba(24, 24, 27, 0.45))",
876
+ padding: "9px 16px",
877
+ letterSpacing: "0.04em",
878
+ textShadow: "0 1px 0 #ffffff",
879
+ textTransform: "uppercase",
880
+ arrowSize: "9px",
881
+ arrowWidth: "20px",
882
+ animation: animations.flip
883
+ }),
884
+ goldFoil: createTheme({
885
+ background: "linear-gradient(115deg, #713f12 0%, #facc15 18%, #fef08a 32%, #ca8a04 52%, #fef9c3 70%, #a16207 100%)",
886
+ color: "#422006",
887
+ fontFamily: "Palatino Linotype, serif",
888
+ fontSize: "13px",
889
+ fontWeight: 800,
890
+ border: "2px solid #713f12",
891
+ borderRadius: "5px 16px 5px 16px",
892
+ filter: "drop-shadow(0 9px 14px rgba(113, 63, 18, 0.45))",
893
+ padding: "10px 17px",
894
+ letterSpacing: "0.04em",
895
+ textShadow: "0 1px 0 rgba(255, 255, 255, 0.55)",
896
+ arrowSize: "10px",
897
+ arrowWidth: "21px",
898
+ animation: animations.flip,
899
+ style: {
900
+ fontVariantCaps: "small-caps"
901
+ }
902
+ }),
903
+ bronze: createTheme({
904
+ background: "repeating-linear-gradient(115deg, rgba(255, 255, 255, 0.08) 0 1px, transparent 1px 5px), linear-gradient(135deg, #d97706, #78350f)",
905
+ color: "#ffedd5",
906
+ fontFamily: "Georgia, serif",
907
+ fontSize: "13px",
908
+ fontWeight: 700,
909
+ border: "2px solid #fdba74",
910
+ borderRadius: "8px",
911
+ filter: "drop-shadow(0 9px 14px rgba(120, 53, 15, 0.5))",
912
+ padding: "9px 16px",
913
+ textShadow: "0 1px 2px rgba(66, 32, 6, 0.8)",
914
+ arrowSize: "9px",
915
+ arrowWidth: "19px",
916
+ animation: animations.pop
917
+ }),
918
+ brutalist: createTheme({
919
+ background: "#ffffff",
920
+ color: "#000000",
921
+ fontFamily: "Arial Black, Helvetica, sans-serif",
922
+ fontSize: "12px",
923
+ fontWeight: 900,
924
+ border: "4px solid #000000",
925
+ borderRadius: "0px",
926
+ filter: "drop-shadow(7px 7px 0 #ef4444)",
927
+ padding: "10px 16px",
928
+ letterSpacing: "-0.03em",
929
+ textTransform: "uppercase",
930
+ textAlign: "left",
931
+ arrowSize: "11px",
932
+ arrowWidth: "19px",
933
+ animation: animations.snap
934
+ }),
935
+ chalkboard: createTheme({
936
+ background: "repeating-linear-gradient(175deg, rgba(255, 255, 255, 0.018) 0, rgba(255, 255, 255, 0.018) 2px, transparent 2px, transparent 7px), #163a2c",
937
+ color: "#f5f5dc",
938
+ fontFamily: "Comic Sans MS, Chalkboard, cursive",
939
+ fontSize: "13px",
940
+ fontWeight: 600,
941
+ border: "3px solid #8b5e3c",
942
+ borderRadius: "2px",
943
+ filter: "drop-shadow(4px 6px 0 rgba(66, 32, 6, 0.45))",
944
+ padding: "10px 16px",
945
+ letterSpacing: "0.025em",
946
+ textShadow: "0 0 2px rgba(255, 255, 255, 0.55)",
947
+ textAlign: "left",
948
+ arrowSize: "9px",
949
+ arrowWidth: "18px",
950
+ animation: animations.soft
951
+ })
952
+ };
953
+ var presetThemeNames = Object.keys(presets);
954
+
955
+ // src/hooks/useTooltip.ts
956
+ var import_react = require("react");
957
+ var DEFAULT_HIDE_DELAY = 120;
958
+ var DEFAULT_INTERACTIVE_HIDE_DELAY = 240;
959
+ var VIEWPORT_PADDING = 8;
960
+ var DEFAULT_ARROW_SIZE = 6;
961
+ var DEFAULT_TOOLTIP_GAP = 10;
962
+ var ARROW_EDGE_OFFSET = 10;
963
+ var oppositePlacement = {
964
+ top: "bottom",
965
+ bottom: "top",
966
+ left: "right",
967
+ right: "left"
968
+ };
969
+ var clamp = (value, min, max) => {
970
+ const resolvedMax = Math.max(min, max);
971
+ return Math.min(Math.max(value, min), resolvedMax);
972
+ };
973
+ var useTooltip = ({
974
+ anchor,
975
+ preferredPlacement,
976
+ disabled = false,
977
+ interactive = false,
978
+ hideDelay
979
+ }) => {
980
+ const tooltipRef = (0, import_react.useRef)(null);
981
+ const bodyRef = (0, import_react.useRef)(null);
982
+ const hideTimerRef = (0, import_react.useRef)(null);
983
+ const firstFrameRef = (0, import_react.useRef)(null);
984
+ const secondFrameRef = (0, import_react.useRef)(null);
985
+ const phaseRef = (0, import_react.useRef)("hidden");
986
+ const pendingHideRef = (0, import_react.useRef)(false);
987
+ const [mounted, setMounted] = (0, import_react.useState)(false);
988
+ const [phase, setPhase] = (0, import_react.useState)("hidden");
989
+ const [placement, setPlacement] = (0, import_react.useState)(preferredPlacement);
990
+ const [showVersion, setShowVersion] = (0, import_react.useState)(0);
991
+ const [position, setPosition] = (0, import_react.useState)({
992
+ top: "0px",
993
+ left: "0px",
994
+ "--tooltip-arrow-offset": "50%"
995
+ });
996
+ const resolvedHideDelay = hideDelay ?? (interactive ? DEFAULT_INTERACTIVE_HIDE_DELAY : DEFAULT_HIDE_DELAY);
997
+ const updatePhase = (0, import_react.useCallback)((nextPhase) => {
998
+ phaseRef.current = nextPhase;
999
+ setPhase(nextPhase);
1000
+ }, []);
1001
+ const clearHideTimer = (0, import_react.useCallback)(() => {
1002
+ if (hideTimerRef.current === null) {
1003
+ return;
1004
+ }
1005
+ window.clearTimeout(hideTimerRef.current);
1006
+ hideTimerRef.current = null;
1007
+ }, []);
1008
+ const clearEnterFrames = (0, import_react.useCallback)(() => {
1009
+ if (firstFrameRef.current !== null) {
1010
+ window.cancelAnimationFrame(firstFrameRef.current);
1011
+ firstFrameRef.current = null;
1012
+ }
1013
+ if (secondFrameRef.current !== null) {
1014
+ window.cancelAnimationFrame(secondFrameRef.current);
1015
+ secondFrameRef.current = null;
1016
+ }
1017
+ }, []);
1018
+ const getAvailableSpace = (0, import_react.useCallback)(
1019
+ (currentPlacement, rect) => {
1020
+ switch (currentPlacement) {
1021
+ case "top":
1022
+ return rect.top - VIEWPORT_PADDING;
1023
+ case "bottom":
1024
+ return window.innerHeight - rect.bottom - VIEWPORT_PADDING;
1025
+ case "left":
1026
+ return rect.left - VIEWPORT_PADDING;
1027
+ case "right":
1028
+ return window.innerWidth - rect.right - VIEWPORT_PADDING;
1029
+ }
1030
+ },
1031
+ []
1032
+ );
1033
+ const calculatePosition = (0, import_react.useCallback)(() => {
1034
+ const tooltip = tooltipRef.current;
1035
+ const body = bodyRef.current;
1036
+ if (!anchor || !tooltip || !body) {
1037
+ return;
1038
+ }
1039
+ const rect = anchor.getBoundingClientRect();
1040
+ const computedStyle = window.getComputedStyle(tooltip);
1041
+ const arrowSize = Number.parseFloat(
1042
+ computedStyle.getPropertyValue("--tooltip-arrow-size")
1043
+ ) || DEFAULT_ARROW_SIZE;
1044
+ const tooltipGap = Number.parseFloat(
1045
+ computedStyle.getPropertyValue("--tooltip-gap")
1046
+ ) || DEFAULT_TOOLTIP_GAP;
1047
+ const bodyWidth = body.offsetWidth;
1048
+ const bodyHeight = body.offsetHeight;
1049
+ const distance = arrowSize + tooltipGap;
1050
+ const opposite = oppositePlacement[preferredPlacement];
1051
+ const getRequiredSpace = (currentPlacement) => {
1052
+ if (currentPlacement === "top" || currentPlacement === "bottom") {
1053
+ return bodyHeight + distance;
1054
+ }
1055
+ return bodyWidth + distance;
1056
+ };
1057
+ const preferredAvailable = getAvailableSpace(
1058
+ preferredPlacement,
1059
+ rect
1060
+ );
1061
+ const preferredRequired = getRequiredSpace(preferredPlacement);
1062
+ let nextPlacement = preferredPlacement;
1063
+ if (preferredAvailable < preferredRequired) {
1064
+ const oppositeAvailable = getAvailableSpace(opposite, rect);
1065
+ const oppositeRequired = getRequiredSpace(opposite);
1066
+ if (oppositeAvailable >= oppositeRequired || oppositeAvailable > preferredAvailable) {
1067
+ nextPlacement = opposite;
1068
+ }
1069
+ }
1070
+ const anchorCenterX = rect.left + rect.width / 2;
1071
+ const anchorCenterY = rect.top + rect.height / 2;
1072
+ let top = 0;
1073
+ let left = 0;
1074
+ let arrowOffset = "50%";
1075
+ if (nextPlacement === "top") {
1076
+ top = rect.top - bodyHeight - distance;
1077
+ left = anchorCenterX - bodyWidth / 2;
1078
+ }
1079
+ if (nextPlacement === "bottom") {
1080
+ top = rect.bottom + distance;
1081
+ left = anchorCenterX - bodyWidth / 2;
1082
+ }
1083
+ if (nextPlacement === "left") {
1084
+ top = anchorCenterY - bodyHeight / 2;
1085
+ left = rect.left - bodyWidth - distance;
1086
+ }
1087
+ if (nextPlacement === "right") {
1088
+ top = anchorCenterY - bodyHeight / 2;
1089
+ left = rect.right + distance;
1090
+ }
1091
+ const maxLeft = window.innerWidth - bodyWidth - VIEWPORT_PADDING;
1092
+ const maxTop = window.innerHeight - bodyHeight - VIEWPORT_PADDING;
1093
+ left = clamp(left, VIEWPORT_PADDING, maxLeft);
1094
+ top = clamp(top, VIEWPORT_PADDING, maxTop);
1095
+ if (nextPlacement === "top" || nextPlacement === "bottom") {
1096
+ const offset = clamp(
1097
+ anchorCenterX - left,
1098
+ ARROW_EDGE_OFFSET,
1099
+ bodyWidth - ARROW_EDGE_OFFSET
1100
+ );
1101
+ arrowOffset = `${offset}px`;
1102
+ }
1103
+ if (nextPlacement === "left" || nextPlacement === "right") {
1104
+ const offset = clamp(
1105
+ anchorCenterY - top,
1106
+ ARROW_EDGE_OFFSET,
1107
+ bodyHeight - ARROW_EDGE_OFFSET
1108
+ );
1109
+ arrowOffset = `${offset}px`;
1110
+ }
1111
+ setPlacement(nextPlacement);
1112
+ setPosition({
1113
+ top: `${top}px`,
1114
+ left: `${left}px`,
1115
+ "--tooltip-arrow-offset": arrowOffset
1116
+ });
1117
+ }, [anchor, getAvailableSpace, preferredPlacement]);
1118
+ const removeTooltip = (0, import_react.useCallback)(() => {
1119
+ clearHideTimer();
1120
+ clearEnterFrames();
1121
+ pendingHideRef.current = false;
1122
+ updatePhase("hidden");
1123
+ }, [clearEnterFrames, clearHideTimer, updatePhase]);
1124
+ const runHide = (0, import_react.useCallback)(() => {
1125
+ const currentPhase = phaseRef.current;
1126
+ if (currentPhase === "hidden" || currentPhase === "leaving") {
1127
+ return;
1128
+ }
1129
+ if (currentPhase === "preparing") {
1130
+ removeTooltip();
1131
+ return;
1132
+ }
1133
+ if (currentPhase === "entering") {
1134
+ pendingHideRef.current = true;
1135
+ return;
1136
+ }
1137
+ updatePhase("leaving");
1138
+ }, [removeTooltip, updatePhase]);
1139
+ const hideTooltip = (0, import_react.useCallback)(
1140
+ (immediate = false) => {
1141
+ clearHideTimer();
1142
+ if (immediate) {
1143
+ runHide();
1144
+ return;
1145
+ }
1146
+ hideTimerRef.current = window.setTimeout(() => {
1147
+ hideTimerRef.current = null;
1148
+ runHide();
1149
+ }, resolvedHideDelay);
1150
+ },
1151
+ [clearHideTimer, resolvedHideDelay, runHide]
1152
+ );
1153
+ const showTooltip = (0, import_react.useCallback)(() => {
1154
+ if (!anchor || disabled) {
1155
+ return;
1156
+ }
1157
+ clearHideTimer();
1158
+ clearEnterFrames();
1159
+ pendingHideRef.current = false;
1160
+ setMounted(true);
1161
+ if (phaseRef.current === "entering" || phaseRef.current === "visible") {
1162
+ return;
1163
+ }
1164
+ updatePhase("preparing");
1165
+ setShowVersion((value) => value + 1);
1166
+ }, [anchor, clearEnterFrames, clearHideTimer, disabled, updatePhase]);
1167
+ const keepTooltipOpen = (0, import_react.useCallback)(() => {
1168
+ if (!interactive || disabled) {
1169
+ return;
1170
+ }
1171
+ clearHideTimer();
1172
+ pendingHideRef.current = false;
1173
+ if (phaseRef.current === "leaving") {
1174
+ updatePhase("visible");
1175
+ }
1176
+ }, [clearHideTimer, disabled, interactive, updatePhase]);
1177
+ const onAnimationEnd = (0, import_react.useCallback)(() => {
1178
+ const currentPhase = phaseRef.current;
1179
+ if (currentPhase === "entering") {
1180
+ if (pendingHideRef.current) {
1181
+ pendingHideRef.current = false;
1182
+ updatePhase("leaving");
1183
+ return;
1184
+ }
1185
+ updatePhase("visible");
1186
+ return;
1187
+ }
1188
+ if (currentPhase === "leaving") {
1189
+ removeTooltip();
1190
+ }
1191
+ }, [removeTooltip, updatePhase]);
1192
+ (0, import_react.useLayoutEffect)(() => {
1193
+ if (phase !== "preparing" || !anchor) {
1194
+ return;
1195
+ }
1196
+ calculatePosition();
1197
+ firstFrameRef.current = window.requestAnimationFrame(() => {
1198
+ firstFrameRef.current = null;
1199
+ secondFrameRef.current = window.requestAnimationFrame(() => {
1200
+ secondFrameRef.current = null;
1201
+ if (!anchor || phaseRef.current !== "preparing") {
1202
+ return;
1203
+ }
1204
+ updatePhase("entering");
1205
+ });
1206
+ });
1207
+ return clearEnterFrames;
1208
+ }, [
1209
+ anchor,
1210
+ calculatePosition,
1211
+ clearEnterFrames,
1212
+ phase,
1213
+ showVersion,
1214
+ updatePhase
1215
+ ]);
1216
+ (0, import_react.useEffect)(() => {
1217
+ if (!anchor) {
1218
+ removeTooltip();
1219
+ return;
1220
+ }
1221
+ const onPointerEnter = (event) => {
1222
+ if (event.pointerType === "touch") {
1223
+ return;
1224
+ }
1225
+ showTooltip();
1226
+ };
1227
+ const onPointerLeave = (event) => {
1228
+ if (event.pointerType === "touch") {
1229
+ return;
1230
+ }
1231
+ const relatedTarget = event.relatedTarget;
1232
+ const tooltip = tooltipRef.current;
1233
+ if (interactive && relatedTarget instanceof Node && tooltip?.contains(relatedTarget)) {
1234
+ keepTooltipOpen();
1235
+ return;
1236
+ }
1237
+ hideTooltip(false);
1238
+ };
1239
+ const onPointerDown = (event) => {
1240
+ if (event.pointerType !== "touch") {
1241
+ return;
1242
+ }
1243
+ if (phaseRef.current === "hidden" || phaseRef.current === "leaving") {
1244
+ showTooltip();
1245
+ } else {
1246
+ hideTooltip(true);
1247
+ }
1248
+ };
1249
+ const onFocusIn = () => {
1250
+ showTooltip();
1251
+ };
1252
+ const onFocusOut = (event) => {
1253
+ const relatedTarget = event.relatedTarget;
1254
+ const tooltip = tooltipRef.current;
1255
+ if (relatedTarget instanceof Node && (anchor.contains(relatedTarget) || interactive && tooltip?.contains(relatedTarget))) {
1256
+ return;
1257
+ }
1258
+ hideTooltip(false);
1259
+ };
1260
+ anchor.addEventListener("pointerenter", onPointerEnter);
1261
+ anchor.addEventListener("pointerleave", onPointerLeave);
1262
+ anchor.addEventListener("pointerdown", onPointerDown);
1263
+ anchor.addEventListener("focusin", onFocusIn);
1264
+ anchor.addEventListener("focusout", onFocusOut);
1265
+ return () => {
1266
+ anchor.removeEventListener("pointerenter", onPointerEnter);
1267
+ anchor.removeEventListener("pointerleave", onPointerLeave);
1268
+ anchor.removeEventListener("pointerdown", onPointerDown);
1269
+ anchor.removeEventListener("focusin", onFocusIn);
1270
+ anchor.removeEventListener("focusout", onFocusOut);
1271
+ clearHideTimer();
1272
+ clearEnterFrames();
1273
+ };
1274
+ }, [
1275
+ anchor,
1276
+ clearEnterFrames,
1277
+ clearHideTimer,
1278
+ hideTooltip,
1279
+ interactive,
1280
+ keepTooltipOpen,
1281
+ removeTooltip,
1282
+ showTooltip
1283
+ ]);
1284
+ (0, import_react.useEffect)(() => {
1285
+ if (!interactive || !mounted) {
1286
+ return;
1287
+ }
1288
+ const tooltip = tooltipRef.current;
1289
+ if (!tooltip) {
1290
+ return;
1291
+ }
1292
+ const onPointerEnter = (event) => {
1293
+ if (event.pointerType === "touch") {
1294
+ return;
1295
+ }
1296
+ keepTooltipOpen();
1297
+ };
1298
+ const onPointerLeave = (event) => {
1299
+ if (event.pointerType === "touch") {
1300
+ return;
1301
+ }
1302
+ const relatedTarget = event.relatedTarget;
1303
+ if (relatedTarget instanceof Node && anchor?.contains(relatedTarget)) {
1304
+ keepTooltipOpen();
1305
+ return;
1306
+ }
1307
+ hideTooltip(false);
1308
+ };
1309
+ const onFocusIn = () => {
1310
+ keepTooltipOpen();
1311
+ };
1312
+ const onFocusOut = (event) => {
1313
+ const relatedTarget = event.relatedTarget;
1314
+ if (relatedTarget instanceof Node && (tooltip.contains(relatedTarget) || anchor?.contains(relatedTarget))) {
1315
+ return;
1316
+ }
1317
+ hideTooltip(false);
1318
+ };
1319
+ tooltip.addEventListener("pointerenter", onPointerEnter);
1320
+ tooltip.addEventListener("pointerleave", onPointerLeave);
1321
+ tooltip.addEventListener("focusin", onFocusIn);
1322
+ tooltip.addEventListener("focusout", onFocusOut);
1323
+ return () => {
1324
+ tooltip.removeEventListener("pointerenter", onPointerEnter);
1325
+ tooltip.removeEventListener("pointerleave", onPointerLeave);
1326
+ tooltip.removeEventListener("focusin", onFocusIn);
1327
+ tooltip.removeEventListener("focusout", onFocusOut);
1328
+ };
1329
+ }, [
1330
+ anchor,
1331
+ hideTooltip,
1332
+ interactive,
1333
+ keepTooltipOpen,
1334
+ mounted
1335
+ ]);
1336
+ (0, import_react.useEffect)(() => {
1337
+ if (!anchor || phase === "hidden") {
1338
+ return;
1339
+ }
1340
+ const onDocumentPointerDown = (event) => {
1341
+ const target = event.target;
1342
+ const tooltip = tooltipRef.current;
1343
+ if (target instanceof Node && (anchor.contains(target) || interactive && tooltip?.contains(target))) {
1344
+ return;
1345
+ }
1346
+ hideTooltip(true);
1347
+ };
1348
+ const onKeyDown = (event) => {
1349
+ if (event.key === "Escape") {
1350
+ hideTooltip(true);
1351
+ }
1352
+ };
1353
+ document.addEventListener(
1354
+ "pointerdown",
1355
+ onDocumentPointerDown,
1356
+ true
1357
+ );
1358
+ document.addEventListener("keydown", onKeyDown);
1359
+ window.addEventListener("resize", calculatePosition);
1360
+ window.addEventListener("scroll", calculatePosition, true);
1361
+ return () => {
1362
+ document.removeEventListener(
1363
+ "pointerdown",
1364
+ onDocumentPointerDown,
1365
+ true
1366
+ );
1367
+ document.removeEventListener("keydown", onKeyDown);
1368
+ window.removeEventListener("resize", calculatePosition);
1369
+ window.removeEventListener("scroll", calculatePosition, true);
1370
+ };
1371
+ }, [
1372
+ anchor,
1373
+ calculatePosition,
1374
+ hideTooltip,
1375
+ interactive,
1376
+ phase
1377
+ ]);
1378
+ (0, import_react.useLayoutEffect)(() => {
1379
+ if (phase === "hidden") {
1380
+ return;
1381
+ }
1382
+ const body = bodyRef.current;
1383
+ if (!body) {
1384
+ return;
1385
+ }
1386
+ const resizeObserver = new ResizeObserver(calculatePosition);
1387
+ resizeObserver.observe(body);
1388
+ return () => {
1389
+ resizeObserver.disconnect();
1390
+ };
1391
+ }, [calculatePosition, phase]);
1392
+ (0, import_react.useEffect)(() => {
1393
+ if (!disabled) {
1394
+ return;
1395
+ }
1396
+ hideTooltip(true);
1397
+ }, [disabled, hideTooltip]);
1398
+ return {
1399
+ shouldRender: mounted,
1400
+ phase,
1401
+ placement,
1402
+ position,
1403
+ tooltipRef,
1404
+ bodyRef,
1405
+ calculatePosition,
1406
+ onAnimationEnd
1407
+ };
1408
+ };
1409
+
1410
+ // src/utils/tooltipTheme.ts
1411
+ var BORDER_STYLE_VALUES = /* @__PURE__ */ new Set([
1412
+ "none",
1413
+ "hidden",
1414
+ "dotted",
1415
+ "dashed",
1416
+ "solid",
1417
+ "double",
1418
+ "groove",
1419
+ "ridge",
1420
+ "inset",
1421
+ "outset",
1422
+ "inherit",
1423
+ "initial",
1424
+ "revert",
1425
+ "revert-layer",
1426
+ "unset"
1427
+ ]);
1428
+ var splitCssTokens = (value) => {
1429
+ const tokens = [];
1430
+ let current = "";
1431
+ let depth = 0;
1432
+ for (const character of value.trim()) {
1433
+ if (character === "(") {
1434
+ depth += 1;
1435
+ }
1436
+ if (character === ")") {
1437
+ depth = Math.max(0, depth - 1);
1438
+ }
1439
+ if (/\s/.test(character) && depth === 0) {
1440
+ if (current.trim()) {
1441
+ tokens.push(current.trim());
1442
+ }
1443
+ current = "";
1444
+ continue;
1445
+ }
1446
+ current += character;
1447
+ }
1448
+ if (current.trim()) {
1449
+ tokens.push(current.trim());
1450
+ }
1451
+ return tokens;
1452
+ };
1453
+ var splitOutsideParentheses = (value, separator) => {
1454
+ const result = [];
1455
+ let current = "";
1456
+ let depth = 0;
1457
+ for (const character of value) {
1458
+ if (character === "(") {
1459
+ depth += 1;
1460
+ }
1461
+ if (character === ")") {
1462
+ depth = Math.max(0, depth - 1);
1463
+ }
1464
+ if (character === separator && depth === 0) {
1465
+ if (current.trim()) {
1466
+ result.push(current.trim());
1467
+ }
1468
+ current = "";
1469
+ continue;
1470
+ }
1471
+ current += character;
1472
+ }
1473
+ if (current.trim()) {
1474
+ result.push(current.trim());
1475
+ }
1476
+ return result;
1477
+ };
1478
+ var expandQuad = (values) => {
1479
+ if (values.length === 0) {
1480
+ return [void 0, void 0, void 0, void 0];
1481
+ }
1482
+ if (values.length === 1) {
1483
+ return [values[0], values[0], values[0], values[0]];
1484
+ }
1485
+ if (values.length === 2) {
1486
+ return [values[0], values[1], values[0], values[1]];
1487
+ }
1488
+ if (values.length === 3) {
1489
+ return [values[0], values[1], values[2], values[1]];
1490
+ }
1491
+ return [values[0], values[1], values[2], values[3]];
1492
+ };
1493
+ var isBorderWidthToken = (value) => {
1494
+ return value === "thin" || value === "medium" || value === "thick" || value === "0" || value === "inherit" || value === "initial" || value === "revert" || value === "revert-layer" || value === "unset" || /^-?(?:\d+|\d*\.\d+)(?:px|rem|em|vh|vw|vmin|vmax|%)?$/.test(value) || value.startsWith("calc(") || value.startsWith("var(");
1495
+ };
1496
+ var isBorderStyleToken = (value) => {
1497
+ return BORDER_STYLE_VALUES.has(value);
1498
+ };
1499
+ var parseBorder = (value) => {
1500
+ if (typeof value !== "string" || !value.trim()) {
1501
+ return {};
1502
+ }
1503
+ const tokens = splitCssTokens(value);
1504
+ const widthToken = tokens.find(isBorderWidthToken);
1505
+ const styleToken = tokens.find(isBorderStyleToken);
1506
+ const colorTokens = tokens.filter((token) => {
1507
+ return token !== widthToken && token !== styleToken;
1508
+ });
1509
+ return {
1510
+ width: widthToken ? widthToken : void 0,
1511
+ style: styleToken,
1512
+ color: colorTokens.length ? colorTokens.join(" ") : void 0
1513
+ };
1514
+ };
1515
+ var expandBorderWidths = (value) => {
1516
+ if (value === void 0) {
1517
+ return [void 0, void 0, void 0, void 0];
1518
+ }
1519
+ if (typeof value === "number") {
1520
+ return [value, value, value, value];
1521
+ }
1522
+ return expandQuad(
1523
+ splitCssTokens(String(value)).map((token) => token)
1524
+ );
1525
+ };
1526
+ var expandBorderStyles = (value) => {
1527
+ if (value === void 0) {
1528
+ return [void 0, void 0, void 0, void 0];
1529
+ }
1530
+ return expandQuad(splitCssTokens(String(value)).filter(isBorderStyleToken));
1531
+ };
1532
+ var expandBorderColors = (value) => {
1533
+ if (value === void 0) {
1534
+ return [void 0, void 0, void 0, void 0];
1535
+ }
1536
+ return expandQuad(
1537
+ splitCssTokens(String(value)).map((token) => token)
1538
+ );
1539
+ };
1540
+ var expandBorderRadii = (value) => {
1541
+ if (value === void 0) {
1542
+ return [void 0, void 0, void 0, void 0];
1543
+ }
1544
+ if (typeof value === "number") {
1545
+ return [value, value, value, value];
1546
+ }
1547
+ const parts = splitOutsideParentheses(String(value), "/");
1548
+ const horizontal = expandQuad(
1549
+ splitCssTokens(parts[0] ?? "").map(
1550
+ (token) => token
1551
+ )
1552
+ );
1553
+ if (!parts[1]) {
1554
+ return horizontal;
1555
+ }
1556
+ const vertical = expandQuad(
1557
+ splitCssTokens(parts[1]).map((token) => token)
1558
+ );
1559
+ return horizontal.map((horizontalRadius, index) => {
1560
+ const verticalRadius = vertical[index];
1561
+ if (horizontalRadius === void 0) {
1562
+ return void 0;
1563
+ }
1564
+ if (verticalRadius === void 0 || verticalRadius === horizontalRadius) {
1565
+ return horizontalRadius;
1566
+ }
1567
+ return `${horizontalRadius} ${verticalRadius}`;
1568
+ });
1569
+ };
1570
+ var resolveSurfaceStyle = (style) => {
1571
+ const border = parseBorder(style.border);
1572
+ const borderTop = parseBorder(style.borderTop);
1573
+ const borderRight = parseBorder(style.borderRight);
1574
+ const borderBottom = parseBorder(style.borderBottom);
1575
+ const borderLeft = parseBorder(style.borderLeft);
1576
+ const widths = expandBorderWidths(style.borderWidth ?? border.width);
1577
+ const styles = expandBorderStyles(style.borderStyle ?? border.style);
1578
+ const colors = expandBorderColors(style.borderColor ?? border.color);
1579
+ const radii = expandBorderRadii(style.borderRadius);
1580
+ return {
1581
+ borderTopWidth: style.borderTopWidth ?? borderTop.width ?? widths[0],
1582
+ borderRightWidth: style.borderRightWidth ?? borderRight.width ?? widths[1],
1583
+ borderBottomWidth: style.borderBottomWidth ?? borderBottom.width ?? widths[2],
1584
+ borderLeftWidth: style.borderLeftWidth ?? borderLeft.width ?? widths[3],
1585
+ borderTopStyle: style.borderTopStyle ?? borderTop.style ?? styles[0],
1586
+ borderRightStyle: style.borderRightStyle ?? borderRight.style ?? styles[1],
1587
+ borderBottomStyle: style.borderBottomStyle ?? borderBottom.style ?? styles[2],
1588
+ borderLeftStyle: style.borderLeftStyle ?? borderLeft.style ?? styles[3],
1589
+ borderTopColor: style.borderTopColor ?? borderTop.color ?? colors[0],
1590
+ borderRightColor: style.borderRightColor ?? borderRight.color ?? colors[1],
1591
+ borderBottomColor: style.borderBottomColor ?? borderBottom.color ?? colors[2],
1592
+ borderLeftColor: style.borderLeftColor ?? borderLeft.color ?? colors[3],
1593
+ borderTopLeftRadius: style.borderTopLeftRadius ?? radii[0],
1594
+ borderTopRightRadius: style.borderTopRightRadius ?? radii[1],
1595
+ borderBottomRightRadius: style.borderBottomRightRadius ?? radii[2],
1596
+ borderBottomLeftRadius: style.borderBottomLeftRadius ?? radii[3]
1597
+ };
1598
+ };
1599
+ var splitShadowTokens = (value) => {
1600
+ const tokens = [];
1601
+ let current = "";
1602
+ let depth = 0;
1603
+ for (const character of value.trim()) {
1604
+ if (character === "(") {
1605
+ depth += 1;
1606
+ }
1607
+ if (character === ")") {
1608
+ depth = Math.max(0, depth - 1);
1609
+ }
1610
+ if (/\s/.test(character) && depth === 0) {
1611
+ if (current.trim()) {
1612
+ tokens.push(current.trim());
1613
+ }
1614
+ current = "";
1615
+ continue;
1616
+ }
1617
+ current += character;
1618
+ }
1619
+ if (current.trim()) {
1620
+ tokens.push(current.trim());
1621
+ }
1622
+ return tokens;
1623
+ };
1624
+ var isShadowLengthToken = (value) => {
1625
+ return value === "0" || /^-?(?:\d+|\d*\.\d+)(?:px|rem|em|vh|vw|vmin|vmax|%)?$/.test(value) || value.startsWith("calc(") || value.startsWith("var(");
1626
+ };
1627
+ var isShadowColorToken = (value) => {
1628
+ return value.startsWith("#") || value.startsWith("rgb(") || value.startsWith("rgba(") || value.startsWith("hsl(") || value.startsWith("hsla(") || value.startsWith("oklch(") || value.startsWith("oklab(") || value.startsWith("lab(") || value.startsWith("lch(") || value.startsWith("color(") || value.startsWith("color-mix(") || value.startsWith("var(") || /^[a-zA-Z]+$/.test(value);
1629
+ };
1630
+ var boxShadowToDropShadow = (boxShadow) => {
1631
+ if (typeof boxShadow !== "string" || !boxShadow.trim() || boxShadow.trim() === "none") {
1632
+ return void 0;
1633
+ }
1634
+ const shadows = splitOutsideParentheses(boxShadow, ",");
1635
+ const filters = shadows.map((shadow) => {
1636
+ const tokens = splitShadowTokens(shadow);
1637
+ if (tokens.includes("inset")) {
1638
+ return null;
1639
+ }
1640
+ const lengths = tokens.filter(isShadowLengthToken);
1641
+ if (lengths.length < 2) {
1642
+ return null;
1643
+ }
1644
+ const color = tokens.find((token) => {
1645
+ return token !== "inset" && !isShadowLengthToken(token) && isShadowColorToken(token);
1646
+ });
1647
+ const offsetX = lengths[0];
1648
+ const offsetY = lengths[1];
1649
+ const blur = lengths[2] ?? "0px";
1650
+ return `drop-shadow(${offsetX} ${offsetY} ${blur} ${color ?? "rgba(0, 0, 0, 0.25)"})`;
1651
+ }).filter((value) => {
1652
+ return value !== null;
1653
+ });
1654
+ return filters.length ? filters.join(" ") : void 0;
1655
+ };
1656
+ var mergeThemes = (presetTheme, customTheme) => {
1657
+ if (!customTheme) {
1658
+ return presetTheme;
1659
+ }
1660
+ return {
1661
+ ...presetTheme,
1662
+ ...customTheme,
1663
+ body: {
1664
+ ...presetTheme.body,
1665
+ ...customTheme.body,
1666
+ style: {
1667
+ ...presetTheme.body?.style,
1668
+ ...customTheme.body?.style
1669
+ },
1670
+ background: customTheme.body?.background ?? presetTheme.body?.background,
1671
+ filter: customTheme.body?.filter ?? presetTheme.body?.filter,
1672
+ className: customTheme.body?.className ?? presetTheme.body?.className
1673
+ },
1674
+ arrow: {
1675
+ ...presetTheme.arrow,
1676
+ ...customTheme.arrow
1677
+ },
1678
+ animation: {
1679
+ ...presetTheme.animation,
1680
+ ...customTheme.animation
1681
+ }
1682
+ };
1683
+ };
1684
+ var resolveThemeStyles = (theme) => {
1685
+ const bodyStyle = theme.body?.style ?? {};
1686
+ const surfaceStyle = resolveSurfaceStyle(bodyStyle);
1687
+ const {
1688
+ background,
1689
+ backgroundColor,
1690
+ backgroundImage,
1691
+ border,
1692
+ borderTop,
1693
+ borderRight,
1694
+ borderBottom,
1695
+ borderLeft,
1696
+ borderWidth,
1697
+ borderStyle,
1698
+ borderColor,
1699
+ borderTopWidth,
1700
+ borderRightWidth,
1701
+ borderBottomWidth,
1702
+ borderLeftWidth,
1703
+ borderTopStyle,
1704
+ borderRightStyle,
1705
+ borderBottomStyle,
1706
+ borderLeftStyle,
1707
+ borderTopColor,
1708
+ borderRightColor,
1709
+ borderBottomColor,
1710
+ borderLeftColor,
1711
+ borderRadius,
1712
+ borderTopLeftRadius,
1713
+ borderTopRightRadius,
1714
+ borderBottomRightRadius,
1715
+ borderBottomLeftRadius,
1716
+ boxShadow,
1717
+ filter,
1718
+ backdropFilter,
1719
+ WebkitBackdropFilter,
1720
+ color,
1721
+ ...contentStyle
1722
+ } = bodyStyle;
1723
+ const resolvedBackground = theme.body?.background ?? background ?? backgroundImage ?? backgroundColor ?? "var(--global-color-link)";
1724
+ const resolvedColor = color ?? "var(--global-bg-color)";
1725
+ const resolvedFilter = theme.body?.filter ?? filter ?? boxShadowToDropShadow(boxShadow);
1726
+ return {
1727
+ background: resolvedBackground,
1728
+ color: resolvedColor,
1729
+ contentStyle,
1730
+ surfaceStyle,
1731
+ fillStyle: {
1732
+ backdropFilter,
1733
+ WebkitBackdropFilter
1734
+ },
1735
+ filter: resolvedFilter
1736
+ };
1737
+ };
1738
+
1739
+ // src/components/TooltipProvider.tsx
1740
+ var import_react2 = require("react");
1741
+ var import_jsx_runtime = require("react/jsx-runtime");
1742
+ var DEFAULT_TOOLTIP_VALUES = {
1743
+ defaultRenderPosition: "top",
1744
+ selectTheme: "primary"
1745
+ };
1746
+ var TooltipContext = (0, import_react2.createContext)(DEFAULT_TOOLTIP_VALUES);
1747
+ var TooltipProvider = ({
1748
+ children,
1749
+ defaultRenderPosition = DEFAULT_TOOLTIP_VALUES.defaultRenderPosition,
1750
+ selectTheme = DEFAULT_TOOLTIP_VALUES.selectTheme,
1751
+ customTheme,
1752
+ animation
1753
+ }) => {
1754
+ const value = (0, import_react2.useMemo)(() => {
1755
+ return {
1756
+ defaultRenderPosition,
1757
+ selectTheme,
1758
+ customTheme,
1759
+ animation
1760
+ };
1761
+ }, [animation, customTheme, defaultRenderPosition, selectTheme]);
1762
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(TooltipContext.Provider, { value, children });
1763
+ };
1764
+ var useTooltipDefaults = () => {
1765
+ return (0, import_react2.useContext)(TooltipContext);
1766
+ };
1767
+
1768
+ // src/components/TooltipSurface.tsx
1769
+ var import_react3 = require("react");
1770
+ var import_jsx_runtime2 = require("react/jsx-runtime");
1771
+ var EMPTY_METRICS = {
1772
+ width: 0,
1773
+ height: 0,
1774
+ left: 0,
1775
+ top: 0,
1776
+ path: "",
1777
+ strokeWidth: 0,
1778
+ strokeColor: "transparent"
1779
+ };
1780
+ var clamp2 = (value, min, max) => {
1781
+ return Math.min(Math.max(value, min), Math.max(min, max));
1782
+ };
1783
+ var resolveCssLength = (value, base) => {
1784
+ const normalized = value.trim();
1785
+ if (!normalized) {
1786
+ return 0;
1787
+ }
1788
+ if (normalized.endsWith("%")) {
1789
+ return base * (Number.parseFloat(normalized) / 100);
1790
+ }
1791
+ const parsed = Number.parseFloat(normalized);
1792
+ return Number.isFinite(parsed) ? parsed : 0;
1793
+ };
1794
+ var resolveCornerRadius = (value, width, height) => {
1795
+ const parts = value.trim().split(/\s+/).filter(Boolean);
1796
+ const horizontal = resolveCssLength(parts[0] ?? "0", width);
1797
+ const vertical = resolveCssLength(parts[1] ?? parts[0] ?? "0", height);
1798
+ return Math.min(horizontal, vertical);
1799
+ };
1800
+ var normalizeRadii = (radii, width, height) => {
1801
+ const top = radii.topLeft + radii.topRight;
1802
+ const bottom = radii.bottomLeft + radii.bottomRight;
1803
+ const left = radii.topLeft + radii.bottomLeft;
1804
+ const right = radii.topRight + radii.bottomRight;
1805
+ const scale = Math.min(
1806
+ 1,
1807
+ top > 0 ? width / top : 1,
1808
+ bottom > 0 ? width / bottom : 1,
1809
+ left > 0 ? height / left : 1,
1810
+ right > 0 ? height / right : 1
1811
+ );
1812
+ return {
1813
+ topLeft: radii.topLeft * scale,
1814
+ topRight: radii.topRight * scale,
1815
+ bottomRight: radii.bottomRight * scale,
1816
+ bottomLeft: radii.bottomLeft * scale
1817
+ };
1818
+ };
1819
+ var resolveArrowOffset = (value, edgeLength) => {
1820
+ const normalized = value.trim();
1821
+ if (normalized.endsWith("%")) {
1822
+ return edgeLength * (Number.parseFloat(normalized) / 100);
1823
+ }
1824
+ const parsed = Number.parseFloat(normalized);
1825
+ return Number.isFinite(parsed) ? parsed : edgeLength / 2;
1826
+ };
1827
+ var createSurfacePath = ({
1828
+ placement,
1829
+ bodyWidth,
1830
+ bodyHeight,
1831
+ arrowHeight,
1832
+ arrowWidth,
1833
+ requestedArrowOffset,
1834
+ radii
1835
+ }) => {
1836
+ let x0 = 0;
1837
+ let y0 = 0;
1838
+ let x1 = bodyWidth;
1839
+ let y1 = bodyHeight;
1840
+ let width = bodyWidth;
1841
+ let height = bodyHeight;
1842
+ let left = 0;
1843
+ let top = 0;
1844
+ if (placement === "top") {
1845
+ height += arrowHeight;
1846
+ }
1847
+ if (placement === "bottom") {
1848
+ y0 = arrowHeight;
1849
+ y1 = arrowHeight + bodyHeight;
1850
+ height += arrowHeight;
1851
+ top = -arrowHeight;
1852
+ }
1853
+ if (placement === "left") {
1854
+ width += arrowHeight;
1855
+ }
1856
+ if (placement === "right") {
1857
+ x0 = arrowHeight;
1858
+ x1 = arrowHeight + bodyWidth;
1859
+ width += arrowHeight;
1860
+ left = -arrowHeight;
1861
+ }
1862
+ let edgeLength = bodyWidth;
1863
+ let edgeStartRadius = radii.bottomLeft;
1864
+ let edgeEndRadius = radii.bottomRight;
1865
+ if (placement === "bottom") {
1866
+ edgeStartRadius = radii.topLeft;
1867
+ edgeEndRadius = radii.topRight;
1868
+ }
1869
+ if (placement === "left") {
1870
+ edgeLength = bodyHeight;
1871
+ edgeStartRadius = radii.topRight;
1872
+ edgeEndRadius = radii.bottomRight;
1873
+ }
1874
+ if (placement === "right") {
1875
+ edgeLength = bodyHeight;
1876
+ edgeStartRadius = radii.topLeft;
1877
+ edgeEndRadius = radii.bottomLeft;
1878
+ }
1879
+ const availableStraightEdge = Math.max(
1880
+ 0,
1881
+ edgeLength - edgeStartRadius - edgeEndRadius - 2
1882
+ );
1883
+ const arrowHalf = Math.min(arrowWidth / 2, availableStraightEdge / 2);
1884
+ const minArrowCenter = edgeStartRadius + arrowHalf + 1;
1885
+ const maxArrowCenter = edgeLength - edgeEndRadius - arrowHalf - 1;
1886
+ const arrowCenter = minArrowCenter <= maxArrowCenter ? clamp2(requestedArrowOffset, minArrowCenter, maxArrowCenter) : edgeLength / 2;
1887
+ const tl = radii.topLeft;
1888
+ const tr = radii.topRight;
1889
+ const br = radii.bottomRight;
1890
+ const bl = radii.bottomLeft;
1891
+ let path = "";
1892
+ if (placement === "top") {
1893
+ path = [
1894
+ `M ${x0 + tl} ${y0}`,
1895
+ `H ${x1 - tr}`,
1896
+ `Q ${x1} ${y0} ${x1} ${y0 + tr}`,
1897
+ `V ${y1 - br}`,
1898
+ `Q ${x1} ${y1} ${x1 - br} ${y1}`,
1899
+ `H ${arrowCenter + arrowHalf}`,
1900
+ `L ${arrowCenter} ${y1 + arrowHeight}`,
1901
+ `L ${arrowCenter - arrowHalf} ${y1}`,
1902
+ `H ${x0 + bl}`,
1903
+ `Q ${x0} ${y1} ${x0} ${y1 - bl}`,
1904
+ `V ${y0 + tl}`,
1905
+ `Q ${x0} ${y0} ${x0 + tl} ${y0}`,
1906
+ "Z"
1907
+ ].join(" ");
1908
+ }
1909
+ if (placement === "bottom") {
1910
+ path = [
1911
+ `M ${x0 + tl} ${y0}`,
1912
+ `H ${arrowCenter - arrowHalf}`,
1913
+ `L ${arrowCenter} ${y0 - arrowHeight}`,
1914
+ `L ${arrowCenter + arrowHalf} ${y0}`,
1915
+ `H ${x1 - tr}`,
1916
+ `Q ${x1} ${y0} ${x1} ${y0 + tr}`,
1917
+ `V ${y1 - br}`,
1918
+ `Q ${x1} ${y1} ${x1 - br} ${y1}`,
1919
+ `H ${x0 + bl}`,
1920
+ `Q ${x0} ${y1} ${x0} ${y1 - bl}`,
1921
+ `V ${y0 + tl}`,
1922
+ `Q ${x0} ${y0} ${x0 + tl} ${y0}`,
1923
+ "Z"
1924
+ ].join(" ");
1925
+ }
1926
+ if (placement === "left") {
1927
+ path = [
1928
+ `M ${x0 + tl} ${y0}`,
1929
+ `H ${x1 - tr}`,
1930
+ `Q ${x1} ${y0} ${x1} ${y0 + tr}`,
1931
+ `V ${arrowCenter - arrowHalf}`,
1932
+ `L ${x1 + arrowHeight} ${arrowCenter}`,
1933
+ `L ${x1} ${arrowCenter + arrowHalf}`,
1934
+ `V ${y1 - br}`,
1935
+ `Q ${x1} ${y1} ${x1 - br} ${y1}`,
1936
+ `H ${x0 + bl}`,
1937
+ `Q ${x0} ${y1} ${x0} ${y1 - bl}`,
1938
+ `V ${y0 + tl}`,
1939
+ `Q ${x0} ${y0} ${x0 + tl} ${y0}`,
1940
+ "Z"
1941
+ ].join(" ");
1942
+ }
1943
+ if (placement === "right") {
1944
+ path = [
1945
+ `M ${x0 + tl} ${y0}`,
1946
+ `H ${x1 - tr}`,
1947
+ `Q ${x1} ${y0} ${x1} ${y0 + tr}`,
1948
+ `V ${y1 - br}`,
1949
+ `Q ${x1} ${y1} ${x1 - br} ${y1}`,
1950
+ `H ${x0 + bl}`,
1951
+ `Q ${x0} ${y1} ${x0} ${y1 - bl}`,
1952
+ `V ${arrowCenter + arrowHalf}`,
1953
+ `L ${x0 - arrowHeight} ${arrowCenter}`,
1954
+ `L ${x0} ${arrowCenter - arrowHalf}`,
1955
+ `V ${y0 + tl}`,
1956
+ `Q ${x0} ${y0} ${x0 + tl} ${y0}`,
1957
+ "Z"
1958
+ ].join(" ");
1959
+ }
1960
+ return {
1961
+ width,
1962
+ height,
1963
+ left,
1964
+ top,
1965
+ path
1966
+ };
1967
+ };
1968
+ var getStrokeConfig = (computedStyle) => {
1969
+ const widths = [
1970
+ Number.parseFloat(computedStyle.borderTopWidth) || 0,
1971
+ Number.parseFloat(computedStyle.borderRightWidth) || 0,
1972
+ Number.parseFloat(computedStyle.borderBottomWidth) || 0,
1973
+ Number.parseFloat(computedStyle.borderLeftWidth) || 0
1974
+ ];
1975
+ const styles = [
1976
+ computedStyle.borderTopStyle,
1977
+ computedStyle.borderRightStyle,
1978
+ computedStyle.borderBottomStyle,
1979
+ computedStyle.borderLeftStyle
1980
+ ];
1981
+ const colors = [
1982
+ computedStyle.borderTopColor,
1983
+ computedStyle.borderRightColor,
1984
+ computedStyle.borderBottomColor,
1985
+ computedStyle.borderLeftColor
1986
+ ];
1987
+ const activeIndexes = widths.map((width, index) => ({
1988
+ width,
1989
+ index
1990
+ })).filter(({ width, index }) => {
1991
+ return width > 0 && styles[index] !== "none" && styles[index] !== "hidden";
1992
+ });
1993
+ if (!activeIndexes.length) {
1994
+ return {
1995
+ strokeWidth: 0,
1996
+ strokeColor: "transparent",
1997
+ strokeDasharray: void 0,
1998
+ strokeLinecap: void 0
1999
+ };
2000
+ }
2001
+ const active = activeIndexes.reduce((largest, current) => {
2002
+ return current.width > largest.width ? current : largest;
2003
+ });
2004
+ const strokeWidth = active.width;
2005
+ const strokeStyle = styles[active.index];
2006
+ const strokeColor = colors[active.index];
2007
+ if (strokeStyle === "dashed") {
2008
+ return {
2009
+ strokeWidth,
2010
+ strokeColor,
2011
+ strokeDasharray: `${strokeWidth * 3} ${strokeWidth * 2}`,
2012
+ strokeLinecap: "butt"
2013
+ };
2014
+ }
2015
+ if (strokeStyle === "dotted") {
2016
+ return {
2017
+ strokeWidth,
2018
+ strokeColor,
2019
+ strokeDasharray: `${strokeWidth} ${strokeWidth * 1.6}`,
2020
+ strokeLinecap: "round"
2021
+ };
2022
+ }
2023
+ return {
2024
+ strokeWidth,
2025
+ strokeColor,
2026
+ strokeDasharray: void 0,
2027
+ strokeLinecap: "round"
2028
+ };
2029
+ };
2030
+ var createMaskImage = (width, height, path) => {
2031
+ const svg = [
2032
+ '<svg xmlns="http://www.w3.org/2000/svg"',
2033
+ ` viewBox="0 0 ${width} ${height}"`,
2034
+ ` width="${width}"`,
2035
+ ` height="${height}">`,
2036
+ `<path fill="white" d="${path}"/>`,
2037
+ "</svg>"
2038
+ ].join("");
2039
+ return `url("data:image/svg+xml,${encodeURIComponent(svg)}")`;
2040
+ };
2041
+ var TooltipSurface = ({
2042
+ bodyRef,
2043
+ placement,
2044
+ arrowOffset,
2045
+ surfaceStyle,
2046
+ fillStyle,
2047
+ filter
2048
+ }) => {
2049
+ const surfaceProbeRef = (0, import_react3.useRef)(null);
2050
+ const arrowProbeRef = (0, import_react3.useRef)(null);
2051
+ const [metrics, setMetrics] = (0, import_react3.useState)(EMPTY_METRICS);
2052
+ (0, import_react3.useLayoutEffect)(() => {
2053
+ const body = bodyRef.current;
2054
+ const surfaceProbe = surfaceProbeRef.current;
2055
+ const arrowProbe = arrowProbeRef.current;
2056
+ if (!body || !surfaceProbe || !arrowProbe) {
2057
+ return;
2058
+ }
2059
+ const update = () => {
2060
+ const bodyWidth = body.offsetWidth;
2061
+ const bodyHeight = body.offsetHeight;
2062
+ if (bodyWidth <= 0 || bodyHeight <= 0) {
2063
+ return;
2064
+ }
2065
+ surfaceProbe.style.width = `${bodyWidth}px`;
2066
+ surfaceProbe.style.height = `${bodyHeight}px`;
2067
+ const surfaceComputedStyle = window.getComputedStyle(surfaceProbe);
2068
+ const arrowComputedStyle = window.getComputedStyle(arrowProbe);
2069
+ const arrowHeight = Number.parseFloat(arrowComputedStyle.height) || 6;
2070
+ const arrowWidth = Number.parseFloat(arrowComputedStyle.width) || arrowHeight * 2;
2071
+ const radii = normalizeRadii(
2072
+ {
2073
+ topLeft: resolveCornerRadius(
2074
+ surfaceComputedStyle.borderTopLeftRadius,
2075
+ bodyWidth,
2076
+ bodyHeight
2077
+ ),
2078
+ topRight: resolveCornerRadius(
2079
+ surfaceComputedStyle.borderTopRightRadius,
2080
+ bodyWidth,
2081
+ bodyHeight
2082
+ ),
2083
+ bottomRight: resolveCornerRadius(
2084
+ surfaceComputedStyle.borderBottomRightRadius,
2085
+ bodyWidth,
2086
+ bodyHeight
2087
+ ),
2088
+ bottomLeft: resolveCornerRadius(
2089
+ surfaceComputedStyle.borderBottomLeftRadius,
2090
+ bodyWidth,
2091
+ bodyHeight
2092
+ )
2093
+ },
2094
+ bodyWidth,
2095
+ bodyHeight
2096
+ );
2097
+ const requestedArrowOffset = resolveArrowOffset(
2098
+ arrowOffset,
2099
+ placement === "top" || placement === "bottom" ? bodyWidth : bodyHeight
2100
+ );
2101
+ const surface = createSurfacePath({
2102
+ placement,
2103
+ bodyWidth,
2104
+ bodyHeight,
2105
+ arrowHeight,
2106
+ arrowWidth,
2107
+ requestedArrowOffset,
2108
+ radii
2109
+ });
2110
+ const stroke = getStrokeConfig(surfaceComputedStyle);
2111
+ const nextMetrics = {
2112
+ ...surface,
2113
+ ...stroke
2114
+ };
2115
+ setMetrics((current) => {
2116
+ if (current.width === nextMetrics.width && current.height === nextMetrics.height && current.left === nextMetrics.left && current.top === nextMetrics.top && current.path === nextMetrics.path && current.strokeWidth === nextMetrics.strokeWidth && current.strokeColor === nextMetrics.strokeColor && current.strokeDasharray === nextMetrics.strokeDasharray && current.strokeLinecap === nextMetrics.strokeLinecap) {
2117
+ return current;
2118
+ }
2119
+ return nextMetrics;
2120
+ });
2121
+ };
2122
+ update();
2123
+ const resizeObserver = new ResizeObserver(update);
2124
+ resizeObserver.observe(body);
2125
+ window.addEventListener("resize", update);
2126
+ return () => {
2127
+ resizeObserver.disconnect();
2128
+ window.removeEventListener("resize", update);
2129
+ };
2130
+ }, [arrowOffset, bodyRef, placement, surfaceStyle]);
2131
+ const maskImage = metrics.path ? createMaskImage(metrics.width, metrics.height, metrics.path) : void 0;
2132
+ const resolvedFillStyle = {
2133
+ ...fillStyle,
2134
+ maskImage,
2135
+ maskPosition: "0 0",
2136
+ maskRepeat: "no-repeat",
2137
+ maskSize: "100% 100%",
2138
+ WebkitMaskImage: maskImage,
2139
+ WebkitMaskPosition: "0 0",
2140
+ WebkitMaskRepeat: "no-repeat",
2141
+ WebkitMaskSize: "100% 100%"
2142
+ };
2143
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
2144
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2145
+ "div",
2146
+ {
2147
+ ref: surfaceProbeRef,
2148
+ className: "tooltip-surface-probe",
2149
+ style: surfaceStyle
2150
+ }
2151
+ ),
2152
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { ref: arrowProbeRef, className: "tooltip-arrow-probe" }),
2153
+ metrics.path ? /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
2154
+ "div",
2155
+ {
2156
+ className: "tooltip-surface",
2157
+ style: {
2158
+ width: metrics.width,
2159
+ height: metrics.height,
2160
+ left: metrics.left,
2161
+ top: metrics.top,
2162
+ filter
2163
+ },
2164
+ "aria-hidden": "true",
2165
+ children: [
2166
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2167
+ "div",
2168
+ {
2169
+ className: "tooltip-surface__fill",
2170
+ style: resolvedFillStyle
2171
+ }
2172
+ ),
2173
+ metrics.strokeWidth > 0 ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2174
+ "svg",
2175
+ {
2176
+ className: "tooltip-surface__stroke",
2177
+ width: metrics.width,
2178
+ height: metrics.height,
2179
+ viewBox: `0 0 ${metrics.width} ${metrics.height}`,
2180
+ children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
2181
+ "path",
2182
+ {
2183
+ d: metrics.path,
2184
+ fill: "none",
2185
+ stroke: metrics.strokeColor,
2186
+ strokeWidth: metrics.strokeWidth,
2187
+ strokeDasharray: metrics.strokeDasharray,
2188
+ strokeLinecap: metrics.strokeLinecap,
2189
+ strokeLinejoin: "round",
2190
+ vectorEffect: "non-scaling-stroke"
2191
+ }
2192
+ )
2193
+ }
2194
+ ) : null
2195
+ ]
2196
+ }
2197
+ ) : null
2198
+ ] });
2199
+ };
2200
+
2201
+ // src/components/Tooltip.tsx
2202
+ var import_jsx_runtime3 = require("react/jsx-runtime");
2203
+ var DEFAULT_SHOW_ANIMATION = "slide";
2204
+ var DEFAULT_HIDE_ANIMATION = "fade";
2205
+ var assignRef = (ref, value) => {
2206
+ if (typeof ref === "function") {
2207
+ ref(value);
2208
+ return;
2209
+ }
2210
+ if (ref) {
2211
+ ref.current = value;
2212
+ }
2213
+ };
2214
+ var Tooltip = ({
2215
+ content,
2216
+ children,
2217
+ position,
2218
+ selectTheme,
2219
+ customTheme,
2220
+ animation,
2221
+ disabled = false,
2222
+ interactive = false,
2223
+ hideDelay
2224
+ }) => {
2225
+ const defaults = useTooltipDefaults();
2226
+ const markerRef = (0, import_react4.useRef)(null);
2227
+ const [anchor, setAnchor] = (0, import_react4.useState)(null);
2228
+ const trigger = children ? import_react4.Children.only(children) : null;
2229
+ const triggerRef = trigger?.props.ref;
2230
+ const setTriggerRef = (0, import_react4.useCallback)(
2231
+ (node) => {
2232
+ assignRef(triggerRef, node);
2233
+ setAnchor(node);
2234
+ },
2235
+ [triggerRef]
2236
+ );
2237
+ (0, import_react4.useLayoutEffect)(() => {
2238
+ if (trigger) {
2239
+ return;
2240
+ }
2241
+ const marker = markerRef.current;
2242
+ const parent = marker?.parentElement ?? null;
2243
+ setAnchor(parent);
2244
+ return () => {
2245
+ setAnchor(null);
2246
+ };
2247
+ }, [trigger]);
2248
+ const inheritedTheme = (0, import_react4.useMemo)(() => {
2249
+ return mergeThemes(presets[defaults.selectTheme], defaults.customTheme);
2250
+ }, [defaults.customTheme, defaults.selectTheme]);
2251
+ const theme = (0, import_react4.useMemo)(() => {
2252
+ if (selectTheme) {
2253
+ return mergeThemes(presets[selectTheme], customTheme);
2254
+ }
2255
+ return mergeThemes(inheritedTheme, customTheme);
2256
+ }, [customTheme, inheritedTheme, selectTheme]);
2257
+ const resolvedThemeStyles = (0, import_react4.useMemo)(() => {
2258
+ return resolveThemeStyles(theme);
2259
+ }, [theme]);
2260
+ const localThemeAnimation = selectTheme ? theme.animation : customTheme?.animation;
2261
+ const showAnimation = animation?.show ?? localThemeAnimation?.show ?? defaults.animation?.show ?? inheritedTheme.animation?.show ?? DEFAULT_SHOW_ANIMATION;
2262
+ const hideAnimation = animation?.hide ?? localThemeAnimation?.hide ?? defaults.animation?.hide ?? inheritedTheme.animation?.hide ?? DEFAULT_HIDE_ANIMATION;
2263
+ const animationSpeed = animation?.speed ?? localThemeAnimation?.speed ?? defaults.animation?.speed ?? inheritedTheme.animation?.speed ?? "120ms";
2264
+ const animationEasing = animation?.easing ?? localThemeAnimation?.easing ?? defaults.animation?.easing ?? inheritedTheme.animation?.easing ?? "ease-in-out";
2265
+ const preferredPlacement = position ?? defaults.defaultRenderPosition;
2266
+ const {
2267
+ shouldRender,
2268
+ phase,
2269
+ placement,
2270
+ position: tooltipPosition,
2271
+ tooltipRef,
2272
+ bodyRef,
2273
+ onAnimationEnd
2274
+ } = useTooltip({
2275
+ anchor,
2276
+ preferredPlacement,
2277
+ disabled: disabled || content === null || content === void 0,
2278
+ interactive,
2279
+ hideDelay
2280
+ });
2281
+ const arrowSize = theme.arrow?.size ?? "6px";
2282
+ const arrowWidth = theme.arrow?.width ?? `calc(${arrowSize} * 2)`;
2283
+ const containerStyle = {
2284
+ "--tooltip-bg": resolvedThemeStyles.background,
2285
+ "--tooltip-color": resolvedThemeStyles.color,
2286
+ "--tooltip-arrow-size": arrowSize,
2287
+ "--tooltip-arrow-width": arrowWidth,
2288
+ "--tooltip-animation-speed": animationSpeed,
2289
+ "--tooltip-animation-easing": animationEasing,
2290
+ ...tooltipPosition
2291
+ };
2292
+ const arrowOffset = String(
2293
+ tooltipPosition["--tooltip-arrow-offset"] ?? "50%"
2294
+ );
2295
+ const handleAnimationEnd = (event) => {
2296
+ if (event.target !== event.currentTarget) {
2297
+ return;
2298
+ }
2299
+ onAnimationEnd();
2300
+ };
2301
+ const triggerElement = trigger ? (0, import_react4.cloneElement)(trigger, {
2302
+ ref: setTriggerRef
2303
+ }) : /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { ref: markerRef, hidden: true, "aria-hidden": "true" });
2304
+ const portal = shouldRender && typeof document !== "undefined" ? (0, import_react_dom.createPortal)(
2305
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2306
+ "div",
2307
+ {
2308
+ ref: tooltipRef,
2309
+ className: [
2310
+ "tooltip-container",
2311
+ `tooltip-container--${placement}`,
2312
+ `tooltip-container--phase-${phase}`,
2313
+ `tooltip-container--show-${showAnimation}`,
2314
+ `tooltip-container--hide-${hideAnimation}`,
2315
+ interactive ? "tooltip-container--interactive" : null
2316
+ ].filter(Boolean).join(" "),
2317
+ style: containerStyle,
2318
+ children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
2319
+ "div",
2320
+ {
2321
+ ref: bodyRef,
2322
+ className: "tooltip-body",
2323
+ onAnimationEnd: handleAnimationEnd,
2324
+ children: [
2325
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2326
+ TooltipSurface,
2327
+ {
2328
+ bodyRef,
2329
+ placement,
2330
+ arrowOffset,
2331
+ surfaceStyle: resolvedThemeStyles.surfaceStyle,
2332
+ fillStyle: resolvedThemeStyles.fillStyle,
2333
+ filter: resolvedThemeStyles.filter
2334
+ }
2335
+ ),
2336
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
2337
+ "div",
2338
+ {
2339
+ className: [
2340
+ "tooltip-body__content",
2341
+ theme.body?.className
2342
+ ].filter(Boolean).join(" "),
2343
+ style: resolvedThemeStyles.contentStyle,
2344
+ children: content
2345
+ }
2346
+ )
2347
+ ]
2348
+ }
2349
+ )
2350
+ }
2351
+ ),
2352
+ document.body
2353
+ ) : null;
2354
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_jsx_runtime3.Fragment, { children: [
2355
+ triggerElement,
2356
+ portal
2357
+ ] });
2358
+ };
2359
+ // Annotate the CommonJS export names for ESM import in node:
2360
+ 0 && (module.exports = {
2361
+ Tooltip,
2362
+ TooltipProvider
2363
+ });
2364
+ //# sourceMappingURL=index.js.map