Skip to content

Design Editors ​

Design editors define the styling options merchants can adjust in the Instant Site Editor. Each editor maps to a specific design widget — color pickers, font selectors, background controls, and more.

Overview ​

All design editors are created using factory functions from @lightspeed/crane-api:

typescript
import { design } from '@lightspeed/crane-api';
TypeFactoryPurpose
TEXTdesign.text()Text styling (font, size, color, bold, italic, visibility)
BUTTONdesign.button()Button appearance, size, shape, color, font
IMAGEdesign.image()Image overlay (color, gradient, or none)
TOGGLEdesign.toggle()Boolean design toggle
SELECTBOXdesign.selectbox()Design dropdown selection
BACKGROUNDdesign.background()Background color or gradient
COLOR_PICKERdesign.colorPicker()Standalone color selection
LOGOdesign.logo()Logo styling (font, spacing, frame, capitalization)
DIVIDERdesign.divider()Visual separator in the editor
INFOdesign.info()Informational text in the editor
ACCORDIONdesign.accordion()Collapsible group of design editors

Color Values ​

Several design editors accept color values. Colors can be:

  • Hex colors: '#RGB', '#RRGGBB', or '#RRGGBBAA' format
  • Global colors: Reference the store's global color palette:
    • 'global.color.title'
    • 'global.color.body'
    • 'global.color.button'
    • 'global.color.link'
    • 'global.color.background'

Color Configuration Options ​

Several editors support these optional properties for controlling color selection:

PropertyTypeDescription
colorsstring[]Restricts the color picker to a specific set of colors
enableAlphaColorbooleanEnables transparency (alpha channel) in the color picker
enableAutoColorbooleanEnables the "auto" color option (uses global color)

Global Text Sizes ​

Text size defaults can be a specific integer (pixels) or a reference to a global text size:

  • 'global.textSize.title'
  • 'global.textSize.subtitle'
  • 'global.textSize.body'

Global Fonts ​

Font defaults can be a custom font family name or a reference to a global font:

  • 'global.fontFamily.title'
  • 'global.fontFamily.body'

TEXT ​

Text styling for headings, paragraphs, and other text content.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
colorsstring[]NoRestrict available colors
sizesinteger[]NoRestrict available font sizes (each >= 1)
enableAlphaColorbooleanNoEnable transparency in color picker
enableAutoColorbooleanNoEnable auto color option
hideVisibleTogglebooleanNoHide the visibility toggle in the editor
hideSizebooleanNoHide the size selector in the editor
defaultsobjectNoDefault values

Defaults ​

PropertyTypeRequiredDescription
fontstringNoFont family
sizeinteger | stringNoFont size in pixels, or a global text size reference
boldbooleanNoBold text
italicbooleanNoItalic text
colorstringNoHex color or global color reference
visiblebooleanNoWhether the element is visible

Factory ​

typescript
design.text({
  label: '$label.design.title_style',
  defaults: {
    font: 'global.fontFamily.title',
    size: 'global.textSize.title',
    bold: true,
    italic: false,
    color: 'global.color.title',
    visible: true,
  },
})

BUTTON ​

Button styling including appearance, size, shape, color, and font.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
colorsstring[]NoRestrict available colors
enableAutoColorbooleanNoEnable auto color option
enableAlphaColorbooleanNoEnable transparency in color picker
hideVisibleTogglebooleanNoHide the visibility toggle
hideSizebooleanNoHide the size selector
defaultsobjectNoDefault values

Defaults ​

PropertyTypeRequiredDescription
appearancestringNo"SOLID", "OUTLINE", or "TEXT"
sizestringNo"SMALL", "MEDIUM", or "LARGE"
shapestringNo"ROUND_CORNER", "RECTANGLE", or "PILL"
fontstringNoFont family
colorstringNoHex color or global color reference
visiblebooleanNoWhether the button is visible

Factory ​

typescript
design.button({
  label: '$label.design.button_style',
  defaults: {
    appearance: 'SOLID',
    size: 'MEDIUM',
    shape: 'ROUND_CORNER',
    color: 'global.color.button',
    visible: true,
  },
})

IMAGE ​

