@manohub/ui 0.9.0 → 0.10.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 +13 -7
- package/dist/components/checkbox/index.js +5 -1
- package/dist/components/code-block/index.js +18 -11
- package/dist/components/filter/index.d.ts +8 -2
- package/dist/components/filter/index.js +11 -20
- package/dist/components/form/index.d.ts +39 -0
- package/dist/components/form/index.js +6 -0
- package/dist/components/input/index.d.ts +76 -20
- package/dist/components/input/index.js +64 -15
- package/dist/components/radio/index.js +29 -3
- package/dist/components/search/index.js +37 -35
- package/dist/components/select/index.d.ts +5 -2
- package/dist/components/select/index.js +3 -6
- package/dist/components/select/select-list.d.ts +2 -0
- package/dist/components/select/select-panel.d.ts +9 -4
- package/dist/components/select/select-panel.js +4 -2
- package/dist/components/select/select-tree.d.ts +5 -3
- package/dist/components/select/select-tree.js +3 -15
- package/dist/components/select/select-trigger.d.ts +4 -2
- package/dist/components/select/select-trigger.js +9 -4
- package/dist/components/table/index.d.ts +19 -8
- package/dist/components/table/index.js +3 -3
- package/dist/components/text/index.d.ts +4 -3
- package/dist/components/toast/index.js +16 -1
- package/dist/styles/components/avatar.css +4 -1
- package/dist/styles/components/badge.css +3 -1
- package/dist/styles/components/button.css +7 -2
- package/dist/styles/components/filter.css +22 -34
- package/dist/styles/components/input.css +37 -1
- package/dist/styles/components/input.tokens.css +5 -3
- package/dist/styles/components/pagination.css +8 -2
- package/dist/styles/components/select.css +39 -10
- package/dist/styles/components/select.tokens.css +4 -3
- package/dist/styles/components/steps.tokens.css +5 -3
- package/dist/styles/components/table.css +33 -22
- package/dist/styles/components/table.tokens.css +6 -6
- package/dist/styles/components/tag.css +7 -3
- package/dist/styles/components/text.css +10 -0
- package/dist/styles/components/toast.css +35 -6
- package/dist/styles/components/upload.css +1 -0
- package/dist/styles/components/upload.tokens.css +1 -1
- package/dist/styles/index.css +5 -4
- package/dist/styles/reset.css +52 -167
- package/package.json +2 -2
- package/dist/styles/components/filter.tokens.css +0 -14
package/README.md
CHANGED
|
@@ -7,7 +7,7 @@ AIHub **自绘组件层**:不依赖 farris 的手写 Vue TSX 组件 + 自带
|
|
|
7
7
|
| 层 | 入口 | 内容 |
|
|
8
8
|
|---|---|---|
|
|
9
9
|
| ① 主题 | `@manohub/theme/default.css`(兜底)/ `@manohub/theme/farris.css`(Farris 规范) | **全局**令牌(值)—— 随主题包独立发布,换主题只换这一行 |
|
|
10
|
-
| ② 组件面 | `@manohub/ui/styles.css` | **元素级 reset
|
|
10
|
+
| ② 组件面 | `@manohub/ui/styles.css` | **元素级 reset**(只有盒模型 + 容器基座两面,见下)+ 类与状态协议 + 组件令牌基础值,**无需 JS** 即可使用 |
|
|
11
11
|
| ③ Vue 层 | `@manohub/ui` | Vue 组件:渲染 ② 的类 + 行为增强 |
|
|
12
12
|
| ④ 服务层 | `@manohub/ui` | 命令式反馈:`toast()` / `confirm()` / `alert()` / `showLoading()`(宿主 + 队列 + 生命周期,共用 ③ 的组件) |
|
|
13
13
|
|
|
@@ -37,13 +37,19 @@ pnpm add @manohub/ui @manohub/theme
|
|
|
37
37
|
|
|
38
38
|
只写静态页(不装 Vue)时引这两行即可 —— 类名与 `data-*` 状态协议直接可用。
|
|
39
39
|
|
|
40
|
-
**② 的第一条 import 就是元素级 reset
|
|
41
|
-
`ul` / `ol` 的序号与缩进、`a` 的下划线、标题的默认字阶一并归零。作用域锚 `[data-manohub-ui]`
|
|
42
|
-
且特异性为 0 —— 应用侧写任何元素选择器都能盖过它,所以**不必再自己写一份全局 reset**。
|
|
40
|
+
**② 的第一条 import 就是元素级 reset**(随包内置,不需要第三行),它只有两面:
|
|
43
41
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
42
|
+
1. **盒模型**:`box-sizing: border-box` 覆盖容器、全部后代与伪元素(本包所有面的几何前提);
|
|
43
|
+
2. **容器基座**:`[data-manohub-ui]` 上的字族 / 字号 / 行高 / 字色 / 底色 / 整链高度(令牌的落点)。
|
|
44
|
+
|
|
45
|
+
作用域锚 `[data-manohub-ui]` 且特异性为 0 —— 应用侧写任何元素选择器都能盖过它。
|
|
46
|
+
**它有意不再归零标题字阶、列表序号、链接下划线、控件外观**:那些规则在 Tailwind 的层外
|
|
47
|
+
(未分层 > 分层),会把消费方的工具类整片压住(`border*`、`img` 上的 `h-*`、`hidden` …);
|
|
48
|
+
需要归零的元素各自归到渲染它的组件面上(`img` 在 Avatar / Upload、`a` 在 Button、
|
|
49
|
+
`textarea` 的 `resize` 在 `.mh-input--textarea`、`h1`-`h6` 在 `.mh-text`)。
|
|
50
|
+
Tailwind 消费方另有 preflight 兜底,两者不冲突。
|
|
51
|
+
|
|
52
|
+
所以**不必再自己写一份全局 reset**;也**不要**用元素级选择器去补(那正是被压住的成因)。
|
|
47
53
|
|
|
48
54
|
本包**可独立发布**:组件与类型一律从 `@manohub/ui` 直接引;下游(如 `@manohub/kit`)若转出口,是下游自己的选择。
|
|
49
55
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineComponent, ref, computed, watchEffect, createVNode, mergeProps } from "vue";
|
|
1
|
+
import { defineComponent, ref, computed, watchEffect, createVNode, mergeProps, nextTick } from "vue";
|
|
2
2
|
import { Icon } from "@manohub/icon";
|
|
3
3
|
const Checkbox = /* @__PURE__ */ defineComponent({
|
|
4
4
|
name: "Checkbox",
|
|
@@ -58,6 +58,10 @@ const Checkbox = /* @__PURE__ */ defineComponent({
|
|
|
58
58
|
const next = event.target.checked;
|
|
59
59
|
emit("update:modelValue", next);
|
|
60
60
|
props.onChange?.(next);
|
|
61
|
+
void nextTick(() => {
|
|
62
|
+
const el = inputRef.value;
|
|
63
|
+
if (el && el.checked !== !!props.modelValue) el.checked = !!props.modelValue;
|
|
64
|
+
});
|
|
61
65
|
};
|
|
62
66
|
return () => {
|
|
63
67
|
const state = props.indeterminate ? "indeterminate" : props.modelValue ? "checked" : "unchecked";
|
|
@@ -1,5 +1,8 @@
|
|
|
1
|
-
import { defineComponent, createVNode, mergeProps, ref, computed, onBeforeUnmount } from "vue";
|
|
1
|
+
import { defineComponent, createVNode, mergeProps, ref, computed, onBeforeUnmount, isVNode } from "vue";
|
|
2
2
|
import { Icon } from "@manohub/icon";
|
|
3
|
+
function _isSlot(s) {
|
|
4
|
+
return typeof s === "function" || Object.prototype.toString.call(s) === "[object Object]" && !isVNode(s);
|
|
5
|
+
}
|
|
3
6
|
const CodeView = /* @__PURE__ */ defineComponent({
|
|
4
7
|
name: "CodeView",
|
|
5
8
|
inheritAttrs: false,
|
|
@@ -285,6 +288,7 @@ const CodeBlockBase = /* @__PURE__ */ defineComponent({
|
|
|
285
288
|
attrs
|
|
286
289
|
}) {
|
|
287
290
|
return () => {
|
|
291
|
+
let _slot;
|
|
288
292
|
const shared = {
|
|
289
293
|
language: props.language,
|
|
290
294
|
maxHeight: props.maxHeight,
|
|
@@ -304,16 +308,19 @@ const CodeBlockBase = /* @__PURE__ */ defineComponent({
|
|
|
304
308
|
"onUpdate:modelValue": (v) => emit("update:modelValue", v)
|
|
305
309
|
}), null);
|
|
306
310
|
}
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
311
|
+
const view = {
|
|
312
|
+
...shared,
|
|
313
|
+
code: props.code,
|
|
314
|
+
inline: props.inline,
|
|
315
|
+
plain: props.plain,
|
|
316
|
+
copyable: props.copyable,
|
|
317
|
+
wrap: props.wrap,
|
|
318
|
+
onCopy: props.onCopy
|
|
319
|
+
};
|
|
320
|
+
const body = slots.default;
|
|
321
|
+
return body ? createVNode(CodeView, view, _isSlot(_slot = body()) ? _slot : {
|
|
322
|
+
default: () => [_slot]
|
|
323
|
+
}) : createVNode(CodeView, view, null);
|
|
317
324
|
};
|
|
318
325
|
}
|
|
319
326
|
});
|
|
@@ -41,7 +41,12 @@ export interface FilterProps {
|
|
|
41
41
|
title?: string;
|
|
42
42
|
/** 标题下的说明小字(透传给 `Form.Header`) */
|
|
43
43
|
description?: string;
|
|
44
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* label 列宽(px),透传给 `Form`。
|
|
46
|
+
*
|
|
47
|
+
* **缺省不设**:不传即与 `Form` 一致(取令牌 `--ui-form-label-width`,120)。
|
|
48
|
+
* 想收窄(筛选条的标签多为四字)就显式传,例如 `labelWidth={68}`。
|
|
49
|
+
*/
|
|
45
50
|
labelWidth?: number;
|
|
46
51
|
/** 受控条件快照(`条件名 → 值`);不传即非受控(由 `defaultValue` 起) */
|
|
47
52
|
modelValue?: FilterValues;
|
|
@@ -79,7 +84,8 @@ export interface FilterItemProps {
|
|
|
79
84
|
* 增量只有一处 —— **读写的值都是归一后的**(`'all'` / 空数组 / 空值 → 空串),
|
|
80
85
|
* 于是消费方直接把 `value` 绑给控件,不必自己处理哨兵。
|
|
81
86
|
*
|
|
82
|
-
*
|
|
87
|
+
* 字段宽**自适应**:字段区是 `Form` 的多列动态档(`Filter` 传 `columns="auto"`),
|
|
88
|
+
* 故本件只输出 `Form.Item` 自己的类 —— 列宽由那条网格轨道算,换行下来的字段与上一行逐列对齐。
|
|
83
89
|
*
|
|
84
90
|
* @example
|
|
85
91
|
* <Filter.Item code="status" label="授权状态">
|
|
@@ -2,8 +2,6 @@ import { defineComponent, createVNode, ref, h, Fragment } from "vue";
|
|
|
2
2
|
import { Button } from "../button/index.js";
|
|
3
3
|
import { FormItem, Form } from "../form/index.js";
|
|
4
4
|
const FILTER_ALL = "all";
|
|
5
|
-
const FILTER_LABEL_WIDTH = 68;
|
|
6
|
-
const FILTER_GAP = 16;
|
|
7
5
|
function normalizeFilterValue(value) {
|
|
8
6
|
if (Array.isArray(value)) {
|
|
9
7
|
const kept = value.map((item) => normalizeFilterValue(item)).filter((item) => item !== "");
|
|
@@ -96,7 +94,7 @@ const FilterRoot = /* @__PURE__ */ defineComponent({
|
|
|
96
94
|
emit("update:modelValue", next);
|
|
97
95
|
props.onReset?.(next);
|
|
98
96
|
};
|
|
99
|
-
const
|
|
97
|
+
const onFormKeydown = (event) => {
|
|
100
98
|
if (event.key !== "Enter" || event.isComposing) return;
|
|
101
99
|
const target = event.target;
|
|
102
100
|
if (target?.tagName !== "INPUT" || target.closest("[popover]")) return;
|
|
@@ -118,30 +116,23 @@ const FilterRoot = /* @__PURE__ */ defineComponent({
|
|
|
118
116
|
"ref": formRef,
|
|
119
117
|
"class": ["mh-filter__form", attrs.class].filter(Boolean).join(" "),
|
|
120
118
|
"style": attrs.style,
|
|
121
|
-
"labelWidth": props.labelWidth
|
|
122
|
-
"
|
|
119
|
+
"labelWidth": props.labelWidth,
|
|
120
|
+
"columns": "auto",
|
|
121
|
+
"onKeydown": onFormKeydown,
|
|
123
122
|
"modelValue": props.modelValue,
|
|
124
123
|
"defaultValue": props.defaultValue,
|
|
125
124
|
"onChange": onFormChange
|
|
126
125
|
}, {
|
|
127
|
-
default: () =>
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
h(Form.Header, {
|
|
126
|
+
default: () => {
|
|
127
|
+
const raw = slots.default?.();
|
|
128
|
+
const fields = Array.isArray(raw) ? raw : raw == null ? [] : [raw];
|
|
129
|
+
return [h(Form.Header, {
|
|
132
130
|
title: props.title,
|
|
133
131
|
description: props.description
|
|
134
132
|
}, {
|
|
135
133
|
extra: renderActions
|
|
136
|
-
}),
|
|
137
|
-
|
|
138
|
-
h("div", {
|
|
139
|
-
class: "mh-filter__fields",
|
|
140
|
-
onKeydown: onFieldsKeydown
|
|
141
|
-
}, {
|
|
142
|
-
default: () => slots.default?.()
|
|
143
|
-
})
|
|
144
|
-
]
|
|
134
|
+
}), ...fields];
|
|
135
|
+
}
|
|
145
136
|
});
|
|
146
137
|
}
|
|
147
138
|
});
|
|
@@ -181,7 +172,7 @@ const FilterItem = /* @__PURE__ */ defineComponent({
|
|
|
181
172
|
"required": props.required,
|
|
182
173
|
"error": props.error,
|
|
183
174
|
"hint": props.hint,
|
|
184
|
-
"class":
|
|
175
|
+
"class": attrs.class,
|
|
185
176
|
"style": attrs.style
|
|
186
177
|
}, {
|
|
187
178
|
default: (scope) => slots.default?.({
|
|
@@ -99,6 +99,18 @@ export interface FormProps {
|
|
|
99
99
|
defaultValue?: FormValues;
|
|
100
100
|
/** 值变更(快照含**全部已登记字段**,未设值的字段为 `undefined`) */
|
|
101
101
|
onChange?: (values: FormValues) => void;
|
|
102
|
+
/**
|
|
103
|
+
* 根节点的键盘事件(**转发到表单根**)。
|
|
104
|
+
*
|
|
105
|
+
* 本件是 `inheritAttrs: false`,根节点只显式绑 `class` / `style` —— 不声明的监听器会被**静默丢掉**
|
|
106
|
+
* (与该文件里已修过的「消费方 style 被静默丢弃」同款前科)。而根节点就是「全部字段行的容器」,
|
|
107
|
+
* 故它是「字段区层面的委托」的落点:本包 `Filter` 的「字段区回车 = 查询」就搭在这条通道上
|
|
108
|
+
* (构造 `Filter` 时因此不必再套一层只为挂事件的壳 —— 那会改变 `class` / `style` 的落点)。
|
|
109
|
+
*
|
|
110
|
+
* **有意只开这一条**:其它监听器(如 `onClick`)不转发;要把某一条也接进来,先当一次公开行为变更裁决。
|
|
111
|
+
* 要不要拦、拦哪些按键(本包 `Filter` 收窄到「`<input>` 上的回车」)由调用方自己判断,本件只转发。
|
|
112
|
+
*/
|
|
113
|
+
onKeydown?: (event: KeyboardEvent) => void;
|
|
102
114
|
}
|
|
103
115
|
export interface FormItemProps {
|
|
104
116
|
/**
|
|
@@ -193,6 +205,15 @@ export interface FormItemProps {
|
|
|
193
205
|
* `{ y, x }` 上下 / 左右分别给,缺省 0(贴容器边)。页面里的表单在 `Panel.Body` 里、内距由那块给;
|
|
194
206
|
* **弹窗 / 抽屉里没有别的容器**给内距,就用表单自带的 `padding={{ y: 16, x: 20 }}`。
|
|
195
207
|
*
|
|
208
|
+
* ## 键盘事件(`onKeydown` 转发到根节点)
|
|
209
|
+
*
|
|
210
|
+
* `onKeydown` 是本件的**声明式入口**(缺省不绑):传进来的处理器绑在根节点上 ——
|
|
211
|
+
* 本件是 `inheritAttrs: false`,根节点只显式绑 `class` / `style`,不声明的监听器会被静默丢掉。
|
|
212
|
+
* 根节点即「全部字段行的容器」,因此它是「字段区层面的委托」的落点:本包 `Filter` 的
|
|
213
|
+
* 「字段区回车 = 查询」就搭在这里,构造 `Filter` 时**不必**再套一层只为挂事件的壳
|
|
214
|
+
* (那会改变 `class` / `style` 的落点)。要不要拦、拦哪些按键由调用方自己判断,本件只转发。
|
|
215
|
+
* **有意只开这一条**:其它监听器不转发,扩张要先当一次公开行为变更裁决。
|
|
216
|
+
*
|
|
196
217
|
* ## 只读值(摘要 / 详情)
|
|
197
218
|
*
|
|
198
219
|
* 「向导最后一步的确认摘要」「详情弹窗」不需要另起一套描述列表件 —— 只用表单行本身,
|
|
@@ -455,6 +476,11 @@ export declare const Form: {
|
|
|
455
476
|
type: PropType<(values: FormValues) => void>;
|
|
456
477
|
default: undefined;
|
|
457
478
|
};
|
|
479
|
+
/** 根节点的键盘事件(转发到表单根;缺省不绑)—— 用途与边界见 `FormProps` 的同名注释 */
|
|
480
|
+
onKeydown: {
|
|
481
|
+
type: PropType<(event: KeyboardEvent) => void>;
|
|
482
|
+
default: undefined;
|
|
483
|
+
};
|
|
458
484
|
}>> & Readonly<{
|
|
459
485
|
"onUpdate:modelValue"?: ((values: FormValues) => any) | undefined;
|
|
460
486
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -463,6 +489,7 @@ export declare const Form: {
|
|
|
463
489
|
padding: Padding;
|
|
464
490
|
layout: "horizontal" | "vertical";
|
|
465
491
|
onChange: (values: FormValues) => void;
|
|
492
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
466
493
|
defaultValue: FormValues;
|
|
467
494
|
gap: number;
|
|
468
495
|
columns: FormColumns;
|
|
@@ -544,12 +571,18 @@ export declare const Form: {
|
|
|
544
571
|
type: PropType<(values: FormValues) => void>;
|
|
545
572
|
default: undefined;
|
|
546
573
|
};
|
|
574
|
+
/** 根节点的键盘事件(转发到表单根;缺省不绑)—— 用途与边界见 `FormProps` 的同名注释 */
|
|
575
|
+
onKeydown: {
|
|
576
|
+
type: PropType<(event: KeyboardEvent) => void>;
|
|
577
|
+
default: undefined;
|
|
578
|
+
};
|
|
547
579
|
}>> & Readonly<{
|
|
548
580
|
"onUpdate:modelValue"?: ((values: FormValues) => any) | undefined;
|
|
549
581
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, {
|
|
550
582
|
padding: Padding;
|
|
551
583
|
layout: "horizontal" | "vertical";
|
|
552
584
|
onChange: (values: FormValues) => void;
|
|
585
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
553
586
|
defaultValue: FormValues;
|
|
554
587
|
gap: number;
|
|
555
588
|
columns: FormColumns;
|
|
@@ -626,6 +659,11 @@ export declare const Form: {
|
|
|
626
659
|
type: PropType<(values: FormValues) => void>;
|
|
627
660
|
default: undefined;
|
|
628
661
|
};
|
|
662
|
+
/** 根节点的键盘事件(转发到表单根;缺省不绑)—— 用途与边界见 `FormProps` 的同名注释 */
|
|
663
|
+
onKeydown: {
|
|
664
|
+
type: PropType<(event: KeyboardEvent) => void>;
|
|
665
|
+
default: undefined;
|
|
666
|
+
};
|
|
629
667
|
}>> & Readonly<{
|
|
630
668
|
"onUpdate:modelValue"?: ((values: FormValues) => any) | undefined;
|
|
631
669
|
}>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
|
|
@@ -634,6 +672,7 @@ export declare const Form: {
|
|
|
634
672
|
padding: Padding;
|
|
635
673
|
layout: "horizontal" | "vertical";
|
|
636
674
|
onChange: (values: FormValues) => void;
|
|
675
|
+
onKeydown: (event: KeyboardEvent) => void;
|
|
637
676
|
defaultValue: FormValues;
|
|
638
677
|
gap: number;
|
|
639
678
|
columns: FormColumns;
|
|
@@ -236,6 +236,11 @@ const FormRoot = /* @__PURE__ */ defineComponent({
|
|
|
236
236
|
onChange: {
|
|
237
237
|
type: Function,
|
|
238
238
|
default: void 0
|
|
239
|
+
},
|
|
240
|
+
/** 根节点的键盘事件(转发到表单根;缺省不绑)—— 用途与边界见 `FormProps` 的同名注释 */
|
|
241
|
+
onKeydown: {
|
|
242
|
+
type: Function,
|
|
243
|
+
default: void 0
|
|
239
244
|
}
|
|
240
245
|
},
|
|
241
246
|
emits: {
|
|
@@ -313,6 +318,7 @@ const FormRoot = /* @__PURE__ */ defineComponent({
|
|
|
313
318
|
} = splitFormHeader(list);
|
|
314
319
|
return createVNode("div", {
|
|
315
320
|
"class": ["mh-form", columnsClass(), props.layout === "vertical" ? "mh-form--vertical" : "", attrs.class].filter(Boolean).join(" "),
|
|
321
|
+
"onKeydown": props.onKeydown,
|
|
316
322
|
"style": [
|
|
317
323
|
mergePartStyle(attrs.style, props.padding),
|
|
318
324
|
/* 行距同时下发实体 `gap` 与变量:多列的轨道下限公式要用**同一个**行距值算 ——
|
|
@@ -22,6 +22,11 @@ export interface TextareaAutoSize {
|
|
|
22
22
|
* 附加位:`prefix` / `suffix` **插槽**里放什么由你决定(图标 / 单位 / 域名 / 你自己的可点元素),
|
|
23
23
|
* 本件不内置标签件 —— 纯装饰形态无底色、不参与 Tab 序列,可点形态的热区与底色归消费方。
|
|
24
24
|
*
|
|
25
|
+
* **属性落点**(用错位置就会「样式在壳上、属性在组件上被丢掉」):
|
|
26
|
+
* `class` / `style` → 表壳 `.mh-input__wrap`(整件的宽度与显式锚);**其余 attrs 一律透传到控件**
|
|
27
|
+
* (`id` / `name` / `aria-*` / `data-*` / `title` / 原生事件)—— 壳只是排版容器,属性落它上面等于丢掉
|
|
28
|
+
* —— 见 `forwardAttrs`;触发器形态另有 `controlClass` / `controlAttrs` 两个**专口子**(同名键以它为准)。
|
|
29
|
+
*
|
|
25
30
|
* @example 受控 + 可清除
|
|
26
31
|
* <Input modelValue={kw} placeholder="搜索" clearable prefix={<Icon name="search" />} onChange={setKw} />
|
|
27
32
|
*
|
|
@@ -35,8 +40,9 @@ export interface TextareaAutoSize {
|
|
|
35
40
|
* <Textarea modelValue={note} autoSize={{ minRows: 2, maxRows: 6 }} maxlength={500} showCount onChange={setNote} />
|
|
36
41
|
*
|
|
37
42
|
* @example 触发器形态(复合件用:控件换成 `<button>`,表壳 / 清除位 / 右侧图标位全部复用)
|
|
38
|
-
* <Input as="button" clearable hasValue={!!value} controlClass="my-picker"
|
|
39
|
-
* {{
|
|
43
|
+
* <Input as="button" clearable hasValue={!!value} placeholder="请选择" controlClass="my-picker"
|
|
44
|
+
* controlAttrs={{ popovertarget: id }}>
|
|
45
|
+
* {{ default: () => value, suffix: () => <Icon name="chevron-down" /> }}
|
|
40
46
|
* </Input>
|
|
41
47
|
*/
|
|
42
48
|
export declare const Input: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
|
|
@@ -50,6 +56,13 @@ export declare const Input: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
50
56
|
type: StringConstructor;
|
|
51
57
|
default: string;
|
|
52
58
|
};
|
|
59
|
+
/**
|
|
60
|
+
* 占位文案。两种形态都消费它:
|
|
61
|
+
* - 缺省(`as="input"`)走原生 `::placeholder` 伪元素;
|
|
62
|
+
* - 触发器形态(`as="button"`)**没有 `::placeholder` 可用**,改由一个 span 承载
|
|
63
|
+
* (`.mh-input__placeholder`)—— 当且仅当 `hasValue === false` 且本 prop 有值时渲染它,
|
|
64
|
+
* 并**取代** `default` 插槽(见上面触发器一节)。没传 `hasValue` 的调用方行为不变。
|
|
65
|
+
*/
|
|
53
66
|
placeholder: {
|
|
54
67
|
type: StringConstructor;
|
|
55
68
|
default: undefined;
|
|
@@ -107,7 +120,7 @@ export declare const Input: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
107
120
|
type: NumberConstructor;
|
|
108
121
|
default: undefined;
|
|
109
122
|
};
|
|
110
|
-
/**
|
|
123
|
+
/** 右侧字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
111
124
|
showCount: {
|
|
112
125
|
type: BooleanConstructor;
|
|
113
126
|
default: boolean;
|
|
@@ -137,12 +150,14 @@ export declare const Input: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
137
150
|
type: StringConstructor;
|
|
138
151
|
default: undefined;
|
|
139
152
|
};
|
|
140
|
-
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown`
|
|
153
|
+
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown` 落到控件上);
|
|
154
|
+
* 与透传的 attrs 撞名时以本 prop 为准 */
|
|
141
155
|
controlAttrs: {
|
|
142
156
|
type: PropType<Record<string, unknown>>;
|
|
143
157
|
default: undefined;
|
|
144
158
|
};
|
|
145
|
-
/**
|
|
159
|
+
/** 显式覆盖清除位显隐;不给时仍按「有内容」判定(多选类复合件没有单值可判)。
|
|
160
|
+
* 同时是触发器形态「显示值还是显示占位」的判据(仅当它为 `false` 且传了 `placeholder` 时接管) */
|
|
146
161
|
hasValue: {
|
|
147
162
|
type: BooleanConstructor;
|
|
148
163
|
default: undefined;
|
|
@@ -160,6 +175,13 @@ export declare const Input: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
160
175
|
type: StringConstructor;
|
|
161
176
|
default: string;
|
|
162
177
|
};
|
|
178
|
+
/**
|
|
179
|
+
* 占位文案。两种形态都消费它:
|
|
180
|
+
* - 缺省(`as="input"`)走原生 `::placeholder` 伪元素;
|
|
181
|
+
* - 触发器形态(`as="button"`)**没有 `::placeholder` 可用**,改由一个 span 承载
|
|
182
|
+
* (`.mh-input__placeholder`)—— 当且仅当 `hasValue === false` 且本 prop 有值时渲染它,
|
|
183
|
+
* 并**取代** `default` 插槽(见上面触发器一节)。没传 `hasValue` 的调用方行为不变。
|
|
184
|
+
*/
|
|
163
185
|
placeholder: {
|
|
164
186
|
type: StringConstructor;
|
|
165
187
|
default: undefined;
|
|
@@ -217,7 +239,7 @@ export declare const Input: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
217
239
|
type: NumberConstructor;
|
|
218
240
|
default: undefined;
|
|
219
241
|
};
|
|
220
|
-
/**
|
|
242
|
+
/** 右侧字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
221
243
|
showCount: {
|
|
222
244
|
type: BooleanConstructor;
|
|
223
245
|
default: boolean;
|
|
@@ -247,12 +269,14 @@ export declare const Input: import("vue").DefineComponent<import("vue").ExtractP
|
|
|
247
269
|
type: StringConstructor;
|
|
248
270
|
default: undefined;
|
|
249
271
|
};
|
|
250
|
-
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown`
|
|
272
|
+
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown` 落到控件上);
|
|
273
|
+
* 与透传的 attrs 撞名时以本 prop 为准 */
|
|
251
274
|
controlAttrs: {
|
|
252
275
|
type: PropType<Record<string, unknown>>;
|
|
253
276
|
default: undefined;
|
|
254
277
|
};
|
|
255
|
-
/**
|
|
278
|
+
/** 显式覆盖清除位显隐;不给时仍按「有内容」判定(多选类复合件没有单值可判)。
|
|
279
|
+
* 同时是触发器形态「显示值还是显示占位」的判据(仅当它为 `false` 且传了 `placeholder` 时接管) */
|
|
256
280
|
hasValue: {
|
|
257
281
|
type: BooleanConstructor;
|
|
258
282
|
default: undefined;
|
|
@@ -307,7 +331,7 @@ export interface TextareaProps {
|
|
|
307
331
|
/** 是否带边框 */
|
|
308
332
|
bordered?: boolean;
|
|
309
333
|
maxlength?: number;
|
|
310
|
-
/** 右下角字数统计(须给 `maxlength`
|
|
334
|
+
/** 右下角字数统计(须给 `maxlength` 才渲染) */
|
|
311
335
|
showCount?: boolean;
|
|
312
336
|
autofocus?: boolean;
|
|
313
337
|
onChange?: (v: string) => void;
|
|
@@ -315,8 +339,9 @@ export interface TextareaProps {
|
|
|
315
339
|
/**
|
|
316
340
|
* 多行输入(同一份面;结构与单行不同,故单列一个件)。
|
|
317
341
|
*
|
|
318
|
-
* ⚠️
|
|
319
|
-
*
|
|
342
|
+
* ⚠️ **输入族没有 `mono` 档**(`Input` 与 `Textarea` 都没有)。要等宽的输入框别拿 `Text mono` 去包
|
|
343
|
+
* —— 那会丢掉输入能力;目前只能由应用侧保留一条带 `font-family: var(--ui-font-mono)` 的样式登记
|
|
344
|
+
* (缺件登记见下游仓 `aihub-frontend/docs/kit-gaps.md`,本仓不复制那份台账)。
|
|
320
345
|
*
|
|
321
346
|
* @example 备注框:自适应 2~6 行 + 限长计数
|
|
322
347
|
* <Textarea modelValue={note} autoSize={{ minRows: 2, maxRows: 6 }} maxlength={500} showCount onChange={setNote} />
|
|
@@ -371,6 +396,7 @@ export declare const Textarea: import("vue").DefineComponent<import("vue").Extra
|
|
|
371
396
|
type: NumberConstructor;
|
|
372
397
|
default: undefined;
|
|
373
398
|
};
|
|
399
|
+
/** 右下角字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
374
400
|
showCount: {
|
|
375
401
|
type: BooleanConstructor;
|
|
376
402
|
default: boolean;
|
|
@@ -435,6 +461,7 @@ export declare const Textarea: import("vue").DefineComponent<import("vue").Extra
|
|
|
435
461
|
type: NumberConstructor;
|
|
436
462
|
default: undefined;
|
|
437
463
|
};
|
|
464
|
+
/** 右下角字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
438
465
|
showCount: {
|
|
439
466
|
type: BooleanConstructor;
|
|
440
467
|
default: boolean;
|
|
@@ -478,6 +505,13 @@ export declare const InputCompound: {
|
|
|
478
505
|
type: StringConstructor;
|
|
479
506
|
default: string;
|
|
480
507
|
};
|
|
508
|
+
/**
|
|
509
|
+
* 占位文案。两种形态都消费它:
|
|
510
|
+
* - 缺省(`as="input"`)走原生 `::placeholder` 伪元素;
|
|
511
|
+
* - 触发器形态(`as="button"`)**没有 `::placeholder` 可用**,改由一个 span 承载
|
|
512
|
+
* (`.mh-input__placeholder`)—— 当且仅当 `hasValue === false` 且本 prop 有值时渲染它,
|
|
513
|
+
* 并**取代** `default` 插槽(见上面触发器一节)。没传 `hasValue` 的调用方行为不变。
|
|
514
|
+
*/
|
|
481
515
|
placeholder: {
|
|
482
516
|
type: StringConstructor;
|
|
483
517
|
default: undefined;
|
|
@@ -535,7 +569,7 @@ export declare const InputCompound: {
|
|
|
535
569
|
type: NumberConstructor;
|
|
536
570
|
default: undefined;
|
|
537
571
|
};
|
|
538
|
-
/**
|
|
572
|
+
/** 右侧字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
539
573
|
showCount: {
|
|
540
574
|
type: BooleanConstructor;
|
|
541
575
|
default: boolean;
|
|
@@ -565,12 +599,14 @@ export declare const InputCompound: {
|
|
|
565
599
|
type: StringConstructor;
|
|
566
600
|
default: undefined;
|
|
567
601
|
};
|
|
568
|
-
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown`
|
|
602
|
+
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown` 落到控件上);
|
|
603
|
+
* 与透传的 attrs 撞名时以本 prop 为准 */
|
|
569
604
|
controlAttrs: {
|
|
570
605
|
type: PropType<Record<string, unknown>>;
|
|
571
606
|
default: undefined;
|
|
572
607
|
};
|
|
573
|
-
/**
|
|
608
|
+
/** 显式覆盖清除位显隐;不给时仍按「有内容」判定(多选类复合件没有单值可判)。
|
|
609
|
+
* 同时是触发器形态「显示值还是显示占位」的判据(仅当它为 `false` 且传了 `placeholder` 时接管) */
|
|
574
610
|
hasValue: {
|
|
575
611
|
type: BooleanConstructor;
|
|
576
612
|
default: undefined;
|
|
@@ -622,6 +658,13 @@ export declare const InputCompound: {
|
|
|
622
658
|
type: StringConstructor;
|
|
623
659
|
default: string;
|
|
624
660
|
};
|
|
661
|
+
/**
|
|
662
|
+
* 占位文案。两种形态都消费它:
|
|
663
|
+
* - 缺省(`as="input"`)走原生 `::placeholder` 伪元素;
|
|
664
|
+
* - 触发器形态(`as="button"`)**没有 `::placeholder` 可用**,改由一个 span 承载
|
|
665
|
+
* (`.mh-input__placeholder`)—— 当且仅当 `hasValue === false` 且本 prop 有值时渲染它,
|
|
666
|
+
* 并**取代** `default` 插槽(见上面触发器一节)。没传 `hasValue` 的调用方行为不变。
|
|
667
|
+
*/
|
|
625
668
|
placeholder: {
|
|
626
669
|
type: StringConstructor;
|
|
627
670
|
default: undefined;
|
|
@@ -679,7 +722,7 @@ export declare const InputCompound: {
|
|
|
679
722
|
type: NumberConstructor;
|
|
680
723
|
default: undefined;
|
|
681
724
|
};
|
|
682
|
-
/**
|
|
725
|
+
/** 右侧字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
683
726
|
showCount: {
|
|
684
727
|
type: BooleanConstructor;
|
|
685
728
|
default: boolean;
|
|
@@ -709,12 +752,14 @@ export declare const InputCompound: {
|
|
|
709
752
|
type: StringConstructor;
|
|
710
753
|
default: undefined;
|
|
711
754
|
};
|
|
712
|
-
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown`
|
|
755
|
+
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown` 落到控件上);
|
|
756
|
+
* 与透传的 attrs 撞名时以本 prop 为准 */
|
|
713
757
|
controlAttrs: {
|
|
714
758
|
type: PropType<Record<string, unknown>>;
|
|
715
759
|
default: undefined;
|
|
716
760
|
};
|
|
717
|
-
/**
|
|
761
|
+
/** 显式覆盖清除位显隐;不给时仍按「有内容」判定(多选类复合件没有单值可判)。
|
|
762
|
+
* 同时是触发器形态「显示值还是显示占位」的判据(仅当它为 `false` 且传了 `placeholder` 时接管) */
|
|
718
763
|
hasValue: {
|
|
719
764
|
type: BooleanConstructor;
|
|
720
765
|
default: undefined;
|
|
@@ -757,6 +802,13 @@ export declare const InputCompound: {
|
|
|
757
802
|
type: StringConstructor;
|
|
758
803
|
default: string;
|
|
759
804
|
};
|
|
805
|
+
/**
|
|
806
|
+
* 占位文案。两种形态都消费它:
|
|
807
|
+
* - 缺省(`as="input"`)走原生 `::placeholder` 伪元素;
|
|
808
|
+
* - 触发器形态(`as="button"`)**没有 `::placeholder` 可用**,改由一个 span 承载
|
|
809
|
+
* (`.mh-input__placeholder`)—— 当且仅当 `hasValue === false` 且本 prop 有值时渲染它,
|
|
810
|
+
* 并**取代** `default` 插槽(见上面触发器一节)。没传 `hasValue` 的调用方行为不变。
|
|
811
|
+
*/
|
|
760
812
|
placeholder: {
|
|
761
813
|
type: StringConstructor;
|
|
762
814
|
default: undefined;
|
|
@@ -814,7 +866,7 @@ export declare const InputCompound: {
|
|
|
814
866
|
type: NumberConstructor;
|
|
815
867
|
default: undefined;
|
|
816
868
|
};
|
|
817
|
-
/**
|
|
869
|
+
/** 右侧字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
818
870
|
showCount: {
|
|
819
871
|
type: BooleanConstructor;
|
|
820
872
|
default: boolean;
|
|
@@ -844,12 +896,14 @@ export declare const InputCompound: {
|
|
|
844
896
|
type: StringConstructor;
|
|
845
897
|
default: undefined;
|
|
846
898
|
};
|
|
847
|
-
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown`
|
|
899
|
+
/** 展开到**控件元素**上的属性(触发器形态要 `popovertarget` / `aria-*` / `onKeydown` 落到控件上);
|
|
900
|
+
* 与透传的 attrs 撞名时以本 prop 为准 */
|
|
848
901
|
controlAttrs: {
|
|
849
902
|
type: PropType<Record<string, unknown>>;
|
|
850
903
|
default: undefined;
|
|
851
904
|
};
|
|
852
|
-
/**
|
|
905
|
+
/** 显式覆盖清除位显隐;不给时仍按「有内容」判定(多选类复合件没有单值可判)。
|
|
906
|
+
* 同时是触发器形态「显示值还是显示占位」的判据(仅当它为 `false` 且传了 `placeholder` 时接管) */
|
|
853
907
|
hasValue: {
|
|
854
908
|
type: BooleanConstructor;
|
|
855
909
|
default: undefined;
|
|
@@ -934,6 +988,7 @@ export declare const InputCompound: {
|
|
|
934
988
|
type: NumberConstructor;
|
|
935
989
|
default: undefined;
|
|
936
990
|
};
|
|
991
|
+
/** 右下角字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
937
992
|
showCount: {
|
|
938
993
|
type: BooleanConstructor;
|
|
939
994
|
default: boolean;
|
|
@@ -998,6 +1053,7 @@ export declare const InputCompound: {
|
|
|
998
1053
|
type: NumberConstructor;
|
|
999
1054
|
default: undefined;
|
|
1000
1055
|
};
|
|
1056
|
+
/** 右下角字数统计(**须给 `maxlength` 才渲染**:没有分母的 `n/0` 是坏值) */
|
|
1001
1057
|
showCount: {
|
|
1002
1058
|
type: BooleanConstructor;
|
|
1003
1059
|
default: boolean;
|