feat(DatePicker): add DatePicker draggable cell

This commit is contained in:
Sergey Krylov 2024-05-21 06:55:54 +03:00
parent 38457fbcff
commit d012eb21a2
22 changed files with 763 additions and 265 deletions

View File

@ -12,4 +12,7 @@ module.exports = {
'./configs/jest/__mocks__/fileMock.js',
'\\.(css|less|scss)$': 'identity-obj-proxy',
},
transformIgnorePatterns: [
'/node_modules/(?!react-dnd|dnd-core|@react-dnd|react-dnd-html5-backend)',
],
};

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -35,6 +35,8 @@
"normalize.css": "8.0.1",
"prop-types": "15.8.1",
"react": "18.2.0",
"react-dnd": "^16.0.1",
"react-dnd-html5-backend": "^16.0.1",
"react-dom": "18.2.0",
"react-router-dom": "6.22.3"
},

View File

@ -0,0 +1,3 @@
export const ItemTypes = {
CELL: 'date-cell',
};

View File

@ -6,3 +6,4 @@ export type {
WeekDaysKeys,
WeekDaysValues,
} from './date';
export { ItemTypes } from './drag';

View File

@ -1,16 +0,0 @@
.firstDate {
background-color: blue;
color: white;
border-top-left-radius: 10px
}
.inSelection {
background: gold;
color: darkgrey;
}
.lastDate {
background-color: blue;
color: white;
border-bottom-right-radius: 10px
}

View File

