dune-react 0.0.8 → 0.0.9

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 (107) hide show
  1. package/dist/components/puck-base/article-card.js +1 -1
  2. package/dist/components/puck-base/container.d.ts +7 -1
  3. package/dist/components/puck-base/container.js +2 -1
  4. package/dist/components/puck-base/content.d.ts +1 -4
  5. package/dist/components/puck-base/content.js +15 -17
  6. package/dist/components/puck-base/core/types.d.ts +2 -2
  7. package/dist/components/puck-base/editor-context.d.ts +8 -0
  8. package/dist/components/puck-base/fields/auto-field.d.ts +1 -0
  9. package/dist/components/puck-base/fields/auto-field.js +131 -49
  10. package/dist/components/puck-base/gradient-text.js +12 -3
  11. package/dist/components/puck-block/banner-sections/announcement-banner-1/announcement-banner.js +1 -1
  12. package/dist/components/puck-block/contact-sections/api/form-leads.d.ts +16 -0
  13. package/dist/components/puck-block/contact-sections/api/form-leads.js +25 -0
  14. package/dist/components/puck-block/contact-sections/contact-us-1/contact-us.js +8 -16
  15. package/dist/components/puck-block/contact-sections/contact-us-2/contact-us-2.d.ts +26 -0
  16. package/dist/components/puck-block/contact-sections/contact-us-2/contact-us-2.js +229 -0
  17. package/dist/components/puck-block/contact-sections/contact-us-2/index.d.ts +5 -0
  18. package/dist/components/puck-block/contact-sections/contact-us-2/index.js +72 -0
  19. package/dist/components/puck-block/contact-sections/contact-us-3/contact-us-3.d.ts +29 -0
  20. package/dist/components/puck-block/contact-sections/contact-us-3/contact-us-3.js +245 -0
  21. package/dist/components/puck-block/contact-sections/contact-us-3/index.d.ts +5 -0
  22. package/dist/components/puck-block/contact-sections/contact-us-3/index.js +101 -0
  23. package/dist/components/puck-block/cta-sections/banner-cta-1/banner-cta.js +9 -8
  24. package/dist/components/puck-block/cta-sections/gradient-cta-1/gradient-cta.js +3 -3
  25. package/dist/components/puck-block/cta-sections/gradient-cta-1/index.js +4 -4
  26. package/dist/components/puck-block/cta-sections/newsletter-signup-1/newsletter-signup.js +5 -4
  27. package/dist/components/puck-block/cta-sections/promo-section-1/promo-section.js +6 -5
  28. package/dist/components/puck-block/faq-sections/faq-2/faq-2.d.ts +16 -0
  29. package/dist/components/puck-block/faq-sections/faq-2/faq-2.js +56 -0
  30. package/dist/components/puck-block/faq-sections/faq-2/index.d.ts +5 -0
  31. package/dist/components/puck-block/faq-sections/faq-2/index.js +62 -0
  32. package/dist/components/puck-block/feature-sections/feature-cards-1/feature-cards.d.ts +3 -4
  33. package/dist/components/puck-block/feature-sections/feature-cards-1/feature-cards.js +13 -3
  34. package/dist/components/puck-block/feature-sections/feature-cards-1/index.js +34 -14
  35. package/dist/components/puck-block/feature-sections/feature-showcase-1/feature-showcase.js +2 -8
  36. package/dist/components/puck-block/feature-sections/product-features-1/product-features.js +5 -25
  37. package/dist/components/puck-block/gallery-sections/gallery-1/gallery.js +3 -2
  38. package/dist/components/puck-block/gallery-sections/gallery-2/gallery-2.d.ts +14 -0
  39. package/dist/components/puck-block/gallery-sections/gallery-2/gallery-2.js +88 -0
  40. package/dist/components/puck-block/gallery-sections/gallery-2/index.d.ts +5 -0
  41. package/dist/components/puck-block/gallery-sections/gallery-2/index.js +44 -0
  42. package/dist/components/puck-block/gallery-sections/gallery-3/gallery-3.d.ts +17 -0
  43. package/dist/components/puck-block/gallery-sections/gallery-3/gallery-3.js +121 -0
  44. package/dist/components/puck-block/gallery-sections/gallery-3/index.d.ts +5 -0
  45. package/dist/components/puck-block/gallery-sections/gallery-3/index.js +60 -0
  46. package/dist/components/puck-block/hero-sections/fullscreen-hero-1/fullscreen-hero.d.ts +6 -1
  47. package/dist/components/puck-block/hero-sections/fullscreen-hero-1/fullscreen-hero.js +56 -20
  48. package/dist/components/puck-block/hero-sections/fullscreen-hero-1/index.js +12 -1
  49. package/dist/components/puck-block/hero-sections/gradient-hero-1/gradient-hero.d.ts +1 -1
  50. package/dist/components/puck-block/hero-sections/gradient-hero-1/gradient-hero.js +9 -6
  51. package/dist/components/puck-block/hero-sections/gradient-hero-1/index.js +4 -4
  52. package/dist/components/puck-block/hero-sections/image-hero-1/image-hero.d.ts +4 -1
  53. package/dist/components/puck-block/hero-sections/image-hero-1/image-hero.js +60 -62
  54. package/dist/components/puck-block/index.d.ts +15 -0
  55. package/dist/components/puck-block/location-sections/location-1/index.d.ts +5 -0
  56. package/dist/components/puck-block/location-sections/location-1/index.js +103 -0
  57. package/dist/components/puck-block/location-sections/location-1/location.d.ts +27 -0
  58. package/dist/components/puck-block/location-sections/location-1/location.js +143 -0
  59. package/dist/components/puck-block/location-sections/location-2/index.d.ts +5 -0
  60. package/dist/components/puck-block/location-sections/location-2/index.js +111 -0
  61. package/dist/components/puck-block/location-sections/location-2/location.d.ts +25 -0
  62. package/dist/components/puck-block/location-sections/location-2/location.js +136 -0
  63. package/dist/components/puck-block/location-sections/location-3/index.d.ts +5 -0
  64. package/dist/components/puck-block/location-sections/location-3/index.js +83 -0
  65. package/dist/components/puck-block/location-sections/location-3/location.d.ts +22 -0
  66. package/dist/components/puck-block/location-sections/location-3/location.js +129 -0
  67. package/dist/components/puck-block/metrics-sections/stats-2/index.d.ts +5 -0
  68. package/dist/components/puck-block/metrics-sections/stats-2/index.js +77 -0
  69. package/dist/components/puck-block/metrics-sections/stats-2/stats-2.d.ts +16 -0
  70. package/dist/components/puck-block/metrics-sections/stats-2/stats-2.js +59 -0
  71. package/dist/components/puck-block/metrics-sections/stats-3/index.d.ts +5 -0
  72. package/dist/components/puck-block/metrics-sections/stats-3/index.js +94 -0
  73. package/dist/components/puck-block/metrics-sections/stats-3/stats-3.d.ts +17 -0
  74. package/dist/components/puck-block/metrics-sections/stats-3/stats-3.js +60 -0
  75. package/dist/components/puck-block/pricing-sections/pricing-2/index.d.ts +5 -0
  76. package/dist/components/puck-block/pricing-sections/pricing-2/index.js +152 -0
  77. package/dist/components/puck-block/pricing-sections/pricing-2/pricing-2.d.ts +24 -0
  78. package/dist/components/puck-block/pricing-sections/pricing-2/pricing-2.js +68 -0
  79. package/dist/components/puck-block/showcase-sections/before-after-1/before-after.d.ts +20 -0
  80. package/dist/components/puck-block/showcase-sections/before-after-1/before-after.js +73 -0
  81. package/dist/components/puck-block/showcase-sections/before-after-1/index.d.ts +5 -0
  82. package/dist/components/puck-block/showcase-sections/before-after-1/index.js +74 -0
  83. package/dist/components/puck-block/showcase-sections/case-study-1/case-study.js +2 -8
  84. package/dist/components/puck-block/team-sections/team-grid-1/team-grid.js +4 -24
  85. package/dist/components/puck-block/team-sections/team-grid-2/index.d.ts +5 -0
  86. package/dist/components/puck-block/team-sections/team-grid-2/index.js +63 -0
  87. package/dist/components/puck-block/team-sections/team-grid-2/team-grid-2.d.ts +21 -0
  88. package/dist/components/puck-block/team-sections/team-grid-2/team-grid-2.js +46 -0
  89. package/dist/components/puck-block/team-sections/team-profiles-1/index.d.ts +5 -0
  90. package/dist/components/puck-block/team-sections/team-profiles-1/index.js +54 -0
  91. package/dist/components/puck-block/team-sections/team-profiles-1/team-profiles.d.ts +21 -0
  92. package/dist/components/puck-block/team-sections/team-profiles-1/team-profiles.js +107 -0
  93. package/dist/components/puck-block/testimonial-sections/logo-marquee-1/logo-marquee.js +2 -1
  94. package/dist/components/puck-block/testimonial-sections/logo-wall-1/index.d.ts +5 -0
  95. package/dist/components/puck-block/testimonial-sections/logo-wall-1/index.js +50 -0
  96. package/dist/components/puck-block/testimonial-sections/logo-wall-1/logo-wall.d.ts +15 -0
  97. package/dist/components/puck-block/testimonial-sections/logo-wall-1/logo-wall.js +57 -0
  98. package/dist/components/puck-block/testimonial-sections/review-section-1/review-section.js +3 -2
  99. package/dist/components/puck-block/text-sections/articles-1/articles.d.ts +1 -0
  100. package/dist/components/puck-block/text-sections/articles-1/articles.js +19 -6
  101. package/dist/components/puck-block/text-sections/articles-1/index.js +16 -4
  102. package/dist/components/puck-block/text-sections/content-section-1/content-section.js +5 -4
  103. package/dist/components/puck-block/text-sections/tab-section-1/tab-section.js +3 -2
  104. package/dist/components/shadcn/navigation-menu.d.ts +1 -1
  105. package/dist/components/shadcn/navigation-menu.js +33 -0
  106. package/dist/index.js +104 -74
  107. package/package.json +1 -1
