@archbase/kanban 4.0.37
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/LICENSE +13 -0
- package/README.md +630 -0
- package/dist/archbase-kanban-4.0.37.tgz +0 -0
- package/dist/components/Card/Card.d.ts +26 -0
- package/dist/components/Card/index.d.ts +1 -0
- package/dist/components/CardSkeleton/CardSkeleton.d.ts +9 -0
- package/dist/components/CardSkeleton/index.d.ts +2 -0
- package/dist/components/Column/Column.d.ts +47 -0
- package/dist/components/Column/index.d.ts +1 -0
- package/dist/components/ColumnAdder/ColumnAdder.d.ts +6 -0
- package/dist/components/ColumnAdder/index.d.ts +1 -0
- package/dist/components/ColumnContent/ColumnContent.d.ts +24 -0
- package/dist/components/ColumnContent/index.d.ts +1 -0
- package/dist/components/ColumnHeader/ColumnHeader.d.ts +10 -0
- package/dist/components/ColumnHeader/index.d.ts +1 -0
- package/dist/components/DefaultCard/DefaultCard.d.ts +3 -0
- package/dist/components/DefaultCard/index.d.ts +1 -0
- package/dist/components/GenericItem/GenericItem.d.ts +26 -0
- package/dist/components/GenericItem/index.d.ts +1 -0
- package/dist/components/Kanban.d.ts +3 -0
- package/dist/components/index.d.ts +2 -0
- package/dist/components/types.d.ts +124 -0
- package/dist/context/KanbanContext.d.ts +5 -0
- package/dist/global/dnd/dropManager.d.ts +16 -0
- package/dist/global/dnd/useCardDnd.d.ts +22 -0
- package/dist/global/dnd/useColumnDnd.d.ts +29 -0
- package/dist/index.css +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +1041 -0
- package/dist/utils/columnsUtils.d.ts +4 -0
- package/dist/utils/getPrefix.d.ts +2 -0
- package/dist/utils/getSharedProps.d.ts +8 -0
- package/dist/utils/infinite-scroll.d.ts +4 -0
- package/dist/utils/mergeRefs.d.ts +5 -0
- package/dist/utils/scroll.d.ts +2 -0
- package/package.json +66 -0
- package/src/common/_index.scss +0 -0
- package/src/components/Card/Card.tsx +215 -0
- package/src/components/Card/_Card.scss +11 -0
- package/src/components/Card/_index.scss +1 -0
- package/src/components/Card/index.ts +1 -0
- package/src/components/CardSkeleton/CardSkeleton.tsx +45 -0
- package/src/components/CardSkeleton/_CardSkeleton.scss +245 -0
- package/src/components/CardSkeleton/_index.scss +1 -0
- package/src/components/CardSkeleton/index.ts +2 -0
- package/src/components/Column/Column.tsx +246 -0
- package/src/components/Column/_Column.scss +44 -0
- package/src/components/Column/_index.scss +1 -0
- package/src/components/Column/index.ts +1 -0
- package/src/components/ColumnAdder/ColumnAdder.tsx +18 -0
- package/src/components/ColumnAdder/_ColumnAdder.scss +0 -0
- package/src/components/ColumnAdder/_index.scss +1 -0
- package/src/components/ColumnAdder/index.ts +1 -0
- package/src/components/ColumnContent/ColumnContent.tsx +238 -0
- package/src/components/ColumnContent/_ColumnContent.scss +23 -0
- package/src/components/ColumnContent/_index.scss +1 -0
- package/src/components/ColumnContent/index.ts +1 -0
- package/src/components/ColumnHeader/ColumnHeader.tsx +43 -0
- package/src/components/ColumnHeader/_ColumnHeader.scss +26 -0
- package/src/components/ColumnHeader/_index.scss +1 -0
- package/src/components/ColumnHeader/index.ts +1 -0
- package/src/components/DefaultCard/DefaultCard.tsx +9 -0
- package/src/components/DefaultCard/_DefaultCard.scss +14 -0
- package/src/components/DefaultCard/_index.scss +1 -0
- package/src/components/DefaultCard/index.ts +1 -0
- package/src/components/GenericItem/GenericItem.tsx +132 -0
- package/src/components/GenericItem/_GenericItem.scss +4 -0
- package/src/components/GenericItem/_index.scss +1 -0
- package/src/components/GenericItem/index.ts +1 -0
- package/src/components/Kanban.tsx +102 -0
- package/src/components/_Kanban.scss +8 -0
- package/src/components/_index.scss +9 -0
- package/src/components/index.ts +2 -0
- package/src/components/types.ts +155 -0
- package/src/context/KanbanContext.tsx +19 -0
- package/src/global/_index.scss +3 -0
- package/src/global/assets/styles/abstracts/_breakpoints.scss +71 -0
- package/src/global/assets/styles/abstracts/_colors.scss +85 -0
- package/src/global/assets/styles/abstracts/_functions.scss +3 -0
- package/src/global/assets/styles/abstracts/_index.scss +5 -0
- package/src/global/assets/styles/abstracts/_mixins.scss +49 -0
- package/src/global/assets/styles/abstracts/_padding.scss +1 -0
- package/src/global/assets/styles/abstracts/_variables.scss +8 -0
- package/src/global/assets/styles/base/_index.scss +34 -0
- package/src/global/dnd/dropManager.ts +301 -0
- package/src/global/dnd/useCardDnd.tsx +225 -0
- package/src/global/dnd/useColumnDnd.tsx +231 -0
- package/src/global/theme-default.scss +137 -0
- package/src/index.ts +6 -0
- package/src/utils/columnsUtils.ts +19 -0
- package/src/utils/getPrefix.ts +7 -0
- package/src/utils/getSharedProps.ts +18 -0
- package/src/utils/infinite-scroll.ts +18 -0
- package/src/utils/mergeRefs.ts +23 -0
- package/src/utils/scroll.ts +34 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
2
|
+
import { BoardItem, DndState } from "@/components/types";
|
|
3
|
+
import { withPrefix } from "@/utils/getPrefix";
|
|
4
|
+
import {
|
|
5
|
+
draggable,
|
|
6
|
+
dropTargetForElements,
|
|
7
|
+
} from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
8
|
+
import {
|
|
9
|
+
attachClosestEdge,
|
|
10
|
+
extractClosestEdge,
|
|
11
|
+
type Edge,
|
|
12
|
+
} from "@atlaskit/pragmatic-drag-and-drop-hitbox/closest-edge";
|
|
13
|
+
import { setCustomNativeDragPreview } from "@atlaskit/pragmatic-drag-and-drop/element/set-custom-native-drag-preview";
|
|
14
|
+
import { preserveOffsetOnSource } from "@atlaskit/pragmatic-drag-and-drop/element/preserve-offset-on-source";
|
|
15
|
+
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
|
|
16
|
+
import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
|
|
17
|
+
import { useKanbanContext } from "@/context/KanbanContext";
|
|
18
|
+
|
|
19
|
+
// ── Column DnD State ──────────────────────────────────────────────────
|
|
20
|
+
|
|
21
|
+
export type TColumnState =
|
|
22
|
+
| { type: "idle" }
|
|
23
|
+
| { type: "is-dragging" }
|
|
24
|
+
| { type: "is-dragging-and-left-self" }
|
|
25
|
+
| { type: "is-card-over"; isOverChildCard: boolean; dragging: DOMRect }
|
|
26
|
+
| { type: "is-column-over"; closestEdge: Edge; rect: DOMRect }
|
|
27
|
+
| { type: "preview"; container: HTMLElement; dragging: DOMRect };
|
|
28
|
+
|
|
29
|
+
const isCardData = (data: any) => data.type === "card";
|
|
30
|
+
const isColumnData = (data: any) => data.type === "column";
|
|
31
|
+
const idle: TColumnState = { type: "idle" };
|
|
32
|
+
|
|
33
|
+
export const useColumnDnd = (
|
|
34
|
+
data: BoardItem,
|
|
35
|
+
index: number,
|
|
36
|
+
items: BoardItem[],
|
|
37
|
+
onColumnDndStateChange?: (info: DndState) => void,
|
|
38
|
+
allowColumnDrag?: boolean,
|
|
39
|
+
hasCustomPreview?: boolean,
|
|
40
|
+
) => {
|
|
41
|
+
const { viewOnly } = useKanbanContext();
|
|
42
|
+
const isColumnDraggable =
|
|
43
|
+
!viewOnly && allowColumnDrag !== false && data.isDraggable !== false;
|
|
44
|
+
|
|
45
|
+
const headerRef = useRef<HTMLDivElement>(null);
|
|
46
|
+
const outerFullHeightRef = useRef<HTMLDivElement | null>(null);
|
|
47
|
+
const innerRef = useRef<HTMLDivElement | null>(null);
|
|
48
|
+
const [state, setState] = useState<TColumnState>(idle);
|
|
49
|
+
|
|
50
|
+
const cardOverShadowCount =
|
|
51
|
+
state.type === "is-card-over" && !state.isOverChildCard ? 1 : 0;
|
|
52
|
+
const totalTasksCount = data.totalChildrenCount + cardOverShadowCount;
|
|
53
|
+
|
|
54
|
+
const setIsCardOver = useCallback(
|
|
55
|
+
({ data, location }: { data: any; location: any }) => {
|
|
56
|
+
const innerMost = location.current.dropTargets[0];
|
|
57
|
+
const isOverChildCard = Boolean(innerMost?.data["card-drop-target"]);
|
|
58
|
+
|
|
59
|
+
const proposed: TColumnState = {
|
|
60
|
+
type: "is-card-over",
|
|
61
|
+
dragging: data.rect,
|
|
62
|
+
isOverChildCard,
|
|
63
|
+
};
|
|
64
|
+
|
|
65
|
+
setState((current) => {
|
|
66
|
+
if (
|
|
67
|
+
current.type === proposed.type &&
|
|
68
|
+
current.isOverChildCard === proposed.isOverChildCard &&
|
|
69
|
+
current.dragging === proposed.dragging
|
|
70
|
+
) {
|
|
71
|
+
return current;
|
|
72
|
+
}
|
|
73
|
+
return proposed;
|
|
74
|
+
});
|
|
75
|
+
},
|
|
76
|
+
[],
|
|
77
|
+
);
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
const outer = outerFullHeightRef.current;
|
|
81
|
+
const inner = innerRef.current;
|
|
82
|
+
const header = headerRef.current;
|
|
83
|
+
if (!outer || !inner || !header) return;
|
|
84
|
+
|
|
85
|
+
const scroller = outer.querySelector(
|
|
86
|
+
`.${withPrefix("column-content-list")}`,
|
|
87
|
+
);
|
|
88
|
+
|
|
89
|
+
const columnData = {
|
|
90
|
+
type: "column",
|
|
91
|
+
columnId: data.id,
|
|
92
|
+
column: data,
|
|
93
|
+
index,
|
|
94
|
+
};
|
|
95
|
+
|
|
96
|
+
return combine(
|
|
97
|
+
draggable({
|
|
98
|
+
element: header,
|
|
99
|
+
getInitialData: () => columnData,
|
|
100
|
+
canDrag: () => isColumnDraggable,
|
|
101
|
+
|
|
102
|
+
onGenerateDragPreview({ location, nativeSetDragImage }) {
|
|
103
|
+
const rect = outer.getBoundingClientRect();
|
|
104
|
+
|
|
105
|
+
setCustomNativeDragPreview({
|
|
106
|
+
nativeSetDragImage,
|
|
107
|
+
getOffset: preserveOffsetOnSource({
|
|
108
|
+
element: outer,
|
|
109
|
+
input: location.current.input,
|
|
110
|
+
}),
|
|
111
|
+
render({ container }) {
|
|
112
|
+
if (hasCustomPreview) {
|
|
113
|
+
setState({ type: "preview", container, dragging: rect });
|
|
114
|
+
} else {
|
|
115
|
+
const clone = outer.cloneNode(true) as HTMLElement;
|
|
116
|
+
clone.style.width = `${rect.width}px`;
|
|
117
|
+
clone.style.height = `${rect.height}px`;
|
|
118
|
+
clone.style.transform = "rotate(4deg)";
|
|
119
|
+
clone.style.boxShadow = "0 8px 24px rgba(0,0,0,0.15)";
|
|
120
|
+
container.appendChild(clone);
|
|
121
|
+
}
|
|
122
|
+
},
|
|
123
|
+
});
|
|
124
|
+
},
|
|
125
|
+
|
|
126
|
+
onDragStart() {
|
|
127
|
+
setState({ type: "is-dragging" });
|
|
128
|
+
},
|
|
129
|
+
|
|
130
|
+
onDrop() {
|
|
131
|
+
setState(idle);
|
|
132
|
+
},
|
|
133
|
+
}),
|
|
134
|
+
|
|
135
|
+
dropTargetForElements({
|
|
136
|
+
element: outer,
|
|
137
|
+
|
|
138
|
+
getData({ input, element }) {
|
|
139
|
+
return attachClosestEdge(columnData, {
|
|
140
|
+
input,
|
|
141
|
+
element,
|
|
142
|
+
allowedEdges: ["left", "right"],
|
|
143
|
+
});
|
|
144
|
+
},
|
|
145
|
+
|
|
146
|
+
canDrop({ source }) {
|
|
147
|
+
return isCardData(source.data) || isColumnData(source.data);
|
|
148
|
+
},
|
|
149
|
+
|
|
150
|
+
getIsSticky: () => true,
|
|
151
|
+
|
|
152
|
+
onDragStart({ source, location }) {
|
|
153
|
+
if (isCardData(source.data)) {
|
|
154
|
+
setIsCardOver({ data: source.data, location });
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
onDragEnter({ source, location, self }) {
|
|
159
|
+
if (isCardData(source.data)) {
|
|
160
|
+
setIsCardOver({ data: source.data, location });
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
if (isColumnData(source.data) && source.data.columnId !== data.id) {
|
|
164
|
+
const closestEdge = extractClosestEdge(self.data);
|
|
165
|
+
if (!closestEdge) return;
|
|
166
|
+
const rect = outer.getBoundingClientRect();
|
|
167
|
+
setState({ type: "is-column-over", closestEdge, rect });
|
|
168
|
+
}
|
|
169
|
+
},
|
|
170
|
+
|
|
171
|
+
onDrag({ source, self }) {
|
|
172
|
+
if (!isColumnData(source.data)) return;
|
|
173
|
+
if (source.data.columnId === data.id) return;
|
|
174
|
+
|
|
175
|
+
const closestEdge = extractClosestEdge(self.data);
|
|
176
|
+
if (!closestEdge) return;
|
|
177
|
+
|
|
178
|
+
setState((current) => {
|
|
179
|
+
if (
|
|
180
|
+
current.type === "is-column-over" &&
|
|
181
|
+
current.closestEdge === closestEdge
|
|
182
|
+
) {
|
|
183
|
+
return current;
|
|
184
|
+
}
|
|
185
|
+
const rect = outer.getBoundingClientRect();
|
|
186
|
+
return { type: "is-column-over", closestEdge, rect };
|
|
187
|
+
});
|
|
188
|
+
},
|
|
189
|
+
|
|
190
|
+
onDropTargetChange({ source, location }) {
|
|
191
|
+
if (isCardData(source.data)) {
|
|
192
|
+
setIsCardOver({ data: source.data, location });
|
|
193
|
+
}
|
|
194
|
+
},
|
|
195
|
+
|
|
196
|
+
onDragLeave({ source }) {
|
|
197
|
+
if (isColumnData(source.data) && source.data.columnId === data.id) {
|
|
198
|
+
setState({ type: "is-dragging-and-left-self" });
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
setState(idle);
|
|
202
|
+
},
|
|
203
|
+
|
|
204
|
+
onDrop() {
|
|
205
|
+
setState(idle);
|
|
206
|
+
},
|
|
207
|
+
}),
|
|
208
|
+
|
|
209
|
+
autoScrollForElements({
|
|
210
|
+
canScroll({ source }) {
|
|
211
|
+
return isCardData(source.data);
|
|
212
|
+
},
|
|
213
|
+
getConfiguration: () => ({ maxScrollSpeed: "standard" as const }),
|
|
214
|
+
element: scroller,
|
|
215
|
+
}),
|
|
216
|
+
);
|
|
217
|
+
}, [data, index, items?.length, isColumnDraggable, hasCustomPreview]);
|
|
218
|
+
|
|
219
|
+
useEffect(() => {
|
|
220
|
+
onColumnDndStateChange?.({ state, column: data });
|
|
221
|
+
}, [state, onColumnDndStateChange]);
|
|
222
|
+
|
|
223
|
+
return {
|
|
224
|
+
headerRef,
|
|
225
|
+
outerFullHeightRef,
|
|
226
|
+
innerRef,
|
|
227
|
+
state,
|
|
228
|
+
cardOverShadowCount,
|
|
229
|
+
totalTasksCount,
|
|
230
|
+
};
|
|
231
|
+
};
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
:root {
|
|
2
|
+
--vf-font-familly: "Raleway", sans-serif;
|
|
3
|
+
--vf-prefix-class: "vf";
|
|
4
|
+
|
|
5
|
+
//COLORS
|
|
6
|
+
|
|
7
|
+
--vf-color-white: #fff;
|
|
8
|
+
--vf-color-black: #000;
|
|
9
|
+
|
|
10
|
+
--vf-color-primary: #5f55ee;
|
|
11
|
+
--vf-color-primary-50: #fcf9ff;
|
|
12
|
+
--vf-color-primary-100: #f5eefa;
|
|
13
|
+
--vf-color-primary-200: #e0ccef;
|
|
14
|
+
--vf-color-primary-300: #c198e0;
|
|
15
|
+
--vf-color-primary-400: #ad76d5;
|
|
16
|
+
--vf-color-primary-500: #9854cb;
|
|
17
|
+
--vf-color-primary-600: #7a43a2;
|
|
18
|
+
--vf-color-primary-700: #5b327a;
|
|
19
|
+
--vf-color-primary-800: #3d2251;
|
|
20
|
+
--vf-color-primary-900: #301942;
|
|
21
|
+
--vf-color-primary-950: #1e1129;
|
|
22
|
+
|
|
23
|
+
--vf-color-secondary: #fdb022;
|
|
24
|
+
--vf-color-secondary-50: #fffcf5;
|
|
25
|
+
--vf-color-secondary-100: #fffaeb;
|
|
26
|
+
--vf-color-secondary-200: #fef0c7;
|
|
27
|
+
--vf-color-secondary-300: #fedf89;
|
|
28
|
+
--vf-color-secondary-400: #fec84b;
|
|
29
|
+
--vf-color-secondary-500: #fdb022;
|
|
30
|
+
--vf-color-secondary-600: #f79009;
|
|
31
|
+
--vf-color-secondary-700: #dc6803;
|
|
32
|
+
--vf-color-secondary-800: #b54708;
|
|
33
|
+
--vf-color-secondary-900: #92330a;
|
|
34
|
+
--vf-color-secondary-950: #6c2304;
|
|
35
|
+
|
|
36
|
+
--vf-color-red: #ff4141;
|
|
37
|
+
--vf-color-red-50: #fff4f4;
|
|
38
|
+
--vf-color-red-100: #ffe8e8;
|
|
39
|
+
--vf-color-red-200: #ffd4d4;
|
|
40
|
+
--vf-color-red-300: #ffb4b4;
|
|
41
|
+
--vf-color-red-400: #ff8383;
|
|
42
|
+
--vf-color-red-500: #ff4141;
|
|
43
|
+
--vf-color-red-600: #ff1616;
|
|
44
|
+
--vf-color-red-700: #d80000;
|
|
45
|
+
--vf-color-red-800: #b50000;
|
|
46
|
+
--vf-color-red-900: #7e040e;
|
|
47
|
+
--vf-color-red-950: #64020a;
|
|
48
|
+
|
|
49
|
+
--vf-color-gray: #9d9d9d;
|
|
50
|
+
--vf-color-gray-50: #ffffff;
|
|
51
|
+
--vf-color-gray-100: #f0f0f0;
|
|
52
|
+
--vf-color-gray-200: #dadada;
|
|
53
|
+
--vf-color-gray-300: #cecece;
|
|
54
|
+
--vf-color-gray-400: #b6b6b6;
|
|
55
|
+
--vf-color-gray-500: #9d9d9d;
|
|
56
|
+
--vf-color-gray-600: #6a6a6a;
|
|
57
|
+
--vf-color-gray-700: #545454;
|
|
58
|
+
--vf-color-gray-800: #373737;
|
|
59
|
+
--vf-color-gray-900: #1c1c1c;
|
|
60
|
+
--vf-color-gray-950: #000000;
|
|
61
|
+
|
|
62
|
+
--vf-color-green: #29b58b;
|
|
63
|
+
--vf-color-green-50: #f1fffb;
|
|
64
|
+
--vf-color-green-100: #e2fff6;
|
|
65
|
+
--vf-color-green-200: #ccfff0;
|
|
66
|
+
--vf-color-green-300: #a3edd7;
|
|
67
|
+
--vf-color-green-400: #52c8a4;
|
|
68
|
+
--vf-color-green-500: #29b58b;
|
|
69
|
+
--vf-color-green-600: #00a372;
|
|
70
|
+
--vf-color-green-700: #00825b;
|
|
71
|
+
--vf-color-green-800: #006346;
|
|
72
|
+
--vf-color-green-900: #00412e;
|
|
73
|
+
--vf-color-green-950: #002117;
|
|
74
|
+
|
|
75
|
+
--vf-color-orange: #29b58b;
|
|
76
|
+
--vf-color-orange-50: #fffdf6;
|
|
77
|
+
--vf-color-orange-100: #fffaea;
|
|
78
|
+
--vf-color-orange-200: #fff5d4;
|
|
79
|
+
--vf-color-orange-300: #ffecaa;
|
|
80
|
+
--vf-color-orange-400: #ffe27f;
|
|
81
|
+
--vf-color-orange-500: #ffcf2b;
|
|
82
|
+
--vf-color-orange-600: #e6ba27;
|
|
83
|
+
--vf-color-orange-700: #bf9b20;
|
|
84
|
+
--vf-color-orange-800: #806716;
|
|
85
|
+
--vf-color-orange-900: #4d3f0d;
|
|
86
|
+
--vf-color-orange-950: #342a08;
|
|
87
|
+
--vf-color-orange-1000: #fa8900;
|
|
88
|
+
|
|
89
|
+
--vf-color-ashgrey: #b3afa1;
|
|
90
|
+
--vf-color-ashgrey-50: #fdfdfc;
|
|
91
|
+
--vf-color-ashgrey-100: #fbfbf9;
|
|
92
|
+
--vf-color-ashgrey-200: #f7f6f2;
|
|
93
|
+
--vf-color-ashgrey-300: #f0efea;
|
|
94
|
+
--vf-color-ashgrey-400: #dddad0;
|
|
95
|
+
--vf-color-ashgrey-500: #b3afa1;
|
|
96
|
+
--vf-color-ashgrey-600: #858071;
|
|
97
|
+
--vf-color-ashgrey-700: #5e5267;
|
|
98
|
+
--vf-color-ashgrey-800: #676252;
|
|
99
|
+
--vf-color-ashgrey-900: #39321d;
|
|
100
|
+
--vf-color-ashgrey-950: #282210;
|
|
101
|
+
|
|
102
|
+
--vf-color-snow: #b3afa1;
|
|
103
|
+
--vf-color-snow-50: #fdfcfd;
|
|
104
|
+
--vf-color-snow-100: #faf9fb;
|
|
105
|
+
--vf-color-snow-200: #f5f2f7;
|
|
106
|
+
--vf-color-snow-300: #edeaf0;
|
|
107
|
+
--vf-color-snow-400: #d7d0dd;
|
|
108
|
+
--vf-color-snow-500: #aba1b3;
|
|
109
|
+
--vf-color-snow-600: #7c7185;
|
|
110
|
+
--vf-color-snow-700: #5e5267;
|
|
111
|
+
--vf-color-snow-800: #463454;
|
|
112
|
+
--vf-color-snow-900: #2d1d39;
|
|
113
|
+
--vf-color-snow-950: #1e1028;
|
|
114
|
+
|
|
115
|
+
--vf-color-gray-0: #fff;
|
|
116
|
+
--vf-color-yellow-50: #ffb300;
|
|
117
|
+
--vf-color-cyan-50: #00bcd4;
|
|
118
|
+
--vf-color-blue-50: #2196f3;
|
|
119
|
+
--vf-color-violet-50: #673ab7;
|
|
120
|
+
|
|
121
|
+
--vf-color-info: #1677ff;
|
|
122
|
+
--vf-color-success: #52c41a;
|
|
123
|
+
--vf-color-warning: #faad14;
|
|
124
|
+
--vf-color-error: #ff4d4f;
|
|
125
|
+
|
|
126
|
+
--vf-control-bar-height: 48px;
|
|
127
|
+
|
|
128
|
+
--vf-border-radius: 12px;
|
|
129
|
+
|
|
130
|
+
--vf-progress-bar-bg: #fff3;
|
|
131
|
+
--vf-progress-bar-load-bg: #fff6;
|
|
132
|
+
--vf-progress-bar-play-bg: var(--vf-color-primary);
|
|
133
|
+
|
|
134
|
+
--vf-dropdown-menu-item-hover: #ffffff1a;
|
|
135
|
+
--vf-sound-icon-size: 18px;
|
|
136
|
+
--vf-sound-icon-color: #fff;
|
|
137
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import "./components/_index.scss";
|
|
2
|
+
import { dropHandler, dropColumnHandler } from "./global/dnd/dropManager";
|
|
3
|
+
|
|
4
|
+
export type { BoardProps, BoardItem, BoardData } from "./components/types";
|
|
5
|
+
export { default as Kanban } from "./components/Kanban";
|
|
6
|
+
export { dropHandler, dropColumnHandler };
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BoardData, BoardItem } from "@/components";
|
|
2
|
+
|
|
3
|
+
export const getColumnsFromDataSource = (dataSource: BoardData) => {
|
|
4
|
+
if (!dataSource?.root) return [];
|
|
5
|
+
return dataSource.root.children?.map((child) => dataSource[child]) || [];
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
export const getColumnChildren = (column: BoardItem, dataSource: BoardData) => {
|
|
9
|
+
if (!column) return [];
|
|
10
|
+
return column.children?.map((child) => dataSource[child]) || [];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export const getHeaderHeight = (header: HTMLDivElement): number => {
|
|
14
|
+
if (!header) return 0;
|
|
15
|
+
const style = window.getComputedStyle(header);
|
|
16
|
+
const marginTop = parseFloat(style.marginTop) || 0;
|
|
17
|
+
const marginBottom = parseFloat(style.marginBottom) || 0;
|
|
18
|
+
return header.offsetHeight + marginTop + marginBottom;
|
|
19
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { BoardProps } from "@/components";
|
|
2
|
+
|
|
3
|
+
export const getSharedProps = (props: BoardProps) => {
|
|
4
|
+
const {
|
|
5
|
+
viewOnly = false,
|
|
6
|
+
virtualization = true,
|
|
7
|
+
cardsGap = 8,
|
|
8
|
+
allowColumnAdder = true,
|
|
9
|
+
allowListFooter,
|
|
10
|
+
} = props;
|
|
11
|
+
return {
|
|
12
|
+
viewOnly,
|
|
13
|
+
virtualization,
|
|
14
|
+
cardsGap,
|
|
15
|
+
allowColumnAdder,
|
|
16
|
+
allowListFooter,
|
|
17
|
+
};
|
|
18
|
+
};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { withPrefix } from "./getPrefix";
|
|
2
|
+
|
|
3
|
+
export const checkIfSkeletonIsVisible = ({ columnId, limit = 20 }): boolean => {
|
|
4
|
+
const skeletons = document.querySelectorAll(
|
|
5
|
+
`.${withPrefix("generic-item-skeleton")}[data-rkk-column="${columnId}"]`
|
|
6
|
+
);
|
|
7
|
+
|
|
8
|
+
if (!skeletons.length) return false;
|
|
9
|
+
|
|
10
|
+
const skeletonsToCheck = Array.from(skeletons).slice(0, limit);
|
|
11
|
+
|
|
12
|
+
const isVisible = skeletonsToCheck.some((skeleton) => {
|
|
13
|
+
const { top, bottom } = skeleton.getBoundingClientRect();
|
|
14
|
+
return top <= window.innerHeight && bottom >= 0;
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
return isVisible;
|
|
18
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
type CallbackRef<T> = (ref: T | null) => void;
|
|
4
|
+
type Ref<T> = React.MutableRefObject<T> | CallbackRef<T>;
|
|
5
|
+
|
|
6
|
+
const toFnRef = <T>(ref?: Ref<T | null> | null) =>
|
|
7
|
+
!ref || typeof ref === "function"
|
|
8
|
+
? ref
|
|
9
|
+
: (value: T | null) => {
|
|
10
|
+
ref.current = value;
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
export default function mergeRefs<T>(
|
|
14
|
+
refA?: Ref<T | null> | null,
|
|
15
|
+
refB?: Ref<T | null> | null
|
|
16
|
+
): React.RefCallback<T> {
|
|
17
|
+
const a = toFnRef(refA);
|
|
18
|
+
const b = toFnRef(refB);
|
|
19
|
+
return (value: T | null) => {
|
|
20
|
+
if (typeof a === "function") a(value);
|
|
21
|
+
if (typeof b === "function") b(value);
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { BoardItem, ScrollEvent } from "@/components";
|
|
2
|
+
import { withPrefix } from "./getPrefix";
|
|
3
|
+
|
|
4
|
+
export const handleScroll = (
|
|
5
|
+
e: React.UIEvent<HTMLDivElement> | number,
|
|
6
|
+
virtualization: boolean,
|
|
7
|
+
onScroll: (e: ScrollEvent, column: BoardItem) => void,
|
|
8
|
+
column: BoardItem
|
|
9
|
+
) => {
|
|
10
|
+
const scrollContainer = document.querySelector(
|
|
11
|
+
`.${withPrefix("column-content-list")}`
|
|
12
|
+
);
|
|
13
|
+
if (!scrollContainer) return;
|
|
14
|
+
|
|
15
|
+
const { scrollHeight, clientHeight } = scrollContainer;
|
|
16
|
+
let offset: number;
|
|
17
|
+
if (virtualization) {
|
|
18
|
+
offset = typeof e === "number" ? e : 0;
|
|
19
|
+
} else {
|
|
20
|
+
const target = (e as React.UIEvent<HTMLDivElement>)
|
|
21
|
+
.target as HTMLDivElement;
|
|
22
|
+
offset = target.scrollTop;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
const syntheticEvent = {
|
|
26
|
+
target: {
|
|
27
|
+
scrollTop: offset,
|
|
28
|
+
scrollHeight,
|
|
29
|
+
clientHeight,
|
|
30
|
+
},
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
onScroll?.(syntheticEvent, column);
|
|
34
|
+
};
|