cssreactjsformsmaterial-uifrontend

Box within an input is always showing up in MUI TextField


I have a form that is using MUI Form within a Dialog and for some reason the TextField will never have the standard variant look. It always has the border of a filled. Making it weirder is that I tried to add an Input from the NextUi library and I could not get rid of a box within the Input (I assume forced to be there from global mui styles?). Every single TextField I put anywhere on my website has this and even the Autocomplete component has this as well. Is this global mui styles effecting this? I cannot override it with any styling I have tried.

This is the Form (Just the base taken right from MUI docs as you can see that Standard one is not standard):

import * as React from 'react';
import Box from '@mui/material/Box';
import TextField from '@mui/material/TextField';

export default function AddInfoForm() {
    return (
        <Box
            component="form"
            sx={{
                '& > :not(style)': { m: 1, width: '25ch' },
            }}
            noValidate
            autoComplete="off"
        >
            <TextField id="outlined-basic" label="Outlined" variant="outlined" />
            <TextField id="filled-basic" label="Filled" variant="filled" />
            <TextField id="standard-basic" label="Standard" variant="standard" />
        </Box>
    );
}

This is the component its in (I know its a mess right now):

import { useState, useRef } from 'react';
import { GoogleAuthProvider, signInWithPopup, RecaptchaVerifier, signInWithPhoneNumber } from 'firebase/auth';
import { auth } from '../../utils/Auth/FirebaseConfig';
import { Stepper, Step, StepLabel, Button, Typography, SvgIcon, TextField, Box, Modal, Dialog, DialogContent, useMediaQuery, useTheme, CssBaseline } from '@mui/material';
import { makeStyles } from '@mui/styles';
import AuthService from '../../services/auth.service';
import 'react-phone-number-input/style.css'
import PhoneInput from 'react-phone-number-input'
import AddInfoForm from './AddInfoForm';

const useStyles = makeStyles((theme) => ({
    googleButton: {
        userSelect: 'none',
        WebkitAppearance: 'none',
        backgroundColor: 'white',
        backgroundImage: 'none',
        border: '1px solid #747775',
        borderRadius: '4px',
        boxSizing: 'border-box',
        color: '#1f1f1f',
        cursor: 'pointer',
        fontFamily: "'Roboto', arial, sans-serif",
        fontSize: '14px',
        height: '40px',
        letterSpacing: '0.25px',
        outline: 'none',
        overflow: 'hidden',
        padding: '0 12px',
        position: 'relative',
        textAlign: 'center',
        transition: 'background-color .218s, border-color .218s, box-shadow .218s',
        verticalAlign: 'middle',
        whiteSpace: 'nowrap',
        maxWidth: '400px',
        minWidth: 'min-content',
        '&:hover': {
            boxShadow: '0 1px 2px 0 rgba(60, 64, 67, .30), 0 1px 3px 1px rgba(60, 64, 67, .15)'
        },
        // other styles for different states
    },
    googleIcon: {
        height: '20px',
        marginRight: '12px',
        minWidth: '20px',
        width: '20px'
    },
    // other styles for different parts of the button
}));

// Define the steps
const steps = ['Personal Information', 'Contact Information', 'Account Preferences', 'Security Settings', 'Terms and Agreements'];

// Define a component for each step
const StepContent = ({ step }) => {
    switch (step) {
        case 0:
            return <div>Personal Information Form</div>; // Replace with your form component
        case 1:
            return <div>Contact Information Form</div>; // Replace with your form component
        case 2:
            return <div>Account Preferences Form</div>; // Replace with your form component
        case 3:
            return <div>Security Settings Form</div>; // Replace with your form component
        case 4:
            return <div>Terms and Agreements</div>; // Replace with your form component
        default:
            return <div>Unknown Step</div>;
    }
};

