InformationBox.tsx 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import { ExternalLink, Maximize2, Minimize2 } from 'lucide-react'
  2. import Link from 'next/link'
  3. import { forwardRef, ReactNode, useState } from 'react'
  4. import { Button } from 'ui'
  5. interface InformationBoxProps {
  6. icon?: ReactNode
  7. title: ReactNode | string
  8. description?: ReactNode | string
  9. url?: string
  10. urlLabel?: string
  11. defaultVisibility?: boolean
  12. hideCollapse?: boolean
  13. button?: React.ReactNode
  14. className?: string
  15. block?: boolean
  16. }
  17. /** @deprecated Use `Admonition` from 'ui-patterns' instead. */
  18. const InformationBox = forwardRef<HTMLDivElement, InformationBoxProps>(
  19. (
  20. {
  21. icon,
  22. title,
  23. description,
  24. url,
  25. urlLabel = 'Read more',
  26. defaultVisibility = false,
  27. hideCollapse = false,
  28. button,
  29. className = '',
  30. block = false,
  31. },
  32. ref
  33. ) => {
  34. const [isExpanded, setIsExpanded] = useState<boolean>(defaultVisibility)
  35. return (
  36. <div
  37. ref={ref}
  38. role="alert"
  39. className={`${block ? 'block w-full' : ''}
  40. block w-full rounded-md border bg-surface-300/25 py-3 ${className}`}
  41. >
  42. <div className="flex flex-col px-4">
  43. <div className="flex items-center justify-between">
  44. <div className="flex w-full space-x-3 items-center">
  45. {icon && <span className="text-foreground-lighter">{icon}</span>}
  46. <div className="grow">
  47. <h5 className="text-foreground">{title}</h5>
  48. </div>
  49. </div>
  50. {description && !hideCollapse ? (
  51. <div
  52. className="cursor-pointer text-foreground-lighter"
  53. onClick={() => setIsExpanded(!isExpanded)}
  54. >
  55. {isExpanded ? (
  56. <Minimize2 size={14} strokeWidth={1.5} />
  57. ) : (
  58. <Maximize2 size={14} strokeWidth={1.5} />
  59. )}
  60. </div>
  61. ) : null}
  62. </div>
  63. {(description || url || button) && (
  64. <div
  65. className={`flex flex-col space-y-3 overflow-hidden transition-all ${
  66. isExpanded ? 'mt-3' : ''
  67. }`}
  68. style={{ maxHeight: isExpanded ? 500 : 0 }}
  69. >
  70. <div className="text-foreground-light text-sm">{description}</div>
  71. {url && (
  72. <div>
  73. <Button asChild type="default" icon={<ExternalLink />}>
  74. <Link href={url} target="_blank" rel="noreferrer">
  75. {urlLabel}
  76. </Link>
  77. </Button>
  78. </div>
  79. )}
  80. {button && <div>{button}</div>}
  81. </div>
  82. )}
  83. </div>
  84. </div>
  85. )
  86. }
  87. )
  88. InformationBox.displayName = 'InformationBox'
  89. export default InformationBox