Updated snippet cards (WIP)

This commit is contained in:
Angelos Chalaris
2019-08-23 13:48:48 +03:00
parent 6990b61e44
commit d12e35a5c8
55 changed files with 456 additions and 501 deletions

View File

@ -12,35 +12,18 @@ import ReactCSSTransitionReplace from 'react-css-transition-replace';
// ===================================================
// Snippet Card HOC - check components below for more
// ===================================================
const SnippetCard = ({ short, snippetData, ...rest }) => {
let difficulty = snippetData.tags.includes('advanced')
? 'advanced'
: snippetData.tags.includes('beginner')
? 'beginner'
: 'intermediate';
return short ? (
<ShortCard snippetData={snippetData} difficulty={difficulty} {...rest} />
const SnippetCard = ({ short, snippetData, ...rest }) =>
short ? (
<ShortCard snippetData={snippetData} {...rest} />
) : (
<FullCard snippetData={snippetData} difficulty={difficulty} {...rest} />
<FullCard snippetData={snippetData} {...rest} />
);
};
// ===================================================
// Simple card corner for difficulty display
// ===================================================
const CardCorner = ({ difficulty = 'intermediate' }) => (
<div
className={`card-corner ${difficulty}`}
aria-label={difficulty}
title={difficulty}
/>
);
// ===================================================
// Full snippet view (tags, code, title, description)
// ===================================================
const FullCard = ({ snippetData, difficulty, isDarkMode }) => {
const [examplesOpen, setExamplesOpen] = React.useState(false);
const FullCard = ({ snippetData, isDarkMode }) => {
console.log(snippetData);
const tags = snippetData.tags;
let cardCodeHtml = `${optimizeAllNodes(
getCodeBlocks(snippetData.html).html,
@ -53,11 +36,13 @@ const FullCard = ({ snippetData, difficulty, isDarkMode }) => {
)}`;
return (
<div className='card'>
<CardCorner difficulty={difficulty} />
<h4 className='card-title'>{snippetData.title}</h4>
{tags.map(tag => (
<span className='tag' key={`tag_${tag}`}>{tag}</span>
))}
<h4 className='card-title'>
{snippetData.title}&nbsp;&nbsp;
{tags.map(tag => (
<span className={`tag tag-${tag}`} key={`tag_${tag}`}>{tag}</span>
))}
</h4>
<div
className='card-description'
dangerouslySetInnerHTML={{
@ -65,20 +50,32 @@ const FullCard = ({ snippetData, difficulty, isDarkMode }) => {
}}
/>
<div className='card-bottom'>
<h5 className='card-section-title card-section-html'>HTML</h5>
<pre
className={`card-code language-${config.secondLanguage}`}
dangerouslySetInnerHTML={{ __html: cardCodeHtml }}
/>
<h5 className='card-section-title card-section-css'>CSS</h5>
<pre
className={`card-code language-${config.language}`}
dangerouslySetInnerHTML={{ __html: cardCodeCss }}
/>
{
cardCodeJs && <pre
className={`card-code language-${config.optionalLanguage}`}
dangerouslySetInnerHTML={{ __html: cardCodeJs }}
/>
cardCodeJs && <>
<h5 className='card-section-title card-section-js'>JavaScript</h5>
<pre
className={`card-code language-${config.optionalLanguage}`}
dangerouslySetInnerHTML={{ __html: cardCodeJs }}
/>
</>
}
<h5 className='card-section-demo-title'>Demo</h5>
<div className='card-snippet-demo' data-scope={snippetData.id}>
<style>
{snippetData.code.scopedCss}
</style>
<div dangerouslySetInnerHTML={{__html: snippetData.code.html}} />
</div>
{/* <button
className='button button-example-toggler'
onClick={() => setExamplesOpen(!examplesOpen)}
@ -108,7 +105,6 @@ const FullCard = ({ snippetData, difficulty, isDarkMode }) => {
const ShortCard = ({
snippetData,
withCode = false,
difficulty,
isDarkMode
}) => {
let cardCodeHtml;
@ -118,7 +114,6 @@ const ShortCard = ({
)}`;
return (
<div className='card short'>
<CardCorner difficulty={difficulty} />
<h4 className='card-title'>
<AniLink
paintDrip

View File

@ -11,15 +11,18 @@
border-radius: 0.125rem;
padding: 1rem;
.card-title {
font-size: 1.125rem;
font-size: 1.5rem;
line-height: 1.375;
font-weight: 500;
margin: 0px 0px 0.125rem;
font-weight: 700;
margin: 0px 0px 1.25rem;
color: var(--card-fore-color-light);
a, a:link, a:visited {
font-weight: 500;
font-weight: 700;
transition: 0.3s ease all;
color: var(--card-fore-color);
color: var(--card-fore-color-light);
}
padding-bottom: 0.5rem;
border-bottom: 1px solid var(--card-border-color);
}
.card-description {
margin: 0.125rem -0.5rem 0.125rem;
@ -34,13 +37,14 @@
margin-right: -1rem;
border-radius: 0.125rem;
border-top-left-radius: 22px;
width: calc(100% - 2rem);
}
.card-code {
position: relative;
margin: 1.5rem 0px -1rem 0px;
margin: 0.25rem 0px 0rem 1rem;
background: var(--pre-back-color);
width: calc(100% - 36px);
border-radius: 1.375rem 0px 0.125rem 0.125rem;
width: 100%;
border-radius: 0.25rem;
line-height: 1.15;
padding: 2.25rem 1.125rem 2.25rem;
}
@ -73,77 +77,105 @@
}
}
}
&:not(.short) {
background: linear-gradient(to bottom, var(--card-back-color) 0px, var(--card-back-color) calc(100% - 17px), var(--pre-back-color) calc(100% - 16px));
}
// Card sections
.card-section-title {
font-size: 0.875rem;
color: var(--card-back-color);
display: inline-block;
padding: 0 0.5rem;
line-height: 2;
border-radius: 0.125rem;
margin: 1.25rem 1rem 0.125rem 1rem;
font-weight: 700;
&.card-section-html {
background-image: linear-gradient(135deg,#ff4c9f,#ff7b74);
}
&.card-section-css {
background-image: linear-gradient(135deg,#7983ff,#5f9de9);
}
&.card-section-js {
background-image: linear-gradient(135deg,#ffb000,#f58818);
}
}
// Card expertise corners
.card-corner {
box-sizing: border-box;
position: absolute;
top: 24px;
right: 16px;
width: 0.5rem;
height: 0.5rem;
border-radius: 0.5rem;
background: var(--corner-color);
&.beginner {
--corner-color: var(--beginner-color);
}
&.intermediate {
--corner-color: var(--intermediate-color);
}
&.advanced {
--corner-color: var(--advanced-color);
}
&.intermediate, &.advanced {
&::before {
display: block;
position: absolute;
content: '';
top: 0px;
right: 12px;
width: 0.5rem;
height: 0.5rem;
border-radius: 0.5rem;
background: var(--corner-color);
}
}
&.advanced {
&::after {
display: block;
position: absolute;
content: '';
top: 0px;
right: 24px;
width: 0.5rem;
height: 0.5rem;
border-radius: 0.5rem;
background: var(--corner-color);
}
}
.card-section-demo-title {
margin: 0.5rem 1rem .5rem;
color: var(--card-fore-color-light);
font-size: 1rem;
font-weight: 700;
line-height: 2.25;
}
.card-snippet-demo {
width: calc(100% - 0.25rem);
margin: 0.5rem 1rem .5rem;
background: #f5f6f9;
border-radius: .25rem;
padding: .75rem 1.25rem;
}
// Tags
:not(.token).tag {
transition: 0.3s ease all;
border: 2px solid var(--tag-border-color);
border-radius: 0.25rem;
border: 1px solid var(--tag-border-color);
border-radius: 0.125rem;
color: var(--tag-fore-color);
text-transform: uppercase;
margin: 0px 0.375rem 0.25rem 0px;
display: inline-block;
padding: 0.125rem 0.25rem;
padding: 0.125rem 0.5rem;
letter-spacing: 0.25px;
font-size: 0.625rem;
line-height: 1.4;
font-weight: 500;
font-size: 0.75rem;
vertical-align: 0.125rem;
line-height: 2;
font-weight: 600;
&:first-of-type {
margin-top: 0.375rem;
}
background-repeat: no-repeat;
padding-left: 1.5rem;
background-position-x: 0.375rem;
background-position-y: center;
background-size: 14px;
}
.tag-animation {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23616B8F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-loader'%3E%3Cline x1='12' y1='2' x2='12' y2='6'%3E%3C/line%3E%3Cline x1='12' y1='18' x2='12' y2='22'%3E%3C/line%3E%3Cline x1='4.93' y1='4.93' x2='7.76' y2='7.76'%3E%3C/line%3E%3Cline x1='16.24' y1='16.24' x2='19.07' y2='19.07'%3E%3C/line%3E%3Cline x1='2' y1='12' x2='6' y2='12'%3E%3C/line%3E%3Cline x1='18' y1='12' x2='22' y2='12'%3E%3C/line%3E%3Cline x1='4.93' y1='19.07' x2='7.76' y2='16.24'%3E%3C/line%3E%3Cline x1='16.24' y1='7.76' x2='19.07' y2='4.93'%3E%3C/line%3E%3C/svg%3E");
}
.tag-visual {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23616B8F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-eye'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3C/svg%3E");
}
.tag-other {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23616B8F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-tag'%3E%3Cpath d='M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z'%3E%3C/path%3E%3Cline x1='7' y1='7' x2='7' y2='7'%3E%3C/line%3E%3C/svg%3E");
}
.tag-interactivity {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23616B8F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-edit-2'%3E%3Cpath d='M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'%3E%3C/path%3E%3C/svg%3E");
}
.tag-layout {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23616B8F' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-layout'%3E%3Crect x='3' y='3' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='3' y1='9' x2='21' y2='9'%3E%3C/line%3E%3Cline x1='9' y1='21' x2='9' y2='9'%3E%3C/line%3E%3C/svg%3E");
}
.page-container.dark {
.tag-animation {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23BEC1CB' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-loader'%3E%3Cline x1='12' y1='2' x2='12' y2='6'%3E%3C/line%3E%3Cline x1='12' y1='18' x2='12' y2='22'%3E%3C/line%3E%3Cline x1='4.93' y1='4.93' x2='7.76' y2='7.76'%3E%3C/line%3E%3Cline x1='16.24' y1='16.24' x2='19.07' y2='19.07'%3E%3C/line%3E%3Cline x1='2' y1='12' x2='6' y2='12'%3E%3C/line%3E%3Cline x1='18' y1='12' x2='22' y2='12'%3E%3C/line%3E%3Cline x1='4.93' y1='19.07' x2='7.76' y2='16.24'%3E%3C/line%3E%3Cline x1='16.24' y1='7.76' x2='19.07' y2='4.93'%3E%3C/line%3E%3C/svg%3E");
}
.tag-visual {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23BEC1CB' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-eye'%3E%3Cpath d='M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z'%3E%3C/path%3E%3Ccircle cx='12' cy='12' r='3'%3E%3C/circle%3E%3C/svg%3E");
}
.tag-other {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23BEC1CB' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-tag'%3E%3Cpath d='M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z'%3E%3C/path%3E%3Cline x1='7' y1='7' x2='7' y2='7'%3E%3C/line%3E%3C/svg%3E");
}
.tag-interactivity {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23BEC1CB' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-edit-2'%3E%3Cpath d='M17 3a2.828 2.828 0 1 1 4 4L7.5 20.5 2 22l1.5-5.5L17 3z'%3E%3C/path%3E%3C/svg%3E");
}
.tag-layout {
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='24' height='24' viewBox='0 0 24 24' fill='none' stroke='%23BEC1CB' stroke-width='2' stroke-linecap='round' stroke-linejoin='round' class='feather feather-layout'%3E%3Crect x='3' y='3' width='18' height='18' rx='2' ry='2'%3E%3C/rect%3E%3Cline x1='3' y1='9' x2='21' y2='9'%3E%3C/line%3E%3Cline x1='9' y1='21' x2='9' y2='9'%3E%3C/line%3E%3C/svg%3E");
}
}
// Animation for card example
.roll-up-height {
transition: height 0.3s ease-in-out;

View File

@ -46,6 +46,8 @@ pre[class*="language-"] {
overflow: auto;
margin: 0.5rem 0;
white-space: pre-wrap;
font-size: 1rem;
line-height: 2;
}
pre[class*="language-"]::-moz-selection, pre[class*="language-"] ::-moz-selection,
@ -59,9 +61,10 @@ code[class*="language-"]::selection, code[class*="language-"] ::selection {
}
:not(pre) > code[class*="language-"] {
padding: .1em;
padding: .25em .375;
border-radius: .3em;
white-space: normal;
border: 1px solid var(--code-border-color);
}
.namespace {
@ -75,7 +78,7 @@ code[class*="language-"]::selection, code[class*="language-"] ::selection {
&.punctuation {
color: var(--token-color-b);
}
&.property, &.tag, &.boolean, &.constant, &.symbol, &.deleted, &.function {
&.tag, &.boolean, &.constant, &.symbol, &.deleted, &.function {
color: var(--token-color-c);
}
&.number, &.class-name {
@ -90,6 +93,9 @@ code[class*="language-"]::selection, code[class*="language-"] ::selection {
&.regex {
color: var(--token-color-g);
}
&.property {
color: var(--token-color-i);
}
&.important, &.variable {
color: var(--token-color-h);
}
@ -107,7 +113,7 @@ code[class*="language-"]::selection, code[class*="language-"] ::selection {
color: var(--token-color-f);
}
p > code, a > code {
p > code, a > code, li > code {
&, &[class*="language-"] {
color: var(--code-fore-color);
background: var(--code-back-color);

View File

@ -1,6 +1,6 @@
:root {
// Interface color palette
--back-color: #F5F6FA;
--back-color: #f5f6fa;
--back-color-dark: #D7DDF3;
--fore-color: #404454;
--fore-color-light: #575E7A;
@ -41,24 +41,26 @@
// Card color palette
--card-back-color: #FFFFFF;
--card-fore-color: #212121;
--card-border-color: #E4E6EC;
--card-fore-color-light: #424242;
--card-shadow-color-a: rgba(240, 242, 247, 0.1);
--card-shadow-color-b: rgba(0, 32, 128, 0.1);
// Pre & Code color palette
--pre-fore-color: #e57373;
--pre-fore-color: #d7ecff;
--pre-back-color: #1e253d;
--pre-selected-color: #041248;
// Token color palette
--token-color-a: #7f99a5; // Comments
--token-color-b: #bdbdbd; // Punctuation
--token-color-c: #64b5f6; // Functions
--token-color-a: #8ca2d3; // Comments
--token-color-b: #5ac8e3; // Punctuation
--token-color-c: #25d0e5; // Functions
--token-color-d: #ff8f00; // Numbers
--token-color-e: #c5e1a5; // Strings
--token-color-f: #ce93d8; // Keywords
--token-color-e: #ffd694; // Strings
--token-color-f: #b7adff; // Keywords
--token-color-g: #26c6da; // Regular expressions
--token-color-h: #e57373; // Variables
--token-color-i: #85b4ff; // Property
// Tag color palette
--tag-border-color: #D7DDF3;
@ -75,7 +77,8 @@
// Code color palette
--code-fore-color: #0324AB;
--code-back-color: #EDF0FC;
--code-back-color: #fbf9ff;
--code-border-color: #e0dbff;
--code-selected-color: #BDEDFE;
}
@ -112,8 +115,9 @@
// Button color palette remains unchanged for consistency
// Card color palette
--card-back-color: #434E76;
--card-back-color: hsl(227, 28%, 36%);
--card-fore-color: #F0F0F0;
--card-border-color: #13151B;
--card-fore-color-light: #D6D6D6; // previously C0C0C0, careful
--card-shadow-color-b: rgba(1, 8, 30, 0.24);
@ -134,7 +138,8 @@
// Code color palette
--code-fore-color: #d1dafe;
--code-back-color: #4f5fa0;
--code-back-color: #45538c;
--code-border-color: #3e3c75;
--code-selected-color: #0dbcfb;
}

View File

@ -86,4 +86,12 @@
font-display: swap;
src: local('Noto Sans SemiBold Italic'), local('NotoSans-SemiBoldItalic'), url(../../../assets/NotoSans-SemiBoldItalic.ttf) format('truetype');
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 {
font-family: 'Noto Sans';
font-style: normal;
font-weight: 700;
font-display: swap;
src: local('Noto Sans Bold'), local('NotoSans-Bold'), url(../../../assets/NotoSans-Bold.ttf) format('truetype');
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;
}

View File

@ -33,9 +33,10 @@ const SnippetPage = props => {
</AniLink>
<SnippetCard
snippetData={{
id: postData.id,
title: postData.title,
html: post.html,
code: postData.attributes.codeBlocks.code,
code: postData.attributes.codeBlocks,
tags: postData.attributes.tags,
}}
isDarkMode={props.isDarkMode}