primer_view_components 0.0.54 → 0.0.55

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.
Files changed (35) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +37 -0
  3. data/app/components/primer/alpha/tab_nav.html.erb +11 -0
  4. data/app/components/primer/alpha/tab_nav.rb +130 -0
  5. data/app/components/primer/{tab_nav_component.html.erb → alpha/tab_panels.html.erb} +3 -8
  6. data/app/components/primer/alpha/tab_panels.rb +82 -0
  7. data/app/components/primer/alpha/underline_nav.rb +1 -7
  8. data/app/components/primer/alpha/underline_panels.html.erb +1 -1
  9. data/app/components/primer/base_component.rb +1 -1
  10. data/app/components/primer/beta/breadcrumbs.html.erb +2 -1
  11. data/app/components/primer/beta/breadcrumbs.rb +15 -13
  12. data/app/components/primer/navigation/tab_component.rb +2 -2
  13. data/app/components/primer/octicon_component.rb +6 -1
  14. data/app/components/primer/tab_container_component.rb +1 -1
  15. data/app/lib/primer/class_name_helper.rb +14 -13
  16. data/app/lib/primer/octicon/cache.rb +10 -2
  17. data/app/lib/primer/tab_nav_helper.rb +35 -0
  18. data/app/lib/primer/tabbed_component_helper.rb +3 -3
  19. data/lib/primer/classify/cache.rb +0 -6
  20. data/lib/primer/classify/utilities.rb +1 -1
  21. data/lib/primer/classify/utilities.yml +35 -0
  22. data/lib/primer/classify.rb +0 -5
  23. data/lib/primer/view_components/version.rb +1 -1
  24. data/lib/rubocop/cop/primer/base_cop.rb +28 -0
  25. data/lib/rubocop/cop/primer/deprecated_arguments.rb +1 -15
  26. data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +1 -15
  27. data/lib/tasks/docs.rake +5 -5
  28. data/lib/tasks/utilities.rake +2 -0
  29. data/static/arguments.yml +29 -36
  30. data/static/classes.yml +1 -0
  31. data/static/constants.json +16 -17
  32. data/static/statuses.json +2 -1
  33. metadata +22 -5
  34. data/app/components/primer/tab_nav_component.rb +0 -151
  35. data/lib/primer/classify/functional_text_colors.rb +0 -64
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c9b70049a9f24586f7b1239cdd97832cb9e813cc063ca475c77ae00ed448a6c4
4
- data.tar.gz: 8df167c58fa86039a008d301969af68f7efa8e4345d49abf269cb09734ec1841
3
+ metadata.gz: 24d9b6954280f4366b91f69fe7d29af41b8ce480b015a6d2f281c9e6c3bd4637
4
+ data.tar.gz: cae48c352697db57fd18b2712850cdc5a47da809449dcbd1f32398a777135cda
5
5
  SHA512:
6
- metadata.gz: 7c87327784f69a03b4636e2952c98da1feb4b5c47776c8e46cd423ae562d25aa061c99f0ff3ebee605984816db3b3c6209fd7ddb5ed0577a1ed7b1ff8a68bbc8
7
- data.tar.gz: c386eb3940ee79d8992b45168e18846863c6d503801674d13efe6ea8617cfc9d7a3957e3e324959c884d13bdd66113188ea23c9bcbf9dce00ff9eb54ce0deef3
6
+ metadata.gz: e334ce2c9e71f8b54f0a22d094a333ce1df7216a601885732c2a1f669e03d67f4b0e2d9799c39600edc33e9ef972949a02de1a8adc4081c702b14d4bfe6bacbc
7
+ data.tar.gz: 4640a31794a5e6df77bcf1a707758bb970d80a33afbcd42a812efd3ce3c9f032b7789de55f3ab0d74d7d8657c1d06f3965f926437cf609455f3db4b2c4a2bc6f
data/CHANGELOG.md CHANGED
@@ -30,6 +30,39 @@ The category for changes related to documentation, testing and tooling. Also, fo
30
30
 
31
31
  ## main
32
32
 
