@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.
Files changed (95) hide show
  1. package/LICENSE +13 -0
  2. package/README.md +630 -0
  3. package/dist/archbase-kanban-4.0.37.tgz +0 -0
  4. package/dist/components/Card/Card.d.ts +26 -0
  5. package/dist/components/Card/index.d.ts +1 -0
  6. package/dist/components/CardSkeleton/CardSkeleton.d.ts +9 -0
  7. package/dist/components/CardSkeleton/index.d.ts +2 -0
  8. package/dist/components/Column/Column.d.ts +47 -0
  9. package/dist/components/Column/index.d.ts +1 -0
  10. package/dist/components/ColumnAdder/ColumnAdder.d.ts +6 -0
  11. package/dist/components/ColumnAdder/index.d.ts +1 -0
  12. package/dist/components/ColumnContent/ColumnContent.d.ts +24 -0
  13. package/dist/components/ColumnContent/index.d.ts +1 -0
  14. package/dist/components/ColumnHeader/ColumnHeader.d.ts +10 -0
  15. package/dist/components/ColumnHeader/index.d.ts +1 -0
  16. package/dist/components/DefaultCard/DefaultCard.d.ts +3 -0
  17. package/dist/components/DefaultCard/index.d.ts +1 -0
  18. package/dist/components/GenericItem/GenericItem.d.ts +26 -0
  19. package/dist/components/GenericItem/index.d.ts +1 -0
  20. package/dist/components/Kanban.d.ts +3 -0
  21. package/dist/components/index.d.ts +2 -0
  22. package/dist/components/types.d.ts +124 -0
  23. package/dist/context/KanbanContext.d.ts +5 -0
  24. package/dist/global/dnd/dropManager.d.ts +16 -0
  25. package/dist/global/dnd/useCardDnd.d.ts +22 -0
  26. package/dist/global/dnd/useColumnDnd.d.ts +29 -0
  27. package/dist/index.css +1 -0
  28. package/dist/index.d.ts +4 -0
  29. package/dist/index.js +1041 -0
  30. package/dist/utils/columnsUtils.d.ts +4 -0
  31. package/dist/utils/getPrefix.d.ts +2 -0
  32. package/dist/utils/getSharedProps.d.ts +8 -0
  33. package/dist/utils/infinite-scroll.d.ts +4 -0
  34. package/dist/utils/mergeRefs.d.ts +5 -0
  35. package/dist/utils/scroll.d.ts +2 -0
  36. package/package.json +66 -0
  37. package/src/common/_index.scss +0 -0
  38. package/src/components/Card/Card.tsx +215 -0
  39. package/src/components/Card/_Card.scss +11 -0
  40. package/src/components/Card/_index.scss +1 -0
  41. package/src/components/Card/index.ts +1 -0
  42. package/src/components/CardSkeleton/CardSkeleton.tsx +45 -0
  43. package/src/components/CardSkeleton/_CardSkeleton.scss +245 -0
  44. package/src/components/CardSkeleton/_index.scss +1 -0
  45. package/src/components/CardSkeleton/index.ts +2 -0
  46. package/src/components/Column/Column.tsx +246 -0
  47. package/src/components/Column/_Column.scss +44 -0
  48. package/src/components/Column/_index.scss +1 -0
  49. package/src/components/Column/index.ts +1 -0
  50. package/src/components/ColumnAdder/ColumnAdder.tsx +18 -0
  51. package/src/components/ColumnAdder/_ColumnAdder.scss +0 -0
  52. package/src/components/ColumnAdder/_index.scss +1 -0
  53. package/src/components/ColumnAdder/index.ts +1 -0
  54. package/src/components/ColumnContent/ColumnContent.tsx +238 -0
  55. package/src/components/ColumnContent/_ColumnContent.scss +23 -0
  56. package/src/components/ColumnContent/_index.scss +1 -0
  57. package/src/components/ColumnContent/index.ts +1 -0
  58. package/src/components/ColumnHeader/ColumnHeader.tsx +43 -0
  59. package/src/components/ColumnHeader/_ColumnHeader.scss +26 -0
  60. package/src/components/ColumnHeader/_index.scss +1 -0
  61. package/src/components/ColumnHeader/index.ts +1 -0
  62. package/src/components/DefaultCard/DefaultCard.tsx +9 -0
  63. package/src/components/DefaultCard/_DefaultCard.scss +14 -0
  64. package/src/components/DefaultCard/_index.scss +1 -0
  65. package/src/components/DefaultCard/index.ts +1 -0
  66. package/src/components/GenericItem/GenericItem.tsx +132 -0
  67. package/src/components/GenericItem/_GenericItem.scss +4 -0
  68. package/src/components/GenericItem/_index.scss +1 -0
  69. package/src/components/GenericItem/index.ts +1 -0
  70. package/src/components/Kanban.tsx +102 -0
  71. package/src/components/_Kanban.scss +8 -0
  72. package/src/components/_index.scss +9 -0
  73. package/src/components/index.ts +2 -0
  74. package/src/components/types.ts +155 -0
  75. package/src/context/KanbanContext.tsx +19 -0
  76. package/src/global/_index.scss +3 -0
  77. package/src/global/assets/styles/abstracts/_breakpoints.scss +71 -0
  78. package/src/global/assets/styles/abstracts/_colors.scss +85 -0
  79. package/src/global/assets/styles/abstracts/_functions.scss +3 -0
  80. package/src/global/assets/styles/abstracts/_index.scss +5 -0
  81. package/src/global/assets/styles/abstracts/_mixins.scss +49 -0
  82. package/src/global/assets/styles/abstracts/_padding.scss +1 -0
  83. package/src/global/assets/styles/abstracts/_variables.scss +8 -0
  84. package/src/global/assets/styles/base/_index.scss +34 -0
  85. package/src/global/dnd/dropManager.ts +301 -0
  86. package/src/global/dnd/useCardDnd.tsx +225 -0
  87. package/src/global/dnd/useColumnDnd.tsx +231 -0
  88. package/src/global/theme-default.scss +137 -0
  89. package/src/index.ts +6 -0
  90. package/src/utils/columnsUtils.ts +19 -0
  91. package/src/utils/getPrefix.ts +7 -0
  92. package/src/utils/getSharedProps.ts +18 -0
  93. package/src/utils/infinite-scroll.ts +18 -0
  94. package/src/utils/mergeRefs.ts +23 -0
  95. package/src/utils/scroll.ts +34 -0
