From 6f7a547e15067687002b1e994f6de58360a5aee2 Mon Sep 17 00:00:00 2001 From: Cillian O'Ruanaidh Date: Fri, 29 Aug 2025 14:21:14 +0100 Subject: [PATCH] Add a :link_to_or_disabled helper method --- app/helpers/link_helper.rb | 23 +++++++++++++++++++ .../spree/orders/form/_cart_links.html.haml | 6 ++--- .../css/admin_v3/components/buttons.scss | 4 ++++ spec/helpers/link_helper_spec.rb | 21 +++++++++++++++++ 4 files changed, 50 insertions(+), 4 deletions(-) diff --git a/app/helpers/link_helper.rb b/app/helpers/link_helper.rb index dde2433446..fced430271 100644 --- a/app/helpers/link_helper.rb +++ b/app/helpers/link_helper.rb @@ -1,6 +1,29 @@ # frozen_string_literal: true module LinkHelper + def link_to_or_disabled(name = nil, options = nil, html_options = nil, &block) + html_options, options, name = options, name, block if block_given? + html_options ||= {} + + if !!html_options.delete(:disabled) + # https://www.scottohara.me/blog/2021/05/28/disabled-links.html + html_options.merge!( + 'aria-disabled': true, + class: (html_options[:class].to_s.split + ["disabled"]).uniq.join(" "), + role: "link" + ) + if block_given? + content_tag("a", name, **html_options, &block) + else + content_tag("a", name, **html_options) + end + elsif block_given? + link_to options, html_options, &block + else + link_to name, options, html_options + end + end + def link_to_service(baseurl, name, html_options = {}, &) return if name.blank? diff --git a/app/views/spree/orders/form/_cart_links.html.haml b/app/views/spree/orders/form/_cart_links.html.haml index a3114cb670..a9b17a2172 100644 --- a/app/views/spree/orders/form/_cart_links.html.haml +++ b/app/views/spree/orders/form/_cart_links.html.haml @@ -1,5 +1,3 @@ .row.links - %a.continue-shopping.button.secondary{ @insufficient_stock_lines.any? ? { disabled: "disabled" } : { href: current_shop_products_path } } - = t :orders_edit_continue - %a#checkout-link.button.primary.right{ @insufficient_stock_lines.any? ? { disabled: "disabled" } : { href: main_app.checkout_path } } - = t :orders_edit_checkout + = link_to_or_disabled t(:orders_edit_continue), current_shop_products_path, class: "continue-shopping button secondary", disabled: @insufficient_stock_lines.any? + = link_to_or_disabled t(:orders_edit_checkout), main_app.checkout_path, class: "button primary right", disabled: @insufficient_stock_lines.any?, id: "checkout-link" diff --git a/app/webpacker/css/admin_v3/components/buttons.scss b/app/webpacker/css/admin_v3/components/buttons.scss index 01ede577d1..7de1a2ab6e 100644 --- a/app/webpacker/css/admin_v3/components/buttons.scss +++ b/app/webpacker/css/admin_v3/components/buttons.scss @@ -182,6 +182,10 @@ a.button { text-decoration: none; } +a[aria-disabled] { + pointer-events: none; +} + .button.disruptive::before { margin-right: 3px; diff --git a/spec/helpers/link_helper_spec.rb b/spec/helpers/link_helper_spec.rb index 14dc507343..aceeca8cf7 100644 --- a/spec/helpers/link_helper_spec.rb +++ b/spec/helpers/link_helper_spec.rb @@ -9,4 +9,25 @@ RSpec.describe LinkHelper do expect(helper.ext_url("http://example.com/", "bla")).to eq("http://example.com/bla") end end + + describe "link_to_or_disabled" do + it "behaves like the standard :link_to method e.g. it accepts the same arguments and accepts + blocks, etc." do + expect(helper.link_to_or_disabled("Go", "http://example.com/")).to eq( + "Go" + ) + expect(helper.link_to_or_disabled("Go", "http://example.com/", class: "button")).to eq( + "Go" + ) + expect(helper.link_to_or_disabled("http://example.com/") { "Go" }).to eq( + "Go" + ) + end + + it "accepts an additional boolean :disabled argument, which if true renders a disabled link" do + expect(helper.link_to_or_disabled("Go", "http://example.com/", disabled: true)).to eq( + "Go" + ) + end + end end