@monolith-forensics/monolith-ui 1.3.112-dev.0 → 1.3.112-dev.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.
@@ -1,2 +1,2 @@
1
1
  import { KanbanGroupKey, KanbanProps } from "./types";
2
- export declare const Kanban: <TCard, TGroup extends KanbanGroupKey>({ cards, getCardId, getCardGroup, getCardOrder, renderCard, onCardsReorder, groupOrder, groupLabels, renderColumnHeader, columnWidth, columnHeight, estimatedCardHeight, overscanCount, orderStep, minOrderGap, emptyColumnPlaceholder, className, }: KanbanProps<TCard, TGroup>) => import("react/jsx-runtime").JSX.Element;
2
+ export declare const Kanban: <TCard, TGroup extends KanbanGroupKey>({ cards, getCardId, getCardGroup, getCardOrder, renderCard, onCardsReorder, groupOrder, groupLabels, renderColumnHeader, columnWidth, columnGap, cardGap, columnHeight, estimatedCardHeight, overscanCount, orderStep, minOrderGap, emptyColumnPlaceholder, className, }: KanbanProps<TCard, TGroup>) => import("react/jsx-runtime").JSX.Element;
@@ -1,7 +1,7 @@
1
1
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
2
  import { DndContext, DragOverlay, KeyboardSensor, MeasuringStrategy, PointerSensor, closestCenter, getFirstCollision, pointerWithin, rectIntersection, useSensor, useSensors, } from "@dnd-kit/core";
3
3
  import { sortableKeyboardCoordinates } from "@dnd-kit/sortable";
4
- import { useCallback, useEffect, useRef, useState, } from "react";
4
+ import { useCallback, useEffect, useRef, useState } from "react";
5
5
  import { KanbanColumn } from "./KanbanColumn";
6
6
  import { findContainer, fromCardToken, isCardToken, isGroupToken, moveCard, moveCardToInsertIndex, } from "./board";
7
7
  import { dropAnimation } from "./constants";
@@ -9,7 +9,7 @@ import { CardContainer, Board } from "./styles";
9
9
  import { useKanbanBoardData } from "./useKanbanBoardData";
10
10
  import { useKanbanRowHeights } from "./useKanbanRowHeights";
11
11
  import { DEFAULT_MIN_ORDER_GAP, DEFAULT_ORDER_STEP, calculateOrderValue, } from "./utils";
12
- export const Kanban = ({ cards, getCardId, getCardGroup, getCardOrder, renderCard, onCardsReorder, groupOrder, groupLabels, renderColumnHeader, columnWidth = 320, columnHeight, estimatedCardHeight = 100, overscanCount = 4, orderStep = DEFAULT_ORDER_STEP, minOrderGap = DEFAULT_MIN_ORDER_GAP, emptyColumnPlaceholder, className, }) => {
12
+ export const Kanban = ({ cards, getCardId, getCardGroup, getCardOrder, renderCard, onCardsReorder, groupOrder, groupLabels, renderColumnHeader, columnWidth = 320, columnGap = 12, cardGap = 8, columnHeight, estimatedCardHeight = 100, overscanCount = 4, orderStep = DEFAULT_ORDER_STEP, minOrderGap = DEFAULT_MIN_ORDER_GAP, emptyColumnPlaceholder, className, }) => {
13
13
  var _a, _b;
14
14
  const [activeCardToken, setActiveCardToken] = useState(null);
15
15
  const [activeOverlayWidth, setActiveOverlayWidth] = useState(null);
@@ -214,14 +214,14 @@ export const Kanban = ({ cards, getCardId, getCardGroup, getCardOrder, renderCar
214
214
  droppable: {
215
215
  strategy: MeasuringStrategy.Always,
216
216
  },
217
- }, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragEnd: handleDragEnd, onDragCancel: handleDragCancel, children: [_jsx(Board, { className: className, children: Object.keys(board).map((columnToken) => {
217
+ }, onDragStart: handleDragStart, onDragOver: handleDragOver, onDragEnd: handleDragEnd, onDragCancel: handleDragCancel, children: [_jsx(Board, { className: className, "$columnGap": columnGap, children: Object.keys(board).map((columnToken) => {
218
218
  var _a, _b;
219
219
  const columnItems = (_a = board[columnToken]) !== null && _a !== void 0 ? _a : [];
220
220
  const groupValue = groupValueByToken.get(columnToken);
221
221
  if (groupValue == null) {
222
222
  return null;
223
223
  }
224
- return (_jsx(KanbanColumn, { columnToken: columnToken, groupValue: groupValue, groupLabel: groupLabels === null || groupLabels === void 0 ? void 0 : groupLabels[String(groupValue)], renderColumnHeader: renderColumnHeader, itemTokens: columnItems, cardByToken: cardByToken, cardIdByToken: cardIdByToken, groupByToken: groupValueByToken, renderCard: renderCard, onMeasure: onRowMeasured, rowHeights: (_b = columnHeights[columnToken]) !== null && _b !== void 0 ? _b : {}, listRefMap: listRefMap, columnWidth: columnWidth, columnHeight: columnHeight, estimatedCardHeight: estimatedCardHeight, overscanCount: overscanCount, emptyColumnPlaceholder: emptyColumnPlaceholder }, columnToken));
224
+ return (_jsx(KanbanColumn, { columnToken: columnToken, groupValue: groupValue, groupLabel: groupLabels === null || groupLabels === void 0 ? void 0 : groupLabels[String(groupValue)], renderColumnHeader: renderColumnHeader, itemTokens: columnItems, cardByToken: cardByToken, cardIdByToken: cardIdByToken, groupByToken: groupValueByToken, renderCard: renderCard, onMeasure: onRowMeasured, rowHeights: (_b = columnHeights[columnToken]) !== null && _b !== void 0 ? _b : {}, listRefMap: listRefMap, columnWidth: columnWidth, columnHeight: columnHeight, cardGap: cardGap, estimatedCardHeight: estimatedCardHeight, overscanCount: overscanCount, emptyColumnPlaceholder: emptyColumnPlaceholder }, columnToken));
225
225
  }) }), _jsx(DragOverlay, { adjustScale: false, dropAnimation: dropAnimation, children: activeCard && activeGroup != null ? (_jsx("div", { style: { width: activeOverlayWidth !== null && activeOverlayWidth !== void 0 ? activeOverlayWidth : undefined }, children: _jsx(CardContainer, { "$isDragging": true, "$isDragOverlay": true, children: renderCard({
226
226
  card: activeCard,
227
227
  cardId: getCardId(activeCard),
@@ -16,8 +16,9 @@ export interface KanbanColumnProps<TCard, TGroup extends KanbanGroupKey> {
16
16
  listRefMap: MutableRefObject<Record<string, VariableSizeList | null>>;
17
17
  columnWidth: number;
18
18
  columnHeight?: number;
19
+ cardGap: number;
19
20
  estimatedCardHeight: number;
20
21
  overscanCount: number;
21
22
  emptyColumnPlaceholder?: ReactNode;
22
23
  }
23
- export declare const KanbanColumn: <TCard, TGroup extends KanbanGroupKey>({ columnToken, groupValue, groupLabel, renderColumnHeader, itemTokens, cardByToken, cardIdByToken, groupByToken, renderCard, onMeasure, rowHeights, listRefMap, columnWidth, columnHeight, estimatedCardHeight, overscanCount, emptyColumnPlaceholder, }: KanbanColumnProps<TCard, TGroup>) => import("react/jsx-runtime").JSX.Element;
24
+ export declare const KanbanColumn: <TCard, TGroup extends KanbanGroupKey>({ columnToken, groupValue, groupLabel, renderColumnHeader, itemTokens, cardByToken, cardIdByToken, groupByToken, renderCard, onMeasure, rowHeights, listRefMap, columnWidth, columnHeight, cardGap, estimatedCardHeight, overscanCount, emptyColumnPlaceholder, }: KanbanColumnProps<TCard, TGroup>) => import("react/jsx-runtime").JSX.Element;
@@ -6,9 +6,8 @@ import { useOverlayScrollbars } from "overlayscrollbars-react";
6
6
  import AutoSizer from "react-virtualized-auto-sizer";
7
7
  import { VariableSizeList } from "react-window";
8
8
  import { Column, ColumnBody, ColumnCount, ColumnHeader, EmptyColumn, } from "./styles";
9
- import { CARD_GAP } from "./constants";
10
9
  import { MemoizedSortableVirtualRow } from "./virtualRow";
11
- export const KanbanColumn = ({ columnToken, groupValue, groupLabel, renderColumnHeader, itemTokens, cardByToken, cardIdByToken, groupByToken, renderCard, onMeasure, rowHeights, listRefMap, columnWidth, columnHeight, estimatedCardHeight, overscanCount, emptyColumnPlaceholder, }) => {
10
+ export const KanbanColumn = ({ columnToken, groupValue, groupLabel, renderColumnHeader, itemTokens, cardByToken, cardIdByToken, groupByToken, renderCard, onMeasure, rowHeights, listRefMap, columnWidth, columnHeight, cardGap, estimatedCardHeight, overscanCount, emptyColumnPlaceholder, }) => {
12
11
  const { setNodeRef, isOver } = useDroppable({
13
12
  id: columnToken,
14
13
  data: {
@@ -24,6 +23,7 @@ export const KanbanColumn = ({ columnToken, groupValue, groupLabel, renderColumn
24
23
  groupByToken,
25
24
  renderCard,
26
25
  onMeasure,
26
+ cardGap,
27
27
  }), [
28
28
  cardByToken,
29
29
  cardIdByToken,
@@ -32,6 +32,7 @@ export const KanbanColumn = ({ columnToken, groupValue, groupLabel, renderColumn
32
32
  itemTokens,
33
33
  onMeasure,
34
34
  renderCard,
35
+ cardGap,
35
36
  ]);
36
37
  const previousOrderTokensRef = useRef([]);
37
38
  const scrollTargetRef = useRef(null);
@@ -112,6 +113,6 @@ export const KanbanColumn = ({ columnToken, groupValue, groupLabel, renderColumn
112
113
  }, outerRef: setScrollViewportRef, width: width, height: height, itemCount: cardCount, overscanCount: overscanCount, itemData: rowData, itemKey: (index, data) => data.itemTokens[index], itemSize: (index) => {
113
114
  var _a;
114
115
  const token = rowData.itemTokens[index];
115
- return (_a = rowHeights[token]) !== null && _a !== void 0 ? _a : estimatedCardHeight + CARD_GAP;
116
+ return (_a = rowHeights[token]) !== null && _a !== void 0 ? _a : estimatedCardHeight + cardGap;
116
117
  }, children: MemoizedSortableVirtualRow })) })) }) })] }));
117
118
  };
@@ -1,5 +1,4 @@
1
1
  import { DropAnimation } from "@dnd-kit/core";
2
2
  export declare const GROUP_PREFIX = "group::";
3
3
  export declare const CARD_PREFIX = "card::";
4
- export declare const CARD_GAP = 5;
5
4
  export declare const dropAnimation: DropAnimation;
@@ -1,7 +1,6 @@
1
1
  import { defaultDropAnimationSideEffects } from "@dnd-kit/core";
2
2
  export const GROUP_PREFIX = "group::";
3
3
  export const CARD_PREFIX = "card::";
4
- export const CARD_GAP = 5;
5
4
  export const dropAnimation = {
6
5
  duration: 220,
7
6
  easing: "cubic-bezier(0.2, 0, 0, 1)",
@@ -1,4 +1,6 @@
1
- export declare const Board: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, never>> & string;
1
+ export declare const Board: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
2
+ $columnGap?: number;
3
+ }>> & string;
2
4
  export declare const Column: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components/dist/types").Substitute<import("react").DetailedHTMLProps<import("react").HTMLAttributes<HTMLDivElement>, HTMLDivElement>, {
3
5
  $width: number;
4
6
  $isOver: boolean;
@@ -2,7 +2,7 @@ import styled from "styled-components";
2
2
  export const Board = styled.div `
3
3
  display: flex;
4
4
  align-items: stretch;
5
- gap: 12px;
5
+ gap: ${({ $columnGap }) => $columnGap !== null && $columnGap !== void 0 ? $columnGap : 12}px;
6
6
  width: 100%;
7
7
  height: 100%;
8
8
  min-height: 0;
@@ -46,6 +46,8 @@ export interface KanbanProps<TCard, TGroup extends KanbanGroupKey> {
46
46
  renderColumnHeader?: (group: TGroup, cardCount: number) => ReactNode;
47
47
  /** Width of each column in pixels. Defaults to `320`. */
48
48
  columnWidth?: number;
49
+ /** Gap between columns in pixels. Defaults to `8`. */
50
+ columnGap?: number;
49
51
  /** Fixed column body height in pixels. If omitted, it grows with container layout. */
50
52
  columnHeight?: number;
51
53
  /** Fallback card height estimate for virtualization. Defaults to `100`. */
@@ -60,4 +62,6 @@ export interface KanbanProps<TCard, TGroup extends KanbanGroupKey> {
60
62
  emptyColumnPlaceholder?: ReactNode;
61
63
  /** Optional class name applied to the board root element. */
62
64
  className?: string;
65
+ /** Gap between cards in pixels. Defaults to `8`. */
66
+ cardGap?: number;
63
67
  }
@@ -8,6 +8,7 @@ export interface ColumnRowData<TCard, TGroup extends KanbanGroupKey> {
8
8
  cardIdByToken: Map<string, string>;
9
9
  groupByToken: Map<string, TGroup>;
10
10
  renderCard: (args: RenderCardArgs<TCard, TGroup>) => ReactNode;
11
+ cardGap: number;
11
12
  onMeasure: (columnToken: string, cardToken: string, index: number, height: number) => void;
12
13
  }
13
14
  export declare const MemoizedSortableVirtualRow: import("react").MemoExoticComponent<({ data, index, style, }: ListChildComponentProps<ColumnRowData<any, any>>) => import("react/jsx-runtime").JSX.Element | null>;
@@ -4,7 +4,6 @@ import { CSS } from "@dnd-kit/utilities";
4
4
  import { areEqual, } from "react-window";
5
5
  import { memo, useCallback, useEffect, useState } from "react";
6
6
  import { CardContainer } from "./styles";
7
- import { CARD_GAP } from "./constants";
8
7
  const SortableVirtualRow = ({ data, index, style, }) => {
9
8
  const cardToken = data.itemTokens[index];
10
9
  const card = data.cardByToken.get(cardToken);
@@ -36,7 +35,7 @@ const SortableVirtualRow = ({ data, index, style, }) => {
36
35
  if (!nextHeight || nextHeight <= 0) {
37
36
  return;
38
37
  }
39
- data.onMeasure(data.columnToken, cardToken, index, Math.ceil(nextHeight) + CARD_GAP);
38
+ data.onMeasure(data.columnToken, cardToken, index, Math.ceil(nextHeight) + data.cardGap);
40
39
  });
41
40
  observer.observe(contentNode);
42
41
  return () => observer.disconnect();
@@ -44,7 +43,7 @@ const SortableVirtualRow = ({ data, index, style, }) => {
44
43
  if (!card || !cardId || group == null) {
45
44
  return null;
46
45
  }
47
- return (_jsx("div", { ref: setCombinedRef, style: Object.assign(Object.assign({}, style), { transform: CSS.Transform.toString(transform), transition, willChange: isDragging || isSorting ? "transform" : undefined, zIndex: isDragging ? 2 : 1 }), children: _jsx(CardContainer, { ref: setContentNode, style: { marginBottom: CARD_GAP }, "$isDragging": isDragging, "$isDragOverlay": false, children: _jsx("div", Object.assign({}, attributes, listeners, { children: data.renderCard({
46
+ return (_jsx("div", { ref: setCombinedRef, style: Object.assign(Object.assign({}, style), { transform: CSS.Transform.toString(transform), transition, willChange: isDragging || isSorting ? "transform" : undefined, zIndex: isDragging ? 2 : 1 }), children: _jsx(CardContainer, { ref: setContentNode, style: { marginBottom: data.cardGap }, "$isDragging": isDragging, "$isDragOverlay": false, children: _jsx("div", Object.assign({}, attributes, listeners, { children: data.renderCard({
48
47
  card,
49
48
  cardId,
50
49
  group,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@monolith-forensics/monolith-ui",
3
- "version": "1.3.112-dev.0",
3
+ "version": "1.3.112-dev.1",
4
4
  "main": "./dist/index.js",
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Matt Danner (Monolith Forensics LLC)",
@@ -1,16 +0,0 @@
1
- export declare const ORDER_GAP = 1024;
2
- type GetOrderByCardId = (cardId: string) => number;
3
- export type OrderComputationResult = {
4
- newOrder: number;
5
- beforeCardId: string | null;
6
- afterCardId: string | null;
7
- };
8
- type ComputeOrderParams = {
9
- destinationCardIds: string[];
10
- movedCardId: string;
11
- destinationIndex: number;
12
- getOrderByCardId: GetOrderByCardId;
13
- orderGap?: number;
14
- };
15
- export declare const computeOrderForMove: ({ destinationCardIds, movedCardId, destinationIndex, getOrderByCardId, orderGap, }: ComputeOrderParams) => OrderComputationResult;
16
- export {};
@@ -1,52 +0,0 @@
1
- export const ORDER_GAP = 1024;
2
- const coerceOrderValue = (value, fallback) => {
3
- return Number.isFinite(value) ? value : fallback;
4
- };
5
- export const computeOrderForMove = ({ destinationCardIds, movedCardId, destinationIndex, getOrderByCardId, orderGap = ORDER_GAP, }) => {
6
- const total = destinationCardIds.length;
7
- if (total === 0) {
8
- return {
9
- newOrder: 0,
10
- beforeCardId: null,
11
- afterCardId: null,
12
- };
13
- }
14
- const safeIndex = Math.max(0, Math.min(destinationIndex, total - 1));
15
- const currentCardId = destinationCardIds[safeIndex];
16
- const resolvedIndex = currentCardId === movedCardId
17
- ? safeIndex
18
- : destinationCardIds.indexOf(movedCardId);
19
- const targetIndex = resolvedIndex >= 0 ? resolvedIndex : safeIndex;
20
- const beforeCardId = targetIndex > 0 ? destinationCardIds[targetIndex - 1] : null;
21
- const afterCardId = targetIndex < total - 1 ? destinationCardIds[targetIndex + 1] : null;
22
- if (beforeCardId === null && afterCardId === null) {
23
- return {
24
- newOrder: 0,
25
- beforeCardId,
26
- afterCardId,
27
- };
28
- }
29
- if (beforeCardId === null && afterCardId !== null) {
30
- const afterOrder = coerceOrderValue(getOrderByCardId(afterCardId), 0);
31
- return {
32
- newOrder: afterOrder - orderGap,
33
- beforeCardId,
34
- afterCardId,
35
- };
36
- }
37
- if (beforeCardId !== null && afterCardId === null) {
38
- const beforeOrder = coerceOrderValue(getOrderByCardId(beforeCardId), 0);
39
- return {
40
- newOrder: beforeOrder + orderGap,
41
- beforeCardId,
42
- afterCardId,
43
- };
44
- }
45
- const beforeOrder = coerceOrderValue(getOrderByCardId(beforeCardId), 0);
46
- const afterOrder = coerceOrderValue(getOrderByCardId(afterCardId), beforeOrder + orderGap);
47
- return {
48
- newOrder: (beforeOrder + afterOrder) / 2,
49
- beforeCardId,
50
- afterCardId,
51
- };
52
- };