@apify/ui-library 0.71.1-featcolortokens-178953.55 → 0.71.1-featcolortokens-178953.58

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 (99) hide show
  1. package/dist/tsconfig.build.tsbuildinfo +1 -0
  2. package/package.json +7 -5
  3. package/.stylelintrc +0 -12
  4. package/CHANGELOG.md +0 -3334
  5. package/CODEOWNERS +0 -7
  6. package/eslint.config.mjs +0 -44
  7. package/src/codemods/generate_typograpy_tokens_files.mjs +0 -137
  8. package/src/components/action_link.tsx +0 -60
  9. package/src/components/actor_template_card.tsx +0 -116
  10. package/src/components/badge.tsx +0 -148
  11. package/src/components/banner.tsx +0 -94
  12. package/src/components/blog_article.tsx +0 -85
  13. package/src/components/box.tsx +0 -127
  14. package/src/components/button.tsx +0 -305
  15. package/src/components/chip.tsx +0 -128
  16. package/src/components/code/action_button.tsx +0 -96
  17. package/src/components/code/code_block/code_block.styled.tsx +0 -180
  18. package/src/components/code/code_block/code_block.tsx +0 -224
  19. package/src/components/code/code_block/code_block_with_tabs.tsx +0 -257
  20. package/src/components/code/code_block/utils.tsx +0 -67
  21. package/src/components/code/index.ts +0 -5
  22. package/src/components/code/inline_code/inline_code.tsx +0 -62
  23. package/src/components/code/one_line_code/one_line_code.tsx +0 -228
  24. package/src/components/code/prism_highlighter.tsx +0 -180
  25. package/src/components/color_wheel_gradient.tsx +0 -31
  26. package/src/components/floating/index.ts +0 -3
  27. package/src/components/floating/menu.tsx +0 -189
  28. package/src/components/floating/menu_common.tsx +0 -31
  29. package/src/components/floating/menu_components.tsx +0 -99
  30. package/src/components/image.tsx +0 -24
  31. package/src/components/index.ts +0 -22
  32. package/src/components/link.tsx +0 -114
  33. package/src/components/message.tsx +0 -153
  34. package/src/components/rating.tsx +0 -106
  35. package/src/components/readme_renderer/index.ts +0 -3
  36. package/src/components/readme_renderer/pythonize_value.ts +0 -76
  37. package/src/components/readme_renderer/table_of_contents.tsx +0 -272
  38. package/src/components/readme_renderer/utils.tsx +0 -46
  39. package/src/components/simple_markdown/index.ts +0 -2
  40. package/src/components/simple_markdown/simple_markdown.tsx +0 -214
  41. package/src/components/simple_markdown/simple_markdown_components.tsx +0 -293
  42. package/src/components/tabs/index.ts +0 -2
  43. package/src/components/tabs/tab.tsx +0 -217
  44. package/src/components/tabs/tabs.tsx +0 -169
  45. package/src/components/tag.tsx +0 -196
  46. package/src/components/text/heading_content.tsx +0 -56
  47. package/src/components/text/heading_marketing.tsx +0 -55
  48. package/src/components/text/heading_shared.tsx +0 -55
  49. package/src/components/text/index.ts +0 -19
  50. package/src/components/text/text_base.tsx +0 -52
  51. package/src/components/text/text_content.tsx +0 -104
  52. package/src/components/text/text_marketing.tsx +0 -152
  53. package/src/components/text/text_shared.tsx +0 -95
  54. package/src/components/tile/horizontal_tile.tsx +0 -77
  55. package/src/components/tile/index.ts +0 -2
  56. package/src/components/tile/shared.ts +0 -27
  57. package/src/components/tile/vertical_tile.tsx +0 -59
  58. package/src/components/to_consolidate/card.tsx +0 -141
  59. package/src/components/to_consolidate/index.ts +0 -4
  60. package/src/components/to_consolidate/markdown.tsx +0 -609
  61. package/src/components/to_consolidate/pagination.tsx +0 -136
  62. package/src/components/to_consolidate/tab_number_chip.tsx +0 -31
  63. package/src/design_system/colors/build_color_tokens.js +0 -169
  64. package/src/design_system/colors/figma_color_tokens.dark.json +0 -886
  65. package/src/design_system/colors/figma_color_tokens.light.json +0 -886
  66. package/src/design_system/colors/generated/colors_theme.dark.ts +0 -110
  67. package/src/design_system/colors/generated/colors_theme.light.ts +0 -110
  68. package/src/design_system/colors/generated/dark.ts +0 -147
  69. package/src/design_system/colors/generated/light.ts +0 -147
  70. package/src/design_system/colors/generated/palette.dark.ts +0 -74
  71. package/src/design_system/colors/generated/palette.light.ts +0 -74
  72. package/src/design_system/colors/generated/properties_theme.ts +0 -179
  73. package/src/design_system/colors/index.ts +0 -7
  74. package/src/design_system/colors_theme.ts +0 -213
  75. package/src/design_system/properties_theme.ts +0 -453
  76. package/src/design_system/supernova_typography_tokens.json +0 -657
  77. package/src/design_system/theme.ts +0 -25
  78. package/src/design_system/tokens/index.ts +0 -5
  79. package/src/design_system/tokens/layouts.ts +0 -29
  80. package/src/design_system/tokens/radiuses.ts +0 -22
  81. package/src/design_system/tokens/shadows.ts +0 -22
  82. package/src/design_system/tokens/spaces.ts +0 -15
  83. package/src/design_system/tokens/transitions.ts +0 -19
  84. package/src/design_system/typography_theme.ts +0 -197
  85. package/src/index.ts +0 -8
  86. package/src/type_utils.ts +0 -7
  87. package/src/ui_dependency_provider.tsx +0 -58
  88. package/src/utils/copy_to_clipboard.ts +0 -24
  89. package/src/utils/image_color.ts +0 -42
  90. package/src/utils/index.ts +0 -4
  91. package/src/utils/resize_observer.ts +0 -18
  92. package/src/utils/sanitization.ts +0 -14
  93. package/style-dictionary.config.json +0 -29
  94. package/tsconfig.build.json +0 -17
  95. package/tsconfig.json +0 -10
  96. /package/{src/design_system/colors/generated → style/colors}/dark.scss +0 -0
  97. /package/{src/design_system/colors/generated → style/colors}/light.scss +0 -0
  98. /package/{src/design_system/colors/generated → style/colors}/palette.dark.scss +0 -0
  99. /package/{src/design_system/colors/generated → style/colors}/palette.light.scss +0 -0
