You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
|
|
4 months ago | |
|---|---|---|
| .. | ||
| README.md | 5 months ago | |
| index.ts | 5 months ago | |
| tabs-content.svelte | 5 months ago | |
| tabs-context.ts | 5 months ago | |
| tabs-indicator.svelte | 4 months ago | |
| tabs-list.svelte | 5 months ago | |
| tabs-trigger.svelte | 5 months ago | |
| tabs.css | 5 months ago | |
| tabs.svelte | 4 months ago | |
| types.ts | 5 months ago | |
README.md
Eidos Tabs
Visual wrapper over Soma Tabs. Eidos adds size, variant, collapse and motion presentation; Soma owns value, activation mode, roving focus, ARIA, presence and event emission.
Baselines
| Platform | Surface | Comparison |
|---|---|---|
Air (glm-5) |
Tabs, List, Trigger, Content; sizes xs-lg, variants line/surface/pills, mobile vertical collapse below md, behavior cue on value change. |
Covered. Eidos keeps the same variants and size range, generalizes collapse through collapseAt, and exposes motion through CSS/data attrs. |
| Radix Tabs | Root, List, Trigger, Content; controlled/uncontrolled, orientation, dir, activation mode, list loop, forceMount. |
Covered by Soma/Eidos. Loop lives on root instead of list. |
| Bits UI Tabs | Root, List, Trigger, Content; bindable value, automatic/manual activation, force-mounted transitions. |
Covered. Eidos keeps transitions declarative with motionPreset and content keepMounted. |
| Ark UI Tabs | Root, List, Trigger, Content, Indicator; activation mode, deselectable, lazyMount, unmountOnExit, custom ids. |
Indicator is covered. deselectable is intentionally not supported; tabs remain one-of-many. lazyMount/unmountOnExit map to Soma default plus forceMount/keepMounted. |
| shadcn-svelte Tabs | Styled Bits/Radix-like Root/List/Trigger/Content. | Covered with first-party tokens and compound namespace. |
| React Aria Tabs | Tabs, TabList, Tab, TabPanel; orientation, disabled keys, controlled selection and accessibility relations. |
Covered with per-trigger disabled and value-based trigger/content registry. |
Sources: Radix, Bits UI, Ark UI, shadcn-svelte, React Aria.
Anatomy
<script lang="ts">
import { Tabs } from '$uix/eidos/components/tabs';
let value = $state('account');
</script>
<Tabs bind:value variant="line" size="md">
<Tabs.List aria-label="Account sections">
<Tabs.Trigger value="account">Account</Tabs.Trigger>
<Tabs.Trigger value="security">Security</Tabs.Trigger>
<Tabs.Indicator />
</Tabs.List>
<Tabs.Content value="account">Account panel</Tabs.Content>
<Tabs.Content value="security" keepMounted>Security panel</Tabs.Content>
</Tabs>
Decisions
| Gap / Choice | Decision |
|---|---|
Air mobile collapse was hard-coded to md |
Eidos uses `collapseAt: 'never' |
Ark deselectable |
Not supported. Tabs are a required one-of-many content selector in UIX; deselection belongs to disclosure/toggle patterns. |
Ark lazyMount / unmountOnExit |
Soma default is lazy/unmounted inactive content. keepMounted aliases Soma forceMount for consumers that need persistent panels. |
| Ark/animated indicator | Implemented as Tabs.Indicator; measurement is visual-only in Eidos, while the part marker remains declared in Morfo/Soma. |
| Tablist accessible name | Tabs.List requires consumer-provided aria-label or aria-labelledby; Soma warns in dev instead of inventing a generic label. |
Visual Props
| Prop | Values | Effect |
|---|---|---|
size |
xs | sm | md | lg |
Trigger height, padding and content spacing. |
variant |
line | surface | pills |
Underline, card/surface, or pill-track treatment. |
fitted |
boolean |
Triggers take equal width. |
collapseAt |
'never' | breakpoint | px number |
Vertical tabs collapse responsively below threshold. |
scrollable |
boolean |
Allows overflow scrolling on the list. |
motionPreset |
none | fade | slide |
Content transition recipe. |
Ownership
- Morfo declares tab/list/trigger/content/indicator roles, states and ARIA relationships.
- Soma owns value, keyboard navigation, activation mode, trigger/content ID registries, disabled handling and presence.
- Eidos owns size/variant/collapse/scroll/motion presentation and indicator geometry.
Baseline
Referencia local: Soma + Morfo + Eidos. La capa visual de Eidos expone size / variant / color sobre el comportamiento que Soma ya implementa; el morfo declara parts, ARIA, keyboard y eventos sema. Las decisiones se alinean con las bibliotecas externas listadas en la Comparativa.
Comparativa
| Capacidad | Bits UI | Ark UI | React Aria | shadcn-svelte | UIX |
|---|---|---|---|---|---|
| Surface compound (root + parts) | ✓ | ✓ | ✓ | ✓ | ✓ |
| ARIA semantics + keyboard nav | ✓ | ✓ | ✓ | parcial | ✓ via morfo |
| Variantes visuales (size / variant) | parcial | parcial | n/a | tailwind | ✓ recipe |
| Form integration | parcial | parcial | ✓ | parcial | ✓ via Field |
| Eventos sema declarativos | n/a | n/a | n/a | n/a | ✓ |
Decisiones
- El wrapper Eidos se mantiene fino: ergonomía visual + tokens. Comportamiento y ARIA viven en Soma + Morfo.
- Strings públicos usan idlangref bajo
components.{kebab}.*, con catálogo ensrc/uix/langs/components/{kebab}.ts. - Eventos sema declarados en el morfo cubren los cambios de estado que cargan peso perceptivo (commit, signal). Las navegaciones internas por teclado son focus moves, no eventos.
- Cuando la API necesita comportamiento nuevo, va a Soma / Morfo primero; Eidos sólo expone la receta visual del resultado.
Gaps
| Gap | Disposición | Detalle |
|---|---|---|
| API extendida sobre las referencias externas | diferir | Sólo si llega un caso de uso real. Mantener la superficie estable. |
| Cobertura adicional de variantes visuales | diferir | El recipe cubre sm/md/lg + solid/outline/ghost. Más variantes requieren caso concreto. |
| Documentación per-prop exhaustiva | implementar | Cuando se cierre el ciclo de remediación de cada componente. |
| Tests browser-level del flujo completo (Playwright) | implementar | Cobertura visual + interacciones. Se hace en una pasada conjunta de tests. |