Image design controls for overlay effects.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
staticbooleanNoMust match the content IMAGE editor's static value
colorsstring[]NoRestrict available colors (hex only)
enableAlphaColorbooleanNoEnable transparency in color picker
hideVisibleTogglebooleanNoHide the visibility toggle
defaultsobjectNoDefault values

Defaults ​

PropertyTypeRequiredDescription
overlaystringNo"COLOR", "GRADIENT", or "NONE"
colorstring | string[]NoOverlay color(s) — see rules below
visiblebooleanNoWhether the image is visible

Overlay Color Rules ​

OverlayColor Requirement
"COLOR"color is required and must be a single color value
"GRADIENT"color is required and must be an array of exactly 2 colors
"NONE" or not setcolor must not be defined

Factory ​

typescript
design.image({
  label: '$label.design.hero_image',
  defaults: { overlay: 'COLOR', color: '#00000066' },
})

⚠️ Validation

  • The static flag must match between content and design IMAGE editors for the same field. Mismatch produces: "Both content and design editor need to have same value for attribute static."
  • Invalid color/overlay combinations produce specific errors. For example, providing a single color when overlay is GRADIENT produces: "color must be an array when overlay is GRADIENT."

TOGGLE ​

Boolean design toggle for enabling or disabling design features.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
defaultsobjectNoDefault values

Defaults ​

PropertyTypeRequiredDescription
enabledbooleanNoDefault toggle state

Factory ​

typescript
design.toggle({
  label: '$label.design.enable_animation',
  defaults: { enabled: true },
})

SELECTBOX ​

Dropdown selection for design options.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
descriptionstringNoTranslation key for description text
optionsarrayNoArray of selectable options
defaultsobjectNoDefault values

Each option:

PropertyTypeRequiredDescription
valuestringNoOption value
labelstringNoTranslation key for option label

Defaults ​

PropertyTypeRequiredDescription
valuestringNoDefault selected value

Factory ​

typescript
design.selectbox({
  label: '$label.design.layout_style',
  description: '$label.design.layout_style_desc',
  options: [
    { value: 'compact', label: '$label.options.compact' },
    { value: 'spacious', label: '$label.options.spacious' },
  ],
  defaults: { value: 'compact' },
})

BACKGROUND ​

Background color or gradient controls.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
colorsstring[]NoRestrict available colors
enableAlphaColorbooleanNoEnable transparency in color picker
enableAutoColorbooleanNoEnable auto color option
defaultsobjectNoDefault values

Defaults ​

PropertyTypeRequiredDescription
stylestringNo"COLOR" or "GRADIENT"
colorstring | string[]NoBackground color(s) — see rules below

Background Color Rules ​

StyleColor Requirement
"COLOR"color is required and must be a single color value
"GRADIENT"color is required and must be an array of exactly 2 colors

Factory ​

typescript
// Solid color
design.background({
  label: '$label.design.section_background',
  defaults: { style: 'COLOR', color: '#FFFFFF' },
})

// Gradient
design.background({
  label: '$label.design.section_background',
  defaults: { style: 'GRADIENT', color: ['#FF0000', '#0000FF'] },
})

⚠️ Validation

Invalid color/style combinations produce errors:

  • "color is required when style is GRADIENT"
  • "color must be an array when style is GRADIENT"
  • "color array must have exactly 2 items when style is GRADIENT"
  • "color must be a single value when style is COLOR"

COLOR_PICKER ​

Standalone color picker for custom color settings that don't fit into other editor types.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
descriptionstringNoTranslation key for optional helper copy the site editor shows with this color picker (placement and styling are defined by the editor, not the theme)
colorsstring[]NoRestrict available colors
enableAlphaColorbooleanNoEnable transparency in color picker
enableAutoColorbooleanNoEnable auto color option
defaultsobjectNoDefault values

Defaults ​

PropertyTypeRequiredDescription
colorstringNoHex color or global color reference

Factory ​

typescript
design.colorPicker({
  label: '$label.design.accent_color',
  description: '$label.design.accent_color_help',
  defaults: { color: '#FF5733' },
})

TIP

Use design.colorPicker() from @lightspeed/crane-api so section design config stays aligned with validation and types.

