@beydesign/storybook 0.0.1 → 0.0.2
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 +60 -40
- package/dist/App.js +161 -5
- package/dist/assets/animations/loading-animation.json +1 -0
- package/dist/index.d.ts +12 -2
- package/dist/index.js +12 -4
- package/dist/stories/Agent/AgentCard.d.ts +3 -0
- package/dist/stories/Agent/AgentCard.js +102 -0
- package/dist/stories/Agent/AgentCard.stories.d.ts +13 -0
- package/dist/stories/Agent/AgentCard.stories.js +303 -0
- package/dist/stories/Agent/AgentCardSkeleton.d.ts +2 -0
- package/dist/stories/Agent/AgentCardSkeleton.js +6 -0
- package/dist/stories/Agent/AgentCardSkeleton.stories.d.ts +13 -0
- package/dist/stories/Agent/AgentCardSkeleton.stories.js +101 -0
- package/dist/stories/Agent/CreateNewCard.d.ts +7 -0
- package/dist/stories/Agent/CreateNewCard.js +25 -0
- package/dist/stories/Agent/CreateNewCard.stories.d.ts +7 -0
- package/dist/stories/Agent/CreateNewCard.stories.js +23 -0
- package/dist/stories/Agent/index.d.ts +4 -0
- package/dist/stories/Agent/index.js +4 -0
- package/dist/stories/Agent/types.d.ts +96 -0
- package/dist/stories/Agent/types.js +7 -0
- package/dist/stories/Buttons/MainButton.d.ts +3 -0
- package/dist/stories/Buttons/MainButton.js +302 -0
- package/dist/stories/Buttons/MainButton.stories.d.ts +28 -0
- package/dist/stories/Buttons/MainButton.stories.js +299 -0
- package/dist/stories/Buttons/ToggleButtonGroup.d.ts +3 -0
- package/dist/stories/Buttons/ToggleButtonGroup.js +34 -0
- package/dist/stories/Buttons/ToggleButtonGroup.stories.d.ts +9 -0
- package/dist/stories/Buttons/ToggleButtonGroup.stories.js +78 -0
- package/dist/stories/Buttons/index.d.ts +3 -0
- package/dist/stories/Buttons/index.js +3 -0
- package/dist/stories/{types/button.d.ts → Buttons/types.d.ts} +37 -14
- package/dist/stories/{types/button.js → Buttons/types.js} +12 -2
- package/dist/stories/Credits/CreditsCard.d.ts +3 -0
- package/dist/stories/Credits/CreditsCard.js +53 -0
- package/dist/stories/Credits/CreditsCard.stories.d.ts +7 -0
- package/dist/stories/Credits/CreditsCard.stories.js +34 -0
- package/dist/stories/Credits/CreditsCardSkeleton.d.ts +3 -0
- package/dist/stories/Credits/CreditsCardSkeleton.js +30 -0
- package/dist/stories/Credits/CreditsCardSkeleton.stories.d.ts +7 -0
- package/dist/stories/Credits/CreditsCardSkeleton.stories.js +40 -0
- package/dist/stories/Credits/index.d.ts +3 -0
- package/dist/stories/Credits/index.js +3 -0
- package/dist/stories/Credits/types.d.ts +57 -0
- package/dist/stories/Credits/types.js +11 -0
- package/dist/stories/EntityCard/EntityCard.d.ts +3 -0
- package/dist/stories/EntityCard/EntityCard.js +22 -0
- package/dist/stories/EntityCard/EntityCard.stories.d.ts +10 -0
- package/dist/stories/EntityCard/EntityCard.stories.js +187 -0
- package/dist/stories/EntityCard/EntityCardSkeleton.d.ts +3 -0
- package/dist/stories/EntityCard/EntityCardSkeleton.js +9 -0
- package/dist/stories/EntityCard/EntityCardSkeleton.stories.d.ts +10 -0
- package/dist/stories/EntityCard/EntityCardSkeleton.stories.js +73 -0
- package/dist/stories/EntityCard/index.d.ts +3 -0
- package/dist/stories/EntityCard/index.js +3 -0
- package/dist/stories/EntityCard/types.d.ts +54 -0
- package/dist/stories/EntityCard/types.js +1 -0
- package/dist/stories/Form/AutoComplete.d.ts +3 -0
- package/dist/stories/Form/AutoComplete.js +163 -0
- package/dist/stories/Form/AutoComplete.stories.d.ts +6 -0
- package/dist/stories/Form/AutoComplete.stories.js +88 -0
- package/dist/stories/Form/Checkbox.d.ts +3 -0
- package/dist/stories/Form/Checkbox.js +65 -0
- package/dist/stories/Form/Checkbox.stories.d.ts +13 -0
- package/dist/stories/Form/Checkbox.stories.js +121 -0
- package/dist/stories/Form/Dropdown.d.ts +3 -0
- package/dist/stories/Form/Dropdown.js +183 -0
- package/dist/stories/Form/Dropdown.stories.d.ts +6 -0
- package/dist/stories/Form/Dropdown.stories.js +122 -0
- package/dist/stories/Form/FileUpload/FileUpload.d.ts +3 -0
- package/dist/stories/Form/FileUpload/FileUpload.js +128 -0
- package/dist/stories/Form/FileUpload/FileUpload.stories.d.ts +7 -0
- package/dist/stories/Form/FileUpload/FileUpload.stories.js +51 -0
- package/dist/stories/Form/FileUpload/FileUploading.d.ts +3 -0
- package/dist/stories/Form/FileUpload/FileUploading.js +49 -0
- package/dist/stories/Form/FileUpload/FileUploading.stories.d.ts +10 -0
- package/dist/stories/Form/FileUpload/FileUploading.stories.js +108 -0
- package/dist/stories/Form/FileUpload/UploadedFile.d.ts +3 -0
- package/dist/stories/Form/FileUpload/UploadedFile.js +12 -0
- package/dist/stories/Form/FileUpload/UploadedFile.stories.d.ts +7 -0
- package/dist/stories/Form/FileUpload/UploadedFile.stories.js +73 -0
- package/dist/stories/Form/FileUpload/index.d.ts +3 -0
- package/dist/stories/Form/FileUpload/index.js +3 -0
- package/dist/stories/Form/TextArea.d.ts +3 -0
- package/dist/stories/Form/TextArea.js +23 -0
- package/dist/stories/Form/TextArea.stories.d.ts +161 -0
- package/dist/stories/Form/TextArea.stories.js +142 -0
- package/dist/stories/Form/TextInput.d.ts +3 -0
- package/dist/stories/Form/TextInput.js +57 -0
- package/dist/stories/Form/TextInput.stories.d.ts +155 -0
- package/dist/stories/Form/TextInput.stories.js +155 -0
- package/dist/stories/Form/Toggle.d.ts +3 -0
- package/dist/stories/Form/Toggle.js +57 -0
- package/dist/stories/Form/Toggle.stories.d.ts +6 -0
- package/dist/stories/Form/Toggle.stories.js +79 -0
- package/dist/stories/Form/index.d.ts +8 -0
- package/dist/stories/Form/index.js +8 -0
- package/dist/stories/Form/types.d.ts +274 -0
- package/dist/stories/Form/types.js +46 -0
- package/dist/stories/Foundations/Colors.d.ts +2 -0
- package/dist/stories/Foundations/Colors.js +266 -0
- package/dist/stories/Foundations/Colors.stories.d.ts +6 -0
- package/dist/stories/Foundations/Colors.stories.js +15 -0
- package/dist/stories/Foundations/index.d.ts +1 -0
- package/dist/stories/Foundations/index.js +1 -0
- package/dist/stories/Navigation/ComplexHeader.d.ts +3 -0
- package/dist/stories/Navigation/ComplexHeader.js +21 -0
- package/dist/stories/Navigation/ComplexHeader.stories.d.ts +6 -0
- package/dist/stories/Navigation/ComplexHeader.stories.js +82 -0
- package/dist/stories/Navigation/Header.d.ts +3 -0
- package/dist/stories/Navigation/Header.js +9 -0
- package/dist/stories/Navigation/Header.stories.d.ts +7 -0
- package/dist/stories/Navigation/Header.stories.js +87 -0
- package/dist/stories/Navigation/NavItem.d.ts +3 -0
- package/dist/stories/Navigation/NavItem.js +66 -0
- package/dist/stories/Navigation/NavItem.stories.d.ts +14 -0
- package/dist/stories/Navigation/NavItem.stories.js +100 -0
- package/dist/stories/Navigation/ProcessHeader.d.ts +3 -0
- package/dist/stories/Navigation/ProcessHeader.js +11 -0
- package/dist/stories/Navigation/ProcessHeader.stories.d.ts +6 -0
- package/dist/stories/Navigation/ProcessHeader.stories.js +76 -0
- package/dist/stories/Navigation/Sidebar.d.ts +3 -0
- package/dist/stories/Navigation/Sidebar.js +115 -0
- package/dist/stories/Navigation/Sidebar.stories.d.ts +11 -0
- package/dist/stories/Navigation/Sidebar.stories.js +174 -0
- package/dist/stories/Navigation/index.d.ts +6 -0
- package/dist/stories/Navigation/index.js +6 -0
- package/dist/stories/Navigation/types.d.ts +186 -0
- package/dist/stories/Navigation/types.js +21 -0
- package/dist/stories/PlanCard/PlanCard.d.ts +3 -0
- package/dist/stories/PlanCard/PlanCard.js +13 -0
- package/dist/stories/PlanCard/PlanCard.stories.d.ts +9 -0
- package/dist/stories/PlanCard/PlanCard.stories.js +125 -0
- package/dist/stories/PlanCard/PlanCardSkeleton.d.ts +3 -0
- package/dist/stories/PlanCard/PlanCardSkeleton.js +6 -0
- package/dist/stories/PlanCard/PlanCardSkeleton.stories.d.ts +7 -0
- package/dist/stories/PlanCard/PlanCardSkeleton.stories.js +40 -0
- package/dist/stories/PlanCard/index.d.ts +3 -0
- package/dist/stories/PlanCard/index.js +3 -0
- package/dist/stories/PlanCard/types.d.ts +61 -0
- package/dist/stories/PlanCard/types.js +1 -0
- package/dist/stories/StripeProduct/StripeProduct.d.ts +3 -0
- package/dist/stories/StripeProduct/StripeProduct.js +24 -0
- package/dist/stories/StripeProduct/StripeProduct.stories.d.ts +10 -0
- package/dist/stories/StripeProduct/StripeProduct.stories.js +110 -0
- package/dist/stories/StripeProduct/StripeProductCardSkeleton.d.ts +3 -0
- package/dist/stories/StripeProduct/StripeProductCardSkeleton.js +6 -0
- package/dist/stories/StripeProduct/StripeProductCardSkeleton.stories.d.ts +16 -0
- package/dist/stories/StripeProduct/StripeProductCardSkeleton.stories.js +137 -0
- package/dist/stories/StripeProduct/index.d.ts +3 -0
- package/dist/stories/StripeProduct/index.js +3 -0
- package/dist/stories/StripeProduct/types.d.ts +56 -0
- package/dist/stories/StripeProduct/types.js +1 -0
- package/dist/stories/Typography/Typography.d.ts +3 -0
- package/dist/stories/Typography/Typography.js +22 -0
- package/dist/stories/Typography/Typography.stories.d.ts +25 -0
- package/dist/stories/Typography/Typography.stories.js +225 -0
- package/dist/stories/Typography/index.d.ts +2 -0
- package/dist/stories/Typography/index.js +2 -0
- package/dist/stories/Typography/types.d.ts +46 -0
- package/dist/stories/Typography/types.js +27 -0
- package/dist/stories/UI/Avatar.d.ts +3 -0
- package/dist/stories/UI/Avatar.js +76 -0
- package/dist/stories/UI/Avatar.stories.d.ts +8 -0
- package/dist/stories/UI/Avatar.stories.js +76 -0
- package/dist/stories/UI/Badge.d.ts +3 -0
- package/dist/stories/UI/Badge.js +118 -0
- package/dist/stories/UI/Badge.stories.d.ts +11 -0
- package/dist/stories/UI/Badge.stories.js +107 -0
- package/dist/stories/UI/CheckIcon.d.ts +3 -0
- package/dist/stories/UI/CheckIcon.js +36 -0
- package/dist/stories/UI/CheckIcon.stories.d.ts +7 -0
- package/dist/stories/UI/CheckIcon.stories.js +48 -0
- package/dist/stories/UI/FeatureBanner.d.ts +3 -0
- package/dist/stories/UI/FeatureBanner.js +34 -0
- package/dist/stories/UI/FeatureBanner.stories.d.ts +9 -0
- package/dist/stories/UI/FeatureBanner.stories.js +131 -0
- package/dist/stories/UI/HintBubble.d.ts +3 -0
- package/dist/stories/UI/HintBubble.js +28 -0
- package/dist/stories/UI/HintBubble.stories.d.ts +9 -0
- package/dist/stories/UI/HintBubble.stories.js +68 -0
- package/dist/stories/UI/Logo.d.ts +3 -0
- package/dist/stories/UI/Logo.js +60 -0
- package/dist/stories/UI/Logo.stories.d.ts +11 -0
- package/dist/stories/UI/Logo.stories.js +65 -0
- package/dist/stories/UI/Menu.d.ts +3 -0
- package/dist/stories/UI/Menu.js +56 -0
- package/dist/stories/UI/Menu.stories.d.ts +7 -0
- package/dist/stories/UI/Menu.stories.js +80 -0
- package/dist/stories/UI/ProgressIndicator.d.ts +3 -0
- package/dist/stories/UI/ProgressIndicator.js +35 -0
- package/dist/stories/UI/ProgressIndicator.stories.d.ts +10 -0
- package/dist/stories/UI/ProgressIndicator.stories.js +98 -0
- package/dist/stories/UI/PromoBanner.d.ts +3 -0
- package/dist/stories/UI/PromoBanner.js +34 -0
- package/dist/stories/UI/PromoBanner.stories.d.ts +9 -0
- package/dist/stories/UI/PromoBanner.stories.js +159 -0
- package/dist/stories/UI/SkeletonLoader.d.ts +3 -0
- package/dist/stories/UI/SkeletonLoader.js +19 -0
- package/dist/stories/UI/SkeletonLoader.stories.d.ts +8 -0
- package/dist/stories/UI/SkeletonLoader.stories.js +74 -0
- package/dist/stories/UI/Stepper.d.ts +3 -0
- package/dist/stories/UI/Stepper.js +67 -0
- package/dist/stories/UI/Stepper.stories.d.ts +6 -0
- package/dist/stories/UI/Stepper.stories.js +65 -0
- package/dist/stories/UI/Topbar.d.ts +3 -0
- package/dist/stories/UI/Topbar.js +9 -0
- package/dist/stories/UI/Topbar.stories.d.ts +6 -0
- package/dist/stories/UI/Topbar.stories.js +71 -0
- package/dist/stories/UI/index.d.ts +13 -0
- package/dist/stories/UI/index.js +13 -0
- package/dist/stories/UI/types.d.ts +398 -0
- package/dist/stories/UI/types.js +110 -0
- package/dist/utils/common.d.ts +2 -0
- package/dist/utils/common.js +20 -0
- package/dist/utils/icon.d.ts +6 -0
- package/dist/utils/icon.js +6 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.js +3 -0
- package/dist/utils/typography.d.ts +14 -0
- package/dist/utils/typography.js +46 -0
- package/package.json +48 -42
- package/dist/stories/Button.d.ts +0 -4
- package/dist/stories/Button.js +0 -258
- package/dist/stories/Colors.d.ts +0 -5
- package/dist/stories/Colors.js +0 -9
- package/dist/stories/Header.d.ts +0 -12
- package/dist/stories/Header.js +0 -4
- package/dist/stories/Header.stories.d.ts +0 -18
- package/dist/stories/Header.stories.js +0 -26
- package/dist/stories/Page.d.ts +0 -3
- package/dist/stories/Page.js +0 -8
- package/dist/stories/Page.stories.d.ts +0 -12
- package/dist/stories/Page.stories.js +0 -24
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Box, Checkbox as MuiCheckbox } from '@mui/material';
|
|
3
|
+
import { CheckboxType } from './types';
|
|
4
|
+
import { Typography, TypographySize, TypographyWeight } from '../Typography';
|
|
5
|
+
export const Checkbox = ({ type = CheckboxType.Checkbox, label, checked, disabled, required, onChange, style, }) => {
|
|
6
|
+
const props = {
|
|
7
|
+
checked,
|
|
8
|
+
disabled,
|
|
9
|
+
required,
|
|
10
|
+
onChange,
|
|
11
|
+
disableRipple: true,
|
|
12
|
+
};
|
|
13
|
+
const handleRadioClick = () => {
|
|
14
|
+
if (!disabled && onChange) {
|
|
15
|
+
const event = {
|
|
16
|
+
target: { checked: !checked },
|
|
17
|
+
};
|
|
18
|
+
onChange(event);
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
return (_jsxs(Box, { display: "flex", alignItems: "center", justifyContent: "space-between", padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', sx: style, children: [type === CheckboxType.Checkbox ? (_jsx(MuiCheckbox, { ...props, sx: {
|
|
22
|
+
padding: 0,
|
|
23
|
+
'&.Mui-checked': {
|
|
24
|
+
color: disabled
|
|
25
|
+
? 'var(--color-background-bg-button-disabled)'
|
|
26
|
+
: 'var(--color-background-bg-brand-primary)',
|
|
27
|
+
borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)',
|
|
28
|
+
'&:hover': {
|
|
29
|
+
color: 'var(--color-background-bg-brand-primary-hover)',
|
|
30
|
+
},
|
|
31
|
+
},
|
|
32
|
+
} })) : type === CheckboxType.Radio ? (_jsx(Box, { onClick: handleRadioClick, sx: {
|
|
33
|
+
width: '20px',
|
|
34
|
+
height: '20px',
|
|
35
|
+
borderRadius: 'var(--spacing-tokens-size-in-px-radius-radius-full)',
|
|
36
|
+
border: checked ? '6px solid' : '1px solid',
|
|
37
|
+
borderColor: disabled
|
|
38
|
+
? 'var(--color-background-bg-button-disabled)'
|
|
39
|
+
: checked
|
|
40
|
+
? 'var(--color-background-bg-brand-primary)'
|
|
41
|
+
: 'var(--color-background-bg-button-disabled)',
|
|
42
|
+
display: 'flex',
|
|
43
|
+
alignItems: 'center',
|
|
44
|
+
justifyContent: 'center',
|
|
45
|
+
cursor: disabled ? 'not-allowed' : 'pointer',
|
|
46
|
+
position: 'relative',
|
|
47
|
+
backgroundColor: 'transparent',
|
|
48
|
+
boxSizing: 'border-box',
|
|
49
|
+
transition: 'all 0.2s ease-in-out',
|
|
50
|
+
'&:hover': !disabled
|
|
51
|
+
? {
|
|
52
|
+
borderColor: 'var(--color-background-bg-brand-primary-hover)',
|
|
53
|
+
}
|
|
54
|
+
: undefined,
|
|
55
|
+
'&::after': {
|
|
56
|
+
content: '""',
|
|
57
|
+
position: 'absolute',
|
|
58
|
+
width: '10px',
|
|
59
|
+
height: '10px',
|
|
60
|
+
borderRadius: 'var(--spacing-tokens-size-in-px-radius-radius-full)',
|
|
61
|
+
backgroundColor: 'transparent',
|
|
62
|
+
transition: 'all 0.2s ease-in-out',
|
|
63
|
+
},
|
|
64
|
+
} })) : null, label && (_jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.Medium, children: label }))] }));
|
|
65
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { Checkbox } from './Checkbox';
|
|
3
|
+
declare const meta: Meta<typeof Checkbox>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof Checkbox>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Checked: Story;
|
|
8
|
+
export declare const DisabledUnchecked: Story;
|
|
9
|
+
export declare const DisabledChecked: Story;
|
|
10
|
+
export declare const Radio: Story;
|
|
11
|
+
export declare const RadioChecked: Story;
|
|
12
|
+
export declare const RadioDisabledUnchecked: Story;
|
|
13
|
+
export declare const RadioDisabledChecked: Story;
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import { Checkbox } from './Checkbox';
|
|
2
|
+
import { CheckboxType } from './types';
|
|
3
|
+
const meta = {
|
|
4
|
+
title: 'Design System/Components/Form/Checkbox',
|
|
5
|
+
component: Checkbox,
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: 'centered',
|
|
8
|
+
design: {
|
|
9
|
+
type: 'figspec',
|
|
10
|
+
url: 'https://www.figma.com/design/mIhjz2yJjcpLlIqw6oUivt/Beyond-Presence?node-id=4646-6014&t=WuGtJ4j0CjG68xIe-1',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
tags: ['autodocs'],
|
|
14
|
+
argTypes: {
|
|
15
|
+
label: {
|
|
16
|
+
control: 'text',
|
|
17
|
+
description: 'Checkbox label',
|
|
18
|
+
table: {
|
|
19
|
+
type: { summary: 'string' },
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
type: {
|
|
23
|
+
control: 'select',
|
|
24
|
+
description: 'Checkbox type variant',
|
|
25
|
+
options: Object.values(CheckboxType),
|
|
26
|
+
table: {
|
|
27
|
+
type: { summary: 'string' },
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
checked: {
|
|
31
|
+
control: 'boolean',
|
|
32
|
+
description: 'Checkbox checked state',
|
|
33
|
+
table: {
|
|
34
|
+
type: { summary: 'boolean' },
|
|
35
|
+
},
|
|
36
|
+
},
|
|
37
|
+
disabled: {
|
|
38
|
+
control: 'boolean',
|
|
39
|
+
description: 'Checkbox disabled state',
|
|
40
|
+
table: {
|
|
41
|
+
type: { summary: 'boolean' },
|
|
42
|
+
},
|
|
43
|
+
},
|
|
44
|
+
required: {
|
|
45
|
+
control: 'boolean',
|
|
46
|
+
description: 'Checkbox required state',
|
|
47
|
+
table: {
|
|
48
|
+
type: { summary: 'boolean' },
|
|
49
|
+
},
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
};
|
|
53
|
+
export default meta;
|
|
54
|
+
export const Default = {
|
|
55
|
+
args: {
|
|
56
|
+
label: 'Select Me',
|
|
57
|
+
type: CheckboxType.Checkbox,
|
|
58
|
+
required: true,
|
|
59
|
+
checked: false,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
export const Checked = {
|
|
63
|
+
args: {
|
|
64
|
+
label: 'Select Me',
|
|
65
|
+
type: CheckboxType.Checkbox,
|
|
66
|
+
required: true,
|
|
67
|
+
checked: true,
|
|
68
|
+
},
|
|
69
|
+
};
|
|
70
|
+
export const DisabledUnchecked = {
|
|
71
|
+
args: {
|
|
72
|
+
label: 'Select Me',
|
|
73
|
+
type: CheckboxType.Checkbox,
|
|
74
|
+
required: true,
|
|
75
|
+
checked: false,
|
|
76
|
+
disabled: true,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
export const DisabledChecked = {
|
|
80
|
+
args: {
|
|
81
|
+
label: 'Select Me',
|
|
82
|
+
type: CheckboxType.Checkbox,
|
|
83
|
+
required: true,
|
|
84
|
+
checked: true,
|
|
85
|
+
disabled: true,
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
export const Radio = {
|
|
89
|
+
args: {
|
|
90
|
+
label: 'Radio',
|
|
91
|
+
type: CheckboxType.Radio,
|
|
92
|
+
required: true,
|
|
93
|
+
checked: false,
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
export const RadioChecked = {
|
|
97
|
+
args: {
|
|
98
|
+
label: 'Radio',
|
|
99
|
+
type: CheckboxType.Radio,
|
|
100
|
+
required: true,
|
|
101
|
+
checked: true,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
export const RadioDisabledUnchecked = {
|
|
105
|
+
args: {
|
|
106
|
+
label: 'Radio',
|
|
107
|
+
type: CheckboxType.Radio,
|
|
108
|
+
required: true,
|
|
109
|
+
checked: false,
|
|
110
|
+
disabled: true,
|
|
111
|
+
},
|
|
112
|
+
};
|
|
113
|
+
export const RadioDisabledChecked = {
|
|
114
|
+
args: {
|
|
115
|
+
label: 'Radio',
|
|
116
|
+
type: CheckboxType.Radio,
|
|
117
|
+
required: true,
|
|
118
|
+
checked: true,
|
|
119
|
+
disabled: true,
|
|
120
|
+
},
|
|
121
|
+
};
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useCallback, useEffect, useMemo, useRef, useState, } from 'react';
|
|
3
|
+
import { DropdownType } from './types';
|
|
4
|
+
import { Box, ClickAwayListener, Popper } from '@mui/material';
|
|
5
|
+
import { Typography, TypographySize, TypographyWeight } from '../Typography';
|
|
6
|
+
import { getIconComponent } from '../../utils';
|
|
7
|
+
import { Checkbox } from './Checkbox';
|
|
8
|
+
export const Dropdown = ({ disabled = false, placeholder = 'Select an option', label = 'Select', showLeadingIcon = false, leadingIcon = 'List', showClear = true, options, required = false, showCheckboxes = false, showTicks = true, ...props }) => {
|
|
9
|
+
const [open, setOpen] = useState(false);
|
|
10
|
+
const [highlightedIndex, setHighlightedIndex] = useState(-1);
|
|
11
|
+
const anchorRef = useRef(null);
|
|
12
|
+
const optionsContainerRef = useRef(null);
|
|
13
|
+
const value = useMemo(() => {
|
|
14
|
+
if (props.type === DropdownType.SingleSelect) {
|
|
15
|
+
return props.value;
|
|
16
|
+
}
|
|
17
|
+
return Array.isArray(props.value) ? props.value.join(', ') : '';
|
|
18
|
+
}, [props.type, props.value]);
|
|
19
|
+
const handleOptionSelect = useCallback((option) => {
|
|
20
|
+
if (props.type === DropdownType.SingleSelect) {
|
|
21
|
+
props.onChange(option);
|
|
22
|
+
setOpen(false);
|
|
23
|
+
}
|
|
24
|
+
else if (Array.isArray(props.value)) {
|
|
25
|
+
const newValue = props.value.includes(option)
|
|
26
|
+
? props.value.filter((item) => item !== option)
|
|
27
|
+
: [...props.value, option];
|
|
28
|
+
props.onChange(newValue);
|
|
29
|
+
}
|
|
30
|
+
}, [props]);
|
|
31
|
+
const handleClear = (e) => {
|
|
32
|
+
e.stopPropagation();
|
|
33
|
+
if (props.type === DropdownType.SingleSelect) {
|
|
34
|
+
props.onChange('');
|
|
35
|
+
}
|
|
36
|
+
else {
|
|
37
|
+
props.onChange([]);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
const handleKeyDown = (e) => {
|
|
41
|
+
if (disabled)
|
|
42
|
+
return;
|
|
43
|
+
switch (e.key) {
|
|
44
|
+
case 'Enter':
|
|
45
|
+
e.preventDefault();
|
|
46
|
+
if (open) {
|
|
47
|
+
handleOptionSelect(options[highlightedIndex]);
|
|
48
|
+
}
|
|
49
|
+
break;
|
|
50
|
+
case ' ':
|
|
51
|
+
e.preventDefault();
|
|
52
|
+
setOpen((prev) => !prev);
|
|
53
|
+
break;
|
|
54
|
+
case 'Escape':
|
|
55
|
+
e.preventDefault();
|
|
56
|
+
setOpen(false);
|
|
57
|
+
break;
|
|
58
|
+
case 'ArrowDown':
|
|
59
|
+
e.preventDefault();
|
|
60
|
+
if (!open) {
|
|
61
|
+
setOpen(true);
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
setHighlightedIndex((prev) => prev < options.length - 1 ? prev + 1 : 0);
|
|
65
|
+
}
|
|
66
|
+
break;
|
|
67
|
+
case 'ArrowUp':
|
|
68
|
+
e.preventDefault();
|
|
69
|
+
if (!open) {
|
|
70
|
+
setOpen(true);
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
setHighlightedIndex((prev) => prev > 0 ? prev - 1 : options.length - 1);
|
|
74
|
+
}
|
|
75
|
+
break;
|
|
76
|
+
case 'Tab':
|
|
77
|
+
if (open) {
|
|
78
|
+
setOpen(false);
|
|
79
|
+
}
|
|
80
|
+
break;
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
// Select highlighted option on Enter
|
|
84
|
+
useEffect(() => {
|
|
85
|
+
const handleKeyPress = (e) => {
|
|
86
|
+
if (open &&
|
|
87
|
+
e.key === 'Enter' &&
|
|
88
|
+
highlightedIndex >= 0 &&
|
|
89
|
+
highlightedIndex < options.length &&
|
|
90
|
+
!disabled) {
|
|
91
|
+
handleOptionSelect(options[highlightedIndex]);
|
|
92
|
+
}
|
|
93
|
+
};
|
|
94
|
+
window.addEventListener('keydown', handleKeyPress);
|
|
95
|
+
return () => {
|
|
96
|
+
window.removeEventListener('keydown', handleKeyPress);
|
|
97
|
+
};
|
|
98
|
+
}, [open, highlightedIndex, options, handleOptionSelect, disabled]);
|
|
99
|
+
// Scroll to highlighted option
|
|
100
|
+
useEffect(() => {
|
|
101
|
+
if (open && highlightedIndex >= 0 && optionsContainerRef.current) {
|
|
102
|
+
const highlightedElement = optionsContainerRef.current.children[highlightedIndex];
|
|
103
|
+
if (highlightedElement) {
|
|
104
|
+
highlightedElement.scrollIntoView({ block: 'nearest' });
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}, [highlightedIndex, open]);
|
|
108
|
+
const isOptionSelected = (option) => {
|
|
109
|
+
if (props.type === DropdownType.SingleSelect) {
|
|
110
|
+
return props.value === option;
|
|
111
|
+
}
|
|
112
|
+
return Array.isArray(props.value) && props.value.includes(option);
|
|
113
|
+
};
|
|
114
|
+
return (_jsx(ClickAwayListener, { onClickAway: () => setOpen(false), children: _jsxs(Box, { display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', position: 'relative', width: "100%", minWidth: '300px', children: [label && (_jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.Regular, textStyle: { textAlign: 'left' }, required: required, children: label })), _jsxs(Box, { ref: anchorRef, display: 'flex', flexDirection: 'row', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', alignItems: 'center', justifyContent: 'space-between', border: `1px solid ${open
|
|
115
|
+
? 'var(--color-border-border-component-active)'
|
|
116
|
+
: 'var(--color-border-border-component)'}`, borderRadius: '4px', bgcolor: disabled
|
|
117
|
+
? 'var(--color-background-bg-component-disabled)'
|
|
118
|
+
: 'var(--color-background-bg-component)', position: 'relative', onClick: () => !disabled && setOpen((prev) => !prev), onKeyDown: handleKeyDown, tabIndex: disabled ? -1 : 0, "aria-haspopup": "listbox", "aria-expanded": open, "aria-disabled": disabled, role: "combobox", children: [_jsx(Box, { display: "flex", alignItems: "center", flexShrink: 0, children: showLeadingIcon &&
|
|
119
|
+
getIconComponent(leadingIcon, {
|
|
120
|
+
width: '24px',
|
|
121
|
+
height: '24px',
|
|
122
|
+
color: 'var(--color-foreground-fg-secondary)',
|
|
123
|
+
'aria-hidden': 'true',
|
|
124
|
+
}) }), _jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.Regular, textStyle: {
|
|
125
|
+
flexGrow: 1,
|
|
126
|
+
minWidth: 0,
|
|
127
|
+
textAlign: 'left',
|
|
128
|
+
overflow: 'hidden',
|
|
129
|
+
textOverflow: 'ellipsis',
|
|
130
|
+
whiteSpace: 'nowrap',
|
|
131
|
+
maxWidth: '100%',
|
|
132
|
+
}, color: value
|
|
133
|
+
? 'var(--color-text-text-title)'
|
|
134
|
+
: 'var(--color-text-text-placeholder)', children: value || placeholder }), _jsxs(Box, { display: "flex", alignItems: "center", gap: "var(--spacing-tokens-size-in-px-spacing-spacing-sm)", flexShrink: 0, children: [!disabled &&
|
|
135
|
+
showClear &&
|
|
136
|
+
value &&
|
|
137
|
+
getIconComponent('X', {
|
|
138
|
+
width: '24px',
|
|
139
|
+
height: '24px',
|
|
140
|
+
color: 'var(--color-foreground-fg-secondary)',
|
|
141
|
+
onClick: handleClear,
|
|
142
|
+
'aria-label': 'Clear selection',
|
|
143
|
+
role: 'button',
|
|
144
|
+
tabIndex: 0,
|
|
145
|
+
onKeyDown: (e) => {
|
|
146
|
+
if (e.key === 'Enter' || e.key === ' ') {
|
|
147
|
+
e.preventDefault();
|
|
148
|
+
handleClear(e);
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
}), !disabled &&
|
|
152
|
+
getIconComponent(open ? 'CaretUp' : 'CaretDown', {
|
|
153
|
+
width: '24px',
|
|
154
|
+
height: '24px',
|
|
155
|
+
color: 'var(--color-foreground-fg-secondary)',
|
|
156
|
+
'aria-hidden': 'true',
|
|
157
|
+
})] })] }), _jsx(Popper, { open: open, anchorEl: anchorRef.current, placement: "bottom-start", style: { width: anchorRef.current?.offsetWidth, zIndex: 1300 }, children: _jsx(Box, { ref: optionsContainerRef, bgcolor: 'var(--color-background-bg-component)', borderRadius: '4px', width: '100%', maxHeight: '200px', overflow: 'auto', boxShadow: '0px 4px 8px rgba(0, 0, 0, 0.1)', mt: '4px', role: "listbox", sx: {
|
|
158
|
+
border: '1px solid var(--color-border-border-component)',
|
|
159
|
+
}, children: options.length === 0 ? (_jsx(Box, { display: 'flex', flexDirection: 'row', paddingX: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', paddingY: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', children: _jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.Regular, children: "No options found" }) })) : (options.map((option, index) => (_jsxs(Box, { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', onClick: () => handleOptionSelect(option), onMouseEnter: () => setHighlightedIndex(index), sx: {
|
|
160
|
+
cursor: 'pointer',
|
|
161
|
+
backgroundColor: highlightedIndex === index
|
|
162
|
+
? 'var(--color-background-bg-page)'
|
|
163
|
+
: isOptionSelected(option)
|
|
164
|
+
? 'var(--color-background-bg-element)'
|
|
165
|
+
: 'transparent',
|
|
166
|
+
'&:hover': {
|
|
167
|
+
backgroundColor: 'var(--color-background-bg-card-highlight)',
|
|
168
|
+
},
|
|
169
|
+
width: '100%',
|
|
170
|
+
boxSizing: 'border-box',
|
|
171
|
+
}, role: "option", "aria-selected": isOptionSelected(option), children: [_jsxs(Box, { display: 'flex', flexDirection: 'row', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', width: "calc(100% - 24px)", overflow: "hidden", children: [showCheckboxes && (_jsx(Box, { flexShrink: 0, children: _jsx(Checkbox, { checked: isOptionSelected(option), onChange: () => handleOptionSelect(option), style: { margin: 0, padding: 0 } }) })), _jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.Regular, color: "var(--color-text-text-title)", textStyle: {
|
|
172
|
+
overflow: 'hidden',
|
|
173
|
+
textOverflow: 'ellipsis',
|
|
174
|
+
whiteSpace: 'nowrap',
|
|
175
|
+
width: '100%',
|
|
176
|
+
}, children: option })] }), _jsx(Box, { flexShrink: 0, display: "flex", alignItems: "center", children: showTicks &&
|
|
177
|
+
isOptionSelected(option) &&
|
|
178
|
+
getIconComponent('Check', {
|
|
179
|
+
width: '16px',
|
|
180
|
+
height: '16px',
|
|
181
|
+
color: 'var(--color-foreground-fg-brand-primary)',
|
|
182
|
+
}) })] }, option)))) }) })] }) }));
|
|
183
|
+
};
|
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
import { Dropdown } from './Dropdown';
|
|
2
|
+
import { DropdownType } from './types';
|
|
3
|
+
const meta = {
|
|
4
|
+
title: 'Design System/Components/Form/Dropdown',
|
|
5
|
+
component: Dropdown,
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: 'centered',
|
|
8
|
+
design: {
|
|
9
|
+
type: 'figspec',
|
|
10
|
+
url: 'https://www.figma.com/design/mIhjz2yJjcpLlIqw6oUivt/Beyond-Presence?node-id=4501-25356&t=XsmO3ZzXQ9rb1lu5-1',
|
|
11
|
+
},
|
|
12
|
+
},
|
|
13
|
+
tags: ['autodocs'],
|
|
14
|
+
argTypes: {
|
|
15
|
+
options: {
|
|
16
|
+
control: 'select',
|
|
17
|
+
description: 'The options to display in the dropdown',
|
|
18
|
+
table: {
|
|
19
|
+
type: { summary: 'string[]' },
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
value: {
|
|
23
|
+
control: 'text',
|
|
24
|
+
description: 'The value of the selected option',
|
|
25
|
+
table: {
|
|
26
|
+
type: { summary: 'string' },
|
|
27
|
+
},
|
|
28
|
+
},
|
|
29
|
+
onChange: {
|
|
30
|
+
description: 'The onChange handler for the selected option',
|
|
31
|
+
table: {
|
|
32
|
+
type: { summary: 'function' },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
disabled: {
|
|
36
|
+
control: 'boolean',
|
|
37
|
+
description: 'Whether the autocomplete is disabled',
|
|
38
|
+
table: {
|
|
39
|
+
type: { summary: 'boolean' },
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
placeholder: {
|
|
43
|
+
control: 'text',
|
|
44
|
+
description: 'The placeholder of the autocomplete',
|
|
45
|
+
table: {
|
|
46
|
+
type: { summary: 'string' },
|
|
47
|
+
},
|
|
48
|
+
},
|
|
49
|
+
type: {
|
|
50
|
+
control: 'select',
|
|
51
|
+
description: 'The type of the dropdown',
|
|
52
|
+
options: Object.values(DropdownType),
|
|
53
|
+
table: {
|
|
54
|
+
defaultValue: { summary: DropdownType.SingleSelect },
|
|
55
|
+
type: { summary: 'string' },
|
|
56
|
+
},
|
|
57
|
+
},
|
|
58
|
+
label: {
|
|
59
|
+
control: 'text',
|
|
60
|
+
description: 'The label of the dropdown',
|
|
61
|
+
table: {
|
|
62
|
+
type: { summary: 'string' },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
leadingIcon: {
|
|
66
|
+
control: 'select',
|
|
67
|
+
description: 'The leading icon of the dropdown',
|
|
68
|
+
options: ['Cactus', 'MagnifyingGlass', 'User', 'Check', 'X'],
|
|
69
|
+
table: {
|
|
70
|
+
type: { summary: 'string' },
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
required: {
|
|
74
|
+
control: 'boolean',
|
|
75
|
+
description: 'Whether the dropdown is required',
|
|
76
|
+
table: {
|
|
77
|
+
type: { summary: 'boolean' },
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
showClear: {
|
|
81
|
+
control: 'boolean',
|
|
82
|
+
description: 'Whether to show the clear button',
|
|
83
|
+
table: {
|
|
84
|
+
type: { summary: 'boolean' },
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
showLeadingIcon: {
|
|
88
|
+
control: 'boolean',
|
|
89
|
+
description: 'Whether to show the leading icon',
|
|
90
|
+
table: {
|
|
91
|
+
type: { summary: 'boolean' },
|
|
92
|
+
},
|
|
93
|
+
},
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
export default meta;
|
|
97
|
+
export const Default = {
|
|
98
|
+
args: {
|
|
99
|
+
options: [
|
|
100
|
+
'Option 1',
|
|
101
|
+
'Option 2',
|
|
102
|
+
'Option 3',
|
|
103
|
+
'Option 4',
|
|
104
|
+
'Option 5',
|
|
105
|
+
'Option 6',
|
|
106
|
+
'Option 7',
|
|
107
|
+
'Option 8',
|
|
108
|
+
'Option 9',
|
|
109
|
+
'Option 10',
|
|
110
|
+
],
|
|
111
|
+
value: 'Option 1',
|
|
112
|
+
onChange: () => { },
|
|
113
|
+
type: DropdownType.SingleSelect,
|
|
114
|
+
placeholder: 'Select an option',
|
|
115
|
+
label: 'Select',
|
|
116
|
+
leadingIcon: 'List',
|
|
117
|
+
disabled: false,
|
|
118
|
+
showClear: true,
|
|
119
|
+
showLeadingIcon: true,
|
|
120
|
+
required: false,
|
|
121
|
+
},
|
|
122
|
+
};
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { useRef, useState } from 'react';
|
|
3
|
+
import { Box } from '@mui/material';
|
|
4
|
+
import { FileDoc, FilePdf, FileTxt, FileXls, FilePpt, FileJs, FileCss, FileHtml, FileImage, FileAudio, FileVideo, FileZip, FileCode, UploadSimple, FileCsv, } from '@phosphor-icons/react';
|
|
5
|
+
import { Typography, TypographySize, TypographyWeight } from '../../Typography';
|
|
6
|
+
// Map file extensions to their corresponding icons
|
|
7
|
+
const fileIconMap = {
|
|
8
|
+
// Document/Text Files
|
|
9
|
+
'.doc': FileDoc,
|
|
10
|
+
'.docx': FileDoc,
|
|
11
|
+
'.txt': FileTxt,
|
|
12
|
+
'.rtf': FileDoc,
|
|
13
|
+
// Spreadsheet Files
|
|
14
|
+
'.csv': FileCsv,
|
|
15
|
+
'.xls': FileXls,
|
|
16
|
+
'.xlsx': FileXls,
|
|
17
|
+
// Presentation Files
|
|
18
|
+
'.ppt': FilePpt,
|
|
19
|
+
'.pptx': FilePpt,
|
|
20
|
+
// Code/Markup Files
|
|
21
|
+
'.js': FileJs,
|
|
22
|
+
'.ts': FileCode,
|
|
23
|
+
'.css': FileCss,
|
|
24
|
+
'.html': FileHtml,
|
|
25
|
+
'.json': FileJs,
|
|
26
|
+
'.xml': FileXls,
|
|
27
|
+
// Media Files
|
|
28
|
+
'.jpg': FileImage,
|
|
29
|
+
'.jpeg': FileImage,
|
|
30
|
+
'.png': FileImage,
|
|
31
|
+
'.gif': FileImage,
|
|
32
|
+
'.svg': FileImage,
|
|
33
|
+
'.mp3': FileAudio,
|
|
34
|
+
'.wav': FileAudio,
|
|
35
|
+
'.mp4': FileVideo,
|
|
36
|
+
'.mov': FileVideo,
|
|
37
|
+
// Archive Files
|
|
38
|
+
'.zip': FileZip,
|
|
39
|
+
'.rar': FileZip,
|
|
40
|
+
'.tar': FileZip,
|
|
41
|
+
'.gz': FileZip,
|
|
42
|
+
// PDF Files
|
|
43
|
+
'.pdf': FilePdf,
|
|
44
|
+
};
|
|
45
|
+
// Default icon for unknown file types
|
|
46
|
+
const defaultIcon = FileCode;
|
|
47
|
+
export const FileUpload = ({ disabled, sx, acceptedFileTypes = '.pdf,.doc,.docx,.txt', maxFileSizeMB = 10, onFileSelect, }) => {
|
|
48
|
+
const [isDragging, setIsDragging] = useState(false);
|
|
49
|
+
const fileInputRef = useRef(null);
|
|
50
|
+
// Function to get the icons to display based on acceptedFileTypes
|
|
51
|
+
const getFileTypeIcons = () => {
|
|
52
|
+
// Parse the acceptedFileTypes string into an array of extensions
|
|
53
|
+
const extensions = acceptedFileTypes
|
|
54
|
+
.toLowerCase()
|
|
55
|
+
.split(',')
|
|
56
|
+
.map((ext) => ext.trim())
|
|
57
|
+
.filter((ext) => ext.startsWith('.'));
|
|
58
|
+
// Get unique icons for the accepted file types
|
|
59
|
+
const uniqueIcons = new Map();
|
|
60
|
+
extensions.forEach((ext) => {
|
|
61
|
+
const IconComponent = fileIconMap[ext] || defaultIcon;
|
|
62
|
+
// Use the component name as key to avoid duplicates
|
|
63
|
+
uniqueIcons.set(IconComponent.name, IconComponent);
|
|
64
|
+
});
|
|
65
|
+
return Array.from(uniqueIcons.values());
|
|
66
|
+
};
|
|
67
|
+
const fileIcons = getFileTypeIcons();
|
|
68
|
+
const handleFileSelect = (files) => {
|
|
69
|
+
if (!files || disabled)
|
|
70
|
+
return;
|
|
71
|
+
const file = files[0];
|
|
72
|
+
if (file.size > maxFileSizeMB * 1024 * 1024) {
|
|
73
|
+
alert(`File size exceeds the maximum limit of ${maxFileSizeMB}MB`);
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (onFileSelect)
|
|
77
|
+
onFileSelect(file);
|
|
78
|
+
};
|
|
79
|
+
const handleClick = () => {
|
|
80
|
+
if (disabled)
|
|
81
|
+
return;
|
|
82
|
+
else if (fileInputRef.current) {
|
|
83
|
+
fileInputRef.current.click();
|
|
84
|
+
}
|
|
85
|
+
};
|
|
86
|
+
const handleDragOver = (e) => {
|
|
87
|
+
e.preventDefault();
|
|
88
|
+
if (!disabled) {
|
|
89
|
+
setIsDragging(true);
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
const handleDragLeave = (e) => {
|
|
93
|
+
e.preventDefault();
|
|
94
|
+
setIsDragging(false);
|
|
95
|
+
};
|
|
96
|
+
const handleDrop = (e) => {
|
|
97
|
+
e.preventDefault();
|
|
98
|
+
setIsDragging(false);
|
|
99
|
+
if (!disabled) {
|
|
100
|
+
handleFileSelect(e.dataTransfer.files);
|
|
101
|
+
}
|
|
102
|
+
};
|
|
103
|
+
const handleInputChange = (e) => {
|
|
104
|
+
handleFileSelect(e.target.files);
|
|
105
|
+
};
|
|
106
|
+
const iconProps = {
|
|
107
|
+
height: '20px',
|
|
108
|
+
width: '20px',
|
|
109
|
+
color: disabled
|
|
110
|
+
? 'var(--color-text-text-subtle)'
|
|
111
|
+
: 'var(--color-text-text-paragraph)',
|
|
112
|
+
};
|
|
113
|
+
return (_jsxs(Box, { display: 'flex', flexDirection: 'column', alignItems: 'center', justifyContent: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', border: `1.5px dashed ${isDragging ? 'var(--color-background-bg-brand-primary-hover)' : 'var(--color-background-bg-brand-primary)'}`, bgcolor: disabled
|
|
114
|
+
? 'var(--color-background-bg-component-contrast-subtle)'
|
|
115
|
+
: isDragging
|
|
116
|
+
? 'var(--color-background-bg-component-hover)'
|
|
117
|
+
: 'var(--color-background-bg-element)', sx: { cursor: disabled ? 'not-allowed' : 'pointer', ...sx }, onClick: handleClick, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, children: [_jsx("input", { type: "file", ref: fileInputRef, style: { display: 'none' }, accept: acceptedFileTypes, onChange: handleInputChange, disabled: disabled }), _jsx(Box, { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', border: `2px solid ${disabled
|
|
118
|
+
? 'var(--color-border-border-component)'
|
|
119
|
+
: isDragging
|
|
120
|
+
? 'var(--color-background-bg-brand-primary-hover)'
|
|
121
|
+
: 'var(--color-background-bg-brand-primary)'}`, borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', bgcolor: 'var(--color-background-bg-component)', children: _jsx(UploadSimple, { height: '20px', width: '20px', weight: "bold", color: disabled
|
|
122
|
+
? 'var(--color-foreground-fg-disabled)'
|
|
123
|
+
: 'var(--color-foreground-fg-brand-primary)' }) }), _jsxs(Box, { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', children: [_jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.SemiBold, color: disabled
|
|
124
|
+
? 'var(--color-text-text-disabled)'
|
|
125
|
+
: 'var(--color-text-text-accent)', textStyle: { cursor: disabled ? 'not-allowed' : 'pointer' }, children: "Click to upload" }), _jsx(Typography, { size: TypographySize.TextS, weight: TypographyWeight.Regular, color: disabled
|
|
126
|
+
? 'var(--color-text-text-subtle)'
|
|
127
|
+
: 'var(--color-text-text-paragraph)', children: "or drag and drop" }), _jsxs(Box, { display: 'flex', flexDirection: 'row', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', children: [fileIcons.map((Icon, index) => (_jsx(Icon, { ...iconProps }, index))), fileIcons.length === 0 && _jsx(FileCode, { ...iconProps })] })] })] }));
|
|
128
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { Meta, StoryObj } from '@storybook/react';
|
|
2
|
+
import { FileUpload } from './FileUpload';
|
|
3
|
+
declare const meta: Meta<typeof FileUpload>;
|
|
4
|
+
export default meta;
|
|
5
|
+
type Story = StoryObj<typeof FileUpload>;
|
|
6
|
+
export declare const Default: Story;
|
|
7
|
+
export declare const Disabled: Story;
|