primer_view_components 0.36.5 → 0.38.0

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 (60) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +32 -0
  3. data/app/assets/javascripts/components/primer/beta/details_toggle_element.d.ts +39 -0
  4. data/app/assets/javascripts/components/primer/primer.d.ts +1 -0
  5. data/app/assets/javascripts/primer_view_components.js +1 -1
  6. data/app/assets/javascripts/primer_view_components.js.map +1 -1
  7. data/app/assets/styles/primer_view_components.css +1 -1
  8. data/app/assets/styles/primer_view_components.css.map +1 -1
  9. data/app/components/primer/alpha/action_menu/action_menu_element.js +13 -3
  10. data/app/components/primer/alpha/action_menu/action_menu_element.ts +14 -2
  11. data/app/components/primer/alpha/dialog.css +1 -1
  12. data/app/components/primer/alpha/dialog.css.json +0 -1
  13. data/app/components/primer/alpha/dialog.css.map +1 -1
  14. data/app/components/primer/alpha/dialog.pcss +1 -4
  15. data/app/components/primer/alpha/dropdown.rb +8 -0
  16. data/app/components/primer/alpha/form_control.rb +47 -7
  17. data/app/components/primer/alpha/toggle_switch.html.erb +1 -1
  18. data/app/components/primer/alpha/toggle_switch.js +1 -0
  19. data/app/components/primer/alpha/toggle_switch.rb +14 -2
  20. data/app/components/primer/alpha/toggle_switch.ts +1 -0
  21. data/app/components/primer/beta/auto_complete/item.rb +2 -3
  22. data/app/components/primer/beta/auto_complete/no_result_item.rb +21 -0
  23. data/app/components/primer/beta/details.html.erb +8 -6
  24. data/app/components/primer/beta/details.rb +42 -0
  25. data/app/components/primer/beta/details_toggle_element.d.ts +39 -0
  26. data/app/components/primer/beta/details_toggle_element.js +60 -0
  27. data/app/components/primer/beta/details_toggle_element.ts +57 -0
  28. data/app/components/primer/beta/markdown.rb +1 -0
  29. data/app/components/primer/beta/nav_list.rb +1 -1
  30. data/app/components/primer/dialog_helper.js +3 -0
  31. data/app/components/primer/dialog_helper.ts +3 -0
  32. data/app/components/primer/primer.d.ts +1 -0
  33. data/app/components/primer/primer.js +1 -0
  34. data/app/components/primer/primer.ts +1 -0
  35. data/app/lib/primer/forms/action_menu.html.erb +1 -1
  36. data/app/lib/primer/forms/action_menu.rb +5 -0
  37. data/lib/primer/view_components/version.rb +2 -2
  38. data/lib/primer/yard/component_manifest.rb +11 -10
  39. data/lib/primer/yard/lookbook_pages_backend.rb +8 -0
  40. data/previews/primer/alpha/action_menu_preview/multiple_select_form.html.erb +1 -1
  41. data/previews/primer/alpha/form_control_preview/playground.html.erb +14 -6
  42. data/previews/primer/alpha/overlay_preview.rb +0 -31
  43. data/previews/primer/alpha/select_preview.rb +6 -6
  44. data/previews/primer/alpha/text_field_preview.rb +22 -22
  45. data/previews/primer/alpha/toggle_switch_preview.rb +4 -0
  46. data/previews/primer/beta/auto_complete_preview.rb +6 -0
  47. data/previews/primer/beta/details_preview.rb +12 -0
  48. data/previews/primer/beta/markdown_preview.rb +9 -9
  49. data/previews/primer/beta/nav_list_preview/truncate.html.erb +25 -0
  50. data/previews/primer/beta/nav_list_preview.rb +4 -24
  51. data/previews/primer/beta/relative_time_preview.rb +20 -10
  52. data/static/arguments.json +23 -0
  53. data/static/audited_at.json +1 -0
  54. data/static/constants.json +8 -0
  55. data/static/info_arch.json +213 -85
  56. data/static/previews.json +42 -67
  57. data/static/statuses.json +1 -0
  58. metadata +8 -4
  59. data/previews/primer/alpha/overlay_preview/in_an_action_menu.html.erb +0 -13
  60. data/previews/primer/alpha/overlay_preview/overlay_with_header_filter.html.erb +0 -16
