Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] feat: TET-895 File Uploader component #139

Closed
wants to merge 9 commits into from
33 changes: 33 additions & 0 deletions src/components/FileItem/FileItem.props.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { MouseEvent } from 'react';

import { FileItemConfig } from './FileItem.styles';
import { FileItemState, FileItemThumbnail } from './types';

export type FileItemProps = {
custom?: FileItemConfig;
file: File;
state?: FileItemState;
isInverted?: boolean;
isExtended?: boolean;
thumbnail?: FileItemThumbnail;
uploadedPercentage?: number;
timeLeftText?: string;
alertText?: string;
onReplaceClick?: (e?: MouseEvent) => void;
onRetryClick?: (e?: MouseEvent) => void;
onCloseClick?: (e?: MouseEvent) => void;
};

export type Fallback = {
state: FileItemState;
isInverted: boolean;
isExtended: boolean;
thumbnail: FileItemThumbnail;
};

export const fallback: Fallback = {
state: 'uploading',
isInverted: false,
isExtended: false,
thumbnail: 'none',
};
170 changes: 170 additions & 0 deletions src/components/FileItem/FileItem.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,170 @@
import { action } from '@storybook/addon-actions';
import type { Meta, StoryObj } from '@storybook/react';

import { FileItem } from './FileItem';
import { mockTextFile, mockImageFile } from './mocks';

import { FileItemDocs } from '@/docs-components/FileItemDocs';
import { TetDocs } from '@/docs-components/TetDocs';

const meta = {
title: 'FileItem',
component: FileItem,
tags: ['autodocs'],
argTypes: {},
args: {
file: mockTextFile(),
state: 'uploaded',
isInverted: false,
isExtended: false,
thumbnail: 'none',
uploadedPercentage: 25,
timeLeftText: '7 seconds left',
alertText: 'Short alert text',
onReplaceClick: action('onReplaceClick'),
onRetryClick: action('onRetryClick'),
onCloseClick: action('onCloseClick'),
},
parameters: {
docs: {
description: {
component:
'Enable users to upload specific files, such as images, documents, or videos, to a particular location. The user can perform this action by dragging and dropping files into the designated area or browsing local storage.',
},
page: () => (
<TetDocs docs="https://docs.tetrisly.com/components/in-progress/fileuploader">
<FileItemDocs />
</TetDocs>
),
},
},
} satisfies Meta<typeof FileItem>;

export default meta;
type Story = StoryObj<typeof meta>;

export const Default: Story = {
args: {
file: mockTextFile(),
state: 'uploaded',
isExtended: false,
thumbnail: 'none',
onCloseClick: action('onCloseClick'),
},
};

export const Uploading: Story = {
args: {
file: mockTextFile(),
state: 'uploading',
uploadedPercentage: 25,
onCloseClick: action('onCloseClick'),
},
};

export const Uploaded: Story = {
args: {
file: mockTextFile(),
state: 'uploaded',
onCloseClick: action('onCloseClick'),
},
};

export const Replaceable: Story = {
args: {
file: mockTextFile(),
state: 'replaceable',
onReplaceClick: action('onReplaceClick'),
onCloseClick: action('onCloseClick'),
},
};

export const Alert: Story = {
args: {
file: mockTextFile(),
state: 'alert',
alertText: 'Short alert text',
onRetryClick: action('onRetryClick'),
onCloseClick: action('onCloseClick'),
},
};

export const ExtendedUploading: Story = {
args: {
file: mockTextFile(),
state: 'uploading',
isExtended: true,
uploadedPercentage: 25,
timeLeftText: '7 seconds left',
onCloseClick: action('onCloseClick'),
},
};

export const ExtendedUploaded: Story = {
args: {
file: mockTextFile(),
state: 'uploaded',
isExtended: true,
onCloseClick: action('onCloseClick'),
},
};

export const ExtendedReplaceable: Story = {
args: {
file: mockTextFile(),
state: 'replaceable',
isExtended: true,
onReplaceClick: action('onReplaceClick'),
onCloseClick: action('onCloseClick'),
},
};

export const ExtendedAlert: Story = {
args: {
file: mockTextFile(),
state: 'alert',
isExtended: true,
alertText: 'Short alert text',
onRetryClick: action('onRetryClick'),
onCloseClick: action('onCloseClick'),
},
};

export const ExtendedUploadingFile: Story = {
args: {
file: mockTextFile(),
state: 'uploading',
isExtended: true,
thumbnail: 'file',
uploadedPercentage: 25,
timeLeftText: '7 seconds left',
onCloseClick: action('onCloseClick'),
},
};

export const ExtendedAlertImage: Story = {
args: {
file: mockImageFile(),
state: 'alert',
isExtended: true,
thumbnail: 'photo',
alertText: 'Short alert text',
onReplaceClick: action('onReplaceClick'),
onRetryClick: action('onRetryClick'),
onCloseClick: action('onCloseClick'),
},
};

export const ExtendedInvertedAlertImage: Story = {
args: {
file: mockImageFile(),
state: 'alert',
isExtended: true,
isInverted: true,
thumbnail: 'photo',
alertText: 'Short alert text',
onReplaceClick: action('onReplaceClick'),
onRetryClick: action('onRetryClick'),
onCloseClick: action('onCloseClick'),
},
};
65 changes: 65 additions & 0 deletions src/components/FileItem/FileItem.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { compressedVariantStyles, extendedVariantStyles } from './components';
import { FileItemThumbnail } from './types';

import type { BaseProps } from '@/types/BaseProps';

export type FileItemConfig = BaseProps & {
state?: {
uploading?: BaseProps;
uploaded?: BaseProps;
replaceable?: BaseProps;
alert?: BaseProps;
};
inverted?: {
yes?: BaseProps;
no?: BaseProps;
};
thumbnail?: Record<FileItemThumbnail, BaseProps>;
invertedAlert?: BaseProps;
compressed?: BaseProps;
extended?: BaseProps;
};

export const defaultConfig = {
display: 'flex',
flexDirection: 'column',
gap: '$space-component-gap-small',
borderRadius: '$border-radius-large',
state: {
uploading: {
backgroundColor: '$color-interaction-neutral-subtle-normal',
},
uploaded: {
backgroundColor: '$color-interaction-default-subtle-normal',
},
replaceable: {
backgroundColor: '$color-interaction-default-subtle-normal',
},
alert: {
backgroundColor: '$color-interaction-alert-subtle-normal',
},
},
inverted: {
yes: {
backgroundColor: '$color-interaction-background-formField',
borderWidth: '$border-width-100',
borderStyle: '$border-style-solid',
borderColor: '$color-interaction-border-neutral-normal',
},
no: {},
},
thumbnail: {
none: {},
file: {},
photo: {},
},
invertedAlert: {
borderColor: '$color-interaction-border-alert',
},
compressed: compressedVariantStyles.defaultConfig,
extended: extendedVariantStyles.defaultConfig,
} as const satisfies FileItemConfig;

export const fileItemStyles = {
defaultConfig,
};
Loading
Loading