Home > database >  Changing Bullet point list to Checkbox after conditions have been met
Changing Bullet point list to Checkbox after conditions have been met

Time:10-05

I'm trying to create a password validator with certain regex condition in material UI that changes from bullet point to checkbox when conditions are met. enter image description here

So far I've tried using the npm library: NiceInputPassword however this doesn't let me change the state as easily so I'm going back to my regular Material UI. I've read documentation on lists in material UI but I couldn't find anything that allows me to change bullet points to checkboxes as shown in the image.

CodePudding user response:

There are a few bits to this to achieve your outcome using the libraries and components, so I'll try to explain as best I can.

React-Nice-Input-Password accepts a prop to provide a custom class name for each of the states and specifically for success you can use <NiceInputPassword successClassName="custom-success". With that added you are now able to style the bullet points and by using the same CSS selectors with your own custom-success name you can set the final style, .input-password__description li.custom-success:before. Note you may be able to provide a less specific selector but I didn't investigate this.

Now for the styles comes the interesting part. Set background-color: transparent so you don't see the current style applied, then add a background image with a Edit ReactNiceInputPassword (forked)

Supporting links:

CodePudding user response:

I think you can meet all your requirements using @mui/material and @mui/icons-material libraries like this:

import { TextField } from "@mui/material";
import { useEffect, useState } from "react";
import "./styles.css";
import CheckCircleIcon from "@mui/icons-material/CheckCircle";
import CircleIcon from "@mui/icons-material/Circle";

function checkUppercase(str) {
  for (let i = 0; i < str.length; i  ) {
    if (
      str.charAt(i) === str.charAt(i).toUpperCase() &&
      str.charAt(i).match(/[a-z]/i)
    ) {
      return true;
    }
  }
  return false;
}

const SPECIAL_CHARS = "!@#$%^&*()";

function checkSpecialChars(str) {
  const alreadyFoundChars = [];
  for (let i = 0; i < str.length; i  ) {
    const currentChar = str[i];
    if (!alreadyFoundChars.includes(currentChar)) {
      if (SPECIAL_CHARS.includes(currentChar)) {
        alreadyFoundChars.push(currentChar);
      }
    }
  }
  return alreadyFoundChars.length >= 3;
}

const getIcon = (isChecked) => {
  const smallDotIcon = <CircleIcon sx={{ fontSize: "0.4rem" }} />;
  const checkCircleIcon = <CheckCircleIcon sx={{ fontSize: "0.8rem" }} />;
  const iconToBeRendered = isChecked ? checkCircleIcon : smallDotIcon;

  return (
    <div
      style={{
        height: "20px",
        width: "15px",
        display: "flex",
        alignItems: "center",
        justifyContent: "center"
      }}
    >
      {iconToBeRendered}
    </div>
  );
};

const prepareHelperText = (value) => {
  const firstIcon = getIcon(value.length >= 8);
  const secondIcon = getIcon(checkUppercase(value));
  const thirdIcon = getIcon(checkSpecialChars(value));

  return (
    <div>
      <div style={{ display: "flex" }}>
        {firstIcon}
        Must contain at least 8 characters
      </div>
      <div style={{ display: "flex" }}>
        {secondIcon} Must contain at least 1 uppercase letter
      </div>
      <div style={{ display: "flex" }}>
        {thirdIcon} Must contain 3 of the 4 types of characters !@#$%^&*()
      </div>
    </div>
  );
};

export default function App() {
  const [value, setValue] = useState("");
  const [helperText, setHelperText] = useState("");

  useEffect(() => {
    setHelperText(prepareHelperText(value));
  }, [value]);

  return (
    <div className="App">
      <TextField
        type="password"
        label="Password"
        value={value}
        onChange={(e) => setValue(e.target.value)}
        helperText={helperText}
        sx={{
          "& .Mui-focused": {
            color: "purple"
          },
          "& label.Mui-focused": {
            color: "purple !important"
          },
          "& .MuiOutlinedInput-root": {
            "&.Mui-focused fieldset": {
              borderColor: "purple"
            }
          }
        }}
      />
    </div>
  );
}

You can take a look at this sandbox for a live working example of this solution.

  • Related