@banbox/chat 1.0.4 → 1.0.5

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/index.cjs CHANGED
@@ -1611,27 +1611,12 @@ var ChatFooter = ({
1611
1611
  ] });
1612
1612
  };
1613
1613
  var ChatFooter_default = ChatFooter;
1614
- function ChatHeader({ left, right, below }) {
1614
+ function ChatHeader({ left, right, below, className }) {
1615
1615
  return /* @__PURE__ */ jsxRuntime.jsxs("div", { children: [
1616
- /* @__PURE__ */ jsxRuntime.jsxs(
1617
- "div",
1618
- {
1619
- style: {
1620
- borderBottom: "1px solid #e1e1e1",
1621
- height: 64,
1622
- display: "flex",
1623
- alignItems: "flex-start",
1624
- justifyContent: "space-between",
1625
- paddingLeft: 16,
1626
- paddingRight: 16,
1627
- paddingTop: 10
1628
- },
1629
- children: [
1630
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "flex-start", gap: 12 }, children: left }),
1631
- right
1632
- ]
1633
- }
1634
- ),
1616
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: `border-b border-[#e1e1e1] h-[64px] flex items-start justify-between px-4 pt-2.5${className ? ` ${className}` : ""}`, children: [
1617
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-start gap-3", children: left }),
1618
+ right
1619
+ ] }),
1635
1620
  below && /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: below })
1636
1621
  ] });
1637
1622
  }
@@ -1774,7 +1759,7 @@ var ChatInquiryBar = ({ id, onView, className, label, buttonLabel }) => {
1774
1759
  );
1775
1760
  };
1776
1761
  var ChatInquiryBar_default = ChatInquiryBar;
