import React, { useState, useContext, PropsWithChildren } from 'react'; import _get from 'lodash/get'; import { DevContainer } from 'tailchat-shared'; import clsx from 'clsx'; export interface SidebarViewMenuItemType { type: 'item'; title: string; content: React.ReactNode; /** * 是否是仅开发者可见 */ isDev?: boolean; /** * 隐藏这个项 */ hidden?: boolean; } interface SidebarViewLinkType { type: 'link'; title: string; onClick: () => void; isDanger?: boolean; } const SidebarViewMenuItemTitle: React.FC< PropsWithChildren<{ active?: boolean; isDanger?: boolean; onClick: () => void; }> > = (props) => (
{props.children}
); interface SidebarViewContextProps { content: React.ReactNode; setContent: (content: React.ReactNode) => void; } export const SidebarViewContext = React.createContext(null); SidebarViewContext.displayName = 'SidebarViewContext'; export type SidebarViewMenuItem = SidebarViewMenuItemType | SidebarViewLinkType; export type SidebarViewMenuType = | { type: 'group'; title: string; children: SidebarViewMenuItem[]; } | SidebarViewMenuItem; interface SidebarViewMenuProps { menu: SidebarViewMenuType; } const SidebarViewMenuItem: React.FC = React.memo( (props) => { const { menu } = props; const context = useContext(SidebarViewContext); if (!context) { return null; } const { content, setContent } = context; if (menu.type === 'group') { return (
{menu.title}
{menu.children.map((sub, i) => ( ))}
); } else if (menu.type === 'item') { if (menu.hidden === true) { return null; } const component = ( setContent(menu.content)} > {menu.title} ); if (menu.isDev === true) { return {component}; } else { return
{component}
; } } else if (menu.type === 'link') { return (
{menu.title}
); } return null; } ); SidebarViewMenuItem.displayName = 'SidebarViewMenuItem'; interface SidebarViewProps { menu: SidebarViewMenuType[]; /** * 默认内容路径 * @default "0.children.0.content" */ defaultContentPath: string; } export const SidebarView: React.FC = React.memo((props) => { const { menu, defaultContentPath = '0.children.0.content' } = props; const [content, setContent] = useState( _get(menu, defaultContentPath, null) ); return (
{menu.map((item, i) => ( ))}
{content}
); }); SidebarView.displayName = 'SidebarView';