primer_view_components 0.0.9 → 0.0.14

Sign up to get free protection for your applications and to get access to all the features.
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 %>