You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/morfo/components/splitter.ts

172 lines
5.0 KiB

import type { Morfo } from '../types';
import { v } from '../types';
export const splitterMorfo = {
name: 'Splitter',
kebab: 'splitter',
// Sema is in scope: the splitter's three-event drag shape ships a
// per-component cascade in `src/uix/sema/components/splitter.ts`
// (pickup sound on `handle-pick`, dynamic per-emit overrides on
// `handle-drag`, snap chime on `commit-set`). Without `'sema'`
// here the cascade rules would never load and `handle-*` events
// would fall through to the family base — which for `handle` has
// no `sound` slice, so drag would be silent. Eidos is in scope too
// since the components/splitter eidos wrappers reference the morfo
// in their CSS recipe (`data-event='commit-set'` pulse).
scope: ['soma', 'sema', 'eidos'],
expression: 'pack',
apg: 'https://www.w3.org/WAI/ARIA/apg/patterns/windowsplitter/',
texts: {
label: '#?components.splitter.label|Splitter',
resize: '#?components.splitter.resize|Resize panels'
},
events: [
// Splitter mirrors Slider's three-event grip/drag/commit shape. Both
// are direct-manipulation primitives where the user grabs a handle,
// drags it, and releases — the sema rendering should match so
// audio/haptic projections feel coherent across the family.
{
// User grabs the resize trigger (pointerdown). Coincident with
// the gesture start — no settled value yet.
name: 'handle-pick',
semantic: {
family: 'handle',
verb: 'pick',
target: v.partRef('resize-trigger'),
sequence: 'coincident'
}
},
{
// Continuous resize during drag (pointermove). Coincident with
// each frame of motion — the value is in flux.
name: 'handle-drag',
semantic: {
family: 'handle',
verb: 'drag',
target: v.partRef('resize-trigger'),
sequence: 'coincident'
}
},
{
// Value committed on release (pointerup). The settled panel
// sizes are now the source of truth.
name: 'commit-set',
semantic: {
family: 'commit',
verb: 'set',
target: v.partRef('provider'),
intent: 'neutral',
sequence: 'post'
}
}
],
direction: {},
parts: [
{
name: 'Provider',
kebab: 'provider',
archetype: 'provider',
kind: 'public',
defaultElement: 'div',
optional: false,
data: [
{
attr: 'data-orientation',
values: ['horizontal', 'vertical'],
value: v.propRef('orientation')
},
{ attr: 'data-disabled', value: v.propRef('disabled'), severity: 'optional' },
{ attr: 'data-resizing', value: v.propRef('resizing'), severity: 'optional' }
],
aria: []
},
{
name: 'Panel',
kebab: 'panel',
archetype: 'content',
kind: 'public',
defaultElement: 'div',
optional: false,
states: ['collapsed', 'expanded'],
data: [
{
attr: 'data-state',
values: ['collapsed', 'expanded'],
value: v.propRef('state')
},
{
attr: 'data-orientation',
values: ['horizontal', 'vertical'],
value: v.propRef('orientation')
},
{ attr: 'data-splitter-panel-id', value: v.propRef('panelId'), emit: 'value' }
],
aria: []
},
{
name: 'ResizeTrigger',
kebab: 'resize-trigger',
archetype: 'trigger',
kind: 'public',
defaultElement: 'div',
role: 'separator',
optional: false,
states: ['dragging', 'hover', 'inactive'],
data: [
{
attr: 'data-state',
values: ['dragging', 'hover', 'inactive'],
value: v.propRef('state')
},
{
attr: 'data-orientation',
values: ['horizontal', 'vertical'],
value: v.propRef('orientation')
},
{ attr: 'data-disabled', value: v.propRef('disabled'), severity: 'optional' },
{ attr: 'data-dragging', value: v.propRef('dragging'), severity: 'optional' }
],
aria: [
{
attr: 'aria-label',
value: v.translationRef('#?components.splitter.resize|Resize panels'),
severity: 'recommended'
},
{ attr: 'aria-orientation', value: v.propRef('orientation') },
{ attr: 'aria-valuenow', value: v.propRef('size') },
{ attr: 'aria-valuemin', value: v.propRef('minSize') },
{ attr: 'aria-valuemax', value: v.propRef('maxSize') }
],
// Conditions added in the P1·CONTRATO keyboard wave: four arrows were
// declared unconditionally while only TWO ever resize. The provider
// resolves its pair through `getDirectionalKeys(dir, orientation)`
// (splitter-provider :675-677), so the cross-axis pair is inert.
keyboard: [
{
key: 'ArrowRight',
action: 'resize',
condition: { when: 'prop-equals', prop: 'orientation', value: 'horizontal' }
},
{
key: 'ArrowLeft',
action: 'resize',
condition: { when: 'prop-equals', prop: 'orientation', value: 'horizontal' }
},
{
key: 'ArrowUp',
action: 'resize',
condition: { when: 'prop-equals', prop: 'orientation', value: 'vertical' }
},
{
key: 'ArrowDown',
action: 'resize',
condition: { when: 'prop-equals', prop: 'orientation', value: 'vertical' }
},
{ key: 'Home', action: 'minimize' },
{ key: 'End', action: 'maximize' },
{ key: 'Enter', action: 'toggle' }
]
}
]
} as const satisfies Morfo;

Powered by TurnKey Linux.