Logo styling controls including text formatting, spacing, frame, and capitalization. This editor is specific to logo elements.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the editor label
colorsstring[]NoRestrict available colors
sizesinteger[]NoRestrict available font sizes (each >= 1)
defaultsobjectNoDefault values

Defaults ​

PropertyTypeRequiredDescription
fontstringNoFont family
sizeinteger | stringNoFont size in pixels, or a global text size reference
boldbooleanNoBold text
italicbooleanNoItalic text
colorstringNoHex color or global color reference
visiblebooleanNoWhether the logo is visible
spacingintegerNoLetter spacing (1–9)
frameobjectNoLogo frame configuration
capitalizationstringNo"none", "all", or "small"

The frame object:

PropertyTypeRequiredDescription
visiblebooleanYesWhether the frame is visible
widthintegerNoFrame width (1–49)
colorstringNoHex color or global color reference

Factory ​

typescript
design.logo({
  label: '$label.design.logo_style',
  defaults: {
    font: 'global.fontFamily.title',
    size: 24,
    bold: true,
    color: 'global.color.title',
    visible: true,
    spacing: 2,
    capitalization: 'none',
    frame: { visible: false },
  },
})

ℹ️ Mandatory for Headers

The LOGO design editor is mandatory for sections with type HEADER. It must be defined with the key logo. See Sections.

DIVIDER ​

Visual separator in the design editor UI. Does not affect storefront rendering.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the divider label
defaultsobjectNoDefault values (empty, type only)

Factory ​

typescript
design.divider({
  label: '$label.design.advanced_options',
})

INFO ​

Informational text displayed in the design editor UI. Like DIVIDER, this does not affect storefront rendering — it provides guidance or contextual help to merchants within the design panel.

Properties ​

PropertyTypeRequiredDescription
labelstringYesTranslation key for the info title
descriptionstringYesTranslation key for the info description
buttonobjectNoOptional link button in the editor

The button object:

PropertyTypeRequiredDescription
labelstringYesTranslation key for button text
linkstringYesURL (must be a valid URL)

Defaults ​

PropertyTypeRequiredDescription
descriptionstringNoDefault info text (translation key)
buttonobjectNoDefault button configuration (optional)
button.labelstringNoDefault button text (translation key)
button.linkstringNoDefault button URL (must be a valid URL)

Factory ​

typescript
design.info({
  label: '$label.design.help_info',
  description: '$label.design.help_description',
  button: {
    label: '$label.design.learn_more',
    link: 'https://docs.example.com',
  },
})

ACCORDION ​

Groups multiple design editors into collapsible accordion sections in the Instant Site Editor. Each accordion item has a label and contains a set of nested design editors. This is purely an organizational tool for the editor UI — it does not affect storefront rendering directly. The nested editors within the accordion are what control the actual styling. This is useful for organizing complex design panels with many settings into logical, expandable categories.

Properties ​

PropertyTypeRequiredDescription
itemsobjectYesMap of accordion items keyed by unique item identifier
sortablebooleanNoIf true, merchants can reorder items within this accordion group; when enabled, each item must define its own positionFieldName

Each accordion item:

PropertyTypeRequiredDescription
labelstringYesTranslation key for the accordion item header
positionFieldNamestringConditionalKey of the editor within this item that stores the sort position for that item (required when the accordion's sortable property is true)
editorsobjectYesMap of design editors within this accordion item

Within an accordion item, the editors object can contain standard design editors such as TEXT, BUTTON, IMAGE, TOGGLE, SELECTBOX, BACKGROUND, COLOR_PICKER, LOGO, and DIVIDER (for example, design.selectbox(), design.toggle(), design.divider(), design.text(), etc.), but it cannot contain another ACCORDION or an INFO editor.

Factory ​

typescript
design.accordion({
  sortable: true,
  items: {
    page_settings: {
      label: '$label.accordion.page_settings',
      positionFieldName: 'sortPosition',
      editors: {
        sortPosition: design.selectbox({
          label: '$label.sort_position.label',
          options: [
            { value: '1', label: '$label.sort_position.first' },
            { value: '2', label: '$label.sort_position.second' },
          ],
          defaults: { value: '1' },
        }),
        layout: design.selectbox({
          label: '$label.layout_style.label',
          options: [
            { value: 'GRID', label: '$label.layout_style.grid' },
            { value: 'LIST', label: '$label.layout_style.list' },
          ],
          defaults: { value: 'GRID' },
        }),
        showFilters: design.toggle({
          label: '$label.show_filters.label',
          defaults: { enabled: true },
        }),
      },
    },
    card_settings: {
      label: '$label.accordion.card_settings',
      positionFieldName: 'sortPosition',
      editors: {
        sortPosition: design.selectbox({
          label: '$label.sort_position.label',
          options: [
            { value: '1', label: '$label.sort_position.first' },
            { value: '2', label: '$label.sort_position.second' },
          ],
          defaults: { value: '1' },
        }),
        cardSize: design.selectbox({
          label: '$label.card_size.label',
          options: [
            { value: 'SMALL', label: '$label.card_size.small' },
            { value: 'LARGE', label: '$label.card_size.large' },
          ],
          defaults: { value: 'LARGE' },
        }),
        showBorder: design.toggle({
          label: '$label.show_border.label',
          defaults: { enabled: false },
        }),
      },
    },
  },
})

💡 Nested Editor Access

Use the useAccordionElementDesign composable to access nested editor values from within your Vue component. See UI Composables for details.

Showcase Default Factories ​

When defining showcase configurations, the design.default.*() factories create standalone default values:

typescript
import { design } from '@lightspeed/crane-api';

design.default.text({ font: 'Arial', size: 18, bold: false, color: '#333333', visible: true });
design.default.button({ appearance: 'SOLID', size: 'MEDIUM', shape: 'PILL', color: '#000000', visible: true });
design.default.background({ style: 'COLOR', color: '#F5F5F5' });
design.default.image({ overlay: 'NONE' });
design.default.colorPicker({ color: '#FF0000' });
design.default.logo({ font: 'Arial', size: 20, color: '#000000', visible: true });
design.default.toggle({ enabled: true });
design.default.selectbox({ value: 'default' });
design.default.info({ description: '$label.showcase.info_text' });
design.default.accordion({
  items: {
    page_settings: {
      editors: {
        layout: design.default.selectbox({ value: 'GRID' }),
      },
    },
    card_settings: {
      editors: {
        showBorder: design.default.toggle({ enabled: false }),
      },
    },
  },
});

See Showcases for usage in showcase files.

Complete Example ​

typescript
// settings/design.ts
import { design } from '@lightspeed/crane-api';

export default {
  title_style: design.text({
    label: '$label.design.title_style',
    defaults: {
      font: 'global.fontFamily.title',
      size: 'global.textSize.title',
      bold: true,
      italic: false,
      color: 'global.color.title',
      visible: true,
    },
  }),
  description_style: design.text({
    label: '$label.design.description_style',
    defaults: {
      font: 'global.fontFamily.body',
      size: 'global.textSize.body',
      bold: false,
      color: 'global.color.body',
      visible: true,
    },
  }),
  button_style: design.button({
    label: '$label.design.button_style',
    defaults: {
      appearance: 'SOLID',
      size: 'MEDIUM',
      shape: 'ROUND_CORNER',
      color: 'global.color.button',
      visible: true,
    },
  }),
  section_background: design.background({
    label: '$label.design.background',
    defaults: { style: 'COLOR', color: '#FFFFFF' },
  }),
  hero_image: design.image({
    label: '$label.design.hero_image',
    defaults: { overlay: 'NONE' },
  }),
  help_info: design.info({
    label: '$label.design.help_info',
    description: '$label.design.help_description',
    button: {
      label: '$label.design.learn_more',
      link: 'https://docs.example.com',
    },
  }),
  styling: design.accordion({
    items: {
      page_settings: {
        label: '$label.accordion.page_settings',
        editors: {
          layout: design.selectbox({
            label: '$label.layout_style.label',
            options: [
              { value: 'GRID', label: '$label.layout_style.grid' },
              { value: 'LIST', label: '$label.layout_style.list' },
            ],
            defaults: { value: 'GRID' },
          }),
          showFilters: design.toggle({
            label: '$label.show_filters.label',
            defaults: { enabled: true },
          }),
        },
      },
    },
  }),
};