@apify/ui-library 1.141.3 → 1.145.2-featverifieddeveloperbadge-bd59c6.13
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/README.md +90 -19
- package/dist/src/components/box/box.d.ts +15 -14
- package/dist/src/components/box/box.d.ts.map +1 -1
- package/dist/src/components/box/box.js +10 -33
- package/dist/src/components/box/box.js.map +1 -1
- package/dist/src/components/breadcrumb/breadcrumb.d.ts.map +1 -1
- package/dist/src/components/breadcrumb/breadcrumb.js +1 -0
- package/dist/src/components/breadcrumb/breadcrumb.js.map +1 -1
- package/dist/src/components/card/card.d.ts.map +1 -1
- package/dist/src/components/card/card.js +1 -0
- package/dist/src/components/card/card.js.map +1 -1
- package/dist/src/components/chip/chip.d.ts.map +1 -1
- package/dist/src/components/chip/chip.js +2 -0
- package/dist/src/components/chip/chip.js.map +1 -1
- package/dist/src/components/code/code_block/code_block.styled.d.ts.map +1 -1
- package/dist/src/components/code/code_block/code_block.styled.js +1 -2
- package/dist/src/components/code/code_block/code_block.styled.js.map +1 -1
- package/dist/src/components/code/one_light_theme.d.ts.map +1 -1
- package/dist/src/components/code/one_light_theme.js +1 -0
- package/dist/src/components/code/one_light_theme.js.map +1 -1
- package/dist/src/components/dropdown/dropdown.context.d.ts +6 -0
- package/dist/src/components/dropdown/dropdown.context.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown.context.js +10 -0
- package/dist/src/components/dropdown/dropdown.context.js.map +1 -0
- package/dist/src/components/dropdown/dropdown.d.ts +48 -0
- package/dist/src/components/dropdown/dropdown.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown.js +65 -0
- package/dist/src/components/dropdown/dropdown.js.map +1 -0
- package/dist/src/components/dropdown/dropdown.styled.d.ts +35 -0
- package/dist/src/components/dropdown/dropdown.styled.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown.styled.js +241 -0
- package/dist/src/components/dropdown/dropdown.styled.js.map +1 -0
- package/dist/src/components/dropdown/dropdown.types.d.ts +17 -0
- package/dist/src/components/dropdown/dropdown.types.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown.types.js +2 -0
- package/dist/src/components/dropdown/dropdown.types.js.map +1 -0
- package/dist/src/components/dropdown/dropdown_button.d.ts +10 -0
- package/dist/src/components/dropdown/dropdown_button.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown_button.js +16 -0
- package/dist/src/components/dropdown/dropdown_button.js.map +1 -0
- package/dist/src/components/dropdown/dropdown_root.d.ts +11 -0
- package/dist/src/components/dropdown/dropdown_root.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown_root.js +19 -0
- package/dist/src/components/dropdown/dropdown_root.js.map +1 -0
- package/dist/src/components/dropdown/dropdown_shell.d.ts +15 -0
- package/dist/src/components/dropdown/dropdown_shell.d.ts.map +1 -0
- package/dist/src/components/dropdown/dropdown_shell.js +69 -0
- package/dist/src/components/dropdown/dropdown_shell.js.map +1 -0
- package/dist/src/components/dropdown/index.d.ts +7 -0
- package/dist/src/components/dropdown/index.d.ts.map +1 -0
- package/dist/src/components/dropdown/index.js +5 -0
- package/dist/src/components/dropdown/index.js.map +1 -0
- 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/message/message.d.ts +2 -0
- package/dist/src/components/message/message.d.ts.map +1 -1
- package/dist/src/components/message/message.js +2 -0
- package/dist/src/components/message/message.js.map +1 -1
- package/dist/src/components/pagination/pagination.d.ts.map +1 -1
- package/dist/src/components/pagination/pagination.js +1 -0
- package/dist/src/components/pagination/pagination.js.map +1 -1
- package/dist/src/components/tabs/tab.js +1 -1
- package/dist/src/components/tabs/tab.js.map +1 -1
- package/dist/src/utils/css_utils.d.ts +17 -0
- package/dist/src/utils/css_utils.d.ts.map +1 -1
- package/dist/src/utils/css_utils.js +54 -0
- package/dist/src/utils/css_utils.js.map +1 -1
- package/dist/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +10 -5
- package/src/components/box/box.stories.tsx +18 -0
- package/src/components/box/box.tsx +31 -62
- package/src/components/breadcrumb/breadcrumb.tsx +1 -0
- package/src/components/card/card.tsx +1 -0
- package/src/components/chip/chip.tsx +2 -0
- package/src/components/code/code_block/code_block.styled.tsx +1 -2
- package/src/components/code/one_light_theme.ts +1 -0
- package/src/components/dropdown/dropdown.context.tsx +14 -0
- package/src/components/dropdown/dropdown.stories.tsx +343 -0
- package/src/components/dropdown/dropdown.styled.ts +265 -0
- package/src/components/dropdown/dropdown.tsx +259 -0
- package/src/components/dropdown/dropdown.types.ts +18 -0
- package/src/components/dropdown/dropdown_button.tsx +45 -0
- package/src/components/dropdown/dropdown_root.tsx +41 -0
- package/src/components/dropdown/dropdown_shell.tsx +139 -0
- package/src/components/dropdown/index.ts +6 -0
- package/src/components/index.ts +1 -0
- package/src/components/message/message.stories.jsx +1 -0
- package/src/components/message/message.tsx +2 -0
- package/src/components/pagination/pagination.tsx +1 -0
- package/src/components/tabs/tab.tsx +1 -1
- package/src/design_system/colors/build_color_tokens.js +14 -0
- package/src/design_system/colors/colors.stories.tsx +395 -0
- package/src/utils/css_utils.ts +79 -0
- package/style/colors/tokens.dark.css +149 -0
- package/style/colors/tokens.light.css +149 -0
- package/src/design_system/colors/Colors.mdx +0 -50
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@apify/ui-library",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.145.2-featverifieddeveloperbadge-bd59c6.13+33d7a3fb5e7",
|
|
4
4
|
"description": "React UI library used by apify.com",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
"access": "public"
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
|
-
"test": "
|
|
14
|
+
"test": "vitest run",
|
|
15
|
+
"test:watch": "vitest watch",
|
|
15
16
|
"lint": "oxlint --type-aware .",
|
|
16
17
|
"lint:fix": "oxlint --type-aware --fix .",
|
|
17
18
|
"build": "pnpm run clean && pnpm run compile",
|
|
@@ -27,11 +28,12 @@
|
|
|
27
28
|
"It's not nice, but helps us to get around the problem of multiple react instances."
|
|
28
29
|
],
|
|
29
30
|
"dependencies": {
|
|
30
|
-
"@apify/ui-icons": "^1.
|
|
31
|
+
"@apify/ui-icons": "^1.41.1-featverifieddeveloperbadge-bd59c6.30+33d7a3fb5e7",
|
|
31
32
|
"@floating-ui/react": "^0.27.19",
|
|
32
33
|
"@floating-ui/react-dom": "^2.1.8",
|
|
33
34
|
"@radix-ui/react-checkbox": "^1.3.3",
|
|
34
35
|
"@radix-ui/react-collapsible": "^1.1.12",
|
|
36
|
+
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
|
35
37
|
"@radix-ui/react-radio-group": "^1.3.8",
|
|
36
38
|
"@radix-ui/react-switch": "^1.2.6",
|
|
37
39
|
"@react-hook/resize-observer": "^2.0.2",
|
|
@@ -59,11 +61,14 @@
|
|
|
59
61
|
"styled-components": "^6.1.19"
|
|
60
62
|
},
|
|
61
63
|
"devDependencies": {
|
|
62
|
-
"@apify-packages/types": "^3.
|
|
64
|
+
"@apify-packages/types": "^3.360.1",
|
|
63
65
|
"@storybook/react-vite": "^10.3.5",
|
|
66
|
+
"@testing-library/react": "^16.3.2",
|
|
64
67
|
"@types/hast": "^3.0.4",
|
|
65
68
|
"@types/lodash": "^4.14.200",
|
|
66
69
|
"@types/react": "19.2.2",
|
|
70
|
+
"jest-styled-components": "^7.4.0",
|
|
71
|
+
"jsdom": "^29.1.1",
|
|
67
72
|
"recast": "^0.23.9",
|
|
68
73
|
"style-dictionary": "^4.4.0",
|
|
69
74
|
"styled-components": "^6.1.19"
|
|
@@ -73,5 +78,5 @@
|
|
|
73
78
|
"src",
|
|
74
79
|
"style"
|
|
75
80
|
],
|
|
76
|
-
"gitHead": "
|
|
81
|
+
"gitHead": "33d7a3fb5e710c1d9f32465b6e63edd9667b601a"
|
|
77
82
|
}
|
|
@@ -59,6 +59,24 @@ export const PaddingSpacing: Story = {
|
|
|
59
59
|
),
|
|
60
60
|
};
|
|
61
61
|
|
|
62
|
+
/**
|
|
63
|
+
* Responsive props accept breakpoint objects, e.g. `{ mobile: 'space8', tablet: 'space16', desktop: 'space32' }`.
|
|
64
|
+
* (*Resize the preview to see spacing change between mobile, tablet, and desktop breakpoints.*)
|
|
65
|
+
*/
|
|
66
|
+
export const ResponsiveProps: Story = {
|
|
67
|
+
render: () => (
|
|
68
|
+
<Box
|
|
69
|
+
p={{ mobile: 'space8', tablet: 'space16', desktop: 'space32' }}
|
|
70
|
+
style={{ background: '#fff8e1', borderRadius: '0.4rem', border: '1px solid #f6d365' }}
|
|
71
|
+
>
|
|
72
|
+
<Sample
|
|
73
|
+
label="Box with p={{ mobile: 'space8', tablet: 'space16', desktop: 'space32' }}"
|
|
74
|
+
background="#fff"
|
|
75
|
+
/>
|
|
76
|
+
</Box>
|
|
77
|
+
),
|
|
78
|
+
};
|
|
79
|
+
|
|
62
80
|
/** `as` prop renders the Box as a different HTML element while keeping all spacing props. */
|
|
63
81
|
export const PolymorphicAs: Story = {
|
|
64
82
|
render: () => (
|
|
@@ -1,31 +1,32 @@
|
|
|
1
1
|
import type React from 'react';
|
|
2
2
|
import { forwardRef } from 'react';
|
|
3
|
-
import styled
|
|
3
|
+
import styled from 'styled-components';
|
|
4
4
|
|
|
5
5
|
import { theme } from '../../design_system/theme.js';
|
|
6
6
|
import type { Size } from '../../design_system/tokens';
|
|
7
7
|
import type { WithTransientProps } from '../../type_utils';
|
|
8
|
+
import { getResponsiveStyles, type ResponsiveValue } from '../../utils/css_utils.js';
|
|
8
9
|
|
|
9
10
|
type ExtendedSize = Size | 'none' | 'auto';
|
|
10
11
|
|
|
11
12
|
export interface MarginSpacingProps {
|
|
12
|
-
m?: ExtendedSize
|
|
13
|
-
mt?: ExtendedSize
|
|
14
|
-
mb?: ExtendedSize
|
|
15
|
-
ml?: ExtendedSize
|
|
16
|
-
mr?: ExtendedSize
|
|
17
|
-
mx?: ExtendedSize
|
|
18
|
-
my?: ExtendedSize
|
|
13
|
+
m?: ResponsiveValue<ExtendedSize>;
|
|
14
|
+
mt?: ResponsiveValue<ExtendedSize>;
|
|
15
|
+
mb?: ResponsiveValue<ExtendedSize>;
|
|
16
|
+
ml?: ResponsiveValue<ExtendedSize>;
|
|
17
|
+
mr?: ResponsiveValue<ExtendedSize>;
|
|
18
|
+
mx?: ResponsiveValue<ExtendedSize>;
|
|
19
|
+
my?: ResponsiveValue<ExtendedSize>;
|
|
19
20
|
}
|
|
20
21
|
|
|
21
22
|
export interface PaddingSpacingProps {
|
|
22
|
-
p?: ExtendedSize
|
|
23
|
-
pt?: ExtendedSize
|
|
24
|
-
pb?: ExtendedSize
|
|
25
|
-
pl?: ExtendedSize
|
|
26
|
-
pr?: ExtendedSize
|
|
27
|
-
px?: ExtendedSize
|
|
28
|
-
py?: ExtendedSize
|
|
23
|
+
p?: ResponsiveValue<ExtendedSize>;
|
|
24
|
+
pt?: ResponsiveValue<ExtendedSize>;
|
|
25
|
+
pb?: ResponsiveValue<ExtendedSize>;
|
|
26
|
+
pl?: ResponsiveValue<ExtendedSize>;
|
|
27
|
+
pr?: ResponsiveValue<ExtendedSize>;
|
|
28
|
+
px?: ResponsiveValue<ExtendedSize>;
|
|
29
|
+
py?: ResponsiveValue<ExtendedSize>;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
32
|
type SharedBoxProps = {
|
|
@@ -54,53 +55,21 @@ const getSizeValue = (token?: ExtendedSize) => {
|
|
|
54
55
|
};
|
|
55
56
|
|
|
56
57
|
const StyledBox = styled.div<WithTransientProps<MarginSpacingProps & PaddingSpacingProps>>`
|
|
57
|
-
${({ $mt, $my, $m }) =>
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
${({ $
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
${({ $
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
margin-right: ${getSizeValue($mr || $mx || $m)};
|
|
73
|
-
`}
|
|
74
|
-
|
|
75
|
-
${({ $ml, $mx, $m }) =>
|
|
76
|
-
($ml || $mx || $m) &&
|
|
77
|
-
css`
|
|
78
|
-
margin-left: ${getSizeValue($ml || $mx || $m)};
|
|
79
|
-
`}
|
|
80
|
-
|
|
81
|
-
${({ $pt, $py, $p }) =>
|
|
82
|
-
($pt || $py || $p) &&
|
|
83
|
-
css`
|
|
84
|
-
padding-top: ${getSizeValue($pt || $py || $p)};
|
|
85
|
-
`}
|
|
86
|
-
|
|
87
|
-
${({ $pb, $py, $p }) =>
|
|
88
|
-
($pb || $py || $p) &&
|
|
89
|
-
css`
|
|
90
|
-
padding-bottom: ${getSizeValue($pb || $py || $p)};
|
|
91
|
-
`}
|
|
92
|
-
|
|
93
|
-
${({ $pr, $px, $p }) =>
|
|
94
|
-
($pr || $px || $p) &&
|
|
95
|
-
css`
|
|
96
|
-
padding-right: ${getSizeValue($pr || $px || $p)};
|
|
97
|
-
`}
|
|
98
|
-
|
|
99
|
-
${({ $pl, $px, $p }) =>
|
|
100
|
-
($pl || $px || $p) &&
|
|
101
|
-
css`
|
|
102
|
-
padding-left: ${getSizeValue($pl || $px || $p)};
|
|
103
|
-
`}
|
|
58
|
+
${({ $mt, $my, $m }) => getResponsiveStyles('margin-top', getSizeValue, $mt, [$my, $m])}
|
|
59
|
+
|
|
60
|
+
${({ $mb, $my, $m }) => getResponsiveStyles('margin-bottom', getSizeValue, $mb, [$my, $m])}
|
|
61
|
+
|
|
62
|
+
${({ $mr, $mx, $m }) => getResponsiveStyles('margin-right', getSizeValue, $mr, [$mx, $m])}
|
|
63
|
+
|
|
64
|
+
${({ $ml, $mx, $m }) => getResponsiveStyles('margin-left', getSizeValue, $ml, [$mx, $m])}
|
|
65
|
+
|
|
66
|
+
${({ $pt, $py, $p }) => getResponsiveStyles('padding-top', getSizeValue, $pt, [$py, $p])}
|
|
67
|
+
|
|
68
|
+
${({ $pb, $py, $p }) => getResponsiveStyles('padding-bottom', getSizeValue, $pb, [$py, $p])}
|
|
69
|
+
|
|
70
|
+
${({ $pr, $px, $p }) => getResponsiveStyles('padding-right', getSizeValue, $pr, [$px, $p])}
|
|
71
|
+
|
|
72
|
+
${({ $pl, $px, $p }) => getResponsiveStyles('padding-left', getSizeValue, $pl, [$px, $p])}
|
|
104
73
|
`;
|
|
105
74
|
// This component should work as a base component for all low level components (Heading, Message, Card, ...) to make it easy to define spacing.
|
|
106
75
|
// 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`
|
|
@@ -29,6 +29,7 @@ const StyledBreadcrumbLink = styled(Link)`
|
|
|
29
29
|
&:hover {
|
|
30
30
|
color: ${theme.color.neutral.textMuted};
|
|
31
31
|
span {
|
|
32
|
+
/* TODO: (typography-partial) font-weight override without paired font-size/line-height — revisit to confirm intended typography token. */
|
|
32
33
|
font-weight: 500;
|
|
33
34
|
}
|
|
34
35
|
}
|
|
@@ -60,6 +60,7 @@ export const StyledCardWrapper = styled(Box)<StyledCardProps>`
|
|
|
60
60
|
margin-left: 2rem;
|
|
61
61
|
|
|
62
62
|
button {
|
|
63
|
+
/* TODO: (typography-mismatch) font-size 1.4rem + line-height 1.4rem + font-weight 500 is not a token in typography_theme.ts — resolve with designer. */
|
|
63
64
|
font-size: 1.4rem;
|
|
64
65
|
line-height: 1.4rem;
|
|
65
66
|
font-weight: 500;
|
|
@@ -50,6 +50,7 @@ const chipSizeStyle = {
|
|
|
50
50
|
border-radius: 100px;
|
|
51
51
|
`,
|
|
52
52
|
[CHIP_SIZES.LARGE]: css`
|
|
53
|
+
/* TODO: (typography-mismatch) 16px/20px does not match any canonical typography token — needs designer input. Blocks migrating chipSizeStyle to typography token interpolations (XS/S match bodyS, M matches bodyM). */
|
|
53
54
|
font-size: 16px;
|
|
54
55
|
line-height: 20px;
|
|
55
56
|
padding: 2px 8px;
|
|
@@ -114,6 +115,7 @@ const StyledChip = styled.span<{ size: CHIP_SIZES; type: CHIP_TYPES; clickable:
|
|
|
114
115
|
flex-direction: row;
|
|
115
116
|
justify-content: center;
|
|
116
117
|
align-items: center;
|
|
118
|
+
/* TODO: (typography-keyword) 'normal' keyword used instead of numeric value (400) or typography token. */
|
|
117
119
|
font-weight: normal;
|
|
118
120
|
white-space: nowrap;
|
|
119
121
|
cursor: ${({ clickable }) => (clickable ? 'pointer' : 'default')};
|
|
@@ -118,10 +118,9 @@ export const CodeBlockWrapper = styled(SyntaxHighlighterBaseStylesWrapper)<{
|
|
|
118
118
|
|
|
119
119
|
&::after {
|
|
120
120
|
/* ensures same width of text when switching tabs and making it bold */
|
|
121
|
-
${theme.typography.
|
|
121
|
+
${theme.typography.content.tablet.heading5}
|
|
122
122
|
display: block;
|
|
123
123
|
content: attr(title);
|
|
124
|
-
font-weight: bold;
|
|
125
124
|
height: 0px;
|
|
126
125
|
color: transparent;
|
|
127
126
|
overflow: hidden;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { createContext, useContext } from 'react';
|
|
2
|
+
|
|
3
|
+
export type DropdownContextValue = {
|
|
4
|
+
handleSelectAndClose: (event?: Event) => void;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
export const DropdownContext = createContext<DropdownContextValue | null>(null);
|
|
8
|
+
export const useDropdownContext = () => {
|
|
9
|
+
const context = useContext(DropdownContext);
|
|
10
|
+
if (!context) {
|
|
11
|
+
throw new Error('Dropdown components must be used within a DropdownRoot provider');
|
|
12
|
+
}
|
|
13
|
+
return context;
|
|
14
|
+
};
|
|
@@ -0,0 +1,343 @@
|
|
|
1
|
+
import { useRef, useState } from 'react';
|
|
2
|
+
import styled from 'styled-components';
|
|
3
|
+
|
|
4
|
+
import { AnalyticsIcon, ArrowRightIcon, PeopleIcon, UnlockIcon } from '@apify/ui-icons';
|
|
5
|
+
|
|
6
|
+
import { Dropdown } from './dropdown.js';
|
|
7
|
+
import { DropdownButton } from './dropdown_button.js';
|
|
8
|
+
import { DropdownShell } from './dropdown_shell.js';
|
|
9
|
+
|
|
10
|
+
const CLASS_NAME_PREFIX = 'Dropdown';
|
|
11
|
+
const elementClass = (name: string) => `${CLASS_NAME_PREFIX}-${name}`;
|
|
12
|
+
|
|
13
|
+
const ELEMENT_CLASSES = {
|
|
14
|
+
CUSTOM_BUTTON: elementClass('custom_button'),
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
interface DropdownStoryProps {
|
|
18
|
+
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
19
|
+
align?: 'start' | 'center' | 'end';
|
|
20
|
+
sideOffset?: number;
|
|
21
|
+
alignOffset?: number;
|
|
22
|
+
width?: string;
|
|
23
|
+
height?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const DropdownWrapper = styled.div`
|
|
27
|
+
position: relative;
|
|
28
|
+
padding-bottom: 40rem;
|
|
29
|
+
margin-top: 300px;
|
|
30
|
+
#positioned-wrapper {
|
|
31
|
+
display: flex;
|
|
32
|
+
gap: 20px;
|
|
33
|
+
position: absolute;
|
|
34
|
+
left: 50%;
|
|
35
|
+
transform: translate(-50%, 0);
|
|
36
|
+
}
|
|
37
|
+
overflow: auto;
|
|
38
|
+
|
|
39
|
+
.${ELEMENT_CLASSES.CUSTOM_BUTTON} {
|
|
40
|
+
padding: 8px 16px;
|
|
41
|
+
background: #007bff;
|
|
42
|
+
color: white;
|
|
43
|
+
border: none;
|
|
44
|
+
border-radius: 4px;
|
|
45
|
+
cursor: pointer;
|
|
46
|
+
font-size: 14px;
|
|
47
|
+
|
|
48
|
+
&:hover {
|
|
49
|
+
background: #0056b3;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
`;
|
|
53
|
+
|
|
54
|
+
export default {
|
|
55
|
+
title: 'UI-Library/Inputs/Dropdown',
|
|
56
|
+
component: Dropdown,
|
|
57
|
+
parameters: {
|
|
58
|
+
layout: 'padded',
|
|
59
|
+
design: {
|
|
60
|
+
type: 'figma',
|
|
61
|
+
url: 'https://www.figma.com/design/duSsGnk84UMYav8mg8QNgR/%F0%9F%93%96-Shared-library?node-id=5236-33981&p=f&t=ufGWQB5VxrrP26yD-0',
|
|
62
|
+
},
|
|
63
|
+
},
|
|
64
|
+
argTypes: {
|
|
65
|
+
side: {
|
|
66
|
+
control: { type: 'select' },
|
|
67
|
+
options: ['top', 'right', 'bottom', 'left'],
|
|
68
|
+
},
|
|
69
|
+
align: {
|
|
70
|
+
control: { type: 'select' },
|
|
71
|
+
options: ['start', 'center', 'end'],
|
|
72
|
+
},
|
|
73
|
+
sideOffset: {
|
|
74
|
+
control: { type: 'number' },
|
|
75
|
+
},
|
|
76
|
+
alignOffset: {
|
|
77
|
+
control: { type: 'number' },
|
|
78
|
+
},
|
|
79
|
+
width: {
|
|
80
|
+
control: { type: 'text' },
|
|
81
|
+
description: 'Width of the dropdown (e.g., "200px", "50%", "full-width")',
|
|
82
|
+
},
|
|
83
|
+
height: {
|
|
84
|
+
control: { type: 'text' },
|
|
85
|
+
description: 'Height of the dropdown (e.g., "300px", "50vh", "auto")',
|
|
86
|
+
},
|
|
87
|
+
},
|
|
88
|
+
args: {
|
|
89
|
+
side: 'bottom',
|
|
90
|
+
align: 'start',
|
|
91
|
+
sideOffset: 4,
|
|
92
|
+
alignOffset: 0,
|
|
93
|
+
width: '250px',
|
|
94
|
+
height: '450px',
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
export const CustomButton = (args: DropdownStoryProps) => {
|
|
99
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
100
|
+
const [radioValue, setRadioValue] = useState('option1');
|
|
101
|
+
const buttonRef = useRef<HTMLButtonElement>(null);
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<DropdownWrapper>
|
|
105
|
+
<div id="positioned-wrapper">
|
|
106
|
+
<div>
|
|
107
|
+
<button
|
|
108
|
+
ref={buttonRef}
|
|
109
|
+
className={ELEMENT_CLASSES.CUSTOM_BUTTON}
|
|
110
|
+
onClick={() => setIsOpen(!isOpen)}
|
|
111
|
+
>
|
|
112
|
+
Custom Button with Dropdown
|
|
113
|
+
</button>
|
|
114
|
+
|
|
115
|
+
<DropdownShell
|
|
116
|
+
isOpen={isOpen}
|
|
117
|
+
onIsOpenChange={setIsOpen}
|
|
118
|
+
closeOnSelect={false}
|
|
119
|
+
width={args.width}
|
|
120
|
+
height={args.height}
|
|
121
|
+
triggerRef={buttonRef}
|
|
122
|
+
contentProps={{
|
|
123
|
+
side: args.side,
|
|
124
|
+
align: args.align,
|
|
125
|
+
sideOffset: args.sideOffset,
|
|
126
|
+
alignOffset: args.alignOffset,
|
|
127
|
+
}}
|
|
128
|
+
>
|
|
129
|
+
<Dropdown.Item selected>Selected item</Dropdown.Item>
|
|
130
|
+
<Dropdown.Item icon={<ArrowRightIcon size="16" />}>Item with icon</Dropdown.Item>
|
|
131
|
+
<Dropdown.Item description="This is a description">Item with description</Dropdown.Item>
|
|
132
|
+
<Dropdown.Item description="This is a very very veryyy looong description">
|
|
133
|
+
Item with very very very looong name and description
|
|
134
|
+
</Dropdown.Item>
|
|
135
|
+
<Dropdown.Item disabled>Disabled item</Dropdown.Item>
|
|
136
|
+
<Dropdown.Separator />
|
|
137
|
+
<Dropdown.Label>Checkbox group</Dropdown.Label>
|
|
138
|
+
<Dropdown.CheckboxItem checked={true}>Checkbox item (checked)</Dropdown.CheckboxItem>
|
|
139
|
+
<Dropdown.CheckboxItem checked={false}>Checkbox item (unchecked)</Dropdown.CheckboxItem>
|
|
140
|
+
<Dropdown.Separator />
|
|
141
|
+
<Dropdown.Label>Radio group</Dropdown.Label>
|
|
142
|
+
<Dropdown.RadioGroup
|
|
143
|
+
options={[
|
|
144
|
+
{ value: 'option1', label: 'Radio option 1' },
|
|
145
|
+
{ value: 'option2', label: 'Radio option 2' },
|
|
146
|
+
{ value: 'option3', label: 'Radio option 3' },
|
|
147
|
+
]}
|
|
148
|
+
value={radioValue}
|
|
149
|
+
setValue={setRadioValue}
|
|
150
|
+
/>
|
|
151
|
+
<Dropdown.Controls>
|
|
152
|
+
<Dropdown.Item selected>Selected item</Dropdown.Item>
|
|
153
|
+
<Dropdown.Item icon={<ArrowRightIcon size="16" />}>Item with icon</Dropdown.Item>
|
|
154
|
+
<Dropdown.Item description="This is a description">Item with description</Dropdown.Item>
|
|
155
|
+
<Dropdown.Item description="This is a very very veryyy looong description">
|
|
156
|
+
Item with very very very looong name and description
|
|
157
|
+
</Dropdown.Item>
|
|
158
|
+
</Dropdown.Controls>
|
|
159
|
+
</DropdownShell>
|
|
160
|
+
</div>
|
|
161
|
+
</div>
|
|
162
|
+
</DropdownWrapper>
|
|
163
|
+
);
|
|
164
|
+
};
|
|
165
|
+
|
|
166
|
+
export const DefaultButtonVariants = (args: DropdownStoryProps) => {
|
|
167
|
+
const [checked1, setChecked1] = useState(false);
|
|
168
|
+
const [checked2, setChecked2] = useState(true);
|
|
169
|
+
const [checked3, setChecked3] = useState(true);
|
|
170
|
+
const [radioValue, setRadioValue] = useState('one');
|
|
171
|
+
return (
|
|
172
|
+
<DropdownWrapper>
|
|
173
|
+
<div id="positioned-wrapper">
|
|
174
|
+
<DropdownButton
|
|
175
|
+
buttonLabel="Dropdown (closeOnSelect=true)"
|
|
176
|
+
closeOnSelect={true}
|
|
177
|
+
width={args.width}
|
|
178
|
+
height={args.height}
|
|
179
|
+
buttonProps={{
|
|
180
|
+
variant: 'secondary',
|
|
181
|
+
size: 'medium',
|
|
182
|
+
onClick: () => undefined,
|
|
183
|
+
trackingId: 'dropdown-button-2',
|
|
184
|
+
}}
|
|
185
|
+
contentProps={{
|
|
186
|
+
side: args.side,
|
|
187
|
+
align: args.align,
|
|
188
|
+
sideOffset: args.sideOffset,
|
|
189
|
+
alignOffset: args.alignOffset,
|
|
190
|
+
}}
|
|
191
|
+
>
|
|
192
|
+
<Dropdown.Label>Section label</Dropdown.Label>
|
|
193
|
+
<Dropdown.Item>Plain item</Dropdown.Item>
|
|
194
|
+
<Dropdown.Item icon={<PeopleIcon size="16" />} trailingIcon={<ArrowRightIcon size="16" />}>
|
|
195
|
+
Item with icons
|
|
196
|
+
</Dropdown.Item>
|
|
197
|
+
<Dropdown.Item description="Describe item">Item with description</Dropdown.Item>
|
|
198
|
+
<Dropdown.Item description="A reeeeaaaally looooooong description">
|
|
199
|
+
Item with loooong text and description
|
|
200
|
+
</Dropdown.Item>
|
|
201
|
+
<Dropdown.Item icon={<UnlockIcon size="16" />} description="Describe item">
|
|
202
|
+
Item with icon and description
|
|
203
|
+
</Dropdown.Item>
|
|
204
|
+
<Dropdown.Item selected description="Describe item">
|
|
205
|
+
Selected item with description
|
|
206
|
+
</Dropdown.Item>
|
|
207
|
+
<Dropdown.Item selected trailingIcon={<AnalyticsIcon size="16" />} description="Describe item">
|
|
208
|
+
Selected item with trailing icon
|
|
209
|
+
</Dropdown.Item>
|
|
210
|
+
<Dropdown.Item
|
|
211
|
+
disabled
|
|
212
|
+
icon={<AnalyticsIcon size="16" />}
|
|
213
|
+
trailingIcon={<PeopleIcon size="16" />}
|
|
214
|
+
description="Describe item"
|
|
215
|
+
>
|
|
216
|
+
Disabled item with icons and description
|
|
217
|
+
</Dropdown.Item>
|
|
218
|
+
<Dropdown.Separator />
|
|
219
|
+
<Dropdown.Label>Checkbox group</Dropdown.Label>
|
|
220
|
+
<Dropdown.CheckboxItem checked={checked1} onCheckedChange={setChecked1} description="Describe item">
|
|
221
|
+
Checkbox item 1
|
|
222
|
+
</Dropdown.CheckboxItem>
|
|
223
|
+
<Dropdown.CheckboxItem
|
|
224
|
+
disabled
|
|
225
|
+
checked={checked2}
|
|
226
|
+
onCheckedChange={setChecked2}
|
|
227
|
+
description="Describe item"
|
|
228
|
+
>
|
|
229
|
+
Checkbox item 2 (disabled)
|
|
230
|
+
</Dropdown.CheckboxItem>
|
|
231
|
+
<Dropdown.CheckboxItem
|
|
232
|
+
checked={checked3}
|
|
233
|
+
onCheckedChange={setChecked3}
|
|
234
|
+
icon={<ArrowRightIcon size="16" />}
|
|
235
|
+
trailingIcon={<AnalyticsIcon size="16" />}
|
|
236
|
+
description="Describe item"
|
|
237
|
+
>
|
|
238
|
+
Checkbox with icons 3
|
|
239
|
+
</Dropdown.CheckboxItem>
|
|
240
|
+
<Dropdown.Separator />
|
|
241
|
+
<Dropdown.Label>Radio group</Dropdown.Label>
|
|
242
|
+
<Dropdown.RadioGroup
|
|
243
|
+
options={[
|
|
244
|
+
{
|
|
245
|
+
label: 'One with a reeeaaaally looooooong label',
|
|
246
|
+
description: 'Describe item but very very loooong',
|
|
247
|
+
value: 'one',
|
|
248
|
+
},
|
|
249
|
+
{ label: 'Two', value: 'two', description: 'Describe item', disabled: true },
|
|
250
|
+
{ label: 'Three', value: 'three' },
|
|
251
|
+
]}
|
|
252
|
+
value={radioValue}
|
|
253
|
+
setValue={setRadioValue}
|
|
254
|
+
/>
|
|
255
|
+
</DropdownButton>
|
|
256
|
+
<br />
|
|
257
|
+
<br />
|
|
258
|
+
<DropdownButton
|
|
259
|
+
buttonLabel="Dropdown (closeOnSelect=false)"
|
|
260
|
+
closeOnSelect={false}
|
|
261
|
+
width={args.width}
|
|
262
|
+
height={args.height}
|
|
263
|
+
buttonProps={{
|
|
264
|
+
variant: 'secondary',
|
|
265
|
+
size: 'medium',
|
|
266
|
+
onClick: () => undefined,
|
|
267
|
+
trackingId: 'dropdown-button-2',
|
|
268
|
+
}}
|
|
269
|
+
contentProps={{
|
|
270
|
+
side: args.side,
|
|
271
|
+
align: args.align,
|
|
272
|
+
sideOffset: args.sideOffset,
|
|
273
|
+
alignOffset: args.alignOffset,
|
|
274
|
+
}}
|
|
275
|
+
>
|
|
276
|
+
<Dropdown.Label>Section label</Dropdown.Label>
|
|
277
|
+
<Dropdown.Item>Plain item</Dropdown.Item>
|
|
278
|
+
<Dropdown.Item icon={<PeopleIcon size="16" />} trailingIcon={<AnalyticsIcon size="16" />}>
|
|
279
|
+
Item with icons
|
|
280
|
+
</Dropdown.Item>
|
|
281
|
+
<Dropdown.Item description="Describe item">Item with description</Dropdown.Item>
|
|
282
|
+
<Dropdown.Item description="A reeeeaaaally looooooong description">
|
|
283
|
+
Item with loooong text and description
|
|
284
|
+
</Dropdown.Item>
|
|
285
|
+
<Dropdown.Item icon={<AnalyticsIcon size="16" />} description="Describe item">
|
|
286
|
+
Item with icon and description
|
|
287
|
+
</Dropdown.Item>
|
|
288
|
+
<Dropdown.Item selected description="Describe item">
|
|
289
|
+
Selected item with description
|
|
290
|
+
</Dropdown.Item>
|
|
291
|
+
<Dropdown.Item selected trailingIcon={<UnlockIcon size="16" />} description="Describe item">
|
|
292
|
+
Selected item with trailing icon
|
|
293
|
+
</Dropdown.Item>
|
|
294
|
+
<Dropdown.Item
|
|
295
|
+
disabled
|
|
296
|
+
icon={<UnlockIcon size="16" />}
|
|
297
|
+
trailingIcon={<ArrowRightIcon size="16" />}
|
|
298
|
+
description="Describe item"
|
|
299
|
+
>
|
|
300
|
+
Disabled item with icons and description
|
|
301
|
+
</Dropdown.Item>
|
|
302
|
+
<Dropdown.Separator />
|
|
303
|
+
<Dropdown.Label>Checkbox group</Dropdown.Label>
|
|
304
|
+
<Dropdown.CheckboxItem checked={checked1} onCheckedChange={setChecked1} description="Describe item">
|
|
305
|
+
Checkbox item 1
|
|
306
|
+
</Dropdown.CheckboxItem>
|
|
307
|
+
<Dropdown.CheckboxItem
|
|
308
|
+
disabled
|
|
309
|
+
checked={checked2}
|
|
310
|
+
onCheckedChange={setChecked2}
|
|
311
|
+
description="Describe item"
|
|
312
|
+
>
|
|
313
|
+
Checkbox item 2 (disabled)
|
|
314
|
+
</Dropdown.CheckboxItem>
|
|
315
|
+
<Dropdown.CheckboxItem
|
|
316
|
+
checked={checked3}
|
|
317
|
+
onCheckedChange={setChecked3}
|
|
318
|
+
icon={<PeopleIcon size="16" />}
|
|
319
|
+
trailingIcon={<UnlockIcon size="16" />}
|
|
320
|
+
description="Describe item"
|
|
321
|
+
>
|
|
322
|
+
Checkbox with icons 3
|
|
323
|
+
</Dropdown.CheckboxItem>
|
|
324
|
+
<Dropdown.Separator />
|
|
325
|
+
<Dropdown.Label>Radio group</Dropdown.Label>
|
|
326
|
+
<Dropdown.RadioGroup
|
|
327
|
+
options={[
|
|
328
|
+
{
|
|
329
|
+
label: 'One with a reeeaaaally looooooong label',
|
|
330
|
+
description: 'Describe item but very very loooong',
|
|
331
|
+
value: 'one',
|
|
332
|
+
},
|
|
333
|
+
{ label: 'Two', value: 'two', description: 'Describe item', disabled: true },
|
|
334
|
+
{ label: 'Three', value: 'three' },
|
|
335
|
+
]}
|
|
336
|
+
value={radioValue}
|
|
337
|
+
setValue={setRadioValue}
|
|
338
|
+
/>
|
|
339
|
+
</DropdownButton>
|
|
340
|
+
</div>
|
|
341
|
+
</DropdownWrapper>
|
|
342
|
+
);
|
|
343
|
+
};
|