Goal
Add AEM SPA React Text component showing paragraph texts created using Typescript and Material UI (MUI). Using MUI there are no global style-sheets, each component is independent, so there are no css conflicts at page level polluting global scope. In the following steps a MUI theme created with device specific breakpoints shows AdobeCaslonPro font and device specific font sizes...
Typography in Sketch File (opened using Windows Lunacy App)
Typography in AEM
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-react-spa-material-ui-text" -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-react-spa-material-ui-text/components/spa
/apps/eaem-sites-react-spa-material-ui-text/components/page
/apps/eaem-sites-react-spa-material-ui-text/components/text
3) Open a command prompt (terminal) at eaem-sites-react-spa-material-ui-text\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-react-spa-material-ui-text/components/text. In the next step we'd be creating the react render type script...
5) Add the component render script in eaem-sites-react-spa-material-ui-text\ui.frontend\src\components\AEMText\AEMText.tsx with the following code...
import { MapTo } from "@adobe/cq-react-editable-components"; import React, { FC, useState, useEffect } from "react"; import { makeStyles, Theme, createStyles } from "@material-ui/core"; import { createMuiTheme } from "@material-ui/core/styles"; import createBreakpoints from "@material-ui/core/styles/createBreakpoints"; type TextProps = { cqPath: string; text: string; }; const AEMTextEditConfig = { emptyLabel: "Text - Experience AEM", isEmpty: function (props: any) { return !props || !props.text || props.text.trim().length < 1; } }; function extractModelId(path: string) { return path && path.replace(/\/|:/g, "_"); } enum BREAKPOINTS { XS = 0, SM = 768, MD = 992, LG = 1200, XL = 1600 } const eaemTheme = createMuiTheme({ breakpoints: createBreakpoints({ values: { xs: BREAKPOINTS.XS, sm: BREAKPOINTS.SM, md: BREAKPOINTS.MD, lg: BREAKPOINTS.LG, xl: BREAKPOINTS.XL }, get down() { return (key : number | string) => { let values = this.values as any; return `@media (max-width: ${values[key]- 0.05}px)`; } }, get between() { return (a : number | string, b : number | string) => { let values = this.values as any; return `@media (min-width:${values[a]}px) and (max-width:${values[b] - 0.05}px)`; } } }) }); const useStyles = makeStyles(() => { console.log(eaemTheme.breakpoints.up("md")); return createStyles({ root: { fontFamily: 'AdobeCaslonPro, Times, serif !important', '& h1': { [eaemTheme.breakpoints.down("xl")]: { fontSize: '34px', }, [eaemTheme.breakpoints.down("lg")]: { fontSize: '30px', }, [eaemTheme.breakpoints.down("md")]: { fontSize: '26px', } }, '& h2': { [eaemTheme.breakpoints.down("xl")]: { fontSize: '28px', }, [eaemTheme.breakpoints.down("lg")]: { fontSize: '25px', }, [eaemTheme.breakpoints.down("md")]: { fontSize: '22px', } }, '& h3': { [eaemTheme.breakpoints.down("xl")]: { fontSize: '22px', }, [eaemTheme.breakpoints.down("lg")]: { fontSize: '20px', }, [eaemTheme.breakpoints.down("md")]: { fontSize: '18px', } }, '& p': { fontSize: '13px', }, "& a:hover": { textDecoration: "none" } } }) }); const AEMText: FC<TextProps> = props => { const classes = useStyles(); return ( <div className={classes.root} id={extractModelId(props.cqPath)} data-rte-editelement dangerouslySetInnerHTML={{ __html: props.text }} /> ); }; export default MapTo("eaem-sites-spa-how-to-react/components/text")(AEMText, AEMTextEditConfig);
6) Add AEMText.tsx path in eaem-sites-react-spa-material-ui-text\ui.frontend\src\components\import-components.js
import './Page/Page';
import './AEMText/AEMText';
import './Title/Title';
import './Nav/Nav';
import './Image/Image';
No comments:
Post a Comment