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

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 (121) hide show
  1. package/dist/src/design_system/colors/generated/{dark.d.ts → css_variables.dark.d.ts} +1 -1
  2. package/dist/src/design_system/colors/generated/css_variables.dark.d.ts.map +1 -0
  3. package/dist/src/design_system/colors/generated/css_variables.dark.js +147 -0
  4. package/dist/src/design_system/colors/generated/css_variables.dark.js.map +1 -0
  5. package/dist/src/design_system/colors/generated/{light.d.ts → css_variables.light.d.ts} +1 -1
  6. package/dist/src/design_system/colors/generated/css_variables.light.d.ts.map +1 -0
  7. package/dist/src/design_system/colors/generated/css_variables.light.js +147 -0
  8. package/dist/src/design_system/colors/generated/css_variables.light.js.map +1 -0
  9. package/dist/src/design_system/colors/generated/{palette.dark.d.ts → css_variables_palette.dark.d.ts} +1 -1
  10. package/dist/src/design_system/colors/generated/css_variables_palette.dark.d.ts.map +1 -0
  11. package/dist/src/design_system/colors/generated/css_variables_palette.dark.js +74 -0
  12. package/dist/src/design_system/colors/generated/css_variables_palette.dark.js.map +1 -0
  13. package/dist/src/design_system/colors/generated/{palette.light.d.ts → css_variables_palette.light.d.ts} +1 -1
  14. package/dist/src/design_system/colors/generated/css_variables_palette.light.d.ts.map +1 -0
  15. package/dist/src/design_system/colors/generated/css_variables_palette.light.js +74 -0
  16. package/dist/src/design_system/colors/generated/css_variables_palette.light.js.map +1 -0
  17. package/dist/src/design_system/colors/index.d.ts +4 -4
  18. package/dist/src/design_system/colors/index.d.ts.map +1 -1
  19. package/dist/src/design_system/colors/index.js +4 -4
  20. package/dist/src/design_system/colors/index.js.map +1 -1
  21. package/dist/tsconfig.build.tsbuildinfo +1 -1
  22. package/package.json +3 -2
  23. package/src/codemods/generate_typograpy_tokens_files.mjs +137 -0
  24. package/src/components/action_link.tsx +60 -0
  25. package/src/components/actor_template_card.tsx +116 -0
  26. package/src/components/badge.tsx +148 -0
  27. package/src/components/banner.tsx +94 -0
  28. package/src/components/blog_article.tsx +85 -0
  29. package/src/components/box.tsx +127 -0
  30. package/src/components/button.tsx +305 -0
  31. package/src/components/chip.tsx +128 -0
  32. package/src/components/code/action_button.tsx +96 -0
  33. package/src/components/code/code_block/code_block.styled.tsx +180 -0
  34. package/src/components/code/code_block/code_block.tsx +224 -0
  35. package/src/components/code/code_block/code_block_with_tabs.tsx +257 -0
  36. package/src/components/code/code_block/utils.tsx +67 -0
  37. package/src/components/code/index.ts +5 -0
  38. package/src/components/code/inline_code/inline_code.tsx +62 -0
  39. package/src/components/code/one_line_code/one_line_code.tsx +228 -0
  40. package/src/components/code/prism_highlighter.tsx +180 -0
  41. package/src/components/color_wheel_gradient.tsx +31 -0
  42. package/src/components/floating/index.ts +3 -0
  43. package/src/components/floating/menu.tsx +189 -0
  44. package/src/components/floating/menu_common.tsx +31 -0
  45. package/src/components/floating/menu_components.tsx +99 -0
  46. package/src/components/image.tsx +24 -0
  47. package/src/components/index.ts +22 -0
  48. package/src/components/link.tsx +114 -0
  49. package/src/components/message.tsx +153 -0
  50. package/src/components/rating.tsx +106 -0
  51. package/src/components/readme_renderer/index.ts +3 -0
  52. package/src/components/readme_renderer/pythonize_value.ts +76 -0
  53. package/src/components/readme_renderer/table_of_contents.tsx +272 -0
  54. package/src/components/readme_renderer/utils.tsx +46 -0
  55. package/src/components/simple_markdown/index.ts +2 -0
  56. package/src/components/simple_markdown/simple_markdown.tsx +214 -0
  57. package/src/components/simple_markdown/simple_markdown_components.tsx +293 -0
  58. package/src/components/tabs/index.ts +2 -0
  59. package/src/components/tabs/tab.tsx +217 -0
  60. package/src/components/tabs/tabs.tsx +169 -0
  61. package/src/components/tag.tsx +196 -0
  62. package/src/components/text/heading_content.tsx +56 -0
  63. package/src/components/text/heading_marketing.tsx +55 -0
  64. package/src/components/text/heading_shared.tsx +55 -0
  65. package/src/components/text/index.ts +19 -0
  66. package/src/components/text/text_base.tsx +52 -0
  67. package/src/components/text/text_content.tsx +104 -0
  68. package/src/components/text/text_marketing.tsx +152 -0
  69. package/src/components/text/text_shared.tsx +95 -0
  70. package/src/components/tile/horizontal_tile.tsx +77 -0
  71. package/src/components/tile/index.ts +2 -0
  72. package/src/components/tile/shared.ts +27 -0
  73. package/src/components/tile/vertical_tile.tsx +59 -0
  74. package/src/components/to_consolidate/card.tsx +141 -0
  75. package/src/components/to_consolidate/index.ts +4 -0
  76. package/src/components/to_consolidate/markdown.tsx +609 -0
  77. package/src/components/to_consolidate/pagination.tsx +136 -0
  78. package/src/components/to_consolidate/tab_number_chip.tsx +31 -0
  79. package/src/design_system/colors/build_color_tokens.js +183 -0
  80. package/src/design_system/colors/figma_color_tokens.dark.json +886 -0
  81. package/src/design_system/colors/figma_color_tokens.light.json +886 -0
  82. package/src/design_system/colors/generated/colors_theme.dark.ts +110 -0
  83. package/src/design_system/colors/generated/colors_theme.light.ts +110 -0
  84. package/{dist/src/design_system/colors/generated/dark.js → src/design_system/colors/generated/css_variables.dark.ts} +1 -1
  85. package/{dist/src/design_system/colors/generated/light.js → src/design_system/colors/generated/css_variables.light.ts} +1 -1
  86. package/{dist/src/design_system/colors/generated/palette.dark.js → src/design_system/colors/generated/css_variables_palette.dark.ts} +1 -1
  87. package/{dist/src/design_system/colors/generated/palette.light.js → src/design_system/colors/generated/css_variables_palette.light.ts} +1 -1
  88. package/{dist/src/design_system/properties_theme.js → src/design_system/colors/generated/properties_theme.ts} +20 -156
  89. package/src/design_system/colors/index.ts +7 -0
  90. package/src/design_system/supernova_typography_tokens.json +657 -0
  91. package/src/design_system/theme.ts +25 -0
  92. package/src/design_system/tokens/index.ts +5 -0
  93. package/src/design_system/tokens/layouts.ts +29 -0
  94. package/src/design_system/tokens/radiuses.ts +22 -0
  95. package/src/design_system/tokens/shadows.ts +22 -0
  96. package/src/design_system/tokens/spaces.ts +15 -0
  97. package/src/design_system/tokens/transitions.ts +19 -0
  98. package/src/design_system/typography_theme.ts +197 -0
  99. package/src/index.ts +8 -0
  100. package/src/type_utils.ts +7 -0
  101. package/src/ui_dependency_provider.tsx +58 -0
  102. package/src/utils/copy_to_clipboard.ts +24 -0
  103. package/src/utils/image_color.ts +42 -0
  104. package/src/utils/index.ts +4 -0
  105. package/src/utils/resize_observer.ts +18 -0
  106. package/src/utils/sanitization.ts +14 -0
  107. package/dist/src/design_system/colors/generated/dark.d.ts.map +0 -1
  108. package/dist/src/design_system/colors/generated/dark.js.map +0 -1
  109. package/dist/src/design_system/colors/generated/light.d.ts.map +0 -1
  110. package/dist/src/design_system/colors/generated/light.js.map +0 -1
  111. package/dist/src/design_system/colors/generated/palette.dark.d.ts.map +0 -1
  112. package/dist/src/design_system/colors/generated/palette.dark.js.map +0 -1
  113. package/dist/src/design_system/colors/generated/palette.light.d.ts.map +0 -1
  114. package/dist/src/design_system/colors/generated/palette.light.js.map +0 -1
  115. package/dist/src/design_system/colors_theme.d.ts +0 -213
  116. package/dist/src/design_system/colors_theme.d.ts.map +0 -1
  117. package/dist/src/design_system/colors_theme.js +0 -213
  118. package/dist/src/design_system/colors_theme.js.map +0 -1
  119. package/dist/src/design_system/properties_theme.d.ts +0 -175
  120. package/dist/src/design_system/properties_theme.d.ts.map +0 -1
  121. package/dist/src/design_system/properties_theme.js.map +0 -1
