diff --git a/app/models/govuk_publishing_components/component_wrapper_helper_options.rb b/app/models/govuk_publishing_components/component_wrapper_helper_options.rb index b6b2200dca..e2f69b19cc 100644 --- a/app/models/govuk_publishing_components/component_wrapper_helper_options.rb +++ b/app/models/govuk_publishing_components/component_wrapper_helper_options.rb @@ -12,6 +12,7 @@ def self.description - `lang` - accepts a language attribute value - `open` - accepts an open attribute value (true or false) - `hidden` - accepts an empty string, 'hidden', or 'until-found' +- `tabindex` - accepts an integer. The integer can also be passed as a string. " end end diff --git a/app/views/govuk_publishing_components/components/_error_alert.html.erb b/app/views/govuk_publishing_components/components/_error_alert.html.erb index d4c2d61cf3..758de80901 100644 --- a/app/views/govuk_publishing_components/components/_error_alert.html.erb +++ b/app/views/govuk_publishing_components/components/_error_alert.html.erb @@ -10,9 +10,10 @@ component_helper.add_class("gem-c-error-alert govuk-!-display-none-print") component_helper.add_data_attribute({ module: "initial-focus" }) component_helper.add_role("alert") + component_helper.set_tabindex("-1") %> -<%= tag.div(**component_helper.all_attributes, tabindex: "-1") do %> +<%= tag.div(**component_helper.all_attributes) do %> <% if description.present? %> <%= tag.h2 message, class: "gem-c-error-summary__title" %> <%= tag.div description, class: "gem-c-error-summary__body" %> diff --git a/lib/govuk_publishing_components/presenters/component_wrapper_helper.rb b/lib/govuk_publishing_components/presenters/component_wrapper_helper.rb index b252f33411..a378bf5cdd 100644 --- a/lib/govuk_publishing_components/presenters/component_wrapper_helper.rb +++ b/lib/govuk_publishing_components/presenters/component_wrapper_helper.rb @@ -12,6 +12,7 @@ def initialize(options) check_lang_is_valid(@options[:lang]) if @options.include?(:lang) check_open_is_valid(@options[:open]) if @options.include?(:open) check_hidden_is_valid(@options[:hidden]) if @options.include?(:hidden) + check_tabindex_is_valid(@options[:tabindex]) if @options.include?(:tabindex) end def all_attributes @@ -25,6 +26,7 @@ def all_attributes attributes[:lang] = @options[:lang] unless @options[:lang].blank? attributes[:open] = @options[:open] unless @options[:open].blank? attributes[:hidden] = @options[:hidden] unless @options[:hidden].nil? + attributes[:tabindex] = @options[:tabindex] unless @options[:tabindex].blank? attributes end @@ -69,6 +71,11 @@ def set_hidden(hidden_attribute) @options[:hidden] = hidden_attribute end + def set_tabindex(tabindex_attribute) + check_tabindex_is_valid(tabindex_attribute) + @options[:tabindex] = tabindex_attribute + end + private def check_id_is_valid(id) @@ -146,6 +153,16 @@ def check_hidden_is_valid(hidden_attribute) end end + def check_tabindex_is_valid(tabindex_attribute) + return if tabindex_attribute.blank? + + tabindex_attribute = tabindex_attribute.to_s + + unless /^-?[0-9]+$/.match?(tabindex_attribute) + raise(ArgumentError, "tabindex_attribute attribute (#{tabindex_attribute}) is not recognised") + end + end + def extend_string(option, string) ((@options[option] ||= "") << " #{string}").strip! end diff --git a/spec/lib/govuk_publishing_components/components/component_wrapper_helper_spec.rb b/spec/lib/govuk_publishing_components/components/component_wrapper_helper_spec.rb index 62fd4af5f8..6396518aab 100644 --- a/spec/lib/govuk_publishing_components/components/component_wrapper_helper_spec.rb +++ b/spec/lib/govuk_publishing_components/components/component_wrapper_helper_spec.rb @@ -13,6 +13,7 @@ lang: "en", open: true, hidden: "", + tabindex: "0", } component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(args) expected = { @@ -27,6 +28,7 @@ lang: "en", open: true, hidden: "", + tabindex: "0", } expect(component_helper.all_attributes).to eql(expected) end @@ -218,5 +220,65 @@ helper.set_hidden("hidden") expect(helper.all_attributes[:hidden]).to eql("hidden") end + + it "can set an tabindex attribute, overriding a passed value" do + helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: -1) + helper.set_tabindex("1") + expect(helper.all_attributes[:tabindex]).to eql("1") + end + + describe "tabindex value regex" do + it "accepts string numbers" do + component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: "-984347284732") + expected = { + tabindex: "-984347284732", + } + expect(component_helper.all_attributes).to eql(expected) + end + + it "accepts integer numbers" do + component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: -984_347_284_732) + expected = { + tabindex: -984_347_284_732, + } + expect(component_helper.all_attributes).to eql(expected) + end + + it "accepts 0" do + component_helper = GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: "0") + expected = { + tabindex: "0", + } + expect(component_helper.all_attributes).to eql(expected) + end + + it "does not accept text before a number" do + error = "tabindex_attribute attribute (abc1) is not recognised" + expect { + GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: "abc1") + }.to raise_error(ArgumentError, error) + end + + it "does not accept text after a number" do + error = "tabindex_attribute attribute (123abc) is not recognised" + expect { + GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: "123abc") + }.to raise_error(ArgumentError, error) + end + + it "does not accept extra negative symbols" do + error = "tabindex_attribute attribute (--1) is not recognised" + expect { + GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: "--1") + }.to raise_error(ArgumentError, error) + end + + it "does not accept extra symbols" do + error = "tabindex_attribute attribute (-1!???) is not recognised" + expect { + GovukPublishingComponents::Presenters::ComponentWrapperHelper.new(tabindex: "-1!???") + }.to raise_error(ArgumentError, error) + end + end end end