@topconsultnpm/sdkui-react-beta 6.16.89 → 6.16.90

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.
@@ -845,5 +845,5 @@ const TMDcmtPreviewWrapper = ({ currentDcmt, layoutMode, fromDTD, dcmtFile, devi
845
845
  const isMobile = deviceType === DeviceType.MOBILE;
846
846
  return (layoutMode === LayoutModes.Update ?
847
847
  _jsx(TMDcmtPreview, { isVisible: isVisible, onClosePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, allowMaximize: !isMobile && countVisibleLeafPanels() > 1, onMaximizePanel: (!isMobile && countVisibleLeafPanels() > 1) ? () => toggleMaximize("tmDcmtPreview") : undefined, dcmtData: currentDcmt, isResizingActive: isResizingActive }) :
848
- _jsx(TMFileUploader, { onFileUpload: onFileUpload, onClose: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive }));
848
+ _jsx(TMFileUploader, { onFileUpload: onFileUpload, onClose: (!isMobile && countVisibleLeafPanels() > 1) ? () => setPanelVisibilityById('tmDcmtPreview', false) : undefined, isRequired: fromDTD?.archiveConstraint === ArchiveConstraints.ContentCompulsory && dcmtFile === null, defaultBlob: dcmtFile, deviceType: deviceType, isResizingActive: isResizingActive, enableDragDropOverlay: true }));
849
849
  };
@@ -0,0 +1,7 @@
1
+ interface TMDragDropOverlayProps {
2
+ uploadedFile: File | null;
3
+ handleFile: (file: File) => void;
4
+ refocusAfterFileInput: () => void;
5
+ }
6
+ declare const TMDragDropOverlay: (props: TMDragDropOverlayProps) => import("react/jsx-runtime").JSX.Element;
7
+ export default TMDragDropOverlay;
@@ -0,0 +1,99 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { useEffect, useState } from "react";
3
+ import Toppy from '../../../assets/Toppy-generico.png';
4
+ const TMDragDropOverlay = (props) => {
5
+ const { uploadedFile, handleFile, refocusAfterFileInput } = props;
6
+ const [dragOver, setDragOver] = useState(false);
7
+ useEffect(() => {
8
+ if (uploadedFile)
9
+ return;
10
+ const handleWindowDragEnter = (e) => {
11
+ e.preventDefault();
12
+ setDragOver(true);
13
+ };
14
+ const handleWindowDragOver = (e) => {
15
+ e.preventDefault();
16
+ };
17
+ const handleWindowDragLeave = (e) => {
18
+ e.preventDefault();
19
+ if (e.clientX === 0 && e.clientY === 0) {
20
+ setDragOver(false);
21
+ }
22
+ };
23
+ const handleWindowDrop = (e) => {
24
+ e.preventDefault();
25
+ setDragOver(false);
26
+ const file = e.dataTransfer?.files?.[0];
27
+ if (file)
28
+ handleFile(file);
29
+ refocusAfterFileInput();
30
+ };
31
+ window.addEventListener('dragenter', handleWindowDragEnter);
32
+ window.addEventListener('dragover', handleWindowDragOver);
33
+ window.addEventListener('dragleave', handleWindowDragLeave);
34
+ window.addEventListener('drop', handleWindowDrop);
35
+ return () => {
36
+ window.removeEventListener('dragenter', handleWindowDragEnter);
37
+ window.removeEventListener('dragover', handleWindowDragOver);
38
+ window.removeEventListener('dragleave', handleWindowDragLeave);
39
+ window.removeEventListener('drop', handleWindowDrop);
40
+ };
41
+ }, [uploadedFile, handleFile, refocusAfterFileInput]);
42
+ // Il div è sempre presente, ma visibile solo se dragOver e nessun file caricato
43
+ const isVisible = !uploadedFile && dragOver;
44
+ return (_jsxs("div", { style: {
45
+ display: 'flex',
46
+ opacity: isVisible ? 1 : 0,
47
+ pointerEvents: isVisible ? 'auto' : 'none',
48
+ position: 'fixed',
49
+ top: 0,
50
+ left: 0,
51
+ width: '100%',
52
+ height: '100%',
53
+ background: 'rgba(0,0,0,0.5)',
54
+ zIndex: 999999,
55
+ alignItems: 'center',
56
+ justifyContent: 'center',
57
+ color: '#fff',
58
+ fontSize: '1.8rem',
59
+ fontWeight: 700,
60
+ borderRadius: 12,
61
+ cursor: 'copy',
62
+ boxShadow: '0 8px 20px rgba(0,0,0,0.3)',
63
+ backdropFilter: 'blur(5px)',
64
+ transition: 'opacity 0.2s, transform 0.2s, background 0.2s',
65
+ }, onDragEnter: (e) => { e.preventDefault(); e.stopPropagation(); setDragOver(true); }, onDragOver: (e) => { e.preventDefault(); e.stopPropagation(); setDragOver(true); }, onDragLeave: (e) => {
66
+ e.preventDefault();
67
+ e.stopPropagation();
68
+ // Solo se il cursore ha lasciato il div principale
69
+ if (!e.currentTarget.contains(e.relatedTarget)) {
70
+ setDragOver(false);
71
+ }
72
+ }, onDrop: (e) => {
73
+ e.preventDefault();
74
+ e.stopPropagation();
75
+ const file = e.dataTransfer.files[0];
76
+ if (file)
77
+ handleFile(file);
78
+ refocusAfterFileInput();
79
+ setDragOver(false);
80
+ }, children: [_jsx("div", { onClick: () => {
81
+ setDragOver(false);
82
+ handleFile(null);
83
+ }, style: {
84
+ position: 'absolute',
85
+ top: 15,
86
+ right: 20,
87
+ cursor: 'pointer',
88
+ fontSize: '1.8rem',
89
+ fontWeight: 700,
90
+ color: '#fff',
91
+ }, children: _jsx("i", { className: 'dx-icon-close', style: { fontSize: 25 } }) }), _jsxs("div", { style: {
92
+ display: 'flex',
93
+ flexDirection: 'column',
94
+ alignItems: 'center',
95
+ gap: 20,
96
+ textAlign: 'center',
97
+ }, children: [_jsx("img", { src: Toppy, alt: "Toppy", style: { width: 80, height: 'auto' } }), _jsx("div", { style: { fontSize: '1.6rem' }, children: "Rilascia il tuo file qui" })] })] }));
98
+ };
99
+ export default TMDragDropOverlay;
@@ -8,6 +8,7 @@ interface ITMFileUploader {
8
8
  deviceType?: DeviceType;
9
9
  isResizingActive?: boolean;
10
10
  showTMPanel?: boolean;
11
+ enableDragDropOverlay?: boolean;
11
12
  }