@@ -0,0 +1,57 @@
1
+ import {controller, target} from '@github/catalyst'
2
+
3
+ /**
4
+ * A companion Catalyst element for the Details view component. This element
5
+ * ensures the <details> and <summary> elements markup is properly accessible by
6
+ * updating the aria-label and aria-expanded attributes on click.
7
+ *
8
+ * aria-label values default to "Expand" and "Collapse". To override those
9
+ * values, use the `data-aria-label-open` and `data-aria-label-closed`
10
+ * attributes on the summary target.
11
+ *
12
+ * @example
13
+ * ```html
14
+ * <details-toggle>
15
+ * <details open=true data-target="details-toggle.detailsTarget">
16
+ * <summary
17
+ * aria-expanded="true"
18
+ * aria-label="Collapse me"
19
+ * data-target="details-toggle.summaryTarget"
20
+ * data-action="click:details-toggle#toggle"
21
+ * data-aria-label-closed="Expand me"
22
+ * data-aria-label-open="Collapse me"
23
+ * >
24
+ * Click me
25
+ * </summary>
26
+ * <div>Contents</div>
27
+ * </details>
28
+ * </details-toggle>
29
+ * ```
30
+ */
31
+
32
+ @controller
33
+ class DetailsToggleElement extends HTMLElement {
34
+ @target detailsTarget!: HTMLDetailsElement
35
+ @target summaryTarget!: HTMLElement
36
+
37
+ toggle() {
38
+ const detailsIsOpen = this.detailsTarget.hasAttribute('open')
39
+ if (detailsIsOpen) {
40
+ const ariaLabelClosed = this.summaryTarget.getAttribute('data-aria-label-closed') || 'Expand'
41
+ this.summaryTarget.setAttribute('aria-label', ariaLabelClosed)
42
+ this.summaryTarget.setAttribute('aria-expanded', 'false')
43
+ } else {
44
+ const ariaLabelOpen = this.summaryTarget.getAttribute('data-aria-label-open') || 'Collapse'
45
+ this.summaryTarget.setAttribute('aria-label', ariaLabelOpen)
46
+ this.summaryTarget.setAttribute('aria-expanded', 'true')
47
+ }
48
+ }
49
+ }
50
+
51
+ declare global {
52
+ interface Window {
53
+ DetailsToggleElement: typeof DetailsToggleElement
54
+ }
55
+ }
56
+
57
+ window.DetailsToggleElement = DetailsToggleElement
@@ -3,6 +3,7 @@
3
3
  module Primer
4
4
  module Beta
5
5
  # Use `Markdown` to wrap markdown content.
6
+ # @accessibility This component is purely presentational. Consumers should handle accessibility expectations, such as ensuring that an overflowing, scrollable code block or table is keyboard accessible.
6
7
  class Markdown < Primer::Component
7
8
  status :beta
8
9
 
@@ -168,7 +168,7 @@ module Primer
168
168
  end
169
169
  end
170
170
 
171
- # Lists that contain top-level items (i.e. items outside of a group) should be wrapped in a <ul>
171
+ # Lists that contain top-level items (i.e. items outside of a group) should be wrapped in a `<ul>`
172
172
  def render_outer_list?
173
173
  items.any? { |item| !group?(item) }
174
174
  end
