# Tabs

A flexible tab navigation component with horizontal scrolling, closable tabs, and custom rendering support. Features include automatic overflow handling, smooth scrolling animations, and tab reload functionality. Perfect for document interfaces, dashboards, and multi-panel applications.

## Installation

```bash
npm install @ticatec/uniface-element
```

## Import

```typescript
import Tabs, { type TabActionHandler, type TabCloseHandler, type TabRender } from "@ticatec/uniface-element/Tabs";
```

## Basic Usage

```svelte
<script>
  import Tabs from "@ticatec/uniface-element/Tabs";
  
  let tabs = [
    { text: "Home" },
    { text: "Products" },
    { text: "Services" },
    { text: "About" },
    { text: "Contact" }
  ];
  
  let activeTab = tabs[0];
</script>

<Tabs {tabs} bind:activeTab>
  <div class="tab-content">
    <h2>{activeTab.text}</h2>
    <p>Content for {activeTab.text} tab</p>
  </div>
</Tabs>
```

## Props

| Prop | Type | Default | Description |
|------|------|---------|-------------|
| `tabs` | `Array<any>` | `[]` | Array of tab objects |
| `activeTab` | `any` | `null` | Currently active tab object |
| `textField` | `string` | `"text"` | Field name for tab display text |
| `simple` | `boolean` | `false` | Whether to use simple styling |
| `closable` | `boolean \| TabActionHandler` | `false` | Whether tabs can be closed |
| `scrollStep` | `number` | `100` | Scroll step size in pixels |
| `tabRender` | `TabRender` | `null` | Custom tab rendering component |
| `reloadHandler` | `TabActionHandler` | `null` | Handler for tab reload action |
| `closeHandler` | `TabCloseHandler` | `null` | Handler for tab close action |
| `style` | `string` | `""` | Additional CSS styles |
| `class` | `string` | `""` | CSS class name |

## Type Definitions

### TabActionHandler
```typescript
type TabActionHandler = (tab: any) => void;
```

### TabCloseHandler
```typescript
type TabCloseHandler = (tab: any) => Promise<boolean>;
```

### TabRender
```typescript
type TabRender = (tab: any) => any;
```

## Examples

### Basic Tab Navigation

```svelte
<script>
  import Tabs from "@ticatec/uniface-element/Tabs";
  
  let navigationTabs = [
    { id: 1, text: "Dashboard", icon: "dashboard" },
    { id: 2, text: "Analytics", icon: "analytics" },
    { id: 3, text: "Reports", icon: "reports" },
    { id: 4, text: "Settings", icon: "settings" }
  ];
  
  let currentTab = navigationTabs[0];
</script>

<div class="app-container">
  <Tabs tabs={navigationTabs} bind:activeTab={currentTab} style="height: 400px;">
    {#if currentTab.id === 1}
      <div class="dashboard">
        <h2>📊 Dashboard</h2>
        <p>Welcome to your dashboard overview</p>
        <div class="stats">
          <div class="stat">Users: 1,234</div>
          <div class="stat">Revenue: $12,345</div>
          <div class="stat">Orders: 567</div>
        </div>
      </div>
    {:else if currentTab.id === 2}
      <div class="analytics">
        <h2>📈 Analytics</h2>
        <p>View your performance metrics</p>
        <div class="charts">
          <div class="chart">Monthly Growth: +15%</div>
          <div class="chart">Conversion Rate: 3.2%</div>
        </div>
      </div>
    {:else if currentTab.id === 3}
      <div class="reports">
        <h2>📋 Reports</h2>
        <p>Generate and view reports</p>
        <button>Generate Monthly Report</button>
        <button>Export Data</button>
      </div>
    {:else if currentTab.id === 4}
      <div class="settings">
        <h2>⚙️ Settings</h2>
        <p>Configure your preferences</p>
        <label><input type="checkbox"> Email notifications</label>
        <label><input type="checkbox"> Dark mode</label>
      </div>
    {/if}
  </Tabs>
</div>

<style>
  .app-container {
    max-width: 800px;
    margin: 20px auto;
    border: 1px solid #ddd;
    border-radius: 8px;
  }
  
  .dashboard, .analytics, .reports, .settings {
    padding: 20px;
  }
  
  .stats, .charts {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 16px;
    margin-top: 16px;
  }
  
  .stat, .chart {
    padding: 12px;
    background: #f8f9fa;
    border-radius: 4px;
    text-align: center;
  }
  
  .reports button {
    margin: 8px 8px 8px 0;
    padding: 8px 16px;
    border: none;
    background: #007bff;
    color: white;
    border-radius: 4px;
    cursor: pointer;
  }
  
  .settings label {
    display: block;
    margin: 8px 0;
  }
</style>
```

