@antadesign/anta 0.3.33 → 0.3.35

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.
Files changed (205) hide show
  1. package/LICENSE.md +14 -1
  2. package/README.md +9 -0
  3. package/dist/anta_helpers.d.ts +46 -30
  4. package/dist/anta_helpers.js +66 -25
  5. package/dist/bundle.css +1 -1
  6. package/dist/bundle.js +2 -1353
  7. package/dist/components/Banner.d.ts +25 -40
  8. package/dist/components/Banner.js +15 -17
  9. package/dist/components/Breadcrumbs.d.ts +0 -1
  10. package/dist/components/Breadcrumbs.js +0 -1
  11. package/dist/components/Button.d.ts +2 -3
  12. package/dist/components/Button.js +1 -0
  13. package/dist/components/ButtonCopy.js +3 -2
  14. package/dist/components/Calendar.js +13 -13
  15. package/dist/components/Card.d.ts +9 -17
  16. package/dist/components/Card.js +50 -46
  17. package/dist/components/Dialog.d.ts +1 -0
  18. package/dist/components/Dialog.js +16 -10
  19. package/dist/components/Expander.d.ts +6 -21
  20. package/dist/components/Expander.js +24 -23
  21. package/dist/components/Icon.d.ts +8 -14
  22. package/dist/components/Input.d.ts +77 -96
  23. package/dist/components/Input.js +23 -27
  24. package/dist/components/InputAutocomplete.d.ts +29 -10
  25. package/dist/components/InputAutocomplete.js +25 -8
  26. package/dist/components/InputDate.d.ts +0 -1
  27. package/dist/components/InputDate.js +2 -3
  28. package/dist/components/InputTime.d.ts +10 -4
  29. package/dist/components/InputTime.js +20 -16
  30. package/dist/components/Loader.d.ts +2 -2
  31. package/dist/components/Menu.d.ts +5 -4
  32. package/dist/components/Menu.js +13 -8
  33. package/dist/components/MenuItem.js +1 -14
  34. package/dist/components/MenuItemCopy.js +2 -2
  35. package/dist/components/Panel.d.ts +3 -1
  36. package/dist/components/Panel.js +17 -11
  37. package/dist/components/Progress.d.ts +21 -23
  38. package/dist/components/Progress.js +13 -9
  39. package/dist/components/RadioGroup.js +6 -8
  40. package/dist/components/{select-parts.css → Select.css} +1 -1
  41. package/dist/components/Select.d.ts +53 -36
  42. package/dist/components/Select.js +53 -98
  43. package/dist/components/SelectFaceted.d.ts +7 -4
  44. package/dist/components/SelectFaceted.js +21 -10
  45. package/dist/components/Slider.d.ts +28 -11
  46. package/dist/components/Slider.js +20 -20
  47. package/dist/components/Steps.css +1 -1
  48. package/dist/components/Steps.d.ts +0 -1
  49. package/dist/components/Steps.js +1 -12
  50. package/dist/components/Tabs.d.ts +17 -20
  51. package/dist/components/Tabs.js +7 -9
  52. package/dist/components/Text.d.ts +55 -36
  53. package/dist/components/Text.js +35 -22
  54. package/dist/components/Title.d.ts +19 -27
  55. package/dist/components/Title.js +2 -1
  56. package/dist/components/Toaster.js +9 -2
  57. package/dist/components/Tooltip.d.ts +10 -15
  58. package/dist/components/copy-props.d.ts +14 -3
  59. package/dist/components/copy-props.js +14 -3
  60. package/dist/components/select-tree.d.ts +24 -0
  61. package/dist/components/select-tree.js +35 -0
  62. package/dist/element-base.d.ts +10 -0
  63. package/dist/element-base.js +15 -0
  64. package/dist/elements/a-avatar.css +1 -1
  65. package/dist/elements/a-avatar.js +2 -28
  66. package/dist/elements/a-banner.css +1 -1
  67. package/dist/elements/a-banner.d.ts +4 -1
  68. package/dist/elements/a-banner.js +22 -112
  69. package/dist/elements/a-breadcrumbs.d.ts +1 -0
  70. package/dist/elements/a-breadcrumbs.js +1 -0
  71. package/dist/elements/a-button.css +1 -1
  72. package/dist/elements/a-button.d.ts +10 -7
  73. package/dist/elements/a-button.js +18 -1
  74. package/dist/elements/a-calendar.d.ts +14 -13
  75. package/dist/elements/a-calendar.js +29 -24
  76. package/dist/elements/a-card.css +1 -1
  77. package/dist/elements/a-card.d.ts +0 -9
  78. package/dist/elements/a-card.js +0 -184
  79. package/dist/elements/a-checkbox.css +1 -1
  80. package/dist/elements/a-copy.css +1 -1
  81. package/dist/elements/a-copy.d.ts +1 -5
  82. package/dist/elements/a-copy.js +129 -108
  83. package/dist/elements/a-dialog.css +1 -1
  84. package/dist/elements/a-dialog.d.ts +1 -1
  85. package/dist/elements/a-dialog.js +68 -194
  86. package/dist/elements/a-expander.css +1 -1
  87. package/dist/elements/a-expander.d.ts +4 -30
  88. package/dist/elements/a-expander.js +85 -344
  89. package/dist/elements/a-icon.d.ts +5 -23
  90. package/dist/elements/a-icon.js +1 -2
  91. package/dist/elements/a-input-date.d.ts +1 -0
  92. package/dist/elements/a-input-date.js +1 -0
  93. package/dist/elements/a-input-time.css +1 -1
  94. package/dist/elements/a-input-time.d.ts +2 -1
  95. package/dist/elements/a-input-time.js +101 -168
  96. package/dist/elements/a-input.css +1 -1
  97. package/dist/elements/a-input.d.ts +10 -8
  98. package/dist/elements/a-input.js +155 -230
  99. package/dist/elements/a-loader.d.ts +5 -8
  100. package/dist/elements/a-loader.js +1 -2
  101. package/dist/elements/a-menu-item.css +1 -1
  102. package/dist/elements/a-menu-item.d.ts +5 -3
  103. package/dist/elements/a-menu-item.js +5 -1
  104. package/dist/elements/a-menu.css +1 -1
  105. package/dist/elements/a-menu.d.ts +5 -7
  106. package/dist/elements/a-menu.js +383 -299
  107. package/dist/elements/a-panel.css +1 -1
  108. package/dist/elements/a-panel.js +19 -37
  109. package/dist/elements/a-progress.css +1 -1
  110. package/dist/elements/a-progress.d.ts +0 -22
  111. package/dist/elements/a-progress.js +0 -100
  112. package/dist/elements/a-radio-group.d.ts +1 -1
  113. package/dist/elements/a-radio-group.js +6 -4
  114. package/dist/elements/a-select-faceted.d.ts +1 -0
  115. package/dist/elements/a-select-faceted.js +1 -0
  116. package/dist/elements/a-select.d.ts +1 -0
  117. package/dist/elements/a-select.js +1 -0
  118. package/dist/elements/a-slider.css +1 -1
  119. package/dist/elements/a-slider.d.ts +11 -3
  120. package/dist/elements/a-slider.js +244 -242
  121. package/dist/elements/a-steps.d.ts +1 -0
  122. package/dist/elements/a-steps.js +1 -0
  123. package/dist/elements/a-switch.css +1 -1
  124. package/dist/elements/a-tab.css +1 -1
  125. package/dist/elements/a-tabpanel.d.ts +2 -2
  126. package/dist/elements/a-tabpanel.js +13 -3
  127. package/dist/elements/a-tabs.css +1 -1
  128. package/dist/elements/a-tabs.d.ts +1 -1
  129. package/dist/elements/a-tabs.js +6 -4
  130. package/dist/elements/a-tag.css +1 -1
  131. package/dist/elements/a-tag.d.ts +1 -0
  132. package/dist/elements/a-tag.js +1 -0
  133. package/dist/elements/a-text.css +1 -1
  134. package/dist/elements/a-text.d.ts +6 -43
  135. package/dist/elements/a-text.js +110 -193
  136. package/dist/elements/a-title.css +1 -1
  137. package/dist/elements/a-title.d.ts +1 -0
  138. package/dist/elements/a-title.js +1 -0
  139. package/dist/elements/a-toast.css +1 -1
  140. package/dist/elements/a-toast.d.ts +10 -45
  141. package/dist/elements/a-toast.js +80 -66
  142. package/dist/elements/a-toaster.css +1 -1
  143. package/dist/elements/a-toaster.js +9 -44
  144. package/dist/elements/a-tooltip.css +1 -1
  145. package/dist/elements/a-tooltip.d.ts +1 -1
  146. package/dist/elements/a-tooltip.js +142 -136
  147. package/dist/elements/copy-behavior.d.ts +1 -1
  148. package/dist/elements/copy-behavior.js +21 -21
  149. package/dist/elements/index.d.ts +9 -3
  150. package/dist/elements/index.js +6 -6
  151. package/dist/elements/input-focus-modality.d.ts +15 -0
  152. package/dist/elements/input-focus-modality.js +44 -0
  153. package/dist/elements/input-trailing-actions.d.ts +5 -0
  154. package/dist/elements/input-trailing-actions.js +38 -0
  155. package/dist/elements/shadow-aria.d.ts +2 -0
  156. package/dist/elements/shadow-aria.js +2 -1
  157. package/dist/elements/value-input.d.ts +3 -0
  158. package/dist/elements/value-input.js +12 -0
  159. package/dist/general_types.d.ts +103 -96
  160. package/dist/index.d.ts +1 -1
  161. package/dist/input-events.d.ts +4 -0
  162. package/dist/input-events.js +15 -0
  163. package/dist/jsx-runtime.d.ts +70 -23
  164. package/dist/jsx-runtime.js +26 -19
  165. package/dist/native-event-props.d.ts +2 -0
  166. package/dist/native-event-props.js +10 -0
  167. package/dist/reset.css +1 -1
  168. package/dist/theme-antithesis.css +10 -1
  169. package/dist/theme-antune.css +1 -1
  170. package/docs/accessibility.md +17 -3
  171. package/docs/changelog.md +384 -2
  172. package/docs/comparison.md +2 -2
  173. package/docs/components/avatar.md +5 -0
  174. package/docs/components/banner.md +117 -187
  175. package/docs/components/breadcrumbs.md +9 -6
  176. package/docs/components/button.md +22 -0
  177. package/docs/components/card.md +74 -28
  178. package/docs/components/checkbox.md +9 -10
  179. package/docs/components/dialog.md +83 -32
  180. package/docs/components/expander.md +198 -435
  181. package/docs/components/icon.md +11 -17
  182. package/docs/components/input-autocomplete.md +152 -52
  183. package/docs/components/input-date.md +175 -148
  184. package/docs/components/input-time.md +81 -38
  185. package/docs/components/input.md +343 -349
  186. package/docs/components/loader.md +2 -1
  187. package/docs/components/menu.md +35 -6
  188. package/docs/components/panel.md +18 -0
  189. package/docs/components/progress.md +83 -49
  190. package/docs/components/radio.md +39 -43
  191. package/docs/components/select-faceted.md +54 -7
  192. package/docs/components/select.md +390 -386
  193. package/docs/components/slider.md +136 -19
  194. package/docs/components/steps.md +6 -3
  195. package/docs/components/switch.md +8 -9
  196. package/docs/components/tabs.md +110 -104
  197. package/docs/components/text.md +110 -86
  198. package/docs/components/title.md +47 -33
  199. package/docs/components/toaster.md +242 -84
  200. package/docs/components/tooltip.md +204 -113
  201. package/docs/install-config.md +461 -96
  202. package/docs/packages/plot.md +228 -143
  203. package/docs/theming.md +29 -13
  204. package/package.json +43 -4
  205. package/theme-antithesis-license.md +66 -0
