From bbae4e327dfbf9df764edfc337c954335ac9d756 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Tue, 29 Apr 2025 19:54:04 +0200 Subject: [PATCH 1/2] Create UI component for alerts --- .../solidus_admin/ui/alert/component.html.erb | 35 ++++++++++++++ .../solidus_admin/ui/alert/component.js | 20 ++++++++ .../solidus_admin/ui/alert/component.rb | 47 +++++++++++++++++++ .../solidus_admin/ui/alert/component.yml | 2 + admin/config/tailwind.config.js | 1 + .../ui/alert/component_preview.rb | 10 ++++ .../alert/component_preview/overview.html.erb | 41 ++++++++++++++++ .../solidus_admin/ui/alert/component_spec.rb | 9 ++++ 8 files changed, 165 insertions(+) create mode 100644 admin/app/components/solidus_admin/ui/alert/component.html.erb create mode 100644 admin/app/components/solidus_admin/ui/alert/component.js create mode 100644 admin/app/components/solidus_admin/ui/alert/component.rb create mode 100644 admin/app/components/solidus_admin/ui/alert/component.yml create mode 100644 admin/spec/components/previews/solidus_admin/ui/alert/component_preview.rb create mode 100644 admin/spec/components/previews/solidus_admin/ui/alert/component_preview/overview.html.erb create mode 100644 admin/spec/components/solidus_admin/ui/alert/component_spec.rb diff --git a/admin/app/components/solidus_admin/ui/alert/component.html.erb b/admin/app/components/solidus_admin/ui/alert/component.html.erb new file mode 100644 index 00000000000..92bd42b5862 --- /dev/null +++ b/admin/app/components/solidus_admin/ui/alert/component.html.erb @@ -0,0 +1,35 @@ +
-animation-class="-translate-y-[150%] opacity-0" + data-<%= stimulus_id %>-transition-value="<%= Rails.env.test? ? 1000 : 500 %>" + role="dialog" + aria-label="<%= @title %>" + aria-live="polite" +> +
+
+ <%= icon %> +
+
+

<%= @title %>

+

<%= @description.html_safe %>

