OpenMAIC DSL SlideContent Type Structure: A Complete Guide

The SlideContent type in the OpenMAIC DSL is a discriminated union with a literal type: "slide" field that encapsulates a PPTCanvas drawing surface, optional background metadata, and runtime version tracking to represent fully qualified slide objects.

The SlideContent type serves as the core data structure for representing individual slides within the OpenMAIC presentation framework. Defined in the @openmaic/dsl npm package and re-exported through the main repository's type definitions, this interface provides the schema for canvas dimensions, element hierarchies, and slide-specific metadata. Understanding this structure is essential for developers building custom renderers, editors, or migration tools for the OpenMAIC ecosystem.

Structure of the SlideContent Type

SlideContent follows a discriminated union pattern where the type field acts as a singleton discriminator. According to the source in lib/types/stage.ts, the interface is re-exported from @openmaic/dsl and exposes the following fields:

Field Type Description
type "slide" Literal string discriminant identifying the content as a slide
canvas PPTCanvas The slide's drawing surface containing dimensions and renderable elements
schemaVersion? number Optional version identifier for schema migration handling
background? SlideBackground Optional background specification (solid color, gradient, or image)
metadata? Record<string, unknown> Arbitrary key-value pairs for editor or runtime annotations

The discriminant approach allows TypeScript to narrow union types effectively when processing mixed content collections.

The PPTCanvas Interface

The canvas property implements the PPTCanvas interface, which adopts a PPT-style coordinate system for rendering. In lib/types/stage.ts, this nested structure defines the spatial container for all slide elements:

interface PPTCanvas {
  /** Width in points (typically 720pt for standard 10-inch slide width) */
  width: number;
  /** Height in points (typically 540pt for standard 7.5-inch slide height) */
  height: number;
  /** Ordered array of elements rendered to the slide */
  elements: PPTElement[];
}

Each PPTElement within the elements array is itself a discriminated union representing drawable objects such as text boxes, images, shapes, or video embeds. Elements carry geometry properties (x, y, width, height, rotate) alongside content-specific payloads.

Runtime Type Guards

Because SlideContent participates in union types, the OpenMAIC DSL provides runtime validation through the isSlideContent guard function. Exported from lib/types/stage.ts and sourced from @openmaic/dsl, this utility performs structural validation:

import { isSlideContent } from '@/lib/types/stage';

// Returns true only if obj.type === 'slide' and required canvas field exists
if (isSlideContent(unknownObject)) {
  // TypeScript narrows unknownObject to SlideContent
  console.log(unknownObject.canvas.width);
}

Using this guard prevents runtime errors when handling data from external sources or untyped JSON payloads.

Working with SlideContent Objects

Creating a New Slide Programmatically

Instantiate a compliant SlideContent object by satisfying the discriminant and canvas requirements:

import type { SlideContent } from '@/lib/types/stage';
import { isSlideContent } from '@/lib/types/stage';

const blankSlide: SlideContent = {
  type: 'slide',
  schemaVersion: 4,
  canvas: {
    width: 720,
    height: 540,
    elements: []
  },
  background: { color: '#ffffff' },
  metadata: { author: 'system' }
};

if (isSlideContent(blankSlide)) {
  console.log('Slide validated and ready for rendering');
}

Adding Elements to an Existing Slide

Manipulate the immutable slide structure by spreading existing properties when adding new elements:

import type { SlideContent, PPTTextElement } from '@/lib/types/stage';

function addTitle(slide: SlideContent, title: string): SlideContent {
  const textElement: PPTTextElement = {
    type: 'text',
    id: `title-${Date.now()}`,
    x: 50,
    y: 30,
    width: 620,
    height: 80,
    rotate: 0,
    text: title,
    style: { fontSize: 36, fontWeight: 'bold', color: '#222222' }
  };

  return {
    ...slide,
    canvas: {
      ...slide.canvas,
      elements: [...slide.canvas.elements, textElement]
    }
  };
}

Migrating Legacy Slide Schemas

Handle version drift using the built-in migration utility:

import { migrateSlideContent } from '@/lib/types/stage';
import type { SlideContent } from '@/lib/types/stage';

const legacySlide: SlideContent = {
  type: 'slide',
  // Missing schemaVersion implies legacy data
  canvas: { width: 720, height: 540, elements: [] }
};

const currentSlide = migrateSlideContent(legacySlide);
console.log(`Migrated to schema version ${currentSlide.schemaVersion}`);

Key Implementation Files

The SlideContent type and its associated utilities are distributed across the following locations:

Summary

  • SlideContent is a discriminated union using type: "slide" as its discriminator, defined in @openmaic/dsl and re-exported from lib/types/stage.ts
  • The canvas property contains a PPTCanvas with width, height, and an ordered elements array of PPTElement objects
  • Optional fields include schemaVersion for migration tracking, background for visual styling, and metadata for extensibility
  • The isSlideContent runtime guard provides safe type narrowing when processing untyped data
  • The migrateSlideContent function handles schema evolution and backward compatibility

Frequently Asked Questions

How does OpenMAIC distinguish SlideContent from other content types?

OpenMAIC uses a discriminated union pattern where the literal string "slide" in the type property distinguishes SlideContent from other content variants. TypeScript leverages this literal type to provide automatic type narrowing in conditional blocks, while the isSlideContent runtime guard performs equivalent checks in JavaScript execution contexts.

What coordinate system does the PPTCanvas use?

The PPTCanvas interface adopts a point-based coordinate system consistent with PowerPoint specifications, typically operating at 72 DPI where 720 points equals 10 inches of width. All element positioning through x and y properties, as well as dimensions via width and height, reference this absolute coordinate space regardless of the target display resolution.

Can I extend SlideContent with custom fields?

The metadata?: Record<string, unknown> field provides an extension point for arbitrary data without breaking the core schema. Store custom annotations, editor state, or application-specific flags within this object while preserving type safety for standard SlideContent properties. Avoid modifying the canvas structure directly, as this may break renderer compatibility.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →