@hectorbliss/denik-calendar 0.0.2 → 0.0.3
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/README.md +54 -0
- package/dist/index.cjs +34 -14
- package/dist/index.d.cts +32 -1
- package/dist/index.d.ts +32 -1
- package/dist/index.js +34 -14
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,7 +111,60 @@ interface CalendarConfig {
|
|
|
111
111
|
edit?: ReactNode;
|
|
112
112
|
close?: ReactNode;
|
|
113
113
|
};
|
|
114
|
+
renderColumnHeader?: (props: ColumnHeaderProps) => ReactNode;
|
|
114
115
|
}
|
|
116
|
+
|
|
117
|
+
interface ColumnHeaderProps {
|
|
118
|
+
date: Date;
|
|
119
|
+
index: number;
|
|
120
|
+
isToday: boolean;
|
|
121
|
+
locale: string;
|
|
122
|
+
}
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Custom Column Headers
|
|
126
|
+
|
|
127
|
+
Transform the calendar from weekdays to any resource type:
|
|
128
|
+
|
|
129
|
+
```tsx
|
|
130
|
+
// Padel courts booking
|
|
131
|
+
<Calendar
|
|
132
|
+
events={courtEvents}
|
|
133
|
+
config={{
|
|
134
|
+
renderColumnHeader: ({ index }) => (
|
|
135
|
+
<div className="text-center font-semibold">
|
|
136
|
+
Court {index + 1}
|
|
137
|
+
</div>
|
|
138
|
+
)
|
|
139
|
+
}}
|
|
140
|
+
/>
|
|
141
|
+
|
|
142
|
+
// Meeting rooms
|
|
143
|
+
<Calendar
|
|
144
|
+
events={roomEvents}
|
|
145
|
+
config={{
|
|
146
|
+
renderColumnHeader: ({ index }) => {
|
|
147
|
+
const rooms = ["Sala A", "Sala B", "Sala C", "Sala D", "Sala E", "Sala F", "Sala G"];
|
|
148
|
+
return <span>{rooms[index]}</span>;
|
|
149
|
+
}
|
|
150
|
+
}}
|
|
151
|
+
/>
|
|
152
|
+
|
|
153
|
+
// Employees schedule
|
|
154
|
+
<Calendar
|
|
155
|
+
events={shifts}
|
|
156
|
+
config={{
|
|
157
|
+
renderColumnHeader: ({ index }) => {
|
|
158
|
+
const team = ["Ana", "Carlos", "María", "Pedro", "Laura", "Diego", "Sofia"];
|
|
159
|
+
return (
|
|
160
|
+
<div className="flex flex-col items-center">
|
|
161
|
+
<img src={`/avatars/${index}.jpg`} className="w-8 h-8 rounded-full" />
|
|
162
|
+
<span className="text-sm">{team[index]}</span>
|
|
163
|
+
</div>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
}}
|
|
167
|
+
/>
|
|
115
168
|
```
|
|
116
169
|
|
|
117
170
|
## Features
|
|
@@ -121,6 +174,7 @@ interface CalendarConfig {
|
|
|
121
174
|
- Block time slots
|
|
122
175
|
- Week navigation
|
|
123
176
|
- Auto-scroll to current hour
|
|
177
|
+
- Custom column headers (resources, courts, rooms, employees)
|
|
124
178
|
- Customizable icons
|
|
125
179
|
- Locale support
|
|
126
180
|
- TypeScript support
|
package/dist/index.cjs
CHANGED
|
@@ -217,18 +217,29 @@ var cn = (...classes) => classes.filter(Boolean).join(" ");
|
|
|
217
217
|
var DefaultTrashIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "w-4 h-4", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" }) });
|
|
218
218
|
var DefaultEditIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "w-4 h-4", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" }) });
|
|
219
219
|
var DefaultCloseIcon = () => /* @__PURE__ */ jsxRuntime.jsx("svg", { viewBox: "0 0 24 24", className: "w-4 h-4", fill: "currentColor", children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) });
|
|
220
|
-
var DayHeader = ({
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
220
|
+
var DayHeader = ({
|
|
221
|
+
date,
|
|
222
|
+
locale,
|
|
223
|
+
index,
|
|
224
|
+
renderColumnHeader
|
|
225
|
+
}) => {
|
|
226
|
+
const isToday2 = isToday(date);
|
|
227
|
+
if (renderColumnHeader) {
|
|
228
|
+
return /* @__PURE__ */ jsxRuntime.jsx("div", { className: "grid place-items-center", children: renderColumnHeader({ date, index, isToday: isToday2, locale }) });
|
|
229
|
+
}
|
|
230
|
+
return /* @__PURE__ */ jsxRuntime.jsxs("p", { className: "grid place-items-center", children: [
|
|
231
|
+
/* @__PURE__ */ jsxRuntime.jsx("span", { className: "capitalize", children: date.toLocaleDateString(locale, { weekday: "short" }) }),
|
|
232
|
+
/* @__PURE__ */ jsxRuntime.jsx(
|
|
233
|
+
"span",
|
|
234
|
+
{
|
|
235
|
+
className: cn(
|
|
236
|
+
isToday2 && "bg-blue-500 rounded-full p-1 text-white"
|
|
237
|
+
),
|
|
238
|
+
children: date.getDate()
|
|
239
|
+
}
|
|
240
|
+
)
|
|
241
|
+
] });
|
|
242
|
+
};
|
|
232
243
|
function Calendar({
|
|
233
244
|
date = /* @__PURE__ */ new Date(),
|
|
234
245
|
events = [],
|
|
@@ -239,7 +250,7 @@ function Calendar({
|
|
|
239
250
|
onRemoveBlock,
|
|
240
251
|
config = {}
|
|
241
252
|
}) {
|
|
242
|
-
const { locale = "es-MX", icons = {} } = config;
|
|
253
|
+
const { locale = "es-MX", icons = {}, renderColumnHeader } = config;
|
|
243
254
|
const week = completeWeek(date);
|
|
244
255
|
const [activeId, setActiveId] = react.useState(null);
|
|
245
256
|
const { canMove } = useCalendarEvents(events);
|
|
@@ -291,7 +302,16 @@ function Calendar({
|
|
|
291
302
|
/* @__PURE__ */ jsxRuntime.jsxs("article", { className: "w-full bg-white shadow rounded-xl", children: [
|
|
292
303
|
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "grid grid-cols-8 place-items-center py-4", children: [
|
|
293
304
|
/* @__PURE__ */ jsxRuntime.jsx("p", { children: /* @__PURE__ */ jsxRuntime.jsx("span", { className: "text-sm text-gray-500", children: Intl.DateTimeFormat().resolvedOptions().timeZone }) }),
|
|
294
|
-
week.map((day) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
305
|
+
week.map((day, index) => /* @__PURE__ */ jsxRuntime.jsx(
|
|
306
|
+
DayHeader,
|
|
307
|
+
{
|
|
308
|
+
date: day,
|
|
309
|
+
locale,
|
|
310
|
+
index,
|
|
311
|
+
renderColumnHeader
|
|
312
|
+
},
|
|
313
|
+
day.toISOString()
|
|
314
|
+
))
|
|
295
315
|
] }),
|
|
296
316
|
/* @__PURE__ */ jsxRuntime.jsxs("section", { className: "grid grid-cols-8 max-h-[80vh] overflow-y-auto", children: [
|
|
297
317
|
/* @__PURE__ */ jsxRuntime.jsx(TimeColumn, {}),
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode, RefObject } from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Props passed to custom column header renderer
|
|
6
|
+
* Use this to build custom headers for resources (courts, rooms, employees, etc.)
|
|
7
|
+
*/
|
|
8
|
+
interface ColumnHeaderProps {
|
|
9
|
+
/** The date for this column */
|
|
10
|
+
date: Date;
|
|
11
|
+
/** Column index (0-6) */
|
|
12
|
+
index: number;
|
|
13
|
+
/** Whether this column represents today */
|
|
14
|
+
isToday: boolean;
|
|
15
|
+
/** The configured locale */
|
|
16
|
+
locale: string;
|
|
17
|
+
}
|
|
4
18
|
/**
|
|
5
19
|
* Generic calendar event - decoupled from any ORM
|
|
6
20
|
*/
|
|
@@ -30,6 +44,23 @@ interface CalendarConfig {
|
|
|
30
44
|
edit?: ReactNode;
|
|
31
45
|
close?: ReactNode;
|
|
32
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Custom renderer for column headers.
|
|
49
|
+
* Use this to display resources (courts, rooms, employees) instead of weekdays.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // Padel courts
|
|
53
|
+
* renderColumnHeader: ({ index }) => <span>Court {index + 1}</span>
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // With custom styling
|
|
57
|
+
* renderColumnHeader: ({ date, isToday }) => (
|
|
58
|
+
* <div className={isToday ? "font-bold" : ""}>
|
|
59
|
+
* {date.toLocaleDateString("en", { weekday: "short" })}
|
|
60
|
+
* </div>
|
|
61
|
+
* )
|
|
62
|
+
*/
|
|
63
|
+
renderColumnHeader?: (props: ColumnHeaderProps) => ReactNode;
|
|
33
64
|
}
|
|
34
65
|
/**
|
|
35
66
|
* Calendar component props
|
|
@@ -128,4 +159,4 @@ declare function useClickOutside<T extends HTMLElement>({ isActive, onOutsideCli
|
|
|
128
159
|
*/
|
|
129
160
|
declare function formatDate(date: Date, locale?: string): string;
|
|
130
161
|
|
|
131
|
-
export { Calendar, type CalendarConfig, type CalendarEvent, type CalendarProps, Calendar as SimpleBigWeekView, addDaysToDate, addMinutesToDate, areSameDates, completeWeek, formatDate, fromDateToTimeString, fromMinsToLocaleTimeString, fromMinsToTimeString, generateHours, getDaysInMonth, getMonday, isToday, useCalendarEvents, useClickOutside, useEventOverlap };
|
|
162
|
+
export { Calendar, type CalendarConfig, type CalendarEvent, type CalendarProps, type ColumnHeaderProps, Calendar as SimpleBigWeekView, addDaysToDate, addMinutesToDate, areSameDates, completeWeek, formatDate, fromDateToTimeString, fromMinsToLocaleTimeString, fromMinsToTimeString, generateHours, getDaysInMonth, getMonday, isToday, useCalendarEvents, useClickOutside, useEventOverlap };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
2
|
import { ReactNode, RefObject } from 'react';
|
|
3
3
|
|
|
4
|
+
/**
|
|
5
|
+
* Props passed to custom column header renderer
|
|
6
|
+
* Use this to build custom headers for resources (courts, rooms, employees, etc.)
|
|
7
|
+
*/
|
|
8
|
+
interface ColumnHeaderProps {
|
|
9
|
+
/** The date for this column */
|
|
10
|
+
date: Date;
|
|
11
|
+
/** Column index (0-6) */
|
|
12
|
+
index: number;
|
|
13
|
+
/** Whether this column represents today */
|
|
14
|
+
isToday: boolean;
|
|
15
|
+
/** The configured locale */
|
|
16
|
+
locale: string;
|
|
17
|
+
}
|
|
4
18
|
/**
|
|
5
19
|
* Generic calendar event - decoupled from any ORM
|
|
6
20
|
*/
|
|
@@ -30,6 +44,23 @@ interface CalendarConfig {
|
|
|
30
44
|
edit?: ReactNode;
|
|
31
45
|
close?: ReactNode;
|
|
32
46
|
};
|
|
47
|
+
/**
|
|
48
|
+
* Custom renderer for column headers.
|
|
49
|
+
* Use this to display resources (courts, rooms, employees) instead of weekdays.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* // Padel courts
|
|
53
|
+
* renderColumnHeader: ({ index }) => <span>Court {index + 1}</span>
|
|
54
|
+
*
|
|
55
|
+
* @example
|
|
56
|
+
* // With custom styling
|
|
57
|
+
* renderColumnHeader: ({ date, isToday }) => (
|
|
58
|
+
* <div className={isToday ? "font-bold" : ""}>
|
|
59
|
+
* {date.toLocaleDateString("en", { weekday: "short" })}
|
|
60
|
+
* </div>
|
|
61
|
+
* )
|
|
62
|
+
*/
|
|
63
|
+
renderColumnHeader?: (props: ColumnHeaderProps) => ReactNode;
|
|
33
64
|
}
|
|
34
65
|
/**
|
|
35
66
|
* Calendar component props
|
|
@@ -128,4 +159,4 @@ declare function useClickOutside<T extends HTMLElement>({ isActive, onOutsideCli
|
|
|
128
159
|
*/
|
|
129
160
|
declare function formatDate(date: Date, locale?: string): string;
|
|
130
161
|
|
|
131
|
-
export { Calendar, type CalendarConfig, type CalendarEvent, type CalendarProps, Calendar as SimpleBigWeekView, addDaysToDate, addMinutesToDate, areSameDates, completeWeek, formatDate, fromDateToTimeString, fromMinsToLocaleTimeString, fromMinsToTimeString, generateHours, getDaysInMonth, getMonday, isToday, useCalendarEvents, useClickOutside, useEventOverlap };
|
|
162
|
+
export { Calendar, type CalendarConfig, type CalendarEvent, type CalendarProps, type ColumnHeaderProps, Calendar as SimpleBigWeekView, addDaysToDate, addMinutesToDate, areSameDates, completeWeek, formatDate, fromDateToTimeString, fromMinsToLocaleTimeString, fromMinsToTimeString, generateHours, getDaysInMonth, getMonday, isToday, useCalendarEvents, useClickOutside, useEventOverlap };
|
package/dist/index.js
CHANGED
|
@@ -215,18 +215,29 @@ var cn = (...classes) => classes.filter(Boolean).join(" ");
|
|
|
215
215
|
var DefaultTrashIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "w-4 h-4", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z" }) });
|
|
216
216
|
var DefaultEditIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "w-4 h-4", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z" }) });
|
|
217
217
|
var DefaultCloseIcon = () => /* @__PURE__ */ jsx("svg", { viewBox: "0 0 24 24", className: "w-4 h-4", fill: "currentColor", children: /* @__PURE__ */ jsx("path", { d: "M19 6.41L17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z" }) });
|
|
218
|
-
var DayHeader = ({
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
218
|
+
var DayHeader = ({
|
|
219
|
+
date,
|
|
220
|
+
locale,
|
|
221
|
+
index,
|
|
222
|
+
renderColumnHeader
|
|
223
|
+
}) => {
|
|
224
|
+
const isToday2 = isToday(date);
|
|
225
|
+
if (renderColumnHeader) {
|
|
226
|
+
return /* @__PURE__ */ jsx("div", { className: "grid place-items-center", children: renderColumnHeader({ date, index, isToday: isToday2, locale }) });
|
|
227
|
+
}
|
|
228
|
+
return /* @__PURE__ */ jsxs("p", { className: "grid place-items-center", children: [
|
|
229
|
+
/* @__PURE__ */ jsx("span", { className: "capitalize", children: date.toLocaleDateString(locale, { weekday: "short" }) }),
|
|
230
|
+
/* @__PURE__ */ jsx(
|
|
231
|
+
"span",
|
|
232
|
+
{
|
|
233
|
+
className: cn(
|
|
234
|
+
isToday2 && "bg-blue-500 rounded-full p-1 text-white"
|
|
235
|
+
),
|
|
236
|
+
children: date.getDate()
|
|
237
|
+
}
|
|
238
|
+
)
|
|
239
|
+
] });
|
|
240
|
+
};
|
|
230
241
|
function Calendar({
|
|
231
242
|
date = /* @__PURE__ */ new Date(),
|
|
232
243
|
events = [],
|
|
@@ -237,7 +248,7 @@ function Calendar({
|
|
|
237
248
|
onRemoveBlock,
|
|
238
249
|
config = {}
|
|
239
250
|
}) {
|
|
240
|
-
const { locale = "es-MX", icons = {} } = config;
|
|
251
|
+
const { locale = "es-MX", icons = {}, renderColumnHeader } = config;
|
|
241
252
|
const week = completeWeek(date);
|
|
242
253
|
const [activeId, setActiveId] = useState(null);
|
|
243
254
|
const { canMove } = useCalendarEvents(events);
|
|
@@ -289,7 +300,16 @@ function Calendar({
|
|
|
289
300
|
/* @__PURE__ */ jsxs("article", { className: "w-full bg-white shadow rounded-xl", children: [
|
|
290
301
|
/* @__PURE__ */ jsxs("section", { className: "grid grid-cols-8 place-items-center py-4", children: [
|
|
291
302
|
/* @__PURE__ */ jsx("p", { children: /* @__PURE__ */ jsx("span", { className: "text-sm text-gray-500", children: Intl.DateTimeFormat().resolvedOptions().timeZone }) }),
|
|
292
|
-
week.map((day) => /* @__PURE__ */ jsx(
|
|
303
|
+
week.map((day, index) => /* @__PURE__ */ jsx(
|
|
304
|
+
DayHeader,
|
|
305
|
+
{
|
|
306
|
+
date: day,
|
|
307
|
+
locale,
|
|
308
|
+
index,
|
|
309
|
+
renderColumnHeader
|
|
310
|
+
},
|
|
311
|
+
day.toISOString()
|
|
312
|
+
))
|
|
293
313
|
] }),
|
|
294
314
|
/* @__PURE__ */ jsxs("section", { className: "grid grid-cols-8 max-h-[80vh] overflow-y-auto", children: [
|
|
295
315
|
/* @__PURE__ */ jsx(TimeColumn, {}),
|