@baishuyun/ai-design 1.0.0

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 (366) hide show
  1. package/.storybook/main.ts +29 -0
  2. package/.storybook/preview.ts +16 -0
  3. package/.turbo/turbo-build.log +14 -0
  4. package/CHANGELOG.md +12 -0
  5. package/components.json +22 -0
  6. package/debug-storybook.log +88 -0
  7. package/dist/ai-design.js +20482 -0
  8. package/dist/ai-design.js.map +1 -0
  9. package/dist/ai-design.umd.cjs +260 -0
  10. package/dist/ai-design.umd.cjs.map +1 -0
  11. package/dist/src/components/abs-fullscreen-gradient-bg.d.ts +10 -0
  12. package/dist/src/components/abs-fullscreen-gradient-bg.d.ts.map +1 -0
  13. package/dist/src/components/agent-scroll-selector.d.ts +11 -0
  14. package/dist/src/components/agent-scroll-selector.d.ts.map +1 -0
  15. package/dist/src/components/agent-select.d.ts +16 -0
  16. package/dist/src/components/agent-select.d.ts.map +1 -0
  17. package/dist/src/components/attachment-part-group.d.ts +16 -0
  18. package/dist/src/components/attachment-part-group.d.ts.map +1 -0
  19. package/dist/src/components/attachment-part.d.ts +19 -0
  20. package/dist/src/components/attachment-part.d.ts.map +1 -0
  21. package/dist/src/components/attachments-previewer.d.ts +18 -0
  22. package/dist/src/components/attachments-previewer.d.ts.map +1 -0
  23. package/dist/src/components/base-button.d.ts +8 -0
  24. package/dist/src/components/base-button.d.ts.map +1 -0
  25. package/dist/src/components/border-animation.d.ts +23 -0
  26. package/dist/src/components/border-animation.d.ts.map +1 -0
  27. package/dist/src/components/border-color-animation.d.ts +11 -0
  28. package/dist/src/components/border-color-animation.d.ts.map +1 -0
  29. package/dist/src/components/bot-avatar-name.d.ts +6 -0
  30. package/dist/src/components/bot-avatar-name.d.ts.map +1 -0
  31. package/dist/src/components/bot-icon.d.ts +5 -0
  32. package/dist/src/components/bot-icon.d.ts.map +1 -0
  33. package/dist/src/components/bs-entry-select.d.ts +18 -0
  34. package/dist/src/components/bs-entry-select.d.ts.map +1 -0
  35. package/dist/src/components/bs-icons.d.ts +75 -0
  36. package/dist/src/components/bs-icons.d.ts.map +1 -0
  37. package/dist/src/components/card-field.d.ts +11 -0
  38. package/dist/src/components/card-field.d.ts.map +1 -0
  39. package/dist/src/components/card.d.ts +11 -0
  40. package/dist/src/components/card.d.ts.map +1 -0
  41. package/dist/src/components/chat-area-header.d.ts +13 -0
  42. package/dist/src/components/chat-area-header.d.ts.map +1 -0
  43. package/dist/src/components/circle-checker.d.ts +10 -0
  44. package/dist/src/components/circle-checker.d.ts.map +1 -0
  45. package/dist/src/components/collapsible-txt-msg.d.ts +11 -0
  46. package/dist/src/components/collapsible-txt-msg.d.ts.map +1 -0
  47. package/dist/src/components/confirm-dialog.d.ts +26 -0
  48. package/dist/src/components/confirm-dialog.d.ts.map +1 -0
  49. package/dist/src/components/fake-bot-msg.d.ts +8 -0
  50. package/dist/src/components/fake-bot-msg.d.ts.map +1 -0
  51. package/dist/src/components/fields-design-info-table.d.ts +7 -0
  52. package/dist/src/components/fields-design-info-table.d.ts.map +1 -0
  53. package/dist/src/components/fields-generating-indicator.d.ts +6 -0
  54. package/dist/src/components/fields-generating-indicator.d.ts.map +1 -0
  55. package/dist/src/components/fields-portal.d.ts +8 -0
  56. package/dist/src/components/fields-portal.d.ts.map +1 -0
  57. package/dist/src/components/fields-previewer.d.ts +19 -0
  58. package/dist/src/components/fields-previewer.d.ts.map +1 -0
  59. package/dist/src/components/font-icon.d.ts +6 -0
  60. package/dist/src/components/font-icon.d.ts.map +1 -0
  61. package/dist/src/components/form-info-editor.d.ts +31 -0
  62. package/dist/src/components/form-info-editor.d.ts.map +1 -0
  63. package/dist/src/components/formula-tag.d.ts +8 -0
  64. package/dist/src/components/formula-tag.d.ts.map +1 -0
  65. package/dist/src/components/generate-animation.d.ts +5 -0
  66. package/dist/src/components/generate-animation.d.ts.map +1 -0
  67. package/dist/src/components/icon-btn.d.ts +9 -0
  68. package/dist/src/components/icon-btn.d.ts.map +1 -0
  69. package/dist/src/components/img-part.d.ts +10 -0
  70. package/dist/src/components/img-part.d.ts.map +1 -0
  71. package/dist/src/components/legacy-slot.d.ts +11 -0
  72. package/dist/src/components/legacy-slot.d.ts.map +1 -0
  73. package/dist/src/components/line-checker.d.ts +19 -0
  74. package/dist/src/components/line-checker.d.ts.map +1 -0
  75. package/dist/src/components/linear-gradient-border-btn.d.ts +10 -0
  76. package/dist/src/components/linear-gradient-border-btn.d.ts.map +1 -0
  77. package/dist/src/components/linear-gradient-color-bg-animation.d.ts +8 -0
  78. package/dist/src/components/linear-gradient-color-bg-animation.d.ts.map +1 -0
  79. package/dist/src/components/memoized-markdown.d.ts +5 -0
  80. package/dist/src/components/memoized-markdown.d.ts.map +1 -0
  81. package/dist/src/components/message-content.d.ts +6 -0
  82. package/dist/src/components/message-content.d.ts.map +1 -0
  83. package/dist/src/components/number-part.d.ts +9 -0
  84. package/dist/src/components/number-part.d.ts.map +1 -0
  85. package/dist/src/components/office-container.d.ts +12 -0
  86. package/dist/src/components/office-container.d.ts.map +1 -0
  87. package/dist/src/components/option-item.d.ts +9 -0
  88. package/dist/src/components/option-item.d.ts.map +1 -0
  89. package/dist/src/components/previewer-header.d.ts +21 -0
  90. package/dist/src/components/previewer-header.d.ts.map +1 -0
  91. package/dist/src/components/primary-confirm-btn.d.ts +10 -0
  92. package/dist/src/components/primary-confirm-btn.d.ts.map +1 -0
  93. package/dist/src/components/primary-entry-btn.d.ts +9 -0
  94. package/dist/src/components/primary-entry-btn.d.ts.map +1 -0
  95. package/dist/src/components/scroll-to-bottom-btn.d.ts +6 -0
  96. package/dist/src/components/scroll-to-bottom-btn.d.ts.map +1 -0
  97. package/dist/src/components/split-line.d.ts +5 -0
  98. package/dist/src/components/split-line.d.ts.map +1 -0
  99. package/dist/src/components/square-checker.d.ts +15 -0
  100. package/dist/src/components/square-checker.d.ts.map +1 -0
  101. package/dist/src/components/tab-radio-group.d.ts +20 -0
  102. package/dist/src/components/tab-radio-group.d.ts.map +1 -0
  103. package/dist/src/components/tooltip.d.ts +6 -0
  104. package/dist/src/components/tooltip.d.ts.map +1 -0
  105. package/dist/src/components/ui/button.d.ts +12 -0
  106. package/dist/src/components/ui/button.d.ts.map +1 -0
  107. package/dist/src/components/ui/dialog.d.ts +24 -0
  108. package/dist/src/components/ui/dialog.d.ts.map +1 -0
  109. package/dist/src/components/ui/icons.d.ts +176 -0
  110. package/dist/src/components/ui/icons.d.ts.map +1 -0
  111. package/dist/src/components/ui/popover.d.ts +10 -0
  112. package/dist/src/components/ui/popover.d.ts.map +1 -0
  113. package/dist/src/components/ui/spinner.d.ts +3 -0
  114. package/dist/src/components/ui/spinner.d.ts.map +1 -0
  115. package/dist/src/components/ui/tooltip.d.ts +13 -0
  116. package/dist/src/components/ui/tooltip.d.ts.map +1 -0
  117. package/dist/src/components/user-txt-msg-bubble.d.ts +6 -0
  118. package/dist/src/components/user-txt-msg-bubble.d.ts.map +1 -0
  119. package/dist/src/components/warning-msg.d.ts +6 -0
  120. package/dist/src/components/warning-msg.d.ts.map +1 -0
  121. package/dist/src/const/ui.d.ts +7 -0
  122. package/dist/src/const/ui.d.ts.map +1 -0
  123. package/dist/src/hooks/use-resizable-width.d.ts +24 -0
  124. package/dist/src/hooks/use-resizable-width.d.ts.map +1 -0
  125. package/dist/src/hooks/use-shadow.d.ts +25 -0
  126. package/dist/src/hooks/use-shadow.d.ts.map +1 -0
  127. package/dist/src/index.d.ts +66 -0
  128. package/dist/src/index.d.ts.map +1 -0
  129. package/dist/src/lib/utils.d.ts +4 -0
  130. package/dist/src/lib/utils.d.ts.map +1 -0
  131. package/dist/src/stories/AbsFullscreenGradientBg.stories.d.ts +17 -0
  132. package/dist/src/stories/AbsFullscreenGradientBg.stories.d.ts.map +1 -0
  133. package/dist/src/stories/AgentScrollSelector.stories.d.ts +11 -0
  134. package/dist/src/stories/AgentScrollSelector.stories.d.ts.map +1 -0
  135. package/dist/src/stories/AgentSelect.stories.d.ts +14 -0
  136. package/dist/src/stories/AgentSelect.stories.d.ts.map +1 -0
  137. package/dist/src/stories/AttachmentPart.stories.d.ts +23 -0
  138. package/dist/src/stories/AttachmentPart.stories.d.ts.map +1 -0
  139. package/dist/src/stories/AttachmentPartGroup.stories.d.ts +21 -0
  140. package/dist/src/stories/AttachmentPartGroup.stories.d.ts.map +1 -0
  141. package/dist/src/stories/AttachmentsPreviewer.stories.d.ts +20 -0
  142. package/dist/src/stories/AttachmentsPreviewer.stories.d.ts.map +1 -0
  143. package/dist/src/stories/BaseButton.stories.d.ts +18 -0
  144. package/dist/src/stories/BaseButton.stories.d.ts.map +1 -0
  145. package/dist/src/stories/BorderAnimation.stories.d.ts +21 -0
  146. package/dist/src/stories/BorderAnimation.stories.d.ts.map +1 -0
  147. package/dist/src/stories/BorderColorAnimation.stories.d.ts +26 -0
  148. package/dist/src/stories/BorderColorAnimation.stories.d.ts.map +1 -0
  149. package/dist/src/stories/BotAvatarAndName.stories.d.ts +18 -0
  150. package/dist/src/stories/BotAvatarAndName.stories.d.ts.map +1 -0
  151. package/dist/src/stories/BotIcon.stories.d.ts +17 -0
  152. package/dist/src/stories/BotIcon.stories.d.ts.map +1 -0
  153. package/dist/src/stories/BsEntrySelect.stories.d.ts +13 -0
  154. package/dist/src/stories/BsEntrySelect.stories.d.ts.map +1 -0
  155. package/dist/src/stories/BsTooltip.stories.d.ts +7 -0
  156. package/dist/src/stories/BsTooltip.stories.d.ts.map +1 -0
  157. package/dist/src/stories/Card.stories.d.ts +14 -0
  158. package/dist/src/stories/Card.stories.d.ts.map +1 -0
  159. package/dist/src/stories/CardField.stories.d.ts +13 -0
  160. package/dist/src/stories/CardField.stories.d.ts.map +1 -0
  161. package/dist/src/stories/ChatAreaHeader.stories.d.ts +14 -0
  162. package/dist/src/stories/ChatAreaHeader.stories.d.ts.map +1 -0
  163. package/dist/src/stories/CircleChecker.stories.d.ts +21 -0
  164. package/dist/src/stories/CircleChecker.stories.d.ts.map +1 -0
  165. package/dist/src/stories/CollapsibleTextMsg.stories.d.ts +16 -0
  166. package/dist/src/stories/CollapsibleTextMsg.stories.d.ts.map +1 -0
  167. package/dist/src/stories/ConfirmDialog.stories.d.ts +61 -0
  168. package/dist/src/stories/ConfirmDialog.stories.d.ts.map +1 -0
  169. package/dist/src/stories/FakeBotMsg.stories.d.ts +21 -0
  170. package/dist/src/stories/FakeBotMsg.stories.d.ts.map +1 -0
  171. package/dist/src/stories/FormInfoEditor.stories.d.ts +15 -0
  172. package/dist/src/stories/FormInfoEditor.stories.d.ts.map +1 -0
  173. package/dist/src/stories/FormulaTag.stories.d.ts +37 -0
  174. package/dist/src/stories/FormulaTag.stories.d.ts.map +1 -0
  175. package/dist/src/stories/GenerateAnimation.stories.d.ts +17 -0
  176. package/dist/src/stories/GenerateAnimation.stories.d.ts.map +1 -0
  177. package/dist/src/stories/IconBtn.stories.d.ts +15 -0
  178. package/dist/src/stories/IconBtn.stories.d.ts.map +1 -0
  179. package/dist/src/stories/IconLib.d.ts +12 -0
  180. package/dist/src/stories/IconLib.d.ts.map +1 -0
  181. package/dist/src/stories/Icons.stories.d.ts +24 -0
  182. package/dist/src/stories/Icons.stories.d.ts.map +1 -0
  183. package/dist/src/stories/ImgMsgPart.stories.d.ts +20 -0
  184. package/dist/src/stories/ImgMsgPart.stories.d.ts.map +1 -0
  185. package/dist/src/stories/LegacySlot.stories.d.ts +16 -0
  186. package/dist/src/stories/LegacySlot.stories.d.ts.map +1 -0
  187. package/dist/src/stories/LineChecker.stories.d.ts +23 -0
  188. package/dist/src/stories/LineChecker.stories.d.ts.map +1 -0
  189. package/dist/src/stories/LinearGradientBorderBtn.stories.d.ts +22 -0
  190. package/dist/src/stories/LinearGradientBorderBtn.stories.d.ts.map +1 -0
  191. package/dist/src/stories/LinearGradientColorBgAnimation.stories.d.ts +23 -0
  192. package/dist/src/stories/LinearGradientColorBgAnimation.stories.d.ts.map +1 -0
  193. package/dist/src/stories/MemoizedMarkdown.stories.d.ts +23 -0
  194. package/dist/src/stories/MemoizedMarkdown.stories.d.ts.map +1 -0
  195. package/dist/src/stories/MessageContent.stories.d.ts +16 -0
  196. package/dist/src/stories/MessageContent.stories.d.ts.map +1 -0
  197. package/dist/src/stories/NumbersMsgPart.stories.d.ts +19 -0
  198. package/dist/src/stories/NumbersMsgPart.stories.d.ts.map +1 -0
  199. package/dist/src/stories/OfficeContainer.stories.d.ts +8 -0
  200. package/dist/src/stories/OfficeContainer.stories.d.ts.map +1 -0
  201. package/dist/src/stories/OptionItem.stories.d.ts +20 -0
  202. package/dist/src/stories/OptionItem.stories.d.ts.map +1 -0
  203. package/dist/src/stories/PreviewerHeader.stories.d.ts +12 -0
  204. package/dist/src/stories/PreviewerHeader.stories.d.ts.map +1 -0
  205. package/dist/src/stories/PrimaryConfirmBtn.stories.d.ts +19 -0
  206. package/dist/src/stories/PrimaryConfirmBtn.stories.d.ts.map +1 -0
  207. package/dist/src/stories/PrimaryEntryBtn.stories.d.ts +26 -0
  208. package/dist/src/stories/PrimaryEntryBtn.stories.d.ts.map +1 -0
  209. package/dist/src/stories/ScrollToBottom.stories.d.ts +15 -0
  210. package/dist/src/stories/ScrollToBottom.stories.d.ts.map +1 -0
  211. package/dist/src/stories/SplitLine.stories.d.ts +9 -0
  212. package/dist/src/stories/SplitLine.stories.d.ts.map +1 -0
  213. package/dist/src/stories/SquareChecker.stories.d.ts +26 -0
  214. package/dist/src/stories/SquareChecker.stories.d.ts.map +1 -0
  215. package/dist/src/stories/TabRadioGroup.stories.d.ts +18 -0
  216. package/dist/src/stories/TabRadioGroup.stories.d.ts.map +1 -0
  217. package/dist/src/stories/UserTextMsgBubble.stories.d.ts +14 -0
  218. package/dist/src/stories/UserTextMsgBubble.stories.d.ts.map +1 -0
  219. package/dist/src/stories/WarningMessage.stories.d.ts +16 -0
  220. package/dist/src/stories/WarningMessage.stories.d.ts.map +1 -0
  221. package/dist/src/stories/fields-design-info-table.stories.d.ts +14 -0
  222. package/dist/src/stories/fields-design-info-table.stories.d.ts.map +1 -0
  223. package/dist/src/stories/fields-generating.stories.d.ts +20 -0
  224. package/dist/src/stories/fields-generating.stories.d.ts.map +1 -0
  225. package/dist/src/stories/fields-previewer.stories.d.ts +19 -0
  226. package/dist/src/stories/fields-previewer.stories.d.ts.map +1 -0
  227. package/dist/src/types.d.ts +8 -0
  228. package/dist/src/types.d.ts.map +1 -0
  229. package/package.json +80 -0
  230. package/src/components/abs-fullscreen-gradient-bg.tsx +35 -0
  231. package/src/components/agent-scroll-selector.tsx +181 -0
  232. package/src/components/agent-select.tsx +149 -0
  233. package/src/components/attachment-part-group.tsx +35 -0
  234. package/src/components/attachment-part.tsx +179 -0
  235. package/src/components/attachments-previewer.tsx +324 -0
  236. package/src/components/base-button.tsx +49 -0
  237. package/src/components/border-animation.tsx +107 -0
  238. package/src/components/border-color-animation.tsx +66 -0
  239. package/src/components/bot-avatar-name.tsx +36 -0
  240. package/src/components/bot-icon.tsx +23 -0
  241. package/src/components/bs-entry-select.tsx +724 -0
  242. package/src/components/bs-icons.tsx +1201 -0
  243. package/src/components/card-field.tsx +23 -0
  244. package/src/components/card.tsx +36 -0
  245. package/src/components/chat-area-header.tsx +65 -0
  246. package/src/components/circle-checker.tsx +66 -0
  247. package/src/components/collapsible-txt-msg.tsx +63 -0
  248. package/src/components/confirm-dialog.tsx +139 -0
  249. package/src/components/fake-bot-msg.tsx +49 -0
  250. package/src/components/fields-design-info-table.tsx +160 -0
  251. package/src/components/fields-generating-indicator.tsx +95 -0
  252. package/src/components/fields-portal.tsx +18 -0
  253. package/src/components/fields-previewer.tsx +216 -0
  254. package/src/components/font-icon.tsx +17 -0
  255. package/src/components/form-info-editor.tsx +253 -0
  256. package/src/components/formula-tag.tsx +32 -0
  257. package/src/components/generate-animation.tsx +56 -0
  258. package/src/components/icon-btn.tsx +43 -0
  259. package/src/components/img-part.tsx +27 -0
  260. package/src/components/legacy-slot.tsx +103 -0
  261. package/src/components/line-checker.tsx +160 -0
  262. package/src/components/linear-gradient-border-btn.tsx +48 -0
  263. package/src/components/linear-gradient-color-bg-animation.tsx +103 -0
  264. package/src/components/memoized-markdown.tsx +32 -0
  265. package/src/components/message-content.tsx +21 -0
  266. package/src/components/number-part.tsx +46 -0
  267. package/src/components/office-container.tsx +83 -0
  268. package/src/components/option-item.tsx +28 -0
  269. package/src/components/previewer-header.tsx +270 -0
  270. package/src/components/primary-confirm-btn.tsx +58 -0
  271. package/src/components/primary-entry-btn.tsx +48 -0
  272. package/src/components/scroll-to-bottom-btn.tsx +28 -0
  273. package/src/components/split-line.tsx +9 -0
  274. package/src/components/square-checker.tsx +87 -0
  275. package/src/components/tab-radio-group.tsx +83 -0
  276. package/src/components/tooltip.tsx +53 -0
  277. package/src/components/ui/button.tsx +51 -0
  278. package/src/components/ui/dialog.tsx +104 -0
  279. package/src/components/ui/icons.tsx +1267 -0
  280. package/src/components/ui/popover.tsx +50 -0
  281. package/src/components/ui/spinner.tsx +17 -0
  282. package/src/components/ui/tooltip.tsx +53 -0
  283. package/src/components/user-txt-msg-bubble.tsx +19 -0
  284. package/src/components/warning-msg.tsx +27 -0
  285. package/src/const/ui.ts +52 -0
  286. package/src/hooks/use-resizable-width.ts +92 -0
  287. package/src/hooks/use-shadow.ts +127 -0
  288. package/src/index.ts +76 -0
  289. package/src/lib/utils.ts +52 -0
  290. package/src/stories/AbsFullscreenGradientBg.stories.tsx +36 -0
  291. package/src/stories/AgentScrollSelector.stories.tsx +95 -0
  292. package/src/stories/AgentSelect.stories.tsx +134 -0
  293. package/src/stories/AttachmentPart.stories.tsx +122 -0
  294. package/src/stories/AttachmentPartGroup.stories.tsx +152 -0
  295. package/src/stories/AttachmentsPreviewer.stories.tsx +306 -0
  296. package/src/stories/BaseButton.stories.tsx +33 -0
  297. package/src/stories/BorderAnimation.stories.tsx +116 -0
  298. package/src/stories/BorderColorAnimation.stories.tsx +63 -0
  299. package/src/stories/BotAvatarAndName.stories.ts +24 -0
  300. package/src/stories/BotIcon.stories.ts +22 -0
  301. package/src/stories/BsEntrySelect.stories.tsx +261 -0
  302. package/src/stories/BsTooltip.stories.tsx +32 -0
  303. package/src/stories/Card.stories.tsx +28 -0
  304. package/src/stories/CardField.stories.tsx +87 -0
  305. package/src/stories/ChatAreaHeader.stories.ts +26 -0
  306. package/src/stories/CircleChecker.stories.tsx +89 -0
  307. package/src/stories/CollapsibleTextMsg.stories.ts +44 -0
  308. package/src/stories/ConfirmDialog.stories.tsx +123 -0
  309. package/src/stories/FakeBotMsg.stories.tsx +36 -0
  310. package/src/stories/FormInfoEditor.stories.tsx +173 -0
  311. package/src/stories/FormulaTag.stories.tsx +68 -0
  312. package/src/stories/GenerateAnimation.stories.ts +20 -0
  313. package/src/stories/IconBtn.stories.tsx +32 -0
  314. package/src/stories/IconLib.tsx +45 -0
  315. package/src/stories/Icons.stories.ts +22 -0
  316. package/src/stories/ImgMsgPart.stories.tsx +42 -0
  317. package/src/stories/LegacySlot.stories.tsx +56 -0
  318. package/src/stories/LineChecker.stories.tsx +134 -0
  319. package/src/stories/LinearGradientBorderBtn.stories.tsx +86 -0
  320. package/src/stories/LinearGradientColorBgAnimation.stories.tsx +60 -0
  321. package/src/stories/MemoizedMarkdown.stories.tsx +102 -0
  322. package/src/stories/MessageContent.stories.tsx +36 -0
  323. package/src/stories/NumbersMsgPart.stories.tsx +42 -0
  324. package/src/stories/OfficeContainer.stories.tsx +82 -0
  325. package/src/stories/OptionItem.stories.tsx +77 -0
  326. package/src/stories/PreviewerHeader.stories.tsx +91 -0
  327. package/src/stories/PrimaryConfirmBtn.stories.tsx +60 -0
  328. package/src/stories/PrimaryEntryBtn.stories.tsx +74 -0
  329. package/src/stories/ScrollToBottom.stories.tsx +24 -0
  330. package/src/stories/SplitLine.stories.tsx +40 -0
  331. package/src/stories/SquareChecker.stories.tsx +96 -0
  332. package/src/stories/TabRadioGroup.stories.tsx +84 -0
  333. package/src/stories/UserTextMsgBubble.stories.ts +24 -0
  334. package/src/stories/WarningMessage.stories.tsx +23 -0
  335. package/src/stories/assets/accessibility.png +0 -0
  336. package/src/stories/assets/accessibility.svg +1 -0
  337. package/src/stories/assets/addon-library.png +0 -0
  338. package/src/stories/assets/assets.png +0 -0
  339. package/src/stories/assets/avif-test-image.avif +0 -0
  340. package/src/stories/assets/context.png +0 -0
  341. package/src/stories/assets/demo.css +539 -0
  342. package/src/stories/assets/demo_index.html +7988 -0
  343. package/src/stories/assets/discord.svg +1 -0
  344. package/src/stories/assets/docs.png +0 -0
  345. package/src/stories/assets/figma-plugin.png +0 -0
  346. package/src/stories/assets/github.svg +1 -0
  347. package/src/stories/assets/iconfont.css +1377 -0
  348. package/src/stories/assets/iconfont.eot +0 -0
  349. package/src/stories/assets/iconfont.json +2382 -0
  350. package/src/stories/assets/iconfont.svg +697 -0
  351. package/src/stories/assets/iconfont.ttf +0 -0
  352. package/src/stories/assets/iconfont.woff +0 -0
  353. package/src/stories/assets/iconfont.woff2 +0 -0
  354. package/src/stories/assets/share.png +0 -0
  355. package/src/stories/assets/styling.png +0 -0
  356. package/src/stories/assets/testing.png +0 -0
  357. package/src/stories/assets/theming.png +0 -0
  358. package/src/stories/assets/tutorials.svg +1 -0
  359. package/src/stories/assets/youtube.svg +1 -0
  360. package/src/stories/fields-design-info-table.stories.tsx +203 -0
  361. package/src/stories/fields-generating.stories.tsx +41 -0
  362. package/src/stories/fields-previewer.stories.tsx +77 -0
  363. package/src/style.css +223 -0
  364. package/src/types.ts +8 -0
  365. package/tsconfig.json +12 -0
  366. package/vite.config.ts +42 -0
