@rufous/ui 0.3.1 → 0.3.12
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/dist/main.cjs +200 -57
- package/dist/main.css +7 -0
- package/dist/main.d.cts +14 -0
- package/dist/main.d.ts +14 -0
- package/dist/main.js +200 -57
- package/package.json +2 -2
package/dist/main.cjs
CHANGED
|
@@ -3016,6 +3016,11 @@ var parseDisplay = (str, fmt = "MM/DD/YYYY") => {
|
|
|
3016
3016
|
};
|
|
3017
3017
|
var isoToDate = (iso) => {
|
|
3018
3018
|
if (!iso) return null;
|
|
3019
|
+
if (iso.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(iso)) {
|
|
3020
|
+
const d2 = new Date(iso);
|
|
3021
|
+
if (isNaN(d2.getTime())) return null;
|
|
3022
|
+
return new Date(d2.getFullYear(), d2.getMonth(), d2.getDate());
|
|
3023
|
+
}
|
|
3019
3024
|
const [datePart] = iso.split("T");
|
|
3020
3025
|
const [y, mo, d] = datePart.split("-").map(Number);
|
|
3021
3026
|
if (!y || !mo || !d) return null;
|
|
@@ -3028,7 +3033,7 @@ var today = () => {
|
|
|
3028
3033
|
var isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
3029
3034
|
var normaliseBoundary = (d) => {
|
|
3030
3035
|
if (!d) return null;
|
|
3031
|
-
const base = d instanceof Date ? d : isoToDate(
|
|
3036
|
+
const base = d instanceof Date ? d : isoToDate(d);
|
|
3032
3037
|
if (!base) return null;
|
|
3033
3038
|
return new Date(base.getFullYear(), base.getMonth(), base.getDate());
|
|
3034
3039
|
};
|
|
@@ -3184,6 +3189,24 @@ var SpinnerPanel = ({
|
|
|
3184
3189
|
},
|
|
3185
3190
|
"PM"
|
|
3186
3191
|
)));
|
|
3192
|
+
var formatViewsDisplay = (d, views) => {
|
|
3193
|
+
if (!views.includes("day") && !views.includes("month")) return String(d.getFullYear());
|
|
3194
|
+
if (!views.includes("day")) return `${MONTHS_SHORT[d.getMonth()]} ${d.getFullYear()}`;
|
|
3195
|
+
return "";
|
|
3196
|
+
};
|
|
3197
|
+
var parseYearDisplay = (str) => {
|
|
3198
|
+
const y = parseInt(str.trim(), 10);
|
|
3199
|
+
if (isNaN(y) || y < 1e3 || y > 9999) return null;
|
|
3200
|
+
return new Date(y, 0, 1);
|
|
3201
|
+
};
|
|
3202
|
+
var parseMonthYearDisplay = (str) => {
|
|
3203
|
+
const parts = str.trim().split(/\s+/);
|
|
3204
|
+
if (parts.length < 2) return null;
|
|
3205
|
+
const mm = parseMonthName(parts[0]);
|
|
3206
|
+
const yyyy = parseInt(parts[parts.length - 1], 10);
|
|
3207
|
+
if (mm < 0 || isNaN(yyyy) || yyyy < 1e3) return null;
|
|
3208
|
+
return new Date(yyyy, mm, 1);
|
|
3209
|
+
};
|
|
3187
3210
|
var CalendarBody = ({
|
|
3188
3211
|
viewMonth,
|
|
3189
3212
|
viewYear,
|
|
@@ -3196,18 +3219,48 @@ var CalendarBody = ({
|
|
|
3196
3219
|
onMonthSelect,
|
|
3197
3220
|
onYearSelect,
|
|
3198
3221
|
minDate,
|
|
3199
|
-
maxDate
|
|
3222
|
+
maxDate,
|
|
3223
|
+
views,
|
|
3224
|
+
onFinalMonthSelect,
|
|
3225
|
+
onFinalYearSelect
|
|
3200
3226
|
}) => {
|
|
3201
|
-
const
|
|
3202
|
-
const
|
|
3203
|
-
const
|
|
3227
|
+
const hasDayView = views.includes("day");
|
|
3228
|
+
const hasMonthView = views.includes("month");
|
|
3229
|
+
const hasYearView = views.includes("year");
|
|
3230
|
+
const [pickerView, setPickerView] = (0, import_react21.useState)(() => {
|
|
3231
|
+
if (!hasDayView && !hasMonthView) return "year";
|
|
3232
|
+
if (!hasDayView) return "month";
|
|
3233
|
+
return "calendar";
|
|
3234
|
+
});
|
|
3235
|
+
const handleMonthClick = () => {
|
|
3236
|
+
if (!hasMonthView || !hasDayView) return;
|
|
3237
|
+
setPickerView((v) => v === "month" ? "calendar" : "month");
|
|
3238
|
+
};
|
|
3239
|
+
const handleYearClick = () => {
|
|
3240
|
+
if (!hasYearView) return;
|
|
3241
|
+
if (pickerView === "year") {
|
|
3242
|
+
setPickerView(hasDayView ? "calendar" : "month");
|
|
3243
|
+
} else {
|
|
3244
|
+
setPickerView("year");
|
|
3245
|
+
}
|
|
3246
|
+
};
|
|
3204
3247
|
const handleMonthPick = (month) => {
|
|
3205
3248
|
onMonthSelect(month);
|
|
3206
|
-
|
|
3249
|
+
if (hasDayView) {
|
|
3250
|
+
setPickerView("calendar");
|
|
3251
|
+
} else {
|
|
3252
|
+
onFinalMonthSelect?.(month, viewYear);
|
|
3253
|
+
}
|
|
3207
3254
|
};
|
|
3208
3255
|
const handleYearPick = (year) => {
|
|
3209
3256
|
onYearSelect(year);
|
|
3210
|
-
|
|
3257
|
+
if (!hasDayView && !hasMonthView) {
|
|
3258
|
+
onFinalYearSelect?.(year);
|
|
3259
|
+
} else if (hasMonthView) {
|
|
3260
|
+
setPickerView("month");
|
|
3261
|
+
} else {
|
|
3262
|
+
setPickerView("calendar");
|
|
3263
|
+
}
|
|
3211
3264
|
};
|
|
3212
3265
|
const currentYear = todayDate.getFullYear();
|
|
3213
3266
|
const yearStart = viewYear - 6;
|
|
@@ -3231,18 +3284,35 @@ var CalendarBody = ({
|
|
|
3231
3284
|
return /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__header" }, /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__header-labels" }, /* @__PURE__ */ import_react21.default.createElement(
|
|
3232
3285
|
"span",
|
|
3233
3286
|
{
|
|
3234
|
-
className:
|
|
3287
|
+
className: [
|
|
3288
|
+
"rf-date-picker__month-label",
|
|
3289
|
+
pickerView === "month" ? "rf-date-picker__month-label--active" : "",
|
|
3290
|
+
!hasMonthView || !hasDayView ? "rf-date-picker__label--static" : ""
|
|
3291
|
+
].filter(Boolean).join(" "),
|
|
3235
3292
|
onClick: handleMonthClick
|
|
3236
3293
|
},
|
|
3237
3294
|
MONTHS[viewMonth]
|
|
3238
3295
|
), /* @__PURE__ */ import_react21.default.createElement(
|
|
3239
3296
|
"span",
|
|
3240
3297
|
{
|
|
3241
|
-
className:
|
|
3298
|
+
className: [
|
|
3299
|
+
"rf-date-picker__year-label",
|
|
3300
|
+
pickerView === "year" ? "rf-date-picker__year-label--active" : "",
|
|
3301
|
+
!hasYearView ? "rf-date-picker__label--static" : ""
|
|
3302
|
+
].filter(Boolean).join(" "),
|
|
3242
3303
|
onClick: handleYearClick
|
|
3243
3304
|
},
|
|
3244
3305
|
viewYear
|
|
3245
|
-
)), /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__nav" }, pickerView === "year" ?
|
|
3306
|
+
)), /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__nav" }, pickerView === "year" ? (
|
|
3307
|
+
// Year page navigation
|
|
3308
|
+
/* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear - 16), "aria-label": "Previous years" }, "\u2039"), /* @__PURE__ */ import_react21.default.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear + 16), "aria-label": "Next years" }, "\u203A"))
|
|
3309
|
+
) : pickerView === "month" && !hasDayView ? (
|
|
3310
|
+
// Month-only or month+year mode: ‹ › change year
|
|
3311
|
+
/* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear - 1), "aria-label": "Previous year" }, "\u2039"), /* @__PURE__ */ import_react21.default.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear + 1), "aria-label": "Next year" }, "\u203A"))
|
|
3312
|
+
) : (
|
|
3313
|
+
// Normal month navigation
|
|
3314
|
+
/* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onPrev, disabled: isPrevDisabled, "aria-label": "Previous month" }, "\u2039"), /* @__PURE__ */ import_react21.default.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onNext, disabled: isNextDisabled, "aria-label": "Next month" }, "\u203A"))
|
|
3315
|
+
))), pickerView === "month" && /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__month-grid" }, MONTHS_SHORT.map((m, idx) => {
|
|
3246
3316
|
const monthDisabled = isMonthDisabled(idx);
|
|
3247
3317
|
return /* @__PURE__ */ import_react21.default.createElement(
|
|
3248
3318
|
"button",
|
|
@@ -3278,7 +3348,7 @@ var CalendarBody = ({
|
|
|
3278
3348
|
},
|
|
3279
3349
|
y
|
|
3280
3350
|
);
|
|
3281
|
-
})), pickerView === "calendar" && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__weekdays" }, WEEKDAYS.map((w) => /* @__PURE__ */ import_react21.default.createElement("div", { key: w, className: "rf-date-picker__weekday" }, w))), /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__grid" }, dayCells.map((day, idx) => {
|
|
3351
|
+
})), pickerView === "calendar" && hasDayView && /* @__PURE__ */ import_react21.default.createElement(import_react21.default.Fragment, null, /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__weekdays" }, WEEKDAYS.map((w) => /* @__PURE__ */ import_react21.default.createElement("div", { key: w, className: "rf-date-picker__weekday" }, w))), /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__grid" }, dayCells.map((day, idx) => {
|
|
3282
3352
|
if (day === null) return /* @__PURE__ */ import_react21.default.createElement("div", { key: `e-${idx}`, className: "rf-date-picker__day rf-date-picker__day--empty" });
|
|
3283
3353
|
const cellDate = new Date(viewYear, viewMonth, day);
|
|
3284
3354
|
const isSelected = selectedDate ? isSameDay(cellDate, selectedDate) : false;
|
|
@@ -3321,8 +3391,12 @@ var DateField = ({
|
|
|
3321
3391
|
placeholder,
|
|
3322
3392
|
className = "",
|
|
3323
3393
|
style,
|
|
3324
|
-
sx
|
|
3394
|
+
sx,
|
|
3395
|
+
views: viewsProp
|
|
3325
3396
|
}) => {
|
|
3397
|
+
const views = viewsProp ?? ["day", "month", "year"];
|
|
3398
|
+
const hasDayView = views.includes("day");
|
|
3399
|
+
const hasMonthView = views.includes("month");
|
|
3326
3400
|
const minDate = normaliseBoundary(minDateProp);
|
|
3327
3401
|
const maxDate = normaliseBoundary(maxDateProp);
|
|
3328
3402
|
const sxClass = useSx(sx);
|
|
@@ -3352,6 +3426,8 @@ var DateField = ({
|
|
|
3352
3426
|
if (!value) return "";
|
|
3353
3427
|
const d = isoToDate(value);
|
|
3354
3428
|
if (!d) return "";
|
|
3429
|
+
const viewsStr = formatViewsDisplay(d, views);
|
|
3430
|
+
if (viewsStr) return viewsStr;
|
|
3355
3431
|
let str = formatDisplay(d, dateFormat);
|
|
3356
3432
|
if (isDatetimeType(type)) {
|
|
3357
3433
|
const t = parseTimeFromISO(value);
|
|
@@ -3382,15 +3458,20 @@ var DateField = ({
|
|
|
3382
3458
|
if (d) {
|
|
3383
3459
|
setViewYear(d.getFullYear());
|
|
3384
3460
|
setViewMonth(d.getMonth());
|
|
3385
|
-
|
|
3386
|
-
if (
|
|
3387
|
-
|
|
3388
|
-
|
|
3389
|
-
|
|
3390
|
-
|
|
3391
|
-
|
|
3461
|
+
const viewsStr = formatViewsDisplay(d, views);
|
|
3462
|
+
if (viewsStr) {
|
|
3463
|
+
setInputStr(viewsStr);
|
|
3464
|
+
} else {
|
|
3465
|
+
let str = formatDisplay(d, dateFormat);
|
|
3466
|
+
if (isDatetimeType(type)) {
|
|
3467
|
+
const t = parseTimeFromISO(value);
|
|
3468
|
+
setHour(t.h);
|
|
3469
|
+
setMinute(t.m);
|
|
3470
|
+
setAmpm(t.ampm);
|
|
3471
|
+
str += " " + formatTimeDisplay(t.h, t.m, t.ampm);
|
|
3472
|
+
}
|
|
3473
|
+
setInputStr(str);
|
|
3392
3474
|
}
|
|
3393
|
-
setInputStr(str);
|
|
3394
3475
|
}
|
|
3395
3476
|
}, [value, type]);
|
|
3396
3477
|
(0, import_react21.useEffect)(() => {
|
|
@@ -3411,11 +3492,17 @@ var DateField = ({
|
|
|
3411
3492
|
onChange?.("");
|
|
3412
3493
|
return;
|
|
3413
3494
|
}
|
|
3414
|
-
|
|
3415
|
-
|
|
3495
|
+
const viewsStr = formatViewsDisplay(d, views);
|
|
3496
|
+
let str;
|
|
3497
|
+
if (viewsStr) {
|
|
3498
|
+
str = viewsStr;
|
|
3499
|
+
} else {
|
|
3500
|
+
str = formatDisplay(d, dateFormat);
|
|
3501
|
+
if (isDatetimeType(type)) str += " " + formatTimeDisplay(h, m, ap);
|
|
3502
|
+
}
|
|
3416
3503
|
setInputStr(str);
|
|
3417
3504
|
onChange?.(buildISO(d, type, h, m, ap));
|
|
3418
|
-
}, [type, onChange, dateFormat]);
|
|
3505
|
+
}, [type, onChange, dateFormat, views]);
|
|
3419
3506
|
const isOutOfRange = (d) => (minDate ? isBeforeDay(d, minDate) : false) || (maxDate ? isAfterDay(d, maxDate) : false);
|
|
3420
3507
|
const handleDayClick = (day) => {
|
|
3421
3508
|
const d = new Date(viewYear, viewMonth, day);
|
|
@@ -3429,49 +3516,102 @@ var DateField = ({
|
|
|
3429
3516
|
};
|
|
3430
3517
|
const handleToday = () => {
|
|
3431
3518
|
const t = today();
|
|
3432
|
-
if (
|
|
3433
|
-
|
|
3434
|
-
|
|
3435
|
-
|
|
3436
|
-
|
|
3519
|
+
if (!hasDayView && !hasMonthView) {
|
|
3520
|
+
const d = new Date(t.getFullYear(), 0, 1);
|
|
3521
|
+
if (isOutOfRange(d)) return;
|
|
3522
|
+
setViewYear(t.getFullYear());
|
|
3523
|
+
commitDate(d, hour, minute, ampm);
|
|
3524
|
+
setOpen(false);
|
|
3525
|
+
} else if (!hasDayView) {
|
|
3526
|
+
const d = new Date(t.getFullYear(), t.getMonth(), 1);
|
|
3527
|
+
if (isOutOfRange(d)) return;
|
|
3528
|
+
setViewYear(t.getFullYear());
|
|
3529
|
+
setViewMonth(t.getMonth());
|
|
3530
|
+
commitDate(d, hour, minute, ampm);
|
|
3531
|
+
setOpen(false);
|
|
3532
|
+
} else {
|
|
3533
|
+
if (isOutOfRange(t)) return;
|
|
3534
|
+
setViewYear(t.getFullYear());
|
|
3535
|
+
setViewMonth(t.getMonth());
|
|
3536
|
+
commitDate(t, hour, minute, ampm);
|
|
3537
|
+
if (type === "date") setOpen(false);
|
|
3538
|
+
}
|
|
3437
3539
|
};
|
|
3540
|
+
const handleFinalMonthSelect = (0, import_react21.useCallback)((month, year) => {
|
|
3541
|
+
const d = new Date(year, month, 1);
|
|
3542
|
+
if (isOutOfRange(d)) return;
|
|
3543
|
+
setSelectedDate(d);
|
|
3544
|
+
setViewYear(year);
|
|
3545
|
+
setViewMonth(month);
|
|
3546
|
+
setInputStr(`${MONTHS_SHORT[month]} ${year}`);
|
|
3547
|
+
onChange?.(buildISO(d, type, hour, minute, ampm));
|
|
3548
|
+
setOpen(false);
|
|
3549
|
+
}, [isOutOfRange, onChange, type, hour, minute, ampm]);
|
|
3550
|
+
const handleFinalYearSelect = (0, import_react21.useCallback)((year) => {
|
|
3551
|
+
const d = new Date(year, 0, 1);
|
|
3552
|
+
if (isOutOfRange(d)) return;
|
|
3553
|
+
setSelectedDate(d);
|
|
3554
|
+
setViewYear(year);
|
|
3555
|
+
setInputStr(String(year));
|
|
3556
|
+
onChange?.(buildISO(d, type, hour, minute, ampm));
|
|
3557
|
+
setOpen(false);
|
|
3558
|
+
}, [isOutOfRange, onChange, type, hour, minute, ampm]);
|
|
3438
3559
|
const handleClear = () => commitDate(null, hour, minute, ampm);
|
|
3439
3560
|
const handleInputChange = (e) => {
|
|
3440
3561
|
const raw = e.target.value;
|
|
3441
3562
|
setInputStr(raw);
|
|
3442
|
-
|
|
3443
|
-
|
|
3444
|
-
|
|
3445
|
-
|
|
3446
|
-
|
|
3447
|
-
|
|
3448
|
-
|
|
3449
|
-
|
|
3450
|
-
|
|
3451
|
-
|
|
3452
|
-
|
|
3453
|
-
|
|
3454
|
-
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
|
|
3458
|
-
|
|
3459
|
-
|
|
3460
|
-
|
|
3461
|
-
|
|
3563
|
+
let parsed = null;
|
|
3564
|
+
if (!hasDayView && !hasMonthView) {
|
|
3565
|
+
parsed = parseYearDisplay(raw);
|
|
3566
|
+
} else if (!hasDayView) {
|
|
3567
|
+
parsed = parseMonthYearDisplay(raw);
|
|
3568
|
+
} else {
|
|
3569
|
+
const dateWordCount = getDateWordCount(dateFormat);
|
|
3570
|
+
const words = raw.split(" ");
|
|
3571
|
+
const datePart = words.slice(0, dateWordCount).join(" ");
|
|
3572
|
+
const timeParts = words.slice(dateWordCount);
|
|
3573
|
+
parsed = parseDisplay(datePart, dateFormat);
|
|
3574
|
+
if (parsed && !isOutOfRange(parsed)) {
|
|
3575
|
+
setSelectedDate(parsed);
|
|
3576
|
+
setViewYear(parsed.getFullYear());
|
|
3577
|
+
setViewMonth(parsed.getMonth());
|
|
3578
|
+
let h = hour, m = minute, ap = ampm;
|
|
3579
|
+
if (isDatetimeType(type) && timeParts.length >= 2) {
|
|
3580
|
+
const timePart = timeParts[0];
|
|
3581
|
+
const periodPart = timeParts[1]?.toUpperCase();
|
|
3582
|
+
if (timePart?.includes(":")) {
|
|
3583
|
+
const [hStr, mStr] = timePart.split(":");
|
|
3584
|
+
const parsedH = parseInt(hStr, 10);
|
|
3585
|
+
const parsedM = parseInt(mStr, 10);
|
|
3586
|
+
if (!isNaN(parsedH) && parsedH >= 1 && parsedH <= 12) {
|
|
3587
|
+
h = parsedH;
|
|
3588
|
+
setHour(h);
|
|
3589
|
+
}
|
|
3590
|
+
if (!isNaN(parsedM) && parsedM >= 0 && parsedM <= 59) {
|
|
3591
|
+
m = parsedM;
|
|
3592
|
+
setMinute(m);
|
|
3593
|
+
}
|
|
3462
3594
|
}
|
|
3463
|
-
if (
|
|
3464
|
-
|
|
3465
|
-
|
|
3595
|
+
if (periodPart === "AM" || periodPart === "PM") {
|
|
3596
|
+
ap = periodPart;
|
|
3597
|
+
setAmpm(ap);
|
|
3466
3598
|
}
|
|
3467
3599
|
}
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
|
|
3600
|
+
isInternalChange.current = true;
|
|
3601
|
+
onChange?.(buildISO(parsed, type, h, m, ap));
|
|
3602
|
+
} else if (!raw) {
|
|
3603
|
+
setSelectedDate(null);
|
|
3604
|
+
isInternalChange.current = true;
|
|
3605
|
+
onChange?.("");
|
|
3472
3606
|
}
|
|
3607
|
+
return;
|
|
3608
|
+
}
|
|
3609
|
+
if (parsed && !isOutOfRange(parsed)) {
|
|
3610
|
+
setSelectedDate(parsed);
|
|
3611
|
+
setViewYear(parsed.getFullYear());
|
|
3612
|
+
setViewMonth(parsed.getMonth());
|
|
3473
3613
|
isInternalChange.current = true;
|
|
3474
|
-
onChange?.(buildISO(parsed, type,
|
|
3614
|
+
onChange?.(buildISO(parsed, type, hour, minute, ampm));
|
|
3475
3615
|
} else if (!raw) {
|
|
3476
3616
|
setSelectedDate(null);
|
|
3477
3617
|
isInternalChange.current = true;
|
|
@@ -3657,7 +3797,10 @@ var DateField = ({
|
|
|
3657
3797
|
onMonthSelect: setViewMonth,
|
|
3658
3798
|
onYearSelect: setViewYear,
|
|
3659
3799
|
minDate,
|
|
3660
|
-
maxDate
|
|
3800
|
+
maxDate,
|
|
3801
|
+
views,
|
|
3802
|
+
onFinalMonthSelect: handleFinalMonthSelect,
|
|
3803
|
+
onFinalYearSelect: handleFinalYearSelect
|
|
3661
3804
|
}
|
|
3662
3805
|
), type === "datetime" && /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__time-section" }, /* @__PURE__ */ import_react21.default.createElement("div", { className: "rf-date-picker__time-label" }, "Time"), /* @__PURE__ */ import_react21.default.createElement(
|
|
3663
3806
|
SpinnerPanel,
|
package/dist/main.css
CHANGED
|
@@ -1344,6 +1344,13 @@ pre {
|
|
|
1344
1344
|
background-color: rgba(164, 27, 6, 0.1);
|
|
1345
1345
|
color: #a41b06;
|
|
1346
1346
|
}
|
|
1347
|
+
.rf-date-picker__label--static {
|
|
1348
|
+
cursor: default !important;
|
|
1349
|
+
pointer-events: none;
|
|
1350
|
+
}
|
|
1351
|
+
.rf-date-picker__label--static:hover {
|
|
1352
|
+
background-color: transparent !important;
|
|
1353
|
+
}
|
|
1347
1354
|
.rf-date-picker__nav {
|
|
1348
1355
|
display: flex;
|
|
1349
1356
|
align-items: center;
|
package/dist/main.d.cts
CHANGED
|
@@ -658,6 +658,20 @@ interface DateFieldProps {
|
|
|
658
658
|
placeholder?: string;
|
|
659
659
|
className?: string;
|
|
660
660
|
style?: CSSProperties;
|
|
661
|
+
/**
|
|
662
|
+
* Which selection panels are available in the picker.
|
|
663
|
+
* - `"day"` — day calendar (default)
|
|
664
|
+
* - `"month"` — month grid
|
|
665
|
+
* - `"year"` — year grid
|
|
666
|
+
*
|
|
667
|
+
* Common patterns:
|
|
668
|
+
* - `["month", "year"]` — month+year picker, no day calendar
|
|
669
|
+
* - `["year"]` — year-only picker
|
|
670
|
+
* - `["month"]` — month picker (‹ › navigate years)
|
|
671
|
+
*
|
|
672
|
+
* Defaults to `["day", "month", "year"]` (full picker).
|
|
673
|
+
*/
|
|
674
|
+
views?: ("day" | "month" | "year")[];
|
|
661
675
|
/** Scoped style overrides. Supports nested CSS selectors with & */
|
|
662
676
|
sx?: SxProp;
|
|
663
677
|
}
|
package/dist/main.d.ts
CHANGED
|
@@ -658,6 +658,20 @@ interface DateFieldProps {
|
|
|
658
658
|
placeholder?: string;
|
|
659
659
|
className?: string;
|
|
660
660
|
style?: CSSProperties;
|
|
661
|
+
/**
|
|
662
|
+
* Which selection panels are available in the picker.
|
|
663
|
+
* - `"day"` — day calendar (default)
|
|
664
|
+
* - `"month"` — month grid
|
|
665
|
+
* - `"year"` — year grid
|
|
666
|
+
*
|
|
667
|
+
* Common patterns:
|
|
668
|
+
* - `["month", "year"]` — month+year picker, no day calendar
|
|
669
|
+
* - `["year"]` — year-only picker
|
|
670
|
+
* - `["month"]` — month picker (‹ › navigate years)
|
|
671
|
+
*
|
|
672
|
+
* Defaults to `["day", "month", "year"]` (full picker).
|
|
673
|
+
*/
|
|
674
|
+
views?: ("day" | "month" | "year")[];
|
|
661
675
|
/** Scoped style overrides. Supports nested CSS selectors with & */
|
|
662
676
|
sx?: SxProp;
|
|
663
677
|
}
|
package/dist/main.js
CHANGED
|
@@ -2867,6 +2867,11 @@ var parseDisplay = (str, fmt = "MM/DD/YYYY") => {
|
|
|
2867
2867
|
};
|
|
2868
2868
|
var isoToDate = (iso) => {
|
|
2869
2869
|
if (!iso) return null;
|
|
2870
|
+
if (iso.endsWith("Z") || /[+-]\d{2}:?\d{2}$/.test(iso)) {
|
|
2871
|
+
const d2 = new Date(iso);
|
|
2872
|
+
if (isNaN(d2.getTime())) return null;
|
|
2873
|
+
return new Date(d2.getFullYear(), d2.getMonth(), d2.getDate());
|
|
2874
|
+
}
|
|
2870
2875
|
const [datePart] = iso.split("T");
|
|
2871
2876
|
const [y, mo, d] = datePart.split("-").map(Number);
|
|
2872
2877
|
if (!y || !mo || !d) return null;
|
|
@@ -2879,7 +2884,7 @@ var today = () => {
|
|
|
2879
2884
|
var isSameDay = (a, b) => a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
|
|
2880
2885
|
var normaliseBoundary = (d) => {
|
|
2881
2886
|
if (!d) return null;
|
|
2882
|
-
const base = d instanceof Date ? d : isoToDate(
|
|
2887
|
+
const base = d instanceof Date ? d : isoToDate(d);
|
|
2883
2888
|
if (!base) return null;
|
|
2884
2889
|
return new Date(base.getFullYear(), base.getMonth(), base.getDate());
|
|
2885
2890
|
};
|
|
@@ -3035,6 +3040,24 @@ var SpinnerPanel = ({
|
|
|
3035
3040
|
},
|
|
3036
3041
|
"PM"
|
|
3037
3042
|
)));
|
|
3043
|
+
var formatViewsDisplay = (d, views) => {
|
|
3044
|
+
if (!views.includes("day") && !views.includes("month")) return String(d.getFullYear());
|
|
3045
|
+
if (!views.includes("day")) return `${MONTHS_SHORT[d.getMonth()]} ${d.getFullYear()}`;
|
|
3046
|
+
return "";
|
|
3047
|
+
};
|
|
3048
|
+
var parseYearDisplay = (str) => {
|
|
3049
|
+
const y = parseInt(str.trim(), 10);
|
|
3050
|
+
if (isNaN(y) || y < 1e3 || y > 9999) return null;
|
|
3051
|
+
return new Date(y, 0, 1);
|
|
3052
|
+
};
|
|
3053
|
+
var parseMonthYearDisplay = (str) => {
|
|
3054
|
+
const parts = str.trim().split(/\s+/);
|
|
3055
|
+
if (parts.length < 2) return null;
|
|
3056
|
+
const mm = parseMonthName(parts[0]);
|
|
3057
|
+
const yyyy = parseInt(parts[parts.length - 1], 10);
|
|
3058
|
+
if (mm < 0 || isNaN(yyyy) || yyyy < 1e3) return null;
|
|
3059
|
+
return new Date(yyyy, mm, 1);
|
|
3060
|
+
};
|
|
3038
3061
|
var CalendarBody = ({
|
|
3039
3062
|
viewMonth,
|
|
3040
3063
|
viewYear,
|
|
@@ -3047,18 +3070,48 @@ var CalendarBody = ({
|
|
|
3047
3070
|
onMonthSelect,
|
|
3048
3071
|
onYearSelect,
|
|
3049
3072
|
minDate,
|
|
3050
|
-
maxDate
|
|
3073
|
+
maxDate,
|
|
3074
|
+
views,
|
|
3075
|
+
onFinalMonthSelect,
|
|
3076
|
+
onFinalYearSelect
|
|
3051
3077
|
}) => {
|
|
3052
|
-
const
|
|
3053
|
-
const
|
|
3054
|
-
const
|
|
3078
|
+
const hasDayView = views.includes("day");
|
|
3079
|
+
const hasMonthView = views.includes("month");
|
|
3080
|
+
const hasYearView = views.includes("year");
|
|
3081
|
+
const [pickerView, setPickerView] = useState7(() => {
|
|
3082
|
+
if (!hasDayView && !hasMonthView) return "year";
|
|
3083
|
+
if (!hasDayView) return "month";
|
|
3084
|
+
return "calendar";
|
|
3085
|
+
});
|
|
3086
|
+
const handleMonthClick = () => {
|
|
3087
|
+
if (!hasMonthView || !hasDayView) return;
|
|
3088
|
+
setPickerView((v) => v === "month" ? "calendar" : "month");
|
|
3089
|
+
};
|
|
3090
|
+
const handleYearClick = () => {
|
|
3091
|
+
if (!hasYearView) return;
|
|
3092
|
+
if (pickerView === "year") {
|
|
3093
|
+
setPickerView(hasDayView ? "calendar" : "month");
|
|
3094
|
+
} else {
|
|
3095
|
+
setPickerView("year");
|
|
3096
|
+
}
|
|
3097
|
+
};
|
|
3055
3098
|
const handleMonthPick = (month) => {
|
|
3056
3099
|
onMonthSelect(month);
|
|
3057
|
-
|
|
3100
|
+
if (hasDayView) {
|
|
3101
|
+
setPickerView("calendar");
|
|
3102
|
+
} else {
|
|
3103
|
+
onFinalMonthSelect?.(month, viewYear);
|
|
3104
|
+
}
|
|
3058
3105
|
};
|
|
3059
3106
|
const handleYearPick = (year) => {
|
|
3060
3107
|
onYearSelect(year);
|
|
3061
|
-
|
|
3108
|
+
if (!hasDayView && !hasMonthView) {
|
|
3109
|
+
onFinalYearSelect?.(year);
|
|
3110
|
+
} else if (hasMonthView) {
|
|
3111
|
+
setPickerView("month");
|
|
3112
|
+
} else {
|
|
3113
|
+
setPickerView("calendar");
|
|
3114
|
+
}
|
|
3062
3115
|
};
|
|
3063
3116
|
const currentYear = todayDate.getFullYear();
|
|
3064
3117
|
const yearStart = viewYear - 6;
|
|
@@ -3082,18 +3135,35 @@ var CalendarBody = ({
|
|
|
3082
3135
|
return /* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__header" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__header-labels" }, /* @__PURE__ */ React72.createElement(
|
|
3083
3136
|
"span",
|
|
3084
3137
|
{
|
|
3085
|
-
className:
|
|
3138
|
+
className: [
|
|
3139
|
+
"rf-date-picker__month-label",
|
|
3140
|
+
pickerView === "month" ? "rf-date-picker__month-label--active" : "",
|
|
3141
|
+
!hasMonthView || !hasDayView ? "rf-date-picker__label--static" : ""
|
|
3142
|
+
].filter(Boolean).join(" "),
|
|
3086
3143
|
onClick: handleMonthClick
|
|
3087
3144
|
},
|
|
3088
3145
|
MONTHS[viewMonth]
|
|
3089
3146
|
), /* @__PURE__ */ React72.createElement(
|
|
3090
3147
|
"span",
|
|
3091
3148
|
{
|
|
3092
|
-
className:
|
|
3149
|
+
className: [
|
|
3150
|
+
"rf-date-picker__year-label",
|
|
3151
|
+
pickerView === "year" ? "rf-date-picker__year-label--active" : "",
|
|
3152
|
+
!hasYearView ? "rf-date-picker__label--static" : ""
|
|
3153
|
+
].filter(Boolean).join(" "),
|
|
3093
3154
|
onClick: handleYearClick
|
|
3094
3155
|
},
|
|
3095
3156
|
viewYear
|
|
3096
|
-
)), /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__nav" }, pickerView === "year" ?
|
|
3157
|
+
)), /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__nav" }, pickerView === "year" ? (
|
|
3158
|
+
// Year page navigation
|
|
3159
|
+
/* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear - 16), "aria-label": "Previous years" }, "\u2039"), /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear + 16), "aria-label": "Next years" }, "\u203A"))
|
|
3160
|
+
) : pickerView === "month" && !hasDayView ? (
|
|
3161
|
+
// Month-only or month+year mode: ‹ › change year
|
|
3162
|
+
/* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear - 1), "aria-label": "Previous year" }, "\u2039"), /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: () => onYearSelect(viewYear + 1), "aria-label": "Next year" }, "\u203A"))
|
|
3163
|
+
) : (
|
|
3164
|
+
// Normal month navigation
|
|
3165
|
+
/* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onPrev, disabled: isPrevDisabled, "aria-label": "Previous month" }, "\u2039"), /* @__PURE__ */ React72.createElement("button", { type: "button", className: "rf-date-picker__nav-btn", onClick: onNext, disabled: isNextDisabled, "aria-label": "Next month" }, "\u203A"))
|
|
3166
|
+
))), pickerView === "month" && /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__month-grid" }, MONTHS_SHORT.map((m, idx) => {
|
|
3097
3167
|
const monthDisabled = isMonthDisabled(idx);
|
|
3098
3168
|
return /* @__PURE__ */ React72.createElement(
|
|
3099
3169
|
"button",
|
|
@@ -3129,7 +3199,7 @@ var CalendarBody = ({
|
|
|
3129
3199
|
},
|
|
3130
3200
|
y
|
|
3131
3201
|
);
|
|
3132
|
-
})), pickerView === "calendar" && /* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__weekdays" }, WEEKDAYS.map((w) => /* @__PURE__ */ React72.createElement("div", { key: w, className: "rf-date-picker__weekday" }, w))), /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__grid" }, dayCells.map((day, idx) => {
|
|
3202
|
+
})), pickerView === "calendar" && hasDayView && /* @__PURE__ */ React72.createElement(React72.Fragment, null, /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__weekdays" }, WEEKDAYS.map((w) => /* @__PURE__ */ React72.createElement("div", { key: w, className: "rf-date-picker__weekday" }, w))), /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__grid" }, dayCells.map((day, idx) => {
|
|
3133
3203
|
if (day === null) return /* @__PURE__ */ React72.createElement("div", { key: `e-${idx}`, className: "rf-date-picker__day rf-date-picker__day--empty" });
|
|
3134
3204
|
const cellDate = new Date(viewYear, viewMonth, day);
|
|
3135
3205
|
const isSelected = selectedDate ? isSameDay(cellDate, selectedDate) : false;
|
|
@@ -3172,8 +3242,12 @@ var DateField = ({
|
|
|
3172
3242
|
placeholder,
|
|
3173
3243
|
className = "",
|
|
3174
3244
|
style,
|
|
3175
|
-
sx
|
|
3245
|
+
sx,
|
|
3246
|
+
views: viewsProp
|
|
3176
3247
|
}) => {
|
|
3248
|
+
const views = viewsProp ?? ["day", "month", "year"];
|
|
3249
|
+
const hasDayView = views.includes("day");
|
|
3250
|
+
const hasMonthView = views.includes("month");
|
|
3177
3251
|
const minDate = normaliseBoundary(minDateProp);
|
|
3178
3252
|
const maxDate = normaliseBoundary(maxDateProp);
|
|
3179
3253
|
const sxClass = useSx(sx);
|
|
@@ -3203,6 +3277,8 @@ var DateField = ({
|
|
|
3203
3277
|
if (!value) return "";
|
|
3204
3278
|
const d = isoToDate(value);
|
|
3205
3279
|
if (!d) return "";
|
|
3280
|
+
const viewsStr = formatViewsDisplay(d, views);
|
|
3281
|
+
if (viewsStr) return viewsStr;
|
|
3206
3282
|
let str = formatDisplay(d, dateFormat);
|
|
3207
3283
|
if (isDatetimeType(type)) {
|
|
3208
3284
|
const t = parseTimeFromISO(value);
|
|
@@ -3233,15 +3309,20 @@ var DateField = ({
|
|
|
3233
3309
|
if (d) {
|
|
3234
3310
|
setViewYear(d.getFullYear());
|
|
3235
3311
|
setViewMonth(d.getMonth());
|
|
3236
|
-
|
|
3237
|
-
if (
|
|
3238
|
-
|
|
3239
|
-
|
|
3240
|
-
|
|
3241
|
-
|
|
3242
|
-
|
|
3312
|
+
const viewsStr = formatViewsDisplay(d, views);
|
|
3313
|
+
if (viewsStr) {
|
|
3314
|
+
setInputStr(viewsStr);
|
|
3315
|
+
} else {
|
|
3316
|
+
let str = formatDisplay(d, dateFormat);
|
|
3317
|
+
if (isDatetimeType(type)) {
|
|
3318
|
+
const t = parseTimeFromISO(value);
|
|
3319
|
+
setHour(t.h);
|
|
3320
|
+
setMinute(t.m);
|
|
3321
|
+
setAmpm(t.ampm);
|
|
3322
|
+
str += " " + formatTimeDisplay(t.h, t.m, t.ampm);
|
|
3323
|
+
}
|
|
3324
|
+
setInputStr(str);
|
|
3243
3325
|
}
|
|
3244
|
-
setInputStr(str);
|
|
3245
3326
|
}
|
|
3246
3327
|
}, [value, type]);
|
|
3247
3328
|
useEffect7(() => {
|
|
@@ -3262,11 +3343,17 @@ var DateField = ({
|
|
|
3262
3343
|
onChange?.("");
|
|
3263
3344
|
return;
|
|
3264
3345
|
}
|
|
3265
|
-
|
|
3266
|
-
|
|
3346
|
+
const viewsStr = formatViewsDisplay(d, views);
|
|
3347
|
+
let str;
|
|
3348
|
+
if (viewsStr) {
|
|
3349
|
+
str = viewsStr;
|
|
3350
|
+
} else {
|
|
3351
|
+
str = formatDisplay(d, dateFormat);
|
|
3352
|
+
if (isDatetimeType(type)) str += " " + formatTimeDisplay(h, m, ap);
|
|
3353
|
+
}
|
|
3267
3354
|
setInputStr(str);
|
|
3268
3355
|
onChange?.(buildISO(d, type, h, m, ap));
|
|
3269
|
-
}, [type, onChange, dateFormat]);
|
|
3356
|
+
}, [type, onChange, dateFormat, views]);
|
|
3270
3357
|
const isOutOfRange = (d) => (minDate ? isBeforeDay(d, minDate) : false) || (maxDate ? isAfterDay(d, maxDate) : false);
|
|
3271
3358
|
const handleDayClick = (day) => {
|
|
3272
3359
|
const d = new Date(viewYear, viewMonth, day);
|
|
@@ -3280,49 +3367,102 @@ var DateField = ({
|
|
|
3280
3367
|
};
|
|
3281
3368
|
const handleToday = () => {
|
|
3282
3369
|
const t = today();
|
|
3283
|
-
if (
|
|
3284
|
-
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3370
|
+
if (!hasDayView && !hasMonthView) {
|
|
3371
|
+
const d = new Date(t.getFullYear(), 0, 1);
|
|
3372
|
+
if (isOutOfRange(d)) return;
|
|
3373
|
+
setViewYear(t.getFullYear());
|
|
3374
|
+
commitDate(d, hour, minute, ampm);
|
|
3375
|
+
setOpen(false);
|
|
3376
|
+
} else if (!hasDayView) {
|
|
3377
|
+
const d = new Date(t.getFullYear(), t.getMonth(), 1);
|
|
3378
|
+
if (isOutOfRange(d)) return;
|
|
3379
|
+
setViewYear(t.getFullYear());
|
|
3380
|
+
setViewMonth(t.getMonth());
|
|
3381
|
+
commitDate(d, hour, minute, ampm);
|
|
3382
|
+
setOpen(false);
|
|
3383
|
+
} else {
|
|
3384
|
+
if (isOutOfRange(t)) return;
|
|
3385
|
+
setViewYear(t.getFullYear());
|
|
3386
|
+
setViewMonth(t.getMonth());
|
|
3387
|
+
commitDate(t, hour, minute, ampm);
|
|
3388
|
+
if (type === "date") setOpen(false);
|
|
3389
|
+
}
|
|
3288
3390
|
};
|
|
3391
|
+
const handleFinalMonthSelect = useCallback3((month, year) => {
|
|
3392
|
+
const d = new Date(year, month, 1);
|
|
3393
|
+
if (isOutOfRange(d)) return;
|
|
3394
|
+
setSelectedDate(d);
|
|
3395
|
+
setViewYear(year);
|
|
3396
|
+
setViewMonth(month);
|
|
3397
|
+
setInputStr(`${MONTHS_SHORT[month]} ${year}`);
|
|
3398
|
+
onChange?.(buildISO(d, type, hour, minute, ampm));
|
|
3399
|
+
setOpen(false);
|
|
3400
|
+
}, [isOutOfRange, onChange, type, hour, minute, ampm]);
|
|
3401
|
+
const handleFinalYearSelect = useCallback3((year) => {
|
|
3402
|
+
const d = new Date(year, 0, 1);
|
|
3403
|
+
if (isOutOfRange(d)) return;
|
|
3404
|
+
setSelectedDate(d);
|
|
3405
|
+
setViewYear(year);
|
|
3406
|
+
setInputStr(String(year));
|
|
3407
|
+
onChange?.(buildISO(d, type, hour, minute, ampm));
|
|
3408
|
+
setOpen(false);
|
|
3409
|
+
}, [isOutOfRange, onChange, type, hour, minute, ampm]);
|
|
3289
3410
|
const handleClear = () => commitDate(null, hour, minute, ampm);
|
|
3290
3411
|
const handleInputChange = (e) => {
|
|
3291
3412
|
const raw = e.target.value;
|
|
3292
3413
|
setInputStr(raw);
|
|
3293
|
-
|
|
3294
|
-
|
|
3295
|
-
|
|
3296
|
-
|
|
3297
|
-
|
|
3298
|
-
|
|
3299
|
-
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3414
|
+
let parsed = null;
|
|
3415
|
+
if (!hasDayView && !hasMonthView) {
|
|
3416
|
+
parsed = parseYearDisplay(raw);
|
|
3417
|
+
} else if (!hasDayView) {
|
|
3418
|
+
parsed = parseMonthYearDisplay(raw);
|
|
3419
|
+
} else {
|
|
3420
|
+
const dateWordCount = getDateWordCount(dateFormat);
|
|
3421
|
+
const words = raw.split(" ");
|
|
3422
|
+
const datePart = words.slice(0, dateWordCount).join(" ");
|
|
3423
|
+
const timeParts = words.slice(dateWordCount);
|
|
3424
|
+
parsed = parseDisplay(datePart, dateFormat);
|
|
3425
|
+
if (parsed && !isOutOfRange(parsed)) {
|
|
3426
|
+
setSelectedDate(parsed);
|
|
3427
|
+
setViewYear(parsed.getFullYear());
|
|
3428
|
+
setViewMonth(parsed.getMonth());
|
|
3429
|
+
let h = hour, m = minute, ap = ampm;
|
|
3430
|
+
if (isDatetimeType(type) && timeParts.length >= 2) {
|
|
3431
|
+
const timePart = timeParts[0];
|
|
3432
|
+
const periodPart = timeParts[1]?.toUpperCase();
|
|
3433
|
+
if (timePart?.includes(":")) {
|
|
3434
|
+
const [hStr, mStr] = timePart.split(":");
|
|
3435
|
+
const parsedH = parseInt(hStr, 10);
|
|
3436
|
+
const parsedM = parseInt(mStr, 10);
|
|
3437
|
+
if (!isNaN(parsedH) && parsedH >= 1 && parsedH <= 12) {
|
|
3438
|
+
h = parsedH;
|
|
3439
|
+
setHour(h);
|
|
3440
|
+
}
|
|
3441
|
+
if (!isNaN(parsedM) && parsedM >= 0 && parsedM <= 59) {
|
|
3442
|
+
m = parsedM;
|
|
3443
|
+
setMinute(m);
|
|
3444
|
+
}
|
|
3313
3445
|
}
|
|
3314
|
-
if (
|
|
3315
|
-
|
|
3316
|
-
|
|
3446
|
+
if (periodPart === "AM" || periodPart === "PM") {
|
|
3447
|
+
ap = periodPart;
|
|
3448
|
+
setAmpm(ap);
|
|
3317
3449
|
}
|
|
3318
3450
|
}
|
|
3319
|
-
|
|
3320
|
-
|
|
3321
|
-
|
|
3322
|
-
|
|
3451
|
+
isInternalChange.current = true;
|
|
3452
|
+
onChange?.(buildISO(parsed, type, h, m, ap));
|
|
3453
|
+
} else if (!raw) {
|
|
3454
|
+
setSelectedDate(null);
|
|
3455
|
+
isInternalChange.current = true;
|
|
3456
|
+
onChange?.("");
|
|
3323
3457
|
}
|
|
3458
|
+
return;
|
|
3459
|
+
}
|
|
3460
|
+
if (parsed && !isOutOfRange(parsed)) {
|
|
3461
|
+
setSelectedDate(parsed);
|
|
3462
|
+
setViewYear(parsed.getFullYear());
|
|
3463
|
+
setViewMonth(parsed.getMonth());
|
|
3324
3464
|
isInternalChange.current = true;
|
|
3325
|
-
onChange?.(buildISO(parsed, type,
|
|
3465
|
+
onChange?.(buildISO(parsed, type, hour, minute, ampm));
|
|
3326
3466
|
} else if (!raw) {
|
|
3327
3467
|
setSelectedDate(null);
|
|
3328
3468
|
isInternalChange.current = true;
|
|
@@ -3508,7 +3648,10 @@ var DateField = ({
|
|
|
3508
3648
|
onMonthSelect: setViewMonth,
|
|
3509
3649
|
onYearSelect: setViewYear,
|
|
3510
3650
|
minDate,
|
|
3511
|
-
maxDate
|
|
3651
|
+
maxDate,
|
|
3652
|
+
views,
|
|
3653
|
+
onFinalMonthSelect: handleFinalMonthSelect,
|
|
3654
|
+
onFinalYearSelect: handleFinalYearSelect
|
|
3512
3655
|
}
|
|
3513
3656
|
), type === "datetime" && /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__time-section" }, /* @__PURE__ */ React72.createElement("div", { className: "rf-date-picker__time-label" }, "Time"), /* @__PURE__ */ React72.createElement(
|
|
3514
3657
|
SpinnerPanel,
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rufous/ui",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "0.3.
|
|
4
|
+
"version": "0.3.12",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"description": "Experimental: A lightweight React UI component library (Beta)",
|
|
7
7
|
"style": "./dist/main.css",
|
|
@@ -93,4 +93,4 @@
|
|
|
93
93
|
"react": "^18.0.0 || ^19.0.0",
|
|
94
94
|
"react-dom": "^18.0.0 || ^19.0.0"
|
|
95
95
|
}
|
|
96
|
-
}
|
|
96
|
+
}
|