Appearance
Kotlin component integration
Android installation. Retain one model per component on the UI thread. Use a MaterialTheme and a bounded or scrolling consumer host. Core is pure Kotlin/JVM; the application owns persistence, remote services and saved state.
Resource Timeline
core.timeline exports TimelineResource, TimelineEntry, TimelineAssignment, TimelineData, TimelineWindow, scales/zoom, layout and grouping projections. Assignments may share one entry across resources. Ends are exclusive floating local minutes; imported overlaps render deterministically.
Create TimelineModel(start, data, days = 90) and render TimelineView(model). The resource axis stays fixed while a virtual viewport scrolls horizontally. setScale, setZoom, select, navigate, setGroupBy and toggleGroup preserve confirmed values. Collapsed paths are structured lists, not delimiter strings.
Pass TimelineInteractions(onCreate, onMove, allowOverlap = false) for proposals. Confirm only after application validation by replacing model.data with model.setData(...); TimelineData.applying(edit) rejects stale originals. Moving shared entries checks every assigned resource. Unknown provider coverage never permits an edit, even with overlaps allowed.
TimelinePresentation supplies decorative entry/resource/group composables and current context actions. Wrappers own geometry, selection and gestures. Actions are re-resolved and enabled state rechecked at dispatch. Keep persistence and interactive controls out of decorative slots.
setDataProvider(TimelineDataProvider) accepts a suspending query-to-page function. The view requests a buffered visible interval and ordered resource IDs. Pages validate before replacing their queried occupancy; outside coverage is retained. Generation checks and coroutine cancellation reject stale replies. reload() retries failures; authoritative setData cancels pending work. Consumers perform networking and authentication. Empty pages mean no entries only within confirmed coverage; they do not authorize unqueried intervals.
Task Manager
core.tasks exports GanttTask, GanttTaskKind.Activity/Summary/Milestone, TaskSchedule, TaskCollection, TaskDependency and TaskOrderPosition. Schedules use civil dates and exclusive ends. Summary progress includes every descendant activity, including unscheduled and hidden descendants; milestones contribute dates, not progress.
TaskManagerModel(data, start, days) is shared by TaskManagerView and TaskTimelineView. Both use TaskActions for details, schedule, duration, progress, group and sibling-order forms, plus optional creation. Missing capabilities are hidden. Confirm through adding, replacing or reordering and model.setData. Dependencies validate references/cycles and remain visual only. There is no implicit scheduling or direct progress/resize grip on task charts.
Resources
Use ResourceItem(id, title, ResourceUsage.Finite(quantity)) for consumable stock, or ResourceUsage.Reusable(capacity) for concurrent capacity. Adjacent exclusive intervals do not overlap. Invalid or over-allocated snapshots reject atomically.
Calendar integration uses ResourcePlan, ResourcesModel(plan, date) and ResourcesView(model, today, onChangeRequested = { model.confirm(it) }). The composed model.calendar retains navigation when setPlan changes data.
Timeline integration uses ResourceTimelinePlan(items, rows, placements), ResourcesTimelineModel(plan, start, days) and ResourcesTimelineView. Every placement carries an item ID, row ID and timed entry. ResourceTimelinePolicy adds row/item blocks, optional overlap prevention and consumer validation. Policies apply to placement, movement, resizing, reassignment and removal.
propose returns an immutable change without reserving stock. confirm rejects foreign instances, old revisions and newly invalid candidates. An authoritative setPlan invalidates outstanding proposals. Async consumers must validate their backend state before confirmation. The UI offers native date/time forms as well as hold-to-drag paths; ordinary swipes remain scrolling gestures.
Availability Picker
Create nonoverlapping AvailabilityRule intervals inside AvailabilityData. AvailabilityPickerModel(start, days, data) has a fixed civil-date horizon whose last selectable date is start + days - 1. AvailabilityPickerView emits only a complete valid selection, or null for an explicit reset. setSelection does not echo a callback. A changed completed selection remains visible with an issue.
Rules distinguish availability, start/end permission, traversal and minimum duration. Missing coverage is unknown. An unavailable day may be an exclusive end when permitted; it is not consumed. setData cancels pending loads, and completion checks current rules. AvailabilityDataProvider supplies clipped query pages; empty pages retain unknown gaps. Queries at the upper supported civil-date boundary are clipped to a representable exclusive end. No reservation or pricing is performed.
AvailabilityPickerConfiguration groups language, layout, indicators, interactivity, reset placement and optional opaque timezone context. AvailabilityPresentation provides text, bounded day/hint content, indicator color and optional badges. Annotations and badges never change rules. All configured months remain available on narrow layouts. Native disabled endpoints preserve the same validation path.
Appearance and native controls
Provide LocalComponentAppearance with ComponentAppearance to configure frame, day and card styles, independent content/header density and fill/content sizing. Models and confirmed data are independent of appearance. LocalCalendarPresentation adds Calendar/Resources event tint and decorative content, plus per-band constraint captions. TimelinePresentation.tint resolves entry color from the original entry/assignment/resource context; content slots can compose Android images, icons and initials without introducing image-loading dependencies into Core. Android date/time inputs use platform dialogs; the package does not draw imitation iOS controls.
The demo owns settings, fixture translation and confirmation examples. Activity saved state includes confirmed task/timeline/resource changes, selection, grouping, zoom and horizontal viewport position. Native task, timeline and resource forms also retain their pending values. Saved state is transient UI restoration, not backend persistence. Resource stack transitions use 180 ms and Compose's system animation duration scale; turning off system animations removes the transition. Haptic feedback remains native. Source implementation and runtime/visual acceptance are tracked separately in docs/native-android.md; do not infer release readiness from these API examples.
Half-day Calendar bars
Set CalendarPresentation(dayEdges = { CalendarDayEdges.Half }) through LocalCalendarPresentation. Week bars use fractional first/last cells and lane allocation; clipped continuations and single-day events retain full cells. The default is Full. Domain intervals and callbacks retain exclusive ends. The regular demo opts in; Month/Day retain native list presentation.
Buffered entries and cursor resource pages
TimelineModel.setLoadingPolicy(TimelineLoadingPolicy(...)) configures prefetchViewports, minPrefetchMinutes, triggerViewports, minTriggerMinutes, debounceMilliseconds and maxCachedWindows. Trigger margins cannot exceed prefetch margins. Empty pages retain coverage, newer overlapping responses win, and oldest cached windows are evicted first. Provider/policy replacement, explicit reload and authoritative setData invalidate coverage. The application must serve confirmed edits on subsequent reads.
setResourceProvider(provider, policy) accepts TimelineResourceProvider and TimelineResourceLoadingPolicy. The suspending provider receives a TimelineResourceQuery(cursor, limit) and returns TimelineResourcePage(rows, nextCursor). Null ends pagination. Repeated cursors, duplicate IDs and empty nonterminal pages fail without advancing. Providers own stable ordering. The measured row viewport overrides a too-small minimum. Row pages remain loaded on reverse scrolling; fill sizing prevents a content-height feedback loop. resourceLoadState, hasMoreResources and retryResources() expose recovery. Custom renderers call requestResources(visibleRows, remainingRows).
ResourcesTimelineModel.setDataProvider(ResourceTimelineDataProvider) adapts lazy ResourceTimelinePlan responses into the same time-window cache. Return the unchanged configured items and rows, plus placements overlapping the query for its resource IDs. Retained placements preserve item references. Unknown coverage blocks editing; global capacity remains the backend's responsibility. Do not attach a resource-row provider directly to the composition's inner Timeline.
See demo walkthrough for the corresponding controls.