@botuyo/chat-widget-standalone 1.0.0 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +243 -290
- package/dist/{ChatWidget-B6W68bT_.js → ChatWidget-BCHSZnMy.js} +17 -17
- package/dist/{ChatWidget-B6W68bT_.js.map → ChatWidget-BCHSZnMy.js.map} +1 -1
- package/dist/botuyo-chat.css +1 -1
- package/dist/botuyo-chat.js +1 -1
- package/dist/{chunk-audio-CgduwQLl.js → chunk-audio-BT2WWPfS.js} +2 -2
- package/dist/{chunk-audio-CgduwQLl.js.map → chunk-audio-BT2WWPfS.js.map} +1 -1
- package/dist/{chunk-chat-ui-EAAXXtnK.js → chunk-chat-ui-BHfnFN_3.js} +10 -10
- package/dist/{chunk-chat-ui-EAAXXtnK.js.map → chunk-chat-ui-BHfnFN_3.js.map} +1 -1
- package/dist/{chunk-gallery-B9sBFYYc.js → chunk-gallery-CHMxgXlB.js} +2 -2
- package/dist/{chunk-gallery-B9sBFYYc.js.map → chunk-gallery-CHMxgXlB.js.map} +1 -1
- package/dist/src/chat-widget/ChatWidget.d.ts +3 -0
- package/dist/src/chat-widget/ChatWidget.d.ts.map +1 -0
- package/dist/src/chat-widget/ChatWidgetProvider.d.ts +81 -0
- package/dist/src/chat-widget/ChatWidgetProvider.d.ts.map +1 -0
- package/dist/src/chat-widget/components/AudioPlayer.d.ts +8 -0
- package/dist/src/chat-widget/components/AudioPlayer.d.ts.map +1 -0
- package/dist/src/chat-widget/components/AudioPlayer.stories.d.ts +37 -0
- package/dist/src/chat-widget/components/AudioPlayer.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/ChatWindow.d.ts +28 -0
- package/dist/src/chat-widget/components/ChatWindow.d.ts.map +1 -0
- package/dist/src/chat-widget/components/ChatWindow.stories.d.ts +71 -0
- package/dist/src/chat-widget/components/ChatWindow.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/ErrorBoundary.d.ts +36 -0
- package/dist/src/chat-widget/components/ErrorBoundary.d.ts.map +1 -0
- package/dist/src/chat-widget/components/ErrorBoundary.stories.d.ts +29 -0
- package/dist/src/chat-widget/components/ErrorBoundary.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/Gallery.d.ts +14 -0
- package/dist/src/chat-widget/components/Gallery.d.ts.map +1 -0
- package/dist/src/chat-widget/components/Gallery.stories.d.ts +33 -0
- package/dist/src/chat-widget/components/Gallery.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/Icons.d.ts +7 -0
- package/dist/src/chat-widget/components/Icons.d.ts.map +1 -0
- package/dist/src/chat-widget/components/InputArea.d.ts +20 -0
- package/dist/src/chat-widget/components/InputArea.d.ts.map +1 -0
- package/dist/src/chat-widget/components/InputArea.stories.d.ts +61 -0
- package/dist/src/chat-widget/components/InputArea.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/LanguageSelector.d.ts +25 -0
- package/dist/src/chat-widget/components/LanguageSelector.d.ts.map +1 -0
- package/dist/src/chat-widget/components/Launcher.d.ts +21 -0
- package/dist/src/chat-widget/components/Launcher.d.ts.map +1 -0
- package/dist/src/chat-widget/components/Launcher.stories.d.ts +75 -0
- package/dist/src/chat-widget/components/Launcher.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/LiveCallInputArea.d.ts +29 -0
- package/dist/src/chat-widget/components/LiveCallInputArea.d.ts.map +1 -0
- package/dist/src/chat-widget/components/MessageBubble.d.ts +14 -0
- package/dist/src/chat-widget/components/MessageBubble.d.ts.map +1 -0
- package/dist/src/chat-widget/components/MessageBubble.stories.d.ts +70 -0
- package/dist/src/chat-widget/components/MessageBubble.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/MessageList.d.ts +15 -0
- package/dist/src/chat-widget/components/MessageList.d.ts.map +1 -0
- package/dist/src/chat-widget/components/MessageList.stories.d.ts +52 -0
- package/dist/src/chat-widget/components/MessageList.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/TypingIndicator.d.ts +2 -0
- package/dist/src/chat-widget/components/TypingIndicator.d.ts.map +1 -0
- package/dist/src/chat-widget/components/TypingIndicator.stories.d.ts +39 -0
- package/dist/src/chat-widget/components/TypingIndicator.stories.d.ts.map +1 -0
- package/dist/src/chat-widget/components/VoiceInputArea.d.ts +26 -0
- package/dist/src/chat-widget/components/VoiceInputArea.d.ts.map +1 -0
- package/dist/src/chat-widget/components/index.d.ts +16 -0
- package/dist/src/chat-widget/components/index.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useAnalytics.d.ts +19 -0
- package/dist/src/chat-widget/hooks/useAnalytics.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useChatSocket.d.ts +30 -0
- package/dist/src/chat-widget/hooks/useChatSocket.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useChatState.d.ts +23 -0
- package/dist/src/chat-widget/hooks/useChatState.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useChatWidget.d.ts +48 -0
- package/dist/src/chat-widget/hooks/useChatWidget.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useDarkMode.d.ts +6 -0
- package/dist/src/chat-widget/hooks/useDarkMode.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useDynamicHeight.d.ts +10 -0
- package/dist/src/chat-widget/hooks/useDynamicHeight.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useFocusTrap.d.ts +34 -0
- package/dist/src/chat-widget/hooks/useFocusTrap.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useHighContrast.d.ts +6 -0
- package/dist/src/chat-widget/hooks/useHighContrast.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useIsMobile.d.ts +2 -0
- package/dist/src/chat-widget/hooks/useIsMobile.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useNotifications.d.ts +23 -0
- package/dist/src/chat-widget/hooks/useNotifications.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useRateLimit.d.ts +15 -0
- package/dist/src/chat-widget/hooks/useRateLimit.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useSEOMetadata.d.ts +10 -0
- package/dist/src/chat-widget/hooks/useSEOMetadata.d.ts.map +1 -0
- package/dist/src/chat-widget/hooks/useWidgetTheme.d.ts +12 -0
- package/dist/src/chat-widget/hooks/useWidgetTheme.d.ts.map +1 -0
- package/dist/src/chat-widget/i18n/LanguageContext.d.ts +33 -0
- package/dist/src/chat-widget/i18n/LanguageContext.d.ts.map +1 -0
- package/dist/src/chat-widget/i18n/index.d.ts +8 -0
- package/dist/src/chat-widget/i18n/index.d.ts.map +1 -0
- package/dist/src/chat-widget/i18n/translations.d.ts +177 -0
- package/dist/src/chat-widget/i18n/translations.d.ts.map +1 -0
- package/dist/src/chat-widget/i18n/useTranslations.d.ts +27 -0
- package/dist/src/chat-widget/i18n/useTranslations.d.ts.map +1 -0
- package/dist/src/chat-widget/index.d.ts +11 -0
- package/dist/src/chat-widget/index.d.ts.map +1 -0
- package/dist/src/chat-widget/types/index.d.ts +268 -0
- package/dist/src/chat-widget/types/index.d.ts.map +1 -0
- package/dist/src/chat-widget/types/socket.d.ts +101 -0
- package/dist/src/chat-widget/types/socket.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/dateUtils.d.ts +33 -0
- package/dist/src/chat-widget/utils/dateUtils.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/defaultAssets.d.ts +20 -0
- package/dist/src/chat-widget/utils/defaultAssets.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/deviceId.d.ts +18 -0
- package/dist/src/chat-widget/utils/deviceId.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/fileValidation.d.ts +75 -0
- package/dist/src/chat-widget/utils/fileValidation.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/logger.d.ts +31 -0
- package/dist/src/chat-widget/utils/logger.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/performance.d.ts +50 -0
- package/dist/src/chat-widget/utils/performance.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/storage.d.ts +24 -0
- package/dist/src/chat-widget/utils/storage.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/theme.d.ts +122 -0
- package/dist/src/chat-widget/utils/theme.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/theme.examples.d.ts +47 -0
- package/dist/src/chat-widget/utils/theme.examples.d.ts.map +1 -0
- package/dist/src/chat-widget/utils/themes/index.d.ts +12 -0
- package/dist/src/chat-widget/utils/themes/index.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/components/CallButton.d.ts +12 -0
- package/dist/src/chat-widget/voice/components/CallButton.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/components/LiveCallOverlay.d.ts +12 -0
- package/dist/src/chat-widget/voice/components/LiveCallOverlay.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/components/VoiceButton.d.ts +13 -0
- package/dist/src/chat-widget/voice/components/VoiceButton.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/components/VoiceChatOverlay.d.ts +12 -0
- package/dist/src/chat-widget/voice/components/VoiceChatOverlay.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/components/WaveformVisualizer.d.ts +12 -0
- package/dist/src/chat-widget/voice/components/WaveformVisualizer.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/components/index.d.ts +10 -0
- package/dist/src/chat-widget/voice/components/index.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/index.d.ts +11 -0
- package/dist/src/chat-widget/voice/index.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/types.d.ts +232 -0
- package/dist/src/chat-widget/voice/types.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/useLiveCall.d.ts +13 -0
- package/dist/src/chat-widget/voice/useLiveCall.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/useVoiceChat.d.ts +13 -0
- package/dist/src/chat-widget/voice/useVoiceChat.d.ts.map +1 -0
- package/dist/src/chat-widget/voice/useVoiceState.d.ts +38 -0
- package/dist/src/chat-widget/voice/useVoiceState.d.ts.map +1 -0
- package/dist/src/lib/utils.d.ts +3 -0
- package/dist/src/lib/utils.d.ts.map +1 -0
- package/dist/standalone.d.ts +95 -0
- package/dist/standalone.d.ts.map +1 -0
- package/dist/stats.html +1 -1
- package/package.json +3 -7
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{r as e,j as r}from"./vendor-react-CtfcjTlq.js";import{u as s,c as a,Z as o,C as t,b as l,X as n}from"./chunk-chat-ui-
|
|
1
|
+
import{r as e,j as r}from"./vendor-react-CtfcjTlq.js";import{u as s,c as a,Z as o,C as t,b as l,X as n}from"./chunk-chat-ui-BHfnFN_3.js";const i=e.memo(function({images:n,radius:i="rounded-lg"}){const{t:d}=s("extracted"),[h,u]=e.useState(0),[m,x]=e.useState(!1),b=()=>{u(e=>(e+1)%n.length)},g=()=>{u(e=>(e-1+n.length)%n.length)},p=e=>{u(e),x(!0)},[v,j]=e.useState(/* @__PURE__ */new Set),f=e=>{j(r=>new Set(r).add(e))};return 1===n.length?/* @__PURE__ */r.jsx("div",{className:"my-3 relative group",children:v.has(0)?/* @__PURE__ */r.jsxs("div",{className:a("w-full h-48 flex flex-col items-center justify-center","border bg-muted text-muted-foreground",i),style:{borderColor:"hsl(var(--border))"},children:[
|
|
2
2
|
/* @__PURE__ */r.jsx("svg",{className:"w-12 h-12 mb-2 opacity-50",fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:/* @__PURE__ */r.jsx("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,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"})}),
|
|
3
3
|
/* @__PURE__ */r.jsx("span",{className:"text-sm",children:"Imagen no disponible"})]}):/* @__PURE__ */r.jsxs(r.Fragment,{children:[
|
|
4
4
|
/* @__PURE__ */r.jsx("img",{src:n[0].src,alt:n[0].alt||"Imagen",className:a("w-full h-auto object-cover cursor-pointer transition-all duration-300","border shadow-soft-md hover:shadow-soft-lg hover:scale-[1.02]",i),style:{borderColor:"hsl(var(--border))"},loading:"lazy",onClick:()=>p(0),onError:()=>f(0)}),
|
|
@@ -21,4 +21,4 @@ return r.jsxs("div",{className:"fixed inset-0 z-[100000] bg-black/95 backdrop-bl
|
|
|
21
21
|
/* @__PURE__ */r.jsx("button",{onClick:e=>{e.stopPropagation(),c()},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","aria-label":"Anterior",children:/* @__PURE__ */r.jsx(t,{size:32,className:"text-white"})}),
|
|
22
22
|
/* @__PURE__ */r.jsx("button",{onClick:e=>{e.stopPropagation(),i()},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","aria-label":"Siguiente",children:/* @__PURE__ */r.jsx(l,{size:32,className:"text-white"})})]}),
|
|
23
23
|
/* @__PURE__ */r.jsx("img",{src:e[a].src,alt:e[a].alt||`Imagen ${a+1}`,className:"max-w-[90%] max-h-[90vh] object-contain",onClick:e=>e.stopPropagation()})]})}export{i as Gallery};
|
|
24
|
-
//# sourceMappingURL=chunk-gallery-
|
|
24
|
+
//# sourceMappingURL=chunk-gallery-CHMxgXlB.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chunk-gallery-B9sBFYYc.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 } 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 return (\r\n <div\r\n className=\"fixed 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 >\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-[90vh] object-contain\"\r\n onClick={e => e.stopPropagation()}\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","X","e","stopPropagation"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"chunk-gallery-CHMxgXlB.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 } 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 return (\r\n <div\r\n className=\"fixed 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 >\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-[90vh] object-contain\"\r\n onClick={e => e.stopPropagation()}\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","X","e","stopPropagation"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWidget.d.ts","sourceRoot":"","sources":["../../../src/chat-widget/ChatWidget.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAU9C,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,2CAoKhD"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package @botuyo/chat-widget
|
|
3
|
+
* ChatWidgetProvider - React Context Provider para el widget
|
|
4
|
+
*
|
|
5
|
+
* Este provider permite usar el widget de chat como un componente React estándar
|
|
6
|
+
* con acceso a su estado y métodos a través de hooks.
|
|
7
|
+
*/
|
|
8
|
+
import { ReactNode } from 'react';
|
|
9
|
+
import type { ChatWidgetProps } from './types';
|
|
10
|
+
import { type SupportedLocale } from './i18n';
|
|
11
|
+
export interface ChatWidgetContextValue {
|
|
12
|
+
/** Si el widget está abierto o cerrado */
|
|
13
|
+
isOpen: boolean;
|
|
14
|
+
/** Abrir el widget */
|
|
15
|
+
open: () => void;
|
|
16
|
+
/** Cerrar el widget */
|
|
17
|
+
close: () => void;
|
|
18
|
+
/** Toggle abrir/cerrar */
|
|
19
|
+
toggle: () => void;
|
|
20
|
+
/** Enviar un mensaje programáticamente */
|
|
21
|
+
sendMessage: (text: string) => void;
|
|
22
|
+
/** Limpiar el historial de chat */
|
|
23
|
+
clearMessages: () => void;
|
|
24
|
+
/** Número de mensajes no leídos */
|
|
25
|
+
unreadCount: number;
|
|
26
|
+
}
|
|
27
|
+
export declare function _setInternalSendMessage(fn: ((text: string) => void) | null): void;
|
|
28
|
+
export declare function _setInternalClearMessages(fn: (() => void) | null): void;
|
|
29
|
+
export interface ChatWidgetProviderProps extends ChatWidgetProps {
|
|
30
|
+
/** Children que tendrán acceso al contexto del chat */
|
|
31
|
+
children?: ReactNode;
|
|
32
|
+
/** Configuración inicial del estado del widget */
|
|
33
|
+
initialState?: {
|
|
34
|
+
/** Si el widget debe iniciar abierto */
|
|
35
|
+
isOpen?: boolean;
|
|
36
|
+
};
|
|
37
|
+
/** Idioma inicial del widget (es, en, pt, fr). Si no se especifica, se detecta automáticamente */
|
|
38
|
+
defaultLocale?: SupportedLocale;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Provider que envuelve tu aplicación para dar acceso al Chat Widget
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* import { ChatWidgetProvider } from '@botuyo/chat-widget'
|
|
46
|
+
*
|
|
47
|
+
* function App() {
|
|
48
|
+
* return (
|
|
49
|
+
* <ChatWidgetProvider
|
|
50
|
+
* apiKey="tu-api-key"
|
|
51
|
+
* apiBaseUrl="https://api.botuyo.com"
|
|
52
|
+
* theme={{ primaryColor: '#10b981' }}
|
|
53
|
+
* >
|
|
54
|
+
* <YourApp />
|
|
55
|
+
* </ChatWidgetProvider>
|
|
56
|
+
* )
|
|
57
|
+
* }
|
|
58
|
+
* ```
|
|
59
|
+
*/
|
|
60
|
+
export declare function ChatWidgetProvider({ children, defaultLocale, initialState, onStateChange, ...widgetProps }: ChatWidgetProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
61
|
+
/**
|
|
62
|
+
* Hook para acceder al contexto del Chat Widget
|
|
63
|
+
*
|
|
64
|
+
* @throws Error si se usa fuera del ChatWidgetProvider
|
|
65
|
+
*
|
|
66
|
+
* @example
|
|
67
|
+
* ```tsx
|
|
68
|
+
* function MyComponent() {
|
|
69
|
+
* const chat = useChatWidget()
|
|
70
|
+
*
|
|
71
|
+
* return (
|
|
72
|
+
* <button onClick={chat.open}>
|
|
73
|
+
* Abrir Chat {chat.unreadCount > 0 && `(${chat.unreadCount})`}
|
|
74
|
+
* </button>
|
|
75
|
+
* )
|
|
76
|
+
* }
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
79
|
+
export declare function useChatWidget(): ChatWidgetContextValue;
|
|
80
|
+
export default ChatWidgetProvider;
|
|
81
|
+
//# sourceMappingURL=ChatWidgetProvider.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWidgetProvider.d.ts","sourceRoot":"","sources":["../../../src/chat-widget/ChatWidgetProvider.tsx"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,OAAO,EAAoD,SAAS,EAAE,MAAM,OAAO,CAAA;AAEnF,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AAE9C,OAAO,EAAoB,KAAK,eAAe,EAAE,MAAM,QAAQ,CAAA;AAI/D,MAAM,WAAW,sBAAsB;IACrC,0CAA0C;IAC1C,MAAM,EAAE,OAAO,CAAA;IACf,sBAAsB;IACtB,IAAI,EAAE,MAAM,IAAI,CAAA;IAChB,uBAAuB;IACvB,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB,0BAA0B;IAC1B,MAAM,EAAE,MAAM,IAAI,CAAA;IAClB,0CAA0C;IAC1C,WAAW,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAA;IACnC,mCAAmC;IACnC,aAAa,EAAE,MAAM,IAAI,CAAA;IACzB,mCAAmC;IACnC,WAAW,EAAE,MAAM,CAAA;CACpB;AAMD,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,IAAI,QAE1E;AAED,wBAAgB,yBAAyB,CAAC,EAAE,EAAE,CAAC,MAAM,IAAI,CAAC,GAAG,IAAI,QAEhE;AAMD,MAAM,WAAW,uBAAwB,SAAQ,eAAe;IAC9D,uDAAuD;IACvD,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,kDAAkD;IAClD,YAAY,CAAC,EAAE;QACb,wCAAwC;QACxC,MAAM,CAAC,EAAE,OAAO,CAAA;KACjB,CAAA;IACD,kGAAkG;IAClG,aAAa,CAAC,EAAE,eAAe,CAAA;CAChC;AAID;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,QAAQ,EACR,aAAa,EACb,YAAY,EACZ,aAAa,EACb,GAAG,WAAW,EACf,EAAE,uBAAuB,2CAmFzB;AAID;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAgB,aAAa,IAAI,sBAAsB,CAWtD;AAID,eAAe,kBAAkB,CAAA"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioPlayer.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/AudioPlayer.tsx"],"names":[],"mappings":"AAOA,UAAU,gBAAgB;IACxB,GAAG,EAAE,MAAM,CAAA;IACX,KAAK,EAAE,OAAO,CAAA;IACd,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB;AAED,YAAY,EAAE,gBAAgB,EAAE,CAAA;AAEhC,eAAO,MAAM,WAAW,wDA6EtB,CAAA"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
declare const meta: {
|
|
3
|
+
title: string;
|
|
4
|
+
component: import("react").NamedExoticComponent<import("./AudioPlayer").AudioPlayerProps>;
|
|
5
|
+
parameters: {
|
|
6
|
+
layout: string;
|
|
7
|
+
};
|
|
8
|
+
decorators: ((Story: import("storybook/internal/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
|
|
9
|
+
url: string;
|
|
10
|
+
isBot: boolean;
|
|
11
|
+
primaryColor?: string | undefined;
|
|
12
|
+
}>) => import("react/jsx-runtime").JSX.Element)[];
|
|
13
|
+
tags: string[];
|
|
14
|
+
argTypes: {
|
|
15
|
+
url: {
|
|
16
|
+
control: "text";
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
isBot: {
|
|
20
|
+
control: "boolean";
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
primaryColor: {
|
|
24
|
+
control: "color";
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
};
|
|
29
|
+
export default meta;
|
|
30
|
+
type Story = StoryObj<typeof meta>;
|
|
31
|
+
export declare const Default: Story;
|
|
32
|
+
export declare const CustomColor: Story;
|
|
33
|
+
export declare const PurpleTheme: Story;
|
|
34
|
+
export declare const RedTheme: Story;
|
|
35
|
+
export declare const MultipleAudioPlayers: Story;
|
|
36
|
+
export declare const InvalidAudio: Story;
|
|
37
|
+
//# sourceMappingURL=AudioPlayer.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AudioPlayer.stories.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/AudioPlayer.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAG3D,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;CA4B0B,CAAA;AAEpC,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;AAElC,eAAO,MAAM,OAAO,EAAE,KAMrB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAMzB,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAMtB,CAAA;AAED,eAAO,MAAM,oBAAoB,EAAE,KAkClC,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAM1B,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { BubbleStyles, ChatMessage, MediaConfig } from '../types';
|
|
2
|
+
import { EmotionAvatarMap } from './Launcher';
|
|
3
|
+
export interface ChatWindowProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
isConnected: boolean;
|
|
6
|
+
isTyping: boolean;
|
|
7
|
+
messages: ChatMessage[];
|
|
8
|
+
botName?: string;
|
|
9
|
+
logoUrl?: string;
|
|
10
|
+
welcomeMessage?: string;
|
|
11
|
+
inputPlaceholder?: string;
|
|
12
|
+
primaryColor?: string;
|
|
13
|
+
borderRadius?: string;
|
|
14
|
+
mediaConfig?: MediaConfig;
|
|
15
|
+
onClose: () => void;
|
|
16
|
+
onSendMessage: (message: string) => void;
|
|
17
|
+
position?: 'bottom-right' | 'bottom-left';
|
|
18
|
+
bubbleStyles?: BubbleStyles;
|
|
19
|
+
avatars?: EmotionAvatarMap;
|
|
20
|
+
onSendAttachment?: (file: File, type: 'image' | 'audio' | 'file') => void;
|
|
21
|
+
onSendLocation?: (location: {
|
|
22
|
+
latitude: number;
|
|
23
|
+
longitude: number;
|
|
24
|
+
}) => void;
|
|
25
|
+
theme?: import('../types').ChatTheme;
|
|
26
|
+
}
|
|
27
|
+
export declare function ChatWindow({ isOpen, isConnected, isTyping, messages, botName, logoUrl, welcomeMessage, inputPlaceholder, primaryColor, mediaConfig, onClose, onSendMessage, bubbleStyles, avatars, onSendAttachment, onSendLocation, theme, }: ChatWindowProps): import("react/jsx-runtime").JSX.Element | null;
|
|
28
|
+
//# sourceMappingURL=ChatWindow.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWindow.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/ChatWindow.tsx"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAOtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAG7C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,OAAO,CAAA;IACf,WAAW,EAAE,OAAO,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,QAAQ,EAAE,WAAW,EAAE,CAAA;IACvB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,OAAO,EAAE,MAAM,IAAI,CAAA;IACnB,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,QAAQ,CAAC,EAAE,cAAc,GAAG,aAAa,CAAA;IACzC,YAAY,CAAC,EAAE,YAAY,CAAA;IAC3B,OAAO,CAAC,EAAE,gBAAgB,CAAA;IAC1B,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,KAAK,IAAI,CAAA;IACzE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;IAC5E,KAAK,CAAC,EAAE,OAAO,UAAU,EAAE,SAAS,CAAA;CACrC;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,WAAW,EACX,QAAQ,EACR,QAAQ,EACR,OAAe,EACf,OAAO,EACP,cAAc,EACd,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,OAAO,EACP,aAAa,EACb,YAAY,EACZ,OAAO,EACP,gBAAgB,EAChB,cAAc,EACd,KAAK,GACN,EAAE,eAAe,kDA+NjB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { ChatWindow } from './ChatWindow';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof ChatWindow;
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: string;
|
|
8
|
+
};
|
|
9
|
+
tags: string[];
|
|
10
|
+
argTypes: {
|
|
11
|
+
isOpen: {
|
|
12
|
+
control: "boolean";
|
|
13
|
+
description: string;
|
|
14
|
+
};
|
|
15
|
+
isConnected: {
|
|
16
|
+
control: "boolean";
|
|
17
|
+
description: string;
|
|
18
|
+
};
|
|
19
|
+
isTyping: {
|
|
20
|
+
control: "boolean";
|
|
21
|
+
description: string;
|
|
22
|
+
};
|
|
23
|
+
botName: {
|
|
24
|
+
control: "text";
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
welcomeMessage: {
|
|
28
|
+
control: "text";
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
31
|
+
inputPlaceholder: {
|
|
32
|
+
control: "text";
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
primaryColor: {
|
|
36
|
+
control: "color";
|
|
37
|
+
description: string;
|
|
38
|
+
};
|
|
39
|
+
position: {
|
|
40
|
+
control: "select";
|
|
41
|
+
options: string[];
|
|
42
|
+
description: string;
|
|
43
|
+
};
|
|
44
|
+
onClose: {
|
|
45
|
+
action: string;
|
|
46
|
+
};
|
|
47
|
+
onSendMessage: {
|
|
48
|
+
action: string;
|
|
49
|
+
};
|
|
50
|
+
onSendAttachment: {
|
|
51
|
+
action: string;
|
|
52
|
+
};
|
|
53
|
+
onSendLocation: {
|
|
54
|
+
action: string;
|
|
55
|
+
};
|
|
56
|
+
};
|
|
57
|
+
};
|
|
58
|
+
export default meta;
|
|
59
|
+
type Story = StoryObj<typeof meta>;
|
|
60
|
+
export declare const Default: Story;
|
|
61
|
+
export declare const EmptyChat: Story;
|
|
62
|
+
export declare const BotTyping: Story;
|
|
63
|
+
export declare const Disconnected: Story;
|
|
64
|
+
export declare const WithGallery: Story;
|
|
65
|
+
export declare const WithLocation: Story;
|
|
66
|
+
export declare const WithFile: Story;
|
|
67
|
+
export declare const WithAudio: Story;
|
|
68
|
+
export declare const LongConversation: Story;
|
|
69
|
+
export declare const CustomColors: Story;
|
|
70
|
+
export declare const BottomLeft: Story;
|
|
71
|
+
//# sourceMappingURL=ChatWindow.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ChatWindow.stories.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/ChatWindow.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAA;AAUzC,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8CyB,CAAA;AAEnC,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;AA2BlC,eAAO,MAAM,OAAO,EAAE,KAcrB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAKvB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAKvB,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAK1B,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAezB,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAgB1B,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAetB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAcvB,CAAA;AAED,eAAO,MAAM,gBAAgB,EAAE,KAqC9B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAK1B,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,KAKxB,CAAA"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import React, { Component, ReactNode } from 'react';
|
|
2
|
+
interface ErrorBoundaryProps {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
fallback?: ReactNode;
|
|
5
|
+
onError?: (error: Error, errorInfo: React.ErrorInfo) => void;
|
|
6
|
+
}
|
|
7
|
+
interface ErrorBoundaryState {
|
|
8
|
+
hasError: boolean;
|
|
9
|
+
error: Error | null;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* 🛡️ ERROR BOUNDARY
|
|
13
|
+
*
|
|
14
|
+
* Componente que captura errores de React en sus hijos y muestra un UI de fallback.
|
|
15
|
+
* Previene que un error en un componente rompa toda la aplicación.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```tsx
|
|
19
|
+
* <ErrorBoundary fallback={<div>Algo salió mal</div>}>
|
|
20
|
+
* <MiComponente />
|
|
21
|
+
* </ErrorBoundary>
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* Principios SOLID aplicados:
|
|
25
|
+
* - Single Responsibility: Solo maneja captura de errores
|
|
26
|
+
* - Open/Closed: Extensible mediante props fallback y onError
|
|
27
|
+
*/
|
|
28
|
+
export declare class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|
29
|
+
constructor(props: ErrorBoundaryProps);
|
|
30
|
+
static getDerivedStateFromError(error: Error): ErrorBoundaryState;
|
|
31
|
+
componentDidCatch(error: Error, errorInfo: React.ErrorInfo): void;
|
|
32
|
+
handleReset: () => void;
|
|
33
|
+
render(): string | number | bigint | boolean | Iterable<React.ReactNode> | Promise<string | number | bigint | boolean | React.ReactPortal | React.ReactElement<unknown, string | React.JSXElementConstructor<any>> | Iterable<React.ReactNode> | null | undefined> | import("react/jsx-runtime").JSX.Element | null | undefined;
|
|
34
|
+
}
|
|
35
|
+
export {};
|
|
36
|
+
//# sourceMappingURL=ErrorBoundary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/ErrorBoundary.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAGnD,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,SAAS,CAAA;IACnB,QAAQ,CAAC,EAAE,SAAS,CAAA;IACpB,OAAO,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS,KAAK,IAAI,CAAA;CAC7D;AAED,UAAU,kBAAkB;IAC1B,QAAQ,EAAE,OAAO,CAAA;IACjB,KAAK,EAAE,KAAK,GAAG,IAAI,CAAA;CACpB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,qBAAa,aAAc,SAAQ,SAAS,CAAC,kBAAkB,EAAE,kBAAkB,CAAC;gBACtE,KAAK,EAAE,kBAAkB;IAKrC,MAAM,CAAC,wBAAwB,CAAC,KAAK,EAAE,KAAK,GAAG,kBAAkB;IAIjE,iBAAiB,CAAC,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,KAAK,CAAC,SAAS;IAK1D,WAAW,aAEV;IAED,MAAM;CAyBP"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { ErrorBoundary } from './ErrorBoundary';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof ErrorBoundary;
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: string;
|
|
8
|
+
};
|
|
9
|
+
decorators: ((Story: import("storybook/internal/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
|
|
10
|
+
children: import("react").ReactNode;
|
|
11
|
+
fallback?: import("react").ReactNode;
|
|
12
|
+
onError?: ((error: Error, errorInfo: React.ErrorInfo) => void) | undefined;
|
|
13
|
+
}>) => import("react/jsx-runtime").JSX.Element)[];
|
|
14
|
+
tags: string[];
|
|
15
|
+
argTypes: {
|
|
16
|
+
onError: {
|
|
17
|
+
action: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
export default meta;
|
|
22
|
+
type Story = StoryObj<typeof meta>;
|
|
23
|
+
export declare const Default: Story;
|
|
24
|
+
export declare const WithError: Story;
|
|
25
|
+
export declare const CustomFallback: Story;
|
|
26
|
+
export declare const Interactive: Story;
|
|
27
|
+
export declare const NestedErrorBoundaries: Story;
|
|
28
|
+
export declare const WithErrorCallback: Story;
|
|
29
|
+
//# sourceMappingURL=ErrorBoundary.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ErrorBoundary.stories.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/ErrorBoundary.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAA;AAG/C,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;CAmB4B,CAAA;AAEtC,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;AA8BlC,eAAO,MAAM,OAAO,EAAE,KAarB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAKvB,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAY5B,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAA;AAED,eAAO,MAAM,qBAAqB,EAAE,KA8BnC,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,KAS/B,CAAA"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @package @botuyo/chat-widget
|
|
3
|
+
* Gallery - Componente visual para mostrar galerías de imágenes
|
|
4
|
+
*/
|
|
5
|
+
interface GalleryProps {
|
|
6
|
+
images: Array<{
|
|
7
|
+
src: string;
|
|
8
|
+
alt?: string;
|
|
9
|
+
}>;
|
|
10
|
+
radius?: string;
|
|
11
|
+
}
|
|
12
|
+
export type { GalleryProps };
|
|
13
|
+
export declare const Gallery: import("react").NamedExoticComponent<GalleryProps>;
|
|
14
|
+
//# sourceMappingURL=Gallery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gallery.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/Gallery.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AASH,UAAU,YAAY;IACpB,MAAM,EAAE,KAAK,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAA;IAC5C,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED,YAAY,EAAE,YAAY,EAAE,CAAA;AAE5B,eAAO,MAAM,OAAO,oDA4RlB,CAAA"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
declare const meta: {
|
|
3
|
+
title: string;
|
|
4
|
+
component: import("react").NamedExoticComponent<import("./Gallery").GalleryProps>;
|
|
5
|
+
parameters: {
|
|
6
|
+
layout: string;
|
|
7
|
+
};
|
|
8
|
+
decorators: ((Story: import("storybook/internal/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
|
|
9
|
+
images: Array<{
|
|
10
|
+
src: string;
|
|
11
|
+
alt?: string;
|
|
12
|
+
}>;
|
|
13
|
+
radius?: string | undefined;
|
|
14
|
+
}>) => import("react/jsx-runtime").JSX.Element)[];
|
|
15
|
+
tags: string[];
|
|
16
|
+
argTypes: {
|
|
17
|
+
images: {
|
|
18
|
+
control: "object";
|
|
19
|
+
description: string;
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
export default meta;
|
|
24
|
+
type Story = StoryObj<typeof meta>;
|
|
25
|
+
export declare const SingleImage: Story;
|
|
26
|
+
export declare const TwoImages: Story;
|
|
27
|
+
export declare const ThreeImages: Story;
|
|
28
|
+
export declare const FourImages: Story;
|
|
29
|
+
export declare const ManyImages: Story;
|
|
30
|
+
export declare const PortraitImages: Story;
|
|
31
|
+
export declare const SquareImages: Story;
|
|
32
|
+
export declare const WithLongAltText: Story;
|
|
33
|
+
//# sourceMappingURL=Gallery.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Gallery.stories.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/Gallery.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAG3D,QAAA,MAAM,IAAI;;;;;;;;;eAYP,CAAC;;;;;;;;;;;CAQ4B,CAAA;AAEhC,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;AAElC,eAAO,MAAM,WAAW,EAAE,KASzB,CAAA;AAED,eAAO,MAAM,SAAS,EAAE,KAavB,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAiBzB,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,KAqBxB,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,KAOxB,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAiB5B,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAqB1B,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KAS7B,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Centralized icon exports to optimize bundle size
|
|
3
|
+
* All lucide-react icons are imported here and re-exported
|
|
4
|
+
* This allows for better tree-shaking and reduces duplication
|
|
5
|
+
*/
|
|
6
|
+
export { X, ShieldCheck, Heart, Paperclip, Send, Loader2, Image as ImageIcon, FileAudio, FileText, FileIcon, Plus, MapPin, Mic, Trash2, Play, Pause, MessageCircle, ChevronLeft, ChevronRight, ZoomIn, CheckCheck, MapPin as MapPinBubble, ExternalLink, ArrowRight, Download, } from 'lucide-react';
|
|
7
|
+
//# sourceMappingURL=Icons.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Icons.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/Icons.tsx"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAEL,CAAC,EACD,WAAW,EACX,KAAK,EAGL,SAAS,EACT,IAAI,EACJ,OAAO,EACP,KAAK,IAAI,SAAS,EAClB,SAAS,EACT,QAAQ,EACR,QAAQ,EACR,IAAI,EACJ,MAAM,EACN,GAAG,EACH,MAAM,EAGN,IAAI,EACJ,KAAK,EAGL,aAAa,EAGb,WAAW,EACX,YAAY,EACZ,MAAM,EAGN,UAAU,EACV,MAAM,IAAI,YAAY,EACtB,YAAY,EACZ,UAAU,EACV,QAAQ,GACT,MAAM,cAAc,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { MediaConfig } from '../types';
|
|
2
|
+
export interface Attachment {
|
|
3
|
+
type: 'image' | 'audio' | 'file';
|
|
4
|
+
file: File;
|
|
5
|
+
previewUrl?: string;
|
|
6
|
+
}
|
|
7
|
+
export interface InputAreaProps {
|
|
8
|
+
isConnected: boolean;
|
|
9
|
+
placeholder?: string;
|
|
10
|
+
primaryColor?: string;
|
|
11
|
+
mediaConfig?: MediaConfig;
|
|
12
|
+
onSendMessage: (message: string) => void;
|
|
13
|
+
onSendAttachment?: (file: File, type: 'image' | 'audio' | 'file') => void;
|
|
14
|
+
onSendLocation?: (location: {
|
|
15
|
+
latitude: number;
|
|
16
|
+
longitude: number;
|
|
17
|
+
}) => void;
|
|
18
|
+
}
|
|
19
|
+
export declare function InputArea({ isConnected, placeholder, primaryColor, mediaConfig, onSendMessage, onSendAttachment, onSendLocation, }: InputAreaProps): import("react/jsx-runtime").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=InputArea.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputArea.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/InputArea.tsx"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAA;AAmB3C,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,CAAA;IAChC,IAAI,EAAE,IAAI,CAAA;IACV,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,MAAM,WAAW,cAAc;IAC7B,WAAW,EAAE,OAAO,CAAA;IACpB,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,WAAW,CAAC,EAAE,WAAW,CAAA;IACzB,aAAa,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IACxC,gBAAgB,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,MAAM,KAAK,IAAI,CAAA;IACzE,cAAc,CAAC,EAAE,CAAC,QAAQ,EAAE;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAA;CAC7E;AAED,wBAAgB,SAAS,CAAC,EACxB,WAAW,EACX,WAAqC,EACrC,YAAY,EACZ,WAAW,EACX,aAAa,EACb,gBAAgB,EAChB,cAAc,GACf,EAAE,cAAc,2CA0dhB"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { InputArea } from './InputArea';
|
|
3
|
+
declare const meta: {
|
|
4
|
+
title: string;
|
|
5
|
+
component: typeof InputArea;
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: string;
|
|
8
|
+
};
|
|
9
|
+
decorators: ((Story: import("storybook/internal/csf").PartialStoryFn<import("@storybook/react").ReactRenderer, {
|
|
10
|
+
isConnected: boolean;
|
|
11
|
+
placeholder?: string | undefined;
|
|
12
|
+
primaryColor?: string | undefined;
|
|
13
|
+
mediaConfig?: import("../types").MediaConfig | undefined;
|
|
14
|
+
onSendMessage: (message: string) => void;
|
|
15
|
+
onSendAttachment?: ((file: File, type: "image" | "audio" | "file") => void) | undefined;
|
|
16
|
+
onSendLocation?: ((location: {
|
|
17
|
+
latitude: number;
|
|
18
|
+
longitude: number;
|
|
19
|
+
}) => void) | undefined;
|
|
20
|
+
}>) => import("react/jsx-runtime").JSX.Element)[];
|
|
21
|
+
tags: string[];
|
|
22
|
+
argTypes: {
|
|
23
|
+
isConnected: {
|
|
24
|
+
control: "boolean";
|
|
25
|
+
description: string;
|
|
26
|
+
};
|
|
27
|
+
placeholder: {
|
|
28
|
+
control: "text";
|
|
29
|
+
description: string;
|
|
30
|
+
};
|
|
31
|
+
primaryColor: {
|
|
32
|
+
control: "color";
|
|
33
|
+
description: string;
|
|
34
|
+
};
|
|
35
|
+
mediaConfig: {
|
|
36
|
+
control: "object";
|
|
37
|
+
description: string;
|
|
38
|
+
};
|
|
39
|
+
onSendMessage: {
|
|
40
|
+
action: string;
|
|
41
|
+
};
|
|
42
|
+
onSendAttachment: {
|
|
43
|
+
action: string;
|
|
44
|
+
};
|
|
45
|
+
onSendLocation: {
|
|
46
|
+
action: string;
|
|
47
|
+
};
|
|
48
|
+
};
|
|
49
|
+
};
|
|
50
|
+
export default meta;
|
|
51
|
+
type Story = StoryObj<typeof meta>;
|
|
52
|
+
export declare const Default: Story;
|
|
53
|
+
export declare const Disconnected: Story;
|
|
54
|
+
export declare const CustomPlaceholder: Story;
|
|
55
|
+
export declare const CustomColor: Story;
|
|
56
|
+
export declare const AllMediaEnabled: Story;
|
|
57
|
+
export declare const OnlyText: Story;
|
|
58
|
+
export declare const OnlyImages: Story;
|
|
59
|
+
export declare const ImagesAndLocation: Story;
|
|
60
|
+
export declare const SmallFileLimit: Story;
|
|
61
|
+
//# sourceMappingURL=InputArea.stories.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InputArea.stories.d.ts","sourceRoot":"","sources":["../../../../src/chat-widget/components/InputArea.stories.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAQ,QAAQ,EAAE,MAAM,uBAAuB,CAAA;AAC3D,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAA;AAEvC,QAAA,MAAM,IAAI;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAmCwB,CAAA;AAElC,eAAe,IAAI,CAAA;AACnB,KAAK,KAAK,GAAG,QAAQ,CAAC,OAAO,IAAI,CAAC,CAAA;AAElC,eAAO,MAAM,OAAO,EAAE,KAOrB,CAAA;AAED,eAAO,MAAM,YAAY,EAAE,KAK1B,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,KAK/B,CAAA;AAED,eAAO,MAAM,WAAW,EAAE,KAKzB,CAAA;AAED,eAAO,MAAM,eAAe,EAAE,KAY7B,CAAA;AAED,eAAO,MAAM,QAAQ,EAAE,KAUtB,CAAA;AAED,eAAO,MAAM,UAAU,EAAE,KAYxB,CAAA;AAED,eAAO,MAAM,iBAAiB,EAAE,KAY/B,CAAA;AAED,eAAO,MAAM,cAAc,EAAE,KAY5B,CAAA"}
|