@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.
Files changed (147) hide show
  1. package/README.md +171 -37
  2. package/dist/index.css +114 -114
  3. package/dist/index.js +221 -126
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.min.css +1 -1
  6. package/dist/index.min.js +758 -1
  7. package/dist/index.min.js.map +1 -0
  8. package/es/.dts-output-manifest.json +1 -0
  9. package/es/.dts.tsbuildinfo +1 -0
  10. package/es/core/ColumnManager.d.ts +4 -3
  11. package/es/core/ColumnManager.js +43 -18
  12. package/es/core/ColumnManager.js.map +1 -1
  13. package/es/core/DragController.d.ts +1 -2
  14. package/es/core/DragController.js +11 -1
  15. package/es/core/DragController.js.map +1 -1
  16. package/es/core/EventEmitter.d.ts +0 -1
  17. package/es/core/EventEmitter.js +8 -3
  18. package/es/core/EventEmitter.js.map +1 -1
  19. package/es/core/FilterEngine.d.ts +1 -2
  20. package/es/core/FilterEngine.js +10 -5
  21. package/es/core/FilterEngine.js.map +1 -1
  22. package/es/core/KanbanBoard.d.ts +3 -3
  23. package/es/core/KanbanBoard.js +61 -15
  24. package/es/core/KanbanBoard.js.map +1 -1
  25. package/es/core/Renderer.d.ts +2 -3
  26. package/es/core/Renderer.js +11 -7
  27. package/es/core/Renderer.js.map +1 -1
  28. package/es/core/index.d.ts +2 -3
  29. package/es/core/index.js +1 -1
  30. package/es/index.d.ts +3 -4
  31. package/es/index.js +2 -2
  32. package/es/styles/kanban.css +114 -114
  33. package/es/types/index.d.ts +3 -4
  34. package/es/types/index.js +1 -1
  35. package/es/utils/dom.d.ts +0 -1
  36. package/es/utils/dom.js +1 -1
  37. package/es/utils/dom.js.map +1 -1
  38. package/es/utils/id.d.ts +0 -1
  39. package/es/utils/id.js +1 -1
  40. package/es/utils/id.js.map +1 -1
  41. package/es/utils/index.d.ts +1 -2
  42. package/es/utils/index.js +1 -1
  43. package/es/utils/index.js.map +1 -1
  44. package/es/version.d.ts +0 -1
  45. package/es/version.js +1 -1
  46. package/es/version.js.map +1 -1
  47. package/esm/core/ColumnManager.js +43 -18
  48. package/esm/core/ColumnManager.js.map +1 -1
  49. package/esm/core/DragController.js +11 -1
  50. package/esm/core/DragController.js.map +1 -1
  51. package/esm/core/EventEmitter.js +8 -3
  52. package/esm/core/EventEmitter.js.map +1 -1
  53. package/esm/core/FilterEngine.js +10 -5
  54. package/esm/core/FilterEngine.js.map +1 -1
  55. package/esm/core/KanbanBoard.js +63 -17
  56. package/esm/core/KanbanBoard.js.map +1 -1
  57. package/esm/core/Renderer.js +11 -7
  58. package/esm/core/Renderer.js.map +1 -1
  59. package/esm/index.js +4 -4
  60. package/esm/styles/kanban.less +357 -339
  61. package/esm/utils/dom.js +1 -1
  62. package/esm/utils/dom.js.map +1 -1
  63. package/esm/utils/id.js +1 -1
  64. package/esm/utils/id.js.map +1 -1
  65. package/esm/utils/index.js +2 -2
  66. package/esm/utils/index.js.map +1 -1
  67. package/esm/version.js +1 -1
  68. package/esm/version.js.map +1 -1
  69. package/lib/core/ColumnManager.cjs +43 -18
  70. package/lib/core/ColumnManager.cjs.map +1 -1
  71. package/{esm/core/ColumnManager.d.ts → lib/core/ColumnManager.d.cts} +4 -3
  72. package/lib/core/DragController.cjs +11 -1
  73. package/lib/core/DragController.cjs.map +1 -1
  74. package/{esm/core/DragController.d.ts → lib/core/DragController.d.cts} +1 -2
  75. package/lib/core/EventEmitter.cjs +8 -3
  76. package/lib/core/EventEmitter.cjs.map +1 -1
  77. package/lib/core/{EventEmitter.d.ts → EventEmitter.d.cts} +0 -1
  78. package/lib/core/FilterEngine.cjs +10 -5
  79. package/lib/core/FilterEngine.cjs.map +1 -1
  80. package/{esm/core/FilterEngine.d.ts → lib/core/FilterEngine.d.cts} +1 -2
  81. package/lib/core/KanbanBoard.cjs +61 -15
  82. package/lib/core/KanbanBoard.cjs.map +1 -1
  83. package/{esm/core/KanbanBoard.d.ts → lib/core/KanbanBoard.d.cts} +3 -3
  84. package/lib/core/Renderer.cjs +11 -7
  85. package/lib/core/Renderer.cjs.map +1 -1
  86. package/{esm/core/Renderer.d.ts → lib/core/Renderer.d.cts} +2 -3
  87. package/lib/core/index.cjs +1 -1
  88. package/{esm/core/index.d.ts → lib/core/index.d.cts} +2 -3
  89. package/lib/index.cjs +2 -2
  90. package/lib/{index.d.ts → index.d.cts} +3 -4
  91. package/lib/styles/kanban.css +114 -114
  92. package/lib/types/index.cjs +1 -1
  93. package/{esm/types/index.d.ts → lib/types/index.d.cts} +3 -4
  94. package/lib/utils/dom.cjs +1 -1
  95. package/lib/utils/dom.cjs.map +1 -1
  96. package/lib/utils/{dom.d.ts → dom.d.cts} +0 -1
  97. package/lib/utils/id.cjs +1 -1
  98. package/lib/utils/id.cjs.map +1 -1
  99. package/{esm/utils/id.d.ts → lib/utils/id.d.cts} +0 -1
  100. package/lib/utils/index.cjs +1 -1
  101. package/lib/utils/index.cjs.map +1 -1
  102. package/lib/utils/{index.d.ts → index.d.cts} +1 -2
  103. package/lib/version.cjs +1 -1
  104. package/lib/version.cjs.map +1 -1
  105. package/{esm/version.d.ts → lib/version.d.cts} +0 -1
  106. package/package.json +23 -21
  107. package/es/core/ColumnManager.d.ts.map +0 -1
  108. package/es/core/DragController.d.ts.map +0 -1
  109. package/es/core/EventEmitter.d.ts.map +0 -1
  110. package/es/core/FilterEngine.d.ts.map +0 -1
  111. package/es/core/KanbanBoard.d.ts.map +0 -1
  112. package/es/core/Renderer.d.ts.map +0 -1
  113. package/es/core/index.d.ts.map +0 -1
  114. package/es/index.d.ts.map +0 -1
  115. package/es/types/index.d.ts.map +0 -1
  116. package/es/utils/dom.d.ts.map +0 -1
  117. package/es/utils/id.d.ts.map +0 -1
  118. package/es/utils/index.d.ts.map +0 -1
  119. package/es/version.d.ts.map +0 -1
  120. package/esm/core/ColumnManager.d.ts.map +0 -1
  121. package/esm/core/DragController.d.ts.map +0 -1
  122. package/esm/core/EventEmitter.d.ts +0 -35
  123. package/esm/core/EventEmitter.d.ts.map +0 -1
  124. package/esm/core/FilterEngine.d.ts.map +0 -1
  125. package/esm/core/KanbanBoard.d.ts.map +0 -1
  126. package/esm/core/Renderer.d.ts.map +0 -1
  127. package/esm/core/index.d.ts.map +0 -1
  128. package/esm/core/index.js +0 -17
  129. package/esm/index.d.ts +0 -15
  130. package/esm/index.d.ts.map +0 -1
  131. package/esm/types/index.d.ts.map +0 -1
  132. package/esm/types/index.js +0 -10
  133. package/esm/utils/dom.d.ts +0 -24
  134. package/esm/utils/dom.d.ts.map +0 -1
  135. package/esm/utils/id.d.ts.map +0 -1
  136. package/esm/utils/index.d.ts +0 -25
  137. package/esm/utils/index.d.ts.map +0 -1
  138. package/esm/version.d.ts.map +0 -1
  139. package/lib/core/ColumnManager.d.ts +0 -99
  140. package/lib/core/DragController.d.ts +0 -55
  141. package/lib/core/FilterEngine.d.ts +0 -45
  142. package/lib/core/KanbanBoard.d.ts +0 -152
  143. package/lib/core/Renderer.d.ts +0 -59
  144. package/lib/core/index.d.ts +0 -11
  145. package/lib/types/index.d.ts +0 -209
  146. package/lib/utils/id.d.ts +0 -9
  147. 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
