funda-ui 4.7.740 → 4.7.750
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/Date/index.js +139 -12
- package/EventCalendar/index.js +139 -12
- package/EventCalendarTimeline/index.js +203 -22
- package/Utils/date.d.ts +35 -7
- package/Utils/date.js +133 -12
- package/lib/cjs/Date/index.js +139 -12
- package/lib/cjs/EventCalendar/index.js +139 -12
- package/lib/cjs/EventCalendarTimeline/index.js +203 -22
- package/lib/cjs/Utils/date.d.ts +35 -7
- package/lib/cjs/Utils/date.js +133 -12
- package/lib/esm/EventCalendarTimeline/index.tsx +70 -14
- package/lib/esm/Utils/libs/date.ts +152 -21
- package/package.json +1 -1
|
@@ -13,8 +13,6 @@ import { getTodayDate, getCalendarDate, isValidDate, padZero, getDateDetails, ge
|
|
|
13
13
|
import { clsWrite, combinedCls } from 'funda-utils/dist/cjs/cls';
|
|
14
14
|
import getOs from 'funda-utils//dist/cjs/os';
|
|
15
15
|
|
|
16
|
-
|
|
17
|
-
|
|
18
16
|
export interface EventsValueConfig {
|
|
19
17
|
id: string | number;
|
|
20
18
|
date: string,
|
|
@@ -324,6 +322,8 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
|
|
|
324
322
|
return tableCellMinWidth;
|
|
325
323
|
}, [tableCellMinWidth, appearanceMode, headerShowWeek]);
|
|
326
324
|
|
|
325
|
+
|
|
326
|
+
|
|
327
327
|
const findMondayAndTruncate = (dates: string[]) => {
|
|
328
328
|
const _res = dates.map((s: string) => new Date(s));
|
|
329
329
|
// Find the first Monday in the sequence
|
|
@@ -389,7 +389,45 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
|
|
|
389
389
|
//================================================================
|
|
390
390
|
// Weekly calendar
|
|
391
391
|
//================================================================
|
|
392
|
+
const hasInitializedRef = useRef<boolean>(false);
|
|
393
|
+
|
|
394
|
+
// Helper function to calculate offset from a specific date
|
|
395
|
+
const calculateWeekOffset = (targetDate?: Date) => {
|
|
396
|
+
const _curDate = typeof targetDate === 'undefined' ? date : targetDate;
|
|
397
|
+
|
|
398
|
+
// 1. Get the current selected date (from customTodayDate or user selection)
|
|
399
|
+
const selected = new Date(_curDate.getFullYear(), _curDate.getMonth(), _curDate.getDate());
|
|
400
|
+
|
|
401
|
+
// 2. Get the reference Monday of the "actual current week" (offset 0)
|
|
402
|
+
const currentWeekDates = getWeekDatesFromMon(0);
|
|
403
|
+
const currentMonday = new Date(currentWeekDates[0]);
|
|
404
|
+
currentMonday.setHours(0, 0, 0, 0);
|
|
405
|
+
|
|
406
|
+
// 3. Calculate the difference in days
|
|
407
|
+
const diffTime = selected.getTime() - currentMonday.getTime();
|
|
408
|
+
const diffDays = Math.round(diffTime / (1000 * 60 * 60 * 24));
|
|
409
|
+
|
|
410
|
+
// 4. Update the week offset automatically
|
|
411
|
+
const offset = Math.floor(diffDays / 7);
|
|
412
|
+
setWeekOffset(offset);
|
|
413
|
+
}
|
|
414
|
+
// Initialize weekOffset based on customTodayDate instead of default 0
|
|
392
415
|
const [weekOffset, setWeekOffset] = useState<number>(0);
|
|
416
|
+
|
|
417
|
+
// Sync weekOffset whenever date changes or mode switches to 'week'
|
|
418
|
+
useEffect(() => {
|
|
419
|
+
if (!hasInitializedRef.current) {
|
|
420
|
+
const customDateValid = isValidDate(customTodayDate as never);
|
|
421
|
+
if (customDateValid) {
|
|
422
|
+
calculateWeekOffset(new Date(customTodayDate as string));
|
|
423
|
+
setDate(new Date(customTodayDate as string));
|
|
424
|
+
hasInitializedRef.current = true;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
}, [date, appearanceMode, customTodayDate]);
|
|
428
|
+
|
|
429
|
+
|
|
430
|
+
|
|
393
431
|
const handleNextWeek = () => {
|
|
394
432
|
setWeekOffset(weekOffset + 1);
|
|
395
433
|
return weekOffset + 1;
|
|
@@ -1169,7 +1207,7 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
|
|
|
1169
1207
|
|
|
1170
1208
|
|
|
1171
1209
|
}
|
|
1172
|
-
function handleDayChange(e: React.MouseEvent, currentDay: number) {
|
|
1210
|
+
function handleDayChange(e: React.MouseEvent | null, currentDay: number) {
|
|
1173
1211
|
// Avoid triggering a full table re-render when the clicked cell is already
|
|
1174
1212
|
// the active day; this becomes expensive with large datasets.
|
|
1175
1213
|
if (
|
|
@@ -1260,14 +1298,14 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
|
|
|
1260
1298
|
function handleAppearanceChange(e: React.MouseEvent) {
|
|
1261
1299
|
const _mode = (e.target as any).dataset.mode;
|
|
1262
1300
|
setAppearanceMode(_mode);
|
|
1263
|
-
|
|
1264
|
-
//
|
|
1301
|
+
|
|
1302
|
+
// The useEffect above will handle the weekOffset calculation
|
|
1303
|
+
// as soon as appearanceMode becomes 'week'
|
|
1265
1304
|
onChangeAppearanceMode?.(_mode);
|
|
1266
1305
|
}
|
|
1267
1306
|
|
|
1268
1307
|
|
|
1269
1308
|
|
|
1270
|
-
|
|
1271
1309
|
function handleShowWinYear() {
|
|
1272
1310
|
setWinYear((prevState: boolean) => !prevState);
|
|
1273
1311
|
}
|
|
@@ -1356,7 +1394,9 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
|
|
|
1356
1394
|
data-date={_dateShow}
|
|
1357
1395
|
data-day={_dateDayShow}
|
|
1358
1396
|
data-week={weekDay}
|
|
1359
|
-
|
|
1397
|
+
|
|
1398
|
+
// FIX: In 'week' mode, we don't want a hardcoded minWidth
|
|
1399
|
+
style={appearanceMode === 'week' ? undefined : { minWidth: CELL_MIN_W + 'px' }}
|
|
1360
1400
|
onMouseEnter={(e: React.MouseEvent) => {
|
|
1361
1401
|
onCellMouseEnter?.(e);
|
|
1362
1402
|
}}
|
|
@@ -2242,6 +2282,7 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
|
|
|
2242
2282
|
|
|
2243
2283
|
}
|
|
2244
2284
|
|
|
2285
|
+
|
|
2245
2286
|
// Dual RAF survival test
|
|
2246
2287
|
/*
|
|
2247
2288
|
A single RAF only guarantees "moving to the next frame."
|
|
@@ -2304,15 +2345,30 @@ const EventCalendarTimeline = (props: EventCalendarTimelineProps) => {
|
|
|
2304
2345
|
}, [date]);
|
|
2305
2346
|
|
|
2306
2347
|
|
|
2348
|
+
// Guaranteed year change triggered by the next/prev buttons
|
|
2349
|
+
const isFirstRenderRef = useRef<boolean>(true);
|
|
2350
|
+
const prevYearRef = useRef<number>(year); // Record the year of the last occurrence.
|
|
2307
2351
|
useEffect(() => {
|
|
2308
|
-
//
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
2312
|
-
|
|
2313
|
-
|
|
2314
|
-
|
|
2352
|
+
// 1. Intercept the first render (Mount)
|
|
2353
|
+
if (isFirstRenderRef.current) {
|
|
2354
|
+
isFirstRenderRef.current = false;
|
|
2355
|
+
return;
|
|
2356
|
+
}
|
|
2357
|
+
|
|
2358
|
+
// 2. It only triggers when the year actually changes
|
|
2359
|
+
if (year !== prevYearRef.current) {
|
|
2360
|
+
onChangeYear?.({
|
|
2361
|
+
day: padZero(day),
|
|
2362
|
+
month: padZero(month + 1),
|
|
2363
|
+
year: year.toString()
|
|
2364
|
+
});
|
|
2315
2365
|
|
|
2366
|
+
// Update the old year ref for next comparison
|
|
2367
|
+
prevYearRef.current = year;
|
|
2368
|
+
}
|
|
2369
|
+
}, [year, month, day, onChangeYear]);
|
|
2370
|
+
|
|
2371
|
+
|
|
2316
2372
|
|
|
2317
2373
|
useEffect(() => {
|
|
2318
2374
|
|
|
@@ -1,3 +1,47 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* Get the Sunday of the week of the specific date, and return to the
|
|
4
|
+
* end of January next year if it is New Year's Eve
|
|
5
|
+
* @param {Date | String} v
|
|
6
|
+
* @returns {String} yyyy-MM-dd
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* getSpecialDateEnd('2025-12-29'); // 2026-01-31
|
|
10
|
+
* getSpecialDateEnd('2025-12-17'); // 2025-12-31
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Calculates a special end date based on the week and month logic.
|
|
14
|
+
* @param v - The input date (Date object, string, or timestamp)
|
|
15
|
+
* @returns A formatted date string (YYYY-MM-DD)
|
|
16
|
+
*/
|
|
17
|
+
function getSpecialDateEnd(v: Date | string | number): string {
|
|
18
|
+
// Assuming dateFormat returns a Date object based on your logic
|
|
19
|
+
const date: Date = new Date(v);
|
|
20
|
+
|
|
21
|
+
// getWeekDatesByDate should return Date[]
|
|
22
|
+
const weekDates: Date[] = getWeekDatesByDate(v);
|
|
23
|
+
const sunday: Date = weekDates[6]; // Sunday of that week
|
|
24
|
+
|
|
25
|
+
// If Sunday of this week rolls into the next year
|
|
26
|
+
if (sunday.getFullYear() > date.getFullYear()) {
|
|
27
|
+
const year = sunday.getFullYear();
|
|
28
|
+
|
|
29
|
+
// Get the last day of January of that new year
|
|
30
|
+
// Note: month 1 in 'new Date' is February, day 0 gives the last day of Jan
|
|
31
|
+
const lastDay = new Date(year, 1, 0).getDate();
|
|
32
|
+
|
|
33
|
+
// Using template literals for the return string
|
|
34
|
+
return `${year}-01-${lastDay.toString().padStart(2, '0')}`;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// Default: Return the last day of the current month
|
|
38
|
+
// We create a date for the "0th" day of the next month to get the end of current month
|
|
39
|
+
const endOfCurrentMonth = new Date(date.getFullYear(), date.getMonth() + 1, 0);
|
|
40
|
+
|
|
41
|
+
return getCalendarDate(endOfCurrentMonth);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
|
|
1
45
|
/**
|
|
2
46
|
* The check string contains only hours, minutes, and seconds
|
|
3
47
|
* @returns {Boolean}
|
|
@@ -497,20 +541,44 @@ function getMonthDates(year: number, month: number) {
|
|
|
497
541
|
return dates;
|
|
498
542
|
}
|
|
499
543
|
|
|
544
|
+
|
|
500
545
|
/**
|
|
501
|
-
* Get
|
|
502
|
-
* @param {Number} weekOffset
|
|
503
|
-
*
|
|
546
|
+
* Get all 7 dates for a specific week starting from Sunday.
|
|
547
|
+
* * @param {Number} weekOffset - The offset of weeks from the current week.
|
|
548
|
+
* 0: Current week
|
|
549
|
+
* -1: Previous week
|
|
550
|
+
* 1: Next week
|
|
551
|
+
* @returns {Array<Date>} - An array containing 7 Date objects from Sunday to Saturday.
|
|
504
552
|
*/
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
553
|
+
/*
|
|
554
|
+
// Demo 1: Get dates for the current week (Sunday Start)
|
|
555
|
+
const currentWeekSun = getWeekDatesFromSun(0);
|
|
556
|
+
console.log('Sunday (Start):', currentWeekSun[0].toLocaleDateString());
|
|
557
|
+
console.log('Saturday (End):', currentWeekSun[6].toLocaleDateString());
|
|
508
558
|
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
559
|
+
// Demo 2: Get the date range for the previous week
|
|
560
|
+
const lastWeek = getWeekDatesFromSun(-1);
|
|
561
|
+
const rangeStart = lastWeek[0].toISOString().split('T')[0];
|
|
562
|
+
const rangeEnd = lastWeek[6].toISOString().split('T')[0];
|
|
563
|
+
console.log(`Previous Week Range: ${rangeStart} to ${rangeEnd}`);
|
|
564
|
+
|
|
565
|
+
// Demo 3: Checking for Month/Year transitions
|
|
566
|
+
const transitionWeek = getWeekDatesFromSun(0).map(d => d.toDateString());
|
|
567
|
+
console.log('Transition Week Dates:', transitionWeek);
|
|
568
|
+
|
|
569
|
+
*/
|
|
570
|
+
function getWeekDatesFromSun(weekOffset: number): Date[] {
|
|
571
|
+
const dates: Date[] = [];
|
|
572
|
+
// Start with a clean date (midnight) to avoid timezone/DST shifts during calculation
|
|
573
|
+
const currentDate: Date = new Date();
|
|
574
|
+
currentDate.setHours(0, 0, 0, 0);
|
|
575
|
+
|
|
576
|
+
const dayOfWeek: number = currentDate.getDay();
|
|
577
|
+
|
|
578
|
+
// Move to the Sunday of the current week, then apply the week offset
|
|
579
|
+
// Formula: Current Date - Current Day Index + (Offset * 7)
|
|
580
|
+
currentDate.setDate(currentDate.getDate() - dayOfWeek + (weekOffset * 7));
|
|
512
581
|
|
|
513
|
-
// Get the date of the week
|
|
514
582
|
for (let i = 0; i < 7; i++) {
|
|
515
583
|
const date = new Date(currentDate);
|
|
516
584
|
date.setDate(currentDate.getDate() + i);
|
|
@@ -520,21 +588,48 @@ function getWeekDatesFromSun(weekOffset: number) {
|
|
|
520
588
|
return dates;
|
|
521
589
|
}
|
|
522
590
|
|
|
591
|
+
|
|
523
592
|
/**
|
|
524
|
-
* Get
|
|
525
|
-
* @param {Number} weekOffset
|
|
526
|
-
*
|
|
593
|
+
* Get all 7 dates for a specific week starting from Monday.
|
|
594
|
+
* * @param {Number} weekOffset - The offset of weeks from the current week.
|
|
595
|
+
* 0: Current week
|
|
596
|
+
* -1: Previous week
|
|
597
|
+
* 1: Next week
|
|
598
|
+
* @returns {Array<Date>} - An array containing 7 Date objects from Monday to Sunday.
|
|
527
599
|
*/
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
600
|
+
/*
|
|
601
|
+
// Demo 1: Get dates for the current week
|
|
602
|
+
const currentWeek = getWeekDatesFromMon(0);
|
|
603
|
+
console.log('Monday of this week:', currentWeek[0].toLocaleDateString());
|
|
604
|
+
console.log('Sunday of this week:', currentWeek[6].toLocaleDateString());
|
|
605
|
+
|
|
606
|
+
// Demo 2: Get dates for the next week
|
|
607
|
+
const nextWeek = getWeekDatesFromMon(1);
|
|
608
|
+
console.log('Monday of next week:', nextWeek[0].toLocaleDateString());
|
|
609
|
+
|
|
610
|
+
// Demo 3: Format the output as YYYY-MM-DD
|
|
611
|
+
const formattedWeek = getWeekDatesFromMon(0).map(date => {
|
|
612
|
+
const y = date.getFullYear();
|
|
613
|
+
const m = String(date.getMonth() + 1).padStart(2, '0');
|
|
614
|
+
const d = String(date.getDate()).padStart(2, '0');
|
|
615
|
+
return `${y}-${m}-${d}`;
|
|
616
|
+
});
|
|
617
|
+
console.log('Formatted Week Array:', formattedWeek);
|
|
618
|
+
// Result: ["2025-12-29", "2025-12-30", ..., "2026-01-04"]
|
|
619
|
+
*/
|
|
620
|
+
function getWeekDatesFromMon(weekOffset: number): Date[] {
|
|
621
|
+
const dates: Date[] = [];
|
|
622
|
+
const currentDate: Date = new Date();
|
|
531
623
|
|
|
532
|
-
//
|
|
624
|
+
// Calculate the difference to get to Monday of the current week
|
|
625
|
+
// If today is Sunday (0), we go back 6 days. Otherwise, go to (1 - currentDay).
|
|
533
626
|
const dayOfWeek = currentDate.getDay();
|
|
534
627
|
const diffToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
|
|
535
|
-
|
|
628
|
+
|
|
629
|
+
// Apply the Monday offset and the week offset (7 days per week)
|
|
630
|
+
currentDate.setDate(currentDate.getDate() + diffToMonday + (weekOffset * 7));
|
|
536
631
|
|
|
537
|
-
//
|
|
632
|
+
// Generate the 7 days of the week
|
|
538
633
|
for (let i = 0; i < 7; i++) {
|
|
539
634
|
const date = new Date(currentDate);
|
|
540
635
|
date.setDate(currentDate.getDate() + i);
|
|
@@ -544,7 +639,42 @@ function getWeekDatesFromMon(weekOffset: number) {
|
|
|
544
639
|
return dates;
|
|
545
640
|
}
|
|
546
641
|
|
|
642
|
+
/**
|
|
643
|
+
* Get the date list of the week for the specified date (starting from Monday)
|
|
644
|
+
* @param {Date | String} v - The specified date
|
|
645
|
+
* @returns {Array<Date>} - An array containing 7 Date objects
|
|
646
|
+
*/
|
|
647
|
+
function getWeekDatesByDate(v: Date | string | number): Date[] {
|
|
648
|
+
const dates: Date[] = [];
|
|
649
|
+
|
|
650
|
+
// Ensure we are working with a Date object.
|
|
651
|
+
// If 'dateFormat' was a custom utility in your JS, replace 'new Date(v)' with that utility.
|
|
652
|
+
const currentDate = new Date(v);
|
|
653
|
+
|
|
654
|
+
// Get the day of the week (0 for Sunday, 1 for Monday, ..., 6 for Saturday)
|
|
655
|
+
const dayOfWeek = currentDate.getDay();
|
|
656
|
+
|
|
657
|
+
// Calculate difference to Monday: if Sunday (0) subtract 6 days, otherwise subtract (day - 1)
|
|
658
|
+
const diffToMonday = dayOfWeek === 0 ? -6 : 1 - dayOfWeek;
|
|
659
|
+
|
|
660
|
+
// Create the Monday starting point
|
|
661
|
+
const monday = new Date(currentDate);
|
|
662
|
+
monday.setDate(currentDate.getDate() + diffToMonday);
|
|
663
|
+
|
|
664
|
+
// Generate the 7 days of the week
|
|
665
|
+
for (let i = 0; i < 7; i++) {
|
|
666
|
+
const date = new Date(monday);
|
|
667
|
+
date.setDate(monday.getDate() + i);
|
|
668
|
+
dates.push(date);
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
return dates;
|
|
672
|
+
}
|
|
673
|
+
|
|
547
674
|
export {
|
|
675
|
+
getSpecialDateEnd,
|
|
676
|
+
|
|
677
|
+
//
|
|
548
678
|
isTimeString,
|
|
549
679
|
getNow,
|
|
550
680
|
padZero,
|
|
@@ -594,5 +724,6 @@ export {
|
|
|
594
724
|
// get dates list
|
|
595
725
|
getMonthDates,
|
|
596
726
|
getWeekDatesFromSun,
|
|
597
|
-
getWeekDatesFromMon
|
|
598
|
-
|
|
727
|
+
getWeekDatesFromMon,
|
|
728
|
+
getWeekDatesByDate
|
|
729
|
+
}
|
package/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.
|
|
1
|
+
{"author":"UIUX Lab","email":"uiuxlab@gmail.com","name":"funda-ui","version":"4.7.750","description":"React components using pure Bootstrap 5+ which does not contain any external style and script libraries.","repository":{"type":"git","url":"git+https://github.com/xizon/funda-ui.git"},"scripts":{"test":"echo \"Error: no test specified\" && exit 1"},"keywords":["bootstrap","react-bootstrap","react-components","components","components-react","react-bootstrap-components","react","funda-ui","fundaui","uikit","ui-kit","ui-components"],"bugs":{"url":"https://github.com/xizon/funda-ui/issues"},"homepage":"https://github.com/xizon/funda-ui#readme","main":"all.js","license":"MIT","dependencies":{"react":"^18.2.0","react-dom":"^18.2.0"},"types":"all.d.ts","publishConfig":{"directory":"lib"},"directories":{"lib":"lib"}}
|