import * as React from 'react';
import { InferGetStaticPropsType } from 'next';
import { useRouter } from 'next/router';
import Avatar from '@mui/material/Avatar';
import AvatarGroup from '@mui/material/AvatarGroup';
import Box from '@mui/material/Box';
import Container from '@mui/material/Container';
import Divider from '@mui/material/Divider';
import Typography from '@mui/material/Typography';
import Paper from '@mui/material/Paper';
import Pagination from '@mui/material/Pagination';
import Button from '@mui/material/Button';
import KeyboardArrowRightRoundedIcon from '@mui/icons-material/KeyboardArrowRightRounded';
import Chip from '@mui/material/Chip';
import XIcon from '@mui/icons-material/X';
import GitHubIcon from '@mui/icons-material/GitHub';
import LinkedInIcon from '@mui/icons-material/LinkedIn';
import YouTubeIcon from '@mui/icons-material/YouTube';
import DiscordIcon from 'docs/src/icons/DiscordIcon';
import Head from 'docs/src/modules/components/Head';
import AppHeader from 'docs/src/layouts/AppHeader';
import AppFooter from 'docs/src/layouts/AppFooter';
import GradientText from 'docs/src/components/typography/GradientText';
import BrandingCssVarsProvider from 'docs/src/BrandingCssVarsProvider';
import { authors as AUTHORS } from 'docs/src/modules/components/TopLayoutBlog';
import HeroEnd from 'docs/src/components/home/HeroEnd';
import { Link } from '@mui/docs/Link';
import generateRssFeed from 'docs/scripts/generateRSSFeed';
import Section from 'docs/src/layouts/Section';
import SectionHeadline from 'docs/src/components/typography/SectionHeadline';
import { getAllBlogPosts, BlogPost } from 'docs/lib/sourcing';
export const getStaticProps = () => {
const data = getAllBlogPosts();
generateRssFeed(data.allBlogPosts);
return {
props: data,
};
};
function PostPreview(props: BlogPost) {
return (
{props.tags.map((tag) => (
({
height: 22,
fontWeight: 'medium',
fontSize: theme.typography.pxToRem(13),
'& .MuiChip-label': {
px: '6px',
},
...theme.applyDarkStyles({
color: (theme.vars || theme).palette.grey[200],
}),
})}
/>
))}
{props.title}
{props.description}
{props.authors && (
({
mt: 2,
mb: 1,
alignSelf: 'flex-start',
'& .MuiAvatar-circular': {
width: 28,
height: 28,
fontSize: theme.typography.pxToRem(13),
fontWeight: theme.typography.fontWeightSemiBold,
color: (theme.vars || theme).palette.text.primary,
border: `1px solid ${(theme.vars || theme).palette.divider}`,
outline: '3px solid',
outlineColor: '#FFF',
backgroundColor: (theme.vars || theme).palette.grey[100],
},
...theme.applyDarkStyles({
'& .MuiAvatar-circular': {
outlineColor: (theme.vars || theme).palette.primaryDark[900],
backgroundColor: (theme.vars || theme).palette.primaryDark[700],
},
}),
})}
>
{(props.authors as Array).map((author) => (
))}
)}
{props.authors && (
{props.authors
.slice(0, 3)
.map((userId) => {
const name = AUTHORS[userId as keyof typeof AUTHORS]?.name;
if (name) {
if (props.authors && props.authors.length > 1) {
// display only firstName
return name.split(' ')[0];
}
return name;
}
return userId;
})
.join(', ')}
{props.authors.length > 2 && ', and more.'}
)}
{props.date && (
{new Date(props.date).toDateString()}
)}
}
size="small"
sx={{ mt: { xs: 0.5, md: 0 }, p: { xs: 0, sm: '6px 8px' } }}
>
Read more
);
}
const PAGE_SIZE = 7;
export default function Blog(props: InferGetStaticPropsType) {
const router = useRouter();
const postListRef = React.useRef(null);
const [page, setPage] = React.useState(0);
const [selectedTags, setSelectedTags] = React.useState>({});
const { allBlogPosts, tagInfo: rawTagInfo } = props;
const [firstPost, secondPost, ...otherPosts] = allBlogPosts;
const tagInfo = { ...rawTagInfo };
[firstPost, secondPost].forEach((post) => {
post.tags.forEach((tag) => {
if (tagInfo[tag]) {
tagInfo[tag]! -= 1;
}
});
});
Object.entries(tagInfo).forEach(([tagName, tagCount]) => {
if (tagCount === 0) {
delete tagInfo[tagName];
}
});
const filteredPosts = otherPosts.filter((post) => {
if (Object.keys(selectedTags).length === 0) {
return true;
}
return post.tags.some((tag) => {
return Object.keys(selectedTags).includes(tag);
});
});
const pageStart = page * PAGE_SIZE;
const totalPage = Math.ceil(filteredPosts.length / PAGE_SIZE);
const displayedPosts = filteredPosts.slice(pageStart, pageStart + PAGE_SIZE);
const getTags = React.useCallback(() => {
const { tags = '' } = router.query;
return (typeof tags === 'string' ? tags.split(',') : tags || [])
.map((str) => str.trim())
.filter((tag) => !!tag);
}, [router.query]);
React.useEffect(() => {
const arrayTags = getTags();
const finalTags: Record = {};
arrayTags.forEach((tag) => {
finalTags[tag] = true;
});
setSelectedTags(finalTags);
setPage(0);
}, [getTags]);
const removeTag = (tag: string) => {
router.push(
{
query: {
...router.query,
tags: getTags().filter((value) => value !== tag),
},
},
undefined,
{ shallow: true },
);
};
return (
Stay in the loop with
the latest about MUI's products
}
/>
{[firstPost, secondPost].map((post) => (
({
p: 2,
display: 'flex',
flexDirection: 'column',
backgroundImage: (theme.vars || theme).palette.gradients.radioSubtle,
boxShadow: '0 4px 12px rgba(170, 180, 190, 0.2)',
...theme.applyDarkStyles({
background: (theme.vars || theme).palette.primaryDark[900],
backgroundImage: (theme.vars || theme).palette.gradients.radioSubtle,
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.4)',
}),
})}
>
{post.image && (
)}
))}
Posts{' '}
{Object.keys(selectedTags).length ? (
tagged as{' '}
"{Object.keys(selectedTags)[0]}"
) : (
''
)}
Filter posts by tag
{Object.keys(tagInfo).map((tag) => {
const selected = !!selectedTags[tag];
return (
{
postListRef.current?.scrollIntoView();
removeTag(tag);
},
}
: {
label: tag,
onClick: () => {
postListRef.current?.scrollIntoView();
router.push(
{
query: {
...router.query,
tags: tag,
},
},
undefined,
{ shallow: true },
);
},
})}
size="small"
/>
);
})}
Want to hear more from us?
Get up to date with everything MUI-related through our social media:
svg': { mr: 1 } }}>
GitHub
X
Discord
LinkedIn
Youtube
{displayedPosts.map((post) => (
))}
{
setPage(value - 1);
postListRef.current?.scrollIntoView();
}}
sx={{ mt: 1, mb: 4 }}
/>
);
}