Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
42bcfec
chore: bumps autocomplete element package to 3.1.0
lindseywild Mar 7, 2022
324d0f0
chore: updates changelog
lindseywild Mar 9, 2022
ce0ed9f
feat: updates autocomplete api to match web component
lindseywild Mar 9, 2022
258d73d
docs: build docs
actions-user Mar 9, 2022
1f85564
fix: removes extra file changes
lindseywild Mar 9, 2022
04daed1
Work in progress adding input back in with restrictions
owenniblock Mar 10, 2022
7ef4773
Fixes tests and auto_complete template
owenniblock Mar 10, 2022
0ebdfbd
fix: updates api, writes tests
lindseywild Mar 10, 2022
8e34c9f
docs: build docs
actions-user Mar 10, 2022
70b8227
Update app/components/primer/beta/auto_complete.rb
owenniblock Mar 11, 2022
391b2d5
Fix restrictions on autocomplete input and fix tests
owenniblock Mar 11, 2022
fd7647b
docs: build docs
actions-user Mar 11, 2022
ab0e63f
* explicitly deny name and id on input slot
khiga8 Mar 14, 2022
b017638
* move test to beta folder and add test for deny
khiga8 Mar 14, 2022
c691edf
Add optional input_name parameter to new AutoComplete component
owenniblock Mar 22, 2022
40de4d0
docs: build docs
actions-user Mar 22, 2022
613ed34
* update deny message for name
khiga8 Mar 22, 2022
fb77d81
* update test name message
khiga8 Mar 23, 2022
fcf33d4
Merge branch 'main' into update-auto-complete-package
khiga8 Mar 24, 2022
fe1a356
* yarn upgrade @primer/css
khiga8 Mar 24, 2022
881306b
* bump primer/css dependency in docs
khiga8 Mar 24, 2022
d35cc72
* bump primer/css dependency in demo
khiga8 Mar 24, 2022
cb2b04a
* add stacked and inline classes and body wrapper
khiga8 Mar 24, 2022
8cf51b7
* add example descriptions and re-order by importance
khiga8 Mar 24, 2022
e0c7626
* add link to accessibility section
khiga8 Mar 24, 2022
cf8cfd5
* remove position: relative in examples
khiga8 Mar 24, 2022
bd0aa45
feat: adds wrapping div, restricts to search icon, tests
lindseywild Mar 25, 2022
78360cc
docs: build docs
actions-user Mar 25, 2022
5c6b176
Merge branch 'main' into update-auto-complete-package
khiga8 Mar 25, 2022
6608793
chore: cleanup
lindseywild Mar 28, 2022
d858a03
docs: build docs
actions-user Mar 28, 2022
d222125
Merge branch 'main' into update-auto-complete-package
khiga8 Mar 28, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,13 @@ The category for changes related to documentation, testing and tooling. Also, fo

_Hector Garcia_

### Updates

- Bumps auto-complete package to 3.1.0
- Updates AutoComplete API with optional clear button, restricted icon, and other argument restrictions

_Lindsey Wild_, _Kate Higa_, _Owen Niblock_

- Check for the `gh` CLI tool in release scripts.

_Cameron Dutro_
Expand Down
2 changes: 1 addition & 1 deletion app/assets/javascripts/primer_view_components.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion app/assets/javascripts/primer_view_components.js.map

Large diffs are not rendered by default.

102 changes: 82 additions & 20 deletions app/components/primer/beta/auto_complete.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,7 @@ module Beta
# be used unless there is compelling reason not to. A placeholder is not a label.
class AutoComplete < Primer::Component
status :beta

# Optional icon to be rendered before the input. Has the same arguments as <%= link_to_component(Primer::OcticonComponent) %>.
renders_one :icon, Primer::OcticonComponent

#
# Customizable results list.
#
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
Expand All @@ -32,14 +29,79 @@ class AutoComplete < Primer::Component
Primer::BaseComponent.new(**system_arguments)
}

