primer_view_components 0.13.2 → 0.15.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +63 -0
- data/app/assets/javascripts/app/components/primer/alpha/action_menu/action_menu_element.d.ts +20 -0
- data/app/assets/javascripts/app/components/primer/beta/nav_list.d.ts +0 -11
- data/app/assets/javascripts/app/components/primer/beta/nav_list_group_element.d.ts +19 -0
- data/app/assets/javascripts/app/components/primer/primer.d.ts +1 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/styles/primer_view_components.css +1 -1
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/alpha/action_bar.css +1 -1
- data/app/components/primer/alpha/action_bar.css.json +1 -4
- data/app/components/primer/alpha/action_bar.css.map +1 -1
- data/app/components/primer/alpha/action_bar.pcss +1 -17
- data/app/components/primer/alpha/action_bar_element.js +21 -9
- data/app/components/primer/alpha/action_list/item.rb +13 -3
- data/app/components/primer/alpha/action_list.css +1 -1
- data/app/components/primer/alpha/action_list.css.json +1 -0
- data/app/components/primer/alpha/action_list.css.map +1 -1
- data/app/components/primer/alpha/action_list.pcss +3 -1
- data/app/components/primer/alpha/action_list.rb +5 -5
- data/app/components/primer/alpha/action_menu/action_menu_element.d.ts +20 -0
- data/app/components/primer/alpha/action_menu/action_menu_element.js +126 -28
- data/app/components/primer/alpha/action_menu/action_menu_element.ts +110 -12
- data/app/components/primer/alpha/action_menu/group.rb +23 -0
- data/app/components/primer/alpha/action_menu/heading.rb +17 -0
- data/app/components/primer/alpha/action_menu/list.html.erb +1 -0
- data/app/components/primer/alpha/action_menu/list.rb +62 -60
- data/app/components/primer/alpha/action_menu/list_wrapper.rb +40 -0
- data/app/components/primer/alpha/action_menu.html.erb +20 -18
- data/app/components/primer/alpha/action_menu.rb +38 -1
- data/app/components/primer/alpha/auto_complete.css +1 -1
- data/app/components/primer/alpha/auto_complete.css.map +1 -1
- data/app/components/primer/alpha/button_marketing.css +1 -1
- data/app/components/primer/alpha/button_marketing.css.map +1 -1
- data/app/components/primer/alpha/dialog/header.rb +1 -1
- data/app/components/primer/alpha/dropdown.css +1 -1
- data/app/components/primer/alpha/dropdown.css.map +1 -1
- data/app/components/primer/alpha/layout.css +1 -1
- data/app/components/primer/alpha/layout.css.map +1 -1
- data/app/components/primer/alpha/menu.css +1 -1
- data/app/components/primer/alpha/menu.css.map +1 -1
- data/app/components/primer/alpha/nav_list/divider.rb +1 -0
- data/app/components/primer/alpha/nav_list/group.rb +1 -0
- data/app/components/primer/alpha/nav_list/heading.rb +1 -0
- data/app/components/primer/alpha/nav_list/item.rb +1 -0
- data/app/components/primer/alpha/nav_list.rb +1 -0
- data/app/components/primer/alpha/octicon_symbols.html.erb +1 -1
- data/app/components/primer/alpha/overlay.css +1 -1
- data/app/components/primer/alpha/overlay.css.json +2 -2
- data/app/components/primer/alpha/overlay.css.map +1 -1
- data/app/components/primer/alpha/overlay.pcss +6 -2
- data/app/components/primer/alpha/segmented_control.css +1 -1
- data/app/components/primer/alpha/segmented_control.css.json +0 -1
- data/app/components/primer/alpha/segmented_control.css.map +1 -1
- data/app/components/primer/alpha/segmented_control.js +2 -1
- data/app/components/primer/alpha/segmented_control.pcss +0 -4
- data/app/components/primer/alpha/tab_nav.css +1 -1
- data/app/components/primer/alpha/tab_nav.css.map +1 -1
- data/app/components/primer/alpha/text_field.css +1 -1
- data/app/components/primer/alpha/text_field.css.json +11 -5
- data/app/components/primer/alpha/text_field.css.map +1 -1
- data/app/components/primer/alpha/text_field.pcss +10 -1
- data/app/components/primer/alpha/toggle_switch.css +1 -1
- data/app/components/primer/alpha/toggle_switch.css.map +1 -1
- data/app/components/primer/alpha/tool_tip.js +8 -4
- data/app/components/primer/alpha/tool_tip.ts +9 -4
- data/app/components/primer/alpha/underline_nav.css +1 -1
- data/app/components/primer/alpha/underline_nav.css.map +1 -1
- data/app/components/primer/alpha/x_banner.js +2 -1
- data/app/components/primer/anchored_position.js +2 -1
- data/app/components/primer/beta/auto_complete/auto_complete.html.erb +1 -7
- data/app/components/primer/beta/auto_complete/item.rb +2 -2
- data/app/components/primer/beta/auto_complete.rb +6 -1
- data/app/components/primer/beta/avatar.rb +1 -1
- data/app/components/primer/beta/base_button.rb +3 -4
- data/app/components/primer/beta/blankslate.css +1 -1
- data/app/components/primer/beta/blankslate.css.json +1 -0
- data/app/components/primer/beta/blankslate.css.map +1 -1
- data/app/components/primer/beta/blankslate.html.erb +16 -14
- data/app/components/primer/beta/blankslate.pcss +52 -2
- data/app/components/primer/beta/border_box.css +1 -1
- data/app/components/primer/beta/border_box.css.map +1 -1
- data/app/components/primer/beta/button.css +1 -1
- data/app/components/primer/beta/button.css.json +9 -9
- data/app/components/primer/beta/button.css.map +1 -1
- data/app/components/primer/beta/button.html.erb +18 -20
- data/app/components/primer/beta/button.pcss +15 -16
- data/app/components/primer/beta/button.rb +3 -0
- data/app/components/primer/beta/button_group.css +1 -1
- data/app/components/primer/beta/button_group.css.json +2 -4
- data/app/components/primer/beta/button_group.css.map +1 -1
- data/app/components/primer/beta/button_group.html.erb +3 -1
- data/app/components/primer/beta/button_group.pcss +2 -4
- data/app/components/primer/beta/button_group.rb +41 -12
- data/app/components/primer/beta/clipboard_copy.rb +4 -0
- data/app/components/primer/beta/clipboard_copy_button.rb +25 -0
- data/app/components/primer/beta/counter.rb +1 -1
- data/app/components/primer/beta/flash.html.erb +1 -1
- data/app/components/primer/beta/icon_button.html.erb +4 -6
- data/app/components/primer/beta/icon_button.rb +1 -3
- data/app/components/primer/beta/label.css +1 -1
- data/app/components/primer/beta/label.css.map +1 -1
- data/app/components/primer/beta/link.css +1 -1
- data/app/components/primer/beta/link.css.map +1 -1
- data/app/components/primer/beta/nav_list/group.html.erb +7 -5
- data/app/components/primer/beta/nav_list/group.rb +2 -2
- data/app/components/primer/beta/nav_list.d.ts +0 -11
- data/app/components/primer/beta/nav_list.js +14 -90
- data/app/components/primer/beta/nav_list.ts +1 -85
- data/app/components/primer/beta/nav_list_group_element.d.ts +19 -0
- data/app/components/primer/beta/nav_list_group_element.js +108 -0
- data/app/components/primer/beta/nav_list_group_element.ts +97 -0
- data/app/components/primer/beta/relative_time.rb +4 -4
- data/app/components/primer/beta/subhead.css +1 -1
- data/app/components/primer/beta/subhead.css.json +2 -0
- data/app/components/primer/beta/subhead.css.map +1 -1
- data/app/components/primer/beta/subhead.pcss +8 -1
- data/app/components/primer/beta/subhead.rb +9 -1
- data/app/components/primer/component.rb +3 -0
- data/app/components/primer/focus_group.js +2 -1
- data/app/components/primer/primer.d.ts +1 -0
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/app/forms/action_menu_form.rb +20 -0
- data/app/forms/immediate_validation_form.rb +2 -2
- data/app/lib/primer/experimental_render_helpers.rb +32 -0
- data/app/lib/primer/experimental_slot_helpers.rb +30 -0
- data/app/lib/primer/fetch_or_fallback_helper.rb +0 -1
- data/app/lib/primer/octicon/cache.rb +1 -1
- data/lib/primer/classify.rb +0 -2
- data/lib/primer/forms/action_menu.html.erb +6 -0
- data/lib/primer/forms/action_menu.rb +25 -0
- data/lib/primer/forms/acts_as_component.rb +0 -3
- data/lib/primer/forms/base.rb +0 -1
- data/lib/primer/forms/base_component.rb +0 -2
- data/lib/primer/forms/dsl/action_menu_input.rb +36 -0
- data/lib/primer/forms/dsl/input.rb +8 -1
- data/lib/primer/forms/dsl/input_methods.rb +9 -0
- data/lib/primer/forms/dsl/text_field_input.rb +8 -0
- data/lib/primer/forms/primer_base_component_wrapper.rb +0 -2
- data/lib/primer/forms/primer_text_field.js +40 -5
- data/lib/primer/forms/primer_text_field.ts +39 -7
- data/lib/primer/forms/validation_message.html.erb +2 -1
- data/lib/primer/static/generate_info_arch.rb +1 -2
- data/lib/primer/static/generate_previews.rb +0 -2
- data/lib/primer/view_components/engine.rb +5 -1
- data/lib/primer/view_components/linters/base_linter.rb +3 -2
- data/lib/primer/view_components/linters/deprecated_components_counter.rb +1 -1
- data/lib/primer/view_components/linters/disallow_action_list.rb +1 -0
- data/lib/primer/view_components/linters/severity_schema.rb +1 -0
- data/lib/primer/view_components/version.rb +2 -3
- data/lib/primer/yard/lookbook_pages_backend.rb +2 -4
- data/lib/rubocop/cop/primer/base_cop.rb +1 -1
- data/lib/rubocop/cop/primer/deprecated_arguments.rb +0 -2
- data/lib/rubocop/cop/primer/deprecated_components.rb +1 -1
- data/lib/rubocop/cop/primer/deprecated_label_schemes.rb +1 -1
- data/lib/rubocop/cop/primer/deprecated_label_variants.rb +1 -1
- data/previews/primer/alpha/action_menu_preview.rb +73 -7
- data/previews/primer/alpha/dialog_preview/with_auto_complete.html.erb +8 -0
- data/previews/primer/alpha/dialog_preview.rb +17 -0
- data/previews/primer/alpha/octicon_symbols_preview/default.html.erb +6 -0
- data/previews/primer/alpha/octicon_symbols_preview/playground.html.erb +13 -0
- data/previews/primer/alpha/octicon_symbols_preview.rb +21 -0
- data/previews/primer/alpha/text_field_preview.rb +5 -0
- data/previews/primer/beta/avatar_preview.rb +6 -0
- data/previews/primer/beta/blankslate_preview/inside_flex_container.html.erb +6 -0
- data/previews/primer/beta/blankslate_preview.rb +3 -0
- data/previews/primer/beta/button_group_preview.rb +11 -0
- data/previews/primer/beta/clipboard_copy_button_preview.rb +29 -0
- data/previews/primer/beta/nav_list_preview.rb +10 -1
- data/previews/primer/beta/subhead_preview.rb +32 -4
- data/previews/primer/forms_preview/action_menu_form.html.erb +3 -0
- data/previews/primer/forms_preview.rb +4 -0
- data/static/arguments.json +167 -14
- data/static/audited_at.json +6 -1
- data/static/classes.json +12 -3
- data/static/constants.json +25 -1
- data/static/info_arch.json +585 -78
- data/static/previews.json +198 -0
- data/static/statuses.json +5 -0
- metadata +24 -2
@@ -15,7 +15,7 @@ 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_isKeyboardActivation, _ActionMenuElement_isKeyboardActivationViaEnter, _ActionMenuElement_isKeyboardActivationViaSpace, _ActionMenuElement_isMouseActivation, _ActionMenuElement_isActivation, _ActionMenuElement_handleInvokerActivated, _ActionMenuElement_handleDialogItemActivated, _ActionMenuElement_handleItemActivated, _ActionMenuElement_activateItem, _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_softDisableItems, _ActionMenuElement_potentiallyDisallowActivation, _ActionMenuElement_isKeyboardActivation, _ActionMenuElement_isKeyboardActivationViaEnter, _ActionMenuElement_isKeyboardActivationViaSpace, _ActionMenuElement_isMouseActivation, _ActionMenuElement_isActivation, _ActionMenuElement_handleInvokerActivated, _ActionMenuElement_handleDialogItemActivated, _ActionMenuElement_handleItemActivated, _ActionMenuElement_activateItem, _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
21
|
const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]'];
|
@@ -84,7 +84,7 @@ let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
|
84
84
|
results.push({
|
85
85
|
label: labelEl === null || labelEl === void 0 ? void 0 : labelEl.textContent,
|
86
86
|
value: selectedItem === null || selectedItem === void 0 ? void 0 : selectedItem.getAttribute('data-value'),
|
87
|
-
element: selectedItem
|
87
|
+
element: selectedItem,
|
88
88
|
});
|
89
89
|
}
|
90
90
|
return results;
|
@@ -101,7 +101,7 @@ let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
|
101
101
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_softDisableItems).call(this);
|
102
102
|
if (this.includeFragment) {
|
103
103
|
this.includeFragment.addEventListener('include-fragment-replaced', this, {
|
104
|
-
signal
|
104
|
+
signal,
|
105
105
|
});
|
106
106
|
}
|
107
107
|
}
|
@@ -141,6 +141,8 @@ let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
|
141
141
|
const item = event.target.closest(menuItemSelectors.join(','));
|
142
142
|
const targetIsItem = item !== null;
|
143
143
|
if (targetIsItem && eventIsActivation) {
|
144
|
+
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_potentiallyDisallowActivation).call(this, event))
|
145
|
+
return;
|
144
146
|
const dialogInvoker = item.closest('[data-show-dialog-id]');
|
145
147
|
if (dialogInvoker) {
|
146
148
|
const dialog = this.ownerDocument.getElementById(dialogInvoker.getAttribute('data-show-dialog-id') || '');
|
@@ -150,7 +152,7 @@ let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
|
150
152
|
}
|
151
153
|
}
|
152
154
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_activateItem).call(this, event, item);
|
153
|
-
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemActivated).call(this,
|
155
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemActivated).call(this, item);
|
154
156
|
// Pressing the space key on a button or link will cause the page to scroll unless preventDefault()
|
155
157
|
// is called. While calling preventDefault() appears to have no effect on link navigation, it skips
|
156
158
|
// form submission. The code below therefore only calls preventDefault() if the button has been
|
@@ -167,41 +169,125 @@ let ActionMenuElement = class ActionMenuElement extends HTMLElement {
|
|
167
169
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleIncludeFragmentReplaced).call(this);
|
168
170
|
}
|
169
171
|
}
|
172
|
+
get items() {
|
173
|
+
return Array.from(this.querySelectorAll(menuItemSelectors.join(',')));
|
174
|
+
}
|
175
|
+
getItemById(itemId) {
|
176
|
+
return this.querySelector(`li[data-item-id="${itemId}"`);
|
177
|
+
}
|
178
|
+
isItemDisabled(item) {
|
179
|
+
if (item) {
|
180
|
+
return item.classList.contains('ActionListItem--disabled');
|
181
|
+
}
|
182
|
+
else {
|
183
|
+
return false;
|
184
|
+
}
|
185
|
+
}
|
186
|
+
disableItem(item) {
|
187
|
+
if (item) {
|
188
|
+
item.classList.add('ActionListItem--disabled');
|
189
|
+
item.querySelector('.ActionListContent').setAttribute('aria-disabled', 'true');
|
190
|
+
}
|
191
|
+
}
|
192
|
+
enableItem(item) {
|
193
|
+
if (item) {
|
194
|
+
item.classList.remove('ActionListItem--disabled');
|
195
|
+
item.querySelector('.ActionListContent').removeAttribute('aria-disabled');
|
196
|
+
}
|
197
|
+
}
|
198
|
+
isItemHidden(item) {
|
199
|
+
if (item) {
|
200
|
+
return item.hasAttribute('hidden');
|
201
|
+
}
|
202
|
+
else {
|
203
|
+
return false;
|
204
|
+
}
|
205
|
+
}
|
206
|
+
hideItem(item) {
|
207
|
+
if (item) {
|
208
|
+
item.setAttribute('hidden', 'hidden');
|
209
|
+
}
|
210
|
+
}
|
211
|
+
showItem(item) {
|
212
|
+
if (item) {
|
213
|
+
item.removeAttribute('hidden');
|
214
|
+
}
|
215
|
+
}
|
216
|
+
isItemChecked(item) {
|
217
|
+
if (item) {
|
218
|
+
return item.querySelector('.ActionListContent').getAttribute('aria-checked') === 'true';
|
219
|
+
}
|
220
|
+
else {
|
221
|
+
return false;
|
222
|
+
}
|
223
|
+
}
|
224
|
+
checkItem(item) {
|
225
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
226
|
+
const itemContent = item.querySelector('.ActionListContent');
|
227
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true';
|
228
|
+
if (!ariaChecked) {
|
229
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemActivated).call(this, itemContent);
|
230
|
+
}
|
231
|
+
}
|
232
|
+
}
|
233
|
+
uncheckItem(item) {
|
234
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
235
|
+
const itemContent = item.querySelector('.ActionListContent');
|
236
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true';
|
237
|
+
if (ariaChecked) {
|
238
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_handleItemActivated).call(this, itemContent);
|
239
|
+
}
|
240
|
+
}
|
241
|
+
}
|
170
242
|
};
|
171
|
-
_ActionMenuElement_abortController = new WeakMap()
|
243
|
+
_ActionMenuElement_abortController = new WeakMap();
|
244
|
+
_ActionMenuElement_originalLabel = new WeakMap();
|
245
|
+
_ActionMenuElement_inputName = new WeakMap();
|
246
|
+
_ActionMenuElement_invokerBeingClicked = new WeakMap();
|
247
|
+
_ActionMenuElement_instances = new WeakSet();
|
248
|
+
_ActionMenuElement_softDisableItems = function _ActionMenuElement_softDisableItems() {
|
172
249
|
const { signal } = __classPrivateFieldGet(this, _ActionMenuElement_abortController, "f");
|
173
|
-
for (const item of
|
250
|
+
for (const item of this.querySelectorAll(validSelectors.join(','))) {
|
174
251
|
item.addEventListener('click', __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_potentiallyDisallowActivation).bind(this), { signal });
|
175
252
|
item.addEventListener('keydown', __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_potentiallyDisallowActivation).bind(this), { signal });
|
176
253
|
}
|
177
|
-
}
|
254
|
+
};
|
255
|
+
_ActionMenuElement_potentiallyDisallowActivation = function _ActionMenuElement_potentiallyDisallowActivation(event) {
|
178
256
|
if (!__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isActivation).call(this, event))
|
179
|
-
return;
|
257
|
+
return false;
|
180
258
|
const item = event.target.closest(menuItemSelectors.join(','));
|
181
259
|
if (!item)
|
182
|
-
return;
|
260
|
+
return false;
|
183
261
|
if (item.getAttribute('aria-disabled')) {
|
184
262
|
event.preventDefault();
|
185
263
|
event.stopPropagation();
|
186
264
|
event.stopImmediatePropagation();
|
265
|
+
return true;
|
187
266
|
}
|
188
|
-
|
267
|
+
return false;
|
268
|
+
};
|
269
|
+
_ActionMenuElement_isKeyboardActivation = function _ActionMenuElement_isKeyboardActivation(event) {
|
189
270
|
return __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isKeyboardActivationViaEnter).call(this, event) || __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isKeyboardActivationViaSpace).call(this, event);
|
190
|
-
}
|
271
|
+
};
|
272
|
+
_ActionMenuElement_isKeyboardActivationViaEnter = function _ActionMenuElement_isKeyboardActivationViaEnter(event) {
|
191
273
|
return (event instanceof KeyboardEvent &&
|
192
274
|
event.type === 'keydown' &&
|
193
275
|
!(event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) &&
|
194
276
|
event.key === 'Enter');
|
195
|
-
}
|
277
|
+
};
|
278
|
+
_ActionMenuElement_isKeyboardActivationViaSpace = function _ActionMenuElement_isKeyboardActivationViaSpace(event) {
|
196
279
|
return (event instanceof KeyboardEvent &&
|
197
280
|
event.type === 'keydown' &&
|
198
281
|
!(event.ctrlKey || event.altKey || event.metaKey || event.shiftKey) &&
|
199
282
|
event.key === ' ');
|
200
|
-
}
|
283
|
+
};
|
284
|
+
_ActionMenuElement_isMouseActivation = function _ActionMenuElement_isMouseActivation(event) {
|
201
285
|
return event instanceof MouseEvent && event.type === 'click';
|
202
|
-
}
|
286
|
+
};
|
287
|
+
_ActionMenuElement_isActivation = function _ActionMenuElement_isActivation(event) {
|
203
288
|
return __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isMouseActivation).call(this, event) || __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isKeyboardActivation).call(this, event);
|
204
|
-
}
|
289
|
+
};
|
290
|
+
_ActionMenuElement_handleInvokerActivated = function _ActionMenuElement_handleInvokerActivated(event) {
|
205
291
|
var _a;
|
206
292
|
event.preventDefault();
|
207
293
|
event.stopPropagation();
|
@@ -212,7 +298,8 @@ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalL
|
|
212
298
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_show).call(this);
|
213
299
|
(_a = __classPrivateFieldGet(this, _ActionMenuElement_instances, "a", _ActionMenuElement_firstItem_get)) === null || _a === void 0 ? void 0 : _a.focus();
|
214
300
|
}
|
215
|
-
}
|
301
|
+
};
|
302
|
+
_ActionMenuElement_handleDialogItemActivated = function _ActionMenuElement_handleDialogItemActivated(event, dialog) {
|
216
303
|
this.querySelector('.ActionListWrap').style.display = 'none';
|
217
304
|
const dialog_controller = new AbortController();
|
218
305
|
const { signal } = dialog_controller;
|
@@ -225,7 +312,8 @@ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalL
|
|
225
312
|
};
|
226
313
|
dialog.addEventListener('close', handleDialogClose, { signal });
|
227
314
|
dialog.addEventListener('cancel', handleDialogClose, { signal });
|
228
|
-
}
|
315
|
+
};
|
316
|
+
_ActionMenuElement_handleItemActivated = function _ActionMenuElement_handleItemActivated(item) {
|
229
317
|
// Hide popover after current event loop to prevent changes in focus from
|
230
318
|
// altering the target of the event. Not doing this specifically affects
|
231
319
|
// <a> tags. It causes the event to be sent to the currently focused element
|
@@ -262,7 +350,11 @@ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalL
|
|
262
350
|
item.setAttribute('aria-checked', `${checked}`);
|
263
351
|
}
|
264
352
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateInput).call(this);
|
265
|
-
|
353
|
+
this.dispatchEvent(new CustomEvent('itemActivated', {
|
354
|
+
detail: { item: item.parentElement, checked: this.isItemChecked(item.parentElement) },
|
355
|
+
}));
|
356
|
+
};
|
357
|
+
_ActionMenuElement_activateItem = function _ActionMenuElement_activateItem(event, item) {
|
266
358
|
const eventWillActivateByDefault = (event instanceof MouseEvent && event.type === 'click') ||
|
267
359
|
(event instanceof KeyboardEvent &&
|
268
360
|
event.type === 'keydown' &&
|
@@ -277,22 +369,28 @@ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalL
|
|
277
369
|
event.stopPropagation();
|
278
370
|
const elem = item;
|
279
371
|
elem.click();
|
280
|
-
}
|
372
|
+
};
|
373
|
+
_ActionMenuElement_handleIncludeFragmentReplaced = function _ActionMenuElement_handleIncludeFragmentReplaced() {
|
281
374
|
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "a", _ActionMenuElement_firstItem_get))
|
282
375
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "a", _ActionMenuElement_firstItem_get).focus();
|
283
376
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_softDisableItems).call(this);
|
284
|
-
}
|
377
|
+
};
|
378
|
+
_ActionMenuElement_handleFocusOut = function _ActionMenuElement_handleFocusOut() {
|
285
379
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_hide).call(this);
|
286
|
-
}
|
380
|
+
};
|
381
|
+
_ActionMenuElement_show = function _ActionMenuElement_show() {
|
287
382
|
var _a;
|
288
383
|
(_a = this.popoverElement) === null || _a === void 0 ? void 0 : _a.showPopover();
|
289
|
-
}
|
384
|
+
};
|
385
|
+
_ActionMenuElement_hide = function _ActionMenuElement_hide() {
|
290
386
|
var _a;
|
291
387
|
(_a = this.popoverElement) === null || _a === void 0 ? void 0 : _a.hidePopover();
|
292
|
-
}
|
388
|
+
};
|
389
|
+
_ActionMenuElement_isOpen = function _ActionMenuElement_isOpen() {
|
293
390
|
var _a;
|
294
391
|
return (_a = this.popoverElement) === null || _a === void 0 ? void 0 : _a.matches(':popover-open');
|
295
|
-
}
|
392
|
+
};
|
393
|
+
_ActionMenuElement_setDynamicLabel = function _ActionMenuElement_setDynamicLabel() {
|
296
394
|
if (!this.dynamicLabel)
|
297
395
|
return;
|
298
396
|
const invokerLabel = this.invokerLabel;
|
@@ -311,7 +409,8 @@ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalL
|
|
311
409
|
else {
|
312
410
|
invokerLabel.textContent = __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f");
|
313
411
|
}
|
314
|
-
}
|
412
|
+
};
|
413
|
+
_ActionMenuElement_updateInput = function _ActionMenuElement_updateInput() {
|
315
414
|
if (this.selectVariant === 'single') {
|
316
415
|
const input = this.querySelector(`[data-list-inputs=true] input`);
|
317
416
|
if (!input)
|
@@ -347,10 +446,9 @@ _ActionMenuElement_abortController = new WeakMap(), _ActionMenuElement_originalL
|
|
347
446
|
input.remove();
|
348
447
|
}
|
349
448
|
}
|
350
|
-
}
|
449
|
+
};
|
450
|
+
_ActionMenuElement_firstItem_get = function _ActionMenuElement_firstItem_get() {
|
351
451
|
return this.querySelector(menuItemSelectors.join(','));
|
352
|
-
}, _ActionMenuElement_items_get = function _ActionMenuElement_items_get() {
|
353
|
-
return Array.from(this.querySelectorAll(menuItemSelectors.join(',')));
|
354
452
|
};
|
355
453
|
__decorate([
|
356
454
|
target
|
@@ -12,6 +12,17 @@ type SelectedItem = {
|
|
12
12
|
const validSelectors = ['[role="menuitem"]', '[role="menuitemcheckbox"]', '[role="menuitemradio"]']
|
13
13
|
const menuItemSelectors = validSelectors.map(selector => `:not([hidden]) > ${selector}`)
|
14
14
|
|
15
|
+
export type ItemActivatedEvent = {
|
16
|
+
item: Element
|
17
|
+
checked: boolean
|
18
|
+
}
|
19
|
+
|
20
|
+
declare global {
|
21
|
+
interface HTMLElementEventMap {
|
22
|
+
itemActivated: CustomEvent<ItemActivatedEvent>
|
23
|
+
}
|
24
|
+
}
|
25
|
+
|
15
26
|
@controller
|
16
27
|
export class ActionMenuElement extends HTMLElement {
|
17
28
|
@target
|
@@ -82,7 +93,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
82
93
|
results.push({
|
83
94
|
label: labelEl?.textContent,
|
84
95
|
value: selectedItem?.getAttribute('data-value'),
|
85
|
-
element: selectedItem
|
96
|
+
element: selectedItem,
|
86
97
|
})
|
87
98
|
}
|
88
99
|
|
@@ -102,35 +113,39 @@ export class ActionMenuElement extends HTMLElement {
|
|
102
113
|
|
103
114
|
if (this.includeFragment) {
|
104
115
|
this.includeFragment.addEventListener('include-fragment-replaced', this, {
|
105
|
-
signal
|
116
|
+
signal,
|
106
117
|
})
|
107
118
|
}
|
108
119
|
}
|
109
120
|
|
121
|
+
disconnectedCallback() {
|
122
|
+
this.#abortController.abort()
|
123
|
+
}
|
124
|
+
|
110
125
|
#softDisableItems() {
|
111
126
|
const {signal} = this.#abortController
|
112
127
|
|
113
|
-
for (const item of this
|
128
|
+
for (const item of this.querySelectorAll(validSelectors.join(','))) {
|
114
129
|
item.addEventListener('click', this.#potentiallyDisallowActivation.bind(this), {signal})
|
115
130
|
item.addEventListener('keydown', this.#potentiallyDisallowActivation.bind(this), {signal})
|
116
131
|
}
|
117
132
|
}
|
118
133
|
|
119
|
-
|
120
|
-
|
134
|
+
// returns true if activation was prevented
|
135
|
+
#potentiallyDisallowActivation(event: Event): boolean {
|
136
|
+
if (!this.#isActivation(event)) return false
|
121
137
|
|
122
138
|
const item = (event.target as HTMLElement).closest(menuItemSelectors.join(','))
|
123
|
-
if (!item) return
|
139
|
+
if (!item) return false
|
124
140
|
|
125
141
|
if (item.getAttribute('aria-disabled')) {
|
126
142
|
event.preventDefault()
|
127
143
|
event.stopPropagation()
|
128
144
|
event.stopImmediatePropagation()
|
145
|
+
return true
|
129
146
|
}
|
130
|
-
}
|
131
147
|
|
132
|
-
|
133
|
-
this.#abortController.abort()
|
148
|
+
return false
|
134
149
|
}
|
135
150
|
|
136
151
|
#isKeyboardActivation(event: Event): boolean {
|
@@ -202,6 +217,8 @@ export class ActionMenuElement extends HTMLElement {
|
|
202
217
|
const targetIsItem = item !== null
|
203
218
|
|
204
219
|
if (targetIsItem && eventIsActivation) {
|
220
|
+
if (this.#potentiallyDisallowActivation(event)) return
|
221
|
+
|
205
222
|
const dialogInvoker = item.closest('[data-show-dialog-id]')
|
206
223
|
|
207
224
|
if (dialogInvoker) {
|
@@ -214,7 +231,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
214
231
|
}
|
215
232
|
|
216
233
|
this.#activateItem(event, item)
|
217
|
-
this.#handleItemActivated(
|
234
|
+
this.#handleItemActivated(item)
|
218
235
|
|
219
236
|
// Pressing the space key on a button or link will cause the page to scroll unless preventDefault()
|
220
237
|
// is called. While calling preventDefault() appears to have no effect on link navigation, it skips
|
@@ -263,7 +280,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
263
280
|
dialog.addEventListener('cancel', handleDialogClose, {signal})
|
264
281
|
}
|
265
282
|
|
266
|
-
#handleItemActivated(
|
283
|
+
#handleItemActivated(item: Element) {
|
267
284
|
// Hide popover after current event loop to prevent changes in focus from
|
268
285
|
// altering the target of the event. Not doing this specifically affects
|
269
286
|
// <a> tags. It causes the event to be sent to the currently focused element
|
@@ -304,6 +321,11 @@ export class ActionMenuElement extends HTMLElement {
|
|
304
321
|
}
|
305
322
|
|
306
323
|
this.#updateInput()
|
324
|
+
this.dispatchEvent(
|
325
|
+
new CustomEvent('itemActivated', {
|
326
|
+
detail: {item: item.parentElement, checked: this.isItemChecked(item.parentElement)},
|
327
|
+
}),
|
328
|
+
)
|
307
329
|
}
|
308
330
|
|
309
331
|
#activateItem(event: Event, item: Element) {
|
@@ -410,9 +432,85 @@ export class ActionMenuElement extends HTMLElement {
|
|
410
432
|
return this.querySelector(menuItemSelectors.join(','))
|
411
433
|
}
|
412
434
|
|
413
|
-
get
|
435
|
+
get items(): HTMLElement[] {
|
414
436
|
return Array.from(this.querySelectorAll(menuItemSelectors.join(',')))
|
415
437
|
}
|
438
|
+
|
439
|
+
getItemById(itemId: string): HTMLElement | null {
|
440
|
+
return this.querySelector(`li[data-item-id="${itemId}"`)
|
441
|
+
}
|
442
|
+
|
443
|
+
isItemDisabled(item: Element | null): boolean {
|
444
|
+
if (item) {
|
445
|
+
return item.classList.contains('ActionListItem--disabled')
|
446
|
+
} else {
|
447
|
+
return false
|
448
|
+
}
|
449
|
+
}
|
450
|
+
|
451
|
+
disableItem(item: Element | null) {
|
452
|
+
if (item) {
|
453
|
+
item.classList.add('ActionListItem--disabled')
|
454
|
+
item.querySelector('.ActionListContent')!.setAttribute('aria-disabled', 'true')
|
455
|
+
}
|
456
|
+
}
|
457
|
+
|
458
|
+
enableItem(item: Element | null) {
|
459
|
+
if (item) {
|
460
|
+
item.classList.remove('ActionListItem--disabled')
|
461
|
+
item.querySelector('.ActionListContent')!.removeAttribute('aria-disabled')
|
462
|
+
}
|
463
|
+
}
|
464
|
+
|
465
|
+
isItemHidden(item: Element | null): boolean {
|
466
|
+
if (item) {
|
467
|
+
return item.hasAttribute('hidden')
|
468
|
+
} else {
|
469
|
+
return false
|
470
|
+
}
|
471
|
+
}
|
472
|
+
|
473
|
+
hideItem(item: Element | null) {
|
474
|
+
if (item) {
|
475
|
+
item.setAttribute('hidden', 'hidden')
|
476
|
+
}
|
477
|
+
}
|
478
|
+
|
479
|
+
showItem(item: Element | null) {
|
480
|
+
if (item) {
|
481
|
+
item.removeAttribute('hidden')
|
482
|
+
}
|
483
|
+
}
|
484
|
+
|
485
|
+
isItemChecked(item: Element | null) {
|
486
|
+
if (item) {
|
487
|
+
return item.querySelector('.ActionListContent')!.getAttribute('aria-checked') === 'true'
|
488
|
+
} else {
|
489
|
+
return false
|
490
|
+
}
|
491
|
+
}
|
492
|
+
|
493
|
+
checkItem(item: Element | null) {
|
494
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
495
|
+
const itemContent = item.querySelector('.ActionListContent')!
|
496
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true'
|
497
|
+
|
498
|
+
if (!ariaChecked) {
|
499
|
+
this.#handleItemActivated(itemContent)
|
500
|
+
}
|
501
|
+
}
|
502
|
+
}
|
503
|
+
|
504
|
+
uncheckItem(item: Element | null) {
|
505
|
+
if (item && (this.selectVariant === 'single' || this.selectVariant === 'multiple')) {
|
506
|
+
const itemContent = item.querySelector('.ActionListContent')!
|
507
|
+
const ariaChecked = itemContent.getAttribute('aria-checked') === 'true'
|
508
|
+
|
509
|
+
if (ariaChecked) {
|
510
|
+
this.#handleItemActivated(itemContent)
|
511
|
+
}
|
512
|
+
}
|
513
|
+
}
|
416
514
|
}
|
417
515
|
|
418
516
|
if (!window.customElements.get('action-menu')) {
|
@@ -0,0 +1,23 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Primer
|
5
|
+
module Alpha
|
6
|
+
class ActionMenu
|
7
|
+
# This component is part of <%= link_to_component(Primer::Alpha::ActionMenu) %> and should not be
|
8
|
+
# used as a standalone component.
|
9
|
+
class Group < Primer::Alpha::ActionList
|
10
|
+
# Heading text rendered above the list of items.
|
11
|
+
#
|
12
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionMenu::Heading) %>.
|
13
|
+
def with_heading(**system_arguments, &block)
|
14
|
+
super(component_klass: Primer::Alpha::ActionMenu::Heading, **system_arguments, &block)
|
15
|
+
end
|
16
|
+
|
17
|
+
def with_divider
|
18
|
+
raise "ActionMenu groups cannot have dividers"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
class ActionMenu
|
6
|
+
# Heading used to describe groups within an action menu.
|
7
|
+
class Heading < Primer::Alpha::ActionList::Heading
|
8
|
+
def initialize(**)
|
9
|
+
super
|
10
|
+
|
11
|
+
# Headings don't make sense in a menu context, so use div instead
|
12
|
+
@tag = :div
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render(@list) %>
|