diff --git a/spring-boot-admin-server-ui/src/main/frontend/components.d.ts b/spring-boot-admin-server-ui/src/main/frontend/components.d.ts
index 604df6ad55e..f79ecaefebb 100644
--- a/spring-boot-admin-server-ui/src/main/frontend/components.d.ts
+++ b/spring-boot-admin-server-ui/src/main/frontend/components.d.ts
@@ -3,7 +3,7 @@
// Generated by unplugin-vue-components
// Read more: https://github.com/vuejs/core/pull/3399
// biome-ignore lint: disable
-export {}
+export {};
/* prettier-ignore */
declare module 'vue' {
diff --git a/spring-boot-admin-server-ui/src/main/frontend/components/sba-accordion.stories.ts b/spring-boot-admin-server-ui/src/main/frontend/components/sba-accordion.stories.ts
new file mode 100644
index 00000000000..4e7f8b76a28
--- /dev/null
+++ b/spring-boot-admin-server-ui/src/main/frontend/components/sba-accordion.stories.ts
@@ -0,0 +1,239 @@
+/*
+ * Copyright 2014-2025 the original author or authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+import { ref } from 'vue';
+
+import SbaAccordion from './sba-accordion.vue';
+
+export default {
+ component: SbaAccordion,
+ title: 'Components/Accordion',
+};
+
+const Template = (args) => {
+ return {
+ components: { SbaAccordion },
+ setup() {
+ const isOpen = ref(args.modelValue ?? true);
+ return { args, isOpen };
+ },
+ template: `
+
+
+ ${args.title || 'Accordion Title'}
+
+
+ ${args.actions}
+
+
+ ${args.slot}
+
+
+
+ Current state: {{ isOpen ? 'Open' : 'Closed' }}
+
+ `,
+ };
+};
+
+export const DefaultOpen = {
+ render: Template,
+
+ args: {
+ modelValue: true,
+ title: 'Application Information',
+ slot: `
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Phasellus vitae dolor ac ante ornare pharetra.
+ Proin laoreet ex et lacinia hendrerit. Fusce sed justo at nulla pellentesque maximus sed at diam.
+ Suspendisse sem lorem, lobortis vel orci quis, efficitur porta massa. In vel neque justo.
+ Maecenas dapibus quam ut nisl porta, molestie egestas felis maximus.
+ `,
+ },
+};
+
+export const DefaultClosed = {
+ render: Template,
+
+ args: {
+ modelValue: false,
+ title: 'System Properties',
+ slot: `
+ This content is initially hidden. Click the title to expand the accordion.
+ `,
+ },
+};
+
+export const WithKeyValueTable = {
+ render: Template,
+
+ args: {
+ modelValue: true,
+ title: 'Health Details',
+ slot: `
+
+
+
Status
+ UP
+
+
+
Disk Space
+ 10.5 GB free
+
+
+
Database
+ Connected
+
+
+
Memory
+ 512 MB / 2 GB
+
+
`,
+ },
+};
+
+export const WithActions = {
+ render: Template,
+
+ args: {
+ modelValue: true,
+ title: 'Configuration Settings',
+ actions:
+ 'Edit ',
+ slot: `
+ Configuration content with action buttons in the header.
+ `,
+ },
+};
+
+export const WithId = {
+ render: (args) => {
+ return {
+ components: { SbaAccordion },
+ setup() {
+ const isOpen = ref(args.modelValue ?? true);
+ return { args, isOpen };
+ },
+ template: `
+
+
+ This accordion has an ID and will persist its state in localStorage.
+ Try toggling it and refreshing the page.
+
+
+
+ ${args.title || 'Persisted Accordion'}
+
+
+ ${args.slot}
+
+
+
+ Current state: {{ isOpen ? 'Open' : 'Closed' }}
+
+ LocalStorage key: de.codecentric.spring-boot-admin.accordion.${args.id}.open
+
+
+ `,
+ };
+ },
+
+ args: {
+ id: 'storybook-example',
+ modelValue: true,
+ title: 'Persisted State Example',
+ slot: `
+ This accordion's open/closed state is stored in localStorage using the ID "storybook-example".
+ Try toggling it and refreshing the browser to see the state persist.
+ `,
+ },
+};
+
+export const MultipleAccordions = {
+ render: (args) => {
+ return {
+ components: { SbaAccordion },
+ setup() {
+ const accordion1Open = ref(true);
+ const accordion2Open = ref(false);
+ const accordion3Open = ref(true);
+ return { args, accordion1Open, accordion2Open, accordion3Open };
+ },
+ template: `
+
+
+ First Accordion
+
+ Content of the first accordion.
+
+
+
+
+ Second Accordion
+
+ Content of the second accordion (initially closed).
+
+
+
+
+ Third Accordion
+
+ With Actions
+
+
+ Content of the third accordion with actions.
+
+
+
+
+ States:
+ 1: {{ accordion1Open ? 'Open' : 'Closed' }} |
+ 2: {{ accordion2Open ? 'Open' : 'Closed' }} |
+ 3: {{ accordion3Open ? 'Open' : 'Closed' }}
+
+
+ `,
+ };
+ },
+
+ args: {},
+};
+
+export const NestedContent = {
+ render: Template,
+
+ args: {
+ modelValue: true,
+ title: 'Advanced Configuration',
+ slot: `
+
+
+
Server Settings
+
+ Port: 8080
+ Context Path: /admin
+ SSL Enabled: false
+
+
+
+
Monitoring
+
+ Interval: 10000ms
+ Timeout: 5000ms
+ Retries: 3
+
+
+
`,
+ },
+};
diff --git a/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/sba-accordion.vue b/spring-boot-admin-server-ui/src/main/frontend/components/sba-accordion.vue
similarity index 84%
rename from spring-boot-admin-server-ui/src/main/frontend/views/instances/details/sba-accordion.vue
rename to spring-boot-admin-server-ui/src/main/frontend/components/sba-accordion.vue
index 28c06c41c0c..905692e9b23 100644
--- a/spring-boot-admin-server-ui/src/main/frontend/views/instances/details/sba-accordion.vue
+++ b/spring-boot-admin-server-ui/src/main/frontend/components/sba-accordion.vue
@@ -18,10 +18,14 @@
@@ -31,10 +35,14 @@
@@ -49,6 +57,7 @@
+
+