@ -1,262 +1,44 @@
import classnames from 'classnames';
import { useState } from 'react';
import type { DataDateString } from 'shared/types/date';
import { daysCountBetween, getDataDateString } from 'shared/utils/date';
import { exhaustiveCheck } from 'shared/utils/type';
import { useContext } from 'react';
import { DndProvider } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend';
import { CalendarWidget } from '../../CalendarWidget';
import classes from './DatePicker.style.module.css';
import { CustomDragLayer } from './components/CustomDragLayer';
import { DraggableCell } from './components/DraggableCell';
import DatePickerContextProvider, { DatePickerContext } from './DatePickerContext';
import type { DatePickerContextProviderProps } from './DatePickerContext';
import type { CalendarWidgetProps } from '../../CalendarWidget';
import type { FC } from 'react';
export type DatePickerProps = CalendarWidgetProps & {
firstDate?: Date;
lastDate?: Date;
onSelect?: (params: { dataDate: DataDateString; date: Date; type: 'firstDate' | 'lastDate' }) => void;
onUnselect?: (params: { dataDate: DataDateString; date: Date; type: 'firstDate' | 'lastDate' }) => void;
};
export type DatePickerProps = CalendarWidgetProps & Omit<DatePickerContextProviderProps, 'children'>;
const DatePicker: FC<DatePickerProps> = (props) => {
const {
firstDate,
lastDate,
onSelect,
onUnselect,
...restWidgetProps
} = props;
const [firstSelectedDate, setFirstSelectedDate] = useState<DataDateString | null>(
firstDate
? getDataDateString(firstDate)
: null,
);
const [lastSelectedDate, setLastSelectedDate] = useState<DataDateString | null>(
lastDate
? getDataDateString(lastDate)
: null,
);
const isSelectedFirstDate = firstSelectedDate !== null;
const isSelectedLastDate = lastSelectedDate !== null;
const isSelectedBothDate = isSelectedFirstDate && isSelectedLastDate;
const isCellInSelection = (dataDate: DataDateString) => {
if (!isSelectedFirstDate || !isSelectedLastDate) {
return false;
}
const dateTime = new Date(dataDate).getTime();
const firstDateTime = new Date(firstSelectedDate).getTime();
const lastDateTime = new Date(lastSelectedDate).getTime();
return dateTime >= firstDateTime && dateTime <= lastDateTime;
};
const toggleCellDate = (params: { dataDate: DataDateString | null; type: 'firstDate' | 'lastDate' }) => {
const { dataDate, type } = params;
if (dataDate === null) {
let typedDataDate: DataDateString;
switch (type) {
case 'firstDate':
if (!isSelectedFirstDate) {
return;
}
typedDataDate = firstSelectedDate;
setFirstSelectedDate(null);
break;
case 'lastDate':
if (!isSelectedLastDate) {
return;
}
typedDataDate = lastSelectedDate;
setLastSelectedDate(null);
break;
default:
exhaustiveCheck(type);
break;
}
onUnselect?.({
type,
// @ts-ignore
dataDate: typedDataDate,
// @ts-ignore
date: new Date(typedDataDate),
});
return;
}
switch (type) {
case 'firstDate':
setFirstSelectedDate(dataDate);
break;
case 'lastDate':
setLastSelectedDate(dataDate);
break;
default:
exhaustiveCheck(type);
break;
}
onSelect?.({
type,
dataDate,
date: new Date(dataDate),
});
};
const toggleCellSelection = (dataDate: DataDateString) => {
if (!isSelectedFirstDate && !isSelectedLastDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (isSelectedFirstDate && !isSelectedLastDate) {
if (dataDate < firstSelectedDate) {
toggleCellDate({ dataDate: firstSelectedDate, type: 'lastDate' });
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (dataDate > firstSelectedDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
toggleCellDate({ dataDate: null, type: 'firstDate' });
}
if (!isSelectedFirstDate && isSelectedLastDate) {
if (dataDate < lastSelectedDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (dataDate > lastSelectedDate) {
toggleCellDate({ dataDate: lastSelectedDate, type: 'firstDate' });
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
toggleCellDate({ dataDate: null, type: 'lastDate' });
}
if (isSelectedBothDate) {
if (dataDate < firstSelectedDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (dataDate > lastSelectedDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
if (dataDate === firstSelectedDate) {
toggleCellDate({ dataDate: null, type: 'firstDate' });
return;
}
if (dataDate === lastSelectedDate) {
toggleCellDate({ dataDate: null, type: 'lastDate' });
return;
}
const daysToFirstDate = daysCountBetween(new Date(firstSelectedDate), new Date(dataDate));
const daysToLastDate = daysCountBetween(new Date(lastSelectedDate), new Date(dataDate));
if (daysToFirstDate < daysToLastDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (daysToFirstDate > daysToLastDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
toggleCellDate({ dataDate, type: 'firstDate' });
}
};
const isFirstDate = (dataDate: DataDateString) => dataDate === firstSelectedDate;
const isLastDate = (dataDate: DataDateString) => dataDate === lastSelectedDate;
const getDataTestId = (dataDate: DataDateString) => {
if (isFirstDate(dataDate)) {
return {
'data-testid': 'first-selected-cell',
};
}
if (isLastDate(dataDate)) {
return {
'data-testid': 'last-selected-cell',
};
}
if (isCellInSelection(dataDate)) {
return {
'data-testid': 'cell-in-range',
};
}
return {};
};
const MyCalendar: FC<CalendarWidgetProps> = (props) => {
const { toggleCellSelection, getDataTestId } = useContext(DatePickerContext);
return (
<div>
<button
type="button"
onClick={() => {
setLastSelectedDate(null);
setFirstSelectedDate(null);
}}
onKeyPress={() => {}}
>
reset
</button>
<CalendarWidget
DateCellProps={({ dataDate }) => ({
onClick: () => {
toggleCellSelection(dataDate);
},
className: classnames({
[classes.firstDate as string]: isFirstDate(dataDate),
[classes.inSelection as string]: isCellInSelection(dataDate)
&& !isFirstDate(dataDate)
&& !isLastDate(dataDate),
[classes.lastDate as string]: isLastDate(dataDate),
}),
...getDataTestId(dataDate),
})}
{...restWidgetProps}
/>
</div>
<CalendarWidget
DateCellComponent={DraggableCell}
DateCellProps={({ dataDate }) => ({
onClick: () => {
toggleCellSelection(dataDate);
},
...getDataTestId(dataDate),
})}
{...props}
/>
);
};
const DatePicker: FC<DatePickerProps> = (props) => (
<DndProvider backend={HTML5Backend}>
<DatePickerContextProvider {...props}>
<MyCalendar {...props} />
<CustomDragLayer />
</DatePickerContextProvider>
</DndProvider>
);
export default DatePicker;

View File

@ -0,0 +1,282 @@
import {
createContext,
useCallback,
useMemo,
useState,
} from 'react';
import type { DataDateString } from 'shared/types/date';
import { daysCountBetween, getDataDateString } from 'shared/utils/date';
import { exhaustiveCheck } from 'shared/utils/type';
import type { FC, ReactNode } from 'react';
type DatePickerContextValue = {
firstSelectedDate: DataDateString | null;
lastSelectedDate: DataDateString | null;
isSelectedFirstDate: boolean;
isSelectedLastDate: boolean;
isSelectedBothDate: boolean;
isCellInSelection: (dataDate: DataDateString) => boolean;
toggleCellDate: (params: { dataDate: DataDateString | null; type: 'firstDate' | 'lastDate' }) => void;
toggleCellSelection: (dataDate: DataDateString) => void;
isFirstDate: (dataDate: DataDateString) => boolean;
isLastDate: (dataDate: DataDateString) => boolean;
getDataTestId: (dataDate: DataDateString) => Record<'data-testid', string> | null;
};
export const DatePickerContext = createContext<DatePickerContextValue>({} as DatePickerContextValue);
export type DatePickerContextProviderProps = {
firstDate?: Date;
lastDate?: Date;
onSelect?: (params: { dataDate: DataDateString; date: Date; type: 'firstDate' | 'lastDate' }) => void;
onUnselect?: (params: { dataDate: DataDateString; date: Date; type: 'firstDate' | 'lastDate' }) => void;
children: ReactNode;
};
const DatePickerContextProvider: FC<DatePickerContextProviderProps> = (props) => {
const {
children,
firstDate,
lastDate,
onUnselect,
onSelect,
} = props;
const [firstSelectedDate, setFirstSelectedDate] = useState<DataDateString | null>(
firstDate
? getDataDateString(firstDate)
: null,
);
const [lastSelectedDate, setLastSelectedDate] = useState<DataDateString | null>(
lastDate
? getDataDateString(lastDate)
: null,
);
const isSelectedFirstDate = firstSelectedDate !== null;
const isSelectedLastDate = lastSelectedDate !== null;
const isSelectedBothDate = isSelectedFirstDate && isSelectedLastDate;
const isCellInSelection = useCallback((dataDate: DataDateString) => {
if (!isSelectedFirstDate || !isSelectedLastDate) {
return false;
}
const dateTime = new Date(dataDate).getTime();
const firstDateTime = new Date(firstSelectedDate).getTime();
const lastDateTime = new Date(lastSelectedDate).getTime();
return dateTime >= firstDateTime && dateTime <= lastDateTime;
}, [firstSelectedDate, isSelectedFirstDate, isSelectedLastDate, lastSelectedDate]);
const toggleCellDate = useCallback((params: { dataDate: DataDateString | null; type: 'firstDate' | 'lastDate' }) => {
const { dataDate, type } = params;
if (dataDate === null) {
let typedDataDate: DataDateString;
switch (type) {
case 'firstDate':
if (!isSelectedFirstDate) {
return;
}
typedDataDate = firstSelectedDate;
setFirstSelectedDate(null);
break;
case 'lastDate':
if (!isSelectedLastDate) {
return;
}
typedDataDate = lastSelectedDate;
setLastSelectedDate(null);
break;
default:
exhaustiveCheck(type);
break;
}
onUnselect?.({
type,
// @ts-ignore
dataDate: typedDataDate,
// @ts-ignore
date: new Date(typedDataDate),
});
return;
}
switch (type) {
case 'firstDate':
setFirstSelectedDate(dataDate);
break;
case 'lastDate':
setLastSelectedDate(dataDate);
break;
default:
exhaustiveCheck(type);
break;
}
onSelect?.({
type,
dataDate,
date: new Date(dataDate),
});
}, [firstSelectedDate, isSelectedFirstDate, isSelectedLastDate, lastSelectedDate, onSelect, onUnselect]);
const toggleCellSelection = useCallback((dataDate: DataDateString) => {
if (!isSelectedFirstDate && !isSelectedLastDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (isSelectedFirstDate && !isSelectedLastDate) {
if (dataDate < firstSelectedDate) {
toggleCellDate({ dataDate: firstSelectedDate, type: 'lastDate' });
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (dataDate > firstSelectedDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
toggleCellDate({ dataDate: null, type: 'firstDate' });
}
if (!isSelectedFirstDate && isSelectedLastDate) {
if (dataDate < lastSelectedDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (dataDate > lastSelectedDate) {
toggleCellDate({ dataDate: lastSelectedDate, type: 'firstDate' });
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
toggleCellDate({ dataDate: null, type: 'lastDate' });
}
if (isSelectedBothDate) {
if (dataDate < firstSelectedDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (dataDate > lastSelectedDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
if (dataDate === firstSelectedDate) {
toggleCellDate({ dataDate: null, type: 'firstDate' });
return;
}
if (dataDate === lastSelectedDate) {
toggleCellDate({ dataDate: null, type: 'lastDate' });
return;
}
const daysToFirstDate = daysCountBetween(new Date(firstSelectedDate), new Date(dataDate));
const daysToLastDate = daysCountBetween(new Date(lastSelectedDate), new Date(dataDate));
if (daysToFirstDate < daysToLastDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
return;
}
if (daysToFirstDate > daysToLastDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
return;
}
toggleCellDate({ dataDate, type: 'firstDate' });
}
}, [
firstSelectedDate,
isSelectedBothDate,
isSelectedFirstDate,
isSelectedLastDate,
lastSelectedDate,
toggleCellDate,
]);
const isFirstDate = useCallback((dataDate: DataDateString) => dataDate === firstSelectedDate, [firstSelectedDate]);
const isLastDate = useCallback((dataDate: DataDateString) => dataDate === lastSelectedDate, [lastSelectedDate]);
const getDataTestId = useCallback((dataDate: DataDateString) => {
if (isFirstDate(dataDate)) {
return {
'data-testid': 'first-selected-cell',
};
}
if (isLastDate(dataDate)) {
return {
'data-testid': 'last-selected-cell',
};
}
if (isCellInSelection(dataDate)) {
return {
'data-testid': 'cell-in-range',
};
}
return null;
}, [isCellInSelection, isFirstDate, isLastDate]);
const value: DatePickerContextValue = useMemo(() => ({
firstSelectedDate,
lastSelectedDate,
isSelectedFirstDate,
isSelectedLastDate,
isSelectedBothDate,
isCellInSelection,
toggleCellDate,
toggleCellSelection,
isFirstDate,
isLastDate,
getDataTestId,
}), [
firstSelectedDate,
getDataTestId,
isCellInSelection,
isFirstDate,
isLastDate,
isSelectedBothDate,
isSelectedFirstDate,
isSelectedLastDate,
lastSelectedDate,
toggleCellDate,
toggleCellSelection,
]);
return (
<DatePickerContext.Provider value={value}>
{children}
</DatePickerContext.Provider>
);
};
export default DatePickerContextProvider;

View File

@ -0,0 +1 @@
export { default as CustomDragLayer } from './ui/CustomDragLayer.ui';

View File

@ -0,0 +1,13 @@
.root {
height: 35px;
width: 35px;
background-color: #1892ff;
opacity: 0.8;
border-radius: 50%;
position: fixed;
z-index: 999;
pointer-events: none;
top: 0;
left: 0;
cursor: grabbing;
}

View File

@ -0,0 +1,74 @@
import { useDragLayer } from 'react-dnd';
import { ItemTypes } from 'shared/constants';
import classes from './CustomDragLayer.style.module.css';
import type { XYCoord } from 'react-dnd';
const snapToGrid = (x: number, y: number) => {
const snappedX = Math.round(x / 53) * 53;
const snappedY = Math.round(y / 41) * 41;
return [snappedX, snappedY];
};
const getDragLayerStyles = (
initialOffset: XYCoord | null,
currentOffset: XYCoord | null,
) => {
if (!initialOffset || !currentOffset) {
return {
display: 'none',
};
}
let { x = 0, y = 0 } = currentOffset;
x -= initialOffset.x || 0;
y -= initialOffset.y || 0;
// @ts-ignore
[x, y] = snapToGrid(x, y);
x += initialOffset.x || 0;
y += initialOffset.y || 0;
const transform = `translate(${Math.round(x) + 8.5}px, ${Math.round(y) + 3}px)`;
return {
transform,
WebkitTransform: transform,
};
};
const CustomDragLayer = () => {
const {
itemType,
isDragging,
sourceClientOffset,
initialSourceClientOffset,
} = useDragLayer((monitor) => ({
itemType: monitor.getItemType(),
initialSourceClientOffset: monitor.getInitialSourceClientOffset(),
sourceClientOffset: monitor.getSourceClientOffset(),
isDragging: monitor.isDragging(),
}));
if (itemType !== ItemTypes.CELL) {
return null;
}
if (!isDragging) {
return null;
}
const transformStyles = getDragLayerStyles(initialSourceClientOffset, sourceClientOffset);
return (
<div
className={classes.root}
style={transformStyles}
/>
);
};
export default CustomDragLayer;

View File

@ -0,0 +1 @@
export { default as DraggableCell } from './ui/DraggableCell.ui';

View File

@ -0,0 +1,71 @@
.dateCell {
width: calc((100% / 7));
height: 40px;
background: aquamarine;
display: flex;
justify-content: center;
align-items: center;
&:nth-child(odd):not(:last-child) {
width: calc((100% / 7) - 1px);
border-right: 1px solid black;
}
&:nth-child(even) {
width: calc((100% / 7) - 1px);
border-right: 1px solid black;
}
.today {
color: red;
font-size: 1.2em;
font-weight: bold;
}
.outMothRange {
color: darkgrey;
}
.valueDate {
color: gold;
background: red;
border-radius: 50%;
padding: 5px;
height: 1.2em;
width: 1.2em;
display: inline-flex;
justify-content: center;
align-items: center;
}
}
.firstDate {
background: #cfe8ff;
}
.inSelection {
background: #cfe8ff;
color: black;
}
.lastDate {
background: #cfe8ff;
}
.selectedDateCell {
height: 35px;
width: 35px;
display: flex;
justify-content: center;
align-items: center;
border-radius: 50%;
background-color: #1892ff;
span {
color: white !important;
}
}
.dragging {
background: red;
}

View File

@ -0,0 +1,195 @@
import classnames from 'classnames';
import { useContext, useEffect } from 'react';
import {
useDrag,
useDragDropManager,
useDrop,
} from 'react-dnd';
import { getEmptyImage } from 'react-dnd-html5-backend';
import { CalendarWidgetContext } from 'widgets/CalendarWidget/ui/CalendarWidgetContext';
import type { DateCellProps } from 'widgets/CalendarWidget/ui/components/DateCell/ui/DateCell.ui';
import { DatePickerContext } from 'widgets/DatePicker/ui/DatePickerContext';
import { ItemTypes } from 'shared/constants';
import type { DataDateString } from 'shared/types/date';
import { getDataDateString } from 'shared/utils/date';
import classes from './DraggableCell.style.module.css';
import type { FC } from 'react';
type DraggableCellProps = DateCellProps;
const DraggableCell: FC<DraggableCellProps> = (props) => {
const {
date,
className,
...restProps
} = props;
const {
targetMonthIndex,
value,
highlightToday,
highlightValue,
} = useContext(CalendarWidgetContext);
const {
toggleCellDate,
isFirstDate,
isLastDate,
firstSelectedDate,
lastSelectedDate,
isCellInSelection,
} = useContext(DatePickerContext);
const todayDate = new Date();
const dataDate = getDataDateString(date);
const dataToday = getDataDateString(todayDate);
const dataValue = getDataDateString(value);
const isOutMonthRange = date.getMonth() !== targetMonthIndex;
const dragDropManager = useDragDropManager();
const [{ isDragging, canDrag }, drag, preview] = useDrag(() => ({
type: ItemTypes.CELL,
item: {
dataDate,
isFirstDate: isFirstDate(dataDate),
isLastDate: isLastDate(dataDate),
firstSelectedDate,
lastSelectedDate,
},
collect: (monitor) => ({
isDragging: monitor.isDragging(),
canDrag: isFirstDate(dataDate) || isLastDate(dataDate),
}),
}), [isFirstDate, isLastDate, dataDate]);
const onDropHandler = (item: { dataDate: DataDateString }) => {
const type = isFirstDate(item.dataDate) ? 'firstDate' : 'lastDate';
if (firstSelectedDate !== null && lastSelectedDate !== null) {
if (dataDate < firstSelectedDate && type === 'lastDate') {
toggleCellDate({ dataDate, type: 'firstDate' });
toggleCellDate({ dataDate: firstSelectedDate, type: 'lastDate' });
return;
}
if (dataDate > lastSelectedDate && type === 'firstDate') {
toggleCellDate({ dataDate, type: 'lastDate' });
toggleCellDate({ dataDate: lastSelectedDate, type: 'firstDate' });
return;
}
}
toggleCellDate({ dataDate, type });
};
const [{ isOver }, drop] = useDrop(() => ({
accept: ItemTypes.CELL,
drop: onDropHandler,
collect: (monitor) => ({
isOver: monitor.isOver(),
}),
}), [onDropHandler]);
useEffect(() => {
preview(getEmptyImage(), { captureDraggingState: true });
}, [preview]);
useEffect(() => {
type DragItem = {
dataDate: DataDateString;
isFirstDate: boolean;
isLastDate: boolean;
firstSelectedDate: DataDateString;
lastSelectedDate: DataDateString;
};
const dragItem = dragDropManager.getMonitor().getItem() as DragItem | null;
if (!isOver || !dragItem) {
return;
}
const isDragLast = dragItem.isLastDate;
const isDragFirst = dragItem.isFirstDate;
if (isDragFirst) {
if (dataDate < dragItem.lastSelectedDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
toggleCellDate({ dataDate: dragItem.lastSelectedDate, type: 'lastDate' });
return;
}
if (dataDate > dragItem.lastSelectedDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
toggleCellDate({ dataDate: dragItem.lastSelectedDate, type: 'firstDate' });
}
}
if (isDragLast) {
if (dataDate < dragItem.firstSelectedDate) {
toggleCellDate({ dataDate, type: 'firstDate' });
toggleCellDate({ dataDate: dragItem.firstSelectedDate, type: 'lastDate' });
return;
}
if (dataDate > dragItem.firstSelectedDate) {
toggleCellDate({ dataDate, type: 'lastDate' });
toggleCellDate({ dataDate: dragItem.firstSelectedDate, type: 'firstDate' });
}
}
}, [dataDate, dragDropManager, isFirstDate, isLastDate, isOver, toggleCellDate]);
return (
<div
key={dataDate}
ref={canDrag ? drag : drop}
className={classnames(
classes.dateCell,
className,
{
[classes.firstDate as string]: isFirstDate(dataDate),
[classes.inSelection as string]: isCellInSelection(dataDate)
&& !isFirstDate(dataDate)
&& !isLastDate(dataDate),
[classes.lastDate as string]: isLastDate(dataDate),
},
)}
data-date={dataDate}
data-testid="date-cell"
role="button"
style={{
// eslint-disable-next-line no-nested-ternary
cursor: canDrag ? isDragging ? 'grabbing' : 'grab' : 'pointer',
position: 'relative',
}}
tabIndex={0}
{...restProps}
>
<div
className={classnames({
// @ts-ignore
[classes.selectedDateCell]: isFirstDate(dataDate) || isLastDate(dataDate),
})}
>
<span
className={classnames(
{
[classes.today as string]: Boolean(highlightToday) && dataDate === dataToday,
[classes.outMothRange as string]: isOutMonthRange,
[classes.valueDate as string]: Boolean(highlightValue) && dataDate === dataValue,
},
)}
>
{date.getDate()}
</span>
</div>
</div>
);
};
export default DraggableCell;

View File

@ -2951,6 +2951,27 @@ __metadata:
languageName: node
linkType: hard
"@react-dnd/asap@npm:^5.0.1":
version: 5.0.2
resolution: "@react-dnd/asap@npm:5.0.2"
checksum: 10c0/0063db616db9801c9be18f11a912c3e214f87e714b1e4bf9462952af7ead65cba0b43e1f7c34bc8748811b6926e74d929e5e126f85ebb91b870faf809ceb5177
languageName: node
linkType: hard
"@react-dnd/invariant@npm:^4.0.1":
version: 4.0.2
resolution: "@react-dnd/invariant@npm:4.0.2"
checksum: 10c0/b303cc53fc5074cefb2a76b45b9c73ebb5d35630b18f5dc282ed9a9ac9b0287b9da1f6ac63acfdea2341b8f8187f615afc12d5eb14ec6015964f5c1b167332e2
languageName: node
linkType: hard
"@react-dnd/shallowequal@npm:^4.0.1":
version: 4.0.2
resolution: "@react-dnd/shallowequal@npm:4.0.2"
checksum: 10c0/9a352fd176752e5d9c2797d598aca034b7829111ae0c992d80f40d5f068fcd6a039b1841c741dfa1ab67a36a00664310aec4f0ce216e4112f80875c9fe6fd8dc
languageName: node
linkType: hard
"@remix-run/router@npm:1.15.3":
version: 1.15.3
resolution: "@remix-run/router@npm:1.15.3"
@ -6548,6 +6569,17 @@ __metadata:
languageName: node
linkType: hard
"dnd-core@npm:^16.0.1":
version: 16.0.1
resolution: "dnd-core@npm:16.0.1"
dependencies:
"@react-dnd/asap": "npm:^5.0.1"
"@react-dnd/invariant": "npm:^4.0.1"
redux: "npm:^4.2.0"
checksum: 10c0/6b852c576c88b0a42e618efb37e046334f5e9914b8d38ad139933dd9595b6caf2a484953a6301094d23119c17479549553d71e92fd77fa37318122ea1e579f65
languageName: node
linkType: hard
"dns-packet@npm:^5.2.2":
version: 5.6.1
resolution: "dns-packet@npm:5.6.1"
@ -8495,6 +8527,15 @@ __metadata:
languageName: node
linkType: hard
"hoist-non-react-statics@npm:^3.3.2":
version: 3.3.2
resolution: "hoist-non-react-statics@npm:3.3.2"
dependencies:
react-is: "npm:^16.7.0"
checksum: 10c0/fe0889169e845d738b59b64badf5e55fa3cf20454f9203d1eb088df322d49d4318df774828e789898dcb280e8a5521bb59b3203385662ca5e9218a6ca5820e74
languageName: node
linkType: hard
"hosted-git-info@npm:^2.1.4":
version: 2.8.9
resolution: "hosted-git-info@npm:2.8.9"
@ -10921,6 +10962,8 @@ __metadata:
normalize.css: "npm:8.0.1"
prop-types: "npm:15.8.1"
react: "npm:18.2.0"
react-dnd: "npm:^16.0.1"
react-dnd-html5-backend: "npm:^16.0.1"
react-dom: "npm:18.2.0"
react-router-dom: "npm:6.22.3"
standard-version: "npm:9.5.0"
@ -12657,6 +12700,40 @@ __metadata:
languageName: node
linkType: hard
"react-dnd-html5-backend@npm:^16.0.1":
version: 16.0.1
resolution: "react-dnd-html5-backend@npm:16.0.1"
dependencies:
dnd-core: "npm:^16.0.1"
checksum: 10c0/6e4b632a11e20211d71f5f3bedadf13ecec2fa73372fde388619838294b1375f15b717d1ce128e12c872ff7b15c32d26761d2026b33c14fc55e4fd5477c15289
languageName: node
linkType: hard
"react-dnd@npm:^16.0.1":
version: 16.0.1
resolution: "react-dnd@npm:16.0.1"
dependencies:
"@react-dnd/invariant": "npm:^4.0.1"
"@react-dnd/shallowequal": "npm:^4.0.1"
dnd-core: "npm:^16.0.1"
fast-deep-equal: "npm:^3.1.3"
hoist-non-react-statics: "npm:^3.3.2"
peerDependencies:
"@types/hoist-non-react-statics": ">= 3.3.1"
"@types/node": ">= 12"
"@types/react": ">= 16"
react: ">= 16.14"
peerDependenciesMeta:
"@types/hoist-non-react-statics":
optional: true
"@types/node":
optional: true
"@types/react":
optional: true
checksum: 10c0/d069435750f0d6653cfa2b951cac8abb3583fb144ff134a20176608877d9c5964c63384ebbacaa0fdeef819b592a103de0d8e06f3b742311d64a029ffed0baa3
languageName: node
linkType: hard
"react-dom@npm:18.2.0":
version: 18.2.0
resolution: "react-dom@npm:18.2.0"
@ -12669,7 +12746,7 @@ __metadata:
languageName: node
linkType: hard
"react-is@npm:^16.13.1":
"react-is@npm:^16.13.1, react-is@npm:^16.7.0":
version: 16.13.1
resolution: "react-is@npm:16.13.1"
checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
@ -12828,6 +12905,15 @@ __metadata:
languageName: node
linkType: hard
"redux@npm:^4.2.0":
version: 4.2.1
resolution: "redux@npm:4.2.1"
dependencies:
"@babel/runtime": "npm:^7.9.2"
checksum: 10c0/136d98b3d5dbed1cd6279c8c18a6a74c416db98b8a432a46836bdd668475de6279a2d4fd9d1363f63904e00f0678a8a3e7fa532c897163340baf1e71bb42c742
languageName: node
linkType: hard
"reflect.getprototypeof@npm:^1.0.4":
version: 1.0.6
resolution: "reflect.getprototypeof@npm:1.0.6"