feat(carousel): showIndicators + showControls visibility props

Two new eidos-level booleans on `<Carousel>` so consumers can toggle
the indicator dots and the prev/next triggers without touching the
markup composition. Defaults stay `true` (existing behaviour).

The consumer still renders the parts in markup; the recipe just hides
them via `display: none` when the eidos root stamps
`data-hide-indicators` / `data-hide-controls`. Toggling on/off doesn't
unmount the DOM, so ARIA focus is preserved across the change and the
layout doesn't reflow into a different size.

Naming follows the canonical eidos cascade — `showIndicators`
mirrors calendar's `showWeekNumbers`. Mantine uses `withIndicators`
(default false); we default `true` because the Eidos recipe assumes
indicators are part of the default surface.

Demo: two switches added to the eidos visual-props section + snippet
preview emits the prop when set to false.

Verified: clicking the demo switch flips
`data-hide-indicators` on the root and the indicator-group's
computed `display` goes from default to `none` without remounting.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 5 months ago
parent 92c5e421c9
commit 3fc4ced37b

@ -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);

@ -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)}

@ -67,6 +67,23 @@ export type CarouselProps = ProviderProps & {
* @default '16rem'
*/
verticalBlockSize?: string;
/**
* Show the indicator dots tablist. The consumer still renders the
* `<Carousel.IndicatorGroup>` 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
* `<Carousel.PrevTrigger>` / `<Carousel.NextTrigger>` markup; the
* recipe hides them when `false`.
* @default true
*/
showControls?: boolean;
};
export type CarouselViewportProps = ViewportProps;

@ -58,6 +58,8 @@
let size = $state<CarouselSize>('md');
let variant = $state<CarouselVariant>('surface');
let color = $state<CarouselColor>('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}',
'>',
' <Carousel.Viewport>',
' <Carousel.ItemGroup>',
@ -272,6 +276,8 @@
{size}
{variant}
{color}
{showIndicators}
{showControls}
>
{#snippet children(snippet: CarouselProviderSnippetProps)}
{(api = snippet.api, isPlaying = snippet.isPlaying, '')}
@ -567,6 +573,20 @@
{/each}
</span>
</label>
<label data-uix-control>
<span data-uix-control-label>showIndicators</span>
<span data-uix-switch>
<input type="checkbox" bind:checked={showIndicators} />
<span data-uix-switch-label>{showIndicators ? 'on' : 'off'}</span>
</span>
</label>
<label data-uix-control>
<span data-uix-control-label>showControls</span>
<span data-uix-switch>
<input type="checkbox" bind:checked={showControls} />
<span data-uix-switch-label>{showControls ? 'on' : 'off'}</span>
</span>
</label>
</div>
<div data-uix-code>

Loading…
Cancel
Save

Powered by TurnKey Linux.