33
+ ## 0.0.55
34
+
35
+ ### Breaking changes
36
+
37
+ * `Primer::Breadcrumbs` requires `href`s for all items and no longer accepts the `selected` argument.
38
+
39
+ *Joel Hawksley*
40
+
41
+ * Split `TabNav` into `TabNav` and `TabPanels`.
42
+
43
+ *Kate Higa*
44
+
45
+ ### New
46
+
47
+ * Use the allocation_stats gem to count object allocations in our benchmarks.
48
+ * Improve performance of Octicon cache key construction.
49
+
50
+ *Cameron Dutro*
51
+
52
+ * Update `@primer/css` to `17.7.0` which includes a new argument for `word_break`
53
+
54
+ *Jon Rohan*
55
+
56
+ ### Misc
57
+
58
+ * Clean up extra constants in `UnderlineNav`.
59
+
60
+ *Kate Higa*
61
+
62
+ * Refactor some of the rubocop valid_node? logic into BaseCop class.
63
+
64
+ *Jon Rohan*
65
+
33
66
  ## 0.0.54
34
67
 
35
68
  ### Breaking changes
@@ -68,6 +101,10 @@ The category for changes related to documentation, testing and tooling. Also, fo
68
101
 
69
102
  *Manuel Puyol*
70
103
 
104
+ * Moving text color variables to Utilities class
105
+
106
+ *Jon Rohan*
107
+
71
108
  ### Bug fixes
72
109
 
73
110
  * Linters won't convert HTML special elements.
