@bailierich/booking-components 2.0.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 (83) hide show
  1. package/README.md +319 -0
  2. package/TENANT_DATA_INTEGRATION.md +402 -0
  3. package/TENANT_SETUP.md +316 -0
  4. package/components/BookingFlow/BookingFlow.tsx +790 -0
  5. package/components/BookingFlow/index.ts +5 -0
  6. package/components/BookingFlow/steps/AddonsSelection.tsx +118 -0
  7. package/components/BookingFlow/steps/Confirmation.tsx +185 -0
  8. package/components/BookingFlow/steps/ContactForm.tsx +292 -0
  9. package/components/BookingFlow/steps/CycleAwareDateSelection.tsx +277 -0
  10. package/components/BookingFlow/steps/DateSelection.tsx +473 -0
  11. package/components/BookingFlow/steps/ServiceSelection.tsx +315 -0
  12. package/components/BookingFlow/steps/TimeSelection.tsx +230 -0
  13. package/components/BookingFlow/steps/index.ts +10 -0
  14. package/components/BottomSheet/index.tsx +120 -0
  15. package/components/Forms/FormBlock.tsx +283 -0
  16. package/components/Forms/FormField.tsx +385 -0
  17. package/components/Forms/FormRenderer.tsx +216 -0
  18. package/components/Forms/FormValidation.ts +122 -0
  19. package/components/Forms/index.ts +4 -0
  20. package/components/HoldTimer/HoldTimer.tsx +266 -0
  21. package/components/HoldTimer/index.ts +2 -0
  22. package/components/SectionRenderer.tsx +558 -0
  23. package/components/Sections/About.tsx +145 -0
  24. package/components/Sections/BeforeAfter.tsx +81 -0
  25. package/components/Sections/BookingSection.tsx +76 -0
  26. package/components/Sections/Contact.tsx +103 -0
  27. package/components/Sections/FAQSection.tsx +239 -0
  28. package/components/Sections/FeatureContent.tsx +113 -0
  29. package/components/Sections/FeaturedLink.tsx +103 -0
  30. package/components/Sections/FixedInfoCard.tsx +189 -0
  31. package/components/Sections/Gallery.tsx +83 -0
  32. package/components/Sections/Header.tsx +78 -0
  33. package/components/Sections/Hero.tsx +178 -0
  34. package/components/Sections/ImageSection.tsx +147 -0
  35. package/components/Sections/InstagramFeed.tsx +38 -0
  36. package/components/Sections/LinkList.tsx +76 -0
  37. package/components/Sections/LocationMap.tsx +202 -0
  38. package/components/Sections/Logo.tsx +61 -0
  39. package/components/Sections/MinimalFooter.tsx +78 -0
  40. package/components/Sections/MinimalHeader.tsx +81 -0
  41. package/components/Sections/MinimalNavigation.tsx +63 -0
  42. package/components/Sections/Navbar.tsx +258 -0
  43. package/components/Sections/PricingTable.tsx +106 -0
  44. package/components/Sections/ScrollingTextDivider.tsx +138 -0
  45. package/components/Sections/ScrollingTextDivider.tsx.bak +138 -0
  46. package/components/Sections/ServicesPreview.tsx +129 -0
  47. package/components/Sections/SocialBar.tsx +177 -0
  48. package/components/Sections/Team.tsx +80 -0
  49. package/components/Sections/Testimonials.tsx +92 -0
  50. package/components/Sections/TextSection.tsx +116 -0
  51. package/components/Sections/VideoSection.tsx +178 -0
  52. package/components/Sections/index.ts +57 -0
  53. package/components/index.ts +21 -0
  54. package/dist/index-DAai7Glf.d.mts +474 -0
  55. package/dist/index-DAai7Glf.d.ts +474 -0
  56. package/dist/index.d.mts +1075 -0
  57. package/dist/index.d.ts +1075 -0
  58. package/dist/index.js +22 -0
  59. package/dist/index.js.map +1 -0
  60. package/dist/index.mjs +22 -0
  61. package/dist/index.mjs.map +1 -0
  62. package/dist/styles/index.d.mts +1 -0
  63. package/dist/styles/index.d.ts +1 -0
  64. package/dist/styles/index.js +2 -0
  65. package/dist/styles/index.js.map +1 -0
  66. package/dist/styles/index.mjs +2 -0
  67. package/dist/styles/index.mjs.map +1 -0
  68. package/docs/API.md +849 -0
  69. package/docs/CALLBACKS.md +760 -0
  70. package/docs/COMPLETE_SESSION_SUMMARY.md +404 -0
  71. package/docs/DATA_SHAPES.md +684 -0
  72. package/docs/MIGRATION.md +662 -0
  73. package/docs/PAYMENT_INTEGRATION.md +766 -0
  74. package/docs/SESSION_SUMMARY.md +185 -0
  75. package/docs/STYLING.md +735 -0
  76. package/index.ts +4 -0
  77. package/lib/storage.ts +239 -0
  78. package/package.json +59 -0
  79. package/styles/animations.ts +210 -0
  80. package/styles/index.ts +1 -0
  81. package/tsconfig.json +32 -0
  82. package/tsup.config.ts +13 -0
  83. package/types/index.ts +369 -0
