ChronoLaneJS roadmap
This document is the canonical backlog for work that remains before ChronoLaneJS can be considered stable. GitHub issues may be created for individual work items, but they should reference the identifier here rather than becoming a second roadmap.
Last reviewed: 2026-08-25
Tracking rules
[P0]blocks the first public npm release.[P1]should be completed before a stable1.0.0release.[P2]is valuable follow-up work that does not block the initial API.- Check an item only after its implementation, tests, stories, public types, and documentation are complete.
- Breaking changes should be completed before the first release rather than preserved behind aliases or compatibility wrappers.
- The time-grid render body stays co-located with
TimeGridView. Only genuine renderer extension points and cohesive domain modules should live in separate files.
Release gates
- [P0][REL-01] Complete every P0 correctness and API item.
- The first package must not publish contracts already known to be incorrect or redundant.
- [P0][REL-02] Reserve and configure the
@chronolanejsnpm scope.- The free
@chronolanejsnpm organization owns the scope. @chronolanejs/reactdeclares public access and the npm registry in its package metadata.- The
maximilianwalkerpublishing identity owns the organization and has package write access through its Developers team.
- The free
- [P0][REL-03] Verify the release workflow end to end.
0.1.0-rc.0was published under npm'snexttag with a matching GitHub prerelease from the two-factor-protected publishing account.MaximilianWalker/ChronoLaneJSandpublish.ymlare configured as the npm trusted publisher, and the gated automatic release workflow is enabled.- A release-bearing
devpromotion published1.0.0through semantic-release with provenance. The major version correctly reflected the breaking commits included in the initial stable promotion; a later promotion published1.0.1through the same path. npm run examples:checkcreates one exact tarball and verifies its files, metadata, runtime exports, declarations, and styles from clean consumers.npm run release:verifyenforces fail-closed validation ordering before semantic-release can publish.
- [P0][REL-04] Define the supported runtime matrix.
- CI tests matching React and React DOM 18.2 and 19.0 releases against the supported Node 22, 24, and 26 lines, including a production package build and server-render verification for every combination.
- Chrome and Edge 111+, Firefox 114+, and Safari and iOS Safari 16.4+ are supported without polyfills; older and incomplete-Intl runtimes are not.
- [P1][REL-05] Establish versioning and release notes.
- Semantic-release derives versions and tags from Conventional Commit
messages promoted from
devtomain; curated notes live inCHANGELOG.md. - Fixes and performance changes publish patches, features publish minors, and breaking changes publish majors.
- The bootstrap release candidate uses npm's
nexttag; automatic stable releases frommainuse npm'slatesttag. CHANGELOG.mdprovides curated consumer-visible history alongside the generated release notes and is rendered on GitHub Pages.- Every new major version includes a versioned
docs/migrations/v<major>.mdguide covering all public contract breaks before promotion.
- Semantic-release derives versions and tags from Conventional Commit
messages promoted from
Correctness
- [P0][TG-01] Preserve original event identity in time-grid callbacks.
- Layout segments retain their normalized source event.
- Selection and opening callbacks receive the source with its unclipped boundaries, plus the rendered day/resource occurrence.
- Renderers receive the source event and visible segment separately.
- [P0][TG-02] Return a complete event-drop payload.
- Moves return the source event, proposed start and end, and explicit source and destination day/resource positions.
- Cross-resource moves retain the concrete destination resource.
- Moving a clipped segment preserves the source event's full duration.
- [P0][TG-03] Decouple slot interaction from grid visibility.
- Slots remain selectable and valid movement targets regardless of grid-line styling.
- The redundant
showGridprop is removed; the interaction layer is always mounted and grid-line presentation is owned by CSS.
- [P0][DATE-01] Replace date-shaped time-of-day inputs.
minTimeandmaxTimeaccept strict wall-clockHH:mmvalues, with24:00reserved for the exclusive end of a complete day.- Layout uses minute offsets instead of artificial reference dates and keeps wall-clock rows stable across DST changes.
- [P1][DATE-02] Normalize every externally supplied selection value.
- Selected days and half-open range boundaries accept
CalendarDateInput, are cloned and normalized with the configured time zone, and never mutate controlled application state. - Invalid boundaries throw contextual
TypeErrormessages; empty or reversed selection ranges throwRangeError.
- Selected days and half-open range boundaries accept
- [P1][DATE-03] Define navigation boundary behavior.
minDateandmaxDateare validated inclusive navigation days; partially overlapping ranges remain visible while outward navigation is disabled.- Controlled anchors outside the interval remain rendered. Movement farther
outside is disabled, and the first inward request clamps directly to the
nearest boundary through
onDateChange. - Built-in and range-owned navigation proposals share the same normalization and clamping contract across agenda, month, and time-grid views.
- [P1][RANGE-01] Make range resolution and navigation one coherent
contract.
resolveCalendarRangereturns normalized bounds, days, and onenavigate(direction)function instead of discarding navigation metadata.- Range definitions use
dayCountfor generated spans,datesfor explicit days, and one nestednavigationstrategy withstepDaysorresolveAnchor. - Redundant view-level
navigationStepandnavigateDateprops are removed; callback-produced and non-contiguous definitions retain their strategy.
- [P1][RESOURCE-01] Use stable resource identifier types.
- Replace
unknownresource identifiers withCalendarResourceIdor a constrained generic identifier. - Detect missing or duplicate resource identifiers.
- Document equality and multi-assignment behavior.
- Replace
- [P1][SCALE-01] Validate label configuration explicitly.
labelIntervalmust be an integer multiple ofslotDuration.- Invalid configuration throws instead of silently falling back.
Public API simplification
- [P0][API-01] Make
CalendarPropstype-safe for built-in views.- Replace
[key: string]: unknownwith a discriminated union keyed byview. - Reject misspelled and unsupported props at compile time.
- Preserve a typed path for application-defined view registries.
- Replace
- [P0][API-02] Use one controlled and uncontrolled configuration path.
- Navigation uses
dateanddefaultDateconsistently. Calendarkeeps shared behavior at its root and selected-view configuration underviewProps; direct views receive their own props directly.- Uncontrolled view state is never updated during render.
- Navigation uses
- [P0][API-03] Keep one callback for each user action.
- Event selection and opening use separate semantic callbacks with one shared
(event, interaction, context)shape. - Raw event-root interactions are additive through
eventInteractionsand never replace selection or opening behavior. - Slot selection uses
onSlotSelect(slot, interaction). - Callback naming and argument order are consistent across views.
- Event selection and opening use separate semantic callbacks with one shared
- [P0][API-04] Make callback presence enable interactions.
onEventSelect,onEventOpen,onEventDrop, andonEventResizeenable only their corresponding behavior without remapping gestures.- Optional
canSelectEvent,canOpenEvent,canDragEvent, andcanResizeEventpredicates restrict individual occurrences or segments.
- [P1][API-05] Replace flat renderer props with a
componentscontract.- Group event, slot, background, day-header, resource-header, empty-state, and navigation renderers by view.
- Keep only renderer extension points that own meaningful markup.
- [P1][API-06] Simplify renderer payloads.
- Slot renderers should receive a
slot, selection state, and element props instead of fourteen duplicated fields. - Event renderers should receive the original event, visible segment,
selection state, and element props instead of layout fields repeated both
inside and outside
event. - Time-grid day and resource headers receive their concrete grouping value, covered columns, and prepared title without conflating both levels.
- Slot renderers should receive a
- [P1][API-07] Consolidate remaining visual dimensions.
- Slot width and height use one flat
slotSizingcontract with mutually exclusive fixed and minimum properties; obsolete cell dimensions and nested mode values are removed. - Header row height and time-axis width use typed CSS variables; headers and slots consume one shared column-track definition so their widths cannot conflict.
- Layout-sensitive variables use deterministic pixel lengths, and one frame token owns both the outer border and fixed-width geometry.
- A typed grid-line width token replaces
showGridLines. - Both
Calendarand direct view components receive typedclassNameandCalendarStyleprops.
- Slot width and height use one flat
- [P1][API-08] Keep time-grid scale configuration independently overridable.
- Flat primitive props avoid configuration-object merge rules and unstable object identities when callers override one value.
slotDuration,resizeStep, andlabelIntervalindependently own slot selection, resize precision, and label cadence.
- [P1][API-09] Group resource configuration.
- Keep resource items and their ID, title, and event-assignment accessors in one typed resource contract.
- Preserve generic inference from the resource items.
- [P1][API-10] Group formatting and messages.
- Complete
formattersandmessagesregistries replace scattered format strings, header callbacks, labels, and hardcoded text. - Exported immutable English defaults support explicit consumer-side extension without hidden partial-object merging.
- Complete
- [P1][API-11] Remove the redundant resource preset.
- Resource columns are already a capability of every time-grid range.
- Remove
ResourceViewand theresourceview name; document resources on day, week, and custom time-grid ranges.
- [P1][API-12] Audit the package export surface.
- The root entry exports stable normalization, locale, view, and renderer contracts; low-level date/range construction helpers stay internal.
- Renderer payloads expose semantic dates, intervals, and resource identity; generated keys, rows, lanes, and indexes stay inside time-grid layout code.
- A committed API Extractor report, exact runtime export allowlist, and bidirectional docs verification make accidental surface drift fail checks.
- [P2][API-13] Accept readonly consumer collections.
- Events, background events, resources, selected IDs, and explicit range days should accept readonly arrays without requiring copies.
- [P1][API-14] Make time-grid grouping hierarchy explicit.
- Render separate day and resource header levels when resources are present.
- Allow callers to choose day-first or resource-first column grouping.
- Omit the resource-header level when no resources are configured.
Time-grid implementation
- [P1][ARCH-01] Keep the time-grid render body owned by
TimeGridView.- The view renders its prepared layout directly without a private prop handoff or a generic grid wrapper.
- Future extractions must own a cohesive responsibility, reduce coupling, and expose a smaller contract than the code they replace.
- Pure layout behavior remains in independently testable domain modules.
- [P1][ARCH-02] Retire the generic interaction helper module.
- Event interaction predicates are evaluated where their behavior is owned.
- Drop construction is a focused, independently tested domain operation.
- [P1][ARCH-03] Share event interaction semantics across views.
- One tested policy owns selection, opening, raw interactions, keyboard, and shortcut behavior for month, agenda, and time-grid renderers.
- View-specific markup remains separate and receives cohesive standard React interaction props.
- [P2][ARCH-04] Establish performance limits.
- Benchmark large event and resource sets.
- Avoid repeated linear selected-ID lookups and unnecessary per-render regrouping.
- Decide when resource or event virtualization becomes necessary.
Localization and accessibility
- [P0][I18N-01] Use locale-aware time formatting.
- Remove hardcoded
HH:mmfrom visible and accessible text. - Provide locale-aware defaults and explicit formatter overrides.
- Remove hardcoded
- [P0][I18N-02] Make all library-owned text configurable.
- Cover navigation, grid labels, slot labels, event ranges, empty states, and month overflow text.
- Do not require replacing a renderer solely to translate a string.
- [P1][A11Y-01] Define time-grid keyboard semantics.
- Selectable slots form a labelled composite grid with real rows, cells, concrete day/resource column headers, and one roving Tab stop.
- Arrow, Home, End, and Page keys navigate without changing selection; native Enter and Space activation retain the slot callback contract.
- Passive schedules remain labelled scroll regions, while timed events and edit controls stay in an independent overlay with unchanged interactions.
- [P1][A11Y-02] Replace native-only drag and drop.
- Independent move controls use one slot-target model for pointer, touch, and keyboard input without changing event select/open gestures.
- Complete proposals preview immediately, announce their date, time, and
resource, and invoke
onEventDroponce when committed.
- [P1][A11Y-03] Audit every built-in view with assistive technology.
- Automated axe checks and named Storybook audit surfaces cover day, week, month, agenda, and custom time-grid views.
- The maintainer release audit records screen-reader names, focus visibility, forced colors, 200%/400% zoom, and reduced-width behavior.
- [P2][I18N-03] Add right-to-left layout support.
- Define time-gutter, navigation, event-lane, and resource-column behavior for RTL documents.
Testing and verification
- [P0][TEST-01] Test public callback identity and payloads.
- Browser stories cover ordinary, clipped multi-day, overnight, and multi-resource event callbacks.
- Selection and opening assertions verify source boundaries and occurrence resource data rather than visible layout-segment values.
- [P0][TEST-02] Test event movement across days and resources.
- Unit tests cover duration preservation and cross-resource destinations.
- Browser stories cover pointer, touch, keyboard, cancelled, and cross-resource moves.
- [P0][TEST-03] Add compile-time public API tests.
- Assert accepted prop combinations for every built-in view.
- Assert that typos, wrong callback payloads, and view-incompatible props fail compilation.
- [P1][TEST-04] Cover view state and navigation contracts.
- Controlled and uncontrolled anchor movement is exercised across every built-in view.
- Date and visible-range callbacks assert exact normalized payloads, including the month view's month boundaries.
- Browser coverage verifies min/max disabling and recovery, non-contiguous ranges, and custom range-owned navigation.
- [P1][TEST-05] Cover interaction enablement and renderer contracts.
- Callback-presence defaults and event-specific predicates.
- Selection, opening, resize, and slot interaction with customized renderers.
- Interaction remains available when grid lines are visually hidden.
- [P1][TEST-06] Test supported dependency combinations.
- The CI compatibility matrix installs matching React and React DOM 18.2 and 19.0 releases on every supported Node line.
- Every combination runs unit tests, a production package build, and the built package's server-render verification.
- [P1][TEST-07] Add clean consumer fixtures.
- Install the packed artifact into representative Vite and Next.js apps.
- Verify ESM exports, declarations, CSS, the client directive, lazy locales, SSR import safety, and tree shaking.
- [P1][TEST-08] Expand timezone and locale scenarios.
- Configured-zone and host-timezone matrices cover multiple positive, negative, and fractional UTC offsets plus Lisbon and New York DST changes.
- Locale tests cover Sunday, Monday, and Saturday week starts, 12/24-hour clocks, and rejected or malformed lazy-loaded locale modules.
- [P2][TEST-09] Add visual regression coverage.
- Use deterministic Storybook screenshots for overlap, clipping, responsive widths, custom themes, and RTL.
- [P2][TEST-10] Define meaningful coverage thresholds.
- Measure core and interaction branches while avoiding a target that rewards low-value snapshot tests.
Documentation and examples
- [P0][DOC-01] Update documentation with the final pre-release API.
- Getting started and the API reference use the current names and document event identity, controlled state, time zones, ranges, resources, renderer contracts, and movement payloads with concrete data.
- [P1][DOC-02] Publish a complete API reference.
- The API reference covers every public export and interface
property, including callback payloads, defaults, examples, and thrown
errors.
npm run docs:checkenforces source and GitHub Pages coverage.
- The API reference covers every public export and interface
property, including callback payloads, defaults, examples, and thrown
errors.
- [P1][DOC-03] Document styling and theming.
- Styling and theming defines every supported CSS variable, stable class hook, responsive behavior, and the ownership boundary between library layout and consumer presentation.
- [P1][DOC-04] Add runnable consumer examples.
- The consumer examples provide independently locked Vite and
Next.js applications. They cover controlled navigation, resources,
localization, custom renderers, and interaction state updates and are
production-built by
npm run examples:checkin CI.
- The consumer examples provide independently locked Vite and
Next.js applications. They cover controlled navigation, resources,
localization, custom renderers, and interaction state updates and are
production-built by
- [P1][DOC-05] Document accessibility behavior.
- Accessibility documents current keyboard and focus behavior, messages, equivalent movement inputs and announcements, and custom-renderer responsibilities without claiming open A11Y work is done.
- [P2][DOC-06] Document deliberate non-goals.
- Decide and document ownership of recurrence expansion, persistence, fetching, application state, and design-system styling.
- [P1][DOC-07] Organize the documentation site around reader tasks.
- Replace the promotional documentation masthead with direct access to each document, grouped navigation, a mobile disclosure, breadcrumbs, and a generated page outline.
- Move the documentation campaign to the homepage, use reader-oriented page names, and keep maintainer-only repository rules out of the public documentation navigation.
Website discovery and search
- [P1][WEB-01] Publish every document at a crawlable URL.
- Replace fragment-selected documents such as
/docs/#doc-apiwith stable paths such as/docs/api/,/docs/accessibility/,/docs/migrations/v2/, and/docs/changelog/. - Generate meaningful HTML for the homepage and every document at build time so their primary content does not depend on client-side rendering.
- Make direct requests to every public path return its content on GitHub Pages, and connect documents with ordinary crawlable links.
- Replace fragment-selected documents such as
- [P1][WEB-02] Establish Google discovery and indexing infrastructure.
- Publish a root
sitemap.xmlcontaining fully qualified canonical URLs for the homepage and every public document. Reference it from the host-rootrobots.txtwhen a project-owned domain or controllable GitHub Pages user site makes that file available; a project-path robots file is not valid. - Add a canonical URL, unique title, specific description, and matching Open Graph URL to every generated page.
- Verify the exact GitHub Pages URL-prefix property in Google Search Console,
submit the sitemap, inspect representative URLs, and record or resolve all
reported discovery, rendering, canonicalization, and indexing problems. The
2026-08-25 inspection result and the initial sitemap-processing state are
recorded in
DEVELOPMENT.md.
- Publish a root
- [P1][WEB-03] Make the library's search intent explicit.
- Describe ChronoLaneJS consistently as an open-source React and TypeScript calendar and scheduler across the website, GitHub repository, npm package, release pages, and README files.
- Give core capabilities dedicated pages with complete examples and screenshots, including drag and resize interactions, resource scheduling, time-zone handling, accessibility, custom renderers, TypeScript APIs, and framework integration.
- Use capability-specific page titles and descriptions based on concrete developer queries rather than broad terms such as "modern calendar".
- Add accurate
SoftwareSourceCodestructured data for the repository, package, license, programming language, supported runtime, and current release without treating structured data as a guaranteed rich result.
- [P2][WEB-04] Strengthen GitHub and npm package discovery.
- Audit the GitHub description and topics and the npm description, keywords, homepage, repository, and README opening for the exact project name and its principal React calendar use cases.
- Cross-link the website, repository, npm package, documentation, changelog, migration guides, and GitHub releases with stable public URLs.
- Keep version, installation, compatibility, and release information consistent so search engines can associate those surfaces with one project rather than several incomplete descriptions.
- [P2][WEB-05] Build legitimate external authority.
- Publish substantial technical demonstrations for the library's distinctive capabilities and link readers to the most relevant permanent guide rather than only the homepage.
- Seek inclusion in maintained React and open-source directories, examples, and community resources where the library is genuinely relevant.
- Encourage public adopters and integrations to reference the repository or documentation without manufacturing links or duplicating promotional content across sites.
- [P2][WEB-06] Measure search visibility and decide long-term site identity.
- Track sitemap coverage, indexed URLs, crawl and rendering problems, search queries, impressions, and clicks in Search Console after each release.
- Treat visibility of the official website, GitHub repository, and npm
package for the exact
ChronoLaneJSquery as the initial discovery baseline; measure capability-query growth separately as a longer-term goal. - Evaluate a project-owned domain for durable URLs and stronger branding, including redirect, canonical, and Search Console migration requirements, without treating a domain change as a substitute for crawlable content or external authority.
Repository and maintenance
- [P1][REPO-01] Add structured issue templates.
- Structured bug and feature forms capture reproduction or use-case details, browser/time-zone/locale considerations, accessibility impact, verification expectations, and the relevant roadmap identifier.
- Security reports are directed to the private vulnerability-reporting form.
- [P1][REPO-02] Automate dependency maintenance.
- Weekly Dependabot updates cover the root package, locked Vite and Next.js consumers, and pinned GitHub Actions; routine minor/patch updates are grouped and every pull request runs the full CI matrix.
- Major updates, including major-version security fixes, stay in separate reviewer-requested pull requests; security alerts and routine security groups remain enabled independently.
- [P1][REPO-03] Verify the security-reporting path.
- Private vulnerability reporting is enabled and
SECURITY.mdlinks directly to the repository's private advisory form. - Only npm's
lateststable release is supported. Confirmed issues use a draft advisory and temporary private fork, publish a validated patch frommain, and merge the released fix back intodev.
- Private vulnerability reporting is enabled and
- [P2][REPO-04] Track package size.
- Record an initial ESM and CSS budget and fail CI on unexplained material regressions.
- [P2][REPO-05] Define compatibility review for dependency upgrades.
- Date-fns,
@date-fns/tz, React, TypeScript, Vite, and Storybook upgrades should include explicit public-API and consumer-fixture verification.
- Date-fns,
Product decisions
- [P1][DEC-01] Include precise time-grid event resizing.
onEventResizeandcanResizeEventcover start/end edges with pointer, touch, and keyboard handles independent from event selection/opening.resizeStepowns target precision independently from visible slot size; movement previews the complete interval immediately.- Resizing may cross visible days while retaining the resource.
- Commit emits one complete proposal; Escape, pointer cancel, and no movement emit nothing. Background events remain non-interactive.
- [P1][DEC-02] Decide how multi-day events appear in time-grid views.
multiDayEventLayoutselects the backward-compatible"timed"layout or a"dedicated"region aligned with visible day/resource columns.- Multi-day placement is derived from positive half-open event intervals; no redundant all-day event flag is introduced.
- Dedicated foreground events retain selection, opening, day/resource movement, whole-day resizing, accessible labels, and DST-stable wall times. Background events remain in the hourly grid.
- [P2][DEC-03] Decide the large-resource strategy.
- Define practical limits and whether horizontal virtualization, grouped resources, or consumer-owned pagination belongs in the library.