Browse Source

chore: add search

DaiQiangReal 3 years ago
parent
commit
21329c825c

+ 1 - 3
.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__/
+/__snapshots__/

+ 1 - 30
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(

+ 0 - 225
search/generator.js

@@ -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;

+ 0 - 68
search/searchDemo.js

@@ -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);
-});

+ 0 - 37
src/components/SearchAllInOne/SearchModal/RecommendList/index.jsx

@@ -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 }) => (
-    <a
-        className={cls(styles.recommendItem, { [styles['item-disable']]: disable })}
-        href={disable ? null : url}
-        target={'_blank'}
-        rel="noreferrer"
-    >
-        <div className={styles.imgWrapper}>
-            <Icon type={img} size={'extra-large'} style={{ display: 'block', width: '100%', height: '100%' }} />
-        </div>
-        <div className={styles.detail}>
-            <div className={styles.title}>{title}</div>
-            <div className={styles.content}>{content}</div>
-        </div>
-    </a>
-);
-
-export default props => {
-    const { recommendItemList } = props;
-
-    return (
-        <div>
-            <div className={styles.msg}>
-                <FormattedMessage id={'search.msg.peopleSearch'} />
-            </div>
-            <div className={styles.recommendList}>
-                {recommendItemList.map(item => <RecommendItem {...item} key={item.url} />)}
-            </div>
-        </div>
-    );
-};

+ 0 - 69
src/components/SearchAllInOne/SearchModal/RecommendList/index.module.scss

@@ -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);
-        }
-    }
-}

+ 0 - 174
src/components/SearchAllInOne/SearchModal/ResultList/index.jsx

@@ -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 => `<span class=${styles.highlight}>
-                             ${p1}
-                         </span>`);
-
-        return <span dangerouslySetInnerHTML={{ __html: result }} />;
-    };
-    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 (
-        <div className={styles.results}>
-            <List
-                split={false}
-                emptyContent={<Empty image={<IllustrationNoResult />} 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 (
-                        <List.Item style={{ padding: '0px' }}>
-                            <a
-                                className={cls(classname)}
-                                id={`searchResult-${index}`}
-                                href={item.url}
-                                target={'_blank'}
-                                rel="noreferrer"
-                                onClick={e => {
-                                    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;
-                                }}
-                            >
-                                <div className={styles.imgWrapper}>
-                                    <Icon
-                                        type={iconType}
-                                        size={'extra-large'}
-                                        style={{ display: 'block', width: '100%', height: '100%' }}
-                                    />
-                                </div>
-                                <div className={styles.info}>
-                                    <div className={styles.title}>
-                                        {item.title.length !== 0
-                                            ? item.title
-                                            : isValidElement(item.context)
-                                                ? item.context
-                                                : makeItHighlight(item.context)}
-                                    </div>
-                                    <div className={styles.content}>
-                                        <div className={styles.type}>{intl.formatMessage({ id: `search.belong.${item.belong}` })}</div>
-                                        <div className={styles.context}>
-                                            {isValidElement(item.context)
-                                                ? item.context
-                                                : makeItHighlight(item.context)}
-                                        </div>
-                                    </div>
-                                </div>
-                            </a>
-                        </List.Item>
-                    );
-                }}
-            />
-        </div>
-    );
-};

+ 0 - 105
src/components/SearchAllInOne/SearchModal/ResultList/index.module.scss

@@ -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);
-    }
-}

+ 0 - 54
src/components/SearchAllInOne/SearchModal/index.interface.ts

@@ -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[]
-}
-
-

+ 0 - 179
src/components/SearchAllInOne/SearchModal/index.jsx

@@ -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 = (
-            <div className={styles.inputWrapper}>
-                <Input
-                    ref={_ => (this.inputRef = _)}
-                    value={userInput}
-                    placeholder={this.formatMessage('search.input.placeholder')}
-                    onChange={this.onUserInputChange}
-                    showClear
-                />
-            </div>
-        );
-        return (
-            <div className={styles.searchWrapper}>
-                <Modal
-                    width={688}
-                    visible={searchVisible}
-                    footer={null}
-                    header={header}
-                    maskClosable={true}
-                    closeOnEsc={true}
-                    style={{ top: 40 }}
-                    onCancel={() => this.hideSearch()}
-                >
-                    {userInput.length === 0 ? (
-                        <RecommendList recommendItemList={this.recommendList} />
-                    ) : (
-                        <ResultList searchResult={searchResult} keyword={userInput} />
-                    )}
-                </Modal>
-            </div>
-        );
-    }
-}
-
-export default SearchModal;

+ 0 - 7
src/components/SearchAllInOne/SearchModal/index.module.scss

@@ -1,7 +0,0 @@
-.searchWrapper{
-    display: block;
-}
-.inputWrapper{
-    margin: 24px 0 12px 0;
-
-}

+ 0 - 41
src/components/SearchAllInOne/additionSearch.js

@@ -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;
-}

+ 0 - 22
src/components/SearchAllInOne/common.js

@@ -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;
-    }
-};
-

+ 0 - 65
src/components/SearchAllInOne/index.jsx

@@ -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 <SearchModal key={Math.random()} recommendList={recommendList} intl={intl} />;
-};

+ 0 - 70
src/components/SearchAllInOne/search.ts

@@ -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;
-}

+ 3 - 0
src/html.js

@@ -159,6 +159,9 @@ export default function HTML(props) {
                 {
                     THEME_SWITCHER_URL?<script src={THEME_SWITCHER_URL} defer={true}/>:<script src="https://unpkg.byted-static.com/latest/ies/semi-theme-switcher-opensource/dist/semi-theme-switcher.js" defer={true}/>
                 }
+                {
+                    SEMI_SEARCH_URL?<script src={SEMI_SEARCH_URL} defer={true}/>:<script defer={true}/>
+                }
                 <link rel="icon" href="https://lf9-static.semi.design/obj/semi-tos/images/favicon.ico" />
                 <script dangerouslySetInnerHTML={{ __html: `(${darkmodeProcesser.toString()})()` }} />
                 {props.headComponents}