Menu Grid
ProThe product grid of a till: big tiles with a picture of each dish, tinted by category, a count for what is already in the order, and sold out items that keep their place.
3 items · €18.80
Installation#
Usage#
The preview is yours to explore. Its code comes with a Pro license, paid once and used in every project.
Have a license? Unlock it here
Categories are Koala Tabs, so the grid does one job. Open a Modifier Picker from onClick when an item needs a choice before it goes in the order.
Anatomy#
import {
MenuGrid,
MenuTile,
MenuTileFooter,
MenuTileMedia,
MenuTileMeta,
MenuTileName,
MenuTilePrice,
} from "@/components/ui/menu-grid"
<MenuGrid>
<MenuTile>
<MenuTileMedia />
<MenuTileName />
<MenuTileFooter>
<MenuTilePrice />
<MenuTileMeta />
</MenuTileFooter>
</MenuTile>
</MenuGrid>Media#
A picture is found faster than a name. MenuTileMedia takes a photo, an illustration or an icon, and an icon picks up the category tone. Mix them in one grid: a drink without a photo still lines up with the dishes around it.
Leave the media out and the tiles go back to text, which fits more products on a small screen.
3 items · €18.80
Tones#
Staff find a product by colour before they read it. Give every category one tone and keep it the same on the tab, the tiles and the ticket. The tint is a soft fill, so the name always reads in full ink.
In the order and sold out#
quantity shows how many are already in the order, so a second tap is a decision, not a mistake. Tap the middle tile to add one. soldOut keeps the item in its place, because a missing tile makes staff think they are in the wrong category.
Sizes#
md fits a tablet beside an order panel. lg is for a screen that is only the menu, or one used at arm's length.
Touch density#
On a till, wrap the screen in the touch density. The tabs, buttons and copy grow with it, and the tiles keep their size.
3 items · €18.80
Only the parts you need#
A bar with fixed prices may show the name only. Every part can be left out and the tile still lines up.
API reference#
MenuGrid
The grid. It fits as many columns as the width allows, so the same markup works on a phone, a tablet and a 15 inch till. Accepts className, merged last.
| Prop | Type | Default | Description |
|---|---|---|---|
| size | "md" | "lg" | "md", "lg" under touch density | Tile size: at least 96px tall and 136px wide, or 112px and 160px. |
| tone | MenuTileTone | - | The tone every tile takes unless it sets its own, so a category is coloured once. |
| aria-label | string | - | Name the grid after its category. It is a group, and a screen reader announces the name on entry. |
| Data attribute | Description |
|---|---|
| data-slot | "menu-grid". |
| data-size | The size. |
MenuTile
One product, rendered as a button. Pass onClick to add it to the order. Sold out tiles stay focusable and announced, and ignore clicks.
| Prop | Type | Default | Description |
|---|---|---|---|
| tone | "neutral" | "brand" | "orange" | "warning" | "success" | "teal" | "info" | "purple" | "pink" | "neutral" | The category tint. |
| quantity | number | 0 | How many are already in the order. Above zero, a count appears in the corner and replays each time it grows. |
| soldOut | boolean | false | Mutes the name, greys the media, replaces the children of MenuTilePrice with "Sold out" and ignores clicks. |
| asChild | boolean | false | Renders your own element, for example a link to the item. |
| Data attribute | Description |
|---|---|
| data-slot | "menu-tile", with "menu-tile-count" inside while in the order. |
| data-tone | The tone. |
| data-in-order | Present while quantity is above zero. |
| data-sold-out | Present while soldOut is true. |
MenuTileName
The product name. Wraps to three lines and keeps clear of the count.
| Data attribute | Description |
|---|---|
| data-slot | "menu-tile-name". |
MenuTileMedia
A 4:3 frame at the top of the tile for a photo, an illustration or an icon. With it the tile becomes a card with the media inset, and the count sits on the image. Sold out media fades to grey.
| Data attribute | Description |
|---|---|
| data-slot | "menu-tile-media". |
MenuTileFooter
The bottom row: price on one side, meta on the other.
| Data attribute | Description |
|---|---|
| data-slot | "menu-tile-footer". |
MenuTilePrice
The price, with tabular figures. Format it yourself. Reads "Sold out" on a sold out tile.
| Data attribute | Description |
|---|---|
| data-slot | "menu-tile-price". |
MenuTileMeta
A small muted slot for allergens, a dietary mark or a short code.
| Data attribute | Description |
|---|---|
| data-slot | "menu-tile-meta". |