Quantcast
Channel: Experiencing Adobe Experience Manager (AEM, CQ)
Viewing all articles
Browse latest Browse all 525

AEM 6560 - React SPA component for showing Alert Banner using Material UI

$
0
0

Goal

Add AEM SPA React Alert component showing a banner created using Material UI (MUI) at the top of page. Using MUI there are no global style-sheets, each component is independent and there are no css conflicts at page level. Responsive page layout is created using AEM Grid...

Thank you Joe Ritchie and team...

Demo | Package Install | Github


Banner (View as Published)



Component Dialog in Template



Solution

1) Create the project structure (for both React SPA and MPA authoring) with the following command using maven archetype - https://github.com/adobe/aem-project-archetype

mvn -B archetype:generate -D archetypeGroupId=com.adobe.granite.archetypes -D archetypeArtifactId=aem-project-archetype 
-D archetypeVersion=23 -D aemVersion=6.5.0 -D appTitle="Experience AEM SPA React" -D appId="eaem-sites-spa-how-to-react" -D groupId="com.eaem"
-D frontendModule=react -D includeExamples=n -D includeErrorHandler=n -D includeDispatcherConfig=n

2) Remove all additional components created, except the following required for testing... (or download Package Install)

                                                          /apps/eaem-sites-spa-how-to-react/components/spa
                                                          /apps/eaem-sites-spa-how-to-react/components/page
                                                          /apps/eaem-sites-spa-how-to-react/components/text

3) Open a command prompt (terminal) at eaem-sites-react-spa-material-ui-banner\ui.frontend and install the typscript and material ui specific dependencies

                                                          npm install typescript
                                                          npm install @material-ui/core
                                                          npm install classnames

4) Create the component /apps/eaem-sites-spa-how-to-react/components/alert. In the next step we'd be creating the react render type script...



5) Add the component render script in eaemeaem-sites-react-spa-material-ui-banner\ui.frontend\src\components\Alert\EAEMAlert.tsx with the following code...

import { MapTo } from "@adobe/cq-react-editable-components";
import React, { FC, useState, useEffect } from "react";
import { Link } from "react-router-dom";
import {
IconButton,
Typography,
createStyles,
makeStyles,
Theme,
Portal,
SvgIcon,
SvgIconProps,
Collapse
} from "@material-ui/core";
import CSS from "csstype";
import classNames from "classnames";

const iconStyles = makeStyles(() =>
createStyles({
root: {
fontSize: 20
}
})
);

const EAEMCloseIcon: FC<SvgIconProps> = props => {
const classes = iconStyles();

return (
<SvgIcon
viewBox="0 0 20 20"
{...props}
className={classNames(classes.root, props.className)}
>
<title>Combined Shape</title>
<desc>Created with Sketch.</desc>
<g
id="Symbols"
stroke="none"
strokeWidth="1"
fill="none"
fillRule="evenodd"
>
<g id="Grommet/X-Close" transform="translate(-15.000000, -15.000000)">
<rect id="Rectangle" x="0" y="0" width="50" height="50"></rect>
<path
d="M34.3548387,15 L35,15.6451613 L25.645,24.999 L35,34.3548387 L34.3548387,35 L25,25.645 L15.6451613,35 L15,34.3548387 L24.354,25 L15,15.6451613 L15.6451613,15 L25,24.354 L34.3548387,15 Z"
id="Combined-Shape"
fill="currentColor"
></path>
</g>
</g>
</SvgIcon>
);
};

type AlertProps = {
showAlert: string;
text: string;
linkURL: string;
};

const AlertEditConfig = {
emptyLabel: "Alert - Shows banner at the top of page",

isEmpty: function (props: any) {
return !props || !props.text || props.text.trim().length < 1;
}
};

const useStyles = makeStyles((theme: Theme) =>
createStyles({
closeIcon: {
fontSize: 12,
color: "white",
[theme.breakpoints.up("sm")]: {
fontSize: 16
}
},
container: {
alignItems: "center",
background: "black",
display: "flex"
},
content: {
color: "white",
paddingTop: "15px",
paddingBottom: "15px",
flex: "1 1",
fontFamily: 'Times, serif',
fontSize: 16,
textAlign: "center"
}
})
);

const EAEMAlert: FC<AlertProps> = props => {
const classes = useStyles();

const [open, setOpen] = useState(true);
const [root, setRoot] = useState<HTMLElement | null>(null);

useEffect(() => {
setRoot(document.getElementById("eaem-alert-banner"));
}, [root]);

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

if (!props.text || props.showAlert != "true") {
return null;
}

let text = props.text.trim();

if (text.startsWith("<p>") && text.endsWith("</p>")) {
text = text.substring(3, text.lastIndexOf("</p>"));
}

return (
<Portal container={root}>
<Collapse in={open}>
<Typography className={classes.container} component={"div"}>
<div
className={classes.content}
dangerouslySetInnerHTML={{ __html: text }}
/>
<IconButton onClick={handleClose}>
<EAEMCloseIcon className={classes.closeIcon} />
</IconButton>
</Typography>
</Collapse>
</Portal>
);
};

export default MapTo("eaem-sites-spa-how-to-react/components/alert")(EAEMAlert, AlertEditConfig);

6) Add the EAEMAlert.tsx path in eaem-sites-react-spa-material-ui-banner\ui.frontend\src\components\import-components.js

                                                          import './Page/Page';
                                                          import './Text/Text';
                                                          import './Title/Title';
                                                          import './Nav/Nav';
                                                          import './Image/Image';
                                                          import './Alert/EAEMAlert';



Viewing all articles
Browse latest Browse all 525

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>