KQ-1393 · MOSAIC/FLIP
Mosaic Flip
An image carousel whose change is a wave of turning tiles: each tile waits for the wave from the pointer, a corner, an edge or the centre, then turns 180° about the axis perpendicular to the wave's travel, so the tiles fall away from the origin like dominoes, on the snap spring with a slight lift and shadow mid-turn and each face darkening as it turns from the light. Arrows, dots, a click, a swipe and the keyboard all change it, the active dot glides on the glide spring, and with sound each landing tile ticks. The frame is a labelled slide: Left and Right turn to the previous and next image, Home and End to the ends.
Waylight · field journal
Image 1 of 4: Salt flats at dawn
1 of 4 · salt flats at dawn · arrows, dots or a click turn it
Install
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/mosaic-flip
Props
- images
- readonly { src: string; alt: string }[]
- default —
- The images, in order: any URL a CSS background can load, and what each shows.
- value / defaultValue
- number
- default — / 0
- The index shown (controlled), or shown first when uncontrolled.
- onValueChange
- (index: number) => void
- default —
- Fires from the press, key, swipe or autoplay tick that changed the image, with the new index.
- grid
- number
- default 8
- Columns of tiles, 2 to 20.
- rows
- number
- default —
- Rows of tiles; by default they follow the frame's aspect so tiles stay square.
- origin
- "pointer" | "corner" | "edge" | "center"
- default "pointer"
- Where each wave starts: the pointer (or the control pressed), the leading corner, the leading edge, or the centre.
- speed
- number
- default 1
- Pace of the wave and of each turn, as a multiple (0.25 to 3).
- lift
- number
- default 0.5
- How far a tile rises toward you mid-turn, 0 to 1.
- jitter
- number
- default 0.25
- How irregular the wave front is, 0 (mechanical) to 1 (hand-turned).
- axis
- "wave" | "x" | "y"
- default "wave"
- Tiles turn away from the wave, or all about one axis.
- gap
- number
- default 2
- Grout between tiles, px.
- radius
- number
- default 3
- Tile corner radius, px.
- autoplay
- number
- default 0
- Advance by itself every so many ms while visible, unhovered and unfocused; 0 is off.
- loop
- boolean
- default true
- Wrap past the first and last image.
- controls
- boolean
- default true
- Show the arrows and dots.
- sound
- boolean
- default false
- A soft tick as each tile lands, for changes the visitor makes.
- label
- string
- default "Gallery"
- The carousel's accessible name.
- onSettle
- (index: number) => void
- default —
- Fires when a wave has landed, with the index now shown.
- className
- string
- default "aspect-[16/9] w-full"
- Size the frame here.
| Prop | Type | Default | Description |
|---|---|---|---|
| images | readonly { src: string; alt: string }[] | — | The images, in order: any URL a CSS background can load, and what each shows. |
| value / defaultValue | number | — / 0 | The index shown (controlled), or shown first when uncontrolled. |
| onValueChange | (index: number) => void | — | Fires from the press, key, swipe or autoplay tick that changed the image, with the new index. |
| grid | number | 8 | Columns of tiles, 2 to 20. |
| rows | number | — | Rows of tiles; by default they follow the frame's aspect so tiles stay square. |
| origin | "pointer" | "corner" | "edge" | "center" | "pointer" | Where each wave starts: the pointer (or the control pressed), the leading corner, the leading edge, or the centre. |
| speed | number | 1 | Pace of the wave and of each turn, as a multiple (0.25 to 3). |
| lift | number | 0.5 | How far a tile rises toward you mid-turn, 0 to 1. |
| jitter | number | 0.25 | How irregular the wave front is, 0 (mechanical) to 1 (hand-turned). |
| axis | "wave" | "x" | "y" | "wave" | Tiles turn away from the wave, or all about one axis. |
| gap | number | 2 | Grout between tiles, px. |
| radius | number | 3 | Tile corner radius, px. |
| autoplay | number | 0 | Advance by itself every so many ms while visible, unhovered and unfocused; 0 is off. |
| loop | boolean | true | Wrap past the first and last image. |
| controls | boolean | true | Show the arrows and dots. |
| sound | boolean | false | A soft tick as each tile lands, for changes the visitor makes. |
| label | string | "Gallery" | The carousel's accessible name. |
| onSettle | (index: number) => void | — | Fires when a wave has landed, with the index now shown. |
| className | string | "aspect-[16/9] w-full" | Size the frame here. |