openproject-primer_view_components 0.84.5 → 0.85.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 +6 -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/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/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/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 +6 -0
- data/static/constants.json +1 -1
- data/static/info_arch.json +66 -29
- data/static/previews.json +55 -29
- metadata +3 -2
|
@@ -154,8 +154,8 @@ let SelectPanelElement = class SelectPanelElement extends HTMLElement {
|
|
|
154
154
|
side: this.side,
|
|
155
155
|
anchorOffset: 4,
|
|
156
156
|
});
|
|
157
|
-
this.dialog.style.top = `${top}px`;
|
|
158
|
-
this.dialog.style.left = `${left}px`;
|
|
157
|
+
this.dialog.style.top = `${Math.round(top)}px`;
|
|
158
|
+
this.dialog.style.left = `${Math.round(left)}px`;
|
|
159
159
|
this.dialog.style.bottom = 'auto';
|
|
160
160
|
this.dialog.style.right = 'auto';
|
|
161
161
|
}
|
|
@@ -176,8 +176,8 @@ export class SelectPanelElement extends HTMLElement {
|
|
|
176
176
|
side: this.side,
|
|
177
177
|
anchorOffset: 4,
|
|
178
178
|
})
|
|
179
|
-
this.dialog.style.top = `${top}px`
|
|
180
|
-
this.dialog.style.left = `${left}px`
|
|
179
|
+
this.dialog.style.top = `${Math.round(top)}px`
|
|
180
|
+
this.dialog.style.left = `${Math.round(left)}px`
|
|
181
181
|
this.dialog.style.bottom = 'auto'
|
|
182
182
|
this.dialog.style.right = 'auto'
|
|
183
183
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
.SubHeader{align-items:
|
|
1
|
+
.SubHeader{align-items:baseline;display:grid;grid-template-areas:"left middle right" "bottom bottom bottom";grid-template-columns:auto 1fr auto;margin-bottom:var(--base-size-16)}.SubHeader-rightPane{align-items:center;column-gap:12px;display:flex;grid-area:right}.SubHeader-middlePane{grid-area:middle;text-align:center;white-space:nowrap}.SubHeader-bottomPane{grid-area:bottom}.SubHeader-leftPane{align-items:center;display:flex;flex-wrap:wrap;grid-area:left;row-gap:var(--base-size-16);width:100%}:is(.SubHeader-leftPane [class*=FormControl-input-width--]):not(.FormControl-input-width--auto){width:100vw}.SubHeader-filterContainer{display:flex;flex-basis:max-content;gap:8px;width:100%}.SubHeader-filterInput_hiddenClearButton+.FormControl-input-trailingAction{display:none}@media (max-width:767.98px){.SubHeader{grid-template-areas:"left right" "middle middle" "bottom bottom";grid-template-columns:1fr auto}.SubHeader--expandedSearch{grid-template-areas:"left left" "middle middle" "bottom bottom"}.SubHeader--expandedSearch .SubHeader-hiddenOnExpand{display:none!important}.SubHeader--emptyLeftPane{grid-template-areas:"middle middle right" "bottom bottom bottom";grid-template-columns:auto 1fr auto}.SubHeader--emptyLeftPane .SubHeader-middlePane{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.SubHeader-middlePane{text-align:left}.SubHeader-middlePane:has(>*){margin-top:var(--base-size-16)}}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
"name": "open_project/sub_header",
|
|
3
3
|
"selectors": [
|
|
4
4
|
".SubHeader",
|
|
5
|
-
".SubHeader--expandedSearch",
|
|
6
5
|
".SubHeader-rightPane",
|
|
7
6
|
".SubHeader-middlePane",
|
|
8
7
|
".SubHeader-bottomPane",
|
|
@@ -10,6 +9,8 @@
|
|
|
10
9
|
":is(.SubHeader-leftPane [class*=FormControl-input-width--]):not(.FormControl-input-width--auto)",
|
|
11
10
|
".SubHeader-filterContainer",
|
|
12
11
|
".SubHeader-filterInput_hiddenClearButton+.FormControl-input-trailingAction",
|
|
12
|
+
".SubHeader--expandedSearch",
|
|
13
|
+
".SubHeader--expandedSearch .SubHeader-hiddenOnExpand",
|
|
13
14
|
".SubHeader--emptyLeftPane",
|
|
14
15
|
".SubHeader--emptyLeftPane .SubHeader-middlePane",
|
|
15
16
|
".SubHeader-middlePane:has(>*)"
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["sub_header.pcss"],"names":[],"mappings":"AAEA,WAII,
|
|
1
|
+
{"version":3,"sources":["sub_header.pcss"],"names":[],"mappings":"AAEA,WAII,oBAAqB,CAHrB,YAAa,CACb,8DAA+D,CAC/D,mCAAoC,CAEpC,iCACJ,CAEA,qBAGI,kBAAmB,CACnB,eAAgB,CAFhB,YAAa,CADb,eAIJ,CAEA,sBACI,gBAAiB,CACjB,iBAAkB,CAClB,kBACJ,CAEA,sBACI,gBACJ,CAEA,oBAGI,kBAAmB,CADnB,YAAa,CAEb,cAAe,CAHf,cAAe,CAIf,2BAA4B,CAC5B,UASJ,CAJQ,gGACI,WACJ,CAIR,2BACI,YAAa,CACb,sBAAuB,CAEvB,OAAQ,CADR,UAEJ,CAEA,2EACE,YACF,CAEA,4BACI,WACI,gEAAiE,CACjE,8BACJ,CAEA,2BACI,+DACJ,CAEA,qDACI,sBACJ,CAEA,0BACI,gEAAiE,CACjE,mCACJ,CAEA,gDAGI,eAAgB,CADhB,sBAAuB,CADvB,kBAGJ,CAEA,sBACI,eACJ,CAEA,8BACI,8BACJ,CACJ","file":"sub_header.css","sourcesContent":["/* CSS for SubHeader */\n\n.SubHeader {\n display: grid;\n grid-template-areas: \"left middle right\" \"bottom bottom bottom\";\n grid-template-columns: auto 1fr auto;\n align-items: baseline;\n margin-bottom: var(--base-size-16);\n}\n\n.SubHeader-rightPane {\n grid-area: right;\n display: flex;\n align-items: center;\n column-gap: 12px;\n}\n\n.SubHeader-middlePane {\n grid-area: middle;\n text-align: center;\n white-space: nowrap;\n}\n\n.SubHeader-bottomPane {\n grid-area: bottom;\n}\n\n.SubHeader-leftPane {\n grid-area: left;\n display: flex;\n align-items: center;\n flex-wrap: wrap;\n row-gap: var(--base-size-16);\n width: 100%;\n\n /* Since the container is not full width (due to the grid around it)\n we want it to grow, and then be limited by the max-width of the \"FormControl-input-width--xy\" class */\n & [class*='FormControl-input-width--'] {\n &:not(.FormControl-input-width--auto) {\n width: 100vw;\n }\n }\n}\n\n.SubHeader-filterContainer {\n display: flex;\n flex-basis: max-content;\n width: 100%;\n gap: 8px;\n}\n\n.SubHeader-filterInput_hiddenClearButton + .FormControl-input-trailingAction {\n display: none;\n}\n\n@media (max-width: 767.98px) {\n .SubHeader {\n grid-template-areas: \"left right\" \"middle middle\" \"bottom bottom\";\n grid-template-columns: 1fr auto;\n }\n\n .SubHeader--expandedSearch {\n grid-template-areas: \"left left\" \"middle middle\" \"bottom bottom\";\n }\n\n .SubHeader--expandedSearch .SubHeader-hiddenOnExpand {\n display: none !important;\n }\n\n .SubHeader--emptyLeftPane {\n grid-template-areas: \"middle middle right\" \"bottom bottom bottom\";\n grid-template-columns: auto 1fr auto;\n }\n\n .SubHeader--emptyLeftPane .SubHeader-middlePane {\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n .SubHeader-middlePane {\n text-align: left;\n }\n\n .SubHeader-middlePane:has(> *) {\n margin-top: var(--base-size-16);\n }\n}\n"]}
|
|
@@ -2,16 +2,19 @@
|
|
|
2
2
|
<div class="SubHeader-leftPane">
|
|
3
3
|
<%= render @filter_container do %>
|
|
4
4
|
<%= filter_input %>
|
|
5
|
-
<%= render @
|
|
6
|
-
I18n.t("button_cancel")
|
|
7
|
-
end if @mobile_filter_cancel.present? %>
|
|
5
|
+
<%= render @collapsed_filter_cancel if @collapsed_filter_cancel.present? %>
|
|
8
6
|
<% end if filter_input.present? %>
|
|
9
7
|
|
|
10
|
-
<%= render @
|
|
8
|
+
<%= render @collapsed_filter_trigger if @collapsed_filter_trigger.present? %>
|
|
11
9
|
|
|
12
|
-
<%= render(
|
|
10
|
+
<%= render(Primer::BaseComponent.new(tag: :div, display: :flex)) do %>
|
|
11
|
+
<% quick_filters.each do |quick_filter| %>
|
|
12
|
+
<%= quick_filter %>
|
|
13
|
+
<% end %>
|
|
13
14
|
|
|
14
|
-
|
|
15
|
+
<%= render(@mobile_filter_button) if @mobile_filter_button.present? %>
|
|
16
|
+
<%= filter_button %>
|
|
17
|
+
<% end %>
|
|
15
18
|
|
|
16
19
|
<%= segmented_control %>
|
|
17
20
|
|
|
@@ -22,11 +25,11 @@
|
|
|
22
25
|
<% end %>
|
|
23
26
|
</div>
|
|
24
27
|
|
|
25
|
-
<div class="SubHeader-middlePane
|
|
28
|
+
<div class="SubHeader-middlePane SubHeader-hiddenOnExpand">
|
|
26
29
|
<%= text %>
|
|
27
30
|
</div>
|
|
28
31
|
|
|
29
|
-
<div class="SubHeader-rightPane
|
|
32
|
+
<div class="SubHeader-rightPane SubHeader-hiddenOnExpand">
|
|
30
33
|
<% actions.each do |action| %>
|
|
31
34
|
<%= action %>
|
|
32
35
|
<% end %>
|
|
@@ -4,14 +4,10 @@
|
|
|
4
4
|
display: grid;
|
|
5
5
|
grid-template-areas: "left middle right" "bottom bottom bottom";
|
|
6
6
|
grid-template-columns: auto 1fr auto;
|
|
7
|
-
align-items:
|
|
7
|
+
align-items: baseline;
|
|
8
8
|
margin-bottom: var(--base-size-16);
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
-
.SubHeader--expandedSearch {
|
|
12
|
-
grid-template-areas: "left left left" "bottom bottom bottom";
|
|
13
|
-
}
|
|
14
|
-
|
|
15
11
|
.SubHeader-rightPane {
|
|
16
12
|
grid-area: right;
|
|
17
13
|
display: flex;
|
|
@@ -22,6 +18,7 @@
|
|
|
22
18
|
.SubHeader-middlePane {
|
|
23
19
|
grid-area: middle;
|
|
24
20
|
text-align: center;
|
|
21
|
+
white-space: nowrap;
|
|
25
22
|
}
|
|
26
23
|
|
|
27
24
|
.SubHeader-bottomPane {
|
|
@@ -32,6 +29,8 @@
|
|
|
32
29
|
grid-area: left;
|
|
33
30
|
display: flex;
|
|
34
31
|
align-items: center;
|
|
32
|
+
flex-wrap: wrap;
|
|
33
|
+
row-gap: var(--base-size-16);
|
|
35
34
|
width: 100%;
|
|
36
35
|
|
|
37
36
|
/* Since the container is not full width (due to the grid around it)
|
|
@@ -54,12 +53,20 @@
|
|
|
54
53
|
display: none;
|
|
55
54
|
}
|
|
56
55
|
|
|
57
|
-
@media (max-width:
|
|
56
|
+
@media (max-width: 767.98px) {
|
|
58
57
|
.SubHeader {
|
|
59
58
|
grid-template-areas: "left right" "middle middle" "bottom bottom";
|
|
60
59
|
grid-template-columns: 1fr auto;
|
|
61
60
|
}
|
|
62
61
|
|
|
62
|
+
.SubHeader--expandedSearch {
|
|
63
|
+
grid-template-areas: "left left" "middle middle" "bottom bottom";
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.SubHeader--expandedSearch .SubHeader-hiddenOnExpand {
|
|
67
|
+
display: none !important;
|
|
68
|
+
}
|
|
69
|
+
|
|
63
70
|
.SubHeader--emptyLeftPane {
|
|
64
71
|
grid-template-areas: "middle middle right" "bottom bottom bottom";
|
|
65
72
|
grid-template-columns: auto 1fr auto;
|
|
@@ -76,6 +83,6 @@
|
|
|
76
83
|
}
|
|
77
84
|
|
|
78
85
|
.SubHeader-middlePane:has(> *) {
|
|
79
|
-
margin-top: var(--
|
|
86
|
+
margin-top: var(--base-size-16);
|
|
80
87
|
}
|
|
81
88
|
}
|
|
@@ -7,8 +7,8 @@ module Primer
|
|
|
7
7
|
class SubHeader < Primer::Component
|
|
8
8
|
status :open_project
|
|
9
9
|
|
|
10
|
-
HIDDEN_FILTER_TARGET_SELECTOR = "sub-header.hiddenItemsOnExpandedFilter"
|
|
11
10
|
SHOWN_FILTER_TARGET_SELECTOR = "sub-header.shownItemsOnExpandedFilter"
|
|
11
|
+
FILTER_EXPAND_BUTTON_TARGET_SELECTOR = "sub-header.filterExpandButton"
|
|
12
12
|
|
|
13
13
|
MOBILE_ACTIONS_DISPLAY = [:flex, :none].freeze
|
|
14
14
|
DESKTOP_ACTIONS_DISPLAY = [:none, :flex].freeze
|
|
@@ -101,18 +101,23 @@ module Primer
|
|
|
101
101
|
system_arguments[:data][:action] += " input:sub-header#toggleFilterInputClearButton focus:sub-header#toggleFilterInputClearButton"
|
|
102
102
|
end
|
|
103
103
|
|
|
104
|
-
|
|
105
|
-
display: [:inline_flex, :none],
|
|
106
|
-
aria: { label: label },
|
|
107
|
-
mr: 2,
|
|
108
|
-
"data-action": "click:sub-header#expandFilterInput",
|
|
109
|
-
"data-targets": HIDDEN_FILTER_TARGET_SELECTOR)
|
|
104
|
+
trigger_display = @collapsed_search ? :inline_flex : [:inline_flex, :none]
|
|
110
105
|
|
|
111
|
-
@
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
106
|
+
@collapsed_filter_trigger = Primer::Beta::IconButton.new(icon: system_arguments[:leading_visual][:icon],
|
|
107
|
+
display: trigger_display,
|
|
108
|
+
aria: { label: label },
|
|
109
|
+
mr: 2,
|
|
110
|
+
"data-action": "click:sub-header#expandFilterInput",
|
|
111
|
+
"data-targets": FILTER_EXPAND_BUTTON_TARGET_SELECTOR)
|
|
112
|
+
|
|
113
|
+
@collapsed_filter_cancel = Primer::Beta::IconButton.new(icon: :x,
|
|
114
|
+
"aria-label": I18n.t(:button_cancel),
|
|
115
|
+
scheme: :invisible,
|
|
116
|
+
display: :none,
|
|
117
|
+
data: {
|
|
118
|
+
targets: SHOWN_FILTER_TARGET_SELECTOR,
|
|
119
|
+
action: "click:sub-header#collapseFilterInput"
|
|
120
|
+
})
|
|
116
121
|
|
|
117
122
|
|
|
118
123
|
Primer::Alpha::TextField.new(name: name, label: label, **system_arguments)
|
|
@@ -165,6 +170,18 @@ module Primer
|
|
|
165
170
|
}
|
|
166
171
|
}
|
|
167
172
|
|
|
173
|
+
# Quick filters shown in the left pane next to the search bar (0–5 items).
|
|
174
|
+
# Hidden on mobile. Requires all_filters_button to be set when used.
|
|
175
|
+
# Supports ActionMenus, Buttons, IconButtons, SelectPanels, and SegmentedControls inside the block.
|
|
176
|
+
renders_many :quick_filters, lambda { |**kwargs|
|
|
177
|
+
deny_tag_argument(**kwargs)
|
|
178
|
+
kwargs[:tag] = :div
|
|
179
|
+
kwargs[:mr] ||= 2
|
|
180
|
+
kwargs[:display] = DESKTOP_ACTIONS_DISPLAY
|
|
181
|
+
|
|
182
|
+
Primer::BaseComponent.new(**kwargs)
|
|
183
|
+
}
|
|
184
|
+
|
|
168
185
|
renders_one :segmented_control, lambda { |**system_arguments, &block|
|
|
169
186
|
deny_tag_argument(**system_arguments)
|
|
170
187
|
system_arguments[:mr] ||= 2
|
|
@@ -182,6 +199,7 @@ module Primer
|
|
|
182
199
|
|
|
183
200
|
renders_one :text, lambda { |**system_arguments|
|
|
184
201
|
system_arguments[:font_weight] ||= :bold
|
|
202
|
+
system_arguments[:mx] ||= 2
|
|
185
203
|
|
|
186
204
|
Primer::Beta::Text.new(**system_arguments)
|
|
187
205
|
}
|
|
@@ -195,16 +213,18 @@ module Primer
|
|
|
195
213
|
Primer::BaseComponent.new(**system_arguments)
|
|
196
214
|
}
|
|
197
215
|
|
|
198
|
-
|
|
216
|
+
# @param collapsed_search [Boolean] When true, the search bar starts collapsed as an icon button on all screen sizes. Clicking expands it.
|
|
199
217
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
|
200
|
-
def initialize(**system_arguments)
|
|
218
|
+
def initialize(collapsed_search: false, **system_arguments)
|
|
219
|
+
@collapsed_search = collapsed_search
|
|
201
220
|
@system_arguments = system_arguments
|
|
202
221
|
@system_arguments[:tag] = :"sub-header"
|
|
203
222
|
|
|
223
|
+
filter_container_display = collapsed_search ? :none : DESKTOP_ACTIONS_DISPLAY
|
|
224
|
+
|
|
204
225
|
@filter_container = Primer::BaseComponent.new(tag: :div,
|
|
205
226
|
classes: "SubHeader-filterContainer",
|
|
206
|
-
display:
|
|
207
|
-
|
|
227
|
+
display: filter_container_display,
|
|
208
228
|
mr: 2,
|
|
209
229
|
data: { targets: SHOWN_FILTER_TARGET_SELECTOR })
|
|
210
230
|
|
|
@@ -215,21 +235,22 @@ module Primer
|
|
|
215
235
|
end
|
|
216
236
|
|
|
217
237
|
def before_render
|
|
238
|
+
if quick_filters.any? && filter_button.nil?
|
|
239
|
+
raise ArgumentError, "You must provide a filter_button when using quick_filters."
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
if quick_filters.size > 5
|
|
243
|
+
raise ArgumentError, "SubHeader supports a maximum of 5 quick_filters, got #{quick_filters.size}."
|
|
244
|
+
end
|
|
245
|
+
|
|
218
246
|
@system_arguments[:classes] = class_names(
|
|
219
247
|
@system_arguments[:classes],
|
|
220
|
-
"SubHeader--emptyLeftPane" => !segmented_control? && !filter_button && !filter_input
|
|
248
|
+
"SubHeader--emptyLeftPane" => !segmented_control? && !filter_button && !filter_input && quick_filters.empty?
|
|
221
249
|
)
|
|
222
250
|
end
|
|
223
251
|
|
|
224
252
|
def set_as_hidden_filter_target(system_arguments)
|
|
225
|
-
system_arguments[:
|
|
226
|
-
system_arguments[:data] = merge_data(
|
|
227
|
-
system_arguments, {
|
|
228
|
-
data: {
|
|
229
|
-
targets: HIDDEN_FILTER_TARGET_SELECTOR,
|
|
230
|
-
}
|
|
231
|
-
}
|
|
232
|
-
)
|
|
253
|
+
system_arguments[:classes] = class_names(system_arguments[:classes], "SubHeader-hiddenOnExpand")
|
|
233
254
|
system_arguments
|
|
234
255
|
end
|
|
235
256
|
end
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
declare class SubHeaderElement extends HTMLElement {
|
|
2
2
|
filterInput: HTMLInputElement;
|
|
3
|
-
hiddenItemsOnExpandedFilter: HTMLElement[];
|
|
4
3
|
shownItemsOnExpandedFilter: HTMLElement[];
|
|
4
|
+
filterExpandButton: HTMLElement[];
|
|
5
5
|
connectedCallback(): void;
|
|
6
6
|
setupFilterInputClearButton(): void;
|
|
7
7
|
toggleFilterInputClearButton(): void;
|
|
@@ -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
|
|
|
@@ -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
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
<%= render(Primer::OpenProject::SubHeader.new(collapsed_search: true)) do |component|
|
|
2
|
+
component.with_filter_input(name: "filter", label: "Filter")
|
|
3
|
+
|
|
4
|
+
component.with_filter_button(mobile_label: "All filters") do
|
|
5
|
+
"All filters"
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
component.with_quick_filter do
|
|
9
|
+
render(Primer::Alpha::SelectPanel.new(title: "Version",
|
|
10
|
+
select_variant: :single,
|
|
11
|
+
fetch_strategy: :local,
|
|
12
|
+
dynamic_label: true,
|
|
13
|
+
dynamic_label_prefix: "Version")) do |panel|
|
|
14
|
+
panel.with_show_button { "Version" }
|
|
15
|
+
panel.with_item(label: "1.0")
|
|
16
|
+
panel.with_item(label: "2.0")
|
|
17
|
+
panel.with_item(label: "2.1")
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
component.with_quick_filter do
|
|
22
|
+
render(Primer::Alpha::SelectPanel.new(title: "Assignee",
|
|
23
|
+
select_variant: :multiple,
|
|
24
|
+
fetch_strategy: :local,
|
|
25
|
+
dynamic_label: true,
|
|
26
|
+
dynamic_label_prefix: "Assignee")) do |panel|
|
|
27
|
+
panel.with_show_button { "Assignee" }
|
|
28
|
+
panel.with_avatar_item(username: "Alice", src: "https://avatars.githubusercontent.com/u/1?v=4")
|
|
29
|
+
panel.with_avatar_item(username: "Bob", src: "https://avatars.githubusercontent.com/u/2?v=4")
|
|
30
|
+
panel.with_avatar_item(username: "Carol", src: "https://avatars.githubusercontent.com/u/3?v=4")
|
|
31
|
+
panel.with_avatar_item(username: "Dave", src: "https://avatars.githubusercontent.com/u/4?v=4")
|
|
32
|
+
panel.with_avatar_item(username: "Eve", src: "https://avatars.githubusercontent.com/u/5?v=4")
|
|
33
|
+
panel.with_avatar_item(username: "Frank", src: "https://avatars.githubusercontent.com/u/6?v=4")
|
|
34
|
+
panel.with_avatar_item(username: "Grace", src: "https://avatars.githubusercontent.com/u/7?v=4")
|
|
35
|
+
panel.with_avatar_item(username: "Heidi", src: "https://avatars.githubusercontent.com/u/8?v=4")
|
|
36
|
+
panel.with_avatar_item(username: "Ivan", src: "https://avatars.githubusercontent.com/u/9?v=4")
|
|
37
|
+
panel.with_avatar_item(username: "Judy", src: "https://avatars.githubusercontent.com/u/10?v=4")
|
|
38
|
+
panel.with_footer(show_divider: true) do
|
|
39
|
+
render(Primer::Beta::Button.new(scheme: :primary)) { "Apply" }
|
|
40
|
+
end
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
component.with_action_button(leading_icon: :plus, label: "Create", scheme: :primary) do
|
|
45
|
+
"Create"
|
|
46
|
+
end
|
|
47
|
+
end %>
|