# Customizable input used to search for results.
# It is preferred to use this slot sparingly - it will be created by default if not explicity added.
#
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
renders_one :input, lambda { |**system_arguments|
sanitized_args = deny_tag_argument(**system_arguments)
sanitized_args = deny_single_argument(:autofocus, "autofocus is not allowed for accessibility reasons. See https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus#accessibility_considerations for more information.", **sanitized_args)
deny_aria_key(
:label,
"instead of `aria-label`, include `label_text` and set `is_label_visible` to `false` on the component initializer.",
**sanitized_args
)
deny_single_argument(
:id,
"`id` will always be set to @input_id.",
**sanitized_args
)
deny_single_argument(
:name,
"Set @input_name on the component initializer instead with `input_name`.",
**sanitized_args
)
sanitized_args[:id] = @input_id
sanitized_args[:name] = @input_name
sanitized_args[:tag] = :input
sanitized_args[:autocomplete] = "off"

sanitized_args[:type] = :text
sanitized_args[:classes] = class_names(
"form-control",
sanitized_args[:classes]
)

Primer::BaseComponent.new(**sanitized_args)
}

# @example Default
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input-1", list_id: "fruits-popup-1", position: :relative)) %>
# @description
# Labels are stacked by default.
# @code
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--default", list_id: "fruits-popup--default")) %>
#
# @example With inline label
# @description
# Labels can be inline by setting `is_label_inline: true`. However, labels will always become stacked on smaller screen sizes.
# @code
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", is_label_inline: true, input_id: "fruits-input--inline-label", list_id: "fruits-popup--inline-label")) %>
#
# @example With non-visible label
# @description
# A non-visible label may be rendered with `is_label_visible: false`, but it is highly discouraged. See <%= link_to_accessibility %>.
# @code
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--non-visible-label", list_id: "fruits-popup--non-visible-label", is_label_visible: false)) %>
#
# @example With icon
# @description
# To display a search icon, set `with_icon` to `true`.
# @code
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", list_id: "fruits-popup--icon", input_id: "fruits-input--icon", with_icon: true)) %>
#
# @example With icon and non-visible label
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", list_id: "fruits-popup--icon-no-label", input_id: "fruits-input--icon-no-label", with_icon: true, is_label_visible: false)) %>
#
# @example With Non-Visible Label
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input-2", list_id: "fruits-popup-2", is_label_visible: false, position: :relative)) %>
# @example With clear button
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--clear", list_id: "fruits-popup--clear", is_clearable: true)) %>
#
# @example With Custom Classes for the Results
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input-3", list_id: "fruits-popup-3", position: :relative)) do |c| %>
# @example With custom classes for the input
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--custom-input", list_id: "fruits-popup--custom-input")) do |c| %>
# <% c.input(classes: "custom-class") %>
# <% end %>
#
# @example With custom classes for the results
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", input_id: "fruits-input--custom-results", list_id: "fruits-popup--custom-results")) do |c| %>
# <% c.results(classes: "custom-class") do %>
# <%= render(Primer::Beta::AutoComplete::Item.new(selected: true, value: "apple")) do |c| %>
# Apple
Expand All @@ -50,36 +112,36 @@ class AutoComplete < Primer::Component
# <% end %>
# <% end %>
#
# @example With Icon
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", list_id: "fruits-popup-4", input_id: "fruits-input-4", position: :relative)) do |c| %>
# <% c.icon(icon: :search) %>
# <% end %>
#
# @example With Icon and Non-Visible Label
# <%= render(Primer::Beta::AutoComplete.new(label_text: "Fruits", src: "/auto_complete", list_id: "fruits-popup-5", input_id: "fruits-input-5", is_label_visible: false, position: :relative)) do |c| %>
# <% c.icon(icon: :search) %>
# <% end %>
# @param label_text [String] The label of the input.
# @param src [String] The route to query.
# @param input_id [String] Id of the input element.
# @param input_name [String] Optional name of the input element, defaults to `input_id` when not set.
# @param list_id [String] Id of the list element.
# @param with_icon [Boolean] Controls if a search icon is visible, defaults to `false`.
# @param is_label_visible [Boolean] Controls if the label is visible. If `false`, screen reader only text will be added.
# @param is_clearable [Boolean] Adds optional clear button.
# @param is_label_inline [Boolean] Controls if the label is inline. On smaller screens, label will always become stacked.
# @param system_arguments [Hash] <%= link_to_system_arguments_docs %>
def initialize(label_text:, src:, list_id:, input_id:, is_label_visible: true, **system_arguments)
def initialize(label_text:, src:, list_id:, input_id:, input_name: nil, is_label_visible: true, is_label_inline: false, with_icon: false, is_clearable: false, **system_arguments)
@label_text = label_text
@list_id = list_id
@input_id = input_id
@input_name = input_name || input_id
@is_label_visible = is_label_visible
@with_icon = with_icon
@is_clearable = is_clearable

