Are you an LLM? Read llms.txt for a summary of the docs, or llms-full.txt for the full context.
Props – Vev Developer
Skip to content

Props

Props are properties sent from the Design Editor to your component(s).

Base

All props share these common properties:

Name/typeDescription
name
string
Name of the prop
type
string
Type of the prop. Can be one of the following:
string | number | boolean | image | video | audio | color | icon | object | array | select | link | upload | menu | layout | variable.
title
string
Title of the prop visible in the editor. If not set, a sentence case of the name will be used
description
string
Description of the prop visible in the editor.
component
ReactNode
Replaces the field with a custom React component.
initialValue
JSON
The initial value for the field. Have to match the type of the field. Can also be a function or async function returning the value. Function takes one argument with the type context.
validate
boolean | function
Can either be boolean or a function returning boolean. The first argument of the function is the value of the field and the second is the context of the entire form.
hidden
boolean | function
Hide/show field. Can either be boolean or a function returning boolean. The first argument of the function is the context of the entire form. The second is the index of the current array item, or undefined if the field is not inside an array. Can be used to toggle visibility based on values from other fields, e.g. hidden: (context, index) => !context.value.cards[index].showTitle.
onChange
function
A custom onChange for the field. The first argument of the function is the value of the field and the second is the context of the entire form.
storage
string
Select where to store values for the component (like API keys etc.). Can be project | workspace | account.
flex
boolean
When true, the field stretches to fill available space inside a row layout.

String

A field type for string.

type: "string",

Options:

OptionsDescription
type
string
Can be 'text' | 'date' | 'email' | 'url' | 'password'. Default is text.
multiline
boolean | number
Select if the field should be multiline or not. Can either be boolean or a number representing the lines of the text the field should include.
placeholder
string
Placeholder text shown when the field is empty.
minLength
number
The minimum characters for the field.
maxLength
number
The maximum characters for the field.
Example:
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'title',
      type: 'string',
      options: {
        multiline: 3,
        placeholder: 'Enter a title...',
      },
    },
  ],
});

See recipe: Hello World

Number

A field type for number.

type: "number",
OptionsDescription
min
number
The minimum value (in display space — after scaling).
max
number
The maximum value (in display space — after scaling).
scale
number
Display scaling factor. The stored value is multiplied by this for display. E.g. scale: 100 displays 0–1 as 0–100.
display
string
The appearance of the field. Can be 'input' | 'slider' | 'range-slider'.
Default is: input. The range-slider displays a dual-handle slider and stores a [min, max] tuple.
formats
string[]
Allowed unit formats for the number input (e.g. ["px", "%", "em", "None"]). Defaults to ["None"] (plain number). When a format other than None is selected, the stored value includes the unit suffix (e.g. "20px").
precision
number
Number of decimal places. Overrides the default precision for the format. When format is None, defaults to 0 (integers).
placeholder
string
Placeholder text shown when the field is empty.
Example:
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    // Simple number input (stores integer)
    { name: 'count', type: 'number' },
    // Slider with scaling: stores 0–1, displays 0–100%
    {
      name: 'opacity',
      type: 'number',
      options: { min: 0, max: 100, scale: 100, display: 'slider' },
    },
    // Range slider: stores [min, max] tuple
    {
      name: 'priceRange',
      type: 'number',
      options: { min: 0, max: 1000, display: 'range-slider' },
    },
    // Number with units
    {
      name: 'width',
      type: 'number',
      options: { formats: ['px', '%', 'em'] },
    },
    // Decimal precision
    {
      name: 'ratio',
      type: 'number',
      options: { precision: 2 },
    },
  ],
});

Boolean

A field type for boolean. Displays a toggle switch by default, or a checkbox.

type: "boolean",
OptionsDescription
display
string
Can be 'toggle' | 'checkbox'. Default is toggle.
Example:
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    { name: 'showOnMobile', type: 'boolean' },
    { name: 'acceptTerms', type: 'boolean', options: { display: 'checkbox' } },
  ],
});

