Browse Source

feat: highlight code add default semi theme

DaiQiangReal 1 year ago
parent
commit
29c1b223ff

+ 18 - 19
content/plus/CodeHighlight/index.md

@@ -20,21 +20,16 @@ Semi 代码高亮组件使用了 prismjs,支持297 种编程语言的高亮(
 
 ```jsx
 import { CodeHighlight } from '@douyinfe/semi-ui';
-import "prismjs/themes/prism.min.css";  // 手动引入高亮主题
 ```
 
-另有多个主题均在 node_modules 内 prismjs/themes 下。(如果你使用 pnpm,请自行查找具体安装路径或在项目中手动安装 prismjs)
-
 ### 基本用法
 
 ```jsx live=true dir=column
 import { CodeHighlight } from '@douyinfe/semi-ui';
-import "prismjs/themes/prism.min.css";
 
 function Demo() {
 
-    return <CodeHighlight 
-        className="codeHighlightDemo" // 用于防止 Semi 文档站样式影响 Demo 展示效果,实际项目不需要该 ClassName
+    return <CodeHighlight
         language={"javascript"} code={
         `
 import * as React from 'react"
@@ -53,12 +48,10 @@ const Test = ()=>{
 
 ```jsx live=true dir=column
 import { CodeHighlight } from '@douyinfe/semi-ui';
-import "prismjs/themes/prism.min.css";
 
 function Demo() {
 
-    return <CodeHighlight 
-        className="codeHighlightDemo" // 用于防止 Semi 文档站样式影响 Demo 展示效果,实际项目不需要该 ClassName
+    return <CodeHighlight
         language={"css"} code={
         `.grid {
     .semi-row,
@@ -92,12 +85,10 @@ import "prismjs/components/prism-vala.js"
 
 ```jsx live=true dir=column
 import { CodeHighlight } from '@douyinfe/semi-ui';
-import "prismjs/themes/prism.min.css";
 import "prismjs/components/prism-vala.js"
 
 function Demo() {
-    return <CodeHighlight 
-        className="codeHighlightDemo" // 用于防止 Semi 文档站样式影响 Demo 展示效果,实际项目不需要该 ClassName
+    return <CodeHighlight
         language={"vala"} code={
         `public class ExampleApp : Gtk.Application {
     public ExampleApp () {
@@ -126,15 +117,23 @@ function Demo() {
 ```
 
 
+### 自定义主题
+
+设置 `defaultTheme={false}` 关闭默认主题,然后手动将需要的主题的 css 文件拷贝并放入项目中引入即可。
+一些主题可在 node_modules 内 prismjs/themes 下找到,你也可以在网上搜索其他中意的主题。
+
+
+
 ### API
 
-| 属性        | 说明       | 类型     | 默认值 |
-|-----------|----------|--------|-----|
-| className | 类名       | string | -   |
-| code      | 代码纯文本    | string | -   |
-| language  | 语言类型     | string | -   |
-|lineNumber | 是否开启行数显示 | boolean | true |
-| style | 样式       | CSSProperties | - |
+| 属性        | 说明                        | 类型     | 默认值  |
+|-----------|---------------------------|--------|------|
+| className | 类名                        | string | -    |
+| code      | 代码纯文本                     | string | -    |
+| defaultTheme | 是否使用默认主题,添加自己的主题时设置 false | bool | true |
+| language  | 语言类型                      | string | -    |
+|lineNumber | 是否开启行数显示                  | boolean | true |
+| style | 样式                        | CSSProperties | -    |
 
 ## 设计变量
 

+ 199 - 0
packages/semi-foundation/codeHighlight/codeHighlight.scss

@@ -2,3 +2,202 @@
 
 $module: #{$prefix}-codeHighlight;
 
+.#{$module}{
+  &-defaultTheme{
+    /**
+     * prism.js default theme for JavaScript, CSS and HTML
+     * Based on dabblet (http://dabblet.com)
+     * @author Lea Verou
+     */
+
+    pre[class*="language-"],
+    code[class*="language-"]{
+      color: var(--semi-color-text-0);
+      font-size: 13px;
+      text-shadow: none;
+      // font-family: 'Inconsolata', Consolas, Monaco, "Andale Mono", "Ubuntu Mono", monospace;
+      font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, Courier, monospace;
+      direction: ltr;
+      text-align: left;
+      white-space: pre;
+      word-spacing: normal;
+      word-break: normal;
+      line-height: 1.5;
+      -moz-tab-size: 4;
+      -o-tab-size: 4;
+      tab-size: 4;
+
+      -moz-hyphens: none;
+      hyphens: none;
+    }
+
+    pre[class*="language-"]::selection,
+    code[class*="language-"]::selection,
+    pre[class*="language-"]::mozselection,
+    code[class*="language-"]::mozselection {
+      text-shadow: none;
+      background: #b3d4fc;
+    }
+
+
+    pre[class*="language-"]{
+      padding: 1em;
+      margin: .5em 0;
+      overflow: auto;
+      background: #f9f7f9;
+    }
+
+    :not(pre)>code[class*="language-"] {
+      // padding: .1em .3em;
+      display: block;
+      border-radius: .3em;
+      color: #895fe2;
+      background: #f9f7f9;
+    }
+
+    pre{
+      .namespace {
+        opacity: .7;
+      }
+
+      .token.comment,
+      .token.prolog,
+      .token.doctype,
+      .token.cdata {
+        color: #6b7075;
+      }
+
+      .token.punctuation {
+        color: rgba(var(--semi-grey-8), 1),
+      }
+
+      .token.property,
+      .token.tag,
+      .token.boolean,
+      .token.number,
+      .token.constant,
+      .token.symbol,
+      .token.deleted {
+        color: rgba(var(--semi-purple-6), 1);
+      }
+
+      .token.selector,
+      .token.attr-name,
+      .token.string,
+      .token.char,
+      .token.builtin,
+      .token.inserted {
+        color: rgba(var(--semi-green-6), 1);
+      }
+
+      .token.operator,
+      .token.entity,
+      .token.url,
+      .language-css .token.string,
+      .style .token.string {
+        color: rgba(var(--semi-grey-8), 1),
+      }
+
+      .token.atrule,
+      .token.attr-value,
+      .token.keyword {
+        color: rgba(var(--semi-purple-6), 1);
+      }
+
+      .token.function {
+        color: rgba(var(--semi-violet-6), 1);
+      }
+
+      .token.regex,
+      .token.important,
+      .token.variable {
+        color: #d0955f;
+      }
+
+      .token.important,
+      .token.bold {
+        font-weight: bold;
+      }
+
+      .token.italic {
+        font-style: italic;
+      }
+
+      .token.entity {
+        cursor: help;
+      }
+
+    }
+
+    pre[data-line] {
+      position: relative;
+    }
+
+    pre[class*="language-"]>code[class*="language-"] {
+      position: relative;
+      z-index: 1;
+    }
+
+    .line-highlight {
+      position: absolute;
+      left: 0;
+      right: 0;
+      padding: inherit 0;
+      margin-top: 1em;
+      background: #ebf4ff;
+      box-shadow: inset 5px 0 0 #0064d2;
+      z-index: 0;
+      pointer-events: none;
+      line-height: inherit;
+      white-space: pre;
+    }
+  }
+
+  //---- line number ----
+
+
+  pre[class*="language-"].line-numbers {
+    position: relative;
+    padding-left: 3.8em;
+    counter-reset: linenumber;
+  }
+
+  pre[class*="language-"].line-numbers > code {
+    position: relative;
+    white-space: inherit;
+  }
+
+  .line-numbers .line-numbers-rows {
+    position: absolute;
+    pointer-events: none;
+    top: 0;
+    font-size: 100%;
+    left: -3.8em;
+    width: 3em; /* works for line-numbers below 1000 lines */
+    letter-spacing: -1px;
+    border-right: 1px solid #999;
+
+    -webkit-user-select: none;
+    -moz-user-select: none;
+    -ms-user-select: none;
+    user-select: none;
+
+  }
+
+  .line-numbers-rows > span {
+    display: block;
+    counter-increment: linenumber;
+  }
+
+  .line-numbers-rows > span:before {
+    content: counter(linenumber);
+    color: #999;
+    display: block;
+    padding-right: 0.8em;
+    text-align: right;
+  }
+
+}
+
+
+

+ 0 - 1
packages/semi-foundation/codeHighlight/index.ts

@@ -2,7 +2,6 @@ import BaseFoundation, { DefaultAdapter } from '../base/foundation';
 import Prism from 'prismjs';
 import cls from "classnames";
 import "prismjs/plugins/line-numbers/prism-line-numbers.min.js";
-import "prismjs/plugins/line-numbers/prism-line-numbers.min.css";
 
 Prism.manual = true;
 

+ 0 - 1
packages/semi-ui/codeHighlight/_story/codeHighlight.stories.jsx

@@ -1,6 +1,5 @@
 import * as React from 'react'
 import CodeHighlight from '../index';
-import "prismjs/themes/prism.min.css";
 export default {
     title: 'CodeHighlightBasic',
 }

+ 14 - 7
packages/semi-ui/codeHighlight/index.tsx

@@ -9,11 +9,14 @@ import { CSSProperties } from 'react';
 import "@douyinfe/semi-foundation/codeHighlight/codeHighlight.scss";
 import { getDefaultPropsFromGlobalConfig } from '../_utils';
 import PropTypes from 'prop-types';
+import cls from "classnames";
+import { cssClasses } from "@douyinfe/semi-foundation/codeHighlight/constants";
 
 
 interface CodeHighlightProps extends CodeHighlightBaseProps {
     className?: string;
-    style?: CSSProperties
+    style?: CSSProperties;
+    defaultTheme?: boolean
 }
 
 
@@ -34,10 +37,12 @@ class CodeHighlight extends BaseComponent<CodeHighlightProps, CodeHighlightState
         code: PropTypes.string,
         language: PropTypes.string,
         lineNumber: PropTypes.bool,
+        defaultTheme: PropTypes.bool,
     }
 
     static defaultProps = getDefaultPropsFromGlobalConfig(CodeHighlight.__SemiComponentName__, {
-        lineNumber: true
+        lineNumber: true,
+        defaultTheme: true
     })
 
     constructor(props: CodeHighlightProps) {
@@ -66,11 +71,13 @@ class CodeHighlight extends BaseComponent<CodeHighlightProps, CodeHighlightState
     }
 
     render() {
-        return <pre className={this.props.className} style={this.props.style}>
-            <code ref={this.codeRef}>
-                {this.props.code}
-            </code>
-        </pre>;
+        return <div style={this.props.style} className={cls(this.props.className, cssClasses.PREFIX, { [`${cssClasses.PREFIX}-defaultTheme`]: this.props.defaultTheme })} {...this.getDataAttr(this.props)}>
+            <pre>
+                <code ref={this.codeRef}>
+                    {this.props.code}
+                </code>
+            </pre>
+        </div>;
     }
 
 

+ 3 - 140
src/styles/layout.scss

@@ -32,7 +32,7 @@ body[theme-mode="dark"] {
     }
 }
 
-pre:not(.codeHighlightDemo),code:not(.codeHighlightDemo *) {
+pre,code:not(.semi-codeHighlight *) {
     font-family: Inconsolata, monospace;
     background-color: var(--semi-color-fill-1);
     margin-left: 4px;
@@ -40,6 +40,8 @@ pre:not(.codeHighlightDemo),code:not(.codeHighlightDemo *) {
     letter-spacing: -0.01em;
 }
 
+
+
 body[theme-mode="dark"] {
     font-family: "Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", "PingFang SC", "Hiragino Sans GB",
         "Microsoft YaHei", "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -510,143 +512,4 @@ $spCol: var(--semi-color-primary);
 
 
 
-/**
- * prism.js default theme for JavaScript, CSS and HTML
- * Based on dabblet (http://dabblet.com)
- * @author Lea Verou
- */
-// 隔离官网 prism 与 codeHighlight 组件的 prism
-code[class*="language-"],
-pre[class*="language-"] {
-    color: black;
-    background: none;
-    text-shadow: 0 1px white;
-    font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
-    font-size: 1em;
-    text-align: left;
-    white-space: pre;
-    word-spacing: normal;
-    word-break: normal;
-    word-wrap: normal;
-    line-height: 1.5;
-
-    -moz-tab-size: 4;
-    -o-tab-size: 4;
-    tab-size: 4;
-
-    -webkit-hyphens: none;
-    -moz-hyphens: none;
-    -ms-hyphens: none;
-    hyphens: none;
-}
-
-pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
-code[class*="language-"]::-moz-selection, code[class*="language-"] ::-moz-selection {
-    text-shadow: none;
-    background: #b3d4fc;
-}
-
-pre[class*="language-"]::selection, pre[class*="language-"] ::selection,
-code[class*="language-"]::selection, code[class*="language-"] ::selection {
-    text-shadow: none;
-    background: #b3d4fc;
-}
-
-@media print {
-    code[class*="language-"],
-    pre[class*="language-"] {
-        text-shadow: none;
-    }
-}
-
-/* Code blocks */
-pre[class*="language-"] {
-    padding: 1em;
-    margin: .5em 0;
-    overflow: auto;
-}
-
-:not(pre) > code[class*="language-"],
-pre[class*="language-"] {
-    background: #f5f2f0;
-}
-
-/* Inline code */
-:not(pre) > code[class*="language-"] {
-    padding: .1em;
-    border-radius: .3em;
-    white-space: normal;
-}
-
-.token.comment,
-.token.prolog,
-.token.doctype,
-.token.cdata {
-    color: slategray;
-}
-
-.token.punctuation {
-    color: #999;
-}
-
-.token.namespace {
-    opacity: .7;
-}
-
-.token.property,
-.token.tag,
-.token.boolean,
-.token.number,
-.token.constant,
-.token.symbol,
-.token.deleted {
-    color: #905;
-}
-
-.token.selector,
-.token.attr-name,
-.token.string,
-.token.char,
-.token.builtin,
-.token.inserted {
-    color: #690;
-}
-
-.token.operator,
-.token.entity,
-.token.url,
-.language-css .token.string,
-.style .token.string {
-    color: #9a6e3a;
-    /* This background color was intended by the author of this theme. */
-    background: hsla(0, 0%, 100%, .5);
-}
-
-.token.atrule,
-.token.attr-value,
-.token.keyword {
-    color: #07a;
-}
-
-.token.function,
-.token.class-name {
-    color: #DD4A68;
-}
-
-.token.regex,
-.token.important,
-.token.variable {
-    color: #e90;
-}
-
-.token.important,
-.token.bold {
-    font-weight: bold;
-}
-.token.italic {
-    font-style: italic;
-}
 
-.token.entity {
-    cursor: help;
-}