From 1520db69fd08c5289ce8576fba1c00b873e7d346 Mon Sep 17 00:00:00 2001 From: Vadim Kudriavtsev Date: Wed, 22 Jan 2025 03:50:17 +0300 Subject: [PATCH] feat(*): PaginationDots api & example --- .../PaginationDots/PaginationDots.tsx | 206 ++++++++++++++++++ 1 file changed, 206 insertions(+) create mode 100644 packages/plasma-new-hope/src/components/PaginationDots/PaginationDots.tsx diff --git a/packages/plasma-new-hope/src/components/PaginationDots/PaginationDots.tsx b/packages/plasma-new-hope/src/components/PaginationDots/PaginationDots.tsx new file mode 100644 index 0000000000..ef962b8176 --- /dev/null +++ b/packages/plasma-new-hope/src/components/PaginationDots/PaginationDots.tsx @@ -0,0 +1,206 @@ +import React from 'react'; +import cls from 'classnames'; +import { styled } from '@linaria/react'; + +interface Props { + size?: 's' | 'm'; + /** + * Отображение активного элемента + * @default 'dot' + */ + activeElementView?: 'dot' | 'line'; + /** + * Ориентация элементов + * @default `horizontal` + */ + orientation?: 'horizontal' | 'vertical'; + /** + * Растягивается на всю доступную ширину + * @default true + */ + stretch?: boolean; + /** + * Выбранная страница + */ + value?: number; + /** + * Количество страниц + */ + count?: number; +} + +const Dot = styled.div` + padding: 0 0.375rem; + + &:before { + content: ''; + display: block; + border-radius: 50%; + + background-color: #0808081f; + } + + &.active { + &:before { + background-color: #080808; + } + } + + &[data-size='xs'] { + &:before { + width: 0.375rem; + height: 0.375rem; + } + } + + &[data-size='s'] { + &:before { + width: 0.5rem; + height: 0.5rem; + } + } + + &[data-size='m'] { + &:before { + width: 0.75rem; + height: 0.75rem; + } + } +`; + +const Line = styled(Dot)` + &[data-size='s'] { + &:before { + width: 2rem; + height: 0.5rem; + border-radius: 0.375rem; + } + } + + &[data-size='m'] { + &:before { + width: 3rem; + height: 0.75rem; + border-radius: 0.375rem; + } + } + + &.vertical { + &[data-size='s'] { + &:before { + height: 2rem; + width: 0.5rem; + } + } + + &[data-size='m'] { + &:before { + height: 3rem; + width: 0.75rem; + } + } + } +`; + +const Wrapper = styled.div` + display: flex; + align-items: center; + + &.stretch { + width: 100%; + justify-content: space-between; + } + + &.vertical { + flex-direction: column; + + ${Dot} { + padding: 0.375rem 0; + } + + &.stretch { + width: auto; + height: 100%; + } + } +`; + +const PaginationDots: React.FC = ({ + size = 's', + activeElementView = 'dot', + orientation = 'horizontal', + stretch = true, + value = 0, + count, + }) => { + const dots = new Array(count).fill(null); + + const isVertical = orientation === 'vertical'; + + return ( + + {dots.map((_, index) => { + if (index === value) { + const ActiveElement = activeElementView === 'dot' ? Dot : Line; + return ; + } + + const isCurrent = index === value; + + const isFirst = !isCurrent && count > 1 && (index === 0 || index === count - 1); + const isSecond = !isCurrent && count > 2 && (index === 1 || index === count - 2); + + const getSize = () => { + if (size === 's') { + return isFirst ? 'xs' : 's'; + } + + if (isFirst) { + return 'xs'; + } + + if (isSecond) { + return 's'; + } + + return 'm'; + }; + + const dotSize = getSize(); + + return ; + })} + + ); +}; + +export const App = () => { + return ( +
+ + + + + + + + + + + + + + + +
+
+ + + + + +
+
+ ); +};