@brandlab-digital/site-next 3.12.0 → 3.13.0

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.
Files changed (61) hide show
  1. package/README.md +53 -0
  2. package/dist/estate-segment.d.ts +48 -0
  3. package/dist/estate-segment.d.ts.map +1 -0
  4. package/dist/estate-segment.js +54 -0
  5. package/dist/estate-segment.js.map +1 -0
  6. package/dist/google-business-reviews-revalidate.d.ts +61 -0
  7. package/dist/google-business-reviews-revalidate.d.ts.map +1 -0
  8. package/dist/google-business-reviews-revalidate.js +151 -0
  9. package/dist/google-business-reviews-revalidate.js.map +1 -0
  10. package/dist/google-business-reviews-server.d.ts +21 -2
  11. package/dist/google-business-reviews-server.d.ts.map +1 -1
  12. package/dist/google-business-reviews-server.js +21 -4
  13. package/dist/google-business-reviews-server.js.map +1 -1
  14. package/dist/headers.d.ts.map +1 -1
  15. package/dist/headers.js +6 -0
  16. package/dist/headers.js.map +1 -1
  17. package/dist/image-runtime.js +3 -14
  18. package/dist/image-runtime.js.map +1 -1
  19. package/dist/next-sharp.d.ts +14 -0
  20. package/dist/next-sharp.d.ts.map +1 -0
  21. package/dist/next-sharp.js +39 -0
  22. package/dist/next-sharp.js.map +1 -0
  23. package/dist/robots.d.ts +26 -4
  24. package/dist/robots.d.ts.map +1 -1
  25. package/dist/robots.js +49 -2
  26. package/dist/robots.js.map +1 -1
  27. package/dist/ui-kit/prefetch.d.ts +50 -0
  28. package/dist/ui-kit/prefetch.d.ts.map +1 -0
  29. package/dist/ui-kit/prefetch.js +50 -0
  30. package/dist/ui-kit/prefetch.js.map +1 -0
  31. package/dist/ui-kit/primitives/index.d.ts +1 -0
  32. package/dist/ui-kit/primitives/index.d.ts.map +1 -1
  33. package/dist/ui-kit/primitives/index.js +1 -0
  34. package/dist/ui-kit/primitives/index.js.map +1 -1
  35. package/dist/ui-kit/primitives/links.d.ts +13 -2
  36. package/dist/ui-kit/primitives/links.d.ts.map +1 -1
  37. package/dist/ui-kit/primitives/links.js +7 -6
  38. package/dist/ui-kit/primitives/links.js.map +1 -1
  39. package/dist/ui-kit/primitives/quote-button.d.ts +4 -1
  40. package/dist/ui-kit/primitives/quote-button.d.ts.map +1 -1
  41. package/dist/ui-kit/primitives/quote-button.js +3 -2
  42. package/dist/ui-kit/primitives/quote-button.js.map +1 -1
  43. package/dist/ui-kit/sections/site-footer.d.ts.map +1 -1
  44. package/dist/ui-kit/sections/site-footer.js +5 -2
  45. package/dist/ui-kit/sections/site-footer.js.map +1 -1
  46. package/dist/ui-kit/shell/current-link.d.ts +15 -1
  47. package/dist/ui-kit/shell/current-link.d.ts.map +1 -1
  48. package/dist/ui-kit/shell/current-link.js +10 -1
  49. package/dist/ui-kit/shell/current-link.js.map +1 -1
  50. package/dist/ui-kit/shell/index.d.ts +1 -0
  51. package/dist/ui-kit/shell/index.d.ts.map +1 -1
  52. package/dist/ui-kit/shell/index.js +1 -0
  53. package/dist/ui-kit/shell/index.js.map +1 -1
  54. package/dist/ui-kit/shell/intent-prefetch.d.ts +4 -0
  55. package/dist/ui-kit/shell/intent-prefetch.d.ts.map +1 -0
  56. package/dist/ui-kit/shell/intent-prefetch.js +61 -0
  57. package/dist/ui-kit/shell/intent-prefetch.js.map +1 -0
  58. package/dist/ui-kit/shell/site-header.d.ts.map +1 -1
  59. package/dist/ui-kit/shell/site-header.js +2 -3
  60. package/dist/ui-kit/shell/site-header.js.map +1 -1
  61. package/package.json +6 -2
@@ -6,25 +6,26 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
6
6
  */
7
7
  import Link from 'next/link';
8
8
  import { Icon } from '../icons.js';
9
+ import { linkPrefetchProps } from '../prefetch.js';
9
10
  import { slot } from '../skin.js';
10
11
  function isExternal(href) {
11
12
  return /^https?:\/\//i.test(href);
12
13
  }
