primer_view_components 0.0.51 → 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 (77) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +159 -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.html.erb +15 -0
  8. data/app/components/primer/alpha/underline_nav.rb +137 -0
  9. data/app/components/primer/{underline_nav_component.html.erb → alpha/underline_panels.html.erb} +3 -8
  10. data/app/components/primer/alpha/underline_panels.rb +86 -0
  11. data/app/components/primer/base_component.rb +1 -1
  12. data/app/components/primer/beta/avatar_stack.rb +9 -9
  13. data/app/components/primer/{breadcrumb_component.html.erb → beta/breadcrumbs.html.erb} +2 -1
  14. data/app/components/primer/beta/breadcrumbs.rb +61 -0
  15. data/app/components/primer/beta/truncate.html.erb +5 -0
  16. data/app/components/primer/beta/truncate.rb +110 -0
  17. data/app/components/primer/border_box_component.rb +27 -1
  18. data/app/components/primer/clipboard_copy.rb +1 -1
  19. data/app/components/primer/dropdown.rb +7 -7
  20. data/app/components/primer/icon_button.rb +1 -1
  21. data/app/components/primer/navigation/tab_component.rb +8 -6
  22. data/app/components/primer/octicon_component.rb +6 -1
  23. data/app/components/primer/progress_bar_component.rb +0 -3
  24. data/app/components/primer/tab_container_component.rb +1 -1
  25. data/app/lib/primer/class_name_helper.rb +14 -13
  26. data/app/lib/primer/fetch_or_fallback_helper.rb +2 -0
  27. data/app/lib/primer/octicon/cache.rb +10 -2
  28. data/app/lib/primer/tab_nav_helper.rb +35 -0
  29. data/app/lib/primer/tabbed_component_helper.rb +5 -5
  30. data/app/lib/primer/underline_nav_helper.rb +44 -0
  31. data/app/lib/primer/view_helper.rb +1 -0
  32. data/lib/primer/classify/cache.rb +0 -6
  33. data/lib/primer/classify/flex.rb +1 -1
  34. data/lib/primer/classify/functional_colors.rb +1 -1
  35. data/lib/primer/classify/utilities.rb +17 -2
  36. data/lib/primer/classify/utilities.yml +35 -0
  37. data/lib/primer/classify/validation.rb +18 -0
  38. data/lib/primer/classify.rb +4 -13
  39. data/lib/primer/view_components/constants.rb +1 -1
  40. data/lib/primer/view_components/linters/argument_mappers/base.rb +34 -8
  41. data/lib/primer/view_components/linters/argument_mappers/button.rb +5 -6
  42. data/lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb +4 -3
  43. data/lib/primer/view_components/linters/argument_mappers/close_button.rb +43 -0
  44. data/lib/primer/view_components/linters/argument_mappers/flash.rb +32 -0
  45. data/lib/primer/view_components/linters/argument_mappers/helpers/erb_block.rb +48 -5
  46. data/lib/primer/view_components/linters/argument_mappers/label.rb +3 -4
  47. data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +5 -7
  48. data/lib/primer/view_components/linters/autocorrectable.rb +6 -4
  49. data/lib/primer/view_components/linters/{helpers.rb → base_linter.rb} +69 -29
  50. data/lib/primer/view_components/linters/button_component_migration_counter.rb +4 -3
  51. data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +3 -4
  52. data/lib/primer/view_components/linters/close_button_component_migration_counter.rb +110 -3
  53. data/lib/primer/view_components/linters/flash_component_migration_counter.rb +18 -3
  54. data/lib/primer/view_components/linters/label_component_migration_counter.rb +2 -3
  55. data/lib/primer/view_components/version.rb +1 -1
  56. data/lib/rubocop/config/default.yml +5 -0
  57. data/lib/rubocop/cop/primer/base_cop.rb +28 -0
  58. data/lib/rubocop/cop/primer/deprecated_arguments.rb +263 -0
  59. data/lib/rubocop/cop/primer/no_tag_memoize.rb +1 -0
  60. data/lib/rubocop/cop/primer/primer_octicon.rb +178 -0
  61. data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +4 -32
  62. data/lib/rubocop/cop/primer.rb +1 -2
  63. data/lib/tasks/coverage.rake +4 -0
  64. data/lib/tasks/docs.rake +10 -8
  65. data/lib/tasks/utilities.rake +7 -3
  66. data/lib/yard/docs_helper.rb +6 -3
  67. data/static/arguments.yml +82 -64
  68. data/static/classes.yml +10 -0
  69. data/static/constants.json +44 -30
  70. data/static/statuses.json +10 -6
  71. metadata +57 -18
  72. data/app/components/primer/auto_complete/auto_component.d.ts +0 -1
  73. data/app/components/primer/auto_complete/auto_component.js +0 -1
  74. data/app/components/primer/breadcrumb_component.rb +0 -57
  75. data/app/components/primer/tab_nav_component.rb +0 -151
  76. data/app/components/primer/underline_nav_component.rb +0 -187
  77. data/lib/primer/classify/functional_text_colors.rb +0 -64
