primer_view_components 0.0.45 → 0.0.49

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +194 -0
  3. data/app/components/primer/{auto_complete_component.d.ts → auto_complete/auto_component.d.ts} +0 -0
  4. data/app/components/primer/{auto_complete_component.js → auto_complete/auto_component.js} +0 -0
  5. data/app/components/primer/base_component.rb +36 -7
  6. data/app/components/primer/beta/auto_complete.rb +159 -0
  7. data/app/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
  8. data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.html.erb +0 -0
  9. data/app/components/primer/beta/auto_complete/auto_complete.js +1 -0
  10. data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.ts +0 -0
  11. data/app/components/primer/beta/auto_complete/item.rb +44 -0
  12. data/app/components/primer/beta/avatar.rb +77 -0
  13. data/app/components/primer/{avatar_stack_component.html.erb → beta/avatar_stack.html.erb} +0 -0
  14. data/app/components/primer/beta/avatar_stack.rb +92 -0
  15. data/app/components/primer/border_box_component.rb +3 -0
  16. data/app/components/primer/component.rb +9 -1
  17. data/app/components/primer/details_component.rb +12 -8
  18. data/app/components/primer/image_crop.html.erb +4 -4
  19. data/app/components/primer/image_crop.rb +1 -1
  20. data/app/components/primer/markdown.rb +9 -9
  21. data/app/components/primer/menu_component.rb +7 -3
  22. data/app/components/primer/navigation/tab_component.rb +34 -6
  23. data/app/components/primer/popover_component.rb +6 -3
  24. data/app/components/primer/primer.d.ts +1 -1
  25. data/app/components/primer/primer.js +1 -1
  26. data/app/components/primer/primer.ts +1 -1
  27. data/app/components/primer/tab_nav_component.rb +9 -6
  28. data/app/components/primer/timeline_item_component.rb +2 -2
  29. data/app/components/primer/tooltip.rb +1 -1
  30. data/app/components/primer/truncate.rb +6 -1
  31. data/app/components/primer/underline_nav_component.rb +13 -6
  32. data/{app/lib → lib}/primer/classify.rb +12 -39
  33. data/{app/lib → lib}/primer/classify/cache.rb +6 -20
  34. data/{app/lib → lib}/primer/classify/flex.rb +0 -0
  35. data/{app/lib → lib}/primer/classify/functional_background_colors.rb +2 -0
  36. data/{app/lib → lib}/primer/classify/functional_border_colors.rb +2 -0
  37. data/{app/lib → lib}/primer/classify/functional_colors.rb +0 -0
  38. data/{app/lib → lib}/primer/classify/functional_text_colors.rb +2 -0
  39. data/{app/lib → lib}/primer/classify/grid.rb +0 -0
  40. data/{app/lib → lib}/primer/classify/utilities.rb +54 -22
  41. data/{app/lib → lib}/primer/classify/utilities.yml +124 -0
  42. data/lib/primer/view_components.rb +35 -6
  43. data/lib/primer/view_components/constants.rb +55 -0
  44. data/lib/primer/view_components/linters/argument_mappers/base.rb +39 -0
  45. data/lib/primer/view_components/linters/argument_mappers/button.rb +35 -44
  46. data/lib/primer/view_components/linters/argument_mappers/clipboard_copy.rb +25 -0
  47. data/lib/primer/view_components/linters/argument_mappers/label.rb +56 -0
  48. data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +1 -2
  49. data/lib/primer/view_components/linters/autocorrectable.rb +30 -0
  50. data/lib/primer/view_components/linters/button_component_migration_counter.rb +9 -23
  51. data/lib/primer/view_components/linters/clipboard_copy_component_migration_counter.rb +21 -0
  52. data/lib/primer/view_components/linters/helpers.rb +56 -38
  53. data/lib/primer/view_components/linters/label_component_migration_counter.rb +25 -0
  54. data/lib/primer/view_components/statuses.rb +14 -0
  55. data/lib/primer/view_components/version.rb +1 -1
  56. data/lib/rubocop/config/default.yml +12 -0
  57. data/lib/rubocop/cop/primer.rb +4 -0
  58. data/lib/rubocop/cop/primer/no_tag_memoize.rb +42 -0
  59. data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +75 -0
  60. data/lib/tasks/constants.rake +12 -0
  61. data/lib/tasks/docs.rake +89 -34
  62. data/lib/tasks/utilities.rake +9 -11
  63. data/lib/yard/docs_helper.rb +12 -3
  64. data/static/arguments.yml +977 -0
  65. data/static/assets/view-components.svg +18 -0
  66. data/static/classes.yml +174 -0
  67. data/static/constants.json +628 -0
  68. data/static/statuses.json +5 -5
  69. metadata +44 -27
  70. data/app/components/primer/auto_complete.rb +0 -156
  71. data/app/components/primer/auto_complete/item.rb +0 -42
  72. data/app/components/primer/avatar_component.rb +0 -75
  73. data/app/components/primer/avatar_stack_component.rb +0 -84
  74. data/app/components/primer/details_menu_component.d.ts +0 -1
  75. data/app/components/primer/details_menu_component.js +0 -1
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8953ba874b51d234f8b42590fb30c2cc073c54ffd3b7a56dad24b9e6aa4d2f26
4
- data.tar.gz: a0ac7e3a02d41fde2096547c8c68a91f99c003dee28bcb18a5e0862f46c1058f
3
+ metadata.gz: 43c27ddfb1f920ba9dfd9989d859cc61b3fd26bc3788a44873412c971ad58cc1
4
+ data.tar.gz: 640aed54b2b1e68bb24c06989320f445da9e2e3c2981e959e693345f61fc92cf
5
5
  SHA512:
6
- metadata.gz: 89aa1e3a6f977a4bf25675092205034efc9797d275ea9d8e01b7bc50423506f67b2d05ca03a74b69dd3b16b669c6fa68d12b96895647218ca758034ed00d29ab
7
- data.tar.gz: 46eead3cd6ae2b57008f2f7699e572029e736c5000dfd480c0cd5f399de7ac6160f746ccfab2d79305216f7e0602fc280b356051cd120e796f88988dde0fe303
6
+ metadata.gz: 7c6b6ce07b479c462a01cfe65ccda3da920689c5e6642231f897bf5f92f559836d30d6f01bfec2c7ae99545c391abe25b85e7cd45da18de8249f63176b00bedb
7
+ data.tar.gz: ef88c518675d73c7c418fee48a11f173200f3a98ab4f10115fcfad5ccf5fa4ef0b3452da7bb9577a55a3d3286a3536f616f56aac4a07108421e8466abc76250b
data/CHANGELOG.md CHANGED
@@ -1,7 +1,201 @@
1
1
  # CHANGELOG
2
2
 
3
+ <!--
4
+ Authoring changelog entries
5
+
6
+ This file holds all the changes made in previous versions of Primer View Components and the ones coming to the next version.
7
+ To add yours, you need to find in which category to write it under the `main` section. `Main` is the first section on top of the document.
8
+ There are six categories currently in use, `New`, `Updates`, `Bug fixes`, `Breaking changes`, `Deprecations` and `Misc`.
9
+
10
+ - New
11
+ Category for new components, system behaviours, options and arguments changes
12
+
13
+ - Updates
14
+ Every non-breaking change to the source code go there.
15
+
16
+ - Bug Fixes
17
+ Non-breaking bug fixes to existing code.
18
+
19
+ - Breaking Changes
20
+ The category for changes creating incompatibilities to code written with previous versions.
21
+ It includes any changes to components name, signature and behaviour. Also, include removing tags options or changing file location.
22
+ If you are not sure you made breaking changes, ask us in your pull request.
23
+
24
+ - Deprecations
25
+ For changes that explicitly deprecate part of the code base.
26
+
27
+ - Misc
28
+ The category for changes related to documentation, testing and tooling. Also, for pull requests that can't fit in other sections.
29
+ -->
30
+
3
31
  ## main
4
32
 
33
+ ## 0.0.49
34
+
35
+ ### New
36
+
37
+ * Add linter suggestions for `Label` component.
38
+
39
+ *Manuel Puyol*
40
+
41
+ * Add linter suggestions for `ClipboardCopy` component.
42
+
43
+ *Manuel Puyol*
44
+
45
+ ### Updates
46
+
47
+ * Update the `Truncate` component to accept `:strong` as a tag.
48
+
49
+ *Amélia Chavot*
50
+
51
+ * Improve `Primer::Classify::Utilities.classes_to_hash` performance.
52
+
53
+ *Manuel Puyol*
54
+
55
+ ### Breaking changes
56
+
57
+ * Require tab with panels to have `panel_id` so `aria-controls` can be set.
58
+
59
+ *Kate Higa*
60
+
61
+ * Renames:
62
+ * `Primer::AvatarStackComponent` to `Primer::Beta::AvatarStack`.
63
+
64
+ *Manuel Puyol*
65
+
66
+ ### Misc
67
+
68
+ * Extract example tag parsing into helper.
69
+
70
+ *Kate Higa*
71
+
72
+ * Generate a static constant JSON and use it when defining linters.
73
+
74
+ *Manuel Puyol*
75
+
76
+ ## 0.0.48
77
+
78
+ ### Breaking changes
79
+
80
+ * Ensure panels in `Navigation::Tab` have a label.
81
+
82
+ *Kate Higa*
83
+
84
+ ### Misc
85
+
86
+ * Expose custom cops and default config for erblint.
87
+
88
+ *Manuel Puyol*
89
+
90
+ * Fix double constant assign.
91
+
92
+ *Manuel Puyol*
93
+
94
+ ## 0.0.47
95
+
96
+ ### Breaking changes
97
+
98
+ * Restrict tag for `Popover` to `:div` and `Popover` heading slot to headings.
99
+
100
+ *Kate Higa*
101
+
102
+ * Renames:
103
+ * `Primer::AutoComplete` to `Primer::Beta::AutoComplete`
104
+ * `Primer::AutoComplete::Item` to `Primer::Beta::AutoComplete::Item`
105
+ * `Primer::AvatarComponent` to `Primer::Beta::Avatar`
106
+
107
+ *Manuel Puyol*
108
+
109
+ ### Misc
110
+
111
+ * Update `doc_examples_axe_test` to exclude non-standalone components and fix `Markdown` example.
112
+
113
+ *Kate Higa*
114
+
115
+ * Update `DetailsComponent` examples.
116
+
117
+ *Manuel Puyol*
118
+
119
+ * Add linter to suggest system arguments instead of classes.
120
+
121
+ *Manuel Puyol*
122
+
123
+ * Update component generator to create components in the right status module.
124
+
125
+ *Manuel Puyol*
126
+
127
+ * Add example for truncating HTML to `Truncate`.
128
+
129
+ *Joel Hawksley*
130
+
131
+ * Update docs generation to point to the correct file sources.
132
+
133
+ *Manuel Puyol*
134
+
135
+ * Add ENV flag to dump linter data into a file.
136
+
137
+ *Manuel Puyol*
138
+
139
+ ## 0.0.46
140
+
141
+ ### Updates
142
+
143
+ * Default to matching `name` and `id` of `input`.
144
+
145
+ *Kate Higa*
146
+
147
+ * Restrict usage of padding system arguments on BorderBox, recommending use of `padding` density instead.
148
+
149
+ *Joel Hawksley*
150
+
151
+ ### Breaking changes
152
+
153
+ * Restrict `TabNav`and `Tab` tags.
154
+
155
+ *Kate Higa*
156
+
157
+ * Restrict `AvatarStack` body slot tag and `ImageCrop` spinner tag.
158
+
159
+ *Kate Higa*
160
+
161
+ * Restrict `Details` body slot tags and `UnderlineNav` body slot tags.
162
+
163
+ *Kate Higa*
164
+
165
+ * Move Primer::Classify from `app/lib/` to `lib/`. This requires an extra `require "primer/classify"` statement for anywhere Classify is needed.
166
+
167
+ *Manuel Puyol, Jon Rohan*
168
+
169
+ * Restrict `Menu` heading slot tags to heading tags and require `tag` argument.
170
+
171
+ *Kate Higa*
172
+
173
+ * Adding animation, vertical_align, word_break, display, visibility, & position arguments to the utilities class. `animation: :grow` is now `animation: :hover_grow` this was a change because we changed the class name in primer.
174
+
175
+ *Jon Rohan*
176
+
177
+ ### Misc
178
+
179
+ * Update contributing guidelines with release instructions.
180
+
181
+ *Kate Higa*
182
+
183
+ * Prevent flexible tag syntax with rubocop rule.
184
+
185
+ *Kate Higa*
186
+
187
+ * Update linter autocorrection to use `""` instead of `true` for boolean attributes.
188
+
189
+ *Manuel Puyol*
190
+
191
+ * Update Storybook version.
192
+
193
+ *Manuel Puyol*
194
+
195
+ * Added a changelog authoring guide to `CHANGELOG.md`.
196
+
197
+ *Amélia Chavot*
198
+
5
199
  ## 0.0.45
6
200
 
7
201
  ### Updates
@@ -1,5 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "primer/classify"
4
+
3
5
  module Primer
4
6
  # All Primer ViewComponents accept a standard set of options called system arguments, mimicking the [styled-system API](https://styled-system.com/table) used by [Primer React](https://primer.style/components/system-props).
5
7
  #
@@ -43,7 +45,7 @@ module Primer
43
45
  #
44
46
  # | Name | Type | Description |
45
47
  # | :- | :- | :- |
46
- # | `animation` | Symbol | <%= one_of([:fade_in, :fade_out, :fade_up, :fade_down, :scale_in, :pulse, :grow_x, :grow]) %> |
48
+ # | `animation` | Symbol | <%= one_of(Primer::Classify::Utilities.mappings(:animation)) %> |
47
49
  #
48
50
  # ## Border
49
51
  #
@@ -61,7 +63,7 @@ module Primer
61
63
  #
62
64
  # | Name | Type | Description |
63
65
  # | :- | :- | :- |
64
- # | `bg` | String, Symbol | Background color. Accepts either a hex value as a String or <%= one_of(Primer::Classify::FunctionalBorderColors::OPTIONS, lower: true) %> |
66
+ # | `bg` | String, Symbol | Background color. Accepts either a hex value as a String or <%= one_of(Primer::Classify::FunctionalBackgroundColors::OPTIONS, lower: true) %> |
65
67
  # | `border_color` | Symbol | Border color. <%= one_of(Primer::Classify::FunctionalBorderColors::OPTIONS) %> |
66
68
  # | `color` | Symbol | Text color. <%= one_of(Primer::Classify::FunctionalTextColors::OPTIONS) %> |
67
69
  #
@@ -91,11 +93,11 @@ module Primer
91
93
  #
92
94
  # | Name | Type | Description |
93
95
  # | :- | :- | :- |
94
- # | `display` | Symbol | <%= one_of([:none, :block, :flex, :inline, :inline_block, :inline_flex, :table, :table_cell]) %> |
96
+ # | `display` | Symbol | <%= one_of(Primer::Classify::Utilities.mappings(:display)) %> |
95
97
  # | `height` | Symbol | <%= one_of([:fit]) %> |
96
98
  # | `hide` | Symbol | Hide the element at a specific breakpoint. <%= one_of(Primer::Classify::Utilities.mappings(:hide)) %> |
97
- # | `v` | Symbol | Visibility. <%= one_of([:hidden, :visible]) %> |
98
- # | `vertical_align` | Symbol | <%= one_of([:baseline, :top, :middle, :bottom, :text_top, :text_bottom]) %> |
99
+ # | `visibility` | Symbol | Visibility. <%= one_of(Primer::Classify::Utilities.mappings(:visibility)) %> |
100
+ # | `vertical_align` | Symbol | <%= one_of(Primer::Classify::Utilities.mappings(:vertical_align)) %> |
99
101
  #
100
102
  # ## Position
101
103
  #
@@ -104,7 +106,7 @@ module Primer
104
106
  # | `bottom` | Boolean | If `false`, sets `bottom: 0`. |
105
107
  # | `float` | Symbol | <%= one_of(Primer::Classify::Utilities.mappings(:float)) %> |
106
108
  # | `left` | Boolean | If `false`, sets `left: 0`. |
107
- # | `position` | Symbol | <%= one_of([:relative, :absolute, :fixed]) %> |
109
+ # | `position` | Symbol | <%= one_of(Primer::Classify::Utilities.mappings(:position)) %> |
108
110
  # | `right` | Boolean | If `false`, sets `right: 0`. |
109
111
  # | `top` | Boolean | If `false`, sets `top: 0`. |
110
112
  #
@@ -138,7 +140,7 @@ module Primer
138
140
  # | `text_align` | Symbol | Text alignment. <%= one_of([:left, :right, :center]) %> |
139
141
  # | `text_transform` | Symbol | Text alignment. <%= one_of([:uppercase]) %> |
140
142
  # | `underline` | Boolean | Whether text should be underlined. |
141
- # | `word_break` | Symbol | Whether to break words on line breaks. Can only be `:break_all`. |
143
+ # | `word_break` | Symbol | Whether to break words on line breaks. <%= one_of(Primer::Classify::Utilities.mappings(:word_break)) %> |
142
144
  #
143
145
  # ## Other
144
146
  #
@@ -152,6 +154,33 @@ module Primer
152
154
 
153
155
  raise ArgumentError, "`class` is an invalid argument. Use `classes` instead." if system_arguments.key?(:class) && !Rails.env.production?
154
156
 
157
+ if (denylist = system_arguments[:system_arguments_denylist])
158
+ if force_system_arguments? && !ENV["PRIMER_WARNINGS_DISABLED"]
159
+ # Convert denylist from:
160
+ # { [:p, :pt] => "message" } to:
161
+ # { p: "message", pt: "message" }
162
+ unpacked_denylist =
163
+ denylist.each_with_object({}) do |(keys, value), memo|
164
+ keys.each { |key| memo[key] = value }
165
+ end
166
+
167
+ violations = unpacked_denylist.keys & @system_arguments.keys
168
+
169
+ if violations.any?
170
+ message = "Found #{violations.count} #{'violation'.pluralize(violations)}:"
171
+ violations.each do |violation|
172
+ message += "\n The #{violation} system argument is not allowed here. #{unpacked_denylist[violation]}"
173
+ end
174
+
175
+ raise(ArgumentError, message)
176
+ end
177
+ end
178
+
179
+ # Remove :system_arguments_denylist key and any denied keys from system arguments
180
+ @system_arguments.except!(:system_arguments_denylist)
181
+ @system_arguments.except!(*denylist.keys.flatten)
182
+ end
183
+
155
184
  @result = Primer::Classify.call(**@system_arguments.merge(classes: classes))
156
185
 
157
186
  @system_arguments[:"data-view-component"] = true
@@ -0,0 +1,159 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Primer
4
+ module Beta
5
+ # Use `AutoComplete` to provide a user with a list of selectable suggestions that appear when they type into the
6
+ # input field. This list is populated by server search results.
7
+ # @accessibility
8
+ # Always set an accessible label to help the user interact with the component.
9
+ #
10
+ # * Set the `label` slot to render a visible label. Alternatively, associate an existing visible text element
11
+ # as a label by setting `aria-labelledby`.
12
+ # * If you must use a non-visible label, set `:"aria-label"` on `AutoComplete` and Primer
13
+ # will apply it to the correct elements. However, please note that a visible label should almost
14
+ # always be used unless there is compelling reason not to. A placeholder is not a label.
15
+ class AutoComplete < Primer::Component
16
+ status :beta
17
+
18
+ # Optionally render a visible label. See <%= link_to_accessibility %>
19
+ #
20
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
21
+ renders_one :label, lambda { |**system_arguments|
22
+ system_arguments[:for] = @input_id
23
+ system_arguments[:tag] = :label
24
+ Primer::BaseComponent.new(**system_arguments)
25
+ }
26
+
27
+ # Required input used to search for results
28
+ #
29
+ # @param type [Symbol] <%= one_of(Primer::Beta::AutoComplete::Input::TYPE_OPTIONS) %>
30
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
31
+ renders_one :input, lambda { |**system_arguments|
32
+ aria_label = aria("label", system_arguments) || @aria_label
33
+ if aria_label.present?
34
+ system_arguments[:"aria-label"] = aria_label
35
+ system_arguments[:aria]&.delete(:label)
36
+ end
37
+
38
+ name = system_arguments[:name] || @input_id
39
+ Input.new(id: @input_id, name: name, **system_arguments)
40
+ }
41
+
42
+ # Optional icon to be rendered before the input. Has the same arguments as <%= link_to_component(Primer::OcticonComponent) %>.
43
+ #
44
+ renders_one :icon, Primer::OcticonComponent
45
+
46
+ # Customizable results list.
47
+ #
48
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
49
+ renders_one :results, lambda { |**system_arguments|
50
+ system_arguments[:tag] = :ul
51
+ system_arguments[:id] = @list_id
52
+ system_arguments[:classes] = class_names(
53
+ "autocomplete-results",
54
+ system_arguments[:classes]
55
+ )
56
+
57
+ aria_label = system_arguments[:"aria-label"] || system_arguments.dig(:aria, :label) || @aria_label
58
+ system_arguments[:"aria-label"] = aria_label if aria_label.present?
59
+ system_arguments[:aria]&.delete(:label)
60
+
61
+ Primer::BaseComponent.new(**system_arguments)
62
+ }
63
+
64
+ # @example Default
65
+ # <%= render(Primer::Beta::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-1", list_id: "fruits-popup-1", position: :relative)) do |c| %>
66
+ # <% c.label(classes:"").with_content("Fruits") %>
67
+ # <% c.input(type: :text) %>
68
+ # <% end %>
69
+ #
70
+ # @example With `aria-label`
71
+ # <%= render(Primer::Beta::AutoComplete.new("aria-label": "Fruits", src: "/auto_complete", input_id: "fruits-input-2", list_id: "fruits-popup-2", position: :relative)) do |c| %>
72
+ # <% c.input(type: :text) %>
73
+ # <% end %>
74
+ #
75
+ # @example With `aria-labelledby`
76
+ # <%= render(Primer::HeadingComponent.new(tag: :h2, id: "search-1")) { "Search" } %>
77
+ # <%= render(Primer::Beta::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-3", list_id: "fruits-popup-2", position: :relative)) do |c| %>
78
+ # <% c.input("aria-labelledby": "search-1") %>
79
+ # <% end %>
80
+ #
81
+ # @example With custom classes for the results
82
+ # <%= render(Primer::Beta::AutoComplete.new(src: "/auto_complete", input_id: "fruits-input-4", list_id: "fruits-popup-3", position: :relative)) do |c| %>
83
+ # <% c.label(classes:"").with_content("Fruits") %>
84
+ # <% c.input(type: :text) %>
85
+ # <% c.results(classes: "custom-class") do %>
86
+ # <%= render(Primer::Beta::AutoComplete::Item.new(selected: true, value: "apple")) do |c| %>
87
+ # Apple
88
+ # <% end %>
89
+ # <%= render(Primer::Beta::AutoComplete::Item.new(value: "orange")) do |c| %>
90
+ # Orange
91
+ # <% end %>
92
+ # <% end %>
93
+ # <% end %>
94
+ #
95
+ # @example With Icon
96
+ # <%= render(Primer::Beta::AutoComplete.new(src: "/auto_complete", list_id: "fruits-popup-4", input_id: "fruits-input-4", position: :relative)) do |c| %>
97
+ # <% c.label(classes:"").with_content("Fruits") %>
98
+ # <% c.input(type: :text) %>
99
+ # <% c.icon(icon: :search) %>
100
+ # <% end %>
101
+ #
102
+ # @param src [String] The route to query.
103
+ # @param input_id [String] Id of the input element.
104
+ # @param list_id [String] Id of the list element.
105
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
106
+ def initialize(src:, list_id:, input_id:, **system_arguments)
107
+ @list_id = list_id
108
+ @input_id = input_id
109
+ @aria_label = aria("label", system_arguments)
110
+
111
+ system_arguments.delete(:"aria-label") && system_arguments[:aria]&.delete(:label)
112
+
113
+ @system_arguments = system_arguments
114
+ @system_arguments[:tag] = "auto-complete"
115
+ @system_arguments[:src] = src
116
+ @system_arguments[:for] = list_id
117
+ end
118
+
119
+ # add `results` without needing to explicitly call it in the view
120
+ def before_render
121
+ raise ArgumentError, "Missing `input` slot" if input.blank?
122
+ raise ArgumentError, "Accessible label is required." if label.blank? && input.missing_label?
123
+
124
+ results(classes: "") unless results
125
+ end
126
+
127
+ # This component is part of `Primer::Beta::AutoCompleteComponent` and should not be
128
+ # used as a standalone component.
129
+ class Input < Primer::Component
130
+ DEFAULT_TYPE = :text
131
+ TYPE_OPTIONS = [DEFAULT_TYPE, :search].freeze
132
+
133
+ # @param type [Symbol] <%= one_of(Primer::Beta::AutoComplete::Input::TYPE_OPTIONS) %>
134
+ # @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
135
+ def initialize(type: DEFAULT_TYPE, **system_arguments)
136
+ @system_arguments = system_arguments
137
+ @system_arguments[:tag] = :input
138
+
139
+ @aria_label = system_arguments[:"aria-label"]
140
+ @aria_labelledby = system_arguments[:"aria-labelledby"] || system_arguments.dig(:aria, :labelledby)
141
+
142
+ @system_arguments[:type] = fetch_or_fallback(TYPE_OPTIONS, type, DEFAULT_TYPE)
143
+ @system_arguments[:classes] = class_names(
144
+ "form-control",
145
+ system_arguments[:classes]
146
+ )
147
+ end
148
+
149
+ def missing_label?
150
+ @aria_label.blank? && @aria_labelledby.blank?
151
+ end
152
+
153
+ def call
154
+ render(Primer::BaseComponent.new(**@system_arguments))
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end