@rebasepro/ui 0.17.3 → 0.18.1

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 (127) hide show
  1. package/README.md +4 -0
  2. package/dist/components/MultiSelect.d.ts +10 -0
  3. package/dist/index.es.js +2 -1
  4. package/dist/index.es.js.map +1 -1
  5. package/package.json +32 -23
  6. package/src/components/Alert.tsx +0 -118
  7. package/src/components/Autocomplete.tsx +0 -93
  8. package/src/components/Avatar.tsx +0 -73
  9. package/src/components/Badge.tsx +0 -44
  10. package/src/components/BooleanSwitch.tsx +0 -116
  11. package/src/components/BooleanSwitchWithLabel.tsx +0 -120
  12. package/src/components/Button.tsx +0 -110
  13. package/src/components/Card.tsx +0 -43
  14. package/src/components/CenteredView.tsx +0 -35
  15. package/src/components/Checkbox.tsx +0 -129
  16. package/src/components/Chip.tsx +0 -131
  17. package/src/components/CircularProgress.tsx +0 -53
  18. package/src/components/CircularProgressCenter.tsx +0 -27
  19. package/src/components/Collapse.tsx +0 -66
  20. package/src/components/ColorPicker.tsx +0 -140
  21. package/src/components/Container.tsx +0 -51
  22. package/src/components/DateTimeField.tsx +0 -363
  23. package/src/components/DebouncedTextField.tsx +0 -76
  24. package/src/components/Dialog.tsx +0 -159
  25. package/src/components/DialogActions.tsx +0 -29
  26. package/src/components/DialogContent.tsx +0 -27
  27. package/src/components/DialogTitle.tsx +0 -41
  28. package/src/components/ErrorBoundary.tsx +0 -236
  29. package/src/components/ExpandablePanel.tsx +0 -130
  30. package/src/components/FileUpload.tsx +0 -103
  31. package/src/components/FilterChip.tsx +0 -89
  32. package/src/components/IconButton.tsx +0 -101
  33. package/src/components/InfoLabel.tsx +0 -23
  34. package/src/components/InputLabel.tsx +0 -40
  35. package/src/components/Label.tsx +0 -32
  36. package/src/components/LoadingButton.tsx +0 -32
  37. package/src/components/Markdown.tsx +0 -55
  38. package/src/components/Menu.tsx +0 -114
  39. package/src/components/Menubar.tsx +0 -355
  40. package/src/components/MultiSelect.tsx +0 -433
  41. package/src/components/Paper.tsx +0 -23
  42. package/src/components/Popover.tsx +0 -162
  43. package/src/components/RadioGroup.tsx +0 -74
  44. package/src/components/ResizablePanels.tsx +0 -189
  45. package/src/components/SearchBar.tsx +0 -136
  46. package/src/components/Select.tsx +0 -326
  47. package/src/components/Separator.tsx +0 -28
  48. package/src/components/Sheet.tsx +0 -135
  49. package/src/components/Skeleton.tsx +0 -54
  50. package/src/components/Slider.tsx +0 -110
  51. package/src/components/Table.tsx +0 -178
  52. package/src/components/Tabs.tsx +0 -185
  53. package/src/components/TextField.tsx +0 -270
  54. package/src/components/TextareaAutosize.tsx +0 -368
  55. package/src/components/ToggleButtonGroup.tsx +0 -69
  56. package/src/components/Tooltip.tsx +0 -153
  57. package/src/components/Typography.tsx +0 -132
  58. package/src/components/VirtualTable/VirtualTable.performance.test.tsx +0 -90
  59. package/src/components/VirtualTable/VirtualTable.tsx +0 -700
  60. package/src/components/VirtualTable/VirtualTableCell.tsx +0 -59
  61. package/src/components/VirtualTable/VirtualTableHeader.tsx +0 -327
  62. package/src/components/VirtualTable/VirtualTableHeaderRow.tsx +0 -250
  63. package/src/components/VirtualTable/VirtualTableProps.tsx +0 -339
  64. package/src/components/VirtualTable/VirtualTableRow.tsx +0 -51
  65. package/src/components/VirtualTable/fields/VirtualTableDateField.tsx +0 -44
  66. package/src/components/VirtualTable/fields/VirtualTableInput.tsx +0 -89
  67. package/src/components/VirtualTable/fields/VirtualTableNumberInput.tsx +0 -71
  68. package/src/components/VirtualTable/fields/VirtualTableSelect.tsx +0 -107
  69. package/src/components/VirtualTable/fields/VirtualTableSwitch.tsx +0 -28
  70. package/src/components/VirtualTable/index.tsx +0 -10
  71. package/src/components/VirtualTable/selection/SelectionContext.tsx +0 -36
  72. package/src/components/VirtualTable/selection/SelectionStore.ts +0 -54
  73. package/src/components/VirtualTable/types.tsx +0 -47
  74. package/src/components/common/SelectInputLabel.tsx +0 -23
  75. package/src/components/index.tsx +0 -62
  76. package/src/hooks/PortalContainerContext.tsx +0 -50
  77. package/src/hooks/index.ts +0 -7
  78. package/src/hooks/useDebounceCallback.tsx +0 -21
  79. package/src/hooks/useDebounceValue.tsx +0 -20
  80. package/src/hooks/useDebouncedCallback.ts +0 -39
  81. package/src/hooks/useInjectStyles.tsx +0 -31
  82. package/src/hooks/useOutsideAlerter.tsx +0 -46
  83. package/src/icons/GitHubIcon.tsx +0 -21
  84. package/src/icons/HandleIcon.tsx +0 -23
  85. package/src/icons/Icon.tsx +0 -33
  86. package/src/icons/LucideIconByName.tsx +0 -117
  87. package/src/icons/cool_icon_keys.ts +0 -12
  88. package/src/icons/icon_keys.ts +0 -1936
  89. package/src/icons/index.ts +0 -179
  90. package/src/index.css +0 -169
  91. package/src/index.ts +0 -47
  92. package/src/scripts/fixIconSizes.cjs +0 -92
  93. package/src/scripts/fixIconSizesToConst.cjs +0 -106
  94. package/src/scripts/generateIconKeys.ts +0 -41
  95. package/src/scripts/generateIcons.ts +0 -4
  96. package/src/scripts/saveIconFiles.ts +0 -89
  97. package/src/styles.ts +0 -141
  98. package/src/theme.css +0 -168
  99. package/src/util/chip_colors.ts +0 -242
  100. package/src/util/cls.ts +0 -8
  101. package/src/util/debounce.ts +0 -28
  102. package/src/util/hash.ts +0 -11
  103. package/src/util/index.ts +0 -4
  104. package/src/util/key_to_icon_component.ts +0 -11
  105. package/src/util/lazy_chunk.ts +0 -101
  106. package/src/views/CardView.tsx +0 -281
  107. package/src/views/CollectionView/CollectionCardView.tsx +0 -265
  108. package/src/views/CollectionView/CollectionKanbanView.tsx +0 -246
  109. package/src/views/CollectionView/CollectionListView.tsx +0 -240
  110. package/src/views/CollectionView/CollectionTableView.tsx +0 -229
  111. package/src/views/CollectionView/CollectionView.tsx +0 -450
  112. package/src/views/CollectionView/CollectionViewToolbar.tsx +0 -242
  113. package/src/views/CollectionView/CollectionViewTypes.ts +0 -181
  114. package/src/views/CollectionView/DefaultCellRenderer.tsx +0 -404
  115. package/src/views/CollectionView/index.ts +0 -39
  116. package/src/views/CollectionView/resolveTitleProperty.ts +0 -52
  117. package/src/views/CollectionView/utils.ts +0 -14
  118. package/src/views/Kanban/Board.tsx +0 -384
  119. package/src/views/Kanban/BoardColumn.tsx +0 -138
  120. package/src/views/Kanban/BoardColumnTitle.tsx +0 -47
  121. package/src/views/Kanban/BoardSortableList.tsx +0 -182
  122. package/src/views/Kanban/board_types.ts +0 -80
  123. package/src/views/Kanban/index.tsx +0 -5
  124. package/src/views/Kanban/placement.ts +0 -62
  125. package/src/views/KanbanView.tsx +0 -32
  126. package/src/views/ListView.tsx +0 -296
  127. package/src/views/index.ts +0 -5
