Skip to content

Commit abfbd54

Browse files
committed
Revert "Revert "Add support for trailing and leading visual icons in Primer::Beta::Link (primer#2982)" (primer#3040)"
This reverts commit 612307d.
1 parent 6348ede commit abfbd54

File tree

9 files changed

+109
-24
lines changed

9 files changed

+109
-24
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

.changeset/quiet-kids-sort.md

-5
This file was deleted.

app/components/primer/base_component.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -151,13 +151,16 @@ class BaseComponent < Primer::Component
151151
# | :- | :- | :- |
152152
# | classes | String | CSS class name value to be concatenated with generated Primer CSS classes. |
153153
# | test_selector | String | Adds `data-test-selector='given value'` in non-Production environments for testing purposes. |
154+
# | trim | Boolean | Calls `strip` on the content to remove trailing and leading white spaces. |
154155
def initialize(tag:, classes: nil, **system_arguments)
155156
@tag = tag
156157

157158
@system_arguments = validate_arguments(tag: tag, **system_arguments)
158159

159160
@result = Primer::Classify.call(**@system_arguments.merge(classes: classes))
160161

162+
@trim = !!@system_arguments.delete(:trim)
163+
161164
@system_arguments[:"data-view-component"] = true
162165
# Filter out Primer keys so they don't get assigned as HTML attributes
163166
@content_tag_args = add_test_selector(@system_arguments).except(*Primer::Classify::Utilities::UTILITIES.keys)
@@ -167,7 +170,7 @@ def call
167170
if SELF_CLOSING_TAGS.include?(@tag)
168171
tag(@tag, @content_tag_args.merge(@result))
169172
else
170-
content_tag(@tag, content, @content_tag_args.merge(@result))
173+
content_tag(@tag, @trim ? trimmed_content : content, @content_tag_args.merge(@result))
171174
end
172175
end
173176
end
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<%= render Primer::ConditionalWrapper.new(condition: tooltip?, trim: true, tag: :span, position: :relative) do %>
2+
<%= render(Primer::BaseComponent.new(trim: true, **@system_arguments)) do %>
3+
<% if leading_visual %>
4+
<span>
5+
<%= leading_visual %>
6+
</span>
7+
<% end %>
8+
<%= content %>
9+
<% if trailing_visual %>
10+
<span>
11+
<%= trailing_visual %>
12+
</span>
13+
<% end %>
14+
<% end %>
15+
<%= tooltip if tooltip? %>
16+
<% 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

app/components/primer/component.rb

+7
Original file line numberDiff line numberDiff line change
@@ -144,5 +144,12 @@ def should_raise_error?
144144
def should_raise_aria_error?
145145
!Rails.env.production? && raise_on_invalid_aria? && !ENV["PRIMER_WARNINGS_DISABLED"]
146146
end
147+
148+
def trimmed_content
149+
return content unless content.present?
150+
151+
# strip unsets `html_safe`, so we have to set it back again to guarantee that HTML blocks won't break
152+
content.html_safe? ? content.strip.html_safe : content.strip # rubocop:disable Rails/OutputSafety
153+
end
147154
end
148155
end

app/components/primer/conditional_wrapper.rb

+5-2
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,15 @@ class ConditionalWrapper < Primer::Component
1010
def initialize(condition:, **base_component_arguments)
1111
@condition = condition
1212
@base_component_arguments = base_component_arguments
13+
@trim = !!@base_component_arguments.delete(:trim)
1314
end
1415

1516
def call
16-
return content unless @condition
17+
unless @condition
18+
return @trim ? trimmed_content : content
19+
end
1720

18-
BaseComponent.new(**@base_component_arguments).render_in(self) { content }
21+
BaseComponent.new(trim: @trim, **@base_component_arguments).render_in(self) { content }
1922
end
2023
end
2124
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

+22
Original file line numberDiff line numberDiff line change
@@ -92,4 +92,26 @@ 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(".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_leading_visual_icon(icon: "plus")
109+
component.with_trailing_visual_icon(icon: "alert")
110+
"content"
111+
end
112+
113+
assert_selector("a[href='http://google.com']")
114+
assert_selector("a span:first-child .octicon-plus")
115+
assert_selector("a span:nth-child(2) .octicon-alert")
116+
end
95117
end

0 commit comments

Comments
 (0)