@avocadostudio-ai/blocks 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -18,9 +18,16 @@ export declare function normalizeSoftHyphenEntities<T>(value: T, seen?: WeakSet<
18
18
  type ButtonProps = AnchorHTMLAttributes<HTMLAnchorElement> & {
19
19
  href: string;
20
20
  children: ReactNode;
21
+ /**
22
+ * Open the link in a new tab. Off unless the editor turned it on, so no
23
+ * already-published link changes behaviour on its own, and honoured only for
24
+ * an external destination — `linkAttrs` decides, and pairs `target="_blank"`
25
+ * with the `rel="noopener noreferrer"` that makes it safe.
26
+ */
27
+ newTab?: boolean;
21
28
  };
22
- export declare function PrimaryButton({ href, children, className, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
23
- export declare function SecondaryButton({ href, children, className, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
24
- export declare function TertiaryButton({ href, children, className, ...rest }: ButtonProps): import("react/jsx-runtime").JSX.Element;
29
+ export declare const PrimaryButton: ({ href, newTab, children, className, ...rest }: ButtonProps) => import("react/jsx-runtime").JSX.Element;
30
+ export declare const SecondaryButton: ({ href, newTab, children, className, ...rest }: ButtonProps) => import("react/jsx-runtime").JSX.Element;
31
+ export declare const TertiaryButton: ({ href, newTab, children, className, ...rest }: ButtonProps) => import("react/jsx-runtime").JSX.Element;
25
32
  export declare function renderInline(text: string): (string | JSX.Element)[];
26
33
  export declare function renderRichTextContent(input: string): (import("react/jsx-runtime").JSX.Element | import("react/jsx-runtime").JSX.Element[])[];
@@ -1,5 +1,5 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
- import { parseInline, parseRichText, normalizeRichTextBody, resolveRichTextHeadingLevel } from "@avocadostudio-ai/shared";
2
+ import { linkAttrs, parseInline, parseRichText, normalizeRichTextBody, resolveRichTextHeadingLevel } from "@avocadostudio-ai/shared";
3
3
  export { BlockImage } from "./block-image.js";
4
4
  export { RichTextDocument, renderRichTextDocument } from "./_richtext-document.js";
5
5
  // The grammar itself lives in @avocadostudio-ai/shared so that this renderer,
@@ -76,15 +76,14 @@ export function normalizeSoftHyphenEntities(value, seen) {
76
76
  }
77
77
  return value;
78
78
  }
79
- export function PrimaryButton({ href, children, className, ...rest }) {
80
- return (_jsx("a", { href: href, className: ["btn-primary", className].filter(Boolean).join(" "), ...rest, children: children }));
81
- }
82
- export function SecondaryButton({ href, children, className, ...rest }) {
83
- return (_jsx("a", { href: href, className: ["btn-secondary", className].filter(Boolean).join(" "), ...rest, children: children }));
84
- }
85
- export function TertiaryButton({ href, children, className, ...rest }) {
86
- return (_jsx("a", { href: href, className: ["btn-tertiary", className].filter(Boolean).join(" "), ...rest, children: children }));
79
+ function button(variant) {
80
+ return function Button({ href, newTab, children, className, ...rest }) {
81
+ return (_jsx("a", { ...linkAttrs(href, newTab), className: [variant, className].filter(Boolean).join(" "), ...rest, children: children }));
82
+ };
87
83
  }
84
+ export const PrimaryButton = button("btn-primary");
85
+ export const SecondaryButton = button("btn-secondary");
86
+ export const TertiaryButton = button("btn-tertiary");
88
87
  function renderInlineToken(token) {
89
88
  switch (token.type) {
90
89
  case "strong":
@@ -17,5 +17,5 @@ export function Banner(props) {
17
17
  customStyle.backgroundColor = backgroundColor;
18
18
  if (textColor.length > 0)
19
19
  customStyle.color = textColor;
20
- return (_jsx("section", { className: `banner ${variantClass[variant] ?? variantClass.info}`, style: Object.keys(customStyle).length > 0 ? customStyle : undefined, children: _jsxs("div", { className: "banner__inner section__inner", children: [_jsx("p", { className: "banner__text", "data-editable-target": "text", "data-editable-target-label": "text", "data-editable-label": "text", children: renderInline(text) }), ctaText.length > 0 && ctaHref.length > 0 && (_jsx(PrimaryButton, { href: ctaHref, className: "banner__cta", "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: ctaText }))] }) }));
20
+ return (_jsx("section", { className: `banner ${variantClass[variant] ?? variantClass.info}`, style: Object.keys(customStyle).length > 0 ? customStyle : undefined, children: _jsxs("div", { className: "banner__inner section__inner", children: [_jsx("p", { className: "banner__text", "data-editable-target": "text", "data-editable-target-label": "text", "data-editable-label": "text", children: renderInline(text) }), ctaText.length > 0 && ctaHref.length > 0 && (_jsx(PrimaryButton, { href: ctaHref, newTab: props.ctaNewTab === true, className: "banner__cta", "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: ctaText }))] }) }));
21
21
  }
@@ -7,5 +7,5 @@ export function Card(props) {
7
7
  const variant = String(props.variant ?? "default");
8
8
  const isFullBleed = variant === "full-bleed" && imageUrl.length > 0;
9
9
  const HeadingTag = resolveHeadingTag("Card", props);
10
- return (_jsx("section", { children: _jsx("div", { className: "section__inner", children: _jsxs("article", { className: `card${isFullBleed ? " card--full-bleed" : ""}`, children: [isFullBleed ? (_jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__bg-image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 50vw", loading: "lazy", "data-editable-target": "imageUrl", "data-editable-target-label": "image", "data-editable-label": "image" })) : (imageUrl.length > 0 && (_jsx("div", { className: "card__image-wrap", "data-editable-target": "imageUrl", "data-editable-target-label": "image", children: _jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 50vw", loading: "lazy" }) }))), _jsxs("div", { className: isFullBleed ? "card__overlay-content" : undefined, children: [_jsx(HeadingTag, { "data-editable-target": "title", "data-editable-target-label": "title", "data-editable-label": "title", children: String(props.title ?? "") }), _jsx("p", { "data-editable-target": "description", "data-editable-target-label": "description", "data-editable-label": "description", children: String(props.description ?? "") }), _jsx(PrimaryButton, { href: String(props.ctaHref ?? "#"), "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: String(props.ctaText ?? "") })] })] }) }) }));
10
+ return (_jsx("section", { children: _jsx("div", { className: "section__inner", children: _jsxs("article", { className: `card${isFullBleed ? " card--full-bleed" : ""}`, children: [isFullBleed ? (_jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__bg-image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 50vw", loading: "lazy", "data-editable-target": "imageUrl", "data-editable-target-label": "image", "data-editable-label": "image" })) : (imageUrl.length > 0 && (_jsx("div", { className: "card__image-wrap", "data-editable-target": "imageUrl", "data-editable-target-label": "image", children: _jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 50vw", loading: "lazy" }) }))), _jsxs("div", { className: isFullBleed ? "card__overlay-content" : undefined, children: [_jsx(HeadingTag, { "data-editable-target": "title", "data-editable-target-label": "title", "data-editable-label": "title", children: String(props.title ?? "") }), _jsx("p", { "data-editable-target": "description", "data-editable-target-label": "description", "data-editable-label": "description", children: String(props.description ?? "") }), _jsx(PrimaryButton, { href: String(props.ctaHref ?? "#"), newTab: props.ctaNewTab === true, "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: String(props.ctaText ?? "") })] })] }) }) }));
11
11
  }
@@ -12,6 +12,6 @@ export function CardGrid(props) {
12
12
  const imageUrl = typeof row.imageUrl === "string" ? row.imageUrl.trim() : "";
13
13
  const imageAlt = typeof row.imageAlt === "string" ? row.imageAlt.trim() : "";
14
14
  const isFullBleed = cardVariant === "full-bleed" && imageUrl.length > 0;
15
- return (_jsxs("article", { className: `card${isFullBleed ? " card--full-bleed" : ""}`, "data-editable-target": `cards[${idx}]`, "data-editable-target-label": `cards[${idx}]`, "data-editable-label": `cards[${idx}]`, children: [isFullBleed ? (_jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__bg-image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 33vw", loading: "lazy", "data-editable-target": `cards[${idx}].imageUrl`, "data-editable-target-label": `cards[${idx}].imageUrl`, "data-editable-label": `cards[${idx}].imageUrl` })) : (imageUrl.length > 0 && (_jsx("div", { className: "card__image-wrap", "data-editable-target": `cards[${idx}].imageUrl`, "data-editable-target-label": `cards[${idx}].imageUrl`, "data-editable-label": `cards[${idx}].imageUrl`, children: _jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 33vw", loading: "lazy" }) }))), _jsxs("div", { className: isFullBleed ? "card__overlay-content" : undefined, children: [_jsx(ItemHeadingTag, { "data-editable-target": `cards[${idx}].title`, "data-editable-target-label": `cards[${idx}].title`, "data-editable-label": `cards[${idx}].title`, children: String(row.title ?? "") }), _jsx("p", { "data-editable-target": `cards[${idx}].description`, "data-editable-target-label": `cards[${idx}].description`, "data-editable-label": `cards[${idx}].description`, children: String(row.description ?? "") }), _jsx(PrimaryButton, { href: String(row.ctaHref ?? "#"), "data-editable-target": `cards[${idx}].ctaText`, "data-editable-target-label": `cards[${idx}].ctaText`, "data-editable-label": `cards[${idx}].ctaText`, children: String(row.ctaText ?? "") })] })] }, idx));
15
+ return (_jsxs("article", { className: `card${isFullBleed ? " card--full-bleed" : ""}`, "data-editable-target": `cards[${idx}]`, "data-editable-target-label": `cards[${idx}]`, "data-editable-label": `cards[${idx}]`, children: [isFullBleed ? (_jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__bg-image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 33vw", loading: "lazy", "data-editable-target": `cards[${idx}].imageUrl`, "data-editable-target-label": `cards[${idx}].imageUrl`, "data-editable-label": `cards[${idx}].imageUrl` })) : (imageUrl.length > 0 && (_jsx("div", { className: "card__image-wrap", "data-editable-target": `cards[${idx}].imageUrl`, "data-editable-target-label": `cards[${idx}].imageUrl`, "data-editable-label": `cards[${idx}].imageUrl`, children: _jsx(BlockImage, { src: imageUrl, alt: imageAlt.length > 0 ? imageAlt : "Card image", className: "card__image", width: 768, height: 512, sizes: "(max-width: 768px) 100vw, 33vw", loading: "lazy" }) }))), _jsxs("div", { className: isFullBleed ? "card__overlay-content" : undefined, children: [_jsx(ItemHeadingTag, { "data-editable-target": `cards[${idx}].title`, "data-editable-target-label": `cards[${idx}].title`, "data-editable-label": `cards[${idx}].title`, children: String(row.title ?? "") }), _jsx("p", { "data-editable-target": `cards[${idx}].description`, "data-editable-target-label": `cards[${idx}].description`, "data-editable-label": `cards[${idx}].description`, children: String(row.description ?? "") }), _jsx(PrimaryButton, { href: String(row.ctaHref ?? "#"), newTab: row.ctaNewTab === true, "data-editable-target": `cards[${idx}].ctaText`, "data-editable-target-label": `cards[${idx}].ctaText`, "data-editable-label": `cards[${idx}].ctaText`, children: String(row.ctaText ?? "") })] })] }, idx));
16
16
  }) })] }) }));
17
17
  }
@@ -14,6 +14,6 @@ export function Carousel(props) {
14
14
  const description = String(item.description ?? "");
15
15
  const ctaText = String(item.ctaText ?? "");
16
16
  const ctaHref = String(item.ctaHref ?? "");
17
- return (_jsxs("div", { className: "carousel__slide", children: [imageUrl.length > 0 && (_jsx(BlockImage, { className: "carousel__image", src: imageUrl, alt: imageAlt, width: 1200, height: 600, sizes: "(max-width: 900px) 100vw, 80vw", priority: idx === 0, loading: idx === 0 ? "eager" : "lazy" })), (heading.length > 0 || description.length > 0 || ctaText.length > 0) && (_jsxs("div", { className: "carousel__caption", children: [heading.length > 0 && (_jsx(ItemHeadingTag, { "data-editable-target": `items[${idx}].heading`, "data-editable-target-label": `items[${idx}].heading`, "data-editable-label": `items[${idx}].heading`, children: renderInline(heading) })), description.length > 0 && (_jsx("p", { "data-editable-target": `items[${idx}].description`, "data-editable-target-label": `items[${idx}].description`, "data-editable-label": `items[${idx}].description`, children: renderInline(description) })), ctaText.length > 0 && ctaHref.length > 0 && (_jsx(PrimaryButton, { href: ctaHref, className: "carousel__cta", "data-editable-target": `items[${idx}].ctaText`, "data-editable-target-label": `items[${idx}].ctaText`, "data-editable-label": `items[${idx}].ctaText`, children: ctaText }))] }))] }, idx));
17
+ return (_jsxs("div", { className: "carousel__slide", children: [imageUrl.length > 0 && (_jsx(BlockImage, { className: "carousel__image", src: imageUrl, alt: imageAlt, width: 1200, height: 600, sizes: "(max-width: 900px) 100vw, 80vw", priority: idx === 0, loading: idx === 0 ? "eager" : "lazy" })), (heading.length > 0 || description.length > 0 || ctaText.length > 0) && (_jsxs("div", { className: "carousel__caption", children: [heading.length > 0 && (_jsx(ItemHeadingTag, { "data-editable-target": `items[${idx}].heading`, "data-editable-target-label": `items[${idx}].heading`, "data-editable-label": `items[${idx}].heading`, children: renderInline(heading) })), description.length > 0 && (_jsx("p", { "data-editable-target": `items[${idx}].description`, "data-editable-target-label": `items[${idx}].description`, "data-editable-label": `items[${idx}].description`, children: renderInline(description) })), ctaText.length > 0 && ctaHref.length > 0 && (_jsx(PrimaryButton, { href: ctaHref, newTab: item.ctaNewTab === true, className: "carousel__cta", "data-editable-target": `items[${idx}].ctaText`, "data-editable-target-label": `items[${idx}].ctaText`, "data-editable-label": `items[${idx}].ctaText`, children: ctaText }))] }))] }, idx));
18
18
  }) }), items.length > 1 && (_jsxs(_Fragment, { children: [_jsx("button", { className: "carousel__btn carousel__btn--prev", "aria-label": "Previous slide", type: "button", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "15 18 9 12 15 6" }) }) }), _jsx("button", { className: "carousel__btn carousel__btn--next", "aria-label": "Next slide", type: "button", children: _jsx("svg", { width: "24", height: "24", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: _jsx("polyline", { points: "9 18 15 12 9 6" }) }) }), _jsx("div", { className: "carousel__dots", children: items.map((_, idx) => (_jsx("button", { className: `carousel__dot${idx === 0 ? " carousel__dot--active" : ""}`, "aria-label": `Go to slide ${idx + 1}`, type: "button" }, idx))) })] }))] }) }));
19
19
  }
@@ -3,5 +3,5 @@ import { resolveHeadingTag } from "@avocadostudio-ai/shared";
3
3
  import { PrimaryButton, SecondaryButton } from "../_shared.js";
4
4
  export function CTA(props) {
5
5
  const HeadingTag = resolveHeadingTag("CTA", props);
6
- return (_jsx("section", { className: "cta-section", children: _jsxs("div", { className: "section__inner", children: [_jsx(HeadingTag, { "data-editable-target": "title", "data-editable-target-label": "title", "data-editable-label": "title", children: String(props.title ?? "") }), _jsx("p", { "data-editable-target": "description", "data-editable-target-label": "description", "data-editable-label": "description", children: String(props.description ?? "") }), _jsxs("div", { className: "cta__buttons", children: [_jsx(PrimaryButton, { href: String(props.ctaHref ?? "#"), "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: String(props.ctaText ?? "") }), typeof props.secondaryCtaText === "string" && props.secondaryCtaText.length > 0 && (_jsx(SecondaryButton, { href: String(props.secondaryCtaHref ?? "#"), "data-editable-target": "secondaryCtaText", "data-editable-target-label": "secondaryCtaText", "data-editable-label": "secondaryCtaText", children: props.secondaryCtaText }))] })] }) }));
6
+ return (_jsx("section", { className: "cta-section", children: _jsxs("div", { className: "section__inner", children: [_jsx(HeadingTag, { "data-editable-target": "title", "data-editable-target-label": "title", "data-editable-label": "title", children: String(props.title ?? "") }), _jsx("p", { "data-editable-target": "description", "data-editable-target-label": "description", "data-editable-label": "description", children: String(props.description ?? "") }), _jsxs("div", { className: "cta__buttons", children: [_jsx(PrimaryButton, { href: String(props.ctaHref ?? "#"), newTab: props.ctaNewTab === true, "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: String(props.ctaText ?? "") }), typeof props.secondaryCtaText === "string" && props.secondaryCtaText.length > 0 && (_jsx(SecondaryButton, { href: String(props.secondaryCtaHref ?? "#"), newTab: props.secondaryCtaNewTab === true, "data-editable-target": "secondaryCtaText", "data-editable-target-label": "secondaryCtaText", "data-editable-label": "secondaryCtaText", children: props.secondaryCtaText }))] })] }) }));
7
7
  }
@@ -9,7 +9,7 @@ export function Hero(props) {
9
9
  const eyebrow = typeof props.eyebrow === "string" ? props.eyebrow.trim() : "";
10
10
  const HeadingTag = resolveHeadingTag("Hero", props);
11
11
  const contentCenterClass = textAlign === "center" ? " hero__content--center" : "";
12
- const content = (_jsxs("div", { className: `hero__content layout-grid__col${contentCenterClass}`, children: [eyebrow.length > 0 && (_jsx("span", { className: "hero__eyebrow", "data-editable-target": "eyebrow", "data-editable-target-label": "eyebrow", "data-editable-label": "eyebrow", children: eyebrow })), _jsx(HeadingTag, { "data-editable-target": "heading", "data-editable-target-label": "heading", "data-editable-label": "heading", children: String(props.heading ?? "") }), _jsx("p", { "data-editable-target": "subheading", "data-editable-target-label": "subheading", "data-editable-label": "subheading", children: String(props.subheading ?? "") }), _jsxs("div", { className: "hero__actions", children: [_jsx(PrimaryButton, { href: String(props.ctaHref ?? "#"), "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: String(props.ctaText ?? "") }), typeof props.secondaryCtaText === "string" && props.secondaryCtaText.length > 0 && (_jsx(SecondaryButton, { href: String(props.secondaryCtaHref ?? "#"), "data-editable-target": "secondaryCtaText", "data-editable-target-label": "secondaryCtaText", "data-editable-label": "secondaryCtaText", children: props.secondaryCtaText }))] })] }));
12
+ const content = (_jsxs("div", { className: `hero__content layout-grid__col${contentCenterClass}`, children: [eyebrow.length > 0 && (_jsx("span", { className: "hero__eyebrow", "data-editable-target": "eyebrow", "data-editable-target-label": "eyebrow", "data-editable-label": "eyebrow", children: eyebrow })), _jsx(HeadingTag, { "data-editable-target": "heading", "data-editable-target-label": "heading", "data-editable-label": "heading", children: String(props.heading ?? "") }), _jsx("p", { "data-editable-target": "subheading", "data-editable-target-label": "subheading", "data-editable-label": "subheading", children: String(props.subheading ?? "") }), _jsxs("div", { className: "hero__actions", children: [_jsx(PrimaryButton, { href: String(props.ctaHref ?? "#"), newTab: props.ctaNewTab === true, "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: String(props.ctaText ?? "") }), typeof props.secondaryCtaText === "string" && props.secondaryCtaText.length > 0 && (_jsx(SecondaryButton, { href: String(props.secondaryCtaHref ?? "#"), newTab: props.secondaryCtaNewTab === true, "data-editable-target": "secondaryCtaText", "data-editable-target-label": "secondaryCtaText", "data-editable-label": "secondaryCtaText", children: props.secondaryCtaText }))] })] }));
13
13
  if (isFullWidth) {
14
14
  return (_jsxs("section", { className: "hero hero--full-width", children: [_jsx(BlockImage, { className: "hero__bg-image", src: String(props.imageUrl ?? IMAGE_PLACEHOLDER), alt: String(props.imageAlt ?? "Hero image"), width: 1536, height: 1024, sizes: "100vw", priority: true, "data-editable-target": "imageUrl", "data-editable-target-label": "Hero block image", "data-editable-label": "Hero block image" }), _jsx("div", { className: "section__inner hero__inner", children: content })] }));
15
15
  }
@@ -1,6 +1,7 @@
1
1
  "use client";
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import { useState, useRef, useEffect, useCallback } from "react";
4
+ import { linkAttrs } from "@avocadostudio-ai/shared";
4
5
  import { BlockImage } from "../_shared.js";
5
6
  function ChevronDown({ className }) {
6
7
  return (_jsx("svg", { className: className, width: "14", height: "14", viewBox: "0 0 12 12", fill: "none", "aria-hidden": "true", children: _jsx("path", { d: "M3 4.5L6 7.5L9 4.5", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" }) }));
@@ -60,5 +61,5 @@ export function SiteHeader(props) {
60
61
  return clean === activePath;
61
62
  };
62
63
  const hasActiveChild = (link) => link.children?.some((c) => isActive(c.href)) ?? false;
63
- return (_jsxs(_Fragment, { children: [_jsx("header", { className: "site-top-nav", "data-block-chrome": "true", children: _jsxs("div", { className: "site-top-nav-inner", children: [_jsxs("a", { className: "site-brand", href: links[0]?.href ?? "/", "data-editable-target": "siteName", children: [logoUrl ? _jsx(BlockImage, { className: "site-logo", src: logoUrl, alt: `${siteName} logo`, width: 38, height: 38, "data-editable-target": "logoUrl" }) : null, _jsx("span", { className: "site-brand-text", children: siteName })] }), _jsx("nav", { className: "site-nav-links site-nav-links-desktop", "aria-label": "Primary", children: links.map((link, i) => link.children?.length ? (_jsxs("div", { className: "site-nav-dropdown", children: [_jsxs("button", { type: "button", className: `site-nav-dropdown-trigger${hasActiveChild(link) ? " is-active" : ""}`, "data-editable-target": `links[${i}].label`, "data-editable-target-label": `links[${i}].label`, children: [link.label, _jsx(ChevronDown, { className: "site-nav-chevron" })] }), _jsx("div", { className: "site-nav-dropdown-menu", children: link.children.map((child, j) => (_jsx("a", { href: child.href ?? "#", className: isActive(child.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].children[${j}].label`, "data-editable-target-label": `links[${i}].children[${j}].label`, onClick: (e) => e.currentTarget.blur(), children: child.label }, child.href))) })] }, `group-${i}`)) : (_jsx("a", { href: link.href ?? "#", className: isActive(link.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].label`, "data-editable-target-label": `links[${i}].label`, children: link.label }, link.href))) }), _jsxs("div", { ref: menuRef, className: `site-mobile-menu${isOpen ? " is-open" : ""}`, children: [_jsx("button", { ref: toggleRef, type: "button", className: "site-mobile-menu-button", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": "Toggle navigation menu", onClick: toggle, children: _jsxs("span", { className: "burger-icon", "aria-hidden": "true", children: [_jsx("i", {}), _jsx("i", {}), _jsx("i", {})] }) }), isOpen ? (_jsx("nav", { id: menuId, className: "site-nav-links site-nav-links-mobile", "aria-label": "Mobile primary", children: links.map((link, i) => link.children?.length ? (_jsxs("div", { className: "site-nav-mobile-group", children: [_jsxs("button", { type: "button", className: `site-nav-mobile-group-trigger${hasActiveChild(link) ? " is-active" : ""}`, "aria-expanded": expandedGroup === i, onClick: () => setExpandedGroup(expandedGroup === i ? null : i), "data-editable-target": `links[${i}].label`, children: [link.label, _jsx(ChevronDown, { className: `site-nav-chevron${expandedGroup === i ? " is-expanded" : ""}` })] }), expandedGroup === i ? (_jsx("div", { className: "site-nav-mobile-group-children", children: link.children.map((child, j) => (_jsx("a", { href: child.href ?? "#", className: isActive(child.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].children[${j}].label`, onClick: close, children: child.label }, `mobile-${child.href}`))) })) : null] }, `mobile-group-${i}`)) : (_jsx("a", { href: link.href ?? "#", className: isActive(link.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].label`, onClick: close, children: link.label }, `mobile-${link.href}`))) })) : null] })] }) }), isOpen ? (_jsx("div", { className: "site-mobile-backdrop", onClick: close })) : null] }));
64
+ return (_jsxs(_Fragment, { children: [_jsx("header", { className: "site-top-nav", "data-block-chrome": "true", children: _jsxs("div", { className: "site-top-nav-inner", children: [_jsxs("a", { className: "site-brand", href: links[0]?.href ?? "/", "data-editable-target": "siteName", children: [logoUrl ? _jsx(BlockImage, { className: "site-logo", src: logoUrl, alt: `${siteName} logo`, width: 38, height: 38, "data-editable-target": "logoUrl" }) : null, _jsx("span", { className: "site-brand-text", children: siteName })] }), _jsx("nav", { className: "site-nav-links site-nav-links-desktop", "aria-label": "Primary", children: links.map((link, i) => link.children?.length ? (_jsxs("div", { className: "site-nav-dropdown", children: [_jsxs("button", { type: "button", className: `site-nav-dropdown-trigger${hasActiveChild(link) ? " is-active" : ""}`, "data-editable-target": `links[${i}].label`, "data-editable-target-label": `links[${i}].label`, children: [link.label, _jsx(ChevronDown, { className: "site-nav-chevron" })] }), _jsx("div", { className: "site-nav-dropdown-menu", children: link.children.map((child, j) => (_jsx("a", { ...linkAttrs(child.href, child.newTab), className: isActive(child.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].children[${j}].label`, "data-editable-target-label": `links[${i}].children[${j}].label`, onClick: (e) => e.currentTarget.blur(), children: child.label }, child.href))) })] }, `group-${i}`)) : (_jsx("a", { ...linkAttrs(link.href, link.newTab), className: isActive(link.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].label`, "data-editable-target-label": `links[${i}].label`, children: link.label }, link.href))) }), _jsxs("div", { ref: menuRef, className: `site-mobile-menu${isOpen ? " is-open" : ""}`, children: [_jsx("button", { ref: toggleRef, type: "button", className: "site-mobile-menu-button", "aria-expanded": isOpen, "aria-controls": menuId, "aria-label": "Toggle navigation menu", onClick: toggle, children: _jsxs("span", { className: "burger-icon", "aria-hidden": "true", children: [_jsx("i", {}), _jsx("i", {}), _jsx("i", {})] }) }), isOpen ? (_jsx("nav", { id: menuId, className: "site-nav-links site-nav-links-mobile", "aria-label": "Mobile primary", children: links.map((link, i) => link.children?.length ? (_jsxs("div", { className: "site-nav-mobile-group", children: [_jsxs("button", { type: "button", className: `site-nav-mobile-group-trigger${hasActiveChild(link) ? " is-active" : ""}`, "aria-expanded": expandedGroup === i, onClick: () => setExpandedGroup(expandedGroup === i ? null : i), "data-editable-target": `links[${i}].label`, children: [link.label, _jsx(ChevronDown, { className: `site-nav-chevron${expandedGroup === i ? " is-expanded" : ""}` })] }), expandedGroup === i ? (_jsx("div", { className: "site-nav-mobile-group-children", children: link.children.map((child, j) => (_jsx("a", { ...linkAttrs(child.href, child.newTab), className: isActive(child.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].children[${j}].label`, onClick: close, children: child.label }, `mobile-${child.href}`))) })) : null] }, `mobile-group-${i}`)) : (_jsx("a", { ...linkAttrs(link.href, link.newTab), className: isActive(link.href) ? "is-active" : undefined, "data-editable-target": `links[${i}].label`, onClick: close, children: link.label }, `mobile-${link.href}`))) })) : null] })] }) }), isOpen ? (_jsx("div", { className: "site-mobile-backdrop", onClick: close })) : null] }));
64
65
  }
@@ -15,7 +15,7 @@ function TwoColumnChild({ item, headingTag, pathPrefix }) {
15
15
  const label = String(item.label ?? "");
16
16
  if (!label)
17
17
  return null;
18
- return (_jsx("div", { className: "two-column__cta", children: _jsx(PrimaryButton, { href: String(item.href ?? "#"), "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: label }) }));
18
+ return (_jsx("div", { className: "two-column__cta", children: _jsx(PrimaryButton, { href: String(item.href ?? "#"), newTab: item.newTab === true, "data-editable-target": "ctaText", "data-editable-target-label": "ctaText", "data-editable-label": "ctaText", children: label }) }));
19
19
  }
20
20
  if (childType === "video") {
21
21
  const src = String(item.src ?? "");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@avocadostudio-ai/blocks",
3
- "version": "0.3.1",
3
+ "version": "0.3.3",
4
4
  "type": "module",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -26,8 +26,8 @@
26
26
  "dist"
27
27
  ],
28
28
  "dependencies": {
29
- "@avocadostudio-ai/richtext": "^0.3.1",
30
- "@avocadostudio-ai/shared": "^0.3.1"
29
+ "@avocadostudio-ai/shared": "^0.3.3",
30
+ "@avocadostudio-ai/richtext": "^0.3.3"
31
31
  },
32
32
  "peerDependencies": {
33
33
  "next": ">=15.0.0",