dishui 0.0.91 → 0.0.101
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/dist/.release-verified.json +6 -0
- package/dist/ai.js +24 -0
- package/dist/components/Card/Metric2.js +11 -11
- package/dist/components/Card/Metric2.js.map +1 -1
- package/dist/components/Card/Ticket.d.ts +52 -0
- package/dist/components/Card/Ticket2.js +218 -0
- package/dist/components/Card/Ticket2.js.map +1 -0
- package/dist/components/Card/index.d.ts +32 -0
- package/dist/components/Card/index.js +211 -203
- package/dist/components/Card/index.js.map +1 -1
- package/dist/components/GroupButton/index.js +4 -4
- package/dist/components/GroupButton/index.js.map +1 -1
- package/dist/components/GroupedTable/index.js +10 -10
- package/dist/components/GroupedTable/index.js.map +1 -1
- package/dist/components/NavigationList/index.js +9 -9
- package/dist/components/NavigationList/index.js.map +1 -1
- package/dist/components/Section/index.js +11 -11
- package/dist/components/Section/index.js.map +1 -1
- package/dist/components/Skeleton/index.js +1 -1
- package/dist/components/Skeleton/index.js.map +1 -1
- package/dist/components/Table/index.js +6 -6
- package/dist/components/Table/index.js.map +1 -1
- package/dist/components/ai/AgentChat/index.d.ts +54 -0
- package/dist/components/ai/AgentChat/index.js +176 -0
- package/dist/components/ai/AgentChat/index.js.map +1 -0
- package/dist/components/ai/AgentRunCard/index.d.ts +38 -0
- package/dist/components/ai/AgentRunCard/index.js +100 -0
- package/dist/components/ai/AgentRunCard/index.js.map +1 -0
- package/dist/components/ai/AgentScreen/index.d.ts +50 -0
- package/dist/components/ai/AgentScreen/index.js +233 -0
- package/dist/components/ai/AgentScreen/index.js.map +1 -0
- package/dist/components/ai/ApprovalCard/index.d.ts +26 -0
- package/dist/components/ai/ApprovalCard/index.js +89 -0
- package/dist/components/ai/ApprovalCard/index.js.map +1 -0
- package/dist/components/ai/CodeView/index.d.ts +30 -0
- package/dist/components/ai/CodeView/index.js +149 -0
- package/dist/components/ai/CodeView/index.js.map +1 -0
- package/dist/components/ai/CommandSearch/index.d.ts +39 -0
- package/dist/components/ai/CommandSearch/index.js +217 -0
- package/dist/components/ai/CommandSearch/index.js.map +1 -0
- package/dist/components/ai/ContextCards/index.d.ts +42 -0
- package/dist/components/ai/ContextCards/index.js +106 -0
- package/dist/components/ai/ContextCards/index.js.map +1 -0
- package/dist/components/ai/DiffTable/index.d.ts +70 -0
- package/dist/components/ai/DiffTable/index.js +235 -0
- package/dist/components/ai/DiffTable/index.js.map +1 -0
- package/dist/components/ai/FilterTable/index.d.ts +35 -0
- package/dist/components/ai/FilterTable/index.js +86 -0
- package/dist/components/ai/FilterTable/index.js.map +1 -0
- package/dist/components/ai/FineTuneCard/index.d.ts +24 -0
- package/dist/components/ai/FineTuneCard/index.js +75 -0
- package/dist/components/ai/FineTuneCard/index.js.map +1 -0
- package/dist/components/ai/InsightCards/index.d.ts +23 -0
- package/dist/components/ai/InsightCards/index.js +64 -0
- package/dist/components/ai/InsightCards/index.js.map +1 -0
- package/dist/components/ai/IssueCard/index.d.ts +39 -0
- package/dist/components/ai/IssueCard/index.js +78 -0
- package/dist/components/ai/IssueCard/index.js.map +1 -0
- package/dist/components/ai/LoadingState/index.d.ts +22 -0
- package/dist/components/ai/LoadingState/index.js +80 -0
- package/dist/components/ai/LoadingState/index.js.map +1 -0
- package/dist/components/ai/PromptBar/index.d.ts +26 -0
- package/dist/components/ai/PromptBar/index.js +117 -0
- package/dist/components/ai/PromptBar/index.js.map +1 -0
- package/dist/components/ai/RecommendationCard/index.d.ts +44 -0
- package/dist/components/ai/RecommendationCard/index.js +142 -0
- package/dist/components/ai/RecommendationCard/index.js.map +1 -0
- package/dist/components/ai/RecordsTable/index.d.ts +65 -0
- package/dist/components/ai/RecordsTable/index.js +334 -0
- package/dist/components/ai/RecordsTable/index.js.map +1 -0
- package/dist/components/ai/SelectionActions/index.d.ts +19 -0
- package/dist/components/ai/SelectionActions/index.js +40 -0
- package/dist/components/ai/SelectionActions/index.js.map +1 -0
- package/dist/components/ai/StateFlow/index.d.ts +24 -0
- package/dist/components/ai/StateFlow/index.js +50 -0
- package/dist/components/ai/StateFlow/index.js.map +1 -0
- package/dist/components/ai/StreamingText/index.d.ts +44 -0
- package/dist/components/ai/StreamingText/index.js +211 -0
- package/dist/components/ai/StreamingText/index.js.map +1 -0
- package/dist/components/ai/TaskRows/index.d.ts +53 -0
- package/dist/components/ai/TaskRows/index.js +186 -0
- package/dist/components/ai/TaskRows/index.js.map +1 -0
- package/dist/components/ai/Thinking/index.d.ts +47 -0
- package/dist/components/ai/Thinking/index.js +197 -0
- package/dist/components/ai/Thinking/index.js.map +1 -0
- package/dist/components/ai/ToolChips/index.d.ts +21 -0
- package/dist/components/ai/ToolChips/index.js +63 -0
- package/dist/components/ai/ToolChips/index.js.map +1 -0
- package/dist/components/ai/index.d.ts +54 -0
- package/dist/components/ai/shared.d.ts +13 -0
- package/dist/components/ai/shared.js +25 -0
- package/dist/components/ai/shared.js.map +1 -0
- package/dist/components/pro/DataTable/rowDetailExtension.js +1 -1
- package/dist/components/pro/DataTable/rowDetailExtension.js.map +1 -1
- package/dist/components/pro/Flow/constants.js +3 -3
- package/dist/components/pro/Flow/constants.js.map +1 -1
- package/dist/components/pro/Flow/nodes/shapes.js +3 -3
- package/dist/components/pro/Flow/nodes/shapes.js.map +1 -1
- package/dist/components/pro/Flow/utils/themeColor.d.ts +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js +2 -2
- package/dist/components/pro/Flow/utils/themeColor.js.map +1 -1
- package/dist/components/pro/Kanban/Kanban.d.ts +3 -0
- package/dist/components/pro/Kanban/Kanban.js +339 -0
- package/dist/components/pro/Kanban/Kanban.js.map +1 -0
- package/dist/components/pro/Kanban/Swimlanes.d.ts +3 -0
- package/dist/components/pro/Kanban/Swimlanes.js +60 -0
- package/dist/components/pro/Kanban/Swimlanes.js.map +1 -0
- package/dist/components/pro/Kanban/index.d.ts +5 -0
- package/dist/components/pro/Kanban/types.d.ts +103 -0
- package/dist/components/pro/Kanban/useKanbanDrag.d.ts +17 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js +69 -0
- package/dist/components/pro/Kanban/useKanbanDrag.js.map +1 -0
- package/dist/components/pro/Kanban/utils.d.ts +13 -0
- package/dist/components/pro/Kanban/utils.js +48 -0
- package/dist/components/pro/Kanban/utils.js.map +1 -0
- package/dist/components/pro/RichTextEditor/AIRewrite.js +158 -127
- package/dist/components/pro/RichTextEditor/AIRewrite.js.map +1 -1
- package/dist/components/pro/RichTextEditor/BlockHandle.d.ts +2 -0
- package/dist/components/pro/RichTextEditor/BlockHandle.js +156 -115
- package/dist/components/pro/RichTextEditor/BlockHandle.js.map +1 -1
- package/dist/components/pro/RichTextEditor/RichTextEditor.js +136 -159
- package/dist/components/pro/RichTextEditor/RichTextEditor.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js +44 -41
- package/dist/components/pro/RichTextEditor/Toolbar/ColorPicker.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js +59 -53
- package/dist/components/pro/RichTextEditor/Toolbar/FloatingDialogMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js +48 -44
- package/dist/components/pro/RichTextEditor/Toolbar/MarkdownTemplates.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js +67 -63
- package/dist/components/pro/RichTextEditor/Toolbar/TableOpsMenu.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js +182 -129
- package/dist/components/pro/RichTextEditor/Toolbar/Toolbar.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.d.ts +1 -0
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js +3 -3
- package/dist/components/pro/RichTextEditor/Toolbar/ToolbarButton.js.map +1 -1
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.d.ts +3 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js +31 -0
- package/dist/components/pro/RichTextEditor/Toolbar/useAnchoredDropdown.js.map +1 -0
- package/dist/components/pro/RichTextEditor/index.d.ts +1 -1
- package/dist/components/pro/RichTextEditor/types.d.ts +78 -11
- package/dist/components/pro/RichTextEditor/types.js +11 -0
- package/dist/components/pro/RichTextEditor/types.js.map +1 -1
- package/dist/dishui.css +1 -1
- package/dist/index-nostyled.d.ts +1 -1
- package/dist/index.d.ts +6 -3
- package/dist/index.js +134 -107
- package/dist/kanban.js +5 -0
- package/dist/layouts/Sidebar.d.ts +16 -0
- package/dist/layouts/Sidebar.js +85 -52
- package/dist/layouts/Sidebar.js.map +1 -1
- package/dist/utils/i18n.js +20 -0
- package/dist/utils/i18n.js.map +1 -1
- package/dist/utils/menu.js +1 -1
- package/dist/utils/menu.js.map +1 -1
- package/package.json +14 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Kanban.js","names":[],"sources":["../../../../src/components/pro/Kanban/Kanban.tsx"],"sourcesContent":["import React, { useCallback, useEffect, useMemo, useRef, useState } from \"react\";\nimport Card from \"../../Card\";\nimport Swimlanes from \"./Swimlanes\";\nimport type {\n KanbanCard,\n KanbanColumn,\n KanbanDragTarget,\n KanbanId,\n KanbanLane,\n KanbanLabels,\n KanbanLocation,\n KanbanProps,\n} from \"./types\";\nimport { useKanbanDrag } from \"./useKanbanDrag\";\nimport { cardsAt, createCardMove, getCardLocation, idText, idsEqual, locationEquals } from \"./utils\";\nimport \"./styles.css\";\n\nconst DEFAULT_LABELS: Required<KanbanLabels> = {\n loading: \"Loading board\",\n empty: \"No cards\",\n error: \"Could not load the board.\",\n stale: \"Outdated data\",\n retry: \"Try again\",\n unnamedColumn: \"Untitled column\",\n unnamedLane: \"Untitled lane\",\n card: \"card\",\n lift: \"Lifted\",\n move: \"Move with the arrow keys.\",\n drop: \"Dropped\",\n cancel: \"Move cancelled\",\n};\n\nconst DefaultTicket = Card.Ticket;\n\nfunction cssSize(value: number | string | undefined): string | undefined {\n return typeof value === \"number\" ? `${value}px` : value;\n}\n\nfunction resolveId(value: KanbanId | undefined, items: readonly { id: KanbanId }[]): KanbanId | undefined {\n if (value === undefined) return undefined;\n return items.find(item => String(item.id) === String(value))?.id ?? value;\n}\n\nfunction displayText(value: React.ReactNode, fallback: string): string {\n return typeof value === \"string\" || typeof value === \"number\" ? String(value) : fallback;\n}\n\nfunction renderDefaultCard(card: KanbanCard) {\n return (\n <DefaultTicket\n issueKey={card.issueKey ?? card.id}\n title={card.title}\n description={card.description}\n status={card.status}\n issueType={card.issueType}\n assignees={card.assignees}\n priority={card.priority}\n labels={card.labels}\n dueDate={card.dueDate}\n estimate={card.estimate}\n subtaskProgress={card.subtaskProgress}\n disabled={card.disabled}\n />\n );\n}\n\nexport default function Kanban({\n columns,\n lanes,\n cards,\n onCardMove,\n renderCard,\n renderColumnHeader,\n renderLaneHeader,\n readOnly = false,\n loading = false,\n error,\n stale = false,\n empty,\n onRetry,\n labels: labelsInput,\n dragThreshold = 5,\n columnWidth = 280,\n height,\n collapsedLaneIds,\n defaultCollapsedLaneIds,\n onCollapsedLaneIdsChange,\n className = \"\",\n style,\n ...rest\n}: KanbanProps) {\n const labels = useMemo(() => ({ ...DEFAULT_LABELS, ...labelsInput }), [labelsInput]);\n const [keyboardCardId, setKeyboardCardId] = useState<KanbanId | null>(null);\n const [keyboardTarget, setKeyboardTarget] = useState<KanbanLocation | null>(null);\n const [announcement, setAnnouncement] = useState(\"\");\n const keyboardCardRef = useRef<HTMLElement | null>(null);\n\n const commitMove = useCallback((cardId: KanbanId, rawTarget: KanbanDragTarget) => {\n const target: KanbanLocation = {\n columnId: resolveId(rawTarget.columnId, columns) as KanbanId,\n laneId: lanes ? resolveId(rawTarget.laneId, lanes) : undefined,\n index: rawTarget.index,\n };\n const move = createCardMove(cards, cardId, target);\n if (!move || locationEquals(move.from, move.to)) return;\n onCardMove?.(move);\n }, [cards, columns, lanes, onCardMove]);\n\n const drag = useKanbanDrag({\n threshold: dragThreshold,\n disabled: readOnly || !onCardMove,\n onDrop: commitMove,\n });\n\n const activeCardId = drag.draggingId ?? keyboardCardId;\n const activeTarget = drag.target ?? keyboardTarget;\n\n const cancelKeyboard = useCallback((announce = true) => {\n if (keyboardCardId === null) return;\n setKeyboardCardId(null);\n setKeyboardTarget(null);\n if (announce) setAnnouncement(labels.cancel);\n requestAnimationFrame(() => keyboardCardRef.current?.focus());\n }, [keyboardCardId, labels.cancel]);\n\n useEffect(() => {\n const onBlur = () => cancelKeyboard(false);\n window.addEventListener(\"blur\", onBlur);\n return () => window.removeEventListener(\"blur\", onBlur);\n }, [cancelKeyboard]);\n\n const describeLocation = useCallback((target: KanbanLocation) => {\n const column = columns.find(item => idsEqual(item.id, target.columnId));\n const lane = lanes?.find(item => idsEqual(item.id, target.laneId));\n const columnName = displayText(column?.title, labels.unnamedColumn);\n const laneName = lane ? `, ${displayText(lane.title, labels.unnamedLane)}` : \"\";\n return `${columnName}${laneName}, position ${target.index + 1}`;\n }, [columns, lanes, labels.unnamedColumn, labels.unnamedLane]);\n\n const moveKeyboardTarget = useCallback((key: string) => {\n if (keyboardCardId === null || !keyboardTarget) return;\n const columnIndex = Math.max(0, columns.findIndex(column => idsEqual(column.id, keyboardTarget.columnId)));\n const laneIndex = lanes ? Math.max(0, lanes.findIndex(lane => idsEqual(lane.id, keyboardTarget.laneId))) : 0;\n let nextColumnIndex = columnIndex;\n let nextLaneIndex = laneIndex;\n let nextIndex = keyboardTarget.index;\n\n if (key === \"ArrowLeft\") nextColumnIndex = Math.max(0, columnIndex - 1);\n if (key === \"ArrowRight\") nextColumnIndex = Math.min(columns.length - 1, columnIndex + 1);\n if (key === \"ArrowUp\") {\n if (nextIndex > 0) nextIndex -= 1;\n else if (lanes && laneIndex > 0) nextLaneIndex -= 1;\n }\n if (key === \"ArrowDown\") {\n const count = cardsAt(cards.filter(card => !idsEqual(card.id, keyboardCardId)), keyboardTarget.columnId, keyboardTarget.laneId).length;\n if (nextIndex < count) nextIndex += 1;\n else if (lanes && laneIndex < lanes.length - 1) nextLaneIndex += 1;\n }\n\n const columnId = columns[nextColumnIndex]?.id ?? keyboardTarget.columnId;\n const laneId = lanes?.[nextLaneIndex]?.id;\n if (nextColumnIndex !== columnIndex || nextLaneIndex !== laneIndex) {\n const targetCount = cardsAt(cards.filter(card => !idsEqual(card.id, keyboardCardId)), columnId, laneId).length;\n nextIndex = Math.min(nextIndex, targetCount);\n }\n const next = { columnId, laneId, index: nextIndex };\n setKeyboardTarget(next);\n setAnnouncement(describeLocation(next));\n }, [cards, columns, describeLocation, keyboardCardId, keyboardTarget, lanes]);\n\n const onCardKeyDown = useCallback((event: React.KeyboardEvent<HTMLElement>, card: KanbanCard) => {\n if (event.target !== event.currentTarget || card.disabled || readOnly || !onCardMove) return;\n if (event.key === \"Escape\") {\n event.preventDefault();\n cancelKeyboard();\n return;\n }\n if (event.key === \" \" || event.key === \"Enter\") {\n event.preventDefault();\n if (event.repeat) return;\n if (keyboardCardId === null) {\n const from = getCardLocation(cards, card.id);\n if (!from) return;\n keyboardCardRef.current = event.currentTarget;\n setKeyboardCardId(card.id);\n setKeyboardTarget(from);\n setAnnouncement(`${labels.lift} ${displayText(card.title, labels.card)}. ${labels.move}`);\n } else if (idsEqual(keyboardCardId, card.id) && keyboardTarget) {\n commitMove(card.id, keyboardTarget);\n setKeyboardCardId(null);\n setKeyboardTarget(null);\n setAnnouncement(`${labels.drop} ${displayText(card.title, labels.card)}. ${describeLocation(keyboardTarget)}.`);\n requestAnimationFrame(() => keyboardCardRef.current?.focus());\n }\n return;\n }\n if (keyboardCardId !== null && [\"ArrowLeft\", \"ArrowRight\", \"ArrowUp\", \"ArrowDown\"].includes(event.key)) {\n event.preventDefault();\n moveKeyboardTarget(event.key);\n }\n }, [cancelKeyboard, cards, commitMove, describeLocation, keyboardCardId, keyboardTarget, labels, moveKeyboardTarget, onCardMove, readOnly]);\n\n\n const renderCell = (column: KanbanColumn, lane?: KanbanLane) => {\n const cellCards = cardsAt(cards, column.id, lane?.id);\n const disabledCell = readOnly || !!column.disabled || !!lane?.disabled || !onCardMove;\n let insertionIndex = 0;\n return (\n <div\n className=\"dishui-kanban__column\"\n key={`${idText(lane?.id)}:${idText(column.id)}`}\n role=\"group\"\n aria-label={displayText(column.title, labels.unnamedColumn)}\n data-column-id={idText(column.id)}\n data-lane-id={idText(lane?.id)}\n data-disabled={disabledCell || undefined}\n >\n {!lanes && (\n <div className=\"dishui-kanban__column-header\">\n {renderColumnHeader ? renderColumnHeader(column, cellCards) : (\n <><span>{column.title}</span><span className=\"dishui-kanban__count\">{cellCards.length}</span></>\n )}\n </div>\n )}\n <div className=\"dishui-kanban__cards\">\n {cellCards.length === 0 && activeCardId === null && <span className=\"dishui-kanban__cell-empty\">{labels.empty}</span>}\n <DropIndicator columnId={column.id} laneId={lane?.id} index={0} active={locationEquals(activeTarget, { columnId: column.id, laneId: lane?.id, index: 0 })} />\n {cellCards.map(card => {\n const isActive = activeCardId !== null && idsEqual(activeCardId, card.id);\n const cardIndex = insertionIndex;\n if (!isActive) insertionIndex += 1;\n const cardDisabled = disabledCell || !!card.disabled;\n return (\n <React.Fragment key={String(card.id)}>\n <div\n className=\"dishui-kanban__card\"\n role=\"button\"\n tabIndex={cardDisabled ? -1 : 0}\n aria-disabled={cardDisabled}\n aria-describedby=\"dishui-kanban-instructions\"\n data-kanban-disabled={cardDisabled || undefined}\n data-dragging={isActive || undefined}\n onPointerDown={event => drag.onPointerDown(event, card.id)}\n onPointerMove={drag.onPointerMove}\n onPointerUp={drag.onPointerUp}\n onPointerCancel={drag.onPointerCancel}\n onLostPointerCapture={drag.onLostPointerCapture}\n onKeyDown={event => onCardKeyDown(event, card)}\n >\n {renderCard ? renderCard(card, { dragging: isActive, keyboardDragging: idsEqual(keyboardCardId ?? undefined, card.id), disabled: cardDisabled }) : renderDefaultCard(card)}\n </div>\n {!isActive && (\n <DropIndicator\n columnId={column.id}\n laneId={lane?.id}\n index={cardIndex + 1}\n active={locationEquals(activeTarget, { columnId: column.id, laneId: lane?.id, index: cardIndex + 1 })}\n />\n )}\n </React.Fragment>\n );\n })}\n </div>\n </div>\n );\n };\n\n const boardStyle = {\n ...style,\n height: cssSize(height) ?? style?.height,\n \"--dishui-kanban-column-width\": cssSize(columnWidth),\n } as React.CSSProperties;\n\n return (\n <div {...rest} className={`dishui-kanban ${className}`.trim()} style={boardStyle} aria-busy={loading || undefined}>\n <span id=\"dishui-kanban-instructions\" className=\"dishui-kanban__sr-only\">\n Press Space or Enter to lift and drop. Use arrow keys to choose a destination. Press Escape to cancel.\n </span>\n <div className=\"dishui-kanban__sr-only\" role=\"status\" aria-live=\"polite\" aria-atomic=\"true\">{announcement}</div>\n\n {stale && <div className=\"dishui-kanban__stale\" role=\"status\">{labels.stale}</div>}\n {loading ? (\n <div className=\"dishui-kanban__state\" role=\"status\">\n <span>{labels.loading}</span>\n <div className=\"dishui-kanban__skeletons\" aria-hidden=\"true\"><i /><i /><i /></div>\n </div>\n ) : error ? (\n <div className=\"dishui-kanban__state dishui-kanban__state--error\" role=\"alert\">\n <strong>{labels.error}</strong><span>{error}</span>\n {onRetry && <button type=\"button\" onClick={onRetry}>{labels.retry}</button>}\n </div>\n ) : columns.length === 0 || cards.length === 0 ? (\n <div className=\"dishui-kanban__state dishui-kanban__state--empty\">{empty ?? labels.empty}</div>\n ) : (\n <div className=\"dishui-kanban__scroll\" data-dragging={activeCardId !== null || undefined}>\n {lanes && lanes.length > 0 && (\n <div className=\"dishui-kanban__column-headers\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>\n {columns.map(column => {\n const columnCards = cards.filter(card => idsEqual(card.columnId, column.id));\n return <div className=\"dishui-kanban__column-header\" key={String(column.id)}>{renderColumnHeader ? renderColumnHeader(column, columnCards) : <><span>{column.title}</span><span className=\"dishui-kanban__count\">{columnCards.length}</span></>}</div>;\n })}\n </div>\n )}\n {lanes && lanes.length > 0 ? (\n <Swimlanes\n lanes={lanes}\n collapsedLaneIds={collapsedLaneIds}\n defaultCollapsedLaneIds={defaultCollapsedLaneIds}\n onCollapsedLaneIdsChange={onCollapsedLaneIdsChange}\n renderLaneHeader={(lane, context) => {\n const laneCards = cards.filter(card => idsEqual(card.laneId, lane.id));\n return (\n <button className=\"dishui-swimlane__toggle\" type=\"button\" aria-expanded={!context.collapsed} onClick={context.toggle}>\n <span className=\"dishui-swimlane__chevron\" aria-hidden=\"true\">▾</span>\n <span className=\"dishui-swimlane__header-content\">{renderLaneHeader ? renderLaneHeader(lane, laneCards) : lane.title}</span>\n <span className=\"dishui-kanban__count\">{laneCards.length}</span>\n </button>\n );\n }}\n >\n {({ lane }) => <div className=\"dishui-kanban__grid\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>{columns.map(column => renderCell(column, lane))}</div>}\n </Swimlanes>\n ) : (\n <div className=\"dishui-kanban__grid\" style={{ gridTemplateColumns: `repeat(${columns.length}, minmax(var(--dishui-kanban-column-width), 1fr))` }}>{columns.map(column => renderCell(column))}</div>\n )}\n </div>\n )}\n </div>\n );\n}\n\nfunction DropIndicator({ columnId, laneId, index, active }: KanbanLocation & { active: boolean }) {\n return (\n <div\n className=\"dishui-kanban__drop-zone\"\n data-kanban-drop=\"true\"\n data-column-id={String(columnId)}\n data-lane-id={laneId === undefined ? \"\" : String(laneId)}\n data-index={index}\n data-active={active || undefined}\n aria-hidden=\"true\"\n ><span /></div>\n );\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import type { KanbanLane, SwimlanesProps } from "./types";
|
|
3
|
+
export default function Swimlanes<TLane extends KanbanLane = KanbanLane>({ lanes, children, renderLaneHeader, collapsedLaneIds, defaultCollapsedLaneIds, onCollapsedLaneIdsChange, collapsible, empty, className, laneClassName, ...rest }: SwimlanesProps<TLane>): React.JSX.Element;
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { idsEqual as e } from "./utils.js";
|
|
2
|
+
/* empty css */
|
|
3
|
+
import { useCallback as t, useState as n } from "react";
|
|
4
|
+
import { jsx as r, jsxs as i } from "react/jsx-runtime";
|
|
5
|
+
//#region src/components/pro/Kanban/Swimlanes.tsx
|
|
6
|
+
var a = [];
|
|
7
|
+
function o({ lanes: o, children: s, renderLaneHeader: c, collapsedLaneIds: l, defaultCollapsedLaneIds: u = a, onCollapsedLaneIdsChange: d, collapsible: f = !0, empty: p = "No lanes", className: m = "", laneClassName: h = "", ...g }) {
|
|
8
|
+
let _ = l !== void 0, [v, y] = n(u), b = (_ ? l : v).filter((t) => o.some((n) => e(n.id, t))), x = t((t) => {
|
|
9
|
+
let n = b.some((n) => e(n, t)) ? b.filter((n) => !e(n, t)) : [...b, t];
|
|
10
|
+
_ || y(n), d?.(n);
|
|
11
|
+
}, [
|
|
12
|
+
b,
|
|
13
|
+
_,
|
|
14
|
+
d
|
|
15
|
+
]);
|
|
16
|
+
return /* @__PURE__ */ r("div", {
|
|
17
|
+
...g,
|
|
18
|
+
className: `dishui-swimlanes ${m}`.trim(),
|
|
19
|
+
children: o.length === 0 ? /* @__PURE__ */ r("div", {
|
|
20
|
+
className: "dishui-swimlanes__empty",
|
|
21
|
+
children: p
|
|
22
|
+
}) : o.map((t) => {
|
|
23
|
+
let n = b.some((n) => e(n, t.id)), a = {
|
|
24
|
+
lane: t,
|
|
25
|
+
collapsed: n,
|
|
26
|
+
toggle: () => x(t.id)
|
|
27
|
+
};
|
|
28
|
+
return /* @__PURE__ */ i("section", {
|
|
29
|
+
className: `dishui-swimlane ${h}`.trim(),
|
|
30
|
+
"data-lane-id": String(t.id),
|
|
31
|
+
"data-collapsed": n || void 0,
|
|
32
|
+
children: [/* @__PURE__ */ r("header", {
|
|
33
|
+
className: "dishui-swimlane__header",
|
|
34
|
+
children: c ? c(t, a) : /* @__PURE__ */ i("button", {
|
|
35
|
+
className: "dishui-swimlane__toggle",
|
|
36
|
+
type: "button",
|
|
37
|
+
disabled: !f,
|
|
38
|
+
"aria-expanded": !n,
|
|
39
|
+
"aria-controls": `dishui-swimlane-${String(t.id)}`,
|
|
40
|
+
onClick: a.toggle,
|
|
41
|
+
children: [/* @__PURE__ */ r("span", {
|
|
42
|
+
className: "dishui-swimlane__chevron",
|
|
43
|
+
"aria-hidden": "true",
|
|
44
|
+
children: "▾"
|
|
45
|
+
}), /* @__PURE__ */ r("span", { children: t.title })]
|
|
46
|
+
})
|
|
47
|
+
}), /* @__PURE__ */ r("div", {
|
|
48
|
+
id: `dishui-swimlane-${String(t.id)}`,
|
|
49
|
+
className: "dishui-swimlane__content",
|
|
50
|
+
hidden: n,
|
|
51
|
+
children: typeof s == "function" ? s(a) : s
|
|
52
|
+
})]
|
|
53
|
+
}, String(t.id));
|
|
54
|
+
})
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { o as default };
|
|
59
|
+
|
|
60
|
+
//# sourceMappingURL=Swimlanes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Swimlanes.js","names":[],"sources":["../../../../src/components/pro/Kanban/Swimlanes.tsx"],"sourcesContent":["import React, { useCallback, useState } from \"react\";\nimport type { KanbanId, KanbanLane, SwimlanesProps } from \"./types\";\nimport { idsEqual } from \"./utils\";\nimport \"./styles.css\";\n\nconst EMPTY_IDS: KanbanId[] = [];\n\nexport default function Swimlanes<TLane extends KanbanLane = KanbanLane>({\n lanes,\n children,\n renderLaneHeader,\n collapsedLaneIds,\n defaultCollapsedLaneIds = EMPTY_IDS,\n onCollapsedLaneIdsChange,\n collapsible = true,\n empty = \"No lanes\",\n className = \"\",\n laneClassName = \"\",\n ...rest\n}: SwimlanesProps<TLane>) {\n const controlled = collapsedLaneIds !== undefined;\n const [internalIds, setInternalIds] = useState<KanbanId[]>(defaultCollapsedLaneIds);\n const sourceIds = controlled ? collapsedLaneIds : internalIds;\n const collapsedIds = sourceIds.filter(id => lanes.some(lane => idsEqual(lane.id, id)));\n\n const toggleLane = useCallback((id: KanbanId) => {\n const next = collapsedIds.some(item => idsEqual(item, id))\n ? collapsedIds.filter(item => !idsEqual(item, id))\n : [...collapsedIds, id];\n if (!controlled) setInternalIds(next);\n onCollapsedLaneIdsChange?.(next);\n }, [collapsedIds, controlled, onCollapsedLaneIdsChange]);\n\n return (\n <div {...rest} className={`dishui-swimlanes ${className}`.trim()}>\n {lanes.length === 0 ? <div className=\"dishui-swimlanes__empty\">{empty}</div> : lanes.map(lane => {\n const collapsed = collapsedIds.some(id => idsEqual(id, lane.id));\n const context = { lane, collapsed, toggle: () => toggleLane(lane.id) };\n return (\n <section\n className={`dishui-swimlane ${laneClassName}`.trim()}\n key={String(lane.id)}\n data-lane-id={String(lane.id)}\n data-collapsed={collapsed || undefined}\n >\n <header className=\"dishui-swimlane__header\">\n {renderLaneHeader ? renderLaneHeader(lane, context) : (\n <button\n className=\"dishui-swimlane__toggle\"\n type=\"button\"\n disabled={!collapsible}\n aria-expanded={!collapsed}\n aria-controls={`dishui-swimlane-${String(lane.id)}`}\n onClick={context.toggle}\n >\n <span className=\"dishui-swimlane__chevron\" aria-hidden=\"true\">▾</span>\n <span>{lane.title}</span>\n </button>\n )}\n </header>\n <div id={`dishui-swimlane-${String(lane.id)}`} className=\"dishui-swimlane__content\" hidden={collapsed}>\n {typeof children === \"function\" ? children(context) : children}\n </div>\n </section>\n );\n })}\n </div>\n );\n}\n"],"mappings":";;;;;AAKA,IAAM,IAAwB,CAAC;AAE/B,SAAwB,EAAiD,EACvE,UACA,aACA,qBACA,qBACA,6BAA0B,GAC1B,6BACA,iBAAc,IACd,WAAQ,YACR,eAAY,IACZ,mBAAgB,IAChB,GAAG,KACqB;CACxB,IAAM,IAAa,MAAqB,KAAA,GAClC,CAAC,GAAa,KAAkB,EAAqB,CAAuB,GAE5E,KADY,IAAa,IAAmB,EAAA,CACnB,QAAO,MAAM,EAAM,MAAK,MAAQ,EAAS,EAAK,IAAI,CAAE,CAAC,CAAC,GAE/E,IAAa,GAAa,MAAiB;EAC/C,IAAM,IAAO,EAAa,MAAK,MAAQ,EAAS,GAAM,CAAE,CAAC,IACrD,EAAa,QAAO,MAAQ,CAAC,EAAS,GAAM,CAAE,CAAC,IAC/C,CAAC,GAAG,GAAc,CAAE;EAExB,AADK,KAAY,EAAe,CAAI,GACpC,IAA2B,CAAI;CACjC,GAAG;EAAC;EAAc;EAAY;CAAwB,CAAC;CAEvD,OACE,kBAAC,OAAD;EAAK,GAAI;EAAM,WAAW,oBAAoB,IAAY,KAAK;EAC5D,UAAA,EAAM,WAAW,IAAI,kBAAC,OAAD;GAAK,WAAU;GAA2B,UAAA;EAAW,CAAA,IAAI,EAAM,KAAI,MAAQ;GAC/F,IAAM,IAAY,EAAa,MAAK,MAAM,EAAS,GAAI,EAAK,EAAE,CAAC,GACzD,IAAU;IAAE;IAAM;IAAW,cAAc,EAAW,EAAK,EAAE;GAAE;GACrE,OACE,kBAAC,WAAD;IACE,WAAW,mBAAmB,IAAgB,KAAK;IAEnD,gBAAc,OAAO,EAAK,EAAE;IAC5B,kBAAgB,KAAa,KAAA;IAJ/B,UAAA,CAME,kBAAC,UAAD;KAAQ,WAAU;KACf,UAAA,IAAmB,EAAiB,GAAM,CAAO,IAChD,kBAAC,UAAD;MACE,WAAU;MACV,MAAK;MACL,UAAU,CAAC;MACX,iBAAe,CAAC;MAChB,iBAAe,mBAAmB,OAAO,EAAK,EAAE;MAChD,SAAS,EAAQ;MANnB,UAAA,CAQE,kBAAC,QAAD;OAAM,WAAU;OAA2B,eAAY;OAAO,UAAA;MAAO,CAAA,GACrE,kBAAC,QAAD,EAAA,UAAO,EAAK,MAAY,CAAA,CAClB;;IAEJ,CAAA,GACR,kBAAC,OAAD;KAAK,IAAI,mBAAmB,OAAO,EAAK,EAAE;KAAK,WAAU;KAA2B,QAAQ;KACzF,UAAA,OAAO,KAAa,aAAa,EAAS,CAAO,IAAI;IACnD,CAAA,CACE;GAtBF,GAAA,OAAO,EAAK,EAAE,CAsBZ;EAEb,CAAC;CACE,CAAA;AAET"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import type { CardTicketAssignee, CardTicketIssueType, CardTicketLabel, CardTicketPriority, CardTicketStatus, CardTicketSubtaskProgress } from "../../Card";
|
|
3
|
+
export type KanbanId = string | number;
|
|
4
|
+
export interface KanbanColumn {
|
|
5
|
+
id: KanbanId;
|
|
6
|
+
title: React.ReactNode;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
[key: string]: unknown;
|
|
9
|
+
}
|
|
10
|
+
export interface KanbanLane {
|
|
11
|
+
id: KanbanId;
|
|
12
|
+
title: React.ReactNode;
|
|
13
|
+
disabled?: boolean;
|
|
14
|
+
[key: string]: unknown;
|
|
15
|
+
}
|
|
16
|
+
export interface KanbanCard {
|
|
17
|
+
id: KanbanId;
|
|
18
|
+
columnId: KanbanId;
|
|
19
|
+
laneId?: KanbanId;
|
|
20
|
+
title: React.ReactNode;
|
|
21
|
+
description?: React.ReactNode;
|
|
22
|
+
issueKey?: React.ReactNode;
|
|
23
|
+
status?: CardTicketStatus | React.ReactNode;
|
|
24
|
+
issueType?: CardTicketIssueType | React.ReactNode;
|
|
25
|
+
assignees?: CardTicketAssignee[];
|
|
26
|
+
priority?: CardTicketPriority;
|
|
27
|
+
labels?: Array<CardTicketLabel | React.ReactNode>;
|
|
28
|
+
dueDate?: React.ReactNode;
|
|
29
|
+
estimate?: React.ReactNode;
|
|
30
|
+
subtaskProgress?: CardTicketSubtaskProgress;
|
|
31
|
+
disabled?: boolean;
|
|
32
|
+
[key: string]: unknown;
|
|
33
|
+
}
|
|
34
|
+
export interface KanbanLocation {
|
|
35
|
+
columnId: KanbanId;
|
|
36
|
+
laneId?: KanbanId;
|
|
37
|
+
index: number;
|
|
38
|
+
}
|
|
39
|
+
export interface KanbanCardMove {
|
|
40
|
+
card: KanbanCard;
|
|
41
|
+
from: KanbanLocation;
|
|
42
|
+
to: KanbanLocation;
|
|
43
|
+
cards: KanbanCard[];
|
|
44
|
+
}
|
|
45
|
+
export interface KanbanRenderContext {
|
|
46
|
+
dragging: boolean;
|
|
47
|
+
keyboardDragging: boolean;
|
|
48
|
+
disabled: boolean;
|
|
49
|
+
}
|
|
50
|
+
export interface KanbanLabels {
|
|
51
|
+
loading?: string;
|
|
52
|
+
empty?: string;
|
|
53
|
+
error?: string;
|
|
54
|
+
stale?: string;
|
|
55
|
+
retry?: string;
|
|
56
|
+
unnamedColumn?: string;
|
|
57
|
+
unnamedLane?: string;
|
|
58
|
+
card?: string;
|
|
59
|
+
lift?: string;
|
|
60
|
+
move?: string;
|
|
61
|
+
drop?: string;
|
|
62
|
+
cancel?: string;
|
|
63
|
+
}
|
|
64
|
+
export interface KanbanProps extends Omit<React.HTMLAttributes<HTMLDivElement>, "children" | "onError"> {
|
|
65
|
+
columns: KanbanColumn[];
|
|
66
|
+
lanes?: KanbanLane[];
|
|
67
|
+
cards: KanbanCard[];
|
|
68
|
+
onCardMove?: (move: KanbanCardMove) => void;
|
|
69
|
+
renderCard?: (card: KanbanCard, context: KanbanRenderContext) => React.ReactNode;
|
|
70
|
+
renderColumnHeader?: (column: KanbanColumn, cards: KanbanCard[]) => React.ReactNode;
|
|
71
|
+
renderLaneHeader?: (lane: KanbanLane, cards: KanbanCard[]) => React.ReactNode;
|
|
72
|
+
readOnly?: boolean;
|
|
73
|
+
loading?: boolean;
|
|
74
|
+
error?: React.ReactNode;
|
|
75
|
+
stale?: boolean;
|
|
76
|
+
empty?: React.ReactNode;
|
|
77
|
+
onRetry?: () => void;
|
|
78
|
+
labels?: KanbanLabels;
|
|
79
|
+
dragThreshold?: number;
|
|
80
|
+
columnWidth?: number | string;
|
|
81
|
+
height?: number | string;
|
|
82
|
+
collapsedLaneIds?: KanbanId[];
|
|
83
|
+
defaultCollapsedLaneIds?: KanbanId[];
|
|
84
|
+
onCollapsedLaneIdsChange?: (ids: KanbanId[]) => void;
|
|
85
|
+
}
|
|
86
|
+
export interface SwimlaneRenderContext<TLane> {
|
|
87
|
+
lane: TLane;
|
|
88
|
+
collapsed: boolean;
|
|
89
|
+
toggle: () => void;
|
|
90
|
+
}
|
|
91
|
+
export interface SwimlanesProps<TLane extends KanbanLane = KanbanLane> extends Omit<React.HTMLAttributes<HTMLDivElement>, "children"> {
|
|
92
|
+
lanes: TLane[];
|
|
93
|
+
children?: React.ReactNode | ((context: SwimlaneRenderContext<TLane>) => React.ReactNode);
|
|
94
|
+
renderLaneHeader?: (lane: TLane, context: SwimlaneRenderContext<TLane>) => React.ReactNode;
|
|
95
|
+
collapsedLaneIds?: KanbanId[];
|
|
96
|
+
defaultCollapsedLaneIds?: KanbanId[];
|
|
97
|
+
onCollapsedLaneIdsChange?: (ids: KanbanId[]) => void;
|
|
98
|
+
collapsible?: boolean;
|
|
99
|
+
empty?: React.ReactNode;
|
|
100
|
+
laneClassName?: string;
|
|
101
|
+
}
|
|
102
|
+
export interface KanbanDragTarget extends KanbanLocation {
|
|
103
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type React from "react";
|
|
2
|
+
import type { KanbanDragTarget, KanbanId } from "./types";
|
|
3
|
+
export interface UseKanbanDragOptions {
|
|
4
|
+
threshold?: number;
|
|
5
|
+
disabled?: boolean;
|
|
6
|
+
onDrop: (cardId: KanbanId, target: KanbanDragTarget) => void;
|
|
7
|
+
}
|
|
8
|
+
export declare function useKanbanDrag({ threshold, disabled, onDrop }: UseKanbanDragOptions): {
|
|
9
|
+
draggingId: KanbanId | null;
|
|
10
|
+
target: KanbanDragTarget | null;
|
|
11
|
+
onPointerDown: (event: React.PointerEvent<HTMLElement>, cardId: KanbanId) => void;
|
|
12
|
+
onPointerMove: (event: React.PointerEvent<HTMLElement>) => void;
|
|
13
|
+
onPointerUp: (event: React.PointerEvent<HTMLElement>) => void;
|
|
14
|
+
onPointerCancel: () => void;
|
|
15
|
+
onLostPointerCapture: () => void;
|
|
16
|
+
cancelDrag: () => void;
|
|
17
|
+
};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { useCallback as e, useEffect as t, useRef as n, useState as r } from "react";
|
|
2
|
+
//#region src/components/pro/Kanban/useKanbanDrag.ts
|
|
3
|
+
function i(e, t) {
|
|
4
|
+
let n = document.elementFromPoint(e, t), r = n?.closest(".dishui-kanban");
|
|
5
|
+
if (!r) return null;
|
|
6
|
+
let i = n?.closest("[data-kanban-drop]"), a = i?.closest("[data-disabled='true']") ? null : i;
|
|
7
|
+
if (!a) {
|
|
8
|
+
let n = Infinity;
|
|
9
|
+
r.querySelectorAll("[data-kanban-drop]").forEach((r) => {
|
|
10
|
+
if (r.closest("[data-disabled='true']")) return;
|
|
11
|
+
let i = r.getBoundingClientRect(), o = e < i.left ? i.left - e : e > i.right ? e - i.right : 0, s = Math.abs(t - (i.top + i.bottom) / 2), c = o * o + s * s;
|
|
12
|
+
c < n && (n = c, a = r);
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
let o = a?.dataset.columnId, s = a?.dataset.laneId, c = Number(a?.dataset.index);
|
|
16
|
+
return o === void 0 || !Number.isFinite(c) ? null : {
|
|
17
|
+
columnId: o,
|
|
18
|
+
laneId: s || void 0,
|
|
19
|
+
index: c
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function a({ threshold: a = 5, disabled: o = !1, onDrop: s }) {
|
|
23
|
+
let [c, l] = r(null), [u, d] = r(null), f = n(null), p = n(!1), m = n(null), h = e(() => {
|
|
24
|
+
let e = f.current;
|
|
25
|
+
f.current = null, p.current = !1, m.current = null, l(null), d(null), e?.element.hasPointerCapture(e.pointerId) && e.element.releasePointerCapture(e.pointerId);
|
|
26
|
+
}, []), g = e((e, t) => {
|
|
27
|
+
if (o || e.button !== 0 || e.currentTarget.closest("[data-kanban-disabled='true']")) return;
|
|
28
|
+
let n = e.currentTarget;
|
|
29
|
+
f.current = {
|
|
30
|
+
cardId: t,
|
|
31
|
+
pointerId: e.pointerId,
|
|
32
|
+
startX: e.clientX,
|
|
33
|
+
startY: e.clientY,
|
|
34
|
+
element: n
|
|
35
|
+
}, n.setPointerCapture(e.pointerId);
|
|
36
|
+
}, [o]), _ = e((e) => {
|
|
37
|
+
let t = f.current;
|
|
38
|
+
if (!t || t.pointerId !== e.pointerId) return;
|
|
39
|
+
let n = Math.hypot(e.clientX - t.startX, e.clientY - t.startY);
|
|
40
|
+
if (!p.current && n < Math.max(4, Math.min(6, a))) return;
|
|
41
|
+
e.preventDefault(), p.current || (p.current = !0, l(t.cardId));
|
|
42
|
+
let r = i(e.clientX, e.clientY);
|
|
43
|
+
m.current = r, d(r);
|
|
44
|
+
}, [a]), v = e((e) => {
|
|
45
|
+
let t = f.current;
|
|
46
|
+
t && t.pointerId === e.pointerId && (p.current && m.current && s(t.cardId, m.current), h());
|
|
47
|
+
}, [h, s]);
|
|
48
|
+
return t(() => {
|
|
49
|
+
let e = () => h(), t = (e) => {
|
|
50
|
+
e.key === "Escape" && h();
|
|
51
|
+
};
|
|
52
|
+
return window.addEventListener("blur", e), window.addEventListener("keydown", t), () => {
|
|
53
|
+
window.removeEventListener("blur", e), window.removeEventListener("keydown", t), h();
|
|
54
|
+
};
|
|
55
|
+
}, [h]), {
|
|
56
|
+
draggingId: c,
|
|
57
|
+
target: u,
|
|
58
|
+
onPointerDown: g,
|
|
59
|
+
onPointerMove: _,
|
|
60
|
+
onPointerUp: v,
|
|
61
|
+
onPointerCancel: h,
|
|
62
|
+
onLostPointerCapture: h,
|
|
63
|
+
cancelDrag: h
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
export { a as useKanbanDrag };
|
|
68
|
+
|
|
69
|
+
//# sourceMappingURL=useKanbanDrag.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useKanbanDrag.js","names":[],"sources":["../../../../src/components/pro/Kanban/useKanbanDrag.ts"],"sourcesContent":["import { useCallback, useEffect, useRef, useState } from \"react\";\nimport type React from \"react\";\nimport type { KanbanDragTarget, KanbanId } from \"./types\";\n\nexport interface UseKanbanDragOptions {\n threshold?: number;\n disabled?: boolean;\n onDrop: (cardId: KanbanId, target: KanbanDragTarget) => void;\n}\n\ntype PendingDrag = {\n cardId: KanbanId;\n pointerId: number;\n startX: number;\n startY: number;\n element: HTMLElement;\n};\n\nfunction targetFromPoint(x: number, y: number): KanbanDragTarget | null {\n const hit = document.elementFromPoint(x, y) as HTMLElement | null;\n const board = hit?.closest<HTMLElement>(\".dishui-kanban\");\n if (!board) return null;\n\n const direct = hit?.closest<HTMLElement>(\"[data-kanban-drop]\");\n let indicator = direct?.closest<HTMLElement>(\"[data-disabled='true']\") ? null : direct;\n if (!indicator) {\n let bestDistance = Number.POSITIVE_INFINITY;\n board.querySelectorAll<HTMLElement>(\"[data-kanban-drop]\").forEach(candidate => {\n if (candidate.closest(\"[data-disabled='true']\")) return;\n const rect = candidate.getBoundingClientRect();\n const dx = x < rect.left ? rect.left - x : x > rect.right ? x - rect.right : 0;\n const dy = Math.abs(y - (rect.top + rect.bottom) / 2);\n const distance = dx * dx + dy * dy;\n if (distance < bestDistance) {\n bestDistance = distance;\n indicator = candidate;\n }\n });\n }\n\n const columnId = indicator?.dataset.columnId;\n const laneId = indicator?.dataset.laneId;\n const index = Number(indicator?.dataset.index);\n if (columnId === undefined || !Number.isFinite(index)) return null;\n return { columnId, laneId: laneId || undefined, index };\n}\n\nexport function useKanbanDrag({ threshold = 5, disabled = false, onDrop }: UseKanbanDragOptions) {\n const [draggingId, setDraggingId] = useState<KanbanId | null>(null);\n const [target, setTarget] = useState<KanbanDragTarget | null>(null);\n const pendingRef = useRef<PendingDrag | null>(null);\n const activeRef = useRef(false);\n const targetRef = useRef<KanbanDragTarget | null>(null);\n\n const cleanup = useCallback(() => {\n const pending = pendingRef.current;\n pendingRef.current = null;\n activeRef.current = false;\n targetRef.current = null;\n setDraggingId(null);\n setTarget(null);\n if (pending?.element.hasPointerCapture(pending.pointerId)) {\n pending.element.releasePointerCapture(pending.pointerId);\n }\n }, []);\n\n const onPointerDown = useCallback((event: React.PointerEvent<HTMLElement>, cardId: KanbanId) => {\n if (disabled || event.button !== 0 || event.currentTarget.closest(\"[data-kanban-disabled='true']\")) return;\n const element = event.currentTarget;\n pendingRef.current = { cardId, pointerId: event.pointerId, startX: event.clientX, startY: event.clientY, element };\n element.setPointerCapture(event.pointerId);\n }, [disabled]);\n\n const onPointerMove = useCallback((event: React.PointerEvent<HTMLElement>) => {\n const pending = pendingRef.current;\n if (!pending || pending.pointerId !== event.pointerId) return;\n const distance = Math.hypot(event.clientX - pending.startX, event.clientY - pending.startY);\n if (!activeRef.current && distance < Math.max(4, Math.min(6, threshold))) return;\n event.preventDefault();\n if (!activeRef.current) {\n activeRef.current = true;\n setDraggingId(pending.cardId);\n }\n const next = targetFromPoint(event.clientX, event.clientY);\n targetRef.current = next;\n setTarget(next);\n }, [threshold]);\n\n const onPointerUp = useCallback((event: React.PointerEvent<HTMLElement>) => {\n const pending = pendingRef.current;\n if (!pending || pending.pointerId !== event.pointerId) return;\n if (activeRef.current && targetRef.current) onDrop(pending.cardId, targetRef.current);\n cleanup();\n }, [cleanup, onDrop]);\n\n useEffect(() => {\n const cancel = () => cleanup();\n const onKey = (event: KeyboardEvent) => { if (event.key === \"Escape\") cleanup(); };\n window.addEventListener(\"blur\", cancel);\n window.addEventListener(\"keydown\", onKey);\n return () => {\n window.removeEventListener(\"blur\", cancel);\n window.removeEventListener(\"keydown\", onKey);\n cleanup();\n };\n }, [cleanup]);\n\n return {\n draggingId,\n target,\n onPointerDown,\n onPointerMove,\n onPointerUp,\n onPointerCancel: cleanup,\n onLostPointerCapture: cleanup,\n cancelDrag: cleanup,\n };\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { KanbanCard, KanbanCardMove, KanbanId, KanbanLocation } from "./types";
|
|
2
|
+
export declare function idsEqual(a: KanbanId | undefined, b: KanbanId | undefined): boolean;
|
|
3
|
+
export declare function cardsAt(cards: readonly KanbanCard[], columnId: KanbanId, laneId?: KanbanId): KanbanCard[];
|
|
4
|
+
export declare function getCardLocation(cards: readonly KanbanCard[], cardId: KanbanId): KanbanLocation | null;
|
|
5
|
+
/**
|
|
6
|
+
* Pure immutable card move. `to.index` is the insertion index in the target
|
|
7
|
+
* cell after the moving card has been removed, which makes same-cell sorting
|
|
8
|
+
* and cross-column/lane moves follow one rule.
|
|
9
|
+
*/
|
|
10
|
+
export declare function moveKanbanCard(cards: readonly KanbanCard[], cardId: KanbanId, to: KanbanLocation): KanbanCard[];
|
|
11
|
+
export declare function createCardMove(cards: readonly KanbanCard[], cardId: KanbanId, to: KanbanLocation): KanbanCardMove | null;
|
|
12
|
+
export declare function locationEquals(a: KanbanLocation | null, b: KanbanLocation | null): boolean;
|
|
13
|
+
export declare function idText(id: KanbanId | undefined): string;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
//#region src/components/pro/Kanban/utils.ts
|
|
2
|
+
function e(e, t) {
|
|
3
|
+
return e === t;
|
|
4
|
+
}
|
|
5
|
+
function t(t, n, r) {
|
|
6
|
+
return t.filter((t) => e(t.columnId, n) && e(t.laneId, r));
|
|
7
|
+
}
|
|
8
|
+
function n(n, r) {
|
|
9
|
+
let i = n.find((t) => e(t.id, r));
|
|
10
|
+
return i ? {
|
|
11
|
+
columnId: i.columnId,
|
|
12
|
+
laneId: i.laneId,
|
|
13
|
+
index: t(n, i.columnId, i.laneId).findIndex((t) => e(t.id, r))
|
|
14
|
+
} : null;
|
|
15
|
+
}
|
|
16
|
+
function r(n, r, i) {
|
|
17
|
+
let a = n.find((t) => e(t.id, r));
|
|
18
|
+
if (!a) return [...n];
|
|
19
|
+
let o = n.filter((t) => !e(t.id, r)), s = t(o, i.columnId, i.laneId), c = Math.max(0, Math.min(i.index, s.length)), l = {
|
|
20
|
+
...a,
|
|
21
|
+
columnId: i.columnId
|
|
22
|
+
}, u = n.findIndex((t) => e(t.id, r));
|
|
23
|
+
if (i.laneId === void 0 ? delete l.laneId : l.laneId = i.laneId, c === s.length) {
|
|
24
|
+
let t = s[s.length - 1], n = t ? o.findIndex((n) => e(n.id, t.id)) + 1 : Math.min(u, o.length), r = [...o];
|
|
25
|
+
return r.splice(n, 0, l), r;
|
|
26
|
+
}
|
|
27
|
+
let d = s[c].id, f = o.findIndex((t) => e(t.id, d)), p = [...o];
|
|
28
|
+
return p.splice(f, 0, l), p;
|
|
29
|
+
}
|
|
30
|
+
function i(t, i, a) {
|
|
31
|
+
let o = t.find((t) => e(t.id, i)), s = n(t, i);
|
|
32
|
+
return !o || !s ? null : {
|
|
33
|
+
card: o,
|
|
34
|
+
from: s,
|
|
35
|
+
to: a,
|
|
36
|
+
cards: r(t, i, a)
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function a(t, n) {
|
|
40
|
+
return !!t && !!n && e(t.columnId, n.columnId) && e(t.laneId, n.laneId) && t.index === n.index;
|
|
41
|
+
}
|
|
42
|
+
function o(e) {
|
|
43
|
+
return e === void 0 ? "" : String(e);
|
|
44
|
+
}
|
|
45
|
+
//#endregion
|
|
46
|
+
export { t as cardsAt, i as createCardMove, n as getCardLocation, o as idText, e as idsEqual, a as locationEquals, r as moveKanbanCard };
|
|
47
|
+
|
|
48
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","names":[],"sources":["../../../../src/components/pro/Kanban/utils.ts"],"sourcesContent":["import type { KanbanCard, KanbanCardMove, KanbanId, KanbanLocation } from \"./types\";\n\nexport function idsEqual(a: KanbanId | undefined, b: KanbanId | undefined): boolean {\n return a === b;\n}\n\nexport function cardsAt(\n cards: readonly KanbanCard[],\n columnId: KanbanId,\n laneId?: KanbanId,\n): KanbanCard[] {\n return cards.filter(card => idsEqual(card.columnId, columnId) && idsEqual(card.laneId, laneId));\n}\n\nexport function getCardLocation(cards: readonly KanbanCard[], cardId: KanbanId): KanbanLocation | null {\n const card = cards.find(item => idsEqual(item.id, cardId));\n if (!card) return null;\n return {\n columnId: card.columnId,\n laneId: card.laneId,\n index: cardsAt(cards, card.columnId, card.laneId).findIndex(item => idsEqual(item.id, cardId)),\n };\n}\n\n/**\n * Pure immutable card move. `to.index` is the insertion index in the target\n * cell after the moving card has been removed, which makes same-cell sorting\n * and cross-column/lane moves follow one rule.\n */\nexport function moveKanbanCard(\n cards: readonly KanbanCard[],\n cardId: KanbanId,\n to: KanbanLocation,\n): KanbanCard[] {\n const moving = cards.find(card => idsEqual(card.id, cardId));\n if (!moving) return [...cards];\n\n const without = cards.filter(card => !idsEqual(card.id, cardId));\n const targetCards = cardsAt(without, to.columnId, to.laneId);\n const index = Math.max(0, Math.min(to.index, targetCards.length));\n const nextCard: KanbanCard = { ...moving, columnId: to.columnId };\n const originalGlobalIndex = cards.findIndex(card => idsEqual(card.id, cardId));\n if (to.laneId === undefined) delete nextCard.laneId;\n else nextCard.laneId = to.laneId;\n\n if (index === targetCards.length) {\n const lastTarget = targetCards[targetCards.length - 1];\n const globalIndex = lastTarget\n ? without.findIndex(card => idsEqual(card.id, lastTarget.id)) + 1\n : Math.min(originalGlobalIndex, without.length);\n const result = [...without];\n result.splice(globalIndex, 0, nextCard);\n return result;\n }\n\n const beforeId = targetCards[index].id;\n const globalIndex = without.findIndex(card => idsEqual(card.id, beforeId));\n const result = [...without];\n result.splice(globalIndex, 0, nextCard);\n return result;\n}\n\nexport function createCardMove(\n cards: readonly KanbanCard[],\n cardId: KanbanId,\n to: KanbanLocation,\n): KanbanCardMove | null {\n const card = cards.find(item => idsEqual(item.id, cardId));\n const from = getCardLocation(cards, cardId);\n if (!card || !from) return null;\n return { card, from, to, cards: moveKanbanCard(cards, cardId, to) };\n}\n\nexport function locationEquals(a: KanbanLocation | null, b: KanbanLocation | null): boolean {\n return !!a && !!b && idsEqual(a.columnId, b.columnId) && idsEqual(a.laneId, b.laneId) && a.index === b.index;\n}\n\nexport function idText(id: KanbanId | undefined): string {\n return id === undefined ? \"\" : String(id);\n}\n"],"mappings":";AAEA,SAAgB,EAAS,GAAyB,GAAkC;CAClF,OAAO,MAAM;AACf;AAEA,SAAgB,EACd,GACA,GACA,GACc;CACd,OAAO,EAAM,QAAO,MAAQ,EAAS,EAAK,UAAU,CAAQ,KAAK,EAAS,EAAK,QAAQ,CAAM,CAAC;AAChG;AAEA,SAAgB,EAAgB,GAA8B,GAAyC;CACrG,IAAM,IAAO,EAAM,MAAK,MAAQ,EAAS,EAAK,IAAI,CAAM,CAAC;CAEzD,OADK,IACE;EACL,UAAU,EAAK;EACf,QAAQ,EAAK;EACb,OAAO,EAAQ,GAAO,EAAK,UAAU,EAAK,MAAM,CAAC,CAAC,WAAU,MAAQ,EAAS,EAAK,IAAI,CAAM,CAAC;CAC/F,IALkB;AAMpB;AAOA,SAAgB,EACd,GACA,GACA,GACc;CACd,IAAM,IAAS,EAAM,MAAK,MAAQ,EAAS,EAAK,IAAI,CAAM,CAAC;CAC3D,IAAI,CAAC,GAAQ,OAAO,CAAC,GAAG,CAAK;CAE7B,IAAM,IAAU,EAAM,QAAO,MAAQ,CAAC,EAAS,EAAK,IAAI,CAAM,CAAC,GACzD,IAAc,EAAQ,GAAS,EAAG,UAAU,EAAG,MAAM,GACrD,IAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,EAAG,OAAO,EAAY,MAAM,CAAC,GAC1D,IAAuB;EAAE,GAAG;EAAQ,UAAU,EAAG;CAAS,GAC1D,IAAsB,EAAM,WAAU,MAAQ,EAAS,EAAK,IAAI,CAAM,CAAC;CAI7E,IAHI,EAAG,WAAW,KAAA,IAAW,OAAO,EAAS,SACxC,EAAS,SAAS,EAAG,QAEtB,MAAU,EAAY,QAAQ;EAChC,IAAM,IAAa,EAAY,EAAY,SAAS,IAC9C,IAAc,IAChB,EAAQ,WAAU,MAAQ,EAAS,EAAK,IAAI,EAAW,EAAE,CAAC,IAAI,IAC9D,KAAK,IAAI,GAAqB,EAAQ,MAAM,GAC1C,IAAS,CAAC,GAAG,CAAO;EAE1B,OADA,EAAO,OAAO,GAAa,GAAG,CAAQ,GAC/B;CACT;CAEA,IAAM,IAAW,EAAY,EAAM,CAAC,IAC9B,IAAc,EAAQ,WAAU,MAAQ,EAAS,EAAK,IAAI,CAAQ,CAAC,GACnE,IAAS,CAAC,GAAG,CAAO;CAE1B,OADA,EAAO,OAAO,GAAa,GAAG,CAAQ,GAC/B;AACT;AAEA,SAAgB,EACd,GACA,GACA,GACuB;CACvB,IAAM,IAAO,EAAM,MAAK,MAAQ,EAAS,EAAK,IAAI,CAAM,CAAC,GACnD,IAAO,EAAgB,GAAO,CAAM;CAE1C,OADI,CAAC,KAAQ,CAAC,IAAa,OACpB;EAAE;EAAM;EAAM;EAAI,OAAO,EAAe,GAAO,GAAQ,CAAE;CAAE;AACpE;AAEA,SAAgB,EAAe,GAA0B,GAAmC;CAC1F,OAAO,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAS,EAAE,UAAU,EAAE,QAAQ,KAAK,EAAS,EAAE,QAAQ,EAAE,MAAM,KAAK,EAAE,UAAU,EAAE;AACzG;AAEA,SAAgB,EAAO,GAAkC;CACvD,OAAO,MAAO,KAAA,IAAY,KAAK,OAAO,CAAE;AAC1C"}
|