From f3e5f113cab913faa932c984f8675196c2a52277 Mon Sep 17 00:00:00 2001 From: dev Date: Fri, 15 May 2026 20:01:11 +0200 Subject: [PATCH] Drive RatingGroup attrs from Soma runtime --- src/uix/morfo/components/rating-group.ts | 36 ++++++++----- .../rating-group-provider.svelte.ts | 51 +++++++++---------- 2 files changed, 49 insertions(+), 38 deletions(-) diff --git a/src/uix/morfo/components/rating-group.ts b/src/uix/morfo/components/rating-group.ts index 12af0ebe3..c560bbeda 100644 --- a/src/uix/morfo/components/rating-group.ts +++ b/src/uix/morfo/components/rating-group.ts @@ -18,12 +18,16 @@ export const ratingGroupMorfo = { role: 'slider', optional: false, data: [ - { attr: 'data-disabled', severity: 'optional' }, - { attr: 'data-readonly', severity: 'optional' }, - { attr: 'data-invalid', severity: 'optional' }, - { attr: 'data-required', severity: 'optional' }, - { attr: 'data-focused', severity: 'optional' }, - { attr: 'data-orientation', values: ['horizontal', 'vertical'] } + { attr: 'data-disabled', value: v.propRef('disabled'), severity: 'optional' }, + { attr: 'data-readonly', value: v.propRef('readonly'), severity: 'optional' }, + { attr: 'data-invalid', value: v.propRef('invalid'), severity: 'optional' }, + { attr: 'data-required', value: v.propRef('required'), severity: 'optional' }, + { attr: 'data-focused', value: v.propRef('focused'), severity: 'optional' }, + { + attr: 'data-orientation', + values: ['horizontal', 'vertical'], + value: v.propRef('orientation') + } ], aria: [ { attr: 'aria-valuenow', value: v.propRef('value') }, @@ -32,7 +36,7 @@ export const ratingGroupMorfo = { { attr: 'aria-orientation', value: v.propRef('orientation') }, { attr: 'aria-label', - value: v.translationRef('#?components.rating-group.label|Rating'), + value: v.propRef('ariaLabel'), severity: 'recommended' }, { @@ -79,11 +83,19 @@ export const ratingGroupMorfo = { optional: false, states: ['active', 'partial', 'inactive'], data: [ - { attr: 'data-state', values: ['active', 'partial', 'inactive'] }, - { attr: 'data-disabled', severity: 'optional' }, - { attr: 'data-readonly', severity: 'optional' }, - { attr: 'data-orientation', values: ['horizontal', 'vertical'] }, - { attr: 'data-value' } + { + attr: 'data-state', + values: ['active', 'partial', 'inactive'], + value: v.propRef('state') + }, + { attr: 'data-disabled', value: v.propRef('disabled'), severity: 'optional' }, + { attr: 'data-readonly', value: v.propRef('readonly'), severity: 'optional' }, + { + attr: 'data-orientation', + values: ['horizontal', 'vertical'], + value: v.propRef('orientation') + }, + { attr: 'data-value', value: v.propRef('value'), emit: 'value' } ], aria: [] } diff --git a/src/uix/soma/components/rating-group/rating-group-provider.svelte.ts b/src/uix/soma/components/rating-group/rating-group-provider.svelte.ts index e716520cd..d51bbfc52 100644 --- a/src/uix/soma/components/rating-group/rating-group-provider.svelte.ts +++ b/src/uix/soma/components/rating-group/rating-group-provider.svelte.ts @@ -1,5 +1,4 @@ import { context, type WithRefOpts } from '../../provider'; -import { boolToEmptyStrOrUndef } from '$adom'; import { readableActive, type Active, type ActiveProps, type StateProps } from '$libs/reactive'; import type { Direction, @@ -77,12 +76,26 @@ export class RatingGroupProvider { private constructor(opts: RatingGroupOpts) { this.opts = opts; this.soma = Soma.require(); - this.runtime = this.soma.runtime(ratingGroupMorfo, {}); + this.runtime = this.soma.runtime(ratingGroupMorfo, { + props: { + value: () => this.opts.value.current, + min: () => this.opts.min.current, + max: () => this.opts.max.current, + orientation: () => this.opts.orientation.current, + ariaLabel: () => this.resolvedAriaLabel.current, + required: () => this.isRequired, + disabled: () => this.isDisabled, + readonly: () => this.isReadonly, + invalid: () => this.isInvalid, + focused: () => this.focused + } + }); this.runtimePart = this.runtime.part('provider', { id: opts.id, ref: opts.ref, owner: this, - context: RatingGroupProvider.ctx + context: RatingGroupProvider.ctx, + syncAttrs: true }); } @@ -257,23 +270,7 @@ export class RatingGroupProvider { readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props, - role: 'slider' as const, - 'aria-valuenow': this.opts.value.current, - 'aria-valuemin': this.opts.min.current, - 'aria-valuemax': this.opts.max.current, - 'aria-orientation': this.opts.orientation.current, - 'aria-required': this.isRequired || undefined, - 'aria-disabled': this.isDisabled || undefined, - 'aria-readonly': this.isReadonly || undefined, - 'aria-invalid': this.isInvalid || undefined, - 'aria-label': this.resolvedAriaLabel.current, tabindex: this.isDisabled ? -1 : 0, - 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), - 'data-readonly': boolToEmptyStrOrUndef(this.isReadonly), - 'data-invalid': boolToEmptyStrOrUndef(this.isInvalid), - 'data-required': boolToEmptyStrOrUndef(this.isRequired), - 'data-focused': boolToEmptyStrOrUndef(this.focused), - 'data-orientation': this.opts.orientation.current, onkeydown: this.onkeydown, onpointerleave: this.onpointerleave, onfocus: this.onfocus, @@ -302,7 +299,15 @@ export class RatingGroupItemProvider { this.runtimePart = this.provider.runtime.part('item', { id: opts.id, ref: opts.ref, - owner: this + owner: this, + props: { + state: () => this.state, + disabled: () => this.isDisabled, + readonly: () => this.provider.isReadonly, + orientation: () => this.provider.opts.orientation.current, + value: () => this.opts.index.current + 1 + }, + syncAttrs: true }); } @@ -331,12 +336,6 @@ export class RatingGroupItemProvider { readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props, - role: 'presentation' as const, - 'data-state': this.state, - 'data-disabled': boolToEmptyStrOrUndef(this.isDisabled), - 'data-readonly': boolToEmptyStrOrUndef(this.provider.isReadonly), - 'data-orientation': this.provider.opts.orientation.current, - 'data-value': this.opts.index.current + 1, onclick: this.onclick, onpointermove: this.onpointermove } as const)