@atlaskit/editor-common 120.3.3 → 120.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +16 -0
- package/dist/cjs/monitoring/error.js +1 -1
- package/dist/cjs/ui/DropList/index.js +1 -1
- package/dist/cjs/vanilla-tooltip/index.js +134 -35
- package/dist/es2019/monitoring/error.js +1 -1
- package/dist/es2019/ui/DropList/index.js +1 -1
- package/dist/es2019/vanilla-tooltip/index.js +113 -21
- package/dist/esm/monitoring/error.js +1 -1
- package/dist/esm/ui/DropList/index.js +1 -1
- package/dist/esm/vanilla-tooltip/index.js +134 -35
- package/dist/types/vanilla-tooltip/index.d.ts +54 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,21 @@
|
|
|
1
1
|
# @atlaskit/editor-common
|
|
2
2
|
|
|
3
|
+
## 120.4.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [`d1701a4710adf`](https://bitbucket.org/atlassian/atlassian-frontend-monorepo/commits/d1701a4710adf) -
|
|
8
|
+
EDITOR-8658 improve vanilla tooltip api
|
|
9
|
+
|
|
10
|
+
`VanillaTooltip` now accepts any `HTMLElement` as its trigger, generates its own tooltip id when
|
|
11
|
+
none is passed, and only binds its Escape listener while the tooltip is visible.
|
|
12
|
+
|
|
13
|
+
These changes are behind the `platform_editor_use_vanilla_components` experiment.
|
|
14
|
+
|
|
15
|
+
### Patch Changes
|
|
16
|
+
|
|
17
|
+
- Updated dependencies
|
|
18
|
+
|
|
3
19
|
## 120.3.3
|
|
4
20
|
|
|
5
21
|
### Patch Changes
|
|
@@ -28,7 +28,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
28
28
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
29
29
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
30
30
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
31
|
-
var packageVersion = "120.3.
|
|
31
|
+
var packageVersion = "120.3.3";
|
|
32
32
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
33
33
|
// Remove URL as it has UGC
|
|
34
34
|
// Ignored via go/ees007
|
|
@@ -24,7 +24,7 @@ function _isNativeReflectConstruct() { try { var t = !Boolean.prototype.valueOf.
|
|
|
24
24
|
* @jsx jsx
|
|
25
25
|
*/ // eslint-disable-next-line @atlaskit/ui-styling-standard/use-compiled -- Ignored via go/DSP-18766
|
|
26
26
|
var packageName = "@atlaskit/editor-common";
|
|
27
|
-
var packageVersion = "120.3.
|
|
27
|
+
var packageVersion = "120.3.3";
|
|
28
28
|
var halfFocusRing = 1;
|
|
29
29
|
var dropOffset = '0, 8';
|
|
30
30
|
var fadeIn = (0, _react2.keyframes)({
|
|
@@ -10,6 +10,7 @@ var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/creat
|
|
|
10
10
|
var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty"));
|
|
11
11
|
var _core = require("@popperjs/core");
|
|
12
12
|
var _bindEventListener = require("bind-event-listener");
|
|
13
|
+
var _isExperimentEnabled = require("@atlaskit/platform-feature-experiments/is-experiment-enabled");
|
|
13
14
|
var _fg = require("@atlaskit/platform-feature-flags/fg");
|
|
14
15
|
var _unsafeImperative = require("@atlaskit/popper/unsafe-imperative");
|
|
15
16
|
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
|
|
@@ -26,6 +27,26 @@ var endingOffset = {
|
|
|
26
27
|
offset: [0, 8]
|
|
27
28
|
}
|
|
28
29
|
};
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Namespaced to keep generated ids from colliding with ids the host page owns, since they share
|
|
33
|
+
* the document's single id space.
|
|
34
|
+
*/
|
|
35
|
+
var TOOLTIP_ID_PREFIX = 'ak-editor-internal-tooltip';
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Generates a tooltip id for `aria-describedby`/`popovertarget`.
|
|
39
|
+
*
|
|
40
|
+
* `crypto.randomUUID` covers effectively all production traffic
|
|
41
|
+
* The counter is only a fallback for environments without it (for example a non-secure context)
|
|
42
|
+
* and is scoped to this closure rather than module state.
|
|
43
|
+
*/
|
|
44
|
+
var generateTooltipId = function () {
|
|
45
|
+
var count = 0;
|
|
46
|
+
return function () {
|
|
47
|
+
return typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? "".concat(TOOLTIP_ID_PREFIX, "-").concat(crypto.randomUUID()) : "".concat(TOOLTIP_ID_PREFIX, "-").concat(count += 1);
|
|
48
|
+
};
|
|
49
|
+
}();
|
|
29
50
|
function getCreatePopper() {
|
|
30
51
|
if ((0, _fg.fg)('platform-dst-popper-consolidation')) {
|
|
31
52
|
return _unsafeImperative.createPopper;
|
|
@@ -40,9 +61,31 @@ function getCreatePopper() {
|
|
|
40
61
|
* Uses popperJS for positioning
|
|
41
62
|
*/
|
|
42
63
|
var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
43
|
-
function VanillaTooltip(button, content,
|
|
44
64
|
/**
|
|
45
|
-
*
|
|
65
|
+
* Set only while this tooltip is on screen, so no listener is retained at rest.
|
|
66
|
+
*/
|
|
67
|
+
|
|
68
|
+
function VanillaTooltip(
|
|
69
|
+
/**
|
|
70
|
+
* The element that the tooltip describes and Popper uses as its anchor.
|
|
71
|
+
*
|
|
72
|
+
* Prefer a `<button>`: it is focusable and announced by assistive tech for free, and is the
|
|
73
|
+
* only element the browser honours `popovertarget` on. Anything else works, since this
|
|
74
|
+
* class calls `showPopover()`/`hidePopover()` itself, but then make sure it:
|
|
75
|
+
*
|
|
76
|
+
* - **Renders its children**, as the tooltip is appended to the trigger. `<img>`, `<input>`
|
|
77
|
+
* and `<br>` accept the append without error but never render it, leaving the tooltip
|
|
78
|
+
* silently at zero size.
|
|
79
|
+
* - **Is reachable**, if keyboard and screen reader users need the tooltip — usually
|
|
80
|
+
* `tabindex="0"` plus a role and accessible name, since `focus`/`blur` are bound to the
|
|
81
|
+
* trigger and `aria-describedby` is set on it.
|
|
82
|
+
*/
|
|
83
|
+
trigger, content,
|
|
84
|
+
/**
|
|
85
|
+
* Id associated to the tooltip - must be unique within the document.
|
|
86
|
+
*
|
|
87
|
+
* Pass `undefined` to have one generated, which is preferred: callers otherwise have to
|
|
88
|
+
* solve uniqueness themselves, and every consumer had solved it differently.
|
|
46
89
|
*/
|
|
47
90
|
id,
|
|
48
91
|
/**
|
|
@@ -69,29 +112,30 @@ var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
|
69
112
|
(0, _defineProperty2.default)(this, "listeners", []);
|
|
70
113
|
(0, _defineProperty2.default)(this, "shouldHidePopover", false);
|
|
71
114
|
(0, _defineProperty2.default)(this, "isDisplayed", false);
|
|
72
|
-
this.
|
|
115
|
+
this.trigger = trigger;
|
|
73
116
|
this.timeout = timeout;
|
|
74
117
|
this.onShow = onShow;
|
|
75
|
-
|
|
118
|
+
// Created in the trigger's own document rather than the global one, so nothing depends on
|
|
119
|
+
// the parent realm when the editor renders inside an iframe. Gated alongside the Escape
|
|
120
|
+
// listener's window so the whole iframe fix moves as a single unit.
|
|
121
|
+
var ownerDocument = (0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_use_vanilla_components') ? trigger.ownerDocument : document;
|
|
122
|
+
var tooltip = ownerDocument.createElement('span');
|
|
76
123
|
tooltip.role = 'tooltip';
|
|
77
124
|
tooltip.popover = 'hint';
|
|
78
125
|
tooltip.className = className;
|
|
79
|
-
tooltip.id = id;
|
|
126
|
+
tooltip.id = id !== null && id !== void 0 ? id : generateTooltipId();
|
|
80
127
|
tooltip.textContent = content;
|
|
81
128
|
if (styles) {
|
|
82
129
|
Object.assign(tooltip.style, styles);
|
|
83
130
|
}
|
|
84
131
|
this.tooltip = tooltip;
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
// Prepare the button to have the popover target and accessibility properties
|
|
89
|
-
button.setAttribute('popovertarget', tooltip.id);
|
|
90
|
-
button.setAttribute('aria-describedby', tooltip.id);
|
|
132
|
+
this.trigger.appendChild(tooltip);
|
|
133
|
+
this.trigger.setAttribute('popovertarget', tooltip.id);
|
|
134
|
+
this.trigger.setAttribute('aria-describedby', tooltip.id);
|
|
91
135
|
var showEvents = ['mouseenter', 'focus'];
|
|
92
136
|
var hideEvents = ['mouseleave', 'blur'];
|
|
93
137
|
showEvents.forEach(function (event) {
|
|
94
|
-
_this.listeners.push((0, _bindEventListener.bind)(
|
|
138
|
+
_this.listeners.push((0, _bindEventListener.bind)(_this.trigger, {
|
|
95
139
|
type: event,
|
|
96
140
|
listener: function listener() {
|
|
97
141
|
return _this.show();
|
|
@@ -99,21 +143,26 @@ var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
|
99
143
|
}));
|
|
100
144
|
});
|
|
101
145
|
hideEvents.forEach(function (event) {
|
|
102
|
-
_this.listeners.push((0, _bindEventListener.bind)(
|
|
146
|
+
_this.listeners.push((0, _bindEventListener.bind)(_this.trigger, {
|
|
103
147
|
type: event,
|
|
104
148
|
listener: function listener() {
|
|
105
149
|
return _this.hide();
|
|
106
150
|
}
|
|
107
151
|
}));
|
|
108
152
|
});
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
153
|
+
|
|
154
|
+
// Bound for this tooltip's whole lifetime, even while it is off screen. The experiment
|
|
155
|
+
// moves this to `show()` so nothing is retained at rest.
|
|
156
|
+
if (!(0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_use_vanilla_components')) {
|
|
157
|
+
this.listeners.push((0, _bindEventListener.bind)(window, {
|
|
158
|
+
type: 'keydown',
|
|
159
|
+
listener: function listener(e) {
|
|
160
|
+
if (e.key === 'Escape') {
|
|
161
|
+
_this.hide(true);
|
|
162
|
+
}
|
|
114
163
|
}
|
|
115
|
-
}
|
|
116
|
-
}
|
|
164
|
+
}));
|
|
165
|
+
}
|
|
117
166
|
|
|
118
167
|
// Hide the tooltip if the hide transition has completed
|
|
119
168
|
this.tooltip.ontransitionend = function () {
|
|
@@ -125,7 +174,7 @@ var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
|
125
174
|
return (0, _createClass2.default)(VanillaTooltip, [{
|
|
126
175
|
key: "createPopperInstance",
|
|
127
176
|
value: function createPopperInstance() {
|
|
128
|
-
this.popperInstance = getCreatePopper()(this.
|
|
177
|
+
this.popperInstance = getCreatePopper()(this.trigger, this.tooltip, {
|
|
129
178
|
placement: 'top',
|
|
130
179
|
modifiers: [startingOffset]
|
|
131
180
|
});
|
|
@@ -137,22 +186,65 @@ var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
|
137
186
|
// Cancels any pending show/hide, which would otherwise run against detached DOM and
|
|
138
187
|
// invoke `onShow` after the owner has gone away.
|
|
139
188
|
clearTimeout(this.currentTimeoutId);
|
|
189
|
+
// Destroying while visible must not leave the listener bound to a dead tooltip.
|
|
190
|
+
this.unbindEscapeListener();
|
|
140
191
|
(_this$popperInstance = this.popperInstance) === null || _this$popperInstance === void 0 || _this$popperInstance.destroy();
|
|
141
192
|
this.listeners.forEach(function (listener) {
|
|
142
193
|
listener();
|
|
143
194
|
});
|
|
144
195
|
}
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Starts listening for Escape to dismiss this tooltip.
|
|
199
|
+
*
|
|
200
|
+
* A tooltip only ever needs one Escape listener, so this does nothing when one is already
|
|
201
|
+
* bound.
|
|
202
|
+
*/
|
|
203
|
+
}, {
|
|
204
|
+
key: "bindEscapeListener",
|
|
205
|
+
value: function bindEscapeListener() {
|
|
206
|
+
var _this$trigger$ownerDo,
|
|
207
|
+
_this2 = this;
|
|
208
|
+
if (this.unbindEscape) {
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
this.unbindEscape = (0, _bindEventListener.bind)((_this$trigger$ownerDo = this.trigger.ownerDocument.defaultView) !== null && _this$trigger$ownerDo !== void 0 ? _this$trigger$ownerDo : window, {
|
|
212
|
+
type: 'keydown',
|
|
213
|
+
listener: function listener(e) {
|
|
214
|
+
if (e.key === 'Escape') {
|
|
215
|
+
_this2.hide(true);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Stops listening for Escape, so no listener is retained while this tooltip is off screen.
|
|
223
|
+
*
|
|
224
|
+
* Does nothing when no listener is bound.
|
|
225
|
+
*/
|
|
226
|
+
}, {
|
|
227
|
+
key: "unbindEscapeListener",
|
|
228
|
+
value: function unbindEscapeListener() {
|
|
229
|
+
var _this$unbindEscape;
|
|
230
|
+
(_this$unbindEscape = this.unbindEscape) === null || _this$unbindEscape === void 0 || _this$unbindEscape.call(this);
|
|
231
|
+
this.unbindEscape = undefined;
|
|
232
|
+
}
|
|
145
233
|
}, {
|
|
146
234
|
key: "hide",
|
|
147
235
|
value: function hide() {
|
|
148
|
-
var
|
|
236
|
+
var _this3 = this;
|
|
149
237
|
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
150
238
|
clearTimeout(this.currentTimeoutId);
|
|
239
|
+
|
|
240
|
+
// Unbound synchronously so a repeated Escape does not re-enter this tooltip while the
|
|
241
|
+
// hide is still pending.
|
|
242
|
+
this.unbindEscapeListener();
|
|
151
243
|
this.shouldHidePopover = true;
|
|
152
244
|
// Disable the event listeners
|
|
153
245
|
this.currentTimeoutId = setTimeout(function () {
|
|
154
|
-
var
|
|
155
|
-
(
|
|
246
|
+
var _this3$popperInstance;
|
|
247
|
+
(_this3$popperInstance = _this3.popperInstance) === null || _this3$popperInstance === void 0 || _this3$popperInstance.setOptions(function (options) {
|
|
156
248
|
return _objectSpread(_objectSpread({}, options), {}, {
|
|
157
249
|
modifiers: [startingOffset, {
|
|
158
250
|
name: 'eventListeners',
|
|
@@ -160,18 +252,25 @@ var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
|
160
252
|
}]
|
|
161
253
|
});
|
|
162
254
|
});
|
|
163
|
-
|
|
164
|
-
|
|
255
|
+
_this3.tooltip.style.opacity = '0';
|
|
256
|
+
_this3.isDisplayed = false;
|
|
165
257
|
// If transition animations are disabled immediately hide the popover
|
|
166
|
-
if (
|
|
167
|
-
|
|
258
|
+
if (_this3.tooltip.style.transition === 'none') {
|
|
259
|
+
_this3.tooltip.hidePopover();
|
|
168
260
|
}
|
|
169
261
|
}, immediate ? 0 : this.timeout);
|
|
170
262
|
}
|
|
171
263
|
}, {
|
|
172
264
|
key: "show",
|
|
173
265
|
value: function show() {
|
|
174
|
-
var
|
|
266
|
+
var _this4 = this;
|
|
267
|
+
// Bound before the open delay so Escape can dismiss during it, and before the
|
|
268
|
+
// `isDisplayed` guard so re-hovering a tooltip whose hide is still pending (`hide()`
|
|
269
|
+
// unbinds synchronously, but the tooltip stays on screen until its timeout) restores
|
|
270
|
+
// Escape rather than leaving the visible tooltip undismissable.
|
|
271
|
+
if ((0, _isExperimentEnabled.isExperimentEnabled)('platform_editor_use_vanilla_components')) {
|
|
272
|
+
this.bindEscapeListener();
|
|
273
|
+
}
|
|
175
274
|
if (this.isDisplayed) {
|
|
176
275
|
return;
|
|
177
276
|
}
|
|
@@ -191,10 +290,10 @@ var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
|
191
290
|
|
|
192
291
|
// Enable the event listeners
|
|
193
292
|
this.currentTimeoutId = setTimeout(function () {
|
|
194
|
-
var
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
(
|
|
293
|
+
var _this4$popperInstance, _this4$onShow;
|
|
294
|
+
_this4.tooltip.style.opacity = '1';
|
|
295
|
+
_this4.tooltip.style.visibility = 'visible';
|
|
296
|
+
(_this4$popperInstance = _this4.popperInstance) === null || _this4$popperInstance === void 0 || _this4$popperInstance.setOptions(function (options) {
|
|
198
297
|
return _objectSpread(_objectSpread({}, options), {}, {
|
|
199
298
|
modifiers: [endingOffset, {
|
|
200
299
|
name: 'eventListeners',
|
|
@@ -202,8 +301,8 @@ var VanillaTooltip = exports.VanillaTooltip = /*#__PURE__*/function () {
|
|
|
202
301
|
}]
|
|
203
302
|
});
|
|
204
303
|
});
|
|
205
|
-
|
|
206
|
-
(
|
|
304
|
+
_this4.isDisplayed = true;
|
|
305
|
+
(_this4$onShow = _this4.onShow) === null || _this4$onShow === void 0 || _this4$onShow.call(_this4);
|
|
207
306
|
}, this.timeout);
|
|
208
307
|
}
|
|
209
308
|
}]);
|
|
@@ -14,7 +14,7 @@ const NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
14
14
|
const RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
15
15
|
const SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
16
16
|
const packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
17
|
-
const packageVersion = "120.3.
|
|
17
|
+
const packageVersion = "120.3.3";
|
|
18
18
|
const sanitiseSentryEvents = (data, _hint) => {
|
|
19
19
|
// Remove URL as it has UGC
|
|
20
20
|
// Ignored via go/ees007
|
|
@@ -14,7 +14,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
14
14
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
15
15
|
import Layer from '../Layer';
|
|
16
16
|
const packageName = "@atlaskit/editor-common";
|
|
17
|
-
const packageVersion = "120.3.
|
|
17
|
+
const packageVersion = "120.3.3";
|
|
18
18
|
const halfFocusRing = 1;
|
|
19
19
|
const dropOffset = '0, 8';
|
|
20
20
|
const fadeIn = keyframes({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import _defineProperty from "@babel/runtime/helpers/defineProperty";
|
|
2
2
|
import { createPopper as createLegacyPopper } from '@popperjs/core';
|
|
3
3
|
import { bind } from 'bind-event-listener';
|
|
4
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
4
5
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
5
6
|
import { createPopper as createWrappedPopper } from '@atlaskit/popper/unsafe-imperative';
|
|
6
7
|
const startingOffset = {
|
|
@@ -15,6 +16,24 @@ const endingOffset = {
|
|
|
15
16
|
offset: [0, 8]
|
|
16
17
|
}
|
|
17
18
|
};
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* Namespaced to keep generated ids from colliding with ids the host page owns, since they share
|
|
22
|
+
* the document's single id space.
|
|
23
|
+
*/
|
|
24
|
+
const TOOLTIP_ID_PREFIX = 'ak-editor-internal-tooltip';
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Generates a tooltip id for `aria-describedby`/`popovertarget`.
|
|
28
|
+
*
|
|
29
|
+
* `crypto.randomUUID` covers effectively all production traffic
|
|
30
|
+
* The counter is only a fallback for environments without it (for example a non-secure context)
|
|
31
|
+
* and is scoped to this closure rather than module state.
|
|
32
|
+
*/
|
|
33
|
+
const generateTooltipId = (() => {
|
|
34
|
+
let count = 0;
|
|
35
|
+
return () => typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? `${TOOLTIP_ID_PREFIX}-${crypto.randomUUID()}` : `${TOOLTIP_ID_PREFIX}-${count += 1}`;
|
|
36
|
+
})();
|
|
18
37
|
function getCreatePopper() {
|
|
19
38
|
if (fg('platform-dst-popper-consolidation')) {
|
|
20
39
|
return createWrappedPopper;
|
|
@@ -29,9 +48,31 @@ function getCreatePopper() {
|
|
|
29
48
|
* Uses popperJS for positioning
|
|
30
49
|
*/
|
|
31
50
|
export class VanillaTooltip {
|
|
32
|
-
constructor(button, content,
|
|
33
51
|
/**
|
|
34
|
-
*
|
|
52
|
+
* Set only while this tooltip is on screen, so no listener is retained at rest.
|
|
53
|
+
*/
|
|
54
|
+
|
|
55
|
+
constructor(
|
|
56
|
+
/**
|
|
57
|
+
* The element that the tooltip describes and Popper uses as its anchor.
|
|
58
|
+
*
|
|
59
|
+
* Prefer a `<button>`: it is focusable and announced by assistive tech for free, and is the
|
|
60
|
+
* only element the browser honours `popovertarget` on. Anything else works, since this
|
|
61
|
+
* class calls `showPopover()`/`hidePopover()` itself, but then make sure it:
|
|
62
|
+
*
|
|
63
|
+
* - **Renders its children**, as the tooltip is appended to the trigger. `<img>`, `<input>`
|
|
64
|
+
* and `<br>` accept the append without error but never render it, leaving the tooltip
|
|
65
|
+
* silently at zero size.
|
|
66
|
+
* - **Is reachable**, if keyboard and screen reader users need the tooltip — usually
|
|
67
|
+
* `tabindex="0"` plus a role and accessible name, since `focus`/`blur` are bound to the
|
|
68
|
+
* trigger and `aria-describedby` is set on it.
|
|
69
|
+
*/
|
|
70
|
+
trigger, content,
|
|
71
|
+
/**
|
|
72
|
+
* Id associated to the tooltip - must be unique within the document.
|
|
73
|
+
*
|
|
74
|
+
* Pass `undefined` to have one generated, which is preferred: callers otherwise have to
|
|
75
|
+
* solve uniqueness themselves, and every consumer had solved it differently.
|
|
35
76
|
*/
|
|
36
77
|
id,
|
|
37
78
|
/**
|
|
@@ -53,47 +94,53 @@ export class VanillaTooltip {
|
|
|
53
94
|
_defineProperty(this, "listeners", []);
|
|
54
95
|
_defineProperty(this, "shouldHidePopover", false);
|
|
55
96
|
_defineProperty(this, "isDisplayed", false);
|
|
56
|
-
this.
|
|
97
|
+
this.trigger = trigger;
|
|
57
98
|
this.timeout = timeout;
|
|
58
99
|
this.onShow = onShow;
|
|
59
|
-
|
|
100
|
+
// Created in the trigger's own document rather than the global one, so nothing depends on
|
|
101
|
+
// the parent realm when the editor renders inside an iframe. Gated alongside the Escape
|
|
102
|
+
// listener's window so the whole iframe fix moves as a single unit.
|
|
103
|
+
const ownerDocument = isExperimentEnabled('platform_editor_use_vanilla_components') ? trigger.ownerDocument : document;
|
|
104
|
+
const tooltip = ownerDocument.createElement('span');
|
|
60
105
|
tooltip.role = 'tooltip';
|
|
61
106
|
tooltip.popover = 'hint';
|
|
62
107
|
tooltip.className = className;
|
|
63
|
-
tooltip.id = id;
|
|
108
|
+
tooltip.id = id !== null && id !== void 0 ? id : generateTooltipId();
|
|
64
109
|
tooltip.textContent = content;
|
|
65
110
|
if (styles) {
|
|
66
111
|
Object.assign(tooltip.style, styles);
|
|
67
112
|
}
|
|
68
113
|
this.tooltip = tooltip;
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
// Prepare the button to have the popover target and accessibility properties
|
|
73
|
-
button.setAttribute('popovertarget', tooltip.id);
|
|
74
|
-
button.setAttribute('aria-describedby', tooltip.id);
|
|
114
|
+
this.trigger.appendChild(tooltip);
|
|
115
|
+
this.trigger.setAttribute('popovertarget', tooltip.id);
|
|
116
|
+
this.trigger.setAttribute('aria-describedby', tooltip.id);
|
|
75
117
|
const showEvents = ['mouseenter', 'focus'];
|
|
76
118
|
const hideEvents = ['mouseleave', 'blur'];
|
|
77
119
|
showEvents.forEach(event => {
|
|
78
|
-
this.listeners.push(bind(
|
|
120
|
+
this.listeners.push(bind(this.trigger, {
|
|
79
121
|
type: event,
|
|
80
122
|
listener: () => this.show()
|
|
81
123
|
}));
|
|
82
124
|
});
|
|
83
125
|
hideEvents.forEach(event => {
|
|
84
|
-
this.listeners.push(bind(
|
|
126
|
+
this.listeners.push(bind(this.trigger, {
|
|
85
127
|
type: event,
|
|
86
128
|
listener: () => this.hide()
|
|
87
129
|
}));
|
|
88
130
|
});
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
131
|
+
|
|
132
|
+
// Bound for this tooltip's whole lifetime, even while it is off screen. The experiment
|
|
133
|
+
// moves this to `show()` so nothing is retained at rest.
|
|
134
|
+
if (!isExperimentEnabled('platform_editor_use_vanilla_components')) {
|
|
135
|
+
this.listeners.push(bind(window, {
|
|
136
|
+
type: 'keydown',
|
|
137
|
+
listener: e => {
|
|
138
|
+
if (e.key === 'Escape') {
|
|
139
|
+
this.hide(true);
|
|
140
|
+
}
|
|
94
141
|
}
|
|
95
|
-
}
|
|
96
|
-
}
|
|
142
|
+
}));
|
|
143
|
+
}
|
|
97
144
|
|
|
98
145
|
// Hide the tooltip if the hide transition has completed
|
|
99
146
|
this.tooltip.ontransitionend = () => {
|
|
@@ -103,7 +150,7 @@ export class VanillaTooltip {
|
|
|
103
150
|
};
|
|
104
151
|
}
|
|
105
152
|
createPopperInstance() {
|
|
106
|
-
this.popperInstance = getCreatePopper()(this.
|
|
153
|
+
this.popperInstance = getCreatePopper()(this.trigger, this.tooltip, {
|
|
107
154
|
placement: 'top',
|
|
108
155
|
modifiers: [startingOffset]
|
|
109
156
|
});
|
|
@@ -113,13 +160,51 @@ export class VanillaTooltip {
|
|
|
113
160
|
// Cancels any pending show/hide, which would otherwise run against detached DOM and
|
|
114
161
|
// invoke `onShow` after the owner has gone away.
|
|
115
162
|
clearTimeout(this.currentTimeoutId);
|
|
163
|
+
// Destroying while visible must not leave the listener bound to a dead tooltip.
|
|
164
|
+
this.unbindEscapeListener();
|
|
116
165
|
(_this$popperInstance = this.popperInstance) === null || _this$popperInstance === void 0 ? void 0 : _this$popperInstance.destroy();
|
|
117
166
|
this.listeners.forEach(listener => {
|
|
118
167
|
listener();
|
|
119
168
|
});
|
|
120
169
|
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Starts listening for Escape to dismiss this tooltip.
|
|
173
|
+
*
|
|
174
|
+
* A tooltip only ever needs one Escape listener, so this does nothing when one is already
|
|
175
|
+
* bound.
|
|
176
|
+
*/
|
|
177
|
+
bindEscapeListener() {
|
|
178
|
+
var _this$trigger$ownerDo;
|
|
179
|
+
if (this.unbindEscape) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
this.unbindEscape = bind((_this$trigger$ownerDo = this.trigger.ownerDocument.defaultView) !== null && _this$trigger$ownerDo !== void 0 ? _this$trigger$ownerDo : window, {
|
|
183
|
+
type: 'keydown',
|
|
184
|
+
listener: e => {
|
|
185
|
+
if (e.key === 'Escape') {
|
|
186
|
+
this.hide(true);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
/**
|
|
193
|
+
* Stops listening for Escape, so no listener is retained while this tooltip is off screen.
|
|
194
|
+
*
|
|
195
|
+
* Does nothing when no listener is bound.
|
|
196
|
+
*/
|
|
197
|
+
unbindEscapeListener() {
|
|
198
|
+
var _this$unbindEscape;
|
|
199
|
+
(_this$unbindEscape = this.unbindEscape) === null || _this$unbindEscape === void 0 ? void 0 : _this$unbindEscape.call(this);
|
|
200
|
+
this.unbindEscape = undefined;
|
|
201
|
+
}
|
|
121
202
|
hide(immediate = false) {
|
|
122
203
|
clearTimeout(this.currentTimeoutId);
|
|
204
|
+
|
|
205
|
+
// Unbound synchronously so a repeated Escape does not re-enter this tooltip while the
|
|
206
|
+
// hide is still pending.
|
|
207
|
+
this.unbindEscapeListener();
|
|
123
208
|
this.shouldHidePopover = true;
|
|
124
209
|
// Disable the event listeners
|
|
125
210
|
this.currentTimeoutId = setTimeout(() => {
|
|
@@ -140,6 +225,13 @@ export class VanillaTooltip {
|
|
|
140
225
|
}, immediate ? 0 : this.timeout);
|
|
141
226
|
}
|
|
142
227
|
show() {
|
|
228
|
+
// Bound before the open delay so Escape can dismiss during it, and before the
|
|
229
|
+
// `isDisplayed` guard so re-hovering a tooltip whose hide is still pending (`hide()`
|
|
230
|
+
// unbinds synchronously, but the tooltip stays on screen until its timeout) restores
|
|
231
|
+
// Escape rather than leaving the visible tooltip undismissable.
|
|
232
|
+
if (isExperimentEnabled('platform_editor_use_vanilla_components')) {
|
|
233
|
+
this.bindEscapeListener();
|
|
234
|
+
}
|
|
143
235
|
if (this.isDisplayed) {
|
|
144
236
|
return;
|
|
145
237
|
}
|
|
@@ -20,7 +20,7 @@ var NETWORK_FAILURE_REGEX = /^network failure/i;
|
|
|
20
20
|
var RESIZE_OBSERVER_LOOP_REGEX = /ResizeObserver loop completed with undelivered notifications/;
|
|
21
21
|
var SENTRY_DSN = 'https://0b10c8e02fb44d8796c047b102c9bee8@o55978.ingest.sentry.io/4505129224110080';
|
|
22
22
|
var packageName = 'editor-common'; // Sentry doesn't accept '/' in its releases https://docs.sentry.io/platforms/javascript/configuration/releases/
|
|
23
|
-
var packageVersion = "120.3.
|
|
23
|
+
var packageVersion = "120.3.3";
|
|
24
24
|
var sanitiseSentryEvents = function sanitiseSentryEvents(data, _hint) {
|
|
25
25
|
// Remove URL as it has UGC
|
|
26
26
|
// Ignored via go/ees007
|
|
@@ -21,7 +21,7 @@ import withAnalyticsEvents from '@atlaskit/analytics-next/withAnalyticsEvents';
|
|
|
21
21
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
22
22
|
import Layer from '../Layer';
|
|
23
23
|
var packageName = "@atlaskit/editor-common";
|
|
24
|
-
var packageVersion = "120.3.
|
|
24
|
+
var packageVersion = "120.3.3";
|
|
25
25
|
var halfFocusRing = 1;
|
|
26
26
|
var dropOffset = '0, 8';
|
|
27
27
|
var fadeIn = keyframes({
|
|
@@ -5,6 +5,7 @@ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbol
|
|
|
5
5
|
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
|
|
6
6
|
import { createPopper as createLegacyPopper } from '@popperjs/core';
|
|
7
7
|
import { bind } from 'bind-event-listener';
|
|
8
|
+
import { isExperimentEnabled } from '@atlaskit/platform-feature-experiments/is-experiment-enabled';
|
|
8
9
|
import { fg } from '@atlaskit/platform-feature-flags/fg';
|
|
9
10
|
import { createPopper as createWrappedPopper } from '@atlaskit/popper/unsafe-imperative';
|
|
10
11
|
var startingOffset = {
|
|
@@ -19,6 +20,26 @@ var endingOffset = {
|
|
|
19
20
|
offset: [0, 8]
|
|
20
21
|
}
|
|
21
22
|
};
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Namespaced to keep generated ids from colliding with ids the host page owns, since they share
|
|
26
|
+
* the document's single id space.
|
|
27
|
+
*/
|
|
28
|
+
var TOOLTIP_ID_PREFIX = 'ak-editor-internal-tooltip';
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Generates a tooltip id for `aria-describedby`/`popovertarget`.
|
|
32
|
+
*
|
|
33
|
+
* `crypto.randomUUID` covers effectively all production traffic
|
|
34
|
+
* The counter is only a fallback for environments without it (for example a non-secure context)
|
|
35
|
+
* and is scoped to this closure rather than module state.
|
|
36
|
+
*/
|
|
37
|
+
var generateTooltipId = function () {
|
|
38
|
+
var count = 0;
|
|
39
|
+
return function () {
|
|
40
|
+
return typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function' ? "".concat(TOOLTIP_ID_PREFIX, "-").concat(crypto.randomUUID()) : "".concat(TOOLTIP_ID_PREFIX, "-").concat(count += 1);
|
|
41
|
+
};
|
|
42
|
+
}();
|
|
22
43
|
function getCreatePopper() {
|
|
23
44
|
if (fg('platform-dst-popper-consolidation')) {
|
|
24
45
|
return createWrappedPopper;
|
|
@@ -33,9 +54,31 @@ function getCreatePopper() {
|
|
|
33
54
|
* Uses popperJS for positioning
|
|
34
55
|
*/
|
|
35
56
|
export var VanillaTooltip = /*#__PURE__*/function () {
|
|
36
|
-
function VanillaTooltip(button, content,
|
|
37
57
|
/**
|
|
38
|
-
*
|
|
58
|
+
* Set only while this tooltip is on screen, so no listener is retained at rest.
|
|
59
|
+
*/
|
|
60
|
+
|
|
61
|
+
function VanillaTooltip(
|
|
62
|
+
/**
|
|
63
|
+
* The element that the tooltip describes and Popper uses as its anchor.
|
|
64
|
+
*
|
|
65
|
+
* Prefer a `<button>`: it is focusable and announced by assistive tech for free, and is the
|
|
66
|
+
* only element the browser honours `popovertarget` on. Anything else works, since this
|
|
67
|
+
* class calls `showPopover()`/`hidePopover()` itself, but then make sure it:
|
|
68
|
+
*
|
|
69
|
+
* - **Renders its children**, as the tooltip is appended to the trigger. `<img>`, `<input>`
|
|
70
|
+
* and `<br>` accept the append without error but never render it, leaving the tooltip
|
|
71
|
+
* silently at zero size.
|
|
72
|
+
* - **Is reachable**, if keyboard and screen reader users need the tooltip — usually
|
|
73
|
+
* `tabindex="0"` plus a role and accessible name, since `focus`/`blur` are bound to the
|
|
74
|
+
* trigger and `aria-describedby` is set on it.
|
|
75
|
+
*/
|
|
76
|
+
trigger, content,
|
|
77
|
+
/**
|
|
78
|
+
* Id associated to the tooltip - must be unique within the document.
|
|
79
|
+
*
|
|
80
|
+
* Pass `undefined` to have one generated, which is preferred: callers otherwise have to
|
|
81
|
+
* solve uniqueness themselves, and every consumer had solved it differently.
|
|
39
82
|
*/
|
|
40
83
|
id,
|
|
41
84
|
/**
|
|
@@ -62,29 +105,30 @@ export var VanillaTooltip = /*#__PURE__*/function () {
|
|
|
62
105
|
_defineProperty(this, "listeners", []);
|
|
63
106
|
_defineProperty(this, "shouldHidePopover", false);
|
|
64
107
|
_defineProperty(this, "isDisplayed", false);
|
|
65
|
-
this.
|
|
108
|
+
this.trigger = trigger;
|
|
66
109
|
this.timeout = timeout;
|
|
67
110
|
this.onShow = onShow;
|
|
68
|
-
|
|
111
|
+
// Created in the trigger's own document rather than the global one, so nothing depends on
|
|
112
|
+
// the parent realm when the editor renders inside an iframe. Gated alongside the Escape
|
|
113
|
+
// listener's window so the whole iframe fix moves as a single unit.
|
|
114
|
+
var ownerDocument = isExperimentEnabled('platform_editor_use_vanilla_components') ? trigger.ownerDocument : document;
|
|
115
|
+
var tooltip = ownerDocument.createElement('span');
|
|
69
116
|
tooltip.role = 'tooltip';
|
|
70
117
|
tooltip.popover = 'hint';
|
|
71
118
|
tooltip.className = className;
|
|
72
|
-
tooltip.id = id;
|
|
119
|
+
tooltip.id = id !== null && id !== void 0 ? id : generateTooltipId();
|
|
73
120
|
tooltip.textContent = content;
|
|
74
121
|
if (styles) {
|
|
75
122
|
Object.assign(tooltip.style, styles);
|
|
76
123
|
}
|
|
77
124
|
this.tooltip = tooltip;
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
// Prepare the button to have the popover target and accessibility properties
|
|
82
|
-
button.setAttribute('popovertarget', tooltip.id);
|
|
83
|
-
button.setAttribute('aria-describedby', tooltip.id);
|
|
125
|
+
this.trigger.appendChild(tooltip);
|
|
126
|
+
this.trigger.setAttribute('popovertarget', tooltip.id);
|
|
127
|
+
this.trigger.setAttribute('aria-describedby', tooltip.id);
|
|
84
128
|
var showEvents = ['mouseenter', 'focus'];
|
|
85
129
|
var hideEvents = ['mouseleave', 'blur'];
|
|
86
130
|
showEvents.forEach(function (event) {
|
|
87
|
-
_this.listeners.push(bind(
|
|
131
|
+
_this.listeners.push(bind(_this.trigger, {
|
|
88
132
|
type: event,
|
|
89
133
|
listener: function listener() {
|
|
90
134
|
return _this.show();
|
|
@@ -92,21 +136,26 @@ export var VanillaTooltip = /*#__PURE__*/function () {
|
|
|
92
136
|
}));
|
|
93
137
|
});
|
|
94
138
|
hideEvents.forEach(function (event) {
|
|
95
|
-
_this.listeners.push(bind(
|
|
139
|
+
_this.listeners.push(bind(_this.trigger, {
|
|
96
140
|
type: event,
|
|
97
141
|
listener: function listener() {
|
|
98
142
|
return _this.hide();
|
|
99
143
|
}
|
|
100
144
|
}));
|
|
101
145
|
});
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
146
|
+
|
|
147
|
+
// Bound for this tooltip's whole lifetime, even while it is off screen. The experiment
|
|
148
|
+
// moves this to `show()` so nothing is retained at rest.
|
|
149
|
+
if (!isExperimentEnabled('platform_editor_use_vanilla_components')) {
|
|
150
|
+
this.listeners.push(bind(window, {
|
|
151
|
+
type: 'keydown',
|
|
152
|
+
listener: function listener(e) {
|
|
153
|
+
if (e.key === 'Escape') {
|
|
154
|
+
_this.hide(true);
|
|
155
|
+
}
|
|
107
156
|
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
157
|
+
}));
|
|
158
|
+
}
|
|
110
159
|
|
|
111
160
|
// Hide the tooltip if the hide transition has completed
|
|
112
161
|
this.tooltip.ontransitionend = function () {
|
|
@@ -118,7 +167,7 @@ export var VanillaTooltip = /*#__PURE__*/function () {
|
|
|
118
167
|
return _createClass(VanillaTooltip, [{
|
|
119
168
|
key: "createPopperInstance",
|
|
120
169
|
value: function createPopperInstance() {
|
|
121
|
-
this.popperInstance = getCreatePopper()(this.
|
|
170
|
+
this.popperInstance = getCreatePopper()(this.trigger, this.tooltip, {
|
|
122
171
|
placement: 'top',
|
|
123
172
|
modifiers: [startingOffset]
|
|
124
173
|
});
|
|
@@ -130,22 +179,65 @@ export var VanillaTooltip = /*#__PURE__*/function () {
|
|
|
130
179
|
// Cancels any pending show/hide, which would otherwise run against detached DOM and
|
|
131
180
|
// invoke `onShow` after the owner has gone away.
|
|
132
181
|
clearTimeout(this.currentTimeoutId);
|
|
182
|
+
// Destroying while visible must not leave the listener bound to a dead tooltip.
|
|
183
|
+
this.unbindEscapeListener();
|
|
133
184
|
(_this$popperInstance = this.popperInstance) === null || _this$popperInstance === void 0 || _this$popperInstance.destroy();
|
|
134
185
|
this.listeners.forEach(function (listener) {
|
|
135
186
|
listener();
|
|
136
187
|
});
|
|
137
188
|
}
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* Starts listening for Escape to dismiss this tooltip.
|
|
192
|
+
*
|
|
193
|
+
* A tooltip only ever needs one Escape listener, so this does nothing when one is already
|
|
194
|
+
* bound.
|
|
195
|
+
*/
|
|
196
|
+
}, {
|
|
197
|
+
key: "bindEscapeListener",
|
|
198
|
+
value: function bindEscapeListener() {
|
|
199
|
+
var _this$trigger$ownerDo,
|
|
200
|
+
_this2 = this;
|
|
201
|
+
if (this.unbindEscape) {
|
|
202
|
+
return;
|
|
203
|
+
}
|
|
204
|
+
this.unbindEscape = bind((_this$trigger$ownerDo = this.trigger.ownerDocument.defaultView) !== null && _this$trigger$ownerDo !== void 0 ? _this$trigger$ownerDo : window, {
|
|
205
|
+
type: 'keydown',
|
|
206
|
+
listener: function listener(e) {
|
|
207
|
+
if (e.key === 'Escape') {
|
|
208
|
+
_this2.hide(true);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* Stops listening for Escape, so no listener is retained while this tooltip is off screen.
|
|
216
|
+
*
|
|
217
|
+
* Does nothing when no listener is bound.
|
|
218
|
+
*/
|
|
219
|
+
}, {
|
|
220
|
+
key: "unbindEscapeListener",
|
|
221
|
+
value: function unbindEscapeListener() {
|
|
222
|
+
var _this$unbindEscape;
|
|
223
|
+
(_this$unbindEscape = this.unbindEscape) === null || _this$unbindEscape === void 0 || _this$unbindEscape.call(this);
|
|
224
|
+
this.unbindEscape = undefined;
|
|
225
|
+
}
|
|
138
226
|
}, {
|
|
139
227
|
key: "hide",
|
|
140
228
|
value: function hide() {
|
|
141
|
-
var
|
|
229
|
+
var _this3 = this;
|
|
142
230
|
var immediate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
|
|
143
231
|
clearTimeout(this.currentTimeoutId);
|
|
232
|
+
|
|
233
|
+
// Unbound synchronously so a repeated Escape does not re-enter this tooltip while the
|
|
234
|
+
// hide is still pending.
|
|
235
|
+
this.unbindEscapeListener();
|
|
144
236
|
this.shouldHidePopover = true;
|
|
145
237
|
// Disable the event listeners
|
|
146
238
|
this.currentTimeoutId = setTimeout(function () {
|
|
147
|
-
var
|
|
148
|
-
(
|
|
239
|
+
var _this3$popperInstance;
|
|
240
|
+
(_this3$popperInstance = _this3.popperInstance) === null || _this3$popperInstance === void 0 || _this3$popperInstance.setOptions(function (options) {
|
|
149
241
|
return _objectSpread(_objectSpread({}, options), {}, {
|
|
150
242
|
modifiers: [startingOffset, {
|
|
151
243
|
name: 'eventListeners',
|
|
@@ -153,18 +245,25 @@ export var VanillaTooltip = /*#__PURE__*/function () {
|
|
|
153
245
|
}]
|
|
154
246
|
});
|
|
155
247
|
});
|
|
156
|
-
|
|
157
|
-
|
|
248
|
+
_this3.tooltip.style.opacity = '0';
|
|
249
|
+
_this3.isDisplayed = false;
|
|
158
250
|
// If transition animations are disabled immediately hide the popover
|
|
159
|
-
if (
|
|
160
|
-
|
|
251
|
+
if (_this3.tooltip.style.transition === 'none') {
|
|
252
|
+
_this3.tooltip.hidePopover();
|
|
161
253
|
}
|
|
162
254
|
}, immediate ? 0 : this.timeout);
|
|
163
255
|
}
|
|
164
256
|
}, {
|
|
165
257
|
key: "show",
|
|
166
258
|
value: function show() {
|
|
167
|
-
var
|
|
259
|
+
var _this4 = this;
|
|
260
|
+
// Bound before the open delay so Escape can dismiss during it, and before the
|
|
261
|
+
// `isDisplayed` guard so re-hovering a tooltip whose hide is still pending (`hide()`
|
|
262
|
+
// unbinds synchronously, but the tooltip stays on screen until its timeout) restores
|
|
263
|
+
// Escape rather than leaving the visible tooltip undismissable.
|
|
264
|
+
if (isExperimentEnabled('platform_editor_use_vanilla_components')) {
|
|
265
|
+
this.bindEscapeListener();
|
|
266
|
+
}
|
|
168
267
|
if (this.isDisplayed) {
|
|
169
268
|
return;
|
|
170
269
|
}
|
|
@@ -184,10 +283,10 @@ export var VanillaTooltip = /*#__PURE__*/function () {
|
|
|
184
283
|
|
|
185
284
|
// Enable the event listeners
|
|
186
285
|
this.currentTimeoutId = setTimeout(function () {
|
|
187
|
-
var
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
(
|
|
286
|
+
var _this4$popperInstance, _this4$onShow;
|
|
287
|
+
_this4.tooltip.style.opacity = '1';
|
|
288
|
+
_this4.tooltip.style.visibility = 'visible';
|
|
289
|
+
(_this4$popperInstance = _this4.popperInstance) === null || _this4$popperInstance === void 0 || _this4$popperInstance.setOptions(function (options) {
|
|
191
290
|
return _objectSpread(_objectSpread({}, options), {}, {
|
|
192
291
|
modifiers: [endingOffset, {
|
|
193
292
|
name: 'eventListeners',
|
|
@@ -195,8 +294,8 @@ export var VanillaTooltip = /*#__PURE__*/function () {
|
|
|
195
294
|
}]
|
|
196
295
|
});
|
|
197
296
|
});
|
|
198
|
-
|
|
199
|
-
(
|
|
297
|
+
_this4.isDisplayed = true;
|
|
298
|
+
(_this4$onShow = _this4.onShow) === null || _this4$onShow === void 0 || _this4$onShow.call(_this4);
|
|
200
299
|
}, this.timeout);
|
|
201
300
|
}
|
|
202
301
|
}]);
|
|
@@ -5,7 +5,21 @@
|
|
|
5
5
|
* Uses popperJS for positioning
|
|
6
6
|
*/
|
|
7
7
|
export declare class VanillaTooltip {
|
|
8
|
-
|
|
8
|
+
/**
|
|
9
|
+
* The element that the tooltip describes and Popper uses as its anchor.
|
|
10
|
+
*
|
|
11
|
+
* Prefer a `<button>`: it is focusable and announced by assistive tech for free, and is the
|
|
12
|
+
* only element the browser honours `popovertarget` on. Anything else works, since this
|
|
13
|
+
* class calls `showPopover()`/`hidePopover()` itself, but then make sure it:
|
|
14
|
+
*
|
|
15
|
+
* - **Renders its children**, as the tooltip is appended to the trigger. `<img>`, `<input>`
|
|
16
|
+
* and `<br>` accept the append without error but never render it, leaving the tooltip
|
|
17
|
+
* silently at zero size.
|
|
18
|
+
* - **Is reachable**, if keyboard and screen reader users need the tooltip — usually
|
|
19
|
+
* `tabindex="0"` plus a role and accessible name, since `focus`/`blur` are bound to the
|
|
20
|
+
* trigger and `aria-describedby` is set on it.
|
|
21
|
+
*/
|
|
22
|
+
private trigger;
|
|
9
23
|
private timeout;
|
|
10
24
|
/**
|
|
11
25
|
* Called when the tooltip has become visible, after `timeout` has elapsed.
|
|
@@ -19,11 +33,33 @@ export declare class VanillaTooltip {
|
|
|
19
33
|
private shouldHidePopover;
|
|
20
34
|
private tooltip;
|
|
21
35
|
private isDisplayed;
|
|
22
|
-
constructor(button: HTMLButtonElement, content: string,
|
|
23
36
|
/**
|
|
24
|
-
*
|
|
37
|
+
* Set only while this tooltip is on screen, so no listener is retained at rest.
|
|
38
|
+
*/
|
|
39
|
+
private unbindEscape;
|
|
40
|
+
constructor(
|
|
41
|
+
/**
|
|
42
|
+
* The element that the tooltip describes and Popper uses as its anchor.
|
|
43
|
+
*
|
|
44
|
+
* Prefer a `<button>`: it is focusable and announced by assistive tech for free, and is the
|
|
45
|
+
* only element the browser honours `popovertarget` on. Anything else works, since this
|
|
46
|
+
* class calls `showPopover()`/`hidePopover()` itself, but then make sure it:
|
|
47
|
+
*
|
|
48
|
+
* - **Renders its children**, as the tooltip is appended to the trigger. `<img>`, `<input>`
|
|
49
|
+
* and `<br>` accept the append without error but never render it, leaving the tooltip
|
|
50
|
+
* silently at zero size.
|
|
51
|
+
* - **Is reachable**, if keyboard and screen reader users need the tooltip — usually
|
|
52
|
+
* `tabindex="0"` plus a role and accessible name, since `focus`/`blur` are bound to the
|
|
53
|
+
* trigger and `aria-describedby` is set on it.
|
|
54
|
+
*/
|
|
55
|
+
trigger: HTMLElement, content: string,
|
|
56
|
+
/**
|
|
57
|
+
* Id associated to the tooltip - must be unique within the document.
|
|
58
|
+
*
|
|
59
|
+
* Pass `undefined` to have one generated, which is preferred: callers otherwise have to
|
|
60
|
+
* solve uniqueness themselves, and every consumer had solved it differently.
|
|
25
61
|
*/
|
|
26
|
-
id: string,
|
|
62
|
+
id: string | undefined,
|
|
27
63
|
/**
|
|
28
64
|
* Class Name – used for styling.
|
|
29
65
|
*/
|
|
@@ -33,7 +69,7 @@ export declare class VanillaTooltip {
|
|
|
33
69
|
* Useful when the tooltip is rendered in the browser's top layer (via Popover API),
|
|
34
70
|
* where ancestor CSS selectors cannot reach it.
|
|
35
71
|
*/
|
|
36
|
-
styles?: Record<string, string
|
|
72
|
+
styles?: Readonly<Record<string, string>>,
|
|
37
73
|
/**
|
|
38
74
|
* Called when the tooltip has become visible, after `timeout` has elapsed.
|
|
39
75
|
* Not called when the pointer leaves before the tooltip is shown, matching
|
|
@@ -42,6 +78,19 @@ export declare class VanillaTooltip {
|
|
|
42
78
|
onShow?: (() => void) | undefined);
|
|
43
79
|
private createPopperInstance;
|
|
44
80
|
destroy(): void;
|
|
81
|
+
/**
|
|
82
|
+
* Starts listening for Escape to dismiss this tooltip.
|
|
83
|
+
*
|
|
84
|
+
* A tooltip only ever needs one Escape listener, so this does nothing when one is already
|
|
85
|
+
* bound.
|
|
86
|
+
*/
|
|
87
|
+
private bindEscapeListener;
|
|
88
|
+
/**
|
|
89
|
+
* Stops listening for Escape, so no listener is retained while this tooltip is off screen.
|
|
90
|
+
*
|
|
91
|
+
* Does nothing when no listener is bound.
|
|
92
|
+
*/
|
|
93
|
+
private unbindEscapeListener;
|
|
45
94
|
private hide;
|
|
46
95
|
private show;
|
|
47
96
|
}
|
package/package.json
CHANGED