### Simple Tabs

```svelte
<script>
  import Tabs from "@ticatec/uniface-element/Tabs";
  
  let documentTabs = [
    { text: "Introduction" },
    { text: "Getting Started" },
    { text: "API Reference" },
    { text: "Examples" }
  ];
  
  let currentDoc = documentTabs[0];
</script>

<div class="docs-container">
  <Tabs tabs={documentTabs} bind:activeTab={currentDoc} simple style="height: 300px;">
    <div class="doc-content">
      {#if currentDoc.text === "Introduction"}
        <h3>Introduction</h3>
        <p>Welcome to our comprehensive documentation. This guide will help you get started with our platform and make the most of its features.</p>
      {:else if currentDoc.text === "Getting Started"}
        <h3>Getting Started</h3>
        <ol>
          <li>Create an account</li>
          <li>Verify your email</li>
          <li>Complete your profile</li>
          <li>Start using the platform</li>
        </ol>
      {:else if currentDoc.text === "API Reference"}
        <h3>API Reference</h3>
        <p>Complete API documentation with endpoints, parameters, and examples.</p>
        <code>GET /api/users</code>
      {:else if currentDoc.text === "Examples"}
        <h3>Examples</h3>
        <p>Practical examples and code snippets to help you implement common use cases.</p>
      {/if}
    </div>
  </Tabs>
</div>

<style>
  .docs-container {
    max-width: 600px;
    margin: 20px auto;
  }
  
  .doc-content {
    padding: 20px;
    background: #f8f9fa;
  }
  
  .doc-content h3 {
    margin-top: 0;
    color: #333;
  }
  
  .doc-content code {
    background: #e9ecef;
    padding: 4px 8px;
    border-radius: 4px;
    font-family: monospace;
  }
  
  .doc-content ol {
    padding-left: 20px;
  }
  
  .doc-content li {
    margin: 8px 0;
  }
</style>
```

### Closable Tabs

```svelte
<script>
  import Tabs from "@ticatec/uniface-element/Tabs";
  
  let browserTabs = [
    { id: 1, text: "Google", url: "https://google.com", modified: false },
    { id: 2, text: "GitHub", url: "https://github.com", modified: true },
    { id: 3, text: "Stack Overflow", url: "https://stackoverflow.com", modified: false },
    { id: 4, text: "MDN Docs", url: "https://developer.mozilla.org", modified: false }
  ];
  
  let activeTab = browserTabs[0];
  
  async function handleTabClose(tab) {
    if (tab.modified) {
      const confirmed = confirm(`"${tab.text}" has unsaved changes. Close anyway?`);
      if (!confirmed) return false;
    }
    
    console.log(`Closing tab: ${tab.text}`);
    return true;
  }
  
  function addNewTab() {
    const newId = Math.max(...browserTabs.map(t => t.id)) + 1;
    const newTab = {
      id: newId,
      text: "New Tab",
      url: "about:blank",
      modified: false
    };
    
    browserTabs = [...browserTabs, newTab];
    activeTab = newTab;
  }
</script>

<div class="browser-container">
  <div class="browser-header">
    <Tabs 
      tabs={browserTabs} 
      bind:activeTab 
      closable={true}
      closeHandler={handleTabClose}
      style="height: 350px;"
    >
      <div class="page-content">
        <div class="address-bar">
          <span>🔒 {activeTab.url}</span>
        </div>
        <div class="page-body">
          <h2>{activeTab.text}</h2>
          <p>This is the content for {activeTab.text}</p>
          {#if activeTab.modified}
            <p class="modified">⚠️ This page has unsaved changes</p>
          {/if}
          <button on:click={() => activeTab.modified = !activeTab.modified}>
            {activeTab.modified ? 'Mark as Saved' : 'Make Changes'}
          </button>
        </div>
      </div>
    </Tabs>
    <button class="new-tab-btn" on:click={addNewTab}>+</button>
  </div>
</div>

<style>
  .browser-container {
    max-width: 900px;
    margin: 20px auto;
    border: 1px solid #ddd;
    border-radius: 8px;
    overflow: hidden;
  }
  
  .browser-header {
    display: flex;
    align-items: stretch;
  }
  
  .new-tab-btn {
    width: 40px;
    border: none;
    background: #f8f9fa;
    cursor: pointer;
    font-size: 18px;
    border-left: 1px solid #ddd;
  }
  
  .new-tab-btn:hover {
    background: #e9ecef;
  }
  
  .page-content {
    padding: 0;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  
  .address-bar {
    padding: 8px 16px;
    background: #f8f9fa;
    border-bottom: 1px solid #ddd;
    font-family: monospace;
    font-size: 14px;
  }
  
  .page-body {
    padding: 20px;
    flex: 1;
  }
  
  .modified {
    color: #dc3545;
    font-weight: 500;
  }
  
  button {
    margin-top: 12px;
    padding: 8px 16px;
    border: 1px solid #007bff;
    background: white;
    color: #007bff;
    border-radius: 4px;
    cursor: pointer;
  }
  
  button:hover {
    background: #007bff;
    color: white;
  }
</style>
```

