@mixtint/primer-view-components 0.72.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/LICENSE.txt +21 -0
- package/README.md +30 -0
- package/app/assets/images/loading_indicator.svg +1 -0
- package/app/assets/javascripts/components/primer/alpha/action_bar_element.d.ts +17 -0
- package/app/assets/javascripts/components/primer/alpha/action_list.d.ts +16 -0
- package/app/assets/javascripts/components/primer/alpha/action_menu/action_menu_element.d.ts +49 -0
- package/app/assets/javascripts/components/primer/alpha/action_menu/action_menu_focus_zone_stack.d.ts +17 -0
- package/app/assets/javascripts/components/primer/alpha/dropdown/menu.d.ts +1 -0
- package/app/assets/javascripts/components/primer/alpha/dropdown.d.ts +1 -0
- package/app/assets/javascripts/components/primer/alpha/modal_dialog.d.ts +18 -0
- package/app/assets/javascripts/components/primer/alpha/segmented_control.d.ts +12 -0
- package/app/assets/javascripts/components/primer/alpha/select_panel_element.d.ts +65 -0
- package/app/assets/javascripts/components/primer/alpha/tab_container.d.ts +1 -0
- package/app/assets/javascripts/components/primer/alpha/toggle_switch.d.ts +34 -0
- package/app/assets/javascripts/components/primer/alpha/tool_tip.d.ts +27 -0
- package/app/assets/javascripts/components/primer/alpha/tree_view/tree_view.d.ts +42 -0
- package/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_icon_pair_element.d.ts +15 -0
- package/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_include_fragment_element.d.ts +9 -0
- package/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_roving_tab_index.d.ts +3 -0
- package/app/assets/javascripts/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.d.ts +45 -0
- package/app/assets/javascripts/components/primer/alpha/x_banner.d.ts +18 -0
- package/app/assets/javascripts/components/primer/anchored_position.d.ts +27 -0
- package/app/assets/javascripts/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
- package/app/assets/javascripts/components/primer/beta/clipboard_copy.d.ts +1 -0
- package/app/assets/javascripts/components/primer/beta/details_toggle_element.d.ts +40 -0
- package/app/assets/javascripts/components/primer/beta/nav_list.d.ts +20 -0
- package/app/assets/javascripts/components/primer/beta/nav_list_group_element.d.ts +19 -0
- package/app/assets/javascripts/components/primer/beta/relative_time.d.ts +1 -0
- package/app/assets/javascripts/components/primer/dialog_helper.d.ts +15 -0
- package/app/assets/javascripts/components/primer/focus_group.d.ts +19 -0
- package/app/assets/javascripts/components/primer/open_project/border_box/collapsible_header.d.ts +11 -0
- package/app/assets/javascripts/components/primer/open_project/collapsible.d.ts +13 -0
- package/app/assets/javascripts/components/primer/open_project/collapsible_section.d.ts +10 -0
- package/app/assets/javascripts/components/primer/open_project/danger_dialog_form_helper.d.ts +14 -0
- package/app/assets/javascripts/components/primer/open_project/filterable_tree_view.d.ts +29 -0
- package/app/assets/javascripts/components/primer/open_project/page_header_element.d.ts +9 -0
- package/app/assets/javascripts/components/primer/open_project/sub_header_element.d.ts +17 -0
- package/app/assets/javascripts/components/primer/open_project/zen_mode_button.d.ts +18 -0
- package/app/assets/javascripts/components/primer/primer.d.ts +40 -0
- package/app/assets/javascripts/components/primer/scrollable_region.d.ts +13 -0
- package/app/assets/javascripts/components/primer/shared_events.d.ts +26 -0
- package/app/assets/javascripts/components/primer/utils.d.ts +1 -0
- package/app/assets/javascripts/lib/primer/forms/primer_multi_input.d.ts +10 -0
- package/app/assets/javascripts/lib/primer/forms/primer_text_field.d.ts +28 -0
- package/app/assets/javascripts/lib/primer/forms/toggle_switch_input.d.ts +5 -0
- package/app/assets/javascripts/primer_view_components.js +2 -0
- package/app/assets/javascripts/primer_view_components.js.map +1 -0
- package/app/assets/styles/primer_view_components.css +7336 -0
- package/app/assets/styles/primer_view_components.css.map +1 -0
- package/app/components/primer/alpha/action_bar.css +49 -0
- package/app/components/primer/alpha/action_bar.css.json +14 -0
- package/app/components/primer/alpha/action_bar_element.d.ts +17 -0
- package/app/components/primer/alpha/action_bar_element.js +170 -0
- package/app/components/primer/alpha/action_list.css +526 -0
- package/app/components/primer/alpha/action_list.css.json +117 -0
- package/app/components/primer/alpha/action_list.d.ts +16 -0
- package/app/components/primer/alpha/action_list.js +70 -0
- package/app/components/primer/alpha/action_menu/action_menu_element.d.ts +49 -0
- package/app/components/primer/alpha/action_menu/action_menu_element.js +591 -0
- package/app/components/primer/alpha/action_menu/action_menu_focus_zone_stack.d.ts +17 -0
- package/app/components/primer/alpha/action_menu/action_menu_focus_zone_stack.js +62 -0
- package/app/components/primer/alpha/auto_complete.css +131 -0
- package/app/components/primer/alpha/auto_complete.css.json +21 -0
- package/app/components/primer/alpha/banner.css +146 -0
- package/app/components/primer/alpha/banner.css.json +26 -0
- package/app/components/primer/alpha/button_marketing.css +183 -0
- package/app/components/primer/alpha/button_marketing.css.json +30 -0
- package/app/components/primer/alpha/dialog.css +377 -0
- package/app/components/primer/alpha/dialog.css.json +66 -0
- package/app/components/primer/alpha/dropdown/menu.d.ts +1 -0
- package/app/components/primer/alpha/dropdown/menu.js +1 -0
- package/app/components/primer/alpha/dropdown.css +296 -0
- package/app/components/primer/alpha/dropdown.css.json +40 -0
- package/app/components/primer/alpha/dropdown.d.ts +1 -0
- package/app/components/primer/alpha/dropdown.js +1 -0
- package/app/components/primer/alpha/layout.css +374 -0
- package/app/components/primer/alpha/layout.css.json +74 -0
- package/app/components/primer/alpha/menu.css +124 -0
- package/app/components/primer/alpha/menu.css.json +26 -0
- package/app/components/primer/alpha/modal_dialog.d.ts +18 -0
- package/app/components/primer/alpha/modal_dialog.js +187 -0
- package/app/components/primer/alpha/overlay.css +25 -0
- package/app/components/primer/alpha/overlay.css.json +12 -0
- package/app/components/primer/alpha/segmented_control.css +161 -0
- package/app/components/primer/alpha/segmented_control.css.json +31 -0
- package/app/components/primer/alpha/segmented_control.d.ts +12 -0
- package/app/components/primer/alpha/segmented_control.js +59 -0
- package/app/components/primer/alpha/select_panel.css +10 -0
- package/app/components/primer/alpha/select_panel.css.json +7 -0
- package/app/components/primer/alpha/select_panel_element.d.ts +65 -0
- package/app/components/primer/alpha/select_panel_element.js +988 -0
- package/app/components/primer/alpha/skeleton_box.css +36 -0
- package/app/components/primer/alpha/skeleton_box.css.json +6 -0
- package/app/components/primer/alpha/stack.css +266 -0
- package/app/components/primer/alpha/stack.css.json +94 -0
- package/app/components/primer/alpha/stack_item.css +27 -0
- package/app/components/primer/alpha/stack_item.css.json +12 -0
- package/app/components/primer/alpha/tab_container.d.ts +1 -0
- package/app/components/primer/alpha/tab_container.js +1 -0
- package/app/components/primer/alpha/tab_nav.css +112 -0
- package/app/components/primer/alpha/tab_nav.css.json +22 -0
- package/app/components/primer/alpha/text_field.css +838 -0
- package/app/components/primer/alpha/text_field.css.json +134 -0
- package/app/components/primer/alpha/toggle_switch.css +230 -0
- package/app/components/primer/alpha/toggle_switch.css.json +40 -0
- package/app/components/primer/alpha/toggle_switch.d.ts +34 -0
- package/app/components/primer/alpha/toggle_switch.js +179 -0
- package/app/components/primer/alpha/tool_tip.d.ts +27 -0
- package/app/components/primer/alpha/tool_tip.js +443 -0
- package/app/components/primer/alpha/tree_view/tree_view.d.ts +42 -0
- package/app/components/primer/alpha/tree_view/tree_view.js +391 -0
- package/app/components/primer/alpha/tree_view/tree_view_icon_pair_element.d.ts +15 -0
- package/app/components/primer/alpha/tree_view/tree_view_icon_pair_element.js +62 -0
- package/app/components/primer/alpha/tree_view/tree_view_include_fragment_element.d.ts +9 -0
- package/app/components/primer/alpha/tree_view/tree_view_include_fragment_element.js +28 -0
- package/app/components/primer/alpha/tree_view/tree_view_roving_tab_index.d.ts +3 -0
- package/app/components/primer/alpha/tree_view/tree_view_roving_tab_index.js +130 -0
- package/app/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.d.ts +45 -0
- package/app/components/primer/alpha/tree_view/tree_view_sub_tree_node_element.js +429 -0
- package/app/components/primer/alpha/tree_view.css +396 -0
- package/app/components/primer/alpha/tree_view.css.json +52 -0
- package/app/components/primer/alpha/underline_nav.css +150 -0
- package/app/components/primer/alpha/underline_nav.css.json +26 -0
- package/app/components/primer/alpha/x_banner.d.ts +18 -0
- package/app/components/primer/alpha/x_banner.js +51 -0
- package/app/components/primer/anchored_position.d.ts +27 -0
- package/app/components/primer/anchored_position.js +159 -0
- package/app/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
- package/app/components/primer/beta/auto_complete/auto_complete.js +1 -0
- package/app/components/primer/beta/avatar.css +77 -0
- package/app/components/primer/beta/avatar.css.json +17 -0
- package/app/components/primer/beta/avatar_stack.css +145 -0
- package/app/components/primer/beta/avatar_stack.css.json +28 -0
- package/app/components/primer/beta/blankslate.css +168 -0
- package/app/components/primer/beta/blankslate.css.json +23 -0
- package/app/components/primer/beta/border_box.css +218 -0
- package/app/components/primer/beta/border_box.css.json +54 -0
- package/app/components/primer/beta/breadcrumbs.css +29 -0
- package/app/components/primer/beta/breadcrumbs.css.json +9 -0
- package/app/components/primer/beta/button.css +359 -0
- package/app/components/primer/beta/button.css.json +86 -0
- package/app/components/primer/beta/button_group.css +20 -0
- package/app/components/primer/beta/button_group.css.json +12 -0
- package/app/components/primer/beta/clipboard_copy.d.ts +1 -0
- package/app/components/primer/beta/clipboard_copy.js +58 -0
- package/app/components/primer/beta/counter.css +38 -0
- package/app/components/primer/beta/counter.css.json +10 -0
- package/app/components/primer/beta/details_toggle_element.d.ts +40 -0
- package/app/components/primer/beta/details_toggle_element.js +65 -0
- package/app/components/primer/beta/flash.css +152 -0
- package/app/components/primer/beta/flash.css.json +27 -0
- package/app/components/primer/beta/label.css +109 -0
- package/app/components/primer/beta/label.css.json +24 -0
- package/app/components/primer/beta/link.css +79 -0
- package/app/components/primer/beta/link.css.json +19 -0
- package/app/components/primer/beta/nav_list.d.ts +20 -0
- package/app/components/primer/beta/nav_list.js +192 -0
- package/app/components/primer/beta/nav_list_group_element.d.ts +19 -0
- package/app/components/primer/beta/nav_list_group_element.js +111 -0
- package/app/components/primer/beta/popover.css +215 -0
- package/app/components/primer/beta/popover.css.json +33 -0
- package/app/components/primer/beta/progress_bar.css +27 -0
- package/app/components/primer/beta/progress_bar.css.json +10 -0
- package/app/components/primer/beta/relative_time.d.ts +1 -0
- package/app/components/primer/beta/relative_time.js +1 -0
- package/app/components/primer/beta/state.css +59 -0
- package/app/components/primer/beta/state.css.json +13 -0
- package/app/components/primer/beta/subhead.css +64 -0
- package/app/components/primer/beta/subhead.css.json +14 -0
- package/app/components/primer/beta/timeline_item.css +106 -0
- package/app/components/primer/beta/timeline_item.css.json +16 -0
- package/app/components/primer/beta/truncate.css +30 -0
- package/app/components/primer/beta/truncate.css.json +12 -0
- package/app/components/primer/dialog_helper.d.ts +15 -0
- package/app/components/primer/dialog_helper.js +132 -0
- package/app/components/primer/focus_group.d.ts +19 -0
- package/app/components/primer/focus_group.js +163 -0
- package/app/components/primer/open_project/border_box/collapsible_header.css +21 -0
- package/app/components/primer/open_project/border_box/collapsible_header.css.json +11 -0
- package/app/components/primer/open_project/border_box/collapsible_header.d.ts +11 -0
- package/app/components/primer/open_project/border_box/collapsible_header.js +21 -0
- package/app/components/primer/open_project/border_grid.css +35 -0
- package/app/components/primer/open_project/border_grid.css.json +11 -0
- package/app/components/primer/open_project/collapsible.d.ts +13 -0
- package/app/components/primer/open_project/collapsible.js +67 -0
- package/app/components/primer/open_project/collapsible_section.css +5 -0
- package/app/components/primer/open_project/collapsible_section.css.json +6 -0
- package/app/components/primer/open_project/collapsible_section.d.ts +10 -0
- package/app/components/primer/open_project/collapsible_section.js +16 -0
- package/app/components/primer/open_project/danger_dialog_form_helper.d.ts +14 -0
- package/app/components/primer/open_project/danger_dialog_form_helper.js +54 -0
- package/app/components/primer/open_project/drag_handle.css +6 -0
- package/app/components/primer/open_project/drag_handle.css.json +6 -0
- package/app/components/primer/open_project/filterable_tree_view.d.ts +29 -0
- package/app/components/primer/open_project/filterable_tree_view.js +409 -0
- package/app/components/primer/open_project/input_group.css +22 -0
- package/app/components/primer/open_project/input_group.css.json +12 -0
- package/app/components/primer/open_project/page_header.css +87 -0
- package/app/components/primer/open_project/page_header.css.json +20 -0
- package/app/components/primer/open_project/page_header_element.d.ts +9 -0
- package/app/components/primer/open_project/page_header_element.js +23 -0
- package/app/components/primer/open_project/side_panel/section.css +27 -0
- package/app/components/primer/open_project/side_panel/section.css.json +11 -0
- package/app/components/primer/open_project/sub_header.css +80 -0
- package/app/components/primer/open_project/sub_header.css.json +17 -0
- package/app/components/primer/open_project/sub_header_element.d.ts +17 -0
- package/app/components/primer/open_project/sub_header_element.js +76 -0
- package/app/components/primer/open_project/zen_mode_button.d.ts +18 -0
- package/app/components/primer/open_project/zen_mode_button.js +64 -0
- package/app/components/primer/primer.d.ts +40 -0
- package/app/components/primer/primer.js +40 -0
- package/app/components/primer/scrollable_region.d.ts +13 -0
- package/app/components/primer/scrollable_region.js +52 -0
- package/app/components/primer/shared_events.d.ts +26 -0
- package/app/components/primer/shared_events.js +1 -0
- package/app/components/primer/truncate.css +23 -0
- package/app/components/primer/truncate.css.json +13 -0
- package/app/components/primer/utils.d.ts +1 -0
- package/app/components/primer/utils.js +16 -0
- package/app/lib/primer/forms/primer_multi_input.d.ts +10 -0
- package/app/lib/primer/forms/primer_multi_input.js +44 -0
- package/app/lib/primer/forms/primer_text_field.d.ts +28 -0
- package/app/lib/primer/forms/primer_text_field.js +119 -0
- package/app/lib/primer/forms/toggle_switch_input.d.ts +5 -0
- package/app/lib/primer/forms/toggle_switch_input.js +34 -0
- package/package.json +103 -0
- package/static/arguments.json +6472 -0
- package/static/audited_at.json +173 -0
- package/static/classes.json +781 -0
- package/static/constants.json +1972 -0
- package/static/form_previews.json +118 -0
- package/static/info_arch.json +21331 -0
- package/static/previews.json +9436 -0
- package/static/statuses.json +173 -0
|
@@ -0,0 +1,591 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
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;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
8
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
9
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
10
|
+
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");
|
|
11
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
12
|
+
};
|
|
13
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
14
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
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
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
17
|
+
};
|
|
18
|
+
var _ActionMenuElement_instances, _a, _ActionMenuElement_abortController, _ActionMenuElement_originalLabel, _ActionMenuElement_inputName, _ActionMenuElement_invokerBeingClicked, _ActionMenuElement_intersectionObserver, _ActionMenuElement_focusZoneStack, _ActionMenuElement_updateLevels, _ActionMenuElement_softDisableItems, _ActionMenuElement_potentiallyDisallowActivation, _ActionMenuElement_isAnchorActivationViaSpace, _ActionMenuElement_isClipboardActivationViaKeyboard, _ActionMenuElement_isActivation, _ActionMenuElement_handleItemKeyboardEvent, _ActionMenuElement_handleToggleEvent, _ActionMenuElement_handleInvokerActivated, _ActionMenuElement_handleDialogItemActivated, _ActionMenuElement_handleItemActivated, _ActionMenuElement_handleIncludeFragmentReplaced, _ActionMenuElement_handleFocusOut, _ActionMenuElement_show, _ActionMenuElement_hide, _ActionMenuElement_isOpen, _ActionMenuElement_setDynamicLabel, _ActionMenuElement_updateInput, _ActionMenuElement_firstItem_get, _ActionMenuElement_subMenuForItem, _ActionMenuElement_itemForSubMenu;
|
|
19
|
+
var ActionMenuElement_1;
|
|
20
|
+
import { controller, target } from '@github/catalyst';
|
|
21
|
+
import '@oddbird/popover-polyfill';
|
|
22
|
+
import { observeMutationsUntilConditionMet } from '../../utils';
|
|
23
|
+
import { ActionMenuFocusZoneStack } from './action_menu_focus_zone_stack';
|
|
24
|
+
import { ClipboardCopyElement } from '@github/clipboard-copy-element';
|
|
25
|
+
let ActionMenuElement = ActionMenuElement_1 = _a = class ActionMenuElement extends HTMLElement {
|
|
26
|
+
constructor() {
|
|
27
|
+
super(...arguments);
|
|
28
|
+
_ActionMenuElement_instances.add(this);
|
|
29
|
+
_ActionMenuElement_abortController.set(this, void 0);
|
|
30
|
+
_ActionMenuElement_originalLabel.set(this, '');
|
|
31
|
+
_ActionMenuElement_inputName.set(this, '');
|
|
32
|
+
_ActionMenuElement_invokerBeingClicked.set(this, false);
|
|
33
|
+
_ActionMenuElement_intersectionObserver.set(this, void 0);
|
|
34
|
+
_ActionMenuElement_focusZoneStack.set(this, void 0);
|
|
35
|
+
}
|
|
36
|
+
get selectVariant() {
|
|
37
|
+
return this.getAttribute('data-select-variant');
|
|
38
|
+
}
|
|
39
|
+
set selectVariant(variant) {
|
|
40
|
+
if (variant) {
|
|
41
|
+
this.setAttribute('data-select-variant', variant);
|
|
42
|
+
}
|
|
43
|
+
else {
|
|
44
|
+
this.removeAttribute('variant');
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
get dynamicLabelPrefix() {
|
|
48
|
+
const prefix = this.getAttribute('data-dynamic-label-prefix');
|
|
49
|
+
if (!prefix)
|
|
50
|
+
return '';
|
|
51
|
+
return `${prefix}:`;
|
|
52
|
+
}
|
|
53
|
+
set dynamicLabelPrefix(value) {
|
|
54
|
+
this.setAttribute('data-dynamic-label', value);
|
|
55
|
+
}
|
|
56
|
+
get dynamicLabel() {
|
|
57
|
+
return this.hasAttribute('data-dynamic-label');
|
|
58
|
+
}
|
|
59
|
+
set dynamicLabel(value) {
|
|
60
|
+
this.toggleAttribute('data-dynamic-label', value);
|
|
61
|
+
}
|
|
62
|
+
get popoverElement() {
|
|
63
|
+
return this.invokerElement?.popoverTargetElement || null;
|
|
64
|
+
}
|
|
65
|
+
// i.e. sub-menus
|
|
66
|
+
get childPopoverElements() {
|
|
67
|
+
return Array.from(this.overlay.querySelectorAll('anchored-position'));
|
|
68
|
+
}
|
|
69
|
+
get invokerElement() {
|
|
70
|
+
const id = this.querySelector('[role=menu]')?.id;
|
|
71
|
+
if (!id)
|
|
72
|
+
return null;
|
|
73
|
+
for (const el of this.querySelectorAll(`[aria-controls]`)) {
|
|
74
|
+
if (el.getAttribute('aria-controls') === id) {
|
|
75
|
+
return el;
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return null;
|
|
79
|
+
}
|
|
80
|
+
get invokerLabel() {
|
|
81
|
+
if (!this.invokerElement)
|
|
82
|
+
return null;
|
|
83
|
+
return this.invokerElement.querySelector('.Button-label');
|
|
84
|
+
}
|
|
85
|
+
get selectedItems() {
|
|
86
|
+
const selectedItems = this.querySelectorAll('[aria-checked=true]');
|
|
87
|
+
const results = [];
|
|
88
|
+
for (const selectedItem of selectedItems) {
|
|
89
|
+
const labelEl = selectedItem.querySelector('.ActionListItem-label');
|
|
90
|
+
results.push({
|
|
91
|
+
label: labelEl?.textContent,
|
|
92
|
+
value: selectedItem?.getAttribute('data-value'),
|
|
93
|
+
element: selectedItem,
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
return results;
|
|
97
|
+
}
|
|
98
|
+
connectedCallback() {
|
|
99
|
+
const { signal } = (__classPrivateFieldSet(this, _ActionMenuElement_abortController, new AbortController(), "f"));
|
|
100
|
+
this.addEventListener('keydown', this, { signal });
|
|
101
|
+
this.addEventListener('click', this, { signal });
|
|
102
|
+
this.addEventListener('mouseover', this, { signal });
|
|
103
|
+
this.addEventListener('focusout', this, { signal });
|
|
104
|
+
this.addEventListener('mousedown', this, { signal });
|
|
105
|
+
this.addEventListener('toggle', this, { signal, capture: true });
|
|
106
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_setDynamicLabel).call(this);
|
|
107
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateInput).call(this);
|
|
108
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_softDisableItems).call(this);
|
|
109
|
+
if (this.includeFragment) {
|
|
110
|
+
this.includeFragment.addEventListener('include-fragment-replaced', this, {
|
|
111
|
+
signal,
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
// The code below updates the menu (i.e. overlay) position whenever the invoker button
|
|
115
|
+
// changes position within its scroll container.
|
|
116
|
+
//
|
|
117
|
+
// See: https://github.com/primer/view_components/issues/3175
|
|
118
|
+
const scrollUpdater = () => {
|
|
119
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isOpen).call(this)) {
|
|
120
|
+
this.overlay?.update();
|
|
121
|
+
}
|
|
122
|
+
};
|
|
123
|
+
__classPrivateFieldSet(this, _ActionMenuElement_intersectionObserver, new IntersectionObserver(entries => {
|
|
124
|
+
for (const entry of entries) {
|
|
125
|
+
const elem = entry.target;
|
|
126
|
+
if (elem === this.invokerElement) {
|
|
127
|
+
if (entry.isIntersecting) {
|
|
128
|
+
// eslint-disable-next-line github/prefer-observers
|
|
129
|
+
window.addEventListener('scroll', scrollUpdater, { capture: true });
|
|
130
|
+
}
|
|
131
|
+
else {
|
|
132
|
+
window.removeEventListener('scroll', scrollUpdater, { capture: true });
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}), "f");
|
|
137
|
+
observeMutationsUntilConditionMet(this, () => Boolean(this.invokerElement), () => __classPrivateFieldGet(this, _ActionMenuElement_intersectionObserver, "f").observe(this.invokerElement));
|
|
138
|
+
// If there's no include fragment, then no async fetching will occur and we can
|
|
139
|
+
// mark the component as ready.
|
|
140
|
+
if (!this.includeFragment) {
|
|
141
|
+
this.setAttribute('data-ready', 'true');
|
|
142
|
+
}
|
|
143
|
+
const levelObserver = new MutationObserver(() => __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateLevels).call(this));
|
|
144
|
+
levelObserver.observe(this, { childList: true, subtree: true });
|
|
145
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateLevels).call(this);
|
|
146
|
+
__classPrivateFieldSet(this, _ActionMenuElement_focusZoneStack, new ActionMenuFocusZoneStack(), "f");
|
|
147
|
+
}
|
|
148
|
+
disconnectedCallback() {
|
|
149
|
+
__classPrivateFieldGet(this, _ActionMenuElement_abortController, "f").abort();
|
|
150
|
+
}
|
|
151
|
+
handleEvent(event) {
|
|
152
|
+
const targetIsInvoker = this.invokerElement?.contains(event.target);
|
|
153
|
+
const eventIsActivation = __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isActivation).call(this, event);
|
|
154
|
+
if (event.type === 'toggle' && event instanceof ToggleEvent) {
|
|
155
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleToggleEvent).call(this, event);
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
if (targetIsInvoker && event.type === 'mousedown') {
|
|
159
|
+
__classPrivateFieldSet(this, _ActionMenuElement_invokerBeingClicked, true, "f");
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
// Prevent safari bug that dismisses menu on mousedown instead of allowing
|
|
163
|
+
// the click event to propagate to the button
|
|
164
|
+
if (event.type === 'mousedown') {
|
|
165
|
+
event.preventDefault();
|
|
166
|
+
return;
|
|
167
|
+
}
|
|
168
|
+
if (targetIsInvoker && eventIsActivation) {
|
|
169
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleInvokerActivated).call(this, event);
|
|
170
|
+
__classPrivateFieldSet(this, _ActionMenuElement_invokerBeingClicked, false, "f");
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
if (event.type === 'focusout') {
|
|
174
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_invokerBeingClicked, "f"))
|
|
175
|
+
return;
|
|
176
|
+
// Give the browser time to focus the next element
|
|
177
|
+
requestAnimationFrame(() => {
|
|
178
|
+
if (!this.contains(document.activeElement) || document.activeElement === this.invokerElement) {
|
|
179
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleFocusOut).call(this);
|
|
180
|
+
}
|
|
181
|
+
});
|
|
182
|
+
return;
|
|
183
|
+
}
|
|
184
|
+
const item = event.target.closest(ActionMenuElement_1.menuItemSelectors.join(','));
|
|
185
|
+
const targetIsItem = item !== null;
|
|
186
|
+
if (targetIsItem && eventIsActivation) {
|
|
187
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_potentiallyDisallowActivation).call(this, event))
|
|
188
|
+
return;
|
|
189
|
+
const dialogInvoker = item.closest('[data-show-dialog-id]');
|
|
190
|
+
if (dialogInvoker) {
|
|
191
|
+
const dialog = this.ownerDocument.getElementById(dialogInvoker.getAttribute('data-show-dialog-id') || '');
|
|
192
|
+
if (dialog && this.contains(dialogInvoker)) {
|
|
193
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleDialogItemActivated).call(this, event, dialog);
|
|
194
|
+
return;
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
// Pressing the space key on a link will cause the page to scroll unless preventDefault() is called.
|
|
198
|
+
// We then click it manually to navigate.
|
|
199
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isAnchorActivationViaSpace).call(this, event)) {
|
|
200
|
+
event.preventDefault();
|
|
201
|
+
item.click();
|
|
202
|
+
}
|
|
203
|
+
const subMenu = __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_subMenuForItem).call(this, item);
|
|
204
|
+
if (subMenu) {
|
|
205
|
+
// Prevent submitting a form when clicking on sub-menu items
|
|
206
|
+
event.preventDefault();
|
|
207
|
+
subMenu.showPopover();
|
|
208
|
+
return;
|
|
209
|
+
}
|
|
210
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemActivated).call(this, item);
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
if (event.type === 'include-fragment-replaced') {
|
|
214
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleIncludeFragmentReplaced).call(this);
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
if (targetIsItem && event instanceof KeyboardEvent) {
|
|
218
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemKeyboardEvent).call(this, event, item);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
get items() {
|
|
222
|
+
return Array.from(this.querySelectorAll(ActionMenuElement_1.menuItemSelectors.join(',')));
|
|
223
|
+
}
|
|
224
|
+
getItemById(itemId) {
|
|
225
|
+
return this.querySelector(`li[data-item-id="${itemId}"`);
|
|
226
|
+
}
|
|
227
|
+
isItemDisabled(item) {
|
|
228
|
+
if (item) {
|
|
229
|
+
return item.classList.contains('ActionListItem--disabled');
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
return false;
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
disableItem(item) {
|
|
236
|
+
if (item) {
|
|
237
|
+
item.classList.add('ActionListItem--disabled');
|
|
238
|
+
item.querySelector('.ActionListContent').setAttribute('aria-disabled', 'true');
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
enableItem(item) {
|
|
242
|
+
if (item) {
|
|
243
|
+
item.classList.remove('ActionListItem--disabled');
|
|
244
|
+
item.querySelector('.ActionListContent').removeAttribute('aria-disabled');
|
|
245
|
+
}
|
|
246
|
+
}
|
|
247
|
+
isItemHidden(item) {
|
|
248
|
+
if (item) {
|
|
249
|
+
return item.hasAttribute('hidden');
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
return false;
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
hideItem(item) {
|
|
256
|
+
if (item) {
|
|
257
|
+
item.setAttribute('hidden', 'hidden');
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
showItem(item) {
|
|
261
|
+
if (item) {
|
|
262
|
+
item.removeAttribute('hidden');
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
isItemChecked(item) {
|
|
266
|
+
if (item) {
|
|
267
|
+
return item.querySelector('.ActionListContent').getAttribute('aria-checked') === 'true';
|
|
268
|
+
}
|
|
269
|
+
else {
|
|
270
|
+
return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
checkItem(item) {
|
|
274
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
|
275
|
+
const itemContent = item.querySelector('.ActionListContent');
|
|
276
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true';
|
|
277
|
+
if (!ariaChecked) {
|
|
278
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemActivated).call(this, itemContent);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
uncheckItem(item) {
|
|
283
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
|
284
|
+
const itemContent = item.querySelector('.ActionListContent');
|
|
285
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true';
|
|
286
|
+
if (ariaChecked) {
|
|
287
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemActivated).call(this, itemContent);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
};
|
|
292
|
+
_ActionMenuElement_abortController = new WeakMap();
|
|
293
|
+
_ActionMenuElement_originalLabel = new WeakMap();
|
|
294
|
+
_ActionMenuElement_inputName = new WeakMap();
|
|
295
|
+
_ActionMenuElement_invokerBeingClicked = new WeakMap();
|
|
296
|
+
_ActionMenuElement_intersectionObserver = new WeakMap();
|
|
297
|
+
_ActionMenuElement_focusZoneStack = new WeakMap();
|
|
298
|
+
_ActionMenuElement_instances = new WeakSet();
|
|
299
|
+
_ActionMenuElement_updateLevels = function _ActionMenuElement_updateLevels() {
|
|
300
|
+
let idx = 1;
|
|
301
|
+
for (const menu of this.querySelectorAll('[role=menu]')) {
|
|
302
|
+
menu.setAttribute('data-level', idx.toString());
|
|
303
|
+
idx++;
|
|
304
|
+
}
|
|
305
|
+
};
|
|
306
|
+
_ActionMenuElement_softDisableItems = function _ActionMenuElement_softDisableItems() {
|
|
307
|
+
const { signal } = __classPrivateFieldGet(this, _ActionMenuElement_abortController, "f");
|
|
308
|
+
for (const item of this.querySelectorAll(ActionMenuElement_1.validSelectors.join(','))) {
|
|
309
|
+
item.addEventListener('click', __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_potentiallyDisallowActivation).bind(this), { signal });
|
|
310
|
+
item.addEventListener('keydown', __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_potentiallyDisallowActivation).bind(this), { signal });
|
|
311
|
+
}
|
|
312
|
+
};
|
|
313
|
+
_ActionMenuElement_potentiallyDisallowActivation = function _ActionMenuElement_potentiallyDisallowActivation(event) {
|
|
314
|
+
if (!__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isActivation).call(this, event))
|
|
315
|
+
return false;
|
|
316
|
+
const item = event.target.closest(ActionMenuElement_1.menuItemSelectors.join(','));
|
|
317
|
+
if (!item)
|
|
318
|
+
return false;
|
|
319
|
+
if (item.getAttribute('aria-disabled')) {
|
|
320
|
+
event.preventDefault();
|
|
321
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
322
|
+
event.stopPropagation();
|
|
323
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
324
|
+
event.stopImmediatePropagation();
|
|
325
|
+
return true;
|
|
326
|
+
}
|
|
327
|
+
return false;
|
|
328
|
+
};
|
|
329
|
+
_ActionMenuElement_isAnchorActivationViaSpace = function _ActionMenuElement_isAnchorActivationViaSpace(event) {
|
|
330
|
+
return (event.target instanceof HTMLAnchorElement &&
|
|
331
|
+
event instanceof KeyboardEvent &&
|
|
332
|
+
event.type === 'keydown' &&
|
|
333
|
+
!(event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) &&
|
|
334
|
+
event.key === ' ');
|
|
335
|
+
};
|
|
336
|
+
_ActionMenuElement_isClipboardActivationViaKeyboard = function _ActionMenuElement_isClipboardActivationViaKeyboard(event) {
|
|
337
|
+
return (event.target instanceof ClipboardCopyElement &&
|
|
338
|
+
event instanceof KeyboardEvent &&
|
|
339
|
+
event.type === 'keydown' &&
|
|
340
|
+
!(event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) &&
|
|
341
|
+
(event.key === ' ' || event.key === 'Enter'));
|
|
342
|
+
};
|
|
343
|
+
_ActionMenuElement_isActivation = function _ActionMenuElement_isActivation(event) {
|
|
344
|
+
// Some browsers fire MouseEvents (Firefox) and others fire PointerEvents (Chrome). Activating an item via
|
|
345
|
+
// enter or space counterintuitively fires one of these rather than a KeyboardEvent. Since PointerEvent
|
|
346
|
+
// inherits from MouseEvent, it is enough to check for MouseEvent here.
|
|
347
|
+
return ((event instanceof MouseEvent && event.type === 'click') ||
|
|
348
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isAnchorActivationViaSpace).call(this, event) ||
|
|
349
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isClipboardActivationViaKeyboard).call(this, event));
|
|
350
|
+
};
|
|
351
|
+
_ActionMenuElement_handleItemKeyboardEvent = function _ActionMenuElement_handleItemKeyboardEvent(event, item) {
|
|
352
|
+
switch (event.key) {
|
|
353
|
+
case 'ArrowRight': {
|
|
354
|
+
const subMenu = __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_subMenuForItem).call(this, item);
|
|
355
|
+
subMenu?.showPopover();
|
|
356
|
+
break;
|
|
357
|
+
}
|
|
358
|
+
case 'ArrowLeft':
|
|
359
|
+
if (item.closest('role[menu]') !== this.list) {
|
|
360
|
+
const overlay = item.closest('anchored-position');
|
|
361
|
+
overlay?.hidePopover();
|
|
362
|
+
}
|
|
363
|
+
break;
|
|
364
|
+
}
|
|
365
|
+
};
|
|
366
|
+
_ActionMenuElement_handleToggleEvent = function _ActionMenuElement_handleToggleEvent(event) {
|
|
367
|
+
const subMenu = event.target;
|
|
368
|
+
if (event.newState === 'open') {
|
|
369
|
+
// allow tabbing away from primary menu, but trap focus in sub-menus
|
|
370
|
+
const isPrimaryMenu = subMenu === this.overlay;
|
|
371
|
+
__classPrivateFieldGet(this, _ActionMenuElement_focusZoneStack, "f").push(subMenu, { trapFocus: !isPrimaryMenu });
|
|
372
|
+
window.requestAnimationFrame(() => {
|
|
373
|
+
const firstItem = subMenu.querySelector(ActionMenuElement_1.menuItemSelectors.join(','));
|
|
374
|
+
firstItem?.focus();
|
|
375
|
+
});
|
|
376
|
+
}
|
|
377
|
+
else {
|
|
378
|
+
// Note that this will also cause focus to return to the invoker button, which is
|
|
379
|
+
// desirable
|
|
380
|
+
__classPrivateFieldGet(this, _ActionMenuElement_focusZoneStack, "f").pop(subMenu);
|
|
381
|
+
const item = __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_itemForSubMenu).call(this, subMenu);
|
|
382
|
+
const openPopover = document.querySelector(':popover-open');
|
|
383
|
+
if (item && !openPopover) {
|
|
384
|
+
item.focus();
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
};
|
|
388
|
+
_ActionMenuElement_handleInvokerActivated = function _ActionMenuElement_handleInvokerActivated(event) {
|
|
389
|
+
event.preventDefault();
|
|
390
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
|
391
|
+
event.stopPropagation();
|
|
392
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isOpen).call(this)) {
|
|
393
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_hide).call(this);
|
|
394
|
+
}
|
|
395
|
+
else {
|
|
396
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_show).call(this);
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
_ActionMenuElement_handleDialogItemActivated = function _ActionMenuElement_handleDialogItemActivated(event, dialog) {
|
|
400
|
+
if (this.contains(dialog)) {
|
|
401
|
+
this.querySelector('.ActionListWrap').style.display = 'none';
|
|
402
|
+
}
|
|
403
|
+
const dialog_controller = new AbortController();
|
|
404
|
+
const { signal } = dialog_controller;
|
|
405
|
+
const handleDialogClose = () => {
|
|
406
|
+
dialog_controller.abort();
|
|
407
|
+
if (this.contains(dialog)) {
|
|
408
|
+
this.querySelector('.ActionListWrap').style.display = '';
|
|
409
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isOpen).call(this)) {
|
|
410
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_hide).call(this);
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
const activeElement = this.ownerDocument.activeElement;
|
|
414
|
+
const lostFocus = this.ownerDocument.activeElement === this.ownerDocument.body;
|
|
415
|
+
const focusInClosedMenu = this.contains(activeElement);
|
|
416
|
+
const focusInDialog = dialog.contains(activeElement);
|
|
417
|
+
if (lostFocus || focusInClosedMenu || focusInDialog) {
|
|
418
|
+
setTimeout(() => {
|
|
419
|
+
// if the activeElement has changed after a task, then it's likely
|
|
420
|
+
// that other JS has tried to shift focus. We should respect that
|
|
421
|
+
// focus shift as long as it's not back at the document.
|
|
422
|
+
const newActiveElement = this.ownerDocument.activeElement;
|
|
423
|
+
if (newActiveElement === activeElement || newActiveElement === this.ownerDocument.body) {
|
|
424
|
+
this.invokerElement?.focus();
|
|
425
|
+
}
|
|
426
|
+
}, 0);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
// a modal <dialog> element will close all popovers
|
|
430
|
+
dialog.addEventListener('close', handleDialogClose, { signal });
|
|
431
|
+
dialog.addEventListener('cancel', handleDialogClose, { signal });
|
|
432
|
+
};
|
|
433
|
+
_ActionMenuElement_handleItemActivated = function _ActionMenuElement_handleItemActivated(item) {
|
|
434
|
+
// Hide popover after current event loop to prevent changes in focus from
|
|
435
|
+
// altering the target of the event. Not doing this specifically affects
|
|
436
|
+
// <a> tags. It causes the event to be sent to the currently focused element
|
|
437
|
+
// instead of the anchor, which effectively prevents navigation, i.e. it
|
|
438
|
+
// appears as if hitting enter does nothing. Curiously, clicking instead
|
|
439
|
+
// works fine.
|
|
440
|
+
if (this.selectVariant !== 'multiple') {
|
|
441
|
+
setTimeout(() => {
|
|
442
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isOpen).call(this)) {
|
|
443
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_hide).call(this);
|
|
444
|
+
}
|
|
445
|
+
});
|
|
446
|
+
}
|
|
447
|
+
// The rest of the code below deals with single/multiple selection behavior, and should not
|
|
448
|
+
// interfere with events fired by menu items whose behavior is specified outside the library.
|
|
449
|
+
if (this.selectVariant !== 'multiple' && this.selectVariant !== 'single')
|
|
450
|
+
return;
|
|
451
|
+
const ariaChecked = item.getAttribute('aria-checked');
|
|
452
|
+
const checked = ariaChecked !== 'true';
|
|
453
|
+
if (this.selectVariant === 'single') {
|
|
454
|
+
// Only check, never uncheck here. Single-select mode does not allow unchecking a checked item.
|
|
455
|
+
if (checked) {
|
|
456
|
+
item.setAttribute('aria-checked', 'true');
|
|
457
|
+
}
|
|
458
|
+
for (const checkedItem of this.querySelectorAll('[aria-checked]')) {
|
|
459
|
+
if (checkedItem !== item) {
|
|
460
|
+
checkedItem.setAttribute('aria-checked', 'false');
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_setDynamicLabel).call(this);
|
|
464
|
+
}
|
|
465
|
+
else {
|
|
466
|
+
// multi-select mode allows unchecking a checked item
|
|
467
|
+
item.setAttribute('aria-checked', `${checked}`);
|
|
468
|
+
}
|
|
469
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateInput).call(this);
|
|
470
|
+
this.dispatchEvent(new CustomEvent('itemActivated', {
|
|
471
|
+
bubbles: true,
|
|
472
|
+
detail: { item: item.parentElement, checked: this.isItemChecked(item.parentElement) },
|
|
473
|
+
}));
|
|
474
|
+
};
|
|
475
|
+
_ActionMenuElement_handleIncludeFragmentReplaced = function _ActionMenuElement_handleIncludeFragmentReplaced() {
|
|
476
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "a", _ActionMenuElement_firstItem_get)?.focus();
|
|
477
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_softDisableItems).call(this);
|
|
478
|
+
// async items have loaded, so component is ready
|
|
479
|
+
this.setAttribute('data-ready', 'true');
|
|
480
|
+
};
|
|
481
|
+
_ActionMenuElement_handleFocusOut = function _ActionMenuElement_handleFocusOut() {
|
|
482
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_hide).call(this);
|
|
483
|
+
};
|
|
484
|
+
_ActionMenuElement_show = function _ActionMenuElement_show() {
|
|
485
|
+
this.popoverElement?.showPopover();
|
|
486
|
+
};
|
|
487
|
+
_ActionMenuElement_hide = function _ActionMenuElement_hide() {
|
|
488
|
+
this.popoverElement?.hidePopover();
|
|
489
|
+
for (const child of this.childPopoverElements) {
|
|
490
|
+
child.hidePopover();
|
|
491
|
+
}
|
|
492
|
+
};
|
|
493
|
+
_ActionMenuElement_isOpen = function _ActionMenuElement_isOpen() {
|
|
494
|
+
return this.popoverElement?.matches(':popover-open');
|
|
495
|
+
};
|
|
496
|
+
_ActionMenuElement_setDynamicLabel = function _ActionMenuElement_setDynamicLabel() {
|
|
497
|
+
if (this.selectVariant !== 'single')
|
|
498
|
+
return;
|
|
499
|
+
if (!this.dynamicLabel)
|
|
500
|
+
return;
|
|
501
|
+
const invokerLabel = this.invokerLabel;
|
|
502
|
+
if (!invokerLabel)
|
|
503
|
+
return;
|
|
504
|
+
__classPrivateFieldSet(this, _ActionMenuElement_originalLabel, __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f") || (invokerLabel.textContent || ''), "f");
|
|
505
|
+
const itemLabel = this.querySelector('[aria-checked=true] .ActionListItem-label');
|
|
506
|
+
if (itemLabel && this.dynamicLabel) {
|
|
507
|
+
const prefixSpan = document.createElement('span');
|
|
508
|
+
prefixSpan.classList.add('color-fg-muted');
|
|
509
|
+
const contentSpan = document.createElement('span');
|
|
510
|
+
prefixSpan.textContent = this.dynamicLabelPrefix;
|
|
511
|
+
contentSpan.textContent = itemLabel.textContent || '';
|
|
512
|
+
invokerLabel.replaceChildren(prefixSpan, contentSpan);
|
|
513
|
+
}
|
|
514
|
+
else {
|
|
515
|
+
invokerLabel.textContent = __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f");
|
|
516
|
+
}
|
|
517
|
+
};
|
|
518
|
+
_ActionMenuElement_updateInput = function _ActionMenuElement_updateInput() {
|
|
519
|
+
if (this.selectVariant === 'single') {
|
|
520
|
+
const input = this.querySelector(`[data-list-inputs=true] input`);
|
|
521
|
+
if (!input)
|
|
522
|
+
return;
|
|
523
|
+
const selectedItem = this.selectedItems[0];
|
|
524
|
+
if (selectedItem) {
|
|
525
|
+
input.value = (selectedItem.value || selectedItem.label || '').trim();
|
|
526
|
+
input.removeAttribute('disabled');
|
|
527
|
+
}
|
|
528
|
+
else {
|
|
529
|
+
input.setAttribute('disabled', 'disabled');
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
else if (this.selectVariant !== 'none') {
|
|
533
|
+
// multiple select variant
|
|
534
|
+
const inputList = this.querySelector('[data-list-inputs=true]');
|
|
535
|
+
if (!inputList)
|
|
536
|
+
return;
|
|
537
|
+
const inputs = inputList.querySelectorAll('input');
|
|
538
|
+
if (inputs.length > 0) {
|
|
539
|
+
__classPrivateFieldSet(this, _ActionMenuElement_inputName, __classPrivateFieldGet(this, _ActionMenuElement_inputName, "f") || inputs[0].name, "f");
|
|
540
|
+
}
|
|
541
|
+
for (const selectedItem of this.selectedItems) {
|
|
542
|
+
const newInput = document.createElement('input');
|
|
543
|
+
newInput.setAttribute('data-list-input', 'true');
|
|
544
|
+
newInput.type = 'hidden';
|
|
545
|
+
newInput.autocomplete = 'off';
|
|
546
|
+
newInput.name = __classPrivateFieldGet(this, _ActionMenuElement_inputName, "f");
|
|
547
|
+
newInput.value = (selectedItem.value || selectedItem.label || '').trim();
|
|
548
|
+
inputList.append(newInput);
|
|
549
|
+
}
|
|
550
|
+
for (const input of inputs) {
|
|
551
|
+
input.remove();
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
};
|
|
555
|
+
_ActionMenuElement_firstItem_get = function _ActionMenuElement_firstItem_get() {
|
|
556
|
+
return this.querySelector(ActionMenuElement_1.menuItemSelectors.join(','));
|
|
557
|
+
};
|
|
558
|
+
_ActionMenuElement_subMenuForItem = function _ActionMenuElement_subMenuForItem(item) {
|
|
559
|
+
const popoverId = item.getAttribute('popovertarget');
|
|
560
|
+
if (popoverId) {
|
|
561
|
+
return this.querySelector(`[id="${popoverId}"]`);
|
|
562
|
+
}
|
|
563
|
+
return null;
|
|
564
|
+
};
|
|
565
|
+
_ActionMenuElement_itemForSubMenu = function _ActionMenuElement_itemForSubMenu(subMenu) {
|
|
566
|
+
const anchorId = subMenu.getAttribute('anchor');
|
|
567
|
+
if (anchorId) {
|
|
568
|
+
return this.querySelector(`[id="${anchorId}"]`);
|
|
569
|
+
}
|
|
570
|
+
return null;
|
|
571
|
+
};
|
|
572
|
+
ActionMenuElement.validItemRoles = ['menuitem', 'menuitemcheckbox', 'menuitemradio'];
|
|
573
|
+
ActionMenuElement.validSelectors = ActionMenuElement_1.validItemRoles.map(role => `[role="${role}"]`);
|
|
574
|
+
ActionMenuElement.menuItemSelectors = ActionMenuElement_1.validSelectors.map(selector => `:not([hidden]) > ${selector}`);
|
|
575
|
+
__decorate([
|
|
576
|
+
target
|
|
577
|
+
], ActionMenuElement.prototype, "includeFragment", void 0);
|
|
578
|
+
__decorate([
|
|
579
|
+
target
|
|
580
|
+
], ActionMenuElement.prototype, "overlay", void 0);
|
|
581
|
+
__decorate([
|
|
582
|
+
target
|
|
583
|
+
], ActionMenuElement.prototype, "list", void 0);
|
|
584
|
+
ActionMenuElement = ActionMenuElement_1 = __decorate([
|
|
585
|
+
controller
|
|
586
|
+
], ActionMenuElement);
|
|
587
|
+
export { ActionMenuElement };
|
|
588
|
+
if (!window.customElements.get('action-menu')) {
|
|
589
|
+
window.ActionMenuElement = ActionMenuElement;
|
|
590
|
+
window.customElements.define('action-menu', ActionMenuElement);
|
|
591
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import AnchoredPositionElement from '../../anchored_position';
|
|
2
|
+
type StackEntry = {
|
|
3
|
+
element: AnchoredPositionElement;
|
|
4
|
+
abortController?: AbortController;
|
|
5
|
+
};
|
|
6
|
+
export declare class ActionMenuFocusZoneStack {
|
|
7
|
+
#private;
|
|
8
|
+
constructor();
|
|
9
|
+
get current(): StackEntry | undefined;
|
|
10
|
+
push(next: AnchoredPositionElement, options?: {
|
|
11
|
+
trapFocus: boolean;
|
|
12
|
+
}): void;
|
|
13
|
+
pop(target?: AnchoredPositionElement): void;
|
|
14
|
+
elementIsMenuItem(element: HTMLElement): boolean;
|
|
15
|
+
get isEmpty(): boolean;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
+
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
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
+
};
|
|
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
|
+
var _ActionMenuFocusZoneStack_instances, _ActionMenuFocusZoneStack_stack, _ActionMenuFocusZoneStack_setupFocusZone, _ActionMenuFocusZoneStack_validItemRoles_get;
|
|
13
|
+
import { FocusKeys, focusTrap, focusZone } from '@primer/behaviors';
|
|
14
|
+
import { ActionMenuElement } from './action_menu_element';
|
|
15
|
+
export class ActionMenuFocusZoneStack {
|
|
16
|
+
constructor() {
|
|
17
|
+
_ActionMenuFocusZoneStack_instances.add(this);
|
|
18
|
+
_ActionMenuFocusZoneStack_stack.set(this, void 0);
|
|
19
|
+
__classPrivateFieldSet(this, _ActionMenuFocusZoneStack_stack, [], "f");
|
|
20
|
+
}
|
|
21
|
+
get current() {
|
|
22
|
+
return __classPrivateFieldGet(this, _ActionMenuFocusZoneStack_stack, "f")[__classPrivateFieldGet(this, _ActionMenuFocusZoneStack_stack, "f").length - 1];
|
|
23
|
+
}
|
|
24
|
+
push(next, options = { trapFocus: true }) {
|
|
25
|
+
const { trapFocus } = options;
|
|
26
|
+
__classPrivateFieldGet(this, _ActionMenuFocusZoneStack_stack, "f").push({ element: next, abortController: __classPrivateFieldGet(this, _ActionMenuFocusZoneStack_instances, "m", _ActionMenuFocusZoneStack_setupFocusZone).call(this, next, trapFocus) });
|
|
27
|
+
}
|
|
28
|
+
pop(target) {
|
|
29
|
+
if (target) {
|
|
30
|
+
while (__classPrivateFieldGet(this, _ActionMenuFocusZoneStack_stack, "f").length > 0 && this.current?.element !== target) {
|
|
31
|
+
const entry = __classPrivateFieldGet(this, _ActionMenuFocusZoneStack_stack, "f").pop();
|
|
32
|
+
entry?.abortController?.abort();
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
const entry = __classPrivateFieldGet(this, _ActionMenuFocusZoneStack_stack, "f").pop();
|
|
36
|
+
entry?.abortController?.abort();
|
|
37
|
+
}
|
|
38
|
+
elementIsMenuItem(element) {
|
|
39
|
+
return __classPrivateFieldGet(this, _ActionMenuFocusZoneStack_instances, "a", _ActionMenuFocusZoneStack_validItemRoles_get).includes(element.getAttribute('role') || '');
|
|
40
|
+
}
|
|
41
|
+
get isEmpty() {
|
|
42
|
+
return __classPrivateFieldGet(this, _ActionMenuFocusZoneStack_stack, "f").length === 0;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
_ActionMenuFocusZoneStack_stack = new WeakMap(), _ActionMenuFocusZoneStack_instances = new WeakSet(), _ActionMenuFocusZoneStack_setupFocusZone = function _ActionMenuFocusZoneStack_setupFocusZone(containerEl, trapFocus) {
|
|
46
|
+
const focusZoneAbortController = focusZone(containerEl, {
|
|
47
|
+
bindKeys: FocusKeys.ArrowVertical | FocusKeys.ArrowHorizontal | FocusKeys.HomeAndEnd | FocusKeys.Backspace,
|
|
48
|
+
focusOutBehavior: 'wrap',
|
|
49
|
+
focusableElementFilter: (element) => {
|
|
50
|
+
return this.elementIsMenuItem(element) && element.closest('anchored-position') === containerEl;
|
|
51
|
+
},
|
|
52
|
+
});
|
|
53
|
+
if (trapFocus) {
|
|
54
|
+
const { signal: focusZoneSignal } = focusZoneAbortController;
|
|
55
|
+
return focusTrap(containerEl, undefined, focusZoneSignal);
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
return focusZoneAbortController;
|
|
59
|
+
}
|
|
60
|
+
}, _ActionMenuFocusZoneStack_validItemRoles_get = function _ActionMenuFocusZoneStack_validItemRoles_get() {
|
|
61
|
+
return ActionMenuElement.validItemRoles;
|
|
62
|
+
};
|