refactor(soma): ola 1 de F3 — los gestos handle sueltan targetOverride (censo 64 → 51)

Los cuatro componentes de gesto con «campos de elemento propios», y la
pregunta A-36 primero en cada sitio:

- path-trace y rotate-align (3+3): tokenEl/trackEl y needleEl/dialEl SON los
  elementos que sus partes registran (los escribe la registracion) — el
  override re-decia el destino declarado singleton. No-op puros, retirados.
- float-panel (4): la QUEDA preguntaba ¿allowedTargets o retirar? y la
  respuesta estaba en la fila de la doctrina del sello: el content ES la
  posicion (grip y terminal, morfo.md §Where the stamp lands). contentRef es
  el elemento registrado del target declarado y el ?? dragEl/resizeEl era
  cinturon de la era fallbackTarget, inalcanzable durante el arrastre del
  propio panel. Retirados.
- drag-drop (3): draggable y droppable son partes REPETIDAS con la instancia
  correcta en la mano — anclados por identidad (partInstance + trigger
  anclado, el idioma de tag-group). Verificado que source/target son
  exactamente los refs registrados (opts.ref.current en los dos call sites),
  asi que la identidad resuelve; un elemento ajeno cae a la resolucion del
  runtime.

Verificado: suites navegador de los 4 → 34/34 · censo 64 → 51 (−13 exactos) ·
check 69 = base, 0 propios.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
alpha-0.1-dir-prefs
dev 2 months ago
parent 281840db3e
commit f6e4f40723

@ -294,9 +294,14 @@ montado):
navigation-menu · menubar · virtual-list/grid · pagination (declarado;
anclar desde los 5 controles) · css-field · number-field (exponen
`targetOverride` en su API pública de `commit()` — retirarla) ·
drag-drop · path-trace · rotate-align (gestos handle con campos de
elemento propios) · float-panel drag/resize (header/resize-handle:
¿allowedTargets o retirar?) · metrics/menu-dial/onion-menu (vistas de
~~drag-drop · path-trace · rotate-align · float-panel~~ (**HECHOS
2026-08-13, censo 64 → 51**: los «campos de elemento propios» eran los
MISMOS elementos que las partes registran — 10 no-op retirados; las 3
emisiones de drag-drop ancladas por identidad a sus partes repetidas
[`source`/`target` SON los refs registrados, verificado]; y la pregunta de
float-panel la respondió la fila de la doctrina del sello: el content ES
la posición → retirar los 4, el `?? dragEl` era cinturón de la era
fallbackTarget) · metrics/menu-dial/onion-menu (vistas de
eidos: deben REGISTRAR sus partes con `runtime.part()` — hoy emiten con
elementos locales no registrados, `partInstance` daría null) ·
select/combobox (elección del llamante trigger/input: leer providers) ·

@ -159,9 +159,12 @@ export class DragDropProvider {
};
this.keyboard = params.keyboard;
this.announceTemplate(DRAG_DROP_LANGS.DRAG_STARTED, { item: params.label });
// Morfo: handle-pick on `draggable`. The source element is the
// draggable that just initiated the drag — pass it as fallback.
void this.runtime.trigger('handle-pick', { targetOverride: params.source });
// Morfo: handle-pick on `draggable`, a REPEATED part — anchor on the
// registered instance that initiated the drag (identity, never a raw
// element); unregistered falls back to the runtime's own resolution.
const pickInstance = this.runtime.partInstance('draggable', params.source);
if (pickInstance) void pickInstance.trigger('handle-pick');
else void this.runtime.trigger('handle-pick');
if (params.keyboard) {
this.setupKeyboardNav();
@ -216,9 +219,11 @@ export class DragDropProvider {
item: drag.label,
target: targetLabel.trim()
});
// Morfo: handle-drop on `droppable`. The target is the droppable
// that received the dropped item.
void this.runtime.trigger('handle-drop', { targetOverride: target });
// Morfo: handle-drop on `droppable`, repeated — anchor on the instance
// that received the item.
const dropInstance = this.runtime.partInstance('droppable', target);
if (dropInstance) void dropInstance.trigger('handle-drop');
else void this.runtime.trigger('handle-drop');
this.finish();
}
@ -231,9 +236,11 @@ export class DragDropProvider {
outcome: 'cancel'
});
this.announce(DRAG_DROP_LANGS.DRAG_CANCELLED);
// Morfo: commit-cancel on `draggable`. The source still holds
// the dragged-from element; use it as fallback target.
void this.runtime.trigger('commit-cancel', { targetOverride: drag.source });
// Morfo: commit-cancel on `draggable`, repeated — anchor on the source
// instance the cancelled drag came from.
const cancelInstance = this.runtime.partInstance('draggable', drag.source);
if (cancelInstance) void cancelInstance.trigger('commit-cancel');
else void this.runtime.trigger('commit-cancel');
// Return focus to the source for keyboard drags.
const source = drag.source;
this.finish();

