@visns-studio/visns-components 5.14.11 → 5.14.13
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.
- package/package.json +5 -5
- package/src/components/DataGrid.jsx +51 -0
- package/src/components/Field.jsx +15 -0
- package/src/components/Form.jsx +57 -8
- package/src/components/generic/GenericReport.jsx +1437 -589
- package/src/components/generic/StandardModal.jsx +62 -12
- package/src/components/styles/Field.module.scss +144 -48
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React from 'react';
|
|
1
|
+
import React, { useState, useEffect } from 'react';
|
|
2
2
|
import Popup from 'reactjs-popup';
|
|
3
3
|
import { X } from 'lucide-react';
|
|
4
4
|
import formStyles from '../styles/Form.module.scss';
|
|
@@ -33,6 +33,40 @@ const StandardModal = ({
|
|
|
33
33
|
showHeader = false,
|
|
34
34
|
customStyles = {}
|
|
35
35
|
}) => {
|
|
36
|
+
// Device detection state
|
|
37
|
+
const [windowWidth, setWindowWidth] = useState(typeof window !== 'undefined' ? window.innerWidth : 1024);
|
|
38
|
+
|
|
39
|
+
// Device detection utility
|
|
40
|
+
const getDeviceType = () => {
|
|
41
|
+
const hasTouch = typeof window !== 'undefined' && ('ontouchstart' in window || navigator.maxTouchPoints > 0);
|
|
42
|
+
const userAgent = typeof window !== 'undefined' ? navigator.userAgent : '';
|
|
43
|
+
|
|
44
|
+
// Mobile detection: width + user agent + touch
|
|
45
|
+
const isMobileUA = /Android|webOS|iPhone|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
|
|
46
|
+
const isMobileWidth = windowWidth <= 768;
|
|
47
|
+
const isMobile = isMobileUA || (isMobileWidth && hasTouch);
|
|
48
|
+
|
|
49
|
+
// Tablet detection: iPad or Android tablets or medium width with touch
|
|
50
|
+
const isTabletUA = /iPad|Android(?!.*Mobile)/i.test(userAgent);
|
|
51
|
+
const isTabletWidth = windowWidth > 768 && windowWidth <= 1024;
|
|
52
|
+
const isTablet = isTabletUA || (isTabletWidth && hasTouch && !isMobile);
|
|
53
|
+
|
|
54
|
+
return { isMobile, isTablet, isDesktop: !isMobile && !isTablet };
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
const { isMobile, isTablet } = getDeviceType();
|
|
58
|
+
|
|
59
|
+
// Handle window resize
|
|
60
|
+
useEffect(() => {
|
|
61
|
+
if (typeof window === 'undefined') return;
|
|
62
|
+
|
|
63
|
+
const handleResize = () => {
|
|
64
|
+
setWindowWidth(window.innerWidth);
|
|
65
|
+
};
|
|
66
|
+
|
|
67
|
+
window.addEventListener('resize', handleResize);
|
|
68
|
+
return () => window.removeEventListener('resize', handleResize);
|
|
69
|
+
}, []);
|
|
36
70
|
// Apply vertical alignment class if needed
|
|
37
71
|
const getModalClasses = () => {
|
|
38
72
|
let classes = formStyles.modal;
|
|
@@ -42,36 +76,52 @@ const StandardModal = ({
|
|
|
42
76
|
return classes;
|
|
43
77
|
};
|
|
44
78
|
|
|
45
|
-
// Get size-based styles for the popup content
|
|
79
|
+
// Get size-based styles for the popup content with device-aware positioning
|
|
46
80
|
const getContentStyle = () => {
|
|
47
81
|
const baseStyle = {
|
|
48
82
|
...customStyles.modal
|
|
49
83
|
};
|
|
50
84
|
|
|
51
|
-
//
|
|
85
|
+
// Device-specific positioning for virtual keyboard accommodation
|
|
86
|
+
let positioningStyle = {};
|
|
87
|
+
if (isMobile || isTablet) {
|
|
88
|
+
// Position modal higher on mobile/tablet to accommodate virtual keyboard
|
|
89
|
+
positioningStyle = {
|
|
90
|
+
top: '5%', // Position higher (5% from top)
|
|
91
|
+
left: '50%', // Center horizontally
|
|
92
|
+
transform: 'translateX(-50%)', // Only center horizontally, no vertical transform
|
|
93
|
+
maxHeight: '85vh', // Limit height to prevent overflow
|
|
94
|
+
overflowY: 'auto', // Allow scrolling within modal if needed
|
|
95
|
+
position: 'fixed' // Ensure fixed positioning for proper centering
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
// Apply size-based styles with device considerations
|
|
52
100
|
switch (size) {
|
|
53
101
|
case 'small':
|
|
54
102
|
return {
|
|
55
103
|
...baseStyle,
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
104
|
+
...positioningStyle,
|
|
105
|
+
width: isMobile ? '95vw' : '400px',
|
|
106
|
+
minWidth: isMobile ? '300px' : '400px',
|
|
107
|
+
maxWidth: isMobile ? '95vw' : '600px'
|
|
59
108
|
};
|
|
60
109
|
case 'large':
|
|
61
110
|
return {
|
|
62
111
|
...baseStyle,
|
|
112
|
+
...positioningStyle,
|
|
63
113
|
width: '95vw',
|
|
64
|
-
minWidth: '800px',
|
|
65
|
-
maxWidth: '1600px'
|
|
114
|
+
minWidth: isMobile ? '300px' : '800px',
|
|
115
|
+
maxWidth: isMobile ? '95vw' : '1600px'
|
|
66
116
|
};
|
|
67
117
|
case 'medium':
|
|
68
118
|
default:
|
|
69
|
-
// Use the same dimensions as modalWide class (original modal sizing)
|
|
70
119
|
return {
|
|
71
120
|
...baseStyle,
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
121
|
+
...positioningStyle,
|
|
122
|
+
width: isMobile ? '95vw' : '90vw',
|
|
123
|
+
minWidth: isMobile ? '300px' : '600px',
|
|
124
|
+
maxWidth: isMobile ? '95vw' : '1400px'
|
|
75
125
|
};
|
|
76
126
|
}
|
|
77
127
|
};
|
|
@@ -845,66 +845,146 @@ input[type='file']:hover {
|
|
|
845
845
|
.file-upload-container {
|
|
846
846
|
display: flex;
|
|
847
847
|
flex-direction: column;
|
|
848
|
-
gap:
|
|
848
|
+
gap: 1em;
|
|
849
849
|
width: 100%;
|
|
850
|
+
border: 2px dashed var(--border-color, #ddd);
|
|
851
|
+
border-radius: var(--br, 8px);
|
|
852
|
+
padding: 1.5em;
|
|
853
|
+
background: var(--tertiary-color, #fafafa);
|
|
854
|
+
transition: all 0.3s ease;
|
|
855
|
+
position: relative;
|
|
850
856
|
}
|
|
851
857
|
|
|
858
|
+
/* Removed hover effect on main container */
|
|
859
|
+
|
|
852
860
|
.file-upload-container input[type='file'] {
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
861
|
+
position: absolute;
|
|
862
|
+
width: 0.1px;
|
|
863
|
+
height: 0.1px;
|
|
864
|
+
opacity: 0;
|
|
865
|
+
overflow: hidden;
|
|
866
|
+
z-index: -1;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
.file-upload-button-wrapper {
|
|
870
|
+
display: flex;
|
|
871
|
+
flex-direction: column;
|
|
872
|
+
align-items: center;
|
|
873
|
+
gap: 0.5em;
|
|
874
|
+
padding: 1em;
|
|
875
|
+
border: 2px dashed transparent;
|
|
876
|
+
border-radius: var(--br, 6px);
|
|
877
|
+
cursor: pointer;
|
|
878
|
+
transition: all 0.3s ease;
|
|
879
|
+
}
|
|
880
|
+
|
|
881
|
+
/* Removed hover effect on button wrapper */
|
|
882
|
+
|
|
883
|
+
.file-upload-button {
|
|
884
|
+
display: inline-flex;
|
|
885
|
+
align-items: center;
|
|
886
|
+
gap: 0.5em;
|
|
887
|
+
padding: 0.75em 1.5em;
|
|
888
|
+
background: var(--primary-color, #007bff);
|
|
889
|
+
color: #ffffff;
|
|
890
|
+
border: none;
|
|
891
|
+
border-radius: var(--br, 6px);
|
|
892
|
+
font-weight: 500;
|
|
893
|
+
font-size: 0.9em;
|
|
894
|
+
cursor: pointer;
|
|
895
|
+
transition: all 0.3s ease;
|
|
896
|
+
box-shadow: 0 2px 4px rgba(var(--primary-color-rgb, 0, 123, 255), 0.2);
|
|
897
|
+
}
|
|
898
|
+
|
|
899
|
+
.file-upload-button:hover {
|
|
900
|
+
background: rgba(var(--primary-color-rgb, 0, 123, 255), 0.9);
|
|
901
|
+
color: #ffffff;
|
|
902
|
+
transform: translateY(-1px);
|
|
903
|
+
box-shadow: 0 4px 8px rgba(var(--primary-color-rgb, 0, 123, 255), 0.3);
|
|
904
|
+
}
|
|
905
|
+
|
|
906
|
+
.file-upload-help-text {
|
|
907
|
+
font-size: 0.85em;
|
|
908
|
+
color: var(--muted-text-color, #6c757d);
|
|
909
|
+
text-align: center;
|
|
910
|
+
margin-top: 0.5em;
|
|
858
911
|
}
|
|
859
912
|
|
|
860
913
|
.file-list {
|
|
861
914
|
width: 100%;
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
background: var(--tertiary-color);
|
|
865
|
-
max-height: 200px;
|
|
915
|
+
background: transparent;
|
|
916
|
+
max-height: 220px;
|
|
866
917
|
overflow-y: auto;
|
|
867
|
-
padding: 0
|
|
918
|
+
padding: 0;
|
|
919
|
+
margin-top: 0.75em;
|
|
920
|
+
display: flex;
|
|
921
|
+
flex-direction: column;
|
|
922
|
+
gap: 0.3em;
|
|
868
923
|
}
|
|
869
924
|
|
|
870
925
|
.file-list li {
|
|
871
926
|
display: flex;
|
|
872
927
|
justify-content: space-between;
|
|
873
928
|
align-items: center;
|
|
874
|
-
padding: 0.75em
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
transition:
|
|
880
|
-
|
|
929
|
+
padding: 0.5em 0.75em;
|
|
930
|
+
background: var(--item-color, #fff);
|
|
931
|
+
border: 1px solid var(--border-color, #e0e6ed);
|
|
932
|
+
border-radius: var(--br, 6px);
|
|
933
|
+
font-size: 0.8rem;
|
|
934
|
+
transition: all 0.2s ease;
|
|
935
|
+
min-height: 36px;
|
|
936
|
+
box-shadow: 0 1px 2px rgba(0, 0, 0, 0.04);
|
|
937
|
+
position: relative;
|
|
938
|
+
overflow: hidden;
|
|
881
939
|
}
|
|
882
940
|
|
|
883
|
-
.file-list li:
|
|
884
|
-
border-
|
|
941
|
+
.file-list li:hover {
|
|
942
|
+
border-color: var(--primary-color, #007bff);
|
|
943
|
+
box-shadow: 0 2px 8px rgba(var(--primary-color-rgb, 0, 123, 255), 0.15);
|
|
944
|
+
transform: translateY(-1px);
|
|
885
945
|
}
|
|
886
946
|
|
|
887
|
-
.file-list li:hover {
|
|
888
|
-
background: rgba(var(--
|
|
947
|
+
.file-list li:hover .file-icon {
|
|
948
|
+
background: rgba(var(--primary-color-rgb, 0, 123, 255), 0.15);
|
|
949
|
+
border-color: rgba(var(--primary-color-rgb, 0, 123, 255), 0.3);
|
|
950
|
+
transform: scale(1.05);
|
|
951
|
+
}
|
|
952
|
+
|
|
953
|
+
.file-list li:hover .file-image-preview {
|
|
954
|
+
transform: scale(1.05);
|
|
955
|
+
}
|
|
956
|
+
|
|
957
|
+
.file-list li:hover .file-name {
|
|
958
|
+
color: var(--primary-color, #007bff);
|
|
889
959
|
}
|
|
890
960
|
|
|
891
961
|
.trash-button {
|
|
892
|
-
background:
|
|
893
|
-
border:
|
|
962
|
+
background: rgba(var(--danger-color-rgb, 220, 53, 69), 0.08);
|
|
963
|
+
border: 1px solid rgba(var(--danger-color-rgb, 220, 53, 69), 0.2);
|
|
894
964
|
cursor: pointer;
|
|
895
|
-
color: var(--
|
|
965
|
+
color: var(--danger-color, #dc3545);
|
|
896
966
|
display: flex;
|
|
897
967
|
align-items: center;
|
|
898
|
-
|
|
968
|
+
justify-content: center;
|
|
969
|
+
padding: 0.35em;
|
|
970
|
+
border-radius: 4px;
|
|
971
|
+
transition: all 0.2s ease;
|
|
972
|
+
min-width: 28px;
|
|
973
|
+
height: 28px;
|
|
974
|
+
flex-shrink: 0;
|
|
899
975
|
}
|
|
900
976
|
|
|
901
977
|
.trash-button:hover {
|
|
902
|
-
|
|
978
|
+
background: var(--danger-color, #dc3545);
|
|
979
|
+
color: var(--secondary-color, #fff);
|
|
980
|
+
border-color: var(--danger-color, #dc3545);
|
|
981
|
+
transform: translateY(-1px);
|
|
982
|
+
box-shadow: 0 2px 4px rgba(var(--danger-color-rgb, 220, 53, 69), 0.3);
|
|
903
983
|
}
|
|
904
984
|
|
|
905
985
|
.trash-button svg {
|
|
906
|
-
width:
|
|
907
|
-
height:
|
|
986
|
+
width: 0.9em;
|
|
987
|
+
height: 0.9em;
|
|
908
988
|
}
|
|
909
989
|
|
|
910
990
|
/* Enhanced File Upload Styling */
|
|
@@ -1034,15 +1114,16 @@ input[type='file']:hover {
|
|
|
1034
1114
|
.file-list-item-image {
|
|
1035
1115
|
display: flex;
|
|
1036
1116
|
align-items: center;
|
|
1037
|
-
gap: 0.
|
|
1038
|
-
padding: 0.75em
|
|
1039
|
-
border-bottom: 1px solid var(--border-color,
|
|
1040
|
-
font-size: 0.
|
|
1041
|
-
background:
|
|
1042
|
-
border-radius:
|
|
1043
|
-
transition: all 0.
|
|
1044
|
-
margin-bottom: 0.
|
|
1117
|
+
gap: 0.5em;
|
|
1118
|
+
padding: 0.5em 0.75em;
|
|
1119
|
+
border-bottom: 1px solid rgba(var(--border-color-rgb, 224, 230, 237), 0.3);
|
|
1120
|
+
font-size: 0.85rem;
|
|
1121
|
+
background: transparent;
|
|
1122
|
+
border-radius: 4px;
|
|
1123
|
+
transition: all 0.2s ease;
|
|
1124
|
+
margin-bottom: 0.25em;
|
|
1045
1125
|
border: 1px solid transparent;
|
|
1126
|
+
min-height: 36px;
|
|
1046
1127
|
}
|
|
1047
1128
|
|
|
1048
1129
|
.file-list-item-image {
|
|
@@ -1063,23 +1144,37 @@ input[type='file']:hover {
|
|
|
1063
1144
|
border-color: var(--success-color, #28a745);
|
|
1064
1145
|
}
|
|
1065
1146
|
|
|
1147
|
+
/* Enhanced image file styling */
|
|
1148
|
+
.file-list-item-image .file-icon,
|
|
1149
|
+
.file-list-item-image .file-image-preview {
|
|
1150
|
+
background: rgba(var(--success-color-rgb, 40, 167, 69), 0.12) !important;
|
|
1151
|
+
border-color: rgba(var(--success-color-rgb, 40, 167, 69), 0.3) !important;
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1066
1154
|
.file-icon {
|
|
1067
|
-
font-size: 1.
|
|
1155
|
+
font-size: 1.1em;
|
|
1068
1156
|
display: flex;
|
|
1069
1157
|
align-items: center;
|
|
1070
1158
|
justify-content: center;
|
|
1071
|
-
width:
|
|
1072
|
-
height:
|
|
1159
|
+
width: 1.8em;
|
|
1160
|
+
height: 1.8em;
|
|
1073
1161
|
flex-shrink: 0;
|
|
1162
|
+
background: rgba(var(--primary-color-rgb, 0, 123, 255), 0.08);
|
|
1163
|
+
border-radius: 4px;
|
|
1164
|
+
border: 1px solid rgba(var(--primary-color-rgb, 0, 123, 255), 0.15);
|
|
1165
|
+
transition: all 0.2s ease;
|
|
1074
1166
|
}
|
|
1075
1167
|
|
|
1076
1168
|
.file-name {
|
|
1077
1169
|
flex: 1;
|
|
1078
|
-
color: var(--paragraph-color, #
|
|
1170
|
+
color: var(--paragraph-color, #2c3e50);
|
|
1079
1171
|
font-weight: 500;
|
|
1080
1172
|
overflow: hidden;
|
|
1081
1173
|
text-overflow: ellipsis;
|
|
1082
1174
|
white-space: nowrap;
|
|
1175
|
+
margin-left: 0.75em;
|
|
1176
|
+
font-size: 0.85em;
|
|
1177
|
+
line-height: 1.3;
|
|
1083
1178
|
}
|
|
1084
1179
|
|
|
1085
1180
|
/* Image Preview Styling */
|
|
@@ -1123,21 +1218,22 @@ input[type='file']:hover {
|
|
|
1123
1218
|
display: flex;
|
|
1124
1219
|
align-items: center;
|
|
1125
1220
|
justify-content: center;
|
|
1126
|
-
width:
|
|
1127
|
-
height:
|
|
1221
|
+
width: 1.8em;
|
|
1222
|
+
height: 1.8em;
|
|
1128
1223
|
flex-shrink: 0;
|
|
1129
|
-
background: rgba(var(--
|
|
1130
|
-
border: 1px solid var(--
|
|
1131
|
-
border-radius:
|
|
1224
|
+
background: rgba(var(--success-color-rgb, 40, 167, 69), 0.08);
|
|
1225
|
+
border: 1px solid rgba(var(--success-color-rgb, 40, 167, 69), 0.2);
|
|
1226
|
+
border-radius: 4px;
|
|
1132
1227
|
overflow: hidden;
|
|
1228
|
+
transition: all 0.2s ease;
|
|
1133
1229
|
}
|
|
1134
1230
|
|
|
1135
1231
|
.file-thumbnail {
|
|
1136
1232
|
width: 100%;
|
|
1137
1233
|
height: 100%;
|
|
1138
1234
|
object-fit: cover;
|
|
1139
|
-
border-radius:
|
|
1140
|
-
transition: transform 0.
|
|
1235
|
+
border-radius: 3px;
|
|
1236
|
+
transition: transform 0.2s ease;
|
|
1141
1237
|
}
|
|
1142
1238
|
|
|
1143
1239
|
.file-thumbnail:hover {
|