Merge pull request #32 from Discours/cards-css-modules

Rewrite several components style to css-modules
This commit is contained in:
Igor Lobanov 2022-10-15 14:11:03 +02:00 committed by GitHub
commit 14c6a1ce19
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 557 additions and 393 deletions

View File

@ -0,0 +1,4 @@
<svg width="12" height="12" viewBox="0 0 12 12" fill="none" xmlns="http://www.w3.org/2000/svg">
<path
d="M7.92 6C7.92 6.37974 7.80739 6.75095 7.59642 7.06669C7.38545 7.38244 7.08559 7.62853 6.73475 7.77385C6.38392 7.91917 5.99787 7.95719 5.62543 7.88311C5.25298 7.80902 4.91087 7.62616 4.64235 7.35764C4.37384 7.08913 4.19098 6.74702 4.11689 6.37457C4.04281 6.00213 4.08083 5.61608 4.22615 5.26525C4.37147 4.91441 4.61756 4.61455 4.93331 4.40358C5.24905 4.19261 5.62026 4.08 6 4.08C6.50904 4.08058 6.99706 4.28305 7.357 4.643C7.71695 5.00294 7.91942 5.49096 7.92 6ZM12 3.36V8.64C11.999 9.53082 11.6447 10.3849 11.0148 11.0148C10.3849 11.6447 9.53082 11.999 8.64 12H3.36C2.46918 11.999 1.61514 11.6447 0.985236 11.0148C0.355332 10.3849 0.00100889 9.53082 0 8.64V3.36C0.00100889 2.46918 0.355332 1.61514 0.985236 0.985236C1.61514 0.355332 2.46918 0.00100889 3.36 0H8.64C9.53082 0.00100889 10.3849 0.355332 11.0148 0.985236C11.6447 1.61514 11.999 2.46918 12 3.36ZM8.88 6C8.88 5.43039 8.71109 4.87357 8.39463 4.39996C8.07817 3.92634 7.62838 3.55721 7.10213 3.33923C6.57588 3.12125 5.99681 3.06421 5.43814 3.17534C4.87947 3.28646 4.36631 3.56076 3.96353 3.96353C3.56076 4.36631 3.28646 4.87947 3.17534 5.43814C3.06421 5.99681 3.12125 6.57588 3.33923 7.10213C3.55721 7.62838 3.92634 8.07817 4.39996 8.39463C4.87357 8.71109 5.43039 8.88 6 8.88C6.76356 8.87914 7.4956 8.57543 8.03551 8.03551C8.57543 7.4956 8.87914 6.76356 8.88 6ZM9.84 2.88C9.84 2.7376 9.79777 2.59839 9.71866 2.47999C9.63954 2.36159 9.52709 2.2693 9.39553 2.21481C9.26397 2.16031 9.1192 2.14605 8.97954 2.17383C8.83987 2.20162 8.71158 2.27019 8.61088 2.37088C8.51019 2.47158 8.44162 2.59987 8.41383 2.73953C8.38605 2.8792 8.40031 3.02397 8.45481 3.15553C8.5093 3.28709 8.60159 3.39954 8.71999 3.47866C8.83839 3.55777 8.9776 3.6 9.12 3.6C9.31096 3.6 9.49409 3.52414 9.62912 3.38912C9.76414 3.25409 9.84 3.07096 9.84 2.88Z" fill="#fff"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

@ -8,30 +8,30 @@
} }
} }
.author__details { .authorDetails {
display: flex; display: flex;
flex: 1; flex: 1;
padding-right: 1.2rem; padding-right: 1.2rem;
width: max-content; width: max-content;
} }
.author__details-wrapper { .authorDetailsWrapper {
flex: 1; flex: 1;
} }
.author__name { .authorName {
border: none !important; border: none !important;
font-size: 1.7rem; font-size: 1.7rem;
font-weight: 500; font-weight: 500;
margin-bottom: 0.8rem; margin-bottom: 0.8rem;
} }
.author__about { .authorAbout {
font-size: 1.5rem; font-size: 1.5rem;
color: rgb(0 0 0 / 60%); color: rgb(0 0 0 / 60%);
} }
.author__subscribe { .authorSubscribe {
@include media-breakpoint-down(lg) { @include media-breakpoint-down(lg) {
padding: 0 0 0 42px; padding: 0 0 0 42px;
} }
@ -43,6 +43,7 @@
height: 32px; height: 32px;
margin-right: 0.4rem; margin-right: 0.4rem;
position: relative; position: relative;
transition: background-color 0.2s;
vertical-align: middle; vertical-align: middle;
width: 32px; width: 32px;
@ -57,8 +58,17 @@
position: absolute; position: absolute;
top: 50%; top: 50%;
transform: translate(-50%, -50%); transform: translate(-50%, -50%);
transition: filter 0.2s;
width: 18px; width: 18px;
} }
&:hover {
background: #000;
&::before {
filter: invert(0);
}
}
} }
a[href*='facebook.com/'] { a[href*='facebook.com/'] {
@ -90,9 +100,15 @@
background-image: url(/icons/tumblr-white.svg); background-image: url(/icons/tumblr-white.svg);
} }
} }
a[href*='instagram.com/'] {
&::before {
background-image: url(/icons/instagram-white.svg);
}
}
} }
.button--subscribe { .buttonSubscribe {
align-items: center; align-items: center;
aspect-ratio: 1/1; aspect-ratio: 1/1;
background: #f6f6f6; background: #f6f6f6;
@ -105,14 +121,15 @@
} }
} }
.button__label { .buttonLabel {
display: none; display: none;
} }
.button--write { .buttonWrite {
background: #f7f7f7; background: #f7f7f7;
color: #000; color: #000;
display: inline-flex; display: inline-flex;
@include font-size(1.5rem); @include font-size(1.5rem);
.icon { .icon {
@ -123,3 +140,62 @@
height: 15px; height: 15px;
} }
} }
.authorPage {
.authorName {
@include font-size(3.4rem);
font-weight: 500;
margin-bottom: 0.2em;
}
.authorAbout {
color: #696969;
@include font-size(1.7rem);
}
.authorSubscribe {
display: flex;
margin-top: 2rem;
}
.authorDetails {
display: block;
}
.buttonLabel {
display: block;
}
.buttonSubscribe {
aspect-ratio: auto;
background-color: #000;
border-radius: 2px;
float: none;
padding-bottom: 0.6rem;
padding-top: 0.6rem;
.icon {
margin-right: 0.5em;
img {
filter: invert(1);
}
}
&:hover {
.icon img {
filter: invert(0.7);
}
}
}
.buttonSubscribe img {
vertical-align: text-top;
}
.button {
margin-right: 1.6rem;
vertical-align: middle;
}
}

View File

