@olwiba/ui 0.0.35 → 0.0.37

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/dist/index.d.ts CHANGED
@@ -242,12 +242,14 @@ interface HeroSectionProps {
242
242
  label: string;
243
243
  href: string;
244
244
  };
245
- heroImage: React.ReactNode;
245
+ heroImage?: React.ReactNode;
246
+ media?: 'image' | 'phone' | 'none';
247
+ phoneSize?: 'sm' | 'md' | 'lg';
246
248
  avatarUrls?: string[];
247
249
  socialProofText?: string;
248
250
  renderLink?: AppShellRenderLink;
249
251
  }
250
- declare function HeroSection({ heading, badge, description, primaryCta, secondaryCta, heroImage, avatarUrls, socialProofText, renderLink, }: HeroSectionProps): react_jsx_runtime.JSX.Element;
252
+ declare function HeroSection({ heading, badge, description, primaryCta, secondaryCta, heroImage, media, phoneSize, avatarUrls, socialProofText, renderLink, }: HeroSectionProps): react_jsx_runtime.JSX.Element;
251
253
 
252
254
  interface FeaturesSectionProps {
253
255
  title?: string;
@@ -357,9 +359,36 @@ interface StatsSectionProps {
357
359
  }
358
360
  declare function StatsSection({ title, description, badge, stats, }: StatsSectionProps): react_jsx_runtime.JSX.Element;
359
361
 
360
- declare function NewsletterSection(): react_jsx_runtime.JSX.Element;
362
+ interface NewsletterSectionProps {
363
+ badge?: string;
364
+ title?: string;
365
+ description?: string;
366
+ placeholder?: string;
367
+ submitLabel?: string;
368
+ privacyHref?: string;
369
+ privacyLabel?: string;
370
+ successTitle?: string;
371
+ successDescription?: string;
372
+ onSubscribe?: (email: string) => void | Promise<void>;
373
+ }
374
+ declare function NewsletterSection({ badge, title, description, placeholder, submitLabel, privacyHref, privacyLabel, successTitle, successDescription, onSubscribe, }?: NewsletterSectionProps): react_jsx_runtime.JSX.Element;
361
375
 
362
- declare function ContactSection(): react_jsx_runtime.JSX.Element;
376
+ type ContactInfoItem = {
377
+ label: string;
378
+ value: string;
379
+ icon?: LucideIcon;
380
+ };
381
+ interface ContactSectionProps {
382
+ badge?: string;
383
+ title?: string;
384
+ description?: string;
385
+ contactInfo?: ContactInfoItem[];
386
+ successTitle?: string;
387
+ successDescription?: string;
388
+ sendAnotherLabel?: string;
389
+ onSubmit?: (event: React.FormEvent<HTMLFormElement>) => void | Promise<void>;
390
+ }
391
+ declare function ContactSection({ badge, title, description, contactInfo, successTitle, successDescription, sendAnotherLabel, onSubmit, }?: ContactSectionProps): react_jsx_runtime.JSX.Element;
363
392
 
364
393
  interface NavbarProps {
365
394
  brand: {
@@ -600,6 +629,54 @@ interface ConfirmDialogProps extends Pick<UseConfirmReturn, 'isOpen' | 'options'
600
629
  }
601
630
  declare function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructive }: ConfirmDialogProps): react_jsx_runtime.JSX.Element;
602
631
 