@@ -102,6 +102,9 @@ export class DialogHelperElement extends HTMLElement {
102
102
  // The click target _must_ be the dialog element itself, and not elements underneath or inside.
103
103
  if (target !== dialog || !dialog?.open)
104
104
  return;
105
+ // If the dialog contains a form, do not close the dialog when clicking outside of the dialog
106
+ if (dialog.querySelector('form'))
107
+ return;
105
108
  const rect = dialog.getBoundingClientRect();
106
109
  const clickWasInsideDialog = rect.top <= event.clientY &&
107
110
  event.clientY <= rect.top + rect.height &&
@@ -111,6 +111,9 @@ export class DialogHelperElement extends HTMLElement {
111
111
  // The click target _must_ be the dialog element itself, and not elements underneath or inside.
112
112
  if (target !== dialog || !dialog?.open) return
113
113
 
114
+ // If the dialog contains a form, do not close the dialog when clicking outside of the dialog
115
+ if (dialog.querySelector('form')) return
116
+
114
117
  const rect = dialog.getBoundingClientRect()
115
118
  const clickWasInsideDialog =
116
119
  rect.top <= event.clientY &&
@@ -25,3 +25,4 @@ import '../../lib/primer/forms/primer_text_field';
25
25
  import '../../lib/primer/forms/toggle_switch_input';
26
26
  import './alpha/action_menu/action_menu_element';
27
27
  import './alpha/select_panel_element';
28
+ import './beta/details_toggle_element';
@@ -25,3 +25,4 @@ import '../../lib/primer/forms/primer_text_field';
25
25
  import '../../lib/primer/forms/toggle_switch_input';
26
26
  import './alpha/action_menu/action_menu_element';
27
27
  import './alpha/select_panel_element';
28
+ import './beta/details_toggle_element';
@@ -25,3 +25,4 @@ import '../../lib/primer/forms/primer_text_field'
25
25
  import '../../lib/primer/forms/toggle_switch_input'
26
26
  import './alpha/action_menu/action_menu_element'
27
27
  import './alpha/select_panel_element'
28
+ import './beta/details_toggle_element'
@@ -1,6 +1,6 @@
1
1
  <%= render(FormControl.new(input: @input)) do %>
2
2
  <%= render(Primer::Alpha::ActionMenu.new(**@input.input_arguments)) do |menu| %>
3
- <% menu.with_show_button { "Select..." } %>
3
+ <% menu.with_show_button("aria-describedby": @label_id) { "Select..." } %>
4
4
  <% @input.block.call(menu) if @input.block %>
5
5
  <% end %>
6
6
  <% end %>
@@ -8,6 +8,7 @@ module Primer
8
8
 
9
9
  def initialize(input:)
10
10
  @input = input
11
+ @input.label_arguments[:id] = label_id
11
12
 
12
13
  @input.input_arguments[:form_arguments] = {
13
14
  name: @input.name,
@@ -20,6 +21,10 @@ module Primer
20
21
  @input.input_arguments[:dynamic_label] = true
21
22
  end
22
23
  end
24
+
25
+ def label_id
26
+ @label_id ||= "label-#{@input.base_id}"
27
+ end
23
28
  end
24
29
  end
25
30
  end
@@ -5,8 +5,8 @@ module Primer
5
5
  module ViewComponents
6
6
  module VERSION
7
7
  MAJOR = 0
8
- MINOR = 36
9
- PATCH = 5
8
+ MINOR = 38
9
+ PATCH = 0
10
10
 
11
11
  STRING = [MAJOR, MINOR, PATCH].join(".")
12
12
  end
@@ -86,16 +86,17 @@ module Primer
86
86
  Primer::Alpha::ActionList::Item => { examples: false },
87
87
 
88
88
  # Forms
89
- Primer::Alpha::TextField => { form_component: true },
90
- Primer::Alpha::TextArea => { form_component: true, published: false },
91
- Primer::Alpha::Select => { form_component: true, published: false },
92
- Primer::Alpha::MultiInput => { form_component: true, js: true, published: false },
93
- Primer::Alpha::RadioButton => { form_component: true, published: false },
94
- Primer::Alpha::RadioButtonGroup => { form_component: true, published: false },
95
- Primer::Alpha::CheckBox => { form_component: true, published: false },
96
- Primer::Alpha::CheckBoxGroup => { form_component: true, published: false },
97
- Primer::Alpha::SubmitButton => { form_component: true, published: false },
98
- Primer::Alpha::FormButton => { form_component: true, published: false }
89
+ Primer::Alpha::FormControl => { form_component: true },
90
+ Primer::Alpha::TextField => { form_component: true, js: true },
91
+ Primer::Alpha::TextArea => { form_component: true },
92
+ Primer::Alpha::Select => { form_component: true },
93
+ Primer::Alpha::MultiInput => { form_component: true, js: true },
94
+ Primer::Alpha::RadioButton => { form_component: true },
95
+ Primer::Alpha::RadioButtonGroup => { form_component: true },
96
+ Primer::Alpha::CheckBox => { form_component: true },
97
+ Primer::Alpha::CheckBoxGroup => { form_component: true },
98
+ Primer::Alpha::SubmitButton => { form_component: true },
99
+ Primer::Alpha::FormButton => { form_component: true }
99
100
  }.freeze
100
101
 
101
102
  include Enumerable
@@ -165,6 +165,12 @@ module Primer
165
165
  class LookbookPagesBackend < Backend
166
166
  attr_reader :registry, :manifest
167
167
 
168
+ IGNORED_COMPONENTS = [
169
+ Primer::Alpha::FormControl
170
+ ]
171
+
172
+ IGNORED_COMPONENTS.freeze
173
+
168
174
  def initialize(registry, manifest)
169
175
  @registry = registry
170
176
  @manifest = manifest
@@ -172,6 +178,8 @@ module Primer
172
178
 
173
179
  def generate
174
180
  each_component do |component_ref|
181
+ next if IGNORED_COMPONENTS.include?(component_ref.klass)
182
+
175
183
  page_for(component_ref).generate
176
184
  end
177
185
  generate_system_args_docs
@@ -3,7 +3,7 @@
3
3
  <% menu.with_show_button { "Strategy" } %>
4
4
  <% menu.with_item(label: "Fast forward", data: { value: "fast_forward" }) %>
5
5
  <% menu.with_item(label: "Recursive", data: { value: "recursive" }) %>
6
- <% menu.with_item(label: "Ours", data: { value: "ours" }) %>
6
+ <% menu.with_item(label: "Ours", data: { value: "ours" }, active: true) %>
7
7
  <% menu.with_item(label: "Resolve") %>
8
8
  <% end %>
9
9
  <hr>
@@ -1,9 +1,17 @@
1
- <%= render(Primer::Alpha::FormControl.new(**system_arguments)) do |component| %>
2
- <% component.with_input do |input_arguments| %>
3
- <%= render(Primer::Alpha::SegmentedControl.new("aria-label": "Best character", **input_arguments)) do |seg| %>
4
- <% seg.with_item(label: "Han Solo", selected: true) %>
5
- <% seg.with_item(label: "Luke Skywalker") %>
6
- <% seg.with_item(label: "Leia Organa") %>
1
+ <div>
2
+ <strong>NOTE: </strong>The <pre style="display: inline">FormControl </pre>component cannot automatically connect
3
+ the label to the provided input. Please take care to pass the <pre style="display: inline">for:</pre> attribute
4
+ to <pre style="display: inline">FormControl</pre>, eg:
5
+ <pre style="display: inline">Primer::Alpha::FormControl.new(label_arguments: { for: "field-name-or-id" })</pre>.
6
+ - Your friendly neighborhood accessibility team.
7
+ </div>
8
+
9
+ <br>
10
+
11
+ <%= form_with(url: "/foo") do |f| %>
12
+ <%= render(Primer::Alpha::FormControl.new(**system_arguments, label_arguments: { for: "bar" })) do |component| %>
13
+ <% component.with_input do |input_arguments| %>
14
+ <%= f.text_field(:bar, **input_arguments) %>
7
15
  <% end %>
8
16
  <% end %>
9
17
  <% end %>
@@ -164,37 +164,6 @@ module Primer
164
164
  })
165
165
  end
166
166
 
167
- # @label In an ActionMenu
168
- def in_an_action_menu
169
- render_with_template(locals: {})
170
- end
171
-
172
- # @label Dialog with header and footer
173
- #
174
- def dialog_with_header_footer
175
- render(Primer::Alpha::Overlay.new(title: "Dialog", role: :dialog, size: :large, padding: :condensed)) do |d|
176
- d.with_header(title: "Large Dialog Header", divider: true)
177
- d.with_show_button { "Show Overlay" }
178
- d.with_footer { "Large Dialog Footer" }
179
- d.with_body { "This is a long body for the overlay dialog. <br>".html_safe * 20 }
180
- end
181
- end
182
-
183
- def overlay_with_header_filter
184
- render_with_template(locals: {})
185
- end
186
-
187
- def overlay_with_header_subtitle
188
- render(Primer::Alpha::Overlay.new(title: "Dialog", role: :dialog, size: :large, padding: :condensed)) do |d|
189
- d.with_header(title: "Large Dialog Header", divider: true) do |h|
190
- h.with_subtitle {"A subtitle"}
191
- end
192
- d.with_show_button { "Show Overlay" }
193
- d.with_footer { "Large Dialog Footer" }
194
- d.with_body { "This is a long body for the overlay dialog. <br>".html_safe * 20 }
195
- end
196
- end
197
-
198
167
  def in_a_sticky_container
199
168
  render_with_template(locals: {})
200
169
  end
@@ -70,7 +70,7 @@ module Primer
70
70
  # @label With caption
71
71
  # @snapshot
72
72
  def with_caption
