gatsby-plugin-mdx#MDXRenderer JavaScript Examples
The following examples show how to use
gatsby-plugin-mdx#MDXRenderer.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: {mdx.slug}.js From wiki with GNU General Public License v3.0 | 6 votes |
BlogPost = React.memo(({ data }) => { // highlight-line
React.useEffect(() => {
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
let series = data.mdx.slug.split('/')[0];
let contents = undefined;
for (let item of data.allContentsYaml.nodes) {
if (item.series === series) {
contents = item;
break
}
}
return (
<Layout
frontmatter={data.mdx.frontmatter}
contents={contents}
>
<MDXRenderer>
{data.mdx.body}
</MDXRenderer>
</Layout>
)
})
Example #2
Source File: contact.js From gatsby-starter-portfolio-minimal with MIT License | 6 votes |
Contact = ({ content }) => {
const { body, frontmatter } = content[0].node
// Required for animation
const ref = useRef()
const onScreen = useOnScreen(ref)
const variants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
}
return (
<StyledSection
id="contact"
ref={ref}
variants={variants}
animate={onScreen ? "visible" : "hidden"}
>
<StyledContentWrapper>
<h3>{frontmatter.title}</h3>
<MDXRenderer>{body}</MDXRenderer>
<div className="profile">
<Img
className="avatar"
fluid={frontmatter.profileImage.childImageSharp.fluid}
/>
<div className="details">
<strong>{frontmatter.name}</strong>
<br />
<a href={`mailto:${frontmatter.email}`}>
<Underlining highlight>{frontmatter.email}</Underlining>
</a>
</div>
</div>
<Social width="9rem" padding="0.5rem 1.25rem" withIcon />
</StyledContentWrapper>
</StyledSection>
)
}
Example #3
Source File: noteTemplate.js From gatsby-remark-obsidian with GNU General Public License v3.0 | 6 votes |
export default function Template({ pageContext }) {
const { body } = pageContext;
return (
<div id="content">
<MDXProvider>
<MDXRenderer>{body}</MDXRenderer>
</MDXProvider>
</div>
);
}
Example #4
Source File: default-page.js From gatsby-starter-graphcms-blog with BSD Zero Clause License | 6 votes |
function DefaultPageTemplate({ pageContext: { page } }) {
return (
<div className="divide-y divide-gray-200">
<div className="pt-6 pb-8 space-y-2 md:space-y-5">
<h1 className="text-3xl leading-9 font-extrabold text-gray-900 tracking-tight sm:text-4xl sm:leading-10 md:text-6xl md:leading-14">
{page.title}
</h1>
{page.subtitle && (
<p className="text-lg leading-7 text-gray-500">{page.subtitle}</p>
)}
</div>
<div className="pb-16 lg:pb-20">
<div className="prose max-w-none pt-10 pb-8">
<MDXRenderer>{page.content.markdownNode.childMdx.body}</MDXRenderer>
</div>
</div>
</div>
)
}
Example #5
Source File: imprint.js From gatsby-starter-portfolio-minimal with MIT License | 6 votes |
Imprint = ({ data }) => {
const { body, frontmatter } = data.imprint.edges[0].node
const { title, seoTitle, useSeoTitleSuffix, useSplashScreen } = frontmatter
const globalState = {
isIntroDone: useSplashScreen ? false : true,
darkMode: false,
}
return (
<GlobalStateProvider initialState={globalState}>
<Layout>
<SEO
title={
useSeoTitleSuffix
? `${seoTitle} - ${seoTitleSuffix}`
: `${seoTitle}`
}
meta={[{ name: "robots", content: "noindex" }]}
/>
<StyledSection id={title}>
<StyledContentWrapper>
<h1 data-testid="heading">{title}</h1>
<MDXRenderer>{body}</MDXRenderer>
</StyledContentWrapper>
</StyledSection>
</Layout>
</GlobalStateProvider>
)
}
Example #6
Source File: static.js From fellowship-program-website with MIT License | 6 votes |
StaticPage = ({ data: { mdx } }) => {
return (
<>
<PageMetadata title={mdx.frontmatter.title} />
<PageBody>
<MDXProvider components={components}>
<MDXRenderer>{mdx.body}</MDXRenderer>
</MDXProvider>
</PageBody>
</>
)
}
Example #7
Source File: mdx-custom-renderer.js From cloudflare-docs-engine with Apache License 2.0 | 6 votes |
MDXCustomRenderer = ({ data: { mdx } }) => {
return (
<MDXProvider components={components}>
<MDXRenderer frontmatter={mdx.frontmatter}>
{mdx.body}
</MDXRenderer>
</MDXProvider>
)
}
Example #8
Source File: mission.js From crypto-dappy-learning-hub with Apache License 2.0 | 6 votes |
Post = ({ data: { mdx: post } }) => {
const { title } = post.frontmatter;
const { body } = post;
return (
<Layout>
<h1>{title}</h1>
<MDXRenderer>{body}</MDXRenderer>
</Layout>
);
}
Example #9
Source File: privacy.js From gatsby-starter-portfolio-minimal with MIT License | 6 votes |
Privacy = ({ data }) => {
const { body, frontmatter } = data.privacy.edges[0].node
const { title, seoTitle, useSeoTitleSuffix, useSplashScreen } = frontmatter
const globalState = {
isIntroDone: useSplashScreen ? false : true,
darkMode: false,
}
return (
<GlobalStateProvider initialState={globalState}>
<Layout>
<SEO
title={
useSeoTitleSuffix
? `${seoTitle} - ${seoTitleSuffix}`
: `${seoTitle}`
}
meta={[{ name: "robots", content: "noindex" }]}
/>
<StyledSection id={title}>
<StyledContentWrapper>
<h1 data-testid="heading">{title}</h1>
<MDXRenderer>{body}</MDXRenderer>
</StyledContentWrapper>
</StyledSection>
</Layout>
</GlobalStateProvider>
)
}
Example #10
Source File: Mdx.js From operate-first.github.io-old with GNU General Public License v3.0 | 6 votes |
DocTemplate = ({ data: { site, mdx }, location }) => {
const siteTitle = site.siteMetadata.title;
const shortcodes = { Link, JupyterNotebook }; // Provide common components here
return (
<Layout location={location} title={siteTitle}>
<SEO
title={mdx.frontmatter.title}
description={mdx.frontmatter.description}
srcLink={mdx.fields.srcLink}
/>
<PageSection className="doc" variant={PageSectionVariants.light}>
<TextContent>
<h1>{mdx.frontmatter.title}</h1>
<MDXProvider components={shortcodes}>
<MDXRenderer>{mdx.body}</MDXRenderer>
</MDXProvider>
</TextContent>
</PageSection>
</Layout>
);
}
Example #11
Source File: wiki.js From velocitypowered.com with MIT License | 6 votes |
export default function Documentation({ location, data }) {
const article = data.mdx
return (
<>
<Seo title={article.frontmatter.title} description={article.excerpt} />
<DocumentationContainer>
<Sidebar sidebar={wikiSidebar} location={location} />
<ContentWrapper>
<Content>
<h1>{article.frontmatter.title}</h1>
<MDXProvider components={shortlinks}>
<MDXRenderer>{article.body}</MDXRenderer>
</MDXProvider>
</Content>
</ContentWrapper>
</DocumentationContainer>
</>
)
}
Example #12
Source File: meetup-post.js From codeursenseine.com with MIT License | 6 votes |
MeetupPost = ({ data }) => {
const { body, frontmatter, parent } = data.mdx;
return (
<MeetupLayout title={frontmatter.title}>
<Stack spacing={8}>
<A as={Link} to="/meetups">
Retour à la liste des meetups
</A>
<MeetupTitle metadata={frontmatter} />
<MeetupRegistration metadata={frontmatter} />
<Box>
<MDXRenderer>{body}</MDXRenderer>
</Box>
<MeetupRegistration metadata={frontmatter} />
<Button
variant="outline"
as="a"
href={`https://github.com/CodeursEnSeine/codeursenseine-new/edit/master/content/meetups/${parent.base}`}
leftIcon={<FaGithub />}
>
Modifier cette page
</Button>
</Stack>
</MeetupLayout>
);
}
Example #13
Source File: PageLayout.js From codeursenseine.com with MIT License | 6 votes |
PageLayout = ({ pageContext }) => {
const { body, title, theme, pagePath } = pageContext;
return (
<Layout theme={theme}>
<Seo title={title} />
<OgUrl path={pagePath} />
<MDXRenderer>{body}</MDXRenderer>
</Layout>
);
}
Example #14
Source File: index.js From royalhackaway.com with MIT License | 6 votes |
HomePage = ({ data }) => {
const { name, short_description } = data.mdx.frontmatter
return (
<Layout parentData={data.mdx}>
<SiteSEO title={name} description={short_description} />
<EventContextProvider data={data}>
<div class={mdxClass}>
<MDXRenderer>{data.mdx.body}</MDXRenderer>
</div>
</EventContextProvider>
</Layout>
)
}
Example #15
Source File: index.js From royalhackaway.com with MIT License | 5 votes |
EventFrequentlyAskedQuestionsSection = ({
type,
children,
title = "Frequently Asked Questions",
subtitle = "Answers to some questions we get a lot of!",
}) => {
const [opened, setOpened] = useState(null)
const data = React.useContext(EventContext)
return (
<Section title={title} subtitle={subtitle} type={type}>
<div className="container">
<div className="row">
{partition(data.mdx.frontmatter.faq, 2).map((column, index) => (
<div className="col-12 col-md-6" key={index}>
{column.map(faq => (
<div
key={faq.fields.slug}
onClick={() => {
if (faq.fields.slug === opened) {
setOpened(null)
} else {
setOpened(faq.fields.slug)
}
}}
>
<Collapsable
title={faq.frontmatter.name}
collapsed={opened !== faq.fields.slug}
>
<MDXRenderer>{faq.body}</MDXRenderer>
</Collapsable>
</div>
))}
</div>
))}
{children}
</div>
</div>
</Section>
)
}
Example #16
Source File: SpeakerCard.js From codeursenseine.com with MIT License | 5 votes |
SpeakerCard = ({ speaker }) => {
const {
name,
image: { publicURL },
company,
twitterLink,
githubLink,
} = speaker?.childMdx?.frontmatter;
const { body } = speaker?.childMdx;
return (
<Card borderLeftWidth={2} borderLeftColor="brand.600">
<Flex>
<Box mr={4}>
<AspectRatio ratio={1} w="6em" maxW="100%">
<Image src={publicURL} borderRadius={4} />
</AspectRatio>
</Box>
<Box>
<Heading fontSize="lg">{name}</Heading>
<Heading fontSize="md">{company}</Heading>
{twitterLink && (
<IconButton
as="a"
target="_blank"
href={twitterLink}
title={`${name} Twitter`}
icon={<FaTwitter />}
variant="ghost"
colorScheme="brand"
rel="noopener noreferrer"
/>
)}
{githubLink && (
<IconButton
as="a"
target="_blank"
href={githubLink}
title={`${name} Github`}
icon={<FaGithub />}
variant="ghost"
colorScheme="brand"
rel="noopener noreferrer"
/>
)}
</Box>
</Flex>
{body && (
<Box mt={4}>
<MDXRenderer mt={4}>{body}</MDXRenderer>
</Box>
)}
</Card>
);
}
Example #17
Source File: about.js From gatsby-starter-portfolio-minimal with MIT License | 5 votes |
About = ({ content }) => {
const { frontmatter, body } = content[0].node
const { isIntroDone } = useContext(Context).state
const tControls = useAnimation()
const iControls = useAnimation()
// Required for animating the text content
const tRef = useRef()
const tOnScreen = useOnScreen(tRef)
// Required for animating the image
const iRef = useRef()
const iOnScreen = useOnScreen(iRef)
// Only trigger animations if the intro is done or disabled
useEffect(() => {
if (isIntroDone) {
if (tOnScreen) tControls.start({ opacity: 1, y: 0 })
if (iOnScreen) iControls.start({ opacity: 1, x: 0 })
}
}, [isIntroDone, tControls, iControls, tOnScreen, iOnScreen])
return (
<StyledSection id="about">
<StyledContentWrapper>
<motion.div
className="inner-wrapper"
ref={tRef}
initial={{ opacity: 0, y: 20 }}
animate={tControls}
>
<h3 className="section-title">{frontmatter.title}</h3>
<div className="text-content">
<MDXRenderer>{body}</MDXRenderer>
</div>
</motion.div>
<motion.div
className="image-content"
ref={iRef}
initial={{ opacity: 0, x: 20 }}
animate={iControls}
>
<Img
className="about-author"
fluid={frontmatter.image.childImageSharp.fluid}
/>
</motion.div>
</StyledContentWrapper>
</StyledSection>
)
}
Example #18
Source File: hero.js From gatsby-starter-portfolio-minimal with MIT License | 5 votes |
Hero = ({ content }) => {
const { frontmatter, body } = content[0].node
const { isIntroDone, darkMode } = useContext(Context).state
// Controls to orchestrate animations of greetings, emoji, social profiles, underlining
const gControls = useAnimation()
const eControls = useAnimation()
const sControls = useAnimation()
const uControls = useAnimation()
// Start Animations after the splashScreen sequence is done
useEffect(() => {
const pageLoadSequence = async () => {
if (isIntroDone) {
eControls.start({
rotate: [0, -10, 12, -10, 9, 0, 0, 0, 0, 0, 0],
transition: { duration: 2.5, loop: 3, repeatDelay: 1 },
})
await gControls.start({
opacity: 1,
y: 0,
transition: { delay: 0.4 },
})
await sControls.start({
opacity: 1,
x: 0,
})
// Animate underlining to hover state
await uControls.start({
boxShadow: `inset 0 -2rem 0 ${
darkMode ? darkTheme.colors.secondary : lightTheme.colors.secondary
}`,
transition: { delay: 0.4, ease: "circOut" },
})
}
}
pageLoadSequence()
}, [isIntroDone, darkMode, eControls, gControls, sControls, uControls])
return (
<StyledSection id="hero">
<StyledContentWrapper>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={gControls}
data-testid="animated-heading"
>
<h1 className="title">
<div className="greetings">
{frontmatter.greetings}
<motion.div
animate={eControls}
style={{ originX: 0.7, originY: 0.7 }}
>
<Img
className="emoji"
fluid={frontmatter.icon.childImageSharp.fluid}
/>
</motion.div>
</div>
{frontmatter.title}
</h1>
<h2 className="subtitle">
{frontmatter.subtitlePrefix}{" "}
<AnimatedUnderlining animate={uControls} big>
{frontmatter.subtitle}
</AnimatedUnderlining>
</h2>
<div className="description">
<MDXRenderer>{body}</MDXRenderer>
</div>
</motion.div>
<motion.div initial={{ opacity: 0, x: 20 }} animate={sControls}>
<Social fontSize=".95rem" padding=".3rem 1.25rem" width="auto" />
</motion.div>
</StyledContentWrapper>
</StyledSection>
)
}
Example #19
Source File: blog-post.js From gatsby-starter-graphcms-blog with BSD Zero Clause License | 4 votes |
function BlogPostTemplate({
data: { authorImage, coverImage },
pageContext: { nextPost, page, previousPost },
}) {
return (
<article>
<header className="pt-6 lg:pb-10">
<div className="space-y-1 text-center">
<dl className="space-y-10">
<div>
<dt className="sr-only">Published on</dt>
<dd className="text-base leading-6 font-medium text-gray-500">
<time dateTime={page.date}>{page.date}</time>
</dd>
</div>
</dl>
<div>
<h1 className="text-3xl leading-9 font-extrabold text-gray-900 tracking-tight sm:text-4xl sm:leading-10 md:text-5xl md:leading-14">
{page.title}
</h1>
</div>
</div>
</header>
<div
className="divide-y lg:divide-y-0 divide-gray-200 lg:grid lg:grid-cols-4 lg:col-gap-6 pb-16 lg:pb-20"
style={{ gridTemplateRows: 'auto 1fr' }}
>
<dl className="pt-6 pb-10 lg:pt-11 lg:border-b lg:border-gray-200">
<dt className="sr-only">Author</dt>
<dd>
<ul className="flex justify-center lg:block space-x-8 sm:space-x-12 lg:space-x-0 lg:space-y-8">
<li className="flex space-x-2">
<Img
fluid={authorImage.localFile.childImageSharp.fluid}
className="w-10 h-10 rounded-full"
fadeIn={false}
/>
<dl className="flex-1 text-sm font-medium leading-5">
<dt className="sr-only">Name</dt>
<dd className="text-gray-900">{page.author.name}</dd>
{page.author.title && (
<React.Fragment>
<dt className="sr-only">Title</dt>
<dd className="text-gray-500">{page.author.title}</dd>
</React.Fragment>
)}
</dl>
</li>
</ul>
</dd>
</dl>
<div className="divide-y divide-gray-200 lg:pb-0 lg:col-span-3 lg:row-span-2">
{coverImage && (
<Img
fluid={coverImage.localFile.childImageSharp.fluid}
className="mb-8 rounded"
fadeIn={false}
/>
)}
<div className="prose max-w-none pt-10 pb-8">
<MDXRenderer>{page.content.markdownNode.childMdx.body}</MDXRenderer>
</div>
</div>
<footer className="text-sm font-medium leading-5 divide-y divide-gray-200 lg:col-start-1 lg:row-start-2">
{(nextPost || previousPost) && (
<div className="space-y-8 py-8">
{nextPost && (
<div>
<h2 className="text-xs tracking-wide uppercase text-gray-500">
Next Post
</h2>
<div className="text-purple-500 hover:text-purple-600">
<Link to={`/posts/${nextPost.slug}`}>{nextPost.title}</Link>
</div>
</div>
)}
{previousPost && (
<div>
<h2 className="text-xs tracking-wide uppercase text-gray-500">
Previous Post
</h2>
<div className="text-purple-500 hover:text-purple-600">
<Link to={`/posts/${previousPost.slug}`}>
{previousPost.title}
</Link>
</div>
</div>
)}
</div>
)}
<div className="pt-8">
<Link to="/" className="text-purple-500 hover:text-purple-600">
← Back to the blog
</Link>
</div>
</footer>
</div>
</article>
)
}
Example #20
Source File: projects.js From gatsby-starter-portfolio-minimal with MIT License | 4 votes |
Projects = ({ content }) => {
const { darkMode } = useContext(Context).state
const sectionDetails = content[0].node
const projects = content.slice(1, content.length)
// visibleProject is needed to show which project is currently
// being viewed in the horizontal slider on mobile and tablet
const [visibleProject, setVisibleProject] = useState(1)
// projects don't track the visibility by using the onScreen hook
// instead they use react-visibility-sensor, therefore their visibility
// is also stored differently
const [onScreen, setOnScreen] = useState({})
const handleOnScreen = el => {
if (!onScreen[el]) {
const updatedOnScreen = { ...onScreen }
updatedOnScreen[el] = true
setOnScreen(updatedOnScreen)
}
}
const pVariants = {
hidden: { opacity: 0, y: 20 },
visible: { opacity: 1, y: 0 },
}
useEffect(() => {
// mobile and tablet only: set first project as visible in the
// horizontal slider
setVisibleProject(1)
// required for animations: set visibility for all projects to
// "false" initially
let initial = {}
projects.forEach(project => {
initial[project.node.frontmatter.position] = false
})
setOnScreen(initial)
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
// Required for animating the title
const tRef = useRef()
const tOnScreen = useOnScreen(tRef)
const tVariants = {
hidden: { opacity: 0 },
visible: { opacity: 1 },
}
// Required for animating the button
const bRef = useRef()
const bOnScreen = useOnScreen(bRef)
const bVariants = {
hidden: { opacity: 0 },
visible: { opacity: 1 },
}
return (
<StyledSection id="projects">
<StyledContentWrapper>
<motion.div
ref={tRef}
variants={tVariants}
animate={tOnScreen ? "visible" : "hidden"}
>
<h3 className="section-title">{sectionDetails.frontmatter.title}</h3>
<div className="counter">
{visibleProject} / {projects.length}
</div>
</motion.div>
<div className="projects">
{projects.map((project, key) => {
const { body, frontmatter } = project.node
return (
<VisibilitySensor
key={key}
onChange={() => handleOnScreen(key + 1)}
partialVisibility={true}
minTopValue={100}
>
<StyledProject
position={key + 1}
variants={pVariants}
animate={
onScreen[frontmatter.position] ? "visible" : "hidden"
}
>
<div className="details">
<div className="category">
{frontmatter.emoji} {frontmatter.category}
</div>
<div className="title">{frontmatter.title}</div>
<MDXRenderer>{body}</MDXRenderer>
<div className="tags">
{frontmatter.tags.map(tag => (
<Underlining key={tag} highlight>
{tag}
</Underlining>
))}
</div>
<div className="links">
{frontmatter.github && (
<a
href={frontmatter.github}
target="_blank"
rel="nofollow noopener noreferrer"
aria-label="External Link"
>
<Icon
name="github"
color={
darkMode
? darkTheme.colors.subtext
: lightTheme.colors.subtext
}
/>
</a>
)}
{frontmatter.external && (
<a
href={frontmatter.external}
target="_blank"
rel="nofollow noopener noreferrer"
aria-label="External Link"
>
<Icon
name="external"
color={
darkMode
? darkTheme.colors.subtext
: lightTheme.colors.subtext
}
/>
</a>
)}
</div>
</div>
{/* If image in viewport changes, update state accordingly */}
<VisibilitySensor
onChange={() => setVisibleProject(frontmatter.position)}
>
<Img
className="screenshot"
fluid={frontmatter.screenshot.childImageSharp.fluid}
/>
</VisibilitySensor>
</StyledProject>
</VisibilitySensor>
)
})}
</div>
</StyledContentWrapper>
{sectionDetails.frontmatter.buttonVisible && (
<motion.a
ref={bRef}
variants={bVariants}
animate={bOnScreen ? "visible" : "hidden"}
className="cta-btn"
href={sectionDetails.frontmatter.buttonUrl}
target="_blank"
rel="nofollow noopener noreferrer"
aria-label="External Link"
>
<Button type="button" textAlign="center" center>
{sectionDetails.frontmatter.buttonText}
</Button>
</motion.a>
)}
</StyledSection>
)
}
Example #21
Source File: blog-post.js From blog with Apache License 2.0 | 4 votes |
BlogPostTemplate = ({ data, pageContext, location }) => {
const post = data.mdx;
const siteTitle = data.site.siteMetadata.title;
const { previous, next } = pageContext;
const author = AuthorData[post.frontmatter.author];
const tags = post.frontmatter.tags;
let twitterCard = null;
if (post.frontmatter && post.frontmatter.featuredImage) {
twitterCard = post.frontmatter.featuredImage.childImageSharp.sizes.src;
}
return (
<Layout location={location} title={siteTitle}>
<SEO
title={post.frontmatter.title}
description={post.frontmatter.description || post.excerpt}
twitterCard={twitterCard}
/>
<article>
<header>
<h1
style={{
marginTop: rhythm(1),
marginBottom: 0,
}}
>
{post.frontmatter.title}
</h1>
<p
>
</p>
<Byline date={post.frontmatter.date} author={author.name} identifier={post.frontmatter.author} />
<ShareButton location={location} siteMetadata={data.site.siteMetadata} post={post.frontmatter}/>
</header>
<MDXProvider components={components}>
<MDXRenderer>{post.body}</MDXRenderer>
</MDXProvider>
<Tags tags={tags}/>
<Comments/>
<hr
style={{
marginTop: rhythm(1),
marginBottom: rhythm(1),
}}
/>
<footer>
<Author identifier={post.frontmatter.author} author={author} />
</footer>
</article>
<nav>
<ul
style={{
display: "flex",
flexWrap: "wrap",
justifyContent: "space-between",
listStyle: "none",
padding: 0,
}}
>
<li>
{next && (
<Link to={next.fields.postPath} rel="next">
← {next.frontmatter.title}
</Link>
)}
</li>
<li>
{previous && (
<Link to={previous.fields.postPath} rel="prev">
{previous.frontmatter.title} →
</Link>
)}
</li>
</ul>
</nav>
</Layout>
);
}
Example #22
Source File: blog-post.js From adarshaacharya.com.np with MIT License | 4 votes |
BlogPostTemplate = ({ data, pageContext }) => {
const commentBox = React.createRef();
const { theme } = useDarkMode();
const post = data.mdx;
const { previous, next, slug } = pageContext;
React.useEffect(() => {
const commentScript = document.createElement('script');
// theme for github
const commentsTheme =
theme && theme === 'dark' ? 'github-dark' : 'github-light';
commentScript.async = true;
commentScript.src = 'https://utteranc.es/client.js';
commentScript.setAttribute('repo', commentsRepo);
commentScript.setAttribute('issue-term', 'pathname');
commentScript.setAttribute('label', 'blog-comment');
commentScript.setAttribute('theme', commentsTheme);
commentScript.setAttribute('crossorigin', 'anonymous');
if (commentBox && commentBox.current) {
commentBox.current.appendChild(commentScript);
} else {
console.log(`Error adding utterances comments on: ${commentBox}`);
}
const removeScript = () => {
commentScript.remove();
document.querySelectorAll('.utterances').forEach(el => el.remove());
};
// clean up on component unmount
return () => {
removeScript();
};
}, [theme]); // eslint-disable-line
return (
<Layout>
<SEO
title={post.frontmatter.title}
author={post.frontmatter.author}
description={post.frontmatter.description}
keywords={post.frontmatter.tags}
slug={`/blog/${slug}`}
isBlogPost
/>
<hr />
<PostHeader>
<PostTitle>{post.frontmatter.title}</PostTitle>
<Flex justify="space-between">
<span role="img" aria-label="author">
? {post.frontmatter.author}
</span>
<span role="img" aria-label="date">
{' '}
?️ {post.frontmatter.date}
</span>
<span role="img" aria-label="readingTime">
? {post.fields.readingTime.text}
</span>
</Flex>
</PostHeader>
<hr />
<div className="blog-content">
<MDXRenderer>{post.body}</MDXRenderer>
</div>
<hr />
<div id="comments">
<h2>Comments</h2>
<Comment ref={commentBox} />
</div>
{/* recommendation */}
<Flex justify="space-between" className="recommendation">
{previous && (
<Link to={`/blog/${previous.frontmatter.slug}/`} rel="prev">
← {previous.frontmatter.title}
</Link>
)}
{next && (
<Link to={`/blog/${next.frontmatter.slug}/`} rel="next">
{next.frontmatter.title} →
</Link>
)}
</Flex>
<Subscribe />
</Layout>
);
}
Example #23
Source File: post.jsx From xetera.dev with MIT License | 4 votes |
export default function Post(props) {
const { data, pageContext } = props
const post = data.mdx
const { previous, next, ogImage } = pageContext
const { imageTop, imageBottom } = post.frontmatter
const isDraft = post.frontmatter.draft
const distance = formatDistance(new Date(post.frontmatter.date), new Date(), {
addSuffix: true,
})
return (
<>
<Layout imageTop={imageTop} imageBottom={imageBottom}>
<LayoutContent mx="auto" width="100%">
<SEO
canonical={post.slug}
title={post.frontmatter.title}
description={post.frontmatter.description || post.excerpt}
image={ogImage}
/>
<Grid gap={24}>
<CenteredGrid
gridRowGap={3}
as="header"
mx="auto"
width="100%"
mt={[8, 12, 18]}
>
<Text color="text.300">
<Box
as="span"
fontWeight="semibold"
color="brand.100"
textTransform="uppercase"
>
{isDraft && "Draft"} Article
</Box>
<Box mx={3} as="span">
—
</Box>
{post.fields.readingTime.text}
</Text>
<Heading
as="h1"
mb={2}
color="text.200"
fontSize={["3xl", "4xl", "7xl"]}
lineHeight="110%"
fontWeight="black"
>
{post.frontmatter.title}
</Heading>
<Text
as="h2"
fontSize={["lg", "xl"]}
fontWeight="normal"
color="text.300"
mb={4}
>
{post.frontmatter.description}
</Text>
{isDraft && <DraftDisclaimer />}
<Hr />
<Flex
alignItems="flex-start"
color="text.400"
justify="space-between"
flexDirection={{ base: "column", md: "row" }}
>
<HStack
mb={{ base: 2, md: 0 }}
justify="center"
textTransform="capitalize"
// fontSize="sm"
spacing={{ base: 4, md: 6 }}
fontWeight="medium"
>
{post.frontmatter.tags.map((tag, i) => (
<Text color="brand.100" key={tag}>
{tag}
</Text>
))}
</HStack>
<Flex
alignItems={{ base: "flex-start", md: "flex-end" }}
flexDirection="column"
>
<Text
as="time"
dateTime={post.frontmatter.date}
color="text.100"
>
{post.frontmatter.date}
</Text>
<Text fontSize="sm">{distance}</Text>
</Flex>
</Flex>
</CenteredGrid>
<CenteredGrid
className="blog-post centered-grid"
fontSize="lg"
lineHeight={{ base: "180%", md: "200%" }}
>
<ExContextWrapper>
<MDXProvider
components={{
T,
...Chatbox,
...MarkdownComponents,
...MarkdownOverrides,
...postData,
Link,
Box,
Flex,
Grid,
Button,
getImage,
Constrain,
ImageWrapper,
WideMedia,
GatsbyImage,
StaticImage,
maxWidth,
Text,
Heading,
Skeleton,
Tag,
ChakraImage: Image,
Image,
Toastable,
Hr,
a: ({ children, ...props }) => (
<Link color="brandSecondary" {...props}>
{children}
</Link>
),
RoughNotation,
h6: makeHeader("h6"),
h5: makeHeader("h5"),
h4: makeHeader("h4", { fonts: ["md", "lg", "xl"] }),
h3: makeHeader("h3", { fonts: ["md", "lg", "2xl"] }),
h2: makeHeader("h2", { fonts: ["md", "lg", "2xl"], mt: 6 }),
h1: makeHeader("h1", {
fonts: ["lg", "xl", "4xl"],
mt: 8,
mb: 8,
}),
table: ({ children, ...props }) => (
<Box overflowX="auto" mb={8}>
<Table {...props}>{children}</Table>
</Box>
),
th: Th,
tr: Tr,
td: ({ children, ...props }) => (
<Td
fontSize={["sm", "md", "lg"]}
verticalAlign="initial"
{...props}
>
{children}
</Td>
),
ul: ({ children, ...props }) => (
<Box
as="ul"
listStyleType={sample([
"katakana",
"hiragana",
"simp-chinese-formal",
"korean-hanja-formal",
"korean-hangul-formal",
])}
fontSize={["md", null, "lg"]}
mb={8}
{...props}
>
{children}
</Box>
),
blockquote: ({ children, ...props }) => (
<Box
as="blockquote"
textAlign="center"
borderColor="borderSubtle"
fontSize={{ base: "lg", lg: "2xl" }}
color="text.200"
mt={4}
mb={8}
px={{ base: 8, lg: 24 }}
{...props}
>
{children}
</Box>
),
p: ({ children, ...props }) => (
<Text
as="p"
fontSize={["md", null, "lg"]}
mb={8}
{...props}
>
{children}
</Text>
),
}}
>
<MDXRenderer>{post.body}</MDXRenderer>
</MDXProvider>
</ExContextWrapper>
</CenteredGrid>
{!isDraft && (
<CenteredGrid>
<Box as="footer">
<Grid
as="section"
gridAutoFlow="row"
alignItems="center"
justifyContent="center"
gridTemplateColumns={["1fr", null, null, "1fr 1fr"]}
flexDirection={["row", "column"]}
gap={4}
m={0}
p={0}
className="justify-center flex flex-row p-0 m-0 text-sm w-fullgap-4"
>
<Navigator pos="left" link={previous} />
<Navigator pos="right" link={next} />
</Grid>
</Box>
</CenteredGrid>
)}
</Grid>
<PopupPortal>
<Popup />
</PopupPortal>
</LayoutContent>
</Layout>
</>
)
}
Example #24
Source File: index.js From gatsby-blog-mdx with MIT License | 4 votes |
render() {
const post = this.props.data.mdx
const isAboutPage = post.fields.slug.includes("/about")
// Customize markdown component
const mdxComponents = {
"ul.li": ({ children }) => {
return (
<li>
<span className="icon-wrap">
<ChevronRight className="icon-chevron-right" />
</span>
<span className="ul-children">{children}</span>
</li>
)
},
"ol.li": ({ children }) => {
return (
<li>
<span>{children}</span>
</li>
)
},
hr: () => <Hr widthInPercent="100" verticalMargin="0.8rem" />,
// Use the below components without having to import in *.mdx
Primary,
Danger,
Warning,
Success,
Info,
Collapsable,
U,
}
return (
<Layout showTitle={true} isPostTemplate>
<SEO title={post.frontmatter.title} description={post.excerpt} />
<div
className="switch-container"
style={{ textAlign: "end", margin: "0 1.1rem" }}
>
<ToggleMode />
</div>
<StyledHTML className="post-html">
{!isAboutPage && (
<>
<h1 className="post-title">{post.frontmatter.title}</h1>
{/* Show tag & date */}
<div
className="post-data"
style={{
display: "flex",
justifyContent: "space-between",
alignItems: "center",
marginBottom: "0.5rem",
}}
>
<div style={{ display: "flex", alignItems: "center" }}>
<div style={{ display: "flex", flexWrap: "wrap" }}>
{post.frontmatter.tags &&
post.frontmatter.tags.map((tag, i) => (
<p
key={i}
style={{
margin: "0.3rem 0.3rem",
padding: "0.15rem 0.4rem",
border: "1px solid #aaa",
borderRadius: "5px",
fontSize: "0.8rem",
}}
>
{tag}
</p>
))}
</div>
</div>
<p
style={{
fontStyle: "italic",
margin: "0",
marginBottom: "0.3rem",
}}
>
{post.frontmatter.date}
</p>
</div>
<Hr />
</>
)}
{/* Render mdx */}
<MDXProvider components={mdxComponents}>
<MDXRenderer>{post.body}</MDXRenderer>
</MDXProvider>
</StyledHTML>
{!isAboutPage && (
<>
<ShareButtons location={this.state.location} />
<LinkEdgePosts pageContext={this.props.pageContext} />
<Hr widthInPercent="97" verticalMargin="0.8rem" />
<Profile />
<Hr widthInPercent="97" verticalMargin="0.8rem" />
{comments.facebook.enabled && (
<FacebookComments
location={this.state.location}
reload={this.registerFacebookComments}
/>
)}
{comments.disqus.enabled && comments.disqus.shortName && (
<DisqusComments
shortName={comments.disqus.shortName}
location={this.state.location}
/>
)}
{comments.utterances.enabled && comments.utterances.repoUrl && (
<UtterancesComments innerRef={this.utterancesRef} />
)}
</>
)}
</Layout>
)
}
Example #25
Source File: SponsorCard.js From codeursenseine.com with MIT License | 4 votes |
SponsorCard = ({ logoSrc, link, name, excerpt, children }) => {
const containerRef = React.useRef();
const contentRef = React.useRef();
const [isExpandable, setIsExpandable] = React.useState(false);
const { isOpen, onOpen, onClose } = useDisclosure();
React.useEffect(() => {
if (containerRef.current && contentRef.current) {
setIsExpandable(
contentRef.current.offsetHeight - containerRef.current.offsetHeight > 0
);
}
}, [setIsExpandable]);
return (
<>
<Card
ref={containerRef}
as="article"
maxH="22rem"
position="relative"
p={0}
>
<Box ref={contentRef} p={6}>
{logoSrc && (
<>
<Link
d="block"
href={link}
title={name}
target="_blank"
rel="noopener noreferrer"
>
<AspectRatio ratio={320 / 190}>
<Image src={logoSrc} alt={name} objectFit="fit" />
</AspectRatio>
</Link>
<Divider />
</>
)}
<Box d="flex" alignItems="baseline">
<A href={link} title={name} target="_blank">
{name}
</A>
</Box>
<Text fontSize="sm">{excerpt}</Text>
</Box>
{isExpandable && (
<Box
position="absolute"
bottom={0}
left={0}
right={0}
pt={16}
textAlign="center"
background="linear-gradient(0deg, rgba(255,255,255,1) 50%, rgba(255,255,255,0) 100%)"
>
<Button
onClick={onOpen}
variant="unstyled"
d="inline-block"
fontSize="sm"
h="auto"
m={4}
p={4}
py={2}
_hover={{ color: "brand.600" }}
>
Lire la suite
</Button>
</Box>
)}
</Card>
<Modal motionPreset="scale" isOpen={isOpen} onClose={onClose}>
<ModalOverlay />
<ModalContent>
<ModalHeader fontSize="xl">
<Box>
<Text>{name}</Text>
</Box>
</ModalHeader>
<ModalCloseButton />
<ModalBody>
<MDXRenderer>{children}</MDXRenderer>
</ModalBody>
</ModalContent>
</Modal>
</>
);
}
Example #26
Source File: ConferenceCard.js From codeursenseine.com with MIT License | 4 votes |
ConferenceCard = ({ conference, speakers }) => {
const { isOpen, onOpen, onClose } = useDisclosure();
const capitalizeFirstLetter = (string) =>
string.charAt(0).toUpperCase() + string.slice(1);
if (conference?.childMdx?.frontmatter?.type === "break") {
return (
<Card variant="primary" mt={2}>
<Stack align="center">
<Text>{conference?.childMdx?.frontmatter?.title}</Text>
</Stack>
</Card>
);
}
return (
<Stack>
<Grid
templateColumns={["repeat(1, 1fr)", "repeat(1, 1fr) repeat(1, 4fr)"]}
mt={3}
>
<Stack mr={3}>
<Flex
display={["none", "flex"]}
flexDirection="column"
justifyContent="space-between"
h="100%"
borderColor="blue.50"
borderStyle="solid"
borderTopWidth={1}
borderBottomWidth={1}
>
<Text color="blue.600">
{conference.childMdx.frontmatter.startHour}
</Text>
<Text color="blue.600">
{conference.childMdx.frontmatter.endHour}
</Text>
</Flex>
<Stack display={["block", "none"]} mb={2}>
<Text color="blue.600">
{`${conference.childMdx.frontmatter.startHour} - ${conference.childMdx.frontmatter.endHour}`}
</Text>
</Stack>
{conference.childMdx.frontmatter.isKeynote && (
<Badge colorScheme="brand" width="fit-content">
Keynote
</Badge>
)}
</Stack>
<Card
borderLeftWidth={2}
borderLeftColor="brand.600"
onClick={onOpen}
w="full"
isLink
>
<Heading fontSize="md">
{conference.childMdx.frontmatter.title}
</Heading>
{speakers?.map((speaker) => (
<SpeakerPreview
key={speaker.childMdx.frontmatter.slug}
speaker={speaker}
/>
))}
<Center>
<Button
colorScheme="brand"
variant="link"
width="fit-content"
mt={2}
>
Voir les détails et s'inscrire
</Button>
</Center>
</Card>
</Grid>
<Drawer size="md" isOpen={isOpen} placement="right" onClose={onClose}>
<DrawerOverlay>
<DrawerContent>
<DrawerCloseButton />
<DrawerHeader>
<Stack alignItems="center" display="flex" flexDirection="row">
<Text fontSize="sm" mt={2}>
{capitalizeFirstLetter(
dayjs(conference.childMdx.frontmatter.eventDate).format(
"dddd D MMM"
)
)}{" "}
{`${conference.childMdx.frontmatter.startHour} - ${conference.childMdx.frontmatter.endHour}`}
</Text>
{conference.childMdx.frontmatter.isKeynote && (
<Badge
ml={3}
h="fit-content"
colorScheme="brand"
width="fit-content"
>
Keynote
</Badge>
)}
</Stack>
<Text>{conference.childMdx.frontmatter.title}</Text>
<Stack mt={3}>
{speakers?.map((speaker) => (
<SpeakerPreview
key={speaker.childMdx.frontmatter.slug}
speaker={speaker}
/>
))}
</Stack>
</DrawerHeader>
<DrawerBody overflow="auto">
<MDXRenderer>{conference.childMdx.body}</MDXRenderer>
</DrawerBody>
{conference.childMdx.frontmatter.meetupLink && (
<DrawerFooter display="flex" flexDirection="column">
<Button isFullWidth variant="outline" mb={3} onClick={onClose}>
Fermer
</Button>
<Button
colorScheme="brand"
as={Link}
target="_blank"
to={conference.childMdx.frontmatter.meetupLink}
isFullWidth
>
S'inscrire
</Button>
</DrawerFooter>
)}
</DrawerContent>
</DrawerOverlay>
</Drawer>
</Stack>
);
}