diff --git a/src/layouts/components/Homepage/HeroBody.tsx b/src/layouts/components/Homepage/HeroBody.tsx
index f2f0f3b397..bd594daff2 100644
--- a/src/layouts/components/Homepage/HeroBody.tsx
+++ b/src/layouts/components/Homepage/HeroBody.tsx
@@ -5,14 +5,19 @@ import {
Text,
Box,
Divider,
+ VStack,
HStack,
+ Spacer,
} from "@chakra-ui/react"
import {
FormErrorMessage,
FormLabel,
+ IconButton,
Input,
Radio,
+ SingleSelect,
} from "@opengovsg/design-system-react"
+import _ from "lodash"
import { useState } from "react"
import { BiInfoCircle } from "react-icons/bi"
@@ -37,6 +42,285 @@ export interface HeroBodyFormFields {
background: string
}
+const HERO_LAYOUTS = {
+ CENTERED: {
+ value: "center",
+ label: "Centre-aligned text",
+ },
+ IMAGE_ONLY: {
+ value: "image",
+ label: "Image only",
+ },
+ SIDE_SECTION: {
+ value: "side",
+ label: "Side section",
+ },
+} as const
+
+interface HeroCenteredLayoutProps extends HeroBodyFormFields {
+ index: number
+ errors: {
+ title: string
+ subtitle: string
+ background: string
+ } & HeroBodyFormFields
+}
+
+const HeroCenteredLayout = ({
+ title,
+ subtitle,
+ background,
+ index,
+ errors,
+}: HeroCenteredLayoutProps) => {
+ const { onChange } = useEditableContext()
+ return (
+ <>
+
+ Hero title
+
+ {errors.title}
+
+
+ Hero subtitle
+
+ {errors.subtitle}
+
+
+ {/* TODO: migrate this to design system components */}
+
+
+ Hero background image
+
+
+ {errors.background}
+
+
+ >
+ )
+}
+
+const HeroImageOnlyLayout = ({
+ errors,
+ background,
+ index,
+}: Omit) => {
+ const { onChange } = useEditableContext()
+ return (
+
+ {/* TODO: migrate this to design system components */}
+
+
+ Hero background image
+
+
+ {errors.background}
+
+
+ )
+}
+
+type SectionSize = "half" | "one-third"
+
+type SectionAlignment = "left" | "right"
+
+type SectionBackgroundColor = "black" | "white" | "translucent gray"
+
+interface HeroSideSectionProps {
+ background: string
+ index: number
+ errors: {
+ title: string
+ subtitle: string
+ background: string
+ } & HeroBodyFormFields
+ size: SectionSize
+ alignment: SectionAlignment
+ backgroundColor: SectionBackgroundColor
+}
+
+const HeroSideSectionLayout = ({
+ background,
+ index,
+ errors,
+ size = "half",
+ alignment = "left",
+ backgroundColor = "black",
+}: HeroSideSectionProps) => {
+ const { onChange } = useEditableContext()
+ const [, setSectionSize] = useState(size)
+ const [, setSectionAlignment] = useState(alignment)
+ const [, setSectionBackgroundColor] = useState(backgroundColor)
+
+ return (
+ <>
+
+ {/* TODO: migrate this to design system components */}
+
+
+ Hero background image
+
+
+ {errors.background}
+
+
+
+ Section size
+ {
+ setSectionSize(nextSectionSize as SectionSize)
+ }}
+ defaultValue="half"
+ >
+
+
+ Half (1/2) of banner
+
+
+
+ Third (1/3) of banner
+
+
+
+
+
+ Alignment
+ {
+ setSectionAlignment(nextSectionAlignment as SectionAlignment)
+ }}
+ defaultValue="left"
+ >
+
+
+ Left
+
+
+
+ Right
+
+
+
+
+
+ Section background colour
+
+ setSectionBackgroundColor("black")}
+ _focus={{
+ boxShadow: "0 0 0 2px var(--chakra-colors-border-action-default)",
+ }}
+ >
+
+
+ setSectionBackgroundColor("white")}
+ >
+
+
+ setSectionBackgroundColor("translucent gray")}
+ />
+
+
+ >
+ )
+}
+
+type HeroBannerLayouts = typeof HERO_LAYOUTS[keyof typeof HERO_LAYOUTS]["value"]
+
+interface HeroLayoutFormProps {
+ children: (props: {
+ currentSelectedOption: HeroBannerLayouts
+ }) => React.ReactNode
+}
+
+const HeroLayoutForm = ({ children }: HeroLayoutFormProps): JSX.Element => {
+ const [currentLayout, setCurrentLayout] = useState(
+ HERO_LAYOUTS.CENTERED.value
+ )
+
+ return (
+ <>
+
+ Layout
+ setCurrentLayout(val as HeroBannerLayouts)}
+ />
+
+
+ {children({ currentSelectedOption: currentLayout })}
+
+ >
+ )
+}
+
interface HeroBodyProps extends HeroBodyFormFields {
index: number
errors: {
@@ -54,14 +338,10 @@ interface HeroBodyProps extends HeroBodyFormFields {
}
export const HeroBody = ({
- title,
- subtitle,
- background,
- index,
- errors,
handleHighlightDropdownToggle,
notification,
children,
+ ...rest
}: HeroBodyProps) => {
const [heroSectionType, setHeroSectionType] = useState(
"highlights"
@@ -93,48 +373,36 @@ export const HeroBody = ({
-
- Hero title
-
- {errors.title}
-
-
- Hero subtitle
-
- {errors.subtitle}
-
-
- {/* TODO: migrate this to design system components */}
-
-
- Hero background image
-
-
- {errors.background}
-
-
+
+
+ {({ currentSelectedOption }) => {
+ if (currentSelectedOption === HERO_LAYOUTS.CENTERED.value) {
+ return
+ }
+
+ if (currentSelectedOption === HERO_LAYOUTS.IMAGE_ONLY.value) {
+ return
+ }
+
+ if (currentSelectedOption === HERO_LAYOUTS.SIDE_SECTION.value) {
+ return (
+
+ )
+ }
+
+ const unmatchedOption: never = currentSelectedOption
+ throw new Error(`Unmatched option for layout: ${unmatchedOption}`)
+ }}
+
-
+
Customise Layout
@@ -149,21 +417,11 @@ export const HeroBody = ({
}}
defaultValue="highlights"
>
-
-
+
+
Button + Highlights
-
+
Dropdown