æ¬è¨äºã¯ Reactã¦ã£ã¼ã¯ 4æ¥ç®ã®è¨äºã§ãã
ð 3æ¥ç® â¶â¶ æ¬è¨äº â¶â¶ 5æ¥ç® ð±

- ã¯ããã«
- ï¼ç°¡åã«ï¼MUI/Emotionã¨ã¯
- éçºç°å¢ã®æºå
- ãªãªã¸ãã«ã¢ã³ã¼ãã£ãªã³ã³ã³ãã¼ãã³ãã使ãã
- ãããã«
ã¯ããã«
ã¯ããã¾ãã¦ãã¤ã³ãã¢å éä¸ã§éåä¸è¶³æ°å³ãªãæ°åå
¥ç¤¾4å¹´ç®ã®è¥¿å
ã§ãã
æ®æ®µã¯ããã³ãã¨ã³ãã¨ã³ã¸ãã¢ã¨ãã¦ãæ¥åã¢ããªã®éçºã»éç¨ã«æºãã£ã¦ãã¾ãã
仿¥ã¯Reactã¦ã£ã¼ã¯ã¨ãããã¨ã§ãReactããã¸ã§ã¯ãåãã®ã³ã³ãã¼ãã³ãã©ã¤ãã©ãªã®éçºçµé¨ããã¨ã«ãMUIã®ã³ã³ãã¼ãã³ããEmotionã§ã¹ã¿ã¤ãªã³ã°ããæ¹æ³ã«ã¤ãã¦ã¾ã¨ãã¾ãã
Next.jsã®è¨å®æ¹æ³ã«ã¤ãã¦ãç°¡åã«è§¦ãã¦ãã¾ãã®ã§ãæ¢åããã¸ã§ã¯ãã¸ã®å°å
¥ã®éã«ãåèã«ãªãã°ã§ãã
ï¼ç°¡åã«ï¼MUI/Emotionã¨ã¯
MUI
MUI(Material-UI)ã¯Reactã³ã³ãã¼ãã³ãã©ã¤ãã©ãªã§ãã
Googleã®Material Designï¼ãããªã¢ã«ãã¶ã¤ã³ï¼ã«åºã¥ãã¦ãã¶ã¤ã³ãããUIã³ã³ãã¼ãã³ããæä¾ãã¦ãã¾ãã
Emotion
Emotionã¯JavaScriptã§CSSãè¨è¿°ããããã®ã©ã¤ãã©ãªã§ãã
Reactãã¯ããã¨ããJavaScript (TypeScript)ã©ã¤ãã©ãªã§ãã¹ã¿ã¤ãªã³ã°ã«ä½¿ç¨ãããã¨ãã§ãã¾ãã
éçºç°å¢ã®æºå
Next.jsã®ããã¸ã§ã¯ã使
ä»åã¯Next.jsã®ããã¸ã§ã¯ãã«MUIã¨Emotionãå°å
¥ãã¦ãã³ã³ãã¼ãã³ããã¹ã¿ã¤ãªã³ã°ãã¦ããã¾ãã
ã¾ãã¯ãNext.jsã®ããã¸ã§ã¯ãã使ãã¾ãã
ã¤ã³ã¹ãã¼ã«
以ä¸ã®ã³ãã³ããå®è¡ãã¦ãNext.jsãã¤ã³ã¹ãã¼ã«ãã¾ããTypeScriptã使ç¨ãããã®ã§ããªãã·ã§ã³ã§æå®ãã¦ãã¾ãã
npx create-next-app@latest --typescript
ã³ãã³ããå®è¡ããã¨è¨å®ã«ã¤ãã¦è³ªåãããã®ã§ãå¿
è¦ã«å¿ãã¦åçãã¦ãã ããã
ä»åã¯ä»¥ä¸ã®ããã«è¨å®ãã¦ãã¾ãã
ããã§Next.jsã®ããã¸ã§ã¯ãã使ããã¾ããã
MUI/Emotionã®ã¤ã³ã¹ãã¼ã«
ã¤ã³ã¹ãã¼ã«
ç¶ãã¦ã以ä¸ã®ã³ãã³ãã§MUIã¨Emotionãã¤ã³ã¹ãã¼ã«ãã¾ãã
npm install @mui/material @emotion/react @emotion/styled
Next.jsã®è¨å®
Next.jsï¼TypeScriptï¼ã®ããã¸ã§ã¯ãã§Emotionã使ç¨ããããã«ãtsconfig.jsonã«è¨å®ã追å ãã¾ãã
{
"compilerOptions": {
"jsxImportSource": "@emotion/react", // JSX Pragmaãè¨å®
"types": ["@emotion/react/types/css-prop"], // Emotionã®åå®ç¾©ãã¡ã¤ã«ãè¨å®
}
}
ããã§è¨å®ã¯å®äºã§ãã
ãªãªã¸ãã«ã¢ã³ã¼ãã£ãªã³ã³ã³ãã¼ãã³ãã使ãã
ä»åã¯ãMUIã®Accordionãå ã«ããªãªã¸ãã«ã®ã¢ã³ã¼ãã£ãªã³ã³ã³ãã¼ãã³ãã使ãã¦ããã¾ãã
1.èªä½ã³ã³ãã¼ãã³ããå®ç¾©ãã
ã¾ãã¯ãMUIã®ã³ã³ãã¼ãã³ããã©ãããã¦ãèªä½ã³ã³ãã¼ãã³ãï¼ä»¥éãCustomAccordionï¼ã使ãã¾ãã
MUIã®ã¢ã³ã¼ãã£ãªã³ã¯æ¬æ¥ã3ã¤ã®ã³ã³ãã¼ãã³ãï¼Accordion/AccordionSummary/AccordionDetailsï¼ã§æ§æããã¦ãã¾ãããCustomAccordionã§ã¯ãããã1ã¤ã®ã³ã³ãã¼ãã³ãã«ã¾ã¨ãã¾ãã
ããã«ãAccordionSummaryãAccordionDetailsã«è¨å®ããå
容ã¯å¤ããæ¸¡ããããã«ãpropsãè¨å®ãã¾ãã
CustomAccordion.tsx
import { Accordion, AccordionDetails, AccordionSummary } from "@mui/material"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { ReactNode } from "react"; export type CustomAccordionProps = { summaryContent: ReactNode; detailContent: ReactNode; }; export const CustomAccordion = ({summaryContent, detailContent}: CustomAccordionProps) => ( <Accordion> <AccordionSummary expandIcon={<ExpandMoreIcon />}> {summaryContent} </AccordionSummary> <AccordionDetails>{detailContent}</AccordionDetails> </Accordion> );
ã³ã³ãã¼ãã³ããå¼ã³åºãå´ã®ãã¡ã¤ã«
<CustomAccordion summaryContent={'Accordion 1'} detailContent={'ã¢ã³ã¼ãã£ãªã³1ã®ã³ã³ãã³ãã§ãã'} /> <CustomAccordion summaryContent={'Accordion 2'} detailContent={'ã¢ã³ã¼ãã£ãªã³2ã®ã³ã³ãã³ãã§ãã'} />
CustomAccordionï¼MUIã®ããã©ã«ãã¹ã¿ã¤ã«ï¼

