@olwiba/ui 0.2.25 → 0.2.26

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 (202) hide show
  1. package/content/docs/app/app-shell.mdx +71 -0
  2. package/content/docs/app/auth-section.mdx +73 -0
  3. package/content/docs/app/billing-panel.mdx +38 -0
  4. package/content/docs/app/empty-state.mdx +47 -0
  5. package/content/docs/app/error-page.mdx +31 -0
  6. package/content/docs/app/index.mdx +13 -0
  7. package/content/docs/app/meta.json +4 -0
  8. package/content/docs/app/onboarding-wizard.mdx +41 -0
  9. package/content/docs/app/settings-section.mdx +37 -0
  10. package/content/docs/app/team-members-panel.mdx +35 -0
  11. package/content/docs/app/update-banner.mdx +43 -0
  12. package/content/docs/components/activity-feed.mdx +42 -0
  13. package/content/docs/components/chart.mdx +47 -0
  14. package/content/docs/components/command-menu.mdx +41 -0
  15. package/content/docs/components/confirm-dialog.mdx +26 -0
  16. package/content/docs/components/context-menu.mdx +26 -0
  17. package/content/docs/components/data-table.mdx +40 -0
  18. package/content/docs/components/dock.mdx +26 -0
  19. package/content/docs/components/feature-card.mdx +26 -0
  20. package/content/docs/components/file-upload.mdx +35 -0
  21. package/content/docs/components/full-page-spinner.mdx +44 -0
  22. package/content/docs/components/glass-card.mdx +26 -0
  23. package/content/docs/components/image-card.mdx +26 -0
  24. package/content/docs/components/index.mdx +49 -0
  25. package/content/docs/components/load-more.mdx +34 -0
  26. package/content/docs/components/meta.json +35 -0
  27. package/content/docs/components/notifications-popover.mdx +34 -0
  28. package/content/docs/components/notify.mdx +40 -0
  29. package/content/docs/components/olwiba-ui-context.mdx +69 -0
  30. package/content/docs/components/page-header.mdx +42 -0
  31. package/content/docs/components/pricing-card.mdx +26 -0
  32. package/content/docs/components/register-hotkeys.mdx +50 -0
  33. package/content/docs/components/root-error-fallback.mdx +39 -0
  34. package/content/docs/components/spotlight.mdx +26 -0
  35. package/content/docs/components/stat-card.mdx +26 -0
  36. package/content/docs/components/suspensed.mdx +42 -0
  37. package/content/docs/components/testimonial-card.mdx +26 -0
  38. package/content/docs/components/theme-color-updater.mdx +40 -0
  39. package/content/docs/components/theme-switch-minimal.mdx +32 -0
  40. package/content/docs/components/version-banner.mdx +44 -0
  41. package/content/docs/email/action-email.mdx +62 -0
  42. package/content/docs/email/email-layout.mdx +58 -0
  43. package/content/docs/email/email-link-fallback.mdx +46 -0
  44. package/content/docs/email/index.mdx +32 -0
  45. package/content/docs/email/meta.json +10 -0
  46. package/content/docs/email/notice-email.mdx +51 -0
  47. package/content/docs/hooks/index.mdx +21 -0
  48. package/content/docs/hooks/meta.json +16 -0
  49. package/content/docs/hooks/use-confirm.mdx +81 -0
  50. package/content/docs/hooks/use-controlled-open.mdx +53 -0
  51. package/content/docs/hooks/use-copy-to-clipboard.mdx +26 -0
  52. package/content/docs/hooks/use-debounce.mdx +26 -0
  53. package/content/docs/hooks/use-intersection-observer.mdx +26 -0
  54. package/content/docs/hooks/use-local-storage.mdx +26 -0
  55. package/content/docs/hooks/use-media-query.mdx +26 -0
  56. package/content/docs/hooks/use-mounted.mdx +39 -0
  57. package/content/docs/hooks/use-pagination.mdx +26 -0
  58. package/content/docs/hooks/use-scrolled-past.mdx +44 -0
  59. package/content/docs/index.mdx +68 -0
  60. package/content/docs/marketing/contact-section.mdx +16 -0
  61. package/content/docs/marketing/cta-section.mdx +31 -0
  62. package/content/docs/marketing/faq-section.mdx +16 -0
  63. package/content/docs/marketing/features-section.mdx +23 -0
  64. package/content/docs/marketing/footer.mdx +16 -0
  65. package/content/docs/marketing/hero-section.mdx +16 -0
  66. package/content/docs/marketing/index.mdx +22 -0
  67. package/content/docs/marketing/meta.json +20 -0
  68. package/content/docs/marketing/navbar.mdx +16 -0
  69. package/content/docs/marketing/newsletter-section.mdx +16 -0
  70. package/content/docs/marketing/post-list.mdx +32 -0
  71. package/content/docs/marketing/pricing-section.mdx +16 -0
  72. package/content/docs/marketing/stats-section.mdx +16 -0
  73. package/content/docs/marketing/steps-section.mdx +60 -0
  74. package/content/docs/marketing/team-section.mdx +16 -0
  75. package/content/docs/marketing/testimonials-section.mdx +16 -0
  76. package/content/docs/mechanics/carousel.mdx +42 -0
  77. package/content/docs/mechanics/index.mdx +11 -0
  78. package/content/docs/mechanics/meta.json +4 -0
  79. package/content/docs/mechanics/sortable.mdx +44 -0
  80. package/content/docs/meta.json +4 -0
  81. package/content/docs/motion/animated-swap.mdx +75 -0
  82. package/content/docs/motion/count-up.mdx +31 -0
  83. package/content/docs/motion/fade-in.mdx +34 -0
  84. package/content/docs/motion/index.mdx +12 -0
  85. package/content/docs/motion/meta.json +4 -0
  86. package/content/docs/motion/page-transition.mdx +29 -0
  87. package/content/docs/motion/stagger-children.mdx +31 -0
  88. package/content/docs/overlays/index.mdx +9 -0
  89. package/content/docs/overlays/meta.json +4 -0
  90. package/content/docs/overlays/overlay.mdx +60 -0
  91. package/content/docs/overlays/underlay.mdx +56 -0
  92. package/dist/email/index.d.ts +8 -1
  93. package/dist/email/index.js +3 -3
  94. package/dist/email/index.js.map +1 -1
  95. package/docs-manifest.json +253 -0
  96. package/package.json +16 -8
  97. package/site/demos/action-email.tsx +6 -0
  98. package/site/demos/activity-feed.tsx +42 -0
  99. package/site/demos/animated-swap.tsx +42 -0
  100. package/site/demos/app-shell.tsx +47 -0
  101. package/site/demos/app-ui-page.tsx +9 -0
  102. package/site/demos/application-sidebar-block.tsx +9 -0
  103. package/site/demos/auth-section.tsx +15 -0
  104. package/site/demos/auth-split-block.tsx +9 -0
  105. package/site/demos/billing-page.tsx +157 -0
  106. package/site/demos/billing-panel.tsx +26 -0
  107. package/site/demos/carousel.tsx +34 -0
  108. package/site/demos/chart.tsx +55 -0
  109. package/site/demos/command-menu.tsx +39 -0
  110. package/site/demos/confirm-dialog.tsx +27 -0
  111. package/site/demos/contact-form-block.tsx +3 -0
  112. package/site/demos/contact-section.tsx +2 -0
  113. package/site/demos/context-menu.tsx +30 -0
  114. package/site/demos/count-up.tsx +23 -0
  115. package/site/demos/cta-section.tsx +6 -0
  116. package/site/demos/dashboard-overview-block.tsx +9 -0
  117. package/site/demos/dashboard-shell-block.tsx +10 -0
  118. package/site/demos/data-table.tsx +47 -0
  119. package/site/demos/demo-brand.tsx +23 -0
  120. package/site/demos/dock.tsx +20 -0
  121. package/site/demos/document-sidebar-block.tsx +9 -0
  122. package/site/demos/email-examples.tsx +58 -0
  123. package/site/demos/email-frame.tsx +50 -0
  124. package/site/demos/email-layout.tsx +6 -0
  125. package/site/demos/email-link-fallback.tsx +6 -0
  126. package/site/demos/email-previews.generated.ts +11 -0
  127. package/site/demos/empty-state-block.tsx +3 -0
  128. package/site/demos/empty-state.tsx +23 -0
  129. package/site/demos/error-page.tsx +5 -0
  130. package/site/demos/fade-in.tsx +18 -0
  131. package/site/demos/faq-section.tsx +6 -0
  132. package/site/demos/feature-card.tsx +13 -0
  133. package/site/demos/features-section.tsx +6 -0
  134. package/site/demos/file-upload.tsx +16 -0
  135. package/site/demos/footer.tsx +42 -0
  136. package/site/demos/full-page-spinner.tsx +9 -0
  137. package/site/demos/glass-card.tsx +14 -0
  138. package/site/demos/glow-effect.tsx +3 -0
  139. package/site/demos/gradient-background.tsx +3 -0
  140. package/site/demos/grid-pattern.tsx +3 -0
  141. package/site/demos/hero-section.tsx +6 -0
  142. package/site/demos/image-card.tsx +17 -0
  143. package/site/demos/login-block.tsx +9 -0
  144. package/site/demos/marketing-cta-block.tsx +3 -0
  145. package/site/demos/marketing-demo-data.tsx +114 -0
  146. package/site/demos/marketing-faq-block.tsx +3 -0
  147. package/site/demos/marketing-features-block.tsx +3 -0
  148. package/site/demos/marketing-footer-block.tsx +3 -0
  149. package/site/demos/marketing-hero-block.tsx +10 -0
  150. package/site/demos/marketing-nav-block.tsx +3 -0
  151. package/site/demos/marketing-newsletter-block.tsx +3 -0
  152. package/site/demos/marketing-page.tsx +52 -0
  153. package/site/demos/marketing-pricing-block.tsx +3 -0
  154. package/site/demos/marketing-stats-block.tsx +3 -0
  155. package/site/demos/marketing-team-block.tsx +3 -0
  156. package/site/demos/marketing-testimonials-block.tsx +3 -0
  157. package/site/demos/navbar.tsx +32 -0
  158. package/site/demos/newsletter-section.tsx +2 -0
  159. package/site/demos/noise-overlay.tsx +3 -0
  160. package/site/demos/not-found-block.tsx +3 -0
  161. package/site/demos/notice-email.tsx +6 -0
  162. package/site/demos/notifications-popover.tsx +27 -0
  163. package/site/demos/notify.tsx +44 -0
  164. package/site/demos/olwiba-ui-context.tsx +51 -0
  165. package/site/demos/onboarding-block.tsx +3 -0
  166. package/site/demos/onboarding-wizard.tsx +43 -0
  167. package/site/demos/overlay.tsx +72 -0
  168. package/site/demos/page-header.tsx +15 -0
  169. package/site/demos/page-transition.tsx +34 -0
  170. package/site/demos/post-list.tsx +24 -0
  171. package/site/demos/pricing-card.tsx +27 -0
  172. package/site/demos/pricing-section.tsx +6 -0
  173. package/site/demos/register-hotkeys.tsx +39 -0
  174. package/site/demos/root-error-fallback.tsx +28 -0
  175. package/site/demos/settings-layout-block.tsx +3 -0
  176. package/site/demos/settings-section.tsx +22 -0
  177. package/site/demos/sign-in-page.tsx +10 -0
  178. package/site/demos/sortable.tsx +30 -0
  179. package/site/demos/spotlight.tsx +29 -0
  180. package/site/demos/stagger-children.tsx +16 -0
  181. package/site/demos/stat-card.tsx +12 -0
  182. package/site/demos/stats-section.tsx +6 -0
  183. package/site/demos/steps-section.tsx +66 -0
  184. package/site/demos/suspensed.tsx +31 -0
  185. package/site/demos/team-members-panel.tsx +26 -0
  186. package/site/demos/team-section.tsx +2 -0
  187. package/site/demos/testimonial-card.tsx +17 -0
  188. package/site/demos/testimonials-section.tsx +6 -0
  189. package/site/demos/theme-color-updater.tsx +32 -0
  190. package/site/demos/theme-switch-minimal.tsx +10 -0
  191. package/site/demos/underlay.tsx +74 -0
  192. package/site/demos/update-banner.tsx +31 -0
  193. package/site/demos/use-copy-to-clipboard.tsx +21 -0
  194. package/site/demos/use-debounce.tsx +25 -0
  195. package/site/demos/use-intersection-observer.tsx +32 -0
  196. package/site/demos/use-local-storage.tsx +22 -0
  197. package/site/demos/use-media-query.tsx +31 -0
  198. package/site/demos/use-pagination.tsx +31 -0
  199. package/site/demos/user-profile-block.tsx +3 -0
  200. package/site/demos/version-banner.tsx +27 -0
  201. package/src/email/EmailLinkFallback.tsx +7 -1
  202. package/src/email/index.ts +3 -0
