I am new to React UI Libraries like material-ui and notistack. In my project Components like are being used with some styling/css. In the whole react application when there is a long dynamic text that is put inside this Snackbar component its GUI gets disturbed and the text cut offs and goes out of the component. How can i habndle this and make it responsive so that it can handle very long texts inside it.

Following is the code for the Snackbar Component in file SanckbarProvider.tsx

import React from "react";
import {
  SnackbarProvider as NisSnackbarProvider,
  SnackbarProviderProps,
} from "notistack";

import { Fade } from "@material-ui/core";
import { TransitionProps } from "@material-ui/core/transitions";
import { makeStyles } from "@material-ui/core/styles";
import { CloseButton } from "./CloseButton";


const variantStyle = (color: string, backgroundColor: string) => ({
  height: "36px;",
  color: `${color} !important`,
  backgroundColor: `${backgroundColor} !important`,
  opacity: "0.95 !important",
  borderRadius: "3px;",
  boxShadow: "0 2px 10px 0 rgba(0,0,0,0.1);",
  alignContent: "center",
  marginRight: "-4px !important",
});

const useStyles = makeStyles(() => ({
  success: variantStyle("#3AA658", "#BBE9B6"),
  error: variantStyle("#FFFFFF", "#D07B7B"),
  warning: variantStyle("#FFFFFF", "#EC9E4D"),
  info: variantStyle("#FFFFFF", "#6da4d0"),
}));

const FadeTransition = (props: TransitionProps) => <Fade {...props}/>;

const SnackbarProvider = ({ children }: SnackbarProviderProps): JSX.Element => {
  const classes = useStyles();

  return (
    <NisSnackbarProvider
      classes={{
        variantSuccess: classes.success,
        variantError: classes.error,
        variantWarning: classes.warning,
        variantInfo: classes.info,
      }}
      action={key => <CloseButton id={key} />}
      maxSnack={7}
      anchorOrigin={{vertical: "bottom", horizontal: "right"}}
      autoHideDuration={3000}
      transitionDuration={{enter: 1000, exit: 500}}
      TransitionComponent={FadeTransition}
      variant={"success"}
      preventDuplicate
    >
      {children}
    </NisSnackbarProvider>
  );
};

export default SnackbarProvider;

And this is for main app component in App.tsx

const ContentWrapper = styled.div<WrapperProps>`
  overflow-x: hidden;
  background: ${(props) => (props.showBackground ? "white" : "transparent")};
  height: calc(100vh);
`;

const LinearProgressWrapper = styled.div`
 position: absolute;
 top: ${LINEAR_PROGRESS_TOP_POSITION};
 left: 0;
 width: 100%;
 z-index: 100;
`;

const LinearProgressStyled = styled(LinearProgress)`
  height: 6px;
`;

const App = (): JSX.Element => {

  const dispatch = useDispatch();
  const size = useScreenSize();
  const loginState = useSelector(loginSelector);
  const showLoadingIndicator = useSelector(pendingApiCallsExist);
  const { authenticated } = loginState;
  const selectedScreen = useSelector((state: IRootState) => state.ui.view);

  const shouldShowBigTopbar = !!(selectedScreen === ViewTypes.WorkspacesList && IS_MAC_OS);

  // for some reasons, after logout, sizesReducer is reset.
  // So it's needed to manually trigger recalculation
  useLayoutEffect(() => {
    if (size.height !== -1) {
      dispatch(resizeAction(size));
    }
  }, [authenticated, dispatch, size]);

  return (
    <StylesProvider injectFirst>
      <MuiThemeProvider theme={maTheme}>
        <ThemeProvider theme={maTheme}>
          <I18nextProvider i18n={i18n}>
            <SnackbarProvider>
              <Socket url={SOCKET_URL}/>
              <ContentWrapper
                showBackground={shouldShowBigTopbar}
              >
                <Router history={routerHistory}>
                  <Routes />
                  {showLoadingIndicator && <LinearProgressWrapper>
                    <LinearProgressStyled />
                  </LinearProgressWrapper>}
                  <SnackbarsList />
                </Router>
              </ContentWrapper>
            </SnackbarProvider>
          </I18nextProvider>
        </ThemeProvider>
      </MuiThemeProvider>
    </StylesProvider>
  );
};

export default App;

This the the code for rendering the info and moreinfo snackbar

import React, { useState } from "react";
import {
  Card,
  CardActions,
  Collapse,
  IconButton,
  Paper,
  Typography,
} from "@material-ui/core";
import { makeStyles } from "@material-ui/core/styles";
import CloseIcon from "@material-ui/icons/Close";
import ExpandMoreIcon from "@material-ui/icons/ExpandMore";

import { SnackbarMessage, useSnackbar } from "notistack";
import { autoUpdater } from "electron-updater";