73
- render(Primer::Alpha::Select.new(caption: "With a caption", name: "my-select-list", label: "Favorite place to visit")) do |component|
73
+ render(Primer::Alpha::Select.new(caption: "With a caption", name: "my-select-list-1", label: "Favorite place to visit")) do |component|
74
74
  component.option(label: "Lopez Island", value: "lopez")
75
75
  component.option(label: "Shaw Island", value: "shaw")
76
76
  component.option(label: "Orcas Island", value: "orcas")
@@ -81,7 +81,7 @@ module Primer
81
81
  # @label Visually hidden label
82
82
  # @snapshot
83
83
  def visually_hide_label
84
- render(Primer::Alpha::Select.new(visually_hide_label: true, name: "my-select-list", label: "Favorite place to visit")) do |component|
84
+ render(Primer::Alpha::Select.new(visually_hide_label: true, name: "my-select-list-2", label: "Favorite place to visit")) do |component|
85
85
  component.option(label: "Lopez Island", value: "lopez")
86
86
  component.option(label: "Shaw Island", value: "shaw")
87
87
  component.option(label: "Orcas Island", value: "orcas")
@@ -92,7 +92,7 @@ module Primer
92
92
  # @label Full width
93
93
  # @snapshot
94
94
  def full_width
95
- render(Primer::Alpha::Select.new(full_width: true, name: "my-select-list", label: "Favorite place to visit")) do |component|
95
+ render(Primer::Alpha::Select.new(full_width: true, name: "my-select-list-3", label: "Favorite place to visit")) do |component|
96
96
  component.option(label: "Lopez Island", value: "lopez")
97
97
  component.option(label: "Shaw Island", value: "shaw")
98
98
  component.option(label: "Orcas Island", value: "orcas")
@@ -103,7 +103,7 @@ module Primer
103
103
  # @label Not full width
104
104
  # @snapshot
105
105
  def not_full_width
106
- render(Primer::Alpha::Select.new(full_width: false, name: "my-select-list", label: "Favorite place to visit")) do |component|
106
+ render(Primer::Alpha::Select.new(full_width: false, name: "my-select-list-4", label: "Favorite place to visit")) do |component|
107
107
  component.option(label: "Lopez Island", value: "lopez")
108
108
  component.option(label: "Shaw Island", value: "shaw")
109
109
  component.option(label: "Orcas Island", value: "orcas")
@@ -114,7 +114,7 @@ module Primer
114
114
  # @label Disabled
115
115
  # @snapshot
116
116
  def disabled
117
- render(Primer::Alpha::Select.new(disabled: true, name: "my-select-list", label: "Favorite place to visit")) do |component|
117
+ render(Primer::Alpha::Select.new(disabled: true, name: "my-select-list-5", label: "Favorite place to visit")) do |component|
118
118
  component.option(label: "Lopez Island", value: "lopez")
119
119
  component.option(label: "Shaw Island", value: "shaw")
120
120
  component.option(label: "Orcas Island", value: "orcas")
@@ -125,7 +125,7 @@ module Primer
125
125
  # @label Invalid
126
126
  # @snapshot
127
127
  def invalid
128
- render(Primer::Alpha::Select.new(invalid: true, name: "my-select-list", label: "Favorite place to visit")) do |component|
128
+ render(Primer::Alpha::Select.new(invalid: true, name: "my-select-list-6", label: "Favorite place to visit")) do |component|
129
129
  component.option(label: "Lopez Island", value: "lopez")
130
130
  component.option(label: "Shaw Island", value: "shaw")
131
131
  component.option(label: "Orcas Island", value: "orcas")
@@ -115,122 +115,122 @@ module Primer
115
115
  # @label With caption
116
116
  # @snapshot
117
117
  def with_caption
118
- render(Primer::Alpha::TextField.new(caption: "With a caption", name: "my-text-field", label: "My text field"))
118
+ render(Primer::Alpha::TextField.new(caption: "With a caption", name: "my-text-field-1", label: "My text field"))
119
119
  end
120
120
 
121
121
  # @label Visually hidden label
122
122
  # @snapshot
123
123
  def visually_hide_label
124
- render(Primer::Alpha::TextField.new(visually_hide_label: true, name: "my-text-field", label: "My text field"))
124
+ render(Primer::Alpha::TextField.new(visually_hide_label: true, name: "my-text-field-2", label: "My text field"))
125
125
  end
126
126
 
127
127
  # @label Show clear button