### Tabs with Reload Functionality

```svelte
<script>
  import Tabs from "@ticatec/uniface-element/Tabs";
  
  let dataTabs = [
    { id: 1, text: "Sales Data", lastUpdated: "2 min ago", loading: false },
    { id: 2, text: "User Analytics", lastUpdated: "5 min ago", loading: false },
    { id: 3, text: "Performance", lastUpdated: "10 min ago", loading: false }
  ];
  
  let activeDataTab = dataTabs[0];
  
  function handleTabReload(tab) {
    console.log(`Reloading tab: ${tab.text}`);
    
    // Set loading state
    tab.loading = true;
    dataTabs = [...dataTabs];
    
    // Simulate data reload
    setTimeout(() => {
      tab.loading = false;
      tab.lastUpdated = "Just now";
      dataTabs = [...dataTabs];
    }, 2000);
  }
</script>

<div class="data-dashboard">
  <Tabs 
    tabs={dataTabs} 
    bind:activeTab={activeDataTab} 
    reloadHandler={handleTabReload}
    style="height: 400px;"
  >
    <div class="data-content">
      <div class="data-header">
        <h3>{activeDataTab.text}</h3>
        <div class="last-updated">
          {#if activeDataTab.loading}
            <span class="loading">🔄 Refreshing...</span>
          {:else}
            <span>Last updated: {activeDataTab.lastUpdated}</span>
          {/if}
        </div>
      </div>
      
      <div class="data-body">
        {#if activeDataTab.id === 1}
          <div class="chart-placeholder">
            <h4>Sales Overview</h4>
            <div class="metrics">
              <div>Total Sales: $45,678</div>
              <div>Growth: +12.5%</div>
              <div>Transactions: 234</div>
            </div>
          </div>
        {:else if activeDataTab.id === 2}
          <div class="chart-placeholder">
            <h4>User Engagement</h4>
            <div class="metrics">
              <div>Active Users: 1,890</div>
              <div>Session Duration: 4:32</div>
              <div>Bounce Rate: 23%</div>
            </div>
          </div>
        {:else if activeDataTab.id === 3}
          <div class="chart-placeholder">
            <h4>System Performance</h4>
            <div class="metrics">
              <div>Response Time: 145ms</div>
              <div>Uptime: 99.9%</div>
              <div>CPU Usage: 45%</div>
            </div>
          </div>
        {/if}
      </div>
    </div>
  </Tabs>
</div>

<style>
  .data-dashboard {
    max-width: 800px;
    margin: 20px auto;
    border: 1px solid #ddd;
    border-radius: 8px;
  }
  
  .data-content {
    padding: 20px;
    height: 100%;
    display: flex;
    flex-direction: column;
  }
  
  .data-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 20px;
    padding-bottom: 12px;
    border-bottom: 1px solid #eee;
  }
  
  .data-header h3 {
    margin: 0;
  }
  
  .last-updated {
    font-size: 14px;
    color: #666;
  }
  
  .loading {
    color: #007bff;
    animation: pulse 1.5s infinite;
  }
  
  @keyframes pulse {
    0%, 100% { opacity: 1; }
    50% { opacity: 0.5; }
  }
  
  .chart-placeholder {
    flex: 1;
    background: #f8f9fa;
    border-radius: 8px;
    padding: 20px;
    text-align: center;
  }
  
  .chart-placeholder h4 {
    margin: 0 0 20px 0;
    color: #333;
  }
  
  .metrics {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(150px, 1fr));
    gap: 16px;
  }
  
  .metrics div {
    padding: 16px;
    background: white;
    border-radius: 4px;
    font-weight: 500;
  }
</style>
```