const infoBase = {
  alignContent: "center",
  backgroundColor: "#D07B7B",
  borderRadius: "3px;",
  boxShadow: "0 2px 10px 0 rgba(0,0,0,0.1);",
  color: "#FFFFFF",
  marginRight: "-4px",
  opacity: "0.95",
  padding: "6px 16px",
};

const useStyles = makeStyles((theme) => ({
  card: {
    marginRight: "-4px",
    maxWidth: 440,
    minWidth: 344,
  },
  info: {
    ...infoBase,
    height: "36px",
  },
  icons: {
    marginLeft: "auto !important",
    marginRight: "-8px",
    paddingLeft: "16px",
  },
  expand: {
    color: "#FFFFFF",
    padding: "8px 8px",
    transform: "rotate(0deg)",
    transition: theme.transitions.create("transform", {
      duration: theme.transitions.duration.shortest,
    }),
  },
  expandOpen: {
    transform: "rotate(180deg)",
  },
  moreInfo: {
    ...infoBase,
    maxHeight: "156px",
    overflowWrap: "break-word",
  },
}));

interface IProps {
  id: string | number,
  info: string,
  moreInfo: string,
}

const MoreInfoSnackbar = (props: IProps): JSX.Element => {
  const {id, info, moreInfo} = props;
  const classes = useStyles();
  const { closeSnackbar } = useSnackbar();
  const [expanded, setExpanded] = useState(false);

  const handleExpandClick = () => setExpanded(!expanded);
  const handleDismiss = () => closeSnackbar(id);

  // TODO: What the heck to do with this? - very, very hacky!
  const renderErrorIcon = () => (
    <svg className="MuiSvgIcon-root" focusable="false" viewBox="0 0 28 28"
      aria-hidden="true"
      style={{fontSize: "20px", marginInlineEnd: "8px"}}
    >
      <path
        d="M12,2C17.53,2 22,6.47 22,12C22,17.53 17.53,22 12,22C6.47,22 2,17.53 2,12C2,6.47 6.47,2 12,2M15.59,7L12,10.59L8.41,7L7,8.41L10.59,12L7,15.59L8.41,17L12,13.41L15.59,17L17,15.59L13.41,12L17,8.41L15.59,7Z">
      </path>
    </svg>
  );

  const renderActionIcons = () => (
    <div className={classes.icons}>
      <IconButton
        style={{
          transform: expanded ? "rotate(180deg)" : "",
        }}
        aria-label="Show more"
        className={classes.expand}
        onClick={handleExpandClick}
      >
        <ExpandMoreIcon />
      </IconButton>
      <IconButton className={classes.expand} onClick={handleDismiss}>
        <CloseIcon />
      </IconButton>
    </div>
  );

  const renderInfo = () => (
    <CardActions className={classes.info}>
      {renderErrorIcon()}
      <Typography gutterBottom>
        {info}
      </Typography>
      {renderActionIcons()}
    </CardActions>
  );

  const renderMoreInfo = () => (
    <Collapse in={expanded} timeout="auto" unmountOnExit>
      <Paper className={classes.moreInfo}>
        <Typography gutterBottom>
          {moreInfo}
        </Typography>
      </Paper>
    </Collapse>
  );

  return (
    <Card className={classes.card}>
      {renderInfo()}
      {renderMoreInfo()}
    </Card>
  );
};

type IErrors = {
  info: string
  moreInfo: string
}

const processMessage = (message: React.ReactNode): IErrors => {
  if (typeof message === "string") {
    return {info: message, moreInfo: ""};
  }
  if (Array.isArray(message)) {
    const info = typeof message[0] === "string" ? message[0] : "";
    const moreInfo = typeof message[1] === "string" ? message[1] : "";
    return {info, moreInfo};
  }
  return {info: "", moreInfo: ""};
};

/**
 This is the set callback signature that notistack allows for returning
 a customized snackbar.

 It is not straightforward to get more data into the custom snackbar.
 So we leverage the message param. It can be a string or an array.
 We could use a JSON string and then parse it to get a bunch more options
 but for now, we are just adding an extra "moreInfo" string

 Works with a message array of [message, moreInfo], I.e:
 import { getMoreInfoSnackbar } from "../../snacks/MoreInfoSnackbar";
 ...
 enqueueSnackbar(
   ["something went wrong", "More detailed info, accessed via dropdown"],
   {
      content: getMoreInfoSnackbar,
      persist: true,
    },
 );
 */
export const getMoreInfoSnackbar = (key: React.ReactText, message: React.ReactNode): SnackbarMessage => {
  const {info, moreInfo} = processMessage(message);
  return <MoreInfoSnackbar id={key} info={info} moreInfo={moreInfo}/>;
};
export default MoreInfoSnackbar;

Can someone help to resolve this issue as mentioned above? How can a make this snackbar component resize/grow with the content inside it and adjsut and align the content fit ito it.

Snackbar Component Image

0

There are 0 best solutions below