- - 🎨 TypeScript 类型完整
9
- - 📦 支持 ESM / CJS 双格式输出
10
-
11
- ## 安装
12
-
13
- ```bash
14
- npm install @composy/kanban-core
15
- ```
16
-
17
- ## 快速开始
18
-
19
- ```typescript
20
- import { /* 需要的导出 */ } from '@composy/kanban-core'
21
-
22
- // 根据实际 API 使用
23
- ```
24
-
25
- ## 目录结构
26
-
27
- ```
28
- packages/core/
29
- ├── src/ # 源码
30
- ├── package.json
31
- ├── tsconfig.json # ESM 构建配置
32
- └── tsconfig.cjs.json # CJS 构建配置
33
- ```
34
-
35
- ## License
36
-
37
- MIT
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: 400px;
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: 16px;
13
- padding: 8px;
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 280px;
20
- max-width: 280px;
21
- background: #f4f5f7;
22
- border-radius: 8px;
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 - 200px);
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 48px;
30
- max-width: 48px;
31
- min-height: 200px;
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 2px #4c9aff;
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: 6px;
44
- padding: 10px 12px;
45
- border-bottom: 1px solid #e1e4e8;
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: #a0a0a0;
53
- font-size: 12px;
54
- letter-spacing: -3px;
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: 2px 0;
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: 12px;
63
- height: 12px;
64
- border-radius: 3px;
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: 14px;
68
+ font-size: var(--ld-px-14);
69
69
  font-weight: 600;