@@ -1,384 +0,0 @@
1
- import React, { useEffect, useRef, useState } from "react";
2
- import { createPortal } from "react-dom";
3
- import {
4
- closestCorners,
5
- DndContext,
6
- DragEndEvent,
7
- DragOverEvent,
8
- DragOverlay,
9
- DragStartEvent,
10
- PointerSensor,
11
- useSensor,
12
- useSensors
13
- } from "@dnd-kit/core";
14
- import { arrayMove, SortableContext } from "@dnd-kit/sortable";
15
- import { BoardColumn } from "./BoardColumn";
16
- import { placeDroppedCard } from "./placement";
17
- import { BoardItem, BoardItemMap, BoardProps } from "./board_types";
18
- import { cls } from "../../util";
19
-
20
- export function Board<T, COLUMN extends string>({
21
- data,
22
- columns: columnsProp,
23
- columnLabels,
24
- columnColors,
25
- className,
26
- assignColumn,
27
- allowColumnReorder = false,
28
- onColumnReorder,
29
- onItemsReorder,
30
- ItemComponent,
31
- columnLoadingState,
32
- onLoadMoreColumn,
33
- onAddItemToColumn,
34
- AddColumnComponent
35
- }: BoardProps<T, COLUMN>) {
36
-
37
- const [activeItem, setActiveItem] = useState<BoardItem<T> | null>(null);
38
- const [isDragging, setIsDragging] = useState(false);
39
- const [dragOverColumnId, setDragOverColumnId] = useState<string | null>(null);
40
-
41
- /**
42
- * Which column the card was picked up from.
43
- *
44
- * `handleDragOver` moves the card between columns in `itemMapState` while
45
- * the pointer is still down — that is what makes the gap open up under the
46
- * cursor. So by the time the drop is handled, looking the card up by id
47
- * finds it in its *destination*, and the board was reporting the move as
48
- * source === target: a cross-column drop looked like a plain reorder and
49
- * the column property was never written. The card snapped back on the next
50
- * fetch.
51
- */
52
- const dragSourceColumnRef = useRef<COLUMN | null>(null);
53
-
54
- const [itemMapState, setItemMapState] = useState<BoardItemMap<T>>(() => {
55
- const dataColumnMap: Record<string, COLUMN> = data.reduce((prev, item: BoardItem<T>) => ({
56
- ...prev,
57
- [item.id]: assignColumn(item)
58
- }), {});
59
- return columnsProp.reduce(
60
- (previous: BoardItemMap<T>, column: COLUMN) => ({
61
- ...previous,
62
- [column]: data.filter((item: BoardItem<T>) => dataColumnMap[item.id] === column)
63
- }),
64
- {} as BoardItemMap<T>
65
- );
66
- });
67
-
68
- const sensors = useSensors(
69
- useSensor(PointerSensor, {
70
- activationConstraint: {
71
- distance: 5
72
- }
73
- })
74
- );
75
-
76
- useEffect(() => {
77
- if (isDragging) return;
78
-
79
- const dataColumnMap: Record<string, COLUMN> = data.reduce((prev, item) => ({
80
- ...prev,
81
- [item.id]: assignColumn(item)
82
- }), {});
83
-
84
- const newItemMap = columnsProp.reduce(
85
- (previous: BoardItemMap<T>, column: COLUMN) => ({
86
- ...previous,
87
- [column]: data.filter((item: BoardItem<T>) => dataColumnMap[item.id] === column)
88
- }),
89
- {} as BoardItemMap<T>
90
- );
91
-
92
- setItemMapState(prevMap => {
93
- let changed = false;
94
-
95
- for (const col of columnsProp) {
96
- const prevItems = prevMap[col] ?? [];
97
- const newItems = newItemMap[col] ?? [];
98
-
99
- if (prevItems.length !== newItems.length) {
100
- changed = true;
101
- continue;
102
- }
103
- for (let i = 0; i < prevItems.length; i++) {
104
- if (prevItems[i].id !== newItems[i].id || prevItems[i].data !== newItems[i].data) {
105
- changed = true;
106
- break;
107
- }
108
- }
109
- }
110
-
111
- if (!changed) {
112
- return prevMap;
113
- }
114
-
115
- const updated: BoardItemMap<T> = {};
116
- for (const col of columnsProp) {
117
- const prevItems = prevMap[col] ?? [];
118
- const newItems = newItemMap[col] ?? [];
119
-
120
- const prevById = new Map<string, BoardItem<T>>();
121
- for (const item of prevItems) {
122
- prevById.set(item.id, item);
123
- }
124
-
125
- updated[col] = newItems.map(newItem => {
126
- const prev = prevById.get(newItem.id);
127
- if (prev && prev.data === newItem.data) {
128
- return prev;
129
- }
130
- return newItem;
131
- });
132
- }
133
- return updated;
134
- });
135
- }, [data, columnsProp, assignColumn]);
136
-
137
- const findColumnByItemId = (id: string): string | undefined => {
138
- return Object.keys(itemMapState).find(col => itemMapState[col]?.some(i => i.id === id));
139
- };
140
-
141
- const handleDragStart = (event: DragStartEvent) => {
142
- setIsDragging(true);
143
- setDragOverColumnId(null);
144
- const { active } = event;
145
-
146
- if (active.data.current?.type === "ITEM") {
147
- const columnId = findColumnByItemId(active.id as string);
148
- dragSourceColumnRef.current = (columnId as COLUMN | undefined) ?? null;
149
- if (columnId) {
150
- const item = itemMapState[columnId]?.find(i => i.id === active.id);
151
- setActiveItem(item || null);
152
- }
153
- }
154
- };
155
-
156
- const handleDragOver = (event: DragOverEvent) => {
157
- const {
158
- active,
159
- over
160
- } = event;
161
-
162
- if (!over) {
163
- setDragOverColumnId(null);
164
- return;
165
- }
166
-
167
- let currentHoveredColumnId: string | null = null;
168
- const overId = over.id as string;
169
- const overDataType = over.data.current?.type as string | undefined;
170
-
171
- if (overDataType === "ITEM-LIST" || overDataType === "COLUMN") {
172
- currentHoveredColumnId = overId;
173
- } else if (overDataType === "ITEM") {
174
- currentHoveredColumnId = findColumnByItemId(overId) || null;
175
- } else if (columnsProp.includes(overId as COLUMN)) {
176
- currentHoveredColumnId = overId;
177
- }
178
-
179
- setDragOverColumnId(currentHoveredColumnId);
180
-
181
- if (active.data.current?.type !== "ITEM") {
182
- return;
183
- }
184
-
185
- const activeId = active.id as string;
186
- const activeItemColumn = findColumnByItemId(activeId);
187
- let overColumnForMove = findColumnByItemId(overId);
188
-
189
- if (!overColumnForMove && overDataType === "ITEM-LIST") {
190
- overColumnForMove = overId;
191
- }
192
- if (!overColumnForMove && columnsProp.includes(overId as COLUMN)) {
193
- overColumnForMove = overId;
194
- }
195
-
196
- if (!activeItemColumn || !overColumnForMove) return;
197
- if (activeItemColumn === overColumnForMove) return;
198
-
199
- if (itemMapState[overColumnForMove]?.some(i => i.id === activeId)) {
200
- return;
201
- }
202
-
203
- setItemMapState(currentMap => {
204
- const activeItems = [...(currentMap[activeItemColumn] || [])];
205
- const overItems = [...(currentMap[overColumnForMove!] || [])];
206
- const activeIndex = activeItems.findIndex(i => i.id === activeId);
207
-
208
- if (activeIndex === -1) return currentMap;
209
-
210
- let overIndex;
211
- if (overDataType === "ITEM-LIST" || (columnsProp.includes(overId as COLUMN) && !findColumnByItemId(overId))) {
212
- overIndex = overItems.length;
213
- } else {
214
- overIndex = overItems.findIndex(i => i.id === overId);
215
- if (overIndex !== -1) {
216
- const activeTop = active.rect.current.translated?.top ?? 0;
217
- const activeHeight = active.rect.current.translated?.height ?? 0;
218
- const activeCenter = activeTop + activeHeight / 2;
219
-
220
- const overTop = over?.rect.top ?? 0;
221
- const overHeight = over?.rect.height ?? 0;
222
- const overCenter = overTop + overHeight / 2;
223
-
224
- const isBelowOverItem = activeCenter > overCenter;
225
-
226
- const modifier = isBelowOverItem ? 1 : 0;
227
- overIndex = overIndex >= 0 ? overIndex + modifier : overItems.length;
228
- } else {
229
- overIndex = overItems.length;
230
- }
231
- }
232
-
233
- const newItemMap = { ...currentMap };
234
- const [moved] = activeItems.splice(activeIndex, 1);
235
- overItems.splice(overIndex, 0, moved);
236
- newItemMap[activeItemColumn] = activeItems;
237
- newItemMap[overColumnForMove!] = overItems;
238
- return newItemMap;
239
- });
240
- };
241
-
242
- // Escape, or a drop outside the board. `handleDragOver` may already have
243
- // moved the card between columns, so the next `data` effect has to be
244
- // allowed to put it back.
245
- const handleDragCancel = () => {
246
- setIsDragging(false);
247
- setActiveItem(null);
248
- setDragOverColumnId(null);
249
- dragSourceColumnRef.current = null;
250
- };
251
-
252
- const handleDragEnd = (event: DragEndEvent) => {
253
- const {
254
- active,
255
- over
256
- } = event;
257
-
258
- const sourceColumn = dragSourceColumnRef.current;
259
-
260
- setIsDragging(false);
261
- setActiveItem(null);
262
- setDragOverColumnId(null);
263
- dragSourceColumnRef.current = null;
264
-
265
- if (!over) return;
266
-
267
- const activeId = active.id as string;
268
- const overId = over.id as string;
269
-
270
- if (active.data.current?.type === "COLUMN") {
271
- if (activeId !== overId) {
272
- const oldIndex = columnsProp.indexOf(activeId as COLUMN);
273
- const newIndex = columnsProp.indexOf(overId as COLUMN);
274
- if (oldIndex !== -1 && newIndex !== -1) {
275
- const reordered = arrayMove(columnsProp, oldIndex, newIndex);
276
- onColumnReorder?.(reordered);
277
- }
278
- }
279
- return;
280
- }
281
-
282
- // Where the card sits right now — `handleDragOver` has already put it in
283
- // the column being hovered, so this is the destination, not the origin.
284
- const currentCol = findColumnByItemId(activeId) as COLUMN | undefined;
285
- let targetCol = findColumnByItemId(overId) as COLUMN | undefined;
286
-
287
- if (!targetCol) {
288
- const overDataType = over.data.current?.type;
289
- if (overDataType === "ITEM-LIST" || columnsProp.includes(overId as COLUMN)) {
290
- targetCol = overId as COLUMN;
291
- }
292
- }
293
- targetCol = targetCol ?? currentCol;
294
-
295
- if (!currentCol || !targetCol) return;
296
-
297
- const targetItems = itemMapState[targetCol] || [];
298
- const movedItem = (itemMapState[currentCol] || []).find(i => i.id === activeId);
299
- if (!movedItem) return;
300
-
301
- const finalTargetItems = placeDroppedCard({
302
- targetItems,
303
- movedItem,
304
- overId,
305
- changedColumn: (sourceColumn ?? currentCol) !== targetCol
306
- });
307
-
308
- onItemsReorder?.(finalTargetItems, {
309
- itemId: activeId,
310
- // The column the pointer went down in. `currentCol` would report a
311
- // cross-column move as a same-column reorder.
312
- sourceColumn: (sourceColumn ?? currentCol),
313
- targetColumn: targetCol
314
- });
315
- };
316
-
317
- return (
318
- <DndContext
319
- sensors={sensors}
320
- // `rectIntersection`, the default, only reports a target while the
321
- // dragged rect physically overlaps it, and prefers whichever
322
- // overlap is largest — on a board of tall columns that means a card
323
- // held over a gap reports nothing, and one held near a column edge
324
- // reports the neighbour. `closestCorners` is the sortable-list
325
- // recommendation and is what makes the drop land where it looks
326
- // like it will.
327
- collisionDetection={closestCorners}
328
- onDragStart={handleDragStart}
329
- onDragOver={handleDragOver}
330
- onDragEnd={handleDragEnd}
331
- onDragCancel={handleDragCancel}
332
- >
333
- <div className={cls("flex flex-row h-full w-full overflow-x-auto p-4 select-none items-start", className)}>
334
- <SortableContext items={columnsProp}>
335
- {columnsProp.map((col, index) => {
336
- const colItems = itemMapState[col] || [];
337
- const loadingState = columnLoadingState?.[col];
338
- return (
339
- <BoardColumn
340
- key={String(col)}
341
- id={String(col)}
342
- title={columnLabels?.[col] ?? String(col)}
343
- items={colItems}
344
- index={index}
345
- ItemComponent={ItemComponent}
346
- isDragging={isDragging}
347
- isDragOverColumn={dragOverColumnId === String(col)}
348
- allowReorder={allowColumnReorder}
349
- loading={loadingState?.loading}
350
- hasMore={loadingState?.hasMore}
351
- error={loadingState?.error}
352
- totalCount={loadingState?.totalCount}
353
- color={columnColors?.[col]}
354
- onLoadMore={onLoadMoreColumn ? () => onLoadMoreColumn(col) : undefined}
355
- onAddItem={onAddItemToColumn ? () => onAddItemToColumn(col) : undefined}
356
- />
357
- );
358
- })}
359
- </SortableContext>
360
- {AddColumnComponent}
361
- </div>
362
-
363
- {/* The overlay used to be positioned by hand, from `mousemove`
364
- listeners on `window` and a grab offset measured off whatever
365
- `[role='button']` the pointer went down on. dnd-kit already
366
- tracks the pointer and already knows the grab offset — the
367
- hand-rolled copy drifted from the position collision detection
368
- was actually using, so the card you saw and the slot you got
369
- were two different things. */}
370
- {typeof document !== "undefined" && createPortal(
371
- <DragOverlay dropAnimation={null} zIndex={9999}>
372
- {activeItem && (
373
- <ItemComponent
374
- item={activeItem}
375
- isDragging={true}
376
- isClone={true}
377
- />
378
- )}
379
- </DragOverlay>,
380
- document.body
381
- )}
382
- </DndContext>
383
- );
384
- }
@@ -1,138 +0,0 @@
1
- import React, { memo, useMemo } from "react";
2
- import { SortableContext, useSortable, verticalListSortingStrategy } from "@dnd-kit/sortable";
3
- import { CSS } from "@dnd-kit/utilities";
4
- import { BoardSortableList } from "./BoardSortableList";
5
- import { BoardColumnTitle } from "./BoardColumnTitle";
6
- import { BoardItem, BoardItemViewProps } from "./board_types";
7
- import {
8
- IconButton
9
- } from "../../components";
10
- import { cls } from "../../util";
11
- import { iconSize, PlusIcon } from "../../icons";
12
-
13
- export interface BoardColumnProps<T> {
14
- id: string;
15
- title: string;
16
- items: BoardItem<T>[];
17
- index: number;
18
- ItemComponent: React.ComponentType<BoardItemViewProps<T>>;
19
- isDragging: boolean;
20
- isDragOverColumn: boolean;
21
- allowReorder?: boolean;
22
- loading?: boolean;
23
- hasMore?: boolean;
24
- error?: Error;
25
- onLoadMore?: () => void;
26
- onAddItem?: () => void;
27
- totalCount?: number;
28
- color?: any;
29
- style?: React.CSSProperties;
30
- }
31
-
32
- export const BoardColumn = memo(function BoardColumn<T>({
33
- id,
34
- title,
35
- items,
36
- ItemComponent,
37
- isDragging,
38
- isDragOverColumn,
39
- allowReorder = false,
40
- loading = false,
41
- hasMore = false,
42
- error,
43
- onLoadMore,
44
- onAddItem,
45
- totalCount,
46
- color,
47
- style
48
- }: BoardColumnProps<T>) {
49
- const {
50
- setNodeRef,
51
- attributes,
52
- listeners,
53
- isDragging: isColumnBeingDragged,
54
- transform,
55
- transition
56
- } = useSortable({
57
- id,
58
- data: { type: "COLUMN" },
59
- disabled: !allowReorder
60
- });
61
-
62
- const combinedStyle = useMemo(() => ({
63
- ...style,
64
- transform: CSS.Translate.toString(transform),
65
- transition,
66
- zIndex: isColumnBeingDragged ? 2 : 1
67
- }), [style, transform, transition, isColumnBeingDragged]);
68
-
69
- const dragListeners = allowReorder ? listeners : {};
70
-
71
- const columnClassName = useMemo(() => cls(
72
- "border h-full w-80 min-w-80 mx-2 flex flex-col rounded-md border-surface-200 dark:border-surface-800",
73
- isColumnBeingDragged ? "ring-2 ring-primary" : ""
74
- ), [isColumnBeingDragged]);
75
-
76
- const headerClassName = useMemo(() => cls(
77
- "flex items-center justify-between px-2 rounded-t-md transition-colors duration-200 ease-in-out",
78
- isColumnBeingDragged
79
- ? "bg-surface-100 dark:bg-surface-700"
80
- : "bg-surface-50 hover:bg-surface-100 dark:bg-surface-800 dark:hover:bg-surface-700",
81
- allowReorder ? "cursor-grab" : ""
82
- ), [isColumnBeingDragged, allowReorder]);
83
-
84
- const itemIds = useMemo(() => items.map(i => i.id), [items]);
85
-
86
- return (
87
- <div
88
- ref={setNodeRef}
89
- style={combinedStyle}
90
- {...attributes}
91
- className={columnClassName}
92
- >
93
- <div
94
- {...dragListeners}
95
- className={headerClassName}
96
- >
97
- <div className="flex items-center gap-2">
98
- <BoardColumnTitle aria-label={`${title} item list`} color={color}>
99
- {title}
100
- </BoardColumnTitle>
101
- {totalCount !== undefined && (
102
- <span className="text-xs text-surface-500 dark:text-surface-400">
103
- {totalCount}
104
- </span>
105
- )}
106
- </div>
107
- {onAddItem && (
108
- <IconButton
109
- size="small"
110
- onClick={(e: React.MouseEvent) => {
111
- e.stopPropagation();
112
- onAddItem();
113
- }}
114
- className="opacity-60 hover:opacity-100"
115
- >
116
- <PlusIcon size={iconSize.small}/>
117
- </IconButton>
118
- )}
119
- </div>
120
- <SortableContext
121
- items={itemIds}
122
- strategy={verticalListSortingStrategy}
123
- >
124
- <BoardSortableList
125
- columnId={id}
126
- items={items}
127
- ItemComponent={ItemComponent}
128
- isDragging={isDragging}
129
- isDragOverColumn={isDragOverColumn}
130
- loading={loading}
131
- hasMore={hasMore}
132
- error={error}
133
- onLoadMore={onLoadMore}
134
- />
135
- </SortableContext>
136
- </div>
137
- );
138
- }) as <T>(props: BoardColumnProps<T>) => React.ReactElement;
@@ -1,47 +0,0 @@
1
- import React, { useMemo } from "react";
2
- import { Typography } from "../../components";
3
- import { cls, getColorSchemeForKey } from "../../util";
4
-
5
- export interface BoardColumnTitleProps {
6
- children: React.ReactNode;
7
- className?: string;
8
- "aria-label"?: string;
9
- color?: any;
10
- }
11
-
12
- export function BoardColumnTitle({
13
- children,
14
- className,
15
- color,
16
- ...props
17
- }: BoardColumnTitleProps) {
18
- const colorScheme = useMemo(() => {
19
- if (!color) return undefined;
20
- if (typeof color === "string") {
21
- return getColorSchemeForKey(color);
22
- }
23
- return color;
24
- }, [color]);
25
-
26
- return (
27
- <Typography
28
- variant="subtitle2"
29
- component="h4"
30
- className={
31
- cls("py-3 px-3 transition-colors duration-200 flex-grow select-none relative outline-none focus:outline focus:outline-2 focus:outline-offset-2 flex items-center gap-3",
32
- className)
33
- }
34
- {...props}
35
- >
36
- {colorScheme && (
37
- <div
38
- className="w-3 h-3 rounded-full flex-shrink-0"
39
- style={{
40
- backgroundColor: colorScheme.darkColor ?? colorScheme.color
41
- }}
42
- />
43
- )}
44
- {children}
45
- </Typography>
46
- );
47
- }