diff --git a/.gitignore b/.gitignore index 69ca51160d..d2c0127752 100644 --- a/.gitignore +++ b/.gitignore @@ -5,8 +5,6 @@ server/view/ .expo/ # json -static/search_data_client.json -search/data_client.json static/changeLog.json static/designToken.json @@ -226,4 +224,4 @@ fastlane/readme.md tmp # test -/__snapshots__/ \ No newline at end of file +/__snapshots__/ diff --git a/gatsby-node.js b/gatsby-node.js index da94457ba0..e5077b1595 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -8,7 +8,6 @@ const MiniCssExtractPlugin = require('mini-css-extract-plugin'); const path = require('path'); const fs = require('fs'); -const processGraphQLData = require('./search/generator'); const items = ['basic', 'chart']; const sha1 = require('sha1'); const hash = sha1(`${new Date().getTime()}${Math.random()}`); @@ -179,6 +178,7 @@ exports.onCreateWebpackConfig = ({ stage, rules, loaders, plugins, actions }) => }, plugins: [plugins.extractText(),plugins.define({ "THEME_SWITCHER_URL":JSON.stringify(process.env['THEME_SWITCHER_URL']), + "SEMI_SEARCH_URL":JSON.stringify(process.env['SEMI_SEARCH_URL']), "DSM_URL":JSON.stringify(process.env['DSM_URL']), 'process.env.SEMI_SITE_HEADER':JSON.stringify(process.env.SEMI_SITE_HEADER), 'process.env.SEMI_SITE_BANNER':JSON.stringify(process.env.SEMI_SITE_BANNER), @@ -232,35 +232,6 @@ exports.createPages = async ({ actions, graphql, reporter }) => { const blogPostTemplate = path.resolve('src/templates/postTemplate.js'); - // 开始处理搜索数据 - // console.log('building search data.'); - const searchData = await graphql(` - query MyQuery { - allMdx { - nodes { - id - fields { - slug - type - typeOrder - } - frontmatter { - brief - localeCode - title - } - tableOfContents - mdxAST - } - } - }`); - - // 在此你可以处理searchData(GraphQL查询的raw数据) 或者传入回调 处理运算后的数据 - processGraphQLData(searchData, processedData => {}); - // 搜索有用到,但是目前没有搜索,先注释掉,不然影响文档站的本地调试 - // fs.copyFileSync('./search/data_client.json', './static/search_data_client.json'); - // console.log('building search data success.') - // 搜索数据处理结束 const result = await graphql(` query { allMdx( diff --git a/search/generator.js b/search/generator.js deleted file mode 100644 index 984579956d..0000000000 --- a/search/generator.js +++ /dev/null @@ -1,225 +0,0 @@ -const fs = require("fs"); -// function decycle(object, replacer) { -// let objects = new WeakMap(); // object to path mappings -// return (function derez(value, path) { -// let old_path; // The path of an earlier occurance of value -// let nu; // The new object or array - -// if (replacer !== undefined) { -// value = replacer(value); -// } -// if (typeof value === "object" && value !== null && !(value instanceof Boolean) && !(value instanceof Date) && !(value instanceof Number) && !(value instanceof RegExp) && !(value instanceof String)) { -// old_path = objects.get(value); -// if (old_path !== undefined) { -// return { $ref: old_path }; -// } -// objects.set(value, path); -// if (Array.isArray(value)) { -// nu = []; -// value.forEach(function(element, i) { -// nu[i] = derez(element, path + "[" + i + "]"); -// }); -// } else { -// nu = {}; -// Object.keys(value).forEach(function(name) { -// nu[name] = derez(value[name], path + "[" + JSON.stringify(name) + "]"); -// }); -// } -// return nu; -// } -// return value; -// })(object, "$"); -// } - -// function retrocycle($) { -// let px = /^\$(?:\[(?:\d+|"(?:[^\\"\u0000-\u001f]|\\(?:[\\"\/bfnrt]|u[0-9a-zA-Z]{4}))*")\])*$/; -// (function rez(value) { -// if (value && typeof value === "object") { -// if (Array.isArray(value)) { -// value.forEach(function(element, i) { -// if (typeof element === "object" && element !== null) { -// let path = element.$ref; -// if (typeof path === "string" && px.test(path)) { -// value[i] = eval(path); -// } else { -// rez(element); -// } -// } -// }); -// } else { -// Object.keys(value).forEach(function(name) { -// let item = value[name]; -// if (typeof item === "object" && item !== null) { -// let path = item.$ref; -// if (typeof path === "string" && px.test(path)) { -// value[name] = eval(path); -// } else { -// rez(item); -// } -// } -// }); -// } -// } -// })($); -// return $; -// } -class SingleMdxProcessor { - constructor(mdxNode) { - this.belong=`component`; - this.mdxID = mdxNode.id; - this.slug = mdxNode.fields.slug; - this.headingContext=mdxNode.tableOfContents.items; - this.locale = this.slug.indexOf("en-US") === -1 ? "zh-CN" : "en-US"; - this.nodeMap={} - this.mdxInfo = { - slug: this.slug, - belong:this.belong, - brief: mdxNode.frontmatter.brief, - title: mdxNode.frontmatter.title, - folder:mdxNode.fields.type, - nodeUniqueIDList: [], - }; - this.closestAnchorAncestorUniqueID=null; - this.headingNodeMap={} - this.processChildNode(mdxNode.mdxAST,null,null); - this.processHeadingParent(); - - } - - getMdxInfo(){ - //暂时无用 删除以缩小文件体积 - delete this.mdxInfo['nodeUniqueIDList']; - return {mdxInfo:this.mdxInfo,locale:this.locale,nodeMap:this.nodeMap}; - } - - processHeadingParent(ancestor=null,items=this.headingContext){ - if(!items) - return; - for(let item of items){ - let headingNode=this.headingNodeMap[item.title]; - if(!headingNode) - continue; - headingNode.parent=ancestor?ancestor.uniqueID:null; - //使用 heading context 修正 anchor - headingNode.anchor=item.url?item.url:headingNode.value; - if(item.items){ - this.processHeadingParent(headingNode,item.items); - } - } - } - - - processChildNode(childNode, meaningfulType) { - const belong=this.belong; - const mdxID = this.mdxID; - const mdxInfo = this.mdxInfo; - const type=childNode.type; - const uniqueID = `${mdxID}#${type}#${Math.random()}`; - if (type === "heading") { - const value = childNode.children[0].value; - const anchor = '#'+value; - const node = { - uniqueID, - belong, - type, - value, - parent:null, - anchor, - mdxInfo, - meaningfulType: "heading", - }; - this.nodeMap[uniqueID] = node; - this.closestAnchorAncestorUniqueID=node.uniqueID; - this.mdxInfo.nodeUniqueIDList.push(uniqueID); - this.headingNodeMap[value]=node; - return; - } - if (type === "text") { - const value = childNode.value; - const node = { - uniqueID, - belong, - type, - value, - parent:this.closestAnchorAncestorUniqueID, - mdxInfo, - meaningfulType, - }; - this.nodeMap[uniqueID] = node; - this.mdxInfo.nodeUniqueIDList.push(uniqueID); - return; - } - if (type === "code" || type === "jsx") { - return; - const value = childNode.value; - const node = { - uniqueID, - belong, - type, - value, - parent:this.closestAnchorAncestorUniqueID, - mdxInfo, - meaningfulType: type, - }; - this.nodeMap[uniqueID] = node; - this.mdxInfo.nodeUniqueIDList.push(uniqueID); - return; - } - - - if (type === "list"||type==='listItem'||type==='root'||type==='strong') { - for (let child of childNode.children) { - this.processChildNode(child,type); - } - return; - } - - if (type === "paragraph" || type === "table" || type === "tableCell") { - for (let child of childNode.children) { - this.processChildNode(child, type === "paragraph" ? "paragraph" : "table"); - } - return; - } - } -} - -function processGraphQLData(rawGraphQLData,extraDataCallback) { - const {data}=rawGraphQLData; - // let data = null; - // try { - // data = JSON.parse(fs.readFileSync("search/data_graphQL.json")).data; - // if (!data) { - // console.error("FATAL ERROR: GraphQL data in empty. Data:", data); - // process.exit(1); - // } - // } catch (e) { - // console.error("FATAL ERROR: Run GraphQL for searching failed! Error message: " + e); - // process.exit(1); - // } - - let dataToClient = { - 'zh-CN': { mdxInfoList: [], nodeMap: {} }, - 'en-US': { mdxInfoList: [], nodeMap: {} }, - }; - const nodeArray = data.allMdx.nodes; - //开始解析mdxNode - nodeArray.map(mdxNode=>{ - const {mdxInfo,locale,nodeMap}=(new SingleMdxProcessor(mdxNode,dataToClient)).getMdxInfo(); - dataToClient[locale].mdxInfoList.push(mdxInfo); - Object.assign(dataToClient[locale].nodeMap,nodeMap); - }) - - //暂时无用 删除以缩小文件体积 - dataToClient['zh-CN'].mdxInfoList; - dataToClient['en-US'].mdxInfoList; - - extraDataCallback&&extraDataCallback(dataToClient); - try { - fs.writeFileSync("search/data_client.json",JSON.stringify(dataToClient)); - } catch (e) { - console.error("FATAL ERROR: Can not write search data to disk."); - process.exit(1); - } -} - -module.exports=processGraphQLData; diff --git a/search/searchDemo.js b/search/searchDemo.js deleted file mode 100644 index 164bd571f6..0000000000 --- a/search/searchDemo.js +++ /dev/null @@ -1,68 +0,0 @@ -const fs = require("fs"); -const readline = require("readline"); - -function search(str) { - const locale = "zh-CN"; - const { nodeMap, mdxInfoList } = JSON.parse(fs.readFileSync("data_client.json"))[locale]; - - //搜索正文 - const getContext = (node) => { - let context = []; - while (node.parent) { - context.push(nodeMap[node.parent].value); - node = nodeMap[node.parent]; - } - return context.reverse(); - }; - const resultNodeList = Object.entries(nodeMap) - .map(([_, value]) => value) - .filter((node) => { - if (node.type === "jsx") return false; - return node.value.indexOf(str) !== -1; - }); - - let resultList = []; - resultNodeList.map((node) => { - const result = { - text: node.value, - type: node.meaningfulType, - context: getContext(node).join(" => "), - url: "https://semi.design/design/" + node.mdxInfo.slug + (node.anchor ? node.anchor : nodeMap[node.parent].anchor), - }; - resultList.push(result); - }); - - //搜索mdx yaml (标题+brief) - const resultMdxInfoList = mdxInfoList.filter((mdxInfo) => mdxInfo.title.indexOf(str) !== -1 || (mdxInfo.brief&&mdxInfo.brief.indexOf(str) !== -1)); - resultList = resultList.concat( - resultMdxInfoList.map((mdxInfo) => { - const keyInTitleOrBrief = mdxInfo.title.indexOf(str) !== -1 ? "title" : "brief"; - return { - text: mdxInfo[keyInTitleOrBrief], - type: keyInTitleOrBrief, - url: "https://semi.design/design/" + mdxInfo.slug, - }; - }) - ); - return resultList; -} - -function readSyncByRl(tips) { - tips = tips || "> "; - - return new Promise((resolve) => { - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - }); - - rl.question(tips, (answer) => { - rl.close(); - resolve(answer.trim()); - }); - }); -} - -readSyncByRl("请输入搜索关键词:").then((res) => { - search(res); -}); diff --git a/src/components/SearchAllInOne/SearchModal/RecommendList/index.jsx b/src/components/SearchAllInOne/SearchModal/RecommendList/index.jsx deleted file mode 100644 index 36078049b8..0000000000 --- a/src/components/SearchAllInOne/SearchModal/RecommendList/index.jsx +++ /dev/null @@ -1,37 +0,0 @@ -import React from 'react'; -import styles from './index.module.scss'; -import { Icon } from '@douyinfe/semi-ui'; -import { FormattedMessage } from 'react-intl'; -import cls from 'classnames'; - -const RecommendItem = ({ img, title, url, content, disable = false }) => ( - -
- -
-
-
{title}
-
{content}
-
-
-); - -export default props => { - const { recommendItemList } = props; - - return ( -
-
- -
-
- {recommendItemList.map(item => )} -
-
- ); -}; diff --git a/src/components/SearchAllInOne/SearchModal/RecommendList/index.module.scss b/src/components/SearchAllInOne/SearchModal/RecommendList/index.module.scss deleted file mode 100644 index d42ec69dbf..0000000000 --- a/src/components/SearchAllInOne/SearchModal/RecommendList/index.module.scss +++ /dev/null @@ -1,69 +0,0 @@ -.recommendList { - display: flex; - flex-wrap: wrap; - justify-content: space-between; -} -.msg { - font-family: PingFang SC; - margin: 12px 0 0px 0; - font-style: normal; - font-weight: 600; - font-size: 14px; - line-height: 20px; - position: relative; - left: 16px; - color: var(--semi-color-text-0); -} -.item-disable{ - filter: grayscale(100%); - &:hover{ - cursor: default !important; - background-color:rgba(0,0,0,0) !important; - } -} -.recommendItem { - display: flex; - width: 260px; - align-items: center; - margin: 6px 0 20px 0; - color: var(--semi-color-text-0); - padding: 16px; - border-radius: 6px; - &:hover { - text-decoration: none; - color: var(--semi-color-text-0); - background-color: var(--semi-color-default); - } - .imgWrapper { - box-sizing: border-box; - max-width: 30%; - height: 60px; - margin-right: 16px; - } - .detail { - .title { - font-family: PingFang SC; - font-size: 18px; - font-style: normal; - font-weight: 400; - line-height: 24px; - letter-spacing: 0em; - text-align: left; - margin-bottom: 7px; - } - .content { - flex: 1; - display: block; - font-family: PingFang SC; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 18px; - letter-spacing: 0em; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - color: var(--semi-color-disabled-text); - } - } -} diff --git a/src/components/SearchAllInOne/SearchModal/ResultList/index.jsx b/src/components/SearchAllInOne/SearchModal/ResultList/index.jsx deleted file mode 100644 index 151b3a55ae..0000000000 --- a/src/components/SearchAllInOne/SearchModal/ResultList/index.jsx +++ /dev/null @@ -1,174 +0,0 @@ -/* argus-disable dangerMethod */ -/* eslint-disable max-lines-per-function */ -import React, { isValidElement, useRef, useEffect, useState } from 'react'; -import styles from './index.module.scss'; -import { Icon, List, Empty } from '@douyinfe/semi-ui'; -import { IllustrationNoResult } from '@douyinfe/semi-illustrations'; -import _ from 'lodash-es'; -import cls from 'classnames'; -import { useIntl } from 'react-intl'; -import { makeAnchorId } from 'utils/index'; -import * as commonUtils from '../../common'; - -const isResultInThisPage = resultUrl => { - if (!process.browser) { - return false; - } - - return location.pathname === resultUrl.split('#')[0]; -}; - -export default props => { - const intl = useIntl(); - const { searchResult, keyword } = props; - const makeItHighlight = words => { - - const reg = new RegExp(`(${_.escapeRegExp(keyword)})`, 'i'); - const result = words.replace(reg, p1 => ` - ${p1} - `); - - return ; - }; - const ref = useRef({ endIndexCache: 0, currentSelectedIndexCache: 0 }); - const [endIndex, setEndIndex] = useState(10); - - const pagedSearchResult = searchResult.slice(0, endIndex <= searchResult.length ? endIndex : searchResult.length); - useEffect(() => { - const scrollEle = document.querySelector(`.${ styles.list}`); - const scrollEventListener = _.throttle(event => { - if (commonUtils.isScrollContainerScrollToEnd(scrollEle, 500)) { - setEndIndex(ref.current.endIndexCache + 10); - ref.current.endIndexCache += 10; - } - }, 500); - scrollEle.addEventListener('scroll', scrollEventListener); - return () => { - scrollEle.removeEventListener('scroll', scrollEventListener); - }; - }, []); - - const [currentSelectedIndex, setCurrentSelectedIndex] = useState(0); - - useEffect(() => { - const upDownBtnOnPressListener = keyEvent => { - let targetIndex; - if (keyEvent.code === 'ArrowDown') { - targetIndex = ref.current.currentSelectedIndexCache + 1; - if (targetIndex > searchResult.length) { - targetIndex = 0; - } - } else if (keyEvent.code === 'ArrowUp') { - targetIndex = ref.current.currentSelectedIndexCache - 1; - if (targetIndex < 0) { - targetIndex = 0; - } - } else { - if (keyEvent.code === 'Enter' && searchResult.length > 0) { - window.open(searchResult[ref.current.currentSelectedIndexCache].url); - } - return; - } - setTimeout(() => { - setCurrentSelectedIndex(targetIndex); - ref.current.currentSelectedIndexCache = targetIndex; - - - const currentSelectedDom = document.querySelector(`#searchResult-${targetIndex}`); - const scrollViewContainer = document.querySelector(`.${ styles.list}`); - const position = commonUtils.isDomVisibleInScrollView(currentSelectedDom, scrollViewContainer); - if (position > 0) { - scrollViewContainer.scrollTop = scrollViewContainer.scrollTop + currentSelectedDom.clientHeight; - } else if (position < 0) { - scrollViewContainer.scrollTop = scrollViewContainer.scrollTop - currentSelectedDom.clientHeight; - } - }, 0); - }; - document.addEventListener('keydown', upDownBtnOnPressListener); - - return () => document.removeEventListener('keydown', upDownBtnOnPressListener); - }, [searchResult]); - - return ( -
- } description={'角度过于刁钻,未找到结果'} />} - className={styles.list} - dataSource={pagedSearchResult} - renderItem={(item, index) => { - const classname = {}; - classname[styles.resultItem] = true; - classname[styles.hovered] = index === currentSelectedIndex; - let iconType = 'search-text'; - switch (item.belong) { - case 'component': - iconType = 'search-text'; - break; - case 'material': - iconType = 'search-material'; - break; - default: - break; - } - - return ( - - { - if (!isResultInThisPage(item.url)) { - return; - } - let hash = item.url.split('#')[1]; - hash = decodeURI(hash); - const safeHash = makeAnchorId(hash); - const resultDom = document.querySelector(`#${safeHash}`); - window.hideSearch(); - if (resultDom) { - resultDom.scrollIntoView(); - } - e.preventDefault(); - e.stopPropagation(); - }} - onMouseEnter={() => { - setCurrentSelectedIndex(index); - ref.current.currentSelectedIndexCache = index; - }} - > -
- -
-
-
- {item.title.length !== 0 - ? item.title - : isValidElement(item.context) - ? item.context - : makeItHighlight(item.context)} -
-
-
{intl.formatMessage({ id: `search.belong.${item.belong}` })}
-
- {isValidElement(item.context) - ? item.context - : makeItHighlight(item.context)} -
-
-
-
-
- ); - }} - /> -
- ); -}; diff --git a/src/components/SearchAllInOne/SearchModal/ResultList/index.module.scss b/src/components/SearchAllInOne/SearchModal/ResultList/index.module.scss deleted file mode 100644 index 21434afcd7..0000000000 --- a/src/components/SearchAllInOne/SearchModal/ResultList/index.module.scss +++ /dev/null @@ -1,105 +0,0 @@ -.highlight { - color: rgba(var(--semi-blue-5), 1); -} - -.results { - width: 640px; - padding-bottom: 24px; - .hovered { - background-color: rgba(var(--semi-grey-0), 1); - } - .resultItem { - box-sizing: border-box; - display: block; - text-decoration: none; - color: black; - &:visited &:hover &:active { - text-decoration: none; - } - - height: 92px; - display: flex; - padding: 16px; - border-radius: 6px; - .imgWrapper { - box-sizing: border-box; - width: 88px; - height: 60px; - margin-right: 16px; - } - .info { - box-sizing: border-box; - width: 490px; - .title { - font-family: system, -apple-system, BlinkMacSystemFont, PingFang SC, Segoe UI, Microsoft YaHei, - wenquanyi micro hei, Hiragino Sans GB, Hiragino Sans GB W3, Roboto, Oxygen, Ubuntu, Cantarell, - Fira Sans, Droid Sans, Helvetica Neue, Helvetica, Arial, sans-serif; - font-size: 18px; - font-style: normal; - font-weight: 400; - line-height: 24px; - letter-spacing: 0em; - text-align: left; - margin-bottom: 7px; - } - .content { - display: flex; - .type { - display: block; - width: fit-content; - border-right: 1px solid rgba(var(--semi-grey-1), 1); - padding-right: 12px; - margin-right: 12px; - } - .context { - flex: 1; - display: block; - font-family: system, -apple-system, BlinkMacSystemFont, PingFang SC, Segoe UI, Microsoft YaHei, - wenquanyi micro hei, Hiragino Sans GB, Hiragino Sans GB W3, Roboto, Oxygen, Ubuntu, Cantarell, - Fira Sans, Droid Sans, Helvetica Neue, Helvetica, Arial, sans-serif; - font-size: 14px; - font-style: normal; - font-weight: 400; - line-height: 18px; - letter-spacing: 0em; - white-space: nowrap; - text-overflow: ellipsis; - overflow: hidden; - color: var(--semi-color-disabled-text); - } - } - } - } -} - -.list { - height: 550px; - overflow-y: auto; - overflow-x: hidden; - &::-webkit-scrollbar { - width: 8px; - height: 8px; - } - - &::-webkit-scrollbar-track { - background: rgba(0, 0, 0, 0); - } - - &::-webkit-scrollbar-corner { - background-color: rgba(0, 0, 0, 0); - } - - &::-webkit-scrollbar-thumb { - border-radius: 6px; - background: transparent; - transition: all 1s; - } - - &:hover::-webkit-scrollbar-thumb { - background: var(--semi-color-fill-2); - } - - &::-webkit-scrollbar-thumb:hover { - background: var(--semi-color-fill-1); - } -} diff --git a/src/components/SearchAllInOne/SearchModal/index.interface.ts b/src/components/SearchAllInOne/SearchModal/index.interface.ts deleted file mode 100644 index 89f22c73ad..0000000000 --- a/src/components/SearchAllInOne/SearchModal/index.interface.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ReactElement } from "react"; - -export interface resultItemInterface { - img?: string | ReactElement; - title: string | ReactElement | string[]; - type: string | ReactElement; - context: string | ReactElement | string[] - url: string; -} -export interface recommendItemInterface { - img: string | ReactElement, - title: string | ReactElement, - content: string | ReactElement - url: string -} -export interface mdxInfoInterface { - "slug": string, - "title": string, - "brief"?: string, - folder?: string -} - -export interface nodeInterface { - "uniqueID": string, - "type": 'heading' | 'text' | 'code' | 'jsx' | 'list' | 'listItem' | 'root' | 'strong' | 'paragraph' | 'table' | 'tableCell', - "value": string, - "parent": string | null, - "anchor": string, - "mdxInfo": mdxInfoInterface, - "meaningfulType": 'heading' | 'code' | 'jsx' | 'list' | 'listItem' | 'root' | 'strong' | 'paragraph' | 'table' -} -export interface searchDataInterface { - 'zh-CN'?: { - mdxInfoList: mdxInfoInterface[], - nodeMap: { - [propName: string]: nodeInterface - } - }, - 'en-US'?: { - mdxInfoList: mdxInfoInterface[], - nodeMap: { - [propName: string]: nodeInterface - } - } -} -export interface searchFuncResultItemInterface { - text: string; - type: 'heading' | 'code' | 'jsx' | 'list' | 'listItem' | 'root' | 'strong' | 'paragraph' | 'table' | 'brief' | 'title'; - url: string; - mdxInfo: mdxInfoInterface - context?: string[] -} - - diff --git a/src/components/SearchAllInOne/SearchModal/index.jsx b/src/components/SearchAllInOne/SearchModal/index.jsx deleted file mode 100644 index 578ae8143d..0000000000 --- a/src/components/SearchAllInOne/SearchModal/index.jsx +++ /dev/null @@ -1,179 +0,0 @@ -import React from 'react'; -import { withPrefix } from 'gatsby'; -import axios from 'axios'; -import { Modal, Input } from '@douyinfe/semi-ui'; -import _ from 'lodash-es'; -import { _t } from 'utils/locale'; -import searchFunc from '../search'; -import searchMateral from '../additionSearch'; -import RecommendList from './RecommendList'; -import ResultList from './ResultList'; -import styles from './index.module.scss'; -class SearchModal extends React.Component { - constructor(props) { - super(props); - this.state = { - userInput: '', - searchResult: [], - searchVisible: false, - }; - - this.locale = props.intl.locale; - this.recommendList = props.recommendList; - this.data = null; - this.search = _.debounce(this.search, 300); - this.standBy = () => {}; - _.bindAll(this, [ - 'init', - 'getSearchJSON', - 'search', - 'showSearch', - 'hideSearch', - 'onUserInputChange', - 'transResult', - ]); - this.init(); - } - - async init() { - await this.getSearchJSON(); - } - componentDidMount() { - window.showSearch = () => this.showSearch(); - window.hideSearch = () => this.hideSearch(); - } - formatMessage(id) { - return this.props.intl.formatMessage({ id }); - } - - async getSearchJSON() { - await axios(withPrefix('/search_data_client.json')) - .then(res => { - this.data = res.data; - }) - .then(() => { - this.standBy(); - }); - } - - async search(value) { - - - if (!this.data) { - this.standBy = () => this.search(value); - return; - } - - let searchFuncResult = searchFunc(value, this.data, this.props.intl.locale); - - let searchResult = this.transResult(searchFuncResult); - const materialSearchResult = await searchMateral(value, this.locale); - let i; - if (_.get(searchResult[0], 'type', false) !== this.formatMessage('search.type.heading')) { - i = -1; - } else { - i = 1; - while (_.get(searchResult[i], 'type', false) === this.formatMessage('search.type.heading')) { - i++; - } - i--; - } - searchResult = searchResult - .slice(0, i + 1) - .concat(materialSearchResult) - .concat(searchResult.slice(i + 1)); - - - this.setState({ searchResult }); - } - - transResult(result) { - const resultList = []; - - result.map(item => { - if (item.type === 'brief') { - resultList.push({ - title: [item.mdxInfo.folder, item.mdxInfo.title, this.formatMessage('search.type.brief')], - url: item.url, - belong: item.belong, - type: _t('search.type.brief'), - context: item.text, - }); - } else if (item.type === 'title') { - resultList.push({ - title: [item.mdxInfo.folder, item.mdxInfo.title, item.text], - url: item.url, - belong: item.belong, - type: this.formatMessage('search.type.heading'), - context: item.text, - }); - } else { - resultList.push({ - title: item.context, - url: item.url, - belong: item.belong, - type: this.formatMessage(`search.type.${item.type}`), - context: item.text, - }); - } - }); - return resultList; - } - - showSearch() { - this.setState({ searchVisible: true, userInput: '', searchResult: [] }); - setTimeout(() => { - this.inputRef && this.inputRef.focus(); - }, 0); - } - - hideSearch() { - this.setState({ searchVisible: false, userInput: '', searchResult: [] }); - } - - onUserInputChange(value) { - this.setState({ userInput: value }); - if (value !== '') { - this.search(value); - } else { - this.setState({ searchResult: [] }); - } - } - - render() { - const { userInput, searchVisible, searchResult } = this.state; - const header = ( -
- (this.inputRef = _)} - value={userInput} - placeholder={this.formatMessage('search.input.placeholder')} - onChange={this.onUserInputChange} - showClear - /> -
- ); - return ( -
- this.hideSearch()} - > - {userInput.length === 0 ? ( - - ) : ( - - )} - -
- ); - } -} - -export default SearchModal; diff --git a/src/components/SearchAllInOne/SearchModal/index.module.scss b/src/components/SearchAllInOne/SearchModal/index.module.scss deleted file mode 100644 index 2ee4535d67..0000000000 --- a/src/components/SearchAllInOne/SearchModal/index.module.scss +++ /dev/null @@ -1,7 +0,0 @@ -.searchWrapper{ - display: block; -} -.inputWrapper{ - margin: 24px 0 12px 0; - -} \ No newline at end of file diff --git a/src/components/SearchAllInOne/additionSearch.js b/src/components/SearchAllInOne/additionSearch.js deleted file mode 100644 index f2490ea8e0..0000000000 --- a/src/components/SearchAllInOne/additionSearch.js +++ /dev/null @@ -1,41 +0,0 @@ -import axios from 'axios'; - -export default async function searchMaterial(keyword, localeCode = 'zh-CN') { - const extractMaterialInfo = materialData => { - const { title, category, id } = materialData; - return { - belong: 'material', - title: [title], - context: localeCode === 'zh-CN' ? category.text : category.text_en_US, - type: 'material', - url: `https://semi.design/material/${localeCode}/detail/${id}`, - }; - }; - - const searchUrl = 'https://semi.design/api/material/search'; - let materialList = []; - try { - materialList = ( - await axios.get(searchUrl, { - timeout: 1000, - params: { - pageSize: 999, - pageNum: 1, - needDetail: 1, - type: 1, - isPublic: 1, - isDraft: 0, - orderBy: 'stars', - orderDir: -1, - needLikes: true, - query: keyword, - search: true, - }, - }) - ).data.data.list; - } catch (e) { - console.log(e); - } - const materialResult = materialList.map(material => extractMaterialInfo(material)); - return materialResult; -} diff --git a/src/components/SearchAllInOne/common.js b/src/components/SearchAllInOne/common.js deleted file mode 100644 index 39b1f110f7..0000000000 --- a/src/components/SearchAllInOne/common.js +++ /dev/null @@ -1,22 +0,0 @@ -export const isScrollContainerScrollToEnd = (scrollContainer, offset = 0) => { - if (!scrollContainer) { - return; - } - return scrollContainer.scrollHeight - (scrollContainer.scrollTop + scrollContainer.offsetHeight) < offset; -}; - -export const isDomVisibleInScrollView = (ele, scrollContainer, offset = 0) => { - if (!(ele && scrollContainer)) { - return; - } - if (ele.offsetTop < scrollContainer.scrollTop) { - return -1; - } - if (ele.offsetTop > scrollContainer.scrollTop && ele.offsetTop < scrollContainer.scrollTop + scrollContainer.clientHeight) { - return 0; - } - if (ele.offsetTop > scrollContainer.scrollTop + scrollContainer.clientHeight) { - return 1; - } -}; - diff --git a/src/components/SearchAllInOne/index.jsx b/src/components/SearchAllInOne/index.jsx deleted file mode 100644 index 3077afc9bf..0000000000 --- a/src/components/SearchAllInOne/index.jsx +++ /dev/null @@ -1,65 +0,0 @@ -import React from 'react'; -import { useIntl } from 'react-intl'; - -import SearchModal from './SearchModal'; -import { recommendItemInterface } from './SearchModal/index.interface'; -export default () => { - const intl = useIntl(); - const recommendList = [ - { - img: 'search-start', - title: intl.locale === 'en-US' ? 'Quick Start' : '快速开始', - content: intl.locale === 'en-US' ? 'Component' : '组件', - url: - intl.locale === 'en-US' - ? 'https://semi.design/en-US/start/getting-started' - : 'https://semi.design/zh-CN/start/getting-started', - }, - { - img: 'search-form', - title: intl.locale === 'en-US' ? 'Form' : '表单', - content: intl.locale === 'en-US' ? 'Component' : '组件', - url: - intl.locale === 'en-US' - ? 'https://semi.design/en-US/components/form' - : 'https://semi.design/zh-CN/components/form', - }, - { - img: 'search-table', - title: intl.locale === 'en-US' ? 'Table' : '表格', - content: intl.locale === 'en-US' ? 'Component' : '组件', - url: - intl.locale === 'en-US' - ? 'https://semi.design/en-US/components/table' - : 'https://semi.design/zh-CN/components/table', - }, - { - img: 'search-site', - title: intl.locale === 'en-US' ? 'Semi Material Market' : 'Semi 物料市场', - disable: false, - content: intl.locale === 'en-US' ? 'Site' : '站点', - url: 'https://semi.design/material', - }, - { - img: 'search-design', - title: intl.locale === 'en-US' ? 'Design Language' : '了解设计语言', - disable: true, - content: intl.locale === 'en-US' ? 'Design' : '设计规范', - url: - intl.locale === 'en-US' - ? 'https://semi.design/design/en-US/handbook/intro' - : 'https://semi.design/design/zh-CN/handbook/intro', - }, - { - img: 'search-icon', - title: intl.locale === 'en-US' ? 'Icon' : '图标', - content: intl.locale === 'en-US' ? 'Component' : '组件', - url: - intl.locale === 'en-US' - ? 'https://semi.design/en-US/basic/icon' - : 'https://semi.design/zh-CN/basic/icon', - }, - ]; - - return ; -}; diff --git a/src/components/SearchAllInOne/search.ts b/src/components/SearchAllInOne/search.ts deleted file mode 100644 index cc00c31cad..0000000000 --- a/src/components/SearchAllInOne/search.ts +++ /dev/null @@ -1,70 +0,0 @@ -import { withPrefix } from 'gatsby' -import { searchFuncResultItemInterface } from './index.interface'; -import lodash from 'lodash-es'; - -export default function search(str,data,locale) { - const { nodeMap, mdxInfoList } = data[locale]; - //搜索正文 - const getContext = (node) => { - const context = []; - while (node.parent) { - context.push(nodeMap[node.parent].value); - node = nodeMap[node.parent]; - } - return context.reverse(); - }; - const calcHashViaAnchor=(anchor)=>{ - return '#'+encodeURI(anchor[0]==='#'?anchor.slice(1):anchor); - } - const typeCollection=['heading','text','code','jsx','list','listItem','root','strong','paragraph','table','tableCell']; - const resultNodeListSortedByType={}; - //按照类型排序 - Object.entries(nodeMap) - .map(([_, value]) => value) - .filter((node) => { - if (node.type === "jsx") return false; - return new RegExp(`${lodash.escapeRegExp(str)}`,'i').test(node.value); - }).map((item)=>{ - if(!resultNodeListSortedByType[item.type]){ - resultNodeListSortedByType[item.type]=[]; - } - resultNodeListSortedByType[item.type].push(item); - }); - let resultNodeList=[]; - typeCollection.map((type)=>{ - resultNodeListSortedByType[type]&&(resultNodeList=resultNodeList.concat(resultNodeListSortedByType[type])); - }) - - let resultList = []; - resultNodeList.map((node) => { - const result:searchFuncResultItemInterface = { - text: node.value, - type: node.meaningfulType, - belong:node.belong, - context: getContext(node), - url: withPrefix(node.mdxInfo.slug + (node.anchor ?calcHashViaAnchor(node.anchor) : (node.parent?calcHashViaAnchor(nodeMap[node.parent].anchor):''))), - mdxInfo:node.mdxInfo, - }; - resultList.push(result); - }); - - //搜索mdx yaml (标题+brief) - const resultMdxInfoList = mdxInfoList.filter((mdxInfo) => (new RegExp(`${lodash.escapeRegExp(str)}`,'i').test(mdxInfo.title) ) || (new RegExp(`${lodash.escapeRegExp(str)}`,'i').test(mdxInfo.brief&&mdxInfo.brief))); - resultList = resultList.concat( - resultMdxInfoList.map((mdxInfo) => { - const keyInTitleOrBrief = new RegExp(`${lodash.escapeRegExp(str)}`,'i').test(mdxInfo.title) ? 'title' : 'brief'; - - - return { - text: mdxInfo[keyInTitleOrBrief], - type: keyInTitleOrBrief, - belong:mdxInfo['belong'], - url: withPrefix(mdxInfo.slug), - mdxInfo - }; - }) - ); - - - return resultList; -} diff --git a/src/html.js b/src/html.js index 58dc19abe3..73321e7e4c 100644 --- a/src/html.js +++ b/src/html.js @@ -159,6 +159,9 @@ export default function HTML(props) { { THEME_SWITCHER_URL?