@readme/markdown 6.87.0 → 6.88.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (96) hide show
  1. package/README.md +81 -23
  2. package/components/Anchor.jsx +15 -26
  3. package/components/Callout/index.tsx +41 -0
  4. package/components/Callout/style.scss +11 -39
  5. package/components/CardsGrid/index.tsx +18 -0
  6. package/components/CardsGrid/style.scss +12 -0
  7. package/components/Code/index.tsx +75 -0
  8. package/components/Code/style.scss +54 -47
  9. package/components/CodeTabs/index.tsx +38 -0
  10. package/components/CodeTabs/style.scss +22 -30
  11. package/components/Embed/index.tsx +98 -0
  12. package/components/Embed/style.scss +59 -69
  13. package/components/Glossary/index.tsx +37 -0
  14. package/components/{GlossaryItem → Glossary}/style.scss +16 -18
  15. package/components/HTMLBlock/index.tsx +38 -0
  16. package/components/Heading/index.tsx +31 -0
  17. package/components/Heading/style.scss +9 -15
  18. package/components/Image/index.tsx +113 -0
  19. package/components/Image/style.scss +62 -64
  20. package/components/Table/index.tsx +20 -0
  21. package/components/Table/style.scss +17 -23
  22. package/components/TableOfContents/{index.jsx → index.tsx} +3 -8
  23. package/components/{index.js → index.ts} +2 -2
  24. package/dist/components/Callout/index.d.ts +9 -0
  25. package/dist/components/CardsGrid/index.d.ts +7 -0
  26. package/dist/components/Code/index.d.ts +11 -0
  27. package/dist/components/CodeTabs/index.d.ts +3 -0
  28. package/dist/components/Embed/index.d.ts +15 -0
  29. package/dist/components/Glossary/index.d.ts +10 -0
  30. package/dist/components/HTMLBlock/index.d.ts +7 -0
  31. package/dist/components/Heading/index.d.ts +8 -0
  32. package/dist/components/Image/index.d.ts +16 -0
  33. package/dist/components/Table/index.d.ts +7 -0
  34. package/dist/components/TableOfContents/index.d.ts +3 -0
  35. package/dist/components/index.d.ts +12 -0
  36. package/dist/contexts/GlossaryTerms.d.ts +7 -0
  37. package/dist/contexts/index.d.ts +5 -0
  38. package/dist/enums.d.ts +14 -0
  39. package/dist/errors/mdx-syntax-error.d.ts +5 -0
  40. package/dist/example/App.d.ts +4 -0
  41. package/dist/example/Doc.d.ts +3 -0
  42. package/dist/example/Form.d.ts +3 -0
  43. package/dist/example/Header.d.ts +3 -0
  44. package/dist/example/RenderError.d.ts +23 -0
  45. package/dist/example/Root.d.ts +3 -0
  46. package/dist/example/docs.d.ts +2 -0
  47. package/dist/example/index.d.ts +1 -0
  48. package/dist/index.d.ts +9 -0
  49. package/dist/lib/ast-processor.d.ts +12 -0
  50. package/dist/lib/compile.d.ts +8 -0
  51. package/dist/lib/hast.d.ts +3 -0
  52. package/dist/lib/index.d.ts +9 -0
  53. package/dist/lib/mdast.d.ts +2 -0
  54. package/dist/lib/mdx.d.ts +4 -0
  55. package/dist/lib/owlmoji.d.ts +4 -0
  56. package/dist/lib/plain.d.ts +6 -0
  57. package/dist/lib/run.d.ts +24 -0
  58. package/dist/main.css +2 -17
  59. package/dist/main.js +70726 -29897
  60. package/dist/main.node.js +90150 -50188
  61. package/dist/processor/compile/callout.d.ts +3 -0
  62. package/dist/processor/compile/code-tabs.d.ts +3 -0
  63. package/dist/processor/compile/compatibility.d.ts +53 -0
  64. package/dist/processor/compile/embed.d.ts +3 -0
  65. package/dist/processor/compile/gemoji.d.ts +3 -0
  66. package/dist/processor/compile/html-block.d.ts +3 -0
  67. package/dist/processor/compile/image.d.ts +3 -0
  68. package/dist/processor/compile/index.d.ts +2 -0
  69. package/dist/processor/compile/table.d.ts +0 -0
  70. package/dist/processor/compile/variable.d.ts +3 -0
  71. package/dist/processor/plugin/toc.d.ts +9 -0
  72. package/dist/processor/transform/callouts.d.ts +2 -0
  73. package/dist/processor/transform/code-tabs.d.ts +3 -0
  74. package/dist/processor/transform/div.d.ts +3 -0
  75. package/dist/processor/transform/embeds.d.ts +3 -0
  76. package/dist/processor/transform/gemoji+.d.ts +3 -0
  77. package/dist/processor/transform/images.d.ts +3 -0
  78. package/dist/processor/transform/index.d.ts +9 -0
  79. package/dist/processor/transform/inject-components.d.ts +7 -0
  80. package/dist/processor/transform/readme-components.d.ts +7 -0
  81. package/dist/processor/transform/readme-to-mdx.d.ts +3 -0
  82. package/dist/processor/transform/tables-to-jsx.d.ts +3 -0
  83. package/dist/processor/transform/variables.d.ts +5 -0
  84. package/dist/processor/utils.d.ts +77 -0
  85. package/package.json +93 -99
  86. package/styles/components.scss +1 -1
  87. package/components/Callout/index.jsx +0 -42
  88. package/components/Code/index.jsx +0 -103
  89. package/components/CodeTabs/index.jsx +0 -60
  90. package/components/Embed/index.jsx +0 -88
  91. package/components/GlossaryItem/index.jsx +0 -44
  92. package/components/HTMLBlock/index.jsx +0 -68
  93. package/components/Heading/index.jsx +0 -56
  94. package/components/Image/index.jsx +0 -107
  95. package/components/Style.jsx +0 -30
  96. package/components/Table/index.jsx +0 -19
