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.
Files changed (147) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +44 -0
  3. data/app/assets/javascripts/primer_view_components.js +1 -1
  4. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  5. data/app/assets/styles/primer_view_components.css +2 -2
  6. data/app/assets/styles/primer_view_components.css.map +1 -1
  7. data/app/components/primer/alpha/action_list/divider.rb +2 -0
  8. data/app/components/primer/alpha/action_list/heading.rb +2 -0
  9. data/app/components/primer/alpha/action_list/item.rb +8 -6
  10. data/app/components/primer/alpha/action_list.rb +1 -0
  11. data/app/components/primer/alpha/auto_complete/auto_complete.html.erb +1 -1
  12. data/app/components/primer/alpha/auto_complete/item.rb +1 -0
  13. data/app/components/primer/alpha/auto_complete.rb +3 -2
  14. data/app/components/primer/alpha/banner.html.erb +1 -1
  15. data/app/components/primer/alpha/banner.rb +1 -0
  16. data/app/components/primer/alpha/button_marketing.rb +2 -0
  17. data/app/components/primer/alpha/dialog.rb +3 -0
  18. data/app/components/primer/alpha/image.rb +1 -0
  19. data/app/components/primer/alpha/image_crop.html.erb +1 -1
  20. data/app/components/primer/alpha/layout.css +1 -0
  21. data/app/components/primer/alpha/layout.css.json +1 -0
  22. data/app/components/primer/alpha/layout.css.map +1 -0
  23. data/app/components/primer/alpha/layout.pcss +268 -0
  24. data/app/components/primer/{menu_component.css → alpha/menu.css} +0 -0
  25. data/app/components/primer/alpha/menu.css.json +1 -0
  26. data/app/components/primer/alpha/menu.css.map +1 -0
  27. data/app/components/primer/{menu_component.html.erb → alpha/menu.html.erb} +0 -0
  28. data/app/components/primer/{menu_component.pcss → alpha/menu.pcss} +0 -0
  29. data/app/components/primer/alpha/menu.rb +76 -0
  30. data/app/components/primer/{octicon_symbols_component.html.erb → alpha/octicon_symbols.html.erb} +0 -0
  31. data/app/components/primer/alpha/octicon_symbols.rb +61 -0
  32. data/app/components/primer/alpha/text_field.rb +1 -0
  33. data/app/components/primer/alpha/toggle_switch.html.erb +2 -2
  34. data/app/components/primer/alpha/toggle_switch.rb +2 -0
  35. data/app/components/primer/alpha/tool_tip.js +77 -69
  36. data/app/components/primer/alpha/tool_tip.ts +63 -51
  37. data/app/components/primer/alpha/tooltip.rb +2 -0
  38. data/app/components/primer/beta/auto_complete/item.rb +4 -4
  39. data/app/components/primer/beta/auto_complete.rb +3 -3
  40. data/app/components/primer/beta/avatar.rb +1 -0
  41. data/app/components/primer/beta/base_button.rb +1 -0
  42. data/app/components/primer/beta/blankslate.rb +5 -5
  43. data/app/components/primer/beta/button.rb +7 -7
  44. data/app/components/primer/beta/clipboard_copy.html.erb +2 -2
  45. data/app/components/primer/beta/clipboard_copy.rb +1 -0
  46. data/app/components/primer/beta/close_button.rb +2 -1
  47. data/app/components/primer/beta/counter.rb +1 -0
  48. data/app/components/primer/beta/heading.rb +1 -0
  49. data/app/components/primer/beta/icon_button.html.erb +1 -1
  50. data/app/components/primer/beta/icon_button.rb +1 -0
  51. data/app/components/primer/beta/label.rb +1 -0
  52. data/app/components/primer/beta/markdown.rb +291 -0
  53. data/app/components/primer/{octicon_component.html.erb → beta/octicon.html.erb} +0 -0
  54. data/app/components/primer/beta/octicon.rb +88 -0
  55. data/app/components/primer/beta/relative_time.rb +2 -1
  56. data/app/components/primer/{spinner_component.html.erb → beta/spinner.html.erb} +0 -0
  57. data/app/components/primer/beta/spinner.rb +46 -0
  58. data/app/components/primer/beta/text.rb +1 -0
  59. data/app/components/primer/blankslate_component.rb +3 -3
  60. data/app/components/primer/box.rb +1 -0
  61. data/app/components/primer/button_component.rb +3 -3
  62. data/app/components/primer/conditional_wrapper.rb +2 -0
  63. data/app/components/primer/hellip_button.rb +2 -0
  64. data/app/components/primer/icon_button.html.erb +2 -2
  65. data/app/components/primer/icon_button.rb +1 -0
  66. data/app/components/primer/layout_component.rb +2 -0
  67. data/app/components/primer/local_time.rb +3 -0
  68. data/app/components/primer/markdown.rb +2 -283
  69. data/app/components/primer/menu_component.rb +2 -69
  70. data/app/components/primer/navigation/tab_component.rb +2 -2
  71. data/app/components/primer/octicon_component.rb +3 -81
  72. data/app/components/primer/octicon_symbols_component.rb +2 -52
  73. data/app/components/primer/primer.d.ts +2 -0
  74. data/app/components/primer/primer.js +2 -0
  75. data/app/components/primer/primer.pcss +2 -3
  76. data/app/components/primer/primer.ts +2 -0
  77. data/app/components/primer/spinner_component.rb +2 -38
  78. data/app/components/primer/state_component.rb +1 -0
  79. data/app/components/primer/subhead_component.rb +2 -0
  80. data/app/components/primer/tab_container_component.rb +2 -0
  81. data/app/components/primer/time_ago_component.rb +2 -1
  82. data/app/components/primer/timeline_item_component.rb +3 -2
  83. data/app/components/primer/tooltip.rb +1 -0
  84. data/app/components/primer/truncate.rb +2 -0
  85. data/app/forms/immediate_validation_form.rb +29 -0
  86. data/app/forms/multi_input_form.rb +4 -2
  87. data/app/lib/primer/css/layout.css +1 -378
  88. data/app/lib/primer/css/layout.css.json +1 -1
  89. data/app/lib/primer/octicon/cache.rb +1 -1
  90. data/app/lib/primer/view_helper.rb +1 -1
  91. data/lib/primer/deprecations.yml +30 -0
  92. data/lib/primer/forms/builder.rb +48 -8
  93. data/lib/primer/forms/check_box.html.erb +3 -1
  94. data/lib/primer/forms/dsl/input.rb +23 -1
  95. data/lib/primer/forms/dsl/multi_input.rb +6 -9
  96. data/lib/primer/forms/dsl/select_list_input.rb +1 -1
  97. data/lib/primer/forms/dsl/text_field_input.rb +31 -1
  98. data/lib/primer/forms/form_control.html.erb +17 -13
  99. data/lib/primer/forms/form_control.rb +2 -0
  100. data/lib/primer/forms/multi.html.erb +6 -2
  101. data/lib/primer/forms/primer_multi_input.d.ts +10 -0
  102. data/lib/primer/forms/primer_multi_input.js +45 -0
  103. data/lib/primer/forms/primer_multi_input.ts +46 -0
  104. data/lib/primer/forms/primer_text_field.d.ts +1 -0
  105. data/lib/primer/forms/primer_text_field.js +62 -0
  106. data/lib/primer/forms/primer_text_field.ts +48 -0
  107. data/lib/primer/forms/radio_button.html.erb +3 -1
  108. data/lib/primer/forms/text_field.html.erb +8 -8
  109. data/lib/primer/forms/text_field.rb +11 -0
  110. data/lib/primer/view_components/linters/close_button_component_migration_counter.rb +1 -1
  111. data/lib/primer/view_components/version.rb +1 -1
  112. data/lib/tasks/docs.rake +6 -6
  113. data/lib/tasks/helpers/ast_traverser.rb +1 -1
  114. data/previews/primer/alpha/action_list_preview.rb +1 -1
  115. data/previews/primer/alpha/auto_complete_preview.rb +62 -6
  116. data/previews/primer/alpha/layout_preview.rb +179 -6
  117. data/previews/primer/{menu_component_preview → alpha/menu_preview}/default.html.erb +3 -3
  118. data/previews/primer/{menu_component_preview → alpha/menu_preview}/playground.html.erb +3 -3
  119. data/previews/primer/alpha/menu_preview.rb +14 -0
  120. data/previews/primer/alpha/toggle_switch_preview.rb +11 -9
  121. data/previews/primer/beta/auto_complete_preview/with_submit_button.html.erb +1 -1
  122. data/previews/primer/beta/auto_complete_preview.rb +19 -17
  123. data/previews/primer/{markdown_preview.rb → beta/markdown_preview.rb} +14 -12
  124. data/previews/primer/beta/octicon_preview.rb +24 -0
  125. data/previews/primer/beta/spinner_preview.rb +22 -0
  126. data/previews/primer/forms/forms_preview/immediate_validation_form.html.erb +3 -0
  127. data/previews/primer/forms/forms_preview/multi_input_form.html.erb +12 -1
  128. data/previews/primer/forms/forms_preview.rb +2 -0
  129. data/previews/primer/url_helpers.rb +15 -0
  130. data/static/arguments.json +178 -178
  131. data/static/audited_at.json +5 -0
  132. data/static/constants.json +50 -40
  133. data/static/statuses.json +12 -7
  134. metadata +34 -24
  135. data/app/components/primer/beta/button_group.css +0 -1
  136. data/app/components/primer/beta/button_group.css.json +0 -1
  137. data/app/components/primer/beta/button_group.css.map +0 -1
  138. data/app/components/primer/beta/button_group.pcss +0 -92
  139. data/app/components/primer/button_component.css +0 -1
  140. data/app/components/primer/button_component.css.json +0 -1
  141. data/app/components/primer/button_component.css.map +0 -1
  142. data/app/components/primer/button_component.pcss +0 -557
  143. data/app/components/primer/menu_component.css.json +0 -1
  144. data/app/components/primer/menu_component.css.map +0 -1
  145. data/previews/primer/menu_component_preview.rb +0 -12
  146. data/previews/primer/octicon_component_preview.rb +0 -22
  147. data/previews/primer/spinner_component_preview.rb +0 -20