@@ -1,180 +0,0 @@
1
- import styled, { css } from 'styled-components';
2
-
3
- import { theme } from '../../../design_system/theme.js';
4
- import { Box } from '../../box.js';
5
- import type { SharedTextProps, SharedTextSize } from '../../text/text_shared.js';
6
-
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
- `;
26
-
27
- export const CodeBlockWrapper = styled(SyntaxHighlighterBaseStylesWrapper) <{
28
- $hasHeader: boolean;
29
- $gradientRotation?: number;
30
- $highlightLines?: number[];
31
- $hasActionButton?: boolean;
32
- $hasTabs?: boolean;
33
- $fullWidth?: boolean;
34
- $showLineNumbers?: boolean;
35
- $fullHeight?: boolean;
36
- size?: SharedTextSize,
37
- }>`
38
- position: relative;
39
- display: flex;
40
- flex-direction: column;
41
- min-width: 266px;
42
-
43
- .CodeBlock-Header {
44
- padding-top: 7px; /* only 7 due to transform translateY(1px) */
45
- gap: ${theme.space.space4};
46
- background-color: ${theme.color.neutral.backgroundSubtle};
47
- border-bottom: 1px solid ${theme.color.neutral.border};
48
- z-index: 3;
49
- position: relative;
50
- display: flex;
51
- height: 4rem;
52
-
53
- .CodeBlock-HeaderTitle {
54
- margin-left: ${theme.space.space16};
55
- margin-bottom: ${theme.space.space8};
56
- margin-top: 0.5rem;
57
- }
58
-
59
- .CodeBlock-HeaderTabsWrapper {
60
- display: flex;
61
- transform: translateY(1px);
62
- padding-right: ${theme.space.space32};
63
- padding-left: ${theme.space.space8};
64
- overflow-x: auto;
65
- overflow-y: hidden;
66
- gap: ${theme.space.space4};
67
-
68
- margin-right: ${({ $hasActionButton }) => ($hasActionButton ? '128' : '20')}px;
69
-
70
- .CodeBlock-Tab {
71
- border-radius: ${theme.radius.radius8};
72
- background-color: transparent;
73
- border: 1px solid transparent;
74
- border-bottom-left-radius: 0;
75
- border-bottom-right-radius: 0;
76
- border-bottom: none;
77
- cursor: pointer;
78
- height: 3.2rem;
79
- max-width: 26rem;
80
-
81
- color: ${theme.color.neutral.textMuted};
82
-
83
- text-align: center;
84
- white-space: nowrap;
85
-
86
- padding: 0.2rem ${theme.space.space8} 0.6rem ${theme.space.space8};
87
- p {
88
- padding-top: 0.2rem;
89
- text-overflow: ellipsis;
90
- overflow: hidden;
91
- }
92
-
93
-
94
- &.selected {
95
- color: ${theme.color.neutral.text};
96
- border: 1px solid ${theme.color.neutral.border};
97
- background-color: ${theme.color.neutral.backgroundMuted};
98
- border-bottom: none;
99
- padding: 0.6rem ${theme.space.space8};
100
- p {
101
- padding-top: 0;
102
- }
103
- }
104
-
105
- &:hover {
106
- border: 1px solid ${theme.color.neutral.border};
107
- border-bottom: none;
108
- text-decoration: none;
109
- }
110
-
111
- &::after {
112
- /* ensures same width of text when switching tabs and making it bold */
113
- ${theme.typography.shared.tablet.bodyMStrong}
114
- display: block;
115
- content: attr(title);
116
- font-weight: bold;
117
- height: 0px;
118
- color: transparent;
119
- overflow: hidden;
120
- visibility: hidden;
121
- }
122
- }
123
- }
124
- }
125
-
126
-
127
- .CodeBlock-TopRightActionsWrapper {
128
- position: absolute;
129
- top: 0;
130
- right: 0;
131
- ${({ $hasHeader }) => ($hasHeader
132
- ? css`
133
- padding-top: 6px;
134
- padding-right: ${theme.space.space8};`
135
- : css`
136
- padding-top: ${theme.space.space16};
137
- padding-right: ${theme.space.space16};`)}
138
-
139
- display: flex;
140
- gap: ${theme.space.space8};
141
- z-index: 3;
142
- height: 3.9rem;
143
-
144
- ${({ $hasHeader }) => $hasHeader && css`
145
- padding-left: ${theme.space.space32};
146
- background: linear-gradient(
147
- to right,
148
- transparent,
149
- ${theme.color.neutral.backgroundSubtle} 20px
150
- );
151
- `}
152
- }
153
-
154
- .CodeBlock-Gradient {
155
- right: 0px;
156
- bottom: 0px;
157
-
158
- aspect-ratio: 1/1;
159
- height: 250%;
160
-
161
- transform: translate(50%, 70%) rotate(${({ $gradientRotation }) => $gradientRotation ?? 0}deg) scaleX(-1);
162
- }
163
-
164
- .CodeBlock-HederDotsWrapper {
165
- display: flex;
166
- padding: ${theme.space.space8};
167
- align-items: flex-start;
168
- gap: ${theme.space.space8};
169
- margin-bottom: 0.5rem;
170
- margin-left: ${theme.space.space8};
171
- background: transparent;
172
-
173
- .CodeBlock-HeaderDot {
174
- width: 1.2rem;
175
- height: 1.2rem;
176
- border-radius: 50%;
177
- background-color: ${theme.color.neutral.iconSubtle};
178
- }
179
- }
180
- `;
@@ -1,224 +0,0 @@
1
- import clsx from 'clsx';
2
- import React, { useMemo, useRef, useState } from 'react';
3
-
4
- import type { RegularBoxProps } from '../../box.js';
5
- import { ColorWheelGradient } from '../../color_wheel_gradient.js';
6
- import { Link } from '../../link.js';
7
- import { Text } from '../../text/index.js';
8
- import type { SharedTextSize } from '../../text/text_shared.js';
9
- import { ActionButton, CopyButton } from '../action_button.js';
10
- import { PrismSyntaxHighlighter } from '../prism_highlighter.js';
11
- import { CodeBlockWrapper } from './code_block.styled.js';
12
- import { getBashLinePrefixes, getNumberLinePrefixes } from './utils.js';
13
-
14
- type CodeTab = {
15
- key: string;
16
- label: string;
17
- code: string;
18
- id?: string;
19
- highlightLines?: number[];
20
- language?: string;
21
- bashCommandsStart?: number[];
22
- to?: string;
23
- }
24
-
25
- type HeaderProps = {
26
- tabs: CodeTab[] | null;
27
- currentTab: CodeTab | null;
28
- onTabChange: (tab: CodeTab, e: React.MouseEvent) => void;
29
- title?: string;
30
- showBashHeader?: boolean;
31
- }
32
-
33
- const LANGUAGES_WITHOUT_LINE_NUMBERS = ['json', 'jsonp', 'jsonp', 'rss', 'yaml', 'xml', 'html', 'bash', 'text', 'dockerfile', 'http'];
34
-
35
- const HeaderDots = () => {
36
- return (
37
- <div className="CodeBlock-HederDotsWrapper">
38
- <div className="CodeBlock-HeaderDot" />
39
- <div className="CodeBlock-HeaderDot" />
40
- <div className="CodeBlock-HeaderDot" />
41
- </div>
42
- );
43
- };
44
-
45
- const Header = ({
46
- tabs,
47
- currentTab,
48
- showBashHeader,
49
- onTabChange,
50
- title,
51
- }: HeaderProps) => {
52
- return (
53
- <div className="CodeBlock-Header">
54
- {showBashHeader && <HeaderDots />}
55
- {title && (
56
- <Text weight="bold" className="CodeBlock-HeaderTitle">
57
- {title}
58
- </Text>
59
- )}
60
- <div className="CodeBlock-HeaderTabsWrapper">
61
- {tabs?.map((tab) => {
62
- const selected = tab.key === currentTab?.key;
63
- const props = {
64
- className: clsx('CodeBlock-Tab', { selected }),
65
- onClick: (e: React.MouseEvent) => onTabChange(tab, e),
66
- title: tab.label,
67
- id: tab.id ?? tab.key,
68
- };
69
-
70
- const label = <Text weight={tab.key === currentTab?.key ? 'bold' : 'normal'}>
71
- {tab.label}
72
- </Text>;
73
-
74
- if (tab.to) {
75
- return (
76
- <Link key={tab.key} to={tab.to} {...props}>
77
- {label}
78
- </Link>
79
- );
80
- }
81
- return (
82
- <div key={tab.key} {...props}>
83
- {label}
84
- </div>
85
- );
86
- })}
87
- </div>
88
- </div>
89
- );
90
- };
91
-
92
- export type CodeBlockProps = RegularBoxProps & {
93
- content: string | CodeTab[]; // TODO: Try to make it work with children props
94
- size?: SharedTextSize;
95
- language?: string | undefined;
96
- className?: string;
97
- hideBashHeader?: boolean;
98
- onTabChange?: (key: string, e: React.MouseEvent) => Promise<void> | void;
99
- showGradient?: boolean;
100
- gradientRotation?: number;
101
- highlightLines?: number[];
102
- showActionButton?: boolean;
103
- actionButtonLabel?: string;
104
- onActionButtonClick?: () => Promise<void> | void;
105
- defaultTabKey?: string;
106
- fullWidth?: boolean;
107
- fullHeight?: boolean;
108
- title?: string;
109
- hideCopyButton?: boolean;
110
- bashCommandsStart?: number[];
111
- hideBashPromptPrefixes?: boolean;
112
- hideLineNumbers?: boolean | undefined;
113
- }
114
-
115
- export const CodeBlock = ({
116
- content,
117
- size,
118
- language,
119
- highlightLines,
120
- onTabChange,
121
- defaultTabKey,
122
- showGradient,
123
- hideBashHeader,
124
- showActionButton,
125
- fullWidth,
126
- actionButtonLabel,
127
- gradientRotation = 340,
128
- hideLineNumbers,
129
- fullHeight,
130
- title,
131
- hideCopyButton,
132
- bashCommandsStart,
133
- hideBashPromptPrefixes,
134
- onActionButtonClick,
135
- ...rest
136
- }: CodeBlockProps) => {
137
- const isMultiTab = content instanceof Array;
138
- const defaultTab = isMultiTab
139
- ? content.find((tab) => tab.key === defaultTabKey) ?? content[0]
140
- : null;
141
- const [currentTab, setCurrentTab] = useState<CodeTab | null>(defaultTab);
142
- const currentCode = (isMultiTab ? currentTab?.code : content)?.trim() ?? '';
143
- const currentLanguage = language ?? currentTab?.language;
144
-
145
- const currentHighlightLines = useMemo(
146
- () => (isMultiTab ? currentTab?.highlightLines ?? [] : highlightLines),
147
- [isMultiTab, currentTab, highlightLines],
148
- );
149
-
150
- const isBash = currentLanguage === 'bash';
151
-
152
- const showLineNumbers = !hideLineNumbers && !LANGUAGES_WITHOUT_LINE_NUMBERS.includes(currentLanguage ?? '');
153
- const showBashHeader = isBash && !hideBashHeader && !isMultiTab;
154
-
155
- const showHeader = isMultiTab || !!title || showBashHeader;
156
-
157
- const syntaxHighlighterRef = useRef<HTMLPreElement>(null);
158
-
159
- const handleTabClick = async (tab: CodeTab, e: React.MouseEvent) => {
160
- await onTabChange?.(tab.key, e);
161
- setCurrentTab(tab);
162
- syntaxHighlighterRef.current?.scrollTo(0, 0);
163
- };
164
-
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]);
179
-
180
- return (
181
- <CodeBlockWrapper
182
- $hasHeader={showHeader}
183
- $gradientRotation={gradientRotation}
184
- $hasActionButton={showActionButton}
185
- $hasTabs={isMultiTab}
186
- $fullWidth={fullWidth}
187
- $fullHeight={fullHeight}
188
- $showLineNumbers={showLineNumbers}
189
- {...rest}
190
- >
191
- {showHeader && (
192
- <Header
193
- tabs={isMultiTab ? content : null}
194
- currentTab={currentTab}
195
- onTabChange={handleTabClick}
196
- showBashHeader={showBashHeader}
197
- title={title}
198
- />
199
- )}
200
-
201
- <PrismSyntaxHighlighter
202
- code={currentCode}
203
- linePrefixes={linePrefixes}
204
- highlightLines={currentHighlightLines}
205
- language={currentLanguage || 'text'}
206
- size={size}
207
- ref={syntaxHighlighterRef}
208
- isSingleLine={false}
209
- />
210
-
211
- <div className="CodeBlock-TopRightActionsWrapper">
212
- {showActionButton && <ActionButton successStyle onClick={onActionButtonClick}>{actionButtonLabel ?? 'Run on Apify'}</ActionButton>}
213
- {!hideCopyButton && <CopyButton code={currentCode} />}
214
- </div>
215
-
216
- {showGradient && (
217
- <ColorWheelGradient
218
- className="CodeBlock-Gradient"
219
- blurSize={69}
220
- />
221
- )}
222
- </CodeBlockWrapper >
223
- );
224
- };
@@ -1,257 +0,0 @@
1
- import clsx from 'clsx';
2
- import React from 'react';
3
- import styled from 'styled-components';
4
-
5
- import { theme } from '../../../design_system/theme.js';
6
- import { useSharedUiDependencies } from '../../../ui_dependency_provider.js';
7
- import { Box, type MarginSpacingProps, type RegularBoxProps } from '../../box.js';
8
- import { Link, type RegularLinkProps } from '../../link.js';
9
- import { HeadingShared } from '../../text/heading_shared.js';
10
- import { CodeBlock, type CodeBlockProps } from './code_block.js';
11
-
12
- export type CodeBlockTabKey = 'cli' | 'http' | 'javascript' | 'mcp' | 'openapi' | 'python' | 'typescript';
13
- type CodeBlockTabConfig = {
14
- label: string;
15
- language: string;
16
- src: string;
17
- };
18
-
19
- export const CODE_BLOCK_TAB_CATALOG: Record<CodeBlockTabKey, CodeBlockTabConfig> = {
20
- cli: {
21
- label: 'CLI',
22
- language: 'bash',
23
- src: 'https://apify.com/img/icons/code.svg',
24
- },
25
- http: {
26
- label: 'HTTP',
27
- language: 'bash',
28
- src: 'https://apify.com/img/icons/http.svg',
29
- },
30
- javascript: {
31
- label: 'JavaScript',
32
- language: 'javascript',
33
- // TODO: duplicate icon from 'template-icons' to 'icons' folder on the web
34
- src: 'https://apify.com/img/template-icons/javascript.svg',
35
- },
36
- mcp: {
37
- label: 'MCP',
38
- language: 'bash',
39
- src: 'https://apify.com/img/icons/mcp.svg',
40
- },
41
- openapi: {
42
- label: 'OpenAPI',
43
- language: 'json',
44
- src: 'https://apify.com/img/icons/openapi.svg',
45
- },
46
- python: {
47
- label: 'Python',
48
- language: 'python',
49
- // TODO: duplicate icon from 'template-icons' to 'icons' folder on the web
50
- src: 'https://apify.com/img/template-icons/python.svg',
51
- },
52
- typescript: {
53
- label: 'TypeScript',
54
- language: 'typescript',
55
- // TODO: duplicate icon from 'template-icons' to 'icons' folder on the web
56
- src: 'https://apify.com/img/template-icons/typescript.svg',
57
- },
58
- };
59
-
60
- type SharedBoxProps = Omit<RegularBoxProps, 'as' | 'children' | 'onClick'> & MarginSpacingProps;
61
-
62
- type SharedCodeBlockProps = Omit<CodeBlockProps, 'bashCommandsStart' | 'content' | 'language' | 'defaultTabKey' | 'onTabChange'>;
63
- type SharedLinkProps = Pick<RegularLinkProps, 'to' | 'rel' | 'target'>;
64
-
65
- export type CodeBlockTabProps = {
66
- key: CodeBlockTabKey;
67
- bashCommandsStart?: number[];
68
- content: string;
69
- languageOverride?: string;
70
- onClick?: (e: React.MouseEvent) => void;
71
- } & Partial<SharedLinkProps>;
72
-
73
- type CodeBlockWithTabsProps = SharedBoxProps & {
74
- codeBlockProps: SharedCodeBlockProps;
75
- currentTabKey: CodeBlockTabKey;
76
- tabs: CodeBlockTabProps[];
77
- };
78
-
79
- export const CODE_BLOCK_WITH_TABS_CLASSNAMES = {
80
- WRAPPER: 'CodeBlockWithTabsWrapper',
81
- TABS: 'CodeBlockWithTabsTabs',
82
- TAB: 'CodeBlockWithTabsTab',
83
- CONTENT: 'CodeBlockWithTabsContent',
84
- };
85
-
86
- const CodeBlockWithTabsWrapper = styled(Box)`
87
- .${CODE_BLOCK_WITH_TABS_CLASSNAMES.TABS} {
88
- min-width: 266px;
89
- height: 72px;
90
- padding-inline: ${theme.space.space8};
91
- display: flex;
92
- gap: ${theme.space.space4};
93
- overflow-x: auto;
94
- background-color: ${theme.color.neutral.backgroundSubtle};
95
- border: 1px solid ${theme.color.neutral.border};
96
- border-bottom: none;
97
- border-top-right-radius: ${theme.radius.radius12};
98
- border-top-left-radius: ${theme.radius.radius12};
99
- position: relative;
100
-
101
- & > [role="tabpanel"] {
102
- position: sticky;
103
- right: 0;
104
- top: 0;
105
- height: 100%;
106
- width: 0;
107
- margin-left: auto;
108
-
109
- &::after {
110
- right: -${theme.space.space8};
111
- height: 100%;
112
- width: ${theme.space.space16};
113
- background: linear-gradient(90deg, rgba(255, 255, 255, 0) 0%, ${theme.color.neutral.backgroundSubtle} 100%);
114
- content: ' ';
115
- pointer-events: none;
116
- position: absolute;
117
- }
118
- }
119
-
120
- @media ${theme.device.tablet} {
121
- height: 88px;
122
- justify-content: center;
123
- gap: ${theme.space.space24};
124
- padding-inline: ${theme.space.space24};
125
-
126
- & > [role="tabpanel"] {
127
- margin-left: unset;
128
-
129
- &::after {
130
- right: -${theme.space.space24};
131
- width: ${theme.space.space32};
132
- }
133
- }
134
- }
135
- }
136
-
137
- .${CODE_BLOCK_WITH_TABS_CLASSNAMES.TAB} {
138
- min-width: 64px;
139
- position: relative;
140
- padding: ${theme.space.space12} ${theme.space.space8};
141
- color: ${theme.color.neutral.textMuted};
142
- display: flex;
143
- flex-direction: column;
144
- flex-shrink: 0;
145
- align-items: center;
146
- justify-content: flex-end;
147
- gap: ${theme.space.space4};
148
- cursor: pointer;
149
-
150
- img {
151
- width: 20px;
152
- height: 20px;
153
- }
154
-
155
- [role="tabpanel"] {
156
- bottom: 0;
157
- width: 100%;
158
- height: 2px;
159
- color: ${theme.color.neutral.text};
160
- background-color: ${theme.color.primaryBlack.action};
161
- border-radius: ${theme.radius.radiusFull};
162
- display: none;
163
- position: absolute;
164
- z-index: 2;
165
- }
166
-
167
- &.selected {
168
- color: ${theme.color.neutral.text};
169
-
170
- [role="tabpanel"] {
171
- display: block;
172
- }
173
- }
174
-
175
- &:hover {
176
- color: ${theme.color.neutral.text};
177
- text-decoration: none;
178
- }
179
- }
180
-
181
- .${CODE_BLOCK_WITH_TABS_CLASSNAMES.CONTENT} {
182
- max-width: initial;
183
- border-top-left-radius: 0;
184
- border-top-right-radius: 0;
185
- }
186
- `;
187
-
188
- const IMG_RESIZE = {
189
- width: 20,
190
- height: 20,
191
- };
192
-
193
- export const CodeBlockWithTabs = ({ className, codeBlockProps, currentTabKey, tabs, ...props }: CodeBlockWithTabsProps) => {
194
- const { generateProxyImageUrl } = useSharedUiDependencies();
195
- const currentTab = tabs.find((tab) => tab.key === currentTabKey) ?? tabs[0];
196
-
197
- return (
198
- <CodeBlockWithTabsWrapper className={clsx(CODE_BLOCK_WITH_TABS_CLASSNAMES.WRAPPER, className)} {...props}>
199
- <div className={CODE_BLOCK_WITH_TABS_CLASSNAMES.TABS}>
200
- {tabs.map((tab) => {
201
- const { label, src } = CODE_BLOCK_TAB_CATALOG[tab.key];
202
- const selected = tab.key === currentTab?.key;
203
-
204
- const commonProps = {
205
- className: clsx(CODE_BLOCK_WITH_TABS_CLASSNAMES.TAB, { selected }),
206
- 'data-test': `code-block-tab-${tab.key}`,
207
- onClick: tab.onClick,
208
- };
209
- const children = (
210
- <>
211
- <img src={generateProxyImageUrl?.(src, { resize: IMG_RESIZE }) ?? src} alt={label} />
212
- <HeadingShared type="titleS" as="p">
213
- {label}
214
- </HeadingShared>
215
- <div role="tabpanel" />
216
- </>
217
- );
218
-
219
- // if the tab has a 'to' prop, render a Link component
220
- if (tab.to) {
221
- return (
222
- <Link
223
- {...commonProps}
224
- to={tab.to}
225
- rel={tab.rel}
226
- target={tab.target}
227
- key={tab.key}
228
- >
229
- {children}
230
- </Link>
231
- );
232
- }
233
-
234
- return (
235
- <div
236
- {...commonProps}
237
- role="button"
238
- key={tab.key}
239
- >
240
- {children}
241
- </div>
242
- );
243
- })}
244
-
245
- <div role="tabpanel" />
246
- </div>
247
- <CodeBlock
248
- bashCommandsStart={currentTab?.bashCommandsStart}
249
- content={currentTab?.content ?? ''}
250
- language={currentTab.languageOverride ?? CODE_BLOCK_TAB_CATALOG[currentTab?.key]?.language}
251
- className={CODE_BLOCK_WITH_TABS_CLASSNAMES.CONTENT}
252
- hideBashHeader
253
- {...codeBlockProps}
254
- />
255
- </CodeBlockWithTabsWrapper>
256
- );
257
- };