Skip to content

feat!: v2 — compound components, RTL, dark mode, a11y, responsive, i18n, loading states, slot creation, and breaking refactors#70

Merged
Jaganath-MSJ merged 96 commits into
betafrom
dev
May 9, 2026
Merged

feat!: v2 — compound components, RTL, dark mode, a11y, responsive, i18n, loading states, slot creation, and breaking refactors#70
Jaganath-MSJ merged 96 commits into
betafrom
dev

Conversation

@Jaganath-MSJ

Copy link
Copy Markdown
Owner

Pull Request Checklist

  • My code follows the code guidelines of this project
  • I have updated the documentation accordingly (if applicable)
  • Tests and builds pass locally

Description

This is the v2 major release of calendar-simple. It introduces a large set of new features, a full test suite, comprehensive documentation, and several breaking changes. The calendar has been significantly restructured to support compound component composition, a migrated date library (dayjs → Luxon), and a much richer public API.


⚠️ Breaking Changes

  • Luxon migration (refactor!): dayjs replaced with Luxon throughout. All internal date handling now uses DateTime. Consumers passing raw Date values are unaffected (boundaries still accept JS Date), but custom hooks or utilities relying on dayjs objects will need updating.
  • ISO date formatting fix (fix!): Plural unit names corrected and ISO date format standardised — any code relying on the previously incorrect output will need to be updated.
  • i18n restructure (feat(calendar)!): Locale support is now driven entirely by Luxon. The locale prop replaces any prior ad-hoc formatting configuration.
  • Compound component pattern (feat!): CalendarProvider, useCalendar, CALENDAR_ACTIONS, and per-view props types (HeaderProps, ViewProps, MonthViewProps, WeekViewProps, DayViewProps, ScheduleViewProps, CustomViewProps) are now exported from src/index.ts. This enables building fully custom calendar layouts using composition.
  • Event colorstyle: The color property on CalendarEvent has been replaced by a style: CSSProperties prop for flexible event styling.

New Features

Compound Component Pattern

  • <Calendar> now accepts children — compose <Header>, <View>, and other pieces as needed.
  • Exports: CalendarProvider, useCalendar, CALENDAR_ACTIONS, and all view prop types.
  • New useCalendarProps<T>() hook merges context config with local overrides for prop distribution.

Internationalisation (i18n / Localization)

  • New locale prop accepts any BCP 47 language tag (e.g. "fr", "ar", "ja").
  • Full Luxon locale support for month names, day names, and date formatting across all views.

RTL (Right-to-Left) Layout

  • New direction prop: "ltr" | "rtl".
  • All view CSS updated to use logical properties (inline-start/end, block-start/end) so layout mirrors correctly in RTL locales.

Dark Mode / Color Scheme

  • New colorScheme prop: "light" | "dark" | "auto".
  • "auto" detects system preference via prefers-color-scheme.
  • New useColorScheme hook exported for external use.
  • Dark mode variables applied to all views, event chips, popovers, skeleton, and header.

Loading State & Skeleton UIs

  • New isLoading prop:
    • Without events: shows view-specific skeleton (MonthSkeleton, TimeGridSkeleton, ScheduleSkeleton).
    • With events already loaded: keeps existing data visible under a non-interactive overlay during background refreshes (avoids blank-screen flicker, DI-3).
  • New renderLoading?: () => ReactNode prop for custom loading UI.

Accessibility (a11y)

  • Full keyboard navigation across all views: Tab focus management, Enter/Space activation, Escape to close popovers.
  • ARIA roles, labels, and attributes on all interactive elements (event chips, date cells, navigation buttons, popovers).
  • WCAG-compliant event text contrast via new utilities in src/utils/contrast.ts.

Responsive Design

  • Tablet and phone CSS breakpoints added for all views: Header, Month, Week, Day, Schedule.
  • Schedule view flex layout fixed to prevent content clipping.

