diff --git a/src/uix/morfo/components/css-field.ts b/src/uix/morfo/components/css-field.ts index 68b2a984e..3cd03085e 100644 --- a/src/uix/morfo/components/css-field.ts +++ b/src/uix/morfo/components/css-field.ts @@ -158,9 +158,9 @@ export const cssFieldMorfo = { }, { attr: 'aria-disabled', - value: v.literal('true'), + value: v.propRef('disabled'), severity: 'optional', - condition: { when: 'prop-truthy', prop: 'disabled' } + ariaBoolean: true } ] }, @@ -185,9 +185,9 @@ export const cssFieldMorfo = { }, { attr: 'aria-disabled', - value: v.literal('true'), + value: v.propRef('disabled'), severity: 'optional', - condition: { when: 'prop-truthy', prop: 'disabled' } + ariaBoolean: true } ] }, diff --git a/src/uix/morfo/components/number-field.ts b/src/uix/morfo/components/number-field.ts index 5691063b6..03c505a4a 100644 --- a/src/uix/morfo/components/number-field.ts +++ b/src/uix/morfo/components/number-field.ts @@ -150,9 +150,9 @@ export const numberFieldMorfo = { }, { attr: 'aria-disabled', - value: v.literal('true'), + value: v.propRef('disabled'), severity: 'optional', - condition: { when: 'prop-truthy', prop: 'disabled' } + ariaBoolean: true } ] }, @@ -177,9 +177,9 @@ export const numberFieldMorfo = { }, { attr: 'aria-disabled', - value: v.literal('true'), + value: v.propRef('disabled'), severity: 'optional', - condition: { when: 'prop-truthy', prop: 'disabled' } + ariaBoolean: true } ] }, 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 8a4de984e..cf4901569 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 @@ -1,6 +1,6 @@ import { watch } from 'runed'; import { context, type WithRefOpts } from '../../provider'; -import { boolToEmptyStrOrUndef, boolToStr, isHTMLElement } from '$adom'; +import { boolToEmptyStrOrUndef, isHTMLElement } from '$adom'; import { readableActive, type Active, type ActiveProps, type StateProps } from '$libs/reactive'; import type { OnChangeFn, @@ -586,7 +586,9 @@ export class CssFieldIncrementTriggerProvider { this.runtimePart = this.provider.runtime.part('increment-trigger', { id: opts.id, ref: opts.ref, - owner: this + owner: this, + // trigger-local disabled (includes atMax) → renderProps resolves aria-disabled + props: { disabled: () => this.isDisabled } }); } @@ -609,13 +611,10 @@ export class CssFieldIncrementTriggerProvider { readonly props = $derived.by(() => this.runtimePart.assert({ - ...this.runtimePart.props, - type: 'button' as const, + // type, aria-label, data-spin-field, aria-disabled are morfo-declared. + ...this.runtimePart.renderProps(), tabindex: -1, disabled: this.isDisabled || undefined, - 'aria-label': this.provider.soma.langs.ts(CSS_FIELD_LANGS.INCREMENT), - 'data-spin-field-increment-trigger': '', - 'aria-disabled': boolToStr(this.isDisabled), 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), onclick: this.handleClick, onpointerdown: this.handlePointerDown, @@ -653,7 +652,9 @@ export class CssFieldDecrementTriggerProvider { this.runtimePart = this.provider.runtime.part('decrement-trigger', { id: opts.id, ref: opts.ref, - owner: this + owner: this, + // trigger-local disabled (includes atMin) → renderProps resolves aria-disabled + props: { disabled: () => this.isDisabled } }); } @@ -676,13 +677,10 @@ export class CssFieldDecrementTriggerProvider { readonly props = $derived.by(() => this.runtimePart.assert({ - ...this.runtimePart.props, - type: 'button' as const, + // type, aria-label, data-spin-field, aria-disabled are morfo-declared. + ...this.runtimePart.renderProps(), tabindex: -1, disabled: this.isDisabled || undefined, - 'aria-label': this.provider.soma.langs.ts(CSS_FIELD_LANGS.DECREMENT), - 'data-spin-field-decrement-trigger': '', - 'aria-disabled': boolToStr(this.isDisabled), 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), onclick: this.handleClick, onpointerdown: this.handlePointerDown, @@ -810,10 +808,8 @@ export class CssFieldScrubberProvider { readonly props = $derived.by(() => this.runtimePart.assert({ - ...this.runtimePart.props, - role: 'presentation' as const, - 'aria-hidden': true as const, - 'data-spin-field-scrubber': '', + // role, aria-hidden, data-spin-field-scrubber are morfo-declared. + ...this.runtimePart.renderProps(), 'data-scrubbing': boolToEmptyStrOrUndef(this.provider.scrubbing), 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), style: { diff --git a/src/uix/soma/components/number-field/number-field-provider.svelte.ts b/src/uix/soma/components/number-field/number-field-provider.svelte.ts index cde5fa552..384414adb 100644 --- a/src/uix/soma/components/number-field/number-field-provider.svelte.ts +++ b/src/uix/soma/components/number-field/number-field-provider.svelte.ts @@ -1,6 +1,6 @@ import { watch } from 'runed'; import { context, type WithRefOpts } from '../../provider'; -import { boolToEmptyStrOrUndef, boolToStr, isHTMLElement } from '$adom'; +import { boolToEmptyStrOrUndef, isHTMLElement } from '$adom'; import { readableActive, type Active, type ActiveProps, type StateProps } from '$libs/reactive'; import type { OnChangeFn, @@ -11,7 +11,6 @@ import type { } from '../../types'; import { KEYS } from '../../keyboard'; import { Soma } from '../../core/soma.svelte'; -import { NUMBER_FIELD_LANGS } from './langs'; import { FieldProvider } from '../field'; // ── Intl fallback cache ────────────────────────────────────────────────────── @@ -660,7 +659,9 @@ export class NumberFieldIncrementTriggerProvider { this.runtimePart = this.provider.runtime.part('increment-trigger', { id: opts.id, ref: opts.ref, - owner: this + owner: this, + // trigger-local disabled (includes atMax) → renderProps resolves aria-disabled + props: { disabled: () => this.isDisabled } }); } @@ -683,13 +684,10 @@ export class NumberFieldIncrementTriggerProvider { readonly props = $derived.by(() => this.runtimePart.assert({ - ...this.runtimePart.props, - type: 'button' as const, + // type, aria-label, data-spin-field, aria-disabled are morfo-declared. + ...this.runtimePart.renderProps(), tabindex: -1, disabled: this.isDisabled || undefined, - 'aria-label': this.provider.soma.langs.ts(NUMBER_FIELD_LANGS.INCREMENT), - 'data-spin-field-increment-trigger': '', - 'aria-disabled': boolToStr(this.isDisabled), 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), onclick: this.handleClick, onpointerdown: this.handlePointerDown, @@ -727,7 +725,9 @@ export class NumberFieldDecrementTriggerProvider { this.runtimePart = this.provider.runtime.part('decrement-trigger', { id: opts.id, ref: opts.ref, - owner: this + owner: this, + // trigger-local disabled (includes atMin) → renderProps resolves aria-disabled + props: { disabled: () => this.isDisabled } }); } @@ -750,13 +750,10 @@ export class NumberFieldDecrementTriggerProvider { readonly props = $derived.by(() => this.runtimePart.assert({ - ...this.runtimePart.props, - type: 'button' as const, + // type, aria-label, data-spin-field, aria-disabled are morfo-declared. + ...this.runtimePart.renderProps(), tabindex: -1, disabled: this.isDisabled || undefined, - 'aria-label': this.provider.soma.langs.ts(NUMBER_FIELD_LANGS.DECREMENT), - 'data-spin-field-decrement-trigger': '', - 'aria-disabled': boolToStr(this.isDisabled), 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), onclick: this.handleClick, onpointerdown: this.handlePointerDown, @@ -889,10 +886,8 @@ export class NumberFieldScrubberProvider { readonly props = $derived.by(() => this.runtimePart.assert({ - ...this.runtimePart.props, - role: 'presentation' as const, - 'aria-hidden': true as const, - 'data-spin-field-scrubber': '', + // role, aria-hidden, data-spin-field-scrubber are morfo-declared. + ...this.runtimePart.renderProps(), 'data-scrubbing': boolToEmptyStrOrUndef(this.provider.scrubbing), 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), style: {