primer_view_components 0.0.9 → 0.0.14

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +31 -1
  3. data/README.md +2 -175
  4. data/app/components/primer/avatar_component.rb +22 -11
  5. data/app/components/primer/base_component.rb +56 -11
  6. data/app/components/primer/blankslate_component.html.erb +1 -1
  7. data/app/components/primer/blankslate_component.rb +71 -116
  8. data/app/components/primer/border_box_component.html.erb +5 -5
  9. data/app/components/primer/border_box_component.rb +45 -33
  10. data/app/components/primer/box_component.rb +6 -4
  11. data/app/components/primer/breadcrumb_component.html.erb +2 -2
  12. data/app/components/primer/breadcrumb_component.rb +23 -30
  13. data/app/components/primer/button_component.rb +26 -9
  14. data/app/components/primer/component.rb +1 -0
  15. data/app/components/primer/counter_component.rb +13 -9
  16. data/app/components/primer/details_component.html.erb +1 -1
  17. data/app/components/primer/details_component.rb +18 -18
  18. data/app/components/primer/dropdown_menu_component.html.erb +1 -1
  19. data/app/components/primer/dropdown_menu_component.rb +6 -6
  20. data/app/components/primer/flash_component.html.erb +2 -2
  21. data/app/components/primer/flash_component.rb +42 -12
  22. data/app/components/primer/flex_component.rb +5 -5
  23. data/app/components/primer/flex_item_component.rb +5 -5
  24. data/app/components/primer/heading_component.rb +4 -4
  25. data/app/components/primer/label_component.rb +37 -14
  26. data/app/components/primer/layout_component.html.erb +1 -1
  27. data/app/components/primer/layout_component.rb +22 -5
  28. data/app/components/primer/link_component.rb +17 -7
  29. data/app/components/primer/octicon_component.rb +20 -7
  30. data/app/components/primer/popover_component.html.erb +1 -1
  31. data/app/components/primer/popover_component.rb +61 -23
  32. data/app/components/primer/progress_bar_component.html.erb +2 -2
  33. data/app/components/primer/progress_bar_component.rb +40 -30
  34. data/app/components/primer/slot.rb +1 -0
  35. data/app/components/primer/spinner_component.html.erb +6 -0
  36. data/app/components/primer/spinner_component.rb +39 -0
  37. data/app/components/primer/state_component.rb +26 -14
  38. data/app/components/primer/subhead_component.html.erb +4 -4
  39. data/app/components/primer/subhead_component.rb +68 -43
  40. data/app/components/primer/text_component.rb +10 -4
  41. data/app/components/primer/timeline_item_component.html.erb +4 -4
  42. data/app/components/primer/timeline_item_component.rb +48 -24
  43. data/app/components/primer/underline_nav_component.html.erb +1 -1
  44. data/app/components/primer/underline_nav_component.rb +5 -5
  45. data/app/components/primer/view_components.rb +1 -0
  46. data/lib/primer/classify.rb +2 -4
  47. data/lib/primer/view_components/version.rb +1 -1
  48. metadata +4 -2
@@ -1,5 +1,5 @@
1
- <%= render Primer::BaseComponent.new(**@kwargs) do %>
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
2
  <% items.each do |item| %>
3
- <%= render Primer::BaseComponent.new(**item.kwargs) %>
3
+ <%= render Primer::BaseComponent.new(**item.system_arguments) %>
4
4
  <% end %>
5
5
  <% end %>
@@ -1,23 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- ##
4
- # Use progress components to visualize task completion.
5
-
6
- ## Basic example
7
- #
8
- # The `Primer::ProgressBarComponent` can take the following arguments:
9
- #
10
- # 1. `size` (string). Can be "small" or "large". Increases the height of the progress bar.
11
- #
12
- # The `Primer::ProgressBarComponent` uses the [Slots API](https://github.com/github/view_component#slots-experimental) and at least one slot is required for the component to render. Each slot accepts a `percentage` parameter, which is used to set the width of the completed bar.
13
- #
14
- # ```ruby
15
- # <%= render(Primer::ProgressBarComponent.new(size: :small)) do |component| %>
16
- # <% component.slot(:item, bg: :blue-4, percentage: 50) %>
17
- # <% end %>
18
- # ```
19
- ##
20
3
  module Primer
4
+ # Use ProgressBar to visualize task completion.
21
5
  class ProgressBarComponent < Primer::Component
22
6
  include ViewComponent::Slotable
23
7
 
@@ -32,15 +16,38 @@ module Primer
32
16
  }.freeze
33
17
 
34
18
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
35
-
36
- def initialize(size: SIZE_DEFAULT, percentage: 0, **kwargs)
37
- @kwargs = kwargs
38
- @kwargs[:classes] = class_names(
39
- @kwargs[:classes],
19
+ # @example 20|Default
20
+ # <%= render(Primer::ProgressBarComponent.new) do |component| %>
21
+ # <% component.slot(:item, percentage: 25) %>
22
+ # <% end %>
23
+ #
24
+ # @example 20|Small
25
+ # <%= render(Primer::ProgressBarComponent.new(size: :small)) do |component| %>
26
+ # <% component.slot(:item, bg: :blue_4, percentage: 50) %>
27
+ # <% end %>
28
+ #
29
+ # @example 30|Large
30
+ # <%= render(Primer::ProgressBarComponent.new(size: :large)) do |component| %>
31
+ # <% component.slot(:item, bg: :red_4, percentage: 75) %>
32
+ # <% end %>
33
+ #
34
+ # @example 20|Multiple items
35
+ # <%= render(Primer::ProgressBarComponent.new) do |component| %>
36
+ # <% component.slot(:item, percentage: 10) %>
37
+ # <% component.slot(:item, bg: :blue_4, percentage: 20) %>
38
+ # <% component.slot(:item, bg: :red_4, percentage: 30) %>
39
+ # <% end %>
40
+ #
41
+ # @param size [Symbol] <%= one_of(Primer::ProgressBarComponent::SIZE_OPTIONS) %> Increases height.
42
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
43
+ def initialize(size: SIZE_DEFAULT, **system_arguments)
44
+ @system_arguments = system_arguments
45
+ @system_arguments[:classes] = class_names(
46
+ @system_arguments[:classes],
40
47
  "Progress",
41
48
  SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)]
42
49
  )
43
- @kwargs[:tag] = :span
50
+ @system_arguments[:tag] = :span
44
51
 
45
52
  end
46
53
 
@@ -50,16 +57,19 @@ module Primer
50
57
 
51
58
  class Item < ViewComponent::Slot
52
59
  include ClassNameHelper
53
- attr_reader :kwargs
60
+ attr_reader :system_arguments
54
61
 
55
- def initialize(percentage: 0, bg: :green, **kwargs)
62
+ # @param percentage [Integer] Percentage completion of item.
63
+ # @param bg [Symbol] Color of item.
64
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
65
+ def initialize(percentage: 0, bg: :green, **system_arguments)
56
66
  @percentage = percentage
57
- @kwargs = kwargs
67
+ @system_arguments = system_arguments
58
68
 
59
- @kwargs[:tag] = :span
60
- @kwargs[:bg] = bg
61
- @kwargs[:style] = "width: #{@percentage}%;"
62
- @kwargs[:classes] = class_names("Progress-item", @kwargs[:classes])
69
+ @system_arguments[:tag] = :span
70
+ @system_arguments[:bg] = bg
71
+ @system_arguments[:style] = "width: #{@percentage}%;"
72
+ @system_arguments[:classes] = class_names("Progress-item", @system_arguments[:classes])
63
73
  end
64
74
  end
65
75
  end
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # @private
4
5
  class Slot < ViewComponent::Slot
5
6
  include ClassNameHelper
6
7
  include FetchOrFallbackHelper
