primer_view_components 0.0.6 → 0.0.11

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 (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +71 -30
  3. data/README.md +1 -158
  4. data/app/components/primer/avatar_component.rb +11 -0
  5. data/app/components/primer/base_component.rb +7 -12
  6. data/app/components/primer/blankslate_component.html.erb +8 -2
  7. data/app/components/primer/blankslate_component.rb +70 -118
  8. data/app/components/primer/border_box_component.rb +16 -4
  9. data/app/components/primer/box_component.rb +2 -0
  10. data/app/components/primer/breadcrumb_component.rb +13 -20
  11. data/app/components/primer/button_component.rb +21 -4
  12. data/app/components/primer/component.rb +1 -0
  13. data/app/components/primer/counter_component.rb +5 -0
  14. data/app/components/primer/details_component.rb +4 -4
  15. data/app/components/primer/flash_component.html.erb +14 -0
  16. data/app/components/primer/flash_component.rb +73 -0
  17. data/app/components/primer/label_component.rb +17 -0
  18. data/app/components/primer/layout_component.rb +18 -1
  19. data/app/components/primer/link_component.rb +10 -0
  20. data/app/components/primer/octicon_component.rb +45 -0
  21. data/app/components/primer/popover_component.rb +38 -0
  22. data/app/components/primer/progress_bar_component.rb +29 -19
  23. data/app/components/primer/slot.rb +1 -0
  24. data/app/components/primer/spinner_component.html.erb +6 -0
  25. data/app/components/primer/spinner_component.rb +38 -0
  26. data/app/components/primer/state_component.rb +19 -7
  27. data/app/components/primer/subhead_component.rb +45 -20
  28. data/app/components/primer/text_component.rb +6 -0
  29. data/app/components/primer/timeline_item_component.rb +24 -0
  30. data/app/components/primer/view_components.rb +3 -0
  31. data/lib/primer/classify.rb +4 -0
  32. data/lib/primer/view_components/version.rb +1 -1
  33. metadata +27 -8
@@ -1,12 +1,46 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # Use popovers to bring attention to specific user interface elements, typically to suggest an action or to guide users through a new experience.
5
+ #
6
+ # By default, the popover renders with absolute positioning, meaning it should usually be wrapped in an element with a relative position in order to be positioned properly. To render the popover with relative positioning, use the relative property.
4
7
  class PopoverComponent < Primer::Component
5
8
  include ViewComponent::Slotable
6
9
 
7
10
  with_slot :heading, class_name: "Heading"
8
11
  with_slot :body, class_name: "Body"
9
12
 
13
+ # @example 150|Default
14
+ # <%= render Primer::PopoverComponent.new do |component| %>
15
+ # <% component.slot(:heading) do %>
16
+ # Activity feed
17
+ # <% end %>
18
+ # <% component.slot(:body) do %>
19
+ # This is the Popover body.
20
+ # <% end %>
21
+ # <% end %>
22
+ #
23
+ # @example 150|Large
24
+ # <%= render Primer::PopoverComponent.new do |component| %>
25
+ # <% component.slot(:heading) do %>
26
+ # Activity feed
27
+ # <% end %>
28
+ # <% component.slot(:body, large: true) do %>
29
+ # This is the large Popover body.
30
+ # <% end %>
31
+ # <% end %>
32
+ #
33
+ # @example 150|Caret position
34
+ # <%= render Primer::PopoverComponent.new do |component| %>
35
+ # <% component.slot(:heading) do %>
36
+ # Activity feed
37
+ # <% end %>
38
+ # <% component.slot(:body, caret: :left) do %>
39
+ # This is the large Popover body.
40
+ # <% end %>
41
+ # <% end %>
42
+ #
43
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
10
44
  def initialize(**kwargs)
11
45
  @kwargs = kwargs
12
46
  @kwargs[:tag] ||= :div
@@ -24,6 +58,7 @@ module Primer
24
58
  end
25
59
 
26
60
  class Heading < ViewComponent::Slot
61
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
27
62
  def initialize(**kwargs)
28
63
  @kwargs = kwargs
29
64
  @kwargs[:mb] ||= 2
@@ -52,6 +87,9 @@ module Primer
52
87
  :top_right => "Popover-message--top-right"
53
88
  }.freeze
54
89
 
90
+ # @param caret [Symbol] <%= one_of(Primer::PopoverComponent::Body::CARET_MAPPINGS.keys) %>
91
+ # @param large [Boolean] Whether to use the large version of the component.
92
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
55
93
  def initialize(caret: CARET_DEFAULT, large: false, **kwargs)
