feat(shared): Let images break out to fill the screen on mobile
This commit is contained in:
parent
8174b40972
commit
5888ccfbc7
9 changed files with 46 additions and 37 deletions
|
@ -39,13 +39,13 @@ const MdxPage = props => {
|
||||||
<meta property="og:locale" content="en_US" key='locale' />
|
<meta property="og:locale" content="en_US" key='locale' />
|
||||||
<meta property="og:site_name" content="freesewing.dev" key='site' />
|
<meta property="og:site_name" content="freesewing.dev" key='site' />
|
||||||
</Head>
|
</Head>
|
||||||
<div className="flex flex-row-reverse flex-wrap xl:flex-nowrap justify-end px-8 xl:px-0">
|
<div className="flex flex-row-reverse flex-wrap xl:flex-nowrap justify-end">
|
||||||
{props.toc && (
|
{props.toc && (
|
||||||
<div className="mb-8 px-0 w-full xl:w-80 2xl:w-96 xl:pl-8 2xl:pl-16">
|
<div className="mb-8 w-full xl:w-80 2xl:w-96 xl:pl-8 2xl:pl-16">
|
||||||
<TocWrapper toc={props.toc} app={app}/>
|
<TocWrapper toc={props.toc} app={app}/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="px-0 xl:pl-8 2xl:pl-16">
|
<div className="xl:pl-8 2xl:pl-16">
|
||||||
<MdxWrapper mdx={props.mdx} app={app} components={components} />
|
<MdxWrapper mdx={props.mdx} app={app} components={components} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -5,7 +5,8 @@ import MdxWrapper from 'shared/components/wrappers/mdx'
|
||||||
import mdxCompiler from 'shared/mdx/compiler'
|
import mdxCompiler from 'shared/mdx/compiler'
|
||||||
import Markdown from 'react-markdown'
|
import Markdown from 'react-markdown'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import Modal from 'shared/components/modal.js'
|
import Lightbox from 'shared/components/lightbox.js'
|
||||||
|
import ImageWrapper from 'shared/components/wrappers/img.js'
|
||||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||||
import { strapiHost } from 'shared/config/freesewing.mjs'
|
import { strapiHost } from 'shared/config/freesewing.mjs'
|
||||||
import { strapiImage } from 'shared/utils.js'
|
import { strapiImage } from 'shared/utils.js'
|
||||||
|
@ -82,17 +83,19 @@ const PostPage = ({ post, author }) => {
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<figure>
|
<figure>
|
||||||
<Modal>
|
<Lightbox>
|
||||||
|
<ImageWrapper>
|
||||||
<img
|
<img
|
||||||
src={`${strapiHost}${post.image.url}`}
|
src={`${strapiHost}${post.image.url}`}
|
||||||
alt={post.caption}
|
alt={post.caption}
|
||||||
className="shadow m-auto"
|
className="shadow m-auto"
|
||||||
/>
|
/>
|
||||||
|
</ImageWrapper>
|
||||||
<figcaption
|
<figcaption
|
||||||
className="text-center mb-8 prose m-auto mt-1"
|
className="text-center mb-8 prose m-auto mt-1"
|
||||||
dangerouslySetInnerHTML={{__html: post.caption}}
|
dangerouslySetInnerHTML={{__html: post.caption}}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Lightbox>
|
||||||
</figure>
|
</figure>
|
||||||
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
||||||
<MdxWrapper mdx={post.mdx} app={app} />
|
<MdxWrapper mdx={post.mdx} app={app} />
|
||||||
|
|
|
@ -62,7 +62,7 @@ const BlogIndexPage = (props) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Page app={app} title={t('blog')} slug='blog'>
|
<Page app={app} title={t('blog')} slug='blog'>
|
||||||
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2 px-8 max-w-7xl">
|
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2 max-w-7xl">
|
||||||
{props.posts.map(post => <Preview app={app} post={post} key={post.slug}/>)
|
{props.posts.map(post => <Preview app={app} post={post} key={post.slug}/>)
|
||||||
}
|
}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@ import mdxCompiler from 'shared/mdx/compiler'
|
||||||
import Markdown from 'react-markdown'
|
import Markdown from 'react-markdown'
|
||||||
import Head from 'next/head'
|
import Head from 'next/head'
|
||||||
import PageLink from 'shared/components/page-link.js'
|
import PageLink from 'shared/components/page-link.js'
|
||||||
import Modal from 'shared/components/modal.js'
|
import Lightbox from 'shared/components/lightbox.js'
|
||||||
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
|
||||||
import { strapiHost } from 'shared/config/freesewing.mjs'
|
import { strapiHost } from 'shared/config/freesewing.mjs'
|
||||||
import { strapiImage } from 'shared/utils.js'
|
import { strapiImage } from 'shared/utils.js'
|
||||||
|
@ -82,7 +82,7 @@ const PostPage = ({ post, maker }) => {
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<figure>
|
<figure>
|
||||||
<Modal>
|
<Lightbox>
|
||||||
<img
|
<img
|
||||||
src={`${strapiHost}${post.image.url}`}
|
src={`${strapiHost}${post.image.url}`}
|
||||||
alt={post.caption}
|
alt={post.caption}
|
||||||
|
@ -92,7 +92,7 @@ const PostPage = ({ post, maker }) => {
|
||||||
className="text-center mb-8 prose m-auto"
|
className="text-center mb-8 prose m-auto"
|
||||||
dangerouslySetInnerHTML={{__html: post.caption}}
|
dangerouslySetInnerHTML={{__html: post.caption}}
|
||||||
/>
|
/>
|
||||||
</Modal>
|
</Lightbox>
|
||||||
</figure>
|
</figure>
|
||||||
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
<div className="strapi prose lg:prose-lg mb-12 m-auto">
|
||||||
<MdxWrapper mdx={post.mdx} app={app} />
|
<MdxWrapper mdx={post.mdx} app={app} />
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import Logo from 'shared/components/logos/freesewing.js'
|
import FreeSewingIcon from 'shared/components/icons/freesewing.js'
|
||||||
|
|
||||||
const Breadcrumbs = ({ crumbs=[], title }) => (
|
const Breadcrumbs = ({ crumbs=[], title }) => (
|
||||||
<ul className="flex flex-row flex-wrap gap-2 font-bold">
|
<ul className="flex flex-row flex-wrap gap-2 font-bold">
|
||||||
<li>
|
<li>
|
||||||
<Link href="/">
|
<Link href="/">
|
||||||
<a title="FreeSewing" className="text-base-content">
|
<a title="FreeSewing" className="text-base-content">
|
||||||
<Logo size={24} fill="currentColor" stroke={false}/>
|
<FreeSewingIcon />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</li>
|
</li>
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
import { useState } from 'react'
|
import { useState } from 'react'
|
||||||
|
|
||||||
const Modal = ({ cancel, children }) => {
|
const Lightbox = ({ cancel, children }) => {
|
||||||
|
|
||||||
const [ modal, setModal ] = useState(false)
|
const [ box, setBox ] = useState(false)
|
||||||
|
|
||||||
if (modal) return (
|
if (box) return (
|
||||||
<div className={`
|
<div className={`
|
||||||
fixed top-0 left-0 right-0 w-screen h-screen
|
fixed top-0 left-0 right-0 w-screen h-screen
|
||||||
bg-neutral bg-opacity-90 z-30
|
bg-neutral bg-opacity-90 z-30
|
||||||
hover:cursor-zoom-out flex flex-col justify-center
|
hover:cursor-zoom-out flex flex-col justify-center
|
||||||
`} onClick={() => setModal(false)}>
|
`} onClick={() => setBox(false)}>
|
||||||
<div className="m-auto text-neutral-content lightbox" style={{
|
<div className="m-auto text-neutral-content lightbox" style={{
|
||||||
maxHeight: "calc(100vh - 6rem)",
|
maxHeight: "calc(100vh - 6rem)",
|
||||||
maxWidth: "calc(100vw - 6rem)",
|
maxWidth: "calc(100vw - 6rem)",
|
||||||
|
@ -21,10 +21,10 @@ const Modal = ({ cancel, children }) => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
onClick={() => setModal(!modal)}
|
onClick={() => setBox(!box)}
|
||||||
className="hover:cursor-zoom-in"
|
className="hover:cursor-zoom-in"
|
||||||
>{children}</div>
|
>{children}</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Modal
|
export default Lightbox
|
|
@ -1,5 +1,6 @@
|
||||||
import Popout from 'shared/components/popout'
|
import Popout from 'shared/components/popout'
|
||||||
import Modal from 'shared/components/modal'
|
import Lightbox from 'shared/components/lightbox'
|
||||||
|
import ImageWrapper from 'shared/components/wrappers/img.js'
|
||||||
|
|
||||||
const Figure = props => {
|
const Figure = props => {
|
||||||
|
|
||||||
|
@ -11,17 +12,15 @@ const Figure = props => {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<figure className="block my-4">
|
<figure className="block my-4">
|
||||||
<Modal>
|
<Lightbox>
|
||||||
|
<ImageWrapper>
|
||||||
<img
|
<img
|
||||||
src={props?.src}
|
src={props?.src}
|
||||||
alt={props?.alt || ''}
|
alt={props?.alt || ''}
|
||||||
title={title || ''}
|
title={title || ''}
|
||||||
className="m-auto"
|
className="m-auto"
|
||||||
style={{
|
|
||||||
maxHeight: "calc(100vh - 6rem)",
|
|
||||||
maxWidth: "calc(100vw - 6rem)",
|
|
||||||
}}
|
|
||||||
/>
|
/>
|
||||||
|
</ImageWrapper>
|
||||||
{title
|
{title
|
||||||
? <figcaption className="text-center italic mt-1">{title}</figcaption>
|
? <figcaption className="text-center italic mt-1">{title}</figcaption>
|
||||||
: (
|
: (
|
||||||
|
@ -31,7 +30,7 @@ const Figure = props => {
|
||||||
</Popout>
|
</Popout>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
</Modal>
|
</Lightbox>
|
||||||
</figure>
|
</figure>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
7
packages/freesewing.shared/components/wrappers/img.js
Normal file
7
packages/freesewing.shared/components/wrappers/img.js
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
/* Breaks image out of its parent container to fill the screen on mobile */
|
||||||
|
const ImageWrapper = ({ children }) => (
|
||||||
|
<div className="-ml-8 -mr-8 sm:m-0">{children}</div>
|
||||||
|
)
|
||||||
|
|
||||||
|
export default ImageWrapper
|
||||||
|
|
|
@ -235,7 +235,7 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* modal */
|
/* Lightbox */
|
||||||
.lightbox img {
|
.lightbox img {
|
||||||
max-width: calc(100vw - 6rem);
|
max-width: calc(100vw - 6rem);
|
||||||
max-height: calc(100vh - 6rem);
|
max-height: calc(100vh - 6rem);
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue