{
  "$schema": "https://uipkge.dev/schema/registry-item.json",
  "name": "calendar",
  "title": "Calendar",
  "type": "registry:ui",
  "files": [
    {
      "path": "packages/registry-svelte/components/calendar/Calendar.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLAttributes } from 'svelte/elements'\n  import { CalendarDate } from '@internationalized/date'\n  import type { DateValue } from '@internationalized/date'\n  import type { CalendarRange } from './calendar-state.svelte'\n  import type { LayoutTypes } from './index'\n\n  export interface CalendarProps extends Omit<HTMLAttributes<HTMLDivElement>, 'placeholder'> {\n    /**\n     * Selected date (`type=\"single\"`), dates (`type=\"multiple\"`), or range\n     * (`type=\"range\"` as `{ start, end }`). Two-way bindable (`bind:value`).\n     *\n     * INTENTIONAL DIVERGENCE from React: React's DayPicker-based Calendar uses\n     * native `Date` (`selected: Date | Date[] | { from, to }`). This Svelte\n     * calendar keeps `DateValue` to match the Vue/reka-ui twin. Convert at the\n     * boundary with `new CalendarDate(d.getFullYear(), d.getMonth() + 1, d.getDate())`.\n     */\n    value?: DateValue | DateValue[] | CalendarRange\n    /** Viewed month. Two-way bindable (`bind:placeholder`). */\n    placeholder?: DateValue\n    type?: 'single' | 'multiple' | 'range'\n    /** React DayPicker-parity alias for `type`. When set, overrides `type`. */\n    mode?: 'single' | 'multiple' | 'range'\n    /** Whether to render days outside the current month. Mirrors React `showOutsideDays` (default true). When false, outside days render as invisible placeholders. */\n    showOutsideDays?: boolean\n    numberOfMonths?: number\n    pagedNavigation?: boolean\n    weekStartsOn?: number\n    fixedWeeks?: boolean\n    weekdayFormat?: 'narrow' | 'short' | 'long'\n    locale?: string\n    minValue?: DateValue\n    maxValue?: DateValue\n    disabled?: boolean\n    readonly?: boolean\n    isDateDisabled?: (date: DateValue) => boolean\n    isDateUnavailable?: (date: DateValue) => boolean\n    layout?: LayoutTypes\n    yearRange?: DateValue[]\n    onValueChange?: (value: DateValue | DateValue[] | CalendarRange | undefined) => void\n    onPlaceholderChange?: (placeholder: DateValue) => void\n    /** Overrides the prev/next chevron icons. */\n    prevIcon?: Snippet\n    nextIcon?: Snippet\n    /** Overrides the whole heading area. Receives the viewed date plus month/year jump helpers. */\n    heading?: Snippet<\n      [\n        {\n          date: DateValue\n          headingValue: string\n          months: CalendarDate[]\n          years: DateValue[]\n          setMonth: (month: number) => void\n          setYear: (year: number) => void\n        },\n      ]\n    >\n    /** Overrides a day cell's content. */\n    cell?: Snippet<[{ day: CalendarDate; month: CalendarDate }]>\n    ref?: HTMLDivElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { setContext } from 'svelte'\n  import { getLocalTimeZone, today } from '@internationalized/date'\n  import { ChevronDown } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n  import { CALENDAR_CONTEXT_KEY, CalendarState } from './calendar-state.svelte'\n  import CalendarCell from './CalendarCell.svelte'\n  import CalendarCellTrigger from './CalendarCellTrigger.svelte'\n  import CalendarGrid from './CalendarGrid.svelte'\n  import CalendarGridBody from './CalendarGridBody.svelte'\n  import CalendarGridHead from './CalendarGridHead.svelte'\n  import CalendarGridRow from './CalendarGridRow.svelte'\n  import CalendarHeadCell from './CalendarHeadCell.svelte'\n  import CalendarHeader from './CalendarHeader.svelte'\n  import CalendarHeading from './CalendarHeading.svelte'\n  import CalendarNextButton from './CalendarNextButton.svelte'\n  import CalendarPrevButton from './CalendarPrevButton.svelte'\n\n  let {\n    class: className,\n    value = $bindable<DateValue | DateValue[] | CalendarRange | undefined>(undefined),\n    placeholder = $bindable<DateValue | undefined>(undefined),\n    type = 'single',\n    mode = undefined,\n    showOutsideDays = true,\n    numberOfMonths = 1,\n    pagedNavigation = false,\n    weekStartsOn = undefined,\n    fixedWeeks = false,\n    weekdayFormat = 'narrow',\n    locale = 'en',\n    minValue = undefined,\n    maxValue = undefined,\n    disabled = false,\n    readonly = false,\n    isDateDisabled = undefined,\n    isDateUnavailable = undefined,\n    layout = undefined,\n    yearRange: yearRangeProp = undefined,\n    onValueChange,\n    onPlaceholderChange,\n    prevIcon,\n    nextIcon,\n    heading,\n    cell,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: CalendarProps = $props()\n\n  // React parity: `mode` overrides `type` when set (`mode=\"range\"` === `type=\"range\"`).\n  const effectiveType = $derived(mode ?? type)\n\n  // Initial capture is intentional: props sync into the state via the $effect below.\n  // svelte-ignore state_referenced_locally\n  const state = new CalendarState(\n    {\n      type: effectiveType,\n      locale,\n      weekStartsOn,\n      fixedWeeks,\n      numberOfMonths,\n      pagedNavigation,\n      disabled,\n      readonly,\n      weekdayFormat,\n      minValue,\n      maxValue,\n      isDateDisabled,\n      isDateUnavailable,\n      showOutsideDays,\n      value,\n      placeholder,\n    },\n    {\n      onValueChange: (v) => {\n        value = v\n        onValueChange?.(v)\n      },\n      onPlaceholderChange: (p) => {\n        placeholder = p\n        onPlaceholderChange?.(p)\n      },\n    },\n  )\n  setContext(CALENDAR_CONTEXT_KEY, state)\n\n  // Inward sync: parent props → state (equality-guarded, never loops with\n  // the outward callbacks above).\n  $effect(() => {\n    state.syncFromProps({\n      type: effectiveType,\n      locale,\n      weekStartsOn,\n      fixedWeeks,\n      numberOfMonths,\n      pagedNavigation,\n      disabled,\n      readonly,\n      weekdayFormat,\n      minValue,\n      maxValue,\n      isDateDisabled,\n      isDateUnavailable,\n      showOutsideDays,\n      value,\n      placeholder,\n    })\n  })\n\n  // The state owns the keyboard-focus root for arrow-key day navigation.\n  $effect(() => {\n    state.rootEl = ref\n  })\n\n  const yearRange = $derived.by((): DateValue[] => {\n    if (yearRangeProp) return yearRangeProp\n    const base = state.placeholder ?? today(getLocalTimeZone())\n    const start = minValue ?? base.subtract({ years: 100 })\n    const end = maxValue ?? base.add({ years: 10 })\n    const years: DateValue[] = []\n    let current = start\n    let guard = 0\n    while (current.compare(end) <= 0 && guard++ < 500) {\n      years.push(current)\n      current = current.add({ years: 1 })\n    }\n    return years\n  })\n\n  const monthsOfYear = $derived.by((): CalendarDate[] => {\n    const y = state.placeholder.year\n    return Array.from({ length: 12 }, (_, i) => new CalendarDate(y, i + 1, 1))\n  })\n\n  const monthName = $derived.by(() => {\n    const fmt = new Intl.DateTimeFormat(locale, { month: 'short' })\n    return (d: DateValue) => fmt.format(new Date(d.year, d.month - 1, 1))\n  })\n\n  const yearName = $derived.by(() => {\n    const fmt = new Intl.DateTimeFormat(locale, { year: 'numeric' })\n    return (d: DateValue) => fmt.format(new Date(d.year, d.month - 1, 1))\n  })\n\n  /** Clamp the day so Jan 31 → Feb lands on Feb 28/29 instead of overflowing. */\n  function clampDay(year: number, month: number, day: number): number {\n    return Math.min(day, new Date(year, month, 0).getDate())\n  }\n\n  function setMonth(month: number) {\n    const p = state.placeholder\n    state.setPlaceholder(new CalendarDate(p.year, month, clampDay(p.year, month, p.day)))\n  }\n\n  function setYear(year: number) {\n    const p = state.placeholder\n    state.setPlaceholder(new CalendarDate(year, p.month, clampDay(year, p.month, p.day)))\n  }\n\n  function onMonthChange(e: Event) {\n    setMonth(Number((e.target as HTMLSelectElement | null)?.value))\n  }\n\n  function onYearChange(e: Event) {\n    setYear(Number((e.target as HTMLSelectElement | null)?.value))\n  }\n</script>\n\n{#snippet monthSelect(date: DateValue)}\n  <div class=\"relative inline-flex items-center\">\n    <select\n      data-uipkge\n      data-slot=\"calendar-month-select\"\n      class=\"border-input hover:bg-accent/60 text-foreground focus-visible:ring-ring h-8 cursor-pointer appearance-none rounded-md border bg-transparent pr-6 pl-2.5 text-xs font-medium transition-colors focus-visible:ring-1 focus-visible:outline-none\"\n      value={date.month}\n      onchange={onMonthChange}\n    >\n      {#each monthsOfYear as month (month.toString())}\n        <option value={month.month} class=\"bg-popover text-popover-foreground\">\n          {monthName(month)}\n        </option>\n      {/each}\n    </select>\n    <ChevronDown class=\"text-muted-foreground pointer-events-none absolute right-1.5 size-3.5 opacity-60\" />\n  </div>\n{/snippet}\n\n{#snippet yearSelect(date: DateValue)}\n  <div class=\"relative inline-flex items-center\">\n    <select\n      data-uipkge\n      data-slot=\"calendar-year-select\"\n      class=\"border-input hover:bg-accent/60 text-foreground focus-visible:ring-ring h-8 cursor-pointer appearance-none rounded-md border bg-transparent pr-6 pl-2.5 text-xs font-medium transition-colors focus-visible:ring-1 focus-visible:outline-none\"\n      value={date.year}\n      onchange={onYearChange}\n    >\n      {#each yearRange as year (year.toString())}\n        <option value={year.year} class=\"bg-popover text-popover-foreground\">\n          {yearName(year)}\n        </option>\n      {/each}\n    </select>\n    <ChevronDown class=\"text-muted-foreground pointer-events-none absolute right-1.5 size-3.5 opacity-60\" />\n  </div>\n{/snippet}\n\n<div bind:this={ref} data-uipkge data-slot=\"calendar\" class={cn('p-3', className)} {...restProps}>\n  <CalendarHeader class=\"pt-0\">\n    <nav class=\"absolute inset-x-0 top-0 flex items-center justify-between gap-1\" aria-label=\"Calendar navigation\">\n      <CalendarPrevButton icon={prevIcon} />\n      <CalendarNextButton icon={nextIcon} />\n    </nav>\n\n    {#if heading}\n      {@render heading({\n        date: state.placeholder,\n        headingValue: state.headingValue,\n        months: monthsOfYear,\n        years: yearRange,\n        setMonth,\n        setYear,\n      })}\n    {:else if layout === 'month-and-year'}\n      <div class=\"flex items-center justify-center gap-1\">\n        {@render monthSelect(state.placeholder)}\n        {@render yearSelect(state.placeholder)}\n      </div>\n    {:else if layout === 'month-only'}\n      <div class=\"flex items-center justify-center gap-1\">\n        {@render monthSelect(state.placeholder)}\n        {yearName(state.placeholder)}\n      </div>\n    {:else if layout === 'year-only'}\n      <div class=\"flex items-center justify-center gap-1\">\n        {monthName(state.placeholder)}\n        {@render yearSelect(state.placeholder)}\n      </div>\n    {:else}\n      <CalendarHeading />\n    {/if}\n  </CalendarHeader>\n\n  <div class=\"mt-4 flex flex-col gap-y-4 sm:flex-row sm:gap-x-4 sm:gap-y-0\">\n    {#each state.grids as month (month.value.toString())}\n      <CalendarGrid class=\"motion-safe:animate-[calendar-month-in_220ms_cubic-bezier(0.22,1,0.36,1)_both]\">\n        <CalendarGridHead>\n          <CalendarGridRow>\n            {#each state.weekDays as day, i (i)}\n              <CalendarHeadCell>\n                {day}\n              </CalendarHeadCell>\n            {/each}\n          </CalendarGridRow>\n        </CalendarGridHead>\n        <CalendarGridBody>\n          {#each month.rows as weekDates, index (`weekDate-${index}`)}\n            <CalendarGridRow class=\"mt-2 w-full\">\n              {#each weekDates as weekDate (weekDate.toString())}\n                <CalendarCell date={weekDate}>\n                  <CalendarCellTrigger day={weekDate} month={month.value} {cell} />\n                </CalendarCell>\n              {/each}\n            </CalendarGridRow>\n          {/each}\n        </CalendarGridBody>\n      </CalendarGrid>\n    {/each}\n  </div>\n\n  {@render children?.()}\n</div>\n\n<style>\n  :global {\n    @keyframes calendar-month-in {\n      from {\n        opacity: 0;\n        transform: translateY(4px);\n      }\n      to {\n        opacity: 1;\n        transform: translateY(0);\n      }\n    }\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    :global([data-slot='calendar'] [class*='animate-\\[calendar-month']) {\n      animation: none !important;\n    }\n  }\n</style>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/Calendar.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarCell.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n  import type { CalendarDate } from '@internationalized/date'\n\n  export interface CalendarCellProps extends HTMLAttributes<HTMLTableCellElement> {\n    date: CalendarDate\n    ref?: HTMLTableCellElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { getContext } from 'svelte'\n  import { cn } from '$lib/utils'\n  import { CALENDAR_CONTEXT_KEY, type CalendarState } from './calendar-state.svelte'\n\n  let { class: className, date, children, ref = $bindable(null), ...restProps }: CalendarCellProps = $props()\n\n  const state = getContext<CalendarState | undefined>(CALENDAR_CONTEXT_KEY)\n  const disabledDate = $derived(state?.isDisabledDate(date) ?? false)\n  const isRange = $derived(state?.type === 'range')\n</script>\n\n<td\n  bind:this={ref}\n  data-uipkge\n  data-slot=\"calendar-cell\"\n  data-disabled={disabledDate ? '' : undefined}\n  class={cn(\n    'relative flex-1 p-0 text-center text-sm focus-within:relative focus-within:z-20',\n    isRange &&\n      '[&:has([data-selected])]:bg-accent [&:has([data-highlighted])]:bg-accent first:[&:has([data-selected])]:rounded-l-md last:[&:has([data-selected])]:rounded-r-md [&:has([data-selected][data-selection-end])]:rounded-r-md [&:has([data-selected][data-selection-start])]:rounded-l-md',\n    className,\n  )}\n  {...restProps}\n>\n  {@render children?.()}\n</td>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarCell.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarCellTrigger.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLButtonAttributes } from 'svelte/elements'\n  import type { CalendarDate } from '@internationalized/date'\n\n  export interface CalendarCellTriggerProps extends HTMLButtonAttributes {\n    day: CalendarDate\n    month: CalendarDate\n    /** Overrides the day content (defaults to the day number). Receives the same `{ day, month }`. */\n    cell?: Snippet<[{ day: CalendarDate; month: CalendarDate }]>\n    children?: Snippet\n    ref?: HTMLButtonElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { getContext } from 'svelte'\n  import { cn } from '$lib/utils'\n  import { buttonVariants } from '$lib/components/ui/button/button.variants'\n  import { CALENDAR_CONTEXT_KEY, type CalendarState } from './calendar-state.svelte'\n\n  let {\n    class: className,\n    day,\n    month,\n    cell,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: CalendarCellTriggerProps = $props()\n\n  const state = getContext<CalendarState | undefined>(CALENDAR_CONTEXT_KEY)\n\n  const selected = $derived(state?.isSelected(day) ?? false)\n  const selectionStart = $derived(state?.isSelectionStart(day) ?? false)\n  const selectionEnd = $derived(state?.isSelectionEnd(day) ?? false)\n  const highlighted = $derived(state?.isHighlighted(day) ?? false)\n  const disabledDate = $derived(state?.isDisabledDate(day) ?? false)\n  const unavailable = $derived(state?.isUnavailableDate(day) ?? false)\n  const isToday = $derived(state?.isTodayDate(day) ?? false)\n  const outsideView = $derived(state ? state.isOutsideView(day, month) : false)\n  const isRange = $derived(state?.type === 'range')\n  const hiddenOutside = $derived(outsideView && state?.showOutsideDays === false)\n</script>\n\n<button\n  bind:this={ref}\n  type=\"button\"\n  data-uipkge\n  data-slot=\"calendar-cell-trigger\"\n  data-day={day.toString()}\n  data-value={day.toString()}\n  data-selected={selected ? '' : undefined}\n  data-selection-start={selectionStart || undefined}\n  data-selection-end={selectionEnd || undefined}\n  data-highlighted={highlighted || undefined}\n  data-disabled={disabledDate ? '' : undefined}\n  data-unavailable={unavailable ? '' : undefined}\n  data-today={isToday ? '' : undefined}\n  data-outside-view={outsideView ? '' : undefined}\n  aria-label={state?.formatDay(day)}\n  aria-hidden={hiddenOutside || undefined}\n  aria-disabled={unavailable && !disabledDate ? 'true' : undefined}\n  disabled={disabledDate || hiddenOutside}\n  tabindex={hiddenOutside || (state && !state.isTabbableDate(day)) ? -1 : 0}\n  class={cn(\n    buttonVariants({ variant: 'ghost' }),\n    'size-9 cursor-pointer p-0 font-normal transition-[color,background-color,transform,box-shadow] duration-150 aria-selected:opacity-100',\n    '[&[data-today]:not([data-selected])]:bg-accent [&[data-today]:not([data-selected])]:text-accent-foreground',\n    // Single / multiple: selected day gets the primary fill.\n    !isRange &&\n      'data-[selected]:bg-primary data-[selected]:text-primary-foreground data-[selected]:hover:bg-primary data-[selected]:hover:text-primary-foreground data-[selected]:focus:bg-primary data-[selected]:focus:text-primary-foreground data-[selected]:opacity-100 data-[selected]:shadow-sm motion-safe:data-[selected]:animate-[calendar-day-pop_220ms_cubic-bezier(0.22,1.4,0.36,1)_both]',\n    // Range: middle days get the accent fill, start/end get primary + pop (mirrors RangeCalendar).\n    isRange &&\n      'data-[selected]:bg-accent data-[selected]:text-accent-foreground data-[selected]:opacity-100',\n    isRange &&\n      'data-[selection-start]:bg-primary data-[selection-start]:text-primary-foreground data-[selection-start]:hover:bg-primary data-[selection-start]:hover:text-primary-foreground data-[selection-start]:focus:bg-primary data-[selection-start]:focus:text-primary-foreground motion-safe:data-[selection-start]:animate-[calendar-day-pop_220ms_cubic-bezier(0.22,1.4,0.36,1)_both]',\n    isRange &&\n      'data-[selection-end]:bg-primary data-[selection-end]:text-primary-foreground data-[selection-end]:hover:bg-primary data-[selection-end]:hover:text-primary-foreground data-[selection-end]:focus:bg-primary data-[selection-end]:focus:text-primary-foreground motion-safe:data-[selection-end]:animate-[calendar-day-pop_220ms_cubic-bezier(0.22,1.4,0.36,1)_both]',\n    // Disabled\n    'data-[disabled]:text-muted-foreground data-[disabled]:opacity-50',\n    // Unavailable\n    'data-[unavailable]:text-destructive-foreground data-[unavailable]:line-through',\n    // Outside months\n    'data-[outside-view]:text-muted-foreground',\n    hiddenOutside && 'invisible pointer-events-none',\n    className,\n  )}\n  onclick={() => state?.select(day)}\n  onkeydown={(e) => state?.handleDayKeydown(e, day)}\n  onmouseenter={() => state?.hover(day)}\n  onmouseleave={() => state?.hover(null)}\n  onfocus={() => {\n    if (state) {\n      state.focusedDate = day\n      state.hover(null)\n    }\n  }}\n  {...restProps}\n>\n  {#if cell}\n    {@render cell({ day, month })}\n  {:else if children}\n    {@render children()}\n  {:else}\n    {day.day}\n  {/if}\n</button>\n\n<style>\n  :global {\n    @keyframes calendar-day-pop {\n      0% {\n        transform: scale(0.86);\n      }\n      70% {\n        transform: scale(1.06);\n      }\n      100% {\n        transform: scale(1);\n      }\n    }\n  }\n\n  @media (prefers-reduced-motion: reduce) {\n    :global([data-slot='calendar-cell-trigger']) {\n      animation: none !important;\n      transition: none !important;\n    }\n  }\n</style>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarCellTrigger.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarGrid.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface CalendarGridProps extends HTMLAttributes<HTMLTableElement> {\n    ref?: HTMLTableElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  let { class: className, children, ref = $bindable(null), ...restProps }: CalendarGridProps = $props()\n</script>\n\n<table bind:this={ref} data-uipkge data-slot=\"calendar-grid\" class={cn('w-full border-collapse', className)} {...restProps}>\n  {@render children?.()}\n</table>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarGrid.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarGridBody.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface CalendarGridBodyProps extends HTMLAttributes<HTMLTableSectionElement> {\n    ref?: HTMLTableSectionElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  let { children, ref = $bindable(null), ...restProps }: CalendarGridBodyProps = $props()\n</script>\n\n<tbody bind:this={ref} data-uipkge data-slot=\"calendar-grid-body\" {...restProps}>\n  {@render children?.()}\n</tbody>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarGridBody.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarGridHead.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface CalendarGridHeadProps extends HTMLAttributes<HTMLTableSectionElement> {\n    ref?: HTMLTableSectionElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  let { class: className, children, ref = $bindable(null), ...restProps }: CalendarGridHeadProps = $props()\n</script>\n\n<thead bind:this={ref} data-uipkge data-slot=\"calendar-grid-head\" class={className} {...restProps}>\n  {@render children?.()}\n</thead>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarGridHead.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarGridRow.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface CalendarGridRowProps extends HTMLAttributes<HTMLTableRowElement> {\n    ref?: HTMLTableRowElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  let { class: className, children, ref = $bindable(null), ...restProps }: CalendarGridRowProps = $props()\n</script>\n\n<tr bind:this={ref} data-uipkge data-slot=\"calendar-grid-row\" class={cn('flex', className)} {...restProps}>\n  {@render children?.()}\n</tr>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarGridRow.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarHeadCell.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface CalendarHeadCellProps extends HTMLAttributes<HTMLTableCellElement> {\n    ref?: HTMLTableCellElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  let { class: className, children, ref = $bindable(null), ...restProps }: CalendarHeadCellProps = $props()\n</script>\n\n<th\n  bind:this={ref}\n  scope=\"col\"\n  data-uipkge\n  data-slot=\"calendar-head-cell\"\n  class={cn('text-muted-foreground flex-1 rounded-md text-xs font-normal', className)}\n  {...restProps}\n>\n  {@render children?.()}\n</th>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarHeadCell.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarHeader.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface CalendarHeaderProps extends HTMLAttributes<HTMLDivElement> {\n    ref?: HTMLDivElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  let { class: className, children, ref = $bindable(null), ...restProps }: CalendarHeaderProps = $props()\n</script>\n\n<div\n  bind:this={ref}\n  data-uipkge\n  data-slot=\"calendar-header\"\n  class={cn('relative flex w-full items-center justify-center px-8 pt-1', className)}\n  {...restProps}\n>\n  {@render children?.()}\n</div>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarHeader.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarHeading.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLAttributes } from 'svelte/elements'\n\n  export interface CalendarHeadingProps extends Omit<HTMLAttributes<HTMLDivElement>, 'children'> {\n    children?: Snippet<[{ headingValue: string }]>\n    ref?: HTMLDivElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { getContext } from 'svelte'\n  import { cn } from '$lib/utils'\n  import { CALENDAR_CONTEXT_KEY, type CalendarState } from './calendar-state.svelte'\n\n  let { class: className, children, ref = $bindable(null), ...restProps }: CalendarHeadingProps = $props()\n\n  const state = getContext<CalendarState | undefined>(CALENDAR_CONTEXT_KEY)\n  const headingValue = $derived(state?.headingValue ?? '')\n</script>\n\n<div bind:this={ref} data-uipkge data-slot=\"calendar-heading\" class={cn('text-sm font-medium', className)} {...restProps}>\n  {#if children}\n    {@render children({ headingValue })}\n  {:else}\n    {headingValue}\n  {/if}\n</div>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarHeading.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarNextButton.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLButtonAttributes } from 'svelte/elements'\n\n  export interface CalendarNextButtonProps extends HTMLButtonAttributes {\n    /** Overrides the default chevron icon. */\n    icon?: Snippet\n    ref?: HTMLButtonElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { getContext } from 'svelte'\n  import { ChevronRight } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n  import { Button } from '$lib/components/ui/button'\n  import { buttonVariants } from '$lib/components/ui/button/button.variants'\n  import { CALENDAR_CONTEXT_KEY, type CalendarState } from './calendar-state.svelte'\n\n  let { class: className, icon, children, ref = $bindable(null), ...restProps }: CalendarNextButtonProps = $props()\n\n  const state = getContext<CalendarState | undefined>(CALENDAR_CONTEXT_KEY)\n</script>\n\n<Button\n  type=\"button\"\n  variant=\"outline\"\n  bind:ref\n  data-slot=\"calendar-next-button\"\n  aria-label=\"Next month\"\n  disabled={state ? !state.canGoNext : undefined}\n  class={cn(\n    buttonVariants({ variant: 'outline' }),\n    'size-9 bg-transparent p-0 opacity-70 hover:opacity-100 focus-visible:opacity-100',\n    className,\n  )}\n  onclick={() => state?.goNext()}\n  {...restProps}\n>\n  {#if icon}\n    {@render icon()}\n  {:else if children}\n    {@render children()}\n  {:else}\n    <ChevronRight class=\"size-4\" aria-hidden=\"true\" />\n  {/if}\n</Button>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarNextButton.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/CalendarPrevButton.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { Snippet } from 'svelte'\n  import type { HTMLButtonAttributes } from 'svelte/elements'\n\n  export interface CalendarPrevButtonProps extends HTMLButtonAttributes {\n    /** Overrides the default chevron icon. */\n    icon?: Snippet\n    ref?: HTMLButtonElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { getContext } from 'svelte'\n  import { ChevronLeft } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n  import { Button } from '$lib/components/ui/button'\n  import { buttonVariants } from '$lib/components/ui/button/button.variants'\n  import { CALENDAR_CONTEXT_KEY, type CalendarState } from './calendar-state.svelte'\n\n  let { class: className, icon, children, ref = $bindable(null), ...restProps }: CalendarPrevButtonProps = $props()\n\n  const state = getContext<CalendarState | undefined>(CALENDAR_CONTEXT_KEY)\n</script>\n\n<Button\n  type=\"button\"\n  variant=\"outline\"\n  bind:ref\n  data-slot=\"calendar-prev-button\"\n  aria-label=\"Previous month\"\n  disabled={state ? !state.canGoPrev : undefined}\n  class={cn(\n    buttonVariants({ variant: 'outline' }),\n    'size-9 bg-transparent p-0 opacity-70 hover:opacity-100 focus-visible:opacity-100',\n    className,\n  )}\n  onclick={() => state?.goPrev()}\n  {...restProps}\n>\n  {#if icon}\n    {@render icon()}\n  {:else if children}\n    {@render children()}\n  {:else}\n    <ChevronLeft class=\"size-4\" aria-hidden=\"true\" />\n  {/if}\n</Button>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/CalendarPrevButton.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/NativeSelect.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLSelectAttributes } from 'svelte/elements'\n\n  export interface NativeSelectProps extends Omit<HTMLSelectAttributes, 'onchange'> {\n    value?: string | number | string[]\n    label?: string\n    placeholder?: string\n    readonly?: boolean\n    error?: boolean\n    errorMessages?: string | string[]\n    successMessages?: string | string[]\n    hint?: string\n    variant?: 'outlined' | 'filled' | 'solo' | 'underlined'\n    density?: 'compact' | 'default' | 'comfortable'\n    color?: 'primary' | 'secondary' | 'error' | 'success' | 'warning' | 'info'\n    hideDetails?: boolean\n    bgColor?: string\n    onchange?: (value: string | number | string[] | undefined) => void\n    ref?: HTMLSelectElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { ChevronDown } from '@lucide/svelte'\n  import { cn } from '$lib/utils'\n\n  const uid = $props.id()\n\n  let {\n    class: className,\n    value = $bindable<string | number | string[] | undefined>(undefined),\n    label = '',\n    placeholder = '',\n    disabled = false,\n    readonly = false,\n    error = false,\n    errorMessages = [],\n    successMessages = [],\n    hint = '',\n    variant = 'outlined',\n    density = 'default',\n    color: _color = 'primary',\n    hideDetails = false,\n    bgColor,\n    onchange,\n    children,\n    ref = $bindable(null),\n    ...restProps\n  }: NativeSelectProps = $props()\n\n  const hasError = $derived(error || (Array.isArray(errorMessages) ? errorMessages.length > 0 : !!errorMessages))\n  const hasSuccess = $derived(\n    !hasError && (Array.isArray(successMessages) ? successMessages.length > 0 : !!successMessages),\n  )\n\n  const densityClasses = {\n    compact: 'h-8 text-xs',\n    default: 'h-9 text-sm',\n    comfortable: 'h-10 text-base',\n  }\n\n  const variantClasses = {\n    outlined: 'border bg-transparent',\n    filled: 'border-b-2 bg-muted/30 border-transparent',\n    solo: 'border bg-card shadow-md',\n    underlined: 'border-b bg-transparent rounded-none border-x-0 border-t-0',\n  }\n\n  const stateClasses = $derived.by(() => {\n    if (hasError) return 'border-destructive focus-visible:ring-destructive/20'\n    if (hasSuccess) return 'border-success focus-visible:border-success'\n    return 'border-input focus-visible:border-ring focus-visible:ring-ring/20 focus-visible:ring-[3px]'\n  })\n</script>\n\n<div class={cn('relative w-full', densityClasses[density])}>\n  <!-- Label -->\n  {#if label}\n    <label for={uid} class={cn('mb-1 block text-sm font-medium', hasError && 'text-destructive')}>\n      {label}\n    </label>\n  {/if}\n\n  <!-- Select Wrapper -->\n  <div class={cn('group/native-select relative w-full', className)}>\n    <!-- `readonly` is accepted for API parity but not rendered: it is invalid on\n         <select> and browsers ignore it (same effective behavior as the Vue twin). -->\n    <select\n      bind:this={ref}\n      bind:value\n      id={uid}\n      data-uipkge\n      data-slot=\"native-select\"\n      disabled={disabled}\n      aria-label={label || placeholder || undefined}\n      class={cn(\n        'border-input placeholder:text-muted-foreground selection:bg-primary selection:text-primary-foreground dark:bg-input/30 dark:hover:bg-input/50',\n        variantClasses[variant],\n        stateClasses,\n        densityClasses[density],\n        'w-full min-w-0 appearance-none rounded-md border bg-transparent px-3 pr-9 shadow-xs transition-[color,box-shadow] outline-none disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50',\n        bgColor,\n      )}\n      onchange={() => onchange?.(value)}\n      {...restProps}\n    >\n      {@render children?.()}\n    </select>\n    <ChevronDown\n      class=\"text-muted-foreground pointer-events-none absolute top-1/2 right-3.5 size-4 -translate-y-1/2 opacity-50 select-none\"\n      aria-hidden=\"true\"\n      data-uipkge\n      data-slot=\"native-select-icon\"\n    />\n  </div>\n\n  <!-- Details: hint, error, success -->\n  {#if !hideDetails}\n    <div\n      class={cn('mt-1 text-xs', {\n        'text-destructive': hasError,\n        'text-success': hasSuccess,\n        'text-muted-foreground': !hasError && !hasSuccess,\n      })}\n    >\n      {#if hasError}\n        {#if typeof errorMessages === 'string'}\n          <span>{errorMessages}</span>\n        {:else}\n          <span>{errorMessages[0]}</span>\n        {/if}\n      {:else if hasSuccess}\n        {#if typeof successMessages === 'string'}\n          <span>{successMessages}</span>\n        {:else}\n          <span>{successMessages[0]}</span>\n        {/if}\n      {:else}\n        {hint}\n      {/if}\n    </div>\n  {/if}\n</div>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/NativeSelect.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/NativeSelectOption.svelte",
      "content": "<script lang=\"ts\" module>\n  import type { HTMLOptionAttributes } from 'svelte/elements'\n\n  export interface NativeSelectOptionProps extends HTMLOptionAttributes {\n    ref?: HTMLOptionElement | null\n  }\n</script>\n\n<script lang=\"ts\">\n  import { cn } from '$lib/utils'\n\n  let { class: className, children, ref = $bindable(null), ...restProps }: NativeSelectOptionProps = $props()\n</script>\n\n<option\n  bind:this={ref}\n  data-slot=\"native-select-option\"\n  class={cn('bg-popover text-popover-foreground', className)}\n  {...restProps}\n>\n  {@render children?.()}\n</option>\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/NativeSelectOption.svelte"
    },
    {
      "path": "packages/registry-svelte/components/calendar/calendar-state.svelte.ts",
      "content": "/**\n * Calendar state shared between `Calendar.svelte` (root) and its parts via\n * Svelte context. Replaces what reka-ui's `CalendarRoot` provided in the Vue\n * twin: grid computation, selection, min/max + disabled/unavailable gating,\n * month navigation, and roving-focus keyboard navigation — all hand-rolled\n * with runes on top of `@internationalized/date`.\n */\nimport { tick } from 'svelte'\nimport {\n  CalendarDate,\n  endOfMonth,\n  endOfWeek,\n  getLocalTimeZone,\n  startOfWeek,\n  today,\n  type DateValue,\n  type DayOfWeek,\n} from '@internationalized/date'\n\nexport const CALENDAR_CONTEXT_KEY = 'calendar'\n\nexport type CalendarSelectionType = 'single' | 'multiple' | 'range'\n\n/**\n * Range value for `type=\"range\"` (two-click start/end selection).\n *\n * INTENTIONAL DIVERGENCE from React: React's DayPicker-based Calendar uses\n * native `Date` objects (`{ from: Date, to: Date }`). This Svelte calendar\n * keeps `@internationalized/date` `DateValue` (CalendarDate) to match the\n * Vue/reka-ui twin and preserve timezone-safe arithmetic. Convert at the\n * boundary with `new CalendarDate(d.getFullYear(), d.getMonth() + 1, d.getDate())`.\n */\nexport interface CalendarRange {\n  start: DateValue | undefined\n  end: DateValue | undefined\n}\n\nconst DAY_OF_WEEK_BY_INDEX: DayOfWeek[] = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']\n\nexport interface CalendarGridData {\n  /** First day of the rendered month. */\n  value: CalendarDate\n  rows: CalendarDate[][]\n}\n\nexport interface CalendarStateOptions {\n  onValueChange?: (value: DateValue | DateValue[] | CalendarRange | undefined) => void\n  onPlaceholderChange?: (placeholder: DateValue) => void\n}\n\nfunction toCalendarDate(date: DateValue): CalendarDate {\n  return new CalendarDate(date.year, date.month, date.day)\n}\n\nfunction sameDate(a: DateValue | undefined, b: DateValue | undefined): boolean {\n  if (a == null || b == null) return a == null && b == null\n  return a.compare(b) === 0\n}\n\nfunction sameDateArray(a: DateValue[], b: DateValue[]): boolean {\n  return a.length === b.length && a.every((d, i) => d.compare(b[i]!) === 0)\n}\n\nfunction isCalendarRange(v: unknown): v is CalendarRange {\n  return typeof v === 'object' && v !== null && ('start' in v || 'end' in v)\n}\n\nfunction sameRange(a: CalendarRange | undefined, b: CalendarRange | undefined): boolean {\n  if (a == null || b == null) return a == null && b == null\n  return sameDate(a.start, b.start) && sameDate(a.end, b.end)\n}\n\nexport class CalendarState {\n  type = $state<CalendarSelectionType>('single')\n  locale = $state('en')\n  weekStartsOn = $state<number | undefined>(undefined)\n  fixedWeeks = $state(false)\n  numberOfMonths = $state(1)\n  pagedNavigation = $state(false)\n  disabled = $state(false)\n  readonly = $state(false)\n  weekdayFormat = $state<'narrow' | 'short' | 'long'>('narrow')\n  minValue = $state<DateValue | undefined>(undefined)\n  maxValue = $state<DateValue | undefined>(undefined)\n  isDateDisabled = $state<((date: DateValue) => boolean) | undefined>(undefined)\n  isDateUnavailable = $state<((date: DateValue) => boolean) | undefined>(undefined)\n\n  showOutsideDays = $state(true)\n\n  placeholder = $state<CalendarDate>(today(getLocalTimeZone()))\n  singleValue = $state<DateValue | undefined>(undefined)\n  multipleValue = $state<DateValue[]>([])\n  rangeValue = $state<CalendarRange | undefined>(undefined)\n  hoverDate = $state<CalendarDate | undefined>(undefined)\n  focusedDate = $state<CalendarDate>(today(getLocalTimeZone()))\n  rootEl = $state<HTMLElement | null>(null)\n\n  #options: CalendarStateOptions\n\n  constructor(initial?: {\n    type?: CalendarSelectionType\n    locale?: string\n    weekStartsOn?: number\n    fixedWeeks?: boolean\n    numberOfMonths?: number\n    pagedNavigation?: boolean\n    disabled?: boolean\n    readonly?: boolean\n    weekdayFormat?: 'narrow' | 'short' | 'long'\n    minValue?: DateValue\n    maxValue?: DateValue\n    isDateDisabled?: (date: DateValue) => boolean\n    isDateUnavailable?: (date: DateValue) => boolean\n    showOutsideDays?: boolean\n    value?: DateValue | DateValue[] | CalendarRange\n    placeholder?: DateValue\n  }, options: CalendarStateOptions = {}) {\n    this.#options = options\n    if (initial) this.syncFromProps(initial)\n    // First tab stop: the selected day when visible, else the viewed month.\n    this.focusedDate = this.initialFocusedDate()\n  }\n\n  get firstDayOfWeek(): DayOfWeek | undefined {\n    return this.weekStartsOn != null ? (DAY_OF_WEEK_BY_INDEX[this.weekStartsOn] ?? undefined) : undefined\n  }\n\n  get grids(): CalendarGridData[] {\n    const firstDay = this.firstDayOfWeek\n    const out: CalendarGridData[] = []\n    const base = new CalendarDate(this.placeholder.year, this.placeholder.month, 1)\n    for (let i = 0; i < Math.max(1, this.numberOfMonths); i++) {\n      const monthStart = base.add({ months: i })\n      const monthEnd = endOfMonth(monthStart)\n      const start = startOfWeek(monthStart, this.locale, firstDay)\n      const end = endOfWeek(monthEnd, this.locale, firstDay)\n      const rows: CalendarDate[][] = []\n      let cursor = start\n      let guard = 0\n      while (cursor.compare(end) <= 0 && guard++ < 64) {\n        const week: CalendarDate[] = []\n        for (let d = 0; d < 7; d++) {\n          week.push(cursor)\n          cursor = cursor.add({ days: 1 })\n        }\n        rows.push(week)\n      }\n      if (this.fixedWeeks) {\n        while (rows.length < 6) {\n          const week: CalendarDate[] = []\n          for (let d = 0; d < 7; d++) {\n            week.push(cursor)\n            cursor = cursor.add({ days: 1 })\n          }\n          rows.push(week)\n        }\n      }\n      out.push({ value: monthStart, rows })\n    }\n    return out\n  }\n\n  get weekDays(): string[] {\n    const start = startOfWeek(\n      new CalendarDate(this.placeholder.year, this.placeholder.month, 1),\n      this.locale,\n      this.firstDayOfWeek,\n    )\n    const fmt = new Intl.DateTimeFormat(this.locale, { weekday: this.weekdayFormat })\n    return Array.from({ length: 7 }, (_, i) => fmt.format(new Date(start.year, start.month - 1, start.day + i)))\n  }\n\n  get headingValue(): string {\n    const first = new CalendarDate(this.placeholder.year, this.placeholder.month, 1)\n    const monthYear = new Intl.DateTimeFormat(this.locale, { month: 'long', year: 'numeric' })\n    if (this.numberOfMonths <= 1) {\n      return monthYear.format(new Date(first.year, first.month - 1, 1))\n    }\n    const last = first.add({ months: this.numberOfMonths - 1 })\n    const firstLabel = monthYear.format(new Date(first.year, first.month - 1, 1))\n    const lastLabel = monthYear.format(new Date(last.year, last.month - 1, 1))\n    if (first.year === last.year) {\n      const monthOnly = new Intl.DateTimeFormat(this.locale, { month: 'long' })\n      return `${monthOnly.format(new Date(first.year, first.month - 1, 1))} – ${lastLabel}`\n    }\n    return `${firstLabel} – ${lastLabel}`\n  }\n\n  /** Value in the shape the parent binds (`bind:value`). */\n  get currentValue(): DateValue | DateValue[] | CalendarRange | undefined {\n    if (this.type === 'multiple') return [...this.multipleValue]\n    if (this.type === 'range') return this.rangeValue ? { ...this.rangeValue } : undefined\n    return this.singleValue\n  }\n\n  isSelected(date: DateValue): boolean {\n    if (this.type === 'multiple') return this.multipleValue.some((v) => v.compare(date) === 0)\n    if (this.type === 'range') {\n      const r = this.rangeValue\n      if (!r?.start) return false\n      if (!r.end) return r.start.compare(date) === 0\n      return date.compare(r.start) >= 0 && date.compare(r.end) <= 0\n    }\n    return this.singleValue != null && this.singleValue.compare(date) === 0\n  }\n\n  isSelectionStart(date: DateValue): boolean {\n    if (this.type !== 'range') return false\n    const s = this.rangeValue?.start\n    return s != null && s.compare(date) === 0\n  }\n\n  isSelectionEnd(date: DateValue): boolean {\n    if (this.type !== 'range') return false\n    const e = this.rangeValue?.end\n    return e != null && e.compare(date) === 0\n  }\n\n  /** Hover-preview middle days while a range start is picked but no end yet. */\n  isHighlighted(date: DateValue): boolean {\n    if (this.type !== 'range') return false\n    const start = this.rangeValue?.start\n    const end = this.rangeValue?.end\n    if (!start || end) return false\n    const hover = this.hoverDate\n    if (!hover || hover.compare(start) === 0) return false\n    const lo = start.compare(hover) <= 0 ? start : hover\n    const hi = lo === start ? hover : start\n    return date.compare(lo) > 0 && date.compare(hi) < 0\n  }\n\n  hover(date: CalendarDate | null): void {\n    this.hoverDate = date ?? undefined\n  }\n\n  isDisabledDate(date: DateValue): boolean {\n    if (this.disabled) return true\n    if (this.minValue && date.compare(this.minValue) < 0) return true\n    if (this.maxValue && date.compare(this.maxValue) > 0) return true\n    return this.isDateDisabled?.(date) ?? false\n  }\n\n  isUnavailableDate(date: DateValue): boolean {\n    return this.isDateUnavailable?.(date) ?? false\n  }\n\n  isTodayDate(date: DateValue): boolean {\n    return date.compare(today(getLocalTimeZone())) === 0\n  }\n\n  isOutsideView(date: CalendarDate, month: CalendarDate): boolean {\n    return date.year !== month.year || date.month !== month.month\n  }\n\n  /** The one tabbable day in the roving-tabindex grid. */\n  isTabbableDate(day: CalendarDate): boolean {\n    return day.compare(this.focusedDate) === 0\n  }\n\n  isDateVisible(date: DateValue): boolean {\n    return this.grids.some((g) => g.value.year === date.year && g.value.month === date.month)\n  }\n\n  get canGoPrev(): boolean {\n    if (!this.minValue) return true\n    const step = this.pagedNavigation ? Math.max(1, this.numberOfMonths) : 1\n    const target = new CalendarDate(this.placeholder.year, this.placeholder.month, 1).subtract({ months: step })\n    return target.compare(new CalendarDate(this.minValue.year, this.minValue.month, 1)) >= 0\n  }\n\n  get canGoNext(): boolean {\n    if (!this.maxValue) return true\n    const step = this.pagedNavigation ? Math.max(1, this.numberOfMonths) : 1\n    const target = new CalendarDate(this.placeholder.year, this.placeholder.month, 1).add({ months: step })\n    return target.compare(new CalendarDate(this.maxValue.year, this.maxValue.month, 1)) <= 0\n  }\n\n  select(date: DateValue): void {\n    if (this.disabled || this.readonly) return\n    if (this.isDisabledDate(date) || this.isUnavailableDate(date)) return\n    if (this.type === 'multiple') {\n      const exists = this.multipleValue.some((v) => v.compare(date) === 0)\n      const next = exists ? this.multipleValue.filter((v) => v.compare(date) !== 0) : [...this.multipleValue, date]\n      this.multipleValue = next\n      this.#options.onValueChange?.(next)\n    } else if (this.type === 'range') {\n      const r = this.rangeValue\n      if (!r?.start || (r.start && r.end)) {\n        const next: CalendarRange = { start: date, end: undefined }\n        this.rangeValue = next\n        this.#options.onValueChange?.(next)\n      } else if (date.compare(r.start) < 0) {\n        const next: CalendarRange = { start: date, end: r.start }\n        this.rangeValue = next\n        this.#options.onValueChange?.(next)\n      } else {\n        const next: CalendarRange = { start: r.start, end: date }\n        this.rangeValue = next\n        this.#options.onValueChange?.(next)\n      }\n      this.hoverDate = undefined\n    } else {\n      this.singleValue = date\n      this.#options.onValueChange?.(date)\n    }\n    this.focusedDate = toCalendarDate(date)\n  }\n\n  setPlaceholder(date: DateValue, opts?: { focus?: CalendarDate }): void {\n    const next = toCalendarDate(date)\n    this.placeholder = next\n    this.focusedDate = opts?.focus ?? next\n    this.#options.onPlaceholderChange?.(next)\n  }\n\n  goPrev(): void {\n    if (!this.canGoPrev) return\n    const step = this.pagedNavigation ? Math.max(1, this.numberOfMonths) : 1\n    this.setPlaceholder(this.placeholder.subtract({ months: step }))\n  }\n\n  goNext(): void {\n    if (!this.canGoNext) return\n    const step = this.pagedNavigation ? Math.max(1, this.numberOfMonths) : 1\n    this.setPlaceholder(this.placeholder.add({ months: step }))\n  }\n\n  formatDay(date: DateValue): string {\n    return new Intl.DateTimeFormat(this.locale, { dateStyle: 'full' }).format(\n      new Date(date.year, date.month - 1, date.day),\n    )\n  }\n\n  focusDay(date: CalendarDate): void {\n    this.focusedDate = date\n    this.rootEl\n      ?.querySelector<HTMLButtonElement>(`[data-day=\"${date.toString()}\"]`)\n      ?.focus({ preventScroll: true })\n  }\n\n  handleDayKeydown(e: KeyboardEvent, day: CalendarDate): void {\n    const firstDay = this.firstDayOfWeek\n    let target: CalendarDate | null = null\n    switch (e.key) {\n      case 'ArrowRight':\n        target = day.add({ days: 1 })\n        break\n      case 'ArrowLeft':\n        target = day.subtract({ days: 1 })\n        break\n      case 'ArrowUp':\n        target = day.subtract({ days: 7 })\n        break\n      case 'ArrowDown':\n        target = day.add({ days: 7 })\n        break\n      case 'Home':\n        target = startOfWeek(day, this.locale, firstDay)\n        break\n      case 'End':\n        target = endOfWeek(day, this.locale, firstDay)\n        break\n      case 'PageUp':\n        target = e.shiftKey ? day.subtract({ years: 1 }) : day.subtract({ months: 1 })\n        break\n      case 'PageDown':\n        target = e.shiftKey ? day.add({ years: 1 }) : day.add({ months: 1 })\n        break\n      default:\n        return\n    }\n    e.preventDefault()\n    if (this.isDateVisible(target)) {\n      this.focusDay(target)\n    } else {\n      // Move the view first, then focus once the new month renders.\n      this.setPlaceholder(new CalendarDate(target.year, target.month, 1), { focus: target })\n      void tick().then(() => this.focusDay(target as CalendarDate))\n    }\n  }\n\n  /**\n   * Inward sync: parent props → state. Every assignment is equality-guarded\n   * so the parent's `$effect` calling this never loops with the outward\n   * `onValueChange` / `onPlaceholderChange` callbacks.\n   */\n  syncFromProps(p: {\n    type?: CalendarSelectionType\n    locale?: string\n    weekStartsOn?: number\n    fixedWeeks?: boolean\n    numberOfMonths?: number\n    pagedNavigation?: boolean\n    disabled?: boolean\n    readonly?: boolean\n    weekdayFormat?: 'narrow' | 'short' | 'long'\n    minValue?: DateValue\n    maxValue?: DateValue\n    isDateDisabled?: (date: DateValue) => boolean\n    isDateUnavailable?: (date: DateValue) => boolean\n    showOutsideDays?: boolean\n    value?: DateValue | DateValue[] | CalendarRange\n    placeholder?: DateValue\n  }): void {\n    this.type = p.type ?? 'single'\n    this.locale = p.locale ?? 'en'\n    this.weekStartsOn = p.weekStartsOn\n    this.fixedWeeks = p.fixedWeeks ?? false\n    this.numberOfMonths = p.numberOfMonths ?? 1\n    this.pagedNavigation = p.pagedNavigation ?? false\n    this.disabled = p.disabled ?? false\n    this.readonly = p.readonly ?? false\n    this.weekdayFormat = p.weekdayFormat ?? 'narrow'\n    this.minValue = p.minValue\n    this.maxValue = p.maxValue\n    this.isDateDisabled = p.isDateDisabled\n    this.isDateUnavailable = p.isDateUnavailable\n    this.showOutsideDays = p.showOutsideDays ?? true\n\n    if (this.type === 'range') {\n      const r = isCalendarRange(p.value) ? p.value : undefined\n      if (!sameRange(this.rangeValue, r)) this.rangeValue = r ? { start: r.start, end: r.end } : undefined\n    } else if (this.type === 'multiple') {\n      const arr = isCalendarRange(p.value) ? [] : Array.isArray(p.value) ? p.value : p.value ? [p.value] : []\n      if (!sameDateArray(this.multipleValue, arr)) this.multipleValue = [...arr]\n    } else {\n      const v = isCalendarRange(p.value) ? undefined : Array.isArray(p.value) ? p.value[0] : p.value\n      if (!sameDate(this.singleValue, v)) this.singleValue = v\n    }\n\n    const ph = p.placeholder ? toCalendarDate(p.placeholder) : today(getLocalTimeZone())\n    if (this.placeholder.compare(ph) !== 0) {\n      this.placeholder = ph\n      this.focusedDate = this.initialFocusedDate()\n    }\n  }\n\n  private initialFocusedDate(): CalendarDate {\n    const single =\n      this.type === 'single'\n        ? this.singleValue\n        : this.type === 'range'\n          ? this.rangeValue?.start\n          : this.multipleValue[0]\n    if (single) {\n      const asDate = toCalendarDate(single)\n      if (this.isDateVisible(asDate)) return asDate\n    }\n    const now = today(getLocalTimeZone())\n    if (this.isDateVisible(now)) return now\n    return toCalendarDate(this.placeholder)\n  }\n}\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/calendar-state.svelte.ts"
    },
    {
      "path": "packages/registry-svelte/components/calendar/index.ts",
      "content": "export { default as Calendar, type CalendarProps } from './Calendar.svelte'\nexport { default as CalendarCell, type CalendarCellProps } from './CalendarCell.svelte'\nexport { default as CalendarCellTrigger, type CalendarCellTriggerProps } from './CalendarCellTrigger.svelte'\nexport { default as CalendarGrid, type CalendarGridProps } from './CalendarGrid.svelte'\nexport { default as CalendarGridBody, type CalendarGridBodyProps } from './CalendarGridBody.svelte'\nexport { default as CalendarGridHead, type CalendarGridHeadProps } from './CalendarGridHead.svelte'\nexport { default as CalendarGridRow, type CalendarGridRowProps } from './CalendarGridRow.svelte'\nexport { default as CalendarHeadCell, type CalendarHeadCellProps } from './CalendarHeadCell.svelte'\nexport { default as CalendarHeader, type CalendarHeaderProps } from './CalendarHeader.svelte'\nexport { default as CalendarHeading, type CalendarHeadingProps } from './CalendarHeading.svelte'\nexport { default as CalendarNextButton, type CalendarNextButtonProps } from './CalendarNextButton.svelte'\nexport { default as CalendarPrevButton, type CalendarPrevButtonProps } from './CalendarPrevButton.svelte'\nexport { default as NativeSelect, type NativeSelectProps } from './NativeSelect.svelte'\nexport { default as NativeSelectOption, type NativeSelectOptionProps } from './NativeSelectOption.svelte'\n\nexport {\n  CalendarState,\n  CALENDAR_CONTEXT_KEY,\n  type CalendarRange,\n  type CalendarSelectionType,\n  type CalendarGridData,\n} from './calendar-state.svelte'\n\nexport type LayoutTypes = 'month-and-year' | 'month-only' | 'year-only' | undefined\n",
      "type": "registry:ui",
      "target": "~/src/lib/components/ui/calendar/index.ts"
    }
  ],
  "dependencies": [
    "@internationalized/date",
    "@lucide/svelte"
  ],
  "devDependencies": [],
  "registryDependencies": [
    "https://uipkge.dev/r/svelte/button.json"
  ],
  "description": "Single-month calendar grid for date selection (hand-rolled runes state + @internationalized/date). Use inline or in a custom popover. For form fields, use Date Picker. Supports min/max, disabled dates, multi-month, and locale.",
  "categories": [
    "date-time"
  ]
}