@gymmymac/bob-widget 2.0.0 → 3.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 (36) hide show
  1. package/README.md +20 -4
  2. package/dist/BobProvider.d.ts +6 -0
  3. package/dist/components/BobSuggestions.d.ts +15 -0
  4. package/dist/components/ChatInterface.d.ts +3 -0
  5. package/dist/components/MatrixProductLoader.d.ts +14 -0
  6. package/dist/components/ProductBadge.d.ts +15 -0
  7. package/dist/components/ProductTile.d.ts +20 -0
  8. package/dist/components/SparkDealBanner.d.ts +14 -0
  9. package/dist/components/SwipeableBob.d.ts +24 -0
  10. package/dist/components/mobile/ContainedChatDrawer.d.ts +2 -2
  11. package/dist/components/mobile/MobileBobCharacter.d.ts +12 -1
  12. package/dist/components/mobile/MobileBobLayoutCore.d.ts +39 -0
  13. package/dist/components/mobile/MobileChatDrawer.d.ts +3 -0
  14. package/dist/components/mobile/MobileProductColumn.d.ts +1 -0
  15. package/dist/components/mobile/ServicePackageDetailView.d.ts +31 -0
  16. package/dist/components/mobile/index.d.ts +2 -0
  17. package/dist/hooks/useBobAnimation.d.ts +12 -2
  18. package/dist/hooks/useBobAnimationData.d.ts +1 -0
  19. package/dist/hooks/useBobStateTransitions.d.ts +2 -0
  20. package/dist/hooks/usePositionFactors.d.ts +28 -0
  21. package/dist/hooks/useReturningUser.d.ts +10 -0
  22. package/dist/hooks/useSparkDeals.d.ts +27 -0
  23. package/dist/hooks/useSpeechSynthesis.d.ts +2 -1
  24. package/dist/hooks/useThemeSettings.d.ts +22 -0
  25. package/dist/hooks/useViewportSize.d.ts +2 -0
  26. package/dist/index.d.ts +15 -3
  27. package/dist/index.js +35 -13
  28. package/dist/index.mjs +5443 -2991
  29. package/dist/style.css +1 -1
  30. package/dist/styles/carfix-tokens.d.ts +166 -0
  31. package/dist/styles/glass.d.ts +49 -0
  32. package/dist/types/index.d.ts +1 -1
  33. package/dist/types/message.d.ts +6 -3
  34. package/dist/types/product.d.ts +96 -9
  35. package/dist/utils/debug.d.ts +23 -0
  36. package/package.json +2 -2
package/README.md CHANGED
@@ -2,6 +2,18 @@
2
2
 
3
3
  AI-powered automotive parts assistant widget for integration into partner websites.
4
4
 
5
+ **v3.0.0** - Major release with multi-tenant support, RAF animations, swipeable Bob, and enhanced mobile experience.
6
+
7
+ ## What's New in v3.0.0
8
+
9
+ - 🎭 **SwipeableBob**: Gesture-based interactions - swipe Bob away or back into view
10
+ - 🏢 **Multi-Tenant Support**: Configurable looks and animations per tenant
11
+ - 🎬 **RAF Animations**: Smooth 60fps animations using requestAnimationFrame
12
+ - ⚡ **MatrixProductLoader**: Cyberpunk-style loading with phased states
13
+ - 🔥 **SparkDealBanner**: Animated promotional banners
14
+ - 👋 **Returning User Detection**: Personalized greetings for repeat visitors
15
+ - 🎨 **Theme Settings**: Dynamic theme configuration from database
16
+
5
17
  ## Installation
6
18
 
7
19
  ```bash
@@ -84,13 +96,13 @@ Or programmatically:
84
96
  ```tsx
85
97
  import { BOB_VERSION, getBobVersion } from '@gymmymac/bob-widget';
86
98
 
87
- console.log(`Bob Widget Version: ${getBobVersion()}`); // e.g., "1.1.4"
99
+ console.log(`Bob Widget Version: ${getBobVersion()}`); // "3.0.0"
88
100
  ```
89
101
 
90
102
  Check the console for startup logs:
91
103
  ```
92
- [BobWidget] Package loaded - v1.1.4
93
- [BobWidget] v1.1.4 initialized
104
+ [BobWidget] Package loaded - v3.0.0
105
+ [BobWidget] v3.0.0 initialized
94
106
  [BobWidget] QueryClient: internal
95
107
  ```
96
108
 
@@ -211,10 +223,14 @@ function App() {
211
223
 
212
224
  ## Dependencies
213
225
 
214
- Bob Widget v1.1.4+ bundles its own dependencies. You only need:
226
+ Bob Widget v3.0.0+ bundles its own dependencies. You only need:
215
227
  - `react` ^18.0.0
216
228
  - `react-dom` ^18.0.0
217
229
 
230
+ ## Changelog
231
+
232
+ See [CHANGELOG.md](./CHANGELOG.md) for version history.
233
+
218
234
  ## Integration Guide
219
235
 
220
236
  For detailed integration instructions, see [CARFIX-INTEGRATION.md](./CARFIX-INTEGRATION.md).
@@ -93,6 +93,12 @@ export declare function useBobContext(): BobContextValue;
93
93
  * Hook to access Bob's Supabase client
94
94
  */
95
95
  export declare function useBobSupabase(): SupabaseClient;
96
+ /**
97
+ * Hook to safely access Bob's Supabase client
98
+ * Returns null instead of throwing when used outside BobProvider
99
+ * Use this in widget components that need to work without BobProvider
100
+ */
101
+ export declare function useBobSupabaseSafe(): SupabaseClient | null;
96
102
  /**
97
103
  * Hook to access host context
98
104
  */
@@ -0,0 +1,15 @@
1
+ import { default as React } from 'react';
2
+ import { Product } from '../types/product';
3
+
4
+ interface BobSuggestionsProps {
5
+ products: Product[];
6
+ title?: string;
7
+ onProductClick?: (product: Product) => void;
8
+ onAddToCart?: (product: Product) => void;
9
+ }
10
+ /**
11
+ * Displays products Bob is actively recommending - styled to match CARFIX website.
12
+ * Rendered inline within chat messages when Bob presents specific products.
13
+ */
14
+ export declare const BobSuggestions: React.FC<BobSuggestionsProps>;
15
+ export default BobSuggestions;
@@ -1,5 +1,6 @@
1
1
  import { default as React } from 'react';
2
2
  import { Message } from '../types/message';
3
+ import { Product } from '../types/product';
3
4
 
4
5
  interface ChatInterfaceProps {
5
6
  messages: Message[];
@@ -15,6 +16,8 @@ interface ChatInterfaceProps {
15
16
  onToggleMute?: () => void;
16
17
  isSpeaking?: boolean;
17
18
  className?: string;
19
+ onAddToCart?: (product: Product) => void;
20
+ onProductClick?: (product: Product) => void;
18
21
  }
19
22
  export declare const ChatInterface: React.FC<ChatInterfaceProps>;
20
23
  export {};
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ import { SparkDeal } from '../hooks/useSparkDeals';
3
+
4
+ export type LoaderPhase = 'hidden' | 'researching' | 'loading' | 'success';
5
+ interface MatrixProductLoaderProps {
6
+ phase: LoaderPhase;
7
+ message?: string;
8
+ onComplete?: () => void;
9
+ onSparkDealClick?: (deal: SparkDeal) => void;
10
+ /** Optional product/brand names for subliminal messaging */
11
+ subliminalBrands?: string[];
12
+ }
13
+ export declare const MatrixProductLoader: React.FC<MatrixProductLoaderProps>;
14
+ export default MatrixProductLoader;
@@ -0,0 +1,15 @@
1
+ import { default as React } from 'react';
2
+ import { BADGE_CONFIG } from '../styles/carfix-tokens';
3
+
4
+ type BadgeType = keyof typeof BADGE_CONFIG;
5
+ interface ProductBadgeProps {
6
+ type: BadgeType;
7
+ value?: string;
8
+ className?: string;
9
+ }
10
+ /**
11
+ * Consistent badge component for product attributes
12
+ * Matches CARFIX website styling exactly
13
+ */
14
+ export declare const ProductBadge: React.FC<ProductBadgeProps>;
15
+ export default ProductBadge;
@@ -0,0 +1,20 @@
1
+ import { default as React } from 'react';
2
+ import { Product } from '../types';
3
+
4
+ interface ProductTileProps {
5
+ product: Product;
6
+ isSpotlighted?: boolean;
7
+ onProductClick?: (product: Product) => void;
8
+ onAddToCart?: (product: Product) => void;
9
+ }
10
+ /**
11
+ * ProductTile - Premium Glassmorphism Product Cards
12
+ *
13
+ * iOS 26-inspired liquid glass design:
14
+ * - Frosted translucent glass with backdrop blur
15
+ * - Sharp white text with high contrast
16
+ * - CARFIX orange price highlights
17
+ * - Hover: scale(1.04), translateY(-4px), enhanced glow
18
+ */
19
+ export declare const ProductTile: React.FC<ProductTileProps>;
20
+ export {};
@@ -0,0 +1,14 @@
1
+ import { default as React } from 'react';
2
+ import { SparkDeal } from '../hooks/useSparkDeals';
3
+ import { MatrixTheme } from '../hooks/useThemeSettings';
4
+
5
+ interface SparkDealBannerProps {
6
+ deals: SparkDeal[];
7
+ currentDealIndex: number;
8
+ onDealChange: (index: number) => void;
9
+ onDealClick: (deal: SparkDeal) => void;
10
+ scrollSpeed: number;
11
+ theme: Partial<MatrixTheme>;
12
+ }
13
+ export declare const SparkDealBanner: React.FC<SparkDealBannerProps>;
14
+ export default SparkDealBanner;
@@ -0,0 +1,24 @@
1
+ import { default as React } from 'react';
2
+ import { BobPosition } from './mobile/MobileBobCharacter';
3
+
4
+ interface SwipeableBobProps {
5
+ children: React.ReactNode;
6
+ isSpeaking?: boolean;
7
+ hasProducts?: boolean;
8
+ onVisibilityChange?: (visible: boolean) => void;
9
+ onPositionChange?: (position: BobPosition) => void;
10
+ currentPosition?: BobPosition;
11
+ }
12
+ /**
13
+ * SwipeableBob - Phase 2: Swipeable Bob Overlay with 3-Position System
14
+ *
15
+ * Features:
16
+ * - Swipe left to hide Bob (center → partial-left → hidden)
17
+ * - Swipe right to show Bob (hidden → partial-left → center)
18
+ * - Vertical "BOB" tab on left edge when hidden
19
+ * - Auto-reappear when TTS starts speaking
20
+ * - Auto-move to partial-left when products appear
21
+ * - Spring animation for slide in/out
22
+ */
23
+ export declare const SwipeableBob: React.FC<SwipeableBobProps>;
24
+ export {};
@@ -16,8 +16,8 @@ interface ContainedChatDrawerProps {
16
16
  isSpeaking?: boolean;
17
17
  }
18
18
  /**
19
- * ContainedChatDrawer - Chat drawer using absolute positioning
20
- * Stays within parent container bounds instead of viewport.
19
+ * ContainedChatDrawer - Premium Glassmorphism Chat Drawer
20
+ * iOS 26 liquid glass design with CARFIX branding
21
21
  */
22
22
  export declare const ContainedChatDrawer: React.FC<ContainedChatDrawerProps>;
23
23
  export {};
@@ -1,13 +1,24 @@
1
1
  import { default as React } from 'react';
2
2
 
3
+ export type BobPosition = 'center' | 'partial-left' | 'hidden';
3
4
  interface MobileBobCharacterProps {
4
5
  currentImage: string;
5
6
  animationState: string;
6
7
  counterOverlayUrl?: string;
7
8
  counterHeightPercent?: number;
8
9
  scale?: number;
9
- position?: 'center' | 'left';
10
+ position?: BobPosition;
10
11
  verticalOffset?: number;
12
+ /** Theatrical entrance - controls fade-in opacity */
13
+ hasArrived?: boolean;
11
14
  }
15
+ /**
16
+ * MobileBobCharacter - Bob with 3-position system
17
+ *
18
+ * Positions:
19
+ * - center: Bob centered on screen (welcome/idle state)
20
+ * - partial-left: Bob slides left, ~30% visible (products displayed)
21
+ * - hidden: Bob fully off-screen left (user swiped, full product view)
22
+ */
12
23
  export declare const MobileBobCharacter: React.FC<MobileBobCharacterProps>;
13
24
  export {};
@@ -0,0 +1,39 @@
1
+ import { default as React } from 'react';
2
+ import { BobPosition } from './MobileBobCharacter';
3
+ import { Product, ServicePackage } from '../../types';
4
+ import { HighlightedProduct } from '../../types/message';
5
+ import { Vehicle } from '../../types/vehicle';
6
+
7
+ interface MobileBobLayoutCoreProps {
8
+ currentImage: string;
9
+ animationState: string;
10
+ backdropUrl?: string;
11
+ counterOverlayUrl?: string;
12
+ counterHeightPercent?: number;
13
+ products: Product[];
14
+ servicePackages: ServicePackage[];
15
+ highlightedPartType?: string | null;
16
+ highlightedProduct?: HighlightedProduct | null;
17
+ onProductClick?: (product: Product) => void;
18
+ onPackageSelect?: (pkg: ServicePackage) => void;
19
+ isResearching?: boolean;
20
+ onAddToCart?: (product: Product) => void;
21
+ onNavigateToProductPage?: (product: Product) => void;
22
+ vehicle?: Vehicle | null;
23
+ onChangeVehicle?: () => void;
24
+ bobOffset?: number;
25
+ bobScale?: number;
26
+ bobHasArrived?: boolean;
27
+ externalBobPosition?: BobPosition;
28
+ onBobPositionChange?: (position: BobPosition) => void;
29
+ }
30
+ /**
31
+ * MobileBobLayoutCore - Bob character, backdrop, and products with 3-position system.
32
+ *
33
+ * Bob Positions:
34
+ * - center: Welcome/idle state, no products
35
+ * - partial-left: Products visible, Bob partially off-screen
36
+ * - hidden: User swiped, full product view
37
+ */
38
+ export declare const MobileBobLayoutCore: React.FC<MobileBobLayoutCoreProps>;
39
+ export {};
@@ -1,5 +1,6 @@
1
1
  import { default as React } from 'react';
2
2
  import { Message } from '../../types/message';
3
+ import { Product } from '../../types/product';
3
4
 
4
5
  interface MobileChatDrawerProps {
5
6
  messages: Message[];
@@ -14,6 +15,8 @@ interface MobileChatDrawerProps {
14
15
  isMuted?: boolean;
15
16
  onToggleMute?: () => void;
16
17
  isSpeaking?: boolean;
18
+ onAddToCart?: (product: Product) => void;
19
+ onProductClick?: (product: Product) => void;
17
20
  }
18
21
  export declare const MobileChatDrawer: React.FC<MobileChatDrawerProps>;
19
22
  export {};
@@ -13,6 +13,7 @@ interface MobileProductColumnProps {
13
13
  visible?: boolean;
14
14
  counterHeightPercent?: number;
15
15
  hasVehicle?: boolean;
16
+ onAddToCart?: (product: Product | Product[]) => void;
16
17
  }
17
18
  export declare const MobileProductColumn: React.FC<MobileProductColumnProps>;
18
19
  export {};
@@ -0,0 +1,31 @@
1
+ import { default as React } from 'react';
2
+ import { PreparedTier, PreparedTierProduct } from '../../types/product';
3
+
4
+ /**
5
+ * Service package interface - preparedTiers is the ONLY source of truth
6
+ */
7
+ interface ServicePackageDetail {
8
+ id: string;
9
+ title: string;
10
+ description: string;
11
+ from_price: number;
12
+ estimated_time?: string;
13
+ difficulty_level?: string;
14
+ bundle_discount_percentage?: number;
15
+ carfixValueProducts?: string[];
16
+ preparedTiers?: PreparedTier[];
17
+ icon_url?: string;
18
+ }
19
+ interface ServicePackageDetailViewProps {
20
+ package: ServicePackageDetail;
21
+ onBack: () => void;
22
+ onAddToCart?: (products: PreparedTierProduct[]) => void;
23
+ onNavigateToProductPage?: (sku: string) => void;
24
+ }
25
+ /**
26
+ * ServicePackageDetailView - CARFIX Website Specification
27
+ * Uses preparedTiers EXCLUSIVELY - no client-side fallback processing
28
+ * Server is the single source of truth for products, prices, and tiers
29
+ */
30
+ export declare const ServicePackageDetailView: React.FC<ServicePackageDetailViewProps>;
31
+ export {};
@@ -1,7 +1,9 @@
1
1
  export { MobileBobCharacter } from './MobileBobCharacter';
2
+ export { MobileBobLayoutCore } from './MobileBobLayoutCore';
2
3
  export { MobileChatDrawer } from './MobileChatDrawer';
3
4
  export { MobileProductColumn } from './MobileProductColumn';
4
5
  export { MobileBobLayout } from './MobileBobLayout';
5
6
  export { ContainedMobileBobLayout } from './ContainedMobileBobLayout';
6
7
  export { ContainedChatDrawer } from './ContainedChatDrawer';
7
8
  export { ProductDetailView } from './ProductDetailView';
9
+ export { ServicePackageDetailView } from './ServicePackageDetailView';
@@ -1,7 +1,16 @@
1
1
  export type AnimationState = string;
2
- export declare const useBobAnimation: () => {
2
+ interface UseBobAnimationOptions {
3
+ isSpeaking?: boolean;
4
+ }
5
+ /**
6
+ * Bob Animation Hook - v3.0 requestAnimationFrame Implementation
7
+ *
8
+ * FIXES: Animation acceleration bug caused by setInterval stacking
9
+ * SOLUTION: Single RAF loop with refs for mutable state
10
+ */
11
+ export declare const useBobAnimation: (options?: UseBobAnimationOptions) => {
3
12
  animationState: string;
4
- setAnimationState: import('react').Dispatch<import('react').SetStateAction<string>>;
13
+ setAnimationState: (newState: AnimationState) => void;
5
14
  getCurrentImage: () => string;
6
15
  getCurrentOffset: () => number;
7
16
  getCurrentScale: () => number;
@@ -12,3 +21,4 @@ export declare const useBobAnimation: () => {
12
21
  setManualMode: import('react').Dispatch<import('react').SetStateAction<boolean>>;
13
22
  isLoading: boolean;
14
23
  };
24
+ export {};
@@ -45,6 +45,7 @@ export interface BobAnimationData {
45
45
  * Centralized React Query hook for Bob's animation data.
46
46
  * Fetches once, caches for 30 seconds, deduplicates requests across components.
47
47
  * Includes realtime subscriptions for automatic updates.
48
+ * Gracefully degrades when used outside BobProvider.
48
49
  */
49
50
  export declare const useBobAnimationData: (lookId?: string | null) => import('@tanstack/react-query').UseQueryResult<BobAnimationData, Error>;
50
51
  /**
@@ -10,6 +10,8 @@ export declare const useBobStateTransitions: ({ states, setAnimationState, manua
10
10
  chatStage: ChatStage;
11
11
  initialize: () => void;
12
12
  onUserInput: () => void;
13
+ onSpeechStart: () => void;
14
+ onSpeechEnd: () => void;
13
15
  onStreamStart: () => void;
14
16
  onStreamComplete: () => void;
15
17
  onShowingProduct: () => void;
@@ -0,0 +1,28 @@
1
+ import { ViewportSize } from './useViewportSize';
2
+
3
+ /**
4
+ * Position factors for responsive Bob positioning and UI scaling.
5
+ * These factors allow fine-tuned control across mobile, tablet, and desktop.
6
+ */
7
+ export interface PositionFactors {
8
+ /** Multiplier for Bob's position offsets (1.0 = full offset, 0.5 = half) */
9
+ bobOffset: number;
10
+ /** Multiplier for product column width (1.0 = 80%, 0.6 = 48%) */
11
+ productWidth: number;
12
+ /** General UI element scaling factor */
13
+ uiScale: number;
14
+ /** Bob's partial-left position (percentage from left edge) */
15
+ partialLeftPosition: number;
16
+ /** Bob's hidden position (percentage from left edge) */
17
+ hiddenPosition: number;
18
+ }
19
+ /**
20
+ * Returns device-specific position factors for consistent Bob positioning
21
+ * across mobile, tablet, and desktop viewports.
22
+ */
23
+ export declare function usePositionFactors(): PositionFactors;
24
+ /**
25
+ * Get position factors for a specific viewport size.
26
+ * Can be used directly if viewport is known.
27
+ */
28
+ export declare function getPositionFactors(viewport: ViewportSize): PositionFactors;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Hook to detect returning users within a configurable time window.
3
+ * Stores last visit timestamp in localStorage and checks if user
4
+ * has visited within the threshold period.
5
+ */
6
+ export declare function useReturningUser(thresholdDays?: number): {
7
+ isReturningUser: boolean;
8
+ lastVisitDate: Date | null;
9
+ daysSinceLastVisit: number | null;
10
+ };
@@ -0,0 +1,27 @@
1
+ export interface SparkDeal {
2
+ id: string;
3
+ brand: string;
4
+ product_name: string;
5
+ price: number;
6
+ original_price?: number;
7
+ image_url?: string;
8
+ sku: string;
9
+ category?: string;
10
+ valid_until?: string;
11
+ }
12
+ interface SparkDealsSettings {
13
+ enabled: boolean;
14
+ inRain: boolean;
15
+ rainFrequency: number;
16
+ primingEnabled: boolean;
17
+ bannerEnabled: boolean;
18
+ delayMs: number;
19
+ scrollSpeed: number;
20
+ maxPerSession: number;
21
+ minResearchTime: number;
22
+ bobCommentary: boolean;
23
+ }
24
+ export declare function useSparkDealsSettings(): import('@tanstack/react-query').UseQueryResult<SparkDealsSettings, Error>;
25
+ export declare function useSparkDeals(enabled?: boolean): import('@tanstack/react-query').UseQueryResult<SparkDeal[], Error>;
26
+ export declare function getSparkDealWords(deals: SparkDeal[]): string[];
27
+ export {};
@@ -4,11 +4,12 @@ interface UseSpeechSynthesisProps {
4
4
  onFailed?: () => void;
5
5
  }
6
6
  export declare const useSpeechSynthesis: ({ onStart, onEnd, onFailed, }?: UseSpeechSynthesisProps) => {
7
- speak: (text: string) => Promise<void>;
7
+ speak: (text: string, isGreeting?: boolean) => void;
8
8
  stop: () => void;
9
9
  pause: () => void;
10
10
  resume: () => void;
11
11
  isSpeaking: boolean;
12
12
  isSupported: boolean;
13
+ retryPendingGreeting: () => void;
13
14
  };
14
15
  export {};
@@ -0,0 +1,22 @@
1
+ export interface ThemeSetting {
2
+ id: string;
3
+ setting_key: string;
4
+ color_value: string;
5
+ hex_preview: string | null;
6
+ description: string | null;
7
+ }
8
+ export interface MatrixTheme {
9
+ primary: string;
10
+ secondary: string;
11
+ success: string;
12
+ background: string;
13
+ backgroundMode: 'dark' | 'light';
14
+ sparkDealColor: string;
15
+ primaryHex: string;
16
+ secondaryHex: string;
17
+ successHex: string;
18
+ backgroundHex: string;
19
+ sparkDealHex: string;
20
+ }
21
+ export declare function useThemeSettings(): import('@tanstack/react-query').UseQueryResult<MatrixTheme, Error>;
22
+ export declare function getThemeCssVars(theme: MatrixTheme): Record<string, string>;
@@ -0,0 +1,2 @@
1
+ export type ViewportSize = 'mobile' | 'tablet' | 'desktop';
2
+ export declare function useViewportSize(): ViewportSize;
package/dist/index.d.ts CHANGED
@@ -3,19 +3,28 @@
3
3
  *
4
4
  * AI-powered automotive parts assistant widget - Full immersive experience
5
5
  *
6
+ * v3.0.0 - Major rebuild with multi-tenant support, RAF animations, swipeable Bob
6
7
  * v1.4.0 - Redesigned PTT button: 3x larger, green "TALK" text, floating cartoon style
7
8
  * v1.3.1 - Bottom offset support for host navigation bars
8
9
  * v1.3.0 - GA4 Analytics integration
9
10
  */
10
11
  export { BOB_VERSION, getBobVersion } from './version';
11
- export { BobProvider, useBobContext, useBobSupabase, useHostContext, useHostApiConfig, useBobCallbacks, useBobAnalyticsConfig, useBobAnalytics, useBobLayoutConfig, } from './BobProvider';
12
+ export { BobProvider, useBobContext, useBobSupabase, useBobSupabaseSafe, useHostContext, useHostApiConfig, useBobCallbacks, useBobAnalyticsConfig, useBobAnalytics, useBobLayoutConfig, } from './BobProvider';
12
13
  export { BobWidget } from './components/BobWidget';
13
14
  export type { BobWidgetProps } from './components/BobWidget';
14
15
  export { Bob } from './components/Bob';
15
16
  export type { BobVariant } from './components/Bob';
16
17
  export { BobCharacter } from './components/BobCharacter';
17
18
  export { ChatInterface } from './components/ChatInterface';
18
- export { MobileBobCharacter, MobileChatDrawer, MobileProductColumn, MobileBobLayout, ContainedMobileBobLayout, ContainedChatDrawer } from './components/mobile';
19
+ export { BobSuggestions } from './components/BobSuggestions';
20
+ export { ProductBadge } from './components/ProductBadge';
21
+ export { CARFIX_COLORS, QUALITY_TIER_CONFIG, IMAGE_URLS, BADGE_CONFIG, TYPOGRAPHY, isRotorProduct, getDisplayPrice, formatNZD, } from './styles/carfix-tokens';
22
+ export { SwipeableBob } from './components/SwipeableBob';
23
+ export { ProductTile } from './components/ProductTile';
24
+ export { MatrixProductLoader } from './components/MatrixProductLoader';
25
+ export type { LoaderPhase } from './components/MatrixProductLoader';
26
+ export { SparkDealBanner } from './components/SparkDealBanner';
27
+ export { MobileBobCharacter, MobileChatDrawer, MobileProductColumn, MobileBobLayout, MobileBobLayoutCore, ContainedMobileBobLayout, ContainedChatDrawer, ServicePackageDetailView } from './components/mobile';
19
28
  export { useBobChat } from './hooks/useBobChat';
20
29
  export { useSpeechSynthesis } from './hooks/useSpeechSynthesis';
21
30
  export { useBobAnimation } from './hooks/useBobAnimation';
@@ -23,9 +32,12 @@ export { useBobAnimationData } from './hooks/useBobAnimationData';
23
32
  export { useBobStateTransitions } from './hooks/useBobStateTransitions';
24
33
  export { useSpeechRecognition } from './hooks/useSpeechRecognition';
25
34
  export { useBobBackdrop } from './hooks/useBobBackdrop';
35
+ export { useThemeSettings } from './hooks/useThemeSettings';
36
+ export { useSparkDeals } from './hooks/useSparkDeals';
37
+ export { useReturningUser } from './hooks/useReturningUser';
26
38
  export type { HostContext, HostUserContext, HostVehicleContext, HostCartContext, HostHistoryContext, BobConfig, HostApiConfig, BobCallbacks, BobProviderConfig, BobLayoutConfig, } from './types/context';
27
39
  export type { Vehicle } from './types/vehicle';
28
- export type { Product, APIPart, CartItem, ServicePackage, } from './types/product';
40
+ export type { Product, APIPart, CartItem, ServicePackage, Partslot, QualityTiers, Part, } from './types/product';
29
41
  export type { Message, HighlightedProduct, } from './types/message';
30
42
  export type { BobAnimationConfig, AnimationStateDefinition, BobLook, BobAnimationData, } from './hooks/useBobAnimationData';
31
43
  export type { BobEventName, BobAnalyticsEvent, BobGA4Config, SessionStartParams, MessageSentParams, VehicleIdentifiedParams, PartsViewedParams, ProductParams, CheckoutParams, SpeechParams, ErrorParams, } from './types/analytics';