Slot Creation

  • New creatable prop enables clicking empty time-grid slots to trigger event creation.
  • New onSlotClick?: (startDate: Date, endDate: Date) => void callback receives the slot's time bounds.

Custom Renderers

  • renderEvent?: (event: CalendarEvent) => ReactNode — replace event chips.
  • renderHeader?: (props: RenderHeaderProps) => ReactNode — replace entire header.
  • renderHourCell?: (date: Date) => ReactNode — replace hour labels in time grid.
  • renderDateCell?: (props: RenderDateCellProps) => ReactNode — replace date numbers in Month view.
  • renderScheduleSeparator?: (date: Date) => ReactNode — replace date group separators in Schedule view.

Error Boundary

  • New CalendarErrorBoundary component wraps all custom renderers so an exception in user-supplied render props shows a graceful fallback instead of crashing the calendar (DI-4).

Week Numbers

  • New showWeekNumbers prop displays ISO week numbers in the leftmost column of the Month grid.

CustomDays View

  • New customDays prop and customDays view type (ECalendarViewType.customDays) for flexible multi-day time-grid layouts (e.g. 3-day view).

Additional New Props

Prop Description
testId data-testid on root element for testing
minHour / maxHour Clamp the time-grid to a specific hour range
weekStartsOn / weekEndsOn Configurable first/last day of week
showAdjacentMonths Toggle adjacent-month dates in the month grid
resetDateOnViewChange Reset selected date to today when switching views
showAllDayRow Toggle the all-day banner row in Week/Day views
eventOverlapOffset Pixel offset between stacked overlapping events
eventsAreSorted Skip internal sort when events are pre-sorted (performance)
enrichedEventsByDate Pass a pre-built O(1) date-keyed event map

Bug Fixes

  • onMoreClick now correctly passes the hidden events array as its second argument.
  • testId-container and root CSS variables are now properly applied in compound component mode.
  • scrollIntoView (current-time auto-scroll) no longer scrolls ancestor containers unexpectedly.
  • All-day banner navigation arrows now appear correctly when a chip's rendered boundary differs from the event's actual day.
  • Partial-day event overlap layout fixed in the all-day banner and day event grid.
  • Schedule view content no longer clips due to incorrect flex layout.
  • selectedDate prop now stays in sync on external updates; year picker list calculation corrected.
  • Event z-index capped to prevent overlapping with the header.

Refactoring

  • dayjs fully removed; all date logic uses Luxon DateTime.
  • Constants consolidated; locale/keyboard utility functions merged into common.ts and formatting.ts.
  • Theme types extracted to src/types/theme.ts; CalendarClassNames moved there too.
  • Redundant props removed from individual view components (now derived through useCalendarProps).
  • ESLint migrated to flat config format (eslint.config.js).

Testing

  • Full unit test suite added — 123-file diff includes new tests for every hook, utility, and view component.
  • New test files: useColorScheme, useAllDayBanner, useDayEventLayout, useMonthGrid, useScheduleView, useResizeObserver, useEvents, contrast.ts, common.ts, date.ts, formatting.ts, CalendarContext, all view components, all core components, Popover, Header, skeletons.
  • QA Storybook stories: QA/EdgeCases, QA/Interactions, QA/LayoutLimits, QA/Performance, QA/TimeFormatting, QA/Views.
  • New story files: Accessibility, CustomDayView, Customization, Localization.
  • ResizeObserver mock added to setupTests.ts for consistent test sizes.

Documentation

  • CLAUDE.md added with full architecture guide and development patterns.
  • README.md and FEATURES.md restructured and expanded with all new features.
  • JSDoc added to all public types, CalendarContext, constants, and core hooks.
  • useEvents edge-case caveats documented (negative-duration filter C-TC3; eventsAreSorted bypass K-03).
  • Old docs/ directory removed (content merged into README/FEATURES).

