Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[website] Add a Blog index page #30121

Merged
merged 35 commits into from
Jan 17, 2022
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
35 commits
Select commit Hold shift + click to select a range
c8acd40
initial prototype commit
danilo-leal Dec 8, 2021
b4685c4
add blog link to header
siriwatknp Dec 15, 2021
acbb270
add first iteration of blog index
siriwatknp Dec 15, 2021
dd306d5
remove experiment
siriwatknp Dec 15, 2021
7c6f930
fix types
siriwatknp Dec 15, 2021
7fbdc05
design adjustments
danilo-leal Dec 17, 2021
0675a90
sourcing tags and add pagination
siriwatknp Dec 18, 2021
73f3ff5
update blog tags
siriwatknp Dec 18, 2021
6d2e686
use delete icon on Chip
siriwatknp Dec 18, 2021
d59995e
fix a11y
siriwatknp Dec 21, 2021
e4aa2a4
fix semantic
siriwatknp Dec 21, 2021
febca62
Merge branch 'master' of https://github.com/mui-org/material-ui into …
siriwatknp Dec 21, 2021
bae0577
add feature toggle and fix broken avatar
siriwatknp Dec 21, 2021
20e56b9
update feature toggle to commonjs
siriwatknp Dec 25, 2021
c7c994a
Merge branch 'master' of https://github.com/mui-org/material-ui into …
danilo-leal Jan 3, 2022
e866e06
a few design tweaks, pagination theming and post preview clickable area
danilo-leal Jan 3, 2022
108e6b4
Merge branch 'master' into blog-index-page
siriwatknp Jan 6, 2022
b4b2d6b
remove hover from chip in post preview
danilo-leal Jan 6, 2022
0f090ad
update posts tags
danilo-leal Jan 6, 2022
f42cdd0
top layout blog update and tweaks to the index page
danilo-leal Jan 6, 2022
0c78961
small fine tunings
danilo-leal Jan 6, 2022
7f4bddc
fix author names
siriwatknp Jan 7, 2022
068585d
fix tag count
siriwatknp Jan 7, 2022
ed19aee
few tweaks
danilo-leal Jan 7, 2022
6d9eac0
Merge branch 'master' into blog-index-page
danilo-leal Jan 7, 2022
0731b23
remove tag count
siriwatknp Jan 11, 2022
17f3389
Merge branch 'master' of https://github.com/mui-org/material-ui into …
siriwatknp Jan 11, 2022
eda146f
Merge branch 'blog-index-page' of https://github.com/danilo-leal/mate…
siriwatknp Jan 11, 2022
d200ced
fix feature toggle
siriwatknp Jan 11, 2022
69b56a9
small tweak to the chip color
danilo-leal Jan 11, 2022
a442ea4
small tweak to the blog post design
danilo-leal Jan 11, 2022
578d5ea
change to ref
siriwatknp Jan 12, 2022
f10ec63
fix on button's padding
danilo-leal Jan 12, 2022
38dd3f0
copy update
danilo-leal Jan 12, 2022
481fe14
use author name as alt text for avatar picture
danilo-leal Jan 12, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 14 additions & 8 deletions docs/lib/sourcing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { getHeaders } from '@mui/markdown';

const blogDir = path.join(process.cwd(), 'pages/blog');

export const getBlogFilenames = (ext = '.md') => {
export const getBlogFilePaths = (ext = '.md') => {
return fs.readdirSync(blogDir).filter((file) => file.endsWith(ext));
};

Expand All @@ -18,9 +18,9 @@ export interface BlogPost {
date?: string;
}

export const getBlogPost = (filename: string): BlogPost => {
const slug = filename.replace(/\.md$/, '');
const content = fs.readFileSync(path.join(blogDir, filename), 'utf-8');
export const getBlogPost = (filePath: string): BlogPost => {
const slug = filePath.replace(/\.md$/, '');
const content = fs.readFileSync(path.join(blogDir, filePath), 'utf-8');

const headers = getHeaders(content) as unknown as BlogPost;

Expand All @@ -31,10 +31,10 @@ export const getBlogPost = (filename: string): BlogPost => {
};

export const getAllBlogPosts = () => {
const filenames = getBlogFilenames();
const posts = filenames
const filePaths = getBlogFilePaths();
const allBlogPosts = filePaths
.map((name) => getBlogPost(name))
// sort posts by date in descending order
// sort allBlogPosts by date in descending order
.sort((post1, post2) => {
if (post1.date && post2.date) {
return new Date(post1.date) > new Date(post2.date) ? -1 : 1;
Expand All @@ -44,5 +44,11 @@ export const getAllBlogPosts = () => {
}
return -1;
});
return posts;
const tagInfo: Record<string, number | undefined> = {};
allBlogPosts.forEach((post) => {
(post.tags || []).forEach((tag) => {
tagInfo[tag] = (tagInfo[tag] || 0) + 1;
});
});
return { allBlogPosts, allTags: Object.keys(tagInfo), tagInfo };
};
175 changes: 111 additions & 64 deletions docs/pages/blog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@ import Section from 'docs/src/layouts/Section';
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 KeyboardArrowRightRounded from '@mui/icons-material/KeyboardArrowRightRounded';
import Chip from '@mui/material/Chip';
import Link from 'docs/src/modules/components/Link';
import Head from 'docs/src/modules/components/Head';
import AppHeader from 'docs/src/layouts/AppHeader';
import AppFooter from 'docs/src/layouts/AppFooter';
Expand All @@ -24,19 +24,17 @@ import { authors } from 'docs/src/modules/components/TopLayoutBlog';
import HeroEnd from 'docs/src/components/home/HeroEnd';

export const getStaticProps = async () => {
const allBlogPosts = getAllBlogPosts();
const data = getAllBlogPosts();
return {
props: {
allBlogPosts,
},
props: data,
};
};

const PostPreview = (props: BlogPost) => {
return (
<React.Fragment>
{props.tags && (
<Box sx={{ display: 'flex', gap: 1, mb: 4 }}>
<Box sx={{ display: 'flex', gap: 1, mb: 1 }}>
{props.tags.map((tag) => (
<Chip
key={tag}
Expand Down Expand Up @@ -122,8 +120,6 @@ const PostPreview = (props: BlogPost) => {
<Button
component="a"
danilo-leal marked this conversation as resolved.
Show resolved Hide resolved
href={`/blog/${props.slug}`}
target="_blank"
rel="noopener nofollow"
endIcon={<KeyboardArrowRightRounded fontSize="small" />}
sx={{
p: { xs: 0, sm: 0.5 },
Expand All @@ -144,41 +140,53 @@ const PostPreview = (props: BlogPost) => {
);
};

const TAGS = [
'News',
'Material Design',
'Components',
'Accessibility',
'How to guides',
'System',
'New Joiners',
'Developer survey',
];

export default function Blog(props: InferGetStaticPropsType<typeof getStaticProps>) {
const PAGE_SIZE = 5;
const router = useRouter();
const [page, setPage] = React.useState(0);
const [selectedTags, setSelectedTags] = React.useState<Record<string, boolean>>({});
const { allBlogPosts } = props;
const { allBlogPosts, allTags, tagInfo } = props;
const [firstPost, secondPost, ...otherPosts] = allBlogPosts.filter((post) => !!post.title);
const filteredPosts = otherPosts.filter(
(post) =>
!Object.keys(selectedTags).length ||
(post.tags || []).some((tag) => 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 postList = document.getElementById('post-list');
if (postList) {
postList.scrollIntoView();
}
}, [router.query, page]);
React.useEffect(() => {
const arrayTags = getTags();
const finalTags: Record<string, boolean> = {};
arrayTags.forEach((tag) => {
finalTags[tag] = true;
});
setSelectedTags(finalTags);
setPage(0);
}, [getTags]);
const appendTag = (tag: string) => {
return [...getTags(), tag];
};
const removeTag = (tag: string) => {
return getTags().filter((value) => value !== tag);
router.push(
{
query: {
...router.query,
tags: getTags().filter((value) => value !== tag),
},
},
undefined,
{ shallow: true },
);
};
return (
<BrandingProvider>
Expand Down Expand Up @@ -210,12 +218,7 @@ export default function Blog(props: InferGetStaticPropsType<typeof getStaticProp
>
{[firstPost, secondPost].map((post) => (
<Paper
component={Link}
danilo-leal marked this conversation as resolved.
Show resolved Hide resolved
key={post.slug}
href="/blog/"
target="_blank"
rel="noreferrer noopener"
noLinkStyle
variant="outlined"
sx={{ p: 2, display: 'flex', flexDirection: 'column', alignItems: 'initial' }}
>
Expand All @@ -238,6 +241,7 @@ export default function Blog(props: InferGetStaticPropsType<typeof getStaticProp
</Box>
</Section>
<Container
id="post-list"
sx={{
mt: 2,
display: 'grid',
Expand Down Expand Up @@ -269,48 +273,91 @@ export default function Blog(props: InferGetStaticPropsType<typeof getStaticProp
}}
>
<Typography color="text.primary" fontWeight="500" sx={{ mb: 2 }}>
Filter by tags
Filter by tag
</Typography>
<Box sx={{ display: 'flex', gap: 1, flexWrap: 'wrap' }}>
{TAGS.map((tag) => (
<Chip
key={tag}
variant={selectedTags[tag] ? 'filled' : 'outlined'}
label={tag}
size="small"
sx={{ py: 1.2 }}
onClick={() =>
router.push(
{
query: {
...router.query,
tags: (selectedTags[tag] ? removeTag(tag) : appendTag(tag)).join(','),
},
{allTags.map((tag) => {
const selected = !!selectedTags[tag];
return (
<Chip
key={tag}
variant={selected ? 'filled' : 'outlined'}
{...(selected
? {
label: tag,
onDelete: () => removeTag(tag),
}
: {
label: (
<React.Fragment>
{tag}{' '}
<Typography
component="span"
sx={(theme) => ({
borderRadius: 1,
bgcolor: selected ? 'primary.50' : 'grey.300',
px: 0.5,
mr: -0.25,
fontSize: '0.75rem',
fontWeight: 500,
...(theme.palette.mode === 'dark' && {
bgcolor: 'primaryDark.600',
}),
})}
>
{tagInfo[tag]}
</Typography>
</React.Fragment>
),
onClick: () => {
router.push(
{
query: {
...router.query,
tags: tag,
},
},
undefined,
{ shallow: true },
);
},
})}
size="small"
sx={{
py: 1.2,
'&:hover': {
bgcolor: 'primary.100',
},
undefined,
{ shallow: true },
)
}
/>
))}
'& .MuiChip-deleteIcon': {
color: 'primary.700',
'&:hover': { color: 'primary.700' },
},
}}
/>
);
})}
</Box>
</Box>
</Box>
<Box>
{otherPosts
.filter(
(post) =>
!Object.keys(selectedTags).length ||
(post.tags || []).some((tag) => Object.keys(selectedTags).includes(tag)),
)
.map((post, index) => (
<React.Fragment key={post.slug}>
<Box sx={{ py: 3, display: 'flex', flexDirection: 'column' }}>
<PostPreview {...post} />
</Box>
{index !== otherPosts.length - 1 && <Divider />}
</React.Fragment>
))}
{displayedPosts.map((post, index) => (
<React.Fragment key={post.slug}>
<Box sx={{ py: 3, display: 'flex', flexDirection: 'column' }}>
<PostPreview {...post} />
</Box>
{index !== displayedPosts.length - 1 && <Divider />}
</React.Fragment>
))}
<Pagination
page={page + 1}
count={totalPage}
variant="outlined"
shape="rounded"
onChange={(_, value) => {
setPage(value - 1);
}}
sx={{ mt: 2, mb: 10 }}
/>
</Box>
</Container>
</main>
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/2020-q3-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: An update on our mission for Q3 2020.
date: 2020-10-14T00:00:00.000Z
authors: ['oliviertassinari']
card: true
tags: ['News']
---

This update covers our progress over the last three months, and what we aim to achieve in the coming months.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/2020.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: 2020 has been another great year, not only for MUI, but also for th
date: 2020-12-31T00:00:00.000Z
authors: ['oliviertassinari', 'mbrookes']
card: true
tags: ['News']
---

2020 has been another great year, not only for MUI, but also for the ecosystem.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/2021-q1-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: An update on our mission for Q1 2021.
date: 2021-04-12T00:00:00.000Z
authors: ['oliviertassinari']
card: true
tags: ['News']
---

This update covers our progress over the last three months, and what we aim to achieve in the months ahead.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/2021-q2-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: An update on our mission for Q2 2021.
date: 2021-07-12T00:00:00.000Z
authors: ['oliviertassinari', 'mbrookes']
card: true
tags: ['News']
---

This update covers our progress over the last three months.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/2021-q3-update.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: An update on our mission for Q3 2021.
date: 2021-10-26T00:00:00.000Z
authors: ['oliviertassinari']
card: true
tags: ['News']
---

This update covers our progress over the last three months.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/benny-joo-joining.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: We are excited to share that Benny Joo has joined MUI. He has start
date: 2021-11-16T00:00:00.000Z
authors: ['mnajdova']
card: false
tags: ['Company']
---

We are excited to share that [Benny Joo](https://github.com/hbjORbj) has joined MUI.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/danail-hadjiatanasov-joining.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: We are excited to share that Danail Hadjiatanasov has joined MUI as
date: 2020-10-23T00:00:00.000Z
authors: ['oliviertassinari']
card: true
tags: ['Company']
---

We are excited to share that [Danail Hadjiatanasov](https://twitter.com/danail_h) has joined MUI as part of the enterprise team. This was his first full-time week.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/danilo-leal-joining.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: We are excited to share that Danilo Leal has joined MUI.
date: 2021-07-15T00:00:00.000Z
authors: ['oliviertassinari']
card: true
tags: ['Company']
---

We are excited to share that [Danilo Leal](https://daniloleal.co/) has joined MUI!
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/marija-najdova-joining.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: We are excited to share that Marija Najdova has joined MUI. She has
date: 2020-09-15T00:00:00.000Z
authors: ['oliviertassinari']
card: true
tags: ['Company']
---

We are excited to share that [Marija Najdova](https://twitter.com/marijanajdova) has joined MUI. She has started this week full-time, and is now part of the community team.
Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/material-ui-is-now-mui.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ title: Material-UI is now MUI!
description: Starting today, we are evolving our brand identity. We are clarifying the difference between our company and our products.
date: 2021-09-16T00:00:00.000Z
authors: ['oliviertassinari', 'danilo-leal', 'mbrookes']
tags: ['News']
card: true
---

Expand Down
1 change: 1 addition & 0 deletions docs/pages/blog/matheus-wichman-joining.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ description: We are excited to share that Matheus Wichman has joined MUI.
date: 2021-04-05T00:00:00.000Z
authors: ['oliviertassinari']
card: true
tags: ['Company']
---

We are excited to share that [Matheus Wichman](https://github.com/m4theushw) has joined MUI.
Expand Down