@anker-in/campaign-ui 0.3.2 → 0.3.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (229) hide show
  1. package/dist/cjs/components/LiveChatWidget/LiveChatWidget.d.ts +21 -1
  2. package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js +1 -1
  3. package/dist/cjs/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
  4. package/dist/cjs/components/LiveChatWidget/api/chat.d.ts +23 -2
  5. package/dist/cjs/components/LiveChatWidget/api/chat.js +2 -2
  6. package/dist/cjs/components/LiveChatWidget/api/chat.js.map +3 -3
  7. package/dist/cjs/components/LiveChatWidget/components/ChatHeader.js +1 -1
  8. package/dist/cjs/components/LiveChatWidget/components/ChatHeader.js.map +2 -2
  9. package/dist/cjs/components/LiveChatWidget/components/ChatInput.d.ts +5 -0
  10. package/dist/cjs/components/LiveChatWidget/components/ChatInput.js +1 -1
  11. package/dist/cjs/components/LiveChatWidget/components/ChatInput.js.map +3 -3
  12. package/dist/cjs/components/LiveChatWidget/components/ChatMessage.js +2 -2
  13. package/dist/cjs/components/LiveChatWidget/components/ChatMessage.js.map +3 -3
  14. package/dist/cjs/components/LiveChatWidget/components/ChatWindow.d.ts +5 -0
  15. package/dist/cjs/components/LiveChatWidget/components/ChatWindow.js +1 -1
  16. package/dist/cjs/components/LiveChatWidget/components/ChatWindow.js.map +3 -3
  17. package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.d.ts +51 -0
  18. package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.js +33 -0
  19. package/dist/cjs/components/LiveChatWidget/components/ComplianceDialog.js.map +7 -0
  20. package/dist/cjs/components/LiveChatWidget/components/MessageContent/CartCard.js +1 -1
  21. package/dist/cjs/components/LiveChatWidget/components/MessageContent/CartCard.js.map +3 -3
  22. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ErrorBlock.js +1 -1
  23. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ErrorBlock.js.map +2 -2
  24. package/dist/cjs/components/LiveChatWidget/components/MessageContent/FAQList.js +1 -1
  25. package/dist/cjs/components/LiveChatWidget/components/MessageContent/FAQList.js.map +3 -3
  26. package/dist/cjs/components/LiveChatWidget/components/MessageContent/PolicyBlock.js +2 -2
  27. package/dist/cjs/components/LiveChatWidget/components/MessageContent/PolicyBlock.js.map +3 -3
  28. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +17 -24
  29. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js +1 -4
  30. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +3 -3
  31. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.d.ts +7 -1
  32. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.js +1 -1
  33. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductComparison.js.map +3 -3
  34. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductList.js +1 -1
  35. package/dist/cjs/components/LiveChatWidget/components/MessageContent/ProductList.js.map +3 -3
  36. package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.d.ts +4 -1
  37. package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.js +1 -1
  38. package/dist/cjs/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +3 -3
  39. package/dist/cjs/components/LiveChatWidget/components/MessageContent/QuickReplies.js +1 -1
  40. package/dist/cjs/components/LiveChatWidget/components/MessageContent/QuickReplies.js.map +2 -2
  41. package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js +1 -1
  42. package/dist/cjs/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +3 -3
  43. package/dist/cjs/components/LiveChatWidget/components/MessageContent.js +1 -1
  44. package/dist/cjs/components/LiveChatWidget/components/MessageContent.js.map +2 -2
  45. package/dist/cjs/components/LiveChatWidget/components/MessageList.js +2 -2
  46. package/dist/cjs/components/LiveChatWidget/components/MessageList.js.map +2 -2
  47. package/dist/cjs/components/LiveChatWidget/constants.d.ts +5 -0
  48. package/dist/cjs/components/LiveChatWidget/constants.js +1 -1
  49. package/dist/cjs/components/LiveChatWidget/constants.js.map +3 -3
  50. package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.d.ts +9 -0
  51. package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.js +1 -1
  52. package/dist/cjs/components/LiveChatWidget/hooks/useChatAPI.js.map +3 -3
  53. package/dist/cjs/components/LiveChatWidget/hooks/useChatState.d.ts +35 -2
  54. package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js +1 -1
  55. package/dist/cjs/components/LiveChatWidget/hooks/useChatState.js.map +3 -3
  56. package/dist/cjs/components/LiveChatWidget/index.d.ts +1 -1
  57. package/dist/cjs/components/LiveChatWidget/index.js +1 -1
  58. package/dist/cjs/components/LiveChatWidget/index.js.map +2 -2
  59. package/dist/cjs/components/LiveChatWidget/types.d.ts +212 -3
  60. package/dist/cjs/components/LiveChatWidget/types.js +1 -1
  61. package/dist/cjs/components/LiveChatWidget/types.js.map +1 -1
  62. package/dist/cjs/components/LiveChatWidget/utils/fetcher.d.ts +42 -0
  63. package/dist/cjs/components/LiveChatWidget/utils/fetcher.js +2 -0
  64. package/dist/cjs/components/LiveChatWidget/utils/fetcher.js.map +7 -0
  65. package/dist/cjs/components/chat/markdown.js +1 -1
  66. package/dist/cjs/components/chat/markdown.js.map +2 -2
  67. package/dist/cjs/components/credits/creditsBanner/index.js +2 -2
  68. package/dist/cjs/components/credits/creditsBanner/index.js.map +2 -2
  69. package/dist/cjs/components/index.d.ts +2 -0
  70. package/dist/cjs/components/index.js +1 -1
  71. package/dist/cjs/components/index.js.map +3 -3
  72. package/dist/cjs/stories/LiveChatWidget.stories.d.ts +1 -79
  73. package/dist/cjs/stories/LiveChatWidget.stories.js +8 -47
  74. package/dist/cjs/stories/LiveChatWidget.stories.js.map +3 -3
  75. package/dist/esm/components/LiveChatWidget/LiveChatWidget.d.ts +21 -1
  76. package/dist/esm/components/LiveChatWidget/LiveChatWidget.js +1 -1
  77. package/dist/esm/components/LiveChatWidget/LiveChatWidget.js.map +3 -3
  78. package/dist/esm/components/LiveChatWidget/api/chat.d.ts +23 -2
  79. package/dist/esm/components/LiveChatWidget/api/chat.js +2 -2
  80. package/dist/esm/components/LiveChatWidget/api/chat.js.map +3 -3
  81. package/dist/esm/components/LiveChatWidget/components/ChatHeader.js +1 -1
  82. package/dist/esm/components/LiveChatWidget/components/ChatHeader.js.map +2 -2
  83. package/dist/esm/components/LiveChatWidget/components/ChatInput.d.ts +5 -0
  84. package/dist/esm/components/LiveChatWidget/components/ChatInput.js +1 -1
  85. package/dist/esm/components/LiveChatWidget/components/ChatInput.js.map +3 -3
  86. package/dist/esm/components/LiveChatWidget/components/ChatMessage.js +2 -2
  87. package/dist/esm/components/LiveChatWidget/components/ChatMessage.js.map +3 -3
  88. package/dist/esm/components/LiveChatWidget/components/ChatWindow.d.ts +5 -0
  89. package/dist/esm/components/LiveChatWidget/components/ChatWindow.js +1 -1
  90. package/dist/esm/components/LiveChatWidget/components/ChatWindow.js.map +3 -3
  91. package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.d.ts +51 -0
  92. package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.js +33 -0
  93. package/dist/esm/components/LiveChatWidget/components/ComplianceDialog.js.map +7 -0
  94. package/dist/esm/components/LiveChatWidget/components/MessageContent/CartCard.js +1 -1
  95. package/dist/esm/components/LiveChatWidget/components/MessageContent/CartCard.js.map +3 -3
  96. package/dist/esm/components/LiveChatWidget/components/MessageContent/ErrorBlock.js +1 -1
  97. package/dist/esm/components/LiveChatWidget/components/MessageContent/ErrorBlock.js.map +2 -2
  98. package/dist/esm/components/LiveChatWidget/components/MessageContent/FAQList.js +1 -1
  99. package/dist/esm/components/LiveChatWidget/components/MessageContent/FAQList.js.map +3 -3
  100. package/dist/esm/components/LiveChatWidget/components/MessageContent/PolicyBlock.js +2 -2
  101. package/dist/esm/components/LiveChatWidget/components/MessageContent/PolicyBlock.js.map +3 -3
  102. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.d.ts +17 -24
  103. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js +1 -4
  104. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductCard.js.map +3 -3
  105. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.d.ts +7 -1
  106. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.js +1 -1
  107. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductComparison.js.map +3 -3
  108. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductList.js +1 -1
  109. package/dist/esm/components/LiveChatWidget/components/MessageContent/ProductList.js.map +3 -3
  110. package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.d.ts +4 -1
  111. package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.js +1 -1
  112. package/dist/esm/components/LiveChatWidget/components/MessageContent/PromotionList.js.map +3 -3
  113. package/dist/esm/components/LiveChatWidget/components/MessageContent/QuickReplies.js +1 -1
  114. package/dist/esm/components/LiveChatWidget/components/MessageContent/QuickReplies.js.map +2 -2
  115. package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js +1 -1
  116. package/dist/esm/components/LiveChatWidget/components/MessageContent/TextBlock.js.map +3 -3
  117. package/dist/esm/components/LiveChatWidget/components/MessageContent.js +1 -1
  118. package/dist/esm/components/LiveChatWidget/components/MessageContent.js.map +2 -2
  119. package/dist/esm/components/LiveChatWidget/components/MessageList.js +2 -2
  120. package/dist/esm/components/LiveChatWidget/components/MessageList.js.map +2 -2
  121. package/dist/esm/components/LiveChatWidget/constants.d.ts +5 -0
  122. package/dist/esm/components/LiveChatWidget/constants.js +1 -1
  123. package/dist/esm/components/LiveChatWidget/constants.js.map +3 -3
  124. package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.d.ts +9 -0
  125. package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.js +1 -1
  126. package/dist/esm/components/LiveChatWidget/hooks/useChatAPI.js.map +3 -3
  127. package/dist/esm/components/LiveChatWidget/hooks/useChatState.d.ts +35 -2
  128. package/dist/esm/components/LiveChatWidget/hooks/useChatState.js +1 -1
  129. package/dist/esm/components/LiveChatWidget/hooks/useChatState.js.map +3 -3
  130. package/dist/esm/components/LiveChatWidget/index.d.ts +1 -1
  131. package/dist/esm/components/LiveChatWidget/index.js +1 -1
  132. package/dist/esm/components/LiveChatWidget/index.js.map +2 -2
  133. package/dist/esm/components/LiveChatWidget/types.d.ts +212 -3
  134. package/dist/esm/components/LiveChatWidget/utils/fetcher.d.ts +42 -0
  135. package/dist/esm/components/LiveChatWidget/utils/fetcher.js +2 -0
  136. package/dist/esm/components/LiveChatWidget/utils/fetcher.js.map +7 -0
  137. package/dist/esm/components/chat/markdown.js +1 -1
  138. package/dist/esm/components/chat/markdown.js.map +2 -2
  139. package/dist/esm/components/credits/creditsBanner/index.js +2 -2
  140. package/dist/esm/components/credits/creditsBanner/index.js.map +2 -2
  141. package/dist/esm/components/index.d.ts +2 -0
  142. package/dist/esm/components/index.js +1 -1
  143. package/dist/esm/components/index.js.map +3 -3
  144. package/dist/esm/stories/LiveChatWidget.stories.d.ts +1 -79
  145. package/dist/esm/stories/LiveChatWidget.stories.js +8 -47
  146. package/dist/esm/stories/LiveChatWidget.stories.js.map +3 -3
  147. package/dist/index.d.mts +1305 -0
  148. package/dist/index.d.ts +1305 -0
  149. package/dist/index.js +26656 -0
  150. package/dist/index.js.map +1 -0
  151. package/dist/index.mjs +26641 -0
  152. package/dist/index.mjs.map +1 -0
  153. package/package.json +8 -1
  154. package/src/components/LiveChatWidget/LiveChatWidget.tsx +887 -0
  155. package/src/components/LiveChatWidget/api/chat.ts +175 -0
  156. package/src/components/LiveChatWidget/components/ChatBubble.tsx +152 -0
  157. package/src/components/LiveChatWidget/components/ChatHeader.tsx +150 -0
  158. package/src/components/LiveChatWidget/components/ChatInput.tsx +253 -0
  159. package/src/components/LiveChatWidget/components/ChatMessage.tsx +190 -0
  160. package/src/components/LiveChatWidget/components/ChatWindow.tsx +363 -0
  161. package/src/components/LiveChatWidget/components/ComplianceDialog.tsx +216 -0
  162. package/src/components/LiveChatWidget/components/MessageContent/CartCard.tsx +202 -0
  163. package/src/components/LiveChatWidget/components/MessageContent/ErrorBlock.tsx +75 -0
  164. package/src/components/LiveChatWidget/components/MessageContent/FAQList.tsx +128 -0
  165. package/src/components/LiveChatWidget/components/MessageContent/PolicyBlock.tsx +152 -0
  166. package/src/components/LiveChatWidget/components/MessageContent/ProductCard.tsx +227 -0
  167. package/src/components/LiveChatWidget/components/MessageContent/ProductComparison.tsx +377 -0
  168. package/src/components/LiveChatWidget/components/MessageContent/ProductList.tsx +293 -0
  169. package/src/components/LiveChatWidget/components/MessageContent/PromotionList.tsx +170 -0
  170. package/src/components/LiveChatWidget/components/MessageContent/QuickReplies.tsx +91 -0
  171. package/src/components/LiveChatWidget/components/MessageContent/TextBlock.tsx +110 -0
  172. package/src/components/LiveChatWidget/components/MessageContent/ThinkingBlock.tsx +53 -0
  173. package/src/components/LiveChatWidget/components/MessageContent/index.ts +16 -0
  174. package/src/components/LiveChatWidget/components/MessageContent.tsx +113 -0
  175. package/src/components/LiveChatWidget/components/MessageList.tsx +261 -0
  176. package/src/components/LiveChatWidget/components/ScrollAnchor.tsx +75 -0
  177. package/src/components/LiveChatWidget/constants.ts +36 -0
  178. package/src/components/LiveChatWidget/hooks/useChatAPI.ts +146 -0
  179. package/src/components/LiveChatWidget/hooks/useChatState.ts +1090 -0
  180. package/src/components/LiveChatWidget/hooks/useSession.ts +123 -0
  181. package/src/components/LiveChatWidget/index.tsx +63 -0
  182. package/src/components/LiveChatWidget/types.ts +1011 -0
  183. package/src/components/LiveChatWidget/utils/cartTransformers.ts +72 -0
  184. package/src/components/LiveChatWidget/utils/fetcher.ts +131 -0
  185. package/src/components/LiveChatWidget/utils/messageRenderers.ts +120 -0
  186. package/src/components/LiveChatWidget/utils/productTransformers.ts +149 -0
  187. package/src/components/LiveChatWidget/utils/userId.ts +140 -0
  188. package/src/components/LiveChatWidget/utils/validation.ts +99 -0
  189. package/src/components/chat/markdown.tsx +1 -1
  190. package/src/components/credits/creditsBanner/index.tsx +5 -5
  191. package/src/components/index.ts +23 -0
  192. package/src/stories/LiveChatWidget.stories.tsx +322 -0
  193. package/src/styles/livechat.css +317 -0
  194. package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.d.ts +0 -7
  195. package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.js +0 -2
  196. package/dist/cjs/components/credits/context/hooks/useFunctionMemberPrice.js.map +0 -7
  197. package/dist/cjs/components/credits/context/utils/atobID.d.ts +0 -1
  198. package/dist/cjs/components/credits/context/utils/atobID.js +0 -2
  199. package/dist/cjs/components/credits/context/utils/atobID.js.map +0 -7
  200. package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.d.ts +0 -5
  201. package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.js +0 -2
  202. package/dist/cjs/components/credits/context/utils/functionDiscountCalculate.js.map +0 -7
  203. package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.d.ts +0 -8
  204. package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.js +0 -2
  205. package/dist/cjs/components/credits/context/utils/getFunctionMemberPrice.js.map +0 -7
  206. package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.d.ts +0 -9
  207. package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js +0 -2
  208. package/dist/cjs/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js.map +0 -7
  209. package/dist/cjs/components/credits/context/utils/variantGetCoupon.d.ts +0 -6
  210. package/dist/cjs/components/credits/context/utils/variantGetCoupon.js +0 -2
  211. package/dist/cjs/components/credits/context/utils/variantGetCoupon.js.map +0 -7
  212. package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.d.ts +0 -7
  213. package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.js +0 -2
  214. package/dist/esm/components/credits/context/hooks/useFunctionMemberPrice.js.map +0 -7
  215. package/dist/esm/components/credits/context/utils/atobID.d.ts +0 -1
  216. package/dist/esm/components/credits/context/utils/atobID.js +0 -2
  217. package/dist/esm/components/credits/context/utils/atobID.js.map +0 -7
  218. package/dist/esm/components/credits/context/utils/functionDiscountCalculate.d.ts +0 -5
  219. package/dist/esm/components/credits/context/utils/functionDiscountCalculate.js +0 -2
  220. package/dist/esm/components/credits/context/utils/functionDiscountCalculate.js.map +0 -7
  221. package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.d.ts +0 -8
  222. package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.js +0 -2
  223. package/dist/esm/components/credits/context/utils/getFunctionMemberPrice.js.map +0 -7
  224. package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.d.ts +0 -9
  225. package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js +0 -2
  226. package/dist/esm/components/credits/context/utils/getFunctionMemberPriceDiscountConfig.js.map +0 -7
  227. package/dist/esm/components/credits/context/utils/variantGetCoupon.d.ts +0 -6
  228. package/dist/esm/components/credits/context/utils/variantGetCoupon.js +0 -2
  229. package/dist/esm/components/credits/context/utils/variantGetCoupon.js.map +0 -7
