Restaurant menus and spa or salon price lists — also a QR-menu page. Each category is a labelled section with a sticky jump bar of plain anchors, prices are tabular and formatted by Intl (the full currency name for screen readers), tags are words (never emoji), the 14 EU allergens are localized, unavailable items say “Not today” instead of a strikethrough and missing prices read “Market price”. Zero JavaScript.
Installation
The whole kit as one package — get updates by bumping the version. Add the styles to globals.css: @import "@vamos-ui/react/styles.css";
Usage
import { MenuList } from "@vamos-ui/react/blocks";
<MenuList
title="Tonight at *Kıyı*"
priceNote="Prices include VAT. No service charge is added."
categories={[{ title: "Cold meze", items: [
{ name: "Haydari", description: "Strained yoghurt, dill.", prices: [{ amount: { amount: "180", currency: "TRY" } }], tags: ["vegetarian"], allergens: ["milk"] },
] }]}
/>Examples
Photo (brunch)
A 72px square photo per item; items without one keep the column.
Service list (spa, Turkish)
Service · duration · price rows; several durations become small columns; “Randevu” links are named after the service.
QR menu at phone width
The category bar scrolls horizontally and sticks under the top edge.
API
MenuList
| Prop | Type | Default |
|---|---|---|
variantLayout. | "classic" | "photo" | "service-list" | "classic" |
categoriesEmpty categories are hidden (shown in edit mode). | { title; note?; anchor?; items: MenuItem[] }[] | — |
categories[].items{ name, description?, prices: { label?, amount?: Money }[] (1–4), duration?, tags?, allergens?, image?, unavailable?, bookHref? } | MenuItem[] | — |
tagsRendered as accent-ink words (MENU_TAGS). vegan, vegetarian, gluten-free, dairy-free and halal also map to schema.org suitableForDiet. | ("vegetarian" | "vegan" | "gluten-free" | "dairy-free" | "nut-free" | "halal" | "spicy" | "new" | "chef-pick" | "to-share" | "seasonal")[] | — |
allergensgluten, crustaceans, eggs, fish, peanuts, soybeans, milk, nuts, celery, mustard, sesame, sulphites, lupin, molluscs. | Allergen[] | — |
priceNoteTax / service note (required by the house rules). | ReactNode | — |
showNavSticky category jump bar. | boolean | more than 2 categories |
bookHrefservice-list: booking page for every row. | string | — |
showAllergensAllergen line under items. | boolean | true |
labels / localeTag and allergen names, Market price, Not today, Book. | Partial<Site2Labels> / string | — |
headingLevelOutline level of the title; categories and dishes follow (1 → h2 categories, h3 dishes — a whole menu page). Without a title, categories take this level. | 1 | 2 | 3 | 2 |
categories[].items[].imagephoto variant: 72px square, sizes="72px". | SiteImage | — |
theme / anchor / id / className / components / editModeShared block props. | BlockBaseProps | — |
menuJsonLd({ categories, name? })
| Prop | Type | Default |
|---|---|---|
returnsschema.org Menu → MenuSection → MenuItem + Offer (+ suitableForDiet). | object | — |