@botuyo/chat-widget-standalone 1.0.60 → 1.0.62

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 (42) hide show
  1. package/LICENSE +21 -21
  2. package/README.md +302 -323
  3. package/dist/Avatar3D-LfNJe183.js.map +1 -1
  4. package/dist/botuyo-chat.es.js +35 -36
  5. package/dist/botuyo-chat.es.js.map +1 -1
  6. package/dist/botuyo-chat.umd.js +1 -1
  7. package/dist/botuyo-chat.umd.js.map +1 -1
  8. package/dist/{chunk-audio-CjO94O6M.js → chunk-audio-Cam9NjvU.js} +2 -2
  9. package/dist/chunk-audio-Cam9NjvU.js.map +1 -0
  10. package/dist/{chunk-chat-ui-D94hKAOR.js → chunk-chat-ui-VGFEt16R.js} +32 -32
  11. package/dist/chunk-chat-ui-VGFEt16R.js.map +1 -0
  12. package/dist/{chunk-gallery-54UV-aGf.js → chunk-gallery-DPka8_Y7.js} +2 -2
  13. package/dist/chunk-gallery-DPka8_Y7.js.map +1 -0
  14. package/dist/src/chat-widget/ChatWidget.d.ts.map +1 -1
  15. package/dist/src/chat-widget/components/Gallery.stories.d.ts.map +1 -1
  16. package/dist/src/chat-widget/components/MessageBubble.d.ts.map +1 -1
  17. package/dist/src/chat-widget/components/MessageList.d.ts.map +1 -1
  18. package/dist/src/chat-widget/hooks/useChatSocket.d.ts.map +1 -1
  19. package/dist/src/chat-widget/hooks/useWidgetTheme.d.ts +1 -1
  20. package/dist/src/chat-widget/types/index.d.ts +20 -0
  21. package/dist/src/chat-widget/types/index.d.ts.map +1 -1
  22. package/dist/src/chat-widget/utils/theme.d.ts +4 -3
  23. package/dist/src/chat-widget/utils/theme.d.ts.map +1 -1
  24. package/dist/standalone.d.ts +6 -1
  25. package/dist/standalone.d.ts.map +1 -1
  26. package/dist/stats-umd.html +1 -1
  27. package/dist/stats.html +1 -1
  28. package/package.json +155 -155
  29. package/dist/ShadowChatWidget.d.ts +0 -25
  30. package/dist/ShadowChatWidget.d.ts.map +0 -1
  31. package/dist/chunk-audio-CjO94O6M.js.map +0 -1
  32. package/dist/chunk-chat-ui-D94hKAOR.js.map +0 -1
  33. package/dist/chunk-gallery-54UV-aGf.js.map +0 -1
  34. package/dist/src/chat-widget/utils/theme.examples.d.ts +0 -47
  35. package/dist/src/chat-widget/utils/theme.examples.d.ts.map +0 -1
  36. package/dist/src/chat-widget/utils/themes/index.d.ts +0 -12
  37. package/dist/src/chat-widget/utils/themes/index.d.ts.map +0 -1
  38. package/examples/cdn-example.html +0 -226
  39. package/examples/nextjs-example.js +0 -188
  40. package/examples/nextjs-example.tsx +0 -229
  41. package/examples/react-example.js +0 -168
  42. package/examples/react-example.tsx +0 -221
@@ -1 +0,0 @@
1
- {"version":3,"file":"chunk-gallery-54UV-aGf.js","sources":["../src/chat-widget/components/Gallery.tsx"],"sourcesContent":["/**\r\n * @package @botuyo/chat-widget\r\n * Gallery - Componente visual para mostrar galerías de imágenes\r\n */\r\n\r\n'use client'\r\n\r\nimport { useState, memo, useRef, useEffect } from 'react'\r\nimport { useTranslations } from '@/chat-widget/i18n'\r\nimport { ChevronLeft, ChevronRight, X, ZoomIn } from './Icons'\r\nimport { cn } from '@/lib/utils'\r\n\r\ninterface GalleryProps {\r\n images: Array<{ src: string; alt?: string }>\r\n radius?: string\r\n}\r\n\r\nexport type { GalleryProps }\r\n\r\nexport const Gallery = memo(function Gallery({ images, radius = 'rounded-lg' }: GalleryProps) {\r\n const { t } = useTranslations('extracted')\r\n const [currentIndex, setCurrentIndex] = useState(0)\r\n const [isLightboxOpen, setIsLightboxOpen] = useState(false)\r\n\r\n const nextImage = () => {\r\n setCurrentIndex(prev => (prev + 1) % images.length)\r\n }\r\n\r\n const prevImage = () => {\r\n setCurrentIndex(prev => (prev - 1 + images.length) % images.length)\r\n }\r\n\r\n const openLightbox = (index: number) => {\r\n setCurrentIndex(index)\r\n setIsLightboxOpen(true)\r\n }\r\n\r\n const [imageError, setImageError] = useState<Set<number>>(new Set())\r\n\r\n const handleImageError = (index: number) => {\r\n setImageError(prev => new Set(prev).add(index))\r\n }\r\n\r\n // Si solo hay 1 imagen, mostrar como imagen simple\r\n if (images.length === 1) {\r\n return (\r\n <div className=\"my-3 relative group\">\r\n {imageError.has(0) ? (\r\n <div\r\n className={cn(\r\n 'w-full h-48 flex flex-col items-center justify-center',\r\n 'border bg-muted text-muted-foreground',\r\n radius\r\n )}\r\n style={{ borderColor: 'hsl(var(--border))' }}\r\n >\r\n <svg\r\n className=\"w-12 h-12 mb-2 opacity-50\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\r\n />\r\n </svg>\r\n <span className=\"text-sm\">Imagen no disponible</span>\r\n </div>\r\n ) : (\r\n <>\r\n <img\r\n src={images[0].src}\r\n alt={images[0].alt || 'Imagen'}\r\n className={cn(\r\n 'w-full h-auto object-cover cursor-pointer transition-all duration-300',\r\n 'border shadow-soft-md hover:shadow-soft-lg hover:scale-[1.02]',\r\n radius\r\n )}\r\n style={{ borderColor: 'hsl(var(--border))' }}\r\n loading=\"lazy\"\r\n onClick={() => openLightbox(0)}\r\n onError={() => handleImageError(0)}\r\n />\r\n <div className=\"absolute top-2 right-2 bg-black/50 backdrop-blur-sm p-1.5 rounded-full opacity-0 group-hover:opacity-100 transition-opacity\">\r\n <ZoomIn size={16} className=\"text-white\" />\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n )\r\n }\r\n\r\n // Si hay 2-3 imágenes, mostrar grid horizontal\r\n if (images.length <= 3) {\r\n return (\r\n <div className={cn('my-3 grid gap-2', images.length === 2 ? 'grid-cols-2' : 'grid-cols-3')}>\r\n {images.map((img, idx) => (\r\n <div key={idx} className=\"relative group overflow-hidden\">\r\n {imageError.has(idx) ? (\r\n <div\r\n className={cn(\r\n 'w-full h-32 flex flex-col items-center justify-center',\r\n 'border bg-muted text-muted-foreground',\r\n radius\r\n )}\r\n >\r\n <svg\r\n className=\"w-8 h-8 opacity-50\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\r\n />\r\n </svg>\r\n </div>\r\n ) : (\r\n <>\r\n <img\r\n src={img.src}\r\n alt={img.alt || `Imagen ${idx + 1}`}\r\n className={cn(\r\n 'w-full h-32 object-cover cursor-pointer transition-all duration-300',\r\n 'border border-border shadow-soft-md hover:shadow-soft-lg hover:scale-110',\r\n radius\r\n )}\r\n loading=\"lazy\"\r\n onClick={() => openLightbox(idx)}\r\n onError={() => handleImageError(idx)}\r\n />\r\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/40 to-transparent opacity-0 group-hover:opacity-100 transition-opacity flex items-end justify-end p-2\">\r\n <span className=\"text-white text-xs font-bold bg-black/50 backdrop-blur-sm px-2 py-1 rounded-full\">\r\n {idx + 1}/{images.length}\r\n </span>\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n ))}\r\n\r\n {/* Lightbox */}\r\n {isLightboxOpen && (\r\n <Lightbox\r\n images={images}\r\n currentIndex={currentIndex}\r\n onClose={() => setIsLightboxOpen(false)}\r\n onNext={nextImage}\r\n onPrev={prevImage}\r\n />\r\n )}\r\n </div>\r\n )\r\n }\r\n\r\n // Si hay 4+ imágenes, mostrar carrusel con thumbnails\r\n return (\r\n <div className=\"my-3 space-y-2\">\r\n {/* Imagen Principal */}\r\n <div className=\"relative group\">\r\n {imageError.has(currentIndex) ? (\r\n <div\r\n className={cn(\r\n 'w-full h-56 flex flex-col items-center justify-center',\r\n 'border bg-muted text-muted-foreground',\r\n radius\r\n )}\r\n style={{ borderColor: 'hsl(var(--border))' }}\r\n >\r\n <svg\r\n className=\"w-12 h-12 mb-2 opacity-50\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\r\n />\r\n </svg>\r\n <span className=\"text-sm\">Imagen no disponible</span>\r\n </div>\r\n ) : (\r\n <>\r\n <img\r\n src={images[currentIndex].src}\r\n alt={images[currentIndex].alt || `Imagen ${currentIndex + 1}`}\r\n className={cn(\r\n 'w-full h-56 object-cover cursor-pointer transition-all duration-300',\r\n 'border shadow-soft-md',\r\n radius\r\n )}\r\n style={{ borderColor: 'hsl(var(--border))' }}\r\n loading=\"lazy\"\r\n onClick={() => openLightbox(currentIndex)}\r\n onError={() => handleImageError(currentIndex)}\r\n />\r\n\r\n {/* Overlay con controles */}\r\n <div className=\"absolute inset-0 bg-gradient-to-t from-black/60 via-transparent to-black/20 opacity-0 group-hover:opacity-100 transition-opacity flex items-center justify-between px-3\">\r\n <button\r\n onClick={prevImage}\r\n className=\"p-2 rounded-full shadow-soft-lg transition-all hover:scale-110 active:scale-95\"\r\n style={{\r\n backgroundColor: 'hsl(var(--card) / 0.9)',\r\n color: 'hsl(var(--foreground))',\r\n }}\r\n aria-label={t('anterior')}\r\n >\r\n <ChevronLeft size={20} />\r\n </button>\r\n <button\r\n onClick={nextImage}\r\n className=\"p-2 rounded-full shadow-soft-lg transition-all hover:scale-110 active:scale-95\"\r\n style={{\r\n backgroundColor: 'hsl(var(--card) / 0.9)',\r\n color: 'hsl(var(--foreground))',\r\n }}\r\n aria-label={t('siguiente')}\r\n >\r\n <ChevronRight size={20} />\r\n </button>\r\n </div>\r\n\r\n {/* Badge con contador */}\r\n <div className=\"absolute top-3 right-3 bg-black/70 backdrop-blur-sm px-3 py-1 rounded-full\">\r\n <span className=\"text-white text-xs font-bold\">\r\n {currentIndex + 1} / {images.length}\r\n </span>\r\n </div>\r\n\r\n {/* Icono de zoom */}\r\n <div className=\"absolute bottom-3 right-3 bg-black/70 backdrop-blur-sm p-2 rounded-full opacity-0 group-hover:opacity-100 transition-opacity\">\r\n <ZoomIn size={16} className=\"text-white\" />\r\n </div>\r\n </>\r\n )}\r\n </div>\r\n\r\n {/* Thumbnails */}\r\n <div className=\"flex gap-2 overflow-x-auto pb-2 scrollbar-thin scrollbar-thumb-border scrollbar-track-transparent\">\r\n {images.map((img, idx) => (\r\n <button\r\n key={idx}\r\n onClick={() => setCurrentIndex(idx)}\r\n className={cn(\r\n 'flex-shrink-0 w-16 h-16 overflow-hidden transition-all duration-300 relative',\r\n 'border-2 hover:scale-110',\r\n radius,\r\n currentIndex === idx\r\n ? 'border-[hsl(210,90%,50%)] ring-2 ring-[hsl(210,90%,50%)]/30 scale-105'\r\n : 'border-border hover:border-[hsl(210,90%,70%)] opacity-70 hover:opacity-100'\r\n )}\r\n >\r\n {imageError.has(idx) ? (\r\n <div className=\"w-full h-full flex items-center justify-center bg-muted\">\r\n <svg\r\n className=\"w-6 h-6 opacity-50\"\r\n fill=\"none\"\r\n stroke=\"currentColor\"\r\n viewBox=\"0 0 24 24\"\r\n >\r\n <path\r\n strokeLinecap=\"round\"\r\n strokeLinejoin=\"round\"\r\n strokeWidth={2}\r\n d=\"M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z\"\r\n />\r\n </svg>\r\n </div>\r\n ) : (\r\n <img\r\n src={img.src}\r\n alt={img.alt || `Thumbnail ${idx + 1}`}\r\n className=\"w-full h-full object-cover\"\r\n loading=\"lazy\"\r\n onError={() => handleImageError(idx)}\r\n />\r\n )}\r\n </button>\r\n ))}\r\n </div>\r\n\r\n {/* Lightbox */}\r\n {isLightboxOpen && (\r\n <Lightbox\r\n images={images}\r\n currentIndex={currentIndex}\r\n onClose={() => setIsLightboxOpen(false)}\r\n onNext={nextImage}\r\n onPrev={prevImage}\r\n />\r\n )}\r\n </div>\r\n )\r\n})\r\n\r\n// ==========================================\r\n// 🔍 LIGHTBOX (Modal de Imagen)\r\n// ==========================================\r\n\r\ninterface LightboxProps {\r\n images: Array<{ src: string; alt?: string }>\r\n currentIndex: number\r\n onClose: () => void\r\n onNext: () => void\r\n onPrev: () => void\r\n}\r\n\r\nfunction Lightbox({ images, currentIndex, onClose, onNext, onPrev }: LightboxProps) {\r\n const { t } = useTranslations('extracted')\r\n\r\n // Keyboard navigation\r\n useEffect(() => {\r\n const handler = (e: KeyboardEvent) => {\r\n if (e.key === 'Escape') onClose()\r\n if (e.key === 'ArrowLeft') onPrev()\r\n if (e.key === 'ArrowRight') onNext()\r\n }\r\n window.addEventListener('keydown', handler)\r\n return () => window.removeEventListener('keydown', handler)\r\n }, [onClose, onPrev, onNext])\r\n\r\n // Touch swipe support\r\n const touchStartX = useRef(0)\r\n const handleTouchStart = (e: React.TouchEvent) => {\r\n touchStartX.current = e.touches[0].clientX\r\n }\r\n const handleTouchEnd = (e: React.TouchEvent) => {\r\n const dx = e.changedTouches[0].clientX - touchStartX.current\r\n if (Math.abs(dx) > 50) {\r\n if (dx > 0) { onPrev() } else { onNext() }\r\n }\r\n }\r\n\r\n return (\r\n <div\r\n className=\"absolute inset-0 z-[100000] bg-black/95 backdrop-blur-sm flex items-center justify-center animate-in fade-in duration-200\"\r\n onClick={onClose}\r\n onTouchStart={handleTouchStart}\r\n onTouchEnd={handleTouchEnd}\r\n >\r\n {/* Botón Cerrar */}\r\n <button\r\n onClick={onClose}\r\n className=\"absolute top-4 right-4 bg-white/10 hover:bg-white/20 p-2 rounded-full transition-all hover:scale-110 active:scale-95 z-10\"\r\n aria-label={t('cerrar')}\r\n >\r\n <X size={24} className=\"text-white\" />\r\n </button>\r\n\r\n {/* Contador */}\r\n <div className=\"absolute top-4 left-4 bg-white/10 backdrop-blur-sm px-4 py-2 rounded-full z-10\">\r\n <span className=\"text-white text-sm font-bold\">\r\n {currentIndex + 1} / {images.length}\r\n </span>\r\n </div>\r\n\r\n {/* Controles de Navegación */}\r\n {images.length > 1 && (\r\n <>\r\n <button\r\n onClick={e => {\r\n e.stopPropagation()\r\n onPrev()\r\n }}\r\n className=\"absolute left-4 bg-white/10 hover:bg-white/20 p-3 rounded-full transition-all hover:scale-110 active:scale-95 z-10\"\r\n aria-label=\"Anterior\"\r\n >\r\n <ChevronLeft size={32} className=\"text-white\" />\r\n </button>\r\n <button\r\n onClick={e => {\r\n e.stopPropagation()\r\n onNext()\r\n }}\r\n className=\"absolute right-4 bg-white/10 hover:bg-white/20 p-3 rounded-full transition-all hover:scale-110 active:scale-95 z-10\"\r\n aria-label=\"Siguiente\"\r\n >\r\n <ChevronRight size={32} className=\"text-white\" />\r\n </button>\r\n </>\r\n )}\r\n\r\n {/* Imagen */}\r\n <img\r\n src={images[currentIndex].src}\r\n alt={images[currentIndex].alt || `Imagen ${currentIndex + 1}`}\r\n className=\"max-w-[90%] max-h-[85%] object-contain\"\r\n onClick={e => e.stopPropagation()}\r\n />\r\n\r\n {/* Thumbnails strip */}\r\n {images.length > 1 && (\r\n <div className=\"absolute bottom-4 left-1/2 -translate-x-1/2 flex gap-2 bg-black/50 backdrop-blur-sm px-3 py-2 rounded-full z-10\">\r\n {images.map((_, idx) => (\r\n <button\r\n key={idx}\r\n onClick={e => {\r\n e.stopPropagation()\r\n // Navigate to this index — use repeated prev/next to reach\r\n const diff = idx - currentIndex\r\n if (diff > 0) for (let i = 0; i < diff; i++) onNext()\r\n if (diff < 0) for (let i = 0; i < Math.abs(diff); i++) onPrev()\r\n }}\r\n className={cn(\r\n 'w-2 h-2 rounded-full transition-all',\r\n idx === currentIndex ? 'bg-white scale-125' : 'bg-white/40 hover:bg-white/60'\r\n )}\r\n aria-label={`Imagen ${idx + 1}`}\r\n />\r\n ))}\r\n </div>\r\n )}\r\n </div>\r\n )\r\n}\r\n"],"names":["Gallery","memo","images","radius","t","useTranslations","currentIndex","setCurrentIndex","useState","isLightboxOpen","setIsLightboxOpen","nextImage","prev","length","prevImage","openLightbox","index","imageError","setImageError","Set","handleImageError","add","className","children","has","jsxs","cn","style","borderColor","jsx","fill","stroke","viewBox","strokeLinecap","strokeLinejoin","strokeWidth","d","Fragment","src","alt","loading","onClick","onError","ZoomIn","size","map","img","idx","Lightbox","onClose","onNext","onPrev","backgroundColor","color","ChevronLeft","ChevronRight","useEffect","handler","e","key","window","addEventListener","removeEventListener","touchStartX","useRef","onTouchStart","current","touches","clientX","onTouchEnd","dx","changedTouches","Math","abs","X","stopPropagation","_","diff","i"],"mappings":"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"}
@@ -1,47 +0,0 @@
1
- /**
2
- * Ejemplo de uso del Sistema de Temas
3
- *
4
- * Este archivo demuestra cómo usar los temas predefinidos,
5
- * crear temas personalizados y aplicarlos al widget.
6
- */
7
- declare const defaultTheme: Required<Omit<import("..").ChatTheme, "defaultLocale" | "avatars" | "emotion" | "starterPrompt" | "bubbleStyles" | "promptPersistence" | "avatarScale" | "showPromptAvatar" | "animations" | "effects" | "avatar3dUrl">>;
8
- declare const customSimpleTheme: {
9
- primaryColor: string;
10
- botName: string;
11
- cssVariables: {
12
- primary: string;
13
- };
14
- };
15
- declare const customFullTheme: {
16
- primaryColor: string;
17
- botName: string;
18
- logoUrl: string;
19
- position: "bottom-left";
20
- welcomeMessage: string;
21
- inputPlaceholder: string;
22
- cssVariables: {
23
- background: string;
24
- foreground: string;
25
- card: string;
26
- cardForeground: string;
27
- primary: string;
28
- primaryForeground: string;
29
- muted: string;
30
- mutedForeground: string;
31
- border: string;
32
- destructive: string;
33
- radius: string;
34
- };
35
- };
36
- export declare const mergedTheme: Required<Omit<import("..").ChatTheme, "defaultLocale" | "avatars" | "emotion" | "starterPrompt" | "bubbleStyles" | "promptPersistence" | "avatarScale" | "showPromptAvatar" | "animations" | "effects" | "avatar3dUrl">>;
37
- export declare const myComponent: {
38
- backgroundColor: string;
39
- color: string;
40
- borderColor: string;
41
- };
42
- export declare const containerStyle: {
43
- backgroundColor: string;
44
- };
45
- export declare function MyApp(): boolean;
46
- export { defaultTheme, customSimpleTheme, customFullTheme, };
47
- //# sourceMappingURL=theme.examples.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"theme.examples.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/utils/theme.examples.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAuBH,QAAA,MAAM,YAAY,0NAAgB,CAAA;AA6BlC,QAAA,MAAM,iBAAiB;;;;;;CAOtB,CAAA;AAGD,QAAA,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;CAoBpB,CAAA;AAiBD,eAAO,MAAM,WAAW,0NAAoC,CAAA;AAmB5D,eAAO,MAAM,WAAW;;;;CAIvB,CAAA;AAkBD,eAAO,MAAM,cAAc;;CAG1B,CAAA;AAyBD,wBAAgB,KAAK,YAcpB;AAuFD,OAAO,EAEL,YAAY,EAMZ,iBAAiB,EACjB,eAAe,GAEhB,CAAA"}
@@ -1,12 +0,0 @@
1
- /**
2
- * @package @botuyo/chat-widget
3
- * Exportaciones centrales del sistema de temas
4
- *
5
- * Importa desde aquí todo lo relacionado con temas:
6
- * import { DEFAULT_THEME, getSolidStyles, mergeThemeWithDefaults } from './utils/themes'
7
- */
8
- export type { CSSVariables } from '../theme';
9
- export { DEFAULT_CSS_VARIABLES, DARK_CSS_VARIABLES } from '../theme';
10
- export { DEFAULT_THEME, } from '../theme';
11
- export { mergeThemeWithDefaults, getPrimaryColor, cssVariablesToInlineStyles, getSolidStyles, } from '../theme';
12
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../../src/chat-widget/utils/themes/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAA;AAG5C,OAAO,EAAE,qBAAqB,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAGpE,OAAO,EACL,aAAa,GAId,MAAM,UAAU,CAAA;AAGjB,OAAO,EACL,sBAAsB,EACtB,eAAe,EACf,0BAA0B,EAC1B,cAAc,GACf,MAAM,UAAU,CAAA"}
@@ -1,226 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="es">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>Ejemplo CDN - BotUyo Chat Widget</title>
7
- <style>
8
- * {
9
- margin: 0;
10
- padding: 0;
11
- box-sizing: border-box;
12
- }
13
-
14
- body {
15
- font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, sans-serif;
16
- background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
17
- min-height: 100vh;
18
- display: flex;
19
- align-items: center;
20
- justify-content: center;
21
- padding: 20px;
22
- }
23
-
24
- .container {
25
- background: white;
26
- padding: 40px;
27
- border-radius: 20px;
28
- box-shadow: 0 20px 60px rgba(0, 0, 0, 0.3);
29
- max-width: 600px;
30
- width: 100%;
31
- }
32
-
33
- h1 {
34
- color: #333;
35
- margin-bottom: 10px;
36
- }
37
-
38
- p {
39
- color: #666;
40
- margin-bottom: 30px;
41
- line-height: 1.6;
42
- }
43
-
44
- .button-group {
45
- display: flex;
46
- gap: 10px;
47
- flex-wrap: wrap;
48
- }
49
-
50
- button {
51
- background: #10b981;
52
- color: white;
53
- border: none;
54
- padding: 12px 24px;
55
- border-radius: 8px;
56
- cursor: pointer;
57
- font-size: 14px;
58
- font-weight: 600;
59
- transition: all 0.3s ease;
60
- }
61
-
62
- button:hover {
63
- background: #059669;
64
- transform: translateY(-2px);
65
- box-shadow: 0 5px 15px rgba(16, 185, 129, 0.4);
66
- }
67
-
68
- button:active {
69
- transform: translateY(0);
70
- }
71
-
72
- .status {
73
- margin-top: 20px;
74
- padding: 15px;
75
- background: #f3f4f6;
76
- border-radius: 8px;
77
- font-size: 14px;
78
- color: #666;
79
- }
80
-
81
- .status strong {
82
- color: #10b981;
83
- }
84
-
85
- code {
86
- background: #f3f4f6;
87
- padding: 2px 6px;
88
- border-radius: 4px;
89
- font-family: 'Courier New', monospace;
90
- font-size: 13px;
91
- }
92
- </style>
93
- </head>
94
- <body>
95
- <div class="container">
96
- <h1>🎉 Ejemplo CDN del Chat Widget</h1>
97
- <p>
98
- Este es un ejemplo de integración del <strong>BotUyo Chat Widget</strong> usando CDN.
99
- No requiere React, Next.js ni ningún framework - solo JavaScript vanilla.
100
- </p>
101
-
102
- <div class="button-group">
103
- <button onclick="if(widget) widget.open()">🚀 Abrir Chat</button>
104
- <button onclick="if(widget) widget.close()">❌ Cerrar Chat</button>
105
- <button onclick="if(widget) widget.toggle()">🔄 Toggle Chat</button>
106
- <button onclick="sendTestMessage()">💬 Enviar Mensaje</button>
107
- <button onclick="showState()">📊 Ver Estado</button>
108
- </div>
109
-
110
- <div class="status" id="status">
111
- <strong>Estado:</strong> Inicializando widget...
112
- </div>
113
-
114
- <div style="margin-top: 30px; padding-top: 30px; border-top: 1px solid #e5e7eb;">
115
- <h3 style="color: #666; margin-bottom: 10px;">Código de integración:</h3>
116
- <pre style="background: #1f2937; color: #10b981; padding: 15px; border-radius: 8px; overflow-x: auto; font-size: 12px;"><code>&lt;script src="https://cdn.botuyo.com/chat-widget.js"&gt;&lt;/script&gt;
117
- &lt;script&gt;
118
- const widget = BotUyoChat.init({
119
- apiKey: 'demo-api-key',
120
- apiBaseUrl: 'https://api.botuyo.com',
121
- theme: {
122
- primaryColor: '#10b981',
123
- botName: 'Demo Bot',
124
- position: 'bottom-right'
125
- }
126
- });
127
- &lt;/script&gt;</code></pre>
128
- </div>
129
- </div>
130
-
131
- <!-- IMPORTANTE: Cargar el script del widget -->
132
- <!-- En producción, usar: https://cdn.botuyo.com/chat-widget.js -->
133
- <script src="../dist/botuyo-chat.js"></script>
134
-
135
- <script>
136
- // Esperar a que el script esté cargado
137
- let widget;
138
-
139
- // Inicializar el widget cuando BotUyoChat esté disponible
140
- window.addEventListener('DOMContentLoaded', () => {
141
- if (window.BotUyoChat) {
142
- widget = window.BotUyoChat.init({
143
- apiKey: 'demo-api-key-12345',
144
- apiBaseUrl: 'https://api.botuyo.com', // Cambiar por tu API real
145
-
146
- theme: {
147
- primaryColor: '#10b981',
148
- botName: 'Demo Assistant',
149
- position: 'bottom-right',
150
- welcomeMessage: '¡Hola! 👋 Soy el asistente de demo. ¿En qué puedo ayudarte?',
151
- inputPlaceholder: 'Escribe tu mensaje aquí...',
152
- starterPrompt: '¿Necesitas ayuda? 💬',
153
- borderRadius: '1rem',
154
- launcherBorderRadius: '50%'
155
- },
156
-
157
- pageContext: {
158
- page: 'Demo CDN',
159
- url: window.location.href,
160
- title: document.title,
161
- demo: true
162
- },
163
-
164
- onStateChange: (isOpen) => {
165
- updateStatus(`Chat ${isOpen ? 'abierto' : 'cerrado'}`);
166
- console.log('Estado del chat:', isOpen);
167
- },
168
-
169
- onNavigate: (url) => {
170
- console.log('Navegación solicitada a:', url);
171
- alert(`El bot solicita navegar a: ${url}`);
172
- },
173
-
174
- onLogin: (userData) => {
175
- console.log('Usuario autenticado:', userData);
176
- updateStatus('Usuario autenticado correctamente');
177
- },
178
-
179
- onEvent: (eventName, data) => {
180
- console.log('Evento:', eventName, data);
181
- }
182
- });
183
-
184
- // Actualizar estado inicial cuando el widget esté listo
185
- setTimeout(() => {
186
- updateStatus('Widget listo para usar ✅');
187
- }, 1000);
188
- } else {
189
- updateStatus('❌ Error: BotUyoChat no está disponible. Verifica que el script esté cargado.');
190
- }
191
- });
192
- // Funciones auxiliares
193
- function updateStatus(message) {
194
- const statusEl = document.getElementById('status');
195
- statusEl.innerHTML = `<strong>Estado:</strong> ${message}`;
196
- }
197
-
198
- function sendTestMessage() {
199
- if (!widget) {
200
- alert('Widget no está inicializado');
201
- return;
202
- }
203
- widget.sendMessage('Este es un mensaje de prueba enviado programáticamente 🎯');
204
- widget.open();
205
- updateStatus('Mensaje enviado programáticamente');
206
- }
207
-
208
- function showState() {
209
- if (!widget) {
210
- alert('Widget no está inicializado');
211
- return;
212
- }
213
- const state = widget.getState();
214
- alert(JSON.stringify(state, null, 2));
215
- updateStatus('Estado mostrado en consola');
216
- console.log('Estado del widget:', state);
217
- }
218
-
219
- // Ejemplo de actualización dinámica del tema
220
- setTimeout(() => {
221
- console.log('💡 Tip: Puedes actualizar el tema en cualquier momento:');
222
- console.log('widget.update({ theme: { primaryColor: "#8b5cf6" } })');
223
- }, 3000);
224
- </script>
225
- </body>
226
- </html>
@@ -1,188 +0,0 @@
1
- "use strict";
2
- // @ts-nocheck
3
- /**
4
- * Ejemplo de uso del Chat Widget en Next.js 13+ (App Router)
5
- * Con TypeScript, Server Components y Client Components
6
- *
7
- * ⚠️ NOTA: Este archivo contiene MÚLTIPLES EJEMPLOS de código en secciones separadas.
8
- * NO está diseñado para ejecutarse directamente - es un archivo de REFERENCIA.
9
- * Copia las secciones individuales que necesites a tus propios archivos.
10
- *
11
- * Los errores de "Duplicate identifier" son esperados porque hay múltiples
12
- * ejemplos de imports en diferentes secciones del mismo archivo.
13
- */
14
- Object.defineProperty(exports, "__esModule", { value: true });
15
- exports.metadata = void 0;
16
- exports.default = RootLayout;
17
- exports.default = HomePage;
18
- exports.ChatButton = ChatButton;
19
- exports.default = ProductPage;
20
- // ========== app/layout.tsx (Root Layout) ==========
21
- var chat_widget_standalone_1 = require("@botuyo/chat-widget-standalone");
22
- require("./globals.css");
23
- exports.metadata = {
24
- title: 'Mi App con Chat Widget',
25
- description: 'Ejemplo de integración del Chat Widget en Next.js',
26
- };
27
- function RootLayout(_a) {
28
- var children = _a.children;
29
- return (<html lang="es">
30
- <body>
31
- <chat_widget_standalone_1.ChatWidgetProvider apiKey={process.env.NEXT_PUBLIC_CHAT_API_KEY} apiBaseUrl={process.env.NEXT_PUBLIC_CHAT_API_URL} theme={{
32
- primaryColor: '#10b981',
33
- botName: 'Asistente BotUyo',
34
- position: 'bottom-right',
35
- welcomeMessage: '¡Hola! 👋 ¿Cómo puedo ayudarte?',
36
- bubbleStyles: {
37
- launcher: {
38
- pulse: true
39
- }
40
- }
41
- }} includeSEOMetadata={true} onNavigate={function (url) {
42
- // Next.js navigation
43
- window.location.href = url;
44
- }}>
45
- {children}
46
- </chat_widget_standalone_1.ChatWidgetProvider>
47
- </body>
48
- </html>);
49
- }
50
- // ========== app/page.tsx (Homepage - Server Component) ==========
51
- var ChatButton_1 = require("@/components/ChatButton");
52
- function HomePage() {
53
- return (<main className="min-h-screen bg-gradient-to-br from-blue-50 to-green-50">
54
- <div className="container mx-auto px-4 py-12">
55
- <h1 className="text-4xl font-bold text-center mb-8">
56
- Next.js + Chat Widget
57
- </h1>
58
-
59
- <div className="max-w-2xl mx-auto bg-white p-8 rounded-lg shadow-lg">
60
- <h2 className="text-2xl font-semibold mb-4">Bienvenido</h2>
61
- <p className="text-gray-600 mb-6">
62
- Este es un ejemplo de integración del Chat Widget en Next.js 13+
63
- usando el App Router y Server/Client Components.
64
- </p>
65
-
66
- {/* Client Component con control del chat */}
67
- <ChatButton_1.ChatButton />
68
- </div>
69
- </div>
70
- </main>);
71
- }
72
- // ========== components/ChatButton.tsx (Client Component) ==========
73
- 'use client';
74
- var chat_widget_standalone_2 = require("@botuyo/chat-widget-standalone");
75
- function ChatButton() {
76
- var chat = (0, chat_widget_standalone_2.useChatWidget)();
77
- return (<div className="space-y-4">
78
- <div className="flex gap-3">
79
- <button onClick={chat.open} className="flex-1 bg-green-500 hover:bg-green-600 text-white px-6 py-3 rounded-lg font-semibold transition">
80
- Abrir Chat
81
- </button>
82
-
83
- <button onClick={function () { return chat.sendMessage('Hola, necesito información'); }} className="flex-1 bg-blue-500 hover:bg-blue-600 text-white px-6 py-3 rounded-lg font-semibold transition">
84
- Mensaje Rápido
85
- </button>
86
- </div>
87
-
88
- {chat.unreadCount > 0 && (<div className="bg-yellow-50 border border-yellow-200 rounded-lg p-4">
89
- <p className="text-yellow-800">
90
- Tienes {chat.unreadCount} mensaje(s) nuevo(s)
91
- </p>
92
- </div>)}
93
- </div>);
94
- }
95
- // ========== app/products/[id]/page.tsx (Dynamic Route con Context) ==========
96
- 'use client';
97
- function ProductPage(_a) {
98
- var params = _a.params;
99
- return (<chat_widget_standalone_1.ChatWidgetProvider apiKey={process.env.NEXT_PUBLIC_CHAT_API_KEY} apiBaseUrl={process.env.NEXT_PUBLIC_CHAT_API_URL} pageContext={{
100
- page: 'Product',
101
- productId: params.id,
102
- url: window.location.href,
103
- // Cualquier información relevante del producto
104
- }} theme={{
105
- primaryColor: '#10b981',
106
- welcomeMessage: "\u00BFTienes preguntas sobre este producto? \uD83D\uDECD\uFE0F",
107
- }}>
108
- <div>
109
- <h1>Producto {params.id}</h1>
110
- {/* Contenido del producto */}
111
- </div>
112
- </chat_widget_standalone_1.ChatWidgetProvider>);
113
- }
114
- // ========== .env.local ==========
115
- /*
116
- NEXT_PUBLIC_CHAT_API_KEY=your-api-key-here
117
- NEXT_PUBLIC_CHAT_API_URL=https://api.botuyo.com
118
- */
119
- // ========== next.config.js ==========
120
- /*
121
- /** @type {import('next').NextConfig} *\/
122
- const nextConfig = {
123
- reactStrictMode: true,
124
- transpilePackages: ['@botuyo/chat-widget-standalone'],
125
- }
126
-
127
- module.exports = nextConfig
128
- */
129
- // ========== tsconfig.json ==========
130
- /*
131
- {
132
- "compilerOptions": {
133
- "target": "ES2020",
134
- "lib": ["dom", "dom.iterable", "esnext"],
135
- "allowJs": true,
136
- "skipLibCheck": true,
137
- "strict": true,
138
- "forceConsistentCasingInFileNames": true,
139
- "noEmit": true,
140
- "esModuleInterop": true,
141
- "module": "esnext",
142
- "moduleResolution": "bundler",
143
- "resolveJsonModule": true,
144
- "isolatedModules": true,
145
- "jsx": "preserve",
146
- "incremental": true,
147
- "plugins": [
148
- {
149
- "name": "next"
150
- }
151
- ],
152
- "paths": {
153
- "@/*": ["./src/*"]
154
- }
155
- },
156
- "include": ["next-env.d.ts", "**\/*.ts", "**\/*.tsx", ".next/types/**\/*.ts"],
157
- "exclude": ["node_modules"]
158
- }
159
- */
160
- // ========== package.json ==========
161
- /*
162
- {
163
- "name": "nextjs-chat-widget-example",
164
- "version": "0.1.0",
165
- "private": true,
166
- "scripts": {
167
- "dev": "next dev",
168
- "build": "next build",
169
- "start": "next start",
170
- "lint": "next lint"
171
- },
172
- "dependencies": {
173
- "@botuyo/chat-widget-standalone": "^1.0.0",
174
- "next": "^14.0.0",
175
- "react": "^18.2.0",
176
- "react-dom": "^18.2.0"
177
- },
178
- "devDependencies": {
179
- "@types/node": "^20",
180
- "@types/react": "^18",
181
- "@types/react-dom": "^18",
182
- "autoprefixer": "^10.0.1",
183
- "postcss": "^8",
184
- "tailwindcss": "^3.3.0",
185
- "typescript": "^5"
186
- }
187
- }
188
- */