@@ -0,0 +1,127 @@
1
+ import React, { forwardRef } from 'react';
2
+ import styled, { css } from 'styled-components';
3
+
4
+ import { theme } from '../design_system/theme.js';
5
+ import type { Size } from '../design_system/tokens/index.js';
6
+ import type { WithTransientProps } from '../type_utils.js';
7
+
8
+ type ExtendedSize = Size | 'none' | 'auto';
9
+
10
+ export interface MarginSpacingProps {
11
+ m?: ExtendedSize,
12
+ mt?: ExtendedSize,
13
+ mb?: ExtendedSize,
14
+ ml?: ExtendedSize,
15
+ mr?: ExtendedSize,
16
+ mx?: ExtendedSize,
17
+ my?: ExtendedSize,
18
+ }
19
+
20
+ export interface PaddingSpacingProps {
21
+ p?: ExtendedSize,
22
+ pt?: ExtendedSize,
23
+ pb?: ExtendedSize,
24
+ pl?: ExtendedSize,
25
+ pr?: ExtendedSize,
26
+ px?: ExtendedSize,
27
+ py?: ExtendedSize,
28
+ }
29
+
30
+ type SharedBoxProps = {
31
+ children?: React.ReactNode,
32
+ className?: string,
33
+ style?: React.CSSProperties
34
+ onClick?: (e: React.MouseEvent) => void,
35
+ id?: string,
36
+ }
37
+
38
+ // This should be renamed - these props are global for any element not just Boxes
39
+ export type RegularBoxProps = SharedBoxProps & { as?: React.ElementType };
40
+
41
+ type OlBoxProps = SharedBoxProps & { as: 'ol', start?: number };
42
+
43
+ /** Combines together RegularBoxProps and props for specific elements. */
44
+ type AnyBoxProps = RegularBoxProps | OlBoxProps;
45
+
46
+ export type BoxProps = MarginSpacingProps & PaddingSpacingProps & AnyBoxProps;
47
+
48
+ const getSizeValue = (token?: ExtendedSize) => {
49
+ if (!token || token === 'none') return 0;
50
+ if (token === 'auto') return 'auto';
51
+ return theme.space[token] || 0;
52
+ };
53
+
54
+ const StyledBox = styled.div<WithTransientProps<MarginSpacingProps & PaddingSpacingProps>>`
55
+ ${({ $mt, $my, $m }) => ($mt || $my || $m) && css`
56
+ margin-top: ${getSizeValue($mt || $my || $m)};
57
+ `}
58
+
59
+ ${({ $mb, $my, $m }) => ($mb || $my || $m) && css`
60
+ margin-bottom: ${getSizeValue($mb || $my || $m)};
61
+ `}
62
+
63
+ ${({ $mr, $mx, $m }) => ($mr || $mx || $m) && css`
64
+ margin-right: ${getSizeValue($mr || $mx || $m)};
65
+ `}
66
+
67
+ ${({ $ml, $mx, $m }) => ($ml || $mx || $m) && css`
68
+ margin-left: ${getSizeValue($ml || $mx || $m)};
69
+ `}
70
+
71
+ ${({ $pt, $py, $p }) => ($pt || $py || $p) && css`
72
+ padding-top: ${getSizeValue($pt || $py || $p)};
73
+ `}
74
+
75
+ ${({ $pb, $py, $p }) => ($pb || $py || $p) && css`
76
+ padding-bottom: ${getSizeValue($pb || $py || $p)};
77
+ `}
78
+
79
+ ${({ $pr, $px, $p }) => ($pr || $px || $p) && css`
80
+ padding-right: ${getSizeValue($pr || $px || $p)};
81
+ `}
82
+
83
+ ${({ $pl, $px, $p }) => ($pl || $px || $p) && css`
84
+ padding-left: ${getSizeValue($pl || $px || $p)};
85
+ `}
86
+ `;
87
+ // This component should work as a base component for all low level components (Heading, Message, Card, ...) to make it easy to define spacing.
88
+ // Right now, it's quite common to define some sort of spacing on these components already using css. Card = styled.div`margin-bottom: theme.space.space8`
89
+ // We should get rid of it and define it using props for Box component Card = styled(Box).attrs({mb: 'space8'})
90
+ export const Box = forwardRef<HTMLElement, BoxProps>(({
91
+ m,
92
+ mt,
93
+ mb,
94
+ ml,
95
+ mr,
96
+ mx,
97
+ my,
98
+ p,
99
+ pt,
100
+ pb,
101
+ pl,
102
+ pr,
103
+ px,
104
+ py,
105
+ as,
106
+ ...rest
107
+ }: BoxProps, ref) => (
108
+ <StyledBox
109
+ $m={m}
110
+ $mt={mt}
111
+ $mb={mb}
112
+ $ml={ml}
113
+ $mr={mr}
114
+ $mx={mx}
115
+ $my={my}
116
+ $p={p}
117
+ $pt={pt}
118
+ $pb={pb}
119
+ $pl={pl}
120
+ $pr={pr}
121
+ $px={px}
122
+ $py={py}
123
+ as={as}
124
+ ref={ref}
125
+ {...rest}
126
+ />
127
+ ));
@@ -0,0 +1,305 @@
1
+ import React, { forwardRef } from 'react';
2
+ import styled, { css } from 'styled-components';
3
+
4
+ import { ExternalLinkIcon } from '@apify/ui-icons';
5
+
6
+ import { theme } from '../design_system/theme.js';
7
+ import { type WithRequired, type WithTransientProps } from '../type_utils.js';
8
+ import { useSharedUiDependencies } from '../ui_dependency_provider.js';
9
+ import { Box, type MarginSpacingProps, type RegularBoxProps } from './box.js';
10
+ import { isUrlExternal, Link, type LinkProps } from './link.js';
11
+
12
+ type ButtonSize = 'medium' | 'small';
13
+ type ButtonColor = 'default' | 'success' | 'danger';
14
+ type ButtonVariant = 'primary' | 'secondary' | 'text';
15
+
16
+ export interface TransientButtonProps {
17
+ size?: ButtonSize;
18
+ color?: ButtonColor;
19
+ variant?: ButtonVariant;
20
+ }
21
+
22
+ export interface RegularButtonProps {
23
+ trackingId?: string,
24
+ trackingData?: object,
25
+ LeftIcon?: React.ElementType,
26
+ RightIcon?: React.ElementType,
27
+ disabled?: boolean;
28
+ }
29
+
30
+ // Props shared for both types of the button
31
+ export type CommonButtonProps = RegularButtonProps & TransientButtonProps & MarginSpacingProps;
32
+ // Regular button must have onClick defined
33
+ export type ButtonProps = CommonButtonProps & WithRequired<RegularBoxProps, 'onClick'>;
34
+ // OR it can pass to to become anchor link - in that case onClick is not needed
35
+ export type AnchorButtonProps = CommonButtonProps & RegularBoxProps & LinkProps;
36
+
37
+ // typeguard to distinguish between the two options for props
38
+ function isAnchorButton(props: ButtonProps | AnchorButtonProps): props is AnchorButtonProps {
39
+ return (props as AnchorButtonProps).to !== undefined;
40
+ }
41
+
42
+ type ButtonColorCombinations = {
43
+ [Type in ButtonVariant]: {
44
+ [Size in ButtonColor]: {
45
+ textColor: string,
46
+ borderColor: string
47
+ backgroundColor: string,
48
+
49
+ // hover & active state affects both border & background.
50
+ hoverColor?: string,
51
+ activeColor?: string,
52
+ actionTextColor?: string,
53
+
54
+ // only exception is primary outlined button
55
+ actionBorderColor?: string
56
+ }
57
+ };
58
+ };
59
+
60
+ type ButtonSizeCombinations = {
61
+ [Size in ButtonSize]: {
62
+ fontSize: number,
63
+ horizontalPadding: number,
64
+ height: number,
65
+ };
66
+ };
67
+
68
+ const BUTTON_COLOR_VARIANTS_CSS: ButtonColorCombinations = {
69
+ primary: {
70
+ default: {
71
+ textColor: theme.color.neutral.backgroundSubtle,
72
+ backgroundColor: theme.color.primary.action,
73
+ borderColor: theme.color.primary.action,
74
+ hoverColor: theme.color.primary.actionHover,
75
+ activeColor: theme.color.primary.actionActive,
76
+ },
77
+ success: {
78
+ textColor: theme.color.neutral.backgroundSubtle,
79
+ backgroundColor: theme.color.success.action,
80
+ borderColor: theme.color.success.action,
81
+ hoverColor: theme.color.success.actionHover,
82
+ activeColor: theme.color.success.actionActive,
83
+ },
84
+ danger: {
85
+ textColor: theme.color.neutral.backgroundSubtle,
86
+ backgroundColor: theme.color.danger.action,
87
+ borderColor: theme.color.danger.action,
88
+ hoverColor: theme.color.danger.actionHover,
89
+ activeColor: theme.color.danger.actionActive,
90
+ },
91
+ },
92
+ secondary: {
93
+ default: {
94
+ textColor: theme.color.neutral.text,
95
+ backgroundColor: theme.color.neutral.backgroundMuted,
96
+ borderColor: theme.color.neutral.border,
97
+ hoverColor: theme.color.neutral.actionSecondaryHover,
98
+ activeColor: theme.color.neutral.actionSecondaryActive,
99
+ actionBorderColor: theme.color.neutral.border,
100
+ },
101
+ success: {
102
+ textColor: theme.color.success.text,
103
+ backgroundColor: theme.color.neutral.backgroundMuted,
104
+ borderColor: theme.color.neutral.border,
105
+ hoverColor: theme.color.success.actionHover,
106
+ activeColor: theme.color.success.actionActive,
107
+ actionTextColor: theme.color.neutral.background,
108
+ },
109
+ danger: {
110
+ textColor: theme.color.danger.text,
111
+ backgroundColor: theme.color.neutral.backgroundMuted,
112
+ borderColor: theme.color.neutral.border,
113
+ hoverColor: theme.color.danger.actionHover,
114
+ activeColor: theme.color.danger.actionActive,
115
+ actionTextColor: theme.color.neutral.background,
116
+ },
117
+ },
118
+ text: {
119
+ default: {
120
+ textColor: theme.color.neutral.text,
121
+ backgroundColor: 'transparent',
122
+ borderColor: 'transparent',
123
+ // TODO: Not sure about these
124
+ hoverColor: theme.color.neutral.hover,
125
+ activeColor: theme.color.neutral.actionSecondaryActive,
126
+ },
127
+ success: {
128
+ textColor: theme.color.success.text,
129
+ backgroundColor: 'transparent',
130
+ borderColor: 'transparent',
131
+ hoverColor: theme.color.success.backgroundSubtleHover,
132
+ activeColor: theme.color.success.backgroundSubtleActive,
133
+ },
134
+ danger: {
135
+ textColor: theme.color.danger.text,
136
+ backgroundColor: 'transparent',
137
+ borderColor: 'transparent',
138
+ hoverColor: theme.color.danger.backgroundSubtleHover,
139
+ activeColor: theme.color.danger.backgroundSubtleActive,
140
+ },
141
+ },
142
+ };
143
+
144
+ export const BUTTON_SIZE_VARIANTS_CSS: ButtonSizeCombinations = {
145
+ medium: {
146
+ fontSize: 14,
147
+ height: 36,
148
+ horizontalPadding: 12,
149
+ },
150
+ small: {
151
+ fontSize: 14,
152
+ height: 28,
153
+ horizontalPadding: 8,
154
+ },
155
+ };
156
+
157
+ export const getButtonColorStyles = (variant: ButtonVariant = 'primary', color: ButtonColor = 'default') => {
158
+ const {
159
+ backgroundColor,
160
+ borderColor,
161
+ textColor,
162
+ actionTextColor,
163
+ activeColor,
164
+ hoverColor,
165
+ actionBorderColor,
166
+ } = BUTTON_COLOR_VARIANTS_CSS[variant][color];
167
+
168
+ return css`
169
+ color: ${textColor};
170
+ background-color: ${backgroundColor};
171
+ border-color: ${borderColor};
172
+
173
+ &:hover {
174
+ color: ${actionTextColor || textColor};
175
+ background-color: ${hoverColor};
176
+ border-color: ${actionBorderColor || hoverColor};
177
+ }
178
+
179
+ &:active {
180
+ color: ${actionTextColor || textColor};
181
+ background-color: ${activeColor};
182
+ border-color: ${actionBorderColor || activeColor};
183
+ }
184
+
185
+ &:disabled {
186
+ color: ${theme.color.neutral.textDisabled};
187
+ background-color: ${theme.color.neutral.disabled};
188
+ border-color: ${variant === 'text' ? 'transparent' : theme.color.neutral.disabled};
189
+
190
+ cursor: default;
191
+ }
192
+ `;
193
+ };
194
+
195
+ export const getButtonSizeStyles = (size: ButtonSize = 'medium') => {
196
+ const {
197
+ fontSize,
198
+ height,
199
+ horizontalPadding,
200
+ } = BUTTON_SIZE_VARIANTS_CSS[size];
201
+
202
+ return css`
203
+ height: ${height}px;
204
+ font-size: ${fontSize}px;
205
+ /* We just want to ensure padding on the sides. Height is set the the hard way for simplicity */
206
+ padding: 0 ${horizontalPadding}px;
207
+ `;
208
+ };
209
+
210
+ const StyledButton = styled(Box)<WithTransientProps<TransientButtonProps>>`
211
+ /* Basic positioning */
212
+ display: inline-flex;
213
+ align-items: center;
214
+ /* NOT sure about this. It needs to be set when we want 100% width button */
215
+ /* Maybe we can add block property */
216
+ justify-content: center;
217
+ gap: ${theme.space.space8};
218
+
219
+ /* Basic styles */
220
+ font-weight: 500;
221
+ white-space: nowrap;
222
+ cursor: pointer;
223
+ transition: border-color ${theme.transition.fastEaseOut}, background-color ${theme.transition.fastEaseOut};
224
+
225
+ /* Border is always defined, but it can be set to transparent */
226
+ border-style: solid;
227
+ border-width: 1px;
228
+ border-radius: ${theme.radius.radius6};
229
+ border-color: transparent;
230
+
231
+ /* Colors */
232
+ ${(props) => getButtonColorStyles(props.$variant, props.$color)}
233
+
234
+ /* Paddings & font size */
235
+ ${(props) => getButtonSizeStyles(props.$size)}
236
+ `;
237
+
238
+ export const Button = forwardRef<HTMLElement, ButtonProps | AnchorButtonProps>((props, ref) => {
239
+ const {
240
+ as,
241
+ children,
242
+ size,
243
+ color,
244
+ variant,
245
+ LeftIcon,
246
+ RightIcon,
247
+ onClick,
248
+ trackingId,
249
+ trackingData,
250
+ ...rest
251
+ } = props;
252
+
253
+ const {
254
+ trackClick,
255
+ windowLocationHost,
256
+ } = useSharedUiDependencies();
257
+ const trackedOnClick = (e: React.MouseEvent) => {
258
+ if (trackClick && trackingId) trackClick(trackingId, trackingData);
259
+ if (onClick) onClick(e);
260
+ };
261
+
262
+ const iconSize = size === 'medium' ? '16' : '12';
263
+
264
+ if (isAnchorButton(props)) {
265
+ const isExternal = isUrlExternal(props.to, windowLocationHost);
266
+ const EffectiveRightIcon = (isExternal && !props.hideExternalIcon) ? ExternalLinkIcon : RightIcon;
267
+
268
+ return (
269
+ <StyledButton
270
+ $size={size}
271
+ $color={color}
272
+ $variant={variant}
273
+ // If anchor is undefined, we just render it as a regular button
274
+ forwardedAs={props.disabled ? 'button' : Link}
275
+ ref={ref}
276
+ onClick={trackedOnClick}
277
+ to={props.to}
278
+ {...rest}
279
+ // If we want to show external icon, we use button's slot for icon
280
+ hideExternalIcon={true}
281
+ >
282
+ {LeftIcon && <LeftIcon size={iconSize} />}
283
+ {children}
284
+ {EffectiveRightIcon && <EffectiveRightIcon size={iconSize} />}
285
+ </StyledButton>
286
+ );
287
+ }
288
+
289
+ return (
290
+ <StyledButton
291
+ $size={size}
292
+ $color={color}
293
+ $variant={variant}
294
+ forwardedAs={ as || 'button'}
295
+ ref={ref}
296
+ onClick={trackedOnClick}
297
+ type='button'
298
+ {...rest}
299
+ >
300
+ {LeftIcon && <LeftIcon size={iconSize} />}
301
+ {children}
302
+ {RightIcon && <RightIcon size={iconSize} />}
303
+ </StyledButton>
304
+ );
305
+ });
@@ -0,0 +1,128 @@
1
+ import clsx from 'clsx';
2
+ import type { FC } from 'react';
3
+ import React, { forwardRef } from 'react';
4
+ import styled, { css } from 'styled-components';
5
+
6
+ import type { ValueOf } from '@apify-packages/types';
7
+
8
+ import { theme } from '../design_system/theme.js';
9
+ import type { RegularBoxProps } from './box.js';
10
+
11
+ const CHIP_SIZES = {
12
+ EXTRA_SMALL: 'XS',
13
+ SMALL: 'S',
14
+ MEDIUM: 'M',
15
+ LARGE: 'L',
16
+ } as const;
17
+ type CHIP_SIZES = ValueOf<typeof CHIP_SIZES>;
18
+
19
+ const CHIP_TYPES = {
20
+ DEFAULT: 'DEFAULT',
21
+ PRIMARY: 'PRIMARY',
22
+ SUCCESS: 'SUCCESS',
23
+ WARNING: 'WARNING',
24
+ DANGER: 'DANGER',
25
+ } as const;
26
+ type CHIP_TYPES = ValueOf<typeof CHIP_TYPES>;
27
+
28
+ export const classNames = {
29
+ BODY: 'Chip-body',
30
+ };
31
+
32
+ const chipSizeStyle = {
33
+ [CHIP_SIZES.EXTRA_SMALL]: css`
34
+ font-size: 12px;
35
+ line-height: 16px;
36
+ padding: 0 4px;
37
+ border-radius: 6px;
38
+ `,
39
+ [CHIP_SIZES.SMALL]: css`
40
+ font-size: 12px;
41
+ line-height: 16px;
42
+ padding: 2px 4px;
43
+ border-radius: 6px;
44
+ `,
45
+ [CHIP_SIZES.MEDIUM]: css`
46
+ font-size: 14px;
47
+ line-height: 20px;
48
+ padding: 2px 8px;
49
+ border-radius: 100px;
50
+ `,
51
+ [CHIP_SIZES.LARGE]: css`
52
+ font-size: 16px;
53
+ line-height: 20px;
54
+ padding: 2px 8px;
55
+ border-radius: 100px;
56
+ `,
57
+ } satisfies Record<CHIP_SIZES, unknown>;
58
+
59
+ const chipTypeStyle = {
60
+ [CHIP_TYPES.DEFAULT]: css`
61
+ color: ${theme.color.neutral.text};
62
+ background: ${theme.color.neutral.chipBackground};
63
+ `,
64
+ [CHIP_TYPES.PRIMARY]: css`
65
+ color: ${theme.color.primary.chipText};
66
+ background: ${theme.color.primary.chipBackground};
67
+ `,
68
+ [CHIP_TYPES.SUCCESS]: css`
69
+ color: ${theme.color.success.chipText};
70
+ background: ${theme.color.success.chipBackground};
71
+ `,
72
+ [CHIP_TYPES.WARNING]: css`
73
+ color: ${theme.color.warning.chipText};
74
+ background: ${theme.color.warning.chipBackground};
75
+ `,
76
+ [CHIP_TYPES.DANGER]: css`
77
+ color: ${theme.color.danger.chipText};
78
+ background: ${theme.color.danger.chipBackground};
79
+ `,
80
+ } satisfies Record<CHIP_TYPES, unknown>;
81
+
82
+ const StyledChip = styled.span<{size: CHIP_SIZES, type: CHIP_TYPES, clickable: boolean}>`
83
+ ${({ size }) => chipSizeStyle[size]};
84
+ ${({ type }) => chipTypeStyle[type]};
85
+ /* Static styles */
86
+ width: fit-content;
87
+ display: flex;
88
+ flex-direction: row;
89
+ justify-content: center;
90
+ align-items: center;
91
+ font-weight: normal;
92
+ white-space: nowrap;
93
+ cursor: ${({ clickable }) => (clickable ? 'pointer' : 'default')};
94
+ gap: ${theme.space.space4};
95
+ `;
96
+
97
+ export type ChipProps = RegularBoxProps & {
98
+ type?: CHIP_TYPES
99
+ size?: CHIP_SIZES
100
+ icon?: React.ReactNode
101
+ clickable?: boolean
102
+ }
103
+
104
+ /**
105
+ * Component for displaying status and for labelling other components.
106
+ */
107
+ export const Chip = forwardRef(({
108
+ type = CHIP_TYPES.DEFAULT,
109
+ size = CHIP_SIZES.MEDIUM,
110
+ icon,
111
+ children,
112
+ className,
113
+ ...passThroughProps
114
+ }: ChipProps, ref) => {
115
+ const otherProps = { ...passThroughProps, type, size, className: clsx(className, classNames.BODY) };
116
+
117
+ return <StyledChip ref={ref} {...otherProps}>{children}{icon}</StyledChip>;
118
+ });
119
+
120
+ Chip.displayName = 'Chip';
121
+
122
+ type SpecificChipProps = Omit<ChipProps, 'type'>
123
+
124
+ export const PrimaryChip: FC<SpecificChipProps> = (props) => <Chip type={CHIP_TYPES.PRIMARY} {...props} />;
125
+ export const NeutralChip: FC<SpecificChipProps> = (props) => <Chip type={CHIP_TYPES.DEFAULT} {...props} />;
126
+ export const SuccessChip: FC<SpecificChipProps> = (props) => <Chip type={CHIP_TYPES.SUCCESS} {...props} />;
127
+ export const DangerChip: FC<SpecificChipProps> = (props) => <Chip type={CHIP_TYPES.DANGER} {...props} />;
128
+ export const WarningChip: FC<SpecificChipProps> = (props) => <Chip type={CHIP_TYPES.WARNING} {...props} />;
@@ -0,0 +1,96 @@
1
+ import React from 'react';
2
+ import styled, { css } from 'styled-components';
3
+
4
+ import { CheckIcon, CopyIcon } from '@apify/ui-icons';
5
+
6
+ import { theme } from '../../design_system/theme.js';
7
+ import { useCopyToClipboard } from '../../utils/index.js';
8
+ import { Text } from '../text/index.js';
9
+
10
+ interface StyledButtonProps {
11
+ $successStyle?: boolean;
12
+ $hasText?: boolean;
13
+ }
14
+
15
+ const StyledButton = styled.button<StyledButtonProps>`
16
+ display: flex;
17
+ justify-content: center;
18
+ align-items: center;
19
+
20
+ border: 1px solid ${theme.color.neutral.border};
21
+ border-radius: ${theme.radius.radius6};
22
+
23
+ cursor: pointer;
24
+
25
+ background: ${theme.color.neutral.backgroundMuted};
26
+ color: ${theme.color.neutral.icon};
27
+ &:hover {
28
+ background-color: ${theme.color.neutral.hover};
29
+ }
30
+
31
+ padding: ${theme.space.space4};
32
+ height: 2.8rem;
33
+ width: 2.8rem;
34
+
35
+ svg {
36
+ width: 2rem;
37
+ height: 2rem;
38
+ }
39
+
40
+ ${({ $hasText }) => $hasText
41
+ && css`
42
+ width: auto;
43
+ padding: ${theme.space.space4} ${theme.space.space8};
44
+ p {
45
+ white-space: nowrap;
46
+ }
47
+ `}
48
+
49
+ ${({ $successStyle }) => $successStyle
50
+ && css`
51
+ background-color: ${theme.color.success.action};
52
+ color: ${theme.color.neutral.textOnPrimary};
53
+ border: none;
54
+ :active {
55
+ background-color: ${theme.color.success.actionActive};
56
+ }
57
+ :hover {
58
+ background-color: ${theme.color.success.action};
59
+ }
60
+ `}
61
+ `;
62
+
63
+ interface ActionButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
64
+ successStyle?: boolean;
65
+ }
66
+
67
+ export const ActionButton = ({
68
+ successStyle,
69
+ children,
70
+ ...props
71
+ }: ActionButtonProps) => {
72
+ const hasText = typeof children === 'string';
73
+
74
+ return (
75
+ <StyledButton
76
+ $successStyle={successStyle}
77
+ $hasText={hasText}
78
+ {...props}
79
+ >
80
+ {hasText ? <Text weight="bold">{children}</Text> : children}
81
+ </StyledButton>
82
+ );
83
+ };
84
+
85
+ interface CopyButtonProps extends React.ButtonHTMLAttributes<HTMLButtonElement> {
86
+ code: string;
87
+ }
88
+
89
+ export const CopyButton = ({ code, ...props }: CopyButtonProps) => {
90
+ const [isCopied, handleClick] = useCopyToClipboard({ text: code });
91
+ return (
92
+ <ActionButton onClick={handleClick} data-test='copy_to_clipboard' {...props}>
93
+ {isCopied ? <CheckIcon size="16" /> : <CopyIcon size="16" />}
94
+ </ActionButton>
95
+ );
96
+ };