|
|
|
|
@ -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<RangeCalendarProvider>('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,9 +132,9 @@ export class RangeCalendarProvider {
|
|
|
|
|
|
|
|
|
|
private constructor(opts: RangeCalendarOpts) {
|
|
|
|
|
this.opts = opts;
|
|
|
|
|
this.runtimePart = Soma.require()
|
|
|
|
|
.runtime(rangeCalendarMorfo, {})
|
|
|
|
|
.part('provider', {
|
|
|
|
|
this.soma = Soma.require();
|
|
|
|
|
this.runtime = this.soma.runtime(rangeCalendarMorfo, {});
|
|
|
|
|
this.runtimePart = this.runtime.part('provider', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
owner: this,
|
|
|
|
|
@ -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<DateValue>[] = $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', {
|
|
|
|
|
this.provider = RangeCalendarProvider.require();
|
|
|
|
|
this.runtimePart = this.provider.runtime.part('cell', {
|
|
|
|
|
id: opts.id,
|
|
|
|
|
ref: opts.ref,
|
|
|
|
|
owner: this,
|
|
|
|
|
context: RangeCalendarCellProvider.ctx
|
|
|
|
|
});
|
|
|
|
|
this.provider = RangeCalendarProvider.require();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
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(() =>
|
|
|
|
|
|