@beydesign/storybook 0.0.41 → 0.0.43

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.
@@ -6,12 +6,12 @@ import { Typography, TypographySize, TypographyWeight } from '../Typography';
6
6
  import { Toggle, TogglePosition } from '../Form';
7
7
  import { Badge, ProgressIndicator, ProgressIndicatorMode, BadgeColor, BadgeSize, Menu, } from '../UI';
8
8
  import { MainButton, ButtonHierarchy, ButtonSize } from '../Buttons';
9
- import { ArrowsCounterClockwise } from '@phosphor-icons/react';
10
- export const AgentCard = ({ title, description = '', date = '', showDate = false, badges = [], showBadges = false, showTimeBadge = false, showDescription = false, showMenu = false, menuItems = [], active = false, showActiveToggle = false, onActiveToggleChange, activeToggleDisabled = false, agentImage, time, onPreview, agentState, previewButtonText = 'Preview', }) => {
9
+ import { ArrowsCounterClockwise, Warning } from '@phosphor-icons/react';
10
+ export const AgentCard = ({ title, description = '', date = '', showDate = false, badges = [], showBadges = false, showTimeBadge = false, showDescription = false, showMenu = false, menuItems = [], active = false, showActiveToggle = false, onActiveToggleChange, activeToggleDisabled = false, agentImage, time, onPreview, agentState, previewButtonText = 'Preview', showStatusBadge = false, statusBadgeText = '', }) => {
11
11
  const [hovered, setHovered] = useState(false);
12
12
  const [imageError, setImageError] = useState(false);
13
13
  const [isLoading, setIsLoading] = useState(!!agentImage);
14
- // const isError = agentState === AgentState.error;
14
+ const isError = agentState === AgentState.error;
15
15
  const isDraft = agentState === AgentState.pending;
16
16
  const isProcessing = agentState === AgentState.processing;
17
17
  const isReady = agentState === AgentState.ready;
@@ -59,17 +59,24 @@ export const AgentCard = ({ title, description = '', date = '', showDate = false
59
59
  }
60
60
  return (_jsx("img", { src: agentImage, alt: "Agent", width: '100%', height: '100%', style: { objectFit: 'cover', height: '100%', width: '100%' } }));
61
61
  };
62
- return (_jsxs(Box, { width: '300px', display: 'flex', flexDirection: 'column', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-xl)', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', bgcolor: isDraft
63
- ? 'var(--colors-light-background-bg-element)'
64
- : 'var(--colors-light-background-bg-component)', boxShadow: `var(--global-shadows-shadow-xs-offset-x) var(--global-shadows-shadow-xs-offset-y) var(--global-shadows-shadow-xs-blur) var(--global-shadows-shadow-xs-spread) var(--global-shadows-shadow-xs-color)`, children: [_jsxs(Box, { display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative', width: '100%', sx: { aspectRatio: 1 }, borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', overflow: 'hidden', onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: [renderImageContent(), showTimeBadge && time && (_jsx(Badge, { text: time, size: BadgeSize.md, fill: true, style: {
62
+ return (_jsxs(Box, { width: '300px', display: 'flex', flexDirection: 'column', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-xl)', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', bgcolor: isError
63
+ ? 'var(--colors-light-background-bg-error-subtle)'
64
+ : isDraft
65
+ ? 'var(--colors-light-background-bg-element)'
66
+ : 'var(--colors-light-background-bg-component)', boxShadow: `var(--global-shadows-shadow-xs-offset-x) var(--global-shadows-shadow-xs-offset-y) var(--global-shadows-shadow-xs-blur) var(--global-shadows-shadow-xs-spread) var(--global-shadows-shadow-xs-color)`, children: [_jsxs(Box, { display: 'flex', justifyContent: 'center', alignItems: 'center', position: 'relative', sx: { aspectRatio: 1 }, borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', overflow: 'hidden', onMouseEnter: () => setHovered(true), onMouseLeave: () => setHovered(false), children: [renderImageContent(), showTimeBadge && time && (_jsx(Badge, { text: time, size: BadgeSize.md, fill: true, style: {
65
67
  position: 'absolute',
66
68
  right: '8px',
67
69
  bottom: '8px',
68
70
  zIndex: 2,
69
- }, color: BadgeColor.Violet })), showMenu && menuItems.length > 0 && (_jsx(Menu, { items: menuItems, style: {
71
+ }, color: BadgeColor.Violet })), showStatusBadge && statusBadgeText && (_jsx(Badge, { text: statusBadgeText, size: BadgeSize.md, fill: true, style: {
72
+ position: 'absolute',
73
+ left: '8px',
74
+ top: '8px',
75
+ zIndex: 2,
76
+ }, color: BadgeColor.Blue })), showMenu && menuItems.length > 0 && (_jsx(Menu, { items: menuItems, style: {
70
77
  zIndex: 2,
71
78
  position: 'absolute',
72
79
  right: '8px',
73
80
  top: '8px',
74
- } })), isReady && hovered && onPreview && (_jsx(Box, { position: 'absolute', top: '0', left: '0', width: '100%', height: '100%', bgcolor: 'var(--colors-light-background-bg-component-hover)', sx: { zIndex: 1 }, display: 'flex', justifyContent: 'center', alignItems: 'center', children: _jsx(MainButton, { text: previewButtonText, onClick: onPreview, showTrailingIcon: true, trailingIcon: "Play", hierarchy: ButtonHierarchy.SecondaryTransparent, size: ButtonSize.sm, style: { border: 'none' } }) })), isProcessing && (_jsxs(Box, { position: 'absolute', top: '0', left: '0', width: '100%', height: '100%', bgcolor: 'var(--colors-light-background-bg-component-hover)', style: { zIndex: 1 }, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', children: [_jsx(ArrowsCounterClockwise, { size: 24, weight: "bold", color: 'var(--primitives-desktop-primary-white-100)' }), _jsx(Typography, { text: "Agent creation in progress", size: TypographySize.TextS, weight: TypographyWeight.SemiBold, color: 'var(--primitives-desktop-primary-white-100)' }), _jsx(ProgressIndicator, { mode: ProgressIndicatorMode.Percentage, currentValue: 50, maxValue: 100, textColor: 'var(--primitives-desktop-primary-white-100)' })] }))] }), _jsx(Typography, { text: title, size: TypographySize.HeadingXS, weight: TypographyWeight.SemiBold }), (showDate || showActiveToggle) && (_jsxs(Box, { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', children: [showDate && (_jsx(Typography, { text: date, size: TypographySize.TextS, weight: TypographyWeight.Regular, color: 'var(--colors-light-text-text-subtle)', style: { flex: 1 } })), showActiveToggle && (_jsx(Toggle, { checked: active, onChange: (checked) => onActiveToggleChange?.(checked), disabled: activeToggleDisabled, text: "Active", togglePosition: TogglePosition.Right, style: { flex: 1 } }))] })), showBadges && (_jsx(Box, { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', children: badges.map((badge, index) => (_jsx(Badge, { text: badge, size: BadgeSize.lg, fill: true }, `badge-${index}-${badge}`))) })), showDescription && (_jsx(Typography, { text: description, size: TypographySize.TextS, weight: TypographyWeight.Regular, color: 'var(--colors-light-text-text-paragraph)' }))] }));
81
+ } })), isReady && hovered && onPreview && active && (_jsx(Box, { position: 'absolute', top: '0', left: '0', width: '100%', height: '100%', bgcolor: 'var(--colors-light-background-bg-component-hover)', sx: { zIndex: 1 }, display: 'flex', justifyContent: 'center', alignItems: 'center', children: _jsx(MainButton, { text: previewButtonText, onClick: onPreview, showTrailingIcon: true, trailingIcon: "Play", hierarchy: ButtonHierarchy.SecondaryTransparent, size: ButtonSize.sm, style: { border: 'none' } }) })), isProcessing && (_jsxs(Box, { position: 'absolute', top: '0', left: '0', width: '100%', height: '100%', bgcolor: 'var(--colors-light-background-bg-component-hover)', style: { zIndex: 1 }, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', children: [_jsx(ArrowsCounterClockwise, { size: 24, weight: "bold", color: 'var(--primitives-desktop-primary-white-100)' }), _jsx(Typography, { text: "Agent creation in progress", size: TypographySize.TextS, weight: TypographyWeight.SemiBold, color: 'var(--primitives-desktop-primary-white-100)' }), _jsx(ProgressIndicator, { mode: ProgressIndicatorMode.Percentage, currentValue: 50, maxValue: 100, textColor: 'var(--primitives-desktop-primary-white-100)' })] })), isError && (_jsxs(Box, { position: 'absolute', top: '0', left: '0', width: '100%', height: '100%', bgcolor: 'var(--colors-light-background-bg-error-solid)', style: { zIndex: 1, opacity: 0.7 }, display: 'flex', flexDirection: 'column', justifyContent: 'center', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', children: [_jsx(Warning, { size: 74, color: 'var(--primitives-desktop-primary-white-100)' }), _jsx(Typography, { text: "Something went wrong", size: TypographySize.TextS, weight: TypographyWeight.SemiBold, color: 'var(--primitives-desktop-primary-white-100)' })] }))] }), _jsx(Typography, { text: title, size: TypographySize.HeadingXS, weight: TypographyWeight.SemiBold }), (showDate || showActiveToggle) && (_jsxs(Box, { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', children: [showDate && (_jsx(Typography, { text: date, size: TypographySize.TextS, weight: TypographyWeight.Regular, color: 'var(--colors-light-text-text-subtle)', style: { flex: 1 } })), showActiveToggle && (_jsx(Toggle, { checked: active, onChange: (checked) => onActiveToggleChange?.(checked), disabled: activeToggleDisabled, text: "Active", togglePosition: TogglePosition.Right, style: { flex: 1 } }))] })), showBadges && (_jsx(Box, { display: 'flex', flexDirection: 'row', flexWrap: 'wrap', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', children: badges.map((badge, index) => (_jsx(Badge, { text: badge, size: BadgeSize.lg, fill: true }, `badge-${index}-${badge}`))) })), showDescription && (_jsx(Typography, { text: description, size: TypographySize.TextS, weight: TypographyWeight.Regular, color: 'var(--colors-light-text-text-paragraph)' }))] }));
75
82
  };
@@ -7,3 +7,5 @@ export declare const Placeholder: Story;
7
7
  export declare const CustomPreviewText: Story;
8
8
  export declare const LoadingPreview: Story;
9
9
  export declare const NoImage: Story;
10
+ export declare const WithStatusBadge: Story;
11
+ export declare const NoStatusBadge: Story;
@@ -124,6 +124,20 @@ const meta = {
124
124
  defaultValue: { summary: 'Preview' },
125
125
  },
126
126
  },
127
+ showStatusBadge: {
128
+ control: 'boolean',
129
+ description: 'Whether to show the status badge',
130
+ table: {
131
+ type: { summary: 'boolean' },
132
+ },
133
+ },
134
+ statusBadgeText: {
135
+ control: 'text',
136
+ description: 'Text to display in the status badge',
137
+ table: {
138
+ type: { summary: 'string' },
139
+ },
140
+ },
127
141
  },
128
142
  };
129
143
  export default meta;
@@ -149,6 +163,8 @@ export const Placeholder = {
149
163
  ],
150
164
  showMenu: true,
151
165
  agentState: AgentState.ready,
166
+ showStatusBadge: true,
167
+ statusBadgeText: 'Active',
152
168
  },
