@@ -5,6 +5,15 @@ import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
55
66export type EnumerationType = 'eager' | 'lazy' ;
77
8+ export type ThemeColors = {
9+ background ?: string ;
10+ text ?: string ;
11+ primary ?: string ;
12+ secondary ?: string ;
13+ accent ?: string ;
14+ gridLines ?: string ;
15+ } ;
16+
817interface Dot {
918 pos : number ;
1019 column : number ;
@@ -42,15 +51,45 @@ interface Narration {
4251}
4352
4453interface EnumerationDemoProps extends React . HTMLAttributes < HTMLDivElement > {
45- demoType ?: EnumerationType | undefined | null ;
54+ demoType ?: EnumerationType ;
55+ isDarkMode ?: boolean ;
56+ customColors ?: ThemeColors ;
4657}
4758
48- const EnumerationDemo : React . FC < EnumerationDemoProps > = ( { demoType } ) => {
59+ const EnumerationDemo : React . FC < EnumerationDemoProps > = ( {
60+ demoType,
61+ isDarkMode = false ,
62+ customColors = { } ,
63+ className,
64+ ...props
65+ } ) => {
4966 const [ progress , setProgress ] = useState ( 0 ) ;
5067 const [ playing , setPlaying ] = useState ( false ) ;
5168 const [ type , setType ] = useState < EnumerationType > ( demoType || 'eager' ) ;
5269 const [ explosions , setExplosions ] = useState < ExplosionParticle [ ] > ( [ ] ) ;
5370 const [ positions , setPositions ] = useState < Position [ ] > ( [ ] ) ;
71+
72+ // Theme configuration
73+ const theme = {
74+ background :
75+ customColors . background || ( isDarkMode ? 'rgb(24, 24, 27)' : 'white' ) ,
76+ text :
77+ customColors . text ||
78+ ( isDarkMode ? 'rgb(250, 250, 250)' : 'rgb(24, 24, 27)' ) ,
79+ primary :
80+ customColors . primary ||
81+ ( isDarkMode ? 'rgb(59, 130, 246)' : 'rgb(59, 130, 246)' ) ,
82+ secondary :
83+ customColors . secondary ||
84+ ( isDarkMode ? 'rgb(244, 114, 182)' : 'rgb(249, 115, 22)' ) ,
85+ accent :
86+ customColors . accent ||
87+ ( isDarkMode ? 'rgb(168, 85, 247)' : 'rgb(168, 85, 247)' ) ,
88+ gridLines :
89+ customColors . gridLines ||
90+ ( isDarkMode ? 'rgb(63, 63, 70)' : 'rgb(229, 231, 235)' ) ,
91+ } ;
92+
5493 const processedStepsRef = useRef < Set < string > > ( new Set ( ) ) ;
5594 const animationRef = useRef < number | null > ( null ) ;
5695
@@ -448,21 +487,41 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
448487 const narration = getNarration ( ) ;
449488
450489 return (
451- < Card className = 'w-full max-w-2xl' >
490+ < Card
491+ className = { `w-full max-w-2xl ${ isDarkMode ? 'dark' : '' } ${
492+ className || ''
493+ } `}
494+ style = { {
495+ backgroundColor : theme . background ,
496+ color : theme . text ,
497+ } }
498+ { ...props }
499+ >
452500 < CardHeader >
453501 < CardTitle className = 'flex items-baseline gap-2' >
454- < span > { type === 'eager' ? 'Eager' : 'Lazy' } Enumeration</ span >
455- < span className = 'text-sm text-gray-500 font-normal' >
502+ < span style = { { color : theme . text } } >
503+ { type === 'eager' ? 'Eager' : 'Lazy' } Enumeration
504+ </ span >
505+ < span
506+ className = 'text-sm font-normal'
507+ style = { { color : `${ theme . text } 88` } }
508+ >
456509 { type === 'eager'
457510 ? 'Processes all items through each step before moving to next step'
458- : 'Processes each needed item through all steps before moving to next item' }
511+ : 'Processes each needed item through steps before moving to next item' }
459512 </ span >
460513 </ CardTitle >
461514 </ CardHeader >
462515 < CardContent >
463- < div className = 'h-12 mb-4 text-lg font-medium text-center' >
516+ < div
517+ className = 'h-12 mb-4 text-lg font-medium text-center'
518+ style = { { color : theme . text } }
519+ >
464520 { narration . title }
465- < div className = 'text-sm text-gray-500 font-normal' >
521+ < div
522+ className = 'text-sm font-normal'
523+ style = { { color : `${ theme . text } 88` } }
524+ >
466525 { narration . description }
467526 </ div >
468527 </ div >
@@ -472,6 +531,7 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
472531 key = { i }
473532 x = { 50 + i * 100 }
474533 y = { 30 }
534+ style = { { fill : theme . text } }
475535 className = 'text-sm font-medium'
476536 textAnchor = 'middle'
477537 >
@@ -488,7 +548,7 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
488548 y1 = { 40 }
489549 x2 = { 100 + i * 100 }
490550 y2 = { 360 }
491- stroke = '#ddd'
551+ stroke = { theme . gridLines }
492552 strokeDasharray = '4,4'
493553 />
494554 ) ) }
@@ -501,16 +561,14 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
501561 cx = { 50 + dot . column * 100 }
502562 cy = { 80 + i * 40 }
503563 r = { 8 }
504- className = { `
505- ${
506- dot . skipped
507- ? 'fill-gray-300'
508- : dot . transformed
509- ? 'fill-blue-500'
510- : 'fill-orange-500'
511- }
512- transition-colors duration-500
513- ` }
564+ fill = {
565+ dot . skipped
566+ ? theme . gridLines
567+ : dot . transformed
568+ ? theme . primary
569+ : theme . secondary
570+ }
571+ className = 'transition-colors duration-500'
514572 />
515573 ) ,
516574 ) }
@@ -528,19 +586,20 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
528586 cx = { x }
529587 cy = { y }
530588 r = { radius }
531- fill = 'red'
589+ fill = { theme . accent }
532590 opacity = { opacity }
533591 />
534592 ) ;
535593 } ) }
536594 </ svg >
537595
538596 < div className = 'space-y-4' >
539- { demoType ? (
540- ''
541- ) : (
597+ { ! demoType && (
542598 < div className = 'flex items-center justify-between mb-4' >
543- < div className = 'flex items-center gap-2' >
599+ < div
600+ className = 'flex items-center gap-2'
601+ style = { { color : theme . text } }
602+ >
544603 < span > Eager</ span >
545604 < Switch
546605 checked = { type === 'lazy' }
@@ -558,9 +617,7 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
558617 </ div >
559618 ) }
560619
561- { demoType ? (
562- ''
563- ) : (
620+ { ! demoType && (
564621 < Slider
565622 value = { [ progress ] }
566623 onValueChange = { ( [ value ] ) => {
@@ -577,7 +634,8 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
577634 { progress < MAX_PROGRESS && (
578635 < button
579636 onClick = { ( ) => setPlaying ( ( prev ) => ! prev ) }
580- className = 'px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600'
637+ className = 'px-4 py-2 rounded hover:opacity-90 transition-opacity'
638+ style = { { backgroundColor : theme . primary , color : 'white' } }
581639 >
582640 { playing ? 'Pause' : 'Play' }
583641 </ button >
@@ -590,7 +648,8 @@ const EnumerationDemo: React.FC<EnumerationDemoProps> = ({ demoType }) => {
590648 setExplosions ( [ ] ) ;
591649 processedStepsRef . current . clear ( ) ;
592650 } }
593- className = 'px-4 py-2 bg-gray-200 text-gray-800 rounded hover:bg-gray-300'
651+ className = 'px-4 py-2 rounded hover:opacity-90 transition-opacity'
652+ style = { { backgroundColor : theme . gridLines , color : theme . text } }
594653 >
595654 Reset
596655 </ button >
0 commit comments