shadcn.io is not affiliated with official shadcn/ui
Horizontal Card Skeleton Block for Ark UI
A recipe card with the picture beside the text that loads in place: a drawn bowl, a title, a three-line description and two tags come in over bars when you press Load.
Installation
Overview
Show a card with its picture beside the text while it loads, then swap the content in without moving anything, with this horizontal card skeleton for React with Ark UI. One hairline frame with a plus mark on each corner holds a recipe from Challis, a recipe app: a drawn bowl in a fixed column at the start, then the title, a three-line description and two tags. The frame is real from the first paint; the picture, the title, the description and the tags are Skeleton bars that become the recipe in the same place, all at once. The bowl is drawn in greyscale rather than photographed, the description is a Skeleton Text effect whose words come in one after another, and the tags are Badges. On a phone the picture stacks on top at a fixed height. It's built from Skeleton, Skeleton Text, Badge and Guides, with a CSS entrance only. For recipes, listings, products and any card whose picture sits beside its text.
FAQ
What stays local, and how do I wire it to a real query?
Nothing is fetched. The recipe is typed in RECIPE. Load starts a 700 millisecond timer, and when it ends the phase becomes ready and the data swaps in; Reload goes back to the bars and in again. To wire it for real, delete the timer, the Load button and the polite line, and set data-state (loading or ready) and aria-busy on the card from your query's pending state, or use the bars as a Suspense fallback and render the real content when it arrives. Keep one component for the bars and the data so they can't drift apart.
Why doesn't the card jump when the data arrives?
The picture is a fixed-width column that stretches to the height of the text beside it, and holds the bar and the drawing in the same place. The description's bars and words share one grid cell, and each tag shares a cell with its bar, so the larger layer sets the size. The polite line reserves two lines, so the card is exactly as tall before, during and after loading. On a phone the picture is a fixed h-36 band above the text.
How does the layout change on a phone?
Below the small breakpoint the card is a column: the picture on top at 144 pixels, the text under it. From the small breakpoint it is a row with the picture in an 11rem column that stretches to the text's height and never shrinks. The picture's drawing is cropped to fill the box, so it works at any height; a photograph would use object-cover the same way.
How do I use a real photograph?
The bowl is a drawn scene (Pic around the Scene component with a bowl kind added to the kit), so the block ships no image file. For a photograph, replace the Scene inside Pic with <img alt="" className="size-full object-cover" src={recipe.cover} /> and give the wrapper its real description; the bar still holds the box until the image is ready.
Is it accessible?
The card is marked busy while it loads and carries a screen-reader-only "Loading recipe…", and the polite line announces what loaded once. The bars are hidden from assistive technology and the layer that isn't showing is invisible, so it is neither read nor focusable. The pulse stops when the data is in, and under reduced motion there is no pulse, no spinner and no stagger: the swap is instant.