@@ -0,0 +1,6 @@
1
+ import { FaqSection } from '@olwiba/ui';
2
+ import { demoFaqItems } from './marketing-demo-data';
3
+
4
+ export default function Demo() {
5
+ return <FaqSection items={demoFaqItems} />;
6
+ }
@@ -0,0 +1,13 @@
1
+ 'use client';
2
+ import { FeatureCard } from '@olwiba/ui';
3
+ import { BarChart2, Shield, Zap } from 'lucide-react';
4
+
5
+ export default function Demo() {
6
+ return (
7
+ <div className="grid gap-4 p-6 sm:grid-cols-3">
8
+ <FeatureCard icon={Zap} title="Fast by default" description="Built on optimised primitives. Nothing ships that slows you down." />
9
+ <FeatureCard icon={Shield} title="Secure" description="Authentication and access control baked in from day one." />
10
+ <FeatureCard icon={BarChart2} title="Analytics" description="Understand usage with built-in telemetry and reporting tools." href="#" />
11
+ </div>
12
+ );
13
+ }
@@ -0,0 +1,6 @@
1
+ import { FeaturesSection } from '@olwiba/ui';
2
+ import { demoFeatures } from './marketing-demo-data';
3
+
4
+ export default function Demo() {
5
+ return <FeaturesSection features={demoFeatures} />;
6
+ }
@@ -0,0 +1,16 @@
1
+ 'use client';
2
+ import { FileUpload } from '@olwiba/ui';
3
+
4
+ export default function Demo() {
5
+ return (
6
+ <div className="mx-auto max-w-md p-8">
7
+ <FileUpload
8
+ multiple
9
+ accept="image/png,image/jpeg"
10
+ maxSizeMb={5}
11
+ maxFiles={4}
12
+ hint="PNG or JPG, up to 5MB each"
13
+ />
14
+ </div>
15
+ );
16
+ }
@@ -0,0 +1,42 @@
1
+ import { Footer } from '@olwiba/ui';
2
+ import { Zap } from 'lucide-react';
3
+
4
+ const navLinks = [
5
+ { label: 'Features', href: '#' },
6
+ { label: 'Pricing', href: '#' },
7
+ { label: 'About', href: '#' },
8
+ { label: 'Blog', href: '#' },
9
+ { label: 'Privacy', href: '#' },
10
+ { label: 'Terms', href: '#' },
11
+ ];
12
+
13
+ const socialLinks = [
14
+ {
15
+ label: 'GitHub',
16
+ href: '#',
17
+ icon: (
18
+ <svg viewBox="0 0 24 24" aria-hidden="true" className="size-5 fill-current">
19
+ <path fillRule="evenodd" d="M12 2C6.477 2 2 6.484 2 12.017c0 4.425 2.865 8.18 6.839 9.504.5.092.682-.217.682-.483 0-.237-.008-.868-.013-1.703-2.782.605-3.369-1.343-3.369-1.343-.454-1.158-1.11-1.466-1.11-1.466-.908-.62.069-.608.069-.608 1.003.07 1.531 1.032 1.531 1.032.892 1.53 2.341 1.088 2.91.832.092-.647.35-1.088.636-1.338-2.22-.253-4.555-1.113-4.555-4.951 0-1.093.39-1.988 1.029-2.688-.103-.253-.446-1.272.098-2.65 0 0 .84-.27 2.75 1.026A9.564 9.564 0 0112 6.844c.85.004 1.705.115 2.504.337 1.909-1.296 2.747-1.027 2.747-1.027.546 1.379.202 2.398.1 2.651.64.7 1.028 1.595 1.028 2.688 0 3.848-2.339 4.695-4.566 4.942.359.31.678.921.678 1.856 0 1.338-.012 2.419-.012 2.747 0 .268.18.58.688.482A10.019 10.019 0 0022 12.017C22 6.484 17.522 2 12 2z" clipRule="evenodd" />
20
+ </svg>
21
+ ),
22
+ },
23
+ {
24
+ label: 'X',
25
+ href: '#',
26
+ icon: (
27
+ <svg viewBox="0 0 24 24" aria-hidden="true" className="size-5 fill-current">
28
+ <path d="M13.6823 10.6218L20.2391 3h-1.5961l-5.7041 6.6168L8.5419 3H3.4482l6.8893 10.0168L3.4482 21h1.5962l6.0213-6.9902L15.4581 21h5.0937L13.6823 10.6218zm-2.1315 2.4768l-.6978-.9985L5.5792 4.1579h2.3908l4.4832 6.4168.6978.9985 5.8267 8.3358h-2.3908l-4.7561-6.8122z" />
29
+ </svg>
30
+ ),
31
+ },
32
+ ];
33
+
34
+ export default function Demo() {
35
+ return (
36
+ <Footer
37
+ brand={{ name: 'Nexus Inc', logo: <Zap className="size-4" /> }}
38
+ navLinks={navLinks}
39
+ socialLinks={socialLinks}
40
+ />
41
+ );
42
+ }
@@ -0,0 +1,9 @@
1
+ import { FullPageSpinner } from '@olwiba/ui';
2
+
3
+ export default function FullPageSpinnerDemo() {
4
+ return (
5
+ <div className="relative h-40 w-full max-w-sm rounded-lg border border-dashed overflow-hidden">
6
+ <FullPageSpinner message="Loading..." />
7
+ </div>
8
+ );
9
+ }
@@ -0,0 +1,14 @@
1
+ 'use client';
2
+ import { GlassCard } from '@olwiba/ui';
3
+
4
+ export default function Demo() {
5
+ return (
6
+ <div className="relative flex items-center justify-center overflow-hidden rounded-2xl bg-gradient-to-br from-violet-500 via-blue-500 to-cyan-400 p-12">
7
+ <div className="absolute inset-0 bg-[radial-gradient(ellipse_at_top_right,_var(--tw-gradient-stops))] from-white/20 to-transparent" />
8
+ <GlassCard blur="md" className="max-w-xs p-6">
9
+ <h3 className="font-semibold">Glass card</h3>
10
+ <p className="mt-1 text-sm text-muted-foreground">Frosted glass effect with configurable blur and transparency.</p>
11
+ </GlassCard>
12
+ </div>
13
+ );
14
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">GlowEffect — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">GradientBackground — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">GridPattern — coming soon</div>;
3
+ }
@@ -0,0 +1,6 @@
1
+ import { HeroSection } from '@olwiba/ui';
2
+ import { demoHero } from './marketing-demo-data';
3
+
4
+ export default function Demo() {
5
+ return <HeroSection {...demoHero} />;
6
+ }
@@ -0,0 +1,17 @@
1
+ 'use client';
2
+ import { ImageCard } from '@olwiba/ui';
3
+
4
+ export default function Demo() {
5
+ return (
6
+ <div className="grid gap-4 p-6 sm:grid-cols-2">
7
+ <ImageCard src="https://picsum.photos/seed/mountain/640/360" alt="Mountain landscape" overlay="subtle">
8
+ <h3 className="font-semibold text-lg">Mountain escape</h3>
9
+ <p className="text-sm text-white/80">Swiss Alps</p>
10
+ </ImageCard>
11
+ <ImageCard src="https://picsum.photos/seed/city/640/360" alt="City skyline" overlay="strong">
12
+ <h3 className="font-semibold text-lg">City lights</h3>
13
+ <p className="text-sm text-white/80">New York</p>
14
+ </ImageCard>
15
+ </div>
16
+ );
17
+ }
@@ -0,0 +1,9 @@
1
+ import { AuthSection } from '@olwiba/ui';
2
+
3
+ export default function LoginBlockDemo() {
4
+ return (
5
+ <div className="w-full max-w-5xl">
6
+ <AuthSection layout="centered" />
7
+ </div>
8
+ );
9
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingCtaBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,114 @@
1
+ import { Bell, Blocks, Rocket } from 'lucide-react';
2
+
3
+ export const demoHero = {
4
+ badge: 'Launch kit',
5
+ heading: 'Ship polished product pages without rebuilding the same sections',
6
+ description:
7
+ 'Composable marketing blocks, app shells, and interaction patterns built on the Olwiba design system.',
8
+ primaryCta: { label: 'Explore blocks', href: '#features' },
9
+ secondaryCta: { label: 'View docs', href: '/docs' },
10
+ media: 'image' as const,
11
+ heroImage: (
12
+ <div className="grid aspect-[4/3] place-items-center bg-gradient-to-br from-primary/20 via-background to-muted p-8">
13
+ <div className="rounded-3xl border bg-background/80 p-6 text-center shadow-xl backdrop-blur">
14
+ <Rocket className="mx-auto mb-3 size-10 text-primary" />
15
+ <p className="text-sm font-medium text-muted-foreground">Preview-ready UI blocks</p>
16
+ </div>
17
+ </div>
18
+ ),
19
+ };
20
+
21
+ export const demoFeatures = [
22
+ {
23
+ icon: Blocks,
24
+ title: 'Composable sections',
25
+ description: 'Hero, CTA, pricing, FAQ, and feature blocks that can be assembled quickly.',
26
+ },
27
+ {
28
+ icon: Bell,
29
+ title: 'Product patterns',
30
+ description: 'App-ready components for dashboards, notifications, and settings screens.',
31
+ },
32
+ {
33
+ icon: Rocket,
34
+ title: 'Launch focused',
35
+ description: 'Sensible defaults keep demos useful before a product adds custom copy.',
36
+ },
37
+ ];
38
+
39
+ export const demoStats = [
40
+ { value: '40+', label: 'Blocks', description: 'Reusable sections, shells, and app patterns.' },
41
+ { value: '3', label: 'Layers', description: 'CN primitives, UI blocks, and Pro compositions.' },
42
+ { value: '100%', label: 'Composable', description: 'Bring your router, copy, and product logic.' },
43
+ { value: '0', label: 'Blank demos', description: 'Required props are supplied in the docs site.' },
44
+ ];
45
+
46
+ export const demoTestimonials = [
47
+ {
48
+ quote: 'The defaults are polished enough to preview, but still flexible once product copy lands.',
49
+ name: 'Ollie',
50
+ role: 'Founder',
51
+ company: 'Olwiba',
52
+ initials: 'O',
53
+ rating: 5,
54
+ },
55
+ {
56
+ quote: 'A shared block system means the next product starts from a stronger baseline.',
57
+ name: 'Nexus',
58
+ role: 'Factory layer',
59
+ company: 'Olwiba',
60
+ initials: 'N',
61
+ rating: 5,
62
+ },
63
+ ];
64
+
65
+ export const demoPlans = [
66
+ {
67
+ name: 'Starter',
68
+ monthly: 0,
69
+ annual: 0,
70
+ description: 'For trying the component surface in a small product.',
71
+ cta: 'Start free',
72
+ features: [
73
+ { label: 'Core marketing sections', included: true },
74
+ { label: 'App shell patterns', included: true },
75
+ { label: 'Premium compositions', included: false },
76
+ ],
77
+ },
78
+ {
79
+ name: 'Pro',
80
+ monthly: 29,
81
+ annual: 290,
82
+ description: 'For products that need richer launch and app surfaces.',
83
+ cta: 'Upgrade',
84
+ highlighted: true,
85
+ features: [
86
+ { label: 'Everything in Starter', included: true },
87
+ { label: 'Advanced app blocks', included: true },
88
+ { label: 'Private Pro components', included: true },
89
+ ],
90
+ },
91
+ ];
92
+
93
+ export const demoCta = {
94
+ heading: 'Start with the blocks, then make them yours',
95
+ description: 'Use the defaults to prototype quickly, then pass product-specific copy and actions.',
96
+ primaryCta: { label: 'Browse components', href: '/docs' },
97
+ secondaryCta: { label: 'See features', href: '#features' },
98
+ footnote: 'Built on @olwiba/cn tokens and primitives.',
99
+ };
100
+
101
+ export const demoFaqItems = [
102
+ {
103
+ question: 'Can these blocks be used in a real app?',
104
+ answer: 'Yes. They are published package components, not one-off docs examples.',
105
+ },
106
+ {
107
+ question: 'Do I need to provide props?',
108
+ answer: 'Required content props keep production pages explicit while demos supply safe sample data.',
109
+ },
110
+ {
111
+ question: 'Can links use a router?',
112
+ answer: 'Yes. Components accept renderLink where routing needs to be framework-specific.',
113
+ },
114
+ ];
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingFaqBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingFeaturesBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingFooterBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,10 @@
1
+ import { HeroSection } from '@olwiba/ui';
2
+ import { demoHero } from './marketing-demo-data';
3
+
4
+ export default function MarketingHeroBlockDemo() {
5
+ return (
6
+ <div className="w-full max-w-6xl">
7
+ <HeroSection {...demoHero} />
8
+ </div>
9
+ );
10
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingNavBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingNewsletterBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,52 @@
1
+ import {
2
+ CtaSection,
3
+ FaqSection,
4
+ FeaturesSection,
5
+ Footer,
6
+ HeroSection,
7
+ Navbar,
8
+ PricingSection,
9
+ StatsSection,
10
+ TestimonialsSection,
11
+ } from '@olwiba/ui';
12
+ import { demoBrandLogo, demoBrandName } from './demo-brand';
13
+ import {
14
+ demoCta,
15
+ demoFaqItems,
16
+ demoFeatures,
17
+ demoHero,
18
+ demoPlans,
19
+ demoStats,
20
+ demoTestimonials,
21
+ } from './marketing-demo-data';
22
+
23
+ export default function Demo() {
24
+ return (
25
+ <div className="w-full max-w-6xl space-y-4">
26
+ <Navbar
27
+ brand={{ name: demoBrandName, logo: demoBrandLogo, href: '/' }}
28
+ navLinks={[
29
+ { label: 'features', href: '#features' },
30
+ { label: 'pricing', href: '#pricing' },
31
+ { label: 'faq', href: '#faq' },
32
+ ]}
33
+ />
34
+ <HeroSection {...demoHero} />
35
+ <FeaturesSection features={demoFeatures} />
36
+ <StatsSection stats={demoStats} />
37
+ <TestimonialsSection testimonials={demoTestimonials} />
38
+ <PricingSection plans={demoPlans} />
39
+ <CtaSection {...demoCta} />
40
+ <FaqSection items={demoFaqItems} />
41
+ <Footer
42
+ brand={{ name: demoBrandName, logo: demoBrandLogo, href: '/' }}
43
+ navLinks={[
44
+ { label: 'features', href: '#features' },
45
+ { label: 'pricing', href: '#pricing' },
46
+ { label: 'docs', href: '/docs' },
47
+ ]}
48
+ status={{ label: 'All systems operational' }}
49
+ />
50
+ </div>
51
+ );
52
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingPricingBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingStatsBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingTeamBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">MarketingTestimonialsBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,32 @@
1
+ import { Navbar } from '@olwiba/ui';
2
+ import { demoBrandLogo, demoBrandName } from './demo-brand';
3
+
4
+ /**
5
+ * Every prop is supplied deliberately. `brand` and `navLinks` are required, and
6
+ * this demo previously rendered `<Navbar />` bare — which threw on `brand.href`
7
+ * before the component painted anything, so the page showed no preview at all.
8
+ *
9
+ * The lockup comes from `~/lib/demo-brand`, shared with the AppShell demo, so
10
+ * the marketing header and the app sidebar are showing the same badge rather
11
+ * than two copies that can drift apart.
12
+ *
13
+ * Lowercase throughout on purpose — a lowercase name has no cap-height and no
14
+ * descenders, which is the least forgiving case for the vertical alignment
15
+ * between the name and the logo badge beside it.
16
+ */
17
+ export default function Demo() {
18
+ return (
19
+ <Navbar
20
+ brand={{ name: demoBrandName, logo: demoBrandLogo, href: '/' }}
21
+ navLinks={[
22
+ { label: 'features', href: '#features' },
23
+ { label: 'pricing', href: '#pricing' },
24
+ { label: 'docs', href: '#docs' },
25
+ ]}
26
+ cta={{
27
+ secondary: { label: 'sign in', href: '#sign-in' },
28
+ primary: { label: 'get started', href: '#get-started' },
29
+ }}
30
+ />
31
+ );
32
+ }
@@ -0,0 +1,2 @@
1
+ import { NewsletterSection } from '@olwiba/ui';
2
+ export default function Demo() { return <NewsletterSection />; }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">NoiseOverlay — coming soon</div>;
3
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">NotFoundBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,6 @@
1
+ 'use client';
2
+ import { EmailFrame } from './email-frame';
3
+
4
+ export default function Demo() {
5
+ return <EmailFrame id="notice-email" />;
6
+ }
@@ -0,0 +1,27 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+ import { NotificationsPopover, type NotificationItem } from '@olwiba/ui';
4
+ import { GitPullRequest, Rocket, UserPlus } from 'lucide-react';
5
+
6
+ const initial: NotificationItem[] = [
7
+ { id: '1', title: 'Deploy complete', description: 'v0.1.16 is live on production.', timestamp: '2m ago', icon: <Rocket className="size-4" /> },
8
+ { id: '2', title: 'Ana Sousa requested a review', description: 'feat: billing usage alerts (#482)', timestamp: '1h ago', avatar: 'https://ui.shadcn.com/avatars/01.png' },
9
+ { id: '3', title: 'New team member', description: 'Marcus Webb accepted your invite.', timestamp: 'Yesterday', icon: <UserPlus className="size-4" />, read: true },
10
+ { id: '4', title: 'PR merged', description: 'fix: onboarding wizard pending state (#479)', timestamp: '2d ago', icon: <GitPullRequest className="size-4" />, read: true },
11
+ ];
12
+
13
+ export default function Demo() {
14
+ const [notifications, setNotifications] = React.useState(initial);
15
+
16
+ return (
17
+ <div className="flex min-h-[420px] items-start justify-end p-8">
18
+ <NotificationsPopover
19
+ notifications={notifications}
20
+ onMarkAllRead={() => setNotifications((prev) => prev.map((n) => ({ ...n, read: true })))}
21
+ onNotificationClick={(clicked) =>
22
+ setNotifications((prev) => prev.map((n) => (n.id === clicked.id ? { ...n, read: true } : n)))
23
+ }
24
+ />
25
+ </div>
26
+ );
27
+ }
@@ -0,0 +1,44 @@
1
+ 'use client';
2
+ import { notify } from '@olwiba/ui';
3
+ import { Button, Toaster } from '@olwiba/cn';
4
+
5
+ export default function Demo() {
6
+ return (
7
+ <div className="flex flex-wrap items-center justify-center gap-3 p-8">
8
+ <Button
9
+ variant="outline"
10
+ onClick={() => notify({ variant: 'success', title: 'Deploy complete', description: 'nexus-genesis is live on production.' })}
11
+ >
12
+ Success toast
13
+ </Button>
14
+ <Button
15
+ variant="outline"
16
+ onClick={() =>
17
+ notify({
18
+ variant: 'message',
19
+ title: 'New comment',
20
+ description: 'Left a note on your latest deploy.',
21
+ action: { label: 'Reply', onClick: () => {} },
22
+ })
23
+ }
24
+ >
25
+ Message toast
26
+ </Button>
27
+ <Button
28
+ variant="outline"
29
+ onClick={() =>
30
+ notify({
31
+ variant: 'info',
32
+ title: 'Build queued',
33
+ description: 'Your project will start building shortly.',
34
+ action: { label: 'Undo', onClick: () => {} },
35
+ secondaryAction: { label: 'Dismiss', onClick: () => {} },
36
+ })
37
+ }
38
+ >
39
+ Action toast
40
+ </Button>
41
+ <Toaster />
42
+ </div>
43
+ );
44
+ }
@@ -0,0 +1,51 @@
1
+ import { OlwibaUIProvider, useOlwibaUI } from '@olwiba/ui';
2
+ import * as React from 'react';
3
+
4
+ function DeviceInfo() {
5
+ const { isMobile } = useOlwibaUI();
6
+
7
+ return (
8
+ <div className="flex flex-col items-center gap-2 text-center">
9
+ <div className="rounded-lg bg-muted px-4 py-2 font-mono text-sm">
10
+ isMobile = <span className="text-primary">{String(isMobile)}</span>
11
+ </div>
12
+ <p className="text-xs text-muted-foreground">
13
+ {isMobile ? 'Rendering mobile layout' : 'Rendering desktop layout'}
14
+ </p>
15
+ </div>
16
+ );
17
+ }
18
+
19
+ export default function OlwibaUIContextDemo() {
20
+ const [isMobile, setIsMobile] = React.useState(false);
21
+
22
+ return (
23
+ <div className="flex flex-col items-center gap-4">
24
+ <OlwibaUIProvider isMobile={isMobile}>
25
+ <DeviceInfo />
26
+ </OlwibaUIProvider>
27
+ <div className="flex gap-2">
28
+ <button
29
+ onClick={() => setIsMobile(false)}
30
+ className={`rounded-md px-3 py-1.5 text-sm transition-colors ${
31
+ !isMobile
32
+ ? 'bg-primary text-primary-foreground'
33
+ : 'bg-muted text-muted-foreground hover:bg-muted/80'
34
+ }`}
35
+ >
36
+ Desktop
37
+ </button>
38
+ <button
39
+ onClick={() => setIsMobile(true)}
40
+ className={`rounded-md px-3 py-1.5 text-sm transition-colors ${
41
+ isMobile
42
+ ? 'bg-primary text-primary-foreground'
43
+ : 'bg-muted text-muted-foreground hover:bg-muted/80'
44
+ }`}
45
+ >
46
+ Mobile
47
+ </button>
48
+ </div>
49
+ </div>
50
+ );
51
+ }
@@ -0,0 +1,3 @@
1
+ export default function Demo() {
2
+ return <div className="p-8 text-muted-foreground text-sm">OnboardingBlock — coming soon</div>;
3
+ }
@@ -0,0 +1,43 @@
1
+ 'use client';
2
+ import * as React from 'react';
3
+ import { OnboardingWizard } from '@olwiba/ui';
4
+ import { Input } from '@olwiba/cn';
5
+
6
+ export default function Demo() {
7
+ const [workspaceName, setWorkspaceName] = React.useState('');
8
+ const [done, setDone] = React.useState(false);
9
+
10
+ if (done) {
11
+ return <p className="p-8 text-center text-sm text-muted-foreground">Workspace <strong>{workspaceName || 'Untitled'}</strong> is ready.</p>;
12
+ }
13
+
14
+ return (
15
+ <div className="mx-auto max-w-md p-8">
16
+ <OnboardingWizard
17
+ onComplete={() => setDone(true)}
18
+ steps={[
19
+ {
20
+ id: 'welcome',
21
+ title: 'Welcome to Nexus',
22
+ description: 'Let’s get your workspace set up in a couple of steps.',
23
+ content: <p className="text-sm text-muted-foreground">This will only take a minute.</p>,
24
+ },
25
+ {
26
+ id: 'workspace',
27
+ title: 'Name your workspace',
28
+ content: (
29
+ <Input value={workspaceName} onChange={(e) => setWorkspaceName(e.target.value)} placeholder="Acme Inc." />
30
+ ),
31
+ onNext: () => (workspaceName.trim() ? true : 'Give your workspace a name to continue.'),
32
+ },
33
+ {
34
+ id: 'invite',
35
+ title: 'Invite your team',
36
+ description: 'Optional — you can always invite people later.',
37
+ content: <Input placeholder="teammate@company.com" />,
38
+ },
39
+ ]}
40
+ />
41
+ </div>
42
+ );
43
+ }