primer_view_components 0.0.14 → 0.0.19
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 +82 -0
- data/app/components/primer/avatar_component.rb +24 -6
- 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 +63 -15
- data/app/components/primer/blankslate_component.html.erb +4 -4
- data/app/components/primer/blankslate_component.rb +34 -8
- data/app/components/primer/border_box_component.rb +29 -13
- data/app/components/primer/box_component.rb +10 -0
- data/app/components/primer/breadcrumb_component.rb +3 -2
- data/app/components/primer/button_component.rb +3 -3
- data/app/components/primer/button_group_component.html.erb +5 -0
- data/app/components/primer/button_group_component.rb +37 -0
- data/app/components/primer/button_marketing_component.rb +73 -0
- data/app/components/primer/component.rb +13 -0
- data/app/components/primer/counter_component.rb +21 -13
- data/app/components/primer/details_component.rb +10 -6
- 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 +77 -0
- data/app/components/primer/dropdown_menu_component.rb +35 -3
- data/app/components/primer/flash_component.rb +10 -7
- data/app/components/primer/flex_component.rb +47 -9
- data/app/components/primer/flex_item_component.rb +16 -1
- data/app/components/primer/heading_component.rb +7 -0
- data/app/components/primer/label_component.rb +6 -6
- data/app/components/primer/layout_component.rb +2 -2
- data/app/components/primer/link_component.rb +7 -3
- 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 +11 -6
- data/app/components/primer/popover_component.rb +6 -4
- data/app/components/primer/progress_bar_component.rb +9 -9
- data/app/components/primer/slot.rb +1 -0
- data/app/components/primer/spinner_component.rb +10 -7
- data/app/components/primer/state_component.rb +6 -6
- data/app/components/primer/subhead_component.rb +6 -3
- data/app/components/primer/text_component.rb +1 -1
- data/app/components/primer/timeline_item_component.rb +4 -1
- data/app/components/primer/tooltip_component.rb +88 -0
- data/app/components/primer/truncate_component.rb +41 -0
- data/app/components/primer/underline_nav_component.rb +26 -1
- data/app/components/primer/view_components.rb +9 -0
- data/lib/primer/class_name_helper.rb +1 -0
- data/lib/primer/classify.rb +141 -106
- data/lib/primer/classify/cache.rb +125 -0
- data/lib/primer/fetch_or_fallback_helper.rb +9 -0
- data/lib/primer/join_style_arguments_helper.rb +14 -0
- data/lib/primer/view_components.rb +32 -0
- data/lib/primer/view_components/engine.rb +1 -0
- data/lib/primer/view_components/version.rb +1 -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 +80 -19
@@ -10,30 +10,43 @@ module Primer
|
|
10
10
|
with_slot :footer, class_name: "Footer"
|
11
11
|
with_slot :row, collection: true, class_name: "Row"
|
12
12
|
|
13
|
-
# @example
|
14
|
-
# <%= render(Primer::BorderBoxComponent.new) do |component|
|
15
|
-
# component.slot(:header)
|
16
|
-
#
|
17
|
-
#
|
18
|
-
# component.slot(:
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
13
|
+
# @example auto|Header, body, rows, and footer
|
14
|
+
# <%= render(Primer::BorderBoxComponent.new) do |component| %>
|
15
|
+
# <% component.slot(:header) do %>
|
16
|
+
# Header
|
17
|
+
# <% end %>
|
18
|
+
# <% component.slot(:body) do %>
|
19
|
+
# Body
|
20
|
+
# <% end %>
|
21
|
+
# <% component.slot(:row) do %>
|
22
|
+
# <% if true %>
|
23
|
+
# Row one
|
24
|
+
# <% end %>
|
25
|
+
# <% end %>
|
26
|
+
# <% component.slot(:row) do %>
|
27
|
+
# Row two
|
28
|
+
# <% end %>
|
29
|
+
# <% component.slot(:footer) do %>
|
30
|
+
# Footer
|
31
|
+
# <% end %>
|
32
|
+
# <% end %>
|
22
33
|
#
|
23
34
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
24
35
|
def initialize(**system_arguments)
|
25
36
|
@system_arguments = system_arguments
|
26
37
|
@system_arguments[:tag] = :div
|
27
|
-
@system_arguments[:classes] = class_names(
|
28
|
-
"Box",
|
29
|
-
system_arguments[:classes]
|
30
|
-
)
|
38
|
+
@system_arguments[:classes] = class_names("Box", system_arguments[:classes])
|
31
39
|
end
|
32
40
|
|
33
41
|
def render?
|
34
42
|
rows.any? || header.present? || body.present? || footer.present?
|
35
43
|
end
|
36
44
|
|
45
|
+
def self.status
|
46
|
+
Primer::Component::STATUSES[:beta]
|
47
|
+
end
|
48
|
+
|
49
|
+
# :nodoc:
|
37
50
|
class Header < Primer::Slot
|
38
51
|
attr_reader :system_arguments
|
39
52
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
@@ -47,6 +60,7 @@ module Primer
|
|
47
60
|
end
|
48
61
|
end
|
49
62
|
|
63
|
+
# :nodoc:
|
50
64
|
class Body < Primer::Slot
|
51
65
|
attr_reader :system_arguments
|
52
66
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
@@ -60,6 +74,7 @@ module Primer
|
|
60
74
|
end
|
61
75
|
end
|
62
76
|
|
77
|
+
# :nodoc:
|
63
78
|
class Footer < Primer::Slot
|
64
79
|
attr_reader :system_arguments
|
65
80
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
@@ -73,6 +88,7 @@ module Primer
|
|
73
88
|
end
|
74
89
|
end
|
75
90
|
|
91
|
+
# :nodoc:
|
76
92
|
class Row < Primer::Slot
|
77
93
|
attr_reader :system_arguments
|
78
94
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
@@ -3,6 +3,12 @@
|
|
3
3
|
module Primer
|
4
4
|
# A basic wrapper component for most layout related needs.
|
5
5
|
class BoxComponent < Primer::Component
|
6
|
+
# @example auto|Default
|
7
|
+
# <%= render(Primer::BoxComponent.new) { "Your content here" } %>
|
8
|
+
#
|
9
|
+
# @example auto|Color and padding
|
10
|
+
# <%= render(Primer::BoxComponent.new(bg: :gray, p: 3)) { "Hello world" } %>
|
11
|
+
#
|
6
12
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
7
13
|
def initialize(**system_arguments)
|
8
14
|
@system_arguments = system_arguments
|
@@ -12,5 +18,9 @@ module Primer
|
|
12
18
|
def call
|
13
19
|
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
14
20
|
end
|
21
|
+
|
22
|
+
def self.status
|
23
|
+
Primer::Component::STATUSES[:stable]
|
24
|
+
end
|
15
25
|
end
|
16
26
|
end
|
@@ -7,7 +7,7 @@ module Primer
|
|
7
7
|
|
8
8
|
with_slot :item, collection: true, class_name: "BreadcrumbItem"
|
9
9
|
|
10
|
-
# @example
|
10
|
+
# @example auto|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 %>
|
@@ -33,7 +33,8 @@ module Primer
|
|
33
33
|
# @param selected [Boolean] Whether or not the item is selected and not rendered as a link.
|
34
34
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
35
35
|
def initialize(href: nil, selected: false, **system_arguments)
|
36
|
-
@href
|
36
|
+
@href = href
|
37
|
+
@system_arguments = system_arguments
|
37
38
|
|
38
39
|
@href = nil if selected
|
39
40
|
@system_arguments[:tag] = :li
|
@@ -16,7 +16,7 @@ module Primer
|
|
16
16
|
VARIANT_MAPPINGS = {
|
17
17
|
:small => "btn-sm",
|
18
18
|
DEFAULT_VARIANT => "",
|
19
|
-
:large => "btn-large"
|
19
|
+
:large => "btn-large"
|
20
20
|
}.freeze
|
21
21
|
VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
|
22
22
|
|
@@ -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 auto|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 auto|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" } %>
|
@@ -0,0 +1,37 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# Use ButtonGroupComponent to render a series of buttons.
|
5
|
+
class ButtonGroupComponent < Primer::Component
|
6
|
+
include ViewComponent::SlotableV2
|
7
|
+
|
8
|
+
# Required list of buttons to be rendered.
|
9
|
+
#
|
10
|
+
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::ButtonComponent) %>.
|
11
|
+
renders_many :buttons, ->(**kwargs) { Primer::ButtonComponent.new(group_item: true, **kwargs) }
|
12
|
+
|
13
|
+
# @example auto|Default
|
14
|
+
# <%= render(Primer::ButtonGroupComponent.new) do |component|
|
15
|
+
# component.button { "Default" }
|
16
|
+
# component.button(button_type: :primary) { "Primary" }
|
17
|
+
# component.button(button_type: :danger) { "Danger" }
|
18
|
+
# component.button(button_type: :outline) { "Outline" }
|
19
|
+
# component.button(classes: "my-class") { "Custom class" }
|
20
|
+
# end %>
|
21
|
+
#
|
22
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
23
|
+
def initialize(**system_arguments)
|
24
|
+
@system_arguments = system_arguments
|
25
|
+
@system_arguments[:tag] ||= :div
|
26
|
+
|
27
|
+
@system_arguments[:classes] = class_names(
|
28
|
+
"BtnGroup",
|
29
|
+
system_arguments[:classes]
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
def render?
|
34
|
+
buttons.any?
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
@@ -0,0 +1,73 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# Use buttons for actions (e.g. in forms). Use links for destinations, or moving from one page to another.
|
5
|
+
class ButtonMarketingComponent < Primer::Component
|
6
|
+
DEFAULT_BUTTON_TYPE = :default
|
7
|
+
BUTTON_TYPE_MAPPINGS = {
|
8
|
+
DEFAULT_BUTTON_TYPE => "",
|
9
|
+
:primary => "btn-primary-mktg",
|
10
|
+
:outline => "btn-outline-mktg",
|
11
|
+
:transparent => "btn-transparent"
|
12
|
+
}.freeze
|
13
|
+
BUTTON_TYPE_OPTIONS = BUTTON_TYPE_MAPPINGS.keys
|
14
|
+
|
15
|
+
DEFAULT_VARIANT = :default
|
16
|
+
VARIANT_MAPPINGS = {
|
17
|
+
DEFAULT_VARIANT => "",
|
18
|
+
:large => "btn-large-mktg"
|
19
|
+
}.freeze
|
20
|
+
VARIANT_OPTIONS = VARIANT_MAPPINGS.keys
|
21
|
+
|
22
|
+
DEFAULT_TAG = :button
|
23
|
+
TAG_OPTIONS = [DEFAULT_TAG, :a].freeze
|
24
|
+
|
25
|
+
DEFAULT_TYPE = :button
|
26
|
+
TYPE_OPTIONS = [DEFAULT_TYPE, :submit].freeze
|
27
|
+
|
28
|
+
# @example auto|Button types
|
29
|
+
# <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
|
30
|
+
# <%= render(Primer::ButtonMarketingComponent.new(button_type: :primary, mr: 2)) { "Primary" } %>
|
31
|
+
# <%= render(Primer::ButtonMarketingComponent.new(button_type: :outline)) { "Outline" } %>
|
32
|
+
# <div class="bg-gray-dark">
|
33
|
+
# <%= render(Primer::ButtonMarketingComponent.new(button_type: :transparent)) { "Transparent" } %>
|
34
|
+
# </div>
|
35
|
+
#
|
36
|
+
# @example auto|Sizes
|
37
|
+
# <%= render(Primer::ButtonMarketingComponent.new(mr: 2)) { "Default" } %>
|
38
|
+
# <%= render(Primer::ButtonMarketingComponent.new(variant: :large)) { "Large" } %>
|
39
|
+
#
|
40
|
+
# @param button_type [Symbol] <%= one_of(Primer::ButtonMarketingComponent::BUTTON_TYPE_OPTIONS) %>
|
41
|
+
# @param variant [Symbol] <%= one_of(Primer::ButtonMarketingComponent::VARIANT_OPTIONS) %>
|
42
|
+
# @param tag [Symbol] <%= one_of(Primer::ButtonMarketingComponent::TAG_OPTIONS) %>
|
43
|
+
# @param type [Symbol] <%= one_of(Primer::ButtonMarketingComponent::TYPE_OPTIONS) %>
|
44
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
45
|
+
def initialize(
|
46
|
+
button_type: DEFAULT_BUTTON_TYPE,
|
47
|
+
variant: DEFAULT_VARIANT,
|
48
|
+
tag: DEFAULT_TAG,
|
49
|
+
type: DEFAULT_TYPE,
|
50
|
+
**system_arguments
|
51
|
+
)
|
52
|
+
@system_arguments = system_arguments
|
53
|
+
@system_arguments[:tag] = fetch_or_fallback(TAG_OPTIONS, tag, DEFAULT_TAG)
|
54
|
+
|
55
|
+
if @system_arguments[:tag] == :a
|
56
|
+
@system_arguments[:role] = :button
|
57
|
+
else
|
58
|
+
@system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
|
59
|
+
end
|
60
|
+
|
61
|
+
@system_arguments[:classes] = class_names(
|
62
|
+
"btn-mktg",
|
63
|
+
BUTTON_TYPE_MAPPINGS[fetch_or_fallback(BUTTON_TYPE_OPTIONS, button_type, DEFAULT_BUTTON_TYPE)],
|
64
|
+
VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant, DEFAULT_VARIANT)],
|
65
|
+
system_arguments[:classes]
|
66
|
+
)
|
67
|
+
end
|
68
|
+
|
69
|
+
def call
|
70
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -6,5 +6,18 @@ module Primer
|
|
6
6
|
include ClassNameHelper
|
7
7
|
include FetchOrFallbackHelper
|
8
8
|
include OcticonsHelper
|
9
|
+
include JoinStyleArgumentsHelper
|
10
|
+
|
11
|
+
# sourced from https://primer.style/doctocat/usage/front-matter#status
|
12
|
+
STATUSES = {
|
13
|
+
alpha: :alpha,
|
14
|
+
beta: :beta,
|
15
|
+
stable: :stable,
|
16
|
+
deprecated: :deprecated
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
def self.status
|
20
|
+
STATUSES[:alpha]
|
21
|
+
end
|
9
22
|
end
|
10
23
|
end
|
@@ -7,16 +7,16 @@ module Primer
|
|
7
7
|
SCHEME_MAPPINGS = {
|
8
8
|
DEFAULT_SCHEME => "Counter",
|
9
9
|
:gray => "Counter Counter--gray",
|
10
|
-
:light_gray => "Counter Counter--gray-light"
|
10
|
+
:light_gray => "Counter Counter--gray-light"
|
11
11
|
}.freeze
|
12
12
|
|
13
13
|
#
|
14
|
-
# @example
|
14
|
+
# @example auto|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)
|
18
18
|
# @param scheme [Symbol] Color scheme. One of `SCHEME_MAPPINGS.keys`.
|
19
|
-
# @param limit [Integer] Maximum value to display. (e.x. if count == 6,000 and limit == 5000, counter will display "5,000+")
|
19
|
+
# @param limit [Integer, nil] Maximum value to display. Pass `nil` for no limit. (e.x. if `count` == 6,000 and `limit` == 5000, counter will display "5,000+")
|
20
20
|
# @param hide_if_zero [Boolean] If true, a `hidden` attribute is added to the counter if `count` is zero.
|
21
21
|
# @param text [String] Text to display instead of count.
|
22
22
|
# @param round [Boolean] Whether to apply our standard rounding logic to value.
|
@@ -30,23 +30,31 @@ module Primer
|
|
30
30
|
round: false,
|
31
31
|
**system_arguments
|
32
32
|
)
|
33
|
-
@count
|
33
|
+
@count = count
|
34
|
+
@limit = limit
|
35
|
+
@hide_if_zero = hide_if_zero
|
36
|
+
@text = text
|
37
|
+
@round = round
|
38
|
+
@system_arguments = system_arguments
|
34
39
|
|
40
|
+
@has_limit = !@limit.nil?
|
35
41
|
@system_arguments[:title] = title
|
36
42
|
@system_arguments[:tag] = :span
|
37
43
|
@system_arguments[:classes] = class_names(
|
38
44
|
@system_arguments[:classes],
|
39
45
|
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_MAPPINGS.keys, scheme, DEFAULT_SCHEME)]
|
40
46
|
)
|
41
|
-
if count == 0 && hide_if_zero
|
42
|
-
@system_arguments[:hidden] = true
|
43
|
-
end
|
47
|
+
@system_arguments[:hidden] = true if count == 0 && hide_if_zero # rubocop:disable Style/NumericPredicate
|
44
48
|
end
|
45
49
|
|
46
50
|
def call
|
47
51
|
render(Primer::BaseComponent.new(**@system_arguments)) { value }
|
48
52
|
end
|
49
53
|
|
54
|
+
def self.status
|
55
|
+
Primer::Component::STATUSES[:beta]
|
56
|
+
end
|
57
|
+
|
50
58
|
private
|
51
59
|
|
52
60
|
def title
|
@@ -58,8 +66,8 @@ module Primer
|
|
58
66
|
"Infinity"
|
59
67
|
else
|
60
68
|
count = @count.to_i
|
61
|
-
str = number_with_delimiter([count, @limit].min)
|
62
|
-
str += "+" if count > @limit
|
69
|
+
str = number_with_delimiter(@has_limit ? [count, @limit].min : count)
|
70
|
+
str += "+" if @has_limit && count > @limit
|
63
71
|
str
|
64
72
|
end
|
65
73
|
end
|
@@ -73,16 +81,16 @@ module Primer
|
|
73
81
|
"∞"
|
74
82
|
else
|
75
83
|
if @round
|
76
|
-
count = [@count.to_i, @limit].min
|
84
|
+
count = @has_limit ? [@count.to_i, @limit].min : @count.to_i
|
77
85
|
precision = count.between?(100_000, 999_999) ? 0 : 1
|
78
|
-
units = {thousand: "k", million: "m", billion: "b"}
|
86
|
+
units = { thousand: "k", million: "m", billion: "b" }
|
79
87
|
str = number_to_human(count, precision: precision, significant: false, units: units, format: "%n%u")
|
80
88
|
else
|
81
89
|
@count = @count.to_i
|
82
|
-
str = number_with_delimiter([@count, @limit].min)
|
90
|
+
str = number_with_delimiter(@has_limit ? [@count, @limit].min : @count)
|
83
91
|
end
|
84
92
|
|
85
|
-
str += "+" if @count.to_i > @limit
|
93
|
+
str += "+" if @has_limit && @count.to_i > @limit
|
86
94
|
str
|
87
95
|
end
|
88
96
|
end
|
@@ -1,11 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
#
|
5
|
-
# overlay - options are `none`, `default` and `dark`. Dictates the type of overlay to render with.
|
6
|
-
# button - options are `default` and `reset`. default will make the target a default primer ``.btn`
|
7
|
-
# reset will remove all styles from the <summary> element.
|
8
|
-
#
|
4
|
+
# Use DetailsComponent to reveal content after clicking a button.
|
9
5
|
class DetailsComponent < Primer::Component
|
10
6
|
include ViewComponent::Slotable
|
11
7
|
|
@@ -13,12 +9,15 @@ module Primer
|
|
13
9
|
OVERLAY_MAPPINGS = {
|
14
10
|
NO_OVERLAY => "",
|
15
11
|
:default => "details-overlay",
|
16
|
-
:dark => "details-overlay details-overlay-dark"
|
12
|
+
:dark => "details-overlay details-overlay-dark"
|
17
13
|
}.freeze
|
18
14
|
|
19
15
|
with_slot :body, class_name: "Body"
|
20
16
|
with_slot :summary, class_name: "Summary"
|
21
17
|
|
18
|
+
# @param overlay [Symbol] Dictates the type of overlay to render with. <%= one_of(Primer::DetailsComponent::OVERLAY_MAPPINGS.keys) %>
|
19
|
+
# @param reset [Boolean] Defatuls to false. If set to true, it will remove the default caret and remove style from the summary element
|
20
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
22
21
|
def initialize(overlay: NO_OVERLAY, reset: false, **system_arguments)
|
23
22
|
@system_arguments = system_arguments
|
24
23
|
@system_arguments[:tag] = :details
|
@@ -33,7 +32,10 @@ module Primer
|
|
33
32
|
summary.present? && body.present?
|
34
33
|
end
|
35
34
|
|
35
|
+
# Use the Summary slot as a trigger to reveal the content.
|
36
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 %>
|
37
39
|
def initialize(button: true, **system_arguments)
|
38
40
|
@button = button
|
39
41
|
|
@@ -49,7 +51,9 @@ module Primer
|
|
49
51
|
end
|
50
52
|
end
|
51
53
|
|
54
|
+
# Use the Body slot as the main content to be shown when triggered by the Summary.
|
52
55
|
class Body < Primer::Slot
|
56
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
53
57
|
def initialize(**system_arguments)
|
54
58
|
@system_arguments = system_arguments
|
55
59
|
@system_arguments[:tag] ||= :div
|
@@ -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
|