updates to blog styling mdx stuff (#635)

update

fixes

gap fix

update related post

heading and leading update
This commit is contained in:
BFlat authored and GitHub committed 2024-07-27 00:28:29 +07:00
1 parent 7b4d893705
commit a924d4e748
11 files changed
+364 -160

No files matched your search

+3
View File
@@ -16,6 +16,9 @@
"typecheck": "tsc --noEmit"
},
"dependencies": {
"@fortawesome/fontawesome-svg-core": "6.2.1",
"@fortawesome/free-brands-svg-icons": "6.2.1",
"@fortawesome/free-solid-svg-icons": "6.2.1",
"@mdx-js/react": "^3.0.1",
"autoprefixer": "^10.4.19",
"gatsby": "^5.13.5",
+16 -13
View File
@@ -3,23 +3,26 @@ title: Blog Post 1
slug: /blog-1
date: 2024-07-23
featuredImage: "./2D_many_phases.png"
author: wil
category:
author: Wil
category:
---
# Hello World
## Heading 2
this is the first post as a prove of concept
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nunc ac neque enim. Nam eget diam sit amet elit aliquet iaculis a id magna. Etiam sit amet tortor libero. Curabitur fringilla ullamcorper magna at ultrices. Aliquam erat volutpat. Fusce sit amet libero maximus, scelerisque dui et, bibendum mi.
**test image**
Mauris justo diam, facilisis sed consequat eu, porttitor in risus. Curabitur in
tempor quam, sit amet pellentesque ex. Proin porta lobortis nulla, vitae tempor
lorem accumsan vitae. Integer pulvinar aliquam mauris et tempus. Vivamus
accumsan facilisis nisi. Aenean quam justo, finibus nec ipsum ut, porttitor
vulputate nunc. Suspendisse a mi in odio dignissim lacinia in in risus. Nam
ultrices nulla eget justo malesuada viverra.
### Heading 3
Quis ligula sem pellentesque ornare eleifend per curabitur quam. Est potenti augue facilisis mi diam. Cras dignissim turpis erat dictum fermentum aptent. Non proin pharetra semper turpis a ipsum mi euismod. Venenatis potenti eleifend auctor dictum neque felis. Quis purus dui lacus fringilla potenti. Ex tempus etiam mus nulla, sociosqu netus lacus ac. Nulla suspendisse fusce dolor nibh faucibus magnis. Sem habitant sed lorem per dictum.
![2-D_Phase_5](./2-D_Phase_5_.jpg)
**test youtube shortcode**
<Youtube videoId="amPMMEAmf0Q"/>
end of doc
<Youtube videoId="amPMMEAmf0Q" />
end of doc
@@ -0,0 +1,40 @@
import { Link } from "gatsby";
import React, { ReactNode } from "react";
import { twMerge } from "tailwind-merge";
interface ButtonProps {
onClick?: () => void;
to?: string;
children?: ReactNode;
className?: string;
variant?: "primary" | "secondary";
}
const Button = ({
onClick,
to,
children,
className,
variant = "primary",
}: ButtonProps) => {
const baseClasses =
"flex w-fit px-4 py-2 rounded-lg font-semibold text-white hover:bg-primary-400 transition-colors duration-200";
const variantClasses = variant === "primary" ? "bg-primary" : "bg-secondary";
const btnClasses = twMerge(baseClasses, variantClasses, className);
return (
<>
{onClick ? (
<button onClick={onClick} className={btnClasses}>
{children}
</button>
) : (
<Link to={to || "/"} className={btnClasses}>
{children}
</Link>
)}
</>
);
};
export default Button;
@@ -1,5 +1,5 @@
import React, { DetailedHTMLProps, HTMLAttributes } from "react";
import { twMerge } from 'tailwind-merge'
import { twMerge } from "tailwind-merge";
type HeadingProps = DetailedHTMLProps<
HTMLAttributes<HTMLHeadingElement>,
@@ -11,29 +11,34 @@ export const P = ({
className,
...rest
}: DetailedHTMLProps<
HTMLAttributes<HTMLParagraphElement>,
HTMLParagraphElement
HTMLAttributes<HTMLParagraphElement>,
HTMLParagraphElement
>) => (
<p className={twMerge("text-md", className)} {...rest} >
<p className={twMerge("text-[18px]", className)} {...rest}>
{children}
</p>
);
export const H1 = ({ children, className, ...rest }: HeadingProps) => (
<h1 className={twMerge("text-3xl md:text-5xl font-bold", className)} {...rest}>
<h1
className={twMerge("text-3xl font-bold md:text-5xl", className)}
{...rest}
>
{children}
</h1>
);
export const H2 = ({ children, className, ...rest }: HeadingProps) => (
<h2 className={twMerge("text-xl md:text-2xl font-bold", className)} {...rest}>
<h2
className={twMerge("text-2xl font-bold md:text-4xl", className)}
{...rest}
>
{children}
</h2>
);
export const H3 = ({ children, className, ...rest }: HeadingProps) => (
<h3 className={twMerge("text-xl font-bold", className)} {...rest}>
<h3 className={twMerge("text-xl font-bold md:text-3xl", className)} {...rest}>
{children}
</h3>
);
@@ -54,4 +59,4 @@ export const H6 = ({ children, className, ...rest }: HeadingProps) => (
<h6 className={twMerge("text-sm font-bold", className)} {...rest}>
{children}
</h6>
);
);
@@ -1,9 +1,35 @@
import React from "react"
import React from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import {
faFacebook,
faInstagram,
faLinkedin,
faTiktok,
faTwitter,
} from "@fortawesome/free-brands-svg-icons";
const socialMedia = [
{ icon: faTwitter, link: "https://twitter.com" },
{ icon: faInstagram, link: "https://instagram.com" },
{ icon: faTiktok, link: "https://tiktok.com" },
];
const SocialIcons = () => {
return (
<div className="text-white">I</div>
)
}
<div className="flex gap-2">
{socialMedia.map((social, index) => (
<a
key={index}
href={social.link}
target="_blank"
rel="noopener noreferrer"
className="text-md flex h-9 w-9 items-center justify-center rounded-full bg-white/10 text-white transition-all hover:bg-white/20"
>
<FontAwesomeIcon icon={social.icon} />
</a>
))}
</div>
);
};
export default SocialIcons
export default SocialIcons;
@@ -4,21 +4,20 @@ const respIframeWrapper = {
position: "relative" as "relative",
height: 0,
overflow: "hidden",
paddingBottom: "50%"
}
paddingBottom: "50%",
};
export const Youtube = ({
videoId,
title,
}:{
}: {
videoId: string;
title?: string;
})=>{
return(
<div style={respIframeWrapper}>
}) => {
return (
<div style={respIframeWrapper} className="youtube-video">
<iframe
className="border-0 absolute top-0 left-0 w-full h-full"
className="absolute left-0 top-0 h-full w-full border-0"
src={`https://www.youtube.com/embed/${videoId}`}
title={title ?? "YouTube video player"}
allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share"
@@ -29,4 +28,4 @@ export const Youtube = ({
/>
</div>
);
};
};
+14 -10
View File
@@ -4,29 +4,33 @@ import React, { ReactNode } from "react";
import SocialIcons from "./SocialIcons";
export default function Layout({ children }: { children: ReactNode }) {
return (
<div className="font-sans min-h-screen flex flex-col">
<div className="flex min-h-screen flex-col font-sans">
<nav className="bg-panel">
<div className="mx-auto max-w-screen-xl py-3.5 px-4 flex items-center">
<div className="mx-auto flex max-w-screen-xl items-center px-4 py-3.5">
<div className="grow">
<Link to="/">
<StaticImage alt="Logo" src="../images/Storyteller-Logo.png" height={36} />
<StaticImage
alt="Logo"
src="../images/Storyteller-Logo.png"
height={36}
/>
</Link>
</div>
<SocialIcons />
</div>
</nav>
<div className="grow mx-auto max-w-screen-xl px-4 my-4 md:my-8 w-full">
<div className="mx-auto my-4 w-full max-w-screen-xl grow px-4 md:my-8">
{children}
</div>
<footer className="bg-panel">
<div className="text-white/80 text-sm mx-auto max-w-screen-xl py-3 px-4 flex flex-col lg:flex-row items-center lg:items-start justify-between gap-3">
© 2024 All Rights Reserved, Storyteller.ai
<SocialIcons />
<div className="mx-auto max-w-screen-xl">
<div className="flex flex-col items-center justify-between gap-3 px-4 py-6 text-sm text-white/80 lg:flex-row lg:py-3">
<span>© 2024 All Rights Reserved, Storyteller.ai</span>
<SocialIcons />
</div>
</div>
</footer>
</div>
);
}
}
@@ -1,17 +1,21 @@
import React from "react"
import { MDXProvider } from "@mdx-js/react"
import { graphql, Link } from "gatsby"
import type { PageProps } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import Layout from "./layout"
import { Youtube } from "./Youtube"
import React from "react";
import { MDXProvider } from "@mdx-js/react";
import { graphql, Link } from "gatsby";
import type { PageProps } from "gatsby";
import { GatsbyImage, getImage } from "gatsby-plugin-image";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronLeft } from "@fortawesome/free-solid-svg-icons";
import Layout from "./layout";
import { Youtube } from "./Youtube";
import * as MdTypography from "./MdTypography";
import Button from "./Button";
const shortcodes = { Link, Youtube }; // Provide common components here
const shortcodes = { Link, Youtube } // Provide common components here
export default function PostTemplate({ data, children }:PageProps<Queries.PostTemplateQuery>) {
export default function PostTemplate({
data,
children,
}: PageProps<Queries.PostTemplateQuery>) {
const post = data.mdx;
const featuredImage =
post?.frontmatter?.featuredImage?.childImageSharp?.gatsbyImageData &&
@@ -19,34 +23,89 @@ export default function PostTemplate({ data, children }:PageProps<Queries.PostTe
return (
<Layout>
<Link to="/" className="font-semibold hover:underline opacity-80 text-md">Back to Learn</Link>
<MdTypography.H1 className="mt-4 mb-6">{post?.frontmatter?.title}</MdTypography.H1>
<div className="w-full h-[500px] rounded-lg overflow-hidden">
{featuredImage &&
<Link
to="/"
className="text-md flex w-fit items-center gap-1.5 font-semibold opacity-80 hover:underline"
>
<FontAwesomeIcon icon={faChevronLeft} className="text-sm" />
Back to Learn
</Link>
<MdTypography.H1 className="mb-6 mt-6">
{post?.frontmatter?.title}
</MdTypography.H1>
<div className="h-[200px] w-full overflow-hidden rounded-lg bg-panel/10 sm:h-[300px] md:h-[400px] lg:h-[500px]">
{featuredImage && (
<GatsbyImage
alt={`${post.frontmatter.title} featured image`}
image={featuredImage}
className="w-full h-full object-cover"
className="h-full w-full object-cover"
/>
}
)}
</div>
<div className="mdx-styles mt-6">
<MDXProvider components={{
// Map HTML element tag to React component
h1: MdTypography.H1,
h2: MdTypography.H2,
h3: MdTypography.H3,
h4: MdTypography.H4,
h5: MdTypography.H5,
h6: MdTypography.H6,
p: MdTypography.P,
...shortcodes
}}>
{children}
</MDXProvider>
<div className="mt-8 flex gap-28 lg:mt-10">
<div className="mdx-styles group mb-20 grow">
<MDXProvider
components={{
h1: MdTypography.H1,
h2: MdTypography.H2,
h3: MdTypography.H3,
h4: MdTypography.H4,
h5: MdTypography.H5,
h6: MdTypography.H6,
p: MdTypography.P,
...shortcodes,
}}
>
{children}
</MDXProvider>
</div>
<div className="hidden min-w-[280px] flex-col gap-8 lg:flex">
<div className="overflow-hidden rounded-lg bg-panel/5">
<div className="p-4">
<MdTypography.H2 className="mb-3 font-bold leading-5 md:text-[18px]">
Turn your ideas into videos with ease
</MdTypography.H2>
<Button>Create now</Button>
</div>
<div className="h-40 bg-panel/5" />
</div>
<div className="flex items-center gap-3">
<div className="pointer-events-none h-12 w-12 select-none overflow-hidden rounded-full border border-panel/20 bg-panel/10">
{featuredImage && (
<GatsbyImage
alt={`${post.frontmatter.title} featured image`}
image={featuredImage}
className="h-full w-full object-cover"
/>
)}
</div>
<div className="text-md flex flex-col">
<span>Written by</span>
<span className="font-bold">
{post?.frontmatter?.author || ""}
</span>
</div>
</div>
<hr className="w-full border-panel/15" />
<div className="flex flex-col gap-3">
<MdTypography.H4>Related posts</MdTypography.H4>
<div className="flex flex-col gap-8">
<Link to="/" className="group flex flex-col gap-2">
<div className="h-40 overflow-hidden rounded-lg bg-panel/5">
<div className="flex h-full w-full items-center justify-center object-cover transition-all duration-[400ms] group-hover:scale-110">
Related Post Image Here
</div>
</div>
<MdTypography.H4 className="my-0 text-[17px] transition-all group-hover:text-link">
Title of related post
</MdTypography.H4>
</Link>
</div>
</div>
</div>
</div>
</Layout>
)
);
}
export const query = graphql`
@@ -54,16 +113,14 @@ export const query = graphql`
mdx(id: { eq: $id }) {
frontmatter {
title
author
date(formatString: "MMMM DD, YYYY")
featuredImage{
featuredImage {
childImageSharp {
gatsbyImageData(
width: 800
placeholder: BLURRED
)
gatsbyImageData(width: 800, placeholder: BLURRED)
}
}
}
}
}
`
`;
+92 -69
View File
@@ -1,72 +1,99 @@
import React from "react"
import { graphql, Link } from "gatsby"
import type { HeadFC, PageProps } from "gatsby"
import { GatsbyImage, getImage } from "gatsby-plugin-image"
import React from "react";
import { graphql, Link } from "gatsby";
import type { HeadFC, PageProps } from "gatsby";
import { GatsbyImage, getImage } from "gatsby-plugin-image";
import "../styles/global.css";
import Layout from "../components/layout"
import Layout from "../components/layout";
import * as MdTypography from "../components/MdTypography";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faChevronRight } from "@fortawesome/free-solid-svg-icons";
const IndexPage = ({data}:PageProps<Queries.IndexPageQuery>) =>{
console.log(data)
return(
const IndexPage = ({ data }: PageProps<Queries.IndexPageQuery>) => {
console.log(data);
return (
<Layout>
<div className="flex flex-col gap-6">
<div>
<MdTypography.H1 className="mb-1 md:mb-2">Learn</MdTypography.H1>
<MdTypography.P className="opacity-90 text-[18px] leading-6">Tutorials, tips and tricks on how to create better content.</MdTypography.P>
<MdTypography.P className="text-[18px] font-semibold leading-6 opacity-80">
Tutorials, tips and tricks on how to create better content.
</MdTypography.P>
</div>
<Link to="/">
<div className="grid grid-cols-5 rounded-lg overflow-hidden group">
<div className="col-span-full lg:col-span-3 bg-panel/20 h-52 sm:h-96">
<div className="w-full h-full object-cover group-hover:scale-105 transition-all duration-[400ms] flex items-center justify-center">
Featured Post Image Here
</div>
</div>
<div className="col-span-full lg:col-span-2 p-4 lg:p-6 text-center lg:text-start bg-panel/5 flex flex-col justify-center">
<MdTypography.P className="text-sm font-bold opacity-70 hover:text-link transition-all uppercase">Category</MdTypography.P>
<MdTypography.H2 className="group-hover:text-link transition-all">Featured Post Title</MdTypography.H2>
<MdTypography.P className="hidden lg:block mt-3 font-semibold opacity-70">Read More</MdTypography.P>
<div className="group grid grid-cols-5 overflow-hidden rounded-lg">
<div className="col-span-full h-52 bg-panel/20 sm:h-96 lg:col-span-3">
<div className="flex h-full w-full items-center justify-center object-cover transition-all duration-[400ms] group-hover:scale-110">
Featured Post Image Here
</div>
</div>
<div className="col-span-full flex flex-col justify-center bg-panel/5 p-4 text-center lg:col-span-2 lg:p-6 lg:text-start">
<MdTypography.P className="text-md font-bold uppercase opacity-70 transition-all hover:text-link">
Category
</MdTypography.P>
<MdTypography.H2 className="text-2xl transition-all group-hover:text-link md:text-3xl">
Featured Post Title
</MdTypography.H2>
<MdTypography.P className="text-md mt-3 hidden w-fit items-center gap-1.5 font-semibold opacity-70 lg:flex">
Read More
<FontAwesomeIcon
icon={faChevronRight}
className="me-2 text-xs"
/>
</MdTypography.P>
</div>
</div>
</Link>
{data.allMdx.nodes
? <BlogRoll posts={data.allMdx.nodes} />
: <p>failed loading blog posts</p>
}
{data.allMdx.nodes ? (
<BlogRoll posts={data.allMdx.nodes} />
) : (
<p>failed loading blog posts</p>
)}
</div>
</Layout>
)
}
function BlogRoll ({posts}:{posts:Queries.IndexPageQuery["allMdx"]["nodes"]}){
if (posts.length > 0){
return(
<ul className="grid grid-cols-2 md:grid-cols-3 gap-5">
{posts.map((post)=>{
);
};
function BlogRoll({
posts,
}: {
posts: Queries.IndexPageQuery["allMdx"]["nodes"];
}) {
if (posts.length > 0) {
return (
<ul className="grid grid-cols-2 gap-5 md:grid-cols-3 md:gap-6">
{posts.map((post) => {
const postProps = post.frontmatter;
if(postProps && postProps.slug && postProps.title){
const featuredImage = postProps.featuredImage?.childImageSharp?.gatsbyImageData && getImage(postProps.featuredImage.childImageSharp.gatsbyImageData);
return(
if (postProps && postProps.slug && postProps.title) {
const featuredImage =
postProps.featuredImage?.childImageSharp?.gatsbyImageData &&
getImage(postProps.featuredImage.childImageSharp.gatsbyImageData);
return (
<li key={post.id} className="group">
<Link to={postProps.slug}>
<div className="rounded-lg overflow-hidden bg-panel/5 h-32 sm:h-52">
{featuredImage &&
<GatsbyImage
alt={`${postProps.title} featured image`}
image={featuredImage}
className="w-full h-full object-cover group-hover:scale-105 transition-all duration-[400ms]"
/>
}
<div className="h-32 overflow-hidden rounded-lg bg-panel/5 sm:h-52">
{featuredImage && (
<GatsbyImage
alt={`${postProps.title} featured image`}
image={featuredImage}
className="h-full w-full object-cover transition-all duration-[400ms] group-hover:scale-110"
/>
)}
</div>
<div className="flex flex-col mt-3">
<div className="mt-3 flex flex-col">
<div>
<Link to="/" className="text-sm font-bold opacity-70 hover:text-link transition-all uppercase">Category</Link>
<Link
to="/"
className="text-sm font-bold uppercase opacity-70 transition-all hover:text-link"
>
Category
</Link>
</div>
<MdTypography.H4 className="group-hover:text-link transition-all my-0">{postProps.title}</MdTypography.H4>
<MdTypography.H4 className="my-0 text-[16px] transition-all group-hover:text-link md:text-[18px]">
{postProps.title}
</MdTypography.H4>
{/* <h4>{postProps.date}</h4> */}
</div>
{/* <p className="italic">by {postProps.author ?? "unknown"}</p> */}
</Link>
</li>
@@ -76,35 +103,31 @@ function BlogRoll ({posts}:{posts:Queries.IndexPageQuery["allMdx"]["nodes"]}){
</ul>
);
}
return <p>There are no Posts!</p>
return <p>There are no Posts!</p>;
}
export const query = graphql`
query IndexPage {
allMdx {
nodes {
id
frontmatter {
title
author
slug
date(formatString: "MMMM DD, YYYY")
featuredImage{
childImageSharp {
gatsbyImageData(
width: 800
placeholder: BLURRED
)
}
allMdx {
nodes {
id
frontmatter {
title
author
slug
date(formatString: "MMMM DD, YYYY")
featuredImage {
childImageSharp {
gatsbyImageData(width: 800, placeholder: BLURRED)
}
}
internal {
contentFilePath
}
}
internal {
contentFilePath
}
}
}
`
}
`;
export default IndexPage;
export const Head: HeadFC = () => <title>Storyteller Blog</title>
export const Head: HeadFC = () => <title>Storyteller Blog</title>;
+45 -4
View File
@@ -2,11 +2,52 @@
@tailwind components;
@tailwind utilities;
@import url('https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap');
@import url("https://fonts.googleapis.com/css2?family=Source+Sans+3:ital,wght@0,200..900;1,200..900&display=swap");
body {
font-family: 'Source Sans 3', sans-serif;
font-family: "Source Sans 3", sans-serif;
color: #242433;
min-height: 100vh;
}
}
.mdx-styles {
p {
@apply leading-[1.7rem];
}
p:not(:last-child) {
@apply mb-6;
}
h1:not(:last-child) {
@apply mb-6;
}
h1:not(:first-child) {
@apply mt-10;
}
h2:not(:last-child) {
@apply mb-6;
}
h2:not(:first-child) {
@apply mt-10;
}
h3:not(:last-child) {
@apply mb-6;
}
h3:not(:first-child) {
@apply mt-6;
}
span:not(:last-child) {
@apply mb-6;
}
.youtube-video:not(:last-child) {
@apply mb-6;
}
}
+6 -3
View File
@@ -3733,7 +3733,7 @@ __metadata:
languageName: node
linkType: hard
"@fortawesome/fontawesome-svg-core@npm:^6.2.1":
"@fortawesome/fontawesome-svg-core@npm:6.2.1, @fortawesome/fontawesome-svg-core@npm:^6.2.1":
version: 6.2.1
resolution: "@fortawesome/fontawesome-svg-core@npm:6.2.1::__archiveUrl=https%3A%2F%2Fnpm.fontawesome.com%2F%40fortawesome%2Ffontawesome-svg-core%2F-%2F6.2.1%2Ffontawesome-svg-core-6.2.1.tgz"
dependencies:
@@ -3742,7 +3742,7 @@ __metadata:
languageName: node
linkType: hard
"@fortawesome/free-brands-svg-icons@npm:^6.2.1":
"@fortawesome/free-brands-svg-icons@npm:6.2.1, @fortawesome/free-brands-svg-icons@npm:^6.2.1":
version: 6.2.1
resolution: "@fortawesome/free-brands-svg-icons@npm:6.2.1::__archiveUrl=https%3A%2F%2Fnpm.fontawesome.com%2F%40fortawesome%2Ffree-brands-svg-icons%2F-%2F6.2.1%2Ffree-brands-svg-icons-6.2.1.tgz"
dependencies:
@@ -3751,7 +3751,7 @@ __metadata:
languageName: node
linkType: hard
"@fortawesome/free-solid-svg-icons@npm:^6.2.1":
"@fortawesome/free-solid-svg-icons@npm:6.2.1, @fortawesome/free-solid-svg-icons@npm:^6.2.1":
version: 6.2.1
resolution: "@fortawesome/free-solid-svg-icons@npm:6.2.1::__archiveUrl=https%3A%2F%2Fnpm.fontawesome.com%2F%40fortawesome%2Ffree-solid-svg-icons%2F-%2F6.2.1%2Ffree-solid-svg-icons-6.2.1.tgz"
dependencies:
@@ -30245,6 +30245,9 @@ __metadata:
version: 0.0.0-use.local
resolution: "storyteller-ai-blog@workspace:packages/gatsby-blog"
dependencies:
"@fortawesome/fontawesome-svg-core": 6.2.1
"@fortawesome/free-brands-svg-icons": 6.2.1
"@fortawesome/free-solid-svg-icons": 6.2.1
"@mdx-js/react": ^3.0.1
"@types/node": ^20.11.19
"@types/react": ^18.2.55