Updates from template
This commit is contained in:
@ -1,8 +1,6 @@
|
||||
import React from 'react';
|
||||
import { graphql, useStaticQuery } from 'gatsby';
|
||||
import { graphql, useStaticQuery, Link } from 'gatsby';
|
||||
import { connect } from 'react-redux';
|
||||
import AniLink from 'gatsby-plugin-transition-link/AniLink';
|
||||
import ReactCSSTransitionReplace from 'react-css-transition-replace';
|
||||
import config from '../../../config';
|
||||
|
||||
import { toggleDarkMode } from '../state/app';
|
||||
@ -58,48 +56,34 @@ const Shell = ({
|
||||
<div className={isDarkMode ? 'page-container dark' : 'page-container'}>
|
||||
{/* Menu */}
|
||||
<header className='menu'>
|
||||
<AniLink
|
||||
cover
|
||||
direction={viewportWidth < 600 ? 'up' : 'right'}
|
||||
bg={isDarkMode ? '#434E76' : '#FFFFFF'}
|
||||
<Link
|
||||
to='/search'
|
||||
aria-label='Search'
|
||||
aria-label='Search' title='Search'
|
||||
className={isSearch ? 'menu-button active' : 'menu-button'}
|
||||
>
|
||||
<SearchIcon />
|
||||
</AniLink>
|
||||
<AniLink
|
||||
cover
|
||||
direction={viewportWidth < 600 ? 'up' : 'right'}
|
||||
bg={isDarkMode ? '#434E76' : '#FFFFFF'}
|
||||
</Link>
|
||||
<Link
|
||||
to='/list'
|
||||
aria-label='Snippet list'
|
||||
aria-label='Snippet list' title='Snippet list'
|
||||
className={isList ? 'menu-button active' : 'menu-button'}
|
||||
>
|
||||
<ListIcon />
|
||||
</AniLink>
|
||||
</Link>
|
||||
{/* eslint-disable-next-line */}
|
||||
<a target='_blank'
|
||||
rel='noopener'
|
||||
href={config.repositoryUrl}
|
||||
aria-label='View on GitHub'
|
||||
title='View on GitHub'
|
||||
className='menu-button'
|
||||
>
|
||||
<GithubIcon />
|
||||
</a>
|
||||
{/*
|
||||
The use of React.Fragment here will cause a lot of errors to show up in webber:dev.
|
||||
Truth is, this is the only decent way I found to deal with this module's odd behavior.
|
||||
Keep as is, unless you can provide a better solution, in which case please send a PR.
|
||||
*/}
|
||||
<ReactCSSTransitionReplace
|
||||
transitionName='cross-fade'
|
||||
transitionEnterTimeout={300}
|
||||
transitionLeaveTimeout={300}
|
||||
component='button'
|
||||
<button
|
||||
aria-label={isDarkMode ? 'Switch to light mode' : 'Switch to dark mode'}
|
||||
title={isDarkMode ? 'Switch to light mode' : 'Switch to dark mode'}
|
||||
className='menu-button'
|
||||
childComponent={React.Fragment}
|
||||
>
|
||||
{isDarkMode ? (
|
||||
<LightModeIcon
|
||||
@ -112,7 +96,7 @@ const Shell = ({
|
||||
onClick={() => dispatch(toggleDarkMode(!isDarkMode))}
|
||||
/>
|
||||
)}
|
||||
</ReactCSSTransitionReplace>
|
||||
</button>
|
||||
</header>
|
||||
{/* Content */}
|
||||
<div className='content'>
|
||||
|
||||
@ -1,13 +1,12 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'gatsby';
|
||||
import { CopyToClipboard } from 'react-copy-to-clipboard';
|
||||
import config from '../../../config';
|
||||
|
||||
import { getTextualContent, getCodeBlocks, optimizeAllNodes } from '../util';
|
||||
// import ShareIcon from './SVGs/ShareIcon';
|
||||
import AniLink from 'gatsby-plugin-transition-link/AniLink';
|
||||
import CollapseOpenIcon from './SVGs/CollapseOpenIcon';
|
||||
import CollapseClosedIcon from './SVGs/CollapseClosedIcon';
|
||||
import ReactCSSTransitionReplace from 'react-css-transition-replace';
|
||||
|
||||
// ===================================================
|
||||
// Snippet Card HOC - check components below for more
|
||||
@ -95,18 +94,12 @@ const FullCard = ({ snippetData, difficulty, isDarkMode }) => {
|
||||
>
|
||||
{examplesOpen ? <CollapseOpenIcon /> : <CollapseClosedIcon />}Examples
|
||||
</button>
|
||||
<ReactCSSTransitionReplace
|
||||
transitionName='roll-up'
|
||||
transitionEnterTimeout={300}
|
||||
transitionLeaveTimeout={300}
|
||||
>
|
||||
{examplesOpen && (
|
||||
<pre
|
||||
className='section card-examples language-py'
|
||||
dangerouslySetInnerHTML={{ __html: cardExamplesHtml }}
|
||||
/>
|
||||
)}
|
||||
</ReactCSSTransitionReplace>
|
||||
{examplesOpen && (
|
||||
<pre
|
||||
className='section card-examples language-py'
|
||||
dangerouslySetInnerHTML={{ __html: cardExamplesHtml }}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@ -127,50 +120,46 @@ const ShortCard = ({
|
||||
getCodeBlocks(snippetData.html).code,
|
||||
)}`;
|
||||
return (
|
||||
<div className='card short'>
|
||||
<CardCorner difficulty={difficulty} />
|
||||
<h4 className='card-title'>
|
||||
<AniLink
|
||||
paintDrip
|
||||
to={`/snippet/${snippetData.id}`}
|
||||
hex={isDarkMode ? '#434E76' : '#FFFFFF'}
|
||||
>
|
||||
<Link to={`/snippet/${snippetData.id}`} rel='canonical' className='clickable-card-wrapper'>
|
||||
<div className='card short'>
|
||||
<CardCorner difficulty={difficulty} />
|
||||
<h4 className='card-title'>
|
||||
{snippetData.title}
|
||||
</AniLink>
|
||||
</h4>
|
||||
<div
|
||||
className='card-description'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `${getTextualContent(snippetData.html)}`,
|
||||
}}
|
||||
/>
|
||||
{withCode ? <div className='card-bottom'>
|
||||
<CopyToClipboard
|
||||
text={snippetData.code}
|
||||
onCopy={() => {
|
||||
let tst = document.createElement('div');
|
||||
tst.classList = 'toast';
|
||||
tst.innerHTML = 'Snippet copied to clipboard!';
|
||||
document.body.appendChild(tst);
|
||||
setTimeout(function() {
|
||||
tst.style.opacity = 0;
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(tst);
|
||||
}, 300);
|
||||
}, 1700);
|
||||
</h4>
|
||||
<div
|
||||
className='card-description'
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `${getTextualContent(snippetData.html)}`,
|
||||
}}
|
||||
>
|
||||
<button
|
||||
className='button button-a button-copy'
|
||||
aria-label='Copy to clipboard'
|
||||
/>
|
||||
</CopyToClipboard>
|
||||
<pre
|
||||
className={`card-code language-${config.language}`}
|
||||
dangerouslySetInnerHTML={{ __html: cardCodeHtml }}
|
||||
/>
|
||||
</div> : '' }
|
||||
</div>
|
||||
{withCode ? <div className='card-bottom'>
|
||||
<CopyToClipboard
|
||||
text={snippetData.code}
|
||||
onCopy={() => {
|
||||
let tst = document.createElement('div');
|
||||
tst.classList = 'toast';
|
||||
tst.innerHTML = 'Snippet copied to clipboard!';
|
||||
document.body.appendChild(tst);
|
||||
setTimeout(function() {
|
||||
tst.style.opacity = 0;
|
||||
setTimeout(function() {
|
||||
document.body.removeChild(tst);
|
||||
}, 300);
|
||||
}, 1700);
|
||||
}}
|
||||
>
|
||||
<button
|
||||
className='button button-a button-copy'
|
||||
aria-label='Copy to clipboard'
|
||||
/>
|
||||
</CopyToClipboard>
|
||||
<pre
|
||||
className={`card-code language-${config.language}`}
|
||||
dangerouslySetInnerHTML={{ __html: cardCodeHtml }}
|
||||
/>
|
||||
</div> : '' }
|
||||
</div>
|
||||
</Link>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { Link } from 'gatsby';
|
||||
import { connect } from 'react-redux';
|
||||
import AniLink from 'gatsby-plugin-transition-link/AniLink';
|
||||
|
||||
import Shell from '../components/Shell';
|
||||
import Meta from '../components/Meta';
|
||||
@ -21,10 +21,8 @@ const NotFoundPage = ({ isDarkMode }) => (
|
||||
<p className='empty-page-subtext'>
|
||||
Seems like you have reached a page that does not exist.
|
||||
</p>
|
||||
<AniLink
|
||||
paintDrip
|
||||
<Link
|
||||
to='/'
|
||||
hex={isDarkMode ? '#434E76' : '#FFFFFF'}
|
||||
className='button button-a button-home'
|
||||
>
|
||||
<svg
|
||||
@ -43,7 +41,7 @@ const NotFoundPage = ({ isDarkMode }) => (
|
||||
<polyline points='9 22 9 12 15 12 15 22'></polyline>
|
||||
</svg>
|
||||
Go home
|
||||
</AniLink>
|
||||
</Link>
|
||||
</div>
|
||||
</Shell>
|
||||
</>
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
import React from 'react';
|
||||
import { graphql } from 'gatsby';
|
||||
import { graphql, Link } from 'gatsby';
|
||||
import { connect } from 'react-redux';
|
||||
import { pushNewPage } from '../state/app';
|
||||
import { capitalize } from '../util';
|
||||
|
||||
import Shell from '../components/Shell';
|
||||
import Meta from '../components/Meta';
|
||||
import AniLink from 'gatsby-plugin-transition-link/AniLink';
|
||||
import SnippetCard from '../components/SnippetCard';
|
||||
|
||||
import { getRawCodeBlocks as getCodeBlocks } from '../util';
|
||||
@ -60,14 +59,12 @@ const ListPage = props => {
|
||||
{tags.map(tag => (
|
||||
<>
|
||||
<h3 className='tag-title' key={`tag_title_${tag}`}>
|
||||
<AniLink
|
||||
<Link
|
||||
key={`tag_link_${tag}`}
|
||||
paintDrip
|
||||
to={`/tag/${tag}`}
|
||||
hex={props.isDarkMode ? '#434E76' : '#FFFFFF'}
|
||||
>
|
||||
{capitalize(tag)}
|
||||
</AniLink>
|
||||
</Link>
|
||||
</h3>
|
||||
{snippets
|
||||
.filter(snippet => snippet.tags[0] === tag)
|
||||
@ -85,13 +82,11 @@ const ListPage = props => {
|
||||
{staticPages.map(page => (
|
||||
<SimpleCard
|
||||
title={(
|
||||
<AniLink
|
||||
paintDrip
|
||||
<Link
|
||||
to={`/${page.url}`}
|
||||
hex={props.isDarkMode ? '#434E76' : '#FFFFFF'}
|
||||
>
|
||||
{page.title}
|
||||
</AniLink>
|
||||
</Link>
|
||||
)}
|
||||
>
|
||||
<p>{page.description}</p>
|
||||
|
||||
@ -52,6 +52,7 @@
|
||||
background-position: center;
|
||||
width: 44px;
|
||||
height: 44px;
|
||||
z-index: 10;
|
||||
}
|
||||
.button.button-social-sh {
|
||||
position: absolute;
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
// Cards
|
||||
// ===================================================
|
||||
.card {
|
||||
backface-visibility: hidden;
|
||||
will-change: transform;
|
||||
position: relative;
|
||||
transition: all 0.3s ease;
|
||||
margin: 1rem 1.25rem;
|
||||
@ -126,7 +128,7 @@
|
||||
}
|
||||
|
||||
// Tags
|
||||
.tag {
|
||||
:not(.token).tag {
|
||||
transition: 0.3s ease all;
|
||||
border: 2px solid var(--tag-border-color);
|
||||
border-radius: 0.25rem;
|
||||
@ -144,7 +146,13 @@
|
||||
}
|
||||
}
|
||||
|
||||
// Animation for card example
|
||||
.roll-up-height {
|
||||
transition: height 0.3s ease-in-out;
|
||||
.clickable-card-wrapper {
|
||||
&:link, &:visited {
|
||||
&:hover, &:focus {
|
||||
text-decoration: none;
|
||||
.card {
|
||||
transform: scale(1.025);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -28,7 +28,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans Light'), local('NotoSans-Light'), url(../../../assets/NotoSans-Light.ttf) format('truetype');
|
||||
src: local('Noto Sans Light'), local('NotoSans-Light'), url(../../../assets/NotoSans-Light.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
@ -36,7 +36,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 300;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans LightItalic'), local('NotoSans-LightItalic'), url(../../../assets/NotoSans-LightItalic.ttf) format('truetype');
|
||||
src: local('Noto Sans LightItalic'), local('NotoSans-LightItalic'), url(../../../assets/NotoSans-LightItalic.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
@ -44,7 +44,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans'), local('NotoSans-Regular'), url(../../../assets/NotoSans-Regular.ttf) format('truetype');
|
||||
src: local('Noto Sans'), local('NotoSans-Regular'), url(../../../assets/NotoSans-Regular.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
@ -52,7 +52,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 400;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans Italic'), local('NotoSans-Italic'), url(../../../assets/NotoSans-Italic.ttf) format('truetype');
|
||||
src: local('Noto Sans Italic'), local('NotoSans-Italic'), url(../../../assets/NotoSans-Italic.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
@ -60,7 +60,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans Medium'), local('NotoSans-Medium'), url(../../../assets/NotoSans-Medium.ttf) format('truetype');
|
||||
src: local('Noto Sans Medium'), local('NotoSans-Medium'), url(../../../assets/NotoSans-Medium.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
@ -68,7 +68,7 @@
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans Medium Italic'), local('NotoSans-MediumItalic'), url(../../../assets/NotoSans-MediumItalic.ttf) format('truetype');
|
||||
src: local('Noto Sans Medium Italic'), local('NotoSans-MediumItalic'), url(../../../assets/NotoSans-MediumItalic.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
@ -76,7 +76,7 @@
|
||||
font-style: normal;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans SemiBold'), local('NotoSans-SemiBold'), url(../../../assets/NotoSans-SemiBold.ttf) format('truetype');
|
||||
src: local('Noto Sans SemiBold'), local('NotoSans-SemiBold'), url(../../../assets/NotoSans-SemiBold.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@font-face {
|
||||
@ -84,6 +84,6 @@
|
||||
font-style: italic;
|
||||
font-weight: 600;
|
||||
font-display: swap;
|
||||
src: local('Noto Sans SemiBold Italic'), local('NotoSans-SemiBoldItalic'), url(../../../assets/NotoSans-SemiBoldItalic.ttf) format('truetype');
|
||||
src: local('Noto Sans SemiBold Italic'), local('NotoSans-SemiBoldItalic'), url(../../../assets/NotoSans-SemiBoldItalic.woff2) format('woff2');
|
||||
unicode-range: U+0000-00FF, U+0131, U+0152-0153, U+02BB-02BC, U+02C6, U+02DA, U+02DC, U+2000-206F, U+2074, U+20AC, U+2122, U+2191, U+2193, U+2212, U+2215, U+FEFF, U+FFFD;
|
||||
}
|
||||
@ -63,23 +63,3 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Animate transition between light and dark mode
|
||||
.cross-fade-leave {
|
||||
transform: scale(1);
|
||||
}
|
||||
.cross-fade-leave.cross-fade-leave-active {
|
||||
transition: all 0.3s cubic-bezier(0.47, 0, 0.745, 0.715);
|
||||
transform: scale(0.1);
|
||||
}
|
||||
.cross-fade-enter {
|
||||
transform: scale(0.1);
|
||||
}
|
||||
.cross-fade-enter.cross-fade-enter-active {
|
||||
transition: all 0.3s cubic-bezier(0.215, 0.610, 0.355, 1);
|
||||
transform: scale(0.95)
|
||||
}
|
||||
.cross-fade-height {
|
||||
height: 61px;
|
||||
transition: height 0.15s ease-in-out 0.15s;
|
||||
}
|
||||
10
src/docs/templates/SnippetPage.js
vendored
10
src/docs/templates/SnippetPage.js
vendored
@ -1,12 +1,11 @@
|
||||
import React from 'react';
|
||||
import { graphql } from 'gatsby';
|
||||
import { graphql, Link } from 'gatsby';
|
||||
import { connect } from 'react-redux';
|
||||
|
||||
import Meta from '../components/Meta';
|
||||
import Shell from '../components/Shell';
|
||||
import SnippetCard from '../components/SnippetCard';
|
||||
import BackArrowIcon from '../components/SVGs/BackArrowIcon';
|
||||
import AniLink from 'gatsby-plugin-transition-link/AniLink';
|
||||
|
||||
// ===================================================
|
||||
// Individual snippet page template
|
||||
@ -21,16 +20,13 @@ const SnippetPage = props => {
|
||||
<>
|
||||
<Meta title={post.frontmatter.title} description={post.excerpt} />
|
||||
<Shell>
|
||||
<AniLink
|
||||
<Link
|
||||
className='link-back'
|
||||
to={`${props.lastPageUrl}`}
|
||||
cover
|
||||
direction='right'
|
||||
bg={props.isDarkMode ? '#434E76' : '#FFFFFF'}
|
||||
>
|
||||
<BackArrowIcon />
|
||||
Back to {props.lastPageTitle}
|
||||
</AniLink>
|
||||
</Link>
|
||||
<SnippetCard
|
||||
snippetData={{
|
||||
title: postData.title,
|
||||
|
||||
@ -7,19 +7,10 @@ const capitalize = (str, lowerRest = false) =>
|
||||
|
||||
// Get the textual content in a gatsby page
|
||||
const getTextualContent = (str, noExplain = false) => {
|
||||
const regex = /([\s\S]*?)<div class="gatsby-highlight"/g;
|
||||
const results = [];
|
||||
let m = null;
|
||||
while ((m = regex.exec(str)) !== null) {
|
||||
if (m.index === regex.lastIndex) regex.lastIndex += 1;
|
||||
|
||||
m.forEach((match, groupIndex) => {
|
||||
results.push(match);
|
||||
});
|
||||
}
|
||||
if(noExplain)
|
||||
return results[1].slice(0, results[1].lastIndexOf('<p>'));
|
||||
return results[1];
|
||||
const result = str.slice(0, str.indexOf('<div class="gatsby-highlight"'));
|
||||
if (noExplain)
|
||||
return result.slice(0, result.lastIndexOf('<p>'));
|
||||
return result;
|
||||
};
|
||||
|
||||
// Gets the code blocks in a gatsby page
|
||||
|
||||
Reference in New Issue
Block a user