refactor: make view components more modular

This commit is contained in:
zyachel 2022-08-03 14:52:14 +05:30
parent 18c9cd4bd1
commit a8574c4f0c
12 changed files with 372 additions and 621 deletions

View file

@ -40,9 +40,9 @@ const getAnswers = async slug => {
author: {
uid: ansObj.node.answer.author.uid,
isAnon: ansObj.node.answer.author.isAnon,
avatar: ansObj.node.answer.author.profileImageUrl,
image: ansObj.node.answer.author.profileImageUrl,
isVerified: ansObj.node.answer.author.isVerified,
profile: ansObj.node.answer.author.profileUrl,
url: ansObj.node.answer.author.profileUrl,
name: `${ansObj.node.answer.author.names[0].givenName} ${ansObj.node.answer.author.names[0].familyName}`,
credential: ansObj.node.answer.authorCredential?.translatedString,
// additionalCredentials: ansObj.node.answer?.credibilityFacts.map(),

View file

@ -35,7 +35,7 @@ const getTopic = async slug => {
uid: author.user.uid,
name: `${author.user.names[0].givenName} ${author.user.names[0].familyName}`,
profile: author.user.profileUrl,
avatar: author.user.profileImageUrl,
image: author.user.profileImageUrl,
isAnon: author.user.isAnon,
isVerified: author.user.isVerified,
numFollowers: author.user.followerCount,

View file

@ -1,74 +0,0 @@
//-//////////////////////////////////////////////////////
//- INCLUDES/EXTENDS
//-//////////////////////////////////////////////////////
include ../mixins/_formatText.pug
//-//////////////////////////////////////////////////////
//- LOCAL HELPER MIXINS
//-//////////////////////////////////////////////////////
//- mixin to format date and stuff
mixin addDate(date)
- const dateObj = new Date(date / 1000);
time.answer__metadata-data(datetime= dateObj.toISOString(), title=dateObj.toUTCString())= Intl.DateTimeFormat('en-US', {year: '2-digit', month: 'short', day: 'numeric' }).format(dateObj)
//-//////////////////////////////////////////////////////
//- MAIN CONTENT
//-//////////////////////////////////////////////////////
article.answer
//- ABOUT AUTHOR
figure.answer__author
figcaption.answer__author-name
if answerObj.author.isAnon
span Anonymous
else
a.answers__link(href=answerObj.author.profile)= answerObj.author.name
if answerObj.author.isVerified
svg.answer__icon
title verified
use(href='/misc/sprite.svg#icon-verified')
img.answer__author-image(src=answerObj.author.avatar.replace('https://', "/api/v1/image/"), alt=`${answerObj.author.name}'s profile photo`, loading='lazy')
p.answer__author-credentials(aria-label=`${answerObj.author.name}'s credentials`)= answerObj.author.credential || ''
//- ORIGINAL QUESTION
h3.answer__question.heading.heading__tertiary
span Originally answered to 
a.answer__link.answers__link(href=answerObj.originalQuestion.url)
+spansChecker(answerObj.originalQuestion.text[0].spans)
//- ANSWER
.answer__text
+formatText(answerObj.text)
//- for quora plus answers. since quora only shows half answer, we gotta warn viewer.
unless answerObj.isViewable
p.answer__unviewable
svg.answer__icon: use(href='/misc/sprite.svg#icon-danger')
| This is a Quora plus answer and hence full answer is not viewable.
//- ANSWER METADATA
.answer__metadata
p.answer__metadata-item
svg.answer__icon: use(href='/misc/sprite.svg#icon-clock')
+addDate(answerObj.creationTime)
span.answer__metadata-text  Answered
if answerObj.updatedTime
p.answer__metadata-item
svg.answer__icon: use(href='/misc/sprite.svg#icon-clock-edit')
+addDate(answerObj.updatedTime)
span.answer__metadata-text  Edited
p.answer__metadata-item
svg.answer__icon: use(href='/misc/sprite.svg#icon-eye')
span.answer__metadata-data= answerObj.numViews
span.answer__metadata-text  Views
p.answer__metadata-item
svg.answer__icon: use(href='/misc/sprite.svg#icon-arrow-up')
span.answer__metadata-data= answerObj.numUpvotes
span.answer__metadata-text  Upvotes
p.answer__metadata-item
svg.answer__icon: use(href='/misc/sprite.svg#icon-comments')
span.answer__metadata-data= answerObj.numComments
span.answer__metadata-text  Comments
p.answer__metadata-item
svg.answer__icon: use(href='/misc/sprite.svg#icon-share')
span.answer__metadata-data= answerObj.numShares
span.answer__metadata-text  Shares

View file

@ -0,0 +1,50 @@
//-//////////////////////////////////////////////////////
//- INCLUDES/EXTENDS
//-//////////////////////////////////////////////////////
include ../mixins/_formatText
include ../mixins/_metadata
include ../mixins/_utils
//-//////////////////////////////////////////////////////
//- MAIN CONTENT
//-//////////////////////////////////////////////////////
mixin addAnswer(answer)
article.answer
//- ABOUT AUTHOR
figure.metadata-primary
figcaption.metadata-primary__heading
if answer.author.isAnon
span Anonymous
else
a.link.metadata-primary__link(href=answer.author.url)= answer.author.name
if answer.author.isVerified
svg.icon.metadata-primary__icon
title verified
use(href='/misc/sprite.svg#icon-verified')
img.metadata-primary__image(src=answer.author.image.replace('https://', "/api/v1/image/"), alt=`${answer.author.name}'s profile photo`, loading='lazy')
p.metadata-primary__misc(aria-label=`${answer.author.name}'s credentials`)= answer.author.credential || ''
//- ORIGINAL QUESTION
h3.answer__question.heading.heading__tertiary
span Originally answered to 
a.answer__link.answers__link(href=answer.originalQuestion.url)
+spansChecker(answer.originalQuestion.text[0].spans)
//- ANSWER
section.answer__text.text__container
+formatText(answer.text)
//- for quora plus answers. since quora only shows half answer, we gotta warn viewer.
unless answer.isViewable
p.answer__unviewable
svg.icon.answer__icon: use(href='/misc/sprite.svg#icon-danger')
| This is a Quora plus answer and hence full answer is not viewable.
//- ANSWER METADATA
section.answer__metadata-secondary.metadata-secondary
+addMetadataSecondary('clock', 'Answered', answer.creationTime, 'date')
if answer.updatedTime
+addMetadataSecondary('clock-edit', 'Updated', answer.updatedTime, 'date')
+addMetadataSecondary('eye', 'Views', answer.numViews)
+addMetadataSecondary('arrow-up', 'Upvotes', answer.numUpvotes)
+addMetadataSecondary('comments', 'Comments', answer.numComments)
+addMetadataSecondary('share', 'Shares', answer.numShares)

View file

@ -8,28 +8,28 @@ mixin spansChecker(spans)
- if(span.modifiers.math)
//- setting that var in the base.pug value to true here, so that mathjax library is loaded in the end
- someAnswerContainsMath = true;
span.answer__span-math= `\\(${span.text}\\)`
span.text__span-math= `\\(${span.text}\\)`
//- handle small code text
- else if (span.modifiers.code)
code.answer__span-code= span.text
code.text__span-code= span.text
//- handle misc. embedded content
- else if (span.modifiers.embed)
a.answer__span-link.answers__link(href=span.modifiers.embed.url)= span.modifiers.embed.title || '(link to user embedded content)'
a.text__span-link.text__link(href=span.modifiers.embed.url)= span.modifiers.embed.title || '(link to user embedded content)'
//- handle links
- else if (span.modifiers.link) //- removing quora.com from the link in case it is a quora.com link.
a.answer__span-link.answers__link(href=span.modifiers.link.url.split('https://www.quora.com')[1] || span.modifiers.link.url)=span.text
a.text__span-link.text__link(href=span.modifiers.link.url.split('https://www.quora.com')[1] || span.modifiers.link.url)=span.text
//- handle bold + italic text
- else if (!!span.modifiers.bold && !!span.modifiers.italic)
strong.answer__span-bold: em.answer__span-italic= span.text
strong.text__span-bold: em.text__span-italic= span.text
//- handle bold text
- else if (!!span.modifiers.bold)
strong.answer__span-bold= span.text
strong.text__span-bold= span.text
//- handle italic text
- else if (!!span.modifiers.italic)
em.answer__span-italic= span.text
em.text__span-italic= span.text
//- regular plain text
- else
span.answer__span-plain= span.text
span.text__span-plain= span.text
//-//////////////////////////////////////////////////////
//- MAIN MIXIN TO FORMAT ANY TEXT
@ -38,32 +38,33 @@ mixin formatText(text)
each para in text
//- handle images
-if(para.type ==='image')
img.answer__para.answer__image(src=para.spans[0].modifiers.master_url.replace('https://', "/api/v1/image/"), alt='User embedded image', loading='lazy')
.text__para.text__image-container
img.text__image(src=para.spans[0].modifiers.master_url.replace('https://', "/api/v1/image/"), alt='User embedded image', loading='lazy')
//- handle code blocks
- else if (para.type ==='code')
pre.answer__para.answer__code: code
pre.text__para.text__code: code
+spansChecker(para.spans)
//- handle quotes
- else if(para.quoted)
blockquote.answer__para.answer__quote
blockquote.text__para.text__quote
+spansChecker(para.spans)
//- handling lists
-else if(para.type.includes('-list'))
p(class=`answer__para answer__${para.type} answer__${para.type}--${para.indent}` role='listitem')
p(class=`text__para text__${para.type} text__${para.type}--${para.indent}` role='listitem')
+spansChecker(para.spans)
//- handling horizontal rule
- else if(para.type === 'horizontal-rule')
hr.answer__para.answer__hr
hr.text__para.text__hr
//- handling embedded youtube video
- else if(para.type === 'yt-embed')
.answer__para.answer__embed
a.answer__span-link.answers__link(href=para.spans[0].modifiers.embed.url) (link to user-embedded YouTube video)
.text__para.text__embed
a.text__span-link.text__link(href=para.spans[0].modifiers.embed.url) (link to user-embedded YouTube video)
//- handling embedded tweet
- else if(para.type === 'tweet')
.answer__para.answer__embed.answer__embed-tweet
.text__para.text__embed.text__embed-tweet
//- directly pasting raw HTML which pug will process just fine
| !{para.spans[0].modifiers.embed.html}
//- rest of the types that don't need/can't be put in a semantic html tag
- else
p(class=`answer__para answer__${para.type}`)
p(class=`text__para text__${para.type}`)
+spansChecker(para.spans)

View file

@ -0,0 +1,19 @@
//-//////////////////////////////////////////////////////
//- INCLUDES/EXTENDS
//-//////////////////////////////////////////////////////
include ../mixins/_formatText
include ../mixins/_utils
mixin addMetadataSecondary(iconName, name, number, numberType='number')
p.metadata-secondary__item
svg.icon.metadata-secondary__icon: use(href=`/misc/sprite.svg#icon-${iconName}`)
case numberType
when 'number'
+formatNumber(number, 'metadata-secondary__data')
when 'date'
+addDate(number)
when 'empty'
span
default
span= number
span.metadata-secondary__text= name

View file

@ -0,0 +1,10 @@
//-//////////////////////////////////////////////////////
//- SMALL MIXINS THAT ARE USED IN MANY PLACES
//-//////////////////////////////////////////////////////
mixin addDate(date, className='')
- const dateObj = new Date(date / 1000);
time(class= className, datetime= dateObj.toISOString(), title=dateObj.toUTCString())= Intl.DateTimeFormat('en-US', {year: '2-digit', month: 'short', day: 'numeric' }).format(dateObj)
mixin formatNumber(number, className='')
span(class=className)= new Intl.NumberFormat().format(number)

View file

@ -3,6 +3,7 @@
//-//////////////////////////////////////////////////////
extends ../base
include ../mixins/_formatText
include ../mixins/_answer
//-//////////////////////////////////////////////////////
//- MAIN CONTENT
@ -23,8 +24,8 @@ block content
.answers-box.answers__answers-box
h2.heading.heading__secondary.answers__answers-box-heading Answers
.answers-box__list
each answerObj in data.answers
include ../layout/_answer
each answer in data.answers
+addAnswer(answer)
//- TOPICS TAGGED WITH THIS QUESTION
aside.topics.answers__topics

View file

@ -2,13 +2,8 @@
//- INCLUDES/EXTENDS
//-//////////////////////////////////////////////////////
extends ../base
//-//////////////////////////////////////////////////////
//- LOCAL HELPER MIXINS
//-//////////////////////////////////////////////////////
//- mixin to make number a bit more readable
mixin formatNumber(number, ...classes)
span(class=classes.join(' '))= new Intl.NumberFormat().format(number)
include ../mixins/_metadata
include ../mixins/_utils
//-//////////////////////////////////////////////////////
//- MAIN CONTENT
@ -16,71 +11,52 @@ mixin formatNumber(number, ...classes)
block content
main#main.main.topic
//- TOPIC NAME AND METADATA
.topic__stats.topic-stats
h1.heading.heading__primary.topic__heading.topic-stats__heading= data.name
img.topic-stats__image(src=data.image.replace('https://', "/api/v1/image/") alt=`image depicting ${data.name}`, loading='lazy')
section.topic__stats.topic-stats
.metadata-primary
h1.heading.heading__primary.metadata-primary__heading.topic__name= data.name
img.metadata-primary__image(src=data.image.replace('https://', "/api/v1/image/") alt=`cover photo of '${data.name}' topic`, loading='lazy')
p.metadata-primary__misc
if data.aliases.length
p.topic-stats__aliases
span.topic-stats__aliases-text Also known as: 
span.topic-stats__aliases-list= data.aliases.join(', ')
.topic-stats__metadata
p.topic-stats__metadata-item
svg.icon.topic-stats__icon: use(href='/misc/sprite.svg#icon-user')
+formatNumber(data.numFollowers, 'topic-stats__metadata-data')
span.topic-stats__metadata-text  Followers
p.topic-stats__metadata-item
svg.icon.topic-stats__icon: use(href='/misc/sprite.svg#icon-question')
+formatNumber(data.numQuestions, 'topic-stats__metadata-data')
span.topic-stats__metadata-text  Questions
span Also known as: 
span= data.aliases.join(', ')
.metadata-secondary
+addMetadataSecondary('user','Followers', data.numFollowers)
+addMetadataSecondary('question','Questions', data.numQuestions)
if data.isAdult
p.topic-stats__metadata-item
svg.icon.topic-stats__icon: use(href='/misc/sprite.svg#icon-danger')
span.topic-stats__metadata-data 18+
span.topic-stats__metadata-text  Adult Topic
a.topic__link(href='https://www.quora.com' + data.url) View on Quora
+addMetadataSecondary('danger', 'Adult Topic', '18+', true)
a.link(href='https://www.quora.com' + data.url) View on Quora
//- AUTHORS RELATED TO THE TOPIC AND METADATA
.topic__famous-authors.famous-authors
h2.heading.heading__secondary.famous-authors__heading Most viewed authors
h2.heading.heading__secondary Most viewed authors
.famous-authors__list
each author in data.mostViewedAuthors
figure.famous-authors__author
figcaption.famous-authors__author-name
.famous-authors__item
figure.metadata-primary
figcaption.metadata-primary__heading
if author.isAnon
span Anonymous
else
a.topic__link(href=author.profile)= author.name
a.link(href=author.profile)= author.name
if author.isVerified
svg.famous-authors__icon
svg.icon.metadata-primary__icon
title verified
use(href='/misc/sprite.svg#icon-verified')
img.famous-authors__author-image(src=author.avatar.replace('https://', "/api/v1/image/"), alt=`${author.name}'s profile photo`, loading='lazy')
if author.credential
p.famous-authors__author-credentials(aria-label=`${author.name}'s credentials`)= author.credential || ''
.famous-authors__metadata
p.famous-authors__metadata-item
svg.icon.famous-authors__icon: use(href='/misc/sprite.svg#icon-user')
+formatNumber(author.numFollowers, 'famous-authors__metadata-data')
span.famous-authors__metadata-text  Followers
p.famous-authors__metadata-item
svg.icon.famous-authors__icon: use(href='/misc/sprite.svg#icon-eye')
+formatNumber(author.numViews, 'famous-authors__metadata-data')
span.famous-authors__metadata-text  Views
p.famous-authors__metadata-item
svg.icon.famous-authors__icon: use(href='/misc/sprite.svg#icon-comments')
+formatNumber(author.numAnswers, 'famous-authors__metadata-data')
span.famous-authors__metadata-text  Answers
img.metadata-primary__image(src=author.image.replace('https://', "/api/v1/image/"), alt=`${author.name}'s profile photo`, loading='lazy')
p.metadata-primary__misc(aria-label=`${author.name}'s credentials`)= author.credential || ''
.metadata-secondary
+addMetadataSecondary('user', 'Followers', author.numFollowers)
+addMetadataSecondary('eye', 'Views', author.numViews)
+addMetadataSecondary('comments', 'Answers', author.numAnswers)
//- RELATED TOPICS
.topic__related-topics.related-topics
h2.heading.heading__secondary.related-topics__heading Related Topics
h2.heading.heading__secondary Related Topics
.related-topics__list
each topic in data.relatedTopics
.related-topics__topic
a.topic__link.related-topics__topic-name(href=topic.url)= topic.name
img.related-topics__image(src=topic.image.replace('https://', "/api/v1/image/") alt=`image depicting ${topic.name}`, loading='lazy')
.related-topics__metadata
p.related-topics__metadata-item
svg.icon.related-topics__icon: use(href='/misc/sprite.svg#icon-user')
+formatNumber(topic.numFollowers, 'related-topics__metadata-data')
span.topic-stats__metadata-text  Followers
.metadata-primary
a.link.metadata-primary__heading(href=topic.url)= topic.name
img.metadata-primary__image(src=topic.image.replace('https://', "/api/v1/image/") alt=`cover photo of '${topic.name}' topic`, loading='lazy')
p.metadata-primary__misc
+formatNumber(topic.numFollowers)
| Followers

View file

@ -3,28 +3,6 @@
////////////////////////////////////////////////////////
@use 'mixins' as *;
////////////////////////////////////////////////////////
// SKIP TO MAIN CONTENT LINK
////////////////////////////////////////////////////////
.skip-link {
position: absolute;
left: 50%;
// background: var(--clr-base-bg);
color: var(--clr-base-heading);
text-decoration: none;
text-align: center;
font-weight: 500;
padding: 0 var(--space-100);
border-radius: 0 0 5px 5px;
font-size: var(--fs-180);
transform: translate(-50%, -150%);
transition: transform 200ms ease;
&:is(:focus, :focus-visible) {
transform: translate(-50%, 0);
}
}
////////////////////////////////////////////////////////
// THEME CHANGER
////////////////////////////////////////////////////////
@ -93,65 +71,173 @@
.heading {
color: var(--clr-base-heading);
font-weight: 600;
&__primary {
font-size: var(--fs-300);
@include respond-to(bp-550) {
font-size: var(--fs-270);
}
}
}
////////////////////////////////////////////////////////
// FEATURES
// LINKS
////////////////////////////////////////////////////////
.features {
.link {
@include format-link(var(--clr-base-link), var(--clr-base-link-alt-alpha));
}
.skip-link {
position: absolute;
left: 50%;
// background: var(--clr-base-bg);
color: var(--clr-base-heading);
text-decoration: none;
text-align: center;
font-weight: 500;
padding: 0 var(--space-100);
border-radius: 0 0 5px 5px;
font-size: var(--fs-180);
transform: translate(-50%, -150%);
transition: transform 200ms ease;
&:is(:focus, :focus-visible) {
transform: translate(-50%, 0);
}
}
////////////////////////////////////////////////////////
// METADATA
////////////////////////////////////////////////////////
.metadata-primary {
display: grid;
gap: var(--space-800);
gap: 0 var(--space-100);
grid-template-columns: auto 1fr;
grid-template-rows: repeat(2, min-content);
font-size: var(--fs-160);
&__heading {
justify-self: center;
}
grid-column: 2 / -1;
align-self: end;
color: var(--clr-base-heading-alt-alpha);
font-weight: 600;
&__list {
display: grid;
gap: var(--space-800);
grid-template-columns: repeat(auto-fit, minmax(40rem, 1fr));
// for verified icon
display: flex;
gap: var(--space-050);
justify-items: start;
@include respond-to(bp-900) {
gap: var(--space-500);
grid-template-columns: auto;
// for name linking to profile
a {
font-size: 1.05em;
color: currentColor;
}
}
&__feature {
display: grid;
gap: var(--space-100);
grid-template-rows: repeat(3, min-content);
font-size: var(--fs-160);
// justify-items: center;
// text-align: center;
&__misc {
grid-column: 2 / -1;
align-self: start;
}
&__feature-icon {
&__image {
grid-row: 1 / -1;
grid-column: 1 / span 1;
margin-block: auto;
max-height: var(--img-dim, --fs-600);
max-width: var(--img-dim, --fs-600);
// min-height: 100%;
// min-width: 100%;
object-fit: cover;
clip-path: circle(50% at 50% 50%);
}
&__icon {
grid-column: 1 / span 1;
justify-self: end;
align-self: center;
height: 1.3em;
width: 1.3em;
fill: var(--clr-base-icon);
grid-row: 1 / 2;
flex: 0 0 auto;
}
}
height: 3em;
width: 3em;
.metadata-secondary {
justify-self: start;
@include respond-to(bp-750) {
height: 2em;
width: 2em;
}
}
&__feature-heading {
grid-row: 2 / 3;
font-size: 1.3em;
}
&__feature-text {
grid-row: 3 / 4;
}
@include respond-to(bp-900) {
gap: var(--space-500);
}
@include respond-to(bp-750) {
display: flex;
gap: var(--space-200);
align-items: center;
flex-wrap: wrap;
&__item {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 0 var(--space-050);
}
&__icon {
grid-column: 1 / span 1;
justify-self: end;
align-self: center;
height: 1.3em;
width: 1.3em;
fill: var(--clr-base-icon);
}
&__data {
grid-column: -2 / -1;
justify-self: start;
}
&__text {
grid-row: 2 / span 1;
grid-column: 1 / -1;
justify-self: center;
font-size: 0.9em;
color: var(--clr-base-text-alt-alpha);
}
}
////////////////////////////////////////////////////////
// ANSWER
////////////////////////////////////////////////////////
.answer {
--img-dim: var(--fs-600);
display: grid;
gap: var(--space-200);
// question area
&__question {
font-size: 1.05em;
}
&__unviewable {
// for aligning both text and svg
display: grid;
align-content: center;
justify-content: start;
grid-auto-flow: column;
gap: var(--space-100);
align-items: center;
margin-top: var(--space-200);
color: var(--clr-base-heading-alt-alpha);
font-weight: 500;
// border: 1px solid var(--clr-base-icon-alt-alpha);
// padding: var(--space-100);
}
&__icon {
height: 1.3em;
width: 1.3em;
}
}
@ -230,7 +316,67 @@
}
////////////////////////////////////////////////////////
// ANSWERS
// ABOUT PAGE COMPONENTS
////////////////////////////////////////////////////////
.features {
display: grid;
gap: var(--space-800);
&__heading {
justify-self: center;
}
&__list {
display: grid;
gap: var(--space-800);
grid-template-columns: repeat(auto-fit, minmax(40rem, 1fr));
@include respond-to(bp-900) {
gap: var(--space-500);
grid-template-columns: auto;
}
}
&__feature {
display: grid;
gap: var(--space-100);
grid-template-rows: repeat(3, min-content);
font-size: var(--fs-160);
// justify-items: center;
// text-align: center;
}
&__feature-icon {
fill: var(--clr-base-icon);
grid-row: 1 / 2;
height: 3em;
width: 3em;
@include respond-to(bp-750) {
height: 2em;
width: 2em;
}
}
&__feature-heading {
grid-row: 2 / 3;
font-size: 1.3em;
}
&__feature-text {
grid-row: 3 / 4;
}
@include respond-to(bp-900) {
gap: var(--space-500);
}
@include respond-to(bp-750) {
gap: var(--space-200);
}
}
////////////////////////////////////////////////////////
// ANSWER PAGE COMPONENTS
////////////////////////////////////////////////////////
.answers-box {
display: grid;
@ -242,120 +388,6 @@
}
}
.answer {
display: grid;
gap: var(--space-200);
// author area
&__author {
display: grid;
gap: 0 var(--space-100);
grid-template-columns: auto 1fr;
grid-template-rows: repeat(2, min-content);
font-size: var(--fs-160);
}
&__author-name {
grid-column: 2 / -1;
align-self: end;
color: var(--clr-base-heading-alt-alpha);
font-weight: 500;
// for verified icon
display: flex;
gap: var(--space-050);
// for name linking to profile
a {
font-size: 1.05em;
color: currentColor;
}
}
&__author-credentials {
grid-column: 2 / -1;
align-self: start;
}
&__author-image {
grid-row: 1 / -1;
grid-column: 1 / span 1;
max-height: var(--fs-600);
max-width: var(--fs-600);
min-height: 100%;
min-width: 100%;
object-fit: cover;
clip-path: circle(50% at 50% 50%);
}
// question area
&__question {
font-size: 1.05em;
}
&__unviewable {
// for aligning both text and svg
display: grid;
align-content: center;
justify-content: start;
grid-auto-flow: column;
gap: var(--space-100);
align-items: center;
margin-top: var(--space-200);
color: var(--clr-base-heading-alt-alpha);
font-weight: 500;
// border: 1px solid var(--clr-base-icon-alt-alpha);
// padding: var(--space-100);
}
// metadata(likes, shares, etc)
&__metadata {
justify-self: start;
display: flex;
gap: var(--space-200);
align-items: center;
flex-wrap: wrap;
}
&__metadata-item {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 0 var(--space-050);
}
&__icon {
grid-column: 1 / span 1;
justify-self: end;
align-self: center;
height: 1.3em;
width: 1.3em;
fill: var(--clr-base-icon);
}
&__metadata-data {
grid-column: -2 / -1;
justify-self: start;
}
&__metadata-text {
grid-row: 2 / span 1;
grid-column: 1 / -1;
justify-self: center;
font-size: 0.9em;
color: var(--clr-base-text-alt-alpha);
}
}
////////////////////////////////////////////////////////
// TOPICS
////////////////////////////////////////////////////////
.topics {
display: grid;
gap: var(--space-200);
@ -364,19 +396,13 @@
list-style: none;
display: grid;
gap: var(--space-100);
// display: flex;
// flex-wrap: wrap;
}
&__item {
// flex: 0 1 auto
font-weight: 500;
}
}
////////////////////////////////////////////////////////
// RELATED
////////////////////////////////////////////////////////
.related {
display: grid;
align-content: start;
@ -394,281 +420,29 @@
}
////////////////////////////////////////////////////////
// TOPIC STATS
// TOPIC PAGE COMPONENTS
////////////////////////////////////////////////////////
.topic-stats {
--img-dim: var(--fs-1000);
display: grid;
gap: var(--space-050) var(--space-200);
grid-template-columns: auto 1fr;
grid-template-rows: repeat(3, auto);
&__heading {
grid-column: 2 / -1;
align-self: end;
line-height: 1;
@include respond-to(bp-450) {
align-self: center;
}
}
&__image {
grid-row: 1 / -1;
grid-column: 1 / span 1;
max-height: var(--fs-1000);
max-width: var(--fs-1000);
margin-block: auto;
object-fit: contain;
@include respond-to(bp-450) {
max-height: var(--fs-800);
max-width: var(--fs-800);
}
}
&__aliases {
@include respond-to(bp-450) {
grid-column: 1 / -1;
}
}
&__metadata {
display: flex;
gap: var(--space-500);
align-items: center;
flex-wrap: wrap;
@include respond-to(bp-750) {
// margin-top: var(--space-100);
grid-column: 1 / -1;
}
@include respond-to(bp-650) {
gap: var(--space-200);
}
}
&__metadata-item {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 0 var(--space-050);
}
&__icon {
grid-column: 1 / span 1;
justify-self: end;
align-self: center;
height: 1.3em;
width: 1.3em;
fill: var(--clr-base-icon);
}
&__metadata-data {
grid-column: -2 / -1;
justify-self: start;
}
&__metadata-text {
grid-row: 2 / span 1;
grid-column: 1 / -1;
justify-self: center;
font-size: 0.9em;
color: var(--clr-base-text-alt-alpha);
}
@include respond-to(bp-750) {
grid-template-rows: repeat(2, auto);
row-gap: var(--space-100);
}
@include respond-to(bp-450) {
grid-template-rows: auto;
}
}
////////////////////////////////////////////////////////
// FAMOUS AUTHORS
////////////////////////////////////////////////////////
.famous-authors {
display: grid;
gap: var(--space-300);
&__list {
display: grid;
gap: var(--space-500);
}
&__author {
display: grid;
gap: var(--space-050) var(--space-100);
grid-template-columns: auto 1fr;
grid-template-rows: repeat(3, min-content);
font-size: var(--fs-160);
@include respond-to(bp-750) {
grid-template-rows: repeat(2, min-content);
}
}
&__author-name {
grid-column: 2 / -1;
line-height: 1;
align-self: center;
color: var(--clr-base-heading-alt-alpha);
font-weight: 500;
// for verified icon
display: flex;
gap: var(--space-050);
// for name linking to profile
a {
font-size: 1.05em;
color: currentColor;
}
}
&__author-credentials {
grid-column: 2 / -1;
word-break: break-word;
}
&__author-image {
margin-block: auto;
grid-row: 1 / -1;
grid-column: 1 / span 1;
max-height: var(--fs-800);
max-width: var(--fs-800);
object-fit: cover;
clip-path: circle(50% at 50% 50%);
@include respond-to(bp-750) {
max-height: var(--fs-600);
max-width: var(--fs-600);
}
}
&__metadata {
display: flex;
gap: var(--space-200);
align-items: center;
flex-wrap: wrap;
@include respond-to(bp-750) {
margin-top: var(--space-100);
grid-column: 1 / -1;
}
}
&__metadata-item {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 0 var(--space-050);
}
&__icon {
grid-column: 1 / span 1;
justify-self: end;
align-self: center;
height: 1em;
width: 1em;
fill: var(--clr-base-icon);
}
&__metadata-data {
grid-column: -2 / -1;
justify-self: start;
}
&__metadata-text {
grid-row: 2 / span 1;
grid-column: 1 / -1;
justify-self: center;
line-height: 1;
font-size: 0.9em;
color: var(--clr-base-text-alt-alpha);
}
}
////////////////////////////////////////////////////////
// RELATED TOPICS
////////////////////////////////////////////////////////
.famous-authors,
.related-topics {
--img-dim: var(--fs-600);
display: grid;
gap: var(--space-300);
&__list {
display: grid;
gap: var(--space-500);
gap: var(--space-400);
}
&__topic {
&__item {
display: grid;
gap: 0 var(--space-200);
grid-template-columns: auto 1fr;
grid-template-rows: repeat(2, min-content);
}
&__topic-name {
grid-column: 2 / -1;
justify-self: start;
font-weight: 500;
font-size: 1.05em;
}
&__image {
grid-row: 1 / -1;
max-height: var(--fs-800);
max-width: var(--fs-800);
min-height: 100%;
min-width: 100%;
object-fit: contain;
@include respond-to(bp-750) {
max-height: var(--fs-600);
max-width: var(--fs-600);
}
}
&__metadata {
grid-row: -2 / -1;
justify-self: start;
}
&__metadata-item {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 0 var(--space-050);
}
&__icon {
grid-column: 1 / span 1;
justify-self: end;
align-self: center;
height: 1em;
width: 1em;
fill: var(--clr-base-icon);
}
&__metadata-data {
grid-column: -2 / -1;
justify-self: start;
}
&__metadata-text {
grid-row: 2 / span 1;
grid-column: 1 / -1;
justify-self: center;
line-height: 1;
font-size: 0.9em;
color: var(--clr-base-text-alt-alpha);
gap: var(--space-100);
}
}

View file

@ -6,7 +6,6 @@
////////////////////////////////////////////////////////
// HEADER
////////////////////////////////////////////////////////
.header {
background-color: var(--clr-hf-bg);
@ -181,11 +180,11 @@
}
////////////////////////////////////////////////////////
// ANSWER
// TEXT
////////////////////////////////////////////////////////
.answer {
// main answer formatting
&__text {
.text {
// main text formatting
&__container {
border-block: 1px solid var(--clr-base-icon-alt-alpha);
padding: var(--space-100);
@ -207,6 +206,7 @@
}
&__image {
display: inline-block;
max-width: 100%;
max-height: 100%;
object-fit: contain;
@ -303,7 +303,8 @@
font-style: italic;
}
&__span-link {
&__span-link,
&__link {
@include format-link(
var(--clr-base-link),
var(--clr-base-link-alt-alpha),

View file

@ -202,9 +202,8 @@
}
////////////////////////////////////////////////////////
// ANSWERED
// ANSWERS
////////////////////////////////////////////////////////
.answers {
// justify-self: center;
padding: var(--space-800);
@ -285,7 +284,6 @@
// TOPIC
////////////////////////////////////////////////////////
.topic {
// justify-self: center;
padding: var(--space-800);
display: grid;
@ -295,11 +293,7 @@
align-items: start;
gap: var(--space-800);
&__stats {
grid-column: 1 / -1;
}
&__heading {
&__name {
font-size: var(--fs-300);
@include respond-to(bp-550) {
@ -307,14 +301,13 @@
}
}
&__link {
@include format-link(var(--clr-base-link), var(--clr-base-link-alt-alpha));
&__stats {
grid-column: 1 / -1;
}
@include respond-to(bp-1200) {
display: flex;
flex-direction: column;
// gap: var(--space-800);
}
@include respond-to(bp-900) {