primer_view_components 0.0.22 → 0.0.27

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 (44) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +74 -1
  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.js +1 -0
  8. data/app/components/primer/avatar_component.rb +2 -4
  9. data/app/components/primer/base_component.rb +5 -13
  10. data/app/components/primer/blankslate_component.rb +2 -0
  11. data/app/components/primer/border_box_component.rb +2 -4
  12. data/app/components/primer/box_component.rb +2 -4
  13. data/app/components/primer/breadcrumb_component.html.erb +1 -2
  14. data/app/components/primer/breadcrumb_component.rb +24 -12
  15. data/app/components/primer/component.rb +2 -13
  16. data/app/components/primer/counter_component.rb +2 -4
  17. data/app/components/primer/details_component.rb +2 -3
  18. data/app/components/primer/dropdown_menu_component.rb +2 -4
  19. data/app/components/primer/flash_component.rb +2 -4
  20. data/app/components/primer/label_component.rb +18 -24
  21. data/app/components/primer/layout_component.html.erb +3 -9
  22. data/app/components/primer/layout_component.rb +30 -5
  23. data/app/components/primer/link_component.rb +2 -4
  24. data/app/components/primer/octicon_component.rb +4 -6
  25. data/app/components/primer/primer.js +1 -0
  26. data/app/components/primer/primer.ts +1 -0
  27. data/app/components/primer/progress_bar_component.html.erb +1 -1
  28. data/app/components/primer/progress_bar_component.rb +24 -27
  29. data/app/components/primer/spinner_component.rb +2 -4
  30. data/app/components/primer/state_component.rb +2 -4
  31. data/app/components/primer/subhead_component.html.erb +3 -15
  32. data/app/components/primer/subhead_component.rb +44 -58
  33. data/app/components/primer/time_ago_component.js +1 -0
  34. data/app/components/primer/time_ago_component.rb +47 -0
  35. data/app/components/primer/time_ago_component.ts +1 -0
  36. data/app/components/primer/underline_nav_component.html.erb +5 -5
  37. data/app/components/primer/underline_nav_component.rb +24 -5
  38. data/app/lib/primer/classify/functional_colors.rb.orig +124 -0
  39. data/app/lib/primer/status/dsl.rb +43 -0
  40. data/app/lib/primer/test_selector_helper.rb +20 -0
  41. data/app/lib/primer/view_helper/dsl.rb +2 -2
  42. data/lib/primer/view_components/version.rb +1 -1
  43. data/static/statuses.json +1 -1
  44. metadata +12 -3
@@ -1,17 +1,11 @@
1
1
  <%= render(Primer::FlexComponent.new(**@system_arguments)) do %>
2
2
  <% if @side == :left %>
3
- <%= render Primer::BaseComponent.new(tag: :div, classes: "flex-shrink-0", col: (@responsive ? [12, nil, @sidebar_col] : @sidebar_col), mb: (@responsive ? [4, nil, 0] : nil)) do %>
4
- <%= sidebar %>
5
- <% end %>
3
+ <%= sidebar %>
6
4
  <% end %>
7
5
 
8
- <%= render Primer::BaseComponent.new(tag: :div, classes: "flex-shrink-0", col: (@responsive ? [12, nil, @main_col] : @main_col), mb: (@responsive ? [4, nil, 0] : nil)) do %>
9
- <%= main %>
10
- <% end %>
6
+ <%= main %>
11
7
 
12
8
  <% if @side == :right %>
13
- <%= render Primer::BaseComponent.new(tag: :div, classes: "flex-shrink-0", col: (@responsive ? [12, nil, @sidebar_col] : @sidebar_col)) do %>
14
- <%= sidebar %>
15
- <% end %>
9
+ <%= sidebar %>
16
10
  <% end %>
17
11
  <% end %>
@@ -3,7 +3,32 @@
3
3
  module Primer
4
4
  # Use Layout to build a main/sidebar layout.
5
5
  class LayoutComponent < Primer::Component
6
- with_content_areas :main, :sidebar
6
+ include ViewComponent::SlotableV2
7
+
8
+ # The main content
9
+ #
10
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
11
+ renders_one :main, lambda { |**system_arguments|
12
+ system_arguments[:classes] = class_names("flex-shrink-0", system_arguments[:classes])
13
+ system_arguments[:col] = (@responsive ? [12, nil, @main_col] : @main_col)
14
+ system_arguments[:mb] = (@responsive ? [4, nil, 0] : nil)
15
+
16
+ Primer::BaseComponent.new(tag: :div, **system_arguments)
17
+ }
18
+
19
+ # The sidebar content
20
+ #
21
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
22
+ renders_one :sidebar, lambda { |**system_arguments|
23
+ system_arguments[:classes] = class_names("flex-shrink-0", system_arguments[:classes])
24
+ system_arguments[:col] = (@responsive ? [12, nil, @sidebar_col] : @sidebar_col)
25
+
26
+ if @side == :left
27
+ system_arguments[:mb] = (@responsive ? [4, nil, 0] : nil)
28
+ end
29
+
30
+ Primer::BaseComponent.new(tag: :div, **system_arguments)
31
+ }
7
32
 
8
33
  DEFAULT_SIDE = :right
9
34
  ALLOWED_SIDES = [DEFAULT_SIDE, :left].freeze
@@ -14,14 +39,14 @@ module Primer
14
39
 
15
40
  # @example Default
16
41
  # <%= render(Primer::LayoutComponent.new) do |component| %>
17
- # <% component.with(:sidebar) { "Sidebar" } %>
18
- # <% component.with(:main) { "Main" } %>
42
+ # <% component.sidebar { "Sidebar" } %>
43
+ # <% component.main { "Main" } %>
19
44
  # <% end %>
20
45
  #
21
46
  # @example Left sidebar
22
47
  # <%= render(Primer::LayoutComponent.new(side: :left)) do |component| %>
23
- # <% component.with(:sidebar) { "Sidebar" } %>
24
- # <% component.with(:main) { "Main" } %>
48
+ # <% component.sidebar { "Sidebar" } %>
49
+ # <% component.main { "Main" } %>
25
50
  # <% end %>
26
51
  #
27
52
  # @param responsive [Boolean] Whether to collapse layout to a single column at smaller widths.
@@ -3,6 +3,8 @@
3
3
  module Primer
4
4
  # Use links for moving from one page to another. The Link component styles anchor tags with default blue styling and hover text-decoration.
5
5
  class LinkComponent < Primer::Component
6
+ status :beta
7
+
6
8
  # @example Default
7
9
  # <%= render(Primer::LinkComponent.new(href: "http://www.google.com")) { "Link" } %>
8
10
  #
@@ -25,9 +27,5 @@ module Primer
25
27
  def call
26
28
  render(Primer::BaseComponent.new(**@system_arguments)) { content }
27
29
  end
28
-
29
- def self.status
30
- Primer::Component::STATUSES[:beta]
31
- end
32
30
  end
33
31
  end
@@ -4,8 +4,10 @@ module Primer
4
4
  # Renders an [Octicon](https://primer.style/octicons/) with <%= link_to_system_arguments_docs %>.
5
5
  class OcticonComponent < Primer::Component
6
6
  view_helper :octicon
7
+ status :beta
7
8
 
8
- include Primer::ClassNameHelper
9
+ include ClassNameHelper
10
+ include TestSelectorHelper
9
11
  include OcticonsHelper
10
12
 
11
13
  SIZE_DEFAULT = :small
@@ -38,15 +40,11 @@ module Primer
38
40
  # Filter out classify options to prevent them from becoming invalid html attributes.
39
41
  # Note height and width are both classify options and valid html attributes.
40
42
  octicon_helper_options = @system_arguments.slice(:height, :width)
41
- @system_arguments = @system_arguments.except(*Primer::Classify::VALID_KEYS, :classes).merge(octicon_helper_options)
43
+ @system_arguments = add_test_selector(@system_arguments).except(*Primer::Classify::VALID_KEYS, :classes).merge(octicon_helper_options)
42
44
  end
43
45
 
44
46
  def call
45
47
  octicon(@icon, { **@system_arguments })
46
48
  end
47
-
48
- def self.status
49
- Primer::Component::STATUSES[:beta]
50
- end
51
49
  end
52
50
  end
@@ -1 +1,2 @@
1
1
  import './tab_container_component';
2
+ import './time_ago_component';
@@ -1 +1,2 @@
1
1
  import './tab_container_component'
2
+ import './time_ago_component'
@@ -1,5 +1,5 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
2
  <% items.each do |item| %>
3
- <%= render Primer::BaseComponent.new(**item.system_arguments) %>
3
+ <%= item %>
4
4
  <% end %>
5
5
  <% end %>
@@ -3,9 +3,25 @@
3
3
  module Primer
4
4
  # Use ProgressBar to visualize task completion.
5
5
  class ProgressBarComponent < Primer::Component
6
- include ViewComponent::Slotable
6
+ include ViewComponent::SlotableV2
7
+ status :beta
7
8
 
8
- with_slot :item, collection: true, class_name: "Item"
9
+ # Use the Item slot to add an item to the progress bas
10
+ #
11
+ # @param percentage [Integer] The percent complete
12
+ # @param bg [Symbol] The background color
13
+ # @param kwargs [Hash] The same arguments as <%= link_to_system_arguments_docs %>.
14
+ renders_many :items, lambda { |percentage: 0, bg: :green, **system_arguments|
15
+ percentage = percentage
16
+ system_arguments = system_arguments
17
+
18
+ system_arguments[:tag] = :span
19
+ system_arguments[:bg] = bg
20
+ system_arguments[:style] = join_style_arguments(system_arguments[:style], "width: #{percentage}%;")
21
+ system_arguments[:classes] = class_names("Progress-item", system_arguments[:classes])
22
+
23
+ Primer::BaseComponent.new(**system_arguments)
24
+ }
9
25
 
10
26
  SIZE_DEFAULT = :default
11
27
 
@@ -18,24 +34,24 @@ module Primer
18
34
  SIZE_OPTIONS = SIZE_MAPPINGS.keys
19
35
  # @example Default
20
36
  # <%= render(Primer::ProgressBarComponent.new) do |component| %>
21
- # <% component.slot(:item, percentage: 25) %>
37
+ # <% component.item(percentage: 25) %>
22
38
  # <% end %>
23
39
  #
24
40
  # @example Small
25
41
  # <%= render(Primer::ProgressBarComponent.new(size: :small)) do |component| %>
26
- # <% component.slot(:item, bg: :blue_4, percentage: 50) %>
42
+ # <% component.item(bg: :blue_4, percentage: 50) %>
27
43
  # <% end %>
28
44
  #
29
45
  # @example Large
30
46
  # <%= render(Primer::ProgressBarComponent.new(size: :large)) do |component| %>
31
- # <% component.slot(:item, bg: :red_4, percentage: 75) %>
47
+ # <% component.item(bg: :red_4, percentage: 75) %>
32
48
  # <% end %>
33
49
  #
34
50
  # @example Multiple items
35
51
  # <%= 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) %>
52
+ # <% component.item(percentage: 10) %>
53
+ # <% component.item(bg: :blue_4, percentage: 20) %>
54
+ # <% component.item(bg: :red_4, percentage: 30) %>
39
55
  # <% end %>
40
56
  #
41
57
  # @param size [Symbol] <%= one_of(Primer::ProgressBarComponent::SIZE_OPTIONS) %> Increases height.
@@ -53,24 +69,5 @@ module Primer
53
69
  def render?
54
70
  items.any?
55
71
  end
56
-
57
- # :nodoc:
58
- class Item < Primer::Slot
59
- attr_reader :system_arguments
60
-
61
- # @param percentage [Integer] Percentage completion of item.
62
- # @param bg [Symbol] Color of item.
63
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
64
- def initialize(percentage: 0, bg: :green, **system_arguments)
65
- @percentage = percentage
66
- @system_arguments = system_arguments
67
-
68
- @system_arguments[:tag] = :span
69
- @system_arguments[:bg] = bg
70
- @system_arguments[:style] =
71
- join_style_arguments(@system_arguments[:style], "width: #{@percentage}%;")
72
- @system_arguments[:classes] = class_names("Progress-item", @system_arguments[:classes])
73
- end
74
- end
75
72
  end
76
73
  end
@@ -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
@@ -1,17 +1,5 @@
1
1
  <%= render Primer::BaseComponent.new(**@system_arguments) do %>
2
- <% if heading.present? %>
3
- <%= render Primer::BaseComponent.new(**heading.system_arguments) do %>
4
- <%= heading.content %>
5
- <% end %>
6
- <% end %>
7
- <% if actions.present? %>
8
- <%= render Primer::BaseComponent.new(**actions.system_arguments) do %>
9
- <%= actions.content %>
10
- <% end %>
11
- <% end %>
12
- <% if description.present? %>
13
- <%= render Primer::BaseComponent.new(**description.system_arguments) do %>
14
- <%= description.content %>
15
- <% end %>
16
- <% end %>
2
+ <%= heading %>
3
+ <%= actions %>
4
+ <%= description %>
17
5
  <% end %>
@@ -3,41 +3,74 @@
3
3
  module Primer
4
4
  # Use the Subhead component for page headings.
5
5
  class SubheadComponent < Primer::Component
6
- include ViewComponent::Slotable
6
+ status :beta
7
7
 