@@ -10,7 +10,7 @@ const CompoundArticleCard = ({
10
10
  className
11
11
  }) => {
12
12
  return /* @__PURE__ */ jsxs("div", { className: cn("flex flex-col gap-4", className), children: [
13
- /* @__PURE__ */ jsx("div", { className: "bg-muted rounded-md aspect-video mb-2 overflow-hidden", children: (image == null ? void 0 : image.src) ? /* @__PURE__ */ jsx(CompoundImage, { src: image.src, alt: image.alt }) : null }),
13
+ image && /* @__PURE__ */ jsx("div", { className: "bg-muted mb-2 aspect-video overflow-hidden rounded-md [&>span]:h-full [&>span]:w-full", children: /* @__PURE__ */ jsx(CompoundImage, { src: image.src || "", alt: image.alt, className: "h-full w-full object-cover" }) }),
14
14
  !!heading || !!description || !!button ? /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
15
15
  heading ? /* @__PURE__ */ jsx("h3", { className: "text-xl tracking-tight", children: heading }) : null,
16
16
  description ? /* @__PURE__ */ jsx("p", { className: "text-muted-foreground max-w-xs text-base", children: description }) : null,
@@ -1,4 +1,4 @@
1
- import { ReactNode } from "react";
1
+ import { CSSProperties, ReactNode } from "react";
2
2
  type PaddingLevel = "none" | "small" | "medium" | "large";
3
3
  export type SectionStyle = "default" | "dark" | "muted" | "inverted" | "custom";
4
4
  export type OverlayStyle = "none" | "gradient-top" | "gradient-bottom" | "noise";
@@ -14,5 +14,11 @@ export interface CompoundContainerProps {
14
14
  overlay?: OverlayStyle;
15
15
  className?: string;
16
16
  }
17
+ /**
18
+ * Section-scoped CSS variable presets.
19
+ * These override the root-level CSS variables so child components
20
+ * using `bg-background`, `text-foreground` etc. automatically adapt.
21
+ */
22
+ export declare const SECTION_STYLE_VARS: Record<string, CSSProperties>;
17
23
  export declare const CompoundContainer: ({ children, padding, sectionStyle, backgroundColor, backgroundImage, overlay, className, }: CompoundContainerProps) => import("react/jsx-runtime").JSX.Element;
18
24
  export {};
@@ -86,5 +86,6 @@ const CompoundContainer = ({
86
86
  ) });
87
87
  };
88
88
  export {
89
- CompoundContainer
89
+ CompoundContainer,
90
+ SECTION_STYLE_VARS
90
91
  };
@@ -9,9 +9,6 @@ export interface CompoundContentProps {
9
9
  buttons?: CompoundButtonProps[];
10
10
  alignContent?: "start" | "center" | "end";
11
11
  className?: string;
12
- }
13
- interface CompoundContentPropsWithSpacing extends CompoundContentProps {
14
12
  spacing?: "normal" | "tight";
15
13
  }
16
- export declare const CompoundContent: ({ badge, heading, description, features, buttons, alignContent, className, spacing, }: CompoundContentPropsWithSpacing) => import("react/jsx-runtime").JSX.Element;
17
- export {};
14
+ export declare const CompoundContent: ({ badge, heading, description, features, buttons, alignContent, className, spacing, }: CompoundContentProps) => import("react/jsx-runtime").JSX.Element;
@@ -61,7 +61,7 @@ const CompoundContent = ({
61
61
  "h2",
62
62
  {
63
63
  className: cn(
64
- "text-3xl md:text-5xl tracking-tighter lg:max-w-xl font-regular",
64
+ "font-serif font-regular text-3xl tracking-tighter md:text-5xl lg:max-w-xl",
65
65
  textAlignClassnames
66
66
  ),
67
67
  children: heading
@@ -71,7 +71,7 @@ const CompoundContent = ({
71
71
  "p",
72
72
  {
73
73
  className: cn(
74
- "text-lg leading-relaxed tracking-tight text-muted-foreground",
74
+ "text-muted-foreground text-lg leading-relaxed tracking-tight",
75
75
  {
76
76
  "lg:max-w-sm": alignContent === "start" || alignContent === "end",
77
77
  "lg:max-w-xl": alignContent === "center"
@@ -86,7 +86,7 @@ const CompoundContent = ({
86
86
  DynamicIcon,
87
87
  {
88
88
  name: feature.icon,
89
- className: "w-6 h-6 shrink-0"
89
+ className: "h-6 w-6 shrink-0"
90
90
  }
91
91
  ) : null,
92
92
  /* @__PURE__ */ jsxs("div", { className: "flex flex-col", children: [
@@ -98,20 +98,18 @@ const CompoundContent = ({
98
98
  }
99
99
  )
100
100
  ] }) : null,
101
- Array.isArray(buttons) && buttons.length > 0 ? /* @__PURE__ */ jsx("div", { className: cn("gap-4 flex-wrap", rowPositionClassNames), children: buttons.map(
102
- (button, index) => button.label ? /* @__PURE__ */ jsx(
103
- CompoundButton,
104
- {
105
- label: button.label,
106
- url: button.url,
107
- action: button.action,
108
- variant: button.variant,
109
- size: button.size,
110
- icon: button.icon
111
- },
112
- index
113
- ) : null
114
- ) }) : null
101
+ Array.isArray(buttons) && buttons.length > 0 ? /* @__PURE__ */ jsx("div", { className: cn("flex-wrap gap-4", rowPositionClassNames), children: buttons.filter((button) => !!button.label).map((button, index) => /* @__PURE__ */ jsx(
102
+ CompoundButton,
103
+ {
104
+ label: button.label,
105
+ url: button.url,
106
+ action: button.action,
107
+ variant: button.variant,
108
+ size: button.size,
109
+ icon: button.icon
110
+ },
111
+ index
112
+ )) }) : null
115
113
  ]
116
114
  }
117
115
  );
@@ -5,12 +5,12 @@ export type Feature = {
5
5
  name: string;
6
6
  description?: string;
7
7
  };
8
- export type ActionType = "page" | "external" | "email" | "phone" | "section" | "download" | "none";
8
+ export type ActionType = "page" | "external" | "scroll" | "email" | "phone" | "section" | "download" | "none";
9
9
  export type Action = {
10
10
  type: ActionType;
11
11
  pageUrl?: string;
12
12
  externalUrl?: string;
13
- openInNewTab?: "true" | "false";
13
+ openInNewTab?: string;
14
14
  email?: string;
15
15
  subject?: string;
16
16
  phone?: string;
@@ -1,4 +1,10 @@
1
1
  import { type RefObject } from "react";
2
+ export type SitePage = {
3
+ /** 页面 slug,如 "about"、"pricing",用作路由值 */
4
+ slug: string;
5
+ /** 页面显示名,如 "关于我们"、"定价" */
6
+ label: string;
7
+ };
2
8
  type EditorContextValue = {
3
9
  openFieldsPanel: (componentId: string, componentType: string) => void;
4
10
  openAddSection: (index: number, zone: string) => void;
@@ -9,6 +15,8 @@ type EditorContextValue = {
9
15
  siteId?: string;
10
16
  /** 后台 API 域名,如 https://api.example.com */
11
17
  domain?: string;
18
+ /** 站内可选页面列表,用于 url 字段快捷选择 */
19
+ sitePages?: SitePage[];
12
20
  };
13
21
  export declare const EditorContextProvider: import("react").Provider<EditorContextValue>;
14
22
  export declare const useEditorContext: () => EditorContextValue;
@@ -1,2 +1,3 @@
1
1
  import type { AutoFieldProps } from "./types";
2
+ /** 按 field.type 分发控件;名为 url 且类型为 text 时固定使用 UrlField(链接 + 站内路由) */
2
3
  export declare const AutoField: import("react").NamedExoticComponent<AutoFieldProps>;
@@ -1,5 +1,5 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { memo, useState, useRef, useMemo, useCallback, useEffect } from "react";
2
+ import { memo, useCallback, useState, useRef, useMemo, useEffect } from "react";
3
3
  import { Input } from "../../shadcn/input.js";
4
4
  import { Textarea } from "../../shadcn/textarea.js";
5
5
  import { Label } from "../../shadcn/label.js";
@@ -8,7 +8,8 @@ import { Button } from "../../shadcn/button.js";
8
8
  import { Select, SelectTrigger, SelectValue, SelectContent, SelectItem } from "../../shadcn/select.js";
9
9
  import { Popover, PopoverTrigger, PopoverContent } from "../../shadcn/popover.js";
10
10
  import { ToggleGroup, ToggleGroupItem } from "../../shadcn/toggle-group.js";
11
- import { ChevronDownIcon, CheckIcon } from "lucide-react";
11
+ import { LinkIcon, XIcon, ClipboardIcon, GlobeIcon, ChevronDownIcon, CheckIcon } from "lucide-react";
12
+ import { useEditorContext } from "../editor-context.js";
12
13
  const LARGE_SELECT_THRESHOLD = 200;
13
14
  const VIRTUAL_ITEM_HEIGHT = 32;
14
15
  const VIRTUAL_VIEWPORT_HEIGHT = 256;
@@ -159,62 +160,131 @@ const VirtualizedSelectField = memo(function VirtualizedSelectField2({
159
160
  ]
160
161
  }
161
162
  ) }),
162
- /* @__PURE__ */ jsxs(
163
- PopoverContent,
164
- {
165
- className: "w-(--radix-popover-trigger-width) p-2",
166
- children: [
167
- /* @__PURE__ */ jsx(
168
- Input,
169
- {
170
- value: search,
171
- onChange: (e) => setSearch(e.target.value),
172
- placeholder: "Search options...",
173
- className: "mb-2"
174
- }
175
- ),
176
- /* @__PURE__ */ jsx(
163
+ /* @__PURE__ */ jsxs(PopoverContent, { className: "w-(--radix-popover-trigger-width) p-2", children: [
164
+ /* @__PURE__ */ jsx(
165
+ Input,
166
+ {
167
+ value: search,
168
+ onChange: (e) => setSearch(e.target.value),
169
+ placeholder: "Search options...",
170
+ className: "mb-2"
171
+ }
172
+ ),
173
+ /* @__PURE__ */ jsx(
174
+ "div",
175
+ {
176
+ ref: viewportRef,
177
+ className: "relative touch-pan-y overflow-y-auto overscroll-contain rounded-md border",
178
+ style: {
179
+ height: VIRTUAL_VIEWPORT_HEIGHT,
180
+ WebkitOverflowScrolling: "touch"
181
+ },
182
+ onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
183
+ children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground p-3 text-sm", children: "No options found." }) : /* @__PURE__ */ jsx("div", { style: { height: totalHeight, position: "relative" }, children: /* @__PURE__ */ jsx(
177
184
  "div",
178
185
  {
179
- ref: viewportRef,
180
- className: "relative touch-pan-y overflow-y-auto overscroll-contain rounded-md border",
181
186
  style: {
182
- height: VIRTUAL_VIEWPORT_HEIGHT,
183
- WebkitOverflowScrolling: "touch"
187
+ position: "absolute",
188
+ top: startIndex * VIRTUAL_ITEM_HEIGHT,
189
+ left: 0,
190
+ right: 0
184
191
  },
185
- onScroll: (e) => setScrollTop(e.currentTarget.scrollTop),
186
- children: filteredOptions.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-muted-foreground p-3 text-sm", children: "No options found." }) : /* @__PURE__ */ jsx("div", { style: { height: totalHeight, position: "relative" }, children: /* @__PURE__ */ jsx(
187
- "div",
188
- {
189
- style: {
190
- position: "absolute",
191
- top: startIndex * VIRTUAL_ITEM_HEIGHT,
192
- left: 0,
193
- right: 0
192
+ children: visibleOptions.map((opt) => {
193
+ const isSelected = opt.stringValue === selectedString;
194
+ return /* @__PURE__ */ jsxs(
195
+ "button",
196
+ {
197
+ type: "button",
198
+ className: "hover:bg-accent hover:text-accent-foreground flex h-8 w-full items-center justify-between px-2 text-left text-sm",
199
+ onClick: () => handleSelect(opt.stringValue),
200
+ children: [
201
+ /* @__PURE__ */ jsx("span", { className: "truncate", children: opt.label }),
202
+ isSelected ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-primary ml-2 size-4 shrink-0" }) : null
203
+ ]
194
204
  },
195
- children: visibleOptions.map((opt) => {
196
- const isSelected = opt.stringValue === selectedString;
197
- return /* @__PURE__ */ jsxs(
198
- "button",
199
- {
200
- type: "button",
201
- className: "hover:bg-accent hover:text-accent-foreground flex h-8 w-full items-center justify-between px-2 text-left text-sm",
202
- onClick: () => handleSelect(opt.stringValue),
203
- children: [
204
- /* @__PURE__ */ jsx("span", { className: "truncate", children: opt.label }),
205
- isSelected ? /* @__PURE__ */ jsx(CheckIcon, { className: "text-primary ml-2 size-4 shrink-0" }) : null
206
- ]
207
- },
208
- opt.stringValue
209
- );
210
- })
211
- }
212
- ) })
205
+ opt.stringValue
206
+ );
207
+ })
213
208
  }
214
- )
209
+ ) })
210
+ }
211
+ )
212
+ ] })
213
+ ] })
214
+ ] });
215
+ });
216
+ const UrlField = memo(function UrlField2({
217
+ label,
218
+ value,
219
+ onChange,
220
+ sitePages
221
+ }) {
222
+ const currentValue = value ?? "";
223
+ const selectedSlug = currentValue.startsWith("/") ? currentValue.slice(1) : null;
224
+ const handlePaste = useCallback(async () => {
225
+ try {
226
+ const text = await navigator.clipboard.readText();
227
+ if (text) onChange(text.trim());
228
+ } catch {
229
+ }
230
+ }, [onChange]);
231
+ return /* @__PURE__ */ jsxs("div", { className: "mb-4 space-y-3", children: [
232
+ /* @__PURE__ */ jsx(Label, { children: label }),
233
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", children: [
234
+ /* @__PURE__ */ jsxs("div", { className: "flex flex-1 items-center gap-2 rounded-lg border px-3 py-2", children: [
235
+ /* @__PURE__ */ jsx(LinkIcon, { className: "text-muted-foreground size-4 shrink-0" }),
236
+ /* @__PURE__ */ jsx(
237
+ "input",
238
+ {
239
+ className: "w-full bg-transparent text-sm outline-none placeholder:text-muted-foreground",
240
+ placeholder: "https:// or /page-slug",
241
+ value: currentValue,
242
+ onChange: (e) => onChange(e.target.value)
243
+ }
244
+ ),
245
+ currentValue && /* @__PURE__ */ jsx(
246
+ "button",
247
+ {
248
+ type: "button",
249
+ className: "text-muted-foreground hover:text-foreground shrink-0",
250
+ onClick: () => onChange(""),
251
+ children: /* @__PURE__ */ jsx(XIcon, { className: "size-3.5" })
252
+ }
253
+ )
254
+ ] }),
255
+ /* @__PURE__ */ jsxs(
256
+ Button,
257
+ {
258
+ type: "button",
259
+ variant: "outline",
260
+ size: "sm",
261
+ className: "shrink-0 gap-1.5",
262
+ onClick: handlePaste,
263
+ children: [
264
+ /* @__PURE__ */ jsx(ClipboardIcon, { className: "size-3.5" }),
265
+ "Paste"
215
266
  ]
216
267
  }
217
268
  )
269
+ ] }),
270
+ sitePages.length > 0 && /* @__PURE__ */ jsxs("div", { className: "space-y-2", children: [
271
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground text-xs font-medium", children: "Site pages" }),
272
+ /* @__PURE__ */ jsx("div", { className: "flex flex-wrap gap-2", children: sitePages.map((page) => {
273
+ const isSelected = selectedSlug === page.slug;
274
+ return /* @__PURE__ */ jsxs(
275
+ "button",
276
+ {
277
+ type: "button",
278
+ className: `inline-flex items-center gap-1.5 rounded-full border px-3 py-1 text-xs font-medium transition-colors ${isSelected ? "border-primary bg-primary text-primary-foreground" : "border-border bg-background text-foreground hover:bg-accent"}`,
279
+ onClick: () => onChange(isSelected ? "" : `${page.slug}`),
280
+ children: [
281
+ /* @__PURE__ */ jsx(GlobeIcon, { className: "size-3" }),
282
+ page.label
283
+ ]
284
+ },
285
+ page.slug
286
+ );
287
+ }) })
218
288
  ] })
219
289
  ] });