@@ -0,0 +1,246 @@
1
+ import React, { memo, useMemo } from "react";
2
+ import { createPortal } from "react-dom";
3
+ import {
4
+ BoardItem,
5
+ BoardProps,
6
+ ConfigMap,
7
+ DndState,
8
+ ScrollEvent,
9
+ } from "../types";
10
+ import { withPrefix } from "@/utils/getPrefix";
11
+ import classNames from "classnames";
12
+ import ColumnHeader from "../ColumnHeader";
13
+ import ColumnContent from "../ColumnContent";
14
+ import { useColumnDnd } from "@/global/dnd/useColumnDnd";
15
+
16
+ const ColumnDropIndicator = memo(
17
+ ({
18
+ width,
19
+ height,
20
+ customIndicator,
21
+ }: {
22
+ width: number;
23
+ height: number;
24
+ customIndicator?: React.ReactNode;
25
+ }) => (
26
+ <div className={withPrefix("column-shadow-container")}>
27
+ {customIndicator || (
28
+ <div
29
+ className={withPrefix("column-shadow")}
30
+ style={{ width, height }}
31
+ />
32
+ )}
33
+ </div>
34
+ ),
35
+ );
36
+
37
+
38
+ interface Props {
39
+ index: number;
40
+ data: BoardItem;
41
+ items: BoardItem[];
42
+ configMap: ConfigMap;
43
+ allowColumnDrag?: boolean;
44
+
45
+ // Renderers
46
+ renderColumnHeader?: (column: BoardItem) => React.ReactNode;
47
+ renderColumnFooter?: (column: BoardItem) => React.ReactNode;
48
+ renderColumnWrapper: (
49
+ column: BoardItem,
50
+ props: {
51
+ children: React.ReactNode;
52
+ className?: string;
53
+ style?: React.CSSProperties;
54
+ ref?: React.RefObject<HTMLDivElement>;
55
+ },
56
+ ) => React.ReactNode;
57
+ renderSkeletonCard?: BoardProps["renderSkeletonCard"];
58
+ renderListFooter?: (column: BoardItem) => React.ReactNode;
59
+ renderColumnAdder?: (column: BoardItem) => React.ReactNode;
60
+ renderGap?: (column: BoardItem) => React.ReactNode;
61
+
62
+ // DnD renderers
63
+ renderCardDragIndicator?: (card: BoardItem, info: any) => React.ReactNode;
64
+ renderCardDragPreview?: (card: BoardItem, info: any) => React.ReactNode;
65
+ renderColumnDragIndicator?: (
66
+ column: BoardItem,
67
+ info: { width: number; height: number; edge: "left" | "right" },
68
+ ) => React.ReactNode;
69
+ renderColumnDragPreview?: (column: BoardItem, info: any) => React.ReactNode;
70
+
71
+ // Styling
72
+ columnWrapperStyle?: (column: BoardItem) => React.CSSProperties;
73
+ columnWrapperClassName?: (column: BoardItem) => string;
74
+ columnHeaderStyle?: (column: BoardItem) => React.CSSProperties;
75
+ columnHeaderClassName?: (column: BoardItem) => string;
76
+ columnStyle?: (column: BoardItem) => React.CSSProperties;
77
+ columnClassName?: (column: BoardItem) => string;
78
+ columnListContentStyle?: (column: BoardItem) => React.CSSProperties;
79
+ columnListContentClassName?: (column: BoardItem) => string;
80
+ cardWrapperStyle?: (card: BoardItem, column: BoardItem) => React.CSSProperties;
81
+ cardWrapperClassName?: string;
82
+
83
+ onColumnClick?: (e: React.MouseEvent<HTMLDivElement>, column: BoardItem) => void;
84
+ onCardClick?: (e: React.MouseEvent<HTMLDivElement>, card: BoardItem) => void;
85
+ onCardDndStateChange?: (info: DndState) => void;
86
+ onColumnDndStateChange?: (info: DndState) => void;
87
+ onScroll?: (e: ScrollEvent, column: BoardItem) => void;
88
+
89
+ loadMore?: (columnId: string) => void;
90
+ }
91
+
92
+
93
+ const Column = (props: Props) => {
94
+ const {
95
+ index,
96
+ data,
97
+ items,
98
+ onColumnClick,
99
+ renderColumnHeader,
100
+ renderColumnWrapper,
101
+ renderColumnFooter,
102
+ columnWrapperStyle,
103
+ columnHeaderStyle,
104
+ onColumnDndStateChange,
105
+ columnWrapperClassName,
106
+ columnHeaderClassName,
107
+ columnListContentClassName,
108
+ columnClassName,
109
+ columnStyle,
110
+ renderColumnDragPreview,
111
+ renderColumnDragIndicator,
112
+ allowColumnDrag,
113
+ ...rest
114
+ } = props;
115
+
116
+
117
+ const {
118
+ headerRef,
119
+ outerFullHeightRef,
120
+ innerRef,
121
+ state,
122
+ cardOverShadowCount,
123
+ } = useColumnDnd(
124
+ data,
125
+ index,
126
+ items,
127
+ onColumnDndStateChange,
128
+ allowColumnDrag,
129
+ !!renderColumnDragPreview,
130
+ );
131
+
132
+
133
+ const isDragging = state.type === "is-dragging" || state.type === "preview";
134
+ const isHidden = state.type === "is-dragging-and-left-self";
135
+ const isColumnOver = state.type === "is-column-over";
136
+ const closestEdge = isColumnOver ? state.closestEdge : null;
137
+
138
+
139
+ const columnIndicator = useMemo(() => {
140
+ if (!isColumnOver) return null;
141
+
142
+ const { width, height } = state.rect;
143
+ const edge = state.closestEdge === "left" ? "left" : "right";
144
+ const custom = renderColumnDragIndicator?.(data, { width, height, edge });
145
+
146
+ return (
147
+ <ColumnDropIndicator
148
+ width={width}
149
+ height={height}
150
+ customIndicator={custom}
151
+ />
152
+ );
153
+ }, [isColumnOver, state, renderColumnDragIndicator, data]);
154
+
155
+
156
+ const previewContent = useMemo(() => {
157
+ if (state.type !== "preview" || !renderColumnDragPreview) return null;
158
+
159
+ return renderColumnDragPreview(data, {
160
+ state,
161
+ data,
162
+ index,
163
+ isDraggable: data.isDraggable !== false,
164
+ });
165
+ }, [state, data, index, renderColumnDragPreview]);
166
+
167
+
168
+ const containerClassName = classNames(
169
+ withPrefix("column-outer"),
170
+ columnWrapperClassName?.(data),
171
+ );
172
+
173
+ const columnWrapperContent = (children: React.ReactNode) =>
174
+ renderColumnWrapper ? (
175
+ renderColumnWrapper(data, {
176
+ children,
177
+ className: containerClassName,
178
+ style: columnWrapperStyle?.(data),
179
+ ref: outerFullHeightRef,
180
+ })
181
+ ) : (
182
+ <div
183
+ className={containerClassName}
184
+ ref={outerFullHeightRef}
185
+ style={columnWrapperStyle?.(data)}
186
+ >
187
+ {children}
188
+ </div>
189
+ );
190
+
191
+
192
+ const dragStyle = isHidden
193
+ ? { display: "none" as const }
194
+ : isDragging
195
+ ? { opacity: 0.4 }
196
+ : undefined;
197
+
198
+
199
+ return (
200
+ <>
201
+ {closestEdge === "left" && columnIndicator}
202
+
203
+ <div onClick={(e) => onColumnClick?.(e, data)} style={dragStyle}>
204
+ {columnWrapperContent(
205
+ <div
206
+ className={classNames(
207
+ withPrefix("column"),
208
+ columnClassName?.(data),
209
+ )}
210
+ ref={innerRef}
211
+ style={columnStyle?.(data)}
212
+ >
213
+ <div className={withPrefix("column-wrapper")}>
214
+ <ColumnHeader
215
+ renderColumnHeader={renderColumnHeader}
216
+ columnHeaderStyle={columnHeaderStyle}
217
+ columnHeaderClassName={columnHeaderClassName?.(data)}
218
+ data={data}
219
+ ref={headerRef}
220
+ />
221
+ <ColumnContent
222
+ items={items}
223
+ column={data}
224
+ columnListContentClassName={columnListContentClassName?.(data)}
225
+ cardOverHeight={
226
+ cardOverShadowCount ? (state as any).dragging.height : null
227
+ }
228
+ cardOverShadowCount={cardOverShadowCount}
229
+ {...rest}
230
+ />
231
+ {renderColumnFooter?.(data)}
232
+ </div>
233
+ </div>,
234
+ )}
235
+
236
+ {state.type === "preview" &&
237
+ previewContent &&
238
+ createPortal(previewContent, state.container)}
239
+ </div>
240
+
241
+ {closestEdge === "right" && columnIndicator}
242
+ </>
243
+ );
244
+ };
245
+
246
+ export default Column;
@@ -0,0 +1,44 @@
1
+ @use "./../../global/assets/styles/abstracts/variables" as *;
2
+
3
+ .#{$prefix}-column-outer {
4
+ min-width: 264px;
5
+ max-width: 264px;
6
+ height: 100%; // Changed from max-height to height for proper cascading
7
+ display: flex;
8
+ flex-direction: column;
9
+ transition: all 0.1s ease;
10
+ -webkit-transition: all 0.1s ease;
11
+ -moz-transition: all 0.1s ease;
12
+ -ms-transition: all 0.1s ease;
13
+ -o-transition: all 0.1s ease;
14
+
15
+ .#{$prefix}-column {
16
+ display: flex;
17
+ flex-direction: column;
18
+ gap: 10px;
19
+ padding: 10px;
20
+ border-radius: 10px;
21
+ background-color: #f0f0f0;
22
+ position: relative;
23
+ overflow: hidden;
24
+
25
+ &-wrapper {
26
+ display: flex;
27
+ flex-direction: column;
28
+ flex: 1;
29
+ gap: 16px;
30
+ max-height: 100%;
31
+ }
32
+ }
33
+ }
34
+
35
+ .#{$prefix}-column-shadow-container {
36
+ position: relative;
37
+ flex-shrink: 0;
38
+ }
39
+
40
+ .#{$prefix}-column-shadow {
41
+ border-radius: 10px;
42
+ background-color: #ffffffb7;
43
+ border: 1px solid var(--Schemes-Outline-Variant, #e8ecf5);
44
+ }
@@ -0,0 +1 @@
1
+ @forward "./Column";
@@ -0,0 +1 @@
1
+ export { default as Column } from "./Column";
@@ -0,0 +1,18 @@
1
+ import { useKanbanContext } from "@/context/KanbanContext";
2
+ import { withPrefix } from "@/utils/getPrefix";
3
+ import React from "react";
4
+
5
+ interface Props {
6
+ renderColumnAdder: () => React.ReactNode;
7
+ }
8
+
9
+ const ColumnAdder = ({ renderColumnAdder }: Props) => {
10
+ const { allowColumnAdder = true } = useKanbanContext();
11
+ if (!allowColumnAdder) return null;
12
+
13
+ return (
14
+ <div className={withPrefix("column-adder")}>{renderColumnAdder?.()}</div>
15
+ );
16
+ };
17
+
18
+ export default ColumnAdder;
File without changes
@@ -0,0 +1 @@
1
+ @forward "./ColumnAdder";
@@ -0,0 +1 @@
1
+ export { default } from "./ColumnAdder";
@@ -0,0 +1,238 @@
1
+ import { withPrefix } from "@/utils/getPrefix";
2
+ import React, { forwardRef } from "react";
3
+ import {
4
+ BoardItem,
5
+ BoardProps,
6
+ ConfigMap,
7
+ DndState,
8
+ ScrollEvent,
9
+ } from "../types";
10
+ import classNames from "classnames";
11
+ import { VList } from "virtua";
12
+ import GenericItem from "../GenericItem";
13
+ import { handleScroll } from "@/utils/scroll";
14
+ import { checkIfSkeletonIsVisible } from "@/utils/infinite-scroll";
15
+ import { useKanbanContext } from "@/context/KanbanContext";
16
+
17
+ interface ListProps {
18
+ column: BoardItem;
19
+ items: BoardItem[];
20
+ configMap: ConfigMap;
21
+ cardWrapperStyle?: (
22
+ card: BoardItem,
23
+ column: BoardItem
24
+ ) => React.CSSProperties;
25
+ cardWrapperClassName?: string;
26
+ cardsGap?: number;
27
+ cardOverHeight?: number;
28
+ cardOverShadowCount?: number;
29
+ renderCardDragIndicator?: (card: BoardItem, info: any) => React.ReactNode;
30
+ renderCardDragPreview?: (card: BoardItem, info: any) => React.ReactNode;
31
+ onCardDndStateChange?: (info: DndState) => void;
32
+ renderSkeletonCard?: BoardProps["renderSkeletonCard"];
33
+ onScroll?: (e: React.UIEvent<HTMLDivElement>) => void;
34
+ onCardClick?: (e: React.MouseEvent<HTMLDivElement>, card: BoardItem) => void;
35
+ renderListFooter?: (column: BoardItem) => React.ReactNode;
36
+ renderGap?: (column: BoardItem) => React.ReactNode;
37
+ }
38
+
39
+ const renderGenericItem = (
40
+ items: BoardItem[],
41
+ index: number,
42
+ column: BoardItem,
43
+ configMap: ConfigMap,
44
+ cardOverShadowCount: number,
45
+ renderListFooter: (column: BoardItem) => React.ReactNode,
46
+ props: any,
47
+ count: number
48
+ ) => {
49
+ return (
50
+ <GenericItem
51
+ key={index}
52
+ index={index}
53
+ options={{
54
+ data: items[index],
55
+ column,
56
+ configMap,
57
+ isSkeleton: index >= items.length,
58
+ renderListFooter,
59
+ isShadow:
60
+ cardOverShadowCount && index === count - (renderListFooter ? 2 : 1),
61
+ isListFooter:
62
+ renderListFooter && index === count - (renderListFooter ? 1 : 0),
63
+ ...props,
64
+ }}
65
+ />
66
+ );
67
+ };
68
+
69
+ const VirtualizedList = ({
70
+ column,
71
+ items,
72
+ configMap,
73
+ onScroll,
74
+ cardOverShadowCount,
75
+ renderListFooter,
76
+ ...props
77
+ }: ListProps) => {
78
+ const count =
79
+ column?.totalChildrenCount +
80
+ cardOverShadowCount +
81
+ (renderListFooter ? 1 : 0);
82
+
83
+ return (
84
+ <VList
85
+ count={count}
86
+ onScroll={onScroll}
87
+ className={withPrefix("column-content-list")}
88
+ >
89
+ {(index: number) =>
90
+ renderGenericItem(
91
+ items,
92
+ index,
93
+ column,
94
+ configMap,
95
+ cardOverShadowCount,
96
+ renderListFooter,
97
+ props,
98
+ count
99
+ )
100
+ }
101
+ </VList>
102
+ );
103
+ };
104
+
105
+ const NormalList = ({
106
+ column,
107
+ items,
108
+ configMap,
109
+ onScroll,
110
+ cardOverShadowCount,
111
+ renderListFooter,
112
+ ...props
113
+ }: ListProps) => {
114
+ const count =
115
+ column?.totalChildrenCount +
116
+ cardOverShadowCount +
117
+ (renderListFooter ? 1 : 0);
118
+
119
+ return (
120
+ <div className={withPrefix("column-content-list")} onScroll={onScroll}>
121
+ {Array.from(
122
+ {
123
+ length: count,
124
+ },
125
+ (_, index) =>
126
+ renderGenericItem(
127
+ items,
128
+ index,
129
+ column,
130
+ configMap,
131
+ cardOverShadowCount,
132
+ renderListFooter,
133
+ props,
134
+ count
135
+ )
136
+ )}
137
+ </div>
138
+ );
139
+ };
140
+
141
+ interface Props {
142
+ items: BoardItem[];
143
+ column: BoardItem;
144
+ columnListContentStyle?: (column: BoardItem) => React.CSSProperties;
145
+ columnListContentClassName?: string;
146
+ configMap: ConfigMap;
147
+ renderSkeletonCard?: BoardProps["renderSkeletonCard"];
148
+ cardWrapperStyle?: (
149
+ card: BoardItem,
150
+ column: BoardItem
151
+ ) => React.CSSProperties;
152
+ cardWrapperClassName?: string;
153
+ onScroll?: (e: ScrollEvent, column: BoardItem) => void;
154
+ onCardClick?: (e: React.MouseEvent<HTMLDivElement>, card: BoardItem) => void;
155
+ loadMore?: (columnId: string) => void;
156
+ cardOverShadowCount?: number;
157
+ cardOverHeight?: number;
158
+ onCardDndStateChange?: (info: DndState) => void;
159
+ renderCardDragIndicator?: (card: BoardItem, info: any) => React.ReactNode;
160
+ renderCardDragPreview?: (card: BoardItem, info: any) => React.ReactNode;
161
+ renderListFooter?: (column: BoardItem) => React.ReactNode;
162
+ renderGap?: (column: BoardItem) => React.ReactNode;
163
+ }
164
+
165
+ const ColumnContent = forwardRef<HTMLDivElement, Props>((props, ref) => {
166
+ const {
167
+ items,
168
+ column,
169
+ configMap,
170
+ columnListContentStyle,
171
+ columnListContentClassName,
172
+ cardWrapperStyle,
173
+ renderSkeletonCard,
174
+ cardWrapperClassName,
175
+ onCardClick,
176
+ loadMore,
177
+ cardOverShadowCount,
178
+ cardOverHeight,
179
+ onCardDndStateChange,
180
+ renderCardDragIndicator,
181
+ renderCardDragPreview,
182
+ renderListFooter,
183
+ renderGap,
184
+ } = props;
185
+ const {
186
+ virtualization = true,
187
+ cardsGap,
188
+ allowListFooter,
189
+ } = useKanbanContext();
190
+ const containerClassName = classNames(
191
+ withPrefix("column-content"),
192
+ columnListContentClassName
193
+ );
194
+
195
+ const onScroll = (e: ScrollEvent, column: BoardItem) => {
196
+ const isSkeletonVisible = checkIfSkeletonIsVisible({
197
+ columnId: column?.id,
198
+ });
199
+ if (isSkeletonVisible) loadMore?.(column?.id);
200
+ props?.onScroll?.(e, column);
201
+ };
202
+
203
+ const List = virtualization ? VirtualizedList : NormalList;
204
+
205
+ return (
206
+ <div
207
+ ref={ref}
208
+ className={containerClassName}
209
+ style={columnListContentStyle?.(column)}
210
+ >
211
+ <List
212
+ column={column}
213
+ items={items}
214
+ configMap={configMap}
215
+ cardWrapperStyle={cardWrapperStyle}
216
+ cardWrapperClassName={cardWrapperClassName}
217
+ cardsGap={cardsGap}
218
+ renderSkeletonCard={renderSkeletonCard}
219
+ onScroll={(e) => handleScroll(e, virtualization, onScroll, column)}
220
+ onCardClick={onCardClick}
221
+ cardOverShadowCount={cardOverShadowCount}
222
+ onCardDndStateChange={onCardDndStateChange}
223
+ renderCardDragIndicator={renderCardDragIndicator}
224
+ renderCardDragPreview={renderCardDragPreview}
225
+ cardOverHeight={cardOverHeight}
226
+ renderGap={renderGap}
227
+ renderListFooter={
228
+ (allowListFooter !== undefined && allowListFooter?.(column)) ||
229
+ allowListFooter === undefined
230
+ ? renderListFooter
231
+ : null
232
+ }
233
+ />
234
+ </div>
235
+ );
236
+ });
237
+
238
+ export default ColumnContent;
@@ -0,0 +1,23 @@
1
+ @use "../../global/assets/styles/abstracts/variables" as *;
2
+
3
+ .#{$prefix}-column-content {
4
+ flex: 1;
5
+ position: relative;
6
+ height: 0; // This forces the flex item to shrink and become scrollable
7
+ min-height: 0; // Ensure flex child can shrink below content size
8
+
9
+ &-list {
10
+ height: 100%;
11
+ overflow-y: auto; // Enable vertical scrolling
12
+ overflow-x: hidden;
13
+ contain: none !important;
14
+ scrollbar-width: thin; /* For Firefox */
15
+ scrollbar-color: rgba(0, 0, 0, 0.3) transparent; /* For Firefox - thumb and track color */
16
+ transition: scrollbar-color 0.3s ease;
17
+
18
+ // Show scrollbar on hover for better UX
19
+ &:hover {
20
+ scrollbar-color: rgba(0, 0, 0, 0.3) transparent;
21
+ }
22
+ }
23
+ }
@@ -0,0 +1 @@
1
+ @forward "./ColumnContent";
@@ -0,0 +1 @@
1
+ export { default } from "./ColumnContent";
@@ -0,0 +1,43 @@
1
+ import { withPrefix } from "@/utils/getPrefix";
2
+ import React, { forwardRef } from "react";
3
+ import { BoardItem } from "../types";
4
+ import classNames from "classnames";
5
+
6
+ interface Props {
7
+ renderColumnHeader?: (column: BoardItem) => React.ReactNode;
8
+ columnHeaderStyle?: (column: BoardItem) => React.CSSProperties;
9
+ columnHeaderClassName?: string;
10
+ data: BoardItem;
11
+ }
12
+
13
+ const ColumnHeader = forwardRef<HTMLDivElement, Props>((props, ref) => {
14
+ const {
15
+ renderColumnHeader,
16
+ columnHeaderStyle,
17
+ columnHeaderClassName = "",
18
+ data,
19
+ } = props;
20
+
21
+ const headerClassName = classNames(
22
+ withPrefix("column-header"),
23
+ columnHeaderClassName,
24
+ );
25
+
26
+ if (renderColumnHeader)
27
+ return <div ref={ref}>{renderColumnHeader(data)}</div>;
28
+
29
+ return (
30
+ <header
31
+ ref={ref}
32
+ className={headerClassName}
33
+ style={columnHeaderStyle?.(data)}
34
+ >
35
+ <div className={withPrefix("column-header-left")}>{data?.title}</div>
36
+ <div className={withPrefix("column-header-right")}>
37
+ {data?.totalItemsCount || data?.totalChildrenCount || 0}
38
+ </div>
39
+ </header>
40
+ );
41
+ });
42
+
43
+ export default ColumnHeader;
@@ -0,0 +1,26 @@
1
+ @use "./../../global/assets/styles/abstracts/variables" as *;
2
+
3
+ .#{$prefix}-column-header {
4
+ display: flex;
5
+ justify-content: space-between;
6
+ align-items: center;
7
+ border-radius: 10px;
8
+ height: 24px;
9
+ margin-bottom: 10px;
10
+ background-color: #f0f0f0;
11
+
12
+ &-left {
13
+ font-size: 18px;
14
+ font-weight: 600;
15
+ color: #000;
16
+ }
17
+
18
+ &-right {
19
+ font-size: 15px;
20
+ background-color: #37352f14;
21
+ color: #37352f;
22
+ padding: 5px 10px;
23
+ border-radius: 5px;
24
+ font-weight: 500;
25
+ }
26
+ }
@@ -0,0 +1 @@
1
+ @forward "./ColumnHeader";
@@ -0,0 +1 @@
1
+ export { default } from "./ColumnHeader";
@@ -0,0 +1,9 @@
1
+ import React from "react";
2
+ import { CardRenderProps } from "../types";
3
+ import { withPrefix } from "@/utils/getPrefix";
4
+
5
+ const DefaultCard = (props: CardRenderProps) => {
6
+ return <div className={withPrefix("default-card")}>{props?.data?.title}</div>;
7
+ };
8
+
9
+ export default DefaultCard;
@@ -0,0 +1,14 @@
1
+ @use "../../global/assets/styles/abstracts/variables" as *;
2
+
3
+ .#{$prefix}-default-card {
4
+ background-color: #fff;
5
+ padding: 10px;
6
+ border-radius: 8px;
7
+ border: 1px solid #ccc;
8
+ box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
9
+ cursor: pointer;
10
+ -webkit-border-radius: 8px;
11
+ -moz-border-radius: 8px;
12
+ -ms-border-radius: 8px;
13
+ -o-border-radius: 8px;
14
+ }
@@ -0,0 +1 @@
1
+ @forward "./DefaultCard";
@@ -0,0 +1 @@
1
+ export { default } from "./DefaultCard";