@@ -1,169 +1,260 @@
1
1
  # Tooltip
2
2
 
3
- A small floating bubble that describes the element it's placed inside. Render
4
- `<Tooltip>` as a child of the element it annotates — it doesn't affect that
5
- element's layout, and its content can be anything.
6
-
7
- It shows on hover (after a short `delay`) and on keyboard focus, and dismisses
8
- on mouse leave, blur, Esc, or when the anchor scrolls away. On touch
9
- devices — where there's no hover and a tap shouldn't surface it — it opens on
10
- **press-and-hold** and lingers briefly after you lift, so it stays readable. By
11
- default the bubble is **pinned** under the anchor; pass `follow` to make it
12
- **track the cursor** (fading out as the cursor moves away), or `interactive` to
13
- make it hoverable and clickable (for content like links).
14
-
15
- When the anchor implements **`getAnchorRect(): DOMRect`**, the bubble positions
16
- against that rect instead of the anchor's full box. Anta's `Input` reports its
17
- field box, so a tooltip on an `<Input>` points at the field, not the surrounding
18
- label or hint.
3
+ Use Tooltip for supplementary explanations and the full text of clipped labels.
4
+ Place it inside the element it describes. It takes no space in that element's
5
+ layout. Keep essential instructions and actions available without a tooltip.
19
6
 
