# Censo transversal de naming de props y convención de API — re-auditoría de componentes Dimensiones 2 (convención de nombres) y 4 (API normalizada) a nivel de CATÁLOGO. Fuente por celda: el `types.ts` del componente (leídos: familia fields al completo en su pass + barrido de types 2026-07-07 sobre controls/overlays/selección/data/ media). Objetivo del checkpoint: UNA norma por concepto; cada divergencia lleva evidencia y pide veredicto. ## A. Convenciones CONFIRMADAS catálogo-completo (canon de facto — solo falta escribirlo) | Concepto | Patrón canónico | Evidencia | |---|---|---| | Valor + cambio (valued controls) | `value` (bindable) + `onValueChange: OnChangeFn` | fields ×14, radio-group, toggle-group, rating-group, select, combobox, listbox, calendar, pickers — el par dominante | | Estado binario semántico | nombre ARIA-alineado, NO value: `checked`/`onCheckedChange` (checkbox :15-19, switch :21-23) · `pressed`/`onPressedChange` (toggle :20-22) · + `indeterminate`/`onIndeterminateChange` (checkbox :16-21) | Convención Radix/bits seguida a rajatabla — REGLA: binarios hablan su ARIA | | Apertura de overlay | `open` (bindable) + `onOpenChange` + **`onOpenChangeComplete`** (post-animación) | popover :11-15, dialog :12-51, drawer :46-73, tooltip :34-38, float-panel :20-24, dropdown-menu :18-22 — ×6 EXACTO, incluida la variante Complete | | Cierre/outside | `onInteractOutside: (e: PointerEvent)` + `onFocusOutside` + `dismissible` + `restoreScrollDelay` | dialog :97-106, drawer :62-92, dropdown-menu :61-63 | | Flotante | `side` + `align` + `forceMount` + `modal` (+ `updatePositionStrategy` en menús) | popover/dropdown-menu/float-panel | | Flags de estado plano | `disabled` / `readonly` / `required` / `invalid` (booleans planos, OR-merge Field/Form) | catálogo entero; `is*` SOLO en snippetProps derivados (isFocused/isHovering/isPlaying — rating :21, carousel :18) — separación limpia | | Form-bridge | `name` (+ hidden input; `value` enviado condicionado al estado) | checkbox/switch/toggle :67-69, radio-group, date-field (ISO), knob/radio-group como PARTE morfo | | Navegación de lista | `loop` + `orientation` + `dir: Direction` | radio-group :39-41, toggle-group, select :46, combobox :45, listbox :55 | | Localización | `locale?` (fallback reactivo soma.langs) + `dir` + `hourCycle` | familia date/time | | Tipado de callbacks | `OnChangeFn` para todo callback con dato | transversal (las excepciones, abajo B.2) | ## B. DIVERGENCIAS reales (veredicto requerido — evidencia por celda) ### B.1 Multiplicidad de selección — TRES nombres para el mismo eje | Nombre | Quién | |---|---| | `type: 'single' \| 'multiple'` | select :17, combobox :17 (+ calendar `type` single/multiple) | | `selectionMode: 'single' \| 'multiple'` | listbox :6-51, tree-view :4-14 | | `multiple: boolean` | file-upload :53 | **Propuesta**: un solo nombre (candidato `selectionMode` — no colisiona con el `type` nativo de button/input que ya significa otra cosa en el catálogo; `type` de select/combobox además choca con `PinInputType`/`data-type` que son OTRO eje). Decidir si `multiple: boolean` sobrevive como azúcar donde no hay modo-single-con-array. ### B.2 Callback terminal — CUATRO patrones (de la familia fields, confirmado) (a) `onValueCommit: OnChangeFn` (mask, editable) · (b) `onSubmit(value)` crudo (search, password) · (c) solo evento sema (date/time/color) · (d) `onComplete` (pin-input). **Propuesta**: (a) como norma; (d) azúcar de completitud si se distingue patrón-lleno de commit. ### B.3 Valor primario: `value` genérico vs palabra de dominio | Patrón | Quién | |---|---| | `value` genérico | fields, grupos, select/combobox/listbox, **carousel** (:83 — ¡para el índice de slide!) | | Palabra de dominio | pagination `page`/`onPageChange` (:23-39) · file-upload `files`/`onFilesChange` (:38-40) | **Cuestión**: ¿regla "value salvo que el dominio tenga palabra universal" (page, files)? Entonces carousel debería decir `index`/`onIndexChange` (su snippet YA habla de `index` :8-32) — hoy es el híbrido incoherente. ### B.4 Doble eje seleccionado/expandido tree-view: `selectedValue` + `expandedValue` (+ `onExpandedChange`) :9-26 — sufijo `-Value` para desambiguar ejes (estilo Ark). Coherente internamente; PERO convive con el `value` a secas del resto. **Propuesta**: canonizar el sufijo SOLO para componentes multi-eje (tree, chronos) y documentarlo. ### B.5 Deseleccionabilidad — polaridad invertida `deselectable?: boolean` (toggle-group :4) vs `preventDeselect?: boolean` (calendar :112). El MISMO concepto, nombres opuestos. **Propuesta**: uno de los dos catálogo-completo (candidato `deselectable` — positivo, sin negación mental). ### B.6 Delays de hover — dos convenciones popover `openDelay`/`closeDelay` (:31-33) vs tooltip `delayDuration`/`skipDelayDuration` (:18-20, nombres Radix). **Propuesta**: unificar (candidato openDelay/closeDelay — simétrico y describe el efecto; skipDelayDuration se re-nombra a algo del grupo, p.ej. `groupSkipDelay`). ### B.7 Prefijos de capacidad `allowsCustomValue` (combobox :53, estilo React-Aria "allows") vs adjetivos planos (`deselectable`, `dismissible`) vs `allowHalf` (rating :63 — "allow" singular). TRES micro-convenciones. **Propuesta**: adjetivo plano cuando exista (`deselectable`); `allowX` solo si no hay adjetivo natural; nunca `allowsX`. ### B.8 `defaultValue` — adopción parcial editable :16-21 Y select :28 (¡no era único!). El resto del catálogo confía en `$bindable(inicial)`. **Veredicto**: canonizar en valued-controls (¿quién más lo necesita?) o podar ambos. ### B.9 Validación — tres firmas (de fields, confirmado) `validate` + `onInvalid` razones TIPADAS (color-field) · sin tipar (date/time y ranges) · `validate` boolean + `onValueInvalid` (tags-input). **Propuesta**: nivelar a razones tipadas; un solo nombre de callback. ### B.10 Async-en-vuelo `isPending`/`data-pending` (form) vs `loading` (button, field enum). Puede ser distinción legítima (form en vuelo vs control ocupado) — decidir si se unifica o se documenta. ### B.11 Callbacks de gesto sin par de valor splitter `onResize(sizes)`/`onResizeEnd(sizes)` (:16-18) — datos por callback sin `sizes` bindable visible. Verificar si hay par bindable (por-Panel); si no, es el único flujo one-way del catálogo → veredicto. ## C. Filas heredadas del pass de fields (siguen vivas) | Concepto | Norma emergente | Divergentes | |---|---|---| | Segundo valor temporal | `placeholder` + `onPlaceholderChange` | — (date/time + ranges coherentes) | | Callbacks por sub-valor | `onStartValueChange`/`onEndValueChange` junto a `onValueChange` | — (ranges coherentes entre sí) | | Valor multi-contexto | `values: Record` + `LangSpec` + `required: K[]` | field-langs único | | Doble valor colección+borrador | `value` + `inputValue` ambos bindables | tags-input; combobox :29 TAMBIÉN usa `inputValue` ✓ coherente ×2 | | Eje conmutable | `X` + `onXChange` + `allowedXs` | color-field (format) | | Debounce | `debounceMs` (sufijo-unidad) | search-field | | Completitud | `data-complete`/`isComplete` | mask-field, pin-input | | Visibilidad de contenido | `visible`/`onVisibilityChange` + `purpose` | password-field (concepto DISTINTO del `open` de overlays — legítimo, documentar la distinción) | | Cardinalidad | `enabledSelections` + `whenFull` | toggle-group (dueño único ✓ por decisión 2026-06-27) | | Render condicional | `onlyWhen{Required·Optional·Invalid}` | field ×3 | | Identidad de item | `index` requerido + `value` (tags-input) | listbox/select items usan `value` sin índice — censo cerrado: el index-required es exclusivo de tags (¿necesario?) | | Tamaño/variante (eidos) | `size` (ResponsiveProp) + `variant` + `rounded`/`shape`/`block` | catálogo coherente | ## D. Reglas de API que el veredicto debe ratificar (el "style guide" de props) 1. `value`/`onValueChange` para el valor primario; palabra de dominio (`page`, `files`) SOLO si es universal — y entonces con su par `on{Word}Change`. 2. Binarios hablan su ARIA: `checked`, `pressed`, `indeterminate` — nunca `value: boolean`. 3. Overlays: `open`/`onOpenChange`/`onOpenChangeComplete` — intocable (ya es ley de facto ×6). 4. Booleans de capacidad: adjetivo plano positivo (`deselectable`, `dismissible`, `loop`). 5. `on{Sustantivo}Change` para estado; `on{Verbo}` para gestos/diagnóstico (`onPress`, `onResize`); crudo sin OnChangeFn SOLO señal-sin-payload (`onValueRevert` ✓). 6. `is*` prohibido en props; reservado a snippetProps derivados. 7. Multi-eje: sufijo `-Value` (`selectedValue`/`expandedValue`) solo donde hay ≥2 ejes. 8. Unidades en el nombre cuando el número las tiene: `debounceMs`, `restoreScrollDelay` (ms implícito documentado) — decidir sufijo-unidad como norma. *(Censo cerrado con el barrido de types 2026-07-07 — media-player provider y service components quedan para verificación dirigida en fixes; sus superficies no mostraron pares de valor divergentes.)*