@korsolutions/ui 0.0.72 → 0.0.75

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.
Files changed (168) hide show
  1. package/dist/module/components/calendar/calendar/calendar-root.js +57 -0
  2. package/dist/module/components/calendar/calendar/calendar-root.js.map +1 -0
  3. package/dist/module/components/calendar/{components → calendar}/calendar-weeks.js +12 -5
  4. package/dist/module/components/calendar/calendar/calendar-weeks.js.map +1 -0
  5. package/dist/module/components/calendar/calendar/index.js +19 -0
  6. package/dist/module/components/calendar/calendar/index.js.map +1 -0
  7. package/dist/module/components/calendar/calendar/types.js.map +1 -0
  8. package/dist/module/components/calendar/{variants → calendar/variants}/default.js +29 -13
  9. package/dist/module/components/calendar/calendar/variants/default.js.map +1 -0
  10. package/dist/module/components/calendar/calendar/variants/index.js.map +1 -0
  11. package/dist/module/components/calendar/index.js +3 -16
  12. package/dist/module/components/calendar/index.js.map +1 -1
  13. package/dist/module/components/calendar/{context.js → shared/calendar-context.js} +2 -2
  14. package/dist/module/components/calendar/shared/calendar-context.js.map +1 -0
  15. package/dist/module/components/calendar/{components → shared}/calendar-day.js +12 -11
  16. package/dist/module/components/calendar/shared/calendar-day.js.map +1 -0
  17. package/dist/module/components/calendar/{components → shared}/calendar-header.js +1 -1
  18. package/dist/module/components/calendar/shared/calendar-header.js.map +1 -0
  19. package/dist/module/components/calendar/shared/calendar-nav-buttons.js +63 -0
  20. package/dist/module/components/calendar/shared/calendar-nav-buttons.js.map +1 -0
  21. package/dist/module/components/calendar/{components → shared}/calendar-title.js +2 -2
  22. package/dist/module/components/calendar/shared/calendar-title.js.map +1 -0
  23. package/dist/module/components/calendar/{components → shared}/calendar-week-labels.js +1 -1
  24. package/dist/module/components/calendar/shared/calendar-week-labels.js.map +1 -0
  25. package/dist/module/components/calendar/shared/types.js +4 -0
  26. package/dist/module/components/calendar/shared/types.js.map +1 -0
  27. package/dist/module/components/calendar/timeline/calendar-timeline.js +138 -0
  28. package/dist/module/components/calendar/timeline/calendar-timeline.js.map +1 -0
  29. package/dist/module/components/calendar/timeline/index.js +4 -0
  30. package/dist/module/components/calendar/timeline/index.js.map +1 -0
  31. package/dist/module/components/calendar/timeline/types.js +4 -0
  32. package/dist/module/components/calendar/timeline/types.js.map +1 -0
  33. package/dist/module/components/calendar/timeline/variants/default.js +62 -0
  34. package/dist/module/components/calendar/timeline/variants/default.js.map +1 -0
  35. package/dist/module/components/calendar/timeline/variants/index.js +7 -0
  36. package/dist/module/components/calendar/timeline/variants/index.js.map +1 -0
  37. package/dist/module/components/calendar/week-calendar/index.js +4 -0
  38. package/dist/module/components/calendar/week-calendar/index.js.map +1 -0
  39. package/dist/module/components/calendar/week-calendar/types.js +4 -0
  40. package/dist/module/components/calendar/week-calendar/types.js.map +1 -0
  41. package/dist/module/components/calendar/week-calendar/variants/default.js +145 -0
  42. package/dist/module/components/calendar/week-calendar/variants/default.js.map +1 -0
  43. package/dist/module/components/calendar/week-calendar/variants/index.js +7 -0
  44. package/dist/module/components/calendar/week-calendar/variants/index.js.map +1 -0
  45. package/dist/module/components/calendar/week-calendar/week-calendar.js +170 -0
  46. package/dist/module/components/calendar/week-calendar/week-calendar.js.map +1 -0
  47. package/dist/module/components/index.js +1 -1
  48. package/dist/module/index.js +2 -1
  49. package/dist/module/index.js.map +1 -1
  50. package/dist/module/themes/provider.js.map +1 -1
  51. package/dist/module/utils/date-utils.js +45 -17
  52. package/dist/module/utils/date-utils.js.map +1 -1
  53. package/dist/typescript/src/components/calendar/{components → calendar}/calendar-root.d.ts +2 -1
  54. package/dist/typescript/src/components/calendar/calendar/calendar-root.d.ts.map +1 -0
  55. package/dist/typescript/src/components/calendar/calendar/calendar-weeks.d.ts.map +1 -0
  56. package/dist/typescript/src/components/calendar/calendar/index.d.ts +25 -0
  57. package/dist/typescript/src/components/calendar/calendar/index.d.ts.map +1 -0
  58. package/dist/typescript/src/components/calendar/calendar/types.d.ts +7 -0
  59. package/dist/typescript/src/components/calendar/calendar/types.d.ts.map +1 -0
  60. package/dist/typescript/src/components/calendar/calendar/variants/default.d.ts +3 -0
  61. package/dist/typescript/src/components/calendar/calendar/variants/default.d.ts.map +1 -0
  62. package/dist/typescript/src/components/calendar/calendar/variants/index.d.ts.map +1 -0
  63. package/dist/typescript/src/components/calendar/index.d.ts +7 -24
  64. package/dist/typescript/src/components/calendar/index.d.ts.map +1 -1
  65. package/dist/typescript/src/components/calendar/{context.d.ts → shared/calendar-context.d.ts} +10 -4
  66. package/dist/typescript/src/components/calendar/shared/calendar-context.d.ts.map +1 -0
  67. package/dist/typescript/src/components/calendar/shared/calendar-day.d.ts.map +1 -0
  68. package/dist/typescript/src/components/calendar/shared/calendar-header.d.ts.map +1 -0
  69. package/dist/typescript/src/components/calendar/shared/calendar-nav-buttons.d.ts +7 -0
  70. package/dist/typescript/src/components/calendar/shared/calendar-nav-buttons.d.ts.map +1 -0
  71. package/dist/typescript/src/components/calendar/shared/calendar-title.d.ts.map +1 -0
  72. package/dist/typescript/src/components/calendar/shared/calendar-week-labels.d.ts.map +1 -0
  73. package/dist/typescript/src/components/calendar/shared/types.d.ts +18 -0
  74. package/dist/typescript/src/components/calendar/shared/types.d.ts.map +1 -0
  75. package/dist/typescript/src/components/calendar/timeline/calendar-timeline.d.ts +23 -0
  76. package/dist/typescript/src/components/calendar/timeline/calendar-timeline.d.ts.map +1 -0
  77. package/dist/typescript/src/components/calendar/timeline/index.d.ts +4 -0
  78. package/dist/typescript/src/components/calendar/timeline/index.d.ts.map +1 -0
  79. package/dist/typescript/src/components/calendar/timeline/types.d.ts +13 -0
  80. package/dist/typescript/src/components/calendar/timeline/types.d.ts.map +1 -0
  81. package/dist/typescript/src/components/calendar/timeline/variants/default.d.ts +3 -0
  82. package/dist/typescript/src/components/calendar/timeline/variants/default.d.ts.map +1 -0
  83. package/dist/typescript/src/components/calendar/timeline/variants/index.d.ts +4 -0
  84. package/dist/typescript/src/components/calendar/timeline/variants/index.d.ts.map +1 -0
  85. package/dist/typescript/src/components/calendar/week-calendar/index.d.ts +4 -0
  86. package/dist/typescript/src/components/calendar/week-calendar/index.d.ts.map +1 -0
  87. package/dist/typescript/src/components/calendar/week-calendar/types.d.ts +7 -0
  88. package/dist/typescript/src/components/calendar/week-calendar/types.d.ts.map +1 -0
  89. package/dist/typescript/src/components/calendar/week-calendar/variants/default.d.ts +3 -0
  90. package/dist/typescript/src/components/calendar/week-calendar/variants/default.d.ts.map +1 -0
  91. package/dist/typescript/src/components/calendar/week-calendar/variants/index.d.ts +4 -0
  92. package/dist/typescript/src/components/calendar/week-calendar/variants/index.d.ts.map +1 -0
  93. package/dist/typescript/src/components/calendar/week-calendar/week-calendar.d.ts +16 -0
  94. package/dist/typescript/src/components/calendar/week-calendar/week-calendar.d.ts.map +1 -0
  95. package/dist/typescript/src/components/index.d.ts +1 -1
  96. package/dist/typescript/src/index.d.ts.map +1 -1
  97. package/dist/typescript/src/themes/provider.d.ts +4 -0
  98. package/dist/typescript/src/themes/provider.d.ts.map +1 -1
  99. package/dist/typescript/src/utils/date-utils.d.ts +8 -1
  100. package/dist/typescript/src/utils/date-utils.d.ts.map +1 -1
  101. package/package.json +1 -1
  102. package/src/components/calendar/calendar/calendar-root.tsx +73 -0
  103. package/src/components/calendar/{components → calendar}/calendar-weeks.tsx +22 -8
  104. package/src/components/calendar/calendar/index.ts +26 -0
  105. package/src/components/calendar/calendar/types.ts +7 -0
  106. package/src/components/calendar/{variants → calendar/variants}/default.tsx +30 -14
  107. package/src/components/calendar/index.ts +21 -24
  108. package/src/components/calendar/shared/calendar-context.ts +35 -0
  109. package/src/components/calendar/{components → shared}/calendar-day.tsx +41 -13
  110. package/src/components/calendar/{components → shared}/calendar-header.tsx +7 -2
  111. package/src/components/calendar/shared/calendar-nav-buttons.tsx +81 -0
  112. package/src/components/calendar/{components → shared}/calendar-title.tsx +8 -3
  113. package/src/components/calendar/{components → shared}/calendar-week-labels.tsx +8 -2
  114. package/src/components/calendar/shared/types.ts +24 -0
  115. package/src/components/calendar/timeline/calendar-timeline.tsx +204 -0
  116. package/src/components/calendar/timeline/index.ts +6 -0
  117. package/src/components/calendar/timeline/types.ts +13 -0
  118. package/src/components/calendar/timeline/variants/default.tsx +59 -0
  119. package/src/components/calendar/timeline/variants/index.ts +5 -0
  120. package/src/components/calendar/week-calendar/index.ts +3 -0
  121. package/src/components/calendar/week-calendar/types.ts +7 -0
  122. package/src/components/calendar/week-calendar/variants/default.tsx +141 -0
  123. package/src/components/calendar/week-calendar/variants/index.ts +5 -0
  124. package/src/components/calendar/week-calendar/week-calendar.tsx +256 -0
  125. package/src/components/index.ts +1 -1
  126. package/src/index.tsx +2 -0
  127. package/src/themes/provider.tsx +4 -0
  128. package/src/utils/date-utils.ts +53 -21
  129. package/dist/module/components/calendar/components/calendar-day.js.map +0 -1
  130. package/dist/module/components/calendar/components/calendar-header.js.map +0 -1
  131. package/dist/module/components/calendar/components/calendar-nav-button.js +0 -61
  132. package/dist/module/components/calendar/components/calendar-nav-button.js.map +0 -1
  133. package/dist/module/components/calendar/components/calendar-root.js +0 -39
  134. package/dist/module/components/calendar/components/calendar-root.js.map +0 -1
  135. package/dist/module/components/calendar/components/calendar-title.js.map +0 -1
  136. package/dist/module/components/calendar/components/calendar-week-labels.js.map +0 -1
  137. package/dist/module/components/calendar/components/calendar-weeks.js.map +0 -1
  138. package/dist/module/components/calendar/context.js.map +0 -1
  139. package/dist/module/components/calendar/types.js.map +0 -1
  140. package/dist/module/components/calendar/variants/default.js.map +0 -1
  141. package/dist/module/components/calendar/variants/index.js.map +0 -1
  142. package/dist/typescript/src/components/calendar/components/calendar-day.d.ts.map +0 -1
  143. package/dist/typescript/src/components/calendar/components/calendar-header.d.ts.map +0 -1
  144. package/dist/typescript/src/components/calendar/components/calendar-nav-button.d.ts +0 -10
  145. package/dist/typescript/src/components/calendar/components/calendar-nav-button.d.ts.map +0 -1
  146. package/dist/typescript/src/components/calendar/components/calendar-root.d.ts.map +0 -1
  147. package/dist/typescript/src/components/calendar/components/calendar-title.d.ts.map +0 -1
  148. package/dist/typescript/src/components/calendar/components/calendar-week-labels.d.ts.map +0 -1
  149. package/dist/typescript/src/components/calendar/components/calendar-weeks.d.ts.map +0 -1
  150. package/dist/typescript/src/components/calendar/context.d.ts.map +0 -1
  151. package/dist/typescript/src/components/calendar/types.d.ts +0 -37
  152. package/dist/typescript/src/components/calendar/types.d.ts.map +0 -1
  153. package/dist/typescript/src/components/calendar/variants/default.d.ts +0 -3
  154. package/dist/typescript/src/components/calendar/variants/default.d.ts.map +0 -1
  155. package/dist/typescript/src/components/calendar/variants/index.d.ts.map +0 -1
  156. package/src/components/calendar/components/calendar-nav-button.tsx +0 -60
  157. package/src/components/calendar/components/calendar-root.tsx +0 -42
  158. package/src/components/calendar/context.ts +0 -23
  159. package/src/components/calendar/types.ts +0 -39
  160. /package/dist/module/components/calendar/{types.js → calendar/types.js} +0 -0
  161. /package/dist/module/components/calendar/{variants → calendar/variants}/index.js +0 -0
  162. /package/dist/typescript/src/components/calendar/{components → calendar}/calendar-weeks.d.ts +0 -0
  163. /package/dist/typescript/src/components/calendar/{variants → calendar/variants}/index.d.ts +0 -0
  164. /package/dist/typescript/src/components/calendar/{components → shared}/calendar-day.d.ts +0 -0
  165. /package/dist/typescript/src/components/calendar/{components → shared}/calendar-header.d.ts +0 -0
  166. /package/dist/typescript/src/components/calendar/{components → shared}/calendar-title.d.ts +0 -0
  167. /package/dist/typescript/src/components/calendar/{components → shared}/calendar-week-labels.d.ts +0 -0
  168. /package/src/components/calendar/{variants → calendar/variants}/index.ts +0 -0
