@manohub/ui 0.6.1 → 0.7.1
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 +12 -4
- package/dist/components/button/index.d.ts +8 -8
- package/dist/components/capsule/index.d.ts +13 -9
- package/dist/components/capsule/index.js +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 +58 -6
- package/dist/components/dialog/index.js +45 -8
- package/dist/components/drawer/index.d.ts +18 -6
- package/dist/components/drawer/index.js +11 -5
- package/dist/components/form/index.d.ts +115 -17
- package/dist/components/form/index.js +39 -9
- package/dist/components/input/index.d.ts +4 -4
- package/dist/components/input/index.js +1 -1
- package/dist/components/layout/index.d.ts +43 -1
- package/dist/components/layout/index.js +22 -2
- package/dist/components/notice/index.d.ts +24 -11
- package/dist/components/notice/index.js +11 -5
- package/dist/components/notification/index.d.ts +2 -2
- package/dist/components/page/index.js +4 -4
- 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/radio/index.d.ts +1 -1
- package/dist/components/radio/index.js +1 -0
- package/dist/components/search/index.d.ts +26 -6
- package/dist/components/search/index.js +22 -4
- 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 +74 -8
- package/dist/components/table/index.js +69 -16
- package/dist/components/tabs/index.d.ts +145 -125
- package/dist/components/tabs/index.js +93 -117
- package/dist/components/tag/index.d.ts +2 -2
- package/dist/components/text/index.d.ts +120 -0
- package/dist/components/text/index.js +55 -0
- package/dist/components/toast/index.d.ts +8 -8
- package/dist/components/toast/index.js +11 -2
- package/dist/components/upload/index.d.ts +30 -0
- package/dist/components/upload/index.js +7 -1
- package/dist/index.d.ts +6 -5
- package/dist/index.js +6 -3
- package/dist/services/dialog.d.ts +20 -5
- package/dist/services/dialog.js +8 -1
- package/dist/styles/components/capsule.css +4 -4
- package/dist/styles/components/dialog.css +40 -1
- package/dist/styles/components/form.css +206 -26
- package/dist/styles/components/input.css +29 -2
- package/dist/styles/components/layout.css +2 -0
- package/dist/styles/components/select.css +11 -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/components/text.css +101 -0
- package/dist/styles/components/toast.css +12 -6
- package/dist/styles/index.css +8 -4
- package/dist/styles/operations/tabs.css +73 -0
- package/dist/styles/reset.css +205 -0
- package/package.json +2 -2
- package/dist/components/tabset/index.d.ts +0 -105
- package/dist/components/tabset/index.js +0 -68
- package/dist/styles/components/tabs.tokens.css +0 -30
- package/dist/styles/operations/tabset.css +0 -57
|
@@ -4,6 +4,33 @@ import { type Padding } from '../part-padding';
|
|
|
4
4
|
export type FormPadding = Padding;
|
|
5
5
|
/** label 列的水平对齐:`right`(默认,与 farris / 主流水平表单一致)或 `left` */
|
|
6
6
|
export type FormLabelAlign = 'left' | 'right';
|
|
7
|
+
/**
|
|
8
|
+
* 字段行的排布档:
|
|
9
|
+
*
|
|
10
|
+
* - `1`(默认):逐行;
|
|
11
|
+
* - `2 ~ 6`:**列数上限** —— 容器放得下 N 列就并排,放不下**少排一列**(不会把控件压成窄条)。
|
|
12
|
+
* 高列数(5 / 6)在默认最小宽 320 下要容器 1632 / 1960px 才排得出来,普通表单页用不到 ——
|
|
13
|
+
* 留着它是给「宽屏展示页 / 大屏看板」这类场景,配 `columnMinWidth` 才好落地;
|
|
14
|
+
* - `'auto'`:**列数随容器宽度动态变化** —— 能排几列排几列,每列宽由 `columnMinWidth` 决定。
|
|
15
|
+
*
|
|
16
|
+
* 两类的差别是**可预期性**(不是能力高低):
|
|
17
|
+
*
|
|
18
|
+
* - 数字档承诺「最多 N 列」,所以「哪几个字段同排」在够宽的容器里是确定的;
|
|
19
|
+
* - 动态档会一路排下去(默认参数下 1320px 就够 4 列),窄了就减 ——
|
|
20
|
+
* 同一个表单在不同容器里列数不同 ⇒ **字段的相对位置会变**。要「两个字段必须并肩」就别用它。
|
|
21
|
+
*/
|
|
22
|
+
export type FormColumns = 1 | 2 | 3 | 4 | 5 | 6 | 'auto';
|
|
23
|
+
/**
|
|
24
|
+
* 行内**垂直**对齐(label 与控件在控件行内怎么对齐):
|
|
25
|
+
*
|
|
26
|
+
* - `center`(默认):label 文字与控件**中线**对齐 —— 单行控件(输入框 / 选择器 / 开关)用它;
|
|
27
|
+
* - `start`:label 与控件**首行文字**对齐 —— 多行控件(文本域)与整块内容用它,
|
|
28
|
+
* 否则 label 会落到整块高度的中间。
|
|
29
|
+
*
|
|
30
|
+
* 不传即**自动判定**(样式按控件类型切档:文本域行零配置就是顶对齐);
|
|
31
|
+
* 显式传入优先于自动判定,用于自绘内容(卡片组 / 表格 / 富文本这类样式认不出来的块)。
|
|
32
|
+
*/
|
|
33
|
+
export type FormItemAlign = 'center' | 'start';
|
|
7
34
|
/** 表单值:**字段名 → 值**(键就是 `Form.Item` 的 `name`) */
|
|
8
35
|
export type FormValues = Record<string, unknown>;
|
|
9
36
|
/**
|
|
@@ -31,16 +58,27 @@ export interface FormProps {
|
|
|
31
58
|
*
|
|
32
59
|
* 宽表单(>600px)里让输入框一路拉到右边缘很难看,两种收法二选一:
|
|
33
60
|
* ① 收宽度 —— 传 `controlWidth={360}`,控件列封顶、右侧留白;
|
|
34
|
-
* ②
|
|
61
|
+
* ② 分列 —— 传 `columns`(`2 | 3 | 4` 上限档,或 `'auto'` 动态),把行并排起来(见下)。
|
|
35
62
|
*/
|
|
36
63
|
controlWidth?: number;
|
|
37
64
|
/**
|
|
38
|
-
* 列数:`1
|
|
65
|
+
* 列数:`1`(默认,逐行)/ `2 ~ 6`(**容器够宽才并排**,窄了按列最小宽度自动回落一列)/
|
|
66
|
+
* `'auto'`(列数随容器宽度动态变化,取舍见 `FormColumns`)。
|
|
39
67
|
*
|
|
40
|
-
*
|
|
41
|
-
* 在对应 `Form.Item` 上给 `fullWidth
|
|
68
|
+
* 多列下每一行都要能独立成格,所以「整行内容」(说明行、卡片组、表格、文本域)记得
|
|
69
|
+
* 在对应 `Form.Item` 上给 `fullWidth`,否则会被压成一格。
|
|
42
70
|
*/
|
|
43
|
-
columns?:
|
|
71
|
+
columns?: FormColumns;
|
|
72
|
+
/**
|
|
73
|
+
* 一列的**最小宽度**(px);缺省取令牌 `--ui-form-column-min`(320 = 「label 120 + 一个还能用的
|
|
74
|
+
* 输入框」的下限)。
|
|
75
|
+
*
|
|
76
|
+
* 它同时是**回落阈值**与**动态列数的除数**:数字档下容器窄于
|
|
77
|
+
* `N × 最小宽 + (N − 1) × 行距` 就少排一列;动态档下列数 =
|
|
78
|
+
* `floor((容器宽 + 行距) / (最小宽 + 行距))`。抽屉 / 弹窗里嫌字段太窄就调小(如 280),
|
|
79
|
+
* 宽页面里嫌列太多就调大(如 380)。
|
|
80
|
+
*/
|
|
81
|
+
columnMinWidth?: number;
|
|
44
82
|
/**
|
|
45
83
|
* 表单内距(**px 数字**,与 `Panel` 同一口径):`number` = 四边同值;`{ y, x }` = 上下 / 左右分别给。
|
|
46
84
|
*
|
|
@@ -112,6 +150,11 @@ export interface FormItemProps {
|
|
|
112
150
|
* 两个都给时 `text` 优先(`readonly` 只是把 label 的弱化带过去)。
|
|
113
151
|
*/
|
|
114
152
|
readonly?: boolean;
|
|
153
|
+
/**
|
|
154
|
+
* 行内**垂直**对齐:`center`(默认,label 与控件中线对齐)/ `start`(label 与控件首行文字对齐,
|
|
155
|
+
* 用于多行与整块内容)。不传即按控件类型自动判定(文本域自动顶对齐),显式传入优先。
|
|
156
|
+
*/
|
|
157
|
+
align?: FormItemAlign;
|
|
115
158
|
}
|
|
116
159
|
/**
|
|
117
160
|
* 表单行(**自建**):`label + 控件 + 错误 + 说明` 四件。
|
|
@@ -128,13 +171,28 @@ export interface FormItemProps {
|
|
|
128
171
|
* ## 宽表单怎么处理(两条杠杆,可叠加)
|
|
129
172
|
*
|
|
130
173
|
* - **限宽**:`controlWidth` 封顶控件列(表单级给默认、逐行可覆盖)—— 单列表单不至于把输入框拉成长条;
|
|
131
|
-
* -
|
|
132
|
-
*
|
|
133
|
-
*
|
|
174
|
+
* - **分列**:`columns` 让行并排,宽度用得更充分。档位见 `FormColumns`:
|
|
175
|
+
* `2 ~ 6` 是**列数上限**(宽够就并排、窄了自动少排一列);`'auto'` 是**列数随宽度动态变化**。
|
|
176
|
+
* 回落阈值与动态列数都由 `columnMinWidth`(缺省令牌 `--ui-form-column-min` = 320)决定,
|
|
177
|
+
* **不需要消费方写媒体查询**;多列下「整块内容」记得 `fullWidth`。
|
|
134
178
|
*
|
|
135
179
|
* `Form.Item` 是唯一入口(`Form` 只承载表单级设置、行间距/列数与容器内距),
|
|
136
180
|
* 控件从默认插槽进,因此输入框 / 下拉 / 文本域 / 自绘分组卡片共用同一个容器。
|
|
137
181
|
*
|
|
182
|
+
* ## 行内垂直对齐(label 与控件怎么对齐)
|
|
183
|
+
*
|
|
184
|
+
* 对齐参照是**控件那一行**,不是整行:控件列与 label 同处第 1 行,错误 / 说明自然落第 2 行起 ——
|
|
185
|
+
* 所以提示文案的有无与长短都不会带动 label 的位置。规则按控件形态自动切档,消费方零配置:
|
|
186
|
+
*
|
|
187
|
+
* - **单行控件**(输入框 / 选择器 / 开关 / 自绘单行内容):label 与控件**中线**对齐,**与控件高度无关**
|
|
188
|
+
* —— 档位切 sm/md/lg、换主题、放自绘控件都自动成立;
|
|
189
|
+
* - **多行与整块内容**(文本域这类样式认得出形态的):label 与控件**首行文字**对齐,不会落到整块中间;
|
|
190
|
+
* - 样式认不出形态的自绘块(卡片组 / 表格 / 富文本)用 `align="start"` 显式声明;要强制居中用 `align="center"`。
|
|
191
|
+
*
|
|
192
|
+
* **本件不再依赖任何「控件高度」常量**:从前用一个外部注入的高度变量把 label 撑到控件高,
|
|
193
|
+
* 而那个变量在骨架层没有任何出处(回退成 `auto`),于是 label 盒退化成一行文字并贴行顶 ——
|
|
194
|
+
* 输入框中线偏高 6px、大号档偏高 10px、文本域偏高 9px,档位越高错得越多。
|
|
195
|
+
*
|
|
138
196
|
* ## 容器内距(`padding`)
|
|
139
197
|
*
|
|
140
198
|
* 与 `Panel` **同一口径同一实现**(`src/components/part-padding.ts`):`number` 四边同值、
|
|
@@ -211,6 +269,11 @@ export declare const FormItem: import("vue").DefineComponent<import("vue").Extra
|
|
|
211
269
|
type: BooleanConstructor;
|
|
212
270
|
default: boolean;
|
|
213
271
|
};
|
|
272
|
+
/** 行内垂直对齐;不传即自动(单行居中、多行顶对齐) */
|
|
273
|
+
align: {
|
|
274
|
+
type: PropType<FormItemAlign>;
|
|
275
|
+
default: undefined;
|
|
276
|
+
};
|
|
214
277
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
215
278
|
/** 字段名(绑定的键);不传即纯布局行(值由消费方自己在控件上绑定) */
|
|
216
279
|
name: {
|
|
@@ -259,12 +322,18 @@ export declare const FormItem: import("vue").DefineComponent<import("vue").Extra
|
|
|
259
322
|
type: BooleanConstructor;
|
|
260
323
|
default: boolean;
|
|
261
324
|
};
|
|
325
|
+
/** 行内垂直对齐;不传即自动(单行居中、多行顶对齐) */
|
|
326
|
+
align: {
|
|
327
|
+
type: PropType<FormItemAlign>;
|
|
328
|
+
default: undefined;
|
|
329
|
+
};
|
|
262
330
|
}>> & Readonly<{}>, {
|
|
263
331
|
text: string;
|
|
264
332
|
name: string;
|
|
265
333
|
label: string;
|
|
266
334
|
error: string;
|
|
267
335
|
required: boolean;
|
|
336
|
+
align: FormItemAlign;
|
|
268
337
|
readonly: boolean;
|
|
269
338
|
hint: string;
|
|
270
339
|
labelWidth: number;
|
|
@@ -345,11 +414,16 @@ export declare const Form: {
|
|
|
345
414
|
type: NumberConstructor;
|
|
346
415
|
default: undefined;
|
|
347
416
|
};
|
|
348
|
-
/** 列数:1(逐行,默认)/ 2
|
|
417
|
+
/** 列数:1(逐行,默认)/ 2~6(够宽才并排,窄了回落一列)/ 'auto'(列数随容器宽度动态变化) */
|
|
349
418
|
columns: {
|
|
350
|
-
type: PropType<
|
|
419
|
+
type: PropType<FormColumns>;
|
|
351
420
|
default: number;
|
|
352
421
|
};
|
|
422
|
+
/** 一列的最小宽度(px);缺省取令牌 --ui-form-column-min(320);它同时是回落阈值 */
|
|
423
|
+
columnMinWidth: {
|
|
424
|
+
type: NumberConstructor;
|
|
425
|
+
default: undefined;
|
|
426
|
+
};
|
|
353
427
|
/** 表单内距(px 数字,或 `{ y, x }`);缺省 0 = 贴容器边(弹窗 / 抽屉里常用它自带内距) */
|
|
354
428
|
padding: {
|
|
355
429
|
type: PropType<FormPadding>;
|
|
@@ -398,11 +472,12 @@ export declare const Form: {
|
|
|
398
472
|
onChange: (values: FormValues) => void;
|
|
399
473
|
defaultValue: FormValues;
|
|
400
474
|
gap: number;
|
|
401
|
-
columns:
|
|
475
|
+
columns: FormColumns;
|
|
402
476
|
modelValue: FormValues;
|
|
403
477
|
labelWidth: number;
|
|
404
478
|
labelAlign: FormLabelAlign;
|
|
405
479
|
controlWidth: number;
|
|
480
|
+
columnMinWidth: number;
|
|
406
481
|
}, true, {}, SlotsType<{
|
|
407
482
|
default?: () => VNodeChild;
|
|
408
483
|
}>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, {}, any, import("vue").ComponentProvideOptions, {
|
|
@@ -428,11 +503,16 @@ export declare const Form: {
|
|
|
428
503
|
type: NumberConstructor;
|
|
429
504
|
default: undefined;
|
|
430
505
|
};
|
|
431
|
-
/** 列数:1(逐行,默认)/ 2
|
|
506
|
+
/** 列数:1(逐行,默认)/ 2~6(够宽才并排,窄了回落一列)/ 'auto'(列数随容器宽度动态变化) */
|
|
432
507
|
columns: {
|
|
433
|
-
type: PropType<
|
|
508
|
+
type: PropType<FormColumns>;
|
|
434
509
|
default: number;
|
|
435
510
|
};
|
|
511
|
+
/** 一列的最小宽度(px);缺省取令牌 --ui-form-column-min(320);它同时是回落阈值 */
|
|
512
|
+
columnMinWidth: {
|
|
513
|
+
type: NumberConstructor;
|
|
514
|
+
default: undefined;
|
|
515
|
+
};
|
|
436
516
|
/** 表单内距(px 数字,或 `{ y, x }`);缺省 0 = 贴容器边(弹窗 / 抽屉里常用它自带内距) */
|
|
437
517
|
padding: {
|
|
438
518
|
type: PropType<FormPadding>;
|
|
@@ -479,11 +559,12 @@ export declare const Form: {
|
|
|
479
559
|
onChange: (values: FormValues) => void;
|
|
480
560
|
defaultValue: FormValues;
|
|
481
561
|
gap: number;
|
|
482
|
-
columns:
|
|
562
|
+
columns: FormColumns;
|
|
483
563
|
modelValue: FormValues;
|
|
484
564
|
labelWidth: number;
|
|
485
565
|
labelAlign: FormLabelAlign;
|
|
486
566
|
controlWidth: number;
|
|
567
|
+
columnMinWidth: number;
|
|
487
568
|
}>;
|
|
488
569
|
__isFragment?: never;
|
|
489
570
|
__isTeleport?: never;
|
|
@@ -504,11 +585,16 @@ export declare const Form: {
|
|
|
504
585
|
type: NumberConstructor;
|
|
505
586
|
default: undefined;
|
|
506
587
|
};
|
|
507
|
-
/** 列数:1(逐行,默认)/ 2
|
|
588
|
+
/** 列数:1(逐行,默认)/ 2~6(够宽才并排,窄了回落一列)/ 'auto'(列数随容器宽度动态变化) */
|
|
508
589
|
columns: {
|
|
509
|
-
type: PropType<
|
|
590
|
+
type: PropType<FormColumns>;
|
|
510
591
|
default: number;
|
|
511
592
|
};
|
|
593
|
+
/** 一列的最小宽度(px);缺省取令牌 --ui-form-column-min(320);它同时是回落阈值 */
|
|
594
|
+
columnMinWidth: {
|
|
595
|
+
type: NumberConstructor;
|
|
596
|
+
default: undefined;
|
|
597
|
+
};
|
|
512
598
|
/** 表单内距(px 数字,或 `{ y, x }`);缺省 0 = 贴容器边(弹窗 / 抽屉里常用它自带内距) */
|
|
513
599
|
padding: {
|
|
514
600
|
type: PropType<FormPadding>;
|
|
@@ -557,11 +643,12 @@ export declare const Form: {
|
|
|
557
643
|
onChange: (values: FormValues) => void;
|
|
558
644
|
defaultValue: FormValues;
|
|
559
645
|
gap: number;
|
|
560
|
-
columns:
|
|
646
|
+
columns: FormColumns;
|
|
561
647
|
modelValue: FormValues;
|
|
562
648
|
labelWidth: number;
|
|
563
649
|
labelAlign: FormLabelAlign;
|
|
564
650
|
controlWidth: number;
|
|
651
|
+
columnMinWidth: number;
|
|
565
652
|
}, {}, string, SlotsType<{
|
|
566
653
|
default?: () => VNodeChild;
|
|
567
654
|
}>, import("vue").GlobalComponents, import("vue").GlobalDirectives, string, import("vue").ComponentProvideOptions> & import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps & {
|
|
@@ -637,6 +724,11 @@ export declare const Form: {
|
|
|
637
724
|
type: BooleanConstructor;
|
|
638
725
|
default: boolean;
|
|
639
726
|
};
|
|
727
|
+
/** 行内垂直对齐;不传即自动(单行居中、多行顶对齐) */
|
|
728
|
+
align: {
|
|
729
|
+
type: PropType<FormItemAlign>;
|
|
730
|
+
default: undefined;
|
|
731
|
+
};
|
|
640
732
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
641
733
|
/** 字段名(绑定的键);不传即纯布局行(值由消费方自己在控件上绑定) */
|
|
642
734
|
name: {
|
|
@@ -685,12 +777,18 @@ export declare const Form: {
|
|
|
685
777
|
type: BooleanConstructor;
|
|
686
778
|
default: boolean;
|
|
687
779
|
};
|
|
780
|
+
/** 行内垂直对齐;不传即自动(单行居中、多行顶对齐) */
|
|
781
|
+
align: {
|
|
782
|
+
type: PropType<FormItemAlign>;
|
|
783
|
+
default: undefined;
|
|
784
|
+
};
|
|
688
785
|
}>> & Readonly<{}>, {
|
|
689
786
|
text: string;
|
|
690
787
|
name: string;
|
|
691
788
|
label: string;
|
|
692
789
|
error: string;
|
|
693
790
|
required: boolean;
|
|
791
|
+
align: FormItemAlign;
|
|
694
792
|
readonly: boolean;
|
|
695
793
|
hint: string;
|
|
696
794
|
labelWidth: number;
|
|
@@ -55,6 +55,11 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
55
55
|
readonly: {
|
|
56
56
|
type: Boolean,
|
|
57
57
|
default: false
|
|
58
|
+
},
|
|
59
|
+
/** 行内垂直对齐;不传即自动(单行居中、多行顶对齐) */
|
|
60
|
+
align: {
|
|
61
|
+
type: String,
|
|
62
|
+
default: void 0
|
|
58
63
|
}
|
|
59
64
|
},
|
|
60
65
|
slots: Object,
|
|
@@ -95,6 +100,10 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
95
100
|
"mh-form-item",
|
|
96
101
|
props.error ? "is-invalid" : "",
|
|
97
102
|
props.fullWidth ? "mh-form-item--full" : "",
|
|
103
|
+
// 无 label 列:控件位与提示横跨整行(两列 grid 下第一列不能留空位)
|
|
104
|
+
showLabel ? "" : "mh-form-item--no-label",
|
|
105
|
+
// 行内垂直对齐:**只在显式传入时**挂类;不传即由样式按控件类型自动判定(见 form.css 的顶对齐档)
|
|
106
|
+
props.align ? `mh-form-item--align-${props.align}` : "",
|
|
98
107
|
// 右对齐是基类默认值,只有左对齐需要额外的修饰类(两处都挂会让「谁胜出」依赖源码顺序)
|
|
99
108
|
labelAlign === "left" ? "mh-form-item--label-left" : "",
|
|
100
109
|
// 只读展示行:label 降一档为次要色,与值拉开层级(样式见 `.mh-form-item--readonly .mh-form-item__label`)
|
|
@@ -123,11 +132,11 @@ const FormItem = /* @__PURE__ */ defineComponent({
|
|
|
123
132
|
"class": "mh-form-item__text",
|
|
124
133
|
"data-empty": textIsEmpty ? "true" : "false"
|
|
125
134
|
}, [textIsEmpty ? FORM_TEXT_EMPTY : props.text])
|
|
126
|
-
) : slots.default?.(scope()), props.error ? createVNode("div", {
|
|
135
|
+
) : slots.default?.(scope())]), props.error ? createVNode("div", {
|
|
127
136
|
"class": "mh-form-item__error"
|
|
128
137
|
}, [props.error]) : null, props.hint ? createVNode("div", {
|
|
129
138
|
"class": "mh-form-item__hint"
|
|
130
|
-
}, [props.hint]) : null])
|
|
139
|
+
}, [props.hint]) : null]);
|
|
131
140
|
};
|
|
132
141
|
}
|
|
133
142
|
});
|
|
@@ -198,14 +207,19 @@ const FormRoot = /* @__PURE__ */ defineComponent({
|
|
|
198
207
|
type: Number,
|
|
199
208
|
default: void 0
|
|
200
209
|
},
|
|
201
|
-
/** 列数:1(逐行,默认)/ 2
|
|
210
|
+
/** 列数:1(逐行,默认)/ 2~6(够宽才并排,窄了回落一列)/ 'auto'(列数随容器宽度动态变化) */
|
|
202
211
|
columns: {
|
|
203
|
-
type: Number,
|
|
212
|
+
type: [Number, String],
|
|
204
213
|
default: 1
|
|
205
214
|
},
|
|
215
|
+
/** 一列的最小宽度(px);缺省取令牌 --ui-form-column-min(320);它同时是回落阈值 */
|
|
216
|
+
columnMinWidth: {
|
|
217
|
+
type: Number,
|
|
218
|
+
default: void 0
|
|
219
|
+
},
|
|
206
220
|
/** 表单内距(px 数字,或 `{ y, x }`);缺省 0 = 贴容器边(弹窗 / 抽屉里常用它自带内距) */
|
|
207
221
|
padding: {
|
|
208
|
-
type: [Number, Object],
|
|
222
|
+
type: [Number, Object, String],
|
|
209
223
|
default: void 0
|
|
210
224
|
},
|
|
211
225
|
/**
|
|
@@ -302,6 +316,12 @@ const FormRoot = /* @__PURE__ */ defineComponent({
|
|
|
302
316
|
return cleared;
|
|
303
317
|
}
|
|
304
318
|
});
|
|
319
|
+
const columnsClass = () => {
|
|
320
|
+
const value = props.columns;
|
|
321
|
+
if (value === "auto") return "mh-form--columns-auto";
|
|
322
|
+
if (typeof value !== "number" || value <= 1) return "";
|
|
323
|
+
return value === 2 ? "mh-form--two-column" : `mh-form--columns-${value}`;
|
|
324
|
+
};
|
|
305
325
|
return () => {
|
|
306
326
|
const raw = slots.default?.();
|
|
307
327
|
const list = Array.isArray(raw) ? raw : raw == null ? [] : [raw];
|
|
@@ -310,10 +330,20 @@ const FormRoot = /* @__PURE__ */ defineComponent({
|
|
|
310
330
|
rest
|
|
311
331
|
} = splitFormHeader(list);
|
|
312
332
|
return createVNode("div", {
|
|
313
|
-
"class": ["mh-form",
|
|
314
|
-
"style": [
|
|
315
|
-
|
|
316
|
-
|
|
333
|
+
"class": ["mh-form", columnsClass(), props.layout === "vertical" ? "mh-form--vertical" : "", attrs.class].filter(Boolean).join(" "),
|
|
334
|
+
"style": [
|
|
335
|
+
mergePartStyle(attrs.style, props.padding),
|
|
336
|
+
/* 行距同时下发实体 `gap` 与变量:多列的轨道下限公式要用**同一个**行距值算 ——
|
|
337
|
+
从前公式里硬编码 8px,`gap={16}` 时列宽会算偏(临界宽度上还会误判回落)。 */
|
|
338
|
+
props.gap !== void 0 ? {
|
|
339
|
+
gap: `${props.gap}px`,
|
|
340
|
+
"--mh-form-gap": `${props.gap}px`
|
|
341
|
+
} : null,
|
|
342
|
+
/* 一列最小宽度:动态档列数的除数、数字档的回落阈值 */
|
|
343
|
+
props.columnMinWidth !== void 0 ? {
|
|
344
|
+
"--mh-form-column-min": `${props.columnMinWidth}px`
|
|
345
|
+
} : null
|
|
346
|
+
]
|
|
317
347
|
}, [header, rest]);
|
|
318
348
|
};
|
|
319
349
|
}
|
|
@@ -249,12 +249,12 @@ export declare const Input: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
249
249
|
autofocus: boolean;
|
|
250
250
|
modelValue: string;
|
|
251
251
|
status: InputStatus;
|
|
252
|
+
as: "button" | "input";
|
|
252
253
|
readonly: boolean;
|
|
253
254
|
clearable: boolean;
|
|
254
255
|
maxlength: number;
|
|
255
256
|
showCount: boolean;
|
|
256
257
|
onEnter: (v: string) => void;
|
|
257
|
-
as: "button" | "input";
|
|
258
258
|
controlClass: string;
|
|
259
259
|
controlAttrs: Record<string, unknown>;
|
|
260
260
|
hasValue: boolean;
|
|
@@ -547,12 +547,12 @@ export declare const InputCompound: {
|
|
|
547
547
|
autofocus: boolean;
|
|
548
548
|
modelValue: string;
|
|
549
549
|
status: InputStatus;
|
|
550
|
+
as: "button" | "input";
|
|
550
551
|
readonly: boolean;
|
|
551
552
|
clearable: boolean;
|
|
552
553
|
maxlength: number;
|
|
553
554
|
showCount: boolean;
|
|
554
555
|
onEnter: (v: string) => void;
|
|
555
|
-
as: "button" | "input";
|
|
556
556
|
controlClass: string;
|
|
557
557
|
controlAttrs: Record<string, unknown>;
|
|
558
558
|
hasValue: boolean;
|
|
@@ -678,12 +678,12 @@ export declare const InputCompound: {
|
|
|
678
678
|
autofocus: boolean;
|
|
679
679
|
modelValue: string;
|
|
680
680
|
status: InputStatus;
|
|
681
|
+
as: "button" | "input";
|
|
681
682
|
readonly: boolean;
|
|
682
683
|
clearable: boolean;
|
|
683
684
|
maxlength: number;
|
|
684
685
|
showCount: boolean;
|
|
685
686
|
onEnter: (v: string) => void;
|
|
686
|
-
as: "button" | "input";
|
|
687
687
|
controlClass: string;
|
|
688
688
|
controlAttrs: Record<string, unknown>;
|
|
689
689
|
hasValue: boolean;
|
|
@@ -804,12 +804,12 @@ export declare const InputCompound: {
|
|
|
804
804
|
autofocus: boolean;
|
|
805
805
|
modelValue: string;
|
|
806
806
|
status: InputStatus;
|
|
807
|
+
as: "button" | "input";
|
|
807
808
|
readonly: boolean;
|
|
808
809
|
clearable: boolean;
|
|
809
810
|
maxlength: number;
|
|
810
811
|
showCount: boolean;
|
|
811
812
|
onEnter: (v: string) => void;
|
|
812
|
-
as: "button" | "input";
|
|
813
813
|
controlClass: string;
|
|
814
814
|
controlAttrs: Record<string, unknown>;
|
|
815
815
|
hasValue: boolean;
|
|
@@ -184,7 +184,7 @@ const Input = /* @__PURE__ */ defineComponent({
|
|
|
184
184
|
"tabindex": -1,
|
|
185
185
|
"onClick": () => revealed.value = !revealed.value
|
|
186
186
|
}, [createVNode(Icon, {
|
|
187
|
-
"name": "
|
|
187
|
+
"name": "preview",
|
|
188
188
|
"class": "mh-input__eye-icon"
|
|
189
189
|
}, null)]) : null, slots.suffix ? createVNode("span", {
|
|
190
190
|
"class": "mh-input__suffix"
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type PropType, type SlotsType, type VNodeChild } from 'vue';
|
|
2
|
+
import { type Padding } from '../part-padding';
|
|
2
3
|
/**
|
|
3
4
|
* 布局间距档:**只开放令牌档位,不开放任意 px**(`none/sm/md/lg/xl` → `0 / --ui-space-1/2/3/4`)。
|
|
4
5
|
*
|
|
@@ -32,7 +33,8 @@ export type LayoutSpan = 1 | 2 | 3 | 4;
|
|
|
32
33
|
*
|
|
33
34
|
* ## 与其它件的边界
|
|
34
35
|
*
|
|
35
|
-
* - 表单里并排字段用 `Form columns
|
|
36
|
+
* - 表单里并排字段用 `Form` 的 `columns`(它管 label 列、行距与**回落**),不要用本族拼表单
|
|
37
|
+
* —— 本族的列数是**恒定**的,窄了只等分收窄,表单会被压出不可用的窄控件;
|
|
36
38
|
* - 页面级两栏(各自滚动)用 `Page.Split`;
|
|
37
39
|
* - 只有「块与块怎么摆」这一件事归本族,滚动 / 工具位 / 卡片外观都不归它。
|
|
38
40
|
*/
|
|
@@ -63,6 +65,20 @@ export declare const Layout: {
|
|
|
63
65
|
type: NumberConstructor;
|
|
64
66
|
default: undefined;
|
|
65
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* 内距:**走骨架件共享口径**(`Padding`,同 `Card` / `Form` / `Page` / `Panel`)——
|
|
70
|
+
* `number` 四边同值、`{ y, x }` 分上下 / 左右、`string` 原样下发(CSS 简写,**逃生舱**)。
|
|
71
|
+
* 口径与理由见 `part-padding.ts`。
|
|
72
|
+
*
|
|
73
|
+
* ⚠️ 与 `gap` 不同口径:`gap` 只开放令牌档(防间距分叉),`padding` 接具体值 ——
|
|
74
|
+
* 内距在设计稿里常是**确定坐标**,令牌梯度(最大 24px)表达不了。
|
|
75
|
+
* ⚠️ 用它之前先想一次:这个数真是「内距」吗?若是「与某个内容列对齐」这类**布局坐标**,
|
|
76
|
+
* 优先改由结构表达(同轴容器 / `columns` / `minColumnWidth`)。
|
|
77
|
+
*/
|
|
78
|
+
padding: {
|
|
79
|
+
type: PropType<Padding>;
|
|
80
|
+
default: undefined;
|
|
81
|
+
};
|
|
66
82
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
67
83
|
/** 行间距档(默认 `md` 8px;要贴紧写 `none`) */
|
|
68
84
|
gap: {
|
|
@@ -89,7 +105,22 @@ export declare const Layout: {
|
|
|
89
105
|
type: NumberConstructor;
|
|
90
106
|
default: undefined;
|
|
91
107
|
};
|
|
108
|
+
/**
|
|
109
|
+
* 内距:**走骨架件共享口径**(`Padding`,同 `Card` / `Form` / `Page` / `Panel`)——
|
|
110
|
+
* `number` 四边同值、`{ y, x }` 分上下 / 左右、`string` 原样下发(CSS 简写,**逃生舱**)。
|
|
111
|
+
* 口径与理由见 `part-padding.ts`。
|
|
112
|
+
*
|
|
113
|
+
* ⚠️ 与 `gap` 不同口径:`gap` 只开放令牌档(防间距分叉),`padding` 接具体值 ——
|
|
114
|
+
* 内距在设计稿里常是**确定坐标**,令牌梯度(最大 24px)表达不了。
|
|
115
|
+
* ⚠️ 用它之前先想一次:这个数真是「内距」吗?若是「与某个内容列对齐」这类**布局坐标**,
|
|
116
|
+
* 优先改由结构表达(同轴容器 / `columns` / `minColumnWidth`)。
|
|
117
|
+
*/
|
|
118
|
+
padding: {
|
|
119
|
+
type: PropType<Padding>;
|
|
120
|
+
default: undefined;
|
|
121
|
+
};
|
|
92
122
|
}>> & Readonly<{}>, {
|
|
123
|
+
padding: Padding;
|
|
93
124
|
justify: LayoutJustify;
|
|
94
125
|
gap: LayoutGap;
|
|
95
126
|
align: LayoutAlign;
|
|
@@ -124,6 +155,11 @@ export declare const Layout: {
|
|
|
124
155
|
type: PropType<LayoutSpan>;
|
|
125
156
|
default: number;
|
|
126
157
|
};
|
|
158
|
+
/** 内距:口径同 `Layout.Row`(共享 `Padding`,复用 `mergePartStyle`) */
|
|
159
|
+
padding: {
|
|
160
|
+
type: PropType<Padding>;
|
|
161
|
+
default: undefined;
|
|
162
|
+
};
|
|
127
163
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
|
|
128
164
|
/** 单元内间距档(默认 `md` 8px;要贴紧写 `none`) */
|
|
129
165
|
gap: {
|
|
@@ -150,7 +186,13 @@ export declare const Layout: {
|
|
|
150
186
|
type: PropType<LayoutSpan>;
|
|
151
187
|
default: number;
|
|
152
188
|
};
|
|
189
|
+
/** 内距:口径同 `Layout.Row`(共享 `Padding`,复用 `mergePartStyle`) */
|
|
190
|
+
padding: {
|
|
191
|
+
type: PropType<Padding>;
|
|
192
|
+
default: undefined;
|
|
193
|
+
};
|
|
153
194
|
}>> & Readonly<{}>, {
|
|
195
|
+
padding: Padding;
|
|
154
196
|
wrap: boolean;
|
|
155
197
|
justify: LayoutJustify;
|
|
156
198
|
span: LayoutSpan;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { defineComponent, createVNode } from "vue";
|
|
2
|
+
import { mergePartStyle } from "../part-padding.js";
|
|
2
3
|
function modifier(base, name, value) {
|
|
3
4
|
return value === void 0 || value === "" ? "" : `${base}--${name}-${value}`;
|
|
4
5
|
}
|
|
@@ -30,6 +31,11 @@ const LayoutColumn = /* @__PURE__ */ defineComponent({
|
|
|
30
31
|
span: {
|
|
31
32
|
type: Number,
|
|
32
33
|
default: 1
|
|
34
|
+
},
|
|
35
|
+
/** 内距:口径同 `Layout.Row`(共享 `Padding`,复用 `mergePartStyle`) */
|
|
36
|
+
padding: {
|
|
37
|
+
type: [Number, Object, String],
|
|
38
|
+
default: void 0
|
|
33
39
|
}
|
|
34
40
|
},
|
|
35
41
|
slots: Object,
|
|
@@ -39,7 +45,7 @@ const LayoutColumn = /* @__PURE__ */ defineComponent({
|
|
|
39
45
|
}) {
|
|
40
46
|
return () => createVNode("div", {
|
|
41
47
|
"class": ["mh-layout-column", modifier("mh-layout-column", "gap", props.gap), modifier("mh-layout-column", "align", props.align), props.justify && props.justify !== "start" ? modifier("mh-layout-column", "justify", props.justify) : "", props.wrap ? "mh-layout-column--wrap" : "", props.span > 1 ? `mh-layout-column--span-${props.span}` : "", attrs.class].filter(Boolean).join(" "),
|
|
42
|
-
"style": attrs.style
|
|
48
|
+
"style": mergePartStyle(attrs.style, props.padding)
|
|
43
49
|
}, [slots.default?.()]);
|
|
44
50
|
}
|
|
45
51
|
});
|
|
@@ -71,6 +77,20 @@ const LayoutRow = /* @__PURE__ */ defineComponent({
|
|
|
71
77
|
minColumnWidth: {
|
|
72
78
|
type: Number,
|
|
73
79
|
default: void 0
|
|
80
|
+
},
|
|
81
|
+
/**
|
|
82
|
+
* 内距:**走骨架件共享口径**(`Padding`,同 `Card` / `Form` / `Page` / `Panel`)——
|
|
83
|
+
* `number` 四边同值、`{ y, x }` 分上下 / 左右、`string` 原样下发(CSS 简写,**逃生舱**)。
|
|
84
|
+
* 口径与理由见 `part-padding.ts`。
|
|
85
|
+
*
|
|
86
|
+
* ⚠️ 与 `gap` 不同口径:`gap` 只开放令牌档(防间距分叉),`padding` 接具体值 ——
|
|
87
|
+
* 内距在设计稿里常是**确定坐标**,令牌梯度(最大 24px)表达不了。
|
|
88
|
+
* ⚠️ 用它之前先想一次:这个数真是「内距」吗?若是「与某个内容列对齐」这类**布局坐标**,
|
|
89
|
+
* 优先改由结构表达(同轴容器 / `columns` / `minColumnWidth`)。
|
|
90
|
+
*/
|
|
91
|
+
padding: {
|
|
92
|
+
type: [Number, Object, String],
|
|
93
|
+
default: void 0
|
|
74
94
|
}
|
|
75
95
|
},
|
|
76
96
|
slots: Object,
|
|
@@ -86,7 +106,7 @@ const LayoutRow = /* @__PURE__ */ defineComponent({
|
|
|
86
106
|
if (props.minColumnWidth) style["--mh-layout-row-min"] = `${props.minColumnWidth}px`;
|
|
87
107
|
return createVNode("div", {
|
|
88
108
|
"class": ["mh-layout-row", modifier("mh-layout-row", "gap", props.gap), modifier("mh-layout-row", "align", props.align), props.justify && props.justify !== "start" ? modifier("mh-layout-row", "justify", props.justify) : "", isGrid ? "mh-layout-row--grid" : "", isGrid ? modifier("mh-layout-row", "columns", props.columns) : "", attrs.class].filter(Boolean).join(" "),
|
|
89
|
-
"style": style
|
|
109
|
+
"style": mergePartStyle(style, props.padding)
|
|
90
110
|
}, [slots.default?.()]);
|
|
91
111
|
};
|
|
92
112
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type IconName } from '@manohub/icon';
|
|
1
2
|
import { type PropType, type SlotsType, type VNodeChild } from 'vue';
|
|
2
3
|
export type NoticeTone = 'info' | 'success' | 'warning' | 'error';
|
|
3
4
|
/**
|
|
@@ -24,10 +25,10 @@ export type NoticeTone = 'info' | 'success' | 'warning' | 'error';
|
|
|
24
25
|
* | 有标题 | `message` + `description`(或插槽) | **标题行 + 描述行**两行 |
|
|
25
26
|
*
|
|
26
27
|
* @example 可关闭的说明条(列表页顶部)
|
|
27
|
-
* <Notice closable onClose={() => (visible = false)}
|
|
28
|
+
* <Notice closable onClose={() => (visible = false)} icon>值映射用于将来源向量转换为目标值。</Notice>
|
|
28
29
|
*
|
|
29
30
|
* @example 带标题与操作
|
|
30
|
-
* <Notice tone="warning"
|
|
31
|
+
* <Notice tone="warning" icon message="尚未完成实名认证" description="使用该服务前须完成认证"
|
|
31
32
|
* action="立即认证" :on-action="goAuth" />
|
|
32
33
|
*/
|
|
33
34
|
export declare const Notice: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
@@ -46,9 +47,15 @@ export declare const Notice: import("vue").DefineComponent<import("vue").Extract
|
|
|
46
47
|
type: StringConstructor;
|
|
47
48
|
default: undefined;
|
|
48
49
|
};
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
|
|
50
|
+
/**
|
|
51
|
+
* 前置图标:缺省 `false` 不出图标;`true` 按 `tone` 映射;也可直接给字形名。
|
|
52
|
+
*
|
|
53
|
+
* 与 `Toast.icon` / `Notification.icon` **同名同型**(0.6.x 本件叫 `showIcon` 且只收布尔,
|
|
54
|
+
* 三件三个名字三种默认 —— 已统一)。默认值仍与 `Toast` 不同:`Toast` 是「浮出即走」的
|
|
55
|
+
* 消息条,图标是它的主要语义承载;本件是嵌在页面里的说明条,页面里别处往往已经有图标,故缺省不出。
|
|
56
|
+
*/
|
|
57
|
+
icon: {
|
|
58
|
+
type: PropType<boolean | IconName>;
|
|
52
59
|
default: boolean;
|
|
53
60
|
};
|
|
54
61
|
/** 是否渲染右上关闭按钮(规范:仅通知类信息可关闭) */
|
|
@@ -92,9 +99,15 @@ export declare const Notice: import("vue").DefineComponent<import("vue").Extract
|
|
|
92
99
|
type: StringConstructor;
|
|
93
100
|
default: undefined;
|
|
94
101
|
};
|
|
95
|
-
/**
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
/**
|
|
103
|
+
* 前置图标:缺省 `false` 不出图标;`true` 按 `tone` 映射;也可直接给字形名。
|
|
104
|
+
*
|
|
105
|
+
* 与 `Toast.icon` / `Notification.icon` **同名同型**(0.6.x 本件叫 `showIcon` 且只收布尔,
|
|
106
|
+
* 三件三个名字三种默认 —— 已统一)。默认值仍与 `Toast` 不同:`Toast` 是「浮出即走」的
|
|
107
|
+
* 消息条,图标是它的主要语义承载;本件是嵌在页面里的说明条,页面里别处往往已经有图标,故缺省不出。
|
|
108
|
+
*/
|
|
109
|
+
icon: {
|
|
110
|
+
type: PropType<boolean | IconName>;
|
|
98
111
|
default: boolean;
|
|
99
112
|
};
|
|
100
113
|
/** 是否渲染右上关闭按钮(规范:仅通知类信息可关闭) */
|
|
@@ -123,14 +136,14 @@ export declare const Notice: import("vue").DefineComponent<import("vue").Extract
|
|
|
123
136
|
default: undefined;
|
|
124
137
|
};
|
|
125
138
|
}>> & Readonly<{}>, {
|
|
139
|
+
icon: boolean | "search" | "link" | "filter" | "copy" | "help" | "table" | "menu" | "delete" | "image" | "close" | "key" | "page-title" | "loading" | "info" | "alert" | "chevron-left" | "chevron-right" | "chevron-down" | "chevron-up" | "check" | "user" | "download" | "back" | "folder" | "folder-open" | "file" | "file-code" | "file-json" | "file-text" | "terminal" | "shield" | "tool" | "plus" | "notification" | "settings" | "logout" | "home" | "workbench" | "apps" | "favorite" | "favorite-filled" | "drag-handle" | "edit" | "refresh" | "upload" | "save" | "more" | "preview" | "external-link" | "minus" | "plus-circle" | "close-circle" | "list" | "calendar" | "clock" | "lock" | "unlock" | "users" | "archive" | "package" | "plug" | "branch" | "tag" | "ai" | "shield-check" | "shield-alert" | "history";
|
|
126
140
|
onClose: () => void;
|
|
127
141
|
message: string;
|
|
128
|
-
tone: NoticeTone;
|
|
129
142
|
closable: boolean;
|
|
143
|
+
tone: NoticeTone;
|
|
130
144
|
description: string;
|
|
131
|
-
showIcon: boolean;
|
|
132
|
-
closeText: string;
|
|
133
145
|
action: string;
|
|
146
|
+
closeText: string;
|
|
134
147
|
onAction: () => void;
|
|
135
148
|
}, SlotsType<{
|
|
136
149
|
default?: () => VNodeChild;
|