article card list updated
This commit is contained in:
1 parent
55b4ce14d3
commit
3631216be4
10 files changed
+152
-122
No files matched your search
@@ -38,14 +38,14 @@ export const App: React.FC<IAppProps> = props => {
|
||||
/>
|
||||
)}
|
||||
>
|
||||
<section className={cx('content', `content_${props.layout}`, {
|
||||
<div className={cx('content', `content_${props.layout}`, {
|
||||
'content--padding-top--menu': props.menuPadding,
|
||||
'reduced-motion': motionDisabled,
|
||||
})}>
|
||||
{props.children}
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<Comments />
|
||||
{/* <Comments /> */}
|
||||
</Wrapper>
|
||||
</ConfigContext.Provider>
|
||||
)
|
||||
|
||||
@@ -1,12 +1,8 @@
|
||||
import * as React from 'react'
|
||||
import './styles.css'
|
||||
|
||||
import cx from 'classnames'
|
||||
import { Date } from './Date'
|
||||
|
||||
interface IImage {
|
||||
alt: string
|
||||
src: string
|
||||
srcSet: Array<{ url: string, density: number }>
|
||||
}
|
||||
import { IImage } from 'src/types'
|
||||
|
||||
export interface IArticleCardProps {
|
||||
article: any
|
||||
@@ -15,86 +11,6 @@ export interface IArticleCardProps {
|
||||
|
||||
export const ArticleCard: React.FC<IArticleCardProps> = ({ article, ...props }) => (
|
||||
<section className="ArticleCard">
|
||||
<style jsx>{`
|
||||
.ArticleCard {
|
||||
--article-card-width: 30%;
|
||||
--article-card-image-height: 15em;
|
||||
--article-card-margin: var(--double-margin) var(--single-margin);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
margin: var(--article-card-margin);
|
||||
width: var(--article-card-width);
|
||||
min-width: 15em;
|
||||
max-width: 20em;
|
||||
|
||||
border-radius: 10px;
|
||||
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ArticleCard > a {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ArticleCard-image {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: var(--article-card-image-height);
|
||||
}
|
||||
|
||||
.ArticleCard-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
|
||||
transition: all 150ms ease-out;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ArticleCard-body {
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
|
||||
height: 5em;
|
||||
|
||||
padding: .75em 1em;
|
||||
}
|
||||
|
||||
.ArticleCard:hover img {
|
||||
width: 105%;
|
||||
height: 105%;
|
||||
|
||||
top: -2.5%;
|
||||
left: -2.5%;
|
||||
}
|
||||
|
||||
// Tablet
|
||||
@media screen and (min-width: var(--tablet-min-width)) and (max-width: var(--tablet-max-width)) {
|
||||
.ArticleCard {
|
||||
--article-card-image-height: 12em;
|
||||
}
|
||||
}
|
||||
|
||||
// Mobile
|
||||
@media (max-width: 31.25em) {
|
||||
.ArticleCard {
|
||||
--article-card-width: 100%;
|
||||
--article-card-margin: var(--single-margin) 0;
|
||||
}
|
||||
}
|
||||
`}</style>
|
||||
|
||||
<a className="invisible" href={article.url}>
|
||||
<div className="ArticleCard-image">
|
||||
{!props.preview ? null : (
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
.ArticleCard {
|
||||
--article-card-width: 100%;
|
||||
--article-card-image-height: 15em;
|
||||
--article-card-margin: var(--double-margin) var(--single-margin);
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
|
||||
/* margin: var(--article-card-margin); */
|
||||
width: var(--article-card-width);
|
||||
/* min-width: 15em; */
|
||||
/* max-width: 20em; */
|
||||
|
||||
border-radius: 10px;
|
||||
|
||||
box-shadow: 0 0 20px rgba(0, 0, 0, 0.15);
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.ArticleCard > a {
|
||||
display: block;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.ArticleCard-image {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
width: 100%;
|
||||
height: var(--article-card-image-height);
|
||||
}
|
||||
|
||||
.ArticleCard-image img {
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
object-fit: cover;
|
||||
|
||||
transition: all 150ms ease-out;
|
||||
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
}
|
||||
|
||||
.ArticleCard-body {
|
||||
z-index: 1000;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
justify-content: space-between;
|
||||
align-items: flex-start;
|
||||
|
||||
height: 5em;
|
||||
|
||||
padding: 0.75em 1em;
|
||||
}
|
||||
|
||||
.ArticleCard:hover img {
|
||||
width: 105%;
|
||||
height: 105%;
|
||||
|
||||
top: -2.5%;
|
||||
left: -2.5%;
|
||||
}
|
||||
|
||||
/* Tablet */
|
||||
@media screen and (min-width: var(--tablet-min-width)) and (max-width: var(--tablet-max-width)) {
|
||||
.ArticleCard {
|
||||
--article-card-image-height: 12em;
|
||||
}
|
||||
}
|
||||
|
||||
/* Mobile */
|
||||
@media (max-width: 31.25em) {
|
||||
.ArticleCard {
|
||||
--article-card-width: 100%;
|
||||
--article-card-margin: var(--single-margin) 0;
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
import { ArticleCard } from './ArticleCard'
|
||||
import { Pager } from './Pager'
|
||||
import { CardGrid } from './CardGrid'
|
||||
|
||||
export interface IArticleCardListProps {
|
||||
articles: any[]
|
||||
@@ -7,18 +8,13 @@ export interface IArticleCardListProps {
|
||||
prevPage: number | null
|
||||
}
|
||||
|
||||
export const ArticleCardList:React.FC<IArticleCardListProps> = ({ articles, nextPage, prevPage }) => (
|
||||
<div>
|
||||
<style jsx>{`
|
||||
.body {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
`}</style>
|
||||
|
||||
<div className={'body'}>
|
||||
export const ArticleCardList: React.FC<IArticleCardListProps> = ({ articles, nextPage, prevPage }) => (
|
||||
<>
|
||||
<CardGrid
|
||||
style={{
|
||||
marginBottom: 'var(--size-m)',
|
||||
}}
|
||||
>
|
||||
{articles.map((article, i) => {
|
||||
const preview = {
|
||||
alt: article.title,
|
||||
@@ -34,11 +30,11 @@ export const ArticleCardList:React.FC<IArticleCardListProps> = ({ articles, next
|
||||
/>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
</CardGrid>
|
||||
|
||||
<Pager
|
||||
nextHref={nextPage ? `/articles/${nextPage}` : null}
|
||||
prevHref={prevPage ? `/articles/${prevPage}` : null}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
@@ -0,0 +1,13 @@
|
||||
import './styles.css'
|
||||
|
||||
export type CardGridProps = {
|
||||
style?: React.CSSProperties
|
||||
}
|
||||
|
||||
export const CardGrid: React.FC<CardGridProps> = props => {
|
||||
return (
|
||||
<section className={'card-grid'} style={props.style}>
|
||||
{props.children}
|
||||
</section>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
.card-grid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr 1fr;
|
||||
grid-gap: var(--size-xl) var(--size-l);
|
||||
}
|
||||
|
||||
/* .card-grid > *:first-child {
|
||||
grid-row: 1 / 1;
|
||||
grid-column: 1 / 1;
|
||||
} */
|
||||
|
||||
@media screen and (max-width: 31.25em) {
|
||||
}
|
||||
@@ -21,11 +21,16 @@ export const Wrapper: React.FC<WrapperProps> = props => (
|
||||
.content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
main {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
`}</style>
|
||||
|
||||
{props.header}
|
||||
|
||||
<main className={'content'}>
|
||||
<main>
|
||||
{props.children}
|
||||
</main>
|
||||
|
||||
|
||||
+3
-1
@@ -23,10 +23,12 @@
|
||||
--tablet-min-width: 31.25em;
|
||||
--tablet-max-width: 64em;
|
||||
|
||||
/* CONTENT */
|
||||
--content-full: 100%;
|
||||
--content-wide: 90%;
|
||||
--content-semi-wide: 70%;
|
||||
--content-thin: 60%;
|
||||
--content-width: var(--content-full);
|
||||
|
||||
--embed-video-ratio: 56.25%;
|
||||
|
||||
@@ -71,7 +73,7 @@
|
||||
--size-s: 0.5em;
|
||||
--size-m: 1em;
|
||||
--size-l: 2em;
|
||||
--size-xl: 5em;
|
||||
--size-xl: 3em;
|
||||
|
||||
/* EFFECTS */
|
||||
--radius: 10px;
|
||||
|
||||
+18
-16
@@ -1,25 +1,27 @@
|
||||
.content {
|
||||
margin: 0 auto 1em;
|
||||
// margin: 0 auto 1em;
|
||||
|
||||
&.content_full {
|
||||
width: var(--content-full);
|
||||
}
|
||||
width: var(--content-width);
|
||||
}
|
||||
|
||||
&.content_wide {
|
||||
width: var(--content-wide);
|
||||
}
|
||||
.content_full {
|
||||
--content-width: var(--content-full);
|
||||
}
|
||||
|
||||
&.content_semi-wide {
|
||||
width: var(--content-semi-wide);
|
||||
}
|
||||
.content_wide {
|
||||
--content-width: var(--content-wide);
|
||||
}
|
||||
|
||||
&.content_thin {
|
||||
width: var(--content-thin);
|
||||
}
|
||||
.content_semi-wide {
|
||||
--content-width: var(--content-semi-wide);
|
||||
}
|
||||
|
||||
&.content--padding-top--menu {
|
||||
padding-top: var(--menu-thickness);
|
||||
}
|
||||
.content_thin {
|
||||
--content-width: var(--content-thin);
|
||||
}
|
||||
|
||||
.content--padding-top--menu {
|
||||
padding-top: var(--menu-thickness);
|
||||
}
|
||||
|
||||
// Animation on load
|
||||
|
||||
@@ -23,3 +23,9 @@ export interface IMeta {
|
||||
twitterSite: string
|
||||
twitterCreator: string
|
||||
}
|
||||
|
||||
export interface IImage {
|
||||
alt: string
|
||||
src: string
|
||||
srcSet: Array<{ url: string, density: number }>
|
||||
}
|
||||
Reference in new issue
Block a user