Envisioning LogoEnvisioning App (1.0.3)
Configuration

Blocks

Configure reusable UI components for page layouts

Overview

Blocks are reusable UI components that display data. They are defined once in the blocks array and referenced by ID in page configurations.

import type { Config } from "@envisioning/app";

const blocks: Config["navigation"]["blocks"] = [
  {
    id: "entitiesList",
    block: "GridBlock",
    schemaKey: "entities",
    itemBlockId: "entityListItem",
    gap: 1.5,
  },
];

Block Structure

Every block has:

PropertyTypeRequiredDescription
idstringYesUnique identifier referenced in pages
blockstringYesBlock type name
...configvariousVariesBlock-specific configuration

Available Block Types

Block TypeDescription
GridBlockGrid layout for lists of items
ListItemBlockSingle list item with icon, labels
CardItemBlockCard with image and nested blocks
ItemTitleBlockTitle display with main/extra labels
TextBlockSimple text display
MarkdownBlockMarkdown content rendering
ImageBlockImage display with various options
MiniChartBlockSmall metric visualization
DivisionBlockSection divider with optional label
DashBlockDecorative dash/line
SourceListBlockList of sources/links
PaginationBlockNext/previous navigation
SearchFieldBlockSearch input field
ScopeMenuBlockScope selector
MetricHelperBlockMetric explanation panel
ChartLegendBlockChart legend display
CopyrightBlockCopyright notice

See the Blocks reference for detailed documentation of each block type.


Template Syntax

Block properties support template interpolation with {placeholder} syntax:

{
  id: "entityTitle",
  block: "ItemTitleBlock",
  mainLabel: "{context.title}",
  extraLabel: "{context.collection.title}",
}

Available prefixes:

  • context - Current item data (in detail pages)
  • block - Current block's resolved data
  • data - Full application data
  • config - Configuration object

Common Patterns

List with Items

A grid displaying multiple items, each rendered with a sub-block:

// Grid block
{
  id: "entitiesList",
  block: "GridBlock",
  schemaKey: "entities",      // Data source from schema
  itemBlockId: "entityItem",  // Block to render each item
  gap: 1.5,
}

// Item block
{
  id: "entityItem",
  block: "ListItemBlock",
  schemaKey: "entities",
  iconName: "circleFillEv",
  iconColor: "accent",
  mainLabel: "{context.title}",
  extraLabel: "{context.collection.title}",
  to: { page: "technology" },
  showFavorite: true,
  variant: "labelTop",
  size: "lg",
}

Cards Grid

// Cards container
{
  id: "entitiesCards",
  block: "GridBlock",
  schemaKey: "entities",
  itemBlockId: "entityCard",
  gap: 3,
}

// Card item
{
  id: "entityCard",
  block: "CardItemBlock",
  schemaKey: "entities",
  mainLabel: "{context.title}",
  extraLabel: "{context.collection.title}",
  to: { page: "technology" },
  showFavorite: true,
  contentBlocks: ["trlChart", "spacer", "costChart"],
  variant: "labelTop",
  size: "md",
}

Text Content

{
  id: "contextSummary",
  block: "MarkdownBlock",
  markdown: "{context.summary}",
}

{
  id: "aboutText",
  block: "MarkdownBlock",
  markdown: "{data.project.about}",
}

Metric Charts

{
  id: "trlChart",
  block: "MiniChartBlock",
  noDataLabel: "N/A",
  metricJoinKey: "trl",
  textSize: "md",
  chartSize: "sm",
  chartType: "ProgressSteps",
  colorOn: "accent",
  addBox: true,
  resultMain: "{block.label}",
  resultMore: "{block.description}",
  resultShort: "{block.value}/{config.schema.objects.trl.metricDomain[1]}",
  ticksMode: "default",
  showHelp: true,
}

Layout Helpers

// Spacers
{
  id: "spacerLg",
  block: "DivisionBlock",
  marginTop: "lg",
}

// Dividers with labels
{
  id: "divisionSources",
  block: "DivisionBlock",
  label: "SOURCES ({context.sources.length})",
  labelColor: "dimmed",
  marginTop: "md",
  labelSize: "xs",
}

// Decorative dash
{
  id: "dash",
  block: "DashBlock",
  color: "accent",
  size: "lg",
  gap: "xl",
  align: "left",
}

// Horizontal rule
{
  id: "hr",
  block: "DashBlock",
  color: "border",
  size: "full",
  gap: "xl2",
  align: "center",
}
{
  id: "techsPagination",
  block: "PaginationBlock",
  color: "accent",
  background: "panel",
  mode: "nextPrevious",
  path: "{data.allEntities}",
  isCyclic: true,
  pathToLabel: "title",
}

{
  id: "panelSearch",
  block: "SearchFieldBlock",
}

Images

{
  id: "coverImage",
  block: "ImageBlock",
  url: "/cover.png",
  bgSize: "cover",
  rounded: true,
  aspectRatio: "video",
}

{
  id: "techImage",
  block: "ImageBlock",
  url: "{context.image.url}",
  rounded: true,
  isExpandable: false,
  color: "panel-down",
  bgSize: "cover",
  aspectRatio: "video",
  maxHeight: 400,
}

Color Values

Common color values used in blocks:

ColorDescription
accentPrimary accent color
foregroundMain text color
dimmedMuted text color
borderBorder color
panelPanel background
panel-downDarker panel
transparentNo color
grayGray color

Size Values

Common size values:

SizeDescription
xsExtra small
smSmall
mdMedium
lgLarge
xlExtra large
xl2, xl3Larger variants

Complete Example

export const blocks: Config["navigation"]["blocks"] = [
  // List blocks
  {
    id: "entitiesList",
    block: "GridBlock",
    schemaKey: "entities",
    itemBlockId: "entityListItem",
    gap: 1.5,
  },
  {
    id: "entityListItem",
    block: "ListItemBlock",
    schemaKey: "entities",
    iconName: "circleFillEv",
    iconColor: "accent",
    mainLabel: "{context.title}",
    extraLabel: "{context.collection.title}",
    to: { page: "technology" },
    showFavorite: true,
    variant: "labelTop",
    size: "lg",
  },

  // Content blocks
  {
    id: "contextSummary",
    block: "MarkdownBlock",
    markdown: "{context.summary}",
  },
  {
    id: "trlChart",
    block: "MiniChartBlock",
    metricJoinKey: "trl",
    chartType: "ProgressSteps",
    colorOn: "accent",
    resultMain: "{block.label}",
    showHelp: true,
  },

  // Layout blocks
  {
    id: "spacerMd",
    block: "DivisionBlock",
    marginTop: "md",
  },
  {
    id: "dash",
    block: "DashBlock",
    color: "accent",
    size: "lg",
    align: "left",
  },

  // Navigation
  {
    id: "panelSearch",
    block: "SearchFieldBlock",
  },
  {
    id: "pagination",
    block: "PaginationBlock",
    mode: "nextPrevious",
    path: "{data.allEntities}",
    isCyclic: true,
  },
] as const;

On this page