import { createFromIconfontCN, SearchOutlined, VerticalAlignTopOutlined } from '@ant-design/icons'; import { Input, Menu, Tooltip } from 'antd'; import classNames from 'classnames'; import { FormattedMessage, useIntl, useLocale } from 'dumi'; import { cloneDeep } from 'lodash-es'; import React, { ReactNode, useEffect, useRef, useState } from 'react'; import { Demo, ExampleTopic } from '../../types'; import { filterTreeNode } from '../utils'; import styles from './index.module.less'; // menu icon const MenuIcon = createFromIconfontCN({ scriptUrl: '//at.alicdn.com/t/font_470089_1lnym745udm.js', // generated by iconfont.cn }); export interface ExampleSiderProps { /** * 当前 Example (受控) */ currentDemo: Demo; /** * 当选中的 Demo 被改变时做些什么 */ onDemoClicked: (demo: Demo) => void; /** * 所有的案例主题 */ exampleTopics: ExampleTopic[]; showExampleDemoTitle: boolean; } /** * DEMO 预览页面的菜单 */ const ExampleSider: React.FC = (props) => { const { currentDemo, onDemoClicked, exampleTopics } = props; // 菜单栏展开keys const [openKeys, setOpenKeys] = useState([]); const menuRef = useRef(null); // 初始化点击进来的示例按钮a的dom const [aRef, setARef] = useState(); // input 搜索框的value const [searchValue, setSearchValue] = useState(''); const locale = useLocale(); const intl = useIntl(); const getCurrentTopics = () => { const res = filterTreeNode( { id: 'FAKE_ID', childrenKey: 'exampleTopics', title: { zh: 'FAKE_TITLE', en: 'FAKE_TITLE', }, exampleTopics: cloneDeep(exampleTopics), }, searchValue, locale.id, ); return res?.exampleTopics || []; }; // 初始化菜单栏展开keys useEffect(() => { const { targetExample, targetTopic } = currentDemo; const keys = [`TOPIC-${targetTopic?.id}`, `EXAMPLE-${targetTopic.id}-${targetExample?.id}`]; setOpenKeys(keys); }, [currentDemo]); // 初始化滚动到中间 useEffect(() => { if (aRef) { aRef.scrollIntoView({ block: 'center', behavior: 'smooth', }); } }, [aRef]); // 获取搜索后的文本结构 左文本 + 搜索文本 + 右文本 const getSearchValueTitle = (title: string): ReactNode => searchValue && title.match(searchValue) ? ( <> {title.replace(new RegExp(`${searchValue}.*`), '')} {searchValue} {title.replace(new RegExp(`.*?${searchValue}`), '')} ) : ( title ); // 图例按钮 + img + tooltip文本 const renderExampleDemoCard = (demo: Demo) => ( { // TODO: DEAL WITH ME // if (dom && !aRef && item.value === getPath(currentExample)) { // setARef(dom); // } }} className={classNames(styles.card, { [styles.current]: currentDemo.id === demo.id, })} >
); const renderSubMenu = () => { return getCurrentTopics().map((topic) => { return ( {topic.icon && } {topic.title && getSearchValueTitle(topic.title[locale.id])}
} > {topic.examples.map((example) => { return ( {example.demos.map((demo) => { return ( { onDemoClicked({ ...demo, targetExample: example, targetTopic: topic, }); }} > {renderExampleDemoCard(demo)} ); })} ); })} ); }); }; // 搜索栏 const renderSearchBar = () => { return (
} value={searchValue} onChange={(e: any) => setSearchValue(e.target.value)} /> ) as React.ReactNode}> setOpenKeys([])} />
); }; return (
{renderSearchBar()} { setOpenKeys(keys); }} > {renderSubMenu()}
); }; export default ExampleSider;