Blog home solid
This commit is contained in:
parent
63010cba59
commit
1dbc67dc79
|
@ -23,119 +23,15 @@ $breakpoint-huge: 1280px;
|
|||
/* ********************* */
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-Thin.ttf) format('truetype');
|
||||
font-weight: 200;
|
||||
font-family: WorkSans;
|
||||
src: url(/fonts/WorkSans/WorkSans-VariableFont_wght.ttf) format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-ThinItalic.ttf) format('truetype');
|
||||
font-weight: 200;
|
||||
font-family: WorkSans;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-Regular.ttf) format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-MediumItalic.ttf) format('truetype');
|
||||
font-style: italic;
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-Medium.ttf) format('truetype');
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-LightItalic.ttf) format('truetype');
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-Light.ttf) format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-Italic.ttf) format('truetype');
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-BoldItalic.ttf) format('truetype');
|
||||
font-weight: 700;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-Bold.ttf) format('truetype');
|
||||
font-weight: 700;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-BlackItalic.ttf) format('truetype');
|
||||
font-weight: 900;
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: Roboto;
|
||||
src: url(/fonts/Roboto/Roboto-Black.ttf) format('truetype');
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: RobotoSlab;
|
||||
src: url(/fonts/RobotoSlab/RobotoSlab-ExtraLight.ttf) format('truetype');
|
||||
font-weight: 100;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: RobotoSlab;
|
||||
src: url(/fonts/RobotoSlab/RobotoSlab-Thin.ttf) format('truetype');
|
||||
font-weight: 200;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: RobotoSlab;
|
||||
src: url(/fonts/RobotoSlab/RobotoSlab-Light.ttf) format('truetype');
|
||||
font-weight: 300;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: RobotoSlab;
|
||||
src: url(/fonts/RobotoSlab/RobotoSlab-Regular.ttf) format('truetype');
|
||||
font-weight: 400;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: RobotoSlab;
|
||||
src: url(/fonts/RobotoSlab/RobotoSlab-SemiBold.ttf) format('truetype');
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: RobotoSlab;
|
||||
src: url(/fonts/RobotoSlab/RobotoSlab-Bold.ttf) format('truetype');
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
@font-face {
|
||||
font-family: RobotoSlab;
|
||||
src: url(/fonts/RobotoSlab/RobotoSlab-ExtraBold.ttf) format('truetype');
|
||||
font-weight: 700;
|
||||
src: url(/fonts/WorkSans/WorkSans-Italic-VariableFont_wght.ttf)
|
||||
format('truetype');
|
||||
}
|
||||
|
||||
@font-face {
|
||||
|
@ -217,7 +113,10 @@ body {
|
|||
}
|
||||
|
||||
.hide-scroll {
|
||||
::-webkit-scrollbar {
|
||||
&::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ export function Breadcrumbs() {
|
|||
console.log('Breadcrumbs ➡️ path:', path);
|
||||
|
||||
return (
|
||||
<div className="flex items-center font-roboto">
|
||||
<div className="flex items-center font-sans">
|
||||
{/* <HomeSVG className="h-4 w-4 mr-1 text-primary fill-current" /> */}
|
||||
<span className="children:last:font-medium">
|
||||
{path.map((item, index) => (
|
||||
|
|
|
@ -25,7 +25,7 @@ export const DropdownItem = (props: DropdownItemProps) => {
|
|||
className={classNames(
|
||||
'flex items-center',
|
||||
'block',
|
||||
'font-roboto text-sm text-primary',
|
||||
'font-sans text-sm text-primary',
|
||||
'hover:text-opacity-100 text-opacity-75',
|
||||
'select-none',
|
||||
'cursor-pointer',
|
||||
|
|
|
@ -5,7 +5,7 @@ export function Footer() {
|
|||
return (
|
||||
<div className="bg-primary py-6 text-center mt-10">
|
||||
<Contained>
|
||||
<div className="font-roboto text-base text-white font-medium desktop:text-sm">
|
||||
<div className="font-sans text-base text-white font-medium desktop:text-sm">
|
||||
c c c
|
||||
</div>
|
||||
</Contained>
|
||||
|
|
|
@ -1,42 +0,0 @@
|
|||
import classNames from 'classnames';
|
||||
|
||||
interface Props {
|
||||
size?: 'tiny' | 'small' | 'medium' | 'large';
|
||||
theme?: 'default' | 'alt';
|
||||
bold?: boolean;
|
||||
children: string;
|
||||
className?: string;
|
||||
onClick?(): void;
|
||||
}
|
||||
|
||||
export function OutlineBlock(props: Props) {
|
||||
const {
|
||||
children,
|
||||
size = 'medium',
|
||||
theme = 'default',
|
||||
bold,
|
||||
className,
|
||||
onClick,
|
||||
} = props;
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={onClick}
|
||||
className={classNames(
|
||||
theme === 'alt' && 'border-2 border-white rounded-md',
|
||||
theme === 'default' && 'border-2 border-secondary rounded-lg',
|
||||
size === 'tiny' && 'px-2 text-xs',
|
||||
size === 'small' && 'py-1 px-3 text-sm',
|
||||
size === 'medium' && 'py-2 px-3',
|
||||
size === 'large' && 'py-3 px-3 text-lg',
|
||||
onClick && 'cursor-pointer',
|
||||
)}
|
||||
>
|
||||
<span
|
||||
className={classNames('text-primary', bold && 'font-medium', className)}
|
||||
>
|
||||
{children}
|
||||
</span>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -20,7 +20,7 @@ const Bold = ({ children }) => (
|
|||
);
|
||||
|
||||
const Paragraph = ({ children }) => (
|
||||
<p className="mb-3 tracking-wide font-roboto">{children}</p>
|
||||
<p className="mb-3 tracking-wide font-sans">{children}</p>
|
||||
);
|
||||
|
||||
const options = {
|
||||
|
@ -42,7 +42,7 @@ const options = {
|
|||
[BLOCKS.HEADING_2]: (node: Heading2) => {
|
||||
const content = (node.content[0] as Text)?.value;
|
||||
return (
|
||||
<h2 className="mt-8 mb-2 text-3xl font-semibold tracking-wide font-roboto">
|
||||
<h2 className="mt-8 mb-2 text-3xl font-semibold tracking-wide font-sans">
|
||||
{content}
|
||||
</h2>
|
||||
);
|
||||
|
@ -50,15 +50,13 @@ const options = {
|
|||
[BLOCKS.HEADING_3]: (node: Heading3) => {
|
||||
const content = (node.content[0] as Text)?.value;
|
||||
return (
|
||||
<h2 className="mt-6 mb-2 text-xl font-semibold font-roboto">
|
||||
{content}
|
||||
</h2>
|
||||
<h2 className="mt-6 mb-2 text-xl font-semibold font-sans">{content}</h2>
|
||||
);
|
||||
},
|
||||
[BLOCKS.HEADING_4]: (node: Heading4) => {
|
||||
const content = (node.content[0] as Text)?.value;
|
||||
return (
|
||||
<h2 className="mt-6 mb-2 text-lg font-bold font-roboto">{content}</h2>
|
||||
<h2 className="mt-6 mb-2 text-lg font-bold font-sans">{content}</h2>
|
||||
);
|
||||
},
|
||||
[BLOCKS.EMBEDDED_ASSET]: (node: AssetLinkBlock) => {
|
||||
|
|
|
@ -6,7 +6,7 @@ export function SectionTitle(props: Props) {
|
|||
const { children } = props;
|
||||
|
||||
return (
|
||||
<div className="flex justify-center font-roboto text-xl text-primary mb-3">
|
||||
<div className="flex justify-center font-sans text-xl text-primary mb-3">
|
||||
{children}
|
||||
<div className="absolute w-10 h-1 mt-8 rounded-full bg-secondary"></div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
|
||||
interface Props {
|
||||
tag: string;
|
||||
}
|
||||
|
||||
export function TagBlock(props: Props) {
|
||||
const { tag } = props;
|
||||
const href = `/blog?tag=${tag.toLowerCase()}`;
|
||||
|
||||
return (
|
||||
<a
|
||||
href={href}
|
||||
className={classNames(
|
||||
'px-2 text-xs cursor-pointer rounded-full border border-secondary bg-secondary bg-opacity-25 text-primary font-thin',
|
||||
)}
|
||||
>
|
||||
<p className="flex items-center h-4">{tag.toLowerCase()}</p>
|
||||
</a>
|
||||
);
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
import React from 'react';
|
||||
import { TagBlock } from './TagBlock';
|
||||
|
||||
interface Props {
|
||||
tags: string[];
|
||||
}
|
||||
|
||||
export function TagRow({ tags }: Props) {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
height: 'calc(1rem + 2px)',
|
||||
}}
|
||||
className="flex flex-wrap space-x-2 overflow-hidden"
|
||||
>
|
||||
{tags
|
||||
.filter(tag => Boolean(tag))
|
||||
// Maximum of three tags
|
||||
.slice(0, 3)
|
||||
.map(tag => (
|
||||
<TagBlock key={tag} tag={tag} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -16,7 +16,7 @@ export function ArticleSubtitleSection({ subtitle }: Props) {
|
|||
style={{
|
||||
maxWidth: isDesktop ? '700px' : 'unset',
|
||||
}}
|
||||
className="w-full mb-3 text-lg font-medium text-center text-gray-900 desktop:mb-6 desktop:text-2xl font-roboto"
|
||||
className="w-full mb-3 text-lg font-medium text-center text-gray-900 desktop:mb-6 desktop:text-2xl font-sans"
|
||||
>
|
||||
{subtitle}
|
||||
</span>
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
import React from 'react';
|
||||
import YouTube from 'react-youtube';
|
||||
|
||||
interface Props {
|
||||
video: string;
|
||||
}
|
||||
|
||||
export function ArticleFeatureVideoWidget({ video }: Props) {
|
||||
return (
|
||||
<div className="w-full">
|
||||
<div
|
||||
style={{
|
||||
// Padding bottom of 56.25% corresponds to 16/9 aspect ratio
|
||||
paddingBottom: '56.25%',
|
||||
}}
|
||||
className="relative h-0 w-full rounded-lg overflow-hidden"
|
||||
>
|
||||
<YouTube
|
||||
videoId={video}
|
||||
className="absolute inset-0 w-full h-full"
|
||||
// Tracking -> user started video
|
||||
// onPlay={() => }
|
||||
/>
|
||||
|
||||
{/* <div className="absolute inset-0 flex justify-center items-center">
|
||||
<div className="flex justify-center items-center rounded-full bg-primary h-20 w-20">
|
||||
<div
|
||||
style={{
|
||||
clipPath: 'polygon(100% 50%, 0 0, 0 100%)',
|
||||
}}
|
||||
className="bg-white ml-2 w-8 h-10"
|
||||
></div>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
|
||||
<div className="w-10/12 desktop:w-64 text-sm desktop:text-base italic mt-4 pl-2">
|
||||
Lorem ipsum dolor sit amet consectetur adipisicing elit. Soluta labore
|
||||
eius iure aliquid asperiores cum, quibusdam sapiente!
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -1,105 +0,0 @@
|
|||
import { useRouter } from 'next/router';
|
||||
import React, { useState } from 'react';
|
||||
// import ShareSVG from '../../../assets/svgs/share.svg';
|
||||
import {
|
||||
shareToFacebook,
|
||||
shareToReddit,
|
||||
shareToTwitter,
|
||||
shareToWhatsApp,
|
||||
} from '../../../utils/share';
|
||||
import { Button } from '../../Button';
|
||||
import { Dropdown } from '../../Dropdown';
|
||||
import { DropdownItem } from '../../DropdownItem';
|
||||
import { Input } from '../../Input';
|
||||
import { InputGroup } from '../../InputGroup';
|
||||
|
||||
interface IShareDropdownItems {
|
||||
id: string;
|
||||
name: string;
|
||||
onClick: () => void;
|
||||
}
|
||||
|
||||
interface Props {
|
||||
id: string;
|
||||
title: string;
|
||||
slug: string;
|
||||
}
|
||||
|
||||
export function ArticleShareWidget(props: Props) {
|
||||
const { id, title, slug } = props;
|
||||
|
||||
const router = useRouter();
|
||||
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
|
||||
const articleUrl = `oxen.io${router.asPath}`;
|
||||
|
||||
const dropdownItems: Array<IShareDropdownItems> = [
|
||||
{
|
||||
id: 'share-to-facebook',
|
||||
name: 'Facebook',
|
||||
onClick: () => shareToFacebook(title, slug),
|
||||
},
|
||||
{
|
||||
id: 'share-to-twitter',
|
||||
name: 'Twitter',
|
||||
onClick: () => shareToTwitter(title, slug),
|
||||
},
|
||||
{
|
||||
id: 'share-to-whatsapp',
|
||||
name: 'WhatsApp',
|
||||
onClick: () => shareToWhatsApp(title, slug),
|
||||
},
|
||||
{
|
||||
id: 'share-to-reddit',
|
||||
name: 'Reddit',
|
||||
onClick: () => shareToReddit(title, slug),
|
||||
},
|
||||
];
|
||||
|
||||
return (
|
||||
<div className="flex justify-center w-full z-10">
|
||||
<div
|
||||
style={{ width: 'fit-content' }}
|
||||
className="flex bg-soft cursor-pointer rounded-md text-primary my-4"
|
||||
>
|
||||
<div
|
||||
className="flex flex-1 items-center cursor-pointer px-2 py-1 space-x-1 hover:bg-subtle-2 font-medium rounded-r-md"
|
||||
onClick={() => setIsDropdownOpen(true)}
|
||||
>
|
||||
{/* <ShareSVG className="h-8" /> */}
|
||||
<span>Share</span>
|
||||
</div>
|
||||
|
||||
<Dropdown
|
||||
isOpen={isDropdownOpen}
|
||||
onClickAway={() => setIsDropdownOpen(false)}
|
||||
pull="center"
|
||||
offsetX={-50}
|
||||
offsetY={25}
|
||||
>
|
||||
<>
|
||||
<div className="px-3 pt-1 pb-2">
|
||||
<InputGroup className="w-full rounded-sm bg-secondary bg-opacity-25">
|
||||
<Input
|
||||
style={{ minWidth: '9rem' }}
|
||||
border="none"
|
||||
readonly
|
||||
value={articleUrl}
|
||||
/>
|
||||
|
||||
<Button type="text" size="small" color="primary">
|
||||
COPY
|
||||
</Button>
|
||||
</InputGroup>
|
||||
</div>
|
||||
|
||||
{dropdownItems.map(item => (
|
||||
<DropdownItem key={item.id} id={item.id} onSelect={item.onClick}>
|
||||
<div className="w-full text-center">{item.name}</div>
|
||||
</DropdownItem>
|
||||
))}
|
||||
</>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -13,7 +13,7 @@ export function ArticleWidgetAuthor({ author, publishedDate }: Props) {
|
|||
<Avatar size={10} imageSrc={author?.avatar.imageUrl} />
|
||||
|
||||
<div className="flex flex-col leading-tight">
|
||||
<span className="text-sm font-bold tracking-wider font-roboto">
|
||||
<span className="text-sm font-bold tracking-wider font-sans">
|
||||
By: {author?.name}
|
||||
</span>
|
||||
<span>{publishedDate}</span>
|
||||
|
|
|
@ -1,104 +1,85 @@
|
|||
import classNames from 'classnames';
|
||||
import router from 'next/dist/client/router';
|
||||
import { SyntheticEvent } from 'react';
|
||||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
import { useMeasure } from 'react-use';
|
||||
import { IPost } from '../../types/cms';
|
||||
import { generateURL } from '../../utils/routing';
|
||||
import { titleCase } from '../../utils/text';
|
||||
import { OutlineBlock } from '../OutlineBlock';
|
||||
import { TagRow } from '../TagRow';
|
||||
|
||||
export function ArticleCard(props: IPost): JSX.Element {
|
||||
const {
|
||||
featureImage,
|
||||
title,
|
||||
description,
|
||||
subtitle,
|
||||
/*tags*/ slug,
|
||||
// city,
|
||||
// category,
|
||||
featureImage,
|
||||
publishedDate,
|
||||
author,
|
||||
tags,
|
||||
slug,
|
||||
} = props;
|
||||
|
||||
const router = useRouter();
|
||||
const [ref, { width }] = useMeasure();
|
||||
const isSmall = width < 130;
|
||||
|
||||
const handleClick = (e: SyntheticEvent) => {
|
||||
const { href, as } = generateURL(slug);
|
||||
|
||||
e.preventDefault();
|
||||
router.push(href, as);
|
||||
};
|
||||
|
||||
const tags = ['admin', 'testing'];
|
||||
const { href, as } = generateURL(slug);
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={classNames(
|
||||
'overflow-hidden w-full bg-white shadow-lg bg-opacity-75',
|
||||
isSmall ? 'rounded-md' : 'rounded-lg',
|
||||
'overflow-hidden w-full bg-opacity-75',
|
||||
isSmall ? 'pb-3' : 'pb-1',
|
||||
)}
|
||||
onClick={e => handleClick(e)}
|
||||
>
|
||||
<div
|
||||
style={{ paddingBottom: '60%' }}
|
||||
className="relative w-full h-0 overflow-hidden bg-white bg-opacity-25"
|
||||
onClick={() => router.push(href, as)}
|
||||
className="relative aspect-w-16 aspect-h-9"
|
||||
>
|
||||
{featureImage.imageUrl && (
|
||||
<div className="absolute inset-0">
|
||||
<img
|
||||
className="object-cover w-full h-full"
|
||||
src={featureImage?.imageUrl}
|
||||
alt={featureImage?.description}
|
||||
/>
|
||||
</div>
|
||||
<img
|
||||
className="object-cover cursor-pointer"
|
||||
src={featureImage?.imageUrl}
|
||||
alt={featureImage?.description}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className={isSmall ? 'px-3' : 'px-4'}>
|
||||
<div>
|
||||
<div className={isSmall ? 'py-1' : 'py-3'}>
|
||||
<div
|
||||
style={{
|
||||
lineHeight: '1em',
|
||||
height: '2em',
|
||||
paddingBottom: '2.1em',
|
||||
}}
|
||||
className={classNames(
|
||||
isSmall ? 'text-base' : 'text-xl',
|
||||
'font-roboto overflow-hidden cursor-pointer',
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</div>
|
||||
<Link href={href} as={as}>
|
||||
<a>
|
||||
<p
|
||||
style={{
|
||||
maxHeight: '2em',
|
||||
}}
|
||||
className={classNames(
|
||||
isSmall ? 'text-base' : 'text-lg',
|
||||
'font-sans overflow-hidden cursor-pointer mb-3 hover:underline leading-none text-primary',
|
||||
)}
|
||||
>
|
||||
{title}
|
||||
</p>
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<p
|
||||
style={{
|
||||
lineHeight: '1em',
|
||||
height: '2em',
|
||||
height: '4em',
|
||||
paddingBottom: '2.1em',
|
||||
}}
|
||||
className="text-base text-gray-700"
|
||||
className="mt-1 overflow-hidden text-xs leading-none text-gray-800"
|
||||
>
|
||||
{subtitle}
|
||||
{description?.substr(0, 250) ?? subtitle}...
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className={classNames('flex space-x-1 mt-1', !isSmall && 'mb-2')}>
|
||||
{tags
|
||||
.filter(tag => Boolean(tag))
|
||||
// Maximum of three tags
|
||||
.slice(0, 3)
|
||||
.map(tag => (
|
||||
<div key={tag.toLowerCase()}>
|
||||
{isSmall ? (
|
||||
<span className="text-xs font-medium text-primary hover:underline">
|
||||
{titleCase(tag)}
|
||||
</span>
|
||||
) : (
|
||||
<OutlineBlock size="tiny" theme="default" bold key={tag}>
|
||||
{titleCase(tag)}
|
||||
</OutlineBlock>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
<div className="flex flex-col space-y-1">
|
||||
<p className="mt-2 font-sans text-xs text-gray-800">
|
||||
{publishedDate} — {author.name}
|
||||
</p>
|
||||
<TagRow tags={tags} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
import Link from 'next/link';
|
||||
import { useRouter } from 'next/router';
|
||||
import React from 'react';
|
||||
import { IPost } from '../../types/cms';
|
||||
import { generateURL } from '../../utils/routing';
|
||||
import { TagRow } from '../TagRow';
|
||||
|
||||
export function ArticleCardFeature(props: IPost) {
|
||||
const {
|
||||
featureImage,
|
||||
title,
|
||||
subtitle,
|
||||
description,
|
||||
author,
|
||||
publishedDate,
|
||||
tags,
|
||||
slug,
|
||||
} = props;
|
||||
|
||||
const { href, as } = generateURL(slug);
|
||||
|
||||
const router = useRouter();
|
||||
const onClick = () => router.push(href, as);
|
||||
|
||||
return (
|
||||
<div className="flex w-full space-x-6">
|
||||
<div className="w-7/12 relatvie">
|
||||
<div
|
||||
onClick={onClick}
|
||||
style={{ minHeight: '100%' }}
|
||||
className="bg-opacity-25 cursor-pointer bg-primary aspect-w-14 aspect-h-8"
|
||||
>
|
||||
<img className="object-cover" src={featureImage.imageUrl} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex flex-col justify-between w-5/12">
|
||||
<div className="flex flex-col space-y-3">
|
||||
<Link href={href} as={as}>
|
||||
<a
|
||||
style={{ height: '2.95em' }}
|
||||
className="overflow-hidden font-sans text-3xl font-medium leading-none hover:underline"
|
||||
>
|
||||
{title} and other sutff thatfills u pthe title for lots of lines
|
||||
and lots more lines and heaps of lines
|
||||
</a>
|
||||
</Link>
|
||||
|
||||
<div className="flex-grow overflow-hidden">
|
||||
<p
|
||||
style={{ maxHeight: '7.25em' }}
|
||||
className="overflow-hidden text-sm leading-tight "
|
||||
>
|
||||
{description.substring(0, 250)}...
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<p className="mt-3 mb-2 font-sans text-xs font-thin">
|
||||
{publishedDate} — {author.name}
|
||||
</p>
|
||||
|
||||
<TagRow tags={tags} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
|
@ -46,7 +46,7 @@ export function ArticleCardRow(post: IPost) {
|
|||
<div className="flex w-full space-x-6">
|
||||
<ArticlePreviewImage />
|
||||
<div className="w-2/3">
|
||||
<h3 className="font-roboto text-twoxl text-primary">
|
||||
<h3 className="font-sans text-twoxl text-primary">
|
||||
{post.title}
|
||||
</h3>
|
||||
</div>
|
||||
|
@ -62,7 +62,7 @@ export function ArticleCardRow(post: IPost) {
|
|||
className="flex flex-col flex-grow"
|
||||
>
|
||||
<Link href={href} as={as}>
|
||||
<a className="text-xl font-roboto text-primary">{post.title}</a>
|
||||
<a className="font-sans text-xl text-primary">{post.title}</a>
|
||||
</Link>
|
||||
|
||||
<ArticlePreviewContent />
|
||||
|
|
|
@ -13,13 +13,13 @@ interface Props {
|
|||
export function CardGrid({ children }: Props) {
|
||||
const { isMobile, isTablet, isDesktop, isHuge } = useContext(ScreenContext);
|
||||
|
||||
const spacing = isHuge ? 4 : isDesktop ? 4 : 3;
|
||||
const spacingX = `pl-${spacing}`;
|
||||
const spacing = isHuge ? 4 : isDesktop ? 6 : 4;
|
||||
const spacingY = `space-y-${spacing}`;
|
||||
const spacingX = `space-x-${spacing}`;
|
||||
|
||||
return (
|
||||
<>
|
||||
{isMobile || isTablet ? (
|
||||
{isMobile ? (
|
||||
<div className="">
|
||||
<HorizontalScrollable>
|
||||
{children.map(child => (
|
||||
|
@ -42,26 +42,11 @@ export function CardGrid({ children }: Props) {
|
|||
<div className={classNames('flex flex-col', spacingY)}>
|
||||
{_.chunk(
|
||||
children,
|
||||
isHuge ? 4 : isDesktop ? 3 : isTablet ? 2 : 1,
|
||||
isHuge ? 4 : isDesktop ? 2 : isTablet ? 2 : 1,
|
||||
).map(group => (
|
||||
<div key={uuid()} className="flex">
|
||||
<div key={uuid()} className={classNames('flex w-full', spacingX)}>
|
||||
{group.map((item, index) => (
|
||||
<div
|
||||
key={uuid()}
|
||||
className={classNames(
|
||||
spacingX,
|
||||
index === 0 && group.length > 1 && spacingX,
|
||||
index === 1 && group.length > 2 && spacingX,
|
||||
index === 2 && group.length > 3 && spacingX,
|
||||
isHuge
|
||||
? 'w-1/4'
|
||||
: isDesktop
|
||||
? 'w-1/3'
|
||||
: isTablet
|
||||
? 'w-1/2'
|
||||
: 'w-full',
|
||||
)}
|
||||
>
|
||||
<div key={uuid()} className="flex-1">
|
||||
{item}
|
||||
</div>
|
||||
))}
|
||||
|
|
|
@ -8,7 +8,7 @@ export function ColorPalette() {
|
|||
<SectionTitle>Color Palette</SectionTitle>
|
||||
</div>
|
||||
<div className="flex pb-10 space-x-4">
|
||||
<div className="flex flex-col space-y-3 font-roboto">
|
||||
<div className="flex flex-col space-y-3 font-sans">
|
||||
<div className="flex justify-center items-center w-8 h-8 text-3xl">
|
||||
0
|
||||
</div>
|
||||
|
|
|
@ -11,11 +11,16 @@ interface Props {
|
|||
}
|
||||
|
||||
export default function Layout({ children }: Props) {
|
||||
const { isTablet } = useContext(ScreenContext);
|
||||
const { isTablet, isDesktop } = useContext(ScreenContext);
|
||||
const { sideMenuSplit, sideMenuExpanded } = useSelector(
|
||||
(state: IState) => state.navigation,
|
||||
);
|
||||
|
||||
const marginLeft =
|
||||
(!sideMenuSplit && isDesktop) || isTablet
|
||||
? UI.SIDE_MENU_SIDE_BAR_WIDTH_PX
|
||||
: 0;
|
||||
|
||||
return (
|
||||
<div
|
||||
style={{ height: '100vh', width: '100%' }}
|
||||
|
@ -32,7 +37,7 @@ export default function Layout({ children }: Props) {
|
|||
<SideMenu />
|
||||
<div
|
||||
style={{
|
||||
marginLeft: `${isTablet ? UI.SIDE_MENU_SIDE_BAR_WIDTH_PX : 0}px`,
|
||||
marginLeft: `${marginLeft}px`,
|
||||
filter:
|
||||
!sideMenuSplit && sideMenuExpanded
|
||||
? 'brightness(0.9)'
|
||||
|
|
|
@ -27,7 +27,7 @@ export function DesktopHeader() {
|
|||
</Link>
|
||||
</div>
|
||||
|
||||
<div className="flex ml-6 space-x-4">
|
||||
<div className="flex ml-6 space-x-4 text-sm">
|
||||
{NAVIGATION.MENU_ITEMS.map(item => (
|
||||
<Link key={item.label} href={item.href} as={item.href}>
|
||||
<a className="uppercase whitespace-no-wrap hover:underline">
|
||||
|
|
|
@ -4,6 +4,6 @@ import { DesktopHeader } from './DesktopHeader';
|
|||
import { MobileHeader } from './MobileHeader';
|
||||
|
||||
export function Header() {
|
||||
const { isHuge } = useContext(ScreenContext);
|
||||
return <>{isHuge ? <DesktopHeader /> : <MobileHeader />}</>;
|
||||
const { isDesktop } = useContext(ScreenContext);
|
||||
return <>{isDesktop ? <DesktopHeader /> : <MobileHeader />}</>;
|
||||
}
|
||||
|
|
|
@ -38,9 +38,9 @@ export function SideMenuInner() {
|
|||
))}
|
||||
</div>
|
||||
|
||||
{!isHuge && (
|
||||
<Contained>
|
||||
<div className="flex flex-col w-full space-y-4">
|
||||
<Contained>
|
||||
<div className="flex flex-col w-full space-y-4">
|
||||
{!isDesktop && (
|
||||
<div
|
||||
className={classNames(
|
||||
'flex justify-between pt-8 pb-2 font-medium uppercase font-prompt',
|
||||
|
@ -57,15 +57,14 @@ export function SideMenuInner() {
|
|||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
<div className="flex space-x-3">
|
||||
<FacebookSVG className="h-10" />
|
||||
<TwitterSVG className="h-10" />
|
||||
<InstargamSVG className="h-10" />
|
||||
</div>
|
||||
)}
|
||||
<div className="flex space-x-3">
|
||||
<FacebookSVG className="h-10" />
|
||||
<TwitterSVG className="h-10" />
|
||||
<InstargamSVG className="h-10" />
|
||||
</div>
|
||||
</Contained>
|
||||
)}
|
||||
</div>
|
||||
</Contained>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
import classNames from 'classnames';
|
||||
import React from 'react';
|
||||
import { useSelector } from 'react-redux';
|
||||
import React, { useRef } from 'react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useClickAway } from 'react-use';
|
||||
import { UI } from '../../constants';
|
||||
import { collapseSideMenu } from '../../state/navigation';
|
||||
import { IState } from '../../state/reducers';
|
||||
import { SideMenuInner } from './SideMenuInner';
|
||||
import { SideBarMode, SideMenuSideBar } from './SideMenuSideBar';
|
||||
|
@ -11,8 +13,16 @@ export function SideMenuSplit() {
|
|||
(state: IState) => state.navigation,
|
||||
);
|
||||
|
||||
console.log('Side menu split?', sideMenuSplit);
|
||||
console.log('SideMenuSplit ➡️ sideMenuExpanded:', sideMenuExpanded);
|
||||
const ref = useRef(null);
|
||||
const dispatch = useDispatch();
|
||||
|
||||
const onClickAway = () => {
|
||||
if (sideMenuExpanded && !sideMenuSplit) {
|
||||
dispatch(collapseSideMenu());
|
||||
}
|
||||
};
|
||||
|
||||
useClickAway(ref, onClickAway);
|
||||
|
||||
const transform =
|
||||
sideMenuSplit || sideMenuExpanded
|
||||
|
@ -21,6 +31,7 @@ export function SideMenuSplit() {
|
|||
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
style={{
|
||||
minWidth: '50vw',
|
||||
zIndex: 30033,
|
||||
|
|
|
@ -8,12 +8,12 @@ export interface IMenuItem {
|
|||
|
||||
const MENU_ITEMS: IMenuItem[] = [
|
||||
{ label: 'Docs', href: '/' },
|
||||
{ label: 'Dev Updates', href: '/' },
|
||||
// { label: 'Dev Updates', href: '/' },
|
||||
{ label: 'CoinGecko', href: '/' },
|
||||
{ label: 'Wallet', href: '/' },
|
||||
{ label: 'Explorer', href: '/' },
|
||||
{ label: 'Community', href: '/' },
|
||||
{ label: 'Technology', href: '/' },
|
||||
{ label: 'Tech', href: '/' },
|
||||
];
|
||||
|
||||
// TODO - Put SIDE_MENU_ITEMS in Contentful and fetch them server side.
|
||||
|
|
|
@ -2,7 +2,7 @@ const UI = {
|
|||
MOBILE_BREAKPOINT: 500,
|
||||
TABLET_BREAKPOINT: 715,
|
||||
DESKTOP_BREAKPOINT: 1100,
|
||||
MAX_CONTENT_WIDTH: 1233,
|
||||
MAX_CONTENT_WIDTH: 1000,
|
||||
PAGE_CONTAINED_PADDING_VW: 5,
|
||||
|
||||
HEADER_HEIGHT_PX: 50,
|
||||
|
|
|
@ -25,5 +25,5 @@ export function useScreenSize() {
|
|||
if (isHuge !== _isHuge) setIsHuge(_isHuge);
|
||||
}, [width]);
|
||||
|
||||
return { isMobile, isTablet, isDesktop, isHuge };
|
||||
return { isMobile, isTablet, isDesktop, isHuge, width };
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@
|
|||
"react-dom": "^17.0.0",
|
||||
"react-paginate": "^6.5.0",
|
||||
"react-redux": "^7.2.1",
|
||||
"react-use": "^15.3.4",
|
||||
"react-use": "^17.1.0",
|
||||
"redux": "^4.0.5",
|
||||
"redux-firestore": "^0.14.0",
|
||||
"swr": "^0.3.9",
|
||||
|
|
|
@ -65,13 +65,13 @@ function oxen404() {
|
|||
<div style={_404SectionStyles} className="absolute left-0 z-50">
|
||||
<h1
|
||||
style={_404TitleStyles}
|
||||
className="-mb-4 text-opacity-25 font-roboto text-primary text-8xl"
|
||||
className="-mb-4 text-opacity-25 font-sans text-primary text-8xl"
|
||||
>
|
||||
404
|
||||
</h1>
|
||||
<p
|
||||
style={_404TextStyles}
|
||||
className="text-4xl tracking-tight font-roboto text-primary"
|
||||
className="text-4xl tracking-tight font-sans text-primary"
|
||||
>
|
||||
Nothing found here.
|
||||
</p>
|
||||
|
@ -87,7 +87,7 @@ function oxen404() {
|
|||
<div className="z-50 flex-col flex-grow my-4">
|
||||
<h2
|
||||
className={classNames(
|
||||
'text-primary font-roboto font-semibold ml-1 mt-6 text-twoxl whitespace-no-wrap',
|
||||
'text-primary font-sans font-semibold ml-1 mt-6 text-twoxl whitespace-no-wrap',
|
||||
)}
|
||||
>
|
||||
Something went wrong?
|
||||
|
@ -107,7 +107,7 @@ function oxen404() {
|
|||
<div
|
||||
role="button"
|
||||
className={classNames(
|
||||
'bg-primary cursor-pointer mt-4 text-white font-roboto px-4 py-2 select-none rounded-lg text-center',
|
||||
'bg-primary cursor-pointer mt-4 text-white font-sans px-4 py-2 select-none rounded-lg text-center',
|
||||
isMobile ? 'text-lg' : 'text-sm',
|
||||
isMobile ? 'w-full' : 'w-4/12',
|
||||
)}
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
import { InferGetServerSidePropsType } from 'next';
|
||||
import Head from 'next/head';
|
||||
import React from 'react';
|
||||
import { useRouter } from 'next/router';
|
||||
import React, { useEffect } from 'react';
|
||||
import { ArticleCard } from '../../components/cards/ArticleCard';
|
||||
import { ArticleCardFeature } from '../../components/cards/ArticleCardFeature';
|
||||
import { CardGrid } from '../../components/cards/CardGrid';
|
||||
import { Contained } from '../../components/Contained';
|
||||
import { CmsApi } from '../../services/cms';
|
||||
import { generateTitle } from '../../utils/metadata';
|
||||
|
||||
|
@ -21,13 +24,23 @@ const Blog = (
|
|||
|
||||
console.log('index ➡️ posts:', posts);
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
useEffect(() => {
|
||||
console.log('index ➡️ router.query;:', router.query);
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<Head>
|
||||
<title>{generateTitle('Blog')}</title>
|
||||
</Head>
|
||||
|
||||
<div className="flex flex-col w-full space-y-10">
|
||||
<div className="flex flex-col w-full mt-6 space-y-10">
|
||||
<Contained>
|
||||
<ArticleCardFeature {...posts[0]} />
|
||||
</Contained>
|
||||
|
||||
<CardGrid>
|
||||
{[...posts, ...posts, ...posts, ...posts, ...posts]?.map(post => (
|
||||
<ArticleCard key={post.id} {...post} />
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -127,12 +127,13 @@ export class CmsApi {
|
|||
console.log('blog ➡️ author', rawAuthor);
|
||||
|
||||
return {
|
||||
id: rawData.sys.id,
|
||||
body: rawPost.body,
|
||||
subtitle: rawPost.subtitle,
|
||||
publishedDate: moment(rawPost.publishedDate).format('DD MMM YYYY'),
|
||||
id: rawData.sys.id ?? null,
|
||||
body: rawPost.body ?? null,
|
||||
subtitle: rawPost.subtitle ?? null,
|
||||
description: rawPost.description ?? null,
|
||||
publishedDate: moment(rawPost.publishedDate).format('DD MMMM YYYY'),
|
||||
slug: rawPost.slug,
|
||||
tags: rawPost?.tags ?? [],
|
||||
tags: rawPost?.tags?.map(t => t?.fields?.label) ?? [],
|
||||
title: rawPost.title,
|
||||
featureImage: this.convertImage(rawFeatureImage),
|
||||
author: this.convertAuthor(rawAuthor),
|
||||
|
|
|
@ -16,6 +16,7 @@ export type TPages = {
|
|||
};
|
||||
|
||||
export interface INavigation {
|
||||
headerCollapsed: boolean;
|
||||
sideMenuExpanded: boolean;
|
||||
sideMenuSplit: boolean;
|
||||
pages?: TPages;
|
||||
|
@ -24,11 +25,13 @@ export interface INavigation {
|
|||
export const initialNavigationState: INavigation = {
|
||||
// Side menu expanded only toggles for mobile.
|
||||
// On desktop it's always open (if it fits).
|
||||
headerCollapsed: true,
|
||||
sideMenuExpanded: false,
|
||||
sideMenuSplit: true,
|
||||
};
|
||||
|
||||
export enum NavigationActions {
|
||||
SET_HEADER_COLLAPSED = 'SET_HEADER_COLLAPSED',
|
||||
SET_SIDE_MENU_SPLIT = 'SET_SIDE_MENU_SPLIT',
|
||||
EXPAND_SIDE_MENU = 'EXPAND_SIDE_MENU',
|
||||
COLLAPSE_SIDE_MENU = 'COLLAPSE_SIDE_MENU',
|
||||
|
@ -38,6 +41,11 @@ export enum NavigationActions {
|
|||
// ////////////////////////////// //
|
||||
// Action Creators //
|
||||
// ////////////////////////////// //
|
||||
export const setHeaderCollapsed = (collapsed: boolean) => ({
|
||||
type: NavigationActions.SET_HEADER_COLLAPSED,
|
||||
payload: collapsed,
|
||||
});
|
||||
|
||||
export const setSideMenuSplit = (split: boolean) => ({
|
||||
type: NavigationActions.SET_SIDE_MENU_SPLIT,
|
||||
payload: split,
|
||||
|
|
|
@ -14,6 +14,9 @@ export const navigationReducer = (
|
|||
action: NavigationAction,
|
||||
) => {
|
||||
switch (action.type) {
|
||||
case NavigationActions.SET_HEADER_COLLAPSED: {
|
||||
return { ...state, headerCollapsed: action.payload };
|
||||
}
|
||||
case NavigationActions.SET_SIDE_MENU_SPLIT: {
|
||||
return { ...state, sideMenuSplit: action.payload };
|
||||
}
|
||||
|
|
|
@ -11,8 +11,7 @@ module.exports = {
|
|||
},
|
||||
fontFamily: {
|
||||
prompt: ['Prompt'],
|
||||
roboto: ['Roboto'],
|
||||
robotoslab: ['RobotoSlab'],
|
||||
sans: ['WorkSans'],
|
||||
},
|
||||
fontSize: {
|
||||
xs: ['.75rem'],
|
||||
|
|
|
@ -19,17 +19,18 @@ export type IFigureImage = {
|
|||
imageUrl: string;
|
||||
};
|
||||
|
||||
export type IPost = {
|
||||
export interface IPost {
|
||||
id: string;
|
||||
title: string;
|
||||
subtitle: string;
|
||||
description: string;
|
||||
body: Document;
|
||||
author?: IAuthor;
|
||||
publishedDate: string;
|
||||
featureImage?: IFigureImage;
|
||||
tags: Array<string>;
|
||||
slug: string;
|
||||
};
|
||||
}
|
||||
|
||||
export type BodyDocument = {
|
||||
nodeType: 'document';
|
||||
|
|
141
yarn.lock
141
yarn.lock
|
@ -1396,11 +1396,6 @@
|
|||
"@types/react" "*"
|
||||
hoist-non-react-statics "^3.3.0"
|
||||
|
||||
"@types/js-cookie@2.2.6":
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f"
|
||||
integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==
|
||||
|
||||
"@types/json-schema@^7.0.3", "@types/json-schema@^7.0.4":
|
||||
version "7.0.5"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.5.tgz#dcce4430e64b443ba8945f0290fb564ad5bac6dd"
|
||||
|
@ -1753,7 +1748,7 @@
|
|||
"@webassemblyjs/wast-parser" "1.9.0"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@xobotyi/scrollbar-width@1.9.5":
|
||||
"@xobotyi/scrollbar-width@^1.9.5":
|
||||
version "1.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d"
|
||||
integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==
|
||||
|
@ -2775,11 +2770,6 @@ boolbase@^1.0.0, boolbase@~1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
|
||||
integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
|
||||
|
||||
bowser@^1.7.3:
|
||||
version "1.9.4"
|
||||
resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a"
|
||||
integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ==
|
||||
|
||||
boxen@^1.2.1:
|
||||
version "1.3.0"
|
||||
resolved "https://registry.yarnpkg.com/boxen/-/boxen-1.3.0.tgz#55c6c39a8ba58d9c61ad22cd877532deb665a20b"
|
||||
|
@ -3550,7 +3540,7 @@ copy-descriptor@^0.1.0:
|
|||
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
|
||||
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
|
||||
|
||||
copy-to-clipboard@^3.2.0:
|
||||
copy-to-clipboard@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae"
|
||||
integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==
|
||||
|
@ -3800,7 +3790,7 @@ css-tree@1.0.0-alpha.37:
|
|||
mdn-data "2.0.4"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-tree@1.0.0-alpha.39, css-tree@^1.0.0-alpha.28:
|
||||
css-tree@1.0.0-alpha.39:
|
||||
version "1.0.0-alpha.39"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.0.0-alpha.39.tgz#2bff3ffe1bb3f776cf7eefd91ee5cba77a149eeb"
|
||||
integrity sha512-7UvkEYgBAHRG9Nt980lYxjsTrCyHFN53ky3wVsDkiMdVqylqRt+Zc+jm5qw7/qyOvN2dHSYtX0e4MbCCExSvnA==
|
||||
|
@ -3808,6 +3798,14 @@ css-tree@1.0.0-alpha.39, css-tree@^1.0.0-alpha.28:
|
|||
mdn-data "2.0.6"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-tree@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5"
|
||||
integrity sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==
|
||||
dependencies:
|
||||
mdn-data "2.0.14"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-unit-converter@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21"
|
||||
|
@ -3913,16 +3911,16 @@ csso@^4.0.2:
|
|||
dependencies:
|
||||
css-tree "1.0.0-alpha.39"
|
||||
|
||||
csstype@^2.5.5:
|
||||
version "2.6.13"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.13.tgz#a6893015b90e84dd6e85d0e3b442a1e84f2dbe0f"
|
||||
integrity sha512-ul26pfSQTZW8dcOnD2iiJssfXw0gdNVX9IJDH/X3K5DGPfj+fUYe3kB+swUY6BF3oZDxaID3AJt+9/ojSAE05A==
|
||||
|
||||
csstype@^3.0.2:
|
||||
version "3.0.2"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.2.tgz#ee5ff8f208c8cd613b389f7b222c9801ca62b3f7"
|
||||
integrity sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==
|
||||
|
||||
csstype@^3.0.6:
|
||||
version "3.0.6"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.6.tgz#865d0b5833d7d8d40f4e5b8a6d76aea3de4725ef"
|
||||
integrity sha512-+ZAmfyWMT7TiIlzdqJgjMb7S4f1beorDbWbsocyK4RaiqA5RTX3K14bnBWmmA9QEM0gRdsjyyrEmcyga8Zsxmw==
|
||||
|
||||
currently-unhandled@^0.4.1:
|
||||
version "0.4.1"
|
||||
resolved "https://registry.yarnpkg.com/currently-unhandled/-/currently-unhandled-0.4.1.tgz#988df33feab191ef799a61369dd76c17adf957ea"
|
||||
|
@ -4690,10 +4688,10 @@ fast-shallow-equal@^1.0.0:
|
|||
resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b"
|
||||
integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==
|
||||
|
||||
fastest-stable-stringify@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-1.0.1.tgz#9122d406d4c9d98bea644a6b6853d5874b87b028"
|
||||
integrity sha1-kSLUBtTJ2YvqZEpraFPVh0uHsCg=
|
||||
fastest-stable-stringify@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76"
|
||||
integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==
|
||||
|
||||
fastparse@^1.1.2:
|
||||
version "1.1.2"
|
||||
|
@ -5599,12 +5597,11 @@ ini@^1.3.4, ini@^1.3.5, ini@~1.3.0:
|
|||
resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927"
|
||||
integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==
|
||||
|
||||
inline-style-prefixer@^4.0.0:
|
||||
version "4.0.2"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-4.0.2.tgz#d390957d26f281255fe101da863158ac6eb60911"
|
||||
integrity sha512-N8nVhwfYga9MiV9jWlwfdj1UDIaZlBFu4cJSJkIr7tZX7sHpHhGR5su1qdpW+7KPL8ISTvCIkcaFi/JdBknvPg==
|
||||
inline-style-prefixer@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz#f73d5dbf2855733d6b153a4d24b7b47a73e9770b"
|
||||
integrity sha512-XTHvRUS4ZJNzC1GixJRmOlWSS45fSt+DJoyQC9ytj0WxQfcgofQtDtyKKYxHUqEsWCs+LIWftPF1ie7+i012Fg==
|
||||
dependencies:
|
||||
bowser "^1.7.3"
|
||||
css-in-js-utils "^2.0.0"
|
||||
|
||||
insert-css@^2.0.0:
|
||||
|
@ -6457,6 +6454,11 @@ md5.js@^1.3.4:
|
|||
inherits "^2.0.1"
|
||||
safe-buffer "^5.1.2"
|
||||
|
||||
mdn-data@2.0.14:
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||
|
||||
mdn-data@2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
|
||||
|
@ -6734,19 +6736,19 @@ nan@^2.12.1, nan@^2.13.2:
|
|||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.1.tgz#d7be34dfa3105b91494c3147089315eff8874b01"
|
||||
integrity sha512-isWHgVjnFjh2x2yuJ/tj3JbwoHu3UC2dX5G/88Cm24yB6YopVgxvBObDY7n5xW6ExmFhJpSEQqFPvq9zaXc8Jw==
|
||||
|
||||
nano-css@^5.2.1:
|
||||
version "5.3.0"
|
||||
resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.0.tgz#9d3cd29788d48b6a07f52aa4aec7cf4da427b6b5"
|
||||
integrity sha512-uM/9NGK9/E9/sTpbIZ/bQ9xOLOIHZwrrb/CRlbDHBU/GFS7Gshl24v/WJhwsVViWkpOXUmiZ66XO7fSB4Wd92Q==
|
||||
nano-css@^5.3.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.1.tgz#b709383e07ad3be61f64edffacb9d98250b87a1f"
|
||||
integrity sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==
|
||||
dependencies:
|
||||
css-tree "^1.0.0-alpha.28"
|
||||
csstype "^2.5.5"
|
||||
fastest-stable-stringify "^1.0.1"
|
||||
inline-style-prefixer "^4.0.0"
|
||||
rtl-css-js "^1.9.0"
|
||||
sourcemap-codec "^1.4.1"
|
||||
stacktrace-js "^2.0.0"
|
||||
stylis "3.5.0"
|
||||
css-tree "^1.1.2"
|
||||
csstype "^3.0.6"
|
||||
fastest-stable-stringify "^2.0.2"
|
||||
inline-style-prefixer "^6.0.0"
|
||||
rtl-css-js "^1.14.0"
|
||||
sourcemap-codec "^1.4.8"
|
||||
stacktrace-js "^2.0.2"
|
||||
stylis "^4.0.6"
|
||||
|
||||
nanoid@^3.1.12:
|
||||
version "3.1.12"
|
||||
|
@ -8334,25 +8336,24 @@ react-universal-interface@^0.6.2:
|
|||
resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b"
|
||||
integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==
|
||||
|
||||
react-use@^15.3.4:
|
||||
version "15.3.4"
|
||||
resolved "https://registry.yarnpkg.com/react-use/-/react-use-15.3.4.tgz#f853d310bd71f75b38900a8caa3db93f6dc6e872"
|
||||
integrity sha512-cHq1dELW6122oi1+xX7lwNyE/ugZs5L902BuO8eFJCfn2api1KeuPVG1M/GJouVARoUf54S2dYFMKo5nQXdTag==
|
||||
react-use@^17.1.0:
|
||||
version "17.1.0"
|
||||
resolved "https://registry.yarnpkg.com/react-use/-/react-use-17.1.0.tgz#a2db05f7cca2f09a6b90b2151cd4c620e9582fe8"
|
||||
integrity sha512-BVVG5FWXYhfkQcGhtSYNx3wPh5bvOZieH2iq1h6/WYTDCScade1JqoM5XRHPkYXfFzAzhb8QlAtt9Suj8yAumA==
|
||||
dependencies:
|
||||
"@types/js-cookie" "2.2.6"
|
||||
"@xobotyi/scrollbar-width" "1.9.5"
|
||||
copy-to-clipboard "^3.2.0"
|
||||
"@xobotyi/scrollbar-width" "^1.9.5"
|
||||
copy-to-clipboard "^3.3.1"
|
||||
fast-deep-equal "^3.1.3"
|
||||
fast-shallow-equal "^1.0.0"
|
||||
js-cookie "^2.2.1"
|
||||
nano-css "^5.2.1"
|
||||
nano-css "^5.3.1"
|
||||
react-universal-interface "^0.6.2"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
screenfull "^5.0.0"
|
||||
screenfull "^5.1.0"
|
||||
set-harmonic-interval "^1.0.1"
|
||||
throttle-debounce "^2.1.0"
|
||||
throttle-debounce "^3.0.1"
|
||||
ts-easing "^0.2.0"
|
||||
tslib "^2.0.0"
|
||||
tslib "^2.1.0"
|
||||
|
||||
react@^17.0.0:
|
||||
version "17.0.0"
|
||||
|
@ -8792,7 +8793,7 @@ ripemd160@^2.0.0, ripemd160@^2.0.1:
|
|||
hash-base "^3.0.0"
|
||||
inherits "^2.0.1"
|
||||
|
||||
rtl-css-js@^1.9.0:
|
||||
rtl-css-js@^1.14.0:
|
||||
version "1.14.0"
|
||||
resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.14.0.tgz#daa4f192a92509e292a0519f4b255e6e3c076b7d"
|
||||
integrity sha512-Dl5xDTeN3e7scU1cWX8c9b6/Nqz3u/HgR4gePc1kWXYiQWVQbKCEyK6+Hxve9LbcJ5EieHy1J9nJCN3grTtGwg==
|
||||
|
@ -8906,10 +8907,10 @@ schema-utils@^2.6.1, schema-utils@^2.6.5, schema-utils@^2.6.6:
|
|||
ajv "^6.12.2"
|
||||
ajv-keywords "^3.4.1"
|
||||
|
||||
screenfull@^5.0.0:
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.0.2.tgz#b9acdcf1ec676a948674df5cd0ff66b902b0bed7"
|
||||
integrity sha512-cCF2b+L/mnEiORLN5xSAz6H3t18i2oHh9BA8+CQlAh5DRw2+NFAGQJOSYbcGw8B2k04g/lVvFcfZ83b3ysH5UQ==
|
||||
screenfull@^5.1.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.1.0.tgz#85c13c70f4ead4c1b8a935c70010dfdcd2c0e5c8"
|
||||
integrity sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA==
|
||||
|
||||
scss-tokenizer@^0.2.3:
|
||||
version "0.2.3"
|
||||
|
@ -9216,7 +9217,7 @@ source-map@^0.5.0, source-map@^0.5.6:
|
|||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
||||
sourcemap-codec@^1.4.1:
|
||||
sourcemap-codec@^1.4.8:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||
|
@ -9314,7 +9315,7 @@ stacktrace-gps@^3.0.4:
|
|||
source-map "0.5.6"
|
||||
stackframe "^1.1.1"
|
||||
|
||||
stacktrace-js@^2.0.0:
|
||||
stacktrace-js@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b"
|
||||
integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==
|
||||
|
@ -9581,16 +9582,16 @@ stylis-rule-sheet@0.0.10:
|
|||
resolved "https://registry.yarnpkg.com/stylis-rule-sheet/-/stylis-rule-sheet-0.0.10.tgz#44e64a2b076643f4b52e5ff71efc04d8c3c4a430"
|
||||
integrity sha512-nTbZoaqoBnmK+ptANthb10ZRZOGC+EmTLLUxeYIuHNkEKcmKgXX1XWKkUBT2Ac4es3NybooPe0SmvKdhKJZAuw==
|
||||
|
||||
stylis@3.5.0:
|
||||
version "3.5.0"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.0.tgz#016fa239663d77f868fef5b67cf201c4b7c701e1"
|
||||
integrity sha512-pP7yXN6dwMzAR29Q0mBrabPCe0/mNO1MSr93bhay+hcZondvMMTpeGyd8nbhYJdyperNT2DRxONQuUGcJr5iPw==
|
||||
|
||||
stylis@3.5.4:
|
||||
version "3.5.4"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
|
||||
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
|
||||
|
||||
stylis@^4.0.6:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.7.tgz#412a90c28079417f3d27c028035095e4232d2904"
|
||||
integrity sha512-OFFeUXFgwnGOKvEXaSv0D0KQ5ADP0n6g3SVONx6I/85JzNZ3u50FRwB3lVIk1QO2HNdI75tbVzc4Z66Gdp9voA==
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
|
@ -9780,10 +9781,10 @@ text-table@^0.2.0:
|
|||
resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4"
|
||||
integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=
|
||||
|
||||
throttle-debounce@^2.1.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
|
||||
integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
|
||||
throttle-debounce@^3.0.1:
|
||||
version "3.0.1"
|
||||
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb"
|
||||
integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg==
|
||||
|
||||
through2@^2.0.0:
|
||||
version "2.0.5"
|
||||
|
@ -9942,10 +9943,10 @@ tslib@^1.8.1, tslib@^1.9.0:
|
|||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.13.0.tgz#c881e13cc7015894ed914862d276436fa9a47043"
|
||||
integrity sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==
|
||||
|
||||
tslib@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.1.tgz#410eb0d113e5b6356490eec749603725b021b43e"
|
||||
integrity sha512-SgIkNheinmEBgx1IUNirK0TUD4X9yjjBRTqqjggWCU3pUEqIk3/Uwl3yRixYKT6WjQuGiwDv4NomL3wqRCj+CQ==
|
||||
tslib@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
|
||||
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
|
||||
|
||||
tsutils@^3.17.1:
|
||||
version "3.17.1"
|
||||
|
|
Loading…
Reference in New Issue