+
+
+
+ +
+
diff --git a/admin/app/components/solidus_admin/ui/alert/component.js b/admin/app/components/solidus_admin/ui/alert/component.js new file mode 100644 index 00000000000..de1cecf8644 --- /dev/null +++ b/admin/app/components/solidus_admin/ui/alert/component.js @@ -0,0 +1,20 @@ +import { Controller } from "@hotwired/stimulus" + +export default class extends Controller { + static targets = ["closeButton"] + static classes = ["animation"] + static values = { transition: Number } + + connect() { + this.closeButtonTarget.focus() + + requestAnimationFrame(() => { + this.element.classList.remove(...this.animationClasses) + }) + } + + close() { + this.element.classList.add(...this.animationClasses) + setTimeout(() => this.element.remove(), this.transitionValue) + } +} diff --git a/admin/app/components/solidus_admin/ui/alert/component.rb b/admin/app/components/solidus_admin/ui/alert/component.rb new file mode 100644 index 00000000000..c183eaf8659 --- /dev/null +++ b/admin/app/components/solidus_admin/ui/alert/component.rb @@ -0,0 +1,47 @@ +# frozen_string_literal: true + +class SolidusAdmin::UI::Alert::Component < SolidusAdmin::BaseComponent + SCHEMES = { + success: %w[ + border-forest bg-seafoam + ], + warning: %w[ + border-orange bg-sazerac + ], + danger: %w[ + border-red-500 bg-red-100 text-black + ], + info: %w[ + border-gray-500 bg-gray-50 + ], + } + + ICONS = { + success: { + name: "checkbox-circle-fill", + class: "fill-forest", + }, + warning: { + name: "error-warning-fill", + class: "fill-orange", + }, + danger: { + name: "error-warning-fill", + class: "fill-red-500", + }, + info: { + name: "information-fill", + class: "fill-gray-500", + }, + } + + def initialize(title:, description:, scheme: :success) + @title = title + @description = description + @scheme = scheme + end + + def icon + icon_tag(ICONS.dig(@scheme.to_sym, :name), class: "w-5 h-5 #{ICONS.dig(@scheme.to_sym, :class)}") + end +end diff --git a/admin/app/components/solidus_admin/ui/alert/component.yml b/admin/app/components/solidus_admin/ui/alert/component.yml new file mode 100644 index 00000000000..a97e4c40196 --- /dev/null +++ b/admin/app/components/solidus_admin/ui/alert/component.yml @@ -0,0 +1,2 @@ +en: + close: Close diff --git a/admin/config/tailwind.config.js b/admin/config/tailwind.config.js index 930a0db0792..aa2a497bbca 100644 --- a/admin/config/tailwind.config.js +++ b/admin/config/tailwind.config.js @@ -42,6 +42,7 @@ module.exports = { // Extra colors (not part of the original palette) "papaya-whip": "#f9e3d9", + sazerac: "#fcf0dd", // UI Red red: { diff --git a/admin/spec/components/previews/solidus_admin/ui/alert/component_preview.rb b/admin/spec/components/previews/solidus_admin/ui/alert/component_preview.rb new file mode 100644 index 00000000000..f89bc2dd395 --- /dev/null +++ b/admin/spec/components/previews/solidus_admin/ui/alert/component_preview.rb @@ -0,0 +1,10 @@ +# frozen_string_literal: true + +# @component "ui/toast" +class SolidusAdmin::UI::Alert::ComponentPreview < ViewComponent::Preview + include SolidusAdmin::Preview + + def overview + render_with_template + end +end diff --git a/admin/spec/components/previews/solidus_admin/ui/alert/component_preview/overview.html.erb b/admin/spec/components/previews/solidus_admin/ui/alert/component_preview/overview.html.erb new file mode 100644 index 00000000000..6bdd3b2389c --- /dev/null +++ b/admin/spec/components/previews/solidus_admin/ui/alert/component_preview/overview.html.erb @@ -0,0 +1,41 @@ +
+
+
+ Success +
+ +
+ <%= render current_component.new(scheme: :success, title: "Added Solidus T-Shirt", description: "Add another product or view product in a new window".html_safe) %> +
+
+ +
+
+ Warning +
+ +
+ <%= render current_component.new(scheme: :warning, title: "No active stock locations left", description: "You can assign new active stock location here".html_safe) %> +
+
+ +
+
+ Danger +
+ +
+ <%= render current_component.new(scheme: :danger, title: "Request was not completed", description: "Cannot destroy default store") %> +
+
+ +
+
+ Info +
+ +
+ <%= render current_component.new(scheme: :info, title: "Locales available", description: "Did you know you can update storefront locales here?".html_safe) %> +
+
+
diff --git a/admin/spec/components/solidus_admin/ui/alert/component_spec.rb b/admin/spec/components/solidus_admin/ui/alert/component_spec.rb new file mode 100644 index 00000000000..0927fefcb34 --- /dev/null +++ b/admin/spec/components/solidus_admin/ui/alert/component_spec.rb @@ -0,0 +1,9 @@ +# frozen_string_literal: true + +require "spec_helper" + +RSpec.describe SolidusAdmin::UI::Alert::Component, type: :component do + it "renders the overview preview" do + render_preview(:overview) + end +end From 74ca15d863f19961f14ceb406b3d8036f939c7a7 Mon Sep 17 00:00:00 2001 From: Eugene Chaikin Date: Mon, 5 May 2025 14:02:29 +0200 Subject: [PATCH 2/2] Share alert animation controller between alert and toast components --- .../solidus_admin/ui/alert/component.html.erb | 10 +++++----- .../solidus_admin/ui/toast/component.html.erb | 10 +++++----- .../solidus_admin/ui/toast/component.js | 20 ------------------- .../alert_animation_controller.js} | 0 4 files changed, 10 insertions(+), 30 deletions(-) delete mode 100644 admin/app/components/solidus_admin/ui/toast/component.js rename admin/app/{components/solidus_admin/ui/alert/component.js => javascript/solidus_admin/controllers/alert_animation_controller.js} (100%) diff --git a/admin/app/components/solidus_admin/ui/alert/component.html.erb b/admin/app/components/solidus_admin/ui/alert/component.html.erb index 92bd42b5862..a6a892fd2ae 100644 --- a/admin/app/components/solidus_admin/ui/alert/component.html.erb +++ b/admin/app/components/solidus_admin/ui/alert/component.html.erb @@ -5,9 +5,9 @@ transform -translate-y-[150%] opacity-0 duration-500 <%= SCHEMES.fetch(@scheme.to_sym).join(' ') %> " - data-controller="<%= stimulus_id %>" - data-<%= stimulus_id %>-animation-class="-translate-y-[150%] opacity-0" - data-<%= stimulus_id %>-transition-value="<%= Rails.env.test? ? 1000 : 500 %>" + data-controller="alert-animation" + data-alert-animation-animation-class="-translate-y-[150%] opacity-0" + data-alert-animation-transition-value="<%= Rails.env.test? ? 1000 : 500 %>" role="dialog" aria-label="<%= @title %>" aria-live="polite" @@ -26,8 +26,8 @@ type="button" title="<%= t(".close") %>" aria-label="<%= t(".close") %>" - data-action="<%= stimulus_id %>#close" - data-<%= stimulus_id %>-target="closeButton" + data-action="alert-animation#close" + data-alert-animation-target="closeButton" > <%= icon_tag('close-fill', class: "w-6 h-6 #{ICONS.dig(@scheme.to_sym, :class)}") %> diff --git a/admin/app/components/solidus_admin/ui/toast/component.html.erb b/admin/app/components/solidus_admin/ui/toast/component.html.erb index 6c382e18292..27b6a23d508 100644 --- a/admin/app/components/solidus_admin/ui/toast/component.html.erb +++ b/admin/app/components/solidus_admin/ui/toast/component.html.erb @@ -6,9 +6,9 @@ pointer-events-auto <%= SCHEMES.fetch(@scheme.to_sym).join(' ') %> " - data-controller="<%= stimulus_id %>" - data-<%= stimulus_id %>-animation-class="translate-y-full opacity-0" - data-<%= stimulus_id %>-transition-value="<%= Rails.env.test? ? 1000 : 500 %>" + data-controller="alert-animation" + data-alert-animation-animation-class="translate-y-full opacity-0" + data-alert-animation-transition-value="<%= Rails.env.test? ? 1000 : 500 %>" role="dialog" aria-label="<%= t(".#{@scheme}_label") %>" aria-live="polite" @@ -21,9 +21,9 @@ type="button" class="ml-2 align-text-bottom" title="<%= t('.close_text') %>" - data-action="<%= stimulus_id %>#close" + data-action="alert-animation#close" aria-label="<%= t('.close_text') %>" - data-<%= stimulus_id %>-target="closeButton" + data-alert-animation-target="closeButton" > <%= icon_tag('close-line', class: "w-[1.125rem] h-[1.125rem] fill-current") %> diff --git a/admin/app/components/solidus_admin/ui/toast/component.js b/admin/app/components/solidus_admin/ui/toast/component.js deleted file mode 100644 index de1cecf8644..00000000000 --- a/admin/app/components/solidus_admin/ui/toast/component.js +++ /dev/null @@ -1,20 +0,0 @@ -import { Controller } from "@hotwired/stimulus" - -export default class extends Controller { - static targets = ["closeButton"] - static classes = ["animation"] - static values = { transition: Number } - - connect() { - this.closeButtonTarget.focus() - - requestAnimationFrame(() => { - this.element.classList.remove(...this.animationClasses) - }) - } - - close() { - this.element.classList.add(...this.animationClasses) - setTimeout(() => this.element.remove(), this.transitionValue) - } -} diff --git a/admin/app/components/solidus_admin/ui/alert/component.js b/admin/app/javascript/solidus_admin/controllers/alert_animation_controller.js similarity index 100% rename from admin/app/components/solidus_admin/ui/alert/component.js rename to admin/app/javascript/solidus_admin/controllers/alert_animation_controller.js