feat(website): add icons for sections (#8377)

* feat(website): add icons for sections

* chore: make requested changes

* fix: add icon for function parameters
This commit is contained in:
Suneet Tipirneni
2022-07-28 10:26:06 -04:00
committed by GitHub
parent c25e8ad78b
commit ec43c184fe
5 changed files with 70 additions and 70 deletions

View File

@@ -1,4 +1,5 @@
import type { ReactNode } from 'react'; import type { ReactNode } from 'react';
import { VscListSelection, VscSymbolParameter } from 'react-icons/vsc';
import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter'; import { PrismAsyncLight as SyntaxHighlighter } from 'react-syntax-highlighter';
import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism'; import { vscDarkPlus } from 'react-syntax-highlighter/dist/cjs/styles/prism';
import { CodeListingSeparatorType } from './CodeListing'; import { CodeListingSeparatorType } from './CodeListing';
@@ -48,11 +49,16 @@ export function DocContainer({ name, kind, excerpt, summary, typeParams, childre
</div> </div>
) : null} ) : null}
<div className="space-y-10"> <div className="space-y-10">
<Section title="Summary" className="dark:text-white"> <Section iconElement={<VscListSelection />} title="Summary" className="dark:text-white">
<p className="text-dark-100 dark:text-gray-300 m-0">{summary ?? 'No summary provided.'}</p> <p className="text-dark-100 dark:text-gray-300 m-0">{summary ?? 'No summary provided.'}</p>
</Section> </Section>
{typeParams?.length ? ( {typeParams?.length ? (
<Section title="Type Parameters" className="dark:text-white" defaultClosed> <Section
iconElement={<VscSymbolParameter />}
title="Type Parameters"
className="dark:text-white"
defaultClosed
>
<TypeParamTable data={typeParams} /> <TypeParamTable data={typeParams} />
</Section> </Section>
) : null} ) : null}

View File

