@composy/kanban-core 0.0.1 → 0.0.2
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/README.md +171 -37
- package/dist/index.css +114 -114
- package/dist/index.js +221 -126
- package/dist/index.js.map +1 -1
- package/dist/index.min.css +1 -1
- package/dist/index.min.js +758 -1
- package/dist/index.min.js.map +1 -0
- package/es/.dts-output-manifest.json +1 -0
- package/es/.dts.tsbuildinfo +1 -0
- package/es/core/ColumnManager.d.ts +4 -3
- package/es/core/ColumnManager.js +43 -18
- package/es/core/ColumnManager.js.map +1 -1
- package/es/core/DragController.d.ts +1 -2
- package/es/core/DragController.js +11 -1
- package/es/core/DragController.js.map +1 -1
- package/es/core/EventEmitter.d.ts +0 -1
- package/es/core/EventEmitter.js +8 -3
- package/es/core/EventEmitter.js.map +1 -1
- package/es/core/FilterEngine.d.ts +1 -2
- package/es/core/FilterEngine.js +10 -5
- package/es/core/FilterEngine.js.map +1 -1
- package/es/core/KanbanBoard.d.ts +3 -3
- package/es/core/KanbanBoard.js +61 -15
- package/es/core/KanbanBoard.js.map +1 -1
- package/es/core/Renderer.d.ts +2 -3
- package/es/core/Renderer.js +11 -7
- package/es/core/Renderer.js.map +1 -1
- package/es/core/index.d.ts +2 -3
- package/es/core/index.js +1 -1
- package/es/index.d.ts +3 -4
- package/es/index.js +2 -2
- package/es/styles/kanban.css +114 -114
- package/es/types/index.d.ts +3 -4
- package/es/types/index.js +1 -1
- package/es/utils/dom.d.ts +0 -1
- package/es/utils/dom.js +1 -1
- package/es/utils/dom.js.map +1 -1
- package/es/utils/id.d.ts +0 -1
- package/es/utils/id.js +1 -1
- package/es/utils/id.js.map +1 -1
- package/es/utils/index.d.ts +1 -2
- package/es/utils/index.js +1 -1
- package/es/utils/index.js.map +1 -1
- package/es/version.d.ts +0 -1
- package/es/version.js +1 -1
- package/es/version.js.map +1 -1
- package/esm/core/ColumnManager.js +43 -18
- package/esm/core/ColumnManager.js.map +1 -1
- package/esm/core/DragController.js +11 -1
- package/esm/core/DragController.js.map +1 -1
- package/esm/core/EventEmitter.js +8 -3
- package/esm/core/EventEmitter.js.map +1 -1
- package/esm/core/FilterEngine.js +10 -5
- package/esm/core/FilterEngine.js.map +1 -1
- package/esm/core/KanbanBoard.js +63 -17
- package/esm/core/KanbanBoard.js.map +1 -1
- package/esm/core/Renderer.js +11 -7
- package/esm/core/Renderer.js.map +1 -1
- package/esm/index.js +4 -4
- package/esm/styles/kanban.less +357 -339
- package/esm/utils/dom.js +1 -1
- package/esm/utils/dom.js.map +1 -1
- package/esm/utils/id.js +1 -1
- package/esm/utils/id.js.map +1 -1
- package/esm/utils/index.js +2 -2
- package/esm/utils/index.js.map +1 -1
- package/esm/version.js +1 -1
- package/esm/version.js.map +1 -1
- package/lib/core/ColumnManager.cjs +43 -18
- package/lib/core/ColumnManager.cjs.map +1 -1
- package/{esm/core/ColumnManager.d.ts → lib/core/ColumnManager.d.cts} +4 -3
- package/lib/core/DragController.cjs +11 -1
- package/lib/core/DragController.cjs.map +1 -1
- package/{esm/core/DragController.d.ts → lib/core/DragController.d.cts} +1 -2
- package/lib/core/EventEmitter.cjs +8 -3
- package/lib/core/EventEmitter.cjs.map +1 -1
- package/lib/core/{EventEmitter.d.ts → EventEmitter.d.cts} +0 -1
- package/lib/core/FilterEngine.cjs +10 -5
- package/lib/core/FilterEngine.cjs.map +1 -1
- package/{esm/core/FilterEngine.d.ts → lib/core/FilterEngine.d.cts} +1 -2
- package/lib/core/KanbanBoard.cjs +61 -15
- package/lib/core/KanbanBoard.cjs.map +1 -1
- package/{esm/core/KanbanBoard.d.ts → lib/core/KanbanBoard.d.cts} +3 -3
- package/lib/core/Renderer.cjs +11 -7
- package/lib/core/Renderer.cjs.map +1 -1
- package/{esm/core/Renderer.d.ts → lib/core/Renderer.d.cts} +2 -3
- package/lib/core/index.cjs +1 -1
- package/{esm/core/index.d.ts → lib/core/index.d.cts} +2 -3
- package/lib/index.cjs +2 -2
- package/lib/{index.d.ts → index.d.cts} +3 -4
- package/lib/styles/kanban.css +114 -114
- package/lib/types/index.cjs +1 -1
- package/{esm/types/index.d.ts → lib/types/index.d.cts} +3 -4
- package/lib/utils/dom.cjs +1 -1
- package/lib/utils/dom.cjs.map +1 -1
- package/lib/utils/{dom.d.ts → dom.d.cts} +0 -1
- package/lib/utils/id.cjs +1 -1
- package/lib/utils/id.cjs.map +1 -1
- package/{esm/utils/id.d.ts → lib/utils/id.d.cts} +0 -1
- package/lib/utils/index.cjs +1 -1
- package/lib/utils/index.cjs.map +1 -1
- package/lib/utils/{index.d.ts → index.d.cts} +1 -2
- package/lib/version.cjs +1 -1
- package/lib/version.cjs.map +1 -1
- package/{esm/version.d.ts → lib/version.d.cts} +0 -1
- package/package.json +23 -21
- package/es/core/ColumnManager.d.ts.map +0 -1
- package/es/core/DragController.d.ts.map +0 -1
- package/es/core/EventEmitter.d.ts.map +0 -1
- package/es/core/FilterEngine.d.ts.map +0 -1
- package/es/core/KanbanBoard.d.ts.map +0 -1
- package/es/core/Renderer.d.ts.map +0 -1
- package/es/core/index.d.ts.map +0 -1
- package/es/index.d.ts.map +0 -1
- package/es/types/index.d.ts.map +0 -1
- package/es/utils/dom.d.ts.map +0 -1
- package/es/utils/id.d.ts.map +0 -1
- package/es/utils/index.d.ts.map +0 -1
- package/es/version.d.ts.map +0 -1
- package/esm/core/ColumnManager.d.ts.map +0 -1
- package/esm/core/DragController.d.ts.map +0 -1
- package/esm/core/EventEmitter.d.ts +0 -35
- package/esm/core/EventEmitter.d.ts.map +0 -1
- package/esm/core/FilterEngine.d.ts.map +0 -1
- package/esm/core/KanbanBoard.d.ts.map +0 -1
- package/esm/core/Renderer.d.ts.map +0 -1
- package/esm/core/index.d.ts.map +0 -1
- package/esm/core/index.js +0 -17
- package/esm/index.d.ts +0 -15
- package/esm/index.d.ts.map +0 -1
- package/esm/types/index.d.ts.map +0 -1
- package/esm/types/index.js +0 -10
- package/esm/utils/dom.d.ts +0 -24
- package/esm/utils/dom.d.ts.map +0 -1
- package/esm/utils/id.d.ts.map +0 -1
- package/esm/utils/index.d.ts +0 -25
- package/esm/utils/index.d.ts.map +0 -1
- package/esm/version.d.ts.map +0 -1
- package/lib/core/ColumnManager.d.ts +0 -99
- package/lib/core/DragController.d.ts +0 -55
- package/lib/core/FilterEngine.d.ts +0 -45
- package/lib/core/KanbanBoard.d.ts +0 -152
- package/lib/core/Renderer.d.ts +0 -59
- package/lib/core/index.d.ts +0 -11
- package/lib/types/index.d.ts +0 -209
- package/lib/utils/id.d.ts +0 -9
- package/lib/version.d.ts +0 -6
package/README.md
CHANGED
|
@@ -1,37 +1,171 @@
|
|
|
1
|
-
# @composy/kanban-core
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
npm install @composy/kanban-core
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
```
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
├──
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
1
|
+
# @composy/kanban-core
|
|
2
|
+
|
|
3
|
+
基于实际源码能力构建的 **看板视图核心库**,是 LDesign Kanban
|
|
4
|
+
workspace 的框架无关 TypeScript 核心。核心由 `KanbanBoard`
|
|
5
|
+
门面类统一编排 5 个子系统:`ColumnManager`(列与卡片数据管理)、`DragController`(卡片/列拖拽)、`FilterEngine`(筛选与搜索)、`Renderer`(DOM 渲染)、`EventEmitter`(事件总线)。内置卡片增删改移、跨列拖拽、列折叠、WIP 限制、标签、优先级、多条件筛选、搜索、看板数据导入导出、生命周期事件与自定义渲染器等能力,适用于任务管理、项目管理等看板场景。
|
|
6
|
+
|
|
7
|
+
## 安装
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# pnpm
|
|
11
|
+
pnpm add @composy/kanban-core
|
|
12
|
+
|
|
13
|
+
# npm
|
|
14
|
+
npm install @composy/kanban-core
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
> 框架适配(如 Vue 3)请安装对应的 `@composy/kanban-vue` 适配包,直接消费本核心模块。
|
|
18
|
+
|
|
19
|
+
## 目录结构
|
|
20
|
+
|
|
21
|
+
基于真实 `src/` 布局:
|
|
22
|
+
|
|
23
|
+
```
|
|
24
|
+
src/
|
|
25
|
+
├── index.ts # 入口,聚合导出
|
|
26
|
+
├── core/ # KanbanBoard / EventEmitter / ColumnManager / DragController / FilterEngine / Renderer
|
|
27
|
+
├── types/index.ts # Label/Card/Column/Board/KanbanOptions/KanbanEventMap/FilterCriteria/BoardData
|
|
28
|
+
├── styles/kanban.less # 看板样式(编译为 index.css)
|
|
29
|
+
├── version.ts # VERSION 常量
|
|
30
|
+
└── utils/ # dom.ts / id.ts
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 核心 API 详表
|
|
34
|
+
|
|
35
|
+
### 类与工厂
|
|
36
|
+
|
|
37
|
+
| 名称 | 类型 | 签名 | 用途 |
|
|
38
|
+
| ------------------- | ---- | --------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
39
|
+
| `KanbanBoard` | 类 | `new KanbanBoard(options: KanbanOptions)` | 看板主类:编排列/卡片管理、拖拽、筛选、渲染、事件,对外暴露完整 API |
|
|
40
|
+
| `createKanbanBoard` | 函数 | `(options: KanbanOptions) => KanbanBoard` | 创建看板实例的工厂函数 |
|
|
41
|
+
| `EventEmitter` | 类 | `new EventEmitter()` | 轻量事件总线,提供 `on/once/off/emit/removeAll` |
|
|
42
|
+
| `ColumnManager` | 类 | `new ColumnManager(events: EventEmitter)` | 列与卡片数据的增删改查、移动、折叠等管理 |
|
|
43
|
+
| `DragController` | 类 | `new DragController(events: EventEmitter, classPrefix: string)` | 卡片/列拖拽交互控制,跨列拖放 |
|
|
44
|
+
| `FilterEngine` | 类 | `new FilterEngine(events: EventEmitter)` | 按多条件筛选卡片、关键词搜索、清除筛选 |
|
|
45
|
+
| `Renderer` | 类 | `new Renderer(container, events, dragController, options)` | 将列/卡片渲染为 DOM,支持自定义卡片与列头渲染器 |
|
|
46
|
+
|
|
47
|
+
### KanbanBoard 实例方法(真实签名)
|
|
48
|
+
|
|
49
|
+
| 名称 | 类型 | 签名 | 用途 |
|
|
50
|
+
| ------------------------------------------------------ | ---- | ----------------------------------------------------------------------------------- | --------------------------------------------------------- |
|
|
51
|
+
| `addColumn` / `removeColumn` | 方法 | `(partial: Partial<Column>) => Column` / `(id: string) => Column \| undefined` | 添加并重渲染 / 移除列 |
|
|
52
|
+
| `updateColumn` / `moveColumn` / `toggleColumnCollapse` | 方法 | `(id, changes?) / (id, toIndex) / (id) => void` | 更新列 / 移动列顺序 / 折叠展开 |
|
|
53
|
+
| `getColumns` / `getColumn` | 方法 | `() => Column[]` / `(id: string) => Column \| undefined` | 获取全部/单列 |
|
|
54
|
+
| `addCard` / `removeCard` | 方法 | `(columnId, partial) => Card \| undefined` / `(cardId) => Card \| undefined` | 向指定列添加 / 移除卡片 |
|
|
55
|
+
| `updateCard` / `moveCard` | 方法 | `(cardId, changes) / (cardId, toColumnId, toIndex) => void` | 更新 / 移动卡片(支持跨列) |
|
|
56
|
+
| `getCard` / `getAllCards` / `getCardCount` | 方法 | `(cardId: string) => Card \| undefined` / `() => Card[]` / `() => number` | 卡片查询 |
|
|
57
|
+
| `filter` / `search` / `clearFilter` | 方法 | `(criteria: FilterCriteria) => void` / `(keyword: string) => Card[]` / `() => void` | 按条件筛选 / 关键词搜索 / 清除筛选 |
|
|
58
|
+
| `exportData` / `importData` | 方法 | `() => BoardData` / `(data: BoardData) => void` | 导出看板数据(含版本/标题/列/标签/导出时间) / 导入并渲染 |
|
|
59
|
+
| `on` / `once` / `off` | 方法 | `(event: string, handler: EventHandler) => () => void` | 事件监听/一次性/移除 |
|
|
60
|
+
| `getLabels` / `addLabel` / `removeLabel` | 方法 | `() => Label[]` / `(label: Label) => void` / `(id: string) => void` | 标签管理 |
|
|
61
|
+
| `getBoardElement` | 方法 | `() => HTMLElement \| null` | 获取看板根 DOM 元素 |
|
|
62
|
+
| `getOptions` | 方法 | `() => Readonly<KanbanOptions>` | 获取配置快照 |
|
|
63
|
+
| `destroy` / `isDestroyed` | 方法 | `() => void` / `() => boolean` | 销毁实例 / 是否已销毁 |
|
|
64
|
+
|
|
65
|
+
### 类型
|
|
66
|
+
|
|
67
|
+
| 名称 | 类型 | 签名 | 用途 |
|
|
68
|
+
| ------------------------------------- | ---- | ------------------------------------------------- | ----------------------------------------------------------------------------- |
|
|
69
|
+
| `Board` / `Column` / `Card` / `Label` | 接口 | — | 看板数据模型(看板/列/卡片/标签) |
|
|
70
|
+
| `BoardData` | 接口 | `{ version; title; columns; labels; exportedAt }` | 看板导入导出数据格式 |
|
|
71
|
+
| `KanbanOptions` | 接口 | — | 配置项:容器/列/标签/标题/拖拽开关/搜索/渲染器/各类回调 |
|
|
72
|
+
| `KanbanEventMap` | 接口 | — | 事件映射:ready/destroy/error、card:_, column:_, filter:_, data:_ 等 |
|
|
73
|
+
| `FilterCriteria` | 接口 | — | 筛选条件:keyword/labelIds/assignees/priorities/columnIds/dueDateRange/custom |
|
|
74
|
+
| `VERSION` | 常量 | `string` | 包版本号,随 `exportData` 写入 |
|
|
75
|
+
|
|
76
|
+
## 使用示例
|
|
77
|
+
|
|
78
|
+
基于真实导出,创建看板并操作数据与事件:
|
|
79
|
+
|
|
80
|
+
```ts
|
|
81
|
+
import { createKanbanBoard } from '@composy/kanban-core'
|
|
82
|
+
|
|
83
|
+
const board = createKanbanBoard({
|
|
84
|
+
container: '#board', // CSS 选择器或 HTMLElement
|
|
85
|
+
title: '迭代看板',
|
|
86
|
+
draggable: true,
|
|
87
|
+
crossColumnDrag: true,
|
|
88
|
+
searchable: true,
|
|
89
|
+
columns: [
|
|
90
|
+
{ id: 'todo', title: '待办', order: 0 },
|
|
91
|
+
{ id: 'done', title: '已完成', order: 1 },
|
|
92
|
+
],
|
|
93
|
+
onCardClick: card => window.dispatchEvent(new CustomEvent('kanban-card-click', { detail: card })),
|
|
94
|
+
onCardMove: (card, from, to, _index) =>
|
|
95
|
+
window.dispatchEvent(new CustomEvent('kanban-card-move', { detail: { card, from, to } })),
|
|
96
|
+
})
|
|
97
|
+
|
|
98
|
+
// 添加列与卡片
|
|
99
|
+
board.addColumn({ id: 'doing', title: '进行中', order: 1, wipLimit: 3 })
|
|
100
|
+
board.addCard('todo', { id: 'c1', title: '设计评审', priority: 'high' })
|
|
101
|
+
|
|
102
|
+
// 跨列移动、折叠
|
|
103
|
+
board.moveCard('c1', 'doing', 0)
|
|
104
|
+
board.toggleColumnCollapse('todo')
|
|
105
|
+
|
|
106
|
+
// 筛选与搜索
|
|
107
|
+
board.search('设计')
|
|
108
|
+
board.filter({ priorities: ['high'], columnIds: ['todo'] })
|
|
109
|
+
board.clearFilter()
|
|
110
|
+
|
|
111
|
+
// 事件监听
|
|
112
|
+
const offReady = board.on('ready', () =>
|
|
113
|
+
document.documentElement.setAttribute('data-kanban-ready', 'true')
|
|
114
|
+
)
|
|
115
|
+
offReady()
|
|
116
|
+
|
|
117
|
+
// 导入导出
|
|
118
|
+
const data = board.exportData()
|
|
119
|
+
board.importData(data)
|
|
120
|
+
|
|
121
|
+
// 销毁
|
|
122
|
+
board.destroy()
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
### Data normalization and boundaries
|
|
126
|
+
|
|
127
|
+
- Imported and initial columns are cloned into the core model. Column and card order values are
|
|
128
|
+
normalized before rendering and moving.
|
|
129
|
+
- moveColumn and moveCard clamp an out-of-range index to the valid destination range. Move events
|
|
130
|
+
and callbacks report the effective index.
|
|
131
|
+
- importData rejects a payload without a columns array and emits the error event instead of mutating
|
|
132
|
+
the board.
|
|
133
|
+
- Invalid card or range dates do not match dueDateRange filters. An empty search clears the active
|
|
134
|
+
search criteria.
|
|
135
|
+
|
|
136
|
+
## 构建脚本 & 验证命令
|
|
137
|
+
|
|
138
|
+
```bash
|
|
139
|
+
pnpm build # 构建产物(es/lib/esm/dist,含 index.css)
|
|
140
|
+
pnpm type-check # 类型检查
|
|
141
|
+
pnpm lint / lint:check / lint:fix # 代码规范(/0-warning 严格 / 自动修复)
|
|
142
|
+
pnpm test # 单元测试(可加 --watch/--coverage/--changed/--failed/--ui)
|
|
143
|
+
pnpm release # 发布
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
## 产物说明
|
|
147
|
+
|
|
148
|
+
构建由 `@composy/builder`(`ldesign-builder build`)驱动,产出多格式产物:
|
|
149
|
+
|
|
150
|
+
| 目录 | 说明 | package.json 入口 |
|
|
151
|
+
| ------- | -------------------------------------------------- | ------------------------------------- |
|
|
152
|
+
| `es/` | ES Modules(含 `.d.ts` 类型声明) | `module` / `exports.import` / `types` |
|
|
153
|
+
| `lib/` | CommonJS(`.cjs`) | `main` / `exports.require` |
|
|
154
|
+
| `esm/` | ESM 兼容产物 | 随 `exports` 子路径分发 |
|
|
155
|
+
| `dist/` | 浏览器压缩产物(含 `index.css` / `index.min.css`) | `unpkg` / `jsdelivr` / `browser` |
|
|
156
|
+
|
|
157
|
+
`sideEffects: false` 便于 tree-shaking。`exports`
|
|
158
|
+
提供子路径:`./core`、`./types`、`./utils`(均支持通配符深层路径)。`src/styles/kanban.less`
|
|
159
|
+
编译后通过 `style` 字段与 `./dist/index.css`、`./dist/index.min.css` 子路径提供样式。
|
|
160
|
+
|
|
161
|
+
## 备注
|
|
162
|
+
|
|
163
|
+
- **框架无关**:本包为纯核心逻辑,不绑定 React/Vue;框架适配由上层 `@composy/kanban-vue` 等提供。
|
|
164
|
+
- **peerDeps**:无运行期第三方运行时依赖,`devDependencies`
|
|
165
|
+
仅含构建/测试工具(`@composy/builder`、`@composy/testing`、`@composy/release`、eslint、tsc)。
|
|
166
|
+
- **入站密钥**:`publishConfig.registry` 指向私有 npm 源
|
|
167
|
+
`http://npm.longrise.cn:6286/`,发布时按该源执行。
|
|
168
|
+
- **样式引入**:使用本包需额外引入编译产物 CSS(如
|
|
169
|
+
`@composy/kanban-core/dist/index.css`),入口 JS 中的 Less 导入由 Builder 在构建时提取。
|
|
170
|
+
- **自定义渲染**:通过 `KanbanOptions.cardRenderer` / `columnHeaderRenderer`
|
|
171
|
+
可接管卡片与列头 DOM 渲染。
|
package/dist/index.css
CHANGED
|
@@ -2,140 +2,140 @@
|
|
|
2
2
|
/* @composy/kanban-core - Default Styles */
|
|
3
3
|
.kanban-board {
|
|
4
4
|
width: 100%;
|
|
5
|
-
min-height:
|
|
5
|
+
min-height: var(--ld-px-400);
|
|
6
6
|
overflow-x: auto;
|
|
7
7
|
overflow-y: hidden;
|
|
8
8
|
max-width: 100%;
|
|
9
9
|
}
|
|
10
10
|
.kanban-columns {
|
|
11
11
|
display: flex;
|
|
12
|
-
gap:
|
|
13
|
-
padding:
|
|
12
|
+
gap: var(--ld-px-16);
|
|
13
|
+
padding: var(--ld-px-8);
|
|
14
14
|
min-height: 100%;
|
|
15
15
|
align-items: flex-start;
|
|
16
16
|
}
|
|
17
17
|
/* Column */
|
|
18
18
|
.kanban-column {
|
|
19
|
-
flex: 0 0
|
|
20
|
-
max-width:
|
|
21
|
-
background:
|
|
22
|
-
border-radius:
|
|
19
|
+
flex: 0 0 var(--ld-px-280);
|
|
20
|
+
max-width: var(--ld-px-280);
|
|
21
|
+
background: var(--ld-bg-surface);
|
|
22
|
+
border-radius: var(--ld-px-8);
|
|
23
23
|
display: flex;
|
|
24
24
|
flex-direction: column;
|
|
25
|
-
max-height: calc(100vh -
|
|
25
|
+
max-height: calc(100vh - var(--ld-px-200));
|
|
26
26
|
transition: opacity 0.2s, box-shadow 0.2s;
|
|
27
27
|
}
|
|
28
28
|
.kanban-column--collapsed {
|
|
29
|
-
flex: 0 0
|
|
30
|
-
max-width:
|
|
31
|
-
min-height:
|
|
29
|
+
flex: 0 0 var(--ld-px-48);
|
|
30
|
+
max-width: var(--ld-px-48);
|
|
31
|
+
min-height: var(--ld-px-200);
|
|
32
32
|
}
|
|
33
33
|
.kanban-column--dragging {
|
|
34
34
|
opacity: 0.5;
|
|
35
35
|
}
|
|
36
36
|
.kanban-column--drag-over {
|
|
37
|
-
box-shadow: 0 0 0
|
|
37
|
+
box-shadow: 0 0 0 var(--ld-px-2) var(--ld-primary-500);
|
|
38
38
|
}
|
|
39
39
|
/* Column Header */
|
|
40
40
|
.kanban-column-header {
|
|
41
41
|
display: flex;
|
|
42
42
|
align-items: center;
|
|
43
|
-
gap:
|
|
44
|
-
padding:
|
|
45
|
-
border-bottom:
|
|
43
|
+
gap: var(--ld-px-6);
|
|
44
|
+
padding: var(--ld-px-10) var(--ld-px-12);
|
|
45
|
+
border-bottom: var(--ld-px-1) solid var(--ld-border);
|
|
46
46
|
-webkit-user-select: none;
|
|
47
47
|
-moz-user-select: none;
|
|
48
48
|
user-select: none;
|
|
49
49
|
}
|
|
50
50
|
.kanban-column-drag-handle {
|
|
51
51
|
cursor: grab;
|
|
52
|
-
color:
|
|
53
|
-
font-size:
|
|
54
|
-
letter-spacing: -
|
|
52
|
+
color: var(--ld-text-secondary);
|
|
53
|
+
font-size: var(--ld-px-12);
|
|
54
|
+
letter-spacing: calc(-1 * var(--ld-px-3));
|
|
55
55
|
line-height: 1;
|
|
56
|
-
padding:
|
|
56
|
+
padding: var(--ld-px-2) 0;
|
|
57
57
|
}
|
|
58
58
|
.kanban-column-drag-handle:active {
|
|
59
59
|
cursor: grabbing;
|
|
60
60
|
}
|
|
61
61
|
.kanban-column-color {
|
|
62
|
-
width:
|
|
63
|
-
height:
|
|
64
|
-
border-radius:
|
|
62
|
+
width: var(--ld-px-12);
|
|
63
|
+
height: var(--ld-px-12);
|
|
64
|
+
border-radius: var(--ld-px-3);
|
|
65
65
|
flex-shrink: 0;
|
|
66
66
|
}
|
|
67
67
|
.kanban-column-title {
|
|
68
|
-
font-size:
|
|
68
|
+
font-size: var(--ld-px-14);
|
|
69
69
|
font-weight: 600;
|
|
70
|
-
color:
|
|
70
|
+
color: var(--ld-text-primary);
|
|
71
71
|
flex: 1;
|
|
72
72
|
overflow: hidden;
|
|
73
73
|
text-overflow: ellipsis;
|
|
74
74
|
white-space: nowrap;
|
|
75
75
|
}
|
|
76
76
|
.kanban-column-count {
|
|
77
|
-
font-size:
|
|
78
|
-
color:
|
|
79
|
-
background:
|
|
80
|
-
border-radius:
|
|
81
|
-
padding:
|
|
77
|
+
font-size: var(--ld-px-12);
|
|
78
|
+
color: var(--ld-text-secondary);
|
|
79
|
+
background: var(--ld-bg-hover);
|
|
80
|
+
border-radius: var(--ld-px-10);
|
|
81
|
+
padding: var(--ld-px-1) var(--ld-px-8);
|
|
82
82
|
flex-shrink: 0;
|
|
83
83
|
}
|
|
84
84
|
.kanban-column-count--limit {
|
|
85
|
-
background:
|
|
86
|
-
color:
|
|
85
|
+
background: var(--ld-danger-50);
|
|
86
|
+
color: var(--ld-danger-700);
|
|
87
87
|
}
|
|
88
88
|
.kanban-column-collapse-btn,
|
|
89
89
|
.kanban-column-actions-btn {
|
|
90
90
|
background: none;
|
|
91
91
|
border: none;
|
|
92
92
|
cursor: pointer;
|
|
93
|
-
color:
|
|
94
|
-
font-size:
|
|
95
|
-
padding:
|
|
96
|
-
border-radius:
|
|
93
|
+
color: var(--ld-text-secondary);
|
|
94
|
+
font-size: var(--ld-px-12);
|
|
95
|
+
padding: var(--ld-px-2) var(--ld-px-4);
|
|
96
|
+
border-radius: var(--ld-px-3);
|
|
97
97
|
line-height: 1;
|
|
98
98
|
}
|
|
99
99
|
.kanban-column-collapse-btn:hover,
|
|
100
100
|
.kanban-column-actions-btn:hover {
|
|
101
|
-
background:
|
|
102
|
-
color:
|
|
101
|
+
background: var(--ld-bg-hover);
|
|
102
|
+
color: var(--ld-text-primary);
|
|
103
103
|
}
|
|
104
104
|
/* Column Body */
|
|
105
105
|
.kanban-column-body {
|
|
106
106
|
flex: 1;
|
|
107
107
|
overflow-y: auto;
|
|
108
|
-
padding:
|
|
109
|
-
min-height:
|
|
108
|
+
padding: var(--ld-px-8);
|
|
109
|
+
min-height: var(--ld-px-40);
|
|
110
110
|
}
|
|
111
111
|
.kanban-column-body--drag-over {
|
|
112
|
-
background:
|
|
113
|
-
border-radius: 0 0
|
|
112
|
+
background: var(--ld-primary-50);
|
|
113
|
+
border-radius: 0 0 var(--ld-px-8) var(--ld-px-8);
|
|
114
114
|
}
|
|
115
115
|
/* Placeholder */
|
|
116
116
|
.kanban-placeholder {
|
|
117
|
-
background:
|
|
118
|
-
border:
|
|
119
|
-
border-radius:
|
|
120
|
-
margin-bottom:
|
|
121
|
-
min-height:
|
|
117
|
+
background: var(--ld-primary-50);
|
|
118
|
+
border: var(--ld-px-2) dashed var(--ld-primary-300);
|
|
119
|
+
border-radius: var(--ld-px-6);
|
|
120
|
+
margin-bottom: var(--ld-px-8);
|
|
121
|
+
min-height: var(--ld-px-40);
|
|
122
122
|
transition: height 0.15s ease;
|
|
123
123
|
}
|
|
124
124
|
/* Card */
|
|
125
125
|
.kanban-card {
|
|
126
|
-
background:
|
|
127
|
-
border-radius:
|
|
128
|
-
padding:
|
|
129
|
-
margin-bottom:
|
|
126
|
+
background: var(--ld-bg-container);
|
|
127
|
+
border-radius: var(--ld-px-6);
|
|
128
|
+
padding: var(--ld-px-10) var(--ld-px-12);
|
|
129
|
+
margin-bottom: var(--ld-px-8);
|
|
130
130
|
cursor: pointer;
|
|
131
|
-
box-shadow:
|
|
131
|
+
box-shadow: var(--ld-shadow-1);
|
|
132
132
|
transition: box-shadow 0.2s, transform 0.15s, opacity 0.2s;
|
|
133
|
-
border:
|
|
133
|
+
border: var(--ld-px-1) solid transparent;
|
|
134
134
|
position: relative;
|
|
135
135
|
}
|
|
136
136
|
.kanban-card:hover {
|
|
137
|
-
box-shadow:
|
|
138
|
-
border-color:
|
|
137
|
+
box-shadow: var(--ld-shadow-2);
|
|
138
|
+
border-color: var(--ld-border);
|
|
139
139
|
}
|
|
140
140
|
.kanban-card--dragging {
|
|
141
141
|
opacity: 0.4;
|
|
@@ -147,50 +147,50 @@
|
|
|
147
147
|
left: 0;
|
|
148
148
|
top: 0;
|
|
149
149
|
bottom: 0;
|
|
150
|
-
width:
|
|
151
|
-
border-radius:
|
|
150
|
+
width: var(--ld-px-3);
|
|
151
|
+
border-radius: var(--ld-px-6) 0 0 var(--ld-px-6);
|
|
152
152
|
}
|
|
153
153
|
.kanban-card-priority--low {
|
|
154
|
-
background:
|
|
154
|
+
background: var(--ld-success-500);
|
|
155
155
|
}
|
|
156
156
|
.kanban-card-priority--medium {
|
|
157
|
-
background:
|
|
157
|
+
background: var(--ld-warning-500);
|
|
158
158
|
}
|
|
159
159
|
.kanban-card-priority--high {
|
|
160
|
-
background:
|
|
160
|
+
background: var(--ld-danger-500);
|
|
161
161
|
}
|
|
162
162
|
.kanban-card-priority--urgent {
|
|
163
|
-
background:
|
|
163
|
+
background: var(--ld-danger-700);
|
|
164
164
|
}
|
|
165
165
|
/* Card Labels */
|
|
166
166
|
.kanban-card-labels {
|
|
167
167
|
display: flex;
|
|
168
168
|
flex-wrap: wrap;
|
|
169
|
-
gap:
|
|
170
|
-
margin-bottom:
|
|
169
|
+
gap: var(--ld-px-4);
|
|
170
|
+
margin-bottom: var(--ld-px-6);
|
|
171
171
|
}
|
|
172
172
|
.kanban-card-label {
|
|
173
173
|
display: inline-block;
|
|
174
|
-
padding:
|
|
175
|
-
border-radius:
|
|
176
|
-
font-size:
|
|
177
|
-
color:
|
|
174
|
+
padding: var(--ld-px-1) var(--ld-px-8);
|
|
175
|
+
border-radius: var(--ld-px-3);
|
|
176
|
+
font-size: var(--ld-px-11);
|
|
177
|
+
color: var(--ld-text-inverse);
|
|
178
178
|
font-weight: 500;
|
|
179
179
|
line-height: 1.6;
|
|
180
180
|
}
|
|
181
181
|
/* Card Title */
|
|
182
182
|
.kanban-card-title {
|
|
183
|
-
font-size:
|
|
183
|
+
font-size: var(--ld-px-14);
|
|
184
184
|
font-weight: 500;
|
|
185
|
-
color:
|
|
185
|
+
color: var(--ld-text-primary);
|
|
186
186
|
line-height: 1.4;
|
|
187
187
|
word-break: break-word;
|
|
188
188
|
}
|
|
189
189
|
/* Card Description */
|
|
190
190
|
.kanban-card-desc {
|
|
191
|
-
font-size:
|
|
192
|
-
color:
|
|
193
|
-
margin-top:
|
|
191
|
+
font-size: var(--ld-px-12);
|
|
192
|
+
color: var(--ld-text-secondary);
|
|
193
|
+
margin-top: var(--ld-px-4);
|
|
194
194
|
line-height: 1.4;
|
|
195
195
|
display: -webkit-box;
|
|
196
196
|
-webkit-line-clamp: 2;
|
|
@@ -202,26 +202,26 @@
|
|
|
202
202
|
display: flex;
|
|
203
203
|
align-items: center;
|
|
204
204
|
justify-content: space-between;
|
|
205
|
-
margin-top:
|
|
206
|
-
gap:
|
|
205
|
+
margin-top: var(--ld-px-8);
|
|
206
|
+
gap: var(--ld-px-8);
|
|
207
207
|
}
|
|
208
208
|
.kanban-card-assignees {
|
|
209
209
|
display: flex;
|
|
210
|
-
gap: -
|
|
210
|
+
gap: calc(-1 * var(--ld-px-4));
|
|
211
211
|
}
|
|
212
212
|
.kanban-card-avatar {
|
|
213
213
|
display: inline-flex;
|
|
214
214
|
align-items: center;
|
|
215
215
|
justify-content: center;
|
|
216
|
-
width:
|
|
217
|
-
height:
|
|
216
|
+
width: var(--ld-px-24);
|
|
217
|
+
height: var(--ld-px-24);
|
|
218
218
|
border-radius: 50%;
|
|
219
|
-
background:
|
|
220
|
-
color:
|
|
221
|
-
font-size:
|
|
219
|
+
background: var(--ld-bg-hover);
|
|
220
|
+
color: var(--ld-text-secondary);
|
|
221
|
+
font-size: var(--ld-px-11);
|
|
222
222
|
font-weight: 600;
|
|
223
|
-
border:
|
|
224
|
-
margin-left: -
|
|
223
|
+
border: var(--ld-px-2) solid var(--ld-text-inverse);
|
|
224
|
+
margin-left: calc(-1 * var(--ld-px-4));
|
|
225
225
|
}
|
|
226
226
|
.kanban-card-avatar:first-child {
|
|
227
227
|
margin-left: 0;
|
|
@@ -230,78 +230,78 @@
|
|
|
230
230
|
display: inline-flex;
|
|
231
231
|
align-items: center;
|
|
232
232
|
justify-content: center;
|
|
233
|
-
width:
|
|
234
|
-
height:
|
|
233
|
+
width: var(--ld-px-24);
|
|
234
|
+
height: var(--ld-px-24);
|
|
235
235
|
border-radius: 50%;
|
|
236
|
-
background:
|
|
237
|
-
color:
|
|
238
|
-
font-size:
|
|
236
|
+
background: var(--ld-gray-400);
|
|
237
|
+
color: var(--ld-text-secondary);
|
|
238
|
+
font-size: var(--ld-px-10);
|
|
239
239
|
font-weight: 600;
|
|
240
|
-
border:
|
|
241
|
-
margin-left: -
|
|
240
|
+
border: var(--ld-px-2) solid var(--ld-text-inverse);
|
|
241
|
+
margin-left: calc(-1 * var(--ld-px-4));
|
|
242
242
|
}
|
|
243
243
|
.kanban-card-due {
|
|
244
|
-
font-size:
|
|
245
|
-
color:
|
|
244
|
+
font-size: var(--ld-px-12);
|
|
245
|
+
color: var(--ld-text-secondary);
|
|
246
246
|
display: flex;
|
|
247
247
|
align-items: center;
|
|
248
|
-
gap:
|
|
248
|
+
gap: var(--ld-px-4);
|
|
249
249
|
}
|
|
250
250
|
.kanban-card-due--overdue {
|
|
251
|
-
color:
|
|
251
|
+
color: var(--ld-danger-500);
|
|
252
252
|
font-weight: 600;
|
|
253
253
|
}
|
|
254
254
|
/* Add Buttons */
|
|
255
255
|
.kanban-add-card {
|
|
256
|
-
padding: 0
|
|
256
|
+
padding: 0 var(--ld-px-4);
|
|
257
257
|
}
|
|
258
258
|
.kanban-add-card-btn {
|
|
259
259
|
width: 100%;
|
|
260
|
-
padding:
|
|
260
|
+
padding: var(--ld-px-6) var(--ld-px-8);
|
|
261
261
|
background: none;
|
|
262
262
|
border: none;
|
|
263
|
-
border-radius:
|
|
264
|
-
color:
|
|
265
|
-
font-size:
|
|
263
|
+
border-radius: var(--ld-px-6);
|
|
264
|
+
color: var(--ld-text-secondary);
|
|
265
|
+
font-size: var(--ld-px-13);
|
|
266
266
|
cursor: pointer;
|
|
267
267
|
text-align: left;
|
|
268
268
|
transition: background 0.15s, color 0.15s;
|
|
269
269
|
}
|
|
270
270
|
.kanban-add-card-btn:hover {
|
|
271
|
-
background:
|
|
272
|
-
color:
|
|
271
|
+
background: var(--ld-bg-hover);
|
|
272
|
+
color: var(--ld-text-primary);
|
|
273
273
|
}
|
|
274
274
|
.kanban-add-column {
|
|
275
|
-
flex: 0 0
|
|
275
|
+
flex: 0 0 var(--ld-px-280);
|
|
276
276
|
}
|
|
277
277
|
.kanban-add-column-btn {
|
|
278
278
|
width: 100%;
|
|
279
|
-
padding:
|
|
280
|
-
background:
|
|
281
|
-
border:
|
|
282
|
-
border-radius:
|
|
283
|
-
color:
|
|
284
|
-
font-size:
|
|
279
|
+
padding: var(--ld-px-10);
|
|
280
|
+
background: var(--ld-bg-surface-soft);
|
|
281
|
+
border: var(--ld-px-2) dashed var(--ld-gray-300);
|
|
282
|
+
border-radius: var(--ld-px-8);
|
|
283
|
+
color: var(--ld-text-secondary);
|
|
284
|
+
font-size: var(--ld-px-14);
|
|
285
285
|
cursor: pointer;
|
|
286
286
|
transition: background 0.15s, border-color 0.15s, color 0.15s;
|
|
287
287
|
}
|
|
288
288
|
.kanban-add-column-btn:hover {
|
|
289
|
-
background:
|
|
290
|
-
border-color:
|
|
291
|
-
color:
|
|
289
|
+
background: var(--ld-bg-hover);
|
|
290
|
+
border-color: var(--ld-gray-500);
|
|
291
|
+
color: var(--ld-text-primary);
|
|
292
292
|
}
|
|
293
293
|
/* Scrollbar */
|
|
294
294
|
.kanban-column-body::-webkit-scrollbar {
|
|
295
|
-
width:
|
|
295
|
+
width: var(--ld-px-6);
|
|
296
296
|
}
|
|
297
297
|
.kanban-column-body::-webkit-scrollbar-track {
|
|
298
298
|
background: transparent;
|
|
299
299
|
}
|
|
300
300
|
.kanban-column-body::-webkit-scrollbar-thumb {
|
|
301
|
-
background:
|
|
302
|
-
border-radius:
|
|
301
|
+
background: var(--ld-gray-400);
|
|
302
|
+
border-radius: var(--ld-px-3);
|
|
303
303
|
}
|
|
304
304
|
.kanban-column-body::-webkit-scrollbar-thumb:hover {
|
|
305
|
-
background:
|
|
305
|
+
background: var(--ld-gray-500);
|
|
306
306
|
}
|
|
307
|
-
/*# sourceMappingURL=src
|
|
307
|
+
/*# sourceMappingURL=src\styles\kanban.less.map */
|