primer_view_components 0.0.18 → 0.0.23
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.
- checksums.yaml +4 -4
- data/CHANGELOG.md +101 -0
- data/app/assets/javascripts/primer_view_components.js +2 -0
- data/app/assets/javascripts/primer_view_components.js.map +1 -0
- data/app/components/primer/avatar_component.rb +27 -9
- data/app/components/primer/avatar_stack_component.html.erb +10 -0
- data/app/components/primer/avatar_stack_component.rb +81 -0
- data/app/components/primer/base_component.rb +4 -4
- data/app/components/primer/blankslate_component.html.erb +3 -3
- data/app/components/primer/blankslate_component.rb +16 -24
- data/app/components/primer/border_box_component.html.erb +4 -18
- data/app/components/primer/border_box_component.rb +75 -72
- data/app/components/primer/box_component.rb +2 -2
- data/app/components/primer/breadcrumb_component.rb +1 -1
- data/app/components/primer/button_component.rb +2 -2
- data/app/components/primer/button_group_component.rb +4 -1
- data/app/components/primer/button_marketing_component.rb +2 -2
- data/app/components/primer/component.rb +9 -6
- data/app/components/primer/counter_component.rb +5 -1
- data/app/components/primer/details_component.html.erb +2 -6
- data/app/components/primer/details_component.rb +22 -35
- data/app/components/primer/dropdown/menu_component.html.erb +12 -0
- data/app/components/primer/dropdown/menu_component.rb +48 -0
- data/app/components/primer/dropdown_component.html.erb +9 -0
- data/app/components/primer/dropdown_component.rb +75 -0
- data/app/components/primer/dropdown_menu_component.rb +8 -4
- data/app/components/primer/flash_component.html.erb +4 -7
- data/app/components/primer/flash_component.rb +18 -18
- data/app/components/primer/flex_component.rb +38 -1
- data/app/components/primer/flex_item_component.rb +15 -1
- data/app/components/primer/heading_component.rb +3 -1
- data/app/components/primer/label_component.rb +15 -25
- data/app/components/primer/layout_component.rb +2 -2
- data/app/components/primer/link_component.rb +6 -2
- data/app/components/primer/markdown_component.rb +293 -0
- data/app/components/primer/menu_component.html.erb +6 -0
- data/app/components/primer/menu_component.rb +71 -0
- data/app/components/primer/octicon_component.rb +9 -3
- data/app/components/primer/popover_component.rb +5 -5
- data/app/components/primer/primer.js +1 -0
- data/app/components/primer/primer.ts +1 -0
- data/app/components/primer/progress_bar_component.rb +5 -5
- data/app/components/primer/spinner_component.rb +7 -3
- data/app/components/primer/state_component.rb +21 -10
- data/app/components/primer/subhead_component.html.erb +3 -15
- data/app/components/primer/subhead_component.rb +45 -61
- data/app/components/primer/tab_container_component.js +1 -0
- data/app/components/primer/tab_container_component.rb +41 -0
- data/app/components/primer/tab_container_component.ts +1 -0
- data/app/components/primer/tab_nav_component.html.erb +17 -0
- data/app/components/primer/tab_nav_component.rb +108 -0
- data/app/components/primer/text_component.rb +1 -1
- data/app/components/primer/timeline_item_component.html.erb +4 -16
- data/app/components/primer/timeline_item_component.rb +41 -52
- data/app/components/primer/tooltip_component.rb +5 -5
- data/app/components/primer/truncate_component.rb +4 -4
- data/app/components/primer/underline_nav_component.rb +2 -2
- data/{lib → app/lib}/primer/class_name_helper.rb +0 -0
- data/{lib → app/lib}/primer/classify.rb +21 -10
- data/app/lib/primer/classify/cache.rb +125 -0
- data/{lib → app/lib}/primer/fetch_or_fallback_helper.rb +1 -1
- data/{lib → app/lib}/primer/join_style_arguments_helper.rb +1 -1
- data/app/lib/primer/view_helper.rb +22 -0
- data/app/lib/primer/view_helper/dsl.rb +34 -0
- data/lib/primer/view_components.rb +32 -1
- data/lib/primer/view_components/engine.rb +11 -3
- data/lib/primer/view_components/version.rb +5 -1
- data/lib/yard/renders_many_handler.rb +19 -0
- data/lib/yard/renders_one_handler.rb +19 -0
- data/static/statuses.json +1 -0
- metadata +61 -10
- data/app/components/primer/view_components.rb +0 -56
@@ -3,91 +3,94 @@
|
|
3
3
|
module Primer
|
4
4
|
# BorderBox is a Box component with a border.
|
5
5
|
class BorderBoxComponent < Primer::Component
|
6
|
-
include ViewComponent::
|
6
|
+
include ViewComponent::SlotableV2
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
# Optional Header.
|
9
|
+
#
|
10
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
11
|
+
renders_one :header, lambda { |**system_arguments|
|
12
|
+
system_arguments[:tag] = :div
|
13
|
+
system_arguments[:classes] = class_names(
|
14
|
+
"Box-header",
|
15
|
+
system_arguments[:classes]
|
16
|
+
)
|
12
17
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
#
|
17
|
-
# component.slot(:row) { "Row one" }
|
18
|
-
# component.slot(:row) { "Row two" }
|
19
|
-
# component.slot(:row) { "Row three" }
|
20
|
-
# component.slot(:footer) { "Footer" }
|
21
|
-
# end %>
|
18
|
+
Primer::BaseComponent.new(**system_arguments)
|
19
|
+
}
|
20
|
+
|
21
|
+
# Optional Body.
|
22
22
|
#
|
23
23
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
"Box",
|
24
|
+
renders_one :body, lambda { |**system_arguments|
|
25
|
+
system_arguments[:tag] = :div
|
26
|
+
system_arguments[:classes] = class_names(
|
27
|
+
"Box-body",
|
29
28
|
system_arguments[:classes]
|
30
29
|
)
|
31
|
-
end
|
32
30
|
|
33
|
-
|
34
|
-
|
35
|
-
end
|
31
|
+
Primer::BaseComponent.new(**system_arguments)
|
32
|
+
}
|
36
33
|
|
37
|
-
#
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
34
|
+
# Optional Footer.
|
35
|
+
#
|
36
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
37
|
+
renders_one :footer, lambda { |**system_arguments|
|
38
|
+
system_arguments[:tag] = :div
|
39
|
+
system_arguments[:classes] = class_names(
|
40
|
+
"Box-footer",
|
41
|
+
system_arguments[:classes]
|
42
|
+
)
|
43
|
+
|
44
|
+
Primer::BaseComponent.new(**system_arguments)
|
45
|
+
}
|
46
|
+
|
47
|
+
# Use Rows to add rows with borders and maintain the same padding.
|
48
|
+
#
|
49
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
50
|
+
renders_many :rows, lambda { |**system_arguments|
|
51
|
+
system_arguments[:tag] = :li
|
52
|
+
system_arguments[:classes] = class_names(
|
53
|
+
"Box-row",
|
54
|
+
system_arguments[:classes]
|
55
|
+
)
|
56
|
+
|
57
|
+
Primer::BaseComponent.new(**system_arguments)
|
58
|
+
}
|
50
59
|
|
51
|
-
#
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
60
|
+
# @example Header, body, rows, and footer
|
61
|
+
# <%= render(Primer::BorderBoxComponent.new) do |component| %>
|
62
|
+
# <% component.header do %>
|
63
|
+
# Header
|
64
|
+
# <% end %>
|
65
|
+
# <% component.body do %>
|
66
|
+
# Body
|
67
|
+
# <% end %>
|
68
|
+
# <% component.row do %>
|
69
|
+
# <% if true %>
|
70
|
+
# Row one
|
71
|
+
# <% end %>
|
72
|
+
# <% end %>
|
73
|
+
# <% component.row do %>
|
74
|
+
# Row two
|
75
|
+
# <% end %>
|
76
|
+
# <% component.footer do %>
|
77
|
+
# Footer
|
78
|
+
# <% end %>
|
79
|
+
# <% end %>
|
80
|
+
#
|
81
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
82
|
+
def initialize(**system_arguments)
|
83
|
+
@system_arguments = system_arguments
|
84
|
+
@system_arguments[:tag] = :div
|
85
|
+
@system_arguments[:classes] = class_names("Box", system_arguments[:classes])
|
63
86
|
end
|
64
87
|
|
65
|
-
|
66
|
-
|
67
|
-
attr_reader :system_arguments
|
68
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
69
|
-
def initialize(**system_arguments)
|
70
|
-
@system_arguments = system_arguments
|
71
|
-
@system_arguments[:tag] = :div
|
72
|
-
@system_arguments[:classes] = class_names(
|
73
|
-
"Box-footer",
|
74
|
-
system_arguments[:classes]
|
75
|
-
)
|
76
|
-
end
|
88
|
+
def render?
|
89
|
+
rows.any? || header.present? || body.present? || footer.present?
|
77
90
|
end
|
78
91
|
|
79
|
-
|
80
|
-
|
81
|
-
attr_reader :system_arguments
|
82
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
83
|
-
def initialize(**system_arguments)
|
84
|
-
@system_arguments = system_arguments
|
85
|
-
@system_arguments[:tag] = :li
|
86
|
-
@system_arguments[:classes] = class_names(
|
87
|
-
"Box-row",
|
88
|
-
system_arguments[:classes]
|
89
|
-
)
|
90
|
-
end
|
92
|
+
def self.status
|
93
|
+
Primer::Component::STATUSES[:beta]
|
91
94
|
end
|
92
95
|
end
|
93
96
|
end
|
@@ -3,10 +3,10 @@
|
|
3
3
|
module Primer
|
4
4
|
# A basic wrapper component for most layout related needs.
|
5
5
|
class BoxComponent < Primer::Component
|
6
|
-
# @example
|
6
|
+
# @example Default
|
7
7
|
# <%= render(Primer::BoxComponent.new) { "Your content here" } %>
|
8
8
|
#
|
9
|
-
# @example
|
9
|
+
# @example Color and padding
|
10
10
|
# <%= render(Primer::BoxComponent.new(bg: :gray, p: 3)) { "Hello world" } %>
|
11
11
|
#
|
12
12
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
@@ -7,7 +7,7 @@ module Primer
|
|
7
7
|
|
8
8
|
with_slot :item, collection: true, class_name: "BreadcrumbItem"
|
9
9
|
|
10
|
-
# @example
|
10
|
+
# @example Basic
|
11
11
|
# <%= render(Primer::BreadcrumbComponent.new) do |component| %>
|
12
12
|
# <% component.slot(:item, href: "/") do %>Home<% end %>
|
13
13
|
# <% component.slot(:item, href: "/about") do %>About<% end %>
|
@@ -26,13 +26,13 @@ module Primer
|
|
26
26
|
DEFAULT_TYPE = :button
|
27
27
|
TYPE_OPTIONS = [DEFAULT_TYPE, :reset, :submit].freeze
|
28
28
|
|
29
|
-
# @example
|
29
|
+
# @example Button types
|
30
30
|
# <%= render(Primer::ButtonComponent.new) { "Default" } %>
|
31
31
|
# <%= render(Primer::ButtonComponent.new(button_type: :primary)) { "Primary" } %>
|
32
32
|
# <%= render(Primer::ButtonComponent.new(button_type: :danger)) { "Danger" } %>
|
33
33
|
# <%= render(Primer::ButtonComponent.new(button_type: :outline)) { "Outline" } %>
|
34
34
|
#
|
35
|
-
# @example
|
35
|
+
# @example Variants
|
36
36
|
# <%= render(Primer::ButtonComponent.new(variant: :small)) { "Small" } %>
|
37
37
|
# <%= render(Primer::ButtonComponent.new(variant: :medium)) { "Medium" } %>
|
38
38
|
# <%= render(Primer::ButtonComponent.new(variant: :large)) { "Large" } %>
|
@@ -5,9 +5,12 @@ module Primer
|
|
5
5
|
class ButtonGroupComponent < Primer::Component
|
6
6
|
include ViewComponent::SlotableV2
|
7
7
|
|
8
|
+
# Required list of buttons to be rendered.
|
9
|
+
#
|
10
|
+
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::ButtonComponent) %>.
|
8
11
|
renders_many :buttons, ->(**kwargs) { Primer::ButtonComponent.new(group_item: true, **kwargs) }
|
9
12
|
|
10
|
-
# @example
|
13
|
+
# @example Default
|
11
14
|
# <%= render(Primer::ButtonGroupComponent.new) do |component|
|
12
15
|
# component.button { "Default" }
|
13
16
|
# component.button(button_type: :primary) { "Primary" }
|
@@ -25,7 +25,7 @@ module Primer
|
|
25
25
|
DEFAULT_TYPE = :button
|
26
26
|
TYPE_OPTIONS = [DEFAULT_TYPE, :submit].freeze
|
27
27
|
|
28
|
-
# @example
|
28
|
+
# @example Button types
|
29
29
|
# <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
|
30
30
|
# <%= render(Primer::ButtonMarketingComponent.new(button_type: :primary, mr: 2)) { "Primary" } %>
|
31
31
|
# <%= render(Primer::ButtonMarketingComponent.new(button_type: :outline)) { "Outline" } %>
|
@@ -33,7 +33,7 @@ module Primer
|
|
33
33
|
# <%= render(Primer::ButtonMarketingComponent.new(button_type: :transparent)) { "Transparent" } %>
|
34
34
|
# </div>
|
35
35
|
#
|
36
|
-
# @example
|
36
|
+
# @example Sizes
|
37
37
|
# <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
|
38
38
|
# <%= render(Primer::ButtonMarketingComponent.new(variant: :large)) { "Large" } %>
|
39
39
|
#
|
@@ -1,5 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "octicons_helper/helper"
|
4
|
+
|
3
5
|
module Primer
|
4
6
|
# @private
|
5
7
|
class Component < ViewComponent::Base
|
@@ -7,18 +9,19 @@ module Primer
|
|
7
9
|
include FetchOrFallbackHelper
|
8
10
|
include OcticonsHelper
|
9
11
|
include JoinStyleArgumentsHelper
|
12
|
+
include ViewHelper::DSL
|
13
|
+
include ViewHelper
|
10
14
|
|
11
15
|
# sourced from https://primer.style/doctocat/usage/front-matter#status
|
12
16
|
STATUSES = {
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
stable: :stable
|
17
|
+
alpha: :alpha,
|
18
|
+
beta: :beta,
|
19
|
+
stable: :stable,
|
20
|
+
deprecated: :deprecated
|
18
21
|
}.freeze
|
19
22
|
|
20
23
|
def self.status
|
21
|
-
STATUSES[:
|
24
|
+
STATUSES[:alpha]
|
22
25
|
end
|
23
26
|
end
|
24
27
|
end
|
@@ -11,7 +11,7 @@ module Primer
|
|
11
11
|
}.freeze
|
12
12
|
|
13
13
|
#
|
14
|
-
# @example
|
14
|
+
# @example Default
|
15
15
|
# <%= render(Primer::CounterComponent.new(count: 25)) %>
|
16
16
|
#
|
17
17
|
# @param count [Integer, Float::INFINITY, nil] The number to be displayed (e.x. # of issues, pull requests)
|
@@ -51,6 +51,10 @@ module Primer
|
|
51
51
|
render(Primer::BaseComponent.new(**@system_arguments)) { value }
|
52
52
|
end
|
53
53
|
|
54
|
+
def self.status
|
55
|
+
Primer::Component::STATUSES[:beta]
|
56
|
+
end
|
57
|
+
|
54
58
|
private
|
55
59
|
|
56
60
|
def title
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Primer
|
4
4
|
# Use DetailsComponent to reveal content after clicking a button.
|
5
5
|
class DetailsComponent < Primer::Component
|
6
|
-
include ViewComponent::
|
6
|
+
include ViewComponent::SlotableV2
|
7
7
|
|
8
8
|
NO_OVERLAY = :none
|
9
9
|
OVERLAY_MAPPINGS = {
|
@@ -12,8 +12,27 @@ module Primer
|
|
12
12
|
:dark => "details-overlay details-overlay-dark"
|
13
13
|
}.freeze
|
14
14
|
|
15
|
-
|
16
|
-
|
15
|
+
# Use the Summary slot as a trigger to reveal the content.
|
16
|
+
#
|
17
|
+
# @param button [Boolean] Whether to render the Summary as a button or not.
|
18
|
+
# @param kwargs [Hash] The same arguments as <%= link_to_system_arguments_docs %>.
|
19
|
+
renders_one :summary, lambda { |button = true, **system_arguments|
|
20
|
+
system_arguments = system_arguments
|
21
|
+
system_arguments[:tag] = :summary
|
22
|
+
system_arguments[:role] = "button"
|
23
|
+
|
24
|
+
Primer::BaseComponent.new(**system_arguments) unless button
|
25
|
+
|
26
|
+
Primer::ButtonComponent.new(**system_arguments)
|
27
|
+
}
|
28
|
+
|
29
|
+
# Use the Body slot as the main content to be shown when triggered by the Summary.
|
30
|
+
#
|
31
|
+
# @param kwargs [Hash] The same arguments as <%= link_to_system_arguments_docs %>.
|
32
|
+
renders_one :body, lambda { |**system_arguments|
|
33
|
+
system_arguments[:tag] ||= :div
|
34
|
+
Primer::BaseComponent.new(**system_arguments)
|
35
|
+
}
|
17
36
|
|
18
37
|
# @param overlay [Symbol] Dictates the type of overlay to render with. <%= one_of(Primer::DetailsComponent::OVERLAY_MAPPINGS.keys) %>
|
19
38
|
# @param reset [Boolean] Defatuls to false. If set to true, it will remove the default caret and remove style from the summary element
|
@@ -31,37 +50,5 @@ module Primer
|
|
31
50
|
def render?
|
32
51
|
summary.present? && body.present?
|
33
52
|
end
|
34
|
-
|
35
|
-
# Use the Summary slot as a trigger to reveal the content.
|
36
|
-
class Summary < Primer::Slot
|
37
|
-
# @param button [Boolean] Whether to render the Summary as a button or not.
|
38
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
39
|
-
def initialize(button: true, **system_arguments)
|
40
|
-
@button = button
|
41
|
-
|
42
|
-
@system_arguments = system_arguments
|
43
|
-
@system_arguments[:tag] = :summary
|
44
|
-
@system_arguments[:role] = "button"
|
45
|
-
end
|
46
|
-
|
47
|
-
def component
|
48
|
-
return Primer::BaseComponent.new(**@system_arguments) unless @button
|
49
|
-
|
50
|
-
Primer::ButtonComponent.new(**@system_arguments)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
# Use the Body slot as the main content to be shown when triggered by the Summary.
|
55
|
-
class Body < Primer::Slot
|
56
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
57
|
-
def initialize(**system_arguments)
|
58
|
-
@system_arguments = system_arguments
|
59
|
-
@system_arguments[:tag] ||= :div
|
60
|
-
end
|
61
|
-
|
62
|
-
def component
|
63
|
-
Primer::BaseComponent.new(**@system_arguments)
|
64
|
-
end
|
65
|
-
end
|
66
53
|
end
|
67
54
|
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
module Dropdown
|
5
|
+
# This component is part of `Primer::DropdownComponent` and should not be
|
6
|
+
# used as a standalone component.
|
7
|
+
class MenuComponent < Primer::Component
|
8
|
+
include ViewComponent::SlotableV2
|
9
|
+
|
10
|
+
SCHEME_DEFAULT = :default
|
11
|
+
SCHEME_MAPPINGS = {
|
12
|
+
SCHEME_DEFAULT => "",
|
13
|
+
:dark => "dropdown-menu-dark"
|
14
|
+
}.freeze
|
15
|
+
|
16
|
+
DIRECTION_DEFAULT = :se
|
17
|
+
DIRECTION_OPTIONS = [DIRECTION_DEFAULT, :sw, :w, :e, :ne, :s].freeze
|
18
|
+
|
19
|
+
renders_many :items, lambda { |divider: false, **system_arguments|
|
20
|
+
system_arguments[:tag] = :li
|
21
|
+
system_arguments[:role] = :none if divider
|
22
|
+
system_arguments[:classes] = class_names(
|
23
|
+
system_arguments[:classes],
|
24
|
+
"dropdown-item" => !divider,
|
25
|
+
"dropdown-divider" => divider
|
26
|
+
)
|
27
|
+
|
28
|
+
Primer::BaseComponent.new(**system_arguments)
|
29
|
+
}
|
30
|
+
|
31
|
+
def initialize(direction: DIRECTION_DEFAULT, scheme: SCHEME_DEFAULT, header: nil, **system_arguments)
|
32
|
+
@header = header
|
33
|
+
@direction = direction
|
34
|
+
@system_arguments = system_arguments
|
35
|
+
|
36
|
+
@system_arguments[:tag] = "details-menu"
|
37
|
+
@system_arguments[:role] = "menu"
|
38
|
+
|
39
|
+
@system_arguments[:classes] = class_names(
|
40
|
+
@system_arguments[:classes],
|
41
|
+
"dropdown-menu",
|
42
|
+
"dropdown-menu-#{fetch_or_fallback(DIRECTION_OPTIONS, direction, DIRECTION_DEFAULT)}",
|
43
|
+
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_MAPPINGS.keys, scheme, SCHEME_DEFAULT)]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|