slider-as-wrapper
This commit is contained in:
parent
7a97e8303d
commit
a3f63e0da0
|
@ -11,6 +11,7 @@ import { deleteReaction } from '../../stores/zine/reactions'
|
|||
import { formatDate } from '../../utils'
|
||||
import { SharePopup } from './SharePopup'
|
||||
import stylesHeader from '../Nav/Header.module.scss'
|
||||
import Userpic from '../Author/Userpic'
|
||||
|
||||
export default (props: {
|
||||
level?: number
|
||||
|
@ -40,16 +41,11 @@ export default (props: {
|
|||
<Show
|
||||
when={!props.compact}
|
||||
fallback={
|
||||
<div class={styles.commentDetails}>
|
||||
<a href={`/author/${comment()?.createdBy?.slug}`}>
|
||||
@{(comment()?.createdBy || { name: 'anonymous' }).name}
|
||||
</a>
|
||||
<div class={styles.commentArticle}>
|
||||
<Icon name="reply-arrow" />
|
||||
<a href={`#comment-${comment()?.id}`}>
|
||||
#{(comment()?.shout || { title: 'Lorem ipsum titled' }).title}
|
||||
</a>
|
||||
</div>
|
||||
<div>
|
||||
<Userpic user={comment().createdBy as Author} isBig={false} isAuthorsList={false} />
|
||||
<small class={styles.commentArticle}>
|
||||
<a href={`#comment-${comment()?.id}`}>{comment()?.shout.title || ''}</a>
|
||||
</small>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
|
@ -141,9 +137,9 @@ export default (props: {
|
|||
<textarea name="reply" id="reply" rows="5"></textarea>
|
||||
<div class={styles.replyFormControls}>
|
||||
<button class="button button--light" onClick={() => setIsReplyVisible(false)}>
|
||||
Отмена
|
||||
{t('Cancel')}
|
||||
</button>
|
||||
<button class="button">Отправить</button>
|
||||
<button class="button">{t('Send')}</button>
|
||||
</div>
|
||||
</form>
|
||||
</Show>
|
||||
|
|
|
@ -14,6 +14,7 @@ import { clsx } from 'clsx'
|
|||
import { CommentsTree } from './CommentsTree'
|
||||
import { useSession } from '../../context/session'
|
||||
import VideoPlayer from './VideoPlayer'
|
||||
import Slider from '../_shared/Slider'
|
||||
|
||||
interface ArticleProps {
|
||||
article: Shout
|
||||
|
@ -29,13 +30,7 @@ interface MediaItem {
|
|||
const MediaView = (props: { media: MediaItem; kind: Shout['layout'] }) => {
|
||||
return (
|
||||
<>
|
||||
<Switch
|
||||
fallback={
|
||||
<picture>
|
||||
<source src={props.media.url} />
|
||||
</picture>
|
||||
}
|
||||
>
|
||||
<Switch fallback={<a href={props.media.url}>{t('Cannot show this media type')}</a>}>
|
||||
<Match when={props.kind === 'audio'}>
|
||||
<div>
|
||||
<h5>{props.media.title}</h5>
|
||||
|
@ -116,7 +111,21 @@ export const FullArticle = (props: ArticleProps) => {
|
|||
<div class={styles.shoutCover} style={{ 'background-image': `url('${props.article.cover}')` }} />
|
||||
</div>
|
||||
|
||||
<Show when={media()}>
|
||||
<Show
|
||||
when={media() && props.article.layout !== 'image'}
|
||||
fallback={
|
||||
<Slider>
|
||||
<For each={media() || []}>
|
||||
{(m: MediaItem) => (
|
||||
<>
|
||||
<img src={m.url || m.pic} alt={m.title} />
|
||||
<div innerHTML={m.body} />
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
}
|
||||
>
|
||||
<div class="media-items">
|
||||
<For each={media() || []}>
|
||||
{(m: MediaItem) => (
|
||||
|
@ -148,7 +157,7 @@ export const FullArticle = (props: ArticleProps) => {
|
|||
<Show when={props.article.stat?.viewed}>
|
||||
<div class={clsx(styles.shoutStatsItem)}>
|
||||
<Icon name="eye" class={styles.icon} />
|
||||
<sup>{props.article.stat?.viewed}</sup>
|
||||
{props.article.stat?.viewed}
|
||||
</div>
|
||||
</Show>
|
||||
|
||||
|
|
|
@ -33,9 +33,6 @@ export const AuthorCard = (props: AuthorCardProps) => {
|
|||
() => session()?.news?.authors?.some((u) => u === props.author.slug) || false
|
||||
)
|
||||
const canFollow = createMemo(() => !props.hideFollow && session()?.user?.slug !== props.author.slug)
|
||||
const bio = createMemo(() => {
|
||||
return props.caption || props.author.bio || t('Our regular contributor')
|
||||
})
|
||||
|
||||
const name = () => {
|
||||
return props.author.name === 'Дискурс' && locale() !== 'ru'
|
||||
|
@ -76,7 +73,7 @@ export const AuthorCard = (props: AuthorCardProps) => {
|
|||
<div
|
||||
class={styles.authorAbout}
|
||||
classList={{ 'text-truncate': props.truncateBio }}
|
||||
innerHTML={props.caption || bio()}
|
||||
innerHTML={props.author.bio}
|
||||
></div>
|
||||
</Show>
|
||||
</div>
|
||||
|
|
|
@ -51,6 +51,7 @@ export default (props: UserpicProps) => {
|
|||
src={props.user.userpic || '/icons/user-default.svg'}
|
||||
alt={props.user.name || ''}
|
||||
classList={{ anonymous: !props.user.userpic }}
|
||||
loading="lazy"
|
||||
/>
|
||||
}
|
||||
>
|
||||
|
|
|
@ -20,6 +20,11 @@
|
|||
a {
|
||||
border: none;
|
||||
}
|
||||
|
||||
.icon {
|
||||
height: 1.2em;
|
||||
width: 1.2em;
|
||||
}
|
||||
}
|
||||
|
||||
.shoutCardWithBorder {
|
||||
|
|
|
@ -13,9 +13,10 @@ import { t } from '../../utils/intl'
|
|||
import { Row3 } from '../Feed/Row3'
|
||||
import { Row2 } from '../Feed/Row2'
|
||||
import { Beside } from '../Feed/Beside'
|
||||
import Slider from '../Feed/Slider'
|
||||
import Slider from '../_shared/Slider'
|
||||
import { Row1 } from '../Feed/Row1'
|
||||
import styles from '../../styles/Topic.module.scss'
|
||||
import { ArticleCard } from '../Feed/Card'
|
||||
|
||||
export const PRERENDERED_ARTICLES_COUNT = 21
|
||||
const LOAD_MORE_PAGE_SIZE = 9 // Row3 + Row3 + Row3
|
||||
|
@ -106,7 +107,21 @@ export const LayoutShoutsPage = (props: PageProps) => {
|
|||
<ModeSwitcher />
|
||||
<Row1 article={sortedArticles()[0]} />
|
||||
<Row2 articles={sortedArticles().slice(1, 3)} />
|
||||
<Slider title={title()} articles={sortedArticles().slice(5, 11)} />
|
||||
<Slider title={title()}>
|
||||
<For each={sortedArticles().slice(5, 11)}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: true,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
<Beside
|
||||
beside={sortedArticles()[12]}
|
||||
title={t('Top viewed')}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
import { createEffect, createMemo, createSignal, For, onMount, Show } from 'solid-js'
|
||||
import type { Author } from '../../graphql/types.gen'
|
||||
import { AuthorCard } from '../Author/Card'
|
||||
import { t } from '../../utils/intl'
|
||||
import { useAuthorsStore, setAuthorsSort } from '../../stores/zine/authors'
|
||||
import { AuthorsSortBy, setAuthorsSort, useAuthorsStore } from '../../stores/zine/authors'
|
||||
import { useRouter } from '../../stores/router'
|
||||
import styles from '../../styles/AllTopics.module.scss'
|
||||
import { AuthorCard } from '../Author/Card'
|
||||
import { clsx } from 'clsx'
|
||||
import { useSession } from '../../context/session'
|
||||
import { locale } from '../../stores/ui'
|
||||
import { translit } from '../../utils/ru2en'
|
||||
import styles from '../../styles/AllTopics.module.scss'
|
||||
import { SearchField } from '../_shared/SearchField'
|
||||
import { scrollHandler } from '../../utils/scroll'
|
||||
import { StatMetrics } from '../_shared/StatMetrics'
|
||||
|
@ -17,19 +17,20 @@ type AllAuthorsPageSearchParams = {
|
|||
by: '' | 'name' | 'shouts' | 'followers'
|
||||
}
|
||||
|
||||
type Props = {
|
||||
type AllAuthorsViewProps = {
|
||||
authors: Author[]
|
||||
}
|
||||
|
||||
const PAGE_SIZE = 20
|
||||
const ALPHABET = [...'@АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ']
|
||||
|
||||
export const AllAuthorsView = (props: Props) => {
|
||||
export const AllAuthorsView = (props: AllAuthorsViewProps) => {
|
||||
const [limit, setLimit] = createSignal(PAGE_SIZE)
|
||||
const { searchParams, changeSearchParam } = useRouter<AllAuthorsPageSearchParams>()
|
||||
const { searchParams, changeSearchParam } = useRouter()
|
||||
const [filterResults, setFilterResults] = createSignal<Author[]>([])
|
||||
const { sortedAuthors } = useAuthorsStore({
|
||||
authors: props.authors,
|
||||
sortBy: searchParams().by || 'name'
|
||||
sortBy: (searchParams().by || 'shouts') as AuthorsSortBy
|
||||
})
|
||||
|
||||
const { session } = useSession()
|
||||
|
@ -41,13 +42,11 @@ export const AllAuthorsView = (props: Props) => {
|
|||
}
|
||||
})
|
||||
createEffect(() => {
|
||||
setAuthorsSort(searchParams().by || 'shouts')
|
||||
setFilteredAuthors(sortedAuthors())
|
||||
setAuthorsSort((searchParams().by || 'shouts') as AuthorsSortBy)
|
||||
setFilterResults(sortedAuthors())
|
||||
setLimit(PAGE_SIZE)
|
||||
})
|
||||
|
||||
const subscribed = (s) => Boolean(session()?.news?.authors && session()?.news?.authors?.includes(s || ''))
|
||||
|
||||
const byLetter = createMemo<{ [letter: string]: Author[] }>(() => {
|
||||
return sortedAuthors().reduce((acc, author) => {
|
||||
let letter = author.name.trim().split(' ').pop().at(0).toUpperCase()
|
||||
|
@ -64,6 +63,39 @@ export const AllAuthorsView = (props: Props) => {
|
|||
return keys
|
||||
})
|
||||
|
||||
const subscribed = (s) => Boolean(session()?.news?.authors && session()?.news?.authors?.includes(s || ''))
|
||||
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
const filterAuthors = (value) => {
|
||||
/* very stupid filter by string algorithm with no deps */
|
||||
let q = value.toLowerCase()
|
||||
if (q.length > 0) {
|
||||
setFilterResults([])
|
||||
if (locale() === 'ru') q = translit(q, 'ru')
|
||||
const aaa: Author[] = sortedAuthors()
|
||||
sortedAuthors().forEach((author) => {
|
||||
let flag = false
|
||||
author.slug.split('-').forEach((w) => {
|
||||
if (w.startsWith(q)) flag = true
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
let wrds: string = author.name.toLowerCase()
|
||||
if (locale() === 'ru') wrds = translit(wrds, 'ru')
|
||||
wrds.split(' ').forEach((w: string) => {
|
||||
if (w.startsWith(q)) flag = true
|
||||
})
|
||||
}
|
||||
|
||||
if (!flag && aaa.includes(author)) {
|
||||
const idx = aaa.indexOf(author)
|
||||
aaa.splice(idx, 1)
|
||||
}
|
||||
})
|
||||
setFilterResults(aaa)
|
||||
}
|
||||
}
|
||||
|
||||
const showMore = () => setLimit((oldLimit) => oldLimit + PAGE_SIZE)
|
||||
const AllAuthorsHead = () => (
|
||||
<div class="row">
|
||||
|
@ -76,54 +108,24 @@ export const AllAuthorsView = (props: Props) => {
|
|||
<a href="/authors?by=shouts">{t('By shouts')}</a>
|
||||
</li>
|
||||
<li classList={{ selected: searchParams().by === 'followers' }}>
|
||||
<a href="/authors?by=followers">{t('By rating')}</a>
|
||||
<a href="/authors?by=followers">{t('By popularity')}</a>
|
||||
</li>
|
||||
<li classList={{ selected: !searchParams().by || searchParams().by === 'name' }}>
|
||||
<li classList={{ selected: searchParams().by === 'name' }}>
|
||||
<a href="/authors?by=name">{t('By name')}</a>
|
||||
</li>
|
||||
<li class="view-switcher__search">
|
||||
<Show when={searchParams().by !== 'name'}>
|
||||
<li class="view-switcher__search">
|
||||
<SearchField onChange={filterAuthors} />
|
||||
</li>
|
||||
</li>
|
||||
</Show>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
const [filteredAuthors, setFilteredAuthors] = createSignal<Author[]>([])
|
||||
// eslint-disable-next-line sonarjs/cognitive-complexity
|
||||
const filterAuthors = (value) => {
|
||||
/* very stupid search algorithm with no deps */
|
||||
let q = value.toLowerCase()
|
||||
if (q.length > 0) {
|
||||
setFilteredAuthors([])
|
||||
if (locale() === 'ru') q = translit(q, 'ru')
|
||||
const aaa: Author[] = sortedAuthors()
|
||||
sortedAuthors().forEach((a) => {
|
||||
let flag = false
|
||||
a.slug.split('-').forEach((w) => {
|
||||
if (w.startsWith(q)) flag = true
|
||||
})
|
||||
|
||||
if (!flag) {
|
||||
let wrds: string = a.name.toLowerCase()
|
||||
if (locale() === 'ru') wrds = translit(wrds, 'ru')
|
||||
wrds.split(' ').forEach((w: string) => {
|
||||
if (w.startsWith(q)) flag = true
|
||||
})
|
||||
}
|
||||
|
||||
if (!flag && aaa.includes(a)) {
|
||||
const idx = aaa.indexOf(a)
|
||||
aaa.splice(idx, 1)
|
||||
}
|
||||
})
|
||||
setFilteredAuthors(aaa)
|
||||
}
|
||||
}
|
||||
return (
|
||||
<div class={clsx(styles.allTopicsPage, 'wide-container')}>
|
||||
<Show when={sortedAuthors().length > 0 || filteredAuthors().length > 0}>
|
||||
<Show when={sortedAuthors().length > 0}>
|
||||
<div class="shift-content">
|
||||
<AllAuthorsHead />
|
||||
|
||||
|
@ -132,7 +134,7 @@ export const AllAuthorsView = (props: Props) => {
|
|||
<div class="col-lg-10 col-xl-9">
|
||||
<ul class={clsx('nodash', styles.alphabet)}>
|
||||
<For each={ALPHABET}>
|
||||
{(letter: string, index) => (
|
||||
{(letter, index) => (
|
||||
<li>
|
||||
<Show when={letter in byLetter()} fallback={letter}>
|
||||
<a
|
||||
|
@ -176,27 +178,22 @@ export const AllAuthorsView = (props: Props) => {
|
|||
</For>
|
||||
</Show>
|
||||
|
||||
<Show when={searchParams().by && searchParams().by !== 'name'}>
|
||||
<div class={clsx(styles.stats, 'row')}>
|
||||
<div class="col-lg-10 col-xl-9">
|
||||
<For each={filteredAuthors().slice(0, limit())}>
|
||||
{(author) => (
|
||||
<>
|
||||
<AuthorCard
|
||||
author={author}
|
||||
compact={false}
|
||||
hasLink={true}
|
||||
subscribed={subscribed(author.slug)}
|
||||
noSocialButtons={true}
|
||||
isAuthorsList={true}
|
||||
truncateBio={true}
|
||||
/>
|
||||
<StatMetrics fields={['shouts', 'followers', 'comments']} stat={author.stat} />
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
</div>
|
||||
<Show when={searchParams().by && searchParams().by !== 'title'}>
|
||||
<For each={filterResults().slice(0, limit())}>
|
||||
{(author) => (
|
||||
<>
|
||||
<AuthorCard
|
||||
author={author}
|
||||
hasLink={true}
|
||||
subscribed={subscribed(author.slug)}
|
||||
noSocialButtons={true}
|
||||
isAuthorsList={true}
|
||||
truncateBio={true}
|
||||
/>
|
||||
<StatMetrics fields={['shouts', 'followers', 'comments']} stat={author.stat} />
|
||||
</>
|
||||
)}
|
||||
</For>
|
||||
</Show>
|
||||
|
||||
<Show when={sortedAuthors().length > limit() && searchParams().by !== 'name'}>
|
||||
|
|
|
@ -8,7 +8,7 @@ import { Row1 } from '../Feed/Row1'
|
|||
import Hero from '../Discours/Hero'
|
||||
import { Beside } from '../Feed/Beside'
|
||||
import RowShort from '../Feed/RowShort'
|
||||
import Slider from '../Feed/Slider'
|
||||
import Slider from '../_shared/Slider'
|
||||
import Group from '../Feed/Group'
|
||||
import type { Shout, Topic } from '../../graphql/types.gen'
|
||||
import { t } from '../../utils/intl'
|
||||
|
@ -18,6 +18,7 @@ import { useTopAuthorsStore } from '../../stores/zine/topAuthors'
|
|||
import { locale } from '../../stores/ui'
|
||||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||
import { splitToPages } from '../../utils/splitToPages'
|
||||
import { ArticleCard } from '../Feed/Card'
|
||||
|
||||
type HomeProps = {
|
||||
randomTopics: Topic[]
|
||||
|
@ -120,7 +121,21 @@ export const HomeView = (props: HomeProps) => {
|
|||
wrapper={'author'}
|
||||
/>
|
||||
|
||||
<Slider title={t('Top month articles')} articles={topMonthArticles()} />
|
||||
<Slider title={t('Top month articles')}>
|
||||
<For each={topMonthArticles()}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: true,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
|
||||
<Row2 articles={sortedArticles().slice(10, 12)} />
|
||||
|
||||
|
@ -132,7 +147,21 @@ export const HomeView = (props: HomeProps) => {
|
|||
|
||||
{randomLayout()}
|
||||
|
||||
<Slider title={t('Favorite')} articles={topArticles()} />
|
||||
<Slider title={t('Favorite')}>
|
||||
<For each={topArticles()}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: true,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
|
||||
<Beside
|
||||
beside={sortedArticles()[20]}
|
||||
|
|
|
@ -13,8 +13,9 @@ import { useAuthorsStore } from '../../stores/zine/authors'
|
|||
import { restoreScrollPosition, saveScrollPosition } from '../../utils/scroll'
|
||||
import { splitToPages } from '../../utils/splitToPages'
|
||||
import { clsx } from 'clsx'
|
||||
import Slider from '../Feed/Slider'
|
||||
import Slider from '../_shared/Slider'
|
||||
import { Row1 } from '../Feed/Row1'
|
||||
import { ArticleCard } from '../Feed/Card'
|
||||
|
||||
type TopicsPageSearchParams = {
|
||||
by: 'comments' | '' | 'recent' | 'viewed' | 'rating' | 'commented'
|
||||
|
@ -122,7 +123,21 @@ export const TopicView = (props: TopicProps) => {
|
|||
wrapper={'author'}
|
||||
/>
|
||||
|
||||
<Slider title={title()} articles={sortedArticles().slice(5, 11)} />
|
||||
<Slider title={title()}>
|
||||
<For each={sortedArticles().slice(5, 11)}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: true,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
|
||||
<Beside
|
||||
beside={sortedArticles()[12]}
|
||||
|
@ -134,12 +149,21 @@ export const TopicView = (props: TopicProps) => {
|
|||
<Row2 articles={sortedArticles().slice(13, 15)} isEqual={true} />
|
||||
<Row1 article={sortedArticles()[15]} />
|
||||
|
||||
<Slider
|
||||
title={title()}
|
||||
articles={sortedArticles().slice(16, 22)}
|
||||
slidesPerView={3}
|
||||
isCardsWithCover={false}
|
||||
/>
|
||||
<Slider slidesPerView={3} title={title()}>
|
||||
<For each={sortedArticles().slice(16, 22)}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: false,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</Slider>
|
||||
|
||||
<Row3 articles={sortedArticles().slice(23, 26)} />
|
||||
<Row2 articles={sortedArticles().slice(26, 28)} />
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
import { ArticleCard } from './Card'
|
||||
import { Swiper, Navigation, Pagination } from 'swiper'
|
||||
import type { SwiperOptions } from 'swiper'
|
||||
import 'swiper/scss'
|
||||
|
@ -6,14 +5,15 @@ import 'swiper/scss/navigation'
|
|||
import 'swiper/scss/pagination'
|
||||
import './Slider.scss'
|
||||
import type { Shout } from '../../graphql/types.gen'
|
||||
import { createEffect, createMemo, createSignal, Show, For } from 'solid-js'
|
||||
import { Icon } from '../_shared/Icon'
|
||||
import { createEffect, createMemo, createSignal, Show, For, JSX } from 'solid-js'
|
||||
import { Icon } from './Icon'
|
||||
|
||||
interface SliderProps {
|
||||
title?: string
|
||||
articles: Shout[]
|
||||
articles?: Shout[]
|
||||
slidesPerView?: number
|
||||
isCardsWithCover?: boolean
|
||||
children?: JSX.Element
|
||||
}
|
||||
|
||||
export default (props: SliderProps) => {
|
||||
|
@ -66,21 +66,7 @@ export default (props: SliderProps) => {
|
|||
<h2 class="col-12">{props.title}</h2>
|
||||
<Show when={!!articles()}>
|
||||
<div class="swiper" classList={{ 'cards-with-cover': isCardsWithCover }} ref={el}>
|
||||
<div class="swiper-wrapper">
|
||||
<For each={articles()}>
|
||||
{(a: Shout) => (
|
||||
<ArticleCard
|
||||
article={a}
|
||||
settings={{
|
||||
additionalClass: 'swiper-slide',
|
||||
isFloorImportant: true,
|
||||
isWithCover: isCardsWithCover,
|
||||
nodate: true
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</For>
|
||||
</div>
|
||||
<div class="swiper-wrapper">{props.children}</div>
|
||||
<div class="slider-arrow-next" ref={nextEl} onClick={() => swiper()?.slideNext()}>
|
||||
<Icon name="slider-arrow" class={'icon'} />
|
||||
</div>
|
|
@ -15,6 +15,7 @@
|
|||
"By alphabet": "По алфавиту",
|
||||
"By authors": "По авторам",
|
||||
"By name": "По имени",
|
||||
"By popularity": "По популярности",
|
||||
"By rating": "По популярности",
|
||||
"By relevance": "По релевантности",
|
||||
"By shouts": "По публикациям",
|
||||
|
|
Loading…
Reference in New Issue
Block a user