See recipe: Conditional rendering

Select

Can be used to display either radio buttons, a dropdown, checkbox list, or autocomplete.

type: "select",

Options:

OptionsDescription
items
array
An array of options in this format: label: string, value: string.
Can also be async.
display
string
Can be: 'checkbox' | 'radio' | 'dropdown' | 'autocomplete'.
Default is dropdown.
multiselect
boolean
If it should be possible to select multiple values.
placeholder
string
Placeholder text when nothing is selected.
Example:
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'selectFruits',
      type: 'select',
      options: {
        display: 'radio',
        items: [
          { label: 'Apple', value: 'apple' },
          { label: 'Orange', value: 'orange' },
          { label: 'Banana', value: 'banana' },
        ],
      },
    },
  ],
});

See recipe: Select

Image

A field type for image. This will display an image upload field in the editor.

type: "image",
Example:
import { Image } from '@vev/react';
 
function MyComponent({ image }) {
  return <Image src={image} />;
}
 
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'image',
      type: 'image',
      title: 'Image',
    },
  ],
});

The Image component from @vev/react accepts a src prop with the image value. It handles responsive images and optimized loading automatically.

See recipe: Image with caption

Video

A field type for video. This will display a video upload field in the editor.

type: "video",
Example:
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'video',
      type: 'video',
    },
  ],
});

Audio

A field type for audio. This will display an audio upload field in the editor.

type: "audio",
Example:
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'audio',
      type: 'audio',
    },
  ],
});

Color

A field type for color. This will display a color picker in the editor. The stored value is a color string (hex, rgba, etc.).

type: "color",
Example:
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'backgroundColor',
      type: 'color',
    },
  ],
});

See recipe: Editable CSS

Icon

A field type for icon. This will display an icon/shape picker in the editor. Stores the full shape object { key, name, path } where path is [width, height, pathData].

type: "icon",
Example:
import { Icon } from '@vev/react';
 
function MyComponent({ icon }) {
  return <Icon d={icon} />;
}
 
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'icon',
      type: 'icon',
      title: 'Icon',
    },
  ],
});

The Icon component from @vev/react accepts a d prop with the icon value. It handles SVG shapes, legacy path arrays, and image URLs automatically.

Link

A field for link. This will display a link field in the editor. This will give a search field for internal links. If an internal link is not selected it will behave like an external link.

type: "link",
registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'link',
      type: 'link',
    },
  ],
});

Object

A field type for object. This can be used to display fields in a group. All the Vev props can be used as fields.

type: "object",
fields: VevProps[],

Example

registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'header',
      type: 'object',
      fields: [
        {
          name: 'title',
          type: 'string',
        },
        { name: 'subtitle', type: 'string' },
        { name: 'image', type: 'image' },
      ],
    },
  ],
});

Array

A field type for array. The of property defines which item types are available when adding to the list.

Simple arrays

For arrays of a single primitive type, set of to 'string' or 'number':

{
  name: 'tags',
  type: 'array',
  of: 'string',
}

Array of objects with fields

Set of to 'object' and provide fields directly on the array field:

{
  name: 'links',
  type: 'array',
  of: 'object',
  fields: [
    { name: 'label', type: 'string' },
    { name: 'url', type: 'string', options: { type: 'url' } },
    { name: 'external', type: 'boolean' },
  ],
}

Mixed arrays

When of contains multiple entries, the editor shows a dropdown when adding an item so the user can choose the type:

{
  name: 'content',
  type: 'array',
  of: [
    {
      name: 'text',
      type: 'object',
      title: 'Text Block',
      fields: [
        { name: 'heading', type: 'string' },
        { name: 'body', type: 'string', options: { multiline: 3 } },
      ],
    },
    {
      name: 'image',
      type: 'object',
      title: 'Image Block',
      fields: [
        { name: 'src', type: 'image' },
        { name: 'alt', type: 'string' },
      ],
    },
  ],
}

List preview

Every element in an array field can have a custom list preview. If not defined, the editor will try to find a title and image from the data.

