From 75007a3ca62615fb3ff6034920f390e6113b21b9 Mon Sep 17 00:00:00 2001 From: Ben Life Date: Fri, 20 Dec 2024 16:48:46 -0500 Subject: [PATCH] add header component --- src/components/puck/Header.tsx | 188 +++++++++++++++++++++ src/components/puck/index.ts | 1 + src/components/puck/registry/components.ts | 5 + 3 files changed, 194 insertions(+) create mode 100644 src/components/puck/Header.tsx diff --git a/src/components/puck/Header.tsx b/src/components/puck/Header.tsx new file mode 100644 index 0000000..dff6c74 --- /dev/null +++ b/src/components/puck/Header.tsx @@ -0,0 +1,188 @@ +import * as React from "react"; +import { Link, CTA, ImageType, Image } from "@yext/pages-components"; +import { ComponentConfig, Fields } from "@measured/puck"; +import { + resolveYextEntityField, + themeMangerCn, + useDocument, + YextEntityField, + YextEntityFieldSelector, +} from "../../index.ts"; +import { cva, VariantProps } from "class-variance-authority"; +import { v4 } from "uuid"; + +const PLACEHOLDER_LOGO_URL = "https://placehold.co/50"; + +const headerVariants = cva("", { + variants: { + backgroundColor: { + default: "bg-header-backgroundColor", + primary: "bg-palette-primary", + secondary: "bg-palette-secondary", + accent: "bg-palette-accent", + text: "bg-palette-text", + background: "bg-palette-background", + }, + }, + defaultVariants: { + backgroundColor: "default", + }, +}); + +export interface HeaderProps extends VariantProps { + logo: { + image: YextEntityField; + }; + links: { cta: YextEntityField; id?: string }[]; +} + +const headerFields: Fields = { + logo: { + type: "object", + label: "Logo", + objectFields: { + image: YextEntityFieldSelector({ + label: "Image", + filter: { + types: ["type.image"], + }, + }), + }, + }, + links: { + type: "array", + label: "Links", + arrayFields: { + cta: YextEntityFieldSelector({ + label: "Call To Action", + filter: { + types: ["type.cta"], + }, + }), + }, + getItemSummary: (_, i) => `Link ${i !== undefined ? i + 1 : ""}`, + defaultItemProps: { + id: v4(), + cta: { + field: "", + constantValue: { link: "#", label: "Link" }, + constantValueEnabled: true, + }, + }, + }, + backgroundColor: { + label: "Background Color", + type: "select", + options: [ + { label: "Default", value: "default" }, + { label: "Primary", value: "primary" }, + { label: "Secondary", value: "secondary" }, + { label: "Accent", value: "accent" }, + { label: "Text", value: "text" }, + { label: "Background", value: "background" }, + ], + }, +}; + +export const Header: ComponentConfig = { + fields: headerFields, + defaultProps: { + logo: { + image: { + field: "", + constantValue: { + height: 50, + width: 50, + url: PLACEHOLDER_LOGO_URL, + }, + constantValueEnabled: true, + }, + }, + links: [ + { + cta: { + field: "", + constantValue: { link: "#", label: "Link" }, + constantValueEnabled: true, + }, + }, + { + cta: { + field: "", + constantValue: { link: "#", label: "Link" }, + constantValueEnabled: true, + }, + }, + { + cta: { + field: "", + constantValue: { link: "#", label: "Link" }, + constantValueEnabled: true, + }, + }, + ], + }, + label: "Header", + render: (props) => , + resolveData: ({ props }, { lastData }) => { + if (lastData?.props.links.length === props.links.length) { + return { props }; + } + + return { + props: { + ...props, + links: props.links.map((link) => ({ + ...link, + id: link.id ?? v4(), + })), + }, + }; + }, +}; + +const HeaderComponent: React.FC = (props) => { + const document = useDocument(); + const { logo, links, backgroundColor } = props; + + const resolvedLogo = resolveYextEntityField(document, logo.image); + const resolvedLinks = links + ?.map((link) => { + const resolvedCTA = resolveYextEntityField(document, link.cta); + if (resolvedCTA) { + return { + id: link.id!, + ...resolvedCTA, + }; + } + }) + .filter((link) => link !== undefined); + + console.log(resolvedLinks, links); + return ( +
+
+ {resolvedLogo && ( + + )} +
+
    + {resolvedLinks?.map((item, idx) => ( +
  • + +
  • + ))} +
+
+
+
+ ); +}; diff --git a/src/components/puck/index.ts b/src/components/puck/index.ts index 33ce5fd..4a10821 100644 --- a/src/components/puck/index.ts +++ b/src/components/puck/index.ts @@ -6,6 +6,7 @@ export { Emails, type EmailsProps } from "./Emails.tsx"; export { FlexContainer, type FlexContainerProps } from "./FlexContainer.tsx"; export { GetDirections, type GetDirectionsProps } from "./GetDirections.tsx"; export { GridSection, type GridSectionProps } from "./GridSection.tsx"; +export { Header, type HeaderProps } from "./Header.tsx"; export { HeadingText, type HeadingTextProps } from "./HeadingText.tsx"; export { HoursTable, type HoursTableProps } from "./HoursTable.tsx"; export { HoursStatus, type HoursStatusProps } from "./HoursStatus.tsx"; diff --git a/src/components/puck/registry/components.ts b/src/components/puck/registry/components.ts index b52a4ab..3a227b1 100644 --- a/src/components/puck/registry/components.ts +++ b/src/components/puck/registry/components.ts @@ -76,6 +76,11 @@ export const ui: Registry = [ registryDependencies: ["section"], files: ["GridSection.tsx"], }, + { + name: "Header", + type: "registry:ui", + files: ["Header.tsx"], + }, { name: "HeadingText", type: "registry:ui",