feature: Настроен адаптив виджета TimeFrameSlider

This commit is contained in:
Ilia Mashkov
2025-11-21 15:42:39 +03:00
parent 364c5e1ff1
commit 2958cc734a
2 changed files with 107 additions and 23 deletions

View File

@@ -24,8 +24,9 @@
overflow: hidden; overflow: hidden;
@media (width <=768px) { @media (width <=768px) {
min-height: auto; padding: 60px 20px 20px;
padding: 20px;
background-image: unset;
} }
} }
@@ -47,10 +48,15 @@
@media (width <=768px) { @media (width <=768px) {
position: relative;
inset: unset;
margin-bottom: 20px; margin-bottom: 20px;
padding-left: 0; padding-left: 0;
font-size: 20px; font-size: 20px;
border: none;
} }
} }
@@ -70,10 +76,16 @@
background-size: 100% 1px; background-size: 100% 1px;
@media (width <=768px) { @media (width <=768px) {
position: unset;
display: flex; display: flex;
flex-direction: column; flex-direction: column;
width: 100%;
height: auto; height: auto;
margin: 0;
background-image: unset;
} }
} }
@@ -90,10 +102,13 @@
transform-origin: left; transform-origin: left;
@media (width <=768px) { @media (width <=768px) {
position: static; left: 20px;
bottom: 13px;
order: 2; order: 2;
gap: 10px;
margin-top: 20px; margin-top: 20px;
padding: 0; padding: 0;
} }
@@ -107,6 +122,59 @@
.buttons { .buttons {
display: flex; display: flex;
gap: 20px; gap: 20px;
@media (width <=768px) {
gap: 8px;
}
}
.chevronIcon {
width: 9px;
height: 14px;
@media (width <=768px) {
width: 6px;
height: 11.5px;
}
}
.dots {
display: none;
@media (width <=768px) {
position: absolute;
left: 50%;
bottom: 32px;
display: flex;
gap: 10px;
justify-content: center;
width: 100%;
transform: translate(-50%, -50%);
}
}
.dot {
width: 6px;
height: 6px;
padding: 0;
border: none;
border-radius: 50%;
background-color: var(--color-primary);
cursor: pointer;
opacity: 0.4;
transition: opacity 0.3s ease;
&.activeDot {
opacity: 1;
}
} }
.rotated { .rotated {
@@ -120,7 +188,7 @@
z-index: 0; z-index: 0;
display: flex; display: flex;
gap: 40px; gap: 60px;
color: var(--color-text); color: var(--color-text);
font-weight: 700; font-weight: 700;
@@ -161,15 +229,12 @@
display: block; display: block;
margin-bottom: 40px; margin-bottom: 20px;
padding-top: 40px;
color: var(--color-text); color: var(--color-text);
font-weight: 700; font-weight: 700;
font-size: 20px; font-size: 16px;
text-align: center; text-align: left;
border-top: 1px solid var(--color-border);
} }
} }
@@ -179,6 +244,12 @@
} }
} }
.eventCarousel { .carouselContainer {
padding: 55px 80px 105px; padding: 55px 80px 105px;
@media (width <=768px) {
padding: 0;
border-top: 1px solid #C7CDD9;
}
} }

View File

@@ -3,6 +3,7 @@
* Главный компонент временной шкалы с круговой диаграммой и каруселью событий * Главный компонент временной шкалы с круговой диаграммой и каруселью событий
*/ */
import classNames from 'classnames'
import gsap from 'gsap' import gsap from 'gsap'
import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react' import { memo, useCallback, useEffect, useMemo, useRef, useState } from 'react'
@@ -127,18 +128,19 @@ export const TimeFrameSlider = memo(() => {
<div className={styles.content}> <div className={styles.content}>
<div className={styles.centerDate}> <div className={styles.centerDate}>
<span ref={startYearRef}>{currentPeriod.yearFrom}</span> <span ref={startYearRef}>{currentPeriod.yearFrom}</span>
{'\u00A0'}
<span ref={endYearRef}>{currentPeriod.yearTo}</span> <span ref={endYearRef}>{currentPeriod.yearTo}</span>
</div> </div>
<div className={styles.periodLabel}>{currentPeriod.label}</div> <div className={styles.periodLabel}>{currentPeriod.label}</div>
<div className={styles.circleContainer}>
<CircleTimeline <CircleTimeline
periods={HISTORICAL_PERIODS} periods={HISTORICAL_PERIODS}
activeIndex={activePeriod} activeIndex={activePeriod}
onPeriodChange={setActivePeriod} onPeriodChange={setActivePeriod}
rotation={rotation} rotation={rotation}
/> />
</div>
<div className={styles.controls}> <div className={styles.controls}>
<div className={styles.pagination}> <div className={styles.pagination}>
@@ -153,7 +155,7 @@ export const TimeFrameSlider = memo(() => {
onClick={handlePrev} onClick={handlePrev}
aria-label='Предыдущий период' aria-label='Предыдущий период'
> >
<ChevronSvg width={9} height={14} stroke='#42567A' /> <ChevronSvg className={styles.chevronIcon} stroke='#42567A' />
</Button> </Button>
<Button <Button
variant='round' variant='round'
@@ -163,19 +165,30 @@ export const TimeFrameSlider = memo(() => {
aria-label='Следующий период' aria-label='Следующий период'
> >
<ChevronSvg <ChevronSvg
width={9} className={classNames(styles.chevronIcon, styles.rotated)}
height={14}
stroke='#42567A' stroke='#42567A'
className={styles.rotated}
/> />
</Button> </Button>
</div> </div>
</div> </div>
</div> </div>
<div className={styles.eventCarousel}> <div className={styles.carouselContainer}>
<EventsCarousel events={currentPeriod.events} visible /> <EventsCarousel events={currentPeriod.events} visible />
</div> </div>
<div className={styles.dots}>
{HISTORICAL_PERIODS.map((_, index) => (
<button
key={index}
className={classNames(styles.dot, {
[styles.activeDot]: index === activePeriod,
})}
onClick={() => setActivePeriod(index)}
aria-label={`Перейти к периоду ${index + 1}`}
/>
))}
</div>
</div> </div>
) )
}) })