@@ -0,0 +1,59 @@
1
+ import { useThemedStyles } from "../../../../utils/use-themed-styles";
2
+ import type { TimelineStyles } from "../types";
3
+
4
+ const HOUR_HEIGHT = 60;
5
+ const TIME_COLUMN_WIDTH = 60;
6
+
7
+ export const useTimelineVariantDefault = (): TimelineStyles => {
8
+ return useThemedStyles(
9
+ ({ colors, radius, fontFamily, fontSize }): TimelineStyles => ({
10
+ container: {
11
+ backgroundColor: colors.background,
12
+ borderRadius: radius,
13
+ borderWidth: 1,
14
+ borderColor: colors.border,
15
+ },
16
+ timeline: {
17
+ flexDirection: "row",
18
+ minHeight: HOUR_HEIGHT * 24,
19
+ },
20
+ timeColumn: {
21
+ width: TIME_COLUMN_WIDTH,
22
+ borderRightWidth: 1,
23
+ borderRightColor: colors.border,
24
+ },
25
+ timeSlot: {
26
+ height: HOUR_HEIGHT,
27
+ paddingHorizontal: 8,
28
+ alignItems: "flex-end",
29
+ },
30
+ timeText: {
31
+ fontSize: fontSize * 0.75,
32
+ fontWeight: "500",
33
+ fontFamily,
34
+ color: colors.mutedForeground,
35
+ },
36
+ eventsColumn: {
37
+ flex: 1,
38
+ position: "relative",
39
+ },
40
+ hourLine: {
41
+ height: HOUR_HEIGHT,
42
+ borderBottomWidth: 1,
43
+ borderBottomColor: colors.border,
44
+ },
45
+ currentTimeDot: {
46
+ width: 10,
47
+ height: 10,
48
+ borderRadius: 5,
49
+ marginLeft: -5,
50
+ backgroundColor: colors.danger,
51
+ },
52
+ currentTimeLineBar: {
53
+ flex: 1,
54
+ height: 2,
55
+ backgroundColor: colors.danger,
56
+ },
57
+ }),
58
+ );
59
+ };
@@ -0,0 +1,5 @@
1
+ import { useTimelineVariantDefault } from "./default";
2
+
3
+ export const TimelineVariants = {
4
+ default: useTimelineVariantDefault,
5
+ };
@@ -0,0 +1,3 @@
1
+ export type { WeekCalendarStyles } from "./types";
2
+ export { WeekCalendar } from "./week-calendar";
3
+ export type { WeekCalendarProps } from "./week-calendar";
@@ -0,0 +1,7 @@
1
+ import type { StyleProp, ViewStyle } from "react-native";
2
+ import type { BaseCalendarStyles } from "../shared/types";
3
+
4
+ export interface WeekCalendarStyles extends BaseCalendarStyles {
5
+ weekStrip?: StyleProp<ViewStyle>;
6
+ swipeContainer?: StyleProp<ViewStyle>;
7
+ }
@@ -0,0 +1,141 @@
1
+ import { hslaSetRelativeLightness } from "../../../../utils/hsla-utils";
2
+ import { useThemedStyles } from "../../../../utils/use-themed-styles";
3
+ import type { WeekCalendarStyles } from "../types";
4
+
5
+ export const useWeekCalendarVariantDefault = (): WeekCalendarStyles => {
6
+ return useThemedStyles(
7
+ ({ colors, radius, fontFamily, fontSize }): WeekCalendarStyles => ({
8
+ root: {
9
+ padding: 16,
10
+ backgroundColor: colors.background,
11
+ borderRadius: radius,
12
+ borderWidth: 1,
13
+ borderColor: colors.border,
14
+ },
15
+ header: {
16
+ flexDirection: "row",
17
+ justifyContent: "space-between",
18
+ alignItems: "center",
19
+ marginBottom: 16,
20
+ paddingHorizontal: 8,
21
+ },
22
+ headerTitle: {
23
+ fontSize: fontSize * 1.125,
24
+ fontWeight: "600",
25
+ fontFamily,
26
+ color: colors.foreground,
27
+ },
28
+ navButtons: {
29
+ flexDirection: "row",
30
+ gap: 4,
31
+ },
32
+ navButton: {
33
+ default: {
34
+ width: 32,
35
+ height: 32,
36
+ borderRadius: radius,
37
+ alignItems: "center",
38
+ justifyContent: "center",
39
+ backgroundColor: "transparent",
40
+ },
41
+ disabled: {
42
+ opacity: 0.5,
43
+ },
44
+ hovered: {
45
+ backgroundColor: hslaSetRelativeLightness(colors.secondary, -1),
46
+ },
47
+ },
48
+ navButtonIcon: {
49
+ default: {
50
+ color: colors.foreground,
51
+ size: fontSize * 1.25,
52
+ style: {
53
+ color: colors.foreground,
54
+ fontSize: fontSize * 1.25,
55
+ lineHeight: fontSize * 1.25,
56
+ textAlign: "center",
57
+ fontWeight: "500",
58
+ pointerEvents: "none",
59
+ },
60
+ },
61
+ disabled: {
62
+ color: colors.mutedForeground,
63
+ },
64
+ },
65
+ weekLabels: {
66
+ flexDirection: "row",
67
+ justifyContent: "space-between",
68
+ marginBottom: 8,
69
+ paddingVertical: 8,
70
+ gap: 2,
71
+ },
72
+ weekLabel: {
73
+ fontSize: fontSize * 0.875,
74
+ fontWeight: "500",
75
+ fontFamily,
76
+ color: colors.mutedForeground,
77
+ width: 40,
78
+ textAlign: "center",
79
+ },
80
+ swipeContainer: {
81
+ overflow: "hidden",
82
+ },
83
+ weekStrip: {
84
+ flexDirection: "row",
85
+ justifyContent: "space-between",
86
+ gap: 2,
87
+ },
88
+ dayButton: {
89
+ default: {
90
+ width: 40,
91
+ height: 40,
92
+ borderRadius: radius * 0.5,
93
+ alignItems: "center",
94
+ justifyContent: "center",
95
+ backgroundColor: "transparent",
96
+ },
97
+ selected: {
98
+ backgroundColor: colors.primary,
99
+ },
100
+ today: {
101
+ borderWidth: 1,
102
+ borderColor: colors.primary,
103
+ },
104
+ disabled: {
105
+ opacity: 0.3,
106
+ },
107
+ hovered: {
108
+ backgroundColor: colors.muted,
109
+ },
110
+ },
111
+ dayText: {
112
+ default: {
113
+ fontSize,
114
+ fontFamily,
115
+ color: colors.foreground,
116
+ fontWeight: "400",
117
+ pointerEvents: "none",
118
+ },
119
+ selected: {
120
+ color: colors.primaryForeground,
121
+ fontWeight: "600",
122
+ },
123
+ today: {
124
+ color: colors.primary,
125
+ fontWeight: "600",
126
+ },
127
+ disabled: {
128
+ color: colors.mutedForeground,
129
+ },
130
+ },
131
+ dayMarker: {
132
+ width: 5,
133
+ height: 5,
134
+ borderRadius: 2.5,
135
+ backgroundColor: colors.primary,
136
+ marginTop: 2,
137
+ alignSelf: "center",
138
+ },
139
+ }),
140
+ );
141
+ };
@@ -0,0 +1,5 @@
1
+ import { useWeekCalendarVariantDefault } from "./default";
2
+
3
+ export const WeekCalendarVariants = {
4
+ default: useWeekCalendarVariantDefault,
5
+ };
@@ -0,0 +1,256 @@
1
+ import React, { useCallback, useMemo, useRef, useState } from "react";
2
+ import {
3
+ Platform,
4
+ Pressable,
5
+ ScrollView,
6
+ StyleSheet,
7
+ Text,
8
+ View,
9
+ type NativeScrollEvent,
10
+ type NativeSyntheticEvent,
11
+ type StyleProp,
12
+ type ViewStyle,
13
+ } from "react-native";
14
+ import { useComponentsConfig } from "../../../themes";
15
+ import {
16
+ addWeeks,
17
+ endOfWeek,
18
+ formatDate,
19
+ getWeekDates,
20
+ isDateAfter,
21
+ isDateBefore,
22
+ startOfWeek,
23
+ subWeeks,
24
+ } from "../../../utils/date-utils";
25
+ import {
26
+ CalendarContext,
27
+ type CalendarContextValue,
28
+ } from "../shared/calendar-context";
29
+ import { CalendarDay } from "../shared/calendar-day";
30
+ import type { CalendarNavButtonState } from "../shared/types";
31
+ import { WeekCalendarVariants } from "./variants";
32
+
33
+ const DEFAULT_WEEK_DAYS = ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"];
34
+
35
+ export interface WeekCalendarProps {
36
+ value?: Date | null;
37
+ onChange?: (date: Date | null) => void;
38
+ defaultWeek?: Date;
39
+ minDate?: Date;
40
+ maxDate?: Date;
41
+ markedDates?: Date[];
42
+ weekDays?: string[];
43
+ variant?: keyof typeof WeekCalendarVariants;
44
+ style?: StyleProp<ViewStyle>;
45
+ }
46
+
47
+ const calculateNavState = (
48
+ isDisabled: boolean,
49
+ isHovered: boolean,
50
+ ): CalendarNavButtonState => {
51
+ if (isDisabled) return "disabled";
52
+ if (isHovered) return "hovered";
53
+ return "default";
54
+ };
55
+
56
+ export function WeekCalendar(props: WeekCalendarProps) {
57
+ const {
58
+ value,
59
+ onChange,
60
+ defaultWeek = new Date(),
61
+ minDate,
62
+ maxDate,
63
+ markedDates,
64
+ weekDays = DEFAULT_WEEK_DAYS,
65
+ style,
66
+ } = props;
67
+ const styles = WeekCalendarVariants[props.variant || "default"]();
68
+ const config = useComponentsConfig();
69
+ const PrevIcon = config?.calendar?.prevIcon;
70
+ const NextIcon = config?.calendar?.nextIcon;
71
+
72
+ const [currentWeekStart, setCurrentWeekStart] = useState<Date>(
73
+ startOfWeek(defaultWeek),
74
+ );
75
+ const [containerWidth, setContainerWidth] = useState(0);
76
+ const scrollRef = useRef<React.ComponentRef<typeof ScrollView>>(null);
77
+ const [prevHovered, setPrevHovered] = useState(false);
78
+ const [nextHovered, setNextHovered] = useState(false);
79
+
80
+ const currentMonth = currentWeekStart;
81
+
82
+ const goToPrev = useCallback(() => {
83
+ setCurrentWeekStart((prev) => subWeeks(prev, 1));
84
+ }, []);
85
+
86
+ const goToNext = useCallback(() => {
87
+ setCurrentWeekStart((prev) => addWeeks(prev, 1));
88
+ }, []);
89
+
90
+ const isPrevDisabled = useMemo(() => {
91
+ if (!minDate) return false;
92
+ const prevWeekEnd = endOfWeek(subWeeks(currentWeekStart, 1));
93
+ return isDateBefore(prevWeekEnd, minDate);
94
+ }, [currentWeekStart, minDate]);
95
+
96
+ const isNextDisabled = useMemo(() => {
97
+ if (!maxDate) return false;
98
+ const nextWeekStart = addWeeks(currentWeekStart, 1);
99
+ return isDateAfter(nextWeekStart, maxDate);
100
+ }, [currentWeekStart, maxDate]);
101
+
102
+ const prevState = calculateNavState(isPrevDisabled, prevHovered);
103
+ const nextState = calculateNavState(isNextDisabled, nextHovered);
104
+
105
+ const prevIconProps = StyleSheet.flatten([
106
+ styles.navButtonIcon?.default,
107
+ styles.navButtonIcon?.[prevState],
108
+ ]);
109
+ const nextIconProps = StyleSheet.flatten([
110
+ styles.navButtonIcon?.default,
111
+ styles.navButtonIcon?.[nextState],
112
+ ]);
113
+
114
+ // Strip logic
115
+ const prevWeekDates = getWeekDates(subWeeks(currentWeekStart, 1));
116
+ const currentWeekDates = getWeekDates(currentWeekStart);
117
+ const nextWeekDates = getWeekDates(addWeeks(currentWeekStart, 1));
118
+ const weeks = [prevWeekDates, currentWeekDates, nextWeekDates];
119
+ const scrollKey = currentWeekStart.getTime();
120
+
121
+ const handleScrollEnd = useCallback(
122
+ (event: NativeSyntheticEvent<NativeScrollEvent>) => {
123
+ const offsetX = event.nativeEvent.contentOffset.x;
124
+ const pageIndex = Math.round(offsetX / containerWidth);
125
+
126
+ if (pageIndex === 0) {
127
+ setCurrentWeekStart(subWeeks(currentWeekStart, 1));
128
+ } else if (pageIndex === 2) {
129
+ setCurrentWeekStart(addWeeks(currentWeekStart, 1));
130
+ }
131
+ },
132
+ [containerWidth, currentWeekStart],
133
+ );
134
+
135
+ const contextValue = useMemo<CalendarContextValue>(
136
+ () => ({
137
+ value,
138
+ onChange,
139
+ currentMonth,
140
+ goToPrev,
141
+ goToNext,
142
+ isPrevDisabled,
143
+ isNextDisabled,
144
+ minDate,
145
+ maxDate,
146
+ markedDates,
147
+ styles,
148
+ currentWeekStart,
149
+ setCurrentWeekStart,
150
+ }),
151
+ [
152
+ value,
153
+ onChange,
154
+ currentMonth,
155
+ goToPrev,
156
+ goToNext,
157
+ isPrevDisabled,
158
+ isNextDisabled,
159
+ minDate,
160
+ maxDate,
161
+ markedDates,
162
+ styles,
163
+ currentWeekStart,
164
+ ],
165
+ );
166
+
167
+ return (
168
+ <CalendarContext.Provider value={contextValue}>
169
+ <View style={[styles.root, style]}>
170
+ {/* Header */}
171
+ <View style={styles.header}>
172
+ <Text style={styles.headerTitle}>
173
+ {formatDate(currentMonth, "MMMM yyyy")}
174
+ </Text>
175
+ <View style={styles.navButtons}>
176
+ <Pressable
177
+ onPress={goToPrev}
178
+ onHoverIn={() => setPrevHovered(true)}
179
+ onHoverOut={() => setPrevHovered(false)}
180
+ disabled={isPrevDisabled}
181
+ style={[styles.navButton?.default, styles.navButton?.[prevState]]}
182
+ >
183
+ {PrevIcon ? (
184
+ <PrevIcon {...prevIconProps} />
185
+ ) : (
186
+ <Text style={prevIconProps?.style}>‹</Text>
187
+ )}
188
+ </Pressable>
189
+ <Pressable
190
+ onPress={goToNext}
191
+ onHoverIn={() => setNextHovered(true)}
192
+ onHoverOut={() => setNextHovered(false)}
193
+ disabled={isNextDisabled}
194
+ style={[styles.navButton?.default, styles.navButton?.[nextState]]}
195
+ >
196
+ {NextIcon ? (
197
+ <NextIcon {...nextIconProps} />
198
+ ) : (
199
+ <Text style={nextIconProps?.style}>›</Text>
200
+ )}
201
+ </Pressable>
202
+ </View>
203
+ </View>
204
+
205
+ {/* Week day labels */}
206
+ <View style={styles.weekLabels}>
207
+ {weekDays.map((day, index) => (
208
+ <Text key={index} numberOfLines={1} style={styles.weekLabel}>
209
+ {day}
210
+ </Text>
211
+ ))}
212
+ </View>
213
+
214
+ {/* Swipeable strip */}
215
+ <View
216
+ style={styles.swipeContainer}
217
+ onLayout={(e) => setContainerWidth(e.nativeEvent.layout.width)}
218
+ >
219
+ {containerWidth > 0 && (
220
+ <ScrollView
221
+ ref={scrollRef}
222
+ key={scrollKey}
223
+ horizontal
224
+ pagingEnabled
225
+ showsHorizontalScrollIndicator={false}
226
+ scrollEventThrottle={16}
227
+ onMomentumScrollEnd={handleScrollEnd}
228
+ onLayout={() => {
229
+ if (Platform.OS === "web") {
230
+ scrollRef.current?.scrollTo({
231
+ x: containerWidth,
232
+ animated: false,
233
+ });
234
+ }
235
+ }}
236
+ {...(Platform.OS !== "web"
237
+ ? { contentOffset: { x: containerWidth, y: 0 } }
238
+ : {})}
239
+ >
240
+ {weeks.map((weekDates, weekIndex) => (
241
+ <View
242
+ key={weekIndex}
243
+ style={[styles.weekStrip, { width: containerWidth }]}
244
+ >
245
+ {weekDates.map((date, dayIndex) => (
246
+ <CalendarDay key={dayIndex} date={date} />
247
+ ))}
248
+ </View>
249
+ ))}
250
+ </ScrollView>
251
+ )}
252
+ </View>
253
+ </View>
254
+ </CalendarContext.Provider>
255
+ );
256
+ }
@@ -5,8 +5,8 @@ export * from "./badge";
5
5
  export * from "./button";