@ -751,9 +751,11 @@ export class FloatPanelProvider {
/* already released */
}
this.bringToFront();
void this.runtime.trigger('handle-pick', {
targetOverride: this.contentRef.current ?? this.dragEl ?? undefined
});
// Morfo target is `content` — the panel IS the position (the stamp
// doctrine's own row) — and content registers `contentRef`, so the
// runtime resolves it alone; the old `?? dragEl` belt was
// fallbackTarget-era and unreachable mid-drag.
void this.runtime.trigger('handle-pick');
}
e.preventDefault();
const clamped = this.clampPosition(
@ -795,9 +797,7 @@ export class FloatPanelProvider {
// the geometry effect resyncs the DOM at rest. Commit BEFORE clearing
// `dragging` so the effect's first non-active run reads the final value.
if (this.dragLivePos) this.setPosition(this.dragLivePos);
void this.runtime.trigger('handle-drop', {
targetOverride: this.contentRef.current ?? this.dragEl ?? undefined
});
void this.runtime.trigger('handle-drop');
}
// Always settle the grabbed state (it was set on pointerdown, so a press
// WITHOUT movement — a plain click on the header — must lower it too).
@ -884,9 +884,7 @@ export class FloatPanelProvider {
/* already released */
}
this.bringToFront();
void this.runtime.trigger('handle-resize-start', {
targetOverride: this.contentRef.current ?? this.resizeEl ?? undefined
});
void this.runtime.trigger('handle-resize-start');
}
e.preventDefault();
@ -946,9 +944,7 @@ export class FloatPanelProvider {
// Commit final size + position once; geometry effect resyncs at rest.
if (this.resizeLiveSize) this.setSize(this.resizeLiveSize);
if (this.resizeLivePos) this.setPosition(this.resizeLivePos);
void this.runtime.trigger('handle-resize-end', {
targetOverride: this.contentRef.current ?? this.resizeEl ?? undefined
});
void this.runtime.trigger('handle-resize-end');
}
// Always settle (set on pointerdown, so a no-move press must lower it too).
this.resizing = false;

@ -353,7 +353,7 @@ export class PathTraceProvider {
private firePick(): void {
if (this.pickFired) return;
this.pickFired = true;
void this.runtime.trigger('handle-pick', { targetOverride: this.tokenEl ?? undefined });
void this.runtime.trigger('handle-pick');
}
private complete(): void {
@ -363,7 +363,7 @@ export class PathTraceProvider {
this.tracing = false;
this.offPath = false;
this.cancelQueuedHandleDrag();
void this.runtime.trigger('handle-drop', { targetOverride: this.trackEl ?? undefined });
void this.runtime.trigger('handle-drop');
this.announce(PATH_TRACE_LANGS.COMPLETE, 'polite');
this.host.solve(telemetry);
this.tel = null;
@ -393,7 +393,7 @@ export class PathTraceProvider {
)
return;
this.lastDragSignalAt = now;
void this.runtime.trigger('handle-drag', { targetOverride: this.tokenEl ?? undefined });
void this.runtime.trigger('handle-drag');
}, this.opts.ref.current ?? undefined);
}

@ -327,7 +327,7 @@ export class RotateAlignProvider {
const detent = Math.round(angle / DETENT_DEG);
if (detent !== this.lastDetent) {
this.lastDetent = detent;
void this.runtime.trigger('handle-drag', { targetOverride: this.needleEl ?? undefined });
void this.runtime.trigger('handle-drag');
}
const on = Math.abs(shortest(angle, this.target)) <= this.toleranceDeg;
if (on && !this.aligned) {
@ -367,7 +367,7 @@ export class RotateAlignProvider {
private firePick(): void {
if (this.pickFired) return;
this.pickFired = true;
void this.runtime.trigger('handle-pick', { targetOverride: this.needleEl ?? undefined });
void this.runtime.trigger('handle-pick');
}
private complete(): void {
@ -376,7 +376,7 @@ export class RotateAlignProvider {
const telemetry = this.buildTelemetry();
this.rotating = false;
this.settleHandle = null;
void this.runtime.trigger('handle-drop', { targetOverride: this.dialEl ?? undefined });
void this.runtime.trigger('handle-drop');
this.announce(ROTATE_ALIGN_LANGS.COMPLETE, 'polite');
this.host.solve(telemetry);
this.tel = null;

Loading…
Cancel
Save

Powered by TurnKey Linux.