Tooling & CI

  • Husky + commitlint + lint-staged added for pre-commit formatting and commit message enforcement.
  • Prettier configuration added (.prettierrc, .prettierignore).
  • GitHub Actions CI workflow: runs npm test and npm run build on PRs.
  • Node.js 18 dropped from CI matrix.
  • Playground switched to local calendar-simple dependency.
  • rollup-plugin-visualizer added for bundle analysis.

Fixes #DI-3, #DI-4

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update

How Has This Been Tested?

  • Tested via Storybook — full QA story suite added (QA/EdgeCases, QA/Interactions, QA/LayoutLimits, QA/Performance, QA/TimeFormatting, QA/Views)
  • Tested via local playground application
  • Verified build bundle (npm run build)

Unit tests added or updated for all hooks, utilities, components, and the context layer. Run with:

npm test

To run a specific area:

npm test -- useColorScheme      # Color scheme hook
npm test -- MonthView           # Month view component
npm test -- CalendarContext     # State management
npm test -- contrast            # WCAG contrast utilities

123 files changed — 19,082 insertions, 5,526 deletions across 80 commits. The headline items are the Luxon migration (breaking), compound component pattern (breaking), RTL, dark mode, full a11y, responsive breakpoints, loading skeletons, slot creation, and a complete unit test suite.

- Add ESLint with TypeScript and React plugins for code quality
- Include linting npm scripts for manual and auto-fix runs
- Configure ESLint to ignore build and storybook directories
This resolves potential dependency conflicts when installing packages with mismatched peer dependencies, ensuring a smoother installation process.
- Add .prettierrc with formatting rules and .prettierignore file
- Integrate eslint-config-prettier to avoid conflicts between ESLint and Prettier
- Update package.json with format scripts and add eslint-config-prettier dependency
- Apply Prettier formatting to existing code (quotes, semicolons, trailing commas)
- Fix missing newline at end of file in index.css and preview.ts
- Add weekStartsOn and weekEndsOn props to various views
- Update WeekView to calculate days based on config
- Modify MonthView to generate custom week range grids
- Extend useMonthGrid hook to accept week boundaries
- Set default values (0 for Sun, 6 for Sat) in constants
… range

- Add minHour and maxHour props to Calendar component and default constants
- Update TimeColumn, DayColumn, DayView, WeekView and CurrentTimeLine to respect the time boundaries
- Filter events in useDayEventLayout hook to only include those within the specified hour range
- Adjust event positioning and current time line calculation based on minHour offset
- Hide current time line when current time is outside the displayed range
Add storybook examples for the newly introduced props:
- WithTimeLimits story in DayView and WeekView to demonstrate minHour/maxHour
- CustomWeekStartEnd story in MonthView and WeekView to show weekStartsOn/weekEndsOn

Update README and FEATURES documentation to include these new props
… display

Add a new boolean prop showAdjacentMonths to CalendarProps that controls
whether dates from adjacent months should be displayed in the month view.
This provides users with the option to hide empty cells from previous/next
months for a cleaner interface when desired. The prop defaults to true to
maintain backward compatibility with existing behavior.
…display

- Introduce new `customDays` view type for displaying 1-10 consecutive days
- Add `CustomDaysView` with time grid layout and configurable day count
- Update CalendarContext to handle navigation for custom day ranges
- Extend Header component for date range and navigation in custom views
- Add Storybook stories for custom day configurations (1, 3, 5, 10 days)
- Include validation to ensure customDays is between 1 and 10 inclusive
…ures

- Add storybook examples demonstrating showAdjacentMonths prop behavior
- Update FEATURES.md to document adjacent months functionality and customDays view
- Update README.md with customDays view example and prop documentation
- Extend ECalendarViewType type definition to include "customDays"
- Rename CALENDAR_CONSTANTS to LAYOUT_CONSTANTS to better reflect its purpose
- Move calendar-related constants from time.ts to new calendar.ts file
- Fix typo in CALENDER_STRINGS to CALENDAR_STRINGS
- Update all imports to reference new constant names and locations
- Remove BOM character from theme.ts file
Move CalendarClassNames, ThemeStyle, and CalendarTheme interfaces from
calendar.ts to a new theme.ts file for better organization.

