Jelajahi Sumber

Merge branch 'main' into release

pointhalo 3 tahun lalu
induk
melakukan
20af0a4356

+ 2 - 2
.vscode/settings.json

@@ -17,7 +17,7 @@
         "editor.defaultFormatter": "michelemelluso.code-beautifier"
     },
     "[typescriptreact]": {
-        "editor.defaultFormatter": "dbaeumer.vscode-eslint"
+        "editor.defaultFormatter": "vscode.typescript-language-features"
     },
     "typescript.updateImportsOnFileMove.enabled": "always",
     "files.autoSave": "onFocusChange",
@@ -44,4 +44,4 @@
         "backtop",
         "Splited"
     ]
-}
+}

+ 5 - 1
content/basic/tokens/index-en-US.md

@@ -197,6 +197,10 @@ It is used to describe the sequence of interface elements
 
 <DesignToken componentName='global' reg={/z-/}/>
 
+## Animation
+
+<DesignToken componentName="global" isAnimation={true} />
+
 ## Variables not yet supported
 
 Currently, Semi does not support global variables in the following categories. If you have related requirements, you can give feedback through issue and describe your expected needs in detail.
@@ -210,4 +214,4 @@ Currently, Semi does not support global variables in the following categories. I
 **Media query**
 
 ## Customization
-If you need to customize the global variable style, please go to [Semi DSM](https://semi.design/dsm), make your own theme and publish it
+If you need to customize the global variable style, please go to [Semi DSM](https://semi.design/dsm), make your own theme and publish it

+ 4 - 1
content/basic/tokens/index.md

@@ -201,6 +201,10 @@ brief: Semi Design Tokens
 
 <DesignToken componentName='global' reg={/z-/}/>
 
+## 动画
+
+<DesignToken componentName="global" isAnimation={true} />
+
 ## 尚未支持的变量
 目前,Semi 尚未支持以下类别的全局变量,如果你有相关需求,可以通过issue进行反馈,详细描述你的预期需求,我们会在评估后进行处理
 
@@ -208,7 +212,6 @@ brief: Semi Design Tokens
 
 **字间距 letter spacing**
 
-**时长 duration**
 
 **媒体查询 media query**
 

+ 1 - 0
gatsby-node.js

@@ -182,6 +182,7 @@ exports.onCreateWebpackConfig = ({ stage, rules, loaders, plugins, actions }) =>
             "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),
+            'process.env.D2C_URL': JSON.stringify(process.env.D2C_URL),
         })],
     });
 };

+ 2 - 1
packages/semi-foundation/tagInput/tagInput.scss

@@ -13,7 +13,7 @@ $module: #{$prefix}-tagInput;
     width: 100%;
     box-sizing: border-box;
     transition: background-color $transition_duration-tagInput-bg $transition_function-tagInput-bg $transition_delay-tagInput-bg,
-    border $transition_duration-tagInput-border $transition_function-tagInput-border $transition_delay-tagInput-border;
+        border $transition_duration-tagInput-border $transition_function-tagInput-border $transition_delay-tagInput-border;
 
     &-drag {
 
@@ -23,6 +23,7 @@ $module: #{$prefix}-tagInput;
         }
 
         &-handler {
+            color: $color-tagInput_handler-icon-default;
             margin-right: $spacing-tagInput_drag_handler-marginRight;
             cursor: move;
         }

+ 2 - 0
packages/semi-foundation/tagInput/variables.scss

@@ -28,6 +28,8 @@ $color-tagInput_danger-border-hover: var(--semi-color-danger-light-hover); // 
 $color-tagInput_danger-bg-focus: var(--semi-color-danger-light-default); // 危险标签输入框背景颜色 - 选中
 $color-tagInput_danger-border-focus: var(--semi-color-danger); // 危险标签输入框描边颜色 - 选中
 
+$color-tagInput_handler-icon-default: var(--semi-color-text-2); // 可拖拽的标签拖拽按钮颜色
+
 $spacing-tagInput_small-Y: 1px; // 小尺寸标签输入框标签顶部外边距
 $spacing-tagInput_default-Y: $spacing-super-tight; // 默认尺寸标签输入框标签顶部外边距
 $spacing-tagInput_large-Y: 3px; // 大尺寸标签输入框标签顶部外边距

+ 28 - 4
scripts/designToken.js

@@ -1,12 +1,13 @@
 const fs = require('fs');
 const path = require('path');
 const lodash = require('lodash');
