import type { Snippet } from 'svelte';
import type { HTMLAttributes } from 'svelte/elements';
import type { DateCategory, DateRange, ResourceTimelineView, TimelineCellContext, TimelineDayContext, TimelineGroup, TimelineGroupContext, TimelineHeaderContext, TimelineLegendContext, TimelineRange, TimelineResource, TimelineResourceContext, TimelineSpanContext } from './resource-timeline.types.js';
import type { ResourceTimelineSlots, ResourceTimelineVariants } from './resource-timeline.variants.js';
/**
* @summary Resources as lanes, days as columns; each item a bar.
* @description Resource timeline: every row is a resource (a room, a chair, a
* vehicle, a person), every column a day of a navigable window, and each item
* a bar spanning the days it occupies, stacked when two overlap in one lane.
* The occupancy view neither `Calendar` (timed events on a date grid) nor
* `Planner` (one item, one day bucket) expresses.
*
* Three contracts decide whether your data lands where you expect:
*
* - **`getRange` is inclusive.** `{ start, end }` are both days the bar covers.
* A booking stored as check-in → check-out converts by subtracting a day:
* the last *night* is `checkOut − 1`. Same convention as `CalendarEvent.end`.
* - **Local date strings are taken verbatim** — `'2026-06-16'` is never
* UTC-parsed, so a plain date never shifts a day west of Greenwich (the same
* parser `Planner.getDate` uses). Pass a `Date` when you need an instant
* converted to its local day.
* - **The window is `value` + `view`.** `view="week"` snaps to the week
* containing `value`; `view="days"` runs `days` columns **starting at**
* `value`, so "the next 14 nights" needs no second anchor.
*
* Two departures from `Calendar`/`Planner`, both forced by the sticky resource
* column: **navigation does not slide-animate** (a `transform` ancestor breaks
* `position: sticky`, so there is no `animated` prop), and **there is no
* swipe-to-navigate** (the day track already claims the horizontal gesture, the
* one that scrolls it). Arrow keys and the header arrows do the navigating;
* `overflow-x` sits on the track, never on the root, so a wide window never
* scrolls the page sideways.
*
* Scale is honest rather than engineered: roughly 20 lanes × 30 days is
* comfortable, and there is no virtualization in this version. Sort a longer
* list into `groups` and page the window instead.
*
* @tag display
* @tag data
* @related Calendar
* @related Planner
* @stability beta
*
* @example Hotel occupancy — rooms as lanes, the last night is `checkOut − 1`
* ```svelte
*
*
* b.roomId}
* getRange={(b) => ({ start: b.checkIn, end: addDays(isoToDate(b.checkOut), -1) })}
* getLabel={(b) => b.guest}
* onItemClick={(booking, room) => openBooking(booking, room)}
* />
* ```
*
* @example Coloured by category, with a custom bar
* ```svelte
* s.chairId}
* getCategoryId={(s) => s.serviceId}
* getRange={(s) => ({ start: s.day, end: s.day })}
* >
* {#snippet span({ item, totalDays })}
* {item.client} · {totalDays}d
* {/snippet}
*
* ```
*/
export interface ResourceTimelineProps extends ResourceTimelineVariants, Omit, 'children'> {
/** The lanes, top to bottom. An empty list renders the `empty` state. */
resources?: TimelineResource[];
/**
* Heading rows above the lanes carrying the matching `groupId`. Supplying
* them re-orders the lanes to follow this list; a lane whose `groupId` names
* no group is appended without a heading rather than dropped.
*/
groups?: TimelineGroup[];
/** The items to lay out as bars. */
items?: T[];
/** Which lane an item belongs to. An id that is in no `resources` entry drops the item (DEV warns). Required. */
getResourceId: (item: T) => string;
/**
* The item's **inclusive** day range: both `start` and `end` are days the
* bar covers. A stay ending at check-out passes `checkOut − 1`. Return
* `Date`s, or local date strings (`'2026-06-16'`) which are read verbatim and
* never UTC-parsed. A range whose end precedes its start is rendered with the
* two swapped and warns in DEV. Required.
* @summary The days the bar covers, both ends inclusive.
*/
getRange: (item: T) => TimelineRange;
/** Stable key for an item, used as the `{#each}` key. Defaults to resource id + start day + index. */
getId?: (item: T) => string;
/** The bar's text and accessible name. Without it a bar renders as a plain occupancy block. */
getLabel?: (item: T) => string;
/** The item's category id, looked up in `categories`. Falls back to `resource.categoryId`. */
getCategoryId?: (item: T) => string | undefined;
/** Colour buckets for the bars, and the legend below the grid. */
categories?: DateCategory[];
/** `week` snaps to the week containing `value`; `days` starts at `value`. @default 'week' */
view?: ResourceTimelineView;
/** Column count for `view="days"`. Ignored in `week`. @default 14 */
days?: number;
/** Reference date the window is anchored on. Supports `bind:value`. @default today */
value?: Date;
/** First day of the week for `view="week"` (0=Sun … 6=Sat). @default 1 */
weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6;
/**
* BCP 47 locale tag for the weekday names and the header title. Defaults to
* `'auto'`, which follows the active `` locale, so an app that
* already declares its language does not repeat it here. SSR-safe: the locale
* comes from context, so server and client resolve the same tag. Pass an
* explicit tag (e.g. `'de-DE'`) to override.
* @default 'auto'
* @summary Which language the weekday names and the title are rendered in.
*/
locale?: string;
/** Earliest navigable date. The window clamps span-preserving, so it never collapses at the bound. */
minDate?: Date;
/** Latest navigable date. The window clamps span-preserving, so it never collapses at the bound. */
maxDate?: Date;
/** Predicate for days that cannot be activated, on top of `minDate`/`maxDate`. */
isDateDisabled?: (date: Date) => boolean;
/** Visual style: `default`, `bordered` (a framed grid) or `ghost` (no grid lines, pill bars). @default 'default' */
variant?: 'default' | 'bordered' | 'ghost';
/** Density: lane width, day-column width and bar height. @default 'md' */
size?: 'sm' | 'md' | 'lg';
/**
* Tint today's column. Visual only — `aria-current="date"` is set on today's
* header and cells either way, so switching the highlight off never costs the
* semantic pointer.
* @default true
* @summary Tint today's column. The `aria-current` pointer stays either way.
*/
highlightToday?: boolean;
/** Tint Saturday/Sunday columns. @default false */
highlightWeekend?: boolean;
/**
* Keep the resource column pinned while the day track scrolls sideways. Turn
* it off inside a shell that already provides its own horizontal scrolling.
* @default true
* @summary Pin the resource column while the day track scrolls sideways.
*/
stickyResourceColumn?: boolean;
/** Bar rows to render per lane; anything past it becomes a `+n` chip at the lane's right edge. Unset renders every row. */
maxRowsPerLane?: number;
/** Render the category legend below the grid. Ignored without `categories`. @default true */
showLegend?: boolean;
/** Disable navigation and cell activation. @default false */
disabled?: boolean;
/** Fires after navigation with the new reference date and the visible window; load data here. */
onNavigate?: (date: Date, range: DateRange) => void;
/**
* Fires when a bar is activated: a click on it, or Enter/Space on **any**
* cell it covers (the bar overhangs those cells, so the keyboard reaches what
* the pointer hits). Where several bars stack on one day, activating again
* steps through them, top row first, then wraps.
* @summary Fires when a bar is activated by click or keyboard.
*/
onItemClick?: (item: T, resource: TimelineResource) => void;
/**
* Fires when a cell **no bar covers** is activated: the hook for an "add
* booking" affordance. Activating a day inside an existing stay fires
* `onItemClick` instead, from click or keyboard.
* @summary Fires when a free cell is activated (the "add" hook).
*/
onCellClick?: (resource: TimelineResource, date: Date) => void;
/** Replace the default toolbar (prev/title/today/next). */
header?: Snippet<[TimelineHeaderContext]>;
/** Customise a day column's header. */
dayHeader?: Snippet<[TimelineDayContext]>;
/** Customise a lane's label in the resource column. */
resourceLabel?: Snippet<[TimelineResourceContext]>;
/** Customise a group heading row. */
groupLabel?: Snippet<[TimelineGroupContext]>;
/** Render a bar's content: receives the clipped geometry and the typed item. */
span?: Snippet<[TimelineSpanContext]>;
/** Render extra content inside every (resource, day) cell, e.g. an "add" affordance on free days. */
cell?: Snippet<[TimelineCellContext]>;
/** Replace the default category legend. */
legend?: Snippet<[TimelineLegendContext]>;
/** Replace the "no resources" message shown when `resources` is empty. */
empty?: Snippet;
/** Extra classes merged onto the root element. */
class?: string;
/**
* Remove all default tv() classes; only user-provided classes apply. Note
* that this also strips the layout's custom properties (`--rt-lane-w`,
* `--rt-day-w`, `--rt-bar-h` …), so an unstyled timeline has to re-declare
* them along with the look.
* @default false
*/
unstyled?: boolean;
/** Per-slot class overrides merged with tv() styles. Slots: base | header | headerTitle | nav | navButton | track | dayHeaderRow | corner | dayHeader | dayHeaderWeekday | dayHeaderDate | body | groupRow | groupLabel | lane | laneHeader | laneLabel | laneDescription | dayCell | span | spanLabel | overflow | legend | legendItem | legendDot | legendLabel | empty */
slotClasses?: Partial>;
/** Apply a named preset registered via ``. */
preset?: string;
}
export { default as ResourceTimeline } from './ResourceTimeline.svelte';
export { default as ResourceTimelineHeader } from './ResourceTimelineHeader.svelte';
export { getTimelineDays, getTimelineWindow, layoutTimeline, parseTimelineDate, type TimelineLayoutOptions, type TimelineWindow } from './resource-timeline.engine.js';
export type { DateCategory, DateRange, ResourceTimelineContext, ResourceTimelineSlotName, ResourceTimelineView, TimelineCellContext, TimelineDayContext, TimelineGroup, TimelineGroupContext, TimelineHeaderContext, TimelineLaneContext, TimelineLegendContext, TimelineRange, TimelineResource, TimelineResourceContext, TimelineSpanContext } from './resource-timeline.types.js';
export { type ResourceTimelineSlots, type ResourceTimelineVariants, resourceTimelineVariants } from './resource-timeline.variants.js';