@kkkarsss/ui 1.2.2 → 1.3.0
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.
- package/dist/ui/controls/button/button.js +8 -1
- package/dist/ui/controls/chip/chip.js +8 -2
- package/dist/ui/information/block/block.d.ts +1 -0
- package/dist/ui/information/block/block.js +9 -2
- package/dist/ui/information/calendar-like/calendar-item-wrapper.d.ts +1 -0
- package/dist/ui/information/calendar-like/calendar-item-wrapper.js +4 -2
- package/dist/ui/information/calendar-like/calendar-item.d.ts +0 -3
- package/dist/ui/information/calendar-like/calendar-item.js +15 -6
- package/dist/ui/information/calendar-like/calendar-like.js +31 -10
- package/dist/ui/information/calendar-like/calendar-like.stories.js +4 -3
- package/dist/ui/information/calendar-like/calendar-slot.d.ts +3 -0
- package/dist/ui/information/calendar-like/calendar-slot.js +37 -16
- package/package.json +2 -1
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { animated, useSpring, config } from '@react-spring/web';
|
|
3
|
+
import { useState } from 'react';
|
|
2
4
|
import { jc } from '../../../utils';
|
|
3
5
|
import { Typo } from '../../information';
|
|
4
6
|
const variantMap = {
|
|
@@ -7,5 +9,10 @@ const variantMap = {
|
|
|
7
9
|
selling: 'bg-accent text-accent-foreground',
|
|
8
10
|
};
|
|
9
11
|
export const Button = ({ children, onClick, variant = 'active', disabled = false }) => {
|
|
10
|
-
|
|
12
|
+
const [pressed, setPressed] = useState(false);
|
|
13
|
+
const springs = useSpring({
|
|
14
|
+
transform: pressed ? 'scale(0.96)' : 'scale(1)',
|
|
15
|
+
config: config.stiff,
|
|
16
|
+
});
|
|
17
|
+
return (_jsx(animated.button, { style: springs, onMouseDown: () => setPressed(true), onMouseUp: () => setPressed(false), onMouseLeave: () => setPressed(false), className: jc('w-auto px-4 py-2 text-[14px] font-medium border border-transparent cursor-pointer outline-none', 'disabled:opacity-50 disabled:cursor-not-allowed disabled:pointer-events-none hover:not-disabled:opacity-90', variantMap[variant]), onClick: onClick, disabled: disabled, children: _jsx(Typo, { size: 'm', children: children }) }));
|
|
11
18
|
};
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import {
|
|
2
|
+
import { animated, config, useSpring } from '@react-spring/web';
|
|
3
|
+
import { Activity, createElement, useState } from 'react';
|
|
3
4
|
import { jc } from '../../../utils';
|
|
4
5
|
const variantMap = {
|
|
5
6
|
default: 'bg-secondary text-secondary-foreground',
|
|
@@ -7,5 +8,10 @@ const variantMap = {
|
|
|
7
8
|
secondary: 'bg-transparent text-secondary-foreground border border-secondary-foreground',
|
|
8
9
|
};
|
|
9
10
|
export const Chip = ({ children, onClick, accLeft, variant = 'default' }) => {
|
|
10
|
-
|
|
11
|
+
const [pressed, setPressed] = useState(false);
|
|
12
|
+
const springs = useSpring({
|
|
13
|
+
transform: pressed ? 'scale(0.95)' : 'scale(1)',
|
|
14
|
+
config: config.stiff,
|
|
15
|
+
});
|
|
16
|
+
return (_jsxs(animated.button, { style: springs, onMouseDown: () => setPressed(true), onMouseUp: () => setPressed(false), onMouseLeave: () => setPressed(false), onClick: onClick, className: jc('flex items-center text-nowrap gap-[5px] w-min px-2 py-1 rounded-2xl outline-none border-none cursor-pointer text-[14px]', variantMap[variant]), children: [_jsx(Activity, { mode: accLeft ? 'visible' : 'hidden', children: accLeft ? createElement(accLeft, { size: 14, color: 'white', strokeWidth: 3 }) : null }), children] }));
|
|
11
17
|
};
|
|
@@ -1,10 +1,17 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { animated, config, useSpring } from '@react-spring/web';
|
|
2
3
|
import { jc } from '../../../utils';
|
|
3
4
|
import { Flex, Offset } from '../../layout';
|
|
4
5
|
const typeMap = {
|
|
5
6
|
fill: 'h-full',
|
|
6
7
|
hug: 'h-auto',
|
|
7
8
|
};
|
|
8
|
-
export const Block = ({ children, title, topAcc, filters, type = 'fill', maxWidth, maxHeight, minWidth, minHeight, }) => {
|
|
9
|
-
|
|
9
|
+
export const Block = ({ children, title, topAcc, filters, type = 'fill', maxWidth, maxHeight, minWidth, minHeight, animate = true, }) => {
|
|
10
|
+
const springs = useSpring({
|
|
11
|
+
from: { opacity: 0, transform: 'translateY(10px)' },
|
|
12
|
+
to: { opacity: 1, transform: 'translateY(0px)' },
|
|
13
|
+
config: config.gentle,
|
|
14
|
+
immediate: !animate,
|
|
15
|
+
});
|
|
16
|
+
return (_jsxs(animated.div, { className: jc('w-full flex flex-col', 'rounded-2xl', 'bg-background-accent', 'shadow-[0_0_8px_var(--shadow)]', 'scrollbar-none', 'overflow-hidden', typeMap[type]), style: { ...springs, maxWidth, maxHeight, minWidth, minHeight }, children: [_jsx("div", { className: jc('sticky', 'top-0', 'z-20', 'bg-background-accent', 'w-full', 'shrink-0'), children: _jsxs(Flex, { direction: 'column', children: [_jsxs(Flex, { justify: 'space-between', align: 'center', children: [title && _jsx(Offset, { type: 'both', children: title }), _jsx("div", { className: 'mx-m', children: _jsx(Flex, { direction: 'column', children: _jsx(Flex, { align: 'center', gap: '4px', children: topAcc }) }) })] }), filters && _jsx("div", { className: 'mb-l', children: filters })] }) }), _jsx("div", { className: "flex-1 overflow-auto scrollbar-none", children: _jsx(Flex, { direction: 'column', type: 'fill', children: children }) })] }));
|
|
10
17
|
};
|
|
@@ -12,5 +12,6 @@ export type TCalendarItemWrapperProps = {
|
|
|
12
12
|
onDragEnd?: (e: DragEvent<HTMLDivElement>, id: string) => void;
|
|
13
13
|
onResize?: (id: string, newEstimatedTime: number) => void;
|
|
14
14
|
renderTask: (task: TCalendarTask) => ReactNode;
|
|
15
|
+
overlappingTasksCount?: number;
|
|
15
16
|
};
|
|
16
17
|
export declare const CalendarItemWrapper: FC<TCalendarItemWrapperProps>;
|
|
@@ -38,6 +38,7 @@ export const CalendarItemWrapper = ({ task, position, onDragStart, onDragEnd, on
|
|
|
38
38
|
};
|
|
39
39
|
const displayHeight = previewEstimatedTime ? `${(previewEstimatedTime / 15) * 20}px` : position.height;
|
|
40
40
|
return (_jsx("div", { draggable: !!onDragStart, onDragStart: (e) => {
|
|
41
|
+
console.log('CalendarItemWrapper: onDragStart', task.id);
|
|
41
42
|
onDragStart?.(e, task.id);
|
|
42
43
|
const el = e.currentTarget;
|
|
43
44
|
// Создаем пустой элемент для скрытия стандартного ghost image браузера
|
|
@@ -47,11 +48,12 @@ export const CalendarItemWrapper = ({ task, position, onDragStart, onDragEnd, on
|
|
|
47
48
|
if (el) {
|
|
48
49
|
// Используем setTimeout, чтобы прозрачность и pointer-events применились после того, как браузер создаст ghost image
|
|
49
50
|
setTimeout(() => {
|
|
50
|
-
el.style.opacity = '0';
|
|
51
|
+
el.style.opacity = '0.4';
|
|
51
52
|
el.style.pointerEvents = 'none';
|
|
52
53
|
}, 0);
|
|
53
54
|
}
|
|
54
55
|
}, onDragEnd: (e) => {
|
|
56
|
+
console.log('CalendarItemWrapper: onDragEnd');
|
|
55
57
|
onDragEnd?.(e, task.id);
|
|
56
58
|
const el = e.currentTarget;
|
|
57
59
|
if (el) {
|
|
@@ -63,5 +65,5 @@ export const CalendarItemWrapper = ({ task, position, onDragStart, onDragEnd, on
|
|
|
63
65
|
width: position.width,
|
|
64
66
|
left: position.left,
|
|
65
67
|
top: position.top,
|
|
66
|
-
}, className: jc('calendar-item absolute p-[2px] transition-[height,width,left,opacity] flex flex-col z-50 select-none', onDragStart ? 'cursor-move' : '', 'hover:z-[60]', previewEstimatedTime !== null ? 'transition-none z-[60]' : ''), children: _jsxs("div", { className: "w-full h-full relative group/item", children: [renderTask(task), onResize && (_jsx("div", { className: "absolute bottom-0 left-0 right-1 h-2 cursor-ns-resize group/resize flex items-center justify-center z-[70]", onMouseDown: handleMouseDown, children: _jsx("div", { className: "w-8 h-1 bg-accent/30 rounded-full opacity-0 group-hover/resize:opacity-100 transition-opacity" }) }))] }) }));
|
|
68
|
+
}, className: jc('calendar-item absolute p-[2px] transition-[height,width,left,opacity] flex flex-col z-50 select-none', onDragStart ? 'cursor-move' : '', 'hover:z-[60]', previewEstimatedTime !== null ? 'transition-none z-[60]' : '', 'active:z-[100]'), children: _jsxs("div", { className: "w-full h-full relative group/item", children: [renderTask(task), onResize && (_jsx("div", { className: "absolute bottom-0 left-0 right-1 h-2 cursor-ns-resize group/resize flex items-center justify-center z-[70]", onMouseDown: handleMouseDown, children: _jsx("div", { className: "w-8 h-1 bg-accent/30 rounded-full opacity-0 group-hover/resize:opacity-100 transition-opacity" }) }))] }) }));
|
|
67
69
|
};
|
|
@@ -1,9 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { animated, config, useSpring } from '@react-spring/web';
|
|
3
|
+
import { useState } from 'react';
|
|
2
4
|
import { jc } from '../../../utils';
|
|
3
5
|
import { Flex } from '../../layout';
|
|
4
|
-
export const CalendarItem = ({ title,
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
export const CalendarItem = ({ title, color, className, onClick }) => {
|
|
7
|
+
const [pressed, setPressed] = useState(false);
|
|
8
|
+
const springs = useSpring({
|
|
9
|
+
transform: pressed ? 'scale(0.98)' : 'scale(1)',
|
|
10
|
+
config: config.stiff,
|
|
11
|
+
});
|
|
12
|
+
return (_jsx(animated.div, { style: {
|
|
13
|
+
...springs,
|
|
14
|
+
backgroundColor: color ? `${color}ac` : undefined,
|
|
15
|
+
border: 0,
|
|
16
|
+
borderLeft: `3px solid ${color}`,
|
|
17
|
+
}, onMouseDown: () => setPressed(true), onMouseUp: () => setPressed(false), onMouseLeave: () => setPressed(false), onClick: onClick, className: jc('w-full h-full rounded-[8px] border flex flex-col transition-colors relative', onClick && 'cursor-pointer', className), children: _jsx(Flex, { gap: "8px", align: "center", justify: "space-between", type: "fill", children: _jsx(Flex, { gap: "8px", align: "center", type: "fill", className: "min-w-0 flex-1", children: title }) }) }));
|
|
9
18
|
};
|
|
@@ -23,7 +23,7 @@ const CurrentTimeLine = () => {
|
|
|
23
23
|
// 15 минут = 20 пикселей (высота слота)
|
|
24
24
|
return totalMinutes * (20 / 15);
|
|
25
25
|
}, [now]);
|
|
26
|
-
return (_jsxs("div", { className: "absolute left-0 right-0 z-
|
|
26
|
+
return (_jsxs("div", { className: "absolute left-0 right-0 z-[101] pointer-events-none flex items-center", style: { top: `${topOffset}px` }, children: [_jsx("div", { className: "w-2 h-2 rounded-full bg-red-500 -ml-1" }), _jsx("div", { className: "flex-1 h-[2px] bg-red-500" })] }));
|
|
27
27
|
};
|
|
28
28
|
export const CalendarLike = ({ tasks, slots = DEFAULT_SLOTS, showCurrentTime = true, autoScrollToCurrentTime = true, renderTask, onTaskDrop, onTaskResize, onCreateTask, }) => {
|
|
29
29
|
const containerRef = useRef(null);
|
|
@@ -58,6 +58,7 @@ export const CalendarLike = ({ tasks, slots = DEFAULT_SLOTS, showCurrentTime = t
|
|
|
58
58
|
}
|
|
59
59
|
}, [showCurrentTime, autoScrollToCurrentTime]);
|
|
60
60
|
const handleDragStart = (e, task) => {
|
|
61
|
+
console.log('CalendarLike: handleDragStart', task.id);
|
|
61
62
|
setIsDragging(true);
|
|
62
63
|
e.dataTransfer.setData('taskId', task.id);
|
|
63
64
|
e.dataTransfer.setData('taskTitle', task.title || '');
|
|
@@ -67,26 +68,46 @@ export const CalendarLike = ({ tasks, slots = DEFAULT_SLOTS, showCurrentTime = t
|
|
|
67
68
|
}
|
|
68
69
|
// Сохраняем в глобальную переменную для доступа во время dragOver
|
|
69
70
|
// eslint-disable-next-line react-hooks/immutability
|
|
70
|
-
window._draggingTask =
|
|
71
|
-
id: task.id,
|
|
72
|
-
title: task.title,
|
|
73
|
-
estimatedTime: task.estimatedTime,
|
|
74
|
-
color: task.color,
|
|
75
|
-
};
|
|
71
|
+
window._draggingTask = task;
|
|
76
72
|
};
|
|
77
73
|
const handleDragEnd = () => {
|
|
78
74
|
setIsDragging(false);
|
|
79
75
|
delete window._draggingTask;
|
|
80
76
|
};
|
|
81
77
|
const handleDrop = (e, hour, minutes) => {
|
|
78
|
+
console.log('CalendarLike: handleDrop triggered', { hour, minutes });
|
|
82
79
|
setIsDragging(false);
|
|
83
|
-
|
|
80
|
+
// Пытаемся получить taskId из dataTransfer
|
|
81
|
+
let taskId = e.dataTransfer.getData('taskId');
|
|
82
|
+
// Если в dataTransfer пусто (бывает в некоторых браузерах/ситуациях),
|
|
83
|
+
// берем из глобальной переменной, которую мы засетили в handleDragStart
|
|
84
|
+
if (!taskId && window._draggingTask) {
|
|
85
|
+
taskId = window._draggingTask.id;
|
|
86
|
+
console.log('CalendarLike: taskId recovered from _draggingTask:', taskId);
|
|
87
|
+
}
|
|
88
|
+
console.log('CalendarLike: taskId for drop:', taskId);
|
|
84
89
|
if (taskId && onTaskDrop) {
|
|
85
90
|
onTaskDrop(taskId, hour, minutes);
|
|
86
91
|
}
|
|
92
|
+
else {
|
|
93
|
+
console.warn('CalendarLike: taskId or onTaskDrop missing', { taskId, hasOnTaskDrop: !!onTaskDrop });
|
|
94
|
+
}
|
|
95
|
+
// Очищаем глобальную переменную после дропа
|
|
96
|
+
delete window._draggingTask;
|
|
87
97
|
};
|
|
88
|
-
return (_jsxs("div", { ref: containerRef, className: jc('relative border-l border-secondary
|
|
98
|
+
return (_jsxs("div", { ref: containerRef, className: jc('relative border-l border-secondary ml-12 select-none', isDragging ? 'is-dragging' : ''), children: [showCurrentTime && _jsx(CurrentTimeLine, {}), slots.map((slotIndex) => {
|
|
89
99
|
const tasksForSlot = tasksBySlot[slotIndex];
|
|
90
|
-
|
|
100
|
+
const currentSlotTime = slotIndex * 15; // в минутах от начала дня
|
|
101
|
+
// Считаем сколько задач пересекают этот слот (для кластеризации превью)
|
|
102
|
+
// Исключаем текущую перетаскиваемую задачу из подсчета, чтобы превью не считало себя помехой
|
|
103
|
+
const draggingTask = window._draggingTask;
|
|
104
|
+
const overlappingTasksCount = tasks.filter((task) => {
|
|
105
|
+
if (draggingTask && task.id === draggingTask.id)
|
|
106
|
+
return false;
|
|
107
|
+
const taskStart = task.dueDate.getHours() * 60 + task.dueDate.getMinutes();
|
|
108
|
+
const taskEnd = taskStart + task.estimatedTime;
|
|
109
|
+
return currentSlotTime >= taskStart && currentSlotTime < taskEnd;
|
|
110
|
+
}).length;
|
|
111
|
+
return (_jsx(CalendarSlot, { slotIndex: slotIndex, onDrop: handleDrop, onCreateTask: onCreateTask, renderTask: renderTask, overlappingTasksCount: overlappingTasksCount, children: tasksForSlot?.map((task) => (_jsx(CalendarItemWrapper, { task: task, position: task.position, onDragStart: (e) => handleDragStart(e, task), onDragEnd: handleDragEnd, onResize: onTaskResize, renderTask: renderTask }, task.id))) }, slotIndex));
|
|
91
112
|
})] }));
|
|
92
113
|
};
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
-
import { Circle, CircleCheckBig
|
|
2
|
+
import { Circle, CircleCheckBig } from 'lucide-react';
|
|
3
3
|
import { useState } from 'react';
|
|
4
4
|
import { CalendarLike, CalendarItem } from './calendar-like';
|
|
5
5
|
import { Cell } from '../cell/cell';
|
|
@@ -53,6 +53,7 @@ const INITIAL_TASKS = [
|
|
|
53
53
|
dueDate: getTodayAtHour(17),
|
|
54
54
|
estimatedTime: 30,
|
|
55
55
|
isCompleted: true,
|
|
56
|
+
color: '#8b5cf6',
|
|
56
57
|
},
|
|
57
58
|
];
|
|
58
59
|
export const Interactive = {
|
|
@@ -96,14 +97,14 @@ export const Interactive = {
|
|
|
96
97
|
return (_jsx(CalendarItem, { title: _jsx(Cell, { subtitle: _jsx(Typo, { size: 'xs', weight: '500', children: "CODE-1" }), title: _jsx(Typo, { weight: "500", textDecoration: isCompleted ? 'line-through' : 'none', className: "truncate", children: task.title }), accLeft: [
|
|
97
98
|
{
|
|
98
99
|
icon: isCompleted ? CircleCheckBig : Circle,
|
|
99
|
-
color: '
|
|
100
|
+
color: 'white',
|
|
100
101
|
strokeWidth: 3,
|
|
101
102
|
onClick: (e) => {
|
|
102
103
|
e?.stopPropagation();
|
|
103
104
|
setTasks((prev) => prev.map((t) => (t.id === task.id ? { ...t, isCompleted: !t.isCompleted } : t)));
|
|
104
105
|
},
|
|
105
106
|
},
|
|
106
|
-
] }), color: task.color,
|
|
107
|
+
] }), color: task.color, onClick: () => handleTaskClick(task.id) }));
|
|
107
108
|
} })] }));
|
|
108
109
|
},
|
|
109
110
|
};
|
|
@@ -1,8 +1,11 @@
|
|
|
1
1
|
import { type FC, type DragEvent, ReactNode } from 'react';
|
|
2
|
+
import { TCalendarTask } from './types';
|
|
2
3
|
export type TCalendarSlotProps = {
|
|
3
4
|
slotIndex: number;
|
|
4
5
|
onDrop?: (e: DragEvent<HTMLDivElement>, hour: number, minutes: number) => void;
|
|
5
6
|
onCreateTask?: (hour: number, minutes: number, estimatedTime: number) => void;
|
|
7
|
+
renderTask?: (task: TCalendarTask) => ReactNode;
|
|
6
8
|
children?: ReactNode;
|
|
9
|
+
overlappingTasksCount?: number;
|
|
7
10
|
};
|
|
8
11
|
export declare const CalendarSlot: FC<TCalendarSlotProps>;
|
|
@@ -1,30 +1,43 @@
|
|
|
1
1
|
import { jsxs as _jsxs, jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
import { animated, config, useSpring } from '@react-spring/web';
|
|
2
3
|
import { useState } from 'react';
|
|
4
|
+
import { jc } from '../../../utils';
|
|
3
5
|
import { Typo } from '../text/typo';
|
|
4
|
-
export const CalendarSlot = ({ slotIndex, onDrop, onCreateTask, children }) => {
|
|
6
|
+
export const CalendarSlot = ({ slotIndex, onDrop, onCreateTask, renderTask, children, overlappingTasksCount = 0, }) => {
|
|
5
7
|
const hour = Math.floor(slotIndex / 4);
|
|
6
8
|
const minutes = (slotIndex % 4) * 15;
|
|
7
9
|
const isTopSlot = slotIndex % 4 === 0;
|
|
8
10
|
const [selection, setSelection] = useState(null);
|
|
9
11
|
const [dragOverInfo, setDragOverInfo] = useState(null);
|
|
12
|
+
const springs = useSpring({
|
|
13
|
+
to: {
|
|
14
|
+
opacity: dragOverInfo ? 1 : 0.6,
|
|
15
|
+
height: dragOverInfo ? `${(dragOverInfo.task.estimatedTime / 15) * 20}px` : '40px',
|
|
16
|
+
},
|
|
17
|
+
config: { ...config.stiff, precision: 0.001 },
|
|
18
|
+
});
|
|
19
|
+
const handleDragEnter = (e) => {
|
|
20
|
+
e.preventDefault();
|
|
21
|
+
};
|
|
10
22
|
const handleDragOver = (e) => {
|
|
11
23
|
e.preventDefault();
|
|
24
|
+
e.dataTransfer.dropEffect = 'move';
|
|
12
25
|
// Пытаемся получить данные из глобальной переменной
|
|
13
26
|
const draggingTask = window._draggingTask;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
});
|
|
27
|
+
if (!draggingTask)
|
|
28
|
+
return;
|
|
29
|
+
if (!dragOverInfo) {
|
|
30
|
+
setDragOverInfo({
|
|
31
|
+
task: draggingTask,
|
|
32
|
+
topOffset: 0, // Приклеиваем к началу слота (15-минутка)
|
|
33
|
+
});
|
|
34
|
+
}
|
|
23
35
|
};
|
|
24
36
|
const handleDragLeave = () => {
|
|
25
37
|
setDragOverInfo(null);
|
|
26
38
|
};
|
|
27
39
|
const handleInternalDrop = (e) => {
|
|
40
|
+
console.log('CalendarSlot: handleInternalDrop triggered', { hour, minutes });
|
|
28
41
|
setDragOverInfo(null);
|
|
29
42
|
onDrop?.(e, hour, minutes); // Приклеиваем к началу слота (15-минутка)
|
|
30
43
|
};
|
|
@@ -57,14 +70,22 @@ export const CalendarSlot = ({ slotIndex, onDrop, onCreateTask, children }) => {
|
|
|
57
70
|
document.addEventListener('mousemove', onMouseMove);
|
|
58
71
|
document.addEventListener('mouseup', onMouseUp);
|
|
59
72
|
};
|
|
60
|
-
return (_jsxs("div", { onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleInternalDrop, onMouseDown: handleMouseDown, className: `relative h-5 group hover:z-10 has-[.calendar-item:hover]:z-30 has-[.calendar-item:active]:z-30 ${isTopSlot ? 'border-t border-t-secondary
|
|
73
|
+
return (_jsxs("div", { onDragEnter: handleDragEnter, onDragOver: handleDragOver, onDragLeave: handleDragLeave, onDrop: handleInternalDrop, onMouseDown: handleMouseDown, className: `relative h-5 group hover:z-10 has-[.calendar-item:hover]:z-30 has-[.calendar-item:active]:z-30 ${isTopSlot ? 'border-t border-t-secondary' : ''}`, children: [isTopSlot && (_jsx("div", { className: "absolute -left-12 top-0 -translate-y-1/2 w-10 text-right", children: _jsxs(Typo, { size: "xs", color: "secondary", children: [String(hour).padStart(2, '0'), ":00"] }) })), _jsxs("div", { className: "pl-4 relative h-full", children: [children, dragOverInfo !== null && (_jsx(animated.div, { className: jc('absolute z-[100] pointer-events-none flex flex-col overflow-hidden'), style: {
|
|
74
|
+
...springs,
|
|
61
75
|
top: `${dragOverInfo.topOffset}px`,
|
|
62
|
-
height: `${(dragOverInfo.estimatedTime / 15) * 20}px`,
|
|
63
76
|
minHeight: '20px',
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
}, children: _jsx("div", { className: "p-1", children: _jsx(Typo, { size: "s", weight: "500", className: "truncate leading-none", children: dragOverInfo.title || 'Переместить сюда' }) }) })), selection && (_jsx("div", { className: "absolute left-4 right-1
|
|
77
|
+
width: overlappingTasksCount > 0 ? `${100 / (overlappingTasksCount + 1)}%` : '100%',
|
|
78
|
+
left: overlappingTasksCount > 0 ? `${(overlappingTasksCount * 100) / (overlappingTasksCount + 1)}%` : '0',
|
|
79
|
+
}, children: renderTask ? (renderTask(dragOverInfo.task)) : (_jsx("div", { className: "p-1", children: _jsx(Typo, { size: "s", weight: "500", className: "truncate leading-none", children: dragOverInfo.task.title || 'Переместить сюда' }) })) })), selection && (_jsx("div", { className: "absolute left-4 right-1 z-[40] pointer-events-none", style: {
|
|
67
80
|
top: '0px',
|
|
68
81
|
height: `${(selection.currentEstimatedTime / 15) * 20}px`,
|
|
69
|
-
|
|
82
|
+
width: overlappingTasksCount > 0 ? `${100 / (overlappingTasksCount + 1)}%` : '100%',
|
|
83
|
+
left: overlappingTasksCount > 0 ? `${(overlappingTasksCount * 100) / (overlappingTasksCount + 1)}%` : '0',
|
|
84
|
+
}, children: renderTask ? (renderTask({
|
|
85
|
+
id: 'new-task-preview',
|
|
86
|
+
title: 'Новая задача',
|
|
87
|
+
dueDate: new Date(new Date().setHours(hour, minutes, 0, 0)),
|
|
88
|
+
estimatedTime: selection.currentEstimatedTime,
|
|
89
|
+
color: 'white',
|
|
90
|
+
})) : (_jsxs("div", { className: "border rounded-sm h-full p-1", children: [_jsx(Typo, { size: "xs", weight: "500", children: "\u041D\u043E\u0432\u0430\u044F \u0437\u0430\u0434\u0430\u0447\u0430" }), _jsxs(Typo, { size: "xs", color: "secondary", children: [selection.currentEstimatedTime, " \u043C\u0438\u043D"] })] })) }))] })] }));
|
|
70
91
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kkkarsss/ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.3.0",
|
|
4
4
|
"description": "UI Kit for kkkarsss projects",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|
|
@@ -60,6 +60,7 @@
|
|
|
60
60
|
"vitest": "^4.0.18"
|
|
61
61
|
},
|
|
62
62
|
"dependencies": {
|
|
63
|
+
"@react-spring/web": "^10.0.3",
|
|
63
64
|
"date-fns": "^4.1.0",
|
|
64
65
|
"react-datepicker": "^9.1.0",
|
|
65
66
|
"react-day-picker": "^9.13.0"
|