primer_view_components 0.0.7 → 0.0.12

Sign up to get free protection for your applications and to get access to all the features.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +72 -31
  3. data/README.md +2 -157
  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 +39 -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 +21 -2
@@ -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,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_OPTIONS) %>
29
+ def initialize(size: DEFAULT_SIZE, style: DEFAULT_STYLE, **kwargs)
30
+ @kwargs = kwargs
31
+ @kwargs[:tag] = :svg
32
+ @kwargs[:width] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
33
+ @kwargs[:height] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)]
34
+ @kwargs[:viewBox] = "0 0 16 16"
35
+ @kwargs[:fill] = :none
36
+ @kwargs[: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,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 = 7
8
+ PATCH = 12
9
9
 
10
10
  STRING = [MAJOR, MINOR, PATCH].join(".")
11
11
  end