diff --git a/frontend/src/lib/components/apps/components/display/AppAccordionList.svelte b/frontend/src/lib/components/apps/components/display/AppAccordionList.svelte
new file mode 100644
index 0000000000..5aa12072de
--- /dev/null
+++ b/frontend/src/lib/components/apps/components/display/AppAccordionList.svelte
@@ -0,0 +1,163 @@
+
+
+{#each Object.keys(css ?? {}) as key (key)}
+
+{/each}
+
+
+
+
+
+ {#if $app.subgrids?.[`${id}-0`]}
+ {#if Array.isArray(result) && result.length > 0}
+ {#each result ?? [] as value, index}
+
+
+ {#if activeIndex === index}
+
+ {
+ if (!inputs[id]) {
+ inputs[id] = { [index]: value }
+ } else {
+ inputs[id] = { ...inputs[id], [index]: value }
+ }
+ outputs?.inputs.set(inputs, true)
+ }}
+ onRemove={(id) => {
+ if (inputs?.[id] == undefined) {
+ return
+ }
+ if (index == 0) {
+ delete inputs[id]
+ inputs = { ...inputs }
+ } else {
+ delete inputs[id][index]
+ inputs[id] = { ...inputs[id] }
+ }
+ outputs?.inputs.set(inputs, true)
+ }}
+ {value}
+ {index}
+ >
+ {
+ if (!$connectingInput.opened) {
+ $selectedComponent = [id]
+ }
+ onFocus()
+ }}
+ />
+
+
+ {/if}
+
+ {/each}
+ {:else}
+
+
+
+ {#if !Array.isArray(result)}
+
Input data is not an array
+ {/if}
+ {/if}
+ {/if}
+
+
diff --git a/frontend/src/lib/components/apps/components/layout/AppTabs.svelte b/frontend/src/lib/components/apps/components/layout/AppTabs.svelte
index 4d702c5eef..ff85e7f87c 100644
--- a/frontend/src/lib/components/apps/components/layout/AppTabs.svelte
+++ b/frontend/src/lib/components/apps/components/layout/AppTabs.svelte
@@ -48,6 +48,8 @@
selectedTabIndex: 0
})
+ const titleBarHeight = 40; // Example height of a single accordion title bar in pixels
+
function handleTabSelection() {
selectedIndex = tabs?.indexOf(selected)
outputs?.selectedTabIndex.set(selectedIndex)
@@ -170,28 +172,72 @@
{/each}
- {/if}
-
-
- {#if $app.subgrids}
- {#each tabs ?? [] as _res, i}
-
{
- if (!$connectingInput.opened) {
- $selectedComponent = [id]
- handleTabSelection()
- }
- }}
- />
+ {:else if resolvedConfig.tabsKind == 'accordion'}
+
+ {#each tabs ?? [] as res, index}
+
+
+ {#if selected == res}
+
+ {
+ if (!$connectingInput.opened) {
+ $selectedComponent = [id]
+ handleTabSelection()
+ }
+ }}
+ />
+
+ {/if}
+
{/each}
- {/if}
-
+
+ {:else}
+
+ {#if $app.subgrids}
+ {#each tabs ?? [] as _res, i}
+ {
+ if (!$connectingInput.opened) {
+ $selectedComponent = [id]
+ handleTabSelection()
+ }
+ }}
+ />
+ {/each}
+ {/if}
+
+ {/if}
diff --git a/frontend/src/lib/components/apps/editor/component/Component.svelte b/frontend/src/lib/components/apps/editor/component/Component.svelte
index 264da8082d..6d4d0a396e 100644
--- a/frontend/src/lib/components/apps/editor/component/Component.svelte
+++ b/frontend/src/lib/components/apps/editor/component/Component.svelte
@@ -27,6 +27,7 @@
import AppJobIdLogComponent from '../../components/display/AppJobIdLogComponent.svelte'
import AppJobIdFlowStatus from '../../components/display/AppJobIdFlowStatus.svelte'
import AppCarouselList from '../../components/display/AppCarouselList.svelte'
+ import AppAccordionList from '../../components/display/AppAccordionList.svelte'
import AppAggridTableEe from '../../components/display/table/AppAggridTableEe.svelte'
import AppCustomComponent from '../../components/display/AppCustomComponent.svelte'
import AppStatCard from '../../components/display/AppStatCard.svelte'
@@ -871,6 +872,15 @@
{render}
bind:initializing
/>
+ {:else if component.type === 'accordionlistcomponent'}
+
{:else if component.type === 'statcomponent'}
export type SelectStepComponent = BaseComponent<'selectstepcomponent'>
export type CarouselListComponent = BaseComponent<'carousellistcomponent'>
+export type AccordionListComponent = BaseComponent<'accordionlistcomponent'>
export type StatisticCardComponent = BaseComponent<'statcomponent'>
export type MenuComponent = BaseComponent<'menucomponent'> & {
menuItems: (BaseAppComponent & ButtonComponent & GridItem)[]
@@ -351,6 +354,7 @@ export type TypedComponent =
| DownloadComponent
| ChartJsComponent
| CarouselListComponent
+ | AccordionListComponent
| PlotlyComponentV2
| ChartJsComponentV2
| StatisticCardComponent
@@ -446,7 +450,7 @@ const buttonColorOptions = [...BUTTON_COLORS]
export const selectOptions = {
buttonColorOptions,
- tabsKindOptions: ['tabs', 'sidebar', 'invisibleOnView'],
+ tabsKindOptions: ['tabs', 'sidebar', 'accordion', 'invisibleOnView'],
buttonSizeOptions: ['xs', 'sm', 'md', 'lg', 'xl'],
tableSearchOptions: ['By Component', 'By Runnable', 'Disabled'],
chartThemeOptions: ['theme1', 'theme2', 'theme3'],
@@ -2852,7 +2856,7 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
},
carousellistcomponent: {
name: 'Carousel List',
- icon: ListIcon,
+ icon: GalleryThumbnails,
documentationLink: `${documentationBaseUrl}/carousel`,
dims: '3:8-12:8' as AppComponentDimensions,
customCss: {
@@ -2878,6 +2882,25 @@ See date-fns format for more information. By default, it is 'dd.MM.yyyy HH:mm'
numberOfSubgrids: 1
}
},
+ accordionlistcomponent: {
+ name: 'Accordion List',
+ icon: ListCollapse,
+ documentationLink: `${documentationBaseUrl}/accordion`,
+ dims: '3:8-12:8' as AppComponentDimensions,
+ customCss: {
+ container: { class: '', style: '' }
+ },
+ initialData: {
+ configuration: {},
+ componentInput: {
+ type: 'static',
+ fieldType: 'array',
+ subFieldType: 'object',
+ value: [{ header: 'First', foo: 1 }, { header: 'Second', foo: 2 }, { header: 'Third', foo: 3 }] as object[]
+ },
+ numberOfSubgrids: 1
+ }
+ },
iconcomponent: {
name: 'Icon',
icon: Smile,
@@ -4152,6 +4175,17 @@ export const presetComponents = {
},
type: 'sidebartabscomponent'
},
+ accordiontabcomponent: {
+ name: 'Accordion Tabs',
+ icon: ListCollapse,
+ targetComponent: 'tabscomponent' as const,
+ configuration: {
+ tabsKind: {
+ value: 'accordion'
+ }
+ },
+ type: 'accordiontabcomponent'
+ },
invisibletabscomponent: {
name: 'Invisible Tabs',
icon: PanelTopInactive,
diff --git a/frontend/src/lib/components/apps/editor/component/sets.ts b/frontend/src/lib/components/apps/editor/component/sets.ts
index dc11ce9268..999db0b63a 100644
--- a/frontend/src/lib/components/apps/editor/component/sets.ts
+++ b/frontend/src/lib/components/apps/editor/component/sets.ts
@@ -3,7 +3,7 @@ import type { ComponentSet } from '../../types'
const tabs: ComponentSet = {
title: 'Tabs',
components: ['tabscomponent', 'conditionalwrapper'],
- presets: ['sidebartabscomponent', 'invisibletabscomponent']
+ presets: ['sidebartabscomponent', 'accordiontabcomponent', 'invisibletabscomponent']
} as const
const layout: ComponentSet = {
@@ -19,6 +19,7 @@ const layout: ComponentSet = {
'modalcomponent',
'steppercomponent',
'carousellistcomponent',
+ 'accordionlistcomponent',
'decisiontreecomponent',
'navbarcomponent',
'recomputeallcomponent'
diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/cssUtils.ts b/frontend/src/lib/components/apps/editor/componentsPanel/cssUtils.ts
index 81b450fd80..1e3f152c7e 100644
--- a/frontend/src/lib/components/apps/editor/componentsPanel/cssUtils.ts
+++ b/frontend/src/lib/components/apps/editor/componentsPanel/cssUtils.ts
@@ -299,6 +299,13 @@ export const customisationByComponent: Customisation[] = [
],
variables: []
},
+ {
+ components: ['accordionlistcomponent'],
+ selectors: [
+ { selector: '.wm-accordion', comment: 'Accordion component', customCssKey: 'container' }
+ ],
+ variables: []
+ },
{
components: ['formcomponent'],
selectors: [
diff --git a/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts b/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts
index 847075de5a..5cf626b4cc 100644
--- a/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts
+++ b/frontend/src/lib/components/apps/editor/componentsPanel/quickStyleProperties.ts
@@ -654,6 +654,9 @@ export const quickStyleProperties: Record<
header: [...containerDefaultProps, typographyGrouping],
container: containerDefaultProps
},
+ accordionlistcomponent: {
+ container: containerDefaultProps
+ },
carousellistcomponent: {
container: containerDefaultProps
},