Material UI


反応器でよく使われるUIライブラリ
設定
npm install @mui/material @emotion/react @emotion/styled
npm install @mui/icons-material
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
<link
  rel="stylesheet"
  href="https://fonts.googleapis.com/icon?family=Material+Icons"
/>
属性はhttps://mui.com/components
リファレンス
いんさつじゅつ
import React from 'react';
import { Typography } from '@mui/material';

export default function Create() {
	return (
		<div>
			<Typography
				variant='h6'
				component='h2'
				color='textSecondary'
				gutterBottom
			>
				Create a New Note
			</Typography>
		</div>
	);
}
適用する変数タグ
component DOMにアップロードするタグ
カラーフォントの色
gutterbottomテキストの下に余白を生成

styledcomponentをmaterialに適用する


エンコーディングを容易にするために拡張
vscode-styled-コンポーネントのインストール
import { styled } from '@mui/material/styles';
const StyledButton = styled(Button)`
	font-size: 1rem;
	&:hover {
		background-color: blue;
	}
`;
<StyledButton
				// className={classes}
				onClick={() => console.log('clicked')}
				type='submit'
				color='secondary'
				variant='contained'
				size='large'
				endIcon={<KeyboardArrowRightIcon />}
			>
				Submit
			</StyledButton>

テーマの設定


デフォルトトピック:https://mui.com/customization/default-theme/#main-content
import { createTheme, ThemeProvider } from '@mui/material';
import { grey, purple } from '@mui/material/colors';
const theme = createTheme({
 status: {
    danger: '#e53e3e',
  },
  palette: {
    primary: {
      main: '#0971f1',
      dark: '#053e85',
    },
    neutral: {
      main: '#64748B',
      contrastText: '#fff',
    },
	secondary: grey,
  },
typography: {
		fontFamily: 'Hubballi',
		fontWeightLight: 400,
		fontWeightMedium: 500,
		fontWeightRegular: 600,
		fontWeightBold: 700,
	},
});
<ThemeProvider theme={theme}>
  <CustomCheckbox defaultChecked />
</ThemeProvider>
トピックを適用したいコンポーネントにThemeProviderを上書きすればよい.
@mui/material/colorsの色でmain、light、darkも設定できます
index.css
@import url('https://fonts.googleapis.com/css2?family=Hubballi&display=swap');
フォントはテーマとしても使用できます
トピックのマージ
import { deepmerge } from '@mui/utils';
import { createTheme } from '@mui/material/styles';

const theme = createTheme(deepmerge(options1, options2));
FormControl,FormLabel RadioGroup FormControlLabel Radio
<StyledForm>
					<FormLabel>Note Category</FormLabel>
					<RadioGroup
						value={category}
						onChange={(e) => {
							setCategory(e.target.value);
						}}
					>
						<FormControlLabel value='money' control={<Radio />} label='Money' />
						<FormControlLabel value='todos' control={<Radio />} label='Todos' />
						<FormControlLabel
							value='reminders'
							control={<Radio />}
							label='Reminders'
						/>
						<FormControlLabel value='work' control={<Radio />} label='Work' />
					</RadioGroup>
</StyledForm>

GRID


12列グリッドシステムをサポート
反応型Web対応.
<Container>
			<Grid container>
				{notes.map((note) => (
					<Grid item xs={12} sm={8} md={4} lg={3} key={note.id}>
						<Paper>{note.title}</Paper>
					</Grid>
				))}
			</Grid>
</Container>
Grid容器で包み、各物品をGrid itemで充填します.
xssm mdlgは、画面サイズに応じて、どのくらいの列を入力するかを決定します.

レイアウト

<Layout>
					<Routes>
						<Route path='/' element={<Notes />} />
						<Route path='/create' element={<Create />} />
					</Routes>
</Layout>
レイアウト構成部品からサブアイテムを受信して出力
import { Drawer, Paper, Typography } from '@mui/material';
import { styled } from '@mui/material/styles';

const drawerWidth = `240px`;
const StyledDiv = styled('div')`
	background-color: #f9f9f9;
	width: 100%;
`;
const RootDiv = styled('div')`
	display: flex;
`;
const StyledDrawer = styled(Drawer)`
	width: ${drawerWidth};
	& > div {
		width: ${drawerWidth};
	}
`;
export default function Layout({ children }) {
	return (
		<RootDiv>
			<StyledDrawer variant='permanent' anchor='left'>
				<div>
					<Typography variant='h5'>Ninja Notes</Typography>
				</div>
			</StyledDrawer>
			<StyledDiv>{children}</StyledDiv>
		</RootDiv>
	);
}

List

<RootDiv>
			<StyledDrawer variant='permanent' anchor='left'>
				<div>
					<Typography variant='h5'>Ninja Notes</Typography>
				</div>
				<List sx={{ '& .active': { bgcolor: '#e0e0e0' } }}>
					{/* <ListItem>
						<ListItemText primary='hello'></ListItemText>
					</ListItem> */}
					{menuitems.map((item, i) => (
						<ListItem
							key={i}
							button
							onClick={() => navigate(item.path)}
							className={location.pathname === item.path ? 'active' : null}
						>
							<ListItemIcon>{item.icon}</ListItemIcon>
							<ListItemText primary={item.text} />
						</ListItem>
					))}
				</List>
			</StyledDrawer>
			<StyledDiv>{children}</StyledDiv>
		</RootDiv>

Styled componentの使用

const StyledDiv = styled('div')`
	background-color: #f9f9f9;
	width: 100%;
	padding: ${(props) => props.theme.spacing(3)};
`;
${}を使用してStyledDivのpropsを取得
themeproviderのサブコンポーネントならthemeを呼び出すことでも使えます!!!
const StyledCard = styled(Card)`
	border: ${(props) =>
		props.note.category === 'reminders' ? '1px solid red' : ''};
`;
<StyledCard elevation={1} note={note}>
{children}
</StyledCard>

Appbar(ヘッダ)


.appbar {
		width: calc(100% - ${drawerWidth});
		.avatar {
			margin-left: ${({ theme }) => theme.spacing(2)};
		}
	}
<AppBar className='appbar' color='default' elevation={0}>
				<Toolbar>
					<Typography className='date'>
						Today is the {format(new Date(), 'do MMMM Y')}
					</Typography>
					<Typography>Mario</Typography>
					<Avatar className='avatar' src='/mario-av.png' />
				</Toolbar>
</AppBar>

Masonryライブラリ


異なる長さの単品を綺麗に展示できます.
const breakpoints = {
	default: 3,
	1100: 2,
	700: 1,
};
const StyledContainer = styled(Container)`
	.my-masonry-grid {
		/* display: -webkit-box; */
		/* display: -ms-flexbox; */
		display: flex;
		margin-left: -30px;
		width: auto;
	}
	.my-masonry-grid-column {
		padding-left: 30px;
		background-clip: padding-box;
	}
	.my-masonry-grid-column > div {
		/* background-color: grey; */
		margin-bottom: 30px;
	}
`;
<Masonry
				breakpointCols={breakpoints}
				className='my-masonry-grid'
				columnClassName='my-masonry-grid-column'
			>
				{notes.map((note) => (
					<div key={note.id}>
						<NoteCard note={note} handleDelete={handleDelete} />
					</div>
				))}
</Masonry>