+const { merge } = require("lodash");
 
 
 const isComment = codeLine => lodash.startsWith(codeLine, '//') || lodash.startsWith(codeLine, '/*');
 const getTokenCategory = codeLine => {
-    const categorySet = new Set(['color', 'width', 'height', 'spacing', 'radius', 'font', 'motion']);
-    const firstWord = lodash.get(codeLine.match(/\$([\w\W]+?)-/), 1, { toLowerCase: () => null }).toLowerCase();
+    const categorySet = new Set(['color', 'width', 'height', 'spacing', 'radius', 'font', 'motion', "animation", "transition"]);
+    const firstWord = lodash.get(codeLine.match(/\$([\w\W]+?)[-_]/), 1, { toLowerCase: () => null }).toLowerCase();
     if (firstWord) {
         return categorySet.has(firstWord) ? firstWord : 'other';
     } else {
@@ -15,12 +16,17 @@ const getTokenCategory = codeLine => {
 };
 const codeLineSplit = codeLine => {
     const [key, value, comment] = codeLine.split(/:|\/\/|\/\*/).map(code => code.trim()).filter(code => code);
-    return { key, value: lodash.trimEnd(value, ';'), comment:comment && comment.replace("ignore-semi-css-trans", ""), category: getTokenCategory(codeLine), raw: codeLine };
+    let category = getTokenCategory(codeLine);
+    if (category==='transition'){
+        category = "animation";
+    }
+    return { key, value: lodash.trimEnd(value, ';'), comment:comment && comment.replace("ignore-semi-css-trans", ""), category: category, raw: codeLine };
 };
 
 const getGlobalDesignToken = () => {
     const globalScssContentArray = fs.readFileSync(path.join(__dirname, '../packages/semi-theme-default/scss/global.scss'), { encoding: 'utf-8' }).split('\n');
     const paletteScssContentArray = fs.readFileSync(path.join(__dirname, '../packages/semi-theme-default/scss/_palette.scss'), { encoding: 'utf-8' }).split('\n');
+    const animationScssContentArray = fs.readFileSync(path.join(__dirname, '../packages/semi-theme-default/scss/animation.scss'), { encoding: 'utf-8' }).split('\n');
     const normalContentArray = fs.readFileSync(path.join(__dirname, '../packages/semi-theme-default/scss/variables.scss'), { encoding: 'utf-8' }).split('\n');
     const getLightAndDarkScss = scssFileContentArray => {
         const contentArray = scssFileContentArray.map(codeLine => codeLine.trim())
@@ -79,12 +85,23 @@ const getGlobalDesignToken = () => {
     const normalContent = normalContentArray.map(codeLine => codeLine.trim())
         .filter(codeLine => codeLine && !isComment(codeLine))
         .map(codeLine => codeLineSplit(codeLine));
-    return { global: globalScssContent, palette: paletteContent, normal: normalContent };
+
+    const animationContent = animationScssContentArray.map(codeLine => codeLine.trim())
+        .filter(codeLine => codeLine && !isComment(codeLine))
+        .filter(codeLine => !codeLine.startsWith('body'))
+        .filter(codeLine => !codeLine.startsWith('}'))
+        .filter(codeLine => !codeLine.startsWith('@'))
+        .map(codeLine=>codeLineSplit(codeLine)).map(token=>{
+            token.category="animation";
+            return token;
+        });
+    return { global: globalScssContent, palette: paletteContent, normal: normalContent, animation:animationContent };
 };
 
 // 官网组件 design token 注入
 async function main() {
     const componentVariablesMap = {};
+    const animationVariablesMap = {};
     const semiUIDir = path.join(__dirname, '../packages/semi-foundation');
     fs.readdirSync(semiUIDir).map(dirname => {
         const variableSCSSPath = path.join(semiUIDir, dirname, 'variables.scss');
@@ -93,7 +110,14 @@ async function main() {
             const scssCodeLineList = raw.split('\n').filter(codeLine => codeLine && !isComment(codeLine));
             componentVariablesMap[dirname.toLowerCase()] = scssCodeLineList.map(codeLine => codeLineSplit(codeLine));
         }
+        const animationSCSSPath = path.join(semiUIDir, dirname, 'animation.scss');
+        if (fs.existsSync(animationSCSSPath)){
+            const raw = fs.readFileSync(animationSCSSPath, { encoding: 'utf-8' });
+            const scssCodeLineList = raw.split('\n').filter(codeLine => codeLine && !isComment(codeLine));
+            animationVariablesMap[dirname.toLowerCase()] = scssCodeLineList.map(codeLine => codeLineSplit(codeLine));
+        }
     });
+    merge(componentVariablesMap, animationVariablesMap);
     componentVariablesMap.global = getGlobalDesignToken();
     const [_, __, savePath] = process.argv;
     fs.writeFileSync(savePath || './designToken.json', JSON.stringify(componentVariablesMap));

+ 50 - 14
src/components/DesignToken/index.tsx

@@ -4,20 +4,21 @@ import { Tabs, Table } from '@douyinfe/semi-ui';
 import { useIntl } from 'react-intl';
 import { Link } from 'gatsby';
 import lodash from 'lodash-es';
-interface Props{
+interface Props {
     componentName?: string;
     isColorPalette?: boolean;
     reg?: RegExp;
+    isAnimation?: boolean
 }
 
-interface Token{
+interface Token {
     key: string;
     value: string;
     category: string;
     raw: string;
 }
 
-interface DesignToken{
+interface DesignToken {
     // eslint-disable-next-line @typescript-eslint/ban-ts-comment
     // @ts-ignore
     global: {
@@ -30,18 +31,19 @@ interface DesignToken{
             dark: Token[];
         };
         normal: Token[];
+        animation: Token[];
     };
     [key: string]: Token[];
 
 }
 
 
-interface TokenMayWithColor extends Token{
+interface TokenMayWithColor extends Token {
     color?: string;
 }
 
 
-const JumpLink = ({ value, availableKeySet }: {value: string;availableKeySet: Set<string>}): ReactElement => {
+const JumpLink = ({ value, availableKeySet }: { value: string; availableKeySet: Set<string> }): ReactElement => {
     const { locale } = useIntl();
     const originValue = value;
     if (value.startsWith('var')) {
@@ -57,7 +59,7 @@ const JumpLink = ({ value, availableKeySet }: {value: string;availableKeySet: Se
     }
 };
 
-const TokenTable = ({ tokenList, designToken, currentTab,mode='light' }: {mode?:'light'|'dark',tokenList: TokenMayWithColor[];designToken: DesignToken; currentTab?: string; }): React.ReactElement => {
+const TokenTable = ({ tokenList, designToken, currentTab, mode = 'light' }: { mode?: 'light' | 'dark', tokenList: TokenMayWithColor[]; designToken: DesignToken; currentTab?: string; }): React.ReactElement => {
     const intl = useIntl();
     const globalTokenJumpAvailableSet = useMemo(() => {
         const global = designToken?.global;
@@ -76,7 +78,7 @@ const TokenTable = ({ tokenList, designToken, currentTab,mode='light' }: {mode?:
                         <div data-token={lodash.trim(text, '$')} style={{ fontWeight: 600 }}> <div style={{
                             width: 16, height: 16, display: 'inline-block', borderRadius: 3, backgroundColor: color,
                             transform: 'translateY(0.3rem)', marginRight: 8
-                        }} className={mode==='dark'?'semi-always-dark':'semi-always-light'}
+                        }} className={mode === 'dark' ? 'semi-always-dark' : 'semi-always-light'}
                         /> {text}
                         </div>
                     );
@@ -98,14 +100,14 @@ const TokenTable = ({ tokenList, designToken, currentTab,mode='light' }: {mode?:
                 <div>{text || intl.formatMessage({ id: 'designToken.WIP' })}</div>
         },
 
-    ], [intl.locale,mode]);
+    ], [intl.locale, mode]);
     if (!tokenList) {
         return null;
     }
     return <Table key={currentTab} columns={columns} dataSource={tokenList} />;
 };
 
-const TokenTab = ({ designToken, componentName }: {designToken: DesignToken;componentName: string}): React.ReactElement => {
+const TokenTab = ({ designToken, componentName }: { designToken: DesignToken; componentName: string }): React.ReactElement => {
     const componentDesignTokenList = useMemo(() => designToken[componentName], [designToken, componentName]);
     const tabList = useMemo(() => {
         const categorySet = new Set();
@@ -126,9 +128,9 @@ const TokenTab = ({ designToken, componentName }: {designToken: DesignToken;comp
     );
 };
 
-const GlobalTokenTab = ({ designToken, isColorPalette = false, reg }: {designToken: DesignToken;isColorPalette?: boolean;reg: RegExp}): React.ReactElement => {
+const GlobalTokenTab = ({ designToken, isColorPalette = false, reg }: { designToken: DesignToken; isColorPalette?: boolean; reg: RegExp }): React.ReactElement => {
     const { global, palette, normal } = designToken.global;
-    const [currentTab, setCurrentTab] = useState<'light'|'dark'>('light');
+    const [currentTab, setCurrentTab] = useState<'light' | 'dark'>('light');
     const [hasTab, setHasTab] = useState(true);
     const tokenList: TokenMayWithColor[] = useMemo(() => {
         if (!isColorPalette) {
@@ -151,14 +153,44 @@ const GlobalTokenTab = ({ designToken, isColorPalette = false, reg }: {designTok
     return (
         <>
             {hasTab ? (
-                <Tabs defaultActiveKey={'light'} tabList={[{ tab: 'Light', itemKey: 'light' }, { tab: 'Dark', itemKey: 'dark' }]} onChange={(key:typeof currentTab): void => setCurrentTab(key)}>
-                    <TokenTable designToken={designToken} tokenList={tokenList} mode={currentTab}/>
+                <Tabs defaultActiveKey={'light'} tabList={[{ tab: 'Light', itemKey: 'light' }, { tab: 'Dark', itemKey: 'dark' }]} onChange={(key: typeof currentTab): void => setCurrentTab(key)}>
+                    <TokenTable designToken={designToken} tokenList={tokenList} mode={currentTab} />
                 </Tabs>
             ) : <TokenTable designToken={designToken} tokenList={tokenList} mode={currentTab} />}
         </>
     );
 };
 
+
+const GlobalAnimationToken = ({ designToken }: { designToken: DesignToken }) => {
+    const animationList = useMemo(() => designToken?.global?.animation ?? [], [designToken]);
+    const tokenMap = useMemo(() => {
+        const tokenMap = {};
+        animationList.forEach(token => {
+            const tab = token['key'].match(/--semi-transition_([\w\W]+)-/)?.[1] ?? "other";
+            tokenMap[tab] = [...(tokenMap[tab] ?? []), token];
+        })
+        return tokenMap;
+    }, [animationList]);
+
+
+
+    return <>
+        <Tabs defaultActiveKey={Object.keys(tokenMap)[0]} >
+            {Object.entries(tokenMap).map(([category, tokenList]) => {
+                return <Tabs.TabPane tab={category} itemKey={category} key={category}>
+                    <TokenTable designToken={designToken} tokenList={tokenList} />
+                </Tabs.TabPane>
+            })}
+        </Tabs>
+    </>
+
+
+
+
+}
+
+
 const DesignToken = (props: Props): React.ReactElement => {
 
     const [componentName, setComponentName] = useState(props.componentName?.toLowerCase());
@@ -195,9 +227,13 @@ const DesignToken = (props: Props): React.ReactElement => {
 
     return (
         <div>
-            {designToken && componentName && (props.componentName === 'global' ?
+            {designToken && componentName && !props.isAnimation && (props.componentName === 'global' ?
                 <GlobalTokenTab designToken={designToken} reg={props.reg} isColorPalette={props.isColorPalette} /> :
                 <TokenTab designToken={designToken} componentName={componentName} />)}
+
+            {
+                props.isAnimation && <GlobalAnimationToken designToken={designToken} />
+            }
         </div>
     );
 };

+ 4 - 1
src/locale/en-US.js

@@ -81,7 +81,10 @@ const appLocale = {
         "home.theme": "Theming",
         "home.theme.desc": "Create variations of UI Styles that suit your brand with full flexibility",
         "volcengine_theme": "Volce Engine Theme",
-        "home.pro.desc": "Design with real code components,convert your deisgn to code with one click",
+        "home.pro.title": "Semi Design D2C",
+        "home.pro.desc": "Design with real code components,convert your design to code with one click",
+        "home.pro.start": "Get Started",
+        "beta": "Beta",
 
         "semi_design_share_2code": "#Semi Design2Code# Topic Activity is now open!",
         "access_is_simple_and_easy_to_use;": "Semi is easy to get started; the UI is beautiful and consistent; and the API is comprehensive, too.",

+ 3 - 0
src/locale/zh-CN.js

@@ -115,7 +115,10 @@ const appLocale = {
         "excellent_design_of_mid_background_enterprise_applications": "设计出色的中后台企业应用",
         "home.theme": "百变主题",
         "home.theme.desc": "快速克隆或深度定制,灵活调配符合品牌调性的设计风格",
+        "home.pro.title": "Semi Design 设计稿转代码",
         "home.pro.desc": "基于 40+ 真实组件代码设计,海量页面模板前端代码一键转",
+        "home.pro.start": "快速开始",
+        "beta": "公测",
 
         "default": "默认",
         "feishu_universe_design_theme": "飞书 Universe Design 主题",

+ 46 - 8
src/sitePages/newHome/components/pro/pro.jsx

@@ -1,23 +1,61 @@
-import { _t } from "src/utils/locale";
+import { _t } from 'src/utils/locale';
 import React from 'react';
+import { Button, Tag } from '@douyinfe/semi-ui';
 import styles from './pro.module.scss';
+import { navigate } from 'gatsby-link';
+import { getLocale } from '../../../../utils/locale';
 
 function Pro(props) {
+    const goD2CStart = () => {
+        navigate(`/code/${getLocale()}/start/quick-start`);
+    };
+    const isInternal = process.env.D2C_URL;
+
     return (
         <div {...props} className={styles.macBookPro2}>
             <div className={styles.frame14294}>
                 <div className={styles.frame4151}>
-                    <p className={styles.semiPro}>Semi Pro</p>
-                </div>
-                <p className={styles.text}><span className={styles.text_4c571d3f}>{_t("home.pro.desc", { }, "基于")}</span></p>
-                <div className={styles.buttonSecondarySolid}>
-                    <p className={styles.text_001dc6a1}>{_t("under_construction", { }, "建设中")}</p>
+                    <p className={styles.semiPro}>{_t('home.pro.title')}</p>
+                    {isInternal && (
+                        <Tag style={{ color: '#F0B114', background: '#41464C', marginLeft: 12 }}>
+                            {_t('beta', {}, '公测')}
+                        </Tag>
+                    )}
                 </div>
+                <p className={styles.text}>
+                    <span className={styles.text_4c571d3f}>{_t('home.pro.desc', {}, '基于')}</span>
+                </p>
+                {isInternal ? (
+                    <Button onClick={goD2CStart} size="large" theme="solid" className={styles.extraLarge}>
+                        {_t('home.pro.start', {}, '快速开始')}
+                    </Button>
+                ) : (
+                    <div className={styles.buttonSecondarySolid}>
+                        <p className={styles.text_001dc6a1}>{_t('under_construction', {}, '建设中')}</p>
+                    </div>
+                )}
             </div>
-            <div className={styles.autoWrapper}><img src="https://lf9-static.semi.design/obj/semi-tos/images/homepage-pro-code.jpg" className={styles.syntaxHighlighter} />
+            <div className={styles.autoWrapper}>
+                <img
+                    src="https://lf9-static.semi.design/obj/semi-tos/images/homepage-pro-code.jpg"
+                    className={styles.syntaxHighlighter}
+                />
                 <div className={styles.rectangle1080}></div>
                 <div className={styles.frame14295}>
-                    <div className={styles.autoWrapper}><img src="https://lf9-static.semi.design/obj/semi-tos/images/5de23960-3242-11ec-8b14-8fb159794ae4.png" className={styles.chromeStandart} /><img src="https://lf9-static.semi.design/obj/semi-tos/images/5ddb0d70-3242-11ec-adec-e911cea4cf98.png" className={styles.chromeStandart_2167fd7e} /><img src="https://lf9-static.semi.design/obj/semi-tos/images/5ddc6d00-3242-11ec-9c23-a9f1bde3758e.png" className={styles.chromeStandart_07210c83} /></div>
+                    <div className={styles.autoWrapper}>
+                        <img
+                            src="https://lf9-static.semi.design/obj/semi-tos/images/5de23960-3242-11ec-8b14-8fb159794ae4.png"
+                            className={styles.chromeStandart}
+                        />
+                        <img
+                            src="https://lf9-static.semi.design/obj/semi-tos/images/5ddb0d70-3242-11ec-adec-e911cea4cf98.png"
+                            className={styles.chromeStandart_2167fd7e}
+                        />
+                        <img
+                            src="https://lf9-static.semi.design/obj/semi-tos/images/5ddc6d00-3242-11ec-9c23-a9f1bde3758e.png"
+                            className={styles.chromeStandart_07210c83}
+                        />
+                    </div>
                 </div>
             </div>
         </div>

+ 12 - 1
src/sitePages/newHome/components/pro/pro.module.scss

@@ -23,7 +23,7 @@
 }
 
 .semiPro {
-    width: 321px;
+    // width: 321px;
     font-size: 32px;
     font-family: Inter;
     color: var(--semi-color-white);
@@ -82,6 +82,17 @@
     vertical-align: top;
 }
 
+.extraLarge {
+    height: 48px;
+    padding: 12px 24px;
+    border-radius: 6px;
+
+    :global(.semi-button-content) {
+        font-size: 16px;
+        line-height: 22px;
+    }
+}
+
 .autoWrapper {
     position: relative;
     line-height: 0;