@chronux/react
v0.1.1
Published
Headless React hooks and providers for the Chronux platform
Maintainers
Readme
@chronux/react
Headless React hooks and providers for the Chronux calendar platform. This library provides all the state management and logic you need to build custom calendar UIs.
Installation
npm install @chronux/react @chronux/coreUsage
Basic Setup
import {
CalendarProvider,
useCalendar,
useCalendarState,
} from '@chronux/react';
function App() {
const options = {
events: [
{
id: '1',
start: new Date('2024-01-15T10:00:00'),
end: new Date('2024-01-15T11:00:00'),
data: { title: 'Meeting' },
},
],
};
return (
<CalendarProvider options={options}>
<CustomCalendar />
</CalendarProvider>
);
}
function CustomCalendar() {
const calendar = useCalendar();
const state = useCalendarState();
return (
<div>
<div>
<button onClick={() => calendar.previous()}>Previous</button>
<button onClick={() => calendar.next()}>Next</button>
<button onClick={() => calendar.today()}>Today</button>
</div>
<div>{state.currentDate.toDateString()}</div>
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)' }}>
{calendar
.getCells()
.map((row, rowIndex) =>
row.map((cell, colIndex) => (
<div key={`${rowIndex}-${colIndex}`}>{cell.date.getDate()}</div>
))
)}
</div>
</div>
);
}Using Individual Hooks
import {
useCalendar,
useCalendarState,
useCalendarEvents,
useCalendarSelection,
useCalendarView,
useCalendarActions,
useCalendarData,
useCalendarSubscription,
useCalendarSelector,
} from '@chronux/react';
function CalendarControls() {
const calendar = useCalendar();
const state = useCalendarState();
const events = useCalendarEvents();
const selection = useCalendarSelection();
const view = useCalendarView();
const actions = useCalendarActions();
const data = useCalendarData();
return (
<div>
<button onClick={actions.previous}>Previous</button>
<button onClick={actions.next}>Next</button>
<button onClick={actions.today}>Today</button>
<p>Current date: {state.currentDate.toDateString()}</p>
<p>View: {view.id}</p>
<p>Events: {events.length}</p>
<p>Selected dates: {selection.length}</p>
<p>Today's events: {data.todayEvents.length}</p>
</div>
);
}
function OptimizedComponent() {
const currentDate = useCalendarSelector(state => state.currentDate);
const eventCount = useCalendarSelector(state => state.events.length);
return (
<div>
<p>Date: {currentDate.toDateString()}</p>
<p>Events: {eventCount}</p>
</div>
);
}Custom Calendar Instance
import { useCalendarInstance } from '@chronux/react';
function CustomCalendarInstance() {
const calendar = useCalendarInstance({
events: [],
defaultView: 'month',
});
return (
<div>
<button onClick={() => calendar.next()}>Next</button>
<p>State: {JSON.stringify(calendar.getState())}</p>
</div>
);
}API Reference
CalendarProvider
Provides the calendar context to child components.
Props:
options: Calendar configuration optionscalendar: Optional external calendar instancechildren: React children
Hooks
useCalendar()
Returns the calendar instance with all methods and APIs.
const calendar = useCalendar();
calendar.next();
calendar.previous();
calendar.today();
calendar.setView('week');useCalendarState()
Returns the current calendar state.
const state = useCalendarState();
// state.currentDate, state.events, state.selection, etc.useCalendarEvents()
Returns the current calendar events.
const events = useCalendarEvents();useCalendarSelection()
Returns the current selection.
const selection = useCalendarSelection();useCalendarView()
Returns the current view configuration.
const view = useCalendarView();useCalendarInstance(options)
Creates a standalone calendar instance without context.
const calendar = useCalendarInstance({
events: [],
defaultView: 'month',
});useCalendarActions()
Returns memoized calendar actions for better performance.
const actions = useCalendarActions();
actions.next();
actions.previous();
actions.selectDate(new Date());useCalendarData()
Returns derived calendar data for the current view.
const data = useCalendarData();
// data.cells, data.rowModel, data.headerGroups, data.eventsForCurrentView, etc.useCalendarSubscription()
Subscribes to the entire calendar state. Use this when you need access to the full state.
const state = useCalendarSubscription();
// Full calendar stateuseCalendarSelector(selector)
Subscribes to specific parts of the calendar state for optimal performance.
const currentDate = useCalendarSelector(state => state.currentDate);
const eventCount = useCalendarSelector(state => state.events.length);
const selectedDates = useCalendarSelector(state => state.selection);Performance Optimization
The library is designed for optimal performance:
- Selective Subscriptions: Use
useCalendarSelectorto subscribe only to the state you need - Memoized Actions:
useCalendarActionsprovides memoized callbacks - No Provider Re-renders: The provider doesn't manage state, components handle their own subscriptions
Building Custom UIs
Since this is a headless library, you have complete control over the UI. Here are some examples:
Custom Grid Layout
function CustomGrid() {
const calendar = useCalendar();
const cells = calendar.getCells();
return (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(7, 1fr)' }}>
{cells.map((row, rowIndex) =>
row.map((cell, colIndex) => (
<div
key={`${rowIndex}-${colIndex}`}
onClick={() => calendar.selectDate(cell.date)}
style={{
padding: '8px',
border: '1px solid #ccc',
backgroundColor: cell.isSelected ? '#e3f2fd' : 'white',
}}
>
{cell.date.getDate()}
{cell.events.map(event => (
<div key={event.id} style={{ fontSize: '12px', color: 'blue' }}>
{event.id}
</div>
))}
</div>
))
)}
</div>
);
}Custom Navigation
function CustomNavigation() {
const calendar = useCalendar();
const state = useCalendarState();
return (
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
<button onClick={() => calendar.previous()}>←</button>
<span>{state.currentDate.toLocaleDateString()}</span>
<button onClick={() => calendar.next()}>→</button>
<button onClick={() => calendar.today()}>Today</button>
</div>
);
}License
MIT