2.MUIã®CSSã¯ã©ã¹ã確èªãã
次ã«ãMUIã®ã³ã³ãã¼ãã³ããã¹ã¿ã¤ãªã³ã°ããããã®æºåãè¡ãã¾ãã
MUIã«ã¯åã³ã³ãã¼ãã³ãã®æ©è½ã«é¢ããæ
å ±ãAPIãªãã¡ã¬ã³ã¹ããã¥ã¡ã³ãã«ã¾ã¨ãããã¦ãããä½¿ç¨æ¹æ³ãè¨å®å¯è½ãªPropsã«ã¤ãã¦è¨è¼ããã¦ãã¾ãã
ä¾ãã°ãAccordionã«é¢ãã¦ã¯ä»¥ä¸ã®ãã¼ã¸ãåç
§ãã¦ãã ããã
mui.com
ããã©ã«ãã®CSSã䏿¸ãããå ´åã¯ãCSS classesã®é
ãåç
§ããã¹ã¿ã¤ãªã³ã°ãããç®æã«é©ç¨ããã¦ããCSSã¯ã©ã¹ã確èªãã¾ãã
3.Emotionã§MUIã®ããã©ã«ãCSSã䏿¸ããã
ãããããMUIã®ã³ã³ãã¼ãã³ãã®ã¹ã¿ã¤ã«ã䏿¸ããã¦ã¹ã¿ã¤ãªã³ã°ãã¦ããã¾ãã
Emotionã®ã¹ã¿ã¤ã«è¨æ³
propsçµç±ã§ã¹ã¿ã¤ã«ã渡ãå ´åã¯ãcss propsã使ç¨ãã¾ããã¹ã¿ã¤ã«è¨æ³ã¯ãã¹ããªã³ã°ã¹ã¿ã¤ã«ã¨ãªãã¸ã§ã¯ãã¹ã¿ã¤ã«ã®2種é¡ãããã¾ãã
TypeScriptã®ããã¸ã§ã¯ãã®å ´åãEmotionããªãã¸ã§ã¯ãã¹ã¿ã¤ã«ãæ¨å¥¨ãã¦ãã¾ãã
詳ããã¯ä»¥ä¸ãåç
§ãã¦ãã ããã
emotion.sh
èªä½ã³ã³ãã¼ãã³ããã¹ã¿ã¤ãªã³ã°ãã
ä»åã¯ã#20B2AAããã¼ã¹ã«ã©ã¼ã«ããã¹ã¿ã¤ã«ãé©ç¨ããæå°å¹
ãæå®ã§ããããã«propsã追å ãã¾ãã
ã¹ã¿ã¤ã«ã®ä¸æ¸ãã«ã¤ãã¦ã¯ãMUIã®CSSã¯ã©ã¹ãæå®ããã¹ã¿ã¤ã«ãè¨å®ãã¦ããã ãã§åé¡ããã¾ããã
ãã ãCSSã¯ã©ã¹ã®æå®ã ãã§ã¯ã¹ã¿ã¤ã«ã䏿¸ãã§ããªãå ´åã¯ã親ã»ã¬ã¯ã¿ãåç
§ãããªã©ãã¦CSSã®è©³ç´°åº¦ã調æ´ãã¦ãã ããã
ã¾ããcssã颿°ã¨ãã¦å®ç¾©ããpropsã弿°ã¨ãã¦åçãªå¤ã§ã¹ã¿ã¤ã«ã夿´ãããã¨ãã§ãã¾ãã
ä»åã¯props minWidthã«è¨å®ãããå¤ãminWidthããããã£ã«è¨å®ãããã¨ã§ãåçã«æå°å¹
ãæå®ã§ããããã«ãã¦ãã¾ãã
CustomAccordion.tsx
import { Accordion, AccordionDetails, AccordionSummary } from "@mui/material"; import ExpandMoreIcon from "@mui/icons-material/ExpandMore"; import { ReactNode } from "react"; import { css } from '@emotion/react' export type CustomAccordionProps = { summaryContent: ReactNode; detailContent: ReactNode; minWidth?: string, // æ°ãã追å ããprops }; export const CustomAccordion = ({ summaryContent, detailContent, minWidth = '500px' }: CustomAccordionProps) => ( <Accordion css={styles.accordion(minWidth)} > // minWidthã«è¨å®ãããå¤ã弿°ã¨ãã¦ã»ãã <AccordionSummary expandIcon={<ExpandMoreIcon />} css={styles.summary}> {summaryContent} </AccordionSummary> <AccordionDetails css={styles.detail}>{detailContent}</AccordionDetails> </Accordion> ); const styles = { accordion: (minWidth: CustomAccordionProps['minWidth']) => css({ minWidth: minWidth, // propsããæ¸¡ã£ã¦ããå¤ãcssã®å¤ã¨ãã¦é©ç¨ }), summary: css({ '&.MuiAccordionSummary-root ': { // 親ã»ã¬ã¯ã¿ãåç § backgroundColor: '#20B2AA', borderTop: 'solid 2px #20B2AA', }, '.MuiAccordionSummary-content': { color: '#FFF', fontWeight: 'bold' }, '.MuiAccordionSummary-expandIconWrapper': { color: '#FFF', } }), detail: css({ '&.MuiAccordionDetails-root' : { backgroundColor: `rgba(32, 178, 170, 0.1)`, border: 'solid 2px #20B2AA', padding: '32px' } }) }
ã³ã³ãã¼ãã³ããå¼ã³åºãå´ã®ãã¡ã¤ã«
<CustomAccordion summaryContent={'Accordion 1'} detailContent={'ã¢ã³ã¼ãã£ãªã³1ã®ã³ã³ãã³ãã§ãã'} minWidth={'700px'} /> <CustomAccordion summaryContent={'Accordion 2'} detailContent={'ã¢ã³ã¼ãã£ãªã³2ã®ã³ã³ãã³ãã§ãã'} minWidth={'700px'}/>
CustomAccordionï¼Emotionã使ã£ã¦ã¹ã¿ã¤ãªã³ã°ï¼

ããã§ãMUIã®ã³ã³ãã¼ãã³ããEmotionã§ã¹ã¿ã¤ãªã³ã°ããCustomAccordionã®å®æã§ãã
ãããã«
ä»åã¯MUIã®ã³ã³ãã¼ãã³ããEmotionã§ã¹ã¿ã¤ãªã³ã°ããæ¹æ³ããç´¹ä»ãã¾ããã
MUIã¨Emotionãåããããã¨ã§ãã«ã¹ã¿ãã¤ãºæ§ãé«ã¾ããæè»ãªã³ã³ãã¼ãã³ãéçºãå¯è½ã«ãªãã¾ãã
ãã²ãMUIã¨Emotionã使ã£ã¦ãèªå好ã¿ã®Reactã³ã³ãã¼ãã³ãã使ãã¦ã¿ã¦ãã ããã