@@ -21,6 +21,7 @@ import {
2121 type RequiredMetadata ,
2222 useEditorStore ,
2323} from "../../store"
24+ import { chakraAny } from "../../utils"
2425import { NavbarItem } from "./NavbarItem"
2526import { SettingsModal } from "./SettingsModal"
2627import { TemplateNameInput } from "./TemplateNameInput"
@@ -64,7 +65,13 @@ export const Header = ({
6465 onClose,
6566 exportOptions,
6667 onViewAllTemplates,
67- } : HeaderProps ) => {
68+ } : HeaderProps ) : React . ReactElement => {
69+ const FlexAny = chakraAny ( Flex )
70+ const DividerAny = chakraAny ( Divider )
71+ const MenuButtonAny = chakraAny ( MenuButton )
72+ const MenuListAny = chakraAny ( MenuList )
73+ const MenuItemAny = chakraAny ( MenuItem )
74+
6875 const { imageList, originalImageList, currentImage } = useEditorStore ( )
6976 const templateId = useEditorStore ( ( s ) => s . templateId )
7077 const templateIsPrivate = useEditorStore ( ( s ) => s . templateIsPrivate )
@@ -102,8 +109,15 @@ export const Header = ({
102109 }
103110 } , [ provider , templateId , syncStatus ] )
104111
112+ const visibleExportOptions =
113+ exportOptions ?. filter ( ( exportOption ) =>
114+ typeof exportOption . isVisible === "boolean"
115+ ? exportOption . isVisible
116+ : exportOption . isVisible ( imageList , currentImage ) ,
117+ ) ?? [ ]
118+
105119 return (
106- < Flex
120+ < FlexAny
107121 as = "header"
108122 width = "full"
109123 h = "16"
@@ -117,7 +131,7 @@ export const Header = ({
117131 >
118132 { provider ? (
119133 < >
120- < Flex alignItems = "center" gap = "2" px = "4" height = "full" ml = "-4" >
134+ < FlexAny alignItems = "center" gap = "2" px = "4" height = "full" ml = "-4" >
121135 { templateId && (
122136 < Icon
123137 as = {
@@ -135,8 +149,8 @@ export const Header = ({
135149 />
136150 ) }
137151 < TemplateNameInput />
138- </ Flex >
139- < Divider
152+ </ FlexAny >
153+ < DividerAny
140154 orientation = "vertical"
141155 borderColor = "editorBattleshipGrey.200"
142156 height = "40%"
@@ -147,102 +161,103 @@ export const Header = ({
147161 variant = "icon"
148162 onClick = { ( ) => setIsSettingsOpen ( true ) }
149163 />
150- < Divider
164+ < DividerAny
151165 orientation = "vertical"
152166 borderColor = "editorBattleshipGrey.200"
153167 height = "40%"
154168 />
155- < Flex alignItems = "center" >
169+ < FlexAny alignItems = "center" >
156170 < TemplatesDropdown onViewAllTemplates = { onViewAllTemplates } />
157- </ Flex >
158- < Divider
171+ </ FlexAny >
172+ < DividerAny
159173 orientation = "vertical"
160174 borderColor = "editorBattleshipGrey.200"
161175 height = "40%"
162176 />
163177 </ >
164178 ) : null }
165- < Flex ml = "6" >
179+ < FlexAny ml = "6" >
166180 < TemplateStatus />
167- </ Flex >
181+ </ FlexAny >
168182 < Spacer />
169- { exportOptions
170- ?. filter ( ( exportOption ) =>
171- typeof exportOption . isVisible === "boolean"
172- ? exportOption . isVisible
173- : exportOption . isVisible ( imageList , currentImage ) ,
174- )
175- . map ( ( exportOption ) => (
176- < React . Fragment key = { `export-option-${ exportOption . label } ` } >
177- { exportOption . type === "button" ? (
178- < NavbarItem
179- key = { `export-button-${ exportOption . label } ` }
183+ { visibleExportOptions . map ( ( exportOption , exportOptionIndex ) => (
184+ < React . Fragment key = { `export-option-${ exportOption . label } ` } >
185+ { exportOption . type === "button" ? (
186+ < NavbarItem
187+ key = { `export-button-${ exportOption . label } ` }
188+ icon = { exportOption . icon }
189+ label = { exportOption . label }
190+ onClick = { ( ) => {
191+ const images = imageList . map ( ( image , index ) => ( {
192+ url : image ,
193+ file : originalImageList [ index ] ,
194+ } ) )
195+ const cImage = images . find (
196+ ( image ) => image . url === currentImage ,
197+ )
198+ exportOption . onClick ( images , {
199+ // biome-ignore lint/style/noNonNullAssertion: <required here>
200+ url : cImage ! . url ,
201+ // biome-ignore lint/style/noNonNullAssertion: <required here>
202+ file : cImage ! . file ,
203+ } )
204+ } }
205+ />
206+ ) : (
207+ < Menu
208+ key = { `export-menu-${ exportOption . label } ` }
209+ placement = "bottom-end"
210+ strategy = "fixed"
211+ >
212+ < MenuButtonAny
213+ as = { NavbarItem }
180214 icon = { exportOption . icon }
181215 label = { exportOption . label }
182- onClick = { ( ) => {
183- const images = imageList . map ( ( image , index ) => ( {
184- url : image ,
185- file : originalImageList [ index ] ,
186- } ) )
187- const cImage = images . find (
188- ( image ) => image . url === currentImage ,
189- )
190- exportOption . onClick ( images , {
191- // biome-ignore lint/style/noNonNullAssertion: <required here>
192- url : cImage ! . url ,
193- // biome-ignore lint/style/noNonNullAssertion: <required here>
194- file : cImage ! . file ,
195- } )
196- } }
197- />
198- ) : (
199- < Menu
200- key = { `export-menu-${ exportOption . label } ` }
201- placement = "bottom-end"
202- strategy = "fixed"
203216 >
204- < MenuButton
205- as = { NavbarItem }
206- icon = { exportOption . icon }
207- label = { exportOption . label }
208- >
209- { exportOption . label }
210- </ MenuButton >
211- < MenuList >
212- { exportOption . options
213- . filter ( ( option ) =>
214- typeof option . isVisible === "boolean"
215- ? option . isVisible
216- : option . isVisible ( imageList , currentImage ) ,
217- )
218- . map ( ( option ) => (
219- < MenuItem
220- key = { `export-menu-option-${ option . label } ` }
221- onClick = { ( ) => {
222- const images = imageList . map ( ( image , index ) => ( {
223- url : image ,
224- file : originalImageList [ index ] ,
225- } ) )
226- const cImage = images . find (
227- ( image ) => image . url === currentImage ,
228- )
229- option . onClick ( images , {
230- // biome-ignore lint/style/noNonNullAssertion: <required here>
231- url : cImage ! . url ,
232- // biome-ignore lint/style/noNonNullAssertion: <required here>
233- file : cImage ! . file ,
234- } )
235- } }
236- >
237- { option . label }
238- </ MenuItem >
239- ) ) }
240- </ MenuList >
241- </ Menu >
242- ) }
243- </ React . Fragment >
244- ) ) }
245- < Divider
217+ { exportOption . label }
218+ </ MenuButtonAny >
219+ < MenuListAny >
220+ { exportOption . options
221+ . filter ( ( option ) =>
222+ typeof option . isVisible === "boolean"
223+ ? option . isVisible
224+ : option . isVisible ( imageList , currentImage ) ,
225+ )
226+ . map ( ( option ) => (
227+ < MenuItemAny
228+ key = { `export-menu-option-${ option . label } ` }
229+ onClick = { ( ) => {
230+ const images = imageList . map ( ( image , index ) => ( {
231+ url : image ,
232+ file : originalImageList [ index ] ,
233+ } ) )
234+ const cImage = images . find (
235+ ( image ) => image . url === currentImage ,
236+ )
237+ option . onClick ( images , {
238+ // biome-ignore lint/style/noNonNullAssertion: <required here>
239+ url : cImage ! . url ,
240+ // biome-ignore lint/style/noNonNullAssertion: <required here>
241+ file : cImage ! . file ,
242+ } )
243+ } }
244+ >
245+ { option . label }
246+ </ MenuItemAny >
247+ ) ) }
248+ </ MenuListAny >
249+ </ Menu >
250+ ) }
251+ { exportOptionIndex < visibleExportOptions . length - 1 ? (
252+ < DividerAny
253+ orientation = "vertical"
254+ borderColor = "editorBattleshipGrey.200"
255+ height = "40%"
256+ />
257+ ) : null }
258+ </ React . Fragment >
259+ ) ) }
260+ < DividerAny
246261 orientation = "vertical"
247262 borderColor = "editorBattleshipGrey.200"
248263 height = "40%"
@@ -270,6 +285,6 @@ export const Header = ({
270285 } }
271286 />
272287 ) }
273- </ Flex >
288+ </ FlexAny >
274289 )
275290}
0 commit comments