primer_view_components 0.0.23 → 0.0.28
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +98 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/javascripts/primer_view_components.js.map.orig +5 -0
- data/app/assets/javascripts/primer_view_components.js.orig +6 -0
- data/app/components/primer/auto_complete_component.d.ts +1 -0
- data/app/components/primer/auto_complete_component.html.erb +5 -0
- data/app/components/primer/auto_complete_component.js +1 -0
- data/app/components/primer/auto_complete_component.rb +98 -0
- data/app/components/primer/auto_complete_component.ts +1 -0
- data/app/components/primer/auto_complete_item_component.rb +40 -0
- data/app/components/primer/avatar_component.rb +8 -9
- data/app/components/primer/base_component.rb +7 -15
- data/app/components/primer/blankslate_component.html.erb +1 -5
- data/app/components/primer/blankslate_component.rb +2 -0
- data/app/components/primer/border_box_component.rb +32 -6
- data/app/components/primer/box_component.rb +3 -5
- data/app/components/primer/breadcrumb_component.html.erb +1 -2
- data/app/components/primer/breadcrumb_component.rb +24 -12
- data/app/components/primer/component.rb +1 -13
- data/app/components/primer/counter_component.rb +17 -9
- data/app/components/primer/details_component.rb +3 -3
- data/app/components/primer/dropdown_menu_component.rb +2 -4
- data/app/components/primer/flash_component.html.erb +2 -2
- data/app/components/primer/flash_component.rb +2 -4
- data/app/components/primer/flex_component.rb +16 -16
- data/app/components/primer/heading_component.rb +1 -1
- data/app/components/primer/label_component.rb +9 -9
- data/app/components/primer/layout_component.html.erb +3 -9
- data/app/components/primer/layout_component.rb +30 -5
- data/app/components/primer/link_component.rb +37 -9
- data/app/components/primer/octicon_component.rb +4 -7
- data/app/components/primer/popover_component.html.erb +3 -7
- data/app/components/primer/popover_component.rb +58 -62
- data/app/components/primer/primer.d.ts +3 -0
- data/app/components/primer/primer.js +2 -0
- data/app/components/primer/primer.ts +2 -0
- data/app/components/primer/progress_bar_component.html.erb +1 -1
- data/app/components/primer/progress_bar_component.rb +24 -27
- data/app/components/primer/spinner_component.rb +2 -4
- data/app/components/primer/state_component.rb +2 -4
- data/app/components/primer/subhead_component.rb +2 -0
- data/app/components/primer/tab_container_component.d.ts +1 -0
- data/app/components/primer/text_component.rb +3 -1
- data/app/components/primer/time_ago_component.d.ts +1 -0
- data/app/components/primer/time_ago_component.js +1 -0
- data/app/components/primer/time_ago_component.rb +47 -0
- data/app/components/primer/time_ago_component.ts +1 -0
- data/app/components/primer/timeline_item_component.rb +2 -1
- data/app/components/primer/underline_nav_component.html.erb +5 -5
- data/app/components/primer/underline_nav_component.rb +24 -5
- data/app/lib/primer/classify.rb +9 -14
- data/app/lib/primer/classify/cache.rb +7 -2
- data/app/lib/primer/classify/functional_background_colors.rb +61 -0
- data/app/lib/primer/classify/functional_border_colors.rb +51 -0
- data/app/lib/primer/classify/functional_colors.rb +66 -0
- data/app/lib/primer/classify/functional_text_colors.rb +62 -0
- data/app/lib/primer/fetch_or_fallback_helper.rb +13 -4
- data/app/lib/primer/status/dsl.rb +43 -0
- data/app/lib/primer/test_selector_helper.rb +20 -0
- data/app/lib/primer/view_helper.rb +9 -12
- data/lib/primer/view_components/engine.rb +4 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/static/statuses.json +1 -1
- metadata +37 -4
- data/app/lib/primer/view_helper/dsl.rb +0 -34
@@ -3,9 +3,10 @@
|
|
3
3
|
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
|
+
status :beta
|
7
7
|
|
8
|
-
include
|
8
|
+
include ClassNameHelper
|
9
|
+
include TestSelectorHelper
|
9
10
|
include OcticonsHelper
|
10
11
|
|
11
12
|
SIZE_DEFAULT = :small
|
@@ -38,15 +39,11 @@ module Primer
|
|
38
39
|
# Filter out classify options to prevent them from becoming invalid html attributes.
|
39
40
|
# Note height and width are both classify options and valid html attributes.
|
40
41
|
octicon_helper_options = @system_arguments.slice(:height, :width)
|
41
|
-
@system_arguments = @system_arguments.except(*Primer::Classify::VALID_KEYS, :classes).merge(octicon_helper_options)
|
42
|
+
@system_arguments = add_test_selector(@system_arguments).except(*Primer::Classify::VALID_KEYS, :classes).merge(octicon_helper_options)
|
42
43
|
end
|
43
44
|
|
44
45
|
def call
|
45
46
|
octicon(@icon, { **@system_arguments })
|
46
47
|
end
|
47
|
-
|
48
|
-
def self.status
|
49
|
-
Primer::Component::STATUSES[:beta]
|
50
|
-
end
|
51
48
|
end
|
52
49
|
end
|
@@ -1,10 +1,6 @@
|
|
1
1
|
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
2
|
-
<%= render
|
3
|
-
|
4
|
-
|
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,37 +5,84 @@ 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::
|
8
|
+
include ViewComponent::SlotableV2
|
9
|
+
status :beta
|
9
10
|
|
10
|
-
|
11
|
-
|
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
|
+
block&.call
|
58
|
+
}
|
12
59
|
|
13
60
|
# @example Default
|
14
61
|
# <%= render Primer::PopoverComponent.new do |component| %>
|
15
|
-
# <% component.
|
62
|
+
# <% component.heading do %>
|
16
63
|
# Activity feed
|
17
64
|
# <% end %>
|
18
|
-
# <% component.
|
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.
|
72
|
+
# <% component.heading do %>
|
26
73
|
# Activity feed
|
27
74
|
# <% end %>
|
28
|
-
# <% component.
|
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.
|
82
|
+
# <% component.heading do %>
|
36
83
|
# Activity feed
|
37
84
|
# <% end %>
|
38
|
-
# <% component.
|
85
|
+
# <% component.body(caret: :left) do %>
|
39
86
|
# This is the large Popover body.
|
40
87
|
# <% end %>
|
41
88
|
# <% end %>
|
@@ -57,59 +104,8 @@ module Primer
|
|
57
104
|
body.present?
|
58
105
|
end
|
59
106
|
|
60
|
-
|
61
|
-
|
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
|
107
|
+
def body_component
|
108
|
+
Primer::BoxComponent.new(**@body_arguments)
|
113
109
|
end
|
114
110
|
end
|
115
111
|
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::
|
6
|
+
include ViewComponent::SlotableV2
|
7
|
+
status :beta
|
7
8
|
|
8
|
-
|
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: :success_inverse, **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.
|
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.
|
42
|
+
# <% component.item(bg: :info_inverse, percentage: 50) %>
|
27
43
|
# <% end %>
|
28
44
|
#
|
29
45
|
# @example Large
|
30
46
|
# <%= render(Primer::ProgressBarComponent.new(size: :large)) do |component| %>
|
31
|
-
# <% component.
|
47
|
+
# <% component.item(bg: :danger_inverse, percentage: 75) %>
|
32
48
|
# <% end %>
|
33
49
|
#
|
34
50
|
# @example Multiple items
|
35
51
|
# <%= render(Primer::ProgressBarComponent.new) do |component| %>
|
36
|
-
# <% component.
|
37
|
-
# <% component.
|
38
|
-
# <% component.
|
52
|
+
# <% component.item(percentage: 10) %>
|
53
|
+
# <% component.item(bg: :info_inverse, percentage: 20) %>
|
54
|
+
# <% component.item(bg: :danger_inverse, 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
|
@@ -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: :
|
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: :
|
44
|
+
# <% component.badge(bg: :success_inverse, color: :text_white, icon: :check) %>
|
44
45
|
# <% component.body { "Success!" } %>
|
45
46
|
# <% end %>
|
46
47
|
# </div>
|