13
- function Anchor({ href, external, hooks, children }) {
14
+ function Anchor({ href, external, prefetch, hooks, children, }) {
14
15
  if (external ?? isExternal(href)) {
15
16
  return (_jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", ...hooks, children: children }));
16
17
  }
17
- return (_jsx(Link, { href: href, ...hooks, children: children }));
18
+ return (_jsx(Link, { href: href, ...linkPrefetchProps(prefetch), ...hooks, children: children }));
18
19
  }
19
20
  export const BUTTON_VARIANTS = ['primary', 'secondary', 'quiet'];
20
21
  /** A link styled as a button. A primary action is at least 44 px tall (structure.css). */
21
- export function ButtonLink({ href, children, icon, iconPosition = 'end', external, variant = 'primary', layout, classes }) {
22
+ export function ButtonLink({ href, children, icon, iconPosition = 'end', external, prefetch, variant = 'primary', layout, classes }) {
22
23
  const iconNode = icon ? _jsx("span", { ...slot(classes, 'icon'), children: _jsx(Icon, { name: icon }) }) : null;
23
- return (_jsxs(Anchor, { href: href, external: external, hooks: { 'data-bl': 'button', 'data-variant': variant, 'data-size': layout?.size ?? 'regular', className: classes?.root }, children: [iconPosition === 'start' ? iconNode : null, _jsx("span", { ...slot(classes, 'label'), children: children }), iconPosition === 'end' ? iconNode : null] }));
24
+ return (_jsxs(Anchor, { href: href, external: external, prefetch: prefetch, hooks: { 'data-bl': 'button', 'data-variant': variant, 'data-size': layout?.size ?? 'regular', className: classes?.root }, children: [iconPosition === 'start' ? iconNode : null, _jsx("span", { ...slot(classes, 'label'), children: children }), iconPosition === 'end' ? iconNode : null] }));
24
25
  }
25
26
  /** An inline or standalone text link. */
26
- export function TextLink({ href, children, external, variant = 'inline', classes }) {
27
- return (_jsx(Anchor, { href: href, external: external, hooks: { 'data-bl': 'text-link', 'data-variant': variant, className: classes?.root }, children: children }));
27
+ export function TextLink({ href, children, external, prefetch, variant = 'inline', classes }) {
28
+ return (_jsx(Anchor, { href: href, external: external, prefetch: prefetch, hooks: { 'data-bl': 'text-link', 'data-variant': variant, className: classes?.root }, children: children }));
28
29
  }
29
30
  /**
30
31
  * A `tel:` link. Its accessible name is its visible text, which always includes the number (WCAG 2.5.3). Use it for
@@ -1 +1 @@
1
- {"version":3,"file":"links.js","sourceRoot":"","sources":["../../../src/ui-kit/primitives/links.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * Link primitives: `ButtonLink`, `TextLink` and `PhoneLink`. Server components; every link is a real `<a href>`.\n * External links open in a new tab with `rel=\"noopener noreferrer\"`. `PhoneLink` requires a typed placement, which the\n * shared instrumentation reads to send one `phone_link_click` per tap; nothing here emits events itself.\n */\nimport Link from 'next/link'\nimport type { ReactNode } from 'react'\nimport type { PhoneCallPlacement } from '../../analytics.js'\nimport { Icon, type UiIconName } from '../icons.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { UiPhone } from '../types.js'\n\nfunction isExternal(href: string) {\n return /^https?:\\/\\//i.test(href)\n}\n\n/** Data hooks and the skin class for an anchor's root. */\ntype AnchorHooks = { readonly className: string | undefined } & Readonly<Record<`data-${string}`, string | undefined>>\n\nfunction Anchor({ href, external, hooks, children }: { href: string; external?: boolean | undefined; hooks: AnchorHooks; children: ReactNode }) {\n if (external ?? isExternal(href)) {\n return (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" {...hooks}>\n {children}\n </a>\n )\n }\n return (\n <Link href={href} {...hooks}>\n {children}\n </Link>\n )\n}\n\nexport type ButtonLinkSlot = 'root' | 'label' | 'icon'\nexport const BUTTON_VARIANTS = ['primary', 'secondary', 'quiet'] as const\nexport type ButtonVariant = (typeof BUTTON_VARIANTS)[number]\nexport type ButtonLinkSkin = SkinEntry<ButtonLinkSlot, ButtonVariant, { size?: 'regular' | 'large' }>\n\nexport interface ButtonLinkProps extends ButtonLinkSkin {\n readonly href: string\n readonly children: ReactNode\n /** An icon after the label (`arrow`) or before it (`phone`). */\n readonly icon?: UiIconName\n readonly iconPosition?: 'start' | 'end'\n /** Force external handling; by default `http(s)://` links are external. */\n readonly external?: boolean\n}\n\n/** A link styled as a button. A primary action is at least 44 px tall (structure.css). */\nexport function ButtonLink({ href, children, icon, iconPosition = 'end', external, variant = 'primary', layout, classes }: ButtonLinkProps) {\n const iconNode = icon ? <span {...slot(classes, 'icon')}><Icon name={icon} /></span> : null\n return (\n <Anchor\n href={href}\n external={external}\n hooks={{ 'data-bl': 'button', 'data-variant': variant, 'data-size': layout?.size ?? 'regular', className: classes?.root }}\n >\n {iconPosition === 'start' ? iconNode : null}\n <span {...slot(classes, 'label')}>{children}</span>\n {iconPosition === 'end' ? iconNode : null}\n </Anchor>\n )\n}\n\nexport type TextLinkSlot = 'root'\nexport type TextLinkSkin = SkinEntry<TextLinkSlot, 'inline' | 'standalone'>\n\nexport interface TextLinkProps extends TextLinkSkin {\n readonly href: string\n readonly children: ReactNode\n readonly external?: boolean\n}\n\n/** An inline or standalone text link. */\nexport function TextLink({ href, children, external, variant = 'inline', classes }: TextLinkProps) {\n return (\n <Anchor href={href} external={external} hooks={{ 'data-bl': 'text-link', 'data-variant': variant, className: classes?.root }}>\n {children}\n </Anchor>\n )\n}\n\nexport type PhoneLinkSlot = 'root' | 'icon' | 'label' | 'number'\nexport type PhoneLinkSkin = SkinEntry<PhoneLinkSlot, 'text' | 'button'>\n\nexport interface PhoneLinkProps extends PhoneLinkSkin {\n readonly phone: UiPhone\n /** Where the link sits, for `phone_link_click`. Required: a section sets its own. */\n readonly placement: PhoneCallPlacement\n /** Optional words before the number, for example \"Call\". The accessible name is always the visible text. */\n readonly label?: string\n /** The phone icon on the left (header and hero). */\n readonly showIcon?: boolean\n}\n\n/**\n * A `tel:` link. Its accessible name is its visible text, which always includes the number (WCAG 2.5.3). Use it for\n * every call link: a literal `tel:` anywhere else fails lint (K1) and C10 checks the href against the evidence file.\n */\nexport function PhoneLink({ phone, placement, label, showIcon = false, variant = 'text', classes }: PhoneLinkProps) {\n return (\n <a href={phone.telHref} data-bl=\"phone-link\" data-variant={variant} data-phone-location={placement} className={classes?.root}>\n {showIcon ? (\n <span {...slot(classes, 'icon')}>\n <Icon name=\"phone\" />\n </span>\n ) : null}\n {label ? (\n <>\n <span {...slot(classes, 'label')}>{label}</span>{' '}\n </>\n ) : null}\n <span {...slot(classes, 'number')}>{phone.display}</span>\n </a>\n )\n}\n"]}
1
+ {"version":3,"file":"links.js","sourceRoot":"","sources":["../../../src/ui-kit/primitives/links.tsx"],"names":[],"mappings":";AAAA;;;;GAIG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAG5B,OAAO,EAAE,IAAI,EAAmB,MAAM,aAAa,CAAA;AACnD,OAAO,EAAE,iBAAiB,EAAqB,MAAM,gBAAgB,CAAA;AACrE,OAAO,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAA;AAGjD,SAAS,UAAU,CAAC,IAAY;IAC9B,OAAO,eAAe,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACnC,CAAC;AAKD,SAAS,MAAM,CAAC,EACd,IAAI,EACJ,QAAQ,EACR,QAAQ,EACR,KAAK,EACL,QAAQ,GAOT;IACC,IAAI,QAAQ,IAAI,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACjC,OAAO,CACL,YAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,KAAK,KAAK,YAC/D,QAAQ,GACP,CACL,CAAA;IACH,CAAC;IACD,OAAO,CACL,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,KAAM,iBAAiB,CAAC,QAAQ,CAAC,KAAM,KAAK,YACzD,QAAQ,GACJ,CACR,CAAA;AACH,CAAC;AAGD,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,OAAO,CAAU,CAAA;AAmBzE,0FAA0F;AAC1F,MAAM,UAAU,UAAU,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,YAAY,GAAG,KAAK,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,EAAmB;IAClJ,MAAM,QAAQ,GAAG,IAAI,CAAC,CAAC,CAAC,kBAAU,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,YAAE,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,GAAI,GAAO,CAAC,CAAC,CAAC,IAAI,CAAA;IAC3F,OAAO,CACL,MAAC,MAAM,IACL,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,QAAQ,EAClB,KAAK,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,cAAc,EAAE,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,IAAI,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,aAExH,YAAY,KAAK,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,EAC3C,kBAAU,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAAG,QAAQ,GAAQ,EAClD,YAAY,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,IAClC,CACV,CAAA;AACH,CAAC;AAgBD,yCAAyC;AACzC,MAAM,UAAU,QAAQ,CAAC,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,OAAO,GAAG,QAAQ,EAAE,OAAO,EAAiB;IACzG,OAAO,CACL,KAAC,MAAM,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,SAAS,EAAE,WAAW,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,EAAE,YAC7I,QAAQ,GACF,CACV,CAAA;AACH,CAAC;AAeD;;;GAGG;AACH,MAAM,UAAU,SAAS,CAAC,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,GAAG,KAAK,EAAE,OAAO,GAAG,MAAM,EAAE,OAAO,EAAkB;IAChH,OAAO,CACL,aAAG,IAAI,EAAE,KAAK,CAAC,OAAO,aAAU,YAAY,kBAAe,OAAO,yBAAuB,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,IAAI,aACzH,QAAQ,CAAC,CAAC,CAAC,CACV,kBAAU,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,YAC7B,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,GAAG,GAChB,CACR,CAAC,CAAC,CAAC,IAAI,EACP,KAAK,CAAC,CAAC,CAAC,CACP,8BACE,kBAAU,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAAG,KAAK,GAAQ,EAAC,GAAG,IACnD,CACJ,CAAC,CAAC,CAAC,IAAI,EACR,kBAAU,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAG,KAAK,CAAC,OAAO,GAAQ,IACvD,CACL,CAAA;AACH,CAAC","sourcesContent":["/**\n * Link primitives: `ButtonLink`, `TextLink` and `PhoneLink`. Server components; every link is a real `<a href>`.\n * External links open in a new tab with `rel=\"noopener noreferrer\"`. `PhoneLink` requires a typed placement, which the\n * shared instrumentation reads to send one `phone_link_click` per tap; nothing here emits events itself.\n */\nimport Link from 'next/link'\nimport type { ReactNode } from 'react'\nimport type { PhoneCallPlacement } from '../../analytics.js'\nimport { Icon, type UiIconName } from '../icons.js'\nimport { linkPrefetchProps, type LinkPrefetch } from '../prefetch.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { UiPhone } from '../types.js'\n\nfunction isExternal(href: string) {\n return /^https?:\\/\\//i.test(href)\n}\n\n/** Data hooks and the skin class for an anchor's root. */\ntype AnchorHooks = { readonly className: string | undefined } & Readonly<Record<`data-${string}`, string | undefined>>\n\nfunction Anchor({\n href,\n external,\n prefetch,\n hooks,\n children,\n}: {\n href: string\n external?: boolean | undefined\n prefetch?: LinkPrefetch | undefined\n hooks: AnchorHooks\n children: ReactNode\n}) {\n if (external ?? isExternal(href)) {\n return (\n <a href={href} target=\"_blank\" rel=\"noopener noreferrer\" {...hooks}>\n {children}\n </a>\n )\n }\n return (\n <Link href={href} {...linkPrefetchProps(prefetch)} {...hooks}>\n {children}\n </Link>\n )\n}\n\nexport type ButtonLinkSlot = 'root' | 'label' | 'icon'\nexport const BUTTON_VARIANTS = ['primary', 'secondary', 'quiet'] as const\nexport type ButtonVariant = (typeof BUTTON_VARIANTS)[number]\nexport type ButtonLinkSkin = SkinEntry<ButtonLinkSlot, ButtonVariant, { size?: 'regular' | 'large' }>\n\nexport interface ButtonLinkProps extends ButtonLinkSkin {\n readonly href: string\n readonly children: ReactNode\n /** An icon after the label (`arrow`) or before it (`phone`). */\n readonly icon?: UiIconName\n readonly iconPosition?: 'start' | 'end'\n /** Force external handling; by default `http(s)://` links are external. */\n readonly external?: boolean\n /**\n * Prefetch by link role (`LINK_PREFETCH_POLICY`): `auto` (the default, Next's prefetch in view) for a main action,\n * `intent` for an in-content card link, `false` for footer, area, nearby, map and finder links.\n */\n readonly prefetch?: LinkPrefetch\n}\n\n/** A link styled as a button. A primary action is at least 44 px tall (structure.css). */\nexport function ButtonLink({ href, children, icon, iconPosition = 'end', external, prefetch, variant = 'primary', layout, classes }: ButtonLinkProps) {\n const iconNode = icon ? <span {...slot(classes, 'icon')}><Icon name={icon} /></span> : null\n return (\n <Anchor\n href={href}\n external={external}\n prefetch={prefetch}\n hooks={{ 'data-bl': 'button', 'data-variant': variant, 'data-size': layout?.size ?? 'regular', className: classes?.root }}\n >\n {iconPosition === 'start' ? iconNode : null}\n <span {...slot(classes, 'label')}>{children}</span>\n {iconPosition === 'end' ? iconNode : null}\n </Anchor>\n )\n}\n\nexport type TextLinkSlot = 'root'\nexport type TextLinkSkin = SkinEntry<TextLinkSlot, 'inline' | 'standalone'>\n\nexport interface TextLinkProps extends TextLinkSkin {\n readonly href: string\n readonly children: ReactNode\n readonly external?: boolean\n /**\n * Prefetch by link role (`LINK_PREFETCH_POLICY`): `auto` (the default, Next's prefetch in view) for a main action,\n * `intent` for an in-content card link, `false` for footer, area, nearby, map and finder links.\n */\n readonly prefetch?: LinkPrefetch\n}\n\n/** An inline or standalone text link. */\nexport function TextLink({ href, children, external, prefetch, variant = 'inline', classes }: TextLinkProps) {\n return (\n <Anchor href={href} external={external} prefetch={prefetch} hooks={{ 'data-bl': 'text-link', 'data-variant': variant, className: classes?.root }}>\n {children}\n </Anchor>\n )\n}\n\nexport type PhoneLinkSlot = 'root' | 'icon' | 'label' | 'number'\nexport type PhoneLinkSkin = SkinEntry<PhoneLinkSlot, 'text' | 'button'>\n\nexport interface PhoneLinkProps extends PhoneLinkSkin {\n readonly phone: UiPhone\n /** Where the link sits, for `phone_link_click`. Required: a section sets its own. */\n readonly placement: PhoneCallPlacement\n /** Optional words before the number, for example \"Call\". The accessible name is always the visible text. */\n readonly label?: string\n /** The phone icon on the left (header and hero). */\n readonly showIcon?: boolean\n}\n\n/**\n * A `tel:` link. Its accessible name is its visible text, which always includes the number (WCAG 2.5.3). Use it for\n * every call link: a literal `tel:` anywhere else fails lint (K1) and C10 checks the href against the evidence file.\n */\nexport function PhoneLink({ phone, placement, label, showIcon = false, variant = 'text', classes }: PhoneLinkProps) {\n return (\n <a href={phone.telHref} data-bl=\"phone-link\" data-variant={variant} data-phone-location={placement} className={classes?.root}>\n {showIcon ? (\n <span {...slot(classes, 'icon')}>\n <Icon name=\"phone\" />\n </span>\n ) : null}\n {label ? (\n <>\n <span {...slot(classes, 'label')}>{label}</span>{' '}\n </>\n ) : null}\n <span {...slot(classes, 'number')}>{phone.display}</span>\n </a>\n )\n}\n"]}
@@ -1,4 +1,5 @@
1
1
  import type { LeadCtaPlacement } from '../../analytics.js';
2
+ import { type LinkPrefetch } from '../prefetch.js';
2
3
  import { type SkinEntry } from '../skin.js';
3
4
  import type { ButtonVariant } from './links.js';
4
5
  export type QuoteButtonSlot = 'root' | 'label' | 'icon';
@@ -15,6 +16,8 @@ export interface QuoteButtonProps extends QuoteButtonSkin {
15
16
  readonly placement: LeadCtaPlacement;
16
17
  /** A stable id for `lead_cta_click`, for example `quote-header` or `quote-cta`. */
17
18
  readonly ctaId: string;
19
+ /** `auto` by default: the main quote action keeps Next's prefetch (`LINK_PREFETCH_POLICY.primaryAction`). */
20
+ readonly prefetch?: LinkPrefetch;
18
21
  }
19
- export declare function QuoteButton({ label, href, placement, ctaId, variant, layout, classes }: QuoteButtonProps): import("react/jsx-runtime").JSX.Element;
22
+ export declare function QuoteButton({ label, href, placement, ctaId, prefetch, variant, layout, classes }: QuoteButtonProps): import("react/jsx-runtime").JSX.Element;
20
23
  //# sourceMappingURL=quote-button.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"quote-button.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/primitives/quote-button.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE1D,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;AACvD,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,eAAe,EAAE,aAAa,EAAE;IAAE,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAEvH,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,yGAAyG;IACzG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;IACpC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAmB,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,gBAAgB,2CAmBpH"}
1
+ {"version":3,"file":"quote-button.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/primitives/quote-button.tsx"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAA;AAE1D,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,gBAAgB,CAAA;AACrE,OAAO,EAAQ,KAAK,SAAS,EAAE,MAAM,YAAY,CAAA;AACjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAA;AAE/C,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,OAAO,GAAG,MAAM,CAAA;AACvD,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,eAAe,EAAE,aAAa,EAAE;IAAE,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC;IAAC,IAAI,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAA;AAEvH,MAAM,WAAW,gBAAiB,SAAQ,eAAe;IACvD,yGAAyG;IACzG,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,uFAAuF;IACvF,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,mDAAmD;IACnD,QAAQ,CAAC,SAAS,EAAE,gBAAgB,CAAA;IACpC,mFAAmF;IACnF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,6GAA6G;IAC7G,QAAQ,CAAC,QAAQ,CAAC,EAAE,YAAY,CAAA;CACjC;AAED,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAmB,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,gBAAgB,2CAoB9H"}
@@ -8,8 +8,9 @@ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
8
8
  */
9
9
  import Link from 'next/link';
10
10
  import { Icon } from '../icons.js';
11
+ import { linkPrefetchProps } from '../prefetch.js';
11
12
  import { slot } from '../skin.js';
12
- export function QuoteButton({ label, href, placement, ctaId, variant = 'primary', layout, classes }) {
13
- return (_jsxs(Link, { href: href, "data-bl": "quote-button", "data-variant": variant, "data-size": layout?.size ?? 'regular', "data-bl-cta": ctaId, "data-bl-cta-placement": placement, className: classes?.root, children: [_jsx("span", { ...slot(classes, 'label'), children: label }), layout?.icon === false ? null : (_jsx("span", { ...slot(classes, 'icon'), children: _jsx(Icon, { name: "arrow" }) }))] }));
13
+ export function QuoteButton({ label, href, placement, ctaId, prefetch, variant = 'primary', layout, classes }) {
14
+ return (_jsxs(Link, { href: href, ...linkPrefetchProps(prefetch), "data-bl": "quote-button", "data-variant": variant, "data-size": layout?.size ?? 'regular', "data-bl-cta": ctaId, "data-bl-cta-placement": placement, className: classes?.root, children: [_jsx("span", { ...slot(classes, 'label'), children: label }), layout?.icon === false ? null : (_jsx("span", { ...slot(classes, 'icon'), children: _jsx(Icon, { name: "arrow" }) }))] }));
14
15
  }
15
16
  //# sourceMappingURL=quote-button.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"quote-button.js","sourceRoot":"","sources":["../../../src/ui-kit/primitives/quote-button.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAA;AAiBjD,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,EAAoB;IACnH,OAAO,CACL,MAAC,IAAI,IACH,IAAI,EAAE,IAAI,aACF,cAAc,kBACR,OAAO,eACV,MAAM,EAAE,IAAI,IAAI,SAAS,iBACvB,KAAK,2BACK,SAAS,EAChC,SAAS,EAAE,OAAO,EAAE,IAAI,aAExB,kBAAU,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAAG,KAAK,GAAQ,EAC/C,MAAM,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC/B,kBAAU,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,YAC7B,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,GAAG,GAChB,CACR,IACI,CACR,CAAA;AACH,CAAC","sourcesContent":["/**\n * `QuoteButton`: the quote action. A server-rendered link to the page's quote form (for example `/contact#quote`), so\n * it works before scripts run. When a `QuoteDialog` is on the page (3.10.0) it opens the dialog instead; on the\n * contact page the link scrolls to the form. It carries the `data-bl-cta` hooks only: from 3.9.0 the shared\n * instrumentation reads them and sends `lead_cta_click` when lead diagnostics are on. Nothing is sent in 3.8.0, and\n * nothing here emits events itself.\n */\nimport Link from 'next/link'\nimport type { LeadCtaPlacement } from '../../analytics.js'\nimport { Icon } from '../icons.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { ButtonVariant } from './links.js'\n\nexport type QuoteButtonSlot = 'root' | 'label' | 'icon'\nexport type QuoteButtonSkin = SkinEntry<QuoteButtonSlot, ButtonVariant, { size?: 'regular' | 'large'; icon?: boolean }>\n\nexport interface QuoteButtonProps extends QuoteButtonSkin {\n /** The site's recorded quote label, or one from the closed list (C5), for example \"Get a free quote\". */\n readonly label: string\n /** The quote form this falls back to without scripts, for example `/contact#quote`. */\n readonly href: string\n /** Where the button sits, for `lead_cta_click`. */\n readonly placement: LeadCtaPlacement\n /** A stable id for `lead_cta_click`, for example `quote-header` or `quote-cta`. */\n readonly ctaId: string\n}\n\nexport function QuoteButton({ label, href, placement, ctaId, variant = 'primary', layout, classes }: QuoteButtonProps) {\n return (\n <Link\n href={href}\n data-bl=\"quote-button\"\n data-variant={variant}\n data-size={layout?.size ?? 'regular'}\n data-bl-cta={ctaId}\n data-bl-cta-placement={placement}\n className={classes?.root}\n >\n <span {...slot(classes, 'label')}>{label}</span>\n {layout?.icon === false ? null : (\n <span {...slot(classes, 'icon')}>\n <Icon name=\"arrow\" />\n </span>\n )}\n </Link>\n )\n}\n"]}
1
+ {"version":3,"file":"quote-button.js","sourceRoot":"","sources":["../../../src/ui-kit/primitives/quote-button.tsx"],"names":[],"mappings":";AAAA;;;;;;GAMG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAE5B,OAAO,EAAE,IAAI,EAAE,MAAM,aAAa,CAAA;AAClC,OAAO,EAAE,iBAAiB,EAAqB,MAAM,gBAAgB,CAAA;AACrE,OAAO,EAAE,IAAI,EAAkB,MAAM,YAAY,CAAA;AAmBjD,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,GAAG,SAAS,EAAE,MAAM,EAAE,OAAO,EAAoB;IAC7H,OAAO,CACL,MAAC,IAAI,IACH,IAAI,EAAE,IAAI,KACN,iBAAiB,CAAC,QAAQ,CAAC,aACvB,cAAc,kBACR,OAAO,eACV,MAAM,EAAE,IAAI,IAAI,SAAS,iBACvB,KAAK,2BACK,SAAS,EAChC,SAAS,EAAE,OAAO,EAAE,IAAI,aAExB,kBAAU,IAAI,CAAC,OAAO,EAAE,OAAO,CAAC,YAAG,KAAK,GAAQ,EAC/C,MAAM,EAAE,IAAI,KAAK,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC/B,kBAAU,IAAI,CAAC,OAAO,EAAE,MAAM,CAAC,YAC7B,KAAC,IAAI,IAAC,IAAI,EAAC,OAAO,GAAG,GAChB,CACR,IACI,CACR,CAAA;AACH,CAAC","sourcesContent":["/**\n * `QuoteButton`: the quote action. A server-rendered link to the page's quote form (for example `/contact#quote`), so\n * it works before scripts run. When a `QuoteDialog` is on the page (3.10.0) it opens the dialog instead; on the\n * contact page the link scrolls to the form. It carries the `data-bl-cta` hooks only: from 3.9.0 the shared\n * instrumentation reads them and sends `lead_cta_click` when lead diagnostics are on. Nothing is sent in 3.8.0, and\n * nothing here emits events itself.\n */\nimport Link from 'next/link'\nimport type { LeadCtaPlacement } from '../../analytics.js'\nimport { Icon } from '../icons.js'\nimport { linkPrefetchProps, type LinkPrefetch } from '../prefetch.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { ButtonVariant } from './links.js'\n\nexport type QuoteButtonSlot = 'root' | 'label' | 'icon'\nexport type QuoteButtonSkin = SkinEntry<QuoteButtonSlot, ButtonVariant, { size?: 'regular' | 'large'; icon?: boolean }>\n\nexport interface QuoteButtonProps extends QuoteButtonSkin {\n /** The site's recorded quote label, or one from the closed list (C5), for example \"Get a free quote\". */\n readonly label: string\n /** The quote form this falls back to without scripts, for example `/contact#quote`. */\n readonly href: string\n /** Where the button sits, for `lead_cta_click`. */\n readonly placement: LeadCtaPlacement\n /** A stable id for `lead_cta_click`, for example `quote-header` or `quote-cta`. */\n readonly ctaId: string\n /** `auto` by default: the main quote action keeps Next's prefetch (`LINK_PREFETCH_POLICY.primaryAction`). */\n readonly prefetch?: LinkPrefetch\n}\n\nexport function QuoteButton({ label, href, placement, ctaId, prefetch, variant = 'primary', layout, classes }: QuoteButtonProps) {\n return (\n <Link\n href={href}\n {...linkPrefetchProps(prefetch)}\n data-bl=\"quote-button\"\n data-variant={variant}\n data-size={layout?.size ?? 'regular'}\n data-bl-cta={ctaId}\n data-bl-cta-placement={placement}\n className={classes?.root}\n >\n <span {...slot(classes, 'label')}>{label}</span>\n {layout?.icon === false ? null : (\n <span {...slot(classes, 'icon')}>\n <Icon name=\"arrow\" />\n </span>\n )}\n </Link>\n )\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"site-footer.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/site-footer.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"site-footer.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/sections/site-footer.tsx"],"names":[],"mappings":"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"}
@@ -11,6 +11,9 @@ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-run
11
11
  *
12
12
  * Variants: `columns`; `photo`, with the site's backdrop image for the panel in `media` (decorative, `aria-hidden`),
13
13
  * for example Superior's sunlit water. Signature art goes in `decoration`.
14
+ *
15
+ * Prefetch is off on every internal footer link and the logo (`LINK_PREFETCH_POLICY.footer`): the footer comes into
16
+ * view on every full scroll, and visitors rarely follow its links.
14
17
  */
15
18
  import Link from 'next/link';
16
19
  import { Icon, SocialIcon } from '../icons.js';
@@ -23,14 +26,14 @@ function isExternal(href) {
23
26
  return /^https?:\/\//i.test(href);
24
27
  }
25
28
  function FooterLink({ link, hooks }) {
26
- return isExternal(link.href) ? (_jsx("a", { href: link.href, ...hooks, target: "_blank", rel: "noopener noreferrer", children: link.label })) : (_jsx(Link, { href: link.href, ...hooks, children: link.label }));
29
+ return isExternal(link.href) ? (_jsx("a", { href: link.href, ...hooks, target: "_blank", rel: "noopener noreferrer", children: link.label })) : (_jsx(Link, { href: link.href, prefetch: false, ...hooks, children: link.label }));
27
30
  }
28
31
  function currentYear() {
29
32
  return Number(new Intl.DateTimeFormat('en-AU', { year: 'numeric', timeZone: 'Australia/Sydney' }).format(new Date()));
30
33
  }
31
34
  export function SiteFooter({ brandName, homeHref = '/', logo, description, licences = [], socials = [], phone, phoneLabel, email, address, columns, legal, media, decoration, idPrefix = 'bl-footer', variant = 'columns', classes, }) {
32
35
  const policies = [legal.privacy, legal.terms].filter((link) => !!link);
33
- return (_jsxs("footer", { "data-bl": "footer", "data-variant": variant, className: classes?.root, children: [decoration ? (_jsx("div", { "data-slot": "decoration", "aria-hidden": "true", children: decoration })) : null, _jsxs("div", { ...slot(classes, 'panel'), children: [variant === 'photo' && media ? (_jsx("div", { ...slot(classes, 'media'), "aria-hidden": "true", children: media })) : null, _jsxs("div", { ...slot(classes, 'inner'), children: [_jsxs("div", { ...slot(classes, 'brand'), children: [_jsx(Link, { href: homeHref, ...slot(classes, 'logo'), "aria-label": brandName, children: logo }), _jsx("p", { ...slot(classes, 'description'), children: description }), licences.length > 0 ? (_jsx("ul", { ...slot(classes, 'licences'), children: licences.map((licence) => (_jsx("li", { children: licence.href ? (_jsx("a", { ...slot(classes, 'licenceLink'), href: licence.href, target: "_blank", rel: "noopener noreferrer", children: licence.text })) : (licence.text) }, licence.text))) })) : null, socials.length > 0 ? (_jsx("ul", { ...slot(classes, 'social'), children: socials.map((social) => (_jsx("li", { children: _jsx("a", { ...slot(classes, 'socialLink'), href: social.href, "aria-label": social.label, target: "_blank", rel: "noopener noreferrer", children: _jsx(SocialIcon, { kind: social.kind }) }) }, social.href))) })) : null, _jsxs("div", { ...slot(classes, 'contact'), children: [_jsx(PhoneLink, { phone: phone, placement: "footer", label: phoneLabel, classes: { root: classes?.phone, label: classes?.phoneLabel, number: classes?.phoneNumber } }), email ? (_jsx("a", { ...slot(classes, 'email'), href: `mailto:${email}`, children: email })) : null, address ? _jsx("p", { ...slot(classes, 'address'), children: address }) : null] })] }), _jsx(SiteFooterColumns, { className: classes?.columns, children: COLUMN_KEYS.map((key) => {
36
+ return (_jsxs("footer", { "data-bl": "footer", "data-variant": variant, className: classes?.root, children: [decoration ? (_jsx("div", { "data-slot": "decoration", "aria-hidden": "true", children: decoration })) : null, _jsxs("div", { ...slot(classes, 'panel'), children: [variant === 'photo' && media ? (_jsx("div", { ...slot(classes, 'media'), "aria-hidden": "true", children: media })) : null, _jsxs("div", { ...slot(classes, 'inner'), children: [_jsxs("div", { ...slot(classes, 'brand'), children: [_jsx(Link, { href: homeHref, prefetch: false, ...slot(classes, 'logo'), "aria-label": brandName, children: logo }), _jsx("p", { ...slot(classes, 'description'), children: description }), licences.length > 0 ? (_jsx("ul", { ...slot(classes, 'licences'), children: licences.map((licence) => (_jsx("li", { children: licence.href ? (_jsx("a", { ...slot(classes, 'licenceLink'), href: licence.href, target: "_blank", rel: "noopener noreferrer", children: licence.text })) : (licence.text) }, licence.text))) })) : null, socials.length > 0 ? (_jsx("ul", { ...slot(classes, 'social'), children: socials.map((social) => (_jsx("li", { children: _jsx("a", { ...slot(classes, 'socialLink'), href: social.href, "aria-label": social.label, target: "_blank", rel: "noopener noreferrer", children: _jsx(SocialIcon, { kind: social.kind }) }) }, social.href))) })) : null, _jsxs("div", { ...slot(classes, 'contact'), children: [_jsx(PhoneLink, { phone: phone, placement: "footer", label: phoneLabel, classes: { root: classes?.phone, label: classes?.phoneLabel, number: classes?.phoneNumber } }), email ? (_jsx("a", { ...slot(classes, 'email'), href: `mailto:${email}`, children: email })) : null, address ? _jsx("p", { ...slot(classes, 'address'), children: address }) : null] })] }), _jsx(SiteFooterColumns, { className: classes?.columns, children: COLUMN_KEYS.map((key) => {
34
37
  const column = columns[key];
35
38
  if (!column || column.links.length === 0)
36
39
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"site-footer.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/site-footer.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * S27 `SiteFooter`: the v1 §6 footer, structured the same on every site. Server component; one small client island\n * (`SiteFooterColumns`) turns the columns into a phone accordion.\n *\n * Column 1: the logo, a short description, one line per licence (with its register link when given), social and\n * Business Profile icons, then the phone (`phone_link_click` placement `footer`), the email and the address only when\n * it is public. Then Services, Areas and Company, each under a real H2, in that order. A bottom bar: © year name ·\n * ABN · the privacy and terms links. Never a quote button, \"based in\", opening hours, a guides column or a \"back to\n * top\" text link: the props have no place for them.\n *\n * Variants: `columns`; `photo`, with the site's backdrop image for the panel in `media` (decorative, `aria-hidden`),\n * for example Superior's sunlit water. Signature art goes in `decoration`.\n */\nimport Link from 'next/link'\nimport type { ReactNode } from 'react'\nimport { Icon, SocialIcon } from '../icons.js'\nimport { PhoneLink } from '../primitives/links.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { UiLink, UiPhone, UiSocial } from '../types.js'\nimport { SiteFooterColumns } from './site-footer-columns.js'\n\nexport const SITE_FOOTER_VARIANTS = ['columns', 'photo'] as const\nexport type SiteFooterVariant = (typeof SITE_FOOTER_VARIANTS)[number]\n\nexport type SiteFooterSlot =\n | 'root'\n | 'panel'\n | 'media'\n | 'inner'\n | 'brand'\n | 'logo'\n | 'description'\n | 'licences'\n | 'licenceLink'\n | 'social'\n | 'socialLink'\n | 'contact'\n | 'phone'\n | 'phoneLabel'\n | 'phoneNumber'\n | 'email'\n | 'address'\n | 'columns'\n | 'column'\n | 'heading'\n | 'toggle'\n | 'list'\n | 'link'\n | 'bottom'\n | 'bottomInner'\n | 'legal'\n | 'policies'\n | 'policyLink'\n\nexport type SiteFooterSkin = SkinEntry<SiteFooterSlot, SiteFooterVariant>\n\n/** One licence line: the text as the register shows it, and the register link when there is one. */\nexport interface SiteFooterLicence {\n readonly text: string\n readonly href?: string\n}\n\nexport interface SiteFooterColumn {\n /** The H2 text, for example \"Services\". */\n readonly heading: string\n readonly links: readonly UiLink[]\n}\n\nexport interface SiteFooterProps extends SiteFooterSkin {\n /** The logo link's accessible name. */\n readonly brandName: string\n readonly homeHref?: string\n /** The site's logo node (decorative inside the named link). */\n readonly logo: ReactNode\n /** Two or three lines about the business. */\n readonly description: string\n readonly licences?: readonly SiteFooterLicence[]\n readonly socials?: readonly UiSocial[]\n readonly phone: UiPhone\n /** Optional words before the number, for example \"Call us\". */\n readonly phoneLabel?: string\n readonly email?: string\n /** Only when the business shows its address publicly. */\n readonly address?: string\n /** Services, Areas and Company, rendered in that order; leave one out when the site has nothing true for it. */\n readonly columns: {\n readonly services?: SiteFooterColumn\n readonly areas?: SiteFooterColumn\n readonly company?: SiteFooterColumn\n }\n readonly legal: {\n /** The legal or trading name. */\n readonly name: string\n readonly abn?: string\n /** Defaults to the current year in Sydney. */\n readonly year?: number\n /** The privacy policy link, labelled by the site. */\n readonly privacy?: UiLink\n /** The terms link, labelled by the site. */\n readonly terms?: UiLink\n }\n /** The `photo` variant's backdrop image for the panel (decorative). */\n readonly media?: ReactNode\n /** Signature art, rendered `aria-hidden`. */\n readonly decoration?: ReactNode\n /** Prefix for the column list ids (default `bl-footer`). */\n readonly idPrefix?: string\n}\n\nconst COLUMN_KEYS = ['services', 'areas', 'company'] as const\n\nfunction isExternal(href: string) {\n return /^https?:\\/\\//i.test(href)\n}\n\nfunction FooterLink({ link, hooks }: { link: UiLink; hooks?: { 'data-slot': string; className: string | undefined } }) {\n return isExternal(link.href) ? (\n <a href={link.href} {...hooks} target=\"_blank\" rel=\"noopener noreferrer\">\n {link.label}\n </a>\n ) : (\n <Link href={link.href} {...hooks}>\n {link.label}\n </Link>\n )\n}\n\nfunction currentYear() {\n return Number(new Intl.DateTimeFormat('en-AU', { year: 'numeric', timeZone: 'Australia/Sydney' }).format(new Date()))\n}\n\nexport function SiteFooter({\n brandName,\n homeHref = '/',\n logo,\n description,\n licences = [],\n socials = [],\n phone,\n phoneLabel,\n email,\n address,\n columns,\n legal,\n media,\n decoration,\n idPrefix = 'bl-footer',\n variant = 'columns',\n classes,\n}: SiteFooterProps) {\n const policies = [legal.privacy, legal.terms].filter((link): link is UiLink => !!link)\n return (\n <footer data-bl=\"footer\" data-variant={variant} className={classes?.root}>\n {decoration ? (\n <div data-slot=\"decoration\" aria-hidden=\"true\">\n {decoration}\n </div>\n ) : null}\n <div {...slot(classes, 'panel')}>\n {variant === 'photo' && media ? (\n <div {...slot(classes, 'media')} aria-hidden=\"true\">\n {media}\n </div>\n ) : null}\n <div {...slot(classes, 'inner')}>\n <div {...slot(classes, 'brand')}>\n <Link href={homeHref} {...slot(classes, 'logo')} aria-label={brandName}>\n {logo}\n </Link>\n <p {...slot(classes, 'description')}>{description}</p>\n {licences.length > 0 ? (\n <ul {...slot(classes, 'licences')}>\n {licences.map((licence) => (\n <li key={licence.text}>\n {licence.href ? (\n <a {...slot(classes, 'licenceLink')} href={licence.href} target=\"_blank\" rel=\"noopener noreferrer\">\n {licence.text}\n </a>\n ) : (\n licence.text\n )}\n </li>\n ))}\n </ul>\n ) : null}\n {socials.length > 0 ? (\n <ul {...slot(classes, 'social')}>\n {socials.map((social) => (\n <li key={social.href}>\n <a {...slot(classes, 'socialLink')} href={social.href} aria-label={social.label} target=\"_blank\" rel=\"noopener noreferrer\">\n <SocialIcon kind={social.kind} />\n </a>\n </li>\n ))}\n </ul>\n ) : null}\n <div {...slot(classes, 'contact')}>\n <PhoneLink phone={phone} placement=\"footer\" label={phoneLabel} classes={{ root: classes?.phone, label: classes?.phoneLabel, number: classes?.phoneNumber }} />\n {email ? (\n <a {...slot(classes, 'email')} href={`mailto:${email}`}>\n {email}\n </a>\n ) : null}\n {address ? <p {...slot(classes, 'address')}>{address}</p> : null}\n </div>\n </div>\n <SiteFooterColumns className={classes?.columns}>\n {COLUMN_KEYS.map((key) => {\n const column = columns[key]\n if (!column || column.links.length === 0) return null\n const listId = `${idPrefix}-${key}`\n return (\n <div key={key} {...slot(classes, 'column')} data-column={key}>\n <h2 {...slot(classes, 'heading')}>\n <span data-slot=\"headingText\">{column.heading}</span>\n <button type=\"button\" {...slot(classes, 'toggle')} aria-expanded=\"false\" aria-controls={listId} hidden>\n <span>{column.heading}</span>\n <Icon name=\"chevron\" />\n </button>\n </h2>\n <ul id={listId} {...slot(classes, 'list')}>\n {column.links.map((link) => (\n <li key={link.href}>\n <FooterLink link={link} hooks={slot(classes, 'link')} />\n </li>\n ))}\n </ul>\n </div>\n )\n })}\n </SiteFooterColumns>\n </div>\n </div>\n <div {...slot(classes, 'bottom')}>\n <div {...slot(classes, 'bottomInner')}>\n <p {...slot(classes, 'legal')}>\n © {legal.year ?? currentYear()} {legal.name}\n {legal.abn ? (\n <>\n <span aria-hidden=\"true\"> · </span>\n <span>ABN {legal.abn}</span>\n </>\n ) : null}\n </p>\n {policies.length > 0 ? (\n <ul {...slot(classes, 'policies')}>\n {policies.map((link) => (\n <li key={link.href}>\n <FooterLink link={link} hooks={slot(classes, 'policyLink')} />\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n </div>\n </footer>\n )\n}\n"]}
1
+ {"version":3,"file":"site-footer.js","sourceRoot":"","sources":["../../../src/ui-kit/sections/site-footer.tsx"],"names":[],"mappings":"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","sourcesContent":["/**\n * S27 `SiteFooter`: the v1 §6 footer, structured the same on every site. Server component; one small client island\n * (`SiteFooterColumns`) turns the columns into a phone accordion.\n *\n * Column 1: the logo, a short description, one line per licence (with its register link when given), social and\n * Business Profile icons, then the phone (`phone_link_click` placement `footer`), the email and the address only when\n * it is public. Then Services, Areas and Company, each under a real H2, in that order. A bottom bar: © year name ·\n * ABN · the privacy and terms links. Never a quote button, \"based in\", opening hours, a guides column or a \"back to\n * top\" text link: the props have no place for them.\n *\n * Variants: `columns`; `photo`, with the site's backdrop image for the panel in `media` (decorative, `aria-hidden`),\n * for example Superior's sunlit water. Signature art goes in `decoration`.\n *\n * Prefetch is off on every internal footer link and the logo (`LINK_PREFETCH_POLICY.footer`): the footer comes into\n * view on every full scroll, and visitors rarely follow its links.\n */\nimport Link from 'next/link'\nimport type { ReactNode } from 'react'\nimport { Icon, SocialIcon } from '../icons.js'\nimport { PhoneLink } from '../primitives/links.js'\nimport { slot, type SkinEntry } from '../skin.js'\nimport type { UiLink, UiPhone, UiSocial } from '../types.js'\nimport { SiteFooterColumns } from './site-footer-columns.js'\n\nexport const SITE_FOOTER_VARIANTS = ['columns', 'photo'] as const\nexport type SiteFooterVariant = (typeof SITE_FOOTER_VARIANTS)[number]\n\nexport type SiteFooterSlot =\n | 'root'\n | 'panel'\n | 'media'\n | 'inner'\n | 'brand'\n | 'logo'\n | 'description'\n | 'licences'\n | 'licenceLink'\n | 'social'\n | 'socialLink'\n | 'contact'\n | 'phone'\n | 'phoneLabel'\n | 'phoneNumber'\n | 'email'\n | 'address'\n | 'columns'\n | 'column'\n | 'heading'\n | 'toggle'\n | 'list'\n | 'link'\n | 'bottom'\n | 'bottomInner'\n | 'legal'\n | 'policies'\n | 'policyLink'\n\nexport type SiteFooterSkin = SkinEntry<SiteFooterSlot, SiteFooterVariant>\n\n/** One licence line: the text as the register shows it, and the register link when there is one. */\nexport interface SiteFooterLicence {\n readonly text: string\n readonly href?: string\n}\n\nexport interface SiteFooterColumn {\n /** The H2 text, for example \"Services\". */\n readonly heading: string\n readonly links: readonly UiLink[]\n}\n\nexport interface SiteFooterProps extends SiteFooterSkin {\n /** The logo link's accessible name. */\n readonly brandName: string\n readonly homeHref?: string\n /** The site's logo node (decorative inside the named link). */\n readonly logo: ReactNode\n /** Two or three lines about the business. */\n readonly description: string\n readonly licences?: readonly SiteFooterLicence[]\n readonly socials?: readonly UiSocial[]\n readonly phone: UiPhone\n /** Optional words before the number, for example \"Call us\". */\n readonly phoneLabel?: string\n readonly email?: string\n /** Only when the business shows its address publicly. */\n readonly address?: string\n /** Services, Areas and Company, rendered in that order; leave one out when the site has nothing true for it. */\n readonly columns: {\n readonly services?: SiteFooterColumn\n readonly areas?: SiteFooterColumn\n readonly company?: SiteFooterColumn\n }\n readonly legal: {\n /** The legal or trading name. */\n readonly name: string\n readonly abn?: string\n /** Defaults to the current year in Sydney. */\n readonly year?: number\n /** The privacy policy link, labelled by the site. */\n readonly privacy?: UiLink\n /** The terms link, labelled by the site. */\n readonly terms?: UiLink\n }\n /** The `photo` variant's backdrop image for the panel (decorative). */\n readonly media?: ReactNode\n /** Signature art, rendered `aria-hidden`. */\n readonly decoration?: ReactNode\n /** Prefix for the column list ids (default `bl-footer`). */\n readonly idPrefix?: string\n}\n\nconst COLUMN_KEYS = ['services', 'areas', 'company'] as const\n\nfunction isExternal(href: string) {\n return /^https?:\\/\\//i.test(href)\n}\n\nfunction FooterLink({ link, hooks }: { link: UiLink; hooks?: { 'data-slot': string; className: string | undefined } }) {\n return isExternal(link.href) ? (\n <a href={link.href} {...hooks} target=\"_blank\" rel=\"noopener noreferrer\">\n {link.label}\n </a>\n ) : (\n <Link href={link.href} prefetch={false} {...hooks}>\n {link.label}\n </Link>\n )\n}\n\nfunction currentYear() {\n return Number(new Intl.DateTimeFormat('en-AU', { year: 'numeric', timeZone: 'Australia/Sydney' }).format(new Date()))\n}\n\nexport function SiteFooter({\n brandName,\n homeHref = '/',\n logo,\n description,\n licences = [],\n socials = [],\n phone,\n phoneLabel,\n email,\n address,\n columns,\n legal,\n media,\n decoration,\n idPrefix = 'bl-footer',\n variant = 'columns',\n classes,\n}: SiteFooterProps) {\n const policies = [legal.privacy, legal.terms].filter((link): link is UiLink => !!link)\n return (\n <footer data-bl=\"footer\" data-variant={variant} className={classes?.root}>\n {decoration ? (\n <div data-slot=\"decoration\" aria-hidden=\"true\">\n {decoration}\n </div>\n ) : null}\n <div {...slot(classes, 'panel')}>\n {variant === 'photo' && media ? (\n <div {...slot(classes, 'media')} aria-hidden=\"true\">\n {media}\n </div>\n ) : null}\n <div {...slot(classes, 'inner')}>\n <div {...slot(classes, 'brand')}>\n <Link href={homeHref} prefetch={false} {...slot(classes, 'logo')} aria-label={brandName}>\n {logo}\n </Link>\n <p {...slot(classes, 'description')}>{description}</p>\n {licences.length > 0 ? (\n <ul {...slot(classes, 'licences')}>\n {licences.map((licence) => (\n <li key={licence.text}>\n {licence.href ? (\n <a {...slot(classes, 'licenceLink')} href={licence.href} target=\"_blank\" rel=\"noopener noreferrer\">\n {licence.text}\n </a>\n ) : (\n licence.text\n )}\n </li>\n ))}\n </ul>\n ) : null}\n {socials.length > 0 ? (\n <ul {...slot(classes, 'social')}>\n {socials.map((social) => (\n <li key={social.href}>\n <a {...slot(classes, 'socialLink')} href={social.href} aria-label={social.label} target=\"_blank\" rel=\"noopener noreferrer\">\n <SocialIcon kind={social.kind} />\n </a>\n </li>\n ))}\n </ul>\n ) : null}\n <div {...slot(classes, 'contact')}>\n <PhoneLink phone={phone} placement=\"footer\" label={phoneLabel} classes={{ root: classes?.phone, label: classes?.phoneLabel, number: classes?.phoneNumber }} />\n {email ? (\n <a {...slot(classes, 'email')} href={`mailto:${email}`}>\n {email}\n </a>\n ) : null}\n {address ? <p {...slot(classes, 'address')}>{address}</p> : null}\n </div>\n </div>\n <SiteFooterColumns className={classes?.columns}>\n {COLUMN_KEYS.map((key) => {\n const column = columns[key]\n if (!column || column.links.length === 0) return null\n const listId = `${idPrefix}-${key}`\n return (\n <div key={key} {...slot(classes, 'column')} data-column={key}>\n <h2 {...slot(classes, 'heading')}>\n <span data-slot=\"headingText\">{column.heading}</span>\n <button type=\"button\" {...slot(classes, 'toggle')} aria-expanded=\"false\" aria-controls={listId} hidden>\n <span>{column.heading}</span>\n <Icon name=\"chevron\" />\n </button>\n </h2>\n <ul id={listId} {...slot(classes, 'list')}>\n {column.links.map((link) => (\n <li key={link.href}>\n <FooterLink link={link} hooks={slot(classes, 'link')} />\n </li>\n ))}\n </ul>\n </div>\n )\n })}\n </SiteFooterColumns>\n </div>\n </div>\n <div {...slot(classes, 'bottom')}>\n <div {...slot(classes, 'bottomInner')}>\n <p {...slot(classes, 'legal')}>\n © {legal.year ?? currentYear()} {legal.name}\n {legal.abn ? (\n <>\n <span aria-hidden=\"true\"> · </span>\n <span>ABN {legal.abn}</span>\n </>\n ) : null}\n </p>\n {policies.length > 0 ? (\n <ul {...slot(classes, 'policies')}>\n {policies.map((link) => (\n <li key={link.href}>\n <FooterLink link={link} hooks={slot(classes, 'policyLink')} />\n </li>\n ))}\n </ul>\n ) : null}\n </div>\n </div>\n </footer>\n )\n}\n"]}
@@ -7,9 +7,23 @@ export declare function CurrentLink({ href, slot, hub, prefetch, className, chil
7
7
  readonly href: string;
8
8
  readonly slot: string;
9
9
  readonly hub?: boolean;
10
- /** False for links in panels and the drawer: hidden panels count as in view and would prefetch every menu page. */
10
+ /**
11
+ * False for links in panels and the drawer: hidden panels count as in view and would prefetch every menu page. The
12
+ * current page is never prefetched, whatever this says.
13
+ */
11
14
  readonly prefetch?: boolean | undefined;
12
15
  readonly className?: string | undefined;
13
16
  readonly children: ReactNode;
14
17
  }): import("react/jsx-runtime").JSX.Element;
18
+ /**
19
+ * The header logo's home link: prefetch stays Next's default except on the home page itself, which is never
20
+ * prefetched. No `aria-current`: the logo is named by the brand, not as a menu item.
21
+ */
22
+ export declare function LogoLink({ href, label, slot, className, children, }: {
23
+ readonly href: string;
24
+ readonly label: string;
25
+ readonly slot: string;
26
+ readonly className?: string | undefined;
27
+ readonly children: ReactNode;
28
+ }): import("react/jsx-runtime").JSX.Element;
15
29
  //# sourceMappingURL=current-link.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"current-link.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/current-link.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAOtC,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,WAG3D;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,WAO1E;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAI,EACJ,GAAW,EACX,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB,mHAAmH;IACnH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC7B,2CAcA"}
1
+ {"version":3,"file":"current-link.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/current-link.tsx"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAOtC,8EAA8E;AAC9E,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,WAG3D;AAED,4FAA4F;AAC5F,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,WAO1E;AAED,wBAAgB,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAI,EACJ,GAAW,EACX,QAAQ,EACR,SAAS,EACT,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;IACtB;;;OAGG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC7B,2CAeA;AAED;;;GAGG;AACH,wBAAgB,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,SAAS,EACT,QAAQ,GACT,EAAE;IACD,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACvC,QAAQ,CAAC,QAAQ,EAAE,SAAS,CAAA;CAC7B,2CAOA"}
@@ -29,6 +29,15 @@ export function isCurrentSection(pathname, paths) {
29
29
  }
30
30
  export function CurrentLink({ href, slot, hub = false, prefetch, className, children, }) {
31
31
  const pathname = usePathname();
32
- return (_jsx(Link, { href: href, prefetch: prefetch, "data-slot": slot, "data-hub": hub ? 'true' : undefined, "aria-current": isCurrentPage(pathname, href) ? 'page' : undefined, className: className, children: children }));
32
+ const current = isCurrentPage(pathname, href);
33
+ return (_jsx(Link, { href: href, prefetch: current ? false : prefetch, "data-slot": slot, "data-hub": hub ? 'true' : undefined, "aria-current": current ? 'page' : undefined, className: className, children: children }));
34
+ }
35
+ /**
36
+ * The header logo's home link: prefetch stays Next's default except on the home page itself, which is never
37
+ * prefetched. No `aria-current`: the logo is named by the brand, not as a menu item.
38
+ */
39
+ export function LogoLink({ href, label, slot, className, children, }) {
40
+ const pathname = usePathname();
41
+ return (_jsx(Link, { href: href, prefetch: isCurrentPage(pathname, href) ? false : undefined, "aria-label": label, "data-slot": slot, className: className, children: children }));
33
42
  }
34
43
  //# sourceMappingURL=current-link.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"current-link.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/current-link.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG7C,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAA;AACxC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,IAAY;IAC1D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAChE,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAC,IAAI,CAAC,CAAA;AACxD,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,KAAwB;IACzE,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QAChE,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;QACnC,OAAO,OAAO,KAAK,OAAO,IAAI,CAAC,OAAO,KAAK,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAA;IACtF,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAI,EACJ,GAAG,GAAG,KAAK,EACX,QAAQ,EACR,SAAS,EACT,QAAQ,GAST;IACC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,OAAO,CACL,KAAC,IAAI,IACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,QAAQ,eACP,IAAI,cACL,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,kBACpB,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAChE,SAAS,EAAE,SAAS,YAEnB,QAAQ,GACJ,CACR,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\n/**\n * A menu link that marks itself `aria-current=\"page\"` on its own page. A client leaf only because the root layout\n * can't read the route: it receives one href and its server-rendered label, and renders in the server HTML with the\n * right state.\n */\nimport Link from 'next/link'\nimport { usePathname } from 'next/navigation'\nimport type { ReactNode } from 'react'\n\nfunction normalisePath(path: string) {\n const bare = path.split(/[?#]/, 1)[0] ?? ''\n return bare.replace(/\\/+$/, '') || '/'\n}\n\n/** True when `href` is the current page. External links are never current. */\nexport function isCurrentPage(pathname: string, href: string) {\n if (!href.startsWith('/') || href.startsWith('//')) return false\n return normalisePath(pathname) === normalisePath(href)\n}\n\n/** True when the page is one of `paths` or below it (the home path matches only itself). */\nexport function isCurrentSection(pathname: string, paths: readonly string[]) {\n const current = normalisePath(pathname)\n return paths.some((path) => {\n if (!path.startsWith('/') || path.startsWith('//')) return false\n const section = normalisePath(path)\n return current === section || (section !== '/' && current.startsWith(`${section}/`))\n })\n}\n\nexport function CurrentLink({\n href,\n slot,\n hub = false,\n prefetch,\n className,\n children,\n}: {\n readonly href: string\n readonly slot: string\n readonly hub?: boolean\n /** False for links in panels and the drawer: hidden panels count as in view and would prefetch every menu page. */\n readonly prefetch?: boolean | undefined\n readonly className?: string | undefined\n readonly children: ReactNode\n}) {\n const pathname = usePathname()\n return (\n <Link\n href={href}\n prefetch={prefetch}\n data-slot={slot}\n data-hub={hub ? 'true' : undefined}\n aria-current={isCurrentPage(pathname, href) ? 'page' : undefined}\n className={className}\n >\n {children}\n </Link>\n )\n}\n"]}
1
+ {"version":3,"file":"current-link.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/current-link.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;;AAEZ;;;;GAIG;AACH,OAAO,IAAI,MAAM,WAAW,CAAA;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAG7C,SAAS,aAAa,CAAC,IAAY;IACjC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAA;AACxC,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa,CAAC,QAAgB,EAAE,IAAY;IAC1D,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAA;IAChE,OAAO,aAAa,CAAC,QAAQ,CAAC,KAAK,aAAa,CAAC,IAAI,CAAC,CAAA;AACxD,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB,CAAC,QAAgB,EAAE,KAAwB;IACzE,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAA;IACvC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;QACzB,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;YAAE,OAAO,KAAK,CAAA;QAChE,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,CAAA;QACnC,OAAO,OAAO,KAAK,OAAO,IAAI,CAAC,OAAO,KAAK,GAAG,IAAI,OAAO,CAAC,UAAU,CAAC,GAAG,OAAO,GAAG,CAAC,CAAC,CAAA;IACtF,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,EAC1B,IAAI,EACJ,IAAI,EACJ,GAAG,GAAG,KAAK,EACX,QAAQ,EACR,SAAS,EACT,QAAQ,GAYT;IACC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,MAAM,OAAO,GAAG,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;IAC7C,OAAO,CACL,KAAC,IAAI,IACH,IAAI,EAAE,IAAI,EACV,QAAQ,EAAE,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,eACzB,IAAI,cACL,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,kBACpB,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,EAC1C,SAAS,EAAE,SAAS,YAEnB,QAAQ,GACJ,CACR,CAAA;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,QAAQ,CAAC,EACvB,IAAI,EACJ,KAAK,EACL,IAAI,EACJ,SAAS,EACT,QAAQ,GAOT;IACC,MAAM,QAAQ,GAAG,WAAW,EAAE,CAAA;IAC9B,OAAO,CACL,KAAC,IAAI,IAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,EAAE,aAAa,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,gBAAc,KAAK,eAAa,IAAI,EAAE,SAAS,EAAE,SAAS,YACpI,QAAQ,GACJ,CACR,CAAA;AACH,CAAC","sourcesContent":["'use client'\n\n/**\n * A menu link that marks itself `aria-current=\"page\"` on its own page. A client leaf only because the root layout\n * can't read the route: it receives one href and its server-rendered label, and renders in the server HTML with the\n * right state.\n */\nimport Link from 'next/link'\nimport { usePathname } from 'next/navigation'\nimport type { ReactNode } from 'react'\n\nfunction normalisePath(path: string) {\n const bare = path.split(/[?#]/, 1)[0] ?? ''\n return bare.replace(/\\/+$/, '') || '/'\n}\n\n/** True when `href` is the current page. External links are never current. */\nexport function isCurrentPage(pathname: string, href: string) {\n if (!href.startsWith('/') || href.startsWith('//')) return false\n return normalisePath(pathname) === normalisePath(href)\n}\n\n/** True when the page is one of `paths` or below it (the home path matches only itself). */\nexport function isCurrentSection(pathname: string, paths: readonly string[]) {\n const current = normalisePath(pathname)\n return paths.some((path) => {\n if (!path.startsWith('/') || path.startsWith('//')) return false\n const section = normalisePath(path)\n return current === section || (section !== '/' && current.startsWith(`${section}/`))\n })\n}\n\nexport function CurrentLink({\n href,\n slot,\n hub = false,\n prefetch,\n className,\n children,\n}: {\n readonly href: string\n readonly slot: string\n readonly hub?: boolean\n /**\n * False for links in panels and the drawer: hidden panels count as in view and would prefetch every menu page. The\n * current page is never prefetched, whatever this says.\n */\n readonly prefetch?: boolean | undefined\n readonly className?: string | undefined\n readonly children: ReactNode\n}) {\n const pathname = usePathname()\n const current = isCurrentPage(pathname, href)\n return (\n <Link\n href={href}\n prefetch={current ? false : prefetch}\n data-slot={slot}\n data-hub={hub ? 'true' : undefined}\n aria-current={current ? 'page' : undefined}\n className={className}\n >\n {children}\n </Link>\n )\n}\n\n/**\n * The header logo's home link: prefetch stays Next's default except on the home page itself, which is never\n * prefetched. No `aria-current`: the logo is named by the brand, not as a menu item.\n */\nexport function LogoLink({\n href,\n label,\n slot,\n className,\n children,\n}: {\n readonly href: string\n readonly label: string\n readonly slot: string\n readonly className?: string | undefined\n readonly children: ReactNode\n}) {\n const pathname = usePathname()\n return (\n <Link href={href} prefetch={isCurrentPage(pathname, href) ? false : undefined} aria-label={label} data-slot={slot} className={className}>\n {children}\n </Link>\n )\n}\n"]}
@@ -3,4 +3,5 @@ export { MOBILE_DRAWER_VARIANTS, MobileDrawer, type MobileDrawerLayout, type Mob
3
3
  export { UtilityBar, type UtilityBarLayout, type UtilityBarProps, type UtilityBarSkin, type UtilityBarSlot, type UtilityLicence, type UtilityRating, } from './utility-bar.js';
4
4
  export { MOBILE_CALL_BAR_VARIANTS, MobileCallBar, type MobileCallBarProps, type MobileCallBarSkin, type MobileCallBarSlot, type MobileCallBarVariant, } from './mobile-call-bar.js';
5
5
  export { BACK_TO_TOP_OFFSETS, BackToTop, type BackToTopLayout, type BackToTopProps, type BackToTopSkin, type BackToTopSlot } from './back-to-top.js';
6
+ export { IntentPrefetch, intentPrefetchTarget } from './intent-prefetch.js';
6
7
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,wBAAwB,EACxB,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,iBAAiB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,sBAAsB,EACtB,YAAY,EACZ,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,gBAAgB,EACrB,KAAK,gBAAgB,EACrB,KAAK,mBAAmB,EACxB,KAAK,UAAU,GAChB,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,UAAU,EACV,KAAK,gBAAgB,EACrB,KAAK,eAAe,EACpB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,aAAa,GACnB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,wBAAwB,EACxB,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,iBAAiB,EACtB,KAAK,iBAAiB,EACtB,KAAK,oBAAoB,GAC1B,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAE,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,KAAK,aAAa,EAAE,KAAK,aAAa,EAAE,MAAM,kBAAkB,CAAA;AACpJ,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA"}
@@ -3,4 +3,5 @@ export { MOBILE_DRAWER_VARIANTS, MobileDrawer, } from './mobile-drawer.js';
3
3
  export { UtilityBar, } from './utility-bar.js';
4
4
  export { MOBILE_CALL_BAR_VARIANTS, MobileCallBar, } from './mobile-call-bar.js';
5
5
  export { BACK_TO_TOP_OFFSETS, BackToTop } from './back-to-top.js';
6
+ export { IntentPrefetch, intentPrefetchTarget } from './intent-prefetch.js';
6
7
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,UAAU,GAMX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,sBAAsB,EACtB,YAAY,GAOb,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,UAAU,GAOX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,wBAAwB,EACxB,aAAa,GAKd,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAqF,MAAM,kBAAkB,CAAA","sourcesContent":["export {\n SITE_HEADER_VARIANTS,\n SiteHeader,\n type SiteHeaderLayout,\n type SiteHeaderProps,\n type SiteHeaderSkin,\n type SiteHeaderSlot,\n type SiteHeaderVariant,\n} from './site-header.js'\nexport {\n MOBILE_DRAWER_VARIANTS,\n MobileDrawer,\n type MobileDrawerLayout,\n type MobileDrawerProps,\n type MobileDrawerSkin,\n type MobileDrawerSlot,\n type MobileDrawerVariant,\n type ShellQuote,\n} from './mobile-drawer.js'\nexport {\n UtilityBar,\n type UtilityBarLayout,\n type UtilityBarProps,\n type UtilityBarSkin,\n type UtilityBarSlot,\n type UtilityLicence,\n type UtilityRating,\n} from './utility-bar.js'\nexport {\n MOBILE_CALL_BAR_VARIANTS,\n MobileCallBar,\n type MobileCallBarProps,\n type MobileCallBarSkin,\n type MobileCallBarSlot,\n type MobileCallBarVariant,\n} from './mobile-call-bar.js'\nexport { BACK_TO_TOP_OFFSETS, BackToTop, type BackToTopLayout, type BackToTopProps, type BackToTopSkin, type BackToTopSlot } from './back-to-top.js'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,UAAU,GAMX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,sBAAsB,EACtB,YAAY,GAOb,MAAM,oBAAoB,CAAA;AAC3B,OAAO,EACL,UAAU,GAOX,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,wBAAwB,EACxB,aAAa,GAKd,MAAM,sBAAsB,CAAA;AAC7B,OAAO,EAAE,mBAAmB,EAAE,SAAS,EAAqF,MAAM,kBAAkB,CAAA;AACpJ,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAA","sourcesContent":["export {\n SITE_HEADER_VARIANTS,\n SiteHeader,\n type SiteHeaderLayout,\n type SiteHeaderProps,\n type SiteHeaderSkin,\n type SiteHeaderSlot,\n type SiteHeaderVariant,\n} from './site-header.js'\nexport {\n MOBILE_DRAWER_VARIANTS,\n MobileDrawer,\n type MobileDrawerLayout,\n type MobileDrawerProps,\n type MobileDrawerSkin,\n type MobileDrawerSlot,\n type MobileDrawerVariant,\n type ShellQuote,\n} from './mobile-drawer.js'\nexport {\n UtilityBar,\n type UtilityBarLayout,\n type UtilityBarProps,\n type UtilityBarSkin,\n type UtilityBarSlot,\n type UtilityLicence,\n type UtilityRating,\n} from './utility-bar.js'\nexport {\n MOBILE_CALL_BAR_VARIANTS,\n MobileCallBar,\n type MobileCallBarProps,\n type MobileCallBarSkin,\n type MobileCallBarSlot,\n type MobileCallBarVariant,\n} from './mobile-call-bar.js'\nexport { BACK_TO_TOP_OFFSETS, BackToTop, type BackToTopLayout, type BackToTopProps, type BackToTopSkin, type BackToTopSlot } from './back-to-top.js'\nexport { IntentPrefetch, intentPrefetchTarget } from './intent-prefetch.js'\n"]}
@@ -0,0 +1,4 @@
1
+ /** The site path an intent link points to, without its fragment; null for another site or no href. */
2
+ export declare function intentPrefetchTarget(href: string | null): string | null;
3
+ export declare function IntentPrefetch(): null;
4
+ //# sourceMappingURL=intent-prefetch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-prefetch.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/intent-prefetch.tsx"],"names":[],"mappings":"AA4BA,sGAAsG;AACtG,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,IAAI,CAIvE;AAOD,wBAAgB,cAAc,IAAI,IAAI,CAsBrC"}
@@ -0,0 +1,61 @@
1
+ 'use client';
2
+ /**
3
+ * `IntentPrefetch`: prefetches an in-content card link when a visitor shows intent, not when it scrolls into view.
4
+ * Links with `prefetch="intent"` (ButtonLink, TextLink, QuoteButton) render `prefetch={false}` and
5
+ * `data-prefetch="intent"`; this island holds one document listener for pointer entry, focus and touch, and calls
6
+ * `router.prefetch(href)` for the one link the visitor points at, focuses or touches, once per page address. A touch
7
+ * prefetches only the touched link, never the list around it; the current page and links to other sites are never
8
+ * prefetched.
9
+ *
10
+ * Mount it once, in the root layout, beside the header:
11
+ *
12
+ * // src/app/layout.tsx
13
+ * import { IntentPrefetch } from '@brandlab-digital/site-next/ui-kit/shell'
14
+ * <body>
15
+ * <SiteHeader … />
16
+ * <IntentPrefetch />
17
+ * …
18
+ * </body>
19
+ *
20
+ * It renders nothing; without scripts the links still work and simply do not prefetch.
21
+ */
22
+ import { useRouter } from 'next/navigation';
23
+ import { useEffect } from 'react';
24
+ import { INTENT_PREFETCH_SELECTOR } from '../prefetch.js';
25
+ const INTENT_EVENTS = ['pointerenter', 'focusin', 'touchstart'];
26
+ /** The site path an intent link points to, without its fragment; null for another site or no href. */
27
+ export function intentPrefetchTarget(href) {
28
+ if (!href || !href.startsWith('/') || href.startsWith('//'))
29
+ return null;
30
+ const target = href.split('#', 1)[0] ?? '';
31
+ return target || null;
32
+ }
33
+ function samePage(target, location) {
34
+ const path = (value) => value.replace(/\/+$/, '') || '/';
35
+ return path(target.split('?', 1)[0] ?? '') === path(location.pathname);
36
+ }
37
+ export function IntentPrefetch() {
38
+ const router = useRouter();
39
+ useEffect(() => {
40
+ const prefetched = new Set();
41
+ const onIntent = (event) => {
42
+ const element = event.target instanceof Element ? event.target : null;
43
+ const link = element?.closest(INTENT_PREFETCH_SELECTOR);
44
+ const target = intentPrefetchTarget(link?.getAttribute('href') ?? null);
45
+ if (!target || prefetched.has(target) || samePage(target, window.location))
46
+ return;
47
+ prefetched.add(target);
48
+ router.prefetch(target);
49
+ };
50
+ // Capture, so pointerenter (which does not bubble) reaches the document; passive, so touch never waits on it.
51
+ const options = { capture: true, passive: true };
52
+ for (const type of INTENT_EVENTS)
53
+ document.addEventListener(type, onIntent, options);
54
+ return () => {
55
+ for (const type of INTENT_EVENTS)
56
+ document.removeEventListener(type, onIntent, options);
57
+ };
58
+ }, [router]);
59
+ return null;
60
+ }
61
+ //# sourceMappingURL=intent-prefetch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-prefetch.js","sourceRoot":"","sources":["../../../src/ui-kit/shell/intent-prefetch.tsx"],"names":[],"mappings":"AAAA,YAAY,CAAA;AAEZ;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAA;AAC3C,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AACjC,OAAO,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAA;AAEzD,MAAM,aAAa,GAAG,CAAC,cAAc,EAAE,SAAS,EAAE,YAAY,CAAU,CAAA;AAExE,sGAAsG;AACtG,MAAM,UAAU,oBAAoB,CAAC,IAAmB;IACtD,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAA;IACxE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAA;IAC1C,OAAO,MAAM,IAAI,IAAI,CAAA;AACvB,CAAC;AAED,SAAS,QAAQ,CAAC,MAAc,EAAE,QAAkB;IAClD,MAAM,IAAI,GAAG,CAAC,KAAa,EAAE,EAAE,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,IAAI,GAAG,CAAA;IAChE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;AACxE,CAAC;AAED,MAAM,UAAU,cAAc;IAC5B,MAAM,MAAM,GAAG,SAAS,EAAE,CAAA;IAE1B,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAA;QACpC,MAAM,QAAQ,GAAG,CAAC,KAAY,EAAE,EAAE;YAChC,MAAM,OAAO,GAAG,KAAK,CAAC,MAAM,YAAY,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAA;YACrE,MAAM,IAAI,GAAG,OAAO,EAAE,OAAO,CAAoB,wBAAwB,CAAC,CAAA;YAC1E,MAAM,MAAM,GAAG,oBAAoB,CAAC,IAAI,EAAE,YAAY,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,CAAA;YACvE,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC;gBAAE,OAAM;YAClF,UAAU,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;YACtB,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAA;QACzB,CAAC,CAAA;QACD,8GAA8G;QAC9G,MAAM,OAAO,GAA4B,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,CAAA;QACzE,KAAK,MAAM,IAAI,IAAI,aAAa;YAAE,QAAQ,CAAC,gBAAgB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;QACpF,OAAO,GAAG,EAAE;YACV,KAAK,MAAM,IAAI,IAAI,aAAa;gBAAE,QAAQ,CAAC,mBAAmB,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAA;QACzF,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,MAAM,CAAC,CAAC,CAAA;IAEZ,OAAO,IAAI,CAAA;AACb,CAAC","sourcesContent":["'use client'\n\n/**\n * `IntentPrefetch`: prefetches an in-content card link when a visitor shows intent, not when it scrolls into view.\n * Links with `prefetch=\"intent\"` (ButtonLink, TextLink, QuoteButton) render `prefetch={false}` and\n * `data-prefetch=\"intent\"`; this island holds one document listener for pointer entry, focus and touch, and calls\n * `router.prefetch(href)` for the one link the visitor points at, focuses or touches, once per page address. A touch\n * prefetches only the touched link, never the list around it; the current page and links to other sites are never\n * prefetched.\n *\n * Mount it once, in the root layout, beside the header:\n *\n * // src/app/layout.tsx\n * import { IntentPrefetch } from '@brandlab-digital/site-next/ui-kit/shell'\n * <body>\n * <SiteHeader … />\n * <IntentPrefetch />\n * …\n * </body>\n *\n * It renders nothing; without scripts the links still work and simply do not prefetch.\n */\nimport { useRouter } from 'next/navigation'\nimport { useEffect } from 'react'\nimport { INTENT_PREFETCH_SELECTOR } from '../prefetch.js'\n\nconst INTENT_EVENTS = ['pointerenter', 'focusin', 'touchstart'] as const\n\n/** The site path an intent link points to, without its fragment; null for another site or no href. */\nexport function intentPrefetchTarget(href: string | null): string | null {\n if (!href || !href.startsWith('/') || href.startsWith('//')) return null\n const target = href.split('#', 1)[0] ?? ''\n return target || null\n}\n\nfunction samePage(target: string, location: Location) {\n const path = (value: string) => value.replace(/\\/+$/, '') || '/'\n return path(target.split('?', 1)[0] ?? '') === path(location.pathname)\n}\n\nexport function IntentPrefetch(): null {\n const router = useRouter()\n\n useEffect(() => {\n const prefetched = new Set<string>()\n const onIntent = (event: Event) => {\n const element = event.target instanceof Element ? event.target : null\n const link = element?.closest<HTMLAnchorElement>(INTENT_PREFETCH_SELECTOR)\n const target = intentPrefetchTarget(link?.getAttribute('href') ?? null)\n if (!target || prefetched.has(target) || samePage(target, window.location)) return\n prefetched.add(target)\n router.prefetch(target)\n }\n // Capture, so pointerenter (which does not bubble) reaches the document; passive, so touch never waits on it.\n const options: AddEventListenerOptions = { capture: true, passive: true }\n for (const type of INTENT_EVENTS) document.addEventListener(type, onIntent, options)\n return () => {\n for (const type of INTENT_EVENTS) document.removeEventListener(type, onIntent, options)\n }\n }, [router])\n\n return null\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"site-header.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/site-header.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAA4C,MAAM,wCAAwC,CAAA;AAG1H,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,EAAY,KAAK,SAAS,EAAoB,MAAM,YAAY,CAAA;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,EAAgB,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEzF,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,KAAK,GACL,OAAO,GACP,MAAM,GACN,KAAK,GACL,MAAM,GACN,MAAM,GACN,SAAS,GACT,MAAM,GACN,SAAS,GACT,OAAO,GACP,WAAW,GACX,WAAW,GACX,YAAY,GACZ,cAAc,GACd,WAAW,GACX,YAAY,GACZ,WAAW,GACX,UAAU,GACV,eAAe,GACf,eAAe,GACf,cAAc,GACd,SAAS,GACT,OAAO,GACP,WAAW,GACX,YAAY,GACZ,aAAa,GACb,OAAO,GACP,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,WAAW,CAAA;AACf,eAAO,MAAM,oBAAoB,qCAAsC,CAAA;AACvE;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AACrE,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAA;IACpC,mGAAmG;IACnG,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CACtC;AACD,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAA;AAE3F,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAA;IACvC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,mGAAmG;IACnG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,CAAA;IAClD,yFAAyF;IACzF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAA;IAC9C,iDAAiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAA;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,SAAS,EACT,OAAO,EACP,MAAM,EACN,UAAU,EACV,QAAsB,EACtB,OAAoB,EACpB,MAAM,EACN,OAAO,GACR,EAAE,eAAe,2CAoEjB"}
1
+ {"version":3,"file":"site-header.d.ts","sourceRoot":"","sources":["../../../src/ui-kit/shell/site-header.tsx"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,kBAAkB,EAA4C,MAAM,wCAAwC,CAAA;AAE1H,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAMtC,OAAO,EAAY,KAAK,SAAS,EAAoB,MAAM,YAAY,CAAA;AACvE,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAA;AAGpD,OAAO,EAAgB,KAAK,gBAAgB,EAAE,KAAK,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEzF,MAAM,MAAM,cAAc,GACtB,MAAM,GACN,MAAM,GACN,KAAK,GACL,OAAO,GACP,MAAM,GACN,KAAK,GACL,MAAM,GACN,MAAM,GACN,SAAS,GACT,MAAM,GACN,SAAS,GACT,OAAO,GACP,WAAW,GACX,WAAW,GACX,YAAY,GACZ,cAAc,GACd,WAAW,GACX,YAAY,GACZ,WAAW,GACX,UAAU,GACV,eAAe,GACf,eAAe,GACf,cAAc,GACd,SAAS,GACT,OAAO,GACP,WAAW,GACX,YAAY,GACZ,aAAa,GACb,OAAO,GACP,YAAY,GACZ,WAAW,GACX,YAAY,GACZ,WAAW,CAAA;AACf,eAAO,MAAM,oBAAoB,qCAAsC,CAAA;AACvE;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AACrE,MAAM,WAAW,gBAAgB;IAC/B,4DAA4D;IAC5D,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,GAAG,KAAK,CAAA;IACpC,mGAAmG;IACnG,QAAQ,CAAC,kBAAkB,CAAC,EAAE,OAAO,CAAA;CACtC;AACD,MAAM,MAAM,cAAc,GAAG,SAAS,CAAC,cAAc,EAAE,iBAAiB,EAAE,gBAAgB,CAAC,CAAA;AAE3F,MAAM,WAAW,eAAgB,SAAQ,cAAc;IACrD,QAAQ,CAAC,UAAU,EAAE,kBAAkB,CAAA;IACvC,uCAAuC;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAA;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAA;IACxB,4DAA4D;IAC5D,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAA;IACvB,mGAAmG;IACnG,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;IACxC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,QAAQ,EAAE,GAAG,SAAS,CAAA;IAClD,yFAAyF;IACzF,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B,8FAA8F;IAC9F,QAAQ,CAAC,OAAO,CAAC,EAAE,SAAS,CAAA;IAC5B,4CAA4C;IAC5C,QAAQ,CAAC,MAAM,CAAC,EAAE,gBAAgB,GAAG,SAAS,CAAA;IAC9C,iDAAiD;IACjD,QAAQ,CAAC,UAAU,CAAC,EAAE,SAAS,CAAA;IAC/B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;CACvC;AAED,wBAAgB,UAAU,CAAC,EACzB,UAAU,EACV,SAAS,EACT,QAAQ,EACR,IAAI,EACJ,KAAK,EACL,UAAU,EACV,KAAK,EACL,OAAO,EACP,SAAS,EACT,OAAO,EACP,MAAM,EACN,UAAU,EACV,QAAsB,EACtB,OAAoB,EACpB,MAAM,EACN,OAAO,GACR,EAAE,eAAe,2CAoEjB"}
@@ -1,19 +1,18 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
2
  import Image from 'next/image';
3
- import Link from 'next/link';
4
3
  import { SkipLink } from '../../ui.js';
5
4
  import { MAIN_CONTENT_ID } from '../../navigation/constants.js';
6
5
  import { Icon } from '../icons.js';
7
6
  import { PhoneLink } from '../primitives/links.js';
8
7
  import { QuoteButton } from '../primitives/quote-button.js';
9
8
  import { cx, slot } from '../skin.js';
10
- import { CurrentLink } from './current-link.js';
9
+ import { CurrentLink, LogoLink } from './current-link.js';
11
10
  import { HeaderRoot, NavController, NavItem, NavPanel, NavTrigger } from './header-client.js';
12
11
  import { MobileDrawer } from './mobile-drawer.js';
13
12
  export const SITE_HEADER_VARIANTS = ['standard', 'call-first'];
14
13
  export function SiteHeader({ navigation, brandName, homeHref, logo, phone, phoneLabel, quote, socials, skipLabel, utility, drawer, drawerLogo, idPrefix = 'bl-header', variant = 'standard', layout, classes, }) {
15
14
  const callFirst = variant === 'call-first';
16
- return (_jsxs(_Fragment, { children: [_jsx(SkipLink, { targetId: MAIN_CONTENT_ID, "data-bl": "skip", className: classes?.skip, children: skipLabel }), utility, _jsx(HeaderRoot, { variant: variant, navAlign: layout?.navAlign ?? 'center', compactAfterScroll: layout?.compactAfterScroll ?? false, className: classes?.root, children: _jsx("div", { ...slot(classes, 'bar'), children: _jsxs("div", { ...slot(classes, 'inner'), children: [_jsx(Link, { href: homeHref, "aria-label": brandName, ...slot(classes, 'logo'), children: logo }), _jsx(NavController, { label: "Main", className: classes?.nav, children: _jsx("ul", { ...slot(classes, 'list'), children: navigation.items.map((item) => item.kind === 'link' ? (_jsx(LinkItem, { item: item, classes: classes }, item.id)) : (_jsx(MenuItem, { item: item, panelId: `${idPrefix}-panel-${item.id}`, classes: classes }, item.id))) }) }), _jsxs("div", { ...slot(classes, 'actions'), children: [_jsx(PhoneLink, { phone: phone, placement: "header", label: phoneLabel, showIcon: true, variant: callFirst ? 'button' : 'text', classes: { root: classes?.phone, icon: classes?.phoneIcon, label: classes?.phoneLabel, number: classes?.phoneNumber } }), _jsx(QuoteButton, { label: quote.label, href: quote.href, placement: "header", ctaId: "quote-header", classes: { root: classes?.quote, label: classes?.quoteLabel, icon: classes?.quoteIcon } }), _jsx(MobileDrawer, { ...drawer, classes: {
15
+ return (_jsxs(_Fragment, { children: [_jsx(SkipLink, { targetId: MAIN_CONTENT_ID, "data-bl": "skip", className: classes?.skip, children: skipLabel }), utility, _jsx(HeaderRoot, { variant: variant, navAlign: layout?.navAlign ?? 'center', compactAfterScroll: layout?.compactAfterScroll ?? false, className: classes?.root, children: _jsx("div", { ...slot(classes, 'bar'), children: _jsxs("div", { ...slot(classes, 'inner'), children: [_jsx(LogoLink, { href: homeHref, label: brandName, slot: "logo", className: classes?.logo, children: logo }), _jsx(NavController, { label: "Main", className: classes?.nav, children: _jsx("ul", { ...slot(classes, 'list'), children: navigation.items.map((item) => item.kind === 'link' ? (_jsx(LinkItem, { item: item, classes: classes }, item.id)) : (_jsx(MenuItem, { item: item, panelId: `${idPrefix}-panel-${item.id}`, classes: classes }, item.id))) }) }), _jsxs("div", { ...slot(classes, 'actions'), children: [_jsx(PhoneLink, { phone: phone, placement: "header", label: phoneLabel, showIcon: true, variant: callFirst ? 'button' : 'text', classes: { root: classes?.phone, icon: classes?.phoneIcon, label: classes?.phoneLabel, number: classes?.phoneNumber } }), _jsx(QuoteButton, { label: quote.label, href: quote.href, placement: "header", ctaId: "quote-header", classes: { root: classes?.quote, label: classes?.quoteLabel, icon: classes?.quoteIcon } }), _jsx(MobileDrawer, { ...drawer, classes: {
17
16
  ...drawer?.classes,
18
17
  menuButton: cx(drawer?.classes?.menuButton, classes?.menuButton),
19
18
  menuLabel: cx(drawer?.classes?.menuLabel, classes?.menuLabel),