77 lines
2.2 KiB
Svelte
77 lines
2.2 KiB
Svelte
<script lang="ts">
|
|
import type { ComponentProps } from 'svelte';
|
|
import type Calendar from './calendar.svelte';
|
|
import CalendarMonthSelect from './calendar-month-select.svelte';
|
|
import CalendarYearSelect from './calendar-year-select.svelte';
|
|
import { DateFormatter, getLocalTimeZone, type DateValue } from '@internationalized/date';
|
|
|
|
let {
|
|
captionLayout,
|
|
months,
|
|
monthFormat,
|
|
years,
|
|
yearFormat,
|
|
month,
|
|
locale,
|
|
placeholder = $bindable(),
|
|
monthIndex = 0
|
|
}: {
|
|
captionLayout: ComponentProps<typeof Calendar>['captionLayout'];
|
|
months: ComponentProps<typeof CalendarMonthSelect>['months'];
|
|
monthFormat: ComponentProps<typeof CalendarMonthSelect>['monthFormat'];
|
|
years: ComponentProps<typeof CalendarYearSelect>['years'];
|
|
yearFormat: ComponentProps<typeof CalendarYearSelect>['yearFormat'];
|
|
month: DateValue;
|
|
placeholder: DateValue | undefined;
|
|
locale: string;
|
|
monthIndex: number;
|
|
} = $props();
|
|
|
|
function formatYear(date: DateValue) {
|
|
const dateObj = date.toDate(getLocalTimeZone());
|
|
if (typeof yearFormat === 'function') return yearFormat(dateObj.getFullYear());
|
|
return new DateFormatter(locale, { year: yearFormat }).format(dateObj);
|
|
}
|
|
|
|
function formatMonth(date: DateValue) {
|
|
const dateObj = date.toDate(getLocalTimeZone());
|
|
if (typeof monthFormat === 'function') return monthFormat(dateObj.getMonth() + 1);
|
|
return new DateFormatter(locale, { month: monthFormat }).format(dateObj);
|
|
}
|
|
</script>
|
|
|
|
{#snippet MonthSelect()}
|
|
<CalendarMonthSelect
|
|
{months}
|
|
{monthFormat}
|
|
value={month.month}
|
|
onchange={(e) => {
|
|
if (!placeholder) return;
|
|
const v = Number.parseInt(e.currentTarget.value);
|
|
const newPlaceholder = placeholder.set({ month: v });
|
|
placeholder = newPlaceholder.subtract({ months: monthIndex });
|
|
}}
|
|
/>
|
|
{/snippet}
|
|
|
|
{#snippet YearSelect()}
|
|
<CalendarYearSelect {years} {yearFormat} value={month.year} />
|
|
{/snippet}
|
|
|
|
{#if captionLayout === 'dropdown'}
|
|
{@render MonthSelect()}
|
|
{@render YearSelect()}
|
|
{:else if captionLayout === 'dropdown-months'}
|
|
{@render MonthSelect()}
|
|
{#if placeholder}
|
|
{formatYear(placeholder)}
|
|
{/if}
|
|
{:else if captionLayout === 'dropdown-years'}
|
|
{#if placeholder}
|
|
{formatMonth(placeholder)}
|
|
{/if}
|
|
{@render YearSelect()}
|
|
{:else}
|
|
{formatMonth(month)} {formatYear(month)}
|
|
{/if}
|