From 72c195d1c615b3a72a7cea84cf15dfbc3cc8494e Mon Sep 17 00:00:00 2001 From: dev Date: Fri, 15 May 2026 19:55:09 +0200 Subject: [PATCH] Drive Splitter attrs from Soma runtime --- src/uix/morfo/components/splitter.ts | 40 ++++++++++---- .../splitter/splitter-provider.svelte.ts | 53 ++++++++++--------- 2 files changed, 59 insertions(+), 34 deletions(-) diff --git a/src/uix/morfo/components/splitter.ts b/src/uix/morfo/components/splitter.ts index 01c81eea1..058d824a7 100644 --- a/src/uix/morfo/components/splitter.ts +++ b/src/uix/morfo/components/splitter.ts @@ -17,9 +17,13 @@ export const splitterMorfo = { defaultElement: 'div', optional: false, data: [ - { attr: 'data-orientation', values: ['horizontal', 'vertical'] }, - { attr: 'data-disabled', severity: 'optional' }, - { attr: 'data-resizing', severity: 'optional' } + { + 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: [] }, @@ -32,9 +36,17 @@ export const splitterMorfo = { optional: false, states: ['collapsed', 'expanded'], data: [ - { attr: 'data-state', values: ['collapsed', 'expanded'] }, - { attr: 'data-orientation', values: ['horizontal', 'vertical'] }, - { attr: 'data-splitter-panel-id' } + { + 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: [] }, @@ -48,10 +60,18 @@ export const splitterMorfo = { optional: false, states: ['dragging', 'hover', 'inactive'], data: [ - { attr: 'data-state', values: ['dragging', 'hover', 'inactive'] }, - { attr: 'data-orientation', values: ['horizontal', 'vertical'] }, - { attr: 'data-disabled', severity: 'optional' }, - { attr: 'data-dragging', severity: 'optional' } + { + 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: [ { diff --git a/src/uix/soma/components/splitter/splitter-provider.svelte.ts b/src/uix/soma/components/splitter/splitter-provider.svelte.ts index 2d66e0ded..05e9efad1 100644 --- a/src/uix/soma/components/splitter/splitter-provider.svelte.ts +++ b/src/uix/soma/components/splitter/splitter-provider.svelte.ts @@ -1,10 +1,8 @@ import { context, type WithRefOpts } from '../../provider'; -import { boolToEmptyStrOrUndef } from '$adom'; import { state, type Active, type ActiveProps, type StateProps } from '$libs/reactive'; import type { OnChangeFn, Orientation, Direction, SomaKeyboardEvent } from '../../types'; import { KEYS, getDirectionalKeys } from '../../keyboard'; import { Soma } from '../../core/soma.svelte'; -import { SPLITTER_LANGS } from './langs'; import { splitterMorfo } from '../../../morfo/components/splitter'; import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte'; @@ -77,12 +75,19 @@ export class SplitterProvider { private constructor(opts: SplitterOpts) { this.opts = opts; this.soma = Soma.require(); - this.runtime = this.soma.runtime(splitterMorfo, {}); + this.runtime = this.soma.runtime(splitterMorfo, { + props: { + orientation: () => this.opts.orientation.current, + disabled: () => this.opts.disabled.current, + resizing: () => this.resizing + } + }); this.runtimePart = this.runtime.part('provider', { id: opts.id, ref: opts.ref, owner: this, - context: SplitterProvider.ctx + context: SplitterProvider.ctx, + syncAttrs: true }); } @@ -254,10 +259,7 @@ export class SplitterProvider { height: '100%', width: '100%', overflow: 'hidden' - }, - 'data-orientation': this.opts.orientation.current, - 'data-disabled': boolToEmptyStrOrUndef(this.opts.disabled.current), - 'data-resizing': boolToEmptyStrOrUndef(this.resizing) + } } as const) ); } @@ -292,7 +294,13 @@ export class SplitterPanelProvider { this.runtimePart = this.provider.runtime.part('panel', { id: opts.id, ref: opts.ref, - owner: this + owner: this, + props: { + state: () => (this.isCollapsed ? 'collapsed' : 'expanded'), + orientation: () => this.provider.opts.orientation.current, + panelId: () => this.opts.panelId.current + }, + syncAttrs: true }); this.cleanup = this.provider.registerPanel({ @@ -327,10 +335,7 @@ export class SplitterPanelProvider { overflow: 'hidden', 'min-width': this.provider.opts.orientation.current === 'horizontal' ? '0px' : undefined, 'min-height': this.provider.opts.orientation.current === 'vertical' ? '0px' : undefined - }, - 'data-splitter-panel-id': this.opts.panelId.current, - 'data-state': this.isCollapsed ? 'collapsed' : 'expanded', - 'data-orientation': this.provider.opts.orientation.current + } } as const) ); } @@ -368,7 +373,17 @@ export class SplitterResizeTriggerProvider { this.runtimePart = this.provider.runtime.part('resize-trigger', { id: opts.id, ref: opts.ref, - owner: this + owner: this, + props: { + state: () => this.dataState, + orientation: () => this.provider.opts.orientation.current, + disabled: () => this.isDisabled, + dragging: () => this.dragging, + size: () => this.ariaValueNow, + minSize: () => this.ariaValueMin, + maxSize: () => this.ariaValueMax + }, + syncAttrs: true }); // Cleanup drag state on unmount @@ -554,17 +569,7 @@ export class SplitterResizeTriggerProvider { readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props, - role: 'separator' as const, - 'aria-label': this.provider.soma.langs.ts(SPLITTER_LANGS.RESIZE), - 'aria-orientation': this.provider.opts.orientation.current, - 'aria-valuenow': this.ariaValueNow, - 'aria-valuemin': this.ariaValueMin, - 'aria-valuemax': this.ariaValueMax, tabindex: this.isDisabled ? -1 : 0, - 'data-state': this.dataState, - 'data-orientation': this.provider.opts.orientation.current, - 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), - 'data-dragging': boolToEmptyStrOrUndef(this.dragging), style: { cursor: this.isDisabled ? 'default' : this.isVertical ? 'row-resize' : 'col-resize', 'touch-action': 'none',