package/README.md CHANGED
@@ -10,42 +10,100 @@ npm install --save @readme/markdown
10
10
 
11
11
  ## Usage
12
12
 
13
- By default, the updated markdown package exports a function which takes a string of [ReadMe-flavored markdown](https://docs.readme.com/rdmd/docs/syntax-extensions) and returns a tree of React components:
14
-
15
13
  ```jsx
16
14
  import React from 'react';
17
- import rdmd from '@readme/markdown';
15
+ import rmdx from '@readme/markdown';
18
16
 
19
- export default ({ body }) => <div className="markdown-body">{rdmd(body)}</div>;
17
+ export default ({ body }) => <div className="markdown-body">{run(compile(body))}</div>;
20
18
  ```
21
19
 
22
- ### Export Methods
20
+ ### API
21
+
22
+ #### `compile`
23
+
24
+ Compiles mdx to js. A wrapper around [`mdx.compile`](https://mdxjs.com/packages/mdx/#compilefile-options)
25
+
26
+ You usually only need this when calling `run` as well. It's been left as a seperate step as a potential caching opportunity.
27
+
28
+ ###### Parameters
29
+
30
+ - `string` (`string`) -- An mdx document
31
+ - `opts` ([`CompileOpts`](#compileopts), optional) -- configuration
32
+
33
+ ###### Returns
34
+
35
+ compiled code (`string`)
36
+
37
+ #### `run`
38
+
39
+ Run compiled code. A wrapper around [`mdx.run`](https://mdxjs.com/packages/mdx/#runcode-options)
40
+
41
+ > [!CAUTION]
42
+ > This `eval`'s JavaScript.
43
+
44
+ ###### Parameters
45
+
46
+ - `string` (`string`) -- A compiled mdx document
47
+ - `opts` (`RunOpts`, optional) -- configuration
48
+
49
+ ###### Returns
50
+
51
+ A module ([`RMDXModule`](#rmdxmodule)) of renderable components
52
+
53
+ #### `mdx`
54
+
55
+ Compiles an ast to mdx.
56
+
57
+ #### `mdast`
58
+
59
+ Parses mdx to an mdast.
60
+
61
+ #### `hast`
62
+
63
+ Parses mdx to an hast.
64
+
65
+ #### `plain`
66
+
67
+ > [!NOTE]
68
+ > unimplemented
69
+
70
+ #### `utils`
71
+
72
+ Additional defaults, helpers, components, etc.
73
+
74
+ ### `CompileOpts`
75
+
76
+ Extends [`CompileOptions`](https://mdxjs.com/packages/mdx/#compileoptions)
77
+
78
+ ###### Additional Properties
79
+
80
+ - `lazyImages` (`boolean`, optional) -- Load images lazily.
81
+ - `safeMode` (`boolean`, optional) -- Extract script tags from `HTMLBlock`s
82
+ - `components` (`Record<string, string>`, optional) -- An object of tag names to mdx.
83
+ - `copyButtons` (`Boolean`, optional) — Automatically insert a button to copy a block of text to the clipboard. Currently used on `<code>` elements.
84
+
85
+ ### `RunOpts`
86
+
87
+ Extends [`RunOptions`](https://mdxjs.com/packages/mdx/#runoptions)
23
88
 
24
- In addition to the default React processor, the package exports some other methods for transforming ReadMe-flavored markdown:
89
+ ###### Additional Properties
25
90
 
26
- | Export | Description | Arguments |
27
- | --------: | :--------------------------------------------- | :---------------- |
28
- | _`react`_ | _(default)_ returns a VDOM tree object | `text`, `options` |
29
- | _`md`_ | transform mdast in to ReadMe-flavored markdown | `tree`, `options` |
30
- | _`html`_ | transform markdown in to HTML | `text`, `options` |
31
- | _`mdast`_ | transform markdown to an mdast object | `text`, `options` |
32
- | _`hast`_ | transform markdown to HAST object | `text`, `options` |
33
- | _`plain`_ | transform markdown to plain text | `text`, `options` |
34
- | _`utils`_ | contexts, defaults, helpers, etc. | N/A |
91
+ - `components` (`Record<string, MDXModule>`, optional) -- An object of tag names to executed components.
92
+ - `imports` (`Record<string, unknown>`, optional) -- An object of modules to import.
93
+ - `terms` (`GlossaryTerm[]`, optional)
94
+ - `variables` (`Variables`, optional) -- An object containing [user variables}(https://github.com/readmeio/variable).
35
95
 
36
- ### Settings & Options
96
+ ### `RMDXModule`
37
97
 
38
- Each processor method takes an options object which you can use to adjust the output HTML or React tree. These options include:
98
+ ###### Properties
39
99
 
40
- - **`compatibilityMode`** Enable [compatibility features](https://github.com/readmeio/api-explorer/issues/668) from our old markdown engine.
41
- - **`copyButtons`** Automatically insert a button to copy a block of text to the clipboard. Currently used on `<code>` elements.
42
- - **`correctnewlines`** Render new line delimeters as `<br>` tags.
43
- - **`markdownOptions`** — Remark [parser options](https://github.com/remarkjs/remark/tree/main/packages/remark-stringify#processorusestringify-options).
44
- - **`safeMode`** — Render html blocks as `<pre>` elements. We normally allow all manner of html attributes that could potentially execute JavaScript.
100
+ - `default` (`() => MDXContent`) -- The mdx douments default export
101
+ - `toc` (`HastHeading[]`) -- A list of headings in the document
102
+ - `Toc` (`() => MDCContent`) -- A table of contents component
45
103
 
46
104
  ## Flavored Syntax
47
105
 
48
- Our old editor rendered "Magic Block" components from a custom, JSON-based syntax. To provide seamless backwards-compatibility, our new processor ships with built in support for parsing this old format, and transpiles it straight in to our new, flavored Markdown.
106
+ ~~Our old editor rendered "Magic Block" components from a custom, JSON-based syntax. To provide seamless backwards-compatibility, our new processor ships with built in support for parsing this old format, and transpiles it straight in to our new, flavored Markdown.~~
49
107
 
50
108
  We've also sprinkled a bit of our own syntactic sugar on top to let you supercharge your docs. [**Learn more about ReadMe's flavored syntax!**](https://docs.readme.com/rdmd/docs/syntax-extensions)
51
109
 
@@ -1,11 +1,11 @@
1
- const PropTypes = require('prop-types');
2
- const React = require('react');
1
+ import { string, node } from 'prop-types';
2
+ import React from 'react';
3
3
 
4
- const BaseUrlContext = require('../contexts/BaseUrl');
4
+ import BaseUrlContext from '../contexts/BaseUrl';
5
5
 
6
6
  // Nabbed from here:
7
7
  // https://github.com/readmeio/api-explorer/blob/0dedafcf71102feedaa4145040d3f57d79d95752/packages/api-explorer/src/lib/markdown/renderer.js#L52
8
- function getHref(href, baseUrl) {
8
+ export function getHref(href, baseUrl) {
9
9
  const [path, hash] = href.split('#');
10
10
  const hashStr = hash ? `#${hash}` : '';
11
11
 
@@ -18,7 +18,7 @@ function getHref(href, baseUrl) {
18
18
 
19
19
  const ref = path.match(/^ref:([-_a-zA-Z0-9#]*)$/);
20
20
  if (ref) {
21
- return `${base}/reference/${ref[1]}${hashStr}`;
21
+ return `${base}/reference-link/${ref[1]}${hashStr}`;
22
22
  }
23
23
 
24
24
  // we need to perform two matches for changelogs in case
@@ -49,7 +49,9 @@ function docLink(href) {
49
49
  }
50
50
 
51
51
  function Anchor(props) {
52
- const { baseUrl, children, href, target, title, ...attrs } = props;
52
+ const { children, href, target, title, ...attrs } = props;
53
+ const baseUrl = useContext(BaseUrlContext);
54
+
53
55
  return (
54
56
  // eslint-disable-next-line react/jsx-props-no-spreading
55
57
  <a {...attrs} href={getHref(href, baseUrl)} target={target} title={title} {...docLink(href)}>
@@ -59,12 +61,12 @@ function Anchor(props) {
59
61
  }
60
62
 
61
63
  Anchor.propTypes = {
62
- baseUrl: PropTypes.string,
63
- children: PropTypes.node.isRequired,
64
- download: PropTypes.string,
65
- href: PropTypes.string,
66
- target: PropTypes.string,
67
- title: PropTypes.string,
64
+ baseUrl: string,
65
+ children: node.isRequired,
66
+ download: string,
67
+ href: string,
68
+ target: string,
69
+ title: string,
68
70
  };
69
71
 
70
72
  Anchor.defaultProps = {
@@ -74,17 +76,4 @@ Anchor.defaultProps = {
74
76
  title: '',
75
77
  };
76
78
 
77
- const AnchorWithContext = props => (
78
- <BaseUrlContext.Consumer>{baseUrl => <Anchor baseUrl={baseUrl} {...props} />}</BaseUrlContext.Consumer>
79
- );
80
-
81
- AnchorWithContext.sanitize = sanitizeSchema => {
82
- // This is for our custom link formats
83
- sanitizeSchema.protocols.href.push('doc', 'target', 'ref', 'blog', 'changelog', 'page');
84
-
85
- return sanitizeSchema;
86
- };
87
-
88
- module.exports = AnchorWithContext;
89
-
90
- AnchorWithContext.getHref = getHref;
79
+ export default Anchor;
@@ -0,0 +1,41 @@
1
+ import * as React from 'react';
2
+
3
+ interface Props extends React.PropsWithChildren<React.HTMLAttributes<HTMLQuoteElement>> {
4
+ attributes?: {};
5
+ icon: string;
6
+ theme?: string;
7
+ empty?: boolean;
8
+ }
9
+
10
+ const themes: Record<string, string> = {
11
+ '\uD83D\uDCD8': 'info',
12
+ '\uD83D\uDEA7': 'warn',
13
+ '\u26A0\uFE0F': 'warn',
14
+ '\uD83D\uDC4D': 'okay',
15
+ '\u2705': 'okay',
16
+ '\u2757\uFE0F': 'error',
17
+ '\u2757': 'error',
18
+ '\uD83D\uDED1': 'error',
19
+ '\u2049\uFE0F': 'error',
20
+ '\u203C\uFE0F': 'error',
21
+ '\u2139\uFE0F': 'info',
22
+ '\u26A0': 'warn',
23
+ };
24
+
25
+ const Callout = (props: Props) => {
26
+ const { attributes, children, icon, empty } = props;
27
+ let theme = props.theme || themes[icon] || 'default';
28
+
29
+ return (
30
+ // @ts-ignore
31
+ <blockquote {...attributes} className={`callout callout_${theme}`} theme={icon}>
32
+ <h3 className={`callout-heading${empty ? ' empty' : ''}`}>
33
+ <span className="callout-icon">{icon}</span>
34
+ {empty || React.Children.toArray(children)[0]}
35
+ </h3>
36
+ {React.Children.toArray(children).slice(1)}
37
+ </blockquote>
38
+ );
39
+ };
40
+
41
+ export default Callout;
@@ -1,19 +1,16 @@
1
- /* stylelint-disable no-descending-specificity */
2
- /* stylelint-disable font-family-no-missing-generic-family-keyword */
3
- /* stylelint-disable order/properties-alphabetical-order */
4
- /* stylelint-disable order/order */
5
1
  @mixin callout($l-offset: 1.33rem) {
6
2
  --background: #{lighten(#dfe2e5, 8.75%)};
7
3
  --border: #{lighten(#6a737d, 12.5%)};
8
4
 
9
- background: var(--background);
10
- border-color: var(--border);
11
- color: var(--text);
12
- padding: $l-offset;
5
+ & {
6
+ background: var(--background);
7
+ border-color: var(--border);
8
+ color: var(--text);
9
+ padding: $l-offset;
10
+ }
13
11
 
14
12
  &_info {
15
13
  $color: #46b8da;
16
-
17
14
  --background: #e3edf2;
18
15
  --title: #{$color};
19
16
  --border: #{lighten($color, 5%)}; // should be #5bc0de
@@ -22,7 +19,6 @@
22
19
  &_warn,
23
20
  &_warning {
24
21
  $color: #eea236;
25
-
26
22
  --background: #fcf8f2;
27
23
  --title: #{$color};
28
24
  --border: #{lighten($color, 5%)};
@@ -32,7 +28,6 @@
32
28
  &_okay,
33
29
  &_success {
34
30
  $color: #489e49;
35
-
36
31
  --background: #f3f8f3;
37
32
  --title: #{$color};
38
33
  --border: #{lighten($color, 5%)}; // should be #50af51
@@ -41,7 +36,6 @@
41
36
  &_err,
42
37
  &_error {
43
38
  $color: #d43f3a;
44
-
45
39
  --background: #fdf7f7;
46
40
  --title: #{$color};
47
41
  --border: #{lighten($color, 5%)}; // should be #d9534f
@@ -51,7 +45,6 @@
51
45
  margin-left: $l-offset;
52
46
  position: relative;
53
47
  }
54
-
55
48
  ul,
56
49
  ol {
57
50
  padding-left: 1.3em;
@@ -60,11 +53,9 @@
60
53
  a {
61
54
  color: inherit;
62
55
  }
63
-
64
56
  hr {
65
57
  border-color: var(--border, var(--markdown-edge, #eee));
66
58
  }
67
-
68
59
  blockquote {
69
60
  color: var(--text);
70
61
  border-color: var(--border);
@@ -74,10 +65,6 @@
74
65
 
75
66
  .callout-heading {
76
67
  color: var(--title, --text);
77
- font-size: 1.25em; // match h3
78
- font-family: var(--markdown-title-font); // match h3
79
- font-weight: var(--markdown-title-weight, 600); // match h3
80
- line-height: 1.25; // match h3
81
68
  margin-bottom: calc(#{$l-offset} * 0.5);
82
69
 
83
70
  &:only-child {
@@ -87,18 +74,15 @@
87
74
  &.empty {
88
75
  float: left;
89
76
  margin-top: calc(#{$l-offset} * 0.5);
90
-
91
77
  .callout-icon {
92
78
  line-height: 0;
93
79
  }
94
80
  }
95
-
96
81
  > * {
97
82
  color: inherit;
98
83
  margin: 0;
99
84
  }
100
-
101
- &::before {
85
+ &:before {
102
86
  position: absolute;
103
87
  right: 100%;
104
88
  width: 2.4em;
@@ -106,24 +90,20 @@
106
90
  font: normal normal normal 1em/1 FontAwesome;
107
91
  }
108
92
  }
109
-
110
93
  .callout-icon {
111
94
  float: left;
112
95
  margin-left: calc(-#{$l-offset} - 0.5em);
113
96
  margin-right: -0.25rem;
114
97
  }
115
98
  }
116
-
117
- @mixin callout-custom-icons($R: callout) {
99
+ @mixin calloutCustomIcons($R: callout) {
118
100
  --emoji: 1em;
119
- --icon-font: fontawesome;
120
-
101
+ --icon-font: FontAwesome;
121
102
  &-icon {
122
103
  font-size: var(--emoji, 0);
123
104
  color: var(--icon-color, inherit) !important;
124
105
  }
125
-
126
- &-icon::before {
106
+ &-icon:before {
127
107
  content: var(--icon);
128
108
  font-family: var(--icon-font);
129
109
  font-size: var(--icon-size, 1rem);
@@ -136,30 +116,24 @@
136
116
  -webkit-font-smoothing: antialiased;
137
117
  -moz-osx-font-smoothing: grayscale;
138
118
  }
139
-
140
119
  @at-root .rdmdCallouts--useIconFont & {
141
120
  --emoji: unset;
142
-
143
121
  &_okay {
144
122
  /* thumbs up */
145
123
  --icon: '\f164';
146
124
  }
147
-
148
125
  &_info {
149
126
  /* info circle */
150
127
  --icon: '\f05a';
151
128
  }
152
-
153
129
  &_warn {
154
130
  /* warning triangle */
155
131
  --icon: '\f071';
156
132
  }
157
-
158
133
  &_error {
159
134
  /* warning circle */
160
135
  --icon: '\f06a';
161
136
  }
162
-
163
137
  &_default {
164
138
  /* warning circle */
165
139
  --emoji: 1rem;
@@ -172,9 +146,7 @@
172
146
  // bump specificity
173
147
  @include callout;
174
148
  }
175
-
176
- @include callout-custom-icons;
177
-
149
+ @include calloutCustomIcons;
178
150
  border-top-right-radius: var(--markdown-radius);
179
151
  border-bottom-right-radius: var(--markdown-radius);
180
152
  }
@@ -0,0 +1,18 @@
1
+ import React from 'react';
2
+
3
+ import './style.scss';
4
+
5
+ const Card = ({ children }) => <div className="Card">{children}</div>;
6
+
7
+ const CardsGrid = ({ columns = 2, children }) => {
8
+ columns = columns >= 2 ? columns : 2;
9
+ return (
10
+ <div className="CardsGrid" style={{ gridTemplateColumns: `repeat(${columns}, 1fr)` }}>
11
+ {React.Children.map(children, e => (
12
+ <Card>{e}</Card>
13
+ ))}
14
+ </div>
15
+ );
16
+ };
17
+
18
+ export default CardsGrid;
@@ -0,0 +1,12 @@
1
+ .CardsGrid {
2
+ display: grid;
3
+ gap: 20px;
4
+
5
+ .Card {
6
+ padding: 10px;
7
+ backdrop-filter: blur(20px);
8
+ border: 1px solid rgba(black, 0.1);
9
+ border-radius: 5px;
10
+ box-shadow: 0 1px 2px #{rgba(black, 0.05)}, 0 2px 5px #{rgba(black, 0.02)};
11
+ }
12
+ }
@@ -0,0 +1,75 @@
1
+ import copy from 'copy-to-clipboard';
2
+ import React, { createRef } from 'react';
3
+
4
+ // Only load CodeMirror in the browser, for SSR
5
+ // apps. Necessary because of people like this:
6
+ // https://github.com/codemirror/CodeMirror/issues/3701#issuecomment-164904534
7
+ let syntaxHighlighter;
8
+ let canonicalLanguage = _ => '';
9
+
10
+ if (typeof window !== 'undefined') {
11
+ import('@readme/syntax-highlighter').then(module => {
12
+ syntaxHighlighter = module.default;
13
+ canonicalLanguage = module.canonical;
14
+ });
15
+ }
16
+
17
+ function CopyCode({ codeRef, rootClass = 'rdmd-code-copy', className = '' }) {
18
+ const copyClass = `${rootClass}_copied`;
19
+ const button = createRef<HTMLButtonElement>();
20
+
21
+ const copier = () => {
22
+ const code = codeRef.current.textContent;
23
+
24
+ if (copy(code)) {
25
+ const el = button.current;
26
+ el.classList.add(copyClass);
27
+
28
+ setTimeout(() => el.classList.remove(copyClass), 1500);
29
+ }
30
+ };
31
+
32
+ return <button ref={button} aria-label="Copy Code" className={`${rootClass} ${className}`} onClick={copier} />;
33
+ }
34
+
35
+ interface CodeProps {
36
+ children?: string[] | string;
37
+ copyButtons?: boolean;
38
+ lang?: string;
39
+ meta?: string;
40
+ theme?: string;
41
+ value?: string;
42
+ }
43
+
44
+ const Code = (props: CodeProps) => {
45
+ const { children, copyButtons, lang, theme, value } = props;
46
+
47
+ const language = canonicalLanguage(lang);
48
+
49
+ const codeRef = createRef<HTMLElement>();
50
+
51
+ const codeOpts = {
52
+ inline: !lang,
53
+ tokenizeVariables: true,
54
+ dark: theme === 'dark',
55
+ };
56
+
57
+ const code = value ?? (Array.isArray(children) ? children[0] : children) ?? '';
58
+ const highlightedCode = syntaxHighlighter && code ? syntaxHighlighter(code, language, codeOpts, { mdx: true }) : code;
59
+
60
+ return (
61
+ <>
62
+ {copyButtons && <CopyCode className="fa" codeRef={codeRef} />}
63
+ <code
64
+ ref={codeRef}
65
+ className={['rdmd-code', `lang-${language}`, `theme-${theme}`].join(' ')}
66
+ data-lang={language}
67
+ suppressHydrationWarning={true}
68
+ >
69
+ {highlightedCode}
70
+ </code>
71
+ </>
72
+ );
73
+ };
74
+
75
+ export default Code;
@@ -1,16 +1,16 @@
1
- /* stylelint-disable no-duplicate-selectors */
2
- /* stylelint-disable no-descending-specificity */
3
- /* stylelint-disable font-family-no-missing-generic-family-keyword */
4
- /* stylelint-disable declaration-property-value-disallowed-list */
5
- /* stylelint-disable scss/selector-no-redundant-nesting-selector */
6
- /* stylelint-disable order/properties-alphabetical-order */
7
- @mixin gfm-code-base-styles($background: #f6f8fa, $background-dark: #242e34, $text: inherit) {
1
+ @mixin gfmCodeBaseStyles($background: #f6f8fa, $background-dark: #242e34, $text: inherit) {
8
2
  --font-size: 90%;
9
3
 
10
4
  code,
11
5
  kbd,
12
6
  pre {
13
- font-family: SFMono-Regular, Consolas, 'Liberation Mono', Menlo, Courier, monospace;
7
+ font-family:
8
+ SFMono-Regular,
9
+ Consolas,
10
+ Liberation Mono,
11
+ Menlo,
12
+ Courier,
13
+ monospace;
14
14
  font-family: var(--md-code-font, SFMono-Regular, Consolas, Liberation Mono, Menlo, Courier, monospace);
15
15
  font-size: 1em;
16
16
  }
@@ -23,7 +23,6 @@
23
23
  pre {
24
24
  margin-bottom: 0;
25
25
  margin-top: 0;
26
- word-wrap: normal;
27
26
  }
28
27
 
29
28
  code {
@@ -40,6 +39,10 @@
40
39
  }
41
40
  }
42
41
 
42
+ pre {
43
+ word-wrap: normal;
44
+ }
45
+
43
46
  pre > code {
44
47
  background: 0 0;
45
48
  border: 0;
@@ -97,29 +100,32 @@
97
100
  }
98
101
  }
99
102
 
100
- @mixin copy-code-button {
103
+ @mixin copyCodeButton {
101
104
  button.rdmd-code-copy {
102
- appearance: unset;
103
- background: inherit;
104
- background: var(--md-code-background, inherit);
105
- border: none;
106
- border-radius: 3px;
107
- box-shadow:
108
- inset 0 0 0 1px rgba(#aaa, 0.66),
109
- -1px 2px 6px -3px rgba(black, 0.1);
110
- color: inherit;
111
- color: var(--md-code-text, inherit);
112
- cursor: copy;
113
105
  display: none !important; // hide by default
114
- font: inherit;
115
- margin: 0.5em 0.6em 0 0;
116
- outline: none !important;
117
- padding: 0.25em 0.7em;
118
- transition: 0.15s ease-out;
106
+
107
+ & {
108
+ -webkit-appearance: unset;
109
+ margin: 0.5em 0.6em 0 0;
110
+ padding: 0.25em 0.7em;
111
+ cursor: copy;
112
+ font: inherit;
113
+ color: inherit;
114
+ color: var(--md-code-text, inherit);
115
+ border: none;
116
+ border-radius: 3px;
117
+ outline: none !important;
118
+ background: inherit;
119
+ background: var(--md-code-background, inherit);
120
+ box-shadow:
121
+ inset 0 0 0 1px rgba(#aaa, 0.66),
122
+ -1px 2px 6px -3px rgba(black, 0.1);
123
+ transition: 0.15s ease-out;
124
+ }
119
125
 
120
126
  &:not(:hover) {
121
- &::before,
122
- &::after {
127
+ &:before,
128
+ &:after {
123
129
  opacity: 0.66;
124
130
  }
125
131
  }
@@ -137,41 +143,42 @@
137
143
  inset 0 0 0 1px rgba(#8b8b8b, 0.5),
138
144
  inset 1px 4px 6px -2px rgba(0, 0, 0, 0.175);
139
145
 
140
- &::before,
141
- &::after {
146
+ &:before,
147
+ &:after {
142
148
  opacity: 0.75;
143
149
  }
144
150
  }
145
151
 
146
- &::before,
147
- &::after {
152
+ &:before,
153
+ &:after {
148
154
  display: inline-block;
149
155
  font:
150
156
  normal normal normal 1em/1 'Font Awesome 5 Free',
151
- FontAwesome;
152
- font-family: ReadMe-Icons;
153
- font-feature-settings: 'liga';
154
- font-variant-ligatures: discretionary-ligatures;
155
- line-height: 2;
157
+ 'FontAwesome';
156
158
  text-rendering: auto;
157
159
  -webkit-font-smoothing: antialiased;
160
+
161
+ line-height: 2;
162
+ font-family: 'ReadMe-Icons';
163
+ font-variant-ligatures: discretionary-ligatures;
164
+ font-feature-settings: 'liga';
158
165
  }
159
166
 
160
- &::before {
167
+ &:before {
161
168
  content: '\e6c9';
162
169
  font-weight: 800;
163
170
  transition: 0.3s 0.15s ease;
164
171
  }
165
172
 
166
- &::after {
173
+ &:after {
167
174
  // @todo why are these !important @rafe, you dumbell?
168
175
  content: '\e942' !important;
169
176
  font-weight: 900 !important;
170
- left: 50%;
171
- opacity: 0 !important;
172
177
  position: absolute;
173
178
  top: 50%;
179
+ left: 50%;
174
180
  transform: translate(-50%, -50%) scale(0.33);
181
+ opacity: 0 !important;
175
182
  transition: 0.3s 0s ease;
176
183
  }
177
184
 
@@ -185,16 +192,16 @@
185
192
  opacity: 1;
186
193
  }
187
194
 
188
- &::before {
189
- opacity: 0 !important;
195
+ &:before {
190
196
  transition: 0.3s 0s ease;
191
197
  transform: scale(0.33);
198
+ opacity: 0 !important;
192
199
  }
193
200
 
194
- &::after {
195
- opacity: 1 !important;
201
+ &:after {
196
202
  transition: 0.3s 0.15s ease;
197
203
  transform: translate(-50%, -50%) scale(1);
204
+ opacity: 1 !important;
198
205
  }
199
206
  }
200
207
  }
@@ -245,6 +252,6 @@
245
252
 
246
253
  .markdown-body {
247
254
  // --md-code-background: #F6F8FA;
248
- @include gfm-code-base-styles;
249
- @include copy-code-button;
255
+ @include gfmCodeBaseStyles;
256
+ @include copyCodeButton;
250
257
  }