@label_classes = is_label_inline ? "autocomplete-label-inline" : "autocomplete-label-stacked"
@system_arguments = deny_tag_argument(**system_arguments)
@system_arguments[:tag] = "auto-complete"
@system_arguments[:src] = src
@system_arguments[:for] = list_id
end

# add `results` without needing to explicitly call them in the view
# add `input` and `results` without needing to explicitly call them in the view
def before_render
results(classes: "") unless results
input(classes: "") unless input
end
end
end
Expand Down
22 changes: 16 additions & 6 deletions app/components/primer/beta/auto_complete/auto_complete.html.erb
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
<%= render Primer::BaseComponent.new(**@system_arguments) do %>
<label for="<%= @input_id %>">
<label for="<%= @input_id %>" class="<%= @label_classes %>">
<% if @is_label_visible %>
<%= @label_text %>
<% else %>
<span class="sr-only"><%= @label_text %></span>
<% end %>
<% if icon.present? %>
<%= icon %>
<% end %>
</label>
<input id="<%= @input_id %>" name="<%= @input_id %>" type="text" class="form-control" autocomplete="off">
<%= results %>
<span class="autocomplete-body">
<% if @with_icon %>
<div class="form-control autocomplete-embedded-icon-wrap">
<%= render Primer::OcticonComponent.new(:search) %>
<% end %>
<%= input %>
<% if @is_clearable %>
<button id="<%= @input_id %>-clear" class="btn-octicon" aria-label="Clear"><%= primer_octicon "x" %></button>
<% end %>
<% if @with_icon %>
</div>
<% end %>
<%= results %>
</span>
<div id="<%= @list_id %>-feedback" class="sr-only"></div>
<% end %>
11 changes: 9 additions & 2 deletions app/components/primer/component.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,17 @@ def deny_single_argument(key, help_text, **arguments)
def deny_aria_label(tag:, arguments:)
return arguments.except!(:skip_aria_label_check) if arguments[:skip_aria_label_check]
return if arguments[:role]
return unless aria(:label, arguments)
return unless INVALID_ARIA_LABEL_TAGS.include?(tag)

raise ArgumentError, "Don't use `aria-label` on `#{tag}` elements. See https://www.tpgi.com/short-note-on-aria-label-aria-labelledby-and-aria-describedby/" if should_raise_aria_error?
deny_aria_key(
:label,
"Don't use `aria-label` on `#{tag}` elements. See https://www.tpgi.com/short-note-on-aria-label-aria-labelledby-and-aria-describedby/",
**arguments
)
end

def deny_aria_key(key, help_text, **arguments)
raise ArgumentError, help_text if should_raise_aria_error? && aria(key, arguments)
end

def deny_tag_argument(**arguments)
Expand Down
12 changes: 7 additions & 5 deletions demo/test/components/previews/primer/auto_complete_preview.rb
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
module Primer
class AutoCompletePreview < ViewComponent::Preview
def default
render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: "/auto_complete", position: :relative))
render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: "/auto_complete"))
end

def with_non_visible_label
render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: "/auto_complete", is_label_visible: false, position: :relative))
render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: "/auto_complete", is_label_visible: false))
end