### Custom Tab Rendering

```svelte
<script>
  import Tabs from "@ticatec/uniface-element/Tabs";
  import CustomTab from "./CustomTab.svelte";
  
  let projectTabs = [
    { 
      id: 1, 
      text: "Frontend", 
      status: "active", 
      notifications: 3,
      color: "#007bff"
    },
    { 
      id: 2, 
      text: "Backend", 
      status: "warning", 
      notifications: 1,
      color: "#ffc107"
    },
    { 
      id: 3, 
      text: "Database", 
      status: "error", 
      notifications: 5,
      color: "#dc3545"
    },
    { 
      id: 4, 
      text: "DevOps", 
      status: "success", 
      notifications: 0,
      color: "#28a745"
    }
  ];
  
  let activeProject = projectTabs[0];
  
  async function handleProjectClose(tab) {
    const confirmed = confirm(`Close project "${tab.text}"?`);
    return confirmed;
  }
</script>

<!-- CustomTab.svelte -->
<script>
  export let tab;
  export let closeTab = null;
  export let reloadTab = null;
  export let closable = false;
  
  function getStatusIcon(status) {
    switch (status) {
      case 'active': return '🟢';
      case 'warning': return '🟡';
      case 'error': return '🔴';
      case 'success': return '✅';
      default: return '⚪';
    }
  }
</script>

<div class="custom-tab" style="border-left: 3px solid {tab.color};">
  <div class="tab-content">
    <span class="status-icon">{getStatusIcon(tab.status)}</span>
    <span class="tab-text">{tab.text}</span>
    {#if tab.notifications > 0}
      <span class="notification-badge">{tab.notifications}</span>
    {/if}
  </div>
  
  <div class="tab-actions">
    {#if reloadTab}
      <button class="action-btn" on:click={reloadTab}>🔄</button>
    {/if}
    {#if closable && closeTab}
      <button class="action-btn close" on:click={closeTab}>×</button>
    {/if}
  </div>
</div>

<style>
  .custom-tab {
    display: flex;
    align-items: center;
    justify-content: space-between;
    padding: 8px 12px;
    background: white;
    border-radius: 4px 4px 0 0;
    min-width: 120px;
  }
  
  .tab-content {
    display: flex;
    align-items: center;
    gap: 6px;
  }
  
  .status-icon {
    font-size: 12px;
  }
  
  .tab-text {
    font-weight: 500;
  }
  
  .notification-badge {
    background: #dc3545;
    color: white;
    font-size: 10px;
    padding: 2px 6px;
    border-radius: 10px;
    min-width: 16px;
    text-align: center;
  }
  
  .tab-actions {
    display: flex;
    gap: 4px;
  }
  
  .action-btn {
    background: none;
    border: none;
    padding: 2px 4px;
    cursor: pointer;
    border-radius: 2px;
    font-size: 12px;
  }
  
  .action-btn:hover {
    background: #f8f9fa;
  }
  
  .action-btn.close:hover {
    background: #dc3545;
    color: white;
  }
</style>

<!-- Main component -->
<div class="project-dashboard">
  <Tabs 
    tabs={projectTabs} 
    bind:activeTab={activeProject}
    tabRender={CustomTab}
    closable={true}
    closeHandler={handleProjectClose}
    style="height: 350px;"
  >
    <div class="project-content">
      <h3>{activeProject.text} Project</h3>
      <div class="project-status">
        <span>Status: </span>
        <span class="status {activeProject.status}">{activeProject.status.toUpperCase()}</span>
      </div>
      
      {#if activeProject.notifications > 0}
        <div class="notifications">
          <h4>Notifications ({activeProject.notifications})</h4>
          <ul>
            {#each Array(activeProject.notifications) as _, i}
              <li>Notification #{i + 1} for {activeProject.text}</li>
            {/each}
          </ul>
        </div>
      {:else}
        <p>No notifications for this project.</p>
      {/if}
    </div>
  </Tabs>
</div>

<style>
  .project-dashboard {
    max-width: 800px;
    margin: 20px auto;
    border: 1px solid #ddd;
    border-radius: 8px;
  }
  
  .project-content {
    padding: 20px;
  }
  
  .project-status {
    margin: 16px 0;
  }
  
  .status {
    padding: 4px 8px;
    border-radius: 4px;
    font-weight: bold;
    text-transform: uppercase;
    font-size: 12px;
  }
  
  .status.active {
    background: #cce5ff;
    color: #004085;
  }
  
  .status.warning {
    background: #fff3cd;
    color: #856404;
  }
  
  .status.error {
    background: #f8d7da;
    color: #721c24;
  }
  
  .status.success {
    background: #d4edda;
    color: #155724;
  }
  
  .notifications h4 {
    margin: 20px 0 12px 0;
  }
  
  .notifications ul {
    padding-left: 20px;
  }
  
  .notifications li {
    margin: 8px 0;
  }
</style>
```

