fix(tree-view): target branches for emerge-expand/collapse

Morfo declaraba target='item' para emerge-expand y emerge-collapse,
pero los items son hojas — no se expanden. El stamp del data-event-*
debe aterrizar en el branch (data-tree-view-branch), que es el part
que realmente revela/oculta contenido.

- Morfo: target: v.partRef('item') → v.partRef('branch') en ambos
  events de emerge. commit-select sigue en item (selección aplica
  tanto a leaves como a branches).
- Pack: selector `onItem(emerge-*)` → `onBranch(emerge-*)`. Las dos
  cascadas de emerge ahora matchean el elemento correcto en DOM.

tree-grid no afectado: su Row es a la vez item y branch (data-has-
children + data-expanded en el mismo part), así que target='row'
ya estaba correcto.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
active-uix
dev 5 months ago
parent 43b1537291
commit 66318c4759

@ -32,22 +32,28 @@ export const treeViewMorfo = {
// sección desplegable)." Tree expand fits exactly. Was // sección desplegable)." Tree expand fits exactly. Was
// misclassified as `shift.navigate` (which is for context/regime // misclassified as `shift.navigate` (which is for context/regime
// change, not content revealing). // change, not content revealing).
//
// Target is `branch` (not `item`): items are leaves — they
// don't expand. The data-event-* stamp lands on the branch
// element (`data-tree-view-branch`), which is what the sema
// pack selector targets.
name: 'emerge-expand', name: 'emerge-expand',
semantic: { semantic: {
family: 'emerge', family: 'emerge',
verb: 'expand', verb: 'expand',
target: v.partRef('item'), target: v.partRef('branch'),
sequence: 'post' sequence: 'post'
} }
}, },
{ {
// Collapse a node — per book cap. 26: "emerge.collapse — una // Collapse a node — per book cap. 26: "emerge.collapse — una
// región se contrae." // región se contrae." Target is `branch` for the same reason
// as emerge-expand above.
name: 'emerge-collapse', name: 'emerge-collapse',
semantic: { semantic: {
family: 'emerge', family: 'emerge',
verb: 'collapse', verb: 'collapse',
target: v.partRef('item'), target: v.partRef('branch'),
sequence: 'post' sequence: 'post'
} }
} }

@ -6,10 +6,12 @@ import type { Sema } from '../sema-map';
/** /**
* TreeView perceptual defaults — SOFT EMERGE + COMMIT. * TreeView perceptual defaults — SOFT EMERGE + COMMIT.
* *
* TreeView has three event surfaces, all targeting the `item` part: * TreeView has three event surfaces:
* - `commit-select` (commit.select, affirm) — leaf or branch selected * - `commit-select` on `item` — leaf or branch selected (affirm intent
* - `emerge-expand` (emerge.expand) — branch reveals children * via family deltas). Item part covers both leaves and branches
* - `emerge-collapse` (emerge.collapse) — branch hides children * from the selection standpoint.
* - `emerge-expand` on `branch` — branch reveals children.
* - `emerge-collapse` on `branch` — branch hides children.
* *
* Strategy (book cap. 22 §10 + cap. 26 emerge open/close discipline): * Strategy (book cap. 22 §10 + cap. 26 emerge open/close discipline):
* - EXPAND: `emerge.soft` (gain 0.08) — content reveals, ascending * - EXPAND: `emerge.soft` (gain 0.08) — content reveals, ascending
@ -21,15 +23,14 @@ import type { Sema } from '../sema-map';
* content surfaces elsewhere), and the select chime mustn't * content surfaces elsewhere), and the select chime mustn't
* compete with that downstream signal. * compete with that downstream signal.
* *
* Note on target: morfo declares all three events targeting `item` * Target split: expand/collapse target `branch` because items are
* (leaves). Branches also have role="treeitem" but a different part * leaves — they don't expand. The DOM marker on a branch is
* marker (`data-tree-view-branch`). If branches end up emitting at * `data-tree-view-branch`, distinct from `data-tree-view-item`. The
* runtime without the `data-tree-view-item` marker, this cascade will * selectors below honour that split.
* miss them — a known concern noted in the morfo declaration audit.
* The pack follows the morfo declaration verbatim; any mismatch is a
* morfo-level fix outside this pack's scope.
*/ */
const onBranch = (matchers?: Parameters<typeof semaSelector<typeof treeViewMorfo>>[2]) =>
semaSelector(treeViewMorfo, 'branch', matchers);
const onItem = (matchers?: Parameters<typeof semaSelector<typeof treeViewMorfo>>[2]) => const onItem = (matchers?: Parameters<typeof semaSelector<typeof treeViewMorfo>>[2]) =>
semaSelector(treeViewMorfo, 'item', matchers); semaSelector(treeViewMorfo, 'item', matchers);
@ -37,11 +38,11 @@ export const treeViewSema: Sema = {
name: 'tree-view', name: 'tree-view',
cascade: [ cascade: [
{ {
selector: onItem({ eventName: 'emerge-expand' }), selector: onBranch({ eventName: 'emerge-expand' }),
sound: soundTuning('emerge.soft') sound: soundTuning('emerge.soft')
}, },
{ {
selector: onItem({ eventName: 'emerge-collapse' }), selector: onBranch({ eventName: 'emerge-collapse' }),
sound: soundTuning('emerge.exit.soft') sound: soundTuning('emerge.exit.soft')
}, },
{ {

Loading…
Cancel
Save

Powered by TurnKey Linux.