themes-noir/contact_sheet.go
Alex Dunmow 1bebbea5ad initial: theme plugin noir
Bootstrapped during the 2026-06-06 BlockNinja consolidation. Was previously
an unversioned directory inside ~/src/blockninja-themes/noir.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-06 14:11:40 +08:00

56 lines
1.4 KiB
Go

package main
import (
"bytes"
"context"
"git.dev.alexdunmow.com/block/core/blocks"
)
// ContactSheetBlockMeta defines the Noir contact sheet block.
var ContactSheetBlockMeta = blocks.BlockMeta{
Key: "contact_sheet",
Title: "Contact Sheet",
Description: "Numbered photograph frames with sprocket motif evoking a darkroom contact sheet.",
Source: "noir",
Category: blocks.CategoryContent,
}
// ContactSheetBlock renders a contact-sheet grid.
// Content shape: {"items":[{"image":"...","frame":"01","label":"..."}, ...]}
func ContactSheetBlock(ctx context.Context, content map[string]any) string {
items := getSlice(content, "items")
var frames []ContactFrame
for i, item := range items {
frame := getString(item, "frame")
if frame == "" {
frame = padFrame(i + 1)
}
frames = append(frames, ContactFrame{
Image: blocks.ResolveMediaPath(getString(item, "image")),
Frame: frame,
Label: getString(item, "label"),
})
}
var buf bytes.Buffer
_ = contactSheetComponent(frames).Render(ctx, &buf)
return buf.String()
}
// ContactFrame represents a single numbered frame in the contact sheet.
type ContactFrame struct {
Image string
Frame string
Label string
}
// padFrame zero-pads a frame number to two digits ("01", "02", ..., "10").
func padFrame(n int) string {
if n < 10 {
return "0" + intToString(n)
}
return intToString(n)
}