Skip to content

Commit ff3d809

Browse files
committed
feat: improve flowexample section node layout
1 parent eafd2d1 commit ff3d809

12 files changed

Lines changed: 28380 additions & 48 deletions

src/blocks/FlowExampleBlock.ts

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,13 @@ export const FlowExampleBlock: Block = {
3131
},
3232
{
3333
name: "sectionLayout",
34-
label: "Flow Layout",
34+
label: "Section Layout",
3535
type: "select",
3636
required: true,
37-
defaultValue: "flowCenter",
37+
defaultValue: "center",
3838
options: [
39-
{ label: "Flow center", value: "flowCenter" },
40-
{ label: "Flow left", value: "flowLeft" },
41-
{ label: "Flow right", value: "flowRight" },
39+
{ label: "Center", value: "center" },
40+
{ label: "Left", value: "left" },
4241
],
4342
},
4443
{
@@ -70,6 +69,17 @@ export const FlowExampleBlock: Block = {
7069
type: "textarea",
7170
localized: true,
7271
},
72+
{
73+
name: "flowLayout",
74+
label: "Flow Layout",
75+
type: "select",
76+
required: true,
77+
defaultValue: "left",
78+
options: [
79+
{ label: "Flow left", value: "left" },
80+
{ label: "Flow right", value: "right" },
81+
],
82+
},
7383
{
7484
name: "flow",
7585
type: "group",
@@ -92,6 +102,7 @@ export const FlowExampleBlock: Block = {
92102
label: "Flow items",
93103
type: "array",
94104
fields: [
105+
flowIconField(),
95106
{
96107
name: "color",
97108
type: "select",

src/collections/pages.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@ export const Pages: CollectionConfig = {
6262
{ label: "open-source-no-code-automation", value: "open-source-no-code-automation" },
6363
{ label: "contact", value: "contact" },
6464
{ label: "actions", value: "actions" },
65+
{ label: "action-details", value: "action-details" },
6566
{ label: "community-edition", value: "community-edition" },
6667
{ label: "enterprise-edition", value: "enterprise-edition" },
6768
{ label: "subscription", value: "subscription" },

src/components/nodes/NodeDisplay.tsx

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import { StableBadge } from "@/components/ui/StableBadge"
44
import { Card, Flex, Text } from "@code0-tech/pictor"
55
import { IconNote, IconVariable } from "@tabler/icons-react"
6+
import type { ReactNode } from "react"
67

78
export type NodeSegmentType = "text" | "literal" | "reference" | "node"
89
export type NodeAccent = "brand" | "yellow" | "aqua" | "blue" | "pink"
@@ -25,6 +26,7 @@ export interface NodeSegment {
2526
}
2627

2728
export interface NodeItem {
29+
icon?: ReactNode
2830
color: NodeAccent
2931
segments: NodeSegment[]
3032
outline: boolean
@@ -52,16 +54,21 @@ export function NodeMessage({ segments }: { segments: NodeSegment[] }) {
5254
)
5355
case "node":
5456
return (
55-
<StableBadge key={`${segment.type}-${segment.value}-${index}`} style={{ verticalAlign: "middle", textWrap: "nowrap" }} border>
56-
<IconNote size={12} className="text-white" />
57+
<StableBadge
58+
key={`${segment.type}-${segment.value}-${index}`}
59+
style={{ verticalAlign: "middle", textWrap: "nowrap" }}
60+
border
61+
className="border-white/20! bg-white/8! shadow-[0_2px_8px_rgba(0,0,0,0.22),inset_0_1px_0_rgba(255,255,255,0.08)]"
62+
>
63+
<IconNote size={12} className="text-brand" />
5764
<Text size="sm" style={{ color: "white" }}>
5865
{segment.value}
5966
</Text>
6067
</StableBadge>
6168
)
6269
case "text":
6370
return (
64-
<Text key={`${segment.type}-${index}`} size="sm" style={{ color: "inherit" }}>
71+
<Text key={`${segment.type}-${index}`} size="md" style={{ color: "inherit" }}>
6572
{segment.value}
6673
</Text>
6774
)
@@ -73,7 +80,9 @@ export function NodeDisplay({ node }: { node: NodeItem }) {
7380
return (
7481
<Card paddingSize="xs" py="0.35" borderColor="info" color="primary" outline={node.outline}>
7582
<Flex align="center" style={{ gap: "0.7rem" }}>
76-
<IconNote color={ICON_COLOR_MAP[node.color]} size={16} className="shrink-0" />
83+
<span className="flex size-4 shrink-0 items-center justify-center [&>svg]:size-4" style={{ color: ICON_COLOR_MAP[node.color] }}>
84+
{node.icon ?? <IconNote size={16} />}
85+
</span>
7786
<Flex align="center" wrap="wrap" className="text-secondary!" style={{ gap: "0.35rem" }}>
7887
<NodeMessage segments={node.segments} />
7988
</Flex>
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
"use client"
2+
3+
import { Card, Flex, Text } from "@code0-tech/pictor"
4+
import type { ReactNode } from "react"
5+
6+
export interface TriggerDisplayProps {
7+
icon: ReactNode
8+
text: string
9+
}
10+
11+
export function TriggerDisplay({ icon, text }: TriggerDisplayProps) {
12+
return (
13+
<Flex align="center" className="relative z-10 min-w-44 shrink-0 flex-col" style={{ gap: "0.7rem" }}>
14+
<Card
15+
variant="normal"
16+
color="secondary"
17+
paddingSize="xs"
18+
display="flex"
19+
align="center"
20+
justify="center"
21+
className="border-white/10 shadow-lg shadow-black/20"
22+
style={{
23+
aspectRatio: "1 / 1",
24+
height: "60px",
25+
minHeight: "60px",
26+
minWidth: "60px",
27+
transform: "rotate(45deg)",
28+
width: "60px",
29+
}}
30+
>
31+
<span className="flex items-center justify-center text-brand" style={{ transform: "rotate(-45deg)" }}>
32+
{icon}
33+
</span>
34+
</Card>
35+
<Text size="xs" style={{ textAlign: "center", width: "200px" }} className="font-medium text-secondary!">
36+
{text}
37+
</Text>
38+
</Flex>
39+
)
40+
}

src/components/sections/FlowExampleSection.tsx

Lines changed: 17 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ export function FlowExampleSection({ content }: FlowExampleSectionProps) {
2525
content.flow?.items?.map((item, index) => ({
2626
id: String(item.id ?? index),
2727
node: {
28+
icon: getIcon(item.icon, 16),
2829
color: item.color as NodeAccent,
2930
outline: item.outline !== false,
3031
segments: item.segments.map((segment) => ({
@@ -33,11 +34,10 @@ export function FlowExampleSection({ content }: FlowExampleSectionProps) {
3334
})),
3435
},
3536
})) ?? []
36-
const isCenter = content.sectionLayout === "flowCenter"
37-
const isRight = content.sectionLayout === "flowRight"
37+
const isFlowRight = content.flowLayout === "right"
3838
const showBorder = Boolean(content.showBorder)
3939
const flow = (
40-
<div className={cn("relative m-2 min-w-0 overflow-hidden rounded-2xl border border-white/10 bg-light", isCenter ? "min-h-72" : "min-h-72 lg:min-h-96", isRight && "lg:order-2")}>
40+
<div className={cn("relative m-2 min-h-72 min-w-0 overflow-hidden rounded-2xl border border-white/10 bg-light lg:min-h-96", isFlowRight && "lg:order-2")}>
4141
<DotBackground
4242
className="opacity-50 mask-[radial-gradient(ellipse_at_center,black_35%,transparent_85%)]"
4343
dotColor="rgba(255,255,255,0.14)"
@@ -52,10 +52,9 @@ export function FlowExampleSection({ content }: FlowExampleSectionProps) {
5252
className={cn(
5353
"flex flex-col justify-center",
5454
showBorder && "p-8 md:p-10",
55-
!showBorder && isCenter && "pt-8 md:pt-10",
56-
!showBorder && !isCenter && !isRight && "py-8 pl-8 md:py-10 md:pl-10",
57-
!showBorder && isRight && "py-8 pr-8 md:py-10 md:pr-10",
58-
isRight && "lg:order-1"
55+
!showBorder && !isFlowRight && "py-8 pl-8 md:py-10 md:pl-10",
56+
!showBorder && isFlowRight && "py-8 pr-8 md:py-10 md:pr-10",
57+
isFlowRight && "lg:order-1"
5958
)}
6059
delayChildren={0.06}
6160
staggerChildren={0.08}
@@ -72,26 +71,22 @@ export function FlowExampleSection({ content }: FlowExampleSectionProps) {
7271
)}
7372
</StaggerContainer>
7473
)
75-
7674
const example = (
77-
<article className={cn("relative z-10 overflow-hidden", isCenter ? "flex flex-col" : "grid lg:grid-cols-2")}>
78-
{isCenter ? (
79-
<>
80-
{flow}
81-
{(content.contentHeading || content.contentDescription) && body}
82-
</>
83-
) : (
84-
<>
85-
{flow}
86-
{body}
87-
</>
88-
)}
75+
<article className="relative z-10 grid min-h-96 overflow-hidden lg:grid-cols-2">
76+
{flow}
77+
{body}
8978
</article>
9079
)
9180

9281
return (
93-
<Section heading={content.sectionHeading} description={content.sectionDescription} linkButton={content.sectionLinkButton} funnelType="center" animation={{ preset: "none" }}>
94-
<div className={cn("mx-auto w-full", isCenter && "max-w-5xl")}>
82+
<Section
83+
heading={content.sectionHeading}
84+
description={content.sectionDescription}
85+
linkButton={content.sectionLinkButton}
86+
funnelType={content.sectionLayout ?? "center"}
87+
animation={{ preset: "none" }}
88+
>
89+
<div className="mx-auto w-full">
9590
{showBorder ? (
9691
<Card size="lg" variant="light" className="p-2!">
9792
{example}

src/components/sections/client/FlowExampleDiagram.tsx

Lines changed: 2 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
"use client"
22

3-
import { Text } from "@code0-tech/pictor"
43
import { getNodeAccentColor, NodeDisplay, type NodeItem } from "@/components/nodes/NodeDisplay"
4+
import { TriggerDisplay } from "@/components/nodes/TriggerDisplay"
55
import { m as motion, useReducedMotion } from "motion/react"
66
import type { ReactNode } from "react"
77

@@ -16,19 +16,6 @@ export interface FlowDiagramItem {
1616
node: NodeItem
1717
}
1818

19-
function FlowNode({ node }: { node: FlowDiagramNode }) {
20-
return (
21-
<div className="relative z-10 flex min-w-44 shrink-0 flex-col items-center">
22-
<div className="flex size-12 rotate-45 items-center justify-center rounded-xl border border-white/10 bg-primary text-brand shadow-lg shadow-black/20">
23-
<span className="flex -rotate-45 items-center justify-center">{node.icon}</span>
24-
</div>
25-
<Text size="sm" className="absolute left-1/2 top-[calc(100%+0.25rem)] z-20 -translate-x-1/2 whitespace-nowrap text-center font-medium text-secondary!">
26-
{node.text}
27-
</Text>
28-
</div>
29-
)
30-
}
31-
3219
export function FlowExampleDiagram({ trigger, items }: { trigger: FlowDiagramNode; items: FlowDiagramItem[] }) {
3320
const reducedMotion = useReducedMotion()
3421
const nodes = [{ id: trigger.id, trigger }, ...items]
@@ -84,7 +71,7 @@ export function FlowExampleDiagram({ trigger, items }: { trigger: FlowDiagramNod
8471
transition={{ duration: 0.38, delay: index * 0.2, ease: [0.22, 1, 0.36, 1] }}
8572
>
8673
{"trigger" in node ? (
87-
<FlowNode node={node.trigger} />
74+
<TriggerDisplay icon={node.trigger.icon} text={node.trigger.text} />
8875
) : (
8976
<motion.div
9077
className="relative isolate rounded-2xl"

0 commit comments

Comments
 (0)