@apify/ui-library 0.65.3 → 0.66.1-featuresyntaxhighlighter-48cb44.19

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 (50) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/dist/src/components/action_link.d.ts +3 -1
  3. package/dist/src/components/action_link.d.ts.map +1 -1
  4. package/dist/src/components/action_link.js +2 -2
  5. package/dist/src/components/action_link.js.map +1 -1
  6. package/dist/src/components/code/code_block/code_block.d.ts.map +1 -1
  7. package/dist/src/components/code/code_block/code_block.js +14 -20
  8. package/dist/src/components/code/code_block/code_block.js.map +1 -1
  9. package/dist/src/components/code/code_block/code_block.styled.d.ts +8 -2
  10. package/dist/src/components/code/code_block/code_block.styled.d.ts.map +1 -1
  11. package/dist/src/components/code/code_block/code_block.styled.js +14 -68
  12. package/dist/src/components/code/code_block/code_block.styled.js.map +1 -1
  13. package/dist/src/components/code/code_block/utils.d.ts +5 -1
  14. package/dist/src/components/code/code_block/utils.d.ts.map +1 -1
  15. package/dist/src/components/code/code_block/utils.js +23 -12
  16. package/dist/src/components/code/code_block/utils.js.map +1 -1
  17. package/dist/src/components/code/index.d.ts +1 -0
  18. package/dist/src/components/code/index.d.ts.map +1 -1
  19. package/dist/src/components/code/index.js +1 -0
  20. package/dist/src/components/code/index.js.map +1 -1
  21. package/dist/src/components/code/one_line_code/one_line_code.d.ts.map +1 -1
  22. package/dist/src/components/code/one_line_code/one_line_code.js +15 -22
  23. package/dist/src/components/code/one_line_code/one_line_code.js.map +1 -1
  24. package/dist/src/components/code/prism_highlighter.d.ts +20 -0
  25. package/dist/src/components/code/prism_highlighter.d.ts.map +1 -0
  26. package/dist/src/components/code/prism_highlighter.js +117 -0
  27. package/dist/src/components/code/prism_highlighter.js.map +1 -0
  28. package/dist/src/components/image.d.ts +4 -5
  29. package/dist/src/components/image.d.ts.map +1 -1
  30. package/dist/src/components/image.js.map +1 -1
  31. package/dist/src/ui_dependency_provider.d.ts +8 -7
  32. package/dist/src/ui_dependency_provider.d.ts.map +1 -1
  33. package/dist/src/ui_dependency_provider.js.map +1 -1
  34. package/dist/tsconfig.build.tsbuildinfo +1 -1
  35. package/package.json +4 -4
  36. package/src/components/action_link.tsx +5 -4
  37. package/src/components/code/code_block/code_block.styled.tsx +21 -69
  38. package/src/components/code/code_block/code_block.tsx +25 -36
  39. package/src/components/code/code_block/utils.tsx +53 -0
  40. package/src/components/code/index.ts +1 -0
  41. package/src/components/code/one_line_code/one_line_code.tsx +24 -27
  42. package/src/components/code/prism_highlighter.tsx +180 -0
  43. package/src/components/image.tsx +2 -1
  44. package/src/ui_dependency_provider.tsx +9 -1
  45. package/dist/src/components/code/syntax_highlighter.d.ts +0 -15
  46. package/dist/src/components/code/syntax_highlighter.d.ts.map +0 -1
  47. package/dist/src/components/code/syntax_highlighter.js +0 -103
  48. package/dist/src/components/code/syntax_highlighter.js.map +0 -1
  49. package/src/components/code/code_block/utils.ts +0 -19
  50. package/src/components/code/syntax_highlighter.tsx +0 -134
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apify/ui-library",
3
- "version": "0.65.3",
3
+ "version": "0.66.1-featuresyntaxhighlighter-48cb44.19+dd172314efe",
4
4
  "description": "React UI library used by apify.com",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -33,9 +33,10 @@
33
33
  "fast-average-color": "^9.4.0",
34
34
  "history": "^5.3.0",
35
35
  "lodash": "^4.17.21",
36
+ "prism-react-renderer": "^2.4.1",
37
+ "prismjs": "^1.30.0",
36
38
  "query-string": "^8.1.0",
37
39
  "react-markdown": "^8.0.5",
38
- "react-syntax-highlighter": "^15.5.0",
39
40
  "rehype-raw": "^6.1.1",
40
41
  "rehype-sanitize": "^6.0.0",
41
42
  "remark-gfm": "^3.0.1",
@@ -54,7 +55,6 @@
54
55
  "@types/lodash": "^4.14.200",
55
56
  "@types/node": "^22.10.5",
56
57
  "@types/react": "^18.2.74",
57
- "@types/react-syntax-highlighter": "^15.5.9",
58
58
  "@types/styled-components": "^5.1.34",
59
59
  "eslint": "^9.22.0",
60
60
  "eslint-plugin-import": "2.26.0",
@@ -65,5 +65,5 @@
65
65
  "typescript": "^5.1.6",
66
66
  "typescript-eslint": "^8.24.0"
67
67
  },
68
- "gitHead": "d28107308e89cc139489334a352f51de1ce3ff8f"
68
+ "gitHead": "dd172314efe4cbe8e1fbb4454a4a71dc517103ef"
69
69
  }
@@ -24,18 +24,19 @@ const StyledGuidepost = styled(Box)<{ $isBackLink: boolean }>`
24
24
  }
25
25
  `;
26
26
 
27
- export const ActionLink: React.FC<LinkProps> = ({
27
+ export const ActionLink: React.FC<LinkProps & { contentProps?: object }> = ({
28
28
  children,
29
- as,
29
+ as = Link,
30
+ contentProps,
30
31
  ...rest
31
32
  }) => {
32
33
  return (
33
34
  <StyledGuidepost
34
- forwardedAs={as || Link}
35
+ forwardedAs={as}
35
36
  $isBackLink={false}
36
37
  {...rest}
37
38
  >
38
- <Heading as='span' type='titleM'>{children}</Heading>
39
+ <Heading as='span' type='titleM' {...contentProps}>{children}</Heading>
39
40
  <ArrowRightIcon size="16" />
40
41
  </StyledGuidepost>
41
42
  );
@@ -1,10 +1,28 @@
1
1
  import styled, { css } from 'styled-components';
2
2
 
3
3
  import { theme } from '../../../design_system/theme.js';
4
- import type { SharedTextSize } from '../../text/text_shared.js';
5
- import { SyntaxHighlighterBaseStylesWrapper } from '../syntax_highlighter.js';
4
+ import { Box } from '../../box.js';
5
+ import type { SharedTextProps, SharedTextSize } from '../../text/text_shared.js';
6
6
 
7
- const HIGHLIGHT_BACKGROUND_COLOR = 'rgba(22, 114, 235, 0.05)';
7
+ export type SyntaxHighlighterBaseStylesWrapperProps = SharedTextProps & {
8
+ $fullWidth?: boolean;
9
+ $fullHeight?: string;
10
+ $showLineNumbers?: boolean;
11
+ }
12
+
13
+ export const SyntaxHighlighterBaseStylesWrapper = styled(Box)<SyntaxHighlighterBaseStylesWrapperProps>`
14
+ background-color: ${theme.color.neutral.backgroundMuted} !important;
15
+ border: 1px solid ${theme.color.neutral.border};
16
+ border-radius: ${theme.radius.radius12};
17
+ overflow: hidden;
18
+
19
+ width: 100%;
20
+ ${({ $fullWidth }) => !$fullWidth && css`max-width: 860px;`}
21
+ ${({ $fullHeight }) => !$fullHeight && css`max-height: 600px;`}
22
+
23
+ background-color: transparent;
24
+ position: relative;
25
+ `;
8
26
 
9
27
  export const CodeBlockWrapper = styled(SyntaxHighlighterBaseStylesWrapper) <{
10
28
  $hasHeader: boolean;
@@ -105,72 +123,6 @@ export const CodeBlockWrapper = styled(SyntaxHighlighterBaseStylesWrapper) <{
105
123
  }
106
124
  }
107
125
 
108
- .CodePre {
109
- z-index: 2;
110
- padding: ${theme.space.space16} 0 !important;
111
-
112
- code {
113
- & > span {
114
- display: block;
115
- padding-left: ${({ $showLineNumbers }) => ($showLineNumbers ? theme.space.space8 : theme.space.space16)};
116
- padding-right: ${theme.space.space16};
117
- &:hover {
118
- background-color: ${HIGHLIGHT_BACKGROUND_COLOR} !important;
119
- border-left: 6px solid ${theme.color.neutral.border} !important;
120
- padding-left: ${({ $showLineNumbers }) => ($showLineNumbers ? '0.2' : '1')}rem;
121
- }
122
- }
123
-
124
- // Common styles
125
- [data*='bash']{
126
- &::before {
127
- color: ${theme.color.lavender.base};
128
- padding-right: ${theme.space.space16};
129
- min-width: ${theme.space.space24};
130
- user-select: none;
131
- -webkit-user-select: none;
132
- font-size: 1em;
133
- }
134
- }
135
-
136
- [data*='bashStartCommand'] {
137
- &::before {
138
- content: '$';
139
- }
140
- }
141
-
142
- [data*='bashCommand'] {
143
- &::before {
144
- content: '>';
145
- }
146
- }
147
-
148
- [data*='bashEmptyLine'] {
149
- &::before {
150
- content: ' ';
151
- }
152
- }
153
-
154
- [data*='highlighted'] {
155
- background-color: ${HIGHLIGHT_BACKGROUND_COLOR} !important;
156
- border-left: 6px solid ${theme.color.neutral.border} !important;
157
- padding-left: ${({ $showLineNumbers }) => ($showLineNumbers ? '0.2' : '1')}rem;
158
- }
159
-
160
-
161
- .linenumber {
162
- color: ${theme.color.neutral.textSubtle} !important;
163
- padding-right: ${theme.space.space16} !important;
164
- min-width: ${theme.space.space24} !important;
165
- box-sizing: unset !important;
166
- user-select: none;
167
- -webkit-user-select: none;
168
-
169
- ${({ $showLineNumbers }) => (!$showLineNumbers && css`display: none !important;`)}
170
-
171
- }
172
- }
173
- }
174
126
 
175
127
  .CodeBlock-TopRightActionsWrapper {
176
128
  position: absolute;
@@ -1,5 +1,5 @@
1
1
  import clsx from 'clsx';
2
- import React, { useCallback, useMemo, useRef, useState } from 'react';
2
+ import React, { useMemo, useRef, useState } from 'react';
3
3
 
4
4
  import type { RegularBoxProps } from '../../box.js';
5
5
  import { ColorWheelGradient } from '../../color_wheel_gradient.js';
@@ -7,9 +7,9 @@ import { Link } from '../../link.js';
7
7
  import { Text } from '../../text/index.js';
8
8
  import type { SharedTextSize } from '../../text/text_shared.js';
9
9
  import { ActionButton, CopyButton } from '../action_button.js';
10
- import { SyntaxHighlighter } from '../syntax_highlighter.js';
10
+ import { PrismSyntaxHighlighter } from '../prism_highlighter.js';
11
11
  import { CodeBlockWrapper } from './code_block.styled.js';
12
- import { mapPrefixToBashLine } from './utils.js';
12
+ import { getBashLinePrefixes, getNumberLinePrefixes } from './utils.js';
13
13
 
14
14
  type CodeTab = {
15
15
  key: string;
@@ -149,9 +149,7 @@ export const CodeBlock = ({
149
149
 
150
150
  const isBash = currentLanguage === 'bash';
151
151
 
152
- const showLineNumbers = !hideLineNumbers
153
- && !LANGUAGES_WITHOUT_LINE_NUMBERS.includes(currentLanguage ?? '');
154
- const showBashPrompt = isBash && !hideBashPromptPrefixes;
152
+ const showLineNumbers = !hideLineNumbers && !LANGUAGES_WITHOUT_LINE_NUMBERS.includes(currentLanguage ?? '');
155
153
  const showBashHeader = isBash && !hideBashHeader && !isMultiTab;
156
154
 
157
155
  const showHeader = isMultiTab || !!title || showBashHeader;
@@ -164,28 +162,20 @@ export const CodeBlock = ({
164
162
  syntaxHighlighterRef.current?.scrollTo(0, 0);
165
163
  };
166
164
 
167
- const currentBashLinesPrefixes = useMemo(() => {
168
- if (!showBashPrompt) return [];
169
- return mapPrefixToBashLine(
170
- currentCode,
171
- currentTab?.bashCommandsStart ?? bashCommandsStart,
172
- );
173
- }, [currentCode, bashCommandsStart, showBashPrompt, currentTab]);
174
-
175
- const getLineProps = useCallback(
176
- (lineNumber: number) => {
177
- const data = [];
178
- if (currentHighlightLines?.includes(lineNumber)) {
179
- data.push('highlighted');
180
- }
181
- if (showBashPrompt) {
182
- data.push(currentBashLinesPrefixes[lineNumber - 1]);
183
- }
184
-
185
- return { data: data.join(' ') };
186
- },
187
- [currentHighlightLines, showBashPrompt, currentBashLinesPrefixes],
188
- );
165
+ const showBashPrompt = isBash && !hideBashPromptPrefixes;
166
+ const effectiveBashCommandsStart = currentTab?.bashCommandsStart ?? bashCommandsStart;
167
+
168
+ const linePrefixes = useMemo(() => {
169
+ if (showBashPrompt) {
170
+ return getBashLinePrefixes(currentCode, effectiveBashCommandsStart);
171
+ }
172
+
173
+ if (showLineNumbers) {
174
+ return getNumberLinePrefixes(currentCode);
175
+ }
176
+
177
+ return {};
178
+ }, [showLineNumbers, showBashPrompt, currentCode, effectiveBashCommandsStart]);
189
179
 
190
180
  return (
191
181
  <CodeBlockWrapper
@@ -208,16 +198,15 @@ export const CodeBlock = ({
208
198
  />
209
199
  )}
210
200
 
211
- <SyntaxHighlighter
212
- showLineNumbers
213
- wrapLines
214
- language={currentLanguage}
201
+ <PrismSyntaxHighlighter
202
+ code={currentCode}
203
+ linePrefixes={linePrefixes}
204
+ highlightLines={currentHighlightLines}
205
+ language={currentLanguage || 'text'}
215
206
  size={size}
216
- lineProps={getLineProps}
217
207
  ref={syntaxHighlighterRef}
218
- >
219
- {currentCode}
220
- </SyntaxHighlighter>
208
+ isSingleLine={false}
209
+ />
221
210
 
222
211
  <div className="CodeBlock-TopRightActionsWrapper">
223
212
  {showActionButton && <ActionButton successStyle onClick={onActionButtonClick}>{actionButtonLabel ?? 'Run on Apify'}</ActionButton>}
@@ -0,0 +1,53 @@
1
+ import type { ReactNode } from 'react';
2
+
3
+ import { theme } from '../../../design_system/theme.js';
4
+ import { CodeHighlighterLineBashPrefix, CodeHighlighterLinePrefix } from '../prism_highlighter.js';
5
+
6
+ // input: [2, 4, 5, 6, 8, 10, 11, 12]
7
+ // returns string indicating what type of line it is (bashStartCommand, bashCommand, bashEmptyLine)
8
+ // commands start -> bashStartCommand
9
+ // every next line after command start until next command start or empty line -> bashCommand
10
+ export const getBashLinePrefixes = (
11
+ code: string,
12
+ bashCommandsStart: number[] = [],
13
+ isOneLine?: boolean) => {
14
+ const lines = code.split('\n').map((line) => line.trim());
15
+
16
+ const bashLinePrefixesArray = lines.map((line, i) => {
17
+ const isEmptyLine = line.startsWith('#') || !line;
18
+
19
+ // by default each line that is not empty or comment is a command start
20
+ if (bashCommandsStart.length === 0) {
21
+ return isEmptyLine ? (
22
+ <CodeHighlighterLineBashPrefix $isOneLine={isOneLine} />
23
+ ) : (
24
+ <CodeHighlighterLineBashPrefix $isOneLine={isOneLine} color={theme.color.lavender.base}>$</CodeHighlighterLineBashPrefix>
25
+ );
26
+ }
27
+
28
+ if (bashCommandsStart.includes(i + 1)) {
29
+ return (
30
+ <CodeHighlighterLineBashPrefix $isOneLine={isOneLine} color={theme.color.lavender.base}>$</CodeHighlighterLineBashPrefix>
31
+ );
32
+ }
33
+
34
+ if (isEmptyLine) {
35
+ return (
36
+ <CodeHighlighterLineBashPrefix $isOneLine={isOneLine}/>
37
+ );
38
+ }
39
+
40
+ return (
41
+ <CodeHighlighterLineBashPrefix $isOneLine={isOneLine} color={theme.color.lavender.base}>&lt;</CodeHighlighterLineBashPrefix>
42
+ );
43
+ });
44
+
45
+ return Object.fromEntries(bashLinePrefixesArray.map((linePrefix, i) => [i + 1, linePrefix]));
46
+ };
47
+
48
+ export const getNumberLinePrefixes = (code: string): Record<number, ReactNode> => {
49
+ const numberOfLines = code.split('\n').length;
50
+ const numbersArray = Array.from({ length: numberOfLines }, (_, i) => i + 1);
51
+
52
+ return Object.fromEntries(numbersArray.map((number) => [number, <CodeHighlighterLinePrefix>{number}</CodeHighlighterLinePrefix>]));
53
+ };
@@ -2,3 +2,4 @@ export * from './code_block/code_block.js';
2
2
  export * from './code_block/code_block_with_tabs.js';
3
3
  export * from './one_line_code/one_line_code.js';
4
4
  export * from './inline_code/inline_code.js';
5
+ export * from './prism_highlighter.js';
@@ -8,8 +8,10 @@ import type { BoxProps } from '../../box.js';
8
8
  import { Text } from '../../text/index.js';
9
9
  import type { SharedTextSize } from '../../text/text_shared.js';
10
10
  import { ActionButton, CopyButton } from '../action_button.js';
11
- import type { SyntaxHighlighterBaseStylesWrapperProps } from '../syntax_highlighter.js';
12
- import { SyntaxHighlighter, SyntaxHighlighterBaseStylesWrapper } from '../syntax_highlighter.js';
11
+ import type { SyntaxHighlighterBaseStylesWrapperProps } from '../code_block/code_block.styled.js';
12
+ import { SyntaxHighlighterBaseStylesWrapper } from '../code_block/code_block.styled.js';
13
+ import { getBashLinePrefixes } from '../code_block/utils.js';
14
+ import { PrismSyntaxHighlighter } from '../prism_highlighter.js';
13
15
 
14
16
  export const oneLineCodeClassNames = {
15
17
  gradientWrapper: 'OneLineCode-GradientWrapper',
@@ -83,7 +85,6 @@ const OneLineCodeWrapper = styled(SyntaxHighlighterBaseStylesWrapper)<OneLineCod
83
85
  position: relative;
84
86
  flex: 1;
85
87
  min-width: 0;
86
- padding-top: ${theme.space.space8};
87
88
  display: flex;
88
89
 
89
90
  .${oneLineCodeClassNames.gradient} {
@@ -92,6 +93,7 @@ const OneLineCodeWrapper = styled(SyntaxHighlighterBaseStylesWrapper)<OneLineCod
92
93
  top: 0;
93
94
  bottom: 0;
94
95
  width: 4rem;
96
+ z-index: 5;
95
97
  background: linear-gradient(
96
98
  to right,
97
99
  transparent,
@@ -105,6 +107,7 @@ const OneLineCodeWrapper = styled(SyntaxHighlighterBaseStylesWrapper)<OneLineCod
105
107
  overflow-x: auto;
106
108
  overflow-y: hidden;
107
109
  display: flex;
110
+ align-items: center;
108
111
  gap: ${theme.space.space16};
109
112
  padding: 0 ${theme.space.space8} !important;
110
113
  margin-left: ${theme.space.space8} !important;
@@ -114,30 +117,19 @@ const OneLineCodeWrapper = styled(SyntaxHighlighterBaseStylesWrapper)<OneLineCod
114
117
  scrollbar-color: ${theme.color.neutral.border} transparent;
115
118
 
116
119
 
117
- .CodePre {
118
- overflow: unset !important;
120
+ pre {
119
121
  display: flex;
120
122
  flex: 1;
121
123
  align-items: center;
122
- height: 2.8rem;
124
+ height: 100%;
123
125
 
124
126
  code {
125
- & > span {
126
- text-overflow: ellipsis;
127
- overflow: hidden;
128
- white-space: nowrap;
129
- vertical-align: text-top;
130
- ${({ $showBashPrefixes }) => $showBashPrefixes && css`
131
- &::before {
132
- color: ${theme.color.lavender.base};
133
- padding-right: ${theme.space.space16};
134
- min-width: ${theme.space.space24};
135
- user-select: none;
136
- -webkit-user-select: none;
137
- content: "$";
138
- font-size: 1em;
139
- }
140
- `}
127
+ height: 100%;
128
+ display: flex;
129
+ align-items: center;
130
+
131
+ & > div {
132
+ padding-right: ${theme.space.space16};
141
133
  }
142
134
  }
143
135
  }
@@ -182,6 +174,11 @@ export function OneLineCode({
182
174
 
183
175
  const showBashPrefixes = language === 'bash';
184
176
 
177
+ const linePrefixes = useMemo(
178
+ () => (showBashPrefixes ? getBashLinePrefixes(code, [1], true) : {}),
179
+ [showBashPrefixes, code],
180
+ );
181
+
185
182
  return (
186
183
  <OneLineCodeWrapper
187
184
  $httpMethod={httpMethod}
@@ -197,13 +194,13 @@ export function OneLineCode({
197
194
  {httpMethod}
198
195
  </Text>
199
196
  )}
200
- <SyntaxHighlighter
197
+ <PrismSyntaxHighlighter
201
198
  language={language}
202
199
  size={size}
203
- wrapLines
204
- >
205
- {code}
206
- </SyntaxHighlighter>
200
+ linePrefixes={linePrefixes}
201
+ code={code}
202
+ isSingleLine={true}
203
+ />
207
204
  </div>
208
205
  <div className={oneLineCodeClassNames.gradient} />
209
206
  </div>
@@ -0,0 +1,180 @@
1
+ import clsx from 'clsx';
2
+ import _ from 'lodash';
3
+ import type { HighlightProps } from 'prism-react-renderer';
4
+ import { Highlight, Prism, themes } from 'prism-react-renderer';
5
+ import type { ReactNode } from 'react';
6
+ import { forwardRef, useRef } from 'react';
7
+ import styled, { css } from 'styled-components';
8
+
9
+ import { theme } from '../../design_system/theme.js';
10
+ import { useSharedUiDependencies } from '../../ui_dependency_provider.js';
11
+ import { Text } from '../text/index.js';
12
+ import type { SharedTextSize } from '../text/text_shared.js';
13
+
14
+ (typeof global !== 'undefined' ? global : window).Prism = Prism;
15
+
16
+ const HIGHLIGHT_BACKGROUND_COLOR = 'rgba(22, 114, 235, 0.05)';
17
+
18
+ const loadLanguages = async () => {
19
+ await Promise.all([
20
+ // @ts-expect-error The library is badly typed and does not export the type
21
+ import('prismjs/components/prism-bash.js'),
22
+ // @ts-expect-error The library is badly typed and does not export the type
23
+ import('prismjs/components/prism-rust.js'),
24
+ // @ts-expect-error The library is badly typed and does not export the type
25
+ import('prismjs/components/prism-bash.js'),
26
+ // @ts-expect-error The library is badly typed and does not export the type
27
+ import('prismjs/components/prism-docker.js'),
28
+ // @ts-expect-error The library is badly typed and does not export the type
29
+ import('prismjs/components/prism-http.js'),
30
+ // @ts-expect-error The library is badly typed and does not export the type
31
+ import('prismjs/components/prism-javascript.js'),
32
+ // @ts-expect-error The library is badly typed and does not export the type
33
+ import('prismjs/components/prism-json.js'),
34
+ // @ts-expect-error The library is badly typed and does not export the type
35
+ import('prismjs/components/prism-markup.js'),
36
+ // @ts-expect-error The library is badly typed and does not export the type
37
+ import('prismjs/components/prism-python.js'),
38
+ // @ts-expect-error The library is badly typed and does not export the type
39
+ import('prismjs/components/prism-typescript.js'),
40
+ // @ts-expect-error The library is badly typed and does not export the type
41
+ import('prismjs/components/prism-xml-doc.js'),
42
+ // @ts-expect-error The library is badly typed and does not export the type
43
+ import('prismjs/components/prism-yaml.js'),
44
+ ]);
45
+ };
46
+
47
+ void loadLanguages();
48
+
49
+ type StyledPreProps = {
50
+ $hasLinePrefixes: boolean,
51
+ $isSingleLine: boolean
52
+ };
53
+
54
+ const StyledPre = styled.pre<StyledPreProps>`
55
+ width: 100%;
56
+ position: relative;
57
+ overflow: auto;
58
+ z-index: 2;
59
+ padding: ${({ $isSingleLine }) => ($isSingleLine ? 0 : `${theme.space.space16} 0`)};
60
+ margin: 0;
61
+
62
+ code {
63
+ min-width: 100%;
64
+ display: inline-block;
65
+ vertical-align: middle;
66
+
67
+ *,
68
+ *::before,
69
+ *::after {
70
+ text-shadow: none !important;
71
+ font-style: normal !important;
72
+ font-family: inherit !important;
73
+ font-size: inherit !important;
74
+ font-weight: inherit !important;
75
+ line-height: inherit !important;
76
+ background-color: transparent !important;
77
+ }
78
+
79
+ & > div {
80
+ display: block;
81
+
82
+ &.highlighted {
83
+ background-color: ${HIGHLIGHT_BACKGROUND_COLOR} !important;
84
+ border-left: 6px solid ${theme.color.neutral.border} !important;
85
+ padding-left: ${({ $hasLinePrefixes }) => ($hasLinePrefixes ? '0.2' : '1')}rem;
86
+ }
87
+
88
+ ${({ $isSingleLine }) => !$isSingleLine && css<{$hasLinePrefixes: boolean}>`
89
+ &:hover {
90
+ background-color: ${HIGHLIGHT_BACKGROUND_COLOR} !important;
91
+ border-left: 6px solid ${theme.color.neutral.border} !important;
92
+ padding-left: ${({ $hasLinePrefixes }) => ($hasLinePrefixes ? '0.2' : '1')}rem;
93
+ }
94
+ `}
95
+
96
+ ${({ $isSingleLine }) => ($isSingleLine ? css<StyledPreProps>`
97
+ white-space: nowrap;
98
+ vertical-align: text-top;
99
+ ` : css<StyledPreProps>`
100
+ padding-left: ${({ $hasLinePrefixes }) => ($hasLinePrefixes ? theme.space.space8 : theme.space.space16)};
101
+ padding-right: ${theme.space.space16};
102
+
103
+ &:hover {
104
+ background-color: ${HIGHLIGHT_BACKGROUND_COLOR} !important;
105
+ border-left: 6px solid ${theme.color.neutral.border} !important;
106
+ padding-left: ${({ $hasLinePrefixes }) => ($hasLinePrefixes ? '0.2' : '1')}rem;
107
+ }
108
+ `)}
109
+ }
110
+ }
111
+ `;
112
+
113
+ export const CodeHighlighterLinePrefix = styled(Text).attrs({ as: 'span' })`
114
+ display: inline-block;
115
+ margin-right: ${theme.space.space16};
116
+ text-align: right;
117
+ min-width: ${theme.space.space24};
118
+ color: ${({ color }) => color || theme.color.neutral.textSubtle};
119
+ user-select: none;
120
+ -webkit-user-select: none;
121
+ `;
122
+
123
+ export const CodeHighlighterLineBashPrefix = styled(CodeHighlighterLinePrefix)<{ $isOneLine?: boolean }>`
124
+ min-width: ${({ $isOneLine }) => ($isOneLine ? 'unset' : theme.space.space16)} !important;
125
+ `;
126
+
127
+ type SyntaxHighlighterProps = Omit<HighlightProps, 'children' | 'language'> & {
128
+ size?: SharedTextSize,
129
+ linePrefixes?: Record<string, ReactNode>,
130
+ highlightLines?: number[],
131
+ language?: string,
132
+ className?: string,
133
+ isSingleLine: boolean,
134
+ };
135
+
136
+ export const PrismSyntaxHighlighter = forwardRef<HTMLPreElement, SyntaxHighlighterProps>(({
137
+ size = 'regular',
138
+ linePrefixes = {},
139
+ highlightLines = [],
140
+ language = 'javascript',
141
+ className,
142
+ isSingleLine,
143
+ ...rest
144
+ }, ref) => {
145
+ const { uiTheme } = useSharedUiDependencies();
146
+ const hasLinePrefixes = !_.isEmpty(linePrefixes);
147
+ const highlightedLinesObject = useRef<Record<number, boolean>>(Object.fromEntries(highlightLines.map((e) => [e, true])));
148
+
149
+ return (
150
+ <Highlight
151
+ theme={uiTheme === 'DARK' ? themes.nightOwl : themes.oneLight}
152
+ language={language}
153
+ {...rest}
154
+ >
155
+ {({ className: prismClassName, tokens, getLineProps, getTokenProps }) => (
156
+ <StyledPre
157
+ className={clsx(className, prismClassName)}
158
+ $hasLinePrefixes={hasLinePrefixes}
159
+ $isSingleLine={isSingleLine}
160
+ ref={ref}
161
+ >
162
+ <Text
163
+ size={size}
164
+ type='code'
165
+ as='code'
166
+ >
167
+ {tokens.map((line, i) => (
168
+ <div key={i} {...getLineProps({ line, className: highlightedLinesObject.current[i + 1] ? 'highlighted' : '' })}>
169
+ {hasLinePrefixes && (linePrefixes[i + 1] || <CodeHighlighterLinePrefix />)}
170
+ {line.map((token, key) => (
171
+ <span key={key} {...getTokenProps({ token })} />
172
+ ))}
173
+ </div>
174
+ ))}
175
+ </Text>
176
+ </StyledPre>
177
+ )}
178
+ </Highlight>
179
+ );
180
+ });
@@ -1,5 +1,6 @@
1
1
  import { forwardRef } from 'react';
2
2
 
3
+ import type { ImageProxyOptions } from '../ui_dependency_provider.js';
3
4
  import { useSharedUiDependencies } from '../ui_dependency_provider.js';
4
5
  import { Box, type BoxProps } from './box.js';
5
6
 
@@ -9,7 +10,7 @@ type ImageProps = {
9
10
  width?: number,
10
11
  height?: number,
11
12
  loading?: 'eager' | 'lazy' | undefined;
12
- }
13
+ } & ImageProxyOptions
13
14
 
14
15
  export const Image = forwardRef<HTMLImageElement, ImageProps & Omit<BoxProps, 'as'>>((props, ref) => {
15
16
  const { InternalImage } = useSharedUiDependencies();
@@ -10,6 +10,14 @@ export interface AgnosticInternalLinkProps extends Omit<React.AnchorHTMLAttribut
10
10
  href: string;
11
11
  }
12
12
 
13
+ export type ImageProxyOptions = {
14
+ extension?: string,
15
+ resize?: {
16
+ width?: number,
17
+ height?: number,
18
+ }
19
+ }
20
+
13
21
  export interface UiDependencies {
14
22
  InternalLink: React.ForwardRefExoticComponent<AgnosticInternalLinkProps & React.RefAttributes<HTMLAnchorElement>>,
15
23
  InternalImage: React.ForwardRefExoticComponent<React.RefAttributes<HTMLImageElement>>,
@@ -22,7 +30,7 @@ export interface UiDependencies {
22
30
  isHrefTrusted: (href: string) => boolean,
23
31
  uiTheme?: UiThemeOption, // Optional - as we can just fallback to light theme on the web
24
32
  // TODO: Make required once we add it on the web
25
- generateProxyImageUrl?: (url: string, options: { extension?: string, resize?: { width?: number, height?: number } }) => string
33
+ generateProxyImageUrl?: (url: string, options: ImageProxyOptions) => string
26
34
  }
27
35
 
28
36
  interface UiDependencyProviderProps {
@@ -1,15 +0,0 @@
1
- import type { SyntaxHighlighterProps as ReactSyntaxHighlighterProps } from 'react-syntax-highlighter';
2
- import { type SharedTextProps } from '../text/index.js';
3
- import type { SharedTextSize } from '../text/text_shared.js';
4
- type SyntaxHighlighterProps = ReactSyntaxHighlighterProps & {
5
- size: SharedTextSize;
6
- };
7
- export declare const SyntaxHighlighter: import("react").ForwardRefExoticComponent<Omit<SyntaxHighlighterProps, "ref"> & import("react").RefAttributes<HTMLPreElement>>;
8
- export type SyntaxHighlighterBaseStylesWrapperProps = SharedTextProps & {
9
- $fullWidth?: boolean;
10
- $fullHeight?: string;
11
- $showLineNumbers?: boolean;
12
- };
13
- export declare const SyntaxHighlighterBaseStylesWrapper: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../box.js").BoxProps & import("react").RefAttributes<HTMLElement>>, any, SyntaxHighlighterBaseStylesWrapperProps, never>;
14
- export {};
15
- //# sourceMappingURL=syntax_highlighter.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"syntax_highlighter.d.ts","sourceRoot":"","sources":["../../../../src/components/code/syntax_highlighter.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,sBAAsB,IAAI,2BAA2B,EAAE,MAAM,0BAA0B,CAAC;AAiCtG,OAAO,EAAE,KAAK,eAAe,EAAQ,MAAM,kBAAkB,CAAC;AAC9D,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAoD7D,KAAK,sBAAsB,GAAG,2BAA2B,GAAG;IAAE,IAAI,EAAE,cAAc,CAAA;CAAE,CAAC;AAErF,eAAO,MAAM,iBAAiB,gIAsB5B,CAAC;AAEH,MAAM,MAAM,uCAAuC,GAAG,eAAe,GAAG;IACpE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC9B,CAAA;AAED,eAAO,MAAM,kCAAkC,wNAY9C,CAAC"}