@pelatform/ui 2.0.0 → 2.1.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 (43) hide show
  1. package/README.md +360 -5
  2. package/dist/animation.d.ts +6 -4
  3. package/dist/animation.js +3 -1
  4. package/dist/base.d.ts +1 -1
  5. package/dist/base.js +3 -1
  6. package/dist/components.d.ts +1 -2987
  7. package/dist/components.js +2 -2318
  8. package/dist/css/color/gray.css +105 -0
  9. package/dist/css/color/neutral.css +105 -0
  10. package/dist/css/color/slate.css +105 -0
  11. package/dist/css/color/stone.css +105 -0
  12. package/dist/css/color/zinc.css +105 -0
  13. package/dist/css/styles/style-lyra.css +1335 -0
  14. package/dist/css/styles/style-maia.css +1360 -0
  15. package/dist/css/styles/style-mira.css +1362 -0
  16. package/dist/css/styles/style-nova.css +1360 -0
  17. package/dist/css/styles/style-vega.css +1356 -0
  18. package/dist/hooks.d.ts +1 -93
  19. package/dist/hooks.js +2 -7
  20. package/dist/index.d.ts +1 -68
  21. package/dist/index.js +2 -7
  22. package/dist/radix.d.ts +1 -0
  23. package/dist/radix.js +4 -0
  24. package/dist/style.css +2 -0
  25. package/package.json +74 -48
  26. package/LICENSE +0 -21
  27. package/css/components/apexcharts.css +0 -101
  28. package/css/components/book.css +0 -19
  29. package/css/components/extra.css +0 -12
  30. package/css/components/image-input.css +0 -51
  31. package/css/components/leaflet.css +0 -25
  32. package/css/components/patterns.css +0 -34
  33. package/css/components/rating.css +0 -89
  34. package/css/components/scrollable.css +0 -118
  35. package/css/components/theme-transition.css +0 -51
  36. package/css/source.css +0 -20
  37. package/css/theme.css +0 -237
  38. package/dist/aria.d.ts +0 -1
  39. package/dist/aria.js +0 -2
  40. package/dist/chunk-UEVIEY7W.js +0 -51
  41. package/dist/chunk-VZEE3GOC.js +0 -458
  42. package/dist/default.d.ts +0 -1
  43. package/dist/default.js +0 -2
@@ -1,2320 +1,4 @@
1
1
  "use client";
2
- import {
3
- useMetaColor
4
- } from "./chunk-UEVIEY7W.js";
5
- import {
6
- Icons
7
- } from "./chunk-VZEE3GOC.js";
8
2
 
