@mission-studio/puck 1.0.5 → 1.0.16

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 (40) hide show
  1. package/dist/ResponsiveToggleField-BihXsGIJ.d.mts +26 -0
  2. package/dist/ResponsiveToggleField-CfBKL5oY.d.ts +26 -0
  3. package/dist/chunk-A3QDUUOF.mjs +80 -0
  4. package/dist/chunk-D3L26TIT.mjs +76 -0
  5. package/dist/chunk-KV2RSRAM.mjs +114 -0
  6. package/dist/{chunk-R7TH6TWG.mjs → chunk-ML3AS3AY.mjs} +56 -84
  7. package/dist/{chunk-OZYZPWP7.mjs → chunk-SYXQQITG.mjs} +253 -287
  8. package/dist/config/server.d.mts +5 -0
  9. package/dist/config/server.d.ts +5 -0
  10. package/dist/config/server.js +2207 -0
  11. package/dist/config/server.mjs +133 -0
  12. package/dist/config-entry.js +334 -395
  13. package/dist/config-entry.mjs +5 -3
  14. package/dist/editor.d.mts +5 -2
  15. package/dist/editor.d.ts +5 -2
  16. package/dist/editor.js +271 -309
  17. package/dist/editor.mjs +10 -6
  18. package/dist/hooks/index.d.mts +3 -2
  19. package/dist/hooks/index.d.ts +3 -2
  20. package/dist/index.d.mts +7 -287
  21. package/dist/index.d.ts +7 -287
  22. package/dist/index.js +59 -92
  23. package/dist/index.mjs +20 -16
  24. package/dist/renderer.d.mts +289 -0
  25. package/dist/renderer.d.ts +289 -0
  26. package/dist/renderer.js +2162 -0
  27. package/dist/renderer.mjs +57 -0
  28. package/dist/resolve/index.d.mts +10 -0
  29. package/dist/resolve/index.d.ts +10 -0
  30. package/dist/resolve/index.js +202 -0
  31. package/dist/resolve/index.mjs +124 -0
  32. package/dist/styles.css +1 -1
  33. package/dist/types-D-CIduaE.d.mts +111 -0
  34. package/dist/types-D-CIduaE.d.ts +111 -0
  35. package/dist/typography-DwjKOx3F.d.mts +49 -0
  36. package/dist/typography-DwjKOx3F.d.ts +49 -0
  37. package/package.json +16 -1
  38. package/dist/ResponsiveToggleField-CVhKzDAT.d.mts +0 -183
  39. package/dist/ResponsiveToggleField-CVhKzDAT.d.ts +0 -183
  40. package/dist/chunk-TTKY3YGP.mjs +0 -262
