From 2052341ee2ee667903e54798f12eccd51d957515 Mon Sep 17 00:00:00 2001 From: Owen Niblock Date: Tue, 4 Jun 2024 14:01:37 +0100 Subject: [PATCH 1/3] Add sr-only option to spinner --- app/components/primer/beta/spinner.html.erb | 3 ++ app/components/primer/beta/spinner.rb | 16 ++++++- static/arguments.json | 6 +++ test/components/beta/spinner_test.rb | 48 +++++++++++++++++++++ 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/app/components/primer/beta/spinner.html.erb b/app/components/primer/beta/spinner.html.erb index adabca4226..7b40309a4c 100644 --- a/app/components/primer/beta/spinner.html.erb +++ b/app/components/primer/beta/spinner.html.erb @@ -2,3 +2,6 @@ <% end %> +<% if no_aria_label? %> + <%= @sr_text %> +<% end %> diff --git a/app/components/primer/beta/spinner.rb b/app/components/primer/beta/spinner.rb index f47ab1d1c1..e4bc99f05c 100644 --- a/app/components/primer/beta/spinner.rb +++ b/app/components/primer/beta/spinner.rb @@ -12,6 +12,7 @@ class Spinner < Primer::Component DEFAULT_SIZE => 32, :large => 64 }.freeze + DEFAULT_SR_TEXT = "Loading" SIZE_OPTIONS = SIZE_MAPPINGS.keys @@ -22,7 +23,7 @@ class Spinner < Primer::Component # @param size [Symbol] <%= one_of(Primer::Beta::Spinner::SIZE_MAPPINGS) %> # @param style [String] Custom element styles. # @param system_arguments [Hash] <%= link_to_system_arguments_docs %> - def initialize(size: DEFAULT_SIZE, style: DEFAULT_STYLE, **system_arguments) + def initialize(size: DEFAULT_SIZE, style: DEFAULT_STYLE, sr_text: DEFAULT_SR_TEXT, **system_arguments) @system_arguments = deny_tag_argument(**system_arguments) @system_arguments[:tag] = :svg @system_arguments[:style] ||= style @@ -31,6 +32,19 @@ def initialize(size: DEFAULT_SIZE, style: DEFAULT_STYLE, **system_arguments) @system_arguments[:height] = SIZE_MAPPINGS[fetch_or_fallback(SIZE_OPTIONS, size, DEFAULT_SIZE)] @system_arguments[:viewBox] = "0 0 16 16" @system_arguments[:fill] = :none + @system_arguments[:aria] ||= {} + @sr_text = sr_text + + if no_aria_label? + @system_arguments[:aria][:hidden] = true + else + @system_arguments[:role] = "img" + end + end + + def no_aria_label? + !@system_arguments[:aria][:label] && !@system_arguments[:"aria-label"] && + !@system_arguments[:aria][:labelledby] && !@system_arguments[:"aria-labelledby"] end end end diff --git a/static/arguments.json b/static/arguments.json index f6d491afca..fb3905a527 100644 --- a/static/arguments.json +++ b/static/arguments.json @@ -4282,6 +4282,12 @@ "default": "`box-sizing: content-box; color: var(--color-icon-primary);`", "description": "Custom element styles." }, + { + "name": "sr_text", + "type": "String", + "default": "Loading", + "description": "Screen reader only text, added unless aria-label is set." + }, { "name": "system_arguments", "type": "Hash", diff --git a/test/components/beta/spinner_test.rb b/test/components/beta/spinner_test.rb index 67231d0688..faab977d31 100644 --- a/test/components/beta/spinner_test.rb +++ b/test/components/beta/spinner_test.rb @@ -44,4 +44,52 @@ def test_no_box_sizing_style def test_status assert_component_state(Primer::Beta::Spinner, :beta) end + + def test_adds_default_sr_span + render_inline(Primer::Beta::Spinner.new) + + assert_selector("span.sr-only", text: "Loading") + end + + def test_adds_custom_sr_span + render_inline(Primer::Beta::Spinner.new(sr_text: "Custom Loading")) + + assert_selector("span.sr-only", text: "Custom Loading") + end + + def test_no_custom_sr_span_with_aria_label + render_inline(Primer::Beta::Spinner.new("aria-label": "Aria label")) + + assert_no_selector("span.sr-only") + end + + def test_no_custom_sr_span_with_aria_label_hash + render_inline(Primer::Beta::Spinner.new(aria: { label: "Aria label"})) + + assert_no_selector("span.sr-only") + end + + def test_no_custom_sr_span_with_aria_labelledby + render_inline(Primer::Beta::Spinner.new("aria-labelledby": "my_id")) + + assert_no_selector("span.sr-only") + end + + def test_no_custom_sr_span_with_aria_labelledby_hash + render_inline(Primer::Beta::Spinner.new(aria: { labelledby: "my_id"})) + + assert_no_selector("span.sr-only") + end + + def test_adds_img_role_with_aria_label + render_inline(Primer::Beta::Spinner.new("aria-label": "Aria label")) + + assert_selector("svg[role=img]") + end + + def test_adds_aria_hidden_with_no_aria_label + render_inline(Primer::Beta::Spinner.new) + + assert_selector("svg[aria-hidden=true]") + end end From 34dbde5adbcb996e9b4d314c7fff4db8d9ced1cc Mon Sep 17 00:00:00 2001 From: Owen Niblock Date: Tue, 4 Jun 2024 14:25:19 +0100 Subject: [PATCH 2/3] Add changeset --- .changeset/blue-insects-buy.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/blue-insects-buy.md diff --git a/.changeset/blue-insects-buy.md b/.changeset/blue-insects-buy.md new file mode 100644 index 0000000000..8931121e1d --- /dev/null +++ b/.changeset/blue-insects-buy.md @@ -0,0 +1,5 @@ +--- +'@primer/view-components': minor +--- + +Adds default sr-only text to spinner component From 6b6532c03bd8cd9aa729e0ba0464467e80087b60 Mon Sep 17 00:00:00 2001 From: Owen Niblock Date: Tue, 4 Jun 2024 17:02:49 +0100 Subject: [PATCH 3/3] Add sr_text to playground --- previews/primer/beta/spinner_preview.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/previews/primer/beta/spinner_preview.rb b/previews/primer/beta/spinner_preview.rb index 937a8a61c2..c2792be7bf 100644 --- a/previews/primer/beta/spinner_preview.rb +++ b/previews/primer/beta/spinner_preview.rb @@ -7,8 +7,8 @@ class SpinnerPreview < ViewComponent::Preview # @label Playground # # @param size [Symbol] select [small, medium, large] - def playground(size: :medium) - render(Primer::Beta::Spinner.new(size: size)) + def playground(size: :medium, sr_text: "Loading content...") + render(Primer::Beta::Spinner.new(size: size, sr_text: sr_text)) end # @label Default Options