@primer/view-components 0.36.1 → 0.36.2-rc.cf1c67eb
Sign up to get free protection for your applications and to get access to all the features.
- package/app/assets/javascripts/components/primer/alpha/action_menu/action_menu_element.d.ts +2 -0
- package/app/assets/javascripts/components/primer/primer.d.ts +1 -0
- package/app/assets/javascripts/components/primer/utils.d.ts +1 -0
- package/app/assets/javascripts/primer_view_components.js +1 -1
- package/app/assets/javascripts/primer_view_components.js.map +1 -1
- package/app/components/primer/alpha/action_menu/action_menu_element.d.ts +2 -0
- package/app/components/primer/alpha/action_menu/action_menu_element.js +31 -1
- package/app/components/primer/alpha/select_panel_element.js +6 -19
- package/app/components/primer/primer.d.ts +1 -0
- package/app/components/primer/primer.js +1 -0
- package/app/components/primer/utils.d.ts +1 -0
- package/app/components/primer/utils.js +16 -0
- package/package.json +1 -1
@@ -1,5 +1,6 @@
|
|
1
1
|
import '@oddbird/popover-polyfill';
|
2
2
|
import type { IncludeFragmentElement } from '@github/include-fragment-element';
|
3
|
+
import AnchoredPositionElement from '../../anchored_position';
|
3
4
|
type SelectVariant = 'none' | 'single' | 'multiple' | null;
|
4
5
|
type SelectedItem = {
|
5
6
|
label: string | null | undefined;
|
@@ -9,6 +10,7 @@ type SelectedItem = {
|
|
9
10
|
export declare class ActionMenuElement extends HTMLElement {
|
10
11
|
#private;
|
11
12
|
includeFragment: IncludeFragmentElement;
|
13
|
+
overlay: AnchoredPositionElement;
|
12
14
|
get selectVariant(): SelectVariant;
|
13
15
|
set selectVariant(variant: SelectVariant);
|
14
16
|
get dynamicLabelPrefix(): string;
|
@@ -15,9 +15,10 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
15
15
|
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");
|
16
16
|
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
17
17
|
};
|
18
|
-
var _ActionMenuElement_instances, _ActionMenuElement_abortController, _ActionMenuElement_originalLabel, _ActionMenuElement_inputName, _ActionMenuElement_invokerBeingClicked, _ActionMenuElement_softDisableItems, _ActionMenuElement_potentiallyDisallowActivation, _ActionMenuElement_isAnchorActivationViaSpace, _ActionMenuElement_isActivation, _ActionMenuElement_handleInvokerActivated, _ActionMenuElement_handleDialogItemActivated, _ActionMenuElement_handleItemActivated, _ActionMenuElement_handleIncludeFragmentReplaced, _ActionMenuElement_handleFocusOut, _ActionMenuElement_show, _ActionMenuElement_hide, _ActionMenuElement_isOpen, _ActionMenuElement_setDynamicLabel, _ActionMenuElement_updateInput, _ActionMenuElement_firstItem_get;
|
18
|
+
var _ActionMenuElement_instances, _ActionMenuElement_abortController, _ActionMenuElement_originalLabel, _ActionMenuElement_inputName, _ActionMenuElement_invokerBeingClicked, _ActionMenuElement_intersectionObserver, _ActionMenuElement_softDisableItems, _ActionMenuElement_potentiallyDisallowActivation, _ActionMenuElement_isAnchorActivationViaSpace, _ActionMenuElement_isActivation, _ActionMenuElement_handleInvokerActivated, _ActionMenuElement_handleDialogItemActivated, _ActionMenuElement_handleItemActivated, _ActionMenuElement_handleIncludeFragmentReplaced, _ActionMenuElement_handleFocusOut, _ActionMenuElement_show, _ActionMenuElement_hide, _ActionMenuElement_isOpen, _ActionMenuElement_setDynamicLabel, _ActionMenuElement_updateInput, _ActionMenuElement_firstItem_get;
|
19
19
|
import { controller, target } from '@github/catalyst';
|
20
20
|
import '@oddbird/popover-polyfill';
|
21
|
+
import { observeMutationsUntilConditionMet } from '../../utils';
|
21
22
|
const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]'];
|
22
23
|
const menuItemSelectors = validSelectors.map(selector => `:not([hidden]) > ${selector}`);
|
23
24
|
let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
@@ -28,6 +29,7 @@ let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
|
28
29
|
_ActionMenuElement_originalLabel.set(this, '');
|
29
30
|
_ActionMenuElement_inputName.set(this, '');
|
30
31
|
_ActionMenuElement_invokerBeingClicked.set(this, false);
|
32
|
+
_ActionMenuElement_intersectionObserver.set(this, void 0);
|
31
33
|
}
|
32
34
|
get selectVariant() {
|
33
35
|
return this.getAttribute('data-select-variant');
|
@@ -103,6 +105,30 @@ let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
|
103
105
|
signal,
|
104
106
|
});
|
105
107
|
}
|
108
|
+
// The code below updates the menu (i.e. overlay) position whenever the invoker button
|
109
|
+
// changes position within its scroll container.
|
110
|
+
//
|
111
|
+
// See: https://github.com/primer/view_components/issues/3175
|
112
|
+
const scrollUpdater = () => {
|
113
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isOpen).call(this)) {
|
114
|
+
this.overlay?.update();
|
115
|
+
}
|
116
|
+
};
|
117
|
+
__classPrivateFieldSet(this, _ActionMenuElement_intersectionObserver, new IntersectionObserver(entries => {
|
118
|
+
for (const entry of entries) {
|
119
|
+
const elem = entry.target;
|
120
|
+
if (elem === this.invokerElement) {
|
121
|
+
if (entry.isIntersecting) {
|
122
|
+
// eslint-disable-next-line github/prefer-observers
|
123
|
+
window.addEventListener('scroll', scrollUpdater, { capture: true });
|
124
|
+
}
|
125
|
+
else {
|
126
|
+
window.removeEventListener('scroll', scrollUpdater, { capture: true });
|
127
|
+
}
|
128
|
+
}
|
129
|
+
}
|
130
|
+
}), "f");
|
131
|
+
observeMutationsUntilConditionMet(this, () => Boolean(this.invokerElement), () => __classPrivateFieldGet(this, _ActionMenuElement_intersectionObserver, "f").observe(this.invokerElement));
|
106
132
|
}
|
107
133
|
disconnectedCallback() {
|
108
134
|
__classPrivateFieldGet(this, _ActionMenuElement_abortController, "f").abort();
|
@@ -240,6 +266,7 @@ _ActionMenuElement_abortController = new WeakMap();
|
|
240
266
|
_ActionMenuElement_originalLabel = new WeakMap();
|
241
267
|
_ActionMenuElement_inputName = new WeakMap();
|
242
268
|
_ActionMenuElement_invokerBeingClicked = new WeakMap();
|
269
|
+
_ActionMenuElement_intersectionObserver = new WeakMap();
|
243
270
|
_ActionMenuElement_instances = new WeakSet();
|
244
271
|
_ActionMenuElement_softDisableItems = function _ActionMenuElement_softDisableItems() {
|
245
272
|
const { signal } = __classPrivateFieldGet(this, _ActionMenuElement_abortController, "f");
|
@@ -443,6 +470,9 @@ _ActionMenuElement_firstItem_get = function _ActionMenuElement_firstItem_get() {
|
|
443
470
|
__decorate([
|
444
471
|
target
|
445
472
|
], ActionMenuElement.prototype, "includeFragment", void 0);
|
473
|
+
__decorate([
|
474
|
+
target
|
475
|
+
], ActionMenuElement.prototype, "overlay", void 0);
|
446
476
|
ActionMenuElement = __decorate([
|
447
477
|
controller
|
448
478
|
], ActionMenuElement);
|
@@ -15,12 +15,13 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
|
|
15
15
|
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");
|
16
16
|
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
17
17
|
};
|
18
|
-
var _SelectPanelElement_instances, _SelectPanelElement_dialogIntersectionObserver, _SelectPanelElement_abortController, _SelectPanelElement_originalLabel, _SelectPanelElement_inputName, _SelectPanelElement_selectedItems, _SelectPanelElement_loadingDelayTimeoutId, _SelectPanelElement_loadingAnnouncementTimeoutId, _SelectPanelElement_hasLoadedData,
|
18
|
+
var _SelectPanelElement_instances, _SelectPanelElement_dialogIntersectionObserver, _SelectPanelElement_abortController, _SelectPanelElement_originalLabel, _SelectPanelElement_inputName, _SelectPanelElement_selectedItems, _SelectPanelElement_loadingDelayTimeoutId, _SelectPanelElement_loadingAnnouncementTimeoutId, _SelectPanelElement_hasLoadedData, _SelectPanelElement_softDisableItems, _SelectPanelElement_updateTabIndices, _SelectPanelElement_potentiallyDisallowActivation, _SelectPanelElement_isAnchorActivationViaSpace, _SelectPanelElement_isActivation, _SelectPanelElement_checkSelectedItems, _SelectPanelElement_addSelectedItem, _SelectPanelElement_removeSelectedItem, _SelectPanelElement_setTextFieldLoadingSpinnerTimer, _SelectPanelElement_handleIncludeFragmentEvent, _SelectPanelElement_toggleIncludeFragmentElements, _SelectPanelElement_handleRemoteInputEvent, _SelectPanelElement_defaultFilterFn, _SelectPanelElement_handleSearchFieldEvent, _SelectPanelElement_updateItemVisibility, _SelectPanelElement_inErrorState, _SelectPanelElement_setErrorState, _SelectPanelElement_clearErrorState, _SelectPanelElement_maybeAnnounce, _SelectPanelElement_fetchStrategy_get, _SelectPanelElement_filterInputTextFieldElement_get, _SelectPanelElement_performFilteringLocally, _SelectPanelElement_handleInvokerActivated, _SelectPanelElement_handleDialogItemActivated, _SelectPanelElement_handleItemActivated, _SelectPanelElement_setDynamicLabel, _SelectPanelElement_updateInput, _SelectPanelElement_firstItem_get, _SelectPanelElement_hideItem, _SelectPanelElement_showItem, _SelectPanelElement_getItemContent;
|
19
19
|
import { getAnchoredPosition } from '@primer/behaviors';
|
20
20
|
import { controller, target } from '@github/catalyst';
|
21
21
|
import { IncludeFragmentElement } from '@github/include-fragment-element';
|
22
22
|
import '@primer/live-region-element';
|
23
23
|
import '@oddbird/popover-polyfill';
|
24
|
+
import { observeMutationsUntilConditionMet } from '../utils';
|
24
25
|
const validSelectors = ['[role="option"]'];
|
25
26
|
const menuItemSelectors = validSelectors.join(',');
|
26
27
|
const visibleMenuItemSelectors = validSelectors.map(selector => `:not([hidden]) > ${selector}`).join(',');
|
@@ -172,11 +173,11 @@ let SelectPanelElement = class SelectPanelElement extends HTMLElement {
|
|
172
173
|
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_updateInput).call(this);
|
173
174
|
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_softDisableItems).call(this);
|
174
175
|
updateWhenVisible(this);
|
175
|
-
|
176
|
+
observeMutationsUntilConditionMet(this, () => Boolean(this.remoteInput), () => {
|
176
177
|
this.remoteInput.addEventListener('loadstart', this, { signal });
|
177
178
|
this.remoteInput.addEventListener('loadend', this, { signal });
|
178
179
|
});
|
179
|
-
|
180
|
+
observeMutationsUntilConditionMet(this, () => Boolean(this.includeFragment), () => {
|
180
181
|
this.includeFragment.addEventListener('include-fragment-replaced', this, { signal });
|
181
182
|
this.includeFragment.addEventListener('error', this, { signal });
|
182
183
|
this.includeFragment.addEventListener('loadend', this, { signal });
|
@@ -201,7 +202,7 @@ let SelectPanelElement = class SelectPanelElement extends HTMLElement {
|
|
201
202
|
}
|
202
203
|
}
|
203
204
|
}), "f");
|
204
|
-
|
205
|
+
observeMutationsUntilConditionMet(this, () => Boolean(this.dialog), () => {
|
205
206
|
__classPrivateFieldGet(this, _SelectPanelElement_dialogIntersectionObserver, "f").observe(this.dialog);
|
206
207
|
this.dialog.addEventListener('close', this, { signal });
|
207
208
|
if (this.getAttribute('data-open-on-load') === 'true') {
|
@@ -209,7 +210,7 @@ let SelectPanelElement = class SelectPanelElement extends HTMLElement {
|
|
209
210
|
}
|
210
211
|
});
|
211
212
|
if (__classPrivateFieldGet(this, _SelectPanelElement_instances, "a", _SelectPanelElement_fetchStrategy_get) === FetchStrategy.LOCAL) {
|
212
|
-
|
213
|
+
observeMutationsUntilConditionMet(this, () => this.items.length > 0, () => {
|
213
214
|
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_updateItemVisibility).call(this);
|
214
215
|
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_updateInput).call(this);
|
215
216
|
});
|
@@ -399,20 +400,6 @@ _SelectPanelElement_loadingDelayTimeoutId = new WeakMap();
|
|
399
400
|
_SelectPanelElement_loadingAnnouncementTimeoutId = new WeakMap();
|
400
401
|
_SelectPanelElement_hasLoadedData = new WeakMap();
|
401
402
|
_SelectPanelElement_instances = new WeakSet();
|
402
|
-
_SelectPanelElement_waitForCondition = function _SelectPanelElement_waitForCondition(condition, body) {
|
403
|
-
if (condition()) {
|
404
|
-
body();
|
405
|
-
}
|
406
|
-
else {
|
407
|
-
const mutationObserver = new MutationObserver(() => {
|
408
|
-
if (condition()) {
|
409
|
-
body();
|
410
|
-
mutationObserver.disconnect();
|
411
|
-
}
|
412
|
-
});
|
413
|
-
mutationObserver.observe(this, { childList: true, subtree: true });
|
414
|
-
}
|
415
|
-
};
|
416
403
|
_SelectPanelElement_softDisableItems = function _SelectPanelElement_softDisableItems() {
|
417
404
|
const { signal } = __classPrivateFieldGet(this, _SelectPanelElement_abortController, "f");
|
418
405
|
for (const item of this.querySelectorAll(validSelectors.join(','))) {
|
@@ -0,0 +1 @@
|
|
1
|
+
export declare const observeMutationsUntilConditionMet: (element: Element, condition: () => boolean, body: () => void) => void;
|
@@ -0,0 +1,16 @@
|
|
1
|
+
// Waits for condition to return true. If it returns false initially, this function creates a
|
2
|
+
// MutationObserver that calls body() whenever the contents of the component change.
|
3
|
+
export const observeMutationsUntilConditionMet = (element, condition, body) => {
|
4
|
+
if (condition()) {
|
5
|
+
body();
|
6
|
+
}
|
7
|
+
else {
|
8
|
+
const mutationObserver = new MutationObserver(() => {
|
9
|
+
if (condition()) {
|
10
|
+
body();
|
11
|
+
mutationObserver.disconnect();
|
12
|
+
}
|
13
|
+
});
|
14
|
+
mutationObserver.observe(element, { childList: true, subtree: true });
|
15
|
+
}
|
16
|
+
};
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@primer/view-components",
|
3
|
-
"version": "0.36.
|
3
|
+
"version": "0.36.2-rc.cf1c67eb",
|
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",
|