primer_view_components 0.0.44 → 0.0.48
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +187 -0
- data/app/components/primer/avatar_stack_component.rb +9 -3
- data/app/components/primer/base_component.rb +52 -23
- data/app/components/primer/beta/auto_complete.rb +159 -0
- data/app/components/primer/beta/auto_complete/auto_complete.d.ts +1 -0
- data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.html.erb +0 -0
- data/app/components/primer/beta/auto_complete/auto_complete.js +1 -0
- data/app/components/primer/{auto_complete → beta/auto_complete}/auto_complete.ts +0 -0
- data/app/components/primer/beta/auto_complete/item.rb +44 -0
- data/app/components/primer/beta/avatar.rb +77 -0
- data/app/components/primer/border_box_component.rb +3 -0
- data/app/components/primer/clipboard_copy.rb +25 -7
- data/app/components/primer/component.rb +9 -1
- data/app/components/primer/details_component.rb +12 -8
- data/app/components/primer/image_crop.rb +1 -1
- data/app/components/primer/markdown.rb +9 -9
- data/app/components/primer/menu_component.rb +7 -3
- data/app/components/primer/navigation/tab_component.rb +19 -5
- data/app/components/primer/popover_component.rb +6 -3
- data/app/components/primer/primer.d.ts +1 -1
- data/app/components/primer/primer.js +1 -1
- data/app/components/primer/primer.ts +1 -1
- data/app/components/primer/tab_nav_component.rb +8 -6
- data/app/components/primer/timeline_item_component.rb +2 -2
- data/app/components/primer/tooltip.rb +1 -1
- data/app/components/primer/truncate.rb +5 -0
- data/app/components/primer/underline_nav_component.rb +12 -6
- data/{app/lib → lib}/primer/classify.rb +16 -33
- data/{app/lib → lib}/primer/classify/cache.rb +6 -40
- data/{app/lib → lib}/primer/classify/flex.rb +0 -0
- data/{app/lib → lib}/primer/classify/functional_background_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/functional_border_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/functional_colors.rb +0 -0
- data/{app/lib → lib}/primer/classify/functional_text_colors.rb +2 -0
- data/{app/lib → lib}/primer/classify/grid.rb +0 -0
- data/lib/primer/classify/utilities.rb +148 -0
- data/lib/primer/classify/utilities.yml +1271 -0
- data/lib/primer/view_components.rb +1 -0
- data/lib/primer/view_components/linters/argument_mappers/system_arguments.rb +5 -4
- data/lib/primer/view_components/linters/button_component_migration_counter.rb +9 -5
- data/lib/primer/view_components/linters/helpers.rb +132 -17
- data/lib/primer/view_components/statuses.rb +14 -0
- data/lib/primer/view_components/version.rb +1 -1
- data/lib/rubocop/config/default.yml +12 -0
- data/lib/rubocop/cop/primer.rb +4 -0
- data/lib/rubocop/cop/primer/no_tag_memoize.rb +42 -0
- data/lib/rubocop/cop/primer/system_argument_instead_of_class.rb +75 -0
- data/lib/tasks/docs.rake +72 -18
- data/lib/tasks/utilities.rake +105 -0
- data/lib/yard/docs_helper.rb +1 -1
- data/static/statuses.json +4 -4
- metadata +30 -21
- data/app/components/primer/auto_complete.rb +0 -156
- data/app/components/primer/auto_complete/item.rb +0 -42
- data/app/components/primer/avatar_component.rb +0 -75
- data/app/lib/primer/classify/spacing.rb +0 -63
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 2c751bc60362c19e97ba5fbe22227e19186efa799862932a6f7b8541ad8e1eaa
|
4
|
+
data.tar.gz: 4efd584159e4883f8bcc72954fff356c753b0b8980056ee0c58b7a3bd650cb90
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c6169f90241d046f9cee4faf1fb971cac34360c8ebb116e2c2e39fdd0aeff5e8cca17e899bdd8a97f94ebefa4c3705d6929b0978a96f0264dcab3fa96342faaf
|
7
|
+
data.tar.gz: 8576857a521647f43ccb3fe413b0e24b5d65a8c06e9036dd3035b37d8fb5989aa43a7ac2d33863f5faa022c099c6a8386d30de8b764e19cf93b9dcb207fd4eef
|
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,190 @@
|
|
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.48
|
34
|
+
|
35
|
+
### Breaking changes
|
36
|
+
|
37
|
+
* Ensure panels in `Navigation::Tab` have a label.
|
38
|
+
|
39
|
+
*Kate Higa*
|
40
|
+
|
41
|
+
### Misc
|
42
|
+
|
43
|
+
* Expose custom cops and default config for erblint.
|
44
|
+
|
45
|
+
*Manuel Puyol*
|
46
|
+
|
47
|
+
* Fix double constant assign.
|
48
|
+
|
49
|
+
*Manuel Puyol*
|
50
|
+
|
51
|
+
## 0.0.47
|
52
|
+
|
53
|
+
### Breaking changes
|
54
|
+
|
55
|
+
* Restrict tag for `Popover` to `:div` and `Popover` heading slot to headings.
|
56
|
+
|
57
|
+
*Kate Higa*
|
58
|
+
|
59
|
+
* Renames:
|
60
|
+
* `Primer::AutoComplete` to `Primer::Beta::AutoComplete`
|
61
|
+
* `Primer::AutoComplete::Item` to `Primer::Beta::AutoComplete::Item`
|
62
|
+
* `Primer::AvatarComponent` to `Primer::Beta::Avatar`
|
63
|
+
|
64
|
+
*Manuel Puyol*
|
65
|
+
|
66
|
+
### Misc
|
67
|
+
|
68
|
+
* Update `doc_examples_axe_test` to exclude non-standalone components and fix `Markdown` example.
|
69
|
+
|
70
|
+
*Kate Higa*
|
71
|
+
|
72
|
+
* Update `DetailsComponent` examples.
|
73
|
+
|
74
|
+
*Manuel Puyol*
|
75
|
+
|
76
|
+
* Add linter to suggest system arguments instead of classes.
|
77
|
+
|
78
|
+
*Manuel Puyol*
|
79
|
+
|
80
|
+
* Update component generator to create components in the right status module.
|
81
|
+
|
82
|
+
*Manuel Puyol*
|
83
|
+
|
84
|
+
* Add example for truncating HTML to `Truncate`.
|
85
|
+
|
86
|
+
*Joel Hawksley*
|
87
|
+
|
88
|
+
* Update docs generation to point to the correct file sources.
|
89
|
+
|
90
|
+
*Manuel Puyol*
|
91
|
+
|
92
|
+
* Add ENV flag to dump linter data into a file.
|
93
|
+
|
94
|
+
*Manuel Puyol*
|
95
|
+
|
96
|
+
## 0.0.46
|
97
|
+
|
98
|
+
### Updates
|
99
|
+
|
100
|
+
* Default to matching `name` and `id` of `input`.
|
101
|
+
|
102
|
+
*Kate Higa*
|
103
|
+
|
104
|
+
* Restrict usage of padding system arguments on BorderBox, recommending use of `padding` density instead.
|
105
|
+
|
106
|
+
*Joel Hawksley*
|
107
|
+
|
108
|
+
### Breaking changes
|
109
|
+
|
110
|
+
* Restrict `TabNav`and `Tab` tags.
|
111
|
+
|
112
|
+
*Kate Higa*
|
113
|
+
|
114
|
+
* Restrict `AvatarStack` body slot tag and `ImageCrop` spinner tag.
|
115
|
+
|
116
|
+
*Kate Higa*
|
117
|
+
|
118
|
+
* Restrict `Details` body slot tags and `UnderlineNav` body slot tags.
|
119
|
+
|
120
|
+
*Kate Higa*
|
121
|
+
|
122
|
+
* Move Primer::Classify from `app/lib/` to `lib/`. This requires an extra `require "primer/classify"` statement for anywhere Classify is needed.
|
123
|
+
|
124
|
+
*Manuel Puyol, Jon Rohan*
|
125
|
+
|
126
|
+
* Restrict `Menu` heading slot tags to heading tags and require `tag` argument.
|
127
|
+
|
128
|
+
*Kate Higa*
|
129
|
+
|
130
|
+
* 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.
|
131
|
+
|
132
|
+
*Jon Rohan*
|
133
|
+
|
134
|
+
### Misc
|
135
|
+
|
136
|
+
* Update contributing guidelines with release instructions.
|
137
|
+
|
138
|
+
*Kate Higa*
|
139
|
+
|
140
|
+
* Prevent flexible tag syntax with rubocop rule.
|
141
|
+
|
142
|
+
*Kate Higa*
|
143
|
+
|
144
|
+
* Update linter autocorrection to use `""` instead of `true` for boolean attributes.
|
145
|
+
|
146
|
+
*Manuel Puyol*
|
147
|
+
|
148
|
+
* Update Storybook version.
|
149
|
+
|
150
|
+
*Manuel Puyol*
|
151
|
+
|
152
|
+
* Added a changelog authoring guide to `CHANGELOG.md`.
|
153
|
+
|
154
|
+
*Amélia Chavot*
|
155
|
+
|
156
|
+
## 0.0.45
|
157
|
+
|
158
|
+
### Updates
|
159
|
+
|
160
|
+
* Allow copying from elements using `for` in `ClipboardCopy`.
|
161
|
+
|
162
|
+
*Manuel Puyol*
|
163
|
+
|
164
|
+
### Breaking changes
|
165
|
+
|
166
|
+
* Remove `label` argument in favor of `aria-label` in `ClipboardCopy`.
|
167
|
+
|
168
|
+
*Manuel Puyol*
|
169
|
+
|
170
|
+
### Misc
|
171
|
+
|
172
|
+
* Add autocorrect for button linters.
|
173
|
+
|
174
|
+
*Manuel Puyol*
|
175
|
+
|
176
|
+
* Unify contributing guidelines.
|
177
|
+
|
178
|
+
*Kate Higa*
|
179
|
+
|
180
|
+
* Rerun flaky system tests.
|
181
|
+
|
182
|
+
*Manuel Puyol*
|
183
|
+
|
184
|
+
* Check if selector is a classify class in Utilities.
|
185
|
+
|
186
|
+
*Jon Rohan*
|
187
|
+
|
5
188
|
## 0.0.44
|
6
189
|
|
7
190
|
### Updates
|
@@ -30,6 +213,10 @@
|
|
30
213
|
|
31
214
|
### Misc
|
32
215
|
|
216
|
+
* Replace Classify::Spacing class with pre-generated mappings.
|
217
|
+
|
218
|
+
*Jon Rohan*
|
219
|
+
|
33
220
|
* Add linter suggestions for `Button` component.
|
34
221
|
|
35
222
|
*Manuel Puyol*
|
@@ -10,10 +10,13 @@ module Primer
|
|
10
10
|
|
11
11
|
DEFAULT_TAG = :div
|
12
12
|
TAG_OPTIONS = [DEFAULT_TAG, :span].freeze
|
13
|
+
|
14
|
+
DEFAULT_BODY_TAG = :div
|
15
|
+
BODY_TAG_OPTIONS = [DEFAULT_BODY_TAG, :span].freeze
|
13
16
|
# Required list of stacked avatars.
|
14
17
|
#
|
15
|
-
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::
|
16
|
-
renders_many :avatars, Primer::
|
18
|
+
# @param kwargs [Hash] The same arguments as <%= link_to_component(Primer::Beta::Avatar) %>.
|
19
|
+
renders_many :avatars, "Primer::Beta::Avatar"
|
17
20
|
|
18
21
|
# @example Default
|
19
22
|
# <%= render(Primer::AvatarStackComponent.new) do |c| %>
|
@@ -40,6 +43,8 @@ module Primer
|
|
40
43
|
# @param align [Symbol] <%= one_of(Primer::AvatarStackComponent::ALIGN_OPTIONS) %>
|
41
44
|
# @param tooltipped [Boolean] Whether to add a tooltip to the stack or not.
|
42
45
|
# @param body_arguments [Hash] Parameters to add to the Body. If `tooltipped` is set, has the same arguments as <%= link_to_component(Primer::Tooltip) %>.
|
46
|
+
# The default tag is <%= pretty_value(Primer::AvatarStackComponent::DEFAULT_BODY_TAG) %> but can be changed using `tag:`
|
47
|
+
# to <%= one_of(Primer::AvatarStackComponent::BODY_TAG_OPTIONS, lower: true) %>
|
43
48
|
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
|
44
49
|
def initialize(tag: DEFAULT_TAG, align: ALIGN_DEFAULT, tooltipped: false, body_arguments: {}, **system_arguments)
|
45
50
|
@align = fetch_or_fallback(ALIGN_OPTIONS, align, ALIGN_DEFAULT)
|
@@ -47,7 +52,8 @@ module Primer
|
|
47
52
|
@tooltipped = tooltipped
|
48
53
|
@body_arguments = body_arguments
|
49
54
|
|
50
|
-
@body_arguments[:tag]
|
55
|
+
body_tag = @body_arguments[:tag] || DEFAULT_BODY_TAG
|
56
|
+
@body_arguments[:tag] = fetch_or_fallback(BODY_TAG_OPTIONS, body_tag, DEFAULT_BODY_TAG)
|
51
57
|
@body_arguments[:classes] = class_names(
|
52
58
|
"AvatarStack-body",
|
53
59
|
@body_arguments[:classes]
|
@@ -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(
|
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::
|
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,20 +93,20 @@ module Primer
|
|
91
93
|
#
|
92
94
|
# | Name | Type | Description |
|
93
95
|
# | :- | :- | :- |
|
94
|
-
# | `display` | Symbol | <%= one_of(
|
96
|
+
# | `display` | Symbol | <%= one_of(Primer::Classify::Utilities.mappings(:display)) %> |
|
95
97
|
# | `height` | Symbol | <%= one_of([:fit]) %> |
|
96
|
-
# | `hide` | Symbol | Hide the element at a specific breakpoint. <%= one_of(
|
97
|
-
# | `
|
98
|
-
# | `vertical_align` | Symbol | <%= one_of(
|
98
|
+
# | `hide` | Symbol | Hide the element at a specific breakpoint. <%= one_of(Primer::Classify::Utilities.mappings(:hide)) %> |
|
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
|
#
|
102
104
|
# | Name | Type | Description |
|
103
105
|
# | :- | :- | :- |
|
104
106
|
# | `bottom` | Boolean | If `false`, sets `bottom: 0`. |
|
105
|
-
# | `float` | Symbol | <%= one_of(
|
107
|
+
# | `float` | Symbol | <%= one_of(Primer::Classify::Utilities.mappings(:float)) %> |
|
106
108
|
# | `left` | Boolean | If `false`, sets `left: 0`. |
|
107
|
-
# | `position` | Symbol | <%= one_of(
|
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
|
#
|
@@ -112,20 +114,20 @@ module Primer
|
|
112
114
|
#
|
113
115
|
# | Name | Type | Description |
|
114
116
|
# | :- | :- | :- |
|
115
|
-
# | `m` | Integer | Margin. <%= one_of(Primer::Classify::
|
116
|
-
# | `mb` | Integer | Margin bottom. <%= one_of(Primer::Classify::
|
117
|
-
# | `ml` | Integer | Margin left. <%= one_of(Primer::Classify::
|
118
|
-
# | `mr` | Integer | Margin right. <%= one_of(Primer::Classify::
|
119
|
-
# | `mt` | Integer | Margin top. <%= one_of(Primer::Classify::
|
120
|
-
# | `mx` | Integer | Horizontal margins. <%= one_of(Primer::Classify::
|
121
|
-
# | `my` | Integer | Vertical margins. <%= one_of(Primer::Classify::
|
122
|
-
# | `p` | Integer | Padding. <%= one_of(Primer::Classify::
|
123
|
-
# | `pb` | Integer | Padding bottom. <%= one_of(Primer::Classify::
|
124
|
-
# | `pl` | Integer | Padding left. <%= one_of(Primer::Classify::
|
125
|
-
# | `pr` | Integer | Padding right. <%= one_of(Primer::Classify::
|
126
|
-
# | `pt` | Integer | Padding left. <%= one_of(Primer::Classify::
|
127
|
-
# | `px` | Integer | Horizontal padding. <%= one_of(Primer::Classify::
|
128
|
-
# | `py` | Integer | Vertical padding. <%= one_of(Primer::Classify::
|
117
|
+
# | `m` | Integer | Margin. <%= one_of(Primer::Classify::Utilities.mappings(:m)) %> |
|
118
|
+
# | `mb` | Integer | Margin bottom. <%= one_of(Primer::Classify::Utilities.mappings(:mb)) %> |
|
119
|
+
# | `ml` | Integer | Margin left. <%= one_of(Primer::Classify::Utilities.mappings(:ml)) %> |
|
120
|
+
# | `mr` | Integer | Margin right. <%= one_of(Primer::Classify::Utilities.mappings(:mr)) %> |
|
121
|
+
# | `mt` | Integer | Margin top. <%= one_of(Primer::Classify::Utilities.mappings(:mt)) %> |
|
122
|
+
# | `mx` | Integer | Horizontal margins. <%= one_of(Primer::Classify::Utilities.mappings(:mx)) %> |
|
123
|
+
# | `my` | Integer | Vertical margins. <%= one_of(Primer::Classify::Utilities.mappings(:my)) %> |
|
124
|
+
# | `p` | Integer | Padding. <%= one_of(Primer::Classify::Utilities.mappings(:p)) %> |
|
125
|
+
# | `pb` | Integer | Padding bottom. <%= one_of(Primer::Classify::Utilities.mappings(:pb)) %> |
|
126
|
+
# | `pl` | Integer | Padding left. <%= one_of(Primer::Classify::Utilities.mappings(:pl)) %> |
|
127
|
+
# | `pr` | Integer | Padding right. <%= one_of(Primer::Classify::Utilities.mappings(:pr)) %> |
|
128
|
+
# | `pt` | Integer | Padding left. <%= one_of(Primer::Classify::Utilities.mappings(:pt)) %> |
|
129
|
+
# | `px` | Integer | Horizontal padding. <%= one_of(Primer::Classify::Utilities.mappings(:px)) %> |
|
130
|
+
# | `py` | Integer | Vertical padding. <%= one_of(Primer::Classify::Utilities.mappings(:py)) %> |
|
129
131
|
#
|
130
132
|
# ## Typography
|
131
133
|
#
|
@@ -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.
|
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
|