primer_view_components 0.0.9 → 0.0.14
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 +31 -1
- data/README.md +2 -175
- data/app/components/primer/avatar_component.rb +22 -11
- data/app/components/primer/base_component.rb +56 -11
- data/app/components/primer/blankslate_component.html.erb +1 -1
- data/app/components/primer/blankslate_component.rb +71 -116
- data/app/components/primer/border_box_component.html.erb +5 -5
- data/app/components/primer/border_box_component.rb +45 -33
- data/app/components/primer/box_component.rb +6 -4
- data/app/components/primer/breadcrumb_component.html.erb +2 -2
- data/app/components/primer/breadcrumb_component.rb +23 -30
- data/app/components/primer/button_component.rb +26 -9
- data/app/components/primer/component.rb +1 -0
- data/app/components/primer/counter_component.rb +13 -9
- data/app/components/primer/details_component.html.erb +1 -1
- data/app/components/primer/details_component.rb +18 -18
- data/app/components/primer/dropdown_menu_component.html.erb +1 -1
- data/app/components/primer/dropdown_menu_component.rb +6 -6
- data/app/components/primer/flash_component.html.erb +2 -2
- data/app/components/primer/flash_component.rb +42 -12
- data/app/components/primer/flex_component.rb +5 -5
- data/app/components/primer/flex_item_component.rb +5 -5
- data/app/components/primer/heading_component.rb +4 -4
- data/app/components/primer/label_component.rb +37 -14
- data/app/components/primer/layout_component.html.erb +1 -1
- data/app/components/primer/layout_component.rb +22 -5
- data/app/components/primer/link_component.rb +17 -7
- data/app/components/primer/octicon_component.rb +20 -7
- data/app/components/primer/popover_component.html.erb +1 -1
- data/app/components/primer/popover_component.rb +61 -23
- data/app/components/primer/progress_bar_component.html.erb +2 -2
- data/app/components/primer/progress_bar_component.rb +40 -30
- data/app/components/primer/slot.rb +1 -0
- data/app/components/primer/spinner_component.html.erb +6 -0
- data/app/components/primer/spinner_component.rb +39 -0
- data/app/components/primer/state_component.rb +26 -14
- data/app/components/primer/subhead_component.html.erb +4 -4
- data/app/components/primer/subhead_component.rb +68 -43
- data/app/components/primer/text_component.rb +10 -4
- data/app/components/primer/timeline_item_component.html.erb +4 -4
- data/app/components/primer/timeline_item_component.rb +48 -24
- data/app/components/primer/underline_nav_component.html.erb +1 -1
- data/app/components/primer/underline_nav_component.rb +5 -5
- data/app/components/primer/view_components.rb +1 -0
- data/lib/primer/classify.rb +2 -4
- data/lib/primer/view_components/version.rb +1 -1
- metadata +4 -2
@@ -11,14 +11,14 @@ module Primer
|
|
11
11
|
DIRECTION_DEFAULT = :se
|
12
12
|
DIRECTION_OPTIONS = [DIRECTION_DEFAULT, :sw, :w, :e, :ne, :s]
|
13
13
|
|
14
|
-
def initialize(direction: DIRECTION_DEFAULT, scheme: SCHEME_DEFAULT, header: nil, **
|
15
|
-
@header, @direction, @
|
14
|
+
def initialize(direction: DIRECTION_DEFAULT, scheme: SCHEME_DEFAULT, header: nil, **system_arguments)
|
15
|
+
@header, @direction, @system_arguments = header, direction, system_arguments
|
16
16
|
|
17
|
-
@
|
18
|
-
@
|
17
|
+
@system_arguments[:tag] = "details-menu"
|
18
|
+
@system_arguments[:role] = "menu"
|
19
19
|
|
20
|
-
@
|
21
|
-
@
|
20
|
+
@system_arguments[:classes] = class_names(
|
21
|
+
@system_arguments[:classes],
|
22
22
|
"dropdown-menu",
|
23
23
|
"dropdown-menu-#{fetch_or_fallback(DIRECTION_OPTIONS, direction, DIRECTION_DEFAULT)}",
|
24
24
|
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_MAPPINGS.keys, scheme, SCHEME_DEFAULT)]
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= render Primer::BaseComponent.new(**@
|
1
|
+
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
2
2
|
<%= render(Primer::OcticonComponent.new(icon: @icon)) if @icon %>
|
3
3
|
<%= content %>
|
4
4
|
<% if @dismissible %>
|
@@ -7,7 +7,7 @@
|
|
7
7
|
</button>
|
8
8
|
<% end %>
|
9
9
|
<% if actions.present? %>
|
10
|
-
<%= render Primer::BaseComponent.new(**actions.
|
10
|
+
<%= render Primer::BaseComponent.new(**actions.system_arguments) do %>
|
11
11
|
<%= actions.content %>
|
12
12
|
<% end %>
|
13
13
|
<% end %>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
+
# Use the Flash component to inform users of successful or pending actions.
|
4
5
|
class FlashComponent < Primer::Component
|
5
6
|
include ViewComponent::Slotable
|
6
7
|
|
@@ -13,30 +14,59 @@ module Primer
|
|
13
14
|
:danger => "flash-error",
|
14
15
|
:success => "flash-success"
|
15
16
|
}.freeze
|
16
|
-
|
17
|
-
|
17
|
+
# @example 280|Variants
|
18
|
+
# <%= render(Primer::FlashComponent.new) { "This is a flash message!" } %>
|
19
|
+
# <%= render(Primer::FlashComponent.new(variant: :warning)) { "This is a warning flash message!" } %>
|
20
|
+
# <%= render(Primer::FlashComponent.new(variant: :danger)) { "This is a danger flash message!" } %>
|
21
|
+
# <%= render(Primer::FlashComponent.new(variant: :success)) { "This is a success flash message!" } %>
|
22
|
+
#
|
23
|
+
# @example 80|Full width
|
24
|
+
# <%= render(Primer::FlashComponent.new(full: true)) { "This is a full width flash message!" } %>
|
25
|
+
#
|
26
|
+
# @example 80|Dismissible
|
27
|
+
# <%= render(Primer::FlashComponent.new(dismissible: true)) { "This is a dismissible flash message!" } %>
|
28
|
+
#
|
29
|
+
# @example 80|Icon
|
30
|
+
# <%= render(Primer::FlashComponent.new(icon: "people")) { "This is a flash message with an icon!" } %>
|
31
|
+
#
|
32
|
+
# @example 80|With actions
|
33
|
+
# <%= render(Primer::FlashComponent.new) do |component| %>
|
34
|
+
# This is a flash message with actions!
|
35
|
+
# <% component.slot(:actions) do %>
|
36
|
+
# <%= render(Primer::ButtonComponent.new(variant: :small)) { "Take action" } %>
|
37
|
+
# <% end %>
|
38
|
+
# <% end %>
|
39
|
+
#
|
40
|
+
# @param full [Boolean] Whether the component should take up the full width of the screen.
|
41
|
+
# @param spacious [Boolean] Whether to add margin to the bottom of the component.
|
42
|
+
# @param dismissible [Boolean] Whether the component can be dismissed with an X button.
|
43
|
+
# @param icon [String] Name of Octicon icon to use.
|
44
|
+
# @param variant [Symbol] <%= one_of(Primer::FlashComponent::VARIANT_MAPPINGS.keys) %>
|
45
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
46
|
+
def initialize(full: false, spacious: false, dismissible: false, icon: nil, variant: DEFAULT_VARIANT, **system_arguments)
|
18
47
|
@icon = icon
|
19
48
|
@dismissible = dismissible
|
20
|
-
@
|
21
|
-
@
|
22
|
-
@
|
23
|
-
@
|
49
|
+
@system_arguments = system_arguments
|
50
|
+
@system_arguments[:tag] = :div
|
51
|
+
@system_arguments[:classes] = class_names(
|
52
|
+
@system_arguments[:classes],
|
24
53
|
"flash",
|
25
54
|
VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_MAPPINGS.keys, variant, DEFAULT_VARIANT)],
|
26
55
|
"flash-full": full
|
27
56
|
)
|
28
|
-
@
|
57
|
+
@system_arguments[:mb] ||= spacious ? 4 : nil
|
29
58
|
end
|
30
59
|
|
31
60
|
class Actions < ViewComponent::Slot
|
32
61
|
include ClassNameHelper
|
33
62
|
|
34
|
-
attr_reader :
|
63
|
+
attr_reader :system_arguments
|
35
64
|
|
36
|
-
|
37
|
-
|
38
|
-
@
|
39
|
-
@
|
65
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
66
|
+
def initialize(**system_arguments)
|
67
|
+
@system_arguments = system_arguments
|
68
|
+
@system_arguments[:tag] = :div
|
69
|
+
@system_arguments[:classes] = class_names(@system_arguments[:classes], "flash-action")
|
40
70
|
end
|
41
71
|
end
|
42
72
|
end
|
@@ -37,7 +37,7 @@ module Primer
|
|
37
37
|
flex_wrap: FLEX_WRAP_DEFAULT,
|
38
38
|
align_items: ALIGN_ITEMS_DEFAULT,
|
39
39
|
direction: nil,
|
40
|
-
**
|
40
|
+
**system_arguments
|
41
41
|
)
|
42
42
|
@align_items = fetch_or_fallback(ALIGN_ITEMS_OPTIONS, align_items, ALIGN_ITEMS_DEFAULT)
|
43
43
|
@justify_content = fetch_or_fallback(JUSTIFY_CONTENT_OPTIONS, justify_content, JUSTIFY_CONTENT_DEFAULT)
|
@@ -51,13 +51,13 @@ module Primer
|
|
51
51
|
DEFAULT_DIRECTION
|
52
52
|
end
|
53
53
|
|
54
|
-
@
|
55
|
-
@
|
56
|
-
@
|
54
|
+
@system_arguments = system_arguments.merge({ direction: @direction }.compact)
|
55
|
+
@system_arguments[:classes] = class_names(@system_arguments[:classes], component_class_names)
|
56
|
+
@system_arguments[:display] = fetch_or_fallback(INLINE_OPTIONS, inline, INLINE_DEFAULT) ? :inline_flex : :flex
|
57
57
|
end
|
58
58
|
|
59
59
|
def call
|
60
|
-
render(Primer::BoxComponent.new(**@
|
60
|
+
render(Primer::BoxComponent.new(**@system_arguments)) { content }
|
61
61
|
end
|
62
62
|
|
63
63
|
private
|
@@ -5,17 +5,17 @@ module Primer
|
|
5
5
|
FLEX_AUTO_DEFAULT = false
|
6
6
|
FLEX_AUTO_ALLOWED_VALUES = [FLEX_AUTO_DEFAULT, true]
|
7
7
|
|
8
|
-
def initialize(flex_auto: FLEX_AUTO_DEFAULT, **
|
9
|
-
@
|
10
|
-
@
|
8
|
+
def initialize(flex_auto: FLEX_AUTO_DEFAULT, **system_arguments)
|
9
|
+
@system_arguments = system_arguments
|
10
|
+
@system_arguments[:classes] =
|
11
11
|
class_names(
|
12
|
-
@
|
12
|
+
@system_arguments[:classes],
|
13
13
|
"flex-auto" => fetch_or_fallback(FLEX_AUTO_ALLOWED_VALUES, flex_auto, FLEX_AUTO_DEFAULT)
|
14
14
|
)
|
15
15
|
end
|
16
16
|
|
17
17
|
def call
|
18
|
-
render(Primer::BoxComponent.new(**@
|
18
|
+
render(Primer::BoxComponent.new(**@system_arguments)) { content }
|
19
19
|
end
|
20
20
|
end
|
21
21
|
end
|
@@ -2,13 +2,13 @@
|
|
2
2
|
|
3
3
|
module Primer
|
4
4
|
class HeadingComponent < Primer::Component
|
5
|
-
def initialize(**
|
6
|
-
@
|
7
|
-
@
|
5
|
+
def initialize(**system_arguments)
|
6
|
+
@system_arguments = system_arguments
|
7
|
+
@system_arguments[:tag] ||= :h1
|
8
8
|
end
|
9
9
|
|
10
10
|
def call
|
11
|
-
render(Primer::BaseComponent.new(**@
|
11
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
12
12
|
end
|
13
13
|
end
|
14
14
|
end
|
@@ -1,13 +1,20 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
+
# Use labels to add contextual metadata to a design.
|
4
5
|
class LabelComponent < Primer::Component
|
5
|
-
|
6
|
-
|
6
|
+
NEW_SCHEME_MAPPINGS = {
|
7
|
+
primary: "Label--primary",
|
8
|
+
secondary: "Label--secondary",
|
9
|
+
info: "Label--info",
|
10
|
+
success: "Label--success",
|
11
|
+
warning: "Label--warning",
|
12
|
+
danger: "Label--danger",
|
13
|
+
}
|
14
|
+
|
15
|
+
DEPRECATED_SCHEME_MAPPINGS = {
|
7
16
|
gray: "Label--gray",
|
8
17
|
dark_gray: "Label--gray-darker",
|
9
|
-
|
10
|
-
# colored
|
11
18
|
yellow: "Label--yellow",
|
12
19
|
orange: "Label--orange",
|
13
20
|
red: "Label--red",
|
@@ -15,11 +22,11 @@ module Primer
|
|
15
22
|
blue: "Label--blue",
|
16
23
|
purple: "Label--purple",
|
17
24
|
pink: "Label--pink",
|
18
|
-
|
19
|
-
# Deprecated
|
20
25
|
outline: "Label--outline",
|
21
26
|
green_outline: "Label--outline-green",
|
22
27
|
}.freeze
|
28
|
+
|
29
|
+
SCHEME_MAPPINGS = NEW_SCHEME_MAPPINGS.merge(DEPRECATED_SCHEME_MAPPINGS)
|
23
30
|
SCHEME_OPTIONS = SCHEME_MAPPINGS.keys << nil
|
24
31
|
|
25
32
|
VARIANT_MAPPINGS = {
|
@@ -28,21 +35,37 @@ module Primer
|
|
28
35
|
}.freeze
|
29
36
|
VARIANT_OPTIONS = VARIANT_MAPPINGS.keys << nil
|
30
37
|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
38
|
+
# @example 40|Schemes
|
39
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label")) { "default" } %>
|
40
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label", scheme: :gray)) { "gray" } %>
|
41
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label", scheme: :dark_gray)) { "dark_gray" } %>
|
42
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label", scheme: :yellow)) { "yellow" } %>
|
43
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label", scheme: :green)) { "green" } %>
|
44
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label", scheme: :purple)) { "purple" } %>
|
45
|
+
#
|
46
|
+
# @example 40|Variants
|
47
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label")) { "Default" } %>
|
48
|
+
# <%= render(Primer::LabelComponent.new(title: "Label: Label", variant: :large)) { "Large" } %>
|
49
|
+
#
|
50
|
+
# @param title [String] `title` attribute for the component element.
|
51
|
+
# @param scheme [Symbol] <%= one_of(Primer::LabelComponent::DEPRECATED_SCHEME_MAPPINGS.keys) %>
|
52
|
+
# @param variant [Symbol] <%= one_of(Primer::LabelComponent::VARIANT_OPTIONS) %>
|
53
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
54
|
+
def initialize(title:, scheme: nil, variant: nil, **system_arguments)
|
55
|
+
@system_arguments = system_arguments
|
56
|
+
@system_arguments[:bg] = :blue if scheme.nil?
|
57
|
+
@system_arguments[:tag] ||= :span
|
58
|
+
@system_arguments[:title] = title
|
59
|
+
@system_arguments[:classes] = class_names(
|
37
60
|
"Label",
|
38
|
-
|
61
|
+
system_arguments[:classes],
|
39
62
|
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme)],
|
40
63
|
VARIANT_MAPPINGS[fetch_or_fallback(VARIANT_OPTIONS, variant)]
|
41
64
|
)
|
42
65
|
end
|
43
66
|
|
44
67
|
def call
|
45
|
-
render(Primer::BaseComponent.new(**@
|
68
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
46
69
|
end
|
47
70
|
end
|
48
71
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
<%= render(Primer::FlexComponent.new(**@
|
1
|
+
<%= render(Primer::FlexComponent.new(**@system_arguments)) do %>
|
2
2
|
<% if @side == :left %>
|
3
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
4
|
<%= sidebar %>
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
+
# Use Layout to build a main/sidebar layout.
|
4
5
|
class LayoutComponent < Primer::Component
|
5
6
|
with_content_areas :main, :sidebar
|
6
7
|
|
@@ -11,15 +12,31 @@ module Primer
|
|
11
12
|
DEFAULT_SIDEBAR_COL = 3
|
12
13
|
ALLOWED_SIDEBAR_COLS = (1..(MAX_COL - 1)).to_a.freeze
|
13
14
|
|
14
|
-
|
15
|
-
|
15
|
+
# @example 40|Default
|
16
|
+
# <%= render(Primer::LayoutComponent.new) do |component| %>
|
17
|
+
# <% component.with(:sidebar) { "Sidebar" } %>
|
18
|
+
# <% component.with(:main) { "Main" } %>
|
19
|
+
# <% end %>
|
20
|
+
#
|
21
|
+
# @example 40|Left sidebar
|
22
|
+
# <%= render(Primer::LayoutComponent.new(side: :left)) do |component| %>
|
23
|
+
# <% component.with(:sidebar) { "Sidebar" } %>
|
24
|
+
# <% component.with(:main) { "Main" } %>
|
25
|
+
# <% end %>
|
26
|
+
#
|
27
|
+
# @param responsive [Boolean] Whether to collapse layout to a single column at smaller widths.
|
28
|
+
# @param side [Symbol] Which side to display the sidebar on. <%= one_of(Primer::LayoutComponent::ALLOWED_SIDES) %>
|
29
|
+
# @param sidebar_col [Integer] Sidebar column width.
|
30
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
31
|
+
def initialize(responsive: false, side: DEFAULT_SIDE, sidebar_col: DEFAULT_SIDEBAR_COL, **system_arguments)
|
32
|
+
@system_arguments = system_arguments
|
16
33
|
@side = fetch_or_fallback(ALLOWED_SIDES, side, DEFAULT_SIDE)
|
17
34
|
@responsive = responsive
|
18
|
-
@
|
35
|
+
@system_arguments[:classes] = class_names(
|
19
36
|
"gutter-condensed gutter-lg",
|
20
|
-
@
|
37
|
+
@system_arguments[:classes]
|
21
38
|
)
|
22
|
-
@
|
39
|
+
@system_arguments[:direction] = responsive ? [:column, nil, :row] : nil
|
23
40
|
|
24
41
|
@sidebar_col = fetch_or_fallback(ALLOWED_SIDEBAR_COLS, sidebar_col, DEFAULT_SIDEBAR_COL)
|
25
42
|
@main_col = MAX_COL - @sidebar_col
|
@@ -1,19 +1,29 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
+
# Use links for moving from one page to another. The Link component styles anchor tags with default blue styling and hover text-decoration.
|
4
5
|
class LinkComponent < Primer::Component
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
6
|
+
# @example 40|Default
|
7
|
+
# <%= render(Primer::LinkComponent.new(href: "http://www.google.com")) { "Link" } %>
|
8
|
+
#
|
9
|
+
# @example 40|Muted
|
10
|
+
# <%= render(Primer::LinkComponent.new(href: "http://www.google.com", muted: true)) { "Link" } %>
|
11
|
+
#
|
12
|
+
# @param href [String] URL to be used for the Link
|
13
|
+
# @param muted [Boolean] Uses light gray for Link color, and blue on hover
|
14
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
15
|
+
def initialize(href:, muted: false, **system_arguments)
|
16
|
+
@system_arguments = system_arguments
|
17
|
+
@system_arguments[:tag] = :a
|
18
|
+
@system_arguments[:href] = href
|
19
|
+
@system_arguments[:classes] = class_names(
|
20
|
+
@system_arguments[:classes],
|
11
21
|
"muted-link" => fetch_or_fallback([true, false], muted, false)
|
12
22
|
)
|
13
23
|
end
|
14
24
|
|
15
25
|
def call
|
16
|
-
render(Primer::BaseComponent.new(**@
|
26
|
+
render(Primer::BaseComponent.new(**@system_arguments)) { content }
|
17
27
|
end
|
18
28
|
end
|
19
29
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
+
# Renders an [Octicon](https://primer.style/octicons/) with <%= link_to_system_arguments_docs %>.
|
4
5
|
class OcticonComponent < Primer::Component
|
5
6
|
include Primer::ClassNameHelper
|
6
7
|
include OcticonsHelper
|
@@ -13,20 +14,32 @@ module Primer
|
|
13
14
|
}.freeze
|
14
15
|
SIZE_OPTIONS = SIZE_MAPPINGS.keys
|
15
16
|
|
16
|
-
|
17
|
-
|
17
|
+
# @example 25|Default
|
18
|
+
# <%= render(Primer::OcticonComponent.new(icon: "check")) %>
|
19
|
+
#
|
20
|
+
# @example 40|Medium
|
21
|
+
# <%= render(Primer::OcticonComponent.new(icon: "people", size: :medium)) %>
|
22
|
+
#
|
23
|
+
# @example 80|Large
|
24
|
+
# <%= render(Primer::OcticonComponent.new(icon: "x", size: :large)) %>
|
25
|
+
#
|
26
|
+
# @param icon [String] Name of [Octicon](https://primer.style/octicons/) to use.
|
27
|
+
# @param size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS) %>
|
28
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
29
|
+
def initialize(icon:, size: SIZE_DEFAULT, **system_arguments)
|
30
|
+
@icon, @system_arguments = icon, system_arguments
|
18
31
|
|
19
|
-
@
|
20
|
-
@
|
32
|
+
@system_arguments[:class] = Primer::Classify.call(**@system_arguments)[:class]
|
33
|
+
@system_arguments[:height] ||= SIZE_MAPPINGS[size]
|
21
34
|
|
22
35
|
# Filter out classify options to prevent them from becoming invalid html attributes.
|
23
36
|
# Note height and width are both classify options and valid html attributes.
|
24
|
-
octicon_helper_options = @
|
25
|
-
@
|
37
|
+
octicon_helper_options = @system_arguments.slice(:height, :width)
|
38
|
+
@system_arguments = @system_arguments.except(*Primer::Classify::VALID_KEYS, :classes).merge(octicon_helper_options)
|
26
39
|
end
|
27
40
|
|
28
41
|
def call
|
29
|
-
octicon(@icon, **@
|
42
|
+
octicon(@icon, **@system_arguments)
|
30
43
|
end
|
31
44
|
end
|
32
45
|
end
|
@@ -1,22 +1,56 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
+
# Use popovers to bring attention to specific user interface elements, typically to suggest an action or to guide users through a new experience.
|
5
|
+
#
|
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.
|
4
7
|
class PopoverComponent < Primer::Component
|
5
8
|
include ViewComponent::Slotable
|
6
9
|
|
7
10
|
with_slot :heading, class_name: "Heading"
|
8
11
|
with_slot :body, class_name: "Body"
|
9
12
|
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
13
|
+
# @example 150|Default
|
14
|
+
# <%= render Primer::PopoverComponent.new do |component| %>
|
15
|
+
# <% component.slot(:heading) do %>
|
16
|
+
# Activity feed
|
17
|
+
# <% end %>
|
18
|
+
# <% component.slot(:body) do %>
|
19
|
+
# This is the Popover body.
|
20
|
+
# <% end %>
|
21
|
+
# <% end %>
|
22
|
+
#
|
23
|
+
# @example 150|Large
|
24
|
+
# <%= render Primer::PopoverComponent.new do |component| %>
|
25
|
+
# <% component.slot(:heading) do %>
|
26
|
+
# Activity feed
|
27
|
+
# <% end %>
|
28
|
+
# <% component.slot(:body, large: true) do %>
|
29
|
+
# This is the large Popover body.
|
30
|
+
# <% end %>
|
31
|
+
# <% end %>
|
32
|
+
#
|
33
|
+
# @example 150|Caret position
|
34
|
+
# <%= render Primer::PopoverComponent.new do |component| %>
|
35
|
+
# <% component.slot(:heading) do %>
|
36
|
+
# Activity feed
|
37
|
+
# <% end %>
|
38
|
+
# <% component.slot(:body, caret: :left) do %>
|
39
|
+
# This is the large Popover body.
|
40
|
+
# <% end %>
|
41
|
+
# <% end %>
|
42
|
+
#
|
43
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
44
|
+
def initialize(**system_arguments)
|
45
|
+
@system_arguments = system_arguments
|
46
|
+
@system_arguments[:tag] ||= :div
|
47
|
+
@system_arguments[:classes] = class_names(
|
48
|
+
system_arguments[:classes],
|
15
49
|
"Popover"
|
16
50
|
)
|
17
|
-
@
|
18
|
-
@
|
19
|
-
@
|
51
|
+
@system_arguments[:position] ||= :relative
|
52
|
+
@system_arguments[:right] = false unless system_arguments.key?(:right)
|
53
|
+
@system_arguments[:left] = false unless system_arguments.key?(:left)
|
20
54
|
end
|
21
55
|
|
22
56
|
def render?
|
@@ -24,14 +58,15 @@ module Primer
|
|
24
58
|
end
|
25
59
|
|
26
60
|
class Heading < ViewComponent::Slot
|
27
|
-
|
28
|
-
|
29
|
-
@
|
30
|
-
@
|
61
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
62
|
+
def initialize(**system_arguments)
|
63
|
+
@system_arguments = system_arguments
|
64
|
+
@system_arguments[:mb] ||= 2
|
65
|
+
@system_arguments[:tag] ||= :h4
|
31
66
|
end
|
32
67
|
|
33
68
|
def component
|
34
|
-
Primer::HeadingComponent.new(**@
|
69
|
+
Primer::HeadingComponent.new(**@system_arguments)
|
35
70
|
end
|
36
71
|
end
|
37
72
|
|
@@ -52,23 +87,26 @@ module Primer
|
|
52
87
|
:top_right => "Popover-message--top-right"
|
53
88
|
}.freeze
|
54
89
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
90
|
+
# @param caret [Symbol] <%= one_of(Primer::PopoverComponent::Body::CARET_MAPPINGS.keys) %>
|
91
|
+
# @param large [Boolean] Whether to use the large version of the component.
|
92
|
+
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
93
|
+
def initialize(caret: CARET_DEFAULT, large: false, **system_arguments)
|
94
|
+
@system_arguments = system_arguments
|
95
|
+
@system_arguments[:classes] = class_names(
|
96
|
+
system_arguments[:classes],
|
59
97
|
"Popover-message Box",
|
60
98
|
CARET_MAPPINGS[fetch_or_fallback(CARET_MAPPINGS.keys, caret, CARET_DEFAULT)],
|
61
99
|
"Popover-message--large" => large
|
62
100
|
)
|
63
|
-
@
|
64
|
-
@
|
65
|
-
@
|
66
|
-
@
|
67
|
-
@
|
101
|
+
@system_arguments[:p] ||= 4
|
102
|
+
@system_arguments[:mt] ||= 2
|
103
|
+
@system_arguments[:mx] ||= :auto
|
104
|
+
@system_arguments[:text_align] ||= :left
|
105
|
+
@system_arguments[:box_shadow] ||= :large
|
68
106
|
end
|
69
107
|
|
70
108
|
def component
|
71
|
-
Primer::BoxComponent.new(**@
|
109
|
+
Primer::BoxComponent.new(**@system_arguments)
|
72
110
|
end
|
73
111
|
end
|
74
112
|
end
|