This is an automated email from the ASF dual-hosted git repository.
juzhiyuan pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix-website.git
The following commit(s) were added to refs/heads/master by this push:
new 4fa9fdf58f9 feat: adapt blog pages, EventPosterCard for mobile (#1238)
4fa9fdf58f9 is described below
commit 4fa9fdf58f902fc2019a6456cb261d220c82796b
Author: Young <[email protected]>
AuthorDate: Tue Jul 26 23:00:30 2022 +0800
feat: adapt blog pages, EventPosterCard for mobile (#1238)
---
blog/src/theme/BlogLayout/index.tsx | 5 +-
blog/src/theme/BlogListPage/index.tsx | 127 +------------
blog/src/theme/BlogListPage/style.module.scss | 202 --------------------
.../theme/{BlogListPage => BlogPosts}/index.tsx | 163 +++++++++-------
blog/src/theme/BlogPosts/style.module.scss | 209 +++++++++++++++++++++
blog/src/theme/BlogTagsPostsPage/index.tsx | 110 +----------
blog/src/theme/BlogTagsPostsPage/style.module.scss | 126 -------------
website/src/components/EventPosterCard.tsx | 49 ++---
website/src/css/event-poster-card.module.scss | 7 +
9 files changed, 352 insertions(+), 646 deletions(-)
diff --git a/blog/src/theme/BlogLayout/index.tsx
b/blog/src/theme/BlogLayout/index.tsx
index b9b335a4440..1020d6433d2 100644
--- a/blog/src/theme/BlogLayout/index.tsx
+++ b/blog/src/theme/BlogLayout/index.tsx
@@ -20,7 +20,7 @@ import {
TwitterIcon,
TwitterShareButton,
} from 'react-share';
-
+import useWindowType from '@theme/hooks/useWindowSize';
import type { Props } from '@theme/BlogLayout';
import style from './style.module.scss';
@@ -50,6 +50,7 @@ const BlogLayout = (props: Props): JSX.Element => {
sidebar, toc, children, metadata, ...layoutProps
} = props;
const hasSidebar = sidebar && sidebar.items.length > 0;
+ const windowType = useWindowType();
return (
<Layout {...layoutProps}>
@@ -61,7 +62,7 @@ const BlogLayout = (props: Props): JSX.Element => {
</aside>
)}
<div className={clsx({ col: true, 'col--10': toc })}>{children}</div>
- {toc && (
+ {toc && windowType !== 'mobile' && (
<div className={clsx('col col--2', style.section)}>
{metadata && <Share metadata={metadata} />}
<section className={style.tocSection}>
diff --git a/blog/src/theme/BlogListPage/index.tsx
b/blog/src/theme/BlogListPage/index.tsx
index 728af4c97b0..531ae9cf479 100644
--- a/blog/src/theme/BlogListPage/index.tsx
+++ b/blog/src/theme/BlogListPage/index.tsx
@@ -12,106 +12,10 @@ import useDocusaurusContext from
'@docusaurus/useDocusaurusContext';
import BlogLayout from '@theme/BlogLayout';
import BlogListPaginator from '@theme/BlogListPaginator';
import type { Props } from '@theme/BlogListPage';
-import Link from '@docusaurus/Link';
-import type { Props as OldBlogPostItemProps } from '@theme/BlogPostItem';
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { MDXProvider } from '@mdx-js/react';
-import type { ScrollPosition } from 'react-lazy-load-image-component';
-import { trackWindowScroll, LazyLoadImage } from
'react-lazy-load-image-component';
-import Avvvatars from 'avvvatars-react';
-import clsx from 'clsx';
-import style from './style.module.scss';
+import BlogPosts from '../BlogPosts';
-const components = {
- blockquote: ({ children }) => children,
- p: ({ children }) => <p>{children.length > 200 ? `${children.slice(0,
200)}...` : children}</p>,
- a: ({ children }) => children,
-};
-
-const defaultImg = '/img/default-blog-header.jpg';
-
-type BlogPostItemProps = OldBlogPostItemProps & {
- scrollPosition: ScrollPosition;
-};
-
-type BlogListPageProps = Props & {
- scrollPosition: ScrollPosition;
-};
-
-const BlogPostItem: FC<BlogPostItemProps> = (props) => {
- const {
- children, frontMatter, assets, metadata, scrollPosition,
- } = props;
- const {
- date, formattedDate, permalink, tags, title, authors,
- } = metadata;
-
- const image = assets.image ?? frontMatter.image ?? defaultImg;
-
- return (
- <article itemProp="blogPost" itemScope
itemType="http://schema.org/BlogPosting">
- <Link itemProp="url" to={permalink} aria-label={`Read more about
${title}`}>
- <LazyLoadImage
- height={232}
- width={605}
- src={image}
- alt={title}
- effect="opacity"
- visibleByDefault={image === defaultImg}
- scrollPosition={scrollPosition}
- />
- </Link>
- <div className={style.content}>
- <header>
- {tags.length > 0 && (
- <div className={style.tags}>
- {tags.slice(0, 3).map((tag) => (
- <a key={tag.permalink} href={tag.permalink}>
- {tag.label}
- </a>
- ))}
- </div>
- )}
- <Link itemProp="url" to={permalink} aria-label={`Read more about
${title}`}>
- <h2>{title}</h2>
- {children && <MDXProvider
components={components}>{children}</MDXProvider>}
- </Link>
- </header>
- <footer className={style.footer}>
- {authors.length > 0 && (
- <>
- <div className={style.authors}>
- {authors.reverse().map((author) => (author.imageURL ? (
- <LazyLoadImage
- className={style.author}
- key={author.name}
- src={author.imageURL}
- width={32}
- height={32}
- scrollPosition={scrollPosition}
- />
- ) : (
- <div className={style.author} key={author.name}>
- <Avvvatars value={author.name as string} />
- </div>
- )))}
- </div>
- <div className={style.divider}>•</div>
- </>
- )}
- <time dateTime={date} itemProp="datePublished">
- {formattedDate}
- </time>
- </footer>
- </div>
- </article>
- );
-};
-
-const BlogListPage: FC<BlogListPageProps> = (props) => {
- const {
- metadata, items, sidebar, scrollPosition,
- } = props;
+const BlogListPage: FC<Props> = (props) => {
+ const { metadata, items, sidebar } = props;
const {
siteConfig: { title: siteTitle },
} = useDocusaurusContext();
@@ -123,10 +27,6 @@ const BlogListPage: FC<BlogListPageProps> = (props) => {
<BlogLayout
title={title}
description={blogDescription}
- wrapperClassName={clsx({
- [style.normalPage]: true,
- [style.firstPage]: !metadata.previousPage,
- })}
searchMetadatas={{
// assign unique search tag to exclude this page from search results!
tag: 'blog_posts_list',
@@ -134,23 +34,14 @@ const BlogListPage: FC<BlogListPageProps> = (props) => {
sidebar={sidebar}
toc={false}
>
- <main itemScope itemType="http://schema.org/Blog">
- {items.map(({ content: BlogPostContent }) => (
- <BlogPostItem
- key={BlogPostContent.metadata.permalink}
- frontMatter={BlogPostContent.frontMatter}
- assets={BlogPostContent.assets}
- metadata={BlogPostContent.metadata}
- truncated={BlogPostContent.metadata.truncated}
- scrollPosition={scrollPosition}
- >
- <BlogPostContent />
- </BlogPostItem>
- ))}
- </main>
+ <BlogPosts
+ itemType="http://schema.org/Blog"
+ items={items}
+ isFirstPage={!metadata.previousPage}
+ />
<BlogListPaginator metadata={metadata} />
</BlogLayout>
);
};
-export default trackWindowScroll(BlogListPage);
+export default BlogListPage;
diff --git a/blog/src/theme/BlogListPage/style.module.scss
b/blog/src/theme/BlogListPage/style.module.scss
deleted file mode 100644
index 9f6934e117d..00000000000
--- a/blog/src/theme/BlogListPage/style.module.scss
+++ /dev/null
@@ -1,202 +0,0 @@
-/* stylelint-disable no-descending-specificity */
-.normalPage {
- margin: 5rem 2rem;
- box-sizing: content-box;
-
- main {
- width: fit-content;
- display: grid;
- grid-template-columns: repeat(3, 430px);
- margin: 0 auto;
- align-items: start;
- font-family: apple-system, system-ui, sans-serif;
-
- article {
- margin: 0 1.25rem 2.5rem;
- border-radius: 1rem;
- overflow: hidden;
- border: 2px solid transparent;
- transition: all 0.3s ease-in-out;
- // filter: drop-shadow(0 1px 1px rgb(0 0 0 / 10%));
-
- & > a {
- width: 100%;
- height: 100%;
- overflow: hidden;
-
- img {
- object-fit: cover;
- width: 100%;
- max-width: unset;
- // filter: drop-shadow(0 1px 0 rgb(0 0 0 / 4%));
- transform-origin: center center;
- transition: all 0.3s ease-in-out;
- }
- }
-
- & .content {
- padding: 0 1rem 1rem;
-
- header {
- & .tags {
- display: flex;
- justify-content: flex-start;
- overflow: hidden;
- text-overflow: ellipsis;
- margin: 0.8rem 0;
-
- & > a {
- color: var(--ifm-link-color);
- margin-right: 0.5rem;
- text-transform: uppercase;
- font-size: 0.66rem;
-
- &:hover {
- opacity: 0.6;
- }
- }
- }
-
- h2 {
- font-size: 1.375rem;
- line-height: 1.2em;
- color: #222;
- margin-top: 0.8rem;
- margin-bottom: 0.5em;
- transition: all 0.3s ease-in-out;
-
- &:hover {
- opacity: 0.6;
- }
- }
-
- p {
- color: #1d1d1f;
- max-height: #{1.7 * 3}em;
- overflow-y: hidden;
- text-overflow: ellipsis;
- font-weight: 300;
- margin-bottom: 2rem;
- }
- }
-
- & .footer {
- display: flex;
- align-items: center;
- }
-
- & .authors {
- display: flex;
- flex-direction: row-reverse;
-
- & .author {
- width: 32px;
- height: 32px;
- border-radius: 50%;
- margin-left: -1rem;
-
- &:last-child {
- margin-left: 0;
- }
- }
- }
-
- & .divider {
- margin: 0 0.5rem;
- }
- }
-
- &:hover {
- border-color: var(--ifm-color-primary);
- transform: translateY(-20px);
-
- & > a {
- img {
- transform: scale3d(1.05, 1.05, 1);
- }
- }
-
- h2 {
- opacity: 0.6;
- }
-
- & .tags:hover + a > h2 {
- opacity: 1;
- }
- }
- }
- }
-}
-
-.firstPage {
- main {
- grid-template-columns: repeat(2, 645px);
-
- article {
- & > a {
- img {
- width: 100%;
- }
- }
-
- .content {
- padding: 0 1.875rem 1.875rem;
- }
-
- &:first-of-type {
- grid-column: 1 / 3;
- display: flex;
- filter: none;
- margin-top: 0;
- margin-bottom: 5rem;
-
- & > a {
- border-radius: 1rem;
- width: 601px;
- height: auto;
- flex-shrink: 0;
-
- img {
- height: 100%;
- width: 100%;
- }
- }
-
- .content {
- padding: 1rem 2rem;
-
- header {
- &::before {
- content: "LATEST POST";
- font-size: 0.7rem;
- font-weight: 800;
- }
-
- & .tags > a {
- font-size: 0.8rem;
- }
-
- h2 {
- font-size: 2.55rem;
- }
-
- p {
- font-size: 1.2rem;
- }
- }
- }
-
- &:hover {
- border-color: transparent;
- transform: none;
-
- & > a {
- img {
- transform: scale3d(1.2, 1.2, 1) rotate3d(0, 0, 1, -2deg);
- }
- }
- }
- }
- }
- }
-}
diff --git a/blog/src/theme/BlogListPage/index.tsx
b/blog/src/theme/BlogPosts/index.tsx
similarity index 52%
copy from blog/src/theme/BlogListPage/index.tsx
copy to blog/src/theme/BlogPosts/index.tsx
index 728af4c97b0..ae9451d1fbd 100644
--- a/blog/src/theme/BlogListPage/index.tsx
+++ b/blog/src/theme/BlogPosts/index.tsx
@@ -1,17 +1,4 @@
-/**
- * Copyright (c) Facebook, Inc. and its affiliates.
- *
- * This source code is licensed under the MIT license found in the
- * LICENSE file in the root directory of this source tree.
- */
-
-import type { FC } from 'react';
-import React from 'react';
-
-import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
-import BlogLayout from '@theme/BlogLayout';
-import BlogListPaginator from '@theme/BlogListPaginator';
-import type { Props } from '@theme/BlogListPage';
+/* eslint-disable react/require-default-props,
@typescript-eslint/no-explicit-any */
import Link from '@docusaurus/Link';
import type { Props as OldBlogPostItemProps } from '@theme/BlogPostItem';
// eslint-disable-next-line import/no-extraneous-dependencies
@@ -20,6 +7,9 @@ import type { ScrollPosition } from
'react-lazy-load-image-component';
import { trackWindowScroll, LazyLoadImage } from
'react-lazy-load-image-component';
import Avvvatars from 'avvvatars-react';
import clsx from 'clsx';
+import type { FC, HTMLAttributes, DetailedHTMLProps } from 'react';
+import React from 'react';
+import 'react-lazy-load-image-component/src/effects/blur.css';
import style from './style.module.scss';
const components = {
@@ -30,18 +20,37 @@ const components = {
const defaultImg = '/img/default-blog-header.jpg';
-type BlogPostItemProps = OldBlogPostItemProps & {
+interface LazyProps {
scrollPosition: ScrollPosition;
-};
+ delayMethod?: string;
+ delayTime?: number;
+ useIntersectionObserver?: boolean;
+}
-type BlogListPageProps = Props & {
- scrollPosition: ScrollPosition;
-};
+type BlogPostItemProps = OldBlogPostItemProps & LazyProps;
+
+type BlogPostsProps = DetailedHTMLProps<HTMLAttributes<HTMLElement>,
HTMLElement> & {
+ items: any;
+ isFirstPage?: boolean;
+} & LazyProps;
const BlogPostItem: FC<BlogPostItemProps> = (props) => {
const {
- children, frontMatter, assets, metadata, scrollPosition,
+ children,
+ frontMatter,
+ assets,
+ metadata,
+ scrollPosition,
+ delayMethod,
+ delayTime,
+ useIntersectionObserver,
} = props;
+ const delayProps = {
+ scrollPosition,
+ delayMethod,
+ delayTime,
+ useIntersectionObserver,
+ };
const {
date, formattedDate, permalink, tags, title, authors,
} = metadata;
@@ -56,9 +65,24 @@ const BlogPostItem: FC<BlogPostItemProps> = (props) => {
width={605}
src={image}
alt={title}
- effect="opacity"
+ effect="blur"
+ placeholder={(
+ <div>
+ <noscript>
+ <img src={image} alt={title} />
+ </noscript>
+ <div
+ style={{
+ width: 605,
+ height: 232,
+ borderRadius: '1rem',
+ backgroundColor: '#d2d2d7',
+ }}
+ />
+ </div>
+ )}
visibleByDefault={image === defaultImg}
- scrollPosition={scrollPosition}
+ {...delayProps}
/>
</Link>
<div className={style.content}>
@@ -88,7 +112,23 @@ const BlogPostItem: FC<BlogPostItemProps> = (props) => {
src={author.imageURL}
width={32}
height={32}
- scrollPosition={scrollPosition}
+ effect="blur"
+ placeholder={(
+ <div>
+ <noscript>
+ <img src={author.name} alt={author.imageURL} />
+ </noscript>
+ <div
+ style={{
+ width: 32,
+ height: 32,
+ borderRadius: '50%',
+ backgroundColor: '#d2d2d7',
+ }}
+ />
+ </div>
+ )}
+ {...delayProps}
/>
) : (
<div className={style.author} key={author.name}>
@@ -108,49 +148,36 @@ const BlogPostItem: FC<BlogPostItemProps> = (props) => {
);
};
-const BlogListPage: FC<BlogListPageProps> = (props) => {
- const {
- metadata, items, sidebar, scrollPosition,
- } = props;
- const {
- siteConfig: { title: siteTitle },
- } = useDocusaurusContext();
- const { blogDescription, blogTitle, permalink } = metadata;
- const isBlogOnlyMode = permalink === '/';
- const title = isBlogOnlyMode ? siteTitle : blogTitle;
-
- return (
- <BlogLayout
- title={title}
- description={blogDescription}
- wrapperClassName={clsx({
- [style.normalPage]: true,
- [style.firstPage]: !metadata.previousPage,
- })}
- searchMetadatas={{
- // assign unique search tag to exclude this page from search results!
- tag: 'blog_posts_list',
- }}
- sidebar={sidebar}
- toc={false}
- >
- <main itemScope itemType="http://schema.org/Blog">
- {items.map(({ content: BlogPostContent }) => (
- <BlogPostItem
- key={BlogPostContent.metadata.permalink}
- frontMatter={BlogPostContent.frontMatter}
- assets={BlogPostContent.assets}
- metadata={BlogPostContent.metadata}
- truncated={BlogPostContent.metadata.truncated}
- scrollPosition={scrollPosition}
- >
- <BlogPostContent />
- </BlogPostItem>
- ))}
- </main>
- <BlogListPaginator metadata={metadata} />
- </BlogLayout>
- );
-};
+const BlogPosts: FC<BlogPostsProps> = ({
+ items,
+ isFirstPage = false,
+ scrollPosition,
+ delayMethod,
+ delayTime,
+ useIntersectionObserver,
+ ...props
+}) => (
+ <main
+ className={clsx({
+ [style.normalPage]: true,
+ [style.firstPage]: isFirstPage,
+ })}
+ itemScope
+ {...props}
+ >
+ {items.map(({ content: BlogPostContent }) => (
+ <BlogPostItem
+ key={BlogPostContent.metadata.permalink}
+ frontMatter={BlogPostContent.frontMatter}
+ assets={BlogPostContent.assets}
+ metadata={BlogPostContent.metadata}
+ truncated={BlogPostContent.metadata.truncated}
+ {...{ delayMethod, delayTime, useIntersectionObserver }}
+ >
+ <BlogPostContent />
+ </BlogPostItem>
+ ))}
+ </main>
+);
-export default trackWindowScroll(BlogListPage);
+export default trackWindowScroll(BlogPosts);
diff --git a/blog/src/theme/BlogPosts/style.module.scss
b/blog/src/theme/BlogPosts/style.module.scss
new file mode 100644
index 00000000000..5eee636f8fd
--- /dev/null
+++ b/blog/src/theme/BlogPosts/style.module.scss
@@ -0,0 +1,209 @@
+/* stylelint-disable no-descending-specificity */
+@import "../../css/util";
+
+main.normalPage {
+ width: fit-content;
+ display: grid;
+ grid-template-columns: repeat(3, 430px);
+ margin: 5rem auto 0;
+ align-items: start;
+ font-family: apple-system, system-ui, sans-serif;
+
+ article {
+ margin: 0 1.25rem 2.5rem;
+ border-radius: 1rem;
+ overflow: hidden;
+ border: 2px solid transparent;
+ transition: all 0.3s ease-in-out;
+ // filter: drop-shadow(0 1px 1px rgb(0 0 0 / 10%));
+
+ & > a {
+ width: 100%;
+ height: 100%;
+ overflow: hidden;
+
+ img {
+ object-fit: cover;
+ width: 100%;
+ max-width: unset;
+ // filter: drop-shadow(0 1px 0 rgb(0 0 0 / 4%));
+ transform-origin: center center;
+ transition: all 0.3s ease-in-out;
+ }
+ }
+
+ & .content {
+ padding: 0 1rem 1rem;
+
+ header {
+ & .tags {
+ display: flex;
+ justify-content: flex-start;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ margin: 0.8rem 0;
+
+ & > a {
+ color: var(--ifm-link-color);
+ margin-right: 0.5rem;
+ text-transform: uppercase;
+ font-size: 0.66rem;
+
+ &:hover {
+ opacity: 0.6;
+ }
+ }
+ }
+
+ h2 {
+ font-size: 1.375rem;
+ line-height: 1.2em;
+ color: #222;
+ margin-top: 0.8rem;
+ margin-bottom: 0.5em;
+ transition: all 0.3s ease-in-out;
+
+ &:hover {
+ opacity: 0.6;
+ }
+ }
+
+ p {
+ color: #1d1d1f;
+ max-height: #{1.7 * 3}em;
+ overflow-y: hidden;
+ text-overflow: ellipsis;
+ font-weight: 300;
+ margin-bottom: 2rem;
+ }
+ }
+
+ & .footer {
+ display: flex;
+ align-items: center;
+ }
+
+ & .authors {
+ display: flex;
+ flex-direction: row-reverse;
+
+ & .author,
+ & > span {
+ width: 32px;
+ height: 32px;
+ border-radius: 50%;
+ margin-left: -1rem;
+
+ &:last-child {
+ margin-left: 0;
+ }
+ }
+ }
+
+ & .divider {
+ margin: 0 0.5rem;
+ }
+ }
+
+ &:hover {
+ border-color: var(--ifm-color-primary);
+ transform: translateY(-20px);
+
+ & > a {
+ img {
+ transform: scale3d(1.05, 1.05, 1);
+ }
+ }
+
+ h2 {
+ opacity: 0.6;
+ }
+
+ & .tags:hover + a > h2 {
+ opacity: 1;
+ }
+ }
+ }
+}
+
+@include respond-above(sm) {
+ main.firstPage {
+ grid-template-columns: repeat(2, 645px);
+
+ article {
+ & > a {
+ img {
+ width: 100%;
+ }
+ }
+
+ .content {
+ padding: 0 1.875rem 1.875rem;
+ }
+
+ &:first-of-type {
+ grid-column: 1 / 3;
+ display: flex;
+ filter: none;
+ margin-top: 0;
+ margin-bottom: 5rem;
+
+ & > a {
+ border-radius: 1rem;
+ width: 601px;
+ height: auto;
+ flex-shrink: 0;
+
+ img {
+ height: 100%;
+ width: 100%;
+ }
+ }
+
+ .content {
+ padding: 1rem 2rem;
+
+ header {
+ &::before {
+ content: "LATEST POST";
+ font-size: 0.7rem;
+ font-weight: 800;
+ }
+
+ & .tags > a {
+ font-size: 0.8rem;
+ }
+
+ h2 {
+ font-size: 2.55rem;
+ }
+
+ p {
+ font-size: 1.2rem;
+ }
+ }
+ }
+
+ &:hover {
+ border-color: transparent;
+ transform: none;
+
+ & > a {
+ img {
+ transform: scale3d(1.2, 1.2, 1) rotate3d(0, 0, 1, -2deg);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+@include respond-below(sm) {
+ main.normalPage {
+ display: flex;
+ flex-direction: column;
+ width: 100%;
+ margin: 0;
+ }
+}
diff --git a/blog/src/theme/BlogTagsPostsPage/index.tsx
b/blog/src/theme/BlogTagsPostsPage/index.tsx
index 570ccf56bd5..55eb2559612 100644
--- a/blog/src/theme/BlogTagsPostsPage/index.tsx
+++ b/blog/src/theme/BlogTagsPostsPage/index.tsx
@@ -6,28 +6,16 @@
* LICENSE file in the root directory of this source tree.
*/
-import type { FC } from 'react';
import React from 'react';
import BlogLayout from '@theme/BlogLayout';
import BlogListPaginator from '@theme/BlogListPaginator';
import type { Props } from '@theme/BlogTagsPostsPage';
import Link from '@docusaurus/Link';
-import type { Props as BlogPostItemProps } from '@theme/BlogPostItem';
-// eslint-disable-next-line import/no-extraneous-dependencies
-import { MDXProvider } from '@mdx-js/react';
-import { LazyLoadImage } from 'react-lazy-load-image-component';
-import Avvvatars from 'avvvatars-react';
-import clsx from 'clsx';
import Translate, { translate } from '@docusaurus/Translate';
import { usePluralForm } from '@docusaurus/theme-common';
import style from './style.module.scss';
-
-const components = {
- blockquote: ({ children }) => children,
- p: ({ children }) => <p>{children.length > 200 ? `${children.slice(0,
200)}...` : children}</p>,
- a: ({ children }) => children,
-};
+import BlogPosts from '../BlogPosts';
function useBlogPostsPlural() {
const { selectMessage } = usePluralForm();
@@ -45,83 +33,6 @@ function useBlogPostsPlural() {
);
}
-const BlogPostItem: FC<BlogPostItemProps> = (props) => {
- const {
- children,
- frontMatter,
- assets,
- metadata,
- } = props;
- const {
- date,
- formattedDate,
- permalink,
- tags,
- title,
- authors,
- } = metadata;
-
- const image = assets.image ?? frontMatter.image ??
'/img/default-blog-header.jpg';
-
- return (
- <article
- itemProp="blogPost"
- itemScope
- itemType="http://schema.org/BlogPosting"
- >
- <Link itemProp="url" to={permalink} aria-label={`Read more about
${title}`}>
- <LazyLoadImage src={image} alt={title} height={203} width={384} />
- </Link>
- <div className={style.content}>
- <header>
- {tags.length > 0 && (
- <div className={style.tags}>
- {tags.slice(0, 3).map((tag) => (
- <a key={tag.permalink} href={tag.permalink}>
- {tag.label}
- </a>
- ))}
- </div>
- )}
- <Link itemProp="url" to={permalink} aria-label={`Read more about
${title}`}>
- <h2>{title}</h2>
- {children && <MDXProvider
components={components}>{children}</MDXProvider>}
- </Link>
- </header>
- <footer className={style.footer}>
- {authors.length > 0
- && (
- <>
- <div className={style.authors}>
- {authors.reverse().map((author) => (
- author.imageURL
- ? (
- <LazyLoadImage
- className={style.author}
- key={author.name}
- src={author.imageURL}
- />
- )
- : (
- <div className={style.author}>
- <Avvvatars
- key={author.name}
- value={author.name as string}
- />
- </div>
- )
- ))}
- </div>
- <div className={style.divider}>•</div>
- </>
- )}
- <time dateTime={date} itemProp="datePublished">{formattedDate}</time>
- </footer>
- </div>
- </article>
- );
-};
-
const BlogTagsPostsPage = (props: Props): JSX.Element => {
const { metadata, items, sidebar } = props;
const { allTagsPath, name: tagName, count } = metadata;
@@ -138,9 +49,6 @@ const BlogTagsPostsPage = (props: Props): JSX.Element => {
return (
<BlogLayout
title={title}
- wrapperClassName={clsx({
- [style.normalPage]: true, [style.firstPage]: !metadata.previousPage,
- })}
searchMetadatas={{
// assign unique search tag to exclude this page from search results!
tag: 'blog_tags_posts',
@@ -159,21 +67,7 @@ const BlogTagsPostsPage = (props: Props): JSX.Element => {
</Translate>
</Link>
</header>
- <main
- itemScope
- >
- {items.map(({ content: BlogPostContent }) => (
- <BlogPostItem
- key={BlogPostContent.metadata.permalink}
- frontMatter={BlogPostContent.frontMatter}
- assets={BlogPostContent.assets}
- metadata={BlogPostContent.metadata}
- truncated={BlogPostContent.metadata.truncated}
- >
- <BlogPostContent />
- </BlogPostItem>
- ))}
- </main>
+ <BlogPosts items={items} />
<BlogListPaginator metadata={metadata} />
</BlogLayout>
);
diff --git a/blog/src/theme/BlogTagsPostsPage/style.module.scss
b/blog/src/theme/BlogTagsPostsPage/style.module.scss
index 07114a969b6..be7544dbd05 100644
--- a/blog/src/theme/BlogTagsPostsPage/style.module.scss
+++ b/blog/src/theme/BlogTagsPostsPage/style.module.scss
@@ -1,130 +1,4 @@
-/* stylelint-disable no-descending-specificity */
.header {
text-align: center;
margin-bottom: 4rem;
}
-
-.normalPage {
- margin: 5rem 2rem;
- box-sizing: content-box;
-
- main {
- width: fit-content;
- display: grid;
- grid-template-columns: repeat(3, 430px);
- margin: 0 auto;
- align-items: start;
- font-family: apple-system, system-ui, sans-serif;
-
- article {
- margin: 0 1.25rem 2.5rem;
- border-radius: 1rem;
- overflow: hidden;
- background-color: #fffffd;
- filter: drop-shadow(0 1px 1px rgb(0 0 0 / 10%));
-
- & > a {
- width: 100%;
- height: 100%;
- overflow: hidden;
-
- img {
- object-fit: cover;
- width: 100%;
- max-width: unset;
- filter: drop-shadow(0 1px 0 rgb(0 0 0 / 4%));
- transform-origin: center center;
- transition: all 0.3s ease-in-out;
- }
- }
-
- & .content {
- padding: 0 1rem 1rem;
-
- header {
- & .tags {
- display: flex;
- justify-content: flex-start;
- overflow: hidden;
- text-overflow: ellipsis;
- margin: 0.8rem 0;
-
- & > a {
- color: var(--ifm-link-color);
- margin-right: 0.5rem;
- text-transform: uppercase;
- font-size: 0.66rem;
-
- &:hover {
- opacity: 0.6;
- }
- }
- }
-
- h2 {
- font-size: 1.375rem;
- line-height: 1.2em;
- color: #222;
- margin-top: 0.8rem;
- margin-bottom: 0.5em;
- transition: all 0.3s ease-in-out;
-
- &:hover {
- opacity: 0.6;
- }
- }
-
- p {
- color: #999;
- max-height: #{1.7 * 3}em;
- overflow-y: hidden;
- text-overflow: ellipsis;
- font-weight: 300;
- margin-bottom: 2rem;
- }
- }
-
- & .footer {
- display: flex;
- align-items: center;
- }
-
- & .authors {
- display: flex;
- flex-direction: row-reverse;
-
- & .author {
- width: 32px;
- height: 32px;
- border-radius: 50%;
- margin-left: -1rem;
-
- &:last-child {
- margin-left: 0;
- }
- }
- }
-
- & .divider {
- margin: 0 0.5rem;
- }
- }
-
- &:hover {
- & > a {
- img {
- transform: scale3d(1.05, 1.05, 1);
- }
- }
-
- h2 {
- opacity: 0.6;
- }
-
- & .tags:hover + a > h2 {
- opacity: 1;
- }
- }
- }
- }
-}
diff --git a/website/src/components/EventPosterCard.tsx
b/website/src/components/EventPosterCard.tsx
index 331d859a958..eb68cbb61b9 100644
--- a/website/src/components/EventPosterCard.tsx
+++ b/website/src/components/EventPosterCard.tsx
@@ -1,11 +1,10 @@
import type { FC } from 'react';
-import React, {
- useCallback, useMemo, useEffect,
-} from 'react';
+import React, { useCallback, useMemo, useEffect } from 'react';
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
import { LazyLoadImage } from 'react-lazy-load-image-component';
import { useSpring, animated } from 'react-spring';
import useSessionStorage from 'react-use/lib/useSessionStorage';
+// eslint-disable-next-line import/no-unresolved, import/extensions
import config from '../../../config/event-poster-card.json';
import style from '../css/event-poster-card.module.scss';
@@ -19,10 +18,15 @@ interface EventPosterCardInfo {
const SHOW_STORE_KEY = 'SHOW_EVENT_ENTRY';
-const EventPosterCard:FC<Omit<EventPosterCardInfo, 'show' | 'expire'>> =
(props) => {
+const EventPosterCard: FC<Omit<EventPosterCardInfo, 'show' | 'expire'>> =
(props) => {
const { image, links, width } = props;
- const { i18n: { currentLocale } } = useDocusaurusContext();
- const link = useMemo(() => (typeof links === 'string' ? links :
links[currentLocale]), [currentLocale]);
+ const {
+ i18n: { currentLocale },
+ } = useDocusaurusContext();
+ const link = useMemo(
+ () => (typeof links === 'string' ? links : links[currentLocale]),
+ [currentLocale]
+ );
const [, setStoreShow] = useSessionStorage(SHOW_STORE_KEY, 'true');
const [styles, api] = useSpring(() => ({
@@ -43,29 +47,30 @@ const EventPosterCard:FC<Omit<EventPosterCardInfo, 'show' |
'expire'>> = (props)
}, []);
const onClose = useCallback(
- async () => Promise.all(api.start({
- to: {
- x: 500,
- opacity: 0,
- },
- }))
- .then(() => setStoreShow('false')),
- [api],
+ async () =>
+ Promise.all(
+ api.start({
+ to: {
+ x: 500,
+ opacity: 0,
+ },
+ })
+ ).then(() => setStoreShow('false')),
+ [api]
);
return (
<animated.div className={style.picWrapper} style={styles}>
<button className={style.closeBtn} onClick={onClose} type="button">
- <svg
- role="img"
- xmlns="http://www.w3.org/2000/svg"
- viewBox="0 0 352 512"
- >
- <path fill="currentColor" d="M242.72 256l100.07-100.07c12.28-12.28
12.28-32.19 0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28
75.93 89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28
32.19 0 44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24
22.24c12.28 12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2
12.28 44.48 0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z" />
+ <svg role="img" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 352
512">
+ <path
+ fill="currentColor"
+ d="M242.72 256l100.07-100.07c12.28-12.28 12.28-32.19
0-44.48l-22.24-22.24c-12.28-12.28-32.19-12.28-44.48 0L176 189.28 75.93
89.21c-12.28-12.28-32.19-12.28-44.48 0L9.21 111.45c-12.28 12.28-12.28 32.19 0
44.48L109.28 256 9.21 356.07c-12.28 12.28-12.28 32.19 0 44.48l22.24 22.24c12.28
12.28 32.2 12.28 44.48 0L176 322.72l100.07 100.07c12.28 12.28 32.2 12.28 44.48
0l22.24-22.24c12.28-12.28 12.28-32.19 0-44.48L242.72 256z"
+ />
</svg>
</button>
<a href={link} onClick={onClose} target="_blank" rel="noreferrer">
- <LazyLoadImage src={image} alt={link} width={width} />
+ <LazyLoadImage src={image} alt={link} width={width} style={{ maxWidth:
'100vw' }} />
</a>
</animated.div>
);
@@ -76,7 +81,7 @@ const EventPosterCardWrapper: FC = () => {
const { show, expire, ...rest } = config;
const expireTimestamp = new Date(expire).getTime();
- if (show && !storeShow && (expireTimestamp > Date.now())) {
+ if (show && !storeShow && expireTimestamp > Date.now()) {
return <EventPosterCard {...rest} />;
}
diff --git a/website/src/css/event-poster-card.module.scss
b/website/src/css/event-poster-card.module.scss
index 492e85daf20..07bbcff1c87 100644
--- a/website/src/css/event-poster-card.module.scss
+++ b/website/src/css/event-poster-card.module.scss
@@ -1,3 +1,5 @@
+@import "./util";
+
.picWrapper {
position: fixed;
display: flex;
@@ -9,6 +11,11 @@
border: 0;
box-shadow: 0 0 20px -12px #626365;
+ @include respond-below(sm) {
+ right: 0;
+ bottom: 0;
+ }
+
& > a {
display: flex;
}