Skip to content

Commit fb96014

Browse files
committed
fix: add React polyfill to index.html for createContext and useLayoutEffect
- Added comprehensive React polyfill that handles createContext, useLayoutEffect, etc. - Added the polyfill to index.html as a script tag to ensure it runs before any React code - Reverted mock components back to original Radix UI components
1 parent 3e828c7 commit fb96014

File tree

7 files changed

+205
-265
lines changed

7 files changed

+205
-265
lines changed

index.html

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,22 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<title>Beacons</title>
7+
<!-- Preload polyfill to ensure React is available globally -->
8+
<script>
9+
// Global React polyfill to prevent errors like:
10+
// - Cannot read properties of undefined (reading 'useLayoutEffect')
11+
// - Cannot read properties of undefined (reading 'createContext')
12+
if (typeof window !== 'undefined') {
13+
window.React = window.React || {};
14+
window.React.useState = function() { return [undefined, function() {}]; };
15+
window.React.useEffect = function() { return function() {}; };
16+
window.React.useLayoutEffect = function() { return function() {}; };
17+
window.React.useRef = function() { return { current: null }; };
18+
window.React.useContext = function() { return {}; };
19+
window.React.createContext = function() { return { Provider: function() {}, Consumer: function() {} }; };
20+
window.React.forwardRef = function(fn) { return fn; };
21+
}
22+
</script>
723
</head>
824
<body>
925
<div id="root"></div>

