The bottom handle bar is now dynamic. Fixed CP + FO handles, then one
handle per kind of sub-object the focused node has. "Kind" is the SLOT
part of the AST's SLOT.SUBTYPE namespace: sub-objects sharing a SLOT
(e.g. `line.stem_note` + `line.motif`, or `articles.<subtypeA>` +
`articles.<subtypeB>`) collapse into one pane; different SLOTs split.
Score-level kinds emit, in this order: TU (tuning), ST (stage cone +
voices), IN (instruments — linked ones listed read-only), AR (articles),
BA (bars). info metadata is folded into the FO pane (was previously
listed as a sub-object).
Handles are 2-letter labels for now, intended as alt-text for icons in
a later release.
- `subobject-kinds.js` new: `getKindGroups(node)` returns ordered
`[{ kind, items }]`; `KIND_LABEL` maps kind -> 2-letter label.
- `PaneSubObjects.js` now parameterized by `kind` prop; renders one group.
- `AppShell.js` builds the handle bar from `getKindGroups(focusedNode)`;
drops back to FO when the active sub-pane disappears after a focus change.
- `ObjectShort.js` accepts a `readOnly` flag (used for linked instruments).
24 lines
890 B
JavaScript
24 lines
890 B
JavaScript
import { h } from 'vue';
|
||
|
||
// One-line summary row with a drill-down chevron.
|
||
export const ObjectShort = {
|
||
props: ['label', 'typeTag', 'focused', 'hasChildren', 'readOnly'],
|
||
emits: ['focus', 'drillDown'],
|
||
setup(props, { emit }) {
|
||
return () => h('li', {
|
||
class: ['se-object-item', props.focused ? 'focused' : null, props.readOnly ? 'read-only' : null],
|
||
onClick: () => emit('focus'),
|
||
}, [
|
||
props.typeTag ? h('span', { class: 'se-object-type' }, props.typeTag) : null,
|
||
h('span', { class: 'se-object-label' }, props.label),
|
||
props.hasChildren
|
||
? h('button', {
|
||
class: 'se-chevron',
|
||
title: 'Drill down',
|
||
onClick: e => { e.stopPropagation(); emit('drillDown'); },
|
||
}, '›')
|
||
: null,
|
||
]);
|
||
},
|
||
};
|