Skip to content

Commit d074663

Browse files
author
Rajat
committed
Grid component can switch between four new styles
1 parent 7a55b34 commit d074663

12 files changed

Lines changed: 828 additions & 202 deletions

File tree

packages/page-blocks/AGENTS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
# Development tips
2+
3+
- Always use primitives from @courselit/page-primitives to build the entire layout of the block. Don't use any custom styles or classes.

packages/page-blocks/src/blocks/grid/admin-widget/index.tsx

Lines changed: 171 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
11
import 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";
316
import ItemEditor from "./item-editor";
417
import {
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

Comments
 (0)