56
94
  @kwargs = kwargs
57
95
  @kwargs[:classes] = class_names(
@@ -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,8 +16,31 @@ module Primer
32
16
  }.freeze
33
17
 
34
18
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
35
-
36
- def initialize(size: SIZE_DEFAULT, percentage: 0, **kwargs)
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 kwargs [Hash] <%= link_to_style_arguments_docs %>
43
+ def initialize(size: SIZE_DEFAULT, **kwargs)
37
44
  @kwargs = kwargs
38
45
  @kwargs[:classes] = class_names(
39
46
  @kwargs[:classes],
@@ -52,6 +59,9 @@ module Primer
52
59
  include ClassNameHelper
53
60
  attr_reader :kwargs
54
61
 
62
+ # @param percentage [Integer] Percentage completion of item.
63
+ # @param bg [Symbol] Color of item.
64
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
55
65
  def initialize(percentage: 0, bg: :green, **kwargs)
56
66
  @percentage = percentage
57
67
  @kwargs = kwargs
@@ -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(**@kwargs) 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,38 @@
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
+
15
+ #
16
+ # @example 48|Default
17
+ # <%= render(Primer::SpinnerComponent.new) %>
18
+ #
19
+ # @example 32|Small
20
+ # <%= render(Primer::SpinnerComponent.new(size: :small)) %>
21
+ #
22
+ # @example 80|Large
23
+ # <%= render(Primer::SpinnerComponent.new(size: :large)) %>
24
+ #
25
+ # @param size [Symbol] <%= one_of(Primer::SpinnerComponent::SIZE_OPTIONS) %>
26
+ def initialize(size: DEFAULT_SIZE, **kwargs)
27
+ @kwargs = kwargs
28
+ @kwargs[:tag] = :svg
29
+ @kwargs[:width] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
30
+ @kwargs[:height] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
31
+ @kwargs[:viewBox] = "0 0 16 16"
32
+ @kwargs[:fill] = :none
33
+ # Setting `box-sizing: content-box` allows consumers to add padding
34
+ # to the spinner without shrinking the icon
35
+ @kwargs[:style] = "box-sizing: content-box; color: var(--color-icon-primary);"
36
+ end
37
+ end
38
+ 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,6 +22,24 @@ 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 kwargs [Hash] <%= link_to_style_arguments_docs %>
31
43
  def initialize(
32
44
  title:,
33
45
  color: COLOR_DEFAULT,
@@ -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,6 +9,46 @@ module Primer
28
9
  with_slot :actions, class_name: "Actions"
29
10
  with_slot :description, class_name: "Description"
30
11
 
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 kwargs [Hash] <%= link_to_style_arguments_docs %>
31
52
  def initialize(spacious: false, hide_border: false, **kwargs)
32
53
  @kwargs = kwargs
33
54
 
@@ -51,6 +72,8 @@ module Primer
51
72
 
52
73
  attr_reader :kwargs
53
74
 
75
+ # @param danger [Boolean] Whether to style the heading as dangerous.
76
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
54
77
  def initialize(danger: false, **kwargs)
55
78
  @kwargs = kwargs
56
79
  @kwargs[:tag] ||= :div
@@ -67,6 +90,7 @@ module Primer
67
90
 
68
91
  attr_reader :kwargs
69
92
 
93
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
70
94
  def initialize(**kwargs)
71
95
  @kwargs = kwargs
72
96
  @kwargs[:tag] = :div
@@ -79,6 +103,7 @@ module Primer
79
103
 
80
104
  attr_reader :kwargs
81
105
 
106
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
82
107
  def initialize(**kwargs)
83
108
  @kwargs = kwargs
84
109
  @kwargs[:tag] = :div
@@ -1,7 +1,13 @@
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
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 kwargs [Hash] <%= link_to_style_arguments_docs %>
5
11
  def initialize(**kwargs)
6
12
  @kwargs = kwargs
7
13
  @kwargs[:tag] ||= :span
@@ -1,6 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Primer
4
+ # Use `TimelineItem` to display items on a vertical timeline, connected by badge elements.
4
5
  class TimelineItemComponent < Primer::Component
5
6
  include ViewComponent::Slotable
6
7
 
@@ -9,6 +10,18 @@ module Primer
9
10
  with_slot :body, class_name: "Body"
10
11
 
11
12
  attr_reader :kwargs
13
+
14
+ # @example 75|Default
15
+ # <div style="padding-left: 60px">
16
+ # <%= render(Primer::TimelineItemComponent.new) do |component| %>
17
+ # <% component.slot(:avatar, src: "https://github.com/github.png", alt: "github") %>
18
+ # <% component.slot(:badge, bg: :green, color: :white, icon: :check) %>
19
+ # <% component.slot(:body) { "Success!" } %>
20
+ # <% end %>
21
+ # </div>
22
+ #
23
+ # @param condensed [Boolean] Reduce the vertical padding and remove the background from the badge item. Most commonly used in commits.
24
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
12
25
  def initialize(condensed: false, **kwargs)
13
26
  @kwargs = kwargs
14
27
  @kwargs[:tag] = :div
@@ -25,6 +38,12 @@ module Primer
25
38
 
26
39
  class Avatar < Primer::Slot
27
40
  attr_reader :kwargs, :alt, :src, :size, :square
41
+
42
+ # @param alt [String] Alt text for avatar image.
43
+ # @param src [String] Src attribute for avatar image.
44
+ # @param size [Integer] Image size.
45
+ # @param square [Boolean] Whether to round the edges of the image.
46
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
28
47
  def initialize(alt: nil, src: nil, size: 40, square: true, **kwargs)
29
48
  @alt = alt
30
49
  @src = src
@@ -42,6 +61,9 @@ module Primer
42
61
 
43
62
  class Badge < Primer::Slot
44
63
  attr_reader :kwargs, :icon
64
+
65
+ # @param icon [String] Name of [Octicon](https://primer.style/octicons/) to use.
66
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
45
67
  def initialize(icon: nil, **kwargs)
46
68
  @icon = icon
47
69
 
@@ -56,6 +78,8 @@ module Primer
56
78
 
57
79
  class Body < Primer::Slot
58
80
  attr_reader :kwargs
81
+
82
+ # @param kwargs [Hash] <%= link_to_style_arguments_docs %>
59
83
  def initialize(**kwargs)
60
84
  @kwargs = kwargs
61
85
  @kwargs[:tag] = :div
@@ -33,14 +33,17 @@ require_relative "button_component"
33
33
  require_relative "counter_component"
34
34
  require_relative "details_component"
35
35
  require_relative "dropdown_menu_component"
36
+ require_relative "flash_component"
36
37
  require_relative "flex_component"
37
38
  require_relative "flex_item_component"
38
39
  require_relative "heading_component"
39
40
  require_relative "label_component"
40
41
  require_relative "layout_component"
41
42
  require_relative "link_component"
43
+ require_relative "octicon_component"
42
44
  require_relative "popover_component"
43
45
  require_relative "progress_bar_component"
46
+ require_relative "spinner_component"
44
47
  require_relative "state_component"
45
48
  require_relative "subhead_component"
46
49
  require_relative "text_component"
@@ -78,11 +78,13 @@ module Primer
78
78
  }
79
79
  }.freeze
