3e64837dd3
- Implemented ProgressBar component to display progress based on states. - Added EstatusEskeleton for loading state indication. - Created documentation page for ProgressBar with examples and props table. - Developed reusable CodeBlock and VistaComponente components for code display. - Introduced IndiceContenido for navigation within documentation. - Styled ProgressBar and related components with SCSS.
88 lines
2.5 KiB
TypeScript
88 lines
2.5 KiB
TypeScript
import React, { useState, JSX } from 'react';
|
|
|
|
interface Tab {
|
|
id: string;
|
|
title: string | JSX.Element;
|
|
titleText?: string;
|
|
content: JSX.Element;
|
|
disabled?: boolean;
|
|
}
|
|
interface TabsProps {
|
|
tabs: Tab[];
|
|
style?: 'default' | 'box';
|
|
className?: {
|
|
container?: string;
|
|
tab?: string;
|
|
content?: string;
|
|
};
|
|
defaultActiveTab?: string;
|
|
}
|
|
|
|
export default function Tabs({
|
|
tabs,
|
|
style = 'default',
|
|
className,
|
|
defaultActiveTab,
|
|
}: TabsProps) {
|
|
const [activeTab, setActiveTab] = useState<string>(() => {
|
|
// 1) si se pasó defaultActiveTab y existe en tabs (y no está disabled), úsala
|
|
if (defaultActiveTab) {
|
|
const found = tabs.find((t) => t.id === defaultActiveTab && !t.disabled);
|
|
if (found) return found.id;
|
|
}
|
|
// 2) si no, buscar el primer tab habilitado
|
|
const firstEnabled = tabs.find((t) => !t.disabled);
|
|
return firstEnabled ? firstEnabled.id : tabs[0]?.id || '';
|
|
});
|
|
|
|
return (
|
|
<>
|
|
<ul className={`nav nav-tabs style-${style}`} id='myTab' role='tablist'>
|
|
{tabs.map((tab) => (
|
|
<li
|
|
key={tab.id}
|
|
className='nav-item'
|
|
role='presentation'
|
|
title={
|
|
typeof tab.title === 'string' ? tab.title : tab.titleText || ''
|
|
}
|
|
>
|
|
<button
|
|
className={`nav-link ${tab.disabled ? 'disabled' : ''} ${
|
|
activeTab === tab.id ? 'active' : ''
|
|
}`}
|
|
id={`tab-${tab.id}`}
|
|
data-bs-toggle='tab'
|
|
data-bs-target={`#tab-pane-${tab.id}`}
|
|
type='button'
|
|
role='tab'
|
|
aria-controls={`tab-pane-${tab.id}`}
|
|
aria-selected={activeTab === tab.id}
|
|
onClick={() => !tab.disabled && setActiveTab(tab.id)}
|
|
>
|
|
{tab.title.toString().length > 35
|
|
? `${tab.title.toString().slice(0, 35)}...`
|
|
: tab.title}
|
|
</button>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
<div className='tab-content mt-3' id='myTabContent'>
|
|
{tabs.map((tab) => (
|
|
<div
|
|
key={tab.id}
|
|
className={`tab-pane fade ${
|
|
activeTab === tab.id ? 'show active' : ''
|
|
} ${className?.content}`}
|
|
id={`tab-pane-${tab.id}`}
|
|
role='tabpanel'
|
|
aria-labelledby={`tab-${tab.id}`}
|
|
>
|
|
{activeTab === tab.id && tab.content}
|
|
</div>
|
|
))}
|
|
</div>
|
|
</>
|
|
);
|
|
}
|