feat(DatePicker): add DatePicker draggable cell
This commit is contained in:
parent
38457fbcff
commit
d012eb21a2
@ -12,4 +12,7 @@ module.exports = {
|
|||||||
'./configs/jest/__mocks__/fileMock.js',
|
'./configs/jest/__mocks__/fileMock.js',
|
||||||
'\\.(css|less|scss)$': 'identity-obj-proxy',
|
'\\.(css|less|scss)$': 'identity-obj-proxy',
|
||||||
},
|
},
|
||||||
|
transformIgnorePatterns: [
|
||||||
|
'/node_modules/(?!react-dnd|dnd-core|@react-dnd|react-dnd-html5-backend)',
|
||||||
|
],
|
||||||
};
|
};
|
||||||
|
|||||||
BIN
offline_node_modules/@react-dnd-asap-npm-5.0.2-66021d3d61-0063db616d.zip
generated
Normal file
BIN
offline_node_modules/@react-dnd-asap-npm-5.0.2-66021d3d61-0063db616d.zip
generated
Normal file
Binary file not shown.
BIN
offline_node_modules/@react-dnd-invariant-npm-4.0.2-826eacc1ea-b303cc53fc.zip
generated
Normal file
BIN
offline_node_modules/@react-dnd-invariant-npm-4.0.2-826eacc1ea-b303cc53fc.zip
generated
Normal file
Binary file not shown.
BIN
offline_node_modules/@react-dnd-shallowequal-npm-4.0.2-f944714335-9a352fd176.zip
generated
Normal file
BIN
offline_node_modules/@react-dnd-shallowequal-npm-4.0.2-f944714335-9a352fd176.zip
generated
Normal file
Binary file not shown.
BIN
offline_node_modules/dnd-core-npm-16.0.1-552224cee0-6b852c576c.zip
generated
Normal file
BIN
offline_node_modules/dnd-core-npm-16.0.1-552224cee0-6b852c576c.zip
generated
Normal file
Binary file not shown.
BIN
offline_node_modules/hoist-non-react-statics-npm-3.3.2-e7b709e6c1-fe0889169e.zip
generated
Normal file
BIN
offline_node_modules/hoist-non-react-statics-npm-3.3.2-e7b709e6c1-fe0889169e.zip
generated
Normal file
Binary file not shown.
BIN
offline_node_modules/react-dnd-html5-backend-npm-16.0.1-754940d855-6e4b632a11.zip
generated
Normal file
BIN
offline_node_modules/react-dnd-html5-backend-npm-16.0.1-754940d855-6e4b632a11.zip
generated
Normal file
Binary file not shown.
BIN
offline_node_modules/react-dnd-npm-16.0.1-974f047d7b-d069435750.zip
generated
Normal file
BIN
offline_node_modules/react-dnd-npm-16.0.1-974f047d7b-d069435750.zip
generated
Normal file
Binary file not shown.
BIN
offline_node_modules/redux-npm-4.2.1-e7e2cf2e37-136d98b3d5.zip
generated
Normal file
BIN
offline_node_modules/redux-npm-4.2.1-e7e2cf2e37-136d98b3d5.zip
generated
Normal file
Binary file not shown.
@ -35,6 +35,8 @@
|
|||||||
"normalize.css": "8.0.1",
|
"normalize.css": "8.0.1",
|
||||||
"prop-types": "15.8.1",
|
"prop-types": "15.8.1",
|
||||||
"react": "18.2.0",
|
"react": "18.2.0",
|
||||||
|
"react-dnd": "^16.0.1",
|
||||||
|
"react-dnd-html5-backend": "^16.0.1",
|
||||||
"react-dom": "18.2.0",
|
"react-dom": "18.2.0",
|
||||||
"react-router-dom": "6.22.3"
|
"react-router-dom": "6.22.3"
|
||||||
},
|
},
|
||||||
|
|||||||
3
src/shared/constants/drag.ts
Normal file
3
src/shared/constants/drag.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const ItemTypes = {
|
||||||
|
CELL: 'date-cell',
|
||||||
|
};
|
||||||
@ -6,3 +6,4 @@ export type {
|
|||||||
WeekDaysKeys,
|
WeekDaysKeys,
|
||||||
WeekDaysValues,
|
WeekDaysValues,
|
||||||
} from './date';
|
} from './date';
|
||||||
|
export { ItemTypes } from './drag';
|
||||||
|
|||||||
@ -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
|
|
||||||
}
|
|
||||||
@ -1,262 +1,44 @@
|
|||||||
import classnames from 'classnames';
|
import { useContext } from 'react';
|
||||||
import { useState } from 'react';
|
import { DndProvider } from 'react-dnd';
|
||||||
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
import type { DataDateString } from 'shared/types/date';
|
|
||||||
import { daysCountBetween, getDataDateString } from 'shared/utils/date';
|
|
||||||
import { exhaustiveCheck } from 'shared/utils/type';
|
|
||||||
|
|
||||||
import { CalendarWidget } from '../../CalendarWidget';
|
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 { CalendarWidgetProps } from '../../CalendarWidget';
|
||||||
import type { FC } from 'react';
|
import type { FC } from 'react';
|
||||||
|
|
||||||
export type DatePickerProps = CalendarWidgetProps & {
|
export type DatePickerProps = CalendarWidgetProps & Omit<DatePickerContextProviderProps, 'children'>;
|
||||||
firstDate?: Date;
|
|
||||||
lastDate?: Date;
|
|
||||||
onSelect?: (params: { dataDate: DataDateString; date: Date; type: 'firstDate' | 'lastDate' }) => void;
|
|
||||||
onUnselect?: (params: { dataDate: DataDateString; date: Date; type: 'firstDate' | 'lastDate' }) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const DatePicker: FC<DatePickerProps> = (props) => {
|
const MyCalendar: FC<CalendarWidgetProps> = (props) => {
|
||||||
const {
|
const { toggleCellSelection, getDataTestId } = useContext(DatePickerContext);
|
||||||
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 {};
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => {
|
|
||||||
setLastSelectedDate(null);
|
|
||||||
setFirstSelectedDate(null);
|
|
||||||
}}
|
|
||||||
onKeyPress={() => {}}
|
|
||||||
>
|
|
||||||
reset
|
|
||||||
</button>
|
|
||||||
|
|
||||||
<CalendarWidget
|
<CalendarWidget
|
||||||
|
DateCellComponent={DraggableCell}
|
||||||
DateCellProps={({ dataDate }) => ({
|
DateCellProps={({ dataDate }) => ({
|
||||||
onClick: () => {
|
onClick: () => {
|
||||||
toggleCellSelection(dataDate);
|
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),
|
...getDataTestId(dataDate),
|
||||||
})}
|
})}
|
||||||
{...restWidgetProps}
|
{...props}
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const DatePicker: FC<DatePickerProps> = (props) => (
|
||||||
|
<DndProvider backend={HTML5Backend}>
|
||||||
|
<DatePickerContextProvider {...props}>
|
||||||
|
<MyCalendar {...props} />
|
||||||
|
|
||||||
|
<CustomDragLayer />
|
||||||
|
</DatePickerContextProvider>
|
||||||
|
</DndProvider>
|
||||||
|
);
|
||||||
|
|
||||||
export default DatePicker;
|
export default DatePicker;
|
||||||
|
|||||||
282
src/widgets/DatePicker/ui/DatePickerContext.tsx
Normal file
282
src/widgets/DatePicker/ui/DatePickerContext.tsx
Normal 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;
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export { default as CustomDragLayer } from './ui/CustomDragLayer.ui';
|
||||||
@ -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;
|
||||||
|
}
|
||||||
@ -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;
|
||||||
@ -0,0 +1 @@
|
|||||||
|
export { default as DraggableCell } from './ui/DraggableCell.ui';
|
||||||
@ -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;
|
||||||
|
}
|
||||||
@ -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;
|
||||||
88
yarn.lock
88
yarn.lock
@ -2951,6 +2951,27 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"@remix-run/router@npm:1.15.3":
|
||||||
version: 1.15.3
|
version: 1.15.3
|
||||||
resolution: "@remix-run/router@npm:1.15.3"
|
resolution: "@remix-run/router@npm:1.15.3"
|
||||||
@ -6548,6 +6569,17 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"dns-packet@npm:^5.2.2":
|
||||||
version: 5.6.1
|
version: 5.6.1
|
||||||
resolution: "dns-packet@npm:5.6.1"
|
resolution: "dns-packet@npm:5.6.1"
|
||||||
@ -8495,6 +8527,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"hosted-git-info@npm:^2.1.4":
|
||||||
version: 2.8.9
|
version: 2.8.9
|
||||||
resolution: "hosted-git-info@npm:2.8.9"
|
resolution: "hosted-git-info@npm:2.8.9"
|
||||||
@ -10921,6 +10962,8 @@ __metadata:
|
|||||||
normalize.css: "npm:8.0.1"
|
normalize.css: "npm:8.0.1"
|
||||||
prop-types: "npm:15.8.1"
|
prop-types: "npm:15.8.1"
|
||||||
react: "npm:18.2.0"
|
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-dom: "npm:18.2.0"
|
||||||
react-router-dom: "npm:6.22.3"
|
react-router-dom: "npm:6.22.3"
|
||||||
standard-version: "npm:9.5.0"
|
standard-version: "npm:9.5.0"
|
||||||
@ -12657,6 +12700,40 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"react-dom@npm:18.2.0":
|
||||||
version: 18.2.0
|
version: 18.2.0
|
||||||
resolution: "react-dom@npm:18.2.0"
|
resolution: "react-dom@npm:18.2.0"
|
||||||
@ -12669,7 +12746,7 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"react-is@npm:^16.13.1":
|
"react-is@npm:^16.13.1, react-is@npm:^16.7.0":
|
||||||
version: 16.13.1
|
version: 16.13.1
|
||||||
resolution: "react-is@npm:16.13.1"
|
resolution: "react-is@npm:16.13.1"
|
||||||
checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
|
checksum: 10c0/33977da7a5f1a287936a0c85639fec6ca74f4f15ef1e59a6bc20338fc73dc69555381e211f7a3529b8150a1f71e4225525b41b60b52965bda53ce7d47377ada1
|
||||||
@ -12828,6 +12905,15 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
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":
|
"reflect.getprototypeof@npm:^1.0.4":
|
||||||
version: 1.0.6
|
version: 1.0.6
|
||||||
resolution: "reflect.getprototypeof@npm:1.0.6"
|
resolution: "reflect.getprototypeof@npm:1.0.6"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user