From 5581f548cdfdc82e8a5a19dee5cc6f673a32eb04 Mon Sep 17 00:00:00 2001 From: dev Date: Fri, 15 May 2026 03:15:56 +0200 Subject: [PATCH] Consolidate Soma range calendar runtime --- .../range-calendar-provider.svelte.ts | 146 ++++++++++-------- 1 file changed, 83 insertions(+), 63 deletions(-) diff --git a/src/uix/soma/components/range-calendar/range-calendar-provider.svelte.ts b/src/uix/soma/components/range-calendar/range-calendar-provider.svelte.ts index c5c4639a7..c8c09e91a 100644 --- a/src/uix/soma/components/range-calendar/range-calendar-provider.svelte.ts +++ b/src/uix/soma/components/range-calendar/range-calendar-provider.svelte.ts @@ -42,7 +42,7 @@ import type { // ── Contract ───────────────────────────────────────────────────────────────── import { rangeCalendarMorfo } from '../../../morfo/components/range-calendar'; -import type { SomaRuntimePart } from '../../runtime.svelte'; +import type { SomaRuntime, SomaRuntimePart } from '../../runtime.svelte'; const attrs = createAttrs(rangeCalendarMorfo); @@ -102,6 +102,8 @@ export function resolveInitialRangeCalendarPlaceholder( export class RangeCalendarProvider { readonly opts: RangeCalendarOpts; readonly runtimePart: SomaRuntimePart; + readonly soma: Soma; + readonly runtime: SomaRuntime; static readonly ctx = context('RangeCalendar'); static get(): RangeCalendarProvider | undefined { return this.ctx.getOr(undefined) as RangeCalendarProvider | undefined; @@ -113,8 +115,6 @@ export class RangeCalendarProvider { return new RangeCalendarProvider(opts); } - readonly soma = Soma.get(); - headingId = state(''); announcement = $state(''); @@ -132,14 +132,14 @@ export class RangeCalendarProvider { private constructor(opts: RangeCalendarOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('provider', { - id: opts.id, - ref: opts.ref, - owner: this, - context: RangeCalendarProvider.ctx - }); + this.soma = Soma.require(); + this.runtime = this.soma.runtime(rangeCalendarMorfo, {}); + this.runtimePart = this.runtime.part('provider', { + id: opts.id, + ref: opts.ref, + owner: this, + context: RangeCalendarProvider.ctx + }); // Initial focus management used to live in the wrapper. Centralize it // in the provider so the wrapper stays thin. @@ -157,7 +157,7 @@ export class RangeCalendarProvider { // ── Derived reactive model ──────────────────────────────────────────────── readonly effectiveLocale = $derived.by( - () => this.opts.locale.current || this.soma?.langs.getLocale() || 'en' + () => this.opts.locale.current || this.soma.langs.getLocale() || 'en' ); readonly months: Month[] = $derived.by(() => @@ -183,7 +183,7 @@ export class RangeCalendarProvider { ); readonly dateOrder: DateOrder = $derived.by(() => { - return (this.soma?.dates?.getDateOrder?.() ?? 'DMY') as DateOrder; + return (this.soma.dates?.getDateOrder?.() ?? 'DMY') as DateOrder; }); readonly visibleMonths = $derived.by(() => this.months.map((m) => m.value)); @@ -226,7 +226,7 @@ export class RangeCalendarProvider { readonly fullCalendarLabel = $derived.by(() => { const base = this.opts.calendarLabel.current ?? - this.soma?.langs.ts(RANGE_CALENDAR_LANGS.LABEL) ?? + this.soma.langs.ts(RANGE_CALENDAR_LANGS.LABEL) ?? 'Range calendar'; return `${base}, ${this.headingValue}`; }); @@ -510,10 +510,12 @@ export class RangeCalendarHeaderProvider { } private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('header', { id: opts.id, ref: opts.ref, owner: this }); - RangeCalendarProvider.require(); + const provider = RangeCalendarProvider.require(); + this.runtimePart = provider.runtime.part('header', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props } as const) @@ -529,10 +531,12 @@ export class RangeCalendarHeadingProvider { readonly provider: RangeCalendarProvider; private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('heading', { id: opts.id, ref: opts.ref, owner: this }); this.provider = RangeCalendarProvider.require(); + this.runtimePart = this.provider.runtime.part('heading', { + id: opts.id, + ref: opts.ref, + owner: this + }); this.provider.headingId.current = opts.id.current; } readonly headingValue = $derived.by(() => this.provider.headingValue); @@ -551,10 +555,12 @@ abstract class RangeCalendarPaginationButtonProvider { protected constructor(opts: WithRefOpts, part: 'prev-button' | 'next-button', labelRef: string) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part(part, { id: opts.id, ref: opts.ref, owner: this }); this.provider = RangeCalendarProvider.require(); + this.runtimePart = this.provider.runtime.part(part, { + id: opts.id, + ref: opts.ref, + owner: this + }); this.labelRef = labelRef; } @@ -568,7 +574,7 @@ abstract class RangeCalendarPaginationButtonProvider { return this.runtimePart.assert({ ...this.runtimePart.props, type: 'button' as const, - 'aria-label': this.provider.soma?.langs.ts(this.labelRef), + 'aria-label': this.provider.soma.langs.ts(this.labelRef), 'aria-disabled': boolToStr(disabled), 'data-disabled': boolToEmptyStrOrUndef(disabled), disabled, @@ -629,10 +635,12 @@ export class RangeCalendarMonthSelectProvider { private constructor(opts: RangeCalendarMonthSelectOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('month-select', { id: opts.id, ref: opts.ref, owner: this }); this.provider = RangeCalendarProvider.require(); + this.runtimePart = this.provider.runtime.part('month-select', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly monthItems: RangeCalendarMonthSelectSnippetProps['monthItems'] = $derived.by(() => { @@ -668,7 +676,7 @@ export class RangeCalendarMonthSelectProvider { const disabled = this.opts.disabled.current || this.provider.opts.disabled.current; return this.runtimePart.assert({ ...this.runtimePart.props, - 'aria-label': this.provider.soma?.langs.ts(RANGE_CALENDAR_LANGS.MONTH_SELECT), + 'aria-label': this.provider.soma.langs.ts(RANGE_CALENDAR_LANGS.MONTH_SELECT), 'aria-disabled': boolToStr(disabled), 'data-disabled': boolToEmptyStrOrUndef(disabled), disabled, @@ -698,10 +706,12 @@ export class RangeCalendarYearSelectProvider { private constructor(opts: RangeCalendarYearSelectOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('year-select', { id: opts.id, ref: opts.ref, owner: this }); this.provider = RangeCalendarProvider.require(); + this.runtimePart = this.provider.runtime.part('year-select', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly yearItems: RangeCalendarYearSelectSnippetProps['yearItems'] = $derived.by(() => { @@ -737,7 +747,7 @@ export class RangeCalendarYearSelectProvider { const disabled = this.opts.disabled.current || this.provider.opts.disabled.current; return this.runtimePart.assert({ ...this.runtimePart.props, - 'aria-label': this.provider.soma?.langs.ts(RANGE_CALENDAR_LANGS.YEAR_SELECT), + 'aria-label': this.provider.soma.langs.ts(RANGE_CALENDAR_LANGS.YEAR_SELECT), 'aria-disabled': boolToStr(disabled), 'data-disabled': boolToEmptyStrOrUndef(disabled), disabled, @@ -758,10 +768,12 @@ export class RangeCalendarGridProvider { readonly provider: RangeCalendarProvider; private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('grid', { id: opts.id, ref: opts.ref, owner: this }); this.provider = RangeCalendarProvider.require(); + this.runtimePart = this.provider.runtime.part('grid', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly props = $derived.by(() => { const headingId = this.provider.headingId.current; @@ -784,10 +796,12 @@ export class RangeCalendarGridHeadProvider { } private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('grid-head', { id: opts.id, ref: opts.ref, owner: this }); - RangeCalendarProvider.require(); + const provider = RangeCalendarProvider.require(); + this.runtimePart = provider.runtime.part('grid-head', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props } as const) @@ -802,10 +816,12 @@ export class RangeCalendarGridBodyProvider { } private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('grid-body', { id: opts.id, ref: opts.ref, owner: this }); - RangeCalendarProvider.require(); + const provider = RangeCalendarProvider.require(); + this.runtimePart = provider.runtime.part('grid-body', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props } as const) @@ -820,10 +836,12 @@ export class RangeCalendarGridRowProvider { } private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('grid-row', { id: opts.id, ref: opts.ref, owner: this }); - RangeCalendarProvider.require(); + const provider = RangeCalendarProvider.require(); + this.runtimePart = provider.runtime.part('grid-row', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props, role: 'row' as const } as const) @@ -838,10 +856,12 @@ export class RangeCalendarHeadCellProvider { } private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('head-cell', { id: opts.id, ref: opts.ref, owner: this }); - RangeCalendarProvider.require(); + const provider = RangeCalendarProvider.require(); + this.runtimePart = provider.runtime.part('head-cell', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly props = $derived.by(() => this.runtimePart.assert({ ...this.runtimePart.props, scope: 'col' as const } as const) @@ -871,15 +891,13 @@ export class RangeCalendarCellProvider { private constructor(opts: RangeCalendarCellOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('cell', { - id: opts.id, - ref: opts.ref, - owner: this, - context: RangeCalendarCellProvider.ctx - }); this.provider = RangeCalendarProvider.require(); + this.runtimePart = this.provider.runtime.part('cell', { + id: opts.id, + ref: opts.ref, + owner: this, + context: RangeCalendarCellProvider.ctx + }); } readonly flags = $derived.by(() => this.provider.computeFlags(this.opts.date.current)); @@ -959,11 +977,13 @@ export class RangeCalendarDayProvider { private constructor(opts: WithRefOpts) { this.opts = opts; - this.runtimePart = Soma.require() - .runtime(rangeCalendarMorfo, {}) - .part('day', { id: opts.id, ref: opts.ref, owner: this }); this.provider = RangeCalendarProvider.require(); this.cell = RangeCalendarCellProvider.require(); + this.runtimePart = this.provider.runtime.part('day', { + id: opts.id, + ref: opts.ref, + owner: this + }); } readonly focused = $derived.by(() =>