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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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">
              &larr; 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 vote down vote up
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 vote down vote up
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 vote down vote up
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">
            &larr; {previous.frontmatter.title}
          </Link>
        )}

        {next && (
          <Link to={`/blog/${next.frontmatter.slug}/`} rel="next">
            {next.frontmatter.title} &rarr;
          </Link>
        )}
      </Flex>
      <Subscribe />
    </Layout>
  );
}
Example #23
Source File: post.jsx    From xetera.dev with MIT License 4 votes vote down vote up
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 vote down vote up
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 vote down vote up
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 vote down vote up
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>
  );
}