Skip to content

Commit 695cda2

Browse files
committed
example switcher
1 parent eb23dd6 commit 695cda2

File tree

1 file changed

+54
-22
lines changed

1 file changed

+54
-22
lines changed

src/components/AnimatedTerminal.tsx

Lines changed: 54 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useEffect, useState, useMemo, useRef } from 'react';
22

33
type TerminalExample = {
4+
name: string;
45
lines: string[];
56
delay: number; // Delay before starting next example
67
};
@@ -11,6 +12,7 @@ interface AnimatedTerminalProps {
1112

1213
const getExamples = (version: string = '9.8.0'): TerminalExample[] => [
1314
{
15+
name: 'NumPy Basics',
1416
lines: [
1517
'$ ipython',
1618
`IPython ${version} -- An enhanced Interactive Python`,
@@ -26,6 +28,7 @@ const getExamples = (version: string = '9.8.0'): TerminalExample[] => [
2628
delay: 4000,
2729
},
2830
{
31+
name: 'Performance & Plotting',
2932
lines: [
3033
'$ ipython',
3134
`IPython ${version} -- An enhanced Interactive Python`,
@@ -40,6 +43,7 @@ const getExamples = (version: string = '9.8.0'): TerminalExample[] => [
4043
delay: 4000,
4144
},
4245
{
46+
name: 'Functions',
4347
lines: [
4448
'$ ipython',
4549
`IPython ${version} -- An enhanced Interactive Python`,
@@ -97,6 +101,15 @@ export default function AnimatedTerminal({ version }: AnimatedTerminalProps) {
97101
};
98102
}, []);
99103

104+
// Function to switch to a specific example
105+
const switchToExample = (index: number) => {
106+
if (index >= 0 && index < examples.length) {
107+
setCurrentExample(index);
108+
setCurrentLineIndex(0);
109+
setDisplayedLines([]);
110+
}
111+
};
112+
100113
useEffect(() => {
101114
// Pause animation when page is not visible
102115
if (!isVisible) {
@@ -175,30 +188,49 @@ export default function AnimatedTerminal({ version }: AnimatedTerminalProps) {
175188
const minHeight = `${maxLines * lineHeight + padding + controlsHeight}rem`;
176189

177190
return (
178-
<div className="bg-gray-50 dark:bg-gray-900 rounded-lg overflow-hidden font-mono text-sm" style={{ minHeight }}>
179-
{/* macOS Window Controls */}
180-
<div className="bg-gray-200 dark:bg-gray-800 border-b border-gray-300 dark:border-gray-700 px-4 py-2 flex items-center gap-2">
181-
<div className="w-3 h-3 rounded-full bg-red-500"></div>
182-
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
183-
<div className="w-3 h-3 rounded-full bg-green-500"></div>
191+
<div>
192+
<div className="bg-gray-50 dark:bg-gray-900 rounded-lg overflow-hidden font-mono text-sm" style={{ minHeight }}>
193+
{/* macOS Window Controls */}
194+
<div className="bg-gray-200 dark:bg-gray-800 border-b border-gray-300 dark:border-gray-700 px-4 py-2 flex items-center gap-2">
195+
<div className="w-3 h-3 rounded-full bg-red-500"></div>
196+
<div className="w-3 h-3 rounded-full bg-yellow-500"></div>
197+
<div className="w-3 h-3 rounded-full bg-green-500"></div>
198+
</div>
199+
200+
{/* Terminal Content */}
201+
<div className="p-6 whitespace-pre">
202+
{displayedLines.map((line, index) => {
203+
const { prefix, content, prefixColor } = getLinePrefix(line);
204+
const lineColor = getLineColor(line);
205+
206+
return (
207+
<div key={index} className={`${lineColor} whitespace-pre`}>
208+
{prefix && <span className={prefixColor}>{prefix}</span>}
209+
{content}
210+
</div>
211+
);
212+
})}
213+
{displayedLines.length === 0 && (
214+
<div className="text-theme-secondary whitespace-pre">$ ipython</div>
215+
)}
216+
</div>
184217
</div>
185218

186-
{/* Terminal Content */}
187-
<div className="p-6">
188-
{displayedLines.map((line, index) => {
189-
const { prefix, content, prefixColor } = getLinePrefix(line);
190-
const lineColor = getLineColor(line);
191-
192-
return (
193-
<div key={index} className={lineColor}>
194-
{prefix && <span className={prefixColor}>{prefix}</span>}
195-
{content}
196-
</div>
197-
);
198-
})}
199-
{displayedLines.length === 0 && (
200-
<div className="text-theme-secondary">$ ipython</div>
201-
)}
219+
{/* Indicator Dots */}
220+
<div className="flex justify-center items-center gap-2 mt-4">
221+
{examples.map((example, index) => (
222+
<button
223+
key={index}
224+
onClick={() => switchToExample(index)}
225+
className={`transition-all duration-200 focus:outline-none focus:ring-2 focus:ring-theme-primary focus:ring-offset-2 rounded-full ${
226+
index === currentExample
227+
? 'w-3 h-3 bg-theme-accent border-2 border-theme-primary scale-125'
228+
: 'w-2 h-2 bg-gray-400 dark:bg-gray-600 hover:bg-gray-500 dark:hover:bg-gray-500'
229+
}`}
230+
aria-label={`Go to ${example.name}`}
231+
title={example.name}
232+
/>
233+
))}
202234
</div>
203235
</div>
204236
);

0 commit comments

Comments
 (0)