70
- color: #172b4d;
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: 12px;
78
- color: #6b778c;
79
- background: #dfe1e6;
80
- border-radius: 10px;
81
- padding: 1px 8px;
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: #ffebe6;
86
- color: #bf2600;
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: #6b778c;
94
- font-size: 12px;
95
- padding: 2px 4px;
96
- border-radius: 3px;
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: #dfe1e6;
102
- color: #172b4d;
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: 8px;
109
- min-height: 40px;
108
+ padding: var(--ld-px-8);
109
+ min-height: var(--ld-px-40);
110
110
  }
111
111
  .kanban-column-body--drag-over {
112
- background: #e3f2fd;
113
- border-radius: 0 0 8px 8px;
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: #e3f2fd;
118
- border: 2px dashed #90caf9;
119
- border-radius: 6px;
120
- margin-bottom: 8px;
121
- min-height: 40px;
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: #fff;
127
- border-radius: 6px;
128
- padding: 10px 12px;
129
- margin-bottom: 8px;
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: 0 1px 2px rgba(0, 0, 0, 0.08);
131
+ box-shadow: var(--ld-shadow-1);
132
132
  transition: box-shadow 0.2s, transform 0.15s, opacity 0.2s;
133
- border: 1px solid transparent;
133
+ border: var(--ld-px-1) solid transparent;
134
134
  position: relative;
135
135
  }
136
136
  .kanban-card:hover {
137
- box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
138
- border-color: #e1e4e8;
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: 3px;
151
- border-radius: 6px 0 0 6px;
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: #36b37e;
154
+ background: var(--ld-success-500);
155
155
  }
156
156
  .kanban-card-priority--medium {
157
- background: #ffab00;
157
+ background: var(--ld-warning-500);
158
158
  }
159
159
  .kanban-card-priority--high {
160
- background: #ff5630;
160
+ background: var(--ld-danger-500);
161
161
  }
162
162
  .kanban-card-priority--urgent {
163
- background: #bf2600;
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: 4px;
170
- margin-bottom: 6px;
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: 1px 8px;
175
- border-radius: 3px;
176
- font-size: 11px;
177
- color: #fff;
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: 14px;
183
+ font-size: var(--ld-px-14);
184
184
  font-weight: 500;
185
- color: #172b4d;
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: 12px;
192
- color: #6b778c;
193
- margin-top: 4px;
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: 8px;
206
- gap: 8px;
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: -4px;
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: 24px;
217
- height: 24px;
216
+ width: var(--ld-px-24);
217
+ height: var(--ld-px-24);
218
218
  border-radius: 50%;
219
- background: #dfe1e6;
220
- color: #42526e;
221
- font-size: 11px;
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: 2px solid #fff;
224
- margin-left: -4px;
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: 24px;
234
- height: 24px;
233
+ width: var(--ld-px-24);
234
+ height: var(--ld-px-24);
235
235
  border-radius: 50%;
236
- background: #c1c7d0;
237
- color: #42526e;
238
- font-size: 10px;
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: 2px solid #fff;
241
- margin-left: -4px;
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: 12px;
245
- color: #6b778c;
244
+ font-size: var(--ld-px-12);
245
+ color: var(--ld-text-secondary);
246
246
  display: flex;
247
247
  align-items: center;
248
- gap: 4px;
248
+ gap: var(--ld-px-4);
249
249
  }
250
250
  .kanban-card-due--overdue {
251
- color: #ff5630;
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 4px;
256
+ padding: 0 var(--ld-px-4);
257
257
  }
258
258
  .kanban-add-card-btn {
259
259
  width: 100%;
260
- padding: 6px 8px;
260
+ padding: var(--ld-px-6) var(--ld-px-8);
261
261
  background: none;
262
262
  border: none;
263
- border-radius: 6px;
264
- color: #6b778c;
265
- font-size: 13px;
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: #dfe1e6;
272
- color: #172b4d;
271
+ background: var(--ld-bg-hover);
272
+ color: var(--ld-text-primary);
273
273
  }
274
274
  .kanban-add-column {
275
- flex: 0 0 280px;
275
+ flex: 0 0 var(--ld-px-280);
276
276
  }
277
277
  .kanban-add-column-btn {
278
278
  width: 100%;
279
- padding: 10px;
280
- background: rgba(0, 0, 0, 0.04);
281
- border: 2px dashed #d0d4d9;
282
- border-radius: 8px;
283
- color: #6b778c;
284
- font-size: 14px;
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: rgba(0, 0, 0, 0.08);
290
- border-color: #a5adba;
291
- color: #172b4d;
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: 6px;
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: #c1c7d0;
302
- border-radius: 3px;
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: #a5adba;
305
+ background: var(--ld-gray-500);
306
306
  }
307
- /*# sourceMappingURL=src/styles/kanban.less.map */
307
+ /*# sourceMappingURL=src\styles\kanban.less.map */