@@ -0,0 +1,26 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { P as PageTheme, b as ThemeColorKey, C as ColorValue, g as ThemeSpacingKey, T as ThemeBorderKey, d as ThemeShadowKey, m as CustomFieldProps } from './types-D-CIduaE.mjs';
4
+
5
+ type ThemeContextValue = {
6
+ theme: PageTheme;
7
+ resolveColor: (key: ThemeColorKey) => ColorValue;
8
+ resolveSpacing: (key: ThemeSpacingKey) => number;
9
+ resolveBorderRadius: (key: ThemeBorderKey) => number;
10
+ resolveShadow: (key: ThemeShadowKey) => string;
11
+ };
12
+ declare function ThemeProvider({ theme, children, }: {
13
+ theme: PageTheme | null;
14
+ children: ReactNode;
15
+ }): react_jsx_runtime.JSX.Element;
16
+ declare function useTheme(): ThemeContextValue;
17
+
18
+ declare const DEFAULT_THEME: PageTheme;
19
+
20
+ type ResponsiveVisibility = {
21
+ mobile: boolean;
22
+ desktop: boolean;
23
+ };
24
+ declare function ResponsiveToggleField({ value, onChangeAction, disabled, label, }: CustomFieldProps<ResponsiveVisibility>): react_jsx_runtime.JSX.Element;
25
+
26
+ export { DEFAULT_THEME as D, type ResponsiveVisibility as R, ThemeProvider as T, ResponsiveToggleField as a, useTheme as u };
@@ -0,0 +1,26 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { ReactNode } from 'react';
3
+ import { P as PageTheme, b as ThemeColorKey, C as ColorValue, g as ThemeSpacingKey, T as ThemeBorderKey, d as ThemeShadowKey, m as CustomFieldProps } from './types-D-CIduaE.js';
4
+
5
+ type ThemeContextValue = {
6
+ theme: PageTheme;
7
+ resolveColor: (key: ThemeColorKey) => ColorValue;
8
+ resolveSpacing: (key: ThemeSpacingKey) => number;
9
+ resolveBorderRadius: (key: ThemeBorderKey) => number;
10
+ resolveShadow: (key: ThemeShadowKey) => string;
11
+ };
12
+ declare function ThemeProvider({ theme, children, }: {
13
+ theme: PageTheme | null;
14
+ children: ReactNode;
15
+ }): react_jsx_runtime.JSX.Element;
16
+ declare function useTheme(): ThemeContextValue;
17
+
18
+ declare const DEFAULT_THEME: PageTheme;
19
+
20
+ type ResponsiveVisibility = {
21
+ mobile: boolean;
22
+ desktop: boolean;
23
+ };
24
+ declare function ResponsiveToggleField({ value, onChangeAction, disabled, label, }: CustomFieldProps<ResponsiveVisibility>): react_jsx_runtime.JSX.Element;
25
+
26
+ export { DEFAULT_THEME as D, type ResponsiveVisibility as R, ThemeProvider as T, ResponsiveToggleField as a, useTheme as u };
@@ -0,0 +1,80 @@
1
+ // design-system/borders.ts
2
+ var borderRadiusScale = [
3
+ { label: "None", value: 0 },
4
+ { label: "XS", value: 2 },
5
+ { label: "SM", value: 4 },
6
+ { label: "MD", value: 6 },
7
+ { label: "LG", value: 8 },
8
+ { label: "XL", value: 12 },
9
+ { label: "2XL", value: 16 },
10
+ { label: "3XL", value: 24 }
11
+ ];
12
+ var getClosestBorderRadiusValue = (value) => {
13
+ return borderRadiusScale.reduce(
14
+ (prev, curr) => Math.abs(curr.value - value) < Math.abs(prev.value - value) ? curr : prev
15
+ ).value;
16
+ };
17
+ var getBorderRadiusCSS = (value) => {
18
+ return `${value}px`;
19
+ };
20
+
21
+ // design-system/spacing.ts
22
+ var spacingScale = [
23
+ { label: "None", value: 0 },
24
+ { label: "2XS", value: 4 },
25
+ { label: "XS", value: 8 },
26
+ { label: "SM", value: 12 },
27
+ { label: "MD", value: 16 },
28
+ { label: "LG", value: 24 },
29
+ { label: "XL", value: 32 },
30
+ { label: "2XL", value: 48 },
31
+ { label: "3XL", value: 64 },
32
+ { label: "4XL", value: 96 }
33
+ ];
34
+ var getClosestSpacingValue = (value) => {
35
+ return spacingScale.reduce(
36
+ (prev, curr) => Math.abs(curr.value - value) < Math.abs(prev.value - value) ? curr : prev
37
+ ).value;
38
+ };
39
+
40
+ // design-system/typography.ts
41
+ var fontFamilies = [
42
+ { label: "System", value: "system-ui, sans-serif" },
43
+ { label: "Sans", value: "ui-sans-serif, system-ui, sans-serif" },
44
+ { label: "Serif", value: "ui-serif, Georgia, serif" },
45
+ { label: "Mono", value: "ui-monospace, monospace" }
46
+ ];
47
+ var fontSizes = [
48
+ { label: "XS", value: "xs", css: "0.75rem" },
49
+ { label: "SM", value: "sm", css: "0.875rem" },
50
+ { label: "Base", value: "base", css: "1rem" },
51
+ { label: "LG", value: "lg", css: "1.125rem" },
52
+ { label: "XL", value: "xl", css: "1.25rem" },
53
+ { label: "2XL", value: "2xl", css: "1.5rem" },
54
+ { label: "3XL", value: "3xl", css: "1.875rem" },
55
+ { label: "4XL", value: "4xl", css: "2.25rem" },
56
+ { label: "5XL", value: "5xl", css: "3rem" }
57
+ ];
58
+ var fontWeights = [
59
+ { label: "Light", value: 300 },
60
+ { label: "Normal", value: 400 },
61
+ { label: "Medium", value: 500 },
62
+ { label: "Semibold", value: 600 },
63
+ { label: "Bold", value: 700 }
64
+ ];
65
+ var getFontSizeCSS = (value) => {
66
+ const preset = fontSizes.find((p) => p.value === value);
67
+ return preset?.css ?? "1rem";
68
+ };
69
+
70
+ export {
71
+ borderRadiusScale,
72
+ getClosestBorderRadiusValue,
73
+ getBorderRadiusCSS,
74
+ spacingScale,
75
+ getClosestSpacingValue,
76
+ fontFamilies,
77
+ fontSizes,
78
+ fontWeights,
79
+ getFontSizeCSS
80
+ };
@@ -0,0 +1,76 @@
1
+ // theme/defaults.ts
2
+ var DEFAULT_THEME = {
3
+ id: "default",
4
+ name: "Default Theme",
5
+ colors: {
6
+ primary: { color: "#3B82F6", opacity: 100 },
7
+ secondary: { color: "#8B5CF6", opacity: 100 },
8
+ accent: { color: "#10B981", opacity: 100 },
9
+ background: { color: "#FFFFFF", opacity: 100 },
10
+ foreground: { color: "#111827", opacity: 100 },
11
+ muted: { color: "#F3F4F6", opacity: 100 }
12
+ },
13
+ typography: {
14
+ fontFamily: {
15
+ heading: "system-ui, sans-serif",
16
+ body: "system-ui, sans-serif"
17
+ },
18
+ fontSize: {
19
+ base: "base",
20
+ heading: "4xl"
21
+ },
22
+ fontWeight: {
23
+ normal: 400,
24
+ heading: 700
25
+ }
26
+ },
27
+ spacing: {
28
+ xs: 8,
29
+ sm: 12,
30
+ md: 16,
31
+ lg: 24,
32
+ xl: 32
33
+ },
34
+ borders: {
35
+ radiusSmall: 4,
36
+ radiusMedium: 8,
37
+ radiusLarge: 16
38
+ },
39
+ shadows: {
40
+ small: "sm",
41
+ medium: "md",
42
+ large: "lg"
43
+ }
44
+ };
45
+
46
+ // utils/index.ts
47
+ import { twMerge } from "tailwind-merge";
48
+ import { clsx } from "clsx";
49
+ function isValidHex(color) {
50
+ return /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/.test(color);
51
+ }
52
+ function hexToRgba(hex, opacity) {
53
+ const sanitized = hex.replace("#", "");
54
+ const r = parseInt(sanitized.slice(0, 2), 16);
55
+ const g = parseInt(sanitized.slice(2, 4), 16);
56
+ const b = parseInt(sanitized.slice(4, 6), 16);
57
+ return `rgba(${r}, ${g}, ${b}, ${opacity / 100})`;
58
+ }
59
+ function normalizeHex(hex) {
60
+ const sanitized = hex.replace("#", "").toUpperCase();
61
+ if (sanitized.length === 3) {
62
+ return `#${sanitized[0]}${sanitized[0]}${sanitized[1]}${sanitized[1]}${sanitized[2]}${sanitized[2]}`;
63
+ }
64
+ return `#${sanitized}`;
65
+ }
66
+ function cn(...inputs) {
67
+ return twMerge(clsx(inputs));
68
+ }
69
+
70
+ export {
71
+ DEFAULT_THEME,
72
+ isValidHex,
73
+ hexToRgba,
74
+ normalizeHex,
75
+ cn
76
+ };
@@ -0,0 +1,114 @@
1
+ import {
2
+ DEFAULT_THEME
3
+ } from "./chunk-D3L26TIT.mjs";
4
+
5
+ // entries/context.tsx
6
+ import { createContext, useContext } from "react";
7
+ import { jsx } from "react/jsx-runtime";
8
+ var EntriesContext = createContext(null);
9
+ function EntriesProvider({
10
+ entries,
11
+ children
12
+ }) {
13
+ const entriesMap = new Map(entries.map((e) => [e.name, e]));
14
+ const contextValue = {
15
+ entries,
16
+ entryNames: entries.map((e) => e.name),
17
+ getEntry: (name) => entriesMap.get(name),
18
+ getEntryValue: (entryName, fieldKey) => {
19
+ const entry = entriesMap.get(entryName);
20
+ if (!entry) return void 0;
21
+ return entry.content[fieldKey];
22
+ }
23
+ };
24
+ return /* @__PURE__ */ jsx(EntriesContext.Provider, { value: contextValue, children });
25
+ }
26
+ function useEntries() {
27
+ const context = useContext(EntriesContext);
28
+ if (!context) {
29
+ return {
30
+ entries: [],
31
+ entryNames: [],
32
+ getEntry: () => void 0,
33
+ getEntryValue: () => void 0
34
+ };
35
+ }
36
+ return context;
37
+ }
38
+
39
+ // theme/context.tsx
40
+ import { createContext as createContext2, useContext as useContext2 } from "react";
41
+ import { jsx as jsx2 } from "react/jsx-runtime";
42
+ var ThemeContext = createContext2(null);
43
+ function ThemeProvider({
44
+ theme,
45
+ children
46
+ }) {
47
+ const activeTheme = theme ?? DEFAULT_THEME;
48
+ const contextValue = {
49
+ theme: activeTheme,
50
+ resolveColor: (key) => activeTheme.colors[key],
51
+ resolveSpacing: (key) => activeTheme.spacing[key],
52
+ resolveBorderRadius: (key) => activeTheme.borders[key],
53
+ resolveShadow: (key) => activeTheme.shadows[key]
54
+ };
55
+ return /* @__PURE__ */ jsx2(ThemeContext.Provider, { value: contextValue, children });
56
+ }
57
+ function useTheme() {
58
+ const context = useContext2(ThemeContext);
59
+ if (!context) {
60
+ return {
61
+ theme: DEFAULT_THEME,
62
+ resolveColor: (key) => DEFAULT_THEME.colors[key],
63
+ resolveSpacing: (key) => DEFAULT_THEME.spacing[key],
64
+ resolveBorderRadius: (key) => DEFAULT_THEME.borders[key],
65
+ resolveShadow: (key) => DEFAULT_THEME.shadows[key]
66
+ };
67
+ }
68
+ return context;
69
+ }
70
+
71
+ // design-system/shadows.ts
72
+ var shadowPresets = [
73
+ { label: "None", value: "none", css: "none" },
74
+ { label: "XS", value: "xs", css: "0 1px 2px 0 rgb(0 0 0 / 0.05)" },
75
+ {
76
+ label: "SM",
77
+ value: "sm",
78
+ css: "0 1px 3px 0 rgb(0 0 0 / 0.1), 0 1px 2px -1px rgb(0 0 0 / 0.1)"
79
+ },
80
+ {
81
+ label: "MD",
82
+ value: "md",
83
+ css: "0 4px 6px -1px rgb(0 0 0 / 0.1), 0 2px 4px -2px rgb(0 0 0 / 0.1)"
84
+ },
85
+ {
86
+ label: "LG",
87
+ value: "lg",
88
+ css: "0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1)"
89
+ },
90
+ {
91
+ label: "XL",
92
+ value: "xl",
93
+ css: "0 20px 25px -5px rgb(0 0 0 / 0.1), 0 8px 10px -6px rgb(0 0 0 / 0.1)"
94
+ },
95
+ { label: "2XL", value: "2xl", css: "0 25px 50px -12px rgb(0 0 0 / 0.25)" },
96
+ {
97
+ label: "Inner",
98
+ value: "inner",
99
+ css: "inset 0 2px 4px 0 rgb(0 0 0 / 0.05)"
100
+ }
101
+ ];
102
+ var getShadowCSS = (value) => {
103
+ const preset = shadowPresets.find((p) => p.value === value);
104
+ return preset?.css ?? "none";
105
+ };
106
+
107
+ export {
108
+ EntriesProvider,
109
+ useEntries,
110
+ ThemeProvider,
111
+ useTheme,
112
+ shadowPresets,
113
+ getShadowCSS
114
+ };
@@ -1,13 +1,16 @@
1
1
  import {
2
- cn,
3
2
  getShadowCSS,
4
- hexToRgba,
5
3
  useEntries,
6
4
  useTheme
7
- } from "./chunk-TTKY3YGP.mjs";
5
+ } from "./chunk-KV2RSRAM.mjs";
8
6
  import {
7
+ useGtmEvent,
9
8
  useUtmParams
10
9
  } from "./chunk-QSWQDR6M.mjs";
