From 2ef80ccaa64013e93ae7317f51e3396cee914bca Mon Sep 17 00:00:00 2001 From: Sasha Chabin Date: Sun, 25 Aug 2024 18:29:41 +0500 Subject: [PATCH] Show sidebar in Articles (#112) * Update list styles * Add feedback button to Modal * Update modal x-margins * Set aside prop as optional * Show sidebar in modal --- client/api/articles/articles.types.ts | 1 + .../Articles/Article/Article.module.css | 120 +++++++++---- .../components/Articles/Article/Article.tsx | 32 ++-- .../Articles/Article/Article.types.tsx | 1 + .../Common/Feedback/Feedback.module.css | 12 +- .../components/Common/Feedback/Feedback.tsx | 11 +- client/components/MainPage/MainPage.tsx | 1 + client/components/UI/Modal/Modal.module.css | 157 ++++++++++++------ client/components/UI/Modal/Modal.tsx | 15 +- client/pages/[slug].tsx | 11 +- client/pages/map.tsx | 7 +- 11 files changed, 248 insertions(+), 120 deletions(-) diff --git a/client/api/articles/articles.types.ts b/client/api/articles/articles.types.ts index 078c2157..a2b4c1eb 100644 --- a/client/api/articles/articles.types.ts +++ b/client/api/articles/articles.types.ts @@ -3,6 +3,7 @@ export interface Article { attributes: { title: string; description: string; + sidebar: string; createdAt: Date; updatedAt: Date; publishedAt: Date; diff --git a/client/components/Articles/Article/Article.module.css b/client/components/Articles/Article/Article.module.css index 8aba8117..b3e58f4a 100644 --- a/client/components/Articles/Article/Article.module.css +++ b/client/components/Articles/Article/Article.module.css @@ -1,37 +1,40 @@ .Article { - color: #0C1B27; - max-width: 1000px; + max-width: 1280px; margin: 0 auto; - padding: 32px 24px 40px; - font-size: 20px; + padding: 24px; + color: #0C1B27; font-weight: 300; + font-size: 20px; line-height: 1.3; } .Article_external { - padding: 0; + padding-right: 0; + padding-bottom: 0; + padding-left: 0; } .ArticleBack { display: inline-flex; - align-items: center; gap: .5em; - white-space: nowrap; + align-items: center; + margin-bottom: 40px; + color: #0C1B27; font-size: 32px; line-height: 1; text-decoration: none; + white-space: nowrap; text-decoration-skip-ink: none; - color: #0C1B27; } .ArticleBackArrow { display: flex; - align-items: center; justify-content: center; + align-items: center; width: 1.25em; height: 1.25em; - background: rgba(12, 27, 39, 0.07); border-radius: 50%; + background: rgba(12, 27, 39, 0.07); transition: .1s ease; } @@ -44,46 +47,55 @@ } .ArticleTitle { - font-size: 24px; + margin-top: -0.05em; + margin-bottom: 1em; font-weight: 500; + font-size: 24px; line-height: 1.12; } +.Article_external .ArticleContent { + padding-bottom: 0; +} .ArticleContent a:hover { text-decoration: none; } .ArticleContent h2 { - font-size: 22px; - font-weight: 500; - line-height: 1.16; margin-top: 1.4em; margin-bottom: .3em; + font-weight: 500; + font-size: 22px; + line-height: 1.16; } .ArticleContent h3 { - font-size: 18px; - font-weight: 500; - line-height: 1.25; margin-top: 1.9em; margin-bottom: .8em; + font-weight: 500; + font-size: 18px; + line-height: 1.25; } .ArticleContent h4 { - font-size: 14px; - font-weight: 500; - line-height: 1.25; margin-top: 1.75em; margin-bottom: .25em; + font-weight: 500; + font-size: 14px; + line-height: 1.25; } .ArticleContent ol, .ArticleContent ul, .ArticleContent p { + margin-bottom: 1.1em; font-size: 14px; line-height: 1.4; - margin-bottom: 1.1em; + + &:first-child { + margin-top: 0; + } } .ArticleContent li { @@ -95,25 +107,30 @@ color: #667999; } +.ArticleContent ol { + padding-left: 1em; +} + .ArticleContent ul { + padding-left: 1.5em; list-style-type: none; } .ArticleContent ul li:before { content: "—"; display: inline-block; - padding-right: .5em; margin-left: -1.5em; + padding-right: .5em; opacity: .45; } .ArticleContent blockquote { - font-size: 22px; - line-height: 1.35; + margin: 8px 0; padding: 16px; border-radius: 16px; background: #F4F6FB; - margin: 8px 0; + font-size: 22px; + line-height: 1.35; } .ArticleContent blockquote p { @@ -125,18 +142,39 @@ font-weight: 500; } +.ArticleAside { + flex-shrink: 0; + flex-basis: 25%; + margin-top: 56px; + padding: 24px 0; + border-top: 2px solid #eee; +} + +.ArticleText { + flex-grow: 1; +} + +.ArticleAsideFeedback { + display: none; + text-align: right; +} + @media screen and (min-width: 768px) { .Article { - padding-top: 64px; - padding-bottom: 80px; + padding: 32px; + } + + .ArticleTitle { + font-size: 64px; } - .Article_external { - padding: 0; + .ArticleBack { + margin-bottom: 64px; } - .ArticleTitle { - font-size: 64px; + .ArticleContent { + gap: 32px; + padding-bottom: 80px; } .ArticleContent h2 { @@ -161,4 +199,22 @@ margin: 16px 0; padding: 24px; } -} \ No newline at end of file +} + +@media screen and (min-width: 1200px) { + .ArticleContent { + display: flex; + gap: 16px; + } + + + .ArticleAside { + margin: 0; + padding: 0; + border: 0; + } + + .ArticleAsideFeedback { + display: block; + } +} diff --git a/client/components/Articles/Article/Article.tsx b/client/components/Articles/Article/Article.tsx index abf6338b..ee2cb0d0 100644 --- a/client/components/Articles/Article/Article.tsx +++ b/client/components/Articles/Article/Article.tsx @@ -6,25 +6,33 @@ import Link from 'next/link'; import styles from './Article.module.css'; import t from 'utils/typograph'; +import { Feedback } from 'components/Common/Feedback/Feedback'; const cn = classNames.bind(styles); -export function Article({ title, description, external }: ArticleProps) { +function getContent(html) { + return t(md({ html: true }).render(html)); +} + +export function Article({ title, description, sidebar, external }: ArticleProps) { return ( -
+
{!external && Назад } - - {title &&

- {title} -

} - - {description &&
} -
+
+
+ {title &&

{title}

} + {description &&
} +
+ {sidebar && } +
+ ) } diff --git a/client/components/Articles/Article/Article.types.tsx b/client/components/Articles/Article/Article.types.tsx index 1ed9d4c5..81c1cb5a 100644 --- a/client/components/Articles/Article/Article.types.tsx +++ b/client/components/Articles/Article/Article.types.tsx @@ -1,5 +1,6 @@ export type ArticleProps = { title?: string; description: string; + sidebar?: string; external?: boolean }; diff --git a/client/components/Common/Feedback/Feedback.module.css b/client/components/Common/Feedback/Feedback.module.css index 3b5cb857..c5972eb6 100644 --- a/client/components/Common/Feedback/Feedback.module.css +++ b/client/components/Common/Feedback/Feedback.module.css @@ -1,5 +1,5 @@ -.MapFeedback { - display: flex; +.Feedback { + display: inline-flex; justify-content: center; align-items: center; border-radius: 64px; @@ -12,18 +12,18 @@ } /* leaflet styles for links have more specificity */ -.MapFeedback.MapFeedback { +.Feedback.Feedback { color: var(--text-primary); } -.MapFeedback_Size-m, -.MapFeedback_Size-l { +.Feedback_Size-m, +.Feedback_Size-l { height: 48px; padding: 8px 24px; } @media screen and (min-width: 768px) { - .MapFeedback_Size-l { + .Feedback_Size-l { height: 65px; padding: 24px 32px; font-size: 24px; diff --git a/client/components/Common/Feedback/Feedback.tsx b/client/components/Common/Feedback/Feedback.tsx index cca30431..2d3b8be1 100644 --- a/client/components/Common/Feedback/Feedback.tsx +++ b/client/components/Common/Feedback/Feedback.tsx @@ -7,20 +7,15 @@ import styles from './Feedback.module.css'; const cn = classNames.bind(styles); -export function Feedback({ - caption = 'Фидбек', - size -} : FeedbackProps) { +export function Feedback({ size } : FeedbackProps) { return ( - {caption} + Фидбек ); } diff --git a/client/components/MainPage/MainPage.tsx b/client/components/MainPage/MainPage.tsx index 2a592e71..595fcc5e 100644 --- a/client/components/MainPage/MainPage.tsx +++ b/client/components/MainPage/MainPage.tsx @@ -142,6 +142,7 @@ export function MainPage({ cards, cardsDynamicData, marqueeItems, articles }: Ma
diff --git a/client/components/UI/Modal/Modal.module.css b/client/components/UI/Modal/Modal.module.css index 3de264a8..19d68c2f 100644 --- a/client/components/UI/Modal/Modal.module.css +++ b/client/components/UI/Modal/Modal.module.css @@ -1,49 +1,63 @@ +html:has(.Modal) { + scrollbar-color: transparent transparent; +} + .Modal { - margin: auto 16px; + display: flex; + flex-direction: column; + overflow: visible; + width: calc(100% - 32px); + max-width: none; + margin: auto; + max-height: none; padding: 0; border: 0; - border-radius: 16px; - width: 100%; + background: transparent; animation: .2s ease-in-out fadeIn; } +.Modal_Align-top { + margin-top: 16px; +} + +.Modal_Align-center { + margin-top: auto; + margin-bottom: auto; +} + .Modal::backdrop { - background: rgba(12, 27, 39, .2); + background: rgba(12, 27, 39, .3); } .ModalTitle { - font-size: 24px; margin: 0; - padding: 32px 24px 8px; + padding: 24px 48px 0 24px; + font-size: 24px; } -.ModalContent { - padding: 16px 24px 24px; +.ModalInner { + overflow: auto; + height: 100%; + border-radius: 8px; + background: white; + scrollbar-color: transparent transparent; } -.ModalClose { - position: sticky; - top: 0; - float: right; - background: none; - border: 0; - padding: 24px; - color: rgba(0, 0, 0, 0.5); - cursor: pointer; - transition: .15s ease; - border-radius: 50%; +.ModalInner:hover { + scrollbar-color: #7d828a transparent; } -@media (hover) { - .ModalClose:hover { - background-color: rgba(255, 255, 255, 0.8); - color: rgba(0, 0, 0, 0.75); - } +.ModalContent { + padding: 0px 24px 8px; } -.ModalClose:active { - background-color: rgba(255, 255, 255, 0.95); - color: rgba(0, 0, 0, 1); +.ModalClose { + position: absolute; + top: 0; + right: 0; + padding: 16px; + border: 0; + background: none; } .ModalClose svg { @@ -53,42 +67,91 @@ @media screen and (min-width: 768px) { .Modal { - width: 100%; - max-width: 1080px; - margin: 56px auto; - max-height: calc(100vh - 112px); + width: calc(100% - 140px); + background: none; } .Modal_Align-top { - margin-bottom: auto; + margin-top: 56px; } - .Modal_Align-center { - margin-top: auto; - margin-bottom: auto; + .ModalClose { + position: absolute; + top: 0; + right: -12px; + display: flex; + padding: 12px; + border: 0; + border-radius: 50%; + background: #394760; + color: white; + cursor: pointer; + transition: background-color .15s ease, color .15s ease; + transform: translateX(100%); } - .ModalInner { - max-height: inherit; - overflow: auto; + .ModalClose svg { + width: 14px; + height: 14px; } - .ModalClose { - padding: 32px; + @media (hover) { + .ModalClose:hover { + background: #273143; + } } - .ModalClose svg { - width: 24px; - height: 24px; + .ModalClose:active { + background: #0f141b; } .ModalTitle { + padding: 60px 40px 0; font-size: 32px; - padding: 60px 68px 32px; } - + .ModalContent { - padding: 12px 68px 48px; + padding: 8px; + } +} + +@media screen and (min-width: 991px) { + .Modal { + width: calc(100% - 154px); + max-width: 1360px; + } + + .Modal_Align-top { + margin-top: 64px; + } + + .ModalInner { + border-radius: 24px; + } + + .ModalTitle { + padding: 60px 64px 0; + font-size: 32px; + } + + .ModalContent { + padding: 24px 32px; + } + + .ModalClose { + padding: 16px; + right: -12px; + } + + .ModalClose svg { + width: 20px; + height: 20px; + } +} + +@media screen and (min-width: 991px) and (min-height: 800px) { + .Modal { + max-height: calc(100vh - 128px); } } @@ -102,4 +165,4 @@ opacity: 1; transform: translateZ(0); } -} +} \ No newline at end of file diff --git a/client/components/UI/Modal/Modal.tsx b/client/components/UI/Modal/Modal.tsx index 06ff5e56..02269dda 100644 --- a/client/components/UI/Modal/Modal.tsx +++ b/client/components/UI/Modal/Modal.tsx @@ -19,6 +19,7 @@ export function Modal({ children }: ModalProps) { const ref = useRef(null); + const refInner = useRef(null); const close = () => { ref.current.close(); @@ -26,11 +27,12 @@ export function Modal({ useEffect(() => { ref.current.showModal(); + refInner.current.scrollTo(0, 0); // Remove focus after open (document.activeElement as HTMLElement).blur(); const handleClickOutside = (e) => { - if (ref.current.contains(e.target)) { + if (ref.current === e.target) { close(); } } @@ -50,15 +52,14 @@ export function Modal({ onClose={onClose} ref={ref} > -
- - +
{title &&

{t(title)}

} -
{children}
+ + ); } diff --git a/client/pages/[slug].tsx b/client/pages/[slug].tsx index 359b5ddc..ffe7a934 100644 --- a/client/pages/[slug].tsx +++ b/client/pages/[slug].tsx @@ -4,16 +4,21 @@ import Head from 'next/head'; import { articlesApi } from 'api/articles/articles'; import { ArticleProps } from 'components/Articles/Article/Article.types'; import { Article } from 'components/Articles/Article/Article'; +import { Feedback } from 'components/Common/Feedback/Feedback'; -function ArticlePage({ title, description }: ArticleProps) { +function ArticlePage({ title, description, sidebar }: ArticleProps) { return ( <> - + {`Транспорт Екатеринбурга — ${title}`} -
+
); } diff --git a/client/pages/map.tsx b/client/pages/map.tsx index ecbbc413..5a673fd0 100644 --- a/client/pages/map.tsx +++ b/client/pages/map.tsx @@ -25,11 +25,8 @@ export default function Map() { - -
+ +
);