20
7
  ## Examples
21
8
 
9
+ Hover Status for a text explanation, focus the underlined button with Tab,
10
+ follow the cursor, or enter the interactive bubble to use its link.
11
+
22
12
  ```tsx
23
- // Place <Tooltip> inside the element it describes; hover or focus the anchor.
24
- // Pinned under the anchor by default — prefer the top side here (auto-flips
25
- // down when there's no room).
26
- <span style={{ cursor: 'help' }}>
27
- Status
28
- <Tooltip placement="top">Last checked 2 minutes ago</Tooltip>
29
- </span>
30
-
31
- // A near-instant tooltip on a keyboard-focusable button. Never use delay={0} — use ~50.
32
- <Button priority="tertiary" underline="dashed" label="Focus me with the keyboard">
33
- <Tooltip delay={50}>Shows on focus, dismiss with Esc</Tooltip>
34
- </Button>
13
+ <div style={{ display: 'flex', gap: '16px', alignItems: 'center', flexWrap: 'wrap' }}>
14
+ <span style={{ cursor: 'help', display: 'inline-flex', alignItems: 'center', gap: '4px' }}>
15
+ <span>Status</span>
16
+ <Icon shape="info" size={16} style={{ color: 'var(--text-5)' }} />
17
+ <Tooltip placement="top">Last checked 2 minutes ago</Tooltip>
18
+ </span>
19
+ <Button priority="tertiary" underline="dashed" label="Focus me with the keyboard">
20
+ <Tooltip delay={50}>Shows on focus, dismiss with Esc</Tooltip>
21
+ </Button>
22
+ <Button label="Follow the cursor">
23
+ <Tooltip follow>Tracks the pointer, fades as you leave</Tooltip>
24
+ </Button>
25
+ <Button label="Interact">
26
+ <Tooltip interactive placement="top">
27
+ See the <a href="/install/">full guide</a> for details
28
+ </Tooltip>
29
+ </Button>
30
+ </div>
31
+ ```
35
32
 
