import React, { useState, useRef, useEffect, useCallback } from 'react'; import classNames from 'classnames'; import { Tooltip } from 'antd'; import { useTranslation } from 'react-i18next'; import PlayGround, { PlayGroundProps } from './PlayGround'; import styles from './PlayGrounds.module.less'; interface PlayGroundsProps { examples: PlayGroundProps[]; location: Location; playground?: { container?: string; playgroundDidMount?: string; playgroundWillUnmount?: string; htmlCodeTemplate?: string; }; } const PlayGrounds: React.FC = ({ examples = [], location, playground, }) => { const { i18n } = useTranslation(); const defaultExample = examples.find( item => `#${item.filename.split('.')[0]}` === location.hash, ) || examples[0]; const [currentExample, updateCurrentExample] = useState(defaultExample || {}); // 滚动到当前节点 useEffect(() => { const id = currentExample?.filename?.split('.')[0]; const cardNode = document.getElementById(id); if (cardNode) { cardNode.scrollIntoView({ behavior: 'smooth', block: 'nearest', }); } }, [currentExample]); const [hasHorizontalScrollbar, updateHasHorizontalScrollbar] = useState( false, ); const [scrollPostion, updateScrollPostion] = useState('left'); const playgroundScrollDiv = useRef(null); const calcScrollPostion = (node: HTMLElement) => { if (node.scrollLeft < 2) { updateScrollPostion('left'); } else if (node.scrollLeft + node.clientWidth >= node.scrollWidth - 2) { updateScrollPostion('right'); } else { updateScrollPostion('middle'); } }; const onScroll = (e: any) => { if (!e || !e.target) { return; } calcScrollPostion(e.target); }; const onResize = useCallback(() => { if (playgroundScrollDiv && playgroundScrollDiv.current) { const div = playgroundScrollDiv!.current!; updateHasHorizontalScrollbar(div.scrollWidth > div.clientWidth); calcScrollPostion(div); } }, [playgroundScrollDiv]); useEffect(() => { onResize(); }, [examples]); useEffect(() => { window.addEventListener('resize', onResize); return () => { window.removeEventListener('resize', onResize); }; }, []); return (
{examples.map(example => { const title = typeof example.title === 'object' ? example.title[i18n.language] : example.title; return ( ) => { e.preventDefault(); window.history.pushState( {}, '', `#${example.filename.split('.')[0]}`, ); updateCurrentExample(example); }} id={example.filename.split('.')[0]} className={classNames(styles.card, { [styles.current]: example.relativePath === currentExample.relativePath, })} > {title ); })}
{playground && ( )}
); }; export default PlayGrounds;