openproject-primer_view_components 0.84.5 → 0.86.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 +16 -0
- data/app/assets/javascripts/components/primer/open_project/sub_header_element.d.ts +1 -1
- 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_element.js +2 -2
- data/app/components/primer/alpha/select_panel_element.ts +2 -2
- data/app/components/primer/alpha/tree_view/leaf_node.html.erb +5 -0
- data/app/components/primer/alpha/tree_view/leaf_node.rb +18 -0
- data/app/components/primer/alpha/tree_view/node.html.erb +3 -0
- data/app/components/primer/alpha/tree_view/node.rb +10 -0
- data/app/components/primer/alpha/tree_view/sub_tree_node.html.erb +5 -0
- data/app/components/primer/alpha/tree_view/sub_tree_node.rb +18 -0
- data/app/components/primer/alpha/tree_view/trailing_action.html.erb +3 -0
- data/app/components/primer/alpha/tree_view/trailing_action.rb +18 -0
- data/app/components/primer/alpha/tree_view.css +1 -1
- data/app/components/primer/alpha/tree_view.css.json +4 -1
- data/app/components/primer/alpha/tree_view.css.map +1 -1
- data/app/components/primer/alpha/tree_view.pcss +22 -6
- data/app/components/primer/open_project/filterable_tree_view/sub_tree.rb +6 -6
- data/app/components/primer/open_project/filterable_tree_view.css +1 -0
- data/app/components/primer/open_project/filterable_tree_view.css.json +14 -0
- data/app/components/primer/open_project/filterable_tree_view.css.map +1 -0
- data/app/components/primer/open_project/filterable_tree_view.html.erb +26 -14
- data/app/components/primer/open_project/filterable_tree_view.js +294 -5
- data/app/components/primer/open_project/filterable_tree_view.pcss +57 -0
- data/app/components/primer/open_project/filterable_tree_view.rb +58 -10
- data/app/components/primer/open_project/filterable_tree_view.ts +316 -4
- data/app/components/primer/open_project/sub_header.css +1 -1
- data/app/components/primer/open_project/sub_header.css.json +2 -1
- data/app/components/primer/open_project/sub_header.css.map +1 -1
- data/app/components/primer/open_project/sub_header.html.erb +11 -8
- data/app/components/primer/open_project/sub_header.pcss +14 -7
- data/app/components/primer/open_project/sub_header.rb +46 -25
- data/app/components/primer/open_project/sub_header_element.d.ts +1 -1
- data/app/components/primer/open_project/sub_header_element.js +6 -6
- data/app/components/primer/open_project/sub_header_element.ts +5 -10
- data/app/components/primer/primer.pcss +1 -0
- data/app/controllers/primer/view_components/filterable_tree_view_items_controller.rb +192 -0
- data/app/views/primer/view_components/filterable_tree_view_items/_node.html.erb +38 -0
- data/app/views/primer/view_components/filterable_tree_view_items/async_form_tree.html.erb +9 -0
- data/app/views/primer/view_components/filterable_tree_view_items/index.html.erb +6 -0
- data/config/routes.rb +4 -0
- data/lib/primer/view_components/version.rb +2 -2
- data/previews/primer/alpha/select_panel_preview.rb +0 -27
- data/previews/primer/alpha/text_area_preview.rb +0 -1
- data/previews/primer/alpha/text_field_preview.rb +0 -1
- data/previews/primer/alpha/tree_view_preview/leaf_node_playground.html.erb +4 -0
- data/previews/primer/alpha/tree_view_preview.rb +3 -0
- data/previews/primer/open_project/filterable_tree_view_preview/async.html.erb +3 -0
- data/previews/primer/open_project/filterable_tree_view_preview/async_form_input.html.erb +9 -0
- data/previews/primer/open_project/filterable_tree_view_preview/link_nodes.html.erb +18 -0
- data/previews/primer/open_project/filterable_tree_view_preview.rb +23 -2
- data/previews/primer/open_project/sub_header_preview/quick_filters.html.erb +47 -0
- data/previews/primer/open_project/sub_header_preview.rb +23 -1
- data/static/arguments.json +28 -0
- data/static/audited_at.json +1 -0
- data/static/classes.json +9 -0
- data/static/constants.json +10 -1
- data/static/info_arch.json +189 -30
- data/static/previews.json +94 -29
- data/static/statuses.json +1 -0
- metadata +18 -10
|
@@ -23,17 +23,17 @@ let SubHeaderElement = class SubHeaderElement extends HTMLElement {
|
|
|
23
23
|
}
|
|
24
24
|
}
|
|
25
25
|
expandFilterInput() {
|
|
26
|
-
for (const item of this.hiddenItemsOnExpandedFilter) {
|
|
27
|
-
item.classList.add('d-none');
|
|
28
|
-
}
|
|
29
26
|
for (const item of this.shownItemsOnExpandedFilter) {
|
|
30
27
|
item.classList.remove('d-none');
|
|
31
28
|
}
|
|
29
|
+
for (const item of this.filterExpandButton) {
|
|
30
|
+
item.classList.add('d-none');
|
|
31
|
+
}
|
|
32
32
|
this.classList.add('SubHeader--expandedSearch');
|
|
33
33
|
this.filterInput.focus();
|
|
34
34
|
}
|
|
35
35
|
collapseFilterInput() {
|
|
36
|
-
for (const item of this.
|
|
36
|
+
for (const item of this.filterExpandButton) {
|
|
37
37
|
item.classList.remove('d-none');
|
|
38
38
|
}
|
|
39
39
|
for (const item of this.shownItemsOnExpandedFilter) {
|
|
@@ -63,10 +63,10 @@ __decorate([
|
|
|
63
63
|
], SubHeaderElement.prototype, "filterInput", void 0);
|
|
64
64
|
__decorate([
|
|
65
65
|
targets
|
|
66
|
-
], SubHeaderElement.prototype, "
|
|
66
|
+
], SubHeaderElement.prototype, "shownItemsOnExpandedFilter", void 0);
|
|
67
67
|
__decorate([
|
|
68
68
|
targets
|
|
69
|
-
], SubHeaderElement.prototype, "
|
|
69
|
+
], SubHeaderElement.prototype, "filterExpandButton", void 0);
|
|
70
70
|
SubHeaderElement = __decorate([
|
|
71
71
|
controller
|
|
72
72
|
], SubHeaderElement);
|
|
@@ -3,8 +3,8 @@ import {controller, target, targets} from '@github/catalyst'
|
|
|
3
3
|
@controller
|
|
4
4
|
class SubHeaderElement extends HTMLElement {
|
|
5
5
|
@target filterInput: HTMLInputElement
|
|
6
|
-
@targets hiddenItemsOnExpandedFilter: HTMLElement[]
|
|
7
6
|
@targets shownItemsOnExpandedFilter: HTMLElement[]
|
|
7
|
+
@targets filterExpandButton: HTMLElement[]
|
|
8
8
|
|
|
9
9
|
connectedCallback() {
|
|
10
10
|
this.setupFilterInputClearButton()
|
|
@@ -28,28 +28,23 @@ class SubHeaderElement extends HTMLElement {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
expandFilterInput() {
|
|
31
|
-
for (const item of this.hiddenItemsOnExpandedFilter) {
|
|
32
|
-
item.classList.add('d-none')
|
|
33
|
-
}
|
|
34
|
-
|
|
35
31
|
for (const item of this.shownItemsOnExpandedFilter) {
|
|
36
32
|
item.classList.remove('d-none')
|
|
37
33
|
}
|
|
38
|
-
|
|
34
|
+
for (const item of this.filterExpandButton) {
|
|
35
|
+
item.classList.add('d-none')
|
|
36
|
+
}
|
|
39
37
|
this.classList.add('SubHeader--expandedSearch')
|
|
40
|
-
|
|
41
38
|
this.filterInput.focus()
|
|
42
39
|
}
|
|
43
40
|
|
|
44
41
|
collapseFilterInput() {
|
|
45
|
-
for (const item of this.
|
|
42
|
+
for (const item of this.filterExpandButton) {
|
|
46
43
|
item.classList.remove('d-none')
|
|
47
44
|
}
|
|
48
|
-
|
|
49
45
|
for (const item of this.shownItemsOnExpandedFilter) {
|
|
50
46
|
item.classList.add('d-none')
|
|
51
47
|
}
|
|
52
|
-
|
|
53
48
|
this.classList.remove('SubHeader--expandedSearch')
|
|
54
49
|
}
|
|
55
50
|
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Primer
|
|
4
|
+
module ViewComponents
|
|
5
|
+
# :nodoc:
|
|
6
|
+
# :nocov:
|
|
7
|
+
class FilterableTreeViewItemsController < ApplicationController
|
|
8
|
+
# A node in the demo tree. Leaf nodes have no children.
|
|
9
|
+
TreeNode = Data.define(:id, :label, :children, :all_descendant_ids) do
|
|
10
|
+
def leaf?
|
|
11
|
+
children.nil? || children.empty?
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# Returns a filtered copy of this node. Leaf nodes are included if they match the query.
|
|
15
|
+
# Sub-tree nodes are included if they match OR any descendant matches. The all_descendant_ids
|
|
16
|
+
# field always reflects the ORIGINAL (unfiltered) descendant set, so clients can use it to
|
|
17
|
+
# determine which nodes to select when "include sub-items" is active on a filtered tree.
|
|
18
|
+
def filter(query)
|
|
19
|
+
return self if query.empty?
|
|
20
|
+
|
|
21
|
+
if leaf?
|
|
22
|
+
matches?(query) ? self : nil
|
|
23
|
+
else
|
|
24
|
+
filtered_children = children.filter_map { |child| child.filter(query) }
|
|
25
|
+
if matches?(query) || !filtered_children.empty?
|
|
26
|
+
self.class.new(
|
|
27
|
+
id: id,
|
|
28
|
+
label: label,
|
|
29
|
+
children: filtered_children,
|
|
30
|
+
all_descendant_ids: all_descendant_ids
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
def matches?(query)
|
|
39
|
+
label.downcase.include?(query.downcase)
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
# Build a leaf node
|
|
44
|
+
def self.leaf(id:, label:)
|
|
45
|
+
TreeNode.new(id: id, label: label, children: [], all_descendant_ids: [])
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
# Build a branch node, computing all_descendant_ids automatically
|
|
49
|
+
def self.branch(id:, label:, children:)
|
|
50
|
+
all_ids = children.flat_map { |c| [c.id] + c.all_descendant_ids }
|
|
51
|
+
TreeNode.new(id: id, label: label, children: children, all_descendant_ids: all_ids)
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
TREE = [
|
|
55
|
+
branch(
|
|
56
|
+
id: "hogwarts",
|
|
57
|
+
label: "Hogwarts School of Witchcraft and Wizardry",
|
|
58
|
+
children: [
|
|
59
|
+
branch(
|
|
60
|
+
id: "hogwarts-students",
|
|
61
|
+
label: "Students",
|
|
62
|
+
children: [
|
|
63
|
+
branch(
|
|
64
|
+
id: "gryffindor",
|
|
65
|
+
label: "Gryffindor",
|
|
66
|
+
children: [
|
|
67
|
+
leaf(id: "harry-potter", label: "Harry Potter"),
|
|
68
|
+
leaf(id: "ron-weasley", label: "Ron Weasley"),
|
|
69
|
+
leaf(id: "hermione-granger", label: "Hermione Granger"),
|
|
70
|
+
leaf(id: "neville-longbottom", label: "Neville Longbottom"),
|
|
71
|
+
leaf(id: "ginny-weasley", label: "Ginny Weasley")
|
|
72
|
+
]
|
|
73
|
+
),
|
|
74
|
+
branch(
|
|
75
|
+
id: "slytherin",
|
|
76
|
+
label: "Slytherin",
|
|
77
|
+
children: [
|
|
78
|
+
leaf(id: "draco-malfoy", label: "Draco Malfoy"),
|
|
79
|
+
leaf(id: "pansy-parkinson", label: "Pansy Parkinson"),
|
|
80
|
+
leaf(id: "blaise-zabini", label: "Blaise Zabini")
|
|
81
|
+
]
|
|
82
|
+
),
|
|
83
|
+
branch(
|
|
84
|
+
id: "ravenclaw",
|
|
85
|
+
label: "Ravenclaw",
|
|
86
|
+
children: [
|
|
87
|
+
leaf(id: "luna-lovegood", label: "Luna Lovegood"),
|
|
88
|
+
leaf(id: "cho-chang", label: "Cho Chang"),
|
|
89
|
+
leaf(id: "terry-boot", label: "Terry Boot")
|
|
90
|
+
]
|
|
91
|
+
),
|
|
92
|
+
branch(
|
|
93
|
+
id: "hufflepuff",
|
|
94
|
+
label: "Hufflepuff",
|
|
95
|
+
children: [
|
|
96
|
+
leaf(id: "cedric-diggory", label: "Cedric Diggory"),
|
|
97
|
+
leaf(id: "susan-bones", label: "Susan Bones"),
|
|
98
|
+
leaf(id: "hannah-abbott", label: "Hannah Abbott")
|
|
99
|
+
]
|
|
100
|
+
)
|
|
101
|
+
]
|
|
102
|
+
),
|
|
103
|
+
branch(
|
|
104
|
+
id: "hogwarts-teachers",
|
|
105
|
+
label: "Teachers",
|
|
106
|
+
children: [
|
|
107
|
+
leaf(id: "albus-dumbledore", label: "Albus Dumbledore"),
|
|
108
|
+
leaf(id: "minerva-mcgonagall", label: "Minerva McGonagall"),
|
|
109
|
+
leaf(id: "severus-snape", label: "Severus Snape"),
|
|
110
|
+
leaf(id: "rubeus-hagrid", label: "Rubeus Hagrid"),
|
|
111
|
+
leaf(id: "remus-lupin", label: "Remus Lupin"),
|
|
112
|
+
leaf(id: "sybill-trelawney", label: "Sybill Trelawney")
|
|
113
|
+
]
|
|
114
|
+
)
|
|
115
|
+
]
|
|
116
|
+
),
|
|
117
|
+
branch(
|
|
118
|
+
id: "beauxbatons",
|
|
119
|
+
label: "Beauxbatons Academy of Magic",
|
|
120
|
+
children: [
|
|
121
|
+
branch(
|
|
122
|
+
id: "beauxbatons-students",
|
|
123
|
+
label: "Students",
|
|
124
|
+
children: [
|
|
125
|
+
leaf(id: "fleur-delacour", label: "Fleur Delacour"),
|
|
126
|
+
leaf(id: "gabrielle-delacour", label: "Gabrielle Delacour"),
|
|
127
|
+
leaf(id: "cecile-fontaine", label: "Cécile Fontaine")
|
|
128
|
+
]
|
|
129
|
+
),
|
|
130
|
+
branch(
|
|
131
|
+
id: "beauxbatons-teachers",
|
|
132
|
+
label: "Teachers",
|
|
133
|
+
children: [
|
|
134
|
+
leaf(id: "olympe-maxime", label: "Olympe Maxime"),
|
|
135
|
+
leaf(id: "sylvie-beaumont", label: "Sylvie Beaumont")
|
|
136
|
+
]
|
|
137
|
+
)
|
|
138
|
+
]
|
|
139
|
+
),
|
|
140
|
+
branch(
|
|
141
|
+
id: "durmstrang",
|
|
142
|
+
label: "Durmstrang Institute",
|
|
143
|
+
children: [
|
|
144
|
+
branch(
|
|
145
|
+
id: "durmstrang-students",
|
|
146
|
+
label: "Students",
|
|
147
|
+
children: [
|
|
148
|
+
leaf(id: "viktor-krum", label: "Viktor Krum"),
|
|
149
|
+
leaf(id: "dmitri-poliakoff", label: "Dmitri Poliakoff"),
|
|
150
|
+
leaf(id: "gregor-tarasov", label: "Gregor Tarasov")
|
|
151
|
+
]
|
|
152
|
+
),
|
|
153
|
+
branch(
|
|
154
|
+
id: "durmstrang-teachers",
|
|
155
|
+
label: "Teachers",
|
|
156
|
+
children: [
|
|
157
|
+
leaf(id: "igor-karkaroff", label: "Igor Karkaroff"),
|
|
158
|
+
leaf(id: "fyodor-dolohov", label: "Fyodor Dolohov")
|
|
159
|
+
]
|
|
160
|
+
)
|
|
161
|
+
]
|
|
162
|
+
)
|
|
163
|
+
].freeze
|
|
164
|
+
|
|
165
|
+
def index
|
|
166
|
+
query = params[:query].to_s.strip
|
|
167
|
+
select_variant = (params[:select_variant].presence || "multiple").to_sym
|
|
168
|
+
nodes = TREE.filter_map { |node| node.filter(query) }
|
|
169
|
+
|
|
170
|
+
render locals: {
|
|
171
|
+
nodes: nodes,
|
|
172
|
+
query: query,
|
|
173
|
+
select_variant: select_variant
|
|
174
|
+
}
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def async_form_tree
|
|
178
|
+
query = params[:query].to_s.strip
|
|
179
|
+
name = params[:name].to_s.presence || "characters"
|
|
180
|
+
nodes = TREE.filter_map { |node| node.filter(query) }
|
|
181
|
+
builder = ActionView::Helpers::FormBuilder.new("", nil, view_context, {})
|
|
182
|
+
|
|
183
|
+
render locals: {
|
|
184
|
+
nodes: nodes,
|
|
185
|
+
query: query,
|
|
186
|
+
name: name,
|
|
187
|
+
builder: builder
|
|
188
|
+
}
|
|
189
|
+
end
|
|
190
|
+
end
|
|
191
|
+
end
|
|
192
|
+
end
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<% if node.leaf? %>
|
|
2
|
+
<% component.with_leaf(
|
|
3
|
+
label: node.label,
|
|
4
|
+
select_variant: select_variant,
|
|
5
|
+
data: { node_id: node.id }
|
|
6
|
+
) %>
|
|
7
|
+
<% else %>
|
|
8
|
+
<%
|
|
9
|
+
# At the top-level TreeView we must explicitly provide sub_tree_component_klass and
|
|
10
|
+
# select_strategy. At nested levels, FilterableTreeView::SubTree#with_sub_tree already
|
|
11
|
+
# passes both via super and would raise "keyword argument duplicated" if we passed them again.
|
|
12
|
+
sub_tree_opts = {}
|
|
13
|
+
if component.is_a?(Primer::Alpha::TreeView)
|
|
14
|
+
sub_tree_opts[:sub_tree_component_klass] = Primer::OpenProject::FilterableTreeView::SubTree
|
|
15
|
+
sub_tree_opts[:select_strategy] = :self
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# When a filter query is active, every sub-tree in the result is either a match or an ancestor
|
|
19
|
+
# of a match – either way it should be expanded so the user sees the results immediately.
|
|
20
|
+
sub_tree_opts[:expanded] = true if query.present?
|
|
21
|
+
|
|
22
|
+
hierarchy_only = query.present? && !node.label.downcase.include?(query.downcase)
|
|
23
|
+
%>
|
|
24
|
+
<% component.with_sub_tree(
|
|
25
|
+
label: node.label,
|
|
26
|
+
select_variant: select_variant,
|
|
27
|
+
**sub_tree_opts,
|
|
28
|
+
data: {
|
|
29
|
+
node_id: node.id,
|
|
30
|
+
hierarchy_only: (hierarchy_only ? true : nil)
|
|
31
|
+
}
|
|
32
|
+
) do |sub| %>
|
|
33
|
+
<% node.children.each do |child| %>
|
|
34
|
+
<%= render partial: "primer/view_components/filterable_tree_view_items/node",
|
|
35
|
+
locals: { component: sub, node: child, query: query, select_variant: select_variant } %>
|
|
36
|
+
<% end %>
|
|
37
|
+
<% end %>
|
|
38
|
+
<% end %>
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<%= render(Primer::Alpha::TreeView.new(
|
|
2
|
+
data: { target: "filterable-tree-view.treeViewList" },
|
|
3
|
+
form_arguments: { builder: builder, name: name }
|
|
4
|
+
)) do |tree| %>
|
|
5
|
+
<% nodes.each do |node| %>
|
|
6
|
+
<%= render partial: "primer/view_components/filterable_tree_view_items/node",
|
|
7
|
+
locals: { component: tree, node: node, query: query, select_variant: :multiple } %>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% end %>
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
<%= render(Primer::Alpha::TreeView.new(data: { target: "filterable-tree-view.treeViewList" })) do |tree| %>
|
|
2
|
+
<% nodes.each do |node| %>
|
|
3
|
+
<%= render partial: "primer/view_components/filterable_tree_view_items/node",
|
|
4
|
+
locals: { component: tree, node: node, query: query, select_variant: select_variant } %>
|
|
5
|
+
<% end %>
|
|
6
|
+
<% end %>
|
data/config/routes.rb
CHANGED
|
@@ -12,6 +12,10 @@ Primer::ViewComponents::Engine.routes.draw do
|
|
|
12
12
|
resources :tree_view_items, only: [:index]
|
|
13
13
|
get "/tree_view_items/async_alpha", to: "tree_view_items#async_alpha", as: :tree_view_items_async_alpha
|
|
14
14
|
|
|
15
|
+
resources :filterable_tree_view_items, only: [:index]
|
|
16
|
+
get "/filterable_tree_view_items/tree", to: "filterable_tree_view_items#index", as: :filterable_tree_view_items_tree
|
|
17
|
+
get "/filterable_tree_view_items/async_form_tree", to: "filterable_tree_view_items#async_form_tree", as: :filterable_tree_view_items_async_form_tree
|
|
18
|
+
|
|
15
19
|
# generic form submission path
|
|
16
20
|
post "/form_handler", to: "form_handler#form_action", as: :generic_form_submission
|
|
17
21
|
|
|
@@ -54,7 +54,6 @@ module Primer
|
|
|
54
54
|
|
|
55
55
|
# @label Default
|
|
56
56
|
#
|
|
57
|
-
# @snapshot interactive
|
|
58
57
|
# @param open_on_load toggle
|
|
59
58
|
# @param show_filter toggle
|
|
60
59
|
def default(open_on_load: false, show_filter: true)
|
|
@@ -66,7 +65,6 @@ module Primer
|
|
|
66
65
|
|
|
67
66
|
# @label Local fetch
|
|
68
67
|
#
|
|
69
|
-
# @snapshot interactive
|
|
70
68
|
# @param open_on_load toggle
|
|
71
69
|
# @param show_filter toggle
|
|
72
70
|
def local_fetch(open_on_load: false, show_filter: true)
|
|
@@ -75,7 +73,6 @@ module Primer
|
|
|
75
73
|
|
|
76
74
|
# @label Eventually local fetch
|
|
77
75
|
#
|
|
78
|
-
# @snapshot interactive
|
|
79
76
|
# @param open_on_load toggle
|
|
80
77
|
# @param show_filter toggle
|
|
81
78
|
def eventually_local_fetch(open_on_load: false, show_filter: true)
|
|
@@ -84,7 +81,6 @@ module Primer
|
|
|
84
81
|
|
|
85
82
|
# @label Remote fetch
|
|
86
83
|
#
|
|
87
|
-
# @snapshot interactive
|
|
88
84
|
# @param open_on_load toggle
|
|
89
85
|
# @param selected_items text
|
|
90
86
|
def remote_fetch(open_on_load: false, selected_items: "Phaser")
|
|
@@ -93,7 +89,6 @@ module Primer
|
|
|
93
89
|
|
|
94
90
|
# @label Custom loading label
|
|
95
91
|
#
|
|
96
|
-
# @snapshot interactive
|
|
97
92
|
# @param open_on_load toggle
|
|
98
93
|
# @param selected_items text
|
|
99
94
|
def custom_loading_label(open_on_load: false, selected_items: "Phaser")
|
|
@@ -102,7 +97,6 @@ module Primer
|
|
|
102
97
|
|
|
103
98
|
# @label Custom loading description
|
|
104
99
|
#
|
|
105
|
-
# @snapshot interactive
|
|
106
100
|
# @param open_on_load toggle
|
|
107
101
|
# @param selected_items text
|
|
108
102
|
def custom_loading_description(open_on_load: false, selected_items: "Phaser")
|
|
@@ -111,7 +105,6 @@ module Primer
|
|
|
111
105
|
|
|
112
106
|
# @label Local fetch (no results)
|
|
113
107
|
#
|
|
114
|
-
# @snapshot interactive
|
|
115
108
|
# @param open_on_load toggle
|
|
116
109
|
def local_fetch_no_results(open_on_load: false)
|
|
117
110
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -119,7 +112,6 @@ module Primer
|
|
|
119
112
|
|
|
120
113
|
# @label Eventually local fetch (no results)
|
|
121
114
|
#
|
|
122
|
-
# @snapshot interactive
|
|
123
115
|
# @param open_on_load toggle
|
|
124
116
|
def eventually_local_fetch_no_results(open_on_load: false)
|
|
125
117
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -127,7 +119,6 @@ module Primer
|
|
|
127
119
|
|
|
128
120
|
# @label Remote fetch (no results)
|
|
129
121
|
#
|
|
130
|
-
# @snapshot interactive
|
|
131
122
|
# @param open_on_load toggle
|
|
132
123
|
def remote_fetch_no_results(open_on_load: false)
|
|
133
124
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -135,7 +126,6 @@ module Primer
|
|
|
135
126
|
|
|
136
127
|
# @label Single select
|
|
137
128
|
#
|
|
138
|
-
# @snapshot interactive
|
|
139
129
|
# @param dynamic_label toggle
|
|
140
130
|
# @param open_on_load toggle
|
|
141
131
|
def single_select(dynamic_label: false, open_on_load: false)
|
|
@@ -144,7 +134,6 @@ module Primer
|
|
|
144
134
|
|
|
145
135
|
# @label Multiselect
|
|
146
136
|
#
|
|
147
|
-
# @snapshot interactive
|
|
148
137
|
# @param open_on_load toggle
|
|
149
138
|
def multiselect(open_on_load: false)
|
|
150
139
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -154,7 +143,6 @@ module Primer
|
|
|
154
143
|
|
|
155
144
|
# @label With dynamic label
|
|
156
145
|
#
|
|
157
|
-
# @snapshot interactive
|
|
158
146
|
# @param open_on_load toggle
|
|
159
147
|
def with_dynamic_label(open_on_load: false)
|
|
160
148
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -162,7 +150,6 @@ module Primer
|
|
|
162
150
|
|
|
163
151
|
# @label With dynamic label and aria prefix
|
|
164
152
|
#
|
|
165
|
-
# @snapshot interactive
|
|
166
153
|
# @param open_on_load toggle
|
|
167
154
|
def with_dynamic_label_and_aria_prefix(open_on_load: false)
|
|
168
155
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -172,7 +159,6 @@ module Primer
|
|
|
172
159
|
|
|
173
160
|
# @label Footer buttons
|
|
174
161
|
#
|
|
175
|
-
# @snapshot interactive
|
|
176
162
|
# @param open_on_load toggle
|
|
177
163
|
def footer_buttons(open_on_load: false)
|
|
178
164
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -180,7 +166,6 @@ module Primer
|
|
|
180
166
|
|
|
181
167
|
# @label With avatar items
|
|
182
168
|
#
|
|
183
|
-
# @snapshot interactive
|
|
184
169
|
# @param open_on_load toggle
|
|
185
170
|
def with_avatar_items(open_on_load: false)
|
|
186
171
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -188,7 +173,6 @@ module Primer
|
|
|
188
173
|
|
|
189
174
|
# @label SelectPanel with Primer::IconButton
|
|
190
175
|
#
|
|
191
|
-
# @snapshot interactive
|
|
192
176
|
# @param open_on_load toggle
|
|
193
177
|
def select_panel_with_icon_button(open_on_load: false)
|
|
194
178
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -198,7 +182,6 @@ module Primer
|
|
|
198
182
|
|
|
199
183
|
# @label With leading icons
|
|
200
184
|
#
|
|
201
|
-
# @snapshot interactive
|
|
202
185
|
# @param open_on_load toggle
|
|
203
186
|
def with_leading_icons(open_on_load: false)
|
|
204
187
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -206,7 +189,6 @@ module Primer
|
|
|
206
189
|
|
|
207
190
|
# @label With trailing icons
|
|
208
191
|
#
|
|
209
|
-
# @snapshot interactive
|
|
210
192
|
# @param open_on_load toggle
|
|
211
193
|
def with_trailing_icons(open_on_load: false)
|
|
212
194
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -216,7 +198,6 @@ module Primer
|
|
|
216
198
|
|
|
217
199
|
# @label With subtitle
|
|
218
200
|
#
|
|
219
|
-
# @snapshot interactive
|
|
220
201
|
# @param open_on_load toggle
|
|
221
202
|
def with_subtitle(open_on_load: false)
|
|
222
203
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -224,7 +205,6 @@ module Primer
|
|
|
224
205
|
|
|
225
206
|
# @label Remote fetch initial failure
|
|
226
207
|
#
|
|
227
|
-
# @snapshot interactive
|
|
228
208
|
# @param open_on_load toggle
|
|
229
209
|
def remote_fetch_initial_failure(open_on_load: false)
|
|
230
210
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -232,7 +212,6 @@ module Primer
|
|
|
232
212
|
|
|
233
213
|
# @label Remote fetch filter failure
|
|
234
214
|
#
|
|
235
|
-
# @snapshot interactive
|
|
236
215
|
# @param open_on_load toggle
|
|
237
216
|
# @param banner_scheme [Symbol] select [danger, warning]
|
|
238
217
|
# @param show_results toggle
|
|
@@ -253,7 +232,6 @@ module Primer
|
|
|
253
232
|
|
|
254
233
|
# @label Eventually local fetch initial failure
|
|
255
234
|
#
|
|
256
|
-
# @snapshot interactive
|
|
257
235
|
# @param open_on_load toggle
|
|
258
236
|
def eventually_local_fetch_initial_failure(open_on_load: false)
|
|
259
237
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -261,7 +239,6 @@ module Primer
|
|
|
261
239
|
|
|
262
240
|
# @label Single-select form
|
|
263
241
|
#
|
|
264
|
-
# @snapshot interactive
|
|
265
242
|
# @param open_on_load toggle
|
|
266
243
|
def single_select_form(open_on_load: false, route_format: :html)
|
|
267
244
|
render_with_template(locals: { open_on_load: open_on_load, route_format: route_format })
|
|
@@ -269,7 +246,6 @@ module Primer
|
|
|
269
246
|
|
|
270
247
|
# @label Remote fetch form
|
|
271
248
|
#
|
|
272
|
-
# @snapshot interactive
|
|
273
249
|
# @param open_on_load toggle
|
|
274
250
|
# @param selected_items text
|
|
275
251
|
def remote_fetch_form(open_on_load: false, selected_items: "Phaser", route_format: :html)
|
|
@@ -278,7 +254,6 @@ module Primer
|
|
|
278
254
|
|
|
279
255
|
# @label Multi-select form
|
|
280
256
|
#
|
|
281
|
-
# @snapshot interactive
|
|
282
257
|
# @param open_on_load toggle
|
|
283
258
|
def multiselect_form(open_on_load: false, route_format: :html)
|
|
284
259
|
render_with_template(locals: { open_on_load: open_on_load, route_format: route_format })
|
|
@@ -286,7 +261,6 @@ module Primer
|
|
|
286
261
|
|
|
287
262
|
# @label List of links
|
|
288
263
|
#
|
|
289
|
-
# @snapshot interactive
|
|
290
264
|
# @param open_on_load toggle
|
|
291
265
|
def list_of_links(open_on_load: false)
|
|
292
266
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -294,7 +268,6 @@ module Primer
|
|
|
294
268
|
|
|
295
269
|
# @label No values
|
|
296
270
|
#
|
|
297
|
-
# @snapshot interactive
|
|
298
271
|
# @param open_on_load toggle
|
|
299
272
|
def no_values(open_on_load: false)
|
|
300
273
|
render_with_template(locals: { open_on_load: open_on_load })
|
|
@@ -107,7 +107,6 @@ module Primer
|
|
|
107
107
|
end
|
|
108
108
|
|
|
109
109
|
# @label With character limit, over limit
|
|
110
|
-
# @snapshot interactive
|
|
111
110
|
def with_character_limit_over_limit
|
|
112
111
|
render(Primer::Alpha::TextArea.new(id: "my-text-area-with-character-limit-over-limit", name: "my-text-area-with-character-limit-over-limit", character_limit: 10, label: "Tell me about yourself", value: "This text is definitely over the limit."))
|
|
113
112
|
end
|
|
@@ -236,7 +236,6 @@ module Primer
|
|
|
236
236
|
end
|
|
237
237
|
|
|
238
238
|
# @label With character limit, over limit
|
|
239
|
-
# @snapshot interactive
|
|
240
239
|
def with_character_limit_over_limit
|
|
241
240
|
render(Primer::Alpha::TextField.new(character_limit: 10, name: "my-text-field-19", label: "Tell me about yourself", value: "This text is definitely over the limit."))
|
|
242
241
|
end
|
|
@@ -11,5 +11,9 @@
|
|
|
11
11
|
<% if leading_action_icon && leading_action_icon != :none %>
|
|
12
12
|
<% node.with_leading_action_button(icon: leading_action_icon, aria: { label: "Leading action icon" }) %>
|
|
13
13
|
<% end %>
|
|
14
|
+
|
|
15
|
+
<% if trailing_action_icon && trailing_action_icon != :none %>
|
|
16
|
+
<% node.with_trailing_action_button(icon: trailing_action_icon, aria: { label: "Trailing action icon" }) %>
|
|
17
|
+
<% end %>
|
|
14
18
|
<% end %>
|
|
15
19
|
<% end %>
|
|
@@ -126,6 +126,7 @@ module Primer
|
|
|
126
126
|
# @param leading_visual_icon [Symbol] octicon
|
|
127
127
|
# @param leading_action_icon [Symbol] octicon
|
|
128
128
|
# @param trailing_visual_icon [Symbol] octicon
|
|
129
|
+
# @param trailing_action_icon [Symbol] octicon
|
|
129
130
|
# @param select_variant [Symbol] select [multiple, single, none]
|
|
130
131
|
# @param disabled [Boolean] toggle
|
|
131
132
|
def leaf_node_playground(
|
|
@@ -133,6 +134,7 @@ module Primer
|
|
|
133
134
|
leading_visual_icon: nil,
|
|
134
135
|
leading_action_icon: nil,
|
|
135
136
|
trailing_visual_icon: nil,
|
|
137
|
+
trailing_action_icon: nil,
|
|
136
138
|
select_variant: Primer::Alpha::TreeView::Node::DEFAULT_SELECT_VARIANT,
|
|
137
139
|
disabled: false
|
|
138
140
|
)
|
|
@@ -141,6 +143,7 @@ module Primer
|
|
|
141
143
|
leading_visual_icon: leading_visual_icon,
|
|
142
144
|
leading_action_icon: leading_action_icon,
|
|
143
145
|
trailing_visual_icon: trailing_visual_icon,
|
|
146
|
+
trailing_action_icon: trailing_action_icon,
|
|
144
147
|
select_variant: select_variant.to_sym,
|
|
145
148
|
disabled: disabled
|
|
146
149
|
})
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<%= form_with(url: primer_view_components.generic_form_submission_path(format: :json)) do |f| %>
|
|
2
|
+
<%= render(Primer::Alpha::Stack.new) do %>
|
|
3
|
+
<%= render(Primer::OpenProject::FilterableTreeView.new(
|
|
4
|
+
src: primer_view_components.filterable_tree_view_items_async_form_tree_path(name: "characters"),
|
|
5
|
+
form_arguments: { builder: f, name: "characters" }
|
|
6
|
+
)) %>
|
|
7
|
+
<%= render(Primer::Alpha::SubmitButton.new(name: :submit, scheme: :primary, label: "Submit")) %>
|
|
8
|
+
<% end %>
|
|
9
|
+
<% end %>
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
<%= render(Primer::OpenProject::FilterableTreeView.new(
|
|
2
|
+
tree_view_arguments: { node_variant: :anchor },
|
|
3
|
+
filter_mode_control_arguments: { hidden: true }
|
|
4
|
+
)) do |tree| %>
|
|
5
|
+
<% tree.with_sub_tree(label: "Cloud Services", select_variant: :none, expanded: expanded, href: "https://en.wikipedia.org/wiki/Cloud_computing", target: "_blank") do |cloud| %>
|
|
6
|
+
<% cloud.with_leaf(label: "OpenProject", select_variant: :none, href: "https://www.openproject.org", target: "_blank") do |node| %>
|
|
7
|
+
<% node.with_trailing_visual_icon(icon: :"link-external") %>
|
|
8
|
+
<% end %>
|
|
9
|
+
|
|
10
|
+
<% cloud.with_leaf(label: "Hetzner", select_variant: :none, href: "https://www.hetzner.com", target: "_blank") do |node| %>
|
|
11
|
+
<% node.with_trailing_visual_icon(icon: :"link-external") %>
|
|
12
|
+
<% end %>
|
|
13
|
+
<% end %>
|
|
14
|
+
|
|
15
|
+
<% tree.with_leaf(label: "GitHub", select_variant: :none, href: "https://github.com", target: "_blank") do |node| %>
|
|
16
|
+
<% node.with_trailing_visual_icon(icon: :"link-external") %>
|
|
17
|
+
<% end %>
|
|
18
|
+
<% end %>
|