@manohub/ui 0.7.0 → 0.8.0
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 +4 -4
- package/dist/components/button/index.d.ts +14 -8
- package/dist/components/capsule/index.d.ts +13 -9
- package/dist/components/capsule/index.js +1 -1
- package/dist/components/card/index.d.ts +1 -1
- package/dist/components/card/index.js +7 -4
- package/dist/components/checkbox/index.js +1 -0
- package/dist/components/dialog/index.d.ts +1 -1
- package/dist/components/form/index.d.ts +142 -62
- package/dist/components/form/index.js +41 -29
- package/dist/components/input/index.d.ts +74 -6
- package/dist/components/input/index.js +13 -1
- package/dist/components/layout/index.d.ts +43 -1
- package/dist/components/layout/index.js +22 -2
- package/dist/components/list-view/index.d.ts +1 -1
- package/dist/components/notice/index.d.ts +2 -2
- package/dist/components/notification/index.d.ts +2 -2
- package/dist/components/page/index.js +4 -4
- package/dist/components/pagination/index.d.ts +2 -2
- package/dist/components/pagination/index.js +1 -1
- package/dist/components/panel/index.js +4 -4
- package/dist/components/part-padding.d.ts +9 -6
- package/dist/components/part-padding.js +2 -1
- package/dist/components/query-state/index.d.ts +18 -2
- package/dist/components/radio/index.d.ts +1 -1
- package/dist/components/radio/index.js +1 -0
- package/dist/components/select/index.d.ts +32 -30
- package/dist/components/select/index.js +46 -82
- package/dist/components/select/select-list.d.ts +125 -0
- package/dist/components/select/select-list.js +95 -0
- package/dist/components/select/select-panel.d.ts +106 -0
- package/dist/components/select/select-panel.js +72 -0
- package/dist/components/select/select-shared.d.ts +64 -0
- package/dist/components/select/select-shared.js +24 -0
- package/dist/components/select/select-tree-filter.d.ts +61 -0
- package/dist/components/select/select-tree-filter.js +63 -0
- package/dist/components/select/select-tree.d.ts +274 -0
- package/dist/components/select/select-tree.js +263 -0
- package/dist/components/select/select-trigger.d.ts +132 -0
- package/dist/components/select/select-trigger.js +101 -0
- package/dist/components/steps/index.d.ts +232 -6
- package/dist/components/steps/index.js +84 -26
- package/dist/components/switch/index.d.ts +29 -5
- package/dist/components/switch/index.js +8 -2
- package/dist/components/tabbar/index.d.ts +184 -0
- package/dist/components/tabbar/index.js +161 -0
- package/dist/components/table/index.d.ts +99 -12
- package/dist/components/table/index.js +69 -16
- package/dist/components/tabs/index.d.ts +142 -126
- package/dist/components/tabs/index.js +87 -119
- package/dist/components/tag/index.d.ts +2 -2
- package/dist/components/text/index.d.ts +7 -2
- package/dist/components/toast/index.d.ts +8 -8
- package/dist/components/tree/index.d.ts +28 -2
- package/dist/components/tree/index.js +14 -1
- package/dist/index.d.ts +6 -6
- package/dist/index.js +6 -3
- package/dist/styles/components/capsule.css +4 -4
- package/dist/styles/components/form.css +198 -39
- package/dist/styles/components/input.css +53 -1
- package/dist/styles/components/layout.css +2 -0
- package/dist/styles/components/select.css +21 -0
- package/dist/styles/components/select.tokens.css +3 -0
- package/dist/styles/components/steps.css +48 -0
- package/dist/styles/components/{tabs.css → tabbar.css} +66 -65
- package/dist/styles/components/tabbar.tokens.css +30 -0
- package/dist/styles/components/table.css +50 -1
- package/dist/styles/components/table.tokens.css +3 -0
- package/dist/styles/index.css +3 -3
- package/dist/styles/operations/tabs.css +73 -0
- package/package.json +2 -2
- package/dist/components/tabset/index.d.ts +0 -109
- package/dist/components/tabset/index.js +0 -75
- package/dist/styles/components/tabs.tokens.css +0 -30
- package/dist/styles/operations/tabset.css +0 -57
|
@@ -24,9 +24,18 @@ const Table = /* @__PURE__ */ defineComponent({
|
|
|
24
24
|
type: Array,
|
|
25
25
|
default: void 0
|
|
26
26
|
},
|
|
27
|
-
/**
|
|
27
|
+
/**
|
|
28
|
+
* 选择列:`false` = 不出选择列;`true` = 全表可勾选;**函数 = 按行判定可勾选性**。
|
|
29
|
+
*
|
|
30
|
+
* 函数形态下,返回 `false` 的行渲染**禁用态**勾选框(`Checkbox` 自带置灰外观 +
|
|
31
|
+
* `cursor: not-allowed`),且**不进表头全选的增删范围**;整表都不可勾选时,表头勾选框自身禁用。
|
|
32
|
+
*
|
|
33
|
+
* ⚠️ 「有没有选择列」只由 `selectable === false` 决定 —— 函数形态**恒渲染**选择列。
|
|
34
|
+
* ⚠️ 别用「受控回弹」在调用方模拟行级禁用:本件是全受控(`selected = props.modelValue`),
|
|
35
|
+
* 被忽略的上报**不会**让原生 `input.checked` 复位,会留下「整行点亮却不在选中集」的假象。
|
|
36
|
+
*/
|
|
28
37
|
selectable: {
|
|
29
|
-
type: Boolean,
|
|
38
|
+
type: [Boolean, Function],
|
|
30
39
|
default: false
|
|
31
40
|
},
|
|
32
41
|
/** 斑马纹(**显式类**而非 nth-child:表里可能有分组行) */
|
|
@@ -53,6 +62,19 @@ const Table = /* @__PURE__ */ defineComponent({
|
|
|
53
62
|
type: Boolean,
|
|
54
63
|
default: false
|
|
55
64
|
},
|
|
65
|
+
/**
|
|
66
|
+
* 布局档(只决定 `<table>` 的 `table-layout`;**列宽一律由 `<colgroup>` 下发,与档位无关**):
|
|
67
|
+
*
|
|
68
|
+
* - `auto`(缺省)—— 列宽随内容自适应。`column.width` 是**建议值**,
|
|
69
|
+
* 长文本(尤其中文长串 / 无空格串)会顶破列宽把表格撑得比容器还宽 ⇒ 包裹层出横向滚动条。
|
|
70
|
+
* - `fixed` —— `table-layout: fixed`:列宽受声明约束、**不再被内容撑破**,
|
|
71
|
+
* 于是百分比 / 数字权重可以「吃满容器 + 严格按比例」。代价:长文本列要显式 `ellipsis: true`,
|
|
72
|
+
* 否则会**换行**(行高变高)。
|
|
73
|
+
*/
|
|
74
|
+
layout: {
|
|
75
|
+
type: String,
|
|
76
|
+
default: "auto"
|
|
77
|
+
},
|
|
56
78
|
stickyHead: {
|
|
57
79
|
type: Boolean,
|
|
58
80
|
default: false
|
|
@@ -135,10 +157,15 @@ const Table = /* @__PURE__ */ defineComponent({
|
|
|
135
157
|
attrs,
|
|
136
158
|
emit
|
|
137
159
|
}) {
|
|
138
|
-
const keys = computed(() => props.data.map((row) => row[props.rowKey]));
|
|
139
160
|
const selected = computed(() => props.modelValue ?? []);
|
|
140
|
-
const
|
|
141
|
-
const
|
|
161
|
+
const hasSelectColumn = computed(() => props.selectable !== false);
|
|
162
|
+
const isRowSelectable = (row, index) => typeof props.selectable === "function" ? props.selectable(row, index) !== false : props.selectable !== false;
|
|
163
|
+
const selectableKeys = computed(() => props.data.filter((row, index) => isRowSelectable(row, index)).map((row) => row[props.rowKey]));
|
|
164
|
+
const selectableKeySet = computed(() => new Set(selectableKeys.value));
|
|
165
|
+
const selectedSelectable = computed(() => selected.value.filter((key) => selectableKeySet.value.has(key)));
|
|
166
|
+
const allSelected = computed(() => selectableKeys.value.length > 0 && selectedSelectable.value.length >= selectableKeys.value.length);
|
|
167
|
+
const someSelected = computed(() => selectedSelectable.value.length > 0 && !allSelected.value);
|
|
168
|
+
const headerCheckboxDisabled = computed(() => selectableKeys.value.length === 0);
|
|
142
169
|
const innerExpanded = ref(props.defaultExpandedKeys);
|
|
143
170
|
const expanded = computed(() => props.expandedKeys ?? innerExpanded.value);
|
|
144
171
|
const toggleExpand = (key) => {
|
|
@@ -147,19 +174,45 @@ const Table = /* @__PURE__ */ defineComponent({
|
|
|
147
174
|
props.onExpandChange?.(next);
|
|
148
175
|
};
|
|
149
176
|
const resolvedSize = computed(() => props.compact ? "sm" : props.size);
|
|
150
|
-
const leadColumns = computed(() => (
|
|
177
|
+
const leadColumns = computed(() => (hasSelectColumn.value ? 1 : 0) + (props.expandable ? 1 : 0));
|
|
151
178
|
const columnCount = computed(() => leadColumns.value + props.columns.length);
|
|
152
179
|
const isEmpty = computed(() => props.data.length === 0);
|
|
153
180
|
const cellClass = (column) => [column.align === "center" ? "mh-table__cell-center" : "", column.align === "right" ? "mh-table__cell-amount" : "", column.ellipsis ? "mh-table__cell-ellipsis" : ""].filter(Boolean);
|
|
181
|
+
const colStyles = computed(() => {
|
|
182
|
+
const weightSum = props.columns.reduce((sum, item) => typeof item.width === "number" ? sum + item.width : sum, 0);
|
|
183
|
+
return props.columns.map((column) => {
|
|
184
|
+
const style = {};
|
|
185
|
+
if (typeof column.width === "number") {
|
|
186
|
+
if (weightSum > 0) style.width = `${Number((column.width / weightSum * 100).toFixed(4))}%`;
|
|
187
|
+
} else if (column.width) {
|
|
188
|
+
style.width = column.width;
|
|
189
|
+
}
|
|
190
|
+
if (column.minWidth) style.minWidth = `${column.minWidth}px`;
|
|
191
|
+
return style;
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
const colElements = () => createVNode("colgroup", null, [props.expandable ? createVNode("col", null, null) : null, hasSelectColumn.value ? createVNode("col", null, null) : null, props.columns.map((column, index) => createVNode("col", {
|
|
195
|
+
"key": column.key,
|
|
196
|
+
"style": colStyles.value[index]
|
|
197
|
+
}, null))]);
|
|
154
198
|
const commit = (next) => {
|
|
155
199
|
emit("update:modelValue", next);
|
|
156
200
|
emit("change", next);
|
|
157
201
|
};
|
|
158
202
|
const toggleRow = (key) => {
|
|
203
|
+
if (!selectableKeySet.value.has(key)) return;
|
|
159
204
|
const has = selected.value.includes(key);
|
|
160
205
|
commit(has ? selected.value.filter((item) => item !== key) : [...selected.value, key]);
|
|
161
206
|
};
|
|
162
|
-
const toggleAll = () =>
|
|
207
|
+
const toggleAll = () => {
|
|
208
|
+
if (headerCheckboxDisabled.value) return;
|
|
209
|
+
if (allSelected.value) {
|
|
210
|
+
commit(selected.value.filter((key) => !selectableKeySet.value.has(key)));
|
|
211
|
+
return;
|
|
212
|
+
}
|
|
213
|
+
const keep = selected.value.filter((key) => !selectableKeySet.value.has(key));
|
|
214
|
+
commit([...keep, ...selectableKeys.value]);
|
|
215
|
+
};
|
|
163
216
|
const nextOrder = (key) => {
|
|
164
217
|
if (props.sortKey !== key) return "asc";
|
|
165
218
|
if (props.sortOrder === "asc") return "desc";
|
|
@@ -168,7 +221,7 @@ const Table = /* @__PURE__ */ defineComponent({
|
|
|
168
221
|
};
|
|
169
222
|
const sortGlyph = (key) => props.sortKey === key && props.sortOrder === "asc" ? "chevron-up" : "chevron-down";
|
|
170
223
|
return () => {
|
|
171
|
-
const tableClass = ["mh-table", resolvedSize.value === "sm" ? "mh-table--xs" : "", resolvedSize.value === "lg" ? "mh-table--lg" : "", props.borderless ? "mh-table--borderless" : "", props.fill ? "mh-table--fill" : "", props.stickyHead ? "mh-table--sticky-head" : "", props.stickyCol ? "mh-table--sticky-col" : "", attrs.class].filter(Boolean).join(" ");
|
|
224
|
+
const tableClass = ["mh-table", resolvedSize.value === "sm" ? "mh-table--xs" : "", resolvedSize.value === "lg" ? "mh-table--lg" : "", props.borderless ? "mh-table--borderless" : "", props.fill ? "mh-table--fill" : "", props.layout === "fixed" ? "mh-table--fixed" : "", props.stickyHead ? "mh-table--sticky-head" : "", props.stickyCol ? "mh-table--sticky-col" : "", attrs.class].filter(Boolean).join(" ");
|
|
172
225
|
const pager = typeof props.pagination === "object" ? props.pagination : null;
|
|
173
226
|
return createVNode("div", {
|
|
174
227
|
"class": "mh-table-wrapper",
|
|
@@ -179,22 +232,20 @@ const Table = /* @__PURE__ */ defineComponent({
|
|
|
179
232
|
selected: selected.value
|
|
180
233
|
})]) : null, createVNode("table", {
|
|
181
234
|
"class": tableClass
|
|
182
|
-
}, [props.showHeader ? createVNode("thead", null, [createVNode("tr", null, [props.expandable ? createVNode("th", {
|
|
235
|
+
}, [colElements(), props.showHeader ? createVNode("thead", null, [createVNode("tr", null, [props.expandable ? createVNode("th", {
|
|
183
236
|
"class": "mh-table__col-expand",
|
|
184
237
|
"aria-label": "展开"
|
|
185
|
-
}, null) : null,
|
|
238
|
+
}, null) : null, hasSelectColumn.value ? createVNode("th", {
|
|
186
239
|
"class": "mh-table__col-check"
|
|
187
240
|
}, [createVNode(Checkbox, {
|
|
188
241
|
"aria-label": "全选",
|
|
189
242
|
"modelValue": allSelected.value,
|
|
190
243
|
"indeterminate": someSelected.value && !allSelected.value,
|
|
244
|
+
"disabled": headerCheckboxDisabled.value,
|
|
191
245
|
"onChange": toggleAll
|
|
192
246
|
}, null)]) : null, props.columns.map((column) => createVNode("th", {
|
|
193
247
|
"key": column.key,
|
|
194
|
-
"class": [column.required ? "mh-table__cell-required" : "", column.align === "center" ? "mh-table__cell-center" : "", column.align === "right" ? "mh-table__col-actions" : ""].filter(Boolean).join(" ")
|
|
195
|
-
"style": column.width ? {
|
|
196
|
-
width: column.width
|
|
197
|
-
} : void 0
|
|
248
|
+
"class": [column.required ? "mh-table__cell-required" : "", column.align === "center" ? "mh-table__cell-center" : "", column.align === "right" ? "mh-table__col-actions" : ""].filter(Boolean).join(" ")
|
|
198
249
|
}, [column.title, column.sortable ? createVNode("button", {
|
|
199
250
|
"type": "button",
|
|
200
251
|
"class": ["mh-table__sort", props.sortKey === column.key && props.sortOrder ? "mh-table__sort--active" : ""].filter(Boolean).join(" "),
|
|
@@ -235,16 +286,18 @@ const Table = /* @__PURE__ */ defineComponent({
|
|
|
235
286
|
}, [createVNode(Icon, {
|
|
236
287
|
"name": "chevron-down",
|
|
237
288
|
"class": "mh-table__expand-icon"
|
|
238
|
-
}, null)])]) : null,
|
|
289
|
+
}, null)])]) : null, hasSelectColumn.value ? (
|
|
239
290
|
/* 勾选列复用 `Checkbox`(不在表格里手写原生 input)。行本身可能带 onClick(onRow):
|
|
240
291
|
勾选不该顺带触发行点击 —— 阻断挂在**单元格**上,因为 `Checkbox` 的根是 `label`,
|
|
241
|
-
点它会冒泡两次(label 自身一次 + 转发给 input 一次),只挡 input 挡不住行点击。
|
|
292
|
+
点它会冒泡两次(label 自身一次 + 转发给 input 一次),只挡 input 挡不住行点击。
|
|
293
|
+
`selectable` 为函数时逐行判定:返回 `false` 的行给禁用态(置灰 + not-allowed)。 */
|
|
242
294
|
createVNode("td", {
|
|
243
295
|
"class": "mh-table__col-check",
|
|
244
296
|
"onClick": (event) => event.stopPropagation()
|
|
245
297
|
}, [createVNode(Checkbox, {
|
|
246
298
|
"aria-label": "选择本行",
|
|
247
299
|
"modelValue": selected.value.includes(key),
|
|
300
|
+
"disabled": !isRowSelectable(row, index),
|
|
248
301
|
"onChange": () => toggleRow(key)
|
|
249
302
|
}, null)])
|
|
250
303
|
) : null, props.columns.map((column) => createVNode("td", {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { type PropType, type SlotsType, type VNodeChild } from 'vue';
|
|
2
|
-
|
|
1
|
+
import { type PropType, type SlotsType, type VNode, type VNodeChild } from 'vue';
|
|
2
|
+
/** 轨道项:`Tabs` 从 `TabPanel` 提取(写了面板时)或由 `options` 直接给(老写法) */
|
|
3
3
|
export interface TabsOption {
|
|
4
4
|
/** 项文字 */
|
|
5
5
|
label: string;
|
|
@@ -7,177 +7,193 @@ export interface TabsOption {
|
|
|
7
7
|
value: string | number;
|
|
8
8
|
/** 禁用项:不可选 */
|
|
9
9
|
disabled?: boolean;
|
|
10
|
-
/** 单项可关(`closable` 打开时用它例外掉某些项) */
|
|
11
|
-
closable?: boolean;
|
|
12
10
|
}
|
|
13
|
-
export
|
|
14
|
-
/**
|
|
15
|
-
|
|
11
|
+
export interface TabsProps {
|
|
12
|
+
/** 轨道项:**只在默认插槽里没写 `TabPanel` 时**才读(老写法,按顺序与面板一一配对) */
|
|
13
|
+
options?: TabsOption[];
|
|
14
|
+
/** 受控选中值;不传即非受控(由 `defaultValue` 起) */
|
|
15
|
+
value?: string | number;
|
|
16
|
+
/** 非受控初始选中值,缺省第一个可选项的值 */
|
|
17
|
+
defaultValue?: string | number;
|
|
18
|
+
/** 选中变化回调(受控与非受控都会调) */
|
|
19
|
+
onChange?: (value: string | number) => void;
|
|
20
|
+
/** 惰性档:只有激活的面板才渲染(切走即卸载),用于面板很重(图表 / 大表格)的场景 */
|
|
21
|
+
lazy?: boolean;
|
|
22
|
+
}
|
|
23
|
+
/** 一块面板的信息(本件只承载这些,自己不画任何东西) */
|
|
24
|
+
export interface TabPanelProps {
|
|
25
|
+
/** 页签名:轨道上的文字,同时是缺省项值(项值另有要求时用 `value` 覆盖) */
|
|
26
|
+
name: string;
|
|
27
|
+
/** 显式项值;不传即用 `name` */
|
|
28
|
+
value?: string | number;
|
|
29
|
+
/** 禁用项:不可选(组件路径没有原生约束,`Tabs` 会自己兜) */
|
|
30
|
+
disabled?: boolean;
|
|
31
|
+
/** 惰性档:切走即卸载(与 `Tabs` 的同名档取或) */
|
|
32
|
+
lazy?: boolean;
|
|
33
|
+
}
|
|
16
34
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* ## 与 `Tabset` / `Capsule` 的分工(三者都能"切换",判据在**可见形态**)
|
|
20
|
-
*
|
|
21
|
-
* - 本件:**页签条**(`line` 下划线 / `card` 选项卡,页面级分区切换)—— 就是这一族的皮肤;
|
|
22
|
-
* - `Capsule`:胶囊/分段按钮(块状选中底),用于筛选项那种"按钮感"切换;
|
|
23
|
-
* - `Tabset`:**骨架**(把某组互斥项与面板显隐接起来),它不含皮肤 —— 把本件塞进它的 `selector` 插槽即可。
|
|
24
|
-
*
|
|
25
|
-
* ## 指示条为什么不是一个滑块
|
|
26
|
-
*
|
|
27
|
-
* 每个项的指示条是它自己的伪元素、常驻但未选时 `opacity:0; scale:.75` —— "滑过去"的观感来自这两个属性的
|
|
28
|
-
* 过渡。做成一条共享滑块要 JS 量位置,且首帧会跳。**别在页签区加轨线**(会扣走区高 1px,规范明确警告)。
|
|
29
|
-
* (`card` 档不画指示条:选中由底色与顶边表达。)
|
|
35
|
+
* 面板:`Tabs` 的**信息入口**。
|
|
30
36
|
*
|
|
31
|
-
*
|
|
37
|
+
* 使用方只写面板自己的信息(`name` 等),`Tabs` 在渲染期把它提取成轨道项 ——
|
|
38
|
+
* 缺省就是页签条,要换皮就写 `Tabs` 的 `selector` 插槽(胶囊 / 分段按钮 / 单选卡片)。
|
|
32
39
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
40
|
+
* 本件**不画任何东西**:渲染即默认插槽直通。面板壳(`.mh-tabs-panel`)与显隐由 `Tabs` 出,
|
|
41
|
+
* 故挂在本件上的 `class` / `style` 会被搬到那块壳上(面板级样式改的是**壳** —— 内距、限高、
|
|
42
|
+
* 自己滚,挂到内容上就没有这层可改)。
|
|
35
43
|
*
|
|
36
|
-
* @example
|
|
37
|
-
* <Tabs
|
|
38
|
-
*
|
|
39
|
-
*
|
|
40
|
-
*
|
|
41
|
-
* :on-close="remove" :on-add="add" />
|
|
44
|
+
* @example
|
|
45
|
+
* <Tabs v-model:value="current">
|
|
46
|
+
* <TabPanel name="概览">…</TabPanel>
|
|
47
|
+
* <TabPanel name="工具" disabled>…</TabPanel>
|
|
48
|
+
* </Tabs>
|
|
42
49
|
*/
|
|
43
|
-
export declare const
|
|
44
|
-
|
|
45
|
-
type:
|
|
50
|
+
export declare const TabPanel: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
51
|
+
name: {
|
|
52
|
+
type: StringConstructor;
|
|
46
53
|
required: true;
|
|
47
54
|
};
|
|
48
|
-
/** 受控选中值;不传即非受控(由 `defaultValue` 起) */
|
|
49
55
|
value: {
|
|
50
|
-
type: PropType<
|
|
51
|
-
default: undefined;
|
|
52
|
-
};
|
|
53
|
-
/** 非受控初始选中值,缺省第一项 */
|
|
54
|
-
defaultValue: {
|
|
55
|
-
type: PropType<TabsValue | undefined>;
|
|
56
|
+
type: PropType<string | number | undefined>;
|
|
56
57
|
default: undefined;
|
|
57
58
|
};
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
default: undefined;
|
|
62
|
-
};
|
|
63
|
-
/** 形态:`line` 下划线 / `card` 选项卡 */
|
|
64
|
-
type: {
|
|
65
|
-
type: PropType<TabsType>;
|
|
66
|
-
default: string;
|
|
59
|
+
disabled: {
|
|
60
|
+
type: BooleanConstructor;
|
|
61
|
+
default: boolean;
|
|
67
62
|
};
|
|
68
|
-
|
|
69
|
-
centered: {
|
|
63
|
+
lazy: {
|
|
70
64
|
type: BooleanConstructor;
|
|
71
65
|
default: boolean;
|
|
72
66
|
};
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
67
|
+
}>, () => string | number | boolean | VNode<import("vue").RendererNode, import("vue").RendererElement, {
|
|
68
|
+
[key: string]: any;
|
|
69
|
+
}> | import("vue").VNodeArrayChildren | null, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
70
|
+
name: {
|
|
71
|
+
type: StringConstructor;
|
|
72
|
+
required: true;
|
|
73
|
+
};
|
|
74
|
+
value: {
|
|
75
|
+
type: PropType<string | number | undefined>;
|
|
76
|
+
default: undefined;
|
|
77
77
|
};
|
|
78
|
-
|
|
79
|
-
closable: {
|
|
78
|
+
disabled: {
|
|
80
79
|
type: BooleanConstructor;
|
|
81
80
|
default: boolean;
|
|
82
81
|
};
|
|
83
|
-
|
|
84
|
-
addable: {
|
|
82
|
+
lazy: {
|
|
85
83
|
type: BooleanConstructor;
|
|
86
84
|
default: boolean;
|
|
87
85
|
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
86
|
+
}>> & Readonly<{}>, {
|
|
87
|
+
disabled: boolean;
|
|
88
|
+
value: string | number | undefined;
|
|
89
|
+
lazy: boolean;
|
|
90
|
+
}, SlotsType<{
|
|
91
|
+
default?: () => VNodeChild;
|
|
92
|
+
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|
|
93
|
+
/**
|
|
94
|
+
* 面板切换(**操作层骨架 + 组件路径显隐**)。
|
|
95
|
+
*
|
|
96
|
+
* ## 它是什么
|
|
97
|
+
* 把「一组互斥选项」与「按顺序排列的面板」接起来:第 n 个选项 ↔ 第 n 块面板。
|
|
98
|
+
* 骨架(根、面板组、收起态)在操作层 `styles/operations/tabs.css`,本件负责:
|
|
99
|
+
* 受控值、从面板提取项、面板包装与显隐、把 `select` 交给选择控件。
|
|
100
|
+
*
|
|
101
|
+
* ## 信息从哪来(两条路,**写了 `TabPanel` 就以它为准**)
|
|
102
|
+
* - **`TabPanel`(推荐)**:面板自带 `name`(页签文字 + 缺省项值)、`value`、`disabled`、`lazy`,
|
|
103
|
+
* 本件在渲染期提取成轨道项 —— 使用方不必再维护一份与之平行的 `options`;
|
|
104
|
+
* - **`options`(老写法)**:默认插槽给裸节点,按顺序与 `options` 一一配对;
|
|
105
|
+
* 裸节点没有同序项时那块面板**永远不可见**(不越档)。
|
|
106
|
+
* 两条路不叠加:写了 `TabPanel` 的那次渲染里 `options` 不参与(两套并行声明必打架)。
|
|
107
|
+
*
|
|
108
|
+
* ## 选择控件从哪来(`selector` 插槽)
|
|
109
|
+
* - **不传插槽 = 用缺省皮肤 `TabBar`**(页签条形态)—— 绝大多数用法只要这一句;
|
|
110
|
+
* - 传插槽则整块替换:放 `Capsule`(胶囊)、按钮族的分段形态、单选卡片都行,
|
|
111
|
+
* 作用域参数 `{ value, options, select }` 把值、项(已含从 `TabPanel` 提取的那些)与选中回调
|
|
112
|
+
* 递出来。本件不认识任何选择控件的类名 —— **控制器与骨架零互指**,换皮肤不必动本件。
|
|
113
|
+
*
|
|
114
|
+
* ## 显隐只有一条路径
|
|
115
|
+
* 本件按受控值给非选中面板下发 `hidden`,**与控件形态无关**(是不是原生 radio 都一样)。
|
|
116
|
+
* 曾经的「零 JS 路径」(原生 radio + 操作层档位表 `:has(input:nth-of-type(n):checked)`)**已退役**:
|
|
117
|
+
* 写不出通式、上限 8 档、还要求开关与面板同父级同序 —— 局限远大于收益。
|
|
118
|
+
* 故拿 `Capsule` 当控件时**不必**再给它 `name`(那曾经只是给操作层认组用的)。
|
|
119
|
+
*
|
|
120
|
+
* ## 惰性档
|
|
121
|
+
* `lazy` 在 `Tabs` 与 `TabPanel` 上都可给(取或):非激活面板**不渲染**(切走即卸载)。
|
|
122
|
+
* 缺省档全部挂载、只用 `hidden` 藏 —— 保留面板内部状态(滚动位置、局部输入)。
|
|
123
|
+
*
|
|
124
|
+
* @example 最小用法:只写面板信息(缺省页签条)
|
|
125
|
+
* <Tabs v-model:value="current">
|
|
126
|
+
* <TabPanel name="概览">…</TabPanel>
|
|
127
|
+
* <TabPanel name="工具">…</TabPanel>
|
|
128
|
+
* </Tabs>
|
|
129
|
+
*
|
|
130
|
+
* @example 换皮:胶囊作选择控件
|
|
131
|
+
* <Tabs v-model:value="current">
|
|
132
|
+
* {{
|
|
133
|
+
* selector: ({ value, options, select }) =>
|
|
134
|
+
* <Capsule :options="options" modelValue={value} onChange={select} />,
|
|
135
|
+
* default: () => [<TabPanel name="概览">…</TabPanel>, <TabPanel name="工具">…</TabPanel>],
|
|
136
|
+
* }}
|
|
137
|
+
* </Tabs>
|
|
138
|
+
*/
|
|
139
|
+
export declare const Tabs: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
140
|
+
options: {
|
|
141
|
+
type: PropType<TabsOption[]>;
|
|
142
|
+
default: undefined;
|
|
92
143
|
};
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
type: PropType<(value: TabsValue) => void>;
|
|
144
|
+
value: {
|
|
145
|
+
type: PropType<string | number | undefined>;
|
|
96
146
|
default: undefined;
|
|
97
147
|
};
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
148
|
+
defaultValue: {
|
|
149
|
+
type: PropType<string | number | undefined>;
|
|
150
|
+
default: undefined;
|
|
151
|
+
};
|
|
152
|
+
onChange: {
|
|
153
|
+
type: PropType<(value: string | number) => void>;
|
|
101
154
|
default: undefined;
|
|
102
155
|
};
|
|
156
|
+
lazy: {
|
|
157
|
+
type: BooleanConstructor;
|
|
158
|
+
default: boolean;
|
|
159
|
+
};
|
|
103
160
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
104
|
-
'update:value': (value:
|
|
161
|
+
'update:value': (value: string | number) => true;
|
|
105
162
|
}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
106
163
|
options: {
|
|
107
164
|
type: PropType<TabsOption[]>;
|
|
108
|
-
|
|
165
|
+
default: undefined;
|
|
109
166
|
};
|
|
110
|
-
/** 受控选中值;不传即非受控(由 `defaultValue` 起) */
|
|
111
167
|
value: {
|
|
112
|
-
type: PropType<
|
|
168
|
+
type: PropType<string | number | undefined>;
|
|
113
169
|
default: undefined;
|
|
114
170
|
};
|
|
115
|
-
/** 非受控初始选中值,缺省第一项 */
|
|
116
171
|
defaultValue: {
|
|
117
|
-
type: PropType<
|
|
172
|
+
type: PropType<string | number | undefined>;
|
|
118
173
|
default: undefined;
|
|
119
174
|
};
|
|
120
|
-
/** 选中变化回调(受控与非受控都会调) */
|
|
121
175
|
onChange: {
|
|
122
|
-
type: PropType<(value:
|
|
176
|
+
type: PropType<(value: string | number) => void>;
|
|
123
177
|
default: undefined;
|
|
124
178
|
};
|
|
125
|
-
|
|
126
|
-
type: {
|
|
127
|
-
type: PropType<TabsType>;
|
|
128
|
-
default: string;
|
|
129
|
-
};
|
|
130
|
-
/** 整体居中(页签少、要撑满整行时用) */
|
|
131
|
-
centered: {
|
|
179
|
+
lazy: {
|
|
132
180
|
type: BooleanConstructor;
|
|
133
181
|
default: boolean;
|
|
134
182
|
};
|
|
135
|
-
/** 尺寸档(24 / 32 / 40,只覆盖令牌) */
|
|
136
|
-
size: {
|
|
137
|
-
type: PropType<ControlSize>;
|
|
138
|
-
default: string;
|
|
139
|
-
};
|
|
140
|
-
/** 每项带关闭位(单项可用 `option.closable` 覆写) */
|
|
141
|
-
closable: {
|
|
142
|
-
type: BooleanConstructor;
|
|
143
|
-
default: boolean;
|
|
144
|
-
};
|
|
145
|
-
/** 尾部「新增」按钮 */
|
|
146
|
-
addable: {
|
|
147
|
-
type: BooleanConstructor;
|
|
148
|
-
default: boolean;
|
|
149
|
-
};
|
|
150
|
-
/** 「更多」页签的文字 */
|
|
151
|
-
moreLabel: {
|
|
152
|
-
type: StringConstructor;
|
|
153
|
-
default: string;
|
|
154
|
-
};
|
|
155
|
-
/** 关闭某项(只回调,**不从 `options` 里删** —— 数据归调用方) */
|
|
156
|
-
onClose: {
|
|
157
|
-
type: PropType<(value: TabsValue) => void>;
|
|
158
|
-
default: undefined;
|
|
159
|
-
};
|
|
160
|
-
/** 点新增(只回调) */
|
|
161
|
-
onAdd: {
|
|
162
|
-
type: PropType<() => void>;
|
|
163
|
-
default: undefined;
|
|
164
|
-
};
|
|
165
183
|
}>> & Readonly<{
|
|
166
|
-
"onUpdate:value"?: ((value:
|
|
184
|
+
"onUpdate:value"?: ((value: string | number) => any) | undefined;
|
|
167
185
|
}>, {
|
|
168
|
-
|
|
169
|
-
value:
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
defaultValue: TabsValue | undefined;
|
|
174
|
-
closable: boolean;
|
|
175
|
-
centered: boolean;
|
|
176
|
-
addable: boolean;
|
|
177
|
-
moreLabel: string;
|
|
178
|
-
onAdd: () => void;
|
|
186
|
+
value: string | number | undefined;
|
|
187
|
+
onChange: (value: string | number) => void;
|
|
188
|
+
options: TabsOption[];
|
|
189
|
+
defaultValue: string | number | undefined;
|
|
190
|
+
lazy: boolean;
|
|
179
191
|
}, SlotsType<{
|
|
180
|
-
|
|
192
|
+
default?: () => VNodeChild;
|
|
193
|
+
/** 不传即用缺省皮肤 `TabBar`;传了就整块替换(胶囊 / 分段按钮 / 单选卡片…) */
|
|
194
|
+
selector?: (context: {
|
|
195
|
+
value: string | number | undefined;
|
|
181
196
|
options: TabsOption[];
|
|
197
|
+
select: (value: string | number) => void;
|
|
182
198
|
}) => VNodeChild;
|
|
183
199
|
}>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
|