mirror of
https://github.com/luxfi/explore.git
synced 2026-09-24 00:28:18 +00:00
76 lines
2.4 KiB
TypeScript
76 lines
2.4 KiB
TypeScript
import React from 'react';
|
|
|
|
import JsonFileIcon from 'icons/files/json.svg';
|
|
import PlaceholderFileIcon from 'icons/files/placeholder.svg';
|
|
import SolFileIcon from 'icons/files/sol.svg';
|
|
import YulFileIcon from 'icons/files/yul.svg';
|
|
|
|
import { CloseButton } from '@luxfi/ui/close-button';
|
|
import { Hint } from '../../../../components/Hint/Hint';
|
|
|
|
const FILE_ICONS: Record<string, React.ReactNode> = {
|
|
'.json': <JsonFileIcon/>,
|
|
'.sol': <SolFileIcon/>,
|
|
'.yul': <YulFileIcon/>,
|
|
};
|
|
|
|
function getFileExtension(fileName: string) {
|
|
const chunks = fileName.split('.');
|
|
if (chunks.length === 1) {
|
|
return '';
|
|
}
|
|
|
|
return '.' + chunks[chunks.length - 1];
|
|
}
|
|
|
|
interface Props {
|
|
file: File;
|
|
className?: string;
|
|
index?: number;
|
|
onRemove?: (index?: number) => void;
|
|
isDisabled?: boolean;
|
|
error?: string;
|
|
}
|
|
|
|
export const FileSnippet = ({ file, className, index, onRemove, isDisabled, error }: Props) => {
|
|
const handleRemove = React.useCallback((event: React.MouseEvent) => {
|
|
event.stopPropagation();
|
|
onRemove?.(index);
|
|
}, [ index, onRemove ]);
|
|
|
|
const fileExtension = getFileExtension(file.name);
|
|
const fileIcon = FILE_ICONS[fileExtension] || <PlaceholderFileIcon/>;
|
|
|
|
return (
|
|
<div
|
|
className={ [ 'flex max-w-[300px] overflow-hidden items-center text-left gap-x-2', className ].filter(Boolean).join(' ') }
|
|
>
|
|
<div className={ [ 'w-12 h-12 shrink-0', error ? 'text-[var(--color-text-error)]' : '' ].filter(Boolean).join(' ') }>
|
|
{ fileIcon }
|
|
</div>
|
|
<div className="max-w-[calc(100%-58px-24px)]">
|
|
<div className="flex items-center">
|
|
<span
|
|
className={ [
|
|
'font-semibold overflow-hidden text-ellipsis whitespace-nowrap',
|
|
error ? 'text-[var(--color-text-error)]' : '',
|
|
].filter(Boolean).join(' ') }
|
|
>
|
|
{ file.name }
|
|
</span>
|
|
{ Boolean(error) && <Hint label={ error } ml={ 1 } color="var(--color-text-error)"/> }
|
|
<CloseButton
|
|
aria-label="Remove"
|
|
className="ml-2"
|
|
onClick={ handleRemove }
|
|
disabled={ isDisabled }
|
|
/>
|
|
</div>
|
|
<span className="text-[var(--color-text-secondary)] text-sm mt-1 block">
|
|
{ file.size.toLocaleString(undefined, { notation: 'compact', maximumFractionDigits: 2, unit: 'byte', unitDisplay: 'narrow', style: 'unit' }) }
|
|
</span>
|
|
</div>
|
|
</div>
|
|
);
|
|
};
|