def with_icon
render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: "/auto_complete", position: :relative)) do |c|
c.icon(icon: :search)
end
render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: "/auto_complete", with_icon: true))
end

def with_clear_button
render(Primer::Beta::AutoComplete.new(label_text: "Select a fruit", input_id: "input-id", list_id: "test-id", src: "/auto_complete", is_clearable: true))
end
end
end
6 changes: 3 additions & 3 deletions demo/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1390,9 +1390,9 @@
integrity sha512-idupwQC7vpMki4G2HBpQqTAD6MusFkipgfNXxETQ1D4yLkMQ1bMuif09dnHB7bhQBO5pXUFt52LMpPAnM5Zv4w==

"@primer/primitives@^7.5.1":
version "7.5.1"
resolved "https://registry.yarnpkg.com/@primer/primitives/-/primitives-7.5.1.tgz#18aa8a0f3a3f7fd49fcad31a7efb86688bffb9de"
integrity sha512-1pFKR+FcYRPXJ+zK/qtidrCJB7WmTaAX4sG7zE5LvGWjS5latue4pzZrK0FxxGGBdAU3HpoabANsGjv7T7sRRg==
version "7.6.0"
resolved "https://registry.yarnpkg.com/@primer/primitives/-/primitives-7.6.0.tgz#942efe38b6e09bf6d0351c045436e628e32c3ddb"
integrity sha512-cu28QLjectVf2rT4P7m6zS9v4g4yHtErRuPfsgEWEJhbXVIII6vDBm6elJzYixGpTNxpVtSUNezxUXv16l1ejQ==

"@rails/actioncable@^6.0.0":
version "6.1.3"
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"lint:fix": "eslint app/components demo/.storybook --fix"
},
"dependencies": {
"@github/auto-complete-element": "^3.0.2",
"@github/auto-complete-element": "^3.1.0",
"@github/clipboard-copy-element": "^1.1.2",
"@github/details-menu-element": "^1.0.12",
"@github/image-crop-element": "^5.0.0",
Expand Down
18 changes: 18 additions & 0 deletions static/arguments.yml
Original file line number Diff line number Diff line change
Expand Up @@ -201,15 +201,33 @@
type: String
default: N/A
description: Id of the input element.
- name: input_name
type: String
default: "`nil`"
description: Optional name of the input element, defaults to `input_id` when not
set.
- name: list_id
type: String
default: N/A
description: Id of the list element.
- name: with_icon
type: Boolean
default: "`false`"
description: Controls if a search icon is visible, defaults to `false`.
- name: is_label_visible
type: Boolean
default: "`true`"
description: Controls if the label is visible. If `false`, screen reader only
text will be added.
- name: is_clearable
type: Boolean
default: "`false`"
description: Adds optional clear button.
- name: is_label_inline
type: Boolean
default: "`false`"
description: Controls if the label is inline. On smaller screens, label will always
become stacked.
- name: system_arguments
type: Hash
default: N/A
Expand Down
4 changes: 4 additions & 0 deletions static/classes.yml
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@
- ".UnderlineNav-item"
- ".UnderlineNav-octicon"
- ".anim-rotate"
- ".autocomplete-body"
- ".autocomplete-embedded-icon-wrap"
- ".autocomplete-item"
- ".autocomplete-label-inline"
- ".autocomplete-label-stacked"
- ".autocomplete-results"
- ".avatar"
- ".avatar-more"
Expand Down
9 changes: 5 additions & 4 deletions stories/primer/beta/auto_complete_stories.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,12 @@ class Primer::Beta::AutoCompleteStories < ViewComponent::Storybook::Stories
text(:label_text, "Fruits")
text(:src, "/")
text(:input_id, "input-id")
text(:input_name, "input-name")
text(:list_id, "list-id")
end

content do |c|
c.icon(icon: :search)
is_clearable false
is_label_inline false
is_label_visible true
with_icon false
end
end
end
Loading