Skip to content

Commit

Permalink
feat(file-upload-item): обновлен внешний вид (#902)
Browse files Browse the repository at this point in the history
* feat(file-upload-item): update design

* feat(icon-button): add download attribute

* feat(file-upload-item): design review fixes
  • Loading branch information
dmitrsavk committed Dec 9, 2021
1 parent 4b32bf3 commit d0f7d1e
Show file tree
Hide file tree
Showing 16 changed files with 189 additions and 85 deletions.
10 changes: 6 additions & 4 deletions packages/file-upload-item/src/Component.test.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { fireEvent, render } from '@testing-library/react';

import { FileUploadItem, FileStatuses } from './index';
import { FileUploadItem, FileStatuses } from '.';

export const fileProps = {
name: 'Довольно длинное название файла.pdf',
Expand Down Expand Up @@ -77,14 +77,16 @@ describe('FileUploadItem', () => {
expect(cb.mock.calls[0][0]).toBe(fileId);
});

it('should call `onRestore` prop', () => {
it('should call `onDownload` prop', async() => {
const cb = jest.fn();
const fileId = 'id';
const { getByText } = render(
const { baseElement } = render(
<FileUploadItem {...fileProps} downloadLink='/link' onDownload={cb} id={fileId} />,
);

fireEvent.click(getByText(fileProps.name));
const downloadButton = baseElement.querySelector('a') as HTMLAnchorElement;

fireEvent.click(downloadButton);

expect(cb).toBeCalledTimes(1);
expect(cb.mock.calls[0][0]).toBe(fileId);
Expand Down
62 changes: 38 additions & 24 deletions packages/file-upload-item/src/Component.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ import { Spinner } from '@alfalab/core-components-spinner';
import { CrossMIcon } from '@alfalab/icons-glyph/CrossMIcon';
import { CheckmarkCircleMIcon } from '@alfalab/icons-glyph/CheckmarkCircleMIcon';
import { AlertCircleMIcon } from '@alfalab/icons-glyph/AlertCircleMIcon';
import { PointerDownMIcon } from '@alfalab/icons-glyph/PointerDownMIcon';
import { ClockMIcon } from '@alfalab/icons-glyph';

import { fileIcon, humanFileSize } from './utils';

Expand Down Expand Up @@ -41,7 +43,7 @@ export type FileUploadItemProps = {
uploadDate?: string;

/**
* Ссылка на файл. Если прокидывается этот параметр, то заголовок становится ссылкой
* Ссылка на файл. Если прокидывается этот параметр, то появляется кнопка скачивания
*/
downloadLink?: string;

Expand Down Expand Up @@ -146,41 +148,45 @@ export const FileUploadItem: React.FC<FileUploadItemProps> = ({
}, [id, onRestore]);

const renderIcon = useCallback(() => {
if (showRestore) {
return <ClockMIcon className={styles.restoreIcon} />;
}

switch (uploadStatus) {
case 'ERROR':
return <AlertCircleMIcon className={styles.errorIcon} />;
case 'SUCCESS':
return <CheckmarkCircleMIcon className={styles.successIcon} />;
case 'LOADING':
case 'UPLOADING':
return <Spinner visible={true} />;
return (
<div className={styles.spinnerWrapper}>
<Spinner visible={true} className={styles.spinner} />
</div>
);
default: {
return <Icon className={styles.icon} />;
}
}
}, [uploadStatus]);
}, [showRestore, uploadStatus]);

const renderName = useCallback(
const renderInfoSection = useCallback(
() => (
<div className={styles.name}>
{downloadLink ? (
<Link
pseudo={true}
href={downloadLink}
onClick={handleDownload}
download={download}
>
{name}
</Link>
) : (
name
<div className={styles.infoSection}>
<div className={styles.name}>{name}</div>

{uploadStatus === 'ERROR' && error && (
<div className={styles.errorWrapper} role='alert'>
{error}
</div>
)}
</div>
),
[downloadLink, handleDownload, download, name],
[name, uploadStatus, error],
);

const showMeta = !showRestore && (!uploadStatus || uploadStatus === 'SUCCESS');
const showDownload = Boolean(downloadLink) && !showRestore;

return (
<div
Expand All @@ -194,16 +200,12 @@ export const FileUploadItem: React.FC<FileUploadItemProps> = ({
<div className={styles.info}>
{renderIcon()}

{renderName()}
{renderInfoSection()}

{children}

{uploadStatus === 'UPLOADING' && <span>{`${Math.round(uploadPercent)}%`}</span>}

{uploadStatus === 'ERROR' && (
<span className={styles.error} role='alert'>
{error}
</span>
{uploadStatus === 'UPLOADING' && (
<span className={styles.uploadPercent}>{`${Math.round(uploadPercent)}%`}</span>
)}

{showMeta && (
Expand All @@ -225,6 +227,18 @@ export const FileUploadItem: React.FC<FileUploadItemProps> = ({
</Link>
)}

{showDownload && (
<IconButton
size='xxs'
icon={PointerDownMIcon}
className={styles.download}
aria-label='скачать'
href={downloadLink}
onClick={handleDownload}
download={download}
/>
)}

{showDelete && !showRestore && (
<IconButton
size='xxs'
Expand Down
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
88 changes: 66 additions & 22 deletions packages/file-upload-item/src/__snapshots__/Component.test.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,13 @@ Object {
/>
</svg>
<div
class="name"
class="infoSection"
>
<a
class="component primary pseudo"
download="новое_название_файла"
href="/link"
<div
class="name"
>
<span
class="text"
>
Довольно длинное название файла.pdf
</span>
</a>
Довольно длинное название файла.pdf
</div>
</div>
<div
class="meta"
Expand All @@ -54,6 +48,34 @@ Object {
</span>
</div>
</div>
<a
aria-label="скачать"
class="component ghost s component ghost iconOnly download primary"
download="новое_название_файла"
href="/link"
>
<span
class="addons"
>
<span
class="iconWrapper xxs"
>
<svg
class="icon"
fill="currentColor"
focusable="false"
height="24"
role="img"
viewBox="0 0 24 24"
width="24"
>
<path
d="M16.444 9.935L13 13.305V3h-2v10.304L7.556 9.935l-1.399 1.43L12 17.08l5.843-5.715-1.399-1.43zM20 21v-2H4v2h16z"
/>
</svg>
</span>
</span>
</a>
<button
aria-label="удалить"
class="component ghost s component ghost iconOnly delete primary"
Expand Down Expand Up @@ -107,19 +129,13 @@ Object {
/>
</svg>
<div
class="name"
class="infoSection"
>
<a
class="component primary pseudo"
download="новое_название_файла"
href="/link"
<div
class="name"
>
<span
class="text"
>
Довольно длинное название файла.pdf
</span>
</a>
Довольно длинное название файла.pdf
</div>
</div>
<div
class="meta"
Expand All @@ -134,6 +150,34 @@ Object {
</span>
</div>
</div>
<a
aria-label="скачать"
class="component ghost s component ghost iconOnly download primary"
download="новое_название_файла"
href="/link"
>
<span
class="addons"
>
<span
class="iconWrapper xxs"
>
<svg
class="icon"
fill="currentColor"
focusable="false"
height="24"
role="img"
viewBox="0 0 24 24"
width="24"
>
<path
d="M16.444 9.935L13 13.305V3h-2v10.304L7.556 9.935l-1.399 1.43L12 17.08l5.843-5.715-1.399-1.43zM20 21v-2H4v2h16z"
/>
</svg>
</span>
</span>
</a>
<button
aria-label="удалить"
class="component ghost s component ghost iconOnly delete primary"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { setupScreenshotTesting, generateTestCases } from '../../screenshot-utils';

const clip = { x: 0, y: 0, width: 540, height: 50 };
const clip = { x: 0, y: 0, width: 1920, height: 150 };

const screenshotTesting = setupScreenshotTesting({
it,
Expand Down
13 changes: 11 additions & 2 deletions packages/file-upload-item/src/docs/description.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,11 @@
showDelete={true}
/>
<FileUploadItem
name='Название файла.pdf'
name='С кастомной иконкой.pdf'
uploadDate='22.01.2018'
size={50000000}
showDelete={true}
icon={StarLineMIcon}
/>
<FileUploadItem
name='Название файла.txt'
Expand Down Expand Up @@ -56,7 +57,15 @@
uploadDate='22.01.2018'
size={450000000}
uploadStatus='ERROR'
error='размер больше 20 МБ'
error={
<>
<p style={{ margin: 0, marginBottom: '8px' }}>Размер больше 500 Кб</p>
<p style={{ margin: 0 }}>
Недопустимый формат файла. Загрузите файл в одном из этих форматов: .txt, .xml,
.csv
</p>
</>
}
showDelete={false}
/>
</>
Expand Down

0 comments on commit d0f7d1e

Please sign in to comment.