Appearance
Resources
Resources combines Calendar with a finite resource inventory. It is available in the Web implementation (Vanilla, React, Vue) and native SwiftUI implementation. Resources do not add resource lanes to Calendar or change the resource Timeline.
Web
ts
import { createResources } from '@xsigns/chronosketch/resources'
import '@xsigns/chronosketch/resources/styles.css'
const resources = createResources({
date: '2026-09-14',
locale: 'de-DE',
title: 'Verfügbare Ressourcen',
caption: 'Zum Einplanen in den Kalender ziehen.',
defaultDurationMinutes: 60,
showRemainingCount: true,
data: {
items: [
{ id: 'client', title: 'Client demo', quantity: 1 },
{ id: 'team', title: 'Team meeting', quantity: 2, description: 'Project team' },
],
placements: [],
},
onChangeRequested: ({ plan }) => resources.setData(plan),
onEventClick: event => { /* open your event editor */ },
})
resources.mount(document.querySelector('#resources')!)
// resources.destroy() when unmountingReact exports Resources from @xsigns/chronosketch/react with ResourcesOptions as individual props. Vue exports Resources from @xsigns/chronosketch/vue with an options prop. Both require the Resources stylesheet. Supply confirmed updates by replacing data; the wrappers dispose their owned component on unmount.
ResourcePlan.items contains unique, nonempty IDs, titles, nonnegative integer quantity (the total allowance) and optional descriptions. placements contains { resourceId, event }, where event is a standard CalendarEvent. Supply the whole plan, including placements outside the visible range. The library validates unique event IDs, source links, intervals and quantity before accepting a snapshot.
Remaining quantity is total minus placements. One item shows one card, multiple items show a small symbolic stack, zero hides the card. Layers do not encode an exact count. Accessible labels include the remaining count.
Web showRemainingCount (default false) adds the confirmed remaining count in an inset circular/pill badge at the lower right. Long titles keep the full card width; the badge stays inside the card. setShowRemainingCount(boolean) toggles it without resetting Calendar navigation. React/Vue synchronize this option. The Web demo enables it for review; native count badges are not implemented yet.
Month date cells and Week/Day all-day areas create a one-day all-day interval. Week/Day time grids use the dropped time snapped to 15 minutes, with configurable defaultDurationMinutes (1–1440, default 60). Ends remain exclusive and timed values remain floating local times. Select a resource card to choose a date and, optionally, a time without dragging; this also works in Agenda and compact views.
Web title configures the Resources sidebar heading; omitted or empty uses the localized default. caption configures its hint; omitted uses the localized default and caption: '' hides it. Use setTitle(value) and setCaption(value) for runtime updates (undefined restores defaults). React/Vue synchronize both options without resetting Calendar navigation. Text is rendered as plain text. The caption retains its existing compact-layout hiding behavior.
Confirmation, editing and deletion
onChangeRequested receives { previous, plan }. This is a proposal, not a save notification: confirm with setData(plan) or by replacing adapter data. Rejection leaves the confirmed inventory/events unchanged. For asynchronous persistence, compare the previous snapshot/revision against the authoritative plan and reject stale proposals. The component does not serialize remote saves or reserve stock.
Exports editResourcePlacement(plan, event) and removeResourcePlacement(plan, eventId) create validated immutable replacements. Editing preserves the source link and usage; deletion returns one unit. The demo shows an event editor that can convert all-day events to timed events. Forms and persistence are consumer-owned; validate edited events against any application availability policy before confirming. There is no resource quantity editor in V1.
The instance exposes getData, setData, setChangeHandler, mount, destroy and the composed calendar instance for Calendar configuration/navigation. Use setData to update events and inventory together; do not independently replace Calendar events. Calendar presentation options are accepted at construction. Web adapters currently synchronize data/callbacks and recreate on locale/default duration changes; other presentation options are construction-time inputs.
Native SwiftUI
swift
let item = try ResourceItem(id: "client", title: "Client demo", quantity: 1)
let model = try ResourcesModel(
plan: ResourcePlan(items: [item]), date: CivilDate("2026-09-14"),
language: .german, defaultDurationMinutes: 60
)
// Retain model in consumer state and place inside a ScrollView as needed:
ResourcesView(model: model, today: today, showRemainingCount: true, onChangeRequested: { previous, next in
if model.plan == previous { model.setPlan(next) }
}, onEventSelected: { event in /* consumer editor */ })Import ChronoSketchCore and ChronoSketchUI; iOS 26+. Swift uses ResourceItem.detail for the optional description. ResourcePlan.placing, .editing, .removing return validated snapshots; ResourcesModel.setPlan synchronizes Calendar without losing navigation. model.calendar owns Calendar presentation/availability settings.
Native drag transfers are scoped to one Resources instance. Month, Week/Day all-day areas and time-grid columns accept them. Native Month retains its date grid with selected-day agenda. Tapping a card opens native date/time pickers. Wide layouts show the sidebar to the left. Compact layouts place three square, widget-like resource cards per row above Calendar (80-point baseline, scaling with Dynamic Type). Compact cards show titles; descriptions remain available in the accessibility hint. Additional resources continue in the same horizontally scrollable row. Wide sidebars keep the heading visible and scroll their inventory vertically within the height of Calendar. Immediate swipes scroll; the native hold-to-drag gesture lifts a card for placement. Web and native cards use opaque, softly rounded paper surfaces with fanned backing cards. Accent-tinted fills and soft shadows separate the layers without outlines or a leading stripe. Light mode keeps a near-white front; dark mode uses distinct Accent shades for the front and rear cards. All layers remain opaque. Cards support Dynamic Type and accessible availability labels. Device VoiceOver and touch acceptance are separate from package tests and simulator inspection.
Native count and stack feedback
ResourcesView(showRemainingCount: true, ...) displays the remaining quantity inside each card at the lower right. It defaults to false; the native demo enables it. Titles retain the full card width, with a separate row for the count. The existing accessibility value announces availability without repeating the badge.
Each actual pickup and confirmed return exchanges the rear cards' tilt. The arrangement remains across drops, cancellations and inventory updates. Reduce Motion disables the short transition. Repeated placement uses native drag-session callbacks, so keeping a transfer provider alive cannot block the next pickup.
iPhone haptics
ResourcesView(model: model, today: today, hapticsEnabled: false, ...) disables Resources and composed Calendar interaction feedback; the default is true. A soft pulse marks native drag activation, light selection ticks mark a new date or snapped time target, and a success pulse follows acceptance through model.setPlan. Holding the same target does not repeat feedback. Ticks use the shared 80 ms limit without queued pulses. Cancelling or leaving the Calendar produces no success feedback.
The native source/target share an instance-scoped drag session and an in-process text provider tagged with the Resources instance identifier. Drop updates track positions within connected all-day bars as well as individual day/time columns. Unsupported hardware stays silent; simulator checks cannot verify the physical feel of the pulses.
Styling
Web hooks: .xc-resources, .xc-resources-sidebar, .xc-resources-list, .xc-resource-stack[data-multiple], .xc-resource-card, .xc-resource-name, .xc-resource-description, .xc-resources-dialog. Decorative backing layers are pseudo-elements and never independent drag targets. The stock theme follows system light/dark appearance; existing Calendar styles remain overridable.
Inventory scrolling
On wide Web layouts the sidebar is bounded by Calendar height and only .xc-resources-list scrolls vertically. At widths up to 800px it becomes one horizontally scrollable row with three visible cards. The heading stays outside the scroll area. Touch swipes scroll inventory; holding still for 350 ms prepares a Web card drag. Mouse dragging and keyboard placement remain available. Card surfaces derive from --xc-accent when set on Resources, with opaque light and dark fallback colors. Forced-colors mode restores card borders.
Returning scheduled resources
Drag a scheduled placement onto its Resources sidebar to propose removing the placement and returning one unit. Web supports visible Month bars and Week/Day event cards; native iOS exposes this on Week/Day cards only, excluding Month and Agenda lists. The whole sidebar accepts returns, including an exhausted inventory. The normal onChangeRequested / setData or setPlan confirmation contract applies; a cancelled gesture or rejected proposal does not replenish inventory. Deletion remains available as a non-drag alternative.