@chayns-components/core
Version:
A set of beautiful React components for developing your own applications with chayns.
150 lines (149 loc) • 6.16 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = void 0;
var _react = _interopRequireWildcard(require("react"));
var _file = require("../../../utils/file");
var _Icon = _interopRequireDefault(require("../../icon/Icon"));
var _ContextMenu = _interopRequireDefault(require("../../context-menu/ContextMenu"));
var _ListItem = _interopRequireDefault(require("../../list/list-item/ListItem"));
var _FileItem = require("./FileItem.styles");
var _textstring = require("@chayns-components/textstring");
var _textStrings = _interopRequireDefault(require("../../../constants/textStrings"));
var _useKeyboardFocusHighlighting = require("../../../hooks/useKeyboardFocusHighlighting");
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function (e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, default: e }; if (null === e || "object" != typeof e && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (const t in e) "default" !== t && {}.hasOwnProperty.call(e, t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, t)) && (i.get || i.set) ? o(f, t, i) : f[t] = e[t]); return f; })(e, t); }
const FileItem = ({
mimeType,
onRemove,
size,
name,
id,
source,
shouldAllowDownload
}) => {
const canDownload = shouldAllowDownload && !!source;
const canRemove = typeof onRemove === 'function';
const shouldShowKeyboardHighlighting = (0, _useKeyboardFocusHighlighting.useKeyboardFocusHighlighting)(canRemove || !!canDownload);
const handleRemove = (0, _react.useCallback)(() => {
if (canRemove) {
onRemove(id);
}
}, [id, onRemove]);
const handleItemKeyDown = (0, _react.useCallback)(event => {
if (event.key === 'Delete') {
event.preventDefault();
handleRemove();
}
}, [handleRemove]);
const handleRemoveKeyDown = (0, _react.useCallback)(event => {
if (canRemove && (event.key === 'Enter' || event.key === ' ')) {
event.preventDefault();
event.stopPropagation();
handleRemove();
}
}, [handleRemove]);
const humanFileSize = (0, _react.useMemo)(() => {
if (typeof size === 'number') {
return (0, _file.getHumanSize)(size);
}
return undefined;
}, [size]);
const icon = (0, _react.useMemo)(() => (0, _file.getIconByMimeType)(mimeType), [mimeType]);
const handleDownload = (0, _react.useCallback)(() => {
if (!source) return;
if (source instanceof File) {
const url = URL.createObjectURL(source);
const a = document.createElement('a');
a.href = url;
a.download = name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
} else {
// Try fetching as blob to force download. If CORS blocks it,
// fall back to opening the URL directly.
fetch(source).then(res => {
if (!res.ok) throw new Error('fetch failed');
return res.blob();
}).then(blob => {
const url = URL.createObjectURL(blob);
const a = document.createElement('a');
a.href = url;
a.download = name;
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
URL.revokeObjectURL(url);
}).catch(() => {
// CORS or network error: fall back to direct link
const a = document.createElement('a');
a.href = source;
a.download = name;
a.rel = 'noopener noreferrer';
a.target = '_blank';
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
});
}
}, [name, source]);
const downloadText = (0, _textstring.useTextstringValue)({
textstring: (0, _textstring.ttsToITextString)(_textStrings.default.components.fileItem.download)
});
const removeText = (0, _textstring.useTextstringValue)({
textstring: (0, _textstring.ttsToITextString)(_textStrings.default.components.fileItem.remove)
});
const rightElement = (0, _react.useMemo)(() => {
if (!canDownload && !canRemove) return undefined;
// Both actions available → show as ContextMenu
if (canDownload && canRemove) {
const items = [{
icons: ['fa fa-download'],
key: 'download',
onClick: handleDownload,
text: downloadText
}, {
icons: ['fa fa-trash'],
key: 'remove',
onClick: () => onRemove(id),
text: removeText
}];
return /*#__PURE__*/_react.default.createElement(_ContextMenu.default, {
items: items
});
}
const handleClick = () => {
if (canRemove) {
onRemove(id);
return;
}
handleDownload();
};
const handleKeyDown = canRemove ? handleRemoveKeyDown : undefined;
const fileIcon = canRemove ? 'ts-wrong' : 'fa fa-download';
return /*#__PURE__*/_react.default.createElement(_FileItem.StyledFileItemIcon, {
onClick: handleClick,
onKeyDown: handleKeyDown,
role: "button",
tabIndex: 0
}, /*#__PURE__*/_react.default.createElement(_Icon.default, {
icons: [fileIcon]
}));
}, [canDownload, canRemove, downloadText, handleDownload, handleRemoveKeyDown, id, onRemove, removeText]);
return (0, _react.useMemo)(() => /*#__PURE__*/_react.default.createElement(_FileItem.StyledFileItem, null, /*#__PURE__*/_react.default.createElement(_FileItem.StyledFileItemKeyboardWrapper, {
onKeyDown: handleItemKeyDown,
tabIndex: -1
}, /*#__PURE__*/_react.default.createElement(_ListItem.default, {
title: name,
subtitle: humanFileSize,
icons: [icon],
rightElements: rightElement,
shouldEnableKeyboardHighlighting: shouldShowKeyboardHighlighting
}))), [handleItemKeyDown, humanFileSize, icon, name, rightElement, shouldShowKeyboardHighlighting]);
};
FileItem.displayName = 'FileList';
var _default = exports.default = FileItem;
//# sourceMappingURL=FileItem.js.map