openproject-primer_view_components 0.22.1 → 0.22.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +14 -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_bar_element.js +12 -4
- data/app/components/primer/alpha/action_bar_element.ts +10 -4
- data/app/components/primer/alpha/action_menu/action_menu_element.js +4 -1
- data/app/components/primer/alpha/action_menu/action_menu_element.ts +4 -1
- data/app/components/primer/alpha/banner.html.erb +1 -2
- data/app/components/primer/alpha/banner.rb +7 -0
- data/app/components/primer/alpha/dialog.rb +0 -1
- data/app/components/primer/alpha/modal_dialog.js +3 -0
- data/app/components/primer/alpha/modal_dialog.ts +3 -0
- data/app/components/primer/alpha/toggle_switch.js +2 -2
- data/app/components/primer/alpha/toggle_switch.ts +2 -2
- data/app/components/primer/alpha/tool_tip.js +1 -0
- data/app/components/primer/alpha/tool_tip.ts +1 -0
- data/app/components/primer/beta/clipboard_copy.ts +1 -1
- data/app/components/primer/beta/nav_list.js +2 -0
- data/app/components/primer/beta/nav_list.ts +2 -0
- data/app/components/primer/dialog_helper.js +36 -15
- data/app/components/primer/dialog_helper.ts +40 -14
- data/app/components/primer/focus_group.ts +1 -1
- data/lib/primer/view_components/version.rb +1 -1
- data/previews/primer/alpha/dialog_preview/dialog_inside_overlay.html.erb +13 -2
- data/previews/primer/alpha/dialog_preview.rb +1 -0
- data/static/info_arch.json +2 -2
- data/static/previews.json +1 -1
- metadata +3 -3
@@ -140,12 +140,20 @@ _ActionBarElement_firstItem_get = function _ActionBarElement_firstItem_get() {
|
|
140
140
|
return foundItem;
|
141
141
|
};
|
142
142
|
_ActionBarElement_showItem = function _ActionBarElement_showItem(index) {
|
143
|
-
this.items[index]
|
144
|
-
__classPrivateFieldGet(this, _ActionBarElement_instances, "a", _ActionBarElement_menuItems_get)[index]
|
143
|
+
const item = this.items[index];
|
144
|
+
const menuItem = __classPrivateFieldGet(this, _ActionBarElement_instances, "a", _ActionBarElement_menuItems_get)[index];
|
145
|
+
if (!item || !menuItem)
|
146
|
+
return;
|
147
|
+
item.style.setProperty('visibility', 'visible');
|
148
|
+
menuItem.hidden = true;
|
145
149
|
};
|
146
150
|
_ActionBarElement_hideItem = function _ActionBarElement_hideItem(index) {
|
147
|
-
this.items[index]
|
148
|
-
__classPrivateFieldGet(this, _ActionBarElement_instances, "a", _ActionBarElement_menuItems_get)[index]
|
151
|
+
const item = this.items[index];
|
152
|
+
const menuItem = __classPrivateFieldGet(this, _ActionBarElement_instances, "a", _ActionBarElement_menuItems_get)[index];
|
153
|
+
if (!item || !menuItem)
|
154
|
+
return;
|
155
|
+
item.style.setProperty('visibility', 'hidden');
|
156
|
+
menuItem.hidden = false;
|
149
157
|
};
|
150
158
|
_ActionBarElement_menuItems_get = function _ActionBarElement_menuItems_get() {
|
151
159
|
return this.moreMenu.querySelectorAll('[role="menu"] > li');
|
@@ -145,13 +145,19 @@ class ActionBarElement extends HTMLElement {
|
|
145
145
|
}
|
146
146
|
|
147
147
|
#showItem(index: number) {
|
148
|
-
this.items[index]
|
149
|
-
this.#menuItems[index]
|
148
|
+
const item = this.items[index]
|
149
|
+
const menuItem = this.#menuItems[index]
|
150
|
+
if (!item || !menuItem) return
|
151
|
+
item.style.setProperty('visibility', 'visible')
|
152
|
+
menuItem.hidden = true
|
150
153
|
}
|
151
154
|
|
152
155
|
#hideItem(index: number) {
|
153
|
-
this.items[index]
|
154
|
-
this.#menuItems[index]
|
156
|
+
const item = this.items[index]
|
157
|
+
const menuItem = this.#menuItems[index]
|
158
|
+
if (!item || !menuItem) return
|
159
|
+
item.style.setProperty('visibility', 'hidden')
|
160
|
+
menuItem.hidden = false
|
155
161
|
}
|
156
162
|
|
157
163
|
get #menuItems(): NodeListOf<HTMLElement> {
|
@@ -265,7 +265,9 @@ _ActionMenuElement_potentiallyDisallowActivation = function _ActionMenuElement_p
|
|
265
265
|
return false;
|
266
266
|
if (item.getAttribute('aria-disabled')) {
|
267
267
|
event.preventDefault();
|
268
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
268
269
|
event.stopPropagation();
|
270
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
269
271
|
event.stopImmediatePropagation();
|
270
272
|
return true;
|
271
273
|
}
|
@@ -294,6 +296,7 @@ _ActionMenuElement_isActivation = function _ActionMenuElement_isActivation(event
|
|
294
296
|
};
|
295
297
|
_ActionMenuElement_handleInvokerActivated = function _ActionMenuElement_handleInvokerActivated(event) {
|
296
298
|
event.preventDefault();
|
299
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
297
300
|
event.stopPropagation();
|
298
301
|
if (__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_isOpen).call(this)) {
|
299
302
|
__classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_hide).call(this);
|
@@ -320,7 +323,6 @@ _ActionMenuElement_handleDialogItemActivated = function _ActionMenuElement_handl
|
|
320
323
|
}
|
321
324
|
};
|
322
325
|
// a modal <dialog> element will close all popovers
|
323
|
-
setTimeout(() => __classPrivateFieldGet(this, _ActionMenuElement_instances, "m", _ActionMenuElement_show).call(this), 0);
|
324
326
|
dialog.addEventListener('close', handleDialogClose, { signal });
|
325
327
|
dialog.addEventListener('cancel', handleDialogClose, { signal });
|
326
328
|
};
|
@@ -377,6 +379,7 @@ _ActionMenuElement_activateItem = function _ActionMenuElement_activateItem(event
|
|
377
379
|
return;
|
378
380
|
// otherwise, event will not result in activation by default, so we stop it and
|
379
381
|
// simulate a click
|
382
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
380
383
|
event.stopPropagation();
|
381
384
|
const elem = item;
|
382
385
|
elem.click();
|
@@ -141,7 +141,9 @@ export class ActionMenuElement extends HTMLElement {
|
|
141
141
|
|
142
142
|
if (item.getAttribute('aria-disabled')) {
|
143
143
|
event.preventDefault()
|
144
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
144
145
|
event.stopPropagation()
|
146
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
145
147
|
event.stopImmediatePropagation()
|
146
148
|
return true
|
147
149
|
}
|
@@ -260,6 +262,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
260
262
|
|
261
263
|
#handleInvokerActivated(event: Event) {
|
262
264
|
event.preventDefault()
|
265
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
263
266
|
event.stopPropagation()
|
264
267
|
|
265
268
|
if (this.#isOpen()) {
|
@@ -287,7 +290,6 @@ export class ActionMenuElement extends HTMLElement {
|
|
287
290
|
}
|
288
291
|
}
|
289
292
|
// a modal <dialog> element will close all popovers
|
290
|
-
setTimeout(() => this.#show(), 0)
|
291
293
|
dialog.addEventListener('close', handleDialogClose, {signal})
|
292
294
|
dialog.addEventListener('cancel', handleDialogClose, {signal})
|
293
295
|
}
|
@@ -354,6 +356,7 @@ export class ActionMenuElement extends HTMLElement {
|
|
354
356
|
|
355
357
|
// otherwise, event will not result in activation by default, so we stop it and
|
356
358
|
// simulate a click
|
359
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
357
360
|
event.stopPropagation()
|
358
361
|
const elem = item as HTMLElement
|
359
362
|
elem.click()
|
@@ -23,8 +23,7 @@
|
|
23
23
|
scheme: :invisible,
|
24
24
|
icon: :x,
|
25
25
|
aria: { label: @dismiss_label },
|
26
|
-
data: { action: catalyst_action(event: "click", function: "dismiss") }
|
27
|
-
autofocus: true
|
26
|
+
data: { action: catalyst_action(event: "click", function: "dismiss") }
|
28
27
|
)
|
29
28
|
) %>
|
30
29
|
</div>
|
@@ -3,6 +3,13 @@
|
|
3
3
|
module Primer
|
4
4
|
module Alpha
|
5
5
|
# Use `Banner` to highlight important information.
|
6
|
+
#
|
7
|
+
# @accessibility
|
8
|
+
# Depending on the scenario, some Banners may need to receive focus when they appear. This helps to maximize discoverability of the message, especially in critical scenarios. Visit the [Banner's Accessibility section](https://primer.style/components/banner#accessibility) or defer to the accessibility team to determine if your scenario requires focusing the banner.
|
9
|
+
#
|
10
|
+
# To properly focus a banner, add a `tabindex="-1"` to the Banner container, and focus that container (one way is using the [`focus()` API](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus)).
|
11
|
+
#
|
12
|
+
# For more information about the focus management technique, visit the [Accessible Banner Prototype docs](https://github.com/github/accessibility/blob/main/docs/coaching-recommendations/toast-flash-banner/accessible-banner-prototype.md#consideration). This guidance is subject to change.
|
6
13
|
class Banner < Primer::Component
|
7
14
|
status :alpha
|
8
15
|
|
@@ -26,6 +26,7 @@ function clickHandler(event) {
|
|
26
26
|
// If the user is clicking a valid dialog trigger
|
27
27
|
let dialogId = button === null || button === void 0 ? void 0 : button.getAttribute('data-show-dialog-id');
|
28
28
|
if (dialogId) {
|
29
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
29
30
|
event.stopPropagation();
|
30
31
|
const dialog = document.getElementById(dialogId);
|
31
32
|
if (dialog instanceof ModalDialogElement) {
|
@@ -169,11 +170,13 @@ _ModalDialogElement_focusAbortController = new WeakMap(), _ModalDialogElement_in
|
|
169
170
|
case 'Escape':
|
170
171
|
this.close();
|
171
172
|
event.preventDefault();
|
173
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
172
174
|
event.stopPropagation();
|
173
175
|
break;
|
174
176
|
case 'Enter': {
|
175
177
|
const target = event.target;
|
176
178
|
if (target.getAttribute('data-close-dialog-id') === this.id) {
|
179
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
177
180
|
event.stopPropagation();
|
178
181
|
}
|
179
182
|
break;
|
@@ -18,6 +18,7 @@ function clickHandler(event: Event) {
|
|
18
18
|
// If the user is clicking a valid dialog trigger
|
19
19
|
let dialogId = button?.getAttribute('data-show-dialog-id')
|
20
20
|
if (dialogId) {
|
21
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
21
22
|
event.stopPropagation()
|
22
23
|
const dialog = document.getElementById(dialogId)
|
23
24
|
if (dialog instanceof ModalDialogElement) {
|
@@ -170,12 +171,14 @@ export class ModalDialogElement extends HTMLElement {
|
|
170
171
|
case 'Escape':
|
171
172
|
this.close()
|
172
173
|
event.preventDefault()
|
174
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
173
175
|
event.stopPropagation()
|
174
176
|
break
|
175
177
|
case 'Enter': {
|
176
178
|
const target = event.target as HTMLElement
|
177
179
|
|
178
180
|
if (target.getAttribute('data-close-dialog-id') === this.id) {
|
181
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
179
182
|
event.stopPropagation()
|
180
183
|
}
|
181
184
|
break
|
@@ -134,9 +134,9 @@ let ToggleSwitchElement = class ToggleSwitchElement extends HTMLElement {
|
|
134
134
|
credentials: 'same-origin',
|
135
135
|
method: 'POST',
|
136
136
|
headers: {
|
137
|
-
'Requested-With': 'XMLHttpRequest'
|
137
|
+
'Requested-With': 'XMLHttpRequest',
|
138
138
|
},
|
139
|
-
body
|
139
|
+
body,
|
140
140
|
});
|
141
141
|
}
|
142
142
|
catch (error) {
|
@@ -163,9 +163,9 @@ class ToggleSwitchElement extends HTMLElement {
|
|
163
163
|
credentials: 'same-origin',
|
164
164
|
method: 'POST',
|
165
165
|
headers: {
|
166
|
-
'Requested-With': 'XMLHttpRequest'
|
166
|
+
'Requested-With': 'XMLHttpRequest',
|
167
167
|
},
|
168
|
-
body
|
168
|
+
body,
|
169
169
|
})
|
170
170
|
} catch (error) {
|
171
171
|
throw new Error('A network error occurred, please try again.')
|
@@ -310,6 +310,7 @@ class ToolTipElement extends HTMLElement {
|
|
310
310
|
const isOpeningOtherPopover = event.type === 'beforetoggle' && event.currentTarget !== this;
|
311
311
|
const shouldHide = isMouseLeaveFromButton || isEscapeKeydown || isMouseDownOnButton || isOpeningOtherPopover;
|
312
312
|
if (showing && isEscapeKeydown) {
|
313
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
313
314
|
event.stopImmediatePropagation();
|
314
315
|
event.preventDefault();
|
315
316
|
}
|
@@ -316,6 +316,7 @@ class ToolTipElement extends HTMLElement {
|
|
316
316
|
const shouldHide = isMouseLeaveFromButton || isEscapeKeydown || isMouseDownOnButton || isOpeningOtherPopover
|
317
317
|
|
318
318
|
if (showing && isEscapeKeydown) {
|
319
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
319
320
|
event.stopImmediatePropagation()
|
320
321
|
event.preventDefault()
|
321
322
|
}
|
@@ -77,6 +77,7 @@ let NavListElement = class NavListElement extends HTMLElement {
|
|
77
77
|
else {
|
78
78
|
this.expandItem(button);
|
79
79
|
}
|
80
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
80
81
|
e.stopPropagation();
|
81
82
|
}
|
82
83
|
// collapse item
|
@@ -97,6 +98,7 @@ let NavListElement = class NavListElement extends HTMLElement {
|
|
97
98
|
if (this.itemIsExpanded(button) && e.key === 'Escape') {
|
98
99
|
this.collapseItem(button);
|
99
100
|
}
|
101
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
100
102
|
e.stopPropagation();
|
101
103
|
}
|
102
104
|
};
|
@@ -74,6 +74,7 @@ export class NavListElement extends HTMLElement {
|
|
74
74
|
this.expandItem(button)
|
75
75
|
}
|
76
76
|
|
77
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
77
78
|
e.stopPropagation()
|
78
79
|
}
|
79
80
|
|
@@ -96,6 +97,7 @@ export class NavListElement extends HTMLElement {
|
|
96
97
|
this.collapseItem(button)
|
97
98
|
}
|
98
99
|
|
100
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
99
101
|
e.stopPropagation()
|
100
102
|
}
|
101
103
|
|
@@ -11,6 +11,7 @@ var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (
|
|
11
11
|
};
|
12
12
|
var _DialogHelperElement_abortController;
|
13
13
|
function dialogInvokerButtonHandler(event) {
|
14
|
+
var _a;
|
14
15
|
const target = event.target;
|
15
16
|
const button = target === null || target === void 0 ? void 0 : target.closest('button');
|
16
17
|
if (!button || button.hasAttribute('disabled') || button.getAttribute('aria-disabled') === 'true')
|
@@ -25,6 +26,41 @@ function dialogInvokerButtonHandler(event) {
|
|
25
26
|
// If the behaviour is allowed through the dialog will be shown but then
|
26
27
|
// quickly hidden- as if it were never shown. This prevents that.
|
27
28
|
event.preventDefault();
|
29
|
+
// In some older browsers, such as Chrome 122, when a top layer element (such as a dialog)
|
30
|
+
// opens from within a popover, the "hide all popovers" internal algorithm runs, hiding
|
31
|
+
// any popover that is currently open, regardless of whether or not another top layer element,
|
32
|
+
// such as a <dialog> is nested inside.
|
33
|
+
// See https://github.com/whatwg/html/issues/9998.
|
34
|
+
// This is fixed by https://github.com/whatwg/html/pull/10116, but while we still support browsers
|
35
|
+
// that present this bug, we must undo the work they did to hide ancestral popovers of the dialog:
|
36
|
+
let node = button;
|
37
|
+
let fixed = false;
|
38
|
+
while (node) {
|
39
|
+
node = (_a = node.parentElement) === null || _a === void 0 ? void 0 : _a.closest('[popover]:not(:popover-open)');
|
40
|
+
if (node && node.popover === 'auto') {
|
41
|
+
node.classList.add('dialog-inside-popover-fix');
|
42
|
+
node.popover = 'manual';
|
43
|
+
node.showPopover();
|
44
|
+
fixed = true;
|
45
|
+
}
|
46
|
+
}
|
47
|
+
if (fixed) {
|
48
|
+
// We need to re-open the dialog as modal, and also ensure no close event listeners
|
49
|
+
// are trying to act on the close
|
50
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
51
|
+
dialog.addEventListener('close', e => e.stopImmediatePropagation(), { once: true });
|
52
|
+
dialog.close();
|
53
|
+
dialog.showModal();
|
54
|
+
dialog.addEventListener('close', () => {
|
55
|
+
for (const el of dialog.ownerDocument.querySelectorAll('.dialog-inside-popover-fix')) {
|
56
|
+
if (el.contains(dialog)) {
|
57
|
+
el.classList.remove('dialog-inside-popover-fix');
|
58
|
+
el.popover = 'auto';
|
59
|
+
el.showPopover();
|
60
|
+
}
|
61
|
+
}
|
62
|
+
}, { once: true });
|
63
|
+
}
|
28
64
|
}
|
29
65
|
}
|
30
66
|
dialogId = button.getAttribute('data-close-dialog-id') || button.getAttribute('data-submit-dialog-id');
|
@@ -52,21 +88,6 @@ export class DialogHelperElement extends HTMLElement {
|
|
52
88
|
for (const record of records) {
|
53
89
|
if (record.target === this.dialog) {
|
54
90
|
this.ownerDocument.body.classList.toggle('has-modal', this.dialog.hasAttribute('open'));
|
55
|
-
// In some older browsers, such as Chrome 122, when a top layer element (such as a dialog)
|
56
|
-
// opens from within a popover, the "hide all popovers" internal algorithm runs, hiding
|
57
|
-
// any popover that is currently open, regardless of whether or not another top layer element,
|
58
|
-
// such as a <dialog> is nested inside.
|
59
|
-
// See https://github.com/whatwg/html/issues/9998.
|
60
|
-
// This is fixed by https://github.com/whatwg/html/pull/10116, but while we still support browsers that present this bug,
|
61
|
-
// we must undo the work they did to hide ancestral popovers of the dialog:
|
62
|
-
if (this.dialog.hasAttribute('open')) {
|
63
|
-
let node = this.dialog;
|
64
|
-
while (node) {
|
65
|
-
node = node.closest('[popover]:not(:popover-open)');
|
66
|
-
if (node)
|
67
|
-
node.showPopover();
|
68
|
-
}
|
69
|
-
}
|
70
91
|
}
|
71
92
|
}
|
72
93
|
}).observe(this, { subtree: true, attributeFilter: ['open'] });
|
@@ -14,6 +14,46 @@ function dialogInvokerButtonHandler(event: Event) {
|
|
14
14
|
// If the behaviour is allowed through the dialog will be shown but then
|
15
15
|
// quickly hidden- as if it were never shown. This prevents that.
|
16
16
|
event.preventDefault()
|
17
|
+
|
18
|
+
// In some older browsers, such as Chrome 122, when a top layer element (such as a dialog)
|
19
|
+
// opens from within a popover, the "hide all popovers" internal algorithm runs, hiding
|
20
|
+
// any popover that is currently open, regardless of whether or not another top layer element,
|
21
|
+
// such as a <dialog> is nested inside.
|
22
|
+
// See https://github.com/whatwg/html/issues/9998.
|
23
|
+
// This is fixed by https://github.com/whatwg/html/pull/10116, but while we still support browsers
|
24
|
+
// that present this bug, we must undo the work they did to hide ancestral popovers of the dialog:
|
25
|
+
let node: HTMLElement | null | undefined = button
|
26
|
+
let fixed = false
|
27
|
+
while (node) {
|
28
|
+
node = node.parentElement?.closest('[popover]:not(:popover-open)')
|
29
|
+
if (node && node.popover === 'auto') {
|
30
|
+
node.classList.add('dialog-inside-popover-fix')
|
31
|
+
node.popover = 'manual'
|
32
|
+
node.showPopover()
|
33
|
+
fixed = true
|
34
|
+
}
|
35
|
+
}
|
36
|
+
if (fixed) {
|
37
|
+
// We need to re-open the dialog as modal, and also ensure no close event listeners
|
38
|
+
// are trying to act on the close
|
39
|
+
/* eslint-disable-next-line no-restricted-syntax */
|
40
|
+
dialog.addEventListener('close', e => e.stopImmediatePropagation(), {once: true})
|
41
|
+
dialog.close()
|
42
|
+
dialog.showModal()
|
43
|
+
dialog.addEventListener(
|
44
|
+
'close',
|
45
|
+
() => {
|
46
|
+
for (const el of dialog.ownerDocument.querySelectorAll<HTMLElement>('.dialog-inside-popover-fix')) {
|
47
|
+
if (el.contains(dialog)) {
|
48
|
+
el.classList.remove('dialog-inside-popover-fix')
|
49
|
+
el.popover = 'auto'
|
50
|
+
el.showPopover()
|
51
|
+
}
|
52
|
+
}
|
53
|
+
},
|
54
|
+
{once: true},
|
55
|
+
)
|
56
|
+
}
|
17
57
|
}
|
18
58
|
}
|
19
59
|
|
@@ -44,20 +84,6 @@ export class DialogHelperElement extends HTMLElement {
|
|
44
84
|
for (const record of records) {
|
45
85
|
if (record.target === this.dialog) {
|
46
86
|
this.ownerDocument.body.classList.toggle('has-modal', this.dialog.hasAttribute('open'))
|
47
|
-
// In some older browsers, such as Chrome 122, when a top layer element (such as a dialog)
|
48
|
-
// opens from within a popover, the "hide all popovers" internal algorithm runs, hiding
|
49
|
-
// any popover that is currently open, regardless of whether or not another top layer element,
|
50
|
-
// such as a <dialog> is nested inside.
|
51
|
-
// See https://github.com/whatwg/html/issues/9998.
|
52
|
-
// This is fixed by https://github.com/whatwg/html/pull/10116, but while we still support browsers that present this bug,
|
53
|
-
// we must undo the work they did to hide ancestral popovers of the dialog:
|
54
|
-
if (this.dialog.hasAttribute('open')) {
|
55
|
-
let node: HTMLElement | null = this.dialog
|
56
|
-
while (node) {
|
57
|
-
node = node.closest('[popover]:not(:popover-open)')
|
58
|
-
if (node) node.showPopover()
|
59
|
-
}
|
60
|
-
}
|
61
87
|
}
|
62
88
|
}
|
63
89
|
}).observe(this, {subtree: true, attributeFilter: ['open']})
|
@@ -1,9 +1,20 @@
|
|
1
|
-
<%= render(Primer::Alpha::Overlay.new(title: "An overlay")) do |o| %>
|
1
|
+
<%= render(Primer::Alpha::Overlay.new(title: "An overlay", id: "first-overlay")) do |o| %>
|
2
2
|
<% o.with_show_button() { "Show overlay" } %>
|
3
3
|
<% o.with_body() do %>
|
4
4
|
<%= render(Primer::Alpha::Dialog.new(id: "dialog-one", title: title, position: position, subtitle: subtitle, visually_hide_title: false)) do |d| %>
|
5
5
|
<% d.with_show_button { button_text } %>
|
6
|
-
<% d.with_body { body_text} %>
|
6
|
+
<% d.with_body { body_text } %>
|
7
|
+
<% d.with_footer(show_divider: true) do %>
|
8
|
+
<%= render(Primer::ButtonComponent.new(data: { "close-dialog-id": "dialog-one" })) { "Cancel" } %>
|
9
|
+
<% end %>
|
7
10
|
<% end %>
|
8
11
|
<% end %>
|
9
12
|
<% end %>
|
13
|
+
|
14
|
+
<script type="module">
|
15
|
+
document.getElementById('overlay-show-first-overlay')?.addEventListener('click', e => {
|
16
|
+
setTimeout(() => {
|
17
|
+
document.getElementById('first-overlay').querySelector('button')?.click()
|
18
|
+
});
|
19
|
+
});
|
20
|
+
</script>
|
@@ -259,6 +259,7 @@ module Primer
|
|
259
259
|
# @param visually_hide_title [Boolean] toggle
|
260
260
|
# @param button_text [String] text
|
261
261
|
# @param body_text [String] text
|
262
|
+
# @snapshot interactive
|
262
263
|
def dialog_inside_overlay(title: "Test Dialog", subtitle: nil, position: :center, size: :medium, button_text: "Show Dialog", body_text: "Content", position_narrow: :fullscreen, visually_hide_title: false)
|
263
264
|
render_with_template(locals: {
|
264
265
|
title: title,
|
data/static/info_arch.json
CHANGED
@@ -2232,7 +2232,7 @@
|
|
2232
2232
|
{
|
2233
2233
|
"fully_qualified_name": "Primer::Alpha::Banner",
|
2234
2234
|
"description": "Use `Banner` to highlight important information.",
|
2235
|
-
"accessibility_docs":
|
2235
|
+
"accessibility_docs": "Depending on the scenario, some Banners may need to receive focus when they appear. This helps to maximize discoverability of the message, especially in critical scenarios. Visit the [Banner's Accessibility section](https://primer.style/components/banner#accessibility) or defer to the accessibility team to determine if your scenario requires focusing the banner.\n\nTo properly focus a banner, add a `tabindex=\"-1\"` to the Banner container, and focus that container (one way is using the [`focus()` API](https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus)).\n\nFor more information about the focus management technique, visit the [Accessible Banner Prototype docs](https://github.com/github/accessibility/blob/main/docs/coaching-recommendations/toast-flash-banner/accessible-banner-prototype.md#consideration). This guidance is subject to change.",
|
2236
2236
|
"is_form_component": false,
|
2237
2237
|
"is_published": true,
|
2238
2238
|
"requires_js": true,
|
@@ -3379,7 +3379,7 @@
|
|
3379
3379
|
{
|
3380
3380
|
"preview_path": "primer/alpha/dialog/dialog_inside_overlay",
|
3381
3381
|
"name": "dialog_inside_overlay",
|
3382
|
-
"snapshot": "
|
3382
|
+
"snapshot": "interactive",
|
3383
3383
|
"skip_rules": {
|
3384
3384
|
"wont_fix": [
|
3385
3385
|
"region"
|
data/static/previews.json
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openproject-primer_view_components
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.22.
|
4
|
+
version: 0.22.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- GitHub Open Source
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2024-02-
|
12
|
+
date: 2024-02-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionview
|
@@ -916,7 +916,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
916
916
|
requirements:
|
917
917
|
- - ">="
|
918
918
|
- !ruby/object:Gem::Version
|
919
|
-
version: 2.
|
919
|
+
version: 2.7.0
|
920
920
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
921
921
|
requirements:
|
922
922
|
- - ">="
|