11import React , { useEffect , useState } from "react" ;
2- import Settings , { Item , SvgStyle } from "../settings" ;
2+ import Settings , {
3+ GraphicMediaAspectRatio ,
4+ GridGraphicType ,
5+ GridMediaAlignment ,
6+ GridStyle ,
7+ Item ,
8+ SvgStyle ,
9+ } from "../settings" ;
10+ import {
11+ DEFAULT_GRID_STYLE ,
12+ getDefaultMediaAlignment ,
13+ normalizeGraphicType ,
14+ normalizeMediaAlignment ,
15+ } from "../normalizers" ;
316import ItemEditor from "./item-editor" ;
417import {
518 Address ,
@@ -50,6 +63,7 @@ export default function AdminWidget({
5063 preservedStateAcrossRerender,
5164 theme,
5265} : AdminWidgetProps ) : JSX . Element {
66+ const initialStyle : GridStyle = settings . style || DEFAULT_GRID_STYLE ;
5367 const dummyDescription : Record < string , unknown > = {
5468 type : "doc" ,
5569 content : [
@@ -120,6 +134,37 @@ export default function AdminWidget({
120134 ) ;
121135 const [ svgInline , setSvgInline ] = useState ( settings . svgInline || false ) ;
122136 const [ editingSvgStyle , setEditingSvgStyle ] = useState ( false ) ;
137+ const [ style , setStyle ] = useState < GridStyle > ( initialStyle ) ;
138+ const [ graphicType , setGraphicType ] = useState < GridGraphicType > (
139+ normalizeGraphicType ( initialStyle , settings . graphicType || "media" ) ,
140+ ) ;
141+ const [ graphicMediaAspectRatio , setGraphicMediaAspectRatio ] =
142+ useState < GraphicMediaAspectRatio > (
143+ settings . graphicMediaAspectRatio ||
144+ ( settings . style === "mediacard" ? "16/9" : "1/1" ) ,
145+ ) ;
146+ const [ mediaAlignment , setMediaAlignment ] = useState < GridMediaAlignment > (
147+ normalizeMediaAlignment (
148+ initialStyle ,
149+ settings . mediaAlignment || getDefaultMediaAlignment ( initialStyle ) ,
150+ ) ,
151+ ) ;
152+
153+ useEffect ( ( ) => {
154+ const normalizedGraphicType = normalizeGraphicType ( style , graphicType ) ;
155+ const normalizedMediaAlignment = normalizeMediaAlignment (
156+ style ,
157+ mediaAlignment ,
158+ ) ;
159+
160+ if ( normalizedGraphicType !== graphicType ) {
161+ setGraphicType ( normalizedGraphicType ) ;
162+ }
163+
164+ if ( normalizedMediaAlignment !== mediaAlignment ) {
165+ setMediaAlignment ( normalizedMediaAlignment ) ;
166+ }
167+ } , [ style , graphicType , mediaAlignment ] ) ;
123168
124169 const onSettingsChanged = ( ) =>
125170 onChange ( {
@@ -136,6 +181,10 @@ export default function AdminWidget({
136181 columns,
137182 svgStyle,
138183 svgInline,
184+ style,
185+ graphicType,
186+ graphicMediaAspectRatio,
187+ mediaAlignment,
139188 } ) ;
140189
141190 useEffect ( ( ) => {
@@ -154,11 +203,16 @@ export default function AdminWidget({
154203 columns ,
155204 svgStyle ,
156205 svgInline ,
206+ style ,
207+ graphicType ,
208+ graphicMediaAspectRatio ,
209+ mediaAlignment ,
157210 ] ) ;
158211
159212 const onItemChange = ( newItemData : Item ) => {
160- items [ itemBeingEditedIndex ] = newItemData ;
161- setItems ( [ ...items ] ) ;
213+ const newItems = [ ...items ] ;
214+ newItems [ itemBeingEditedIndex ] = newItemData ;
215+ setItems ( newItems ) ;
162216 setItemBeingEditedIndex ( - 1 ) ;
163217 hideActionButtons ( false , { } ) ;
164218 } ;
@@ -193,6 +247,8 @@ export default function AdminWidget({
193247 profile = { profile }
194248 address = { address }
195249 svgStyle = { svgStyle }
250+ graphicType = { graphicType }
251+ style = { style }
196252 />
197253 ) ;
198254 }
@@ -287,14 +343,93 @@ export default function AdminWidget({
287343 </ AdminWidgetPanel >
288344 < AdminWidgetPanel title = "Design" value = "design" >
289345 < Select
290- title = "Items alignment"
346+ title = "Style"
347+ value = { style }
348+ options = { [
349+ { label : "Default" , value : "default" } ,
350+ { label : "Testimonial" , value : "testimonial" } ,
351+ { label : "Feature grid" , value : "featuregrid" } ,
352+ { label : "Media card" , value : "mediacard" } ,
353+ ] }
354+ onChange = { ( value : GridStyle ) => setStyle ( value ) }
355+ />
356+ < Select
357+ title = "Item text alignment"
291358 value = { itemsAlignment }
292359 options = { [
293360 { label : "Left" , value : "left" } ,
294361 { label : "Center" , value : "center" } ,
295362 ] }
296363 onChange = { ( value : Alignment ) => setItemsAlignment ( value ) }
297364 />
365+ { style !== "mediacard" && (
366+ < div className = "flex flex-col gap-4 mb-4" >
367+ { ( style === "default" || style === "featuregrid" ) && (
368+ < Select
369+ title = "Graphic type"
370+ value = { graphicType }
371+ options = { [
372+ { label : "Media" , value : "media" } ,
373+ { label : "SVG" , value : "svg" } ,
374+ ] }
375+ onChange = { ( value : GridGraphicType ) =>
376+ setGraphicType ( value )
377+ }
378+ />
379+ ) }
380+ { ( graphicType === "media" ||
381+ style === "testimonial" ||
382+ style === "featuregrid" ) && (
383+ < Select
384+ title = "Media alignment"
385+ value = { mediaAlignment }
386+ options = {
387+ style === "default"
388+ ? [
389+ { label : "Top" , value : "top" } ,
390+ {
391+ label : "Bottom" ,
392+ value : "bottom" ,
393+ } ,
394+ ]
395+ : [
396+ { label : "Left" , value : "left" } ,
397+ {
398+ label : "Center" ,
399+ value : "center" ,
400+ } ,
401+ {
402+ label : "Right" ,
403+ value : "right" ,
404+ } ,
405+ ]
406+ }
407+ onChange = { ( value : GridMediaAlignment ) =>
408+ setMediaAlignment ( value )
409+ }
410+ />
411+ ) }
412+ </ div >
413+ ) }
414+ { ( ( graphicType === "media" &&
415+ ( style === "default" || style === "featuregrid" ) ) ||
416+ style === "mediacard" ) && (
417+ < Select
418+ title = "Media aspect ratio"
419+ value = { graphicMediaAspectRatio }
420+ options = { [
421+ { label : "Auto" , value : "auto" } ,
422+ { label : "16:9" , value : "16/9" } ,
423+ { label : "4:3" , value : "4/3" } ,
424+ { label : "1:1" , value : "1/1" } ,
425+ { label : "3:4" , value : "3/4" } ,
426+ { label : "9:16" , value : "9/16" } ,
427+ ] }
428+ onChange = { ( value : GraphicMediaAspectRatio ) =>
429+ setGraphicMediaAspectRatio ( value )
430+ }
431+ />
432+ ) }
298433 < PageBuilderSlider
299434 title = "Columns"
300435 value = { columns }
@@ -313,33 +448,39 @@ export default function AdminWidget({
313448 }
314449 onChange = { setVerticalPadding }
315450 />
316- < div className = "flex justify-between mt-2" >
317- < div className = "flex grow items-center gap-1" >
318- < p > Icon inline</ p >
319- < Tooltip title = "The icon (if used) will show inline with the item header" >
320- < HelpCircle className = "w-4 h-4" />
321- </ Tooltip >
322- </ div >
323- < Checkbox
324- checked = { svgInline }
325- onChange = { ( value : boolean ) => setSvgInline ( value ) }
326- />
327- </ div >
328- < div className = "flex justify-between mt-2" >
329- < div className = "flex grow items-center gap-1" >
330- < p > Icon style</ p >
451+ { graphicType === "svg" && style === "default" && (
452+ < div className = "flex justify-between mt-2" >
453+ < div className = "flex grow items-center gap-1" >
454+ < p > Icon inline</ p >
455+ < Tooltip title = "The icon (if used) will show inline with the item header" >
456+ < HelpCircle className = "w-4 h-4" />
457+ </ Tooltip >
458+ </ div >
459+ < Checkbox
460+ checked = { svgInline }
461+ onChange = { ( value : boolean ) => setSvgInline ( value ) }
462+ />
331463 </ div >
332- < Button2
333- size = "icon"
334- variant = "outline"
335- onClick = { ( ) => {
336- setEditingSvgStyle ( true ) ;
337- hideActionButtons ( true , { } ) ;
338- } }
339- >
340- < WandSparkles className = "w-4 h-4" />
341- </ Button2 >
342- </ div >
464+ ) }
465+ { graphicType === "svg" &&
466+ style !== "mediacard" &&
467+ style !== "testimonial" && (
468+ < div className = "flex justify-between mt-2" >
469+ < div className = "flex grow items-center gap-1" >
470+ < p > Icon style</ p >
471+ </ div >
472+ < Button2
473+ size = "icon"
474+ variant = "outline"
475+ onClick = { ( ) => {
476+ setEditingSvgStyle ( true ) ;
477+ hideActionButtons ( true , { } ) ;
478+ } }
479+ >
480+ < WandSparkles className = "w-4 h-4" />
481+ </ Button2 >
482+ </ div >
483+ ) }
343484 </ AdminWidgetPanel >
344485 < AdminWidgetPanel title = "Advanced" value = "advanced" >
345486 < CssIdField value = { cssId } onChange = { setCssId } />
0 commit comments