8
- with_slot :heading, class_name: "Heading"
9
- with_slot :actions, class_name: "Actions"
10
- with_slot :description, class_name: "Description"
8
+ include ViewComponent::SlotableV2
9
+
10
+ # The heading
11
+ #
12
+ # @param danger [Boolean] Whether to style the heading as dangerous.
13
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
14
+ renders_one :heading, lambda { |danger: false, **system_arguments|
15
+ system_arguments[:tag] ||= :div
16
+ system_arguments[:classes] = class_names(
17
+ system_arguments[:classes],
18
+ "Subhead-heading",
19
+ "Subhead-heading--danger": danger
20
+ )
21
+
22
+ Primer::BaseComponent.new(**system_arguments)
23
+ }
24
+
25
+ # Actions
26
+ #
27
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
28
+ renders_one :actions, lambda { |**system_arguments|
29
+ system_arguments[:tag] = :div
30
+ system_arguments[:classes] = class_names(system_arguments[:classes], "Subhead-actions")
31
+
32
+ Primer::BaseComponent.new(**system_arguments)
33
+ }
34
+
35
+ # The description
36
+ #
37
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
38
+ renders_one :description, lambda { |**system_arguments|
39
+ system_arguments[:tag] = :div
40
+ system_arguments[:classes] = class_names(system_arguments[:classes], "Subhead-description")
41
+
42
+ Primer::BaseComponent.new(**system_arguments)
43
+ }
11
44
 
12
45
  # @example Default
13
46
  # <%= render(Primer::SubheadComponent.new) do |component| %>
14
- # <% component.slot(:heading) do %>
47
+ # <% component.heading do %>
15
48
  # My Heading
16
49
  # <% end %>
17
- # <% component.slot(:description) do %>
50
+ # <% component.description do %>
18
51
  # My Description
19
52
  # <% end %>
20
53
  # <% end %>
21
54
  #
22
55
  # @example Without border
23
56
  # <%= render(Primer::SubheadComponent.new(hide_border: true)) do |component| %>
24
- # <% component.slot(:heading) do %>
57
+ # <% component.heading do %>
25
58
  # My Heading
26
59
  # <% end %>
27
- # <% component.slot(:description) do %>
60
+ # <% component.description do %>
28
61
  # My Description
29
62
  # <% end %>
30
63
  # <% end %>
31
64
  #
32
65
  # @example With actions
33
66
  # <%= render(Primer::SubheadComponent.new) do |component| %>
34
- # <% component.slot(:heading) do %>
67
+ # <% component.heading do %>
35
68
  # My Heading
36
69
  # <% end %>
37
- # <% component.slot(:description) do %>
70
+ # <% component.description do %>
38
71
  # My Description
39
72
  # <% end %>
40
- # <% component.slot(:actions) do %>
73
+ # <% component.actions do %>
41
74
  # <%= render(
42
75
  # Primer::ButtonComponent.new(
43
76
  # tag: :a, href: "http://www.google.com", button_type: :danger
@@ -66,52 +99,5 @@ module Primer
66
99
  def render?
67
100
  heading.present?
68
101
  end
69
-
70
- # :nodoc:
71
- class Heading < ViewComponent::Slot
72
- include ClassNameHelper
73
-
74
- attr_reader :system_arguments
75
-
76
- # @param danger [Boolean] Whether to style the heading as dangerous.
77
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
78
- def initialize(danger: false, **system_arguments)
79
- @system_arguments = system_arguments
80
- @system_arguments[:tag] ||= :div
81
- @system_arguments[:classes] = class_names(
82
- @system_arguments[:classes],
83
- "Subhead-heading",
84
- "Subhead-heading--danger": danger
85
- )
86
- end
87
- end
88
-
89
- # :nodoc:
90
- class Actions < ViewComponent::Slot
91
- include ClassNameHelper
92
-
93
- attr_reader :system_arguments
94
-
95
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
96
- def initialize(**system_arguments)
97
- @system_arguments = system_arguments
98
- @system_arguments[:tag] = :div
99
- @system_arguments[:classes] = class_names(@system_arguments[:classes], "Subhead-actions")
100
- end
101
- end
102
-
103
- # :nodoc:
104
- class Description < ViewComponent::Slot
105
- include ClassNameHelper
106
-
107
- attr_reader :system_arguments
108
-
109
- # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
110
- def initialize(**system_arguments)
111
- @system_arguments = system_arguments
112
- @system_arguments[:tag] = :div
113
- @system_arguments[:classes] = class_names(@system_arguments[:classes], "Subhead-description")
114
- end
115
- end
116
102
  end
117
103
  end
@@ -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