| <script lang="ts"> |
| export type TabId = 'scanner' | 'encounters' | 'pictuary'; |
| |
| interface Tab { |
| id: TabId; |
| label: string; |
| icon: string; |
| } |
| |
| interface Props { |
| activeTab: TabId; |
| onTabChange: (tab: TabId) => void; |
| } |
| |
| let { activeTab, onTabChange }: Props = $props(); |
| |
| const tabs: Tab[] = [ |
| { id: 'scanner', label: 'Scanner', icon: 'https://huggingface.co/spaces/Fraser/piclets/resolve/main/assets/snap_logo.png' }, |
| { id: 'encounters', label: 'Encounters', icon: 'https://huggingface.co/spaces/Fraser/piclets/resolve/main/assets/encounters_logo.png' }, |
| { id: 'pictuary', label: 'Pictuary', icon: 'https://huggingface.co/spaces/Fraser/piclets/resolve/main/assets/pictuary_logo.png' } |
| ]; |
| |
| function handleTabClick(tabId: TabId) { |
| onTabChange(tabId); |
| } |
| </script> |
|
|
| <nav class="tab-bar"> |
| <div class="tab-bar-inner"> |
| {#each tabs as tab} |
| <button |
| class="tab-item" |
| class:active={activeTab === tab.id} |
| onclick={() => handleTabClick(tab.id)} |
| > |
| <div class="icon-wrapper"> |
| <img |
| src={tab.icon} |
| alt={tab.label} |
| class="tab-icon" |
| /> |
| </div> |
| </button> |
| {/each} |
| </div> |
| </nav> |
|
|
| <style> |
| .tab-bar { |
| position: fixed; |
| bottom: 0; |
| left: 0; |
| right: 0; |
| background: #f5f5f5; |
| border-top: 1px solid #e0e0e0; |
| z-index: 1000; |
| padding-bottom: env(safe-area-inset-bottom, 0); |
| } |
| |
| .tab-bar-inner { |
| display: flex; |
| justify-content: space-around; |
| align-items: center; |
| height: 70px; |
| } |
| |
| .tab-item { |
| flex: 1; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| background: none; |
| border: none; |
| padding: 6px; |
| cursor: pointer; |
| -webkit-tap-highlight-color: transparent; |
| } |
| |
| .icon-wrapper { |
| position: relative; |
| width: 48px; |
| height: 48px; |
| display: flex; |
| align-items: center; |
| justify-content: center; |
| border-radius: 10px; |
| } |
| |
| .tab-item.active .icon-wrapper { |
| background: rgb(190, 210, 238); |
| } |
| |
| .tab-icon { |
| width: 32px; |
| height: 32px; |
| object-fit: contain; |
| opacity: 0.4; |
| } |
| |
| .tab-item.active .tab-icon { |
| filter: brightness(0) saturate(100%) invert(27%) sepia(51%) saturate(2878%) hue-rotate(192deg) brightness(104%) contrast(97%); |
| opacity: 1; |
| } |
| |
| |
| </style> |