# Pacewall — Sneaker & Shoe Store Product Grid for React and Tailwind CSS

> An animated product grid for shoe and sneaker stores in React and Tailwind CSS: shoes stand on slim shelves, shoppers sort and filter by size, and the shoe itself travels into a detail view with sizes and add to bag. No animation library.

- Kind: Component (Dialogs / Modals)
- Price: Free
- License: MIT License. Do anything with it, keeping the copyright notice.
- Developer: UpFork
- Tags: dialog, card, gallery, grid, ecommerce, shoe-store, sneakers, product-grid, shared-element, web-animations, nextjs, tailwind
- Published: 2026-11-05
- Updated: 2026-11-05
- Page: https://upfork.dev/products/shoe-store-product-grid-react

## AI summary

**Pacewall** — an animated shoe and sneaker product grid for React and Tailwind CSS: shoes stand on slim shelves, shoppers sort and filter by category and size, and the shoe flies into a detail view with sizes and Add to bag. Includes a bag drawer and a Shopify mapper. No animation library.

**Install** (free, no account needed): `npx shadcn@latest add https://upfork.dev/r/shoe-store-product-grid-react.json`. It loads no font; set the CSS variables `--pw-font-display` and `--pw-font-text` (see `components/demo/demo-fonts.ts`). `ShoeWall` imports its own `styles.css`.

**Entry:** `ShoeWall` from `components/shoe-wall/index.ts`.

**Key props** (`ShoeWallProps`; only `shoes` is required):
- `shoes: Shoe[]`: `{ id, slug, href, name, category, price, currency, photo, sizes: { eu, us?, uk?, stock, variantId? }[] }`. `photo` needs `src, width, height, baseline, contact, alt`.
- `defaultDensity`/`density` (`"l" | "m" | "s"`), `defaultSort`/`sort`, `theme`, `shelf`, `filters` (false for a small shop), `headingLevel`, `labels`, `formatPrice`.
- Detail view: `syncUrl`, `openSlug`, `onOpenChange`.
- Bag: `onAddToBag(shoe, size)`, `bagCount`, `bagAnchor`, `onViewBag`, `onSizeGuide`.
- Also: `moreHref`, `totalCount`, `renderImage`, `renderLink`, `sound`, `pointerLight`.
- Separate exports: `BagPeek` (`open`, `items`, `onClose`, `onRemove`) and `fromShopifyProducts(products, options)`, which returns `Shoe[]`.

**Example:**
```tsx
import { ShoeWall } from "@/components/shoe-wall";
<ShoeWall shoes={shoes} defaultDensity="m" syncUrl
  labels={{ heading: "New in" }}
  onAddToBag={(shoe, size) => addToCart(size.variantId)} />
```

**Read next:** `components/shoe-wall/types.ts`, `components/shoe-wall/ShoeWall.tsx`, `components/demo/shoes.ts`, `components/shoe-wall/fromShopifyProducts.ts`.

## How to get it

Install it into a React + Tailwind project with the shadcn CLI. It's free for everyone, so it needs no account, token or setup:

```bash
npx shadcn@latest add https://upfork.dev/r/shoe-store-product-grid-react.json
```

A project set up with UpFork's registry and the member's token (UPFORK_TOKEN) installs it as `@upfork/shoe-store-product-grid-react` too.

## About

A wall of sports shoes for an online store, in React and Tailwind CSS. Each shoe stands on its own slim shelf, with its name and price on a ticket under it. A shopper can rearrange the wall, thin it out to what fits them, and take a pair down: the shoe itself travels from its shelf into a detail view, they pick a size and add it to the bag, and the shoe travels back to its place.

### What is in it

- **A real wall.** Three densities, chosen with small icons of little shelves. Every sole sits exactly on its shelf at every width, and the last row ends in a finished way, with a "See all" placard and empty shelves at low contrast.
- **Arranging that does something.** Sort by price, newest or colour, filter by category and by the shopper's own size, shuffle, and go back to the original order. Every change uses the same flight: shoes lift off the wall, travel in front of it, and land from above.
- **One object in motion.** Click a shoe and that shoe travels to the detail view while its shelf stretches into a long rail under it. Closing is the same journey backwards, and the wall reaches full strength as the shoe lands.
- **Size and bag.** A size picker with arrow keys, sold-out and low-stock states, and EU, US and UK from your data. A fixed-size button that moves through choosing, adding, added and add another, and handles a rejected promise. An optional small bag drawer.
- **Looking closer.** Labelled views that move a camera over the same picture, and zoom that follows the pointer. Zoom stops where the picture would turn soft, so how far it goes depends on your source.
- **Deep links.** `?shoe=slug` opens a shoe on load, and browser back closes it.
- **Everywhere.** Light, dark and auto themes, phones with a bottom sheet and swipe to close, keyboard, screen readers, reduced motion, right to left, and the wall and its links still work with no JavaScript.
- **Small and on its own.** About 20 KB of JavaScript, gzipped, without React. No animation library. Works in Next.js and Vite, with plain `<img>` and `<a>` by default.

### Please read this about the pictures

**The wall expects transparent, side-view pictures with the toe to the left, and most shops do not have them.** The project includes `scripts/photos/`, which takes your own photographs through the same steps: cut out, clean the edge, level the sole, export WebP and AVIF, and measure where the sole meets the shelf.

**The shoes in the demos are not part of the MIT licence, and you should replace them.** Of the 17, seven are real photographs under their own stock licences, and ten are AI-generated images made with Grok and ChatGPT. We have not verified those tools' terms for shipping their images in your product: check them yourself, or replace the pictures. `PHOTOS.md` lists every one. The shop, the shoe names and the prices are invented.

`fromShopifyProducts` maps a Storefront API response to the wall's data. It makes no network calls.