@@ -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(*args, **options, &block)
14
- super(*args, classify(options), &block)
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(method, classify(options), checked_value, unchecked_value, &block)
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(*args, **options, &block)
26
- super(*args, classify(options), &block)
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
- <%= render(Caption.new(input: @input)) %>
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: nil, **options)
38
- check_name!(name) if name
39
- new_options = { name: name || @name, label: nil, **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
 
@@ -5,7 +5,7 @@ module Primer
5
5
  module Dsl
6
6
  # :nodoc:
7
7
  class SelectListInput < Input
8
- SELECT_ARGUMENTS = %i[multiple disabled include_blank prompt].freeze
8
+ SELECT_ARGUMENTS = %i[multiple include_blank prompt].freeze
9
9
 
10
10
  # :nodoc:
11
11
  class Option
@@ -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
- <%= content_tag(:div, style: "flex-grow: 1", **@form_group_arguments) do %>
2
- <% if @input.label %>
3
- <%= builder.label(@input.name, **@input.label_arguments) do %>
4
- <%= @input.label %>
5
- <% if @input.required? %>
6
- <span aria-hidden="true">*</span>
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 %>
@@ -12,6 +12,8 @@ module Primer
12
12
  @form_group_arguments = {
13
13
  class: class_names(
14
14
  "FormControl",
15
+ "flex-1",
16
+ "width-full",
15
17
  "FormControl--fullWidth" => @input.full_width?
16
18
  )
17
19
  }
@@ -1,3 +1,7 @@
1
- <% @input.inputs.each do |child_input| %>
2
- <%= render(child_input.to_component) %>
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
- <%= render(Caption.new(input: @input)) %>
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(FormControl.new(input: @input)) do %>
2
- <% if @input.leading_visual || @input.show_clear_button? %>
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::OcticonComponent.new(**@input.leading_visual)) %>
6
+ <%= render(Primer::Beta::Octicon.new(**@input.leading_visual)) %>
7
7
  </span>