36
- // `follow` tracks the cursor and fades by distance as you move away.
37
- <Button label="Follow the cursor">
38
- <Tooltip follow>Tracks the pointer, fades as you leave</Tooltip>
39
- </Button>
33
+ ## Hover and keyboard focus
40
34
 
41
- // Rich content — render anything.
42
- <Button icon="info">
43
- <Tooltip placement="top">
44
- <strong>Heads up</strong> — this action can't be undone
45
- </Tooltip>
35
+ Hover the button or reach it with Tab to show its explanation after a delay.
36
+ Escape dismisses it. Leaving the anchor, moving focus away, or scrolling also
37
+ closes it. On touch screens, hold the anchor for 500ms; a quick tap does not open
38
+ it. After release, a touch tooltip remains for 1.5 seconds.
39
+
40
+ Give the trigger an accessible name independently. Put explanations that should
41
+ be available before opening on the trigger with authored ARIA. Here,
42
+ `aria-description` supplies the short description in both open and closed states.
43
+
44
+ ```tsx
45
+ <Button label="Publish" aria-description="Makes the draft public">
46
+ <Tooltip id="publish-tooltip" delay={50}>Makes the draft public</Tooltip>
46
47
  </Button>
48
+ ```
49
+
50
+ ## Placement
47
51
 
