Skip to content

Commit

Permalink
feat: Add initial animation
Browse files Browse the repository at this point in the history
  • Loading branch information
ohprettyhak committed Nov 4, 2024
1 parent 06a0210 commit 9dfa62d
Show file tree
Hide file tree
Showing 31 changed files with 548 additions and 100 deletions.
3 changes: 2 additions & 1 deletion gatsby-browser.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import './src/styles/code-highlight.css';
import './src/styles/animation.css';
import '@/styles/code-highlight.css';
import '@/styles/globals.css';
import 'material-symbols/rounded.css';
9 changes: 3 additions & 6 deletions gatsby-config.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,10 @@
import type { GatsbyConfig } from 'gatsby';
import remarkGfm from 'remark-gfm';

import { metadata } from './src/constants/metadata';

const config: GatsbyConfig = {
siteMetadata: {
title: 'semantic',
author: 'Knesssn',
description: 'Make your ✨gorgeous blog with semantic',
siteUrl: `https://semantic.nylonbricks.com`,
},
siteMetadata: metadata,
graphqlTypegen: true,
plugins: [
{
Expand Down
4 changes: 2 additions & 2 deletions gatsby/_queries/blog.ts → gatsby/_queries/post.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { IGatsbyImageData } from 'gatsby-plugin-image';

export type BlogPageQueryType = {
export type PostPageQueryType = {
allMdx: {
nodes: {
id: string;
Expand All @@ -27,7 +27,7 @@ export type BlogPageQueryType = {
};
};

export const BlogPageQuery = `
export const PostPageQuery = `
query GetAllMdxPosts {
allMdx(filter: { internal: { contentFilePath: { regex: "/^(.*/content/posts/)(.*)$/" } } }) {
nodes {
Expand Down
42 changes: 42 additions & 0 deletions gatsby/_utils/page-generator.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import { Actions } from 'gatsby';

const perPage = 8;

export const generatePaginatedPage = (
totalItems: number,
basePath: string,
component: string,
title: string,
createPage: Actions['createPage'],
) => {
const totalPages = Math.ceil(totalItems / perPage);
Array.from({ length: totalPages }).forEach((_, i) => {
createPage({
path: i === 0 ? `/${basePath}` : `/${basePath}/p/${i + 1}`,
component,
context: {
title,
type: basePath,
limit: perPage,
skip: i * perPage,
maxPages: totalPages,
currentPage: i + 1,
},
});
});
};

export const generateMetadataPages = (
items: Set<string>,
pathPrefix: string,
template: string,
createPage: Actions['createPage'],
) => {
items.forEach(item => {
createPage({
path: `/${pathPrefix}/${item}`.toLowerCase(),
component: template,
context: { [pathPrefix]: item },
});
});
};
54 changes: 24 additions & 30 deletions gatsby/createCustomPages.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@ import path from 'path';
import { GatsbyNode } from 'gatsby';

import { AboutPageQuery, AboutPageQueryType } from './_queries/about';
import { BlogPageQuery, BlogPageQueryType } from './_queries/blog';
import { PostPageQuery, PostPageQueryType } from './_queries/post';
import { getImage, IGatsbyImageData } from 'gatsby-plugin-image';
import { generatePaginatedPage, generateMetadataPages } from './_utils/page-generator';

const templates = {
about: path.resolve(`./src/templates/about-template.tsx`),
blog: path.resolve(`./src/templates/blog-template.tsx`),
post: path.resolve(`./src/templates/post-template.tsx`),
posts: path.resolve(`./src/templates/posts-template.tsx`),
category: path.resolve(`./src/templates/category-template.tsx`),
categories: path.resolve(`./src/templates/categories-template.tsx`),
tag: path.resolve(`./src/templates/tag-template.tsx`),
Expand All @@ -19,49 +21,39 @@ export const createCustomPages: GatsbyNode['createPages'] = async ({
actions,
reporter,
}) => {
const { createPage } = actions;
const { createPage, createRedirect } = actions;

// Blog pages
const pageQuery = await graphql<BlogPageQueryType>(BlogPageQuery);
// Post pages
const postQueryResult = await graphql<PostPageQueryType>(PostPageQuery);

if (pageQuery.errors) {
reporter.panicOnBuild('🚨 MDX query error at BlogPageQuery', pageQuery.errors);
if (postQueryResult.errors) {
reporter.panicOnBuild('🚨 MDX query error at PostPageQuery', postQueryResult.errors);
return;
}

const blogs = pageQuery.data?.allMdx.nodes || [];
const posts = postQueryResult.data?.allMdx.nodes || [];
const categories = new Set<string>();
const tags = new Set<string>();

blogs.forEach(({ frontmatter, fields, internal }) => {
posts.forEach(({ frontmatter, fields, internal }) => {
const { slug, category, tag, coverImage } = frontmatter;

const cover: IGatsbyImageData | undefined = getImage(
coverImage?.childImageSharp?.gatsbyImageData || null,
);

createPage({
path: `/blog/${slug}`,
component: `${templates.blog}?__contentFilePath=${internal.contentFilePath}`,
path: `/posts/${slug}`,
component: `${templates.post}?__contentFilePath=${internal.contentFilePath}`,
context: { ...frontmatter, tags: tag ?? [], coverImage: cover, timestamp: fields.timestamp },
});

if (category) categories.add(category);
tag?.forEach(t => tags.add(t));
});

const createMetadataPages = (items: Set<string>, pathPrefix: string, template: string) => {
items.forEach(item => {
createPage({
path: `/${pathPrefix}/${item}`.toLowerCase(),
component: template,
context: { [pathPrefix]: item },
});
});
};

createMetadataPages(categories, 'category', templates.category);
createMetadataPages(tags, 'tag', templates.tag);
generatePaginatedPage(posts.length, 'posts', templates.posts, 'Posts', createPage);
generateMetadataPages(categories, 'category', templates.category, createPage);
generateMetadataPages(tags, 'tag', templates.tag, createPage);

createPage({
path: `/category`,
Expand All @@ -76,20 +68,22 @@ export const createCustomPages: GatsbyNode['createPages'] = async ({
});

// About page
const aboutQuery = await graphql<AboutPageQueryType>(AboutPageQuery);

if (aboutQuery.errors) {
reporter.panicOnBuild('🚨 MDX query error at AboutPageQuery', aboutQuery.errors);
const aboutQueryResult = await graphql<AboutPageQueryType>(AboutPageQuery);
if (aboutQueryResult.errors) {
reporter.panicOnBuild('🚨 MDX query error at AboutPageQuery', aboutQueryResult.errors);
return;
}

if (aboutQuery.data?.mdx) {
const { id, internal } = aboutQuery.data.mdx;
if (aboutQueryResult.data?.mdx) {
const { id, internal } = aboutQueryResult.data.mdx;

createPage({
path: `/about`,
component: `${templates.about}?__contentFilePath=${internal.contentFilePath}`,
context: { id },
});
}

// Redirects
createRedirect({ fromPath: `/post/p/1/`, toPath: `/post/` });
};
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ type FooterProps = {
const Footer = ({ date }: FooterProps) => {
return (
<footer className={styles.root}>
<p className={styles.date}>Last update: {dayjs(date).format('YYYY-DD-MM HH:mm')}</p>
<p className={styles.date}>Last update: {dayjs(date).format('YYYY-MM-DD HH:mm')}</p>
</footer>
);
};
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { style } from '@vanilla-extract/css';

import { theme } from '@/styles/theme.css';
import { rem } from '@/utils/pxto';

export const root = style({});

export const date = style({
...theme.typographies.profile_sub,
marginTop: rem(30),
color: theme.colors.gray.mid,
});
7 changes: 6 additions & 1 deletion src/components/common/Layout/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,12 @@ const Layout = ({ className, children, ...props }: LayoutProps) => {
<div className={styles.root}>
<Sidebar />
<Header />
<main className={clsx(styles.main, className)} {...props}>
<main
className={clsx(styles.main, className)}
{...props}
data-animate={true}
data-animate-speed="slow"
>
{children}
</main>
</div>
Expand Down
57 changes: 57 additions & 0 deletions src/components/common/Pagination/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { clsx } from 'clsx';
import { Link } from 'gatsby';
import React from 'react';

import { theme } from '@/styles/theme.css';

import * as styles from './styles.css';

type PaginationProps = {
currentPage: number;
maxPages: number;
prefix: string;
};

const Pagination = ({ currentPage, maxPages, prefix }: PaginationProps) => {
return (
<nav className={styles.root}>
<ul className={styles.container}>
{currentPage > 1 && (
<li key="pagination-left">
<Link
className={clsx(styles.item, 'material-symbols-rounded')}
to={`/${prefix}/${currentPage - 1 === 1 ? '' : `p/${currentPage - 1}`}`}
aria-label="Previous page"
>
chevron_left
</Link>
</li>
)}

{Array.from({ length: maxPages }, (_, i) => (
<li
key={`pagination-number-${i + 1}`}
className={clsx(styles.item, i + 1 === currentPage && styles.active)}
style={{ fontFamily: theme.fonts.mono }}
>
<Link to={`/${prefix}/${i === 0 ? '' : `p/${i + 1}`}`}>{i + 1}</Link>
</li>
))}

{currentPage < maxPages && (
<li key="pagination-right">
<Link
className={clsx(styles.item, 'material-symbols-rounded')}
to={`/${prefix}/p/${currentPage + 1}`}
aria-label="Next page"
>
chevron_right
</Link>
</li>
)}
</ul>
</nav>
);
};

export default Pagination;
43 changes: 43 additions & 0 deletions src/components/common/Pagination/styles.css.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import { globalStyle, style } from '@vanilla-extract/css';

import { theme } from '@/styles/theme.css';
import { rem } from '@/utils/pxto';

export const root = style({
...theme.layouts.center,
width: '100%',
paddingBlock: rem(65),
});

export const container = style({
...theme.layouts.centerY,
padding: 0,
margin: 0,
listStyle: 'none',
userSelect: 'none',
});

export const item = style({
...theme.layouts.center,
width: rem(28),
height: rem(28),
color: theme.colors.gray.mid,
fontWeight: 400,
cursor: 'pointer',
borderRadius: rem(4),
backgroundColor: 'transparent',
transition: 'color 0.3s, background-color 0.3s',

':hover': { color: theme.colors.gray.accent, backgroundColor: theme.colors.gray.hover },
':active': { color: theme.colors.gray.accent, backgroundColor: theme.colors.border },
});

export const active = style({
color: theme.colors.gray.accent,
backgroundColor: theme.colors.border,
});

globalStyle(`${item} > a`, {
width: '100%',
textAlign: 'center',
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,12 @@ import { formatDate } from '@/utils/date';

import * as styles from './styles.css';

type PostsGridProps = ComponentProps<'div'> & {
type PostGridProps = ComponentProps<'div'> & {
className?: string;
posts: Queries.LatestBlogPostsQuery['allMdx']['nodes'];
};

const PostsGrid = ({ posts, className, ...props }: PostsGridProps) => {
const PostGrid = ({ posts, className, ...props }: PostGridProps) => {
return (
<div className={clsx(styles.grid, className)} {...props}>
{posts.map(({ id, frontmatter }) => {
Expand All @@ -21,7 +21,7 @@ const PostsGrid = ({ posts, className, ...props }: PostsGridProps) => {
);

return (
<Link key={id} className={styles.container} to={`/blog/${frontmatter?.slug}`}>
<Link key={id} className={styles.container} to={`/posts/${frontmatter?.slug}`}>
<div className={styles.cover}>
{coverImage && (
<GatsbyImage
Expand All @@ -40,4 +40,4 @@ const PostsGrid = ({ posts, className, ...props }: PostsGridProps) => {
);
};

export default PostsGrid;
export default PostGrid;
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,6 @@ export const cover = style({
userSelect: 'none',
overflow: 'hidden',
transition: 'filter 0.3s ease',

':hover': { filter: 'brightness(1.3)' },
});

export const title = style({
Expand Down Expand Up @@ -61,6 +59,10 @@ export const description = style({
transition: 'background-color 0.3s ease',
});

globalStyle(`${container}:hover ${cover}, ${container}:active ${cover}`, {
filter: 'brightness(1.3)',
});

globalStyle(`${container}:hover ${title}`, {
backgroundColor: theme.colors.gray.hover,
});
Expand Down
Loading

0 comments on commit 9dfa62d

Please sign in to comment.