@visns-studio/visns-components 5.5.2 → 5.5.3
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
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"@nivo/line": "^0.88.0",
|
|
10
10
|
"@nivo/pie": "^0.88.0",
|
|
11
11
|
"@tinymce/tinymce-react": "^6.1.0",
|
|
12
|
-
"@vitejs/plugin-react": "^4.
|
|
12
|
+
"@vitejs/plugin-react": "^4.4.0",
|
|
13
13
|
"add": "^2.0.6",
|
|
14
14
|
"akar-icons": "^1.9.31",
|
|
15
15
|
"array-move": "^4.0.0",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"axios": "^1.8.4",
|
|
18
18
|
"browser-image-compression": "^2.0.2",
|
|
19
19
|
"dayjs": "^1.11.13",
|
|
20
|
-
"fabric": "^6.6.
|
|
20
|
+
"fabric": "^6.6.4",
|
|
21
21
|
"file-saver": "^2.0.5",
|
|
22
22
|
"framer-motion": "^11.18.2",
|
|
23
23
|
"html-react-parser": "^5.2.3",
|
|
@@ -54,12 +54,13 @@
|
|
|
54
54
|
"reactjs-popup": "^2.0.6",
|
|
55
55
|
"style-loader": "^4.0.0",
|
|
56
56
|
"swapy": "^1.0.5",
|
|
57
|
-
"sweetalert2": "^11.
|
|
57
|
+
"sweetalert2": "^11.19.1",
|
|
58
58
|
"truncate": "^3.0.0",
|
|
59
59
|
"uuid": "^10.0.0",
|
|
60
60
|
"validator": "^13.15.0",
|
|
61
61
|
"vite": "^5.4.18",
|
|
62
|
-
"yarn": "^1.22.22"
|
|
62
|
+
"yarn": "^1.22.22",
|
|
63
|
+
"yet-another-react-lightbox": "^3.22.0"
|
|
63
64
|
},
|
|
64
65
|
"devDependencies": {
|
|
65
66
|
"@babel/core": "^7.26.10",
|
|
@@ -81,7 +82,7 @@
|
|
|
81
82
|
"react-dom": "^17.0.0 || ^18.0.0"
|
|
82
83
|
},
|
|
83
84
|
"name": "@visns-studio/visns-components",
|
|
84
|
-
"version": "5.5.
|
|
85
|
+
"version": "5.5.3",
|
|
85
86
|
"description": "Various packages to assist in the development of our Custom Applications.",
|
|
86
87
|
"main": "src/index.js",
|
|
87
88
|
"files": [
|
|
@@ -16,6 +16,7 @@ import numeral from 'numeral';
|
|
|
16
16
|
import Popup from 'reactjs-popup';
|
|
17
17
|
import 'reactjs-popup/dist/index.css';
|
|
18
18
|
import parse from 'html-react-parser';
|
|
19
|
+
import 'react-toggle/style.css';
|
|
19
20
|
import { saveAs } from 'file-saver';
|
|
20
21
|
import NumberFilter from '@inovua/reactdatagrid-community/NumberFilter';
|
|
21
22
|
import SelectFilter from '@inovua/reactdatagrid-community/SelectFilter';
|
|
@@ -25,9 +26,12 @@ import ReactDataGrid from '@inovua/reactdatagrid-community';
|
|
|
25
26
|
// import SelectFilter from '@visns-studio/visns-datagrid-enterprise/SelectFilter';
|
|
26
27
|
// import DateFilter from '@visns-studio/visns-datagrid-enterprise/DateFilter';
|
|
27
28
|
// import ReactDataGrid from '@visns-studio/visns-datagrid-enterprise';
|
|
28
|
-
import { Gallery } from 'react-grid-gallery';
|
|
29
|
+
// import { Gallery } from 'react-grid-gallery';
|
|
29
30
|
import { confirmAlert } from 'react-confirm-alert';
|
|
30
31
|
import { toast } from 'react-toastify';
|
|
32
|
+
import imageCompression from 'browser-image-compression';
|
|
33
|
+
import Vapor from 'laravel-vapor';
|
|
34
|
+
import Lightbox from 'yet-another-react-lightbox';
|
|
31
35
|
import {
|
|
32
36
|
Alarm,
|
|
33
37
|
ArrowCounterClockwise,
|
|
@@ -59,6 +63,7 @@ import styles from './styles/DataGrid.module.scss';
|
|
|
59
63
|
|
|
60
64
|
import '@inovua/reactdatagrid-community/index.css';
|
|
61
65
|
import 'react-confirm-alert/src/react-confirm-alert.css';
|
|
66
|
+
import 'yet-another-react-lightbox/styles.css';
|
|
62
67
|
|
|
63
68
|
import CustomFetch from './Fetch';
|
|
64
69
|
import Download from './Download';
|
|
@@ -166,6 +171,13 @@ const DataGrid = forwardRef(
|
|
|
166
171
|
/** Gallery Modal States */
|
|
167
172
|
const [modalGalleryShow, setModalGalleryShow] = useState(false);
|
|
168
173
|
const [galleryData, setGalleryData] = useState([]);
|
|
174
|
+
const [uploadProgress, setUploadProgress] = useState(0);
|
|
175
|
+
const [currentItem, setCurrentItem] = useState(null);
|
|
176
|
+
const [isUploading, setIsUploading] = useState(false);
|
|
177
|
+
|
|
178
|
+
/** Lightbox States */
|
|
179
|
+
const [lightboxOpen, setLightboxOpen] = useState(false);
|
|
180
|
+
const [lightboxIndex, setLightboxIndex] = useState(0);
|
|
169
181
|
|
|
170
182
|
/** Gallery Modal Functions */
|
|
171
183
|
const modalGalleryOpen = () => {
|
|
@@ -176,6 +188,149 @@ const DataGrid = forwardRef(
|
|
|
176
188
|
setModalGalleryShow(false);
|
|
177
189
|
};
|
|
178
190
|
|
|
191
|
+
const handleFileUpload = async (files) => {
|
|
192
|
+
if (!currentItem || !currentItem.settings.upload) return;
|
|
193
|
+
|
|
194
|
+
setIsUploading(true);
|
|
195
|
+
const uploadPromises = [];
|
|
196
|
+
|
|
197
|
+
for (let i = 0; i < files.length; i++) {
|
|
198
|
+
const file = files[i];
|
|
199
|
+
|
|
200
|
+
try {
|
|
201
|
+
// Optimize image if needed
|
|
202
|
+
let optimizedFile = file;
|
|
203
|
+
if (file.type.startsWith('image/')) {
|
|
204
|
+
const options = {
|
|
205
|
+
maxSizeMB: 1,
|
|
206
|
+
maxWidthOrHeight: 1920,
|
|
207
|
+
useWebWorker: true,
|
|
208
|
+
};
|
|
209
|
+
try {
|
|
210
|
+
optimizedFile = await imageCompression(
|
|
211
|
+
file,
|
|
212
|
+
options
|
|
213
|
+
);
|
|
214
|
+
} catch (err) {
|
|
215
|
+
console.error('Image compression failed:', err);
|
|
216
|
+
// Continue with original file if compression fails
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
// Upload to Vapor
|
|
221
|
+
const uploadPromise = new Promise((resolve, reject) => {
|
|
222
|
+
Vapor.store(optimizedFile, {
|
|
223
|
+
progress: (progress) => {
|
|
224
|
+
setUploadProgress(progress * 100);
|
|
225
|
+
},
|
|
226
|
+
})
|
|
227
|
+
.then((response) => {
|
|
228
|
+
// Construct the URL with the key parameter
|
|
229
|
+
const uploadSettings =
|
|
230
|
+
currentItem.settings.upload;
|
|
231
|
+
const itemData = currentItem.data;
|
|
232
|
+
const keyValue = itemData[uploadSettings.key];
|
|
233
|
+
const url = keyValue
|
|
234
|
+
? `${uploadSettings.url}/${keyValue}`
|
|
235
|
+
: uploadSettings.url;
|
|
236
|
+
|
|
237
|
+
// Make the PUT request
|
|
238
|
+
CustomFetch(
|
|
239
|
+
url,
|
|
240
|
+
uploadSettings.method || 'POST',
|
|
241
|
+
{
|
|
242
|
+
uuid: response.uuid,
|
|
243
|
+
key: response.key,
|
|
244
|
+
bucket: response.bucket,
|
|
245
|
+
filename: file.name,
|
|
246
|
+
filesize: optimizedFile.size,
|
|
247
|
+
extension: response.extension,
|
|
248
|
+
file_relationship: uploadSettings.id,
|
|
249
|
+
},
|
|
250
|
+
(result) => {
|
|
251
|
+
if (result.error === '') {
|
|
252
|
+
resolve();
|
|
253
|
+
} else {
|
|
254
|
+
toast.error(String(result.error));
|
|
255
|
+
reject(result.error);
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
);
|
|
259
|
+
})
|
|
260
|
+
.catch(reject);
|
|
261
|
+
});
|
|
262
|
+
|
|
263
|
+
uploadPromises.push(uploadPromise);
|
|
264
|
+
} catch (error) {
|
|
265
|
+
console.error('Error uploading file:', error);
|
|
266
|
+
toast.error(
|
|
267
|
+
`Error uploading ${file.name}: ${
|
|
268
|
+
error.message || 'Unknown error'
|
|
269
|
+
}`
|
|
270
|
+
);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
await Promise.all(uploadPromises);
|
|
276
|
+
toast.success('Files uploaded successfully');
|
|
277
|
+
|
|
278
|
+
// Refresh the gallery data
|
|
279
|
+
if (currentItem && currentItem.settings && currentItem.data) {
|
|
280
|
+
const s = currentItem.settings;
|
|
281
|
+
const d = currentItem.data;
|
|
282
|
+
|
|
283
|
+
// Function to access nested property using a series of keys
|
|
284
|
+
const getNestedValue = (data, keys) =>
|
|
285
|
+
keys.reduce(
|
|
286
|
+
(currentValue, key) =>
|
|
287
|
+
currentValue && currentValue[key] !== undefined
|
|
288
|
+
? currentValue[key]
|
|
289
|
+
: undefined,
|
|
290
|
+
data
|
|
291
|
+
);
|
|
292
|
+
|
|
293
|
+
// Fetch updated data
|
|
294
|
+
try {
|
|
295
|
+
const res = await CustomFetch(
|
|
296
|
+
`${form.url}/${d[form.primaryKey]}`,
|
|
297
|
+
'GET',
|
|
298
|
+
{}
|
|
299
|
+
);
|
|
300
|
+
|
|
301
|
+
if (res.data) {
|
|
302
|
+
// Extract the updated nested value
|
|
303
|
+
const updatedNestedValue = getNestedValue(
|
|
304
|
+
res.data,
|
|
305
|
+
s.relation
|
|
306
|
+
);
|
|
307
|
+
|
|
308
|
+
// Update gallery data
|
|
309
|
+
if (
|
|
310
|
+
updatedNestedValue &&
|
|
311
|
+
Array.isArray(updatedNestedValue)
|
|
312
|
+
) {
|
|
313
|
+
const updatedGalleryArray =
|
|
314
|
+
updatedNestedValue.map((item) => ({
|
|
315
|
+
src: item[s.key],
|
|
316
|
+
caption: item.file_name,
|
|
317
|
+
}));
|
|
318
|
+
|
|
319
|
+
setGalleryData(updatedGalleryArray);
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
} catch (error) {
|
|
323
|
+
console.error('Error refreshing gallery data:', error);
|
|
324
|
+
}
|
|
325
|
+
}
|
|
326
|
+
} catch (error) {
|
|
327
|
+
console.error('Error in upload process:', error);
|
|
328
|
+
} finally {
|
|
329
|
+
setIsUploading(false);
|
|
330
|
+
setUploadProgress(0);
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
|
|
179
334
|
/** Modal States */
|
|
180
335
|
const [formData, setFormData] = useState({});
|
|
181
336
|
const [formType, setFormType] = useState('');
|
|
@@ -601,13 +756,16 @@ const DataGrid = forwardRef(
|
|
|
601
756
|
// Extracting nested value using predefined keys from 's.relation'
|
|
602
757
|
const nestedValue = getNestedValue(d, s.relation);
|
|
603
758
|
|
|
604
|
-
// Mapping nested values to create gallery array with source and
|
|
759
|
+
// Mapping nested values to create gallery array with source, captions, and dimensions
|
|
605
760
|
const galleryArray = nestedValue.map((item) => ({
|
|
606
761
|
src: item[s.key],
|
|
607
762
|
caption: item.file_name,
|
|
763
|
+
width: 320, // Default width for proper grid layout
|
|
764
|
+
height: 240, // Default height for proper grid layout
|
|
608
765
|
}));
|
|
609
766
|
|
|
610
767
|
setGalleryData(galleryArray);
|
|
768
|
+
setCurrentItem({ data: d, settings: s });
|
|
611
769
|
|
|
612
770
|
modalGalleryOpen();
|
|
613
771
|
break;
|
|
@@ -2461,11 +2619,9 @@ const DataGrid = forwardRef(
|
|
|
2461
2619
|
if (shouldRenderButton) {
|
|
2462
2620
|
return (
|
|
2463
2621
|
<button
|
|
2464
|
-
className={
|
|
2465
|
-
|
|
2466
|
-
|
|
2467
|
-
'0.2em 1em 0.05em 1em',
|
|
2468
|
-
}}
|
|
2622
|
+
className={
|
|
2623
|
+
styles.clockButton
|
|
2624
|
+
}
|
|
2469
2625
|
onClick={(e) => {
|
|
2470
2626
|
e.stopPropagation();
|
|
2471
2627
|
e.preventDefault();
|
|
@@ -2497,9 +2653,9 @@ const DataGrid = forwardRef(
|
|
|
2497
2653
|
data-tooltip-content={`${column.label} Timer`}
|
|
2498
2654
|
strokeWidth={2}
|
|
2499
2655
|
size={18}
|
|
2500
|
-
|
|
2501
|
-
|
|
2502
|
-
}
|
|
2656
|
+
style={{
|
|
2657
|
+
color: 'white',
|
|
2658
|
+
}}
|
|
2503
2659
|
/>
|
|
2504
2660
|
</button>
|
|
2505
2661
|
);
|
|
@@ -2983,6 +3139,8 @@ const DataGrid = forwardRef(
|
|
|
2983
3139
|
open={modalGalleryShow}
|
|
2984
3140
|
onClose={modalGalleryClose}
|
|
2985
3141
|
closeOnDocumentClick={false}
|
|
3142
|
+
contentStyle={{ width: 'auto', maxWidth: '90vw' }}
|
|
3143
|
+
overlayStyle={{ background: 'rgba(0, 0, 0, 0.7)' }}
|
|
2986
3144
|
>
|
|
2987
3145
|
<div
|
|
2988
3146
|
className={`${styles.modalwrap} ${styles['top--modal']}`}
|
|
@@ -2997,15 +3155,191 @@ const DataGrid = forwardRef(
|
|
|
2997
3155
|
<CircleX strokeWidth={1} size={24} />
|
|
2998
3156
|
</button>
|
|
2999
3157
|
</div>
|
|
3000
|
-
<div
|
|
3158
|
+
<div
|
|
3159
|
+
className={`${styles.modal__content} ${styles['modal__content--gallery']}`}
|
|
3160
|
+
>
|
|
3161
|
+
{currentItem?.settings?.upload && (
|
|
3162
|
+
<div className={styles.uploadSection}>
|
|
3163
|
+
<h3>
|
|
3164
|
+
<Image
|
|
3165
|
+
strokeWidth={1.5}
|
|
3166
|
+
size={18}
|
|
3167
|
+
/>
|
|
3168
|
+
Upload New Images
|
|
3169
|
+
</h3>
|
|
3170
|
+
<div
|
|
3171
|
+
className={styles.dropzoneContainer}
|
|
3172
|
+
>
|
|
3173
|
+
{isUploading && (
|
|
3174
|
+
<div
|
|
3175
|
+
className={
|
|
3176
|
+
styles.progressBar
|
|
3177
|
+
}
|
|
3178
|
+
>
|
|
3179
|
+
<div
|
|
3180
|
+
className={
|
|
3181
|
+
styles.progressBarInner
|
|
3182
|
+
}
|
|
3183
|
+
style={{
|
|
3184
|
+
width: `${uploadProgress}%`,
|
|
3185
|
+
}}
|
|
3186
|
+
></div>
|
|
3187
|
+
</div>
|
|
3188
|
+
)}
|
|
3189
|
+
<div
|
|
3190
|
+
className={styles.dropzone}
|
|
3191
|
+
onClick={() =>
|
|
3192
|
+
document
|
|
3193
|
+
.getElementById(
|
|
3194
|
+
'gallery-file-upload'
|
|
3195
|
+
)
|
|
3196
|
+
.click()
|
|
3197
|
+
}
|
|
3198
|
+
onDragOver={(e) => {
|
|
3199
|
+
e.preventDefault();
|
|
3200
|
+
e.stopPropagation();
|
|
3201
|
+
}}
|
|
3202
|
+
onDragEnter={(e) => {
|
|
3203
|
+
e.preventDefault();
|
|
3204
|
+
e.stopPropagation();
|
|
3205
|
+
}}
|
|
3206
|
+
onDragLeave={(e) => {
|
|
3207
|
+
e.preventDefault();
|
|
3208
|
+
e.stopPropagation();
|
|
3209
|
+
}}
|
|
3210
|
+
onDrop={(e) => {
|
|
3211
|
+
e.preventDefault();
|
|
3212
|
+
e.stopPropagation();
|
|
3213
|
+
const files =
|
|
3214
|
+
e.dataTransfer.files;
|
|
3215
|
+
if (files.length > 0) {
|
|
3216
|
+
handleFileUpload(files);
|
|
3217
|
+
}
|
|
3218
|
+
}}
|
|
3219
|
+
>
|
|
3220
|
+
<CloudUpload
|
|
3221
|
+
strokeWidth={1.5}
|
|
3222
|
+
size={24}
|
|
3223
|
+
/>
|
|
3224
|
+
<p>
|
|
3225
|
+
Drag and drop files here or
|
|
3226
|
+
click to select files
|
|
3227
|
+
</p>
|
|
3228
|
+
<input
|
|
3229
|
+
id="gallery-file-upload"
|
|
3230
|
+
type="file"
|
|
3231
|
+
multiple
|
|
3232
|
+
style={{ display: 'none' }}
|
|
3233
|
+
onChange={(e) => {
|
|
3234
|
+
if (
|
|
3235
|
+
e.target.files
|
|
3236
|
+
.length > 0
|
|
3237
|
+
) {
|
|
3238
|
+
handleFileUpload(
|
|
3239
|
+
e.target.files
|
|
3240
|
+
);
|
|
3241
|
+
e.target.value =
|
|
3242
|
+
null; // Reset input
|
|
3243
|
+
}
|
|
3244
|
+
}}
|
|
3245
|
+
accept="image/*"
|
|
3246
|
+
/>
|
|
3247
|
+
</div>
|
|
3248
|
+
</div>
|
|
3249
|
+
</div>
|
|
3250
|
+
)}
|
|
3001
3251
|
<div className={styles.formcontainer}>
|
|
3002
3252
|
{galleryData.length > 0 ? (
|
|
3003
|
-
<
|
|
3004
|
-
|
|
3005
|
-
|
|
3006
|
-
|
|
3253
|
+
<div
|
|
3254
|
+
className={styles.galleryContainer}
|
|
3255
|
+
>
|
|
3256
|
+
<div
|
|
3257
|
+
className={
|
|
3258
|
+
styles.galleryInstructions
|
|
3259
|
+
}
|
|
3260
|
+
>
|
|
3261
|
+
<Image
|
|
3262
|
+
strokeWidth={1.5}
|
|
3263
|
+
size={16}
|
|
3264
|
+
/>
|
|
3265
|
+
<span>
|
|
3266
|
+
Tap any image to enlarge
|
|
3267
|
+
</span>
|
|
3268
|
+
</div>
|
|
3269
|
+
<div
|
|
3270
|
+
className={
|
|
3271
|
+
styles.customGalleryGrid
|
|
3272
|
+
}
|
|
3273
|
+
>
|
|
3274
|
+
{galleryData.map(
|
|
3275
|
+
(img, index) => (
|
|
3276
|
+
<div
|
|
3277
|
+
key={`gallery-item-${index}`}
|
|
3278
|
+
className={
|
|
3279
|
+
styles.galleryItem
|
|
3280
|
+
}
|
|
3281
|
+
onClick={() => {
|
|
3282
|
+
setLightboxIndex(
|
|
3283
|
+
index
|
|
3284
|
+
);
|
|
3285
|
+
setLightboxOpen(
|
|
3286
|
+
true
|
|
3287
|
+
);
|
|
3288
|
+
}}
|
|
3289
|
+
>
|
|
3290
|
+
<img
|
|
3291
|
+
src={img.src}
|
|
3292
|
+
alt={
|
|
3293
|
+
img.caption ||
|
|
3294
|
+
`Image ${
|
|
3295
|
+
index +
|
|
3296
|
+
1
|
|
3297
|
+
}`
|
|
3298
|
+
}
|
|
3299
|
+
/>
|
|
3300
|
+
{img.caption && (
|
|
3301
|
+
<div
|
|
3302
|
+
className={
|
|
3303
|
+
styles.imageCaption
|
|
3304
|
+
}
|
|
3305
|
+
>
|
|
3306
|
+
{
|
|
3307
|
+
img.caption
|
|
3308
|
+
}
|
|
3309
|
+
</div>
|
|
3310
|
+
)}
|
|
3311
|
+
<div
|
|
3312
|
+
className={
|
|
3313
|
+
styles.galleryImageOverlay
|
|
3314
|
+
}
|
|
3315
|
+
>
|
|
3316
|
+
<span>
|
|
3317
|
+
<Image
|
|
3318
|
+
strokeWidth={
|
|
3319
|
+
1.5
|
|
3320
|
+
}
|
|
3321
|
+
size={
|
|
3322
|
+
16
|
|
3323
|
+
}
|
|
3324
|
+
style={{
|
|
3325
|
+
marginRight:
|
|
3326
|
+
'6px',
|
|
3327
|
+
}}
|
|
3328
|
+
/>
|
|
3329
|
+
Enlarge
|
|
3330
|
+
</span>
|
|
3331
|
+
</div>
|
|
3332
|
+
</div>
|
|
3333
|
+
)
|
|
3334
|
+
)}
|
|
3335
|
+
</div>
|
|
3336
|
+
</div>
|
|
3007
3337
|
) : (
|
|
3008
3338
|
<div className={styles.noDataMessage}>
|
|
3339
|
+
<Image
|
|
3340
|
+
strokeWidth={1.5}
|
|
3341
|
+
size={20}
|
|
3342
|
+
/>
|
|
3009
3343
|
No images available in the gallery
|
|
3010
3344
|
</div>
|
|
3011
3345
|
)}
|
|
@@ -3014,6 +3348,14 @@ const DataGrid = forwardRef(
|
|
|
3014
3348
|
</div>
|
|
3015
3349
|
</div>
|
|
3016
3350
|
</Popup>
|
|
3351
|
+
|
|
3352
|
+
{/* Lightbox for full-size image viewing */}
|
|
3353
|
+
<Lightbox
|
|
3354
|
+
open={lightboxOpen}
|
|
3355
|
+
close={() => setLightboxOpen(false)}
|
|
3356
|
+
index={lightboxIndex}
|
|
3357
|
+
slides={galleryData.map((img) => ({ src: img.src }))}
|
|
3358
|
+
/>
|
|
3017
3359
|
</>
|
|
3018
3360
|
);
|
|
3019
3361
|
}
|
|
@@ -101,7 +101,7 @@ function MultiSelect({
|
|
|
101
101
|
|
|
102
102
|
return (
|
|
103
103
|
<SelectComponent
|
|
104
|
-
closeMenuOnSelect={!multi}
|
|
104
|
+
closeMenuOnSelect={!multi || settings.limit === 1}
|
|
105
105
|
isClearable
|
|
106
106
|
isSearchable
|
|
107
107
|
isMulti={multi}
|
|
@@ -109,7 +109,19 @@ function MultiSelect({
|
|
|
109
109
|
components={{ SelectList }}
|
|
110
110
|
options={selectOptions}
|
|
111
111
|
onChange={(inputValue, action) => {
|
|
112
|
-
|
|
112
|
+
// Special handling for limit=1: keep only the most recent selection
|
|
113
|
+
if (
|
|
114
|
+
settings.limit === 1 &&
|
|
115
|
+
multi &&
|
|
116
|
+
Array.isArray(inputValue) &&
|
|
117
|
+
inputValue.length > 1
|
|
118
|
+
) {
|
|
119
|
+
const latestSelection = inputValue[inputValue.length - 1];
|
|
120
|
+
const newValue = latestSelection ? [latestSelection] : [];
|
|
121
|
+
onChange(newValue, action, settings.id);
|
|
122
|
+
} else {
|
|
123
|
+
onChange(inputValue, action, settings.id);
|
|
124
|
+
}
|
|
113
125
|
}}
|
|
114
126
|
className={
|
|
115
127
|
className
|
|
@@ -130,6 +142,11 @@ function MultiSelect({
|
|
|
130
142
|
value={selectValue}
|
|
131
143
|
onCreateOption={handleCreate}
|
|
132
144
|
placeholder={placeholder ? placeholder : 'Select...'}
|
|
145
|
+
isOptionDisabled={
|
|
146
|
+
settings.limit && multi && settings.limit > 1
|
|
147
|
+
? () => selectValue.length >= settings.limit
|
|
148
|
+
: undefined
|
|
149
|
+
}
|
|
133
150
|
/>
|
|
134
151
|
);
|
|
135
152
|
}
|
|
@@ -21,6 +21,148 @@
|
|
|
21
21
|
}
|
|
22
22
|
}
|
|
23
23
|
|
|
24
|
+
/* Clock button styles */
|
|
25
|
+
.clockButton {
|
|
26
|
+
display: flex;
|
|
27
|
+
align-items: center;
|
|
28
|
+
justify-content: center;
|
|
29
|
+
width: 40px;
|
|
30
|
+
height: 40px;
|
|
31
|
+
border-radius: 4px;
|
|
32
|
+
background-color: #2b6cb0; /* Matching blue from screenshot */
|
|
33
|
+
border: none;
|
|
34
|
+
cursor: pointer;
|
|
35
|
+
transition: all 0.2s ease;
|
|
36
|
+
margin: 0 auto;
|
|
37
|
+
|
|
38
|
+
&:hover {
|
|
39
|
+
background-color: #2563a0; /* Slightly darker blue on hover */
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
svg {
|
|
43
|
+
color: white; /* White icon color */
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
/* Toggle button styles */
|
|
48
|
+
:global {
|
|
49
|
+
.react-toggle {
|
|
50
|
+
touch-action: pan-x;
|
|
51
|
+
display: inline-block;
|
|
52
|
+
position: relative;
|
|
53
|
+
cursor: pointer;
|
|
54
|
+
background-color: transparent;
|
|
55
|
+
border: 0;
|
|
56
|
+
padding: 0;
|
|
57
|
+
-webkit-touch-callout: none;
|
|
58
|
+
-webkit-user-select: none;
|
|
59
|
+
-khtml-user-select: none;
|
|
60
|
+
-moz-user-select: none;
|
|
61
|
+
-ms-user-select: none;
|
|
62
|
+
user-select: none;
|
|
63
|
+
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
64
|
+
-webkit-tap-highlight-color: transparent;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
.react-toggle-screenreader-only {
|
|
68
|
+
border: 0;
|
|
69
|
+
clip: rect(0 0 0 0);
|
|
70
|
+
height: 1px;
|
|
71
|
+
margin: -1px;
|
|
72
|
+
overflow: hidden;
|
|
73
|
+
padding: 0;
|
|
74
|
+
position: absolute;
|
|
75
|
+
width: 1px;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.react-toggle-track {
|
|
79
|
+
width: 50px;
|
|
80
|
+
height: 24px;
|
|
81
|
+
padding: 0;
|
|
82
|
+
border-radius: 30px;
|
|
83
|
+
background-color: #4d4d4d;
|
|
84
|
+
transition: all 0.2s ease;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
|
|
88
|
+
background-color: #000000;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.react-toggle--checked .react-toggle-track {
|
|
92
|
+
background-color: var(--primary-color, #3b82f6);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
.react-toggle--checked:hover:not(.react-toggle--disabled)
|
|
96
|
+
.react-toggle-track {
|
|
97
|
+
background-color: var(--primary-color, #3b82f6);
|
|
98
|
+
opacity: 0.8;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
.react-toggle-track-check {
|
|
102
|
+
position: absolute;
|
|
103
|
+
width: 14px;
|
|
104
|
+
height: 10px;
|
|
105
|
+
top: 0px;
|
|
106
|
+
bottom: 0px;
|
|
107
|
+
margin-top: auto;
|
|
108
|
+
margin-bottom: auto;
|
|
109
|
+
line-height: 0;
|
|
110
|
+
left: 8px;
|
|
111
|
+
opacity: 0;
|
|
112
|
+
transition: opacity 0.25s ease;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
.react-toggle--checked .react-toggle-track-check {
|
|
116
|
+
opacity: 1;
|
|
117
|
+
transition: opacity 0.25s ease;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
.react-toggle-track-x {
|
|
121
|
+
position: absolute;
|
|
122
|
+
width: 10px;
|
|
123
|
+
height: 10px;
|
|
124
|
+
top: 0px;
|
|
125
|
+
bottom: 0px;
|
|
126
|
+
margin-top: auto;
|
|
127
|
+
margin-bottom: auto;
|
|
128
|
+
line-height: 0;
|
|
129
|
+
right: 10px;
|
|
130
|
+
opacity: 1;
|
|
131
|
+
transition: opacity 0.25s ease;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
.react-toggle--checked .react-toggle-track-x {
|
|
135
|
+
opacity: 0;
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
.react-toggle-thumb {
|
|
139
|
+
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
|
|
140
|
+
position: absolute;
|
|
141
|
+
top: 1px;
|
|
142
|
+
left: 1px;
|
|
143
|
+
width: 22px;
|
|
144
|
+
height: 22px;
|
|
145
|
+
border: 1px solid #4d4d4d;
|
|
146
|
+
border-radius: 50%;
|
|
147
|
+
background-color: #fafafa;
|
|
148
|
+
box-sizing: border-box;
|
|
149
|
+
transition: all 0.25s ease;
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
.react-toggle--checked .react-toggle-thumb {
|
|
153
|
+
left: 27px;
|
|
154
|
+
border-color: var(--primary-color, #3b82f6);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.react-toggle--focus .react-toggle-thumb {
|
|
158
|
+
box-shadow: 0px 0px 3px 2px var(--primary-color, #3b82f6);
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
.react-toggle:active:not(.react-toggle--disabled) .react-toggle-thumb {
|
|
162
|
+
box-shadow: 0px 0px 5px 5px var(--primary-color, #3b82f6);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
|
|
24
166
|
.vs-datagrid--row:hover {
|
|
25
167
|
.InovuaReactDataGrid__row-cell-wrap {
|
|
26
168
|
background: var(--hover-color, rgb(230, 240, 250)) !important;
|
|
@@ -128,10 +270,9 @@
|
|
|
128
270
|
|
|
129
271
|
.modalwrap {
|
|
130
272
|
background: var(--tertiary-color);
|
|
131
|
-
border-radius:
|
|
132
|
-
overflow:
|
|
133
|
-
|
|
134
|
-
border-top-right-radius: var(--br);
|
|
273
|
+
border-radius: 8px;
|
|
274
|
+
overflow: hidden;
|
|
275
|
+
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.15);
|
|
135
276
|
}
|
|
136
277
|
|
|
137
278
|
.top--modal {
|
|
@@ -146,17 +287,31 @@
|
|
|
146
287
|
|
|
147
288
|
.modal__header {
|
|
148
289
|
width: 100%;
|
|
149
|
-
border-bottom: 1px solid rgba(var(--primary-rgb), 0.
|
|
290
|
+
border-bottom: 1px solid rgba(var(--primary-rgb), 0.1);
|
|
150
291
|
display: flex;
|
|
151
292
|
align-items: center;
|
|
152
293
|
justify-content: space-between;
|
|
153
|
-
padding: 0.75rem;
|
|
294
|
+
padding: 0.75rem 1rem;
|
|
295
|
+
background-color: #fff;
|
|
154
296
|
|
|
155
297
|
h1 {
|
|
156
298
|
color: var(--secondary-color);
|
|
157
299
|
margin: 0;
|
|
158
300
|
padding: 0;
|
|
159
|
-
font-size: 1.
|
|
301
|
+
font-size: 1.1em;
|
|
302
|
+
font-weight: 600;
|
|
303
|
+
display: flex;
|
|
304
|
+
align-items: center;
|
|
305
|
+
gap: 8px;
|
|
306
|
+
|
|
307
|
+
&::before {
|
|
308
|
+
content: '';
|
|
309
|
+
display: block;
|
|
310
|
+
width: 3px;
|
|
311
|
+
height: 16px;
|
|
312
|
+
background-color: var(--primary-color);
|
|
313
|
+
border-radius: 2px;
|
|
314
|
+
}
|
|
160
315
|
}
|
|
161
316
|
}
|
|
162
317
|
|
|
@@ -169,8 +324,15 @@
|
|
|
169
324
|
outline: none;
|
|
170
325
|
border: none;
|
|
171
326
|
border-radius: var(--br);
|
|
172
|
-
display:
|
|
327
|
+
display: flex;
|
|
328
|
+
align-items: center;
|
|
329
|
+
justify-content: center;
|
|
173
330
|
line-height: 1;
|
|
331
|
+
transition: all 0.2s ease;
|
|
332
|
+
|
|
333
|
+
&:hover {
|
|
334
|
+
background: rgba(var(--paragraph-rgb), 0.1);
|
|
335
|
+
}
|
|
174
336
|
|
|
175
337
|
svg {
|
|
176
338
|
color: var(--primary-color);
|
|
@@ -184,22 +346,315 @@
|
|
|
184
346
|
padding: 0.75rem;
|
|
185
347
|
max-height: 80vh;
|
|
186
348
|
overflow-y: auto;
|
|
349
|
+
|
|
350
|
+
&--gallery {
|
|
351
|
+
padding: 0.75rem;
|
|
352
|
+
background-color: #f9fafb;
|
|
353
|
+
min-width: 600px; /* Ensure the gallery modal has a minimum width */
|
|
354
|
+
max-width: 90vw; /* Limit maximum width */
|
|
355
|
+
}
|
|
187
356
|
}
|
|
188
357
|
|
|
189
358
|
.formcontainer {
|
|
190
359
|
width: 100%;
|
|
360
|
+
padding: 8px 0;
|
|
361
|
+
|
|
362
|
+
/* Custom styling for gallery container */
|
|
363
|
+
.galleryContainer {
|
|
364
|
+
margin-top: 8px;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
/* Gallery instructions styling */
|
|
368
|
+
.galleryInstructions {
|
|
369
|
+
display: flex;
|
|
370
|
+
align-items: center;
|
|
371
|
+
gap: 8px;
|
|
372
|
+
margin-bottom: 12px;
|
|
373
|
+
padding: 10px 12px;
|
|
374
|
+
background-color: #f0f7ff;
|
|
375
|
+
border: 1px solid rgba(var(--primary-rgb), 0.2);
|
|
376
|
+
border-radius: 6px;
|
|
377
|
+
color: var(--secondary-color);
|
|
378
|
+
font-size: 0.9rem;
|
|
379
|
+
|
|
380
|
+
svg {
|
|
381
|
+
color: var(--primary-color);
|
|
382
|
+
flex-shrink: 0;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
span {
|
|
386
|
+
line-height: 1.4;
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
/* Gallery image overlay styling */
|
|
391
|
+
.galleryImageOverlay {
|
|
392
|
+
position: absolute;
|
|
393
|
+
top: 0;
|
|
394
|
+
left: 0;
|
|
395
|
+
right: 0;
|
|
396
|
+
bottom: 0;
|
|
397
|
+
display: flex;
|
|
398
|
+
align-items: center;
|
|
399
|
+
justify-content: center;
|
|
400
|
+
background-color: rgba(0, 0, 0, 0.5);
|
|
401
|
+
color: white;
|
|
402
|
+
opacity: 0;
|
|
403
|
+
transition: opacity 0.3s ease;
|
|
404
|
+
border-radius: 6px;
|
|
405
|
+
z-index: 5;
|
|
406
|
+
|
|
407
|
+
span {
|
|
408
|
+
padding: 8px 14px;
|
|
409
|
+
background-color: rgba(0, 0, 0, 0.75);
|
|
410
|
+
border-radius: 4px;
|
|
411
|
+
font-size: 0.85rem;
|
|
412
|
+
font-weight: 500;
|
|
413
|
+
display: flex;
|
|
414
|
+
align-items: center;
|
|
415
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
|
|
416
|
+
border: 1px solid rgba(255, 255, 255, 0.1);
|
|
417
|
+
|
|
418
|
+
svg {
|
|
419
|
+
color: var(--primary-color, #3b82f6);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
/* Custom grid layout for gallery */
|
|
425
|
+
.customGalleryGrid {
|
|
426
|
+
display: grid;
|
|
427
|
+
grid-template-columns: repeat(4, 1fr); /* 4 columns by default */
|
|
428
|
+
gap: 16px;
|
|
429
|
+
margin-top: 16px;
|
|
430
|
+
|
|
431
|
+
@media (max-width: 1200px) {
|
|
432
|
+
grid-template-columns: repeat(
|
|
433
|
+
3,
|
|
434
|
+
1fr
|
|
435
|
+
); /* 3 columns on medium screens */
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
@media (max-width: 768px) {
|
|
439
|
+
grid-template-columns: repeat(
|
|
440
|
+
2,
|
|
441
|
+
1fr
|
|
442
|
+
); /* 2 columns on small screens */
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
.galleryItem {
|
|
446
|
+
aspect-ratio: 4/3;
|
|
447
|
+
border-radius: 6px;
|
|
448
|
+
overflow: hidden;
|
|
449
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
|
|
450
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
451
|
+
cursor: pointer;
|
|
452
|
+
position: relative;
|
|
453
|
+
display: flex;
|
|
454
|
+
flex-direction: column;
|
|
455
|
+
|
|
456
|
+
&:hover {
|
|
457
|
+
transform: translateY(-2px);
|
|
458
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15);
|
|
459
|
+
|
|
460
|
+
.galleryImageOverlay {
|
|
461
|
+
opacity: 1;
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
img {
|
|
466
|
+
width: 100%;
|
|
467
|
+
height: 100%;
|
|
468
|
+
object-fit: cover;
|
|
469
|
+
display: block;
|
|
470
|
+
}
|
|
471
|
+
|
|
472
|
+
.imageCaption {
|
|
473
|
+
padding: 8px;
|
|
474
|
+
background-color: rgba(0, 0, 0, 0.6);
|
|
475
|
+
color: white;
|
|
476
|
+
font-size: 0.8rem;
|
|
477
|
+
position: absolute;
|
|
478
|
+
bottom: 0;
|
|
479
|
+
left: 0;
|
|
480
|
+
right: 0;
|
|
481
|
+
white-space: nowrap;
|
|
482
|
+
overflow: hidden;
|
|
483
|
+
text-overflow: ellipsis;
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
/* Add custom styles to override react-grid-gallery */
|
|
489
|
+
:global {
|
|
490
|
+
/* These styles will be applied globally */
|
|
491
|
+
.ReactGridGallery_tile {
|
|
492
|
+
border-radius: 6px !important;
|
|
493
|
+
overflow: hidden !important;
|
|
494
|
+
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1) !important;
|
|
495
|
+
transition: transform 0.2s ease, box-shadow 0.2s ease !important;
|
|
496
|
+
cursor: pointer !important;
|
|
497
|
+
margin-bottom: 8px !important;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
.ReactGridGallery_tile:hover {
|
|
501
|
+
transform: translateY(-2px) !important;
|
|
502
|
+
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.15) !important;
|
|
503
|
+
|
|
504
|
+
/* Show overlay on hover */
|
|
505
|
+
.galleryImageOverlay {
|
|
506
|
+
opacity: 1 !important;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
.ReactGridGallery_tile-viewport {
|
|
511
|
+
border-radius: 6px !important;
|
|
512
|
+
overflow: hidden !important;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.ReactGridGallery_tile-description {
|
|
516
|
+
background: rgba(0, 0, 0, 0.6) !important;
|
|
517
|
+
padding: 8px !important;
|
|
518
|
+
font-size: 0.85rem !important;
|
|
519
|
+
}
|
|
520
|
+
}
|
|
191
521
|
}
|
|
192
522
|
|
|
193
523
|
.noDataMessage {
|
|
194
524
|
text-align: center;
|
|
195
525
|
color: var(--secondary-color);
|
|
196
|
-
font-size:
|
|
197
|
-
padding:
|
|
198
|
-
margin:
|
|
526
|
+
font-size: 1rem;
|
|
527
|
+
padding: 1.5rem;
|
|
528
|
+
margin: 1rem auto;
|
|
199
529
|
background: var(--tertiary-color);
|
|
200
530
|
border: 1px solid rgba(var(--primary-rgb), 0.15);
|
|
201
531
|
border-radius: var(--br);
|
|
202
|
-
max-width:
|
|
203
|
-
box-shadow: 0
|
|
532
|
+
max-width: 90%;
|
|
533
|
+
box-shadow: 0 1px 3px rgba(0, 0, 0, 0.05);
|
|
204
534
|
font-style: italic;
|
|
535
|
+
display: flex;
|
|
536
|
+
align-items: center;
|
|
537
|
+
justify-content: center;
|
|
538
|
+
gap: 8px;
|
|
539
|
+
|
|
540
|
+
svg {
|
|
541
|
+
color: var(--primary-color);
|
|
542
|
+
opacity: 0.7;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
545
|
+
|
|
546
|
+
.tdaction {
|
|
547
|
+
cursor: pointer;
|
|
548
|
+
color: #6b7280;
|
|
549
|
+
|
|
550
|
+
&:hover {
|
|
551
|
+
color: var(--primary-color, #3b82f6);
|
|
552
|
+
}
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
.uploadSection {
|
|
556
|
+
margin-bottom: 16px;
|
|
557
|
+
border-bottom: 1px solid #e5e7eb;
|
|
558
|
+
padding-bottom: 16px;
|
|
559
|
+
|
|
560
|
+
h3 {
|
|
561
|
+
font-size: 0.95rem;
|
|
562
|
+
font-weight: 600;
|
|
563
|
+
margin-bottom: 8px;
|
|
564
|
+
color: var(--secondary-color, #111827);
|
|
565
|
+
display: flex;
|
|
566
|
+
align-items: center;
|
|
567
|
+
gap: 6px;
|
|
568
|
+
|
|
569
|
+
svg {
|
|
570
|
+
color: var(--primary-color, #3b82f6);
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
.dropzoneContainer {
|
|
576
|
+
position: relative;
|
|
577
|
+
margin-bottom: 12px;
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
.progressBar {
|
|
581
|
+
height: 3px;
|
|
582
|
+
background-color: #e5e7eb;
|
|
583
|
+
border-radius: 2px;
|
|
584
|
+
overflow: hidden;
|
|
585
|
+
margin-bottom: 8px;
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
.progressBarInner {
|
|
589
|
+
height: 100%;
|
|
590
|
+
background-color: var(--primary-color, #3b82f6);
|
|
591
|
+
transition: width 0.3s ease;
|
|
592
|
+
}
|
|
593
|
+
|
|
594
|
+
.dropzone {
|
|
595
|
+
border: 1px dashed #d1d5db;
|
|
596
|
+
border-radius: 6px;
|
|
597
|
+
padding: 12px;
|
|
598
|
+
text-align: center;
|
|
599
|
+
cursor: pointer;
|
|
600
|
+
transition: all 0.2s ease;
|
|
601
|
+
display: flex;
|
|
602
|
+
flex-direction: row;
|
|
603
|
+
align-items: center;
|
|
604
|
+
justify-content: center;
|
|
605
|
+
gap: 10px;
|
|
606
|
+
|
|
607
|
+
&:hover {
|
|
608
|
+
border-color: var(--primary-color, #3b82f6);
|
|
609
|
+
background-color: rgba(59, 130, 246, 0.05);
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
svg {
|
|
613
|
+
color: var(--primary-color, #3b82f6);
|
|
614
|
+
flex-shrink: 0;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
p {
|
|
618
|
+
margin: 0;
|
|
619
|
+
color: #6b7280;
|
|
620
|
+
font-size: 0.9rem;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
|
|
624
|
+
.filterInput {
|
|
625
|
+
display: flex;
|
|
626
|
+
align-items: center;
|
|
627
|
+
justify-content: flex-start;
|
|
628
|
+
margin-bottom: 10px;
|
|
629
|
+
width: 100%;
|
|
630
|
+
|
|
631
|
+
&--alt {
|
|
632
|
+
display: flex;
|
|
633
|
+
align-items: center;
|
|
634
|
+
justify-content: flex-start;
|
|
635
|
+
margin-bottom: 10px;
|
|
636
|
+
width: 100%;
|
|
637
|
+
height: 58px;
|
|
638
|
+
|
|
639
|
+
.icon-search {
|
|
640
|
+
position: absolute;
|
|
641
|
+
left: 10px;
|
|
642
|
+
color: #6b7280;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
input {
|
|
646
|
+
height: 38px;
|
|
647
|
+
border-radius: 4px;
|
|
648
|
+
border: 1px solid #d1d5db;
|
|
649
|
+
padding: 0 10px 0 35px;
|
|
650
|
+
width: 100%;
|
|
651
|
+
max-width: 300px;
|
|
652
|
+
|
|
653
|
+
&:focus {
|
|
654
|
+
outline: none;
|
|
655
|
+
border-color: var(--primary-color, #3b82f6);
|
|
656
|
+
box-shadow: 0 0 0 2px rgba(59, 130, 246, 0.2);
|
|
657
|
+
}
|
|
658
|
+
}
|
|
659
|
+
}
|
|
205
660
|
}
|
|
@@ -378,6 +378,144 @@ input[type]:not([type='search']):not([type='url']):not([type='hidden']):not(
|
|
|
378
378
|
z-index: -1 !important;
|
|
379
379
|
}
|
|
380
380
|
|
|
381
|
+
/* React Toggle Styling */
|
|
382
|
+
.react-toggle {
|
|
383
|
+
touch-action: pan-x;
|
|
384
|
+
display: inline-block;
|
|
385
|
+
position: relative;
|
|
386
|
+
cursor: pointer;
|
|
387
|
+
background-color: transparent;
|
|
388
|
+
border: 0;
|
|
389
|
+
padding: 0;
|
|
390
|
+
-webkit-touch-callout: none;
|
|
391
|
+
-webkit-user-select: none;
|
|
392
|
+
-khtml-user-select: none;
|
|
393
|
+
-moz-user-select: none;
|
|
394
|
+
-ms-user-select: none;
|
|
395
|
+
user-select: none;
|
|
396
|
+
-webkit-tap-highlight-color: rgba(0, 0, 0, 0);
|
|
397
|
+
-webkit-tap-highlight-color: transparent;
|
|
398
|
+
z-index: 2; /* Ensure toggle is above checkbox */
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
/* Fix for specific toggle in forms */
|
|
402
|
+
form div:has(span:contains('Use T-Bar?')) .react-toggle {
|
|
403
|
+
margin-right: 8px;
|
|
404
|
+
vertical-align: middle;
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/* Hide checkboxes when they're next to a toggle */
|
|
408
|
+
.react-toggle + input[type='checkbox'],
|
|
409
|
+
input[type='checkbox'] + .react-toggle,
|
|
410
|
+
label:has(.react-toggle) input[type='checkbox'],
|
|
411
|
+
div:has(.react-toggle) > input[type='checkbox'],
|
|
412
|
+
form div:has(.react-toggle) input[type='checkbox'] {
|
|
413
|
+
display: none !important;
|
|
414
|
+
visibility: hidden !important;
|
|
415
|
+
opacity: 0 !important;
|
|
416
|
+
position: absolute !important;
|
|
417
|
+
pointer-events: none !important;
|
|
418
|
+
width: 0 !important;
|
|
419
|
+
height: 0 !important;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
.react-toggle-screenreader-only {
|
|
423
|
+
border: 0;
|
|
424
|
+
clip: rect(0 0 0 0);
|
|
425
|
+
height: 1px;
|
|
426
|
+
margin: -1px;
|
|
427
|
+
overflow: hidden;
|
|
428
|
+
padding: 0;
|
|
429
|
+
position: absolute;
|
|
430
|
+
width: 1px;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
.react-toggle-track {
|
|
434
|
+
width: 50px;
|
|
435
|
+
height: 24px;
|
|
436
|
+
padding: 0;
|
|
437
|
+
border-radius: 30px;
|
|
438
|
+
background-color: #4d4d4d;
|
|
439
|
+
transition: all 0.2s ease;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
.react-toggle:hover:not(.react-toggle--disabled) .react-toggle-track {
|
|
443
|
+
background-color: #000000;
|
|
444
|
+
}
|
|
445
|
+
|
|
446
|
+
.react-toggle--checked .react-toggle-track {
|
|
447
|
+
background-color: var(--primary-color, #3b82f6);
|
|
448
|
+
}
|
|
449
|
+
|
|
450
|
+
.react-toggle--checked:hover:not(.react-toggle--disabled) .react-toggle-track {
|
|
451
|
+
background-color: var(--primary-color, #3b82f6);
|
|
452
|
+
opacity: 0.8;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
.react-toggle-track-check {
|
|
456
|
+
position: absolute;
|
|
457
|
+
width: 14px;
|
|
458
|
+
height: 10px;
|
|
459
|
+
top: 0px;
|
|
460
|
+
bottom: 0px;
|
|
461
|
+
margin-top: auto;
|
|
462
|
+
margin-bottom: auto;
|
|
463
|
+
line-height: 0;
|
|
464
|
+
left: 8px;
|
|
465
|
+
opacity: 0;
|
|
466
|
+
transition: opacity 0.25s ease;
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
.react-toggle--checked .react-toggle-track-check {
|
|
470
|
+
opacity: 1;
|
|
471
|
+
transition: opacity 0.25s ease;
|
|
472
|
+
}
|
|
473
|
+
|
|
474
|
+
.react-toggle-track-x {
|
|
475
|
+
position: absolute;
|
|
476
|
+
width: 10px;
|
|
477
|
+
height: 10px;
|
|
478
|
+
top: 0px;
|
|
479
|
+
bottom: 0px;
|
|
480
|
+
margin-top: auto;
|
|
481
|
+
margin-bottom: auto;
|
|
482
|
+
line-height: 0;
|
|
483
|
+
right: 10px;
|
|
484
|
+
opacity: 1;
|
|
485
|
+
transition: opacity 0.25s ease;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
.react-toggle--checked .react-toggle-track-x {
|
|
489
|
+
opacity: 0;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
.react-toggle-thumb {
|
|
493
|
+
transition: all 0.5s cubic-bezier(0.23, 1, 0.32, 1) 0ms;
|
|
494
|
+
position: absolute;
|
|
495
|
+
top: 1px;
|
|
496
|
+
left: 1px;
|
|
497
|
+
width: 22px;
|
|
498
|
+
height: 22px;
|
|
499
|
+
border: 1px solid #4d4d4d;
|
|
500
|
+
border-radius: 50%;
|
|
501
|
+
background-color: #fafafa;
|
|
502
|
+
box-sizing: border-box;
|
|
503
|
+
transition: all 0.25s ease;
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
.react-toggle--checked .react-toggle-thumb {
|
|
507
|
+
left: 27px;
|
|
508
|
+
border-color: var(--primary-color, #3b82f6);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
.react-toggle--focus .react-toggle-thumb {
|
|
512
|
+
box-shadow: 0px 0px 3px 2px var(--primary-color, #3b82f6);
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
.react-toggle:active:not(.react-toggle--disabled) .react-toggle-thumb {
|
|
516
|
+
box-shadow: 0px 0px 5px 5px var(--primary-color, #3b82f6);
|
|
517
|
+
}
|
|
518
|
+
|
|
381
519
|
/* Safari-specific fixes for form elements */
|
|
382
520
|
@supports (-webkit-touch-callout: none) {
|
|
383
521
|
/* Safari-specific styles */
|