primer_view_components 0.0.26 → 0.0.31

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 (65) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +86 -0
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/assets/javascripts/primer_view_components.js.map.orig +5 -0
  6. data/app/assets/javascripts/primer_view_components.js.orig +6 -0
  7. data/app/components/primer/auto_complete_component.d.ts +1 -0
  8. data/app/components/primer/auto_complete_component.html.erb +5 -0
  9. data/app/components/primer/auto_complete_component.js +1 -0
  10. data/app/components/primer/auto_complete_component.rb +98 -0
  11. data/app/components/primer/auto_complete_component.ts +1 -0
  12. data/app/components/primer/auto_complete_item_component.rb +40 -0
  13. data/app/components/primer/avatar_component.rb +8 -9
  14. data/app/components/primer/base_component.rb +6 -18
  15. data/app/components/primer/blankslate_component.html.erb +1 -5
  16. data/app/components/primer/blankslate_component.rb +2 -4
  17. data/app/components/primer/border_box_component.rb +32 -6
  18. data/app/components/primer/box_component.rb +3 -5
  19. data/app/components/primer/breadcrumb_component.rb +1 -0
  20. data/app/components/primer/component.rb +1 -13
  21. data/app/components/primer/counter_component.rb +17 -9
  22. data/app/components/primer/details_component.rb +1 -0
  23. data/app/components/primer/dropdown_menu_component.rb +2 -4
  24. data/app/components/primer/flash_component.html.erb +2 -2
  25. data/app/components/primer/flash_component.rb +2 -4
  26. data/app/components/primer/flex_component.rb +16 -16
  27. data/app/components/primer/heading_component.rb +1 -1
  28. data/app/components/primer/label_component.rb +5 -11
  29. data/app/components/primer/layout_component.html.erb +3 -9
  30. data/app/components/primer/layout_component.rb +30 -5
  31. data/app/components/primer/link_component.rb +37 -9
  32. data/app/components/primer/octicon_component.rb +4 -7
  33. data/app/components/primer/popover_component.html.erb +3 -7
  34. data/app/components/primer/popover_component.rb +76 -63
  35. data/app/components/primer/primer.d.ts +3 -0
  36. data/app/components/primer/primer.js +2 -0
  37. data/app/components/primer/primer.ts +2 -0
  38. data/app/components/primer/progress_bar_component.rb +6 -5
  39. data/app/components/primer/spinner_component.rb +2 -4
  40. data/app/components/primer/state_component.rb +2 -4
  41. data/app/components/primer/subhead_component.rb +2 -4
  42. data/app/components/primer/tab_container_component.d.ts +1 -0
  43. data/app/components/primer/text_component.rb +3 -1
  44. data/app/components/primer/time_ago_component.d.ts +1 -0
  45. data/app/components/primer/time_ago_component.js +1 -0
  46. data/app/components/primer/time_ago_component.rb +47 -0
  47. data/app/components/primer/time_ago_component.ts +1 -0
  48. data/app/components/primer/timeline_item_component.rb +2 -1
  49. data/app/components/primer/underline_nav_component.html.erb +5 -5
  50. data/app/components/primer/underline_nav_component.rb +24 -5
  51. data/app/lib/primer/classify.rb +13 -16
  52. data/app/lib/primer/classify/cache.rb +8 -3
  53. data/app/lib/primer/classify/functional_background_colors.rb +61 -0
  54. data/app/lib/primer/classify/functional_border_colors.rb +51 -0
  55. data/app/lib/primer/classify/functional_colors.rb +68 -0
  56. data/app/lib/primer/classify/functional_text_colors.rb +62 -0
  57. data/app/lib/primer/fetch_or_fallback_helper.rb +17 -4
  58. data/app/lib/primer/status/dsl.rb +43 -0
  59. data/app/lib/primer/test_selector_helper.rb +20 -0
  60. data/app/lib/primer/view_helper.rb +10 -12
  61. data/lib/primer/view_components/engine.rb +4 -0
  62. data/lib/primer/view_components/version.rb +1 -1
  63. data/static/statuses.json +1 -1
  64. metadata +37 -4
  65. data/app/lib/primer/view_helper/dsl.rb +0 -34
@@ -1,10 +1,6 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
- <%= render body.component do %>
3
- <% if heading %>
4
- <%= render heading.component do %>
5
- <%= heading.content %>
6
- <% end %>
7
- <% end %>
8
- <%= body.content %>
2
+ <%= render(body_component) do %>
3
+ <%= heading %>
4
+ <%= body %>
9
5
  <% end %>
10
6
  <% end %>
