import React, { useState } from 'react';
import { graphql, Link } from 'gatsby';
import { Layout as AntLayout, Menu, Icon, Tooltip, Anchor } from 'antd';
import { groupBy } from 'lodash-es';
import { useTranslation } from 'react-i18next';
import Drawer from 'rc-drawer';
import { useMedia } from 'react-use';
import Article from '../components/Article';
import SEO from '../components/Seo';
import Tabs from '../components/Tabs';
import PlayGrounds from '../components/PlayGrounds';
import NavigatorBanner from '../components/NavigatorBanner';
import { capitalize } from '../utils';
import styles from './markdown.module.less';
const MenuIcon = Icon.createFromIconfontCN({
scriptUrl: '//at.alicdn.com/t/font_470089_9m0keqj54r.js', // generated by iconfont.cn
});
const renderMenuItems = (edges: any[]) =>
edges
.filter((edge: any) => {
const {
node: {
fields: { slug },
},
} = edge;
if (slug.endsWith('/API') || slug.endsWith('/design')) {
return false;
}
return true;
})
.sort((a: any, b: any) => {
const {
node: {
frontmatter: { order: aOrder },
},
} = a;
const {
node: {
frontmatter: { order: bOrder },
},
} = b;
return aOrder - bOrder;
})
.map((edge: any) => {
const {
node: {
frontmatter: { title, icon },
fields: { slug },
},
} = edge;
return (
{icon && (
)}
{title}
);
});
const getMenuItemLocaleKey = (slug = '') => {
const slugPieces = slug.split('/');
const menuItemLocaleKey = slugPieces
.slice(slugPieces.indexOf('examples') + 1)
.filter(key => key)
.join('/');
return menuItemLocaleKey;
};
const getExampleOrder = ({
groupedEdgeKey = '',
examples = [],
groupedEdges = {},
}: {
groupedEdgeKey: string;
examples: any[];
groupedEdges: {
[key: string]: any[];
};
}): number => {
const key = getMenuItemLocaleKey(groupedEdgeKey);
if (examples.find(item => item.slug === key)) {
return (examples.findIndex(item => item.slug === key) || 0) + 100;
}
if (!groupedEdges[groupedEdgeKey] && !groupedEdges[groupedEdgeKey].length) {
return 0;
}
return groupedEdges[groupedEdgeKey][0].node.frontmatter.order || 0;
};
export default function Template({
data, // this prop will be injected by the GraphQL query below.
location,
pageContext,
}: {
data: any;
location: Location;
pageContext: {
prev: any;
next: any;
exampleSections: any;
allDemos?: any[];
};
}) {
const { allMarkdownRemark, site } = data; // data.markdownRemark holds our post data
const { edges = [] } = allMarkdownRemark;
const edgesInExamples = edges.filter((item: any) =>
item.node.fields.slug.includes('/examples/'),
);
const pathWithoutTrailingSlashes = location.pathname.replace(/\/$/, '');
const { node: markdownRemark } =
edgesInExamples.find((edge: any) => {
const {
fields: { slug },
} = edge.node;
if (
/\/examples\/.*\/API$/.test(pathWithoutTrailingSlashes) ||
/\/examples\/.*\/design$/.test(pathWithoutTrailingSlashes)
) {
return pathWithoutTrailingSlashes.indexOf(slug) >= 0;
}
return (
pathWithoutTrailingSlashes === slug ||
pathWithoutTrailingSlashes.endsWith(slug)
);
}) || {};
if (!markdownRemark) {
return null;
}
const {
frontmatter,
html,
fields: { slug },
parent: { relativePath },
} = markdownRemark;
const {
siteMetadata: { examples = [], githubUrl, playground },
} = site;
const { t, i18n } = useTranslation();
const groupedEdges = groupBy(
edgesInExamples,
({
node: {
fields: { slug: slugString },
},
}: any) => {
// API.md and deisgn.md
if (slugString.endsWith('/API') || slugString.endsWith('/design')) {
return slugString
.split('/')
.slice(0, -2)
.join('/');
}
// index.md
return slugString
.split('/')
.slice(0, -1)
.join('/');
},
);
const defaultOpenKeys = Object.keys(groupedEdges).filter(key =>
slug.startsWith(key),
);
const [openKeys, setOpenKeys] = useState(defaultOpenKeys);
let activeTab = 'examples' as 'examples' | 'API' | 'design';
let exampleRootSlug = slug;
if (/\/examples\/.*\/API$/.test(pathWithoutTrailingSlashes)) {
activeTab = 'API';
exampleRootSlug = exampleRootSlug.replace(/\/API$/, '');
} else if (/\/examples\/.*\/design$/.test(pathWithoutTrailingSlashes)) {
activeTab = 'design';
exampleRootSlug = exampleRootSlug.replace(/\/design$/, '');
}
const { exampleSections = {}, prev, next, allDemos = [] } = pageContext;
const menu = (
);
const isWide = useMedia('(min-width: 767.99px)', true);
const [drawOpen, setDrawOpen] = useState(false);
const menuSider = isWide ? (
{menu}
) : (
}
wrapperClassName={styles.menuDrawer}
onChange={open => setDrawOpen(!!open)}
width={280}
>
{menu}
);
const allDemosInCategory = groupBy(allDemos || [], demo => {
if (!demo.postFrontmatter || !demo.postFrontmatter[i18n.language]) {
return 'OTHER';
}
return demo.postFrontmatter[i18n.language].title;
});
const Categories = Object.keys(allDemosInCategory).sort(
(a: string, b: string) => {
if (a === 'OTHER') {
return -1;
}
if (b === 'OTHER') {
return 1;
}
return (
allDemosInCategory[a][0].postFrontmatter[i18n.language].order -
allDemosInCategory[b][0].postFrontmatter[i18n.language].order
);
},
);
const galleryPageContent = (
{Categories.map((category: string) => (
))}
{frontmatter.title}
{Categories.map((category: string) => (
{category !== 'OTHER' && (
{category}
)}
{allDemosInCategory[category].map(demo => {
let cardTitle;
if (typeof demo.title === 'string') {
cardTitle = demo.title;
} else {
cardTitle = demo.title
? demo.title[i18n.language]
: demo.filename;
}
const demoSlug = demo.relativePath.replace(
/\/demo\/(.*)\..*/,
(_: string, filename: string) => {
return `#${filename}`;
},
);
return (
-
{cardTitle}
);
})}
))}
);
const exmaplePageContent = (
<>
{frontmatter.title}
0,
API: !!exampleSections.API,
design: !!exampleSections.design,
}}
examplesCount={(exampleSections.examples || []).length}
/>
{exampleSections.examples && (
)}
{exampleSections.API && (
)}
{exampleSections.design && (
)}
>
);
return (
<>
{menuSider}
{pathWithoutTrailingSlashes.endsWith('/examples/gallery')
? galleryPageContent
: exmaplePageContent}
>
);
}
export const pageQuery = graphql`
query {
site {
siteMetadata {
title
githubUrl
examples {
slug
icon
title {
zh
en
}
}
playground {
container
playgroundDidMount
playgroundWillUnmount
dependencies
htmlCodeTemplate
}
}
pathPrefix
}
allMarkdownRemark(
sort: { order: ASC, fields: [frontmatter___order] }
limit: 1000
) {
edges {
node {
html
fields {
slug
}
frontmatter {
title
order
icon
}
parent {
... on File {
relativePath
}
}
}
}
}
}
`;