@visns-studio/visns-components 5.6.0 → 5.6.1
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
CHANGED
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
85
85
|
},
|
|
86
86
|
"name": "@visns-studio/visns-components",
|
|
87
|
-
"version": "5.6.
|
|
87
|
+
"version": "5.6.1",
|
|
88
88
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
89
89
|
"main": "src/index.js",
|
|
90
90
|
"files": [
|
|
@@ -5,6 +5,18 @@ import Select, { createFilter } from 'react-select';
|
|
|
5
5
|
import CreatableSelect from 'react-select/creatable';
|
|
6
6
|
import styles from './styles/MultiSelect.module.scss';
|
|
7
7
|
|
|
8
|
+
// Helper function to detect if the device is a mobile/touch device
|
|
9
|
+
const isTouchDevice = () => {
|
|
10
|
+
// Check if window is defined (to avoid SSR issues)
|
|
11
|
+
if (typeof window === 'undefined') return false;
|
|
12
|
+
|
|
13
|
+
return (
|
|
14
|
+
'ontouchstart' in window ||
|
|
15
|
+
(navigator && navigator.maxTouchPoints > 0) ||
|
|
16
|
+
(navigator && navigator.msMaxTouchPoints > 0)
|
|
17
|
+
);
|
|
18
|
+
};
|
|
19
|
+
|
|
8
20
|
function MultiSelect({
|
|
9
21
|
className,
|
|
10
22
|
inputValue = [], // Default to an empty array
|
|
@@ -20,6 +32,15 @@ function MultiSelect({
|
|
|
20
32
|
const [selectOptions, setSelectOptions] = useState([]);
|
|
21
33
|
const [selectValue, setSelectValue] = useState([]);
|
|
22
34
|
const prevInputValueRef = useRef();
|
|
35
|
+
const [menuPlacement, setMenuPlacement] = useState('bottom');
|
|
36
|
+
|
|
37
|
+
// Detect if it's a touch device and set menu placement accordingly
|
|
38
|
+
// This helps prevent the dropdown from being hidden by the onscreen keyboard on mobile devices
|
|
39
|
+
useEffect(() => {
|
|
40
|
+
if (isTouchDevice()) {
|
|
41
|
+
setMenuPlacement('top'); // Open dropdown above the input on touch devices
|
|
42
|
+
}
|
|
43
|
+
}, []);
|
|
23
44
|
|
|
24
45
|
useEffect(() => {
|
|
25
46
|
const _options =
|
|
@@ -99,6 +120,24 @@ function MultiSelect({
|
|
|
99
120
|
|
|
100
121
|
const SelectComponent = isCreatable ? CreatableSelect : Select;
|
|
101
122
|
|
|
123
|
+
// Handle menu opening to ensure it's visible on mobile
|
|
124
|
+
const handleMenuOpen = () => {
|
|
125
|
+
if (isTouchDevice()) {
|
|
126
|
+
// Give a small delay for the menu to render
|
|
127
|
+
setTimeout(() => {
|
|
128
|
+
const menuElement = document.querySelector(
|
|
129
|
+
'.visns-select__menu'
|
|
130
|
+
);
|
|
131
|
+
if (menuElement) {
|
|
132
|
+
menuElement.scrollIntoView({
|
|
133
|
+
behavior: 'smooth',
|
|
134
|
+
block: 'nearest',
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}, 50);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
102
141
|
return (
|
|
103
142
|
<SelectComponent
|
|
104
143
|
closeMenuOnSelect={!multi || settings.limit === 1}
|
|
@@ -109,6 +148,8 @@ function MultiSelect({
|
|
|
109
148
|
components={{ SelectList }}
|
|
110
149
|
options={selectOptions}
|
|
111
150
|
menuPortalTarget={document.body}
|
|
151
|
+
menuPlacement={menuPlacement}
|
|
152
|
+
onMenuOpen={handleMenuOpen}
|
|
112
153
|
onChange={(inputValue, action) => {
|
|
113
154
|
// Special handling for limit=1: keep only the most recent selection
|
|
114
155
|
if (
|
|
@@ -135,6 +176,10 @@ function MultiSelect({
|
|
|
135
176
|
...provided,
|
|
136
177
|
zIndex: 99999,
|
|
137
178
|
}),
|
|
179
|
+
option: (base) => ({
|
|
180
|
+
...base,
|
|
181
|
+
padding: isTouchDevice() ? '12px 15px' : base.padding, // Larger padding for touch devices
|
|
182
|
+
}),
|
|
138
183
|
menuPortal: (base) => ({
|
|
139
184
|
...base,
|
|
140
185
|
zIndex: 99999,
|
|
@@ -144,7 +189,9 @@ function MultiSelect({
|
|
|
144
189
|
minHeight:
|
|
145
190
|
style && style.multi_select_height
|
|
146
191
|
? style.multi_select_height
|
|
147
|
-
:
|
|
192
|
+
: isTouchDevice()
|
|
193
|
+
? '44px'
|
|
194
|
+
: '50px', // Apple's recommended minimum touch target size
|
|
148
195
|
height: 'auto', // Allow height to grow with content
|
|
149
196
|
}),
|
|
150
197
|
valueContainer: (base) => ({
|
|
@@ -40,6 +40,17 @@
|
|
|
40
40
|
|
|
41
41
|
.navwrap {
|
|
42
42
|
flex: 1;
|
|
43
|
+
overflow-x: auto;
|
|
44
|
+
-webkit-overflow-scrolling: touch; /* For smooth scrolling on iOS */
|
|
45
|
+
|
|
46
|
+
/* Hide scrollbar for most browsers but keep functionality */
|
|
47
|
+
scrollbar-width: none; /* Firefox */
|
|
48
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
49
|
+
|
|
50
|
+
/* Hide scrollbar for Chrome/Safari/Opera */
|
|
51
|
+
&::-webkit-scrollbar {
|
|
52
|
+
display: none;
|
|
53
|
+
}
|
|
43
54
|
}
|
|
44
55
|
|
|
45
56
|
.app-nav {
|
|
@@ -51,6 +62,8 @@
|
|
|
51
62
|
list-style: none;
|
|
52
63
|
align-items: center;
|
|
53
64
|
padding: 0;
|
|
65
|
+
width: max-content; /* Ensure it takes the width of all items */
|
|
66
|
+
min-width: 100%; /* Start at 100% width */
|
|
54
67
|
|
|
55
68
|
.navDropdown {
|
|
56
69
|
border-radius: var(--br);
|
|
@@ -64,6 +77,7 @@
|
|
|
64
77
|
transition: all 0.15s cubic-bezier(0.25, 0.8, 0.25, 1);
|
|
65
78
|
box-sizing: border-box;
|
|
66
79
|
position: relative;
|
|
80
|
+
flex-shrink: 0; /* Prevent items from shrinking too much */
|
|
67
81
|
|
|
68
82
|
a,
|
|
69
83
|
span {
|
|
@@ -441,6 +455,15 @@
|
|
|
441
455
|
.navwrap {
|
|
442
456
|
width: 100%;
|
|
443
457
|
position: relative;
|
|
458
|
+
overflow-y: auto; /* Enable vertical scrolling */
|
|
459
|
+
max-height: calc(100vh - 50px); /* Subtract the logo height */
|
|
460
|
+
scrollbar-width: none; /* Firefox */
|
|
461
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
462
|
+
|
|
463
|
+
/* Hide scrollbar for Chrome/Safari/Opera */
|
|
464
|
+
&::-webkit-scrollbar {
|
|
465
|
+
display: none;
|
|
466
|
+
}
|
|
444
467
|
|
|
445
468
|
.app-nav {
|
|
446
469
|
width: 100%;
|
|
@@ -591,6 +614,15 @@
|
|
|
591
614
|
flex-wrap: nowrap;
|
|
592
615
|
justify-content: space-between;
|
|
593
616
|
align-items: center;
|
|
617
|
+
overflow-x: auto; /* Allow horizontal scrolling if needed */
|
|
618
|
+
-webkit-overflow-scrolling: touch;
|
|
619
|
+
scrollbar-width: none; /* Firefox */
|
|
620
|
+
-ms-overflow-style: none; /* IE and Edge */
|
|
621
|
+
|
|
622
|
+
/* Hide scrollbar for Chrome/Safari/Opera */
|
|
623
|
+
&::-webkit-scrollbar {
|
|
624
|
+
display: none;
|
|
625
|
+
}
|
|
594
626
|
}
|
|
595
627
|
|
|
596
628
|
.content-title {
|
|
@@ -644,6 +676,17 @@
|
|
|
644
676
|
}
|
|
645
677
|
|
|
646
678
|
@media (max-width: 1024px) {
|
|
679
|
+
.hwrap {
|
|
680
|
+
grid-template-columns: auto 1fr auto;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
.navwrap {
|
|
684
|
+
position: relative;
|
|
685
|
+
overflow-x: auto;
|
|
686
|
+
-webkit-overflow-scrolling: touch;
|
|
687
|
+
padding: 0;
|
|
688
|
+
/* No fade indicators - they don't work well with scrolling */
|
|
689
|
+
}
|
|
647
690
|
.app-container {
|
|
648
691
|
width: 100%;
|
|
649
692
|
min-height: 100vh;
|
|
@@ -914,6 +957,19 @@
|
|
|
914
957
|
}
|
|
915
958
|
|
|
916
959
|
@media (max-width: 960px) {
|
|
960
|
+
.hwrap {
|
|
961
|
+
grid-template-columns: auto 1fr auto;
|
|
962
|
+
gap: 0.5rem;
|
|
963
|
+
}
|
|
964
|
+
|
|
965
|
+
.navwrap {
|
|
966
|
+
margin: 0;
|
|
967
|
+
padding: 0;
|
|
968
|
+
}
|
|
969
|
+
|
|
970
|
+
.app-nav {
|
|
971
|
+
gap: 0.25rem; /* Reduce gap between items on smaller screens */
|
|
972
|
+
}
|
|
917
973
|
.userdetails {
|
|
918
974
|
display: none;
|
|
919
975
|
visibility: hidden;
|
|
@@ -953,6 +1009,13 @@
|
|
|
953
1009
|
flex-wrap: nowrap;
|
|
954
1010
|
align-content: center;
|
|
955
1011
|
width: 50%;
|
|
1012
|
+
min-width: 150px; /* Ensure minimum width on small screens */
|
|
1013
|
+
position: relative;
|
|
1014
|
+
|
|
1015
|
+
input {
|
|
1016
|
+
min-width: 0; /* Allow input to shrink below its content size */
|
|
1017
|
+
flex: 1; /* Take available space */
|
|
1018
|
+
}
|
|
956
1019
|
|
|
957
1020
|
button {
|
|
958
1021
|
width: max-content;
|
|
@@ -962,6 +1025,7 @@
|
|
|
962
1025
|
background: var(--primary-color);
|
|
963
1026
|
appearance: none;
|
|
964
1027
|
border-radius: var(--br);
|
|
1028
|
+
flex-shrink: 0; /* Prevent button from shrinking */
|
|
965
1029
|
|
|
966
1030
|
svg {
|
|
967
1031
|
display: block;
|
|
@@ -970,4 +1034,14 @@
|
|
|
970
1034
|
max-width: 20px;
|
|
971
1035
|
}
|
|
972
1036
|
}
|
|
1037
|
+
|
|
1038
|
+
@media (max-width: 768px) {
|
|
1039
|
+
width: auto; /* Allow to take natural width */
|
|
1040
|
+
flex: 1; /* Take available space */
|
|
1041
|
+
|
|
1042
|
+
button {
|
|
1043
|
+
margin: 0 0.25rem;
|
|
1044
|
+
padding: 0.15rem 0.35rem;
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
973
1047
|
}
|