primer_view_components 0.0.22 → 0.0.27

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