@apify/ui-library 1.135.0 → 1.137.0
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/dist/src/components/breadcrumb/breadcrumb.d.ts +17 -0
- package/dist/src/components/breadcrumb/breadcrumb.d.ts.map +1 -0
- package/dist/src/components/breadcrumb/breadcrumb.js +41 -0
- package/dist/src/components/breadcrumb/breadcrumb.js.map +1 -0
- package/dist/src/components/breadcrumb/index.d.ts +2 -0
- package/dist/src/components/breadcrumb/index.d.ts.map +1 -0
- package/dist/src/components/breadcrumb/index.js +2 -0
- package/dist/src/components/breadcrumb/index.js.map +1 -0
- package/dist/src/components/card_container.d.ts +11 -1
- package/dist/src/components/card_container.d.ts.map +1 -1
- package/dist/src/components/card_container.js +13 -5
- package/dist/src/components/card_container.js.map +1 -1
- package/dist/src/components/code/code_block/utils.js +1 -1
- package/dist/src/components/code/code_block/utils.js.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/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +5 -5
- package/src/codemods/generate_typograpy_tokens_files.mjs +1 -1
- package/src/components/badge.stories.jsx +1 -1
- package/src/components/breadcrumb/breadcrumb.stories.tsx +52 -0
- package/src/components/breadcrumb/breadcrumb.tsx +88 -0
- package/src/components/breadcrumb/index.ts +1 -0
- package/src/components/card_container.stories.tsx +17 -3
- package/src/components/card_container.tsx +25 -6
- package/src/components/code/code_block/utils.tsx +2 -2
- package/src/components/index.ts +1 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apify/ui-library",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.137.0",
|
|
4
4
|
"description": "React UI library used by apify.com",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -12,8 +12,8 @@
|
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"test": "echo \"Warning: no test specified\" && exit 0",
|
|
15
|
-
"lint": "
|
|
16
|
-
"lint:fix": "
|
|
15
|
+
"lint": "oxlint --type-aware .",
|
|
16
|
+
"lint:fix": "oxlint --type-aware --fix .",
|
|
17
17
|
"build": "npm run clean && npm run compile",
|
|
18
18
|
"clean": "rimraf ./dist",
|
|
19
19
|
"compile": "tsc -p tsconfig.build.json",
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"It's not nice, but helps us to get around the problem of multiple react instances."
|
|
28
28
|
],
|
|
29
29
|
"dependencies": {
|
|
30
|
-
"@apify/ui-icons": "^1.
|
|
30
|
+
"@apify/ui-icons": "^1.37.0",
|
|
31
31
|
"@floating-ui/react": "^0.27.19",
|
|
32
32
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
33
33
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
@@ -70,5 +70,5 @@
|
|
|
70
70
|
"src",
|
|
71
71
|
"style"
|
|
72
72
|
],
|
|
73
|
-
"gitHead": "
|
|
73
|
+
"gitHead": "31ba6cc576b0e0ce8b7390126ec35cc8127eee80"
|
|
74
74
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { userEvent, within } from 'storybook/test';
|
|
3
|
+
|
|
4
|
+
import { Breadcrumbs } from './breadcrumb.js';
|
|
5
|
+
|
|
6
|
+
type Story = StoryObj<typeof Breadcrumbs>;
|
|
7
|
+
|
|
8
|
+
export default {
|
|
9
|
+
title: 'UI-Library/Breadcrumbs',
|
|
10
|
+
component: Breadcrumbs,
|
|
11
|
+
parameters: {
|
|
12
|
+
layout: 'centered',
|
|
13
|
+
},
|
|
14
|
+
} as const;
|
|
15
|
+
|
|
16
|
+
export const Default: Story = {
|
|
17
|
+
args: {
|
|
18
|
+
items: [
|
|
19
|
+
{ label: 'All Actors', url: '/actors' },
|
|
20
|
+
{ label: 'Generate leads' },
|
|
21
|
+
],
|
|
22
|
+
},
|
|
23
|
+
};
|
|
24
|
+
|
|
25
|
+
export const DeepPath: Story = {
|
|
26
|
+
args: {
|
|
27
|
+
items: [
|
|
28
|
+
{ label: 'All Actors', url: '/actors' },
|
|
29
|
+
{ label: 'Business', url: '/actors/business' },
|
|
30
|
+
{ label: 'Generate leads' },
|
|
31
|
+
],
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export const SingleItem: Story = {
|
|
36
|
+
args: {
|
|
37
|
+
items: [{ label: 'All Actors' }],
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
export const Hovered: Story = {
|
|
42
|
+
args: {
|
|
43
|
+
items: [
|
|
44
|
+
{ label: 'All Actors', url: '/actors' },
|
|
45
|
+
{ label: 'Generate leads' },
|
|
46
|
+
],
|
|
47
|
+
},
|
|
48
|
+
play: async ({ canvasElement }) => {
|
|
49
|
+
const canvas = within(canvasElement);
|
|
50
|
+
await userEvent.hover(canvas.getByText('All Actors'));
|
|
51
|
+
},
|
|
52
|
+
};
|
|
@@ -0,0 +1,88 @@
|
|
|
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 { Box } from '../box.js';
|
|
7
|
+
import { Link } from '../link.js';
|
|
8
|
+
import { Text } from '../text/index.js';
|
|
9
|
+
|
|
10
|
+
export const breadcrumbClassNames = {
|
|
11
|
+
WRAPPER: 'Breadcrumbs__Wrapper',
|
|
12
|
+
SEPARATOR: 'Breadcrumbs__Separator',
|
|
13
|
+
ITEM: 'Breadcrumbs__Item',
|
|
14
|
+
ITEM_ACTIVE: 'Breadcrumbs__Item--active',
|
|
15
|
+
} as const;
|
|
16
|
+
|
|
17
|
+
const StyledBreadcrumbs = styled(Box)`
|
|
18
|
+
display: flex;
|
|
19
|
+
align-items: center;
|
|
20
|
+
gap: ${theme.space.space8};
|
|
21
|
+
`;
|
|
22
|
+
|
|
23
|
+
const StyledBreadcrumbLink = styled(Link)`
|
|
24
|
+
text-decoration: none;
|
|
25
|
+
padding: ${theme.space.space2} ${theme.space.space4};
|
|
26
|
+
border-radius: ${theme.radius.radius6};
|
|
27
|
+
color: ${theme.color.neutral.textSubtle};
|
|
28
|
+
|
|
29
|
+
&:hover {
|
|
30
|
+
color: ${theme.color.neutral.textMuted};
|
|
31
|
+
span {
|
|
32
|
+
font-weight: 500;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
`;
|
|
36
|
+
|
|
37
|
+
const StyledBreadcrumbItemText = styled(Text)`
|
|
38
|
+
padding: ${theme.space.space2} ${theme.space.space4};
|
|
39
|
+
white-space: nowrap;
|
|
40
|
+
`;
|
|
41
|
+
|
|
42
|
+
export type BreadcrumbItem = {
|
|
43
|
+
label: string;
|
|
44
|
+
url?: string;
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
export type BreadcrumbsProps = {
|
|
48
|
+
items: BreadcrumbItem[];
|
|
49
|
+
className?: string;
|
|
50
|
+
};
|
|
51
|
+
|
|
52
|
+
export const Breadcrumbs: React.FC<BreadcrumbsProps> = ({ items, className }) => (
|
|
53
|
+
<StyledBreadcrumbs className={clsx(breadcrumbClassNames.WRAPPER, className)}>
|
|
54
|
+
{items.map((item, index) => {
|
|
55
|
+
const isActive = index === items.length - 1;
|
|
56
|
+
return (
|
|
57
|
+
<React.Fragment key={item.label}>
|
|
58
|
+
{index > 0 && (
|
|
59
|
+
<Text
|
|
60
|
+
as='span'
|
|
61
|
+
size='small'
|
|
62
|
+
weight='medium'
|
|
63
|
+
color={theme.color.neutral.textSubtle}
|
|
64
|
+
className={breadcrumbClassNames.SEPARATOR}
|
|
65
|
+
>
|
|
66
|
+
/
|
|
67
|
+
</Text>
|
|
68
|
+
)}
|
|
69
|
+
<span className={clsx(breadcrumbClassNames.ITEM, isActive && breadcrumbClassNames.ITEM_ACTIVE)}>
|
|
70
|
+
{!isActive && item.url ? (
|
|
71
|
+
<StyledBreadcrumbLink to={item.url}>
|
|
72
|
+
<Text as='span' size='small' weight='normal'>{item.label}</Text>
|
|
73
|
+
</StyledBreadcrumbLink>
|
|
74
|
+
) : (
|
|
75
|
+
<StyledBreadcrumbItemText
|
|
76
|
+
size='small'
|
|
77
|
+
weight={isActive ? 'bold' : 'normal'}
|
|
78
|
+
color={isActive ? theme.color.neutral.text : theme.color.neutral.textSubtle}
|
|
79
|
+
>
|
|
80
|
+
{item.label}
|
|
81
|
+
</StyledBreadcrumbItemText>
|
|
82
|
+
)}
|
|
83
|
+
</span>
|
|
84
|
+
</React.Fragment>
|
|
85
|
+
);
|
|
86
|
+
})}
|
|
87
|
+
</StyledBreadcrumbs>
|
|
88
|
+
);
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './breadcrumb.js';
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/react-vite';
|
|
2
|
+
import { expect } from 'storybook/test';
|
|
2
3
|
import styled from 'styled-components';
|
|
3
4
|
|
|
4
5
|
import { DragIndicatorIcon } from '@apify/ui-icons';
|
|
5
6
|
|
|
6
|
-
import { CardContainer, type CardContainerProps } from './card_container.js';
|
|
7
7
|
import { IconButton } from './icon_button.js';
|
|
8
|
+
import { CardContainer, cardContainerClassNames, type CardContainerProps } from './card_container.js';
|
|
8
9
|
|
|
9
10
|
export default {
|
|
10
11
|
title: 'UI-Library/Cards/CardContainer',
|
|
@@ -14,6 +15,10 @@ export default {
|
|
|
14
15
|
control: { type: 'select' },
|
|
15
16
|
options: ['TOP', 'BOTTOM'],
|
|
16
17
|
},
|
|
18
|
+
contentPadding: {
|
|
19
|
+
control: { type: 'select' },
|
|
20
|
+
options: ['none', 'space2', 'space4', 'space8', 'space12', 'space16', 'space24'],
|
|
21
|
+
},
|
|
17
22
|
},
|
|
18
23
|
tags: ['new'],
|
|
19
24
|
} as Meta<CardContainerProps>;
|
|
@@ -25,8 +30,9 @@ const StoryWrapper = styled.div`
|
|
|
25
30
|
gap: 1rem;
|
|
26
31
|
grid-template-columns: 1fr 1fr 1fr;
|
|
27
32
|
`;
|
|
33
|
+
|
|
28
34
|
/**
|
|
29
|
-
* Default
|
|
35
|
+
* Default CardContainer with various header configurations.
|
|
30
36
|
*/
|
|
31
37
|
export const Default: Story = {
|
|
32
38
|
args: {
|
|
@@ -40,7 +46,7 @@ export const Default: Story = {
|
|
|
40
46
|
<CardContainer
|
|
41
47
|
{...args}
|
|
42
48
|
header={<>
|
|
43
|
-
<CardContainer.Heading>
|
|
49
|
+
<CardContainer.Heading>Test</CardContainer.Heading>
|
|
44
50
|
<IconButton Icon={DragIndicatorIcon}/>
|
|
45
51
|
</>}
|
|
46
52
|
/>
|
|
@@ -64,4 +70,12 @@ export const Default: Story = {
|
|
|
64
70
|
</CardContainer>
|
|
65
71
|
</StoryWrapper>;
|
|
66
72
|
},
|
|
73
|
+
play: async ({ canvasElement }) => {
|
|
74
|
+
const headers = canvasElement.querySelectorAll(`.${cardContainerClassNames.HEADER}`);
|
|
75
|
+
// 5 of 6 containers have headers (one has header={null})
|
|
76
|
+
await expect(headers.length).toBe(5);
|
|
77
|
+
|
|
78
|
+
const contents = canvasElement.querySelectorAll(`.${cardContainerClassNames.CONTENT}`);
|
|
79
|
+
await expect(contents.length).toBe(6);
|
|
80
|
+
},
|
|
67
81
|
};
|
|
@@ -4,6 +4,7 @@ import styled from 'styled-components';
|
|
|
4
4
|
import type { ValueOf } from '@apify-packages/types';
|
|
5
5
|
|
|
6
6
|
import { theme } from '../design_system/theme.js';
|
|
7
|
+
import type { Size } from '../design_system/tokens/index.js';
|
|
7
8
|
import { Box, type BoxProps } from './box.js';
|
|
8
9
|
|
|
9
10
|
export const cardContainerClassNames = {
|
|
@@ -16,7 +17,15 @@ const HEADER_PLACEMENT = {
|
|
|
16
17
|
BOTTOM: 'BOTTOM',
|
|
17
18
|
} as const;
|
|
18
19
|
|
|
19
|
-
|
|
20
|
+
type ContentPaddingValue = Size | 'none';
|
|
21
|
+
|
|
22
|
+
const getContentPadding = (contentPadding?: ContentPaddingValue) => {
|
|
23
|
+
if (contentPadding === 'none') return 0;
|
|
24
|
+
if (contentPadding) return theme.space[contentPadding];
|
|
25
|
+
return theme.space.space16;
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const Wrapper = styled(Box)<{ $headerPlacement: ValueOf<typeof HEADER_PLACEMENT>; $contentPadding?: ContentPaddingValue }>`
|
|
20
29
|
background-color: ${theme.color.neutral.backgroundSubtle};
|
|
21
30
|
border-radius: ${theme.radius.radius12};
|
|
22
31
|
|
|
@@ -26,11 +35,12 @@ const Wrapper = styled(Box)<{ $headerPlacement: ValueOf<typeof HEADER_PLACEMENT>
|
|
|
26
35
|
flex-direction: ${({ $headerPlacement }) => ($headerPlacement === HEADER_PLACEMENT.TOP ? 'column' : 'column-reverse')};
|
|
27
36
|
|
|
28
37
|
.${cardContainerClassNames.CONTENT} {
|
|
29
|
-
/*
|
|
30
|
-
border-radius:
|
|
31
|
-
background-color: ${theme.color.neutral.background};
|
|
38
|
+
/* 11px inner radius to match Figma (outer 12px - 1px visual offset) */
|
|
39
|
+
border-radius: 1.1rem;
|
|
40
|
+
background-color: ${({ $contentPadding }) => ($contentPadding === 'none' ? 'transparent' : theme.color.neutral.background)};
|
|
41
|
+
${({ $contentPadding }) => $contentPadding === 'none' && 'overflow: hidden;'}
|
|
32
42
|
|
|
33
|
-
padding: ${
|
|
43
|
+
padding: ${({ $contentPadding }) => getContentPadding($contentPadding)};
|
|
34
44
|
flex-grow: 1;
|
|
35
45
|
}
|
|
36
46
|
|
|
@@ -53,6 +63,14 @@ export type CardContainerProps = BoxProps & {
|
|
|
53
63
|
* Pass `null` to render without a header section.
|
|
54
64
|
*/
|
|
55
65
|
header: React.ReactNode,
|
|
66
|
+
/**
|
|
67
|
+
* Controls the padding of the content area. Accepts a space token or `'none'`.
|
|
68
|
+
* When set to `'none'`, padding is removed, the content background becomes transparent
|
|
69
|
+
* (the wrapper's subtle background shows through grid gaps), and overflow is hidden (corners clip to the inner border-radius).
|
|
70
|
+
* Other values (e.g. `'space8'`) change the padding but keep the white background.
|
|
71
|
+
* Defaults to `space16` with white background when not provided.
|
|
72
|
+
*/
|
|
73
|
+
contentPadding?: ContentPaddingValue,
|
|
56
74
|
};
|
|
57
75
|
|
|
58
76
|
/**
|
|
@@ -64,9 +82,10 @@ export const CardContainer = ({
|
|
|
64
82
|
children,
|
|
65
83
|
header,
|
|
66
84
|
headerPlacement = HEADER_PLACEMENT.TOP,
|
|
85
|
+
contentPadding,
|
|
67
86
|
...rest
|
|
68
87
|
}: CardContainerProps) => (
|
|
69
|
-
<Wrapper {...rest} $headerPlacement={headerPlacement}>
|
|
88
|
+
<Wrapper {...rest} $headerPlacement={headerPlacement} $contentPadding={contentPadding}>
|
|
70
89
|
{header != null && (
|
|
71
90
|
<div className={cardContainerClassNames.HEADER}>
|
|
72
91
|
{typeof header === 'string' ? <CardContainerHeading>{header}</CardContainerHeading> : header}
|
|
@@ -19,9 +19,9 @@ export const getBashLinePrefixes = (
|
|
|
19
19
|
// by default each line that is not empty or comment is a command start
|
|
20
20
|
if (bashCommandsStart.length === 0) {
|
|
21
21
|
return isEmptyLine ? (
|
|
22
|
-
<CodeHighlighterLineBashPrefix $isOneLine={isOneLine} />
|
|
22
|
+
<CodeHighlighterLineBashPrefix $isOneLine={isOneLine} key={`code-highlighter-line-bash-prefix-${i}`} />
|
|
23
23
|
) : (
|
|
24
|
-
<CodeHighlighterLineBashPrefix $isOneLine={isOneLine} color={theme.color.lavender.base}>$</CodeHighlighterLineBashPrefix>
|
|
24
|
+
<CodeHighlighterLineBashPrefix $isOneLine={isOneLine} color={theme.color.lavender.base} key={`code-highlighter-line-bash-prefix-${i}`}>$</CodeHighlighterLineBashPrefix>
|
|
25
25
|
);
|
|
26
26
|
}
|
|
27
27
|
|
package/src/components/index.ts
CHANGED