8
8
  <% end %>
9
- <%= builder.text_field(@input.name, **@input.input_arguments) %>
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::OcticonComponent.new(icon: :"x-circle-fill")) %>
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::OcticonComponent")
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
@@ -6,7 +6,7 @@ module Primer
6
6
  module VERSION
7
7
  MAJOR = 0
8
8
  MINOR = 0
9
- PATCH = 113
9
+ PATCH = 115
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
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::OcticonSymbolsComponent,
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::MenuComponent,
70
+ Primer::Beta::Markdown,
71
+ Primer::Alpha::Menu,
72
72
  Primer::Navigation::TabComponent,
73
- Primer::OcticonComponent,
73
+ Primer::Beta::Octicon,
74
74
  Primer::Beta::Popover,
75
75
  Primer::Beta::ProgressBar,
76
76
  Primer::StateComponent,
77
- Primer::SpinnerComponent,
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::OcticonComponent" && args.size > 1
57
+ res[:icon] = args.first.source if name == "Primer::Beta::Octicon" && args.size > 1
58
58
 
59
59
  res
60
60
  end
@@ -169,7 +169,7 @@ module Primer
169
169
  tooltip: false
170
170
  )
171
171
  list = Primer::Alpha::ActionList.new(aria: { label: "Action List" })
172
- list.item(
172
+ list.with_item(
173
173
  label: label,
174
174
  truncate_label: truncate_label,
175
175
  href: href,