import React, { useEffect, useState } from 'react'; import { useCallback, useContext } from 'react'; import { Fragment, FC } from 'react'; import { Entry, Link as BaseLink, useDocs, useMenus } from 'docz'; import styled, { css } from 'styled-components'; import { Logo } from '../../ui'; import { breakpoints } from '../../../styles/responsive'; import { mainContext } from '../Main'; import { TOPBAR_LINKS, IconLink } from '../Topbar'; import { useWindowSize } from '../../../config'; import Icon from 'kwai-icon'; import { CollapseContext } from '../../../index'; import Input from '../../../../../components/input'; interface WrapperProps { opened: boolean; mobile: boolean; } const toggle = (p: WrapperProps) => { return !p.opened && p.mobile ? '-100%' : '0'; }; const SidebarWrapper = styled.div` position: sticky; overflow-y: auto; background: #f6f7fb; top: 0; flex-shrink: 0; width: 256px; padding: 0 0 40px 32px; box-sizing: border-box; height: 100vh; margin-right: 42px; border-right: 1px solid ${p => p.theme.colors.grayLight}; transition: transform 0.2s, background 0.3s; transform: translateX(${toggle}); ${p => p.mobile && css` position: absolute; top: 0; left: 0; overflow: auto; z-index: 9999; padding: 30px; `}; `; const LogoLink = styled(BaseLink)` display: block; margin-top: 17px; margin-bottom: 40px; height: 30px; `; const Wrapper = styled.div` position: sticky; display: flex; flex-direction: column; width: 100%; ${p => p.theme.mq({ position: ['relative', 'relative', 'sticky', 'sticky'], top: ['0px', '0px', '50px', '50px'], })}; `; const MenuLink = styled(BaseLink)` height: 48px; line-height: 48px; position: relative; user-select: none; &, &:visited { color: #101934; } &.active, &:hover { color: #00a5aa; } &.active::after { display: block; content: ' '; position: absolute; right: 0; top: 14px; width: 2px; height: 20px; background: #00a5aa; } `; const Link = styled(BaseLink)` font-size: 16px; padding: 2px 0; &, &:visited { color: ${p => p.theme.colors.grayDark}; } &.active, &:hover { color: ${p => p.theme.colors.purple}; } `; const SmallLink = styled(BaseLink)` font-size: 14px; padding: 0 0 5px 10px; &, &.active, &:visited { color: ${p => p.theme.colors.gray}; } &:hover { color: ${p => p.theme.colors.purple}; } `; const Submenu = styled.div` display: flex; flex-direction: column; margin: 5px 0; `; const MenuGroup = styled.h2` height: 48px; font-size: 14px; color: #868da1; line-height: 48px; letter-spacing: 0.3px; font-weight: normal; margin: 0; `; const Down = styled(Icon).attrs(() => ({ name: 'DropDown', size: 'large', color: '#7E8391' }))` transform: rotate(${p => (p.open ? 180 : 0)}deg); transition: all 120ms ease-in; position: absolute; right: 60px; top: 12px; `; const CollapseWrap = styled.h2` cursor: pointer; user-select: none; height: 48px; font-size: 14px; color: #101934; line-height: 48px; letter-spacing: 0.3px; font-weight: normal; margin: 0; position: relative; `; const CountSpan = styled.span` color: #b6bbc7; margin-left: 6px; font-size: 12px; `; interface OpenProps { opened: boolean; } const ToggleBackground = styled.div` content: ''; display: ${(p: OpenProps) => (!p.opened ? 'none' : 'block')}; position: fixed; background-color: rgba(0, 0, 0, 0.4); width: 100vw; height: 100vh; top: 0; bottom: 0; left: 0; right: 0; cursor: pointer; z-index: 98; `; interface MenuProps { doc: Entry; style?: React.CSSProperties; active: boolean; onClick: React.MouseEventHandler; } const Menu: FC = ({ doc, active, onClick, style }) => { //const headings = doc.headings.filter(heading => heading.depth > 1 && heading.depth < 3); //{active && headings.length > 0 && ( // // {headings.map(heading => ( // // {heading.value} // // ))} // //)} return ( {doc.name} ); }; interface TopbarMenuProps { onClick: React.MouseEventHandler; } const TopbarMenu: React.FC = ({ onClick }) => { return ( {TOPBAR_LINKS.map(({ id, children, ...props }) => { const Component = props.to ? Link : IconLink; return ( {children} ); })} ); }; interface SidebarProps { menu: string; pathname?: string; mobile?: boolean; } export const Sidebar: FC = ({ menu: current, pathname, mobile }) => { const docs = useDocs(); console.log(docs); const { width } = useWindowSize(); const { showing, setShowing } = useContext(mainContext); const [query, setQuery] = useState(''); useEffect(() => { document.querySelector('a.active')!.scrollIntoView({ behavior: 'smooth', inline: 'nearest' }); }, []); const menus = useMenus({ query }); console.log(menus); const isDesktop = width > breakpoints.tablet; const [open, setOpen] = useContext(CollapseContext); const toggle = useCallback(() => { setShowing((s: any) => !s); }, []); const handleSidebarToggle = (ev: React.SyntheticEvent) => { if (isDesktop) return; toggle && toggle(); }; const transformed = transformMenus(menus, query); const count = (docs || []).filter(d => d.parent === '组件').length; return ( {mobile && } setQuery(e.target.value)} /> {transformed && transformed.map(({ id, name, menu }: any) => { return ( {name !== 'General' && id !== 'id' && open && {name}} {id === 'id' && ( setOpen(!open)}> 组件 {count && {count}} )} {menu && menu.map((item: any) => { const showItem = name === 'General' || (open && item.parent === '组件'); const doc = docs && docs.find(doc => doc.name === item.name); if (!doc) return null; return ( showItem && ( ) ); })} ); })} {!isDesktop && } ); }; function transformMenus(menus: any, query: string) { if (!query) { const filter = menus.filter((m: any) => m.menu); filter.splice(1, 0, { name: '组件', id: 'id' }); return filter; } return [{ id: 1, name: '搜索结果', menu: menus }]; }