fix: carousel app component, expose current index (#6120)

* feat: carousel app component, expose current index

* minimal diff
This commit is contained in:
Alexander Petric
2025-07-02 12:31:43 -04:00
committed by GitHub
parent 846ca65b87
commit 7284c51762
4 changed files with 48 additions and 7 deletions
@@ -1,5 +1,5 @@
<script lang="ts">
import { getContext } from 'svelte'
import { getContext, untrack } from 'svelte'
import { initConfig, initOutput } from '../../editor/appUtils'
import SubGridEditor from '../../editor/SubGridEditor.svelte'
import type { AppViewerContext, ComponentCustomCSS, RichConfigurations } from '../../types'
@@ -36,7 +36,7 @@
componentContainerHeight
}: Props = $props()
const { app, focusedGrid, selectedComponent, worldStore, connectingInput } =
const { app, focusedGrid, selectedComponent, worldStore, connectingInput, componentControl } =
getContext<AppViewerContext>('AppViewerContext')
let everRender = $state(render)
@@ -44,10 +44,11 @@
render && !everRender && (everRender = true)
})
const outputs = initOutput($worldStore, id, {
let outputs = initOutput($worldStore, id, {
result: undefined,
loading: false,
inputs: {}
inputs: {},
currentIndex: 0
})
const resolvedConfig = $state(
@@ -76,6 +77,41 @@
})
})
let currentPageIndex = $state(0)
// Single update function - ONLY place that calls .set()
function handleIndexChange() {
if (outputs?.currentIndex) {
if (!Array.isArray(result) || result.length === 0) {
// No data or empty data - reset to 0
currentPageIndex = 0
outputs.currentIndex.set(0)
} else if (currentPageIndex >= result.length) {
// Current index is out of bounds - reset to 0
currentPageIndex = 0
outputs.currentIndex.set(0)
} else {
// Valid data and valid current index
outputs.currentIndex.set(currentPageIndex)
// Navigate carousel to match the current index
if (carousel) {
carousel.goTo(currentPageIndex)
}
}
}
}
// Watch for changes and call update function (like working components)
$effect.pre(() => {
currentPageIndex != undefined && untrack(() => handleIndexChange())
})
$componentControl[id] = {
setSelectedIndex: (index: number) => {
if (Array.isArray(result) && index >= 0 && index < result.length) {
currentPageIndex = index
}
}
}
</script>
{#each Object.keys(components['carousellistcomponent'].initialData.configuration) as key (key)}
@@ -1319,6 +1319,7 @@ export function isContainer(type: string): boolean {
type === 'horizontalsplitpanescomponent' ||
type === 'steppercomponent' ||
type === 'listcomponent' ||
type === 'carousellistcomponent' ||
type === 'decisiontreecomponent'
)
}
@@ -1336,6 +1337,9 @@ export function subGridIndexKey(type: string | undefined, id: string, world: Wor
case 'steppercomponent': {
return (world?.outputsById?.[id]?.currentStepIndex?.peak() as number) ?? 0
}
case 'carousellistcomponent': {
return (world?.outputsById?.[id]?.currentIndex?.peak() as number) ?? 0
}
case 'decisiontreecomponent': {
return (world?.outputsById?.[id]?.currentNodeIndex?.peak() as number) ?? 0
}
@@ -38,7 +38,8 @@ const setValue = {
const setSelectedIndex = {
title: 'setSelectedIndex',
description: 'Use the setSelectedIndex function to select a row in a table or an AG Grid table.',
description:
'Use the setSelectedIndex function to select a row in a table, an AG Grid table, or navigate to a slide in a Carousel component.',
example: 'setSelectedIndex(id: string, index: number)',
documentation: 'https://www.windmill.dev/docs/apps/app-runnable-panel#setselectedindex'
}
@@ -90,6 +91,8 @@ export function getComponentControl(type: keyof typeof components): Array<Compon
return [setTab, setValue, setSelectedIndex]
case 'selecttabcomponent':
return [setTab, setValue, setSelectedIndex]
case 'carousellistcomponent':
return [setSelectedIndex]
case 'conditionalwrapper':
case 'steppercomponent':
return [setTab]
@@ -20,8 +20,6 @@
let { component = $bindable(), children }: Props = $props()
let convertToUIEditorCallback: (() => void) | undefined = $state(undefined)
console.log('FOOBAR', component.type)
let selected = $state(
(component.type === 'plotlycomponentv2' || component.type === 'chartjscomponentv2') &&
component.datasets !== undefined