Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions src/app/(after-login)/mypage/_components/MyWritings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,17 +37,17 @@ export default function MyWritings() {

return (
<Tabs>
<TabList>
<TabList activeTab={activeTab} setActiveTab={setActiveTab}>
<TabBtn
tabIndex={0}
index={0}
className='text-lg lg:text-2xl'
activeTab={activeTab}
setActiveTab={setActiveTab}
>
내 에피그램({myEpigramsCount})
</TabBtn>
<TabBtn
tabIndex={1}
index={1}
className='text-lg lg:text-2xl'
activeTab={activeTab}
setActiveTab={setActiveTab}
Expand All @@ -56,15 +56,15 @@ export default function MyWritings() {
</TabBtn>
</TabList>
<TabItemsContainer>
<TabItem tabIndex={0} activeTab={activeTab}>
<TabItem index={0} activeTab={activeTab}>
<MyEpigrams
epigrams={epigrams}
isFetching={isFetchingEpigrams}
hasNextPage={hasNextEpigramPage}
fetchNextPage={fetchNextEpigramPage}
/>
</TabItem>
<TabItem tabIndex={1} activeTab={activeTab}>
<TabItem index={1} activeTab={activeTab}>
<CommentList
linkToEpigram={true}
comments={comments}
Expand Down
10 changes: 5 additions & 5 deletions src/components/Tab.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,9 @@ export const Default: Story = {
const [activeTab, setActiveTab] = useState(0);
return (
<Tabs>
<TabList className={args.TabList}>
<TabList className={args.TabList} activeTab={activeTab} setActiveTab={setActiveTab}>
<TabBtn
tabIndex={0}
index={0}
className={args.TabBtn}
activeClass={args.TabBtnActive}
activeTab={activeTab}
Expand All @@ -66,7 +66,7 @@ export const Default: Story = {
내 에피그램(10)
</TabBtn>
<TabBtn
tabIndex={1}
index={1}
className={args.TabBtn}
activeClass={args.TabBtnActive}
activeTab={activeTab}
Expand All @@ -77,15 +77,15 @@ export const Default: Story = {
</TabList>
<TabItemsContainer className={args.TabItemsContainer}>
<TabItem
tabIndex={0}
index={0}
className={args.TabItem}
animation={args.TabItemAnimation}
activeTab={activeTab}
>
에피그램 리스트
</TabItem>
<TabItem
tabIndex={1}
index={1}
className={args.TabItem}
animation={args.TabItemAnimation}
activeTab={activeTab}
Expand Down
10 changes: 5 additions & 5 deletions src/components/Tab.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ describe('Tab 컴포넌트 테스트', () => {
const [activeTab, setActiveTab] = useState(0);
return (
<Tabs>
<TabList>
<TabBtn tabIndex={0} activeTab={activeTab} setActiveTab={setActiveTab}>
<TabList activeTab={activeTab} setActiveTab={setActiveTab}>
<TabBtn index={0} activeTab={activeTab} setActiveTab={setActiveTab}>
탭 1
</TabBtn>
<TabBtn tabIndex={1} activeTab={activeTab} setActiveTab={setActiveTab}>
<TabBtn index={1} activeTab={activeTab} setActiveTab={setActiveTab}>
탭 2
</TabBtn>
</TabList>
Expand All @@ -34,10 +34,10 @@ describe('Tab 컴포넌트 테스트', () => {
return (
<Tabs>
<TabItemsContainer>
<TabItem tabIndex={0} activeTab={activeTab}>
<TabItem index={0} activeTab={activeTab}>
내용 1
</TabItem>
<TabItem tabIndex={1} activeTab={activeTab}>
<TabItem index={1} activeTab={activeTab}>
내용 2
</TabItem>
</TabItemsContainer>
Expand Down
47 changes: 37 additions & 10 deletions src/components/Tab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ import { cn } from '@/utils/helper';
interface TabListProps {
children: React.ReactNode;
className?: string;
activeTab: number;
setActiveTab: (tab: number) => void;
}

interface TabBtnProps {
children: React.ReactNode;
className?: string;
activeClass?: string;
tabIndex: number;
index: number;
activeTab: number;
setActiveTab: (tab: number) => void;
}
Expand All @@ -26,7 +28,7 @@ interface TabItemsContainerProps {
interface TabItemProps {
children: React.ReactNode;
className?: string;
tabIndex: number;
index: number;
activeTab: number;
animation?: {
enabled?: boolean;
Expand All @@ -53,9 +55,31 @@ export function Tabs({ children }: { children: React.ReactNode }) {
);
}

export function TabList({ children, className }: TabListProps) {
export function TabList({ children, className, activeTab, setActiveTab }: TabListProps) {
const tabs = React.Children.toArray(children);
const totalTabs = tabs.length;

const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'ArrowRight') {
e.preventDefault();
const nextTab = (activeTab + 1) % totalTabs;
setActiveTab(nextTab);
(document.querySelectorAll('[role="tab"]')[nextTab] as HTMLButtonElement)?.focus();
}

if (e.key === 'ArrowLeft') {
e.preventDefault();
const prevTab = (activeTab - 1 + totalTabs) % totalTabs;
setActiveTab(prevTab);
(document.querySelectorAll('[role="tab"]')[prevTab] as HTMLButtonElement)?.focus();
}
};
return (
<ul className={cn('md:gap:6 mb-6 flex flex-wrap gap-4 md:mb-8 lg:mb-12', className)}>
<ul
className={cn('md:gap:6 mb-6 flex flex-wrap gap-4 md:mb-8 lg:mb-12', className)}
role='tablist'
onKeyDown={handleKeyDown}
>
{children}
</ul>
);
Expand All @@ -65,24 +89,27 @@ export function TabBtn({
children,
activeClass,
className,
tabIndex,
index,
activeTab,
setActiveTab,
}: TabBtnProps) {
const active = 'text-black-600 font-semibold';
const isActive = activeTab === tabIndex;
const isActive = activeTab === index;

return (
<li>
<button
tabIndex={tabIndex}
role='tab'
aria-selected={isActive}
tabIndex={isActive ? 0 : -1}
className={cn(
'cursor-pointer leading-5 font-medium text-gray-300 transition-all duration-100',
isActive && active,
isActive && activeClass,
className,
)}
onClick={() => setActiveTab(tabIndex)}
onClick={() => setActiveTab(index)}
onFocus={() => setActiveTab(index)}
>
{children}
</button>
Expand All @@ -94,8 +121,8 @@ export function TabItemsContainer({ children, className }: TabItemsContainerProp
return <ul className={className}>{children}</ul>;
}

export function TabItem({ children, className, tabIndex, activeTab, animation }: TabItemProps) {
const isActive = activeTab === tabIndex;
export function TabItem({ children, className, index, activeTab, animation }: TabItemProps) {
const isActive = activeTab === index;
const { enabled = true, direction = 'y', directionValue = 20, duration = 0.25 } = animation || {};

const [isFirstRender, setIsFirstRender] = useState(true);
Expand Down