選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

link.tsx 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243
  1. /**
  2. * @fileoverview Link component for rendering <a> tags in Markdown.
  3. * Extracted from the main markdown renderer for modularity.
  4. * Handles special rendering for "abbr:" type links for interactive chat actions.
  5. */
  6. import React from 'react'
  7. import { useChatContext } from '@/app/components/base/chat/chat/context'
  8. import { isValidUrl } from './utils'
  9. const Link = ({ node, children, ...props }: any) => {
  10. const { onSend } = useChatContext()
  11. const commonClassName = 'cursor-pointer underline !decoration-primary-700 decoration-dashed'
  12. if (node.properties?.href && node.properties.href?.toString().startsWith('abbr')) {
  13. const hidden_text = decodeURIComponent(node.properties.href.toString().split('abbr:')[1])
  14. return <abbr className={commonClassName} onClick={() => onSend?.(hidden_text)} title={node.children[0]?.value || ''}>{node.children[0]?.value || ''}</abbr>
  15. }
  16. else {
  17. const href = props.href || node.properties?.href
  18. if (href && /^#[a-zA-Z0-9_-]+$/.test(href.toString())) {
  19. const handleClick = (e: React.MouseEvent<HTMLAnchorElement>) => {
  20. e.preventDefault()
  21. // scroll to target element if exists within the answer container
  22. const answerContainer = e.currentTarget.closest('.chat-answer-container')
  23. if (answerContainer) {
  24. const targetId = CSS.escape(href.toString().substring(1))
  25. const targetElement = answerContainer.querySelector(`[id="${targetId}"]`)
  26. if (targetElement)
  27. targetElement.scrollIntoView({ behavior: 'smooth' })
  28. }
  29. }
  30. return <a href={href} onClick={handleClick} className={commonClassName}>{children || 'ScrollView'}</a>
  31. }
  32. if (!href || !isValidUrl(href))
  33. return <span>{children}</span>
  34. return <a href={href} target="_blank" rel="noopener noreferrer" className={commonClassName}>{children || 'Download'}</a>
  35. }
  36. }
  37. export default Link