Components

Components

Sol SSG provides a set of reusable, customizable components for building documentation sites, blogs, and landing pages.

Overview

Components are located in src/sol/ssg/components/ and cover common UI patterns:

ComponentFileDescription
Headerheader.mbtNavigation bar with logo, links, search, theme toggle
Footerfooter.mbtSite footer with columns, copyright, social links
TOCtoc.mbtTable of contents sidebar
Navigationnav_*.mbtSidebar navigation with collapsible sections
Blogblog.mbtPostCard, Hero, TagList for blog layouts
Registryregistry.mbtComponent override system

The header component supports flexible element-based composition.

Configuration

{
  "theme": {
    "header": {
      "sticky": true,
      "left": ["logo", "nav-links"],
      "center": [],
      "right": ["search", "theme-toggle", "social-links"]
    }
  }
}

Available Elements

ElementDescription
logoSite logo or title with link to home
nav-linksNavigation links from nav config
searchSearch input box
theme-toggleDark/light mode toggle button
social-linksGitHub, Twitter icons
lang-switcherLanguage selector dropdown
spacerFlexible spacer element
customCustom HTML tag

Theme Toggle

Built-in dark/light mode support with:

  • Sun/moon icons

  • System preference detection

  • Persisted user preference

Element-based footer with flexible layout.

Configuration

{
  "theme": {
    "footer": {
      "top": ["columns"],
      "bottom": ["message", "copyright", "social-links"],
      "links": [
        {
          "title": "Documentation",
          "items": [
            { "label": "Getting Started", "href": "/guide/" },
            { "label": "API Reference", "href": "/api/" }
          ]
        }
      ],
      "message": "Released under the MIT License.",
      "copyright": "Copyright 2024 Your Name"
    }
  }
}

Available Elements

ElementDescription
columnsLink columns from links config
messageFooter message text
copyrightCopyright notice
social-linksSocial media icons
customCustom HTML tag

Blog Components

Components for blog-style layouts.

PostCard

Display blog posts in a card format:

build_blog_post_card(page : PageMeta) -> Node[Unit]

Features:

  • Cover image (optional)

  • Title with link

  • Date and author

  • Description excerpt

  • Tags list

  • Featured badge

Hero Section

Full-width hero for landing pages:

build_blog_hero(
  title : String,
  subtitle : String?,
  cta_text : String?,
  cta_link : String?,
) -> Node[Unit]

Post Lists

// All posts (optionally limited)
build_blog_post_list(ctx, limit : Int?, featured_only : Bool)

// Featured posts section
build_featured_posts(ctx, limit : Int)

// Recent posts with title
build_recent_posts(ctx, limit : Int, title : String)

// Posts by tag
get_posts_by_tag(pages, tag : String)

Tag List

build_tag_list(tags : Array[String])      // With links
build_tag_list_inline(tags : Array[String]) // Display only

Component Registry

Override default components with custom implementations.

Basic Usage

let registry = ComponentRegistry::defaults()
  .with_header(my_custom_header)
  .with_footer(my_custom_footer)

// Use in rendering
registry.render_header(ctx, page)
registry.render_footer(ctx)

Available Overrides

MethodSignature
with_header(BuildContext, PageMeta) -> Node[Unit]
with_footer(BuildContext) -> Node[Unit]
with_toc(Array[TocItem]) -> Node[Unit]
with_breadcrumb(BuildContext, PageMeta) -> Node[Unit]
with_prev_next(BuildContext, PageMeta) -> Node[Unit]

Themes

CSS variable-based theming with light/dark mode support.

Built-in Themes

ThemeLayoutDescription
defaultDocDocumentation site with sidebar
blogBlogContent-focused, wider main area
minimalHomeClean and simple

Theme Structure

pub struct Theme {
  name : String
  default_layout : ThemeLayout  // Doc | Home | Blog | Landing
  light_colors : ThemeColors
  dark_colors : ThemeColors
  custom_css : String?
}

pub struct ThemeColors {
  primary : String      // Accent color
  text : String         // Main text
  text_muted : String   // Secondary text
  background : String   // Page background
  sidebar_bg : String   // Sidebar background
  border : String       // Border color
  code_bg : String      // Code block background
}

CSS Variables

Themes generate CSS custom properties:

:root {
  --primary-color: #b45309;
  --text-color: #1f2937;
  --text-muted: #4b5563;
  --bg-color: #ffffff;
  --sidebar-bg: #fafafa;
  --border-color: #e5e7eb;
  --code-bg: #f3f4f6;
  --link-color: var(--primary-color);
}

html.dark {
  --primary-color: #fbbf24;
  --text-color: #f3f4f6;
  /* ... dark mode overrides */
}

Creating Custom Theme

fn my_theme() -> Theme {
  {
    name: "custom",
    default_layout: Doc,
    light_colors: {
      primary: "#2563eb",
      text: "#111827",
      text_muted: "#6b7280",
      background: "#ffffff",
      sidebar_bg: "#f9fafb",
      border: "#e5e7eb",
      code_bg: "#f3f4f6",
    },
    dark_colors: {
      primary: "#60a5fa",
      text: "#f9fafb",
      text_muted: "#9ca3af",
      background: "#111827",
      sidebar_bg: "#1f2937",
      border: "#374151",
      code_bg: "#1f2937",
    },
    custom_css: Some(".my-class { ... }"),
  }
}

Layout Types

LayoutUse CaseFeatures
DocDocumentationSidebar + content + TOC
HomeLanding pageFull-width, no sidebar
BlogBlog postsContent-focused, optional sidebar
LandingMarketing pagesHero sections, CTAs

Component Discovery

Sol SSG automatically discovers custom components in your project.

Convention

Place component files in docs/components/:

docs/
โ””โ”€โ”€ components/
    โ”œโ”€โ”€ header.mbt      # Custom header
    โ”œโ”€โ”€ footer.mbt      # Custom footer
    โ””โ”€โ”€ toc.mbt         # Custom TOC

Discovery Result

let result = discover_components(config, cwd)
// result.found: [Header, Footer]
// result.missing: [Toc, Breadcrumb, PrevNext]  // Using defaults