mirror of
https://github.com/phuoc-ng/csslayout.git
synced 2025-08-13 17:44:19 +02:00
Update details layout
This commit is contained in:
@@ -3,7 +3,7 @@
|
|||||||
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import highlight from '../helpers/highlight';
|
import highlight from '../helpers/highlight';
|
||||||
|
|
||||||
@@ -18,8 +18,11 @@ const SampleCode: React.FC<SampleCodeProps> = ({ code, fullHeight = false, lang
|
|||||||
? <></>
|
? <></>
|
||||||
: (
|
: (
|
||||||
<pre
|
<pre
|
||||||
className="hljs"
|
|
||||||
style={{
|
style={{
|
||||||
|
border: 'none',
|
||||||
|
borderRadius: 0,
|
||||||
|
boxShadow: 'none',
|
||||||
|
fontFamily: "'Source Code Pro', monospace",
|
||||||
height: fullHeight ? '100%' : 'auto',
|
height: fullHeight ? '100%' : 'auto',
|
||||||
lineHeight: 1.5,
|
lineHeight: 1.5,
|
||||||
margin: 0,
|
margin: 0,
|
||||||
|
@@ -25,12 +25,6 @@ const ProductList: ProductModel[] = [
|
|||||||
description: 'Favorite JavaScript utilities in single line of code',
|
description: 'Favorite JavaScript utilities in single line of code',
|
||||||
themeColor: '#000200',
|
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',
|
name: 'Front-end Tips',
|
||||||
url: 'https://getfrontend.tips',
|
url: 'https://getfrontend.tips',
|
||||||
|
21
client/helpers/randomIterms.ts
Normal file
21
client/helpers/randomIterms.ts
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
/**
|
||||||
|
* A collection of popular layouts and patterns made with CSS (https://csslayout.io)
|
||||||
|
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
||||||
|
*/
|
||||||
|
|
||||||
|
type Tuple<T> = [number, T[]];
|
||||||
|
|
||||||
|
function randomItems<T>(arr: T[], count: number): T[] {
|
||||||
|
const result = arr.concat().reduce(
|
||||||
|
(p, _, __, arr) => {
|
||||||
|
const [a, b] = p;
|
||||||
|
return (a < count)
|
||||||
|
? [a + 1, b.concat(arr.splice(Math.random() * arr.length | 0, 1))]
|
||||||
|
: p;
|
||||||
|
},
|
||||||
|
[0, []] as Tuple<T>
|
||||||
|
);
|
||||||
|
return (result as Tuple<T>)[1];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default randomItems;
|
@@ -18,8 +18,8 @@ a {
|
|||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
code {
|
pre[class*="language-"] {
|
||||||
font-family: 'Source Code Pro', monospace;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Layout */
|
/* Layout */
|
||||||
|
@@ -3,14 +3,14 @@
|
|||||||
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import Ad from '../components/Ad';
|
import Ad from '../components/Ad';
|
||||||
import useDocumentTitle from '../hooks/useDocumentTitle';
|
import useDocumentTitle from '../hooks/useDocumentTitle';
|
||||||
import Layout from './Layout';
|
import Layout from './Layout';
|
||||||
import Product from '../components/Product';
|
import Product from '../components/Product';
|
||||||
import { ProductList } from '../constants/ProductList';
|
import { ProductList } from '../constants/ProductList';
|
||||||
import randomFromArray from '../helpers/randomFromArray';
|
import randomItems from '../helpers/randomIterms';
|
||||||
|
|
||||||
interface DetailsLayoutProps {
|
interface DetailsLayoutProps {
|
||||||
title: string;
|
title: string;
|
||||||
@@ -19,7 +19,7 @@ interface DetailsLayoutProps {
|
|||||||
const DetailsLayout: React.FC<DetailsLayoutProps> = ({ title, children }) => {
|
const DetailsLayout: React.FC<DetailsLayoutProps> = ({ title, children }) => {
|
||||||
useDocumentTitle(`CSS Layout ∙ ${title}`);
|
useDocumentTitle(`CSS Layout ∙ ${title}`);
|
||||||
|
|
||||||
const product = randomFromArray(ProductList);
|
const products = randomItems(ProductList, 3);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Layout>
|
<Layout>
|
||||||
@@ -36,7 +36,9 @@ const DetailsLayout: React.FC<DetailsLayoutProps> = ({ title, children }) => {
|
|||||||
<div className="sidebar">
|
<div className="sidebar">
|
||||||
<div className="sidebar__inner">
|
<div className="sidebar__inner">
|
||||||
<Ad />
|
<Ad />
|
||||||
<Product product={product} />
|
{
|
||||||
|
products.map(product => <Product key={product.name} product={product} />)
|
||||||
|
}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -3,9 +3,10 @@
|
|||||||
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import React, { useState } from 'react';
|
import * as React from 'react';
|
||||||
|
|
||||||
import SampleCode from '../components/SampleCode';
|
import SampleCode from '../components/SampleCode';
|
||||||
|
import './browserFrame.css';
|
||||||
|
|
||||||
interface BrowserFrameProps {
|
interface BrowserFrameProps {
|
||||||
content: React.ReactNode;
|
content: React.ReactNode;
|
||||||
@@ -13,114 +14,14 @@ interface BrowserFrameProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const BrowserFrame: React.FC<BrowserFrameProps> = ({ content, source }) => {
|
const BrowserFrame: React.FC<BrowserFrameProps> = ({ content, source }) => {
|
||||||
const [isContentActive, setContentActive] = useState(true);
|
|
||||||
const flip = () => setContentActive((isActive) => !isActive);
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div className="demo">
|
||||||
className='shadow-2xl'
|
<div className="demo__source">
|
||||||
style={{
|
{source && <SampleCode fullHeight={true} lang="html" code={source} />}
|
||||||
border: '1px solid rgba(0, 0, 0, 0.2)',
|
|
||||||
borderRadius: '4px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
alignItems: 'center',
|
|
||||||
backgroundColor: 'rgba( 0, 0, 0, 0.05)',
|
|
||||||
borderBottom: '1px solid rgba(0, 0, 0, 0.2)',
|
|
||||||
display: 'flex',
|
|
||||||
padding: '8px 16px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
backgroundColor: '#FF4136',
|
|
||||||
borderRadius: '100%',
|
|
||||||
height: '16px',
|
|
||||||
marginRight: '4px',
|
|
||||||
width: '16px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
backgroundColor: '#FFB700',
|
|
||||||
borderRadius: '100%',
|
|
||||||
height: '16px',
|
|
||||||
marginRight: '4px',
|
|
||||||
width: '16px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
backgroundColor: '#FF4136',
|
|
||||||
borderRadius: '100%',
|
|
||||||
height: '16px',
|
|
||||||
marginRight: '4px',
|
|
||||||
width: '16px',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
{source && (
|
|
||||||
<div style={{ marginLeft: 'auto' }}>
|
|
||||||
<button
|
|
||||||
style={{
|
|
||||||
backgroundColor: '#00449E',
|
|
||||||
borderColor: 'transparent',
|
|
||||||
borderRadius: '4px',
|
|
||||||
color: '#FFF',
|
|
||||||
cursor: 'pointer',
|
|
||||||
padding: '4px 8px',
|
|
||||||
}}
|
|
||||||
onClick={flip}
|
|
||||||
>
|
|
||||||
{isContentActive ? 'Source' : 'Demo'}
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
<div className="demo__live">
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
height: '512px',
|
|
||||||
position: 'relative',
|
|
||||||
transform: isContentActive ? '' : 'rotateY(180deg)',
|
|
||||||
transformStyle: 'preserve-3d',
|
|
||||||
transition: 'transform 1s',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
WebkitBackfaceVisibility: 'hidden',
|
|
||||||
backfaceVisibility: 'hidden',
|
|
||||||
height: '100%',
|
|
||||||
left: 0,
|
|
||||||
opacity: isContentActive ? 1 : 0,
|
|
||||||
overflow: 'scroll',
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
width: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{content}
|
{content}
|
||||||
</div>
|
</div>
|
||||||
{source && (
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
WebkitBackfaceVisibility: 'hidden',
|
|
||||||
backfaceVisibility: 'hidden',
|
|
||||||
height: '100%',
|
|
||||||
left: 0,
|
|
||||||
opacity: isContentActive ? 0 : 1,
|
|
||||||
overflow: 'scroll',
|
|
||||||
position: 'absolute',
|
|
||||||
top: 0,
|
|
||||||
transform: 'rotateY(180deg)',
|
|
||||||
width: '100%',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<SampleCode fullHeight={true} lang="html" code={source} />
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
13
client/placeholders/browserFrame.css
Normal file
13
client/placeholders/browserFrame.css
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
/**
|
||||||
|
* A collection of popular layouts and patterns made with CSS (https://csslayout.io)
|
||||||
|
* (c) 2019 - 2020 Nguyen Huu Phuoc <https://twitter.com/nghuuphuoc>
|
||||||
|
*/
|
||||||
|
|
||||||
|
.demo {
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.2);
|
||||||
|
border-radius: 0.25rem;
|
||||||
|
}
|
||||||
|
.demo__source,
|
||||||
|
.demo__live {
|
||||||
|
height: 32rem;
|
||||||
|
}
|
Reference in New Issue
Block a user