@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,132 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import { BoardItem, BoardProps, ConfigMap, DndState } from "../types";
|
|
3
|
+
import classNames from "classnames";
|
|
4
|
+
import { withPrefix } from "@/utils/getPrefix";
|
|
5
|
+
import CardSkeleton from "../CardSkeleton";
|
|
6
|
+
import Card from "../Card";
|
|
7
|
+
import DefaultCard from "../DefaultCard";
|
|
8
|
+
import { CardShadow } from "../Card/Card";
|
|
9
|
+
|
|
10
|
+
const isCardDraggable = (data: BoardItem, isTypeDraggable: boolean) => {
|
|
11
|
+
return data?.isDraggable !== undefined ? data?.isDraggable : isTypeDraggable;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
interface Props {
|
|
15
|
+
index: number;
|
|
16
|
+
options: {
|
|
17
|
+
data: BoardItem;
|
|
18
|
+
column: BoardItem;
|
|
19
|
+
configMap: ConfigMap;
|
|
20
|
+
//isSkeleton is used to show a skeleton UI when the item is not loaded yet
|
|
21
|
+
isSkeleton: boolean;
|
|
22
|
+
isShadow: boolean;
|
|
23
|
+
isListFooter: boolean;
|
|
24
|
+
renderListFooter?: (column: BoardItem) => React.ReactNode;
|
|
25
|
+
cardWrapperStyle?: (
|
|
26
|
+
card: BoardItem,
|
|
27
|
+
column: BoardItem,
|
|
28
|
+
) => React.CSSProperties;
|
|
29
|
+
cardWrapperClassName?: string;
|
|
30
|
+
cardsGap?: number;
|
|
31
|
+
renderSkeletonCard?: BoardProps["renderSkeletonCard"];
|
|
32
|
+
onCardDndStateChange?: (info: DndState) => void;
|
|
33
|
+
onCardClick?: (
|
|
34
|
+
e: React.MouseEvent<HTMLDivElement>,
|
|
35
|
+
card: BoardItem,
|
|
36
|
+
) => void;
|
|
37
|
+
cardOverHeight?: number;
|
|
38
|
+
renderCardDragIndicator?: (card: BoardItem, info: any) => React.ReactNode;
|
|
39
|
+
renderCardDragPreview?: (card: BoardItem, info: any) => React.ReactNode;
|
|
40
|
+
renderGap?: (column: BoardItem) => React.ReactNode;
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const GenericItem = (props: Props) => {
|
|
45
|
+
const { index, options } = props;
|
|
46
|
+
const {
|
|
47
|
+
data,
|
|
48
|
+
column,
|
|
49
|
+
configMap,
|
|
50
|
+
isSkeleton,
|
|
51
|
+
cardWrapperStyle,
|
|
52
|
+
cardWrapperClassName,
|
|
53
|
+
cardsGap = 8,
|
|
54
|
+
isShadow,
|
|
55
|
+
isListFooter,
|
|
56
|
+
cardOverHeight = 90,
|
|
57
|
+
renderSkeletonCard,
|
|
58
|
+
onCardClick,
|
|
59
|
+
onCardDndStateChange,
|
|
60
|
+
renderCardDragIndicator,
|
|
61
|
+
renderListFooter,
|
|
62
|
+
renderCardDragPreview,
|
|
63
|
+
renderGap,
|
|
64
|
+
} = options;
|
|
65
|
+
|
|
66
|
+
const { render = DefaultCard, isDraggable = true } =
|
|
67
|
+
configMap?.[data?.type] || {};
|
|
68
|
+
|
|
69
|
+
const wrapperClassName = classNames(
|
|
70
|
+
withPrefix("generic-item-wrapper"),
|
|
71
|
+
cardWrapperClassName,
|
|
72
|
+
);
|
|
73
|
+
|
|
74
|
+
const renderCardContent = () => {
|
|
75
|
+
if (isListFooter)
|
|
76
|
+
return (
|
|
77
|
+
<div className={withPrefix("generic-item-list-footer")}>
|
|
78
|
+
{renderListFooter?.(column) || "Default Footer"}
|
|
79
|
+
</div>
|
|
80
|
+
);
|
|
81
|
+
else if (isShadow)
|
|
82
|
+
return (
|
|
83
|
+
<CardShadow
|
|
84
|
+
height={cardOverHeight}
|
|
85
|
+
customIndicator={renderCardDragIndicator?.(data, {
|
|
86
|
+
height: cardOverHeight,
|
|
87
|
+
})}
|
|
88
|
+
/>
|
|
89
|
+
);
|
|
90
|
+
else if (isSkeleton)
|
|
91
|
+
return (
|
|
92
|
+
<div
|
|
93
|
+
className={withPrefix("generic-item-skeleton")}
|
|
94
|
+
data-index={index}
|
|
95
|
+
data-rkk-column={column?.id}
|
|
96
|
+
>
|
|
97
|
+
{renderSkeletonCard?.({ index, column }) || (
|
|
98
|
+
<CardSkeleton animationType="wave" />
|
|
99
|
+
)}
|
|
100
|
+
</div>
|
|
101
|
+
);
|
|
102
|
+
|
|
103
|
+
return (
|
|
104
|
+
<Card
|
|
105
|
+
render={render}
|
|
106
|
+
isDraggable={isCardDraggable(data, isDraggable)}
|
|
107
|
+
data={data}
|
|
108
|
+
column={column}
|
|
109
|
+
index={index}
|
|
110
|
+
onClick={onCardClick}
|
|
111
|
+
cardsGap={cardsGap}
|
|
112
|
+
renderGap={renderGap}
|
|
113
|
+
onCardDndStateChange={onCardDndStateChange}
|
|
114
|
+
renderCardDragIndicator={renderCardDragIndicator}
|
|
115
|
+
renderCardDragPreview={renderCardDragPreview}
|
|
116
|
+
/>
|
|
117
|
+
);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
return (
|
|
121
|
+
<div
|
|
122
|
+
className={wrapperClassName}
|
|
123
|
+
style={{
|
|
124
|
+
...(cardWrapperStyle?.(data, column) || {}),
|
|
125
|
+
}}
|
|
126
|
+
>
|
|
127
|
+
{renderCardContent()}
|
|
128
|
+
</div>
|
|
129
|
+
);
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
export default GenericItem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@forward "./GenericItem";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default } from "./GenericItem";
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { BoardProps } from "./types";
|
|
2
|
+
import {
|
|
3
|
+
getColumnChildren,
|
|
4
|
+
getColumnsFromDataSource,
|
|
5
|
+
} from "@/utils/columnsUtils";
|
|
6
|
+
import { withPrefix } from "@/utils/getPrefix";
|
|
7
|
+
import classNames from "classnames";
|
|
8
|
+
import { Column } from "./Column";
|
|
9
|
+
import { forwardRef, useEffect, useRef } from "react";
|
|
10
|
+
import { autoScroller } from "@atlaskit/pragmatic-drag-and-drop-react-beautiful-dnd-autoscroll";
|
|
11
|
+
import { monitorForElements } from "@atlaskit/pragmatic-drag-and-drop/element/adapter";
|
|
12
|
+
import { combine } from "@atlaskit/pragmatic-drag-and-drop/combine";
|
|
13
|
+
import { autoScrollForElements } from "@atlaskit/pragmatic-drag-and-drop-auto-scroll/element";
|
|
14
|
+
import { KanbanProvider } from "@/context/KanbanContext";
|
|
15
|
+
import mergeRefs from "@/utils/mergeRefs";
|
|
16
|
+
import { handleCardDrop } from "@/global/dnd/dropManager";
|
|
17
|
+
import { getSharedProps } from "@/utils/getSharedProps";
|
|
18
|
+
import ColumnAdder from "./ColumnAdder";
|
|
19
|
+
|
|
20
|
+
const Kanban = forwardRef<HTMLDivElement, BoardProps>((props, ref) => {
|
|
21
|
+
const {
|
|
22
|
+
dataSource,
|
|
23
|
+
rootStyle = {},
|
|
24
|
+
rootClassName,
|
|
25
|
+
onColumnMove,
|
|
26
|
+
onCardMove,
|
|
27
|
+
renderColumnWrapper,
|
|
28
|
+
renderColumnAdder,
|
|
29
|
+
allowColumnDrag,
|
|
30
|
+
...rest
|
|
31
|
+
} = props;
|
|
32
|
+
|
|
33
|
+
const columns = getColumnsFromDataSource(dataSource);
|
|
34
|
+
const internalRef = useRef<HTMLDivElement>(null);
|
|
35
|
+
|
|
36
|
+
useEffect(() => {
|
|
37
|
+
if (!internalRef.current) return;
|
|
38
|
+
|
|
39
|
+
return combine(
|
|
40
|
+
monitorForElements({
|
|
41
|
+
onDragStart({ location }) {
|
|
42
|
+
autoScroller.start({ input: location.current.input });
|
|
43
|
+
},
|
|
44
|
+
onDrag({ location }) {
|
|
45
|
+
autoScroller.updateInput({ input: location.current.input });
|
|
46
|
+
},
|
|
47
|
+
onDrop(args) {
|
|
48
|
+
autoScroller.stop();
|
|
49
|
+
handleCardDrop({
|
|
50
|
+
source: {
|
|
51
|
+
id: (args.source as any).id || "",
|
|
52
|
+
data: args.source.data,
|
|
53
|
+
},
|
|
54
|
+
location: {
|
|
55
|
+
current: {
|
|
56
|
+
dropTargets: args.location.current.dropTargets,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
columns,
|
|
60
|
+
dataSource,
|
|
61
|
+
onCardMove,
|
|
62
|
+
onColumnMove,
|
|
63
|
+
});
|
|
64
|
+
},
|
|
65
|
+
}),
|
|
66
|
+
autoScrollForElements({
|
|
67
|
+
element: internalRef.current,
|
|
68
|
+
canScroll: () => true,
|
|
69
|
+
getConfiguration: () => ({
|
|
70
|
+
maxScrollSpeed: "standard",
|
|
71
|
+
}),
|
|
72
|
+
}),
|
|
73
|
+
);
|
|
74
|
+
}, [columns, dataSource, onCardMove, onColumnMove]);
|
|
75
|
+
|
|
76
|
+
const containerClassName = classNames(withPrefix("board"), rootClassName);
|
|
77
|
+
|
|
78
|
+
return (
|
|
79
|
+
<KanbanProvider {...getSharedProps(props)}>
|
|
80
|
+
<div
|
|
81
|
+
ref={mergeRefs(ref, internalRef)}
|
|
82
|
+
className={containerClassName}
|
|
83
|
+
style={rootStyle}
|
|
84
|
+
>
|
|
85
|
+
{columns?.map((column, index) => (
|
|
86
|
+
<Column
|
|
87
|
+
key={column.id}
|
|
88
|
+
index={index}
|
|
89
|
+
data={column}
|
|
90
|
+
items={getColumnChildren(column, dataSource)}
|
|
91
|
+
renderColumnWrapper={renderColumnWrapper}
|
|
92
|
+
allowColumnDrag={allowColumnDrag}
|
|
93
|
+
{...rest}
|
|
94
|
+
/>
|
|
95
|
+
))}
|
|
96
|
+
<ColumnAdder renderColumnAdder={renderColumnAdder} />
|
|
97
|
+
</div>
|
|
98
|
+
</KanbanProvider>
|
|
99
|
+
);
|
|
100
|
+
});
|
|
101
|
+
|
|
102
|
+
export default Kanban;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { TaskCardState } from "@/global/dnd/useCardDnd";
|
|
2
|
+
import { TColumnState } from "@/global/dnd/useColumnDnd";
|
|
3
|
+
import { CSSProperties, ReactNode } from "react";
|
|
4
|
+
|
|
5
|
+
export interface DndState {
|
|
6
|
+
state: TaskCardState | TColumnState;
|
|
7
|
+
column?: BoardItem;
|
|
8
|
+
card?: BoardItem;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export interface ScrollEvent {
|
|
12
|
+
target: {
|
|
13
|
+
scrollTop: number;
|
|
14
|
+
scrollHeight: number;
|
|
15
|
+
clientHeight: number;
|
|
16
|
+
};
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export type CardRenderProps = {
|
|
20
|
+
data: BoardItem;
|
|
21
|
+
column: BoardItem;
|
|
22
|
+
index: number;
|
|
23
|
+
isDraggable: boolean;
|
|
24
|
+
};
|
|
25
|
+
|
|
26
|
+
export type ConfigMap = {
|
|
27
|
+
[type: string]: {
|
|
28
|
+
render: (props: CardRenderProps) => React.ReactNode;
|
|
29
|
+
isDraggable?: boolean;
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
|
|
33
|
+
export interface BoardItem {
|
|
34
|
+
id: string;
|
|
35
|
+
title: string;
|
|
36
|
+
parentId: string | null;
|
|
37
|
+
children: string[];
|
|
38
|
+
content?: any;
|
|
39
|
+
type?: keyof ConfigMap;
|
|
40
|
+
totalItems?: number;
|
|
41
|
+
// totalChildrenCount is the total number of children in the column
|
|
42
|
+
totalChildrenCount: number;
|
|
43
|
+
// totalItemsCount is the total number of items (real content) in the column
|
|
44
|
+
totalItemsCount?: number;
|
|
45
|
+
isDraggable?: boolean;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export interface BoardData {
|
|
49
|
+
root: BoardItem;
|
|
50
|
+
[key: string]: BoardItem;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
export interface DropColumnParams {
|
|
54
|
+
columnId: string;
|
|
55
|
+
fromIndex: number;
|
|
56
|
+
toIndex: number;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export interface DropCardParams {
|
|
60
|
+
cardId: string;
|
|
61
|
+
fromColumnId: string;
|
|
62
|
+
toColumnId: string;
|
|
63
|
+
taskAbove: string | null;
|
|
64
|
+
taskBelow: string | null;
|
|
65
|
+
position: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export interface BoardProps {
|
|
69
|
+
dataSource: BoardData;
|
|
70
|
+
configMap: ConfigMap;
|
|
71
|
+
viewOnly?: boolean;
|
|
72
|
+
loadMore?: (groupsId: string) => void;
|
|
73
|
+
renderSkeletonCard?: ({
|
|
74
|
+
index,
|
|
75
|
+
column,
|
|
76
|
+
}: {
|
|
77
|
+
index: number;
|
|
78
|
+
column: BoardItem;
|
|
79
|
+
}) => ReactNode;
|
|
80
|
+
renderColumnHeader?: (column: BoardItem) => ReactNode;
|
|
81
|
+
renderCardDragIndicator?: (card: BoardItem, info: any) => ReactNode;
|
|
82
|
+
renderCardDragPreview?: (card: BoardItem, info: any) => ReactNode;
|
|
83
|
+
renderColumnDragIndicator?: (
|
|
84
|
+
column: BoardItem,
|
|
85
|
+
info: { width: number; height: number; edge: "left" | "right" },
|
|
86
|
+
) => ReactNode;
|
|
87
|
+
renderColumnDragPreview?: (column: BoardItem, info: any) => ReactNode;
|
|
88
|
+
|
|
89
|
+
renderListFooter?: (column: BoardItem) => ReactNode;
|
|
90
|
+
allowListFooter?: (column: BoardItem) => boolean;
|
|
91
|
+
|
|
92
|
+
renderColumnAdder?: () => ReactNode;
|
|
93
|
+
allowColumnAdder?: boolean;
|
|
94
|
+
allowColumnDrag?: boolean;
|
|
95
|
+
|
|
96
|
+
renderColumnWrapper?: (
|
|
97
|
+
column: BoardItem,
|
|
98
|
+
{
|
|
99
|
+
children,
|
|
100
|
+
className,
|
|
101
|
+
style,
|
|
102
|
+
}: { children: ReactNode; className?: string; style?: CSSProperties },
|
|
103
|
+
) => ReactNode;
|
|
104
|
+
columnWrapperStyle?: (column: BoardItem) => CSSProperties;
|
|
105
|
+
columnHeaderStyle?: (column: BoardItem) => CSSProperties;
|
|
106
|
+
columnListContentStyle?: (column: BoardItem) => CSSProperties;
|
|
107
|
+
columnListContentClassName?: (column: BoardItem) => string;
|
|
108
|
+
columnWrapperClassName?: (column: BoardItem) => string;
|
|
109
|
+
columnHeaderClassName?: (column: BoardItem) => string;
|
|
110
|
+
columnClassName?: (column: BoardItem) => string;
|
|
111
|
+
columnStyle?: (column: BoardItem) => CSSProperties;
|
|
112
|
+
rootStyle?: CSSProperties;
|
|
113
|
+
rootClassName?: string;
|
|
114
|
+
cardWrapperStyle?: (card: BoardItem, column: BoardItem) => CSSProperties;
|
|
115
|
+
cardWrapperClassName?: string;
|
|
116
|
+
virtualization?: boolean;
|
|
117
|
+
cardsGap?: number;
|
|
118
|
+
// renderGap?: (column: BoardItem) => ReactNode;
|
|
119
|
+
onScroll?: (e: ScrollEvent, column: BoardItem) => void;
|
|
120
|
+
onColumnMove?: ({ columnId, fromIndex, toIndex }: DropColumnParams) => void;
|
|
121
|
+
onCardMove?: ({
|
|
122
|
+
cardId,
|
|
123
|
+
fromColumnId,
|
|
124
|
+
toColumnId,
|
|
125
|
+
taskAbove,
|
|
126
|
+
taskBelow,
|
|
127
|
+
position,
|
|
128
|
+
}: DropCardParams) => void;
|
|
129
|
+
renderColumnFooter?: (column: BoardItem) => ReactNode;
|
|
130
|
+
onColumnClick?: (
|
|
131
|
+
e: React.MouseEvent<HTMLDivElement>,
|
|
132
|
+
column: BoardItem,
|
|
133
|
+
) => void;
|
|
134
|
+
onCardClick?: (e: React.MouseEvent<HTMLDivElement>, card: BoardItem) => void;
|
|
135
|
+
onCardDndStateChange?: (info: DndState) => void;
|
|
136
|
+
onColumnDndStateChange?: (info: DndState) => void;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
export interface DropParams {
|
|
140
|
+
source: {
|
|
141
|
+
id: string;
|
|
142
|
+
data: any;
|
|
143
|
+
};
|
|
144
|
+
location: {
|
|
145
|
+
current: {
|
|
146
|
+
dropTargets: Array<{
|
|
147
|
+
data: any;
|
|
148
|
+
}>;
|
|
149
|
+
};
|
|
150
|
+
};
|
|
151
|
+
columns: BoardItem[];
|
|
152
|
+
dataSource: BoardData;
|
|
153
|
+
onCardMove?: BoardProps["onCardMove"];
|
|
154
|
+
onColumnMove?: BoardProps["onColumnMove"];
|
|
155
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { BoardProps } from "@/components";
|
|
2
|
+
import { createContext, useContext } from "react";
|
|
3
|
+
|
|
4
|
+
const KanbanContext = createContext<Partial<BoardProps> | undefined>(undefined);
|
|
5
|
+
|
|
6
|
+
export const useKanbanContext = () => {
|
|
7
|
+
const context = useContext(KanbanContext);
|
|
8
|
+
if (!context) throw new Error("KanbanContext must be used within a provider");
|
|
9
|
+
return context;
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const KanbanProvider = ({
|
|
13
|
+
children,
|
|
14
|
+
...props
|
|
15
|
+
}: Partial<BoardProps> & { children: React.ReactNode }) => {
|
|
16
|
+
return (
|
|
17
|
+
<KanbanContext.Provider value={props}>{children}</KanbanContext.Provider>
|
|
18
|
+
);
|
|
19
|
+
};
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
// Small devices
|
|
2
|
+
@mixin sm {
|
|
3
|
+
@media (min-width: #{map-get($breakpoints, 'small')}) {
|
|
4
|
+
@content;
|
|
5
|
+
}
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
// Medium devices
|
|
9
|
+
@mixin md {
|
|
10
|
+
@media (min-width: #{map-get($breakpoints, 'medium')}) {
|
|
11
|
+
@content;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Large devices
|
|
16
|
+
@mixin lg {
|
|
17
|
+
@media (min-width: #{map-get($breakpoints, 'large')}) {
|
|
18
|
+
@content;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Extra large devices
|
|
23
|
+
@mixin xl {
|
|
24
|
+
@media (min-width: #{map-get($breakpoints, 'xlarge')}) {
|
|
25
|
+
@content;
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
// ++++++++++ MAX WIDTH ++++++++++
|
|
30
|
+
|
|
31
|
+
// Small devices
|
|
32
|
+
@mixin max-sm {
|
|
33
|
+
@media (max-width: #{map-get($breakpoints, 'small')}) {
|
|
34
|
+
@content;
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Medium devices
|
|
39
|
+
@mixin max-md {
|
|
40
|
+
@media (max-width: #{map-get($breakpoints, 'medium')}) {
|
|
41
|
+
@content;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// Large devices
|
|
46
|
+
@mixin max-lg {
|
|
47
|
+
@media (max-width: #{map-get($breakpoints, 'large')}) {
|
|
48
|
+
@content;
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Extra large devices
|
|
53
|
+
@mixin max-xl {
|
|
54
|
+
@media (max-width: #{map-get($breakpoints, 'xlarge')}) {
|
|
55
|
+
@content;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Custom devices (min-width)
|
|
60
|
+
@mixin rwd($screen) {
|
|
61
|
+
@media (min-width: #{$screen}px) {
|
|
62
|
+
@content;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// Custom devices (max-width)
|
|
67
|
+
@mixin max-rwd($screen) {
|
|
68
|
+
@media (max-width: #{$screen}px) {
|
|
69
|
+
@content;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
$light: white;
|
|
2
|
+
|
|
3
|
+
$main: #d7e7ef;
|
|
4
|
+
|
|
5
|
+
$info: #1cc3eb;
|
|
6
|
+
$info-50: #ecfdff;
|
|
7
|
+
$info-100: #d0f7fd;
|
|
8
|
+
$info-200: #a6edfb;
|
|
9
|
+
$info-300: #69def7;
|
|
10
|
+
$info-400: #1cc3eb;
|
|
11
|
+
$info-500: #08a8d2;
|
|
12
|
+
$info-600: #0a86b0;
|
|
13
|
+
$info-700: #0f6b8f;
|
|
14
|
+
$info-800: #165774;
|
|
15
|
+
$info-900: #174962;
|
|
16
|
+
$info-950: #092f43;
|
|
17
|
+
|
|
18
|
+
$success: #4caf50;
|
|
19
|
+
$success-50: #f3faf3;
|
|
20
|
+
$success-100: #e3f5e3;
|
|
21
|
+
$success-200: #c8eac9;
|
|
22
|
+
$success-300: #9dd89f;
|
|
23
|
+
$success-400: #6bbd6e;
|
|
24
|
+
$success-500: #4caf50;
|
|
25
|
+
$success-600: #358438;
|
|
26
|
+
$success-700: #2d6830;
|
|
27
|
+
$success-800: #275429;
|
|
28
|
+
$success-900: #224525;
|
|
29
|
+
$success-950: #0e2510;
|
|
30
|
+
|
|
31
|
+
$danger: #f04438;
|
|
32
|
+
$danger-50: #fff9f9;
|
|
33
|
+
$danger-100: #ffe3e1;
|
|
34
|
+
$danger-200: #ffccc8;
|
|
35
|
+
$danger-300: #ffa8a2;
|
|
36
|
+
$danger-400: #fc776d;
|
|
37
|
+
$danger-500: #f44336;
|
|
38
|
+
$danger-600: #e22d20;
|
|
39
|
+
$danger-700: #be2217;
|
|
40
|
+
$danger-800: #9d2017;
|
|
41
|
+
$danger-900: #82211a;
|
|
42
|
+
$danger-950: #470c08;
|
|
43
|
+
|
|
44
|
+
$warning: #ffc008;
|
|
45
|
+
$warning-50: #fffeea;
|
|
46
|
+
$warning-100: #fffbc5;
|
|
47
|
+
$warning-200: #fff785;
|
|
48
|
+
$warning-300: #ffed46;
|
|
49
|
+
$warning-400: #ffde1b;
|
|
50
|
+
$warning-500: #ffc008;
|
|
51
|
+
$warning-600: #e29200;
|
|
52
|
+
$warning-700: #bb6802;
|
|
53
|
+
$warning-800: #985008;
|
|
54
|
+
$warning-900: #7c410b;
|
|
55
|
+
$warning-950: #482100;
|
|
56
|
+
|
|
57
|
+
$dark: #131f3c;
|
|
58
|
+
$dark-50: #edf8ff;
|
|
59
|
+
$dark-100: #def2ff;
|
|
60
|
+
$dark-200: #c4e5ff;
|
|
61
|
+
$dark-300: #a1d2ff;
|
|
62
|
+
$dark-400: #7bb6fe;
|
|
63
|
+
$dark-500: #5c96f8;
|
|
64
|
+
$dark-600: #3e72ed;
|
|
65
|
+
$dark-700: #305dd2;
|
|
66
|
+
$dark-800: #2a4fa9;
|
|
67
|
+
$dark-900: #2a4785;
|
|
68
|
+
$dark-950: #131f3c;
|
|
69
|
+
|
|
70
|
+
$secondary: #d6d9e1;
|
|
71
|
+
$secondary-50: #f6f7f9;
|
|
72
|
+
$secondary-100: #f1f2f5;
|
|
73
|
+
$secondary-200: #d6d9e1;
|
|
74
|
+
$secondary-300: #b1b9c8;
|
|
75
|
+
$secondary-400: #8793a9;
|
|
76
|
+
$secondary-500: #68758f;
|
|
77
|
+
$secondary-600: #535e76;
|
|
78
|
+
$secondary-700: #444c60;
|
|
79
|
+
$secondary-800: #3b4151;
|
|
80
|
+
$secondary-900: #343946;
|
|
81
|
+
$secondary-950: #23262e;
|
|
82
|
+
|
|
83
|
+
$grey: #91939a;
|
|
84
|
+
|
|
85
|
+
$hover: #d7e7ef;
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//Cross browser CSS3 mixins
|
|
2
|
+
|
|
3
|
+
@mixin box-shadow($left, $top, $radius, $color) {
|
|
4
|
+
box-shadow: $left $top $radius $color;
|
|
5
|
+
-webkit-box-shadow: $left $top $radius $color;
|
|
6
|
+
-moz-box-shadow: $left $top $radius $color;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
@mixin transition($property, $duration, $easing: linear) {
|
|
10
|
+
transition: $property $duration $easing;
|
|
11
|
+
-webkit-transition: $property $duration $easing;
|
|
12
|
+
-moz-transition: $property $duration $easing;
|
|
13
|
+
-ms-transition: $property $duration $easing;
|
|
14
|
+
-o-transition: $property $duration $easing;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
@mixin border-radius($radius) {
|
|
18
|
+
border-radius: $radius;
|
|
19
|
+
-webkit-border-radius: $radius;
|
|
20
|
+
-moz-border-radius: $radius;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
@mixin border-radii($topleft, $topright, $bottomright, $bottomleft) {
|
|
24
|
+
border-top-left-radius: $topleft;
|
|
25
|
+
border-top-right-radius: $topright;
|
|
26
|
+
border-bottom-right-radius: $bottomright;
|
|
27
|
+
border-bottom-left-radius: $bottomleft;
|
|
28
|
+
-webkit-border-top-left-radius: $topleft;
|
|
29
|
+
-webkit-border-top-right-radius: $topright;
|
|
30
|
+
-webkit-border-bottom-right-radius: $bottomright;
|
|
31
|
+
-webkit-border-bottom-left-radius: $bottomleft;
|
|
32
|
+
-moz-border-radius-topleft: $topleft;
|
|
33
|
+
-moz-border-radius-topright: $topright;
|
|
34
|
+
-moz-border-radius-bottomright: $bottomright;
|
|
35
|
+
-moz-border-radius-bottomleft: $bottomleft;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
@mixin gradient($color1, $color2) {
|
|
39
|
+
background-color: $color1;
|
|
40
|
+
filter: progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr=#{$color1}, endColorstr=#{$color2});
|
|
41
|
+
background-image: -moz-linear-gradient(center top, $color1, $color2);
|
|
42
|
+
background-image: -webkit-gradient(
|
|
43
|
+
linear,
|
|
44
|
+
0% 0%,
|
|
45
|
+
0% 100%,
|
|
46
|
+
from($color1),
|
|
47
|
+
to($color2)
|
|
48
|
+
);
|
|
49
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
$padding-level: 30px;
|