48
- // Interactive: the bubble becomes hoverable + clickable, so its content
49
- // (links, buttons) works. Always pinned — a bubble that follows the cursor
50
- // can't be entered, so `interactive` ignores `follow`. Move from the anchor
51
- // into the bubble to click; press Esc to dismiss.
52
- <Button label="Interact">
53
- <Tooltip interactive placement="top">
54
- See the <a href="/guide">full guide</a> for details
52
+ Choose `top` or `left` to prefer another side. Tooltip flips when that side has
53
+ insufficient room and keeps the bubble within the viewport.
54
+
55
+ ```tsx
56
+ <Button label="Below"><Tooltip>Below the anchor</Tooltip></Button>
57
+ <Button label="Above"><Tooltip placement="top">Above the anchor</Tooltip></Button>
58
+ <Button label="Beside"><Tooltip placement="left">Beside the anchor</Tooltip></Button>
59
+ ```
60
+
61
+ ## Follow the cursor
62
+
63
+ Use `follow` for explanations attached to a larger pointer target. The bubble
64
+ tracks the cursor and fades with distance as the pointer leaves. Moving between
65
+ two `follow` anchors skips the next delay while the previous tooltip is open or
66
+ within its 300ms grace period. Pinned tooltips keep their configured delay.
67
+ Keyboard and touch openings stay anchored to the target.
68
+
69
+ ```tsx
70
+ <Button label="First"><Tooltip follow>First explanation</Tooltip></Button>
71
+ <Button label="Second"><Tooltip follow>Second explanation</Tooltip></Button>
72
+ ```
73
+
74
+ ## Interactive content
75
+
76
+ Pass `interactive` to enter the bubble with the pointer or keyboard and use its
77
+ content. It stays pinned even when `follow` is present. Move from the trigger to
78
+ the link, or focus the trigger and press Tab. Escape dismisses the bubble.
79
+
80
+ This option preserves Tooltip's existing tooltip semantics. The ARIA tooltip
81
+ pattern describes nonfocusable content; use Menu or Dialog for essential actions
82
+ that need an explicit trigger and popup semantics.
83
+
84
+ ```tsx
85
+ <Button label="Help" aria-description="Read the installation guide for setup details">
86
+ <Tooltip id="help-tooltip" interactive placement="top">
87
+ Read the <a href="/install/">installation guide</a>.
55
88
  </Tooltip>
56
89
  </Button>
57
90
  ```
58
91
 
59
- The underlying `<a-tooltip>` works in plain HTML too, as a child of any element:
92
+ ## Show only when truncated
60
93
 