153
169
  };
154
170
  export const CustomPreviewText = {
@@ -164,6 +180,7 @@ export const LoadingPreview = {
164
180
  title: 'Loading Preview Example',
165
181
  // Using a non-existent image to force loading state
166
182
  agentImage: 'https://example.com/non-existent-image.jpg',
183
+ active: false,
167
184
  },
168
185
  parameters: {
169
186
  docs: {
@@ -187,3 +204,34 @@ export const NoImage = {
187
204
  },
188
205
  },
189
206
  };
207
+ export const WithStatusBadge = {
208
+ args: {
209
+ ...Placeholder.args,
210
+ title: 'Status Badge Example',
211
+ showStatusBadge: true,
212
+ statusBadgeText: 'Draft',
213
+ agentState: AgentState.pending,
214
+ },
215
+ parameters: {
216
+ docs: {
217
+ description: {
218
+ story: 'This example demonstrates the agent card with a status badge in the top-left corner.',
219
+ },
220
+ },
221
+ },
222
+ };
223
+ export const NoStatusBadge = {
224
+ args: {
225
+ ...Placeholder.args,
226
+ title: 'No Status Badge Example',
227
+ showStatusBadge: false,
228
+ statusBadgeText: '',
229
+ },
230
+ parameters: {
231
+ docs: {
232
+ description: {
233
+ story: 'This example demonstrates the agent card without a status badge.',
234
+ },
235
+ },
236
+ },
237
+ };
@@ -47,6 +47,10 @@ export type AgentCardProps = {
47
47
  agentState?: AgentState;
48
48
  /** Preview button text */
49
49
  previewButtonText?: string;
50
+ /** Show status badge */
51
+ showStatusBadge?: boolean;
52
+ /** Status badge text */
53
+ statusBadgeText?: string;
50
54
  };
51
55
  export interface AgentCardSkeletonProps {
52
56
  /**
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+ import { FileUploadProps } from '../types';
3
+ export declare const FileUpload: FC<FileUploadProps>;
@@ -0,0 +1,69 @@
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, UploadSimple } from '@phosphor-icons/react';
5
+ import { Typography, TypographySize, TypographyWeight } from '../../Typography';
6
+ export const FileUpload = ({ disabled, sx, acceptedFileTypes = '.pdf,.doc,.docx,.txt', maxFileSizeMB = 10, onFileSelect, }) => {
7
+ const [isDragging, setIsDragging] = useState(false);
8
+ const fileInputRef = useRef(null);
9
+ const handleFileSelect = (files) => {
10
+ if (!files || disabled)
11
+ return;
12
+ const file = files[0];
13
+ if (file.size > maxFileSizeMB * 1024 * 1024) {
14
+ alert(`File size exceeds the maximum limit of ${maxFileSizeMB}MB`);
15
+ return;
16
+ }
17
+ if (onFileSelect)
18
+ onFileSelect(file);
19
+ };
20
+ const handleClick = () => {
21
+ if (disabled)
22
+ return;
23
+ else if (fileInputRef.current) {
24
+ fileInputRef.current.click();
25
+ }
26
+ };
27
+ const handleDragOver = (e) => {
28
+ e.preventDefault();
29
+ if (!disabled) {
30
+ setIsDragging(true);
31
+ }
32
+ };
33
+ const handleDragLeave = (e) => {
34
+ e.preventDefault();
35
+ setIsDragging(false);
36
+ };
37
+ const handleDrop = (e) => {
38
+ e.preventDefault();
39
+ setIsDragging(false);
40
+ if (!disabled) {
41
+ handleFileSelect(e.dataTransfer.files);
42
+ }
43
+ };
44
+ const handleInputChange = (e) => {
45
+ handleFileSelect(e.target.files);
46
+ };
47
+ const iconProps = {
48
+ height: '20px',
49
+ width: '20px',
50
+ color: disabled
51
+ ? 'var(--colors-light-text-text-subtle)'
52
+ : 'var(--colors-light-text-text-paragraph)',
53
+ };
54
+ 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(--colors-light-background-bg-brand-hover)' : 'var(--colors-light-background-bg-brand)'}`, bgcolor: disabled
55
+ ? 'var(--colors-light-background-bg-component-contrast-subtle)'
56
+ : isDragging
57
+ ? 'var(--colors-light-background-bg-element-hover)'
58
+ : 'var(--colors-light-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
59
+ ? 'var(--colors-light-border-border-component)'
60
+ : isDragging
61
+ ? 'var(--colors-light-background-bg-brand-hover)'
62
+ : 'var(--colors-light-background-bg-brand)'}`, borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', bgcolor: 'var(--primitives-desktop-primary-white-100)', children: _jsx(UploadSimple, { height: '20px', width: '20px', weight: "bold", color: disabled
63
+ ? 'var(--colors-light-foreground-fg-disabled)'
64
+ : 'var(--colors-light-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, { text: 'Click to upload', size: TypographySize.TextS, weight: TypographyWeight.SemiBold, color: disabled
65
+ ? 'var(--colors-light-text-text-disabled)'
66
+ : 'var(--colors-light-text-text-accent)', style: { cursor: disabled ? 'not-allowed' : 'pointer' } }), _jsx(Typography, { text: 'or drag and drop', size: TypographySize.TextS, weight: TypographyWeight.Regular, color: disabled
67
+ ? 'var(--colors-light-text-text-subtle)'
68
+ : 'var(--colors-light-text-text-paragraph)' }), _jsxs(Box, { display: 'flex', flexDirection: 'row', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', children: [_jsx(FilePdf, { ...iconProps }), _jsx(FileDoc, { ...iconProps }), _jsx(FileTxt, { ...iconProps })] })] })] }));
69
+ };
@@ -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;
@@ -0,0 +1,51 @@
1
+ import { FileUpload } from './FileUpload';
2
+ const meta = {
3
+ title: 'Design System/Components/Form/FileUpload',
4
+ component: FileUpload,
5
+ parameters: {
6
+ layout: 'centered',
7
+ design: {
8
+ type: 'figspec',
9
+ url: 'https://www.figma.com/design/mIhjz2yJjcpLlIqw6oUivt/Beyond-Presence?node-id=4793-22751&t=rqtBB1YFgMFiNXZa-1',
10
+ },
11
+ },
12
+ tags: ['autodocs'],
13
+ argTypes: {
14
+ disabled: {
15
+ control: 'boolean',
16
+ defaultValue: false,
17
+ description: 'Whether the file upload is disabled',
18
+ table: { type: { summary: 'boolean' } },
19
+ },
20
+ acceptedFileTypes: {
21
+ control: 'text',
22
+ description: 'Accepted file types',
23
+ table: { type: { summary: 'string' } },
24
+ },
25
+ maxFileSizeMB: {
26
+ control: 'number',
27
+ description: 'Max file size in MB',
28
+ table: { type: { summary: 'number' } },
29
+ },
30
+ onFileSelect: {
31
+ description: 'Callback function when a file is selected',
32
+ table: { type: { summary: 'function' } },
33
+ },
34
+ sx: {
35
+ control: 'object',
36
+ description: 'Style of the file upload',
37
+ table: { type: { summary: 'SxProps' } },
38
+ },
39
+ },
40
+ };
41
+ export default meta;
42
+ export const Default = {
43
+ args: {
44
+ disabled: false,
45
+ },
46
+ };
47
+ export const Disabled = {
48
+ args: {
49
+ disabled: true,
50
+ },
51
+ };
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+ import { FileUploadingProps } from '../types';
3
+ export declare const FileUploading: FC<FileUploadingProps>;
@@ -0,0 +1,45 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Fragment } from 'react';
3
+ import { FileUploadingStatus } from '../types';
4
+ import { Box } from '@mui/material';
5
+ import { Typography, TypographySize, TypographyWeight } from '../../Typography';
6
+ import { getIconComponent } from '../../../utils';
7
+ import { ProgressIndicator, ProgressIndicatorMode } from '../../UI';
8
+ export const FileUploading = ({ uploadProgress, uploadingStatus, sx, onCancel, onRetry, fileName, showCancel, showRetry, }) => {
9
+ const isUploading = uploadingStatus === FileUploadingStatus.Uploading;
10
+ const isSuccess = uploadingStatus === FileUploadingStatus.Success;
11
+ const isError = uploadingStatus === FileUploadingStatus.Error;
12
+ const fileExtension = fileName.split('.').pop();
13
+ const getFileIcon = () => {
14
+ if (fileExtension?.toLowerCase() === 'pdf')
15
+ return 'FilePdf';
16
+ if (fileExtension?.toLowerCase().includes('doc'))
17
+ return 'FileDoc';
18
+ if (fileExtension?.toLowerCase() === 'txt')
19
+ return 'FileTxt';
20
+ return 'File';
21
+ };
22
+ return (_jsxs(Box, { display: 'flex', flexDirection: 'column', justifyContent: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', paddingX: 'var(--spacing-tokens-size-in-px-spacing-spacing-xl)', paddingY: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', border: `1px solid ${isError ? 'var(--colors-light-border-border-error)' : 'var(--colors-light-border-border-component)'}`, bgcolor: 'var(--colors-light-background-bg-component-contrast-subtle)', minWidth: '300px', sx: { ...sx }, children: [_jsxs(Box, { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', children: [_jsxs(Box, { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', children: [getIconComponent(getFileIcon(), {
23
+ width: '24px',
24
+ height: '24px',
25
+ color: isError
26
+ ? 'var(--colors-light-text-text-error)'
27
+ : 'var(--colors-light-foreground-fg-primary)',
28
+ }), _jsx(Typography, { text: fileName, size: TypographySize.TextM, weight: TypographyWeight.Regular, color: isError
29
+ ? 'var(--colors-light-text-text-error)'
30
+ : 'var(--primitives-desktop-primary-gray-950)' })] }), _jsxs(Box, { display: 'flex', flexDirection: 'row', alignItems: 'center', paddingY: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', children: [showCancel &&
31
+ onCancel &&
32
+ isUploading &&
33
+ getIconComponent('X', {
34
+ width: '24px',
35
+ height: '24px',
36
+ color: 'var(--colors-light-text-text-title)',
37
+ onClick: onCancel,
38
+ style: { cursor: 'pointer' },
39
+ }), isSuccess &&
40
+ getIconComponent('Check', {
41
+ width: '24px',
42
+ height: '24px',
43
+ color: 'var(--colors-light-foreground-fg-success)',
44
+ })] })] }), _jsxs(Box, { display: 'flex', flexDirection: 'row', justifyContent: 'flex-start', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', children: [!isError && uploadProgress && (_jsx(ProgressIndicator, { currentValue: uploadProgress, maxValue: 100, mode: ProgressIndicatorMode.Percentage, style: { width: '100%' } })), isError && (_jsxs(Fragment, { children: [_jsx(Typography, { text: 'Upload failed, please try again.', size: TypographySize.TextXS, weight: TypographyWeight.Regular, color: 'var(--colors-light-text-text-error)', style: { lineHeight: '16px' } }), showRetry && onRetry && (_jsx(Box, { onClick: onRetry, style: { cursor: 'pointer' }, children: _jsx(Typography, { text: 'Try again', size: TypographySize.TextXS, weight: TypographyWeight.SemiBold, color: 'var(--colors-light-text-text-error)', style: { lineHeight: '16px' } }) }))] }))] })] }));
45
+ };
@@ -0,0 +1,8 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { FileUploading } from './FileUploading';
3
+ declare const meta: Meta<typeof FileUploading>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof FileUploading>;
6
+ export declare const Default: Story;
7
+ export declare const Success: Story;
8
+ export declare const Error: Story;
@@ -0,0 +1,86 @@
1
+ import { FileUploading } from './FileUploading';
2
+ import { FileUploadingStatus } from '../types';
3
+ const meta = {
4
+ title: 'Design System/Components/Form/FileUploading',
5
+ component: FileUploading,
6
+ parameters: {
7
+ layout: 'centered',
8
+ design: {
9
+ type: 'figspec',
10
+ url: 'https://www.figma.com/design/mIhjz2yJjcpLlIqw6oUivt/Beyond-Presence?node-id=4793-22751&t=rqtBB1YFgMFiNXZa-1',
11
+ },
12
+ },
13
+ tags: ['autodocs'],
14
+ argTypes: {
15
+ fileName: {
16
+ control: 'text',
17
+ description: 'The name of the file',
18
+ table: { type: { summary: 'string' } },
19
+ },
20
+ uploadingStatus: {
21
+ control: 'select',
22
+ options: Object.values(FileUploadingStatus),
23
+ defaultValue: FileUploadingStatus.Uploading,
24
+ description: 'The status of the file upload',
25
+ table: { type: { summary: 'FileUploadingStatus' } },
26
+ },
27
+ uploadProgress: {
28
+ control: 'number',
29
+ description: 'The progress of the file upload',
30
+ table: { type: { summary: 'number' } },
31
+ },
32
+ showCancel: {
33
+ control: 'boolean',
34
+ description: 'Whether to show the cancel button',
35
+ table: { type: { summary: 'boolean' } },
36
+ },
37
+ onCancel: {
38
+ action: 'clicked',
39
+ description: 'Callback function when the cancel button is clicked',
40
+ table: { type: { summary: 'function' } },
41
+ },
42
+ showRetry: {
43
+ control: 'boolean',
44
+ description: 'Whether to show the retry button',
45
+ table: { type: { summary: 'boolean' } },
46
+ },
47
+ onRetry: {
48
+ action: 'clicked',
49
+ description: 'Callback function when the retry button is clicked',
50
+ table: { type: { summary: 'function' } },
51
+ },
52
+ sx: {
53
+ control: 'object',
54
+ description: 'Style of the file upload',
55
+ table: { type: { summary: 'SxProps' } },
56
+ },
57
+ },
58
+ };
59
+ export default meta;
60
+ export const Default = {
61
+ args: {
62
+ fileName: 'test.pdf',
63
+ uploadingStatus: FileUploadingStatus.Uploading,
64
+ uploadProgress: 50,
65
+ showCancel: true,
66
+ showRetry: true,
67
+ },
68
+ };
69
+ export const Success = {
70
+ args: {
71
+ fileName: 'test.pdf',
72
+ uploadingStatus: FileUploadingStatus.Success,
73
+ uploadProgress: 100,
74
+ showCancel: true,
75
+ showRetry: true,
76
+ },
77
+ };
78
+ export const Error = {
79
+ args: {
80
+ fileName: 'test.pdf',
81
+ uploadingStatus: FileUploadingStatus.Error,
82
+ uploadProgress: 100,
83
+ showCancel: true,
84
+ showRetry: true,
85
+ },
86
+ };
@@ -0,0 +1,3 @@
1
+ import { FC } from 'react';
2
+ import { UploadedFileProps } from '../types';
3
+ export declare const UploadedFile: FC<UploadedFileProps>;
@@ -0,0 +1,12 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { FileType } from '../types';
3
+ import { Box } from '@mui/material';
4
+ import { File } from '@phosphor-icons/react';
5
+ import { Typography, TypographySize, TypographyWeight } from '../../Typography';
6
+ import { ButtonDisplayMode, ButtonHierarchy, ButtonSize, MainButton, } from '../../Buttons';
7
+ export const UploadedFile = ({ type = FileType.Default, showDelete = true, onDelete, showDownload = true, onDownload, fileName, sx, }) => {
8
+ const isSampleFile = type === FileType.Sample;
9
+ return (_jsxs(Box, { display: 'flex', flexDirection: 'row', alignItems: 'center', justifyContent: 'space-between', borderRadius: 'var(--spacing-tokens-size-in-px-spacing-spacing-xs)', padding: 'var(--spacing-tokens-size-in-px-spacing-spacing-sm)', paddingLeft: 'var(--spacing-tokens-size-in-px-spacing-spacing-lg)', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', bgcolor: isSampleFile
10
+ ? 'var(--colors-light-background-bg-card-highlight)'
11
+ : 'var(--colors-light-background-bg-component-contrast-subtle)', minWidth: '240px', minHeight: '36px', sx: { ...sx }, children: [_jsxs(Box, { display: 'flex', flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', children: [_jsx(File, { width: '24px', height: '24px', color: 'var(--colors-light-foreground-fg-primary)' }), _jsx(Typography, { text: fileName, size: TypographySize.TextM, weight: TypographyWeight.Medium, color: 'var(--colors-light-foreground-fg-primary)' })] }), _jsxs(Box, { display: 'flex', flexDirection: 'row', gap: 'var(--spacing-tokens-size-in-px-spacing-spacing-md)', children: [showDownload && onDownload && (_jsx(MainButton, { hierarchy: ButtonHierarchy.Secondary, size: ButtonSize.xs, displayIconMode: ButtonDisplayMode.Only, displayIcon: "DownloadSimple", onClick: onDownload })), showDelete && onDelete && (_jsx(MainButton, { hierarchy: ButtonHierarchy.Secondary, size: ButtonSize.xs, displayIconMode: ButtonDisplayMode.Only, displayIcon: "X", onClick: onDelete }))] })] }));
12
+ };
@@ -0,0 +1,7 @@
1
+ import type { Meta, StoryObj } from '@storybook/react';
2
+ import { UploadedFile } from './UploadedFile';
3
+ declare const meta: Meta<typeof UploadedFile>;
4
+ export default meta;
5
+ type Story = StoryObj<typeof UploadedFile>;
6
+ export declare const Default: Story;
7
+ export declare const Sample: Story;
@@ -0,0 +1,73 @@
1
+ import { UploadedFile } from './UploadedFile';
2
+ import { FileType } from '../types';
3
+ const meta = {
4
+ title: 'Design System/Components/Form/UploadedFile',
5
+ component: UploadedFile,
6
+ parameters: {
7
+ layout: 'centered',
8
+ design: {
9
+ type: 'figspec',
10
+ url: 'https://www.figma.com/design/mIhjz2yJjcpLlIqw6oUivt/Beyond-Presence?node-id=4793-22751&t=rqtBB1YFgMFiNXZa-1',
11
+ },
12
+ },
13
+ tags: ['autodocs'],
14
+ argTypes: {
15
+ fileName: {
16
+ control: 'text',
17
+ description: 'The name of the file',
18
+ table: { type: { summary: 'string' } },
19
+ },
20
+ type: {
21
+ control: 'select',
22
+ options: Object.values(FileType),
23
+ description: 'The type of the file',
24
+ table: { type: { summary: 'string' } },
25
+ },
26
+ showDelete: {
27
+ control: 'boolean',
28
+ description: 'Whether to show the delete button',
29
+ table: { type: { summary: 'boolean' } },
30
+ },
31
+ showDownload: {
32
+ control: 'boolean',
33
+ description: 'Whether to show the download button',
34
+ table: { type: { summary: 'boolean' } },
35
+ },
36
+ onDelete: {
37
+ action: 'onDelete',
38
+ description: 'Callback function when the delete button is clicked',
39
+ table: { type: { summary: 'function' } },
40
+ },
41
+ onDownload: {
42
+ action: 'onDownload',
43
+ description: 'Callback function when the download button is clicked',
44
+ table: { type: { summary: 'function' } },
45
+ },
46
+ sx: {
47
+ control: 'object',
48
+ description: 'Style of the uploaded file',
49
+ table: { type: { summary: 'SxProps' } },
50
+ },
51
+ },
52
+ };
53
+ export default meta;
54
+ export const Default = {
55
+ args: {
56
+ fileName: 'example.pdf',
57
+ type: FileType.Default,
58
+ showDelete: true,
59
+ showDownload: true,
60
+ onDelete: () => { },
61
+ onDownload: () => { },
62
+ },
63
+ };
64
+ export const Sample = {
65
+ args: {
66
+ fileName: 'sample.txt',
67
+ type: FileType.Sample,
68
+ showDelete: false,
69
+ showDownload: false,
70
+ onDelete: () => { },
71
+ onDownload: () => { },
72
+ },
73
+ };
@@ -0,0 +1,3 @@
1
+ export * from './FileUpload';
2
+ export * from './FileUploading';
3
+ export * from './UploadedFile';
@@ -0,0 +1,3 @@
1
+ export * from './FileUpload';
2
+ export * from './FileUploading';
3
+ export * from './UploadedFile';
@@ -48,7 +48,6 @@ const IOSSwitch = styled((props) => (_jsx(Switch, { focusVisibleClassName: ".Mui
48
48
  duration: 500,
49
49
  }),
50
50
  '&:hover': {
51
- border: '1px solid red',
52
51
  backgroundColor: 'var(--primitives-desktop-primary-gray-200)',
53
52
  },
54
53
  },
@@ -2,4 +2,5 @@ export * from './Checkbox';
2
2
  export * from './Toggle';
3
3
  export * from './TextArea';
4
4
  export * from './TextInput';
5
+ export * from './FileUpload';
5
6
  export * from './types';
@@ -2,4 +2,5 @@ export * from './Checkbox';
2
2
  export * from './Toggle';
3
3
  export * from './TextArea';
4
4
  export * from './TextInput';
5
+ export * from './FileUpload';
5
6
  export * from './types';
@@ -92,3 +92,67 @@ export type CheckboxProps = {
92
92
  /** Event handler for the checkbox */
93
93
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
94
94
  };
95
+ export interface FileUploadProps {
96
+ /** Whether the file upload is disabled */
97
+ disabled?: boolean;
98
+ /** Accepted file types */
99
+ acceptedFileTypes?: string;
100
+ /** Max file size in MB */
101
+ maxFileSizeMB?: number;
102
+ /** Callback function when a file is selected */
103
+ onFileSelect?: (file: File) => void;
104
+ /** Style of the file upload */
105
+ sx?: SxProps<Theme>;
106
+ }
107
+ /**
108
+ * File type variants
109
+ */
110
+ export declare enum FileType {
111
+ Sample = "Sample",
112
+ Default = "Default"
113
+ }
114
+ export interface UploadedFileProps {
115
+ /** Type of the uploaded file */
116
+ type: FileType;
117
+ /** File name */
118
+ fileName: string;
119
+ /** Whether to show the delete button */
120
+ showDelete?: boolean;
121
+ /** Callback function when the delete button is clicked */
122
+ onDelete?: () => void;
123
+ /** Whether to show the download button */
124
+ showDownload?: boolean;
125
+ /** Callback function when the download button is clicked */
126
+ onDownload?: () => void;
127
+ /** Style of the uploaded file */
128
+ sx?: SxProps<Theme>;
129
+ }
130
+ /**
131
+ * File uploading status variants
132
+ */
133
+ export declare enum FileUploadingStatus {
134
+ Uploading = "Uploading",
135
+ Success = "Success",
136
+ Error = "Error"
137
+ }
138
+ /**
139
+ * File uploading component props
140
+ */
141
+ export interface FileUploadingProps {
142
+ /** Status of the file uploading */
143
+ uploadingStatus: FileUploadingStatus;
144
+ /** Progress of the file uploading */
145
+ uploadProgress: number | null;
146
+ /** Style of the file uploading */
147
+ sx?: SxProps<Theme>;
148
+ /** Whether to show the cancel button */
149
+ showCancel?: boolean;
150
+ /** Callback function when the cancel button is clicked */
151
+ onCancel?: () => void;
152
+ /** Whether to show the retry button */
153
+ showRetry?: boolean;
154
+ /** Callback function when the retry button is clicked */
155
+ onRetry?: () => void;
156
+ /** File name */
157
+ fileName: string;
158
+ }
@@ -11,3 +11,20 @@ export var CheckboxType;
11
11
  CheckboxType["Radio"] = "Radio";
12
12
  CheckboxType["Checkbox"] = "Checkbox";
13
13
  })(CheckboxType || (CheckboxType = {}));
14
+ /**
15
+ * File type variants
16
+ */
17
+ export var FileType;
18
+ (function (FileType) {
19
+ FileType["Sample"] = "Sample";
20
+ FileType["Default"] = "Default";
21
+ })(FileType || (FileType = {}));
22
+ /**
23
+ * File uploading status variants
24
+ */
25
+ export var FileUploadingStatus;
26
+ (function (FileUploadingStatus) {
27
+ FileUploadingStatus["Uploading"] = "Uploading";
28
+ FileUploadingStatus["Success"] = "Success";
29
+ FileUploadingStatus["Error"] = "Error";
30
+ })(FileUploadingStatus || (FileUploadingStatus = {}));
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@beydesign/storybook",
3
3
  "private": false,
4
- "version": "0.0.41",
4
+ "version": "0.0.43",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
7
7
  "module": "dist/index.js",