OptionsDescription
preview
object
can either be an object or a function which returns an object: title: string, image: string.

Example

registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'products',
      type: 'array',
      of: 'object',
      fields: [
        { name: 'title', type: 'string' },
        { name: 'price', type: 'number' },
        { name: 'image', type: 'image' },
      ],
      preview(value) {
        return {
          title: value.title,
          image: value.image?.url,
        };
      },
    },
  ],
});

See recipe: Card list

Layout containers

Container field types organize the form UI without creating properties in the form value.

Layout row

Arranges child fields in a row or column. Use flex: true on fields that should stretch to fill available space.

{
  type: 'layout',
  options: { display: 'row' },
  fields: [
    { name: 'x', type: 'number', title: 'X', flex: true },
    { name: 'y', type: 'number', title: 'Y', flex: true },
  ],
}

Options:

OptionsDescription
display
string
Can be row | column. Default is row.

Group

A collapsible card section. Set collapsed: true in options to start closed.

{
  type: 'group',
  title: 'Advanced Settings',
  options: { collapsed: true },
  fields: [
    { name: 'zIndex', type: 'number' },
    { name: 'cssClass', type: 'string' },
  ],
}

Popover

An icon button that opens a popover with nested fields. Useful for tucking away secondary settings.

{
  type: 'popover',
  title: 'Spacing',
  options: { icon: 'settings' },
  fields: [
    { name: 'padTop', type: 'number', title: 'Top' },
    { name: 'padBottom', type: 'number', title: 'Bottom' },
  ],
}

Divider

A horizontal line to visually separate groups of fields.

{ type: 'divider' }

Full layout example

registerVevComponent(MyComponent, {
  name: 'Hero Section',
  props: [
    { name: 'heading', type: 'string', initialValue: 'Welcome' },
    { name: 'body', type: 'string', options: { multiline: 3 } },
    { type: 'divider' },
    {
      type: 'group',
      title: 'Layout',
      fields: [
        {
          type: 'layout', options: { display: 'row' },
          fields: [
            { name: 'columns', type: 'number', title: 'Cols', flex: true },
            { name: 'gap', type: 'number', title: 'Gap', flex: true },
          ],
        },
        {
          type: 'layout', options: { display: 'row' },
          fields: [
            { name: 'align', type: 'select', title: 'Align', flex: true, options: {
              display: 'dropdown',
              items: [
                { label: 'Left', value: 'left' },
                { label: 'Center', value: 'center' },
                { label: 'Right', value: 'right' },
              ],
            }},
            {
              type: 'popover',
              title: 'Spacing',
              options: { icon: 'settings' },
              fields: [
                { name: 'padTop', type: 'number', title: 'Top' },
                { name: 'padBottom', type: 'number', title: 'Bottom' },
              ],
            },
          ],
        },
      ],
    },
    {
      type: 'group',
      title: 'Advanced',
      options: { collapsed: true },
      fields: [
        { name: 'lazyLoad', type: 'boolean' },
        { name: 'anchor', type: 'string', title: 'Anchor ID' },
      ],
    },
  ],
});

Upload

A field to be used for uploading files.

type: "upload",
fields: VevProps[],

Options:

OptionsDescription
accept
string
A comma separated list of unique file type specifiers.

Example

registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      type: 'upload',
      accept: '.jpg,.png',
    },
  ],
});

Menu

A field for adding/editing project menus. Use in conjunction with useMenu.

type: "menu",

Example

registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'projectMenu',
      type: 'menu',
    },
  ],
});

Variable

A field used for getting variable keys. Use in conjunction with useVariable and useSetVariable.

type: "variable",

Options:

OptionsDescription
variableType
string
Filter variables by type. Can be 'color' | 'number' | 'font' | 'text'.

Example

registerVevComponent(MyComponent, {
  name: 'My component',
  props: [
    {
      name: 'variableKey',
      type: 'variable',
    },
  ],
});

See Recipes for practical examples using props.