1777
- var ChatListHeader = ({ onClose, onSearchChange }) => {
1762
+ var ChatListHeader = ({ className, onClose, onSearchChange }) => {
1778
1763
  const [searching, setSearching] = React10__default.default.useState(false);
1779
1764
  const [q, setQ] = React10__default.default.useState("");
1780
1765
  const inputRef = React10__default.default.useRef(null);
@@ -1806,117 +1791,85 @@ var ChatListHeader = ({ onClose, onSearchChange }) => {
1806
1791
  inFromLeft: { opacity: 1, x: 0, transition: { duration: 0.18, ease: [0.16, 1, 0.3, 1] } },
1807
1792
  outToRight: { opacity: 0, x: 24, transition: { duration: 0.16, ease: [0.4, 0, 1, 1] } }
1808
1793
  };
1809
- const btnStyle = {
1810
- height: 36,
1811
- width: 36,
1812
- display: "flex",
1813
- alignItems: "center",
1814
- justifyContent: "center",
1815
- borderRadius: "50%",
1816
- border: "none",
1817
- background: "transparent",
1818
- cursor: "pointer"
1819
- };
1820
- return /* @__PURE__ */ jsxRuntime.jsx(
1821
- "div",
1794
+ return /* @__PURE__ */ jsxRuntime.jsx("div", { className: `h-[64px] border-b border-[#ededed]${className ? ` ${className}` : ""}`, children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex h-full items-center px-[20px]", children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, mode: "wait", children: !searching ? /* @__PURE__ */ jsxRuntime.jsxs(
1795
+ framerMotion.motion.div,
1822
1796
  {
1823
- style: {
1824
- height: 64,
1825
- borderBottom: "1px solid #ededed",
1826
- display: "flex",
1827
- alignItems: "center",
1828
- paddingLeft: 20,
1829
- paddingRight: 20
1830
- },
1831
- children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { initial: false, mode: "wait", children: !searching ? /* @__PURE__ */ jsxRuntime.jsxs(
1832
- framerMotion.motion.div,
1833
- {
1834
- style: { display: "flex", width: "100%", alignItems: "center", justifyContent: "space-between" },
1835
- initial: { opacity: 0, x: -24 },
1836
- animate: "inFromLeft",
1837
- exit: "outToLeft",
1838
- variants,
1839
- children: [
1840
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8, color: "#2c2c2c" }, children: [
1841
- /* @__PURE__ */ jsxRuntime.jsx(MessageIcon, { className: "w-6 h-6" }),
1842
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { fontSize: 22, fontWeight: 600 }, children: "Messenger" })
1843
- ] }),
1844
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", gap: 8 }, children: [
1845
- /* @__PURE__ */ jsxRuntime.jsx("button", { title: "Search", onClick: () => setSearching(true), style: btnStyle, children: /* @__PURE__ */ jsxRuntime.jsx(ChatSearchIcon, { className: "w-5 h-5" }) }),
1846
- /* @__PURE__ */ jsxRuntime.jsx("button", { title: "Close", onClick: onClose, style: btnStyle, children: /* @__PURE__ */ jsxRuntime.jsx(ChatXIcon, { className: "w-6 h-6" }) })
1847
- ] })
1848
- ]
1849
- },
1850
- "normal"
1851
- ) : /* @__PURE__ */ jsxRuntime.jsx(
1852
- framerMotion.motion.div,
1853
- {
1854
- style: { display: "flex", width: "100%", alignItems: "center", gap: 12 },
1855
- initial: { opacity: 0, x: 24 },
1856
- animate: "inFromRight",
1857
- exit: "outToRight",
1858
- variants,
1859
- children: /* @__PURE__ */ jsxRuntime.jsxs(
1860
- "div",
1797
+ className: "flex w-full items-center justify-between",
1798
+ initial: { opacity: 0, x: -24 },
1799
+ animate: "inFromLeft",
1800
+ exit: "outToLeft",
1801
+ variants,
1802
+ children: [
1803
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center gap-3", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "text-[#2c2c2c] flex items-center gap-2", children: [
1804
+ /* @__PURE__ */ jsxRuntime.jsx(MessageIcon, { className: "w-6 h-6" }),
1805
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-[22px] font-semibold", children: "Messenger" })
1806
+ ] }) }),
1807
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center gap-2", children: [
1808
+ /* @__PURE__ */ jsxRuntime.jsx(
1809
+ "button",
1810
+ {
1811
+ title: "Search",
1812
+ onClick: () => setSearching(true),
1813
+ className: "h-9 w-9 place-items-center rounded-full hover:bg-black/5 flex items-center justify-center cursor-pointer border-none bg-transparent",
1814
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChatSearchIcon, { className: "w-5 h-5" })
1815
+ }
1816
+ ),
1817
+ /* @__PURE__ */ jsxRuntime.jsx(
1818
+ "button",
1819
+ {
1820
+ title: "Close",
1821
+ onClick: onClose,
1822
+ className: "h-9 w-9 place-items-center rounded-full hover:bg-black/5 flex items-center justify-center cursor-pointer border-none bg-transparent",
1823
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChatXIcon, { className: "w-6 h-6" })
1824
+ }
1825
+ )
1826
+ ] })
1827
+ ]
1828
+ },
1829
+ "normal"
1830
+ ) : /* @__PURE__ */ jsxRuntime.jsx(
1831
+ framerMotion.motion.div,
1832
+ {
1833
+ className: "flex w-full items-center gap-3",
1834
+ initial: { opacity: 0, x: 24 },
1835
+ animate: "inFromRight",
1836
+ exit: "outToRight",
1837
+ variants,
1838
+ children: /* @__PURE__ */ jsxRuntime.jsx("div", { className: "relative flex-1", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-10 w-full items-center rounded-full border border-[#6A6A6A] bg-white px-[4px] gap-1.5", children: [
1839
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex items-center ms-[12px] w-full", children: [
1840
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-2 grid h-6 w-6 shrink-0 place-items-center text-[#929292]", children: /* @__PURE__ */ jsxRuntime.jsx(ChatSearchIcon, { className: "w-5 h-5" }) }),
1841
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "mr-2 h-6 w-px shrink-0 bg-[#e1e1e1]" }),
1842
+ /* @__PURE__ */ jsxRuntime.jsx(
1843
+ "input",
1861
1844
  {
1862
- style: {
1863
- display: "flex",
1864
- flex: 1,
1865
- height: 40,
1866
- alignItems: "center",
1867
- borderRadius: 9999,
1868
- border: "1px solid #6A6A6A",
1869
- backgroundColor: "#fff",
1870
- padding: "0 4px",
1871
- gap: 6
1845
+ ref: inputRef,
1846
+ value: q,
1847
+ onChange: (e) => {
1848
+ setQ(e.target.value);
1849
+ onSearchChange?.(e.target.value);
1872
1850
  },
1873
- children: [
1874
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", alignItems: "center", flex: 1, marginLeft: 12 }, children: [
1875
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginRight: 8, color: "#929292", flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(ChatSearchIcon, { className: "w-5 h-5" }) }),
1876
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { marginRight: 8, height: 24, width: 1, flexShrink: 0, backgroundColor: "#e1e1e1" } }),
1877
- /* @__PURE__ */ jsxRuntime.jsx(
1878
- "input",
1879
- {
1880
- ref: inputRef,
1881
- value: q,
1882
- onChange: (e) => {
1883
- setQ(e.target.value);
1884
- onSearchChange?.(e.target.value);
1885
- },
1886
- placeholder: "Search",
1887
- style: {
1888
- flex: 1,
1889
- height: "100%",
1890
- background: "transparent",
1891
- fontSize: 15,
1892
- outline: "none",
1893
- border: "none",
1894
- color: "#2c2c2c"
1895
- }
1896
- }
1897
- )
1898
- ] }),
1899
- /* @__PURE__ */ jsxRuntime.jsx(
1900
- "button",
1901
- {
1902
- title: "Close search",
1903
- onClick: () => {
1904
- setSearching(false);
1905
- setQ("");
1906
- onSearchChange?.("");
1907
- },
1908
- style: { ...btnStyle, height: 32, width: 32 },
1909
- children: /* @__PURE__ */ jsxRuntime.jsx(ChatXIcon, { className: "w-5 h-5" })
1910
- }
1911
- )
1912
- ]
1851
+ placeholder: "Search",
1852
+ className: "h-full w-full flex-1 bg-transparent text-[15px] outline-none placeholder:text-[#9C9C9C] border-none"
1913
1853
  }
1914
1854
  )