@@ -5,38 +5,102 @@ module Primer
5
5
  #
6
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.
7
7
  class PopoverComponent < Primer::Component
8
- include ViewComponent::Slotable
8
+ include ViewComponent::SlotableV2
9
+ status :beta
9
10
 
10
- with_slot :heading, class_name: "Heading"
11
- with_slot :body, class_name: "Body"
11
+ CARET_DEFAULT = :top
12
+ CARET_MAPPINGS = {
13
+ CARET_DEFAULT => "",
14
+ :bottom => "Popover-message--bottom",
15
+ :bottom_right => "Popover-message--bottom-right",
16
+ :bottom_left => "Popover-message--bottom-left",
17
+ :left => "Popover-message--left",
18
+ :left_bottom => "Popover-message--left-bottom",
19
+ :left_top => "Popover-message--left-top",
20
+ :right => "Popover-message--right",
21
+ :right_bottom => "Popover-message--right-bottom",
22
+ :right_top => "Popover-message--right-top",
23
+ :top_left => "Popover-message--top-left",
24
+ :top_right => "Popover-message--top-right"
25
+ }.freeze
26
+
27
+ # The heading
28
+ #
29
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
30
+ renders_one :heading, lambda { |**system_arguments|
31
+ system_arguments[:mb] ||= 2
32
+ system_arguments[:tag] ||= :h4
33
+
34
+ Primer::HeadingComponent.new(**system_arguments)
35
+ }
36
+
37
+ # The body
38
+ #
39
+ # @param caret [Symbol] <%= one_of(Primer::PopoverComponent::CARET_MAPPINGS.keys) %>
40
+ # @param large [Boolean] Whether to use the large version of the component.
41
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
42
+ renders_one :body, lambda { |caret: CARET_DEFAULT, large: false, **system_arguments, &block|
43
+ system_arguments[:classes] = class_names(
44
+ system_arguments[:classes],
45
+ "Popover-message Box",
46
+ CARET_MAPPINGS[fetch_or_fallback(CARET_MAPPINGS.keys, caret, CARET_DEFAULT)],
47
+ "Popover-message--large" => large
48
+ )
49
+ system_arguments[:p] ||= 4
50
+ system_arguments[:mt] ||= 2
51
+ system_arguments[:mx] ||= :auto
52
+ system_arguments[:text_align] ||= :left
53
+ system_arguments[:box_shadow] ||= :large
54
+
55
+ # This is a hack to allow the parent to set the slot's content
56
+ @body_arguments = system_arguments
57
+ view_context.capture { block&.call }
58
+ }
12
59
 
13
60
  # @example Default
14
61
  # <%= render Primer::PopoverComponent.new do |component| %>
15
- # <% component.slot(:heading) do %>
62
+ # <% component.heading do %>
16
63
  # Activity feed
17
64
  # <% end %>
18
- # <% component.slot(:body) do %>
65
+ # <% component.body do %>
19
66
  # This is the Popover body.
20
67
  # <% end %>
21
68
  # <% end %>
22
69
  #
23
70
  # @example Large
24
71
  # <%= render Primer::PopoverComponent.new do |component| %>
25
- # <% component.slot(:heading) do %>
72
+ # <% component.heading do %>
26
73
  # Activity feed
27
74
  # <% end %>
28
- # <% component.slot(:body, large: true) do %>
75
+ # <% component.body(large: true) do %>
29
76
  # This is the large Popover body.
30
77
  # <% end %>
31
78
  # <% end %>
32
79
  #
33
80
  # @example Caret position
34
81
  # <%= render Primer::PopoverComponent.new do |component| %>
35
- # <% component.slot(:heading) do %>
82
+ # <% component.heading do %>
36
83
  # Activity feed
37
84
  # <% end %>
38
- # <% component.slot(:body, caret: :left) do %>
39
- # This is the large Popover body.
85
+ # <% component.body(caret: :left) do %>
86
+ # This is the Popover body.
87
+ # <% end %>
88
+ # <% end %>
89
+ #
90
+ # @example With HTML body
91
+ # <%= render Primer::PopoverComponent.new do |component| %>
92
+ # <% component.heading do %>
93
+ # Activity feed
94
+ # <% end %>
95
+ # <% component.body(caret: :left) do %>
96
+ # <p> This is the Popover body.</p>
97
+ # <div>
98
+ # This is using HTML.
99
+ # <ul>
100
+ # <li>Thing #1</li>
101
+ # <li>Thing #2</li>
102
+ # </ul>
103
+ # </div>
40
104
  # <% end %>
41
105
  # <% end %>
42
106
  #
