@redocly/theme 0.45.11 → 0.46.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.
- package/lib/components/CodeBlock/CodeBlock.d.ts +2 -1
- package/lib/components/CodeBlock/CodeBlock.js +33 -9
- package/lib/components/CodeBlock/CodeBlockContainer.d.ts +1 -0
- package/lib/components/CodeBlock/CodeBlockContainer.js +242 -68
- package/lib/components/CodeBlock/variables.js +43 -0
- package/lib/components/Link/Link.js +1 -1
- package/lib/core/hooks/use-theme-config.js +1 -1
- package/lib/core/hooks/use-theme-hooks.js +1 -0
- package/lib/core/types/hooks.d.ts +7 -0
- package/lib/core/utils/add-line-numbers.d.ts +6 -0
- package/lib/core/utils/add-line-numbers.js +18 -0
- package/lib/core/utils/index.d.ts +1 -1
- package/lib/core/utils/index.js +1 -1
- package/lib/markdoc/components/Cards/Card.d.ts +2 -1
- package/lib/markdoc/components/Cards/Card.js +2 -2
- package/lib/markdoc/components/Cards/CardIcon.d.ts +2 -1
- package/lib/markdoc/components/Cards/CardIcon.js +3 -3
- package/lib/markdoc/tags/card.js +5 -0
- package/package.json +1 -3
- package/src/components/CodeBlock/CodeBlock.tsx +21 -7
- package/src/components/CodeBlock/CodeBlockContainer.tsx +243 -68
- package/src/components/CodeBlock/variables.ts +43 -0
- package/src/components/Link/Link.tsx +1 -1
- package/src/core/hooks/use-theme-config.ts +1 -1
- package/src/core/hooks/use-theme-hooks.ts +1 -0
- package/src/core/types/hooks.ts +11 -0
- package/src/core/utils/add-line-numbers.ts +16 -0
- package/src/core/utils/index.ts +1 -1
- package/src/markdoc/components/Cards/Card.tsx +10 -1
- package/src/markdoc/components/Cards/CardIcon.tsx +5 -4
- package/src/markdoc/tags/card.ts +5 -0
- package/lib/core/utils/highlight.d.ts +0 -35
- package/lib/core/utils/highlight.js +0 -129
- package/src/core/utils/highlight.ts +0 -125
|
@@ -7,8 +7,8 @@ exports.CardIcon = CardIcon;
|
|
|
7
7
|
const react_1 = __importDefault(require("react"));
|
|
8
8
|
const styled_components_1 = __importDefault(require("styled-components"));
|
|
9
9
|
const InlineSvg_1 = require("../../../markdoc/components/InlineSvg/InlineSvg");
|
|
10
|
-
function CardIcon({ variant, src, rawContent }) {
|
|
11
|
-
return (react_1.default.createElement(CardIconWrapper, { "$variant": variant }, rawContent ? react_1.default.createElement(CardSvg, { fileRawContent: rawContent }) : react_1.default.createElement(CardImg, { src: src })));
|
|
10
|
+
function CardIcon({ variant, src, rawContent, position }) {
|
|
11
|
+
return (react_1.default.createElement(CardIconWrapper, { "$variant": variant, "$position": position }, rawContent ? react_1.default.createElement(CardSvg, { fileRawContent: rawContent }) : react_1.default.createElement(CardImg, { src: src })));
|
|
12
12
|
}
|
|
13
13
|
const CardImg = styled_components_1.default.img `
|
|
14
14
|
width: var(--card-icon-width);
|
|
@@ -29,7 +29,7 @@ const CardSvg = (0, styled_components_1.default)(InlineSvg_1.InlineSvg) `
|
|
|
29
29
|
`;
|
|
30
30
|
const CardIconWrapper = styled_components_1.default.div `
|
|
31
31
|
display: flex;
|
|
32
|
-
align-
|
|
32
|
+
align-self: ${({ $position }) => ($position ? $position : 'auto')};
|
|
33
33
|
justify-content: center;
|
|
34
34
|
min-width: var(--card-icon-width);
|
|
35
35
|
min-height: var(--card-icon-height);
|
package/lib/markdoc/tags/card.js
CHANGED
|
@@ -28,6 +28,11 @@ exports.card = {
|
|
|
28
28
|
matches: ['start', 'end'],
|
|
29
29
|
default: 'start',
|
|
30
30
|
},
|
|
31
|
+
iconPosition: {
|
|
32
|
+
type: String,
|
|
33
|
+
matches: ['auto', 'start', 'center', 'end'],
|
|
34
|
+
default: 'auto',
|
|
35
|
+
},
|
|
31
36
|
layout: {
|
|
32
37
|
type: String,
|
|
33
38
|
matches: ['horizontal', 'combined', 'vertical'],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@redocly/theme",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.46.0",
|
|
4
4
|
"description": "Shared UI components lib",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"theme",
|
|
@@ -27,7 +27,6 @@
|
|
|
27
27
|
"peerDependencies": {
|
|
28
28
|
"@markdoc/markdoc": "0.4.0",
|
|
29
29
|
"lodash.throttle": "^4.1.1",
|
|
30
|
-
"prismjs": "^1.28.0",
|
|
31
30
|
"react": "^17.0.0 || ^18.0.0",
|
|
32
31
|
"react-dom": "^17.0.0 || ^18.0.0",
|
|
33
32
|
"react-router-dom": "^6.21.1",
|
|
@@ -44,7 +43,6 @@
|
|
|
44
43
|
"@types/jest-when": "3.5.5",
|
|
45
44
|
"@types/lodash.throttle": "4.1.9",
|
|
46
45
|
"@types/node": "18.19.3",
|
|
47
|
-
"@types/prismjs": "1.26.4",
|
|
48
46
|
"@types/react": "18.3.9",
|
|
49
47
|
"@types/react-dom": "18.2.25",
|
|
50
48
|
"@types/styled-components": "5.1.34",
|
|
@@ -4,8 +4,8 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { CodeBlockControlsProps } from '@redocly/theme/components/CodeBlock/CodeBlockControls';
|
|
5
5
|
import type { ReportDialogProps } from '@redocly/theme/components/Feedback/ReportDialog';
|
|
6
6
|
|
|
7
|
-
import {
|
|
8
|
-
import { useModalScrollLock, useReportDialog } from '@redocly/theme/core/hooks';
|
|
7
|
+
import { addLineNumbers } from '@redocly/theme/core/utils';
|
|
8
|
+
import { useModalScrollLock, useReportDialog, useThemeHooks } from '@redocly/theme/core/hooks';
|
|
9
9
|
import { ReportDialog } from '@redocly/theme/components/Feedback/ReportDialog';
|
|
10
10
|
import { CodeBlockContainer } from '@redocly/theme/components/CodeBlock/CodeBlockContainer';
|
|
11
11
|
import { CodeBlockControls } from '@redocly/theme/components/CodeBlock/CodeBlockControls';
|
|
@@ -26,6 +26,7 @@ export type CodeBlockProps = {
|
|
|
26
26
|
codeBlockMaxHeight?: string;
|
|
27
27
|
hideCodeColors?: boolean;
|
|
28
28
|
wrapContents?: boolean;
|
|
29
|
+
[key: string]: unknown;
|
|
29
30
|
};
|
|
30
31
|
|
|
31
32
|
type UnstableExternalCodeSample = {
|
|
@@ -64,12 +65,25 @@ export function CodeBlock({
|
|
|
64
65
|
hideCodeColors,
|
|
65
66
|
wrapContents = false,
|
|
66
67
|
children,
|
|
68
|
+
...rest
|
|
67
69
|
}: React.PropsWithChildren<CodeBlockProps>): JSX.Element {
|
|
68
70
|
const [sourceCode, setSourceCode] = useState<string>(
|
|
69
71
|
(source || externalSource?.sample?.get?.(externalSource)) ?? '',
|
|
70
72
|
);
|
|
73
|
+
const { useCodeHighlight } = useThemeHooks();
|
|
74
|
+
const { highlight } = useCodeHighlight() || {};
|
|
71
75
|
|
|
72
|
-
const highlightedCode = highlightedHtml
|
|
76
|
+
const highlightedCode = highlightedHtml
|
|
77
|
+
? withLineNumbers
|
|
78
|
+
? addLineNumbers(highlightedHtml, startLineNumber)
|
|
79
|
+
: highlightedHtml
|
|
80
|
+
: children
|
|
81
|
+
? null
|
|
82
|
+
: highlight?.(sourceCode, lang, {
|
|
83
|
+
withLineNumbers,
|
|
84
|
+
startLineNumber,
|
|
85
|
+
highlight: rest['data-highlight'] as string | undefined,
|
|
86
|
+
});
|
|
73
87
|
|
|
74
88
|
// The same initial value should be returned for ssr and frontend to avoid issues
|
|
75
89
|
// Because we don't have session storage in ssr and can't get the security details there
|
|
@@ -102,13 +116,11 @@ export function CodeBlock({
|
|
|
102
116
|
/>
|
|
103
117
|
<CodeBlockContainer
|
|
104
118
|
ref={codeBlockRef}
|
|
105
|
-
|
|
119
|
+
withLineNumbers={withLineNumbers}
|
|
106
120
|
dangerouslySetInnerHTML={
|
|
107
121
|
highlightedCode
|
|
108
122
|
? {
|
|
109
|
-
__html:
|
|
110
|
-
? addLineNumbers(highlightedCode, startLineNumber)
|
|
111
|
-
: highlightedCode,
|
|
123
|
+
__html: highlightedCode,
|
|
112
124
|
}
|
|
113
125
|
: undefined
|
|
114
126
|
}
|
|
@@ -142,4 +154,6 @@ const CodeBlockWrapper = styled.div`
|
|
|
142
154
|
border-radius: var(--border-radius);
|
|
143
155
|
background-color: var(--code-block-bg-color);
|
|
144
156
|
margin: 0 0 var(--spacing-sm);
|
|
157
|
+
|
|
158
|
+
--md-pre-margin: 0;
|
|
145
159
|
`;
|
|
@@ -9,6 +9,7 @@ export type CodeBlockContainerProps = PropsWithChildren<{
|
|
|
9
9
|
wrapContents?: boolean;
|
|
10
10
|
ref?: (instance: HTMLPreElement | null) => void;
|
|
11
11
|
className?: string;
|
|
12
|
+
withLineNumbers?: boolean;
|
|
12
13
|
dangerouslySetInnerHTML?: {
|
|
13
14
|
__html: string;
|
|
14
15
|
};
|
|
@@ -42,95 +43,269 @@ const CodeBlockContainerComponent = styled.pre<CodeBlockContainerProps>`
|
|
|
42
43
|
font-family: var(--code-block-font-family);
|
|
43
44
|
}
|
|
44
45
|
}
|
|
45
|
-
/**
|
|
46
|
-
* Based on prism-dark.css
|
|
47
|
-
*/
|
|
48
|
-
code[class*='language-'],
|
|
49
|
-
pre[class*='language-'] {
|
|
50
|
-
text-shadow: 0 -0.1em 0.2em black;
|
|
51
|
-
text-align: left;
|
|
52
|
-
word-spacing: normal;
|
|
53
|
-
word-break: normal;
|
|
54
|
-
word-wrap: normal;
|
|
55
|
-
line-height: 1.5;
|
|
56
|
-
|
|
57
|
-
-moz-tab-size: 4;
|
|
58
|
-
-o-tab-size: 4;
|
|
59
|
-
tab-size: 4;
|
|
60
|
-
|
|
61
|
-
-webkit-hyphens: none;
|
|
62
|
-
-moz-hyphens: none;
|
|
63
|
-
-ms-hyphens: none;
|
|
64
|
-
hyphens: none;
|
|
65
|
-
}
|
|
66
46
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
47
|
+
.highlighted {
|
|
48
|
+
background: var(--layer-color-hover);
|
|
49
|
+
margin-left: calc(var(--spacing-sm) * -1);
|
|
50
|
+
padding-left: var(--spacing-sm);
|
|
51
|
+
width: calc(100% + var(--spacing-sm));
|
|
52
|
+
display: inline-block;
|
|
53
|
+
|
|
54
|
+
&.error {
|
|
55
|
+
background: var(--color-raspberry-2);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
&.warning {
|
|
59
|
+
background: var(--color-carrot-2);
|
|
71
60
|
}
|
|
72
61
|
}
|
|
73
62
|
|
|
74
|
-
|
|
63
|
+
[data-line-number] {
|
|
64
|
+
&::before {
|
|
65
|
+
content: attr(data-line-number);
|
|
66
|
+
display: inline-block;
|
|
67
|
+
min-width: 2em;
|
|
68
|
+
padding-right: 0.8em;
|
|
69
|
+
text-align: right;
|
|
70
|
+
pointer-events: none;
|
|
71
|
+
user-select: none;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
75
74
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
75
|
+
.has-diff {
|
|
76
|
+
> .line {
|
|
77
|
+
&::before {
|
|
78
|
+
content: attr(data-line-number) ' ';
|
|
79
|
+
display: inline-block;
|
|
80
|
+
padding-right: 0.4em;
|
|
81
|
+
text-align: right;
|
|
82
|
+
pointer-events: none;
|
|
83
|
+
user-select: none;
|
|
84
|
+
}
|
|
85
|
+
&[data-line-number]::before {
|
|
86
|
+
min-width: 3em;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
80
89
|
}
|
|
81
90
|
|
|
82
|
-
.
|
|
83
|
-
|
|
91
|
+
.diff {
|
|
92
|
+
margin-left: calc(var(--spacing-sm) * -1);
|
|
93
|
+
padding-left: var(--spacing-sm);
|
|
94
|
+
width: calc(100% + var(--spacing-sm));
|
|
95
|
+
display: inline-block;
|
|
96
|
+
|
|
97
|
+
&.add {
|
|
98
|
+
background: var(--color-grass-2);
|
|
99
|
+
&:before {
|
|
100
|
+
content: attr(data-line-number) ' +';
|
|
101
|
+
color: var(--color-grass-7);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
&.remove {
|
|
105
|
+
background: var(--color-raspberry-2);
|
|
106
|
+
|
|
107
|
+
&:before {
|
|
108
|
+
content: attr(data-line-number) ' -';
|
|
109
|
+
color: var(--color-raspberry-7);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
84
112
|
}
|
|
85
113
|
|
|
86
|
-
.
|
|
87
|
-
|
|
114
|
+
.highlighted-word {
|
|
115
|
+
background: var(--color-carrot-2);
|
|
116
|
+
border: 1px solid var(--color-carrot-5);
|
|
117
|
+
border-radius: 4px;
|
|
88
118
|
}
|
|
89
119
|
|
|
90
|
-
.
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
120
|
+
.has-focused {
|
|
121
|
+
.line {
|
|
122
|
+
margin-left: calc(var(--spacing-sm) * -1);
|
|
123
|
+
padding-left: var(--spacing-sm);
|
|
124
|
+
width: calc(100% + var(--spacing-sm));
|
|
125
|
+
display: inline-block;
|
|
126
|
+
|
|
127
|
+
opacity: 0.7;
|
|
128
|
+
filter: blur(0.095rem);
|
|
129
|
+
transition:
|
|
130
|
+
filter 0.35s,
|
|
131
|
+
opacity 0.35s;
|
|
132
|
+
&.focused {
|
|
133
|
+
opacity: 1;
|
|
134
|
+
filter: blur(0);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
&:hover {
|
|
139
|
+
.line {
|
|
140
|
+
opacity: 1;
|
|
141
|
+
filter: blur(0);
|
|
142
|
+
}
|
|
100
143
|
}
|
|
101
144
|
}
|
|
102
145
|
|
|
103
|
-
|
|
104
|
-
|
|
146
|
+
/*
|
|
147
|
+
* Tree view styles
|
|
148
|
+
*/
|
|
149
|
+
|
|
150
|
+
.shiki {
|
|
151
|
+
&.theme {
|
|
152
|
+
display: inline-block;
|
|
153
|
+
width: 100%;
|
|
154
|
+
|
|
155
|
+
&.tree-view-root {
|
|
156
|
+
display: flex;
|
|
157
|
+
flex-direction: column;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
105
160
|
}
|
|
106
161
|
|
|
107
|
-
.
|
|
108
|
-
|
|
109
|
-
font-weight: bold;
|
|
162
|
+
. .line {
|
|
163
|
+
display: inline-block;
|
|
110
164
|
}
|
|
111
165
|
|
|
112
|
-
.
|
|
113
|
-
|
|
166
|
+
.tree-view-line {
|
|
167
|
+
display: flex;
|
|
114
168
|
}
|
|
115
169
|
|
|
116
|
-
.
|
|
117
|
-
|
|
170
|
+
.tree-view-branch {
|
|
171
|
+
color: var(--code-block-tree-view-lines-color);
|
|
118
172
|
}
|
|
119
173
|
|
|
120
|
-
.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
pointer-events: none;
|
|
128
|
-
user-select: none;
|
|
174
|
+
.tree-view-file {
|
|
175
|
+
display: inline-flex;
|
|
176
|
+
&::before {
|
|
177
|
+
content: '\\ea01';
|
|
178
|
+
margin-left: 0.3rem;
|
|
179
|
+
margin-right: 0.5rem;
|
|
180
|
+
font-family: 'TreeViewIcons';
|
|
129
181
|
}
|
|
130
|
-
}
|
|
131
182
|
|
|
132
|
-
|
|
133
|
-
|
|
183
|
+
&.no-file {
|
|
184
|
+
&::before {
|
|
185
|
+
content: '';
|
|
186
|
+
margin-right: 0;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
&.ext-folder {
|
|
191
|
+
&::before {
|
|
192
|
+
content: '\\ea02';
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
&.ext-img,
|
|
197
|
+
&.ext-png,
|
|
198
|
+
&.ext-jpg,
|
|
199
|
+
&.ext-jpeg,
|
|
200
|
+
&.ext-gif,
|
|
201
|
+
&.ext-svg {
|
|
202
|
+
&::before {
|
|
203
|
+
content: '\\ea03';
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
&.ext-mp2,
|
|
208
|
+
&.ext-mp3,
|
|
209
|
+
&.ext-wav,
|
|
210
|
+
&.ext-ogg,
|
|
211
|
+
&.ext-flac {
|
|
212
|
+
&::before {
|
|
213
|
+
content: '\\ea04';
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
&.ext-mp4,
|
|
218
|
+
&.ext-mkv,
|
|
219
|
+
&.ext-avi,
|
|
220
|
+
&.ext-mov,
|
|
221
|
+
&.ext-wmv,
|
|
222
|
+
&.ext-flv {
|
|
223
|
+
&::before {
|
|
224
|
+
content: '\\ea05';
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
&.ext-txt,
|
|
229
|
+
&.ext-text,
|
|
230
|
+
&.ext-md,
|
|
231
|
+
&.ext-markdown {
|
|
232
|
+
&::before {
|
|
233
|
+
content: '\\ea06';
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
&.ext-js,
|
|
238
|
+
&.ext-ts,
|
|
239
|
+
&.ext-jsx,
|
|
240
|
+
&.ext-tsx,
|
|
241
|
+
&.ext-json,
|
|
242
|
+
&.ext-yaml,
|
|
243
|
+
&.ext-yml,
|
|
244
|
+
&.ext-xml,
|
|
245
|
+
&.ext-html,
|
|
246
|
+
&.ext-css,
|
|
247
|
+
&.ext-scss,
|
|
248
|
+
&.ext-less,
|
|
249
|
+
&.ext-sass,
|
|
250
|
+
&.ext-java,
|
|
251
|
+
&.ext-c,
|
|
252
|
+
&.ext-cpp,
|
|
253
|
+
&.ext-cs,
|
|
254
|
+
&.ext-php,
|
|
255
|
+
&.ext-py,
|
|
256
|
+
&.ext-rb,
|
|
257
|
+
&.ext-go,
|
|
258
|
+
&.ext-swift,
|
|
259
|
+
&.ext-sql,
|
|
260
|
+
&.ext-perl,
|
|
261
|
+
&.ext-lua,
|
|
262
|
+
&.ext-scala,
|
|
263
|
+
&.ext-sh {
|
|
264
|
+
&::before {
|
|
265
|
+
content: '\\ea07';
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
&.ext-zip,
|
|
270
|
+
&.ext-rar,
|
|
271
|
+
&.ext-tar,
|
|
272
|
+
&.ext-gz,
|
|
273
|
+
&.ext-iso {
|
|
274
|
+
&::before {
|
|
275
|
+
content: '\\ea08';
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
&.ext-pdf,
|
|
280
|
+
&.ext-PDF {
|
|
281
|
+
&::before {
|
|
282
|
+
content: '\\ea09';
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
&.ext-excel,
|
|
287
|
+
&.ext-xls,
|
|
288
|
+
&.ext-xlsx {
|
|
289
|
+
&::before {
|
|
290
|
+
content: '\\ea0a';
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
&.ext-powerpoint,
|
|
295
|
+
&.ext-ppt,
|
|
296
|
+
&.ext-pptx {
|
|
297
|
+
&::before {
|
|
298
|
+
content: '\\ea0b';
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
&.ext-doc,
|
|
303
|
+
&.ext-docx,
|
|
304
|
+
&.ext-rtf {
|
|
305
|
+
&::before {
|
|
306
|
+
content: '\\ea0c';
|
|
307
|
+
}
|
|
308
|
+
}
|
|
134
309
|
}
|
|
135
310
|
|
|
136
311
|
${generateCodeBlockTokens()}
|
|
@@ -138,9 +313,9 @@ const CodeBlockContainerComponent = styled.pre<CodeBlockContainerProps>`
|
|
|
138
313
|
${({ hideCodeColors }) =>
|
|
139
314
|
hideCodeColors &&
|
|
140
315
|
css`
|
|
141
|
-
.
|
|
142
|
-
.
|
|
143
|
-
.
|
|
316
|
+
.line-number:not(.highlighted),
|
|
317
|
+
.line-number:not(.highlighted) > span,
|
|
318
|
+
.line-number:not(.highlighted) > span > span {
|
|
144
319
|
color: grey;
|
|
145
320
|
}
|
|
146
321
|
`}
|
|
@@ -1,6 +1,30 @@
|
|
|
1
1
|
import { css } from 'styled-components';
|
|
2
2
|
|
|
3
3
|
export const code = css`
|
|
4
|
+
/**
|
|
5
|
+
* Tree view icons font
|
|
6
|
+
*/
|
|
7
|
+
@font-face {
|
|
8
|
+
font-family: 'TreeViewIcons';
|
|
9
|
+
/**
|
|
10
|
+
* Use the following escape sequences to refer to a specific icon:
|
|
11
|
+
*
|
|
12
|
+
* - \\ea01 file
|
|
13
|
+
* - \\ea02 folder
|
|
14
|
+
* - \\ea03 image
|
|
15
|
+
* - \\ea04 audio
|
|
16
|
+
* - \\ea05 video
|
|
17
|
+
* - \\ea06 text
|
|
18
|
+
* - \\ea07 code
|
|
19
|
+
* - \\ea08 archive
|
|
20
|
+
* - \\ea09 pdf
|
|
21
|
+
* - \\ea0a excel
|
|
22
|
+
* - \\ea0b powerpoint
|
|
23
|
+
* - \\ea0c word
|
|
24
|
+
*/
|
|
25
|
+
src: url('data:application/font-woff;base64,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') format('woff');
|
|
26
|
+
}
|
|
27
|
+
|
|
4
28
|
/**
|
|
5
29
|
* @tokens Code base styles
|
|
6
30
|
*/
|
|
@@ -83,10 +107,29 @@ export const code = css`
|
|
|
83
107
|
--code-block-tokens-atrule-color: var(--code-block-tokens-keyword-color); // @presenter Color
|
|
84
108
|
--code-block-tokens-attr-value-color: var(--code-block-tokens-keyword-color); // @presenter Color
|
|
85
109
|
--code-block-tokens-regex-color: var(--color-carrot-7); // @presenter Color
|
|
110
|
+
--code-block-tokens-regex-char-escape-color: var(--color-grass-8); // @presenter Color
|
|
86
111
|
--code-block-tokens-important-color: var(--code-block-tokens-regex-color); // @presenter Color
|
|
87
112
|
--code-block-tokens-deleted-color: var(--color-red-7); // @presenter Color
|
|
88
113
|
--code-block-tokens-class-name-color: var(--color-carrot-7); // @presenter Color
|
|
89
114
|
--code-block-tokens-function-color: var(--color-carrot-7); // @presenter Color
|
|
115
|
+
--code-block-tokens-invalid-color: var(--color-orange-8); // @presenter Color
|
|
116
|
+
--code-block-tokens-message-error-color: var(--code-block-tokens-invalid-color); // @presenter Color
|
|
117
|
+
--code-block-tokens-unmatched-color: var(--code-block-tokens-invalid-color); // @presenter Color
|
|
118
|
+
--code-block-tokens-markup-bg-color: var(--color-grass-1); // @presenter Color
|
|
119
|
+
--code-block-tokens-markup-foreground-color: var(--color-grass-8); // @presenter Color
|
|
120
|
+
--code-block-tokens-markup-changed-color: var(--color-carrot-1); // @presenter Color
|
|
121
|
+
--code-block-tokens-markup-deleted-color: var(--color-magenta-1); // @presenter Color
|
|
122
|
+
--code-block-tokens-markup-quote-color: var(--color-grass-8); // @presenter Color
|
|
123
|
+
--code-block-tokens-markup-ignored-color: var(--color-blue-1); // @presenter Color
|
|
124
|
+
--code-block-tokens-warm-bg-color: var(--color-warm-grey-2); // @presenter Color
|
|
125
|
+
--code-block-tokens-warm-foreground-color: var(--color-warm-grey-8); // @presenter Color
|
|
126
|
+
--code-block-tokens-meta-diff-range-color: var(--color-purple-8); // @presenter Color
|
|
127
|
+
|
|
128
|
+
/**
|
|
129
|
+
* @tokens Code Block tree view
|
|
130
|
+
*/
|
|
131
|
+
--code-block-tree-view-icon-font-family: 'TreeViewIcons'; // @presenter FontFamily
|
|
132
|
+
--code-block-tree-view-lines-color: var(--border-color-primary); // @presenter Color
|
|
90
133
|
|
|
91
134
|
// @tokens End
|
|
92
135
|
`;
|
|
@@ -19,7 +19,7 @@ export type LinkProps = {
|
|
|
19
19
|
export function Link(props: React.PropsWithChildren<LinkProps>): JSX.Element {
|
|
20
20
|
const context = useContext(ThemeDataContext);
|
|
21
21
|
|
|
22
|
-
if (context) {
|
|
22
|
+
if (context?.components) {
|
|
23
23
|
const { LinkComponent } = context.components;
|
|
24
24
|
return <LinkComponent {...props} />;
|
|
25
25
|
} else {
|
|
@@ -10,7 +10,7 @@ export function useThemeConfig<T extends Record<string, unknown>>(
|
|
|
10
10
|
): T & NonNullable<UiAccessibleConfig> {
|
|
11
11
|
const context = useContext(ThemeDataContext);
|
|
12
12
|
|
|
13
|
-
if (!context) {
|
|
13
|
+
if (!context?.config) {
|
|
14
14
|
return {} as T;
|
|
15
15
|
}
|
|
16
16
|
const { config, hooks } = context;
|
|
@@ -12,6 +12,7 @@ const fallbacks = {
|
|
|
12
12
|
useSubmitFeedback: () => ({ submitFeedback: () => {} }),
|
|
13
13
|
useTelemetry: () => ({ telemetry: () => {} }),
|
|
14
14
|
useBreadcrumbs: () => [],
|
|
15
|
+
useCodeHighlight: () => ({ highlight: (rawContent: string) => rawContent }),
|
|
15
16
|
};
|
|
16
17
|
|
|
17
18
|
export const useThemeHooks = () => {
|
package/src/core/types/hooks.ts
CHANGED
|
@@ -110,6 +110,17 @@ export type ThemeHooks = {
|
|
|
110
110
|
useTelemetry: () => { send(action: TelemetryEvent, data: unknown): void };
|
|
111
111
|
useUserTeams: () => string[];
|
|
112
112
|
usePageProps: <T extends Record<string, unknown>>() => PageProps & T;
|
|
113
|
+
useCodeHighlight: () => {
|
|
114
|
+
highlight: (
|
|
115
|
+
code: string,
|
|
116
|
+
language?: string | undefined,
|
|
117
|
+
highlightOptions?: {
|
|
118
|
+
withLineNumbers?: boolean;
|
|
119
|
+
startLineNumber?: number;
|
|
120
|
+
highlight?: string;
|
|
121
|
+
},
|
|
122
|
+
) => string;
|
|
123
|
+
};
|
|
113
124
|
};
|
|
114
125
|
|
|
115
126
|
export type L10nConfig = {
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const NEW_LINE_EXP = /\n(?!$)/g;
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @param highlightedCode - A string with new line breaks; the line numbers will be added before each line.
|
|
5
|
+
* @param start - The number to start the line numbering from; default is 1
|
|
6
|
+
* @returns A string with line numbers added before each line
|
|
7
|
+
*/
|
|
8
|
+
export function addLineNumbers(highlightedCode: string, start = 1): string {
|
|
9
|
+
const codeLines = highlightedCode.split(NEW_LINE_EXP);
|
|
10
|
+
|
|
11
|
+
return codeLines
|
|
12
|
+
.map((line, i) => {
|
|
13
|
+
return `<span class='line' data-line-number='${start + i}'>${line}</span>`;
|
|
14
|
+
})
|
|
15
|
+
.join('\n');
|
|
16
|
+
}
|
package/src/core/utils/index.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
export * from '@redocly/theme/core/utils/clipboard-service';
|
|
2
2
|
export * from '@redocly/theme/core/utils/css-variables';
|
|
3
|
-
export * from '@redocly/theme/core/utils/
|
|
3
|
+
export * from '@redocly/theme/core/utils/add-line-numbers';
|
|
4
4
|
export * from '@redocly/theme/core/utils/media-css';
|
|
5
5
|
export * from '@redocly/theme/core/utils/theme-helpers';
|
|
6
6
|
export * from '@redocly/theme/core/utils/class-names';
|
|
@@ -12,6 +12,7 @@ export type CardProps = React.PropsWithChildren<{
|
|
|
12
12
|
icon?: string;
|
|
13
13
|
iconRawContent?: string;
|
|
14
14
|
imagePosition?: 'start' | 'end';
|
|
15
|
+
iconPosition?: 'auto' | 'start' | 'center' | 'end';
|
|
15
16
|
lineClamp?: number;
|
|
16
17
|
layout?: 'horizontal' | 'vertical' | 'combined';
|
|
17
18
|
variant?: 'filled' | 'outlined' | 'elevated' | 'ghost';
|
|
@@ -26,6 +27,7 @@ export function Card({
|
|
|
26
27
|
icon,
|
|
27
28
|
iconRawContent,
|
|
28
29
|
imagePosition = 'start',
|
|
30
|
+
iconPosition = 'auto',
|
|
29
31
|
layout = 'vertical',
|
|
30
32
|
variant = 'filled',
|
|
31
33
|
lineClamp,
|
|
@@ -59,7 +61,14 @@ export function Card({
|
|
|
59
61
|
$textAlign={textAlign}
|
|
60
62
|
$hasImage={image !== undefined}
|
|
61
63
|
>
|
|
62
|
-
{icon &&
|
|
64
|
+
{icon && (
|
|
65
|
+
<CardIcon
|
|
66
|
+
variant={iconVariant}
|
|
67
|
+
src={icon}
|
|
68
|
+
rawContent={iconRawContent}
|
|
69
|
+
position={iconPosition}
|
|
70
|
+
/>
|
|
71
|
+
)}
|
|
63
72
|
<ContentWrapper>
|
|
64
73
|
<Title id={cardTitleId} $isCardLink={!!to} $justifyContent={justifyContent}>
|
|
65
74
|
{title}
|
|
@@ -7,11 +7,12 @@ export type CardIconProps = {
|
|
|
7
7
|
variant?: string;
|
|
8
8
|
src: string;
|
|
9
9
|
rawContent?: string;
|
|
10
|
+
position?: 'auto' | 'start' | 'center' | 'end';
|
|
10
11
|
};
|
|
11
12
|
|
|
12
|
-
export function CardIcon({ variant, src, rawContent }: CardIconProps) {
|
|
13
|
+
export function CardIcon({ variant, src, rawContent, position }: CardIconProps) {
|
|
13
14
|
return (
|
|
14
|
-
<CardIconWrapper $variant={variant}>
|
|
15
|
+
<CardIconWrapper $variant={variant} $position={position}>
|
|
15
16
|
{rawContent ? <CardSvg fileRawContent={rawContent} /> : <CardImg src={src} />}
|
|
16
17
|
</CardIconWrapper>
|
|
17
18
|
);
|
|
@@ -36,9 +37,9 @@ const CardSvg = styled(InlineSvg)`
|
|
|
36
37
|
}
|
|
37
38
|
`;
|
|
38
39
|
|
|
39
|
-
const CardIconWrapper = styled.div<{ $variant?: string }>`
|
|
40
|
+
const CardIconWrapper = styled.div<{ $variant?: string; $position?: string }>`
|
|
40
41
|
display: flex;
|
|
41
|
-
align-
|
|
42
|
+
align-self: ${({ $position }) => ($position ? $position : 'auto')};
|
|
42
43
|
justify-content: center;
|
|
43
44
|
min-width: var(--card-icon-width);
|
|
44
45
|
min-height: var(--card-icon-height);
|