1
0
mirror of https://github.com/phuoc-ng/csslayout.git synced 2025-08-06 14:16:50 +02:00

List products on sidebar

This commit is contained in:
Phuoc Nguyen
2021-03-30 15:09:47 +07:00
parent 0e5f8059c5
commit f334b7208d
15 changed files with 287 additions and 125 deletions

View File

@@ -0,0 +1,27 @@
/**
* A collection of popular layouts and patterns made with CSS (https://csslayout.io)
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
*/
import * as React from 'react';
import './product.css';
import ProductModel from '../constants/ProductModel';
import slug from '../helpers/slug';
interface ProductProps {
product: ProductModel;
}
const Product: React.FC<ProductProps> = ({ product }) => {
return (
<div className="product">
<a href={product.url}>
<img className="product__logo" src={`/assets/${slug(product.name)}.png`} alt={`${product.name} - ${product.description}`} />
<div className="product__desc">{product.description}</div>
</a>
</div>
);
};
export default Product;

View File

@@ -0,0 +1,22 @@
/**
* A collection of popular layouts and patterns made with CSS (https://csslayout.io)
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
*/
.product {
border: 1px solid rgba(0, 0, 0, .3);
border-radius: 0.5rem;
margin: 1rem 0;
overflow: hidden;
}
.product a {
text-decoration: none;
}
.product__logo {
height: auto;
width: 100%;
}
.product__desc {
padding: 0.5rem;
text-align: center;
}

View File

@@ -0,0 +1,60 @@
import ProductModel from './ProductModel';
const ProductList: ProductModel[] = [
{
name: 'Blur Page',
url: 'https://blur.page',
description: 'A browser extension to hide sensitive information on a web page',
themeColor: '#4e7fb8',
},
{
name: 'Form Validation',
url: 'https://formvalidation.io',
description: 'The best validation library for JavaScript',
themeColor: '#014ba6',
},
{
name: 'React PDF Viewer',
url: 'https://react-pdf-viewer.dev',
description: 'A React component to view a PDF document',
themeColor: '#fb6303',
},
{
name: '1 LOC',
url: 'https://1loc.dev',
description: 'Favorite JavaScript utilities in single line of code',
themeColor: '#000200',
},
{
name: 'CSS Layout',
url: 'https://csslayout.io',
description: 'A collection of popular layouts and patterns made with CSS',
themeColor: '#e7d900',
},
{
name: 'Front-end Tips',
url: 'https://getfrontend.tips',
description: 'Super tiny, quick tips, tricks and best practices of front-end development',
themeColor: '#2e2c74',
},
{
name: 'HTML DOM',
url: 'https://htmldom.dev',
description: 'How to manage HTML DOM with vanilla JavaScript',
themeColor: '#5b5d8a',
},
{
name: 'Responsive Design Patterns',
url: 'https://responsive.page',
description: 'A collection of patterns to create a responsive web page',
themeColor: '#43246d',
},
{
name: 'this VS that',
url: 'https://thisthat.dev',
description: 'The differences between _ and _ in the front-end development',
themeColor: '#414293',
},
];
export { ProductList };

View File

@@ -0,0 +1,6 @@
export default interface ProductModel {
name: string;
url: string;
description: string;
themeColor: string;
}

View File

@@ -28,10 +28,24 @@ code {
max-width: 64rem; max-width: 64rem;
padding: 0 1rem; padding: 0 1rem;
} }
.content {
display: flex;
}
.main { .main {
margin: 4rem 0; flex: 1;
overflow: auto;
}
.sidebar {
display: none;
} }
/* Sidebar */
.sidebar__inner {
position: sticky;
top: 1rem;
}
/* Hero */
.hero { .hero {
background: var(--background-color); background: var(--background-color);
display: flex; display: flex;
@@ -59,3 +73,23 @@ code {
margin: 2rem 0; margin: 2rem 0;
text-align: center; text-align: center;
} }
/* Responsive */
@media (min-width: 640px) {
.sidebar {
display: block;
flex: 0 0 10rem;
margin-left: 0.5rem;
}
}
@media (min-width: 768px) {
.sidebar {
flex-basis: 12rem;
}
}
@media (min-width: 1024px) {
.sidebar {
flex-basis: 16rem;
margin-left: 1rem;
}
}

View File

@@ -9,7 +9,9 @@ import { Helmet } from 'react-helmet';
import Ad from '../components/Ad'; import Ad from '../components/Ad';
import CoverCard from '../components/CoverCard'; import CoverCard from '../components/CoverCard';
import Heading from '../components/Heading'; import Heading from '../components/Heading';
import Product from '../components/Product';
import Pattern from '../constants/Pattern'; import Pattern from '../constants/Pattern';
import { ProductList } from '../constants/ProductList';
import useDocumentTitle from '../hooks/useDocumentTitle'; import useDocumentTitle from '../hooks/useDocumentTitle';
import Layout from '../layouts/Layout'; import Layout from '../layouts/Layout';
import './explorePage.css'; import './explorePage.css';
@@ -32,8 +34,8 @@ const ExplorePage = () => {
</div> </div>
<div className="container"> <div className="container">
<Ad /> <div className="content">
<main class="main">
<section> <section>
<Heading title="Layout" /> <Heading title="Layout" />
@@ -159,6 +161,17 @@ const ExplorePage = () => {
<CoverCard pattern={Pattern.ValidationIcon} /> <CoverCard pattern={Pattern.ValidationIcon} />
</div> </div>
</section> </section>
</main>
<div className="sidebar">
<div className="sidebar__inner">
<Ad />
{
ProductList.map(product => <Product key={product.name} product={product} />)
}
</div>
</div>
</div>
</div> </div>
</Layout> </Layout>
); );

BIN
public/assets/1-loc.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.3 KiB

BIN
public/assets/blur-page.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

BIN
public/assets/html-dom.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB