Drift dripper, glass
€29.00
4.1(22)
KQ-1350 · STOREFRONT
A complete store home built around cart-drawer, product-grid and product-detail: the whole store is the bag's page, so the bag slides over it on glide and pulls shut; a hero, a category rail and product rails that scroll-snap and glide a page at a time; a category, a card or See all pushes product-grid's shelf in from the right on glide, and the hero pushes product-detail's page. Quick add throws a dot in the product's glaze to the bag on a true arc — x steady, y thrown up and falling — and when it lands the badge bumps on recoil, its count rolls and the button draws a check on flick. Rails take Left, Right, Home and End, pushed screens go back with Back, Alt+Left, Escape or a 1:1 swipe from their left edge that commits by projection.
home · bag 0 items
One command — the source lands in your repo. Or copy it from the Code tab.
$ pnpm dlx shadcn@latest add @kinetiq/storefront
| Prop | Type | Default | Description |
|---|---|---|---|
| rails | number | 2 | How many collections show as rails on the home, 1 to 3. |
| hero | "banner" | "split" | "off" | "banner" | The hero: a banner with the copy over the still life, a split with the copy beside it (a banner on a phone), or none, so the category rail leads. |
| density | "compact" | "regular" | "roomy" | "regular" | Rail card widths (132, 160 or 196px; narrower on a phone) and how much each says — price only, a rating, or the rating and its glazes; also the shelf's density. |
| products | ProductGridItem[] | defaultProducts | The catalogue, in product-grid's shape: categories come from it and every rail, tile and shelf reads it. |
| colors | ProductGridColor[] | defaultProductColors | The glazes products come in, as pigments that read in both themes. |
| collections | StoreCollection[] | defaultStoreCollections | The rails in order: a title, a line, product ids, and how See all sorts and filters the shelf. |
| featured | ProductInfo | defaultProduct | The product the hero opens as a full product page; its glazes paint the hero's still life. |
| heroCopy | StoreHero | defaultStoreHero | The hero's eyebrow, title, line and button words. |
| items / defaultItems | CartLine[] | [] | The lines in the bag, in cart-drawer's shape. |
| onItemsChange | (items: CartLine[]) => void | — | Fires from the quick add, shelf, product page or bag that changed the lines, with all of them. |
| cartOpen / defaultCartOpen | boolean | false | Whether the bag is open over the store. |
| onCartOpenChange | (open: boolean) => void | — | Fires from the Bag button and from the bag's close, Escape, scrim or pull. |
| screen / defaultScreen | "home" | "product" | `category:${string}` | `collection:${string}` | "home" | The screen on show: home, the featured product, or the shelf for a category or a collection. |
| onScreenChange | (screen: StoreScreen) => void | — | Fires from a tile, a card, See all, the hero, Back, Alt+Left, Escape or the back-swipe. |
| onAdd | (line: CartLine) => void | — | Something went in the bag from the store, with the line as it now stands. |
| onCheckout | (items: CartLine[], total: number) => void | Promise<void> | — | Checkout was pressed in the bag; a promise holds its button pending. |
| now | Date | number | defaultStoreNow | The moment the product page's delivery estimate counts from. Never read from the clock during render. |
| format | (amount: number) => string | euros, en-IE | Money everywhere: rails, shelf, product page and bag. |
| storeName | string | "Fernworks Supply" | The store's name in the top bar. |
| status | "ready" | "loading" | "error" | "ready" | Loading draws placeholder cards; error offers Try again. Passed on to the shelf. |
| onRetry | () => void | — | Try again was pressed in the error state. |
| label | string | "Store" | The screen's accessible name. |
| sound | boolean | false | Play a pop as a quick add lands and a category opens, and a swish for pushes, pops and the bag; the composed pieces play their own. Off unless asked for. |
| disabled | boolean | false | Browse only: nothing can be added or bought. |
| className | string | — | Classes for the root. It is 560px tall by default; pass a height class to change it. |