@@ -0,0 +1,11 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <%= extra if @align == :left %>
3
+
4
+ <%= render Primer::BaseComponent.new(**@body_arguments) do %>
5
+ <% tabs.each do |tab| %>
6
+ <%= tab %>
7
+ <% end %>
8
+ <% end %>
9
+
10
+ <%= extra if @align == :right %>
11
+ <% end %>
@@ -0,0 +1,130 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ # Use `TabNav` to style navigation with a tab-based selected state, typically used for navigation placed at the top of the page.
6
+ # For panel navigation, use <%= link_to_component(Primer::Alpha::TabPanels) %> instead.
7
+ #
8
+ # @accessibility
9
+ # - By default, `TabNav` renders links within a `<nav>` element. `<nav>` has an
10
+ # implicit landmark role of `navigation` which should be reserved for main links.
11
+ # For all other set of links, set tag to `:div`.
12
+ # - See <%= link_to_component(Primer::Navigation::TabComponent) %> for additional
13
+ # accessibility considerations.
14
+ class TabNav < Primer::Component
15
+ include Primer::TabbedComponentHelper
16
+ include Primer::TabNavHelper
17
+
18
+ status :alpha
19
+
20
+ BODY_TAG_DEFAULT = :ul
21
+
22
+ TAG_DEFAULT = :nav
23
+ TAG_OPTIONS = [TAG_DEFAULT, :div].freeze
24
+
25
+ # Tabs to be rendered. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
26
+ #
27
+ # @param selected [Boolean] Whether the tab is selected.
28
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
29
+ renders_many :tabs, lambda { |selected: false, **system_arguments|
30
+ system_arguments[:classes] = tab_nav_tab_classes(system_arguments[:classes])
31
+ Primer::Navigation::TabComponent.new(
32
+ list: true,
33
+ selected: selected,
34
+ **system_arguments
35
+ )
36
+ }
37
+
38
+ # Renders extra content to the `TabNav`. This will be rendered after the tabs.
39
+ #
40
+ # @param align [Symbol] <%= one_of(Primer::Alpha::TabNav::EXTRA_ALIGN_OPTIONS) %>
41
+ renders_one :extra, lambda { |align: EXTRA_ALIGN_DEFAULT, &block|
42
+ @align = fetch_or_fallback(EXTRA_ALIGN_OPTIONS, align, EXTRA_ALIGN_DEFAULT)
43
+
44
+ view_context.capture { block&.call }
45
+ }
46
+
47
+ # @example Default with `<nav>`
48
+ # @description
49
+ # `<nav>` is a landmark and should be reserved for main navigation links. See <%= link_to_accessibility %>.
50
+ # @code
51
+ # <%= render(Primer::Alpha::TabNav.new(label: "Default")) do |c| %>
52
+ # <% c.tab(selected: true, href: "#") { "Tab 1" } %>
53
+ # <% c.tab(href: "#") { "Tab 2" } %>
54
+ # <% c.tab(href: "#") { "Tab 3" } %>
55
+ # <% end %>
56
+ #
57
+ # @example Default with `<div>`
58
+ # <%= render(Primer::Alpha::TabNav.new(label: "Default")) do |c| %>
59
+ # <% c.tab(selected: true, href: "#") { "Tab 1" } %>
60
+ # <% c.tab(href: "#") { "Tab 2" } %>
61
+ # <% c.tab(href: "#") { "Tab 3" } %>
62
+ # <% end %>
63
+ #
64
+ # @example With icons and counters
65
+ # <%= render(Primer::Alpha::TabNav.new(label: "With icons and counters")) do |component| %>
66
+ # <% component.tab(href: "#", selected: true) do |t| %>
67
+ # <% t.icon(icon: :star) %>
68
+ # <% t.text { "Item 1" } %>
69
+ # <% end %>
70
+ # <% component.tab(href: "#") do |t| %>
71
+ # <% t.icon(icon: :star) %>
72
+ # <% t.text { "Item 2" } %>
73
+ # <% t.counter(count: 10) %>
74
+ # <% end %>
75
+ # <% component.tab(href: "#") do |t| %>
76
+ # <% t.text { "Item 3" } %>
77
+ # <% t.counter(count: 10) %>
78
+ # <% end %>
79
+ # <% end %>
80
+ #
81
+ # @example With extra content
82
+ # <%= render(Primer::Alpha::TabNav.new(label: "With extra content")) do |c| %>
83
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
84
+ # <% c.tab(href: "#") { "Tab 2" } %>
85
+ # <% c.tab(href: "#") { "Tab 3" } %>
86
+ # <% c.extra do %>
87
+ # <%= render(Primer::ButtonComponent.new(float: :right)) { "Button" } %>
88
+ # <% end %>
89
+ # <% end %>
90
+ #
91
+ # @example Adding extra content after the tabs
92
+ # <%= render(Primer::Alpha::TabNav.new(label: "Adding extra content after the tabs", display: :flex, body_arguments: { flex: 1 })) do |c| %>
93
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
94
+ # <% c.tab(href: "#") { "Tab 2" } %>
95
+ # <% c.tab(href: "#") { "Tab 3" } %>
96
+ # <% c.extra(align: :right) do %>
97
+ # <div>
98
+ # <%= render(Primer::ButtonComponent.new) { "Button" } %>
99
+ # </div>
100
+ # <% end %>
101
+ # <% end %>
102
+ #
103
+ # @example Customizing the body
104
+ # <%= render(Primer::Alpha::TabNav.new(label: "Default", body_arguments: { classes: "custom-class", border: true, border_color: :info })) do |c| %>
105
+ # <% c.tab(selected: true, href: "#") { "Tab 1" }%>
106
+ # <% c.tab(href: "#") { "Tab 2" } %>
107
+ # <% c.tab(href: "#") { "Tab 3" } %>
108
+ # <% end %>
109
+ #
110
+ # @param tag [Symbol] <%= one_of(Primer::Alpha::TabNav::TAG_OPTIONS) %>
111
+ # @param label [String] Sets an `aria-label` that helps assistive technology users understand the purpose of the links, and distinguish it from similar elements.
112
+ # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
113
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
114
+ def initialize(label:, tag: TAG_DEFAULT, body_arguments: {}, **system_arguments)
115
+ @align = EXTRA_ALIGN_DEFAULT
116
+ @system_arguments = system_arguments
117
+ @body_arguments = body_arguments
118
+
119
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT)
120
+ @system_arguments[:classes] = tab_nav_classes(system_arguments[:classes])
121
+
122
+ @body_arguments = body_arguments
123
+ @body_arguments[:tag] = BODY_TAG_DEFAULT
124
+ @body_arguments[:classes] = tab_nav_body_classes(system_arguments[:classes])
125
+
126
+ aria_label_for_page_nav(label)
127
+ end
128
+ end
129
+ end
130
+ end
@@ -1,19 +1,14 @@
1
- <%= wrapper(with_panel: @with_panel, **@wrapper_arguments) do %>
1
+ <%= tab_container_wrapper(with_panel: true, **@wrapper_arguments) do %>
2
2
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
3
3
  <%= extra if @align == :left %>
4
-
5
4
  <%= render Primer::BaseComponent.new(**@body_arguments) do %>
6
5
  <% tabs.each do |tab| %>
7
6
  <%= tab %>
8
7
  <% end %>
9
8
  <% end %>
10
-
11
9
  <%= extra if @align == :right %>
12
10
  <% end %>
13
-
14
- <% if @with_panel %>
15
- <% tabs.each do |tab| %>
16
- <%= tab.panel %>
17
- <% end %>
11
+ <% tabs.each do |tab| %>
12
+ <%= tab.panel %>
18
13
  <% end %>