1915
- },
1916
- "search"
1917
- ) })
1918
- }
1919
- );
1855
+ ] }),
1856
+ /* @__PURE__ */ jsxRuntime.jsx(
1857
+ "button",
1858
+ {
1859
+ title: "Close search",
1860
+ onClick: () => {
1861
+ setSearching(false);
1862
+ setQ("");
1863
+ onSearchChange?.("");
1864
+ },
1865
+ className: "grid h-8 w-8 place-items-center rounded-full text-xl hover:bg-black/5 cursor-pointer border-none bg-transparent",
1866
+ children: /* @__PURE__ */ jsxRuntime.jsx(ChatXIcon, { className: "w-5 h-5" })
1867
+ }
1868
+ )
1869
+ ] }) })
1870
+ },
1871
+ "search"
1872
+ ) }) }) });
1920
1873
  };
1921
1874
  var ChatListHeader_default = ChatListHeader;
1922
1875
  var Row = ({ icon, label, value, highlight }) => {
@@ -2548,6 +2501,7 @@ var ChatMessageItem_default = ChatMessageItem;
2548
2501
  var ChatScroll = ({
2549
2502
  top,
2550
2503
  children,
2504
+ className,
2551
2505
  style,
2552
2506
  bottomAlignWhenShort = false,
2553
2507
  scrollKey
@@ -2555,9 +2509,7 @@ var ChatScroll = ({
2555
2509
  const ref = React10__default.default.useRef(null);
2556
2510
  const scrollToBottom = React10__default.default.useCallback(() => {
2557
2511
  const el = ref.current;
2558
- if (!el) {
2559
- return;
2560
- }
2512
+ if (!el) return;
2561
2513
  el.scrollTop = el.scrollHeight;
2562
2514
  }, []);
2563
2515
  React10__default.default.useEffect(() => {
@@ -2570,26 +2522,12 @@ var ChatScroll = ({
2570
2522
  {
2571
2523
  ref,
2572
2524
  "data-chat-scroll": true,
2573
- style: {
2574
- height: "100%",
2575
- minHeight: 0,
2576
- overflowY: "auto",
2577
- backgroundColor: "#fff",
2578
- padding: 16,
2579
- // custom scrollbar — hide track for clean look
2580
- scrollbarWidth: "thin",
2581
- scrollbarColor: "#d1d5db transparent",
2582
- ...style
2583
- },
2525
+ className: `h-full min-h-0 overflow-y-auto bg-white p-4 custom-scroll-hidden${className ? ` ${className}` : ""}`,
2526
+ style,
2584
2527
  children: /* @__PURE__ */ jsxRuntime.jsxs(
2585
2528
  "div",
2586
2529
  {
2587
- style: {
2588
- minHeight: "100%",
2589
- display: "flex",
2590
- flexDirection: "column",
2591
- justifyContent: bottomAlignWhenShort ? "flex-end" : "flex-start"
2592
- },
2530
+ className: `min-h-full flex flex-col${bottomAlignWhenShort ? " justify-end" : " justify-start"}`,
2593
2531
  children: [
2594
2532
  top,
2595
2533
  children
@@ -2691,6 +2629,7 @@ var Lottie2 = _Lottie__default.default.default ?? _Lottie__default.default;
2691
2629
  var TypingIndicator = ({
2692
2630
  loop = true,
2693
2631
  autoplay = true,
2632
+ className,
2694
2633
  ariaLabel = "Typing\u2026",
2695
2634
  avatarSize = 40,
2696
2635
  style
@@ -2700,53 +2639,28 @@ var TypingIndicator = ({
2700
2639
  {
2701
2640
  role: "status",
2702
2641
  "aria-label": ariaLabel,
2703
- style: {
2704
- position: "relative",
2705
- display: "flex",
2706
- alignItems: "flex-end",
2707
- gap: 6,
2708
- ...style
2709
- },
2642
+ className: `relative flex items-end gap-[6px]${className ? ` ${className}` : ""}`,
2643
+ style,
2710
2644
  children: [
2711
2645
  /* @__PURE__ */ jsxRuntime.jsxs(
2712
2646
  "div",
2713
2647
  {
2714
- style: {
2715
- position: "relative",
2716
- flexShrink: 0,
2717
- borderRadius: "50%",
2718
- border: "1px solid #F1F1F1",
2719
- width: avatarSize,
2720
- height: avatarSize
2721
- },
2648
+ className: "relative shrink-0 rounded-full border border-[#F1F1F1]",
2649
+ style: { width: avatarSize, height: avatarSize },
2722
2650
  children: [
2723
2651
  /* @__PURE__ */ jsxRuntime.jsx(
2724
2652
  "img",
2725
2653
  {
2726
2654
  src: "/chat/img/girl_support.png",
2727
2655
  alt: "avatar image",
2728
- style: { height: "100%", width: "100%", borderRadius: "50%", objectFit: "cover" }
2656
+ className: "h-full w-full rounded-full object-cover"
2729
2657
  }
2730
2658
  ),
2731
- /* @__PURE__ */ jsxRuntime.jsx(
2732
- "span",
2733
- {
2734
- style: {
2735
- position: "absolute",
2736
- bottom: 0,
2737
- right: 0,
2738
- height: 11.25,
2739
- width: 11.25,
2740
- borderRadius: "50%",
2741
- backgroundColor: "#328545",
2742
- outline: "2px solid #fff"
2743
- }
2744
- }
2745
- )
2659
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-0 right-0 h-[11.25px] w-[11.25px] rounded-full bg-[#328545] ring-1 ring-white" })
2746
2660
  ]
2747
2661
  }
2748
2662
  ),
2749
- /* @__PURE__ */ jsxRuntime.jsx("span", { style: { position: "absolute", bottom: -13, left: 30 }, children: /* @__PURE__ */ jsxRuntime.jsx(
2663
+ /* @__PURE__ */ jsxRuntime.jsx("span", { className: "absolute bottom-[-13px] left-[30px]", children: /* @__PURE__ */ jsxRuntime.jsx(
2750
2664
  Lottie2,
2751
2665
  {
2752
2666
  animationData: typingdotanimation2_default,
@@ -2961,7 +2875,20 @@ var avatarBgByInitial = {
2961
2875
  b: "#F0EDEB"
2962
2876
  };
2963
2877
  var GRADIENT_BORDER = "linear-gradient(236.83deg, rgba(51,201,212,0.3) 0.4%, rgba(39,83,251,0.3) 30.28%, rgba(39,83,251,0.3) 50.2%, rgba(39,83,251,0.3) 65.14%, rgba(235,67,255,0.3) 100%)";
2964
- var InboxPopup = ({ adapter, uiCallbacks }) => {
2878
+ function getThemeAttr(theme) {
2879
+ if (!theme || theme === "marketplace") return "marketplace";
2880
+ if (theme === "admin") return "admin";
2881
+ return "custom";
2882
+ }
2883
+ function getThemeVars(theme) {
2884
+ if (!theme || theme === "marketplace" || theme === "admin") return {};
2885
+ const vars = {};
2886
+ if (theme.primary) vars["--color-banbox-primary"] = theme.primary;
2887
+ if (theme.primaryActive) vars["--color-banbox-primary-active"] = theme.primaryActive;
2888
+ if (theme.surfaceLow) vars["--color-banbox-surface-container-low"] = theme.surfaceLow;
2889
+ return vars;
2890
+ }
2891
+ var InboxPopup = ({ adapter, uiCallbacks, theme }) => {
2965
2892
  const { close, selectThread, selectedThreadId, reference } = useChatUI();
2966
2893
  const { isOpen: isGalleryOpen, closeGallery } = useGallery();
2967
2894
  const [threads, setThreads] = React10.useState(() => adapter.threads.list(reference));
@@ -3033,24 +2960,21 @@ var InboxPopup = ({ adapter, uiCallbacks }) => {
3033
2960
  if (nextId) selectThread(nextId);
3034
2961
  setReplyTo(void 0);
3035
2962
  setShowDelete(false);
3036
- uiCallbacks?.showToast?.({
3037
- type: "success",
3038
- title: "Chat Deleted",
3039
- message: "The chat has been deleted successfully."
3040
- });
2963
+ uiCallbacks?.showToast?.({ type: "success", title: "Chat Deleted", message: "The chat has been deleted successfully." });
3041
2964
  };
3042
2965
  const filteredThreads = threads.filter((t) => {
3043
2966
  if (!searchQuery.trim()) return true;
3044
2967
  const q = searchQuery.toLowerCase();
3045
2968
  return t.title.toLowerCase().includes(q) || t.last?.toLowerCase().includes(q) || t.orderId?.toLowerCase().includes(q) || t.inquiryId?.toLowerCase().includes(q);
3046
2969
  });
3047
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "fixed", bottom: 16, right: 16, zIndex: 10002 }, children: [
2970
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-4 right-4 z-[10002]", children: [
3048
2971
  /* @__PURE__ */ jsxRuntime.jsx(
3049
2972
  framerMotion.motion.button,
3050
2973
  {
3051
2974
  "aria-label": "Close chat",
3052
2975
  onClick: close,
3053
- style: { position: "fixed", inset: 0, background: "transparent", border: "none", cursor: "auto" },
2976
+ className: "fixed inset-0 cursor-auto!",
2977
+ style: { background: "transparent", border: "none" },
3054
2978
  initial: { opacity: 0 },
3055
2979
  animate: { opacity: 1 },
3056
2980
  exit: { opacity: 0 },
@@ -3062,14 +2986,14 @@ var InboxPopup = ({ adapter, uiCallbacks }) => {
3062
2986
  {
3063
2987
  role: "dialog",
3064
2988
  "aria-modal": "true",
2989
+ "data-theme": getThemeAttr(theme),
2990
+ className: "banbox-chat-root relative rounded-[20px] p-[3px]",
3065
2991
  style: {
3066
- position: "relative",
3067
2992
  width: 800,
3068
2993
  height: 650,
3069
- borderRadius: 20,
3070
- padding: 3,
3071
2994
  boxShadow: "0px 2px 12px 0px #3B33331A",
3072
- background: GRADIENT_BORDER
2995
+ background: GRADIENT_BORDER,
2996
+ ...getThemeVars(theme)
3073
2997
  },
3074
2998
  initial: { x: "110%" },
3075
2999
  animate: { x: 0 },
@@ -3078,192 +3002,115 @@ var InboxPopup = ({ adapter, uiCallbacks }) => {
3078
3002
  children: /* @__PURE__ */ jsxRuntime.jsxs(
3079
3003
  "div",
3080
3004
  {
3081
- style: {
3082
- position: "relative",
3083
- height: "100%",
3084
- width: "100%",
3085
- overflow: "hidden",
3086
- borderRadius: 18,
3087
- backgroundColor: "#fff",
3088
- overscrollBehavior: "contain"
3089
- },
3005
+ className: "relative h-full w-full overflow-hidden rounded-[18px] bg-white",
3006
+ style: { overscrollBehavior: "contain" },
3090
3007
  children: [
3091
- /* @__PURE__ */ jsxRuntime.jsxs(
3092
- "div",
3093
- {
3094
- style: {
3095
- display: "grid",
3096
- gridTemplateColumns: "1fr 310px",
3097
- height: "100%",
3098
- minHeight: 0
3099
- },
3100
- children: [
3101
- /* @__PURE__ */ jsxRuntime.jsxs(
3102
- "div",
3103
- {
3104
- style: {
3105
- display: "flex",
3106
- flexDirection: "column",
3107
- height: "100%",
3108
- minHeight: 0,
3109
- borderRight: "1px solid #9BBCCF"
3008
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-0 rounded-[14px] ring-1 ring-[#2F80ED]/40" }),
3009
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "grid h-full min-h-0 grid-cols-[1fr_310px]", children: [
3010
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-0 flex-col border-r border-[#9BBCCF]", children: [
3011
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[64px] shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3012
+ ChatHeader,
3013
+ {
3014
+ left: activeThread?.avatarSrc ? /* @__PURE__ */ jsxRuntime.jsx(ChatIdentity_default, { variant: "avatar", src: activeThread.avatarSrc, online, title, subtitle, verified: isVerified, subtitleVariant: "muted" }) : /* @__PURE__ */ jsxRuntime.jsx(ChatIdentity_default, { variant: "initial", initial, bg: avatarBg, online, title, subtitle, verified: isVerified, subtitleVariant: "muted" }),
3015
+ right: uiCallbacks?.renderKebabMenu?.({
3016
+ pinned: Boolean(activeThread?.pinned),
3017
+ onPinToggle: () => {
3018
+ if (activeId) adapter.threads.pin(activeId, !activeThread?.pinned);
3110
3019
  },
3111
- children: [
3112
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: 64, flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3113
- ChatHeader,
3114
- {
3115
- left: activeThread?.avatarSrc ? /* @__PURE__ */ jsxRuntime.jsx(
3116
- ChatIdentity_default,
3117
- {
3118
- variant: "avatar",
3119
- src: activeThread.avatarSrc,
3120
- online,
3121
- title,
3122
- subtitle,
3123
- verified: isVerified,
3124
- subtitleVariant: "muted"
3125
- }
3126
- ) : /* @__PURE__ */ jsxRuntime.jsx(
3127
- ChatIdentity_default,
3128
- {
3129
- variant: "initial",
3130
- initial,
3131
- bg: avatarBg,
3132
- online,
3133
- title,
3134
- subtitle,
3135
- verified: isVerified,
3136
- subtitleVariant: "muted"
3137
- }
3138
- ),
3139
- right: uiCallbacks?.renderKebabMenu?.({
3140
- pinned: Boolean(activeThread?.pinned),
3141
- onPinToggle: () => {
3142
- if (activeId) adapter.threads.pin(activeId, !activeThread?.pinned);
3143
- },
3144
- onDelete: () => setShowDelete(true)
3145
- }) ?? null
3146
- }
3147
- ) }),
3148
- idValue && /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3149
- ChatInquiryBar_default,
3150
- {
3151
- id: idValue,
3152
- label: idLabel,
3153
- buttonLabel: idButtonLabel,
3154
- onView: () => {
3155
- const type = activeThread?.orderId ? "order" : "inquiry";
3156
- uiCallbacks?.onNavigate?.({ type, id: idValue });
3157
- }
3158
- }
3159
- ) }),
3160
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { flex: 1, minHeight: 0, position: "relative" }, children: [
3161
- /* @__PURE__ */ jsxRuntime.jsx(
3162
- ChatScroll_default,
3163
- {
3164
- className: "h-full pb-10",
3165
- bottomAlignWhenShort: false,
3166
- scrollKey,
3167
- style: { height: "100%", overflowY: "auto" },
3168
- children: messages.map((m, idx) => {
3169
- const mine = m.author === "you";
3170
- const isLast = idx === messages.length - 1;
3171
- return /* @__PURE__ */ jsxRuntime.jsx(
3172
- ChatMessageItem_default,
3173
- {
3174
- id: m.id,
3175
- mine,
3176
- time: m.time ?? "",
3177
- authorInitial: typeof m.author === "string" ? m.author : "U",
3178
- avatarBg,
3179
- text: m.text ?? m.content,
3180
- businessCard: m.businessCard,
3181
- addressCard: m.addressCard,
3182
- images: m.images,
3183
- files: m.files,
3184
- audio: m.audio,
3185
- replyTo: m.replyTo,
3186
- showStatus: isLast,
3187
- status: activeThread?.status?.kind === "seen" ? "Seen" : "Delivered",
3188
- onReply: () => setReplyTo(toRef2(m)),
3189
- initialSrc: m.avatarSrc
3190
- },
3191
- m.id
3192
- );
3193
- })
3194
- }
3195
- ),
3196
- /* @__PURE__ */ jsxRuntime.jsx(
3197
- "div",
3198
- {
3199
- style: {
3200
- position: "absolute",
3201
- left: 0,
3202
- right: 0,
3203
- bottom: 0,
3204
- display: "flex",
3205
- alignItems: "center",
3206
- justifyContent: "flex-start",
3207
- padding: "4px 16px 8px",
3208
- background: "#fff",
3209
- pointerEvents: "none"
3210
- },
3211
- children: /* @__PURE__ */ jsxRuntime.jsx(TypingIndicator_default, { style: { pointerEvents: "auto" } })
3212
- }
3213
- )
3214
- ] }),
3215
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3216
- ChatFooter_default,
3020
+ onDelete: () => setShowDelete(true)
3021
+ }) ?? null
3022
+ }
3023
+ ) }),
3024
+ idValue && /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3025
+ ChatInquiryBar_default,
3026
+ {
3027
+ id: idValue,
3028
+ label: idLabel,
3029
+ buttonLabel: idButtonLabel,
3030
+ onView: () => {
3031
+ const type = activeThread?.orderId ? "order" : "inquiry";
3032
+ uiCallbacks?.onNavigate?.({ type, id: idValue });
3033
+ }
3034
+ }
3035
+ ) }),
3036
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "relative h-full min-h-0", children: [
3037
+ /* @__PURE__ */ jsxRuntime.jsx(
3038
+ ChatScroll_default,
3039
+ {
3040
+ className: "h-full pb-10",
3041
+ bottomAlignWhenShort: false,
3042
+ scrollKey,
3043
+ children: messages.map((m, idx) => {
3044
+ const mine = m.author === "you";
3045
+ const isLast = idx === messages.length - 1;
3046
+ return /* @__PURE__ */ jsxRuntime.jsx(
3047
+ ChatMessageItem_default,
3217
3048
  {
3218
- replyTo,
3219
- clearReply: () => setReplyTo(void 0),
3220
- onAfterSend: () => setRev((v) => v + 1),
3221
- onSend: (payload) => {
3222
- if (activeId) adapter.messages.send(activeId, payload);
3223
- }
3049
+ id: m.id,
3050
+ mine,
3051
+ time: m.time ?? "",
3052
+ authorInitial: typeof m.author === "string" ? m.author : "U",
3053
+ avatarBg,
3054
+ text: m.text ?? m.content,
3055
+ businessCard: m.businessCard,
3056
+ addressCard: m.addressCard,
3057
+ images: m.images,
3058
+ files: m.files,
3059
+ audio: m.audio,
3060
+ replyTo: m.replyTo,
3061
+ showStatus: isLast,
3062
+ status: activeThread?.status?.kind === "seen" ? "Seen" : "Delivered",
3063
+ onReply: () => setReplyTo(toRef2(m)),
3064
+ initialSrc: m.avatarSrc
3224
3065
  },
3225
- activeId
3226
- ) })
3227
- ]
3066
+ m.id
3067
+ );
3068
+ })
3228
3069
  }
3229
3070
  ),
3230
- /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { display: "flex", flexDirection: "column", height: "100%", minHeight: 0 }, children: [
3231
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(ChatListHeader_default, { onClose: close, onSearchChange: (val) => setSearchQuery(val) }) }),
3232
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, minHeight: 0, overflowY: "auto" }, children: filteredThreads.map((t) => {
3233
- const status = t.status ?? (t.unread && t.unread > 0 ? { kind: "new", count: t.unread } : { kind: "seen" });
3234
- return /* @__PURE__ */ jsxRuntime.jsx(
3235
- ChatThreadItem_default,
3236
- {
3237
- onClick: () => {
3238
- setReplyTo(void 0);
3239
- selectThread(t.id);
3240
- },
3241
- active: t.id === activeId,
3242
- pinned: Boolean(t.pinned),
3243
- online: t.online,
3244
- verified: Boolean(t.badge),
3245
- title: t.title,
3246
- preview: t.last ?? "",
3247
- time: t.time ?? "",
3248
- status,
3249
- avatarText: t.avatarText ?? "",
3250
- avatarSrc: t.avatarSrc
3251
- },
3252
- t.id
3253
- );
3254
- }) })
3255
- ] })
3256
- ]
3257
- }
3258
- ),
3259
- /* @__PURE__ */ jsxRuntime.jsx(
3260
- ChatConfirmModal,
3261
- {
3262
- open: showDelete,
3263
- onClose: () => setShowDelete(false),
3264
- onConfirm: handleConfirmDelete
3265
- }
3266
- ),
3071
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "pointer-events-none absolute inset-x-0 bottom-0 flex items-center justify-start px-4 pb-2 pt-1 bg-white", children: /* @__PURE__ */ jsxRuntime.jsx(TypingIndicator_default, { className: "pointer-events-auto" }) })
3072
+ ] }) }),
3073
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3074
+ ChatFooter_default,
3075
+ {
3076
+ replyTo,
3077
+ clearReply: () => setReplyTo(void 0),
3078
+ onAfterSend: () => setRev((v) => v + 1),
3079
+ onSend: (payload) => {
3080
+ if (activeId) adapter.messages.send(activeId, payload);
3081
+ }
3082
+ },
3083
+ activeId
3084
+ ) })
3085
+ ] }),
3086
+ /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "flex h-full min-h-0 flex-col", children: [
3087
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(ChatListHeader_default, { onClose: close, onSearchChange: (val) => setSearchQuery(val) }) }),
3088
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0 overflow-y-auto custom-scroll", children: filteredThreads.map((t) => {
3089
+ const status = t.status ?? (t.unread && t.unread > 0 ? { kind: "new", count: t.unread } : { kind: "seen" });
3090
+ return /* @__PURE__ */ jsxRuntime.jsx(
3091
+ ChatThreadItem_default,
3092
+ {
3093
+ onClick: () => {
3094
+ setReplyTo(void 0);
3095
+ selectThread(t.id);
3096
+ },
3097
+ active: t.id === activeId,
3098
+ pinned: Boolean(t.pinned),
3099
+ online: t.online,
3100
+ verified: Boolean(t.badge),
3101
+ title: t.title,
3102
+ preview: t.last ?? "",
3103
+ time: t.time ?? "",
3104
+ status,
3105
+ avatarText: t.avatarText ?? "",
3106
+ avatarSrc: t.avatarSrc
3107
+ },
3108
+ t.id
3109
+ );
3110
+ }) })
3111
+ ] })
3112
+ ] }),
3113
+ /* @__PURE__ */ jsxRuntime.jsx(ChatConfirmModal, { open: showDelete, onClose: () => setShowDelete(false), onConfirm: handleConfirmDelete }),
3267
3114
  /* @__PURE__ */ jsxRuntime.jsx(ChatImagePreviewModal_default, { isOpen: isGalleryOpen, onClose: closeGallery })
