From a55d47433628644c6b3c798526b2e9250834efc0 Mon Sep 17 00:00:00 2001 From: Roman Timashev Date: Tue, 21 Sep 2021 16:07:30 +0300 Subject: [PATCH] add Picture component for displaying images in articles with h/v/s layout support --- pages/[...slug].tsx | 20 ++++---- pages/_app.tsx | 1 - src/components/Image/index.tsx | 36 -------------- src/components/Image/styles.module.css | 12 ----- src/components/Picture/index.tsx | 48 +++++++++++++++++++ .../Picture/picture.module.css} | 17 +++---- src/types.ts | 16 ++++--- 7 files changed, 75 insertions(+), 75 deletions(-) delete mode 100644 src/components/Image/index.tsx delete mode 100644 src/components/Image/styles.module.css create mode 100644 src/components/Picture/index.tsx rename src/{style/kazimir/image.css => components/Picture/picture.module.css} (68%) diff --git a/pages/[...slug].tsx b/pages/[...slug].tsx index e7aadce1..1ecf08cd 100644 --- a/pages/[...slug].tsx +++ b/pages/[...slug].tsx @@ -1,5 +1,4 @@ import Head from 'next/head' -import Image from 'next/image' import { App } from 'src/components/App' import { tail } from 'lodash' import { Page } from 'src/components/Page' @@ -16,6 +15,7 @@ import { paramsToSlug } from '@/remote/lib' import { PageGrid } from '@/components/PageGrid' import { useRouter } from 'next/router' import { FileCard } from '@/components/FIleCard' +import { Picture } from '@/components/Picture' async function getUrls() { let urls = [] @@ -114,16 +114,14 @@ const Index: NextPage = props => { case 'image': return ( -
- {x.data.alt} -
{x.data.caption}
-
+ ) case 'file': diff --git a/pages/_app.tsx b/pages/_app.tsx index 27d68dbd..a3e65971 100644 --- a/pages/_app.tsx +++ b/pages/_app.tsx @@ -4,7 +4,6 @@ import 'src/style/style.css' import 'src/style/content.css' import 'src/style/article.css' import 'src/style/marker/marker-table.css' -import 'src/style/kazimir/image.css' import 'src/style/kazimir/video.css' import App from 'next/app' diff --git a/src/components/Image/index.tsx b/src/components/Image/index.tsx deleted file mode 100644 index 351918af..00000000 --- a/src/components/Image/index.tsx +++ /dev/null @@ -1,36 +0,0 @@ -import s from './styles.module.css' - -import { memo, useRef, useEffect, useCallback } from 'react' - -export type ImageProps = { - style?: React.CSSProperties - src: string - alt?: string - srcSet?: string -} - -export const Image: React.FC = memo(props => { - const ref = useRef() - const onLoad = useCallback((event) => { - event.target.classList.add('loaded') - event.target.classList.remove('pending') - }, []) - - useEffect(() => { - if (ref.current) { - ref.current.classList.add('pending') - } - }) - - return ( - {props.alt} - ) -}) diff --git a/src/components/Image/styles.module.css b/src/components/Image/styles.module.css deleted file mode 100644 index 85db39af..00000000 --- a/src/components/Image/styles.module.css +++ /dev/null @@ -1,12 +0,0 @@ -.image { - width: 100%; - display: block; -} - -.image.pending { - /* opacity: 0; */ -} - -.image.loaded { - /* opacity: 1; */ -} diff --git a/src/components/Picture/index.tsx b/src/components/Picture/index.tsx new file mode 100644 index 00000000..0ae4bc11 --- /dev/null +++ b/src/components/Picture/index.tsx @@ -0,0 +1,48 @@ +import s from './picture.module.css' + +import { memo } from 'react' +import Image from 'next/image' +import { Pic } from '@/types' + +const modifiers = new Map([ + ['square', s.square], + ['vertical', s.vertical], + ['horizontal', ''], +]) + +function size(w: number, h: number, tolerance: number) { + const r = w / h + if (r < 1 && r > tolerance) { + return 'square' + } + + if (w < h) { + return 'vertical' + } + + return 'horizontal' +} + +export type PictureProps = Pic & { + style?: React.CSSProperties +} + +export const Picture: React.FC = memo(props => { + const ss = size(props.width, props.height, 0.95) + const layout = modifiers.get(ss) + + return ( +
+ {props.alt} + {!props.caption ? null : ( +
{props.caption} ({props.width}x{props.height})
+ )} +
+ ) +}) diff --git a/src/style/kazimir/image.css b/src/components/Picture/picture.module.css similarity index 68% rename from src/style/kazimir/image.css rename to src/components/Picture/picture.module.css index 35638b54..cd791059 100644 --- a/src/style/kazimir/image.css +++ b/src/components/Picture/picture.module.css @@ -1,22 +1,23 @@ -.kazimir__image { +.pic { /* position: relative; */ /* width: calc(100% + var(--kazimir-image-increase)); */ /* margin-left: calc(-0.5 * var(--kazimir-image-increase)); */ margin-bottom: var(--size-xl); } -.kazimir__image p { - margin-left: calc(0.5 * var(--kazimir-image-increase)); +.pic.vertical { + max-width: 60%; } -.kazimir__image img { +.pic.square { + max-width: 80%; +} + +.pic img { border-radius: var(--radius); - - max-width: 100%; - max-height: 35em; } -.kazimir__image figcaption { +.pic figcaption { color: var(--color-text); font-size: var(--font-size-second); font-style: italic; diff --git a/src/types.ts b/src/types.ts index cb1082c4..8a43c7d3 100644 --- a/src/types.ts +++ b/src/types.ts @@ -98,6 +98,14 @@ export type ImageDefinition = { alt?: string } +export type Pic = { + src: string + alt?: string + width: number + height: number + caption?: string +} + export type TextToken = { token: 'text' data: string @@ -105,13 +113,7 @@ export type TextToken = { export type ImageToken = { token: 'image' - data: { - src: string - alt: string - caption: string - width: number - height: number - } + data: Pic } export type FileTokenData = {