From b68b8d3154e585295434a2c2f2ab9d81620c7d00 Mon Sep 17 00:00:00 2001 From: David Roetzel Date: Tue, 23 Jun 2026 14:34:14 +0200 Subject: [PATCH] Add `aria-current=page` attribute to selected link --- lib/simple_navigation/item.rb | 6 ++++- spec/simple_navigation/item_spec.rb | 26 ++++++++++++++++++-- spec/simple_navigation/renderer/list_spec.rb | 20 ++++++++++++--- 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/lib/simple_navigation/item.rb b/lib/simple_navigation/item.rb index 580428f..ee0ab88 100644 --- a/lib/simple_navigation/item.rb +++ b/lib/simple_navigation/item.rb @@ -91,7 +91,11 @@ def method # Returns the html attributes for the link as set with the :link_html option # at initialization def link_html_options - @link_html_options ||= options[:link_html] + @link_html_options ||= begin + link_options = options[:link_html] || {} + link_options[:"aria-current"] = "page" if !selected_by_subnav? && selected_by_condition? + link_options + end end protected diff --git a/spec/simple_navigation/item_spec.rb b/spec/simple_navigation/item_spec.rb index aef7de8..c19581f 100644 --- a/spec/simple_navigation/item_spec.rb +++ b/spec/simple_navigation/item_spec.rb @@ -152,10 +152,32 @@ end describe '#link_html_options' do - let(:options) { { link_html: :test } } + let(:options) { { link_html: { class: "test" } } } + + before { allow(item).to receive_messages(selected?: false, selected_by_condition?: false, selected_by_subnav?: false) } it "returns the item's link_html option" do - expect(item.link_html_options).to eq :test + expect(item.link_html_options).to eq({ class: "test" }) + end + + it "doesn't add an `aria-current` attribute" do + expect(item.link_html_options).to_not have_key(:"aria-current") + end + + context "when the item is selected by condition but not by subnav (i.e. a selected leaf)" do + before { allow(item).to receive_messages(selected?: true, selected_by_condition?: true, selected_by_subnav?: false) } + + it "adds an `aria-current` attribute" do + expect(item.link_html_options[:"aria-current"]).to eq "page" + end + end + + context "when the item is selected by subnav and not by condition" do + before { allow(item).to receive_messages(selected?: true, selected_by_condition?: false, selected_by_subnav?: true) } + + it "doesn't add an `aria-current` attribute" do + expect(item.link_html_options).to_not have_key(:"aria-current") + end end end diff --git a/spec/simple_navigation/renderer/list_spec.rb b/spec/simple_navigation/renderer/list_spec.rb index d28f1ed..5ee5bff 100644 --- a/spec/simple_navigation/renderer/list_spec.rb +++ b/spec/simple_navigation/renderer/list_spec.rb @@ -3,13 +3,10 @@ RSpec.describe SimpleNavigation::Renderer::List do let!(:navigation) { setup_navigation('nav_id', 'nav_class') } - let(:item) { nil } let(:options) { { level: :all } } let(:output) { renderer.render(navigation) } let(:renderer) { described_class.new(options) } - before { select_an_item(navigation[item]) if item } - describe '#render' do it "renders an 'ul' tag for the navigation" do expect(output).to have_css('ul') @@ -46,7 +43,10 @@ end context 'when an item is selected' do - let(:item) { :invoices } + before do + allow(navigation[:invoices]).to \ + receive_messages(selected?: true, selected_by_condition?: true) + end it "renders the item's 'li' tag with its id and selected classes" do expect(output).to have_css('li#invoices.selected') @@ -55,6 +55,10 @@ it "renders the item's 'a' tag with the selected classes" do expect(output).to have_css('li#invoices a.selected') end + + it "renders the item's 'a' tag with with an 'aria-current' attribute" do + expect(output).to have_css('li#invoices a[aria-current=page]') + end end context 'when the :ordered option is true' do @@ -88,6 +92,14 @@ it "renders the selected nested item's link as selected" do expect(output).to have_css('li#unpaid.selected') end + + it "renders the selected nested item's 'a' tag with with an 'aria-current' attribute" do + expect(output).to have_css('li#unpaid a[aria-current=page]') + end + + it "does not 'aria-current' to the parent item's link" do + expect(output).to_not have_css('li#invoices > a[aria-current=page]') + end end end end