primer_view_components 0.0.83 → 0.0.86
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +50 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/components/primer/alpha/auto_complete/auto_complete.html.erb +24 -0
- data/app/components/primer/alpha/auto_complete/item.rb +46 -0
- data/app/components/primer/alpha/auto_complete.rb +158 -0
- data/app/components/primer/alpha/button_marketing.rb +1 -1
- data/app/components/primer/alpha/text_field.rb +105 -0
- data/app/components/primer/alpha/tool-tip-element.d.ts +3 -1
- data/app/components/primer/alpha/tool-tip-element.js +20 -13
- data/app/components/primer/alpha/tool-tip-element.ts +23 -14
- data/app/components/primer/alpha/tooltip.rb +1 -1
- data/app/components/primer/beta/auto_complete/auto_complete.html.erb +21 -17
- data/app/components/primer/beta/auto_complete/item.html.erb +21 -0
- data/app/components/primer/beta/auto_complete/item.rb +42 -6
- data/app/components/primer/beta/auto_complete.rb +93 -55
- data/app/components/primer/beta/base_button.rb +47 -0
- data/app/components/primer/{alpha → beta}/border_box/header.html.erb +0 -0
- data/app/components/primer/{alpha → beta}/border_box/header.rb +6 -6
- data/app/components/primer/{border_box_component.html.erb → beta/border_box.html.erb} +0 -0
- data/app/components/primer/beta/border_box.rb +147 -0
- data/app/components/primer/blankslate_component.rb +2 -150
- data/app/components/primer/border_box_component.rb +2 -140
- data/app/components/primer/button_component.html.erb +12 -4
- data/app/components/primer/button_component.rb +2 -2
- data/app/components/primer/clipboard_copy.rb +6 -2
- data/app/components/primer/close_button.rb +1 -1
- data/app/components/primer/conditional_wrapper.rb +36 -0
- data/app/components/primer/hellip_button.rb +1 -1
- data/app/components/primer/icon_button.html.erb +6 -0
- data/app/components/primer/icon_button.rb +46 -10
- data/app/components/primer/link_component.html.erb +12 -0
- data/app/components/primer/link_component.rb +2 -9
- data/app/lib/primer/join_style_arguments_helper.rb +1 -1
- data/lib/primer/classify/utilities.rb +3 -6
- data/lib/primer/form_components.rb +36 -0
- data/lib/primer/forms/acts_as_component.rb +118 -0
- data/lib/primer/forms/base.html.erb +8 -0
- data/lib/primer/forms/base.rb +137 -0
- data/lib/primer/forms/base_component.rb +58 -0
- data/lib/primer/forms/buffer_rewriter.rb +50 -0
- data/lib/primer/forms/caption.html.erb +10 -0
- data/lib/primer/forms/caption.rb +29 -0
- data/lib/primer/forms/check_box.html.erb +9 -0
- data/lib/primer/forms/check_box.rb +16 -0
- data/lib/primer/forms/check_box_group.html.erb +12 -0
- data/lib/primer/forms/check_box_group.rb +14 -0
- data/lib/primer/forms/dsl/check_box_group_input.rb +41 -0
- data/lib/primer/forms/dsl/check_box_input.rb +27 -0
- data/lib/primer/forms/dsl/form_object.rb +25 -0
- data/lib/primer/forms/dsl/form_reference_input.rb +36 -0
- data/lib/primer/forms/dsl/hidden_input.rb +29 -0
- data/lib/primer/forms/dsl/input.rb +259 -0
- data/lib/primer/forms/dsl/input_group.rb +41 -0
- data/lib/primer/forms/dsl/input_methods.rb +86 -0
- data/lib/primer/forms/dsl/multi_input.rb +58 -0
- data/lib/primer/forms/dsl/radio_button_group_input.rb +38 -0
- data/lib/primer/forms/dsl/radio_button_input.rb +37 -0
- data/lib/primer/forms/dsl/select_list_input.rb +53 -0
- data/lib/primer/forms/dsl/submit_button_input.rb +28 -0
- data/lib/primer/forms/dsl/text_area_input.rb +33 -0
- data/lib/primer/forms/dsl/text_field_input.rb +65 -0
- data/lib/primer/forms/form_control.html.erb +18 -0
- data/lib/primer/forms/form_control.rb +23 -0
- data/lib/primer/forms/form_list.html.erb +5 -0
- data/lib/primer/forms/form_list.rb +21 -0
- data/lib/primer/forms/form_reference.html.erb +3 -0
- data/lib/primer/forms/form_reference.rb +14 -0
- data/lib/primer/forms/group.html.erb +5 -0
- data/lib/primer/forms/group.rb +27 -0
- data/lib/primer/forms/hidden_field.html.erb +1 -0
- data/lib/primer/forms/hidden_field.rb +15 -0
- data/lib/primer/forms/multi.html.erb +3 -0
- data/lib/primer/forms/multi.rb +14 -0
- data/lib/primer/forms/radio_button.html.erb +14 -0
- data/lib/primer/forms/radio_button.rb +29 -0
- data/lib/primer/forms/radio_button_group.html.erb +12 -0
- data/lib/primer/forms/radio_button_group.rb +14 -0
- data/lib/primer/forms/select_list.html.erb +5 -0
- data/lib/primer/forms/select_list.rb +26 -0
- data/lib/primer/forms/separator.html.erb +1 -0
- data/lib/primer/forms/separator.rb +8 -0
- data/lib/primer/forms/spacing_wrapper.html.erb +3 -0
- data/lib/primer/forms/spacing_wrapper.rb +8 -0
- data/lib/primer/forms/submit_button.html.erb +4 -0
- data/lib/primer/forms/submit_button.rb +50 -0
- data/lib/primer/forms/text_area.html.erb +5 -0
- data/lib/primer/forms/text_area.rb +16 -0
- data/lib/primer/forms/text_field.html.erb +19 -0
- data/lib/primer/forms/text_field.rb +14 -0
- data/lib/primer/view_components/engine.rb +23 -0
- data/lib/primer/view_components/linters/argument_mappers/button.rb +2 -2
- data/lib/primer/view_components/linters/button_component_migration_counter.rb +1 -1
- data/lib/primer/view_components/linters/helpers/deprecated_components_helpers.rb +4 -8
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/cop/primer/component_name_migration.rb +3 -0
- data/lib/tasks/deprecated.rake +22 -0
- data/lib/tasks/docs.rake +8 -6
- data/static/arguments.yml +188 -52
- data/static/audited_at.json +7 -2
- data/static/classes.yml +25 -8
- data/static/constants.json +66 -39
- data/static/statuses.json +8 -3
- metadata +71 -7
- data/app/components/primer/base_button.rb +0 -43
- data/app/components/primer/blankslate_component.html.erb +0 -30
@@ -1,156 +1,8 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
#
|
5
|
-
|
6
|
-
# `Blankslate` renders an `<h3>` element for the title by default. Update the heading level based on what is appropriate for your page hierarchy by setting `title_tag`.
|
7
|
-
# <%= link_to_heading_practices %>
|
8
|
-
class BlankslateComponent < Primer::Component
|
4
|
+
# BlankslateComponent is deprecated. Please use `Primer::Beta::Blankslate` instead.
|
5
|
+
class BlankslateComponent < Primer::Beta::Blankslate
|
9
6
|
status :deprecated
|
10
|
-
|
11
|
-
# Optional Spinner.
|
12
|
-
#
|
13
|
-
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::SpinnerComponent) %>.
|
14
|
-
renders_one :spinner, lambda { |**system_arguments|
|
15
|
-
system_arguments[:mb] ||= 3
|
16
|
-
Primer::SpinnerComponent.new(**system_arguments)
|
17
|
-
}
|
18
|
-
|
19
|
-
#
|
20
|
-
# @example Basic
|
21
|
-
# <%= render Primer::BlankslateComponent.new(
|
22
|
-
# title: "Title",
|
23
|
-
# description: "Description",
|
24
|
-
# ) %>
|
25
|
-
#
|
26
|
-
# @example Icon
|
27
|
-
# @description
|
28
|
-
# Add an `icon` to give additional context. Refer to the [Octicons](https://primer.style/octicons/) documentation to choose an icon.
|
29
|
-
# @code
|
30
|
-
# <%= render Primer::BlankslateComponent.new(
|
31
|
-
# icon: :globe,
|
32
|
-
# title: "Title",
|
33
|
-
# description: "Description",
|
34
|
-
# ) %>
|
35
|
-
#
|
36
|
-
# @example Loading
|
37
|
-
# @description
|
38
|
-
# Add a [SpinnerComponent](https://primer.style/view-components/components/spinner) to the blankslate in place of an icon.
|
39
|
-
# @code
|
40
|
-
# <%= render Primer::BlankslateComponent.new(
|
41
|
-
# title: "Title",
|
42
|
-
# description: "Description",
|
43
|
-
# ) do |component| %>
|
44
|
-
# <% component.spinner(size: :large) %>
|
45
|
-
# <% end %>
|
46
|
-
#
|
47
|
-
# @example Custom content
|
48
|
-
# @description
|
49
|
-
# Pass custom content as a block in place of `description`.
|
50
|
-
# @code
|
51
|
-
# <%= render Primer::BlankslateComponent.new(
|
52
|
-
# title: "Title",
|
53
|
-
# ) do %>
|
54
|
-
# <em>Your custom content here</em>
|
55
|
-
# <% end %>
|
56
|
-
#
|
57
|
-
# @example Action button
|
58
|
-
# @description
|
59
|
-
# Provide a button to guide users to take action from the blankslate. The button appears below the description and custom content.
|
60
|
-
# @code
|
61
|
-
# <%= render Primer::BlankslateComponent.new(
|
62
|
-
# icon: :book,
|
63
|
-
# title: "Welcome to the mona wiki!",
|
64
|
-
# description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
|
65
|
-
#
|
66
|
-
# button_text: "Create the first page",
|
67
|
-
# button_url: "https://github.com/monalisa/mona/wiki/_new",
|
68
|
-
# ) %>
|
69
|
-
#
|
70
|
-
# @example Link
|
71
|
-
# @description
|
72
|
-
# Add an additional link to help users learn more about a feature. The link will be shown at the very bottom:
|
73
|
-
# @code
|
74
|
-
# <%= render Primer::BlankslateComponent.new(
|
75
|
-
# icon: :book,
|
76
|
-
# title: "Welcome to the mona wiki!",
|
77
|
-
# description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
|
78
|
-
# link_text: "Learn more about wikis",
|
79
|
-
# link_url: "https://docs.github.com/en/github/building-a-strong-community/about-wikis",
|
80
|
-
# ) %>
|
81
|
-
#
|
82
|
-
# @example Variations
|
83
|
-
# @description
|
84
|
-
# There are a few variations of how the Blankslate appears: `narrow` adds a maximum width, `large` increases the font size, and `spacious` adds extra padding.
|
85
|
-
# @code
|
86
|
-
# <%= render Primer::BlankslateComponent.new(
|
87
|
-
# icon: :book,
|
88
|
-
# title: "Welcome to the mona wiki!",
|
89
|
-
# description: "Wikis provide a place in your repository to lay out the roadmap of your project, show the current status, and document software better, together.",
|
90
|
-
# narrow: true,
|
91
|
-
# large: true,
|
92
|
-
# spacious: true,
|
93
|
-
# ) %>
|
94
|
-
#
|
95
|
-
# @param title [String] Text that appears in a larger bold font.
|
96
|
-
# @param title_tag [Symbol] HTML tag to use for title.
|
97
|
-
# @param icon [Symbol] Octicon icon to use at top of component.
|
98
|
-
# @param icon_size [Symbol] <%= one_of(Primer::OcticonComponent::SIZE_MAPPINGS, sort: false) %>
|
99
|
-
# @param image_src [String] Image to display.
|
100
|
-
# @param image_alt [String] Alt text for image.
|
101
|
-
# @param description [String] Text that appears below the title. Typically a whole sentence.
|
102
|
-
# @param button_text [String] The text of the button.
|
103
|
-
# @param button_url [String] The URL where the user will be taken after clicking the button.
|
104
|
-
# @param button_classes [String] Classes to apply to action button
|
105
|
-
# @param link_text [String] The text of the link.
|
106
|
-
# @param link_url [String] The URL where the user will be taken after clicking the link.
|
107
|
-
# @param narrow [Boolean] Adds a maximum width.
|
108
|
-
# @param large [Boolean] Increases the font size.
|
109
|
-
# @param spacious [Boolean] Adds extra padding.
|
110
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
111
|
-
def initialize(
|
112
|
-
title: "",
|
113
|
-
title_tag: :h3,
|
114
|
-
icon: "",
|
115
|
-
icon_size: :medium,
|
116
|
-
image_src: "",
|
117
|
-
image_alt: " ",
|
118
|
-
description: "",
|
119
|
-
button_text: "",
|
120
|
-
button_url: "",
|
121
|
-
button_classes: "btn-primary my-3",
|
122
|
-
link_text: "",
|
123
|
-
link_url: "",
|
124
|
-
|
125
|
-
# variations
|
126
|
-
narrow: false,
|
127
|
-
large: false,
|
128
|
-
spacious: false,
|
129
|
-
|
130
|
-
**system_arguments
|
131
|
-
)
|
132
|
-
@system_arguments = system_arguments
|
133
|
-
@system_arguments[:tag] = :div
|
134
|
-
@system_arguments[:classes] = class_names(
|
135
|
-
@system_arguments[:classes],
|
136
|
-
"blankslate",
|
137
|
-
"blankslate-narrow": narrow,
|
138
|
-
"blankslate-large": large,
|
139
|
-
"blankslate-spacious": spacious
|
140
|
-
)
|
141
|
-
|
142
|
-
@title_tag = title_tag
|
143
|
-
@icon = icon
|
144
|
-
@icon_size = icon_size
|
145
|
-
@image_src = image_src
|
146
|
-
@image_alt = image_alt
|
147
|
-
@title = title
|
148
|
-
@description = description
|
149
|
-
@button_text = button_text
|
150
|
-
@button_url = button_url
|
151
|
-
@button_classes = button_classes
|
152
|
-
@link_text = link_text
|
153
|
-
@link_url = link_url
|
154
|
-
end
|
155
7
|
end
|
156
8
|
end
|
@@ -1,145 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Primer
|
4
|
-
|
5
|
-
|
6
|
-
status :beta
|
7
|
-
|
8
|
-
DEFAULT_PADDING = :default
|
9
|
-
PADDING_MAPPINGS = {
|
10
|
-
DEFAULT_PADDING => "",
|
11
|
-
:condensed => "Box--condensed",
|
12
|
-
:spacious => "Box--spacious"
|
13
|
-
}.freeze
|
14
|
-
PADDING_SUGGESTION = "Perhaps you could consider using :padding options of #{PADDING_MAPPINGS.keys.to_sentence}?"
|
15
|
-
|
16
|
-
DEFAULT_ROW_SCHEME = :default
|
17
|
-
ROW_SCHEME_MAPPINGS = {
|
18
|
-
DEFAULT_ROW_SCHEME => "",
|
19
|
-
:neutral => "Box-row--gray",
|
20
|
-
:info => "Box-row--blue",
|
21
|
-
:warning => "Box-row--yellow"
|
22
|
-
}.freeze
|
23
|
-
|
24
|
-
# Optional Header.
|
25
|
-
#
|
26
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
27
|
-
# @accessibility
|
28
|
-
# When using header.title, the recommended tag is a heading tag, such as h1, h2, h3, etc.
|
29
|
-
renders_one :header, "Primer::Alpha::BorderBox::Header"
|
30
|
-
|
31
|
-
# Optional Body.
|
32
|
-
#
|
33
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
34
|
-
renders_one :body, lambda { |**system_arguments|
|
35
|
-
system_arguments[:tag] = :div
|
36
|
-
system_arguments[:classes] = class_names(
|
37
|
-
"Box-body",
|
38
|
-
system_arguments[:classes]
|
39
|
-
)
|
40
|
-
|
41
|
-
Primer::BaseComponent.new(**system_arguments)
|
42
|
-
}
|
43
|
-
|
44
|
-
# Optional Footer.
|
45
|
-
#
|
46
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
47
|
-
renders_one :footer, lambda { |**system_arguments|
|
48
|
-
system_arguments[:tag] = :div
|
49
|
-
system_arguments[:classes] = class_names(
|
50
|
-
"Box-footer",
|
51
|
-
system_arguments[:classes]
|
52
|
-
)
|
53
|
-
|
54
|
-
Primer::BaseComponent.new(**system_arguments)
|
55
|
-
}
|
56
|
-
|
57
|
-
# Use Rows to add rows with borders and maintain the same padding.
|
58
|
-
#
|
59
|
-
# @param scheme [Symbol] Color scheme. <%= one_of(Primer::BorderBoxComponent::ROW_SCHEME_MAPPINGS.keys) %>
|
60
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
61
|
-
renders_many :rows, lambda { |scheme: DEFAULT_ROW_SCHEME, **system_arguments|
|
62
|
-
system_arguments[:tag] = :li
|
63
|
-
system_arguments[:classes] = class_names(
|
64
|
-
"Box-row",
|
65
|
-
ROW_SCHEME_MAPPINGS[fetch_or_fallback(ROW_SCHEME_MAPPINGS.keys, scheme, DEFAULT_ROW_SCHEME)],
|
66
|
-
system_arguments[:classes]
|
67
|
-
)
|
68
|
-
|
69
|
-
Primer::BaseComponent.new(**system_arguments)
|
70
|
-
}
|
71
|
-
|
72
|
-
# @example Header with title, body, rows, and footer
|
73
|
-
# <%= render(Primer::BorderBoxComponent.new) do |component| %>
|
74
|
-
# <% component.header do |h| %>
|
75
|
-
# <% h.title(tag: :h2) do %>
|
76
|
-
# Header
|
77
|
-
# <% end %>
|
78
|
-
# <% end %>
|
79
|
-
# <% component.body do %>
|
80
|
-
# Body
|
81
|
-
# <% end %>
|
82
|
-
# <% component.row do %>
|
83
|
-
# <% if true %>
|
84
|
-
# Row one
|
85
|
-
# <% end %>
|
86
|
-
# <% end %>
|
87
|
-
# <% component.row do %>
|
88
|
-
# Row two
|
89
|
-
# <% end %>
|
90
|
-
# <% component.footer do %>
|
91
|
-
# Footer
|
92
|
-
# <% end %>
|
93
|
-
# <% end %>
|
94
|
-
#
|
95
|
-
# @example Padding density
|
96
|
-
# <%= render(Primer::BorderBoxComponent.new(padding: :condensed)) do |component| %>
|
97
|
-
# <% component.header do %>
|
98
|
-
# Header
|
99
|
-
# <% end %>
|
100
|
-
# <% component.body do %>
|
101
|
-
# Body
|
102
|
-
# <% end %>
|
103
|
-
# <% component.row do %>
|
104
|
-
# Row two
|
105
|
-
# <% end %>
|
106
|
-
# <% component.footer do %>
|
107
|
-
# Footer
|
108
|
-
# <% end %>
|
109
|
-
# <% end %>
|
110
|
-
#
|
111
|
-
# @example Row colors
|
112
|
-
# <%= render(Primer::BorderBoxComponent.new) do |component| %>
|
113
|
-
# <% component.row do %>
|
114
|
-
# Default
|
115
|
-
# <% end %>
|
116
|
-
# <% component.row(scheme: :neutral) do %>
|
117
|
-
# Neutral
|
118
|
-
# <% end %>
|
119
|
-
# <% component.row(scheme: :info) do %>
|
120
|
-
# Info
|
121
|
-
# <% end %>
|
122
|
-
# <% component.row(scheme: :warning) do %>
|
123
|
-
# Warning
|
124
|
-
# <% end %>
|
125
|
-
# <% end %>
|
126
|
-
#
|
127
|
-
# @param padding [Symbol] <%= one_of(Primer::BorderBoxComponent::PADDING_MAPPINGS.keys) %>
|
128
|
-
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
129
|
-
def initialize(padding: DEFAULT_PADDING, **system_arguments)
|
130
|
-
@system_arguments = deny_tag_argument(**system_arguments)
|
131
|
-
@system_arguments[:tag] = :div
|
132
|
-
@system_arguments[:classes] = class_names(
|
133
|
-
"Box",
|
134
|
-
PADDING_MAPPINGS[fetch_or_fallback(PADDING_MAPPINGS.keys, padding, DEFAULT_PADDING)],
|
135
|
-
system_arguments[:classes]
|
136
|
-
)
|
137
|
-
|
138
|
-
@system_arguments[:system_arguments_denylist] = { [:p, :pt, :pb, :pr, :pl] => PADDING_SUGGESTION }
|
139
|
-
end
|
140
|
-
|
141
|
-
def render?
|
142
|
-
rows.any? || header.present? || body.present? || footer.present?
|
143
|
-
end
|
4
|
+
class BorderBoxComponent < Primer::Beta::BorderBox
|
5
|
+
status :deprecated
|
144
6
|
end
|
145
7
|
end
|
@@ -1,4 +1,12 @@
|
|
1
|
-
|
2
|
-
<%=
|
3
|
-
|
4
|
-
|
1
|
+
<% if tooltip.present? %>
|
2
|
+
<%= render Primer::BaseComponent.new(tag: :div, position: :relative, display: :inline_block) do %>
|
3
|
+
<%= render Primer::Beta::BaseButton.new(**@system_arguments) do -%>
|
4
|
+
<%= leading_visual %><%= trimmed_content %><%= trailing_visual %><%= primer_octicon("triangle-down", ml: 2, mr: -1) if @dropdown %>
|
5
|
+
<% end -%>
|
6
|
+
<%= tooltip %>
|
7
|
+
<% end -%>
|
8
|
+
<% else %>
|
9
|
+
<%= render Primer::Beta::BaseButton.new(**@system_arguments) do -%>
|
10
|
+
<%= leading_visual %><%= trimmed_content %><%= trailing_visual %><%= primer_octicon("triangle-down", ml: 2, mr: -1) if @dropdown %>
|
11
|
+
<% end -%>
|
12
|
+
<% end %>
|
@@ -123,8 +123,8 @@ module Primer
|
|
123
123
|
# @param scheme [Symbol] <%= one_of(Primer::ButtonComponent::SCHEME_OPTIONS) %>
|
124
124
|
# @param variant [Symbol] DEPRECATED. <%= one_of(Primer::ButtonComponent::SIZE_OPTIONS) %>
|
125
125
|
# @param size [Symbol] <%= one_of(Primer::ButtonComponent::SIZE_OPTIONS) %>
|
126
|
-
# @param tag [Symbol] (Primer::BaseButton::DEFAULT_TAG) <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
|
127
|
-
# @param type [Symbol] (Primer::BaseButton::DEFAULT_TYPE) <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
|
126
|
+
# @param tag [Symbol] (Primer::Beta::BaseButton::DEFAULT_TAG) <%= one_of(Primer::Beta::BaseButton::TAG_OPTIONS) %>
|
127
|
+
# @param type [Symbol] (Primer::Beta::BaseButton::DEFAULT_TYPE) <%= one_of(Primer::Beta::BaseButton::TYPE_OPTIONS) %>
|
128
128
|
# @param group_item [Boolean] Whether button is part of a ButtonGroup.
|
129
129
|
# @param block [Boolean] Whether button is full-width with `display: block`.
|
130
130
|
# @param dropdown [Boolean] Whether or not to render a dropdown caret.
|
@@ -12,7 +12,7 @@ module Primer
|
|
12
12
|
# <%= render(Primer::ClipboardCopy.new(value: "Text to copy", "aria-label": "Copy text to the system clipboard")) %>
|
13
13
|
#
|
14
14
|
# @example With text instead of icons
|
15
|
-
# <%= render(Primer::ClipboardCopy.new(value: "Text to copy"
|
15
|
+
# <%= render(Primer::ClipboardCopy.new(value: "Text to copy")) do %>
|
16
16
|
# Click to copy!
|
17
17
|
# <% end %>
|
18
18
|
#
|
@@ -34,10 +34,14 @@ module Primer
|
|
34
34
|
@system_arguments[:value] = value if value.present?
|
35
35
|
end
|
36
36
|
|
37
|
+
# :nodoc:
|
38
|
+
def before_render
|
39
|
+
validate_aria_label if content.blank?
|
40
|
+
end
|
41
|
+
|
37
42
|
private
|
38
43
|
|
39
44
|
def validate!
|
40
|
-
validate_aria_label
|
41
45
|
raise ArgumentError, "Must provide either `value` or `for`" if @value.nil? && @system_arguments[:for].nil?
|
42
46
|
end
|
43
47
|
end
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# Conditionally renders a `Primer::BaseComponent` around the given content. If the given condition
|
5
|
+
# is true, a `Primer::BaseComponent` will render around the content. If the condition is false, only
|
6
|
+
# the content is rendered.
|
7
|
+
#
|
8
|
+
# @example True conditional
|
9
|
+
# <%# condition is true, so content will be wrapped in a <span> tag
|
10
|
+
# <%= render Primer::ConditionalWrapper.new(condition: true, tag: :span, class: "foobar")) do %>
|
11
|
+
# <%# also rendered %>
|
12
|
+
# <p class="bazboo">Some text</p>
|
13
|
+
# <% end %>
|
14
|
+
#
|
15
|
+
# @example False conditional
|
16
|
+
# <%# condition is false so no <span> tag will render around the content (i.e. the <p> tag)
|
17
|
+
# <%= render(Primer::ConditionalWrapper.new(condition: false, tag: :span, class: "foobar")) do %>
|
18
|
+
# <%# this content will be rendered %>
|
19
|
+
# <p class="bazboo">Some text</p>
|
20
|
+
# <% end %>
|
21
|
+
#
|
22
|
+
# @param condition [Boolean] Whether or not to wrap the content in a `Primer::BaseComponent`.
|
23
|
+
# @param base_component_arguments [Hash] The arguments to pass to `Primer::BaseComponent`.
|
24
|
+
class ConditionalWrapper < Primer::Component
|
25
|
+
def initialize(condition:, **base_component_arguments)
|
26
|
+
@condition = condition
|
27
|
+
@base_component_arguments = base_component_arguments
|
28
|
+
end
|
29
|
+
|
30
|
+
def call
|
31
|
+
return content unless @condition
|
32
|
+
|
33
|
+
BaseComponent.new(**@base_component_arguments).render_in(self) { content }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
<%= render Primer::BaseComponent.new(tag: :div, position: :relative, display: :inline_block) do %>
|
2
|
+
<%= render Primer::Beta::BaseButton.new(**@system_arguments) do -%>
|
3
|
+
<%= render Primer::OcticonComponent.new(icon: @icon) %>
|
4
|
+
<% end -%>
|
5
|
+
<%= render Primer::Alpha::Tooltip.new(**@tooltip_arguments) %>
|
6
|
+
<% end %>
|
@@ -8,6 +8,7 @@ module Primer
|
|
8
8
|
# The `aria-label` should describe the action to be invoked rather than the icon itself. For instance,
|
9
9
|
# if your `IconButton` renders a magnifying glass icon and invokes a search action, the `aria-label` should be
|
10
10
|
# `"Search"` instead of `"Magnifying glass"`.
|
11
|
+
# Either `aria-label` or `aria-description` will be used for the `Tooltip` text, depending on which one is present.
|
11
12
|
# [Learn more about best functional image practices (WAI Images)](https://www.w3.org/WAI/tutorials/images/functional)
|
12
13
|
class IconButton < Primer::Component
|
13
14
|
status :beta
|
@@ -18,9 +19,10 @@ module Primer
|
|
18
19
|
:danger => "btn-octicon-danger"
|
19
20
|
}.freeze
|
20
21
|
SCHEME_OPTIONS = SCHEME_MAPPINGS.keys
|
22
|
+
|
21
23
|
# @example Default
|
22
24
|
#
|
23
|
-
# <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search")) %>
|
25
|
+
# <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search", id: "search-button")) %>
|
24
26
|
#
|
25
27
|
# @example Schemes
|
26
28
|
#
|
@@ -29,23 +31,41 @@ module Primer
|
|
29
31
|
#
|
30
32
|
# @example In a BorderBox
|
31
33
|
#
|
32
|
-
# <%= render(Primer::
|
34
|
+
# <%= render(Primer::Beta::BorderBox.new) do |component| %>
|
33
35
|
# <% component.body do %>
|
34
36
|
# <%= render(Primer::Beta::Text.new(pr: 2)) { "Body" } %>
|
35
37
|
# <%= render(Primer::IconButton.new(icon: :pencil, box: true, "aria-label": "Edit")) %>
|
36
38
|
# <% end %>
|
37
39
|
# <% end %>
|
38
40
|
#
|
41
|
+
# @example With an `aria-description`
|
42
|
+
# @description
|
43
|
+
# If you need to have a longer description for the icon button, use both the `aria-label` and `aria-description`
|
44
|
+
# attributes. A label should be short and concise, while the description can be longer as it is intended to provide
|
45
|
+
# more context and information. See the accessibility section for more information.
|
46
|
+
# @code
|
47
|
+
# <%= render(Primer::IconButton.new(icon: :bold, "aria-label": "Bold", "aria-description": "Add bold text, Cmd+b")) %>
|
48
|
+
#
|
49
|
+
# @example Custom tooltip direction
|
50
|
+
#
|
51
|
+
# <%= render(Primer::IconButton.new(icon: :search, "aria-label": "Search", tooltip_direction: :e)) %>
|
52
|
+
#
|
39
53
|
# @param scheme [Symbol] <%= one_of(Primer::IconButton::SCHEME_OPTIONS) %>
|
40
54
|
# @param icon [String] Name of <%= link_to_octicons %> to use.
|
41
|
-
# @param tag [Symbol] <%= one_of(Primer::BaseButton::TAG_OPTIONS) %>
|
42
|
-
# @param type [Symbol] <%= one_of(Primer::BaseButton::TYPE_OPTIONS) %>
|
43
|
-
# @param
|
55
|
+
# @param tag [Symbol] <%= one_of(Primer::Beta::BaseButton::TAG_OPTIONS) %>
|
56
|
+
# @param type [Symbol] <%= one_of(Primer::Beta::BaseButton::TYPE_OPTIONS) %>
|
57
|
+
# @param aria-label [String] String that can be read by assistive technology. A label should be short and concise. See the accessibility section for more information.
|
58
|
+
# @param aria-description [String] String that can be read by assistive technology. A description can be longer as it is intended to provide more context and information. See the accessibility section for more information.
|
59
|
+
# @param tooltip_direction [Symbol] (Primer::Alpha::Tooltip::DIRECTION_DEFAULT) <%= one_of(Primer::Alpha::Tooltip::DIRECTION_OPTIONS) %>
|
60
|
+
# @param box [Boolean] Whether the button is in a <%= link_to_component(Primer::Beta::BorderBox) %>. If `true`, the button will have the `Box-btn-octicon` class.
|
44
61
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
45
|
-
def initialize(icon:, scheme: DEFAULT_SCHEME, box: false, **system_arguments)
|
62
|
+
def initialize(icon:, scheme: DEFAULT_SCHEME, box: false, tooltip_direction: Primer::Alpha::Tooltip::DIRECTION_DEFAULT, **system_arguments)
|
46
63
|
@icon = icon
|
47
64
|
|
48
65
|
@system_arguments = system_arguments
|
66
|
+
|
67
|
+
@system_arguments[:id] ||= "icon-button-#{SecureRandom.hex(4)}"
|
68
|
+
|
49
69
|
@system_arguments[:classes] = class_names(
|
50
70
|
"btn-octicon",
|
51
71
|
SCHEME_MAPPINGS[fetch_or_fallback(SCHEME_OPTIONS, scheme, DEFAULT_SCHEME)],
|
@@ -54,11 +74,27 @@ module Primer
|
|
54
74
|
)
|
55
75
|
|
56
76
|
validate_aria_label
|
57
|
-
end
|
58
77
|
|
59
|
-
|
60
|
-
|
61
|
-
|
78
|
+
@aria_label = aria("label", @system_arguments)
|
79
|
+
@aria_description = aria("description", @system_arguments)
|
80
|
+
|
81
|
+
@tooltip_arguments = {
|
82
|
+
for_id: @system_arguments[:id],
|
83
|
+
direction: tooltip_direction
|
84
|
+
}
|
85
|
+
|
86
|
+
# If we have both an `aria-label` and a `aria-description`, we create a `Tooltip` with the description type and keep the `aria-label` in the button.
|
87
|
+
# Otherwise, the `aria-label` is used as the tooltip text, which is the `aria-labelled-by` of the button, so we don't set it in the button.
|
88
|
+
if @aria_label.present? && @aria_description.present?
|
89
|
+
@system_arguments.delete(:"aria-description")
|
90
|
+
@system_arguments[:aria].delete(:description) if @system_arguments.include?(:aria)
|
91
|
+
@tooltip_arguments[:text] = @aria_description
|
92
|
+
@tooltip_arguments[:type] = :description
|
93
|
+
else
|
94
|
+
@system_arguments.delete(:"aria-label")
|
95
|
+
@system_arguments[:aria].delete(:label) if @system_arguments.include?(:aria)
|
96
|
+
@tooltip_arguments[:text] = @aria_label
|
97
|
+
@tooltip_arguments[:type] = :label
|
62
98
|
end
|
63
99
|
end
|
64
100
|
end
|
@@ -0,0 +1,12 @@
|
|
1
|
+
<% if tooltip.present? %>
|
2
|
+
<%= render Primer::BaseComponent.new(tag: :span, position: :relative) do %>
|
3
|
+
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
4
|
+
<% content %>
|
5
|
+
<% end %>
|
6
|
+
<%= tooltip %>
|
7
|
+
<% end %>
|
8
|
+
<% else %>
|
9
|
+
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
|
10
|
+
<% content %>
|
11
|
+
<% end %>
|
12
|
+
<% end %>
|
@@ -17,6 +17,8 @@ module Primer
|
|
17
17
|
|
18
18
|
# `Tooltip` that appears on mouse hover or keyboard focus over the link. Use tooltips sparingly and as a last resort.
|
19
19
|
# **Important:** This tooltip defaults to `type: :description`. In a few scenarios, `type: :label` may be more appropriate.
|
20
|
+
# The tooltip will appear adjacent to the anchor element. Both the tooltip and the anchor will be nested
|
21
|
+
# under a positioning wrapper.
|
20
22
|
# Consult the <%= link_to_component(Primer::Alpha::Tooltip) %> documentation for more information.
|
21
23
|
#
|
22
24
|
# @param type [Symbol] (:description) <%= one_of(Primer::Alpha::Tooltip::TYPE_OPTIONS) %>
|
@@ -43,9 +45,6 @@ module Primer
|
|
43
45
|
# @example Without underline
|
44
46
|
# <%= render(Primer::LinkComponent.new(href: "#", underline: false)) { "Link" } %>
|
45
47
|
#
|
46
|
-
# @example Span as link
|
47
|
-
# <%= render(Primer::LinkComponent.new(tag: :span)) { "Span as a link" } %>
|
48
|
-
#
|
49
48
|
# @example With tooltip
|
50
49
|
# @description
|
51
50
|
# Use tooltips sparingly and as a last resort. Consult the <%= link_to_component(Primer::Alpha::Tooltip) %> documentation for more information.
|
@@ -80,11 +79,5 @@ module Primer
|
|
80
79
|
def before_render
|
81
80
|
raise ArgumentError, "href is required when using <a> tag" if @system_arguments[:tag] == :a && @system_arguments[:href].nil? && !Rails.env.production?
|
82
81
|
end
|
83
|
-
|
84
|
-
def call
|
85
|
-
render(Primer::BaseComponent.new(**@system_arguments)) do
|
86
|
-
content.to_s + tooltip.to_s
|
87
|
-
end
|
88
|
-
end
|
89
82
|
end
|
90
83
|
end
|
@@ -7,15 +7,12 @@ module Primer
|
|
7
7
|
class Classify
|
8
8
|
# Handler for PrimerCSS utility classes loaded from utilities.rake
|
9
9
|
class Utilities
|
10
|
-
|
11
|
-
# Disabling because we want to load symbols, strings, and integers from the .yml file
|
12
|
-
# rubocop:disable Security/YAMLLoad
|
13
|
-
UTILITIES = YAML.load(
|
10
|
+
UTILITIES = YAML.safe_load(
|
14
11
|
File.read(
|
15
12
|
File.join(File.dirname(__FILE__), "./utilities.yml")
|
16
|
-
)
|
13
|
+
),
|
14
|
+
permitted_classes: [Symbol]
|
17
15
|
).freeze
|
18
|
-
# rubocop:enable Security/YAMLLoad
|
19
16
|
|
20
17
|
BREAKPOINTS = ["", "-sm", "-md", "-lg", "-xl"].freeze
|
21
18
|
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Primer
|
4
|
+
# :nodoc:
|
5
|
+
class FormComponents
|
6
|
+
def self.from_input(input_klass)
|
7
|
+
Class.new(Primer::Component) do
|
8
|
+
@input_klass = input_klass
|
9
|
+
|
10
|
+
class << self
|
11
|
+
attr_reader :input_klass
|
12
|
+
end
|
13
|
+
|
14
|
+
def initialize(**system_arguments, &block)
|
15
|
+
@system_arguments = system_arguments
|
16
|
+
@block = block
|
17
|
+
end
|
18
|
+
|
19
|
+
def call
|
20
|
+
builder = ActionView::Helpers::FormBuilder.new(
|
21
|
+
nil, nil, __vc_original_view_context, {}
|
22
|
+
)
|
23
|
+
|
24
|
+
input = self.class.input_klass.new(
|
25
|
+
builder: builder,
|
26
|
+
form: nil,
|
27
|
+
**@system_arguments,
|
28
|
+
&@block
|
29
|
+
)
|
30
|
+
|
31
|
+
input.render_in(__vc_original_view_context) { content }
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|