@@ -57,59 +121,8 @@ module Primer
57
121
  body.present?
58
122
  end
59
123
 
60
- # :nodoc:
61
- class Heading < Primer::Slot
62
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
63
- def initialize(**system_arguments)
64
- @system_arguments = system_arguments
65
- @system_arguments[:mb] ||= 2
66
- @system_arguments[:tag] ||= :h4
67
- end
68
-
69
- def component
70
- Primer::HeadingComponent.new(**@system_arguments)
71
- end
72
- end
73
-
74
- # :nodoc:
75
- class Body < Slot
76
- CARET_DEFAULT = :top
77
- CARET_MAPPINGS = {
78
- CARET_DEFAULT => "",
79
- :bottom => "Popover-message--bottom",
80
- :bottom_right => "Popover-message--bottom-right",
81
- :bottom_left => "Popover-message--bottom-left",
82
- :left => "Popover-message--left",
83
- :left_bottom => "Popover-message--left-bottom",
84
- :left_top => "Popover-message--left-top",
85
- :right => "Popover-message--right",
86
- :right_bottom => "Popover-message--right-bottom",
87
- :right_top => "Popover-message--right-top",
88
- :top_left => "Popover-message--top-left",
89
- :top_right => "Popover-message--top-right"
90
- }.freeze
91
-
92
- # @param caret [Symbol] <%= one_of(Primer::PopoverComponent::Body::CARET_MAPPINGS.keys) %>
93
- # @param large [Boolean] Whether to use the large version of the component.
94
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
95
- def initialize(caret: CARET_DEFAULT, large: false, **system_arguments)
96
- @system_arguments = system_arguments
97
- @system_arguments[:classes] = class_names(
98
- system_arguments[:classes],
99
- "Popover-message Box",
100
- CARET_MAPPINGS[fetch_or_fallback(CARET_MAPPINGS.keys, caret, CARET_DEFAULT)],
101
- "Popover-message--large" => large
102
- )
103
- @system_arguments[:p] ||= 4
104
- @system_arguments[:mt] ||= 2
105
- @system_arguments[:mx] ||= :auto
106
- @system_arguments[:text_align] ||= :left
107
- @system_arguments[:box_shadow] ||= :large
108
- end
109
-
110
- def component
111
- Primer::BoxComponent.new(**@system_arguments)
112
- end
124
+ def body_component
125
+ Primer::BoxComponent.new(**@body_arguments)
113
126
  end
114
127
  end
115
128
  end
@@ -0,0 +1,3 @@
1
+ import './auto_complete_component';
2
+ import './tab_container_component';
3
+ import './time_ago_component';
@@ -1 +1,3 @@
1
+ import './auto_complete_component';
1
2
  import './tab_container_component';
3
+ import './time_ago_component';
@@ -1 +1,3 @@
1
+ import './auto_complete_component'
1
2
  import './tab_container_component'
3
+ import './time_ago_component'
@@ -4,13 +4,14 @@ module Primer
4
4
  # Use ProgressBar to visualize task completion.
5
5
  class ProgressBarComponent < Primer::Component
6
6
  include ViewComponent::SlotableV2
7
+ status :beta
7
8
 
8
9
  # Use the Item slot to add an item to the progress bas
9
10
  #
10
11
  # @param percentage [Integer] The percent complete
11
12
  # @param bg [Symbol] The background color
12
13
  # @param kwargs [Hash] The same arguments as <%= link_to_system_arguments_docs %>.