Update calendar.ts to import these types from the new module and
re-export them via the main index.ts barrel file.
- Change CalendarEvent interface from color?: string to style?: CSSProperties
- Update all event rendering components to use style prop with fallback to default color
- Modify storybook examples and playground to use style.backgroundColor instead of color
- This allows custom styling beyond just background color (e.g., borders, gradients)
Update all documentation files to reflect the change from `color` to `style` property in the
CalendarEvent interface. Add migration guide section for v1.2.0 breaking change and include
new Storybook stories demonstrating event styling customization.
Remove the 72-character line length restriction for commit message bodies to allow more flexible formatting.
- Add renderEvent prop to allow custom rendering of event items across all views
- Add renderHeader prop to enable custom header component with navigation controls
- Add renderHourCell prop for custom hour slot rendering in time grid views
- Add renderDateCell prop for custom date cell rendering in month and week views
- Update all view components (DayView, WeekView, MonthView, CustomDaysView, ScheduleView) to pass through render props
- Update core components (Popover, AllDayBanner, DayColumn, DayWeekEventItem, MonthEventItem) to support custom rendering
- Extend CalendarProps interface with new renderer type definitions
- Add comprehensive documentation for custom renderer props (renderEvent, renderHeader, renderHourCell, renderDateCell) in README.md and FEATURES.md
- Update CustomView story title for better clarity in Storybook navigation
- Add example story demonstrating all custom renderers in action
…change

When enabled, changing the calendar view (e.g., from Month to Week) will automatically reset the selected date to today. This provides better UX when users switch views and want to quickly see the current period.
Add a new `showAllDayRow` prop to the Calendar component, allowing users to hide the all-day event banner at the top of the Day and Week views. When set to false, all-day and multi-day events are rendered within the main time grid, spanning from the configured minHour to maxHour. This provides more layout flexibility for applications that do not require a separate all-day section.

- Extend dayjs with isBetween plugin to support date overlap checks.
- Update layout hook logic to conditionally include all-day/multi-day events in the grid.
- Add storybook example demonstrating the feature.
Introduce `renderScheduleSeparator` prop to Schedule view, allowing custom UI components to be rendered between date groups. This provides visual separation and customization options for multi-day schedules. The default border is conditionally hidden when a custom separator is provided.
Introduce a new prop to control overlapping event layout in day/week/custom views. When set to 0 (default), events use tiled layout with width expansion. When set to a positive percentage (e.g., 15), events stack with offset creating a layered appearance. This provides visual distinction for concurrent events while maintaining clear time boundaries.
- Replace CustomView.stories.tsx with enhanced CustomDayView.stories.tsx featuring mock events and improved layout
- Update FEATURES.md with detailed descriptions of new calendar capabilities including all-day row, event overlap styling, and custom separators
- Extend TEST_CASES.md with test scenarios for new props and view behaviors
- Update README.md props table with showAllDayRow, eventOverlapOffset, resetDateOnViewChange, and renderScheduleSeparator
Add comprehensive test stories covering different view types, time formatting, user interactions, layout constraints, and edge cases. These stories help verify the calendar component's behavior across various scenarios including overlapping events, controlled state, time range limits, and data validation.
…events

