Skip to main content

Controls

Controls are user input fields that dynamically adjust elements in templates. They allow users to customize templates by changing text, images, and other properties.

Overview​

Controls connect user input to template elements, enabling dynamic customization:

  • Value Controls: Change the content of elements (text, images)
  • Visibility Controls: Show or hide elements based on user selection
  • Control Types: Various input types for different use cases

Control Object​

interface Control {
id: string; // UUID (must match valueControlId exactly!)
label: string; // Display name
type: ControlType; // Control type
displayOrder: number; // Order in UI

// Control-specific
defaultValue?: string; // Default value
maxCharacters?: number; // Max characters (for text)
options?: string[]; // Options (for select)
aspectRatio?: string; // Aspect ratio (for image)
textTransform?: "uppercase" | "lowercase" | "none";
supportsFormatableText?: boolean; // BBCode formatting?

// Exclusive groups
exclusiveGroupIds?: string[]; // IDs of ExclusiveGroups
optionGroups?: Record<string, string>; // Map options to groups
exclusiveOptions?: Record<string, string[]>; // Options that exclude specific groups

// Image controls
backgroundPreference?: 'transparent'; // Auto-remove image background on upload

// Sub-controls
parentControlId?: string; // Makes this a sub-control of another control

// AI assistance
aiHint?: string; // Hint for AI-assisted value generation
aiGenerated?: boolean; // AI should suggest a value for this control
}

Control Types​

TypeDescriptionExample
text_inputSingle-line text input"Headline"
textareaMulti-line text input"Description"
checkboxBoolean toggle"Show logo"
selectDropdown selection"Button style"
numberNumeric input"Price"
colorColor picker"Accent color"
dateDate picker"Event date"
imageImage upload"Main image"
image_videoImage or video upload"Background"
layer_group_selectSelects an active layer group (design variation)"Style variant"

Text Input​

Single-line text input for short text like headlines or labels:

{
"id": "headline-control",
"label": "Headline",
"type": "text_input",
"defaultValue": "Welcome",
"maxCharacters": 50,
"textTransform": "uppercase"
}

Textarea​

Multi-line text input for longer content:

{
"id": "description-control",
"label": "Description",
"type": "textarea",
"defaultValue": "Enter your description here",
"maxCharacters": 500
}

Checkbox​

Boolean toggle for showing/hiding elements:

{
"id": "show-logo-control",
"label": "Show logo",
"type": "checkbox",
"defaultValue": "true"
}

Select​

Dropdown selection with predefined options:

{
"id": "button-style-control",
"label": "Button Style",
"type": "select",
"options": ["Primary", "Secondary", "Outline"],
"defaultValue": "Primary"
}

Image​

Image upload control:

{
"id": "product-image-control",
"label": "Product Image",
"type": "image",
"aspectRatio": "16:9"
}

Image/Video​

Control that accepts either image or video:

{
"id": "background-control",
"label": "Background",
"type": "image_video",
"aspectRatio": "1:1"
}

Image and image_video controls support an optional backgroundPreference property. When set to "transparent", uploaded images are automatically cut out (background removal):

{
"id": "product-control",
"label": "Product",
"type": "image",
"backgroundPreference": "transparent"
}

Layer Group Select​

Selects which layer group (design variation) is currently active. Layer groups let templates define mutually exclusive visual variants (e.g. "Dark", "Light", "Seasonal"):

{
"id": "variant-control",
"label": "Design Variant",
"type": "layer_group_select"
}

Element-Control Connection​

Value Control​

Value controls change the content of elements. The control ID must match the element's valueControlId exactly:

{
"control": {
"id": "headline-control-id",
"label": "Headline",
"type": "textarea"
},
"element": {
"type": "text",
"valueControlId": "headline-control-id" // ← Must match exactly!
}
}

How it works:

  • When the user changes the control value, the element's content updates automatically
  • For text elements, the text property is updated
  • For image elements, the content property is updated

Visibility Control​

Visibility controls show or hide elements based on user selection:

{
"control": {
"id": "logo-visibility-id",
"label": "Show logo",
"type": "checkbox",
"defaultValue": "true"
},
"element": {
"type": "image",
"visibilityControlId": "logo-visibility-id",
"visibilityControlValue": true // Visible when control = true
}
}

How it works:

  • When visibilityControlValue matches the control's value, the element is visible
  • When it doesn't match, the element is hidden
  • Useful for optional elements like logos, badges, or decorative items

Control Properties​