128
128
  # @snapshot
129
129
  def show_clear_button
130
- render(Primer::Alpha::TextField.new(show_clear_button: true, name: "my-text-field", label: "My text field"))
130
+ render(Primer::Alpha::TextField.new(show_clear_button: true, name: "my-text-field-3", label: "My text field"))
131
131
  end
132
132
 
133
133
  # @label Full width
134
134
  # @snapshot
135
135
  def full_width
136
- render(Primer::Alpha::TextField.new(full_width: true, name: "my-text-field", label: "My text field"))
136
+ render(Primer::Alpha::TextField.new(full_width: true, name: "my-text-field-4", label: "My text field"))
137
137
  end
138
138
 
139
139
  # @label Not full width
140
140
  # @snapshot
141
141
  def not_full_width
142
- render(Primer::Alpha::TextField.new(full_width: false, name: "my-text-field", label: "My text field"))
142
+ render(Primer::Alpha::TextField.new(full_width: false, name: "my-text-field-5", label: "My text field"))
143
143
  end
144
144
 
145
145
  # @label Disabled
146
146
  # @snapshot
147
147
  def disabled
148
- render(Primer::Alpha::TextField.new(disabled: true, name: "my-text-field", label: "My text field"))
148
+ render(Primer::Alpha::TextField.new(disabled: true, name: "my-text-field-6", label: "My text field"))
149
149
  end
150
150
 
151
151
  # @label Invalid
152
152
  # @snapshot
153
153
  def invalid
154
- render(Primer::Alpha::TextField.new(invalid: true, name: "my-text-field", label: "My text field"))
154
+ render(Primer::Alpha::TextField.new(invalid: true, name: "my-text-field-7", label: "My text field"))
155
155
  end
156
156
 
157
157
  # @label With placeholder
158
158
  # @snapshot
159
159
  def with_placeholder
160
- render(Primer::Alpha::TextField.new(placeholder: "with a placeholder", name: "my-text-field", label: "My text field"))
160
+ render(Primer::Alpha::TextField.new(placeholder: "with a placeholder", name: "my-text-field-8", label: "My text field"))
161
161
  end
162
162
 
163
163
  # @label Inset
164
164
  # @snapshot
165
165
  def inset
166
- render(Primer::Alpha::TextField.new(inset: true, name: "my-text-field", label: "My text field"))
166
+ render(Primer::Alpha::TextField.new(inset: true, name: "my-text-field-9", label: "My text field"))
167
167
  end
168
168
 
169
169
  # @label Monospace
170
170
  # @snapshot
171
171
  def monospace
172
- render(Primer::Alpha::TextField.new(monospace: true, name: "my-text-field", label: "My text field"))
172
+ render(Primer::Alpha::TextField.new(monospace: true, name: "my-text-field-10", label: "My text field"))
173
173
  end
174
174
 
175
175
  # @label With trailing icon
176
176
  # @snapshot
177
177
  def with_trailing_icon
178
- render(Primer::Alpha::TextField.new(trailing_visual: { icon: { icon: :search } }, name: "my-text-field", label: "My text field"))
178
+ render(Primer::Alpha::TextField.new(trailing_visual: { icon: { icon: :search } }, name: "my-text-field-11", label: "My text field"))
179
179
  end
180
180
 
181
181
  # @label With trailing text
182
182
  # @snapshot
183
183
  def with_trailing_text
184
- render(Primer::Alpha::TextField.new(trailing_visual: { text: { text: "minute" } }, name: "my-text-field", label: "My text field"))
184
+ render(Primer::Alpha::TextField.new(trailing_visual: { text: { text: "minute" } }, name: "my-text-field-12", label: "My text field"))
185
185
  end
186
186
 
187
187
  # @label With trailing long text
188
188
  # @snapshot
189
189
  def with_trailing_long_text
190
- render(Primer::Alpha::TextField.new(trailing_visual: { text: { text: "Long trailing text" } }, name: "my-text-field", label: "My text field"))
190
+ render(Primer::Alpha::TextField.new(trailing_visual: { text: { text: "Long trailing text" } }, name: "my-text-field-13", label: "My text field"))
191
191
  end
192
192
 
193
193
  # @label With trailing counter
194
194
  # @snapshot
195
195
  def with_trailing_counter