632
+ declare const sizes: {
633
+ readonly sm: {
634
+ readonly outer: "w-44";
635
+ readonly height: "h-80";
636
+ readonly notch: "w-16 h-4";
637
+ readonly border: "rounded-[2rem]";
638
+ readonly screen: "rounded-[1.75rem]";
639
+ };
640
+ readonly md: {
641
+ readonly outer: "w-56";
642
+ readonly height: "h-[26rem]";
643
+ readonly notch: "w-20 h-5";
644
+ readonly border: "rounded-[2.5rem]";
645
+ readonly screen: "rounded-[2.25rem]";
646
+ };
647
+ readonly lg: {
648
+ readonly outer: "w-72";
649
+ readonly height: "h-[34rem]";
650
+ readonly notch: "w-24 h-6";
651
+ readonly border: "rounded-[3rem]";
652
+ readonly screen: "rounded-[2.75rem]";
653
+ };
654
+ };
655
+ interface PhoneFrameProps {
656
+ children?: React.ReactNode;
657
+ size?: keyof typeof sizes;
658
+ className?: string;
659
+ float?: boolean;
660
+ }
661
+ declare function PhoneFrame({ children, size, className, float }: PhoneFrameProps): react_jsx_runtime.JSX.Element;
662
+
663
+ declare function AppScreenRoot({ children, className }: {
664
+ children?: React.ReactNode;
665
+ className?: string;
666
+ }): react_jsx_runtime.JSX.Element;
667
+ declare function AppScreenHeader({ children, className }: {
668
+ children?: React.ReactNode;
669
+ className?: string;
670
+ }): react_jsx_runtime.JSX.Element;
671
+ declare function AppScreenBody({ children, className }: {
672
+ children?: React.ReactNode;
673
+ className?: string;
674
+ }): react_jsx_runtime.JSX.Element;
675
+ declare const AppScreen: typeof AppScreenRoot & {
676
+ Header: typeof AppScreenHeader;
677
+ Body: typeof AppScreenBody;
678
+ };
679
+
603
680
  interface GlassCardProps extends React.HTMLAttributes<HTMLDivElement> {
604
681
  blur?: 'sm' | 'md' | 'lg';
605
682
  children: React.ReactNode;
@@ -737,6 +814,11 @@ interface PostListProps {
737
814
  }
738
815
  declare function PostList({ posts, renderLink, emptyMessage }: PostListProps): react_jsx_runtime.JSX.Element;
739
816
 
817
+ interface MdxContentProps {
818
+ code: string;
819
+ }
820
+ declare function MdxContent({ code }: MdxContentProps): react_jsx_runtime.JSX.Element;
821
+
740
822
  declare function useMounted(): boolean;
741
823
 
742
824
  interface UseControlledOpenReturn {
@@ -793,4 +875,4 @@ interface UsePaginationReturn {
793
875
  }
794
876
  declare function usePagination(total: number, pageSize: number): UsePaginationReturn;
795
877
 
796
- export { type AppNavItem, AppShell, type AppShellAction, type AppShellBrand, type AppShellProps, type AppShellRenderLink, type AppShellUser, type AuthFormProps, AuthSection, type AuthSectionProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmOptions, ContactSection, ContextMenu, type ContextMenuDef, type ContextMenuProps, CountUp, type CountUpProps, CtaSection, type CtaSectionProps, DevBanner, type DevBannerProps, Dock, type DockItem, type DockProps, EmptyState, type EmptyStateProps, ErrorPage, type ErrorPageProps, FadeIn, type FadeInProps, FaqSection, type FaqSectionProps, FeatureCard, type FeatureCardProps, FeaturesSection, type FeaturesSectionProps, Footer, type FooterProps, FullPageSpinner, GlassCard, type GlassCardProps, HeroSection, type HeroSectionProps, type Hotkey, ImageCard, type ImageCardProps, Input, type InputProps, LogoStrip, type LogoStripProps, Navbar, type NavbarProps, NewsletterSection, OlwibaUIProvider, type OlwibaUIProviderProps, Overlay, type OverlayProps, type OverlayVariant, PageHeader, type PageHeaderBackButton, type PageHeaderBreadcrumb, type PageHeaderProps, PageTransition, type PageTransitionProps, PostCard, type PostCardProps, PostList, type PostListProps, PricingCard, type PricingCardProps, type PricingFeature, type PricingPlan, PricingSection, type PricingSectionProps, RegisterHotkeys, RootErrorFallback, SectionTitle, type SectionTitleProps, Spotlight, type SpotlightGroup, type SpotlightItem, type SpotlightProps, StaggerChildren, type StaggerChildrenProps, StatCard, type StatCardProps, StatsSection, type StatsSectionProps, Suspensed, Switch, type SwitchProps, TeamSection, TestimonialCard, type TestimonialCardProps, TestimonialsSection, type TestimonialsSectionProps, Textarea, type TextareaProps, ThemeColorUpdater, ThemeSwitchMinimal, type UIMode, Underlay, type UnderlayProps, type UnderlayVariant, type UpgradeComparisonRow, UpgradePrompt, type UpgradePromptProps, type UseConfirmReturn, type UseControlledOpenReturn, type UsePaginationReturn, VersionBanner, cn, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
878
+ export { type AppNavItem, AppScreen, AppShell, type AppShellAction, type AppShellBrand, type AppShellProps, type AppShellRenderLink, type AppShellUser, type AuthFormProps, AuthSection, type AuthSectionProps, Badge, type BadgeProps, Button, type ButtonProps, Card, type CardProps, Checkbox, type CheckboxProps, ConfirmDialog, type ConfirmDialogProps, type ConfirmOptions, type ContactInfoItem, ContactSection, type ContactSectionProps, ContextMenu, type ContextMenuDef, type ContextMenuProps, CountUp, type CountUpProps, CtaSection, type CtaSectionProps, DevBanner, type DevBannerProps, Dock, type DockItem, type DockProps, EmptyState, type EmptyStateProps, ErrorPage, type ErrorPageProps, FadeIn, type FadeInProps, FaqSection, type FaqSectionProps, FeatureCard, type FeatureCardProps, FeaturesSection, type FeaturesSectionProps, Footer, type FooterProps, FullPageSpinner, GlassCard, type GlassCardProps, HeroSection, type HeroSectionProps, type Hotkey, ImageCard, type ImageCardProps, Input, type InputProps, LogoStrip, type LogoStripProps, MdxContent, type MdxContentProps, Navbar, type NavbarProps, NewsletterSection, type NewsletterSectionProps, OlwibaUIProvider, type OlwibaUIProviderProps, Overlay, type OverlayProps, type OverlayVariant, PageHeader, type PageHeaderBackButton, type PageHeaderBreadcrumb, type PageHeaderProps, PageTransition, type PageTransitionProps, PhoneFrame, type PhoneFrameProps, PostCard, type PostCardProps, PostList, type PostListProps, PricingCard, type PricingCardProps, type PricingFeature, type PricingPlan, PricingSection, type PricingSectionProps, RegisterHotkeys, RootErrorFallback, SectionTitle, type SectionTitleProps, Spotlight, type SpotlightGroup, type SpotlightItem, type SpotlightProps, StaggerChildren, type StaggerChildrenProps, StatCard, type StatCardProps, StatsSection, type StatsSectionProps, Suspensed, Switch, type SwitchProps, TeamSection, TestimonialCard, type TestimonialCardProps, TestimonialsSection, type TestimonialsSectionProps, Textarea, type TextareaProps, ThemeColorUpdater, ThemeSwitchMinimal, type UIMode, Underlay, type UnderlayProps, type UnderlayVariant, type UpgradeComparisonRow, UpgradePrompt, type UpgradePromptProps, type UseConfirmReturn, type UseControlledOpenReturn, type UsePaginationReturn, VersionBanner, cn, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
package/dist/index.js CHANGED
@@ -6,6 +6,7 @@ import { Button as Button$1, Card as Card$1, Input as Input$1, Textarea as Texta
6
6
  export { CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@olwiba/cn';
7
7
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
8
  import { Compass, ArrowLeft, X, ArrowRight, Sparkles, Check, Minus, Quote, Star, Twitter, Github, Linkedin, Mail, Phone, MapPin, MessageSquare, Send, Sun, Moon, Menu, Search, TrendingUp, TrendingDown, ChevronRight, ChevronLeft, AlertTriangle, Loader2, ShieldCheck, Building2, MoreVerticalIcon, CreditCardIcon, BellIcon, LogOutIcon } from 'lucide-react';
9
+ import { useMDXComponent } from '@content-collections/mdx/react';
9
10
 
10
11
  // src/lib/utils.ts
11
12
  function cn(...inputs) {
@@ -616,6 +617,54 @@ function SectionTitle({ title, description, badge, className }) {
616
617
  description && /* @__PURE__ */ jsx("p", { className: "mx-auto mt-4 max-w-2xl text-pretty text-muted-foreground", children: description })
617
618
  ] }) });
618
619
  }
620
+ var sizes = {
621
+ sm: { outer: "w-44", height: "h-80", notch: "w-16 h-4", border: "rounded-[2rem]", screen: "rounded-[1.75rem]" },
622
+ md: { outer: "w-56", height: "h-[26rem]", notch: "w-20 h-5", border: "rounded-[2.5rem]", screen: "rounded-[2.25rem]" },
623
+ lg: { outer: "w-72", height: "h-[34rem]", notch: "w-24 h-6", border: "rounded-[3rem]", screen: "rounded-[2.75rem]" }
624
+ };
625
+ function PhoneFrame({ children, size = "md", className, float = true }) {
626
+ const s = sizes[size];
627
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
628
+ float && /* @__PURE__ */ jsx("style", { children: `
629
+ @keyframes olwiba-phone-float {
630
+ 0%, 100% { transform: translateY(0px); }
631
+ 50% { transform: translateY(-10px); }
632
+ }
633
+ .olwiba-phone-float { animation: olwiba-phone-float 5s ease-in-out infinite; }
634
+ ` }),
635
+ /* @__PURE__ */ jsxs(
636
+ "div",
637
+ {
638
+ className: cn(
639
+ "relative mx-auto",
640
+ s.outer,
641
+ float && "olwiba-phone-float",
642
+ className
643
+ ),
644
+ children: [
645
+ /* @__PURE__ */ jsxs(
646
+ "div",
647
+ {
648
+ className: cn(
649
+ "relative flex w-full flex-col overflow-hidden border-[3px] border-foreground/15 bg-muted shadow-2xl",
650
+ s.border,
651
+ s.height
652
+ ),
653
+ children: [
654
+ /* @__PURE__ */ jsx("div", { className: "relative flex justify-center pt-3 pb-1 shrink-0", children: /* @__PURE__ */ jsx("div", { className: cn("rounded-full bg-foreground/10", s.notch) }) }),
655
+ /* @__PURE__ */ jsx("div", { className: cn("mx-1.5 mb-1.5 flex-1 overflow-hidden bg-background", s.screen), children })
656
+ ]
657
+ }
658
+ ),
659
+ /* @__PURE__ */ jsx("div", { className: "absolute right-[-5px] top-24 h-12 w-[3px] rounded-l-sm bg-foreground/15" }),
660
+ /* @__PURE__ */ jsx("div", { className: "absolute left-[-5px] top-20 h-8 w-[3px] rounded-r-sm bg-foreground/15" }),
661
+ /* @__PURE__ */ jsx("div", { className: "absolute left-[-5px] top-32 h-8 w-[3px] rounded-r-sm bg-foreground/15" }),
662
+ /* @__PURE__ */ jsx("div", { className: "absolute left-[-5px] top-44 h-8 w-[3px] rounded-r-sm bg-foreground/15" })
663
+ ]
664
+ }
665
+ )
666
+ ] });
667
+ }
619
668
  var defaultRenderLink4 = ({ href, children, className }) => /* @__PURE__ */ jsx("a", { href, className, children });
