Storeware Docs

Components

Answer with nodes the shop front draws in its own style.

import { ... } from '@storeware/plugin-sdk/components';

countComponentNodes

Every node in a tree, children included.

function countComponentNodes(nodes: readonly ComponentNode[]): number

componentDepth

How deep a tree goes; a stack inside a stack is two.

function componentDepth(nodes: readonly ComponentNode[]): number

parseComponents

Parses an answer, or says why it cannot be drawn. Storeware runs the same check, so a tree this accepts is a tree the shop front draws.

function parseComponents(value: unknown): { ok: true; components: ComponentNode[]; } | { ok: false; problems: string[]; }

components

Builds an answer, checked, so a mistake shows in development, not on a shop.

function components(...nodes: ComponentNode[]): ComponentsAnswer

ComponentNode

type ComponentNode = {
    type: 'heading';
    text: string;
    level?: 2 | 3 | 4 | undefined;
} | {
    type: 'text';
    text: string;
    emphasis?: 'strong' | 'subdued' | undefined;
} | {
    type: 'list';
    items: string[];
    ordered?: boolean | undefined;
} | {
    type: 'table';
    head?: string[] | undefined;
    rows: string[][];
} | {
    type: 'rating';
    value: number;
    count?: number | undefined;
    label?: string | undefined;
} | {
    type: 'badge';
    text: string;
    tone?: (typeof COMPONENT_TONES)[number] | undefined;
} | {
    type: 'image';
    src: string;
    alt: string;
    width?: number | undefined;
    height?: number | undefined;
} | {
    type: 'link';
    text: string;
    href: string;
} | {
    type: 'button_link';
    text: string;
    href: string;
} | {
    type: 'accordion';
    items: {
        title: string;
        children: ComponentNode[];
    }[];
} | {
    type: 'notice';
    text: string;
    tone?: (typeof COMPONENT_TONES)[number] | undefined;
    title?: string | undefined;
} | {
    type: 'stack';
    children: ComponentNode[];
    direction?: 'row' | 'column' | undefined;
};

ComponentType

type ComponentType = ComponentNode['type'];

ComponentsAnswer

type ComponentsAnswer = z.infer<typeof componentsAnswerSchema>;

COMPONENTS_CONTENT_TYPE

const COMPONENTS_CONTENT_TYPE: 'application/vnd.storeware.components+json'

MAX_COMPONENT_NODES

The most nodes one answer may hold, counting every child.

const MAX_COMPONENT_NODES: 200

COMPONENT_IMAGE_HOSTS

The one host an image may come from. An app puts an image there with POST /api/v1/app/assets, which needs no scope, and uses the URL it gets.

const COMPONENT_IMAGE_HOSTS: readonly ['cdn.mystoreware.com']

COMPONENT_TONES

The tones a badge or notice can take, drawn from the theme's own colours.

const COMPONENT_TONES: readonly ['neutral', 'info', 'success', 'warning', 'critical']

COMPONENT_TYPES

const COMPONENT_TYPES: readonly ['heading', 'text', 'list', 'table', 'rating', 'badge', 'image', 'link', 'button_link', 'accordion', 'notice', 'stack']

componentNodeSchema

const componentNodeSchema: z.ZodType<ComponentNode, unknown, z.core.$ZodTypeInternals<ComponentNode, unknown>>

MAX_COMPONENT_DEPTH

The deepest a tree may nest. Enough for an accordion of stacks.

const MAX_COMPONENT_DEPTH: 4

componentsAnswerSchema

What an app answers with: \{ components: [...] \}.

const componentsAnswerSchema: z.ZodObject<{ components: z.ZodArray<z.ZodType<ComponentNode, unknown, z.core.$ZodTypeInternals<ComponentNode, unknown>>>; }, z.core.$strict>

On this page