@@ -0,0 +1,179 @@
1
+ import { ComponentType } from 'react';
2
+ import { cn } from '../lib/utils';
3
+ import { ImgMsgPart } from './img-part';
4
+ import { XlsxIcon, CsvFileIcon, TxtFileIcon, UnknownFileIcon } from './bs-icons';
5
+
6
+ /** File part from AI message */
7
+ export interface FilePart {
8
+ type: 'file';
9
+ url: string;
10
+ name?: string;
11
+ mediaType?: string;
12
+ }
13
+
14
+ export interface AttachmentPartProps {
15
+ part: FilePart;
16
+ className?: string;
17
+ /** Size in pixels (width & height), defaults to 102 */
18
+ size?: number;
19
+ /** Show only the icon without file name */
20
+ iconOnly?: boolean;
21
+ /** Click handler for the attachment */
22
+ onClick?: (part: FilePart) => void;
23
+ }
24
+
25
+ type FileIconComponent = ComponentType;
26
+
27
+ interface FileTypeConfig {
28
+ icon: FileIconComponent;
29
+ /** Icon original size for scaling */
30
+ iconSize: number;
31
+ }
32
+
33
+ /** Map media types to icon configurations */
34
+ const FILE_TYPE_MAP: Record<string, FileTypeConfig> = {
35
+ // Excel files
36
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': {
37
+ icon: XlsxIcon,
38
+ iconSize: 52,
39
+ },
40
+ 'application/vnd.ms-excel': { icon: XlsxIcon, iconSize: 52 },
41
+
42
+ // CSV files
43
+ 'text/csv': { icon: CsvFileIcon, iconSize: 16 },
44
+
45
+ // Text files
46
+ 'text/plain': { icon: TxtFileIcon, iconSize: 16 },
47
+ 'application/octet-stream': { icon: TxtFileIcon, iconSize: 16 }, // treat as text for ts/js files
48
+ };
49
+
50
+ const DEFAULT_FILE_CONFIG: FileTypeConfig = {
51
+ icon: UnknownFileIcon,
52
+ iconSize: 16,
53
+ };
54
+
55
+ /** Check if media type is an image */
56
+ const isImageType = (mediaType?: string): boolean => {
57
+ return Boolean(mediaType?.startsWith('image/'));
58
+ };
59
+
60
+ /** Get file config based on media type and file extension */
61
+ const getFileConfig = (mediaType?: string, fileName?: string): FileTypeConfig => {
62
+ // Check media type first
63
+ if (mediaType && FILE_TYPE_MAP[mediaType]) {
64
+ return FILE_TYPE_MAP[mediaType];
65
+ }
66
+
67
+ // Fallback to file extension
68
+ if (fileName) {
69
+ const ext = fileName.split('.').pop()?.toLowerCase();
70
+ switch (ext) {
71
+ case 'xlsx':
72
+ case 'xls':
73
+ return FILE_TYPE_MAP['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
74
+ case 'csv':
75
+ return FILE_TYPE_MAP['text/csv'];
76
+ case 'txt':
77
+ case 'ts':
78
+ case 'tsx':
79
+ case 'js':
80
+ case 'jsx':
81
+ case 'json':
82
+ case 'md':
83
+ return FILE_TYPE_MAP['text/plain'];
84
+ }
85
+ }
86
+
87
+ return DEFAULT_FILE_CONFIG;
88
+ };
89
+
90
+ /** Extract display file name from full path */
91
+ const getDisplayFileName = (name?: string): string | undefined => {
92
+ if (!name) return undefined;
93
+ // Get last segment of path
94
+ const segments = name.split('/');
95
+ return segments[segments.length - 1];
96
+ };
97
+
98
+ /** Generic file message part component */
99
+ const FileMsgPart = ({
100
+ fileName,
101
+ icon: Icon,
102
+ iconSize,
103
+ className,
104
+ size = 102,
105
+ }: {
106
+ fileName?: string;
107
+ icon: FileIconComponent;
108
+ iconSize: number;
109
+ className?: string;
110
+ size?: number;
111
+ }) => {
112
+ const scale = size / 102;
113
+ const scaledIconSize = (52 / 102) * size; // Target icon takes ~51% of container
114
+ const iconScale = scaledIconSize / iconSize;
115
+ const hasFileName = Boolean(fileName);
116
+
117
+ return (
118
+ <div
119
+ className={cn(
120
+ 'relative flex flex-col items-center justify-center rounded-[10px] bg-[#EFF0F6] px-[10px]',
121
+ hasFileName && 'gap-[6px]',
122
+ className
123
+ )}
124
+ style={{ width: size, height: size }}
125
+ >
126
+ <div
127
+ className="shrink-0 flex items-center justify-center"
128
+ style={{
129
+ width: scaledIconSize,
130
+ height: scaledIconSize,
131
+ }}
132
+ >
133
+ <div
134
+ style={{
135
+ transform: iconScale !== 1 ? `scale(${iconScale})` : undefined,
136
+ transformOrigin: 'center',
137
+ }}
138
+ >
139
+ <Icon />
140
+ </div>
141
+ </div>
142
+ {hasFileName && (
143
+ <p
144
+ className="block max-w-full shrink-0 truncate text-center text-[14px] leading-normal text-[#030303]"
145
+ style={{ fontSize: 14 * scale, maxWidth: '100%', display: 'block' }}
146
+ title={fileName}
147
+ >
148
+ {fileName}
149
+ </p>
150
+ )}
151
+ </div>
152
+ );
153
+ };
154
+
155
+ export const AttachmentPart = ({ part, className, size = 102, iconOnly, onClick }: AttachmentPartProps) => {
156
+ const { url, name, mediaType } = part;
157
+ const handleClick = onClick ? () => onClick(part) : undefined;
158
+
159
+ // Render image for image types
160
+ if (isImageType(mediaType)) {
161
+ return <ImgMsgPart url={url} alt={name} className={className} size={size} onClick={handleClick} />;
162
+ }
163
+
164
+ // Render file icon for other types
165
+ const { icon, iconSize } = getFileConfig(mediaType, name);
166
+ const displayName = iconOnly ? undefined : getDisplayFileName(name);
167
+
168
+ return (
169
+ <div onClick={handleClick} className={onClick ? 'cursor-pointer' : undefined}>
170
+ <FileMsgPart
171
+ fileName={displayName}
172
+ icon={icon}
173
+ iconSize={iconSize}
174
+ className={className}
175
+ size={size}
176
+ />
177
+ </div>
178
+ );
179
+ };
@@ -0,0 +1,324 @@
1
+ import { cn } from '../lib/utils';
2
+ import { transCls } from '../const/ui';
3
+ import { useRef, useState, useEffect, useCallback, ComponentType } from 'react';
4
+ import { RemoveCircleIcon, XlsxIcon, CsvFileIcon, TxtFileIcon, UnknownFileIcon } from './bs-icons';
5
+ import { LoaderIcon } from './ui/icons';
6
+
7
+ export interface AttachmentItem {
8
+ id: string;
9
+ url: string;
10
+ alt?: string;
11
+ isLoading?: boolean;
12
+ /** MIME type, used to decide whether to show image or icon */
13
+ contentType?: string;
14
+ }
15
+
16
+ export interface AttachmentsPreviewerProps {
17
+ attachments: AttachmentItem[];
18
+ className?: string;
19
+ imageSize?: number;
20
+ gap?: number;
21
+ onImageClick?: (attachment: AttachmentItem, index: number) => void;
22
+ onImageRemove?: (attachment: AttachmentItem, index: number) => void;
23
+ }
24
+
25
+ type FileIconComponent = ComponentType;
26
+
27
+ interface FileTypeConfig {
28
+ icon: FileIconComponent;
29
+ /** Icon original size for scaling */
30
+ iconSize: number;
31
+ }
32
+
33
+ const FILE_TYPE_MAP: Record<string, FileTypeConfig> = {
34
+ 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet': {
35
+ icon: XlsxIcon,
36
+ iconSize: 52,
37
+ },
38
+ 'application/vnd.ms-excel': { icon: XlsxIcon, iconSize: 52 },
39
+ 'text/csv': { icon: CsvFileIcon, iconSize: 16 },
40
+ 'text/plain': { icon: TxtFileIcon, iconSize: 16 },
41
+ 'application/octet-stream': { icon: TxtFileIcon, iconSize: 16 },
42
+ };
43
+
44
+ const DEFAULT_FILE_CONFIG: FileTypeConfig = {
45
+ icon: UnknownFileIcon,
46
+ iconSize: 16,
47
+ };
48
+
49
+ const isImageType = (mediaType?: string): boolean => Boolean(mediaType?.startsWith('image/'));
50
+
51
+ const getFileConfig = (mediaType?: string, fileName?: string): FileTypeConfig => {
52
+ if (mediaType && FILE_TYPE_MAP[mediaType]) {
53
+ return FILE_TYPE_MAP[mediaType];
54
+ }
55
+
56
+ if (fileName) {
57
+ const ext = fileName.split('.').pop()?.toLowerCase();
58
+ switch (ext) {
59
+ case 'xlsx':
60
+ case 'xls':
61
+ return FILE_TYPE_MAP['application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'];
62
+ case 'csv':
63
+ return FILE_TYPE_MAP['text/csv'];
64
+ case 'txt':
65
+ case 'ts':
66
+ case 'tsx':
67
+ case 'js':
68
+ case 'jsx':
69
+ case 'json':
70
+ case 'md':
71
+ return FILE_TYPE_MAP['text/plain'];
72
+ }
73
+ }
74
+
75
+ return DEFAULT_FILE_CONFIG;
76
+ };
77
+
78
+ const ChevronRightIcon = () => (
79
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
80
+ <path
81
+ d="M9 6L15 12L9 18"
82
+ stroke="currentColor"
83
+ strokeWidth="2"
84
+ strokeLinecap="round"
85
+ strokeLinejoin="round"
86
+ />
87
+ </svg>
88
+ );
89
+
90
+ const ChevronLeftIcon = () => (
91
+ <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none">
92
+ <path
93
+ d="M15 6L9 12L15 18"
94
+ stroke="currentColor"
95
+ strokeWidth="2"
96
+ strokeLinecap="round"
97
+ strokeLinejoin="round"
98
+ />
99
+ </svg>
100
+ );
101
+
102
+ const NavButton = ({
103
+ direction,
104
+ onClick,
105
+ className,
106
+ }: {
107
+ direction: 'left' | 'right';
108
+ onClick: () => void;
109
+ className?: string;
110
+ }) => {
111
+ return (
112
+ <button
113
+ type="button"
114
+ onClick={onClick}
115
+ className={cn(
116
+ 'flex items-center justify-center',
117
+ 'size-9 p-1 rounded-[18px]',
118
+ 'bg-white shadow-[0px_0px_10px_0px_rgba(0,0,0,0.06)]',
119
+ 'cursor-pointer',
120
+ 'hover:bg-gray-50',
121
+ 'text-gray-600',
122
+ transCls,
123
+ className
124
+ )}
125
+ >
126
+ {direction === 'left' ? <ChevronLeftIcon /> : <ChevronRightIcon />}
127
+ </button>
128
+ );
129
+ };
130
+
131
+ const GradientOverlay = ({
132
+ direction,
133
+ height,
134
+ visible,
135
+ }: {
136
+ direction: 'left' | 'right';
137
+ height: number;
138
+ visible: boolean;
139
+ }) => {
140
+ const isLeft = direction === 'left';
141
+ return (
142
+ <div
143
+ className={cn(
144
+ 'absolute top-2 pointer-events-none z-5',
145
+ isLeft ? 'left-0' : 'right-0',
146
+ transCls,
147
+ visible ? 'opacity-100' : 'opacity-0'
148
+ )}
149
+ style={{ height: `${height}px`, width: '46px' }}
150
+ >
151
+ {/* Gradient layer - from white via white@63.57% to transparent */}
152
+ <div
153
+ className={cn(
154
+ 'absolute inset-0',
155
+ isLeft
156
+ ? 'bg-linear-to-r from-white via-white via-[63.57%] to-transparent'
157
+ : 'bg-linear-to-l from-white via-white via-[63.57%] to-transparent'
158
+ )}
159
+ />
160
+ {/* Blur layer */}
161
+ <div className="absolute inset-0 bg-white blur-[7px]" />
162
+ </div>
163
+ );
164
+ };
165
+
166
+ export const AttachmentsPreviewer = ({
167
+ attachments,
168
+ className,
169
+ imageSize = 53,
170
+ gap = 10,
171
+ onImageClick,
172
+ onImageRemove,
173
+ }: AttachmentsPreviewerProps) => {
174
+ const containerRef = useRef<HTMLDivElement>(null);
175
+ const scrollRef = useRef<HTMLDivElement>(null);
176
+ const [showLeftNav, setShowLeftNav] = useState(false);
177
+ const [showRightNav, setShowRightNav] = useState(false);
178
+
179
+ const checkScroll = useCallback(() => {
180
+ const el = scrollRef.current;
181
+ if (!el) return;
182
+
183
+ const { scrollLeft, scrollWidth, clientWidth } = el;
184
+ setShowLeftNav(scrollLeft > 0);
185
+ setShowRightNav(scrollLeft + clientWidth < scrollWidth - 1);
186
+ }, []);
187
+
188
+ useEffect(() => {
189
+ checkScroll();
190
+ const el = scrollRef.current;
191
+ if (!el) return;
192
+
193
+ el.addEventListener('scroll', checkScroll);
194
+ window.addEventListener('resize', checkScroll);
195
+
196
+ return () => {
197
+ el.removeEventListener('scroll', checkScroll);
198
+ window.removeEventListener('resize', checkScroll);
199
+ };
200
+ }, [checkScroll, attachments]);
201
+
202
+ const scroll = (direction: 'left' | 'right') => {
203
+ const el = scrollRef.current;
204
+ if (!el) return;
205
+
206
+ const scrollAmount = imageSize + gap;
207
+ const newScrollLeft =
208
+ direction === 'left' ? el.scrollLeft - scrollAmount * 2 : el.scrollLeft + scrollAmount * 2;
209
+
210
+ el.scrollTo({
211
+ left: newScrollLeft,
212
+ behavior: 'smooth',
213
+ });
214
+ };
215
+
216
+ if (!attachments.length) {
217
+ return null;
218
+ }
219
+
220
+ return (
221
+ <div
222
+ ref={containerRef}
223
+ className={cn('relative w-full', className)}
224
+ style={{ height: imageSize + 16 }}
225
+ >
226
+ {/* Scrollable images container */}
227
+ <div
228
+ ref={scrollRef}
229
+ className="flex overflow-x-auto scrollbar-hide py-2"
230
+ style={{ gap, height: imageSize + 16 }}
231
+ >
232
+ {attachments.map((attachment, index) => {
233
+ const isImage = isImageType(attachment.contentType);
234
+ const { icon: Icon, iconSize } = getFileConfig(attachment.contentType, attachment.alt);
235
+ const scaledIconSize = (52 / 102) * imageSize;
236
+ const iconScale = scaledIconSize / iconSize;
237
+
238
+ return (
239
+ <div
240
+ key={attachment.id}
241
+ className={cn(
242
+ 'relative shrink-0 cursor-pointer group border border-[#e0e0e0] rounded-lg',
243
+ transCls
244
+ )}
245
+ style={{ width: imageSize, height: imageSize }}
246
+ onClick={() => onImageClick?.(attachment, index)}
247
+ >
248
+ {isImage && attachment.url ? (
249
+ <img
250
+ src={attachment.url}
251
+ alt={attachment.alt || `Attachment ${index + 1}`}
252
+ className="absolute inset-0 h-full w-full rounded-lg object-cover"
253
+ />
254
+ ) : (
255
+ <div className="absolute inset-0 flex h-full w-full items-center justify-center rounded-lg bg-[#EFF0F6]">
256
+ <div
257
+ className="shrink-0 flex items-center justify-center"
258
+ style={{ width: scaledIconSize, height: scaledIconSize }}
259
+ >
260
+ <div
261
+ style={{
262
+ transform: iconScale !== 1 ? `scale(${iconScale})` : undefined,
263
+ transformOrigin: 'center',
264
+ }}
265
+ >
266
+ <Icon />
267
+ </div>
268
+ </div>
269
+ </div>
270
+ )}
271
+
272
+ {attachment.isLoading && (
273
+ <div className="absolute inset-0 flex items-center justify-center rounded-lg bg-black/50 pointer-events-none">
274
+ <div className="inline-flex animate-spin items-center justify-center">
275
+ <LoaderIcon size={16} />
276
+ </div>
277
+ </div>
278
+ )}
279
+
280
+ {onImageRemove /* && !attachment.isLoading*/ && (
281
+ <button
282
+ className={cn(
283
+ 'absolute -top-1.5 -right-1.5',
284
+ 'flex items-center justify-center',
285
+ 'opacity-0 group-hover:opacity-100 cursor-pointer',
286
+ transCls
287
+ )}
288
+ onClick={(e) => {
289
+ e.stopPropagation();
290
+ onImageRemove(attachment, index);
291
+ }}
292
+ >
293
+ <RemoveCircleIcon />
294
+ </button>
295
+ )}
296
+ </div>
297
+ );
298
+ })}
299
+ </div>
300
+
301
+ {/* Left navigation */}
302
+ <GradientOverlay direction="left" height={imageSize} visible={showLeftNav} />
303
+ <NavButton
304
+ direction="left"
305
+ onClick={() => scroll('left')}
306
+ className={cn(
307
+ 'absolute left-0 top-1/2 -translate-y-1/2 z-10',
308
+ showLeftNav ? 'opacity-100' : 'opacity-0 pointer-events-none'
309
+ )}
310
+ />
311
+
312
+ {/* Right navigation */}
313
+ <GradientOverlay direction="right" height={imageSize} visible={showRightNav} />
314
+ <NavButton
315
+ direction="right"
316
+ onClick={() => scroll('right')}
317
+ className={cn(
318
+ 'absolute right-0 top-1/2 -translate-y-1/2 z-10',
319
+ showRightNav ? 'opacity-100' : 'opacity-0 pointer-events-none'
320
+ )}
321
+ />
322
+ </div>
323
+ );
324
+ };
@@ -0,0 +1,49 @@
1
+ import { forwardRef } from 'react';
2
+ import type { ButtonHTMLAttributes, ReactNode } from 'react';
3
+ import { cn } from '../lib/utils';
4
+ import { transCls } from '../const/ui';
5
+ import { BsTooltip } from './tooltip';
6
+
7
+ export interface BaseButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
8
+ icon?: ReactNode;
9
+ tooltip?: string;
10
+ hoverTextCls?: string;
11
+ }
12
+
13
+ export const BaseButton = forwardRef<HTMLButtonElement, BaseButtonProps>(
14
+ ({ className, children, hoverTextCls, tooltip, icon, type, ...rest }, ref) => {
15
+ const btn = (
16
+ <button
17
+ ref={ref}
18
+ type={type ?? 'button'}
19
+ className={cn(
20
+ 'group inline-flex items-center gap-[6px] px-[16px] rounded-[4px] h-[34px]',
21
+ 'border border-solid border-[#E0E0E0] bg-transparent',
22
+ 'text-[14px] font-[400] leading-[normal] text-[#030303]',
23
+ 'hover:bg-[#EFF0F6] hover:border-transparent',
24
+ 'cursor-pointer',
25
+ {
26
+ 'hover:text-[#0265FF]': !hoverTextCls,
27
+ [`hover:${hoverTextCls}`]: hoverTextCls,
28
+ },
29
+ transCls,
30
+ className
31
+ )}
32
+ {...rest}
33
+ >
34
+ {icon ? <span className="shrink-0">{icon}</span> : null}
35
+ {children ? (
36
+ <span className="whitespace-nowrap">{children}</span>
37
+ ) : null}
38
+ </button>
39
+ );
40
+
41
+ if (tooltip) {
42
+ return <BsTooltip content={tooltip}>{btn}</BsTooltip>;
43
+ }
44
+
45
+ return btn;
46
+ }
47
+ );
48
+
49
+ BaseButton.displayName = 'BaseButton';
@@ -0,0 +1,107 @@
1
+ import React from 'react';
2
+ import { cn } from '../lib/utils';
3
+
4
+ export interface BorderAnimationProps {
5
+ children?: React.ReactNode;
6
+ className?: string;
7
+ /** Duration of one full animation cycle in seconds @default 2 */
8
+ duration?: number;
9
+ /** Border radius in pixels @default 4 */
10
+ borderRadius?: number;
11
+ /** Width of the animated beam in pixels @default 30 */
12
+ beamWidth?: number;
13
+ /** Height of the animated beam in pixels @default 4 */
14
+ beamHeight?: number;
15
+ /** Gradient for the animated beam */
16
+ gradient?: string;
17
+ height?: string | number;
18
+ /** Border width in pixels @default 1.5 */
19
+ borderWidth?: number;
20
+ /** Default border color @default '#E5E5E5' */
21
+ borderColor?: string;
22
+ }
23
+
24
+ const defaultGradient = `linear-gradient(90deg,
25
+ rgba(132, 180, 255, 0) 0%,
26
+ rgba(132, 180, 255, 0.5) 10%,
27
+ rgba(132, 180, 255, 1) 25%,
28
+ rgb(2, 101, 255) 50%,
29
+ rgba(177, 250, 255, 1) 75%,
30
+ rgba(177, 250, 255, 0.5) 90%,
31
+ rgba(177, 250, 255, 0) 100%
32
+ )`;
33
+
34
+ export const BorderAnimation: React.FC<BorderAnimationProps> = ({
35
+ children,
36
+ className,
37
+ duration = 2,
38
+ borderRadius = 4,
39
+ beamWidth = 170,
40
+ beamHeight = 4,
41
+ // gradient = 'linear-gradient(180deg, #84B4FF 0%, #0265FF 50%, #B1FAFF 100%)',
42
+ // gradient = 'linear-gradient(90deg, rgb(132, 180, 255) 0%, rgb(2, 101, 255) 50%, rgb(177, 250, 255) 100%)',
43
+ gradient = defaultGradient,
44
+ borderWidth = 1,
45
+ height,
46
+ borderColor = 'transparent',
47
+ }) => {
48
+ const pseudoCls = "gradient-border"
49
+ return (
50
+ <div
51
+ className={cn('relative w-full overflow-hidden', className, pseudoCls)}
52
+ style={{
53
+ borderRadius: `${borderRadius}px`,
54
+ border: `${borderWidth}px solid ${borderColor}`,
55
+ ...(height ? { height } : {}),
56
+ }}
57
+ >
58
+ {children}
59
+ {/* Animated border overlay */}
60
+ <div
61
+ style={{
62
+ position: 'absolute',
63
+ // inset: `${-borderWidth}px`,
64
+ inset: 0,
65
+ pointerEvents: 'none',
66
+ border: `${borderWidth}px solid transparent`,
67
+ borderRadius: 'inherit',
68
+ // contain: 'layout style paint',
69
+ maskImage:
70
+ 'linear-gradient(transparent, transparent), linear-gradient(white, white)',
71
+ WebkitMaskImage:
72
+ 'linear-gradient(transparent, transparent), linear-gradient(white, white)',
73
+ maskOrigin: 'border-box, border-box',
74
+ WebkitMaskOrigin: 'border-box, border-box',
75
+ maskClip: 'padding-box, border-box',
76
+ WebkitMaskClip: 'padding-box, border-box',
77
+ maskComposite: 'intersect',
78
+ WebkitMaskComposite: 'source-in',
79
+ }}
80
+ >
81
+ {/* Traveling beam */}
82
+ <div
83
+ style={{
84
+ position: 'absolute',
85
+ aspectRatio: '1 / 1',
86
+ width: `${beamWidth}px`,
87
+ height: `${beamHeight}px`,
88
+ background: gradient,
89
+ offsetPath: `rect(0px auto auto 0px round ${borderRadius}px)`,
90
+ animation: `bs-border-travel ${duration}s linear infinite`,
91
+ willChange: 'offset-distance',
92
+ transform: 'translateZ(0)',
93
+ backfaceVisibility: 'hidden',
94
+ }}
95
+ />
96
+ </div>
97
+ <style>{`
98
+ @keyframes bs-border-travel {
99
+ 0% { offset-distance: 0%; }
100
+ 100% { offset-distance: 100%; }
101
+ }
102
+ `}</style>
103
+ </div>
104
+ );
105
+ };
106
+
107
+ export default BorderAnimation;