@frontlit/page-builder 0.1.0-alpha.2 → 0.1.0-alpha.4
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.
- package/README.md +32 -0
- package/dist/blocks/index.d.ts +33 -21
- package/dist/blocks/index.js +3 -3
- package/dist/builder/index.d.ts +7 -8
- package/dist/builder/index.js +6 -5
- package/dist/{button-Bzt1GDO-.d.ts → button-OLKN3wPf.d.ts} +2 -2
- package/dist/{chunk-H4P5MFJI.js → chunk-36QHCIPM.js} +205 -251
- package/dist/chunk-36QHCIPM.js.map +1 -0
- package/dist/chunk-BBI7UHOA.js +56 -0
- package/dist/chunk-BBI7UHOA.js.map +1 -0
- package/dist/{chunk-KQKSLI3L.js → chunk-GIKTOAQS.js} +335 -122
- package/dist/chunk-GIKTOAQS.js.map +1 -0
- package/dist/chunk-HWOVSHIW.js +4 -0
- package/dist/{chunk-RUYOL7JZ.js.map → chunk-HWOVSHIW.js.map} +1 -1
- package/dist/{chunk-HDINUNI2.js → chunk-IU4KATI2.js} +69 -96
- package/dist/chunk-IU4KATI2.js.map +1 -0
- package/dist/{chunk-SGNRWWG3.js → chunk-J7Z4UW45.js} +530 -135
- package/dist/chunk-J7Z4UW45.js.map +1 -0
- package/dist/{chunk-UO7XGBGM.js → chunk-K4WCLHMS.js} +1182 -1033
- package/dist/chunk-K4WCLHMS.js.map +1 -0
- package/dist/components/index.d.ts +33 -8
- package/dist/components/index.js +42 -2
- package/dist/components/index.js.map +1 -1
- package/dist/data-slots.d.ts +3 -3
- package/dist/fonts/archivo/archivo-latin-variable.woff2 +0 -0
- package/dist/fonts/hanken-grotesk/hanken-grotesk-latin-variable.woff2 +0 -0
- package/dist/fonts/jetbrains-mono/jetbrains-mono-latin-variable.woff2 +0 -0
- package/dist/fonts/spline-sans-mono/spline-sans-mono-latin-variable.woff2 +0 -0
- package/dist/heading-DQCxQt38.d.ts +20 -0
- package/dist/image-Bk8kPXwP.d.ts +52 -0
- package/dist/index.d.ts +17 -10
- package/dist/index.js +7 -6
- package/dist/models/index.d.ts +5 -5
- package/dist/models/index.js +1 -1
- package/dist/{page-W3hQga4w.d.ts → page-B5Gmm-Ys.d.ts} +1 -1
- package/dist/primitives/index.d.ts +44 -9
- package/dist/primitives/index.js +1 -1
- package/dist/renderer/index.d.ts +12 -8
- package/dist/renderer/index.js +5 -4
- package/dist/{section-background-MsdE40Rk.d.ts → section-background-6V_LCi5e.d.ts} +1 -1
- package/dist/server/index.d.ts +103 -0
- package/dist/server/index.js +2649 -0
- package/dist/server/index.js.map +1 -0
- package/dist/server/islands/code-snippet.d.ts +17 -0
- package/dist/server/islands/code-snippet.js +72 -0
- package/dist/server/islands/code-snippet.js.map +1 -0
- package/dist/server/islands/email-form.d.ts +50 -0
- package/dist/server/islands/email-form.js +406 -0
- package/dist/server/islands/email-form.js.map +1 -0
- package/dist/server/islands/header-mobile-menu.d.ts +22 -0
- package/dist/server/islands/header-mobile-menu.js +422 -0
- package/dist/server/islands/header-mobile-menu.js.map +1 -0
- package/dist/server/islands/inline-embed.d.ts +28 -0
- package/dist/server/islands/inline-embed.js +84 -0
- package/dist/server/islands/inline-embed.js.map +1 -0
- package/dist/server/islands/marquee-track.d.ts +18 -0
- package/dist/server/islands/marquee-track.js +67 -0
- package/dist/server/islands/marquee-track.js.map +1 -0
- package/dist/server/islands/nav-link.d.ts +37 -0
- package/dist/server/islands/nav-link.js +67 -0
- package/dist/server/islands/nav-link.js.map +1 -0
- package/dist/server/islands/support-form.d.ts +17 -0
- package/dist/server/islands/support-form.js +469 -0
- package/dist/server/islands/support-form.js.map +1 -0
- package/dist/server/islands/theme-mode-switcher.d.ts +38 -0
- package/dist/server/islands/theme-mode-switcher.js +169 -0
- package/dist/server/islands/theme-mode-switcher.js.map +1 -0
- package/dist/server/islands/video-with-preview.d.ts +13 -0
- package/dist/server/islands/video-with-preview.js +269 -0
- package/dist/server/islands/video-with-preview.js.map +1 -0
- package/dist/server/primitives.d.ts +200 -0
- package/dist/server/primitives.js +888 -0
- package/dist/server/primitives.js.map +1 -0
- package/dist/server/schema.d.ts +11308 -0
- package/dist/server/schema.js +6179 -0
- package/dist/server/schema.js.map +1 -0
- package/dist/server/theme-CF3fIKvw.d.ts +9 -0
- package/dist/server/theme-style-5_AGy-4V.d.ts +183 -0
- package/dist/server/theme-style-BPaMwk88.d.ts +183 -0
- package/dist/server/theme.d.ts +28 -0
- package/dist/server/theme.js +1671 -0
- package/dist/server/theme.js.map +1 -0
- package/dist/server/widget-YH9BrOwY.d.ts +77 -0
- package/dist/styles.css +121 -15
- package/dist/{theme-style-Cbl7NM-T.d.ts → theme-style-BVd5tOsc.d.ts} +20 -0
- package/dist/theme.css +12 -0
- package/dist/{widget-B_RoG6se.d.ts → widget-CpE2HdgU.d.ts} +17 -14
- package/package.json +60 -12
- package/schema/page.v1.json +3855 -0
- package/schema/site.v1.json +3811 -0
- package/dist/alignment-dZDzN96G.d.ts +0 -5
- package/dist/chunk-H4P5MFJI.js.map +0 -1
- package/dist/chunk-HDINUNI2.js.map +0 -1
- package/dist/chunk-KQKSLI3L.js.map +0 -1
- package/dist/chunk-RUYOL7JZ.js +0 -4
- package/dist/chunk-SGNRWWG3.js.map +0 -1
- package/dist/chunk-UO7XGBGM.js.map +0 -1
- package/dist/image-DAWVx1zQ.d.ts +0 -31
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
// src/blocks/marquee/marquee-track.tsx
|
|
5
|
+
import { useEffect, useId, useRef, useState } from "react";
|
|
6
|
+
|
|
7
|
+
// src/primitives/lib/utils.ts
|
|
8
|
+
import { clsx } from "clsx";
|
|
9
|
+
import { twMerge } from "tailwind-merge";
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return twMerge(clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/blocks/marquee/marquee-track.tsx
|
|
15
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
16
|
+
function MarqueeTrack({
|
|
17
|
+
children,
|
|
18
|
+
speed,
|
|
19
|
+
direction,
|
|
20
|
+
pauseOnHover
|
|
21
|
+
}) {
|
|
22
|
+
const containerRef = useRef(null);
|
|
23
|
+
const contentRef = useRef(null);
|
|
24
|
+
const [containerWidth, setContainerWidth] = useState(0);
|
|
25
|
+
const [contentWidth, setContentWidth] = useState(0);
|
|
26
|
+
const animationName = `pb-marquee-${useId().replace(/[^a-zA-Z0-9]/g, "")}`;
|
|
27
|
+
useEffect(() => {
|
|
28
|
+
const measure = () => {
|
|
29
|
+
setContainerWidth(containerRef.current?.offsetWidth ?? 0);
|
|
30
|
+
setContentWidth(contentRef.current?.offsetWidth ?? 0);
|
|
31
|
+
};
|
|
32
|
+
measure();
|
|
33
|
+
window.addEventListener("resize", measure);
|
|
34
|
+
return () => window.removeEventListener("resize", measure);
|
|
35
|
+
}, [children, speed]);
|
|
36
|
+
const duration = contentWidth > 0 ? contentWidth / speed : 0;
|
|
37
|
+
const duplicatesNeeded = contentWidth > 0 ? Math.max(2, Math.ceil(containerWidth * 2 / contentWidth)) : 2;
|
|
38
|
+
return /* @__PURE__ */ jsxs("div", { ref: containerRef, className: "w-full overflow-hidden", children: [
|
|
39
|
+
contentWidth > 0 && /* @__PURE__ */ jsx("style", { children: `
|
|
40
|
+
@keyframes ${animationName} {
|
|
41
|
+
from { transform: translateX(0); }
|
|
42
|
+
to { transform: translateX(-${contentWidth}px); }
|
|
43
|
+
}
|
|
44
|
+
` }),
|
|
45
|
+
/* @__PURE__ */ jsxs(
|
|
46
|
+
"div",
|
|
47
|
+
{
|
|
48
|
+
className: cn(
|
|
49
|
+
"inline-flex w-max",
|
|
50
|
+
pauseOnHover && "hover:[animation-play-state:paused]"
|
|
51
|
+
),
|
|
52
|
+
style: contentWidth > 0 ? {
|
|
53
|
+
animation: `${animationName} ${duration}s linear infinite`,
|
|
54
|
+
animationDirection: direction === "left" ? "reverse" : "normal"
|
|
55
|
+
} : void 0,
|
|
56
|
+
children: [
|
|
57
|
+
/* @__PURE__ */ jsx("div", { ref: contentRef, className: "inline-flex shrink-0", children }),
|
|
58
|
+
Array.from({ length: duplicatesNeeded }).map((_, i) => /* @__PURE__ */ jsx("div", { className: "inline-flex shrink-0", "aria-hidden": true, children }, i))
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
)
|
|
62
|
+
] });
|
|
63
|
+
}
|
|
64
|
+
export {
|
|
65
|
+
MarqueeTrack
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=marquee-track.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/blocks/marquee/marquee-track.tsx","../../../src/primitives/lib/utils.ts"],"sourcesContent":["\"use client\";\n\nimport React, { useEffect, useId, useRef, useState } from \"react\";\nimport { cn } from \"../../primitives/lib/utils\";\n\n/**\n * Infinite horizontal scroller. Measures the width of one copy of the\n * content, then renders enough duplicate copies to always cover at least\n * twice the container's width, and animates a translateX loop across\n * exactly one content-width — because the duplicates repeat the same\n * sequence, the loop point is visually seamless regardless of how the\n * content width compares to the container width.\n */\nexport function MarqueeTrack({\n children,\n speed,\n direction,\n pauseOnHover,\n}: {\n children: React.ReactNode;\n speed: number;\n direction: \"left\" | \"right\";\n pauseOnHover?: boolean;\n}) {\n const containerRef = useRef<HTMLDivElement>(null);\n const contentRef = useRef<HTMLDivElement>(null);\n const [containerWidth, setContainerWidth] = useState(0);\n const [contentWidth, setContentWidth] = useState(0);\n const animationName = `pb-marquee-${useId().replace(/[^a-zA-Z0-9]/g, \"\")}`;\n\n useEffect(() => {\n const measure = () => {\n setContainerWidth(containerRef.current?.offsetWidth ?? 0);\n setContentWidth(contentRef.current?.offsetWidth ?? 0);\n };\n measure();\n window.addEventListener(\"resize\", measure);\n return () => window.removeEventListener(\"resize\", measure);\n }, [children, speed]);\n\n const duration = contentWidth > 0 ? contentWidth / speed : 0;\n const duplicatesNeeded =\n contentWidth > 0 ? Math.max(2, Math.ceil((containerWidth * 2) / contentWidth)) : 2;\n\n return (\n <div ref={containerRef} className=\"w-full overflow-hidden\">\n {contentWidth > 0 && (\n <style>{`\n @keyframes ${animationName} {\n from { transform: translateX(0); }\n to { transform: translateX(-${contentWidth}px); }\n }\n `}</style>\n )}\n <div\n className={cn(\n \"inline-flex w-max\",\n pauseOnHover && \"hover:[animation-play-state:paused]\",\n )}\n style={\n contentWidth > 0\n ? {\n animation: `${animationName} ${duration}s linear infinite`,\n animationDirection: direction === \"left\" ? \"reverse\" : \"normal\",\n }\n : undefined\n }\n >\n <div ref={contentRef} className=\"inline-flex shrink-0\">\n {children}\n </div>\n {Array.from({ length: duplicatesNeeded }).map((_, i) => (\n <div key={i} className=\"inline-flex shrink-0\" aria-hidden>\n {children}\n </div>\n ))}\n </div>\n </div>\n );\n}\n","import { type ClassValue, clsx } from \"clsx\";\nimport { twMerge } from \"tailwind-merge\";\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs));\n}\n"],"mappings":";;;;AAEA,SAAgB,WAAW,OAAO,QAAQ,gBAAgB;;;ACF1D,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;AD0CQ,cAOF,YAPE;AAlCD,SAAS,aAAa;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAKG;AACD,QAAM,eAAe,OAAuB,IAAI;AAChD,QAAM,aAAa,OAAuB,IAAI;AAC9C,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,CAAC;AACtD,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,CAAC;AAClD,QAAM,gBAAgB,cAAc,MAAM,EAAE,QAAQ,iBAAiB,EAAE,CAAC;AAExE,YAAU,MAAM;AACd,UAAM,UAAU,MAAM;AACpB,wBAAkB,aAAa,SAAS,eAAe,CAAC;AACxD,sBAAgB,WAAW,SAAS,eAAe,CAAC;AAAA,IACtD;AACA,YAAQ;AACR,WAAO,iBAAiB,UAAU,OAAO;AACzC,WAAO,MAAM,OAAO,oBAAoB,UAAU,OAAO;AAAA,EAC3D,GAAG,CAAC,UAAU,KAAK,CAAC;AAEpB,QAAM,WAAW,eAAe,IAAI,eAAe,QAAQ;AAC3D,QAAM,mBACJ,eAAe,IAAI,KAAK,IAAI,GAAG,KAAK,KAAM,iBAAiB,IAAK,YAAY,CAAC,IAAI;AAEnF,SACE,qBAAC,SAAI,KAAK,cAAc,WAAU,0BAC/B;AAAA,mBAAe,KACd,oBAAC,WAAO;AAAA,iCACiB,aAAa;AAAA;AAAA,sDAEQ,YAAY;AAAA;AAAA,mBAEhD;AAAA,IAEZ;AAAA,MAAC;AAAA;AAAA,QACC,WAAW;AAAA,UACT;AAAA,UACA,gBAAgB;AAAA,QAClB;AAAA,QACA,OACE,eAAe,IACX;AAAA,UACE,WAAW,GAAG,aAAa,IAAI,QAAQ;AAAA,UACvC,oBAAoB,cAAc,SAAS,YAAY;AAAA,QACzD,IACA;AAAA,QAGN;AAAA,8BAAC,SAAI,KAAK,YAAY,WAAU,wBAC7B,UACH;AAAA,UACC,MAAM,KAAK,EAAE,QAAQ,iBAAiB,CAAC,EAAE,IAAI,CAAC,GAAG,MAChD,oBAAC,SAAY,WAAU,wBAAuB,eAAW,MACtD,YADO,CAEV,CACD;AAAA;AAAA;AAAA,IACH;AAAA,KACF;AAEJ;","names":[]}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
interface PageBuilderLinkProps {
|
|
4
|
+
href: string;
|
|
5
|
+
children?: React.ReactNode;
|
|
6
|
+
className?: string;
|
|
7
|
+
style?: React.CSSProperties;
|
|
8
|
+
onClick?: React.MouseEventHandler<HTMLAnchorElement>;
|
|
9
|
+
target?: string;
|
|
10
|
+
rel?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Optional host-supplied link. Next.js apps can pass `next/link`; Vite / Remix
|
|
14
|
+
* / plain React hosts can omit it and NavLink will render a native `<a>`.
|
|
15
|
+
*/
|
|
16
|
+
type PageBuilderLinkComponent = React.ComponentType<PageBuilderLinkProps>;
|
|
17
|
+
declare function PageBuilderLinkProvider({ component, children, }: {
|
|
18
|
+
component?: PageBuilderLinkComponent | null;
|
|
19
|
+
children: React.ReactNode;
|
|
20
|
+
}): React.JSX.Element;
|
|
21
|
+
declare function usePageBuilderLinkComponent(): PageBuilderLinkComponent;
|
|
22
|
+
interface NavLinkProps {
|
|
23
|
+
href: string;
|
|
24
|
+
children?: React.ReactNode;
|
|
25
|
+
openInSameTab?: boolean;
|
|
26
|
+
style?: React.CSSProperties;
|
|
27
|
+
className?: string;
|
|
28
|
+
onClick?: () => void;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* A navigation-aware link used inside block widgets. In-page anchors scroll
|
|
32
|
+
* to the target. Internal paths (`/...`) use the host `linkComponent` when
|
|
33
|
+
* one is provided (e.g. Next.js `Link`); everything else is a native `<a>`.
|
|
34
|
+
*/
|
|
35
|
+
declare function NavLink({ href, children, openInSameTab, style, className, onClick, }: NavLinkProps): React.JSX.Element;
|
|
36
|
+
|
|
37
|
+
export { NavLink, type PageBuilderLinkComponent, type PageBuilderLinkProps, PageBuilderLinkProvider, usePageBuilderLinkComponent };
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
// src/components/nav-link.tsx
|
|
5
|
+
import * as React from "react";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
var LINK_CONTEXT_KEY = /* @__PURE__ */ Symbol.for("@frontlit/page-builder/link-context");
|
|
8
|
+
var globalRegistry = globalThis;
|
|
9
|
+
var PageBuilderLinkContext = globalRegistry[LINK_CONTEXT_KEY] ?? (globalRegistry[LINK_CONTEXT_KEY] = React.createContext(null));
|
|
10
|
+
function PageBuilderLinkProvider({
|
|
11
|
+
component,
|
|
12
|
+
children
|
|
13
|
+
}) {
|
|
14
|
+
return /* @__PURE__ */ jsx(PageBuilderLinkContext.Provider, { value: component ?? null, children });
|
|
15
|
+
}
|
|
16
|
+
function usePageBuilderLinkComponent() {
|
|
17
|
+
return React.useContext(PageBuilderLinkContext);
|
|
18
|
+
}
|
|
19
|
+
function NavLink({
|
|
20
|
+
href,
|
|
21
|
+
children,
|
|
22
|
+
openInSameTab = true,
|
|
23
|
+
style,
|
|
24
|
+
className = "",
|
|
25
|
+
onClick
|
|
26
|
+
}) {
|
|
27
|
+
const LinkComponent = usePageBuilderLinkComponent();
|
|
28
|
+
const isInternal = Boolean(href && href.startsWith("/"));
|
|
29
|
+
const isInPageNavigation = Boolean(href && href.startsWith("#"));
|
|
30
|
+
const target = openInSameTab ? void 0 : "_blank";
|
|
31
|
+
const rel = target === "_blank" ? "noopener noreferrer" : void 0;
|
|
32
|
+
const handleClick = () => {
|
|
33
|
+
onClick?.();
|
|
34
|
+
};
|
|
35
|
+
if (!isInPageNavigation && isInternal && LinkComponent) {
|
|
36
|
+
return /* @__PURE__ */ jsx(
|
|
37
|
+
LinkComponent,
|
|
38
|
+
{
|
|
39
|
+
href,
|
|
40
|
+
style,
|
|
41
|
+
className,
|
|
42
|
+
onClick: handleClick,
|
|
43
|
+
target,
|
|
44
|
+
rel,
|
|
45
|
+
children
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
return /* @__PURE__ */ jsx(
|
|
50
|
+
"a",
|
|
51
|
+
{
|
|
52
|
+
href,
|
|
53
|
+
style,
|
|
54
|
+
className,
|
|
55
|
+
target,
|
|
56
|
+
rel,
|
|
57
|
+
onClick: handleClick,
|
|
58
|
+
children
|
|
59
|
+
}
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
export {
|
|
63
|
+
NavLink,
|
|
64
|
+
PageBuilderLinkProvider,
|
|
65
|
+
usePageBuilderLinkComponent
|
|
66
|
+
};
|
|
67
|
+
//# sourceMappingURL=nav-link.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../src/components/nav-link.tsx"],"sourcesContent":["\"use client\";\n\nimport * as React from \"react\";\n\nexport interface PageBuilderLinkProps {\n href: string;\n children?: React.ReactNode;\n className?: string;\n style?: React.CSSProperties;\n onClick?: React.MouseEventHandler<HTMLAnchorElement>;\n target?: string;\n rel?: string;\n}\n\n/**\n * Optional host-supplied link. Next.js apps can pass `next/link`; Vite / Remix\n * / plain React hosts can omit it and NavLink will render a native `<a>`.\n */\nexport type PageBuilderLinkComponent = React.ComponentType<PageBuilderLinkProps>;\n\n// Server-rendered pages load this module more than once (each client island is\n// bundled on its own), so the context is shared through the global registry\n// rather than created per copy. Otherwise a provider from one copy would be\n// invisible to a NavLink from another.\nconst LINK_CONTEXT_KEY = Symbol.for(\"@frontlit/page-builder/link-context\");\nconst globalRegistry = globalThis as typeof globalThis & {\n [LINK_CONTEXT_KEY]?: React.Context<PageBuilderLinkComponent | null>;\n};\nconst PageBuilderLinkContext = (globalRegistry[LINK_CONTEXT_KEY] ??=\n React.createContext<PageBuilderLinkComponent | null>(null));\n\nexport function PageBuilderLinkProvider({\n component,\n children,\n}: {\n component?: PageBuilderLinkComponent | null;\n children: React.ReactNode;\n}) {\n return (\n <PageBuilderLinkContext.Provider value={component ?? null}>\n {children}\n </PageBuilderLinkContext.Provider>\n );\n}\n\nexport function usePageBuilderLinkComponent() {\n return React.useContext(PageBuilderLinkContext);\n}\n\ninterface NavLinkProps {\n href: string;\n children?: React.ReactNode;\n openInSameTab?: boolean;\n style?: React.CSSProperties;\n className?: string;\n onClick?: () => void;\n}\n\n/**\n * A navigation-aware link used inside block widgets. In-page anchors scroll\n * to the target. Internal paths (`/...`) use the host `linkComponent` when\n * one is provided (e.g. Next.js `Link`); everything else is a native `<a>`.\n */\nexport function NavLink({\n href,\n children,\n openInSameTab = true,\n style,\n className = \"\",\n onClick,\n}: NavLinkProps) {\n const LinkComponent = usePageBuilderLinkComponent();\n const isInternal = Boolean(href && href.startsWith(\"/\"));\n const isInPageNavigation = Boolean(href && href.startsWith(\"#\"));\n const target = openInSameTab ? undefined : \"_blank\";\n const rel = target === \"_blank\" ? \"noopener noreferrer\" : undefined;\n const handleClick: React.MouseEventHandler<HTMLAnchorElement> = () => {\n onClick?.();\n };\n\n if (!isInPageNavigation && isInternal && LinkComponent) {\n return (\n <LinkComponent\n href={href}\n style={style}\n className={className}\n onClick={handleClick}\n target={target}\n rel={rel}\n >\n {children}\n </LinkComponent>\n );\n }\n\n return (\n <a\n href={href}\n style={style}\n className={className}\n target={target}\n rel={rel}\n onClick={handleClick}\n >\n {children}\n </a>\n );\n}\n"],"mappings":";;;;AAEA,YAAY,WAAW;AAqCnB;AAfJ,IAAM,mBAAmB,uBAAO,IAAI,qCAAqC;AACzE,IAAM,iBAAiB;AAGvB,IAAM,yBAA0B,wEACxB,oBAA+C,IAAI;AAEpD,SAAS,wBAAwB;AAAA,EACtC;AAAA,EACA;AACF,GAGG;AACD,SACE,oBAAC,uBAAuB,UAAvB,EAAgC,OAAO,aAAa,MAClD,UACH;AAEJ;AAEO,SAAS,8BAA8B;AAC5C,SAAa,iBAAW,sBAAsB;AAChD;AAgBO,SAAS,QAAQ;AAAA,EACtB;AAAA,EACA;AAAA,EACA,gBAAgB;AAAA,EAChB;AAAA,EACA,YAAY;AAAA,EACZ;AACF,GAAiB;AACf,QAAM,gBAAgB,4BAA4B;AAClD,QAAM,aAAa,QAAQ,QAAQ,KAAK,WAAW,GAAG,CAAC;AACvD,QAAM,qBAAqB,QAAQ,QAAQ,KAAK,WAAW,GAAG,CAAC;AAC/D,QAAM,SAAS,gBAAgB,SAAY;AAC3C,QAAM,MAAM,WAAW,WAAW,wBAAwB;AAC1D,QAAM,cAA0D,MAAM;AACpE,cAAU;AAAA,EACZ;AAEA,MAAI,CAAC,sBAAsB,cAAc,eAAe;AACtD,WACE;AAAA,MAAC;AAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA;AAAA,QACA,SAAS;AAAA,QACT;AAAA,QACA;AAAA,QAEC;AAAA;AAAA,IACH;AAAA,EAEJ;AAEA,SACE;AAAA,IAAC;AAAA;AAAA,MACC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,SAAS;AAAA,MAER;AAAA;AAAA,EACH;AAEJ;","names":[]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import React__default from 'react';
|
|
2
|
+
import { T as ThemeStyle } from '../theme-style-5_AGy-4V.js';
|
|
3
|
+
import { P as PageData } from '../widget-YH9BrOwY.js';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* The interactive part of the support-form block: the ticket form and its
|
|
7
|
+
* success message. The block's heading stays server-rendered around it.
|
|
8
|
+
*/
|
|
9
|
+
declare function SupportForm({ theme: overriddenTheme, buttonCaption, successMessage, pageData, editing, }: {
|
|
10
|
+
theme: ThemeStyle;
|
|
11
|
+
buttonCaption: string;
|
|
12
|
+
successMessage: string;
|
|
13
|
+
pageData: PageData;
|
|
14
|
+
editing?: boolean;
|
|
15
|
+
}): React__default.JSX.Element;
|
|
16
|
+
|
|
17
|
+
export { SupportForm };
|
|
@@ -0,0 +1,469 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
"use client";
|
|
3
|
+
|
|
4
|
+
// src/blocks/support-form/form.tsx
|
|
5
|
+
import { useEffect, useRef, useState } from "react";
|
|
6
|
+
|
|
7
|
+
// src/primitives/lib/utils.ts
|
|
8
|
+
import { clsx } from "clsx";
|
|
9
|
+
import { twMerge } from "tailwind-merge";
|
|
10
|
+
function cn(...inputs) {
|
|
11
|
+
return twMerge(clsx(inputs));
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/primitives/components/ui/button.tsx
|
|
15
|
+
import { Slot } from "@radix-ui/react-slot";
|
|
16
|
+
import { cva } from "class-variance-authority";
|
|
17
|
+
import * as React from "react";
|
|
18
|
+
import { jsx } from "react/jsx-runtime";
|
|
19
|
+
var buttonVariants = cva(
|
|
20
|
+
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium ring-offset-background transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:size-4 [&_svg]:shrink-0",
|
|
21
|
+
{
|
|
22
|
+
variants: {
|
|
23
|
+
variant: {
|
|
24
|
+
default: "bg-primary text-primary-foreground hover:bg-primary/90",
|
|
25
|
+
destructive: "bg-destructive text-destructive-foreground hover:bg-destructive/90",
|
|
26
|
+
outline: "border border-input bg-background hover:bg-accent hover:text-accent-foreground",
|
|
27
|
+
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
|
|
28
|
+
ghost: "hover:bg-accent hover:text-accent-foreground",
|
|
29
|
+
link: "text-primary underline-offset-4 hover:underline"
|
|
30
|
+
},
|
|
31
|
+
size: {
|
|
32
|
+
default: "h-10 px-4 py-2",
|
|
33
|
+
sm: "h-9 rounded-md px-3",
|
|
34
|
+
lg: "h-11 rounded-md px-8",
|
|
35
|
+
icon: "h-10 w-10"
|
|
36
|
+
}
|
|
37
|
+
},
|
|
38
|
+
defaultVariants: {
|
|
39
|
+
variant: "default",
|
|
40
|
+
size: "default"
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
);
|
|
44
|
+
var Button = React.forwardRef(
|
|
45
|
+
({ className, variant, size, asChild = false, ...props }, ref) => {
|
|
46
|
+
const Comp = asChild ? Slot : "button";
|
|
47
|
+
return /* @__PURE__ */ jsx(
|
|
48
|
+
Comp,
|
|
49
|
+
{
|
|
50
|
+
className: cn(buttonVariants({ variant, size, className })),
|
|
51
|
+
ref,
|
|
52
|
+
...props
|
|
53
|
+
}
|
|
54
|
+
);
|
|
55
|
+
}
|
|
56
|
+
);
|
|
57
|
+
Button.displayName = "Button";
|
|
58
|
+
|
|
59
|
+
// src/primitives/button.tsx
|
|
60
|
+
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
61
|
+
var Button2 = ({
|
|
62
|
+
variant = "default",
|
|
63
|
+
size = "default",
|
|
64
|
+
disabled = false,
|
|
65
|
+
children,
|
|
66
|
+
className = "",
|
|
67
|
+
theme,
|
|
68
|
+
...props
|
|
69
|
+
}) => {
|
|
70
|
+
const buttonStyles = theme?.interactives?.button;
|
|
71
|
+
const typographyStyles = theme?.typography?.button;
|
|
72
|
+
const isIcon = size === "icon";
|
|
73
|
+
const classes = cn(
|
|
74
|
+
// Base styles
|
|
75
|
+
"",
|
|
76
|
+
// Theme typography
|
|
77
|
+
typographyStyles?.fontFamily,
|
|
78
|
+
typographyStyles?.fontSize,
|
|
79
|
+
typographyStyles?.fontWeight,
|
|
80
|
+
typographyStyles?.lineHeight,
|
|
81
|
+
typographyStyles?.letterSpacing,
|
|
82
|
+
typographyStyles?.textTransform,
|
|
83
|
+
typographyStyles?.textDecoration,
|
|
84
|
+
typographyStyles?.textOverflow,
|
|
85
|
+
// Theme interactivity. Icon buttons stay square — CTA padding
|
|
86
|
+
// would stretch them off the size="icon" box.
|
|
87
|
+
!isIcon && buttonStyles?.padding?.x,
|
|
88
|
+
!isIcon && buttonStyles?.padding?.y,
|
|
89
|
+
buttonStyles?.border?.width,
|
|
90
|
+
buttonStyles?.border?.radius,
|
|
91
|
+
buttonStyles?.border?.style,
|
|
92
|
+
// buttonStyles?.border?.color,
|
|
93
|
+
buttonStyles?.shadow,
|
|
94
|
+
// Theme disabled states
|
|
95
|
+
disabled && buttonStyles?.disabled?.opacity,
|
|
96
|
+
disabled && buttonStyles?.disabled?.cursor,
|
|
97
|
+
disabled && buttonStyles?.disabled?.color,
|
|
98
|
+
disabled && buttonStyles?.disabled?.background,
|
|
99
|
+
disabled && buttonStyles?.disabled?.border,
|
|
100
|
+
// User overrides
|
|
101
|
+
buttonStyles?.custom,
|
|
102
|
+
className
|
|
103
|
+
);
|
|
104
|
+
return /* @__PURE__ */ jsx2(
|
|
105
|
+
Button,
|
|
106
|
+
{
|
|
107
|
+
variant,
|
|
108
|
+
size,
|
|
109
|
+
disabled,
|
|
110
|
+
className: classes,
|
|
111
|
+
...props,
|
|
112
|
+
children
|
|
113
|
+
}
|
|
114
|
+
);
|
|
115
|
+
};
|
|
116
|
+
|
|
117
|
+
// src/primitives/input.tsx
|
|
118
|
+
import React3 from "react";
|
|
119
|
+
|
|
120
|
+
// src/primitives/components/ui/input.tsx
|
|
121
|
+
import * as React2 from "react";
|
|
122
|
+
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
123
|
+
var Input = React2.forwardRef(
|
|
124
|
+
({ className, type, ...props }, ref) => {
|
|
125
|
+
return /* @__PURE__ */ jsx3(
|
|
126
|
+
"input",
|
|
127
|
+
{
|
|
128
|
+
type,
|
|
129
|
+
className: cn(
|
|
130
|
+
"flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
131
|
+
className
|
|
132
|
+
),
|
|
133
|
+
ref,
|
|
134
|
+
...props
|
|
135
|
+
}
|
|
136
|
+
);
|
|
137
|
+
}
|
|
138
|
+
);
|
|
139
|
+
Input.displayName = "Input";
|
|
140
|
+
|
|
141
|
+
// src/primitives/input.tsx
|
|
142
|
+
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
143
|
+
var Input2 = React3.forwardRef(
|
|
144
|
+
({
|
|
145
|
+
className = "",
|
|
146
|
+
theme,
|
|
147
|
+
error = false,
|
|
148
|
+
/*style = {},*/
|
|
149
|
+
...props
|
|
150
|
+
}, ref) => {
|
|
151
|
+
const inputStyles = theme?.interactives?.input;
|
|
152
|
+
const typographyStyles = theme?.typography?.input;
|
|
153
|
+
const classes = cn(
|
|
154
|
+
// Base styles
|
|
155
|
+
// "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
|
156
|
+
// Theme typography
|
|
157
|
+
typographyStyles?.fontFamily,
|
|
158
|
+
typographyStyles?.fontSize,
|
|
159
|
+
typographyStyles?.fontWeight,
|
|
160
|
+
typographyStyles?.lineHeight,
|
|
161
|
+
typographyStyles?.letterSpacing,
|
|
162
|
+
typographyStyles?.textTransform,
|
|
163
|
+
typographyStyles?.textDecoration,
|
|
164
|
+
typographyStyles?.textOverflow,
|
|
165
|
+
// Theme interactivity
|
|
166
|
+
inputStyles?.padding?.x,
|
|
167
|
+
inputStyles?.padding?.y,
|
|
168
|
+
inputStyles?.border?.width,
|
|
169
|
+
inputStyles?.border?.style,
|
|
170
|
+
inputStyles?.border?.radius,
|
|
171
|
+
// inputStyles?.border?.color,
|
|
172
|
+
inputStyles?.shadow,
|
|
173
|
+
// Theme disabled states
|
|
174
|
+
props.disabled && inputStyles?.disabled?.opacity,
|
|
175
|
+
props.disabled && inputStyles?.disabled?.cursor,
|
|
176
|
+
props.disabled && inputStyles?.disabled?.color,
|
|
177
|
+
props.disabled && inputStyles?.disabled?.background,
|
|
178
|
+
props.disabled && inputStyles?.disabled?.border,
|
|
179
|
+
// Error state
|
|
180
|
+
error && "border-red-300 focus:border-red-500 focus:ring-red-500",
|
|
181
|
+
// User overrides
|
|
182
|
+
inputStyles?.custom,
|
|
183
|
+
className
|
|
184
|
+
);
|
|
185
|
+
return /* @__PURE__ */ jsx4(Input, { ref, className: classes, ...props });
|
|
186
|
+
}
|
|
187
|
+
);
|
|
188
|
+
Input2.displayName = "Input";
|
|
189
|
+
|
|
190
|
+
// src/primitives/label.tsx
|
|
191
|
+
import React5 from "react";
|
|
192
|
+
|
|
193
|
+
// src/primitives/components/ui/label.tsx
|
|
194
|
+
import * as LabelPrimitive from "@radix-ui/react-label";
|
|
195
|
+
import { cva as cva2 } from "class-variance-authority";
|
|
196
|
+
import * as React4 from "react";
|
|
197
|
+
import { jsx as jsx5 } from "react/jsx-runtime";
|
|
198
|
+
var labelVariants = cva2(
|
|
199
|
+
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
|
200
|
+
);
|
|
201
|
+
var Label = React4.forwardRef(({ className, ...props }, ref) => /* @__PURE__ */ jsx5(
|
|
202
|
+
LabelPrimitive.Root,
|
|
203
|
+
{
|
|
204
|
+
ref,
|
|
205
|
+
className: cn(labelVariants(), className),
|
|
206
|
+
...props
|
|
207
|
+
}
|
|
208
|
+
));
|
|
209
|
+
Label.displayName = LabelPrimitive.Root.displayName;
|
|
210
|
+
|
|
211
|
+
// src/primitives/label.tsx
|
|
212
|
+
import { jsx as jsx6 } from "react/jsx-runtime";
|
|
213
|
+
var Label2 = React5.forwardRef(
|
|
214
|
+
({ className = "", theme, error = false, ...props }, ref) => {
|
|
215
|
+
const typographyStyles = theme?.typography?.text2;
|
|
216
|
+
const classes = cn(
|
|
217
|
+
// Theme typography
|
|
218
|
+
typographyStyles?.fontFamily,
|
|
219
|
+
typographyStyles?.fontSize,
|
|
220
|
+
typographyStyles?.fontWeight,
|
|
221
|
+
typographyStyles?.lineHeight,
|
|
222
|
+
typographyStyles?.letterSpacing,
|
|
223
|
+
typographyStyles?.textTransform,
|
|
224
|
+
typographyStyles?.textDecoration,
|
|
225
|
+
typographyStyles?.textOverflow,
|
|
226
|
+
// Error state
|
|
227
|
+
error && "text-red-500",
|
|
228
|
+
className
|
|
229
|
+
);
|
|
230
|
+
return /* @__PURE__ */ jsx6(Label, { ref, className: classes, ...props });
|
|
231
|
+
}
|
|
232
|
+
);
|
|
233
|
+
Label2.displayName = "Label";
|
|
234
|
+
|
|
235
|
+
// src/primitives/text2.tsx
|
|
236
|
+
import { jsx as jsx7 } from "react/jsx-runtime";
|
|
237
|
+
var Text2 = ({
|
|
238
|
+
children,
|
|
239
|
+
className = "",
|
|
240
|
+
theme,
|
|
241
|
+
component = "p",
|
|
242
|
+
...props
|
|
243
|
+
}) => {
|
|
244
|
+
const typographyStyles = theme?.typography?.text2;
|
|
245
|
+
const classes = cn(
|
|
246
|
+
// Base styles
|
|
247
|
+
"text-sm",
|
|
248
|
+
// Theme overrides
|
|
249
|
+
typographyStyles?.fontFamily,
|
|
250
|
+
typographyStyles?.fontSize,
|
|
251
|
+
typographyStyles?.fontWeight,
|
|
252
|
+
typographyStyles?.lineHeight,
|
|
253
|
+
typographyStyles?.letterSpacing,
|
|
254
|
+
typographyStyles?.textTransform,
|
|
255
|
+
typographyStyles?.textDecoration,
|
|
256
|
+
typographyStyles?.textOverflow,
|
|
257
|
+
className
|
|
258
|
+
);
|
|
259
|
+
return component === "p" ? /* @__PURE__ */ jsx7("p", { className: classes, ...props, children }) : /* @__PURE__ */ jsx7("span", { className: classes, ...props, children });
|
|
260
|
+
};
|
|
261
|
+
|
|
262
|
+
// src/blocks/support-form/form.tsx
|
|
263
|
+
import { jsx as jsx8, jsxs } from "react/jsx-runtime";
|
|
264
|
+
function suggestionHref(item) {
|
|
265
|
+
if (item.kind === "blog") return `/blog/${item.slug}`;
|
|
266
|
+
if (item.kind === "changelog") return `/changelog`;
|
|
267
|
+
return `/docs/${item.slug}`;
|
|
268
|
+
}
|
|
269
|
+
async function searchDocumentation(query, pageData) {
|
|
270
|
+
if (!pageData.teamId || !pageData.publicApiBaseUrl || query.trim().length < 3)
|
|
271
|
+
return [];
|
|
272
|
+
try {
|
|
273
|
+
const res = await fetch(
|
|
274
|
+
`${pageData.publicApiBaseUrl}/public/${pageData.teamId}/content/documentation/search?q=${encodeURIComponent(query)}&k=3`
|
|
275
|
+
);
|
|
276
|
+
if (!res.ok) return [];
|
|
277
|
+
const body = await res.json();
|
|
278
|
+
const seen = /* @__PURE__ */ new Set();
|
|
279
|
+
return body.items.filter(
|
|
280
|
+
(item) => seen.has(item.documentId) ? false : (seen.add(item.documentId), true)
|
|
281
|
+
);
|
|
282
|
+
} catch {
|
|
283
|
+
return [];
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
async function submitTicket(input, pageData) {
|
|
287
|
+
if (!pageData.teamId || !pageData.publicApiBaseUrl) {
|
|
288
|
+
await new Promise((resolve) => setTimeout(resolve, 600));
|
|
289
|
+
return { success: true };
|
|
290
|
+
}
|
|
291
|
+
try {
|
|
292
|
+
const res = await fetch(
|
|
293
|
+
`${pageData.publicApiBaseUrl}/public/${pageData.teamId}/tickets`,
|
|
294
|
+
{
|
|
295
|
+
method: "POST",
|
|
296
|
+
headers: { "content-type": "application/json" },
|
|
297
|
+
body: JSON.stringify({ ...input, source: "form" })
|
|
298
|
+
}
|
|
299
|
+
);
|
|
300
|
+
return { success: res.ok };
|
|
301
|
+
} catch {
|
|
302
|
+
return { success: false };
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
function SupportForm({
|
|
306
|
+
theme: overriddenTheme,
|
|
307
|
+
buttonCaption,
|
|
308
|
+
successMessage,
|
|
309
|
+
pageData,
|
|
310
|
+
editing
|
|
311
|
+
}) {
|
|
312
|
+
const [subject, setSubject] = useState("");
|
|
313
|
+
const [message, setMessage] = useState("");
|
|
314
|
+
const [email, setEmail] = useState("");
|
|
315
|
+
const [name, setName] = useState("");
|
|
316
|
+
const [suggestions, setSuggestions] = useState([]);
|
|
317
|
+
const [isSubmitting, setIsSubmitting] = useState(false);
|
|
318
|
+
const [success, setSuccess] = useState(false);
|
|
319
|
+
const debounceRef = useRef(null);
|
|
320
|
+
useEffect(() => {
|
|
321
|
+
if (editing) return;
|
|
322
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
323
|
+
debounceRef.current = setTimeout(() => {
|
|
324
|
+
searchDocumentation(subject, pageData).then(setSuggestions);
|
|
325
|
+
}, 400);
|
|
326
|
+
return () => {
|
|
327
|
+
if (debounceRef.current) clearTimeout(debounceRef.current);
|
|
328
|
+
};
|
|
329
|
+
}, [subject]);
|
|
330
|
+
const onSubmit = async (e) => {
|
|
331
|
+
e.preventDefault();
|
|
332
|
+
if (editing) return;
|
|
333
|
+
setIsSubmitting(true);
|
|
334
|
+
try {
|
|
335
|
+
const result = await submitTicket(
|
|
336
|
+
{ subject, message, email, name: name || void 0 },
|
|
337
|
+
pageData
|
|
338
|
+
);
|
|
339
|
+
if (result.success) {
|
|
340
|
+
setSuccess(true);
|
|
341
|
+
setSubject("");
|
|
342
|
+
setMessage("");
|
|
343
|
+
setEmail("");
|
|
344
|
+
setName("");
|
|
345
|
+
setSuggestions([]);
|
|
346
|
+
}
|
|
347
|
+
} finally {
|
|
348
|
+
setIsSubmitting(false);
|
|
349
|
+
}
|
|
350
|
+
};
|
|
351
|
+
const inputStyles = overriddenTheme.interactives.input;
|
|
352
|
+
const inputTypography = overriddenTheme.typography.input;
|
|
353
|
+
const cardStyles = overriddenTheme.interactives.card;
|
|
354
|
+
return success ? /* @__PURE__ */ jsx8(Text2, { theme: overriddenTheme, className: "mt-4", children: successMessage }) : /* @__PURE__ */ jsxs("form", { onSubmit, className: "mt-4 flex w-full max-w-lg flex-col gap-3", children: [
|
|
355
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
|
|
356
|
+
/* @__PURE__ */ jsx8(Label2, { theme: overriddenTheme, htmlFor: "subject", children: "Subject" }),
|
|
357
|
+
/* @__PURE__ */ jsx8(
|
|
358
|
+
Input2,
|
|
359
|
+
{
|
|
360
|
+
theme: overriddenTheme,
|
|
361
|
+
id: "subject",
|
|
362
|
+
value: subject,
|
|
363
|
+
onChange: (e) => setSubject(e.target.value),
|
|
364
|
+
placeholder: "What do you need help with?",
|
|
365
|
+
required: true,
|
|
366
|
+
className: "w-full"
|
|
367
|
+
}
|
|
368
|
+
)
|
|
369
|
+
] }),
|
|
370
|
+
suggestions.length > 0 && /* @__PURE__ */ jsxs(
|
|
371
|
+
"div",
|
|
372
|
+
{
|
|
373
|
+
className: cn(
|
|
374
|
+
"rounded-lg border border-border bg-card p-3 text-sm text-card-foreground shadow-sm",
|
|
375
|
+
cardStyles.border?.width,
|
|
376
|
+
cardStyles.border?.radius,
|
|
377
|
+
cardStyles.border?.style,
|
|
378
|
+
cardStyles.shadow
|
|
379
|
+
),
|
|
380
|
+
children: [
|
|
381
|
+
/* @__PURE__ */ jsx8("p", { className: "mb-1 font-medium", children: "This might help:" }),
|
|
382
|
+
/* @__PURE__ */ jsx8("ul", { className: "list-inside list-disc", children: suggestions.map((doc) => /* @__PURE__ */ jsx8("li", { children: /* @__PURE__ */ jsx8(
|
|
383
|
+
"a",
|
|
384
|
+
{
|
|
385
|
+
href: suggestionHref(doc),
|
|
386
|
+
target: "_blank",
|
|
387
|
+
rel: "noreferrer",
|
|
388
|
+
className: "underline",
|
|
389
|
+
children: doc.title ?? doc.slug
|
|
390
|
+
}
|
|
391
|
+
) }, doc.documentId)) })
|
|
392
|
+
]
|
|
393
|
+
}
|
|
394
|
+
),
|
|
395
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-1 items-start", children: [
|
|
396
|
+
/* @__PURE__ */ jsx8(Label2, { theme: overriddenTheme, htmlFor: "message", children: "Message" }),
|
|
397
|
+
/* @__PURE__ */ jsx8(
|
|
398
|
+
"textarea",
|
|
399
|
+
{
|
|
400
|
+
id: "message",
|
|
401
|
+
value: message,
|
|
402
|
+
onChange: (e) => setMessage(e.target.value),
|
|
403
|
+
placeholder: "Describe the issue\u2026",
|
|
404
|
+
required: true,
|
|
405
|
+
rows: 4,
|
|
406
|
+
className: cn(
|
|
407
|
+
"w-full border border-input bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",
|
|
408
|
+
inputTypography.fontFamily,
|
|
409
|
+
inputTypography.fontSize,
|
|
410
|
+
inputTypography.fontWeight,
|
|
411
|
+
inputTypography.lineHeight,
|
|
412
|
+
inputTypography.letterSpacing,
|
|
413
|
+
inputStyles.border?.width,
|
|
414
|
+
inputStyles.border?.style,
|
|
415
|
+
inputStyles.border?.radius,
|
|
416
|
+
inputStyles.shadow,
|
|
417
|
+
inputStyles.custom
|
|
418
|
+
)
|
|
419
|
+
}
|
|
420
|
+
)
|
|
421
|
+
] }),
|
|
422
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-3 sm:!flex-row", children: [
|
|
423
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1 items-start", children: [
|
|
424
|
+
/* @__PURE__ */ jsx8(Label2, { theme: overriddenTheme, htmlFor: "email", children: "Email" }),
|
|
425
|
+
/* @__PURE__ */ jsx8(
|
|
426
|
+
Input2,
|
|
427
|
+
{
|
|
428
|
+
theme: overriddenTheme,
|
|
429
|
+
id: "email",
|
|
430
|
+
type: "email",
|
|
431
|
+
value: email,
|
|
432
|
+
onChange: (e) => setEmail(e.target.value),
|
|
433
|
+
placeholder: "you@example.com",
|
|
434
|
+
required: true,
|
|
435
|
+
className: "w-full"
|
|
436
|
+
}
|
|
437
|
+
)
|
|
438
|
+
] }),
|
|
439
|
+
/* @__PURE__ */ jsxs("div", { className: "flex flex-1 flex-col gap-1 items-start", children: [
|
|
440
|
+
/* @__PURE__ */ jsx8(Label2, { theme: overriddenTheme, htmlFor: "name", children: "Name (optional)" }),
|
|
441
|
+
/* @__PURE__ */ jsx8(
|
|
442
|
+
Input2,
|
|
443
|
+
{
|
|
444
|
+
theme: overriddenTheme,
|
|
445
|
+
id: "name",
|
|
446
|
+
value: name,
|
|
447
|
+
onChange: (e) => setName(e.target.value),
|
|
448
|
+
placeholder: "Your name",
|
|
449
|
+
className: "w-full"
|
|
450
|
+
}
|
|
451
|
+
)
|
|
452
|
+
] })
|
|
453
|
+
] }),
|
|
454
|
+
/* @__PURE__ */ jsx8(
|
|
455
|
+
Button2,
|
|
456
|
+
{
|
|
457
|
+
theme: overriddenTheme,
|
|
458
|
+
type: "submit",
|
|
459
|
+
disabled: !editing && (isSubmitting || !subject || !message || !email),
|
|
460
|
+
className: "self-start",
|
|
461
|
+
children: buttonCaption
|
|
462
|
+
}
|
|
463
|
+
)
|
|
464
|
+
] });
|
|
465
|
+
}
|
|
466
|
+
export {
|
|
467
|
+
SupportForm
|
|
468
|
+
};
|
|
469
|
+
//# sourceMappingURL=support-form.js.map
|