@@ -0,0 +1,6 @@
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
+ <circle cx="8" cy="8" r="7" stroke="currentColor" stroke-opacity="0.25" stroke-width="2" vector-effect="non-scaling-stroke" />
3
+ <path d="M15 8a7.002 7.002 0 00-7-7" stroke="currentColor" stroke-width="2" stroke-linecap="round" vector-effect="non-scaling-stroke">
4
+ <animateTransform attributeName="transform" type="rotate" from="0 8 8" to="360 8 8" dur="1s" repeatCount="indefinite" />
5
+ </path>
6
+ <% end %>
@@ -0,0 +1,39 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use Primer::SpinnerComponent to let users know that content is being loaded.
5
+ class SpinnerComponent < Primer::Component
6
+
7
+ DEFAULT_SIZE = :medium
8
+ SIZE_MAPPINGS = {
9
+ :small => 16,
10
+ DEFAULT_SIZE => 32,
11
+ :large => 64,
12
+ }.freeze
13
+ SIZE_OPTIONS = SIZE_MAPPINGS.keys
14
+ # Setting `box-sizing: content-box` allows consumers to add padding
15
+ # to the spinner without shrinking the icon
16
+ DEFAULT_STYLE = "box-sizing: content-box; color: var(--color-icon-primary);"
17
+
18
+ #
19
+ # @example 48|Default
20
+ # <%= render(Primer::SpinnerComponent.new) %>
21
+ #
22
+ # @example 32|Small
23
+ # <%= render(Primer::SpinnerComponent.new(size: :small)) %>
24
+ #
25
+ # @example 80|Large
26
+ # <%= render(Primer::SpinnerComponent.new(size: :large)) %>
27
+ #
28
+ # @param size [Symbol] <%= one_of(Primer::SpinnerComponent::SIZE_MAPPINGS) %>
29
+ def initialize(size: DEFAULT_SIZE, style: DEFAULT_STYLE, **system_arguments)
30
+ @system_arguments = system_arguments
31
+ @system_arguments[:tag] = :svg
32
+ @system_arguments[:width] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
33
+ @system_arguments[:height] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
34
+ @system_arguments[:viewBox] = "0 0 16 16"
35
+ @system_arguments[:fill] = :none
36
+ @system_arguments[:style] = DEFAULT_STYLE unless style.nil?
37
+ end
38
+ end
39
+ end
@@ -1,14 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # Component for rendering the status of an item.
4
5
  class StateComponent < Primer::Component
5
- # Component for rendering the status of an item
6
- #
7
- # title(string): (required) title attribute
8
- # color(symbol): label background color
9
- # size(symbol): label size
10
- # counter(integer): counter value
11
- # **args(hash): utility parameters for Primer::Classify
12
6
  COLOR_DEFAULT = :default
13
7
  COLOR_MAPPINGS = {
14
8
  COLOR_DEFAULT => "",
@@ -28,18 +22,36 @@ module Primer
28
22
  TAG_DEFAULT = :span
29
23
  TAG_OPTIONS = [TAG_DEFAULT, :div, :a]
30
24
 
25
+ # @example 40|Default
26
+ # <%= render(Primer::StateComponent.new(title: "title")) { "State" } %>
27
+ #
28
+ # @example 40|Colors
29
+ # <%= render(Primer::StateComponent.new(title: "title")) { "Default" } %>
30
+ # <%= render(Primer::StateComponent.new(title: "title", color: :green)) { "Green" } %>
31
+ # <%= render(Primer::StateComponent.new(title: "title", color: :red)) { "Red" } %>
32
+ # <%= render(Primer::StateComponent.new(title: "title", color: :purple)) { "Purple" } %>
33
+ #
34
+ # @example 40|Sizes
35
+ # <%= render(Primer::StateComponent.new(title: "title")) { "Default" } %>
36
+ # <%= render(Primer::StateComponent.new(title: "title", size: :small)) { "Small" } %>
37
+ #
38
+ # @param title [String] `title` HTML attribute.
39
+ # @param color [Symbol] Background color. <%= one_of(Primer::StateComponent::COLOR_OPTIONS) %>
40
+ # @param tag [Symbol] HTML tag for element. <%= one_of(Primer::StateComponent::TAG_OPTIONS) %>
41
+ # @param size [Symbol] <%= one_of(Primer::StateComponent::SIZE_OPTIONS) %>
42
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
31
43
  def initialize(
32
44
  title:,
33
45
  color: COLOR_DEFAULT,
34
46
  tag: TAG_DEFAULT,
35
47
  size: SIZE_DEFAULT,
36
- **kwargs
48
+ **system_arguments
37
49
  )
38
- @kwargs = kwargs
39
- @kwargs[:title] = title
40
- @kwargs[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT)
41
- @kwargs[:classes] = class_names(
42
- @kwargs[:classes],
50
+ @system_arguments = system_arguments
51
+ @system_arguments[:title] = title
52
+ @system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, TAG_DEFAULT)
53
+ @system_arguments[:classes] = class_names(
54
+ @system_arguments[:classes],
43
55
  "State",
44
56
  COLOR_MAPPINGS[fetch_or_fallback(COLOR_OPTIONS, color, COLOR_DEFAULT)],
45
57
  SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, SIZE_DEFAULT)]
@@ -47,7 +59,7 @@ module Primer
47
59
  end
48
60
 
49
61
  def call
50
- render(Primer::BaseComponent.new(**@kwargs)) { content }
62
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
51
63
  end
52
64
  end
53
65
  end
@@ -1,16 +1,16 @@
1
- <%= render Primer::BaseComponent.new(**@kwargs) do %>
1
+ <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
2
  <% if heading.present? %>
