@nectary/components 1.3.0 → 1.3.1
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/package.json +1 -1
- package/pop/index.js +7 -11
- package/tooltip/index.js +20 -19
- package/tooltip/tooltip-state.d.ts +2 -1
- package/tooltip/tooltip-state.js +50 -48
package/package.json
CHANGED
package/pop/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { defineCustomElement, getBooleanAttribute, getLiteralAttribute, getRect, isAttrTrue, updateLiteralAttribute, getReactEventHandler, updateBooleanAttribute, NectaryElement, throttleAnimationFrame, isElementFocused, updateIntegerAttribute, getIntegerAttribute, getFirstFocusableElement, getFirstSlotElement, Context, subscribeContext, isTargetEqual } from '../utils';
|
|
2
|
-
const templateHTML = '<style>:host{display:contents;position:relative}dialog{position:fixed;left:0;top:0;margin:0;outline:0;padding:0;border:none;box-sizing:border-box;max-width:unset;max-height:unset;z-index:1;background:0 0;overflow:visible}dialog:not([open]){display:none}dialog::backdrop{background-color:transparent}#content{position:relative;z-index:1}#target-open{display:flex;flex-direction:column;position:absolute;left:0;top:0}#focus{display:none;position:absolute;width:0;height:0}</style><slot id="target" name="target" aria-haspopup="dialog" aria-expanded="false"></slot><div id="focus"
|
|
2
|
+
const templateHTML = '<style>:host{display:contents;position:relative}dialog{position:fixed;left:0;top:0;margin:0;outline:0;padding:0;border:none;box-sizing:border-box;max-width:unset;max-height:unset;z-index:1;background:0 0;overflow:visible}dialog:not([open]){display:none}dialog::backdrop{background-color:transparent}#content{position:relative;z-index:1}#target-open{display:flex;flex-direction:column;position:absolute;left:0;top:0}#focus{display:none;position:absolute;width:0;height:0}</style><slot id="target" name="target" aria-haspopup="dialog" aria-expanded="false"></slot><div id="focus"></div><dialog id="dialog"><div id="target-open"><slot name="target-open"></slot></div><div id="content"><slot name="content"></slot></div></dialog>';
|
|
3
3
|
import { assertOrientation, disableScroll, enableScroll, orientationValues } from './utils';
|
|
4
4
|
const template = document.createElement('template');
|
|
5
5
|
template.innerHTML = templateHTML;
|
|
@@ -153,13 +153,13 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
|
|
|
153
153
|
if (!this.isConnected || this.#isOpen()) {
|
|
154
154
|
return;
|
|
155
155
|
}
|
|
156
|
-
this.#$targetSlot.addEventListener('blur', this.#
|
|
157
|
-
this.#$focus.
|
|
158
|
-
this.#$focus.
|
|
156
|
+
this.#$targetSlot.addEventListener('blur', this.#captureActiveElement, true);
|
|
157
|
+
this.#$focus.setAttribute('tabindex', '-1');
|
|
158
|
+
this.#$focus.style.display = 'block';
|
|
159
159
|
this.#$focus.focus();
|
|
160
|
-
this.#$
|
|
161
|
-
this.#$focus.
|
|
162
|
-
this.#$
|
|
160
|
+
this.#$targetSlot.removeEventListener('blur', this.#captureActiveElement, true);
|
|
161
|
+
this.#$focus.removeAttribute('tabindex');
|
|
162
|
+
this.#$focus.removeAttribute('style');
|
|
163
163
|
this.#$dialog.showModal();
|
|
164
164
|
this.#$target.setAttribute('aria-expanded', 'true');
|
|
165
165
|
this.#updateOrientation();
|
|
@@ -336,10 +336,6 @@ defineCustomElement('sinch-pop', class extends NectaryElement {
|
|
|
336
336
|
#dispatchCloseEvent() {
|
|
337
337
|
this.dispatchEvent(new CustomEvent('-close'));
|
|
338
338
|
}
|
|
339
|
-
#captureRelatedActiveElement = e => {
|
|
340
|
-
e.stopPropagation();
|
|
341
|
-
this.#targetActiveElement = e.relatedTarget;
|
|
342
|
-
};
|
|
343
339
|
#captureActiveElement = e => {
|
|
344
340
|
e.stopPropagation();
|
|
345
341
|
this.#targetActiveElement = e.target;
|
package/tooltip/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { assertOrientation, getPopOrientation, orientationValues } from './utils
|
|
|
7
7
|
const TIP_SIZE = 8;
|
|
8
8
|
const SHOW_DELAY = 1000;
|
|
9
9
|
const HIDE_DELAY = 0;
|
|
10
|
-
const ANIMATION_DURATION =
|
|
10
|
+
const ANIMATION_DURATION = 100;
|
|
11
11
|
const template = document.createElement('template');
|
|
12
12
|
template.innerHTML = templateHTML;
|
|
13
13
|
defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
@@ -37,7 +37,8 @@ defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
|
37
37
|
showDelay: SHOW_DELAY,
|
|
38
38
|
hideDelay: this.#shouldReduceMotion ? HIDE_DELAY + ANIMATION_DURATION : HIDE_DELAY,
|
|
39
39
|
hideAnimationDuration: this.#shouldReduceMotion ? 0 : ANIMATION_DURATION,
|
|
40
|
-
|
|
40
|
+
onShowStart: this.#onStateShowStart,
|
|
41
|
+
onShowEnd: this.#onStateShowEnd,
|
|
41
42
|
onHideStart: this.#onStateHideStart,
|
|
42
43
|
onHideEnd: this.#onStateHideEnd
|
|
43
44
|
});
|
|
@@ -108,29 +109,27 @@ defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
|
108
109
|
}
|
|
109
110
|
}
|
|
110
111
|
#onMouseDown = () => {
|
|
111
|
-
this.#tooltipState.
|
|
112
|
-
this.#unsubscribeScroll();
|
|
112
|
+
this.#tooltipState.destroy();
|
|
113
113
|
};
|
|
114
114
|
#onPopClose = () => {
|
|
115
115
|
this.#tooltipState.destroy();
|
|
116
|
-
this.#unsubscribeScroll();
|
|
117
116
|
};
|
|
118
117
|
#onMouseEnter = () => {
|
|
119
118
|
this.#tooltipState.show();
|
|
120
|
-
this.#subscribeScroll();
|
|
121
|
-
this.#subscribeMouseLeaveEvents();
|
|
122
119
|
};
|
|
123
120
|
#onMouseLeave = e => {
|
|
124
121
|
if (!this.#isOpen() || e.relatedTarget !== this.#$contentWrapper && e.relatedTarget !== this.#$target) {
|
|
125
122
|
this.#tooltipState.hide();
|
|
126
|
-
this.#unsubscribeScroll();
|
|
127
123
|
}
|
|
128
124
|
};
|
|
129
125
|
#onScroll = () => {
|
|
130
126
|
this.#tooltipState.destroy();
|
|
131
|
-
this.#unsubscribeScroll();
|
|
132
127
|
};
|
|
133
|
-
#
|
|
128
|
+
#onStateShowStart = () => {
|
|
129
|
+
this.#subscribeScroll();
|
|
130
|
+
this.#subscribeMouseLeaveEvents();
|
|
131
|
+
};
|
|
132
|
+
#onStateShowEnd = () => {
|
|
134
133
|
this.#dispatchShowEvent();
|
|
135
134
|
updateBooleanAttribute(this.#$pop, 'open', true);
|
|
136
135
|
requestAnimationFrame(this.#updateTipOrientation);
|
|
@@ -152,11 +151,14 @@ defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
|
152
151
|
this.#animation.play();
|
|
153
152
|
};
|
|
154
153
|
#onStateHideEnd = () => {
|
|
155
|
-
this.#
|
|
154
|
+
if (this.#isOpen()) {
|
|
155
|
+
this.#animation.finish();
|
|
156
|
+
this.#dispatchHideEvent();
|
|
157
|
+
updateBooleanAttribute(this.#$pop, 'open', false);
|
|
158
|
+
}
|
|
156
159
|
this.#resetTipOrientation();
|
|
157
|
-
updateBooleanAttribute(this.#$pop, 'open', false);
|
|
158
|
-
this.#dispatchHideEvent();
|
|
159
160
|
this.#unsubscribeMouseLeaveEvents();
|
|
161
|
+
this.#unsubscribeScroll();
|
|
160
162
|
};
|
|
161
163
|
#resetTipOrientation() {
|
|
162
164
|
this.#$tip.style.top = '';
|
|
@@ -187,17 +189,16 @@ defineCustomElement('sinch-tooltip', class extends NectaryElement {
|
|
|
187
189
|
if (!this.isConnected) {
|
|
188
190
|
return;
|
|
189
191
|
}
|
|
190
|
-
const
|
|
191
|
-
this.#$tooltipText.textContent =
|
|
192
|
-
if (
|
|
192
|
+
const text = this.text;
|
|
193
|
+
this.#$tooltipText.textContent = text;
|
|
194
|
+
if (text.length === 0) {
|
|
193
195
|
if (this.#isSubscribed) {
|
|
194
196
|
this.#tooltipState.destroy();
|
|
195
197
|
this.#unsubscribeMouseEnterEvent();
|
|
196
|
-
this.#unsubscribeMouseLeaveEvents();
|
|
197
198
|
}
|
|
198
|
-
|
|
199
|
+
} else {
|
|
200
|
+
this.#subscribeMouseEnterEvent();
|
|
199
201
|
}
|
|
200
|
-
this.#subscribeMouseEnterEvent();
|
|
201
202
|
}
|
|
202
203
|
#subscribeMouseEnterEvent() {
|
|
203
204
|
if (!this.isConnected || this.#isSubscribed) {
|
package/tooltip/tooltip-state.js
CHANGED
|
@@ -1,119 +1,121 @@
|
|
|
1
1
|
export class TooltipState {
|
|
2
2
|
#timerId = null;
|
|
3
|
-
#state = '
|
|
3
|
+
#state = 'hide';
|
|
4
4
|
#options;
|
|
5
5
|
constructor(options) {
|
|
6
6
|
this.#options = options;
|
|
7
7
|
}
|
|
8
8
|
show() {
|
|
9
|
+
console.log('-> show');
|
|
9
10
|
switch (this.#state) {
|
|
10
|
-
case '
|
|
11
|
-
{
|
|
12
|
-
this.#delayShow();
|
|
13
|
-
break;
|
|
14
|
-
}
|
|
15
|
-
case 'hide-delay':
|
|
11
|
+
case 'hide':
|
|
16
12
|
{
|
|
17
|
-
this.#
|
|
13
|
+
this.#switchToHideToShow();
|
|
18
14
|
break;
|
|
19
15
|
}
|
|
20
|
-
case 'hide':
|
|
16
|
+
case 'show-to-hide':
|
|
21
17
|
{
|
|
22
|
-
this.#
|
|
23
|
-
this.#onShow();
|
|
18
|
+
this.#switchToState('show');
|
|
24
19
|
break;
|
|
25
20
|
}
|
|
26
21
|
}
|
|
27
22
|
}
|
|
28
23
|
hide() {
|
|
24
|
+
console.log('-> hide');
|
|
29
25
|
switch (this.#state) {
|
|
30
|
-
case 'show
|
|
26
|
+
case 'hide-to-show':
|
|
31
27
|
{
|
|
32
|
-
this.#
|
|
28
|
+
this.#onHideAnimationEnd();
|
|
33
29
|
break;
|
|
34
30
|
}
|
|
35
31
|
case 'show':
|
|
36
32
|
{
|
|
37
|
-
this.#
|
|
33
|
+
this.#switchToShowToHide();
|
|
38
34
|
break;
|
|
39
35
|
}
|
|
40
36
|
}
|
|
41
37
|
}
|
|
42
38
|
interrupt() {
|
|
39
|
+
console.log('-> interrupt');
|
|
43
40
|
switch (this.#state) {
|
|
44
|
-
case 'show
|
|
41
|
+
case 'hide-to-show':
|
|
45
42
|
{
|
|
46
|
-
this.#
|
|
43
|
+
this.#onHideAnimationEnd();
|
|
47
44
|
break;
|
|
48
45
|
}
|
|
49
46
|
case 'show':
|
|
50
47
|
{
|
|
51
|
-
this.#
|
|
48
|
+
this.#switchToShowToHide(true, false);
|
|
52
49
|
break;
|
|
53
50
|
}
|
|
54
|
-
case 'hide
|
|
51
|
+
case 'show-to-hide':
|
|
55
52
|
{
|
|
56
|
-
this.#
|
|
57
|
-
this.#onHideStart();
|
|
53
|
+
this.#switchToShowToHide(true, false);
|
|
58
54
|
break;
|
|
59
55
|
}
|
|
60
56
|
}
|
|
61
57
|
}
|
|
62
58
|
destroy() {
|
|
59
|
+
console.log('-> destroy');
|
|
63
60
|
switch (this.#state) {
|
|
64
|
-
case 'show
|
|
61
|
+
case 'hide-to-show':
|
|
65
62
|
{
|
|
66
|
-
this.#
|
|
63
|
+
this.#onHideAnimationEnd();
|
|
67
64
|
break;
|
|
68
65
|
}
|
|
69
66
|
case 'show':
|
|
70
67
|
{
|
|
71
|
-
this.#
|
|
68
|
+
this.#switchToShowToHide(true, true);
|
|
72
69
|
break;
|
|
73
70
|
}
|
|
74
|
-
case 'hide
|
|
71
|
+
case 'show-to-hide':
|
|
75
72
|
{
|
|
76
|
-
this.#
|
|
77
|
-
this.#onHideStart(true);
|
|
73
|
+
this.#switchToShowToHide(true, true);
|
|
78
74
|
break;
|
|
79
75
|
}
|
|
80
76
|
case 'hide':
|
|
81
77
|
{
|
|
82
|
-
this.#
|
|
83
|
-
this.#onHideEnd();
|
|
78
|
+
this.#onHideAnimationEnd();
|
|
84
79
|
break;
|
|
85
80
|
}
|
|
86
81
|
}
|
|
87
82
|
}
|
|
88
|
-
#
|
|
89
|
-
this.#
|
|
90
|
-
this.#
|
|
83
|
+
#switchToHideToShow() {
|
|
84
|
+
this.#switchToState('hide-to-show');
|
|
85
|
+
this.#options.onShowStart();
|
|
86
|
+
if (this.#options.showDelay === 0) {
|
|
87
|
+
this.#onSwitchToShow();
|
|
88
|
+
} else {
|
|
89
|
+
this.#timerId = window.setTimeout(this.#onSwitchToShow, this.#options.showDelay);
|
|
90
|
+
}
|
|
91
91
|
}
|
|
92
|
-
#
|
|
93
|
-
this.#
|
|
94
|
-
|
|
92
|
+
#switchToShowToHide(skipDelay, skipHideAnimation) {
|
|
93
|
+
this.#switchToState('show-to-hide');
|
|
94
|
+
if (skipDelay === true || this.#options.hideDelay === 0) {
|
|
95
|
+
this.#onShowToHideEnd(skipHideAnimation);
|
|
96
|
+
} else {
|
|
97
|
+
this.#timerId = window.setTimeout(this.#onShowToHideEnd, this.#options.hideDelay);
|
|
98
|
+
}
|
|
95
99
|
}
|
|
96
|
-
#
|
|
97
|
-
this.#
|
|
98
|
-
this.#options.
|
|
100
|
+
#onSwitchToShow = () => {
|
|
101
|
+
this.#switchToState('show');
|
|
102
|
+
this.#options.onShowEnd();
|
|
99
103
|
};
|
|
100
|
-
#
|
|
101
|
-
this.#
|
|
104
|
+
#onShowToHideEnd = skipHideAnimation => {
|
|
105
|
+
this.#switchToState('hide');
|
|
102
106
|
this.#options.onHideStart();
|
|
103
|
-
if (
|
|
104
|
-
this.#
|
|
107
|
+
if (skipHideAnimation === true || this.#options.hideAnimationDuration === 0) {
|
|
108
|
+
this.#onHideAnimationEnd();
|
|
105
109
|
} else {
|
|
106
|
-
this.#timerId = window.setTimeout(this.#
|
|
110
|
+
this.#timerId = window.setTimeout(this.#onHideAnimationEnd, this.#options.hideAnimationDuration);
|
|
107
111
|
}
|
|
108
112
|
};
|
|
109
|
-
#
|
|
110
|
-
this.#
|
|
113
|
+
#onHideAnimationEnd = () => {
|
|
114
|
+
this.#switchToState('hide');
|
|
111
115
|
this.#options.onHideEnd();
|
|
112
116
|
};
|
|
113
|
-
#
|
|
114
|
-
|
|
115
|
-
this.#state = nextState;
|
|
116
|
-
}
|
|
117
|
+
#switchToState(nextState) {
|
|
118
|
+
this.#state = nextState;
|
|
117
119
|
if (this.#timerId !== null) {
|
|
118
120
|
clearTimeout(this.#timerId);
|
|
119
121
|
this.#timerId = null;
|