Reference

Component Props Reference

Components in Meno are reusable structures with typed interfaces. Each prop in the interface declares its type, default value, and optional configuration. Props are defined in components/*.json and their values are passed via the props object on component node instances.


Prop Types

Type

Description

Editor Control

Default Value Type

string

Single-line text

Text input

string

number

Numeric value

Number input

number

boolean

True/false toggle

Checkbox

boolean

select

Dropdown from options

Select dropdown

string

link

URL with optional target

Link editor

{ href, target }

file

File path (upload)

File picker

string

rich-text

HTML content

Rich text editor

string

list

Array of structured items

List editor

object[]

There is NO "image" type. For images, use file with accept: "image/*".


Type Definitions

string

Single-line text input.

{
  "title": { "type": "string", "default": "Hello World" }
}

number

Numeric input.

{
  "count": { "type": "number", "default": 3 }
}

boolean

Toggle switch in the editor.

{
  "visible": { "type": "boolean", "default": true }
}

select

Dropdown selection from predefined options.

{
  "variant": {
    "type": "select",
    "options": ["primary", "secondary", "ghost"],
    "default": "primary"
  }
}

Select props can also reference project-level enums:

{
  "size": {
    "type": "select",
    "enumName": "sizes",
    "default": "md"
  }
}

link

URL with optional target. The editor shows a link input with target toggle.

{
  "cta": {
    "type": "link",
    "default": { "href": "/", "target": "_blank" }
  }
}

The value is an object: { "href": "/about", "target": "_blank" }. The target field is optional.

file

File upload. The accept property restricts file types using MIME patterns.

{
  "avatar": { "type": "file", "accept": "image/*", "default": "" },
  "document": { "type": "file", "accept": "application/pdf", "default": "" }
}

rich-text

HTML content edited with a rich text editor.

{
  "body": { "type": "rich-text", "default": "<p>Enter content here.</p>" }
}

list

Array of structured items. Each item follows a schema defined by itemSchema.

{
  "features": {
    "type": "list",
    "itemSchema": {
      "icon": { "type": "file", "accept": "image/*", "default": "" },
      "title": { "type": "string", "default": "Feature" },
      "description": { "type": "string", "default": "" }
    },
    "default": [
      { "icon": "", "title": "Fast", "description": "Built for speed" }
    ]
  }
}

The itemSchema uses the same prop types as the component interface, except nested list types are not allowed.


Prop Configuration Properties

Property

Applies To

Description

type

All

Prop type (required)

default

All

Default value

options

select

Array of allowed values

enumName

select

Reference to a project-level enum name

accept

file

MIME pattern for file type filtering (e.g., "image/*", "video/*")

itemSchema

list

Record of prop definitions for each list item


Reserved Names

Never use "children" as a prop name. The children key is reserved for slot content passed to the component instance.


Using Props in Component Structure

Props are referenced in the component structure using {{propName}} template expressions.

Text Interpolation

Use {{propName}} in children to insert prop values as text:

{
  "component": {
    "interface": {
      "title": { "type": "string", "default": "Hello" },
      "subtitle": { "type": "string", "default": "World" }
    },
    "structure": {
      "type": "node",
      "tag": "div",
      "children": [
        { "type": "node", "tag": "h2", "children": "{{title}}" },
        { "type": "node", "tag": "p", "children": "{{subtitle}}" }
      ]
    }
  }
}

Attribute Interpolation

Use {{propName}} in attribute values:

{
  "component": {
    "interface": {
      "imageSrc": { "type": "file", "accept": "image/*", "default": "" },
      "imageAlt": { "type": "string", "default": "" }
    },
    "structure": {
      "type": "node",
      "tag": "img",
      "attributes": {
        "src": "{{imageSrc}}",
        "alt": "{{imageAlt}}"
      }
    }
  }
}

Style Mappings

Map prop values to CSS values using _mapping objects:

{
  "component": {
    "interface": {
      "variant": {
        "type": "select",
        "options": ["primary", "secondary"],
        "default": "primary"
      }
    },
    "structure": {
      "type": "node",
      "tag": "button",
      "style": {
        "base": {
          "backgroundColor": {
            "_mapping": true,
            "prop": "variant",
            "values": {
              "primary": "var(--primary)",
              "secondary": "var(--secondary)"
            }
          },
          "padding": "12px 24px"
        }
      },
      "children": "{{text}}"
    }
  }
}

The _mapping object has three fields:

Field

Type

Description

_mapping

true

Marker that identifies this as a style mapping

prop

string

Name of the interface prop to read

values

`Record<string, string \

number>`

Map from prop values to CSS values

Conditional Rendering with Props

Use a mapping in the if property to conditionally render nodes:

{
  "type": "node",
  "tag": "div",
  "if": {
    "_mapping": true,
    "prop": "showBanner",
    "values": { "true": true, "false": false }
  },
  "children": "This is conditionally rendered."
}

Link Mappings

For link nodes, map a link-type prop to the href:

{
  "type": "link",
  "href": { "_mapping": true, "prop": "cta" },
  "children": ["{{ctaText}}"]
}

When values is omitted from a link mapping, it acts as a passthrough for link-type props.


Internationalized Prop Values

Prop values can be localized using the _i18n object format:

{
  "type": "component",
  "component": "Hero",
  "props": {
    "title": { "_i18n": true, "en": "Welcome", "pl": "Witaj" },
    "subtitle": { "_i18n": true, "en": "Get started", "pl": "Rozpocznij" }
  }
}

The correct value is automatically resolved based on the current locale during rendering.


Component JavaScript and CSS

Components can include custom JavaScript and CSS:

{
  "component": {
    "interface": {
      "duration": { "type": "number", "default": 300 }
    },
    "structure": {
      "type": "node",
      "tag": "div",
      "children": "Animated element"
    },
    "javascript": "console.log('Component mounted');",
    "css": ".custom-class { transition: all 0.3s ease; }",
    "defineVars": true
  }
}

The defineVars property controls prop injection into JavaScript:

  • true: all interface props are available as JavaScript variables

  • string[]: only specified props are exposed

  • Omitted: no automatic prop injection


Full Component Example

{
  "component": {
    "interface": {
      "title": { "type": "string", "default": "Card Title" },
      "image": { "type": "file", "accept": "image/*", "default": "" },
      "variant": {
        "type": "select",
        "options": ["default", "featured"],
        "default": "default"
      },
      "link": { "type": "link", "default": { "href": "#" } }
    },
    "structure": {
      "type": "node",
      "tag": "article",
      "style": {
        "base": {
          "borderRadius": "8px",
          "overflow": "hidden",
          "border": {
            "_mapping": true,
            "prop": "variant",
            "values": {
              "default": "1px solid var(--border)",
              "featured": "2px solid var(--primary)"
            }
          }
        }
      },
      "children": [
        {
          "type": "node",
          "tag": "img",
          "attributes": { "src": "{{image}}", "alt": "{{title}}" }
        },
        {
          "type": "node",
          "tag": "div",
          "style": { "base": { "padding": "16px" } },
          "children": [
            { "type": "node", "tag": "h3", "children": "{{title}}" },
            { "type": "slot" }
          ]
        },
        {
          "type": "link",
          "href": { "_mapping": true, "prop": "link" },
          "children": ["Read more"]
        }
      ]
    }
  }
}

Next Steps

Building the future of digital experiences, one website at a time

© 2026 Company. All rights reserved.