80
80
  BORDER_KEYS = [:border, :border_color].freeze
81
+ BORDER_MARGIN_KEYS = [:border_top, :border_bottom, :border_left, :border_right].freeze
81
82
  TYPOGRAPHY_KEYS = [:font_size].freeze
82
83
  VALID_KEYS = (
83
84
  CONCAT_KEYS +
84
85
  BOOLEAN_MAPPINGS.keys +
85
86
  BORDER_KEYS +
87
+ BORDER_MARGIN_KEYS +
86
88
  TYPOGRAPHY_KEYS +
87
89
  TEXT_KEYS +
88
90
  [
@@ -196,6 +198,8 @@ module Primer
196
198
  memo[:classes] << "wb-#{dasherized_val}"
197
199
  elsif BORDER_KEYS.include?(key)
198
200
  memo[:classes] << "border-#{dasherized_val}"
201
+ elsif BORDER_MARGIN_KEYS.include?(key)
202
+ memo[:classes] << "#{key.to_s.dasherize}-#{val}"
199
203
  elsif key == DIRECTION_KEY
200
204
  memo[:classes] << "flex#{breakpoint}-#{dasherized_val}"
201
205
  elsif key == JUSTIFY_CONTENT_KEY
@@ -5,7 +5,7 @@ module Primer
5
5
  module VERSION
6
6
  MAJOR = 0
7
7
  MINOR = 0
8
- PATCH = 6
8
+ PATCH = 11
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH].join(".")
11
11
  end