openproject-primer_view_components 0.86.2 → 0.88.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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +30 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/components/primer/alpha/action_menu/action_menu_element.js +14 -5
- data/app/components/primer/alpha/action_menu/action_menu_element.ts +14 -4
- data/app/components/primer/alpha/select_panel_element.js +11 -1
- data/app/components/primer/alpha/select_panel_element.ts +11 -2
- data/app/components/primer/alpha/tree_view/tree_view.js +27 -11
- data/app/components/primer/alpha/tree_view/tree_view.ts +24 -9
- data/app/components/primer/open_project/avatar_fallback.js +1 -1
- data/app/components/primer/open_project/avatar_fallback.ts +1 -1
- data/app/components/primer/open_project/border_box/collapsible_header.js +1 -1
- data/app/components/primer/open_project/border_box/collapsible_header.ts +1 -1
- data/app/components/primer/open_project/collapsible_section.js +1 -1
- data/app/components/primer/open_project/collapsible_section.ts +1 -1
- data/app/components/primer/open_project/danger_dialog_form_helper.js +1 -1
- data/app/components/primer/open_project/danger_dialog_form_helper.ts +1 -1
- data/app/components/primer/open_project/fieldset.rb +2 -2
- data/app/components/primer/open_project/filterable_tree_view.js +2 -1
- data/app/components/primer/open_project/filterable_tree_view.rb +6 -5
- data/app/components/primer/open_project/filterable_tree_view.ts +3 -2
- data/app/components/primer/open_project/flex_layout.rb +2 -2
- data/app/components/primer/open_project/inline_message.rb +1 -1
- data/app/components/primer/open_project/input_group.html.erb +9 -0
- data/app/components/primer/open_project/input_group.rb +13 -0
- data/app/components/primer/open_project/page_header.rb +1 -1
- data/app/components/primer/open_project/page_header_element.js +1 -1
- data/app/components/primer/open_project/page_header_element.ts +1 -1
- data/app/components/primer/open_project/pagination.rb +1 -3
- data/app/components/primer/open_project/sub_header/{quick_filter.rb → quick_action_component.rb} +7 -1
- data/app/components/primer/open_project/sub_header.html.erb +2 -0
- data/app/components/primer/open_project/sub_header.rb +38 -24
- data/app/components/primer/open_project/sub_header_element.js +4 -3
- data/app/components/primer/open_project/sub_header_element.ts +4 -3
- data/app/components/primer/open_project/zen_mode_button.js +1 -1
- data/app/components/primer/open_project/zen_mode_button.ts +1 -1
- data/lib/primer/view_components/version.rb +2 -2
- data/previews/primer/alpha/select_panel_preview/with_dynamic_label.html.erb +1 -1
- data/previews/primer/alpha/select_panel_preview/with_dynamic_label_and_aria_prefix.html.erb +1 -1
- data/previews/primer/alpha/select_panel_preview.rb +14 -4
- data/previews/primer/alpha/tree_view_preview/doubled_path.html.erb +12 -0
- data/previews/primer/alpha/tree_view_preview/form_input.html.erb +7 -7
- data/previews/primer/alpha/tree_view_preview.rb +6 -0
- data/previews/primer/open_project/filterable_tree_view_preview/custom_no_results_text.html.erb +1 -1
- data/previews/primer/open_project/input_group_preview.rb +9 -0
- data/previews/primer/open_project/sub_header_preview/quick_filters.html.erb +8 -0
- data/static/arguments.json +8 -8
- data/static/audited_at.json +1 -1
- data/static/constants.json +3 -3
- data/static/info_arch.json +33 -10
- data/static/previews.json +23 -10
- data/static/statuses.json +1 -1
- metadata +3 -2
|
@@ -469,6 +469,7 @@ _ActionMenuElement_handleItemActivated = function _ActionMenuElement_handleItemA
|
|
|
469
469
|
else {
|
|
470
470
|
// multi-select mode allows unchecking a checked item
|
|
471
471
|
item.setAttribute('aria-checked', `${checked}`);
|
|
472
|
+
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_setDynamicLabel).call(this);
|
|
472
473
|
}
|
|
473
474
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_updateInput).call(this);
|
|
474
475
|
this.dispatchEvent(new CustomEvent('itemActivated', {
|
|
@@ -498,21 +499,29 @@ _ActionMenuElement_isOpen = function _ActionMenuElement_isOpen() {
|
|
|
498
499
|
return this.popoverElement?.matches(':popover-open');
|
|
499
500
|
};
|
|
500
501
|
_ActionMenuElement_setDynamicLabel = function _ActionMenuElement_setDynamicLabel() {
|
|
501
|
-
if (this.selectVariant !== 'single')
|
|
502
|
-
return;
|
|
503
502
|
if (!this.dynamicLabel)
|
|
504
503
|
return;
|
|
505
504
|
const invokerLabel = this.invokerLabel;
|
|
506
505
|
if (!invokerLabel)
|
|
507
506
|
return;
|
|
508
507
|
__classPrivateFieldSet(this, _ActionMenuElement_originalLabel, __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f") || (invokerLabel.textContent || ''), "f");
|
|
509
|
-
|
|
508
|
+
let itemLabel;
|
|
509
|
+
if (this.selectVariant === 'single') {
|
|
510
|
+
itemLabel = this.querySelector('[aria-checked=true] .ActionListItem-label')?.textContent?.trim();
|
|
511
|
+
}
|
|
512
|
+
else if (this.selectVariant === 'multiple') {
|
|
513
|
+
itemLabel = Array.from(this.querySelectorAll(`[aria-checked=true] .ActionListItem-label`))
|
|
514
|
+
.map(label => (label.textContent || '').trim())
|
|
515
|
+
.filter(Boolean)
|
|
516
|
+
.join(', ');
|
|
517
|
+
}
|
|
518
|
+
itemLabel || (itemLabel = __classPrivateFieldGet(this, _ActionMenuElement_originalLabel, "f"));
|
|
510
519
|
if (itemLabel && this.dynamicLabel) {
|
|
511
520
|
const prefixSpan = document.createElement('span');
|
|
512
521
|
prefixSpan.classList.add('color-fg-muted');
|
|
513
522
|
const contentSpan = document.createElement('span');
|
|
514
|
-
prefixSpan.textContent = this.dynamicLabelPrefix;
|
|
515
|
-
contentSpan.textContent = itemLabel
|
|
523
|
+
prefixSpan.textContent = this.dynamicLabelPrefix ? `${this.dynamicLabelPrefix} ` : '';
|
|
524
|
+
contentSpan.textContent = itemLabel;
|
|
516
525
|
invokerLabel.replaceChildren(prefixSpan, contentSpan);
|
|
517
526
|
}
|
|
518
527
|
else {
|
|
@@ -455,6 +455,8 @@ export class ActionMenuElement extends HTMLElement {
|
|
|
455
455
|
} else {
|
|
456
456
|
// multi-select mode allows unchecking a checked item
|
|
457
457
|
item.setAttribute('aria-checked', `${checked}`)
|
|
458
|
+
|
|
459
|
+
this.#setDynamicLabel()
|
|
458
460
|
}
|
|
459
461
|
|
|
460
462
|
this.#updateInput()
|
|
@@ -497,18 +499,26 @@ export class ActionMenuElement extends HTMLElement {
|
|
|
497
499
|
}
|
|
498
500
|
|
|
499
501
|
#setDynamicLabel() {
|
|
500
|
-
if (this.selectVariant !== 'single') return
|
|
501
502
|
if (!this.dynamicLabel) return
|
|
502
503
|
const invokerLabel = this.invokerLabel
|
|
503
504
|
if (!invokerLabel) return
|
|
504
505
|
this.#originalLabel ||= invokerLabel.textContent || ''
|
|
505
|
-
|
|
506
|
+
let itemLabel: string | undefined
|
|
507
|
+
if (this.selectVariant === 'single') {
|
|
508
|
+
itemLabel = this.querySelector('[aria-checked=true] .ActionListItem-label')?.textContent?.trim()
|
|
509
|
+
} else if (this.selectVariant === 'multiple') {
|
|
510
|
+
itemLabel = Array.from(this.querySelectorAll(`[aria-checked=true] .ActionListItem-label`))
|
|
511
|
+
.map(label => (label.textContent || '').trim())
|
|
512
|
+
.filter(Boolean)
|
|
513
|
+
.join(', ')
|
|
514
|
+
}
|
|
515
|
+
itemLabel ||= this.#originalLabel
|
|
506
516
|
if (itemLabel && this.dynamicLabel) {
|
|
507
517
|
const prefixSpan = document.createElement('span')
|
|
508
518
|
prefixSpan.classList.add('color-fg-muted')
|
|
509
519
|
const contentSpan = document.createElement('span')
|
|
510
|
-
prefixSpan.textContent = this.dynamicLabelPrefix
|
|
511
|
-
contentSpan.textContent = itemLabel
|
|
520
|
+
prefixSpan.textContent = this.dynamicLabelPrefix ? `${this.dynamicLabelPrefix} ` : ''
|
|
521
|
+
contentSpan.textContent = itemLabel
|
|
512
522
|
invokerLabel.replaceChildren(prefixSpan, contentSpan)
|
|
513
523
|
} else {
|
|
514
524
|
invokerLabel.textContent = this.#originalLabel
|
|
@@ -866,6 +866,7 @@ _SelectPanelElement_handleItemActivated = function _SelectPanelElement_handleIte
|
|
|
866
866
|
else {
|
|
867
867
|
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_removeSelectedItem).call(this, item);
|
|
868
868
|
}
|
|
869
|
+
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_setDynamicLabel).call(this);
|
|
869
870
|
}
|
|
870
871
|
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_updateInput).call(this);
|
|
871
872
|
__classPrivateFieldGet(this, _SelectPanelElement_instances, "m", _SelectPanelElement_updateTabIndices).call(this);
|
|
@@ -885,7 +886,16 @@ _SelectPanelElement_setDynamicLabel = function _SelectPanelElement_setDynamicLab
|
|
|
885
886
|
if (!invokerLabel)
|
|
886
887
|
return;
|
|
887
888
|
__classPrivateFieldSet(this, _SelectPanelElement_originalLabel, __classPrivateFieldGet(this, _SelectPanelElement_originalLabel, "f") || (invokerLabel.textContent || ''), "f");
|
|
888
|
-
|
|
889
|
+
let itemLabel;
|
|
890
|
+
if (this.selectVariant === 'single') {
|
|
891
|
+
itemLabel = this.querySelector(`[${this.ariaSelectionType}=true] .ActionListItem-label`)?.textContent;
|
|
892
|
+
}
|
|
893
|
+
else if (this.selectVariant === 'multiple') {
|
|
894
|
+
itemLabel = Array.from(this.querySelectorAll(`[${this.ariaSelectionType}=true] .ActionListItem-label`))
|
|
895
|
+
.map(label => label.textContent?.trim() ?? '')
|
|
896
|
+
.join(', ');
|
|
897
|
+
}
|
|
898
|
+
itemLabel || (itemLabel = __classPrivateFieldGet(this, _SelectPanelElement_originalLabel, "f"));
|
|
889
899
|
if (itemLabel) {
|
|
890
900
|
const prefixSpan = document.createElement('span');
|
|
891
901
|
prefixSpan.classList.add('color-fg-muted');
|
|
@@ -916,6 +916,8 @@ export class SelectPanelElement extends HTMLElement {
|
|
|
916
916
|
} else {
|
|
917
917
|
this.#removeSelectedItem(item)
|
|
918
918
|
}
|
|
919
|
+
|
|
920
|
+
this.#setDynamicLabel()
|
|
919
921
|
}
|
|
920
922
|
|
|
921
923
|
this.#updateInput()
|
|
@@ -952,8 +954,15 @@ export class SelectPanelElement extends HTMLElement {
|
|
|
952
954
|
const invokerLabel = this.invokerLabel
|
|
953
955
|
if (!invokerLabel) return
|
|
954
956
|
this.#originalLabel ||= invokerLabel.textContent || ''
|
|
955
|
-
|
|
956
|
-
|
|
957
|
+
let itemLabel: string | undefined
|
|
958
|
+
if (this.selectVariant === 'single') {
|
|
959
|
+
itemLabel = this.querySelector(`[${this.ariaSelectionType}=true] .ActionListItem-label`)?.textContent
|
|
960
|
+
} else if (this.selectVariant === 'multiple') {
|
|
961
|
+
itemLabel = Array.from(this.querySelectorAll(`[${this.ariaSelectionType}=true] .ActionListItem-label`))
|
|
962
|
+
.map(label => label.textContent?.trim() ?? '')
|
|
963
|
+
.join(', ')
|
|
964
|
+
}
|
|
965
|
+
itemLabel ||= this.#originalLabel
|
|
957
966
|
if (itemLabel) {
|
|
958
967
|
const prefixSpan = document.createElement('span')
|
|
959
968
|
prefixSpan.classList.add('color-fg-muted')
|
|
@@ -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 _TreeViewElement_instances, _TreeViewElement_abortController, _TreeViewElement_autoExpandFrom, _TreeViewElement_eventIsActivation, _TreeViewElement_nodeForEvent, _TreeViewElement_handleNodeEvent, _TreeViewElement_eventIsCheckboxToggle, _TreeViewElement_handleCheckboxToggle, _TreeViewElement_eventIsSingleSelection, _TreeViewElement_handleNodeActivated, _TreeViewElement_handleNodeFocused, _TreeViewElement_handleNodeKeyboardEvent;
|
|
18
|
+
var _TreeViewElement_instances, _TreeViewElement_abortController, _TreeViewElement_autoExpandFrom, _TreeViewElement_eventIsActivation, _TreeViewElement_nodeForEvent, _TreeViewElement_handleNodeEvent, _TreeViewElement_eventIsCheckboxToggle, _TreeViewElement_handleCheckboxToggle, _TreeViewElement_eventIsSingleSelection, _TreeViewElement_handleNodeActivated, _TreeViewElement_handleNodeFocused, _TreeViewElement_handleNodeKeyboardEvent, _TreeViewElement_checkNodeOnly;
|
|
19
19
|
import { controller, target } from '@github/catalyst';
|
|
20
20
|
import { useRovingTabIndex } from './tree_view_roving_tab_index';
|
|
21
21
|
let TreeViewElement = class TreeViewElement extends HTMLElement {
|
|
@@ -97,8 +97,8 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
|
|
|
97
97
|
// behavior for these element types is user- or browser-defined
|
|
98
98
|
if (!(node instanceof HTMLDivElement))
|
|
99
99
|
return;
|
|
100
|
-
const
|
|
101
|
-
const nodeInfo = this.infoFromNode(node,
|
|
100
|
+
const newCheckedValue = this.getNodeCheckedValue(node) === 'true' ? 'false' : 'true';
|
|
101
|
+
const nodeInfo = this.infoFromNode(node, newCheckedValue);
|
|
102
102
|
const checkSuccess = this.dispatchEvent(new CustomEvent('treeViewBeforeNodeChecked', {
|
|
103
103
|
bubbles: true,
|
|
104
104
|
cancelable: true,
|
|
@@ -106,11 +106,11 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
|
|
|
106
106
|
}));
|
|
107
107
|
if (!checkSuccess)
|
|
108
108
|
return;
|
|
109
|
-
if (
|
|
109
|
+
if (newCheckedValue === 'false') {
|
|
110
110
|
this.setNodeCheckedValue(node, 'false');
|
|
111
111
|
}
|
|
112
112
|
else {
|
|
113
|
-
this.
|
|
113
|
+
__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_checkNodeOnly).call(this, node);
|
|
114
114
|
}
|
|
115
115
|
this.dispatchEvent(new CustomEvent('treeViewNodeChecked', {
|
|
116
116
|
bubbles: true,
|
|
@@ -142,7 +142,7 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
|
|
|
142
142
|
return this.querySelector('[aria-current=true]');
|
|
143
143
|
}
|
|
144
144
|
get activeNodes() {
|
|
145
|
-
return
|
|
145
|
+
return this.querySelectorAll('[aria-checked="true"]');
|
|
146
146
|
}
|
|
147
147
|
expandAtPath(path) {
|
|
148
148
|
const node = this.subTreeAtPath(path);
|
|
@@ -175,10 +175,10 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
|
|
|
175
175
|
this.setNodeCheckedValue(node, 'false');
|
|
176
176
|
}
|
|
177
177
|
checkOnlyAtPath(path) {
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
this.
|
|
178
|
+
const node = this.nodeAtPath(path);
|
|
179
|
+
if (!node)
|
|
180
|
+
return;
|
|
181
|
+
__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_checkNodeOnly).call(this, node);
|
|
182
182
|
}
|
|
183
183
|
toggleCheckedAtPath(path) {
|
|
184
184
|
const node = this.nodeAtPath(path);
|
|
@@ -286,6 +286,9 @@ let TreeViewElement = class TreeViewElement extends HTMLElement {
|
|
|
286
286
|
const payload = {
|
|
287
287
|
path: this.getNodePath(node),
|
|
288
288
|
};
|
|
289
|
+
const nodeId = node.getAttribute('data-node-id');
|
|
290
|
+
if (nodeId)
|
|
291
|
+
payload.nodeId = nodeId;
|
|
289
292
|
const inputValue = this.getFormInputValueForNode(node);
|
|
290
293
|
if (inputValue)
|
|
291
294
|
payload.value = inputValue;
|
|
@@ -424,7 +427,12 @@ _TreeViewElement_handleNodeKeyboardEvent = function _TreeViewElement_handleNodeK
|
|
|
424
427
|
}
|
|
425
428
|
else if (this.selectVariant(node) === 'single') {
|
|
426
429
|
event.preventDefault();
|
|
427
|
-
|
|
430
|
+
if (this.getNodeCheckedValue(node) === 'true') {
|
|
431
|
+
this.setNodeCheckedValue(node, 'false');
|
|
432
|
+
}
|
|
433
|
+
else {
|
|
434
|
+
__classPrivateFieldGet(this, _TreeViewElement_instances, "m", _TreeViewElement_checkNodeOnly).call(this, node);
|
|
435
|
+
}
|
|
428
436
|
}
|
|
429
437
|
else if (node instanceof HTMLAnchorElement) {
|
|
430
438
|
// simulate click on space
|
|
@@ -433,6 +441,14 @@ _TreeViewElement_handleNodeKeyboardEvent = function _TreeViewElement_handleNodeK
|
|
|
433
441
|
break;
|
|
434
442
|
}
|
|
435
443
|
};
|
|
444
|
+
_TreeViewElement_checkNodeOnly = function _TreeViewElement_checkNodeOnly(node) {
|
|
445
|
+
for (const el of this.activeNodes) {
|
|
446
|
+
if (el === node)
|
|
447
|
+
continue;
|
|
448
|
+
this.setNodeCheckedValue(el, 'false');
|
|
449
|
+
}
|
|
450
|
+
this.setNodeCheckedValue(node, 'true');
|
|
451
|
+
};
|
|
436
452
|
__decorate([
|
|
437
453
|
target
|
|
438
454
|
], TreeViewElement.prototype, "formInputContainer", void 0);
|
|
@@ -179,8 +179,8 @@ export class TreeViewElement extends HTMLElement {
|
|
|
179
179
|
// behavior for these element types is user- or browser-defined
|
|
180
180
|
if (!(node instanceof HTMLDivElement)) return
|
|
181
181
|
|
|
182
|
-
const
|
|
183
|
-
const nodeInfo = this.infoFromNode(node,
|
|
182
|
+
const newCheckedValue = this.getNodeCheckedValue(node) === 'true' ? 'false' : 'true'
|
|
183
|
+
const nodeInfo = this.infoFromNode(node, newCheckedValue)
|
|
184
184
|
|
|
185
185
|
const checkSuccess = this.dispatchEvent(
|
|
186
186
|
new CustomEvent('treeViewBeforeNodeChecked', {
|
|
@@ -192,10 +192,10 @@ export class TreeViewElement extends HTMLElement {
|
|
|
192
192
|
|
|
193
193
|
if (!checkSuccess) return
|
|
194
194
|
|
|
195
|
-
if (
|
|
195
|
+
if (newCheckedValue === 'false') {
|
|
196
196
|
this.setNodeCheckedValue(node, 'false')
|
|
197
197
|
} else {
|
|
198
|
-
this
|
|
198
|
+
this.#checkNodeOnly(node)
|
|
199
199
|
}
|
|
200
200
|
|
|
201
201
|
this.dispatchEvent(
|
|
@@ -271,7 +271,11 @@ export class TreeViewElement extends HTMLElement {
|
|
|
271
271
|
} else if (this.selectVariant(node) === 'single') {
|
|
272
272
|
event.preventDefault()
|
|
273
273
|
|
|
274
|
-
|
|
274
|
+
if (this.getNodeCheckedValue(node) === 'true') {
|
|
275
|
+
this.setNodeCheckedValue(node, 'false')
|
|
276
|
+
} else {
|
|
277
|
+
this.#checkNodeOnly(node)
|
|
278
|
+
}
|
|
275
279
|
} else if (node instanceof HTMLAnchorElement) {
|
|
276
280
|
// simulate click on space
|
|
277
281
|
node.click()
|
|
@@ -313,7 +317,7 @@ export class TreeViewElement extends HTMLElement {
|
|
|
313
317
|
}
|
|
314
318
|
|
|
315
319
|
get activeNodes() {
|
|
316
|
-
return
|
|
320
|
+
return this.querySelectorAll('[aria-checked="true"]')
|
|
317
321
|
}
|
|
318
322
|
|
|
319
323
|
expandAtPath(path: string[]) {
|
|
@@ -352,11 +356,19 @@ export class TreeViewElement extends HTMLElement {
|
|
|
352
356
|
}
|
|
353
357
|
|
|
354
358
|
checkOnlyAtPath(path: string[]) {
|
|
359
|
+
const node = this.nodeAtPath(path)
|
|
360
|
+
if (!node) return
|
|
361
|
+
|
|
362
|
+
this.#checkNodeOnly(node)
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
#checkNodeOnly(node: Element) {
|
|
355
366
|
for (const el of this.activeNodes) {
|
|
356
|
-
|
|
367
|
+
if (el === node) continue
|
|
368
|
+
this.setNodeCheckedValue(el, 'false')
|
|
357
369
|
}
|
|
358
370
|
|
|
359
|
-
this.
|
|
371
|
+
this.setNodeCheckedValue(node, 'true')
|
|
360
372
|
}
|
|
361
373
|
|
|
362
374
|
toggleCheckedAtPath(path: string[]) {
|
|
@@ -479,10 +491,13 @@ export class TreeViewElement extends HTMLElement {
|
|
|
479
491
|
newInput.removeAttribute('data-target')
|
|
480
492
|
newInput.removeAttribute('form')
|
|
481
493
|
|
|
482
|
-
const payload: {path: string[]; value?: string} = {
|
|
494
|
+
const payload: {path: string[]; nodeId?: string; value?: string} = {
|
|
483
495
|
path: this.getNodePath(node),
|
|
484
496
|
}
|
|
485
497
|
|
|
498
|
+
const nodeId = node.getAttribute('data-node-id')
|
|
499
|
+
if (nodeId) payload.nodeId = nodeId
|
|
500
|
+
|
|
486
501
|
const inputValue = this.getFormInputValueForNode(node)
|
|
487
502
|
if (inputValue) payload.value = inputValue
|
|
488
503
|
|
|
@@ -13,7 +13,7 @@ import {controller} from '@github/catalyst'
|
|
|
13
13
|
* due to a Catalyst bug where @attr accessors aren't properly initialized
|
|
14
14
|
* when elements have pre-existing attribute values.
|
|
15
15
|
*/
|
|
16
|
-
@controller
|
|
16
|
+
@controller('avatar-fallback')
|
|
17
17
|
export class AvatarFallbackElement extends HTMLElement {
|
|
18
18
|
private img: HTMLImageElement | null = null
|
|
19
19
|
private testImage: HTMLImageElement | null = null
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {controller} from '@github/catalyst'
|
|
2
2
|
import {CollapsibleElement} from './collapsible'
|
|
3
3
|
|
|
4
|
-
@controller
|
|
4
|
+
@controller('collapsible-section')
|
|
5
5
|
class CollapsibleSectionElement extends CollapsibleElement {
|
|
6
6
|
get baseClass(): string {
|
|
7
7
|
return 'CollapsibleSection'
|
|
@@ -62,7 +62,7 @@ __decorate([
|
|
|
62
62
|
attr
|
|
63
63
|
], DangerDialogFormHelperElement.prototype, "confirmationLiveMessageUnchecked", void 0);
|
|
64
64
|
DangerDialogFormHelperElement = __decorate([
|
|
65
|
-
controller
|
|
65
|
+
controller('danger-dialog-form-helper')
|
|
66
66
|
], DangerDialogFormHelperElement);
|
|
67
67
|
if (!window.customElements.get('danger-dialog-form-helper')) {
|
|
68
68
|
window.DangerDialogFormHelperElement = DangerDialogFormHelperElement;
|
|
@@ -3,7 +3,7 @@ import type {LiveRegionElement} from '@primer/live-region-element'
|
|
|
3
3
|
|
|
4
4
|
const SUBMIT_BUTTON_SELECTOR = 'input[type=submit],button[type=submit],button[data-submit-dialog-id]'
|
|
5
5
|
|
|
6
|
-
@controller
|
|
6
|
+
@controller('danger-dialog-form-helper')
|
|
7
7
|
class DangerDialogFormHelperElement extends HTMLElement {
|
|
8
8
|
@target checkbox: HTMLInputElement | undefined
|
|
9
9
|
@target liveRegion: LiveRegionElement
|
|
@@ -18,7 +18,7 @@ module Primer
|
|
|
18
18
|
# @param legend_text [String] A legend should be short and concise. The String will also be read by assistive technology.
|
|
19
19
|
# @param visually_hide_legend [Boolean] Controls if the legend is visible. If `true`, screen reader only text will be added.
|
|
20
20
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
|
21
|
-
def initialize(legend_text: nil, visually_hide_legend: false, **system_arguments)
|
|
21
|
+
def initialize(legend_text: nil, visually_hide_legend: false, **system_arguments)
|
|
22
22
|
@legend_text = legend_text
|
|
23
23
|
@visually_hide_legend = visually_hide_legend
|
|
24
24
|
@system_arguments = deny_tag_argument(**system_arguments)
|
|
@@ -40,7 +40,7 @@ module Primer
|
|
|
40
40
|
|
|
41
41
|
attr_reader :text
|
|
42
42
|
|
|
43
|
-
def initialize(text: nil, visually_hide_legend: false, **system_arguments)
|
|
43
|
+
def initialize(text: nil, visually_hide_legend: false, **system_arguments)
|
|
44
44
|
@text = text
|
|
45
45
|
|
|
46
46
|
@system_arguments = deny_tag_argument(**system_arguments)
|
|
@@ -224,6 +224,7 @@ _FilterableTreeViewElement_updateCheckedNodeIds = function _FilterableTreeViewEl
|
|
|
224
224
|
}
|
|
225
225
|
__classPrivateFieldGet(this, _FilterableTreeViewElement_checkedNodeIds, "f").set(nodeId, nodeInfo.checkedValue);
|
|
226
226
|
const payload = { path: nodeInfo.path };
|
|
227
|
+
payload.nodeId = nodeId;
|
|
227
228
|
const dataValue = node.getAttribute('data-value');
|
|
228
229
|
if (dataValue)
|
|
229
230
|
payload.value = dataValue;
|
|
@@ -689,7 +690,7 @@ __decorate([
|
|
|
689
690
|
target
|
|
690
691
|
], FilterableTreeViewElement.prototype, "includeSubItemsCheckBox", void 0);
|
|
691
692
|
FilterableTreeViewElement = __decorate([
|
|
692
|
-
controller
|
|
693
|
+
controller('filterable-tree-view')
|
|
693
694
|
], FilterableTreeViewElement);
|
|
694
695
|
export { FilterableTreeViewElement };
|
|
695
696
|
if (!window.customElements.get('filterable-tree-view')) {
|
|
@@ -199,10 +199,10 @@ module Primer
|
|
|
199
199
|
src: nil,
|
|
200
200
|
tree_view_arguments: {},
|
|
201
201
|
form_arguments: {},
|
|
202
|
-
filter_input_arguments:
|
|
203
|
-
filter_mode_control_arguments:
|
|
204
|
-
include_sub_items_check_box_arguments:
|
|
205
|
-
no_results_node_arguments:
|
|
202
|
+
filter_input_arguments: {},
|
|
203
|
+
filter_mode_control_arguments: {},
|
|
204
|
+
include_sub_items_check_box_arguments: {},
|
|
205
|
+
no_results_node_arguments: {},
|
|
206
206
|
**system_arguments
|
|
207
207
|
)
|
|
208
208
|
@tree_view_arguments = tree_view_arguments.dup
|
|
@@ -218,6 +218,7 @@ module Primer
|
|
|
218
218
|
**tree_view_arguments
|
|
219
219
|
)
|
|
220
220
|
|
|
221
|
+
filter_input_arguments = filter_input_arguments.reverse_merge(DEFAULT_FILTER_INPUT_ARGUMENTS)
|
|
221
222
|
filter_input_arguments[:data] = merge_data(
|
|
222
223
|
filter_input_arguments, {
|
|
223
224
|
data: { target: "filterable-tree-view.filterInput" }
|
|
@@ -250,7 +251,7 @@ module Primer
|
|
|
250
251
|
@system_arguments[:tag] = :"filterable-tree-view"
|
|
251
252
|
@system_arguments[:src] = src if src
|
|
252
253
|
|
|
253
|
-
@no_results_node_arguments = no_results_node_arguments
|
|
254
|
+
@no_results_node_arguments = no_results_node_arguments.reverse_merge(DEFAULT_NO_RESULTS_NODE_ARGUMENTS)
|
|
254
255
|
end
|
|
255
256
|
|
|
256
257
|
def with_default_filter_modes
|
|
@@ -18,7 +18,7 @@ type NodeState = {
|
|
|
18
18
|
|
|
19
19
|
const ASYNC_DEBOUNCE_MS = 300
|
|
20
20
|
|
|
21
|
-
@controller
|
|
21
|
+
@controller('filterable-tree-view')
|
|
22
22
|
export class FilterableTreeViewElement extends HTMLElement {
|
|
23
23
|
@target filterInput: HTMLInputElement
|
|
24
24
|
@target filterModeControlList: HTMLElement
|
|
@@ -119,7 +119,8 @@ export class FilterableTreeViewElement extends HTMLElement {
|
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
this.#checkedNodeIds.set(nodeId, nodeInfo.checkedValue)
|
|
122
|
-
const payload: {path: string[]; value?: string} = {path: nodeInfo.path}
|
|
122
|
+
const payload: {path: string[]; nodeId?: string; value?: string} = {path: nodeInfo.path}
|
|
123
|
+
payload.nodeId = nodeId
|
|
123
124
|
const dataValue = node.getAttribute('data-value')
|
|
124
125
|
if (dataValue) payload.value = dataValue
|
|
125
126
|
this.#checkedNodeFormPayloads.set(nodeId, payload)
|
|
@@ -29,10 +29,10 @@ module Primer
|
|
|
29
29
|
# no slot provided
|
|
30
30
|
return false if rows.empty? && columns.empty? && boxes.empty?
|
|
31
31
|
|
|
32
|
-
if [rows, columns, boxes].
|
|
32
|
+
if [rows, columns, boxes].one? { |arr| !arr.empty? }
|
|
33
33
|
# only rows or columns or boxes are used
|
|
34
34
|
true
|
|
35
|
-
elsif [rows, columns, boxes].
|
|
35
|
+
elsif [rows, columns, boxes].many? { |arr| !arr.empty? }
|
|
36
36
|
# rows, columns and boxes are used together, which is not allowed
|
|
37
37
|
raise ArgumentError, "You can't mix row, column and box slots"
|
|
38
38
|
end
|
|
@@ -33,7 +33,7 @@ module Primer
|
|
|
33
33
|
# @param scheme [Symbol] <%= one_of(Primer::OpenProject::InlineMessage::SCHEME_OPTIONS) %>
|
|
34
34
|
# @param size [Symbol] <%= one_of(Primer::OpenProject::InlineMessage::SIZE_OPTIONS) %>
|
|
35
35
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
|
36
|
-
def initialize(scheme:, size: DEFAULT_SIZE, **system_arguments)
|
|
36
|
+
def initialize(scheme:, size: DEFAULT_SIZE, **system_arguments)
|
|
37
37
|
resolved_scheme = fetch_or_fallback(SCHEME_OPTIONS, scheme)
|
|
38
38
|
resolved_size = fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)
|
|
39
39
|
|
|
@@ -4,6 +4,15 @@
|
|
|
4
4
|
<%= trailing_action %>
|
|
5
5
|
<% end %>
|
|
6
6
|
|
|
7
|
+
<% if @text_input_validation_message %>
|
|
8
|
+
<div class="FormControl-inlineValidation mt-1" id="<%= @text_input_validation_message_id %>">
|
|
9
|
+
<span class="FormControl-inlineValidation--visual">
|
|
10
|
+
<%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %>
|
|
11
|
+
</span>
|
|
12
|
+
<span><%= @text_input_validation_message %></span>
|
|
13
|
+
</div>
|
|
14
|
+
<% end %>
|
|
15
|
+
|
|
7
16
|
<% if caption %>
|
|
8
17
|
<%= caption %>
|
|
9
18
|
<% end %>
|
|
@@ -49,6 +49,19 @@ module Primer
|
|
|
49
49
|
renders_one :text_input, lambda { |readonly: true, **system_arguments|
|
|
50
50
|
deny_single_argument(:input_width, "Set the `input_width` on the `InputGroup`", **system_arguments)
|
|
51
51
|
deny_single_argument(:caption, "Set the `caption` on the `InputGroup`", **system_arguments)
|
|
52
|
+
|
|
53
|
+
# Extract validation_message so it can be rendered outside the flex row.
|
|
54
|
+
# This prevents the trailing action from misaligning when validation is present.
|
|
55
|
+
@text_input_validation_message = system_arguments.delete(:validation_message)
|
|
56
|
+
if @text_input_validation_message
|
|
57
|
+
@text_input_validation_message_id = self.class.generate_id(base_name: "input-group-validation")
|
|
58
|
+
system_arguments[:invalid] = true
|
|
59
|
+
system_arguments[:aria] = merge_aria(
|
|
60
|
+
system_arguments,
|
|
61
|
+
{ aria: { describedby: @text_input_validation_message_id } }
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
|
|
52
65
|
system_arguments[:input_width] = @system_arguments[:input_width]
|
|
53
66
|
|
|
54
67
|
system_arguments[:classes] = class_names(
|
|
@@ -15,7 +15,7 @@ let PageHeaderElement = class PageHeaderElement extends HTMLElement {
|
|
|
15
15
|
}
|
|
16
16
|
};
|
|
17
17
|
PageHeaderElement = __decorate([
|
|
18
|
-
controller
|
|
18
|
+
controller('page-header')
|
|
19
19
|
], PageHeaderElement);
|
|
20
20
|
if (!window.customElements.get('page-header')) {
|
|
21
21
|
window.PageHeaderElement = PageHeaderElement;
|
data/app/components/primer/open_project/sub_header/{quick_filter.rb → quick_action_component.rb}
RENAMED
|
@@ -5,11 +5,17 @@ module Primer
|
|
|
5
5
|
# Thin wrapper for quick filter slots that defers BaseComponent construction to render time,
|
|
6
6
|
# allowing system arguments (e.g. display) to be mutated in before_render.
|
|
7
7
|
# Do not use standalone
|
|
8
|
-
class SubHeader::
|
|
8
|
+
class SubHeader::QuickActionComponent < Primer::Component
|
|
9
9
|
status :open_project
|
|
10
10
|
|
|
11
11
|
def initialize(**system_arguments)
|
|
12
12
|
@system_arguments = system_arguments
|
|
13
|
+
system_arguments[:tag] = :div
|
|
14
|
+
system_arguments[:mr] ||= 2
|
|
15
|
+
system_arguments[:classes] = class_names(
|
|
16
|
+
"SubHeader-hiddenOnExpand",
|
|
17
|
+
system_arguments[:classes]
|
|
18
|
+
)
|
|
13
19
|
end
|
|
14
20
|
|
|
15
21
|
def merge_system_arguments!(**other_arguments)
|