primer_view_components 0.0.113 → 0.0.115
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 +44 -0
- data/app/assets/javascripts/primer_view_components.js +1 -1
- data/app/assets/javascripts/primer_view_components.js.map +1 -1
- data/app/assets/styles/primer_view_components.css +2 -2
- data/app/assets/styles/primer_view_components.css.map +1 -1
- data/app/components/primer/alpha/action_list/divider.rb +2 -0
- data/app/components/primer/alpha/action_list/heading.rb +2 -0
- data/app/components/primer/alpha/action_list/item.rb +8 -6
- data/app/components/primer/alpha/action_list.rb +1 -0
- data/app/components/primer/alpha/auto_complete/auto_complete.html.erb +1 -1
- data/app/components/primer/alpha/auto_complete/item.rb +1 -0
- data/app/components/primer/alpha/auto_complete.rb +3 -2
- data/app/components/primer/alpha/banner.html.erb +1 -1
- data/app/components/primer/alpha/banner.rb +1 -0
- data/app/components/primer/alpha/button_marketing.rb +2 -0
- data/app/components/primer/alpha/dialog.rb +3 -0
- data/app/components/primer/alpha/image.rb +1 -0
- data/app/components/primer/alpha/image_crop.html.erb +1 -1
- data/app/components/primer/alpha/layout.css +1 -0
- data/app/components/primer/alpha/layout.css.json +1 -0
- data/app/components/primer/alpha/layout.css.map +1 -0
- data/app/components/primer/alpha/layout.pcss +268 -0
- data/app/components/primer/{menu_component.css → alpha/menu.css} +0 -0
- data/app/components/primer/alpha/menu.css.json +1 -0
- data/app/components/primer/alpha/menu.css.map +1 -0
- data/app/components/primer/{menu_component.html.erb → alpha/menu.html.erb} +0 -0
- data/app/components/primer/{menu_component.pcss → alpha/menu.pcss} +0 -0
- data/app/components/primer/alpha/menu.rb +76 -0
- data/app/components/primer/{octicon_symbols_component.html.erb → alpha/octicon_symbols.html.erb} +0 -0
- data/app/components/primer/alpha/octicon_symbols.rb +61 -0
- data/app/components/primer/alpha/text_field.rb +1 -0
- data/app/components/primer/alpha/toggle_switch.html.erb +2 -2
- data/app/components/primer/alpha/toggle_switch.rb +2 -0
- data/app/components/primer/alpha/tool_tip.js +77 -69
- data/app/components/primer/alpha/tool_tip.ts +63 -51
- data/app/components/primer/alpha/tooltip.rb +2 -0
- data/app/components/primer/beta/auto_complete/item.rb +4 -4
- data/app/components/primer/beta/auto_complete.rb +3 -3
- data/app/components/primer/beta/avatar.rb +1 -0
- data/app/components/primer/beta/base_button.rb +1 -0
- data/app/components/primer/beta/blankslate.rb +5 -5
- data/app/components/primer/beta/button.rb +7 -7
- data/app/components/primer/beta/clipboard_copy.html.erb +2 -2
- data/app/components/primer/beta/clipboard_copy.rb +1 -0
- data/app/components/primer/beta/close_button.rb +2 -1
- data/app/components/primer/beta/counter.rb +1 -0
- data/app/components/primer/beta/heading.rb +1 -0
- data/app/components/primer/beta/icon_button.html.erb +1 -1
- data/app/components/primer/beta/icon_button.rb +1 -0
- data/app/components/primer/beta/label.rb +1 -0
- data/app/components/primer/beta/markdown.rb +291 -0
- data/app/components/primer/{octicon_component.html.erb → beta/octicon.html.erb} +0 -0
- data/app/components/primer/beta/octicon.rb +88 -0
- data/app/components/primer/beta/relative_time.rb +2 -1
- data/app/components/primer/{spinner_component.html.erb → beta/spinner.html.erb} +0 -0
- data/app/components/primer/beta/spinner.rb +46 -0
- data/app/components/primer/beta/text.rb +1 -0
- data/app/components/primer/blankslate_component.rb +3 -3
- data/app/components/primer/box.rb +1 -0
- data/app/components/primer/button_component.rb +3 -3
- data/app/components/primer/conditional_wrapper.rb +2 -0
- data/app/components/primer/hellip_button.rb +2 -0
- data/app/components/primer/icon_button.html.erb +2 -2
- data/app/components/primer/icon_button.rb +1 -0
- data/app/components/primer/layout_component.rb +2 -0
- data/app/components/primer/local_time.rb +3 -0
- data/app/components/primer/markdown.rb +2 -283
- data/app/components/primer/menu_component.rb +2 -69
- data/app/components/primer/navigation/tab_component.rb +2 -2
- data/app/components/primer/octicon_component.rb +3 -81
- data/app/components/primer/octicon_symbols_component.rb +2 -52
- data/app/components/primer/primer.d.ts +2 -0
- data/app/components/primer/primer.js +2 -0
- data/app/components/primer/primer.pcss +2 -3
- data/app/components/primer/primer.ts +2 -0
- data/app/components/primer/spinner_component.rb +2 -38
- data/app/components/primer/state_component.rb +1 -0
- data/app/components/primer/subhead_component.rb +2 -0
- data/app/components/primer/tab_container_component.rb +2 -0
- data/app/components/primer/time_ago_component.rb +2 -1
- data/app/components/primer/timeline_item_component.rb +3 -2
- data/app/components/primer/tooltip.rb +1 -0
- data/app/components/primer/truncate.rb +2 -0
- data/app/forms/immediate_validation_form.rb +29 -0
- data/app/forms/multi_input_form.rb +4 -2
- data/app/lib/primer/css/layout.css +1 -378
- data/app/lib/primer/css/layout.css.json +1 -1
- data/app/lib/primer/octicon/cache.rb +1 -1
- data/app/lib/primer/view_helper.rb +1 -1
- data/lib/primer/deprecations.yml +30 -0
- data/lib/primer/forms/builder.rb +48 -8
- data/lib/primer/forms/check_box.html.erb +3 -1
- data/lib/primer/forms/dsl/input.rb +23 -1
- data/lib/primer/forms/dsl/multi_input.rb +6 -9
- data/lib/primer/forms/dsl/select_list_input.rb +1 -1
- data/lib/primer/forms/dsl/text_field_input.rb +31 -1
- data/lib/primer/forms/form_control.html.erb +17 -13
- data/lib/primer/forms/form_control.rb +2 -0
- data/lib/primer/forms/multi.html.erb +6 -2
- data/lib/primer/forms/primer_multi_input.d.ts +10 -0
- data/lib/primer/forms/primer_multi_input.js +45 -0
- data/lib/primer/forms/primer_multi_input.ts +46 -0
- data/lib/primer/forms/primer_text_field.d.ts +1 -0
- data/lib/primer/forms/primer_text_field.js +62 -0
- data/lib/primer/forms/primer_text_field.ts +48 -0
- data/lib/primer/forms/radio_button.html.erb +3 -1
- data/lib/primer/forms/text_field.html.erb +8 -8
- data/lib/primer/forms/text_field.rb +11 -0
- data/lib/primer/view_components/linters/close_button_component_migration_counter.rb +1 -1
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/tasks/docs.rake +6 -6
- data/lib/tasks/helpers/ast_traverser.rb +1 -1
- data/previews/primer/alpha/action_list_preview.rb +1 -1
- data/previews/primer/alpha/auto_complete_preview.rb +62 -6
- data/previews/primer/alpha/layout_preview.rb +179 -6
- data/previews/primer/{menu_component_preview → alpha/menu_preview}/default.html.erb +3 -3
- data/previews/primer/{menu_component_preview → alpha/menu_preview}/playground.html.erb +3 -3
- data/previews/primer/alpha/menu_preview.rb +14 -0
- data/previews/primer/alpha/toggle_switch_preview.rb +11 -9
- data/previews/primer/beta/auto_complete_preview/with_submit_button.html.erb +1 -1
- data/previews/primer/beta/auto_complete_preview.rb +19 -17
- data/previews/primer/{markdown_preview.rb → beta/markdown_preview.rb} +14 -12
- data/previews/primer/beta/octicon_preview.rb +24 -0
- data/previews/primer/beta/spinner_preview.rb +22 -0
- data/previews/primer/forms/forms_preview/immediate_validation_form.html.erb +3 -0
- data/previews/primer/forms/forms_preview/multi_input_form.html.erb +12 -1
- data/previews/primer/forms/forms_preview.rb +2 -0
- data/previews/primer/url_helpers.rb +15 -0
- data/static/arguments.json +178 -178
- data/static/audited_at.json +5 -0
- data/static/constants.json +50 -40
- data/static/statuses.json +12 -7
- metadata +34 -24
- data/app/components/primer/beta/button_group.css +0 -1
- data/app/components/primer/beta/button_group.css.json +0 -1
- data/app/components/primer/beta/button_group.css.map +0 -1
- data/app/components/primer/beta/button_group.pcss +0 -92
- data/app/components/primer/button_component.css +0 -1
- data/app/components/primer/button_component.css.json +0 -1
- data/app/components/primer/button_component.css.map +0 -1
- data/app/components/primer/button_component.pcss +0 -557
- data/app/components/primer/menu_component.css.json +0 -1
- data/app/components/primer/menu_component.css.map +0 -1
- data/previews/primer/menu_component_preview.rb +0 -12
- data/previews/primer/octicon_component_preview.rb +0 -22
- data/previews/primer/spinner_component_preview.rb +0 -20
data/lib/primer/forms/builder.rb
CHANGED
|
@@ -2,6 +2,29 @@
|
|
|
2
2
|
|
|
3
3
|
require "primer/classify"
|
|
4
4
|
|
|
5
|
+
# See: https://github.com/rails/rails/pull/46666
|
|
6
|
+
ActionView::Helpers::Tags::Base.prepend(
|
|
7
|
+
Module.new do
|
|
8
|
+
def initialize(*args, **kwargs, &block)
|
|
9
|
+
super
|
|
10
|
+
|
|
11
|
+
return if defined?(@generate_error_markup)
|
|
12
|
+
|
|
13
|
+
@generate_error_markup = @options.delete(:generate_error_markup) { true }
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
private
|
|
17
|
+
|
|
18
|
+
def error_wrapping(html_tag)
|
|
19
|
+
return html_tag unless @generate_error_markup
|
|
20
|
+
|
|
21
|
+
# :nocov:
|
|
22
|
+
super
|
|
23
|
+
# :nocov:
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
)
|
|
27
|
+
|
|
5
28
|
module Primer
|
|
6
29
|
module Forms
|
|
7
30
|
# :nodoc:
|
|
@@ -10,32 +33,49 @@ module Primer
|
|
|
10
33
|
|
|
11
34
|
UTILITY_KEYS = Primer::Classify::Utilities::UTILITIES.keys.freeze
|
|
12
35
|
|
|
13
|
-
def label(
|
|
14
|
-
super(
|
|
36
|
+
def label(method, text = nil, **options, &block)
|
|
37
|
+
super(method, text, classify(options).merge(generate_error_markup: false), &block)
|
|
15
38
|
end
|
|
16
39
|
|
|
17
40
|
def check_box(method, options = {}, checked_value = 1, unchecked_value = 0, &block)
|
|
18
|
-
super(
|
|
41
|
+
super(
|
|
42
|
+
method,
|
|
43
|
+
classify(options).merge(generate_error_markup: false),
|
|
44
|
+
checked_value,
|
|
45
|
+
unchecked_value,
|
|
46
|
+
&block
|
|
47
|
+
)
|
|
19
48
|
end
|
|
20
49
|
|
|
21
50
|
def radio_button(*args, **options, &block)
|
|
22
|
-
super(*args, classify(options), &block)
|
|
51
|
+
super(*args, classify(options).merge(generate_error_markup: false), &block)
|
|
23
52
|
end
|
|
24
53
|
|
|
25
|
-
def select(
|
|
26
|
-
super(
|
|
54
|
+
def select(method, choices = nil, options = {}, html_options = {}, &block)
|
|
55
|
+
super(method, choices, options.merge(generate_error_markup: false), classify(html_options), &block)
|
|
27
56
|
end
|
|
28
57
|
|
|
29
58
|
def text_field(*args, **options, &block)
|
|
30
|
-
super(*args, classify(options), &block)
|
|
59
|
+
super(*args, classify(options).merge(generate_error_markup: false), &block)
|
|
31
60
|
end
|
|
32
61
|
|
|
33
62
|
def text_area(*args, **options, &block)
|
|
34
|
-
super(*args, classify(options), &block)
|
|
63
|
+
super(*args, classify(options).merge(generate_error_markup: false), &block)
|
|
35
64
|
end
|
|
36
65
|
|
|
37
66
|
private
|
|
38
67
|
|
|
68
|
+
# This method does the following:
|
|
69
|
+
#
|
|
70
|
+
# 1. Runs Primer's classify routine to convert entries like mb: 1 to mb-1.
|
|
71
|
+
# 2. Runs classify on both options[:class] and options[:classes]. The first
|
|
72
|
+
# is expected by Rails/HTML while the second is specific to Primer.
|
|
73
|
+
# 3. Combines options[:class] and options[:classes] into options[:class]
|
|
74
|
+
# so the options hash can be easily passed to Rails form builder methods.
|
|
75
|
+
# 4. Sets generate_error_markup: false, which, in combination with the
|
|
76
|
+
# monkeypatch at the top of this file, skips rendering any markup around
|
|
77
|
+
# invalid fields.
|
|
78
|
+
#
|
|
39
79
|
def classify(options)
|
|
40
80
|
options[:classes] = class_names(options.delete(:class), options[:classes])
|
|
41
81
|
options.merge!(Primer::Classify.call(options))
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
<%= builder.label(@input.name, **@input.label_arguments) do %>
|
|
5
5
|
<%= @input.label %>
|
|
6
6
|
<% end %>
|
|
7
|
-
|
|
7
|
+
<% if @input.form_control? %>
|
|
8
|
+
<%= render(Caption.new(input: @input)) %>
|
|
9
|
+
<% end %>
|
|
8
10
|
</span>
|
|
9
11
|
<% end %>
|
|
10
12
|
<% if @input.nested_form_block %>
|
|
@@ -16,7 +16,9 @@ module Primer
|
|
|
16
16
|
|
|
17
17
|
include Primer::ClassNameHelper
|
|
18
18
|
|
|
19
|
-
attr_reader :builder, :form, :input_arguments, :label_arguments, :caption, :validation_message, :ids
|
|
19
|
+
attr_reader :builder, :form, :input_arguments, :label_arguments, :caption, :validation_message, :ids, :form_control
|
|
20
|
+
|
|
21
|
+
alias form_control? form_control
|
|
20
22
|
|
|
21
23
|
def initialize(builder:, form:, **system_arguments)
|
|
22
24
|
@builder = builder
|
|
@@ -41,6 +43,10 @@ module Primer
|
|
|
41
43
|
@full_width = @input_arguments.delete(:full_width)
|
|
42
44
|
@size = @input_arguments.delete(:size)
|
|
43
45
|
|
|
46
|
+
# Whether or not to wrap the component in a FormControl, which renders a
|
|
47
|
+
# label above and validation message beneath the input.
|
|
48
|
+
@form_control = @input_arguments.delete(:form_control) { true }
|
|
49
|
+
|
|
44
50
|
@input_arguments[:invalid] = "true" if invalid?
|
|
45
51
|
|
|
46
52
|
base_id = SecureRandom.hex[0..5]
|
|
@@ -200,6 +206,22 @@ module Primer
|
|
|
200
206
|
true
|
|
201
207
|
end
|
|
202
208
|
|
|
209
|
+
def need_validation_element?
|
|
210
|
+
invalid?
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def validation_arguments
|
|
214
|
+
{
|
|
215
|
+
class: "FormControl-inlineValidation",
|
|
216
|
+
id: validation_id,
|
|
217
|
+
hidden: valid?
|
|
218
|
+
}
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def validation_message_arguments
|
|
222
|
+
{}
|
|
223
|
+
end
|
|
224
|
+
|
|
203
225
|
private
|
|
204
226
|
|
|
205
227
|
def input_data
|
|
@@ -34,19 +34,16 @@ module Primer
|
|
|
34
34
|
check_one_input_visible!
|
|
35
35
|
end
|
|
36
36
|
|
|
37
|
-
def decorate_options(name
|
|
38
|
-
|
|
39
|
-
new_options
|
|
37
|
+
def decorate_options(name:, **options)
|
|
38
|
+
new_options = { name: @name, label: nil, form_control: false, **options }
|
|
39
|
+
new_options[:data] ||= {}
|
|
40
|
+
new_options[:data][:name] = name
|
|
41
|
+
new_options[:data][:targets] = "primer-multi-input.fields"
|
|
40
42
|
new_options[:id] = nil if options[:hidden]
|
|
43
|
+
new_options[:disabled] = true if options[:hidden] # disable to avoid submitting to server
|
|
41
44
|
new_options
|
|
42
45
|
end
|
|
43
46
|
|
|
44
|
-
def check_name!(name)
|
|
45
|
-
return if name == @name
|
|
46
|
-
|
|
47
|
-
raise ArgumentError, "Inputs inside a `multi' block must all have the same name. Expected '#{@name}', got '#{name}'."
|
|
48
|
-
end
|
|
49
|
-
|
|
50
47
|
def check_one_input_visible!
|
|
51
48
|
return if inputs.count { |input| !input.hidden? } <= 1
|
|
52
49
|
|
|
@@ -8,7 +8,7 @@ module Primer
|
|
|
8
8
|
attr_reader(
|
|
9
9
|
*%i[
|
|
10
10
|
name label show_clear_button leading_visual clear_button_id
|
|
11
|
-
visually_hide_label inset monospace field_wrap_classes
|
|
11
|
+
visually_hide_label inset monospace field_wrap_classes auto_check_src
|
|
12
12
|
]
|
|
13
13
|
)
|
|
14
14
|
|
|
@@ -21,6 +21,7 @@ module Primer
|
|
|
21
21
|
@clear_button_id = system_arguments.delete(:clear_button_id)
|
|
22
22
|
@inset = system_arguments.delete(:inset)
|
|
23
23
|
@monospace = system_arguments.delete(:monospace)
|
|
24
|
+
@auto_check_src = system_arguments.delete(:auto_check_src)
|
|
24
25
|
|
|
25
26
|
super(**system_arguments)
|
|
26
27
|
|
|
@@ -29,6 +30,7 @@ module Primer
|
|
|
29
30
|
Primer::Forms::Dsl::Input::SIZE_MAPPINGS[size]
|
|
30
31
|
)
|
|
31
32
|
|
|
33
|
+
add_input_data(:target, "primer-text-field.inputElement") if auto_check_src.present?
|
|
32
34
|
add_input_classes("FormControl-inset") if inset?
|
|
33
35
|
add_input_classes("FormControl-monospace") if monospace?
|
|
34
36
|
end
|
|
@@ -52,6 +54,34 @@ module Primer
|
|
|
52
54
|
def leading_visual?
|
|
53
55
|
!!@leading_visual
|
|
54
56
|
end
|
|
57
|
+
|
|
58
|
+
def need_validation_element?
|
|
59
|
+
super || auto_check_src.present?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
def validation_arguments
|
|
63
|
+
if auto_check_src.present?
|
|
64
|
+
super.merge(
|
|
65
|
+
data: {
|
|
66
|
+
target: "primer-text-field.validationElement"
|
|
67
|
+
}
|
|
68
|
+
)
|
|
69
|
+
else
|
|
70
|
+
super
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def validation_message_arguments
|
|
75
|
+
if auto_check_src.present?
|
|
76
|
+
super.merge(
|
|
77
|
+
data: {
|
|
78
|
+
target: "primer-text-field.validationMessageElement"
|
|
79
|
+
}
|
|
80
|
+
)
|
|
81
|
+
else
|
|
82
|
+
super
|
|
83
|
+
end
|
|
84
|
+
end
|
|
55
85
|
end
|
|
56
86
|
end
|
|
57
87
|
end
|
|
@@ -1,18 +1,22 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
<%= @input.
|
|
5
|
-
|
|
6
|
-
|
|
1
|
+
<% if @input.form_control? %>
|
|
2
|
+
<%= content_tag(:div, **@form_group_arguments) do %>
|
|
3
|
+
<% if @input.label %>
|
|
4
|
+
<%= builder.label(@input.name, **@input.label_arguments) do %>
|
|
5
|
+
<%= @input.label %>
|
|
6
|
+
<% if @input.required? %>
|
|
7
|
+
<span aria-hidden="true">*</span>
|
|
8
|
+
<% end %>
|
|
7
9
|
<% end %>
|
|
8
10
|
<% end %>
|
|
11
|
+
<%= content %>
|
|
12
|
+
<% if @input.need_validation_element? %>
|
|
13
|
+
<%= content_tag(:div, **@input.validation_arguments) do %>
|
|
14
|
+
<%= render(Primer::Beta::Octicon.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %>
|
|
15
|
+
<%= content_tag(:span, @input.validation_messages.first, **@input.validation_message_arguments) %>
|
|
16
|
+
<% end %>
|
|
17
|
+
<% end %>
|
|
18
|
+
<%= render(Caption.new(input: @input)) %>
|
|
9
19
|
<% end %>
|
|
20
|
+
<% else %>
|
|
10
21
|
<%= content %>
|
|
11
|
-
<% if @input.invalid? && @input.validation_messages.present? %>
|
|
12
|
-
<div class="FormControl-inlineValidation" id="<%= @input.validation_id %>">
|
|
13
|
-
<%= render(Primer::OcticonComponent.new(icon: :"alert-fill", size: :xsmall, aria: { hidden: true })) %>
|
|
14
|
-
<span><%= @input.validation_messages.first %></span>
|
|
15
|
-
</div>
|
|
16
|
-
<% end %>
|
|
17
|
-
<%= render(Caption.new(input: @input)) %>
|
|
18
22
|
<% end %>
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
<%=
|
|
1
|
+
<%= render(FormControl.new(input: @input)) do %>
|
|
2
|
+
<primer-multi-input data-name="<%= @input.name %>">
|
|
3
|
+
<% @input.inputs.each do |child_input| %>
|
|
4
|
+
<%= render(child_input.to_component) %>
|
|
5
|
+
<% end %>
|
|
6
|
+
</primer-multi-input>
|
|
3
7
|
<% end %>
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export declare class PrimerMultiInputElement extends HTMLElement {
|
|
2
|
+
fields: HTMLInputElement[];
|
|
3
|
+
activateField(name: string): void;
|
|
4
|
+
private findField;
|
|
5
|
+
}
|
|
6
|
+
declare global {
|
|
7
|
+
interface Window {
|
|
8
|
+
PrimerMultiInputElement: typeof PrimerMultiInputElement;
|
|
9
|
+
}
|
|
10
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
|
8
|
+
import { controller, targets } from '@github/catalyst';
|
|
9
|
+
let PrimerMultiInputElement = class PrimerMultiInputElement extends HTMLElement {
|
|
10
|
+
activateField(name) {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
const fieldWithName = this.findField(name);
|
|
13
|
+
if (!fieldWithName)
|
|
14
|
+
return;
|
|
15
|
+
for (const field of this.fields) {
|
|
16
|
+
if (field === fieldWithName)
|
|
17
|
+
continue;
|
|
18
|
+
field.setAttribute('disabled', 'disabled');
|
|
19
|
+
field.setAttribute('hidden', 'hidden');
|
|
20
|
+
(_a = field.parentElement) === null || _a === void 0 ? void 0 : _a.setAttribute('hidden', 'hidden');
|
|
21
|
+
}
|
|
22
|
+
fieldWithName.removeAttribute('disabled');
|
|
23
|
+
fieldWithName.removeAttribute('hidden');
|
|
24
|
+
(_b = fieldWithName.parentElement) === null || _b === void 0 ? void 0 : _b.removeAttribute('hidden');
|
|
25
|
+
}
|
|
26
|
+
findField(name) {
|
|
27
|
+
for (const field of this.fields) {
|
|
28
|
+
if (field.getAttribute('data-name') === name) {
|
|
29
|
+
return field;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
__decorate([
|
|
36
|
+
targets
|
|
37
|
+
], PrimerMultiInputElement.prototype, "fields", void 0);
|
|
38
|
+
PrimerMultiInputElement = __decorate([
|
|
39
|
+
controller
|
|
40
|
+
], PrimerMultiInputElement);
|
|
41
|
+
export { PrimerMultiInputElement };
|
|
42
|
+
if (!window.customElements.get('primer-multi-input')) {
|
|
43
|
+
Object.assign(window, { PrimerMultiInputElement });
|
|
44
|
+
window.customElements.define('primer-multi-input', PrimerMultiInputElement);
|
|
45
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/* eslint-disable custom-elements/expose-class-on-global */
|
|
2
|
+
import {controller, targets} from '@github/catalyst'
|
|
3
|
+
|
|
4
|
+
@controller
|
|
5
|
+
export class PrimerMultiInputElement extends HTMLElement {
|
|
6
|
+
@targets fields: HTMLInputElement[]
|
|
7
|
+
|
|
8
|
+
activateField(name: string) {
|
|
9
|
+
const fieldWithName = this.findField(name)
|
|
10
|
+
if (!fieldWithName) return
|
|
11
|
+
|
|
12
|
+
for (const field of this.fields) {
|
|
13
|
+
if (field === fieldWithName) continue
|
|
14
|
+
|
|
15
|
+
field.setAttribute('disabled', 'disabled')
|
|
16
|
+
field.setAttribute('hidden', 'hidden')
|
|
17
|
+
|
|
18
|
+
field.parentElement?.setAttribute('hidden', 'hidden')
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
fieldWithName.removeAttribute('disabled')
|
|
22
|
+
fieldWithName.removeAttribute('hidden')
|
|
23
|
+
fieldWithName.parentElement?.removeAttribute('hidden')
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
private findField(name: string): HTMLElement | null {
|
|
27
|
+
for (const field of this.fields) {
|
|
28
|
+
if (field.getAttribute('data-name') === name) {
|
|
29
|
+
return field
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
declare global {
|
|
38
|
+
interface Window {
|
|
39
|
+
PrimerMultiInputElement: typeof PrimerMultiInputElement
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
if (!window.customElements.get('primer-multi-input')) {
|
|
44
|
+
Object.assign(window, {PrimerMultiInputElement})
|
|
45
|
+
window.customElements.define('primer-multi-input', PrimerMultiInputElement)
|
|
46
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import '@github/auto-check-element';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
|
2
|
+
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
|
3
|
+
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
|
4
|
+
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
|
5
|
+
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
|
6
|
+
};
|
|
7
|
+
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
+
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
+
};
|
|
12
|
+
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
13
|
+
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
14
|
+
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
15
|
+
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
16
|
+
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
17
|
+
};
|
|
18
|
+
var _PrimerTextFieldElement_abortController;
|
|
19
|
+
import '@github/auto-check-element';
|
|
20
|
+
import { controller, target } from '@github/catalyst';
|
|
21
|
+
let PrimerTextFieldElement = class PrimerTextFieldElement extends HTMLElement {
|
|
22
|
+
constructor() {
|
|
23
|
+
super(...arguments);
|
|
24
|
+
_PrimerTextFieldElement_abortController.set(this, void 0);
|
|
25
|
+
}
|
|
26
|
+
connectedCallback() {
|
|
27
|
+
var _a;
|
|
28
|
+
(_a = __classPrivateFieldGet(this, _PrimerTextFieldElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
|
|
29
|
+
const { signal } = (__classPrivateFieldSet(this, _PrimerTextFieldElement_abortController, new AbortController(), "f"));
|
|
30
|
+
this.inputElement.addEventListener('auto-check-success', () => { this.clearError(); }, { signal });
|
|
31
|
+
this.inputElement.addEventListener('auto-check-error', (event) => {
|
|
32
|
+
event.detail.response.text().then((error_message) => { this.setError(error_message); });
|
|
33
|
+
}, { signal });
|
|
34
|
+
}
|
|
35
|
+
disconnectedCallback() {
|
|
36
|
+
var _a;
|
|
37
|
+
(_a = __classPrivateFieldGet(this, _PrimerTextFieldElement_abortController, "f")) === null || _a === void 0 ? void 0 : _a.abort();
|
|
38
|
+
}
|
|
39
|
+
clearError() {
|
|
40
|
+
this.inputElement.removeAttribute('invalid');
|
|
41
|
+
this.validationElement.hidden = true;
|
|
42
|
+
this.validationMessageElement.innerText = '';
|
|
43
|
+
}
|
|
44
|
+
setError(message) {
|
|
45
|
+
this.validationMessageElement.innerText = message;
|
|
46
|
+
this.validationElement.hidden = false;
|
|
47
|
+
this.inputElement.setAttribute('invalid', 'true');
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
_PrimerTextFieldElement_abortController = new WeakMap();
|
|
51
|
+
__decorate([
|
|
52
|
+
target
|
|
53
|
+
], PrimerTextFieldElement.prototype, "inputElement", void 0);
|
|
54
|
+
__decorate([
|
|
55
|
+
target
|
|
56
|
+
], PrimerTextFieldElement.prototype, "validationElement", void 0);
|
|
57
|
+
__decorate([
|
|
58
|
+
target
|
|
59
|
+
], PrimerTextFieldElement.prototype, "validationMessageElement", void 0);
|
|
60
|
+
PrimerTextFieldElement = __decorate([
|
|
61
|
+
controller
|
|
62
|
+
], PrimerTextFieldElement);
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import '@github/auto-check-element'
|
|
2
|
+
import {controller, target} from '@github/catalyst'
|
|
3
|
+
|
|
4
|
+
@controller
|
|
5
|
+
class PrimerTextFieldElement extends HTMLElement {
|
|
6
|
+
@target inputElement: HTMLInputElement
|
|
7
|
+
@target validationElement: HTMLElement
|
|
8
|
+
@target validationMessageElement: HTMLElement
|
|
9
|
+
|
|
10
|
+
#abortController: AbortController | null
|
|
11
|
+
|
|
12
|
+
connectedCallback(): void {
|
|
13
|
+
this.#abortController?.abort()
|
|
14
|
+
const {signal} = (this.#abortController = new AbortController())
|
|
15
|
+
|
|
16
|
+
this.inputElement.addEventListener(
|
|
17
|
+
'auto-check-success',
|
|
18
|
+
() => { this.clearError() },
|
|
19
|
+
{signal}
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
this.inputElement.addEventListener(
|
|
23
|
+
'auto-check-error',
|
|
24
|
+
(event: any) => {
|
|
25
|
+
event.detail.response.text().then(
|
|
26
|
+
(error_message: string) => { this.setError(error_message) }
|
|
27
|
+
)
|
|
28
|
+
},
|
|
29
|
+
{signal}
|
|
30
|
+
)
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
disconnectedCallback() {
|
|
34
|
+
this.#abortController?.abort()
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
clearError(): void {
|
|
38
|
+
this.inputElement.removeAttribute('invalid')
|
|
39
|
+
this.validationElement.hidden = true
|
|
40
|
+
this.validationMessageElement.innerText = ''
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
setError(message: string): void {
|
|
44
|
+
this.validationMessageElement.innerText = message
|
|
45
|
+
this.validationElement.hidden = false
|
|
46
|
+
this.inputElement.setAttribute('invalid', 'true')
|
|
47
|
+
}
|
|
48
|
+
}
|
|
@@ -4,7 +4,9 @@
|
|
|
4
4
|
<%= builder.label(@input.name, value: @input.value, **@input.label_arguments) do %>
|
|
5
5
|
<%= @input.label %>
|
|
6
6
|
<% end %>
|
|
7
|
-
|
|
7
|
+
<% if @input.form_control? %>
|
|
8
|
+
<%= render(Caption.new(input: @input)) %>
|
|
9
|
+
<% end %>
|
|
8
10
|
</span>
|
|
9
11
|
<% end %>
|
|
10
12
|
<% if @input.nested_form_block %>
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
<%= render
|
|
2
|
-
|
|
1
|
+
<%= render Primer::ConditionalWrapper.new(condition: @input.auto_check_src, tag: "primer-text-field") do %>
|
|
2
|
+
<%= render(FormControl.new(input: @input)) do %>
|
|
3
3
|
<%= content_tag(:div, **@field_wrap_arguments) do %>
|
|
4
4
|
<% if @input.leading_visual %>
|
|
5
5
|
<span class="FormControl-input-leadingVisualWrap">
|
|
6
|
-
<%= render(Primer::
|
|
6
|
+
<%= render(Primer::Beta::Octicon.new(**@input.leading_visual)) %>
|
|
7
7
|
</span>
|
|
8
8
|
<% end %>
|
|
9
|
-
<%=
|
|
9
|
+
<%= render Primer::ConditionalWrapper.new(condition: @input.auto_check_src, tag: "auto-check", csrf: auto_check_authenticity_token, src: @input.auto_check_src) do %>
|
|
10
|
+
<%= builder.text_field(@input.name, **@input.input_arguments) %>
|
|
11
|
+
<% end %>
|
|
10
12
|
<% if @input.show_clear_button? %>
|
|
11
|
-
<button id="<%= @input.clear_button_id %>" class="FormControl-input-trailingAction" aria-label="Clear">
|
|
12
|
-
<%= render(Primer::
|
|
13
|
+
<button type="button" id="<%= @input.clear_button_id %>" class="FormControl-input-trailingAction" aria-label="Clear">
|
|
14
|
+
<%= render(Primer::Beta::Octicon.new(icon: :"x-circle-fill")) %>
|
|
13
15
|
</button>
|
|
14
16
|
<% end %>
|
|
15
17
|
<% end %>
|
|
16
|
-
<% else %>
|
|
17
|
-
<%= builder.text_field(@input.name, **@input.input_arguments) %>
|
|
18
18
|
<% end %>
|
|
19
19
|
<% end %>
|
|
@@ -20,6 +20,17 @@ module Primer
|
|
|
20
20
|
hidden: @input.hidden?
|
|
21
21
|
}
|
|
22
22
|
end
|
|
23
|
+
|
|
24
|
+
def auto_check_authenticity_token
|
|
25
|
+
return @auto_check_authenticity_token if defined?(@auto_check_authenticity_token)
|
|
26
|
+
|
|
27
|
+
@auto_check_authenticity_token =
|
|
28
|
+
if @input.auto_check_src
|
|
29
|
+
@view_context.form_authenticity_token(
|
|
30
|
+
form_options: { method: :post, action: @input.auto_check_src }
|
|
31
|
+
)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
23
34
|
end
|
|
24
35
|
end
|
|
25
36
|
end
|
|
@@ -40,7 +40,7 @@ module ERBLint
|
|
|
40
40
|
if ast.method_name == :primer_octicon || ast.method_name == :octicon
|
|
41
41
|
octicon_kwargs = ast.arguments[1]
|
|
42
42
|
icon = icon(ast.arguments)
|
|
43
|
-
elsif ast.method_name == :render && code.include?("Primer::
|
|
43
|
+
elsif ast.method_name == :render && code.include?("Primer::Beta::Octicon")
|
|
44
44
|
octicon_kwargs = ast.arguments.first.arguments.last
|
|
45
45
|
icon = icon(ast.arguments.first.arguments)
|
|
46
46
|
else
|
data/lib/tasks/docs.rake
CHANGED
|
@@ -37,7 +37,7 @@ namespace :docs do
|
|
|
37
37
|
Primer::HellipButton,
|
|
38
38
|
Primer::Alpha::Image,
|
|
39
39
|
Primer::LocalTime,
|
|
40
|
-
Primer::
|
|
40
|
+
Primer::Alpha::OcticonSymbols,
|
|
41
41
|
Primer::Alpha::ImageCrop,
|
|
42
42
|
Primer::IconButton,
|
|
43
43
|
Primer::Beta::AutoComplete,
|
|
@@ -67,14 +67,14 @@ namespace :docs do
|
|
|
67
67
|
Primer::Beta::Label,
|
|
68
68
|
Primer::LayoutComponent,
|
|
69
69
|
Primer::Beta::Link,
|
|
70
|
-
Primer::Markdown,
|
|
71
|
-
Primer::
|
|
70
|
+
Primer::Beta::Markdown,
|
|
71
|
+
Primer::Alpha::Menu,
|
|
72
72
|
Primer::Navigation::TabComponent,
|
|
73
|
-
Primer::
|
|
73
|
+
Primer::Beta::Octicon,
|
|
74
74
|
Primer::Beta::Popover,
|
|
75
75
|
Primer::Beta::ProgressBar,
|
|
76
76
|
Primer::StateComponent,
|
|
77
|
-
Primer::
|
|
77
|
+
Primer::Beta::Spinner,
|
|
78
78
|
Primer::SubheadComponent,
|
|
79
79
|
Primer::TabContainerComponent,
|
|
80
80
|
Primer::Beta::Text,
|
|
@@ -515,7 +515,7 @@ namespace :docs do
|
|
|
515
515
|
def lookbook_url(component)
|
|
516
516
|
path = component.name.underscore.gsub("_component", "")
|
|
517
517
|
|
|
518
|
-
"https://primer.style/view-components/lookbook/inspect/#{path}/default/"
|
|
518
|
+
"https://primer.style/view-components/lookbook/inspect/#{path}_preview/default/"
|
|
519
519
|
end
|
|
520
520
|
|
|
521
521
|
def preview_exists?(component)
|
|
@@ -54,7 +54,7 @@ class AstTraverser
|
|
|
54
54
|
end
|
|
55
55
|
|
|
56
56
|
# Octicon is the only component that accepts positional arguments.
|
|
57
|
-
res[:icon] = args.first.source if name == "Primer::
|
|
57
|
+
res[:icon] = args.first.source if name == "Primer::Beta::Octicon" && args.size > 1
|
|
58
58
|
|
|
59
59
|
res
|
|
60
60
|
end
|