@rcarls/rc-tooltip 0.0.0-next-20261020171337
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +62 -0
- package/README.md +79 -0
- package/dist/custom-elements.json +457 -0
- package/dist/rc-tooltip-_7Ftj7QB.js +137 -0
- package/dist/rc-tooltip-_7Ftj7QB.js.map +1 -0
- package/dist/rc-tooltip-define.js +6 -0
- package/dist/rc-tooltip-define.js.map +1 -0
- package/dist/rc-tooltip.js +5 -0
- package/dist/rc-tooltip.js.map +1 -0
- package/dist/types/packages/rc-tooltip/src/define.d.ts +1 -0
- package/dist/types/packages/rc-tooltip/src/index.d.ts +2 -0
- package/dist/types/packages/rc-tooltip/src/rc-tooltip.d.ts +85 -0
- package/dist/types/packages/rc-tooltip/src/rc-tooltip.styles.d.ts +2 -0
- package/package.json +65 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## 0.0.0-next-20261020171337
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 182fcfd: Add `rc-tooltip`, a WAI-ARIA Tooltip wrapper with Popover API enhancement and a positioned fallback.
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- 1179f24: Drop the `@oddbird/css-anchor-positioning` polyfill. Browsers without full
|
|
12
|
+
native anchor positioning now use `AnchorController`'s script positioning,
|
|
13
|
+
which applies the same placement and flip rules and re-positions when the page
|
|
14
|
+
scrolls or the viewport, anchor, or floating element resizes. Those browsers no
|
|
15
|
+
longer download the 41 kB polyfill the first time a popup opens.
|
|
16
|
+
- 5c006de: Ship component CSS minified. Package builds now run the CSS in Lit `css` styles
|
|
17
|
+
and light-DOM structural styles through Lightning CSS, removing comments and
|
|
18
|
+
whitespace while keeping source maps that resolve to each template. Rendered
|
|
19
|
+
styles are unchanged.
|
|
20
|
+
|
|
21
|
+
`@rcarls/rc-common` adds `cssText`, an identity tag that marks a plain CSS
|
|
22
|
+
string for minification. `rc-chip`, `rc-disclosure`, and `rc-accordion` now
|
|
23
|
+
depend on `@rcarls/rc-common` for it.
|
|
24
|
+
|
|
25
|
+
- f1ca82d: Add an anchored, non-modal popover package with a Material rich-tooltip recipe. Share native Popover API visibility and fallback behavior across existing popup components.
|
|
26
|
+
- 622a4f8: Theme popovers and tooltips through the shared token layers. `rc-popover` now
|
|
27
|
+
reads the shared `--rc-popup-*` surface tokens before its own fallbacks, like
|
|
28
|
+
menus and listboxes, and `rc-tooltip` takes its default corner from
|
|
29
|
+
`--rc-radius-sm`. The Material theme sets its popover and tooltip tokens on the
|
|
30
|
+
theme root, so surfaces inside other shadow roots inherit them, and the
|
|
31
|
+
Substrate theme adds popover and tooltip styles.
|
|
32
|
+
- Updated dependencies [e3dfa59]
|
|
33
|
+
- Updated dependencies [50d5610]
|
|
34
|
+
- Updated dependencies [9ee769c]
|
|
35
|
+
- Updated dependencies [1179f24]
|
|
36
|
+
- Updated dependencies [38cd00c]
|
|
37
|
+
- Updated dependencies [5c006de]
|
|
38
|
+
- Updated dependencies [a6553ff]
|
|
39
|
+
- Updated dependencies [2205478]
|
|
40
|
+
- Updated dependencies [4341311]
|
|
41
|
+
- Updated dependencies [899bb5e]
|
|
42
|
+
- Updated dependencies [25fcfe0]
|
|
43
|
+
- Updated dependencies [51f6403]
|
|
44
|
+
- Updated dependencies [9caca6b]
|
|
45
|
+
- Updated dependencies [b9175e9]
|
|
46
|
+
- Updated dependencies [f7f0270]
|
|
47
|
+
- Updated dependencies [f1ca82d]
|
|
48
|
+
- Updated dependencies [b87f27b]
|
|
49
|
+
- Updated dependencies [32ebead]
|
|
50
|
+
- Updated dependencies [bfefedd]
|
|
51
|
+
- Updated dependencies [c130173]
|
|
52
|
+
- Updated dependencies [11680b6]
|
|
53
|
+
- Updated dependencies [223d36c]
|
|
54
|
+
- Updated dependencies [7b91a44]
|
|
55
|
+
- Updated dependencies [aa04ead]
|
|
56
|
+
- Updated dependencies [afcfef8]
|
|
57
|
+
- Updated dependencies [11ef1ad]
|
|
58
|
+
- @rcarls/rc-common@0.0.0-next-20261020171337
|
|
59
|
+
|
|
60
|
+
## 0.6.0
|
|
61
|
+
|
|
62
|
+
- Add `rc-tooltip`, a Popover API tooltip wrapper with an anchored fallback.
|
package/README.md
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# `@rcarls/rc-tooltip`
|
|
2
|
+
|
|
3
|
+
Tooltip wrapper for a consumer-owned trigger and descriptive content, following
|
|
4
|
+
the [WAI-ARIA Tooltip pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/).
|
|
5
|
+
|
|
6
|
+
Docs: [https://richardcarls.github.io/rc-webcomponents/components/rc-tooltip](https://richardcarls.github.io/rc-webcomponents/components/rc-tooltip).
|
|
7
|
+
|
|
8
|
+
## Installation
|
|
9
|
+
|
|
10
|
+
```sh
|
|
11
|
+
npm install @rcarls/rc-tooltip
|
|
12
|
+
```
|
|
13
|
+
|
|
14
|
+
## Import
|
|
15
|
+
|
|
16
|
+
```js
|
|
17
|
+
import '@rcarls/rc-tooltip/define';
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
Put the trigger in the `trigger` slot and one descriptive element in the
|
|
23
|
+
`content` slot:
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<rc-tooltip placement="block-end">
|
|
27
|
+
<button slot="trigger">Save</button>
|
|
28
|
+
<span slot="content">Saves the current document.</span>
|
|
29
|
+
</rc-tooltip>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
The component adds a stable `id` and `role="tooltip"` to the content and
|
|
33
|
+
adds that ID to the trigger's `aria-describedby` list. The content is shown
|
|
34
|
+
when the trigger receives focus or the pointer enters the trigger, stays open
|
|
35
|
+
while the pointer is over the trigger or content, and closes when Escape is
|
|
36
|
+
pressed or both leave. Tooltip content is descriptive only and must not hold
|
|
37
|
+
interactive controls or receive focus.
|
|
38
|
+
|
|
39
|
+
The native Popover API is used when available. Browsers without a working
|
|
40
|
+
Popover API use the same interaction and the `hidden` attribute as a fallback;
|
|
41
|
+
positioning uses the shared `AnchorController` with logical placement and
|
|
42
|
+
viewport clamping.
|
|
43
|
+
|
|
44
|
+
## API
|
|
45
|
+
|
|
46
|
+
| Property | Attribute | Type | Default | Description |
|
|
47
|
+
| ------------------- | ----------- | ----------------- | ----------- | ---------------------------------------------------- |
|
|
48
|
+
| `placement` | `placement` | `AnchorPlacement` | `block-end` | Preferred logical placement relative to the trigger. |
|
|
49
|
+
| _(read-only state)_ | `open` | boolean attribute | absent | Set by the component while the tooltip is visible. |
|
|
50
|
+
|
|
51
|
+
### Slots
|
|
52
|
+
|
|
53
|
+
| Slot | Description |
|
|
54
|
+
| ----------- | ------------------------------------------------------- |
|
|
55
|
+
| `trigger` | Consumer-owned focusable trigger element. |
|
|
56
|
+
| `content` | One consumer-owned element containing descriptive text. |
|
|
57
|
+
| _(default)_ | Fallback content slot when `content` is omitted. |
|
|
58
|
+
|
|
59
|
+
### CSS custom properties
|
|
60
|
+
|
|
61
|
+
| Property | Default | Description |
|
|
62
|
+
| ------------------------------ | ---------------------- | ---------------------------- |
|
|
63
|
+
| `--rc-tooltip-max-inline-size` | `20rem` | Maximum tooltip inline size. |
|
|
64
|
+
| `--rc-tooltip-padding-block` | `0.25em` | Block-axis padding. |
|
|
65
|
+
| `--rc-tooltip-padding-inline` | `0.5em` | Inline-axis padding. |
|
|
66
|
+
| `--rc-tooltip-border` | `1px solid CanvasText` | Tooltip border. |
|
|
67
|
+
| `--rc-tooltip-radius` | `var(--rc-radius-sm)` | Tooltip corner radius. |
|
|
68
|
+
| `--rc-tooltip-background` | `CanvasText` | Tooltip background. |
|
|
69
|
+
| `--rc-tooltip-color` | `Canvas` | Tooltip text color. |
|
|
70
|
+
| `--rc-tooltip-shadow` | `none` | Tooltip shadow. |
|
|
71
|
+
| `--rc-tooltip-font` | `inherit` | Tooltip font. |
|
|
72
|
+
| `--rc-tooltip-line-height` | `normal` | Tooltip line height. |
|
|
73
|
+
| `--rc-tooltip-z-index` | `1` | Fallback stacking order. |
|
|
74
|
+
|
|
75
|
+
### CSS parts
|
|
76
|
+
|
|
77
|
+
| Part | Description |
|
|
78
|
+
| ------ | ---------------------------------------- |
|
|
79
|
+
| `root` | Shadow-DOM wrapper containing the slots. |
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": "1.0.0",
|
|
3
|
+
"readme": "",
|
|
4
|
+
"modules": [
|
|
5
|
+
{
|
|
6
|
+
"kind": "javascript-module",
|
|
7
|
+
"path": "src/define.ts",
|
|
8
|
+
"declarations": [],
|
|
9
|
+
"exports": [
|
|
10
|
+
{
|
|
11
|
+
"kind": "custom-element-definition",
|
|
12
|
+
"name": "rc-tooltip",
|
|
13
|
+
"declaration": {
|
|
14
|
+
"name": "RCTooltip",
|
|
15
|
+
"module": "/src/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"kind": "js",
|
|
20
|
+
"name": "*",
|
|
21
|
+
"declaration": {
|
|
22
|
+
"name": "*",
|
|
23
|
+
"module": "src/index.js"
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
]
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
"kind": "javascript-module",
|
|
30
|
+
"path": "src/index.ts",
|
|
31
|
+
"declarations": [],
|
|
32
|
+
"exports": [
|
|
33
|
+
{
|
|
34
|
+
"kind": "js",
|
|
35
|
+
"name": "RCTooltip",
|
|
36
|
+
"declaration": {
|
|
37
|
+
"name": "default",
|
|
38
|
+
"module": "./rc-tooltip.js"
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
{
|
|
42
|
+
"kind": "js",
|
|
43
|
+
"name": "RCTooltipPlacement",
|
|
44
|
+
"declaration": {
|
|
45
|
+
"name": "RCTooltipPlacement",
|
|
46
|
+
"module": "./rc-tooltip.js"
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
]
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
"kind": "javascript-module",
|
|
53
|
+
"path": "src/rc-tooltip.ts",
|
|
54
|
+
"declarations": [
|
|
55
|
+
{
|
|
56
|
+
"kind": "class",
|
|
57
|
+
"description": "Tooltip wrapper for a consumer-owned trigger and descriptive content,\nfollowing the [WAI-ARIA Tooltip pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/).\nThe trigger remains in light DOM and receives `aria-describedby`; the\ncontent remains in light DOM so the ID relationship works across browsers.\n\nThe native Popover API is used when the supplied content supports it. Older\nbrowsers use the same focus, pointer, Escape, and anchor positioning logic\nwith an explicit visibility fallback. Tooltip content is descriptive and\nmust not contain interactive controls or receive focus.",
|
|
58
|
+
"name": "RCTooltip",
|
|
59
|
+
"cssProperties": [
|
|
60
|
+
{
|
|
61
|
+
"description": "Maximum inline size of the tooltip content.",
|
|
62
|
+
"name": "--rc-tooltip-max-inline-size",
|
|
63
|
+
"default": "20rem"
|
|
64
|
+
},
|
|
65
|
+
{
|
|
66
|
+
"description": "Tooltip block-axis padding.",
|
|
67
|
+
"name": "--rc-tooltip-padding-block",
|
|
68
|
+
"default": "0.25em"
|
|
69
|
+
},
|
|
70
|
+
{
|
|
71
|
+
"description": "Tooltip inline-axis padding.",
|
|
72
|
+
"name": "--rc-tooltip-padding-inline",
|
|
73
|
+
"default": "0.5em"
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
"description": "Tooltip border.",
|
|
77
|
+
"name": "--rc-tooltip-border",
|
|
78
|
+
"default": "1px solid CanvasText"
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
"description": "Tooltip corner radius.",
|
|
82
|
+
"name": "--rc-tooltip-radius",
|
|
83
|
+
"default": "var(--rc-radius-sm)"
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
"description": "Tooltip background.",
|
|
87
|
+
"name": "--rc-tooltip-background",
|
|
88
|
+
"default": "CanvasText"
|
|
89
|
+
},
|
|
90
|
+
{
|
|
91
|
+
"description": "Tooltip text color.",
|
|
92
|
+
"name": "--rc-tooltip-color",
|
|
93
|
+
"default": "Canvas"
|
|
94
|
+
},
|
|
95
|
+
{
|
|
96
|
+
"description": "Tooltip shadow.",
|
|
97
|
+
"name": "--rc-tooltip-shadow",
|
|
98
|
+
"default": "none"
|
|
99
|
+
},
|
|
100
|
+
{
|
|
101
|
+
"description": "Tooltip font.",
|
|
102
|
+
"name": "--rc-tooltip-font",
|
|
103
|
+
"default": "inherit"
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
"description": "Tooltip line height.",
|
|
107
|
+
"name": "--rc-tooltip-line-height",
|
|
108
|
+
"default": "normal"
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
"description": "Tooltip stacking order in the fallback mode.",
|
|
112
|
+
"name": "--rc-tooltip-z-index",
|
|
113
|
+
"default": "1"
|
|
114
|
+
}
|
|
115
|
+
],
|
|
116
|
+
"cssParts": [
|
|
117
|
+
{
|
|
118
|
+
"description": "The shadow-DOM wrapper containing the two slots.",
|
|
119
|
+
"name": "root"
|
|
120
|
+
}
|
|
121
|
+
],
|
|
122
|
+
"slots": [
|
|
123
|
+
{
|
|
124
|
+
"description": "The consumer-owned element that receives focus and hover behavior.",
|
|
125
|
+
"name": "trigger"
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
"description": "The single consumer-owned element containing the tooltip text.",
|
|
129
|
+
"name": "content"
|
|
130
|
+
},
|
|
131
|
+
{
|
|
132
|
+
"description": "A fallback content slot when `content` is omitted.",
|
|
133
|
+
"name": "default"
|
|
134
|
+
}
|
|
135
|
+
],
|
|
136
|
+
"members": [
|
|
137
|
+
{
|
|
138
|
+
"kind": "field",
|
|
139
|
+
"name": "_styledRoots",
|
|
140
|
+
"privacy": "private",
|
|
141
|
+
"static": true,
|
|
142
|
+
"readonly": true,
|
|
143
|
+
"default": "new WeakSet<Document | ShadowRoot>()"
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
"kind": "field",
|
|
147
|
+
"name": "placement",
|
|
148
|
+
"type": {
|
|
149
|
+
"text": "RCTooltipPlacement"
|
|
150
|
+
},
|
|
151
|
+
"default": "'block-end'",
|
|
152
|
+
"description": "Preferred logical placement relative to the trigger.",
|
|
153
|
+
"attribute": "placement"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"kind": "field",
|
|
157
|
+
"name": "_$triggerSlot",
|
|
158
|
+
"type": {
|
|
159
|
+
"text": "HTMLSlotElement"
|
|
160
|
+
},
|
|
161
|
+
"privacy": "private"
|
|
162
|
+
},
|
|
163
|
+
{
|
|
164
|
+
"kind": "field",
|
|
165
|
+
"name": "_$contentSlot",
|
|
166
|
+
"type": {
|
|
167
|
+
"text": "HTMLSlotElement"
|
|
168
|
+
},
|
|
169
|
+
"privacy": "private"
|
|
170
|
+
},
|
|
171
|
+
{
|
|
172
|
+
"kind": "field",
|
|
173
|
+
"name": "_$defaultSlot",
|
|
174
|
+
"type": {
|
|
175
|
+
"text": "HTMLSlotElement"
|
|
176
|
+
},
|
|
177
|
+
"privacy": "private"
|
|
178
|
+
},
|
|
179
|
+
{
|
|
180
|
+
"kind": "field",
|
|
181
|
+
"name": "_$trigger",
|
|
182
|
+
"type": {
|
|
183
|
+
"text": "HTMLElement | null"
|
|
184
|
+
},
|
|
185
|
+
"privacy": "private",
|
|
186
|
+
"default": "null"
|
|
187
|
+
},
|
|
188
|
+
{
|
|
189
|
+
"kind": "field",
|
|
190
|
+
"name": "_$content",
|
|
191
|
+
"type": {
|
|
192
|
+
"text": "HTMLElement | null"
|
|
193
|
+
},
|
|
194
|
+
"privacy": "private",
|
|
195
|
+
"default": "null"
|
|
196
|
+
},
|
|
197
|
+
{
|
|
198
|
+
"kind": "field",
|
|
199
|
+
"name": "_contentState",
|
|
200
|
+
"type": {
|
|
201
|
+
"text": "ContentState | null"
|
|
202
|
+
},
|
|
203
|
+
"privacy": "private",
|
|
204
|
+
"default": "null"
|
|
205
|
+
},
|
|
206
|
+
{
|
|
207
|
+
"kind": "field",
|
|
208
|
+
"name": "_triggerDescribedBy",
|
|
209
|
+
"type": {
|
|
210
|
+
"text": "string | null"
|
|
211
|
+
},
|
|
212
|
+
"privacy": "private",
|
|
213
|
+
"default": "null"
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
"kind": "field",
|
|
217
|
+
"name": "_visible",
|
|
218
|
+
"type": {
|
|
219
|
+
"text": "boolean"
|
|
220
|
+
},
|
|
221
|
+
"privacy": "private",
|
|
222
|
+
"default": "false"
|
|
223
|
+
},
|
|
224
|
+
{
|
|
225
|
+
"kind": "field",
|
|
226
|
+
"name": "_focusWithin",
|
|
227
|
+
"type": {
|
|
228
|
+
"text": "boolean"
|
|
229
|
+
},
|
|
230
|
+
"privacy": "private",
|
|
231
|
+
"default": "false"
|
|
232
|
+
},
|
|
233
|
+
{
|
|
234
|
+
"kind": "field",
|
|
235
|
+
"name": "_pointerWithin",
|
|
236
|
+
"type": {
|
|
237
|
+
"text": "boolean"
|
|
238
|
+
},
|
|
239
|
+
"privacy": "private",
|
|
240
|
+
"default": "false"
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
"kind": "field",
|
|
244
|
+
"name": "_dismissedByEscape",
|
|
245
|
+
"type": {
|
|
246
|
+
"text": "boolean"
|
|
247
|
+
},
|
|
248
|
+
"privacy": "private",
|
|
249
|
+
"default": "false"
|
|
250
|
+
},
|
|
251
|
+
{
|
|
252
|
+
"kind": "field",
|
|
253
|
+
"name": "_slotSyncQueued",
|
|
254
|
+
"type": {
|
|
255
|
+
"text": "boolean"
|
|
256
|
+
},
|
|
257
|
+
"privacy": "private",
|
|
258
|
+
"default": "false"
|
|
259
|
+
},
|
|
260
|
+
{
|
|
261
|
+
"kind": "field",
|
|
262
|
+
"name": "_anchor",
|
|
263
|
+
"privacy": "private",
|
|
264
|
+
"readonly": true,
|
|
265
|
+
"default": "new AnchorController(this, { anchor: () => this._$trigger, floating: () => this._$content, placement: this.placement, offset: 4, disabled: () => !this._visible, })"
|
|
266
|
+
},
|
|
267
|
+
{
|
|
268
|
+
"kind": "field",
|
|
269
|
+
"name": "_popover",
|
|
270
|
+
"privacy": "private",
|
|
271
|
+
"readonly": true,
|
|
272
|
+
"default": "new PopoverController(this, { element: () => this._$content })"
|
|
273
|
+
},
|
|
274
|
+
{
|
|
275
|
+
"kind": "method",
|
|
276
|
+
"name": "_ensureBaseStyles",
|
|
277
|
+
"privacy": "private",
|
|
278
|
+
"static": true,
|
|
279
|
+
"return": {
|
|
280
|
+
"type": {
|
|
281
|
+
"text": "void"
|
|
282
|
+
}
|
|
283
|
+
},
|
|
284
|
+
"parameters": [
|
|
285
|
+
{
|
|
286
|
+
"name": "root",
|
|
287
|
+
"type": {
|
|
288
|
+
"text": "Document | ShadowRoot"
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
]
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
"kind": "field",
|
|
295
|
+
"name": "_onSlotChange",
|
|
296
|
+
"privacy": "private"
|
|
297
|
+
},
|
|
298
|
+
{
|
|
299
|
+
"kind": "method",
|
|
300
|
+
"name": "_queueSlotSync",
|
|
301
|
+
"privacy": "private",
|
|
302
|
+
"return": {
|
|
303
|
+
"type": {
|
|
304
|
+
"text": "void"
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
},
|
|
308
|
+
{
|
|
309
|
+
"kind": "method",
|
|
310
|
+
"name": "_syncSlots",
|
|
311
|
+
"privacy": "private",
|
|
312
|
+
"return": {
|
|
313
|
+
"type": {
|
|
314
|
+
"text": "void"
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
},
|
|
318
|
+
{
|
|
319
|
+
"kind": "method",
|
|
320
|
+
"name": "_applyContentSemantics",
|
|
321
|
+
"privacy": "private",
|
|
322
|
+
"return": {
|
|
323
|
+
"type": {
|
|
324
|
+
"text": "void"
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
{
|
|
329
|
+
"kind": "method",
|
|
330
|
+
"name": "_syncTriggerDescription",
|
|
331
|
+
"privacy": "private",
|
|
332
|
+
"return": {
|
|
333
|
+
"type": {
|
|
334
|
+
"text": "void"
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
},
|
|
338
|
+
{
|
|
339
|
+
"kind": "method",
|
|
340
|
+
"name": "_restoreTrigger",
|
|
341
|
+
"privacy": "private",
|
|
342
|
+
"return": {
|
|
343
|
+
"type": {
|
|
344
|
+
"text": "void"
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
{
|
|
349
|
+
"kind": "method",
|
|
350
|
+
"name": "_restoreContent",
|
|
351
|
+
"privacy": "private",
|
|
352
|
+
"return": {
|
|
353
|
+
"type": {
|
|
354
|
+
"text": "void"
|
|
355
|
+
}
|
|
356
|
+
}
|
|
357
|
+
},
|
|
358
|
+
{
|
|
359
|
+
"kind": "field",
|
|
360
|
+
"name": "_onFocusIn",
|
|
361
|
+
"privacy": "private"
|
|
362
|
+
},
|
|
363
|
+
{
|
|
364
|
+
"kind": "field",
|
|
365
|
+
"name": "_onFocusOut",
|
|
366
|
+
"privacy": "private"
|
|
367
|
+
},
|
|
368
|
+
{
|
|
369
|
+
"kind": "field",
|
|
370
|
+
"name": "_onPointerOver",
|
|
371
|
+
"privacy": "private"
|
|
372
|
+
},
|
|
373
|
+
{
|
|
374
|
+
"kind": "field",
|
|
375
|
+
"name": "_onPointerOut",
|
|
376
|
+
"privacy": "private"
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
"kind": "field",
|
|
380
|
+
"name": "_onKeyDown",
|
|
381
|
+
"privacy": "private"
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
"kind": "method",
|
|
385
|
+
"name": "_syncVisibility",
|
|
386
|
+
"privacy": "private",
|
|
387
|
+
"return": {
|
|
388
|
+
"type": {
|
|
389
|
+
"text": "void"
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
},
|
|
393
|
+
{
|
|
394
|
+
"kind": "method",
|
|
395
|
+
"name": "_openTooltip",
|
|
396
|
+
"privacy": "private",
|
|
397
|
+
"return": {
|
|
398
|
+
"type": {
|
|
399
|
+
"text": "void"
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
},
|
|
403
|
+
{
|
|
404
|
+
"kind": "method",
|
|
405
|
+
"name": "_closeTooltip",
|
|
406
|
+
"privacy": "private",
|
|
407
|
+
"return": {
|
|
408
|
+
"type": {
|
|
409
|
+
"text": "void"
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
],
|
|
414
|
+
"attributes": [
|
|
415
|
+
{
|
|
416
|
+
"description": "Preferred logical placement relative to the trigger.",
|
|
417
|
+
"name": "placement",
|
|
418
|
+
"type": {
|
|
419
|
+
"text": "RCTooltipPlacement"
|
|
420
|
+
},
|
|
421
|
+
"default": "'block-end'",
|
|
422
|
+
"fieldName": "placement"
|
|
423
|
+
},
|
|
424
|
+
{
|
|
425
|
+
"description": "Reflects the tooltip's visible state; set by the component.",
|
|
426
|
+
"name": "open"
|
|
427
|
+
}
|
|
428
|
+
],
|
|
429
|
+
"superclass": {
|
|
430
|
+
"name": "LitElement",
|
|
431
|
+
"package": "lit"
|
|
432
|
+
},
|
|
433
|
+
"tagName": "rc-tooltip",
|
|
434
|
+
"customElement": true
|
|
435
|
+
}
|
|
436
|
+
],
|
|
437
|
+
"exports": [
|
|
438
|
+
{
|
|
439
|
+
"kind": "js",
|
|
440
|
+
"name": "RCTooltip",
|
|
441
|
+
"declaration": {
|
|
442
|
+
"name": "RCTooltip",
|
|
443
|
+
"module": "src/rc-tooltip.ts"
|
|
444
|
+
}
|
|
445
|
+
},
|
|
446
|
+
{
|
|
447
|
+
"kind": "js",
|
|
448
|
+
"name": "default",
|
|
449
|
+
"declaration": {
|
|
450
|
+
"name": "RCTooltip",
|
|
451
|
+
"module": "src/rc-tooltip.ts"
|
|
452
|
+
}
|
|
453
|
+
}
|
|
454
|
+
]
|
|
455
|
+
}
|
|
456
|
+
]
|
|
457
|
+
}
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { css as d, LitElement as _, html as p } from "lit";
|
|
2
|
+
import { property as u, query as a } from "lit/decorators.js";
|
|
3
|
+
import { AnchorController as g, PopoverController as f, cssText as b } from "@rcarls/rc-common";
|
|
4
|
+
const y = d`:host{color-scheme:inherit;display:inline-block}[part=root]{display:inline-block}@media (forced-colors:active){slot[name=content]::slotted(*){color:canvas;background:canvastext;border-color:canvastext}}`;
|
|
5
|
+
var m = Object.defineProperty, r = (c, t, e, i) => {
|
|
6
|
+
for (var s = void 0, l = c.length - 1, h; l >= 0; l--)
|
|
7
|
+
(h = c[l]) && (s = h(t, e, s) || s);
|
|
8
|
+
return s && m(t, e, s), s;
|
|
9
|
+
};
|
|
10
|
+
let v = 0;
|
|
11
|
+
const S = b`@layer rc-base{rc-tooltip>[slot=content],rc-tooltip>:not([slot]){box-sizing:border-box;max-inline-size:var(--rc-tooltip-max-inline-size,20rem);padding-block:var(--rc-tooltip-padding-block,.25em);padding-inline:var(--rc-tooltip-padding-inline,.5em);border:var(--rc-tooltip-border,1px solid CanvasText);border-radius:var(--rc-tooltip-radius,var(--rc-radius-sm,.125em));background:var(--rc-tooltip-background,CanvasText);color:var(--rc-tooltip-color,Canvas);box-shadow:var(--rc-tooltip-shadow,none);font:var(--rc-tooltip-font,inherit);line-height:var(--rc-tooltip-line-height,normal);overflow-wrap:anywhere;pointer-events:auto;z-index:var(--rc-tooltip-z-index,1);display:block;position:fixed}rc-tooltip>[slot=content][hidden],rc-tooltip>:not([slot])[hidden]{display:none!important}}`;
|
|
12
|
+
var n;
|
|
13
|
+
const o = (n = class extends _ {
|
|
14
|
+
constructor() {
|
|
15
|
+
super(...arguments), this.placement = "block-end", this._$trigger = null, this._$content = null, this._contentState = null, this._triggerDescribedBy = null, this._visible = !1, this._focusWithin = !1, this._pointerWithin = !1, this._dismissedByEscape = !1, this._slotSyncQueued = !1, this._anchor = new g(this, {
|
|
16
|
+
anchor: () => this._$trigger,
|
|
17
|
+
floating: () => this._$content,
|
|
18
|
+
placement: this.placement,
|
|
19
|
+
offset: 4,
|
|
20
|
+
disabled: () => !this._visible
|
|
21
|
+
}), this._popover = new f(this, { element: () => this._$content }), this._onSlotChange = () => {
|
|
22
|
+
this._queueSlotSync();
|
|
23
|
+
}, this._onFocusIn = (t) => {
|
|
24
|
+
this._$trigger && t.composedPath().includes(this._$trigger) && (this._focusWithin = !0, this._syncVisibility());
|
|
25
|
+
}, this._onFocusOut = (t) => {
|
|
26
|
+
const e = t.relatedTarget;
|
|
27
|
+
e instanceof Node && this.contains(e) || this._$trigger && t.composedPath().includes(this._$trigger) && (this._focusWithin = !1, this._dismissedByEscape = !1, this._syncVisibility());
|
|
28
|
+
}, this._onPointerOver = (t) => {
|
|
29
|
+
if (t.pointerType === "touch")
|
|
30
|
+
return;
|
|
31
|
+
const e = t.composedPath();
|
|
32
|
+
(this._$trigger && e.includes(this._$trigger) || this._$content && e.includes(this._$content)) && (this._pointerWithin = !0, this._dismissedByEscape = !1, this._syncVisibility());
|
|
33
|
+
}, this._onPointerOut = (t) => {
|
|
34
|
+
if (t.pointerType === "touch")
|
|
35
|
+
return;
|
|
36
|
+
const e = t.relatedTarget;
|
|
37
|
+
if (e instanceof Node && this.contains(e))
|
|
38
|
+
return;
|
|
39
|
+
const i = t.composedPath();
|
|
40
|
+
(this._$trigger && i.includes(this._$trigger) || this._$content && i.includes(this._$content)) && (this._pointerWithin = !1, this._syncVisibility());
|
|
41
|
+
}, this._onKeyDown = (t) => {
|
|
42
|
+
t.key !== "Escape" || !this._visible || (t.stopPropagation(), this._dismissedByEscape = !0, this._focusWithin = !1, this._pointerWithin = !1, this._closeTooltip());
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
connectedCallback() {
|
|
46
|
+
super.connectedCallback(), n._ensureBaseStyles(this.getRootNode()), this.addEventListener("focusin", this._onFocusIn), this.addEventListener("focusout", this._onFocusOut), this.addEventListener("pointerover", this._onPointerOver), this.addEventListener("pointerout", this._onPointerOut), this.addEventListener("keydown", this._onKeyDown), this.hasUpdated && this._queueSlotSync();
|
|
47
|
+
}
|
|
48
|
+
disconnectedCallback() {
|
|
49
|
+
this.removeEventListener("focusin", this._onFocusIn), this.removeEventListener("focusout", this._onFocusOut), this.removeEventListener("pointerover", this._onPointerOver), this.removeEventListener("pointerout", this._onPointerOut), this.removeEventListener("keydown", this._onKeyDown), this._focusWithin = !1, this._pointerWithin = !1, this._dismissedByEscape = !1, this._closeTooltip(), this._restoreTrigger(), this._restoreContent(), this._$trigger = null, this._$content = null, super.disconnectedCallback();
|
|
50
|
+
}
|
|
51
|
+
firstUpdated() {
|
|
52
|
+
this._queueSlotSync();
|
|
53
|
+
}
|
|
54
|
+
updated(t) {
|
|
55
|
+
t.has("placement") && this._anchor.setOptions({ placement: this.placement });
|
|
56
|
+
}
|
|
57
|
+
render() {
|
|
58
|
+
return p`
|
|
59
|
+
<div id="root" part="root">
|
|
60
|
+
<slot name="trigger" @slotchange=${this._onSlotChange}></slot>
|
|
61
|
+
<slot name="content" @slotchange=${this._onSlotChange}></slot>
|
|
62
|
+
<slot @slotchange=${this._onSlotChange}></slot>
|
|
63
|
+
</div>
|
|
64
|
+
`;
|
|
65
|
+
}
|
|
66
|
+
static _ensureBaseStyles(t) {
|
|
67
|
+
if (n._styledRoots.has(t))
|
|
68
|
+
return;
|
|
69
|
+
n._styledRoots.add(t);
|
|
70
|
+
const e = (t instanceof Document ? t : t.ownerDocument).createElement("style");
|
|
71
|
+
e.setAttribute("data-rc-light-dom-base", "rc-tooltip"), e.textContent = S, t instanceof Document ? t.head.append(e) : t.append(e);
|
|
72
|
+
}
|
|
73
|
+
_queueSlotSync() {
|
|
74
|
+
this._slotSyncQueued || (this._slotSyncQueued = !0, queueMicrotask(() => {
|
|
75
|
+
this._slotSyncQueued = !1, this.isConnected && this._syncSlots();
|
|
76
|
+
}));
|
|
77
|
+
}
|
|
78
|
+
_syncSlots() {
|
|
79
|
+
const t = this._$triggerSlot?.assignedElements({ flatten: !0 }).find((i) => i instanceof HTMLElement) ?? null, e = this._$contentSlot?.assignedElements({ flatten: !0 }).find((i) => i instanceof HTMLElement) ?? this._$defaultSlot?.assignedElements({ flatten: !0 }).find((i) => i instanceof HTMLElement) ?? null;
|
|
80
|
+
e !== this._$content && (this._closeTooltip(), this._restoreTrigger(), this._restoreContent(), this._$content = e, this._contentState = null, this._applyContentSemantics()), t !== this._$trigger && (this._restoreTrigger(), this._$trigger = t, this._triggerDescribedBy = null), this._applyContentSemantics(), this._syncTriggerDescription(), this._syncVisibility(), this._visible && this._anchor.update();
|
|
81
|
+
}
|
|
82
|
+
_applyContentSemantics() {
|
|
83
|
+
const t = this._$content;
|
|
84
|
+
t && (this._contentState || (this._contentState = {
|
|
85
|
+
id: t.getAttribute("id"),
|
|
86
|
+
role: t.getAttribute("role"),
|
|
87
|
+
ariaHidden: t.getAttribute("aria-hidden"),
|
|
88
|
+
popover: t.getAttribute("popover"),
|
|
89
|
+
hidden: t.hidden
|
|
90
|
+
}), t.id || (t.id = `rc-tooltip-${++v}`), t.setAttribute("role", "tooltip"), t.setAttribute("popover", "manual"), t.toggleAttribute("hidden", !this._visible), t.setAttribute("aria-hidden", String(!this._visible)));
|
|
91
|
+
}
|
|
92
|
+
_syncTriggerDescription() {
|
|
93
|
+
const t = this._$trigger, e = this._$content;
|
|
94
|
+
if (!t || !e?.id)
|
|
95
|
+
return;
|
|
96
|
+
const i = t.getAttribute("aria-describedby");
|
|
97
|
+
this._triggerDescribedBy === null && (this._triggerDescribedBy = i);
|
|
98
|
+
const s = new Set((i ?? "").split(/\s+/).filter(Boolean));
|
|
99
|
+
s.has(e.id) || s.add(e.id), t.setAttribute("aria-describedby", Array.from(s).join(" "));
|
|
100
|
+
}
|
|
101
|
+
_restoreTrigger() {
|
|
102
|
+
!this._$trigger || this._triggerDescribedBy === null || (this._triggerDescribedBy === "" ? this._$trigger.removeAttribute("aria-describedby") : this._$trigger.setAttribute("aria-describedby", this._triggerDescribedBy), this._triggerDescribedBy = null);
|
|
103
|
+
}
|
|
104
|
+
_restoreContent() {
|
|
105
|
+
const t = this._$content, e = this._contentState;
|
|
106
|
+
!t || !e || (this._popover.sync(!1), e.id === null ? t.removeAttribute("id") : t.setAttribute("id", e.id), e.role === null ? t.removeAttribute("role") : t.setAttribute("role", e.role), e.ariaHidden === null ? t.removeAttribute("aria-hidden") : t.setAttribute("aria-hidden", e.ariaHidden), e.popover === null ? t.removeAttribute("popover") : t.setAttribute("popover", e.popover), t.hidden = e.hidden, this._contentState = null);
|
|
107
|
+
}
|
|
108
|
+
_syncVisibility() {
|
|
109
|
+
const t = !this._dismissedByEscape && (this._focusWithin || this._pointerWithin) && !!this._$content;
|
|
110
|
+
t !== this._visible && (t ? this._openTooltip() : this._closeTooltip());
|
|
111
|
+
}
|
|
112
|
+
_openTooltip() {
|
|
113
|
+
const t = this._$content;
|
|
114
|
+
t && (this._visible = !0, this.toggleAttribute("open", !0), this._applyContentSemantics(), t.hidden = !1, this._popover.sync(!0), this._anchor.update());
|
|
115
|
+
}
|
|
116
|
+
_closeTooltip() {
|
|
117
|
+
const t = this._$content;
|
|
118
|
+
this._visible = !1, this.toggleAttribute("open", !1), t && (this._popover.sync(!1), t.hidden = !0, t.setAttribute("aria-hidden", "true")), this._anchor.update();
|
|
119
|
+
}
|
|
120
|
+
}, n.styles = y, n._styledRoots = /* @__PURE__ */ new WeakSet(), n);
|
|
121
|
+
r([
|
|
122
|
+
u({ type: String })
|
|
123
|
+
], o.prototype, "placement");
|
|
124
|
+
r([
|
|
125
|
+
a("slot[name='trigger']")
|
|
126
|
+
], o.prototype, "_$triggerSlot");
|
|
127
|
+
r([
|
|
128
|
+
a("slot[name='content']")
|
|
129
|
+
], o.prototype, "_$contentSlot");
|
|
130
|
+
r([
|
|
131
|
+
a("slot:not([name])")
|
|
132
|
+
], o.prototype, "_$defaultSlot");
|
|
133
|
+
let C = o;
|
|
134
|
+
export {
|
|
135
|
+
C as R
|
|
136
|
+
};
|
|
137
|
+
//# sourceMappingURL=rc-tooltip-_7Ftj7QB.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-tooltip-_7Ftj7QB.js","sources":["../src/rc-tooltip.styles.ts","../src/rc-tooltip.ts"],"sourcesContent":["import { css } from 'lit';\n\nexport const tooltipStyles = css`\n :host {\n display: inline-block;\n color-scheme: inherit;\n }\n\n [part='root'] {\n display: inline-block;\n }\n\n @media (forced-colors: active) {\n slot[name='content']::slotted(*) {\n border-color: CanvasText;\n background: CanvasText;\n color: Canvas;\n }\n }\n`;\n\nexport default tooltipStyles;\n","import { LitElement, html } from 'lit';\nimport { property, query } from 'lit/decorators.js';\n\nimport {\n AnchorController,\n type AnchorPlacement,\n cssText,\n PopoverController,\n} from '@rcarls/rc-common';\n\nimport tooltipStyles from './rc-tooltip.styles.js';\n\ndeclare global {\n interface HTMLElementTagNameMap {\n 'rc-tooltip': RCTooltip;\n }\n}\n\nexport type RCTooltipPlacement = AnchorPlacement;\n\ntype ContentState = {\n id: string | null;\n role: string | null;\n ariaHidden: string | null;\n popover: string | null;\n hidden: boolean;\n};\n\nlet tooltipId = 0;\n\nconst LIGHT_DOM_CSS = cssText`\n@layer rc-base {\n rc-tooltip > [slot='content'],\n rc-tooltip > :not([slot]) {\n position: fixed;\n display: block;\n box-sizing: border-box;\n max-inline-size: var(--rc-tooltip-max-inline-size, 20rem);\n padding-block: var(--rc-tooltip-padding-block, 0.25em);\n padding-inline: var(--rc-tooltip-padding-inline, 0.5em);\n border: var(--rc-tooltip-border, 1px solid CanvasText);\n border-radius: var(--rc-tooltip-radius, var(--rc-radius-sm, 0.125em));\n background: var(--rc-tooltip-background, CanvasText);\n color: var(--rc-tooltip-color, Canvas);\n box-shadow: var(--rc-tooltip-shadow, none);\n font: var(--rc-tooltip-font, inherit);\n line-height: var(--rc-tooltip-line-height, normal);\n overflow-wrap: anywhere;\n pointer-events: auto;\n z-index: var(--rc-tooltip-z-index, 1);\n }\n\n rc-tooltip > [slot='content'][hidden],\n rc-tooltip > :not([slot])[hidden] {\n display: none !important;\n }\n}\n`;\n\n/**\n * Tooltip wrapper for a consumer-owned trigger and descriptive content,\n * following the [WAI-ARIA Tooltip pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/).\n * The trigger remains in light DOM and receives `aria-describedby`; the\n * content remains in light DOM so the ID relationship works across browsers.\n *\n * The native Popover API is used when the supplied content supports it. Older\n * browsers use the same focus, pointer, Escape, and anchor positioning logic\n * with an explicit visibility fallback. Tooltip content is descriptive and\n * must not contain interactive controls or receive focus.\n *\n * @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-tooltip rc-tooltip docs}\n * @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/ WAI-ARIA Tooltip pattern}\n *\n * @slot trigger - The consumer-owned element that receives focus and hover behavior.\n * @slot content - The single consumer-owned element containing the tooltip text.\n * @slot default - A fallback content slot when `content` is omitted.\n *\n * @csspart root - The shadow-DOM wrapper containing the two slots.\n *\n * @cssprop [--rc-tooltip-max-inline-size=20rem] - Maximum inline size of the tooltip content.\n * @cssprop [--rc-tooltip-padding-block=0.25em] - Tooltip block-axis padding.\n * @cssprop [--rc-tooltip-padding-inline=0.5em] - Tooltip inline-axis padding.\n * @cssprop [--rc-tooltip-border=1px solid CanvasText] - Tooltip border.\n * @cssprop [--rc-tooltip-radius=var(--rc-radius-sm)] - Tooltip corner radius.\n * @cssprop [--rc-tooltip-background=CanvasText] - Tooltip background.\n * @cssprop [--rc-tooltip-color=Canvas] - Tooltip text color.\n * @cssprop [--rc-tooltip-shadow=none] - Tooltip shadow.\n * @cssprop [--rc-tooltip-font=inherit] - Tooltip font.\n * @cssprop [--rc-tooltip-line-height=normal] - Tooltip line height.\n * @cssprop [--rc-tooltip-z-index=1] - Tooltip stacking order in the fallback mode.\n *\n * @attr placement - Preferred logical placement relative to the trigger.\n * @attr [open] - Reflects the tooltip's visible state; set by the component.\n */\nexport class RCTooltip extends LitElement {\n static override styles = tooltipStyles;\n\n private static readonly _styledRoots = new WeakSet<Document | ShadowRoot>();\n\n /** Preferred logical placement relative to the trigger. */\n @property({ type: String })\n placement: RCTooltipPlacement = 'block-end';\n\n @query(\"slot[name='trigger']\")\n private _$triggerSlot!: HTMLSlotElement;\n\n @query(\"slot[name='content']\")\n private _$contentSlot!: HTMLSlotElement;\n\n @query('slot:not([name])')\n private _$defaultSlot!: HTMLSlotElement;\n\n private _$trigger: HTMLElement | null = null;\n private _$content: HTMLElement | null = null;\n private _contentState: ContentState | null = null;\n private _triggerDescribedBy: string | null = null;\n private _visible = false;\n private _focusWithin = false;\n private _pointerWithin = false;\n private _dismissedByEscape = false;\n private _slotSyncQueued = false;\n\n private readonly _anchor = new AnchorController(this, {\n anchor: () => this._$trigger,\n floating: () => this._$content,\n placement: this.placement,\n offset: 4,\n disabled: () => !this._visible,\n });\n\n private readonly _popover = new PopoverController(this, { element: () => this._$content });\n\n override connectedCallback(): void {\n super.connectedCallback();\n RCTooltip._ensureBaseStyles(this.getRootNode() as Document | ShadowRoot);\n this.addEventListener('focusin', this._onFocusIn);\n this.addEventListener('focusout', this._onFocusOut);\n this.addEventListener('pointerover', this._onPointerOver);\n this.addEventListener('pointerout', this._onPointerOut);\n this.addEventListener('keydown', this._onKeyDown);\n\n if (this.hasUpdated) {\n this._queueSlotSync();\n }\n }\n\n override disconnectedCallback(): void {\n this.removeEventListener('focusin', this._onFocusIn);\n this.removeEventListener('focusout', this._onFocusOut);\n this.removeEventListener('pointerover', this._onPointerOver);\n this.removeEventListener('pointerout', this._onPointerOut);\n this.removeEventListener('keydown', this._onKeyDown);\n this._focusWithin = false;\n this._pointerWithin = false;\n this._dismissedByEscape = false;\n this._closeTooltip();\n this._restoreTrigger();\n this._restoreContent();\n this._$trigger = null;\n this._$content = null;\n super.disconnectedCallback();\n }\n\n protected override firstUpdated(): void {\n this._queueSlotSync();\n\n if (import.meta.env.DEV && !this.querySelector(':scope > [slot=\"trigger\"]')) {\n console.warn(\n '[rc-tooltip] No direct child [slot=\"trigger\"] found. Place the trigger element in the trigger slot.',\n this,\n );\n }\n\n if (\n import.meta.env.DEV &&\n !this.querySelector(':scope > [slot=\"content\"]') &&\n !this.querySelector(':scope > :not([slot])')\n ) {\n console.warn(\n '[rc-tooltip] No direct tooltip content found. Place one element in the content slot.',\n this,\n );\n }\n }\n\n protected override updated(changed: Map<PropertyKey, unknown>): void {\n if (changed.has('placement')) {\n this._anchor.setOptions({ placement: this.placement });\n }\n }\n\n protected override render() {\n return html`\n <div id=\"root\" part=\"root\">\n <slot name=\"trigger\" @slotchange=${this._onSlotChange}></slot>\n <slot name=\"content\" @slotchange=${this._onSlotChange}></slot>\n <slot @slotchange=${this._onSlotChange}></slot>\n </div>\n `;\n }\n\n private static _ensureBaseStyles(root: Document | ShadowRoot): void {\n if (RCTooltip._styledRoots.has(root)) {\n return;\n }\n\n RCTooltip._styledRoots.add(root);\n\n const style = (root instanceof Document ? root : root.ownerDocument).createElement('style');\n\n style.setAttribute('data-rc-light-dom-base', 'rc-tooltip');\n style.textContent = LIGHT_DOM_CSS;\n\n if (root instanceof Document) {\n root.head.append(style);\n } else {\n root.append(style);\n }\n }\n\n private _onSlotChange = (): void => {\n this._queueSlotSync();\n };\n\n private _queueSlotSync(): void {\n if (this._slotSyncQueued) {\n return;\n }\n\n this._slotSyncQueued = true;\n\n queueMicrotask(() => {\n this._slotSyncQueued = false;\n\n if (this.isConnected) {\n this._syncSlots();\n }\n });\n }\n\n private _syncSlots(): void {\n const trigger =\n this._$triggerSlot\n ?.assignedElements({ flatten: true })\n .find((element): element is HTMLElement => element instanceof HTMLElement) ?? null;\n const content =\n this._$contentSlot\n ?.assignedElements({ flatten: true })\n .find((element): element is HTMLElement => element instanceof HTMLElement) ??\n this._$defaultSlot\n ?.assignedElements({ flatten: true })\n .find((element): element is HTMLElement => element instanceof HTMLElement) ??\n null;\n\n if (content !== this._$content) {\n this._closeTooltip();\n this._restoreTrigger();\n this._restoreContent();\n this._$content = content;\n this._contentState = null;\n this._applyContentSemantics();\n }\n\n if (trigger !== this._$trigger) {\n this._restoreTrigger();\n this._$trigger = trigger;\n this._triggerDescribedBy = null;\n }\n\n this._applyContentSemantics();\n this._syncTriggerDescription();\n this._syncVisibility();\n\n if (this._visible) {\n this._anchor.update();\n }\n }\n\n private _applyContentSemantics(): void {\n const content = this._$content;\n\n if (!content) {\n return;\n }\n\n if (!this._contentState) {\n this._contentState = {\n id: content.getAttribute('id'),\n role: content.getAttribute('role'),\n ariaHidden: content.getAttribute('aria-hidden'),\n popover: content.getAttribute('popover'),\n hidden: content.hidden,\n };\n }\n\n if (!content.id) {\n content.id = `rc-tooltip-${++tooltipId}`;\n }\n\n content.setAttribute('role', 'tooltip');\n content.setAttribute('popover', 'manual');\n content.toggleAttribute('hidden', !this._visible);\n content.setAttribute('aria-hidden', String(!this._visible));\n }\n\n private _syncTriggerDescription(): void {\n const trigger = this._$trigger;\n const content = this._$content;\n\n if (!trigger || !content?.id) {\n return;\n }\n\n const current = trigger.getAttribute('aria-describedby');\n\n if (this._triggerDescribedBy === null) {\n this._triggerDescribedBy = current;\n }\n\n const tokens = new Set((current ?? '').split(/\\s+/).filter(Boolean));\n\n if (!tokens.has(content.id)) {\n tokens.add(content.id);\n }\n\n trigger.setAttribute('aria-describedby', Array.from(tokens).join(' '));\n }\n\n private _restoreTrigger(): void {\n if (!this._$trigger || this._triggerDescribedBy === null) {\n return;\n }\n\n if (this._triggerDescribedBy === '') {\n this._$trigger.removeAttribute('aria-describedby');\n } else {\n this._$trigger.setAttribute('aria-describedby', this._triggerDescribedBy);\n }\n\n this._triggerDescribedBy = null;\n }\n\n private _restoreContent(): void {\n const content = this._$content;\n const state = this._contentState;\n\n if (!content || !state) {\n return;\n }\n\n this._popover.sync(false);\n\n if (state.id === null) {\n content.removeAttribute('id');\n } else {\n content.setAttribute('id', state.id);\n }\n\n if (state.role === null) {\n content.removeAttribute('role');\n } else {\n content.setAttribute('role', state.role);\n }\n\n if (state.ariaHidden === null) {\n content.removeAttribute('aria-hidden');\n } else {\n content.setAttribute('aria-hidden', state.ariaHidden);\n }\n\n if (state.popover === null) {\n content.removeAttribute('popover');\n } else {\n content.setAttribute('popover', state.popover);\n }\n\n content.hidden = state.hidden;\n this._contentState = null;\n }\n\n private _onFocusIn = (event: FocusEvent): void => {\n if (this._$trigger && event.composedPath().includes(this._$trigger)) {\n this._focusWithin = true;\n this._syncVisibility();\n }\n };\n\n private _onFocusOut = (event: FocusEvent): void => {\n const relatedTarget = event.relatedTarget;\n\n if (relatedTarget instanceof Node && this.contains(relatedTarget)) {\n return;\n }\n\n if (this._$trigger && event.composedPath().includes(this._$trigger)) {\n this._focusWithin = false;\n this._dismissedByEscape = false;\n this._syncVisibility();\n }\n };\n\n private _onPointerOver = (event: PointerEvent): void => {\n if (event.pointerType === 'touch') {\n return;\n }\n\n const path = event.composedPath();\n\n if (\n (this._$trigger && path.includes(this._$trigger)) ||\n (this._$content && path.includes(this._$content))\n ) {\n this._pointerWithin = true;\n this._dismissedByEscape = false;\n this._syncVisibility();\n }\n };\n\n private _onPointerOut = (event: PointerEvent): void => {\n if (event.pointerType === 'touch') {\n return;\n }\n\n const relatedTarget = event.relatedTarget;\n\n if (relatedTarget instanceof Node && this.contains(relatedTarget)) {\n return;\n }\n\n const path = event.composedPath();\n\n if (\n (this._$trigger && path.includes(this._$trigger)) ||\n (this._$content && path.includes(this._$content))\n ) {\n this._pointerWithin = false;\n this._syncVisibility();\n }\n };\n\n private _onKeyDown = (event: KeyboardEvent): void => {\n if (event.key !== 'Escape' || !this._visible) {\n return;\n }\n\n event.stopPropagation();\n this._dismissedByEscape = true;\n this._focusWithin = false;\n this._pointerWithin = false;\n this._closeTooltip();\n };\n\n private _syncVisibility(): void {\n const shouldOpen =\n !this._dismissedByEscape && (this._focusWithin || this._pointerWithin) && !!this._$content;\n\n if (shouldOpen === this._visible) {\n return;\n }\n\n if (shouldOpen) {\n this._openTooltip();\n } else {\n this._closeTooltip();\n }\n }\n\n private _openTooltip(): void {\n const content = this._$content;\n\n if (!content) {\n return;\n }\n\n this._visible = true;\n this.toggleAttribute('open', true);\n this._applyContentSemantics();\n content.hidden = false;\n\n this._popover.sync(true);\n\n this._anchor.update();\n }\n\n private _closeTooltip(): void {\n const content = this._$content;\n\n this._visible = false;\n this.toggleAttribute('open', false);\n\n if (content) {\n this._popover.sync(false);\n content.hidden = true;\n content.setAttribute('aria-hidden', 'true');\n }\n\n this._anchor.update();\n }\n}\n\nexport default RCTooltip;\n"],"names":["tooltipStyles","css","tooltipId","LIGHT_DOM_CSS","cssText","_RCTooltip","_a","LitElement","AnchorController","PopoverController","event","relatedTarget","path","changed","html","root","style","trigger","element","content","current","tokens","state","shouldOpen","__decorateClass","property","query","RCTooltip"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-tooltip-define.js","sources":["../src/define.ts"],"sourcesContent":["import { RCTooltip } from './index.js';\n\ncustomElements.get('rc-tooltip') || customElements.define('rc-tooltip', RCTooltip);\n\nexport * from './index.js';\n"],"names":["RCTooltip"],"mappings":";AAEA,eAAe,IAAI,YAAY,KAAK,eAAe,OAAO,cAAcA,CAAS;"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rc-tooltip.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './index.js';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import { LitElement } from 'lit';
|
|
2
|
+
import { AnchorPlacement } from '@rcarls/rc-common';
|
|
3
|
+
declare global {
|
|
4
|
+
interface HTMLElementTagNameMap {
|
|
5
|
+
'rc-tooltip': RCTooltip;
|
|
6
|
+
}
|
|
7
|
+
}
|
|
8
|
+
export type RCTooltipPlacement = AnchorPlacement;
|
|
9
|
+
/**
|
|
10
|
+
* Tooltip wrapper for a consumer-owned trigger and descriptive content,
|
|
11
|
+
* following the [WAI-ARIA Tooltip pattern](https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/).
|
|
12
|
+
* The trigger remains in light DOM and receives `aria-describedby`; the
|
|
13
|
+
* content remains in light DOM so the ID relationship works across browsers.
|
|
14
|
+
*
|
|
15
|
+
* The native Popover API is used when the supplied content supports it. Older
|
|
16
|
+
* browsers use the same focus, pointer, Escape, and anchor positioning logic
|
|
17
|
+
* with an explicit visibility fallback. Tooltip content is descriptive and
|
|
18
|
+
* must not contain interactive controls or receive focus.
|
|
19
|
+
*
|
|
20
|
+
* @see {@link https://richardcarls.github.io/rc-webcomponents/components/rc-tooltip rc-tooltip docs}
|
|
21
|
+
* @see {@link https://www.w3.org/WAI/ARIA/apg/patterns/tooltip/ WAI-ARIA Tooltip pattern}
|
|
22
|
+
*
|
|
23
|
+
* @slot trigger - The consumer-owned element that receives focus and hover behavior.
|
|
24
|
+
* @slot content - The single consumer-owned element containing the tooltip text.
|
|
25
|
+
* @slot default - A fallback content slot when `content` is omitted.
|
|
26
|
+
*
|
|
27
|
+
* @csspart root - The shadow-DOM wrapper containing the two slots.
|
|
28
|
+
*
|
|
29
|
+
* @cssprop [--rc-tooltip-max-inline-size=20rem] - Maximum inline size of the tooltip content.
|
|
30
|
+
* @cssprop [--rc-tooltip-padding-block=0.25em] - Tooltip block-axis padding.
|
|
31
|
+
* @cssprop [--rc-tooltip-padding-inline=0.5em] - Tooltip inline-axis padding.
|
|
32
|
+
* @cssprop [--rc-tooltip-border=1px solid CanvasText] - Tooltip border.
|
|
33
|
+
* @cssprop [--rc-tooltip-radius=var(--rc-radius-sm)] - Tooltip corner radius.
|
|
34
|
+
* @cssprop [--rc-tooltip-background=CanvasText] - Tooltip background.
|
|
35
|
+
* @cssprop [--rc-tooltip-color=Canvas] - Tooltip text color.
|
|
36
|
+
* @cssprop [--rc-tooltip-shadow=none] - Tooltip shadow.
|
|
37
|
+
* @cssprop [--rc-tooltip-font=inherit] - Tooltip font.
|
|
38
|
+
* @cssprop [--rc-tooltip-line-height=normal] - Tooltip line height.
|
|
39
|
+
* @cssprop [--rc-tooltip-z-index=1] - Tooltip stacking order in the fallback mode.
|
|
40
|
+
*
|
|
41
|
+
* @attr placement - Preferred logical placement relative to the trigger.
|
|
42
|
+
* @attr [open] - Reflects the tooltip's visible state; set by the component.
|
|
43
|
+
*/
|
|
44
|
+
export declare class RCTooltip extends LitElement {
|
|
45
|
+
static styles: import('lit').CSSResult;
|
|
46
|
+
private static readonly _styledRoots;
|
|
47
|
+
/** Preferred logical placement relative to the trigger. */
|
|
48
|
+
placement: RCTooltipPlacement;
|
|
49
|
+
private _$triggerSlot;
|
|
50
|
+
private _$contentSlot;
|
|
51
|
+
private _$defaultSlot;
|
|
52
|
+
private _$trigger;
|
|
53
|
+
private _$content;
|
|
54
|
+
private _contentState;
|
|
55
|
+
private _triggerDescribedBy;
|
|
56
|
+
private _visible;
|
|
57
|
+
private _focusWithin;
|
|
58
|
+
private _pointerWithin;
|
|
59
|
+
private _dismissedByEscape;
|
|
60
|
+
private _slotSyncQueued;
|
|
61
|
+
private readonly _anchor;
|
|
62
|
+
private readonly _popover;
|
|
63
|
+
connectedCallback(): void;
|
|
64
|
+
disconnectedCallback(): void;
|
|
65
|
+
protected firstUpdated(): void;
|
|
66
|
+
protected updated(changed: Map<PropertyKey, unknown>): void;
|
|
67
|
+
protected render(): import('lit-html').TemplateResult<1>;
|
|
68
|
+
private static _ensureBaseStyles;
|
|
69
|
+
private _onSlotChange;
|
|
70
|
+
private _queueSlotSync;
|
|
71
|
+
private _syncSlots;
|
|
72
|
+
private _applyContentSemantics;
|
|
73
|
+
private _syncTriggerDescription;
|
|
74
|
+
private _restoreTrigger;
|
|
75
|
+
private _restoreContent;
|
|
76
|
+
private _onFocusIn;
|
|
77
|
+
private _onFocusOut;
|
|
78
|
+
private _onPointerOver;
|
|
79
|
+
private _onPointerOut;
|
|
80
|
+
private _onKeyDown;
|
|
81
|
+
private _syncVisibility;
|
|
82
|
+
private _openTooltip;
|
|
83
|
+
private _closeTooltip;
|
|
84
|
+
}
|
|
85
|
+
export default RCTooltip;
|
package/package.json
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@rcarls/rc-tooltip",
|
|
3
|
+
"publishConfig": {
|
|
4
|
+
"access": "public"
|
|
5
|
+
},
|
|
6
|
+
"version": "0.0.0-next-20261020171337",
|
|
7
|
+
"description": "Tooltip wrapper for a consumer-owned trigger and descriptive content.",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/richardcarls/rc-webcomponents.git",
|
|
11
|
+
"directory": "packages/rc-tooltip"
|
|
12
|
+
},
|
|
13
|
+
"homepage": "https://richardcarls.github.io/rc-webcomponents/components/rc-tooltip",
|
|
14
|
+
"license": "MIT",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"files": [
|
|
17
|
+
"dist"
|
|
18
|
+
],
|
|
19
|
+
"module": "./dist/rc-tooltip.js",
|
|
20
|
+
"exports": {
|
|
21
|
+
".": {
|
|
22
|
+
"import": {
|
|
23
|
+
"types": "./dist/types/packages/rc-tooltip/src/index.d.ts",
|
|
24
|
+
"default": "./dist/rc-tooltip.js"
|
|
25
|
+
}
|
|
26
|
+
},
|
|
27
|
+
"./define": {
|
|
28
|
+
"import": {
|
|
29
|
+
"types": "./dist/types/packages/rc-tooltip/src/define.d.ts",
|
|
30
|
+
"default": "./dist/rc-tooltip-define.js"
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
"types": "./dist/types/packages/rc-tooltip/src/index.d.ts",
|
|
35
|
+
"sideEffects": [
|
|
36
|
+
"./dist/rc-tooltip-define.js"
|
|
37
|
+
],
|
|
38
|
+
"customElements": "dist/custom-elements.json",
|
|
39
|
+
"scripts": {
|
|
40
|
+
"build": "tsc && vite build && cem analyze",
|
|
41
|
+
"cem:analyze": "cem analyze",
|
|
42
|
+
"preview": "vite preview",
|
|
43
|
+
"test:browser": "vitest --run",
|
|
44
|
+
"test:browser:chrome": "vitest --run --project=chromium",
|
|
45
|
+
"test:browser:firefox": "vitest --run --project=firefox"
|
|
46
|
+
},
|
|
47
|
+
"dependencies": {
|
|
48
|
+
"@rcarls/rc-common": "0.0.0-next-20261020171337"
|
|
49
|
+
},
|
|
50
|
+
"devDependencies": {
|
|
51
|
+
"@custom-elements-manifest/analyzer": "0.11.0",
|
|
52
|
+
"@vitest/browser-playwright": "4.1.5",
|
|
53
|
+
"lit": "^3.0.0",
|
|
54
|
+
"playwright": "^1.56.0",
|
|
55
|
+
"rollup": "^4.60.2",
|
|
56
|
+
"typescript": "~5.9.3",
|
|
57
|
+
"vite": "^7.1.7",
|
|
58
|
+
"vite-plugin-dts": "^4.5.4",
|
|
59
|
+
"vitest": "^4.0.6",
|
|
60
|
+
"vitest-browser-lit": "^1.0.1"
|
|
61
|
+
},
|
|
62
|
+
"peerDependencies": {
|
|
63
|
+
"lit": "^3.0.0"
|
|
64
|
+
}
|
|
65
|
+
}
|