Material UI

jinabbb·2022년 3월 18일
0

리액트에서 많이 쓰는 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

에서 참고하자

타이포그래피 (Typography)

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>
	);
}

variant 적용될 태그

component DOM에 올라갈 태그

color 폰트컬러

gutterbottom 텍스트 밑에 마진이 생긴다

material에 styled componenet 적용하기

편하게 코딩하기 위해 익스텐션

vscode-styled-components 설치

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열의 그리드시스템을 지원한다

반응형 웹을 지원한다.

<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 container로 감싸고 각 아이템은 Grid item으로 채운다.

xs sm md lg는 각각 화면 크기에 맞춰서 열을 얼마나 채울지 정한다.

레이아웃

<Layout>
					<Routes>
						<Route path='/' element={<Notes />} />
						<Route path='/create' element={<Create />} />
					</Routes>
</Layout>

레이아웃 컴포넌트에서 children을 받아서 출력해준다

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>
profile
개발

0개의 댓글