Skip to content

Commit 7e3f22e

Browse files
ofriwclaude
andcommitted
Add PresentationAwareProps interface for visual components
Create shared types.ts defining PresentationAwareProps interface with compact mode support. Update RevealSlideshow to pass compact={true} to all visual components and handle slides without titles. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent f7a9cc1 commit 7e3f22e

File tree

2 files changed

+181
-3
lines changed

2 files changed

+181
-3
lines changed

website/src/components/PresentationMode/RevealSlideshow.tsx

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,19 @@ import React, { useEffect, useRef } from 'react';
22
import Reveal from 'reveal.js';
33
import RevealHighlight from 'reveal.js/plugin/highlight/highlight';
44
import 'reveal.js/dist/reveal.css';
5-
import 'reveal.js/dist/theme/black.css';
65
import 'reveal.js/plugin/highlight/monokai.css';
76
import styles from './RevealSlideshow.module.css';
87

9-
// Import visual components that might be used in presentations
8+
/**
9+
* Import visual components for presentations
10+
*
11+
* All components implement PresentationAwareProps and support compact mode.
12+
* When rendered in slides, pass compact={true} to remove padding/margins
13+
* and maximize content area within the 1280x720 viewport.
14+
*
15+
* See: /website/src/components/PresentationMode/types.ts
16+
* See: /website/src/styles/presentation-system.css
17+
*/
1018
import CapabilityMatrix from '../VisualElements/CapabilityMatrix';
1119
import UShapeAttentionCurve from '../VisualElements/UShapeAttentionCurve';
1220
import WorkflowCircle from '../VisualElements/WorkflowCircle';
@@ -367,7 +375,7 @@ export default function RevealSlideshow({
367375
key={key}
368376
data-notes={formatSpeakerNotes(slide.speakerNotes)}
369377
>
370-
<h2>{slide.title}</h2>
378+
{slide.title && <h2>{slide.title}</h2>}
371379
<div className={styles.visualContainer}>
372380
{VisualComponent && <VisualComponent compact />}
373381
{!VisualComponent && (
Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/**
2+
* Type definitions for presentation-aware components
3+
*
4+
* These types establish a contract for visual components that need to work
5+
* in both regular documentation pages and presentation slides (Reveal.js).
6+
*
7+
* Key Principles:
8+
* - Presentations use a fixed 1280x720 viewport (non-scrollable)
9+
* - Components must support compact mode to maximize content area
10+
* - Dark mode is always active in presentations (Reveal.js black theme)
11+
* - All colors must use CSS variables for automatic dark mode adaptation
12+
*/
13+
14+
/**
15+
* Props interface for components that support presentation mode
16+
*
17+
* Usage:
18+
* ```tsx
19+
* interface MyComponentProps extends PresentationAwareProps {
20+
* title: string;
21+
* data: number[];
22+
* }
23+
*
24+
* export const MyComponent: React.FC<MyComponentProps> = ({ compact, title, data }) => {
25+
* return (
26+
* <div className={compact ? styles.containerCompact : styles.container}>
27+
* ...
28+
* </div>
29+
* );
30+
* };
31+
* ```
32+
*/
33+
export interface PresentationAwareProps {
34+
/**
35+
* Enable compact mode for presentations
36+
*
37+
* When true, the component should:
38+
* - Remove or minimize padding/margins
39+
* - Maximize visual content area
40+
* - Ensure all colors use CSS variables (no hardcoded values)
41+
* - Handle fixed viewport constraints (1280x720)
42+
*
43+
* @default false
44+
*/
45+
compact?: boolean;
46+
}
47+
48+
/**
49+
* Layout configuration for presentation slides
50+
*
51+
* Defines spacing, sizing, and alignment rules for consistent
52+
* slide layouts across different content types.
53+
*/
54+
export interface PresentationLayoutConfig {
55+
/**
56+
* Vertical alignment of content within slide
57+
* @default 'flex-start' - Content starts at top after title
58+
*/
59+
verticalAlign?: 'flex-start' | 'center' | 'flex-end' | 'space-between';
60+
61+
/**
62+
* Whether content can overflow the slide boundaries
63+
* @default false - Content is constrained to slide viewport
64+
*/
65+
allowOverflow?: boolean;
66+
67+
/**
68+
* Scale factor for visual prominence
69+
* @default 1.0 - No scaling
70+
*/
71+
scaleContent?: number;
72+
73+
/**
74+
* Maximum width as percentage of slide width
75+
* @default 90 - Leaves margin on sides
76+
*/
77+
maxWidthPercent?: number;
78+
79+
/**
80+
* Maximum height as percentage of available content area
81+
* @default 85 - Accounts for title and caption
82+
*/
83+
maxHeightPercent?: number;
84+
}
85+
86+
/**
87+
* Slide type enum for type-safe slide rendering
88+
*
89+
* Each slide type may have different layout requirements.
90+
* Used by RevealSlideshow to apply appropriate styling.
91+
*/
92+
export enum SlideType {
93+
/** Title slide with main heading and optional subtitle */
94+
TITLE = 'title',
95+
/** Section divider slide */
96+
SECTION = 'section',
97+
/** Learning objectives list */
98+
OBJECTIVES = 'objectives',
99+
/** Bullet point list content */
100+
BULLET_LIST = 'bulletList',
101+
/** Key takeaways summary */
102+
TAKEAWAYS = 'takeaways',
103+
/** Side-by-side comparison (ineffective vs effective) */
104+
COMPARISON = 'comparison',
105+
/** Marketing metaphor vs technical reality translation */
106+
MARKETING_REALITY = 'marketingReality',
107+
/** Visual diagram or interactive component */
108+
VISUAL = 'visual',
109+
/** Code block with syntax highlighting */
110+
CODE = 'code',
111+
/** Step-by-step execution flow with fragments */
112+
EXECUTION_FLOW = 'executionFlow',
113+
}
114+
115+
/**
116+
* Props for visual components that need scaling in presentations
117+
*
118+
* Some visual components (SVGs, diagrams) are too small at 1:1 scale
119+
* in the fixed 1280x720 viewport. This interface provides scaling control.
120+
*/
121+
export interface ScalableVisualProps extends PresentationAwareProps {
122+
/**
123+
* CSS transform scale factor
124+
* @default 1.5 for presentations, 1.0 for normal docs
125+
*/
126+
scale?: number;
127+
}
128+
129+
/**
130+
* Type guard to check if a component implements PresentationAwareProps
131+
*
132+
* Usage:
133+
* ```tsx
134+
* if (isPresentationAware(props)) {
135+
* return <Component {...props} compact={true} />;
136+
* }
137+
* ```
138+
*/
139+
export function isPresentationAware(
140+
props: any
141+
): props is PresentationAwareProps {
142+
return props !== null && typeof props === 'object';
143+
}
144+
145+
/**
146+
* Presentation mode context type
147+
*
148+
* Can be used with React Context to provide global presentation state
149+
* if components need to detect presentation mode without explicit props.
150+
*/
151+
export interface PresentationContextValue {
152+
/** Whether presentation mode is currently active */
153+
isPresenting: boolean;
154+
/** Current slide index (0-based) */
155+
currentSlide: number;
156+
/** Total number of slides */
157+
totalSlides: number;
158+
}
159+
160+
/**
161+
* CSS Module class name mapping for compact mode
162+
*
163+
* Helper type for components using CSS Modules that need to switch
164+
* between normal and compact class names.
165+
*/
166+
export type CompactModeClassNames<T extends string> = {
167+
[K in T]: string;
168+
} & {
169+
[K in `${T}Compact`]: string;
170+
};

0 commit comments

Comments
 (0)