@neo-reckoning/react 0.1.0-alpha.1 → 0.1.0-alpha.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/README.md +175 -0
  2. package/package.json +2 -2
package/README.md ADDED
@@ -0,0 +1,175 @@
1
+ # @neo-reckoning/react
2
+
3
+ Headless React hooks for calendar state management. Built on [@neo-reckoning/core](https://www.npmjs.com/package/@neo-reckoning/core).
4
+
5
+ All hooks return data structures — no DOM, no components, no CSS. You bring the rendering.
6
+
7
+ ## Install
8
+
9
+ ```
10
+ npm install @neo-reckoning/react @neo-reckoning/core
11
+ ```
12
+
13
+ React 18+ is a peer dependency.
14
+
15
+ ## Hooks
16
+
17
+ ### `useCalendar`
18
+
19
+ Calendar grid with navigation. The primary hook for month/week views.
20
+
21
+ ```typescript
22
+ import { useCalendar } from '@neo-reckoning/react';
23
+
24
+ const { months, next, prev, goTo, focusDate } = useCalendar({
25
+ focusDate: '2026-03-15',
26
+ numberOfMonths: 1,
27
+ ranges: myRanges,
28
+ fidelity: 'month', // 'year' | 'month' | 'week' | 'day'
29
+ weekStartsOn: 1, // Monday
30
+ userTimezone: 'America/New_York',
31
+ });
32
+
33
+ // months[0].weeks[0].days[0].ranges → DayRangeInfo[]
34
+ ```
35
+
36
+ ### `useCalendarEvents`
37
+
38
+ Merges native DateRanges and imported calendar events into a single sorted `CalendarEvent[]`.
39
+
40
+ ```typescript
41
+ import { useCalendarEvents } from '@neo-reckoning/react';
42
+
43
+ const events = useCalendarEvents({
44
+ ranges: myRanges,
45
+ importedEvents: icsEvents, // from @neo-reckoning/ical
46
+ from: windowStart,
47
+ to: windowEnd,
48
+ userTimezone: 'America/New_York',
49
+ });
50
+ ```
51
+
52
+ ### `useTimeline`
53
+
54
+ Timeline data for day views with positioned events and overlap detection.
55
+
56
+ ```typescript
57
+ import { useTimeline } from '@neo-reckoning/react';
58
+
59
+ const { slots } = useTimeline({
60
+ date: '2026-03-23',
61
+ events: dayEvents,
62
+ startHour: 8,
63
+ endHour: 18,
64
+ intervalMinutes: 30,
65
+ });
66
+
67
+ // slots[0].events[0] → { event, top, height, column, totalColumns }
68
+ ```
69
+
70
+ ### `useSpans`
71
+
72
+ Span-level overlap detection with lane assignment for consistent multi-day bar rendering.
73
+
74
+ ```typescript
75
+ import { useSpans } from '@neo-reckoning/react';
76
+
77
+ const spans = useSpans({
78
+ ranges: myRanges,
79
+ from: windowStart,
80
+ to: windowEnd,
81
+ });
82
+
83
+ // spans[0] → { rangeId, startDate, endDate, lane, totalLanes, maxOverlap }
84
+ ```
85
+
86
+ ### `useDayDetail`
87
+
88
+ Time slots and all-day range info for a specific day.
89
+
90
+ ```typescript
91
+ import { useDayDetail } from '@neo-reckoning/react';
92
+
93
+ const { timeSlots, allDayRanges } = useDayDetail(
94
+ '2026-03-23',
95
+ myRanges,
96
+ 'America/New_York',
97
+ );
98
+ ```
99
+
100
+ ### `useRangeCheck`
101
+
102
+ Range evaluation — check which ranges a datetime falls within.
103
+
104
+ ```typescript
105
+ import { useRangeCheck } from '@neo-reckoning/react';
106
+
107
+ const { isInRange, getOccurrences } = useRangeCheck(myRanges, 'America/New_York');
108
+
109
+ const matchingRanges = isInRange(new Date());
110
+ const occurrences = getOccurrences(from, to);
111
+ ```
112
+
113
+ ### `useConflicts`
114
+
115
+ Find scheduling conflicts across a date window.
116
+
117
+ ```typescript
118
+ import { useConflicts } from '@neo-reckoning/react';
119
+
120
+ const conflicts = useConflicts({
121
+ ranges: myRanges,
122
+ from: windowStart,
123
+ to: windowEnd,
124
+ });
125
+
126
+ // conflicts[0] → { rangeA, rangeB, date, overlapStart, overlapEnd }
127
+ ```
128
+
129
+ ### `useFreeSlots`
130
+
131
+ Find available time on a given day.
132
+
133
+ ```typescript
134
+ import { useFreeSlots } from '@neo-reckoning/react';
135
+
136
+ const freeSlots = useFreeSlots({
137
+ ranges: myRanges,
138
+ date: '2026-03-23',
139
+ minDuration: 30,
140
+ dayStart: '09:00',
141
+ dayEnd: '17:00',
142
+ });
143
+
144
+ // freeSlots[0] → { date, startTime, endTime, duration }
145
+ ```
146
+
147
+ ### `useScheduleScore`
148
+
149
+ Schedule quality metrics for evaluating arrangements.
150
+
151
+ ```typescript
152
+ import { useScheduleScore } from '@neo-reckoning/react';
153
+
154
+ const score = useScheduleScore({
155
+ ranges: myRanges,
156
+ from: windowStart,
157
+ to: windowEnd,
158
+ focusBlockMinutes: 60,
159
+ dayStart: '09:00',
160
+ dayEnd: '17:00',
161
+ });
162
+
163
+ // score → { conflicts, freeMinutes, focusBlocks, avgContextSwitches, conflictDays }
164
+ ```
165
+
166
+ ## Design philosophy
167
+
168
+ - **Headless** — returns data, not DOM. Works with any component library or React Native.
169
+ - **No styling** — range IDs, not colors. Your app maps IDs to palettes.
170
+ - **Memoized** — all hooks use `useMemo` for efficient re-renders.
171
+ - **Framework-agnostic core** — all computation lives in `@neo-reckoning/core`. These hooks are thin wrappers.
172
+
173
+ ## License
174
+
175
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@neo-reckoning/react",
3
- "version": "0.1.0-alpha.1",
3
+ "version": "0.1.0-alpha.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -29,7 +29,7 @@
29
29
  },
30
30
  "repository": {
31
31
  "type": "git",
32
- "url": "https://github.com/sdougbrown/neo-reckoning.git",
32
+ "url": "git+https://github.com/sdougbrown/neo-reckoning.git",
33
33
  "directory": "packages/react"
34
34
  },
35
35
  "publishConfig": {