@ailuracode/alpine-calendar 0.1.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) ailuracode
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,68 @@
1
+ # @ailuracode/alpine-calendar
2
+
3
+ Lightweight calendar date logic for Alpine.js, powered by [date-fns](https://date-fns.org/).
4
+
5
+ **[Full documentation →](../../docs/calendar.md)**
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install @ailuracode/alpine-calendar alpinejs
11
+ ```
12
+
13
+ ## Quick example
14
+
15
+ ```js
16
+ import Alpine from "alpinejs";
17
+ import calendar from "@ailuracode/alpine-calendar";
18
+
19
+ Alpine.plugin(calendar);
20
+ Alpine.start();
21
+ ```
22
+
23
+ ```html
24
+ <div x-data="{ cal: $calendar({ weekStartsOn: 1 }) }">
25
+ <div class="btn-group">
26
+ <button type="button" @click="cal.prevMonth()">Previous</button>
27
+ <strong x-text="cal.formatMonth()"></strong>
28
+ <button type="button" @click="cal.nextMonth()">Next</button>
29
+ </div>
30
+
31
+ <div class="weekdays">
32
+ <template x-for="label in cal.weekdayLabels" :key="label">
33
+ <span x-text="label"></span>
34
+ </template>
35
+ </div>
36
+
37
+ <template x-for="week in cal.weeks" :key="week[0].date.toISOString()">
38
+ <div class="week">
39
+ <template x-for="day in week" :key="day.date.toISOString()">
40
+ <button
41
+ type="button"
42
+ :disabled="day.isDisabled"
43
+ :class="{
44
+ 'is-outside': !day.isCurrentMonth,
45
+ 'is-today': day.isToday,
46
+ 'is-selected': day.isSelected
47
+ }"
48
+ @click="cal.select(day.date)"
49
+ x-text="cal.format(day.date, 'd')"
50
+ ></button>
51
+ </template>
52
+ </div>
53
+ </template>
54
+ </div>
55
+ ```
56
+
57
+ ## API summary
58
+
59
+ | | |
60
+ |-|-|
61
+ | **Magic** | `$calendar(options?)` |
62
+ | **Returns** | Independent `CalendarInstance` with month navigation, selection, grid data, and flexible `disabled` matchers |
63
+
64
+ No UI is rendered — you build the markup and styles.
65
+
66
+ ## License
67
+
68
+ MIT
@@ -0,0 +1,26 @@
1
+ /// <reference types="@types/alpinejs" />
2
+
3
+ export type {
4
+ CalendarDateAfterMatcher,
5
+ CalendarDateBeforeMatcher,
6
+ CalendarDateFnsOptions,
7
+ CalendarDateIntervalMatcher,
8
+ CalendarDateOnlyMatcher,
9
+ CalendarDateRangeMatcher,
10
+ CalendarDayOfWeekMatcher,
11
+ CalendarInstance,
12
+ CalendarMagic,
13
+ CalendarMatcher,
14
+ CalendarMatcherFn,
15
+ ResolvedDateFnsContext,
16
+ } from "./index.js";
17
+
18
+ export { matchesCalendarMatcher } from "./index.js";
19
+
20
+ declare global {
21
+ namespace Alpine {
22
+ interface Magics<T> {
23
+ $calendar: import("./index.js").CalendarMagic;
24
+ }
25
+ }
26
+ }
@@ -0,0 +1,112 @@
1
+ import AlpineType from 'alpinejs';
2
+ import { ContextOptions, WeekOptions, FirstWeekContainsDateOptions, FormatOptions, Locale, Day } from 'date-fns';
3
+
4
+ type CalendarDateFnsOptions = ContextOptions<Date> & WeekOptions & FirstWeekContainsDateOptions & Pick<FormatOptions, "useAdditionalWeekYearTokens" | "useAdditionalDayOfYearTokens"> & {
5
+ locale?: Locale;
6
+ };
7
+ type ResolvedDateFnsContext = CalendarDateFnsOptions & {
8
+ locale: Locale;
9
+ weekStartsOn: Day;
10
+ };
11
+
12
+ type CalendarDateRangeMatcher = {
13
+ from: Date;
14
+ to: Date;
15
+ };
16
+ /** Disables dates strictly before `before` (exclusive). */
17
+ type CalendarDateBeforeMatcher = {
18
+ before: Date;
19
+ };
20
+ /** Disables dates strictly after `after` (exclusive). */
21
+ type CalendarDateAfterMatcher = {
22
+ after: Date;
23
+ };
24
+ /** Disables dates strictly between `after` and `before` (exclusive endpoints). */
25
+ type CalendarDateIntervalMatcher = {
26
+ before: Date;
27
+ after: Date;
28
+ };
29
+ /** Disables dates outside the inclusive `only` range. */
30
+ type CalendarDateOnlyMatcher = {
31
+ only: CalendarDateRangeMatcher;
32
+ };
33
+ type CalendarDayOfWeekMatcher = {
34
+ dayOfWeek: Day | Day[];
35
+ };
36
+ type CalendarMatcherFn = (date: Date) => boolean;
37
+ type CalendarMatcher = boolean | Date | Date[] | CalendarDateRangeMatcher | CalendarDateBeforeMatcher | CalendarDateAfterMatcher | CalendarDateIntervalMatcher | CalendarDateOnlyMatcher | CalendarDayOfWeekMatcher | CalendarMatcherFn;
38
+ declare function normalizeMatchers(disabled?: CalendarMatcher | CalendarMatcher[]): CalendarMatcher[];
39
+ /** Returns `true` when the date matches the matcher. */
40
+ declare function matchesCalendarMatcher(date: Date, matcher: CalendarMatcher, context: ResolvedDateFnsContext): boolean;
41
+
42
+ type CalendarMode = "single" | "range" | "multiple";
43
+ type CalendarDateRange = {
44
+ from?: Date;
45
+ to?: Date;
46
+ };
47
+ type CalendarSelection = Date | Date[] | CalendarDateRange | null;
48
+
49
+ interface CalendarOptions {
50
+ locale?: Locale;
51
+ weekStartsOn?: Day;
52
+ minDate?: Date;
53
+ maxDate?: Date;
54
+ mode?: CalendarMode;
55
+ month?: Date;
56
+ selected?: CalendarSelection;
57
+ disabled?: CalendarMatcher | CalendarMatcher[];
58
+ dateFns?: CalendarDateFnsOptions;
59
+ }
60
+ interface CalendarDay {
61
+ date: Date;
62
+ isCurrentMonth: boolean;
63
+ isToday: boolean;
64
+ isSelected: boolean;
65
+ isDisabled: boolean;
66
+ isRangeStart: boolean;
67
+ isRangeEnd: boolean;
68
+ isInRange: boolean;
69
+ }
70
+ interface CalendarInstance {
71
+ month: Date;
72
+ mode: CalendarMode;
73
+ selected: CalendarSelection;
74
+ locale: Locale;
75
+ weekStartsOn: Day;
76
+ dateFns: ResolvedDateFnsContext;
77
+ readonly weeks: CalendarDay[][];
78
+ readonly weekdayLabels: string[];
79
+ prevMonth(): void;
80
+ nextMonth(): void;
81
+ goToMonth(date: Date): void;
82
+ goToToday(): void;
83
+ select(date: Date | null): void;
84
+ clear(): void;
85
+ matches(date: Date, matcher: CalendarMatcher): boolean;
86
+ isSelected(date: Date): boolean;
87
+ isDisabled(date: Date): boolean;
88
+ isToday(date: Date): boolean;
89
+ isSameMonth(date: Date, month?: Date): boolean;
90
+ isInRange(date: Date): boolean;
91
+ isRangeStart(date: Date): boolean;
92
+ isRangeEnd(date: Date): boolean;
93
+ format(date: Date, pattern: string): string;
94
+ formatMonth(month?: Date): string;
95
+ formatYear(month?: Date): string;
96
+ }
97
+ type CalendarMagic = (options?: CalendarOptions) => CalendarInstance;
98
+ /** Creates an independent calendar logic instance backed by date-fns. */
99
+ declare function createCalendar(options?: CalendarOptions): CalendarInstance;
100
+ /** Builds callable `$calendar` magic that returns independent calendar instances. */
101
+ declare function createCalendarMagic(): CalendarMagic;
102
+ /** Alpine.js calendar plugin. Registers callable magic `$calendar`. */
103
+ declare function calendarPlugin(Alpine: AlpineType.Alpine): void;
104
+ declare global {
105
+ namespace Alpine {
106
+ interface Magics<T> {
107
+ $calendar: CalendarMagic;
108
+ }
109
+ }
110
+ }
111
+
112
+ export { type CalendarDateAfterMatcher, type CalendarDateBeforeMatcher, type CalendarDateFnsOptions, type CalendarDateIntervalMatcher, type CalendarDateOnlyMatcher, type CalendarDateRange, type CalendarDateRangeMatcher, type CalendarDay, type CalendarDayOfWeekMatcher, type CalendarInstance, type CalendarMagic, type CalendarMatcher, type CalendarMatcherFn, type CalendarMode, type CalendarOptions, type CalendarSelection, type ResolvedDateFnsContext, createCalendar, createCalendarMagic, calendarPlugin as default, matchesCalendarMatcher, normalizeMatchers };
package/dist/index.js ADDED
@@ -0,0 +1,359 @@
1
+ // src/index.ts
2
+ import {
3
+ addDays,
4
+ addMonths,
5
+ eachDayOfInterval,
6
+ endOfMonth,
7
+ endOfWeek,
8
+ format,
9
+ isBefore as isBefore2,
10
+ isSameDay as isSameDay2,
11
+ isSameMonth,
12
+ isToday as isTodayDate,
13
+ isWithinInterval as isWithinInterval2,
14
+ startOfDay as startOfDay2,
15
+ startOfMonth,
16
+ startOfWeek,
17
+ subMonths
18
+ } from "date-fns";
19
+
20
+ // src/context.ts
21
+ import { enUS } from "date-fns/locale";
22
+ function resolveDateFnsContext(options = {}) {
23
+ const dateFns = options.dateFns ?? {};
24
+ return {
25
+ ...dateFns,
26
+ locale: options.locale ?? dateFns.locale ?? enUS,
27
+ weekStartsOn: options.weekStartsOn ?? dateFns.weekStartsOn ?? 0
28
+ };
29
+ }
30
+
31
+ // src/matchers.ts
32
+ import { getDay, isAfter, isBefore, isSameDay, isWithinInterval, startOfDay } from "date-fns";
33
+ function normalizeMatcherDate(date, context) {
34
+ return startOfDay(date, context);
35
+ }
36
+ function isInclusiveRangeMatcher(matcher) {
37
+ return typeof matcher === "object" && matcher !== null && !Array.isArray(matcher) && !(matcher instanceof Date) && "from" in matcher && "to" in matcher && !("only" in matcher);
38
+ }
39
+ function isDateIntervalMatcher(matcher) {
40
+ return typeof matcher === "object" && matcher !== null && !Array.isArray(matcher) && !(matcher instanceof Date) && "before" in matcher && "after" in matcher;
41
+ }
42
+ function isDateBeforeMatcher(matcher) {
43
+ return typeof matcher === "object" && matcher !== null && !Array.isArray(matcher) && !(matcher instanceof Date) && "before" in matcher && !("after" in matcher);
44
+ }
45
+ function isDateAfterMatcher(matcher) {
46
+ return typeof matcher === "object" && matcher !== null && !Array.isArray(matcher) && !(matcher instanceof Date) && "after" in matcher && !("before" in matcher);
47
+ }
48
+ function isDateOnlyMatcher(matcher) {
49
+ return typeof matcher === "object" && matcher !== null && !Array.isArray(matcher) && !(matcher instanceof Date) && "only" in matcher;
50
+ }
51
+ function isDayOfWeekMatcher(matcher) {
52
+ return typeof matcher === "object" && matcher !== null && !Array.isArray(matcher) && !(matcher instanceof Date) && "dayOfWeek" in matcher;
53
+ }
54
+ function matchesInclusiveRange(day, matcher, context) {
55
+ const from = normalizeMatcherDate(matcher.from, context);
56
+ const to = normalizeMatcherDate(matcher.to, context);
57
+ return isWithinInterval(day, { start: from, end: to }, context);
58
+ }
59
+ function matchesDateOnly(day, matcher, context) {
60
+ const from = normalizeMatcherDate(matcher.only.from, context);
61
+ const to = normalizeMatcherDate(matcher.only.to, context);
62
+ return isBefore(day, from) || isAfter(day, to);
63
+ }
64
+ function matchesDayOfWeek(day, matcher) {
65
+ const days = Array.isArray(matcher.dayOfWeek) ? matcher.dayOfWeek : [matcher.dayOfWeek];
66
+ return days.includes(getDay(day));
67
+ }
68
+ function normalizeMatchers(disabled) {
69
+ if (disabled === void 0) {
70
+ return [];
71
+ }
72
+ return Array.isArray(disabled) ? disabled : [disabled];
73
+ }
74
+ function matchesCalendarMatcher(date, matcher, context) {
75
+ const day = normalizeMatcherDate(date, context);
76
+ if (typeof matcher === "boolean") {
77
+ return matcher;
78
+ }
79
+ if (matcher instanceof Date) {
80
+ return isSameDay(day, matcher, context);
81
+ }
82
+ if (Array.isArray(matcher)) {
83
+ return matcher.some((value) => isSameDay(day, value, context));
84
+ }
85
+ if (typeof matcher === "function") {
86
+ return matcher(day);
87
+ }
88
+ if (isDateOnlyMatcher(matcher)) {
89
+ return matchesDateOnly(day, matcher, context);
90
+ }
91
+ if (isInclusiveRangeMatcher(matcher)) {
92
+ return matchesInclusiveRange(day, matcher, context);
93
+ }
94
+ if (isDateIntervalMatcher(matcher)) {
95
+ const before = normalizeMatcherDate(matcher.before, context);
96
+ const after = normalizeMatcherDate(matcher.after, context);
97
+ return isAfter(day, after) && isBefore(day, before);
98
+ }
99
+ if (isDateBeforeMatcher(matcher)) {
100
+ return isBefore(day, normalizeMatcherDate(matcher.before, context));
101
+ }
102
+ if (isDateAfterMatcher(matcher)) {
103
+ return isAfter(day, normalizeMatcherDate(matcher.after, context));
104
+ }
105
+ if (isDayOfWeekMatcher(matcher)) {
106
+ return matchesDayOfWeek(day, matcher);
107
+ }
108
+ return false;
109
+ }
110
+ function matchesAnyCalendarMatcher(date, matchers, context) {
111
+ return matchers.some((matcher) => matchesCalendarMatcher(date, matcher, context));
112
+ }
113
+ function isDateDisabledByRules(date, minDate, maxDate, matchers, context) {
114
+ const day = normalizeMatcherDate(date, context);
115
+ if (minDate && isBefore(day, minDate)) {
116
+ return true;
117
+ }
118
+ if (maxDate && isAfter(day, maxDate)) {
119
+ return true;
120
+ }
121
+ return matchesAnyCalendarMatcher(day, matchers, context);
122
+ }
123
+
124
+ // src/index.ts
125
+ function normalizeDate(date, context) {
126
+ return startOfDay2(date, context);
127
+ }
128
+ function normalizeRange(range, context) {
129
+ return {
130
+ from: range.from ? normalizeDate(range.from, context) : void 0,
131
+ to: range.to ? normalizeDate(range.to, context) : void 0
132
+ };
133
+ }
134
+ function normalizeSelection(selection, mode, context) {
135
+ if (selection === null) {
136
+ return null;
137
+ }
138
+ if (mode === "single") {
139
+ return selection instanceof Date ? normalizeDate(selection, context) : null;
140
+ }
141
+ if (mode === "multiple") {
142
+ if (!Array.isArray(selection)) {
143
+ return [];
144
+ }
145
+ return selection.map((date) => normalizeDate(date, context));
146
+ }
147
+ if (typeof selection === "object" && !Array.isArray(selection) && !(selection instanceof Date)) {
148
+ return normalizeRange(selection, context);
149
+ }
150
+ return null;
151
+ }
152
+ function resolveConfig(options = {}) {
153
+ const context = resolveDateFnsContext(options);
154
+ return {
155
+ context,
156
+ minDate: options.minDate ? normalizeDate(options.minDate, context) : void 0,
157
+ maxDate: options.maxDate ? normalizeDate(options.maxDate, context) : void 0,
158
+ mode: options.mode ?? "single",
159
+ month: startOfMonth(options.month ?? /* @__PURE__ */ new Date(), context),
160
+ selected: normalizeSelection(options.selected ?? null, options.mode ?? "single", context),
161
+ disabled: normalizeMatchers(options.disabled)
162
+ };
163
+ }
164
+ function getMonthDays(month, context) {
165
+ const start = startOfWeek(startOfMonth(month, context), context);
166
+ const end = endOfWeek(endOfMonth(month, context), context);
167
+ return eachDayOfInterval({ start, end }, context);
168
+ }
169
+ function chunkWeeks(days) {
170
+ const weeks = [];
171
+ for (let index = 0; index < days.length; index += 7) {
172
+ weeks.push(days.slice(index, index + 7));
173
+ }
174
+ return weeks;
175
+ }
176
+ function getWeekdayLabels(context) {
177
+ const start = startOfWeek(/* @__PURE__ */ new Date(), context);
178
+ return Array.from(
179
+ { length: 7 },
180
+ (_, index) => format(addDays(start, index, context), "EEEEEE", context)
181
+ );
182
+ }
183
+ function selectSingleDate(calendar, day) {
184
+ calendar.selected = day;
185
+ }
186
+ function selectMultipleDate(calendar, day) {
187
+ const current = Array.isArray(calendar.selected) ? [...calendar.selected] : [];
188
+ const existingIndex = current.findIndex((value) => isSameDay2(value, day, calendar.dateFns));
189
+ if (existingIndex >= 0) {
190
+ current.splice(existingIndex, 1);
191
+ } else {
192
+ current.push(day);
193
+ }
194
+ calendar.selected = current;
195
+ }
196
+ function selectRangeDate(calendar, day) {
197
+ const range = calendar.selected ?? {};
198
+ if (!range.from || range.from && range.to) {
199
+ calendar.selected = { from: day, to: void 0 };
200
+ return;
201
+ }
202
+ if (isSameDay2(day, range.from, calendar.dateFns)) {
203
+ return;
204
+ }
205
+ if (isBefore2(day, range.from)) {
206
+ calendar.selected = { from: day, to: range.from };
207
+ return;
208
+ }
209
+ calendar.selected = { from: range.from, to: day };
210
+ }
211
+ function isSingleSelected(selected, day, context) {
212
+ return selected instanceof Date ? isSameDay2(selected, day, context) : false;
213
+ }
214
+ function isMultipleSelected(selected, day, context) {
215
+ return Array.isArray(selected) ? selected.some((value) => isSameDay2(value, day, context)) : false;
216
+ }
217
+ function isRangeEndpointSelected(selected, day, context) {
218
+ const range = selected;
219
+ if (!range) {
220
+ return false;
221
+ }
222
+ return (range.from ? isSameDay2(range.from, day, context) : false) || (range.to ? isSameDay2(range.to, day, context) : false);
223
+ }
224
+ function createCalendar(options = {}) {
225
+ const config = resolveConfig(options);
226
+ const calendar = {
227
+ month: config.month,
228
+ mode: config.mode,
229
+ selected: config.selected,
230
+ locale: config.context.locale,
231
+ weekStartsOn: config.context.weekStartsOn,
232
+ dateFns: config.context,
233
+ get weeks() {
234
+ const days = getMonthDays(this.month, this.dateFns);
235
+ return chunkWeeks(days).map(
236
+ (week) => week.map((date) => ({
237
+ date,
238
+ isCurrentMonth: isSameMonth(date, this.month, this.dateFns),
239
+ isToday: isTodayDate(date, this.dateFns),
240
+ isSelected: this.isSelected(date),
241
+ isDisabled: this.isDisabled(date),
242
+ isRangeStart: this.isRangeStart(date),
243
+ isRangeEnd: this.isRangeEnd(date),
244
+ isInRange: this.isInRange(date)
245
+ }))
246
+ );
247
+ },
248
+ get weekdayLabels() {
249
+ return getWeekdayLabels(this.dateFns);
250
+ },
251
+ prevMonth() {
252
+ this.month = subMonths(this.month, 1, this.dateFns);
253
+ },
254
+ nextMonth() {
255
+ this.month = addMonths(this.month, 1, this.dateFns);
256
+ },
257
+ goToMonth(date) {
258
+ this.month = startOfMonth(date, this.dateFns);
259
+ },
260
+ goToToday() {
261
+ this.goToMonth(/* @__PURE__ */ new Date());
262
+ },
263
+ select(date) {
264
+ if (date === null) {
265
+ this.clear();
266
+ return;
267
+ }
268
+ const day = normalizeDate(date, this.dateFns);
269
+ if (this.isDisabled(day)) {
270
+ return;
271
+ }
272
+ if (this.mode === "single") {
273
+ selectSingleDate(this, day);
274
+ return;
275
+ }
276
+ if (this.mode === "multiple") {
277
+ selectMultipleDate(this, day);
278
+ return;
279
+ }
280
+ selectRangeDate(this, day);
281
+ },
282
+ clear() {
283
+ this.selected = this.mode === "multiple" ? [] : null;
284
+ },
285
+ matches(date, matcher) {
286
+ return matchesCalendarMatcher(date, matcher, this.dateFns);
287
+ },
288
+ isSelected(date) {
289
+ const day = normalizeDate(date, this.dateFns);
290
+ if (this.mode === "single") {
291
+ return isSingleSelected(this.selected, day, this.dateFns);
292
+ }
293
+ if (this.mode === "multiple") {
294
+ return isMultipleSelected(this.selected, day, this.dateFns);
295
+ }
296
+ return isRangeEndpointSelected(this.selected, day, this.dateFns);
297
+ },
298
+ isDisabled(date) {
299
+ return isDateDisabledByRules(
300
+ date,
301
+ config.minDate,
302
+ config.maxDate,
303
+ config.disabled,
304
+ this.dateFns
305
+ );
306
+ },
307
+ isToday(date) {
308
+ return isTodayDate(date, this.dateFns);
309
+ },
310
+ isSameMonth(date, month) {
311
+ return isSameMonth(date, month ?? calendar.month, calendar.dateFns);
312
+ },
313
+ isInRange(date) {
314
+ if (this.mode !== "range") {
315
+ return false;
316
+ }
317
+ const range = this.selected;
318
+ if (!(range?.from && range.to)) {
319
+ return false;
320
+ }
321
+ const day = normalizeDate(date, this.dateFns);
322
+ return isWithinInterval2(day, { start: range.from, end: range.to }, this.dateFns) && !isSameDay2(day, range.from, this.dateFns) && !isSameDay2(day, range.to, this.dateFns);
323
+ },
324
+ isRangeStart(date) {
325
+ const range = this.selected;
326
+ return range?.from ? isSameDay2(date, range.from, this.dateFns) : false;
327
+ },
328
+ isRangeEnd(date) {
329
+ const range = this.selected;
330
+ return range?.to ? isSameDay2(date, range.to, this.dateFns) : false;
331
+ },
332
+ format(date, pattern) {
333
+ return format(date, pattern, this.dateFns);
334
+ },
335
+ formatMonth(month) {
336
+ const value = month ?? calendar.month;
337
+ return format(value, "LLLL yyyy", calendar.dateFns);
338
+ },
339
+ formatYear(month) {
340
+ const value = month ?? calendar.month;
341
+ return format(value, "yyyy", calendar.dateFns);
342
+ }
343
+ };
344
+ return calendar;
345
+ }
346
+ function createCalendarMagic() {
347
+ return (options) => createCalendar(options);
348
+ }
349
+ function calendarPlugin(Alpine) {
350
+ Alpine.magic("calendar", () => createCalendarMagic());
351
+ }
352
+ export {
353
+ createCalendar,
354
+ createCalendarMagic,
355
+ calendarPlugin as default,
356
+ matchesCalendarMatcher,
357
+ normalizeMatchers
358
+ };
359
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/matchers.ts"],"sourcesContent":["import type AlpineType from \"alpinejs\";\nimport type { Day, Locale } from \"date-fns\";\nimport {\n addDays,\n addMonths,\n eachDayOfInterval,\n endOfMonth,\n endOfWeek,\n format,\n isBefore,\n isSameDay,\n isSameMonth,\n isToday as isTodayDate,\n isWithinInterval,\n startOfDay,\n startOfMonth,\n startOfWeek,\n subMonths,\n} from \"date-fns\";\nimport {\n type CalendarDateFnsOptions,\n type ResolvedDateFnsContext,\n resolveDateFnsContext,\n} from \"./context.js\";\nimport {\n type CalendarDateAfterMatcher,\n type CalendarDateBeforeMatcher,\n type CalendarDateIntervalMatcher,\n type CalendarDateOnlyMatcher,\n type CalendarDateRangeMatcher,\n type CalendarDayOfWeekMatcher,\n type CalendarMatcher,\n type CalendarMatcherFn,\n isDateDisabledByRules,\n matchesCalendarMatcher,\n normalizeMatchers,\n} from \"./matchers.js\";\n\nexport type CalendarMode = \"single\" | \"range\" | \"multiple\";\n\nexport type CalendarDateRange = {\n from?: Date;\n to?: Date;\n};\n\nexport type CalendarSelection = Date | Date[] | CalendarDateRange | null;\n\nexport type {\n CalendarDateAfterMatcher,\n CalendarDateBeforeMatcher,\n CalendarDateFnsOptions,\n CalendarDateIntervalMatcher,\n CalendarDateOnlyMatcher,\n CalendarDateRangeMatcher,\n CalendarDayOfWeekMatcher,\n CalendarMatcher,\n CalendarMatcherFn,\n ResolvedDateFnsContext,\n};\n\nexport { matchesCalendarMatcher, normalizeMatchers };\n\nexport interface CalendarOptions {\n locale?: Locale;\n weekStartsOn?: Day;\n minDate?: Date;\n maxDate?: Date;\n mode?: CalendarMode;\n month?: Date;\n selected?: CalendarSelection;\n disabled?: CalendarMatcher | CalendarMatcher[];\n dateFns?: CalendarDateFnsOptions;\n}\n\nexport interface CalendarDay {\n date: Date;\n isCurrentMonth: boolean;\n isToday: boolean;\n isSelected: boolean;\n isDisabled: boolean;\n isRangeStart: boolean;\n isRangeEnd: boolean;\n isInRange: boolean;\n}\n\nexport interface CalendarInstance {\n month: Date;\n mode: CalendarMode;\n selected: CalendarSelection;\n locale: Locale;\n weekStartsOn: Day;\n dateFns: ResolvedDateFnsContext;\n readonly weeks: CalendarDay[][];\n readonly weekdayLabels: string[];\n prevMonth(): void;\n nextMonth(): void;\n goToMonth(date: Date): void;\n goToToday(): void;\n select(date: Date | null): void;\n clear(): void;\n matches(date: Date, matcher: CalendarMatcher): boolean;\n isSelected(date: Date): boolean;\n isDisabled(date: Date): boolean;\n isToday(date: Date): boolean;\n isSameMonth(date: Date, month?: Date): boolean;\n isInRange(date: Date): boolean;\n isRangeStart(date: Date): boolean;\n isRangeEnd(date: Date): boolean;\n format(date: Date, pattern: string): string;\n formatMonth(month?: Date): string;\n formatYear(month?: Date): string;\n}\n\nexport type CalendarMagic = (options?: CalendarOptions) => CalendarInstance;\n\ntype ResolvedCalendarConfig = {\n context: ResolvedDateFnsContext;\n minDate?: Date;\n maxDate?: Date;\n mode: CalendarMode;\n month: Date;\n selected: CalendarSelection;\n disabled: CalendarMatcher[];\n};\n\nfunction normalizeDate(date: Date, context: ResolvedDateFnsContext): Date {\n return startOfDay(date, context);\n}\n\nfunction normalizeRange(\n range: CalendarDateRange,\n context: ResolvedDateFnsContext\n): CalendarDateRange {\n return {\n from: range.from ? normalizeDate(range.from, context) : undefined,\n to: range.to ? normalizeDate(range.to, context) : undefined,\n };\n}\n\nfunction normalizeSelection(\n selection: CalendarSelection,\n mode: CalendarMode,\n context: ResolvedDateFnsContext\n): CalendarSelection {\n if (selection === null) {\n return null;\n }\n\n if (mode === \"single\") {\n return selection instanceof Date ? normalizeDate(selection, context) : null;\n }\n\n if (mode === \"multiple\") {\n if (!Array.isArray(selection)) {\n return [];\n }\n\n return selection.map((date) => normalizeDate(date, context));\n }\n\n if (typeof selection === \"object\" && !Array.isArray(selection) && !(selection instanceof Date)) {\n return normalizeRange(selection, context);\n }\n\n return null;\n}\n\nfunction resolveConfig(options: CalendarOptions = {}): ResolvedCalendarConfig {\n const context = resolveDateFnsContext(options);\n\n return {\n context,\n minDate: options.minDate ? normalizeDate(options.minDate, context) : undefined,\n maxDate: options.maxDate ? normalizeDate(options.maxDate, context) : undefined,\n mode: options.mode ?? \"single\",\n month: startOfMonth(options.month ?? new Date(), context),\n selected: normalizeSelection(options.selected ?? null, options.mode ?? \"single\", context),\n disabled: normalizeMatchers(options.disabled),\n };\n}\n\nfunction getMonthDays(month: Date, context: ResolvedDateFnsContext): Date[] {\n const start = startOfWeek(startOfMonth(month, context), context);\n const end = endOfWeek(endOfMonth(month, context), context);\n\n return eachDayOfInterval({ start, end }, context);\n}\n\nfunction chunkWeeks(days: Date[]): Date[][] {\n const weeks: Date[][] = [];\n\n for (let index = 0; index < days.length; index += 7) {\n weeks.push(days.slice(index, index + 7));\n }\n\n return weeks;\n}\n\nfunction getWeekdayLabels(context: ResolvedDateFnsContext): string[] {\n const start = startOfWeek(new Date(), context);\n\n return Array.from({ length: 7 }, (_, index) =>\n format(addDays(start, index, context), \"EEEEEE\", context)\n );\n}\n\nfunction selectSingleDate(calendar: CalendarInstance, day: Date): void {\n calendar.selected = day;\n}\n\nfunction selectMultipleDate(calendar: CalendarInstance, day: Date): void {\n const current = Array.isArray(calendar.selected) ? [...calendar.selected] : [];\n const existingIndex = current.findIndex((value) => isSameDay(value, day, calendar.dateFns));\n\n if (existingIndex >= 0) {\n current.splice(existingIndex, 1);\n } else {\n current.push(day);\n }\n\n calendar.selected = current;\n}\n\nfunction selectRangeDate(calendar: CalendarInstance, day: Date): void {\n const range = (calendar.selected as CalendarDateRange | null) ?? {};\n\n if (!range.from || (range.from && range.to)) {\n calendar.selected = { from: day, to: undefined };\n return;\n }\n\n if (isSameDay(day, range.from, calendar.dateFns)) {\n return;\n }\n\n if (isBefore(day, range.from)) {\n calendar.selected = { from: day, to: range.from };\n return;\n }\n\n calendar.selected = { from: range.from, to: day };\n}\n\nfunction isSingleSelected(\n selected: CalendarSelection,\n day: Date,\n context: ResolvedDateFnsContext\n): boolean {\n return selected instanceof Date ? isSameDay(selected, day, context) : false;\n}\n\nfunction isMultipleSelected(\n selected: CalendarSelection,\n day: Date,\n context: ResolvedDateFnsContext\n): boolean {\n return Array.isArray(selected) ? selected.some((value) => isSameDay(value, day, context)) : false;\n}\n\nfunction isRangeEndpointSelected(\n selected: CalendarSelection,\n day: Date,\n context: ResolvedDateFnsContext\n): boolean {\n const range = selected as CalendarDateRange | null;\n\n if (!range) {\n return false;\n }\n\n return (\n (range.from ? isSameDay(range.from, day, context) : false) ||\n (range.to ? isSameDay(range.to, day, context) : false)\n );\n}\n\n/** Creates an independent calendar logic instance backed by date-fns. */\nexport function createCalendar(options: CalendarOptions = {}): CalendarInstance {\n const config = resolveConfig(options);\n\n const calendar: CalendarInstance = {\n month: config.month,\n mode: config.mode,\n selected: config.selected,\n locale: config.context.locale,\n weekStartsOn: config.context.weekStartsOn,\n dateFns: config.context,\n\n get weeks() {\n const days = getMonthDays(this.month, this.dateFns);\n\n return chunkWeeks(days).map((week) =>\n week.map((date) => ({\n date,\n isCurrentMonth: isSameMonth(date, this.month, this.dateFns),\n isToday: isTodayDate(date, this.dateFns),\n isSelected: this.isSelected(date),\n isDisabled: this.isDisabled(date),\n isRangeStart: this.isRangeStart(date),\n isRangeEnd: this.isRangeEnd(date),\n isInRange: this.isInRange(date),\n }))\n );\n },\n\n get weekdayLabels() {\n return getWeekdayLabels(this.dateFns);\n },\n\n prevMonth() {\n this.month = subMonths(this.month, 1, this.dateFns);\n },\n\n nextMonth() {\n this.month = addMonths(this.month, 1, this.dateFns);\n },\n\n goToMonth(date: Date) {\n this.month = startOfMonth(date, this.dateFns);\n },\n\n goToToday() {\n this.goToMonth(new Date());\n },\n\n select(date: Date | null) {\n if (date === null) {\n this.clear();\n return;\n }\n\n const day = normalizeDate(date, this.dateFns);\n\n if (this.isDisabled(day)) {\n return;\n }\n\n if (this.mode === \"single\") {\n selectSingleDate(this, day);\n return;\n }\n\n if (this.mode === \"multiple\") {\n selectMultipleDate(this, day);\n return;\n }\n\n selectRangeDate(this, day);\n },\n\n clear() {\n this.selected = this.mode === \"multiple\" ? [] : null;\n },\n\n matches(date: Date, matcher: CalendarMatcher) {\n return matchesCalendarMatcher(date, matcher, this.dateFns);\n },\n\n isSelected(date: Date) {\n const day = normalizeDate(date, this.dateFns);\n\n if (this.mode === \"single\") {\n return isSingleSelected(this.selected, day, this.dateFns);\n }\n\n if (this.mode === \"multiple\") {\n return isMultipleSelected(this.selected, day, this.dateFns);\n }\n\n return isRangeEndpointSelected(this.selected, day, this.dateFns);\n },\n\n isDisabled(date: Date) {\n return isDateDisabledByRules(\n date,\n config.minDate,\n config.maxDate,\n config.disabled,\n this.dateFns\n );\n },\n\n isToday(date: Date) {\n return isTodayDate(date, this.dateFns);\n },\n\n isSameMonth(date: Date, month?: Date) {\n return isSameMonth(date, month ?? calendar.month, calendar.dateFns);\n },\n\n isInRange(date: Date) {\n if (this.mode !== \"range\") {\n return false;\n }\n\n const range = this.selected as CalendarDateRange | null;\n\n if (!(range?.from && range.to)) {\n return false;\n }\n\n const day = normalizeDate(date, this.dateFns);\n\n return (\n isWithinInterval(day, { start: range.from, end: range.to }, this.dateFns) &&\n !isSameDay(day, range.from, this.dateFns) &&\n !isSameDay(day, range.to, this.dateFns)\n );\n },\n\n isRangeStart(date: Date) {\n const range = this.selected as CalendarDateRange | null;\n return range?.from ? isSameDay(date, range.from, this.dateFns) : false;\n },\n\n isRangeEnd(date: Date) {\n const range = this.selected as CalendarDateRange | null;\n return range?.to ? isSameDay(date, range.to, this.dateFns) : false;\n },\n\n format(date: Date, pattern: string) {\n return format(date, pattern, this.dateFns);\n },\n\n formatMonth(month?: Date) {\n const value = month ?? calendar.month;\n return format(value, \"LLLL yyyy\", calendar.dateFns);\n },\n\n formatYear(month?: Date) {\n const value = month ?? calendar.month;\n return format(value, \"yyyy\", calendar.dateFns);\n },\n };\n\n return calendar;\n}\n\n/** Builds callable `$calendar` magic that returns independent calendar instances. */\nexport function createCalendarMagic(): CalendarMagic {\n return (options?: CalendarOptions) => createCalendar(options);\n}\n\n/** Alpine.js calendar plugin. Registers callable magic `$calendar`. */\nexport default function calendarPlugin(Alpine: AlpineType.Alpine): void {\n Alpine.magic(\"calendar\", () => createCalendarMagic());\n}\n\ndeclare global {\n namespace Alpine {\n interface Magics<T> {\n $calendar: CalendarMagic;\n }\n }\n}\n","import type {\n ContextOptions,\n Day,\n FirstWeekContainsDateOptions,\n FormatOptions,\n Locale,\n WeekOptions,\n} from \"date-fns\";\nimport { enUS } from \"date-fns/locale\";\n\nexport type CalendarDateFnsOptions = ContextOptions<Date> &\n WeekOptions &\n FirstWeekContainsDateOptions &\n Pick<FormatOptions, \"useAdditionalWeekYearTokens\" | \"useAdditionalDayOfYearTokens\"> & {\n locale?: Locale;\n };\n\nexport type ResolvedDateFnsContext = CalendarDateFnsOptions & {\n locale: Locale;\n weekStartsOn: Day;\n};\n\ntype DateFnsOptionInput = {\n locale?: Locale;\n weekStartsOn?: Day;\n dateFns?: CalendarDateFnsOptions;\n};\n\nexport function resolveDateFnsContext(options: DateFnsOptionInput = {}): ResolvedDateFnsContext {\n const dateFns = options.dateFns ?? {};\n\n return {\n ...dateFns,\n locale: options.locale ?? dateFns.locale ?? enUS,\n weekStartsOn: options.weekStartsOn ?? dateFns.weekStartsOn ?? 0,\n };\n}\n","import type { Day } from \"date-fns\";\nimport { getDay, isAfter, isBefore, isSameDay, isWithinInterval, startOfDay } from \"date-fns\";\nimport type { ResolvedDateFnsContext } from \"./context.js\";\n\nexport type CalendarDateRangeMatcher = {\n from: Date;\n to: Date;\n};\n\n/** Disables dates strictly before `before` (exclusive). */\nexport type CalendarDateBeforeMatcher = {\n before: Date;\n};\n\n/** Disables dates strictly after `after` (exclusive). */\nexport type CalendarDateAfterMatcher = {\n after: Date;\n};\n\n/** Disables dates strictly between `after` and `before` (exclusive endpoints). */\nexport type CalendarDateIntervalMatcher = {\n before: Date;\n after: Date;\n};\n\n/** Disables dates outside the inclusive `only` range. */\nexport type CalendarDateOnlyMatcher = {\n only: CalendarDateRangeMatcher;\n};\n\nexport type CalendarDayOfWeekMatcher = {\n dayOfWeek: Day | Day[];\n};\n\nexport type CalendarMatcherFn = (date: Date) => boolean;\n\nexport type CalendarMatcher =\n | boolean\n | Date\n | Date[]\n | CalendarDateRangeMatcher\n | CalendarDateBeforeMatcher\n | CalendarDateAfterMatcher\n | CalendarDateIntervalMatcher\n | CalendarDateOnlyMatcher\n | CalendarDayOfWeekMatcher\n | CalendarMatcherFn;\n\nfunction normalizeMatcherDate(date: Date, context: ResolvedDateFnsContext): Date {\n return startOfDay(date, context);\n}\n\nfunction isInclusiveRangeMatcher(matcher: CalendarMatcher): matcher is CalendarDateRangeMatcher {\n return (\n typeof matcher === \"object\" &&\n matcher !== null &&\n !Array.isArray(matcher) &&\n !(matcher instanceof Date) &&\n \"from\" in matcher &&\n \"to\" in matcher &&\n !(\"only\" in matcher)\n );\n}\n\nfunction isDateIntervalMatcher(matcher: CalendarMatcher): matcher is CalendarDateIntervalMatcher {\n return (\n typeof matcher === \"object\" &&\n matcher !== null &&\n !Array.isArray(matcher) &&\n !(matcher instanceof Date) &&\n \"before\" in matcher &&\n \"after\" in matcher\n );\n}\n\nfunction isDateBeforeMatcher(matcher: CalendarMatcher): matcher is CalendarDateBeforeMatcher {\n return (\n typeof matcher === \"object\" &&\n matcher !== null &&\n !Array.isArray(matcher) &&\n !(matcher instanceof Date) &&\n \"before\" in matcher &&\n !(\"after\" in matcher)\n );\n}\n\nfunction isDateAfterMatcher(matcher: CalendarMatcher): matcher is CalendarDateAfterMatcher {\n return (\n typeof matcher === \"object\" &&\n matcher !== null &&\n !Array.isArray(matcher) &&\n !(matcher instanceof Date) &&\n \"after\" in matcher &&\n !(\"before\" in matcher)\n );\n}\n\nfunction isDateOnlyMatcher(matcher: CalendarMatcher): matcher is CalendarDateOnlyMatcher {\n return (\n typeof matcher === \"object\" &&\n matcher !== null &&\n !Array.isArray(matcher) &&\n !(matcher instanceof Date) &&\n \"only\" in matcher\n );\n}\n\nfunction isDayOfWeekMatcher(matcher: CalendarMatcher): matcher is CalendarDayOfWeekMatcher {\n return (\n typeof matcher === \"object\" &&\n matcher !== null &&\n !Array.isArray(matcher) &&\n !(matcher instanceof Date) &&\n \"dayOfWeek\" in matcher\n );\n}\n\nfunction matchesInclusiveRange(\n day: Date,\n matcher: CalendarDateRangeMatcher,\n context: ResolvedDateFnsContext\n): boolean {\n const from = normalizeMatcherDate(matcher.from, context);\n const to = normalizeMatcherDate(matcher.to, context);\n\n return isWithinInterval(day, { start: from, end: to }, context);\n}\n\nfunction matchesDateOnly(\n day: Date,\n matcher: CalendarDateOnlyMatcher,\n context: ResolvedDateFnsContext\n): boolean {\n const from = normalizeMatcherDate(matcher.only.from, context);\n const to = normalizeMatcherDate(matcher.only.to, context);\n\n return isBefore(day, from) || isAfter(day, to);\n}\n\nfunction matchesDayOfWeek(day: Date, matcher: CalendarDayOfWeekMatcher): boolean {\n const days = Array.isArray(matcher.dayOfWeek) ? matcher.dayOfWeek : [matcher.dayOfWeek];\n\n return days.includes(getDay(day) as Day);\n}\n\nexport function normalizeMatchers(\n disabled?: CalendarMatcher | CalendarMatcher[]\n): CalendarMatcher[] {\n if (disabled === undefined) {\n return [];\n }\n\n return Array.isArray(disabled) ? disabled : [disabled];\n}\n\n/** Returns `true` when the date matches the matcher. */\nexport function matchesCalendarMatcher(\n date: Date,\n matcher: CalendarMatcher,\n context: ResolvedDateFnsContext\n): boolean {\n const day = normalizeMatcherDate(date, context);\n\n if (typeof matcher === \"boolean\") {\n return matcher;\n }\n\n if (matcher instanceof Date) {\n return isSameDay(day, matcher, context);\n }\n\n if (Array.isArray(matcher)) {\n return matcher.some((value) => isSameDay(day, value, context));\n }\n\n if (typeof matcher === \"function\") {\n return matcher(day);\n }\n\n if (isDateOnlyMatcher(matcher)) {\n return matchesDateOnly(day, matcher, context);\n }\n\n if (isInclusiveRangeMatcher(matcher)) {\n return matchesInclusiveRange(day, matcher, context);\n }\n\n if (isDateIntervalMatcher(matcher)) {\n const before = normalizeMatcherDate(matcher.before, context);\n const after = normalizeMatcherDate(matcher.after, context);\n\n return isAfter(day, after) && isBefore(day, before);\n }\n\n if (isDateBeforeMatcher(matcher)) {\n return isBefore(day, normalizeMatcherDate(matcher.before, context));\n }\n\n if (isDateAfterMatcher(matcher)) {\n return isAfter(day, normalizeMatcherDate(matcher.after, context));\n }\n\n if (isDayOfWeekMatcher(matcher)) {\n return matchesDayOfWeek(day, matcher);\n }\n\n return false;\n}\n\nexport function matchesAnyCalendarMatcher(\n date: Date,\n matchers: CalendarMatcher[],\n context: ResolvedDateFnsContext\n): boolean {\n return matchers.some((matcher) => matchesCalendarMatcher(date, matcher, context));\n}\n\nexport function isDateDisabledByRules(\n date: Date,\n minDate: Date | undefined,\n maxDate: Date | undefined,\n matchers: CalendarMatcher[],\n context: ResolvedDateFnsContext\n): boolean {\n const day = normalizeMatcherDate(date, context);\n\n if (minDate && isBefore(day, minDate)) {\n return true;\n }\n\n if (maxDate && isAfter(day, maxDate)) {\n return true;\n }\n\n return matchesAnyCalendarMatcher(day, matchers, context);\n}\n"],"mappings":"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","names":["isBefore","isSameDay","isWithinInterval","startOfDay","startOfDay","isSameDay","isBefore","isWithinInterval"]}
package/package.json ADDED
@@ -0,0 +1,59 @@
1
+ {
2
+ "name": "@ailuracode/alpine-calendar",
3
+ "version": "0.1.1",
4
+ "description": "Alpine.js calendar date logic powered by date-fns",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "ailuracode",
8
+ "publishConfig": {
9
+ "access": "public"
10
+ },
11
+ "repository": {
12
+ "type": "git",
13
+ "url": "git+https://github.com/ailuracode/alpine.git",
14
+ "directory": "packages/calendar"
15
+ },
16
+ "bugs": {
17
+ "url": "https://github.com/ailuracode/alpine/issues"
18
+ },
19
+ "homepage": "https://github.com/ailuracode/alpine/tree/master/packages/calendar#readme",
20
+ "files": [
21
+ "dist",
22
+ "README.md"
23
+ ],
24
+ "exports": {
25
+ ".": {
26
+ "types": "./dist/index.d.ts",
27
+ "default": "./dist/index.js"
28
+ },
29
+ "./global": {
30
+ "types": "./dist/global.d.ts"
31
+ }
32
+ },
33
+ "types": "./dist/global.d.ts",
34
+ "dependencies": {
35
+ "date-fns": "^4.1.0"
36
+ },
37
+ "peerDependencies": {
38
+ "alpinejs": "^3.0.0",
39
+ "@types/alpinejs": "^3.13.11"
40
+ },
41
+ "peerDependenciesMeta": {
42
+ "@types/alpinejs": {
43
+ "optional": true
44
+ }
45
+ },
46
+ "keywords": [
47
+ "alpinejs",
48
+ "alpine",
49
+ "plugin",
50
+ "calendar",
51
+ "date",
52
+ "date-fns",
53
+ "datepicker"
54
+ ],
55
+ "scripts": {
56
+ "build": "tsup src/index.ts --format esm --dts --clean --sourcemap --out-dir dist && cp src/global.d.ts dist/global.d.ts",
57
+ "test": "vitest run --config ../../vitest.config.js test"
58
+ }
59
+ }