14 KiB
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<T> |
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<T> 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<K,string> + 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)
value/onValueChangepara el valor primario; palabra de dominio (page,files) SOLO si es universal — y entonces con su paron{Word}Change.- Binarios hablan su ARIA:
checked,pressed,indeterminate— nuncavalue: boolean. - Overlays:
open/onOpenChange/onOpenChangeComplete— intocable (ya es ley de facto ×6). - Booleans de capacidad: adjetivo plano positivo (
deselectable,dismissible,loop). on{Sustantivo}Changepara estado;on{Verbo}para gestos/diagnóstico (onPress,onResize); crudo sin OnChangeFn SOLO señal-sin-payload (onValueRevert✓).is*prohibido en props; reservado a snippetProps derivados.- Multi-eje: sufijo
-Value(selectedValue/expandedValue) solo donde hay ≥2 ejes. - 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.)