- Add `enableEnrichedEvents`, `eventsAreSorted`, `isEventOrderingEnabled`, and `sortedMonthView` props to skip expensive computations
- Support pre-sorted and pre-filtered events via `enrichedEventsByDate` to reduce runtime processing
- Bypass layout algorithms when ordering is disabled for faster rendering
- Update all view components and hooks to accept new performance options
Ensure event z-index stays below timeHeaderSpacer (z-index: 15) and stickyTopContainer (z-index: 20) to prevent visual stacking issues. Also sets columnIndex to 0 when ordering is disabled for consistent DOM stacking.
- Add documentation for `enableEnrichedEvents`, `enrichedEventsByDate`, `eventsAreSorted`, `isEventOrderingEnabled`, and `sortedMonthView` props in README.md
- Document performance optimization strategies in FEATURES.md
- Add test cases for performance options in TEST_CASES.md
- Create Performance.stories.tsx with stories demonstrating optimization techniques for handling large event datasets
- Configure vitest with jsdom environment and setup file
- Add test script commands to package.json
- Create initial unit tests for date utilities and Calendar component
- Install required testing dependencies (@testing-library, jsdom, vitest)
…ontext

- Add formatting.test.ts for generateTooltipText and getGmtOffset functions
- Add common.test.ts for calculateMaxEvents, isAllDayEvent, and isMultiDay functions
- Add CalendarContext.test.tsx for CalendarProvider and useCalendar hook
- Tests cover various view types, date manipulations, and edge cases
- Test useEvents hook filtering and enriched events behavior
- Test useAllDayBanner event stacking and visibility logic
- Test useResizeObserver observation and size updates
- Test useScheduleView event grouping and time/title rendering
- Test useMonthGrid Tetris event placement and ordering options
- Test useDayEventLayout overlapping event handling and layout modes
Jaganath-MSJ and others added 25 commits April 22, 2026 20:35
…th views

- Header: replace 640px query with 768px; compact controls stack into two rows
- MonthView: shorter header row (30px) and tighter cell padding at 768px
- MonthEventItem: smaller chips at 768px; dot-only 6px bars at 480px
Replace scrollIntoView() with direct scrollTop manipulation using
getBoundingClientRect() so autoScrollToCurrentTime only scrolls the
ScheduleView container, not outer overflow:hidden ancestors that would
push the calendar header out of view.
…iews

- WeekView: fixed 100px columns at 768px; single-column fill at 480px
- CustomDaysView: add missing overflow-x: auto; same column breakpoints as WeekView
- DayView: reduce day number font to 16px at 768px
- ScheduleView: reduce horizontal padding at 480px; narrow time column
  from 140px to 100px; shrink date number, event time, and title fonts
- Also add missing bottom padding (16px) to base .scheduleView rule
…ping

The .views container had height: 100%, which in the Calendar's flex-column
layout caused it to request the full container height (e.g., 800px) while
the Header also consumed space (~68px). This created overflow that was
clipped by overflow: hidden on the Calendar root, hiding the last date
groups in ScheduleView (e.g., May 5 not visible, May 4 half-clipped).

Change .views to use flex: 1 and min-height: 0 instead, which correctly
distributes remaining space after the Header. This also allows DayView
and WeekView to drop their calc(100% - 68px) workarounds and simply use
height: 100% of the bounded parent.

All tests pass. Verified fix resolves clipping in ScheduleView while
maintaining proper behavior in other views.
- README: detail 768px/480px breakpoints in responsive feature bullet
- README: add new "Responsive & Mobile" section with breakpoint table
- FEATURES.md: rewrite "Responsive Layout" section with per-view breakpoint changes at 768px and 480px
- Include fluid container usage tips for both files
Merge 3 single-export constant files (datetime.ts, formats.ts, ui.ts) into
existing files by domain:
- TIME_CONSTANTS, DATE_FORMATS → calendar.ts (calendar domain)
- KEYBOARD_SHORTCUTS → theme.ts (UI interaction constants)

Move locale utility functions to dedicated module:
- getDayListNames(), getMonthList() → src/utils/locale.ts
- Update 15 files to import from utils instead of constants

Replace remaining magic numbers with named constants across components
and hooks (60 min/hr, 24 hr/day, 7 days/week, millisecond intervals).

