@ticatec/topside-elements 1.0.2 → 1.0.3
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/CHANGELOG.md +8 -0
- package/dist/general/split/README.md +42 -57
- package/dist/general/split/README_CN.md +42 -57
- package/dist/general/split/Split.svelte +100 -15
- package/dist/general/split/Split.svelte.d.ts +15 -0
- package/dist/topside-elements.css +2 -0
- package/docs/components/README.md +3 -3
- package/docs/components/concise-data-table/README.md +52 -2
- package/docs/components/data-table/README.md +54 -8
- package/docs/components/split/README.md +10 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.3
|
|
4
|
+
|
|
5
|
+
### 变更
|
|
6
|
+
- **Split 分割线外观**:线条默认 1px(`width`,原 2px);新增 `hitSize`(不占布局的感应区,默认 8px,靠近即可悬停 / 拖动)、`color`、`gripColor`、`gripSize`、`gripLength`;悬停 / 拖动 / 键盘聚焦时中间淡入深色稍粗的把手,取代原来整条加深。新令牌 `--topside-divider-grip-color`(亮 `#94A3B8` / 暗 `#8a8a8a`)。
|
|
7
|
+
|
|
8
|
+
### 文档
|
|
9
|
+
- 重新生成 `docs/components`(Split、DataTable / ConciseDataTable 合计行相关属性)。
|
|
10
|
+
|
|
3
11
|
## 1.0.0 — 首个公开版本
|
|
4
12
|
|
|
5
13
|
### 新增
|
|
@@ -3,18 +3,20 @@
|
|
|
3
3
|
A draggable divider that resizes the panel you bind it to. Sits between two adjacent panels in a flex container; dragging the divider updates the bound panel's `width` or `height` inline style.
|
|
4
4
|
|
|
5
5
|
> **Naming gotcha**: `direction` describes the **visual orientation of the divider bar**, not the layout direction of the panels.
|
|
6
|
-
> - `direction="vertical"` → a *vertical bar* (
|
|
7
|
-
> - `direction="horizontal"` → a *horizontal bar* (full width,
|
|
6
|
+
> - `direction="vertical"` → a *vertical bar* (`width` px wide, full height) → goes between **left/right** panels (flex row).
|
|
7
|
+
> - `direction="horizontal"` → a *horizontal bar* (full width, `width` px tall) → goes between **top/bottom** panels (flex column).
|
|
8
8
|
|
|
9
9
|
## Features
|
|
10
10
|
|
|
11
11
|
- **Drag-to-resize**: mouse-driven resizing of the bound panel
|
|
12
12
|
- **Two orientations**: vertical bar (default) for left/right splits, horizontal bar for top/bottom splits
|
|
13
|
-
- **
|
|
13
|
+
- **Thin line, generous hit area**: the visible line is 1px by default (`width`), while an invisible `hitSize` zone (8px) around it catches hover and drag without taking layout space
|
|
14
|
+
- **Hover handle**: a darker, thicker, rounded segment fades in at the center on hover / drag / keyboard focus (like the sidebar resizer in Claude)
|
|
15
|
+
- **Customisable look**: `color`, `gripColor`, `gripSize`, `gripLength`
|
|
14
16
|
- **Reverse mode**: for when the bound panel is on the right/bottom of the divider
|
|
15
17
|
- **Fixed mode**: omit `bindingPanel` to render a non-interactive visual divider
|
|
16
18
|
- **Min size guard**: bound panel can't be dragged below 5px
|
|
17
|
-
- **Theme
|
|
19
|
+
- **Theme tokens**: `--topside-dividing-line-color`, `--topside-divider-grip-color`
|
|
18
20
|
- **Cleanup on unmount**: in-flight drag is cancelled if the component is destroyed mid-drag
|
|
19
21
|
|
|
20
22
|
## Installation
|
|
@@ -57,7 +59,12 @@ Drag the bar; the left panel's width updates in real time. The right panel (with
|
|
|
57
59
|
| Prop | Type | Default | Description |
|
|
58
60
|
|------|------|---------|-------------|
|
|
59
61
|
| `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | Visual orientation of the bar. `vertical` = thin tall bar (for left/right splits); `horizontal` = thin wide bar (for top/bottom splits). |
|
|
60
|
-
| `width` | `number` | `
|
|
62
|
+
| `width` | `number` | `1` | Thickness of the visible line in px (takes layout space) |
|
|
63
|
+
| `hitSize` | `number` | `8` | Thickness of the invisible hover/drag zone in px, centered on the line; takes no layout space |
|
|
64
|
+
| `color` | `string` | token | Line color; overrides `--topside-dividing-line-color` |
|
|
65
|
+
| `gripColor` | `string` | token | Color of the handle shown on hover/drag; overrides `--topside-divider-grip-color` |
|
|
66
|
+
| `gripSize` | `number` | `3` | Handle thickness in px |
|
|
67
|
+
| `gripLength` | `number` | `32` | Handle length in px; `0` = full length |
|
|
61
68
|
| `bindingPanel` | `HTMLElement \| undefined` | `undefined` | The panel to resize. Omit to render a fixed, non-draggable divider. |
|
|
62
69
|
| `reverse` | `boolean` | `false` | Flip drag direction. Use when the bound panel sits to the **right/below** the divider (so dragging away from it grows it). |
|
|
63
70
|
| `onResizeEnd` | `(size: number) => void` | `undefined` | Fired once when a drag ends; receives the bound panel's final `clientWidth` or `clientHeight` in px. Not fired for fixed dividers. |
|
|
@@ -94,7 +101,7 @@ The component does **not** emit intermediate events during the drag — it mutat
|
|
|
94
101
|
<p>Drag the bar to resize me.</p>
|
|
95
102
|
</div>
|
|
96
103
|
|
|
97
|
-
<Split bindingPanel={leftPanel} direction="vertical"
|
|
104
|
+
<Split bindingPanel={leftPanel} direction="vertical" />
|
|
98
105
|
|
|
99
106
|
<div style="flex: 1 1 auto; padding: 16px; background: #e8e8e8;">
|
|
100
107
|
<h3>Right</h3>
|
|
@@ -117,7 +124,7 @@ The component does **not** emit intermediate events during the drag — it mutat
|
|
|
117
124
|
<h3>Top</h3>
|
|
118
125
|
</div>
|
|
119
126
|
|
|
120
|
-
<Split bindingPanel={topPanel} direction="horizontal"
|
|
127
|
+
<Split bindingPanel={topPanel} direction="horizontal" />
|
|
121
128
|
|
|
122
129
|
<div style="flex: 1 1 auto; padding: 16px; background: #e8e8e8;">
|
|
123
130
|
<h3>Bottom</h3>
|
|
@@ -186,13 +193,13 @@ Sidebar | Editor | Details, all resizable. Two dividers, both bound to the panel
|
|
|
186
193
|
Sidebar
|
|
187
194
|
</div>
|
|
188
195
|
|
|
189
|
-
<Split bindingPanel={sidebar} direction="vertical"
|
|
196
|
+
<Split bindingPanel={sidebar} direction="vertical" />
|
|
190
197
|
|
|
191
198
|
<div bind:this={editor} style="flex: 1 1 0; background: #0f172a; color: #e2e8f0;">
|
|
192
199
|
Editor
|
|
193
200
|
</div>
|
|
194
201
|
|
|
195
|
-
<Split bindingPanel={editor} direction="vertical"
|
|
202
|
+
<Split bindingPanel={editor} direction="vertical" />
|
|
196
203
|
|
|
197
204
|
<div style="flex: 0 0 320px; background: #111827; color: #e2e8f0;">
|
|
198
205
|
Details
|
|
@@ -214,76 +221,54 @@ Omit `bindingPanel`:
|
|
|
214
221
|
</div>
|
|
215
222
|
```
|
|
216
223
|
|
|
217
|
-
Fixed dividers get the `fixed` class → `pointer-events: none; cursor: default
|
|
224
|
+
Fixed dividers get the `fixed` class → `pointer-events: none; cursor: default`; the hit area and hover handle are not rendered.
|
|
218
225
|
|
|
219
|
-
##
|
|
226
|
+
## Styling Examples
|
|
227
|
+
|
|
228
|
+
```svelte
|
|
229
|
+
<!-- Claude-style: 1px line, wide hit area, short indigo handle -->
|
|
230
|
+
<Split bindingPanel={sidebar} width={1} hitSize={12} gripSize={4} gripLength={48}
|
|
231
|
+
color="#e5e7eb" gripColor="#6366f1" />
|
|
220
232
|
|
|
221
|
-
|
|
233
|
+
<!-- Whole line thickens on hover -->
|
|
234
|
+
<Split bindingPanel={sidebar} gripLength={0} />
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## DOM Structure & CSS
|
|
222
238
|
|
|
223
239
|
```html
|
|
224
240
|
<div
|
|
225
|
-
class="topside-divider {direction}"
|
|
226
|
-
|
|
227
|
-
style="height: 2px" or "width: 2px" <!-- depends on direction -->
|
|
241
|
+
class="topside-divider {direction}" <!-- + 'fixed' without bindingPanel, + 'dragging' while dragging -->
|
|
242
|
+
style="width: 1px; --split-hit: 8px; --split-grip-size: 3px; --split-grip-length: 32px; ..."
|
|
228
243
|
role="separator"
|
|
229
244
|
aria-orientation="{direction}"
|
|
230
245
|
aria-label="Resize handle"
|
|
231
246
|
tabindex="0"
|
|
232
|
-
|
|
233
|
-
/>
|
|
247
|
+
></div>
|
|
234
248
|
```
|
|
235
249
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
background-color: var(--topside-dividing-line-color, #CBD5E1);
|
|
241
|
-
flex: 0 0 auto; /* don't grow or shrink */
|
|
242
|
-
transition: background-color 0.2s ease;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.topside-divider.vertical {
|
|
246
|
-
height: 100%;
|
|
247
|
-
cursor: col-resize;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.topside-divider.horizontal {
|
|
251
|
-
width: 100%;
|
|
252
|
-
cursor: row-resize;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
.topside-divider.fixed {
|
|
256
|
-
cursor: default;
|
|
257
|
-
pointer-events: none;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.topside-divider:hover {
|
|
261
|
-
/* darken 20% via color-mix */
|
|
262
|
-
background-color: color-mix(in srgb, var(--topside-dividing-line-color, #CBD5E1) 80%, #000);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.topside-divider:active {
|
|
266
|
-
transition: none; /* no animation lag during drag */
|
|
267
|
-
}
|
|
268
|
-
```
|
|
250
|
+
- The element itself is the visible line (`width` px thick, `flex: 0 0 auto`), `position: relative; z-index: 5`.
|
|
251
|
+
- `::before` is the transparent **hit area**: centered on the line, `hitSize` px thick. It overlaps the neighbouring panels by about `(hitSize - width) / 2` px on each side, so hovering near the line already shows the resize cursor.
|
|
252
|
+
- `::after` is the **handle**: centered, `gripSize` × `gripLength`, rounded, `opacity: 0`. It fades in on `:hover` (100ms delay, so passing over it doesn't flicker), and immediately while `.dragging` or `:focus-visible`.
|
|
253
|
+
- Fixed dividers hide both pseudo-elements and ignore pointer events.
|
|
269
254
|
|
|
270
255
|
### CSS Custom Properties
|
|
271
256
|
|
|
272
|
-
| Variable | Default | Description |
|
|
257
|
+
| Variable | Default (light / dark) | Description |
|
|
273
258
|
|----------|---------|-------------|
|
|
274
|
-
| `--topside-dividing-line-color` | `#CBD5E1` |
|
|
259
|
+
| `--topside-dividing-line-color` | `#CBD5E1` / `#4a4a4a` | Line color (overridden by the `color` prop) |
|
|
260
|
+
| `--topside-divider-grip-color` | `#94A3B8` / `#8a8a8a` | Handle color (overridden by the `gripColor` prop) |
|
|
275
261
|
|
|
276
262
|
```css
|
|
277
263
|
:root {
|
|
278
|
-
--topside-dividing-line-color: #
|
|
279
|
-
|
|
280
|
-
.dark-theme {
|
|
281
|
-
--topside-dividing-line-color: #3f3f46;
|
|
264
|
+
--topside-dividing-line-color: #e5e7eb;
|
|
265
|
+
--topside-divider-grip-color: #9ca3af;
|
|
282
266
|
}
|
|
283
267
|
```
|
|
284
268
|
|
|
285
269
|
## Behavior Notes
|
|
286
270
|
|
|
271
|
+
- **Hit area overlaps neighbours.** Clicks within about `hitSize / 2` px of the line go to the divider. If a panel has a button or scrollbar right at that edge, lower `hitSize`.
|
|
287
272
|
- **Mouse only.** The drag uses `mousedown` / `mousemove` / `mouseup`. Touch events are not handled — on touch devices the divider will not respond to finger drags.
|
|
288
273
|
- **Min size**: bound panel clamped to ≥5px (won't collapse to zero).
|
|
289
274
|
- **Document-level listeners**: `mousemove` and `mouseup` are attached to `document` during a drag, so the cursor can wander outside the bar without losing the grab.
|
|
@@ -295,7 +280,7 @@ Built-in styles:
|
|
|
295
280
|
## Accessibility
|
|
296
281
|
|
|
297
282
|
- `role="separator"`, `aria-orientation`, `aria-label="Resize handle"`, `tabindex="0"` are set on the divider.
|
|
298
|
-
- **Keyboard
|
|
283
|
+
- **Keyboard**: when focused, arrow keys (←/→ for vertical, ↑/↓ for horizontal) resize the bound panel by 10px and fire `onResizeEnd`; the handle is shown while focused via keyboard.
|
|
299
284
|
- For fixed dividers, consider `aria-disabled="true"` if the visual still looks interactive.
|
|
300
285
|
|
|
301
286
|
## Best Practices
|
|
@@ -3,18 +3,20 @@
|
|
|
3
3
|
一个可拖动的分隔条,用来调整绑定的那个面板的尺寸。放在 flex 容器里两个相邻面板之间,拖动会直接改写绑定面板的 `width` 或 `height` 内联样式。
|
|
4
4
|
|
|
5
5
|
> **命名陷阱**:`direction` 描述的是**分隔条本身的视觉朝向**,不是面板的排布方向。
|
|
6
|
-
> - `direction="vertical"` →
|
|
7
|
-
> - `direction="horizontal"` →
|
|
6
|
+
> - `direction="vertical"` → 一根**竖条**(`width` px 宽,整高)→ 放在**左右**面板之间(flex row)。
|
|
7
|
+
> - `direction="horizontal"` → 一根**横条**(整宽,`width` px 高)→ 放在**上下**面板之间(flex column)。
|
|
8
8
|
|
|
9
9
|
## 功能特性
|
|
10
10
|
|
|
11
11
|
- **拖拽调整**:鼠标拖动改变绑定面板尺寸
|
|
12
12
|
- **两个方向**:竖条(默认,用于左右分栏)或横条(用于上下分栏)
|
|
13
|
-
-
|
|
13
|
+
- **细线 + 宽感应区**:可见线条默认 1px(`width`),周围有一圈不占布局的透明感应区(`hitSize`,默认 8px),靠近线条即可悬停、拖动
|
|
14
|
+
- **悬停把手**:悬停 / 拖动 / 键盘聚焦时,线条中间淡入一段深色、稍粗、圆角的把手(类似 Claude 侧边栏)
|
|
15
|
+
- **外观可调**:`color`、`gripColor`、`gripSize`、`gripLength`
|
|
14
16
|
- **反向模式**:当绑定面板在分隔条的右侧/下方时使用
|
|
15
17
|
- **固定模式**:省略 `bindingPanel` 即渲染为不可交互的视觉分隔条
|
|
16
18
|
- **最小尺寸保护**:绑定面板不会被拖到 5px 以下
|
|
17
|
-
-
|
|
19
|
+
- **主题令牌**:`--topside-dividing-line-color`、`--topside-divider-grip-color`
|
|
18
20
|
- **销毁时清理**:组件在拖动过程中被销毁会自动取消拖动
|
|
19
21
|
|
|
20
22
|
## 安装
|
|
@@ -57,7 +59,12 @@ import Split from '@ticatec/topside-elements/Split';
|
|
|
57
59
|
| 属性 | 类型 | 默认值 | 描述 |
|
|
58
60
|
|------|------|---------|-------------|
|
|
59
61
|
| `direction` | `'vertical' \| 'horizontal'` | `'vertical'` | 分隔条的视觉朝向。`vertical` = 细高竖条(用于左右分栏);`horizontal` = 细宽横条(用于上下分栏) |
|
|
60
|
-
| `width` | `number` | `
|
|
62
|
+
| `width` | `number` | `1` | 可见线条的像素厚度(占布局) |
|
|
63
|
+
| `hitSize` | `number` | `8` | 鼠标感应区厚度(px),以线条为中心向两侧伸出,不占布局 |
|
|
64
|
+
| `color` | `string` | 令牌 | 线条底色,覆盖 `--topside-dividing-line-color` |
|
|
65
|
+
| `gripColor` | `string` | 令牌 | 悬停 / 拖动时把手颜色,覆盖 `--topside-divider-grip-color` |
|
|
66
|
+
| `gripSize` | `number` | `3` | 把手粗细(px) |
|
|
67
|
+
| `gripLength` | `number` | `32` | 把手长度(px),`0` 表示整条 |
|
|
61
68
|
| `bindingPanel` | `HTMLElement \| undefined` | `undefined` | 要调整尺寸的面板。省略则渲染为固定不可拖的分隔条 |
|
|
62
69
|
| `reverse` | `boolean` | `false` | 反转拖动方向。绑定面板在分隔条**右侧/下方**时使用(向远离面板的方向拖动使其变大) |
|
|
63
70
|
| `onResizeEnd` | `(size: number) => void` | `undefined` | 一次拖动结束时触发一次,参数是绑定面板最终的 `clientWidth` 或 `clientHeight`(像素)。固定分隔条不会触发 |
|
|
@@ -94,7 +101,7 @@ import Split from '@ticatec/topside-elements/Split';
|
|
|
94
101
|
<p>拖动中间的条调整我的宽度。</p>
|
|
95
102
|
</div>
|
|
96
103
|
|
|
97
|
-
<Split bindingPanel={leftPanel} direction="vertical"
|
|
104
|
+
<Split bindingPanel={leftPanel} direction="vertical" />
|
|
98
105
|
|
|
99
106
|
<div style="flex: 1 1 auto; padding: 16px; background: #e8e8e8;">
|
|
100
107
|
<h3>右侧</h3>
|
|
@@ -117,7 +124,7 @@ import Split from '@ticatec/topside-elements/Split';
|
|
|
117
124
|
<h3>顶部</h3>
|
|
118
125
|
</div>
|
|
119
126
|
|
|
120
|
-
<Split bindingPanel={topPanel} direction="horizontal"
|
|
127
|
+
<Split bindingPanel={topPanel} direction="horizontal" />
|
|
121
128
|
|
|
122
129
|
<div style="flex: 1 1 auto; padding: 16px; background: #e8e8e8;">
|
|
123
130
|
<h3>底部</h3>
|
|
@@ -186,13 +193,13 @@ import Split from '@ticatec/topside-elements/Split';
|
|
|
186
193
|
侧边栏
|
|
187
194
|
</div>
|
|
188
195
|
|
|
189
|
-
<Split bindingPanel={sidebar} direction="vertical"
|
|
196
|
+
<Split bindingPanel={sidebar} direction="vertical" />
|
|
190
197
|
|
|
191
198
|
<div bind:this={editor} style="flex: 1 1 0; background: #0f172a; color: #e2e8f0;">
|
|
192
199
|
编辑器
|
|
193
200
|
</div>
|
|
194
201
|
|
|
195
|
-
<Split bindingPanel={editor} direction="vertical"
|
|
202
|
+
<Split bindingPanel={editor} direction="vertical" />
|
|
196
203
|
|
|
197
204
|
<div style="flex: 0 0 320px; background: #111827; color: #e2e8f0;">
|
|
198
205
|
详情
|
|
@@ -214,76 +221,54 @@ import Split from '@ticatec/topside-elements/Split';
|
|
|
214
221
|
</div>
|
|
215
222
|
```
|
|
216
223
|
|
|
217
|
-
固定分隔条会加 `fixed` 类 → `pointer-events: none; cursor: default
|
|
224
|
+
固定分隔条会加 `fixed` 类 → `pointer-events: none; cursor: default`,不渲染感应区和把手。
|
|
218
225
|
|
|
219
|
-
##
|
|
226
|
+
## 样式示例
|
|
227
|
+
|
|
228
|
+
```svelte
|
|
229
|
+
<!-- Claude 风格:1px 细线、12px 感应区、短的靛蓝把手 -->
|
|
230
|
+
<Split bindingPanel={sidebar} width={1} hitSize={12} gripSize={4} gripLength={48}
|
|
231
|
+
color="#e5e7eb" gripColor="#6366f1" />
|
|
220
232
|
|
|
221
|
-
|
|
233
|
+
<!-- 悬停时整条加粗 -->
|
|
234
|
+
<Split bindingPanel={sidebar} gripLength={0} />
|
|
235
|
+
```
|
|
236
|
+
|
|
237
|
+
## DOM 结构与 CSS
|
|
222
238
|
|
|
223
239
|
```html
|
|
224
240
|
<div
|
|
225
|
-
class="topside-divider {direction}"
|
|
226
|
-
|
|
227
|
-
style="height: 2px" 或 "width: 2px" <!-- 取决于 direction -->
|
|
241
|
+
class="topside-divider {direction}" <!-- 无 bindingPanel 时加 'fixed',拖动中加 'dragging' -->
|
|
242
|
+
style="width: 1px; --split-hit: 8px; --split-grip-size: 3px; --split-grip-length: 32px; ..."
|
|
228
243
|
role="separator"
|
|
229
244
|
aria-orientation="{direction}"
|
|
230
245
|
aria-label="Resize handle"
|
|
231
246
|
tabindex="0"
|
|
232
|
-
|
|
233
|
-
/>
|
|
247
|
+
></div>
|
|
234
248
|
```
|
|
235
249
|
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
background-color: var(--topside-dividing-line-color, #CBD5E1);
|
|
241
|
-
flex: 0 0 auto; /* 不膨胀不收缩 */
|
|
242
|
-
transition: background-color 0.2s ease;
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
.topside-divider.vertical {
|
|
246
|
-
height: 100%;
|
|
247
|
-
cursor: col-resize;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
.topside-divider.horizontal {
|
|
251
|
-
width: 100%;
|
|
252
|
-
cursor: row-resize;
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
.topside-divider.fixed {
|
|
256
|
-
cursor: default;
|
|
257
|
-
pointer-events: none;
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
.topside-divider:hover {
|
|
261
|
-
/* color-mix 加深 20% */
|
|
262
|
-
background-color: color-mix(in srgb, var(--topside-dividing-line-color, #CBD5E1) 80%, #000);
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
.topside-divider:active {
|
|
266
|
-
transition: none; /* 拖动时无动画延迟 */
|
|
267
|
-
}
|
|
268
|
-
```
|
|
250
|
+
- 元素本身就是可见线条(粗 `width` px,`flex: 0 0 auto`),`position: relative; z-index: 5`。
|
|
251
|
+
- `::before` 是透明**感应区**:以线条为中心、厚 `hitSize` px,向两侧各盖住相邻面板约 `(hitSize - width) / 2` px,鼠标靠近线条就出现拖动光标。
|
|
252
|
+
- `::after` 是**把手**:居中、`gripSize` × `gripLength`、圆角,平时 `opacity: 0`;`:hover` 时延迟 100ms 淡入(划过不闪),`.dragging` 或 `:focus-visible` 时立即显示。
|
|
253
|
+
- 固定分隔条隐藏两个伪元素,不响应鼠标。
|
|
269
254
|
|
|
270
255
|
### CSS 自定义属性
|
|
271
256
|
|
|
272
|
-
| 变量 |
|
|
257
|
+
| 变量 | 默认值(亮 / 暗) | 描述 |
|
|
273
258
|
|------|--------|------|
|
|
274
|
-
| `--topside-dividing-line-color` | `#CBD5E1` |
|
|
259
|
+
| `--topside-dividing-line-color` | `#CBD5E1` / `#4a4a4a` | 线条底色(`color` 属性优先) |
|
|
260
|
+
| `--topside-divider-grip-color` | `#94A3B8` / `#8a8a8a` | 把手颜色(`gripColor` 属性优先) |
|
|
275
261
|
|
|
276
262
|
```css
|
|
277
263
|
:root {
|
|
278
|
-
--topside-dividing-line-color: #
|
|
279
|
-
|
|
280
|
-
.dark-theme {
|
|
281
|
-
--topside-dividing-line-color: #3f3f46;
|
|
264
|
+
--topside-dividing-line-color: #e5e7eb;
|
|
265
|
+
--topside-divider-grip-color: #9ca3af;
|
|
282
266
|
}
|
|
283
267
|
```
|
|
284
268
|
|
|
285
269
|
## 行为说明
|
|
286
270
|
|
|
271
|
+
- **感应区会盖住相邻面板边缘。** 距线条约 `hitSize / 2` px 内的点击由分隔条接收;面板边上正好有按钮或滚动条时,调小 `hitSize`。
|
|
287
272
|
- **仅鼠标。** 拖动用的是 `mousedown` / `mousemove` / `mouseup`。**不**处理 touch 事件,触屏设备上手指拖动不会响应。
|
|
288
273
|
- **最小尺寸**:绑定面板夹到 ≥5px(不会塌成 0)。
|
|
289
274
|
- **document 级监听**:拖动期间 `mousemove` 和 `mouseup` 挂在 `document` 上,光标移出分隔条也不会丢失拖动。
|
|
@@ -295,7 +280,7 @@ import Split from '@ticatec/topside-elements/Split';
|
|
|
295
280
|
## 无障碍访问
|
|
296
281
|
|
|
297
282
|
- 分隔条上设置了 `role="separator"`、`aria-orientation`、`aria-label="Resize handle"`、`tabindex="0"`。
|
|
298
|
-
-
|
|
283
|
+
- **键盘**:聚焦后方向键(竖线 ←/→,横线 ↑/↓)每次调整绑定面板 10px 并触发 `onResizeEnd`;键盘聚焦时显示把手。
|
|
299
284
|
- 固定分隔条如果视觉上还像可交互,建议加 `aria-disabled="true"`。
|
|
300
285
|
|
|
301
286
|
## 最佳实践
|
|
@@ -2,18 +2,38 @@
|
|
|
2
2
|
import {onDestroy} from 'svelte';
|
|
3
3
|
|
|
4
4
|
interface Props {
|
|
5
|
+
/** 分隔线朝向:vertical 竖线(左右分栏),horizontal 横线(上下分栏) */
|
|
5
6
|
direction?: "horizontal" | "vertical";
|
|
7
|
+
/** 可见线条粗细(px),占布局,默认 1 */
|
|
6
8
|
width?: number;
|
|
9
|
+
/** 被拖动调整尺寸的面板;不传则为固定分隔线 */
|
|
7
10
|
bindingPanel?: HTMLElement;
|
|
11
|
+
/** 绑定面板在分隔线右侧 / 下方时设为 true */
|
|
8
12
|
reverse?: boolean;
|
|
13
|
+
/** 线条底色,默认取 --topside-dividing-line-color */
|
|
14
|
+
color?: string;
|
|
15
|
+
/** 悬停 / 拖动时中间把手的颜色,默认取 --topside-divider-grip-color */
|
|
16
|
+
gripColor?: string;
|
|
17
|
+
/** 把手粗细(px),默认 3 */
|
|
18
|
+
gripSize?: number;
|
|
19
|
+
/** 把手长度(px),默认 32;传 0 表示整条加粗 */
|
|
20
|
+
gripLength?: number;
|
|
21
|
+
/** 鼠标感应区厚度(px),不占布局,默认 8 */
|
|
22
|
+
hitSize?: number;
|
|
23
|
+
/** 拖动结束时回调,参数为绑定面板最终宽 / 高(px) */
|
|
9
24
|
onResizeEnd?: (size: number) => void;
|
|
10
25
|
}
|
|
11
26
|
|
|
12
27
|
let {
|
|
13
28
|
direction = "vertical",
|
|
14
|
-
width =
|
|
29
|
+
width = 1,
|
|
15
30
|
bindingPanel,
|
|
16
31
|
reverse = false,
|
|
32
|
+
color,
|
|
33
|
+
gripColor,
|
|
34
|
+
gripSize = 3,
|
|
35
|
+
gripLength = 32,
|
|
36
|
+
hitSize = 8,
|
|
17
37
|
onResizeEnd
|
|
18
38
|
}: Props = $props();
|
|
19
39
|
|
|
@@ -21,7 +41,14 @@
|
|
|
21
41
|
let startPos = $state(0);
|
|
22
42
|
let startSize = $state(0);
|
|
23
43
|
|
|
24
|
-
const style = $derived(
|
|
44
|
+
const style = $derived([
|
|
45
|
+
direction === "horizontal" ? `height: ${width}px` : `width: ${width}px`,
|
|
46
|
+
`--split-hit: ${Math.max(hitSize, width)}px`,
|
|
47
|
+
`--split-grip-size: ${gripSize}px`,
|
|
48
|
+
gripLength > 0 ? `--split-grip-length: ${gripLength}px` : `--split-grip-length: 100%`,
|
|
49
|
+
color ? `--split-color: ${color}` : "",
|
|
50
|
+
gripColor ? `--split-grip-color: ${gripColor}` : ""
|
|
51
|
+
].filter(Boolean).join("; "));
|
|
25
52
|
const fixed = $derived(!bindingPanel);
|
|
26
53
|
|
|
27
54
|
const calculateNewSize = (currentPos: number): number => {
|
|
@@ -107,6 +134,7 @@
|
|
|
107
134
|
<div
|
|
108
135
|
class="topside-divider {direction}"
|
|
109
136
|
class:fixed
|
|
137
|
+
class:dragging={isDragging}
|
|
110
138
|
{style}
|
|
111
139
|
role="separator"
|
|
112
140
|
aria-orientation={direction}
|
|
@@ -118,9 +146,18 @@
|
|
|
118
146
|
|
|
119
147
|
<style>
|
|
120
148
|
.topside-divider {
|
|
121
|
-
|
|
149
|
+
--_color: var(--split-color, var(--topside-dividing-line-color, #CBD5E1));
|
|
150
|
+
--_grip: var(--split-grip-color, var(--topside-divider-grip-color, #94A3B8));
|
|
151
|
+
position: relative;
|
|
152
|
+
z-index: 5;
|
|
122
153
|
flex: 0 0 auto;
|
|
123
|
-
|
|
154
|
+
background-color: var(--_color);
|
|
155
|
+
outline: none;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
.topside-divider.vertical {
|
|
159
|
+
height: 100%;
|
|
160
|
+
cursor: col-resize;
|
|
124
161
|
}
|
|
125
162
|
|
|
126
163
|
.topside-divider.horizontal {
|
|
@@ -128,23 +165,71 @@
|
|
|
128
165
|
cursor: row-resize;
|
|
129
166
|
}
|
|
130
167
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
168
|
+
/* 感应区:透明、不占布局,向两侧伸出,靠近线条即可触发 hover */
|
|
169
|
+
.topside-divider::before {
|
|
170
|
+
content: "";
|
|
171
|
+
position: absolute;
|
|
134
172
|
}
|
|
135
173
|
|
|
136
|
-
.topside-divider.
|
|
137
|
-
|
|
174
|
+
.topside-divider.vertical::before {
|
|
175
|
+
top: 0;
|
|
176
|
+
bottom: 0;
|
|
177
|
+
left: 50%;
|
|
178
|
+
width: var(--split-hit, 8px);
|
|
179
|
+
transform: translateX(-50%);
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
.topside-divider.horizontal::before {
|
|
183
|
+
left: 0;
|
|
184
|
+
right: 0;
|
|
185
|
+
top: 50%;
|
|
186
|
+
height: var(--split-hit, 8px);
|
|
187
|
+
transform: translateY(-50%);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
/* 把手:居中的深色稍粗线段,平时隐藏 */
|
|
191
|
+
.topside-divider::after {
|
|
192
|
+
content: "";
|
|
193
|
+
position: absolute;
|
|
194
|
+
left: 50%;
|
|
195
|
+
top: 50%;
|
|
196
|
+
transform: translate(-50%, -50%);
|
|
197
|
+
border-radius: 999px;
|
|
198
|
+
background-color: var(--_grip);
|
|
199
|
+
opacity: 0;
|
|
138
200
|
pointer-events: none;
|
|
201
|
+
transition: opacity 0.15s ease;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
.topside-divider.vertical::after {
|
|
205
|
+
width: var(--split-grip-size, 3px);
|
|
206
|
+
height: var(--split-grip-length, 32px);
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
.topside-divider.horizontal::after {
|
|
210
|
+
height: var(--split-grip-size, 3px);
|
|
211
|
+
width: var(--split-grip-length, 32px);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/* 稍作延迟,鼠标划过时不闪 */
|
|
215
|
+
.topside-divider:hover::after {
|
|
216
|
+
opacity: 1;
|
|
217
|
+
transition-delay: 0.1s;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
.topside-divider.dragging::after,
|
|
221
|
+
.topside-divider:focus-visible::after {
|
|
222
|
+
opacity: 1;
|
|
223
|
+
transition-delay: 0s;
|
|
139
224
|
}
|
|
140
225
|
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
226
|
+
.topside-divider.fixed {
|
|
227
|
+
cursor: default;
|
|
228
|
+
pointer-events: none;
|
|
144
229
|
}
|
|
145
230
|
|
|
146
|
-
|
|
147
|
-
.topside-divider
|
|
148
|
-
|
|
231
|
+
.topside-divider.fixed::before,
|
|
232
|
+
.topside-divider.fixed::after {
|
|
233
|
+
display: none;
|
|
149
234
|
}
|
|
150
235
|
</style>
|
|
@@ -1,8 +1,23 @@
|
|
|
1
1
|
interface Props {
|
|
2
|
+
/** 分隔线朝向:vertical 竖线(左右分栏),horizontal 横线(上下分栏) */
|
|
2
3
|
direction?: "horizontal" | "vertical";
|
|
4
|
+
/** 可见线条粗细(px),占布局,默认 1 */
|
|
3
5
|
width?: number;
|
|
6
|
+
/** 被拖动调整尺寸的面板;不传则为固定分隔线 */
|
|
4
7
|
bindingPanel?: HTMLElement;
|
|
8
|
+
/** 绑定面板在分隔线右侧 / 下方时设为 true */
|
|
5
9
|
reverse?: boolean;
|
|
10
|
+
/** 线条底色,默认取 --topside-dividing-line-color */
|
|
11
|
+
color?: string;
|
|
12
|
+
/** 悬停 / 拖动时中间把手的颜色,默认取 --topside-divider-grip-color */
|
|
13
|
+
gripColor?: string;
|
|
14
|
+
/** 把手粗细(px),默认 3 */
|
|
15
|
+
gripSize?: number;
|
|
16
|
+
/** 把手长度(px),默认 32;传 0 表示整条加粗 */
|
|
17
|
+
gripLength?: number;
|
|
18
|
+
/** 鼠标感应区厚度(px),不占布局,默认 8 */
|
|
19
|
+
hitSize?: number;
|
|
20
|
+
/** 拖动结束时回调,参数为绑定面板最终宽 / 高(px) */
|
|
6
21
|
onResizeEnd?: (size: number) => void;
|
|
7
22
|
}
|
|
8
23
|
declare const Split: import("svelte").Component<Props, {}, "">;
|
|
@@ -380,6 +380,7 @@
|
|
|
380
380
|
--topside-option-padding: var(--topside-margin-md) var(--topside-margin);
|
|
381
381
|
/* Split token */
|
|
382
382
|
--topside-dividing-line-color: #CBD5E1;
|
|
383
|
+
--topside-divider-grip-color: #94A3B8;
|
|
383
384
|
/* Switch Tokens */
|
|
384
385
|
--topside-switch-width: 100px;
|
|
385
386
|
--topside-switch-height: 30px;
|
|
@@ -779,6 +780,7 @@
|
|
|
779
780
|
--topside-progress-step-completed-icon-color: #60A5FA;
|
|
780
781
|
/* Split token - Dark Theme */
|
|
781
782
|
--topside-dividing-line-color: #4a4a4a;
|
|
783
|
+
--topside-divider-grip-color: #8a8a8a;
|
|
782
784
|
/* Switch token - Dark Theme */
|
|
783
785
|
--topside-switch-color-text-unchecked: #9CA3AF;
|
|
784
786
|
--topside-switch-color-text-checked: #FFFFFF;
|
|
@@ -44,7 +44,7 @@
|
|
|
44
44
|
| [AppTopBar](./app-top-bar/README.md) | `@ticatec/topside-elements/AppTopBar` | [示例](./app-top-bar/example.svelte) | 6 |
|
|
45
45
|
| [Box](./box/README.md) | `@ticatec/topside-elements/Box` | [示例](./box/example.svelte) | 8 |
|
|
46
46
|
| [CriteriaField](./criteria-field/README.md) | `@ticatec/topside-elements/CriteriaField` | [示例](./criteria-field/example.svelte) | 7 |
|
|
47
|
-
| [FlexForm](./
|
|
47
|
+
| [FlexForm](./flex-form/README.md) | `@ticatec/topside-elements/FlexForm` | [示例](./flex-form/example.svelte) | 3 |
|
|
48
48
|
| [FlexRowForm](./flex-row-form/README.md) | `@ticatec/topside-elements/FlexRowForm` | [示例](./flex-row-form/example.svelte) | 4 |
|
|
49
49
|
| [FormField](./form-field/README.md) | `@ticatec/topside-elements/FormField` | [示例](./form-field/example.svelte) | 11 |
|
|
50
50
|
| [GridForm](./grid-form/README.md) | `@ticatec/topside-elements/GridForm` | [示例](./grid-form/example.svelte) | 5 |
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
|
|
101
101
|
| 组件 | 导入路径 | 示例 | 属性数 |
|
|
102
102
|
| --- | --- | --- | ---: |
|
|
103
|
-
| [DataTable](./data-table/README.md) | `@ticatec/topside-elements/DataTable` | [示例](./data-table/example.svelte) |
|
|
103
|
+
| [DataTable](./data-table/README.md) | `@ticatec/topside-elements/DataTable` | [示例](./data-table/example.svelte) | 17 |
|
|
104
104
|
|
|
105
105
|
## 数据展示
|
|
106
106
|
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
| [Icon](./icon/README.md) | `@ticatec/topside-elements/Icon` | [示例](./icon/example.svelte) | 8 |
|
|
121
121
|
| [IconButton](./icon-button/README.md) | `@ticatec/topside-elements/IconButton` | [示例](./icon-button/example.svelte) | 12 |
|
|
122
122
|
| [Separator](./separator/README.md) | `@ticatec/topside-elements/Separator` | [示例](./separator/example.svelte) | 2 |
|
|
123
|
-
| [Split](./split/README.md) | `@ticatec/topside-elements/Split` | [示例](./split/example.svelte) |
|
|
123
|
+
| [Split](./split/README.md) | `@ticatec/topside-elements/Split` | [示例](./split/example.svelte) | 10 |
|
|
124
124
|
| [Tag](./tag/README.md) | `@ticatec/topside-elements/Tag` | [示例](./tag/example.svelte) | 10 |
|
|
125
125
|
| [TextButton](./text-button/README.md) | `@ticatec/topside-elements/TextButton` | [示例](./text-button/example.svelte) | 13 |
|
|
126
126
|
|
|
@@ -192,9 +192,9 @@ export default interface DataColumn {
|
|
|
192
192
|
hint?: CellHint;
|
|
193
193
|
|
|
194
194
|
/**
|
|
195
|
-
*
|
|
195
|
+
* 自定义单元格渲染器(可为 Svelte 组件或 `{ component, props }` 配置对象)
|
|
196
196
|
*/
|
|
197
|
-
render?:
|
|
197
|
+
render?: ColumnRender;
|
|
198
198
|
|
|
199
199
|
/**
|
|
200
200
|
*
|
|
@@ -215,6 +215,19 @@ export default interface DataColumn {
|
|
|
215
215
|
* 获取表格的样式
|
|
216
216
|
*/
|
|
217
217
|
cellStyle?: GetCellStyle;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* 合计行里本列的聚合方式:sum / avg / count / min / max / 自定义函数;
|
|
221
|
+
* 'label' 表示在本列显示合计标签(没有指示列时用)。
|
|
222
|
+
* 只要有一列设置了(或 table 的 summaryValues 覆盖了某列),表格底部就会出现合计行。
|
|
223
|
+
*/
|
|
224
|
+
summary?: SummaryKind | SummaryFn | 'label';
|
|
225
|
+
|
|
226
|
+
/**
|
|
227
|
+
* 合计值的格式化。不设时:count 显示整数(千分位);其它先用 formatter,再退回数字自动格式化
|
|
228
|
+
* (千分位,小数位取本列数据最大小数位,avg 至少 2 位)
|
|
229
|
+
*/
|
|
230
|
+
summaryFormatter?: (value: any, rows: Array<any>) => string;
|
|
218
231
|
}
|
|
219
232
|
```
|
|
220
233
|
|
|
@@ -236,6 +249,14 @@ export type HrefBuilder = (item: any) => Array<HrefLink> | HrefLink | string;
|
|
|
236
249
|
export type CellHint = (value: any) => string;
|
|
237
250
|
```
|
|
238
251
|
|
|
252
|
+
### `ColumnRender`
|
|
253
|
+
|
|
254
|
+
```ts
|
|
255
|
+
export type ColumnRender<Props extends Record<string, any> = Record<string, any>> =
|
|
256
|
+
| Component<any>
|
|
257
|
+
| ColumnRenderObject<Props>;
|
|
258
|
+
```
|
|
259
|
+
|
|
239
260
|
### `CompareFn`
|
|
240
261
|
|
|
241
262
|
```ts
|
|
@@ -248,6 +269,18 @@ export type CompareFn = (o1: any, o2: any) => number;
|
|
|
248
269
|
export type GetCellStyle = (data: any) => string;
|
|
249
270
|
```
|
|
250
271
|
|
|
272
|
+
### `SummaryKind`
|
|
273
|
+
|
|
274
|
+
```ts
|
|
275
|
+
export type SummaryKind = 'sum' | 'avg' | 'count' | 'min' | 'max';
|
|
276
|
+
```
|
|
277
|
+
|
|
278
|
+
### `SummaryFn`
|
|
279
|
+
|
|
280
|
+
```ts
|
|
281
|
+
export type SummaryFn = (values: Array<any>, rows: Array<any>) => any;
|
|
282
|
+
```
|
|
283
|
+
|
|
251
284
|
### `HrefLink`
|
|
252
285
|
|
|
253
286
|
```ts
|
|
@@ -263,6 +296,23 @@ export default interface HrefLink {
|
|
|
263
296
|
}
|
|
264
297
|
```
|
|
265
298
|
|
|
299
|
+
### `ColumnRenderObject`
|
|
300
|
+
|
|
301
|
+
```ts
|
|
302
|
+
export interface ColumnRenderObject<Props extends Record<string, any> = Record<string, any>> {
|
|
303
|
+
/**
|
|
304
|
+
* 自定义 Svelte 单元格组件。
|
|
305
|
+
* 组件会接收 `props` 中传入的属性,并自动接收当前行的数据 `data`。
|
|
306
|
+
*/
|
|
307
|
+
component: Component<any>;
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* 传递给自定义组件的额外属性
|
|
311
|
+
*/
|
|
312
|
+
props?: Props;
|
|
313
|
+
}
|
|
314
|
+
```
|
|
315
|
+
|
|
266
316
|
### `OnHrefClick`
|
|
267
317
|
|
|
268
318
|
```ts
|
|
@@ -36,6 +36,8 @@ import DataTable from '@ticatec/topside-elements/DataTable';
|
|
|
36
36
|
| `style` | 否 | `string` | 否 | `''` | 否 | 附加到组件根元素的内联样式。 |
|
|
37
37
|
| `virtual` | 否 | `boolean` | 否 | `false` | 否 | 行虚拟化(窗口化渲染):仅渲染可视区域附近的行,大数据集(数千行以上) 建议开启。要求所有行高度一致(即统一的 rowHeight),因此默认关闭。 |
|
|
38
38
|
| `overscan` | 否 | `number` | 否 | `8` | 否 | 虚拟化时可视区上下额外渲染的行数。 |
|
|
39
|
+
| `summaryLabel` | 否 | `string` | 否 | `undefined` | 否 | 合计行的标签,默认取 i18n(uniface.dataTable.summaryLabel,"合计" / "Total");传空串则不显示标签 |
|
|
40
|
+
| `summaryValues` | 否 | `Record<string, any> \| null` | 否 | `null` | 否 | 外部提供的合计值,按列 field 取值,优先于列的 summary 在当前 list 上的计算。 分页场景下用它显示服务端算好的全量合计(数字串会按数字格式化)。 |
|
|
39
41
|
|
|
40
42
|
> 组件的“可绑定”表示源码使用了 Svelte 5 的 `$bindable`;服务的“响应式”表示成员使用了 `$state`。复杂类型请同时参考 TypeScript 自动补全。
|
|
41
43
|
|
|
@@ -143,9 +145,9 @@ export default interface DataColumn {
|
|
|
143
145
|
hint?: CellHint;
|
|
144
146
|
|
|
145
147
|
/**
|
|
146
|
-
*
|
|
148
|
+
* 自定义单元格渲染器(可为 Svelte 组件或 `{ component, props }` 配置对象)
|
|
147
149
|
*/
|
|
148
|
-
render?:
|
|
150
|
+
render?: ColumnRender;
|
|
149
151
|
|
|
150
152
|
/**
|
|
151
153
|
*
|
|
@@ -166,6 +168,19 @@ export default interface DataColumn {
|
|
|
166
168
|
* 获取表格的样式
|
|
167
169
|
*/
|
|
168
170
|
cellStyle?: GetCellStyle;
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* 合计行里本列的聚合方式:sum / avg / count / min / max / 自定义函数;
|
|
174
|
+
* 'label' 表示在本列显示合计标签(没有指示列时用)。
|
|
175
|
+
* 只要有一列设置了(或 table 的 summaryValues 覆盖了某列),表格底部就会出现合计行。
|
|
176
|
+
*/
|
|
177
|
+
summary?: SummaryKind | SummaryFn | 'label';
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* 合计值的格式化。不设时:count 显示整数(千分位);其它先用 formatter,再退回数字自动格式化
|
|
181
|
+
* (千分位,小数位取本列数据最大小数位,avg 至少 2 位)
|
|
182
|
+
*/
|
|
183
|
+
summaryFormatter?: (value: any, rows: Array<any>) => string;
|
|
169
184
|
}
|
|
170
185
|
```
|
|
171
186
|
|
|
@@ -265,6 +280,14 @@ export type HrefBuilder = (item: any) => Array<HrefLink> | HrefLink | string;
|
|
|
265
280
|
export type CellHint = (value: any) => string;
|
|
266
281
|
```
|
|
267
282
|
|
|
283
|
+
### `ColumnRender`
|
|
284
|
+
|
|
285
|
+
```ts
|
|
286
|
+
export type ColumnRender<Props extends Record<string, any> = Record<string, any>> =
|
|
287
|
+
| Component<any>
|
|
288
|
+
| ColumnRenderObject<Props>;
|
|
289
|
+
```
|
|
290
|
+
|
|
268
291
|
### `CompareFn`
|
|
269
292
|
|
|
270
293
|
```ts
|
|
@@ -277,6 +300,18 @@ export type CompareFn = (o1: any, o2: any) => number;
|
|
|
277
300
|
export type GetCellStyle = (data: any) => string;
|
|
278
301
|
```
|
|
279
302
|
|
|
303
|
+
### `SummaryKind`
|
|
304
|
+
|
|
305
|
+
```ts
|
|
306
|
+
export type SummaryKind = 'sum' | 'avg' | 'count' | 'min' | 'max';
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### `SummaryFn`
|
|
310
|
+
|
|
311
|
+
```ts
|
|
312
|
+
export type SummaryFn = (values: Array<any>, rows: Array<any>) => any;
|
|
313
|
+
```
|
|
314
|
+
|
|
280
315
|
### `GetRowActions`
|
|
281
316
|
|
|
282
317
|
```ts
|
|
@@ -317,6 +352,23 @@ export default interface HrefLink {
|
|
|
317
352
|
}
|
|
318
353
|
```
|
|
319
354
|
|
|
355
|
+
### `ColumnRenderObject`
|
|
356
|
+
|
|
357
|
+
```ts
|
|
358
|
+
export interface ColumnRenderObject<Props extends Record<string, any> = Record<string, any>> {
|
|
359
|
+
/**
|
|
360
|
+
* 自定义 Svelte 单元格组件。
|
|
361
|
+
* 组件会接收 `props` 中传入的属性,并自动接收当前行的数据 `data`。
|
|
362
|
+
*/
|
|
363
|
+
component: Component<any>;
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* 传递给自定义组件的额外属性
|
|
367
|
+
*/
|
|
368
|
+
props?: Props;
|
|
369
|
+
}
|
|
370
|
+
```
|
|
371
|
+
|
|
320
372
|
### `RowAction`
|
|
321
373
|
|
|
322
374
|
```ts
|
|
@@ -348,12 +400,6 @@ export type OnHrefClick = () => void;
|
|
|
348
400
|
export type ButtonType = 'default' | 'primary' | 'secondary' | 'third' | 'forth';
|
|
349
401
|
```
|
|
350
402
|
|
|
351
|
-
### `ActionHandler`
|
|
352
|
-
|
|
353
|
-
```ts
|
|
354
|
-
export type ActionHandler<T = any> = (data: T) => void | Promise<void>;
|
|
355
|
-
```
|
|
356
|
-
|
|
357
403
|
## 示例
|
|
358
404
|
|
|
359
405
|
完整示例见 [example.svelte](./example.svelte)。
|
|
@@ -21,11 +21,16 @@ import Split from '@ticatec/topside-elements/Split';
|
|
|
21
21
|
|
|
22
22
|
| 属性 | 重要 | 类型 | 必填 | 默认值 | 可绑定/响应式 | 说明 |
|
|
23
23
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
24
|
-
| `direction` | 否 | `"horizontal" \| "vertical"` | 否 | `"vertical"` | 否 |
|
|
25
|
-
| `width` | 否 | `number` | 否 | `
|
|
26
|
-
| `bindingPanel` | 否 | `HTMLElement` | 否 | `undefined` | 否 |
|
|
27
|
-
| `reverse` | 否 | `boolean` | 否 | `false` | 否 |
|
|
28
|
-
| `
|
|
24
|
+
| `direction` | 否 | `"horizontal" \| "vertical"` | 否 | `"vertical"` | 否 | 分隔线朝向:vertical 竖线(左右分栏),horizontal 横线(上下分栏) |
|
|
25
|
+
| `width` | 否 | `number` | 否 | `1` | 否 | 可见线条粗细(px),占布局,默认 1 |
|
|
26
|
+
| `bindingPanel` | 否 | `HTMLElement` | 否 | `undefined` | 否 | 被拖动调整尺寸的面板;不传则为固定分隔线 |
|
|
27
|
+
| `reverse` | 否 | `boolean` | 否 | `false` | 否 | 绑定面板在分隔线右侧 / 下方时设为 true |
|
|
28
|
+
| `color` | 否 | `string` | 否 | `undefined` | 否 | 线条底色,默认取 --topside-dividing-line-color |
|
|
29
|
+
| `gripColor` | 否 | `string` | 否 | `undefined` | 否 | 悬停 / 拖动时中间把手的颜色,默认取 --topside-divider-grip-color |
|
|
30
|
+
| `gripSize` | 否 | `number` | 否 | `3` | 否 | 把手粗细(px),默认 3 |
|
|
31
|
+
| `gripLength` | 否 | `number` | 否 | `32` | 否 | 把手长度(px),默认 32;传 0 表示整条加粗 |
|
|
32
|
+
| `hitSize` | 否 | `number` | 否 | `8` | 否 | 鼠标感应区厚度(px),不占布局,默认 8 |
|
|
33
|
+
| `onResizeEnd` | 否 | `(size: number) => void` | 否 | `undefined` | 否 | 拖动结束时回调,参数为绑定面板最终宽 / 高(px) |
|
|
29
34
|
|
|
30
35
|
> 组件的“可绑定”表示源码使用了 Svelte 5 的 `$bindable`;服务的“响应式”表示成员使用了 `$state`。复杂类型请同时参考 TypeScript 自动补全。
|
|
31
36
|
|
package/package.json
CHANGED