From 75e50becf7c89bd62fe0aa6165bbf8fdba8cb270 Mon Sep 17 00:00:00 2001 From: dev Date: Thu, 11 Jun 2026 23:29:39 +0200 Subject: [PATCH] refactor(soma): de-dup CssField Input via renderProps (spin-field family) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Mirrors the NumberField Input reference. CssField morfo's aria-required/disabled/ readonly/invalid gain `ariaBoolean`; the Input provider drops the hardcoded role + data-spin-field-input + those four aria booleans — all now from renderProps(). Soma keeps the CSS-value-specific bits it genuinely owns: the parsed aria-valuenow, soma-only aria-valuemin/max, aria-valuetext, native form attrs, handlers. Verified in browser (role/aria/data from morfo, parsed aria-valuenow="16") + soma/morfo tests 71/71. Both spin-field inputs are now fully morfo-sourced; the triggers/scrubber + the other families remain on the backlog. Co-Authored-By: Claude Opus 4.8 --- src/uix/morfo/components/css-field.ts | 28 ++++++++++++++++--- .../css-field/css-field-provider.svelte.ts | 11 +++----- 2 files changed, 28 insertions(+), 11 deletions(-) diff --git a/src/uix/morfo/components/css-field.ts b/src/uix/morfo/components/css-field.ts index 798fc767c..68b2a984e 100644 --- a/src/uix/morfo/components/css-field.ts +++ b/src/uix/morfo/components/css-field.ts @@ -100,10 +100,30 @@ export const cssFieldMorfo = { aria: [ { attr: 'aria-valuenow', value: v.propRef('value'), severity: 'optional' }, { attr: 'aria-valuetext', value: v.propRef('value'), severity: 'recommended' }, - { attr: 'aria-required', value: v.propRef('required'), severity: 'optional' }, - { attr: 'aria-disabled', value: v.propRef('disabled'), severity: 'optional' }, - { attr: 'aria-readonly', value: v.propRef('readonly'), severity: 'optional' }, - { attr: 'aria-invalid', value: v.propRef('invalid'), severity: 'optional' } + { + attr: 'aria-required', + value: v.propRef('required'), + severity: 'optional', + ariaBoolean: true + }, + { + attr: 'aria-disabled', + value: v.propRef('disabled'), + severity: 'optional', + ariaBoolean: true + }, + { + attr: 'aria-readonly', + value: v.propRef('readonly'), + severity: 'optional', + ariaBoolean: true + }, + { + attr: 'aria-invalid', + value: v.propRef('invalid'), + severity: 'optional', + ariaBoolean: true + } ], keyboard: [ { key: 'ArrowUp', action: 'increment' }, diff --git a/src/uix/soma/components/css-field/css-field-provider.svelte.ts b/src/uix/soma/components/css-field/css-field-provider.svelte.ts index dfb2069eb..8a4de984e 100644 --- a/src/uix/soma/components/css-field/css-field-provider.svelte.ts +++ b/src/uix/soma/components/css-field/css-field-provider.svelte.ts @@ -529,10 +529,11 @@ export class CssFieldInputProvider { readonly props = $derived.by(() => { const p = this.provider.parsed; return this.runtimePart.assert({ - ...this.runtimePart.props, - role: 'spinbutton' as const, + // Morfo-declared: role, data-spin-field-input, aria-required/disabled/ + // readonly/invalid (the last four via ariaBoolean). Soma adds only the + // CSS-value-specific aria below + handlers/native. + ...this.runtimePart.renderProps(), inputmode: 'text' as const, - 'data-spin-field-input': '', autocomplete: 'off' as const, autocorrect: 'off' as const, spellcheck: false, @@ -542,10 +543,6 @@ export class CssFieldInputProvider { 'aria-valuemin': this.provider.opts.min.current, 'aria-valuemax': this.provider.opts.max.current, 'aria-valuetext': this.provider.opts.value.current || undefined, - 'aria-required': boolToStr(this.provider.isRequired), - 'aria-disabled': boolToStr(this.provider.isDisabled), - 'aria-readonly': boolToStr(this.provider.isReadonly), - 'aria-invalid': boolToStr(this.provider.isInvalid), 'aria-describedby': this.describedBy, disabled: this.provider.isDisabled || undefined, readonly: this.provider.isReadonly || undefined,