@pack/types: TypeScript Type Definitions

The @pack/types provides TypeScript definitions for Pack projects, enabling strong type-checking of sections and data to enhance code quality and developer productivity.

For release notes on every version, see the @pack/types changelog.

Quick Start

Install with a package manager:

npm install @pack/types

Here is a list of exports from this package:

import type {
  // Sections and settings
  Section,
  SectionSchema,
  SectionConfig,
  SectionMap,
  SiteSetting,
  TemplateDataType,
  // Fields
  FormField,
  TextField,
  TextAreaField,
  ImageField,
  MarkdownField,
  RichTextField,
  LinkField,
  NumberField,
  ColorField,
  DateField,
  ProductSearchField,
  CollectionsField,
  ProductBundlesField,
  HtmlField,
  TagsField,
  GroupField,
  ListField,
  GroupListField,
  BlocksField,
  ToggleField,
  SelectField,
  RadioGroupField,
  DimensionField,
  VolumeField,
  WeightField,
  MoneyField,
} from '@pack/types';

// Zod schemas used for validation
import {
  SectionObjectSchema,
  SiteSettingsObjectSchema,
  FormFieldSchema,
  FormFieldComponentSchema,
  TemplateData,
} from '@pack/types';

Typing Your Sections For Validation

You can utilize @pack/types for both section and storefront setting schema validation. Validation issues are logged as warnings in your terminal and browser console when registerSection() or registerStorefrontSettingsSchema() runs.

Start by typing your section and storefront settings schemas by importing the Section and SiteSetting from @pack/types which are now expected when using @pack/react registerSection() and registerStorefrontSettingsSchema().

When using registerSection, type the passed in section schema, for example:

/sections/index.ts

    import {registerSection} from '@pack/react';
    import type {Section} from '@pack/types';

    export function registerSections() {
      registerSection(TabbedThreeTiles as Section, {name: 'tabbed-three-tiles'});
      registerSection(ThreeTiles as Section, {name: 'three-tiles'});
      registerSection(TwoTiles as Section, {name: 'two-tiles'});
    }

When using registerStorefrontSettingsSchema, type the passed in site setting schema, for example:

/storefront-settings/index.ts

    import {registerStorefrontSettingsSchema} from '@pack/react';
    import type {SiteSetting} from '@pack/types';

    export function registerStorefrontSettings() {
      registerStorefrontSettingsSchema([
        account as SiteSetting,
        analytics as SiteSetting,
        cart as SiteSetting,
        collection as SiteSetting,
        footer as SiteSetting,
      ]);
    }

Core Schema Types

Section: The base type for all section components. Sections are the building blocks of pages in Pack. A section is a React component with a Schema property: an object, or a function that receives the template data and returns one.

type Section = React.ComponentType<any> & {
  Schema: SectionSchema | ((data: TemplateDataType) => SectionSchema)
}

SectionSchema: Defines the configuration structure for a section: its label, key, and fields. See The section schema.

type SectionSchema = {
  label: string
  key: string
  fields: FormField[]
  category?: string
  previewSrc?: string
  dataSource?: {
    source: 'shopify'
    type: 'metaobject'
    reference: {type: string}
  }
  description?: string
  defaultValue?: any
  defaultItem?: any
}

SectionMap: A map of section keys to sections.

type SectionMap = Map<string, Section>

SiteSetting: One site settings schema. It has the same shape as a field, usually a group with its own fields.

type SiteSetting = FormField

Field Types

Each field type below lists every property it accepts.

Text & Content Fields

TextField: Single-line text input. See Text Field.

