openproject-primer_view_components 0.22.0 → 0.22.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +8 -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/dialog_helper.js +17 -7
- data/app/components/primer/dialog_helper.ts +16 -7
- data/lib/primer/view_components/version.rb +1 -1
- data/previews/primer/alpha/dialog_preview/dialog_inside_overlay.html.erb +9 -0
- data/previews/primer/alpha/dialog_preview/nested_dialog.html.erb +7 -0
- data/previews/primer/alpha/dialog_preview.rb +23 -0
- data/static/info_arch.json +13 -0
- data/static/previews.json +13 -0
- metadata +3 -2
@@ -18,7 +18,6 @@ function dialogInvokerButtonHandler(event) {
|
|
18
18
|
// If the user is clicking a valid dialog trigger
|
19
19
|
let dialogId = button === null || button === void 0 ? void 0 : button.getAttribute('data-show-dialog-id');
|
20
20
|
if (dialogId) {
|
21
|
-
event.stopPropagation();
|
22
21
|
const dialog = document.getElementById(dialogId);
|
23
22
|
if (dialog instanceof HTMLDialogElement) {
|
24
23
|
dialog.showModal();
|
@@ -26,7 +25,6 @@ function dialogInvokerButtonHandler(event) {
|
|
26
25
|
// If the behaviour is allowed through the dialog will be shown but then
|
27
26
|
// quickly hidden- as if it were never shown. This prevents that.
|
28
27
|
event.preventDefault();
|
29
|
-
event.stopPropagation();
|
30
28
|
}
|
31
29
|
}
|
32
30
|
dialogId = button.getAttribute('data-close-dialog-id') || button.getAttribute('data-submit-dialog-id');
|
@@ -54,6 +52,21 @@ export class DialogHelperElement extends HTMLElement {
|
|
54
52
|
for (const record of records) {
|
55
53
|
if (record.target === this.dialog) {
|
56
54
|
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
|
+
}
|
57
70
|
}
|
58
71
|
}
|
59
72
|
}).observe(this, { subtree: true, attributeFilter: ['open'] });
|
@@ -65,11 +78,8 @@ export class DialogHelperElement extends HTMLElement {
|
|
65
78
|
handleEvent(event) {
|
66
79
|
const target = event.target;
|
67
80
|
const dialog = this.dialog;
|
68
|
-
|
69
|
-
|
70
|
-
// if the target is inside the dialog, but is not the dialog itself, leave
|
71
|
-
// the dialog open
|
72
|
-
if ((target === null || target === void 0 ? void 0 : target.closest('dialog')) === dialog && target !== dialog)
|
81
|
+
// The click target _must_ be the dialog element itself, and not elements underneath or inside.
|
82
|
+
if (target !== dialog || !(dialog === null || dialog === void 0 ? void 0 : dialog.open))
|
73
83
|
return;
|
74
84
|
const rect = dialog.getBoundingClientRect();
|
75
85
|
const clickWasInsideDialog = rect.top <= event.clientY &&
|
@@ -7,7 +7,6 @@ function dialogInvokerButtonHandler(event: Event) {
|
|
7
7
|
// If the user is clicking a valid dialog trigger
|
8
8
|
let dialogId = button?.getAttribute('data-show-dialog-id')
|
9
9
|
if (dialogId) {
|
10
|
-
event.stopPropagation()
|
11
10
|
const dialog = document.getElementById(dialogId)
|
12
11
|
if (dialog instanceof HTMLDialogElement) {
|
13
12
|
dialog.showModal()
|
@@ -15,7 +14,6 @@ function dialogInvokerButtonHandler(event: Event) {
|
|
15
14
|
// If the behaviour is allowed through the dialog will be shown but then
|
16
15
|
// quickly hidden- as if it were never shown. This prevents that.
|
17
16
|
event.preventDefault()
|
18
|
-
event.stopPropagation()
|
19
17
|
}
|
20
18
|
}
|
21
19
|
|
@@ -46,6 +44,20 @@ export class DialogHelperElement extends HTMLElement {
|
|
46
44
|
for (const record of records) {
|
47
45
|
if (record.target === this.dialog) {
|
48
46
|
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
|
+
}
|
49
61
|
}
|
50
62
|
}
|
51
63
|
}).observe(this, {subtree: true, attributeFilter: ['open']})
|
@@ -58,11 +70,8 @@ export class DialogHelperElement extends HTMLElement {
|
|
58
70
|
handleEvent(event: MouseEvent) {
|
59
71
|
const target = event.target as HTMLElement
|
60
72
|
const dialog = this.dialog
|
61
|
-
|
62
|
-
|
63
|
-
// if the target is inside the dialog, but is not the dialog itself, leave
|
64
|
-
// the dialog open
|
65
|
-
if (target?.closest('dialog') === dialog && target !== dialog) return
|
73
|
+
// The click target _must_ be the dialog element itself, and not elements underneath or inside.
|
74
|
+
if (target !== dialog || !dialog?.open) return
|
66
75
|
|
67
76
|
const rect = dialog.getBoundingClientRect()
|
68
77
|
const clickWasInsideDialog =
|
@@ -0,0 +1,9 @@
|
|
1
|
+
<%= render(Primer::Alpha::Overlay.new(title: "An overlay")) do |o| %>
|
2
|
+
<% o.with_show_button() { "Show overlay" } %>
|
3
|
+
<% o.with_body() do %>
|
4
|
+
<%= render(Primer::Alpha::Dialog.new(id: "dialog-one", title: title, position: position, subtitle: subtitle, visually_hide_title: false)) do |d| %>
|
5
|
+
<% d.with_show_button { button_text } %>
|
6
|
+
<% d.with_body { body_text} %>
|
7
|
+
<% end %>
|
8
|
+
<% end %>
|
9
|
+
<% end %>
|
@@ -12,3 +12,10 @@
|
|
12
12
|
<% end %>
|
13
13
|
<% end %>
|
14
14
|
<% end %>
|
15
|
+
|
16
|
+
<div style="margin-top:2rem">
|
17
|
+
<%= render(Primer::Beta::Flash.new(scheme: :warning)) do %>
|
18
|
+
<p>Please be careful nesting dialogs! Note that in this example, opening the second dialog does not close the first.</p>
|
19
|
+
<p>Closing a dialog while opening a dialog inside, will cause both to be invisible which will lead to undesired effects!</p>
|
20
|
+
<% end %>
|
21
|
+
</div>
|
@@ -248,6 +248,29 @@ module Primer
|
|
248
248
|
visually_hide_title: visually_hide_title
|
249
249
|
})
|
250
250
|
end
|
251
|
+
|
252
|
+
# @label Dialog inside Overlay
|
253
|
+
#
|
254
|
+
# @param title [String] text
|
255
|
+
# @param subtitle [String] text
|
256
|
+
# @param size [Symbol] select [small, medium, medium_portrait, large, xlarge]
|
257
|
+
# @param position [Symbol] select [center, right, left]
|
258
|
+
# @param position_narrow [Symbol] select [inherit, bottom, fullscreen, left, right]
|
259
|
+
# @param visually_hide_title [Boolean] toggle
|
260
|
+
# @param button_text [String] text
|
261
|
+
# @param body_text [String] text
|
262
|
+
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
|
+
render_with_template(locals: {
|
264
|
+
title: title,
|
265
|
+
subtitle: subtitle,
|
266
|
+
position: position,
|
267
|
+
size: size,
|
268
|
+
button_text: button_text,
|
269
|
+
body_text: body_text,
|
270
|
+
position_narrow: position_narrow,
|
271
|
+
visually_hide_title: visually_hide_title
|
272
|
+
})
|
273
|
+
end
|
251
274
|
end
|
252
275
|
end
|
253
276
|
end
|
data/static/info_arch.json
CHANGED
@@ -3375,6 +3375,19 @@
|
|
3375
3375
|
"color-contrast"
|
3376
3376
|
]
|
3377
3377
|
}
|
3378
|
+
},
|
3379
|
+
{
|
3380
|
+
"preview_path": "primer/alpha/dialog/dialog_inside_overlay",
|
3381
|
+
"name": "dialog_inside_overlay",
|
3382
|
+
"snapshot": "false",
|
3383
|
+
"skip_rules": {
|
3384
|
+
"wont_fix": [
|
3385
|
+
"region"
|
3386
|
+
],
|
3387
|
+
"will_fix": [
|
3388
|
+
"color-contrast"
|
3389
|
+
]
|
3390
|
+
}
|
3378
3391
|
}
|
3379
3392
|
],
|
3380
3393
|
"subcomponents": [
|
data/static/previews.json
CHANGED
@@ -3186,6 +3186,19 @@
|
|
3186
3186
|
"color-contrast"
|
3187
3187
|
]
|
3188
3188
|
}
|
3189
|
+
},
|
3190
|
+
{
|
3191
|
+
"preview_path": "primer/alpha/dialog/dialog_inside_overlay",
|
3192
|
+
"name": "dialog_inside_overlay",
|
3193
|
+
"snapshot": "false",
|
3194
|
+
"skip_rules": {
|
3195
|
+
"wont_fix": [
|
3196
|
+
"region"
|
3197
|
+
],
|
3198
|
+
"will_fix": [
|
3199
|
+
"color-contrast"
|
3200
|
+
]
|
3201
|
+
}
|
3189
3202
|
}
|
3190
3203
|
]
|
3191
3204
|
},
|
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.1
|
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-05 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: actionview
|
@@ -760,6 +760,7 @@ files:
|
|
760
760
|
- previews/primer/alpha/dialog_preview/autofocus_element.html.erb
|
761
761
|
- previews/primer/alpha/dialog_preview/body_has_scrollbar_overflow.html.erb
|
762
762
|
- previews/primer/alpha/dialog_preview/custom_header.html.erb
|
763
|
+
- previews/primer/alpha/dialog_preview/dialog_inside_overlay.html.erb
|
763
764
|
- previews/primer/alpha/dialog_preview/nested_dialog.html.erb
|
764
765
|
- previews/primer/alpha/dialog_preview/scroll_container.html.erb
|
765
766
|
- previews/primer/alpha/dialog_preview/test.html.erb
|