3268
3115
  ]
3269
3116
  }
@@ -3292,7 +3139,20 @@ function toRef(m) {
3292
3139
  audio: m.audio
3293
3140
  };
3294
3141
  }
3295
- var SinglePopup = ({ adapter, uiCallbacks }) => {
3142
+ function getThemeAttr2(theme) {
3143
+ if (!theme || theme === "marketplace") return "marketplace";
3144
+ if (theme === "admin") return "admin";
3145
+ return "custom";
3146
+ }
3147
+ function getThemeVars2(theme) {
3148
+ if (!theme || theme === "marketplace" || theme === "admin") return {};
3149
+ const vars = {};
3150
+ if (theme.primary) vars["--color-banbox-primary"] = theme.primary;
3151
+ if (theme.primaryActive) vars["--color-banbox-primary-active"] = theme.primaryActive;
3152
+ if (theme.surfaceLow) vars["--color-banbox-surface-container-low"] = theme.surfaceLow;
3153
+ return vars;
3154
+ }
3155
+ var SinglePopup = ({ adapter, uiCallbacks, theme }) => {
3296
3156
  const { close, reference } = useChatUI();
3297
3157
  const threads = adapter.threads.list(reference);
3298
3158
  const initialThreadId = React10__default.default.useMemo(
@@ -3326,13 +3186,14 @@ var SinglePopup = ({ adapter, uiCallbacks }) => {
3326
3186
  setScrollKey(Date.now());
3327
3187
  setReplyTo(void 0);
3328
3188
  }, [activeId, adapter]);
3329
- return /* @__PURE__ */ jsxRuntime.jsxs("div", { style: { position: "fixed", bottom: 16, right: 16, zIndex: 10002 }, children: [
3189
+ return /* @__PURE__ */ jsxRuntime.jsxs("div", { className: "fixed bottom-4 right-4 z-[10002]", children: [
3330
3190
  /* @__PURE__ */ jsxRuntime.jsx(
3331
3191
  framerMotion.motion.button,
3332
3192
  {
3333
3193
  "aria-label": "Close chat",
3334
3194
  onClick: close,
3335
- style: { position: "fixed", inset: 0, background: "transparent", border: "none", cursor: "auto" },
3195
+ className: "fixed inset-0 cursor-auto!",
3196
+ style: { background: "transparent", border: "none" },
3336
3197
  initial: { opacity: 0 },
3337
3198
  animate: { opacity: 1 },
3338
3199
  exit: { opacity: 0 },
@@ -3344,14 +3205,12 @@ var SinglePopup = ({ adapter, uiCallbacks }) => {
3344
3205
  {
3345
3206
  role: "dialog",
3346
3207
  "aria-modal": "true",
3208
+ "data-theme": getThemeAttr2(theme),
3209
+ className: "banbox-chat-root relative h-[650px] w-[450px] rounded-[20px] p-[2px]",
3347
3210
  style: {
3348
- position: "relative",
3349
- height: 650,
3350
- width: 450,
3351
- borderRadius: 20,
3352
- padding: 2,
3353
3211
  boxShadow: "0px 2px 12px 0px #3B33331A",
3354
- background: GRADIENT_BORDER2
3212
+ background: GRADIENT_BORDER2,
3213
+ ...getThemeVars2(theme)
3355
3214
  },
3356
3215
  initial: { x: "110%" },
3357
3216
  animate: { x: 0 },
@@ -3360,18 +3219,10 @@ var SinglePopup = ({ adapter, uiCallbacks }) => {
3360
3219
  children: /* @__PURE__ */ jsxRuntime.jsxs(
3361
3220
  "div",
3362
3221
  {
3363
- style: {
3364
- display: "flex",
3365
- flexDirection: "column",
3366
- height: "100%",
3367
- width: "100%",
3368
- overflow: "hidden",
3369
- borderRadius: 18,
3370
- backgroundColor: "#fff",
3371
- overscrollBehavior: "contain"
3372
- },
3222
+ className: "flex h-full w-full flex-col overflow-hidden rounded-[18px] bg-white",
3223
+ style: { overscrollBehavior: "contain" },
3373
3224
  children: [
3374
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { height: 64, flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3225
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "h-[64px] shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3375
3226
  ChatHeader,
3376
3227
  {
3377
3228
  left: /* @__PURE__ */ jsxRuntime.jsx(
@@ -3391,30 +3242,18 @@ var SinglePopup = ({ adapter, uiCallbacks }) => {
3391
3242
  {
3392
3243
  type: "button",
3393
3244
  onClick: close,
3394
- style: {
3395
- display: "flex",
3396
- alignItems: "center",
3397
- justifyContent: "center",
3398
- height: 34,
3399
- width: 34,
3400
- borderRadius: "50%",
3401
- backgroundColor: "#fff",
3402
- color: "#000",
3403
- border: "none",
3404
- boxShadow: "0px 2px 4px 0px #A5A3AE4D",
3405
- cursor: "pointer"
3406
- },
3245
+ className: "flex h-[34px] w-[34px] items-center justify-center rounded-full bg-white text-black shadow-[0px_2px_4px_0px_#A5A3AE4D] hover:bg-black/5 hover:text-[var(--color-banbox-warning)] cursor-pointer border-none",
3407
3246
  children: /* @__PURE__ */ jsxRuntime.jsx(ChatXIcon, { className: "h-6 w-6" })
3408
3247
  }
3409
3248
  )
3410
3249
  }
3411
3250
  ) }),
3412
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flex: 1, minHeight: 0, position: "relative" }, children: /* @__PURE__ */ jsxRuntime.jsxs(
3251
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex-1 min-h-0", children: /* @__PURE__ */ jsxRuntime.jsxs(
3413
3252
  ChatScroll_default,
3414
3253
  {
3254
+ className: "h-full",
3415
3255
  bottomAlignWhenShort: false,
3416
3256
  scrollKey,
3417
- style: { height: "100%", overflowY: "auto" },
3418
3257
  children: [
3419
3258
  messages.map((m, idx) => {
3420
3259
  const mine = m.author === "you";
@@ -3441,11 +3280,11 @@ var SinglePopup = ({ adapter, uiCallbacks }) => {
3441
3280
  m.id
3442
3281
  );
3443
3282
  }),
3444
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { display: "flex", alignItems: "center", justifyContent: "flex-start" }, children: /* @__PURE__ */ jsxRuntime.jsx(TypingIndicator_default, {}) })
3283
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "flex items-center justify-start", children: /* @__PURE__ */ jsxRuntime.jsx(TypingIndicator_default, {}) })
3445
3284
  ]
3446
3285
  }
3447
3286
  ) }),
3448
- /* @__PURE__ */ jsxRuntime.jsx("div", { style: { flexShrink: 0 }, children: /* @__PURE__ */ jsxRuntime.jsx(
3287
+ /* @__PURE__ */ jsxRuntime.jsx("div", { className: "shrink-0", children: /* @__PURE__ */ jsxRuntime.jsx(
3449
3288
  ChatFooter_default,
3450
3289
  {
3451
3290
  variant: "single",
@@ -3465,7 +3304,7 @@ var SinglePopup = ({ adapter, uiCallbacks }) => {
3465
3304
  ] });
3466
3305
  };
3467
3306
  var SinglePopup_default = SinglePopup;
3468
- function ChatRoot({ adapter, uiCallbacks }) {
3307
+ function ChatRoot({ adapter, uiCallbacks, theme }) {
3469
3308
  const { isOpen, variant } = useChatUI();
3470
3309
  useDisableBodyScroll(isOpen);
3471
3310
  if (typeof window === "undefined") {
@@ -3473,19 +3312,20 @@ function ChatRoot({ adapter, uiCallbacks }) {
3473
3312
  }
3474
3313
  return reactDom.createPortal(
3475
3314
  // GalleryProvider is scoped to the chat only.
3476
- // It is completely separate from the host app's own gallery context.
3477
3315
  /* @__PURE__ */ jsxRuntime.jsx(GalleryProvider, { children: /* @__PURE__ */ jsxRuntime.jsx(framerMotion.AnimatePresence, { mode: "wait", children: isOpen && (variant === "inbox" ? /* @__PURE__ */ jsxRuntime.jsx(
3478
3316
  InboxPopup_default,
3479
3317
  {
3480
3318
  adapter,
3481
- uiCallbacks
3319
+ uiCallbacks,
3320
+ theme
3482
3321
  },
3483
3322
  "inbox"
3484
3323
  ) : /* @__PURE__ */ jsxRuntime.jsx(
3485
3324
  SinglePopup_default,
3486
3325
  {
3487
3326
  adapter,
3488
- uiCallbacks
3327
+ uiCallbacks,
3328
+ theme
3489
3329
  },
3490
3330
  "single"
3491
3331
  )) }) }),