Skip to content

Commit 06a78ea

Browse files
committed
Add support for trailing and leading visual icons
1 parent dbb01c7 commit 06a78ea

File tree

5 files changed

+101
-16
lines changed

5 files changed

+101
-16
lines changed

.changeset/odd-dots-laugh.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@primer/view-components': minor
3+
---
4+
5+
Support leading and trailing icons for Links
+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<% link_content = capture do %>
2+
<%= render(Primer::BaseComponent.new(**@system_arguments)) do %>
3+
<% if leading_visual %>
4+
<span class="Link-visual Link-leadingVisual">
5+
<%= leading_visual %>
6+
</span>
7+
<% end %>
8+
9+
<%= content %>
10+
11+
<% if trailing_visual %>
12+
<span class="Link-visual Link-trailingVisual">
13+
<%= trailing_visual %>
14+
</span>
15+
<% end %>
16+
<% end %>
17+
<% end %>
18+
19+
<% if tooltip.present? %>
20+
<%= render Primer::BaseComponent.new(tag: :span, position: :relative) do %>
21+
<%= link_content %>
22+
<%= tooltip %>
23+
<% end %>
24+
<% else %>
25+
<%= link_content %>
26+
<% end %>

app/components/primer/beta/link.rb

+26-14
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,32 @@ class Link < Primer::Component
3030
Primer::Alpha::Tooltip.new(**system_arguments)
3131
}
3232

33+
# Leading visuals appear to the left of the link text.
34+
#
35+
# Use:
36+
#
37+
# - `leading_visual_icon` which accepts the arguments accepted by <%= link_to_component(Primer::Beta::Octicon) %>.
38+
#
39+
# @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::Beta::Octicon) %>.
40+
renders_one :leading_visual, types: {
41+
icon: lambda { |**system_arguments|
42+
Primer::Beta::Octicon.new(**system_arguments)
43+
}
44+
}
45+
46+
# Trailing visuals appear to the right of the link text.
47+
#
48+
# Use:
49+
#
50+
# - `trailing_visual_icon` which accepts the arguments accepted by <%= link_to_component(Primer::Beta::Octicon) %>.
51+
#
52+
# @param system_arguments [Hash] Same arguments as <%= link_to_component(Primer::Beta::Octicon) %>.
53+
renders_one :trailing_visual, types: {
54+
icon: lambda { |**system_arguments|
55+
Primer::Beta::Octicon.new(**system_arguments)
56+
}
57+
}
58+
3359
# @param href [String] URL to be used for the Link. Required. If the requirements are not met an error will be raised in non production environments. In production, an empty link element will be rendered.
3460
# @param scheme [Symbol] <%= one_of(Primer::Beta::Link::SCHEME_MAPPINGS.keys) %>
3561
# @param muted [Boolean] Uses light gray for Link color, and blue on hover.
@@ -54,20 +80,6 @@ def initialize(href: nil, scheme: DEFAULT_SCHEME, muted: false, underline: false
5480
def before_render
5581
raise ArgumentError, "href is required" if @system_arguments[:href].nil? && !Rails.env.production?
5682
end
57-
58-
def call
59-
if tooltip.present?
60-
render Primer::BaseComponent.new(tag: :span, position: :relative) do
61-
render(Primer::BaseComponent.new(**@system_arguments)) do
62-
content
63-
end.to_s + tooltip.to_s
64-
end
65-
else
66-
render(Primer::BaseComponent.new(**@system_arguments)) do
67-
content
68-
end
69-
end
70-
end
7183
end
7284
end
7385
end

previews/primer/beta/link_preview.rb

+24-2
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@ class LinkPreview < ViewComponent::Preview
99
# @param underline [Boolean]
1010
# @param muted [Boolean]
1111
# @param scheme [Symbol] select [default, primary, secondary]
12-
def playground(scheme: :default, muted: false, underline: true)
13-
render(Primer::Beta::Link.new(href: "#", scheme: scheme, muted: muted, underline: underline)) { "This is a link!" }
12+
# @param leading_visual_icon [Symbol] octicon
13+
# @param trailing_visual_icon [Symbol] octicon
14+
def playground(scheme: :default, muted: false, underline: true, leading_visual_icon: nil, trailing_visual_icon: nil)
15+
render(Primer::Beta::Link.new(href: "#", scheme: scheme, muted: muted, underline: underline)) do |link|
16+
link.with_leading_visual_icon(icon: leading_visual_icon) if leading_visual_icon && leading_visual_icon != :none
17+
link.with_trailing_visual_icon(icon: trailing_visual_icon) if trailing_visual_icon && trailing_visual_icon != :none
18+
"This is a link!"
19+
end
1420
end
1521

1622
# @label Default Options
@@ -66,6 +72,22 @@ def color_scheme_secondary_muted
6672
render(Primer::Beta::Link.new(href: "#", scheme: :secondary, muted: true)) { "This is a muted secondary link color." }
6773
end
6874
# @!endgroup
75+
76+
# @label With leading icon
77+
def with_leading_icon
78+
render(Primer::Beta::Link.new(href: "#")) do |component|
79+
component.with_leading_visual_icon(icon: :"mark-github")
80+
"Link with leading icon"
81+
end
82+
end
83+
84+
# @label With trailing icon
85+
def with_trailing_icon
86+
render(Primer::Beta::Link.new(href: "#")) do |component|
87+
component.with_trailing_visual_icon(icon: :"link-external")
88+
"Link with trailing icon"
89+
end
90+
end
6991
end
7092
end
7193
end

test/components/beta/link_test.rb

+20
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,24 @@ def test_renders_with_tooltip_sibling
9292

9393
assert_selector("a[href='http://google.com'] + tool-tip", text: "Tooltip text", visible: false)
9494
end
95+
96+
def test_renders_leading_visual_icon
97+
render_inline(Primer::Beta::Link.new(href: "http://google.com")) do |component|
98+
component.with_leading_visual_icon(icon: "plus")
99+
"content"
100+
end
101+
102+
assert_selector("a[href='http://google.com']")
103+
assert_selector(".Link-visual.Link-leadingVisual .octicon-plus")
104+
end
105+
106+
def test_renders_trailing_visual_icon
107+
render_inline(Primer::Beta::Link.new(href: "http://google.com")) do |component|
108+
component.with_trailing_visual_icon(icon: "plus")
109+
"content"
110+
end
111+
112+
assert_selector("a[href='http://google.com']")
113+
assert_selector(".Link-visual.Link-trailingVisual .octicon-plus")
114+
end
95115
end

0 commit comments

Comments
 (0)