openproject-primer_view_components 0.64.0 → 0.65.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 +20 -0
- data/app/assets/javascripts/components/primer/open_project/collapsible.d.ts +2 -0
- data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view.d.ts +29 -0
- data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_icon_pair_element.d.ts +15 -0
- data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_include_fragment_element.d.ts +9 -0
- data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_roving_tab_index.d.ts +3 -0
- data/app/assets/javascripts/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +38 -0
- data/app/assets/javascripts/components/primer/primer.d.ts +4 -0
- data/app/assets/javascripts/components/primer/shared_events.d.ts +15 -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/select_panel.css +1 -1
- data/app/components/primer/alpha/select_panel.css.json +2 -2
- data/app/components/primer/alpha/select_panel.css.map +1 -1
- data/app/components/primer/alpha/select_panel.html.erb +1 -1
- data/app/components/primer/alpha/select_panel.pcss +5 -2
- data/app/components/primer/beta/spinner.html.erb +1 -1
- data/app/components/primer/beta/spinner.rb +2 -0
- data/app/components/primer/open_project/border_box/collapsible_header.css +1 -1
- data/app/components/primer/open_project/border_box/collapsible_header.css.json +2 -1
- data/app/components/primer/open_project/border_box/collapsible_header.css.map +1 -1
- data/app/components/primer/open_project/border_box/collapsible_header.html.erb +12 -1
- data/app/components/primer/open_project/border_box/collapsible_header.pcss +4 -0
- data/app/components/primer/open_project/border_box/collapsible_header.rb +16 -12
- data/app/components/primer/open_project/collapsible.d.ts +2 -0
- data/app/components/primer/open_project/collapsible.js +11 -0
- data/app/components/primer/open_project/collapsible.ts +10 -0
- data/app/components/primer/open_project/collapsible_section.html.erb +14 -2
- data/app/components/primer/open_project/collapsible_section.rb +5 -1
- data/app/components/primer/open_project/danger_dialog.html.erb +4 -0
- data/app/components/primer/open_project/feedback_dialog.html.erb +5 -0
- data/app/components/primer/open_project/file_tree_view/directory_node.html.erb +5 -0
- data/app/components/primer/open_project/file_tree_view/directory_node.rb +24 -0
- data/app/components/primer/open_project/file_tree_view/file_node.html.erb +2 -0
- data/app/components/primer/open_project/file_tree_view/file_node.rb +14 -0
- data/app/components/primer/open_project/file_tree_view.rb +15 -0
- data/app/components/primer/open_project/skeleton_box.css +1 -0
- data/app/components/primer/open_project/skeleton_box.css.json +6 -0
- data/app/components/primer/open_project/skeleton_box.css.map +1 -0
- data/app/components/primer/open_project/skeleton_box.html.erb +1 -0
- data/app/components/primer/open_project/skeleton_box.pcss +30 -0
- data/app/components/primer/open_project/skeleton_box.rb +27 -0
- data/app/components/primer/open_project/tree_view/icon.html.erb +1 -0
- data/app/components/primer/open_project/tree_view/icon.rb +22 -0
- data/app/components/primer/open_project/tree_view/icon_pair.html.erb +13 -0
- data/app/components/primer/open_project/tree_view/icon_pair.rb +42 -0
- data/app/components/primer/open_project/tree_view/leading_action.html.erb +3 -0
- data/app/components/primer/open_project/tree_view/leading_action.rb +18 -0
- data/app/components/primer/open_project/tree_view/leaf_node.html.erb +18 -0
- data/app/components/primer/open_project/tree_view/leaf_node.rb +96 -0
- data/app/components/primer/open_project/tree_view/loading_failure_message.html.erb +13 -0
- data/app/components/primer/open_project/tree_view/loading_failure_message.rb +31 -0
- data/app/components/primer/open_project/tree_view/node.html.erb +32 -0
- data/app/components/primer/open_project/tree_view/node.rb +155 -0
- data/app/components/primer/open_project/tree_view/skeleton_loader.html.erb +23 -0
- data/app/components/primer/open_project/tree_view/skeleton_loader.rb +36 -0
- data/app/components/primer/open_project/tree_view/spinner_loader.html.erb +20 -0
- data/app/components/primer/open_project/tree_view/spinner_loader.rb +33 -0
- data/app/components/primer/open_project/tree_view/sub_tree.html.erb +21 -0
- data/app/components/primer/open_project/tree_view/sub_tree.rb +106 -0
- data/app/components/primer/open_project/tree_view/sub_tree_container.html.erb +3 -0
- data/app/components/primer/open_project/tree_view/sub_tree_container.rb +39 -0
- data/app/components/primer/open_project/tree_view/sub_tree_node.html.erb +49 -0
- data/app/components/primer/open_project/tree_view/sub_tree_node.rb +172 -0
- data/app/components/primer/open_project/tree_view/tree_view.d.ts +29 -0
- data/app/components/primer/open_project/tree_view/tree_view.js +238 -0
- data/app/components/primer/open_project/tree_view/tree_view.ts +257 -0
- data/app/components/primer/open_project/tree_view/tree_view_icon_pair_element.d.ts +15 -0
- data/app/components/primer/open_project/tree_view/tree_view_icon_pair_element.js +62 -0
- data/app/components/primer/open_project/tree_view/tree_view_icon_pair_element.ts +56 -0
- data/app/components/primer/open_project/tree_view/tree_view_include_fragment_element.d.ts +9 -0
- data/app/components/primer/open_project/tree_view/tree_view_include_fragment_element.js +29 -0
- data/app/components/primer/open_project/tree_view/tree_view_include_fragment_element.ts +29 -0
- data/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.d.ts +3 -0
- data/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.js +126 -0
- data/app/components/primer/open_project/tree_view/tree_view_roving_tab_index.ts +156 -0
- data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.d.ts +38 -0
- data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.js +362 -0
- data/app/components/primer/open_project/tree_view/tree_view_sub_tree_node_element.ts +402 -0
- data/app/components/primer/open_project/tree_view/visual.html.erb +14 -0
- data/app/components/primer/open_project/tree_view/visual.rb +27 -0
- data/app/components/primer/open_project/tree_view.css +1 -0
- data/app/components/primer/open_project/tree_view.css.json +42 -0
- data/app/components/primer/open_project/tree_view.css.map +1 -0
- data/app/components/primer/open_project/tree_view.html.erb +7 -0
- data/app/components/primer/open_project/tree_view.pcss +319 -0
- data/app/components/primer/open_project/tree_view.rb +367 -0
- data/app/components/primer/primer.d.ts +4 -0
- data/app/components/primer/primer.js +4 -0
- data/app/components/primer/primer.pcss +2 -0
- data/app/components/primer/primer.ts +4 -0
- data/app/components/primer/shared_events.d.ts +15 -0
- data/app/components/primer/shared_events.ts +19 -0
- data/app/lib/primer/forms/acts_as_component.rb +1 -12
- data/lib/primer/view_components/version.rb +1 -1
- data/previews/primer/open_project/file_tree_view_preview/default.html.erb +16 -0
- data/previews/primer/open_project/file_tree_view_preview/playground.html.erb +4 -0
- data/previews/primer/open_project/file_tree_view_preview.rb +69 -0
- data/previews/primer/open_project/skeleton_box_preview.rb +20 -0
- data/previews/primer/open_project/tree_view_preview/default.html.erb +24 -0
- data/previews/primer/open_project/tree_view_preview/empty.html.erb +10 -0
- data/previews/primer/open_project/tree_view_preview/leaf_node_playground.html.erb +15 -0
- data/previews/primer/open_project/tree_view_preview/loading_failure.html.erb +36 -0
- data/previews/primer/open_project/tree_view_preview/loading_skeleton.html.erb +12 -0
- data/previews/primer/open_project/tree_view_preview/loading_spinner.html.erb +12 -0
- data/previews/primer/open_project/tree_view_preview/playground.html.erb +4 -0
- data/previews/primer/open_project/tree_view_preview.rb +139 -0
- data/static/arguments.json +400 -0
- data/static/audited_at.json +17 -0
- data/static/classes.json +18 -0
- data/static/constants.json +83 -0
- data/static/info_arch.json +1379 -0
- data/static/previews.json +167 -0
- data/static/statuses.json +17 -0
- metadata +75 -2
@@ -1 +1 @@
|
|
1
|
-
.SelectPanel-
|
1
|
+
.SelectPanel-loadingPanel{min-height:min(calc(var(--overlay-height) - 10rem),calc(100vh - 2rem))}.SelectPanel-emptyPanel{align-items:center;display:flex;justify-content:center;min-height:min(calc(var(--overlay-height) - 23rem),calc(100vh - 2rem))}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["select_panel.pcss"],"names":[],"mappings":"
|
1
|
+
{"version":3,"sources":["select_panel.pcss"],"names":[],"mappings":"AAAA,0BACE,sEACF,CAEA,wBAEE,kBAAmB,CACnB,YAAa,CACb,sBAAuB,CAHvB,sEAIF","file":"select_panel.css","sourcesContent":[".SelectPanel-loadingPanel {\n min-height: min(calc(var(--overlay-height) - 10rem), calc(100vh - 2rem));\n}\n\n.SelectPanel-emptyPanel {\n min-height: min(calc(var(--overlay-height) - 23rem), calc(100vh - 2rem));\n align-items: center;\n display: flex;\n justify-content: center;\n}\n"]}
|
@@ -97,7 +97,7 @@
|
|
97
97
|
<%= render(@list) %>
|
98
98
|
<% end %>
|
99
99
|
</div>
|
100
|
-
<div data-target="select-panel.noResults" class="
|
100
|
+
<div data-target="select-panel.noResults" class="SelectPanel-emptyPanel" hidden>
|
101
101
|
<h2 class="v-align-middle m-3 f5"><%= @no_results_label %></h2>
|
102
102
|
</div>
|
103
103
|
<% end %>
|
@@ -1,7 +1,10 @@
|
|
1
1
|
.SelectPanel-loadingPanel {
|
2
|
-
min-height: min(var(--overlay-height) - 10rem, 100vh - 2rem);
|
2
|
+
min-height: min(calc(var(--overlay-height) - 10rem), calc(100vh - 2rem));
|
3
3
|
}
|
4
4
|
|
5
5
|
.SelectPanel-emptyPanel {
|
6
|
-
min-height: min(var(--overlay-height) -
|
6
|
+
min-height: min(calc(var(--overlay-height) - 23rem), calc(100vh - 2rem));
|
7
|
+
align-items: center;
|
8
|
+
display: flex;
|
9
|
+
justify-content: center;
|
7
10
|
}
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= render(Primer::BaseComponent.new(tag: :span, hidden: @hidden, data: { target: @target })) do %>
|
1
|
+
<%= render(Primer::BaseComponent.new(tag: :span, hidden: @hidden, data: { target: @target }, **@wrapper_arguments)) do %>
|
2
2
|
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
3
3
|
<circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" fill="none" />
|
4
4
|
<path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke" />
|
@@ -1 +1 @@
|
|
1
|
-
.CollapsibleHeader{align-items:center;cursor:pointer;display:flex}.Box:has(.CollapsibleHeader--collapsed){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:var(--borderWidth-thicker)}.Box:has(.CollapsibleHeader--collapsed) .Box-body,.Box:has(.CollapsibleHeader--collapsed) .Box-footer,.Box:has(.CollapsibleHeader--collapsed) .Box-row{display:none}
|
1
|
+
.CollapsibleHeader{align-items:center;cursor:pointer;display:flex}.Box:has(.CollapsibleHeader--collapsed){border-bottom-left-radius:0;border-bottom-right-radius:0;border-bottom-width:var(--borderWidth-thicker)}.Box:has(.CollapsibleHeader--collapsed) .Box-body,.Box:has(.CollapsibleHeader--collapsed) .Box-footer,.Box:has(.CollapsibleHeader--collapsed) .Box-row{display:none}.CollapsibleHeader--triggerArea{width:100%}
|
@@ -5,6 +5,7 @@
|
|
5
5
|
".Box:has(.CollapsibleHeader--collapsed)",
|
6
6
|
".Box:has(.CollapsibleHeader--collapsed) .Box-body",
|
7
7
|
".Box:has(.CollapsibleHeader--collapsed) .Box-footer",
|
8
|
-
".Box:has(.CollapsibleHeader--collapsed) .Box-row"
|
8
|
+
".Box:has(.CollapsibleHeader--collapsed) .Box-row",
|
9
|
+
".CollapsibleHeader--triggerArea"
|
9
10
|
]
|
10
11
|
}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["collapsible_header.pcss"],"names":[],"mappings":"AAEA,mBAGI,kBAAmB,CAFnB,cAAe,CACf,YAEJ,CAEA,wCACI,2BAA4B,CAC5B,4BAA6B,CAC7B,8CAOJ,CALI,uJAGI,YACJ","file":"collapsible_header.css","sourcesContent":["/* CSS for BorderBox::CollapsibleHeader */\n\n.CollapsibleHeader {\n cursor: pointer;\n display: flex;\n align-items: center;\n}\n\n.Box:has(.CollapsibleHeader--collapsed) {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom-width: var(--borderWidth-thicker);\n\n & .Box-row,\n & .Box-body,\n & .Box-footer {\n display: none;\n }\n}\n"]}
|
1
|
+
{"version":3,"sources":["collapsible_header.pcss"],"names":[],"mappings":"AAEA,mBAGI,kBAAmB,CAFnB,cAAe,CACf,YAEJ,CAEA,wCACI,2BAA4B,CAC5B,4BAA6B,CAC7B,8CAOJ,CALI,uJAGI,YACJ,CAGJ,gCACI,UACJ","file":"collapsible_header.css","sourcesContent":["/* CSS for BorderBox::CollapsibleHeader */\n\n.CollapsibleHeader {\n cursor: pointer;\n display: flex;\n align-items: center;\n}\n\n.Box:has(.CollapsibleHeader--collapsed) {\n border-bottom-left-radius: 0;\n border-bottom-right-radius: 0;\n border-bottom-width: var(--borderWidth-thicker);\n\n & .Box-row,\n & .Box-body,\n & .Box-footer {\n display: none;\n }\n}\n\n.CollapsibleHeader--triggerArea {\n width: 100%;\n}\n"]}
|
@@ -1,5 +1,16 @@
|
|
1
1
|
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
|
2
|
-
<%= render(Primer::OpenProject::FlexLayout.new
|
2
|
+
<%= render(Primer::OpenProject::FlexLayout.new(
|
3
|
+
data: {
|
4
|
+
target: "collapsible-header.triggerElement",
|
5
|
+
action: "click:collapsible-header#toggle keydown:collapsible-header#toggleViaKeyboard"
|
6
|
+
},
|
7
|
+
tabindex: 0,
|
8
|
+
role: "button",
|
9
|
+
aria: {
|
10
|
+
expanded: !@collapsed,
|
11
|
+
},
|
12
|
+
classes: "CollapsibleHeader--triggerArea"
|
13
|
+
)) do |flex| %>
|
3
14
|
<%= flex.with_row do %>
|
4
15
|
<%= title %>
|
5
16
|
<% if count? %>
|
@@ -32,39 +32,43 @@ module Primer
|
|
32
32
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
33
33
|
renders_one :description, lambda { |**system_arguments, &block|
|
34
34
|
system_arguments[:color] ||= :subtle
|
35
|
+
system_arguments[:hidden] = @collapsed
|
36
|
+
|
35
37
|
system_arguments[:data] = merge_data(
|
36
38
|
system_arguments, {
|
37
|
-
|
39
|
+
data: {
|
38
40
|
targets: "collapsible-header.collapsibleElements"
|
39
41
|
}
|
40
42
|
}
|
41
43
|
)
|
42
|
-
system_arguments[:hidden] = @collapsed
|
43
44
|
|
44
45
|
Primer::Beta::Text.new(**system_arguments, &block)
|
45
46
|
}
|
46
47
|
|
47
|
-
|
48
|
+
# @param id [String] The unique ID of the collapsible header.
|
48
49
|
# @param collapsed [Boolean] Whether the header is collapsed on initial render.
|
49
50
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
50
|
-
def initialize(collapsed: false, box:, **system_arguments)
|
51
|
+
def initialize(id: self.class.generate_id, collapsed: false, box:, **system_arguments)
|
51
52
|
@collapsed = collapsed
|
52
53
|
@box = box
|
53
54
|
@system_arguments = system_arguments
|
54
|
-
|
55
|
+
@system_arguments[:id] = id
|
55
56
|
@system_arguments[:tag] = "collapsible-header"
|
56
57
|
@system_arguments[:classes] = class_names(
|
57
58
|
system_arguments[:classes],
|
58
59
|
"CollapsibleHeader",
|
59
60
|
"CollapsibleHeader--collapsed" => @collapsed
|
60
61
|
)
|
61
|
-
@
|
62
|
-
@system_arguments
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
62
|
+
if @collapsed
|
63
|
+
@system_arguments[:data] = merge_data(
|
64
|
+
@system_arguments, {
|
65
|
+
data: {
|
66
|
+
collapsed: @collapsed
|
67
|
+
}
|
68
|
+
}
|
69
|
+
)
|
70
|
+
end
|
71
|
+
|
68
72
|
end
|
69
73
|
|
70
74
|
private
|
@@ -1,8 +1,10 @@
|
|
1
1
|
export declare abstract class CollapsibleElement extends HTMLElement {
|
2
2
|
arrowDown: Element;
|
3
3
|
arrowUp: Element;
|
4
|
+
triggerElement: HTMLElement;
|
4
5
|
collapsibleElements: HTMLElement[];
|
5
6
|
collapsed: boolean;
|
7
|
+
toggleViaKeyboard(event: KeyboardEvent): void;
|
6
8
|
toggle(): void;
|
7
9
|
attributeChangedCallback(name: string): void;
|
8
10
|
hideAll(): void;
|
@@ -11,6 +11,12 @@ export class CollapsibleElement extends HTMLElement {
|
|
11
11
|
super(...arguments);
|
12
12
|
this.collapsed = false;
|
13
13
|
}
|
14
|
+
toggleViaKeyboard(event) {
|
15
|
+
if (event.code === 'Enter' || event.code === 'Space') {
|
16
|
+
event.preventDefault();
|
17
|
+
this.toggle();
|
18
|
+
}
|
19
|
+
}
|
14
20
|
toggle() {
|
15
21
|
this.collapsed = !this.collapsed;
|
16
22
|
}
|
@@ -28,6 +34,7 @@ export class CollapsibleElement extends HTMLElement {
|
|
28
34
|
// For whatever reason, setting `hidden` directly does not work on the SVGs
|
29
35
|
this.arrowDown?.removeAttribute('hidden');
|
30
36
|
this.arrowUp?.setAttribute('hidden', '');
|
37
|
+
this.triggerElement.setAttribute('aria-expanded', 'false');
|
31
38
|
for (const el of this.collapsibleElements) {
|
32
39
|
el.hidden = true;
|
33
40
|
}
|
@@ -36,6 +43,7 @@ export class CollapsibleElement extends HTMLElement {
|
|
36
43
|
expandAll() {
|
37
44
|
this.arrowUp?.removeAttribute('hidden');
|
38
45
|
this.arrowDown?.setAttribute('hidden', '');
|
46
|
+
this.triggerElement.setAttribute('aria-expanded', 'true');
|
39
47
|
for (const el of this.collapsibleElements) {
|
40
48
|
el.hidden = false;
|
41
49
|
}
|
@@ -48,6 +56,9 @@ __decorate([
|
|
48
56
|
__decorate([
|
49
57
|
target
|
50
58
|
], CollapsibleElement.prototype, "arrowUp", void 0);
|
59
|
+
__decorate([
|
60
|
+
target
|
61
|
+
], CollapsibleElement.prototype, "triggerElement", void 0);
|
51
62
|
__decorate([
|
52
63
|
targets
|
53
64
|
], CollapsibleElement.prototype, "collapsibleElements", void 0);
|
@@ -4,10 +4,18 @@ import {attr, target, targets} from '@github/catalyst'
|
|
4
4
|
export abstract class CollapsibleElement extends HTMLElement {
|
5
5
|
@target arrowDown: Element
|
6
6
|
@target arrowUp: Element
|
7
|
+
@target triggerElement: HTMLElement
|
7
8
|
@targets collapsibleElements: HTMLElement[]
|
8
9
|
|
9
10
|
@attr collapsed = false
|
10
11
|
|
12
|
+
toggleViaKeyboard(event: KeyboardEvent) {
|
13
|
+
if (event.code === 'Enter' || event.code === 'Space') {
|
14
|
+
event.preventDefault()
|
15
|
+
this.toggle()
|
16
|
+
}
|
17
|
+
}
|
18
|
+
|
11
19
|
toggle() {
|
12
20
|
this.collapsed = !this.collapsed
|
13
21
|
}
|
@@ -26,6 +34,7 @@ export abstract class CollapsibleElement extends HTMLElement {
|
|
26
34
|
// For whatever reason, setting `hidden` directly does not work on the SVGs
|
27
35
|
this.arrowDown?.removeAttribute('hidden')
|
28
36
|
this.arrowUp?.setAttribute('hidden', '')
|
37
|
+
this.triggerElement.setAttribute('aria-expanded', 'false')
|
29
38
|
|
30
39
|
for (const el of this.collapsibleElements) {
|
31
40
|
el.hidden = true
|
@@ -37,6 +46,7 @@ export abstract class CollapsibleElement extends HTMLElement {
|
|
37
46
|
expandAll() {
|
38
47
|
this.arrowUp?.removeAttribute('hidden')
|
39
48
|
this.arrowDown?.setAttribute('hidden', '')
|
49
|
+
this.triggerElement.setAttribute('aria-expanded', 'true')
|
40
50
|
|
41
51
|
for (const el of this.collapsibleElements) {
|
42
52
|
el.hidden = false
|
@@ -1,7 +1,14 @@
|
|
1
1
|
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
|
2
2
|
<%= render(Primer::OpenProject::FlexLayout.new) do |flex| %>
|
3
3
|
<%= flex.with_row(classes: "CollapsibleSection--triggerArea",
|
4
|
-
|
4
|
+
id: @title_id,
|
5
|
+
tabindex: 0,
|
6
|
+
role: "button",
|
7
|
+
data: {
|
8
|
+
action: "click:collapsible-section#toggle keydown:collapsible-section#toggleViaKeyboard",
|
9
|
+
target: "collapsible-section.triggerElement"
|
10
|
+
},
|
11
|
+
aria: { expanded: !@collapsed, controls: @content_id }) do %>
|
5
12
|
<%= render(Primer::OpenProject::FlexLayout.new(display: :flex, align_items: :center)) do |header| %>
|
6
13
|
<%= header.with_column do %>
|
7
14
|
<%= title %>
|
@@ -18,7 +25,12 @@
|
|
18
25
|
<% end %>
|
19
26
|
<% end %>
|
20
27
|
<% end %>
|
21
|
-
<%= flex.with_row(hidden: @collapsed,
|
28
|
+
<%= flex.with_row(hidden: @collapsed,
|
29
|
+
mt: 3,
|
30
|
+
role: "region",
|
31
|
+
id: @content_id,
|
32
|
+
data: { targets: "collapsible-section.collapsibleElements" },
|
33
|
+
aria: { labelledby: @title_id }) do %>
|
22
34
|
<%= collapsible_content %>
|
23
35
|
<% end %>
|
24
36
|
<% end %>
|
@@ -47,13 +47,17 @@ module Primer
|
|
47
47
|
Primer::BaseComponent.new(tag: :div, **system_arguments)
|
48
48
|
}
|
49
49
|
|
50
|
+
# @param id [String] The unique ID of the collapsible section.
|
50
51
|
# @param collapsed [Boolean] Whether the section is collapsed on initial render.
|
51
52
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
52
|
-
def initialize(collapsed: false, **system_arguments)
|
53
|
+
def initialize(id: self.class.generate_id, collapsed: false, **system_arguments)
|
54
|
+
@title_id = "#{id}-title"
|
55
|
+
@content_id = "#{id}-content"
|
53
56
|
@collapsed = collapsed
|
54
57
|
|
55
58
|
@system_arguments = deny_tag_argument(**system_arguments)
|
56
59
|
@system_arguments[:tag] = "collapsible-section"
|
60
|
+
@system_arguments[:id] = id
|
57
61
|
@system_arguments[:classes] = class_names(
|
58
62
|
@system_arguments[:classes],
|
59
63
|
"CollapsibleSection",
|
@@ -1,10 +1,15 @@
|
|
1
1
|
<%= render @dialog do |dialog| %>
|
2
|
+
<% unless header.present? %>
|
3
|
+
<% dialog.with_header(close_label: I18n.t("button_close")) %>
|
4
|
+
<% end %>
|
5
|
+
|
2
6
|
<% dialog.with_body do %>
|
3
7
|
<%= feedback_message %>
|
4
8
|
<% if additional_details.present? %>
|
5
9
|
<%= additional_details %>
|
6
10
|
<% end %>
|
7
11
|
<% end %>
|
12
|
+
|
8
13
|
<% dialog.with_footer do %>
|
9
14
|
<% if footer.present? %>
|
10
15
|
<%= footer %>
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
class FileTreeView
|
6
|
+
class DirectoryNode < TreeView::SubTreeNode
|
7
|
+
def initialize(icon_arguments: nil, expanded_icon_arguments: nil, collapsed_icon_arguments: nil, **system_arguments)
|
8
|
+
@expanded_icon_arguments = expanded_icon_arguments || icon_arguments || {}
|
9
|
+
@collapsed_icon_arguments = collapsed_icon_arguments || icon_arguments || {}
|
10
|
+
|
11
|
+
super(**system_arguments)
|
12
|
+
end
|
13
|
+
|
14
|
+
def with_file(**system_arguments, &block)
|
15
|
+
with_leaf(**system_arguments, component_klass: FileNode, &block)
|
16
|
+
end
|
17
|
+
|
18
|
+
def with_directory(**system_arguments, &block)
|
19
|
+
with_sub_tree(**system_arguments, component_klass: DirectoryNode, &block)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
class FileTreeView
|
6
|
+
class FileNode < TreeView::LeafNode
|
7
|
+
def initialize(icon_arguments: {}, **system_arguments)
|
8
|
+
@icon_arguments = icon_arguments
|
9
|
+
super(**system_arguments)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
class FileTreeView < TreeView
|
6
|
+
def with_file(**system_arguments, &block)
|
7
|
+
with_leaf(**system_arguments, component_klass: FileNode, &block)
|
8
|
+
end
|
9
|
+
|
10
|
+
def with_directory(**system_arguments, &block)
|
11
|
+
with_sub_tree(**system_arguments, component_klass: DirectoryNode, &block)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
@keyframes shimmer{0%{mask-position:200%}to{mask-position:0}}.SkeletonBox{animation:shimmer;background-color:var(--bgColor-muted);border-radius:var(--borderRadius-small);display:block;height:1rem}@media (prefers-reduced-motion:no-preference){.SkeletonBox{animation:shimmer;animation-duration:1s;animation-iteration-count:infinite;mask-image:linear-gradient(75deg,#000 30%,#000000a6 80%);mask-size:200%}}@media (forced-colors:active){.SkeletonBox{outline:1px solid #0000;outline-offset:-1px}}
|
@@ -0,0 +1 @@
|
|
1
|
+
{"version":3,"sources":["skeleton_box.pcss"],"names":[],"mappings":"AAAA,mBACE,GACE,kBACF,CAEA,GACE,eACF,CACF,CAEA,aAKE,iBAAkB,CAFlB,qCAAsC,CACtC,uCAAwC,CAHxC,aAAc,CACd,WAiBF,CAZE,8CAPF,aAUI,iBAAkB,CAClB,qBAAsB,CACtB,kCAAmC,CAJnC,wDAAqE,CACrE,cAUJ,CANE,CAEA,8BAfF,aAgBI,uBAA8B,CAC9B,mBAEJ,CADE","file":"skeleton_box.css","sourcesContent":["@keyframes shimmer {\n from {\n mask-position: 200%;\n }\n\n to {\n mask-position: 0%;\n }\n}\n\n.SkeletonBox {\n display: block;\n height: 1rem;\n background-color: var(--bgColor-muted);\n border-radius: var(--borderRadius-small);\n animation: shimmer;\n\n @media (prefers-reduced-motion: no-preference) {\n mask-image: linear-gradient(75deg, #000 30%, rgba(0, 0, 0, 0.65) 80%);\n mask-size: 200%;\n animation: shimmer;\n animation-duration: 1s;\n animation-iteration-count: infinite;\n }\n\n @media (forced-colors: active) {\n outline: 1px solid transparent;\n outline-offset: -1px;\n }\n}\n"]}
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render(Primer::BaseComponent.new(**@system_arguments)) %>
|
@@ -0,0 +1,30 @@
|
|
1
|
+
@keyframes shimmer {
|
2
|
+
from {
|
3
|
+
mask-position: 200%;
|
4
|
+
}
|
5
|
+
|
6
|
+
to {
|
7
|
+
mask-position: 0%;
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
.SkeletonBox {
|
12
|
+
display: block;
|
13
|
+
height: 1rem;
|
14
|
+
background-color: var(--bgColor-muted);
|
15
|
+
border-radius: var(--borderRadius-small);
|
16
|
+
animation: shimmer;
|
17
|
+
|
18
|
+
@media (prefers-reduced-motion: no-preference) {
|
19
|
+
mask-image: linear-gradient(75deg, #000 30%, rgba(0, 0, 0, 0.65) 80%);
|
20
|
+
mask-size: 200%;
|
21
|
+
animation: shimmer;
|
22
|
+
animation-duration: 1s;
|
23
|
+
animation-iteration-count: infinite;
|
24
|
+
}
|
25
|
+
|
26
|
+
@media (forced-colors: active) {
|
27
|
+
outline: 1px solid transparent;
|
28
|
+
outline-offset: -1px;
|
29
|
+
}
|
30
|
+
}
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
# A SkeletonBox provides a placeholder for non-text, non-Avatar elements (e.g., hero images)
|
6
|
+
# that are still loading. You can adjust width and height to match the content's dimensions.
|
7
|
+
class SkeletonBox < Primer::Component
|
8
|
+
# @param height [String] Any valid CSS height.
|
9
|
+
# @param width [String] Any valid CSS width.
|
10
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
11
|
+
def initialize(height: nil, width: nil, **system_arguments)
|
12
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
13
|
+
|
14
|
+
styles = []
|
15
|
+
styles << "width: #{width}" if width
|
16
|
+
styles << "height: #{height}" if height
|
17
|
+
|
18
|
+
@system_arguments[:tag] = :div
|
19
|
+
@system_arguments[:style] = styles.join("; ") if styles.present?
|
20
|
+
@system_arguments[:classes] = class_names(
|
21
|
+
@system_arguments.delete(:classes),
|
22
|
+
"SkeletonBox"
|
23
|
+
)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render(Primer::Beta::Octicon.new(**@system_arguments)) %>
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
class TreeView
|
6
|
+
# An icon for a `TreeView` node.
|
7
|
+
#
|
8
|
+
# This component is part of the <%= link_to_component(Primer::OpenProject::TreeView) %> component and should
|
9
|
+
# not be used directly.
|
10
|
+
class Icon < Primer::Component
|
11
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Beta::Octicon) %>.
|
12
|
+
def initialize(**system_arguments)
|
13
|
+
@system_arguments = system_arguments
|
14
|
+
@system_arguments[:focusable] = "false"
|
15
|
+
@system_arguments[:display] = :inline_block
|
16
|
+
@system_arguments[:overflow] = :visible
|
17
|
+
@system_arguments[:style] = "vertical-align: text-bottom;"
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
|
2
|
+
<% if expanded_icon? %>
|
3
|
+
<div data-target="tree-view-icon-pair.expandedIcon" <%= expanded? ? "" : "hidden" %>>
|
4
|
+
<%= expanded_icon %>
|
5
|
+
</div>
|
6
|
+
<% end %>
|
7
|
+
|
8
|
+
<% if collapsed_icon? %>
|
9
|
+
<div data-target="tree-view-icon-pair.collapsedIcon" <%= expanded? ? "hidden" : "" %>>
|
10
|
+
<%= collapsed_icon %>
|
11
|
+
</div>
|
12
|
+
<% end %>
|
13
|
+
<% end %>
|
@@ -0,0 +1,42 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
class TreeView
|
6
|
+
# A pair of icons for a `TreeView` sub-tree that displays distinct icons when the sub-tree is
|
7
|
+
# expanded and collapsed.
|
8
|
+
#
|
9
|
+
# This component is part of the <%= link_to_component(Primer::OpenProject::TreeView) %> component and should
|
10
|
+
# not be used directly.
|
11
|
+
class IconPair < Primer::Component
|
12
|
+
# The expanded icon.
|
13
|
+
#
|
14
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::Icon) %>.
|
15
|
+
renders_one :expanded_icon, lambda { |**system_arguments|
|
16
|
+
Icon.new(**system_arguments)
|
17
|
+
}
|
18
|
+
|
19
|
+
# The collapsed icon.
|
20
|
+
#
|
21
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::OpenProject::TreeView::Icon) %>.
|
22
|
+
renders_one :collapsed_icon, lambda { |**system_arguments|
|
23
|
+
Icon.new(**system_arguments)
|
24
|
+
}
|
25
|
+
|
26
|
+
# Whether or not this icon is expanded.
|
27
|
+
#
|
28
|
+
# @return [Boolean]
|
29
|
+
attr_reader :expanded
|
30
|
+
alias expanded? expanded
|
31
|
+
|
32
|
+
# @param expanded [Boolean] If true, the expanded icon is shown and the collapsed icon is hidden, etc.
|
33
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
34
|
+
def initialize(expanded: false, **system_arguments)
|
35
|
+
@expanded = expanded
|
36
|
+
@system_arguments = deny_tag_argument(**system_arguments)
|
37
|
+
@system_arguments[:tag] = :"tree-view-icon-pair"
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module OpenProject
|
5
|
+
class TreeView
|
6
|
+
# The leading action for `TreeView` nodes.
|
7
|
+
#
|
8
|
+
# This component is part of the <%= link_to_component(Primer::OpenProject::TreeView) %> component and should
|
9
|
+
# not be used directly.
|
10
|
+
class LeadingAction < Primer::Component
|
11
|
+
# @param action [ViewComponent::Base] A component or other renderable to use as the action button etc.
|
12
|
+
def initialize(action:)
|
13
|
+
@action = action
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
<%= render(@node) do |node| %>
|
2
|
+
<% if leading_action? %>
|
3
|
+
<% node.with_leading_action do %>
|
4
|
+
<%= leading_action %>
|
5
|
+
<% end %>
|
6
|
+
<% end %>
|
7
|
+
<% if leading_visual? %>
|
8
|
+
<% node.with_leading_visual do %>
|
9
|
+
<%= leading_visual %>
|
10
|
+
<% end %>
|
11
|
+
<% end %>
|
12
|
+
<% if trailing_visual? %>
|
13
|
+
<% node.with_trailing_visual do %>
|
14
|
+
<%= trailing_visual %>
|
15
|
+
<% end %>
|
16
|
+
<% end %>
|
17
|
+
<% node.with_text_content { @label } %>
|
18
|
+
<% end %>
|