### Horizontal Scrolling Tabs

```svelte
<script>
  import Tabs from "@ticatec/uniface-element/Tabs";
  
  // Create many tabs to demonstrate scrolling
  let manyTabs = Array.from({length: 15}, (_, i) => ({
    id: i + 1,
    text: `Tab ${i + 1}`,
    content: `This is the content for Tab ${i + 1}. Lorem ipsum dolor sit amet, consectetur adipiscing elit.`
  }));
  
  let currentTab = manyTabs[0];
</script>

<div class="scrollable-demo">
  <h3>Horizontal Scrolling Tabs Demo</h3>
  <p>This example shows how tabs automatically scroll when there are too many to fit.</p>
  
  <Tabs 
    tabs={manyTabs} 
    bind:activeTab={currentTab}
    scrollStep={150}
    style="height: 300px; width: 600px;"
  >
    <div class="scroll-content">
      <h4>{currentTab.text}</h4>
      <p>{currentTab.content}</p>
      <div class="tab-info">
        <p><strong>Tab ID:</strong> {currentTab.id}</p>
        <p><strong>Position:</strong> {manyTabs.indexOf(currentTab) + 1} of {manyTabs.length}</p>
      </div>
    </div>
  </Tabs>
</div>

<style>
  .scrollable-demo {
    max-width: 700px;
    margin: 20px auto;
    padding: 20px;
  }
  
  .scrollable-demo h3 {
    margin-bottom: 8px;
  }
  
  .scrollable-demo p {
    margin-bottom: 20px;
    color: #666;
  }
  
  .scroll-content {
    padding: 20px;
    background: #f8f9fa;
    height: 100%;
  }
  
  .tab-info {
    margin-top: 20px;
    padding: 12px;
    background: white;
    border-radius: 4px;
    border-left: 3px solid #007bff;
  }
  
  .tab-info p {
    margin: 4px 0;
    font-size: 14px;
  }
</style>
```

## Features

- **Horizontal Scrolling**: Automatic scroll controls when tabs overflow
- **Closable Tabs**: Optional tab closing with confirmation callbacks
- **Reload Functionality**: Built-in reload button with custom handlers
- **Custom Rendering**: Use custom components for tab appearance
- **Smooth Animations**: CSS transitions and motion tweening
- **Keyboard Accessible**: Full keyboard navigation support
- **Responsive Design**: Adapts to container width
- **Simple Mode**: Minimalist styling option

## Styling

The Tabs component supports extensive CSS customization:

```css
/* Tab panel container */
.uniface-tab-panel {
  /* Your custom styles */
}

/* Individual tab styling */
.uniface-tab {
  /* Tab appearance */
}

.uniface-tab.active {
  /* Active tab styles */
}

/* Simple mode styling */
.uniface-tabs-wrap.simple {
  /* Simple mode overrides */
}

/* Scroll buttons */
.scroll-left, .scroll-right {
  /* Scroll control styling */
}
```

## Accessibility

- Keyboard navigation with Tab and Arrow keys
- ARIA attributes for screen readers
- Focus management and visual indicators
- Semantic HTML structure
- High contrast support

## Best Practices

1. **Tab Management**: Keep tab count reasonable for better UX
2. **Content Loading**: Use reload functionality for dynamic content
3. **Close Confirmation**: Always confirm before closing modified tabs
4. **Custom Rendering**: Use custom tab components for complex layouts
5. **Responsive Design**: Test tab behavior on different screen sizes
6. **Performance**: Consider lazy loading for tab content

## Browser Support

- Modern browsers with CSS Grid and Flexbox support
- Compatible with Svelte 5+
- Smooth animations on supported browsers
- Touch-friendly interface
- Full TypeScript support

## Related Components

- `Accordion` - Collapsible content panels
- `Stepper` - Step-by-step navigation
- `Breadcrumb` - Hierarchical navigation
- `Sidebar` - Side navigation component