@@ -5,7 +5,7 @@ import remarkMath from 'remark-math'
5
5
 
6
6
  const MemoizedReactMarkdown: FC<Options> = memo(
7
7
  ReactMarkdown,
8
- (prevProps, nextProps) => prevProps.children === nextProps.children && prevProps.className === nextProps.className
8
+ (prevProps, nextProps) => prevProps.children === nextProps.children
9
9
  )
10
10
 
11
11
  type MarkdownProps = {
@@ -80,25 +80,25 @@ export function CreditsBanner({ copy, id }: { copy: CreditsBannerCopy; id?: stri
80
80
  ></div>
81
81
  )}
82
82
 
83
- <Container className="l-tablet:h-auto !absolute inset-0 mx-auto grid h-full" asChild>
83
+ <Container className="l:h-auto !absolute inset-0 mx-auto grid h-full" asChild>
84
84
  <div className="grid grid-cols-12">
85
- <div className="l-tablet:col-span-12 l-tablet:justify-start l-tablet:truncate l-tablet:pt-[32px] col-span-5 flex h-full flex-col justify-center text-[#1F2021]">
85
+ <div className="l:col-span-12 l:justify-start l:truncate l:pt-[32px] col-span-5 flex h-full flex-col justify-center text-[#1F2021]">
86
86
  <Heading
87
87
  as="h1"
88
- className="text-[48px] font-bold xl-xxl:text-[40px] l-tablet:text-[32px]"
88
+ className="text-[48px] font-bold xl-xxl:text-[40px] l:text-[32px]"
89
89
  html={isLogin ? copy.login.title?.replace('$name', displayName || '') : copy.unLogin.title}
90
90
  ></Heading>
91
91
 
92
92
  <Text
93
93
  size="3"
94
- className="l-tablet:mt-[4px] l-xxl:text-[14px] mt-[16px]"
94
+ className="l:mt-[4px] l-xxl:text-[14px] mt-[16px]"
95
95
  html={isLogin ? copy.login.description : copy.unLogin.description}
96
96
  ></Text>
97
97
 
98
98
  {!isLogin && (
99
99
  <div
100
100
  className={classNames(
101
- 'mt-[32px] grid w-fit grid-flow-col gap-[12px] l-tablet:mt-[24px]',
101
+ 'mt-[32px] grid w-fit grid-flow-col gap-[12px] l:mt-[24px]',
102
102
  isLogin && 'hidden'
103
103
  )}
104
104
  >
@@ -12,3 +12,26 @@ export {
12
12
  export * from './credits/index.js'
13
13
 
14
14
  export * from './registration/index.js'
15
+
16
+
17
+
18
+ // LiveChatWidget 导出
19
+ export { LiveChatWidget } from './LiveChatWidget/index.js'
20
+ export type {
21
+ LiveChatWidgetProps,
22
+ Message,
23
+ MessageContent,
24
+ MessageRole,
25
+ MessageContentType,
26
+ MessageMetadata,
27
+ MessageRenderer,
28
+ QuickReply,
29
+ ProductCardContent,
30
+ ProductListContent,
31
+ PolicyContent,
32
+ QuickRepliesContent,
33
+ ThinkingContent,
34
+ ErrorContent,
35
+ SSEEvent,
36
+ ChatStreamRequest,
37
+ } from './LiveChatWidget/index.js'
@@ -0,0 +1,322 @@
1
+ /**
2
+ * LiveChatWidget Storybook Stories
3
+ * 展示 LiveChat 组件的各种使用场景和配置
4
+ */
5
+
6
+ import type { Meta, StoryObj } from '@storybook/react'
7
+ import { LiveChatWidget } from '../components/LiveChatWidget'
8
+ import type { MessageRenderer, MessageContent } from '../components/LiveChatWidget'
9
+ import '../styles/livechat.css'
10
+
11
+ const meta: Meta<typeof LiveChatWidget> = {
12
+ title: 'Campaign/LiveChatWidget',
13
+ component: LiveChatWidget,
14
+ parameters: {
15
+ layout: 'fullscreen',
16
+ docs: {
17
+ story: {
18
+ inline: false,
19
+ iframeHeight: 500,
20
+ },
21
+ description: {
22
+ component: `
23
+ # LiveChat 聊天组件
24
+
25
+ 可复用的气泡弹窗聊天组件,支持 SSE 流式消息、自定义渲染器和多种消息类型。
26
+
27
+ ## 功能特性
28
+
29
+ - 🎈 **气泡弹窗**: 可自定义位置的悬浮气泡按钮
30
+ - 💬 **流式消息**: 基于 SSE 的实时流式响应
31
+ - 📦 **多种消息类型**: 文本、商品卡片、商品列表、政策、快捷回复等
32
+ - 🎨 **可定制**: 支持自定义品牌颜色、Logo、渲染器
33
+ - 📱 **响应式**: 移动端全屏,桌面端固定尺寸
34
+ - 💾 **会话管理**: 自动管理 userId 和 sessionId
35
+ - 🔒 **安全防护**: 内置 XSS 防护和输入验证
36
+
37
+ ## 基础用法
38
+
39
+ \`\`\`tsx
40
+ import { LiveChatWidget } from '@anker-in/campaign-ui'
41
+ import '@anker-in/campaign-ui/livechat.css'
42
+
43
+ function App() {
44
+ return (
45
+ <LiveChatWidget
46
+ apiBaseUrl="https://beta-api-livechat.anker.com"
47
+ site="www.eufy.com"
48
+ channel_code="web_homepage"
49
+ welcomeMessage="你好!我是 AI 助手"
50
+ />
51
+ )
52
+ }
53
+ \`\`\`
54
+
55
+ ## 自定义渲染器
56
+
57
+ \`\`\`tsx
58
+ const customRenderers = {
59
+ video: {
60
+ render: (content) => (
61
+ <video src={content.url} controls className="w-full rounded" />
62
+ )
63
+ }
64
+ }
65
+
66
+ <LiveChatWidget
67
+ apiBaseUrl="..."
68
+ site="..."
69
+ customRenderers={customRenderers}
70
+ />
71
+ \`\`\`
72
+ `,
73
+ },
74
+ },
75
+ },
76
+ tags: ['autodocs'],
77
+ argTypes: {
78
+ apiBaseUrl: {
79
+ control: 'text',
80
+ description: 'API 基础 URL',
81
+ },
82
+ headers: {
83
+ control: 'object',
84
+ description: '自定义请求头,将在所有 API 请求中添加',
85
+ table: {
86
+ defaultValue: { summary: 'undefined' },
87
+ },
88
+ },
89
+ recaptchaSitekey: {
90
+ control: 'text',
91
+ description: 'Google reCAPTCHA v3 site key,提供此参数将自动启用 reCAPTCHA v3 验证',
92
+ table: {
93
+ defaultValue: { summary: 'undefined' },
94
+ },
95
+ },
96
+ recaptchaAction: {
97
+ control: 'text',
98
+ description: 'reCAPTCHA action 名称,用于区分不同的验证场景',
99
+ table: {
100
+ defaultValue: { summary: '"activity"' },
101
+ },
102
+ },
103
+ site: {
104
+ control: 'text',
105
+ description: 'Shopify 店铺 URL',
106
+ },
107
+ channelCode: {
108
+ control: 'text',
109
+ description: '渠道编码,用于标识来源渠道',
110
+ table: {
111
+ defaultValue: { summary: 'undefined' },
112
+ },
113
+ },
114
+ welcomeMessage: {
115
+ control: 'text',
116
+ description: '欢迎消息',
117
+ table: {
118
+ defaultValue: { summary: '你好!我是 AI 助手,有什么可以帮助你的吗?' },
119
+ },
120
+ },
121
+ logoUrl: {
122
+ control: 'text',
123
+ description: 'Logo URL',
124
+ },
125
+ position: {
126
+ control: 'object',
127
+ description: '气泡按钮位置对象',
128
+ table: {
129
+ defaultValue: { summary: '{ bottom: "1.5rem", right: "1.5rem" }' },
130
+ },
131
+ },
132
+ },
133
+ args: {
134
+ apiBaseUrl: 'http://172.16.38.183:3003',
135
+ site: 'www.eufy.com',
136
+ loginUserId: 'test_test',
137
+ welcomeMessage: '你好!我是 AI 助手,有什么可以帮助你的吗?',
138
+ },
139
+ }
140
+
141
+ export default meta
142
+ type Story = StoryObj<typeof LiveChatWidget>
143
+
144
+ /**
145
+ * 默认配置 - 展示所有功能
146
+ */
147
+ export const Default: Story = {
148
+ args: {
149
+ // 基础配置
150
+ loginUserId: 'test_test',
151
+ apiBaseUrl: 'http://172.16.38.183:3003',
152
+ site: 'beta.eufy.com',
153
+ channelCode: 'dtc',
154
+ title: 'eufy AI Assistant',
155
+ cartId: 'gid://shopify/Cart/hWN7wB3Pa12gh78d8hPOAUBI?key=0e73db1d3fb5ac21da19099c45033253',
156
+ accessToken: '47b1aa2c0797043f9baba39388029d70',
157
+
158
+ // 自定义位置
159
+ position: { bottom: '24px', right: '30px' },
160
+
161
+ // 欢迎消息
162
+ welcomeMessage: `Welcome to eufy AI Assistant!
163
+
164
+ I can help you with:
165
+ - Product recommendations
166
+ - Order tracking
167
+ - FAQs and support
168
+
169
+ How can I assist you today?`,
170
+
171
+ // 快捷回复
172
+ quickReplies: [
173
+ { id: '1', label: 'Product Info', value: 'Tell me about your products', icon: '📦' },
174
+ { id: '2', label: 'Track Order', value: 'I want to track my order', icon: '🚚' },
175
+ { id: '3', label: 'Support', value: 'I need help with my device', icon: '🔧' },
176
+ { id: '4', label: 'Recommendations', value: 'Recommend products for me', icon: '⭐' },
177
+ ],
178
+
179
+ // 法规协议弹窗
180
+ complianceConfig: {
181
+ title: "Hi! I'm your eufy AI assistant.",
182
+ content: "AI-generated responses can be inaccurate. Please verify important info. Do not input sensitive personal data.",
183
+ checkboxText: 'By starting to use "Live Chat", you agree to Anker\'s <a href="https://www.anker.com/pages/privacy-policy" target="_blank" rel="noopener noreferrer" style="text-decoration: underline;">LIVE CHAT PRIVACY NOTICE</a>.',
184
+ agreeButtonText: "Agree"
185
+ },
186
+
187
+ // reCAPTCHA 配置(取消注释以启用)
188
+ // recaptchaSitekey: '6LfS4J4pAAAAACX1e_WrxutmxxzCK7FU4WzVqL14',
189
+ recaptchaAction: 'livechat',
190
+
191
+ // 显示新会话按钮
192
+ showNewSessionButton: true,
193
+
194
+ // 自定义文案
195
+ commonText: {
196
+ learnMore: 'Learn More',
197
+ total: 'Total',
198
+ },
199
+
200
+ // 自定义消息渲染器
201
+ customRenderers: {
202
+ video: {
203
+ render: (content: MessageContent) => {
204
+ const videoContent = content as any
205
+ return (
206
+ <div className="w-full">
207
+ <video src={videoContent.url} controls className="w-full rounded-lg" poster={videoContent.poster}>
208
+ Your browser does not support video playback
209
+ </video>
210
+ {videoContent.title && <p className="mt-2 text-sm text-gray-600">{videoContent.title}</p>}
211
+ </div>
212
+ )
213
+ },
214
+ } as MessageRenderer,
215
+ image_gallery: {
216
+ render: (content: MessageContent) => {
217
+ const galleryContent = content as any
218
+ const images = galleryContent.images || []
219
+ return (
220
+ <div className="grid grid-cols-2 gap-2">
221
+ {images.map((image: any, index: number) => (
222
+ <div key={index} className="relative aspect-square">
223
+ <img
224
+ src={image.url}
225
+ alt={image.alt || `Image ${index + 1}`}
226
+ className="size-full rounded-lg object-cover"
227
+ />
228
+ </div>
229
+ ))}
230
+ </div>
231
+ )
232
+ },
233
+ } as MessageRenderer,
234
+ },
235
+
236
+ // 自定义产品卡片渲染
237
+ productCardRender: (product, productHandle) => {
238
+ // product 可能为 undefined,此时可用 productHandle 查询
239
+ if (!product) {
240
+ return (
241
+ <div style={{ padding: '16px', border: '1px dashed #ccc', borderRadius: '8px', textAlign: 'center' }}>
242
+ <p>Product loading... (handle: {productHandle})</p>
243
+ </div>
244
+ )
245
+ }
246
+
247
+ const imageUrl = product?.featured_image || ''
248
+ const title = product?.title || ''
249
+ const description = product?.description || ''
250
+ const averageRating = product?.average_rating
251
+
252
+ return (
253
+ <div
254
+ style={{
255
+ border: '2px solid #4CAF50',
256
+ borderRadius: '16px',
257
+ padding: '16px',
258
+ margin: '12px 0',
259
+ backgroundColor: '#f0f9ff',
260
+ boxShadow: '0 4px 12px rgba(76, 175, 80, 0.15)',
261
+ }}
262
+ >
263
+ <div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
264
+ {imageUrl && (
265
+ <img
266
+ src={imageUrl}
267
+ alt={title}
268
+ style={{ width: '60px', height: '60px', borderRadius: '8px', objectFit: 'cover' }}
269
+ />
270
+ )}
271
+ <div style={{ flex: 1 }}>
272
+ <h4 style={{ margin: '0 0 4px 0', fontSize: '16px', fontWeight: 'bold' }}>{title}</h4>
273
+ {description && (
274
+ <p style={{ margin: 0, fontSize: '12px', color: '#666', lineHeight: 1.4 }}>
275
+ {description.slice(0, 80)}...
276
+ </p>
277
+ )}
278
+ {averageRating && (
279
+ <span style={{ fontSize: '12px', color: '#FFB800' }}>Rating: {averageRating.toFixed(1)}</span>
280
+ )}
281
+ </div>
282
+ <button
283
+ style={{
284
+ padding: '8px 16px',
285
+ backgroundColor: '#4CAF50',
286
+ color: 'white',
287
+ borderRadius: '8px',
288
+ border: 'none',
289
+ cursor: 'pointer',
290
+ }}
291
+ onClick={() => console.log('View product:', productHandle, product)}
292
+ >
293
+ View
294
+ </button>
295
+ </div>
296
+ </div>
297
+ )
298
+ },
299
+ },
300
+
301
+ render: args => (
302
+ <LiveChatWidget
303
+ {...args}
304
+ // 所有事件回调
305
+ onOpen={() => console.log('[LiveChat] Chat opened')}
306
+ onClose={() => console.log('[LiveChat] Chat closed')}
307
+ onMessageSend={(message: string) => console.log('[LiveChat] Message sent:', message)}
308
+ onError={(error: Error) => console.error('[LiveChat] Error:', error)}
309
+ onTextMessage={() => console.log('[LiveChat] AI text message received')}
310
+ onProductList={() => console.log('[LiveChat] Product list received')}
311
+ onPromotionList={() => console.log('[LiveChat] Promotion list received')}
312
+ onAddToCart={(product: any) => {
313
+ console.log('[LiveChat] Add to cart:', product)
314
+ alert(`Added "${product.title}" to cart!`)
315
+ }}
316
+ onCart={(cartId: string, checkoutUrl?: string) => {
317
+ console.log('[LiveChat] Cart clicked:', { cartId, checkoutUrl })
318
+ alert(`Cart ID: ${cartId}`)
319
+ }}
320
+ />
321
+ ),
322
+ }
@@ -0,0 +1,317 @@
1
+ /**
2
+ * LiveChat Widget Styles
3
+ *
4
+ * 这个文件包含 LiveChat 组件的基础样式
5
+ * 使用 CSS 变量支持主题定制
6
+ */
7
+
8
+ :root {
9
+ /* 品牌颜色 */
10
+ --livechat-primary: #005D8E;
11
+ --livechat-primary-hover: #005D8E;
12
+ --livechat-background: #ffffff;
13
+ --livechat-text: #111827;
14
+ --livechat-text-secondary: #6b7280;
15
+ --livechat-border: #e5e7eb;
16
+
17
+ /* 消息颜色 */
18
+ --livechat-user-message-bg: #f3f4f6;
19
+ --livechat-assistant-message-bg: #ffffff;
20
+ --livechat-thinking-bg: #fef3c7;
21
+ --livechat-error-bg: #fee2e2;
22
+
23
+ /* 尺寸 */
24
+ --livechat-bubble-size: 48px;
25
+ --livechat-window-width: 390px;
26
+ --livechat-window-height: 80%;
27
+ --livechat-border-radius: 1rem;
28
+
29
+ /* 阴影 */
30
+ --livechat-shadow-sm: 0 1px 2px 0 rgb(0 0 0 / 0.05);
31
+ --livechat-shadow-md: 0 4px 6px -1px rgb(0 0 0 / 0.1);
32
+ --livechat-shadow-lg: 0 10px 15px -3px rgb(0 0 0 / 0.1);
33
+ --livechat-shadow-xl: 0 0 24px rgba(0, 0, 0, 0.15);
34
+ }
35
+
36
+ /* 气泡按钮基础样式 */
37
+ .livechat-bubble {
38
+ position: fixed;
39
+ width: var(--livechat-bubble-size);
40
+ height: var(--livechat-bubble-size);
41
+ border-radius: 50%;
42
+ background: var(--livechat-primary);
43
+ color: white;
44
+ box-shadow: var(--livechat-shadow-xl);
45
+ transition: all 0.2s ease-in-out;
46
+ z-index: 9999;
47
+ }
48
+
49
+ .livechat-bubble:hover {
50
+ background: var(--livechat-primary-hover);
51
+ transform: scale(1.05);
52
+ }
53
+
54
+ .livechat-bubble:active {
55
+ transform: scale(0.95);
56
+ }
57
+
58
+ /* 移动端固定底部样式 */
59
+ @media (max-width: 767px) {
60
+ .livechat-window {
61
+ position: fixed;
62
+ bottom: 0;
63
+ left: 0;
64
+ right: 0;
65
+ width: 100vw;
66
+ height: var(--livechat-mobile-height, 680px); /* 默认高度680px,可通过拖拽调整(最小30%,最大80%) */
67
+ max-height: 80%;
68
+ border-radius: 16px 16px 0 0; /* 上方圆角 */
69
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
70
+ }
71
+ }
72
+
73
+ /* 平板及以上固定尺寸弹窗样式 */
74
+ @media (min-width: 768px) {
75
+ .livechat-window {
76
+ position: fixed;
77
+ bottom: 1rem;
78
+ right: 1rem;
79
+ width: var(--livechat-window-width);
80
+ height: 70vh;
81
+ border-radius: var(--livechat-border-radius);
82
+ box-shadow: var(--livechat-shadow-xl);
83
+ }
84
+ }
85
+
86
+ /* 大屏幕固定高度 */
87
+ @media (min-width: 1920px) {
88
+ .livechat-window {
89
+ height: 720px;
90
+ }
91
+ }
92
+
93
+ /* 聊天窗口动画 */
94
+ .livechat-window-enter {
95
+ animation: livechat-slide-in 0.3s ease-out;
96
+ }
97
+
98
+ .livechat-window-exit {
99
+ animation: livechat-slide-out 0.3s ease-in;
100
+ }
101
+
102
+ @keyframes livechat-slide-in {
103
+ from {
104
+ opacity: 0;
105
+ transform: translateY(1rem);
106
+ }
107
+ to {
108
+ opacity: 1;
109
+ transform: translateY(0);
110
+ }
111
+ }
112
+
113
+ @keyframes livechat-slide-out {
114
+ from {
115
+ opacity: 1;
116
+ transform: translateY(0);
117
+ }
118
+ to {
119
+ opacity: 0;
120
+ transform: translateY(1rem);
121
+ }
122
+ }
123
+
124
+ /* 消息列表滚动样式 */
125
+ .livechat-message-list {
126
+ scrollbar-width: thin;
127
+ scrollbar-color: var(--livechat-border) transparent;
128
+ }
129
+
130
+ .livechat-message-list::-webkit-scrollbar {
131
+ width: 6px;
132
+ }
133
+
134
+ .livechat-message-list::-webkit-scrollbar-track {
135
+ background: transparent;
136
+ }
137
+
138
+ .livechat-message-list::-webkit-scrollbar-thumb {
139
+ background: var(--livechat-border);
140
+ border-radius: 3px;
141
+ }
142
+
143
+ .livechat-message-list::-webkit-scrollbar-thumb:hover {
144
+ background: var(--livechat-text-secondary);
145
+ }
146
+
147
+ /* 思考状态动画 */
148
+ .livechat-thinking-dots {
149
+ display: inline-flex;
150
+ gap: 0.25rem;
151
+ }
152
+
153
+ .livechat-thinking-dots span {
154
+ width: 0.5rem;
155
+ height: 0.5rem;
156
+ border-radius: 50%;
157
+ animation: livechat-thinking 1.4s infinite ease-in-out;
158
+ }
159
+
160
+ .livechat-thinking-dots span:nth-child(1) {
161
+ animation-delay: -0.32s;
162
+ }
163
+
164
+ .livechat-thinking-dots span:nth-child(2) {
165
+ animation-delay: -0.16s;
166
+ }
167
+
168
+ @keyframes livechat-thinking {
169
+ 0%, 80%, 100% {
170
+ transform: scale(0);
171
+ opacity: 0.5;
172
+ }
173
+ 40% {
174
+ transform: scale(1);
175
+ opacity: 1;
176
+ }
177
+ }
178
+
179
+ /* 商品卡片基础样式 */
180
+ .livechat-product-card {
181
+ border: 1px solid var(--livechat-border);
182
+ border-radius: 0.5rem;
183
+ overflow: hidden;
184
+ transition: all 0.2s ease-in-out;
185
+ }
186
+
187
+ .livechat-product-card:hover {
188
+ box-shadow: var(--livechat-shadow-md);
189
+ transform: translateY(-2px);
190
+ }
191
+
192
+ /* 产品列表横向滚动样式 */
193
+ .livechat-product-scroll {
194
+ scrollbar-width: thin;
195
+ scrollbar-color: var(--livechat-border) transparent;
196
+ }
197
+
198
+ .livechat-product-scroll::-webkit-scrollbar {
199
+ height: 8px;
200
+ }
201
+
202
+ .livechat-product-scroll::-webkit-scrollbar-track {
203
+ background: var(--livechat-user-message-bg);
204
+ border-radius: 4px;
205
+ }
206
+
207
+ .livechat-product-scroll::-webkit-scrollbar-thumb {
208
+ background: var(--livechat-border);
209
+ border-radius: 4px;
210
+ }
211
+
212
+ .livechat-product-scroll::-webkit-scrollbar-thumb:hover {
213
+ background: var(--livechat-text-secondary);
214
+ }
215
+
216
+ /* 快捷回复按钮样式 */
217
+ .livechat-quick-reply-button {
218
+ background-color: #EAEAEC;
219
+ color: #1D1D1F;
220
+ border: none;
221
+ border-radius: 19px;
222
+ transition: all 0.2s ease-in-out;
223
+ }
224
+
225
+ .livechat-quick-reply-button:hover {
226
+ background-color: #005D8E;
227
+ color: #ffffff;
228
+ }
229
+
230
+ /* Markdown 内容样式 */
231
+ .livechat-markdown {
232
+ line-height: 1.4;
233
+ font-weight: 700;
234
+ }
235
+
236
+ .livechat-markdown ul,
237
+ .livechat-markdown ol {
238
+ margin-left: 1.5rem;
239
+ }
240
+
241
+ .livechat-markdown li {
242
+ margin-bottom: 0.25rem;
243
+ }
244
+
245
+ .livechat-markdown a {
246
+ color: var(--livechat-primary);
247
+ text-decoration: underline;
248
+ }
249
+
250
+ .livechat-markdown a:hover {
251
+ color: var(--livechat-primary-hover);
252
+ }
253
+
254
+ .livechat-markdown code {
255
+ background: var(--livechat-user-message-bg);
256
+ padding: 0.125rem 0.25rem;
257
+ border-radius: 0.25rem;
258
+ font-family: ui-monospace, monospace;
259
+ font-size: 0.875em;
260
+ }
261
+
262
+ .livechat-markdown strong {
263
+ font-weight: 700;
264
+ }
265
+
266
+ .livechat-markdown em {
267
+ font-style: italic;
268
+ }
269
+
270
+ /* ============================================================================
271
+ 法规协议弹窗样式(与聊天窗口保持一致)
272
+ ============================================================================ */
273
+
274
+ /* 基础样式 */
275
+ .livechat-compliance-dialog {
276
+ background: white;
277
+ display: flex;
278
+ flex-direction: column;
279
+ overflow: hidden;
280
+ animation: livechat-slide-in 0.3s ease-out;
281
+ }
282
+
283
+ /* 移动端固定底部样式 */
284
+ @media (max-width: 767px) {
285
+ .livechat-compliance-dialog {
286
+ position: fixed !important; /* 防止被覆盖 */
287
+ bottom: 0 !important;
288
+ left: 0 !important;
289
+ right: 0 !important;
290
+ width: 100vw;
291
+ max-height: 80%;
292
+ border-radius: 16px 16px 0 0; /* 上方圆角,与聊天窗口一致 */
293
+ box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
294
+ z-index: 9998;
295
+ }
296
+ }
297
+
298
+ /* 平板及以上固定尺寸弹窗样式 */
299
+ @media (min-width: 768px) {
300
+ .livechat-compliance-dialog {
301
+ position: fixed !important; /* 防止被覆盖 */
302
+ bottom: 1rem !important;
303
+ right: 1rem !important;
304
+ width: var(--livechat-window-width); /* 390px,与聊天窗口一致 */
305
+ max-height: 70vh;
306
+ border-radius: var(--livechat-border-radius); /* 1rem */
307
+ box-shadow: var(--livechat-shadow-xl);
308
+ z-index: 9998;
309
+ }
310
+ }
311
+
312
+ /* 大屏幕适配 */
313
+ @media (min-width: 1920px) {
314
+ .livechat-compliance-dialog {
315
+ max-height: 720px;
316
+ }
317
+ }