@primer/view-components 0.0.89 → 0.0.92
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/app/assets/javascripts/primer_view_components.js +1 -1
- package/app/assets/javascripts/primer_view_components.js.map +1 -0
- package/app/assets/styles/primer_view_components.css +0 -0
- package/app/assets/styles/primer_view_components.css.map +1 -0
- package/app/components/primer/alpha/modal-dialog-element.d.ts +18 -0
- package/app/components/primer/alpha/modal-dialog-element.js +143 -0
- package/app/components/primer/alpha/segmented-control-element.d.ts +8 -0
- package/app/components/primer/alpha/segmented-control-element.js +28 -0
- package/app/components/primer/alpha/toggle-switch-element.d.ts +28 -0
- package/app/components/primer/alpha/toggle-switch-element.js +135 -0
- package/app/components/primer/alpha/tool-tip-element.d.ts +3 -3
- package/app/components/primer/alpha/tool-tip-element.js +33 -25
- package/app/components/primer/primer.d.ts +1 -0
- package/app/components/primer/primer.js +1 -0
- package/package.json +15 -4
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
6
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
7
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
10
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
11
|
+
};
|
|
12
|
+
var _ModalDialogElement_instances, _ModalDialogElement_focusAbortController, _ModalDialogElement_abortController, _ModalDialogElement_openButton, _ModalDialogElement_shouldTryLoadingFragment, _ModalDialogElement_overlayBackdrop_get, _ModalDialogElement_keydown;
|
|
13
|
+
import { focusTrap } from '@primer/behaviors';
|
|
14
|
+
import { getFocusableChild } from '@primer/behaviors/utils';
|
|
15
|
+
function focusIfNeeded(elem) {
|
|
16
|
+
if (document.activeElement !== elem) {
|
|
17
|
+
elem === null || elem === void 0 ? void 0 : elem.focus();
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
export class ModalDialogElement extends HTMLElement {
|
|
21
|
+
constructor() {
|
|
22
|
+
super(...arguments);
|
|
23
|
+
_ModalDialogElement_instances.add(this);
|
|
24
|
+
//TODO: Do we remove the abortController from focusTrap?
|
|
25
|
+
_ModalDialogElement_focusAbortController.set(this, new AbortController());
|
|
26
|
+
_ModalDialogElement_abortController.set(this, null);
|
|
27
|
+
_ModalDialogElement_openButton.set(this, void 0);
|
|
28
|
+
_ModalDialogElement_shouldTryLoadingFragment.set(this, true);
|
|
29
|
+
}
|
|
30
|
+
get open() {
|
|
31
|
+
return this.hasAttribute('open');
|
|
32
|
+
}
|
|
33
|
+
set open(value) {
|
|
34
|
+
var _a, _b, _c, _d;
|
|
35
|
+
if (value) {
|
|
36
|
+
if (this.open)
|
|
37
|
+
return;
|
|
38
|
+
this.setAttribute('open', '');
|
|
39
|
+
(_a = __classPrivateFieldGet(this, _ModalDialogElement_instances, "a", _ModalDialogElement_overlayBackdrop_get)) === null || _a === void 0 ? void 0 : _a.classList.remove('Overlay--hidden');
|
|
40
|
+
document.body.style.overflow = 'hidden';
|
|
41
|
+
if (__classPrivateFieldGet(this, _ModalDialogElement_focusAbortController, "f").signal.aborted) {
|
|
42
|
+
__classPrivateFieldSet(this, _ModalDialogElement_focusAbortController, new AbortController(), "f");
|
|
43
|
+
}
|
|
44
|
+
focusTrap(this, undefined, __classPrivateFieldGet(this, _ModalDialogElement_focusAbortController, "f").signal);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
if (!this.open)
|
|
48
|
+
return;
|
|
49
|
+
this.removeAttribute('open');
|
|
50
|
+
(_b = __classPrivateFieldGet(this, _ModalDialogElement_instances, "a", _ModalDialogElement_overlayBackdrop_get)) === null || _b === void 0 ? void 0 : _b.classList.add('Overlay--hidden');
|
|
51
|
+
document.body.style.overflow = 'initial';
|
|
52
|
+
__classPrivateFieldGet(this, _ModalDialogElement_focusAbortController, "f").abort();
|
|
53
|
+
// if #openButton is a child of a menu, we need to focus a suitable child of the menu
|
|
54
|
+
// element since it is expected for the menu to close on click
|
|
55
|
+
const menu = ((_c = __classPrivateFieldGet(this, _ModalDialogElement_openButton, "f")) === null || _c === void 0 ? void 0 : _c.closest('details')) || ((_d = __classPrivateFieldGet(this, _ModalDialogElement_openButton, "f")) === null || _d === void 0 ? void 0 : _d.closest('action-menu'));
|
|
56
|
+
if (menu) {
|
|
57
|
+
focusIfNeeded(getFocusableChild(menu));
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
focusIfNeeded(__classPrivateFieldGet(this, _ModalDialogElement_openButton, "f"));
|
|
61
|
+
}
|
|
62
|
+
__classPrivateFieldSet(this, _ModalDialogElement_openButton, undefined, "f");
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
get showButtons() {
|
|
66
|
+
// Dialogs may also be opened from any arbitrary button with a matching show-dialog-id data attribute
|
|
67
|
+
return document.querySelectorAll(`button[data-show-dialog-id='${this.id}']`);
|
|
68
|
+
}
|
|
69
|
+
connectedCallback() {
|
|
70
|
+
if (!this.hasAttribute('role'))
|
|
71
|
+
this.setAttribute('role', 'dialog');
|
|
72
|
+
const { signal } = (__classPrivateFieldSet(this, _ModalDialogElement_abortController, new AbortController(), "f"));
|
|
73
|
+
this.ownerDocument.addEventListener('click', event => {
|
|
74
|
+
const target = event.target;
|
|
75
|
+
const clickOutsideDialog = target.closest(this.tagName) !== this;
|
|
76
|
+
const button = target === null || target === void 0 ? void 0 : target.closest('button');
|
|
77
|
+
// go over this logic:
|
|
78
|
+
if (!button) {
|
|
79
|
+
if (clickOutsideDialog) {
|
|
80
|
+
// This click is outside the dialog
|
|
81
|
+
this.close();
|
|
82
|
+
}
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let dialogId = button.getAttribute('data-close-dialog-id');
|
|
86
|
+
if (dialogId === this.id) {
|
|
87
|
+
this.close();
|
|
88
|
+
}
|
|
89
|
+
dialogId = button.getAttribute('data-submit-dialog-id');
|
|
90
|
+
if (dialogId === this.id) {
|
|
91
|
+
this.close(true);
|
|
92
|
+
}
|
|
93
|
+
dialogId = button.getAttribute('data-show-dialog-id');
|
|
94
|
+
if (dialogId === this.id) {
|
|
95
|
+
//TODO: see if I can remove this
|
|
96
|
+
event.stopPropagation();
|
|
97
|
+
__classPrivateFieldSet(this, _ModalDialogElement_openButton, button, "f");
|
|
98
|
+
this.show();
|
|
99
|
+
}
|
|
100
|
+
}, { signal });
|
|
101
|
+
this.addEventListener('keydown', e => __classPrivateFieldGet(this, _ModalDialogElement_instances, "m", _ModalDialogElement_keydown).call(this, e));
|
|
102
|
+
}
|
|
103
|
+
disconnectedCallback() {
|
|
104
|
+
var _a;
|
|
105
|
+
(_a = __classPrivateFieldGet(this, _ModalDialogElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
|
|
106
|
+
}
|
|
107
|
+
show() {
|
|
108
|
+
this.open = true;
|
|
109
|
+
}
|
|
110
|
+
close(closed = false) {
|
|
111
|
+
if (this.open === false)
|
|
112
|
+
return;
|
|
113
|
+
const eventType = closed ? 'close' : 'cancel';
|
|
114
|
+
const dialogEvent = new Event(eventType);
|
|
115
|
+
this.dispatchEvent(dialogEvent);
|
|
116
|
+
this.open = false;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
_ModalDialogElement_focusAbortController = new WeakMap(), _ModalDialogElement_abortController = new WeakMap(), _ModalDialogElement_openButton = new WeakMap(), _ModalDialogElement_shouldTryLoadingFragment = new WeakMap(), _ModalDialogElement_instances = new WeakSet(), _ModalDialogElement_overlayBackdrop_get = function _ModalDialogElement_overlayBackdrop_get() {
|
|
120
|
+
var _a;
|
|
121
|
+
if ((_a = this.parentElement) === null || _a === void 0 ? void 0 : _a.hasAttribute('data-modal-dialog-overlay')) {
|
|
122
|
+
return this.parentElement;
|
|
123
|
+
}
|
|
124
|
+
return null;
|
|
125
|
+
}, _ModalDialogElement_keydown = function _ModalDialogElement_keydown(event) {
|
|
126
|
+
if (!(event instanceof KeyboardEvent))
|
|
127
|
+
return;
|
|
128
|
+
if (event.isComposing)
|
|
129
|
+
return;
|
|
130
|
+
switch (event.key) {
|
|
131
|
+
case 'Escape':
|
|
132
|
+
if (this.open) {
|
|
133
|
+
this.close();
|
|
134
|
+
event.preventDefault();
|
|
135
|
+
event.stopPropagation();
|
|
136
|
+
}
|
|
137
|
+
break;
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
if (!window.customElements.get('modal-dialog')) {
|
|
141
|
+
window.ModalDialogElement = ModalDialogElement;
|
|
142
|
+
window.customElements.define('modal-dialog', ModalDialogElement);
|
|
143
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
/* eslint-disable custom-elements/no-constructor */
|
|
2
|
+
export default class SegmentedControlElement extends HTMLElement {
|
|
3
|
+
constructor() {
|
|
4
|
+
super();
|
|
5
|
+
this.addEventListener('click', (event) => {
|
|
6
|
+
var _a, _b;
|
|
7
|
+
const controls = Array.from(this.querySelectorAll('ul button')).filter(tab => tab instanceof HTMLElement && tab.closest(this.tagName) === this);
|
|
8
|
+
if (!(event.target instanceof Element))
|
|
9
|
+
return;
|
|
10
|
+
if (event.target.closest(this.tagName) !== this)
|
|
11
|
+
return;
|
|
12
|
+
const selectedControl = event.target.closest('button');
|
|
13
|
+
if (!(selectedControl instanceof HTMLElement) || !selectedControl.closest('ul'))
|
|
14
|
+
return;
|
|
15
|
+
for (const control of controls) {
|
|
16
|
+
(_a = control.closest('li')) === null || _a === void 0 ? void 0 : _a.classList.remove('SegmentedControl-item--selected');
|
|
17
|
+
control.setAttribute('aria-current', 'false');
|
|
18
|
+
}
|
|
19
|
+
(_b = selectedControl.closest('li')) === null || _b === void 0 ? void 0 : _b.classList.add('SegmentedControl-item--selected');
|
|
20
|
+
selectedControl.setAttribute('aria-current', 'true');
|
|
21
|
+
selectedControl.focus();
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (!window.customElements.get('segmented-control')) {
|
|
26
|
+
window.SegmentedControlElement = SegmentedControlElement;
|
|
27
|
+
window.customElements.define('segmented-control', SegmentedControlElement);
|
|
28
|
+
}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export declare class ToggleSwitchElement extends HTMLElement {
|
|
2
|
+
switch: HTMLElement;
|
|
3
|
+
loadingSpinner: HTMLElement;
|
|
4
|
+
errorIcon: HTMLElement;
|
|
5
|
+
get src(): string | null;
|
|
6
|
+
get csrf(): string | null;
|
|
7
|
+
get csrfField(): string;
|
|
8
|
+
isRemote(): boolean;
|
|
9
|
+
toggle(): void;
|
|
10
|
+
turnOn(): void;
|
|
11
|
+
turnOff(): void;
|
|
12
|
+
isOn(): boolean;
|
|
13
|
+
isOff(): boolean;
|
|
14
|
+
isDisabled(): boolean;
|
|
15
|
+
disable(): void;
|
|
16
|
+
enable(): void;
|
|
17
|
+
private performToggle;
|
|
18
|
+
private setLoadingState;
|
|
19
|
+
private setSuccessState;
|
|
20
|
+
private setErrorState;
|
|
21
|
+
private setFinishedState;
|
|
22
|
+
private check;
|
|
23
|
+
}
|
|
24
|
+
declare global {
|
|
25
|
+
interface Window {
|
|
26
|
+
ToggleSwitchElement: typeof ToggleSwitchElement;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
|
2
|
+
/* eslint-disable custom-elements/define-tag-after-class-definition */
|
|
3
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
4
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
5
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
6
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
7
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
8
|
+
};
|
|
9
|
+
import { controller, target } from '@github/catalyst';
|
|
10
|
+
import { debounce } from '@github/mini-throttle/decorators';
|
|
11
|
+
let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
|
|
12
|
+
get src() {
|
|
13
|
+
const src = this.getAttribute('src');
|
|
14
|
+
if (!src)
|
|
15
|
+
return null;
|
|
16
|
+
const link = this.ownerDocument.createElement('a');
|
|
17
|
+
link.href = src;
|
|
18
|
+
return link.href;
|
|
19
|
+
}
|
|
20
|
+
get csrf() {
|
|
21
|
+
const csrfElement = this.querySelector('[data-csrf]');
|
|
22
|
+
return this.getAttribute('csrf') || (csrfElement instanceof HTMLInputElement && csrfElement.value) || null;
|
|
23
|
+
}
|
|
24
|
+
get csrfField() {
|
|
25
|
+
// the authenticity token is passed into the element and is not generated in js land
|
|
26
|
+
return this.getAttribute('csrf-field') || 'authenticity_token';
|
|
27
|
+
}
|
|
28
|
+
isRemote() {
|
|
29
|
+
return this.src != null;
|
|
30
|
+
}
|
|
31
|
+
toggle() {
|
|
32
|
+
if (this.isRemote()) {
|
|
33
|
+
this.setLoadingState();
|
|
34
|
+
this.check();
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
this.performToggle();
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
turnOn() {
|
|
41
|
+
if (this.isDisabled()) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
this.switch.setAttribute('aria-checked', 'true');
|
|
45
|
+
this.classList.add('ToggleSwitch--checked');
|
|
46
|
+
}
|
|
47
|
+
turnOff() {
|
|
48
|
+
if (this.isDisabled()) {
|
|
49
|
+
return;
|
|
50
|
+
}
|
|
51
|
+
this.switch.setAttribute('aria-checked', 'false');
|
|
52
|
+
this.classList.remove('ToggleSwitch--checked');
|
|
53
|
+
}
|
|
54
|
+
isOn() {
|
|
55
|
+
return this.switch.getAttribute('aria-checked') === 'true';
|
|
56
|
+
}
|
|
57
|
+
isOff() {
|
|
58
|
+
return !this.isOn();
|
|
59
|
+
}
|
|
60
|
+
isDisabled() {
|
|
61
|
+
return this.switch.getAttribute('aria-disabled') === 'true';
|
|
62
|
+
}
|
|
63
|
+
disable() {
|
|
64
|
+
this.switch.setAttribute('aria-disabled', 'true');
|
|
65
|
+
}
|
|
66
|
+
enable() {
|
|
67
|
+
this.switch.setAttribute('aria-disabled', 'false');
|
|
68
|
+
}
|
|
69
|
+
performToggle() {
|
|
70
|
+
if (this.isOn()) {
|
|
71
|
+
this.turnOff();
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
this.turnOn();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
setLoadingState() {
|
|
78
|
+
this.disable();
|
|
79
|
+
this.errorIcon.setAttribute('hidden', 'hidden');
|
|
80
|
+
this.loadingSpinner.removeAttribute('hidden');
|
|
81
|
+
}
|
|
82
|
+
setSuccessState() {
|
|
83
|
+
this.setFinishedState(false);
|
|
84
|
+
}
|
|
85
|
+
setErrorState() {
|
|
86
|
+
this.setFinishedState(true);
|
|
87
|
+
}
|
|
88
|
+
setFinishedState(error) {
|
|
89
|
+
if (error) {
|
|
90
|
+
this.errorIcon.removeAttribute('hidden');
|
|
91
|
+
}
|
|
92
|
+
this.loadingSpinner.setAttribute('hidden', 'hidden');
|
|
93
|
+
this.enable();
|
|
94
|
+
}
|
|
95
|
+
async check() {
|
|
96
|
+
const body = new FormData();
|
|
97
|
+
if (this.csrf) {
|
|
98
|
+
body.append(this.csrfField, this.csrf);
|
|
99
|
+
}
|
|
100
|
+
body.append('value', this.isOn() ? '1' : '0');
|
|
101
|
+
try {
|
|
102
|
+
const response = await fetch(this.src, {
|
|
103
|
+
credentials: 'same-origin',
|
|
104
|
+
method: 'POST',
|
|
105
|
+
body
|
|
106
|
+
});
|
|
107
|
+
if (response.ok) {
|
|
108
|
+
this.setSuccessState();
|
|
109
|
+
this.performToggle();
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
this.setErrorState();
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
catch (error) {
|
|
116
|
+
this.setErrorState();
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
};
|
|
120
|
+
__decorate([
|
|
121
|
+
target
|
|
122
|
+
], ToggleSwitchElement.prototype, "switch", void 0);
|
|
123
|
+
__decorate([
|
|
124
|
+
target
|
|
125
|
+
], ToggleSwitchElement.prototype, "loadingSpinner", void 0);
|
|
126
|
+
__decorate([
|
|
127
|
+
target
|
|
128
|
+
], ToggleSwitchElement.prototype, "errorIcon", void 0);
|
|
129
|
+
__decorate([
|
|
130
|
+
debounce(300)
|
|
131
|
+
], ToggleSwitchElement.prototype, "check", null);
|
|
132
|
+
ToggleSwitchElement = __decorate([
|
|
133
|
+
controller
|
|
134
|
+
], ToggleSwitchElement);
|
|
135
|
+
export { ToggleSwitchElement };
|
|
@@ -9,13 +9,13 @@ declare class ToolTipElement extends HTMLElement {
|
|
|
9
9
|
get direction(): Direction;
|
|
10
10
|
set direction(value: Direction);
|
|
11
11
|
get control(): HTMLElement | null;
|
|
12
|
-
set
|
|
13
|
-
get
|
|
12
|
+
set hiddenFromView(value: true | false);
|
|
13
|
+
get hiddenFromView(): true | false;
|
|
14
14
|
connectedCallback(): void;
|
|
15
15
|
disconnectedCallback(): void;
|
|
16
16
|
handleEvent(event: Event): void;
|
|
17
17
|
static observedAttributes: string[];
|
|
18
|
-
attributeChangedCallback(name: string
|
|
18
|
+
attributeChangedCallback(name: string): void;
|
|
19
19
|
}
|
|
20
20
|
declare global {
|
|
21
21
|
interface Window {
|
|
@@ -1,18 +1,19 @@
|
|
|
1
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
2
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
3
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
4
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
5
|
+
};
|
|
1
6
|
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
7
|
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
8
|
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
9
|
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
10
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
11
|
};
|
|
7
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
-
};
|
|
12
12
|
var _ToolTipElement_instances, _ToolTipElement_abortController, _ToolTipElement_align, _ToolTipElement_side, _ToolTipElement_allowUpdatePosition, _ToolTipElement_update, _ToolTipElement_updatePosition;
|
|
13
13
|
import { getAnchoredPosition } from '@primer/behaviors';
|
|
14
14
|
const TOOLTIP_OPEN_CLASS = 'tooltip-open';
|
|
15
15
|
const TOOLTIP_ARROW_EDGE_OFFSET = 6;
|
|
16
|
+
const TOOLTIP_SR_ONLY_CLASS = 'sr-only';
|
|
16
17
|
const DIRECTION_CLASSES = [
|
|
17
18
|
'tooltip-n',
|
|
18
19
|
'tooltip-s',
|
|
@@ -176,11 +177,13 @@ class ToolTipElement extends HTMLElement {
|
|
|
176
177
|
get control() {
|
|
177
178
|
return this.ownerDocument.getElementById(this.htmlFor);
|
|
178
179
|
}
|
|
179
|
-
set
|
|
180
|
-
this.
|
|
180
|
+
set hiddenFromView(value) {
|
|
181
|
+
this.classList.toggle(TOOLTIP_SR_ONLY_CLASS, value);
|
|
182
|
+
if (this.isConnected)
|
|
183
|
+
__classPrivateFieldGet(this, _ToolTipElement_instances, "m", _ToolTipElement_update).call(this);
|
|
181
184
|
}
|
|
182
|
-
get
|
|
183
|
-
return this.
|
|
185
|
+
get hiddenFromView() {
|
|
186
|
+
return this.classList.contains(TOOLTIP_SR_ONLY_CLASS);
|
|
184
187
|
}
|
|
185
188
|
connectedCallback() {
|
|
186
189
|
var _a;
|
|
@@ -194,7 +197,7 @@ class ToolTipElement extends HTMLElement {
|
|
|
194
197
|
<slot></slot>
|
|
195
198
|
`;
|
|
196
199
|
}
|
|
197
|
-
this.
|
|
200
|
+
this.hiddenFromView = true;
|
|
198
201
|
__classPrivateFieldSet(this, _ToolTipElement_allowUpdatePosition, true, "f");
|
|
199
202
|
if (!this.id) {
|
|
200
203
|
this.id = `tooltip-${Date.now()}-${(Math.random() * 10000).toFixed(0)}`;
|
|
@@ -222,27 +225,35 @@ class ToolTipElement extends HTMLElement {
|
|
|
222
225
|
return;
|
|
223
226
|
// Ensures that tooltip stays open when hovering between tooltip and element
|
|
224
227
|
// WCAG Success Criterion 1.4.13 Hoverable
|
|
225
|
-
if ((event.type === 'mouseenter' || event.type === 'focus') && this.
|
|
226
|
-
this.
|
|
228
|
+
if ((event.type === 'mouseenter' || event.type === 'focus') && this.hiddenFromView) {
|
|
229
|
+
this.hiddenFromView = false;
|
|
227
230
|
}
|
|
228
231
|
else if (event.type === 'blur') {
|
|
229
|
-
this.
|
|
232
|
+
this.hiddenFromView = true;
|
|
230
233
|
}
|
|
231
234
|
else if (event.type === 'mouseleave' &&
|
|
232
235
|
event.relatedTarget !== this.control &&
|
|
233
236
|
event.relatedTarget !== this) {
|
|
234
|
-
this.
|
|
237
|
+
this.hiddenFromView = true;
|
|
235
238
|
}
|
|
236
|
-
else if (event.type === 'keydown' && event.key === 'Escape' && !this.
|
|
237
|
-
this.
|
|
239
|
+
else if (event.type === 'keydown' && event.key === 'Escape' && !this.hiddenFromView) {
|
|
240
|
+
this.hiddenFromView = true;
|
|
238
241
|
}
|
|
239
242
|
}
|
|
240
|
-
attributeChangedCallback(name
|
|
243
|
+
attributeChangedCallback(name) {
|
|
241
244
|
if (name === 'id' || name === 'data-type') {
|
|
242
245
|
if (!this.id || !this.control)
|
|
243
246
|
return;
|
|
244
247
|
if (this.type === 'label') {
|
|
245
|
-
this.control.
|
|
248
|
+
let labelledBy = this.control.getAttribute('aria-labelledby');
|
|
249
|
+
if (labelledBy) {
|
|
250
|
+
labelledBy = `${labelledBy} ${this.id}`;
|
|
251
|
+
}
|
|
252
|
+
else {
|
|
253
|
+
labelledBy = this.id;
|
|
254
|
+
}
|
|
255
|
+
this.control.setAttribute('aria-labelledby', labelledBy);
|
|
256
|
+
// Prevent duplicate accessible name announcements.
|
|
246
257
|
this.setAttribute('aria-hidden', 'true');
|
|
247
258
|
}
|
|
248
259
|
else {
|
|
@@ -251,9 +262,6 @@ class ToolTipElement extends HTMLElement {
|
|
|
251
262
|
this.control.setAttribute('aria-describedby', describedBy);
|
|
252
263
|
}
|
|
253
264
|
}
|
|
254
|
-
else if (this.isConnected && name === 'style' && (oldValue && oldValue.includes('visibility')) || (newValue && newValue.includes('visibility'))) {
|
|
255
|
-
__classPrivateFieldGet(this, _ToolTipElement_instances, "m", _ToolTipElement_update).call(this);
|
|
256
|
-
}
|
|
257
265
|
else if (name === 'data-direction') {
|
|
258
266
|
this.classList.remove(...DIRECTION_CLASSES);
|
|
259
267
|
const direction = this.direction;
|
|
@@ -293,21 +301,21 @@ class ToolTipElement extends HTMLElement {
|
|
|
293
301
|
}
|
|
294
302
|
}
|
|
295
303
|
_ToolTipElement_abortController = new WeakMap(), _ToolTipElement_align = new WeakMap(), _ToolTipElement_side = new WeakMap(), _ToolTipElement_allowUpdatePosition = new WeakMap(), _ToolTipElement_instances = new WeakSet(), _ToolTipElement_update = function _ToolTipElement_update() {
|
|
296
|
-
if (this.
|
|
304
|
+
if (this.hiddenFromView) {
|
|
297
305
|
this.classList.remove(TOOLTIP_OPEN_CLASS, ...DIRECTION_CLASSES);
|
|
298
306
|
}
|
|
299
307
|
else {
|
|
300
308
|
this.classList.add(TOOLTIP_OPEN_CLASS);
|
|
301
309
|
for (const tooltip of this.ownerDocument.querySelectorAll(this.tagName)) {
|
|
302
310
|
if (tooltip !== this)
|
|
303
|
-
tooltip.
|
|
311
|
+
tooltip.hiddenFromView = true;
|
|
304
312
|
}
|
|
305
313
|
__classPrivateFieldGet(this, _ToolTipElement_instances, "m", _ToolTipElement_updatePosition).call(this);
|
|
306
314
|
}
|
|
307
315
|
}, _ToolTipElement_updatePosition = function _ToolTipElement_updatePosition() {
|
|
308
316
|
if (!this.control)
|
|
309
317
|
return;
|
|
310
|
-
if (!__classPrivateFieldGet(this, _ToolTipElement_allowUpdatePosition, "f") || this.
|
|
318
|
+
if (!__classPrivateFieldGet(this, _ToolTipElement_allowUpdatePosition, "f") || this.hiddenFromView)
|
|
311
319
|
return;
|
|
312
320
|
const TOOLTIP_OFFSET = 10;
|
|
313
321
|
this.style.left = `0px`; // Ensures we have reliable tooltip width in `getAnchoredPosition`
|
|
@@ -351,7 +359,7 @@ _ToolTipElement_abortController = new WeakMap(), _ToolTipElement_align = new Wea
|
|
|
351
359
|
}
|
|
352
360
|
this.classList.add(`tooltip-${direction}`);
|
|
353
361
|
};
|
|
354
|
-
ToolTipElement.observedAttributes = ['data-type', 'data-direction', 'id'
|
|
362
|
+
ToolTipElement.observedAttributes = ['data-type', 'data-direction', 'id'];
|
|
355
363
|
if (!window.customElements.get('tool-tip')) {
|
|
356
364
|
window.ToolTipElement = ToolTipElement;
|
|
357
365
|
window.customElements.define('tool-tip', ToolTipElement);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primer/view-components",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.92",
|
|
4
4
|
"description": "ViewComponents for the Primer Design System",
|
|
5
5
|
"main": "app/assets/javascripts/primer_view_components.js",
|
|
6
6
|
"module": "app/components/primer/primer.js",
|
|
@@ -20,22 +20,28 @@
|
|
|
20
20
|
"url": "https://github.com/primer/view_components/issues"
|
|
21
21
|
},
|
|
22
22
|
"files": [
|
|
23
|
+
"app/assets/**/*",
|
|
23
24
|
"app/components/primer/**/*.js",
|
|
25
|
+
"app/components/primer/**/*.css",
|
|
24
26
|
"app/components/primer/**/*.d.ts"
|
|
25
27
|
],
|
|
26
28
|
"scripts": {
|
|
27
29
|
"build:docs": "cd docs && yarn gatsby build --prefix-paths",
|
|
28
30
|
"build:docs:preview": "cd docs && yarn gatsby build",
|
|
29
|
-
"prepare": "rm -rf docs/static && mkdir -p docs/static &&
|
|
31
|
+
"prepare": "rm -rf docs/static && mkdir -p docs/static && yarn build:js && yarn build:css && cp app/assets/**/primer_view_components.* docs/static/",
|
|
30
32
|
"lint": "eslint 'app/components/**/*.ts' demo/.storybook",
|
|
31
33
|
"lint:fix": "eslint 'app/components/**/*.ts' demo/.storybook --fix",
|
|
32
|
-
"changeset:version": "changeset version && script/version"
|
|
34
|
+
"changeset:version": "changeset version && script/version",
|
|
35
|
+
"build:js": "tsc && rollup -c",
|
|
36
|
+
"build:css": "postcss -o app/assets/styles/primer_view_components.css app/components/primer/primer.pcss"
|
|
33
37
|
},
|
|
34
38
|
"dependencies": {
|
|
35
39
|
"@github/auto-complete-element": "^3.3.4",
|
|
40
|
+
"@github/catalyst": "^1.6.0",
|
|
36
41
|
"@github/clipboard-copy-element": "^1.1.2",
|
|
37
42
|
"@github/details-menu-element": "^1.0.12",
|
|
38
43
|
"@github/image-crop-element": "^5.0.0",
|
|
44
|
+
"@github/mini-throttle": "^2.1.0",
|
|
39
45
|
"@github/tab-container-element": "^3.1.2",
|
|
40
46
|
"@github/time-elements": "^3.1.2",
|
|
41
47
|
"@primer/behaviors": "^1.1.3"
|
|
@@ -44,17 +50,22 @@
|
|
|
44
50
|
"@changesets/changelog-github": "^0.4.6",
|
|
45
51
|
"@changesets/cli": "^2.24.1",
|
|
46
52
|
"@github/prettier-config": "0.0.4",
|
|
47
|
-
"@primer/css": "^20.
|
|
53
|
+
"@primer/css": "^20.4.2",
|
|
48
54
|
"@primer/primitives": "^7.9.0",
|
|
49
55
|
"@rollup/plugin-node-resolve": "^13.3.0",
|
|
50
56
|
"@rollup/plugin-typescript": "^8.3.3",
|
|
51
57
|
"@typescript-eslint/eslint-plugin": "^5.31.0",
|
|
52
58
|
"@typescript-eslint/parser": "^5.31.0",
|
|
59
|
+
"cssnano": "^5.1.13",
|
|
53
60
|
"eslint": "^8.20.0",
|
|
54
61
|
"eslint-plugin-custom-elements": "^0.0.6",
|
|
55
62
|
"eslint-plugin-github": "^4.3.7",
|
|
56
63
|
"eslint-plugin-prettier": "^4.2.1",
|
|
57
64
|
"mocha": "^10.0.0",
|
|
65
|
+
"postcss": "^8.4.16",
|
|
66
|
+
"postcss-cli": "^10.0.0",
|
|
67
|
+
"postcss-import": "^14.1.0",
|
|
68
|
+
"postcss-preset-env": "^7.8.0",
|
|
58
69
|
"rollup": "^2.77.1",
|
|
59
70
|
"rollup-plugin-terser": "^7.0.2",
|
|
60
71
|
"tslib": "^2.4.0",
|