@@ -1,8 +1,14 @@
import { AnimatePresence, motion } from 'framer-motion';
import Link from 'next/link'; import Link from 'next/link';
import { useState } from 'react'; import {
import { VscChevronDown, VscChevronRight } from 'react-icons/vsc'; VscSymbolClass,
VscSymbolEnum,
VscSymbolField,
VscSymbolInterface,
VscSymbolMethod,
VscSymbolVariable,
} from 'react-icons/vsc';
import type { ItemListProps } from './ItemSidebar'; import type { ItemListProps } from './ItemSidebar';
import { Section } from './Section';
export type Members = ItemListProps['data']['members']; export type Members = ItemListProps['data']['members'];
@@ -57,39 +63,32 @@ function groupMembers(members: Members): GroupedMembers {
return { Classes, Functions, Enums, Interfaces, Types, Variables }; return { Classes, Functions, Enums, Interfaces, Types, Variables };
} }
export function ListSidebarSection({ members, selectedMember, title }: ListSidebarSectionProps) { function resolveIcon(item: keyof GroupedMembers) {
const [showList, setShowList] = useState(true); switch (item) {
case 'Classes':
return <VscSymbolClass />;
case 'Enums':
return <VscSymbolEnum />;
case 'Interfaces':
return <VscSymbolInterface />;
case 'Types':
return <VscSymbolField />;
case 'Variables':
return <VscSymbolVariable />;
case 'Functions':
return <VscSymbolMethod />;
}
}
export function ListSidebar({ members, selectedMember }: ListSidebarSectionProps) {
const groupItems = groupMembers(members);
return ( return (
<div> <>
<h3 {(Object.keys(groupItems) as (keyof GroupedMembers)[]).map((group, i) => (
className="flex items-center dark:text-white m-0 py-3 font-semibold gap-2 cursor-pointer" <Section iconElement={resolveIcon(group)} key={i} title={group} showSeparator={false}>
onClick={() => setShowList(!showList)} <div className="space-y-2">
> {groupItems[group].map((member, i) => (
{showList ? <VscChevronDown size={20} /> : <VscChevronRight size={20} />}
{title}
</h3>
<AnimatePresence exitBeforeEnter initial={false}>
{showList ? (
<motion.div
className="ml-7 space-y-3"
transition={{ duration: 0.5, ease: [0.04, 0.62, 0.23, 0.98] }}
key="content"
initial="collapsed"
animate="open"
exit="collapsed"
variants={{
open: {
opacity: 1,
height: 'auto',
},
collapsed: {
opacity: 0,
height: 0,
},
}}
>
{members.map((member, i) => (
<div <div
key={i} key={i}
className="flex gap-2 whitespace-pre-wrap no-underline break-all text-blue-500 dark:text-blue-300" className="flex gap-2 whitespace-pre-wrap no-underline break-all text-blue-500 dark:text-blue-300"
@@ -107,25 +106,8 @@ export function ListSidebarSection({ members, selectedMember, title }: ListSideb
</Link> </Link>
</div> </div>
))} ))}
</motion.div>
) : null}
</AnimatePresence>
</div> </div>
); </Section>
}
export function ListSidebar({ members, selectedMember }: ListSidebarSectionProps) {
const groupItems = groupMembers(members);
return (
<>
{Object.keys(groupItems).map((group, i) => (
<ListSidebarSection
key={i}
members={groupItems[group as keyof GroupedMembers]}
selectedMember={selectedMember}
title={group}
/>
))} ))}
</> </>
); );

View File

@@ -8,24 +8,35 @@ export interface SectionProps {
title: string; title: string;
className?: string | undefined; className?: string | undefined;
defaultClosed?: boolean; defaultClosed?: boolean;
iconElement?: JSX.Element;
showSeparator?: boolean;
} }
export function Section({ title, children, className, defaultClosed }: SectionProps) { export function Section({
title,
children,
className,
defaultClosed,
iconElement,
showSeparator = true,
}: SectionProps) {
const [collapsed, setCollapsed] = useState(defaultClosed ?? false); const [collapsed, setCollapsed] = useState(defaultClosed ?? false);
return ( return (
<div className={className}> <div className={className}>
<AnimatePresence initial={false}>
<h3 <h3
className="flex gap-2 whitespace-pre-wrap font-semibold dark:text-white cursor-pointer" className="flex gap-2 whitespace-pre-wrap font-semibold dark:text-white cursor-pointer"
onClick={() => setCollapsed(!collapsed)} onClick={() => setCollapsed(!collapsed)}
> >
{collapsed ? <VscChevronRight size={20} /> : <VscChevronDown size={20} />} {collapsed ? <VscChevronRight size={20} /> : <VscChevronDown size={20} />}
{iconElement ?? null}
{title} {title}
</h3> </h3>
<AnimatePresence initial={false} exitBeforeEnter>
{collapsed ? null : ( {collapsed ? null : (
<> <>
<motion.div <motion.div
className="ml-7 mb-5"
transition={{ duration: 0.5, ease: [0.04, 0.62, 0.23, 0.98] }} transition={{ duration: 0.5, ease: [0.04, 0.62, 0.23, 0.98] }}
key="content" key="content"
initial="collapsed" initial="collapsed"
@@ -37,14 +48,13 @@ export function Section({ title, children, className, defaultClosed }: SectionPr
height: 'auto', height: 'auto',
paddingLeft: '1.75rem', paddingLeft: '1.75rem',
paddingRight: '1.75rem', paddingRight: '1.75rem',
paddingBottom: '2.5rem',
}, },
collapsed: { opacity: 0, height: 0, paddingLeft: '1.75rem', paddingRight: '1.75rem', paddingBottom: 0 }, collapsed: { opacity: 0, height: 0, paddingLeft: '1.75rem', paddingRight: '1.75rem', paddingBottom: 0 },
}} }}
> >
{children} {children}
</motion.div> </motion.div>
<Separator /> {showSeparator && <Separator />}
</> </>
)} )}
</AnimatePresence> </AnimatePresence>

View File

@@ -1,3 +1,4 @@
import { VscSymbolConstant, VscSymbolMethod, VscSymbolProperty } from 'react-icons/vsc';
import { MethodList } from './MethodList'; import { MethodList } from './MethodList';
import { ParameterTable } from './ParameterTable'; import { ParameterTable } from './ParameterTable';
import { PropertyList } from './PropertyList'; import { PropertyList } from './PropertyList';
@@ -11,7 +12,7 @@ export interface PropertiesSectionProps {
export function PropertiesSection({ data }: PropertiesSectionProps) { export function PropertiesSection({ data }: PropertiesSectionProps) {
return data.length ? ( return data.length ? (
<Section title="Properties" className="dark:text-white"> <Section iconElement={<VscSymbolProperty />} title="Properties" className="dark:text-white">
<PropertyList data={data} /> <PropertyList data={data} />
</Section> </Section>
) : null; ) : null;
@@ -23,7 +24,7 @@ export interface MethodsSectionProps {
export function MethodsSection({ data }: MethodsSectionProps) { export function MethodsSection({ data }: MethodsSectionProps) {
return data.length ? ( return data.length ? (
<Section title="Methods" className="dark:text-white"> <Section iconElement={<VscSymbolMethod />} title="Methods" className="dark:text-white">
<MethodList data={data} /> <MethodList data={data} />
</Section> </Section>
) : null; ) : null;
@@ -35,7 +36,7 @@ export interface ParametersSectionProps {
export function ParametersSection({ data }: ParametersSectionProps) { export function ParametersSection({ data }: ParametersSectionProps) {
return data.length ? ( return data.length ? (
<Section title="Parameters" className="dark:text-white"> <Section iconElement={<VscSymbolConstant />} title="Parameters" className="dark:text-white">
<ParameterTable data={data} /> <ParameterTable data={data} />
</Section> </Section>
) : null; ) : null;

View File

@@ -1,3 +1,4 @@
import { VscSymbolEnumMember } from 'react-icons/vsc';
import { CodeListing, CodeListingSeparatorType } from '../CodeListing'; import { CodeListing, CodeListingSeparatorType } from '../CodeListing';
import { DocContainer } from '../DocContainer'; import { DocContainer } from '../DocContainer';
import { Section } from '../Section'; import { Section } from '../Section';
@@ -10,7 +11,7 @@ export interface EnumProps {
export function Enum({ data }: EnumProps) { export function Enum({ data }: EnumProps) {
return ( return (
<DocContainer name={data.name} kind={data.kind} excerpt={data.excerpt} summary={data.summary}> <DocContainer name={data.name} kind={data.kind} excerpt={data.excerpt} summary={data.summary}>
<Section title="Members" className="dark:text-white"> <Section iconElement={<VscSymbolEnumMember />} title="Members" className="dark:text-white">
<div className="flex flex-col gap-5"> <div className="flex flex-col gap-5">
{data.members.map((member) => ( {data.members.map((member) => (
<CodeListing <CodeListing