@ -2,13 +2,14 @@ import { For, Show } from 'solid-js/web'
import type { Author } from '../../graphql/types.gen' import type { Author } from '../../graphql/types.gen'
import Userpic from './Userpic' import Userpic from './Userpic'
import { Icon } from '../Nav/Icon' import { Icon } from '../Nav/Icon'
import './Card.scss' import style from './Card.module.scss'
import { createMemo } from 'solid-js' import { createMemo } from 'solid-js'
import { translit } from '../../utils/ru2en' import { translit } from '../../utils/ru2en'
import { t } from '../../utils/intl' import { t } from '../../utils/intl'
import { useAuthStore } from '../../stores/auth' import { useAuthStore } from '../../stores/auth'
import { locale } from '../../stores/ui' import { locale } from '../../stores/ui'
import { follow, unfollow } from '../../stores/zine/common' import { follow, unfollow } from '../../stores/zine/common'
import { clsx } from 'clsx'
interface AuthorCardProps { interface AuthorCardProps {
compact?: boolean compact?: boolean
@ -17,6 +18,7 @@ interface AuthorCardProps {
hasLink?: boolean hasLink?: boolean
subscribed?: boolean subscribed?: boolean
author: Author author: Author
isAuthorPage?: boolean
} }
export const AuthorCard = (props: AuthorCardProps) => { export const AuthorCard = (props: AuthorCardProps) => {
@ -34,45 +36,51 @@ export const AuthorCard = (props: AuthorCardProps) => {
} }
// TODO: reimplement AuthorCard // TODO: reimplement AuthorCard
return ( return (
<div class="author"> <div class={style.author} classList={{ [style.authorPage]: props.isAuthorPage }}>
<Userpic user={props.author} hasLink={props.hasLink} /> <Userpic user={props.author} hasLink={props.hasLink} isBig={props.isAuthorPage} />
<div class="author__details"> <div class={style.authorDetails}>
<div class="author__details-wrapper"> <div class={style.authorDetailsWrapper}>
<Show when={props.hasLink}> <Show when={props.hasLink}>
<a class="author__name text-3xl text-2xl" href={`/author/${props.author.slug}`}> <a class={style.authorName} href={`/author/${props.author.slug}`}>
{name()} {name()}
</a> </a>
</Show> </Show>
<Show when={!props.hasLink}> <Show when={!props.hasLink}>
<div class="author__name text-3xl text-2xl">{name()}</div> <div class={style.authorName}>{name()}</div>
</Show> </Show>
<Show when={!props.hideDescription}> <Show when={!props.hideDescription}>
<div class="author__about">{bio()}</div> <div class={style.authorAbout}>{bio()}</div>
</Show> </Show>
</div> </div>
<Show when={canFollow()}> <Show when={canFollow()}>
<div class="author__subscribe"> <div class={style.authorSubscribe}>
<Show <Show
when={subscribed()} when={subscribed()}
fallback={ fallback={
<button onClick={() => follow} class="button button--subscribe"> <button
<Icon name="author-subscribe" /> onClick={() => follow}
<span class="button__label">+&nbsp;{t('Follow')}</span> class={clsx('button button--subscribe', style.button, style.buttonSubscribe)}
>
<Icon name="author-subscribe" class={style.icon} />
<span class={style.buttonLabel}>&nbsp;{t('Follow')}</span>
</button> </button>
} }
> >
<button onClick={() => unfollow} class="button button--subscribe"> <button
<Icon name="author-unsubscribe" /> onClick={() => unfollow}
<span class="button__label">-&nbsp;{t('Unfollow')}</span> class={clsx('button button--subscribe', style.button, style.buttonSubscribe)}
>
<Icon name="author-unsubscribe" class={style.icon} />
<span class={style.buttonLabel}>-&nbsp;{t('Unfollow')}</span>
</button> </button>
</Show> </Show>
<Show when={!props.compact}> <Show when={!props.compact}>
<button class="button button--write"> <button class={clsx(style.buttonWrite, style.button, 'button')}>
<Icon name="edit" /> <Icon name="edit" class={style.icon} />
{t('Write')} {t('Write')}
</button> </button>

View File

@ -1,67 +1,6 @@
.user-details { .user-details {
margin-bottom: 4.4rem; margin-bottom: 4.4rem;
padding: 0; padding: 0;
.author__name {
@include font-size(3.4rem);
font-weight: 500;
margin-bottom: 0.2em;
}
.author__about {
color: #696969;
@include font-size(1.7rem);
}
.circlewrap {
margin-right: 4.8rem;
max-width: 168px;
min-width: 168px;
height: 168px;
width: 168px;
}
.circlewrap .userpic {
font-size: 2em;
line-height: 168px;
width: 100%;
}
.author__subscribe {
margin-top: 2rem;
}
.author__details {
display: block;
}
.button--subscribe {
aspect-ratio: auto;
background-color: #000;
border-radius: 2px;
float: none;
padding-bottom: 0.6rem;
padding-top: 0.6rem;
}
.button__label {
display: block;
}
.button--subscribe .icon {
filter: invert(1);
margin-right: 0.5em;
}
.button--subscribe img {
vertical-align: text-top;
}
.button {
margin-right: 1.6rem;
vertical-align: middle;
}
} }
.author-page { .author-page {

View File

@ -7,7 +7,7 @@ export default (props: { author: Author }) => {
<div class="container"> <div class="container">
<div class="row"> <div class="row">
<div class="user-details"> <div class="user-details">
<AuthorCard author={props.author} compact={false} /> <AuthorCard author={props.author} compact={false} isAuthorPage={true} />
</div> </div>
</div> </div>
</div> </div>

View File

@ -33,3 +33,17 @@
} }
} }
} }
.big.circlewrap {
margin-right: 4.8rem;
max-width: 168px;
min-width: 168px;
height: 168px;
width: 168px;
.userpic {
font-size: 2em;
line-height: 168px;
width: 100%;
}
}

View File

@ -1,10 +1,11 @@
import { Show } from 'solid-js/web' import { Show } from 'solid-js/web'
import type { Author } from '../../graphql/types.gen' import type { Author } from '../../graphql/types.gen'
import './Userpic.scss' import style from './Userpic.module.scss'
interface UserpicProps { interface UserpicProps {
user: Author user: Author
hasLink?: boolean hasLink?: boolean
isBig?: boolean
} }
export default (props: UserpicProps) => { export default (props: UserpicProps) => {
@ -15,7 +16,7 @@ export default (props: UserpicProps) => {
} }
return ( return (
<div class="circlewrap"> <div class={style.circlewrap} classList={{ [style.big]: props.isBig }}>
<Show when={props.hasLink}> <Show when={props.hasLink}>
<a href={`/author/${props.user.slug}`}> <a href={`/author/${props.user.slug}`}>
<Show <Show
@ -28,7 +29,7 @@ export default (props: UserpicProps) => {
/> />
} }
> >
<div class="userpic">{letters()}</div> <div class={style.userpic}>{letters()}</div>
</Show> </Show>
</a> </a>
</Show> </Show>
@ -44,7 +45,7 @@ export default (props: UserpicProps) => {
/> />
} }
> >
<div class="userpic">{letters()}</div> <div class={style.userpic}>{letters()}</div>
</Show> </Show>
</Show> </Show>
</div> </div>

View File

@ -1,4 +1,4 @@
.beside-column { .besideColumn {
counter-reset: item; counter-reset: item;
list-style-type: none; list-style-type: none;
padding-left: 0; padding-left: 0;
@ -29,17 +29,6 @@
text-align: center; text-align: center;
width: 2em; width: 2em;
} }
.shout-card--short {
font-size: 1.4rem;
margin-bottom: 0;
.shout-card__title,
.shout-card__subtitle {
display: inline;
@include font-size(1.4rem);
}
}
} }
} }
@ -51,7 +40,7 @@
} }
} }
.beside-column-title { .besideColumnTitle {
align-items: baseline; align-items: baseline;
justify-content: space-between; justify-content: space-between;
display: flex; display: flex;
@ -87,14 +76,14 @@
} }
} }
.beside-column__topic { .besideColumnTopic {
font-size: 1.2rem; font-size: 1.2rem;
letter-spacing: 0.08em; letter-spacing: 0.08em;
margin-bottom: 0.4rem; margin-bottom: 0.4rem;
text-transform: uppercase; text-transform: uppercase;
} }
.beside-column__shout { .besideColumnShout {
font-size: 1.4rem; font-size: 1.4rem;
h4 { h4 {

View File

@ -4,7 +4,7 @@ import { For, Show } from 'solid-js/web'
import { ArticleCard } from './Card' import { ArticleCard } from './Card'
import { AuthorCard } from '../Author/Card' import { AuthorCard } from '../Author/Card'
import { TopicCard } from '../Topic/Card' import { TopicCard } from '../Topic/Card'
import './Beside.scss' import style from './Beside.module.scss'
import type { Author, Shout, Topic, User } from '../../graphql/types.gen' import type { Author, Shout, Topic, User } from '../../graphql/types.gen'
import { Icon } from '../Nav/Icon' import { Icon } from '../Nav/Icon'
import { t } from '../../utils/intl' import { t } from '../../utils/intl'
@ -15,8 +15,10 @@ interface BesideProps {
beside: Shout beside: Shout
wrapper: 'topic' | 'author' | 'article' | 'top-article' wrapper: 'topic' | 'author' | 'article' | 'top-article'
isTopicCompact?: boolean isTopicCompact?: boolean
isTopicInRow?: boolean
topicShortDescription?: boolean topicShortDescription?: boolean
topicsBySlug?: { [slug: string]: Topic } topicsBySlug?: { [slug: string]: Topic }
iconButton?: boolean
} }
export default (props: BesideProps) => { export default (props: BesideProps) => {
@ -27,7 +29,7 @@ export default (props: BesideProps) => {
<Show when={!!props.values}> <Show when={!!props.values}>
<div class="col-md-4"> <div class="col-md-4">
<Show when={!!props.title}> <Show when={!!props.title}>
<div class="beside-column-title"> <div class={style.besideColumnTitle}>
<h4>{props.title}</h4> <h4>{props.title}</h4>
<Show when={props.wrapper === 'author'}> <Show when={props.wrapper === 'author'}>
@ -38,15 +40,17 @@ export default (props: BesideProps) => {
</Show> </Show>
</div> </div>
</Show> </Show>
<ul class="beside-column"> <ul class={style.besideColumn}>
<For each={[...props.values]}> <For each={[...props.values]}>
{(value: Partial<Shout | User | Topic>) => ( {(value: Partial<Shout | User | Topic>) => (
<li classList={{ top: props.wrapper.startsWith('top-') }}> <li classList={{ [style.top]: props.wrapper.startsWith('top-') }}>
<Show when={props.wrapper === 'topic'}> <Show when={props.wrapper === 'topic'}>
<TopicCard <TopicCard
topic={value as Topic} topic={value as Topic}
compact={props.isTopicCompact} compact={props.isTopicCompact}
shortDescription={props.topicShortDescription} shortDescription={props.topicShortDescription}
isTopicInRow={props.isTopicInRow}
iconButton={props.iconButton}
/> />
</Show> </Show>
<Show when={props.wrapper === 'author'}> <Show when={props.wrapper === 'author'}>
@ -58,7 +62,7 @@ export default (props: BesideProps) => {
<Show when={props.wrapper === 'top-article' && value?.slug}> <Show when={props.wrapper === 'top-article' && value?.slug}>
<ArticleCard <ArticleCard
article={value as Shout} article={value as Shout}
settings={{ noimage: true, noauthor: true, nodate: true }} settings={{ noimage: true, noauthor: true, nodate: true, isShort: true }}
/> />
</Show> </Show>
</li> </li>
@ -68,7 +72,7 @@ export default (props: BesideProps) => {
</div> </div>
</Show> </Show>
<div class="col-md-8"> <div class="col-md-8">
<ArticleCard article={props.beside} settings={{}} /> <ArticleCard article={props.beside} settings={{ isBigTitle: true }} />
</div> </div>
</div> </div>
</div> </div>

View File

@ -1,22 +1,12 @@
.shout-card { .shoutCard {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
line-height: 1.2; line-height: 1.2;
margin-bottom: 2.4rem; margin-bottom: 2.4rem;
position: relative; position: relative;
.floor--1 &:nth-child(2) {
border-top: 1px solid #141414;
margin-top: 2.4rem !important;
padding-top: 2.4rem;
.shout-card__cover {
display: none;
}
}
&:hover { &:hover {
.shout-card__cover img { .shoutCardCover img {
transform: scale(1.05); transform: scale(1.05);
} }
} }
@ -26,7 +16,13 @@
} }
} }
.shout-card__titles-container { .shoutCardWithBorder {
border-top: 1px solid #141414;
margin-top: 2.4rem !important;
padding-top: 2.4rem;
}
.shoutCardTitlesContainer {
a { a {
&::before { &::before {
content: ''; content: '';
@ -39,7 +35,7 @@
} }
&:hover { &:hover {
.shout-card__title .shout-card__link-container { .shoutCardTitle .shoutCardLinkContainer {
background-color: #000; background-color: #000;
color: #fff; color: #fff;
} }
@ -47,11 +43,11 @@
} }
} }
.shout-card__cover-container { .shoutCardCoverContainer {
position: relative; position: relative;
} }
.shout-card__cover { .shoutCardCover {
height: 0; height: 0;
margin-bottom: 1.6rem; margin-bottom: 1.6rem;
overflow: hidden; overflow: hidden;
@ -73,25 +69,19 @@
} }
} }
.shout__topic, .shoutAuthor,
.shout__author { .shoutDate {
a {
position: relative;
z-index: 2;
}
}
.shout__author,
.shout__date {
@include font-size(1.2rem); @include font-size(1.2rem);
} }
.shout__author { .shoutAuthor {
margin-right: 1.6rem; margin-right: 1.6rem;
a { a {
border: none; border: none;
color: rgb(0 0 0 / 70%); color: rgb(0 0 0 / 70%);
position: relative;
z-index: 2;
&:hover { &:hover {
color: #fff; color: #fff;
@ -99,15 +89,15 @@
} }
} }
.shout__date { .shoutDate {
color: rgb(0 0 0 / 50%); color: rgb(0 0 0 / 50%);
} }
.shout__details { .shoutDetails {
display: flex; display: flex;
} }
.shout-card__title { .shoutCardTitle {
@include font-size(2.2rem); @include font-size(2.2rem);
font-weight: 700; font-weight: 700;
@ -115,29 +105,33 @@
margin-bottom: 0.8rem; margin-bottom: 0.8rem;
} }
.shout-card__title, .shoutCardTitle,
.shout-card__subtitle { .shoutCardSubtitle {
&, &,
.shout-card__link-container { .shoutCardLinkContainer {
box-decoration-break: clone; box-decoration-break: clone;
/* stylelint-disable-next-line */
-webkit-box-decoration-break: clone;
} }
} }
.shout-card__subtitle { .shoutCardSubtitle {
color: #696969; color: #696969;
@include font-size(1.7rem); @include font-size(1.7rem);
font-weight: 400; font-weight: 400;
line-height: 1.3; line-height: 1.3;
margin-bottom: 0.8rem; margin-bottom: 0.8rem;
transition: color 0.2s, background-color 0.2s, box-shadow 0.2s;
} }
.shout-card__link-container { .shoutCardLinkContainer {
position: relative; position: relative;
transition: color 0.2s, background-color 0.2s, box-shadow 0.2s; transition: color 0.2s, background-color 0.2s, box-shadow 0.2s;
} }
.shout-card__edit-control { .shoutCardEditControl {
border-radius: 2em; border-radius: 2em;
min-height: 2.6em; min-height: 2.6em;
padding: 0 1.4em; padding: 0 1.4em;
@ -149,17 +143,17 @@
} }
} }
.shout-card.withcover { .shoutCard.withcover {
padding: 2.4rem; padding: 2.4rem;
&, &,
a, a,
.shout-card__title, .shoutCardTitle,
.shout-card__subtitle { .shoutCardSubtitle {
color: #fff; color: #fff;
} }
.shout-card__cover { .shoutCardCover {
height: 100%; height: 100%;
left: 0; left: 0;
padding: 0; padding: 0;
@ -178,7 +172,7 @@
} }
} }
.shout-card__type { .shoutCardType {
background: #fff; background: #fff;
border-radius: 100%; border-radius: 100%;
height: 3.2rem; height: 3.2rem;
@ -213,7 +207,7 @@
} }
} }
.shout-card__content { .shoutCardContent {
margin-bottom: 1em; margin-bottom: 1em;
@include media-breakpoint-up(md) { @include media-breakpoint-up(md) {
@ -229,7 +223,7 @@
} }
.col-md-6 .col-md-6 { .col-md-6 .col-md-6 {
.shout-card { .shoutCard {
border-bottom: 1px solid rgb(255 255 255 / 20%); border-bottom: 1px solid rgb(255 255 255 / 20%);
margin: 3.6rem 0 0; margin: 3.6rem 0 0;
padding-bottom: 2rem; padding-bottom: 2rem;
@ -244,71 +238,56 @@
} }
} }
.shout-card__cover-container { .shoutCardCoverContainer {
display: none; display: none;
} }
.shout-card__title, .shoutCardTitle,
.shout-card__subtitle { .shoutCardSubtitle {
display: inline; display: inline;
@include font-size(2.6rem); @include font-size(2.6rem);
line-height: 1.2; line-height: 1.2;
} }
.shout-card__subtitle { .shoutCardSubtitle {
color: #fff; color: #fff;
} }
.shout__author { .shoutAuthor {
margin-top: 0.6em; margin-top: 0.6em;
} }
} }
} }
.floor--important { .shoutCardFloorImportant {
padding-bottom: $container-padding-x;
padding-top: $container-padding-x;
@include media-breakpoint-up(md) {
padding-bottom: $grid-gutter-width;
padding-top: $grid-gutter-width;
}
h2 {
@include font-size(4.4rem);
text-align: center;
}
.shout-card {
margin-bottom: $grid-gutter-width; margin-bottom: $grid-gutter-width;
}
.shout__author { .shoutAuthor {
margin-top: 0.8rem; margin-top: 0.8rem;
}
.col-md-6 { a {
.shout-card__title, color: rgb(255 255 255 / 50%);
.shout-card__subtitle {
display: inline;
@include font-size(2.6rem);
line-height: 1.2;
}
.shout-card__title {
margin-right: 0.3em;
} }
} }
.shout-card__titles-container { .shoutCardTitle {
a {
color: #fff;
}
}
a:hover {
background: #fff;
color: #000 !important;
}
.shoutCardTitlesContainer {
a { a {
color: #fff; color: #fff;
&:hover { &:hover {
.shout-card__title .shout-card__link-container { .shoutCardTitle .shoutCardLinkContainer {
background-color: #fff; background-color: #fff;
color: #000; color: #000;
} }
@ -317,7 +296,7 @@
} }
} }
.shout-card--with-cover { .shoutCardWithCover {
padding: 56.2% 2.4rem 0; padding: 56.2% 2.4rem 0;
@include media-breakpoint-down(sm) { @include media-breakpoint-down(sm) {
@ -325,7 +304,7 @@
} }
&.swiper-slide { &.swiper-slide {
.shout-card__content { .shoutCardContent {
@include media-breakpoint-down(md) { @include media-breakpoint-down(md) {
padding-left: 10%; padding-left: 10%;
} }
@ -334,25 +313,25 @@
&, &,
a, a,
.shout-card__title, .shoutCardTitle,
.shout-card__subtitle { .shoutCardSubtitle {
color: #fff !important; color: #fff !important;
} }
.shout__author, .shoutAuthor,
.shout-card__titles-container { .shoutCardTitlesContainer {
a:hover { a:hover {
&, &,
.shout-card__title .shout-card__link-container { .shoutCardTitle .shoutCardLinkContainer {
background-color: #fff; background-color: #fff;
color: #000 !important; color: #000 !important;
} }
} }
} }
.shout-card__cover-container, .shoutCardCoverContainer,
.shout-card__cover, .shoutCardCover,
.shout-card__content { .shoutCardContent {
height: 100%; height: 100%;
left: 0; left: 0;
margin: 0; margin: 0;
@ -362,7 +341,7 @@
z-index: -1; z-index: -1;
} }
.shout-card__content { .shoutCardContent {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
justify-content: end; justify-content: end;
@ -370,7 +349,7 @@
z-index: 1; z-index: 1;
} }
.shout-card__cover { .shoutCardCover {
padding: 0; padding: 0;
&::after { &::after {
@ -383,43 +362,37 @@
} }
} }
.shout-card__title { .shoutCardTitle {
@include font-size(3.2rem); @include font-size(3.2rem);
} }
} }
.shout-card--content-top { .shoutCardContentTop {
.shout-card__content { .shoutCardContent {
justify-content: start; justify-content: start;
} }
} }
.shout-card--short { .shoutCardPhotoBottom {
.shout-card__title { .shoutCardContent {
@include font-size(1.7rem);
}
}
.shout-card--photo-bottom {
.shout-card__content {
margin-bottom: 1.6rem; margin-bottom: 1.6rem;
} }
.shout-card__cover-container { .shoutCardCoverContainer {
order: 2; order: 2;
} }
} }
.shout-card--feed { .shoutCardFeed {
border-bottom: 1px solid #e8e8e8; border-bottom: 1px solid #e8e8e8;
margin-bottom: 2em; margin-bottom: 2em;
.shout-card__content { .shoutCardContent {
margin-bottom: 0; margin-bottom: 0;
} }
} }
.shout-card__details { .shoutCardDetails {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
flex-wrap: wrap; flex-wrap: wrap;
@ -431,11 +404,11 @@
z-index: 2; z-index: 2;
} }
.shout-card__details-content { .shoutCardDetailsContent {
display: flex; display: flex;
} }
.shout-card__details-item { .shoutCardDetailsTtem {
align-items: center; align-items: center;
display: flex; display: flex;
margin-right: 1.7em; margin-right: 1.7em;
@ -454,7 +427,7 @@
} }
} }
.shout-card__comments { .shoutCardComments {
align-items: center; align-items: center;
display: flex; display: flex;
@ -476,12 +449,12 @@
display: flex; display: flex;
} }
.rating__value { .ratingValue {
font-weight: bold; font-weight: bold;
margin: 0 0.5em; margin: 0 0.5em;
} }
.rating__control { .ratingControl {
align-items: center; align-items: center;
border: 2px solid; border: 2px solid;
border-radius: 100%; border-radius: 100%;
@ -501,20 +474,7 @@
} }
} }
.floor--7 { .shoutCardVertical {
@include media-breakpoint-down(md) {
margin-bottom: 1em;
}
.col-md-6 {
margin-bottom: 1.6em;
@include media-breakpoint-down(md) {
margin-right: 0;
}
}
.shout-card {
aspect-ratio: auto; aspect-ratio: auto;
height: 100%; height: 100%;
margin: 1.6rem 0; margin: 1.6rem 0;
@ -524,9 +484,8 @@
aspect-ratio: 1 / 1.6; aspect-ratio: 1 / 1.6;
padding: 0; padding: 0;
} }
}
.shout-card__title { .shoutCardTitle {
font-size: 2.6rem !important; font-size: 2.6rem !important;
@include media-breakpoint-between(lg, xl) { @include media-breakpoint-between(lg, xl) {
@ -534,11 +493,11 @@
} }
} }
.shout-card__content { .shoutCardContent {
justify-content: start; justify-content: start;
position: relative; position: relative;
.shout-card__subtitle { .shoutCardSubtitle {
@include media-breakpoint-up(lg) { @include media-breakpoint-up(lg) {
@include font-size(2rem); @include font-size(2rem);
} }
@ -552,44 +511,93 @@
.floor--9 { .floor--9 {
/* TODO: refactor these styles */ /* TODO: refactor these styles */
.shout-card__title, .shoutCardTitle,
.shout-card__subtitle { .shoutCardSubtitle {
// display: inline; // display: inline;
font-size: 2.2rem; font-size: 2.2rem;
} }
.shout-card__title { .shoutCardTitle {
padding-right: 0.25em; padding-right: 0.25em;
} }
.shout__author, .shoutAuthor,
.shout__date { .shoutDate {
margin-top: 0.8rem; margin-top: 0.8rem;
} }
.beside-column .shout-card__titles-container { .beside-column .shoutCardTitlesContainer {
position: relative; position: relative;
a:hover { a:hover {
.shout-card__link-container { .shoutCardLinkContainer {
color: #fff; color: #fff;
} }
} }
} }
} }
.col-md-6, .shoutCardBigTitle {
.col-lg-6, .shoutCardTitle {
.col-md-8 {
.shout-card__title {
display: block; display: block;
@include font-size(3.2rem); @include font-size(3.2rem);
padding-right: 0; padding-right: 0;
} }
.shout-card__subtitle { .shoutCardSubtitle {
color: #696969; color: #696969;
@include font-size(2.4rem); @include font-size(2.4rem);
} }
} }
.shoutCardCompact {
.shoutCardTitle,
.shoutCardSubtitle {
display: inline;
@include font-size(2.6rem);
line-height: 1.2;
}
.shoutCardSubtitle {
padding-left: 0.3em;
box-decoration-break: slice;
/* stylelint-disable-next-line */
-webkit-box-decoration-break: slice;
}
a {
color: #fff;
&:hover {
.shoutCardSubtitle {
background-color: #fff;
color: #000;
}
}
}
}
.shoutCardShort {
font-size: 1.4rem;
margin-bottom: 0;
.shoutCardTitle,
.shoutCardSubtitle {
display: inline;
@include font-size(1.4rem);
}
.shoutCardTitle {
padding-right: 0.25em;
}
a:hover {
.shoutCardLinkContainer {
color: #fff;
}
}
}

View File

@ -5,10 +5,12 @@ import type { Shout } from '../../graphql/types.gen'
import { capitalize } from '../../utils' import { capitalize } from '../../utils'
import { translit } from '../../utils/ru2en' import { translit } from '../../utils/ru2en'
import { Icon } from '../Nav/Icon' import { Icon } from '../Nav/Icon'
import './Card.scss' import style from './Card.module.scss'
import { locale } from '../../stores/ui' import { locale } from '../../stores/ui'
import { handleClientRouteLinkClick } from '../../stores/router' import { handleClientRouteLinkClick } from '../../stores/router'
import { getLogger } from '../../utils/logger' import { getLogger } from '../../utils/logger'
import { clsx } from 'clsx'
import CardTopic from './CardTopic'
const log = getLogger('card component') const log = getLogger('card component')
@ -23,6 +25,13 @@ interface ArticleCardProps {
photoBottom?: boolean photoBottom?: boolean
additionalClass?: string additionalClass?: string
isFeedMode?: boolean isFeedMode?: boolean
isFloorImportant?: boolean
isWithCover?: boolean
isBigTitle?: boolean
isVertical?: boolean
isShort?: boolean
withBorder?: boolean
isCompact?: boolean
} }
article: Shout article: Shout
} }
@ -65,56 +74,64 @@ export const ArticleCard = (props: ArticleCardProps) => {
return ( return (
<section <section
class={`shout-card ${props.settings?.additionalClass || ''}`} class={clsx(style.shoutCard, `${props.settings?.additionalClass || ''}`)}
classList={{ classList={{
'shout-card--short': props.settings?.noimage, [style.shoutCardShort]: props.settings?.isShort,
'shout-card--photo-bottom': props.settings?.noimage && props.settings?.photoBottom, [style.shoutCardPhotoBottom]: props.settings?.noimage && props.settings?.photoBottom,
'shout-card--feed': props.settings?.isFeedMode [style.shoutCardFeed]: props.settings?.isFeedMode,
[style.shoutCardFloorImportant]: props.settings?.isFloorImportant,
[style.shoutCardWithCover]: props.settings?.isWithCover,
[style.shoutCardBigTitle]: props.settings?.isBigTitle,
[style.shoutCardVertical]: props.settings?.isVertical,
[style.shoutCardWithBorder]: props.settings?.withBorder,
[style.shoutCardCompact]: props.settings?.isCompact
}} }}
> >
<Show when={!props.settings?.noimage && cover}> <Show when={!props.settings?.noimage && cover}>
<div class="shout-card__cover-container"> <div class={style.shoutCardCoverContainer}>
<div class="shout-card__cover"> <div class={style.shoutCardCover}>
<img src={cover || ''} alt={title || ''} loading="lazy" /> <img src={cover || ''} alt={title || ''} loading="lazy" />
</div> </div>
</div> </div>
</Show> </Show>
<div class="shout-card__content"> <div class={style.shoutCardContent}>
<Show when={layout && layout !== 'article' && !(props.settings?.noicon || props.settings?.noimage)}> <Show when={layout && layout !== 'article' && !(props.settings?.noicon || props.settings?.noimage)}>
<div class="shout-card__type"> <div class={style.shoutCardType}>
<a href={`/topic/${mainTopic.slug}`}> <a href={`/topic/${mainTopic.slug}`}>
<Icon name={layout} /> <Icon name={layout} class={style.icon} />
</a> </a>
</div> </div>
</Show> </Show>
<Show when={!props.settings?.isGroup}> <Show when={!props.settings?.isGroup}>
<div class="shout__topic"> <CardTopic
<a href={`/topic/${mainTopic.slug}`}> title={
{locale() === 'ru' && mainTopic.title ? mainTopic.title : mainTopic.slug.replace('-', ' ')} locale() === 'ru' && mainTopic.title ? mainTopic.title : mainTopic.slug.replace('-', ' ')
</a> }
</div> slug={mainTopic.slug}
isFloorImportant={props.settings?.isFloorImportant}
/>
</Show> </Show>
<div class="shout-card__titles-container"> <div class={style.shoutCardTitlesContainer}>
<a href={`/${slug || ''}`} onClick={handleClientRouteLinkClick}> <a href={`/${slug || ''}`} onClick={handleClientRouteLinkClick}>
<div class="shout-card__title"> <div class={style.shoutCardTitle}>
<span class="shout-card__link-container">{title}</span> <span class={style.shoutCardLinkContainer}>{title}</span>
</div> </div>
<Show when={!props.settings?.nosubtitle && subtitle}> <Show when={!props.settings?.nosubtitle && subtitle}>
<div class="shout-card__subtitle"> <div class={style.shoutCardSubtitle}>
<span class="shout-card__link-container">{subtitle}</span> <span class={style.shoutCardLinkContainer}>{subtitle}</span>
</div> </div>
</Show> </Show>
</a> </a>
</div> </div>
<Show when={!props.settings?.noauthor || !props.settings?.nodate}> <Show when={!props.settings?.noauthor || !props.settings?.nodate}>
<div class="shout__details"> <div class={style.shoutDetails}>
<Show when={!props.settings?.noauthor}> <Show when={!props.settings?.noauthor}>
<div class="shout__author"> <div class={style.shoutAuthor}>
<For each={authors}> <For each={authors}>
{(author, index) => { {(author, index) => {
const name = const name =
@ -134,39 +151,39 @@ export const ArticleCard = (props: ArticleCardProps) => {
</Show> </Show>
<Show when={!props.settings?.nodate}> <Show when={!props.settings?.nodate}>
<div class="shout__date">{formattedDate()}</div> <div class={style.shoutDate}>{formattedDate()}</div>
</Show> </Show>
</div> </div>
</Show> </Show>
<Show when={props.settings?.isFeedMode}> <Show when={props.settings?.isFeedMode}>
<section class="shout-card__details"> <section class={style.shoutCardDetails}>
<div class="shout-card__details-content"> <div class={style.shoutCardDetailsContent}>
<div class="shout-card__details-item rating"> <div class={clsx(style.shoutCardDetailsItem, 'rating')}>
<button class="rating__control">&minus;</button> <button class="rating__control">&minus;</button>
<span class="rating__value">{stat?.rating || ''}</span> <span class="rating__value">{stat?.rating || ''}</span>
<button class="rating__control">+</button> <button class="rating__control">+</button>
</div> </div>
<div class="shout-card__details-item shout-card__comments"> <div class={clsx(style.shoutCardDetailsItem, style.shoutCardComments)}>
<Icon name="eye" /> <Icon name="eye" class={style.icon} />
{stat?.viewed} {stat?.viewed}
</div> </div>
<div class="shout-card__details-item shout-card__comments"> <div class={clsx(style.shoutCardDetailsTtem, style.shoutCardComments)}>
<a href={`/${slug + '#comments' || ''}`}> <a href={`/${slug + '#comments' || ''}`}>
<Icon name="comment" /> <Icon name="comment" class={style.icon} />
{stat?.commented || ''} {stat?.commented || ''}
</a> </a>
</div> </div>
<div class="shout-card__details-item"> <div class={style.shoutCardDetailsItem}>
<button> <button>
<Icon name="bookmark" /> <Icon name="bookmark" class={style.icon} />
</button> </button>
</div> </div>
<div class="shout-card__details-item"> <div class={style.shoutCardDetailsItem}>
<button> <button>
<Icon name="ellipsis" /> <Icon name="ellipsis" class={style.icon} />
</button> </button>
</div> </div>
</div> </div>

View File

@ -0,0 +1,26 @@
.shoutTopic {
font-size: 1.2rem;
letter-spacing: 0.08em;
margin-bottom: 0.8rem;
text-transform: uppercase;
transition: background-color 0.2s;
a {
background: transparent;
border: none;
color: $link-color;
position: relative;
z-index: 2;
&:hover {
background: $link-color;
color: #fff !important;
}
}
}
.shoutTopicFloorImportant {
a {
color: rgb(255 255 255 / 50%);
}
}

View File

@ -0,0 +1,20 @@
import style from './CardTopic.module.scss'
interface CardTopicProps {
title: string
slug: string
isFloorImportant?: boolean
}
export default (props: CardTopicProps) => {
return (
<div
class={style.shoutTopic}
classList={{
[style.shoutTopicFloorImportant]: props.isFloorImportant
}}
>
<a href={`/topic/${props.slug}`}>{props.title}</a>
</div>
)
}

View File

@ -17,7 +17,10 @@ export default (props: GroupProps) => {
<div class="group__header col-12">{props.header}</div> <div class="group__header col-12">{props.header}</div>
<div class="col-lg-6"> <div class="col-lg-6">
<ArticleCard article={props.articles[0]} settings={{ nosubtitle: false, noicon: true }} /> <ArticleCard
article={props.articles[0]}
settings={{ nosubtitle: false, noicon: true, isFloorImportant: true, isBigTitle: true }}
/>
</div> </div>
<div class="col-lg-6"> <div class="col-lg-6">
@ -27,7 +30,10 @@ export default (props: GroupProps) => {
{(a) => ( {(a) => (
<div class="row"> <div class="row">
<div class="col-md-8"> <div class="col-md-8">
<ArticleCard article={a} settings={{ nosubtitle: false, noicon: true }} /> <ArticleCard
article={a}
settings={{ nosubtitle: false, noicon: true, isBigTitle: true }}
/>
</div> </div>
</div> </div>
)} )}
@ -36,12 +42,34 @@ export default (props: GroupProps) => {
<Show when={props.articles.length >= 4}> <Show when={props.articles.length >= 4}>
<div class="col-md-6"> <div class="col-md-6">
<For each={props.articles.slice(1, 3)}> <For each={props.articles.slice(1, 3)}>
{(a) => <ArticleCard article={a} settings={{ noicon: true, noimage: true }} />} {(a) => (
<ArticleCard
article={a}
settings={{
noicon: true,
noimage: true,
isBigTitle: true,
isCompact: true,
isFloorImportant: true
}}
/>
)}
</For> </For>
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<For each={props.articles.slice(3, 5)}> <For each={props.articles.slice(3, 5)}>
{(a) => <ArticleCard article={a} settings={{ noicon: true, noimage: true }} />} {(a) => (
<ArticleCard
article={a}
settings={{
noicon: true,
noimage: true,
isBigTitle: true,
isCompact: true,
isFloorImportant: true
}}
/>
)}
</For> </For>
</div> </div>
</Show> </Show>

View File

@ -21,12 +21,7 @@ export default (props: { articles: Shout[] }) => {
return ( return (
<Show when={!!a}> <Show when={!!a}>
<div class={`col-md-${x[y()][i()]}`}> <div class={`col-md-${x[y()][i()]}`}>
<ArticleCard <ArticleCard article={a} settings={{ isWithCover: x[y()][i()] === '8' }} />
article={a}
settings={{
additionalClass: x[y()][i()] === '8' ? 'shout-card--with-cover' : ''
}}
/>
</div> </div>
</Show> </Show>
) )

View File

@ -10,14 +10,14 @@ export const Row5 = (props: { articles: Shout[] }) => {
<div class="wide-container row"> <div class="wide-container row">
<div class="col-md-3"> <div class="col-md-3">
<ArticleCard article={props.articles[0]} /> <ArticleCard article={props.articles[0]} />
<ArticleCard article={props.articles[1]} /> <ArticleCard article={props.articles[1]} settings={{ noimage: true, withBorder: true }} />
</div> </div>
<div class="col-md-6"> <div class="col-md-6">
<ArticleCard article={props.articles[2]} /> <ArticleCard article={props.articles[2]} settings={{ isBigTitle: true }} />
</div> </div>
<div class="col-md-3"> <div class="col-md-3">
<ArticleCard article={props.articles[3]} /> <ArticleCard article={props.articles[3]} />
<ArticleCard article={props.articles[4]} /> <ArticleCard article={props.articles[4]} settings={{ noimage: true, withBorder: true }} />
</div> </div>
</div> </div>
</div> </div>

View File

@ -10,7 +10,12 @@ export default (props: { articles: Shout[] }) => (
<div class="col-md-6 col-lg-3"> <div class="col-md-6 col-lg-3">
<ArticleCard <ArticleCard
article={a} article={a}
settings={{ additionalClass: 'shout-card--with-cover shout-card--content-top' }} settings={{
additionalClass: 'shout-card--content-top',
isWithCover: true,
isBigTitle: true,
isVertical: true
}}
/> />
</div> </div>
)} )}

View File

@ -1,17 +1,3 @@
.floor--slider {
.shout-card {
.shout-card__cover-container {
z-index: 1;
}
.shout-card__cover {
&::after {
background: linear-gradient(0deg, rgb(0 0 0 / 80%) 0%, rgb(0 0 0 / 0%) 75%);
}
}
}
}
.swiper-slide { .swiper-slide {
height: 0 !important; height: 0 !important;
min-height: 0 !important; min-height: 0 !important;

View File

@ -60,7 +60,12 @@ export default (props: SliderProps) => {
{(a: Shout) => ( {(a: Shout) => (
<ArticleCard <ArticleCard
article={a} article={a}
settings={{ additionalClass: 'shout-card--with-cover swiper-slide' }} settings={{
additionalClass: 'swiper-slide',
isFloorImportant: true,
isWithCover: true,
nodate: true
}}
/> />
)} )}
</For> </For>

View File

@ -18,11 +18,6 @@ export default () => {
<Icon name="pencil" /> <Icon name="pencil" />
</a> </a>
</div> </div>
<div class={clsx(styles.userControlItem, styles.userControlItemSearch)}>
<a href="/search">
<Icon name="search" />
</a>
</div>
<div class={clsx(styles.userControlItem, styles.userControlItemInbox)}> <div class={clsx(styles.userControlItem, styles.userControlItemInbox)}>
<a href="/inbox"> <a href="/inbox">
{/*FIXME: replace with route*/} {/*FIXME: replace with route*/}

View File

@ -7,7 +7,7 @@
margin-left: 0; margin-left: 0;
} }
.topic-details__item { .topicDetailsItem {
margin-bottom: 1.2rem; margin-bottom: 1.2rem;
@include media-breakpoint-up(md) { @include media-breakpoint-up(md) {
@ -17,14 +17,28 @@
} }
} }
.topic-title { .topicInRow {
align-items: center;
display: flex;
justify-content: space-between;
button {
margin-top: 0;
}
.topicTitle {
margin-bottom: 0;
}
}
.topicTitle {
font-weight: bold; font-weight: bold;
@include font-size(1.7rem); @include font-size(1.7rem);
margin-bottom: 0.8rem; margin-bottom: 0.8rem;
} }
.topic__avatar { .topicAvatar {
border-radius: 100%; border-radius: 100%;
height: 64px; height: 64px;
margin-right: 1.2rem; margin-right: 1.2rem;
@ -41,7 +55,7 @@
} }
} }
.topic-description { .topicDescription {
@include font-size(1.5rem); @include font-size(1.5rem);
color: #696969; color: #696969;
@ -52,14 +66,14 @@
} }
} }
.topic-description--short { .topicDescriptionShort {
display: box; display: block;
-webkit-line-clamp: 3; -webkit-line-clamp: 3;
-webkit-box-orient: vertical; -webkit-box-orient: vertical;
overflow: hidden; overflow: hidden;
} }
.topic-details { .topicDetails {
@include font-size(1.7rem); @include font-size(1.7rem);
color: #9fa1a7; color: #9fa1a7;
@ -70,7 +84,7 @@
} }
} }
.topic-details__item { .topicDetailsItem {
margin-right: 1.6rem; margin-right: 1.6rem;
white-space: nowrap; white-space: nowrap;

View File

@ -1,6 +1,6 @@
import { capitalize, plural } from '../../utils' import { capitalize, plural } from '../../utils'
import { Show } from 'solid-js/web' import { Show } from 'solid-js/web'
import './Card.scss' import style from './Card.module.scss'
import { createMemo } from 'solid-js' import { createMemo } from 'solid-js'
import type { Topic } from '../../graphql/types.gen' import type { Topic } from '../../graphql/types.gen'
import { FollowingEntity } from '../../graphql/types.gen' import { FollowingEntity } from '../../graphql/types.gen'
@ -9,6 +9,7 @@ import { locale } from '../../stores/ui'
import { useAuthStore } from '../../stores/auth' import { useAuthStore } from '../../stores/auth'
import { follow, unfollow } from '../../stores/zine/common' import { follow, unfollow } from '../../stores/zine/common'
import { getLogger } from '../../utils/logger' import { getLogger } from '../../utils/logger'
import { Icon } from '../Nav/Icon'
const log = getLogger('TopicCard') const log = getLogger('TopicCard')
@ -18,6 +19,9 @@ interface TopicProps {
subscribed?: boolean subscribed?: boolean
shortDescription?: boolean shortDescription?: boolean
subscribeButtonBottom?: boolean subscribeButtonBottom?: boolean
additionalClass?: string
isTopicInRow?: boolean
iconButton?: boolean
} }
export const TopicCard = (props: TopicProps) => { export const TopicCard = (props: TopicProps) => {
@ -40,15 +44,21 @@ export const TopicCard = (props: TopicProps) => {
} }
} }
return ( return (
<div class="topic" classList={{ row: !props.compact && !props.subscribeButtonBottom }}> <div
class={style.topic}
classList={{
row: !props.compact && !props.subscribeButtonBottom,
[style.topicInRow]: props.isTopicInRow
}}
>
<div classList={{ 'col-md-7': !props.compact && !props.subscribeButtonBottom }}> <div classList={{ 'col-md-7': !props.compact && !props.subscribeButtonBottom }}>
<Show when={props.topic.title}> <Show when={props.topic.title}>
<div class="topic-title"> <div class={style.topicTitle}>
<a href={`/topic/${props.topic.slug}`}>{capitalize(props.topic.title || '')}</a> <a href={`/topic/${props.topic.slug}`}>{capitalize(props.topic.title || '')}</a>
</div> </div>
</Show> </Show>
<Show when={props.topic.pic}> <Show when={props.topic.pic}>
<div class="topic__avatar"> <div class={style.topicAvatar}>
<a href={props.topic.slug}> <a href={props.topic.slug}>
<img src={props.topic.pic} alt={props.topic.title} /> <img src={props.topic.pic} alt={props.topic.title} />
</a> </a>
@ -56,15 +66,18 @@ export const TopicCard = (props: TopicProps) => {
</Show> </Show>
<Show when={!props.compact && props.topic?.body}> <Show when={!props.compact && props.topic?.body}>
<div class="topic-description" classList={{ 'topic-description--short': props.shortDescription }}> <div
class={style.topicDescription}
classList={{ 'topic-description--short': props.shortDescription }}
>
{props.topic.body} {props.topic.body}
</div> </div>
</Show> </Show>
<Show when={props.topic?.stat}> <Show when={props.topic?.stat}>
<div class="topic-details"> <div class={style.topicDetails}>
<Show when={!props.compact}> <Show when={!props.compact}>
<span class="topic-details__item" classList={{ compact: props.compact }}> <span class={style.topicDetailsTtem} classList={{ compact: props.compact }}>
{props.topic.stat?.shouts + {props.topic.stat?.shouts +
' ' + ' ' +
t('post') + t('post') +
@ -73,7 +86,7 @@ export const TopicCard = (props: TopicProps) => {
locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's'] locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's']
)} )}
</span> </span>
<span class="topic-details__item" classList={{ compact: props.compact }}> <span class={style.topicDetailsTtem} classList={{ compact: props.compact }}>
{props.topic.stat?.authors + {props.topic.stat?.authors +
' ' + ' ' +
t('author') + t('author') +
@ -82,7 +95,7 @@ export const TopicCard = (props: TopicProps) => {
locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's'] locale() === 'ru' ? ['ов', '', 'а'] : ['s', '', 's']
)} )}
</span> </span>
<span class="topic-details__item" classList={{ compact: props.compact }}> <span class={style.topicDetailsItem} classList={{ compact: props.compact }}>
{props.topic.stat?.followers + {props.topic.stat?.followers +
' ' + ' ' +
t('follower') + t('follower') +
@ -121,12 +134,16 @@ export const TopicCard = (props: TopicProps) => {
when={subscribed()} when={subscribed()}
fallback={ fallback={
<button onClick={() => subscribe(true)} class="button--light"> <button onClick={() => subscribe(true)} class="button--light">
+&nbsp;{t('Follow')} <Show when={props.iconButton}>{/*<Icon name={}/>*/}</Show>
<Show when={!props.iconButton}>+&nbsp;{t('Follow')}</Show>
</button> </button>
} }
> >
<button onClick={() => subscribe(false)} class="button--light"> <button onClick={() => subscribe(false)} class="button--light">
-&nbsp;{t('Unfollow')} <Show when={props.iconButton}>{/*<Icon name={}/>*/}</Show>
<Show when={!props.iconButton}>-&nbsp;{t('Unfollow')}</Show>
</button> </button>
</Show> </Show>
</div> </div>

View File

@ -82,7 +82,6 @@ export const AuthorView = (props: AuthorProps) => {
</div> </div>
</div> </div>
<div class="floor">
<h3 class="col-12">{title()}</h3> <h3 class="col-12">{title()}</h3>
<div class="row"> <div class="row">
<Show when={sortedArticles().length > 0}> <Show when={sortedArticles().length > 0}>
@ -92,13 +91,24 @@ export const AuthorView = (props: AuthorProps) => {
beside={sortedArticles()[0]} beside={sortedArticles()[0]}
wrapper={'topic'} wrapper={'topic'}
topicShortDescription={true} topicShortDescription={true}
isTopicCompact={true}
isTopicInRow={true}
iconButton={true}
/> />
<Row3 articles={sortedArticles().slice(1, 4)} /> <Row3 articles={sortedArticles().slice(1, 4)} />
<Show when={sortedArticles().length > 4}>
<Row2 articles={sortedArticles().slice(4, 6)} /> <Row2 articles={sortedArticles().slice(4, 6)} />
</Show>
<Show when={sortedArticles().length > 6}>
<Row3 articles={sortedArticles().slice(6, 9)} /> <Row3 articles={sortedArticles().slice(6, 9)} />
</Show>
<Show when={sortedArticles().length > 9}>
<Row3 articles={sortedArticles().slice(9, 12)} /> <Row3 articles={sortedArticles().slice(9, 12)} />
</Show> </Show>
</div> </Show>
</div> </div>
</Show> </Show>
</div> </div>

View File

@ -85,7 +85,10 @@ export const TopicView = (props: TopicProps) => {
<For each={sortedArticles().slice(0, 6)}> <For each={sortedArticles().slice(0, 6)}>
{(article) => ( {(article) => (
<div class="col-md-6"> <div class="col-md-6">
<ArticleCard article={article} /> <ArticleCard
article={article}
settings={{ isFloorImportant: true, isBigTitle: true }}
/>
</div> </div>
)} )}
</For> </For>

View File

@ -211,7 +211,7 @@ button {
font-weight: 400; font-weight: 400;
margin-top: 0.6rem; margin-top: 0.6rem;
padding: 0.6rem 1.2rem 1rem 1rem; padding: 0.6rem 1.2rem 0.6rem 1rem;
} }
form { form {
@ -461,29 +461,48 @@ figcaption {
} }
} }
.floor--7 {
@include media-breakpoint-down(md) {
margin-bottom: 1em;
}
.col-md-6 {
margin-bottom: 1.6em;
@include media-breakpoint-down(md) {
margin-right: 0;
}
}
}
.floor--important { .floor--important {
background: #000; background: #000;
color: #fff; color: #fff;
padding: $grid-gutter-width 0; padding: $grid-gutter-width 0;
padding-bottom: $container-padding-x;
padding-top: $container-padding-x;
@include media-breakpoint-up(md) {
padding-bottom: $grid-gutter-width;
padding-top: $grid-gutter-width;
}
h2 {
@include font-size(4.4rem);
text-align: center;
}
@include media-breakpoint-down(md) { @include media-breakpoint-down(md) {
margin-bottom: 5rem; margin-bottom: 5rem;
} }
.all-materials, .all-materials {
.shout-card__title {
a { a {
color: #fff; color: #fff;
} }
} }
.shout__topic,
.shout__author {
a {
color: rgb(255 255 255 / 50%);
}
}
a:hover { a:hover {
background: #fff; background: #fff;
color: #000 !important; color: #000 !important;
@ -504,25 +523,6 @@ figcaption {
} }
} }
.shout__topic {
font-size: 1.2rem;
letter-spacing: 0.08em;
margin-bottom: 0.8rem;
text-transform: uppercase;
transition: background-color 0.2s;
a {
background: transparent;
border: none;
color: $link-color;
&:hover {
background: $link-color;
color: #fff !important;
}
}
}
/* stylelint-disable-next-line */ /* stylelint-disable-next-line */
astro-island { astro-island {
display: flex !important; display: flex !important;