Krizaka UI
Krizaka UI
Patterns

Shop page

A shop's public page as a document, not as code: an ordered list of sections, each a type and a variant with its settings and blocks, drawn inside one frame and one rhythm. shopPageSchema validates it, defineSection defines a type, one component per type draws the variants. Services come first as a compact price board. First consumer: Akinaza (akinaza#398); demo data only.

Web · ✓Mobile · n/aDesktop · ✓BetaBlocks
import { shopPageSchema, parseShopPage, migrateShopPage, defineSection, ShopFrame, ShopSection, shopStarters } from "@krizaka/ui/shop";

Web only — React, from @krizaka/ui/shop. Beta: its API may still change in a minor version.

  • Mobile · n/a. A shop's public page is a web page; the studio that edits it is the product's. → Profile card

Why it is here. Akinaza's public shop page and its composer: a page as a document of sections and variants (krizaka/akinaza#398, ADR-007, krizaka-ui#742).

When to use

  • The public page of a service business — a salon, a dog walker, a coach, a workshop — where the owner chooses which sections appear, in what order and how each one is drawn.
  • Any product page made of a few repeatable sections that a person arranges, within a catalogue and a bounded number of blocks.

When not to use

  • A page of the product itself or of a Krizaka site.Use instead: Landing page
  • A single list of services with no choice of drawing.Use instead: Service card

Installation

Install

npm install @krizaka/ui @krizaka/tailwind @krizaka/tokens tailwindcss

Styles

@import "tailwindcss";
@import "@krizaka/tailwind";
@import "@krizaka/ui/tailwind.css";

Import

import { shopPageSchema, parseShopPage, migrateShopPage, defineSection, ShopFrame, ShopSection, shopStarters } from "@krizaka/ui/shop";

Examples

Services · menu

The compact price board, the default of every preset: a thumbnail only for a service's own photo, a dotted leader, tabular prices, a button that names its service — beside the hours.

Services · menu in two columns

With nothing beside it, the menu takes two columns from a laptop.

Services · cards

Cards with a 4:3 photo, six at most.

Services · index cards

The Cahier's stamped cards, for a shop that wears the notebook.

A snap strip, phone first.

Hero · poster

The cover with the name over it, art-directed 16:9 on a laptop and 4:5 on a phone.

Hero · split

The title in the frame beside a 4:5 photo.

Hero · banner

A 21:9 photo and the name under it.

Hero · tv

The shop's sign and its latest video in the old television.

Booking · strip

The next free times, one tap each.

Booking · panel

The closing call.

Booking · sticky

The phone bar, held at the bottom edge and never over content.

One 4:5 lead and four squares.

A snap strip of 3:4 photos.

Polaroids, a note and the shop's sign on a textured wall.

The shop's photos in tiles, the first featured.

Video · tv

The shop's latest reel in the old television; a platform's short is behind a button, nothing is requested before the click.

Video · shorts

Another channel's reels, each behind its own button.

Reviews · score and cards

The score as a stamp with its distribution, beside two or three reviews. Nothing under the host's minimum.

Reviews · quote

One large review.

Reviews · strip

The score in one line.

4.7 / 538 verified reviews4.7 out of 5 from 38 verified reviews

Bulletin · board

Pinned notes, newest first, taken down after their last day, three at most.

Bulletin · banner

One line of text above the hero; never an image.

Team · row

Avatars and first names in a line.

Team · cards

A card each with a role.

Visit · card

The hours, the address and a call.

Visit · map

The place on a map: a still and a button on a phone, the live map from sm.

Visit · split

The hours beside the map.

Story · quote

A pull quote and a paragraph.

Story · owner

The owner's face, a paragraph, a way to call.

Plain links: a new tab, no referrer, nofollow.

Social · facade

The latest reel behind a button.

Questions

Native details with the page's FAQPage JSON-LD.

Policies

Cancellation, prices and the booking window.

A compact salon page

The hero, the next free times, the menu beside the hours, a filmstrip and the closing call, inside one frame and one rhythm.

The document

What the product stores: parseShopPage validates a document and answers every issue with its path.

  1. hero · poster
  2. booking · strip
  3. services · menu
  4. gallery · filmstrip
  5. reviews · summary-cards
  6. booking · panel

sections.0.variant

Props

ShopFrame

The page: sets the look preset, the accent, the paper and the density the sections below read.

PropTypeDefaultDescription
accentstring—One of the accents the preset lists as tested (krizaka, akinaza:accent-2…): the owner's choice within the look. Without it, the preset's own. @see @krizaka /tokens shopPresets
density"compact" | "airy"compactThe rhythm: compact 40 px between sections (24 on a phone), airy 64 px (40). The document's, or the preset's.
paper"plain" | "kraft" | "seyes" | "washi"plainThe paper under the page, from the preset: seyes (ruled), kraft (brown — mount PaperGrain once), washi (a tint of the accent) or plain.
presetstring—The look preset (salon-vitrine, @krizaka/tokens): its tokens apply to everything inside.

ShopSection

A section of a shop page.

PropTypeDefaultDescription
actionsReactNode—A link or a button on the right of the heading (« All times → »).
bleedboolean—The content reaches the edges of the screen (a photo, a strip); the heading stays on the frame.
eyebrowReactNode—A short lower-case note above the title.
firstboolean—The section is the page's first (the hero): no hairline, no padding.
leadReactNode—One sentence under the title.
titleReactNode—The h2. Without one the section is named by aria-label.

Accessibility

  • The hero's name is the page's only h1; every section is a section named by its h2.
  • The services are a real list (ul/li), grouped by category, the price is text, and each button names its service (« Choose Short cut »).
  • Third-party media sit behind a facade: a platform's reel, the social facade and the map on a phone request nothing before a click. Reduced motion stills the loops, the neon and the wall.

Keyboard

KeysAction
TabMoves through the page in the visual order: the hero's action, the times, each service's « Choose » button, the photos' strip.
← →Scrolls a focused filmstrip or carousel (they are focusable groups).

Best practices

  • Store the document, not the HTML: the product keeps schema, preset and sections and parses them on write and on read (parseShopPage); an older schema goes through migrateShopPage first.
  • References, not copies: a services section holds a rule (source, groupBy), never a price; the product resolves the services, photos and times at render, so a changed price changes everywhere.
  • Resolve each photo once per page and give a service its own photo or none: the menu draws a thumbnail only for a service that has one, and the trade's defaults go to the hero and the gallery.
  • Give every image its alt and let the section choose the sizes; the first image is the page's LCP and every box has a fixed ratio.
  • A section with nothing to show is not drawn: reviews under the host's minimum, an expired flyer, an empty list draw nothing.
  • The renderer hoists bulletin · banner above the hero (the document keeps the hero first); wrap each section in <div data-shop-key="…"> so the composer's preview can outline it (connectShopPreview).

Generated from the code of @krizaka/ui 3.64.0: its meta.ts, its examples and its types.Edit this documentation on GitHub

On this page