How to Implement Full-Screen Steps in the Presentation Skill
To implement full-screen steps in the presentation skill, extend the Step type with an optional fullScreen boolean property, update the useStepper hook to compute an isFullScreen flag from the current step, and conditionally apply a stage-fullscreen CSS class in the Stage component that sets position: fixed with viewport dimensions.
The presentation skill in ConardLi/garden-skills renders sequential content through a declarative architecture where the useStepper hook manages navigation state and the Stage component handles layout. By implementing full-screen steps in the presentation skill, you can create immersive slides that fill the entire browser viewport while maintaining the skill’s reactive, testable structure.
Extend the Step Type Definition
The step schema lives in src/registry/types.ts. You must add an optional fullScreen property to the Step type so that individual steps can declare whether they should render in full-screen mode.
// src/registry/types.ts
export type Step = {
id: string;
component: React.ReactNode;
/** When true the Stage expands to fill the whole viewport. */
fullScreen?: boolean;
};
This change keeps step definitions declarative; chapter files remain the single source of truth for content and display behavior.
Update the useStepper Hook
The useStepper hook in src/hooks/useStepper.ts tracks the current step index and exposes navigation methods. You need to derive an isFullScreen boolean from the current step’s properties and include it in the hook’s return value.
// src/hooks/useStepper.ts
import { useState, useCallback } from "react";
import { Step } from "../registry/types";
export const useStepper = (steps: Step[]) => {
const [current, setCurrent] = useState(0);
const currentStep = steps[current];
const isFullScreen = !!currentStep.fullScreen;
const next = useCallback(() => {
setCurrent((i) => Math.min(i + 1, steps.length - 1));
}, [steps]);
return { currentStep, isFullScreen, next };
};
By computing isFullScreen inside the hook, you centralize state logic and prevent the Stage component from directly inspecting step metadata.
Configure the Stage Component for Full-Screen Rendering
The Stage component in src/components/Stage.tsx receives the current step from useStepper and renders it. Modify the component to apply the stage-fullscreen CSS class conditionally based on the isFullScreen flag.
// src/components/Stage.tsx
import { useStepper } from "../hooks/useStepper";
import { steps } from "../chapters/01-example/Example";
export const Stage = () => {
const { currentStep, isFullScreen } = useStepper(steps);
return (
<div className={isFullScreen ? "stage-fullscreen" : "stage"}>
{currentStep.component}
</div>
);
};
This approach ensures that layout concerns stay separated from navigation logic; the Stage only reacts to the boolean flag without managing state.
Add Full-Screen CSS Styling
Create the .stage-fullscreen class in src/styles/base.css to force the container into viewport-relative positioning. Use inset: 0 or explicit top/left/width/height declarations, and set a high z-index to overlay other elements.
/* src/styles/base.css */
.stage-fullscreen {
position: fixed;
inset: 0;
width: 100vw;
height: 100vh;
z-index: 9999;
background: #000; /* optional background */
}
/* Hide UI when full-screen is active */
.stage-fullscreen + .progress-bar,
.stage-fullscreen + .navigation {
display: none;
}
These styles remove scrollbars, eliminate surrounding chrome, and ensure the step content fills the visible area on all screen sizes.
Create Full-Screen Steps in Chapter Files
With the infrastructure in place, you can mark any step as full-screen by setting the fullScreen property to true in your chapter definitions. For example, in src/chapters/01-example/Example.tsx:
// src/chapters/01-example/Example.tsx
import { Step } from "../registry/types";
const Intro = () => <div>Full Screen Intro</div>;
const Content = () => <div>Standard Content</div>;
export const steps: Step[] = [
{
id: "intro",
component: <Intro />,
fullScreen: true, // ← enable full-screen for this step
},
{
id: "content",
component: <Content />,
},
];
No additional JavaScript is required to manipulate the DOM directly, preserving the skill’s reactivity and making the feature fully testable.
Summary
- Extend the
Steptype insrc/registry/types.tswith an optionalfullScreenboolean to declaratively mark immersive slides. - Update
useStepperinsrc/hooks/useStepper.tsto exposeisFullScreenderived from the current step’s properties. - Modify the
Stagecomponent insrc/components/Stage.tsxto toggle thestage-fullscreenCSS class based on the hook’s output. - Define viewport styles in
src/styles/base.cssusingposition: fixed,width: 100vw, andheight: 100vhwith a highz-index. - Annotate steps in chapter files (e.g.,
src/chapters/01-example/Example.tsx) withfullScreen: trueto activate the mode.
Frequently Asked Questions
How do I exit full-screen mode during a presentation?
The presentation skill automatically exits full-screen mode when you navigate to a step that does not have fullScreen: true defined in its configuration. Since useStepper recomputes isFullScreen on every step change, the Stage component removes the stage-fullscreen class as soon as the user advances or returns to a standard slide.
Can I toggle full-screen mode with a keyboard shortcut?
Yes. You can integrate the useHotKeys hook (referenced in the ConardLi/garden-skills source) to listen for a key such as F and call a toggle method exposed by useStepper. This method would temporarily override the current step’s fullScreen flag without modifying the chapter definition, allowing dynamic control during live presentations.
Does full-screen mode hide the progress bar and navigation arrows?
Yes. The CSS rules in src/styles/base.css use adjacent sibling selectors (.stage-fullscreen + .progress-bar) to set display: none on UI elements when the full-screen class is active. This ensures that progress indicators and navigation controls do not overlay the immersive content.
What if I need different background colors for different full-screen steps?
Since the Stage component receives the currentStep object from useStepper, you can extend the Step type with an additional optional property such as backgroundColor?: string. The Stage can then apply this value as an inline style or CSS variable alongside the stage-fullscreen class, allowing per-step theming while maintaining the full-screen viewport coverage.
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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →