diff --git a/app/components/op_primer/flash_component.erb b/app/components/op_primer/flash_component.erb
index 4682dfebf99..2f2cb190f3a 100644
--- a/app/components/op_primer/flash_component.erb
+++ b/app/components/op_primer/flash_component.erb
@@ -31,7 +31,11 @@ See COPYRIGHT and LICENSE files for more details.
render(Primer::BaseComponent.new(
tag: :div,
classes: "op-primer-flash--item",
- data: { unique_key: @unique_key }.compact
+ data: {
+ "flash-target": "item",
+ "autohide": @autohide,
+ unique_key: @unique_key
+ }.compact
)) do
render_parent
end
diff --git a/app/components/op_primer/flash_component.rb b/app/components/op_primer/flash_component.rb
index c93edcae9a7..fed84bf511f 100644
--- a/app/components/op_primer/flash_component.rb
+++ b/app/components/op_primer/flash_component.rb
@@ -39,6 +39,8 @@ module OpPrimer
system_arguments[:dismiss_scheme] ||= :remove
system_arguments[:dismiss_label] ||= I18n.t(:button_close)
+ @autohide = system_arguments[:scheme] == :success && system_arguments[:dismiss_scheme] != :none
+
super
end
end
diff --git a/app/views/layouts/_flashes.html.erb b/app/views/layouts/_flashes.html.erb
index c37aa9f0cff..8f9bcd92940 100644
--- a/app/views/layouts/_flashes.html.erb
+++ b/app/views/layouts/_flashes.html.erb
@@ -5,3 +5,6 @@
data-flash-autohide-value="<%= User.current.pref.auto_hide_popups? %>">
<%= render_flash_messages %>
+
+<%# Flash modals render modal components %>
+<%= render_flash_modal %>
diff --git a/app/views/layouts/base.html.erb b/app/views/layouts/base.html.erb
index b864e15fb9f..0895f2c65f5 100644
--- a/app/views/layouts/base.html.erb
+++ b/app/views/layouts/base.html.erb
@@ -118,8 +118,6 @@ See COPYRIGHT and LICENSE files for more details.
<%= content_tag :main, id: "content-wrapper", class: initial_classes, data: stimulus_content_data do %>
<%= render partial: "layouts/flashes" %>
- <%# Flash modals render modal components %>
- <%= render_flash_modal %>
<% if show_onboarding_modal? %>
{
- jQuery('.op-toast.autohide-toaster').remove();
- }, 5000);
-}
-
function addClickEventToAllErrorMessages() {
jQuery('a.afocus').each(function () {
const target = jQuery(this);
diff --git a/frontend/src/stimulus/controllers/flash.controller.ts b/frontend/src/stimulus/controllers/flash.controller.ts
new file mode 100644
index 00000000000..61178e1ca0a
--- /dev/null
+++ b/frontend/src/stimulus/controllers/flash.controller.ts
@@ -0,0 +1,24 @@
+import { ApplicationController } from 'stimulus-use';
+
+export const SUCCESS_AUTOHIDE_TIMEOUT = 5000;
+
+export default class FlashController extends ApplicationController {
+ static values = {
+ autohide: Boolean,
+ };
+
+ declare autohideValue:boolean;
+
+ static targets = [
+ 'item',
+ ];
+
+ declare readonly itemTargets:HTMLElement;
+
+ itemTargetConnected(element:HTMLElement) {
+ const autohide = element.dataset.autohide === 'true';
+ if (this.autohideValue && autohide) {
+ setTimeout(() => element.remove(), SUCCESS_AUTOHIDE_TIMEOUT);
+ }
+ }
+}
diff --git a/frontend/src/stimulus/setup.ts b/frontend/src/stimulus/setup.ts
index e1789326e07..59fa7f5045b 100644
--- a/frontend/src/stimulus/setup.ts
+++ b/frontend/src/stimulus/setup.ts
@@ -10,6 +10,7 @@ import PollForChangesController from './controllers/poll-for-changes.controller'
import TableHighlightingController from './controllers/table-highlighting.controller';
import OpShowWhenCheckedController from './controllers/show-when-checked.controller';
import OpShowWhenValueSelectedController from './controllers/show-when-value-selected.controller';
+import FlashController from './controllers/flash.controller';
declare global {
interface Window {
@@ -31,6 +32,7 @@ instance.register('menus--main', MainMenuController);
instance.register('show-when-checked', OpShowWhenCheckedController);
instance.register('disable-when-checked', OpDisableWhenCheckedController);
instance.register('show-when-value-selected', OpShowWhenValueSelectedController);
+instance.register('flash', FlashController);
instance.register('print', PrintController);
instance.register('refresh-on-form-changes', RefreshOnFormChangesController);
instance.register('async-dialog', AsyncDialogController);