19
14
  <% end %>
@@ -0,0 +1,82 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Alpha
5
+ # Use `TabPanels` for tabs with panel navigation.
6
+ class TabPanels < Primer::Component
7
+ include Primer::TabbedComponentHelper
8
+ include Primer::TabNavHelper
9
+
10
+ status :alpha
11
+
12
+ BODY_TAG_DEFAULT = :ul
13
+
14
+ TAG_DEFAULT = :nav
15
+ TAG_OPTIONS = [TAG_DEFAULT, :div].freeze
16
+
17
+ # Tabs to be rendered. For more information, refer to <%= link_to_component(Primer::Navigation::TabComponent) %>.
18
+ #
19
+ # @param id [String] Unique ID of tab.
20
+ # @param selected [Boolean] Whether the tab is selected.
21
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
22
+ renders_many :tabs, lambda { |id:, selected: false, **system_arguments|
23
+ system_arguments[:id] = id
24
+ system_arguments[:classes] = tab_nav_tab_classes(system_arguments[:classes])
25
+
26
+ Primer::Navigation::TabComponent.new(
27
+ selected: selected,
28
+ with_panel: true,
29
+ list: true,
30
+ panel_id: "panel-#{id}",
31
+ **system_arguments
32
+ )
33
+ }
34
+
35
+ # Renders extra content to the `TabPanels`. This will be rendered after the tabs.
36
+ #
37
+ # @param align [Symbol] <%= one_of(Primer::Alpha::TabNav::EXTRA_ALIGN_OPTIONS) %>
38
+ renders_one :extra, lambda { |align: EXTRA_ALIGN_DEFAULT, &block|
39
+ @align = fetch_or_fallback(EXTRA_ALIGN_OPTIONS, align, EXTRA_ALIGN_DEFAULT)
40
+
41
+ view_context.capture { block&.call }
42
+ }
43
+
44
+ # @example Default
45
+ # <%= render(Primer::Alpha::TabPanels.new(label: "With panels")) do |component| %>
46
+ # <% component.tab(id: "tab-1", selected: true) do |t| %>
47
+ # <% t.text { "Tab 1" } %>
48
+ # <% t.panel do %>
49
+ # Panel 1
50
+ # <% end %>
51
+ # <% end %>
52
+ # <% component.tab(id: "tab-2") do |t| %>
53
+ # <% t.text { "Tab 2" } %>
54
+ # <% t.panel do %>
55
+ # Panel 2
56
+ # <% end %>
57
+ # <% end %>
58
+ # <% end %>
59
+ #
60
+ # @param label [String] Sets an `aria-label` that helps assistive technology users understand the purpose of the tabs.
61
+ # @param align [Symbol] <%= one_of(Primer::TabNavHelper::EXTRA_ALIGN_OPTIONS) %> - Defaults to <%= Primer::TabNavHelper::EXTRA_ALIGN_DEFAULT %>
62
+ # @param body_arguments [Hash] <%= link_to_system_arguments_docs %> for the body wrapper.
63
+ # @param wrapper_arguments [Hash] <%= link_to_system_arguments_docs %> for the `TabContainer` wrapper.
64
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
65
+ def initialize(label:, body_arguments: {}, wrapper_arguments: {}, **system_arguments)
66
+ @align = EXTRA_ALIGN_DEFAULT
67
+ @wrapper_arguments = wrapper_arguments
68
+
69
+ @system_arguments = system_arguments
70
+ @system_arguments[:tag] = :div
71
+ @system_arguments[:classes] = tab_nav_classes(@system_arguments[:classes])
72
+
73
+ @body_arguments = body_arguments
74
+ @body_arguments[:tag] = :ul
75
+ @body_arguments[:classes] = tab_nav_body_classes(@body_arguments[:classes])
76
+
77
+ @body_arguments[:role] = :tablist
78
+ @body_arguments[:"aria-label"] = label
79
+ end
80
+ end
81
+ end
82
+ end
@@ -17,17 +17,11 @@ module Primer
17
17
  include Primer::TabbedComponentHelper
18
18
  include Primer::UnderlineNavHelper
19
19
 
20
- ALIGN_DEFAULT = :left
21
- ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
22
-
23
20
  BODY_TAG_DEFAULT = :ul
24
21
 
25
22
  TAG_DEFAULT = :nav
26
23
  TAG_OPTIONS = [TAG_DEFAULT, :div].freeze