9
- // src/components/feedback/alert.tsx
10
- import {
11
- CheckIcon,
12
- CircleAlertIcon,
13
- CircleCheckIcon,
14
- CircleXIcon,
15
- InfoIcon,
16
- TriangleAlertIcon
17
- } from "@pelatform/ui.core";
18
- import { Alert, AlertIcon, AlertTitle } from "@pelatform/ui.default";
19
- import { toast } from "@pelatform/ui.default/dep";
20
- import { jsx, jsxs } from "react/jsx-runtime";
21
- var iconMap = {
22
- primary: /* @__PURE__ */ jsx(CircleAlertIcon, {}),
23
- success: /* @__PURE__ */ jsx(CircleCheckIcon, {}),
24
- info: /* @__PURE__ */ jsx(InfoIcon, {}),
25
- warning: /* @__PURE__ */ jsx(TriangleAlertIcon, {}),
26
- destructive: /* @__PURE__ */ jsx(CircleXIcon, {})
27
- };
28
- function AlertToast({
29
- message = "This is a toast",
30
- icon = "success",
31
- variant = "mono"
32
- }) {
33
- toast.custom(
34
- () => /* @__PURE__ */ jsxs(Alert, { variant, icon, children: [
35
- /* @__PURE__ */ jsx(AlertIcon, { children: iconMap[icon ?? "success"] }),
36
- /* @__PURE__ */ jsx(AlertTitle, { children: message })
37
- ] }),
38
- {
39
- // Auto-dismiss after 4 seconds
40
- duration: 4e3,
41
- // Generate unique ID to prevent duplicate toasts
42
- id: `alert-toast-${Date.now()}`
43
- }
44
- );
45
- }
46
- function AlertNotification({ message, variant = "info" }) {
47
- if (!message) return null;
48
- const getIcon = () => {
49
- switch (variant) {
50
- case "destructive":
51
- return /* @__PURE__ */ jsx(CircleAlertIcon, {});
52
- case "success":
53
- return /* @__PURE__ */ jsx(CheckIcon, {});
54
- case "info":
55
- return /* @__PURE__ */ jsx(InfoIcon, {});
56
- case "warning":
57
- return /* @__PURE__ */ jsx(TriangleAlertIcon, {});
58
- default:
59
- return /* @__PURE__ */ jsx(InfoIcon, {});
60
- }
61
- };
62
- return /* @__PURE__ */ jsxs(Alert, { variant, children: [
63
- /* @__PURE__ */ jsx(AlertIcon, { children: getIcon() }),
64
- /* @__PURE__ */ jsx(AlertTitle, { children: message })
65
- ] });
66
- }
67
- var AlertComingsoon = ({
68
- message = "This feature is coming soon.",
69
- icon = "success",
70
- variant = "mono"
71
- } = {}) => {
72
- toast.custom(
73
- () => /* @__PURE__ */ jsxs(Alert, { variant, icon, children: [
74
- /* @__PURE__ */ jsx(AlertIcon, { children: /* @__PURE__ */ jsx(CircleAlertIcon, {}) }),
75
- /* @__PURE__ */ jsx(AlertTitle, { children: message })
76
- ] }),
77
- {
78
- // Toast configuration for better UX
79
- position: "top-center",
80
- duration: 3e3,
81
- // Show for 3 seconds
82
- id: `coming-soon-${Date.now()}`
83
- // Prevent duplicate toasts
84
- }
85
- );
86
- };
87
-
88
- // src/components/feedback/dialog.tsx
89
- import {
90
- AlertDialog,
91
- AlertDialogAction,
92
- AlertDialogCancel,
93
- AlertDialogContent,
94
- AlertDialogDescription,
95
- AlertDialogFooter,
96
- AlertDialogHeader,
97
- AlertDialogTitle
98
- } from "@pelatform/ui.default";
99
- import { jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
100
- var ConfirmDismissDialog = ({
101
- open,
102
- onOpenChange,
103
- onConfirm,
104
- onCancel,
105
- title = "Discard changes?",
106
- description = "You have unsaved changes. Are you sure you want to close this dialog?",
107
- confirmText = "Discard changes",
108
- cancelText = "Cancel",
109
- maxWidth = "md:max-w-[375px]"
110
- }) => {
111
- const handleCancel = () => {
112
- if (onCancel) {
113
- onCancel();
114
- } else {
115
- onOpenChange(false);
116
- }
117
- };
118
- return /* @__PURE__ */ jsx2(AlertDialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs2(AlertDialogContent, { className: maxWidth, children: [
119
- /* @__PURE__ */ jsxs2(AlertDialogHeader, { children: [
120
- /* @__PURE__ */ jsx2(AlertDialogTitle, { children: title }),
121
- /* @__PURE__ */ jsx2(AlertDialogDescription, { children: description })
122
- ] }),
123
- /* @__PURE__ */ jsxs2(AlertDialogFooter, { children: [
124
- /* @__PURE__ */ jsx2(AlertDialogCancel, { onClick: handleCancel, children: cancelText }),
125
- /* @__PURE__ */ jsx2(AlertDialogAction, { onClick: onConfirm, children: confirmText })
126
- ] })
127
- ] }) });
128
- };
129
-
130
- // src/components/feedback/screen-loader.tsx
131
- import { cn, LoaderIcon } from "@pelatform/ui.core";
132
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
133
- function ScreenLoader({
134
- loadingText = "Loading...",
135
- className = "",
136
- spinnerClassName = "size-6 animate-spin",
137
- textClassName = "text-muted-foreground font-medium text-sm",
138
- contentLoader = false
139
- } = {}) {
140
- if (contentLoader) {
141
- return /* @__PURE__ */ jsx3("div", { className: cn("flex w-full grow items-center justify-center", className), children: /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2.5", children: [
142
- /* @__PURE__ */ jsx3(LoaderIcon, { className: spinnerClassName, "aria-hidden": "true" }),
143
- /* @__PURE__ */ jsx3("span", { className: textClassName, children: loadingText })
144
- ] }) });
145
- }
146
- return /* @__PURE__ */ jsxs3(
147
- "div",
148
- {
149
- className: cn(
150
- "fixed inset-0 z-500 flex flex-col items-center justify-center gap-2 bg-background transition-opacity duration-700 ease-in-out",
151
- className
152
- ),
153
- role: "status",
154
- "aria-live": "polite",
155
- "aria-label": loadingText,
156
- children: [
157
- /* @__PURE__ */ jsx3(LoaderIcon, { className: spinnerClassName, "aria-hidden": "true" }),
158
- /* @__PURE__ */ jsx3("div", { className: textClassName, children: loadingText })
159
- ]
160
- }
161
- );
162
- }
163
-
164
- // src/components/layout/auth.tsx
165
- import { cn as cn2 } from "@pelatform/ui.core";
166
- import { Card, CardContent } from "@pelatform/ui.default";
167
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
168
- function LayoutAuth({
169
- children,
170
- className,
171
- logo
172
- }) {
173
- return /* @__PURE__ */ jsxs4(
174
- "div",
175
- {
176
- className: cn2("flex min-h-screen grow flex-col items-center justify-center p-4", className),
177
- children: [
178
- logo && /* @__PURE__ */ jsx4("div", { className: "m-5", children: logo }),
179
- /* @__PURE__ */ jsx4(Card, { className: "w-full max-w-md", children: /* @__PURE__ */ jsx4(CardContent, { className: "p-6", children }) })
180
- ]
181
- }
182
- );
183
- }
184
-
185
- // src/components/layout/blank.tsx
186
- import { cn as cn4 } from "@pelatform/ui.core";
187
-
188
- // src/components/layout/grid.tsx
189
- import { useId } from "react";
190
- import { cn as cn3 } from "@pelatform/ui.core";
191
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
192
- function Grid({
193
- cellSize = 12,
194
- strokeWidth = 1,
195
- patternOffset = [0, 0],
196
- className
197
- }) {
198
- const id = useId();
199
- return /* @__PURE__ */ jsxs5(
200
- "svg",
201
- {
202
- className: cn3("pointer-events-none absolute inset-0 text-foreground/10", className),
203
- width: "100%",
204
- height: "100%",
205
- children: [
206
- /* @__PURE__ */ jsx5("defs", { children: /* @__PURE__ */ jsx5(
207
- "pattern",
208
- {
209
- id: `grid-${id}`,
210
- x: patternOffset[0] - 1,
211
- y: patternOffset[1] - 1,
212
- width: cellSize,
213
- height: cellSize,
214
- patternUnits: "userSpaceOnUse",
215
- children: /* @__PURE__ */ jsx5(
216
- "path",
217
- {
218
- d: `M ${cellSize} 0 L 0 0 0 ${cellSize}`,
219
- fill: "transparent",
220
- stroke: "currentColor",
221
- strokeWidth
222
- }
223
- )
224
- }
225
- ) }),
226
- /* @__PURE__ */ jsx5("rect", { fill: `url(#grid-${id})`, width: "100%", height: "100%" })
227
- ]
228
- }
229
- );
230
- }
231
-
232
- // src/components/layout/blank.tsx
233
- import { Fragment, jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
234
- function LayoutBlank({ children, footer, className, logo, logoHref }) {
235
- return /* @__PURE__ */ jsxs6(Fragment, { children: [
236
- /* @__PURE__ */ jsx6("div", { className: "absolute inset-0 isolate overflow-hidden bg-background", children: /* @__PURE__ */ jsx6(
237
- "div",
238
- {
239
- className: cn4(
240
- "-translate-x-1/2 absolute inset-y-0 start-1/2 w-[1200px]",
241
- "mask-intersect mask-[linear-gradient(black,transparent_320px),linear-gradient(90deg,transparent,black_5%,black_95%,transparent)]"
242
- ),
243
- children: /* @__PURE__ */ jsx6(Grid, { cellSize: 60, patternOffset: [0.75, 0], className: "text-foreground/15" })
244
- }
245
- ) }),
246
- /* @__PURE__ */ jsxs6(
247
- "div",
248
- {
249
- className: cn4(
250
- "relative flex min-h-screen w-full flex-col items-center justify-between",
251
- className
252
- ),
253
- children: [
254
- /* @__PURE__ */ jsx6("div", { className: "grow basis-0", children: logo && /* @__PURE__ */ jsx6("div", { className: "pt-4", children: /* @__PURE__ */ jsx6("a", { href: logoHref ?? "#", target: "_blank", className: "block", children: logo }) }) }),
255
- /* @__PURE__ */ jsx6("div", { className: "w-full max-w-4xl px-4 py-16", children }),
256
- /* @__PURE__ */ jsx6("div", { className: "grow basis-0", children: footer })
257
- ]
258
- }
259
- )
260
- ] });
261
- }
262
-
263
- // src/components/layout/body.tsx
264
- import { cn as cn5 } from "@pelatform/ui.core";
265
- import { jsx as jsx7 } from "react/jsx-runtime";
266
- function useMode(slug) {
267
- return Array.isArray(slug) && slug.length > 0 ? slug[0] : void 0;
268
- }
269
- function Body({ slug, children, className }) {
270
- const mode = useMode(slug);
271
- return /* @__PURE__ */ jsx7("body", { className: cn5(mode, className), children });
272
- }
273
-
274
- // src/components/layout/comingsoon.tsx
275
- import { HoverBackground } from "@pelatform/ui.animation";
276
- import { cn as cn6 } from "@pelatform/ui.core";
277
- import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
278
- function ComingSoon({ className, title, description }) {
279
- return /* @__PURE__ */ jsx8("div", { className: cn6("h-[calc(100vh-54px)] w-full overflow-hidden", className), children: /* @__PURE__ */ jsx8(
280
- HoverBackground,
281
- {
282
- colors: {
283
- background: "bg-gradient-to-br from-black via-gray-900 to-zinc-900",
284
- objects: [
285
- "bg-emerald-500/30",
286
- "bg-teal-500/30",
287
- "bg-green-500/30",
288
- "bg-lime-500/30",
289
- "bg-cyan-500/30",
290
- "bg-blue-500/30"
291
- ],
292
- glow: "shadow-emerald-400/70"
293
- },
294
- objectCount: 8,
295
- children: /* @__PURE__ */ jsxs7("div", { className: "flex h-full flex-col items-center justify-center space-y-4 text-center", children: [
296
- title && /* @__PURE__ */ jsx8("h2", { className: "font-bold text-4xl text-white/90", children: title }),
297
- description && /* @__PURE__ */ jsx8("p", { className: "max-w-md text-emerald-100/80 text-lg", children: description })
298
- ] })
299
- }
300
- ) });
301
- }
302
-
303
- // src/components/layout/error.tsx
304
- import { cn as cn7, getAssetsUrl } from "@pelatform/ui.core";
305
- import { Badge } from "@pelatform/ui.default";
306
- import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
307
- function ErrorComponents({
308
- className,
309
- type = "default",
310
- textTitle,
311
- textSubtitle,
312
- button
313
- }) {
314
- if (type === "404") {
315
- return /* @__PURE__ */ jsxs8("div", { className: cn7("flex h-[95%] grow flex-col items-center justify-center", className), children: [
316
- /* @__PURE__ */ jsxs8("div", { className: "mb-10", children: [
317
- /* @__PURE__ */ jsx9(
318
- "img",
319
- {
320
- src: getAssetsUrl("media/illustrations/19.svg"),
321
- className: "max-h-40 dark:hidden",
322
- alt: "illustrations"
323
- }
324
- ),
325
- /* @__PURE__ */ jsx9(
326
- "img",
327
- {
328
- src: getAssetsUrl("media/illustrations/19-dark.svg"),
329
- className: "hidden max-h-40 dark:block",
330
- alt: "illustrations"
331
- }
332
- )
333
- ] }),
334
- /* @__PURE__ */ jsx9(Badge, { variant: "destructive", appearance: "outline", className: "mb-3", children: "404 Error" }),
335
- /* @__PURE__ */ jsx9("h3", { className: "mb-2 text-center font-semibold text-2xl text-foreground", children: textTitle }),
336
- /* @__PURE__ */ jsx9("div", { className: "mb-10 text-center text-base text-secondary-foreground", children: textSubtitle })
337
- ] });
338
- }
339
- if (type === "500") {
340
- return /* @__PURE__ */ jsxs8("div", { className: cn7("flex h-[95%] grow flex-col items-center justify-center", className), children: [
341
- /* @__PURE__ */ jsxs8("div", { className: "mb-10", children: [
342
- /* @__PURE__ */ jsx9(
343
- "img",
344
- {
345
- src: getAssetsUrl("media/illustrations/20.svg"),
346
- className: "max-h-40 dark:hidden",
347
- alt: "illustrations"
348
- }
349
- ),
350
- /* @__PURE__ */ jsx9(
351
- "img",
352
- {
353
- src: getAssetsUrl("media/illustrations/20-dark.svg"),
354
- className: "hidden max-h-40 dark:block",
355
- alt: "illustrations"
356
- }
357
- )
358
- ] }),
359
- /* @__PURE__ */ jsx9(Badge, { variant: "destructive", appearance: "outline", className: "mb-3", children: "500 Error" }),
360
- /* @__PURE__ */ jsx9("h3", { className: "mb-2 text-center font-semibold text-2xl text-foreground", children: textTitle }),
361
- /* @__PURE__ */ jsx9("div", { className: "mb-10 text-center text-base text-secondary-foreground", children: textSubtitle }),
362
- button
363
- ] });
364
- }
365
- return /* @__PURE__ */ jsxs8("div", { className: cn7("flex h-[95%] grow flex-col items-center justify-center", className), children: [
366
- /* @__PURE__ */ jsxs8("div", { className: "mb-10", children: [
367
- /* @__PURE__ */ jsx9(
368
- "img",
369
- {
370
- src: getAssetsUrl("media/illustrations/29.svg"),
371
- className: "max-h-40 dark:hidden",
372
- alt: "illustrations"
373
- }
374
- ),
375
- /* @__PURE__ */ jsx9(
376
- "img",
377
- {
378
- src: getAssetsUrl("media/illustrations/29-dark.svg"),
379
- className: "hidden max-h-40 dark:block",
380
- alt: "illustrations"
381
- }
382
- )
383
- ] }),
384
- /* @__PURE__ */ jsx9("h3", { className: "mb-2 text-center font-semibold text-2xl text-foreground", children: textTitle }),
385
- /* @__PURE__ */ jsx9("div", { className: "mb-10 text-center text-base text-secondary-foreground", children: textSubtitle })
386
- ] });
387
- }
388
-
389
- // src/components/layout/section.tsx
390
- import { cn as cn9, PlusIcon } from "@pelatform/ui.core";
391
-
392
- // src/components/ui/grid-background.tsx
393
- import { cn as cn8 } from "@pelatform/ui.core";
394
- import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
395
- var GridBackground = ({
396
- columns = 4,
397
- className = "",
398
- maxWidthClass = "grid-container"
399
- }) => {
400
- const columnElements = Array.from({ length: columns }, (_, i) => /* @__PURE__ */ jsx10(
401
- "div",
402
- {
403
- className: "h-full w-px",
404
- style: {
405
- backgroundColor: i === 0 ? "var(--grid-base-color)" : "transparent",
406
- backgroundImage: i === 0 ? "none" : `linear-gradient(180deg, var(--grid-dots-color) 50%, transparent 50%)`,
407
- backgroundSize: i === 0 ? "auto" : "1px 8px"
408
- }
409
- },
410
- i
411
- ));
412
- return /* @__PURE__ */ jsx10("div", { className: cn8("stripe-grid -z-50 absolute inset-0 h-full w-full", className), children: /* @__PURE__ */ jsx10("div", { className: "relative h-full w-full overflow-hidden", children: /* @__PURE__ */ jsx10("div", { className: "pointer-events-none absolute top-0 left-0 h-full w-full", "aria-hidden": "true", children: /* @__PURE__ */ jsxs9(
413
- "div",
414
- {
415
- className: cn8("relative mx-auto grid h-full grid-cols-4 grid-rows-1", maxWidthClass),
416
- children: [
417
- columnElements,
418
- /* @__PURE__ */ jsx10(
419
- "div",
420
- {
421
- className: "absolute top-0 right-0 h-full w-px",
422
- style: { backgroundColor: "var(--grid-base-color)" }
423
- }
424
- )
425
- ]
426
- }
427
- ) }) }) });
428
- };
429
-
430
- // src/components/layout/section.tsx
431
- import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
432
- var Cross = () => /* @__PURE__ */ jsxs10("div", { className: "relative h-6 w-6", children: [
433
- /* @__PURE__ */ jsx11("div", { className: "absolute left-3 h-6 w-px bg-background" }),
434
- /* @__PURE__ */ jsx11("div", { className: "absolute top-3 h-px w-6 bg-background" }),
435
- /* @__PURE__ */ jsx11("div", { className: "-translate-x-1/2 -translate-y-1/2 absolute top-1/2 left-1/2", children: /* @__PURE__ */ jsx11(PlusIcon, { size: 20, className: "text-border/70 dark:text-border" }) })
436
- ] });
437
- var Section = ({ children, sectionClassName, className, ...props }) => /* @__PURE__ */ jsx11("section", { className: sectionClassName, ...props, children: /* @__PURE__ */ jsxs10("div", { className: "grid-container relative mx-auto", children: [
438
- /* @__PURE__ */ jsx11(GridBackground, { maxWidthClass: "grid-container" }),
439
- /* @__PURE__ */ jsx11("div", { className: cn9(className), children }),
440
- /* @__PURE__ */ jsx11("div", { className: "-bottom-3 -left-3 absolute z-10 hidden h-6 sm:block", children: /* @__PURE__ */ jsx11(Cross, {}) }),
441
- /* @__PURE__ */ jsx11("div", { className: "-bottom-3 -right-3 -translate-x-px absolute z-10 hidden h-6 sm:block", children: /* @__PURE__ */ jsx11(Cross, {}) })
442
- ] }) });
443
-
444
- // src/components/layout/site-footer.tsx
445
- import { cn as cn10 } from "@pelatform/ui.core";
446
- import { jsx as jsx12 } from "react/jsx-runtime";
447
- function SiteFooter({ children, className }) {
448
- return /* @__PURE__ */ jsx12("footer", { className: cn10("border-border border-t py-5 md:py-0", className), children: /* @__PURE__ */ jsx12("div", { className: "container flex flex-col items-center justify-between gap-4 py-4 md:h-16 md:flex-row", children }) });
449
- }
450
-
451
- // src/components/layout/site-header.tsx
452
- import { cn as cn11 } from "@pelatform/ui.core";
453
- import { jsx as jsx13 } from "react/jsx-runtime";
454
- function SiteHeader({ className, children }) {
455
- return /* @__PURE__ */ jsx13(
456
- "header",
457
- {
458
- className: cn11(
459
- "sticky top-0 z-50 w-full border-border border-b bg-background/95 backdrop-blur-sm supports-backdrop-filter:bg-background/60",
460
- className
461
- ),
462
- children: /* @__PURE__ */ jsx13("div", { className: "container flex h-16 items-center justify-between gap-4", children })
463
- }
464
- );
465
- }
466
-
467
- // src/components/layout/wrapper.tsx
468
- import { cn as cn12 } from "@pelatform/ui.core";
469
- import { jsx as jsx14 } from "react/jsx-runtime";
470
- function MaxWidthWrapper({ className, children }) {
471
- return /* @__PURE__ */ jsx14("div", { className: cn12("mx-auto w-full max-w-7xl p-3 lg:px-10", className), children });
472
- }
473
-
474
- // src/components/mdx/code-display.tsx
475
- import { jsx as jsx15, jsxs as jsxs11 } from "react/jsx-runtime";
476
- function CodeDisplay({
477
- children,
478
- component
479
- }) {
480
- return /* @__PURE__ */ jsxs11("div", { className: "my-6 grid grid-cols-1 gap-6 overflow-hidden md:grid-cols-2", children: [
481
- /* @__PURE__ */ jsx15("div", { className: "w-full overflow-hidden", children }),
482
- /* @__PURE__ */ jsx15("div", { className: "my-6 flex w-full items-center justify-center rounded-lg border bg-gray-50 dark:bg-gray-900", children: component })
483
- ] });
484
- }
485
-
486
- // src/components/mdx/download.tsx
487
- import { cn as cn13, DownloadIcon } from "@pelatform/ui.core";
488
- import { Button } from "@pelatform/ui.default";
489
- import { jsx as jsx16, jsxs as jsxs12 } from "react/jsx-runtime";
490
- function DownloadFile({ children, className, href }) {
491
- return /* @__PURE__ */ jsx16("div", { className: "inline-flex pb-4", children: /* @__PURE__ */ jsx16(Button, { size: "lg", className: cn13("rounded-full", className), children: /* @__PURE__ */ jsxs12("a", { href, target: "_blank", rel: "noopener noreferrer", children: [
492
- /* @__PURE__ */ jsx16(DownloadIcon, { className: "mr-2 size-5" }),
493
- children
494
- ] }) }) });
495
- }
496
-
497
- // src/components/mdx/link.tsx
498
- import { cn as cn14 } from "@pelatform/ui.core";
499
-
500
- // src/components/utils/shared.tsx
501
- import { jsx as jsx17 } from "react/jsx-runtime";
502
- var DefaultImage = ({ src, alt, className }) => /* @__PURE__ */ jsx17("img", { src, alt, className });
503
- var DefaultLink = ({ href, className, children }) => /* @__PURE__ */ jsx17("a", { href, className, children });
504
- var DefaultNavigate = (href) => {
505
- window.location.href = href;
506
- };
507
-
508
- // src/components/mdx/link.tsx
509
- import { jsx as jsx18 } from "react/jsx-runtime";
510
- function ExtraLink({
511
- Link = DefaultLink,
512
- href,
513
- target,
514
- className,
515
- children
516
- }) {
517
- return /* @__PURE__ */ jsx18(
518
- Link,
519
- {
520
- href,
521
- target,
522
- className: cn14("font-medium underline underline-offset-4", className),
523
- children
524
- }
525
- );
526
- }
527
-
528
- // src/components/mdx/video.tsx
529
- import { cn as cn15 } from "@pelatform/ui.core";
530
- import { jsx as jsx19 } from "react/jsx-runtime";
531
- function Video({ className, ...props }) {
532
- return /* @__PURE__ */ jsx19("video", { className: cn15("w-full rounded-lg border", className), controls: true, loop: true, ...props });
533
- }
534
-
535
- // src/components/mdx/wrapper.tsx
536
- import { cn as cn16 } from "@pelatform/ui.core";
537
- import { jsx as jsx20 } from "react/jsx-runtime";
538
- function Wrapper({ children, className }) {
539
- return /* @__PURE__ */ jsx20(
540
- "div",
541
- {
542
- className: cn16(
543
- "prose-no-margin rounded-lg border border-fd-primary/10 bg-radial-[at_bottom] from-blue-500/20 bg-origin-border p-4 dark:bg-black/20",
544
- className
545
- ),
546
- children
547
- }
548
- );
549
- }
550
-
551
- // src/components/mdx/youtube.tsx
552
- import { jsx as jsx21 } from "react/jsx-runtime";
553
- function Youtube({ id }) {
554
- return /* @__PURE__ */ jsx21(
555
- "iframe",
556
- {
557
- src: `https://www.youtube.com/embed/${id}`,
558
- title: `YouTube video with ID ${id}`,
559
- style: {
560
- width: "100%",
561
- height: "auto",
562
- aspectRatio: "16/9",
563
- border: "none",
564
- borderRadius: ".75rem",
565
- overflow: "hidden"
566
- },
567
- allowFullScreen: true
568
- }
569
- );
570
- }
571
-
572
- // src/components/navigation/back-link.tsx
573
- import { ChevronLeftIcon, cn as cn17 } from "@pelatform/ui.core";
574
- import { Button as Button2 } from "@pelatform/ui.default";
575
- import { jsx as jsx22, jsxs as jsxs13 } from "react/jsx-runtime";
576
- function BackLink({ Link = DefaultLink, children, href, className }) {
577
- return /* @__PURE__ */ jsxs13(
578
- Link,
579
- {
580
- href,
581
- className: cn17(
582
- "group flex items-center gap-2 text-foreground transition-colors duration-100 hover:text-foreground/75",
583
- className
584
- ),
585
- children: [
586
- /* @__PURE__ */ jsx22(
587
- Button2,
588
- {
589
- variant: "secondary",
590
- mode: "icon",
591
- className: "group-hover:-translate-x-0.5 size-7.5! transition-transform duration-100",
592
- children: /* @__PURE__ */ jsx22(ChevronLeftIcon, {})
593
- }
594
- ),
595
- /* @__PURE__ */ jsx22("span", { className: "font-semibold text-lg", children })
596
- ]
597
- }
598
- );
599
- }
600
-
601
- // src/components/navigation/command-menu.tsx
602
- import * as React from "react";
603
- import { cn as cn18, googleTrackEvent, SearchIcon } from "@pelatform/ui.core";
604
- import { Button as Button3, CommandDialog, CommandInput, CommandList } from "@pelatform/ui.default";
605
- import { Fragment as Fragment2, jsx as jsx23, jsxs as jsxs14 } from "react/jsx-runtime";
606
- function CommandMenu({
607
- children,
608
- classButton,
609
- classDialog,
610
- searchButtonText = "Search ...",
611
- commandInputPlaceholder = "Type a command or search...",
612
- keyHint = "\u2318K",
613
- ...props
614
- }) {
615
- const [open, setOpen] = React.useState(false);
616
- React.useEffect(() => {
617
- const handleKeyDown = (e) => {
618
- const isCommandShortcut = e.key === "k" && (e.metaKey || e.ctrlKey) || e.key === "/";
619
- if (isCommandShortcut) {
620
- const isTypingInField = e.target instanceof HTMLElement && e.target.isContentEditable || e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement || e.target instanceof HTMLSelectElement;
621
- if (isTypingInField) {
622
- return;
623
- }
624
- e.preventDefault();
625
- setOpen((currentOpen) => {
626
- const newState = !currentOpen;
627
- if (newState) {
628
- googleTrackEvent({
629
- name: "site_header_search_trigger_shortcut",
630
- properties: {
631
- method: e.key === "/" ? "slash" : "cmd_k",
632
- category: "search",
633
- label: `Search Trigger - ${e.key === "/" ? "Slash" : "Cmd+K"}`,
634
- timestamp: Date.now()
635
- }
636
- });
637
- }
638
- return newState;
639
- });
640
- }
641
- };
642
- document.addEventListener("keydown", handleKeyDown);
643
- return () => document.removeEventListener("keydown", handleKeyDown);
644
- }, []);
645
- const handleButtonClick = React.useCallback(() => {
646
- googleTrackEvent({
647
- name: "site_header_search_trigger_click",
648
- properties: {
649
- method: "button_click",
650
- category: "search",
651
- label: "Search Trigger - Button Click",
652
- timestamp: Date.now()
653
- }
654
- });
655
- }, []);
656
- const handleOpenMenu = React.useCallback(() => {
657
- setOpen(true);
658
- handleButtonClick();
659
- }, [handleButtonClick]);
660
- return /* @__PURE__ */ jsxs14(Fragment2, { children: [
661
- /* @__PURE__ */ jsxs14(
662
- Button3,
663
- {
664
- variant: "outline",
665
- mode: "input",
666
- size: "sm",
667
- className: cn18("relative h-8 w-full py-0 pl-2 sm:w-40 sm:pr-12 lg:w-48", classButton),
668
- onClick: handleOpenMenu,
669
- "aria-label": `Open command menu (${keyHint})`,
670
- ...props,
671
- children: [
672
- /* @__PURE__ */ jsx23(SearchIcon, { className: "mr-2 h-4 w-4", "aria-hidden": "true" }),
673
- /* @__PURE__ */ jsx23("span", { className: "inline-flex text-muted-foreground", children: searchButtonText }),
674
- /* @__PURE__ */ jsx23(
675
- "kbd",
676
- {
677
- className: "-translate-y-1/2 pointer-events-none absolute top-1/2 right-[5px] hidden h-5 select-none items-center gap-1 rounded border bg-muted px-1.5 font-medium font-mono text-[10px] opacity-100 sm:flex",
678
- "aria-label": `Keyboard shortcut: ${keyHint}`,
679
- children: keyHint
680
- }
681
- )
682
- ]
683
- }
684
- ),
685
- /* @__PURE__ */ jsxs14(
686
- CommandDialog,
687
- {
688
- open,
689
- onOpenChange: setOpen,
690
- className: cn18(
691
- "**:data-dialog-close:end-[0.925rem] **:data-dialog-close:top-[0.925rem]",
692
- classDialog
693
- ),
694
- children: [
695
- /* @__PURE__ */ jsx23(CommandInput, { placeholder: commandInputPlaceholder, "aria-label": "Search commands" }),
696
- /* @__PURE__ */ jsx23(CommandList, { children })
697
- ]
698
- }
699
- )
700
- ] });
701
- }
702
-
703
- // src/components/navigation/main-nav.tsx
704
- import { ArrowUpRightIcon, ChevronDownIcon, cn as cn19, googleTrackEvent as googleTrackEvent2 } from "@pelatform/ui.core";
705
- import {
706
- DropdownMenu,
707
- DropdownMenuContent,
708
- DropdownMenuItem,
709
- DropdownMenuSub,
710
- DropdownMenuSubContent,
711
- DropdownMenuSubTrigger,
712
- DropdownMenuTrigger
713
- } from "@pelatform/ui.default";
714
- import { jsx as jsx24, jsxs as jsxs15 } from "react/jsx-runtime";
715
- function MainNav({ Link = DefaultLink, pathname, items, className }) {
716
- return /* @__PURE__ */ jsx24("div", { className: cn19("mr-4 hidden items-center justify-center md:flex", className), children: /* @__PURE__ */ jsx24("nav", { className: "flex items-center gap-4 font-medium text-sm xl:gap-6", children: items.map((item) => /* @__PURE__ */ jsx24(NavItemRenderer, { Link, item, pathname, level: 1 }, item.title)) }) });
717
- }
718
- function NavItemRenderer({ Link = DefaultLink, item, pathname, level }) {
719
- const hasChildren = item.children && item.children.length > 0;
720
- const isActive = hasChildren ? item.children?.some(
721
- (child) => child.href === pathname || child.href !== "/" && child.href && pathname?.startsWith(child.href) || (child.children?.some(
722
- (grandchild) => grandchild.href === pathname || grandchild.href !== "/" && grandchild.href && pathname?.startsWith(grandchild.href)
723
- ) ?? false)
724
- ) ?? false : item.href === pathname || item.href !== "/" && item.href && pathname?.startsWith(item.href);
725
- if (hasChildren && level <= 3) {
726
- return /* @__PURE__ */ jsxs15(DropdownMenu, { children: [
727
- /* @__PURE__ */ jsx24(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs15(
728
- "button",
729
- {
730
- className: cn19(
731
- "inline-flex cursor-pointer items-center gap-1 transition-colors hover:text-foreground/80 focus-visible:outline-0",
732
- isActive ? "text-foreground" : "text-foreground/60"
733
- ),
734
- children: [
735
- item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
736
- item.title,
737
- /* @__PURE__ */ jsx24(ChevronDownIcon, { className: "size-3.5" })
738
- ]
739
- }
740
- ) }),
741
- /* @__PURE__ */ jsx24(
742
- DropdownMenuContent,
743
- {
744
- className: "min-w-[150px] overflow-visible",
745
- side: "bottom",
746
- align: "start",
747
- sideOffset: 15,
748
- alignOffset: -10,
749
- children: item.children?.map((child) => /* @__PURE__ */ jsx24(
750
- ChildNavItemRenderer,
751
- {
752
- item: child,
753
- pathname,
754
- level: level + 1
755
- },
756
- child.title
757
- ))
758
- }
759
- )
760
- ] });
761
- }
762
- return /* @__PURE__ */ jsxs15(
763
- Link,
764
- {
765
- href: item.href ?? "#",
766
- ...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
767
- className: cn19(
768
- "relative inline-flex items-center gap-1 transition-colors hover:text-foreground/80",
769
- isActive ? "text-foreground" : "text-foreground/60"
770
- ),
771
- onClick: () => handleMenuClick(item),
772
- children: [
773
- item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
774
- item.title,
775
- item.external && /* @__PURE__ */ jsx24(ArrowUpRightIcon, { className: "size-3.5 opacity-60" })
776
- ]
777
- }
778
- );
779
- }
780
- function ChildNavItemRenderer({ Link = DefaultLink, item, pathname, level }) {
781
- const hasChildren = item.children && item.children.length > 0;
782
- const isChildActive = item.href === pathname || item.href !== "/" && item.href && pathname?.startsWith(item.href) || hasChildren && (item.children?.some(
783
- (grandchild) => grandchild.href === pathname || grandchild.href !== "/" && grandchild.href && pathname?.startsWith(grandchild.href)
784
- ) ?? false);
785
- if (hasChildren && level <= 3) {
786
- return /* @__PURE__ */ jsxs15(DropdownMenuSub, { children: [
787
- /* @__PURE__ */ jsxs15(
788
- DropdownMenuSubTrigger,
789
- {
790
- className: cn19(
791
- "flex w-full items-center justify-between text-muted-foreground hover:text-foreground",
792
- isChildActive && "font-medium text-foreground"
793
- ),
794
- children: [
795
- item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
796
- item.title
797
- ]
798
- }
799
- ),
800
- /* @__PURE__ */ jsx24(DropdownMenuSubContent, { className: "min-w-[150px]", children: item.children?.map((child) => /* @__PURE__ */ jsx24(
801
- ChildNavItemRenderer,
802
- {
803
- item: child,
804
- pathname,
805
- level: level + 1
806
- },
807
- child.title
808
- )) })
809
- ] });
810
- }
811
- return /* @__PURE__ */ jsx24(DropdownMenuItem, { asChild: true, children: /* @__PURE__ */ jsxs15(
812
- Link,
813
- {
814
- href: item.href || "",
815
- ...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
816
- className: cn19(
817
- "block w-full cursor-pointer transition-colors",
818
- isChildActive ? "font-medium text-foreground" : "text-muted-foreground hover:text-foreground"
819
- ),
820
- onClick: () => handleMenuClick(item),
821
- children: [
822
- item.icon && /* @__PURE__ */ jsx24(item.icon, {}),
823
- item.title,
824
- item.external && /* @__PURE__ */ jsx24(ArrowUpRightIcon, { className: "size-3.5 opacity-60" })
825
- ]
826
- }
827
- ) });
828
- }
829
- function handleMenuClick(item) {
830
- googleTrackEvent2({
831
- name: `site_header_menu_${item.title.toLowerCase().replace(/\s+/g, "_")}_link_click`,
832
- properties: {
833
- menu_item: item.title,
834
- menu_path: item.href || "#",
835
- is_external: !!item.external,
836
- category: "navigation",
837
- label: `Header Menu ${item.title} Click`
838
- }
839
- });
840
- }
841
-
842
- // src/components/navigation/mobile-nav.tsx
843
- import { useCallback as useCallback2, useState as useState2 } from "react";
844
- import {
845
- ArrowUpRightIcon as ArrowUpRightIcon2,
846
- ChevronDownIcon as ChevronDownIcon2,
847
- cn as cn20,
848
- MenuIcon
849
- } from "@pelatform/ui.core";
850
- import {
851
- Button as Button4,
852
- Collapsible,
853
- CollapsibleContent,
854
- CollapsibleTrigger,
855
- Drawer,
856
- DrawerContent,
857
- DrawerDescription,
858
- DrawerTitle,
859
- DrawerTrigger
860
- } from "@pelatform/ui.default";
861
- import { jsx as jsx25, jsxs as jsxs16 } from "react/jsx-runtime";
862
- function MobileNav({ children, className }) {
863
- const { setMetaColor, metaColor } = useMetaColor();
864
- const [open, setOpen] = useState2(false);
865
- const onOpenChange = useCallback2(
866
- (open2) => {
867
- setOpen(open2);
868
- setMetaColor(open2 ? "#09090b" : metaColor);
869
- },
870
- [setMetaColor, metaColor]
871
- );
872
- return /* @__PURE__ */ jsx25("div", { className: cn20("flex items-center gap-2.5 md:hidden", className), children: /* @__PURE__ */ jsxs16(Drawer, { open, onOpenChange, children: [
873
- /* @__PURE__ */ jsx25(DrawerTrigger, { asChild: true, children: /* @__PURE__ */ jsxs16(Button4, { variant: "ghost", className: "group/toggle size-8 px-0 text-foreground", children: [
874
- /* @__PURE__ */ jsx25(MenuIcon, {}),
875
- /* @__PURE__ */ jsx25("span", { className: "sr-only", children: "Toggle Menu" })
876
- ] }) }),
877
- /* @__PURE__ */ jsxs16(DrawerContent, { className: "max-h-[60svh] p-0", children: [
878
- /* @__PURE__ */ jsx25(DrawerTitle, { className: "sr-only", children: "Mobile menu" }),
879
- /* @__PURE__ */ jsx25("div", { className: "overflow-auto p-6", children }),
880
- /* @__PURE__ */ jsx25(DrawerDescription, { className: "sr-only", children: "Mobile menu" })
881
- ] })
882
- ] }) });
883
- }
884
- function MobileNavItemRenderer({
885
- Link = DefaultLink,
886
- navigate = DefaultNavigate,
887
- item,
888
- pathname,
889
- level,
890
- onOpenChange
891
- }) {
892
- const router = navigate;
893
- const [isOpen, setIsOpen] = useState2(false);
894
- const hasChildren = item.children && item.children.length > 0;
895
- const isActive = hasChildren ? item.children?.some(
896
- (child) => child.href === pathname || child.href !== "/" && child.href && pathname?.startsWith(child.href) || (child.children?.some(
897
- (grandchild) => grandchild.href === pathname || grandchild.href !== "/" && grandchild.href && pathname?.startsWith(grandchild.href)
898
- ) ?? false)
899
- ) ?? false : item.href === pathname || item.href !== "/" && item.href && pathname?.startsWith(item.href);
900
- if (hasChildren && level <= 3) {
901
- console.log(item);
902
- return /* @__PURE__ */ jsxs16(Collapsible, { open: isOpen, onOpenChange: setIsOpen, children: [
903
- /* @__PURE__ */ jsxs16(
904
- CollapsibleTrigger,
905
- {
906
- className: cn20(
907
- "flex w-full cursor-pointer items-center gap-1 text-sm transition-colors",
908
- isOpen ? "text-foreground" : "text-foreground/60"
909
- ),
910
- children: [
911
- item.icon && /* @__PURE__ */ jsx25(item.icon, {}),
912
- item.title,
913
- /* @__PURE__ */ jsx25(
914
- ChevronDownIcon2,
915
- {
916
- className: cn20(
917
- "ml-auto size-3.5 opacity-60 transition-transform",
918
- isOpen && "rotate-180"
919
- )
920
- }
921
- )
922
- ]
923
- }
924
- ),
925
- /* @__PURE__ */ jsx25(CollapsibleContent, { children: /* @__PURE__ */ jsx25("div", { className: cn20("flex flex-col space-y-2.5 pt-3", `ps-5`), children: item.children.map((child) => /* @__PURE__ */ jsx25(
926
- MobileNavItemRenderer,
927
- {
928
- item: child,
929
- pathname,
930
- level: level + 1,
931
- onOpenChange
932
- },
933
- child.title
934
- )) }) })
935
- ] });
936
- }
937
- return /* @__PURE__ */ jsxs16(
938
- Link,
939
- {
940
- href: item.href || "#",
941
- ...item.external ? { target: "_blank", rel: "noopener noreferrer" } : {},
942
- onClick: () => {
943
- if (!item.external && item.href) {
944
- router(item.href.toString());
945
- }
946
- onOpenChange?.(false);
947
- handleMenuClick(item);
948
- },
949
- className: cn20(
950
- "inline-flex items-center gap-1 text-sm transition-colors",
951
- isActive ? "text-foreground" : "text-foreground/60"
952
- ),
953
- children: [
954
- item.icon && /* @__PURE__ */ jsx25(item.icon, {}),
955
- item.title,
956
- item.external && /* @__PURE__ */ jsx25(ArrowUpRightIcon2, { className: "ml-1 size-3.5 opacity-60" })
957
- ]
958
- }
959
- );
960
- }
961
-
962
- // src/components/providers/query-provider.tsx
963
- import { useState as useState3 } from "react";
964
- import { QueryCache, QueryClient, QueryClientProvider } from "@tanstack/react-query";
965
- import { CircleAlertIcon as CircleAlertIcon2 } from "@pelatform/ui.core";
966
- import { Alert as Alert2, AlertIcon as AlertIcon2, AlertTitle as AlertTitle2 } from "@pelatform/ui.default";
967
- import { toast as toast2 } from "@pelatform/ui.default/dep";
968
- import { jsx as jsx26, jsxs as jsxs17 } from "react/jsx-runtime";
969
- var QueryProvider = ({
970
- client: clientProps,
971
- children
972
- }) => {
973
- const [queryClient] = useState3(
974
- () => new QueryClient({
975
- /** Global query defaults for all queries */
976
- defaultOptions: {
977
- queries: {
978
- /** Time before data is considered stale (5 minutes) */
979
- staleTime: 5 * 60 * 1e3,
980
- /** Time before inactive queries are garbage collected (10 minutes) */
981
- gcTime: 10 * 60 * 1e3,
982
- /** Number of retry attempts on failure */
983
- retry: (failureCount, error) => {
984
- if (error?.status && error.status >= 400 && error.status < 500) {
985
- return false;
986
- }
987
- return failureCount < 3;
988
- },
989
- /** Delay between retries (exponential backoff) */
990
- retryDelay: (attemptIndex) => Math.min(1e3 * 2 ** attemptIndex, 3e4),
991
- /** Refetch on window focus for fresh data */
992
- refetchOnWindowFocus: true,
993
- /** Refetch when network reconnects */
994
- refetchOnReconnect: true
995
- },
996
- mutations: {
997
- /** Number of retry attempts for mutations */
998
- retry: 1,
999
- /** Delay between mutation retries */
1000
- retryDelay: 1e3
1001
- }
1002
- },
1003
- /** Global query cache with error handling */
1004
- queryCache: new QueryCache({
1005
- onError: (error, query) => {
1006
- const message = error?.response?.data?.message || error?.message || "Something went wrong. Please try again.";
1007
- if (process.env.NODE_ENV === "development") {
1008
- console.error("Query Error:", {
1009
- error,
1010
- queryKey: query.queryKey,
1011
- message,
1012
- timestamp: (/* @__PURE__ */ new Date()).toISOString()
1013
- });
1014
- }
1015
- toast2.custom(
1016
- () => /* @__PURE__ */ jsxs17(Alert2, { variant: "mono", icon: "destructive", close: false, children: [
1017
- /* @__PURE__ */ jsx26(AlertIcon2, { children: /* @__PURE__ */ jsx26(CircleAlertIcon2, {}) }),
1018
- /* @__PURE__ */ jsx26(AlertTitle2, { children: message })
1019
- ] }),
1020
- {
1021
- position: "top-center",
1022
- duration: 5e3,
1023
- // Show for 5 seconds
1024
- id: `query-error-${query.queryHash}`
1025
- // Prevent duplicate toasts
1026
- }
1027
- );
1028
- }
1029
- })
1030
- })
1031
- );
1032
- return /* @__PURE__ */ jsx26(QueryClientProvider, { client: clientProps ?? queryClient, children });
1033
- };
1034
-
1035
- // src/components/providers/theme-provider.tsx
1036
- import { DEFAULT_THEME_MODE, THEME_MODES } from "@pelatform/ui.core";
1037
- import { TooltipProvider } from "@pelatform/ui.default";
1038
- import { ThemeProvider as NextThemesProvider } from "@pelatform/ui.default/dep";
1039
- import { jsx as jsx27 } from "react/jsx-runtime";
1040
- function ThemeProvider({ children, ...props }) {
1041
- return /* @__PURE__ */ jsx27(
1042
- NextThemesProvider,
1043
- {
1044
- attribute: "class",
1045
- defaultTheme: DEFAULT_THEME_MODE,
1046
- enableSystem: true,
1047
- disableTransitionOnChange: true,
1048
- enableColorScheme: true,
1049
- storageKey: "theme",
1050
- themes: [THEME_MODES.LIGHT, THEME_MODES.DARK, THEME_MODES.SYSTEM],
1051
- ...props,
1052
- children: /* @__PURE__ */ jsx27(TooltipProvider, { delayDuration: 0, children })
1053
- }
1054
- );
1055
- }
1056
-
1057
- // src/components/ui/announcement.tsx
1058
- import { cn as cn21 } from "@pelatform/ui.core";
1059
- import { Badge as Badge2 } from "@pelatform/ui.default";
1060
- import { jsx as jsx28 } from "react/jsx-runtime";
1061
- var Announcement = ({
1062
- variant = "outline",
1063
- themed = false,
1064
- className,
1065
- ...props
1066
- }) => /* @__PURE__ */ jsx28(
1067
- Badge2,
1068
- {
1069
- variant,
1070
- className: cn21(
1071
- "group max-w-full gap-2 rounded-full bg-background px-3 py-0.5 font-medium shadow-sm transition-all",
1072
- "hover:shadow-md",
1073
- themed && "announcement-themed border-foreground/5",
1074
- className
1075
- ),
1076
- ...props
1077
- }
1078
- );
1079
- var AnnouncementTag = ({ className, ...props }) => /* @__PURE__ */ jsx28(
1080
- "div",
1081
- {
1082
- className: cn21(
1083
- "-ml-2.5 shrink-0 truncate rounded-full bg-foreground/5 px-2.5 py-1 text-xs",
1084
- "group-[.announcement-themed]:bg-background/60",
1085
- className
1086
- ),
1087
- ...props
1088
- }
1089
- );
1090
- var AnnouncementTitle = ({ className, ...props }) => /* @__PURE__ */ jsx28("div", { className: cn21("flex items-center gap-1 truncate py-1", className), ...props });
1091
-
1092
- // src/components/ui/background-paths.tsx
1093
- import { motion } from "@pelatform/ui.animation";
1094
- import { cn as cn22 } from "@pelatform/ui.core";
1095
- import { jsx as jsx29, jsxs as jsxs18 } from "react/jsx-runtime";
1096
- function FloatingPaths({
1097
- position,
1098
- color = "text-slate-950 dark:text-white"
1099
- }) {
1100
- const paths = Array.from({ length: 36 }, (_, i) => ({
1101
- id: i,
1102
- d: `M-${380 - i * 5 * position} -${189 + i * 6}C-${380 - i * 5 * position} -${189 + i * 6} -${312 - i * 5 * position} ${216 - i * 6} ${152 - i * 5 * position} ${343 - i * 6}C${616 - i * 5 * position} ${470 - i * 6} ${684 - i * 5 * position} ${875 - i * 6} ${684 - i * 5 * position} ${875 - i * 6}`,
1103
- color: `rgba(15,23,42,${0.1 + i * 0.03})`,
1104
- width: 0.5 + i * 0.03
1105
- }));
1106
- return /* @__PURE__ */ jsx29("div", { className: "-z-50 pointer-events-none absolute inset-0", children: /* @__PURE__ */ jsx29("svg", { className: cn22("h-full w-full", color), viewBox: "0 0 696 316", fill: "none", children: paths.map((path) => /* @__PURE__ */ jsx29(
1107
- motion.path,
1108
- {
1109
- d: path.d,
1110
- stroke: "currentColor",
1111
- strokeWidth: path.width,
1112
- strokeOpacity: 0.1 + path.id * 0.03,
1113
- initial: { pathLength: 0.3, opacity: 0.6 },
1114
- animate: {
1115
- pathLength: 1,
1116
- opacity: [0.3, 0.6, 0.3],
1117
- pathOffset: [0, 1, 0]
1118
- },
1119
- transition: {
1120
- duration: 20 + Math.random() * 10,
1121
- repeat: Number.POSITIVE_INFINITY,
1122
- ease: "linear"
1123
- }
1124
- },
1125
- path.id
1126
- )) }) });
1127
- }
1128
- function BackgroundPaths({ color = "text-slate-950 dark:text-white" }) {
1129
- return /* @__PURE__ */ jsx29("div", { className: "relative flex min-h-screen w-full items-center justify-center overflow-hidden bg-white dark:bg-neutral-950", children: /* @__PURE__ */ jsxs18("div", { className: "absolute inset-0", children: [
1130
- /* @__PURE__ */ jsx29(FloatingPaths, { position: 1, color }),
1131
- /* @__PURE__ */ jsx29(FloatingPaths, { position: -1, color })
1132
- ] }) });
1133
- }
1134
-
1135
- // src/components/ui/book.tsx
1136
- import { cn as cn23 } from "@pelatform/ui.core";
1137
- import { jsx as jsx30, jsxs as jsxs19 } from "react/jsx-runtime";
1138
- function Book(props) {
1139
- const {
1140
- children,
1141
- color = "#f50537",
1142
- depth,
1143
- texture,
1144
- variant = "default",
1145
- textColor,
1146
- illustration,
1147
- width
1148
- } = props;
1149
- return /* @__PURE__ */ jsx30(
1150
- "div",
1151
- {
1152
- className: cn23("group perspective-[900px] inline-block w-fit"),
1153
- style: {
1154
- "--book-color": color,
1155
- "--text-color": textColor,
1156
- "--book-depth": `${depth || 4}cqw`,
1157
- "--book-width": `${width || 196}px`
1158
- },
1159
- children: /* @__PURE__ */ jsxs19("div", { className: "transform-3d group-hover:transform-[rotateY(-20deg)_scale(1.066)translateX(-8px)] relative aspect-49/60 w-fit min-w-[calc(var(--book-width))] rotate-0 transition-transform duration-500 ease-out contain-inline-size", children: [
1160
- /* @__PURE__ */ jsxs19(
1161
- Stack,
1162
- {
1163
- align: "stretch",
1164
- className: "absolute size-full overflow-hidden rounded-r rounded-l border border-border bg-stone-100 shadow-book dark:bg-stone-800",
1165
- children: [
1166
- variant !== "simple" && /* @__PURE__ */ jsxs19(
1167
- Stack,
1168
- {
1169
- shrink: true,
1170
- grow: true,
1171
- direction: "row",
1172
- className: cn23(
1173
- "relative min-w-[calc(var(--book-width))] overflow-hidden bg-(--book-color)"
1174
- ),
1175
- children: [
1176
- /* @__PURE__ */ jsx30("div", { className: "absolute inset-y-0 min-w-[8.2%] bg-book-bind-bg opacity-100 mix-blend-overlay" }),
1177
- illustration && /* @__PURE__ */ jsx30("div", { className: "object-cover", children: illustration })
1178
- ]
1179
- }
1180
- ),
1181
- /* @__PURE__ */ jsxs19(Stack, { grow: variant === "simple", direction: "row", className: "h-fit", children: [
1182
- /* @__PURE__ */ jsx30("div", { className: "h-full min-w-[8.2%] bg-book-bind-bg opacity-100 mix-blend-overlay" }),
1183
- /* @__PURE__ */ jsx30("div", { className: "w-full contain-inline-size", children })
1184
- ] }),
1185
- texture && /* @__PURE__ */ jsx30(
1186
- "div",
1187
- {
1188
- "aria-hidden": true,
1189
- className: "absolute inset-0 bg-ali bg-cover bg-no-repeat opacity-60 mix-blend-hard-light"
1190
- }
1191
- )
1192
- ]
1193
- }
1194
- ),
1195
- /* @__PURE__ */ jsx30(
1196
- "div",
1197
- {
1198
- "aria-hidden": true,
1199
- className: "absolute top-[3px] h-[calc(100%-2*6px)] w-[calc(var(--book-depth)-2px)] bg-book-pages",
1200
- style: {
1201
- transform: "translateX(calc(var(--book-width) - var(--book-depth) / 2 - 3px)) rotateY(90deg) translateX(calc(var(--book-depth) / 2))"
1202
- }
1203
- }
1204
- ),
1205
- /* @__PURE__ */ jsx30(
1206
- "div",
1207
- {
1208
- "aria-hidden": true,
1209
- className: "book-bg absolute left-0 h-full w-full rounded-r rounded-l-md bg-(--book-color)",
1210
- style: {
1211
- transform: "translateZ(calc(-1 * var(--book-depth)))"
1212
- }
1213
- }
1214
- )
1215
- ] })
1216
- }
1217
- );
1218
- }
1219
- function Stack(props) {
1220
- const {
1221
- children,
1222
- shrink = false,
1223
- grow = false,
1224
- justify = "start",
1225
- align = "start",
1226
- wrap = false,
1227
- padding = 0,
1228
- gap = 0,
1229
- direction = "column",
1230
- className,
1231
- ...etc
1232
- } = props;
1233
- return /* @__PURE__ */ jsx30(
1234
- "div",
1235
- {
1236
- className,
1237
- style: {
1238
- display: "flex",
1239
- flex: "initial",
1240
- flexDirection: direction,
1241
- alignItems: align === "start" ? "flex-start" : align === "end" ? "flex-end" : align,
1242
- justifyContent: justify === "start" ? "flex-start" : justify === "end" ? "flex-end" : justify,
1243
- flexWrap: wrap ? "wrap" : "nowrap",
1244
- flexGrow: grow ? 1 : 0,
1245
- flexShrink: shrink ? 1 : 0,
1246
- padding: `${padding * 4}px`,
1247
- gap: `${gap * 4}px`
1248
- },
1249
- ...etc,
1250
- children
1251
- }
1252
- );
1253
- }
1254
-
1255
- // src/components/ui/dots-pattern.tsx
1256
- import { useId as useId2 } from "react";
1257
- import { cn as cn24 } from "@pelatform/ui.core";
1258
- import { jsx as jsx31, jsxs as jsxs20 } from "react/jsx-runtime";
1259
- function DotsPattern({
1260
- dotSize = 2,
1261
- gapSize = 10,
1262
- patternOffset = [0, 0],
1263
- className
1264
- }) {
1265
- const id = useId2();
1266
- return /* @__PURE__ */ jsxs20(
1267
- "svg",
1268
- {
1269
- className: cn24("pointer-events-none absolute inset-0 text-foreground/10", className),
1270
- width: "100%",
1271
- height: "100%",
1272
- children: [
1273
- /* @__PURE__ */ jsx31("defs", { children: /* @__PURE__ */ jsx31(
1274
- "pattern",
1275
- {
1276
- id: `dots-${id}`,
1277
- x: patternOffset[0] - 1,
1278
- y: patternOffset[1] - 1,
1279
- width: dotSize + gapSize,
1280
- height: dotSize + gapSize,
1281
- patternUnits: "userSpaceOnUse",
1282
- children: /* @__PURE__ */ jsx31("rect", { x: 1, y: 1, width: dotSize, height: dotSize, fill: "currentColor" })
1283
- }
1284
- ) }),
1285
- /* @__PURE__ */ jsx31("rect", { fill: `url(#dots-${id})`, width: "100%", height: "100%" })
1286
- ]
1287
- }
1288
- );
1289
- }
1290
-
1291
- // src/components/ui/hexagon-badge.tsx
1292
- import { cn as cn25 } from "@pelatform/ui.core";
1293
- import { jsx as jsx32, jsxs as jsxs21 } from "react/jsx-runtime";
1294
- var HexagonBadge = ({ children, classNames }) => {
1295
- return /* @__PURE__ */ jsxs21("div", { className: cn25("relative shrink-0", classNames?.base), children: [
1296
- /* @__PURE__ */ jsxs21(
1297
- "svg",
1298
- {
1299
- className: cn25("h-full w-full", classNames?.svg),
1300
- width: "44",
1301
- height: "48",
1302
- viewBox: "0 0 44 48",
1303
- fill: "none",
1304
- xmlns: "http://www.w3.org/2000/svg",
1305
- children: [
1306
- /* @__PURE__ */ jsx32(
1307
- "path",
1308
- {
1309
- d: "M16 2.4641C19.7128 0.320509 24.2872 0.320508 28 2.4641L37.6506 8.0359C41.3634 10.1795 43.6506 14.141 43.6506 \n 18.4282V29.5718C43.6506 33.859 41.3634 37.8205 37.6506 39.9641L28 45.5359C24.2872 47.6795 19.7128 47.6795 16 45.5359L6.34937 \n 39.9641C2.63655 37.8205 0.349365 33.859 0.349365 29.5718V18.4282C0.349365 14.141 2.63655 10.1795 6.34937 8.0359L16 2.4641Z",
1310
- fill: ""
1311
- }
1312
- ),
1313
- /* @__PURE__ */ jsx32(
1314
- "path",
1315
- {
1316
- d: "M16.25 2.89711C19.8081 0.842838 24.1919 0.842837 27.75 2.89711L37.4006 8.46891C40.9587 10.5232 43.1506 14.3196 43.1506 \n 18.4282V29.5718C43.1506 33.6804 40.9587 37.4768 37.4006 39.5311L27.75 45.1029C24.1919 47.1572 19.8081 47.1572 16.25 45.1029L6.59937 \n 39.5311C3.04125 37.4768 0.849365 33.6803 0.849365 29.5718V18.4282C0.849365 14.3196 3.04125 10.5232 6.59937 8.46891L16.25 2.89711Z",
1317
- stroke: ""
1318
- }
1319
- )
1320
- ]
1321
- }
1322
- ),
1323
- /* @__PURE__ */ jsx32(
1324
- "div",
1325
- {
1326
- className: cn25(
1327
- "-translate-y-2/4 -translate-x-2/4 absolute start-2/4 top-2/4 leading-none rtl:translate-x-2/4",
1328
- classNames?.wraper
1329
- ),
1330
- children
1331
- }
1332
- )
1333
- ] });
1334
- };
1335
-
1336
- // src/components/ui/image-input.tsx
1337
- import {
1338
- useCallback as useCallback3,
1339
- useRef,
1340
- useState as useState4
1341
- } from "react";
1342
- import { Fragment as Fragment3, jsx as jsx33, jsxs as jsxs22 } from "react/jsx-runtime";
1343
- var DEFAULT_NULL_INDEX = -1;
1344
- var DEFAULT_DATA_URL_KEY = "dataURL";
1345
- var openFileDialog = (inputRef) => {
1346
- if (!inputRef.current) {
1347
- return;
1348
- }
1349
- inputRef.current.click();
1350
- };
1351
- var getAcceptTypeString = (acceptType, allowNonImageType) => {
1352
- if (acceptType?.length) return acceptType.map((item) => `.${item}`).join(", ");
1353
- if (allowNonImageType) return "";
1354
- return "image/*";
1355
- };
1356
- var getBase64 = async (file) => {
1357
- const reader = new FileReader();
1358
- return await new Promise((resolve) => {
1359
- reader.addEventListener("load", () => {
1360
- resolve(String(reader.result));
1361
- });
1362
- reader.readAsDataURL(file);
1363
- });
1364
- };
1365
- var getImage = async (file) => {
1366
- const image = new Image();
1367
- return await new Promise((resolve) => {
1368
- image.addEventListener("load", () => {
1369
- resolve(image);
1370
- });
1371
- image.src = URL.createObjectURL(file);
1372
- });
1373
- };
1374
- var getListFiles = async (files, dataURLKey) => {
1375
- const promiseFiles = [];
1376
- for (let i = 0; i < files.length; i += 1) {
1377
- promiseFiles.push(getBase64(files[i]));
1378
- }
1379
- return await Promise.all(promiseFiles).then((fileListBase64) => {
1380
- const fileList = fileListBase64.map((base64, index) => ({
1381
- [dataURLKey]: base64,
1382
- file: files[index]
1383
- }));
1384
- return fileList;
1385
- });
1386
- };
1387
- var ImageInput = ({
1388
- value,
1389
- acceptType,
1390
- inputProps,
1391
- multiple,
1392
- children,
1393
- onChange
1394
- }) => {
1395
- const inValue = value || [];
1396
- const inputRef = useRef(null);
1397
- const [keyUpdate, setKeyUpdate] = useState4(DEFAULT_NULL_INDEX);
1398
- const [isDragging, setIsDragging] = useState4(false);
1399
- const onImageRemoveAll = useCallback3(() => {
1400
- onChange?.([]);
1401
- }, [onChange]);
1402
- const handleClickInput = useCallback3(() => {
1403
- openFileDialog(inputRef);
1404
- }, []);
1405
- const onImageUpload = useCallback3(() => {
1406
- handleClickInput();
1407
- }, [handleClickInput]);
1408
- const onInputChange = async (e) => {
1409
- await handleChange(e.target.files);
1410
- if (inputRef.current) inputRef.current.value = "";
1411
- };
1412
- const handleChange = async (files) => {
1413
- if (!files) return;
1414
- const fileList = await getListFiles(files, DEFAULT_DATA_URL_KEY);
1415
- if (!fileList.length) return;
1416
- let updatedFileList;
1417
- const updatedIndexes = [];
1418
- if (keyUpdate > DEFAULT_NULL_INDEX) {
1419
- const [firstFile] = fileList;
1420
- updatedFileList = [...inValue];
1421
- updatedFileList[keyUpdate] = firstFile;
1422
- updatedIndexes.push(keyUpdate);
1423
- } else if (multiple) {
1424
- updatedFileList = [...inValue, ...fileList];
1425
- for (let i = inValue.length; i < updatedFileList.length; i += 1) {
1426
- updatedIndexes.push(i);
1427
- }
1428
- } else {
1429
- updatedFileList = [fileList[0]];
1430
- updatedIndexes.push(0);
1431
- }
1432
- onChange?.(updatedFileList, updatedIndexes);
1433
- };
1434
- const onImageRemove = (index) => {
1435
- const updatedList = [...inValue];
1436
- if (Array.isArray(index)) {
1437
- index.forEach((i) => {
1438
- updatedList.splice(i, 1);
1439
- });
1440
- } else {
1441
- updatedList.splice(index, 1);
1442
- }
1443
- onChange?.(updatedList);
1444
- };
1445
- const onImageUpdate = (index) => {
1446
- setKeyUpdate(index);
1447
- handleClickInput();
1448
- };
1449
- const handleDrag = (e) => {
1450
- e.preventDefault();
1451
- e.stopPropagation();
1452
- };
1453
- const handleDragIn = (e) => {
1454
- e.preventDefault();
1455
- e.stopPropagation();
1456
- if (e.dataTransfer.items && e.dataTransfer.items.length > 0) {
1457
- setIsDragging(true);
1458
- }
1459
- };
1460
- const handleDragOut = (e) => {
1461
- e.preventDefault();
1462
- e.stopPropagation();
1463
- setIsDragging(false);
1464
- };
1465
- const handleDrop = (e) => {
1466
- e.preventDefault();
1467
- e.stopPropagation();
1468
- setIsDragging(false);
1469
- if (e.dataTransfer.files && e.dataTransfer.files.length > 0) {
1470
- handleChange(e.dataTransfer.files);
1471
- }
1472
- };
1473
- const handleDragStart = (e) => {
1474
- e.preventDefault();
1475
- e.stopPropagation();
1476
- e.dataTransfer.clearData();
1477
- };
1478
- return /* @__PURE__ */ jsxs22(Fragment3, { children: [
1479
- /* @__PURE__ */ jsx33(
1480
- "input",
1481
- {
1482
- ref: inputRef,
1483
- type: "file",
1484
- accept: getAcceptTypeString(acceptType),
1485
- multiple,
1486
- onChange: (e) => {
1487
- onInputChange(e);
1488
- },
1489
- style: { display: "none" },
1490
- ...inputProps
1491
- }
1492
- ),
1493
- children?.({
1494
- fileList: inValue,
1495
- onImageUpload,
1496
- onImageRemove,
1497
- onImageUpdate,
1498
- onImageRemoveAll,
1499
- dragProps: {
1500
- onDrop: handleDrop,
1501
- onDragEnter: handleDragIn,
1502
- onDragLeave: handleDragOut,
1503
- onDragOver: handleDrag,
1504
- onDragStart: handleDragStart
1505
- },
1506
- isDragging
1507
- })
1508
- ] });
1509
- };
1510
-
1511
- // src/components/ui/language-switcher.tsx
1512
- import { useTransition } from "react";
1513
- import { cn as cn26, GlobeIcon, getFlagUrl, LanguagesIcon } from "@pelatform/ui.core";
1514
- import {
1515
- Badge as Badge3,
1516
- Button as Button5,
1517
- DropdownMenu as DropdownMenu2,
1518
- DropdownMenuContent as DropdownMenuContent2,
1519
- DropdownMenuItem as DropdownMenuItem2,
1520
- DropdownMenuRadioGroup,
1521
- DropdownMenuRadioItem,
1522
- DropdownMenuSub as DropdownMenuSub2,
1523
- DropdownMenuSubContent as DropdownMenuSubContent2,
1524
- DropdownMenuSubTrigger as DropdownMenuSubTrigger2,
1525
- DropdownMenuTrigger as DropdownMenuTrigger2
1526
- } from "@pelatform/ui.default";
1527
- import { jsx as jsx34, jsxs as jsxs23 } from "react/jsx-runtime";
1528
- function LanguageSwitcher({
1529
- className,
1530
- type = "dropdown",
1531
- variant = "ghost",
1532
- size = "md",
1533
- showNames = true,
1534
- showFlags = true,
1535
- label = "Language",
1536
- i18nEnabled = true,
1537
- currentLocale,
1538
- locales,
1539
- onLocaleChange,
1540
- customFlagUrl = false,
1541
- Image: Image2 = DefaultImage
1542
- }) {
1543
- const [isPending, startTransition] = useTransition();
1544
- const languages = locales ?? [];
1545
- const currentLanguage = languages.find((l) => l.code === currentLocale);
1546
- function handleLanguageChange(newLocale) {
1547
- if (newLocale === currentLocale) return;
1548
- startTransition(() => {
1549
- const maybePromise = onLocaleChange?.(newLocale);
1550
- return maybePromise;
1551
- });
1552
- }
1553
- if (!i18nEnabled && (languages?.length ?? 0) <= 1) {
1554
- return null;
1555
- }
1556
- if (type === "dropdown") {
1557
- return /* @__PURE__ */ jsxs23(DropdownMenu2, { children: [
1558
- /* @__PURE__ */ jsx34(DropdownMenuTrigger2, { asChild: true, children: /* @__PURE__ */ jsxs23(
1559
- Button5,
1560
- {
1561
- variant,
1562
- size,
1563
- className: cn26(
1564
- "group/toggle size-8 px-0 text-foreground ring-0! focus:outline-none! focus:ring-0! focus-visible:outline-none! focus-visible:ring-0! focus-visible:ring-offset-0!",
1565
- isPending && "cursor-not-allowed opacity-50",
1566
- className
1567
- ),
1568
- disabled: isPending,
1569
- children: [
1570
- /* @__PURE__ */ jsx34(LanguagesIcon, { className: "size-4" }),
1571
- /* @__PURE__ */ jsx34("span", { className: "sr-only", children: isPending ? "Changing language..." : "Language dropdown" })
1572
- ]
1573
- }
1574
- ) }),
1575
- /* @__PURE__ */ jsx34(
1576
- DropdownMenuContent2,
1577
- {
1578
- align: "end",
1579
- className: "min-w-[150px]",
1580
- onCloseAutoFocus: (e) => e.preventDefault(),
1581
- children: languages.map((lang) => /* @__PURE__ */ jsxs23(
1582
- DropdownMenuItem2,
1583
- {
1584
- onClick: () => handleLanguageChange(lang.code),
1585
- className: cn26("gap-2", currentLocale === lang.code && "bg-accent"),
1586
- children: [
1587
- showFlags && lang.flag ? /* @__PURE__ */ jsx34(
1588
- Image2,
1589
- {
1590
- src: customFlagUrl ? lang.flag : getFlagUrl(lang.flag),
1591
- alt: `${lang.name} flag`,
1592
- className: "size-4 rounded-full object-cover",
1593
- width: 24,
1594
- height: 24
1595
- }
1596
- ) : showFlags ? /* @__PURE__ */ jsx34(GlobeIcon, { className: "size-4" }) : null,
1597
- showNames && /* @__PURE__ */ jsx34("span", { className: "text-sm", children: lang.name }),
1598
- currentLocale === lang.code && /* @__PURE__ */ jsx34("span", { className: "ms-auto text-muted-foreground text-xs", children: "\u2713" })
1599
- ]
1600
- },
1601
- lang.code
1602
- ))
1603
- }
1604
- )
1605
- ] });
1606
- }
1607
- return /* @__PURE__ */ jsxs23(DropdownMenuSub2, { children: [
1608
- /* @__PURE__ */ jsxs23(
1609
- DropdownMenuSubTrigger2,
1610
- {
1611
- className: cn26(
1612
- "flex items-center gap-2 data-[state=open]:**:data-[slot=badge]:border-input **:data-[slot=dropdown-menu-sub-trigger-indicator]:hidden hover:**:data-[slot=badge]:border-input",
1613
- className
1614
- ),
1615
- children: [
1616
- /* @__PURE__ */ jsx34(GlobeIcon, { className: "size-4" }),
1617
- /* @__PURE__ */ jsxs23("span", { className: "relative flex grow items-center justify-between gap-2", children: [
1618
- label,
1619
- currentLanguage && /* @__PURE__ */ jsxs23(Badge3, { appearance: "outline", className: "-translate-y-1/2 absolute end-0 top-1/2", children: [
1620
- currentLanguage.name,
1621
- showFlags && currentLanguage.flag && /* @__PURE__ */ jsx34(
1622
- Image2,
1623
- {
1624
- src: customFlagUrl ? currentLanguage.flag : getFlagUrl(currentLanguage.flag),
1625
- alt: currentLanguage.name,
1626
- className: "ms-1 size-3.5 rounded-full",
1627
- width: 24,
1628
- height: 24
1629
- }
1630
- )
1631
- ] })
1632
- ] })
1633
- ]
1634
- }
1635
- ),
1636
- /* @__PURE__ */ jsx34(DropdownMenuSubContent2, { className: "w-48", children: /* @__PURE__ */ jsx34(
1637
- DropdownMenuRadioGroup,
1638
- {
1639
- value: currentLocale,
1640
- onValueChange: (value) => handleLanguageChange(value),
1641
- children: languages.map((item) => /* @__PURE__ */ jsxs23(
1642
- DropdownMenuRadioItem,
1643
- {
1644
- value: item.code,
1645
- className: "flex items-center gap-2",
1646
- children: [
1647
- showFlags && item.flag ? /* @__PURE__ */ jsx34(
1648
- Image2,
1649
- {
1650
- src: customFlagUrl ? item.flag : getFlagUrl(item.flag),
1651
- alt: `${item.name} flag`,
1652
- className: "size-4 rounded-full object-cover",
1653
- width: 24,
1654
- height: 24
1655
- }
1656
- ) : showFlags ? /* @__PURE__ */ jsx34(GlobeIcon, { className: "size-4" }) : null,
1657
- /* @__PURE__ */ jsx34("span", { children: item.name })
1658
- ]
1659
- },
1660
- item.code
1661
- ))
1662
- }
1663
- ) })
1664
- ] });
1665
- }
1666
-
1667
- // src/components/ui/logo.tsx
1668
- import { cn as cn27 } from "@pelatform/ui.core";
1669
- import { jsx as jsx35 } from "react/jsx-runtime";
1670
- function Logo({ className }) {
1671
- return /* @__PURE__ */ jsx35(
1672
- "svg",
1673
- {
1674
- xmlns: "http://www.w3.org/2000/svg",
1675
- viewBox: "0 0 300 300",
1676
- className: cn27("size-8 text-primary", className),
1677
- children: /* @__PURE__ */ jsx35(
1678
- "path",
1679
- {
1680
- fill: "currentColor",
1681
- d: "M128.522 1.522c-32.588 5.306-62.029 20.107-84.303 42.38C11.915 76.206-4.329 122.766 1.097 167.5c7.82 64.464 55.004 115.796 119.215 129.692 13.77 2.981 43.538 3.228 57.152.476 55.106-11.142 98.806-49.775 115.475-102.085 9.652-30.288 9.28-64.659-1.019-94.282-13.203-37.974-41.238-69.366-77.545-86.829-9.214-4.432-22.787-8.877-35.198-11.527-12.922-2.76-38.101-3.467-50.655-1.423m45.43 23.051c25.127 4.747 47.405 16.665 66.107 35.368 18.907 18.906 30.066 39.63 35.57 66.059 2.173 10.433 2.429 35.004.478 46-1.644 9.273-7.255 26.356-11.31 34.44-12.206 24.332-34.074 46.206-58.297 58.317-37.669 18.832-85.803 16.865-121.763-4.977-32.079-19.483-53.841-50.921-60.419-87.28-2.115-11.696-2.107-33.116.019-45 5.217-29.172 20.878-56.039 43.866-75.257C88.177 35.545 110.634 25.946 136.5 23.05c9.765-1.094 27.393-.377 37.452 1.523M132.5 32.582c-17.187 2.652-35.032 9.653-49.67 19.487-9.019 6.061-25.684 23.052-31.743 32.367-19.802 30.442-24.936 66.068-14.488 100.534 10.763 35.502 38.905 64.97 73.472 76.934 37.229 12.886 76.705 7.51 108.412-14.763 36.802-25.851 55.968-71.116 48.91-115.511-4.458-28.042-18.237-52.604-40.544-72.276-10.285-9.071-26.471-18.003-40.349-22.267-18.878-5.802-36.218-7.248-54-4.505m89.497 40.668c-.003 1.59-4.605 18.817-6.612 24.75-.837 2.475-2.503 5.57-3.703 6.879-4.588 5.002-5.729 5.121-49.15 5.121-22.293 0-40.532.218-40.532.484 0 .677-10.97 43.679-11.611 45.516-.541 1.551-1.105 1.021-12.792-12.019C86.59 131.698 78 118.349 78 113.527c0-3.566 7.168-32.105 8.856-35.259.622-1.162 2.32-3.048 3.773-4.19C93.24 72.023 93.983 72 157.635 72c50.827 0 64.364.263 64.362 1.25m-37.204 62.319c6.763 8.973 10.207 15.902 10.207 20.535 0 4.848-7.331 31.946-9.565 35.355-3.203 4.888-6.075 5.579-25.942 6.24l-18.441.613-.976 3.094c-.537 1.702-3.299 11.644-6.139 22.094s-5.486 19.351-5.879 19.779c-.394.429-4.574-3.222-9.288-8.112-14.649-15.196-22.751-27.719-22.75-35.167 0-1.925 1.971-10.681 4.38-19.457 3.804-13.856 4.792-16.325 7.506-18.75l3.126-2.793h19.505c19.297 0 19.515-.024 20.398-2.25.491-1.238 2.559-8.55 4.596-16.25s4.641-17.333 5.786-21.407l2.083-7.407 8.084 8.476c4.447 4.662 10.436 11.595 13.309 15.407"
1682
- }
1683
- )
1684
- }
1685
- );
1686
- }
1687
-
1688
- // src/components/ui/mode-switcher.tsx
1689
- import * as React2 from "react";
1690
- import {
1691
- cn as cn28,
1692
- MonitorIcon,
1693
- MoonIcon,
1694
- SunIcon,
1695
- THEME_MODES as THEME_MODES2
1696
- } from "@pelatform/ui.core";
1697
- import {
1698
- Button as Button6,
1699
- DropdownMenu as DropdownMenu3,
1700
- DropdownMenuContent as DropdownMenuContent3,
1701
- DropdownMenuItem as DropdownMenuItem3,
1702
- DropdownMenuTrigger as DropdownMenuTrigger3
1703
- } from "@pelatform/ui.default";
1704
- import { useTheme } from "@pelatform/ui.default/dep";
1705
- import { Fragment as Fragment4, jsx as jsx36, jsxs as jsxs24 } from "react/jsx-runtime";
1706
- function ModeSwitcher({
1707
- className,
1708
- variant = "ghost",
1709
- size = "md",
1710
- cycleOrder = [THEME_MODES2.SYSTEM, THEME_MODES2.LIGHT, THEME_MODES2.DARK],
1711
- type = "toogle",
1712
- label = {
1713
- system: "System",
1714
- dark: "Dark",
1715
- light: "Light"
1716
- }
1717
- }) {
1718
- const { setTheme, theme } = useTheme();
1719
- const toggleTheme = React2.useCallback(() => {
1720
- const currentIndex = cycleOrder.indexOf(theme);
1721
- const nextIndex = (currentIndex + 1) % cycleOrder.length;
1722
- const nextTheme = cycleOrder[nextIndex];
1723
- setTheme(nextTheme);
1724
- }, [theme, setTheme, cycleOrder]);
1725
- const getCurrentIcon = (withLabel = false) => {
1726
- if (theme === THEME_MODES2.SYSTEM) {
1727
- return /* @__PURE__ */ jsxs24(Fragment4, { children: [
1728
- /* @__PURE__ */ jsx36(MonitorIcon, {}),
1729
- " ",
1730
- withLabel && /* @__PURE__ */ jsx36("span", { children: label.system })
1731
- ] });
1732
- }
1733
- if (theme === THEME_MODES2.DARK) {
1734
- return /* @__PURE__ */ jsxs24(Fragment4, { children: [
1735
- /* @__PURE__ */ jsx36(MoonIcon, {}),
1736
- " ",
1737
- withLabel && /* @__PURE__ */ jsx36("span", { children: label.dark })
1738
- ] });
1739
- }
1740
- return /* @__PURE__ */ jsxs24(Fragment4, { children: [
1741
- /* @__PURE__ */ jsx36(SunIcon, {}),
1742
- " ",
1743
- withLabel && /* @__PURE__ */ jsx36("span", { children: label.light })
1744
- ] });
1745
- };
1746
- const isActive = (val) => theme === val;
1747
- if (type === "toogle") {
1748
- return /* @__PURE__ */ jsxs24(
1749
- Button6,
1750
- {
1751
- variant,
1752
- size,
1753
- className: cn28("group/toggle size-8 px-0 text-foreground", className),
1754
- onClick: toggleTheme,
1755
- "aria-label": "Switch theme",
1756
- children: [
1757
- getCurrentIcon(),
1758
- /* @__PURE__ */ jsx36("span", { className: "sr-only", children: "Toggle theme" })
1759
- ]
1760
- }
1761
- );
1762
- }
1763
- if (type === "dropdown") {
1764
- return /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
1765
- /* @__PURE__ */ jsx36(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsxs24(
1766
- Button6,
1767
- {
1768
- variant,
1769
- size,
1770
- className: cn28(
1771
- "group/toggle size-8 px-0 text-foreground ring-0! focus:outline-none! focus:ring-0! focus-visible:outline-none! focus-visible:ring-0! focus-visible:ring-offset-0!",
1772
- className
1773
- ),
1774
- children: [
1775
- getCurrentIcon(),
1776
- /* @__PURE__ */ jsx36("span", { className: "sr-only", children: "Toggle theme" })
1777
- ]
1778
- }
1779
- ) }),
1780
- /* @__PURE__ */ jsxs24(DropdownMenuContent3, { align: "end", onCloseAutoFocus: (e) => e.preventDefault(), children: [
1781
- /* @__PURE__ */ jsxs24(
1782
- DropdownMenuItem3,
1783
- {
1784
- className: isActive("light") ? "bg-accent" : "",
1785
- onClick: () => setTheme("light"),
1786
- children: [
1787
- /* @__PURE__ */ jsx36(SunIcon, {}),
1788
- label.light
1789
- ]
1790
- }
1791
- ),
1792
- /* @__PURE__ */ jsxs24(
1793
- DropdownMenuItem3,
1794
- {
1795
- className: isActive("dark") ? "bg-accent" : "",
1796
- onClick: () => setTheme("dark"),
1797
- children: [
1798
- /* @__PURE__ */ jsx36(MoonIcon, {}),
1799
- label.dark
1800
- ]
1801
- }
1802
- ),
1803
- /* @__PURE__ */ jsxs24(
1804
- DropdownMenuItem3,
1805
- {
1806
- className: isActive("system") ? "bg-accent" : "",
1807
- onClick: () => setTheme("system"),
1808
- children: [
1809
- /* @__PURE__ */ jsx36(MonitorIcon, {}),
1810
- label.system
1811
- ]
1812
- }
1813
- )
1814
- ] })
1815
- ] });
1816
- }
1817
- return /* @__PURE__ */ jsx36(
1818
- DropdownMenuItem3,
1819
- {
1820
- className,
1821
- onSelect: (e) => {
1822
- e.preventDefault();
1823
- toggleTheme();
1824
- },
1825
- children: getCurrentIcon(true)
1826
- }
1827
- );
1828
- }
1829
-
1830
- // src/components/ui/moving-border.tsx
1831
- import { useRef as useRef2 } from "react";
1832
- import {
1833
- motion as motion2,
1834
- useAnimationFrame,
1835
- useMotionTemplate,
1836
- useMotionValue,
1837
- useTransform
1838
- } from "@pelatform/ui.animation";
1839
- import { cn as cn29 } from "@pelatform/ui.core";
1840
- import { Fragment as Fragment5, jsx as jsx37, jsxs as jsxs25 } from "react/jsx-runtime";
1841
- function MovingLabel({
1842
- borderRadius = "1.75rem",
1843
- children,
1844
- as: Component = "button",
1845
- containerClassName,
1846
- borderClassName,
1847
- duration,
1848
- className,
1849
- ...otherProps
1850
- }) {
1851
- return /* @__PURE__ */ jsxs25(
1852
- Component,
1853
- {
1854
- className: cn29("relative h-9 overflow-hidden bg-transparent p-px text-xl", containerClassName),
1855
- style: {
1856
- borderRadius
1857
- },
1858
- ...otherProps,
1859
- children: [
1860
- /* @__PURE__ */ jsx37("div", { className: "absolute inset-0", style: { borderRadius: `calc(${borderRadius} * 0.96)` }, children: /* @__PURE__ */ jsx37(MovingBorder, { duration, rx: "30%", ry: "30%", children: /* @__PURE__ */ jsx37(
1861
- "div",
1862
- {
1863
- className: cn29(
1864
- "h-12 w-20 bg-[radial-gradient(#24B47E_15%,transparent_60%)] opacity-[0.6]",
1865
- borderClassName
1866
- )
1867
- }
1868
- ) }) }),
1869
- /* @__PURE__ */ jsx37(
1870
- "div",
1871
- {
1872
- className: cn29(
1873
- "relative flex h-full w-full items-center justify-center border border-slate-800 bg-slate-900/50 text-sm text-white antialiased backdrop-blur-xl",
1874
- className
1875
- ),
1876
- style: {
1877
- borderRadius: `calc(${borderRadius} * 1)`
1878
- },
1879
- children
1880
- }
1881
- )
1882
- ]
1883
- }
1884
- );
1885
- }
1886
- var MovingBorder = ({
1887
- children,
1888
- duration = 2e3,
1889
- rx,
1890
- ry,
1891
- ...otherProps
1892
- }) => {
1893
- const pathRef = useRef2(null);
1894
- const progress = useMotionValue(0);
1895
- useAnimationFrame((time) => {
1896
- const length = pathRef.current?.getTotalLength();
1897
- if (length) {
1898
- const pxPerMillisecond = length / duration;
1899
- progress.set(time * pxPerMillisecond % length);
1900
- }
1901
- });
1902
- const x = useTransform(progress, (val) => pathRef.current?.getPointAtLength(val).x);
1903
- const y = useTransform(progress, (val) => pathRef.current?.getPointAtLength(val).y);
1904
- const transform = useMotionTemplate`translateX(${x}px) translateY(${y}px) translateX(-50%) translateY(-50%)`;
1905
- return /* @__PURE__ */ jsxs25(Fragment5, { children: [
1906
- /* @__PURE__ */ jsx37(
1907
- "svg",
1908
- {
1909
- preserveAspectRatio: "none",
1910
- className: "absolute h-full w-full",
1911
- width: "100%",
1912
- height: "100%",
1913
- ...otherProps,
1914
- children: /* @__PURE__ */ jsx37("rect", { fill: "none", width: "100%", height: "100%", rx, ry, ref: pathRef })
1915
- }
1916
- ),
1917
- /* @__PURE__ */ jsx37(
1918
- motion2.div,
1919
- {
1920
- style: {
1921
- position: "absolute",
1922
- top: 0,
1923
- left: 0,
1924
- display: "inline-block",
1925
- transform
1926
- },
1927
- children
1928
- }
1929
- )
1930
- ] });
1931
- };
1932
-
1933
- // src/components/ui/subscribe.tsx
1934
- import { useState as useState5 } from "react";
1935
- import { CircleAlertIcon as CircleAlertIcon4, CircleCheckIcon as CircleCheckIcon2, googleTrackEvent as googleTrackEvent3 } from "@pelatform/ui.core";
1936
- import { Alert as Alert4, AlertIcon as AlertIcon4, AlertTitle as AlertTitle4, Button as Button8, Input } from "@pelatform/ui.default";
1937
- import { toast as toast4 } from "@pelatform/ui.default/dep";
1938
-
1939
- // src/components/utils/recaptcha-popover.tsx
1940
- import { CircleAlertIcon as CircleAlertIcon3 } from "@pelatform/ui.core";
1941
- import { Alert as Alert3, AlertIcon as AlertIcon3, AlertTitle as AlertTitle3, Button as Button7 } from "@pelatform/ui.default";
1942
- import { Popover, toast as toast3 } from "@pelatform/ui.default/dep";
1943
- import { useRecaptchaV2 } from "@pelatform/ui.hook";
1944
- import { jsx as jsx38, jsxs as jsxs26 } from "react/jsx-runtime";
1945
- function RecaptchaPopover({
1946
- open,
1947
- onOpenChange,
1948
- onVerify,
1949
- trigger,
1950
- verifyButtonText = "Verify & Submit"
1951
- }) {
1952
- const { containerRef, getToken, resetCaptcha, initializeRecaptcha } = useRecaptchaV2(
1953
- process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY || ""
1954
- );
1955
- const handleOpenChange = (newOpen) => {
1956
- onOpenChange(newOpen);
1957
- if (newOpen) {
1958
- resetCaptcha();
1959
- setTimeout(() => {
1960
- initializeRecaptcha();
1961
- }, 100);
1962
- }
1963
- };
1964
- const handleVerify = () => {
1965
- try {
1966
- const token = getToken();
1967
- if (!token) {
1968
- toast3.custom(
1969
- () => /* @__PURE__ */ jsxs26(Alert3, { variant: "mono", icon: "destructive", children: [
1970
- /* @__PURE__ */ jsx38(AlertIcon3, { children: /* @__PURE__ */ jsx38(CircleAlertIcon3, {}) }),
1971
- /* @__PURE__ */ jsx38(AlertTitle3, { children: "Please complete the reCAPTCHA verification." })
1972
- ] }),
1973
- {
1974
- position: "top-center"
1975
- }
1976
- );
1977
- return;
1978
- }
1979
- onVerify(token);
1980
- } catch (error) {
1981
- console.error("Error getting reCAPTCHA token:", error);
1982
- toast3.custom(
1983
- () => /* @__PURE__ */ jsxs26(Alert3, { variant: "mono", icon: "destructive", children: [
1984
- /* @__PURE__ */ jsx38(AlertIcon3, { children: /* @__PURE__ */ jsx38(CircleAlertIcon3, {}) }),
1985
- /* @__PURE__ */ jsx38(AlertTitle3, { children: "Please complete the reCAPTCHA verification." })
1986
- ] }),
1987
- {
1988
- position: "top-center"
1989
- }
1990
- );
1991
- return;
1992
- }
1993
- };
1994
- return /* @__PURE__ */ jsxs26(Popover.Root, { open, onOpenChange: handleOpenChange, children: [
1995
- /* @__PURE__ */ jsx38(Popover.Trigger, { asChild: true, children: trigger }),
1996
- /* @__PURE__ */ jsx38(Popover.Portal, { children: /* @__PURE__ */ jsxs26(
1997
- Popover.Content,
1998
- {
1999
- className: "z-50 rounded-lg bg-white p-4 shadow-lg",
2000
- sideOffset: 5,
2001
- align: "end",
2002
- onInteractOutside: (e) => {
2003
- if (e.target.tagName === "IFRAME") {
2004
- e.preventDefault();
2005
- }
2006
- },
2007
- children: [
2008
- /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-4", children: [
2009
- /* @__PURE__ */ jsx38("div", { ref: containerRef, className: "min-h-[78px]" }),
2010
- /* @__PURE__ */ jsx38(Button7, { type: "button", variant: "mono", onClick: handleVerify, className: "w-full", children: verifyButtonText })
2011
- ] }),
2012
- /* @__PURE__ */ jsx38(Popover.Arrow, { className: "fill-white" })
2013
- ]
2014
- }
2015
- ) })
2016
- ] });
2017
- }
2018
-
2019
- // src/components/ui/subscribe.tsx
2020
- import { jsx as jsx39, jsxs as jsxs27 } from "react/jsx-runtime";
2021
- function Subscribe({
2022
- heading = "Stay notified on every new release",
2023
- subheading = "Only the updates worth knowing",
2024
- buttonText = "Subscribe",
2025
- loadingButtonText = "Subscribing...",
2026
- inputPlaceholder = "Your email address",
2027
- successMessage = "Thank you for your subscription. Expect amazing stuff soon!",
2028
- invalidEmailMessage = "Invalid email address. Please check and try again.",
2029
- recaptchaMessage = "Please complete the reCAPTCHA verification.",
2030
- errorMessage = "Oops! Something unexpected happened. Please try again later.",
2031
- apiEndpoint = "/api/subscribe",
2032
- verifyButtonText = "Verify & Subscribe",
2033
- className
2034
- } = {}) {
2035
- const [email, setEmail] = useState5("");
2036
- const [loading, setLoading] = useState5(false);
2037
- const [showRecaptcha, setShowRecaptcha] = useState5(false);
2038
- const validateEmail = () => {
2039
- if (!email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
2040
- toast4.custom(
2041
- () => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
2042
- /* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
2043
- /* @__PURE__ */ jsx39(AlertTitle4, { children: invalidEmailMessage })
2044
- ] }),
2045
- {
2046
- position: "top-center"
2047
- }
2048
- );
2049
- return false;
2050
- }
2051
- return true;
2052
- };
2053
- const handleSubmit = async (e) => {
2054
- e.preventDefault();
2055
- if (!validateEmail()) {
2056
- setShowRecaptcha(false);
2057
- return;
2058
- }
2059
- setShowRecaptcha(true);
2060
- };
2061
- const handleVerifiedSubmit = async (token) => {
2062
- if (!token) {
2063
- toast4.custom(
2064
- () => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
2065
- /* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
2066
- /* @__PURE__ */ jsx39(AlertTitle4, { children: recaptchaMessage })
2067
- ] }),
2068
- {
2069
- position: "top-center"
2070
- }
2071
- );
2072
- return;
2073
- }
2074
- setLoading(true);
2075
- setShowRecaptcha(false);
2076
- try {
2077
- googleTrackEvent3({
2078
- name: "site_newsletter_subscribe_submit",
2079
- properties: {
2080
- category: "conversion",
2081
- label: "Newsletter Subscribe Submit",
2082
- email
2083
- }
2084
- });
2085
- const res = await fetch(apiEndpoint, {
2086
- method: "POST",
2087
- headers: {
2088
- "Content-Type": "application/json",
2089
- "x-recaptcha-token": token
2090
- },
2091
- body: JSON.stringify({ email })
2092
- });
2093
- const data = await res.json();
2094
- if (res.ok) {
2095
- toast4.custom(
2096
- () => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "success", children: [
2097
- /* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleCheckIcon2, {}) }),
2098
- /* @__PURE__ */ jsx39(AlertTitle4, { children: successMessage })
2099
- ] }),
2100
- {
2101
- position: "top-center"
2102
- }
2103
- );
2104
- googleTrackEvent3({
2105
- name: "site_newsletter_subscribe_success",
2106
- properties: {
2107
- category: "conversion",
2108
- label: "Newsletter Subscribe Success",
2109
- email
2110
- }
2111
- });
2112
- setEmail("");
2113
- } else {
2114
- toast4.custom(
2115
- () => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
2116
- /* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
2117
- /* @__PURE__ */ jsx39(AlertTitle4, { children: data.message || errorMessage })
2118
- ] }),
2119
- {
2120
- position: "top-center"
2121
- }
2122
- );
2123
- }
2124
- } catch (err) {
2125
- console.error("Newsletter subscription error:", err);
2126
- toast4.custom(
2127
- () => /* @__PURE__ */ jsxs27(Alert4, { variant: "mono", icon: "destructive", children: [
2128
- /* @__PURE__ */ jsx39(AlertIcon4, { children: /* @__PURE__ */ jsx39(CircleAlertIcon4, {}) }),
2129
- /* @__PURE__ */ jsx39(AlertTitle4, { children: errorMessage })
2130
- ] }),
2131
- {
2132
- position: "top-center"
2133
- }
2134
- );
2135
- } finally {
2136
- setLoading(false);
2137
- }
2138
- };
2139
- const style = {
2140
- backgroundImage: `linear-gradient(0deg, transparent 0%, transparent 60%, rgba(183, 183, 183, 0.05) 60%, rgba(183, 183, 183, 0.05) 93%, transparent 93%, transparent 100%), linear-gradient(135deg, transparent 0%, transparent 55%, rgba(183, 183, 183, 0.05) 55%, rgba(183, 183, 183, 0.05) 84%, transparent 84%, transparent 100%), linear-gradient(0deg, transparent 0%, transparent 80%, rgba(183, 183, 183, 0.05) 80%, rgba(183, 183, 183, 0.05) 94%, transparent 94%, transparent 100%), linear-gradient(90deg, rgb(0,0,0), rgb(0,0,0))`
2141
- };
2142
- return /* @__PURE__ */ jsx39("footer", { children: /* @__PURE__ */ jsx39("div", { className: "container pt-10", children: /* @__PURE__ */ jsxs27(
2143
- "div",
2144
- {
2145
- className: `mt-10 mb-8 flex flex-wrap items-center justify-between gap-7 rounded-xl px-10 py-16 md:px-20 ${className || ""}`,
2146
- style,
2147
- children: [
2148
- /* @__PURE__ */ jsxs27("div", { className: "flex flex-col gap-1.5", children: [
2149
- /* @__PURE__ */ jsx39("h2", { className: "font-medium text-3xl text-white", children: heading }),
2150
- /* @__PURE__ */ jsx39("div", { className: "font-medium text-2xl text-white/50", children: subheading })
2151
- ] }),
2152
- /* @__PURE__ */ jsxs27("form", { onSubmit: handleSubmit, className: "flex gap-2.5", children: [
2153
- /* @__PURE__ */ jsx39(
2154
- Input,
2155
- {
2156
- type: "email",
2157
- value: email,
2158
- onChange: (e) => {
2159
- setEmail(e.target.value);
2160
- setShowRecaptcha(false);
2161
- },
2162
- placeholder: inputPlaceholder,
2163
- className: "h-auto rounded-lg border border-input/20 bg-white/5 px-5 py-3 text-white/80 placeholder:text-white/50 focus:outline-none focus:ring md:min-w-64",
2164
- required: true
2165
- }
2166
- ),
2167
- /* @__PURE__ */ jsx39(
2168
- RecaptchaPopover,
2169
- {
2170
- open: showRecaptcha,
2171
- onOpenChange: (open) => {
2172
- if (!open) {
2173
- setShowRecaptcha(false);
2174
- }
2175
- },
2176
- onVerify: handleVerifiedSubmit,
2177
- verifyButtonText,
2178
- trigger: /* @__PURE__ */ jsx39(
2179
- Button8,
2180
- {
2181
- type: "submit",
2182
- className: "h-auto rounded-lg bg-white px-5 py-3 font-semibold text-black/80 hover:bg-white hover:text-black",
2183
- disabled: loading,
2184
- children: loading ? loadingButtonText : buttonText
2185
- }
2186
- )
2187
- }
2188
- )
2189
- ] })
2190
- ]
2191
- }
2192
- ) }) });
2193
- }
2194
-
2195
- // src/components/ui/toolbar.tsx
2196
- import { cn as cn30 } from "@pelatform/ui.core";
2197
- import { jsx as jsx40 } from "react/jsx-runtime";
2198
- var Toolbar = ({ children }) => {
2199
- return /* @__PURE__ */ jsx40("div", { className: "flex grow items-center justify-between gap-2.5 pb-5", children });
2200
- };
2201
- var ToolbarHeading = ({ children, className }) => {
2202
- return /* @__PURE__ */ jsx40("div", { className: cn30("flex flex-col flex-wrap gap-px", className), children });
2203
- };
2204
- var ToolbarTitle = ({ className, children }) => {
2205
- return /* @__PURE__ */ jsx40("h1", { className: cn30("font-semibold text-foreground text-lg", className), children });
2206
- };
2207
- var ToolbarActions = ({ children }) => {
2208
- return /* @__PURE__ */ jsx40("div", { className: "flex flex-wrap items-center gap-1.5 lg:gap-3.5", children });
2209
- };
2210
-
2211
- // src/components/ui/user-avatar.tsx
2212
- import {
2213
- Avatar,
2214
- AvatarFallback,
2215
- AvatarImage,
2216
- AvatarIndicator,
2217
- AvatarStatus
2218
- } from "@pelatform/ui.default";
2219
- import { jsx as jsx41, jsxs as jsxs28 } from "react/jsx-runtime";
2220
- function UserAvatar({ className, indicator = false, src, alt }) {
2221
- const name = alt ?? "User";
2222
- const initial = getInitials(name);
2223
- return /* @__PURE__ */ jsxs28(Avatar, { className, children: [
2224
- /* @__PURE__ */ jsx41(AvatarImage, { src: src ?? void 0, alt: name }),
2225
- /* @__PURE__ */ jsx41(AvatarFallback, { children: initial }),
2226
- indicator && /* @__PURE__ */ jsx41(AvatarIndicator, { className: "-end-2 -top-2", children: /* @__PURE__ */ jsx41(AvatarStatus, { variant: "online", className: "size-2.5" }) })
2227
- ] });
2228
- }
2229
- var getInitials = (name, count) => {
2230
- if (!name || typeof name !== "string") {
2231
- return "";
2232
- }
2233
- const initials = name.split(" ").filter(Boolean).map((part) => part[0].toUpperCase());
2234
- return count && count > 0 ? initials.slice(0, count).join("") : initials.join("");
2235
- };
2236
-
2237
- // src/components/utils/fonts.tsx
2238
- import { jsx as jsx42 } from "react/jsx-runtime";
2239
- var satoshiFontUrl = "https://assets.pelatform.com/fonts/satoshi/Satoshi-Variable.woff2";
2240
- var cssFontFace = `
2241
- @font-face {
2242
- font-family: 'Satoshi';
2243
- src: url('${satoshiFontUrl}') format('woff2');
2244
- font-weight: 300 900;
2245
- font-style: normal;
2246
- font-display: swap;
2247
- }
2248
- `;
2249
- function SatoshiFontCSS() {
2250
- return /* @__PURE__ */ jsx42("style", { dangerouslySetInnerHTML: { __html: cssFontFace } });
2251
- }
2252
- export {
2253
- AlertComingsoon,
2254
- AlertNotification,
2255
- AlertToast,
2256
- Announcement,
2257
- AnnouncementTag,
2258
- AnnouncementTitle,
2259
- BackLink,
2260
- BackgroundPaths,
2261
- Body,
2262
- Book,
2263
- CodeDisplay,
2264
- ComingSoon,
2265
- CommandMenu,
2266
- ConfirmDismissDialog,
2267
- DEFAULT_DATA_URL_KEY,
2268
- DEFAULT_NULL_INDEX,
2269
- DefaultImage,
2270
- DefaultLink,
2271
- DefaultNavigate,
2272
- DotsPattern,
2273
- DownloadFile,
2274
- ErrorComponents,
2275
- ExtraLink,
2276
- FloatingPaths,
2277
- Grid,
2278
- GridBackground,
2279
- HexagonBadge,
2280
- Icons,
2281
- ImageInput,
2282
- LanguageSwitcher,
2283
- LayoutAuth,
2284
- LayoutBlank,
2285
- Logo,
2286
- MainNav,
2287
- MaxWidthWrapper,
2288
- MobileNav,
2289
- MobileNavItemRenderer,
2290
- ModeSwitcher,
2291
- MovingBorder,
2292
- MovingLabel,
2293
- QueryProvider,
2294
- RecaptchaPopover,
2295
- SatoshiFontCSS,
2296
- ScreenLoader,
2297
- Section,
2298
- SiteFooter,
2299
- SiteHeader,
2300
- Stack,
2301
- Subscribe,
2302
- ThemeProvider,
2303
- Toolbar,
2304
- ToolbarActions,
2305
- ToolbarHeading,
2306
- ToolbarTitle,
2307
- UserAvatar,
2308
- Video,
2309
- Wrapper,
2310
- Youtube,
2311
- cssFontFace,
2312
- getAcceptTypeString,
2313
- getBase64,
2314
- getImage,
2315
- getInitials,
2316
- getListFiles,
2317
- handleMenuClick,
2318
- openFileDialog,
2319
- satoshiFontUrl
2320
- };
3
+ // src/components.ts
4
+ export * from "pelatform-ui/components";