@apify/ui-library 0.51.6-featurepublishuilibrary-0a4729.38266 → 0.56.1-featurepublishuilibrary-0a4729.38395
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +82 -0
- package/dist/src/components/action_link.jsx +3 -3
- package/dist/src/components/action_link.jsx.map +1 -1
- package/dist/src/components/blog_article.jsx +2 -2
- package/dist/src/components/blog_article.jsx.map +1 -1
- package/dist/src/components/button.d.ts.map +1 -1
- package/dist/src/components/button.jsx +7 -6
- package/dist/src/components/button.jsx.map +1 -1
- package/dist/src/components/code/action_button.jsx +2 -3
- package/dist/src/components/code/action_button.jsx.map +1 -1
- package/dist/src/components/code/one_line_code/one_line_code.jsx +2 -2
- package/dist/src/components/code/one_line_code/one_line_code.jsx.map +1 -1
- package/dist/src/components/floating/menu.d.ts.map +1 -1
- package/dist/src/components/floating/menu.jsx +23 -27
- package/dist/src/components/floating/menu.jsx.map +1 -1
- package/dist/src/components/floating/menu_components.jsx +2 -2
- package/dist/src/components/floating/menu_components.jsx.map +1 -1
- package/dist/src/components/index.d.ts +1 -0
- package/dist/src/components/index.d.ts.map +1 -1
- package/dist/src/components/index.js +1 -0
- package/dist/src/components/index.js.map +1 -1
- package/dist/src/components/link.jsx +2 -2
- package/dist/src/components/link.jsx.map +1 -1
- package/dist/src/components/message.d.ts.map +1 -1
- package/dist/src/components/message.jsx +6 -6
- package/dist/src/components/message.jsx.map +1 -1
- package/dist/src/components/rating.d.ts +14 -0
- package/dist/src/components/rating.d.ts.map +1 -0
- package/dist/src/components/rating.jsx +70 -0
- package/dist/src/components/rating.jsx.map +1 -0
- package/dist/src/components/simple_markdown/simple_markdown_components.jsx +2 -2
- package/dist/src/components/simple_markdown/simple_markdown_components.jsx.map +1 -1
- package/dist/src/components/to_consolidate/markdown.jsx +2 -2
- package/dist/src/components/to_consolidate/markdown.jsx.map +1 -1
- package/dist/src/components/to_consolidate/pagination.d.ts.map +1 -1
- package/dist/src/components/to_consolidate/pagination.jsx +3 -3
- package/dist/src/components/to_consolidate/pagination.jsx.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -7
- package/src/components/action_link.tsx +3 -3
- package/src/components/blog_article.tsx +2 -2
- package/src/components/button.tsx +8 -6
- package/src/components/code/action_button.tsx +3 -3
- package/src/components/code/one_line_code/one_line_code.tsx +3 -3
- package/src/components/floating/menu.tsx +45 -47
- package/src/components/floating/menu_components.tsx +2 -2
- package/src/components/index.ts +1 -0
- package/src/components/link.tsx +2 -2
- package/src/components/message.tsx +6 -11
- package/src/components/rating.tsx +106 -0
- package/src/components/simple_markdown/simple_markdown_components.tsx +5 -5
- package/src/components/to_consolidate/markdown.tsx +2 -2
- package/src/components/to_consolidate/pagination.tsx +3 -6
- package/tsconfig.build.json +0 -1
package/package.json
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apify/ui-library",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "React
|
|
5
|
-
"license": "
|
|
6
|
-
"repository": "https://github.com/apify-packages/meta-package-repo",
|
|
3
|
+
"version": "0.56.1-featurepublishuilibrary-0a4729.38395+b93664f477",
|
|
4
|
+
"description": "React UI library used by apify.com",
|
|
5
|
+
"license": "Apache-2.0",
|
|
7
6
|
"type": "module",
|
|
8
7
|
"main": "dist/src/index.js",
|
|
9
8
|
"types": "dist/src/index.d.ts",
|
|
@@ -27,9 +26,8 @@
|
|
|
27
26
|
"It's not nice, but helps us to get around the problem of multiple react instances."
|
|
28
27
|
],
|
|
29
28
|
"dependencies": {
|
|
30
|
-
"@apify/icons": "^0.40.5-featurepublishuilibrary-0a4729.38266+7412d8cbd3",
|
|
31
29
|
"@apify/log": "^2.5.11",
|
|
32
|
-
"@apify/ui-icons": "^0.
|
|
30
|
+
"@apify/ui-icons": "^0.4.1-featurepublishuilibrary-0a4729.38395+b93664f477",
|
|
33
31
|
"@floating-ui/react": "^0.26.2",
|
|
34
32
|
"clsx": "^2.0.0",
|
|
35
33
|
"dayjs": "1.11.9",
|
|
@@ -67,5 +65,5 @@
|
|
|
67
65
|
"recast": "^0.23.9",
|
|
68
66
|
"typescript": "^5.1.6"
|
|
69
67
|
},
|
|
70
|
-
"gitHead": "
|
|
68
|
+
"gitHead": "b93664f47710286060a05453f35a21fc8026e429"
|
|
71
69
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { ArrowLeftIcon, ArrowRightIcon } from '@apify/ui-icons';
|
|
5
5
|
|
|
6
6
|
import { theme } from '../design_system/theme';
|
|
7
7
|
import { Box } from './box';
|
|
@@ -36,7 +36,7 @@ export const ActionLink: React.FC<LinkProps> = ({
|
|
|
36
36
|
{...rest}
|
|
37
37
|
>
|
|
38
38
|
<Heading as='span' type='titleM'>{children}</Heading>
|
|
39
|
-
<
|
|
39
|
+
<ArrowRightIcon size="16" />
|
|
40
40
|
</StyledGuidepost>
|
|
41
41
|
);
|
|
42
42
|
};
|
|
@@ -52,7 +52,7 @@ export const BackLink: React.FC<LinkProps> = ({
|
|
|
52
52
|
$isBackLink={true}
|
|
53
53
|
{...rest}
|
|
54
54
|
>
|
|
55
|
-
<
|
|
55
|
+
<ArrowLeftIcon size="16" />
|
|
56
56
|
<Heading as='span' type='titleM'>{children}</Heading>
|
|
57
57
|
</StyledGuidepost>
|
|
58
58
|
);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { ArrowRightIcon } from '@apify/ui-icons';
|
|
5
5
|
|
|
6
6
|
import { theme } from '../design_system/theme';
|
|
7
7
|
|
|
@@ -79,7 +79,7 @@ export function BlogArticle({ imageNode, title, ctaTitle = 'Read more' }: BlogAr
|
|
|
79
79
|
<BlogArticleWrapper>
|
|
80
80
|
<div className={classNames.IMAGE_WRAPPER}>{imageNode}</div>
|
|
81
81
|
<div className={classNames.TEXT}>{title}</div>
|
|
82
|
-
<div className={classNames.READ_POST}>{ctaTitle}<
|
|
82
|
+
<div className={classNames.READ_POST}>{ctaTitle}<ArrowRightIcon size="16" title="" titleId="" /></div>
|
|
83
83
|
</BlogArticleWrapper>
|
|
84
84
|
);
|
|
85
85
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { forwardRef } from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { ExternalLinkIcon } from '@apify/ui-icons';
|
|
5
5
|
|
|
6
6
|
import { theme } from '../design_system/theme';
|
|
7
7
|
import { type WithRequired, type WithTransientProps } from '../type_utils';
|
|
@@ -259,9 +259,11 @@ export const Button = forwardRef<HTMLElement, ButtonProps | AnchorButtonProps>((
|
|
|
259
259
|
if (onClick) onClick(e);
|
|
260
260
|
};
|
|
261
261
|
|
|
262
|
+
const iconSize = size === 'medium' ? '16' : '12';
|
|
263
|
+
|
|
262
264
|
if (isAnchorButton(props)) {
|
|
263
265
|
const isExternal = isUrlExternal(props.to, windowLocationHost);
|
|
264
|
-
const EffectiveRightIcon = (isExternal && !props.hideExternalIcon) ?
|
|
266
|
+
const EffectiveRightIcon = (isExternal && !props.hideExternalIcon) ? ExternalLinkIcon : RightIcon;
|
|
265
267
|
|
|
266
268
|
return (
|
|
267
269
|
<StyledButton
|
|
@@ -277,9 +279,9 @@ export const Button = forwardRef<HTMLElement, ButtonProps | AnchorButtonProps>((
|
|
|
277
279
|
// If we want to show external icon, we use button's slot for icon
|
|
278
280
|
hideExternalIcon={true}
|
|
279
281
|
>
|
|
280
|
-
{LeftIcon && <LeftIcon />}
|
|
282
|
+
{LeftIcon && <LeftIcon size={iconSize} />}
|
|
281
283
|
{children}
|
|
282
|
-
{EffectiveRightIcon && <EffectiveRightIcon />}
|
|
284
|
+
{EffectiveRightIcon && <EffectiveRightIcon size={iconSize} />}
|
|
283
285
|
</StyledButton>
|
|
284
286
|
);
|
|
285
287
|
}
|
|
@@ -295,9 +297,9 @@ export const Button = forwardRef<HTMLElement, ButtonProps | AnchorButtonProps>((
|
|
|
295
297
|
type='button'
|
|
296
298
|
{...rest}
|
|
297
299
|
>
|
|
298
|
-
{LeftIcon && <LeftIcon />}
|
|
300
|
+
{LeftIcon && <LeftIcon size={iconSize} />}
|
|
299
301
|
{children}
|
|
300
|
-
{RightIcon && <RightIcon />}
|
|
302
|
+
{RightIcon && <RightIcon size={iconSize} />}
|
|
301
303
|
</StyledButton>
|
|
302
304
|
);
|
|
303
305
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { CheckIcon, CopyIcon } from '@apify/ui-icons';
|
|
5
5
|
|
|
6
6
|
import { theme } from '../../design_system/theme';
|
|
7
7
|
import { useCopyToClipboard } from '../../utils';
|
|
@@ -10,7 +10,7 @@ import { Text } from '../text';
|
|
|
10
10
|
interface StyledButtonProps {
|
|
11
11
|
$successStyle?: boolean;
|
|
12
12
|
$hasText?: boolean;
|
|
13
|
-
}
|
|
13
|
+
}
|
|
14
14
|
|
|
15
15
|
const StyledButton = styled.button<StyledButtonProps>`
|
|
16
16
|
display: flex;
|
|
@@ -90,7 +90,7 @@ export const CopyButton = ({ code, ...props }: CopyButtonProps) => {
|
|
|
90
90
|
const [isCopied, handleClick] = useCopyToClipboard({ text: code });
|
|
91
91
|
return (
|
|
92
92
|
<ActionButton onClick={handleClick} data-test='copy_to_clipboard' {...props}>
|
|
93
|
-
{isCopied ? <
|
|
93
|
+
{isCopied ? <CheckIcon size="16" /> : <CopyIcon size="16" />}
|
|
94
94
|
</ActionButton>
|
|
95
95
|
);
|
|
96
96
|
};
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import React, { useMemo, useState } from 'react';
|
|
2
2
|
import styled, { css } from 'styled-components';
|
|
3
3
|
|
|
4
|
-
import {
|
|
4
|
+
import { EyeIcon, EyeOffIcon } from '@apify/ui-icons';
|
|
5
5
|
|
|
6
6
|
import { theme } from '../../../design_system/theme';
|
|
7
7
|
import type { BoxProps } from '../../box';
|
|
@@ -214,9 +214,9 @@ export function OneLineCode({
|
|
|
214
214
|
data-test='toggle-visibility-button'
|
|
215
215
|
>
|
|
216
216
|
{showSecret ? (
|
|
217
|
-
<
|
|
217
|
+
<EyeOffIcon size="16" />
|
|
218
218
|
) : (
|
|
219
|
-
<
|
|
219
|
+
<EyeIcon size="16" />
|
|
220
220
|
)}
|
|
221
221
|
</ActionButton>
|
|
222
222
|
)}
|
|
@@ -138,54 +138,52 @@ export const Menu = <T extends MenuOption>({
|
|
|
138
138
|
>
|
|
139
139
|
{selectedIndex !== null ? options[selectedIndex].label : defaultLabel}
|
|
140
140
|
</MenuBaseComponent>
|
|
141
|
-
|
|
142
|
-
<
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
<MenuComponent
|
|
147
|
-
ref={refs.setFloating}
|
|
148
|
-
style={{
|
|
149
|
-
...floatingStyles,
|
|
150
|
-
// TODO: We should consider not doing this by default
|
|
151
|
-
...!isOpen && { display: 'none' }, // needs to be rendered, because of SEO
|
|
152
|
-
}}
|
|
153
|
-
{...getFloatingProps()}
|
|
154
|
-
className={menuClassNames.LIST}
|
|
141
|
+
{isOpen && (
|
|
142
|
+
<FloatingPortal>
|
|
143
|
+
<FloatingFocusManager
|
|
144
|
+
context={context}
|
|
145
|
+
modal={false}
|
|
155
146
|
>
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
event.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
147
|
+
<MenuComponent
|
|
148
|
+
ref={refs.setFloating}
|
|
149
|
+
style={floatingStyles}
|
|
150
|
+
{...getFloatingProps()}
|
|
151
|
+
className={menuClassNames.LIST}
|
|
152
|
+
>
|
|
153
|
+
{options.map((option, i) => (
|
|
154
|
+
<MenuItemComponent
|
|
155
|
+
key={option.value}
|
|
156
|
+
$isSelected={i === selectedIndex}
|
|
157
|
+
$isActive={i === activeIndex}
|
|
158
|
+
ref={(node: HTMLElement | null) => {
|
|
159
|
+
listRef.current[i] = node;
|
|
160
|
+
}}
|
|
161
|
+
role="option"
|
|
162
|
+
tabIndex={i === activeIndex ? 0 : -1}
|
|
163
|
+
className={menuClassNames.ITEM}
|
|
164
|
+
aria-selected={i === selectedIndex && i === activeIndex}
|
|
165
|
+
{...getItemProps({
|
|
166
|
+
onClick: () => handleSelect(i, 'click'), // Handles mouse click
|
|
167
|
+
onKeyDown: (event) => {
|
|
168
|
+
if (event.key === 'Enter') {
|
|
169
|
+
event.preventDefault();
|
|
170
|
+
handleSelect(i, 'enter'); // Handles enter press
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
if (event.key === ' ' && !isTypingRef.current) {
|
|
174
|
+
event.preventDefault();
|
|
175
|
+
handleSelect(i, 'space');
|
|
176
|
+
}
|
|
177
|
+
},
|
|
178
|
+
})}
|
|
179
|
+
>
|
|
180
|
+
{effectiveRenderOption(option)}
|
|
181
|
+
</MenuItemComponent>
|
|
182
|
+
))}
|
|
183
|
+
</MenuComponent>
|
|
184
|
+
</FloatingFocusManager>
|
|
185
|
+
</FloatingPortal>
|
|
186
|
+
)}
|
|
189
187
|
</Box>
|
|
190
188
|
);
|
|
191
189
|
};
|
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
import React, { forwardRef } from 'react';
|
|
6
6
|
import styled, { css } from 'styled-components';
|
|
7
7
|
|
|
8
|
-
import {
|
|
8
|
+
import { ChevronDownIcon } from '@apify/ui-icons';
|
|
9
9
|
|
|
10
10
|
import { theme } from '../../design_system/theme';
|
|
11
11
|
import { Box } from '../box';
|
|
@@ -88,7 +88,7 @@ export const DropdownMenuBaseComponent = forwardRef<HTMLElement, any>(({
|
|
|
88
88
|
return (
|
|
89
89
|
<PlainMenuBaseComponent {...props} ref={ref}>
|
|
90
90
|
{children}
|
|
91
|
-
<
|
|
91
|
+
<ChevronDownIcon size="16" color={theme.color.neutral.icon} />
|
|
92
92
|
</PlainMenuBaseComponent>
|
|
93
93
|
);
|
|
94
94
|
});
|
package/src/components/index.ts
CHANGED
package/src/components/link.tsx
CHANGED
|
@@ -3,7 +3,7 @@ import { createPath, type Path } from 'history';
|
|
|
3
3
|
import React, { forwardRef } from 'react';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { ExternalLinkIcon } from '@apify/ui-icons';
|
|
7
7
|
|
|
8
8
|
import { theme } from '../design_system/theme';
|
|
9
9
|
import { useSharedUiDependencies } from '../ui_dependency_provider';
|
|
@@ -108,7 +108,7 @@ export const Link = forwardRef<HTMLElement, LinkProps>(({
|
|
|
108
108
|
{...rest}
|
|
109
109
|
>
|
|
110
110
|
{children}
|
|
111
|
-
{((isExternal && !hideExternalIcon) || showExternalIcon) && <
|
|
111
|
+
{((isExternal && !hideExternalIcon) || showExternalIcon) && <ExternalLinkIcon size="16" />}
|
|
112
112
|
</StyledLink>
|
|
113
113
|
);
|
|
114
114
|
});
|
|
@@ -2,12 +2,7 @@ import clsx from 'clsx';
|
|
|
2
2
|
import React from 'react';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
AlertTriangle20,
|
|
7
|
-
CheckCircle20,
|
|
8
|
-
Info20,
|
|
9
|
-
X16,
|
|
10
|
-
} from '@apify/icons';
|
|
5
|
+
import { CheckCircleIcon, CrossIcon, InfoIcon, WarningTriangleIcon } from '@apify/ui-icons';
|
|
11
6
|
|
|
12
7
|
import { theme } from '../design_system/theme';
|
|
13
8
|
import { Box, type BoxProps } from './box';
|
|
@@ -87,10 +82,10 @@ const StyledMessage = styled(Box)`
|
|
|
87
82
|
export type MessageType = 'info' | 'warning' | 'success' | 'danger';
|
|
88
83
|
|
|
89
84
|
const typeToIcon: { [key in MessageType]: React.ElementType } = {
|
|
90
|
-
info:
|
|
91
|
-
success:
|
|
92
|
-
warning:
|
|
93
|
-
danger:
|
|
85
|
+
info: InfoIcon,
|
|
86
|
+
success: CheckCircleIcon,
|
|
87
|
+
warning: WarningTriangleIcon,
|
|
88
|
+
danger: WarningTriangleIcon,
|
|
94
89
|
};
|
|
95
90
|
|
|
96
91
|
type MessageProps = BoxProps & {
|
|
@@ -142,7 +137,7 @@ export const Message: React.FC<MessageProps> = ({
|
|
|
142
137
|
onClick={onDismissClick}
|
|
143
138
|
className={messageClassNames.dismiss}
|
|
144
139
|
>
|
|
145
|
-
<
|
|
140
|
+
<CrossIcon size="16" />
|
|
146
141
|
</Button>
|
|
147
142
|
)}
|
|
148
143
|
</StyledMessage>
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { FC } from 'react';
|
|
2
|
+
import React, { Fragment, useMemo } from 'react';
|
|
3
|
+
import styled from 'styled-components';
|
|
4
|
+
|
|
5
|
+
import { StarEmptyIcon, StarFullIcon, StarHalfIcon } from '@apify/ui-icons';
|
|
6
|
+
|
|
7
|
+
import type { ReviewRating } from '@apify-packages/types';
|
|
8
|
+
|
|
9
|
+
import { theme } from '../design_system/theme';
|
|
10
|
+
import type { BoxProps } from './box';
|
|
11
|
+
import { Box } from './box';
|
|
12
|
+
import { Text } from './text';
|
|
13
|
+
|
|
14
|
+
type RatingStatsProps = {
|
|
15
|
+
ratingStats: Record<ReviewRating, number>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const StyledRating = styled(Box)`
|
|
19
|
+
display: flex;
|
|
20
|
+
`;
|
|
21
|
+
|
|
22
|
+
const StyledRatingStats = styled(Box)`
|
|
23
|
+
display: grid;
|
|
24
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
25
|
+
align-items: center;
|
|
26
|
+
gap: 1px ${theme.space.space8};
|
|
27
|
+
align-items: center;
|
|
28
|
+
|
|
29
|
+
p {
|
|
30
|
+
/* TODO: This font is not defined! */
|
|
31
|
+
line-height: 10px;
|
|
32
|
+
font-size: 8px;
|
|
33
|
+
}
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const StyledRatingBar = styled(Box)<{ $widthPercent: number }>`
|
|
37
|
+
height: 5px;
|
|
38
|
+
border-radius: 10px;
|
|
39
|
+
background: ${theme.color.neutral.overflow};
|
|
40
|
+
position: relative;
|
|
41
|
+
overflow: hidden;
|
|
42
|
+
|
|
43
|
+
&::after {
|
|
44
|
+
content: "";
|
|
45
|
+
position: absolute;
|
|
46
|
+
display: block;
|
|
47
|
+
height: 100%;
|
|
48
|
+
left: 0;
|
|
49
|
+
top: 0;
|
|
50
|
+
border-radius: 10px;
|
|
51
|
+
background: ${theme.color.neutral.icon};
|
|
52
|
+
width: ${({ $widthPercent }) => $widthPercent}%;
|
|
53
|
+
|
|
54
|
+
}
|
|
55
|
+
`;
|
|
56
|
+
|
|
57
|
+
// 0 is only for empty rating - we don't display any stars filled
|
|
58
|
+
type RatingProps = BoxProps & {
|
|
59
|
+
rating: number | undefined;
|
|
60
|
+
color?: string;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
export const Rating: FC<RatingProps> = ({
|
|
64
|
+
rating = 0,
|
|
65
|
+
color = theme.color.neutral.icon,
|
|
66
|
+
...rest
|
|
67
|
+
}) => {
|
|
68
|
+
const ratingStatsContent = useMemo(() => [1, 2, 3, 4, 5].map((rate) => {
|
|
69
|
+
const ratingFloor = Math.floor(rating);
|
|
70
|
+
const ratingDecimals = rating % 1;
|
|
71
|
+
|
|
72
|
+
if (ratingFloor >= rate || (ratingFloor === rate - 1 && ratingDecimals > 0.75)) return <StarFullIcon size="12" color={color} key={rate} />;
|
|
73
|
+
if (ratingFloor === rate - 1 && ratingDecimals > 0.25) return <StarHalfIcon size="12" color={color} key={rate} />;
|
|
74
|
+
return <StarEmptyIcon size="12" color={color} key={rate} />;
|
|
75
|
+
}), [rating, color]);
|
|
76
|
+
|
|
77
|
+
return (
|
|
78
|
+
<StyledRating {...rest}>
|
|
79
|
+
{ratingStatsContent}
|
|
80
|
+
</StyledRating>
|
|
81
|
+
);
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
export const RatingStats: FC<RatingStatsProps & BoxProps> = ({
|
|
85
|
+
ratingStats,
|
|
86
|
+
...rest
|
|
87
|
+
}) => {
|
|
88
|
+
const totalRates = ratingStats[1] + ratingStats[2] + ratingStats[3] + ratingStats[4] + ratingStats[5];
|
|
89
|
+
|
|
90
|
+
const ratingStatsContent = useMemo(() => ([5, 4, 3, 2, 1] as const).map((rate) => {
|
|
91
|
+
const widthPercent = totalRates > 0 ? ((ratingStats[rate] / totalRates) * 100) : 0;
|
|
92
|
+
|
|
93
|
+
return (
|
|
94
|
+
<Fragment key={rate}>
|
|
95
|
+
<Text color={theme.color.neutral.textSubtle}>{rate}</Text>
|
|
96
|
+
<StyledRatingBar $widthPercent={widthPercent}/>
|
|
97
|
+
</Fragment>
|
|
98
|
+
);
|
|
99
|
+
}), [totalRates, ratingStats]);
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<StyledRatingStats {...rest}>
|
|
103
|
+
{ratingStatsContent}
|
|
104
|
+
</StyledRatingStats>
|
|
105
|
+
);
|
|
106
|
+
};
|
|
@@ -3,7 +3,7 @@ import React from 'react';
|
|
|
3
3
|
import type { CodeProps, ReactMarkdownProps } from 'react-markdown/lib/ast-to-react';
|
|
4
4
|
import styled from 'styled-components';
|
|
5
5
|
|
|
6
|
-
import {
|
|
6
|
+
import { CheckIcon, LinkIcon } from '@apify/ui-icons';
|
|
7
7
|
|
|
8
8
|
import { theme } from '../../design_system/theme';
|
|
9
9
|
import type { WithOptional } from '../../type_utils';
|
|
@@ -95,14 +95,14 @@ export const MarkdownHeadingWrapper: React.FC<HeadingSharedProps> = ({
|
|
|
95
95
|
to={`#${id}`}
|
|
96
96
|
>
|
|
97
97
|
{isCopied ? (
|
|
98
|
-
<
|
|
98
|
+
<CheckIcon
|
|
99
|
+
size="16"
|
|
99
100
|
color={theme.color.success.action}
|
|
100
|
-
viewBox="0 0 16 16"
|
|
101
101
|
/>
|
|
102
102
|
) : (
|
|
103
|
-
<
|
|
103
|
+
<LinkIcon
|
|
104
|
+
size="16"
|
|
104
105
|
color={theme.color.primary.text}
|
|
105
|
-
viewBox="0 0 16 16"
|
|
106
106
|
/>
|
|
107
107
|
)}
|
|
108
108
|
</Link>
|
|
@@ -9,7 +9,7 @@ import rehypeRaw from 'rehype-raw';
|
|
|
9
9
|
import remarkGfm from 'remark-gfm';
|
|
10
10
|
import styled from 'styled-components';
|
|
11
11
|
|
|
12
|
-
import {
|
|
12
|
+
import { LinkIcon } from '@apify/ui-icons';
|
|
13
13
|
|
|
14
14
|
import type { UiThemeOption } from '../../design_system/theme';
|
|
15
15
|
import { theme } from '../../design_system/theme';
|
|
@@ -487,7 +487,7 @@ const HeadingRendererWithAnchor = ({ node, children }: HeadingRendererProps) =>
|
|
|
487
487
|
href={`#${id}`}
|
|
488
488
|
className={`${markdownClassNames.HEADING_COPY_ICON}`}
|
|
489
489
|
>
|
|
490
|
-
<
|
|
490
|
+
<LinkIcon size="16" />
|
|
491
491
|
</a>
|
|
492
492
|
</Tag>
|
|
493
493
|
);
|
|
@@ -2,10 +2,7 @@ import type { FC } from 'react';
|
|
|
2
2
|
import React, { useMemo } from 'react';
|
|
3
3
|
import styled from 'styled-components';
|
|
4
4
|
|
|
5
|
-
import {
|
|
6
|
-
ChevronRight20,
|
|
7
|
-
ChevronLeft20,
|
|
8
|
-
} from '@apify/icons';
|
|
5
|
+
import { ChevronLeftIcon, ChevronRightIcon } from '@apify/ui-icons';
|
|
9
6
|
|
|
10
7
|
import { theme } from '../../design_system/theme';
|
|
11
8
|
import { Box } from '../box';
|
|
@@ -87,7 +84,7 @@ export const PaginationButtons: FC<PaginationButtonsProps> = ({
|
|
|
87
84
|
onClick={() => onPageChange(page - 1)}
|
|
88
85
|
trackingId='PaginationPrevPage'
|
|
89
86
|
>
|
|
90
|
-
<
|
|
87
|
+
<ChevronLeftIcon size="16" />
|
|
91
88
|
</PaginationButtonBase>
|
|
92
89
|
{pagesToDisplay.map((pageToDisplay) => {
|
|
93
90
|
if (pageToDisplay === LEADING_THREE_DOTS_PAGE_KEY || pageToDisplay === TRAILING_THREE_DOTS_PAGE_KEY) {
|
|
@@ -132,7 +129,7 @@ export const PaginationButtons: FC<PaginationButtonsProps> = ({
|
|
|
132
129
|
onClick={() => onPageChange(page + 1)}
|
|
133
130
|
trackingId='PaginationNextPage'
|
|
134
131
|
>
|
|
135
|
-
<
|
|
132
|
+
<ChevronRightIcon size="16" />
|
|
136
133
|
</PaginationButtonBase>
|
|
137
134
|
</StyledPageSelectionButtons>
|
|
138
135
|
);
|