const Signup = () => {
    const [isFormModalOpen, setIsFormModalOpen] = useState(true);
    const [formStep, setFormStep] = useState(0);
    const [phoneNumber, setPhoneNumber] = useState('');
    const [verificationCode, setVerificationCode] = useState('');
    const [isModalOpen, setIsModalOpen] = useState(false);
    const [type, setType] = useState('');
    const recaptchaVerifier = useRef(null);

    const openMultiStepForm = () => {
        setIsFormModalOpen(true);
        setFormStep(0); // Start from the first step
    };

    const handleGoogleSignUp = async () => {
        const provider = new GoogleAuthProvider();
        try {
            const result = await signInWithPopup(auth, provider);
            const user = result.user;
            setType('google');
            sendUserToBackend(user);
        } catch (error) {
            // Handle Errors here.
            console.error(error);
        }
    };

    const sendUserToBackend = async (user) => {
        const email = user.email;
        const displayName = user.displayName;
        const uid = user.uid;
        const phoneNumber = user.phoneNumber
        try {
            // Check if the user already exists in MongoDB
            const existingUser = await AuthService.checkIfUserExists(uid);
            console.log(existingUser)

            if (existingUser.data.message === 'User not found') {
                // If user does not exist, create a new user in MongoDB
                const response = await AuthService.createFirebaseUser(email, displayName, uid, type, phoneNumber);
                if (response.status === 200) {
                    openMultiStepForm();
                }

                console.log('New user created in backend:', response.data);
            } else {
                console.log('User already exists, signed in successfully');
            }
        } catch (error) {
            console.error('Error handling user data:', error);
        }
    };

    const setUpRecaptcha = () => {
        window.recaptchaVerifier = new RecaptchaVerifier('sign-in-button', {
            'size': 'invisible',
            'callback': (response) => {
                // reCAPTCHA solved, allow phone sign in
                handleSMSLogin();
            }
        }, auth);
    };

    const handleSMSLogin = async () => {
        setType('phone')
        if (!recaptchaVerifier.current) {
            recaptchaVerifier.current = new RecaptchaVerifier(auth, 'sign-in-button', {
                'size': 'invisible',
                'callback': (response) => {
                    // reCAPTCHA solved, allow phone sign in
                }
            });
        }

        const appVerifier = recaptchaVerifier.current;
        try {
            const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, appVerifier);
            window.confirmationResult = confirmationResult;
            setIsModalOpen(true); // Open the modal for verification code input
        } catch (error) {
            console.error("Error during SMS authentication", error);
        }
    };

    // const handleSMSLogin = async () => {
    //     setUpRecaptcha();
    //     const appVerifier = recaptchaVerifier.current;
    //     try {
    //         const confirmationResult = await signInWithPhoneNumber(auth, phoneNumber, appVerifier);
    //         window.confirmationResult = confirmationResult;
    //         setIsModalOpen(true); // Open the modal for verification code input
    //     } catch (error) {
    //         console.error("Error during SMS authentication", error);
    //     }
    // };

    const verifyCode = async () => {
        try {
            const result = await window.confirmationResult.confirm(verificationCode);
            const user = result.user;
            setType('phone');
            sendUserToBackend(user);
            setIsModalOpen(false); // Close the modal after verification
        } catch (error) {
            console.error("Error verifying the code", error);
        }
    };

    // Google Icon as an SVG component
    const GoogleIcon = (props) => (
        <SvgIcon viewBox="0 0 48 48">
            <path fill="#EA4335" d="M24 9.5c3.54 0 6.71 1.22 9.21 3.6l6.85-6.85C35.9 2.38 30.47 0 24 0 14.62 0 6.51 5.38 2.56 13.22l7.98 6.19C12.43 13.72 17.74 9.5 24 9.5z"></path>
            <path fill="#4285F4" d="M46.98 24.55c0-1.57-.15-3.09-.38-4.55H24v9.02h12.94c-.58 2.96-2.26 5.48-4.78 7.18l7.73 6c4.51-4.18 7.09-10.36 7.09-17.65z"></path>
            <path fill="#FBBC05" d="M10.53 28.59c-.48-1.45-.76-2.99-.76-4.59s.27-3.14.76-4.59l-7.98-6.19C.92 16.46 0 20.12 0 24c0 3.88.92 7.54 2.56 10.78l7.97-6.19z"></path>
            <path fill="#34A853" d="M24 48c6.48 0 11.93-2.13 15.89-5.81l-7.73-6c-2.15 1.45-4.92 2.3-8.16 2.3-6.26 0-11.57-4.22-13.47-9.91l-7.98 6.19C6.51 42.62 14.62 48 24 48z"></path>
            <path fill="none" d="M0 0h48v48H0z"></path>
        </SvgIcon>
    );

    const MultiStepForm = () => {
        const [activeStep, setActiveStep] = useState(0);
        const [open, setOpen] = useState(true);
        const theme = useTheme();
        const fullScreen = useMediaQuery(theme.breakpoints.down('md'));
        const isLastStep = activeStep === steps.length - 1;

        const handleClose = () => {
            setOpen(false);
        };

        const handleNext = () => {
            setActiveStep((prevActiveStep) => prevActiveStep + 1);
        };

        const handleBack = () => {
            setActiveStep((prevActiveStep) => prevActiveStep - 1);
        };


        const handleSubmit = () => {
            // Handle final form submission
            setIsFormModalOpen(false);
        };

        return (
            <>
                <CssBaseline />
                <Dialog
                    fullScreen={fullScreen}
                    open={open}
                    onClose={handleClose}
                    aria-labelledby="responsive-dialog-title"
                >
                    <Box sx={{ width: '100%' }}>
                        <Stepper activeStep={activeStep}>
                            {steps.map((label) => (
                                <Step key={label}>
                                    <StepLabel>{label}</StepLabel>
                                </Step>
                            ))}
                        </Stepper>
                        <div>
                            {activeStep === steps.length ? (
                                <div>
                                    <Typography sx={{ mt: 2, mb: 1 }}>
                                        All steps completed - you&apos;re finished
                                    </Typography>
                                    <Button onClick={() => setActiveStep(0)}>Reset</Button>
                                </div>
                            ) : (
                                <div>
                                    <Typography sx={{ mt: 2, mb: 1 }}>Step {activeStep + 1}</Typography>
                                    <StepContent step={activeStep} />

                                    {/* Content */}
                                    <DialogContent>
                                        <AddInfoForm />
                                    </DialogContent>
                                    <Box sx={{ display: 'flex', flexDirection: 'row', pt: 2 }}>
                                        <Button
                                            color="inherit"
                                            disabled={activeStep === 0}
                                            onClick={handleBack}
                                            sx={{ mr: 1 }}
                                        >
                                            Back
                                        </Button>
                                        <Box sx={{ flex: '1 1 auto' }} />
                                        <Button onClick={handleNext}>
                                            {activeStep === steps.length - 1 ? 'Finish' : 'Next'}
                                        </Button>
                                    </Box>
                                </div>
                            )}
                        </div>
                    </Box>
                </Dialog>
            </>
        );
    };

    const classes = useStyles();

    return (
        <>
            <Box sx={{ display: 'flex', flexDirection: 'column' }}>
                <PhoneInput
                    placeholder="Phone number"
                    value={phoneNumber}
                    onChange={(newPhoneNumber) => setPhoneNumber(newPhoneNumber)} />
                {/* <TextField
                    label="Phone Number"
                    value={phoneNumber}
                    onChange={(e) => setPhoneNumber(e.target.value)}
                    fullWidth
                    margin="normal"
                /> */}
                <Button onClick={handleSMSLogin} id="sign-in-button">Continue</Button>
                <Button
                    variant="contained"
                    className={classes.googleButton}
                    startIcon={<GoogleIcon className={classes.googleIcon} />}
                    onClick={handleGoogleSignUp}
                >
                    Sign in with Google
                </Button>
            </Box>
            {/* VERIFICATION MODAL */}
            <Modal
                open={isModalOpen}
                onClose={() => setIsModalOpen(false)}
                aria-labelledby="sms-verification-modal"
                aria-describedby="modal-for-sms-code-verification"
            >
                <Box className={classes.modal}>
                    <h2 id="sms-verification-modal">Enter Verification Code</h2>
                    <TextField
                        label="Verification Code"
                        value={verificationCode}
                        onChange={(e) => setVerificationCode(e.target.value)}
                        fullWidth
                        margin="normal"
                    />
                    <Button onClick={verifyCode}>Verify Code</Button>
                </Box>
            </Modal>

            <MultiStepForm />
        </>
    );
};

export default Signup;

This is the index.js to wrap my app:

import { useEffect } from "react";
import App from './App';
import ReactDOM from 'react-dom';
import { BrowserRouter } from "react-router-dom";
import { ThemeProvider, createTheme } from "@mui/material";
import StyledEngineProvider from "@mui/material/StyledEngineProvider";
import { NextUIProvider } from '@nextui-org/react'
import { QueryClient, QueryClientProvider } from "react-query";
import { UploadProvider } from './services/UploadContext';
import { HistoryProvider } from "./services/HistoryContext";
import { FirebaseProvider } from "./utils/Auth/FirebaseContext";

const delay = () => import(`mapbox-gl/dist/mapbox-gl.css`)
setTimeout(() => delay(), 100);


const initGA = async () => {
  if (process.env.NODE_ENV === 'production') {
    const { default: ReactGA } = await import("react-ga4");
    ReactGA.initialize("G-*******");
  }
};

const theme = createTheme({
  buttons: {
    booking: 'success'
  },
  typography: {
    fontFamily: "'Quicksand', sans-serif",
  },
});

const queryClient = new QueryClient();

const MainApp = () => {
  useEffect(() => {
    initGA();
  }, []);
  return (
    <QueryClientProvider client={queryClient}>
      <StyledEngineProvider injectFirst>
        <NextUIProvider>
          <ThemeProvider theme={theme}>
            <BrowserRouter>
              <HistoryProvider>
                <UploadProvider>
                  <FirebaseProvider>
                    <App />
                  </FirebaseProvider>
                </UploadProvider>
              </HistoryProvider>
            </BrowserRouter>
          </ThemeProvider>
        </NextUIProvider>
      </StyledEngineProvider>
    </QueryClientProvider>
  )
};

const rootElement = document.getElementById('root');
if (rootElement.hasChildNodes()) {
  ReactDOM.hydrate(<MainApp />, rootElement);
} else {
  ReactDOM.render(<MainApp />, rootElement);
}


// ReactDOM.render(<MainApp />, document.getElementById('root'));

Attached is how the form looks currently:

Any help is greatly appreciated!

I tried to override it with inline styles or sx and that did not have any effect. I tried to comment out the NextUi provider and that did not work. I tried makeStyles and it worked for some things but did not have the desired result. I tried to use CssBaseline and that did not work. I tried to override from the main theme and that did not work.


Solution

  • Just an update, I figured it out. I was importing a second form by accident where this form was being used. That caused a styling issue.