12
13
  declare const TMFileUploader: React.FC<ITMFileUploader>;
13
14
  export default TMFileUploader;
@@ -10,7 +10,8 @@ import { DeviceType } from '../../base/TMDeviceProvider';
10
10
  import TMTooltip from '../../base/TMTooltip';
11
11
  import { TMFileViewer, StyledHeaderIcon } from './TMDcmtPreview';
12
12
  import TMPanel from '../../base/TMPanel';
13
- const TMFileUploader = ({ deviceType = DeviceType.DESKTOP, onClose, onFileUpload, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true }) => {
13
+ import TMDragDropOverlay from './TMDragDropOverlay';
14
+ const TMFileUploader = ({ deviceType = DeviceType.DESKTOP, onClose, onFileUpload, isRequired = false, defaultBlob = null, isResizingActive, showTMPanel = true, enableDragDropOverlay = false }) => {
14
15
  const [dragOver, setDragOver] = useState(false);
15
16
  const [uploadedFile, setUploadedFile] = useState(defaultBlob);
16
17
  const [fileName, setFileName] = useState('');
@@ -82,7 +83,7 @@ const TMFileUploader = ({ deviceType = DeviceType.DESKTOP, onClose, onFileUpload
82
83
  document.getElementById('fileInput')?.click();
83
84
  }, []);
84
85
  let content = !uploadedFile ?
85
- _jsx("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsx("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: _jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }) }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file qui o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] }) }) :
86
+ _jsxs("div", { style: { display: 'flex', gap: 10, width: '100%', height: '100%' }, children: [enableDragDropOverlay && _jsx(TMDragDropOverlay, { uploadedFile: uploadedFile, handleFile: handleFile, refocusAfterFileInput: refocusAfterFileInput }), _jsxs(UploadContainer, { ref: uploaderRef, tabIndex: 0, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleDrop, style: { backgroundColor: dragOver ? '#76b1e6' : 'white' }, onDoubleClick: browseHandler, "$isRequired": isRequired, children: [_jsx("div", { style: { display: 'flex', gap: '10px', flexDirection: 'column', position: 'absolute', right: 5, top: 5 }, children: _jsx(TMButton, { btnStyle: 'icon', caption: 'Sfoglia', color: isRequired && !uploadedFile ? 'error' : 'primary', onClick: browseHandler, icon: _jsx(IconFolderOpen, { fontSize: 22 }) }) }), _jsx("p", { style: { fontSize: '1.2rem', fontWeight: 'bold' }, children: deviceType === DeviceType.MOBILE ? 'Clicca per sfogliare il tuo file' : 'Trascina il tuo file qui o fai doppio click per sfogliarlo' }), isRequired && _jsxs("p", { style: { fontWeight: 'bold' }, children: [" ", SDKUI_Localizator.RequiredField, " "] })] })] }) :
86
87
  _jsxs("div", { style: { display: 'flex', flexDirection: 'column', gap: 10, width: '100%', height: '100%' }, children: [_jsxs("div", { style: { backgroundColor: 'white', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.primaryColor }, children: [_jsxs("div", { style: { display: 'flex', alignItems: 'center', gap: 5 }, children: [_jsx("p", { children: "File name:" }), _jsxs("div", { style: { fontWeight: 'bold' }, children: [fileName, " ", _jsxs("span", { children: [" ", ` (${formatBytes(fileSize)})`, " "] })] })] }), uploadedFile && _jsx(TMButton, { btnStyle: 'icon', color: 'error', caption: 'Pulisci', onClick: () => clearFile(true), icon: _jsx(IconClear, { fontSize: 22 }) })] }), extensionHandler(fileExt) === FileExtensionHandler.READY_TO_SHOW ? _jsx(TMFileViewer, { fileBlob: uploadedFile, isResizingActive: isResizingActive }) :
87
88
  _jsx("div", { style: { backgroundColor: '#f6dbdb', padding: '5px 10px', borderRadius: 8, display: 'flex', alignItems: 'center', justifyContent: 'space-between', color: TMColors.error }, children: _jsxs("div", { children: [" ", 'Anteprima non disponibile.', fileExt && _jsx("b", { children: ` (*.${fileExt})` })] }) })] });
88
89
  const innerContent = (_jsxs("div", { style: { width: '100%', height: '100%', padding: '2px', display: 'flex', flexDirection: 'column', gap: 10 }, children: [_jsx(HiddenInput, { id: "fileInput", type: "file", onChange: handleInputChange }), content] }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@topconsultnpm/sdkui-react-beta",
3
- "version": "6.16.89",
3
+ "version": "6.16.90",
4
4
  "description": "",
5
5
  "scripts": {
6
6
  "test": "echo \"Error: no test specified\" && exit 1",