diff --git a/admin/app/components/solidus_admin/ui/panel/component.html.erb b/admin/app/components/solidus_admin/ui/panel/component.html.erb
new file mode 100644
index 00000000000..d6dc94afd75
--- /dev/null
+++ b/admin/app/components/solidus_admin/ui/panel/component.html.erb
@@ -0,0 +1,36 @@
+
+ <% if @title %>
+
+ <%= @title %>
+ <%= render component('ui/toggletip').new(guide: @title_hint, position: :left) if @title_hint %>
+
+ <% end %>
+
+ <% if content? %>
+
+ <%= content %>
+
+ <% end %>
+
+ <% if @actions %>
+
+ <%= @actions %>
+
+ <% end %>
+
diff --git a/admin/app/components/solidus_admin/ui/panel/component.js b/admin/app/components/solidus_admin/ui/panel/component.js
new file mode 100644
index 00000000000..b6e2b996c67
--- /dev/null
+++ b/admin/app/components/solidus_admin/ui/panel/component.js
@@ -0,0 +1,14 @@
+import { Controller } from '@hotwired/stimulus'
+
+export default class extends Controller {
+ static targets = ['output']
+
+ typed(event) {
+ this.text = event.currentTarget.value
+ this.render()
+ }
+
+ render() {
+ this.outputTarget.innerText = this.text
+ }
+}
diff --git a/admin/app/components/solidus_admin/ui/panel/component.rb b/admin/app/components/solidus_admin/ui/panel/component.rb
new file mode 100644
index 00000000000..ac0ecf822d1
--- /dev/null
+++ b/admin/app/components/solidus_admin/ui/panel/component.rb
@@ -0,0 +1,13 @@
+# frozen_string_literal: true
+
+class SolidusAdmin::UI::Panel::Component < SolidusAdmin::BaseComponent
+ # @param title [String] the title of the panel
+ # @param title_hint [String] the title hint of the panel
+ # @param actions [String] the rendered html for the actions section
+ # @block content [String] the rendered html for the content section
+ def initialize(title: nil, title_hint: nil, actions: nil)
+ @title = title
+ @title_hint = title_hint
+ @actions = actions
+ end
+end
diff --git a/admin/app/components/solidus_admin/ui/panel/component.yml b/admin/app/components/solidus_admin/ui/panel/component.yml
new file mode 100644
index 00000000000..6fcfbdd6df7
--- /dev/null
+++ b/admin/app/components/solidus_admin/ui/panel/component.yml
@@ -0,0 +1,4 @@
+# Add your component translations here.
+# Use the translation in the example in your template with `t(".hello")`.
+en:
+ hello: "Hello world!"
diff --git a/admin/spec/components/previews/solidus_admin/ui/panel/component_preview.rb b/admin/spec/components/previews/solidus_admin/ui/panel/component_preview.rb
new file mode 100644
index 00000000000..c6e96d0e5c5
--- /dev/null
+++ b/admin/spec/components/previews/solidus_admin/ui/panel/component_preview.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+
+# @component "ui/panel"
+class SolidusAdmin::UI::Panel::ComponentPreview < ViewComponent::Preview
+ include SolidusAdmin::Preview
+
+ def overview
+ render_with_template
+ end
+end
diff --git a/admin/spec/components/previews/solidus_admin/ui/panel/component_preview/overview.html.erb b/admin/spec/components/previews/solidus_admin/ui/panel/component_preview/overview.html.erb
new file mode 100644
index 00000000000..409e934ba16
--- /dev/null
+++ b/admin/spec/components/previews/solidus_admin/ui/panel/component_preview/overview.html.erb
@@ -0,0 +1,59 @@
+
+
+ Content only
+
+
+ <%= render current_component.new do %>
+
+ <% end %>
+
+
+
+
+ With title
+
+
+ <%= render current_component.new(title: "SEO") do %>
+
+ <% end %>
+
+
+
+
+ With title and hint
+
+
+ <%= render current_component.new(title: "SEO", title_hint: "Search Engine Optimization") do %>
+
+ <% end %>
+
+
+
+
+ With title, hint, and actions
+
+
+ <%= render current_component.new(title: "SEO", title_hint: "Search Engine Optimization", actions: "foo action") do %>
+
+ <% end %>
+
+
+
+
+ With no content
+
+
+ <%= render current_component.new(title: "SEO", title_hint: "Search Engine Optimization", actions: "foo action") %>
+
diff --git a/admin/spec/components/solidus_admin/ui/panel/component_spec.rb b/admin/spec/components/solidus_admin/ui/panel/component_spec.rb
new file mode 100644
index 00000000000..1da12566322
--- /dev/null
+++ b/admin/spec/components/solidus_admin/ui/panel/component_spec.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe SolidusAdmin::UI::Panel::Component, type: :component do
+ it "renders the overview preview" do
+ render_preview(:overview)
+ end
+end