@@ -0,0 +1,735 @@
1
+ # Styling & Theme Customization
2
+
3
+ Complete guide to customizing the appearance of `@oviah/booking-components`.
4
+
5
+ ## Table of Contents
6
+
7
+ - [Theme Configuration](#theme-configuration)
8
+ - [Color Schemes](#color-schemes)
9
+ - [Typography](#typography)
10
+ - [Custom CSS](#custom-css)
11
+ - [Animations](#animations)
12
+ - [Responsive Design](#responsive-design)
13
+ - [Dark Mode](#dark-mode)
14
+ - [Best Practices](#best-practices)
15
+
16
+ ---
17
+
18
+ ## Theme Configuration
19
+
20
+ ### Basic Theme Setup
21
+
22
+ All components accept `colors` and `typography` props for theming:
23
+
24
+ ```tsx
25
+ const theme = {
26
+ colors: {
27
+ primary: '#D8C4FF',
28
+ secondary: '#014421',
29
+ text: '#000000',
30
+ bookingText: '#1A1A1A',
31
+ linkBackground: '#D8C4FF',
32
+ linkText: '#FFFFFF',
33
+ buttonText: '#FFFFFF'
34
+ },
35
+ typography: {
36
+ headingFont: 'Geist Sans',
37
+ bodyFont: 'Inter',
38
+ bodySize: '16px'
39
+ }
40
+ };
41
+
42
+ // Use with any component
43
+ <Hero
44
+ headline="Welcome"
45
+ colors={theme.colors}
46
+ typography={theme.typography}
47
+ />
48
+ ```
49
+
50
+ ### Global Theme Provider (Recommended)
51
+
52
+ Create a theme context to avoid prop drilling:
53
+
54
+ ```tsx
55
+ // contexts/ThemeContext.tsx
56
+ import { createContext, useContext } from 'react';
57
+
58
+ interface Theme {
59
+ colors: ColorScheme;
60
+ typography: TypographyConfig;
61
+ }
62
+
63
+ const ThemeContext = createContext<Theme | null>(null);
64
+
65
+ export function ThemeProvider({ children, theme }: { children: React.ReactNode; theme: Theme }) {
66
+ return (
67
+ <ThemeContext.Provider value={theme}>
68
+ {children}
69
+ </ThemeContext.Provider>
70
+ );
71
+ }
72
+
73
+ export function useTheme() {
74
+ const theme = useContext(ThemeContext);
75
+ if (!theme) throw new Error('useTheme must be used within ThemeProvider');
76
+ return theme;
77
+ }
78
+
79
+ // Usage
80
+ <ThemeProvider theme={theme}>
81
+ <BookingFlow config={config} colors={theme.colors} />
82
+ </ThemeProvider>
83
+ ```
84
+
85
+ ---
86
+
87
+ ## Color Schemes
88
+
89
+ ### Primary Colors
90
+
91
+ Define your brand's main colors:
92
+
93
+ ```typescript
94
+ interface ColorScheme {
95
+ primary: string; // Main brand color
96
+ secondary: string; // Secondary/accent color
97
+ text: string; // Main text color
98
+ }
99
+ ```
100
+
101
+ **Examples:**
102
+
103
+ ```tsx
104
+ // Purple & Green (Default OVIAH theme)
105
+ const oviahTheme = {
106
+ primary: '#D8C4FF',
107
+ secondary: '#014421',
108
+ text: '#000000'
109
+ };
110
+
111
+ // Blue & Orange
112
+ const blueOrangeTheme = {
113
+ primary: '#3B82F6',
114
+ secondary: '#F97316',
115
+ text: '#1F2937'
116
+ };
117
+
118
+ // Pink & Teal
119
+ const pinkTealTheme = {
120
+ primary: '#EC4899',
121
+ secondary: '#14B8A6',
122
+ text: '#111827'
123
+ };
124
+
125
+ // Monochrome
126
+ const monochromeTheme = {
127
+ primary: '#000000',
128
+ secondary: '#6B7280',
129
+ text: '#111827'
130
+ };
131
+ ```
132
+
133
+ ### Extended Colors
134
+
135
+ Additional colors for specific use cases:
136
+
137
+ ```typescript
138
+ interface ExtendedColorScheme extends ColorScheme {
139
+ bookingText?: string; // Text color in booking widget
140
+ linkBackground?: string; // Link button background
141
+ linkText?: string; // Link button text
142
+ buttonText?: string; // Button text color
143
+ }
144
+ ```
145
+
146
+ **Example:**
147
+
148
+ ```tsx
149
+ const extendedTheme = {
150
+ primary: '#D8C4FF',
151
+ secondary: '#014421',
152
+ text: '#000000',
153
+ bookingText: '#1A1A1A', // Slightly softer than pure black
154
+ linkBackground: '#D8C4FF', // Same as primary
155
+ linkText: '#FFFFFF', // White text on colored buttons
156
+ buttonText: '#FFFFFF' // White text on primary buttons
157
+ };
158
+ ```
159
+
160
+ ### Color Utilities
161
+
162
+ Helper functions for color manipulation:
163
+
164
+ ```typescript
165
+ // Convert hex to RGBA
166
+ function hexToRgba(hex: string, alpha: number): string {
167
+ const r = parseInt(hex.slice(1, 3), 16);
168
+ const g = parseInt(hex.slice(3, 5), 16);
169
+ const b = parseInt(hex.slice(5, 7), 16);
170
+ return `rgba(${r}, ${g}, ${b}, ${alpha})`;
171
+ }
172
+
173
+ // Usage
174
+ const transparentPrimary = hexToRgba(colors.primary, 0.1);
175
+ ```
176
+
177
+ ```typescript
178
+ // Get contrast color (black or white) for backgrounds
179
+ function getContrastColor(hexColor: string): string {
180
+ const hex = hexColor.replace('#', '');
181
+ const r = parseInt(hex.substr(0, 2), 16);
182
+ const g = parseInt(hex.substr(2, 2), 16);
183
+ const b = parseInt(hex.substr(4, 2), 16);
184
+ const luminance = (0.299 * r + 0.587 * g + 0.114 * b) / 255;
185
+ return luminance > 0.5 ? '#000000' : '#FFFFFF';
186
+ }
187
+
188
+ // Usage
189
+ const textColor = getContrastColor(colors.primary);
190
+ ```
191
+
192
+ ---
193
+
194
+ ## Typography
195
+
196
+ ### Font Configuration
197
+
198
+ ```typescript
199
+ interface TypographyConfig {
200
+ headingFont?: string; // Font family for headings
201
+ bodyFont?: string; // Font family for body text
202
+ bodySize?: string; // Base font size
203
+ }
204
+ ```
205
+
206
+ ### Loading Custom Fonts
207
+
208
+ #### Using Google Fonts (Next.js)
209
+
210
+ ```tsx
211
+ // app/layout.tsx
212
+ import { Geist_Sans, Inter } from 'next/font/google';
213
+
214
+ const geistSans = Geist_Sans({
215
+ subsets: ['latin'],
216
+ variable: '--font-geist-sans'
217
+ });
218
+
219
+ const inter = Inter({
220
+ subsets: ['latin'],
221
+ variable: '--font-inter'
222
+ });
223
+
224
+ export default function RootLayout({ children }: { children: React.ReactNode }) {
225
+ return (
226
+ <html lang="en" className={`${geistSans.variable} ${inter.variable}`}>
227
+ <body>{children}</body>
228
+ </html>
229
+ );
230
+ }
231
+
232
+ // Use in theme
233
+ const theme = {
234
+ typography: {
235
+ headingFont: 'var(--font-geist-sans)',
236
+ bodyFont: 'var(--font-inter)',
237
+ bodySize: '16px'
238
+ }
239
+ };
240
+ ```
241
+
242
+ #### Using Custom Fonts
243
+
244
+ ```css
245
+ /* globals.css */
246
+ @font-face {
247
+ font-family: 'MyCustomFont';
248
+ src: url('/fonts/MyCustomFont.woff2') format('woff2');
249
+ font-weight: normal;
250
+ font-style: normal;
251
+ }
252
+
253
+ @font-face {
254
+ font-family: 'MyCustomFont';
255
+ src: url('/fonts/MyCustomFont-Bold.woff2') format('woff2');
256
+ font-weight: bold;
257
+ font-style: normal;
258
+ }
259
+ ```
260
+
261
+ ```tsx
262
+ const theme = {
263
+ typography: {
264
+ headingFont: 'MyCustomFont',
265
+ bodyFont: 'system-ui',
266
+ bodySize: '16px'
267
+ }
268
+ };
269
+ ```
270
+
271
+ ### Font Size Scale
272
+
273
+ Recommended font sizes for different screen sizes:
274
+
275
+ ```tsx
276
+ const fontSizes = {
277
+ mobile: {
278
+ xs: '12px',
279
+ sm: '14px',
280
+ base: '16px',
281
+ lg: '18px',
282
+ xl: '20px',
283
+ '2xl': '24px',
284
+ '3xl': '30px'
285
+ },
286
+ tablet: {
287
+ xs: '12px',
288
+ sm: '14px',
289
+ base: '16px',
290
+ lg: '18px',
291
+ xl: '22px',
292
+ '2xl': '28px',
293
+ '3xl': '36px'
294
+ },
295
+ desktop: {
296
+ xs: '12px',
297
+ sm: '14px',
298
+ base: '16px',
299
+ lg: '20px',
300
+ xl: '24px',
301
+ '2xl': '32px',
302
+ '3xl': '48px'
303
+ }
304
+ };
305
+ ```
306
+
307
+ ---
308
+
309
+ ## Custom CSS
310
+
311
+ ### Overriding Component Styles
312
+
313
+ Use CSS custom properties (CSS variables) for easy overrides:
314
+
315
+ ```css
316
+ /* globals.css */
317
+ :root {
318
+ /* Override component spacing */
319
+ --booking-padding: 1.5rem;
320
+ --booking-gap: 1rem;
321
+
322
+ /* Override component sizes */
323
+ --button-height: 44px;
324
+ --input-height: 48px;
325
+
326
+ /* Override borders */
327
+ --border-radius: 12px;
328
+ --border-width: 2px;
329
+
330
+ /* Override shadows */
331
+ --shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.05);
332
+ --shadow-md: 0 4px 6px rgba(0, 0, 0, 0.1);
333
+ --shadow-lg: 0 10px 15px rgba(0, 0, 0, 0.15);
334
+ }
335
+ ```
336
+
337
+ ### Custom Wrapper Styles
338
+
339
+ Wrap components with custom styling:
340
+
341
+ ```tsx
342
+ <div className="custom-booking-wrapper">
343
+ <BookingFlow
344
+ config={config}
345
+ colors={colors}
346
+ />
347
+ </div>
348
+
349
+ <style jsx>{`
350
+ .custom-booking-wrapper {
351
+ max-width: 800px;
352
+ margin: 0 auto;
353
+ padding: 2rem;
354
+ background: linear-gradient(135deg, #f5f5f5 0%, #ffffff 100%);
355
+ border-radius: 24px;
356
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.1);
357
+ }
358
+
359
+ @media (max-width: 768px) {
360
+ .custom-booking-wrapper {
361
+ padding: 1rem;
362
+ border-radius: 16px;
363
+ }
364
+ }
365
+ `}</style>
366
+ ```
367
+
368
+ ### Tailwind CSS Integration
369
+
370
+ If using Tailwind CSS:
371
+
372
+ ```tsx
373
+ <div className="max-w-4xl mx-auto p-6 bg-gradient-to-br from-purple-50 to-green-50 rounded-3xl shadow-2xl">
374
+ <BookingFlow
375
+ config={config}
376
+ colors={{
377
+ primary: '#D8C4FF',
378
+ secondary: '#014421',
379
+ text: '#000000'
380
+ }}
381
+ />
382
+ </div>
383
+ ```
384
+
385
+ ---
386
+
387
+ ## Animations
388
+
389
+ ### Using Built-in Animations
390
+
391
+ ```tsx
392
+ import {
393
+ createEntranceAnimation,
394
+ createStaggerAnimation,
395
+ getSlideVariants,
396
+ getFadeVariants
397
+ } from '@oviah/booking-components/styles';
398
+
399
+ // Entrance animation
400
+ <motion.div {...createEntranceAnimation(0.2)}>
401
+ <Hero headline="Welcome" colors={colors} />
402
+ </motion.div>
403
+
404
+ // Stagger animation for lists
405
+ const staggerConfig = createStaggerAnimation(items.length, 0.1, 0.05);
406
+
407
+ {items.map((item, index) => (
408
+ <motion.div
409
+ key={item.id}
410
+ initial="hidden"
411
+ animate="visible"
412
+ variants={staggerConfig.variants}
413
+ transition={{ delay: staggerConfig.getDelay(index) }}
414
+ >
415
+ {item.content}
416
+ </motion.div>
417
+ ))}
418
+ ```
419
+
420
+ ### Custom Transition Speeds
421
+
422
+ Configure animation speeds in BookingFlow:
423
+
424
+ ```tsx
425
+ <BookingFlow
426
+ config={{
427
+ steps: { ... },
428
+ transitions: {
429
+ style: 'slide', // 'slide' | 'fade'
430
+ speed: 'fast' // 'fast' | 'normal' | 'slow'
431
+ }
432
+ }}
433
+ colors={colors}
434
+ />
435
+ ```
436
+
437
+ ### Respecting User Preferences
438
+
439
+ The components automatically respect `prefers-reduced-motion`:
440
+
441
+ ```tsx
442
+ // This is handled internally
443
+ const reducedMotion = window.matchMedia('(prefers-reduced-motion: reduce)').matches;
444
+ const duration = reducedMotion ? 0.15 : 0.3;
445
+ ```
446
+
447
+ ---
448
+
449
+ ## Responsive Design
450
+
451
+ ### Breakpoints
452
+
453
+ Components use these breakpoints:
454
+
455
+ ```typescript
456
+ const breakpoints = {
457
+ sm: '640px', // Mobile landscape
458
+ md: '768px', // Tablet
459
+ lg: '1024px', // Desktop
460
+ xl: '1280px', // Large desktop
461
+ '2xl': '1536px' // Extra large
462
+ };
463
+ ```
464
+
465
+ ### Responsive Layouts
466
+
467
+ #### Service Selection
468
+
469
+ ```tsx
470
+ <ServiceSelection
471
+ settings={{
472
+ serviceLayout: 'grid',
473
+ columns: 2 // 1 col on mobile, 2 on tablet+
474
+ }}
475
+ colors={colors}
476
+ />
477
+ ```
478
+
479
+ #### Gallery
480
+
481
+ ```tsx
482
+ <Gallery
483
+ columns={3} // Responsive: 2 cols on mobile, 3 on tablet+
484
+ images={images}
485
+ colors={colors}
486
+ />
487
+ ```
488
+
489
+ ### Mobile-First Considerations
490
+
491
+ ```css
492
+ /* Mobile-first approach */
493
+ .booking-container {
494
+ padding: 1rem;
495
+ font-size: 14px;
496
+ }
497
+
498
+ @media (min-width: 768px) {
499
+ .booking-container {
500
+ padding: 2rem;
501
+ font-size: 16px;
502
+ }
503
+ }
504
+
505
+ @media (min-width: 1024px) {
506
+ .booking-container {
507
+ padding: 3rem;
508
+ font-size: 18px;
509
+ }
510
+ }
511
+ ```
512
+
513
+ ---
514
+
515
+ ## Dark Mode
516
+
517
+ ### Implementing Dark Mode
518
+
519
+ ```tsx
520
+ 'use client';
521
+
522
+ import { useState, useEffect } from 'react';
523
+
524
+ function useDarkMode() {
525
+ const [isDark, setIsDark] = useState(false);
526
+
527
+ useEffect(() => {
528
+ const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
529
+ setIsDark(mediaQuery.matches);
530
+
531
+ const handler = (e: MediaQueryListEvent) => setIsDark(e.matches);
532
+ mediaQuery.addEventListener('change', handler);
533
+ return () => mediaQuery.removeEventListener('change', handler);
534
+ }, []);
535
+
536
+ return isDark;
537
+ }
538
+
539
+ // Usage
540
+ export function BookingWithDarkMode() {
541
+ const isDark = useDarkMode();
542
+
543
+ const lightTheme = {
544
+ colors: {
545
+ primary: '#D8C4FF',
546
+ secondary: '#014421',
547
+ text: '#000000',
548
+ bookingText: '#1A1A1A'
549
+ }
550
+ };
551
+
552
+ const darkTheme = {
553
+ colors: {
554
+ primary: '#B8A4DF',
555
+ secondary: '#02652F',
556
+ text: '#FFFFFF',
557
+ bookingText: '#E5E5E5'
558
+ }
559
+ };
560
+
561
+ const theme = isDark ? darkTheme : lightTheme;
562
+
563
+ return (
564
+ <div style={{
565
+ backgroundColor: isDark ? '#1A1A1A' : '#FFFFFF',
566
+ minHeight: '100vh'
567
+ }}>
568
+ <BookingFlow
569
+ config={config}
570
+ colors={theme.colors}
571
+ />
572
+ </div>
573
+ );
574
+ }
575
+ ```
576
+
577
+ ### Dark Mode Color Palettes
578
+
579
+ ```typescript
580
+ const themes = {
581
+ light: {
582
+ colors: {
583
+ primary: '#D8C4FF',
584
+ secondary: '#014421',
585
+ text: '#000000',
586
+ background: '#FFFFFF',
587
+ surface: '#F9FAFB'
588
+ }
589
+ },
590
+ dark: {
591
+ colors: {
592
+ primary: '#B8A4DF',
593
+ secondary: '#02652F',
594
+ text: '#FFFFFF',
595
+ background: '#1A1A1A',
596
+ surface: '#2D2D2D'
597
+ }
598
+ }
599
+ };
600
+ ```
601
+
602
+ ---
603
+
604
+ ## Best Practices
605
+
606
+ ### 1. Use CSS Variables for Consistency
607
+
608
+ ```css
609
+ :root {
610
+ --primary-color: #D8C4FF;
611
+ --secondary-color: #014421;
612
+ --text-color: #000000;
613
+ --spacing-sm: 0.5rem;
614
+ --spacing-md: 1rem;
615
+ --spacing-lg: 2rem;
616
+ }
617
+ ```
618
+
619
+ ### 2. Maintain WCAG Contrast Ratios
620
+
621
+ ```tsx
622
+ // Ensure sufficient contrast (minimum 4.5:1 for normal text)
623
+ const colors = {
624
+ primary: '#D8C4FF',
625
+ text: '#000000' // Good contrast against white backgrounds
626
+ };
627
+
628
+ // For text on colored backgrounds
629
+ const buttonStyles = {
630
+ backgroundColor: colors.primary,
631
+ color: getContrastColor(colors.primary) // Automatically white or black
632
+ };
633
+ ```
634
+
635
+ ### 3. Test on Multiple Devices
636
+
637
+ ```tsx
638
+ // Use responsive testing
639
+ const testSizes = {
640
+ mobile: '375px',
641
+ tablet: '768px',
642
+ desktop: '1440px'
643
+ };
644
+ ```
645
+
646
+ ### 4. Keep Brand Consistency
647
+
648
+ ```tsx
649
+ // Create a brand constants file
650
+ export const BRAND_COLORS = {
651
+ primary: '#D8C4FF',
652
+ secondary: '#014421',
653
+ accent: '#FF6F61'
654
+ } as const;
655
+
656
+ export const BRAND_FONTS = {
657
+ heading: 'Geist Sans',
658
+ body: 'Inter'
659
+ } as const;
660
+
661
+ // Use throughout your app
662
+ <BookingFlow
663
+ config={config}
664
+ colors={BRAND_COLORS}
665
+ />
666
+ ```
667
+
668
+ ### 5. Optimize for Performance
669
+
670
+ ```tsx
671
+ // Lazy load heavy components
672
+ import dynamic from 'next/dynamic';
673
+
674
+ const BookingFlow = dynamic(
675
+ () => import('@oviah/booking-components').then(mod => mod.BookingFlow),
676
+ { ssr: false }
677
+ );
678
+ ```
679
+
680
+ ---
681
+
682
+ ## Example: Complete Custom Theme
683
+
684
+ ```tsx
685
+ // theme.ts
686
+ export const customTheme = {
687
+ colors: {
688
+ primary: '#8B5CF6', // Violet
689
+ secondary: '#10B981', // Emerald
690
+ text: '#111827', // Gray 900
691
+ bookingText: '#374151', // Gray 700
692
+ linkBackground: '#8B5CF6',
693
+ linkText: '#FFFFFF',
694
+ buttonText: '#FFFFFF'
695
+ },
696
+ typography: {
697
+ headingFont: 'Poppins',
698
+ bodyFont: 'Inter',
699
+ bodySize: '16px'
700
+ },
701
+ spacing: {
702
+ container: '1.5rem',
703
+ section: '4rem',
704
+ element: '1rem'
705
+ },
706
+ borderRadius: {
707
+ sm: '8px',
708
+ md: '12px',
709
+ lg: '16px',
710
+ full: '9999px'
711
+ },
712
+ shadows: {
713
+ sm: '0 1px 2px rgba(0, 0, 0, 0.05)',
714
+ md: '0 4px 6px rgba(0, 0, 0, 0.1)',
715
+ lg: '0 10px 15px rgba(0, 0, 0, 0.15)',
716
+ xl: '0 20px 25px rgba(0, 0, 0, 0.15)'
717
+ }
718
+ };
719
+
720
+ // Use throughout your app
721
+ <ThemeProvider theme={customTheme}>
722
+ <BookingFlow
723
+ config={config}
724
+ colors={customTheme.colors}
725
+ />
726
+ </ThemeProvider>
727
+ ```
728
+
729
+ ---
730
+
731
+ ## See Also
732
+
733
+ - [DATA_SHAPES.md](./DATA_SHAPES.md) - Data structures
734
+ - [API.md](./API.md) - Component API reference
735
+ - [CALLBACKS.md](./CALLBACKS.md) - Event handling
package/index.ts ADDED
@@ -0,0 +1,4 @@
1
+ // Main package exports
2
+ export * from './components';
3
+ export * from './types';
4
+ export * from './styles';