admin管理员组

文章数量:1289383

I’m building a React Native/Expo app that uses a custom Dialog component based on @rn-primitives/dialog to display a modal. For most users, the dialog renders correctly. However, some users on certain Android devices (all large-screen or tablet-like devices, e.g. Samsung Galaxy S24+, Xiaomi Redmi Note 12, etc.) only see the dimmed background but not the dialog content.

Here’s the relevant code for my custom Dialog component:

import * as DialogPrimitive from "@rn-primitives/dialog";
import { StyleSheet, useWindowDimensions, View } from "react-native";
import { cn } from "@/utils";
import {
  type ComponentPropsWithoutRef,
  type ElementRef,
  forwardRef,
  type ReactNode,
} from "react";
import { IconX } from "@tabler/icons-react-native";
import { colors } from "@/styles";
import { MotiView } from "moti";

const Dialog = DialogPrimitive.Root;
const DialogTrigger = DialogPrimitive.Trigger;
const DialogPortal = DialogPrimitive.Portal;
const DialogClose = DialogPrimitive.Close;

const DialogOverlay = forwardRef<
  ElementRef<typeof DialogPrimitive.Overlay>,
  ComponentPropsWithoutRef<typeof DialogPrimitive.Overlay>
>(({ className, children, ...props }, ref) => {
  return (
    <DialogPrimitive.Overlay
      style={StyleSheet.absoluteFill}
      className={cn(
        "z-50 flex bg-black/80 justify-center items-center p-2",
        className
      )}
      {...props}
      ref={ref}
    >
      <MotiView
        from={{ top: 16, opacity: 0 }}
        animate={{ top: 0, opacity: 1 }}
        transition={{ type: "spring" }}
      >
        {children as ReactNode}
      </MotiView>
    </DialogPrimitive.Overlay>
  );
});
DialogOverlay.displayName = "DialogOverlay";

const DialogContent = forwardRef<
  ElementRef<typeof DialogPrimitive.Content>,
  ComponentPropsWithoutRef<typeof DialogPrimitive.Content> & {
    portalHost?: string;
    isBottomSheet?: boolean;
    hasCloseButton?: boolean;
  }
>(
  (
    {
      className,
      children,
      portalHost,
      isBottomSheet,
      hasCloseButton = true,
      ...props
    },
    ref
  ) => {
    const { width } = useWindowDimensions();

    return (
      <DialogPortal hostName={portalHost}>
        <DialogOverlay
          className={cn(isBottomSheet && "justify-end")}
          closeOnPress={hasCloseButton}
        >
          <DialogPrimitive.Content
            ref={ref}
            style={{ width: isBottomSheet ? width : undefined }}
            className={cn(
              "z-50 gap-4 p-6 items-center bg-white shadow-lg rounded-2xl",
              className
            )}
            {...props}
          >
            {isBottomSheet && (
              <View className="w-9 h-1 absolute top-2 rounded-full bg-gray-500" />
            )}

            {children}

            {hasCloseButton && (
              <DialogPrimitive.Close className="absolute right-4 top-4 items-center justify-center size-8 bg-gray-200 rounded-full">
                <IconX size={18} color={colors.gray[700]} />
              </DialogPrimitive.Close>
            )}
          </DialogPrimitive.Content>
        </DialogOverlay>
      </DialogPortal>
    );
  }
);
DialogContent.displayName = DialogPrimitive.Content.displayName;

/* Header, Footer, Title, Description omitted for brevity, 
   but they're just basic forwardRef wrappers around 
   DialogPrimitive components */

export {
  Dialog,
  DialogClose,
  DialogContent,
  /* ...other exports */
};

本文标签: javascriptReact Native Modal (Dialog) Not Rendering on Certain Android DevicesStack Overflow