diff --git a/src/uix/eidos/components/carousel/carousel.css b/src/uix/eidos/components/carousel/carousel.css index 35db01c39..79a9d9011 100644 --- a/src/uix/eidos/components/carousel/carousel.css +++ b/src/uix/eidos/components/carousel/carousel.css @@ -177,6 +177,21 @@ pointer-events: none; } +/* + * Visibility toggles for the dots tablist and prev/next triggers. The + * consumer still composes the parts in markup; these data-attrs from + * the eidos root just hide them via the recipe so toggling on/off + * doesn't unmount the DOM (no focus loss, no layout flicker). + */ +[data-carousel][data-hide-indicators] [data-carousel-indicator-group] { + display: none; +} + +[data-carousel][data-hide-controls] [data-carousel-prev-trigger], +[data-carousel][data-hide-controls] [data-carousel-next-trigger] { + display: none; +} + [data-carousel]:focus-visible { outline: var(--focus-ring-width) solid var(--focus-ring-color); outline-offset: var(--focus-ring-offset); diff --git a/src/uix/eidos/components/carousel/carousel.svelte b/src/uix/eidos/components/carousel/carousel.svelte index cc3b55e49..3d17d74e6 100644 --- a/src/uix/eidos/components/carousel/carousel.svelte +++ b/src/uix/eidos/components/carousel/carousel.svelte @@ -16,6 +16,8 @@ color = 'primary', block = true, verticalBlockSize, + showIndicators = true, + showControls = true, value = $bindable(0), orientation = 'horizontal', style, @@ -62,6 +64,8 @@ data-variant={variant} data-color={color} data-block={block ? '' : undefined} + data-hide-indicators={showIndicators ? undefined : ''} + data-hide-controls={showControls ? undefined : ''} > {#snippet children(snippetProps)} {@render bodyContent?.(snippetProps)} diff --git a/src/uix/eidos/components/carousel/types.ts b/src/uix/eidos/components/carousel/types.ts index 7ea385c4b..0795f4783 100644 --- a/src/uix/eidos/components/carousel/types.ts +++ b/src/uix/eidos/components/carousel/types.ts @@ -67,6 +67,23 @@ export type CarouselProps = ProviderProps & { * @default '16rem' */ verticalBlockSize?: string; + /** + * Show the indicator dots tablist. The consumer still renders the + * `` markup — this prop just hides it via + * the recipe when `false`, so toggling it doesn't unmount the dots + * (preserves ARIA focus and avoids layout flicker). Set to `false` + * for hero carousels driven by prev/next or autoplay only. + * @default true + */ + showIndicators?: boolean; + /** + * Show the prev/next trigger buttons. Same semantics as + * `showIndicators` — the consumer still renders the + * `` / `` markup; the + * recipe hides them when `false`. + * @default true + */ + showControls?: boolean; }; export type CarouselViewportProps = ViewportProps; diff --git a/web/routes/uix/components/carousel/+page.svelte b/web/routes/uix/components/carousel/+page.svelte index cfb211f69..b1d35459a 100644 --- a/web/routes/uix/components/carousel/+page.svelte +++ b/web/routes/uix/components/carousel/+page.svelte @@ -58,6 +58,8 @@ let size = $state('md'); let variant = $state('surface'); let color = $state('primary'); + let showIndicators = $state(true); + let showControls = $state(true); // Imperative-API demo: store the handle exposed via the snippet so the // footer buttons + keyboard shortcut can drive the carousel. @@ -191,6 +193,8 @@ autoplay && stopOnLastSnap && ' stopOnLastSnap', disabled && ' disabled', dir && ` dir="${dir}"`, + !showIndicators && ' showIndicators={false}', + !showControls && ' showControls={false}', '>', ' ', ' ', @@ -272,6 +276,8 @@ {size} {variant} {color} + {showIndicators} + {showControls} > {#snippet children(snippet: CarouselProviderSnippetProps)} {(api = snippet.api, isPlaying = snippet.isPlaying, '')} @@ -567,6 +573,20 @@ {/each} + +