620
669
  function HeroSection({
621
670
  heading,
@@ -624,6 +673,8 @@ function HeroSection({
624
673
  primaryCta,
625
674
  secondaryCta,
626
675
  heroImage,
676
+ media = "image",
677
+ phoneSize = "lg",
627
678
  avatarUrls,
628
679
  socialProofText,
629
680
  renderLink = defaultRenderLink4
@@ -648,7 +699,7 @@ function HeroSection({
648
699
  })
649
700
  ] })
650
701
  ] }) }),
651
- /* @__PURE__ */ jsx(FadeIn, { direction: "right", delay: 200, children: /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-2xl", children: heroImage }) })
702
+ media !== "none" && /* @__PURE__ */ jsx(FadeIn, { direction: "right", delay: 200, children: media === "phone" ? /* @__PURE__ */ jsx("div", { className: "flex justify-center", children: /* @__PURE__ */ jsx(PhoneFrame, { size: phoneSize, children: heroImage }) }) : /* @__PURE__ */ jsx("div", { className: "overflow-hidden rounded-2xl", children: heroImage }) })
652
703
  ] }),
653
704
  (avatarUrls?.length || socialProofText) && /* @__PURE__ */ jsx(FadeIn, { direction: "up", delay: 400, children: /* @__PURE__ */ jsxs("div", { className: "mx-auto mt-12 flex max-w-6xl items-center gap-4", children: [
654
705
  avatarUrls && avatarUrls.length > 0 && /* @__PURE__ */ jsx("div", { className: "flex -space-x-3", children: avatarUrls.map((url, i) => /* @__PURE__ */ jsxs(Avatar, { className: "size-9 border-2 border-background", children: [
@@ -1149,31 +1200,54 @@ function StatsSection({
1149
1200
  ] })
1150
1201
  ] }) });
1151
1202
  }
1152
- function NewsletterSection() {
1203
+ var defaults = {
1204
+ badge: "Newsletter",
1205
+ title: "Stay in the loop",
1206
+ description: "New components, release notes, and product tips \u2014 straight to your inbox. No spam, unsubscribe any time.",
1207
+ placeholder: "you@company.com",
1208
+ submitLabel: "Subscribe",
1209
+ privacyHref: "#",
1210
+ privacyLabel: "Privacy Policy",
1211
+ successTitle: "You're on the list.",
1212
+ successDescription: "We'll be in touch soon."
1213
+ };
1214
+ function NewsletterSection({
1215
+ badge = defaults.badge,
1216
+ title = defaults.title,
1217
+ description = defaults.description,
1218
+ placeholder = defaults.placeholder,
1219
+ submitLabel = defaults.submitLabel,
1220
+ privacyHref = defaults.privacyHref,
1221
+ privacyLabel = defaults.privacyLabel,
1222
+ successTitle = defaults.successTitle,
1223
+ successDescription = defaults.successDescription,
1224
+ onSubscribe
1225
+ } = {}) {
1153
1226
  const [email, setEmail] = React25.useState("");
1154
1227
  const [submitted, setSubmitted] = React25.useState(false);
1155
- function handleSubmit(e) {
1228
+ async function handleSubmit(e) {
1156
1229
  e.preventDefault();
1157
1230
  if (!email) return;
1231
+ await onSubscribe?.(email);
1158
1232
  setSubmitted(true);
1159
1233
  }
1160
1234
  return /* @__PURE__ */ jsx("section", { className: "overflow-hidden rounded-2xl border bg-card", children: /* @__PURE__ */ jsxs("div", { className: "relative px-6 py-14 sm:px-10 sm:py-20", children: [
1161
1235
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,hsl(var(--primary)/0.1),transparent_60%)]" }),
1162
1236
  /* @__PURE__ */ jsxs("div", { className: "relative mx-auto max-w-xl text-center", children: [
1163
1237
  /* @__PURE__ */ jsx("div", { className: "mb-4 inline-flex h-10 w-10 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(Mail, { className: "size-5" }) }),
1164
- /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", className: "mb-3", children: "Newsletter" }),
1165
- /* @__PURE__ */ jsx("h2", { className: "text-balance text-3xl font-semibold tracking-tight sm:text-4xl", children: "Stay in the loop" }),
1166
- /* @__PURE__ */ jsx("p", { className: "mx-auto mt-4 max-w-sm text-pretty text-muted-foreground", children: "New components, release notes, and product tips \u2014 straight to your inbox. No spam, unsubscribe any time." }),
1238
+ /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", className: "mb-3", children: badge }),
1239
+ /* @__PURE__ */ jsx("h2", { className: "text-balance text-3xl font-semibold tracking-tight sm:text-4xl", children: title }),
1240
+ /* @__PURE__ */ jsx("p", { className: "mx-auto mt-4 max-w-sm text-pretty text-muted-foreground", children: description }),
1167
1241
  submitted ? /* @__PURE__ */ jsxs("div", { className: "mt-8 rounded-2xl border bg-muted/50 px-6 py-5 text-sm", children: [
1168
- /* @__PURE__ */ jsx("span", { className: "font-medium", children: "You're on the list." }),
1242
+ /* @__PURE__ */ jsx("span", { className: "font-medium", children: successTitle }),
1169
1243
  " ",
1170
- /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: "We'll be in touch soon." })
1244
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground", children: successDescription })
1171
1245
  ] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "mt-8 flex flex-col gap-3 sm:flex-row", children: [
1172
1246
  /* @__PURE__ */ jsx(
1173
1247
  Input$1,
1174
1248
  {
1175
1249
  type: "email",
1176
- placeholder: "you@company.com",
1250
+ placeholder,
1177
1251
  value: email,
1178
1252
  onChange: (e) => setEmail(e.target.value),
1179
1253
  required: true,
@@ -1181,28 +1255,46 @@ function NewsletterSection() {
1181
1255
  }
1182
1256
  ),
1183
1257
  /* @__PURE__ */ jsxs(Button$1, { type: "submit", children: [
1184
- "Subscribe",
1258
+ submitLabel,
1185
1259
  /* @__PURE__ */ jsx(ArrowRight, { className: "ml-2 size-4" })
1186
1260
  ] })
1187
1261
  ] }),
1188
1262
  /* @__PURE__ */ jsxs("p", { className: "mt-4 text-xs text-muted-foreground", children: [
1189
1263
  "By subscribing you agree to our",
1190
1264
  " ",
1191
- /* @__PURE__ */ jsx("a", { href: "#", className: "underline underline-offset-4 hover:text-foreground", children: "Privacy Policy" }),
1265
+ /* @__PURE__ */ jsx("a", { href: privacyHref, className: "underline underline-offset-4 hover:text-foreground", children: privacyLabel }),
1192
1266
  "."
1193
1267
  ] })
1194
1268
  ] })
1195
1269
  ] }) });
1196
1270
  }
1197
- var contactInfo = [
1198
- { Icon: Mail, label: "Email", value: "hello@olwiba.com" },
1199
- { Icon: Phone, label: "Phone", value: "+1 (555) 000-0000" },
1200
- { Icon: MapPin, label: "Office", value: "San Francisco, CA" }
1271
+ var defaultContactInfoResolved = [
1272
+ { icon: Mail, label: "Email", value: "hello@olwiba.com" },
1273
+ { icon: Phone, label: "Phone", value: "+1 (555) 000-0000" },
1274
+ { icon: MapPin, label: "Office", value: "San Francisco, CA" }
1201
1275
  ];
1202
- function ContactSection() {
1276
+ var defaults2 = {
1277
+ badge: "Contact us",
1278
+ title: "Let's talk",
1279
+ description: "Have a question or want to work together? Fill in the form and we'll get back to you within one business day.",
1280
+ successTitle: "Message sent",
1281
+ successDescription: "Thanks for reaching out. We'll get back to you within one business day.",
1282
+ sendAnotherLabel: "Send another"
1283
+ };
1284
+ function ContactSection({
1285
+ badge = defaults2.badge,
1286
+ title = defaults2.title,
1287
+ description = defaults2.description,
1288
+ contactInfo = defaultContactInfoResolved,
1289
+ successTitle = defaults2.successTitle,
1290
+ successDescription = defaults2.successDescription,
1291
+ sendAnotherLabel = defaults2.sendAnotherLabel,
1292
+ onSubmit
1293
+ } = {}) {
1203
1294
  const [submitted, setSubmitted] = React25.useState(false);
1204
- function handleSubmit(e) {
1295
+ async function handleSubmit(e) {
1205
1296
  e.preventDefault();
1297
+ await onSubmit?.(e);
1206
1298
  setSubmitted(true);
1207
1299
  }
1208
1300
  return /* @__PURE__ */ jsx("section", { className: "overflow-hidden rounded-2xl border bg-card", children: /* @__PURE__ */ jsxs("div", { className: "grid lg:grid-cols-[1fr_1.4fr]", children: [
@@ -1210,12 +1302,19 @@ function ContactSection() {
1210
1302
  /* @__PURE__ */ jsx("div", { className: "absolute inset-0 bg-[radial-gradient(circle_at_top_right,hsl(var(--primary-foreground)/0.1),transparent_60%)]" }),
1211
1303
  /* @__PURE__ */ jsxs("div", { className: "relative space-y-6", children: [
1212
1304
  /* @__PURE__ */ jsxs("div", { children: [
1213
- /* @__PURE__ */ jsx(Badge$1, { variant: "secondary", className: "mb-3 bg-primary-foreground/15 text-primary-foreground hover:bg-primary-foreground/20", children: "Contact us" }),
1214
- /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold", children: "Let's talk" }),
1215
- /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-primary-foreground/70", children: "Have a question or want to work together? Fill in the form and we'll get back to you within one business day." })
1305
+ /* @__PURE__ */ jsx(
1306
+ Badge$1,
1307
+ {
1308
+ variant: "secondary",
1309
+ className: "mb-3 bg-primary-foreground/15 text-primary-foreground hover:bg-primary-foreground/20",
1310
+ children: badge
1311
+ }
1312
+ ),
1313
+ /* @__PURE__ */ jsx("h2", { className: "text-2xl font-semibold", children: title }),
1314
+ /* @__PURE__ */ jsx("p", { className: "mt-2 text-sm text-primary-foreground/70", children: description })
1216
1315
  ] }),
1217
1316
  /* @__PURE__ */ jsx(Separator, { className: "bg-primary-foreground/20" }),
1218
- /* @__PURE__ */ jsx("div", { className: "space-y-4", children: contactInfo.map(({ Icon, label, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1317
+ /* @__PURE__ */ jsx("div", { className: "space-y-4", children: contactInfo.map(({ icon: Icon = Mail, label, value }) => /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3", children: [
1219
1318
  /* @__PURE__ */ jsx("div", { className: "flex h-8 w-8 shrink-0 items-center justify-center rounded-lg bg-primary-foreground/10", children: /* @__PURE__ */ jsx(Icon, { className: "size-4" }) }),
1220
1319
  /* @__PURE__ */ jsxs("div", { children: [
1221
1320
  /* @__PURE__ */ jsx("div", { className: "text-xs text-primary-foreground/60", children: label }),
@@ -1227,10 +1326,10 @@ function ContactSection() {
1227
1326
  /* @__PURE__ */ jsx("div", { className: "p-8", children: submitted ? /* @__PURE__ */ jsxs("div", { className: "flex h-full min-h-[320px] flex-col items-center justify-center gap-4 text-center", children: [
1228
1327
  /* @__PURE__ */ jsx("div", { className: "flex h-12 w-12 items-center justify-center rounded-2xl bg-primary/10 text-primary", children: /* @__PURE__ */ jsx(MessageSquare, { className: "size-6" }) }),
1229
1328
  /* @__PURE__ */ jsxs("div", { children: [
1230
- /* @__PURE__ */ jsx("h3", { className: "font-semibold", children: "Message sent" }),
1231
- /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: "Thanks for reaching out. We'll get back to you within one business day." })
1329
+ /* @__PURE__ */ jsx("h3", { className: "font-semibold", children: successTitle }),
1330
+ /* @__PURE__ */ jsx("p", { className: "mt-1 text-sm text-muted-foreground", children: successDescription })
1232
1331
  ] }),
1233
- /* @__PURE__ */ jsx(Button$1, { variant: "outline", onClick: () => setSubmitted(false), children: "Send another" })
1332
+ /* @__PURE__ */ jsx(Button$1, { variant: "outline", onClick: () => setSubmitted(false), children: sendAnotherLabel })
1234
1333
  ] }) : /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, className: "space-y-5", children: [
1235
1334
  /* @__PURE__ */ jsxs("div", { className: "grid gap-4 sm:grid-cols-2", children: [
1236
1335
  /* @__PURE__ */ jsxs("div", { className: "space-y-1.5", children: [
@@ -1790,6 +1889,19 @@ function ConfirmDialog({ isOpen, options, handleConfirm, handleCancel, destructi
1790
1889
  ] })
1791
1890
  ] }) });
1792
1891
  }
1892
+ function AppScreenRoot({ children, className }) {
1893
+ return /* @__PURE__ */ jsx("div", { className: cn("flex h-full flex-col", className), children });
1894
+ }
1895
+ function AppScreenHeader({ children, className }) {
1896
+ return /* @__PURE__ */ jsx("div", { className: cn("flex items-center gap-2 border-b border-border px-4 py-3 shrink-0", className), children });
1897
+ }
1898
+ function AppScreenBody({ children, className }) {
1899
+ return /* @__PURE__ */ jsx("div", { className: cn("flex-1 overflow-auto px-4 py-3", className), children });
1900
+ }
1901
+ var AppScreen = Object.assign(AppScreenRoot, {
1902
+ Header: AppScreenHeader,
1903
+ Body: AppScreenBody
1904
+ });
1793
1905
  var blurClass2 = {
1794
1906
  sm: "backdrop-blur-sm",
1795
1907
  md: "backdrop-blur-md",
@@ -2052,6 +2164,30 @@ function PostList({ posts, renderLink, emptyMessage = "No posts published yet."
2052
2164
  }
2053
2165
  return /* @__PURE__ */ jsx("div", { className: "grid gap-8 sm:grid-cols-2", children: posts.map((post) => /* @__PURE__ */ jsx(PostCard, { ...post, renderLink }, post.slug)) });
2054
2166
  }
2167
+ var components = {
2168
+ h1: ({ className, ...props }) => /* @__PURE__ */ jsx("h1", { className: cn("mt-8 scroll-m-20 text-3xl font-bold tracking-tight text-foreground first:mt-0", className), ...props }),
2169
+ h2: ({ className, ...props }) => /* @__PURE__ */ jsx("h2", { className: cn("mt-10 scroll-m-20 text-2xl font-semibold tracking-tight text-foreground first:mt-0", className), ...props }),
2170
+ h3: ({ className, ...props }) => /* @__PURE__ */ jsx("h3", { className: cn("mt-8 scroll-m-20 text-xl font-semibold tracking-tight text-foreground", className), ...props }),
2171
+ h4: ({ className, ...props }) => /* @__PURE__ */ jsx("h4", { className: cn("mt-6 scroll-m-20 text-lg font-semibold tracking-tight text-foreground", className), ...props }),
2172
+ p: ({ className, ...props }) => /* @__PURE__ */ jsx("p", { className: cn("leading-7 text-muted-foreground [&:not(:first-child)]:mt-6", className), ...props }),
2173
+ ul: ({ className, ...props }) => /* @__PURE__ */ jsx("ul", { className: cn("my-6 ml-6 list-disc text-muted-foreground", className), ...props }),
2174
+ ol: ({ className, ...props }) => /* @__PURE__ */ jsx("ol", { className: cn("my-6 ml-6 list-decimal text-muted-foreground", className), ...props }),
2175
+ li: ({ className, ...props }) => /* @__PURE__ */ jsx("li", { className: cn("mt-2", className), ...props }),
2176
+ blockquote: ({ className, ...props }) => /* @__PURE__ */ jsx("blockquote", { className: cn("mt-6 rounded-r-lg border-l-4 border-primary bg-muted py-4 pl-6 pr-4 italic text-muted-foreground", className), ...props }),
2177
+ hr: (props) => /* @__PURE__ */ jsx("hr", { className: "my-8 border-border", ...props }),
2178
+ img: ({ className, alt, ...props }) => /* @__PURE__ */ jsx("img", { className: cn("rounded-lg border shadow-sm", className), alt, ...props }),
2179
+ pre: ({ className, ...props }) => /* @__PURE__ */ jsx("pre", { className: cn("mt-6 mb-4 overflow-x-auto rounded-lg bg-muted p-4 text-sm", className), ...props }),
2180
+ code: ({ className, ...props }) => /* @__PURE__ */ jsx("code", { className: cn("relative rounded bg-muted px-[0.3rem] py-[0.2rem] font-mono text-sm text-foreground", className), ...props }),
2181
+ table: ({ className, ...props }) => /* @__PURE__ */ jsx("div", { className: "my-6 w-full overflow-y-auto rounded-lg border border-border", children: /* @__PURE__ */ jsx("table", { className: cn("w-full", className), ...props }) }),
2182
+ tr: ({ className, ...props }) => /* @__PURE__ */ jsx("tr", { className: cn("m-0 border-t border-border p-0 even:bg-muted", className), ...props }),
2183
+ th: ({ className, ...props }) => /* @__PURE__ */ jsx("th", { className: cn("border border-border px-4 py-2 text-left font-bold [&[align=center]]:text-center [&[align=right]]:text-right", className), ...props }),
2184
+ td: ({ className, ...props }) => /* @__PURE__ */ jsx("td", { className: cn("border border-border px-4 py-2 text-left [&[align=center]]:text-center [&[align=right]]:text-right", className), ...props }),
2185
+ a: ({ className, ...props }) => /* @__PURE__ */ jsx("a", { className: cn("font-medium text-primary underline underline-offset-4 hover:text-primary/80", className), ...props })
2186
+ };
2187
+ function MdxContent({ code }) {
2188
+ const MDXComponent = useMDXComponent(code);
2189
+ return /* @__PURE__ */ jsx(MDXComponent, { components });
2190
+ }
2055
2191
  function useMounted() {
2056
2192
  const [mounted, setMounted] = useState(false);
2057
2193
  useEffect(() => {
@@ -2186,6 +2322,6 @@ function usePagination(total, pageSize) {
2186
2322
  return { page, pageSize, totalPages, offset, hasPrev: page > 1, hasNext: page < totalPages, goTo, next, prev };
2187
2323
  }
2188
2324
 
2189
- export { AppShell, AuthSection, Badge, Button, Card, Checkbox, ConfirmDialog, ContactSection, ContextMenu, CountUp, CtaSection, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeaturesSection, Footer, FullPageSpinner, GlassCard, HeroSection, ImageCard, Input, LogoStrip, Navbar, NewsletterSection, OlwibaUIProvider, Overlay, PageHeader, PageTransition, PostCard, PostList, PricingCard, PricingSection, RegisterHotkeys, RootErrorFallback, SectionTitle, Spotlight, StaggerChildren, StatCard, StatsSection, Suspensed, Switch, TeamSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpgradePrompt, VersionBanner, cn, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
2325
+ export { AppScreen, AppShell, AuthSection, Badge, Button, Card, Checkbox, ConfirmDialog, ContactSection, ContextMenu, CountUp, CtaSection, DevBanner, Dock, EmptyState, ErrorPage, FadeIn, FaqSection, FeatureCard, FeaturesSection, Footer, FullPageSpinner, GlassCard, HeroSection, ImageCard, Input, LogoStrip, MdxContent, Navbar, NewsletterSection, OlwibaUIProvider, Overlay, PageHeader, PageTransition, PhoneFrame, PostCard, PostList, PricingCard, PricingSection, RegisterHotkeys, RootErrorFallback, SectionTitle, Spotlight, StaggerChildren, StatCard, StatsSection, Suspensed, Switch, TeamSection, TestimonialCard, TestimonialsSection, Textarea, ThemeColorUpdater, ThemeSwitchMinimal, Underlay, UpgradePrompt, VersionBanner, cn, useConfirm, useControlledOpen, useCopyToClipboard, useDebounce, useIntersectionObserver, useLocalStorage, useMediaQuery, useMounted, useOlwibaUI, usePagination, useScrolledPast, useUIMode };
2190
2326
  //# sourceMappingURL=index.js.map
2191
2327
  //# sourceMappingURL=index.js.map