@apify/ui-library 1.83.2-fixactorissuescomponentsoncl-2f1509.6 → 1.84.1

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 (32) hide show
  1. package/dist/src/components/code/code_block/code_block_with_tabs.d.ts.map +1 -1
  2. package/dist/src/components/code/code_block/code_block_with_tabs.js +2 -3
  3. package/dist/src/components/code/code_block/code_block_with_tabs.js.map +1 -1
  4. package/dist/src/components/message.d.ts +12 -1
  5. package/dist/src/components/message.d.ts.map +1 -1
  6. package/dist/src/components/message.js +70 -25
  7. package/dist/src/components/message.js.map +1 -1
  8. package/dist/src/components/readme_renderer/table_of_contents.d.ts +1 -1
  9. package/dist/src/components/readme_renderer/table_of_contents.d.ts.map +1 -1
  10. package/dist/src/components/readme_renderer/utils.d.ts +1 -1
  11. package/dist/src/components/readme_renderer/utils.d.ts.map +1 -1
  12. package/dist/src/components/simple_markdown/simple_markdown.d.ts +1 -1
  13. package/dist/src/components/simple_markdown/simple_markdown.d.ts.map +1 -1
  14. package/dist/src/components/simple_markdown/simple_markdown_components.d.ts +1 -1
  15. package/dist/src/components/simple_markdown/simple_markdown_components.d.ts.map +1 -1
  16. package/dist/src/components/to_consolidate/markdown.d.ts +1 -1
  17. package/dist/src/components/to_consolidate/markdown.d.ts.map +1 -1
  18. package/dist/src/components/to_consolidate/markdown.js +2 -2
  19. package/dist/src/utils/image_color.d.ts.map +1 -1
  20. package/dist/src/utils/image_color.js +1 -0
  21. package/dist/src/utils/image_color.js.map +1 -1
  22. package/dist/tsconfig.build.tsbuildinfo +1 -1
  23. package/package.json +3 -7
  24. package/src/components/code/code_block/code_block_with_tabs.tsx +4 -3
  25. package/src/components/message.tsx +116 -38
  26. package/src/components/readme_renderer/table_of_contents.tsx +1 -1
  27. package/src/components/readme_renderer/utils.tsx +1 -1
  28. package/src/components/simple_markdown/simple_markdown.tsx +1 -1
  29. package/src/components/simple_markdown/simple_markdown_components.tsx +1 -1
  30. package/src/components/tag.tsx +1 -1
  31. package/src/components/to_consolidate/markdown.tsx +3 -3
  32. package/src/utils/image_color.ts +1 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apify/ui-library",
3
- "version": "1.83.2-fixactorissuescomponentsoncl-2f1509.6+407316d3118",
3
+ "version": "1.84.1",
4
4
  "description": "React UI library used by apify.com",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",
@@ -26,7 +26,7 @@
26
26
  "It's not nice, but helps us to get around the problem of multiple react instances."
27
27
  ],
28
28
  "dependencies": {
29
- "@apify/ui-icons": "^1.14.0",
29
+ "@apify/ui-icons": "^1.14.1",
30
30
  "@floating-ui/react": "^0.26.2",
31
31
  "@react-hook/resize-observer": "^2.0.2",
32
32
  "clsx": "^2.0.0",
@@ -52,14 +52,10 @@
52
52
  "styled-components": "^5.3.3"
53
53
  },
54
54
  "devDependencies": {
55
- "@apify/eslint-config": "^1.0.0",
56
55
  "@types/lodash": "^4.14.200",
57
56
  "@types/node": "^22.10.5",
58
57
  "@types/react": "^18.2.74",
59
58
  "@types/styled-components": "^5.1.34",
60
- "eslint-plugin-react": "^7.32.2",
61
- "eslint-plugin-react-hooks": "^5.2.0",
62
- "eslint-plugin-sonarjs": "^1.0.3",
63
59
  "recast": "^0.23.9",
64
60
  "style-dictionary": "^4.4.0",
65
61
  "typescript": "^5.1.6"
@@ -69,5 +65,5 @@
69
65
  "src",
70
66
  "style"
71
67
  ],
