@innosolutions/inno-calendar 1.0.61 → 1.0.63
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.
- package/AGENT.md +1783 -1783
- package/README.md +305 -279
- package/dist/agenda-widget-BiZIpa3f.cjs +2 -0
- package/dist/agenda-widget-BiZIpa3f.cjs.map +1 -0
- package/dist/{agenda-widget-DVj4CEZE.js → agenda-widget-DbqQHhyM.js} +1515 -1494
- package/dist/agenda-widget-DbqQHhyM.js.map +1 -0
- package/dist/components/index.cjs +1 -1
- package/dist/components/index.mjs +1 -1
- package/dist/components/inno-calendar.d.ts +24 -0
- package/dist/components/inno-calendar.d.ts.map +1 -1
- package/dist/components/views/timeline-view.d.ts +12 -1
- package/dist/components/views/timeline-view.d.ts.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.mjs +201 -201
- package/dist/position-utils-BQpbtF6N.cjs.map +1 -1
- package/dist/position-utils-DMVQFywD.js.map +1 -1
- package/dist/slot-selection-context-CRstOosL.js.map +1 -1
- package/dist/slot-selection-context-DBCZI2Dn.cjs.map +1 -1
- package/dist/week-view-C1Vu2ErD.cjs.map +1 -1
- package/dist/week-view-DY167Wok.js.map +1 -1
- package/package.json +138 -138
- package/dist/agenda-widget-D6E-NQK-.cjs +0 -2
- package/dist/agenda-widget-D6E-NQK-.cjs.map +0 -1
- package/dist/agenda-widget-DVj4CEZE.js.map +0 -1
package/README.md
CHANGED
|
@@ -1,279 +1,305 @@
|
|
|
1
|
-
# @inno/calendar
|
|
2
|
-
|
|
3
|
-
A headless-first, fully customizable React calendar for enterprise applications.
|
|
4
|
-
|
|
5
|
-
[](https://www.npmjs.com/package/@innosolutions/inno-calendar)
|
|
6
|
-
[](https://www.typescriptlang.org/)
|
|
7
|
-
[](https://reactjs.org/)
|
|
8
|
-
|
|
9
|
-
> **🤖 AI Agents:** For comprehensive implementation details, copy the contents of [AGENT.md](./AGENT.md) into your context.
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install @innosolutions/inno-calendar
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
```bash
|
|
18
|
-
# Optional: Radix UI for enhanced popovers/tooltips
|
|
19
|
-
npm install @radix-ui/react-popover @radix-ui/react-tooltip @radix-ui/react-dropdown-menu
|
|
20
|
-
```
|
|
21
|
-
|
|
22
|
-
## Quick Start
|
|
23
|
-
|
|
24
|
-
```tsx
|
|
25
|
-
import { InnoCalendar, type CalendarEvent } from "@innosolutions/inno-calendar";
|
|
26
|
-
import "@innosolutions/inno-calendar/styles";
|
|
27
|
-
|
|
28
|
-
const events: CalendarEvent[] = [
|
|
29
|
-
{
|
|
30
|
-
id: "1",
|
|
31
|
-
title: "Team Meeting",
|
|
32
|
-
startDate: new Date("2026-02-04T09:00:00"),
|
|
33
|
-
endDate: new Date("2026-02-04T10:00:00"),
|
|
34
|
-
color: "blue",
|
|
35
|
-
},
|
|
36
|
-
];
|
|
37
|
-
|
|
38
|
-
function MyCalendar() {
|
|
39
|
-
return (
|
|
40
|
-
<InnoCalendar
|
|
41
|
-
events={events}
|
|
42
|
-
initialView="week"
|
|
43
|
-
onEventClick={(event) => console.log(event)}
|
|
44
|
-
onSlotSelect={(selection) =>
|
|
45
|
-
console.log(selection.startDate, selection.endDate)
|
|
46
|
-
}
|
|
47
|
-
/>
|
|
48
|
-
);
|
|
49
|
-
}
|
|
50
|
-
```
|
|
51
|
-
|
|
52
|
-
## Features
|
|
53
|
-
|
|
54
|
-
- **8 View Modes** — Day, Week, Month, Year, Agenda, Timeline (1/3/7 day)
|
|
55
|
-
- **Headless Architecture** — Use hooks directly or pre-built components
|
|
56
|
-
- **Drag & Drop** — Drag to select time ranges, drag events to reschedule
|
|
57
|
-
- **TypeScript** — Fully typed with generic event data support
|
|
58
|
-
- **Customizable** — Custom popovers, settings panels, filters
|
|
59
|
-
- **No External Dependencies** — Native Date API, minimal footprint
|
|
60
|
-
|
|
61
|
-
## Views
|
|
62
|
-
|
|
63
|
-
| View | Description |
|
|
64
|
-
| --------------- | -------------------------- |
|
|
65
|
-
| `day` | Single day hourly grid |
|
|
66
|
-
| `week` | 7-day grid with time slots |
|
|
67
|
-
| `month` | Monthly calendar |
|
|
68
|
-
| `year` | 12-month overview |
|
|
69
|
-
| `agenda` | Scrollable event list |
|
|
70
|
-
| `timeline-day` | Resource timeline (1 day) |
|
|
71
|
-
| `timeline-3day` | Resource timeline (3 days) |
|
|
72
|
-
| `timeline-week` | Resource timeline (7 days) |
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
| "
|
|
89
|
-
| "
|
|
90
|
-
| "
|
|
91
|
-
| "
|
|
92
|
-
| "
|
|
93
|
-
| "
|
|
94
|
-
| "
|
|
95
|
-
| "
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
<
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
//
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
/>
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
:
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
1
|
+
# @inno/calendar
|
|
2
|
+
|
|
3
|
+
A headless-first, fully customizable React calendar for enterprise applications.
|
|
4
|
+
|
|
5
|
+
[](https://www.npmjs.com/package/@innosolutions/inno-calendar)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://reactjs.org/)
|
|
8
|
+
|
|
9
|
+
> **🤖 AI Agents:** For comprehensive implementation details, copy the contents of [AGENT.md](./AGENT.md) into your context.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @innosolutions/inno-calendar
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
# Optional: Radix UI for enhanced popovers/tooltips
|
|
19
|
+
npm install @radix-ui/react-popover @radix-ui/react-tooltip @radix-ui/react-dropdown-menu
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
## Quick Start
|
|
23
|
+
|
|
24
|
+
```tsx
|
|
25
|
+
import { InnoCalendar, type CalendarEvent } from "@innosolutions/inno-calendar";
|
|
26
|
+
import "@innosolutions/inno-calendar/styles";
|
|
27
|
+
|
|
28
|
+
const events: CalendarEvent[] = [
|
|
29
|
+
{
|
|
30
|
+
id: "1",
|
|
31
|
+
title: "Team Meeting",
|
|
32
|
+
startDate: new Date("2026-02-04T09:00:00"),
|
|
33
|
+
endDate: new Date("2026-02-04T10:00:00"),
|
|
34
|
+
color: "blue",
|
|
35
|
+
},
|
|
36
|
+
];
|
|
37
|
+
|
|
38
|
+
function MyCalendar() {
|
|
39
|
+
return (
|
|
40
|
+
<InnoCalendar
|
|
41
|
+
events={events}
|
|
42
|
+
initialView="week"
|
|
43
|
+
onEventClick={(event) => console.log(event)}
|
|
44
|
+
onSlotSelect={(selection) =>
|
|
45
|
+
console.log(selection.startDate, selection.endDate)
|
|
46
|
+
}
|
|
47
|
+
/>
|
|
48
|
+
);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
## Features
|
|
53
|
+
|
|
54
|
+
- **8 View Modes** — Day, Week, Month, Year, Agenda, Timeline (1/3/7 day)
|
|
55
|
+
- **Headless Architecture** — Use hooks directly or pre-built components
|
|
56
|
+
- **Drag & Drop** — Drag to select time ranges, drag events to reschedule
|
|
57
|
+
- **TypeScript** — Fully typed with generic event data support
|
|
58
|
+
- **Customizable** — Custom popovers, settings panels, filters
|
|
59
|
+
- **No External Dependencies** — Native Date API, minimal footprint
|
|
60
|
+
|
|
61
|
+
## Views
|
|
62
|
+
|
|
63
|
+
| View | Description |
|
|
64
|
+
| --------------- | -------------------------- |
|
|
65
|
+
| `day` | Single day hourly grid |
|
|
66
|
+
| `week` | 7-day grid with time slots |
|
|
67
|
+
| `month` | Monthly calendar |
|
|
68
|
+
| `year` | 12-month overview |
|
|
69
|
+
| `agenda` | Scrollable event list |
|
|
70
|
+
| `timeline-day` | Resource timeline (1 day) |
|
|
71
|
+
| `timeline-3day` | Resource timeline (3 days) |
|
|
72
|
+
| `timeline-week` | Resource timeline (7 days) |
|
|
73
|
+
| `resource-day` | Resource view (1 day) |
|
|
74
|
+
| `resource-week` | Resource view (7 days) |
|
|
75
|
+
|
|
76
|
+
## Event Structure
|
|
77
|
+
|
|
78
|
+
```tsx
|
|
79
|
+
interface CalendarEvent<TData = Record<string, unknown>> {
|
|
80
|
+
// Required
|
|
81
|
+
id: string;
|
|
82
|
+
title: ReactNode; // String or JSX
|
|
83
|
+
startDate: Date;
|
|
84
|
+
endDate: Date;
|
|
85
|
+
|
|
86
|
+
// Optional display fields
|
|
87
|
+
color?:
|
|
88
|
+
| "blue"
|
|
89
|
+
| "green"
|
|
90
|
+
| "red"
|
|
91
|
+
| "yellow"
|
|
92
|
+
| "purple"
|
|
93
|
+
| "orange"
|
|
94
|
+
| "pink"
|
|
95
|
+
| "teal"
|
|
96
|
+
| "gray"
|
|
97
|
+
| "indigo";
|
|
98
|
+
hexColor?: string; // Hex override (takes precedence over color)
|
|
99
|
+
description?: ReactNode; // String or JSX
|
|
100
|
+
isCanceled?: boolean;
|
|
101
|
+
isAllDay?: boolean;
|
|
102
|
+
isMultiDay?: boolean;
|
|
103
|
+
isRecurring?: boolean;
|
|
104
|
+
resourceId?: string; // For resource/timeline views
|
|
105
|
+
|
|
106
|
+
// Built-in filtering (optional — skip if you filter server-side)
|
|
107
|
+
scheduleTypeId?: number;
|
|
108
|
+
scheduleTypeName?: ReactNode; // String or JSX
|
|
109
|
+
participants?: ICalendarUser[];
|
|
110
|
+
|
|
111
|
+
// @deprecated — still functional, but migrate to `data` bag.
|
|
112
|
+
// Will be removed in the next major version.
|
|
113
|
+
meetingTookPlace?: boolean; // → data.meetingTookPlace
|
|
114
|
+
isAccepted?: boolean; // → data.isAccepted
|
|
115
|
+
companyId?: number; // → data.companyId
|
|
116
|
+
cancelReason?: string | null; // → data.cancelReason
|
|
117
|
+
user?: ICalendarUser; // → data.user
|
|
118
|
+
// ... and others (see types.ts for full list)
|
|
119
|
+
|
|
120
|
+
data?: TData; // Your custom domain-specific fields (RECOMMENDED)
|
|
121
|
+
}
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### ReactNode Props
|
|
125
|
+
|
|
126
|
+
`title`, `description`, and `scheduleTypeName` accept `ReactNode` — you can pass plain strings (fully backwards compatible) or custom JSX:
|
|
127
|
+
|
|
128
|
+
```tsx
|
|
129
|
+
const event: CalendarEvent = {
|
|
130
|
+
id: "1",
|
|
131
|
+
title: <span><UserIcon className="h-3 w-3 inline" /> John Doe</span>,
|
|
132
|
+
description: <p className="italic">VIP client meeting</p>,
|
|
133
|
+
startDate: new Date(),
|
|
134
|
+
endDate: new Date(),
|
|
135
|
+
};
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
The built-in search and `aria-label` automatically extract plain text from JSX nodes via the `reactNodeToText` utility.
|
|
139
|
+
|
|
140
|
+
### Extended Props (data.extendedProps)
|
|
141
|
+
|
|
142
|
+
For rendering an arbitrary number of custom lines on EventCard/EventBlock, use the `extendedProps` array in the `data` bag:
|
|
143
|
+
|
|
144
|
+
```tsx
|
|
145
|
+
const event: CalendarEvent = {
|
|
146
|
+
id: "1",
|
|
147
|
+
title: "Practical Course",
|
|
148
|
+
startDate: new Date(),
|
|
149
|
+
endDate: new Date(),
|
|
150
|
+
data: {
|
|
151
|
+
extendedProps: [
|
|
152
|
+
<p key="student" className="font-medium">Student: Jane Doe</p>,
|
|
153
|
+
<p key="phone">Phone: +32 123 456 789</p>,
|
|
154
|
+
<div key="info" className="flex items-center gap-1">
|
|
155
|
+
<CarIcon className="h-3 w-3" />
|
|
156
|
+
<span>Automatic transmission</span>
|
|
157
|
+
</div>,
|
|
158
|
+
],
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Each entry renders as its own row. Visible on EventCard (full variant) and EventBlock (events >= 45min). Also shown in tooltips.
|
|
164
|
+
|
|
165
|
+
## Props
|
|
166
|
+
|
|
167
|
+
```tsx
|
|
168
|
+
<InnoCalendar
|
|
169
|
+
// Data
|
|
170
|
+
events={events}
|
|
171
|
+
users={users}
|
|
172
|
+
alwaysShowResources={alwaysShowResources}
|
|
173
|
+
scheduleTypes={scheduleTypes}
|
|
174
|
+
// Initial State
|
|
175
|
+
initialView="week"
|
|
176
|
+
initialDate={new Date()}
|
|
177
|
+
// Callbacks
|
|
178
|
+
onEventClick={(event) => {}}
|
|
179
|
+
onSlotSelect={(selection) => {}}
|
|
180
|
+
onSlotClick={(date, hour) => {}}
|
|
181
|
+
onAddEvent={() => {}}
|
|
182
|
+
onEventDrop={(result) => {}}
|
|
183
|
+
onDateChange={(date, view) => {}}
|
|
184
|
+
onViewChange={(view) => {}}
|
|
185
|
+
// Customization
|
|
186
|
+
renderPopover={({ event, onClose }) => <CustomPopover />}
|
|
187
|
+
settingsContent={<SettingsPanel />}
|
|
188
|
+
filterContent={<FiltersRow />}
|
|
189
|
+
showHeader={true}
|
|
190
|
+
/>
|
|
191
|
+
```
|
|
192
|
+
|
|
193
|
+
## Provider Pattern
|
|
194
|
+
|
|
195
|
+
For shared state across components:
|
|
196
|
+
|
|
197
|
+
```tsx
|
|
198
|
+
import {
|
|
199
|
+
InnoCalendarProvider,
|
|
200
|
+
useInnoCalendar,
|
|
201
|
+
CalendarHeader,
|
|
202
|
+
WeekView,
|
|
203
|
+
} from "@innosolutions/inno-calendar";
|
|
204
|
+
|
|
205
|
+
function App() {
|
|
206
|
+
return (
|
|
207
|
+
<InnoCalendarProvider initialEvents={events} initialView="week">
|
|
208
|
+
<CalendarContent />
|
|
209
|
+
</InnoCalendarProvider>
|
|
210
|
+
);
|
|
211
|
+
}
|
|
212
|
+
|
|
213
|
+
function CalendarContent() {
|
|
214
|
+
const { view, filteredEvents, selectedDate } = useInnoCalendar();
|
|
215
|
+
return (
|
|
216
|
+
<>
|
|
217
|
+
<CalendarHeader />
|
|
218
|
+
<WeekView events={filteredEvents} date={selectedDate} />
|
|
219
|
+
</>
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
## Resource Views
|
|
225
|
+
|
|
226
|
+
The resource views (`resource-day`, `resource-week`) group events by resource and render one row per resource.
|
|
227
|
+
|
|
228
|
+
**Default flow** — resource rows are derived from the events: each unique resource referenced by an event (via `event.resourceId`, `event.data.user`, `event.user`, or `event.participants`) gets its own row. Resources without events are not shown.
|
|
229
|
+
|
|
230
|
+
**Always-show resources** — pass `alwaysShowResources` to guarantee a row for a resource even when it has no events in the current data. Rows without events appear at the bottom so event-containing rows keep visual priority. If a resource listed here also has events, its row is positioned naturally among the event rows and the events are still attached to it.
|
|
231
|
+
|
|
232
|
+
```tsx
|
|
233
|
+
<InnoCalendar
|
|
234
|
+
events={events}
|
|
235
|
+
initialView="resource-week"
|
|
236
|
+
alwaysShowResources={[
|
|
237
|
+
{ id: "room-1", name: "Meeting Room A", avatar: "/rooms/a.jpg" },
|
|
238
|
+
{ id: "room-2", name: "Meeting Room B" },
|
|
239
|
+
]}
|
|
240
|
+
/>
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Each entry accepts the full `ICalendarUser` shape — at minimum `id` and `name` are needed to render the row header; `avatar` and `email` are optional. Updating the array re-renders the resource view immediately.
|
|
244
|
+
|
|
245
|
+
This prop is scoped to the resource views only — it is ignored in `timeline-*` and all other views.
|
|
246
|
+
|
|
247
|
+
## Working Hours
|
|
248
|
+
|
|
249
|
+
```tsx
|
|
250
|
+
const workingHours = {
|
|
251
|
+
0: { enabled: false, from: 8, to: 17 }, // Sunday
|
|
252
|
+
1: { enabled: true, from: 9, to: 18 }, // Monday
|
|
253
|
+
2: { enabled: true, from: 9, to: 18 }, // Tuesday
|
|
254
|
+
3: { enabled: true, from: 9, to: 18 }, // Wednesday
|
|
255
|
+
4: { enabled: true, from: 9, to: 18 }, // Thursday
|
|
256
|
+
5: { enabled: true, from: 9, to: 17 }, // Friday
|
|
257
|
+
6: { enabled: false, from: 8, to: 12 }, // Saturday
|
|
258
|
+
};
|
|
259
|
+
|
|
260
|
+
<InnoCalendar
|
|
261
|
+
events={events}
|
|
262
|
+
preferencesConfig={{
|
|
263
|
+
defaults: { workingHours },
|
|
264
|
+
}}
|
|
265
|
+
/>;
|
|
266
|
+
```
|
|
267
|
+
|
|
268
|
+
## Styles
|
|
269
|
+
|
|
270
|
+
Import the bundled styles for proper rendering:
|
|
271
|
+
|
|
272
|
+
```tsx
|
|
273
|
+
import "@innosolutions/inno-calendar/styles";
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
Or include CSS custom properties for theming:
|
|
277
|
+
|
|
278
|
+
```css
|
|
279
|
+
:root {
|
|
280
|
+
--inno-border-color: #e5e7eb;
|
|
281
|
+
--inno-primary: #3b82f6;
|
|
282
|
+
--inno-hour-height: 96px;
|
|
283
|
+
}
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
## TypeScript
|
|
287
|
+
|
|
288
|
+
```tsx
|
|
289
|
+
import type {
|
|
290
|
+
CalendarEvent,
|
|
291
|
+
TCalendarView,
|
|
292
|
+
TEventColor,
|
|
293
|
+
ICalendarUser,
|
|
294
|
+
IScheduleType,
|
|
295
|
+
ISelectionResult,
|
|
296
|
+
TWorkingHours,
|
|
297
|
+
} from "@innosolutions/inno-calendar";
|
|
298
|
+
|
|
299
|
+
// Utility: extract plain text from any ReactNode (for search, labels, etc.)
|
|
300
|
+
import { reactNodeToText } from "@innosolutions/inno-calendar";
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
## License
|
|
304
|
+
|
|
305
|
+
MIT © [InnoSolutions](https://github.com/innosolutions)
|