61
- ```html
62
- <button>
63
- Publish
64
- <a-tooltip>Makes the draft public</a-tooltip>
65
- </button>
94
+ Use `truncatedOnly` when the explanation repeats a label. A label that fits does
95
+ not open a bubble. Hover both labels to compare a clipped target with one that
96
+ fits.
97
+
98
+ ```tsx
99
+ <div style={{ display: 'flex', gap: '28px', alignItems: 'flex-start', flexWrap: 'wrap' }}>
100
+ <span style={{ display: 'inline-block', maxWidth: '130px', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', cursor: 'help' }}>
101
+ A long label that gets truncated
102
+ <Tooltip truncatedOnly>A long label that gets truncated</Tooltip>
103
+ </span>
104
+ <span style={{ display: 'inline-block', cursor: 'help' }}>
105
+ Short label
106
+ <Tooltip truncatedOnly>Short label</Tooltip>
107
+ </span>
108
+ </div>
66
109
  ```
67
110
 
68
- ### Adjacent and nested tooltips
111
+ Text with `truncate` already creates an automatic tooltip for clipped,
112
+ non-expandable content.
113
+
114
+ ```tsx
115
+ <Text truncate style={{ maxWidth: '160px' }}>
116
+ A long release title that does not fit in this space
117
+ </Text>
118
+ <Text truncate>Short title</Text>
119
+ ```
69
120
 
70
- Only one tooltip shows at a time. Moving between **adjacent** anchors with
71
- `follow` tooltips hands off cleanly — the outgoing bubble cross-fades out as the
72
- next fades in (no blink). If either tooltip does not have `follow`, the next
73
- tooltip waits for its configured delay. With `follow` tooltips (used below to
74
- show it), the outgoing bubble also keeps
75
- trailing the cursor and fades by distance from its anchor (transparent by ~100px
76
- away), so a near hop reads as a smooth cross-fade and a far one is already gone.
77
- With **nested** anchors, the inner (descendant) tooltip wins while you're over
78
- it, and the outer takes back over when you leave. Hover the examples to feel it.
121
+ Nest your own Tooltip inside Text to replace its automatic explanation. An empty
122
+ explicit Tooltip suppresses the automatic one.
79
123
 
80
124
  ```tsx
81
- // Adjacent — moving from one to the next cross-fades, no blink. `follow` adds
82
- // the cursor-trailing + distance fade so the hand-off is most visible.
83
- <Button label="First"><Tooltip follow>First tooltip</Tooltip></Button>
84
- <Button label="Second"><Tooltip follow>Second tooltip</Tooltip></Button>
85
-
86
- // Nested — wrap stray text in a <span> so the tooltip stays a direct child of
87
- // the box (its anchor). The inner tooltip wins while you're over the inner button.
88
- <div tabIndex={0}>
89
- <span>Outer box</span>
90
- <Tooltip follow>Outer tooltip</Tooltip>
91
- <Button label="Inner button"><Tooltip follow>Inner tooltip</Tooltip></Button>
92
- </div>
125
+ <Text truncate style={{ maxWidth: '160px' }}>
126
+ A long release title with a custom explanation
127
+ <Tooltip>This release includes keyboard navigation improvements.</Tooltip>
128
+ </Text>
93
129
  ```
94
130
 
95
- ### Show only when truncated
131
+ ## Adjacent and nested tooltips
96
132
 
97
- Pass **`truncatedOnly`** and the tooltip appears only when its target's text is
98
- actually ellipsized — a label that fits gets no tooltip. The check is a UI-thread
99
- layout read, re-measured on each hover (so resizing the container flips it live). By
100
- default it measures the nearest Anta ellipsizing label (`a-tab-label` /
101
- `a-button-label`) inside the anchor, then the anchor itself; point it elsewhere with
102
- **`truncatedSelector`**. Hover both — only the clipped one reveals its full text:
133
+ One tooltip is open per document. A tooltip on a nested anchor takes precedence
134
+ while that anchor is active. Returning to the outer anchor makes its explanation
135
+ available again.
103
136
 
104
137
  ```tsx
105
- {/* Only the clipped span shows a tooltip. The anchor IS the clipping box here,
106
- so no selector is needed; inside a tab or <Button> the default finds the label. */}
107
- <span style={{ maxWidth: 130, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
108
- A long label that gets truncated
109
- <Tooltip truncatedOnly>A long label that gets truncated</Tooltip>
110
- </span>
138
+ <div style={{ display: 'flex', gap: '40px', alignItems: 'flex-start', flexWrap: 'wrap' }}>
139
+ <div style={{ display: 'flex', gap: '12px' }}>
140
+ <Button label="First"><Tooltip follow>First tooltip</Tooltip></Button>
141
+ <Button label="Second"><Tooltip follow>Second tooltip</Tooltip></Button>
142
+ </div>
143
+ <div tabIndex={0} aria-label="Outer box" style={{ padding: '20px', border: '1px dashed var(--border-4)', borderRadius: '6px', cursor: 'help' }}>
144
+ <span>Outer box</span>
145
+ <Tooltip follow>Outer tooltip</Tooltip>
146
+ <div style={{ marginTop: '12px' }}>
147
+ <Button label="Inner button"><Tooltip follow>Inner tooltip</Tooltip></Button>
148
+ </div>
149
+ </div>
150
+ </div>
111
151
  ```
112
152
 
113
- ### Empty tooltips
153
+ ## Content and shape
114
154
 
115
- A tooltip with nothing to show — no element children and no non-whitespace text —
116
- doesn't open, so `<Tooltip>{maybeEmpty}</Tooltip>` never flashes a blank bubble. This
117
- is automatic (no prop) and re-checked on each hover, so a tooltip whose content
118
- arrives later works normally; a bubble whose content is cleared while it's open
119
- closes itself. Content that's a single icon or image (an element, no text) still
120
- shows.
155
+ Content can include text, icons, and markup. An empty or whitespace-only tooltip
156
+ does not open. Clearing an open tooltip's content closes it; subsequent content
157
+ is available on the next interaction. Use `round` for a softer shape.
158
+
159
+ ```tsx
160
+ <Button label="Release status">
161
+ <Tooltip round><strong>Healthy</strong> · Checked two minutes ago</Tooltip>
162
+ </Button>
163
+ <Button icon="info" aria-label="Action details">
164
+ <Tooltip placement="top"><strong>Heads up</strong> · This action cannot be undone</Tooltip>
165
+ </Button>
166
+ <Button label="No explanation"><Tooltip>{''}</Tooltip></Button>
167
+ ```
121
168
 
122
169
  ## Component props
123
170
 
124
171
  | Prop | Type | Default | Description |
125
172
  |------|------|---------|-------------|
126
- | `children?` | ReactNode | — | Tooltip content. Renders anything — text, markup, an icon + text. Lives in the light DOM, so it's styleable with your own plain CSS. |
127
- | `delay?` | number | 300 | Show delay in milliseconds after hover / focus. Never use `0` — use ~`50` for a near-instant tooltip (0 has caused issues in practice). |
173
+ | `children?` | ReactNode | — | Supplementary text or markup. Content stays in light DOM for application CSS. |
174
+ | `delay?` | number | 300 | Wait in milliseconds after hover or keyboard focus. Use `50` for a short delay. |
128
175
  | `follow?` | boolean | — | Follow the cursor instead of pinning under the anchor. The bubble is pinned (anchored beneath the target) by default; pass `follow` for the cursor-tracking behavior, which fades by distance as the cursor leaves. |
129
- | `interactive?` | boolean | — | Make the bubble hoverable and clickable — enables pointer events and keeps it open while the cursor is over it, so its content (links, buttons) can be interacted with. Always pinned (an interactive bubble can't follow the cursor, even with `follow`). |
176
+ | `interactive?` | boolean | — | Keep content available while the pointer or keyboard focus is inside it. Enables pointer events and pins the bubble even with `follow`. Essential actions belong in a Menu or Dialog with an explicit trigger. |
130
177
  | `placement?` | 'top' \| 'bottom' \| 'left' | bottom | Which side of the anchor the bubble prefers. Auto-flips to the other side when there isn't room. |
131
178
  | `round?` | boolean \| number \| string | — | Round the bubble to a 20px radius (matching a round menu). Pass a `number` (px) or a CSS length string for a custom radius. |
132
179
  | `truncatedOnly?` | boolean | — | Only show when the target is actually truncated (its text overflows and is ellipsized); a label that fits gets no tooltip. The check is a UI-thread layout read, re-measured on each show. By default it measures every Anta ellipsizing label part inside the anchor, then the anchor itself — override with `truncatedSelector`. |
133
180
  | `truncatedSelector?` | string | — | CSS selector (resolved within the anchor) for the element or elements whose overflow decides whether a `truncatedOnly` tooltip shows. |
134
181
 
135
- ## Web Component
182
+ `truncatedOnly` measures the anchor's reported truncation or its `a-tab-label`,
183
+ `a-button-label`, and `a-step-hint` regions. `truncatedSelector` selects a different
184
+ measurement target. Measurements are refreshed when opening.
185
+
186
+ A custom numeric or length `round` prop emits an inline CSS variable. If your CSP
187
+ blocks style attributes, use external `::part(bubble)` CSS for a custom radius.
136
188
 
137
- Use the web component directly when you are not using React or Preact and a native control does not fit.
189
+ ## Web Component
138
190
 
139
- Place `<a-tooltip>` inside the element it describes.
191
+ Place `a-tooltip` directly inside its anchor. The author owns markup, styles,
192
+ accessible names, and descriptions. Tooltip does not add attributes
193
+ to its anchor or rewrite the supplied content.
140
194
 
141
195
  ```html
142
- <a-button role="button" tabindex="0" priority="secondary">
196
+ <a-button role="button" tabindex="0" aria-label="Publish" aria-description="Makes the draft public">
143
197
  <a-button-label>Publish</a-button-label>
144
- <a-tooltip>Make the draft public</a-tooltip>
198
+ <a-tooltip id="raw-publish-tooltip">Makes the draft public</a-tooltip>
145
199
  </a-button>
146
200
  ```
147
201
 
202
+ Referencing the Tooltip host with `aria-describedby` does not provide a reliable
203
+ description while its internal popover is hidden. Use an authored
204
+ `aria-description`, or reference separate application-owned descriptive content
205
+ that remains available to assistive technology.
206
+
207
+ Raw attributes include `delay`, `placement`, `round`, `follow`, `interactive`,
208
+ `truncated-only`, and `truncated-selector`. Boolean attributes use presence.
209
+ An anchor can implement `getAnchorRect(): DOMRect` to advertise a smaller
210
+ positioning region; Input reports its field instead of its label and hint.
211
+
212
+ Default styles load from the external component stylesheet. Under CSP, allow
213
+ that same-origin stylesheet and the browser entry. Runtime positioning updates
214
+ only Tooltip's owned shadow elements. Input and Menu also load their defaults
215
+ from external CSS. Custom values serialized into HTML style attributes remain
216
+ subject to the [CSP guidance](../install-config.md#content-security-policy).
217
+
218
+ Reduced motion disables both fades. Older supported browsers can omit parts of
219
+ the native popover transition while retaining the content and interaction.
220
+
148
221
  ## Styling
149
222
 
150
- The bubble lives in shadow DOM and is exposed as a single **part** — style the box
151
- (background, frost, shadow, radius, padding, a border) with `::part(bubble)`. Its
152
- *content* is slotted light DOM with a **normalized text baseline** (Anta body
153
- typography), so it ignores the anchor's styling; to restyle the text, put a class on
154
- the content you pass to `<Tooltip>` and target that (a rule on the content wins over
155
- the baseline). Both together — hover the button to see it; the classes are just for
156
- the demo:
223
+ Style the visible surface with `::part(bubble)`. Supplied content remains in light
224
+ DOM, so application selectors can style its text. `::part(container)` reaches
225
+ the outer popover and its opening/closing transition. Keep its positioning and
226
+ pointer behavior intact when changing appearance.
227
+
228
+ The classes below identify this demonstration; use your own selectors.
157
229
 
158
230
  ```css
159
- /* the bubble box — a shadow part */
160
- a-tooltip.fancy::part(bubble) {
231
+ a-tooltip.custom-tooltip::part(bubble) {
161
232
  background: #1a161d;
162
233
  border-radius: 10px;
163
234
  padding: 8px 12px;
164
- box-shadow: 0 4px 18px rgba(0, 0, 0, 0.35);
165
- backdrop-filter: none; /* opt out of the frost */
235
+ box-shadow: 0 4px 18px color-mix(in oklch, black 35%, transparent);
236
+ backdrop-filter: none;
237
+ }
238
+ .custom-tooltip-text {
239
+ color: #fff;
240
+ font-size: 15px;
241
+ font-weight: 600;
242
+ letter-spacing: 0.01em;
243
+ }
244
+ ```
245
+
246
+ ## Example
247
+
248
+ ```tsx
249
+ import { Tooltip, Button } from '@antadesign/anta'
250
+
251
+ function Demo() {
252
+ return (
253
+ <div className="container">
254
+ <Button label="Hover me">
255
+ <Tooltip delay={300}>Edit my props or code</Tooltip>
256
+ </Button>
257
+ </div>
258
+ )
166
259
  }
167
- /* the slotted content — a class on what you pass to <Tooltip> */
168
- .tip-rich { color: #fff; font-size: 15px; font-weight: 600; letter-spacing: 0.01em; }
169
260
  ```