import { useState, useEffect, useRef, useEffectEvent } from 'react'
import { Box, Button, Link, Typography } from '@mui/material'
import type { WidgetNoteProps } from './types'
import { styles } from './style'
import ReactMarkdown, { type Components } from 'react-markdown'
const DEFAULT_LABELS = {
showMore: 'Show More',
showLess: 'Show Less',
} as const
const DEFAULT_P = ({ children }: { children?: React.ReactNode }) => (
{children}
)
const COMPONENTS: Components = {
h1: DEFAULT_P,
h2: DEFAULT_P,
h3: DEFAULT_P,
p: DEFAULT_P,
a: ({ children, href, target = '_blank', rel = 'noopener noreferrer' }) => (
{children}
),
img: () => null,
ul: DEFAULT_P,
ol: DEFAULT_P,
li: DEFAULT_P,
}
/**
* Displays text content with markdown support and automatic show more/less functionality for long content. Automatically detects content exceeding 3 lines and shows an expand/collapse button.
*
* @example
* ```tsx
*
* {"**Important:** This data is from Q4 2024."}
*
* ```
*/
export function WidgetNote({
children,
labels = DEFAULT_LABELS,
}: WidgetNoteProps) {
const [isExpanded, setIsExpanded] = useState(false)
const [shouldShowToggle, setShouldShowToggle] = useState(false)
const contentRef = useRef(null)
const checkOverflow = useEffectEvent(() => {
if (contentRef.current) {
// Check if content overflows 3 lines
const isOverflowing =
contentRef.current.scrollHeight > contentRef.current.clientHeight
setShouldShowToggle(isOverflowing)
}
})
useEffect(() => {
checkOverflow()
}, [children])
useEffect(() => {
const element = contentRef.current
if (!element) return
const resizeObserver = new ResizeObserver(() => {
checkOverflow()
})
resizeObserver.observe(element)
return () => {
resizeObserver.disconnect()
}
}, [])
if (!children) {
return null
}
const handleToggle = () => {
setIsExpanded(!isExpanded)
}
const mergedLabels = { ...DEFAULT_LABELS, ...labels }
return (
{children}
{(shouldShowToggle || isExpanded) && (
)}
)
}