diff --git a/components/CodeBlocks/BlockCode.module.css b/components/CodeBlocks/BlockCode.module.css index b0fbea3d0..2c05cf4ae 100644 --- a/components/CodeBlocks/BlockCode.module.css +++ b/components/CodeBlocks/BlockCode.module.css @@ -1,11 +1,34 @@ .code { - @apply static !important; - @apply mb-0 p-5 !important; + @apply static; + @apply mb-0 px-0 py-5; } -.line { - @apply inline-block !important; - @apply w-6 !important; - @apply mr-3 !important; - @apply text-secondary select-none !important; +.code div { + @apply relative; +} + +.hover, +.highlight { + @apply absolute; + @apply w-full h-full; +} + +.hover:hover, +.highlight { + @apply bg-gray-100/10; +} + +.highlight { + @apply border-l-4 border-solid border-l-primary; +} + +.number { + @apply inline-block; + @apply w-6; + @apply ml-5 mr-3; + @apply text-secondary select-none; +} + +.placeholder { + @apply ml-5; } diff --git a/components/CodeBlocks/BlockCode.test.tsx b/components/CodeBlocks/BlockCode.test.tsx index 41312923a..af53a6d9f 100644 --- a/components/CodeBlocks/BlockCode.test.tsx +++ b/components/CodeBlocks/BlockCode.test.tsx @@ -27,29 +27,11 @@ describe('BlockCode', () => { 'rust', ]; - test('should hidden line number and copy button according code block metadata (snapshot)', () => { - const { container } = render( - - const foo = bar(); - - ); - - expect(container).toMatchSnapshot(); - }); - test.each(languages)( 'should render different language correctly (snapshot)', language => { const { container } = render( - + const foo = bar(); ); diff --git a/components/CodeBlocks/BlockCode.tsx b/components/CodeBlocks/BlockCode.tsx index bc98d0dbd..4c2153e59 100644 --- a/components/CodeBlocks/BlockCode.tsx +++ b/components/CodeBlocks/BlockCode.tsx @@ -1,4 +1,3 @@ -import CopyButton from '@components/CopyButton'; import { classNames } from '@components/utils'; import type { Language } from 'prism-react-renderer'; import Highlight, { defaultProps } from 'prism-react-renderer'; @@ -7,40 +6,46 @@ import theme from './monokai'; import { normalizeCode } from './utils'; interface Props { - enableLine: boolean; - enableCopy: boolean; + enableLine?: boolean; + lines?: Set; children?: string; className?: string; } const BlockCode = ({ - enableLine, - enableCopy, + enableLine = true, + lines = new Set(), children, className, -}: Props): JSX.Element => ( - - {({ className, style, tokens, getLineProps, getTokenProps }) => ( -
-        {enableCopy ?  : null}
-        {tokens.map((line, index) => (
-          
- {enableLine ? ( - {index + 1} - ) : null} - {line.map((token, key) => ( - - ))} -
- ))} -
- )} -
-); +}: Props): JSX.Element => { + const code = normalizeCode(children); + const language = className?.replace('language-', '') as Language; + + return ( + + {({ className, style, tokens, getLineProps, getTokenProps }) => ( +
+          {tokens.map((line, index) => (
+            
+ {lines.has(index + 1) ? ( + + ) : ( + + )} + {enableLine ? ( + {index + 1} + ) : ( + + )} + {line.map((token, key) => ( + + ))} +
+ ))} +
+ )} +
+ ); +}; export default BlockCode; diff --git a/components/CodeBlocks/Pre.test.tsx b/components/CodeBlocks/Pre.test.tsx index 32fd5f2fe..4cdba129e 100644 --- a/components/CodeBlocks/Pre.test.tsx +++ b/components/CodeBlocks/Pre.test.tsx @@ -43,6 +43,46 @@ describe('Pre', () => { expect(container).toMatchSnapshot(); }); + test('should hidden line number correctly (snapshot)', () => { + const { container } = render( +
+        Code
+      
+ ); + + expect(container).toMatchSnapshot(); + }); + + test('should hidden copy button correctly (snapshot)', () => { + const { container } = render( +
+        Code
+      
+ ); + + expect(container).toMatchSnapshot(); + }); + + test('should render code title correctly (snapshot)', () => { + const { container } = render( +
+        Code
+      
+ ); + + expect(container).toMatchSnapshot(); + }); + + test('should render highlight lines correctly (snapshot)', () => { + const { container } = render( +
+        Code
+      
+ ); + + expect(container).toMatchSnapshot(); + }); + test('should render live code correctly (snapshot)', () => { const { container } = render(
diff --git a/components/CodeBlocks/Pre.tsx b/components/CodeBlocks/Pre.tsx
index 7fbf300f3..94e57ebe1 100644
--- a/components/CodeBlocks/Pre.tsx
+++ b/components/CodeBlocks/Pre.tsx
@@ -1,22 +1,25 @@
+import CopyButton from '@components/CopyButton';
 import { classNames } from '@components/utils';
 import type { HTMLProps, ReactElement } from 'react';
 import BlockCode from './BlockCode';
 import LiveCode from './LiveCode';
 import styles from './Pre.module.css';
-import { normalizeLanguage } from './utils';
+import { normalizeLanguage, normalizeLines } from './utils';
 
 interface Props extends HTMLProps {
   live?: boolean;
   noline?: boolean;
   nocopy?: boolean;
   title?: string;
+  lines?: string;
 }
 
 const Pre = ({
   live = false,
   noline = false,
   nocopy = false,
-  title,
+  title = '',
+  lines = '',
   children,
   className,
 }: Props): JSX.Element => {
@@ -26,18 +29,20 @@ const Pre = ({
   const languageName = normalizeLanguage(
     languageClass?.replace('language-', '')
   );
+  const highlightLines = normalizeLines(lines);
 
   return (
     
+      {!nocopy ?  : null}
       {live ? (
         {code}
       ) : (
         
           {code}
diff --git a/components/CodeBlocks/__snapshots__/BlockCode.test.tsx.snap b/components/CodeBlocks/__snapshots__/BlockCode.test.tsx.snap
index ce37864b3..53862470f 100644
--- a/components/CodeBlocks/__snapshots__/BlockCode.test.tsx.snap
+++ b/components/CodeBlocks/__snapshots__/BlockCode.test.tsx.snap
@@ -1,74 +1,20 @@
 // Jest Snapshot v1, https://goo.gl/fbAQLP
 
-exports[`BlockCode should hidden line number and copy button according code block metadata (snapshot) 1`] = `
-
-
-    
- - const foo = bar(); - -
-
-
-`; - exports[`BlockCode should render different language correctly (snapshot) 1`] = `
-    
     
+ 1 @@ -88,49 +34,15 @@ exports[`BlockCode should render different language correctly (snapshot) 2`] = ` class="prism-code language-xml code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -150,49 +62,15 @@ exports[`BlockCode should render different language correctly (snapshot) 3`] = ` class="prism-code language-yml code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -212,49 +90,15 @@ exports[`BlockCode should render different language correctly (snapshot) 4`] = ` class="prism-code language-yaml code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -274,49 +118,15 @@ exports[`BlockCode should render different language correctly (snapshot) 5`] = ` class="prism-code language-css code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -360,49 +170,15 @@ exports[`BlockCode should render different language correctly (snapshot) 6`] = ` class="prism-code language-json code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -422,49 +198,15 @@ exports[`BlockCode should render different language correctly (snapshot) 7`] = ` class="prism-code language-md code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -484,49 +226,15 @@ exports[`BlockCode should render different language correctly (snapshot) 8`] = ` class="prism-code language-markdown code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -546,49 +254,15 @@ exports[`BlockCode should render different language correctly (snapshot) 9`] = ` class="prism-code language-js code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -649,49 +323,15 @@ exports[`BlockCode should render different language correctly (snapshot) 10`] = class="prism-code language-javascript code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -752,49 +392,15 @@ exports[`BlockCode should render different language correctly (snapshot) 11`] = class="prism-code language-ts code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -855,49 +461,15 @@ exports[`BlockCode should render different language correctly (snapshot) 12`] = class="prism-code language-typescript code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -958,49 +530,15 @@ exports[`BlockCode should render different language correctly (snapshot) 13`] = class="prism-code language-coffee code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1055,49 +593,15 @@ exports[`BlockCode should render different language correctly (snapshot) 14`] = class="prism-code language-coffeescript code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1152,49 +656,15 @@ exports[`BlockCode should render different language correctly (snapshot) 15`] = class="prism-code language-jsx code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1255,49 +725,15 @@ exports[`BlockCode should render different language correctly (snapshot) 16`] = class="prism-code language-tsx code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1358,49 +794,15 @@ exports[`BlockCode should render different language correctly (snapshot) 17`] = class="prism-code language-objc code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1461,49 +863,15 @@ exports[`BlockCode should render different language correctly (snapshot) 18`] = class="prism-code language-objectivec code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1564,49 +932,15 @@ exports[`BlockCode should render different language correctly (snapshot) 19`] = class="prism-code language-vue code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1626,49 +960,15 @@ exports[`BlockCode should render different language correctly (snapshot) 20`] = class="prism-code language-go code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1729,49 +1029,15 @@ exports[`BlockCode should render different language correctly (snapshot) 21`] = class="prism-code language-java code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 @@ -1791,49 +1057,15 @@ exports[`BlockCode should render different language correctly (snapshot) 22`] = class="prism-code language-rust code" style="color: rgb(118, 217, 230); background-color: rgb(42, 42, 42);" > -
+ 1 diff --git a/components/CodeBlocks/__snapshots__/Pre.test.tsx.snap b/components/CodeBlocks/__snapshots__/Pre.test.tsx.snap index d4462b174..2099d0db2 100644 --- a/components/CodeBlocks/__snapshots__/Pre.test.tsx.snap +++ b/components/CodeBlocks/__snapshots__/Pre.test.tsx.snap @@ -1,58 +1,232 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`Pre should hidden copy button correctly (snapshot) 1`] = ` +
+
+    
+      
+ + + 1 + + + Code + +
+
+
+
+`; + +exports[`Pre should hidden line number correctly (snapshot) 1`] = ` +
+
+    
+    
+      
+ + + + Code + +
+
+
+
+`; + +exports[`Pre should render code title correctly (snapshot) 1`] = ` +
+
+    
+    
+      
+ + + 1 + + + Code + +
+
+
+
+`; + exports[`Pre should render different language correctly (snapshot) 1`] = `
-    
-      
+        
+      
+ +
       
+ 1 @@ -73,53 +247,56 @@ exports[`Pre should render different language correctly (snapshot) 2`] = ` class="language-xml pre" data-language="XML" > -
-      
+        
+      
+ +
       
+ 1 @@ -140,53 +317,56 @@ exports[`Pre should render different language correctly (snapshot) 3`] = ` class="language-yml pre" data-language="YAML" > -
-      
+        
+      
+ +
       
+ 1 @@ -207,53 +387,56 @@ exports[`Pre should render different language correctly (snapshot) 4`] = ` class="language-yaml pre" data-language="YAML" > -
-      
+        
+      
+ +
       
+ 1 @@ -274,53 +457,56 @@ exports[`Pre should render different language correctly (snapshot) 5`] = ` class="language-css pre" data-language="CSS" > -
-      
+        
+      
+ +
       
+ 1 @@ -341,53 +527,56 @@ exports[`Pre should render different language correctly (snapshot) 6`] = ` class="language-json pre" data-language="JSON" > -
-      
+        
+      
+ +
       
+ 1 @@ -408,53 +597,56 @@ exports[`Pre should render different language correctly (snapshot) 7`] = ` class="language-md pre" data-language="Markdown" > -
-      
+        
+      
+ +
       
+ 1 @@ -475,53 +667,56 @@ exports[`Pre should render different language correctly (snapshot) 8`] = ` class="language-markdown pre" data-language="Markdown" > -
-      
+        
+      
+ +
       
+ 1 @@ -542,53 +737,56 @@ exports[`Pre should render different language correctly (snapshot) 9`] = ` class="language-js pre" data-language="JavaScript" > -
-      
+        
+      
+ +
       
+ 1 @@ -609,53 +807,56 @@ exports[`Pre should render different language correctly (snapshot) 10`] = ` class="language-javascript pre" data-language="JavaScript" > -
-      
+        
+      
+ +
       
+ 1 @@ -676,53 +877,56 @@ exports[`Pre should render different language correctly (snapshot) 11`] = ` class="language-ts pre" data-language="TypeScript" > -
-      
+        
+      
+ +
       
+ 1 @@ -743,53 +947,56 @@ exports[`Pre should render different language correctly (snapshot) 12`] = ` class="language-typescript pre" data-language="TypeScript" > -
-      
+        
+      
+ +
       
+ 1 @@ -810,53 +1017,56 @@ exports[`Pre should render different language correctly (snapshot) 13`] = ` class="language-coffee pre" data-language="CoffeeScript" > -
-      
+        
+      
+ +
       
+ 1 @@ -877,53 +1087,56 @@ exports[`Pre should render different language correctly (snapshot) 14`] = ` class="language-coffeescript pre" data-language="CoffeeScript" > -
-      
+        
+      
+ +
       
+ 1 @@ -944,53 +1157,56 @@ exports[`Pre should render different language correctly (snapshot) 15`] = ` class="language-jsx pre" data-language="React" > -
-      
+        
+      
+ +
       
+ 1 @@ -1011,53 +1227,56 @@ exports[`Pre should render different language correctly (snapshot) 16`] = ` class="language-tsx pre" data-language="React" > -
-      
+        
+      
+ +
       
+ 1 @@ -1078,53 +1297,56 @@ exports[`Pre should render different language correctly (snapshot) 17`] = ` class="language-objc pre" data-language="Objective-C" > -
-      
+        
+      
+ +
       
+ 1 @@ -1145,53 +1367,56 @@ exports[`Pre should render different language correctly (snapshot) 18`] = ` class="language-objectivec pre" data-language="Objective-C" > -
-      
+        
+      
+ +
       
+ 1 @@ -1212,53 +1437,56 @@ exports[`Pre should render different language correctly (snapshot) 19`] = ` class="language-vue pre" data-language="Vue" > -
-      
+        
+      
+ +
       
+ 1 @@ -1279,53 +1507,56 @@ exports[`Pre should render different language correctly (snapshot) 20`] = ` class="language-go pre" data-language="Go" > -
-      
+        
+      
+ +
       
+ 1 @@ -1346,53 +1577,56 @@ exports[`Pre should render different language correctly (snapshot) 21`] = ` class="language-java pre" data-language="Java" > -
-      
+        
+      
+ +
       
+ 1 @@ -1413,53 +1647,56 @@ exports[`Pre should render different language correctly (snapshot) 22`] = ` class="language-rust pre" data-language="Rust" > -
-      
+        
+      
+ +
       
+ 1 @@ -1480,53 +1717,56 @@ exports[`Pre should render empty children correctly (snapshot) 1`] = ` class="pre" data-language="Code" > -
-      
+        
+      
+ +
       
+ 1 @@ -1549,53 +1789,126 @@ exports[`Pre should render empty className correctly (snapshot) 1`] = ` class="pre" data-language="Code" > +
-      
+
+
+
+`; + +exports[`Pre should render highlight lines correctly (snapshot) 1`] = ` +
+
+    
+        
+      
+ +
       
+ 1 @@ -1616,6 +1929,43 @@ exports[`Pre should render live code correctly (snapshot) 1`] = ` class="pre" data-language="Code" > +
diff --git a/components/CodeBlocks/utils.ts b/components/CodeBlocks/utils.ts
index a36c53550..849e4ba98 100644
--- a/components/CodeBlocks/utils.ts
+++ b/components/CodeBlocks/utils.ts
@@ -1,3 +1,5 @@
+import parseNumericRange from 'parse-numeric-range';
+
 const normalizeCode = (code: string = '') => code.replace(/\n+$/, '');
 
 const normalizeLanguage = (language: string) => {
@@ -36,4 +38,7 @@ const normalizeLanguage = (language: string) => {
   }
 };
 
-export { normalizeCode, normalizeLanguage };
+const normalizeLines = (expression: string): Set =>
+  new Set(parseNumericRange(expression));
+
+export { normalizeCode, normalizeLanguage, normalizeLines };
diff --git a/components/MDX/__snapshots__/MDX.test.tsx.snap b/components/MDX/__snapshots__/MDX.test.tsx.snap
index 868c1093e..319d09922 100644
--- a/components/MDX/__snapshots__/MDX.test.tsx.snap
+++ b/components/MDX/__snapshots__/MDX.test.tsx.snap
@@ -54,53 +54,56 @@ exports[`MDXPre should render correctly (snapshot) 1`] = `
     class="pre"
     data-language="Code"
   >
-    
-      
+        
+      
+ +
       
+ 1 diff --git a/contents/implementFancyCodeBlock.mdx b/contents/implementFancyCodeBlock.mdx index 698e9aea8..7fd93245c 100644 --- a/contents/implementFancyCodeBlock.mdx +++ b/contents/implementFancyCodeBlock.mdx @@ -86,7 +86,9 @@ some.code(); } ``` -## Meta Code Block +## Code Block Configuration + +### Line Number Disable line number `noline`: @@ -94,19 +96,62 @@ Disable line number `noline`: console.log('No line number!'); ``` +### Copy Button + Disable copy button `nocopy`: ```ts nocopy console.log('No copy button!'); ``` +### Lines Highlight + +Set highlight lines `lines="2,5,8-10,12,14..16,19,22...25"`: + +```ts lines="2,5,8-10,12,14..16,19,22...25" +import type { Parent } from 'mdast'; +import { visit } from 'unist-util-visit'; + +/** + * Markdown abstract syntax tree node definition. + * @see https://github.com/syntax-tree/mdast + */ +interface ContainerDirective extends Parent { + name: string; + attributes: Record; + value?: string; +} + +export default function remarkAdmonitions() { + return (tree: any) => { + visit(tree, (node: ContainerDirective) => { + if (node.type === 'containerDirective') { + // Change container html element to `