196
- render(Primer::Alpha::TextField.new(trailing_visual: { counter: { count: 5 } }, name: "my-text-field", label: "My text field"))
196
+ render(Primer::Alpha::TextField.new(trailing_visual: { counter: { count: 5 } }, name: "my-text-field-14", label: "My text field"))
197
197
  end
198
198
 
199
199
  # @label With trailing label
200
- # @snapshot
200
+ # @snapshot
201
201
  def with_trailing_label
202
- render(Primer::Alpha::TextField.new(trailing_visual: { label: { text: "Hello" } }, name: "my-text-field", label: "My text field"))
202
+ render(Primer::Alpha::TextField.new(trailing_visual: { label: { text: "Hello" } }, name: "my-text-field-15", label: "My text field"))
203
203
  end
204
204
 
205
205
  # @label With leading visual
206
206
  # @snapshot
207
207
  def with_leading_visual
208
- render(Primer::Alpha::TextField.new(leading_visual: { icon: :search }, name: "my-text-field", label: "My text field"))
208
+ render(Primer::Alpha::TextField.new(leading_visual: { icon: :search, "aria-label": "Search" }, name: "my-text-field-16", label: "My text field"))
209
209
  end
210
210
 
211
211
  # @label With validation message
212
212
  # @snapshot
213
213
  def with_validation_message
214
- render(Primer::Alpha::TextField.new(validation_message: "An error occurred!", name: "my-text-field", label: "My text field"))
214
+ render(Primer::Alpha::TextField.new(validation_message: "An error occurred!", name: "my-text-field-17", label: "My text field"))
215
215
  end
216
216
  #
217
217
  # @!endgroup
218
218
 
219
- # @!group Auto check
219
+ # @!group Auto check
220
220
  #
221
221
  # @label Auto check request ok
222
222
  def with_auto_check_ok
223
- render(Primer::Alpha::TextField.new(auto_check_src: UrlHelpers.example_check_ok_path, name: "my-text-field", label: "My text field"))
223
+ render(Primer::Alpha::TextField.new(auto_check_src: UrlHelpers.example_check_ok_path, name: "my-text-field-18", label: "My text field"))
224
224
  end
225
225
 
226
226
  # @label Auto check request accepted
227
227
  def with_auto_check_accepted
228
- render(Primer::Alpha::TextField.new(auto_check_src: UrlHelpers.example_check_accepted_path, name: "my-text-field", label: "My text field"))
228
+ render(Primer::Alpha::TextField.new(auto_check_src: UrlHelpers.example_check_accepted_path, name: "my-text-field-19", label: "My text field"))
229
229
  end
230
230
 
231
231
  # @label Auto check request error
232
232
  def with_auto_check_error
233
- render(Primer::Alpha::TextField.new(auto_check_src: UrlHelpers.example_check_error_path, name: "my-text-field", label: "My text field"))
233
+ render(Primer::Alpha::TextField.new(auto_check_src: UrlHelpers.example_check_error_path, name: "my-text-field-20", label: "My text field"))
234
234
  end
235
235
  #
236
236
  # @!endgroup
@@ -62,6 +62,10 @@ module Primer
62
62
  def with_turbo
63
63
  render(Primer::Alpha::ToggleSwitch.new(src: UrlHelpers.toggle_switch_index_path, turbo: true))
64
64
  end
65
+
66
+ def with_autofocus
67
+ render(Primer::Alpha::ToggleSwitch.new(src: UrlHelpers.toggle_switch_index_path, autofocus: true))
68
+ end
65
69
  end
66
70
  end
67
71
  end
@@ -282,6 +282,12 @@ module Primer
282
282
  def inset
283
283
  render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: UrlHelpers.autocomplete_index_path, show_clear_button: false, inset: true))
284
284
  end
285
+
286
+
287
+ def no_results
288
+ render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", show_clear_button: false, visually_hide_label: false, placeholder: "Placeholder text", size: :medium, full_width: false, width: :auto, disabled: false, invalid: false, input_id: "input-id", list_id: "list-id", input_name: "input-id", inset: false, monospace: false, src: UrlHelpers.autocomplete_no_results_path))
289
+ end
290
+
285
291
  end
286
292
  end
287
293
  end
@@ -58,6 +58,18 @@ module Primer
58
58
  component.with_body { "Body" }
59
59
  end
60
60
  end
