([
new Date(),
new Date(),
@@ -68,157 +71,365 @@ const App = () => {
>
Star
-
- Source code of all examples
+
+ 🔗 Source code of all examples
-
-
- closeOnSelect:
- setSingleCheck(e.currentTarget.checked)}
- />
-
-
-
-
-
- closeOnSelect:
- setRangeCheck(e.currentTarget.checked)}
- />
-
-
-
-
- Custom Styles:
-
- If you used light/dark theme, just be aware of your style under
- specific mode.
-
-
-
-
-
-
-
- First Day of Week: {Weekday_Names_Short[firstDayOfWeek || 0]}
-
- {offsets.map((e) => (
-
- ))}
-
-
-
-
+
+ If you used light/dark theme, just be aware of your style under specific
+ mode.
+
+
+
+
+
+ Single & Range
+
+
+ Custom Styles
+
+
+ Custom Month/Weekday/Format
+
+
+ With Offset
+
+
+ Calendar
+
+
+
+
+
+
+
+ closeOnSelect:
+ setSingleCheck(e.currentTarget.checked)}
+ />
+
+
+
+
+
+ closeOnSelect:
+ setRangeCheck(e.currentTarget.checked)}
+ />
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Check the month name and day labels
+
+
+
+
+
+
+
+
+ First Day of Week: {Weekday_Names_Short[firstDayOfWeek || 0]}
+
+
+ {offsets.map((e) => (
+
+ ))}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
);
};
+const SingleCalendarDemo = () => {
+ const demoDate = new Date();
+ const [date, setDate] = useState(demoDate);
+
+ const handleOnDateSelected = (props: {
+ date: Date;
+ nextMonth: boolean;
+ prevMonth: boolean;
+ selectable: boolean;
+ selected: boolean;
+ today: boolean;
+ }) => {
+ const { date } = props;
+ if (date instanceof Date && !isNaN(date.getTime())) {
+ setDate(date);
+ }
+ };
+
+ return (
+
+ {format(date, 'yyyy-MM-dd')}
+
+
+ );
+};
+
+const RangeCalendarDemo = () => {
+ const demoDate = new Date();
+ const [selectedDates, setSelectedDates] = useState([
+ demoDate,
+ demoDate,
+ ]);
+
+ const handleOnDateSelected: OnDateSelected = ({ selectable, date }) => {
+ let newDates = [...selectedDates];
+ if (selectedDates.length) {
+ if (selectedDates.length === 1) {
+ let firstTime = selectedDates[0];
+ if (firstTime < date) {
+ newDates.push(date);
+ } else {
+ newDates.unshift(date);
+ }
+ setSelectedDates(newDates);
+ return;
+ }
+
+ if (newDates.length === 2) {
+ setSelectedDates([date]);
+ return;
+ }
+ } else {
+ newDates.push(date);
+ setSelectedDates(newDates);
+ }
+ };
+
+ // eventually we want to allow user to freely type their own input and parse the input
+ let intVal = selectedDates[0]
+ ? `${format(selectedDates[0], 'yyyy-MM-dd')}`
+ : '';
+ intVal += selectedDates[1]
+ ? ` - ${format(selectedDates[1], 'yyyy-MM-dd')}`
+ : '';
+
+ return (
+
+ {intVal}
+
+
+ );
+};
+
+const Section: React.FC> = ({
+ title,
+ children,
+}) => (
+
+ {title}
+ {children}
+
+);
+
+const Panel: React.FC> = ({ children }) => (
+
+
+
+
+ {children}
+
+);
+
const config: ThemeConfig = {
initialColorMode: 'light',
useSystemColorMode: false,
diff --git a/src/components/calendarPanel.tsx b/src/components/calendarPanel.tsx
index 1ee8370..8c930c4 100644
--- a/src/components/calendarPanel.tsx
+++ b/src/components/calendarPanel.tsx
@@ -14,9 +14,10 @@ import { CalendarConfigs, DatepickerProps } from '../utils/commonTypes';
import { DatepickerBackBtns, DatepickerForwardBtns } from './dateNavBtns';
import { DayOfMonth } from './dayOfMonth';
-interface CalendarPanelProps extends DatepickerProps {
+export interface CalendarPanelProps extends DatepickerProps {
dayzedHookProps: Omit;
configs: CalendarConfigs;
+ disabledDates?: Set;
onMouseEnterHighlight?: (date: Date) => void;
isInRange?: (date: Date) => boolean | null;
}
@@ -25,6 +26,7 @@ export const CalendarPanel: React.FC = ({
dayzedHookProps,
configs,
propsConfigs,
+ disabledDates,
onMouseEnterHighlight,
isInRange,
}) => {
@@ -125,6 +127,7 @@ export const CalendarPanel: React.FC = ({
propsConfigs={propsConfigs}
renderProps={renderProps}
isInRange={isInRange && isInRange(date)}
+ disabledDates={disabledDates}
onMouseEnter={() => {
if (onMouseEnterHighlight) onMouseEnterHighlight(date);
}}
diff --git a/src/components/dayOfMonth.tsx b/src/components/dayOfMonth.tsx
index ceb863f..2e892fd 100644
--- a/src/components/dayOfMonth.tsx
+++ b/src/components/dayOfMonth.tsx
@@ -6,6 +6,7 @@ import { DatepickerProps, DayOfMonthBtnStyleProps } from '../utils/commonTypes';
interface DayOfMonthProps extends DatepickerProps {
renderProps: RenderProps;
isInRange?: boolean | null;
+ disabledDates?: Set;
dateObj: DateObj;
onMouseEnter?: React.MouseEventHandler | undefined;
}
@@ -20,6 +21,7 @@ export const DayOfMonth: React.FC = ({
dateObj,
propsConfigs,
isInRange,
+ disabledDates,
renderProps,
onMouseEnter,
}) => {
@@ -31,14 +33,12 @@ export const DayOfMonth: React.FC = ({
selectedBtnProps,
todayBtnProps,
} = propsConfigs?.dayOfMonthBtnProps || {};
-
+ const disabled = !selectable || disabledDates?.has(date.getTime());
const styleBtnProps: DayOfMonthBtnStyleProps = useMemo(
() => ({
defaultBtnProps: {
size: 'sm',
variant: 'ghost',
- // background: 'transparent',
- // borderColor: 'transparent',
// this intends to fill the visual gap from Grid to improve the UX
// so the button active area is actually larger than what it's seen
...defaultBtnProps,
@@ -76,26 +76,20 @@ export const DayOfMonth: React.FC = ({
...todayBtnProps,
},
}),
- [
- defaultBtnProps,
- isInRangeBtnProps,
- selectedBtnProps,
- todayBtnProps,
- selectable,
- ]
+ [defaultBtnProps, isInRangeBtnProps, selectedBtnProps, todayBtnProps]
);
return (