27
24
 
28
- ACTIONS_TAG_DEFAULT = :div
29
- ACTIONS_TAG_OPTIONS = [ACTIONS_TAG_DEFAULT, :span].freeze
30
-
31
25
  # Use the tabs to list page links.
32
26
  #
33
27
  # @param selected [Boolean] Whether the tab is selected.
@@ -130,7 +124,7 @@ module Primer
130
124
  @body_arguments[:tag] = :ul
131
125
  @body_arguments[:classes] = underline_nav_body_classes(@body_arguments[:classes])
132
126
 
133
- @system_arguments[:tag] == :nav ? @system_arguments[:"aria-label"] = label : @body_arguments[:"aria-label"] = label
127
+ aria_label_for_page_nav(label)
134
128
  end
135
129
 
136
130
  private
@@ -1,4 +1,4 @@
1
- <%= wrapper(with_panel: true, **@wrapper_arguments) do %>
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 %>
@@ -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::FunctionalTextColors::OPTIONS) %> |
68
+ # | `color` | Symbol | Text color. <%= one_of(Primer::Classify::Utilities.mappings(:color)) %> |
69
69
  #
70
70
  # ## Flex
71
71
  #
@@ -1,6 +1,7 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
2
  <ol>
3
- <% items.each do |item| %>
3
+ <% items.each_with_index do |item, index| %>
4
+ <% item.selected = index == items.length - 1 %>
4
5
  <%= item %>
5
6
  <% end %>
6
7
  </ol>
@@ -2,14 +2,11 @@
2
2
 
3
3
  module Primer
4
4
  module Beta
5
- # Use `Breadcrumb` to display page hierarchy within a section of the site. All of the items in the breadcrumb "trail" are links except for the final item, which is a plain string indicating the current page.
5
+ # Use `Breadcrumbs` to display page hierarchy.
6
6
  class Breadcrumbs < Primer::Component
7
7
  status :beta
8
8
 
9
- # _Note: if both `href` and `selected: true` are passed in, `href` will be ignored and the item will not be rendered as a link._
10
- #
11
9
  # @param href [String] The URL to link to.
12
- # @param selected [Boolean] Whether or not the item is selected and not rendered as a link.
13
10
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
14
11
  renders_many :items, "Item"
15
12
 
@@ -17,7 +14,7 @@ module Primer
17
14
  # <%= render(Primer::Beta::Breadcrumbs.new) do |component| %>
18
15
  # <% component.item(href: "/") do %>Home<% end %>
19
16
  # <% component.item(href: "/about") do %>About<% end %>
20
- # <% component.item(selected: true) do %>Team<% end %>
17
+ # <% component.item(href: "/about/team") do %>Team<% end %>
21
18
  # <% end %>
22
19
  #
23
20
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -34,23 +31,28 @@ module Primer
34
31
  # This component is part of `Primer::Beta::Breadcrumbs` and should not be
35
32
  # used as a standalone component.
36
33
  class Item < Primer::Component
37
- def initialize(href: nil, selected: false, **system_arguments)
34
+ attr_accessor :selected, :href
35
+
36
+ def initialize(href:, **system_arguments)
38
37
  @href = href
39
38
  @system_arguments = system_arguments
39
+ @selected = false
40
40
 
41
- @href = nil if selected
42
41
  @system_arguments[:tag] = :li
43
- @system_arguments[:"aria-current"] = "page" if selected
44
42
  @system_arguments[:classes] = "breadcrumb-item #{@system_arguments[:classes]}"
45
43
  end
46
44
 
47
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
+
48
54
  render(Primer::BaseComponent.new(**@system_arguments)) do
49
- if @href.present?
50
- render(Primer::LinkComponent.new(href: @href)) { content }
51
- else
52
- content
53
- end
55
+ render(Primer::LinkComponent.new(**link_arguments)) { content }
54
56
  end
55
57
  end
56
58
  end
@@ -2,7 +2,7 @@
2
2
 
3
3
  module Primer
4
4
  module Navigation
5
- # This component is part of navigation components such as `Primer::TabNavComponent`
5
+ # This component is part of navigation components such as `Primer::Alpha::TabNav`
6
6
  # and `Primer::Alpha::UnderlineNav` and should not be used by itself.
7
7
  #
8
8
  # @accessibility
@@ -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 `UnderlineNav` and `TabNavComponent` implementations for examples.
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|