@@ -13,6 +13,14 @@ module Primer
13
13
  }.freeze
14
14
  PADDING_SUGGESTION = "Perhaps you could consider using :padding options of #{PADDING_MAPPINGS.keys.to_sentence}?"
15
15
 
16
+ DEFAULT_ROW_SCHEME = :default
17
+ ROW_SCHEME_MAPPINGS = {
18
+ DEFAULT_ROW_SCHEME => "",
19
+ :neutral => "Box-row--gray",
20
+ :info => "Box-row--blue",
21
+ :warning => "Box-row--yellow"
22
+ }.freeze
23
+
16
24
  # Optional Header.
17
25
  #
18
26
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
@@ -54,11 +62,13 @@ module Primer
54
62
 
55
63
  # Use Rows to add rows with borders and maintain the same padding.
56
64
  #
65
+ # @param scheme [Symbol] Color scheme. <%= one_of(Primer::BorderBoxComponent::ROW_SCHEME_MAPPINGS.keys) %>
57
66
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
58
- renders_many :rows, lambda { |**system_arguments|
67
+ renders_many :rows, lambda { |scheme: DEFAULT_ROW_SCHEME, **system_arguments|
59
68
  system_arguments[:tag] = :li
60
69
  system_arguments[:classes] = class_names(
61
70
  "Box-row",
71
+ ROW_SCHEME_MAPPINGS[fetch_or_fallback(ROW_SCHEME_MAPPINGS.keys, scheme, DEFAULT_ROW_SCHEME)],
62
72
  system_arguments[:classes]
63
73
  )
64
74
 
@@ -102,6 +112,22 @@ module Primer
102
112
  # <% end %>
103
113
  # <% end %>
104
114
  #
115
+ # @example Row colors
116
+ # <%= render(Primer::BorderBoxComponent.new) do |component| %>
117
+ # <% component.row do %>
118
+ # Default
119
+ # <% end %>
120
+ # <% component.row(scheme: :neutral) do %>
121
+ # Neutral
122
+ # <% end %>
123
+ # <% component.row(scheme: :info) do %>
124
+ # Info
125
+ # <% end %>
126
+ # <% component.row(scheme: :warning) do %>
127
+ # Warning
128
+ # <% end %>
129
+ # <% end %>
130
+ #
105
131
  # @param padding [Symbol] <%= one_of(Primer::BorderBoxComponent::PADDING_MAPPINGS.keys) %>
106
132
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
107
133
  def initialize(padding: DEFAULT_PADDING, **system_arguments)
@@ -6,7 +6,7 @@ module Primer
6
6
  # @accessibility
7
7
  # Always set an accessible label to help the user interact with the component.
8
8
  class ClipboardCopy < Primer::Component
9
- status :alpha
9
+ status :beta
10
10
 
11
11
  # @example Default
12
12
  # <%= render(Primer::ClipboardCopy.new(value: "Text to copy", "aria-label": "Copy text to the system clipboard")) %>
@@ -28,7 +28,7 @@ module Primer
28
28
  # Dropdown
29
29
  # <% end %>
30
30
  #
31
- # <%= c.menu(header: "Options") do |menu|
31
+ # <% c.menu(header: "Options") do |menu|
32
32
  # menu.item { "Item 1" }
33
33
  # menu.item { "Item 2" }
34
34
  # menu.item { "Item 3" }
@@ -45,7 +45,7 @@ module Primer
45
45
  # Dropdown
46
46
  # <% end %>
47
47
  #
48
- # <%= c.menu(header: "Options") do |menu|
48
+ # <% c.menu(header: "Options") do |menu|
49
49
  # menu.item { "Item 1" }
50
50
  # menu.item { "Item 2" }
51
51
  # menu.item(divider: true)
@@ -63,7 +63,7 @@ module Primer
63
63
  # Dropdown
64
64
  # <% end %>
65
65
  #
66
- # <%= c.menu(header: "Options", direction: :s) do |menu|
66
+ # <% c.menu(header: "Options", direction: :s) do |menu|
67
67
  # menu.item { "Item 1" }
68
68
  # menu.item { "Item 2" }
69
69
  # menu.item { "Item 3" }
@@ -77,7 +77,7 @@ module Primer
77
77
  # Dropdown
78
78
  # <% end %>
79
79
  #
80
- # <%= c.menu(header: "Options") do |menu|
80
+ # <% c.menu(header: "Options") do |menu|
81
81
  # menu.item { "Item 1" }
82
82
  # menu.item { "Item 2" }
83
83
  # menu.item { "Item 3" }
@@ -91,7 +91,7 @@ module Primer
91
91
  # Dropdown
92
92
  # <% end %>
93
93
  #
94
- # <%= c.menu(header: "Options") do |menu|
94
+ # <% c.menu(header: "Options") do |menu|
95
95
  # menu.item { "Item 1" }
96
96
  # menu.item { "Item 2" }
97
97
  # menu.item { "Item 3" }
@@ -105,7 +105,7 @@ module Primer
105
105
  # Dropdown
106
106
  # <% end %>
107
107
  #
108
- # <%= c.menu(as: :list, header: "Options") do |menu|
108
+ # <% c.menu(as: :list, header: "Options") do |menu|
109
109
  # menu.item { "Item 1" }
110
110
  # menu.item { "Item 2" }
111
111
  # menu.item(divider: true)
@@ -120,7 +120,7 @@ module Primer
120
120
  # Dropdown
121
121
  # <% end %>
122
122
  #
123
- # <%= c.menu(header: "Options") do |menu|
123
+ # <% c.menu(header: "Options") do |menu|
124
124
  # menu.item(tag: :button) { "Item 1" }
125
125
  # menu.item(classes: "custom-class") { "Item 2" }
126
126
  # menu.item { "Item 3" }
@@ -42,7 +42,7 @@ module Primer
42
42
  # @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
43
43
  # @param box [Boolean] Whether the button is in a <%= link_to_component(Primer::BorderBoxComponent) %>. If `true`, the button will have the `Box-btn-octicon` class.
44
44
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
45
- def initialize(scheme: DEFAULT_SCHEME, icon:, box: false, **system_arguments)
45
+ def initialize(icon:, scheme: DEFAULT_SCHEME, box: false, **system_arguments)
46
46
  @icon = icon
47
47
 
48
48
  @system_arguments = system_arguments
@@ -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::TabNavComponent`
6
- # and `Primer::UnderlineNavComponent` and should not be used by itself.
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 `UnderlineNavComponent` 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|
@@ -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] ||= :flex
128
+ @wrapper_arguments[:display] ||= :inline_flex
127
129
 
128
130
  return unless @selected
129
131
 
@@ -142,7 +144,7 @@ module Primer
142
144
  end
143
145
 
144
146
  render(Primer::BaseComponent.new(**@wrapper_arguments)) do
145
- yield
147
+ yield if block_given?
146
148
  end
147
149
  end
148
150
 
@@ -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(symbol: icon_key, size: size, **system_arguments.slice(:height, :width))
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
@@ -11,9 +11,6 @@ module Primer
11
11
  # @param bg [Symbol] The background color
12
12
  # @param kwargs [Hash] The same arguments as <%= link_to_system_arguments_docs %>.
13
13
  renders_many :items, lambda { |percentage: 0, bg: :success_inverse, **system_arguments|
14
- percentage = percentage
15
- system_arguments = system_arguments
16
-
17
14
  system_arguments[:tag] = :span
18
15
  system_arguments[:bg] = bg
19
16
  system_arguments[:style] = join_style_arguments(system_arguments[:style], "width: #{percentage}%;")
@@ -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::TabNavComponent) %>.
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
- classes = []
11
-
12
- args.each do |class_name|
13
- case class_name
14
- when String
15
- classes << class_name if class_name.present?
16
- when Hash
17
- class_name.each do |key, val|
18
- classes << key if val
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
- classes.compact.uniq.join(" ")
24
+ classes.compact!
25
+ classes.uniq!
26
+ end.join(" ")
26
27
  end
27
28
  end
28
29
  end
@@ -48,6 +48,7 @@ module Primer
48
48
  end
49
49
  end
50
50
 
51
+ # rubocop:disable Style/OptionalBooleanParameter
51
52
  def fetch_or_fallback_boolean(given_value, fallback = false)
52
53
  if [true, false].include?(given_value)
53
54
  given_value
@@ -55,6 +56,7 @@ module Primer
55
56
  fallback
56
57
  end
57
58
  end
59
+ # rubocop:enable Style/OptionalBooleanParameter
58
60
 
59
61
  def silence_deprecations?
60
62
  Rails.application.config.primer_view_components.silence_deprecations
@@ -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(symbol:, size:, width: nil, height: nil)
13
- [symbol, size, width, height].join("_")
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,15 +16,15 @@ module Primer
16
16
 
17
17
  private
18
18
 
19
- def navigation_tag(with_panel)
20
- with_panel ? :div : :nav
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 wrapper(**system_arguments)
24
- return yield unless @with_panel
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
- yield
27
+ yield if block_given?
28
28
  end
29
29
  end
30
30
 
@@ -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
@@ -1,5 +1,6 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ # :nocov:
3
4
  module Primer
4
5
  # Module to allow shorthand calls for Primer components
5
6
  module ViewHelper
@@ -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
@@ -89,7 +89,7 @@ module Primer
89
89
  def justify_content(value, breakpoint)
90
90
  val = fetch_or_fallback(JUSTIFY_CONTENT_VALUES, value)
91
91
 
92
- formatted_value = val.to_s.gsub(/(flex\_|space\_)/, "")
92
+ formatted_value = val.to_s.gsub(/(flex_|space_)/, "")
93
93
  "flex#{breakpoint}-justify-#{formatted_value}"
94
94
  end
95
95