primer_view_components 0.0.53 → 0.0.57
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 +87 -0
- data/app/components/primer/alpha/tab_nav.html.erb +11 -0
- data/app/components/primer/alpha/tab_nav.rb +130 -0
- data/app/components/primer/{tab_nav_component.html.erb → alpha/tab_panels.html.erb} +3 -8
- data/app/components/primer/alpha/tab_panels.rb +82 -0
- data/app/components/primer/alpha/underline_nav.html.erb +15 -0
- data/app/components/primer/alpha/underline_nav.rb +137 -0
- data/app/components/primer/{underline_nav_component.html.erb → alpha/underline_panels.html.erb} +3 -8
- data/app/components/primer/alpha/underline_panels.rb +86 -0
- data/app/components/primer/base_component.rb +1 -1
- data/app/components/primer/{breadcrumb_component.html.erb → beta/breadcrumbs.html.erb} +2 -1
- data/app/components/primer/beta/breadcrumbs.rb +61 -0
- data/app/components/primer/navigation/tab_component.rb +7 -5
- data/app/components/primer/octicon_component.rb +6 -1
- data/app/components/primer/tab_container_component.rb +1 -1
- data/app/lib/primer/class_name_helper.rb +14 -13
- data/app/lib/primer/octicon/cache.rb +10 -2
- data/app/lib/primer/tab_nav_helper.rb +35 -0
- data/app/lib/primer/tabbed_component_helper.rb +4 -4
- data/app/lib/primer/underline_nav_helper.rb +44 -0
- data/lib/primer/classify/cache.rb +0 -6
- data/lib/primer/classify/utilities.rb +6 -2
- data/lib/primer/classify/utilities.yml +35 -0
- data/lib/primer/classify/validation.rb +1 -1
- data/lib/primer/classify.rb +0 -5
- data/lib/primer/view_components/engine.rb +1 -1
- data/lib/primer/view_components/linters/argument_mappers/button.rb +4 -1
- data/lib/primer/view_components/linters/flash_component_migration_counter.rb +5 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/cop/primer/base_cop.rb +28 -0
- data/lib/rubocop/cop/primer/deprecated_arguments.rb +105 -15
- data/lib/rubocop/cop/primer/primer_octicon.rb +18 -1
- data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +1 -15
- data/lib/tasks/docs.rake +7 -6
- data/lib/tasks/utilities.rake +2 -0
- data/static/arguments.yml +75 -64
- data/static/classes.yml +2 -0
- data/static/constants.json +31 -29
- data/static/statuses.json +7 -5
- metadata +29 -9
- data/app/components/primer/breadcrumb_component.rb +0 -57
- data/app/components/primer/tab_nav_component.rb +0 -151
- data/app/components/primer/underline_nav_component.rb +0 -187
- data/lib/primer/classify/functional_text_colors.rb +0 -64
data/app/components/primer/{underline_nav_component.html.erb → alpha/underline_panels.html.erb}
RENAMED
@@ -1,23 +1,18 @@
|
|
1
|
-
<%=
|
1
|
+
<%= tab_container_wrapper(with_panel: true, **@wrapper_arguments) do %>
|
2
2
|
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
3
3
|
<% if @align == :right %>
|
4
4
|
<%= actions %>
|
5
5
|
<% end %>
|
6
|
-
|
7
6
|
<%= render body do %>
|
8
7
|
<% tabs.each do |tab| %>
|
9
8
|
<%= tab %>
|
10
9
|
<% end %>
|
11
10
|
<% end %>
|
12
|
-
|
13
11
|
<% if @align == :left %>
|
14
12
|
<%= actions %>
|
15
13
|
<% end %>
|
16
14
|
<% end %>
|
17
|
-
|
18
|
-
|
19
|
-
<% tabs.each do |tab| %>
|
20
|
-
<%= tab.panel %>
|
21
|
-
<% end %>
|
15
|
+
<% tabs.each do |tab| %>
|
16
|
+
<%= tab.panel %>
|
22
17
|
<% end %>
|
23
18
|
<% end %>
|
@@ -0,0 +1,86 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Alpha
|
5
|
+
# Use `UnderlinePanels` to style tabs with an associated panel and an underlined selected state.
|
6
|
+
class UnderlinePanels < Primer::Component
|
7
|
+
include Primer::TabbedComponentHelper
|
8
|
+
include Primer::UnderlineNavHelper
|
9
|
+
# Use to render a button and an associated panel slot. See the example below or refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
|
10
|
+
#
|
11
|
+
# @param id [String] Unique ID of tab.
|
12
|
+
# @param selected [Boolean] Whether the tab is selected.
|
13
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
14
|
+
renders_many :tabs, lambda { |id:, selected: false, **system_arguments|
|
15
|
+
system_arguments[:id] = id
|
16
|
+
system_arguments[:classes] = underline_nav_tab_classes(system_arguments[:classes])
|
17
|
+
|
18
|
+
Primer::Navigation::TabComponent.new(
|
19
|
+
selected: selected,
|
20
|
+
with_panel: true,
|
21
|
+
list: true,
|
22
|
+
icon_classes: "UnderlineNav-octicon",
|
23
|
+
panel_id: "panel-#{id}",
|
24
|
+
**system_arguments
|
25
|
+
)
|
26
|
+
}
|
27
|
+
|
28
|
+
# Use actions for a call to action.
|
29
|
+
#
|
30
|
+
# @param tag [Symbol] (Primer::UnderlineNavHelper::ACTIONS_TAG_DEFAULT) <%= one_of(Primer::UnderlineNavHelper::ACTIONS_TAG_OPTIONS) %>
|
31
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
32
|
+
renders_one :actions, lambda { |tag: ACTIONS_TAG_DEFAULT, **system_arguments|
|
33
|
+
system_arguments[:tag] = fetch_or_fallback(ACTIONS_TAG_OPTIONS, tag, ACTIONS_TAG_DEFAULT)
|
34
|
+
system_arguments[:classes] = underline_nav_action_classes(system_arguments[:classes])
|
35
|
+
|
36
|
+
Primer::BaseComponent.new(**system_arguments)
|
37
|
+
}
|
38
|
+
|
39
|
+
# @example Default
|
40
|
+
# <%= render(Primer::Alpha::UnderlinePanels.new(label: "With panels")) do |component| %>
|
41
|
+
# <% component.tab(id: "tab-1", selected: true) do |t| %>
|
42
|
+
# <% t.text { "Tab 1" } %>
|
43
|
+
# <% t.panel do %>
|
44
|
+
# Panel 1
|
45
|
+
# <% end %>
|
46
|
+
# <% end %>
|
47
|
+
# <% component.tab(id: "tab-2") do |t| %>
|
48
|
+
# <% t.text { "Tab 2" } %>
|
49
|
+
# <% t.panel do %>
|
50
|
+
# Panel 2
|
51
|
+
# <% end %>
|
52
|
+
# <% end %>
|
53
|
+
# <% component.actions do %>
|
54
|
+
# <%= render(Primer::ButtonComponent.new) { "Button!" } %>
|
55
|
+
# <% end %>
|
56
|
+
# <% end %>
|
57
|
+
#
|
58
|
+
# @param label [String] Sets an `aria-label` that helps assistive technology users understand the purpose of the tabs.
|
59
|
+
# @param align [Symbol] <%= one_of(Primer::UnderlineNavHelper::ALIGN_OPTIONS) %> - Defaults to <%= Primer::UnderlineNavHelper::ALIGN_DEFAULT %>
|
60
|
+
# @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
|
61
|
+
# @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper.
|
62
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
63
|
+
def initialize(label:, align: ALIGN_DEFAULT, body_arguments: {}, wrapper_arguments: {}, **system_arguments)
|
64
|
+
@align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
|
65
|
+
@wrapper_arguments = wrapper_arguments
|
66
|
+
|
67
|
+
@system_arguments = system_arguments
|
68
|
+
@system_arguments[:tag] = :div
|
69
|
+
@system_arguments[:classes] = underline_nav_classes(@system_arguments[:classes], @align)
|
70
|
+
|
71
|
+
@body_arguments = body_arguments
|
72
|
+
@body_arguments[:tag] = :ul
|
73
|
+
@body_arguments[:classes] = underline_nav_body_classes(@body_arguments[:classes])
|
74
|
+
|
75
|
+
@body_arguments[:role] = :tablist
|
76
|
+
@body_arguments[:"aria-label"] = label
|
77
|
+
end
|
78
|
+
|
79
|
+
private
|
80
|
+
|
81
|
+
def body
|
82
|
+
Primer::BaseComponent.new(**@body_arguments)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -65,7 +65,7 @@ module Primer
|
|
65
65
|
# | :- | :- | :- |
|
66
66
|
# | `bg` | String, Symbol | Background color. Accepts either a hex value as a String or <%= one_of(Primer::Classify::FunctionalBackgroundColors::OPTIONS, lower: true) %> |
|
67
67
|
# | `border_color` | Symbol | Border color. <%= one_of(Primer::Classify::FunctionalBorderColors::OPTIONS) %> |
|
68
|
-
# | `color` | Symbol | Text color. <%= one_of(Primer::Classify::
|
68
|
+
# | `color` | Symbol | Text color. <%= one_of(Primer::Classify::Utilities.mappings(:color)) %> |
|
69
69
|
#
|
70
70
|
# ## Flex
|
71
71
|
#
|
@@ -0,0 +1,61 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Beta
|
5
|
+
# Use `Breadcrumbs` to display page hierarchy.
|
6
|
+
class Breadcrumbs < Primer::Component
|
7
|
+
status :beta
|
8
|
+
|
9
|
+
# @param href [String] The URL to link to.
|
10
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
11
|
+
renders_many :items, "Item"
|
12
|
+
|
13
|
+
# @example Basic
|
14
|
+
# <%= render(Primer::Beta::Breadcrumbs.new) do |component| %>
|
15
|
+
# <% component.item(href: "/") do %>Home<% end %>
|
16
|
+
# <% component.item(href: "/about") do %>About<% end %>
|
17
|
+
# <% component.item(href: "/about/team") do %>Team<% end %>
|
18
|
+
# <% end %>
|
19
|
+
#
|
20
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
21
|
+
def initialize(**system_arguments)
|
22
|
+
@system_arguments = system_arguments
|
23
|
+
@system_arguments[:tag] = :nav
|
24
|
+
@system_arguments[:aria] = { label: "Breadcrumb" }
|
25
|
+
end
|
26
|
+
|
27
|
+
def render?
|
28
|
+
items.any?
|
29
|
+
end
|
30
|
+
|
31
|
+
# This component is part of `Primer::Beta::Breadcrumbs` and should not be
|
32
|
+
# used as a standalone component.
|
33
|
+
class Item < Primer::Component
|
34
|
+
attr_accessor :selected, :href
|
35
|
+
|
36
|
+
def initialize(href:, **system_arguments)
|
37
|
+
@href = href
|
38
|
+
@system_arguments = system_arguments
|
39
|
+
@selected = false
|
40
|
+
|
41
|
+
@system_arguments[:tag] = :li
|
42
|
+
@system_arguments[:classes] = "breadcrumb-item #{@system_arguments[:classes]}"
|
43
|
+
end
|
44
|
+
|
45
|
+
def call
|
46
|
+
link_arguments = { href: @href }
|
47
|
+
|
48
|
+
if selected
|
49
|
+
link_arguments[:"aria-current"] = "page"
|
50
|
+
link_arguments[:classes] = "breadcrumb-item-selected"
|
51
|
+
@system_arguments[:classes] = "#{@system_arguments[:classes]} breadcrumb-item-selected"
|
52
|
+
end
|
53
|
+
|
54
|
+
render(Primer::BaseComponent.new(**@system_arguments)) do
|
55
|
+
render(Primer::LinkComponent.new(**link_arguments)) { content }
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Primer
|
4
4
|
module Navigation
|
5
|
-
# This component is part of navigation components such as `Primer::
|
6
|
-
# and `Primer::
|
5
|
+
# This component is part of navigation components such as `Primer::Alpha::TabNav`
|
6
|
+
# and `Primer::Alpha::UnderlineNav` and should not be used by itself.
|
7
7
|
#
|
8
8
|
# @accessibility
|
9
9
|
# `TabComponent` renders the selected anchor tab with `aria-current="page"` by default.
|
@@ -14,7 +14,7 @@ module Primer
|
|
14
14
|
# Panel controlled by the Tab. This will not render anything in the tab itself.
|
15
15
|
# It will provide a accessor for the Tab's parent to call and render the panel
|
16
16
|
# content in the appropriate place.
|
17
|
-
# Refer to `
|
17
|
+
# Refer to `UnderlineNav` and `TabNav` implementations for examples.
|
18
18
|
#
|
19
19
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
20
20
|
renders_one :panel, lambda { |**system_arguments|
|
@@ -111,19 +111,21 @@ module Primer
|
|
111
111
|
|
112
112
|
@system_arguments = system_arguments
|
113
113
|
@id = @system_arguments[:id]
|
114
|
+
@wrapper_arguments = wrapper_arguments
|
114
115
|
|
115
116
|
if with_panel || @system_arguments[:tag] == :button
|
116
117
|
@system_arguments[:tag] = :button
|
117
118
|
@system_arguments[:type] = :button
|
118
119
|
@system_arguments[:role] = :tab
|
119
120
|
panel_id(panel_id)
|
121
|
+
# https://www.w3.org/TR/wai-aria-practices/#presentation_role
|
122
|
+
@wrapper_arguments[:role] = :presentation
|
120
123
|
else
|
121
124
|
@system_arguments[:tag] = :a
|
122
125
|
end
|
123
126
|
|
124
|
-
@wrapper_arguments = wrapper_arguments
|
125
127
|
@wrapper_arguments[:tag] = :li
|
126
|
-
@wrapper_arguments[:display] ||= :
|
128
|
+
@wrapper_arguments[:display] ||= :inline_flex
|
127
129
|
|
128
130
|
return unless @selected
|
129
131
|
|
@@ -41,7 +41,12 @@ module Primer
|
|
41
41
|
system_arguments.delete(:width)
|
42
42
|
end
|
43
43
|
|
44
|
-
cache_key = Primer::Octicon::Cache.get_key(
|
44
|
+
cache_key = Primer::Octicon::Cache.get_key(
|
45
|
+
symbol: icon_key,
|
46
|
+
size: size,
|
47
|
+
height: system_arguments[:height],
|
48
|
+
width: system_arguments[:width]
|
49
|
+
)
|
45
50
|
|
46
51
|
@system_arguments = system_arguments
|
47
52
|
@system_arguments[:tag] = :svg
|
@@ -2,7 +2,7 @@
|
|
2
2
|
|
3
3
|
module Primer
|
4
4
|
# Use `TabContainer` to create tabbed content with keyboard support. This component does not add any styles.
|
5
|
-
# It only provides the tab functionality. If you want styled Tabs you can look at <%= link_to_component(Primer::
|
5
|
+
# It only provides the tab functionality. If you want styled Tabs you can look at <%= link_to_component(Primer::Alpha::TabNav) %>.
|
6
6
|
#
|
7
7
|
# This component requires javascript.
|
8
8
|
class TabContainerComponent < Primer::Component
|
@@ -7,22 +7,23 @@ module Primer
|
|
7
7
|
# :nodoc:
|
8
8
|
module ClassNameHelper
|
9
9
|
def class_names(*args)
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
10
|
+
[].tap do |classes|
|
11
|
+
args.each do |class_name|
|
12
|
+
case class_name
|
13
|
+
when String
|
14
|
+
classes << class_name if class_name.present?
|
15
|
+
when Hash
|
16
|
+
class_name.each do |key, val|
|
17
|
+
classes << key if val
|
18
|
+
end
|
19
|
+
when Array
|
20
|
+
classes << class_names(*class_name).presence
|
19
21
|
end
|
20
|
-
when Array
|
21
|
-
classes << class_names(*class_name).presence
|
22
22
|
end
|
23
|
-
end
|
24
23
|
|
25
|
-
|
24
|
+
classes.compact!
|
25
|
+
classes.uniq!
|
26
|
+
end.join(" ")
|
26
27
|
end
|
27
28
|
end
|
28
29
|
end
|
@@ -9,8 +9,9 @@ module Primer
|
|
9
9
|
PRELOADED_ICONS = [:alert, :check, :"chevron-down", :paste, :clock, :"dot-fill", :info, :"kebab-horizontal", :link, :lock, :mail, :pencil, :plus, :question, :repo, :search, :"shield-lock", :star, :trash, :x].freeze
|
10
10
|
|
11
11
|
class << self
|
12
|
-
def get_key(
|
13
|
-
|
12
|
+
def get_key(**kwargs)
|
13
|
+
correct_key_args?(**kwargs)
|
14
|
+
kwargs.hash
|
14
15
|
end
|
15
16
|
|
16
17
|
def read(key)
|
@@ -36,6 +37,13 @@ module Primer
|
|
36
37
|
def preload!
|
37
38
|
PRELOADED_ICONS.each { |icon| Primer::OcticonComponent.new(icon: icon) }
|
38
39
|
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def correct_key_args?(symbol:, size:, width: nil, height: nil)
|
44
|
+
# This method does nothing but will raise an ArgumentError if the
|
45
|
+
# wrong args are passed.
|
46
|
+
end
|
39
47
|
end
|
40
48
|
end
|
41
49
|
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Primer
|
6
|
+
# Helper to share tab validation logic between components.
|
7
|
+
# The component will raise an error if there are 0 or 2+ selected tabs.
|
8
|
+
module TabNavHelper
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
EXTRA_ALIGN_DEFAULT = :left
|
12
|
+
EXTRA_ALIGN_OPTIONS = [EXTRA_ALIGN_DEFAULT, :right].freeze
|
13
|
+
|
14
|
+
def tab_nav_tab_classes(classes)
|
15
|
+
class_names(
|
16
|
+
"tabnav-tab",
|
17
|
+
classes
|
18
|
+
)
|
19
|
+
end
|
20
|
+
|
21
|
+
def tab_nav_classes(classes)
|
22
|
+
class_names(
|
23
|
+
"tabnav",
|
24
|
+
classes
|
25
|
+
)
|
26
|
+
end
|
27
|
+
|
28
|
+
def tab_nav_body_classes(classes)
|
29
|
+
class_names(
|
30
|
+
"tabnav-tabs",
|
31
|
+
classes
|
32
|
+
)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -16,12 +16,12 @@ module Primer
|
|
16
16
|
|
17
17
|
private
|
18
18
|
|
19
|
-
def
|
20
|
-
|
19
|
+
def aria_label_for_page_nav(label)
|
20
|
+
@system_arguments[:tag] == :nav ? @system_arguments[:"aria-label"] = label : @body_arguments[:"aria-label"] = label
|
21
21
|
end
|
22
22
|
|
23
|
-
def
|
24
|
-
return yield unless
|
23
|
+
def tab_container_wrapper(with_panel:, **system_arguments)
|
24
|
+
return yield unless with_panel
|
25
25
|
|
26
26
|
render Primer::TabContainerComponent.new(**system_arguments) do
|
27
27
|
yield if block_given?
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "active_support/concern"
|
4
|
+
|
5
|
+
module Primer
|
6
|
+
# Helper to share tab validation logic between components.
|
7
|
+
# The component will raise an error if there are 0 or 2+ selected tabs.
|
8
|
+
module UnderlineNavHelper
|
9
|
+
extend ActiveSupport::Concern
|
10
|
+
|
11
|
+
ALIGN_DEFAULT = :left
|
12
|
+
ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
|
13
|
+
|
14
|
+
ACTIONS_TAG_DEFAULT = :div
|
15
|
+
ACTIONS_TAG_OPTIONS = [ACTIONS_TAG_DEFAULT, :span].freeze
|
16
|
+
|
17
|
+
def underline_nav_classes(classes, align)
|
18
|
+
class_names(
|
19
|
+
classes,
|
20
|
+
"UnderlineNav",
|
21
|
+
"UnderlineNav--right" => align == :right
|
22
|
+
)
|
23
|
+
end
|
24
|
+
|
25
|
+
def underline_nav_body_classes(classes)
|
26
|
+
class_names(
|
27
|
+
"UnderlineNav-body",
|
28
|
+
classes,
|
29
|
+
"list-style-none"
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def underline_nav_action_classes(classes)
|
34
|
+
class_names("UnderlineNav-actions", classes)
|
35
|
+
end
|
36
|
+
|
37
|
+
def underline_nav_tab_classes(classes)
|
38
|
+
class_names(
|
39
|
+
"UnderlineNav-item",
|
40
|
+
classes
|
41
|
+
)
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -3,7 +3,6 @@
|
|
3
3
|
require_relative "flex"
|
4
4
|
require_relative "functional_background_colors"
|
5
5
|
require_relative "functional_border_colors"
|
6
|
-
require_relative "functional_text_colors"
|
7
6
|
require_relative "grid"
|
8
7
|
|
9
8
|
module Primer
|
@@ -55,11 +54,6 @@ module Primer
|
|
55
54
|
values: Primer::Classify::Grid::COL_VALUES
|
56
55
|
)
|
57
56
|
|
58
|
-
preload(
|
59
|
-
keys: [Primer::Classify::COLOR_KEY],
|
60
|
-
values: Primer::Classify::FunctionalTextColors::OPTIONS
|
61
|
-
)
|
62
|
-
|
63
57
|
preload(
|
64
58
|
keys: [Primer::Classify::BG_KEY],
|
65
59
|
values: Primer::Classify::FunctionalBackgroundColors::OPTIONS
|