Media grid
A feed of videos in mixed orientations that never staggers: MediaGrid routes the 9:16 clips to a ShortsShelf (equal-height cards, snap scroll, arrows, “See all”) and lays the others in a uniform 16:9 grid; VideoCard is aspect-aware and gives every card the same body height so rows align.
Web uniquement — React, depuis @krizaka/ui/media-grid. Bêta : son API peut encore changer à une version mineure.
Pourquoi il est là. Orochia's home feed, Explore and a profile's Videos tab (ORO-HOME-FEED): a Shorts shelf for the 9:16, a uniform grid for the 16:9.
Quand l’utiliser
- A home, an explore page or a profile's Videos tab where creators publish both vertical and horizontal video.
- A gallery whose items come from different sources (
uniform: everything in one frame, the odd one drawn whole over a blurred copy).
Quand ne pas l’utiliser
- For a feed that plays one video per screen.À la place : Vertical video
- For still photos the owner reorders.À la place : Photo grid
Installation
Installer
npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcssStyles
@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";Importer
import { MediaGrid, ShortsShelf, VideoCard } from "@krizaka/ui/media-grid";Exemples
A feed
Three horizontal clips in the grid, three vertical on the shelf: every card of a row has one height.
Shorts
See all
Free0:12Pouring the mint tea, slow
Camille12.4K views
Free0:12First snow on rue Saint-Denis
Camille12.4K views
Free0:12Desert camp at blue hour
Camille12.4K views
One frame
mode="uniform": vertical clips drawn whole over a blurred copy inside 16:9 cards.

Pouring the mint tea, slow
2.4K views
Backstage, a minute before
2.4K views
First snow on rue Saint-Denis
2.4K views
The unlock in one tap
2.4K views
Props
MediaGrid
A media grid that never mixes heights badly: a shelf for the 9:16, a uniform grid for the rest.
| Prop | Type | Défaut | Description |
|---|---|---|---|
getIdrequis | (item: T) => string | — | A stable key for an item. |
itemsrequis | readonly T[] | — | The videos, in order. |
orientationOfrequis | (item: T) => VideoCardAspect | — | The source's orientation (from its width and height). |
renderItemrequis | (item: T, state: MediaGridState) => ReactNode | — | One card, drawn in the frame the grid gives (state): use VideoCard. |
shelfrequis | Pick<ShortsShelfProps<unknown>, "title" | "label" | "seeAll" | "previousLabel" | "nextLabel"> | — | The shelf of split: its name, "See all" and arrows, passed translated. |
frame | VideoCardAspect | landscape | The frame of uniform. |
layout | "grid" | "list" | grid | grid or list (one row per video). |
mode | "split" | "uniform" | split | split: verticals on the shelf, the others in the grid · uniform: all in one frame (frame). |
ShortsShelf
A Shorts shelf: equal-height 9:16 cards in a snap-scrolling row.
| Prop | Type | Défaut | Description |
|---|---|---|---|
getIdrequis | (item: T) => string | — | A stable key for an item. |
itemsrequis | readonly T[] | — | The clips, in order. |
labelrequis | string | — | The shelf's accessible name ("Shorts"), passed translated; shown as its heading unless title is set. |
nextLabelrequis | string | — | The next arrow's name. |
previousLabelrequis | string | — | The arrows' names, passed translated. |
renderItemrequis | (item: T, index: number) => ReactNode | — | One card: use VideoCard aspect="portrait". |
seeAll | { href: string; label: string; linkAs?: LinkComponent; } | — | Opens the vertical feed. |
title | ReactNode | — | A heading different from the name. |
VideoCard
A video card whose frame, body and footer have one height per aspect, so a grid row or a shelf never staggers.
| Prop | Type | Défaut | Description |
|---|---|---|---|
hrefrequis | string | — | Where the card opens. |
titlerequis | string | — | The title; it names the card and is its link. |
action | ReactNode | — | One quick action at the end of the footer (a tip, a save). Its clicks must not follow the card's link. |
aspect | VideoCardAspect | landscape | The frame: landscape (16:9) or portrait (9:16). |
badges | ReactNode | — | Badges at the top-left of the picture (Free, a price, 18+). Put them on scrim so they read in both themes. |
blurred | boolean | false | A sensitive picture: blurred and scaled so nothing shows (put the reveal button in overlay). |
creator | VideoCardCreator | — | Who made it: name, photo, profile. |
duration | string | — | The length, already formatted (3:42). |
fallback | ReactNode | — | Shown instead of the picture while there is none. |
fit | "cover" | "contain" | cover | cover fills the frame; contain draws the whole picture over a blurred copy of itself (a source of the other
orientation: no cropped face, no black bar). |
layout | "row" | "stack" | stack | stack (picture over text) or row (picture beside the text: the list mode of a section). |
linkAs | LinkComponent | — | The app's router link (Next's Link). |
loading | "eager" | "lazy" | lazy | eager for the first cards of a page. |
meta | ReactNode | — | What is counted (12.4K views), already formatted. |
overlay | ReactNode | — | Over the whole picture, above the card's link (a veil, a reveal button). |
poster | string | null | — | The picture. |
previewSrc | string | null | — | An animated picture (WebP) shown while the card is hovered or focused. |
Accessibilité
- The shelf is a labelled section whose row is a list; the arrows are named buttons shown with a mouse, hidden on touch (swipe).
- The card's whole surface is the title's link (a stretched link): no nested interactive element.
- The animated preview plays on hover or focus only.
Clavier
| Touches | Action |
|---|---|
| Tab | Each card is one link (its title); the creator and the action are their own stops; the shelf takes the focus to scroll with the arrow keys. |
| Arrow Left / Arrow Right | Scrolls the focused shelf. |
Bonnes pratiques
- Leave
modeonsplitfor a feed: a 9:16 card in a 16:9 grid is what makes a row tower over its neighbours. - Give
orientationOfthe source's width and height, not the card's: a clip of the other shape is drawn withfit="contain", never cropped to a face. - Put what is the product's own in the slots (
badges,action); badges sit onscrimand read in both themes. - Pass every word translated: the shelf's name, its arrows and “See all”.
Composants liés
Générée depuis le code de @krizaka/ui 3.18.0 : son meta.ts, ses exemples et ses types.Modifier cette documentation sur GitHub
