Initial commit after recreate
This commit is contained in:
@@ -0,0 +1,9 @@
|
||||
{
|
||||
"name": "@gnommo/slide-contracts",
|
||||
"private": true,
|
||||
"version": "0.1.0",
|
||||
"type": "module",
|
||||
"exports": {
|
||||
".": "./src/index.ts"
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
import type { SlideTemplateKey } from "./templates";
|
||||
export interface FieldBudget {
|
||||
targetMin?: number;
|
||||
targetMax: number;
|
||||
hardMax: number;
|
||||
notes?: string;
|
||||
}
|
||||
export interface SlideTemplateBudget {
|
||||
template: SlideTemplateKey;
|
||||
description: string;
|
||||
fields: Record<string, FieldBudget>;
|
||||
}
|
||||
export declare const slideTemplateBudgets: Record<SlideTemplateKey, SlideTemplateBudget>;
|
||||
@@ -0,0 +1,138 @@
|
||||
export var slideTemplateBudgets = {
|
||||
SquareYellow: {
|
||||
template: "SquareYellow",
|
||||
description: "One image plus one short header.",
|
||||
fields: {
|
||||
header: { targetMin: 8, targetMax: 24, hardMax: 32 },
|
||||
imageAlt: { targetMin: 12, targetMax: 60, hardMax: 100 }
|
||||
}
|
||||
},
|
||||
SquareVideo: {
|
||||
template: "SquareVideo",
|
||||
description: "One video plus one short header.",
|
||||
fields: {
|
||||
header: { targetMin: 8, targetMax: 24, hardMax: 32 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
}
|
||||
}
|
||||
},
|
||||
FullscreenSplit: {
|
||||
template: "FullscreenSplit",
|
||||
description: "One image, one short text block.",
|
||||
fields: {
|
||||
eyebrow: { targetMin: 6, targetMax: 14, hardMax: 24 },
|
||||
title: { targetMin: 12, targetMax: 34, hardMax: 44 },
|
||||
body: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
},
|
||||
FullscreenVideo: {
|
||||
template: "FullscreenVideo",
|
||||
description: "Full-bleed video with optional short overlay text.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
},
|
||||
caption: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
},
|
||||
FullscreenVideoTitle: {
|
||||
template: "FullscreenVideoTitle",
|
||||
description: "Full-bleed video with one large overlaid title.",
|
||||
fields: {
|
||||
title: { targetMin: 12, targetMax: 26, hardMax: 36 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
}
|
||||
}
|
||||
},
|
||||
FullscreenVideoCenterCaption: {
|
||||
template: "FullscreenVideoCenterCaption",
|
||||
description: "Full-bleed video with one oversized centered caption.",
|
||||
fields: {
|
||||
caption: { targetMin: 12, targetMax: 30, hardMax: 42 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
}
|
||||
}
|
||||
},
|
||||
EquationFocus: {
|
||||
template: "EquationFocus",
|
||||
description: "One display equation plus one short annotation.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
title: { targetMin: 12, targetMax: 32, hardMax: 48 },
|
||||
latexString: {
|
||||
targetMin: 8,
|
||||
targetMax: 60,
|
||||
hardMax: 120,
|
||||
notes: "One expression only."
|
||||
},
|
||||
annotation: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
},
|
||||
QuoteImage: {
|
||||
template: "QuoteImage",
|
||||
description: "One quote plus one image.",
|
||||
fields: {
|
||||
quote: { targetMin: 18, targetMax: 50, hardMax: 72 },
|
||||
attribution: { targetMin: 4, targetMax: 18, hardMax: 24 }
|
||||
}
|
||||
},
|
||||
ChartSingle: {
|
||||
template: "ChartSingle",
|
||||
description: "One chart and one short framing line.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
title: { targetMin: 12, targetMax: 30, hardMax: 40 },
|
||||
body: { targetMin: 12, targetMax: 36, hardMax: 48 },
|
||||
pointLabel: { targetMin: 4, targetMax: 10, hardMax: 14 }
|
||||
}
|
||||
},
|
||||
ProcessFlow: {
|
||||
template: "ProcessFlow",
|
||||
description: "Short pipeline with 3-5 steps.",
|
||||
fields: {
|
||||
title: { targetMin: 12, targetMax: 34, hardMax: 44 },
|
||||
step: { targetMin: 8, targetMax: 22, hardMax: 30 }
|
||||
}
|
||||
},
|
||||
DefinitionCard: {
|
||||
template: "DefinitionCard",
|
||||
description: "One term, one definition, one concrete example.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
term: { targetMin: 6, targetMax: 22, hardMax: 28 },
|
||||
definition: { targetMin: 18, targetMax: 50, hardMax: 65 },
|
||||
example: { targetMin: 12, targetMax: 40, hardMax: 52 }
|
||||
}
|
||||
},
|
||||
GlitchComponentFrame: {
|
||||
template: "GlitchComponentFrame",
|
||||
description: "Interactive hosted component plus one short framing line.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
componentId: { targetMin: 4, targetMax: 24, hardMax: 40 },
|
||||
componentUrl: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted component URL."
|
||||
},
|
||||
caption: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,153 @@
|
||||
import type { SlideTemplateKey } from "./templates";
|
||||
|
||||
export interface FieldBudget {
|
||||
targetMin?: number;
|
||||
targetMax: number;
|
||||
hardMax: number;
|
||||
notes?: string;
|
||||
}
|
||||
|
||||
export interface SlideTemplateBudget {
|
||||
template: SlideTemplateKey;
|
||||
description: string;
|
||||
fields: Record<string, FieldBudget>;
|
||||
}
|
||||
|
||||
export const slideTemplateBudgets: Record<SlideTemplateKey, SlideTemplateBudget> = {
|
||||
SquareYellow: {
|
||||
template: "SquareYellow",
|
||||
description: "One image plus one short header.",
|
||||
fields: {
|
||||
header: { targetMin: 8, targetMax: 24, hardMax: 32 },
|
||||
imageAlt: { targetMin: 12, targetMax: 60, hardMax: 100 }
|
||||
}
|
||||
},
|
||||
SquareVideo: {
|
||||
template: "SquareVideo",
|
||||
description: "One video plus one short header.",
|
||||
fields: {
|
||||
header: { targetMin: 8, targetMax: 24, hardMax: 32 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
}
|
||||
}
|
||||
},
|
||||
FullscreenSplit: {
|
||||
template: "FullscreenSplit",
|
||||
description: "One image, one short text block.",
|
||||
fields: {
|
||||
eyebrow: { targetMin: 6, targetMax: 14, hardMax: 24 },
|
||||
title: { targetMin: 12, targetMax: 34, hardMax: 44 },
|
||||
body: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
},
|
||||
FullscreenVideo: {
|
||||
template: "FullscreenVideo",
|
||||
description: "Full-bleed video with optional short overlay text.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
},
|
||||
caption: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
},
|
||||
FullscreenVideoTitle: {
|
||||
template: "FullscreenVideoTitle",
|
||||
description: "Full-bleed video with one large overlaid title.",
|
||||
fields: {
|
||||
title: { targetMin: 12, targetMax: 26, hardMax: 36 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
}
|
||||
}
|
||||
},
|
||||
FullscreenVideoCenterCaption: {
|
||||
template: "FullscreenVideoCenterCaption",
|
||||
description: "Full-bleed video with one oversized centered caption.",
|
||||
fields: {
|
||||
caption: { targetMin: 12, targetMax: 30, hardMax: 42 },
|
||||
videoSrc: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted or CDN video URL."
|
||||
}
|
||||
}
|
||||
},
|
||||
EquationFocus: {
|
||||
template: "EquationFocus",
|
||||
description: "One display equation plus one short annotation.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
title: { targetMin: 12, targetMax: 32, hardMax: 48 },
|
||||
latexString: {
|
||||
targetMin: 8,
|
||||
targetMax: 60,
|
||||
hardMax: 120,
|
||||
notes: "One expression only."
|
||||
},
|
||||
annotation: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
},
|
||||
QuoteImage: {
|
||||
template: "QuoteImage",
|
||||
description: "One quote plus one image.",
|
||||
fields: {
|
||||
quote: { targetMin: 18, targetMax: 50, hardMax: 72 },
|
||||
attribution: { targetMin: 4, targetMax: 18, hardMax: 24 }
|
||||
}
|
||||
},
|
||||
ChartSingle: {
|
||||
template: "ChartSingle",
|
||||
description: "One chart and one short framing line.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
title: { targetMin: 12, targetMax: 30, hardMax: 40 },
|
||||
body: { targetMin: 12, targetMax: 36, hardMax: 48 },
|
||||
pointLabel: { targetMin: 4, targetMax: 10, hardMax: 14 }
|
||||
}
|
||||
},
|
||||
ProcessFlow: {
|
||||
template: "ProcessFlow",
|
||||
description: "Short pipeline with 3-5 steps.",
|
||||
fields: {
|
||||
title: { targetMin: 12, targetMax: 34, hardMax: 44 },
|
||||
step: { targetMin: 8, targetMax: 22, hardMax: 30 }
|
||||
}
|
||||
},
|
||||
DefinitionCard: {
|
||||
template: "DefinitionCard",
|
||||
description: "One term, one definition, one concrete example.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
term: { targetMin: 6, targetMax: 22, hardMax: 28 },
|
||||
definition: { targetMin: 18, targetMax: 50, hardMax: 65 },
|
||||
example: { targetMin: 12, targetMax: 40, hardMax: 52 }
|
||||
}
|
||||
},
|
||||
GlitchComponentFrame: {
|
||||
template: "GlitchComponentFrame",
|
||||
description: "Interactive hosted component plus one short framing line.",
|
||||
fields: {
|
||||
header: { targetMin: 6, targetMax: 20, hardMax: 28 },
|
||||
componentId: { targetMin: 4, targetMax: 24, hardMax: 40 },
|
||||
componentUrl: {
|
||||
targetMin: 12,
|
||||
targetMax: 160,
|
||||
hardMax: 300,
|
||||
notes: "Prefer a stable hosted component URL."
|
||||
},
|
||||
caption: { targetMin: 12, targetMax: 42, hardMax: 56 }
|
||||
}
|
||||
}
|
||||
};
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
export * from "./templates";
|
||||
export * from "./budgets";
|
||||
export * from "./metadata";
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./templates";
|
||||
export * from "./budgets";
|
||||
export * from "./metadata";
|
||||
@@ -0,0 +1,3 @@
|
||||
export * from "./templates";
|
||||
export * from "./budgets";
|
||||
export * from "./metadata";
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
import type { SlideTemplateKey, SlideTemplateProps } from "./templates";
|
||||
export type SlideTemplateFieldType = "text" | "textarea" | "lines" | "image" | "video" | "latex";
|
||||
export interface SlideTemplateFieldDefinition {
|
||||
name: string;
|
||||
type: SlideTemplateFieldType;
|
||||
label: string;
|
||||
placeholder?: string;
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
}
|
||||
export interface SlideTemplateDefinition {
|
||||
componentKey: SlideTemplateKey;
|
||||
label: string;
|
||||
description: string;
|
||||
displayMode: "square" | "fullscreen";
|
||||
supportedDisplayModes?: Array<"square" | "fullscreen">;
|
||||
fields: SlideTemplateFieldDefinition[];
|
||||
}
|
||||
export interface SlideTemplateAvailability {
|
||||
componentKey: SlideTemplateKey;
|
||||
label: string;
|
||||
description: string;
|
||||
displayMode: "square" | "fullscreen";
|
||||
fields: SlideTemplateFieldDefinition[];
|
||||
}
|
||||
export interface SlideTemplateDraft {
|
||||
props: SlideTemplateProps;
|
||||
latexString?: string;
|
||||
}
|
||||
export declare const slideTemplateDefinitions: Record<SlideTemplateKey, SlideTemplateDefinition>;
|
||||
export declare const slideTemplateDefinitionList: SlideTemplateDefinition[];
|
||||
export declare const slideTemplateAvailabilityList: SlideTemplateAvailability[];
|
||||
export declare const slideTemplateAvailabilityByDisplayMode: {
|
||||
square: SlideTemplateAvailability[];
|
||||
fullscreen: SlideTemplateAvailability[];
|
||||
};
|
||||
export declare const slideTemplateDrafts: Record<SlideTemplateKey, SlideTemplateDraft>;
|
||||
export declare function getSlideTemplateDefinition(componentKey: SlideTemplateKey): SlideTemplateDefinition;
|
||||
export declare function getSlideTemplateAvailability(displayMode?: "square" | "fullscreen"): SlideTemplateAvailability[];
|
||||
export declare function getSlideTemplateDraft(componentKey: SlideTemplateKey): SlideTemplateDraft;
|
||||
@@ -0,0 +1,546 @@
|
||||
var squareYellowDefaults = {
|
||||
header: "",
|
||||
imageSrc: "",
|
||||
imageAlt: ""
|
||||
};
|
||||
var squareVideoDefaults = {
|
||||
header: "",
|
||||
videoSrc: "",
|
||||
posterSrc: ""
|
||||
};
|
||||
var fullscreenSplitDefaults = {
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
body: "",
|
||||
imageSrc: "",
|
||||
imageAlt: "",
|
||||
imagePosition: "left"
|
||||
};
|
||||
var fullscreenVideoDefaults = {
|
||||
header: "",
|
||||
videoSrc: "",
|
||||
posterSrc: "",
|
||||
caption: ""
|
||||
};
|
||||
var fullscreenVideoTitleDefaults = {
|
||||
title: "No need to be discrete",
|
||||
videoSrc: "",
|
||||
posterSrc: ""
|
||||
};
|
||||
var fullscreenVideoCenterCaptionDefaults = {
|
||||
caption: "",
|
||||
videoSrc: "",
|
||||
posterSrc: ""
|
||||
};
|
||||
var equationFocusDefaults = {
|
||||
header: "",
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
annotation: ""
|
||||
};
|
||||
var quoteImageDefaults = {
|
||||
eyebrow: "",
|
||||
quote: "",
|
||||
attribution: "",
|
||||
imageSrc: "",
|
||||
imageAlt: "",
|
||||
imagePosition: "left"
|
||||
};
|
||||
var chartSingleDefaults = {
|
||||
header: "",
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
body: "",
|
||||
points: []
|
||||
};
|
||||
var processFlowDefaults = {
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
steps: []
|
||||
};
|
||||
var definitionCardDefaults = {
|
||||
header: "",
|
||||
eyebrow: "",
|
||||
term: "",
|
||||
definition: "",
|
||||
example: ""
|
||||
};
|
||||
var glitchComponentFrameDefaults = {
|
||||
header: "",
|
||||
componentId: "",
|
||||
componentUrl: "",
|
||||
caption: ""
|
||||
};
|
||||
export var slideTemplateDefinitions = {
|
||||
SquareYellow: {
|
||||
componentKey: "SquareYellow",
|
||||
label: "Square image + header",
|
||||
description: "Square image with a short external header.",
|
||||
displayMode: "square",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short headline",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageSrc",
|
||||
type: "image",
|
||||
label: "Image",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageAlt",
|
||||
type: "text",
|
||||
label: "Alt text",
|
||||
placeholder: "Describe the image",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
SquareVideo: {
|
||||
componentKey: "SquareVideo",
|
||||
label: "Square video + header",
|
||||
description: "Square video inside a framed square slide with a short header.",
|
||||
displayMode: "square",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short headline",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenSplit: {
|
||||
componentKey: "FullscreenSplit",
|
||||
label: "Fullscreen split",
|
||||
description: "Two-panel fullscreen slide with image and text.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "Main title",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "body",
|
||||
type: "textarea",
|
||||
label: "Body",
|
||||
placeholder: "Short supporting text",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageSrc",
|
||||
type: "image",
|
||||
label: "Image",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageAlt",
|
||||
type: "text",
|
||||
label: "Alt text",
|
||||
placeholder: "Describe the image",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imagePosition",
|
||||
type: "text",
|
||||
label: "Image position",
|
||||
placeholder: "left or right"
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenVideo: {
|
||||
componentKey: "FullscreenVideo",
|
||||
label: "Fullscreen video",
|
||||
description: "Full-bleed video slide with optional overlay text.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
},
|
||||
{
|
||||
name: "caption",
|
||||
type: "textarea",
|
||||
label: "Caption",
|
||||
placeholder: "Short framing note"
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenVideoTitle: {
|
||||
componentKey: "FullscreenVideoTitle",
|
||||
label: "Fullscreen video + title",
|
||||
description: "Full-bleed video with one oversized overlaid title.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "No need to be discrete"
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenVideoCenterCaption: {
|
||||
componentKey: "FullscreenVideoCenterCaption",
|
||||
label: "Fullscreen video + centered caption",
|
||||
description: "Full-bleed video with one oversized centered caption.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "caption",
|
||||
type: "text",
|
||||
label: "Caption",
|
||||
placeholder: "Short centered statement"
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
}
|
||||
]
|
||||
},
|
||||
EquationFocus: {
|
||||
componentKey: "EquationFocus",
|
||||
label: "Equation focus",
|
||||
description: "One display equation with a short annotation.",
|
||||
displayMode: "fullscreen",
|
||||
supportedDisplayModes: ["square", "fullscreen"],
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "What does the equation show?",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "latexString",
|
||||
type: "latex",
|
||||
label: "LaTeX equation",
|
||||
placeholder: "\\bar{x} = \\frac{1}{N}\\sum_{i=0}^{N} x_i",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "annotation",
|
||||
type: "textarea",
|
||||
label: "Annotation",
|
||||
placeholder: "One short explanation"
|
||||
}
|
||||
]
|
||||
},
|
||||
QuoteImage: {
|
||||
componentKey: "QuoteImage",
|
||||
label: "Quote + image",
|
||||
description: "Strong quote paired with one image.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "eyebrow",
|
||||
type: "text",
|
||||
label: "Eyebrow",
|
||||
placeholder: "Optional eyebrow"
|
||||
},
|
||||
{
|
||||
name: "quote",
|
||||
type: "textarea",
|
||||
label: "Quote",
|
||||
placeholder: "Short quote",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "attribution",
|
||||
type: "text",
|
||||
label: "Attribution",
|
||||
placeholder: "Person or source"
|
||||
},
|
||||
{
|
||||
name: "imageSrc",
|
||||
type: "image",
|
||||
label: "Image",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageAlt",
|
||||
type: "text",
|
||||
label: "Alt text",
|
||||
placeholder: "Describe the image",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imagePosition",
|
||||
type: "text",
|
||||
label: "Image position",
|
||||
placeholder: "left or right"
|
||||
}
|
||||
]
|
||||
},
|
||||
ChartSingle: {
|
||||
componentKey: "ChartSingle",
|
||||
label: "Single chart",
|
||||
description: "One compact chart with a short framing line.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "Chart title",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "body",
|
||||
type: "textarea",
|
||||
label: "Body",
|
||||
placeholder: "Short interpretation"
|
||||
},
|
||||
{
|
||||
name: "points",
|
||||
type: "lines",
|
||||
label: "Data points",
|
||||
placeholder: "Label: value",
|
||||
description: "One point per line. Format each line as label: value."
|
||||
}
|
||||
]
|
||||
},
|
||||
ProcessFlow: {
|
||||
componentKey: "ProcessFlow",
|
||||
label: "Process flow",
|
||||
description: "Short pipeline with 3 to 5 steps.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "eyebrow",
|
||||
type: "text",
|
||||
label: "Eyebrow",
|
||||
placeholder: "Optional eyebrow"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "Process title",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "steps",
|
||||
type: "lines",
|
||||
label: "Steps",
|
||||
placeholder: "One step per line",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
DefinitionCard: {
|
||||
componentKey: "DefinitionCard",
|
||||
label: "Definition card",
|
||||
description: "Term, definition, and optional example.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "term",
|
||||
type: "text",
|
||||
label: "Term",
|
||||
placeholder: "Key term",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "definition",
|
||||
type: "textarea",
|
||||
label: "Definition",
|
||||
placeholder: "Short definition",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "example",
|
||||
type: "textarea",
|
||||
label: "Example",
|
||||
placeholder: "Optional example"
|
||||
}
|
||||
]
|
||||
},
|
||||
GlitchComponentFrame: {
|
||||
componentKey: "GlitchComponentFrame",
|
||||
label: "Interactive Glitch component",
|
||||
description: "Hosted Glitch component embedded inside the slide surface.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "componentId",
|
||||
type: "text",
|
||||
label: "Component id",
|
||||
placeholder: "lightlane",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "componentUrl",
|
||||
type: "text",
|
||||
label: "Component URL",
|
||||
placeholder: "Optional hosted URL",
|
||||
description: "Optional URL for iframe-hosted components. Leave empty for known local component ids."
|
||||
},
|
||||
{
|
||||
name: "caption",
|
||||
type: "textarea",
|
||||
label: "Caption",
|
||||
placeholder: "Short framing note"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
export var slideTemplateDefinitionList = Object.values(slideTemplateDefinitions);
|
||||
export var slideTemplateAvailabilityList = slideTemplateDefinitionList.flatMap(function (definition) {
|
||||
var _a;
|
||||
var supportedDisplayModes = (_a = definition.supportedDisplayModes) !== null && _a !== void 0 ? _a : [definition.displayMode];
|
||||
return supportedDisplayModes.map(function (displayMode) { return ({
|
||||
componentKey: definition.componentKey,
|
||||
label: definition.label,
|
||||
description: definition.description,
|
||||
displayMode: displayMode,
|
||||
fields: definition.fields
|
||||
}); });
|
||||
});
|
||||
export var slideTemplateAvailabilityByDisplayMode = {
|
||||
square: slideTemplateAvailabilityList.filter(function (definition) { return definition.displayMode === "square"; }),
|
||||
fullscreen: slideTemplateAvailabilityList.filter(function (definition) { return definition.displayMode === "fullscreen"; })
|
||||
};
|
||||
export var slideTemplateDrafts = {
|
||||
SquareYellow: {
|
||||
props: squareYellowDefaults
|
||||
},
|
||||
SquareVideo: {
|
||||
props: squareVideoDefaults
|
||||
},
|
||||
FullscreenSplit: {
|
||||
props: fullscreenSplitDefaults
|
||||
},
|
||||
FullscreenVideo: {
|
||||
props: fullscreenVideoDefaults
|
||||
},
|
||||
FullscreenVideoTitle: {
|
||||
props: fullscreenVideoTitleDefaults
|
||||
},
|
||||
FullscreenVideoCenterCaption: {
|
||||
props: fullscreenVideoCenterCaptionDefaults
|
||||
},
|
||||
EquationFocus: {
|
||||
props: equationFocusDefaults,
|
||||
latexString: ""
|
||||
},
|
||||
QuoteImage: {
|
||||
props: quoteImageDefaults
|
||||
},
|
||||
ChartSingle: {
|
||||
props: chartSingleDefaults
|
||||
},
|
||||
ProcessFlow: {
|
||||
props: processFlowDefaults
|
||||
},
|
||||
DefinitionCard: {
|
||||
props: definitionCardDefaults
|
||||
},
|
||||
GlitchComponentFrame: {
|
||||
props: glitchComponentFrameDefaults
|
||||
}
|
||||
};
|
||||
export function getSlideTemplateDefinition(componentKey) {
|
||||
return slideTemplateDefinitions[componentKey];
|
||||
}
|
||||
export function getSlideTemplateAvailability(displayMode) {
|
||||
if (!displayMode) {
|
||||
return slideTemplateAvailabilityList;
|
||||
}
|
||||
return slideTemplateAvailabilityByDisplayMode[displayMode];
|
||||
}
|
||||
export function getSlideTemplateDraft(componentKey) {
|
||||
return slideTemplateDrafts[componentKey];
|
||||
}
|
||||
@@ -0,0 +1,633 @@
|
||||
import type {
|
||||
ChartSingleData,
|
||||
DefinitionCardData,
|
||||
EquationFocusData,
|
||||
FullscreenVideoData,
|
||||
FullscreenVideoCenterCaptionData,
|
||||
FullscreenVideoTitleData,
|
||||
FullscreenSplitData,
|
||||
GlitchComponentFrameData,
|
||||
ProcessFlowData,
|
||||
QuoteImageData,
|
||||
SlideTemplateKey,
|
||||
SlideTemplateProps,
|
||||
SquareVideoData,
|
||||
SquareYellowData
|
||||
} from "./templates";
|
||||
|
||||
export type SlideTemplateFieldType =
|
||||
| "text"
|
||||
| "textarea"
|
||||
| "lines"
|
||||
| "image"
|
||||
| "video"
|
||||
| "latex";
|
||||
|
||||
export interface SlideTemplateFieldDefinition {
|
||||
name: string;
|
||||
type: SlideTemplateFieldType;
|
||||
label: string;
|
||||
placeholder?: string;
|
||||
description?: string;
|
||||
required?: boolean;
|
||||
}
|
||||
|
||||
export interface SlideTemplateDefinition {
|
||||
componentKey: SlideTemplateKey;
|
||||
label: string;
|
||||
description: string;
|
||||
displayMode: "square" | "fullscreen";
|
||||
supportedDisplayModes?: Array<"square" | "fullscreen">;
|
||||
fields: SlideTemplateFieldDefinition[];
|
||||
}
|
||||
|
||||
export interface SlideTemplateAvailability {
|
||||
componentKey: SlideTemplateKey;
|
||||
label: string;
|
||||
description: string;
|
||||
displayMode: "square" | "fullscreen";
|
||||
fields: SlideTemplateFieldDefinition[];
|
||||
}
|
||||
|
||||
export interface SlideTemplateDraft {
|
||||
props: SlideTemplateProps;
|
||||
latexString?: string;
|
||||
}
|
||||
|
||||
const squareYellowDefaults: SquareYellowData = {
|
||||
header: "",
|
||||
imageSrc: "",
|
||||
imageAlt: ""
|
||||
};
|
||||
|
||||
const squareVideoDefaults: SquareVideoData = {
|
||||
header: "",
|
||||
videoSrc: "",
|
||||
posterSrc: ""
|
||||
};
|
||||
|
||||
const fullscreenSplitDefaults: FullscreenSplitData = {
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
body: "",
|
||||
imageSrc: "",
|
||||
imageAlt: "",
|
||||
imagePosition: "left"
|
||||
};
|
||||
|
||||
const fullscreenVideoDefaults: FullscreenVideoData = {
|
||||
header: "",
|
||||
videoSrc: "",
|
||||
posterSrc: "",
|
||||
caption: ""
|
||||
};
|
||||
|
||||
const fullscreenVideoTitleDefaults: FullscreenVideoTitleData = {
|
||||
title: "No need to be discrete",
|
||||
videoSrc: "",
|
||||
posterSrc: ""
|
||||
};
|
||||
|
||||
const fullscreenVideoCenterCaptionDefaults: FullscreenVideoCenterCaptionData = {
|
||||
caption: "",
|
||||
videoSrc: "",
|
||||
posterSrc: ""
|
||||
};
|
||||
|
||||
const equationFocusDefaults: EquationFocusData = {
|
||||
header: "",
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
annotation: ""
|
||||
};
|
||||
|
||||
const quoteImageDefaults: QuoteImageData = {
|
||||
eyebrow: "",
|
||||
quote: "",
|
||||
attribution: "",
|
||||
imageSrc: "",
|
||||
imageAlt: "",
|
||||
imagePosition: "left"
|
||||
};
|
||||
|
||||
const chartSingleDefaults: ChartSingleData = {
|
||||
header: "",
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
body: "",
|
||||
points: []
|
||||
};
|
||||
|
||||
const processFlowDefaults: ProcessFlowData = {
|
||||
eyebrow: "",
|
||||
title: "",
|
||||
steps: []
|
||||
};
|
||||
|
||||
const definitionCardDefaults: DefinitionCardData = {
|
||||
header: "",
|
||||
eyebrow: "",
|
||||
term: "",
|
||||
definition: "",
|
||||
example: ""
|
||||
};
|
||||
|
||||
const glitchComponentFrameDefaults: GlitchComponentFrameData = {
|
||||
header: "",
|
||||
componentId: "",
|
||||
componentUrl: "",
|
||||
caption: ""
|
||||
};
|
||||
|
||||
export const slideTemplateDefinitions: Record<
|
||||
SlideTemplateKey,
|
||||
SlideTemplateDefinition
|
||||
> = {
|
||||
SquareYellow: {
|
||||
componentKey: "SquareYellow",
|
||||
label: "Square image + header",
|
||||
description: "Square image with a short external header.",
|
||||
displayMode: "square",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short headline",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageSrc",
|
||||
type: "image",
|
||||
label: "Image",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageAlt",
|
||||
type: "text",
|
||||
label: "Alt text",
|
||||
placeholder: "Describe the image",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
SquareVideo: {
|
||||
componentKey: "SquareVideo",
|
||||
label: "Square video + header",
|
||||
description: "Square video inside a framed square slide with a short header.",
|
||||
displayMode: "square",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short headline",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenSplit: {
|
||||
componentKey: "FullscreenSplit",
|
||||
label: "Fullscreen split",
|
||||
description: "Two-panel fullscreen slide with image and text.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "Main title",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "body",
|
||||
type: "textarea",
|
||||
label: "Body",
|
||||
placeholder: "Short supporting text",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageSrc",
|
||||
type: "image",
|
||||
label: "Image",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageAlt",
|
||||
type: "text",
|
||||
label: "Alt text",
|
||||
placeholder: "Describe the image",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imagePosition",
|
||||
type: "text",
|
||||
label: "Image position",
|
||||
placeholder: "left or right"
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenVideo: {
|
||||
componentKey: "FullscreenVideo",
|
||||
label: "Fullscreen video",
|
||||
description: "Full-bleed video slide with optional overlay text.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
},
|
||||
{
|
||||
name: "caption",
|
||||
type: "textarea",
|
||||
label: "Caption",
|
||||
placeholder: "Short framing note"
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenVideoTitle: {
|
||||
componentKey: "FullscreenVideoTitle",
|
||||
label: "Fullscreen video + title",
|
||||
description: "Full-bleed video with one oversized overlaid title.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "No need to be discrete"
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
}
|
||||
]
|
||||
},
|
||||
FullscreenVideoCenterCaption: {
|
||||
componentKey: "FullscreenVideoCenterCaption",
|
||||
label: "Fullscreen video + centered caption",
|
||||
description: "Full-bleed video with one oversized centered caption.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "caption",
|
||||
type: "text",
|
||||
label: "Caption",
|
||||
placeholder: "Short centered statement"
|
||||
},
|
||||
{
|
||||
name: "videoSrc",
|
||||
type: "video",
|
||||
label: "Video",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "posterSrc",
|
||||
type: "image",
|
||||
label: "Poster image",
|
||||
placeholder: "https://..."
|
||||
}
|
||||
]
|
||||
},
|
||||
EquationFocus: {
|
||||
componentKey: "EquationFocus",
|
||||
label: "Equation focus",
|
||||
description: "One display equation with a short annotation.",
|
||||
displayMode: "fullscreen",
|
||||
supportedDisplayModes: ["square", "fullscreen"],
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "What does the equation show?",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "latexString",
|
||||
type: "latex",
|
||||
label: "LaTeX equation",
|
||||
placeholder: "\\bar{x} = \\frac{1}{N}\\sum_{i=0}^{N} x_i",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "annotation",
|
||||
type: "textarea",
|
||||
label: "Annotation",
|
||||
placeholder: "One short explanation"
|
||||
}
|
||||
]
|
||||
},
|
||||
QuoteImage: {
|
||||
componentKey: "QuoteImage",
|
||||
label: "Quote + image",
|
||||
description: "Strong quote paired with one image.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "eyebrow",
|
||||
type: "text",
|
||||
label: "Eyebrow",
|
||||
placeholder: "Optional eyebrow"
|
||||
},
|
||||
{
|
||||
name: "quote",
|
||||
type: "textarea",
|
||||
label: "Quote",
|
||||
placeholder: "Short quote",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "attribution",
|
||||
type: "text",
|
||||
label: "Attribution",
|
||||
placeholder: "Person or source"
|
||||
},
|
||||
{
|
||||
name: "imageSrc",
|
||||
type: "image",
|
||||
label: "Image",
|
||||
placeholder: "https://...",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imageAlt",
|
||||
type: "text",
|
||||
label: "Alt text",
|
||||
placeholder: "Describe the image",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "imagePosition",
|
||||
type: "text",
|
||||
label: "Image position",
|
||||
placeholder: "left or right"
|
||||
}
|
||||
]
|
||||
},
|
||||
ChartSingle: {
|
||||
componentKey: "ChartSingle",
|
||||
label: "Single chart",
|
||||
description: "One compact chart with a short framing line.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "Chart title",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "body",
|
||||
type: "textarea",
|
||||
label: "Body",
|
||||
placeholder: "Short interpretation"
|
||||
},
|
||||
{
|
||||
name: "points",
|
||||
type: "lines",
|
||||
label: "Data points",
|
||||
placeholder: "Label: value",
|
||||
description: "One point per line. Format each line as label: value."
|
||||
}
|
||||
]
|
||||
},
|
||||
ProcessFlow: {
|
||||
componentKey: "ProcessFlow",
|
||||
label: "Process flow",
|
||||
description: "Short pipeline with 3 to 5 steps.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "eyebrow",
|
||||
type: "text",
|
||||
label: "Eyebrow",
|
||||
placeholder: "Optional eyebrow"
|
||||
},
|
||||
{
|
||||
name: "title",
|
||||
type: "text",
|
||||
label: "Title",
|
||||
placeholder: "Process title",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "steps",
|
||||
type: "lines",
|
||||
label: "Steps",
|
||||
placeholder: "One step per line",
|
||||
required: true
|
||||
}
|
||||
]
|
||||
},
|
||||
DefinitionCard: {
|
||||
componentKey: "DefinitionCard",
|
||||
label: "Definition card",
|
||||
description: "Term, definition, and optional example.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "term",
|
||||
type: "text",
|
||||
label: "Term",
|
||||
placeholder: "Key term",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "definition",
|
||||
type: "textarea",
|
||||
label: "Definition",
|
||||
placeholder: "Short definition",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "example",
|
||||
type: "textarea",
|
||||
label: "Example",
|
||||
placeholder: "Optional example"
|
||||
}
|
||||
]
|
||||
},
|
||||
GlitchComponentFrame: {
|
||||
componentKey: "GlitchComponentFrame",
|
||||
label: "Interactive Glitch component",
|
||||
description: "Hosted Glitch component embedded inside the slide surface.",
|
||||
displayMode: "fullscreen",
|
||||
fields: [
|
||||
{
|
||||
name: "header",
|
||||
type: "text",
|
||||
label: "Header",
|
||||
placeholder: "Short header"
|
||||
},
|
||||
{
|
||||
name: "componentId",
|
||||
type: "text",
|
||||
label: "Component id",
|
||||
placeholder: "lightlane",
|
||||
required: true
|
||||
},
|
||||
{
|
||||
name: "componentUrl",
|
||||
type: "text",
|
||||
label: "Component URL",
|
||||
placeholder: "Optional hosted URL",
|
||||
description: "Optional URL for iframe-hosted components. Leave empty for known local component ids."
|
||||
},
|
||||
{
|
||||
name: "caption",
|
||||
type: "textarea",
|
||||
label: "Caption",
|
||||
placeholder: "Short framing note"
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
export const slideTemplateDefinitionList = Object.values(
|
||||
slideTemplateDefinitions
|
||||
);
|
||||
|
||||
export const slideTemplateAvailabilityList: SlideTemplateAvailability[] =
|
||||
slideTemplateDefinitionList.flatMap((definition) => {
|
||||
const supportedDisplayModes =
|
||||
definition.supportedDisplayModes ?? [definition.displayMode];
|
||||
|
||||
return supportedDisplayModes.map((displayMode) => ({
|
||||
componentKey: definition.componentKey,
|
||||
label: definition.label,
|
||||
description: definition.description,
|
||||
displayMode,
|
||||
fields: definition.fields
|
||||
}));
|
||||
});
|
||||
|
||||
export const slideTemplateAvailabilityByDisplayMode = {
|
||||
square: slideTemplateAvailabilityList.filter(
|
||||
(definition) => definition.displayMode === "square"
|
||||
),
|
||||
fullscreen: slideTemplateAvailabilityList.filter(
|
||||
(definition) => definition.displayMode === "fullscreen"
|
||||
)
|
||||
} satisfies Record<"square" | "fullscreen", SlideTemplateAvailability[]>;
|
||||
|
||||
export const slideTemplateDrafts: Record<SlideTemplateKey, SlideTemplateDraft> = {
|
||||
SquareYellow: {
|
||||
props: squareYellowDefaults
|
||||
},
|
||||
SquareVideo: {
|
||||
props: squareVideoDefaults
|
||||
},
|
||||
FullscreenSplit: {
|
||||
props: fullscreenSplitDefaults
|
||||
},
|
||||
FullscreenVideo: {
|
||||
props: fullscreenVideoDefaults
|
||||
},
|
||||
FullscreenVideoTitle: {
|
||||
props: fullscreenVideoTitleDefaults
|
||||
},
|
||||
FullscreenVideoCenterCaption: {
|
||||
props: fullscreenVideoCenterCaptionDefaults
|
||||
},
|
||||
EquationFocus: {
|
||||
props: equationFocusDefaults,
|
||||
latexString: ""
|
||||
},
|
||||
QuoteImage: {
|
||||
props: quoteImageDefaults
|
||||
},
|
||||
ChartSingle: {
|
||||
props: chartSingleDefaults
|
||||
},
|
||||
ProcessFlow: {
|
||||
props: processFlowDefaults
|
||||
},
|
||||
DefinitionCard: {
|
||||
props: definitionCardDefaults
|
||||
},
|
||||
GlitchComponentFrame: {
|
||||
props: glitchComponentFrameDefaults
|
||||
}
|
||||
};
|
||||
|
||||
export function getSlideTemplateDefinition(componentKey: SlideTemplateKey) {
|
||||
return slideTemplateDefinitions[componentKey];
|
||||
}
|
||||
|
||||
export function getSlideTemplateAvailability(displayMode?: "square" | "fullscreen") {
|
||||
if (!displayMode) {
|
||||
return slideTemplateAvailabilityList;
|
||||
}
|
||||
|
||||
return slideTemplateAvailabilityByDisplayMode[displayMode];
|
||||
}
|
||||
|
||||
export function getSlideTemplateDraft(componentKey: SlideTemplateKey) {
|
||||
return slideTemplateDrafts[componentKey];
|
||||
}
|
||||
+144
@@ -0,0 +1,144 @@
|
||||
export declare const slideTemplateKeys: readonly ["SquareYellow", "SquareVideo", "FullscreenSplit", "FullscreenVideo", "FullscreenVideoTitle", "FullscreenVideoCenterCaption", "EquationFocus", "QuoteImage", "ChartSingle", "ProcessFlow", "DefinitionCard", "GlitchComponentFrame"];
|
||||
export type SlideTemplateKey = (typeof slideTemplateKeys)[number];
|
||||
export type SlideTemplateVersion = 1;
|
||||
export interface SquareYellowData {
|
||||
header: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
}
|
||||
export interface SquareVideoData {
|
||||
header: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
}
|
||||
export interface FullscreenSplitData {
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
body: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
imagePosition?: "left" | "right";
|
||||
}
|
||||
export interface FullscreenVideoData {
|
||||
header?: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
caption?: string;
|
||||
}
|
||||
export interface FullscreenVideoTitleData {
|
||||
title?: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
}
|
||||
export interface FullscreenVideoCenterCaptionData {
|
||||
caption?: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
}
|
||||
export interface EquationFocusData {
|
||||
header?: string;
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
annotation?: string;
|
||||
}
|
||||
export interface QuoteImageData {
|
||||
eyebrow?: string;
|
||||
quote: string;
|
||||
attribution?: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
imagePosition?: "left" | "right";
|
||||
}
|
||||
export interface ChartSinglePoint {
|
||||
label: string;
|
||||
value: number;
|
||||
color?: string;
|
||||
}
|
||||
export interface ChartSingleData {
|
||||
header?: string;
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
body?: string;
|
||||
points: ChartSinglePoint[];
|
||||
}
|
||||
export interface ProcessFlowData {
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
steps: string[];
|
||||
}
|
||||
export interface DefinitionCardData {
|
||||
header?: string;
|
||||
eyebrow?: string;
|
||||
term: string;
|
||||
definition: string;
|
||||
example?: string;
|
||||
}
|
||||
export interface GlitchComponentFrameData {
|
||||
header?: string;
|
||||
componentId: string;
|
||||
componentUrl?: string;
|
||||
caption?: string;
|
||||
}
|
||||
export interface SquareYellowContract {
|
||||
componentKey: "SquareYellow";
|
||||
version: 1;
|
||||
props: SquareYellowData;
|
||||
}
|
||||
export interface SquareVideoContract {
|
||||
componentKey: "SquareVideo";
|
||||
version: 1;
|
||||
props: SquareVideoData;
|
||||
}
|
||||
export interface FullscreenSplitContract {
|
||||
componentKey: "FullscreenSplit";
|
||||
version: 1;
|
||||
props: FullscreenSplitData;
|
||||
}
|
||||
export interface FullscreenVideoContract {
|
||||
componentKey: "FullscreenVideo";
|
||||
version: 1;
|
||||
props: FullscreenVideoData;
|
||||
}
|
||||
export interface FullscreenVideoTitleContract {
|
||||
componentKey: "FullscreenVideoTitle";
|
||||
version: 1;
|
||||
props: FullscreenVideoTitleData;
|
||||
}
|
||||
export interface FullscreenVideoCenterCaptionContract {
|
||||
componentKey: "FullscreenVideoCenterCaption";
|
||||
version: 1;
|
||||
props: FullscreenVideoCenterCaptionData;
|
||||
}
|
||||
export interface EquationFocusContract {
|
||||
componentKey: "EquationFocus";
|
||||
version: 1;
|
||||
props: EquationFocusData;
|
||||
latexString: string;
|
||||
}
|
||||
export interface QuoteImageContract {
|
||||
componentKey: "QuoteImage";
|
||||
version: 1;
|
||||
props: QuoteImageData;
|
||||
}
|
||||
export interface ChartSingleContract {
|
||||
componentKey: "ChartSingle";
|
||||
version: 1;
|
||||
props: ChartSingleData;
|
||||
}
|
||||
export interface ProcessFlowContract {
|
||||
componentKey: "ProcessFlow";
|
||||
version: 1;
|
||||
props: ProcessFlowData;
|
||||
}
|
||||
export interface DefinitionCardContract {
|
||||
componentKey: "DefinitionCard";
|
||||
version: 1;
|
||||
props: DefinitionCardData;
|
||||
}
|
||||
export interface GlitchComponentFrameContract {
|
||||
componentKey: "GlitchComponentFrame";
|
||||
version: 1;
|
||||
props: GlitchComponentFrameData;
|
||||
}
|
||||
export type SupportedSlideContract = SquareYellowContract | SquareVideoContract | FullscreenSplitContract | FullscreenVideoContract | FullscreenVideoTitleContract | FullscreenVideoCenterCaptionContract | EquationFocusContract | QuoteImageContract | ChartSingleContract | ProcessFlowContract | DefinitionCardContract | GlitchComponentFrameContract;
|
||||
export type SlideTemplateProps = SupportedSlideContract["props"];
|
||||
@@ -0,0 +1,14 @@
|
||||
export var slideTemplateKeys = [
|
||||
"SquareYellow",
|
||||
"SquareVideo",
|
||||
"FullscreenSplit",
|
||||
"FullscreenVideo",
|
||||
"FullscreenVideoTitle",
|
||||
"FullscreenVideoCenterCaption",
|
||||
"EquationFocus",
|
||||
"QuoteImage",
|
||||
"ChartSingle",
|
||||
"ProcessFlow",
|
||||
"DefinitionCard",
|
||||
"GlitchComponentFrame"
|
||||
];
|
||||
@@ -0,0 +1,197 @@
|
||||
export const slideTemplateKeys = [
|
||||
"SquareYellow",
|
||||
"SquareVideo",
|
||||
"FullscreenSplit",
|
||||
"FullscreenVideo",
|
||||
"FullscreenVideoTitle",
|
||||
"FullscreenVideoCenterCaption",
|
||||
"EquationFocus",
|
||||
"QuoteImage",
|
||||
"ChartSingle",
|
||||
"ProcessFlow",
|
||||
"DefinitionCard",
|
||||
"GlitchComponentFrame"
|
||||
] as const;
|
||||
|
||||
export type SlideTemplateKey = (typeof slideTemplateKeys)[number];
|
||||
export type SlideTemplateVersion = 1;
|
||||
|
||||
export interface SquareYellowData {
|
||||
header: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
}
|
||||
|
||||
export interface SquareVideoData {
|
||||
header: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
}
|
||||
|
||||
export interface FullscreenSplitData {
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
body: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
imagePosition?: "left" | "right";
|
||||
}
|
||||
|
||||
export interface FullscreenVideoData {
|
||||
header?: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
caption?: string;
|
||||
}
|
||||
|
||||
export interface FullscreenVideoTitleData {
|
||||
title?: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
}
|
||||
|
||||
export interface FullscreenVideoCenterCaptionData {
|
||||
caption?: string;
|
||||
videoSrc: string;
|
||||
posterSrc?: string;
|
||||
}
|
||||
|
||||
export interface EquationFocusData {
|
||||
header?: string;
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
annotation?: string;
|
||||
}
|
||||
|
||||
export interface QuoteImageData {
|
||||
eyebrow?: string;
|
||||
quote: string;
|
||||
attribution?: string;
|
||||
imageSrc: string;
|
||||
imageAlt: string;
|
||||
imagePosition?: "left" | "right";
|
||||
}
|
||||
|
||||
export interface ChartSinglePoint {
|
||||
label: string;
|
||||
value: number;
|
||||
color?: string;
|
||||
}
|
||||
|
||||
export interface ChartSingleData {
|
||||
header?: string;
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
body?: string;
|
||||
points: ChartSinglePoint[];
|
||||
}
|
||||
|
||||
export interface ProcessFlowData {
|
||||
eyebrow?: string;
|
||||
title: string;
|
||||
steps: string[];
|
||||
}
|
||||
|
||||
export interface DefinitionCardData {
|
||||
header?: string;
|
||||
eyebrow?: string;
|
||||
term: string;
|
||||
definition: string;
|
||||
example?: string;
|
||||
}
|
||||
|
||||
export interface GlitchComponentFrameData {
|
||||
header?: string;
|
||||
componentId: string;
|
||||
componentUrl?: string;
|
||||
caption?: string;
|
||||
}
|
||||
|
||||
export interface SquareYellowContract {
|
||||
componentKey: "SquareYellow";
|
||||
version: 1;
|
||||
props: SquareYellowData;
|
||||
}
|
||||
|
||||
export interface SquareVideoContract {
|
||||
componentKey: "SquareVideo";
|
||||
version: 1;
|
||||
props: SquareVideoData;
|
||||
}
|
||||
|
||||
export interface FullscreenSplitContract {
|
||||
componentKey: "FullscreenSplit";
|
||||
version: 1;
|
||||
props: FullscreenSplitData;
|
||||
}
|
||||
|
||||
export interface FullscreenVideoContract {
|
||||
componentKey: "FullscreenVideo";
|
||||
version: 1;
|
||||
props: FullscreenVideoData;
|
||||
}
|
||||
|
||||
export interface FullscreenVideoTitleContract {
|
||||
componentKey: "FullscreenVideoTitle";
|
||||
version: 1;
|
||||
props: FullscreenVideoTitleData;
|
||||
}
|
||||
|
||||
export interface FullscreenVideoCenterCaptionContract {
|
||||
componentKey: "FullscreenVideoCenterCaption";
|
||||
version: 1;
|
||||
props: FullscreenVideoCenterCaptionData;
|
||||
}
|
||||
|
||||
export interface EquationFocusContract {
|
||||
componentKey: "EquationFocus";
|
||||
version: 1;
|
||||
props: EquationFocusData;
|
||||
latexString: string;
|
||||
}
|
||||
|
||||
export interface QuoteImageContract {
|
||||
componentKey: "QuoteImage";
|
||||
version: 1;
|
||||
props: QuoteImageData;
|
||||
}
|
||||
|
||||
export interface ChartSingleContract {
|
||||
componentKey: "ChartSingle";
|
||||
version: 1;
|
||||
props: ChartSingleData;
|
||||
}
|
||||
|
||||
export interface ProcessFlowContract {
|
||||
componentKey: "ProcessFlow";
|
||||
version: 1;
|
||||
props: ProcessFlowData;
|
||||
}
|
||||
|
||||
export interface DefinitionCardContract {
|
||||
componentKey: "DefinitionCard";
|
||||
version: 1;
|
||||
props: DefinitionCardData;
|
||||
}
|
||||
|
||||
export interface GlitchComponentFrameContract {
|
||||
componentKey: "GlitchComponentFrame";
|
||||
version: 1;
|
||||
props: GlitchComponentFrameData;
|
||||
}
|
||||
|
||||
export type SupportedSlideContract =
|
||||
| SquareYellowContract
|
||||
| SquareVideoContract
|
||||
| FullscreenSplitContract
|
||||
| FullscreenVideoContract
|
||||
| FullscreenVideoTitleContract
|
||||
| FullscreenVideoCenterCaptionContract
|
||||
| EquationFocusContract
|
||||
| QuoteImageContract
|
||||
| ChartSingleContract
|
||||
| ProcessFlowContract
|
||||
| DefinitionCardContract
|
||||
| GlitchComponentFrameContract;
|
||||
|
||||
export type SlideTemplateProps = SupportedSlideContract["props"];
|
||||
Reference in New Issue
Block a user