Fix TypeScript issues:
- Explicit string type for formatStr in formatting.ts
- Remove invalid ignoreDeprecations from tsconfig.json

Verify: All tests pass, lint clean, build succeeds.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
…atting

- Move handleKeyboardActivation from keyboard.ts into common.ts
- Move getDayListNames and getMonthList from locale.ts into formatting.ts
- Remove locale barrel export; keyboard was never in the barrel
- Update 6 component imports from utils/keyboard to utils barrel
- Delete keyboard.ts and locale.ts
- Add tests for handleKeyboardActivation, getDayListNames, getMonthList
Document every interface, enum, and prop across calendar.ts, events.ts,
and theme.ts.

- File-level @file docblocks on all three modules
- Inline comments on every prop in CalendarProps, CalendarClassNames,
  CalendarEvent, CalendarTheme, and supporting types
- Clarify cross-prop relationships (minHour/maxHour, weekStartsOn/weekEndsOn)
- Describe internal types: RequiredSome, CalendarContentProps, EventListType
Add file-level @file docblocks and inline JSDoc on all exported
constants in calendar.ts and theme.ts, and a full function-level
JSDoc on handleKeyboardActivation in utils/common.ts.

- Document CALENDAR_STRINGS, VIEW_OPTIONS, defaultCalendarProps,
  CALENDAR_ACTIONS, TIME_CONSTANTS, DATE_FORMATS
- Document defaultTheme, LAYOUT_CONSTANTS, KEYBOARD_SHORTCUTS
- Describe handleKeyboardActivation params, return type, and
  why it prevents default and stops propagation
Add file-level @file docblocks and inline JSDoc to CalendarContext.tsx,
useCalendarProps.ts, and useEvents.ts.

- Document CalendarState, CalendarAction, CalendarContextValue,
  and CalendarProviderProps interfaces
- Describe calendarReducer navigation logic and Luxon duration mapping
- Document CalendarProvider and useCalendar function signatures
- Document useCalendarProps merge precedence rules
- Expand useEvents @param entries for eventsAreSorted and
  enableEnrichedEvents
feat!: v2 — compound components, responsive design, accessibility, and new calendar features
- Add `direction` prop to CalendarProps; auto-infers rtl from locale when omitted
- Apply dir attribute to calendar root and container elements
- Migrate all CSS physical properties to logical equivalents across all stylesheets
  (border-inline-end, inset-inline-start, padding-inline, etc.)
- Add RTL clip-path overrides for bannerChip and popover arrow shapes
- Mirror navigation arrow icons in RTL via CSS scaleX(-1)
- Move resolveDirection from constants to utils/common
- Add ArabicLTR and HebrewRTL Storybook stories; extend Localization controls
- Fix formatting.test.ts: EDayType.short → EDayType.half (key did not exist)
- Add tsconfig ignoreDeprecations: "6.0" to silence node10 moduleResolution warning

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Implement dark mode via a new useColorScheme hook that detects the OS
prefers-color-scheme preference and applies live updates. Add colorScheme
prop to force light/dark mode. Apply resolved scheme as data-color-scheme
attribute on calendar roots, switching CSS variable palettes.

- New useColorScheme hook: reads OS preference, respects explicit prop
- New ColorScheme type: "light" | "dark" | "auto"
- Extend CalendarTheme with dark/light sub-objects for per-scheme overrides
- New resolveTheme() utility to merge flat theme with scheme-specific values
- Replace all hardcoded colors with CSS variables for unified theming
- Add matchMedia mock to setupTests.ts for dark mode testing
- Apply data-color-scheme to Calendar, CalendarContent, and Popover roots
…dark mode

Implements color scheme prop with three modes: 'light', 'dark', and 'auto' (default).
Auto mode detects OS preference via prefers-color-scheme media query and updates live
when the user toggles their system theme. Adds useColorScheme hook, comprehensive tests,
and Storybook stories demonstrating light, dark, and auto modes across all view types.
Overhaul both documentation files with a tighter, more navigable
structure. Adds a Table of Contents, removes decorative emoji from
headings, condenses verbose prose into scannable bullet lists, and
reorganizes sections to group related features (RTL, color schemes,
accessibility) together.

- Add Table of Contents to FEATURES.md
- Replace prose paragraphs with concise bullet descriptions
- Standardize punctuation (em-dashes, separators)
- Reorganize feature groupings for easier discovery
The public API declares onMoreClick(date, hiddenEvents?) but the
second argument was never populated — the internal prop type lacked
the parameter, both call sites omitted it, and the MonthView boundary
wrapper dropped it.

- Extended MonthEventItem.onMoreClick prop type to accept hiddenEvents
- Computed hiddenEventsList (non-spacer overflow events) inside the
  visibility-capping block and passed it at both call sites
- Updated MonthView wrapper to forward hiddenEvs alongside the date
- Updated MonthView tests to assert the correct events array is received
In compound-component mode (Calendar with children), CalendarContent
was never rendered so its <section data-testid="…-container"> was
never mounted. The outer <div> also lacked the --calendar-width /
--calendar-height CSS variable overrides, causing MonthView cells
to fall back to the 0px defaults from Calendar.module.css.

- Add data-testid="${testId}-container" to outer <div> when children
  are present
- Spread --calendar-width / --calendar-height into the inline style
  only in the children path (Path A is unchanged)
- Add regression test asserting the testId is accessible in compound
  mode
customDays was initialised from CalendarProvider's initialCustomDays
but never updated when the prop changed after mount, causing the
CustomDaysView to silently render with a stale day count.

- Add SET_CUSTOM_DAYS to CALENDAR_ACTIONS, CalendarAction union,
  and calendarReducer (mirrors SET_VIEW / SET_DATE pattern)
- Add useEffect in CalendarContent to dispatch SET_CUSTOM_DAYS
  whenever props.customDays changes
- Test SET_CUSTOM_DAYS reducer updates state.customDays (3 → 5)
- Test Calendar rerender with new customDays keeps view mounted
- Expand eventsAreSorted JSDoc in CalendarProps and useEvents to explicitly
  state that unsorted input renders in the provided order (the library never
  re-sorts the array)
- Add regression test labelled K-03 that asserts input order is preserved
  when eventsAreSorted=true even when events are not chronologically sorted
- Expand CalendarEvent.endDate JSDoc to note that endDate < startDate causes
  silent filtering (negative-duration guard, C-TC3)
- Expand useEvents hook description to state the filter is intentional and
  events have no renderable duration
- Add regression test labelled C-TC3 asserting that filtered events are dropped
  silently with no console.warn emitted
- Correct isLoading and renderLoading JSDoc in CalendarProps: describe both
  paths (skeleton for empty events, overlay for non-empty events)
- Add data-testid="calendar-loading-overlay" to the overlay div so tests can
  assert its presence without coupling to CSS class names
- Add DI-3 regression test verifying overlay renders (not skeleton) when
  isLoading=true and events are present
Created CalendarErrorBoundary component to prevent the entire calendar from crashing
when custom renderers (renderHeader, etc.) throw. The boundary catches exceptions
and renders a fallback div instead of propagating the error up.

Added integration test verifying the error boundary catches renderer exceptions.
Added rollup-plugin-visualizer to analyze bundle size and composition.
Generates stats.html on every build showing gzip and brotli-compressed
sizes for each module.
feat: RTL support, color scheme/dark mode, error boundary, and bug fixes
@Jaganath-MSJ Jaganath-MSJ merged commit 14d0948 into beta May 9, 2026
5 checks passed
@github-actions

github-actions Bot commented May 9, 2026

Copy link
Copy Markdown

🎉 This PR is included in version 2.0.0-beta.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@github-actions

Copy link
Copy Markdown

🎉 This PR is included in version 2.0.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant