AppbrewDevelopers
Build

UI elements catalog

The building blocks available for composing block UIs.

Everything on this page imports from @gauntlet/ui-builder. When you build a block, reach for these elements before writing raw React Native. They read the platform's style trees, merge theme defaults, and handle the edge cases (CDN image sizing, layout animation, link routing) you would otherwise reimplement.

Prefer ui-builder for new blocks

Some of these elements are also re-exported from @gauntlet/components. For new blocks, always import from @gauntlet/ui-builder and prefer its elements over reaching into @gauntlet/components — the components library is for legacy maintenance and a few app-specific organisms.

Atoms

The primitives. Each takes a style object shaped like the block config's style section, so merchants can restyle them without code.

Layout and structure

  • Box — a view with an optional background: { kind: 'image' | 'gradient' | 'solid' | 'none' }. Use for any container that needs a background asset; plain containers can stay Views.
  • Row / Column — flex containers, so you stop typing flexDirection by hand.
  • Spacer — a fixed gap whose dimensions live in config.
  • Header — the standard "section title + optional image + see-all link" row. Don't hand-roll a heading with a chevron.
  • BlockSection — the root wrapper for a block: pass it the useBlock result and it renders the configured header, navigation button, and content padding for you. Most "carousel of cards" blocks should start here. (Section is its lower-level primitive when you need to bypass the config plumbing.)

Content

  • Text — themed text leaf; set style.kind to pick a typography token. Use it for every text node instead of React Native's Text.
  • Image — responsive image that rounds widths to CDN breakpoints and adapts quality to the connection. Requires a uri and a width or height; returns null otherwise.
  • Icon — renders a registered SVG by iconId, with a remote-URL fallback.
  • HtmlRichText — renders an HTML string (product descriptions, rich-text metafields stored as HTML) with per-tag styles.
  • ShopifyRichText — renders Shopify's rich-text JSON format (what rich_text metafields contain). Use HtmlRichText for raw HTML instead.
  • Video — native MP4/HLS playback, portrait by default; all react-native-video props pass through.
  • YoutubeVideo — thumbnail-plus-play-button YouTube embed.

Interaction

  • Button — pressable CTA with text, optional start/end icons, loading and disabled states, and theme kinds (primary / secondary / tertiary).
  • Link — a pressable that routes a config link ({ kind, value }) through the app's navigation. Use it when the pressable is purely navigational; use Button when it looks like a CTA.
  • Accordion — self-managed expand/collapse panel with animated layout and configurable icons. Always prefer it over a hand-rolled Pressable + state.

Lists

  • List — virtualized scrolling list (FlatList under the hood). For a static handful of items, a plain .map() is lighter.
  • VerticalList — multi-column grid with row/column separators and correct handling of a partial last row. Use for 2+ column grids.

Helper elements

Higher-level, config-shaped compositions. Each renders a complete section from a data prop plus optional layout and style overrides. Use them when your block is "one of the usual sections" rather than a bespoke design.

Cta, Faq, Media, MediaList, MediaListAccordion, RichTextElement (Shopify rich text), RichTextAccordion, RichTextList, TestimonialsList, TextElement, LinkButton, VideoHelperElement, VideoList, HtmlRichTextElement, and YoutubeVideoComponent.

Layout elements

The units a config-declared layout is assembled from. You will mostly meet them indirectly, since the platform instantiates them from layout config, but they are exported for blocks that render layout regions themselves:

TextLayoutItem, ImageLayoutItem, RichTextLayoutItem, HtmlRichTextLayoutItem, AccordionLayoutItem, ListLayoutItem, LinkLayoutItem, LinkButtonLayoutElement, VideoLayoutElement, SpacerLayoutElement.

Layout-driven rendering: Content and getLayoutItem

Content is a block that renders whatever layout its config declares — the fully config-driven end of the spectrum, where even the structure is data. Under the hood it calls getLayoutItem(layout, source, style, options), which resolves a layout tree into the layout elements above. Call getLayoutItem yourself when your own block needs to render a config-declared region inside otherwise hand-written UI.

Putting it together

A card composed from atoms, with an image, a title, and a CTA inside a padded column:

src/app/blocks/feature-card.tsx
import { Button, Column, Image, Text } from '@gauntlet/ui-builder'

<Column style={settings.style?.root}>
  <Image uri={imageUrl} width={width} aspectRatio={1.5} resizeMode="cover" />
  <Text style={settings.style?.title}>{title}</Text>
  <Button
    style={settings.style?.button ?? {}}
    text={ctaText}
    onPress={handlePress}
  />
</Column>

Every element's style comes from the block's style section, so the whole card restyles from the dashboard. Copy that pattern: elements from this catalog, data and styling from config. See it in a full block in Custom blocks.

On this page