Display Order​

Controls the order in which controls appear in the UI:

{
"displayOrder": 0 // Lower numbers appear first
}

Default Value​

Sets the initial value when the template is loaded:

{
"defaultValue": "Welcome to heycreo"
}

Max Characters​

Limits the maximum number of characters for text controls:

{
"maxCharacters": 100
}

Text Transform​

Automatically transforms text case:

{
"textTransform": "uppercase" // Options: "uppercase", "lowercase", "capitalize", "none"
}

Formatable Text​

Enables BBCode formatting for text controls:

{
"supportsFormatableText": true
}

This allows users to use formatting like [b]bold[/b] or [i]italic[/i] in their text.

Exclusive Controls​

Exclusive controls prevent conflicting options from being selected simultaneously. This is useful when certain combinations don't make sense together (e.g., two elements can't both be positioned at the top).

How It Works​

There are two mechanisms for exclusive controls:

  1. Group-based exclusivity (bidirectional): Controls in the same group exclude each other
  2. Option-based exclusivity (unidirectional): Specific options exclude specific groups

Exclusive Groups​

First, define exclusive groups in the template:

{
"exclusiveControlGroups": [
{
"id": "position-top",
"name": "Position Top",
"description": "Elements positioned at the top"
},
{
"id": "position-bottom",
"name": "Position Bottom",
"description": "Elements positioned at the bottom"
}
]
}

Group-Based Exclusivity​

Controls can belong to exclusive groups. When two controls have options from the same group, they exclude each other.

Example:

  • Control A: "Text Position" with options "Top" (group: "position-top") and "Bottom" (group: "position-bottom")
  • Control B: "Badge Position" with options "Top" (group: "position-top") and "Bottom" (group: "position-bottom")

If Control A is set to "Top", Control B cannot be "Top" (must be "Bottom" or another compatible option).

{
"id": "text-position-control",
"label": "Text Position",
"type": "select",
"options": ["Top", "Bottom", "Middle"],
"exclusiveGroupIds": ["position-top", "position-bottom"],
"optionGroups": {
"Top": "position-top",
"Bottom": "position-bottom"
// "Middle" has no group - it's neutral
}
}

Option-Based Exclusivity​

Specific options can exclude entire groups, even if the control doesn't belong to those groups.

Example:

  • Control A has option "Special Mode" that excludes group "position-bottom"
  • When "Special Mode" is selected, any control with options in "position-bottom" is automatically changed
{
"id": "mode-control",
"label": "Display Mode",
"type": "select",
"options": ["Normal", "Special Mode"],
"exclusiveOptions": {
"Special Mode": ["position-bottom"] // This option excludes the "position-bottom" group
}
}

Practical Example​

Scenario: Prevent text and badge from both being at the top or both at the bottom.

{
"exclusiveControlGroups": [
{ "id": "content-top", "name": "Content Top" },
{ "id": "content-bottom", "name": "Content Bottom" }
],
"controls": [
{
"id": "text-variant-control",
"label": "Text Position",
"type": "select",
"options": ["Text Top", "Text Middle", "Text Bottom"],
"exclusiveGroupIds": ["content-top", "content-bottom"],
"optionGroups": {
"Text Top": "content-top",
"Text Bottom": "content-bottom"
// "Text Middle" is neutral
}
},
{
"id": "badge-variant-control",
"label": "Badge Position",
"type": "select",
"options": ["Badge Top", "Badge Bottom"],
"exclusiveGroupIds": ["content-top", "content-bottom"],
"optionGroups": {
"Badge Top": "content-top",
"Badge Bottom": "content-bottom"
}
}
]
}

Result:

  • If "Text Top" is selected, "Badge Top" is automatically changed to "Badge Bottom"
  • If "Badge Top" is selected, "Text Top" is automatically changed to "Text Middle" or "Text Bottom"
  • "Text Middle" can be combined with any badge position (it's neutral)

Best Practices​

  • Use descriptive labels: Make it clear what each control does
  • Set sensible defaults: Provide good default values for better UX
  • Order logically: Use displayOrder to organize controls in a logical flow
  • Match IDs exactly: Control IDs must match element control IDs exactly
  • Use visibility controls: Hide optional elements by default, show them with checkboxes
  • Use exclusive controls: Prevent conflicting combinations (e.g., two elements can't both be at the top)
  • Define groups clearly: Use meaningful group names and descriptions
  • Map all options: When using exclusiveGroupIds, map all options in optionGroups

See also​