220
290
  });
@@ -226,6 +296,18 @@ const AutoField = memo(function AutoField2({
226
296
  }) {
227
297
  var _a, _b;
228
298
  const label = field.label || name;
299
+ const { sitePages } = useEditorContext();
300
+ if (name === "url" && field.type === "text") {
301
+ return /* @__PURE__ */ jsx(
302
+ UrlField,
303
+ {
304
+ label,
305
+ value,
306
+ onChange,
307
+ sitePages: sitePages ?? []
308
+ }
309
+ );
310
+ }
229
311
  switch (field.type) {
230
312
  case "text":
231
313
  return /* @__PURE__ */ jsxs("div", { className: "mb-4 space-y-1.5", children: [
@@ -8,17 +8,26 @@ const TAG_STYLES = {
8
8
  p: "text-base md:text-lg",
9
9
  span: ""
10
10
  };
11
+ const DIRECTION_MAP = {
12
+ "to-r": "to right",
13
+ "to-l": "to left",
14
+ "to-t": "to top",
15
+ "to-b": "to bottom",
16
+ "to-br": "to bottom right",
17
+ "to-bl": "to bottom left"
18
+ };
11
19
  const GradientText = ({
12
20
  text,
13
21
  as: Tag = "h2",
14
- gradientFrom = "oklch(0.7 0.25 260)",
15
- gradientTo = "oklch(0.7 0.25 330)",
22
+ gradientFrom = "var(--primary)",
23
+ gradientTo = "var(--chart-2)",
16
24
  gradientVia,
17
25
  direction = "to-r",
18
26
  className
19
27
  }) => {
28
+ const cssDirection = DIRECTION_MAP[direction] ?? "to right";
20
29
  const gradientStyle = {
21
- backgroundImage: gradientVia ? `linear-gradient(${direction.replace("to-", "to ")}, ${gradientFrom}, ${gradientVia}, ${gradientTo})` : `linear-gradient(${direction.replace("to-", "to ")}, ${gradientFrom}, ${gradientTo})`
30
+ backgroundImage: gradientVia ? `linear-gradient(${cssDirection}, ${gradientFrom}, ${gradientVia}, ${gradientTo})` : `linear-gradient(${cssDirection}, ${gradientFrom}, ${gradientTo})`
22
31
  };
23
32
  return /* @__PURE__ */ jsx(
24
33
  Tag,
@@ -4,7 +4,7 @@ const AnnouncementBanner = ({
4
4
  text,
5
5
  linkText,
6
6
  linkUrl,
7
- backgroundColor = "oklch(0.85 0.15 85)",
7
+ backgroundColor = "var(--primary)",
8
8
  textColor,
9
9
  align = "center",
10
10
  size = "default"
@@ -0,0 +1,16 @@
1
+ /**
2
+ * 联系表单线索:POST 到 `{domain}/api/form-leads`,与站点后端约定一致。
3
+ */
4
+ export interface SubmitFormLeadBody {
5
+ site_id?: string | null;
6
+ name: string;
7
+ email: string;
8
+ phone: string;
9
+ message: string;
10
+ /** 当前页路径,用于归因 */
11
+ source_page: string;
12
+ }
13
+ /**
14
+ * 提交表单线索。成功 resolve;HTTP 非 2xx 或业务 success !== true 时 throw Error(message 为 errMsg 或 HTTP 状态)。
15
+ */
16
+ export declare function submitFormLead(domain: string | undefined | null, body: SubmitFormLeadBody): Promise<void>;
@@ -0,0 +1,25 @@
1
+ function normalizeBaseUrl(domain) {
2
+ return (domain ?? "").replace(/\/$/, "");
3
+ }
4
+ async function submitFormLead(domain, body) {
5
+ const baseUrl = normalizeBaseUrl(domain);
6
+ const res = await fetch(`${baseUrl}/api/form-leads`, {
7
+ method: "POST",
8
+ headers: { "Content-Type": "application/json" },
9
+ body: JSON.stringify({
10
+ site_id: body.site_id,
11
+ name: body.name || "",
12
+ email: body.email || "",
13
+ phone: body.phone || "",
14
+ message: body.message || "",
15
+ source_page: body.source_page
16
+ })
17
+ });
18
+ const data = await res.json().catch(() => null);
19
+ if (!res.ok || !(data == null ? void 0 : data.success)) {
20
+ throw new Error((data == null ? void 0 : data.errMsg) || `HTTP ${res.status}`);
21
+ }
22
+ }
23
+ export {
24
+ submitFormLead
25
+ };
@@ -9,6 +9,7 @@ import { Input } from "../../../shadcn/input.js";
9
9
  import { Label } from "../../../shadcn/label.js";
10
10
  import { Textarea } from "../../../shadcn/textarea.js";
11
11
  import { useEditorContext } from "../../../puck-base/editor-context.js";
12
+ import { submitFormLead } from "../api/form-leads.js";
12
13
  const DEFAULT_FIELDS = [
13
14
  { label: "Name", name: "name", type: "text", required: true },
14
15
  { label: "Email", name: "email", type: "email", required: true },
@@ -28,23 +29,14 @@ const ContactUs = (props) => {
28
29
  if (isEditorMode) return;
29
30
  setSubmitting(true);
30
31
  try {
31
- const baseUrl = (domain || "").replace(/\/$/, "");
32
- const res = await fetch(`${baseUrl}/api/form-leads`, {
33
- method: "POST",
34
- headers: { "Content-Type": "application/json" },
35
- body: JSON.stringify({
36
- site_id: siteId,
37
- name: values.name || "",
38
- email: values.email || "",
39
- phone: values.phone || "",
40
- message: values.message || "",
41
- source_page: typeof window !== "undefined" ? window.location.pathname : ""
42
- })
32
+ await submitFormLead(domain, {
33
+ site_id: siteId,
34
+ name: values.name || "",
35
+ email: values.email || "",
36
+ phone: values.phone || "",
37
+ message: values.message || "",
38
+ source_page: typeof window !== "undefined" ? window.location.pathname : ""
43
39
  });
44
- const data = await res.json().catch(() => null);
45
- if (!res.ok || !(data == null ? void 0 : data.success)) {
46
- throw new Error((data == null ? void 0 : data.errMsg) || `HTTP ${res.status}`);
47
- }
48
40
  toast.success("Message sent successfully!");
49
41
  setValues({});
50
42
  } catch (err) {
@@ -0,0 +1,26 @@
1
+ import { CompoundContainerProps } from "@/components/puck-base/container";
2
+ export interface ContactUs2Button {
3
+ label: string;
4
+ variant?: string;
5
+ size?: string;
6
+ icon?: string;
7
+ }
8
+ export interface ContactUs2Props {
9
+ heading?: string;
10
+ description?: string;
11
+ nameLabel?: string;
12
+ emailLabel?: string;
13
+ phoneLabel?: string;
14
+ companyLabel?: string;
15
+ messageLabel?: string;
16
+ button?: ContactUs2Button;
17
+ image?: {
18
+ src: string;
19
+ alt: string;
20
+ };
21
+ imagePosition?: "start" | "end";
22
+ padding?: CompoundContainerProps["padding"];
23
+ sectionStyle?: CompoundContainerProps["sectionStyle"];
24
+ backgroundColor?: string;
25
+ }
26
+ export declare const ContactUs2: ({ heading, description, nameLabel, emailLabel, phoneLabel, companyLabel, messageLabel, button, image, imagePosition, padding, sectionStyle, backgroundColor, }: ContactUs2Props) => import("react/jsx-runtime").JSX.Element;