@glob-ui/calendar 0.0.0-stage → 0.1.0
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 +21 -0
- package/README.md +16 -2
- package/dist/index.d.mts +92 -0
- package/dist/index.d.ts +92 -0
- package/dist/index.js +461 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +425 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +66 -3
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
"use client"
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __defProps = Object.defineProperties;
|
|
4
|
+
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
5
|
+
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
6
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
7
|
+
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
8
|
+
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
9
|
+
var __spreadValues = (a, b) => {
|
|
10
|
+
for (var prop in b || (b = {}))
|
|
11
|
+
if (__hasOwnProp.call(b, prop))
|
|
12
|
+
__defNormalProp(a, prop, b[prop]);
|
|
13
|
+
if (__getOwnPropSymbols)
|
|
14
|
+
for (var prop of __getOwnPropSymbols(b)) {
|
|
15
|
+
if (__propIsEnum.call(b, prop))
|
|
16
|
+
__defNormalProp(a, prop, b[prop]);
|
|
17
|
+
}
|
|
18
|
+
return a;
|
|
19
|
+
};
|
|
20
|
+
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
21
|
+
var __objRest = (source, exclude) => {
|
|
22
|
+
var target = {};
|
|
23
|
+
for (var prop in source)
|
|
24
|
+
if (__hasOwnProp.call(source, prop) && exclude.indexOf(prop) < 0)
|
|
25
|
+
target[prop] = source[prop];
|
|
26
|
+
if (source != null && __getOwnPropSymbols)
|
|
27
|
+
for (var prop of __getOwnPropSymbols(source)) {
|
|
28
|
+
if (exclude.indexOf(prop) < 0 && __propIsEnum.call(source, prop))
|
|
29
|
+
target[prop] = source[prop];
|
|
30
|
+
}
|
|
31
|
+
return target;
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
// src/calendar.tsx
|
|
35
|
+
import { forwardRef, useEffect, useId, useRef, useState } from "react";
|
|
36
|
+
import { cn } from "@glob-ui/utils";
|
|
37
|
+
import { useControllableState } from "@glob-ui/hooks";
|
|
38
|
+
|
|
39
|
+
// src/date.ts
|
|
40
|
+
var pad = (n, width = 2) => String(n).padStart(width, "0");
|
|
41
|
+
function toISODate(date) {
|
|
42
|
+
return `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`;
|
|
43
|
+
}
|
|
44
|
+
function parseISODate(iso) {
|
|
45
|
+
const [year, month, day] = iso.split("-").map(Number);
|
|
46
|
+
const date = new Date(2e3, 0, 1);
|
|
47
|
+
date.setFullYear(year, month - 1, day);
|
|
48
|
+
date.setHours(0, 0, 0, 0);
|
|
49
|
+
return date;
|
|
50
|
+
}
|
|
51
|
+
function addDays(iso, n) {
|
|
52
|
+
const d = parseISODate(iso);
|
|
53
|
+
return toISODate(new Date(d.getFullYear(), d.getMonth(), d.getDate() + n));
|
|
54
|
+
}
|
|
55
|
+
function addMonths(iso, n) {
|
|
56
|
+
const d = parseISODate(iso);
|
|
57
|
+
const first = new Date(d.getFullYear(), d.getMonth() + n, 1);
|
|
58
|
+
const lastDay = new Date(first.getFullYear(), first.getMonth() + 1, 0).getDate();
|
|
59
|
+
return toISODate(new Date(first.getFullYear(), first.getMonth(), Math.min(d.getDate(), lastDay)));
|
|
60
|
+
}
|
|
61
|
+
function isSameDay(a, b) {
|
|
62
|
+
return a === b;
|
|
63
|
+
}
|
|
64
|
+
function compareISODate(a, b) {
|
|
65
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
66
|
+
}
|
|
67
|
+
function todayISODate() {
|
|
68
|
+
return toISODate(/* @__PURE__ */ new Date());
|
|
69
|
+
}
|
|
70
|
+
function daysInMonth(key) {
|
|
71
|
+
const [year, month] = key.split("-").map(Number);
|
|
72
|
+
return new Date(year, month, 0).getDate();
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
// src/locale.ts
|
|
76
|
+
import { useSyncExternalStore } from "react";
|
|
77
|
+
function resolveLocale(locale) {
|
|
78
|
+
return locale != null ? locale : new Intl.DateTimeFormat().resolvedOptions().locale;
|
|
79
|
+
}
|
|
80
|
+
function defaultWeekStart(locale) {
|
|
81
|
+
var _a, _b, _c;
|
|
82
|
+
try {
|
|
83
|
+
const info = new Intl.Locale(resolveLocale(locale));
|
|
84
|
+
const firstDay = (_c = (_a = info.weekInfo) == null ? void 0 : _a.firstDay) != null ? _c : (_b = info.getWeekInfo) == null ? void 0 : _b.call(info).firstDay;
|
|
85
|
+
if (firstDay) return firstDay % 7;
|
|
86
|
+
} catch (e) {
|
|
87
|
+
}
|
|
88
|
+
return 0;
|
|
89
|
+
}
|
|
90
|
+
function weekdayNames(locale, weekStart) {
|
|
91
|
+
const short = new Intl.DateTimeFormat(locale, { weekday: "short" });
|
|
92
|
+
const long = new Intl.DateTimeFormat(locale, { weekday: "long" });
|
|
93
|
+
return Array.from({ length: 7 }, (_, i) => {
|
|
94
|
+
const date = new Date(2024, 0, 7 + (weekStart + i) % 7);
|
|
95
|
+
return { short: short.format(date), long: long.format(date) };
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
var subscribeNever = () => () => {
|
|
99
|
+
};
|
|
100
|
+
function useHydrated() {
|
|
101
|
+
return useSyncExternalStore(subscribeNever, () => true, () => false);
|
|
102
|
+
}
|
|
103
|
+
var FALLBACK_LOCALE = "en-US";
|
|
104
|
+
function useResolvedLocale(locale) {
|
|
105
|
+
const hydrated = useHydrated();
|
|
106
|
+
if (locale) return locale;
|
|
107
|
+
return hydrated ? resolveLocale() : FALLBACK_LOCALE;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
// src/calendar.tsx
|
|
111
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
112
|
+
var monthKey = (iso) => iso.slice(0, 7);
|
|
113
|
+
var monthStart = (key) => `${key}-01`;
|
|
114
|
+
var shiftMonth = (key, n) => monthKey(addMonths(monthStart(key), n));
|
|
115
|
+
function startOfWeek(iso, weekStart) {
|
|
116
|
+
const offset = (parseISODate(iso).getDay() - weekStart + 7) % 7;
|
|
117
|
+
return addDays(iso, -offset);
|
|
118
|
+
}
|
|
119
|
+
function buildWeeks(key, weekStart) {
|
|
120
|
+
const first = monthStart(key);
|
|
121
|
+
const offset = (parseISODate(first).getDay() - weekStart + 7) % 7;
|
|
122
|
+
const total = Math.ceil((offset + daysInMonth(key)) / 7) * 7;
|
|
123
|
+
const start = addDays(first, -offset);
|
|
124
|
+
const cells = Array.from({ length: total }, (_, i) => {
|
|
125
|
+
const iso = addDays(start, i);
|
|
126
|
+
return { iso, inMonth: monthKey(iso) === key };
|
|
127
|
+
});
|
|
128
|
+
const weeks = [];
|
|
129
|
+
for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7));
|
|
130
|
+
return weeks;
|
|
131
|
+
}
|
|
132
|
+
function dayClasses({
|
|
133
|
+
selected,
|
|
134
|
+
inRange,
|
|
135
|
+
rangeEdge,
|
|
136
|
+
today,
|
|
137
|
+
disabled,
|
|
138
|
+
outside
|
|
139
|
+
}) {
|
|
140
|
+
return cn(
|
|
141
|
+
"inline-flex size-9 items-center justify-center rounded-glob-md text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring motion-reduce:transition-none",
|
|
142
|
+
selected ? "bg-glob-primary font-medium text-glob-primary-foreground hover:opacity-90" : inRange ? cn("bg-glob-primary-light text-glob-text", !rangeEdge && "rounded-none") : "text-glob-text hover:bg-glob-surface-hover",
|
|
143
|
+
today && !selected && "font-semibold ring-1 ring-inset ring-glob-border",
|
|
144
|
+
// Muted, not faded: the text stays above 4.5:1. Disabled days are struck through.
|
|
145
|
+
outside && "text-glob-text-secondary",
|
|
146
|
+
disabled && "cursor-not-allowed text-glob-text-secondary line-through hover:bg-transparent"
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
var Calendar = forwardRef((props, ref) => {
|
|
150
|
+
var _b, _c;
|
|
151
|
+
const _a = props, {
|
|
152
|
+
mode = "single",
|
|
153
|
+
weekStartsOn,
|
|
154
|
+
locale: localeProp,
|
|
155
|
+
min,
|
|
156
|
+
max,
|
|
157
|
+
isDateDisabled,
|
|
158
|
+
month: monthProp,
|
|
159
|
+
defaultMonth,
|
|
160
|
+
onMonthChange,
|
|
161
|
+
numberOfMonths = 1,
|
|
162
|
+
showOutsideDays = true,
|
|
163
|
+
onSelectDay,
|
|
164
|
+
onKeyDown,
|
|
165
|
+
onPointerLeave,
|
|
166
|
+
className,
|
|
167
|
+
value: value,
|
|
168
|
+
defaultValue,
|
|
169
|
+
onChange,
|
|
170
|
+
allowDeselect = false
|
|
171
|
+
} = _a, rest = __objRest(_a, [
|
|
172
|
+
"mode",
|
|
173
|
+
"weekStartsOn",
|
|
174
|
+
"locale",
|
|
175
|
+
"min",
|
|
176
|
+
"max",
|
|
177
|
+
"isDateDisabled",
|
|
178
|
+
"month",
|
|
179
|
+
"defaultMonth",
|
|
180
|
+
"onMonthChange",
|
|
181
|
+
"numberOfMonths",
|
|
182
|
+
"showOutsideDays",
|
|
183
|
+
"onSelectDay",
|
|
184
|
+
"onKeyDown",
|
|
185
|
+
"onPointerLeave",
|
|
186
|
+
"className",
|
|
187
|
+
// Value props are read below, never spread onto the DOM.
|
|
188
|
+
"value",
|
|
189
|
+
"defaultValue",
|
|
190
|
+
"onChange",
|
|
191
|
+
"allowDeselect"
|
|
192
|
+
]);
|
|
193
|
+
const isRange = mode === "range";
|
|
194
|
+
const [singleValue, setSingleValue] = useControllableState(
|
|
195
|
+
isRange ? void 0 : value,
|
|
196
|
+
defaultValue != null ? defaultValue : null,
|
|
197
|
+
isRange ? void 0 : onChange
|
|
198
|
+
);
|
|
199
|
+
const [rangeValue, setRangeValue] = useControllableState(
|
|
200
|
+
isRange ? value : void 0,
|
|
201
|
+
defaultValue != null ? defaultValue : { from: null, to: null },
|
|
202
|
+
isRange ? onChange : void 0
|
|
203
|
+
);
|
|
204
|
+
const hydrated = useHydrated();
|
|
205
|
+
const locale = useResolvedLocale(localeProp);
|
|
206
|
+
const weekStart = weekStartsOn != null ? weekStartsOn : defaultWeekStart(locale);
|
|
207
|
+
const today = hydrated ? todayISODate() : null;
|
|
208
|
+
const initialFocus = isRange ? (_b = rangeValue.from) != null ? _b : todayISODate() : singleValue != null ? singleValue : todayISODate();
|
|
209
|
+
const baseId = useId();
|
|
210
|
+
const rootRef = useRef(null);
|
|
211
|
+
const shouldFocus = useRef(false);
|
|
212
|
+
const [visibleKey, setVisibleKey] = useControllableState(monthProp, defaultMonth != null ? defaultMonth : monthKey(initialFocus), onMonthChange);
|
|
213
|
+
const [focusISO, setFocusISO] = useState(initialFocus);
|
|
214
|
+
const [hoverISO, setHoverISO] = useState(null);
|
|
215
|
+
const minKey = min ? monthKey(min) : null;
|
|
216
|
+
const maxKey = max ? monthKey(max) : null;
|
|
217
|
+
const clampKey = (key) => minKey && key < minKey ? minKey : maxKey && key > maxKey ? maxKey : key;
|
|
218
|
+
const months = Array.from({ length: numberOfMonths }, (_, i) => shiftMonth(visibleKey, i));
|
|
219
|
+
const lastVisibleKey = months[months.length - 1];
|
|
220
|
+
const inBounds = (iso) => (!min || iso >= min) && (!max || iso <= max);
|
|
221
|
+
const isDisabledDay = (iso) => {
|
|
222
|
+
var _a2;
|
|
223
|
+
return !inBounds(iso) || ((_a2 = isDateDisabled == null ? void 0 : isDateDisabled(iso)) != null ? _a2 : false);
|
|
224
|
+
};
|
|
225
|
+
function showDay(iso) {
|
|
226
|
+
const key = monthKey(iso);
|
|
227
|
+
if (key < visibleKey) setVisibleKey(clampKey(key));
|
|
228
|
+
else if (key > lastVisibleKey) setVisibleKey(clampKey(shiftMonth(key, -(numberOfMonths - 1))));
|
|
229
|
+
}
|
|
230
|
+
function moveFocus(iso) {
|
|
231
|
+
if (!inBounds(iso)) return;
|
|
232
|
+
setFocusISO(iso);
|
|
233
|
+
showDay(iso);
|
|
234
|
+
shouldFocus.current = true;
|
|
235
|
+
}
|
|
236
|
+
useEffect(() => {
|
|
237
|
+
var _a2, _b2;
|
|
238
|
+
if (!shouldFocus.current) return;
|
|
239
|
+
shouldFocus.current = false;
|
|
240
|
+
(_b2 = (_a2 = rootRef.current) == null ? void 0 : _a2.querySelector(`[data-iso="${focusISO}"]`)) == null ? void 0 : _b2.focus();
|
|
241
|
+
});
|
|
242
|
+
function pick(iso) {
|
|
243
|
+
if (isDisabledDay(iso)) return;
|
|
244
|
+
if (!isRange) {
|
|
245
|
+
if (iso === singleValue) {
|
|
246
|
+
if (allowDeselect) setSingleValue(null);
|
|
247
|
+
else onSelectDay == null ? void 0 : onSelectDay(iso);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
250
|
+
setSingleValue(iso);
|
|
251
|
+
onSelectDay == null ? void 0 : onSelectDay(iso);
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
const { from, to } = rangeValue;
|
|
255
|
+
if (from === null || to !== null) {
|
|
256
|
+
setRangeValue({ from: iso, to: null });
|
|
257
|
+
} else if (compareISODate(iso, from) < 0) {
|
|
258
|
+
setRangeValue({ from: iso, to: from });
|
|
259
|
+
} else {
|
|
260
|
+
setRangeValue({ from, to: iso });
|
|
261
|
+
}
|
|
262
|
+
setHoverISO(null);
|
|
263
|
+
}
|
|
264
|
+
function onGridKeyDown(e) {
|
|
265
|
+
onKeyDown == null ? void 0 : onKeyDown(e);
|
|
266
|
+
if (e.defaultPrevented) return;
|
|
267
|
+
const iso = e.target.dataset.iso;
|
|
268
|
+
if (!iso) return;
|
|
269
|
+
let next;
|
|
270
|
+
switch (e.key) {
|
|
271
|
+
case "ArrowLeft":
|
|
272
|
+
next = addDays(iso, -1);
|
|
273
|
+
break;
|
|
274
|
+
case "ArrowRight":
|
|
275
|
+
next = addDays(iso, 1);
|
|
276
|
+
break;
|
|
277
|
+
case "ArrowUp":
|
|
278
|
+
next = addDays(iso, -7);
|
|
279
|
+
break;
|
|
280
|
+
case "ArrowDown":
|
|
281
|
+
next = addDays(iso, 7);
|
|
282
|
+
break;
|
|
283
|
+
case "Home":
|
|
284
|
+
next = startOfWeek(iso, weekStart);
|
|
285
|
+
break;
|
|
286
|
+
case "End":
|
|
287
|
+
next = addDays(startOfWeek(iso, weekStart), 6);
|
|
288
|
+
break;
|
|
289
|
+
case "PageUp":
|
|
290
|
+
next = addMonths(iso, e.shiftKey ? -12 : -1);
|
|
291
|
+
break;
|
|
292
|
+
case "PageDown":
|
|
293
|
+
next = addMonths(iso, e.shiftKey ? 12 : 1);
|
|
294
|
+
break;
|
|
295
|
+
default:
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
e.preventDefault();
|
|
299
|
+
moveFocus(next);
|
|
300
|
+
}
|
|
301
|
+
const tabStop = months.includes(monthKey(focusISO)) ? focusISO : monthStart(months[0]);
|
|
302
|
+
const previewEnd = isRange && rangeValue.from !== null && rangeValue.to === null ? hoverISO != null ? hoverISO : null : null;
|
|
303
|
+
const shadeFrom = isRange ? rangeValue.from : null;
|
|
304
|
+
const shadeTo = isRange ? (_c = rangeValue.to) != null ? _c : previewEnd : null;
|
|
305
|
+
const shadeStart = shadeFrom && shadeTo ? compareISODate(shadeFrom, shadeTo) <= 0 ? shadeFrom : shadeTo : null;
|
|
306
|
+
const shadeEnd = shadeFrom && shadeTo ? compareISODate(shadeFrom, shadeTo) <= 0 ? shadeTo : shadeFrom : null;
|
|
307
|
+
const dayFormat = new Intl.DateTimeFormat(locale, { dateStyle: "full" });
|
|
308
|
+
const headingFormat = new Intl.DateTimeFormat(locale, { month: "long", year: "numeric" });
|
|
309
|
+
const names = weekdayNames(locale, weekStart);
|
|
310
|
+
const prevDisabled = minKey !== null && visibleKey <= minKey;
|
|
311
|
+
const nextDisabled = maxKey !== null && lastVisibleKey >= maxKey;
|
|
312
|
+
return /* @__PURE__ */ jsxs(
|
|
313
|
+
"div",
|
|
314
|
+
__spreadProps(__spreadValues({
|
|
315
|
+
ref: (node) => {
|
|
316
|
+
rootRef.current = node;
|
|
317
|
+
if (typeof ref === "function") ref(node);
|
|
318
|
+
else if (ref) ref.current = node;
|
|
319
|
+
},
|
|
320
|
+
role: "group",
|
|
321
|
+
className: cn("flex flex-col gap-3 text-sm text-glob-text", className),
|
|
322
|
+
onKeyDown: onGridKeyDown
|
|
323
|
+
}, rest), {
|
|
324
|
+
onPointerLeave: (e) => {
|
|
325
|
+
onPointerLeave == null ? void 0 : onPointerLeave(e);
|
|
326
|
+
setHoverISO(null);
|
|
327
|
+
},
|
|
328
|
+
children: [
|
|
329
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
330
|
+
/* @__PURE__ */ jsx(
|
|
331
|
+
"button",
|
|
332
|
+
{
|
|
333
|
+
type: "button",
|
|
334
|
+
"aria-label": "Previous month",
|
|
335
|
+
disabled: prevDisabled,
|
|
336
|
+
onClick: () => setVisibleKey(clampKey(shiftMonth(visibleKey, -1))),
|
|
337
|
+
className: "inline-flex size-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring disabled:pointer-events-none disabled:opacity-40",
|
|
338
|
+
children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "h-4 w-4", children: /* @__PURE__ */ jsx("path", { d: "M15 18l-6-6 6-6" }) })
|
|
339
|
+
}
|
|
340
|
+
),
|
|
341
|
+
/* @__PURE__ */ jsx(
|
|
342
|
+
"button",
|
|
343
|
+
{
|
|
344
|
+
type: "button",
|
|
345
|
+
"aria-label": "Next month",
|
|
346
|
+
disabled: nextDisabled,
|
|
347
|
+
onClick: () => setVisibleKey(clampKey(shiftMonth(visibleKey, 1))),
|
|
348
|
+
className: "inline-flex size-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring disabled:pointer-events-none disabled:opacity-40",
|
|
349
|
+
children: /* @__PURE__ */ jsx("svg", { "aria-hidden": "true", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", className: "h-4 w-4", children: /* @__PURE__ */ jsx("path", { d: "M9 18l6-6-6-6" }) })
|
|
350
|
+
}
|
|
351
|
+
)
|
|
352
|
+
] }),
|
|
353
|
+
/* @__PURE__ */ jsx("div", { className: cn("flex gap-4", numberOfMonths === 2 ? "flex-col sm:flex-row" : "flex-col"), children: months.map((key) => {
|
|
354
|
+
const headingId = `${baseId}-${key}`;
|
|
355
|
+
const [year, monthNumber] = key.split("-").map(Number);
|
|
356
|
+
const heading = headingFormat.format(new Date(year, monthNumber - 1, 1));
|
|
357
|
+
return /* @__PURE__ */ jsxs("div", { className: "flex flex-col gap-2", children: [
|
|
358
|
+
/* @__PURE__ */ jsx("div", { id: headingId, "aria-live": "polite", className: "text-center text-sm font-semibold", children: heading }),
|
|
359
|
+
/* @__PURE__ */ jsxs("table", { role: "grid", "aria-labelledby": headingId, className: "border-separate border-spacing-0.5", children: [
|
|
360
|
+
/* @__PURE__ */ jsx("thead", { children: /* @__PURE__ */ jsx("tr", { role: "row", children: names.map((name) => /* @__PURE__ */ jsx("th", { role: "columnheader", scope: "col", "aria-label": name.long, className: "size-9 p-0 text-center text-xs font-medium text-glob-text-secondary", children: name.short }, name.long)) }) }),
|
|
361
|
+
/* @__PURE__ */ jsx("tbody", { children: buildWeeks(key, weekStart).map((week) => /* @__PURE__ */ jsx("tr", { role: "row", children: week.map(({ iso, inMonth }) => {
|
|
362
|
+
if (!inMonth && !showOutsideDays) {
|
|
363
|
+
return /* @__PURE__ */ jsx("td", { role: "gridcell", className: "size-9 p-0" }, iso);
|
|
364
|
+
}
|
|
365
|
+
const day = Number(iso.slice(8));
|
|
366
|
+
const disabled = isDisabledDay(iso);
|
|
367
|
+
const selected = isRange ? iso === rangeValue.from || iso === rangeValue.to : iso === singleValue;
|
|
368
|
+
const inShade = shadeStart !== null && shadeEnd !== null && iso >= shadeStart && iso <= shadeEnd;
|
|
369
|
+
const rangeEdge = iso === shadeStart || iso === shadeEnd;
|
|
370
|
+
const isStop = inMonth && iso === tabStop;
|
|
371
|
+
return /* @__PURE__ */ jsx("td", { role: "gridcell", "aria-selected": selected, className: "p-0", children: /* @__PURE__ */ jsx(
|
|
372
|
+
"button",
|
|
373
|
+
{
|
|
374
|
+
type: "button",
|
|
375
|
+
"data-iso": iso,
|
|
376
|
+
"data-autofocus": isStop ? "" : void 0,
|
|
377
|
+
tabIndex: inMonth && isStop ? 0 : -1,
|
|
378
|
+
"aria-label": dayFormat.format(parseISODate(iso)),
|
|
379
|
+
"aria-current": iso === today ? "date" : void 0,
|
|
380
|
+
"aria-disabled": disabled || void 0,
|
|
381
|
+
onClick: () => {
|
|
382
|
+
if (!inMonth) {
|
|
383
|
+
setFocusISO(iso);
|
|
384
|
+
setVisibleKey(clampKey(monthKey(iso)));
|
|
385
|
+
return;
|
|
386
|
+
}
|
|
387
|
+
setFocusISO(iso);
|
|
388
|
+
pick(iso);
|
|
389
|
+
},
|
|
390
|
+
onFocus: () => {
|
|
391
|
+
setFocusISO(iso);
|
|
392
|
+
if (isRange) setHoverISO(iso);
|
|
393
|
+
},
|
|
394
|
+
onPointerEnter: () => {
|
|
395
|
+
if (isRange && rangeValue.from !== null && rangeValue.to === null) setHoverISO(iso);
|
|
396
|
+
},
|
|
397
|
+
className: dayClasses({ selected, inRange: inShade, rangeEdge, today: iso === today, disabled, outside: !inMonth }),
|
|
398
|
+
children: day
|
|
399
|
+
}
|
|
400
|
+
) }, iso);
|
|
401
|
+
}) }, week[0].iso)) })
|
|
402
|
+
] })
|
|
403
|
+
] }, key);
|
|
404
|
+
}) })
|
|
405
|
+
]
|
|
406
|
+
})
|
|
407
|
+
);
|
|
408
|
+
});
|
|
409
|
+
Calendar.displayName = "Calendar";
|
|
410
|
+
export {
|
|
411
|
+
Calendar,
|
|
412
|
+
FALLBACK_LOCALE,
|
|
413
|
+
addDays,
|
|
414
|
+
addMonths,
|
|
415
|
+
compareISODate,
|
|
416
|
+
defaultWeekStart,
|
|
417
|
+
isSameDay,
|
|
418
|
+
parseISODate,
|
|
419
|
+
resolveLocale,
|
|
420
|
+
toISODate,
|
|
421
|
+
todayISODate,
|
|
422
|
+
useHydrated,
|
|
423
|
+
useResolvedLocale
|
|
424
|
+
};
|
|
425
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/calendar.tsx","../src/date.ts","../src/locale.ts"],"sourcesContent":["\"use client\"\n\nimport { forwardRef, useEffect, useId, useRef, useState } from \"react\"\nimport { cn } from \"@glob-ui/utils\"\nimport { useControllableState } from \"@glob-ui/hooks\"\nimport { addDays, addMonths, compareISODate, daysInMonth, parseISODate, todayISODate } from \"./date\"\nimport { defaultWeekStart, useHydrated, useResolvedLocale, weekdayNames } from \"./locale\"\n\nexport interface DateRange {\n from: string | null\n to: string | null\n}\n\ninterface CalendarBaseProps extends Omit<React.HTMLAttributes<HTMLDivElement>, \"defaultValue\" | \"onChange\"> {\n /** The first day of the week, 0 (Sunday) to 6. Default: from the locale. */\n weekStartsOn?: 0 | 1 | 2 | 3 | 4 | 5 | 6\n /**\n * BCP 47 tag, for example \"es-ES\". Default: the browser's locale. Server-rendered pages show \"en-US\" until\n * hydration, then switch; pass `locale` to avoid the switch.\n */\n locale?: string\n /** Earliest selectable day, \"YYYY-MM-DD\". Days before it are disabled and navigation stops before its month. */\n min?: string\n /** Latest selectable day, \"YYYY-MM-DD\". Days after it are disabled and navigation stops after its month. */\n max?: string\n /** Disables more days. Disabled days can still receive focus, but cannot be selected. */\n isDateDisabled?: (iso: string) => boolean\n /** The visible month, \"YYYY-MM\" (controlled). */\n month?: string\n defaultMonth?: string\n onMonthChange?: (month: string) => void\n /** Shows one month, or two side by side (stacked on small screens). */\n numberOfMonths?: 1 | 2\n /** Muted days from the adjacent months. Not selectable; clicking one moves to its month. Default true. */\n showOutsideDays?: boolean\n /** Called when the user picks an enabled day, even when it is already the selected one. Used by DatePicker to close. */\n onSelectDay?: (iso: string) => void\n}\n\nexport interface CalendarSingleProps extends CalendarBaseProps {\n mode?: \"single\"\n value?: string | null\n defaultValue?: string | null\n onChange?: (iso: string | null) => void\n /** Clicking the selected day again clears it. Default false. */\n allowDeselect?: boolean\n}\n\nexport interface CalendarRangeProps extends CalendarBaseProps {\n mode: \"range\"\n value?: DateRange\n defaultValue?: DateRange\n onChange?: (range: DateRange) => void\n}\n\nexport type CalendarProps = CalendarSingleProps | CalendarRangeProps\n\nconst monthKey = (iso: string) => iso.slice(0, 7)\nconst monthStart = (key: string) => `${key}-01`\nconst shiftMonth = (key: string, n: number) => monthKey(addMonths(monthStart(key), n))\n\n/** Start of the week that contains `iso`. */\nfunction startOfWeek(iso: string, weekStart: number) {\n const offset = (parseISODate(iso).getDay() - weekStart + 7) % 7\n return addDays(iso, -offset)\n}\n\ninterface Cell {\n iso: string\n inMonth: boolean\n}\n\n/** The weeks of a month, as rows of seven cells. Cells from the adjacent months are marked `inMonth: false`. */\nfunction buildWeeks(key: string, weekStart: number): Cell[][] {\n const first = monthStart(key)\n const offset = (parseISODate(first).getDay() - weekStart + 7) % 7\n const total = Math.ceil((offset + daysInMonth(key)) / 7) * 7\n const start = addDays(first, -offset)\n const cells = Array.from({ length: total }, (_, i) => {\n const iso = addDays(start, i)\n return { iso, inMonth: monthKey(iso) === key }\n })\n const weeks: Cell[][] = []\n for (let i = 0; i < cells.length; i += 7) weeks.push(cells.slice(i, i + 7))\n return weeks\n}\n\n/** Classes of one day button. Exported for DatePicker's styling of the same states. */\nfunction dayClasses({\n selected,\n inRange,\n rangeEdge,\n today,\n disabled,\n outside,\n}: {\n selected: boolean\n inRange: boolean\n rangeEdge: boolean\n today: boolean\n disabled: boolean\n outside: boolean\n}) {\n return cn(\n \"inline-flex size-9 items-center justify-center rounded-glob-md text-sm transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring motion-reduce:transition-none\",\n selected\n ? \"bg-glob-primary font-medium text-glob-primary-foreground hover:opacity-90\"\n : inRange\n ? cn(\"bg-glob-primary-light text-glob-text\", !rangeEdge && \"rounded-none\")\n : \"text-glob-text hover:bg-glob-surface-hover\",\n today && !selected && \"font-semibold ring-1 ring-inset ring-glob-border\",\n // Muted, not faded: the text stays above 4.5:1. Disabled days are struck through.\n outside && \"text-glob-text-secondary\",\n disabled && \"cursor-not-allowed text-glob-text-secondary line-through hover:bg-transparent\"\n )\n}\n\n/**\n * A month grid for picking one day, or a range of days. Values are \"YYYY-MM-DD\" strings.\n * Follows the WAI-ARIA date picker grid: one tab stop, arrows move by day and week, PageUp and PageDown by month.\n */\nconst Calendar = forwardRef<HTMLDivElement, CalendarProps>((props, ref) => {\n const {\n mode = \"single\",\n weekStartsOn,\n locale: localeProp,\n min,\n max,\n isDateDisabled,\n month: monthProp,\n defaultMonth,\n onMonthChange,\n numberOfMonths = 1,\n showOutsideDays = true,\n onSelectDay,\n onKeyDown,\n onPointerLeave,\n className,\n // Value props are read below, never spread onto the DOM.\n value,\n defaultValue,\n onChange,\n allowDeselect = false,\n ...rest\n } = props as CalendarProps & { allowDeselect?: boolean }\n const isRange = mode === \"range\"\n const [singleValue, setSingleValue] = useControllableState<string | null>(\n isRange ? undefined : (value as string | null | undefined),\n (defaultValue as string | null | undefined) ?? null,\n isRange ? undefined : (onChange as ((next: string | null) => void) | undefined)\n )\n const [rangeValue, setRangeValue] = useControllableState<DateRange>(\n isRange ? (value as DateRange | undefined) : undefined,\n (defaultValue as DateRange | undefined) ?? { from: null, to: null },\n isRange ? (onChange as ((next: DateRange) => void) | undefined) : undefined\n )\n\n // Locale and today depend on the browser: before hydration they match the server render (see useResolvedLocale).\n const hydrated = useHydrated()\n const locale = useResolvedLocale(localeProp)\n const weekStart = weekStartsOn ?? defaultWeekStart(locale)\n const today = hydrated ? todayISODate() : null\n const initialFocus = isRange ? (rangeValue.from ?? todayISODate()) : (singleValue ?? todayISODate())\n const baseId = useId()\n const rootRef = useRef<HTMLDivElement>(null)\n const shouldFocus = useRef(false)\n\n const [visibleKey, setVisibleKey] = useControllableState<string>(monthProp, defaultMonth ?? monthKey(initialFocus), onMonthChange)\n const [focusISO, setFocusISO] = useState(initialFocus)\n const [hoverISO, setHoverISO] = useState<string | null>(null)\n\n const minKey = min ? monthKey(min) : null\n const maxKey = max ? monthKey(max) : null\n const clampKey = (key: string) => (minKey && key < minKey ? minKey : maxKey && key > maxKey ? maxKey : key)\n const months = Array.from({ length: numberOfMonths }, (_, i) => shiftMonth(visibleKey, i))\n const lastVisibleKey = months[months.length - 1]\n\n const inBounds = (iso: string) => (!min || iso >= min) && (!max || iso <= max)\n const isDisabledDay = (iso: string) => !inBounds(iso) || (isDateDisabled?.(iso) ?? false)\n\n // Keeps `iso` on screen by moving the visible month, if it is off screen.\n function showDay(iso: string) {\n const key = monthKey(iso)\n if (key < visibleKey) setVisibleKey(clampKey(key))\n else if (key > lastVisibleKey) setVisibleKey(clampKey(shiftMonth(key, -(numberOfMonths - 1))))\n }\n\n function moveFocus(iso: string) {\n if (!inBounds(iso)) return\n setFocusISO(iso)\n showDay(iso)\n shouldFocus.current = true\n }\n\n // After a keyboard move, the new day button takes DOM focus once it is rendered.\n useEffect(() => {\n if (!shouldFocus.current) return\n shouldFocus.current = false\n rootRef.current?.querySelector<HTMLElement>(`[data-iso=\"${focusISO}\"]`)?.focus()\n })\n\n function pick(iso: string) {\n if (isDisabledDay(iso)) return\n if (!isRange) {\n if (iso === singleValue) {\n if (allowDeselect) setSingleValue(null)\n else onSelectDay?.(iso)\n return\n }\n setSingleValue(iso)\n onSelectDay?.(iso)\n return\n }\n const { from, to } = rangeValue\n if (from === null || to !== null) {\n setRangeValue({ from: iso, to: null })\n } else if (compareISODate(iso, from) < 0) {\n // A second pick before the first one swaps them.\n setRangeValue({ from: iso, to: from })\n } else {\n setRangeValue({ from, to: iso })\n }\n setHoverISO(null)\n }\n\n function onGridKeyDown(e: React.KeyboardEvent<HTMLDivElement>) {\n onKeyDown?.(e)\n if (e.defaultPrevented) return\n const iso = (e.target as HTMLElement).dataset.iso\n if (!iso) return\n let next: string\n switch (e.key) {\n case \"ArrowLeft\":\n next = addDays(iso, -1)\n break\n case \"ArrowRight\":\n next = addDays(iso, 1)\n break\n case \"ArrowUp\":\n next = addDays(iso, -7)\n break\n case \"ArrowDown\":\n next = addDays(iso, 7)\n break\n case \"Home\":\n next = startOfWeek(iso, weekStart)\n break\n case \"End\":\n next = addDays(startOfWeek(iso, weekStart), 6)\n break\n case \"PageUp\":\n next = addMonths(iso, e.shiftKey ? -12 : -1)\n break\n case \"PageDown\":\n next = addMonths(iso, e.shiftKey ? 12 : 1)\n break\n default:\n return\n }\n e.preventDefault()\n moveFocus(next)\n }\n\n // The one tab stop: the focus day when it is on screen, else the first day of the first month.\n const tabStop = months.includes(monthKey(focusISO)) ? focusISO : monthStart(months[0])\n\n // Range shading: the picked range, or the preview from the first pick to the hovered day.\n const previewEnd = isRange && rangeValue.from !== null && rangeValue.to === null ? (hoverISO ?? null) : null\n const shadeFrom = isRange ? rangeValue.from : null\n const shadeTo = isRange ? (rangeValue.to ?? previewEnd) : null\n const shadeStart = shadeFrom && shadeTo ? (compareISODate(shadeFrom, shadeTo) <= 0 ? shadeFrom : shadeTo) : null\n const shadeEnd = shadeFrom && shadeTo ? (compareISODate(shadeFrom, shadeTo) <= 0 ? shadeTo : shadeFrom) : null\n\n const dayFormat = new Intl.DateTimeFormat(locale, { dateStyle: \"full\" })\n const headingFormat = new Intl.DateTimeFormat(locale, { month: \"long\", year: \"numeric\" })\n const names = weekdayNames(locale, weekStart)\n const prevDisabled = minKey !== null && visibleKey <= minKey\n const nextDisabled = maxKey !== null && lastVisibleKey >= maxKey\n\n return (\n <div\n ref={(node) => {\n rootRef.current = node\n if (typeof ref === \"function\") ref(node)\n else if (ref) ref.current = node\n }}\n role=\"group\"\n className={cn(\"flex flex-col gap-3 text-sm text-glob-text\", className)}\n onKeyDown={onGridKeyDown}\n {...rest}\n onPointerLeave={(e) => {\n onPointerLeave?.(e)\n setHoverISO(null)\n }}\n >\n <div className=\"flex items-center justify-between\">\n <button\n type=\"button\"\n aria-label=\"Previous month\"\n disabled={prevDisabled}\n onClick={() => setVisibleKey(clampKey(shiftMonth(visibleKey, -1)))}\n className=\"inline-flex size-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring disabled:pointer-events-none disabled:opacity-40\"\n >\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"h-4 w-4\">\n <path d=\"M15 18l-6-6 6-6\" />\n </svg>\n </button>\n <button\n type=\"button\"\n aria-label=\"Next month\"\n disabled={nextDisabled}\n onClick={() => setVisibleKey(clampKey(shiftMonth(visibleKey, 1)))}\n className=\"inline-flex size-8 items-center justify-center rounded-glob-sm text-glob-text-secondary transition-colors hover:bg-glob-surface-hover hover:text-glob-text focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-glob-ring disabled:pointer-events-none disabled:opacity-40\"\n >\n <svg aria-hidden=\"true\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" strokeWidth=\"2\" className=\"h-4 w-4\">\n <path d=\"M9 18l6-6-6-6\" />\n </svg>\n </button>\n </div>\n\n <div className={cn(\"flex gap-4\", numberOfMonths === 2 ? \"flex-col sm:flex-row\" : \"flex-col\")}>\n {months.map((key) => {\n const headingId = `${baseId}-${key}`\n const [year, monthNumber] = key.split(\"-\").map(Number)\n const heading = headingFormat.format(new Date(year, monthNumber - 1, 1))\n return (\n <div key={key} className=\"flex flex-col gap-2\">\n <div id={headingId} aria-live=\"polite\" className=\"text-center text-sm font-semibold\">\n {heading}\n </div>\n <table role=\"grid\" aria-labelledby={headingId} className=\"border-separate border-spacing-0.5\">\n <thead>\n <tr role=\"row\">\n {names.map((name) => (\n <th key={name.long} role=\"columnheader\" scope=\"col\" aria-label={name.long} className=\"size-9 p-0 text-center text-xs font-medium text-glob-text-secondary\">\n {name.short}\n </th>\n ))}\n </tr>\n </thead>\n <tbody>\n {buildWeeks(key, weekStart).map((week) => (\n <tr key={week[0].iso} role=\"row\">\n {week.map(({ iso, inMonth }) => {\n if (!inMonth && !showOutsideDays) {\n return <td key={iso} role=\"gridcell\" className=\"size-9 p-0\" />\n }\n const day = Number(iso.slice(8))\n const disabled = isDisabledDay(iso)\n const selected = isRange ? iso === rangeValue.from || iso === rangeValue.to : iso === singleValue\n const inShade = shadeStart !== null && shadeEnd !== null && iso >= shadeStart && iso <= shadeEnd\n const rangeEdge = iso === shadeStart || iso === shadeEnd\n const isStop = inMonth && iso === tabStop\n return (\n <td key={iso} role=\"gridcell\" aria-selected={selected} className=\"p-0\">\n <button\n type=\"button\"\n data-iso={iso}\n // The tab stop is also what a DatePicker focuses when it opens.\n data-autofocus={isStop ? \"\" : undefined}\n tabIndex={inMonth && isStop ? 0 : -1}\n aria-label={dayFormat.format(parseISODate(iso))}\n aria-current={iso === today ? \"date\" : undefined}\n aria-disabled={disabled || undefined}\n onClick={() => {\n if (!inMonth) {\n setFocusISO(iso)\n setVisibleKey(clampKey(monthKey(iso)))\n return\n }\n setFocusISO(iso)\n pick(iso)\n }}\n onFocus={() => {\n setFocusISO(iso)\n if (isRange) setHoverISO(iso)\n }}\n onPointerEnter={() => {\n if (isRange && rangeValue.from !== null && rangeValue.to === null) setHoverISO(iso)\n }}\n className={dayClasses({ selected, inRange: inShade, rangeEdge, today: iso === today, disabled, outside: !inMonth })}\n >\n {day}\n </button>\n </td>\n )\n })}\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )\n })}\n </div>\n </div>\n )\n})\nCalendar.displayName = \"Calendar\"\n\nexport { Calendar }\n","// ISO \"YYYY-MM-DD\" helpers. Values are plain strings, so they serialize and compare without time zones.\n// Every calculation uses local calendar fields (`new Date(y, m, d)`), never `toISOString` and never\n// `+ 86400000`, so daylight saving changes do not shift a day.\n\nconst pad = (n: number, width = 2) => String(n).padStart(width, \"0\")\n\n/** The local calendar date of `date` as \"YYYY-MM-DD\". */\nexport function toISODate(date: Date): string {\n return `${pad(date.getFullYear(), 4)}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}`\n}\n\n/** Local midnight of an ISO date. */\nexport function parseISODate(iso: string): Date {\n const [year, month, day] = iso.split(\"-\").map(Number)\n const date = new Date(2000, 0, 1)\n date.setFullYear(year, month - 1, day)\n date.setHours(0, 0, 0, 0)\n return date\n}\n\n/** The date `n` days after `iso` (negative goes back). */\nexport function addDays(iso: string, n: number): string {\n const d = parseISODate(iso)\n return toISODate(new Date(d.getFullYear(), d.getMonth(), d.getDate() + n))\n}\n\n/**\n * The date `n` months after `iso`, on the same day of the month. When that day does not exist in the\n * target month it is clamped to the last day: Jan 31 + 1 month is Feb 28 (or 29 in a leap year).\n */\nexport function addMonths(iso: string, n: number): string {\n const d = parseISODate(iso)\n const first = new Date(d.getFullYear(), d.getMonth() + n, 1)\n const lastDay = new Date(first.getFullYear(), first.getMonth() + 1, 0).getDate()\n return toISODate(new Date(first.getFullYear(), first.getMonth(), Math.min(d.getDate(), lastDay)))\n}\n\n/** True when both ISO dates are the same day. */\nexport function isSameDay(a: string, b: string): boolean {\n return a === b\n}\n\n/** -1, 0 or 1, for sorting ISO dates. */\nexport function compareISODate(a: string, b: string): -1 | 0 | 1 {\n return a < b ? -1 : a > b ? 1 : 0\n}\n\n/** Today's local date as \"YYYY-MM-DD\". */\nexport function todayISODate(): string {\n return toISODate(new Date())\n}\n\n/** The number of days in the month of `iso` (or of a \"YYYY-MM\" key). */\nexport function daysInMonth(key: string): number {\n const [year, month] = key.split(\"-\").map(Number)\n return new Date(year, month, 0).getDate()\n}\n","import { useSyncExternalStore } from \"react\"\n\n/** The locale to format with: the one passed in, else the runtime default. */\nexport function resolveLocale(locale?: string): string {\n return locale ?? new Intl.DateTimeFormat().resolvedOptions().locale\n}\n\n/**\n * The first day of the week for a locale, 0 (Sunday) to 6 (Saturday). From `Intl.Locale` week data\n * when the runtime has it (for example es-ES starts on Monday), otherwise Sunday.\n */\nexport function defaultWeekStart(locale?: string): number {\n try {\n const info = new Intl.Locale(resolveLocale(locale)) as Intl.Locale & {\n weekInfo?: { firstDay: number }\n getWeekInfo?: () => { firstDay: number }\n }\n const firstDay = info.weekInfo?.firstDay ?? info.getWeekInfo?.().firstDay\n // Intl numbers the days 1 (Monday) to 7 (Sunday).\n if (firstDay) return firstDay % 7\n } catch {\n // Unknown locale tag or no Intl.Locale: fall through to Sunday.\n }\n return 0\n}\n\n/** Short and long weekday names for the seven columns, starting at `weekStart`. */\nexport function weekdayNames(locale: string, weekStart: number) {\n const short = new Intl.DateTimeFormat(locale, { weekday: \"short\" })\n const long = new Intl.DateTimeFormat(locale, { weekday: \"long\" })\n return Array.from({ length: 7 }, (_, i) => {\n // 2024-01-07 is a Sunday: its getDay() is 0, so day (weekStart + i) % 7 lands on the right column.\n const date = new Date(2024, 0, 7 + ((weekStart + i) % 7))\n return { short: short.format(date), long: long.format(date) }\n })\n}\n\nconst subscribeNever = () => () => {}\n\n/**\n * False on the server and during hydration, true after. Lets values that depend on the browser\n * (its locale, today's date) render the same HTML on both sides, then update on the client.\n */\nexport function useHydrated(): boolean {\n return useSyncExternalStore(subscribeNever, () => true, () => false)\n}\n\n/** Locale used before hydration when none is passed, so server and client HTML match. */\nexport const FALLBACK_LOCALE = \"en-US\"\n\n/**\n * The locale to render with. A passed locale is used as is. Without one, the server and the first\n * client render use `FALLBACK_LOCALE`, then the browser's locale takes over. Pass `locale` in\n * server-rendered apps to avoid that switch.\n */\nexport function useResolvedLocale(locale?: string): string {\n const hydrated = useHydrated()\n if (locale) return locale\n return hydrated ? resolveLocale() : FALLBACK_LOCALE\n}\n"],"mappings":"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","names":["_a","_b"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,69 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@glob-ui/calendar",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"main": "./dist/index.js",
|
|
5
|
+
"module": "./dist/index.mjs",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"import": {
|
|
10
|
+
"types": "./dist/index.d.mts",
|
|
11
|
+
"default": "./dist/index.mjs"
|
|
12
|
+
},
|
|
13
|
+
"require": {
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"default": "./dist/index.js"
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
"./package.json": "./package.json"
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist/",
|
|
22
|
+
"LICENSE",
|
|
23
|
+
"README.md"
|
|
24
|
+
],
|
|
25
|
+
"peerDependencies": {
|
|
26
|
+
"react": "^19"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@glob-ui/hooks": "0.1.0",
|
|
30
|
+
"@glob-ui/utils": "0.1.0"
|
|
31
|
+
},
|
|
32
|
+
"devDependencies": {
|
|
33
|
+
"react-dom": "^19",
|
|
34
|
+
"tsup": "^8.5.1"
|
|
35
|
+
},
|
|
36
|
+
"description": "A month grid for picking one day or a range of days. Values are ISO date strings (\"YYYY-MM-DD\"), so they serialize and compare without time zones.",
|
|
37
|
+
"keywords": [
|
|
38
|
+
"react",
|
|
39
|
+
"glob-ui",
|
|
40
|
+
"components",
|
|
41
|
+
"accessible",
|
|
42
|
+
"tailwind",
|
|
43
|
+
"calendar"
|
|
44
|
+
],
|
|
45
|
+
"license": "MIT",
|
|
46
|
+
"author": "Kevin Martínez E",
|
|
47
|
+
"repository": {
|
|
48
|
+
"type": "git",
|
|
49
|
+
"url": "git+https://github.com/kevin-martineze/GlobUI.git",
|
|
50
|
+
"directory": "packages/calendar"
|
|
51
|
+
},
|
|
52
|
+
"homepage": "https://github.com/kevin-martineze/GlobUI#readme",
|
|
53
|
+
"bugs": {
|
|
54
|
+
"url": "https://github.com/kevin-martineze/GlobUI/issues"
|
|
55
|
+
},
|
|
56
|
+
"publishConfig": {
|
|
57
|
+
"access": "public",
|
|
58
|
+
"provenance": true
|
|
59
|
+
},
|
|
60
|
+
"sideEffects": false,
|
|
61
|
+
"type": "commonjs",
|
|
62
|
+
"engines": {
|
|
63
|
+
"node": ">=18.18"
|
|
64
|
+
},
|
|
65
|
+
"scripts": {
|
|
66
|
+
"build": "tsup",
|
|
67
|
+
"dev": "tsup --watch --no-clean"
|
|
68
|
+
}
|
|
6
69
|
}
|