@athoscommerce/snap-preact 1.13.3-beta.168 → 1.13.3-beta.191
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/dist/cjs/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.js +3 -1
- package/dist/cjs/components/src/components/Molecules/ChatMessageText/ChatMessageText.js +2 -1
- package/dist/cjs/components/src/components/Molecules/ChatMessageUser/ChatMessageUser.js +4 -0
- package/dist/cjs/components/src/components/Molecules/ChatProductComparisonMessage/ChatProductComparisonMessage.js +1 -0
- package/dist/cjs/components/src/components/Molecules/ChatQuickview/ChatQuickview.js +514 -0
- package/dist/cjs/components/src/components/Molecules/{ChatProductQueryMessage → ChatQuickview}/index.js +1 -1
- package/dist/cjs/components/src/components/Molecules/ChatResultsDisplay/ChatResultsDisplay.js +2 -2
- package/dist/cjs/components/src/components/Molecules/Slideshow/Slideshow.js +47 -20
- package/dist/cjs/components/src/components/Organisms/Chat/Chat.js +12 -5
- package/dist/cjs/components/src/components/Organisms/Chat/Chat.lang.js +5 -0
- package/dist/cjs/components/src/components/Organisms/Chat/components/ChatAttachments.js +5 -4
- package/dist/cjs/components/src/components/Organisms/Chat/components/ChatComposer.js +3 -3
- package/dist/cjs/components/src/components/Organisms/Chat/components/ChatSideChat.js +3 -3
- package/dist/cjs/components/src/components/Organisms/Chat/components/chatAccentTheme.js +22 -20
- package/dist/cjs/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.js +44 -11
- package/dist/cjs/components/src/index.js +1 -1
- package/dist/cjs/components/src/providers/themeComponents.js +1 -1
- package/dist/cjs/src/Snap.js +13 -1
- package/dist/cjs/src/Templates/Stores/LibraryStore.js +2 -2
- package/dist/cjs/src/Templates/Stores/library/languages/ar.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/de.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/es.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/fr.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/hi.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/it.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/ja.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/ko.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/nl.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/pt.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/ru.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/tr.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/vi.js +45 -34
- package/dist/cjs/src/Templates/Stores/library/languages/zh.js +45 -34
- package/dist/cjs/src/create/createChatController.js +1 -0
- package/dist/esm/components/src/components/Atoms/Button/Button.d.ts +1 -1
- package/dist/esm/components/src/components/Atoms/Button/Button.d.ts.map +1 -1
- package/dist/esm/components/src/components/Molecules/ChatAttachmentContext/ChatAttachmentContext.d.ts +12 -5
- package/dist/esm/components/src/components/Molecules/ChatAttachmentContext/ChatAttachmentContext.d.ts.map +1 -1
- package/dist/esm/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.d.ts +13 -2
- package/dist/esm/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.d.ts.map +1 -1
- package/dist/esm/components/src/components/Molecules/ChatInspirationResultMessage/ChatInspirationResultMessage.js +3 -1
- package/dist/esm/components/src/components/Molecules/ChatMessageText/ChatMessageText.d.ts.map +1 -1
- package/dist/esm/components/src/components/Molecules/ChatMessageText/ChatMessageText.js +2 -1
- package/dist/esm/components/src/components/Molecules/ChatMessageUser/ChatMessageUser.d.ts +17 -3
- package/dist/esm/components/src/components/Molecules/ChatMessageUser/ChatMessageUser.d.ts.map +1 -1
- package/dist/esm/components/src/components/Molecules/ChatMessageUser/ChatMessageUser.js +4 -0
- package/dist/esm/components/src/components/Molecules/ChatProductComparisonMessage/ChatProductComparisonMessage.d.ts +7 -1
- package/dist/esm/components/src/components/Molecules/ChatProductComparisonMessage/ChatProductComparisonMessage.d.ts.map +1 -1
- package/dist/esm/components/src/components/Molecules/ChatProductComparisonMessage/ChatProductComparisonMessage.js +1 -0
- package/dist/esm/components/src/components/Molecules/ChatQuickview/ChatQuickview.d.ts +30 -0
- package/dist/esm/components/src/components/Molecules/ChatQuickview/ChatQuickview.d.ts.map +1 -0
- package/dist/esm/components/src/components/Molecules/ChatQuickview/ChatQuickview.js +508 -0
- package/dist/esm/components/src/components/Molecules/ChatQuickview/index.d.ts +2 -0
- package/dist/esm/components/src/components/Molecules/ChatQuickview/index.d.ts.map +1 -0
- package/dist/esm/components/src/components/Molecules/ChatQuickview/index.js +1 -0
- package/dist/esm/components/src/components/Molecules/ChatResultsDisplay/ChatResultsDisplay.js +2 -2
- package/dist/esm/components/src/components/Molecules/Slideshow/Slideshow.d.ts.map +1 -1
- package/dist/esm/components/src/components/Molecules/Slideshow/Slideshow.js +47 -20
- package/dist/esm/components/src/components/Organisms/Chat/Chat.d.ts.map +1 -1
- package/dist/esm/components/src/components/Organisms/Chat/Chat.js +12 -5
- package/dist/esm/components/src/components/Organisms/Chat/Chat.lang.d.ts +3 -0
- package/dist/esm/components/src/components/Organisms/Chat/Chat.lang.d.ts.map +1 -1
- package/dist/esm/components/src/components/Organisms/Chat/Chat.lang.js +5 -0
- package/dist/esm/components/src/components/Organisms/Chat/components/ChatAttachments.d.ts.map +1 -1
- package/dist/esm/components/src/components/Organisms/Chat/components/ChatAttachments.js +5 -4
- package/dist/esm/components/src/components/Organisms/Chat/components/ChatComposer.d.ts.map +1 -1
- package/dist/esm/components/src/components/Organisms/Chat/components/ChatComposer.js +3 -3
- package/dist/esm/components/src/components/Organisms/Chat/components/ChatSideChat.d.ts.map +1 -1
- package/dist/esm/components/src/components/Organisms/Chat/components/ChatSideChat.js +3 -3
- package/dist/esm/components/src/components/Organisms/Chat/components/chatAccentTheme.d.ts +1 -1
- package/dist/esm/components/src/components/Organisms/Chat/components/chatAccentTheme.d.ts.map +1 -1
- package/dist/esm/components/src/components/Organisms/Chat/components/chatAccentTheme.js +22 -20
- package/dist/esm/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.d.ts +5 -1
- package/dist/esm/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.d.ts.map +1 -1
- package/dist/esm/components/src/components/Organisms/QuickviewLayout/QuickviewLayout.js +44 -11
- package/dist/esm/components/src/index.d.ts +1 -1
- package/dist/esm/components/src/index.d.ts.map +1 -1
- package/dist/esm/components/src/index.js +1 -1
- package/dist/esm/components/src/providers/langComponents.d.ts +2 -2
- package/dist/esm/components/src/providers/langComponents.d.ts.map +1 -1
- package/dist/esm/components/src/providers/themeComponents.d.ts +7 -7
- package/dist/esm/components/src/providers/themeComponents.d.ts.map +1 -1
- package/dist/esm/components/src/providers/themeComponents.js +1 -1
- package/dist/esm/src/Snap.d.ts +1 -0
- package/dist/esm/src/Snap.d.ts.map +1 -1
- package/dist/esm/src/Snap.js +13 -1
- package/dist/esm/src/Templates/Stores/LibraryStore.d.ts +2 -2
- package/dist/esm/src/Templates/Stores/LibraryStore.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/LibraryStore.js +2 -2
- package/dist/esm/src/Templates/Stores/library/languages/ar.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/ar.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/de.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/de.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/es.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/es.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/fr.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/fr.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/hi.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/hi.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/it.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/it.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/ja.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/ja.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/ko.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/ko.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/nl.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/nl.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/pt.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/pt.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/ru.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/ru.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/tr.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/tr.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/vi.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/vi.js +45 -34
- package/dist/esm/src/Templates/Stores/library/languages/zh.d.ts.map +1 -1
- package/dist/esm/src/Templates/Stores/library/languages/zh.js +45 -34
- package/dist/esm/src/create/createChatController.js +1 -0
- package/package.json +12 -12
- package/dist/cjs/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.js +0 -577
- package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.d.ts +0 -38
- package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.d.ts.map +0 -1
- package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/ChatProductQueryMessage.js +0 -571
- package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/index.d.ts +0 -2
- package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/index.d.ts.map +0 -1
- package/dist/esm/components/src/components/Molecules/ChatProductQueryMessage/index.js +0 -1
|
@@ -30,6 +30,10 @@ const defaultStyles = ({ theme, slidesToShow = 1, slideWidth, gap = 16, overlayN
|
|
|
30
30
|
display: 'flex',
|
|
31
31
|
width: `100%`,
|
|
32
32
|
transition: 'transform 0.3s ease-in-out',
|
|
33
|
+
// keep the track on its own compositor layer at all times; otherwise Chrome promotes it
|
|
34
|
+
// when a transform transition starts and demotes it when it ends, re-rasterizing the
|
|
35
|
+
// (scaled) slide content each time, which reads as every image flickering
|
|
36
|
+
willChange: 'transform',
|
|
33
37
|
// Disable transition during dragging
|
|
34
38
|
'&.ss__slideshow__track--dragging': {
|
|
35
39
|
transition: 'none',
|
|
@@ -271,6 +275,8 @@ exports.Slideshow = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
271
275
|
return () => observer.disconnect();
|
|
272
276
|
}, []);
|
|
273
277
|
// Touch/Drag state
|
|
278
|
+
// drag positions live in refs so the document-level mousemove/mouseup listeners
|
|
279
|
+
// (registered once per drag) always read current values instead of stale state
|
|
274
280
|
const [isDragging, setIsDragging] = (0, hooks_1.useState)(false);
|
|
275
281
|
// mirrors `isDragging` state - the state drives renders (the dragging class, the transform,
|
|
276
282
|
// the autoplay effect), but the drag handlers below run through refs and can fire before
|
|
@@ -430,8 +436,17 @@ exports.Slideshow = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
430
436
|
return;
|
|
431
437
|
const diff = currentXRef.current - startXRef.current;
|
|
432
438
|
const threshold = getNavigationThreshold();
|
|
439
|
+
const slideWidthPx = (trackRef.current?.parentElement?.offsetWidth || 0) / visibleSlides;
|
|
433
440
|
if (Math.abs(diff) > threshold) {
|
|
434
|
-
|
|
441
|
+
const slidesDragged = slideWidthPx > 0 ? Math.round(Math.abs(diff) / slideWidthPx) : 0;
|
|
442
|
+
if (slidesDragged > slidesToMove) {
|
|
443
|
+
// long drags land on the slide group they were dragged to instead of snapping back
|
|
444
|
+
setCurrentIndex((prevIndex) => {
|
|
445
|
+
const newIndex = diff > 0 ? prevIndex - slidesDragged : prevIndex + slidesDragged;
|
|
446
|
+
return Math.max(0, Math.min(maxIndex, newIndex));
|
|
447
|
+
});
|
|
448
|
+
}
|
|
449
|
+
else if (diff > 0 && (loop || currentIndex > 0)) {
|
|
435
450
|
// Dragged right - go to previous
|
|
436
451
|
goToPrevious();
|
|
437
452
|
}
|
|
@@ -516,6 +531,16 @@ exports.Slideshow = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
516
531
|
}, autoPlayInterval);
|
|
517
532
|
}
|
|
518
533
|
};
|
|
534
|
+
// The browser fires a click after a drag's mouseup/touchend. Catch it in the capture phase on
|
|
535
|
+
// the container so it never reaches slide content that carries its own onClick (e.g. product
|
|
536
|
+
// cards that open a quickview) — those handlers can't know a drag just happened.
|
|
537
|
+
const handleContainerClickCapture = (event) => {
|
|
538
|
+
if (!hasDraggedRef.current)
|
|
539
|
+
return;
|
|
540
|
+
hasDraggedRef.current = false;
|
|
541
|
+
event.stopPropagation();
|
|
542
|
+
event.preventDefault();
|
|
543
|
+
};
|
|
519
544
|
// Handle image click
|
|
520
545
|
const handleSlideClick = (slide, index) => {
|
|
521
546
|
if (slide.onClick && !isDragging && !hasDraggedRef.current) {
|
|
@@ -662,27 +687,29 @@ exports.Slideshow = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
662
687
|
}, { activeBreakpoint: globalTheme?.activeBreakpoint });
|
|
663
688
|
return ((0, jsx_runtime_1.jsx)(providers_1.CacheProvider, { children: (0, jsx_runtime_1.jsxs)("div", { ...styling, className: (0, classnames_1.default)('ss__slideshow', className), ref: slideshowRef, role: "region", "aria-label": ariaLabel, "aria-labelledby": ariaLabelledBy, "aria-roledescription": "slideshow", onMouseEnter: handleMouseEnter, onMouseLeave: handleMouseLeave,
|
|
664
689
|
// @ts-ignore - ignore
|
|
665
|
-
onKeyDown: handleKeyDown, tabIndex: 0, children: [(0, jsx_runtime_1.jsx)("div", { className: "ss__slideshow__sr-only", ...mergedLang.srInstructions.all }), (0, jsx_runtime_1.jsx)("div", { className: "ss__slideshow__container",
|
|
690
|
+
onKeyDown: handleKeyDown, tabIndex: 0, children: [(0, jsx_runtime_1.jsx)("div", { className: "ss__slideshow__sr-only", ...mergedLang.srInstructions.all }), (0, jsx_runtime_1.jsx)("div", { className: "ss__slideshow__container",
|
|
691
|
+
// @ts-ignore - capture-phase click
|
|
692
|
+
onClickCapture: touchDragging ? handleContainerClickCapture : undefined,
|
|
693
|
+
// Touch events
|
|
694
|
+
// @ts-ignore - touch events
|
|
695
|
+
onTouchStart: touchDragging ? (event) => handleDragStart(event.touches[0].clientX) : undefined,
|
|
696
|
+
// @ts-ignore - touch events
|
|
697
|
+
onTouchMove: touchDragging
|
|
698
|
+
? (event) => {
|
|
699
|
+
if (isDraggingRef.current) {
|
|
700
|
+
event.preventDefault(); // Prevent scrolling while dragging
|
|
701
|
+
}
|
|
702
|
+
const touch = event.touches[0];
|
|
703
|
+
handleDragMove(touch.clientX);
|
|
704
|
+
}
|
|
705
|
+
: undefined, onTouchEnd: touchDragging ? handleDragEnd : undefined,
|
|
706
|
+
// mouse events for desktop dragging
|
|
707
|
+
// move/up are bound on document in handleMouseDown so the drag keeps tracking outside the container
|
|
708
|
+
// @ts-ignore - mouse events
|
|
709
|
+
onMouseDown: touchDragging ? handleMouseDown : undefined, children: (0, jsx_runtime_1.jsx)("div", { ref: trackRef, className: (0, classnames_1.default)('ss__slideshow__track', {
|
|
666
710
|
'ss__slideshow__track--dragging': isDragging,
|
|
667
711
|
'ss__slideshow__track--centered': centerInsufficientSlides && totalSlides <= computedSlidesToShow,
|
|
668
|
-
}), style: { transform: `translateX(${translateX}${translateUnit})` }, role: "group", "aria-label": `Slide group ${currentIndex} of ${totalDots}`,
|
|
669
|
-
// Touch events
|
|
670
|
-
// @ts-ignore - touch events
|
|
671
|
-
onTouchStart: touchDragging ? (event) => handleDragStart(event.touches[0].clientX) : undefined,
|
|
672
|
-
// @ts-ignore - touch events
|
|
673
|
-
onTouchMove: touchDragging
|
|
674
|
-
? (event) => {
|
|
675
|
-
if (isDraggingRef.current) {
|
|
676
|
-
event.preventDefault(); // Prevent scrolling while dragging
|
|
677
|
-
}
|
|
678
|
-
const touch = event.touches[0];
|
|
679
|
-
handleDragMove(touch.clientX);
|
|
680
|
-
}
|
|
681
|
-
: undefined, onTouchEnd: touchDragging ? handleDragEnd : undefined,
|
|
682
|
-
// mouse events for desktop dragging
|
|
683
|
-
// move/up are bound on document in handleMouseDown so the drag keeps tracking outside the track
|
|
684
|
-
// @ts-ignore - mouse events
|
|
685
|
-
onMouseDown: touchDragging ? handleMouseDown : undefined, children: normalizedSlides.map((slide, index) => {
|
|
712
|
+
}), style: { transform: `translateX(${translateX}${translateUnit})` }, role: "group", "aria-label": `Slide group ${currentIndex} of ${totalDots}`, children: normalizedSlides.map((slide, index) => {
|
|
686
713
|
const isVisible = index >= currentIndex && index < currentIndex + computedSlidesToShow;
|
|
687
714
|
const hasClickHandler = !!slide.onClick;
|
|
688
715
|
const hasContent = !!slide.content;
|
|
@@ -399,7 +399,6 @@ exports.ChatOrganism = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
399
399
|
position: 'right',
|
|
400
400
|
hideMessageTypeIndicatorText: false,
|
|
401
401
|
buttonBelowMessage: false,
|
|
402
|
-
poweredByText: 'Powered by Athos Commerce.',
|
|
403
402
|
};
|
|
404
403
|
let props = (0, utilities_1.mergeProps)('chat', globalTheme, defaultProps, properties);
|
|
405
404
|
const { overrideElement, shouldRenderDefault } = (0, hooks_2.useCustomComponentOverride)('chat', props);
|
|
@@ -501,7 +500,13 @@ exports.ChatOrganism = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
501
500
|
const sideChatTypes = isMobile
|
|
502
501
|
? ['inspirationResult', ...(isFirstMobileComparison ? ['productComparison'] : []), ...(mobileProductInfoOpen ? ['productQuery'] : [])]
|
|
503
502
|
: ['inspirationResult', 'productComparison', 'productQuery'];
|
|
504
|
-
|
|
503
|
+
// productQuery panels are additionally driven by the chat quickview store — the controller's
|
|
504
|
+
// `show()` opening the store is what opens the window, and `close()` is what dismisses it
|
|
505
|
+
const quickviewOpen = Boolean(controller.quickviewManager?.store.isOpen);
|
|
506
|
+
const shouldShowSideChat = activeMessage &&
|
|
507
|
+
sideChatTypes.includes(activeMessage?.messageType) &&
|
|
508
|
+
store.currentChat?.dismissedSideChatMessageId !== activeMessage.id &&
|
|
509
|
+
(activeMessage.messageType !== 'productQuery' || quickviewOpen);
|
|
505
510
|
const hasSideChat = !!shouldShowSideChat;
|
|
506
511
|
// Lock body scrolling (wheel + touch) to the chat while it is open. Mobile only —
|
|
507
512
|
// on desktop the chat is a side panel and the page behind it stays scrollable.
|
|
@@ -514,7 +519,8 @@ exports.ChatOrganism = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
514
519
|
if (e.key !== 'Escape')
|
|
515
520
|
return;
|
|
516
521
|
if (store.currentChat?.activeMessage && shouldShowSideChat) {
|
|
517
|
-
|
|
522
|
+
// dismiss through the controller so the product quickview closes with the window
|
|
523
|
+
controller.dismissSideChat();
|
|
518
524
|
}
|
|
519
525
|
else {
|
|
520
526
|
controller.handlers.button.click();
|
|
@@ -547,7 +553,8 @@ exports.ChatOrganism = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
547
553
|
item.requestType !== 'productComparison');
|
|
548
554
|
productAttachmentsToRemove.forEach((item) => store.currentChat?.attachments.remove(item.id));
|
|
549
555
|
setMobileProductInfoOpen(false);
|
|
550
|
-
|
|
556
|
+
// dismiss through the controller so the product quickview closes with the window
|
|
557
|
+
controller.dismissSideChat();
|
|
551
558
|
};
|
|
552
559
|
const requestType = store.currentChat?.requestType;
|
|
553
560
|
const loadingVerbLangKey = requestType ? LOADING_VERB_LANG_KEYS[requestType] : undefined;
|
|
@@ -609,7 +616,7 @@ exports.ChatOrganism = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
609
616
|
// On mobile, interacting with the primary chat (header or anywhere within)
|
|
610
617
|
// dismisses the secondary panel. Capture phase so it fires even when an
|
|
611
618
|
// inner control stops propagation.
|
|
612
|
-
onClickCapture: isMobile && shouldShowSideChat ? () => dismissSideChat() : undefined, children: [(0, jsx_runtime_1.jsxs)("div", { className: 'ss__chat__header', children: [(0, jsx_runtime_1.jsxs)("div", { className: "ss__chat__header__title", children: [logo ? (0, jsx_runtime_1.jsx)(Image_1.Image, { className: "ss__chat__header__title__logo", src: logo, alt: title || '
|
|
619
|
+
onClickCapture: isMobile && shouldShowSideChat ? () => dismissSideChat() : undefined, children: [(0, jsx_runtime_1.jsxs)("div", { className: 'ss__chat__header', children: [(0, jsx_runtime_1.jsxs)("div", { className: "ss__chat__header__title", children: [logo ? ((0, jsx_runtime_1.jsx)(Image_1.Image, { className: "ss__chat__header__title__logo", src: logo, alt: title || (0, Chat_lang_1.langAttrOf)(lang.headerLogo, 'alt') || '' })) : null, (0, jsx_runtime_1.jsxs)("div", { className: "ss__chat__header__title__text", children: [title ? (0, jsx_runtime_1.jsx)("div", { className: "ss__chat__header__title__text__primary", children: title }) : null, subtitle ? (0, jsx_runtime_1.jsx)("div", { className: "ss__chat__header__title__text__secondary", children: subtitle }) : null] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "ss__chat__header__buttons", children: [(0, jsx_runtime_1.jsx)(Button_1.Button, { className: "ss__chat__header__button--new", "aria-label": (0, Chat_lang_1.langAttrOf)(lang.newChatButton, 'aria-label'), icon: { icon: controller.store.initChatLoading ? 'spinner' : 'plus-rounded', title: (0, Chat_lang_1.langAttrOf)(lang.newChatButton, 'title') }, onClick: () => controller.store.createChat() }), store.chats.length > 1 && (0, jsx_runtime_1.jsx)(ChatHistory_1.ChatHistory, { ...subProps.history, controller: controller }), (0, jsx_runtime_1.jsx)(Button_1.Button, { className: "ss__chat__header__button--close", "aria-label": (0, Chat_lang_1.langAttrOf)(lang.closeChatButton, 'aria-label'), icon: { icon: 'close-rounded', title: (0, Chat_lang_1.langAttrOf)(lang.closeChatButton, 'title') }, onClick: () => controller.handlers.button.click() })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "ss__chat__content", children: [(0, jsx_runtime_1.jsx)(ChatSessionFeedback_1.ChatSessionFeedback, { ...subProps.sessionFeedback, controller: controller }), (0, jsx_runtime_1.jsx)("div", { ref: headerRef, className: (0, classnames_1.default)('ss__chat__content__header', {
|
|
613
620
|
'ss__chat__content__header--overlay': messagesOverflow,
|
|
614
621
|
}), children: (0, jsx_runtime_1.jsx)(ChatComparisonsTray_1.ChatComparisonsTray, { ...subProps.comparisonsTray, controller: controller }) }), (0, jsx_runtime_1.jsx)(ChatMessages_1.ChatMessages, { ...subProps.messages, controller: controller, messagesContainerRef: messagesContainerRef, messagesEndRef: messagesEndRef, mobile: isMobile, avatarCharacter: avatarCharacter, avatarImage: avatarImage, sideChatOpen: !!shouldShowSideChat, onProductQuickView: () => setMobileProductInfoOpen(true), scrollToBottom: scrollToBottom, scrollToBottomIfNear: scrollToBottomIfNear, showNewMessages: showNewMessages, setShowNewMessages: setShowNewMessages, messagesOverflow: messagesOverflow }), (0, jsx_runtime_1.jsx)(ChatLoadingIndicator_1.ChatLoadingIndicator, { ...subProps.loadingIndicator, loading: store.loading, verbs: loadingVerbs }), !store.currentChat?.isExpired ? ((0, jsx_runtime_1.jsxs)("div", { className: "ss__chat__content__footer", ref: footerRef, ...dragHandlers, children: [(store.error || store.chatEnabled === false) && ((0, jsx_runtime_1.jsx)("div", { className: "ss__chat__error", children: store.error?.message || (0, Chat_lang_1.langTextOf)(lang.chatUnavailableMessage) })), (0, jsx_runtime_1.jsx)(ChatTopicDrift_1.ChatTopicDrift, { ...subProps.topicDrift, controller: controller, variant: "sessionLimit" }), (0, jsx_runtime_1.jsx)(ChatFacetsBar_1.ChatFacetsBar, { ...subProps.facetsBar, controller: controller, chatRef: chatRef, multiselectFacets: multiselectFacets }), (0, jsx_runtime_1.jsx)(ChatAttachments_1.ChatAttachments, { ...subProps.attachments, controller: controller, activeMessage: activeMessage, sideChatOpen: !!shouldShowSideChat, mobile: isMobile, onProductQuickView: () => setMobileProductInfoOpen(true), onProductAttachmentsRemoved: () => setMobileProductInfoOpen(false) }), (0, jsx_runtime_1.jsx)(ChatTopicDrift_1.ChatTopicDrift, { ...subProps.topicDrift, controller: controller, variant: "drift" }), (0, jsx_runtime_1.jsx)(ChatComposer_1.ChatComposer, { ...subProps.composer, controller: controller, fileInputRef: fileInputRef, onUserSend: () => {
|
|
615
622
|
if (isMobile && mobileProductInfoOpen) {
|
|
@@ -10,6 +10,9 @@ exports.chatDefaultLang = {
|
|
|
10
10
|
closeChatButton: {
|
|
11
11
|
attributes: { 'aria-label': 'Close chat', title: 'Close Chat' },
|
|
12
12
|
},
|
|
13
|
+
headerLogo: {
|
|
14
|
+
attributes: { alt: 'Chat logo' },
|
|
15
|
+
},
|
|
13
16
|
newChatButton: {
|
|
14
17
|
attributes: { 'aria-label': 'New chat', title: 'New Chat' },
|
|
15
18
|
},
|
|
@@ -69,6 +72,7 @@ exports.chatDefaultLang = {
|
|
|
69
72
|
attachmentCompareTitle: { value: 'Compare these products' },
|
|
70
73
|
attachmentAskProductTitle: { value: 'Ask about this product' },
|
|
71
74
|
attachmentImageSimilarTitle: { value: 'Find products similar to this image:' },
|
|
75
|
+
attachmentImageName: { value: 'Image' },
|
|
72
76
|
topicDriftScopeMessage: { value: "I'm here to help with shopping" },
|
|
73
77
|
topicDriftScopeSubMessage: { value: 'Try asking about products, comparisons, or recommendations' },
|
|
74
78
|
topicDriftMessage: { value: 'Looking for something new?' },
|
|
@@ -89,6 +93,7 @@ exports.chatDefaultLang = {
|
|
|
89
93
|
attributes: { 'aria-label': 'Send Message', title: 'Send Message' },
|
|
90
94
|
},
|
|
91
95
|
dropOverlayText: { value: 'Drop image to upload' },
|
|
96
|
+
poweredByText: { value: 'Powered by Athos Commerce.' },
|
|
92
97
|
disclaimerText: { value: 'AI-powered assistant. It sometimes makes mistakes. Avoid sharing personal data.' },
|
|
93
98
|
privacyPolicyLinkText: { value: 'Privacy Policy' },
|
|
94
99
|
expiredMessage: { value: 'This chat is expired. Please start a new chat.' },
|
|
@@ -69,7 +69,8 @@ exports.ChatAttachments = (0, mobx_react_lite_1.observer)((props) => {
|
|
|
69
69
|
const dismissProductAttachment = (id) => {
|
|
70
70
|
store.currentChat?.attachments.remove(id);
|
|
71
71
|
props.onProductAttachmentsRemoved && props.onProductAttachmentsRemoved();
|
|
72
|
-
|
|
72
|
+
// dismiss through the controller so a product quickview closes with the window
|
|
73
|
+
controller.dismissSideChat();
|
|
73
74
|
};
|
|
74
75
|
const productItems = productAttachments.map((item) => {
|
|
75
76
|
const remove = () => dismissProductAttachment(item.id);
|
|
@@ -83,7 +84,7 @@ exports.ChatAttachments = (0, mobx_react_lite_1.observer)((props) => {
|
|
|
83
84
|
});
|
|
84
85
|
const imageItems = imageAttachments.map((item) => ({
|
|
85
86
|
id: item.id,
|
|
86
|
-
name: item.fileName || '
|
|
87
|
+
name: item.fileName || (0, Chat_lang_1.langTextOf)(lang.attachmentImageName) || '',
|
|
87
88
|
imageUrl: item.base64 || item.thumbnailUrl || '',
|
|
88
89
|
isLoading: item.state === 'loading',
|
|
89
90
|
hasError: !!item.error,
|
|
@@ -95,10 +96,10 @@ exports.ChatAttachments = (0, mobx_react_lite_1.observer)((props) => {
|
|
|
95
96
|
const imageTitle = (imageItems.length > 0 && !hasImageError ? (0, Chat_lang_1.langTextOf)(lang.attachmentImageSimilarTitle) : '') || '';
|
|
96
97
|
return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [comparisonItems.length > 0 && ((0, jsx_runtime_1.jsx)(ChatAttachmentContext_1.ChatAttachmentContext, { ...subProps.attachmentContext, title: (0, Chat_lang_1.langTextOf)(lang.attachmentCompareTitle) || '', items: comparisonItems, onClose: () => {
|
|
97
98
|
store.currentChat?.comparisons.resetCommitted();
|
|
98
|
-
|
|
99
|
+
controller.dismissSideChat();
|
|
99
100
|
} })), productItems.length > 0 && ((0, jsx_runtime_1.jsx)(ChatAttachmentContext_1.ChatAttachmentContext, { ...subProps.attachmentContext, title: productTitle, items: productItems, onClose: () => {
|
|
100
101
|
productAttachments.forEach((item) => store.currentChat?.attachments.remove(item.id));
|
|
101
102
|
props.onProductAttachmentsRemoved && props.onProductAttachmentsRemoved();
|
|
102
|
-
|
|
103
|
+
controller.dismissSideChat();
|
|
103
104
|
} })), imageItems.length > 0 && (0, jsx_runtime_1.jsx)(ChatAttachmentContext_1.ChatAttachmentContext, { ...subProps.attachmentContext, title: imageTitle, items: imageItems })] }));
|
|
104
105
|
});
|
|
@@ -43,7 +43,8 @@ const defaultStyles = ({ primaryColorBg, primaryColorFg }) => {
|
|
|
43
43
|
'input[type="text"]': {
|
|
44
44
|
padding: '0.5em 0',
|
|
45
45
|
margin: '0 0 0 1em',
|
|
46
|
-
flex: '1 0
|
|
46
|
+
flex: '1 1 0%',
|
|
47
|
+
minWidth: 0,
|
|
47
48
|
border: 'none',
|
|
48
49
|
backgroundColor: 'transparent',
|
|
49
50
|
'&::placeholder': {
|
|
@@ -113,7 +114,6 @@ exports.ChatComposer = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
113
114
|
const globalTheme = (0, providers_1.useTheme)();
|
|
114
115
|
const globalTreePath = (0, providers_1.useTreePath)();
|
|
115
116
|
const defaultProps = {
|
|
116
|
-
poweredByText: 'Powered by Athos Commerce.',
|
|
117
117
|
treePath: globalTreePath,
|
|
118
118
|
};
|
|
119
119
|
const props = (0, utilities_1.mergeProps)('chatComposer', globalTheme, defaultProps, properties);
|
|
@@ -162,5 +162,5 @@ exports.ChatComposer = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
162
162
|
return;
|
|
163
163
|
controller.search();
|
|
164
164
|
onUserSend && onUserSend();
|
|
165
|
-
} }) })] }), (0, jsx_runtime_1.jsx)("div", { className: 'ss__chat__disclaimer', children: (0, jsx_runtime_1.jsxs)("i", { children: [poweredByText, " ", (0, Chat_lang_1.langTextOf)(lang.disclaimerText), privacyPolicyUrl && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [' ', (0, jsx_runtime_1.jsx)("a", { href: privacyPolicyUrl, target: "_blank", rel: "noopener noreferrer", children: (0, Chat_lang_1.langTextOf)(lang.privacyPolicyLinkText) })] }))] }) })] }) }));
|
|
165
|
+
} }) })] }), (0, jsx_runtime_1.jsx)("div", { className: 'ss__chat__disclaimer', children: (0, jsx_runtime_1.jsxs)("i", { children: [poweredByText ?? (0, Chat_lang_1.langTextOf)(lang.poweredByText), " ", (0, Chat_lang_1.langTextOf)(lang.disclaimerText), privacyPolicyUrl && ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [' ', (0, jsx_runtime_1.jsx)("a", { href: privacyPolicyUrl, target: "_blank", rel: "noopener noreferrer", children: (0, Chat_lang_1.langTextOf)(lang.privacyPolicyLinkText) })] }))] }) })] }) }));
|
|
166
166
|
});
|
|
@@ -16,7 +16,7 @@ const hooks_2 = require("../../../../hooks");
|
|
|
16
16
|
const Button_1 = require("../../../Atoms/Button");
|
|
17
17
|
const ChatInspirationResultMessage_1 = require("../../../Molecules/ChatInspirationResultMessage");
|
|
18
18
|
const ChatProductComparisonMessage_1 = require("../../../Molecules/ChatProductComparisonMessage/ChatProductComparisonMessage");
|
|
19
|
-
const
|
|
19
|
+
const ChatQuickview_1 = require("../../../Molecules/ChatQuickview/ChatQuickview");
|
|
20
20
|
const useChatGestures_1 = require("../hooks/useChatGestures");
|
|
21
21
|
const Chat_lang_1 = require("../Chat.lang");
|
|
22
22
|
const defaultStyles = ({ mobile, footerHeight, primaryColorBg }) => {
|
|
@@ -135,7 +135,7 @@ exports.ChatSideChat = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
135
135
|
theme: props.theme,
|
|
136
136
|
treePath,
|
|
137
137
|
},
|
|
138
|
-
|
|
138
|
+
quickview: {
|
|
139
139
|
disableStyles,
|
|
140
140
|
theme: props.theme,
|
|
141
141
|
treePath,
|
|
@@ -158,7 +158,7 @@ exports.ChatSideChat = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
158
158
|
case 'productComparison':
|
|
159
159
|
return ((0, jsx_runtime_1.jsx)(ChatProductComparisonMessage_1.ChatProductComparisonMessage, { ...subProps.productComparisonMessage, chatItem: activeMessage, controller: controller }));
|
|
160
160
|
case 'productQuery':
|
|
161
|
-
return ((0, jsx_runtime_1.jsx)(
|
|
161
|
+
return ((0, jsx_runtime_1.jsx)(ChatQuickview_1.ChatQuickview, { ...subProps.quickview, chatItem: activeMessage, controller: controller, primaryColor: primaryColorBg, primaryColorText: primaryColorFg }));
|
|
162
162
|
default:
|
|
163
163
|
return null;
|
|
164
164
|
}
|
|
@@ -4,7 +4,7 @@ exports.chatAccentThemeComponents = void 0;
|
|
|
4
4
|
const utilities_1 = require("../../../../utilities");
|
|
5
5
|
/**
|
|
6
6
|
* Accent styling for buttons living inside child components (ChatResult's cart /
|
|
7
|
-
* inquire icons and
|
|
7
|
+
* inquire icons and ChatQuickview's action buttons) — injected through
|
|
8
8
|
* the theme so each child applies it via its own style pipeline instead of the
|
|
9
9
|
* organism reaching in with `!important` overrides.
|
|
10
10
|
*/
|
|
@@ -30,27 +30,29 @@ const chatAccentThemeComponents = ({ primaryAccentColorBg, primaryAccentColorFg,
|
|
|
30
30
|
},
|
|
31
31
|
},
|
|
32
32
|
},
|
|
33
|
-
|
|
33
|
+
chatQuickview: {
|
|
34
34
|
style: {
|
|
35
|
-
'.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
stroke: primaryAccentColorFg,
|
|
42
|
-
},
|
|
43
|
-
'&:not(.ss__button--disabled):hover': {
|
|
44
|
-
background: new utilities_1.Colour(primaryAccentColorBg).mixBlack(),
|
|
45
|
-
},
|
|
35
|
+
'.ss__quickview__add-to-cart.ss__button': {
|
|
36
|
+
background: primaryAccentColorBg,
|
|
37
|
+
color: primaryAccentColorFg,
|
|
38
|
+
svg: {
|
|
39
|
+
fill: primaryAccentColorFg,
|
|
40
|
+
stroke: primaryAccentColorFg,
|
|
46
41
|
},
|
|
47
|
-
'.
|
|
48
|
-
background:
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
42
|
+
'&:not(.ss__button--disabled):hover': {
|
|
43
|
+
background: new utilities_1.Colour(primaryAccentColorBg).mixBlack(),
|
|
44
|
+
},
|
|
45
|
+
},
|
|
46
|
+
'.ss__quickview__more-info.ss__button, .ss__quickview__similar.ss__button, .ss__quickview__discuss.ss__button': {
|
|
47
|
+
background: secondaryAccentColorBg,
|
|
48
|
+
color: secondaryAccentColorFg,
|
|
49
|
+
border: `1px solid ${secondaryAccentColorFg}`,
|
|
50
|
+
svg: {
|
|
51
|
+
fill: secondaryAccentColorFg,
|
|
52
|
+
stroke: secondaryAccentColorFg,
|
|
53
|
+
},
|
|
54
|
+
'&:not(.ss__button--disabled):hover': {
|
|
55
|
+
background: new utilities_1.Colour(secondaryAccentColorBg).mixBlack(),
|
|
54
56
|
},
|
|
55
57
|
},
|
|
56
58
|
},
|
|
@@ -258,7 +258,7 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
258
258
|
hideBadge: false,
|
|
259
259
|
};
|
|
260
260
|
const props = (0, utilities_1.mergeProps)('quickviewLayout', globalTheme, defaultProps, properties);
|
|
261
|
-
const { quickviewManager, className, internalClassName, disableStyles, treePath, hideBadge, column1, column2, column3, column4, recommendation } = props;
|
|
261
|
+
const { quickviewManager, className, internalClassName, disableStyles, treePath, hideBadge, variantDropdownType, column1, column2, column3, column4, recommendation, } = props;
|
|
262
262
|
// NOTE: the `!shouldRenderDefault` return lives below the last hook call — every hook in this
|
|
263
263
|
// component must run unconditionally on every render (shouldRenderDefault can flip while
|
|
264
264
|
// mounted, e.g. when a pending customComponent import resolves or fails).
|
|
@@ -281,6 +281,12 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
281
281
|
moreInfoButton: {
|
|
282
282
|
value: 'More info',
|
|
283
283
|
},
|
|
284
|
+
similarButton: {
|
|
285
|
+
value: 'Similar',
|
|
286
|
+
},
|
|
287
|
+
discussButton: {
|
|
288
|
+
value: 'Discuss',
|
|
289
|
+
},
|
|
284
290
|
loadingText: {
|
|
285
291
|
value: 'Loading…',
|
|
286
292
|
},
|
|
@@ -343,7 +349,8 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
343
349
|
// is within it).
|
|
344
350
|
(0, hooks_1.useEffect)(() => {
|
|
345
351
|
const isOpenNow = Boolean(quickviewManager?.store?.isOpen);
|
|
346
|
-
|
|
352
|
+
// inline embeds (e.g. the chat secondary window) are not modal — Escape must not close them
|
|
353
|
+
if (!shouldRenderDefault || !isOpenNow || props.inline)
|
|
347
354
|
return;
|
|
348
355
|
const onKey = (e) => {
|
|
349
356
|
if (e.key === 'Escape' && !galleryOpen) {
|
|
@@ -352,7 +359,7 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
352
359
|
};
|
|
353
360
|
window.addEventListener('keydown', onKey);
|
|
354
361
|
return () => window.removeEventListener('keydown', onKey);
|
|
355
|
-
}, [shouldRenderDefault, quickviewManager?.store?.isOpen, galleryOpen]);
|
|
362
|
+
}, [shouldRenderDefault, quickviewManager?.store?.isOpen, galleryOpen, props.inline]);
|
|
356
363
|
// Recommendation modules. `findModule` runs inside .map()/recursion and must not call hooks, so
|
|
357
364
|
// resolve every referenced profile's controller + components here (stable order) and let
|
|
358
365
|
// findModule read from this map. Mirrors Organisms/NoResults.
|
|
@@ -449,12 +456,18 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
449
456
|
};
|
|
450
457
|
// Dialog semantics + focus trap for the quickview content, following the autocomplete
|
|
451
458
|
// containers (AutocompleteModal/AutocompleteSlideout): useA11y traps Tab within the
|
|
452
|
-
// content and wires Escape to the callback above.
|
|
459
|
+
// content and wires Escape to the callback above. Inline embeds (e.g. the chat secondary
|
|
460
|
+
// window) are part of the surrounding page — no dialog role and no focus trap, which
|
|
461
|
+
// would otherwise stop the shopper tabbing out to the chat composer.
|
|
453
462
|
const contentProps = {
|
|
454
463
|
className: 'ss__quickview__content',
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
464
|
+
...(props.inline
|
|
465
|
+
? {}
|
|
466
|
+
: {
|
|
467
|
+
role: 'dialog',
|
|
468
|
+
'aria-modal': 'true',
|
|
469
|
+
ref: (e) => (0, hooks_2.useA11y)(e, 0, true, handleEscape),
|
|
470
|
+
}),
|
|
458
471
|
...mergedLang.quickview?.attributes,
|
|
459
472
|
};
|
|
460
473
|
// Prefer `product.display` so the displayed name/image/attributes reflect the
|
|
@@ -549,17 +562,23 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
549
562
|
// the selection whose field matches (e.g. `variantSelection.color`). The field also matches its
|
|
550
563
|
// component-name form (`color_family` → `color-family`). A bare `variantSelection` module is
|
|
551
564
|
// not supported.
|
|
565
|
+
// `variantDropdownType` swaps the component for selections that aren't swatches.
|
|
566
|
+
const renderSelection = (selection) => {
|
|
567
|
+
const isSwatch = selection.type === 'swatch' || selection.type === 'swatches';
|
|
568
|
+
const type = variantDropdownType && !isSwatch ? variantDropdownType : selection.type;
|
|
569
|
+
return ((0, jsx_runtime_1.jsxs)("div", { className: "ss__quickview__variant", children: [(0, jsx_runtime_1.jsx)("div", { className: "ss__quickview__variant-title", children: selection.label || selection.field }), (0, jsx_runtime_1.jsx)(VariantSelection_1.VariantSelection, { selection: selection, type: type, theme: props.theme, treePath: treePath, ...(0, utilities_1.defined)({ disableStyles }) })] }, selection.field));
|
|
570
|
+
};
|
|
552
571
|
if (module == 'variantSelections') {
|
|
553
572
|
if (!selections || selections.length === 0)
|
|
554
573
|
return null;
|
|
555
|
-
return (
|
|
574
|
+
return (0, jsx_runtime_1.jsx)("div", { className: "ss__quickview__variants", children: selections.map((selection) => renderSelection(selection)) });
|
|
556
575
|
}
|
|
557
576
|
if (module.startsWith('variantSelection.')) {
|
|
558
577
|
const name = module.slice('variantSelection.'.length);
|
|
559
578
|
const selection = selections?.find((selection) => selection.field === name || (0, snap_toolbox_1.fieldNameToComponentName)(selection.field) === name);
|
|
560
579
|
if (!name || !selection)
|
|
561
580
|
return null;
|
|
562
|
-
return (
|
|
581
|
+
return renderSelection(selection);
|
|
563
582
|
}
|
|
564
583
|
if (module == 'button.add-to-cart') {
|
|
565
584
|
if (!product)
|
|
@@ -569,7 +588,7 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
569
588
|
if (module == 'button.more-info') {
|
|
570
589
|
if (!url)
|
|
571
590
|
return null;
|
|
572
|
-
return ((0, jsx_runtime_1.jsx)(Button_1.Button, { name: "more-info", internalClassName: "
|
|
591
|
+
return ((0, jsx_runtime_1.jsx)(Button_1.Button, { name: "more-info", internalClassName: "ss__quickview__more-info", lang: { button: lang.moreInfoButton }, onClick: (e) => {
|
|
573
592
|
// track the redirect to the product page as a quickview clickThrough
|
|
574
593
|
// before navigating away (delegated with `quickView: true`)
|
|
575
594
|
if (product) {
|
|
@@ -578,6 +597,20 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
578
597
|
window.location.href = url;
|
|
579
598
|
}, theme: props.theme, treePath: treePath, ...(0, utilities_1.defined)({ disableStyles }) }));
|
|
580
599
|
}
|
|
600
|
+
// Chat-only modules: `button.similar` and `button.discuss` forward to the chat controller
|
|
601
|
+
// that opened the quickview. They render nothing for non-chat source controllers, so a
|
|
602
|
+
// layout carrying them stays safe to share across surfaces.
|
|
603
|
+
if (module == 'button.similar' || module == 'button.discuss') {
|
|
604
|
+
const chatController = quickviewManager.sourceController?.type === 'chat' ? quickviewManager.sourceController : undefined;
|
|
605
|
+
if (!product || !chatController)
|
|
606
|
+
return null;
|
|
607
|
+
if (module == 'button.similar') {
|
|
608
|
+
if (!chatController.store.features?.similarProducts?.enabled)
|
|
609
|
+
return null;
|
|
610
|
+
return ((0, jsx_runtime_1.jsx)(Button_1.Button, { name: "similar", internalClassName: "ss__quickview__similar", lang: { button: lang.similarButton }, onClick: () => chatController.productSimilar(product), theme: props.theme, treePath: treePath, ...(0, utilities_1.defined)({ disableStyles }) }));
|
|
611
|
+
}
|
|
612
|
+
return ((0, jsx_runtime_1.jsx)(Button_1.Button, { name: "discuss", internalClassName: "ss__quickview__discuss", lang: { button: lang.discussButton }, onClick: () => chatController.productQuery(product), theme: props.theme, treePath: treePath, ...(0, utilities_1.defined)({ disableStyles }) }));
|
|
613
|
+
}
|
|
581
614
|
// `quantityPicker` binds to the observable `product.quantity`, which `button.add-to-cart`
|
|
582
615
|
// (via the cart store) picks up when the product is added.
|
|
583
616
|
if (module == 'quantityPicker') {
|
|
@@ -613,5 +646,5 @@ exports.QuickviewLayout = (0, mobx_react_lite_1.observer)((properties) => {
|
|
|
613
646
|
}
|
|
614
647
|
const topRowCounter = { value: 0 };
|
|
615
648
|
const closeButton = ((0, jsx_runtime_1.jsx)(Button_1.Button, { name: "close", internalClassName: "ss__quickview__close", icon: "close-thin", lang: { button: lang.closeButton }, onClick: () => onClose(), theme: props.theme, treePath: treePath, ...(0, utilities_1.defined)({ disableStyles }) }));
|
|
616
|
-
return ((0, jsx_runtime_1.jsx)(providers_1.CacheProvider, { children: (0, jsx_runtime_1.jsx)("div", { ...styling, className: (0, classnames_1.default)('ss__quickview', className, internalClassName), children: error || loading || product ? ((0, jsx_runtime_1.jsxs)("div", { ...contentProps, children: [closeButton, error ? ((0, jsx_runtime_1.jsx)("div", { className: "ss__quickview__error", role: "alert", children: error.message })) : loading ? ((0, jsx_runtime_1.jsx)("div", { className: "ss__quickview__loading", ...mergedLang.loadingText?.all })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [layout?.map((module) => findModule(module, topRowCounter)), (0, jsx_runtime_1.jsx)(Gallery_1.Gallery, { images: galleryImages, open: galleryOpen, startIndex: galleryIndex, onClose: () => setGalleryOpen(false), alt: name, theme: props.theme, treePath: treePath, ...(0, utilities_1.defined)({ disableStyles }) })] }))] })) : null }) }));
|
|
649
|
+
return ((0, jsx_runtime_1.jsx)(providers_1.CacheProvider, { children: (0, jsx_runtime_1.jsx)("div", { ...styling, className: (0, classnames_1.default)('ss__quickview', className, internalClassName), children: error || loading || product ? ((0, jsx_runtime_1.jsxs)("div", { ...contentProps, children: [!props.inline && closeButton, error ? ((0, jsx_runtime_1.jsx)("div", { className: "ss__quickview__error", role: "alert", children: error.message })) : loading ? ((0, jsx_runtime_1.jsx)("div", { className: "ss__quickview__loading", ...mergedLang.loadingText?.all })) : ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [layout?.map((module) => findModule(module, topRowCounter)), (0, jsx_runtime_1.jsx)(Gallery_1.Gallery, { images: galleryImages, open: galleryOpen, startIndex: galleryIndex, onClose: () => setGalleryOpen(false), alt: name, theme: props.theme, treePath: treePath, ...(0, utilities_1.defined)({ disableStyles }) })] }))] })) : null }) }));
|
|
617
650
|
});
|
|
@@ -44,7 +44,7 @@ __exportStar(require("./components/Molecules/ChatInspirationResultMessage"), exp
|
|
|
44
44
|
__exportStar(require("./components/Molecules/ChatMessageText"), exports);
|
|
45
45
|
__exportStar(require("./components/Molecules/ChatMessageUser"), exports);
|
|
46
46
|
__exportStar(require("./components/Molecules/ChatProductComparisonMessage"), exports);
|
|
47
|
-
__exportStar(require("./components/Molecules/
|
|
47
|
+
__exportStar(require("./components/Molecules/ChatQuickview"), exports);
|
|
48
48
|
__exportStar(require("./components/Molecules/ChatResult"), exports);
|
|
49
49
|
__exportStar(require("./components/Molecules/ChatResultsDisplay"), exports);
|
|
50
50
|
__exportStar(require("./components/Molecules/ChatSuggestedQuestions"), exports);
|
package/dist/cjs/src/Snap.js
CHANGED
|
@@ -126,7 +126,7 @@ class Snap {
|
|
|
126
126
|
profiler: services?.profiler,
|
|
127
127
|
logger: services?.logger,
|
|
128
128
|
tracker: services?.tracker || this.tracker,
|
|
129
|
-
quickviewManager: services?.quickviewManager || this.quickviewManager,
|
|
129
|
+
quickviewManager: services?.quickviewManager || (type === snap_controller_1.ControllerTypes.chat ? this.chatQuickviewManager : this.quickviewManager),
|
|
130
130
|
});
|
|
131
131
|
}
|
|
132
132
|
if (callback) {
|
|
@@ -496,6 +496,18 @@ class Snap {
|
|
|
496
496
|
this.logger.error(`Failed to create the Quickview Manager.`, err);
|
|
497
497
|
}
|
|
498
498
|
}
|
|
499
|
+
// Create the chat quickview manager whenever chat controllers are configured — even
|
|
500
|
+
// without a `quickview` config, since chat needs no component target (the productQuery
|
|
501
|
+
// panel renders a QuickviewLayout inline). Settings inherit from the quickview config
|
|
502
|
+
// when one exists so displayFields/imagesField behave consistently across both surfaces.
|
|
503
|
+
if (this.config.controllers?.chat?.length) {
|
|
504
|
+
try {
|
|
505
|
+
this.chatQuickviewManager = new snap_controller_1.QuickviewManager({}, { ...(this.config.quickview?.config || {}), id: 'chat-quickview' });
|
|
506
|
+
}
|
|
507
|
+
catch (err) {
|
|
508
|
+
this.logger.error(`Failed to create the chat Quickview Manager.`, err);
|
|
509
|
+
}
|
|
510
|
+
}
|
|
499
511
|
// create controllers
|
|
500
512
|
Object.keys(this.config?.controllers || {}).forEach((type) => {
|
|
501
513
|
switch (type) {
|
|
@@ -41,7 +41,7 @@ class LibraryStore {
|
|
|
41
41
|
chatMessageText: {},
|
|
42
42
|
chatMessageUser: {},
|
|
43
43
|
chatProductComparisonMessage: {},
|
|
44
|
-
|
|
44
|
+
chatQuickview: {},
|
|
45
45
|
chatResult: {},
|
|
46
46
|
chatResultsDisplay: {},
|
|
47
47
|
chatSuggestedQuestions: {},
|
|
@@ -262,7 +262,7 @@ class LibraryStore {
|
|
|
262
262
|
chatMessageText: {},
|
|
263
263
|
chatMessageUser: {},
|
|
264
264
|
chatProductComparisonMessage: {},
|
|
265
|
-
|
|
265
|
+
chatQuickview: {},
|
|
266
266
|
chatResult: {},
|
|
267
267
|
chatResultsDisplay: {},
|
|
268
268
|
chatSuggestedQuestions: {},
|