@djangocfg/ui-nextjs 2.1.30 → 2.1.31
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 +4 -4
- package/src/hooks/index.ts +4 -0
- package/src/hooks/useBrowserDetect.ts +182 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@djangocfg/ui-nextjs",
|
|
3
|
-
"version": "2.1.
|
|
3
|
+
"version": "2.1.31",
|
|
4
4
|
"description": "Next.js UI component library with Radix UI primitives, Tailwind CSS styling, charts, and form components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ui-components",
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"check": "tsc --noEmit"
|
|
59
59
|
},
|
|
60
60
|
"peerDependencies": {
|
|
61
|
-
"@djangocfg/api": "^2.1.
|
|
62
|
-
"@djangocfg/ui-core": "^2.1.
|
|
61
|
+
"@djangocfg/api": "^2.1.31",
|
|
62
|
+
"@djangocfg/ui-core": "^2.1.31",
|
|
63
63
|
"@types/react": "^19.1.0",
|
|
64
64
|
"@types/react-dom": "^19.1.0",
|
|
65
65
|
"consola": "^3.4.2",
|
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"vidstack": "next"
|
|
107
107
|
},
|
|
108
108
|
"devDependencies": {
|
|
109
|
-
"@djangocfg/typescript-config": "^2.1.
|
|
109
|
+
"@djangocfg/typescript-config": "^2.1.31",
|
|
110
110
|
"@types/node": "^24.7.2",
|
|
111
111
|
"eslint": "^9.37.0",
|
|
112
112
|
"tailwindcss-animate": "1.0.7",
|
package/src/hooks/index.ts
CHANGED
|
@@ -26,3 +26,7 @@ export type { UseHotkeyOptions, HotkeyCallback, Keys } from './useHotkey';
|
|
|
26
26
|
// Device detection
|
|
27
27
|
export { useDeviceDetect } from './useDeviceDetect';
|
|
28
28
|
export type { DeviceDetectResult } from './useDeviceDetect';
|
|
29
|
+
|
|
30
|
+
// Browser detection (advanced - detects Chromium browsers correctly)
|
|
31
|
+
export { useBrowserDetect } from './useBrowserDetect';
|
|
32
|
+
export type { BrowserInfo } from './useBrowserDetect';
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Advanced browser detection hook
|
|
3
|
+
*
|
|
4
|
+
* Detects modern browsers including Chromium-based browsers that may
|
|
5
|
+
* incorrectly report as Safari (Arc, Brave, Vivaldi, Comet, etc.)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
'use client';
|
|
9
|
+
|
|
10
|
+
import { useMemo } from 'react';
|
|
11
|
+
|
|
12
|
+
export interface BrowserInfo {
|
|
13
|
+
// Core browser types
|
|
14
|
+
isChrome: boolean;
|
|
15
|
+
isChromium: boolean; // Any Chromium-based browser
|
|
16
|
+
isSafari: boolean; // Real Safari (WebKit on macOS/iOS)
|
|
17
|
+
isFirefox: boolean;
|
|
18
|
+
isEdge: boolean;
|
|
19
|
+
isOpera: boolean;
|
|
20
|
+
|
|
21
|
+
// Modern Chromium-based browsers
|
|
22
|
+
isBrave: boolean;
|
|
23
|
+
isArc: boolean;
|
|
24
|
+
isVivaldi: boolean;
|
|
25
|
+
isYandex: boolean;
|
|
26
|
+
isSamsungBrowser: boolean;
|
|
27
|
+
isUCBrowser: boolean;
|
|
28
|
+
|
|
29
|
+
// Browser name
|
|
30
|
+
browserName: string;
|
|
31
|
+
|
|
32
|
+
// Engine
|
|
33
|
+
isWebKit: boolean; // Safari's engine
|
|
34
|
+
isBlink: boolean; // Chromium's engine
|
|
35
|
+
isGecko: boolean; // Firefox's engine
|
|
36
|
+
|
|
37
|
+
// For debugging
|
|
38
|
+
userAgent: string;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* Detect browser with improved accuracy for Chromium-based browsers
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* ```tsx
|
|
46
|
+
* const browser = useBrowserDetect();
|
|
47
|
+
*
|
|
48
|
+
* if (browser.isSafari && !browser.isChromium) {
|
|
49
|
+
* // Real Safari
|
|
50
|
+
* }
|
|
51
|
+
*
|
|
52
|
+
* if (browser.isChromium) {
|
|
53
|
+
* // Any Chromium-based browser (Chrome, Edge, Brave, Arc, etc.)
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
*/
|
|
57
|
+
export function useBrowserDetect(): BrowserInfo {
|
|
58
|
+
return useMemo(() => {
|
|
59
|
+
if (typeof window === 'undefined') {
|
|
60
|
+
return {
|
|
61
|
+
isChrome: false,
|
|
62
|
+
isChromium: false,
|
|
63
|
+
isSafari: false,
|
|
64
|
+
isFirefox: false,
|
|
65
|
+
isEdge: false,
|
|
66
|
+
isOpera: false,
|
|
67
|
+
isBrave: false,
|
|
68
|
+
isArc: false,
|
|
69
|
+
isVivaldi: false,
|
|
70
|
+
isYandex: false,
|
|
71
|
+
isSamsungBrowser: false,
|
|
72
|
+
isUCBrowser: false,
|
|
73
|
+
browserName: 'unknown',
|
|
74
|
+
isWebKit: false,
|
|
75
|
+
isBlink: false,
|
|
76
|
+
isGecko: false,
|
|
77
|
+
userAgent: '',
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const ua = window.navigator.userAgent.toLowerCase();
|
|
82
|
+
|
|
83
|
+
// Check for specific browsers first (most specific to least specific)
|
|
84
|
+
|
|
85
|
+
// Edge (Chromium-based)
|
|
86
|
+
const isEdge = ua.includes('edg/') || ua.includes('edge/');
|
|
87
|
+
|
|
88
|
+
// Brave (check for Brave-specific API)
|
|
89
|
+
const isBrave = !!(window.navigator as any).brave;
|
|
90
|
+
|
|
91
|
+
// Arc (check for Arc-specific markers in UA)
|
|
92
|
+
const isArc = ua.includes('arc/');
|
|
93
|
+
|
|
94
|
+
// Vivaldi
|
|
95
|
+
const isVivaldi = ua.includes('vivaldi');
|
|
96
|
+
|
|
97
|
+
// Yandex Browser
|
|
98
|
+
const isYandex = ua.includes('yabrowser');
|
|
99
|
+
|
|
100
|
+
// Samsung Internet
|
|
101
|
+
const isSamsungBrowser = ua.includes('samsungbrowser');
|
|
102
|
+
|
|
103
|
+
// UC Browser
|
|
104
|
+
const isUCBrowser = ua.includes('ucbrowser') || ua.includes('uc browser');
|
|
105
|
+
|
|
106
|
+
// Opera (modern Chromium-based)
|
|
107
|
+
const isOpera = ua.includes('opr/') || ua.includes('opera');
|
|
108
|
+
|
|
109
|
+
// Chrome (not Edge, not other Chromium browsers)
|
|
110
|
+
const isChrome = ua.includes('chrome') &&
|
|
111
|
+
!isEdge &&
|
|
112
|
+
!isOpera &&
|
|
113
|
+
!isYandex &&
|
|
114
|
+
!isSamsungBrowser &&
|
|
115
|
+
!isVivaldi &&
|
|
116
|
+
!isArc &&
|
|
117
|
+
!isBrave;
|
|
118
|
+
|
|
119
|
+
// Firefox
|
|
120
|
+
const isFirefox = ua.includes('firefox') && !ua.includes('seamonkey');
|
|
121
|
+
|
|
122
|
+
// Safari (real Safari, not Chromium pretending to be Safari)
|
|
123
|
+
// Safari will have 'safari' in UA but NOT 'chrome' or 'chromium'
|
|
124
|
+
// Real Safari uses WebKit engine
|
|
125
|
+
// Additional check: Safari has 'version/' in UA, Chromium browsers don't combine it with Safari
|
|
126
|
+
const hasSafariUA = ua.includes('safari');
|
|
127
|
+
const hasChrome = ua.includes('chrome') || ua.includes('crios');
|
|
128
|
+
const hasVersion = ua.includes('version/'); // Real Safari includes Version/XX.X
|
|
129
|
+
const isSafari = hasSafariUA && !hasChrome && hasVersion;
|
|
130
|
+
|
|
131
|
+
// Chromium detection (any browser using Chromium/Blink engine)
|
|
132
|
+
// If it has "chrome" in UA or is one of the known Chromium browsers
|
|
133
|
+
const isChromium = hasChrome ||
|
|
134
|
+
isEdge ||
|
|
135
|
+
isOpera ||
|
|
136
|
+
isYandex ||
|
|
137
|
+
isSamsungBrowser ||
|
|
138
|
+
isVivaldi ||
|
|
139
|
+
isArc ||
|
|
140
|
+
isBrave ||
|
|
141
|
+
isUCBrowser;
|
|
142
|
+
|
|
143
|
+
// Engine detection
|
|
144
|
+
const isWebKit = !isChromium && isSafari;
|
|
145
|
+
const isBlink = isChromium;
|
|
146
|
+
const isGecko = isFirefox;
|
|
147
|
+
|
|
148
|
+
// Determine browser name
|
|
149
|
+
let browserName = 'unknown';
|
|
150
|
+
if (isBrave) browserName = 'Brave';
|
|
151
|
+
else if (isArc) browserName = 'Arc';
|
|
152
|
+
else if (isVivaldi) browserName = 'Vivaldi';
|
|
153
|
+
else if (isYandex) browserName = 'Yandex';
|
|
154
|
+
else if (isSamsungBrowser) browserName = 'Samsung Internet';
|
|
155
|
+
else if (isUCBrowser) browserName = 'UC Browser';
|
|
156
|
+
else if (isEdge) browserName = 'Edge';
|
|
157
|
+
else if (isOpera) browserName = 'Opera';
|
|
158
|
+
else if (isChrome) browserName = 'Chrome';
|
|
159
|
+
else if (isSafari) browserName = 'Safari';
|
|
160
|
+
else if (isFirefox) browserName = 'Firefox';
|
|
161
|
+
|
|
162
|
+
return {
|
|
163
|
+
isChrome,
|
|
164
|
+
isChromium,
|
|
165
|
+
isSafari,
|
|
166
|
+
isFirefox,
|
|
167
|
+
isEdge,
|
|
168
|
+
isOpera,
|
|
169
|
+
isBrave,
|
|
170
|
+
isArc,
|
|
171
|
+
isVivaldi,
|
|
172
|
+
isYandex,
|
|
173
|
+
isSamsungBrowser,
|
|
174
|
+
isUCBrowser,
|
|
175
|
+
browserName,
|
|
176
|
+
isWebKit,
|
|
177
|
+
isBlink,
|
|
178
|
+
isGecko,
|
|
179
|
+
userAgent: window.navigator.userAgent,
|
|
180
|
+
};
|
|
181
|
+
}, []);
|
|
182
|
+
}
|