3
- <%= render Primer::BaseComponent.new(**heading.kwargs) do %>
3
+ <%= render Primer::BaseComponent.new(**heading.system_arguments) do %>
4
4
  <%= heading.content %>
5
5
  <% end %>
6
6
  <% end %>
7
7
  <% if actions.present? %>
8
- <%= render Primer::BaseComponent.new(**actions.kwargs) do %>
8
+ <%= render Primer::BaseComponent.new(**actions.system_arguments) do %>
9
9
  <%= actions.content %>
10
10
  <% end %>
11
11
  <% end %>
12
12
  <% if description.present? %>
13
- <%= render Primer::BaseComponent.new(**description.kwargs) do %>
13
+ <%= render Primer::BaseComponent.new(**description.system_arguments) do %>
14
14
  <%= description.content %>
15
15
  <% end %>
16
16
  <% end %>
@@ -1,26 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- # This component consists of a .Subhead container, which has a light gray bottom border.
4
-
5
- # Use a heading element whenever possible as they can be
6
- # used as navigation for assistive technologies, and avoid skipping levels.
7
-
8
- # ## Basic example
9
-
10
- # The `Primer::SubheadComponent` can take the following arguments:
11
-
12
- # 1. `heading` (string). The heading to be rendered.
13
- # 2. `actions` (content). Slot to render any actions to the right of heading.
14
- # 3. `description` (string). Slot to render description under the heading.
15
-
16
- # ```erb
17
- # <%= Primer::SubheadComponent.new(heading: "Hello world")) do |component| %>
18
- # <% component.slot(:actions) do %>
19
- # My Actions
20
- # <% end %>
21
- # <% end %>
22
- # ```
23
3
  module Primer
4
+ # Use the Subhead component for page headings.
24
5
  class SubheadComponent < Primer::Component
25
6
  include ViewComponent::Slotable
26
7
 
@@ -28,18 +9,58 @@ module Primer
28
9
  with_slot :actions, class_name: "Actions"
29
10
  with_slot :description, class_name: "Description"
30
11
 
31
- def initialize(spacious: false, hide_border: false, **kwargs)
32
- @kwargs = kwargs
33
-
34
- @kwargs[:tag] = :div
35
- @kwargs[:classes] =
12
+ # @example 95|Default
13
+ # <%= render(Primer::SubheadComponent.new) do |component| %>
14
+ # <% component.slot(:heading) do %>
15
+ # My Heading
16
+ # <% end %>
17
+ # <% component.slot(:description) do %>
18
+ # My Description
19
+ # <% end %>
20
+ # <% end %>
21
+ #
22
+ # @example 95|Without border
23
+ # <%= render(Primer::SubheadComponent.new(hide_border: true)) do |component| %>
24
+ # <% component.slot(:heading) do %>
25
+ # My Heading
26
+ # <% end %>
27
+ # <% component.slot(:description) do %>
28
+ # My Description
29
+ # <% end %>
30
+ # <% end %>
31
+ #
32
+ # @example 95|With actions
33
+ # <%= render(Primer::SubheadComponent.new) do |component| %>
34
+ # <% component.slot(:heading) do %>
35
+ # My Heading
36
+ # <% end %>
37
+ # <% component.slot(:description) do %>
38
+ # My Description
39
+ # <% end %>
40
+ # <% component.slot(:actions) do %>
41
+ # <%= render(
42
+ # Primer::ButtonComponent.new(
43
+ # tag: :a, href: "http://www.google.com", button_type: :danger
44
+ # )
45
+ # ) { "Action" } %>
46
+ # <% end %>
47
+ # <% end %>
48
+ #
49
+ # @param spacious [Boolean] Whether to add spacing to the Subhead.
50
+ # @param hide_border [Boolean] Whether to hide the border under the heading.
51
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
52
+ def initialize(spacious: false, hide_border: false, **system_arguments)
53
+ @system_arguments = system_arguments
54
+
55
+ @system_arguments[:tag] = :div
56
+ @system_arguments[:classes] =
36
57
  class_names(
37
- @kwargs[:classes],
58
+ @system_arguments[:classes],
38
59
  "Subhead hx_Subhead--responsive",
39
60
  "Subhead--spacious": spacious,
40
61
  "border-bottom-0": hide_border
41
62
  )
42
- @kwargs[:mb] ||= hide_border ? 0 : nil
63
+ @system_arguments[:mb] ||= hide_border ? 0 : nil
43
64
  end
44
65
 
45
66
  def render?
