openproject-primer_view_components 0.11.0 → 0.13.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +110 -0
- data/app/assets/javascripts/app/components/primer/alpha/tool_tip.d.ts +1 -0
- data/app/assets/javascripts/app/components/primer/primer.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/action_bar/item.rb +7 -4
- data/app/components/primer/alpha/action_bar.rb +2 -2
- data/app/components/primer/alpha/action_bar_element.js +9 -4
- data/app/components/primer/alpha/action_bar_element.ts +9 -2
- data/app/components/primer/alpha/action_list/form_wrapper.html.erb +4 -2
- data/app/components/primer/alpha/action_list/form_wrapper.rb +20 -9
- data/app/components/primer/alpha/action_menu/action_menu_element.js +162 -86
- data/app/components/primer/alpha/action_menu/action_menu_element.ts +197 -82
- data/app/components/primer/alpha/action_menu/list.rb +0 -2
- data/app/components/primer/alpha/action_menu.rb +120 -3
- data/app/components/primer/alpha/check_box_group.rb +2 -0
- data/app/components/primer/alpha/dialog/header.rb +12 -0
- data/app/components/primer/alpha/dialog.rb +1 -1
- data/app/components/primer/alpha/modal_dialog.js +10 -13
- data/app/components/primer/alpha/modal_dialog.ts +10 -13
- data/app/components/primer/alpha/nav_list/divider.rb +2 -5
- data/app/components/primer/alpha/nav_list/group.rb +2 -98
- data/app/components/primer/alpha/nav_list/heading.rb +2 -27
- data/app/components/primer/alpha/nav_list/item.rb +2 -147
- data/app/components/primer/alpha/nav_list.rb +2 -205
- data/app/components/primer/alpha/overlay.css +1 -1
- data/app/components/primer/alpha/overlay.css.map +1 -1
- data/app/components/primer/alpha/overlay.pcss +1 -7
- data/app/components/primer/alpha/overlay.rb +6 -4
- data/app/components/primer/alpha/radio_button_group.rb +2 -0
- data/app/components/primer/alpha/segmented_control/item.html.erb +1 -8
- data/app/components/primer/alpha/segmented_control/item.rb +38 -4
- data/app/components/primer/alpha/segmented_control.css +1 -1
- data/app/components/primer/alpha/segmented_control.css.json +14 -13
- data/app/components/primer/alpha/segmented_control.css.map +1 -1
- data/app/components/primer/alpha/segmented_control.pcss +75 -66
- data/app/components/primer/alpha/segmented_control.rb +10 -0
- data/app/components/primer/alpha/text_field.css +1 -1
- data/app/components/primer/alpha/text_field.css.json +4 -1
- data/app/components/primer/alpha/text_field.css.map +1 -1
- data/app/components/primer/alpha/text_field.pcss +18 -3
- data/app/components/primer/alpha/tool_tip.d.ts +1 -0
- data/app/components/primer/alpha/tool_tip.js +26 -93
- data/app/components/primer/alpha/tool_tip.ts +25 -91
- data/app/components/primer/alpha/tooltip.rb +3 -1
- data/app/components/primer/beta/base_button.rb +4 -0
- data/app/components/primer/beta/button.css +1 -1
- data/app/components/primer/beta/button.css.json +2 -0
- data/app/components/primer/beta/button.css.map +1 -1
- data/app/components/primer/beta/button.pcss +17 -5
- data/app/components/primer/beta/icon_button.html.erb +1 -1
- data/app/components/primer/beta/icon_button.rb +8 -1
- data/app/components/primer/beta/link.css +1 -1
- data/app/components/primer/beta/link.css.json +1 -0
- data/app/components/primer/beta/link.css.map +1 -1
- data/app/components/primer/beta/link.pcss +5 -0
- data/app/components/primer/beta/link.rb +2 -2
- data/app/components/primer/beta/nav_list/divider.rb +14 -0
- data/app/components/primer/beta/nav_list/group.rb +107 -0
- data/app/components/primer/beta/nav_list/heading.rb +36 -0
- data/app/components/primer/beta/nav_list/item.rb +156 -0
- data/app/components/primer/beta/nav_list.rb +212 -0
- data/app/components/primer/focus_group.js +30 -4
- data/app/components/primer/focus_group.ts +29 -2
- data/app/components/primer/open_project/flex_layout.html.erb +23 -0
- data/app/components/primer/open_project/flex_layout.rb +52 -0
- data/app/components/primer/open_project/grid_layout/area.rb +38 -0
- data/app/components/primer/open_project/grid_layout.html.erb +11 -0
- data/app/components/primer/open_project/grid_layout.rb +34 -0
- data/app/components/primer/open_project/page_header.css +1 -1
- data/app/components/primer/open_project/page_header.css.map +1 -1
- data/app/components/primer/open_project/page_header.pcss +4 -0
- data/app/components/primer/primer.d.ts +1 -1
- data/app/components/primer/primer.js +1 -1
- data/app/components/primer/primer.ts +1 -1
- data/app/helpers/primer/form_helper.rb +10 -0
- data/lib/primer/accessibility.rb +3 -1
- data/lib/primer/deprecations.yml +20 -0
- data/lib/primer/forms/check_box_group.html.erb +3 -0
- data/lib/primer/forms/dsl/check_box_group_input.rb +1 -5
- data/lib/primer/forms/dsl/check_box_input.rb +5 -0
- data/lib/primer/forms/dsl/radio_button_input.rb +5 -0
- data/lib/primer/forms/form_control.html.erb +1 -4
- data/lib/primer/forms/radio_button_group.html.erb +3 -0
- data/lib/primer/forms/utils.rb +2 -0
- data/lib/primer/forms/validation_message.html.erb +4 -0
- data/lib/primer/forms/validation_message.rb +14 -0
- data/lib/primer/forms.rb +16 -0
- data/lib/primer/static/generate_info_arch.rb +86 -5
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/primer/yard/component_manifest.rb +4 -0
- data/previews/primer/alpha/action_menu_preview/single_select_form_items.html.erb +31 -0
- data/previews/primer/alpha/action_menu_preview/with_actions.html.erb +6 -5
- data/previews/primer/alpha/action_menu_preview.rb +10 -1
- data/previews/primer/alpha/check_box_group_preview.rb +13 -0
- data/previews/primer/alpha/check_box_preview.rb +1 -0
- data/previews/primer/alpha/dialog_preview/autofocus_element.html.erb +8 -0
- data/previews/primer/alpha/dialog_preview/with_header.html.erb +5 -0
- data/previews/primer/alpha/dialog_preview.rb +22 -0
- data/previews/primer/alpha/overlay_preview.rb +1 -1
- data/previews/primer/alpha/radio_button_group_preview.rb +13 -0
- data/previews/primer/alpha/radio_button_preview.rb +2 -1
- data/previews/primer/alpha/segmented_control_preview.rb +35 -0
- data/previews/primer/alpha/text_field_preview/input_group_leading_action_menu.html.erb +21 -0
- data/previews/primer/alpha/text_field_preview/input_group_leading_button.html.erb +18 -0
- data/previews/primer/alpha/text_field_preview/input_group_trailing_button.html.erb +18 -0
- data/previews/primer/alpha/text_field_preview.rb +21 -0
- data/previews/primer/alpha/tooltip_preview/tooltip_with_dialog_moving_focus_to_input.html.erb +23 -0
- data/previews/primer/alpha/tooltip_preview.rb +6 -1
- data/previews/primer/beta/button_group_preview.rb +6 -6
- data/previews/primer/beta/button_preview.rb +21 -3
- data/previews/primer/beta/icon_button_preview.rb +3 -0
- data/previews/primer/{alpha → beta}/nav_list_preview/trailing_action.html.erb +1 -1
- data/previews/primer/{alpha → beta}/nav_list_preview.rb +5 -5
- data/previews/primer/open_project/flex_layout_preview.rb +73 -0
- data/previews/primer/open_project/grid_layout_preview.rb +37 -0
- data/static/arguments.json +278 -7
- data/static/audited_at.json +8 -0
- data/static/classes.json +15 -0
- data/static/constants.json +47 -1
- data/static/info_arch.json +1338 -632
- data/static/previews.json +271 -167
- data/static/statuses.json +13 -5
- metadata +33 -319
- /data/app/assets/javascripts/app/components/primer/{alpha → beta}/nav_list.d.ts +0 -0
- /data/app/components/primer/{alpha → beta}/nav_list/group.html.erb +0 -0
- /data/app/components/primer/{alpha → beta}/nav_list/item.html.erb +0 -0
- /data/app/components/primer/{alpha → beta}/nav_list.d.ts +0 -0
- /data/app/components/primer/{alpha → beta}/nav_list.html.erb +0 -0
- /data/app/components/primer/{alpha → beta}/nav_list.js +0 -0
- /data/app/components/primer/{alpha → beta}/nav_list.ts +0 -0
@@ -3,104 +3,8 @@
|
|
3
3
|
module Primer
|
4
4
|
module Alpha
|
5
5
|
class NavList
|
6
|
-
|
7
|
-
|
8
|
-
# See <%= link_to_component(Primer::Alpha::NavList) %> for usage examples.
|
9
|
-
class Group < ActionList
|
10
|
-
# A special "show more" list item that appears at the bottom of the group. Clicking
|
11
|
-
# the item will fetch the next page of results from the URL passed in the `src` argument
|
12
|
-
# and append the resulting chunk of HTML to the group.
|
13
|
-
#
|
14
|
-
# @param src [String] The URL to query for additional pages of list items.
|
15
|
-
# @param pages [Integer] The total number of pages in the result set.
|
16
|
-
# @param component_klass [Class] A component class to use instead of the default `Primer::Alpha::NavList::Item` class.
|
17
|
-
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Item) %>.
|
18
|
-
renders_one :show_more_item, lambda { |src:, pages:, component_klass: NavList::Item, **system_arguments|
|
19
|
-
system_arguments[:classes] = class_names(
|
20
|
-
@item_classes,
|
21
|
-
system_arguments[:classes]
|
22
|
-
)
|
23
|
-
system_arguments[:tag] = :div
|
24
|
-
system_arguments[:id] ||= self.class.generate_id(base_name: "item")
|
25
|
-
system_arguments[:hidden] = true
|
26
|
-
system_arguments[:href] = "#"
|
27
|
-
system_arguments[:data] ||= {}
|
28
|
-
system_arguments[:data][:target] = "nav-list.showMoreItem"
|
29
|
-
system_arguments[:data][:action] = "click:nav-list#showMore"
|
30
|
-
system_arguments[:data][:current_page] = "1"
|
31
|
-
system_arguments[:data][:total_pages] = pages.to_s
|
32
|
-
system_arguments[:label_arguments] = {
|
33
|
-
**system_arguments[:label_arguments] || {},
|
34
|
-
color: :accent
|
35
|
-
}
|
36
|
-
|
37
|
-
system_arguments[:content_arguments] = {
|
38
|
-
**system_arguments[:content_arguments] || {},
|
39
|
-
tag: :button
|
40
|
-
}
|
41
|
-
|
42
|
-
system_arguments[:content_arguments][:data] = merge_data(
|
43
|
-
system_arguments[:content_arguments],
|
44
|
-
data: { list_id: id }
|
45
|
-
)
|
46
|
-
|
47
|
-
component_klass.new(list: self, src: src, **system_arguments)
|
48
|
-
}
|
49
|
-
|
50
|
-
# @private
|
51
|
-
def self.custom_element_name
|
52
|
-
Primer::Alpha::NavList.custom_element_name
|
53
|
-
end
|
54
|
-
|
55
|
-
# @param selected_item_id [Symbol] The ID of the currently selected item. Used internally.
|
56
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
57
|
-
def initialize(selected_item_id: nil, **system_arguments)
|
58
|
-
@system_arguments = system_arguments
|
59
|
-
@selected_item_id = selected_item_id
|
60
|
-
|
61
|
-
super(**@system_arguments)
|
62
|
-
end
|
63
|
-
|
64
|
-
# Cause this group to show its list of sub items when rendered.
|
65
|
-
# :nocov:
|
66
|
-
def expand!
|
67
|
-
@expanded = true
|
68
|
-
end
|
69
|
-
# :nocov:
|
70
|
-
|
71
|
-
# @!parse
|
72
|
-
# # Items.
|
73
|
-
# #
|
74
|
-
# # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Item) %>.
|
75
|
-
# renders_many :items
|
76
|
-
|
77
|
-
# @private
|
78
|
-
def build_item(component_klass: NavList::Item, **system_arguments)
|
79
|
-
super(
|
80
|
-
component_klass: component_klass,
|
81
|
-
selected_item_id: @selected_item_id,
|
82
|
-
**system_arguments
|
83
|
-
)
|
84
|
-
end
|
85
|
-
|
86
|
-
# @private
|
87
|
-
def build_avatar_item(component_klass: NavList::Item, **system_arguments)
|
88
|
-
super(
|
89
|
-
component_klass: component_klass,
|
90
|
-
selected_item_id: @selected_item_id,
|
91
|
-
**system_arguments
|
92
|
-
)
|
93
|
-
end
|
94
|
-
|
95
|
-
def kind
|
96
|
-
:group
|
97
|
-
end
|
98
|
-
|
99
|
-
def before_render
|
100
|
-
super
|
101
|
-
|
102
|
-
raise ArgumentError, "NavList groups are required to have headings" unless heading?
|
103
|
-
end
|
6
|
+
class Group < Beta::NavList::Group
|
7
|
+
status :deprecated
|
104
8
|
end
|
105
9
|
end
|
106
10
|
end
|
@@ -3,33 +3,8 @@
|
|
3
3
|
module Primer
|
4
4
|
module Alpha
|
5
5
|
class NavList
|
6
|
-
|
7
|
-
|
8
|
-
# See <%= link_to_component(Primer::Alpha::NavList) %> for usage examples.
|
9
|
-
class Heading < Primer::Component
|
10
|
-
attr_reader :title, :id, :heading_level, :system_arguments
|
11
|
-
|
12
|
-
# @param title [String] The text content of the heading.
|
13
|
-
# @param id [String] The value of the ID HTML attribute. Auto-generated by default.
|
14
|
-
# @param heading_level [Integer] The heading level, i.e. 2 for an `<h2>`, 3 for an `<h3>`, etc.
|
15
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
16
|
-
def initialize(title:, id: self.class.generate_id, heading_level: 2, **system_arguments)
|
17
|
-
@title = title
|
18
|
-
@id = id
|
19
|
-
@heading_level = heading_level
|
20
|
-
@system_arguments = system_arguments
|
21
|
-
end
|
22
|
-
|
23
|
-
def call
|
24
|
-
render(
|
25
|
-
Primer::BaseComponent.new(
|
26
|
-
tag: :"h#{heading_level}",
|
27
|
-
id: id,
|
28
|
-
classes: "ActionListHeader",
|
29
|
-
**system_arguments
|
30
|
-
).with_content(title)
|
31
|
-
)
|
32
|
-
end
|
6
|
+
class Heading < Beta::NavList::Heading
|
7
|
+
status :deprecated
|
33
8
|
end
|
34
9
|
end
|
35
10
|
end
|
@@ -3,153 +3,8 @@
|
|
3
3
|
module Primer
|
4
4
|
module Alpha
|
5
5
|
class NavList
|
6
|
-
|
7
|
-
|
8
|
-
# `selected_item_ids` argument, which accepts a list of valid IDs for the item. Items can also
|
9
|
-
# themselves contain sub items. Sub items are rendered collapsed by default.
|
10
|
-
class Item < Primer::Alpha::ActionList::Item
|
11
|
-
attr_reader :selected_by_ids, :sub_item
|
12
|
-
|
13
|
-
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::ActionList::Item) %>.
|
14
|
-
renders_many :items, lambda { |**system_arguments|
|
15
|
-
raise "Items can only be nested 2 levels deep" if sub_item?
|
16
|
-
|
17
|
-
@list.build_item(parent: self, sub_item: true, **system_arguments).tap do |item|
|
18
|
-
@list.will_add_item(item)
|
19
|
-
end
|
20
|
-
}
|
21
|
-
|
22
|
-
# Whether or not this item is nested under a parent item.
|
23
|
-
#
|
24
|
-
# @return [Boolean]
|
25
|
-
alias sub_item? sub_item
|
26
|
-
|
27
|
-
# @param selected_item_id [Symbol] The ID of the currently selected list item. Used internally.
|
28
|
-
# @param selected_by_ids [Array<Symbol>] The list of IDs that select this item. In other words, if the `selected_item_id` attribute on the parent `NavList` is set to one of these IDs, the item will appear selected.
|
29
|
-
# @param expanded [Boolean] Whether this item shows (expands) or hides (collapses) its list of sub items.
|
30
|
-
# @param sub_item [Boolean] Whether or not this item is nested under a parent item. Used internally.
|
31
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
32
|
-
def initialize(selected_item_id: nil, selected_by_ids: [], sub_item: false, expanded: false, **system_arguments)
|
33
|
-
@selected_item_id = selected_item_id
|
34
|
-
@selected_by_ids = Array(selected_by_ids)
|
35
|
-
@expanded = expanded
|
36
|
-
@sub_item = sub_item
|
37
|
-
|
38
|
-
system_arguments[:classes] = class_names(
|
39
|
-
system_arguments[:classes],
|
40
|
-
"ActionListItem--subItem" => @sub_item
|
41
|
-
)
|
42
|
-
|
43
|
-
@sub_list_arguments = {
|
44
|
-
classes: class_names(
|
45
|
-
"ActionList",
|
46
|
-
"ActionList--subGroup"
|
47
|
-
)
|
48
|
-
}
|
49
|
-
|
50
|
-
@list = system_arguments[:list]
|
51
|
-
|
52
|
-
@sub_list_arguments["data-action"] = "keydown:#{@list.custom_element_name}#handleItemWithSubItemKeydown" if @list
|
53
|
-
|
54
|
-
overrides = { "data-item-id": @selected_by_ids.join(" ") }
|
55
|
-
|
56
|
-
super(**system_arguments, **overrides)
|
57
|
-
end
|
58
|
-
|
59
|
-
def active?
|
60
|
-
item_active?(self) && items.empty?
|
61
|
-
end
|
62
|
-
|
63
|
-
# Cause this item to show its list of sub items when rendered.
|
64
|
-
def expand!
|
65
|
-
@expanded = true
|
66
|
-
end
|
67
|
-
|
68
|
-
def before_render
|
69
|
-
if active_sub_item?
|
70
|
-
expand!
|
71
|
-
|
72
|
-
@content_arguments[:classes] = class_names(
|
73
|
-
@content_arguments[:classes],
|
74
|
-
"ActionListContent--hasActiveSubItem"
|
75
|
-
)
|
76
|
-
else
|
77
|
-
@system_arguments[:classes] = class_names(
|
78
|
-
@system_arguments[:classes],
|
79
|
-
"ActionListItem--navActive" => active?
|
80
|
-
)
|
81
|
-
end
|
82
|
-
|
83
|
-
@content_arguments[:"aria-current"] = "page" if active?
|
84
|
-
|
85
|
-
super
|
86
|
-
|
87
|
-
raise "Cannot render a trailing action for an item with subitems" if items.present? && trailing_action.present?
|
88
|
-
|
89
|
-
raise "Cannot pass `selected_by_ids:` for an item with subitems, since parent items cannot be selected" if items.present? && @selected_by_ids.present?
|
90
|
-
|
91
|
-
return if items.blank?
|
92
|
-
|
93
|
-
@sub_list_arguments[:aria] = merge_aria(
|
94
|
-
@sub_list_arguments,
|
95
|
-
{ aria: { labelledby: id } }
|
96
|
-
)
|
97
|
-
|
98
|
-
raise ArgumentError, "Items with sub-items cannot have hrefs" if href.present?
|
99
|
-
|
100
|
-
@content_arguments[:tag] = :button
|
101
|
-
@content_arguments[:"aria-expanded"] = @expanded.to_s
|
102
|
-
@content_arguments[:"data-action"] = "
|
103
|
-
click:#{@list.custom_element_name}#handleItemWithSubItemClick
|
104
|
-
keydown:#{@list.custom_element_name}#handleItemWithSubItemKeydown
|
105
|
-
"
|
106
|
-
|
107
|
-
with_private_trailing_action_icon(:"chevron-down", classes: "ActionListItem-collapseIcon")
|
108
|
-
|
109
|
-
@system_arguments[:classes] = class_names(
|
110
|
-
@system_arguments[:classes],
|
111
|
-
"ActionListItem--hasSubItem"
|
112
|
-
)
|
113
|
-
end
|
114
|
-
|
115
|
-
def kind
|
116
|
-
:item
|
117
|
-
end
|
118
|
-
|
119
|
-
private
|
120
|
-
|
121
|
-
# Normally it would be easier to simply ask each item for its active status, eg.
|
122
|
-
# items.any?(&:active?), but unfortunately the view context is not set on each
|
123
|
-
# item until _after_ the parent's before_render, etc methods have been called.
|
124
|
-
# This means helper methods like current_page? will blow up with an error, since
|
125
|
-
# `helpers` is simply an alias for the view context (i.e. an instance of
|
126
|
-
# ActionView::Base). Since we know the view context for the parent object must
|
127
|
-
# be set before `before_render` is invoked, we can call helper methods here in
|
128
|
-
# the parent and bypass the problem entirely. Maybe not the most OO approach,
|
129
|
-
# but it works.
|
130
|
-
def item_active?(item)
|
131
|
-
if item.selected_by_ids.present?
|
132
|
-
item.selected_by_ids.include?(@selected_item_id)
|
133
|
-
elsif item.href
|
134
|
-
current_page?(item.href)
|
135
|
-
else
|
136
|
-
# :nocov:
|
137
|
-
false
|
138
|
-
# :nocov:
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
def active_sub_item?
|
143
|
-
items.any? { |subitem| item_active?(subitem) }
|
144
|
-
end
|
145
|
-
|
146
|
-
def current_page?(url)
|
147
|
-
helpers.current_page?(url)
|
148
|
-
end
|
149
|
-
|
150
|
-
def list_class
|
151
|
-
Primer::Alpha::NavList
|
152
|
-
end
|
6
|
+
class Item < Beta::NavList::Item
|
7
|
+
status :deprecated
|
153
8
|
end
|
154
9
|
end
|
155
10
|
end
|
@@ -2,211 +2,8 @@
|
|
2
2
|
|
3
3
|
module Primer
|
4
4
|
module Alpha
|
5
|
-
|
6
|
-
|
7
|
-
# nav list is a list of links.
|
8
|
-
#
|
9
|
-
# Nav list groups can contain sub items. Rather than navigating to a URL, groups
|
10
|
-
# with sub items expand and collapse on click. To indicate this functionality, the
|
11
|
-
# group will automatically render with a trailing chevron icon that changes direction
|
12
|
-
# when the group expands and collapses.
|
13
|
-
#
|
14
|
-
# Nav list items appear visually active when selected. Each nav item must have one
|
15
|
-
# or more ID values that determine which item will appear selected. Use the
|
16
|
-
# `selected_item_id` argument to select the appropriate item.
|
17
|
-
class NavList < Primer::Component
|
18
|
-
status :alpha
|
19
|
-
audited_at "2023-07-10"
|
20
|
-
|
21
|
-
# @private
|
22
|
-
def self.custom_element_name
|
23
|
-
"nav-list"
|
24
|
-
end
|
25
|
-
|
26
|
-
# The heading for the list at large. Accepts the arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Heading) %>.
|
27
|
-
#
|
28
|
-
renders_one :heading, Primer::Alpha::NavList::Heading
|
29
|
-
|
30
|
-
# @!parse
|
31
|
-
# # Adds an item to the list.
|
32
|
-
# #
|
33
|
-
# # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
|
34
|
-
# # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
|
35
|
-
# def with_item(component_klass: Primer::Alpha::NavList::Item, **system_arguments, &block)
|
36
|
-
# end
|
37
|
-
|
38
|
-
# @!parse
|
39
|
-
# # Adds an avatar item to the list. Avatar items are a convenient way to accessibly add an item with a leading avatar image.
|
40
|
-
# #
|
41
|
-
# # @param src [String] The source url of the avatar image.
|
42
|
-
# # @param username [String] The username associated with the avatar.
|
43
|
-
# # @param full_name [String] Optional. The user's full name.
|
44
|
-
# # @param full_name_scheme [Symbol] Optional. How to display the user's full name. <%= one_of(Primer::Alpha::ActionList::Item::DESCRIPTION_SCHEME_OPTIONS) %>
|
45
|
-
# # @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
|
46
|
-
# # @param avatar_arguments [Hash] Optional. The arguments accepted by <%= link_to_component(Primer::Beta::Avatar) %>
|
47
|
-
# # @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
|
48
|
-
# def with_avatar_item(src:, username:, full_name: nil, full_name_scheme: Primer::Alpha::ActionList::Item::DEFAULT_DESCRIPTION_SCHEME, component_klass: Primer::Alpha::NavList::Item, avatar_arguments: {}, **system_arguments, &block)
|
49
|
-
# end
|
50
|
-
|
51
|
-
# @!parse
|
52
|
-
# # Adds a group to the list. A group is a list of links and a (required) heading.
|
53
|
-
# #
|
54
|
-
# # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Group) %>.
|
55
|
-
# def with_group(**system_arguments, &block)
|
56
|
-
# end
|
57
|
-
|
58
|
-
# @!parse
|
59
|
-
# # Adds a divider to the list. Dividers visually separate items and groups.
|
60
|
-
# #
|
61
|
-
# # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Alpha::NavList::Divider) %>.
|
62
|
-
# def with_divider(**system_arguments, &block)
|
63
|
-
# end
|
64
|
-
|
65
|
-
# Items. Items can be individual items, dividers, or groups. See the documentation for `#with_item`, `#with_divider`, and `#with_group` respectively for more information.
|
66
|
-
#
|
67
|
-
renders_many :items, types: {
|
68
|
-
item: {
|
69
|
-
renders: lambda { |**system_arguments, &block|
|
70
|
-
build_item(**system_arguments, &block)
|
71
|
-
},
|
72
|
-
|
73
|
-
as: :item
|
74
|
-
},
|
75
|
-
|
76
|
-
avatar_item: {
|
77
|
-
renders: lambda { |**system_arguments|
|
78
|
-
build_avatar_item(**system_arguments)
|
79
|
-
},
|
80
|
-
|
81
|
-
as: :avatar_item
|
82
|
-
},
|
83
|
-
|
84
|
-
divider: {
|
85
|
-
renders: Primer::Alpha::NavList::Divider,
|
86
|
-
as: :divider
|
87
|
-
},
|
88
|
-
|
89
|
-
group: {
|
90
|
-
renders: lambda { |**system_arguments, &block|
|
91
|
-
Primer::Alpha::NavList::Group.new(
|
92
|
-
selected_item_id: @selected_item_id,
|
93
|
-
**system_arguments,
|
94
|
-
&block
|
95
|
-
)
|
96
|
-
},
|
97
|
-
|
98
|
-
as: :group
|
99
|
-
}
|
100
|
-
}
|
101
|
-
|
102
|
-
# @param selected_item_id [Symbol] The ID of the currently selected item. The default is `nil`, meaning no item is selected.
|
103
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
104
|
-
def initialize(selected_item_id: nil, **system_arguments)
|
105
|
-
@system_arguments = system_arguments
|
106
|
-
@selected_item_id = selected_item_id
|
107
|
-
end
|
108
|
-
|
109
|
-
# Builds a new item but does not add it to the list. Use this method
|
110
|
-
# instead of the `#with_item` slot if you need to render an item outside
|
111
|
-
# the context of a list, eg. if rendering additional items to append to
|
112
|
-
# an existing list, perhaps via a separate HTTP request.
|
113
|
-
#
|
114
|
-
# @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
|
115
|
-
# @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
|
116
|
-
def build_item(component_klass: Primer::Alpha::NavList::Item, **system_arguments, &block)
|
117
|
-
component_klass.new(
|
118
|
-
list: top_level_group,
|
119
|
-
selected_item_id: @selected_item_id,
|
120
|
-
**system_arguments,
|
121
|
-
&block
|
122
|
-
)
|
123
|
-
end
|
124
|
-
|
125
|
-
# Builds a new avatar item but does not add it to the list. Avatar items
|
126
|
-
# are a convenient way to accessibly add an item with a leading avatar
|
127
|
-
# image. Use this method instead of the `#with_avatar_item` slot if you
|
128
|
-
# need to render an avatar item outside the context of a list, eg. if
|
129
|
-
# rendering additional items to append to an existing list, perhaps via
|
130
|
-
# a separate HTTP request.
|
131
|
-
#
|
132
|
-
# @param src [String] The source url of the avatar image.
|
133
|
-
# @param username [String] The username associated with the avatar.
|
134
|
-
# @param full_name [String] Optional. The user's full name.
|
135
|
-
# @param full_name_scheme [Symbol] Optional. How to display the user's full name. <%= one_of(Primer::Alpha::ActionList::Item::DESCRIPTION_SCHEME_OPTIONS) %>
|
136
|
-
# @param component_klass [Class] The class to use instead of the default <%= link_to_component(Primer::Alpha::NavList::Item) %>
|
137
|
-
# @param avatar_arguments [Hash] Optional. The arguments accepted by <%= link_to_component(Primer::Beta::Avatar) %>
|
138
|
-
# @param system_arguments [Hash] These arguments are forwarded to <%= link_to_component(Primer::Alpha::NavList::Item) %>, or whatever class is passed as the `component_klass` argument.
|
139
|
-
def build_avatar_item(src:, username:, full_name: nil, full_name_scheme: Primer::Alpha::ActionList::Item::DEFAULT_DESCRIPTION_SCHEME, component_klass: Primer::Alpha::NavList::Item, avatar_arguments: {}, **system_arguments)
|
140
|
-
component_klass.new(
|
141
|
-
list: top_level_group,
|
142
|
-
selected_item_id: @selected_item_id,
|
143
|
-
label: username,
|
144
|
-
description_scheme: full_name_scheme,
|
145
|
-
**system_arguments
|
146
|
-
).tap do |item|
|
147
|
-
item.with_leading_visual_raw_content do
|
148
|
-
# no alt text necessary
|
149
|
-
item.render(Primer::Beta::Avatar.new(src: src, **avatar_arguments, role: :presentation, size: 16))
|
150
|
-
end
|
151
|
-
|
152
|
-
item.with_description_content(full_name) if full_name
|
153
|
-
end
|
154
|
-
end
|
155
|
-
|
156
|
-
private
|
157
|
-
|
158
|
-
def before_render
|
159
|
-
if heading?
|
160
|
-
raise ArgumentError, "Please don't set an aria-label if a heading is provided" if aria(:label, @system_arguments)
|
161
|
-
|
162
|
-
@system_arguments[:aria] = merge_aria(
|
163
|
-
@system_arguments,
|
164
|
-
{ aria: { labelledby: heading.id } }
|
165
|
-
)
|
166
|
-
else
|
167
|
-
raise ArgumentError, "When no heading is provided, an aria-label must be given" unless aria(:label, @system_arguments)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
|
171
|
-
# Lists that contain top-level items (i.e. items outside of a group) should be wrapped in a <ul>
|
172
|
-
def render_outer_list?
|
173
|
-
items.any? { |item| !group?(item) }
|
174
|
-
end
|
175
|
-
|
176
|
-
def render_divider_between?(item1, item2)
|
177
|
-
return false if either_is_divider?(item1, item2)
|
178
|
-
|
179
|
-
both_are_groups?(item1, item2) || heterogeneous?(item1, item2)
|
180
|
-
end
|
181
|
-
|
182
|
-
def both_are_groups?(item1, item2)
|
183
|
-
group?(item1) && group?(item2)
|
184
|
-
end
|
185
|
-
|
186
|
-
def heterogeneous?(item1, item2)
|
187
|
-
kind(item1) != kind(item2)
|
188
|
-
end
|
189
|
-
|
190
|
-
def either_is_divider?(item1, item2)
|
191
|
-
divider?(item1) || divider?(item2)
|
192
|
-
end
|
193
|
-
|
194
|
-
def group?(item)
|
195
|
-
kind(item) == :group
|
196
|
-
end
|
197
|
-
|
198
|
-
def divider?(item)
|
199
|
-
kind(item) == :divider
|
200
|
-
end
|
201
|
-
|
202
|
-
def kind(item)
|
203
|
-
item.respond_to?(:kind) ? item.kind : :item
|
204
|
-
end
|
205
|
-
|
206
|
-
def top_level_group
|
207
|
-
# dummy group for the list: argument in the item slot above
|
208
|
-
@top_level_group ||= Primer::Alpha::NavList::Group.new(selected_item_id: @selected_item_id)
|
209
|
-
end
|
5
|
+
class NavList < Beta::NavList
|
6
|
+
status :deprecated
|
210
7
|
end
|
211
8
|
end
|
212
9
|
end
|
@@ -1 +1 @@
|
|
1
|
-
anchored-position[popover]{border-width:0;inset:auto;min-width:192px;overflow:visible;padding:0;position:absolute}.Overlay{display:flex}anchored-position[popover]:not(.\:popover-open){display:none}anchored-position.not-anchored::-webkit-backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}anchored-position.not-anchored::backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}@supports selector(:popover-open){anchored-position[popover]:not(.\:popover-open){display:revert}}
|
1
|
+
anchored-position[popover]{background:none;border-width:0;inset:auto;min-width:192px;overflow:visible;padding:0;position:absolute}.Overlay{display:flex}anchored-position[popover]:not(.\:popover-open){display:none}anchored-position.not-anchored::-webkit-backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}anchored-position.not-anchored::backdrop{background-color:var(--overlay-backdrop-bgColor,var(--color-neutral-muted))}@supports selector(:popover-open){anchored-position[popover]:not(.\:popover-open){display:revert}}
|
@@ -1 +1 @@
|
|
1
|
-
{"version":3,"sources":["overlay.pcss"],"names":[],"mappings":"AAAA,
|
1
|
+
{"version":3,"sources":["overlay.pcss"],"names":[],"mappings":"AAAA,2BAOE,eAAgB,CANhB,cAAe,CAIf,UAAW,CADX,eAAgB,CAEhB,gBAAiB,CAJjB,SAAU,CACV,iBAKF,CAEA,SACE,YACF,CAEA,gDACE,YACF,CAEA,iDACE,2EACF,CAFA,yCACE,2EACF,CAGA,kCACE,gDACE,cACF,CACF","file":"overlay.css","sourcesContent":["anchored-position[popover] {\n border-width: 0;\n padding: 0;\n position: absolute;\n min-width: 192px;\n inset: auto;\n overflow: visible;\n background: none;\n}\n\n.Overlay {\n display: flex;\n}\n\nanchored-position[popover]:not(.\\:popover-open) {\n display: none;\n}\n\nanchored-position.not-anchored::backdrop {\n background-color: var(--overlay-backdrop-bgColor, var(--color-neutral-muted));\n}\n\n/* This reverts the declaration above for native popover, where `:popover-open` is supported */\n@supports selector(:popover-open) {\n anchored-position[popover]:not(.\\:popover-open) {\n display: revert;\n }\n}\n"]}
|
@@ -5,6 +5,7 @@ anchored-position[popover] {
|
|
5
5
|
min-width: 192px;
|
6
6
|
inset: auto;
|
7
7
|
overflow: visible;
|
8
|
+
background: none;
|
8
9
|
}
|
9
10
|
|
10
11
|
.Overlay {
|
@@ -25,10 +26,3 @@ anchored-position.not-anchored::backdrop {
|
|
25
26
|
display: revert;
|
26
27
|
}
|
27
28
|
}
|
28
|
-
|
29
|
-
/* This reverts the declaration above for native popover, where `:open` is supported (Chrome 113, Safari TP) */
|
30
|
-
@supports selector(:open) {
|
31
|
-
anchored-position[popover]:not(.\:popover-open) {
|
32
|
-
display: revert;
|
33
|
-
}
|
34
|
-
}
|
@@ -178,10 +178,12 @@ module Primer
|
|
178
178
|
end
|
179
179
|
|
180
180
|
def before_render
|
181
|
-
if
|
182
|
-
|
183
|
-
|
184
|
-
|
181
|
+
if @system_arguments[:role].present?
|
182
|
+
if header?
|
183
|
+
@system_arguments[:aria][:labelledby] ||= title_id
|
184
|
+
else
|
185
|
+
@system_arguments[:aria][:label] = @title
|
186
|
+
end
|
185
187
|
end
|
186
188
|
with_body unless body?
|
187
189
|
end
|
@@ -23,6 +23,8 @@ module Primer
|
|
23
23
|
# @param label [String] Label text displayed above the input.
|
24
24
|
# @param hidden [Boolean] When set to `true`, visually hides the group.
|
25
25
|
# @param caption [String] A string describing the field and what sorts of input it expects. Displayed below the group.
|
26
|
+
# @param invalid [Boolean] If set to `true`, the input will be marked as invalid. Implied if `validation_message` is truthy. This option is set to `true` automatically if the model object associated with the form reports that the input is invalid via Rails validations. It is provided for cases where the form does not have an associated model. If the input is invalid as determined by Rails validations, setting `invalid` to `false` will have no effect.
|
27
|
+
# @param validation_message [String] A string displayed between the caption and the input indicating the input's contents are invalid. This option is, by default, set to the first Rails validation message for the input (assuming the form is associated with a model object). Use `validation_message` to override the default or to provide a validation message in case there is no associated model object.
|
26
28
|
# @param label_arguments [Hash] Attributes that will be passed to Rails' `builder.label` method. These can be HTML attributes or any of the other label options Rails supports. They will appear as HTML attributes on the `<label>` tag.
|
27
29
|
|
28
30
|
# @!method radio_button
|
@@ -2,12 +2,5 @@
|
|
2
2
|
"SegmentedControl-item",
|
3
3
|
"SegmentedControl-item--selected": @selected
|
4
4
|
) %>" role="listitem" data-targets="segmented-control.items">
|
5
|
-
|
6
|
-
<%= render Primer::Beta::IconButton.new(icon: @icon, "aria-label": @label, **@system_arguments) %>
|
7
|
-
<% else %>
|
8
|
-
<%= render Primer::Beta::Button.new(**@system_arguments) do |button| %>
|
9
|
-
<% button.with_leading_visual_icon(icon: @icon) unless @icon.nil? %>
|
10
|
-
<%= @label %>
|
11
|
-
<% end %>
|
12
|
-
<% end %>
|
5
|
+
<%= render @button %>
|
13
6
|
</li>
|
@@ -13,16 +13,50 @@ module Primer
|
|
13
13
|
# @param selected [Boolean] Whether the item is selected
|
14
14
|
# @param icon [Symbol] The icon to use
|
15
15
|
# @param hide_labels [Symbol] Whether to only show the icon
|
16
|
-
def initialize(
|
17
|
-
|
18
|
-
|
19
|
-
|
16
|
+
def initialize(
|
17
|
+
label:,
|
18
|
+
selected: false,
|
19
|
+
icon: nil,
|
20
|
+
hide_labels: false,
|
21
|
+
**system_arguments
|
22
|
+
)
|
20
23
|
@selected = selected
|
21
24
|
|
22
25
|
@system_arguments = system_arguments
|
23
26
|
@system_arguments[:"data-action"] = "click:segmented-control#select" if system_arguments[:href].nil?
|
24
27
|
@system_arguments[:"aria-current"] = selected
|
25
28
|
@system_arguments[:scheme] = :invisible
|
29
|
+
|
30
|
+
if hide_labels
|
31
|
+
@button = Primer::Beta::IconButton.new(
|
32
|
+
icon: icon,
|
33
|
+
"aria-label": label,
|
34
|
+
**@system_arguments
|
35
|
+
)
|
36
|
+
else
|
37
|
+
@button = Primer::Beta::Button.new(**@system_arguments)
|
38
|
+
@button.with_leading_visual_icon(icon: icon) if icon
|
39
|
+
@button.with_content(label)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# @!parse
|
44
|
+
# # Optional trailing Label
|
45
|
+
# #
|
46
|
+
# # @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Beta::Button) %>'s `with_trailing_visual_label` slot.
|
47
|
+
# renders_one(:trailing_visual_label)
|
48
|
+
|
49
|
+
# Optional trailing label.
|
50
|
+
#
|
51
|
+
# @param system_arguments [Hash] The arguments accepted by <%= link_to_component(Primer::Beta::Button) %>'s `with_trailing_visual_label` slot.
|
52
|
+
def with_trailing_visual_label(**system_arguments, &block)
|
53
|
+
@button.with_trailing_visual_label(**system_arguments, &block)
|
54
|
+
end
|
55
|
+
|
56
|
+
private
|
57
|
+
|
58
|
+
def before_render
|
59
|
+
content
|
26
60
|
end
|
27
61
|
end
|
28
62
|
end
|
@@ -1 +1 @@
|
|
1
|
-
.SegmentedControl{background-color:var(--controlTrack-bgColor-rest,var(--color-segmented-control-bg));border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;list-style:none}.SegmentedControl-item{border:var(--borderWidth-thin,max(1px,.0625rem)) solid #0000;border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;
|
1
|
+
.SegmentedControl{--segmentedControl-item-padding:var(--control-small-paddingBlock,0.25rem);background-color:var(--controlTrack-bgColor-rest,var(--color-segmented-control-bg));border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;list-style:none}.SegmentedControl--iconOnly .Button--iconOnly.Button--large,.SegmentedControl--iconOnly .Button--iconOnly.Button--medium,.SegmentedControl--iconOnly .Button--iconOnly.Button--small{padding-inline:0!important;width:100%}.SegmentedControl--small{--segmentedControl-item-padding:var(--control-xsmall-paddingBlock,0.125rem)}.SegmentedControl--small .SegmentedControl-item{height:var(--control-small-size,1.75rem)}.SegmentedControl--small .SegmentedControl-item .Button{padding-inline:calc(var(--control-xsmall-paddingInline-normal,.5rem) - var(--segmentedControl-item-padding))}.SegmentedControl--small.SegmentedControl--iconOnly .SegmentedControl-item{width:var(--control-small-size,1.75rem)}.SegmentedControl--medium .SegmentedControl-item{height:var(--control-medium-size,2rem)}.SegmentedControl--medium.SegmentedControl--iconOnly .SegmentedControl-item{width:var(--control-medium-size,2rem)}.SegmentedControl--large .SegmentedControl-item{height:var(--control-large-size,2.5rem)}.SegmentedControl--large .SegmentedControl-item .Button{padding-inline:calc(var(--control-large-paddingInline-normal,.75rem) - var(--segmentedControl-item-padding))}.SegmentedControl--large.SegmentedControl--iconOnly .SegmentedControl-item{width:var(--control-large-size,2.5rem)}.SegmentedControl-item{border:var(--borderWidth-thin,max(1px,.0625rem)) solid #0000;border-radius:var(--borderRadius-medium,.375rem);display:inline-flex;height:var(--control-medium-size,2rem);justify-content:center;padding:var(--segmentedControl-item-padding);position:relative}.SegmentedControl-item .Button-withTooltip{width:100%}.SegmentedControl-item .Button--invisible:hover:not(:disabled){background-color:var(--controlTrack-bgColor-hover,var(--color-action-list-item-default-hover-bg))}.SegmentedControl-item .Button--invisible:active:not(:disabled){background-color:var(--controlTrack-bgColor-active,var(--color-action-list-item-default-active-bg))}.SegmentedControl-item.SegmentedControl-item--selected{background-color:var(--controlKnob-bgColor-rest,var(--color-segmented-control-button-bg));border-color:var(--controlKnob-borderColor-rest,var(--color-segmented-control-button-selected-border))}.SegmentedControl-item.SegmentedControl-item--selected .Button{font-weight:var(--base-text-weight-semibold,600)}.SegmentedControl-item.SegmentedControl-item--selected .Button:hover{background-color:initial}.SegmentedControl-item.SegmentedControl-item--selected:before{border-color:#0000!important}.SegmentedControl-item.SegmentedControl-item--selected+.SegmentedControl-item:before{border-color:#0000}.SegmentedControl-item .Button-label[data-content]:before{content:attr(data-content);display:block;font-weight:var(--base-text-weight-semibold,600);height:0;visibility:hidden}.SegmentedControl-item:not(:first-child):before{border-left:var(--borderWidth-thin,max(1px,.0625rem)) solid var(--borderColor-default,var(--color-border-default));content:"";inset:0 0 0 -1px;margin-bottom:var(--control-medium-paddingBlock,.375rem);margin-top:var(--control-medium-paddingBlock,.375rem);position:absolute}.SegmentedControl-item .Button{border:0;border-radius:calc(var(--borderRadius-medium,.375rem) - var(--segmentedControl-item-padding)/2);font-weight:var(--base-text-weight-normal,400);height:100%;padding-inline:calc(var(--control-medium-paddingInline-normal,.75rem) - var(--segmentedControl-item-padding));width:100%}.SegmentedControl-item .Button:focus-visible{border-radius:calc(var(--borderRadius-medium,.375rem) - var(--segmentedControl-item-padding)/1);outline-offset:calc(var(--segmentedControl-item-padding) - var(--borderWidth-thin,max(1px, .0625rem)))}.SegmentedControl-item .Button--invisible.Button--invisible-noVisuals .Button-label{color:var(--button-default-fgColor-rest,var(--color-btn-text))}.SegmentedControl--fullWidth{display:flex}.SegmentedControl--fullWidth .SegmentedControl-item{flex:1;justify-content:center}
|