diff --git a/apps/docs/docs/assets/custom-hour.png b/apps/docs/docs/assets/custom-hour.png
new file mode 100644
index 0000000..4a7cd00
Binary files /dev/null and b/apps/docs/docs/assets/custom-hour.png differ
diff --git a/apps/docs/docs/customization/CalendarBody.md b/apps/docs/docs/customization/CalendarBody.md
new file mode 100644
index 0000000..13306b2
--- /dev/null
+++ b/apps/docs/docs/customization/CalendarBody.md
@@ -0,0 +1,66 @@
+# CalendarBody
+
+`CalendarBody` is a core component of the React Native Calendar Kit. It renders the main calendar grid, including time slots, events, and various interactive elements.
+
+## renderHour
+
+A function that allows customization of the hour labels in the time column of the calendar.
+
+### Description
+
+The `renderHour` prop provides a way to customize the appearance of hour labels in the calendar's time column. When provided, this function will be called for each hour label, allowing you to render custom content instead of the default hour text.
+
+### Parameters
+
+The function receives an object with the following properties:
+
+- `hourStr`: A string representation of the hour (e.g., "9:00 AM").
+- `minutes`: The number of minutes since the start of the day for this hour label.
+- `style`: The default style object applied to the hour label. You can extend or override this style in your custom rendering.
+
+### Return Value
+
+The function should return a React node (e.g., JSX element) that will be rendered as the hour label.
+
+### Example
+
+Here's an example of how to use the `renderHour` prop to create custom hour labels with a colored dot:
+
+```tsx
+const renderHour = useCallback(({ hourStr }: RenderHourProps) => {
+ return (
+
+
+ {hourStr}
+
+ );
+ }, []);
+
+
+
+const styles = StyleSheet.create({
+ hourContainer: {
+ flexDirection: 'row',
+ alignItems: 'center',
+ position: 'absolute',
+ left: 8,
+ right: 0,
+ top: -4,
+ gap: 4,
+ },
+ dot: {
+ width: 6,
+ height: 6,
+ borderRadius: 3,
+ backgroundColor: 'blue',
+ },
+ hourText: {
+ fontWeight: 'bold',
+ fontSize: 8,
+ },
+});
+```
+
+In this example, we're rendering a small blue dot next to each hour label and making the text bold. You can customize this further based on your specific design requirements.
+
+![custom-hour](../assets/custom-hour.png)
diff --git a/apps/docs/docs/customization/_category_.json b/apps/docs/docs/customization/_category_.json
new file mode 100644
index 0000000..ff9116d
--- /dev/null
+++ b/apps/docs/docs/customization/_category_.json
@@ -0,0 +1,6 @@
+{
+ "label": "Customization",
+ "position": 3,
+ "collapsible": true,
+ "collapsed": false
+}
diff --git a/apps/docs/package.json b/apps/docs/package.json
index 1c25aa0..ae09111 100644
--- a/apps/docs/package.json
+++ b/apps/docs/package.json
@@ -21,7 +21,7 @@
"@docusaurus/preset-classic": "3.5.2",
"@docusaurus/remark-plugin-npm2yarn": "^3.5.2",
"@easyops-cn/docusaurus-search-local": "^0.44.5",
- "@howljs/calendar-kit": "2.0.3",
+ "@howljs/calendar-kit": "2.0.6",
"@mdx-js/react": "^3.0.0",
"clsx": "^2.0.0",
"glob": "^10.4.2",
diff --git a/apps/docs/yarn.lock b/apps/docs/yarn.lock
index 665493a..7743c89 100644
--- a/apps/docs/yarn.lock
+++ b/apps/docs/yarn.lock
@@ -2573,9 +2573,9 @@ __metadata:
languageName: node
linkType: hard
-"@howljs/calendar-kit@npm:2.0.3":
- version: 2.0.3
- resolution: "@howljs/calendar-kit@npm:2.0.3"
+"@howljs/calendar-kit@npm:2.0.6":
+ version: 2.0.6
+ resolution: "@howljs/calendar-kit@npm:2.0.6"
dependencies:
lodash.debounce: "npm:^4.0.8"
lodash.isequal: "npm:^4.5.0"
@@ -2594,7 +2594,7 @@ __metadata:
optional: true
react-native-haptic-feedback:
optional: true
- checksum: 10/3bcca8efd70749a524e4732366e9efef3f102a46549a1a6bcd9a8edebad84aad16ee6bf27eed40b5464e4469a5ac9c94825425c0f88dd03d2e7bf78769d82b41
+ checksum: 10/330c774a4d5c054cd2577cbddcc3b27f7909d56c747f42baef3cfa71eaddb9a57057beb8850137ae3d7685b64e8650a151cdd2559ad10fe4a7b56bf476f2d5b3
languageName: node
linkType: hard
@@ -5036,7 +5036,7 @@ __metadata:
"@docusaurus/tsconfig": "npm:3.5.2"
"@docusaurus/types": "npm:3.5.2"
"@easyops-cn/docusaurus-search-local": "npm:^0.44.5"
- "@howljs/calendar-kit": "npm:2.0.3"
+ "@howljs/calendar-kit": "npm:2.0.6"
"@mdx-js/react": "npm:^3.0.0"
clsx: "npm:^2.0.0"
glob: "npm:^10.4.2"
diff --git a/packages/react-native-calendar-kit/src/CalendarHeader.tsx b/packages/react-native-calendar-kit/src/CalendarHeader.tsx
index 721eb55..d9a8577 100644
--- a/packages/react-native-calendar-kit/src/CalendarHeader.tsx
+++ b/packages/react-native-calendar-kit/src/CalendarHeader.tsx
@@ -42,6 +42,7 @@ const CalendarHeader: React.FC = ({
eventMinMinutes = MIN_ALL_DAY_MINUTES,
eventMaxMinutes = MAX_ALL_DAY_MINUTES,
eventInitialMinutes = DEFAULT_ALL_DAY_MINUTES,
+ renderDayItem,
}) => {
const {
calendarLayout,
@@ -202,6 +203,7 @@ const CalendarHeader: React.FC = ({
renderEvent,
renderExpandIcon,
resources,
+ renderDayItem,
}),
[
calendarData.minDateUnix,
@@ -211,6 +213,7 @@ const CalendarHeader: React.FC = ({
renderEvent,
renderExpandIcon,
resources,
+ renderDayItem,
]
);
@@ -244,6 +247,7 @@ const CalendarHeader: React.FC = ({
renderExpandIcon={extra.renderExpandIcon}
renderEvent={extra.renderEvent}
pageIndex={index}
+ renderDayItem={extra.renderDayItem}
/>
);
}
@@ -253,6 +257,7 @@ const CalendarHeader: React.FC = ({
pageIndex={index * extra.columns}
startUnix={dateUnixByIndex}
renderEvent={extra.renderEvent}
+ renderDayItem={extra.renderDayItem}
/>
);
};
diff --git a/packages/react-native-calendar-kit/src/components/DayItem.tsx b/packages/react-native-calendar-kit/src/components/DayItem.tsx
index c092a31..9aa6bd2 100644
--- a/packages/react-native-calendar-kit/src/components/DayItem.tsx
+++ b/packages/react-native-calendar-kit/src/components/DayItem.tsx
@@ -1,5 +1,11 @@
-import React, { useMemo } from 'react';
-import { StyleSheet, TouchableOpacity, View } from 'react-native';
+import React, { PropsWithChildren, useMemo } from 'react';
+import {
+ StyleProp,
+ StyleSheet,
+ TouchableOpacity,
+ View,
+ ViewStyle,
+} from 'react-native';
import { useActions } from '../context/ActionsProvider';
import { useHighlightDates } from '../context/HighlightDatesProvider';
import { useLocale } from '../context/LocaleProvider';
@@ -11,6 +17,8 @@ import Text from './Text';
interface DayItemProps {
dateUnix: number;
+ showDayItem?: boolean;
+ dayItemContainerStyle?: StyleProp;
}
const selectDayItemTheme = (state: ThemeConfigs) => ({
@@ -26,7 +34,12 @@ const selectDayItemTheme = (state: ThemeConfigs) => ({
dayContainer: state.dayContainer,
});
-const DayItem: React.FC = ({ dateUnix }) => {
+const DayItem: React.FC> = ({
+ dateUnix,
+ children,
+ showDayItem = true,
+ dayItemContainerStyle,
+}) => {
const { weekDayShort } = useLocale();
const { currentDateUnix } = useNowIndicator();
const { onPressDayNumber } = useActions();
@@ -79,32 +92,37 @@ const DayItem: React.FC = ({ dateUnix }) => {
};
return (
-
-
-
- {weekDayShort[date.weekday % 7]}
-
+
+ {showDayItem && (
+
+
+
+ {weekDayShort[date.weekday % 7]}
+
-
-
- {date.day}
-
-
-
-
+
+
+ {date.day}
+
+
+
+
+ )}
+ {children}
+
);
};
diff --git a/packages/react-native-calendar-kit/src/components/MultiDayBarItem.tsx b/packages/react-native-calendar-kit/src/components/MultiDayBarItem.tsx
index a12e4af..31a856b 100644
--- a/packages/react-native-calendar-kit/src/components/MultiDayBarItem.tsx
+++ b/packages/react-native-calendar-kit/src/components/MultiDayBarItem.tsx
@@ -34,12 +34,14 @@ interface MultiDayBarItemProps {
event: PackedAllDayEvent,
size: SizeAnimation
) => React.ReactNode;
+ renderDayItem?: (date: { dateUnix: number }) => React.ReactNode;
}
const MultiDayBarItem: React.FC = ({
pageIndex,
startUnix,
renderEvent,
+ renderDayItem,
}) => {
const dayBarStyles = useTheme(
useCallback(
@@ -122,7 +124,11 @@ const MultiDayBarItem: React.FC = ({
key={`column_${visibleDates[date].unix}`}
pointerEvents="box-none"
style={animStyle}>
-
+ {renderDayItem ? (
+ renderDayItem({ dateUnix: visibleDates[date].unix })
+ ) : (
+
+ )}
);
};
diff --git a/packages/react-native-calendar-kit/src/components/SingleDayBarItem.tsx b/packages/react-native-calendar-kit/src/components/SingleDayBarItem.tsx
index 8ef54db..2e59462 100644
--- a/packages/react-native-calendar-kit/src/components/SingleDayBarItem.tsx
+++ b/packages/react-native-calendar-kit/src/components/SingleDayBarItem.tsx
@@ -41,6 +41,7 @@ interface SingleDayBarItemProps {
size: SizeAnimation
) => React.ReactNode;
pageIndex: number;
+ renderDayItem?: (date: { dateUnix: number }) => React.ReactNode;
}
const SingleDayBarItem = ({
@@ -48,6 +49,7 @@ const SingleDayBarItem = ({
renderExpandIcon,
renderEvent,
pageIndex,
+ renderDayItem,
}: SingleDayBarItemProps) => {
const dayBarStyles = useTheme(
useCallback(
@@ -135,7 +137,11 @@ const SingleDayBarItem = ({
styles.dayItemContainer,
{ width: hourWidth, borderRightColor: dayBarStyles.borderColor },
]}>
-
+ {renderDayItem ? (
+ renderDayItem({ dateUnix: startUnix })
+ ) : (
+
+ )}
-
+ {renderDayItem ? (
+ renderDayItem({ dateUnix: startUnix })
+ ) : (
+
+ )}
);
};
diff --git a/packages/react-native-calendar-kit/src/index.tsx b/packages/react-native-calendar-kit/src/index.tsx
index ab3df51..22689ad 100644
--- a/packages/react-native-calendar-kit/src/index.tsx
+++ b/packages/react-native-calendar-kit/src/index.tsx
@@ -8,6 +8,7 @@ export { default as CalendarHeader } from './CalendarHeader';
export { default as ResourceHeaderItem } from './components/ResourceHeaderItem';
export { default as MultiDayBarItem } from './components/MultiDayBarItem';
export { default as SingleDayBarItem } from './components/SingleDayBarItem';
+export { default as DayItem } from './components/DayItem';
export { useActions } from './context/ActionsProvider';
export { useBody } from './context/BodyContext';
@@ -48,7 +49,7 @@ export { DraggingEvent } from './components/DraggingEvent';
export type { WeekdayNumbers } from 'luxon';
-export { parseDateTime } from './utils/dateUtils';
+export * from './utils/dateUtils';
export * from './service/rrule';
diff --git a/packages/react-native-calendar-kit/src/types.ts b/packages/react-native-calendar-kit/src/types.ts
index 501c554..86682d5 100644
--- a/packages/react-native-calendar-kit/src/types.ts
+++ b/packages/react-native-calendar-kit/src/types.ts
@@ -630,20 +630,36 @@ export interface CalendarHeaderProps {
*/
dayBarHeight?: number;
- /** Custom header item */
+ /** Custom header item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderHeaderItem?: (props: HeaderItemProps) => React.ReactElement | null;
- /** Custom expand icon */
+ /** Custom expand icon
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderExpandIcon?: (props: {
isExpanded: SharedValue;
}) => React.ReactElement | null;
- /** Custom event item */
+ /** Custom event item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderEvent?: (
event: PackedAllDayEvent,
size: SizeAnimation
) => React.ReactNode;
+ /**
+ * Custom day item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
+ renderDayItem?: (date: { dateUnix: number }) => React.ReactNode;
+
/** Custom left area (multiple days) */
LeftAreaComponent?: React.ReactElement | null | undefined;
@@ -681,20 +697,33 @@ export interface CalendarBodyProps {
/** Custom hour text */
hourFormat?: string;
- /** Custom hour text */
+ /** Custom hour text
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderHour?: (props: RenderHourProps) => React.ReactElement | null;
+ /** Custom dragging hour text
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderDraggingHour?: (props: RenderHourProps) => React.ReactElement | null;
/** Show now indicator */
showNowIndicator?: boolean;
- /** Custom Out of Range item */
+ /** Custom Out of Range item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderCustomOutOfRange?: (
props: OutOfRangeProps
) => React.ReactElement | null;
- /** Custom Unavailable Item */
+ /** Custom Unavailable Item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderCustomUnavailableHour?: (
props: UnavailableHourProps & {
width: SharedValue;
@@ -702,18 +731,27 @@ export interface CalendarBodyProps {
}
) => React.ReactElement | null;
- /** Custom event item */
+ /** Custom event item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderEvent?: (
event: PackedEvent,
size: SizeAnimation
) => React.ReactElement | null;
- /** Custom draggable event item */
+ /** Custom draggable event item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderDraggableEvent?: (
props: DraggableEventProps
) => React.ReactElement | null;
- /** Custom dragging event item */
+ /** Custom dragging event item
+ *
+ * Note: Please use `useCallback` to memoize the function
+ */
renderDraggingEvent?: (
props: DraggingEventProps
) => React.ReactElement | null;