UNPKG

gatsby-theme-zh

Version:
453 lines (452 loc) 23.6 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint no-underscore-dangle: 0 */ const react_1 = __importStar(require("react")); const gatsby_1 = require("gatsby"); const classnames_1 = __importDefault(require("classnames")); const antd_1 = require("antd"); const react_use_1 = require("react-use"); const debounce_1 = __importDefault(require("lodash/debounce")); const lodash_es_1 = require("lodash-es"); const icons_1 = require("@ant-design/icons"); const react_i18next_1 = require("react-i18next"); const react_split_pane_1 = __importDefault(require("react-split-pane")); const standalone_1 = require("@babel/standalone"); const layoutConfig_1 = require("../layoutConfig"); const Toolbar_1 = __importStar(require("./Toolbar")); const ChartViewSwitcher_1 = __importDefault(require("./ChartViewSwitcher")); const LayoutSwitcher_1 = __importDefault(require("./LayoutSwitcher")); const PlayGrounds_1 = __importDefault(require("./PlayGrounds")); const APIDoc_1 = __importDefault(require("./APIDoc")); const PageLoading_1 = __importDefault(require("./PageLoading")); const PlayGround_module_less_1 = __importDefault(require("./PlayGround.module.less")); const document_1 = require("../templates/document"); const { Content, Sider } = antd_1.Layout; const MonacoEditor = react_1.lazy(() => Promise.resolve().then(() => __importStar(require('react-monaco-editor')))); const execute = debounce_1.default((code, node, exampleContainer) => { const script = document.createElement('script'); script.innerHTML = ` try { ${code} } catch(e) { if (window.__reportErrorInPlayGround) { window.__reportErrorInPlayGround(e); } } `; // eslint-disable-next-line no-param-reassign node.innerHTML = exampleContainer || '<div id="container" />'; node.appendChild(script); }, 300); const PlayGround = ({ exampleSections, location, markdownRemark, description, allDemos, categories, }) => { const { site } = gatsby_1.useStaticQuery(gatsby_1.graphql ` query { site { siteMetadata { showChartResize showAPIDoc githubUrl docGitUrl playground { container playgroundDidMount playgroundWillUnmount dependencies htmlCodeTemplate } } } } `); const { siteMetadata: { githubUrl, playground, docGitUrl }, } = site; const localLayout = typeof window !== 'undefined' ? localStorage.getItem('layout') : null; const { showChartResize, showAPIDoc } = site.siteMetadata; const [layout, updateLayout] = react_1.useState(localLayout || 'viewDefault'); const [codeQuery, updateCodeQuery] = react_1.useState(''); const { i18n, t } = react_i18next_1.useTranslation(); const [currentExample, updateCurrentExample] = react_1.useState(); const [editRef, updateEditRef] = react_1.useState(); const { examples } = exampleSections; const playgroundNode = react_1.useRef(null); const [error, setError] = react_1.useState(); const [collapsed, updateCollapsed] = react_1.useState(false); const [showAPISearch, updateShowAPIsearch] = react_1.useState(true); const [compiledCode, updateCompiledCode] = react_1.useState(''); const [currentCategory, updateCurrentCategory] = react_1.useState(''); const [relativePath, updateRelativePath] = react_1.useState(''); const [fileExtension, updateFileExtension] = react_1.useState(''); const [title, updateTitle] = react_1.useState(''); const [view, updateView] = react_1.useState('desktop'); const [docsEmpty, updateDocsEmpty] = react_1.useState(false); const [currentSourceCode, updateCurrentSourceCode] = react_1.useState(''); const [currentSourceData, updateCurrentSourceData] = react_1.useState(null); const editroRef = react_1.useRef(null); const isWide = react_use_1.useMedia('(min-width: 767.99px)', true); const comment = i18n.language === 'zh' ? `// 我们用 insert-css 演示引入自定义样式 // 推荐将样式添加到自己的样式文件中 // 若拷贝官方代码,别忘了 npm install insert-css insertCss(` : `// We use 'insert-css' to insert custom styles // It is recommended to add the style to your own style sheet files // If you want to copy the code directly, please remember to install the npm package 'insert-css insertCss(`; const replaceInsertCss = (str) => { // 统一增加对 insert-css 的使用注释 return str.replace(/^insertCss\(/gm, comment); }; if (typeof window !== 'undefined') { window.__reportErrorInPlayGround = (e) => { console.error(e); // eslint-disable-line no-console setError(e); }; } const updateCurrentExampleParams = (current) => { if (!(current === null || current === void 0 ? void 0 : current.relativePath)) return; updateRelativePath(current === null || current === void 0 ? void 0 : current.relativePath); updateFileExtension((current === null || current === void 0 ? void 0 : current.relativePath.split('.')[current.relativePath.split('.').length - 1]) || 'js'); updateTitle(current === null || current === void 0 ? void 0 : current.title); updateCompiledCode(current.babeledSource); updateCurrentSourceCode(replaceInsertCss(current.source)); }; const setLayout = (ifWide, empty) => { if (!ifWide) { updateLayout('viewTwoRows'); updateCollapsed(true); } else if (!showAPIDoc || empty) { updateLayout('viewTwoCols'); } }; react_1.useEffect(() => { var _a, _b, _c, _d; if (currentExample || !examples) return; const defaultExample = examples.find((item) => `#${item.filename.split('.')[0]}` === location.hash) || examples[0]; updateCurrentExample(defaultExample); if (!((_b = (_a = exampleSections === null || exampleSections === void 0 ? void 0 : exampleSections.design) === null || _a === void 0 ? void 0 : _a.node) === null || _b === void 0 ? void 0 : _b.html) && !description && !((_d = (_c = exampleSections === null || exampleSections === void 0 ? void 0 : exampleSections.API) === null || _c === void 0 ? void 0 : _c.node) === null || _d === void 0 ? void 0 : _d.html)) { updateDocsEmpty(true); } }, [examples, description]); react_1.useEffect(() => { setLayout(isWide, docsEmpty); }, [isWide, docsEmpty]); react_1.useEffect(() => { if (!currentExample || !allDemos) return; updateView('desktop'); updateCurrentExampleParams(currentExample); lodash_es_1.filter(allDemos, (item, key) => { const cur = item.find((val) => (val === null || val === void 0 ? void 0 : val.relativePath) === currentExample.relativePath); if (cur) updateCurrentCategory(key); return item; }); }, [currentExample, allDemos]); const executeCode = () => { if (!compiledCode || !playgroundNode || !playgroundNode.current) { return; } execute(compiledCode, playgroundNode.current, playground === null || playground === void 0 ? void 0 : playground.container); }; react_1.useEffect(() => { executeCode(); }, [compiledCode, error, view]); react_1.useEffect(() => { if (playground === null || playground === void 0 ? void 0 : playground.playgroundDidMount) { // eslint-disable-next-line no-new-func new Function(playground === null || playground === void 0 ? void 0 : playground.playgroundDidMount)(); } return () => { if (playground === null || playground === void 0 ? void 0 : playground.playgroundWillUnmount) { // eslint-disable-next-line no-new-func new Function(playground === null || playground === void 0 ? void 0 : playground.playgroundWillUnmount)(); } }; }, []); const [editorTabs, updateEditroTabs] = react_1.useState([]); const [currentEditorTab, updateCurrentEditorTab] = react_1.useState(Toolbar_1.EDITOR_TABS.JAVASCRIPT); react_1.useEffect(() => { const dataFileMatch = currentSourceCode.match(/fetch\('(.*)'\)/); if (dataFileMatch && dataFileMatch.length > 0) { updateEditroTabs([Toolbar_1.EDITOR_TABS.JAVASCRIPT, Toolbar_1.EDITOR_TABS.DATA]); fetch(dataFileMatch[1]) .then((response) => response.json()) .then((data) => { updateCurrentSourceData(data); }); } }, [currentSourceCode]); const onCodeChange = (value) => { if (currentEditorTab === Toolbar_1.EDITOR_TABS.JAVASCRIPT) { updateCurrentSourceCode(value); try { const { code } = standalone_1.transform(value, { filename: relativePath, presets: ['react', 'typescript', 'es2015', 'stage-3'], plugins: ['transform-modules-umd'], }); updateCompiledCode(code); } catch (e) { console.error(e); // eslint-disable-line no-console setError(e); return; } setError(null); } }; react_1.useEffect(() => { if (editroRef.current) { if (currentEditorTab === Toolbar_1.EDITOR_TABS.JAVASCRIPT) { editroRef.current.setValue(currentSourceCode); } else if (currentEditorTab === Toolbar_1.EDITOR_TABS.DATA) { editroRef.current.setValue(JSON.stringify(currentSourceData, null, 2)); } } }, [currentEditorTab]); const codeEditor = (react_1.default.createElement(MonacoEditor, { height: "calc(100% - 32px)", language: currentEditorTab === Toolbar_1.EDITOR_TABS.JAVASCRIPT ? 'javascript' : 'json', value: currentSourceCode, options: { readOnly: currentEditorTab === Toolbar_1.EDITOR_TABS.DATA, automaticLayout: true, minimap: { enabled: false, }, scrollBeyondLastLine: false, fixedOverflowWidgets: true, }, onChange: (value) => onCodeChange(value), editorWillMount: (monaco) => { monaco.editor.defineTheme('customTheme', { base: 'vs', inherit: true, rules: [], colors: { 'editor.inactiveSelectionBackground': '#ffffff', }, }); monaco.editor.setTheme('customTheme'); }, editorDidMount: (editor, monaco) => { updateEditRef(editor); editor.addAction({ // An unique identifier of the contributed action. id: 'search-in-doc', // A label of the action that will be presented to the user. label: 'search in document', contextMenuGroupId: 'navigation', // An optional array of keybindings for the action. keybindings: [ // eslint-disable-next-line no-bitwise monaco.KeyMod.CtrlCmd | monaco.KeyCode.F10, ], contextMenuOrder: 0, run: (ed) => { const val = ed.getModel().getValueInRange(ed.getSelection()); updateCodeQuery(val); }, }); editroRef.current = editor.getModel(); } })); const dispatchResizeEvent = () => { const e = new Event('resize'); window.dispatchEvent(e); }; const toggle = () => { updateCollapsed(!collapsed); }; react_1.useEffect(() => { dispatchResizeEvent(); if (isWide && showAPIDoc && !docsEmpty) localStorage.setItem('layout', layout); const pane = document.getElementsByClassName('ant-layout'); if (!pane[1]) return; if (layout === 'viewTwoRows') { pane[1].setAttribute('style', 'margin-top: 64px'); } else { pane[1].setAttribute('style', 'margin-top: 0'); } }, [layout, collapsed]); // 图例滚动到当前节点 react_1.useEffect(() => { var _a; if (!currentExample || !(currentExample === null || currentExample === void 0 ? void 0 : currentExample.filename) || !layout) { return; } const id = `example-${(_a = currentExample === null || currentExample === void 0 ? void 0 : currentExample.filename) === null || _a === void 0 ? void 0 : _a.split('.')[0]}`; const cardNode = document.getElementById(id); if (cardNode) { cardNode.scrollIntoView({ behavior: 'smooth', block: 'nearest', }); } }, [currentExample, layout, playground]); const getThemeCode = (type, themeString) => { const colors = JSON.parse(themeString); let res; if (type === 'g2') { res = { styleSheet: { brandColor: colors.colors10[0], paletteQualitative10: colors.colors10, paletteQualitative20: colors.colors20, }, }; } else { res = { theme: { styleSheet: { brandColor: colors.colors10[0], paletteQualitative10: colors.colors10, paletteQualitative20: colors.colors20, }, }, }; } return JSON.stringify(res); }; // 根据pane框度及当前视图判断是否需要展示API文档搜索框 const calcShowSearch = (size) => { const clientw = document.body.clientWidth; if (size / clientw > 0.668) { updateShowAPIsearch(false); } else { updateShowAPIsearch(true); } }; const routes = [ { path: `/${i18n.language}/examples`, breadcrumbName: i18n.language === 'zh' ? '图表示例' : 'Gallery', }, { path: '/category', breadcrumbName: 'Second-level Menu', children: [], }, ]; const getTreeData = () => { const result = []; categories.forEach((category) => { const root = { title: category, value: '', children: [], }; allDemos[category].forEach((item, index) => { const demoSlug = item.relativePath.replace(/\/demo\/(.*)\..*/, (_, filename) => { return `#${filename}`; }); const path = `/${i18n.language}/examples/${demoSlug}`; if (index === 0) { root.value = `root::${path}`; } const child = { title: typeof item.title === 'object' ? item.title[i18n.language] : item.title || (item === null || item === void 0 ? void 0 : item.filename), value: path, }; root.children.push(child); }); result.push(root); }); return result; }; const onChange = (value) => { const tmp = value.split('::'); const path = tmp[1] ? tmp[1] : value; // window.location.assign(path); // window.location.href = `${path}`; window.history.pushState({}, '', `${path}`); window.location.reload(); }; function itemRender(route) { if (route.children) { return (react_1.default.createElement(antd_1.TreeSelect, { className: PlayGround_module_less_1.default.breadDrop, style: { width: '100%' }, value: currentCategory, bordered: false, dropdownStyle: { maxHeight: 640, overflow: 'auto', color: '#7d8a96 !important', paddingRight: '8px', }, dropdownClassName: PlayGround_module_less_1.default.breadDropItem, dropdownMatchSelectWidth: false, treeData: getTreeData(), placeholder: "Please select", treeDefaultExpandAll: true, onChange: onChange })); } return (react_1.default.createElement(gatsby_1.Link, { key: route.path, to: route.path }, route.breadcrumbName)); } return (react_1.default.createElement(react_split_pane_1.default, { split: layoutConfig_1.splitPaneMap[layout].outside.split, size: layoutConfig_1.splitPaneMap[layout].outside.size, onDragFinished: dispatchResizeEvent, onChange: (size) => calcShowSearch(size) }, playground && currentExample && layout ? (react_1.default.createElement(react_split_pane_1.default, { split: layoutConfig_1.splitPaneMap[layout].inside.split, size: layoutConfig_1.splitPaneMap[layout].inside.size, onDragFinished: dispatchResizeEvent, className: PlayGround_module_less_1.default.playground }, react_1.default.createElement(antd_1.Layout, { className: PlayGround_module_less_1.default.playgroundCard }, react_1.default.createElement(Sider, { collapsedWidth: 0, width: 120, trigger: null, collapsible: true, collapsed: collapsed, className: PlayGround_module_less_1.default.menuSider, theme: "light" }, react_1.default.createElement(PlayGrounds_1.default, { examples: examples, currentExample: currentExample, updateCurrentExample: updateCurrentExample })), react_1.default.createElement(icons_1.LeftOutlined, { className: PlayGround_module_less_1.default.trigger, type: collapsed ? 'menu-unfold' : 'menu-fold', onClick: toggle, rotate: collapsed ? 180 : 0 }), relativePath ? (react_1.default.createElement(antd_1.Layout, null, react_1.default.createElement(antd_1.PageHeader, { ghost: false, breadcrumb: isWide ? { routes, itemRender } : {}, title: typeof currentExample.title === 'object' ? currentExample.title[i18n.language] : currentExample.title, subTitle: react_1.default.createElement(antd_1.Tooltip, { title: '在 Git 上编辑' }, react_1.default.createElement("a", { href: document_1.getGithubSourceUrl({ docGitUrl, relativePath, prefix: 'examples', }), target: "_blank", rel: "noopener noreferrer", className: PlayGround_module_less_1.default.editOnGtiHubButton }, react_1.default.createElement(icons_1.EditOutlined, null))), extra: react_1.default.createElement(antd_1.Space, { split: react_1.default.createElement(antd_1.Divider, { type: "vertical" }) }, showChartResize && layout === 'viewDefault' && (react_1.default.createElement(ChartViewSwitcher_1.default, { updateView: updateView, view: view })), showAPIDoc && !docsEmpty && layout !== 'viewTwoRows' && (react_1.default.createElement(LayoutSwitcher_1.default, { updateLayout: updateLayout }))) }), react_1.default.createElement(Content, { className: PlayGround_module_less_1.default.chartContainer }, react_1.default.createElement("div", { className: classnames_1.default(PlayGround_module_less_1.default.preview, `playground-${relativePath.split('/').join('-')}`) }, error ? (react_1.default.createElement(antd_1.Result, { status: "error", title: i18n.language === 'zh' ? '演示代码报错,请检查' : 'Demo code error, please check', subTitle: react_1.default.createElement("pre", null, error && error.message) })) : (react_1.default.createElement("div", { ref: playgroundNode, className: PlayGround_module_less_1.default[view] })))))) : (react_1.default.createElement(antd_1.Skeleton, { paragraph: { rows: 8 }, className: PlayGround_module_less_1.default.skeleton }))), react_1.default.createElement("div", { className: PlayGround_module_less_1.default.editor }, title && fileExtension && (react_1.default.createElement(Toolbar_1.default, { fileExtension: fileExtension, sourceCode: currentSourceCode, playground: playground, location: location, title: title, onExecuteCode: executeCode, editorTabs: editorTabs, currentEditorTab: currentEditorTab, onEditorTabChange: updateCurrentEditorTab, onToggleFullscreen: null })), !relativePath ? (react_1.default.createElement(antd_1.Skeleton, { paragraph: { rows: 8 }, className: PlayGround_module_less_1.default.skeleton })) : (react_1.default.createElement("div", { className: PlayGround_module_less_1.default.monaco }, react_1.default.createElement(react_1.Suspense, { fallback: react_1.default.createElement(PageLoading_1.default, null) }, codeEditor)))))) : (react_1.default.createElement(react_1.default.Fragment, null)), relativePath && (layout === 'viewDefault' || layout === 'viewThreeCols') ? (react_1.default.createElement(APIDoc_1.default, { markdownRemark: markdownRemark, githubUrl: githubUrl, relativePath: relativePath, exampleSections: exampleSections, description: description, codeQuery: codeQuery, showAPISearch: showAPISearch })) : (react_1.default.createElement(react_1.default.Fragment, null)))); }; class ErrorHandlerPlayGround extends react_1.default.Component { constructor() { super(...arguments); this.state = { error: undefined, }; } static getDerivedStateFromError(error) { // 更新 state 使下一次渲染能够显示降级后的 UI return { error }; } render() { const { t } = this.props; const { error } = this.state; if (error) { // 你可以自定义降级后的 UI 并渲染 return (react_1.default.createElement(antd_1.Result, { status: "error", title: t('演示代码报错,请检查'), subTitle: react_1.default.createElement("pre", null, error && error.message) })); } return react_1.default.createElement(PlayGround, Object.assign({}, this.props)); } } exports.default = react_i18next_1.withTranslation()(ErrorHandlerPlayGround);