72
- "gitHead": "407316d311811e7648358e86939a4ba82c503d45"
68
+ "gitHead": "920722b0b5980f8e199451dbd5c1e21969310eb7"
73
69
  }
@@ -1,5 +1,4 @@
1
1
  import clsx from 'clsx';
2
- import _ from 'lodash';
3
2
  import React from 'react';
4
3
  import styled from 'styled-components';
5
4
 
@@ -207,7 +206,7 @@ export const CodeBlockWithTabs = ({ className, codeBlockProps, currentTabKey, ta
207
206
  const commonProps = {
208
207
  className: clsx(CODE_BLOCK_WITH_TABS_CLASSNAMES.TAB, { selected }),
209
208
  'data-test': `code-block-tab-${tab.key}`,
210
- ..._.omit(tab, ['bashCommandsStart', 'content', 'languageOverride']),
209
+ onClick: tab.onClick,
211
210
  };
212
211
  const children = (
213
212
  <>
@@ -224,8 +223,10 @@ export const CodeBlockWithTabs = ({ className, codeBlockProps, currentTabKey, ta
224
223
  return (
225
224
  <Link
226
225
  {...commonProps}
227
- key={tab.key}
228
226
  to={tab.to}
227
+ rel={tab.rel}
228
+ target={tab.target}
229
+ key={tab.key}
229
230
  >
230
231
  {children}
231
232
  </Link>
@@ -1,48 +1,87 @@
1
1
  import clsx from 'clsx';
2
+ import type { ReactNode } from 'react';
2
3
  import React from 'react';
3
- import styled from 'styled-components';
4
+ import styled, { css } from 'styled-components';
4
5
 
5
- import { CheckCircleIcon, CrossIcon, InfoIcon, WarningTriangleIcon } from '@apify/ui-icons';
6
+ import type { IconComponent as IconComponentType } from '@apify/ui-icons';
7
+ import { CheckIcon, CrossIcon, InfoIcon, WarningTriangleIcon, XCircleIcon } from '@apify/ui-icons';
6
8
 
7
9
  import { theme } from '../design_system/theme.js';
8
10
  import { Box, type BoxProps } from './box.js';
11
+ import type { ButtonProps } from './button.js';
9
12
  import { Button } from './button.js';
10
- import { Heading } from './text/index.js';
13
+ import { Text } from './text/index.js';
11
14
 
12
15
  export const messageClassNames = {
13
16
  main: 'Message',
14
17
  icon: 'icon',
15
18
  content: 'content',
16
19
  caption: 'caption',
20
+ description: 'description',
17
21
  dismiss: 'dismiss',
22
+ actionsWrapper: 'actionsWrapper',
18
23
  };
19
24
 
20
- const StyledMessage = styled(Box)`
25
+ const StyledMessage = styled(Box)<{ $boxless?: boolean, $hasCaption?: boolean }>`
21
26
  display: flex;
27
+ align-items: center;
22
28
  gap: ${theme.space.space8};
23
29
 
24
30
  border-radius: ${theme.radius.radius8};
25
31
  box-shadow: ${theme.shadow.shadow1};
26
32
 
27
- .${messageClassNames.content} {
28
- flex: 1;
29
- margin-top: 1px; /* This is to align icon with text (align-items: center not possible - icon should be on top) */
33
+ .${messageClassNames.icon} {
34
+ grid-area: iconArea;
35
+ color: ${theme.color.neutral.icon};
36
+ /* Icon has 16px but text 20. With this extra margin we make the elements aligned */
37
+ margin: ${theme.space.space2} 0;
30
38
  }
31
39
 
32
40
  .${messageClassNames.caption} {
33
- /* TODO: We should not override the default Heading that is rendered for caption but it doesn't look good without these */
34
- line-height: 20px;
35
- font-weight: 600;
36
- margin-bottom: ${theme.space.space4};
41
+ grid-area: captionArea;
37
42
  }
38
43
 
39
- .${messageClassNames.dismiss} {
40
- background: transparent;
41
- height: 20px;
44
+ .${messageClassNames.description} {
45
+ grid-area: descriptionArea;
46
+ }
42
47
 
43
- svg {
44
- color: ${theme.color.neutral.icon}
48
+ .${messageClassNames.content} {
49
+ flex: 1;
50
+ display: grid;
51
+ gap: ${theme.space.space6} ${theme.space.space8};
52
+ grid-template-columns: auto 1fr;
53
+
54
+ a {
55
+ color: ${theme.color.neutral.text};
56
+ text-decoration: underline;
57
+ ${theme.typography.shared.desktop.bodyMMedium};
45
58
  }
59
+
60
+ ${({ $hasCaption }) => ($hasCaption
61
+ ? css`
62
+ grid-template-areas:
63
+ 'iconArea captionArea'
64
+ 'descriptionArea descriptionArea';
65
+ ` : css`
66
+ grid-template-areas:
67
+ 'iconArea descriptionArea';
68
+ `)}
69
+ }
70
+
71
+
72
+ ${({ $boxless }) => (!$boxless && css`
73
+ /* the dismiss button is bigger than text so we apply smaller padding on wrapper & some on the content and icon */
74
+ padding: ${theme.space.space8} ${theme.space.space16};
75
+
76
+ .${messageClassNames.content} {
77
+ padding: ${theme.space.space4} 0;
78
+ }
79
+ `)}
80
+
81
+ .${messageClassNames.actionsWrapper} {
82
+ display: flex;
83
+ align-items: center;
84
+ gap: ${theme.space.space8};
46
85
  }
47
86
 
48
87
  &.borderless {
@@ -55,28 +94,36 @@ const StyledMessage = styled(Box)`
55
94
  background-color: ${theme.color.neutral.background};
56
95
  border: 1px solid ${theme.color.neutral.border};
57
96
 
58
- .${messageClassNames.icon} { color: ${theme.color.primary.icon}; }
97
+ .${messageClassNames.icon} {
98
+ color: ${theme.color.neutral.icon};
99
+ }
59
100
  }
60
101
 
61
102
  &.success {
62
103
  background-color: ${theme.color.success.backgroundSubtle};
63
104
  border: 1px solid ${theme.color.success.borderSubtle};
64
105
 
65
- .${messageClassNames.icon} { color: ${theme.color.success.icon}; }
106
+ .${messageClassNames.icon} {
107
+ color: ${theme.color.success.icon};
108
+ }
66
109
  }
67
110
 
68
111
  &.warning {
69
112
  background-color: ${theme.color.warning.backgroundSubtle};
70
113
  border: 1px solid ${theme.color.warning.borderSubtle};
71
114
 
72
- .${messageClassNames.icon} { color: ${theme.color.warning.icon}; }
115
+ .${messageClassNames.icon} {
116
+ color: ${theme.color.warning.icon};
117
+ }
73
118
  }
74
119
 
75
120
  &.danger {
76
121
  background-color: ${theme.color.danger.backgroundSubtle};
77
122
  border: 1px solid ${theme.color.danger.borderSubtle};
78
123
 
79
- .${messageClassNames.icon} { color: ${theme.color.danger.icon}; }
124
+ .${messageClassNames.icon} {
125
+ color: ${theme.color.danger.icon};
126
+ }
80
127
  }
81
128
  `;
82
129
 
@@ -84,20 +131,27 @@ export type MessageType = 'info' | 'warning' | 'success' | 'danger';
84
131
 
85
132
  const typeToIcon: { [key in MessageType]: React.ElementType } = {
86
133
  info: InfoIcon,
87
- success: CheckCircleIcon,
134
+ success: CheckIcon,
88
135
  warning: WarningTriangleIcon,
89
- danger: WarningTriangleIcon,
136
+ danger: XCircleIcon,
137
+ };
138
+
139
+ type ActionButtonProps = Omit<ButtonProps, 'children'> & {
140
+ label: ReactNode,
90
141
  };
91
142
 
92
143
  type MessageProps = BoxProps & {
93
144
  type: MessageType,
94
145
  caption?: string,
95
- icon?: React.ElementType,
146
+ /** @deprecated Use `Icon` instead. */
147
+ icon?: IconComponentType,
148
+ Icon?: IconComponentType,
96
149
  onDismissClick?: () => void,
97
150
  borderless?: boolean,
98
151
  boxless?: boolean,
99
152
  as?: React.ElementType,
100
153
  dismissTrackingId?: string,
154
+ actions?: ActionButtonProps[],
101
155
  }
102
156
 
103
157
  /**
@@ -105,6 +159,7 @@ type MessageProps = BoxProps & {
105
159
  */
106
160
  export const Message: React.FC<MessageProps> = ({
107
161
  className,
162
+ Icon,
108
163
  icon,
109
164
  caption,
110
165
  children,
@@ -113,33 +168,56 @@ export const Message: React.FC<MessageProps> = ({
113
168
  borderless = false,
114
169
  boxless = false,
115
170
  dismissTrackingId,
171
+ actions = [],
116
172
  as,
117
173
  ...rest
118
174
  }) => {
119
- const Icon = icon || typeToIcon[type];
175
+ const IconComponent = icon || Icon || typeToIcon[type];
176
+ const hasCaption = !!caption && !!children;
177
+
120
178
  return (
121
179
  <StyledMessage
122
180
  className={clsx(className, messageClassNames.main, type, borderless && 'borderless')}
123
181
  mb={boxless ? 'space8' : 'space16'} // TODO: Export message without margin
124
- p={boxless ? 'none' : 'space16'}
125
182
  forwardedAs={as}
183
+ $boxless={boxless}
184
+ $hasCaption={hasCaption}
126
185
  {...rest}
127
186
  >
128
- <Icon className={messageClassNames.icon} size="20" />
129
187
  <div className={messageClassNames.content}>
130
- {caption && (<Heading as='div' type='titleM' className={messageClassNames.caption}>{caption}</Heading>)}
131
- {children}
188
+ <IconComponent className={messageClassNames.icon} size='16' />
189
+ {hasCaption && <Text weight='bold' className={messageClassNames.caption}>{caption}</Text>}
190
+ <div className={messageClassNames.description}>{children}</div>
132
191
  </div>
133
- {onDismissClick && (
134
- <Button
135
- size='small'
136
- variant='tertiary'
137
- trackingId={dismissTrackingId}
138
- onClick={onDismissClick}
139
- className={messageClassNames.dismiss}
140
- >
141
- <CrossIcon size="16" />
142
- </Button>
192
+ {(actions.length > 0 || onDismissClick) && (
193
+ <div className={messageClassNames.actionsWrapper}>
194
+ {actions.length > 0 && (
195
+ <>
196
+ {actions.map(({ label, ...action }, index) => (
197
+ <Button
198
+ key={index}
199
+ size='small'
200
+ variant='primary'
201
+ {...action}
202
+ >
203
+ {label}
204
+ </Button>
205
+ ))}
206
+ </>
207
+ )}
208
+ {onDismissClick && (
209
+ <Button
210
+ size='small'
211
+ variant='tertiary'
212
+ trackingId={dismissTrackingId}
213
+ onClick={onDismissClick}
214
+ className={messageClassNames.dismiss}
215
+ >
216
+ <CrossIcon size="16" color={theme.color.neutral.icon}/>
217
+ </Button>
218
+ )}
219
+
220
+ </div>
143
221
  )}
144
222
  </StyledMessage>
145
223
  );
@@ -4,7 +4,7 @@ import React, {
4
4
  useMemo,
5
5
  } from 'react';
6
6
  import ReactMarkdown from 'react-markdown';
7
- import type { AllowElement } from 'react-markdown/lib/rehype-filter';
7
+ import type { AllowElement } from 'react-markdown/lib/rehype-filter.js';
8
8
  import remarkToc from 'remark-toc';
9
9
  import styled from 'styled-components';
10
10
 
@@ -1,5 +1,5 @@
1
1
  import React, { useCallback } from 'react';
2
- import type { AllowElement } from 'react-markdown/lib/rehype-filter';
2
+ import type { AllowElement } from 'react-markdown/lib/rehype-filter.js';
3
3
  import slugify from 'slugify';
4
4
 
5
5
  export const slugifyHeadingChildren = (
@@ -2,7 +2,7 @@ import type { Element, Root, Text as TextNode } from 'hast';
2
2
  import React, { useCallback, useMemo, useRef } from 'react';
3
3
  import type { Components } from 'react-markdown';
4
4
  import ReactMarkdown, { uriTransformer } from 'react-markdown';
5
- import type { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown';
5
+ import type { ReactMarkdownOptions } from 'react-markdown/lib/react-markdown.js';
6
6
  import rehypeRaw from 'rehype-raw';
7
7
  import rehypeSanitize from 'rehype-sanitize';
8
8
  import remarkGfm from 'remark-gfm';
@@ -1,6 +1,6 @@
1
1
  import qs from 'query-string';
2
2
  import React from 'react';
3
- import type { CodeProps, ReactMarkdownProps } from 'react-markdown/lib/ast-to-react';
3
+ import type { CodeProps, ReactMarkdownProps } from 'react-markdown/lib/ast-to-react.js';
4
4
  import styled from 'styled-components';
5
5
 
6
6
  import { CheckIcon, LinkIcon } from '@apify/ui-icons';
@@ -196,6 +196,6 @@ TagWrapper.displayName = 'Tag';
196
196
 
197
197
  // `forwardRef` can't handle generic types, should be fixable with React 19
198
198
  export const Tag = forwardRef(TagWrapper) as <T extends TagNodeType>(
199
- // eslint-disable-next-line no-use-before-define -- see comment above 👆
199
+
200
200
  props: TagProps<T> & { ref?: ForwardedRef<TagNodePropsMap[T]['element']> },
201
201
  ) => ReturnType<typeof TagWrapper>;
@@ -4,7 +4,7 @@ import qs from 'query-string';
4
4
  import React, { useMemo } from 'react';
5
5
  import type { Components } from 'react-markdown';
6
6
  import ReactMarkdown, { uriTransformer } from 'react-markdown';
7
- import type { AllowElement, Node } from 'react-markdown/lib/rehype-filter';
7
+ import type { AllowElement, Node } from 'react-markdown/lib/rehype-filter.js';
8
8
  import rehypeRaw from 'rehype-raw';
9
9
  import remarkGfm from 'remark-gfm';
10
10
  import styled from 'styled-components';
@@ -266,11 +266,11 @@ const StyledMarkdown = styled(ReactMarkdown) <StyledReadmeProps>`
266
266
  @media (min-width: ${theme.layout.tablet}) {
267
267
  ${theme.typography.content.tablet.snippet}
268
268
  }
269
-
269
+
270
270
  @media (min-width: ${theme.layout.desktop}) {
271
271
  ${theme.typography.content.desktop.snippet}
272
272
  }
273
-
273
+
274
274
  b, strong{
275
275
  font-size: inherit !important;
276
276
  line-height: inherit !important;
@@ -31,6 +31,7 @@ export const useImageColor = () => {
31
31
  try {
32
32
  setColor(patchDarknessInfo(await fac.getColorAsync(element)));
33
33
  } catch (error) {
34
+ // eslint-disable-next-line no-console
34
35
  console.error('Failed to determine the image color.', { error });
35
36
  }
36
37
  };