11import classNames from 'classnames' ;
2- import { HTMLAttributes } from 'react' ;
32
4- // 👨🏻 💻 1A - Add two new types of "iconLeft" & "iconRight"
5- interface IButton extends HTMLAttributes < HTMLButtonElement > {
3+ // 👨🏻💻 1A - This component uses individual props for each map location. Can we refactor it to use slots instead?
4+ interface IPokemonMap {
65 className ?: string ;
7- children : React . ReactNode | React . ReactNode [ ] ;
6+
7+ // North area props
8+ showNorthArea ?: boolean ;
9+ northAreaName ?: string ;
10+ northAreaIcon ?: string ;
11+ northAreaColor ?: string ;
12+
13+ // South area props
14+ showSouthArea ?: boolean ;
15+ southAreaName ?: string ;
16+ southAreaIcon ?: string ;
17+ southAreaColor ?: string ;
18+
19+ // East area props
20+ showEastArea ?: boolean ;
21+ eastAreaName ?: string ;
22+ eastAreaIcon ?: string ;
23+ eastAreaColor ?: string ;
24+
25+ // West area props
26+ showWestArea ?: boolean ;
27+ westAreaName ?: string ;
28+ westAreaIcon ?: string ;
29+ westAreaColor ?: string ;
30+
31+ // Center area props
32+ showCenterArea ?: boolean ;
33+ centerAreaName ?: string ;
34+ centerAreaIcon ?: string ;
35+ centerAreaColor ?: string ;
836}
937
10- const buttonClasses =
11- 'middle none center rounded-lg bg-blue-500 py-3 px-6 font-sans text-xs font-bold uppercase text-white shadow-md shadow-blue-500/20 transition-all hover:shadow-lg hover:shadow-blue-500/40 focus:opacity-[0.85] focus:shadow-none active:opacity-[0.85] active:shadow-none disabled:pointer-events-none disabled:opacity-50 disabled:shadow-none inline-flex items-center justify-center ';
38+ const mapContainerClasses = 'grid grid-cols-3 grid-rows-3 gap-2 w-80 h-80 p-4 bg-green-100 rounded-lg border-2 border-green-300' ;
39+ const areaClasses = 'flex flex-col items- center justify-center p-3 rounded-lg border-2 text-sm font-bold text-white shadow-md';
1240
13- // 👨🏻💻 1B - Extract those types out from the props and then add iconLeft above children and iconRight below
14- // 💄 1C - styling - icon && <span className="mr-2 w-[1.5em] h-[1.5em]">{icon}</span>
15- export const Button = ( { className, children, ...rest } : IButton ) => {
41+ // 👨🏻💻 1B - Look at all these props and conditional logic! This is hard to maintain.
42+ // 👨🏻💻 1C - Refactor this to use northSlot, southSlot, eastSlot, westSlot, centerSlot instead
43+ export const PokemonMap = ( {
44+ className,
45+ showNorthArea,
46+ northAreaName,
47+ northAreaIcon,
48+ northAreaColor,
49+ showSouthArea,
50+ southAreaName,
51+ southAreaIcon,
52+ southAreaColor,
53+ showEastArea,
54+ eastAreaName,
55+ eastAreaIcon,
56+ eastAreaColor,
57+ showWestArea,
58+ westAreaName,
59+ westAreaIcon,
60+ westAreaColor,
61+ showCenterArea,
62+ centerAreaName,
63+ centerAreaIcon,
64+ centerAreaColor
65+ } : IPokemonMap ) => {
1666 return (
17- < button
18- { ...rest }
19- type = "button"
20- className = { classNames ( buttonClasses , className ) }
21- >
22- { children }
23- </ button >
67+ < div className = { classNames ( mapContainerClasses , className ) } >
68+ { /* Empty top-left */ }
69+ < div > </ div >
70+
71+ { /* North area */ }
72+ < div className = { classNames ( areaClasses , northAreaColor || 'bg-gray-400' ) } >
73+ { showNorthArea && (
74+ < >
75+ < span className = "text-2xl mb-1" > { northAreaIcon } </ span >
76+ < span className = "text-xs text-center" > { northAreaName } </ span >
77+ </ >
78+ ) }
79+ </ div >
80+
81+ { /* Empty top-right */ }
82+ < div > </ div >
83+
84+ { /* West area */ }
85+ < div className = { classNames ( areaClasses , westAreaColor || 'bg-gray-400' ) } >
86+ { showWestArea && (
87+ < >
88+ < span className = "text-2xl mb-1" > { westAreaIcon } </ span >
89+ < span className = "text-xs text-center" > { westAreaName } </ span >
90+ </ >
91+ ) }
92+ </ div >
93+
94+ { /* Center area */ }
95+ < div className = { classNames ( areaClasses , centerAreaColor || 'bg-gray-400' ) } >
96+ { showCenterArea && (
97+ < >
98+ < span className = "text-2xl mb-1" > { centerAreaIcon } </ span >
99+ < span className = "text-xs text-center" > { centerAreaName } </ span >
100+ </ >
101+ ) }
102+ </ div >
103+
104+ { /* East area */ }
105+ < div className = { classNames ( areaClasses , eastAreaColor || 'bg-gray-400' ) } >
106+ { showEastArea && (
107+ < >
108+ < span className = "text-2xl mb-1" > { eastAreaIcon } </ span >
109+ < span className = "text-xs text-center" > { eastAreaName } </ span >
110+ </ >
111+ ) }
112+ </ div >
113+
114+ { /* Empty bottom-left */ }
115+ < div > </ div >
116+
117+ { /* South area */ }
118+ < div className = { classNames ( areaClasses , southAreaColor || 'bg-gray-400' ) } >
119+ { showSouthArea && (
120+ < >
121+ < span className = "text-2xl mb-1" > { southAreaIcon } </ span >
122+ < span className = "text-xs text-center" > { southAreaName } </ span >
123+ </ >
124+ ) }
125+ </ div >
126+
127+ { /* Empty bottom-right */ }
128+ < div > </ div >
129+ </ div >
24130 ) ;
25131} ;
26132
27- // 👨🏻💻 1D - Add iconLeft={IconOne} from the icons folder to the first button
28- // 👨🏻💻 1E - Add iconRight={IconTwo} from the icons folder to the second button
29- // 👨🏻💻 1F - Add iconRight and iconLeft to the third button.
30- // Check storybook, you should see some black icons.... Why?
31- // 💅 2A - head over to ./icons/index.tsx
133+ // 👨🏻💻 1D - Look at how verbose these prop combinations are!
134+ // 👨🏻💻 1E - Refactor these to use slots: northSlot={<LocationCard />}, centerSlot={<TownCard />}, etc.
32135export const Exercise = ( ) => (
33- < div className = "grid grid-cols-1 gap-4 w-[300px]" >
34- < Button > Button one</ Button >
35- < Button > Button two</ Button >
36- < Button > Button three</ Button >
136+ < div className = "p-6 bg-blue-50 rounded-lg border-2 border-blue-200" >
137+ < h2 className = "text-2xl font-bold mb-4 text-blue-800" > 🗺️ Pokemon World Map</ h2 >
138+
139+ < PokemonMap
140+ showNorthArea = { true }
141+ northAreaName = "Viridian Forest"
142+ northAreaIcon = "🌲"
143+ northAreaColor = "bg-green-600"
144+
145+ showSouthArea = { true }
146+ southAreaName = "Route 1"
147+ southAreaIcon = "🛤️"
148+ southAreaColor = "bg-yellow-600"
149+
150+ showEastArea = { true }
151+ eastAreaName = "Power Plant"
152+ eastAreaIcon = "⚡"
153+ eastAreaColor = "bg-yellow-500"
154+
155+ showWestArea = { true }
156+ westAreaName = "Mt. Silver"
157+ westAreaIcon = "🏔️"
158+ westAreaColor = "bg-gray-600"
159+
160+ showCenterArea = { true }
161+ centerAreaName = "Pallet Town"
162+ centerAreaIcon = "🏠"
163+ centerAreaColor = "bg-blue-600"
164+ />
37165 </ div >
38- ) ;
166+ ) ;
0 commit comments