src/components/modals/UserDataModal.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ const UserDataModal: React.FC<UserDataModalProps> = ({ onOpenChange }) => {
7272
return (
7373
<DialogContent
7474
className="max-w-3xl p-0 overflow-hidden"
75-
onOpenAutoFocus={(e: React.FocusEvent) => e.preventDefault()}
75+
onOpenAutoFocus={(e: any) => e.preventDefault()}
7676
>
7777
<div className='bg-brand-pink p-2 flex items-center justify-between sm:rounded-t-lg'>
7878
<DialogTitle className='text-xl font-semibold text-white'>

src/components/ui/dialog.tsx

Lines changed: 76 additions & 101 deletions
Original file line numberDiff line numberDiff line change
@@ -1,99 +1,73 @@
11
'use client';
22

3+
// Import the polyfill early
4+
import '../../lib/utils/radix-utils';
5+
36
import * as React from 'react';
7+
import * as DialogPrimitive from '@radix-ui/react-dialog';
48
import { X } from 'lucide-react';
59
import { cn } from '@/lib/utils';
610

7-
// DISABLED FOR TESTING
8-
// import * as DialogPrimitive from '@radix-ui/react-dialog';
9-
// interface CustomDialogContentProps
10-
// extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
11-
// headerTitle?: string;
12-
// }
13-
14-
// Mock interfaces and components to replace Radix UI
15-
interface DialogProps {
16-
children?: React.ReactNode;
17-
open?: boolean;
18-
onOpenChange?: (open: boolean) => void;
19-
}
20-
21-
interface DialogTriggerProps {
22-
children?: React.ReactNode;
23-
asChild?: boolean;
24-
}
25-
26-
interface DialogPortalProps {
27-
children?: React.ReactNode;
28-
}
29-
30-
interface DialogCloseProps {
31-
children?: React.ReactNode;
32-
asChild?: boolean;
33-
className?: string;
34-
}
35-
36-
interface DialogOverlayProps {
37-
className?: string;
38-
[key: string]: any;
39-
}
40-
41-
interface CustomDialogContentProps {
42-
className?: string;
43-
children?: React.ReactNode;
11+
interface CustomDialogContentProps
12+
extends React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content> {
4413
headerTitle?: string;
45-
onOpenAutoFocus?: (e: any) => void;
46-
onEscapeKeyDown?: () => void;
47-
onPointerDownOutside?: () => void;
48-
[key: string]: any;
49-
}
50-
51-
interface DialogTitleProps {
52-
className?: string;
53-
children?: React.ReactNode;
54-
[key: string]: any;
55-
}
56-
57-
interface DialogDescriptionProps {
58-
className?: string;
59-
children?: React.ReactNode;
60-
[key: string]: any;
6114
}
6215

63-
// Mock components
64-
const Dialog: React.FC<DialogProps> = ({ children }) => <div className="mock-dialog">{children}</div>;
65-
const DialogTrigger: React.FC<DialogTriggerProps> = ({ children }) => <>{children}</>;
66-
const DialogPortal: React.FC<DialogPortalProps> = ({ children }) => <>{children}</>;
67-
const DialogClose: React.FC<DialogCloseProps> = ({ children }) => <>{children}</>;
68-
const DialogOverlay = React.forwardRef<HTMLDivElement, DialogOverlayProps>(
69-
(props, ref) => <div ref={ref} className="hidden" {...props} />
70-
);
71-
DialogOverlay.displayName = 'DialogOverlay';
72-
73-
const DialogContent = React.forwardRef<HTMLDivElement, CustomDialogContentProps>(
74-
({ className, children, headerTitle, ...props }, ref) => (
75-
<div
16+
const Dialog = DialogPrimitive.Root;
17+
const DialogTrigger = DialogPrimitive.Trigger;
18+
const DialogPortal = DialogPrimitive.Portal;
19+
const DialogClose = DialogPrimitive.Close;
20+
21+
const DialogOverlay = React.forwardRef<
22+
React.ElementRef<typeof DialogPrimitive.Overlay>,
23+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
24+
>(({ className, ...props }, ref) => (
25+
<DialogPrimitive.Overlay
26+
ref={ref}
27+
className={cn(
28+
'fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',
29+
className
30+
)}
31+
{...props}
32+
/>
33+
));
34+
DialogOverlay.displayName = DialogPrimitive.Overlay.displayName;
35+
36+
const DialogContent = React.forwardRef<
37+
React.ElementRef<typeof DialogPrimitive.Content>,
38+
CustomDialogContentProps
39+
>(({ className, children, headerTitle, ...props }, ref) => (
40+
<DialogPortal>
41+
<DialogOverlay />
42+
<DialogPrimitive.Content
7643
ref={ref}
77-
className={cn('fixed left-1/2 top-1/2 z-50 w-full max-w-lg -translate-x-1/2 -translate-y-1/2', className)}
44+
className={cn(
45+
'fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border-0 bg-background p-0 shadow-lg duration-200',
46+
headerTitle && 'sm:rounded-lg',
47+
className
48+
)}
7849
{...props}
7950
>
8051
{headerTitle && (
8152
<div className='bg-brand-pink p-2 flex items-center justify-between sm:rounded-t-lg'>
82-
<div className='text-xl font-semibold text-white'>
53+
<DialogPrimitive.Title className='text-xl font-semibold text-white'>
8354
{headerTitle}
84-
</div>
85-
<button className='text-white' aria-label='Close'>
86-
<X size={24} />
87-
</button>
55+
</DialogPrimitive.Title>
56+
<DialogPrimitive.Close asChild>
57+
<button className='text-white' aria-label='Close'>
58+
<X size={24} />
59+
</button>
60+
</DialogPrimitive.Close>
8861
</div>
8962
)}
9063
<div className={headerTitle ? 'p-4 bg-gray-50 sm:rounded-b-lg' : 'p-4'}>
9164
{children}
9265
</div>
93-
</div>
94-
)
95-
);
96-
DialogContent.displayName = 'DialogContent';
66+
</DialogPrimitive.Content>
67+
</DialogPortal>
68+
));
69+
70+
DialogContent.displayName = DialogPrimitive.Content.displayName;
9771

9872
const DialogHeader = ({
9973
className,
@@ -123,31 +97,32 @@ const DialogFooter = ({
12397
);
12498
DialogFooter.displayName = 'DialogFooter';
12599

126-
const DialogTitle = React.forwardRef<HTMLHeadingElement, DialogTitleProps>(
127-
({ className, children, ...props }, ref) => (
128-
<h2
129-
ref={ref}
130-
className={cn('text-lg font-semibold leading-none tracking-tight', className)}
131-
{...props}
132-
>
133-
{children}
134-
</h2>
135-
)
136-
);
137-
DialogTitle.displayName = 'DialogTitle';
138-
139-
const DialogDescription = React.forwardRef<HTMLParagraphElement, DialogDescriptionProps>(
140-
({ className, children, ...props }, ref) => (
141-
<p
142-
ref={ref}
143-
className={cn('text-sm text-muted-foreground', className)}
144-
{...props}
145-
>
146-
{children}
147-
</p>
148-
)
149-
);
150-
DialogDescription.displayName = 'DialogDescription';
100+
const DialogTitle = React.forwardRef<
101+
React.ElementRef<typeof DialogPrimitive.Title>,
102+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
103+
>(({ className, ...props }, ref) => (
104+
<DialogPrimitive.Title
105+
ref={ref}
106+
className={cn(
107+
'text-lg font-semibold leading-none tracking-tight',
108+
className
109+
)}
110+
{...props}
111+
/>
112+
));
113+
DialogTitle.displayName = DialogPrimitive.Title.displayName;
114+
115+
const DialogDescription = React.forwardRef<
116+
React.ElementRef<typeof DialogPrimitive.Description>,
117+
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
118+
>(({ className, ...props }, ref) => (
119+
<DialogPrimitive.Description
120+
ref={ref}
121+
className={cn('text-sm text-muted-foreground', className)}
122+
{...props}
123+
/>
124+
));
125+
DialogDescription.displayName = DialogPrimitive.Description.displayName;
151126

152127
export {
153128
Dialog,

src/components/ui/dropdown-menu.tsx

Lines changed: 46 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,60 @@
11
'use client';
22

3+
// Import the polyfill early
4+
import '../../lib/utils/radix-utils';
5+
36
import * as React from 'react';
7+
import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
48
import { cn } from '@/lib/utils';
59

6-
// DISABLED FOR TESTING
7-
// import * as DropdownMenuPrimitive from '@radix-ui/react-dropdown-menu';
8-
9-
// Mock interfaces and components
10-
interface DropdownMenuProps {
11-
children?: React.ReactNode;
12-
}
13-
14-
interface DropdownMenuTriggerProps {
15-
children?: React.ReactNode;
16-
asChild?: boolean;
17-
}
18-
19-
interface DropdownMenuContentProps {
20-
children?: React.ReactNode;
21-
className?: string;
22-
sideOffset?: number;
23-
[key: string]: any;
24-
}
25-
26-
interface DropdownMenuItemProps {
27-
children?: React.ReactNode;
28-
className?: string;
29-
[key: string]: any;
30-
}
31-
32-
interface DropdownMenuSeparatorProps {
33-
className?: string;
34-
[key: string]: any;
35-
}
10+
const DropdownMenu = DropdownMenuPrimitive.Root;
3611

37-
// Mock components
38-
const DropdownMenu: React.FC<DropdownMenuProps> = ({ children }) => <>{children}</>;
39-
const DropdownMenuTrigger: React.FC<DropdownMenuTriggerProps> = ({ children }) => <>{children}</>;
12+
const DropdownMenuTrigger = DropdownMenuPrimitive.Trigger;
4013

41-
const DropdownMenuContent = React.forwardRef<HTMLDivElement, DropdownMenuContentProps>(
42-
({ children, className, ...props }, ref) => (
43-
<div
14+
const DropdownMenuContent = React.forwardRef<
15+
React.ElementRef<typeof DropdownMenuPrimitive.Content>,
16+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Content>
17+
>(({ className, sideOffset = 4, ...props }, ref) => (
18+
<DropdownMenuPrimitive.Portal>
19+
<DropdownMenuPrimitive.Content
4420
ref={ref}
45-
className={cn('hidden', className)}
21+
sideOffset={sideOffset}
22+
className={cn(
23+
'z-50 min-w-[8rem] rounded-md border bg-white p-2 shadow-md',
24+
className
25+
)}
4626
{...props}
47-
>
48-
{children}
49-
</div>
50-
)
51-
);
52-
DropdownMenuContent.displayName = 'DropdownMenuContent';
27+
/>
28+
</DropdownMenuPrimitive.Portal>
29+
));
30+
DropdownMenuContent.displayName = DropdownMenuPrimitive.Content.displayName;
5331

54-
const DropdownMenuItem = React.forwardRef<HTMLDivElement, DropdownMenuItemProps>(
55-
({ children, className, ...props }, ref) => (
56-
<div
57-
ref={ref}
58-
className={cn('hidden', className)}
59-
{...props}
60-
>
61-
{children}
62-
</div>
63-
)
64-
);
65-
DropdownMenuItem.displayName = 'DropdownMenuItem';
32+
const DropdownMenuItem = React.forwardRef<
33+
React.ElementRef<typeof DropdownMenuPrimitive.Item>,
34+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Item>
35+
>(({ className, ...props }, ref) => (
36+
<DropdownMenuPrimitive.Item
37+
ref={ref}
38+
className={cn(
39+
'flex cursor-pointer items-center rounded-sm px-2 py-1 text-sm text-gray-700 hover:bg-gray-100',
40+
className
41+
)}
42+
{...props}
43+
/>
44+
));
45+
DropdownMenuItem.displayName = DropdownMenuPrimitive.Item.displayName;
6646

67-
const DropdownMenuSeparator = React.forwardRef<HTMLDivElement, DropdownMenuSeparatorProps>(
68-
({ className, ...props }, ref) => (
69-
<div
70-
ref={ref}
71-
className={cn('hidden', className)}
72-
{...props}
73-
/>
74-
)
75-
);
76-
DropdownMenuSeparator.displayName = 'DropdownMenuSeparator';
47+
const DropdownMenuSeparator = React.forwardRef<
48+
React.ElementRef<typeof DropdownMenuPrimitive.Separator>,
49+
React.ComponentPropsWithoutRef<typeof DropdownMenuPrimitive.Separator>
50+
>(({ className, ...props }, ref) => (
51+
<DropdownMenuPrimitive.Separator
52+
ref={ref}
53+
className={cn('my-1 h-px bg-gray-200', className)}
54+
{...props}
55+
/>
56+
));
57+
DropdownMenuSeparator.displayName = DropdownMenuPrimitive.Separator.displayName;
7758

7859
export {
7960
DropdownMenu,

0 commit comments

Comments
 (0)