@@ -49,13 +70,15 @@ module Primer
49
70
  class Heading < ViewComponent::Slot
50
71
  include ClassNameHelper
51
72
 
52
- attr_reader :kwargs
73
+ attr_reader :system_arguments
53
74
 
54
- def initialize(danger: false, **kwargs)
55
- @kwargs = kwargs
56
- @kwargs[:tag] ||= :div
57
- @kwargs[:classes] = class_names(
58
- @kwargs[:classes],
75
+ # @param danger [Boolean] Whether to style the heading as dangerous.
76
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
77
+ def initialize(danger: false, **system_arguments)
78
+ @system_arguments = system_arguments
79
+ @system_arguments[:tag] ||= :div
80
+ @system_arguments[:classes] = class_names(
81
+ @system_arguments[:classes],
59
82
  "Subhead-heading",
60
83
  "Subhead-heading--danger": danger
61
84
  )
@@ -65,24 +88,26 @@ module Primer
65
88
  class Actions < ViewComponent::Slot
66
89
  include ClassNameHelper
67
90
 
68
- attr_reader :kwargs
91
+ attr_reader :system_arguments
69
92
 
70
- def initialize(**kwargs)
71
- @kwargs = kwargs
72
- @kwargs[:tag] = :div
73
- @kwargs[:classes] = class_names(@kwargs[:classes], "Subhead-actions")
93
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
94
+ def initialize(**system_arguments)
95
+ @system_arguments = system_arguments
96
+ @system_arguments[:tag] = :div
97
+ @system_arguments[:classes] = class_names(@system_arguments[:classes], "Subhead-actions")
74
98
  end
75
99
  end
76
100
 
77
101
  class Description < ViewComponent::Slot
78
102
  include ClassNameHelper
79
103
 
80
- attr_reader :kwargs
104
+ attr_reader :system_arguments
81
105
 
82
- def initialize(**kwargs)
83
- @kwargs = kwargs
84
- @kwargs[:tag] = :div
85
- @kwargs[:classes] = class_names(@kwargs[:classes], "Subhead-description")
106
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
107
+ def initialize(**system_arguments)
108
+ @system_arguments = system_arguments
109
+ @system_arguments[:tag] = :div
110
+ @system_arguments[:classes] = class_names(@system_arguments[:classes], "Subhead-description")
86
111
  end
87
112
  end
88
113
  end
@@ -1,14 +1,20 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # The Text component is a wrapper component that will apply typography styles to the text inside.
4
5
  class TextComponent < Primer::Component
5
- def initialize(**kwargs)
6
- @kwargs = kwargs
7
- @kwargs[:tag] ||= :span
6
+ # @example 70|Default
7
+ # <%= render(Primer::TextComponent.new(tag: :p, font_weight: :bold)) { "Bold Text" } %>
8
+ # <%= render(Primer::TextComponent.new(tag: :p, color: :red_5)) { "Red Text" } %>
9
+ #
10
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
11
+ def initialize(**system_arguments)
12
+ @system_arguments = system_arguments
13
+ @system_arguments[:tag] ||= :span
8
14
  end
9
15
 
10
16
  def call
11
- render(Primer::BaseComponent.new(**@kwargs)) { content }
17
+ render(Primer::BaseComponent.new(**@system_arguments)) { content }
12
18
  end
13
19
  end
14
20
  end
@@ -1,16 +1,16 @@
1
- <%= render Primer::BaseComponent.new(**kwargs) do %>
1
+ <%= render Primer::BaseComponent.new(**system_arguments) do %>
2
2
  <% if avatar %>
3
- <%= render Primer::AvatarComponent.new(alt: avatar.alt, src: avatar.src, size: avatar.size, square: avatar.square, **avatar.kwargs) %>
3
+ <%= render Primer::AvatarComponent.new(alt: avatar.alt, src: avatar.src, size: avatar.size, square: avatar.square, **avatar.system_arguments) %>
4
4
  <% end %>
5
5
 
6
6
  <% if badge %>
7
- <%= render Primer::BaseComponent.new(**badge.kwargs) do %>
7
+ <%= render Primer::BaseComponent.new(**badge.system_arguments) do %>
8
8
  <%= octicon badge.icon %>
9
9
  <% end %>
10
10
  <% end %>
11
11
 
12
12
  <% if body %>
13
- <%= render Primer::BaseComponent.new(**body.kwargs) do %>
13
+ <%= render Primer::BaseComponent.new(**body.system_arguments) do %>
14
14
  <%= body.content %>
15
15
  <% end %>
16
16
  <% end %>