@ssaprt/tooltip 1.0.0 → 1.0.4

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/README.md CHANGED
@@ -1,77 +1,64 @@
1
- Tooltip by @ssaprt
1
+ # Tooltip by @ssaprt
2
2
 
3
3
  A flexible, themeable, and interactive tooltip library for React and Next.js.
4
4
 
5
- Web version: <a href="https://utility-lub.vercel.app/react/UI-Components/tooltip/">Scroll to Future</a>
6
-
7
- tooltip supports simple text hints, rich React content, interactive controls, media, custom themes, built-in animations, automatic viewport collision handling, touch interaction, and optional global presets through TooltipProvider.
8
-
9
- The provider is optional. Every Tooltip can work independently.
10
-
11
- Features
12
-
13
- Standalone tooltips without a provider
14
-
15
- Optional global TooltipProvider
16
-
17
- More than 50 built-in theme presets
18
-
19
- Per-tooltip theme overrides
20
-
21
- Fully custom themes
22
-
23
- Four preferred placements: top, bottom, left, and right
24
-
25
- Automatic opposite-side fallback
26
-
27
- Automatic viewport clamping
28
-
29
- Arrow position correction near rounded corners
30
-
31
- Unified tooltip body and arrow surface
32
-
33
- Solid colors, gradients, borders, textures, filters, and shadows
34
-
35
- Separate show and hide animations
36
-
37
- Configurable animation speed and easing
38
-
39
- Interactive tooltip content
40
-
41
- Configurable hide delay
42
-
43
- Text, JSX, components, forms, buttons, links, images, video, and other media
44
-
45
- Automatic repositioning while scrolling and resizing
46
-
47
- Automatic updates when tooltip content changes size
48
-
49
- Mouse, touch, focus, and keyboard handling
50
-
51
- React portal rendering into document.body
52
-
53
- TypeScript support
54
-
55
- React and Next.js support
56
-
57
- Adapted for modern Chrome, Safari, Firefox, Edge, iOS Safari, and Chromium-based mobile browsers
58
-
59
- Installation
60
-
5
+ [Web version](https://utility-lub.vercel.app/react/UI-Components/tooltip/)
6
+
7
+ `@ssaprt/tooltip` supports simple text hints, rich React content, interactive controls, media, custom themes, built-in animations, automatic viewport collision handling, touch interaction, and optional global presets through `TooltipProvider`.
8
+
9
+ The provider is optional. Every `Tooltip` can work independently.
10
+
11
+ ## Features
12
+
13
+ - Standalone tooltips without a provider
14
+ - Optional global `TooltipProvider`
15
+ - More than 50 built-in theme presets
16
+ - Per-tooltip theme overrides
17
+ - Fully custom themes
18
+ - Four preferred placements: `top`, `bottom`, `left`, and `right`
19
+ - Automatic opposite-side fallback
20
+ - Automatic viewport clamping
21
+ - Arrow position correction near rounded corners
22
+ - Unified tooltip body and arrow surface
23
+ - Solid colors, gradients, borders, textures, filters, and shadows
24
+ - Separate show and hide animations
25
+ - Configurable animation speed and easing
26
+ - Interactive tooltip content
27
+ - Configurable hide delay
28
+ - Text, JSX, components, forms, buttons, links, images, video, and other media
29
+ - Automatic repositioning while scrolling and resizing
30
+ - Automatic updates when tooltip content changes size
31
+ - Mouse, touch, focus, and keyboard handling
32
+ - React portal rendering into `document.body`
33
+ - TypeScript support
34
+ - React and Next.js support
35
+ - Adapted for modern Chrome, Safari, Firefox, Edge, iOS Safari, and Chromium-based mobile browsers
36
+
37
+ ## Installation
38
+
39
+ ```bash
61
40
  npm install @ssaprt/tooltip
41
+ ```
62
42
 
43
+ ```bash
63
44
  yarn add @ssaprt/tooltip
45
+ ```
64
46
 
47
+ ```bash
65
48
  pnpm add @ssaprt/tooltip
49
+ ```
66
50
 
67
51
  Import the stylesheet once in the application entry point:
68
52
 
53
+ ```ts
69
54
  import "@ssaprt/tooltip/style.css";
55
+ ```
70
56
 
71
- Basic usage
57
+ ## Basic usage
72
58
 
73
- TooltipProvider is not required.
59
+ `TooltipProvider` is not required.
74
60
 
61
+ ```tsx
75
62
  "use client";
76
63
 
77
64
  import { Tooltip } from "@ssaprt/tooltip";
@@ -84,13 +71,15 @@ export const Example = () => {
84
71
  </Tooltip>
85
72
  );
86
73
  };
74
+ ```
87
75
 
88
76
  The child element becomes the tooltip anchor.
89
77
 
90
- Local configuration
78
+ ## Local configuration
91
79
 
92
80
  Every tooltip can define its own position, theme, animation, delay, and behavior.
93
81
 
82
+ ```tsx
94
83
  <Tooltip
95
84
  content="Saved successfully"
96
85
  position="bottom"
@@ -105,11 +94,13 @@ Every tooltip can define its own position, theme, animation, delay, and behavior
105
94
  >
106
95
  <button type="button">Save</button>
107
96
  </Tooltip>
97
+ ```
108
98
 
109
- Tooltip inside an element
99
+ ## Tooltip inside an element
110
100
 
111
101
  A tooltip can also be placed directly inside its target element.
112
102
 
103
+ ```tsx
113
104
  <button type="button">
114
105
  Delete
115
106
 
@@ -119,13 +110,15 @@ A tooltip can also be placed directly inside its target element.
119
110
  selectTheme="red"
120
111
  />
121
112
  </button>
113
+ ```
122
114
 
123
- When children is not passed to Tooltip, the immediate parent element becomes the anchor.
115
+ When `children` is not passed to `Tooltip`, the immediate parent element becomes the anchor.
124
116
 
125
- Optional global provider
117
+ ## Optional global provider
126
118
 
127
- Use TooltipProvider when many tooltips should share the same initial position, preset theme, custom theme overrides, or animations.
119
+ Use `TooltipProvider` when many tooltips should share the same initial position, preset theme, custom theme overrides, animations, interactive behavior, or hide delay.
128
120
 
121
+ ```tsx
129
122
  "use client";
130
123
 
131
124
  import { TooltipProvider } from "@ssaprt/tooltip";
@@ -140,6 +133,8 @@ export const AppProvider = ({
140
133
  <TooltipProvider
141
134
  defaultRenderPosition="top"
142
135
  selectTheme="glass"
136
+ interactive
137
+ hideDelay={300}
143
138
  animation={{
144
139
  show: "slide",
145
140
  hide: "fade",
@@ -151,9 +146,11 @@ export const AppProvider = ({
151
146
  </TooltipProvider>
152
147
  );
153
148
  };
149
+ ```
154
150
 
155
151
  All descendant tooltips inherit these values unless they override them locally.
156
152
 
153
+ ```tsx
157
154
  <Tooltip content="Uses provider defaults">
158
155
  <button type="button">Default tooltip</button>
159
156
  </Tooltip>
@@ -162,6 +159,8 @@ All descendant tooltips inherit these values unless they override them locally.
162
159
  content="Uses local settings"
163
160
  position="right"
164
161
  selectTheme="comic"
162
+ interactive={false}
163
+ hideDelay={120}
165
164
  animation={{
166
165
  show: "zoom",
167
166
  hide: "scale",
@@ -170,25 +169,23 @@ All descendant tooltips inherit these values unless they override them locally.
170
169
  >
171
170
  <button type="button">Local tooltip</button>
172
171
  </Tooltip>
172
+ ```
173
173
 
174
- Configuration priority
174
+ ## Configuration priority
175
175
 
176
176
  Local tooltip values have priority over provider defaults.
177
177
 
178
178
  The effective configuration is resolved in this order:
179
179
 
180
- Props passed directly to Tooltip
181
-
182
- Local customTheme
183
-
184
- Values from TooltipProvider
185
-
186
- Animation settings from the selected preset theme
187
-
188
- Built-in defaults
180
+ 1. Props passed directly to `Tooltip`
181
+ 2. Local `customTheme`
182
+ 3. Values from `TooltipProvider`
183
+ 4. Animation settings from the selected preset theme
184
+ 5. Built-in defaults
189
185
 
190
186
  The default built-in values are:
191
187
 
188
+ ```ts
192
189
  const defaults = {
193
190
  position: "top",
194
191
  selectTheme: "primary",
@@ -196,18 +193,26 @@ const defaults = {
196
193
  hideAnimation: "fade",
197
194
  animationSpeed: "120ms",
198
195
  animationEasing: "ease-in-out",
196
+ interactive: false,
197
+ hideDelay: 120,
199
198
  };
199
+ ```
200
+
201
+ Interactive tooltips use a default hide delay of `240ms` when no local or provider value is supplied.
200
202
 
201
- Text content
203
+ ## Text content
202
204
 
205
+ ```tsx
203
206
  <Tooltip content="Simple text tooltip">
204
207
  <span>Hover me</span>
205
208
  </Tooltip>
209
+ ```
206
210
 
207
- The content prop accepts any valid ReactNode.
211
+ The `content` prop accepts any valid `ReactNode`.
208
212
 
209
- React content
213
+ ## React content
210
214
 
215
+ ```tsx
211
216
  <Tooltip
212
217
  content={
213
218
  <div>
@@ -218,11 +223,13 @@ React content
218
223
  >
219
224
  <button type="button">Build status</button>
220
225
  </Tooltip>
226
+ ```
221
227
 
222
- Interactive content
228
+ ## Interactive content
223
229
 
224
- Set interactive when the user must be able to move the pointer into the tooltip and interact with its content.
230
+ Set `interactive` when the user must be able to move the pointer into the tooltip and interact with its content.
225
231
 
232
+ ```tsx
226
233
  <Tooltip
227
234
  interactive
228
235
  hideDelay={300}
@@ -236,37 +243,25 @@ Set interactive when the user must be able to move the pointer into the tooltip
236
243
  >
237
244
  <button type="button">Open controls</button>
238
245
  </Tooltip>
246
+ ```
239
247
 
240
- With interactive enabled:
241
-
242
- The tooltip remains visible while the pointer is inside it
243
-
244
- Buttons, links, inputs, selects, and other controls remain usable
245
-
246
- Moving from the anchor to the tooltip does not close it
247
-
248
- Moving away from both the anchor and tooltip starts the hide delay
248
+ With `interactive` enabled:
249
249
 
250
- Clicking outside closes the tooltip
250
+ - The tooltip remains visible while the pointer is inside it
251
+ - Buttons, links, inputs, selects, and other controls remain usable
252
+ - Moving from the anchor to the tooltip does not close it
253
+ - Moving away from both the anchor and tooltip starts the hide delay
254
+ - Clicking outside closes the tooltip
255
+ - Pressing `Escape` closes the tooltip
256
+ - Focus can move between the anchor and tooltip content
251
257
 
252
- Pressing Escape closes the tooltip
258
+ The default hide delay is `120ms`. For interactive tooltips, the default is `240ms`. A custom `hideDelay` overrides both values.
253
259
 
254
- Focus can move between the anchor and tooltip content
255
-
256
- The default hide delay is:
257
-
258
- 120
259
-
260
- For interactive tooltips, the default is:
261
-
262
- 240
263
-
264
- A custom hideDelay overrides both values.
265
-
266
- Rich components and media
260
+ ## Rich components and media
267
261
 
268
262
  Tooltip content is not limited to a short string. It can contain complete React interfaces, including cards, media previews, forms, navigation, images, audio, and video.
269
263
 
264
+ ```tsx
270
265
  <Tooltip
271
266
  interactive
272
267
  position="right"
@@ -314,21 +309,25 @@ Tooltip content is not limited to a short string. It can contain complete React
314
309
  >
315
310
  <button type="button">Show preview</button>
316
311
  </Tooltip>
312
+ ```
317
313
 
318
- The tooltip uses ResizeObserver, so its position is recalculated when dynamic content changes size.
314
+ The tooltip uses `ResizeObserver`, so its position is recalculated when dynamic content changes size.
319
315
 
320
- Trigger elements
316
+ ## Trigger elements
321
317
 
322
- Wrapping a DOM element
318
+ ### Wrapping a DOM element
323
319
 
320
+ ```tsx
324
321
  <Tooltip content="Open settings">
325
322
  <button type="button">Settings</button>
326
323
  </Tooltip>
324
+ ```
327
325
 
328
- Wrapping a custom React component
326
+ ### Wrapping a custom React component
329
327
 
330
328
  The wrapped component must forward its ref to a DOM element.
331
329
 
330
+ ```tsx
332
331
  import { forwardRef } from "react";
333
332
 
334
333
  const ActionButton = forwardRef<
@@ -347,11 +346,13 @@ export const Example = () => {
347
346
  </Tooltip>
348
347
  );
349
348
  };
349
+ ```
350
350
 
351
- Using a tooltip inside a custom component
351
+ ### Using a tooltip inside a custom component
352
352
 
353
- When forwarding a ref is not convenient, place Tooltip inside the final DOM element.
353
+ When forwarding a ref is not convenient, place `Tooltip` inside the final DOM element.
354
354
 
355
+ ```tsx
355
356
  export const ActionButton = () => {
356
357
  return (
357
358
  <button type="button">
@@ -360,117 +361,127 @@ export const ActionButton = () => {
360
361
  </button>
361
362
  );
362
363
  };
364
+ ```
363
365
 
364
- Placement
366
+ ## Placement
365
367
 
366
368
  Available placements:
367
369
 
370
+ ```ts
368
371
  type TooltipPlacement =
369
372
  | "top"
370
373
  | "bottom"
371
374
  | "left"
372
375
  | "right";
376
+ ```
373
377
 
374
378
  Example:
375
379
 
380
+ ```tsx
376
381
  <Tooltip content="Rendered on the left" position="left">
377
382
  <button type="button">Left</button>
378
383
  </Tooltip>
384
+ ```
379
385
 
380
386
  The requested placement is preferred, not forced.
381
387
 
382
388
  When there is not enough space, the tooltip checks the opposite side:
383
389
 
384
- top can fall back to bottom
385
-
386
- bottom can fall back to top
387
-
388
- left can fall back to right
389
-
390
- right can fall back to left
390
+ - `top` can fall back to `bottom`
391
+ - `bottom` can fall back to `top`
392
+ - `left` can fall back to `right`
393
+ - `right` can fall back to `left`
391
394
 
392
395
  The final position is clamped to the viewport so the tooltip does not render outside the visible area.
393
396
 
394
397
  The arrow is repositioned automatically and constrained to the straight section of the edge so it does not overlap rounded corners.
395
398
 
396
- Built-in themes
399
+ ## Built-in themes
397
400
 
398
401
  The package includes more than 50 ready-to-use presets with different visual styles, including clean, dark, comic, terminal, glass, neon, retro, cyberpunk, paper, metallic, natural, warning, and decorative themes.
399
402
 
400
403
  Examples include:
401
404
 
402
- "primary"
403
- "secondary"
404
- "dark"
405
- "light"
406
- "comic"
407
- "manga"
408
- "newspaper"
409
- "stickyNote"
410
- "blueprint"
411
- "terminal"
412
- "crt"
413
- "pixel"
414
- "arcade"
415
- "cyberpunk"
416
- "synthwave"
417
- "vaporwave"
418
- "hologram"
419
- "glass"
420
- "frost"
421
- "clay"
422
- "bubblegum"
423
- "candy"
424
- "watermelon"
425
- "lemon"
426
- "lava"
427
- "ember"
428
- "toxic"
429
- "radioactive"
430
- "hazard"
431
- "policeTape"
432
- "construction"
433
- "parchment"
434
- "pirateMap"
435
- "royal"
436
- "noir"
437
- "detective"
438
- "dossier"
439
- "medical"
440
- "laboratory"
441
- "circuit"
442
- "galaxy"
443
- "aurora"
444
- "oceanDepths"
445
- "coralReef"
446
- "forest"
447
- "moss"
448
- "desert"
449
- "snow"
450
- "chrome"
451
- "goldFoil"
452
- "bronze"
453
- "brutalist"
454
- "chalkboard"
405
+ ```ts
406
+ type PresetsThemeType =
407
+ | "primary"
408
+ | "secondary"
409
+ | "dark"
410
+ | "light"
411
+ | "comic"
412
+ | "manga"
413
+ | "newspaper"
414
+ | "stickyNote"
415
+ | "blueprint"
416
+ | "terminal"
417
+ | "crt"
418
+ | "pixel"
419
+ | "arcade"
420
+ | "cyberpunk"
421
+ | "synthwave"
422
+ | "vaporwave"
423
+ | "hologram"
424
+ | "glass"
425
+ | "frost"
426
+ | "clay"
427
+ | "bubblegum"
428
+ | "candy"
429
+ | "watermelon"
430
+ | "lemon"
431
+ | "lava"
432
+ | "ember"
433
+ | "toxic"
434
+ | "radioactive"
435
+ | "hazard"
436
+ | "policeTape"
437
+ | "construction"
438
+ | "parchment"
439
+ | "pirateMap"
440
+ | "royal"
441
+ | "noir"
442
+ | "detective"
443
+ | "dossier"
444
+ | "medical"
445
+ | "laboratory"
446
+ | "circuit"
447
+ | "galaxy"
448
+ | "aurora"
449
+ | "oceanDepths"
450
+ | "coralReef"
451
+ | "forest"
452
+ | "moss"
453
+ | "desert"
454
+ | "snow"
455
+ | "chrome"
456
+ | "goldFoil"
457
+ | "bronze"
458
+ | "brutalist"
459
+ | "chalkboard";
460
+ ```
455
461
 
456
462
  Select a preset globally:
457
463
 
464
+ ```tsx
458
465
  <TooltipProvider selectTheme="cyberpunk">
459
466
  <App />
460
467
  </TooltipProvider>
468
+ ```
461
469
 
462
470
  Or locally:
463
471
 
472
+ ```tsx
464
473
  <Tooltip content="Local theme" selectTheme="terminal">
465
474
  <button type="button">Terminal</button>
466
475
  </Tooltip>
476
+ ```
467
477
 
468
- PresetsThemeType is derived from the actual preset map, so TypeScript only accepts available theme names.
478
+ `PresetsThemeType` is derived from the actual preset map, so TypeScript only accepts available theme names.
469
479
 
470
- Custom themes
480
+ ## Custom themes
471
481
 
472
- A custom theme can be applied globally through TooltipProvider or locally through Tooltip.
482
+ A custom theme can be applied globally through `TooltipProvider` or locally through `Tooltip`.
473
483
 
484
+ ```tsx
474
485
  <Tooltip
475
486
  content="Custom theme"
476
487
  customTheme={{
@@ -502,11 +513,13 @@ A custom theme can be applied globally through TooltipProvider or locally throug
502
513
  >
503
514
  <button type="button">Custom</button>
504
515
  </Tooltip>
516
+ ```
505
517
 
506
518
  Custom theme values are merged with the selected preset. Only the values that must change need to be supplied.
507
519
 
508
- Theme type
520
+ ### Theme type
509
521
 
522
+ ```ts
510
523
  import type { CSSProperties } from "react";
511
524
 
512
525
  type TooltipSize =
@@ -528,27 +541,23 @@ type ThemeType = {
528
541
  };
529
542
  animation?: TooltipAnimationOptions;
530
543
  };
544
+ ```
531
545
 
532
- body.background
546
+ ### `body.background`
533
547
 
534
548
  Controls the complete tooltip surface background, including the arrow.
535
549
 
536
550
  Supported values include:
537
551
 
538
- Solid colors
539
-
540
- Linear gradients
541
-
542
- Radial gradients
543
-
544
- Conic gradients
545
-
546
- Repeating gradients
547
-
548
- CSS variables
549
-
550
- Other valid CSS background values
552
+ - Solid colors
553
+ - Linear gradients
554
+ - Radial gradients
555
+ - Conic gradients
556
+ - Repeating gradients
557
+ - CSS variables
558
+ - Other valid CSS background values
551
559
 
560
+ ```tsx
552
561
  <Tooltip
553
562
  content="Gradient"
554
563
  customTheme={{
@@ -560,13 +569,15 @@ Other valid CSS background values
560
569
  >
561
570
  <button type="button">Gradient</button>
562
571
  </Tooltip>
572
+ ```
563
573
 
564
- body.style
574
+ ### `body.style`
565
575
 
566
- Accepts regular React CSSProperties for the tooltip content and surface configuration.
576
+ Accepts regular React `CSSProperties` for the tooltip content and surface configuration.
567
577
 
568
578
  Common options include:
569
579
 
580
+ ```ts
570
581
  {
571
582
  color: "#ffffff",
572
583
  padding: "10px 14px",
@@ -578,13 +589,15 @@ Common options include:
578
589
  textAlign: "left",
579
590
  maxWidth: "320px",
580
591
  }
592
+ ```
581
593
 
582
594
  Borders and corner radii are used to generate the unified body-and-arrow surface.
583
595
 
584
- body.filter
596
+ ### `body.filter`
585
597
 
586
598
  Applies a filter to the complete tooltip surface, including the arrow.
587
599
 
600
+ ```tsx
588
601
  <Tooltip
589
602
  content="Shadow"
590
603
  customTheme={{
@@ -596,11 +609,13 @@ Applies a filter to the complete tooltip surface, including the arrow.
596
609
  >
597
610
  <button type="button">Shadow</button>
598
611
  </Tooltip>
612
+ ```
599
613
 
600
- body.className
614
+ ### `body.className`
601
615
 
602
616
  Adds a class name to the tooltip content container.
603
617
 
618
+ ```tsx
604
619
  <Tooltip
605
620
  content="Class name"
606
621
  customTheme={{
@@ -611,27 +626,33 @@ Adds a class name to the tooltip content container.
611
626
  >
612
627
  <button type="button">Styled</button>
613
628
  </Tooltip>
629
+ ```
614
630
 
615
- arrow.size
631
+ ### `arrow.size`
616
632
 
617
633
  Controls how far the arrow extends from the tooltip body.
618
634
 
635
+ ```ts
619
636
  arrow: {
620
637
  size: "10px",
621
638
  }
639
+ ```
622
640
 
623
- arrow.width
641
+ ### `arrow.width`
624
642
 
625
643
  Controls the width of the arrow base.
626
644
 
645
+ ```ts
627
646
  arrow: {
628
647
  width: "24px",
629
648
  }
649
+ ```
630
650
 
631
- Animations
651
+ ## Animations
632
652
 
633
653
  Show and hide animations can be configured independently.
634
654
 
655
+ ```tsx
635
656
  <Tooltip
636
657
  content="Animated tooltip"
637
658
  animation={{
@@ -643,9 +664,11 @@ Show and hide animations can be configured independently.
643
664
  >
644
665
  <button type="button">Animate</button>
645
666
  </Tooltip>
667
+ ```
646
668
 
647
669
  Available animation types:
648
670
 
671
+ ```ts
649
672
  type TooltipAnimationType =
650
673
  | "fade"
651
674
  | "slide"
@@ -655,9 +678,11 @@ type TooltipAnimationType =
655
678
  | "flip"
656
679
  | "bounce"
657
680
  | "none";
681
+ ```
658
682
 
659
683
  Animation options:
660
684
 
685
+ ```ts
661
686
  type TooltipAnimationSpeed =
662
687
  | `${number}ms`
663
688
  | `${number}s`;
@@ -668,9 +693,11 @@ type TooltipAnimationOptions = {
668
693
  speed?: TooltipAnimationSpeed;
669
694
  easing?: CSSProperties["animationTimingFunction"];
670
695
  };
696
+ ```
671
697
 
672
698
  Disable animations:
673
699
 
700
+ ```tsx
674
701
  <Tooltip
675
702
  content="No animation"
676
703
  animation={{
@@ -682,66 +709,32 @@ Disable animations:
682
709
  >
683
710
  <button type="button">Static</button>
684
711
  </Tooltip>
712
+ ```
685
713
 
686
- The stylesheet also respects prefers-reduced-motion and reduces animation duration when the user requests reduced motion.
687
-
688
- TooltipProvider API
689
-
690
- TooltipProvider is optional and only supplies global defaults to descendant tooltips.
691
-
692
- Property
693
-
694
- Type
695
-
696
- Default
697
-
698
- Description
699
-
700
- children
701
-
702
- ReactNode
703
-
704
- Required
705
-
706
- Components that can consume the provider defaults
707
-
708
- defaultRenderPosition
709
-
710
- "top" | "bottom" | "left" | "right"
711
-
712
- "top"
713
-
714
- Default preferred placement
715
-
716
- selectTheme
717
-
718
- PresetsThemeType
719
-
720
- "primary"
721
-
722
- Default built-in theme preset
723
-
724
- customTheme
725
-
726
- ThemeType
727
-
728
- undefined
729
-
730
- Global theme overrides merged with the selected preset
714
+ The stylesheet also respects `prefers-reduced-motion` and reduces animation duration when the user requests reduced motion.
731
715
 
732
- animation
716
+ ## `TooltipProvider` API
733
717
 
734
- TooltipAnimationOptions
718
+ `TooltipProvider` is optional and only supplies global defaults to descendant tooltips.
735
719
 
736
- Theme settings
737
-
738
- Global show and hide animation overrides
720
+ | Property | Type | Default | Description |
721
+ | --- | --- | --- | --- |
722
+ | `children` | `ReactNode` | Required | Components that can consume the provider defaults |
723
+ | `defaultRenderPosition` | `"top" \| "bottom" \| "left" \| "right"` | `"top"` | Default preferred placement |
724
+ | `selectTheme` | `PresetsThemeType` | `"primary"` | Default built-in theme preset |
725
+ | `customTheme` | `ThemeType` | `undefined` | Global theme overrides merged with the selected preset |
726
+ | `animation` | `TooltipAnimationOptions` | Theme settings | Global show and hide animation overrides |
727
+ | `interactive` | `boolean` | `false` | Enables interactive behavior for descendant tooltips |
728
+ | `hideDelay` | `number` | `120`, or `240` when interactive | Global delay before descendant tooltips begin hiding |
739
729
 
740
730
  Complete provider example:
741
731
 
732
+ ```tsx
742
733
  <TooltipProvider
743
734
  defaultRenderPosition="bottom"
744
735
  selectTheme="glass"
736
+ interactive
737
+ hideDelay={300}
745
738
  customTheme={{
746
739
  body: {
747
740
  style: {
@@ -765,91 +758,25 @@ Complete provider example:
765
758
  >
766
759
  <App />
767
760
  </TooltipProvider>
768
-
769
- Tooltip API
770
-
771
- Property
772
-
773
- Type
774
-
775
- Default
776
-
777
- Description
778
-
779
- content
780
-
781
- ReactNode
782
-
783
- Required
784
-
785
- Text, JSX, components, controls, media, or any other React content
786
-
787
- children
788
-
789
- ReactElement
790
-
791
- Optional
792
-
793
- Element used as the tooltip anchor; without it, the immediate parent is used
794
-
795
- position
796
-
797
- TooltipPlacement
798
-
799
- Provider value or "top"
800
-
801
- Preferred tooltip placement
802
-
803
- selectTheme
804
-
805
- PresetsThemeType
806
-
807
- Provider value or "primary"
808
-
809
- Local built-in theme preset
810
-
811
- customTheme
812
-
813
- ThemeType
814
-
815
- undefined
816
-
817
- Local theme overrides
818
-
819
- animation
820
-
821
- TooltipAnimationOptions
822
-
823
- Provider or theme settings
824
-
825
- Local show and hide animation settings
826
-
827
- disabled
828
-
829
- boolean
830
-
831
- false
832
-
833
- Prevents the tooltip from opening
834
-
835
- interactive
836
-
837
- boolean
838
-
839
- false
840
-
841
- Enables pointer and focus interaction inside the tooltip
842
-
843
- hideDelay
844
-
845
- number
846
-
847
- 120, or 240 when interactive
848
-
849
- Delay in milliseconds before the tooltip begins hiding
761
+ ```
762
+
763
+ ## `Tooltip` API
764
+
765
+ | Property | Type | Default | Description |
766
+ | --- | --- | --- | --- |
767
+ | `content` | `ReactNode` | Required | Text, JSX, components, controls, media, or any other React content |
768
+ | `children` | `ReactElement` | Optional | Element used as the tooltip anchor; without it, the immediate parent is used |
769
+ | `position` | `TooltipPlacement` | Provider value or `"top"` | Preferred tooltip placement |
770
+ | `selectTheme` | `PresetsThemeType` | Provider value or `"primary"` | Local built-in theme preset |
771
+ | `customTheme` | `ThemeType` | `undefined` | Local theme overrides |
772
+ | `animation` | `TooltipAnimationOptions` | Provider or theme settings | Local show and hide animation settings |
773
+ | `disabled` | `boolean` | `false` | Prevents the tooltip from opening |
774
+ | `interactive` | `boolean` | Provider value or `false` | Enables pointer and focus interaction inside the tooltip |
775
+ | `hideDelay` | `number` | Provider value, `120`, or `240` when interactive | Delay in milliseconds before the tooltip begins hiding |
850
776
 
851
777
  Complete tooltip example:
852
778
 
779
+ ```tsx
853
780
  <Tooltip
854
781
  content={
855
782
  <div>
@@ -877,9 +804,11 @@ Complete tooltip example:
877
804
  >
878
805
  <button type="button">Account</button>
879
806
  </Tooltip>
807
+ ```
880
808
 
881
- Public interfaces
809
+ ## Public interfaces
882
810
 
811
+ ```ts
883
812
  import type { ReactElement, ReactNode } from "react";
884
813
 
885
814
  export type TooltipPlacement =
@@ -889,10 +818,13 @@ export type TooltipPlacement =
889
818
  | "right";
890
819
 
891
820
  export interface TooltipProviderInterface {
821
+ children: ReactNode;
892
822
  defaultRenderPosition?: TooltipPlacement;
893
823
  selectTheme?: PresetsThemeType;
894
824
  customTheme?: ThemeType;
895
825
  animation?: TooltipAnimationOptions;
826
+ interactive?: boolean;
827
+ hideDelay?: number;
896
828
  }
897
829
 
898
830
  export interface TooltipInterface {
@@ -906,9 +838,11 @@ export interface TooltipInterface {
906
838
  interactive?: boolean;
907
839
  hideDelay?: number;
908
840
  }
841
+ ```
909
842
 
910
- TypeScript exports
843
+ ## TypeScript exports
911
844
 
845
+ ```ts
912
846
  import {
913
847
  Tooltip,
914
848
  TooltipProvider,
@@ -925,89 +859,71 @@ import type {
925
859
  TooltipProviderInterface,
926
860
  TooltipSize,
927
861
  } from "@ssaprt/tooltip";
862
+ ```
928
863
 
929
- Browser support
864
+ ## Browser support
930
865
 
931
866
  The package is designed for consistent behavior in modern desktop and mobile browsers:
932
867
 
933
- Google Chrome
934
-
935
- Apple Safari
936
-
937
- Mozilla Firefox
938
-
939
- Microsoft Edge
940
-
941
- iOS Safari
942
-
943
- Chromium-based Android browsers
868
+ - Google Chrome
869
+ - Apple Safari
870
+ - Mozilla Firefox
871
+ - Microsoft Edge
872
+ - iOS Safari
873
+ - Chromium-based Android browsers
944
874
 
945
875
  The implementation uses browser-standard APIs and technologies:
946
876
 
947
- React portals
948
-
949
- Pointer events
950
-
951
- Touch input
952
-
953
- Focus events
954
-
955
- ResizeObserver
877
+ - React portals
878
+ - Pointer events
879
+ - Touch input
880
+ - Focus events
881
+ - `ResizeObserver`
882
+ - `requestAnimationFrame`
883
+ - SVG paths and masks
884
+ - CSS custom properties
885
+ - CSS gradients
886
+ - CSS filters
887
+ - Fixed viewport positioning
956
888
 
957
- requestAnimationFrame
958
-
959
- SVG paths and masks
960
-
961
- CSS custom properties
962
-
963
- CSS gradients
964
-
965
- CSS filters
966
-
967
- Fixed viewport positioning
968
-
969
- Tooltips are rendered into document.body, so they are not normally clipped by overflow: hidden or overflow: auto on application containers.
889
+ Tooltips are rendered into `document.body`, so they are not normally clipped by `overflow: hidden` or `overflow: auto` on application containers.
970
890
 
971
891
  The position is recalculated when:
972
892
 
973
- The window is resized
974
-
975
- The page or an ancestor is scrolled
976
-
977
- Tooltip content changes dimensions
978
-
979
- Media or dynamic components change the tooltip size
893
+ - The window is resized
894
+ - The page or an ancestor is scrolled
895
+ - Tooltip content changes dimensions
896
+ - Media or dynamic components change the tooltip size
980
897
 
981
898
  Legacy Internet Explorer is not supported.
982
899
 
983
- Mouse, keyboard, and touch behavior
900
+ ## Mouse, keyboard, and touch behavior
984
901
 
985
- Desktop pointer behavior:
902
+ ### Desktop pointer behavior
986
903
 
987
- Pointer enter opens the tooltip
904
+ - Pointer enter opens the tooltip
905
+ - Pointer leave starts the configured hide delay
906
+ - Interactive content keeps the tooltip open while hovered
907
+ - Moving through the safe area between the anchor and tooltip keeps an interactive tooltip open
988
908
 
989
- Pointer leave starts the configured hide delay
909
+ ### Keyboard behavior
990
910
 
991
- Interactive content keeps the tooltip open while hovered
911
+ - Focusing the anchor opens the tooltip
912
+ - Focus can move into interactive content
913
+ - `Escape` closes the tooltip
992
914
 
993
- Keyboard behavior:
915
+ ### Touch behavior
994
916
 
995
- Focusing the anchor opens the tooltip
917
+ - A completed tap on the anchor toggles the tooltip
918
+ - Moving the finger to scroll does not open the tooltip
919
+ - A cancelled pointer gesture does not open the tooltip
920
+ - Tapping outside closes the tooltip
996
921
 
997
- Focus can move into interactive content
922
+ ## React and Next.js
998
923
 
999
- Escape closes the tooltip
1000
-
1001
- Touch behavior:
1002
-
1003
- Tapping the anchor toggles the tooltip
1004
-
1005
- Tapping outside closes it
1006
-
1007
- React and Next.js
1008
-
1009
- Tooltip and TooltipProvider use client-side browser APIs and React portals. In Next.js, render them from a Client Component.
924
+ `Tooltip` and `TooltipProvider` use client-side browser APIs and React portals. In Next.js, render them from a Client Component.
1010
925
 
926
+ ```tsx
1011
927
  "use client";
1012
928
 
1013
929
  import { Tooltip, TooltipProvider } from "@ssaprt/tooltip";
@@ -1027,9 +943,11 @@ export const TooltipClientProvider = ({
1027
943
  </TooltipProvider>
1028
944
  );
1029
945
  };
946
+ ```
1030
947
 
1031
948
  Use it in a layout:
1032
949
 
950
+ ```tsx
1033
951
  import { TooltipClientProvider } from "./TooltipClientProvider";
1034
952
 
1035
953
  export default function RootLayout({
@@ -1047,25 +965,22 @@ export default function RootLayout({
1047
965
  </html>
1048
966
  );
1049
967
  }
968
+ ```
1050
969
 
1051
970
  A provider is still optional. A standalone tooltip can be rendered directly from any Client Component.
1052
971
 
1053
- Rendering and overflow
972
+ ## Rendering and overflow
1054
973
 
1055
- The visible tooltip is rendered through a React portal into document.body.
974
+ The visible tooltip is rendered through a React portal into `document.body`.
1056
975
 
1057
976
  This provides several benefits:
1058
977
 
1059
- Parent overflow normally does not clip the tooltip
1060
-
1061
- The tooltip is positioned relative to the viewport
1062
-
1063
- Scroll and resize updates are handled globally
1064
-
1065
- Complex content is isolated from the anchor layout
1066
-
1067
- A high stacking level can be used without depending on the anchor's stacking context
978
+ - Parent overflow normally does not clip the tooltip
979
+ - The tooltip is positioned relative to the viewport
980
+ - Scroll and resize updates are handled globally
981
+ - Complex content is isolated from the anchor layout
982
+ - A high stacking level can be used without depending on the anchor's stacking context
1068
983
 
1069
- License
984
+ ## License
1070
985
 
1071
- MIT
986
+ MIT