diff --git a/admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb b/admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb index 9e295709c4d..8291aeb8b0e 100644 --- a/admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb +++ b/admin/app/components/solidus_admin/orders/show/adjustments/index/component.rb @@ -13,8 +13,6 @@ def title t(".title", number: @order.number) end - NBSP = " ".html_safe - def initialize(order:, adjustments:) @order = order @adjustments = adjustments diff --git a/backend/app/assets/javascripts/spree/backend/handlebars_extensions.js b/backend/app/assets/javascripts/spree/backend/handlebars_extensions.js.erb similarity index 51% rename from backend/app/assets/javascripts/spree/backend/handlebars_extensions.js rename to backend/app/assets/javascripts/spree/backend/handlebars_extensions.js.erb index dd9d2ae7135..f468d033f2b 100644 --- a/backend/app/assets/javascripts/spree/backend/handlebars_extensions.js +++ b/backend/app/assets/javascripts/spree/backend/handlebars_extensions.js.erb @@ -24,3 +24,20 @@ Handlebars.registerHelper("concat", function() { Handlebars.registerHelper("format_money", function(amount, currency) { return Spree.formatMoney(amount, currency); }); + +Handlebars.registerHelper("solidus_icon", function(name) { + var useRemix = <%= Spree::Backend::Config.admin_updated_navbar.to_json %>; + var spritePath = <%= image_path("spree/backend/themes/solidus_admin/remixicon.symbol.svg").to_json %>; + var remixNames = <%= Spree::Backend::REMIX_ICONS.to_json %>; + var symbol = remixNames[name]; + + if (useRemix && symbol) { + return new Handlebars.SafeString( + '' + ); + } + return new Handlebars.SafeString( + '' + ); +}); diff --git a/backend/app/assets/javascripts/spree/backend/templates/orders/line_item.hbs b/backend/app/assets/javascripts/spree/backend/templates/orders/line_item.hbs index 1841126db70..301485f5b08 100644 --- a/backend/app/assets/javascripts/spree/backend/templates/orders/line_item.hbs +++ b/backend/app/assets/javascripts/spree/backend/templates/orders/line_item.hbs @@ -33,12 +33,12 @@ {{#if editing}} - + {{#unless noCancel}} - + {{/unless}} {{else}} - - + + {{/if}} diff --git a/backend/app/assets/javascripts/spree/backend/templates/orders/shipment_tracking.hbs b/backend/app/assets/javascripts/spree/backend/templates/orders/shipment_tracking.hbs index 487ddf1d71b..5fb9dfef291 100644 --- a/backend/app/assets/javascripts/spree/backend/templates/orders/shipment_tracking.hbs +++ b/backend/app/assets/javascripts/spree/backend/templates/orders/shipment_tracking.hbs @@ -16,9 +16,9 @@ {{#if editing}} - - + + {{else}} - + {{/if}} diff --git a/backend/app/assets/javascripts/spree/backend/templates/orders/shipping_method.hbs b/backend/app/assets/javascripts/spree/backend/templates/orders/shipping_method.hbs index 4aa6cbd156b..d1ec5faaa46 100644 --- a/backend/app/assets/javascripts/spree/backend/templates/orders/shipping_method.hbs +++ b/backend/app/assets/javascripts/spree/backend/templates/orders/shipping_method.hbs @@ -25,10 +25,10 @@ {{#if editing}} {{#if shipping_rates}} - + {{/if}} - + {{else}} - + {{/if}} diff --git a/backend/app/assets/javascripts/spree/backend/templates/products/sortable.hbs b/backend/app/assets/javascripts/spree/backend/templates/products/sortable.hbs index b2c16af973d..7dd82abaa03 100644 --- a/backend/app/assets/javascripts/spree/backend/templates/products/sortable.hbs +++ b/backend/app/assets/javascripts/spree/backend/templates/products/sortable.hbs @@ -1,5 +1,5 @@ - + {{solidus_icon "sort"}} {{ name }} {{ display_price }} diff --git a/backend/app/assets/javascripts/spree/backend/templates/stock_items/stock_location_stock_item.hbs b/backend/app/assets/javascripts/spree/backend/templates/stock_items/stock_location_stock_item.hbs index cb5a70401f6..613d5550f95 100644 --- a/backend/app/assets/javascripts/spree/backend/templates/stock_items/stock_location_stock_item.hbs +++ b/backend/app/assets/javascripts/spree/backend/templates/stock_items/stock_location_stock_item.hbs @@ -34,6 +34,6 @@ - - + {{solidus_icon "check"}} + {{solidus_icon "cancel"}} diff --git a/backend/app/assets/javascripts/spree/backend/templates/taxons/_tree.hbs b/backend/app/assets/javascripts/spree/backend/templates/taxons/_tree.hbs index 8d02ab32132..1bf8a09235f 100644 --- a/backend/app/assets/javascripts/spree/backend/templates/taxons/_tree.hbs +++ b/backend/app/assets/javascripts/spree/backend/templates/taxons/_tree.hbs @@ -4,13 +4,13 @@
{{else}}
- + {{solidus_icon "arrows"}} {{/if}} {{name}}
{{#if taxons }} diff --git a/backend/app/assets/javascripts/spree/backend/templates/variants/split.hbs b/backend/app/assets/javascripts/spree/backend/templates/variants/split.hbs index e4d0d7701f9..edbed2109ad 100644 --- a/backend/app/assets/javascripts/spree/backend/templates/variants/split.hbs +++ b/backend/app/assets/javascripts/spree/backend/templates/variants/split.hbs @@ -22,6 +22,6 @@ - - + + diff --git a/backend/app/assets/stylesheets/spree/backend/shared/_icons.scss b/backend/app/assets/stylesheets/spree/backend/shared/_icons.scss index 8a207201dd1..eda96faea28 100644 --- a/backend/app/assets/stylesheets/spree/backend/shared/_icons.scss +++ b/backend/app/assets/stylesheets/spree/backend/shared/_icons.scss @@ -1,10 +1,12 @@ // Some fixes for fontwesome stylesheets -[class^="icon-"], [class*=" icon-"] { +[class^="icon-"], +[class*=" icon-"] { &:before { padding-right: 5px; } - &.button, &.icon_link { + &.button, + &.icon_link { width: auto; &:before { @@ -15,29 +17,53 @@ } .btn.fa { - font: normal normal $btn-font-weight #{$font-size-base}/#{$btn-line-height} "FontAwesome"; + font: normal normal $btn-font-weight #{$font-size-base}/#{$btn-line-height} + "FontAwesome"; } -.fa-email { @extend .fa-envelope } -.fa-resume { @extend .fa-refresh } -.fa-approve { @extend .fa-check } +.fa-email { + @extend .fa-envelope; +} +.fa-resume { + @extend .fa-refresh; +} +.fa-approve { + @extend .fa-check; +} .fa-remove, .fa-cancel, -.fa-void { @extend .fa-times } +.fa-void { + @extend .fa-times; +} -.fa-failure { @extend .fa-thumbs-down } +.fa-failure { + @extend .fa-thumbs-down; +} -.fa-trash { @extend .fa-trash-o } +.fa-trash { + @extend .fa-trash-o; +} -.fa-capture { @extend .fa-thumbs-up } -.fa-credit { @extend .fa-check } -.fa-approve { @extend .fa-check } -.fa-icon-cogs { @extend .fa-cogs } +.fa-capture { + @extend .fa-thumbs-up; +} +.fa-credit { + @extend .fa-check; +} +.fa-approve { + @extend .fa-check; +} +.fa-icon-cogs { + @extend .fa-cogs; +} .fa-ok, -.fa-icon-ok { @extend .fa-check } +.fa-icon-ok { + @extend .fa-check; +} -button, a { +button, +a { &.fa:before { padding-right: 5px; } @@ -49,11 +75,37 @@ button, a { .icon-external-link { @extend .fa; } -.icon-user { @extend .fa-user; } -.icon-signout { @extend .fa-sign-out; } -.icon-external-link { @extend .fa-external-link; } +.icon-user { + @extend .fa-user; +} +.icon-signout { + @extend .fa-sign-out; +} +.icon-external-link { + @extend .fa-external-link; +} // Avoid ugly default browser font (usually a serif) when an element has an icon AND text .fa { font-family: "FontAwesome", $font-family-base !important; } + +.content-wrapper { + svg.icon { + width: 16px; + height: 16px; + fill: currentColor; + } + + .icon_button, + .icon_link { + &:has(svg) { + display: inline-flex; + width: 20px; + height: 20px; + align-items: center; + gap: 0.25rem; + vertical-align: -0.3em; + } + } +} diff --git a/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss b/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss index 3583ec49013..73abccc8fa3 100644 --- a/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss +++ b/backend/app/assets/stylesheets/spree/backend/shared/_tables.scss @@ -23,6 +23,14 @@ table { padding: 3px 0; } + .icon_link:has(svg) { + color: $color-dark; + + &:hover { + color: $color-dark-light; + } + } + &.actions { text-align: right; padding-left: 1.25rem; @@ -48,17 +56,33 @@ table { } } - button[class*='fa-'] { - color: $link-color; + button[class*="fa-"], + button.icon_button:has(.fa) { + padding: 0 !important; + } + + button[class*="fa-"], + .icon_button { + color: $color-dark; background: transparent; border: 0 none; - padding: 0 !important; &:hover { + color: $color-dark-light; background: transparent; } } + .icon_link:has(svg), + .icon_button:has(svg) { + padding: 2px; + + + .icon_link:has(svg), + + .icon_button:has(svg) { + margin-left: 2px; + } + } + .fa-envelope-alt, .fa-eye-open { color: $link-color; padding-left: 0px; @@ -68,20 +92,35 @@ table { } } - .fa-trash:hover, .fa-void:hover, .fa-failure:hover { + .fa-trash:hover, + .fa-void:hover, + .fa-failure:hover, + [data-action="remove"]:hover { color: theme-color("danger"); } - .fa-cancel:hover { + .fa-cancel:hover, + [data-action="cancel"]:hover { color: theme-color("warning"); } - .fa-edit:hover, .fa-capture:hover, .fa-ok:hover, .fa-plus:hover, - .fa-save:hover, .fa-arrows-h:hover, .fa-check:hover { + .fa-edit:hover, + .fa-capture:hover, + .fa-ok:hover, + .fa-plus:hover, + .fa-save:hover, + .fa-arrows-h:hover, + .fa-check:hover, + [data-action="save"]:hover, + [data-action="edit"]:hover, + [data-action="capture"]:hover, + [data-action="add"]:hover, + [data-action="new"]:hover { color: theme-color("success"); } - .fa-copy:hover { + .fa-copy:hover, + [data-action="clone"]:hover { color: theme-color("warning"); } @@ -89,7 +128,8 @@ table { color: theme-color("success"); } - .fa-thumbs-down:hover { + .fa-thumbs-down:hover, + [data-action="void"]:hover { color: theme-color("danger"); } } diff --git a/backend/app/helpers/spree/admin/adjustments_helper.rb b/backend/app/helpers/spree/admin/adjustments_helper.rb index 7fb6f626eb8..2d277d80c1c 100644 --- a/backend/app/helpers/spree/admin/adjustments_helper.rb +++ b/backend/app/helpers/spree/admin/adjustments_helper.rb @@ -5,7 +5,7 @@ module Admin module AdjustmentsHelper def adjustment_state(adjustment) icon = adjustment.finalized? ? "lock" : "unlock" - content_tag(:span, "", class: "fa fa-#{icon}") + solidus_icon(icon) end def display_adjustable(adjustable) diff --git a/backend/app/helpers/spree/admin/navigation_helper.rb b/backend/app/helpers/spree/admin/navigation_helper.rb index 30aa763a1df..20713f5f1a6 100644 --- a/backend/app/helpers/spree/admin/navigation_helper.rb +++ b/backend/app/helpers/spree/admin/navigation_helper.rb @@ -121,13 +121,9 @@ def link_to_delete(resource, options = {}) def link_to_with_icon(icon_name, text, url, options = {}) options[:class] = "#{options[:class]} icon_link with-tip".strip - if icon_name.starts_with?("ri-") - svg_map = image_path("spree/backend/themes/solidus_admin/remixicon.symbol.svg") - icon_tag = tag.svg( - tag.use("xlink:href": "#{svg_map}##{icon_name}"), - "aria-hidden": true, - style: "fill: currentColor;" - ) + icon = icon_for(icon_name) + if icon.starts_with?("ri-") + icon_tag = remix_icon(icon) else options[:class] << " fa fa-#{icon_name}" icon_tag = "".html_safe @@ -141,7 +137,28 @@ def link_to_with_icon(icon_name, text, url, options = {}) end def solidus_icon(icon_name) - icon_name ? content_tag(:i, "", class: icon_name) : "" + if icon_name&.include?("fa-") + icon_name = icon_name.gsub(/(fa\s|fa-)/, "") + Spree.deprecator.warn "Using FontAwesome icon classes with solidus_icon is deprecated. Please use just `#{icon_name}` instead." + end + icon = icon_for(icon_name) + if icon&.starts_with?("ri-") + remix_icon(icon) + elsif icon_name + content_tag(:i, "", class: "fa fa-#{icon_name}") + else + "" + end + end + + def remix_icon(icon_name) + svg_map = image_path("spree/backend/themes/solidus_admin/remixicon.symbol.svg") + tag.svg( + tag.use(href: "#{svg_map}##{icon_name}"), + "aria-hidden": true, + style: "fill: currentColor", + class: "icon" + ) end def configurations_menu_item(link_text, url, description = "") @@ -174,6 +191,12 @@ def settings_tab_item(link_text, url, options = {}) link_to(link_text, url) end end + + private + + def icon_for(icon_name) + Spree::Backend::Config.admin_updated_navbar ? Spree::Backend::REMIX_ICONS.fetch(icon_name, icon_name) : icon_name + end end end end diff --git a/backend/app/views/spree/admin/orders/_shipment_manifest.html.erb b/backend/app/views/spree/admin/orders/_shipment_manifest.html.erb index 39eb7719f93..0155501e523 100644 --- a/backend/app/views/spree/admin/orders/_shipment_manifest.html.erb +++ b/backend/app/views/spree/admin/orders/_shipment_manifest.html.erb @@ -24,8 +24,8 @@ <% if can? :update, item %> - <%= button_tag '', class: 'split-item icon_link fa fa-arrows-h no-text with-tip', data: { action: 'edit', 'variant-id' => item.variant.id }, title: t('spree.actions.split'), type: :button %> - <%= button_tag '', class: 'delete-item fa fa-trash no-text with-tip', data: { action: 'remove', 'variant-id' => item.variant.id }, title: t('spree.actions.delete'), type: :button %> + <%= button_tag class: 'split-item icon_button no-text with-tip', data: { action: 'edit', 'variant-id' => item.variant.id }, title: t('spree.actions.split'), type: :button do %><%= solidus_icon('arrows-h') %><% end %> + <%= button_tag class: 'delete-item icon_button no-text with-tip', data: { action: 'remove', 'variant-id' => item.variant.id }, title: t('spree.actions.delete'), type: :button do %><%= solidus_icon('trash') %><% end %> <% end %> diff --git a/backend/app/views/spree/admin/payments/_log_entries.html.erb b/backend/app/views/spree/admin/payments/_log_entries.html.erb index 48567e58001..3d445cdf993 100644 --- a/backend/app/views/spree/admin/payments/_log_entries.html.erb +++ b/backend/app/views/spree/admin/payments/_log_entries.html.erb @@ -21,7 +21,7 @@
<%= entry.parsed_details.message %>
- '> + <%= solidus_icon(entry.parsed_details.success? ? 'check' : 'remove') %> <% end %> diff --git a/backend/app/views/spree/admin/prices/_master_variant_table.html.erb b/backend/app/views/spree/admin/prices/_master_variant_table.html.erb index 9ec6d3dd993..bce7b966ad5 100644 --- a/backend/app/views/spree/admin/prices/_master_variant_table.html.erb +++ b/backend/app/views/spree/admin/prices/_master_variant_table.html.erb @@ -29,7 +29,6 @@ <%= link_to_edit(price, no_text: true) unless price.discarded? %> <% end %> <% if can?(:destroy, price) %> -   <%= link_to_delete(price, no_text: true) unless price.discarded? %> <% end %> diff --git a/backend/app/views/spree/admin/prices/_table.html.erb b/backend/app/views/spree/admin/prices/_table.html.erb index 604810ec848..2a8ae00c2ab 100644 --- a/backend/app/views/spree/admin/prices/_table.html.erb +++ b/backend/app/views/spree/admin/prices/_table.html.erb @@ -24,7 +24,6 @@ <%= link_to_edit(price, no_text: true) unless price.discarded? %> <% end %> <% if can?(:destroy, price) %> -   <%= link_to_delete(price, no_text: true) unless price.discarded? %> <% end %> diff --git a/backend/app/views/spree/admin/products/index.html.erb b/backend/app/views/spree/admin/products/index.html.erb index 4a009a96f4d..055b5e33c51 100644 --- a/backend/app/views/spree/admin/products/index.html.erb +++ b/backend/app/views/spree/admin/products/index.html.erb @@ -87,9 +87,7 @@ <%= product.display_price&.to_html %> <%= link_to_edit product, no_text: true, class: 'edit' if can?(:edit, product) && !product.deleted? %> -   <%= link_to_clone product, no_text: true, class: 'clone' if can?(:clone, product) %> -   <%= link_to_delete product, no_text: true if can?(:destroy, product) && !product.deleted? %> diff --git a/backend/app/views/spree/admin/shared/_datepicker.html.erb b/backend/app/views/spree/admin/shared/_datepicker.html.erb index f40fe8a76fd..f5691d4e385 100644 --- a/backend/app/views/spree/admin/shared/_datepicker.html.erb +++ b/backend/app/views/spree/admin/shared/_datepicker.html.erb @@ -1,7 +1,7 @@
- <%= solidus_icon('fa fa-calendar') %> + <%= solidus_icon('calendar') %>
<%= f.text_field date_attr, value: datepicker_field_value(f.object.public_send(date_attr)), class: 'form-control datepicker' %> diff --git a/backend/app/views/spree/admin/variants/_table.html.erb b/backend/app/views/spree/admin/variants/_table.html.erb index a65862ce30d..b85f352fdfb 100644 --- a/backend/app/views/spree/admin/variants/_table.html.erb +++ b/backend/app/views/spree/admin/variants/_table.html.erb @@ -33,7 +33,6 @@ <%= link_to_edit(variant, no_text: true) unless variant.deleted? %> <% end %> <% if can?(:destroy, variant) %> -   <%= link_to_delete(variant, no_text: true) unless variant.deleted? %> <% end %> diff --git a/backend/lib/spree/backend/engine.rb b/backend/lib/spree/backend/engine.rb index 4f8c3d53bfd..55eb56f5966 100644 --- a/backend/lib/spree/backend/engine.rb +++ b/backend/lib/spree/backend/engine.rb @@ -1,6 +1,7 @@ # frozen_string_literal: true require "spree/backend/config" +require "spree/backend/remix_icons" module Spree module Backend diff --git a/backend/lib/spree/backend/remix_icons.rb b/backend/lib/spree/backend/remix_icons.rb new file mode 100644 index 00000000000..5f36707f478 --- /dev/null +++ b/backend/lib/spree/backend/remix_icons.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +module Spree + module Backend + REMIX_ICONS = { + "arrows-h" => "ri-arrow-left-right-line", + "calendar" => "ri-calendar-line", + "cancel" => "ri-close-line", + "capture" => "ri-thumb-up-line", + "check" => "ri-check-line", + "copy" => "ri-file-copy-line", + "edit" => "ri-edit-line", + "email" => "ri-mail-line", + "file" => "ri-file-line", + "lock" => "ri-lock-line", + "ok" => "ri-check-line", + "plus" => "ri-add-line", + "refresh" => "ri-refresh-line", + "remove" => "ri-delete-bin-7-line", + "reply" => "ri-reply-line", + "send" => "ri-plane-plane-line", + "th-large" => "ri-function-line", + "trash" => "ri-delete-bin-7-line", + "unlock" => "ri-lock-unlock-line", + "void" => "ri-close-circle-line", + }.freeze + end +end diff --git a/backend/spec/helpers/admin/navigation_helper_spec.rb b/backend/spec/helpers/admin/navigation_helper_spec.rb index 7e5a55bc73c..02dab9bc574 100644 --- a/backend/spec/helpers/admin/navigation_helper_spec.rb +++ b/backend/spec/helpers/admin/navigation_helper_spec.rb @@ -152,9 +152,56 @@ describe "#solidus_icon" do context "if given an icon_name" do - subject(:solidus_icon) { helper.solidus_icon("example-icon-name") } + subject(:solidus_icon) { helper.solidus_icon(icon_name) } - it { is_expected.to eq "" } + context "when the icon is a fontawesome icon" do + let(:icon_name) { "fa fa-example-icon-name" } + + it "returns an fa icon tag" do + Spree.deprecator.silence do + is_expected.to eq '' + end + end + + it "is deprecated" do + expect(Spree.deprecator).to receive(:warn) + subject + end + end + + context "when the icon is a remix icon" do + let(:icon_name) { "ri-example-icon-name" } + + it "returns a svg icon" do + is_expected.to have_css 'svg.icon use[href*="#ri-example-icon-name"]' + end + end + + context "when the icon is a generic icon name" do + context "when the icon name maps to a remix icon" do + let(:icon_name) { "copy" } + + context "when updated navbar is disabled" do + before do + stub_spree_preferences(Spree::Backend::Config, admin_updated_navbar: false) + end + + it "returns an fa icon tag" do + is_expected.to eq '' + end + end + + context "when updated navbar is enabled" do + before do + stub_spree_preferences(Spree::Backend::Config, admin_updated_navbar: true) + end + + it "returns a svg icon" do + is_expected.to have_css 'svg.icon use[href*="#ri-file-copy-line"]' + end + end + end + end end context "if not given nil icon_name" do