6
6
  export * from "./calendar";
7
7
  export * from "./card";
8
- export * from "./combobox";
9
8
  export * from "./checkbox";
9
+ export * from "./combobox";
10
10
  export * from "./empty";
11
11
  export * from "./field";
12
12
  export * from "./icon";
package/src/index.tsx CHANGED
@@ -1,3 +1,4 @@
1
+ import { ScrollBar } from "./components";
1
2
  import { AsyncAlertDialogManager } from "./components/alert-dialog/async-alert-dialog";
2
3
  import { PortalHost } from "./components/portal";
3
4
  import { type PortalHostProps } from "./components/portal/portal.constants";
@@ -31,6 +32,7 @@ export const UIProvider = ({
31
32
  return (
32
33
  <SafeAreaProvider insets={safeAreaInsets}>
33
34
  <ThemeProvider theme={theme} components={components}>
35
+ <ScrollBar />
34
36
  <ToastContainer />
35
37
  {children}
36
38
  <PortalHost container={portalContainer} />
@@ -41,6 +41,10 @@ export interface ComponentsConfig {
41
41
  menu?: {
42
42
  selectionIcon?: React.ComponentType<SvgProps>;
43
43
  };
44
+ calendar?: {
45
+ prevIcon?: React.ComponentType<SvgProps>;
46
+ nextIcon?: React.ComponentType<SvgProps>;
47
+ };
44
48
  }
45
49
 
46
50
  const ThemeContext = createContext<ThemeContext | null>(null);
@@ -8,6 +8,9 @@ export const formatDate = (date: Date, format: string): string => {
8
8
  if (format === "MMMM yyyy") {
9
9
  return `${month} ${year}`;
10
10
  }
11
+ if (format === "MMMM d, yyyy") {
12
+ return `${month} ${day}, ${year}`;
13
+ }
11
14
  if (format === "d") {
12
15
  return day.toString();
13
16
  }
@@ -70,35 +73,23 @@ export const isSameMonth = (date1: Date, date2: Date): boolean => {
70
73
  return date1.getFullYear() === date2.getFullYear() && date1.getMonth() === date2.getMonth();
71
74
  };
72
75
 
73
- export const getWeekDays = (month: number, year: number, week: number): Date[] => {
74
- const days: Date[] = [];
76
+ export const getWeekDays = (month: number, year: number, week: number): (Date | null)[] => {
77
+ const days: (Date | null)[] = [];
75
78
  const firstDayOfMonth = new Date(year, month, 1).getDay();
76
79
  const daysInMonth = getDaysInMonth(new Date(year, month));
77
80
 
78
- // Calculate the date of the first day in the week
79
- const startDay = week * 7 - (firstDayOfMonth === 0 ? 6 : firstDayOfMonth - 1);
81
+ // Calculate the date of the first day in the week (Sunday-start)
82
+ const startDay = week * 7 - firstDayOfMonth + 1;
80
83
 
81
84
  for (let i = 0; i < 7; i++) {
82
85
  const day = startDay + i;
83
- let date: Date;
84
-
85
- if (day < 1) {
86
- // Days from previous month
87
- const prevMonth = month === 0 ? 11 : month - 1;
88
- const prevYear = month === 0 ? year - 1 : year;
89
- const daysInPrevMonth = getDaysInMonth(new Date(prevYear, prevMonth));
90
- date = new Date(prevYear, prevMonth, daysInPrevMonth + day);
91
- } else if (day > daysInMonth) {
92
- // Days from next month
93
- const nextMonth = month === 11 ? 0 : month + 1;
94
- const nextYear = month === 11 ? year + 1 : year;
95
- date = new Date(nextYear, nextMonth, day - daysInMonth);
86
+
87
+ if (day < 1 || day > daysInMonth) {
88
+ // Outside current month — empty cell
89
+ days.push(null);
96
90
  } else {
97
- // Days from current month
98
- date = new Date(year, month, day);
91
+ days.push(new Date(year, month, day));
99
92
  }
100
-
101
- days.push(date);
102
93
  }
103
94
 
104
95
  return days;
@@ -111,3 +102,44 @@ export const getWeeksInMonth = (date: Date): number => {
111
102
  // Calculate total number of weeks
112
103
  return Math.ceil((firstDayOfMonth + daysInMonth) / 7);
113
104
  };
105
+
106
+ export const startOfWeek = (date: Date): Date => {
107
+ const d = new Date(date.getFullYear(), date.getMonth(), date.getDate());
108
+ d.setDate(d.getDate() - d.getDay());
109
+ return d;
110
+ };
111
+
112
+ export const endOfWeek = (date: Date): Date => {
113
+ const d = startOfWeek(date);
114
+ d.setDate(d.getDate() + 6);
115
+ return d;
116
+ };
117
+
118
+ export const getWeekDates = (date: Date): Date[] => {
119
+ const start = startOfWeek(date);
120
+ return Array.from({ length: 7 }, (_, i) => {
121
+ const d = new Date(start);
122
+ d.setDate(start.getDate() + i);
123
+ return d;
124
+ });
125
+ };
126
+
127
+ export const addWeeks = (date: Date, weeks: number): Date => {
128
+ const d = new Date(date);
129
+ d.setDate(d.getDate() + weeks * 7);
130
+ return d;
131
+ };
132
+
133
+ export const subWeeks = (date: Date, weeks: number): Date => {
134
+ return addWeeks(date, -weeks);
135
+ };
136
+
137
+ export const addDays = (date: Date, days: number): Date => {
138
+ const d = new Date(date);
139
+ d.setDate(d.getDate() + days);
140
+ return d;
141
+ };
142
+
143
+ export const subDays = (date: Date, days: number): Date => {
144
+ return addDays(date, -days);
145
+ };
@@ -1 +0,0 @@
1
- {"version":3,"names":["formatDate","isDateAfter","isDateBefore","isDateSameDay","isDateToday","isSameMonth","React","useMemo","useState","Pressable","Text","useCalendarContext","jsx","_jsx","calculateState","date","selected","isCurrentMonth","isDisabled","isHovered","CalendarDay","props","calendar","setIsHovered","currentMonth","minDate","maxDate","state","value","handlePress","onChange","composedStyle","styles","dayButton","default","style","composedTextStyle","dayText","textStyle","onPress","onHoverIn","onHoverOut","disabled","children"],"sourceRoot":"../../../../../src","sources":["components/calendar/components/calendar-day.tsx"],"mappings":"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","ignoreList":[]}
@@ -1 +0,0 @@
1
- {"version":3,"names":["React","View","useCalendarContext","jsx","_jsx","CalendarHeader","props","children","style","viewProps","styles","headerStyle","header"],"sourceRoot":"../../../../../src","sources":["components/calendar/components/calendar-header.tsx"],"mappings":";;AAAA,OAAOA,KAAK,MAAM,OAAO;AACzB,SAASC,IAAI,QAAwD,cAAc;AACnF,SAASC,kBAAkB,QAAQ,eAAY;AAAC,SAAAC,GAAA,IAAAC,IAAA;AAOhD,OAAO,SAASC,cAAcA,CAACC,KAA0B,EAAE;EACzD,MAAM;IAAEC,QAAQ;IAAEC,KAAK;IAAE,GAAGC;EAAU,CAAC,GAAGH,KAAK;EAC/C,MAAM;IAAEI;EAAO,CAAC,GAAGR,kBAAkB,CAAC,CAAC;EAEvC,MAAMS,WAAW,GAAG,CAACD,MAAM,EAAEE,MAAM,EAAEJ,KAAK,CAAC;EAE3C,oBACEJ,IAAA,CAACH,IAAI;IAAA,GAAKQ,SAAS;IAAED,KAAK,EAAEG,WAAY;IAAAJ,QAAA,EACrCA;EAAQ,CACL,CAAC;AAEX","ignoreList":[]}
@@ -1,61 +0,0 @@
1
- "use strict";
2
-
3
- import { addMonths, subMonths } from "../../../utils/date-utils.js";
4
- import React, { useState } from "react";
5
- import { Pressable, Text } from "react-native";
6
- import { useCalendarContext } from "../context.js";
7
- import { jsx as _jsx } from "react/jsx-runtime";
8
- const calculateState = (isDisabled, isHovered) => {
9
- if (isDisabled) return "disabled";
10
- if (isHovered) return "hovered";
11
- return "default";
12
- };
13
- export function CalendarNavButton(props) {
14
- const {
15
- children = props.direction === "prev" ? "‹" : "›",
16
- direction,
17
- style,
18
- textStyle,
19
- ...pressableProps
20
- } = props;
21
- const {
22
- currentMonth,
23
- setCurrentMonth,
24
- minDate,
25
- maxDate,
26
- styles
27
- } = useCalendarContext();
28
- const [isHovered, setIsHovered] = useState(false);
29
- const isDisabled = React.useMemo(() => {
30
- if (direction === "prev" && minDate) {
31
- const prevMonth = subMonths(currentMonth, 1);
32
- return prevMonth < minDate;
33
- }
34
- if (direction === "next" && maxDate) {
35
- const nextMonth = addMonths(currentMonth, 1);
36
- return nextMonth > maxDate;
37
- }
38
- return false;
39
- }, [direction, currentMonth, minDate, maxDate]);
40
- const state = calculateState(isDisabled, isHovered);
41
- const handlePress = () => {
42
- if (isDisabled) return;
43
- const newMonth = direction === "prev" ? subMonths(currentMonth, 1) : addMonths(currentMonth, 1);
44
- setCurrentMonth(newMonth);
45
- };
46
- const buttonStyle = [styles?.navButton?.default, styles?.navButton?.[state], style];
47
- const textStyleCombined = [styles?.navButtonText?.default, styles?.navButtonText?.[state], textStyle];
48
- return /*#__PURE__*/_jsx(Pressable, {
49
- ...pressableProps,
50
- onPress: handlePress,
51
- onHoverIn: () => setIsHovered(true),
52
- onHoverOut: () => setIsHovered(false),
53
- disabled: isDisabled,
54
- style: buttonStyle,
55
- children: /*#__PURE__*/_jsx(Text, {
56
- style: textStyleCombined,
57
- children: children
58
- })
59
- });
60
- }
61
- //# sourceMappingURL=calendar-nav-button.js.map