61
+
62
+ # @label Open
63
+ #
64
+ # @param overlay [Symbol] select [none, default, dark]
65
+ # @param reset [Boolean] toggle
66
+ # @param disabled [Boolean] toggle
67
+ def open(reset: false, overlay: :default, disabled: false)
68
+ render Primer::Beta::Details.new(reset: reset, overlay: overlay, disabled: disabled, open: true) do |component|
69
+ component.with_summary { "Click me" }
70
+ component.with_body { "Body" }
71
+ end
72
+ end
61
73
  end
62
74
  end
63
75
  end
@@ -95,17 +95,17 @@ module Primer
95
95
  <p>And an unordered task list:</p>
96
96
 
97
97
  <ul>
98
- <li><input type=\"checkbox\" checked> Create a sample markdown document</li>
99
- <li><input type=\"checkbox\"> Add task lists to it</li>
100
- <li><input type=\"checkbox\"> Take a vacation</li>
98
+ <li><input id="checkbox-1" type=\"checkbox\" checked><label for="checkbox-1">Create a sample markdown document</label></li>
99
+ <li><input id="checkbox-2" type=\"checkbox\"><label for="checkbox-2">Add task lists to it</label></li>
100
+ <li><input id="checkbox-3" type=\"checkbox\"><label for="checkbox-3">Take a vacation</label></li>
101
101
  </ul>
102
102
 
103
103
  <p>And a \"mixed\" task list:</p>
104
104
 
105
105
  <ul>
106
- <li><input type=\"checkbox\"> Steal underpants</li>
106
+ <li><input id="checkbox-4" type=\"checkbox\"><label for="checkbox-4">Steal underpants</label></li>
107
107
  <li>?</li>
108
- <li><input type=\"checkbox\"> Profit!</li>
108
+ <li><input id="checkbox-5" type=\"checkbox\"> <label for="checkbox-5">Profit!</label></li></li>
109
109
  </ul>
110
110
 
111
111
  And a nested list:
@@ -181,7 +181,7 @@ module Primer
181
181
 
182
182
  <p>If a table is too wide, it should condense down and/or scroll horizontally.</p>
183
183
 
184
- <table>
184
+ <table tabindex="0">
185
185
  <thead>
186
186
  <tr>
187
187
  <th>Artist</th>
@@ -237,13 +237,13 @@ module Primer
237
237
 
238
238
  <pre><code>var foo = \"bar\";</code></pre>
239
239
 
240
- <pre><code>Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. This line should be long enough to demonstrate this.</code></pre>
240
+ <pre tabindex="0"><code>Long, single-line code blocks should not wrap. They should horizontally scroll if they are too long. They should also have a tabindex=0 to ensure keyboard accessibility. This line should be long enough to demonstrate this.</code></pre>
241
241
 
242
- <pre><code>var foo = \"The same thing is true for code with syntax highlighting. A single line of code should horizontally scroll if it is really long.\";</code></pre>
242
+ <pre tabindex="0"><code>var foo = \"The same thing is true for code with syntax highlighting. A single line of code should horizontally scroll if it is really long.\";</code></pre>
243
243
 
244
244
  <p>Inline code inside table cells should still be distinguishable.</p>
245
245
 
246
- <table>
246
+ <table tabindex="0">
247
247
  <thead>
248
248
  <tr>
249
249
  <th>Language</th>
@@ -0,0 +1,25 @@
1
+ <% if truncate_label == :truncate %>
2
+ <div style="margin-bottom:1rem">
3
+ <%= render(
4
+ Primer::Alpha::Banner.new(
5
+ scheme: :warning,
6
+ description: 'If you must use truncation, ensure that users can still access the truncated content in an accessible manner, as truncation should be used sparingly.'
7
+ )
8
+ ) { "Inaccessible pattern" } %>
9
+ </div>
10
+ <% end %>
11
+
12
+ <%= render(Primer::Beta::NavList.new(aria: { label: "List heading" })) do |component| %>
13
+ <% component.with_item(
14
+ label: "Really really long label that may wrap, truncate, or appear as a tooltip",
15
+ truncate_label: truncate_label
16
+ ) %>
17
+ <% component.with_item(
18
+ label: "Really really long label that may wrap, truncate, or appear as a tooltip",
19
+ truncate_label: truncate_label
20
+ ) %>
21
+ <% component.with_item(
22
+ label: "Really really long label that may wrap, truncate, or appear as a tooltip",
23
+ truncate_label: truncate_label
24
+ ) %>
25
+ <% end %>