13
- renders_many :items, lambda { |percentage: 0, bg: :green, **system_arguments|
14
+ renders_many :items, lambda { |percentage: 0, bg: :success_inverse, **system_arguments|
14
15
  percentage = percentage
15
16
  system_arguments = system_arguments
16
17
 
@@ -38,19 +39,19 @@ module Primer
38
39
  #
39
40
  # @example Small
40
41
  # <%= render(Primer::ProgressBarComponent.new(size: :small)) do |component| %>
41
- # <% component.item(bg: :blue_4, percentage: 50) %>
42
+ # <% component.item(bg: :info_inverse, percentage: 50) %>
42
43
  # <% end %>
43
44
  #
44
45
  # @example Large
45
46
  # <%= render(Primer::ProgressBarComponent.new(size: :large)) do |component| %>
46
- # <% component.item(bg: :red_4, percentage: 75) %>
47
+ # <% component.item(bg: :danger_inverse, percentage: 75) %>
47
48
  # <% end %>
48
49
  #
49
50
  # @example Multiple items
50
51
  # <%= render(Primer::ProgressBarComponent.new) do |component| %>
51
52
  # <% component.item(percentage: 10) %>
52
- # <% component.item(bg: :blue_4, percentage: 20) %>
53
- # <% component.item(bg: :red_4, percentage: 30) %>
53
+ # <% component.item(bg: :info_inverse, percentage: 20) %>
54
+ # <% component.item(bg: :danger_inverse, percentage: 30) %>
54
55
  # <% end %>
55
56
  #
56
57
  # @param size [Symbol] <%= one_of(Primer::ProgressBarComponent::SIZE_OPTIONS) %> Increases height.
@@ -3,6 +3,8 @@
3
3
  module Primer
4
4
  # Use Primer::SpinnerComponent to let users know that content is being loaded.
5
5
  class SpinnerComponent < Primer::Component
6
+ status :beta
7
+
6
8
  DEFAULT_SIZE = :medium
7
9
  SIZE_MAPPINGS = {
8
10
  :small => 16,
@@ -34,9 +36,5 @@ module Primer
34
36
  @system_arguments[:viewBox] = "0 0 16 16"
35
37
  @system_arguments[:fill] = :none
36
38
  end
37
-
38
- def self.status
39
- Primer::Component::STATUSES[:beta]
40
- end
41
39
  end
42
40
  end
@@ -3,6 +3,8 @@
3
3
  module Primer
4
4
  # Component for rendering the status of an item.
5
5
  class StateComponent < Primer::Component
6
+ status :beta
7
+
6
8
  COLOR_DEFAULT = :default
7
9
  NEW_COLOR_MAPPINGS = {
8
10
  open: "State--open",
@@ -68,9 +70,5 @@ module Primer
68
70
  def call
69
71
  render(Primer::BaseComponent.new(**@system_arguments)) { content }
70
72
  end
71
-
72
- def self.status
73
- Primer::Component::STATUSES[:beta]
74
- end
75
73
  end
76
74
  end
@@ -3,6 +3,8 @@
3
3
  module Primer
4
4
  # Use the Subhead component for page headings.
5
5
  class SubheadComponent < Primer::Component
6
+ status :beta
7
+
6
8
  include ViewComponent::SlotableV2
7
9
 
8
10
  # The heading
@@ -97,9 +99,5 @@ module Primer
97
99
  def render?
98
100
  heading.present?
99
101
  end
100
-
101
- def self.status
102
- Primer::Component::STATUSES[:beta]
103
- end
104
102
  end
105
103
  end
@@ -0,0 +1 @@
1
+ import '@github/tab-container-element';
@@ -3,9 +3,11 @@
3
3
  module Primer
4
4
  # The Text component is a wrapper component that will apply typography styles to the text inside.
5
5
  class TextComponent < Primer::Component
6
+ status :beta
7
+
6
8
  # @example Default
7
9
  # <%= render(Primer::TextComponent.new(tag: :p, font_weight: :bold)) { "Bold Text" } %>
8
- # <%= render(Primer::TextComponent.new(tag: :p, color: :red_5)) { "Red Text" } %>
10
+ # <%= render(Primer::TextComponent.new(tag: :p, color: :text_danger)) { "Danger Text" } %>
9
11
  #
10
12
  # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
11
13
  def initialize(**system_arguments)
@@ -0,0 +1 @@
1
+ import '@github/time-elements';
@@ -0,0 +1 @@
1
+ import '@github/time-elements';
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ # Use Primer::TimeAgoComponent to display a time relative to how long ago it was. This component requires JavaScript.
5
+ class TimeAgoComponent < Primer::Component
6
+ #
7
+ # @example Default
8
+ # <%= render(Primer::TimeAgoComponent.new(time: Time.at(628232400))) %>
9
+ #
10
+ # @param time [Time] The time to be formatted
11
+ # @param micro [Boolean] If true then the text will be formatted in "micro" mode, using as few characters as possible
12
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
13
+ def initialize(time:, micro: false, **system_arguments)
14
+ @system_arguments = system_arguments
15
+ @system_arguments[:datetime] = time.utc.iso8601
16
+ @system_arguments[:classes] = class_names("no-wrap", @system_arguments[:classes])
17
+ @system_arguments[:tag] = "time-ago"
18
+ @system_arguments[:format] = "micro" if micro
19
+ @time = time
20
+ @micro = micro
21
+ end
22
+
23
+ def call
24
+ render(Primer::BaseComponent.new(**@system_arguments)) { time_in_words }
25
+ end
26
+
27
+ private
28
+
29
+ def time_in_words
30
+ return @time.in_time_zone.strftime("%b %-d, %Y") unless @micro
31
+
32
+ seconds_ago = Time.current - @time
33
+
34
+ if seconds_ago < 1.minute
35
+ "1m"
36
+ elsif seconds_ago >= 1.minute && seconds_ago < 1.hour
37
+ "#{(seconds_ago / 60).floor}m"
38
+ elsif seconds_ago >= 1.hour && seconds_ago < 1.day
39
+ "#{(seconds_ago / 60 / 60).floor}h"
40
+ elsif seconds_ago >= 1.day && seconds_ago < 1.year
41
+ "#{(seconds_ago / 60 / 60 / 24).floor}d"
42
+ elsif seconds_ago >= 1.year
43
+ "#{(seconds_ago / 60 / 60 / 24 / 365).floor}y"
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1 @@
1
+ import '@github/time-elements'
@@ -4,6 +4,7 @@ module Primer
4
4
  # Use `TimelineItem` to display items on a vertical timeline, connected by badge elements.
5
5
  class TimelineItemComponent < Primer::Component
6
6
  include ViewComponent::SlotableV2
7
+ status :beta
7
8
 
8
9
  # Avatar to be rendered to the left of the Badge.
9
10
  #
@@ -40,7 +41,7 @@ module Primer
40
41
  # <div style="padding-left: 60px">
41
42
  # <%= render(Primer::TimelineItemComponent.new) do |component| %>
42
43
  # <% component.avatar(src: "https://github.com/github.png", alt: "github") %>
43
- # <% component.badge(bg: :green, color: :white, icon: :check) %>
44
+ # <% component.badge(bg: :success_inverse, color: :text_white, icon: :check) %>
44
45
  # <% component.body { "Success!" } %>
45
46
  # <% end %>
46
47
  # </div>
@@ -1,11 +1,11 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
- <% if actions && @align == :right %>
2
+ <% if @align == :right %>
3
3
  <%= actions %>
4
4
  <% end %>
5
- <%= render Primer::BaseComponent.new(tag: :ul, classes: "UnderlineNav-body list-style-none") do %>
6
- <%= body %>
7
- <% end %>
8
- <% if actions && @align == :left %>
5
+
6
+ <%= body %>
7
+
8
+ <% if @align == :left %>
9
9
  <%= actions %>
10
10
  <% end %>
11
11
  <% end %>
@@ -5,27 +5,46 @@ module Primer
5
5
  # underlined selected state, typically used for navigation placed at the top
6
6
  # of the page.
7
7
  class UnderlineNavComponent < Primer::Component
8
+ include ViewComponent::SlotableV2
9
+
8
10
  ALIGN_DEFAULT = :left
9
11
  ALIGN_OPTIONS = [ALIGN_DEFAULT, :right].freeze
10
12
 
11
- with_content_areas :body, :actions
13
+ # Use the body for the navigation items
14
+ #
15
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
16
+ renders_one :body, lambda { |**system_arguments|
17
+ system_arguments[:classes] = class_names("UnderlineNav-body", "list-style-none", system_arguments[:classes])
18
+ system_arguments[:tag] ||= :ul
19
+
20
+ Primer::BaseComponent.new(**system_arguments) { content }
21
+ }
22
+
23
+ # Use actions for a call to action
24
+ #
25
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
26
+ renders_one :actions, lambda { |**system_arguments|
27
+ system_arguments[:tag] ||= :div
28
+ system_arguments[:classes] = class_names("UnderlineNav-actions", system_arguments[:classes])
29
+ Primer::BaseComponent.new(**system_arguments) { content }
30
+ }
12
31
 
13
32
  # @example Default
14
33
  # <%= render(Primer::UnderlineNavComponent.new) do |component| %>
15
- # <% component.with(:body) do %>
34
+ # <% component.body do %>
16
35
  # <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
17
36
  # <% end %>
18
- # <% component.with(:actions) do %>
37
+ # <% component.actions do %>
19
38
  # <%= render(Primer::ButtonComponent.new) { "Button!" } %>
20
39
  # <% end %>
21
40
  # <% end %>
22
41
  #
23
42
  # @example Align right
24
43
  # <%= render(Primer::UnderlineNavComponent.new(align: :right)) do |component| %>
25
- # <% component.with(:body) do %>
44
+ # <% component.body do %>
26
45
  # <%= render(Primer::LinkComponent.new(href: "#url")) { "Item 1" } %>
27
46
  # <% end %>
28
- # <% component.with(:actions) do %>
47
+ # <% component.actions do %>
29
48
  # <%= render(Primer::ButtonComponent.new) { "Button!" } %>
30
49
  # <% end %>
31
50
  # <% end %>