Skip to content

Commit

Permalink
wip: wallet tabs
Browse files Browse the repository at this point in the history
  • Loading branch information
shanimal08 committed Feb 28, 2025
1 parent 1cc1beb commit e58f9fe
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 39 deletions.
43 changes: 19 additions & 24 deletions src/components/Tabs/TabContent.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import * as m from 'motion/react-m';
import { useMotionValue } from 'motion/react';
import styled from 'styled-components';
import { ReactNode, useRef } from 'react';
import { TabItem } from '@app/components/Tabs/Tabs.tsx';

const Track = styled(m.div)`
width: 200px;
width: 100%;
display: flex;
`;

Expand All @@ -15,46 +16,40 @@ const ItemWrapper = styled(m.div)`
align-items: center;
justify-content: space-between;
background-color: #0d0d0d;
cursor: grab;
`;

const SPRING_OPTIONS = { type: 'spring', stiffness: 300, damping: 30 };

interface TabItemProps {
item: string;
children: ReactNode;
}
function TabItem({ item }: TabItemProps) {
function Item({ children }: TabItemProps) {
return (
<ItemWrapper
style={{
width: 200,
width: '100%',
height: '100%',
}}
transition={SPRING_OPTIONS}
>
<div className="carousel-item-content">
<div className="carousel-item-title">{item}</div>
</div>
{children}
</ItemWrapper>
);
}

function TabContent({ items, currentIndex }: { items: string[]; currentIndex: number }) {
const trackItemOffset = 200;
const x = useMotionValue(0);
interface TabContentProps {
items: TabItem[];
currentIndex: number;
}

function TabContent({ items, currentIndex }: TabContentProps) {
const containerRef = useRef<HTMLDivElement>(null);
const trackItemOffset = containerRef.current?.offsetWidth || 300;

return (
<Track
style={{
width: 200,
perspective: 1000,
perspectiveOrigin: `${currentIndex * trackItemOffset + 200 / 2}px 50%`,
x: x.get(),
}}
animate={{ x: -(currentIndex * trackItemOffset) }}
transition={SPRING_OPTIONS}
>
{items.map((item, index) => {
return <TabItem key={index} item={item} />;
<Track ref={containerRef} animate={{ x: -(currentIndex * trackItemOffset) }} transition={SPRING_OPTIONS}>
{items.map(({ id, title, content }) => {
return <Item key={`item-content-${id}-${title}`}>{content}</Item>;
})}
</Track>
);
Expand Down
9 changes: 5 additions & 4 deletions src/components/Tabs/TabNav.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import styled from 'styled-components';
import { TabItem } from './Tabs.tsx';

const Wrapper = styled.div`
display: grid;
Expand All @@ -19,16 +20,16 @@ const NavButton = styled.button<{ $isActive?: boolean }>`
}
`;
interface TabNavProps {
items: string[];
items: TabItem[];
currentIndex: number;
onClick: (index: number) => void;
}
function TabNav({ items, currentIndex, onClick }: TabNavProps) {
return (
<Wrapper>
{items.map((item, i) => (
<NavButton $isActive={currentIndex === i} key={`item:${i}-${item}`} onClick={() => onClick(i)}>
{item}
{items.map(({ id, title }, i) => (
<NavButton $isActive={currentIndex === i} key={`item:${i}-${id}`} onClick={() => onClick(i)}>
{title}
</NavButton>
))}
</Wrapper>
Expand Down
24 changes: 16 additions & 8 deletions src/components/Tabs/Tabs.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
import { TabNav } from '@app/components/Tabs/TabNav.tsx';
import { TabContent } from '@app/components/Tabs/TabContent.tsx';
import styled from 'styled-components';
import { useState } from 'react';
import { ReactNode, useState } from 'react';

const TabsWrapper = styled.div`
width: 200px;
height: 200px;
background: rgba(255, 192, 203, 0.31);
width: 100%;
height: 100%;
align-items: center;
display: flex;
overflow: hidden;
Expand All @@ -17,17 +16,26 @@ const Wrapper = styled.div`
align-items: center;
flex-direction: column;
position: relative;
border-radius: 24px;
padding: 1rem;
`;

export function Tabs({ items }: { items: string[] }) {
export interface TabItem {
id: string;
title: string;
content: ReactNode;
}

interface TabsProps {
tabItems: TabItem[];
}
export function Tabs({ tabItems }: TabsProps) {
const [currentIndex, setCurrentIndex] = useState<number>(0);

return (
<Wrapper>
<TabNav items={items} currentIndex={currentIndex} onClick={setCurrentIndex} />
<TabNav items={tabItems} currentIndex={currentIndex} onClick={setCurrentIndex} />
<TabsWrapper>
<TabContent items={items} currentIndex={currentIndex} />
<TabContent items={tabItems} currentIndex={currentIndex} />
</TabsWrapper>
</Wrapper>
);
Expand Down
17 changes: 14 additions & 3 deletions src/containers/main/SidebarNavigation/Sidebars/SidebarWallet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,25 @@ import { memo } from 'react';
import { SB_WIDTH } from '@app/theme/styles.ts';
import { SidebarWrapper } from '../SidebarNavigation.styles.ts';
import { SidebarGrid } from './SidebarWallet.styles.ts';
import { Tabs } from '@app/components/Tabs/Tabs.tsx';
import { TabItem, Tabs } from '@app/components/Tabs/Tabs.tsx';

const variants = {
open: { opacity: 1, right: 0, transition: { duration: 0.3, ease: 'easeIn' } },
closed: { opacity: 0.5, right: -50, transition: { duration: 0.05, ease: 'easeOut' } },
};

const tabItems = ['send', 'receive', 'blaaa'];
const tabItems: TabItem[] = [
{
id: 'send',
title: 'Send',
content: <p>{`meow`}</p>,
},
{
id: 'receive',
title: 'Receiew',
content: <div>{`mmmeeeeemememeow`}</div>,
},
];
const SidebarWallet = memo(function SidebarWallet() {
return (
<SidebarWrapper
Expand All @@ -20,7 +31,7 @@ const SidebarWallet = memo(function SidebarWallet() {
animate="open"
>
<SidebarGrid>
<Tabs items={tabItems} />
<Tabs tabItems={tabItems} />
</SidebarGrid>
</SidebarWrapper>
);
Expand Down

0 comments on commit e58f9fe

Please sign in to comment.