type TextField = {
  component: 'text'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

TextAreaField: Multi-line text input. See Text Area Field.

type TextAreaField = {
  component: 'textarea'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

RichTextField: Rich text editor. Outputs an HTML string. See Rich Text Field.

type RichTextField = {
  component: 'rich-text'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

MarkdownField: Markdown editor. See Markdown Field.

type MarkdownField = {
  component: 'markdown'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

HtmlField: HTML code editor. See HTML Field.

type HtmlField = {
  component: 'html'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

TagsField: Tags entered one at a time. Outputs an array of strings. See Tags Field.

type TagsField = {
  component: 'tags'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

Media & Link Fields

ImageField: Image selected from the Media Manager. See Image Field.

type ImageField = {
  component: 'image'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

LinkField: Links to a page in your storefront or an external site. See Link Field.

type LinkField = {
  component: 'link'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

Numeric, Measurement & Date Fields

NumberField: Numeric input, as a text box or a slider. Set the slider's bounds with validate.min and validate.max. See Number Field.

type NumberField = {
  component: 'number'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  min?: number // not read by the Customizer; use validate.min
  max?: number // not read by the Customizer; use validate.max
  step?: number
  variant?: 'input' | 'slider'
}

DimensionField: A length with a value and unit, matching Shopify's dimension metafield type. See Dimension Field.

type DimensionField = {
  component: 'dimension'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

VolumeField: A volume with a value and unit, matching Shopify's volume metafield type. See Volume Field.

type VolumeField = {
  component: 'volume'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

WeightField: A weight with a value and unit, matching Shopify's weight metafield type. See Weight Field.

type WeightField = {
  component: 'weight'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

MoneyField: An amount and currency code, matching Shopify's money metafield type. See Money Field.

type MoneyField = {
  component: 'money'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

DateField: Date picker. See Date Field.

type DateField = {
  component: 'date'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  dateFormat?: boolean | string
  timeFormat?: boolean | string
}

ColorField: Color picker. See Color Field.

type ColorField = {
  component: 'color'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  colorFormat?: string
  colors?: string[]
  widget?: 'sketch' | 'block'
}

Product & Collection Fields

ProductSearchField: Search for and select a Shopify product. See Product Field.

type ProductSearchField = {
  component: 'productSearch'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

CollectionsField: Select a Shopify collection. See Collection Field.

type CollectionsField = {
  component: 'collections'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

ProductBundlesField: Select a product bundle from Pack. See Product Bundles Field.

type ProductBundlesField = {
  component: 'productBundles'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
}

Group & List Fields

GroupField: Groups related fields together. See Group Field.

type GroupField = {
  component: 'group'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  fields: FormField[]
}

ListField: A repeatable list of a single field. See List Field.

type ListField = {
  component: 'list'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  field: {component: string}
  defaultItem?: unknown
}

GroupListField: A repeatable list of field groups. See Group List Field.

type GroupListField = {
  component: 'group-list'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  fields: FormField[]
  defaultItem?: unknown
}

BlocksField: Dynamic blocks of content with different schemas. Editors can add inline block templates, registered sections listed in sectionTypes, or both. See Blocks Field.

type BlocksField = {
  component: 'blocks'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  /** Inline block templates editors can add via the picker */
  templates?: Record<
    string,
    {
      label: string
      key: string
      category?: string
      itemProps?: {label: string} | ((...args: unknown[]) => unknown)
      fields?: FormField[]
      defaultItem?: unknown
    }
  >
  /** Registered section schema keys that editors can embed as blocks */
  sectionTypes?: string[]
  defaultItem?: unknown
}

At least one of templates or sectionTypes must be defined. A blocks field with neither logs a validation warning (0.2.0), and so does a key that appears in both sectionTypes and templates (0.2.1), since that overlap breaks saving in the Customizer.

Selection Fields

ToggleField: Boolean on/off toggle. See Toggle Field.

type ToggleField = {
  component: 'toggle'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  toggleLabels?: {true: string | boolean; false: string | boolean}
}

SelectField: Dropdown that returns the selected option's value. See Select Field.

type SelectField = {
  component: 'select'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  options?: Array<{label: string; value: string}> | string[]
}

RadioGroupField: Radio inputs that return the selected option's value, shown vertically or horizontally, as radios or buttons. See Radio Group Field.

type RadioGroupField = {
  component: 'radio-group'
  name: string
  label: string
  description?: string
  defaultValue?: unknown
  required?: boolean
  disabled?: boolean
  disabledTooltip?: string
  showLabel?: boolean
  showField?: boolean
  itemProps?: {label: string} | ((...args: unknown[]) => unknown)
  validate?:
    | {max?: number; maxItems?: number; min?: number; required?: boolean}
    | ((...args: unknown[]) => unknown)
  format?: (...args: unknown[]) => unknown
  parse?: (...args: unknown[]) => unknown
  options?: Array<{label: string; value: string}> | string[]
  direction?: 'horizontal' | 'vertical'
  variant?: 'radio' | 'button'
}

FormField is the union of all of these field types.

Was this page helpful?