10
+ import {
11
+ cn,
12
+ hexToRgba
13
+ } from "./chunk-D3L26TIT.mjs";
11
14
 
12
15
  // components/page/Heading.tsx
13
16
  import { jsx } from "react/jsx-runtime";
@@ -162,7 +165,6 @@ function Paragraph({
162
165
  }
163
166
 
164
167
  // components/page/Button.tsx
165
- import { sendGTMEvent } from "@next/third-parties/google";
166
168
  import { jsx as jsx3 } from "react/jsx-runtime";
167
169
  var sizeStyles = {
168
170
  sm: { padding: "8px 16px", fontSize: "0.875rem" },
@@ -199,6 +201,7 @@ function Button({
199
201
  const { resolveColor: resolveColor2 } = useTheme();
200
202
  const { getEntryValue } = useEntries();
201
203
  const utm = useUtmParams();
204
+ const sendEvent = useGtmEvent();
202
205
  const resolvedText = (() => {
203
206
  if (!text) return "Button";
204
207
  if (typeof text === "string") return text;
@@ -212,15 +215,12 @@ function Button({
212
215
  })();
213
216
  const handleClick = () => {
214
217
  const sessionId = typeof window !== "undefined" ? sessionStorage.getItem("session_id") : null;
215
- sendGTMEvent({
216
- event: "button_click",
217
- value: {
218
- text: resolvedText,
219
- href: href || void 0,
220
- variant,
221
- session_id: sessionId,
222
- ...utm
223
- }
218
+ sendEvent("button_click", {
219
+ text: resolvedText,
220
+ href: href || void 0,
221
+ variant,
222
+ session_id: sessionId,
223
+ ...utm
224
224
  });
225
225
  };
226
226
  const resolvedColor = (() => {
@@ -435,7 +435,6 @@ function Image({
435
435
 
436
436
  // components/page/ImageCarousel.tsx
437
437
  import { useState } from "react";
438
- import { sendGTMEvent as sendGTMEvent2 } from "@next/third-parties/google";
439
438
  import { Fragment, jsx as jsx5, jsxs as jsxs2 } from "react/jsx-runtime";
440
439
  var aspectRatioMap2 = {
441
440
  "16:9": "16 / 9",
@@ -465,6 +464,7 @@ function ImageCarousel({
465
464
  const [currentIndex, setCurrentIndex] = useState(0);
466
465
  const { resolveColor: resolveColor2 } = useTheme();
467
466
  const utm = useUtmParams();
467
+ const sendEvent = useGtmEvent();
468
468
  const resolvedArrowColor = (() => {
469
469
  if (!arrowColor) return { color: "#FFFFFF", opacity: 100 };
470
470
  if (typeof arrowColor === "string")
@@ -487,39 +487,30 @@ function ImageCarousel({
487
487
  const goToPrevious = () => {
488
488
  const newIndex = currentIndex === 0 ? images.length - 1 : currentIndex - 1;
489
489
  setCurrentIndex(newIndex);
490
- sendGTMEvent2({
491
- event: "carousel_navigate",
492
- value: {
493
- direction: "previous",
494
- slideIndex: newIndex,
495
- totalSlides: images.length,
496
- ...utm
497
- }
490
+ sendEvent("carousel_navigate", {
491
+ direction: "previous",
492
+ slideIndex: newIndex,
493
+ totalSlides: images.length,
494
+ ...utm
498
495
  });
499
496
  };
500
497
  const goToNext = () => {
501
498
  const newIndex = currentIndex === images.length - 1 ? 0 : currentIndex + 1;
502
499
  setCurrentIndex(newIndex);
503
- sendGTMEvent2({
504
- event: "carousel_navigate",
505
- value: {
506
- direction: "next",
507
- slideIndex: newIndex,
508
- totalSlides: images.length,
509
- ...utm
510
- }
500
+ sendEvent("carousel_navigate", {
501
+ direction: "next",
502
+ slideIndex: newIndex,
503
+ totalSlides: images.length,
504
+ ...utm
511
505
  });
512
506
  };
513
507
  const goToSlide = (index) => {
514
508
  setCurrentIndex(index);
515
- sendGTMEvent2({
516
- event: "carousel_navigate",
517
- value: {
518
- direction: "direct",
519
- slideIndex: index,
520
- totalSlides: images.length,
521
- ...utm
522
- }
509
+ sendEvent("carousel_navigate", {
510
+ direction: "direct",
511
+ slideIndex: index,
512
+ totalSlides: images.length,
513
+ ...utm
523
514
  });
524
515
  };
525
516
  if (images.length === 0) {
@@ -1613,7 +1604,6 @@ function FeatureGrid({
1613
1604
 
1614
1605
  // components/page/Footer.tsx
1615
1606
  import { Facebook, Instagram, Twitter } from "lucide-react";
1616
- import { sendGTMEvent as sendGTMEvent3 } from "@next/third-parties/google";
1617
1607
  import { jsx as jsx18, jsxs as jsxs7 } from "react/jsx-runtime";
1618
1608
  function Footer({
1619
1609
  logo,
@@ -1627,6 +1617,7 @@ function Footer({
1627
1617
  }) {
1628
1618
  const DropZone = puck?.renderDropZone;
1629
1619
  const utm = useUtmParams();
1620
+ const sendEvent = useGtmEvent();
1630
1621
  const getSocialPlatform = (url) => {
1631
1622
  if (url.includes("facebook")) return "facebook";
1632
1623
  if (url.includes("instagram")) return "instagram";
@@ -1635,13 +1626,10 @@ function Footer({
1635
1626
  };
1636
1627
  const handleSocialClick = (url) => {
1637
1628
  const platform = getSocialPlatform(url);
1638
- sendGTMEvent3({
1639
- event: "social_click",
1640
- value: {
1641
- platform,
1642
- url,
1643
- ...utm
1644
- }
1629
+ sendEvent("social_click", {
1630
+ platform,
1631
+ url,
1632
+ ...utm
1645
1633
  });
1646
1634
  };
1647
1635
  const socialLinks = [
@@ -1679,9 +1667,7 @@ function Footer({
1679
1667
 
1680
1668
  // components/page/Topbar.tsx
1681
1669
  import { useState as useState2 } from "react";
1682
- import Link from "next/link";
1683
1670
  import { Menu, X } from "lucide-react";
1684
- import { sendGTMEvent as sendGTMEvent4 } from "@next/third-parties/google";
1685
1671
  import { jsx as jsx19, jsxs as jsxs8 } from "react/jsx-runtime";
1686
1672
  function Topbar({
1687
1673
  logo,
@@ -1695,26 +1681,21 @@ function Topbar({
1695
1681
  const DropZone = puck?.renderDropZone;
1696
1682
  const [mobileMenuOpen, setMobileMenuOpen] = useState2(false);
1697
1683
  const utm = useUtmParams();
1684
+ const sendEvent = useGtmEvent();
1698
1685
  const handleNavClick = (item) => {
1699
- sendGTMEvent4({
1700
- event: "nav_click",
1701
- value: {
1702
- name: item.name,
1703
- url: item.url,
1704
- linkType: item.linkType || "internal",
1705
- ...utm
1706
- }
1686
+ sendEvent("nav_click", {
1687
+ name: item.name,
1688
+ url: item.url,
1689
+ linkType: item.linkType || "internal",
1690
+ ...utm
1707
1691
  });
1708
1692
  };
1709
1693
  const handleMobileMenuToggle = () => {
1710
1694
  const newState = !mobileMenuOpen;
1711
1695
  setMobileMenuOpen(newState);
1712
- sendGTMEvent4({
1713
- event: "mobile_menu_toggle",
1714
- value: {
1715
- open: newState,
1716
- ...utm
1717
- }
1696
+ sendEvent("mobile_menu_toggle", {
1697
+ open: newState,
1698
+ ...utm
1718
1699
  });
1719
1700
  };
1720
1701
  const renderLink = (item, index) => {
@@ -1746,7 +1727,7 @@ function Topbar({
1746
1727
  );
1747
1728
  }
1748
1729
  return /* @__PURE__ */ jsx19(
1749
- Link,
1730
+ "a",
1750
1731
  {
1751
1732
  href: item.url,
1752
1733
  className,
@@ -1769,18 +1750,15 @@ function Topbar({
1769
1750
  style: { maxWidth },
1770
1751
  children: [
1771
1752
  /* @__PURE__ */ jsx19(
1772
- Link,
1753
+ "a",
1773
1754
  {
1774
1755
  href: logoUrl,
1775
1756
  className: "flex-shrink-0",
1776
- onClick: () => sendGTMEvent4({
1777
- event: "nav_click",
1778
- value: {
1779
- name: "logo",
1780
- url: logoUrl,
1781
- linkType: "internal",
1782
- ...utm
1783
- }
1757
+ onClick: () => sendEvent("nav_click", {
1758
+ name: "logo",
1759
+ url: logoUrl,
1760
+ linkType: "internal",
1761
+ ...utm
1784
1762
  }),
1785
1763
  children: logo ? /* @__PURE__ */ jsx19("img", { src: logo, alt: "Logo", className: "h-8" }) : /* @__PURE__ */ jsx19("span", { className: "text-xl font-bold", children: "Logo" })
1786
1764
  }
@@ -1812,7 +1790,6 @@ function Topbar({
1812
1790
  // components/page/Popup.tsx
1813
1791
  import { useState as useState3 } from "react";
1814
1792
  import { icons as icons4, X as X2 } from "lucide-react";
1815
- import { sendGTMEvent as sendGTMEvent5 } from "@next/third-parties/google";
1816
1793
  import { Fragment as Fragment2, jsx as jsx20, jsxs as jsxs9 } from "react/jsx-runtime";
1817
1794
  function Icon2({ name, ...props }) {
1818
1795
  const formatted = name.charAt(0).toUpperCase() + name.slice(1);
@@ -1843,23 +1820,18 @@ function Popup({
1843
1820
  }) {
1844
1821
  const [isOpen, setIsOpen] = useState3(false);
1845
1822
  const utm = useUtmParams();
1823
+ const sendEvent = useGtmEvent();
1846
1824
  const handleOpen = () => {
1847
1825
  setIsOpen(true);
1848
- sendGTMEvent5({
1849
- event: "popup_open",
1850
- value: {
1851
- ctaText,
1852
- type: textLink ? "link" : "button",
1853
- ...utm
1854
- }
1826
+ sendEvent("popup_open", {
1827
+ ctaText,
1828
+ type: textLink ? "link" : "button",
1829
+ ...utm
1855
1830
  });
1856
1831
  };
1857
1832
  const handleClose = () => {
1858
1833
  setIsOpen(false);
1859
- sendGTMEvent5({
1860
- event: "popup_close",
1861
- value: { ctaText, ...utm }
1862
- });
1834
+ sendEvent("popup_close", { ctaText, ...utm });
1863
1835
  };
1864
1836
  const trigger = textLink ? /* @__PURE__ */ jsx20(
1865
1837
  "button",