@djangocfg/ui-tools 2.1.136 → 2.1.137
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
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/ui-tools",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.137",
|
|
4
4
|
"description": "Heavy React tools with lazy loading - for Electron, Vite, CRA, Next.js apps",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui-tools",
|
|
@@ -63,8 +63,8 @@
|
|
|
63
63
|
"check": "tsc --noEmit"
|
|
64
64
|
},
|
|
65
65
|
"peerDependencies": {
|
|
66
|
-
"@djangocfg/i18n": "^2.1.
|
|
67
|
-
"@djangocfg/ui-core": "^2.1.
|
|
66
|
+
"@djangocfg/i18n": "^2.1.137",
|
|
67
|
+
"@djangocfg/ui-core": "^2.1.137",
|
|
68
68
|
"lucide-react": "^0.545.0",
|
|
69
69
|
"react": "^19.0.0",
|
|
70
70
|
"react-dom": "^19.0.0",
|
|
@@ -96,10 +96,10 @@
|
|
|
96
96
|
"@maplibre/maplibre-gl-geocoder": "^1.7.0"
|
|
97
97
|
},
|
|
98
98
|
"devDependencies": {
|
|
99
|
-
"@djangocfg/i18n": "^2.1.
|
|
99
|
+
"@djangocfg/i18n": "^2.1.137",
|
|
100
100
|
"@djangocfg/playground": "workspace:*",
|
|
101
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
102
|
-
"@djangocfg/ui-core": "^2.1.
|
|
101
|
+
"@djangocfg/typescript-config": "^2.1.137",
|
|
102
|
+
"@djangocfg/ui-core": "^2.1.137",
|
|
103
103
|
"@types/mapbox__mapbox-gl-draw": "^1.4.8",
|
|
104
104
|
"@types/node": "^24.7.2",
|
|
105
105
|
"@types/react": "^19.1.0",
|
|
@@ -6,6 +6,7 @@ import { useTypedT, type I18nTranslations } from '@djangocfg/i18n'
|
|
|
6
6
|
import { useImageLoader } from '@djangocfg/ui-core/hooks'
|
|
7
7
|
import { ImageOff } from 'lucide-react'
|
|
8
8
|
import type { GalleryImageProps } from '../../types'
|
|
9
|
+
import { normalizeImageUrl } from '../../utils'
|
|
9
10
|
|
|
10
11
|
/**
|
|
11
12
|
* GalleryImage - Single image with loading state and error handling
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
'use client'
|
|
2
2
|
|
|
3
|
-
import { memo, useCallback, useMemo
|
|
3
|
+
import { memo, useCallback, useMemo } from 'react'
|
|
4
4
|
import { cn } from '@djangocfg/ui-core/lib'
|
|
5
5
|
import { Play } from 'lucide-react'
|
|
6
6
|
import type { GalleryMediaItem } from '../../types'
|
|
7
|
+
import { normalizeImageUrl } from '../../utils'
|
|
7
8
|
|
|
8
9
|
export type GalleryGridLayout =
|
|
9
10
|
| 'auto'
|
|
@@ -347,16 +348,10 @@ const GridItem = memo(function GridItem({
|
|
|
347
348
|
showBadge = false,
|
|
348
349
|
badgeCount = 0,
|
|
349
350
|
}: GridItemProps) {
|
|
350
|
-
const [isLoaded, setIsLoaded] = useState(false)
|
|
351
|
-
|
|
352
351
|
const handleClick = useCallback(() => {
|
|
353
352
|
onClick(index)
|
|
354
353
|
}, [onClick, index])
|
|
355
354
|
|
|
356
|
-
const handleLoad = useCallback(() => {
|
|
357
|
-
setIsLoaded(true)
|
|
358
|
-
}, [])
|
|
359
|
-
|
|
360
355
|
if (!image) return null
|
|
361
356
|
|
|
362
357
|
const isVideo = image.type === 'video'
|
|
@@ -376,17 +371,15 @@ const GridItem = memo(function GridItem({
|
|
|
376
371
|
aria-label={`View image ${index + 1}`}
|
|
377
372
|
>
|
|
378
373
|
<img
|
|
379
|
-
src={image.thumbnail || image.src}
|
|
374
|
+
src={normalizeImageUrl(image.thumbnail || image.src)}
|
|
380
375
|
alt={image.alt || `Image ${index + 1}`}
|
|
381
376
|
className={cn(
|
|
382
377
|
'w-full h-full object-cover transition-transform duration-300 group-hover:scale-105',
|
|
383
|
-
// Staggered reveal animation
|
|
384
|
-
staggerDelay > 0 &&
|
|
385
|
-
staggerDelay > 0 && isLoaded && 'animate-in fade-in zoom-in-95 duration-300 fill-mode-both'
|
|
378
|
+
// Staggered reveal animation with CSS only (no JS state needed)
|
|
379
|
+
staggerDelay > 0 && 'animate-in fade-in zoom-in-95 duration-300 fill-mode-both'
|
|
386
380
|
)}
|
|
387
|
-
style={staggerDelay > 0
|
|
381
|
+
style={staggerDelay > 0 ? { animationDelay } : undefined}
|
|
388
382
|
loading={index === 0 ? 'eager' : 'lazy'}
|
|
389
|
-
onLoad={handleLoad}
|
|
390
383
|
/>
|
|
391
384
|
|
|
392
385
|
{/* Hover overlay */}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* URL normalization utilities for Gallery
|
|
3
|
+
*
|
|
4
|
+
* Handles Mixed Content issues by upgrading HTTP to HTTPS
|
|
5
|
+
* when the page is served over HTTPS.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Normalize image URL to prevent Mixed Content errors
|
|
10
|
+
* Upgrades HTTP to HTTPS when page is served over HTTPS
|
|
11
|
+
*/
|
|
12
|
+
export function normalizeImageUrl(url: string | undefined): string {
|
|
13
|
+
if (!url) return ''
|
|
14
|
+
|
|
15
|
+
// Check if we're on HTTPS page
|
|
16
|
+
const isSecurePage = typeof window !== 'undefined' && window.location.protocol === 'https:'
|
|
17
|
+
|
|
18
|
+
// Upgrade HTTP to HTTPS if on secure page
|
|
19
|
+
if (isSecurePage && url.startsWith('http://')) {
|
|
20
|
+
return url.replace('http://', 'https://')
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
return url
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Normalize array of URLs
|
|
28
|
+
*/
|
|
29
|
+
export function normalizeImageUrls(urls: (string | undefined)[]): string[] {
|
|
30
|
+
return urls.map(normalizeImageUrl).filter(Boolean) as string[]
|
|
31
|
+
}
|