122 lines
3.1 KiB
TypeScript
122 lines
3.1 KiB
TypeScript
import { useState } from 'react'
|
||
|
||
import { HISTORICAL_PERIODS } from '@/entities/TimePeriod'
|
||
import {
|
||
ACTIVE_POSITION_DEGREES,
|
||
FULL_CIRCLE_DEGREES,
|
||
} from '@/widgets/TimeFrameSlider/model'
|
||
|
||
import { CircleTimeline } from './CircleTimeline'
|
||
|
||
import type { Meta, StoryObj } from '@storybook/react'
|
||
|
||
const meta = {
|
||
title: 'Widgets/CircleTimeline',
|
||
component: CircleTimeline,
|
||
parameters: {
|
||
layout: 'centered',
|
||
},
|
||
tags: ['autodocs'],
|
||
} satisfies Meta<typeof CircleTimeline>
|
||
|
||
export default meta
|
||
type Story = StoryObj<typeof meta>
|
||
type CustomStory = Partial<Story> & Pick<Story, 'render'>
|
||
|
||
/**
|
||
* Интерактивный компонент-обертка для управления состоянием
|
||
*/
|
||
function CircleTimelineWithState() {
|
||
const [activeIndex, setActiveIndex] = useState(0)
|
||
|
||
// Расчет угла поворота на основе активного индекса
|
||
// Каждый период занимает 360/6 = 60 градусов
|
||
// Активная позиция находится на -60 градусах (верхний правый угол)
|
||
const rotation =
|
||
ACTIVE_POSITION_DEGREES -
|
||
(FULL_CIRCLE_DEGREES / HISTORICAL_PERIODS.length) * activeIndex
|
||
|
||
return (
|
||
<div style={{ width: '600px', height: '600px', position: 'relative' }}>
|
||
<CircleTimeline
|
||
periods={HISTORICAL_PERIODS}
|
||
activeIndex={activeIndex}
|
||
onPeriodChange={setActiveIndex}
|
||
rotation={rotation}
|
||
/>
|
||
</div>
|
||
)
|
||
}
|
||
|
||
/**
|
||
* Интерактивный вариант со всеми 6 периодами
|
||
*/
|
||
export const Default: CustomStory = {
|
||
render: () => <CircleTimelineWithState />,
|
||
parameters: {
|
||
docs: {
|
||
description: {
|
||
story:
|
||
'Интерактивная демонстрация с возможностью переключения между периодами',
|
||
},
|
||
},
|
||
},
|
||
}
|
||
|
||
/**
|
||
* Первый период (Science) активен
|
||
*/
|
||
export const FirstPeriod: Story = {
|
||
args: {
|
||
periods: HISTORICAL_PERIODS,
|
||
activeIndex: 0,
|
||
onPeriodChange: () => {},
|
||
rotation: ACTIVE_POSITION_DEGREES,
|
||
},
|
||
decorators: [
|
||
(Story) => (
|
||
<div style={{ width: '600px', height: '600px', position: 'relative' }}>
|
||
<Story />
|
||
</div>
|
||
),
|
||
],
|
||
}
|
||
|
||
/**
|
||
* Третий период (Tech) активен
|
||
*/
|
||
export const ThirdPeriod: Story = {
|
||
args: {
|
||
periods: HISTORICAL_PERIODS,
|
||
activeIndex: 2,
|
||
onPeriodChange: () => {},
|
||
rotation: ACTIVE_POSITION_DEGREES - (FULL_CIRCLE_DEGREES / 6) * 2,
|
||
},
|
||
decorators: [
|
||
(Story) => (
|
||
<div style={{ width: '600px', height: '600px', position: 'relative' }}>
|
||
<Story />
|
||
</div>
|
||
),
|
||
],
|
||
}
|
||
|
||
/**
|
||
* Вариант с 3 периодами для демонстрации гибкости
|
||
*/
|
||
export const FewPeriods: Story = {
|
||
args: {
|
||
periods: HISTORICAL_PERIODS.slice(0, 3),
|
||
activeIndex: 0,
|
||
onPeriodChange: () => {},
|
||
rotation: -60,
|
||
},
|
||
decorators: [
|
||
(Story) => (
|
||
<div style={{ width: '600px', height: '600px', position: 'relative' }}>
|
||
<Story />
|
||
</div>
|
||
),
|
||
],
|
||
}
|