@manohub/ui 1.0.0 → 1.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,239 @@
1
+ import { type PropType, type SlotsType, type VNodeChild } from 'vue';
2
+ import type { ControlSize } from '../control-size';
3
+ import type { InputStatus } from './index';
4
+ /**
5
+ * 数字输入(**自绘**)。
6
+ *
7
+ * 与 `Input` **同族同面**(同一个表壳 / 内距 / 状态协议,样式归 `styles/components/input.css`),
8
+ * 按 `AGENTS.md` 硬约束 1 的「同族两件可并排平级导出、共用同一目录与同一份面」处置
9
+ * —— 与 `Input` / `Textarea` 的关系同款,故不另开组件目录、不新增面文件。
10
+ *
11
+ * 为什么单列一个件而不是加进 `Input`:`Input` 的 `modelValue` 是 **string**,且已串起
12
+ * 「密码可见切换 / 清除位 / 字数统计 / 触发器形态」一条链;把数值语义(`min` / `max` / `step` /
13
+ * `precision` / 钳制 / 舍入 / 步进按钮)塞进去会污染统一词表(`AGENTS.md` 硬约束 8)。
14
+ * 本件也**不接** `Input` 的 `as="button"` 触发器形态 —— 那是复合件(`Select` 一族)的口子。
15
+ *
16
+ * 统一词表(与 `Checkbox` / `Switch` / `Input` 同款):`modelValue` / `onChange` / `disabled` / `size`;
17
+ * 值变更时 `emit('update:modelValue')` 与 `onChange` **双走**。
18
+ *
19
+ * ## 值域口径(三条,都是「原生数字框最被讨厌的点」的反面)
20
+ *
21
+ * 1. **空值是 `null`,不是 `0`**:留空与「填了 0」是两件事,前者不提交、后者要提交。
22
+ * 2. **输入中途不钳制**:`-` / `1.` / 空串这些中间态一律原样留着(打一半就被改掉会打断输入);
23
+ * 钳制与舍入发生在**归一时刻** —— `blur` / `Enter` / 步进按钮 / `min`·`max`·`precision` 变化。
24
+ * 3. **非法输入回滚**:解析不出来(如 `1a`)就退回上一个合法值,**不静默变 0**。
25
+ *
26
+ * 属性落点与 `Input` 完全同款:`class` / `style` → 表壳 `.mh-input__wrap`;其余 attrs 一律透传到
27
+ * 控件(`id` / `name` / `aria-*` / `data-*` / 原生事件),见 `forwardAttrs`。
28
+ *
29
+ * @example 受控 + 区间
30
+ * <NumberInput modelValue={timeout} min={0} max={43200} onChange={setTimeout} />
31
+ *
32
+ * @example 表格内 / 行内编辑档(无框)
33
+ * <NumberInput modelValue={row.value} bordered={false} precision={0} onChange={set} />
34
+ *
35
+ * @example 带单位后缀
36
+ * <NumberInput modelValue={size} min={1}>
37
+ * {{ suffix: () => 'MB' }}
38
+ * </NumberInput>
39
+ */
40
+ export interface NumberInputProps {
41
+ /** 受控值(空值为 `null`,不是 `0`) */
42
+ modelValue?: number | null;
43
+ /** 非受控初值(缺省 `null`) */
44
+ defaultValue?: number | null;
45
+ /** 下界(含):归一时刻钳住 */
46
+ min?: number;
47
+ /** 上界(含):归一时刻钳住 */
48
+ max?: number;
49
+ /** 步进量(缺省 1);同时决定 `precision` 的缺省推断(整数步长 → 0 位小数) */
50
+ step?: number;
51
+ /** 小数位;显式给出时优先于按 `step` 推断 */
52
+ precision?: number;
53
+ placeholder?: string;
54
+ /** 尺寸档(与全库 `ControlSize` 同表:24 / 28 / 32) */
55
+ size?: ControlSize;
56
+ disabled?: boolean;
57
+ /** 只读(口径同 `Input`:值可选中复制,但不能改;步进按钮一并收掉) */
58
+ readonly?: boolean;
59
+ /** 校验态(下发 `aria-invalid`,样式走协议不看 data-*);等价于 `status="error"` */
60
+ invalid?: boolean;
61
+ /** 校验状态(`invalid` 的显式写法;两者同时给以 `status` 为准) */
62
+ status?: InputStatus;
63
+ /** 是否带边框(三档口径见 `Input` 的同名 prop:`true` / `false` / `'focus'`) */
64
+ bordered?: boolean | 'focus';
65
+ /** 是否渲染右端步进按钮(缺省 true;`readonly` / `disabled` 时自动不渲染) */
66
+ controls?: boolean;
67
+ /** 失焦时钳到 `[min, max]` 并按 `precision` 舍入(缺省 true) */
68
+ clampOnBlur?: boolean;
69
+ /** 值变更回调(模型与 `emit` 双走) */
70
+ onChange?: (v: number | null) => void;
71
+ /** 回车回调(回车会先做一次归一) */
72
+ onEnter?: (v: number | null) => void;
73
+ }
74
+ export declare const NumberInput: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
75
+ modelValue: {
76
+ type: PropType<number | null>;
77
+ default: undefined;
78
+ };
79
+ defaultValue: {
80
+ type: PropType<number | null>;
81
+ default: null;
82
+ };
83
+ min: {
84
+ type: NumberConstructor;
85
+ default: undefined;
86
+ };
87
+ max: {
88
+ type: NumberConstructor;
89
+ default: undefined;
90
+ };
91
+ step: {
92
+ type: NumberConstructor;
93
+ default: undefined;
94
+ };
95
+ precision: {
96
+ type: NumberConstructor;
97
+ default: undefined;
98
+ };
99
+ placeholder: {
100
+ type: StringConstructor;
101
+ default: undefined;
102
+ };
103
+ size: {
104
+ type: PropType<ControlSize>;
105
+ default: string;
106
+ };
107
+ disabled: {
108
+ type: BooleanConstructor;
109
+ default: boolean;
110
+ };
111
+ readonly: {
112
+ type: BooleanConstructor;
113
+ default: boolean;
114
+ };
115
+ invalid: {
116
+ type: BooleanConstructor;
117
+ default: boolean;
118
+ };
119
+ status: {
120
+ type: PropType<InputStatus>;
121
+ default: undefined;
122
+ };
123
+ /** 是否带边框(三档口径见 `Input` 的同名 prop:`true` 常有框 / `false` 无框 / `'focus'` 聚焦才显框) */
124
+ bordered: {
125
+ type: PropType<boolean | "focus">;
126
+ default: boolean;
127
+ };
128
+ controls: {
129
+ type: BooleanConstructor;
130
+ default: boolean;
131
+ };
132
+ clampOnBlur: {
133
+ type: BooleanConstructor;
134
+ default: boolean;
135
+ };
136
+ onChange: {
137
+ type: PropType<(v: number | null) => void>;
138
+ default: undefined;
139
+ };
140
+ onEnter: {
141
+ type: PropType<(v: number | null) => void>;
142
+ default: undefined;
143
+ };
144
+ }>, () => import("vue/jsx-runtime").JSX.Element, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
145
+ 'update:modelValue': (v: number | null) => true;
146
+ }, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
147
+ modelValue: {
148
+ type: PropType<number | null>;
149
+ default: undefined;
150
+ };
151
+ defaultValue: {
152
+ type: PropType<number | null>;
153
+ default: null;
154
+ };
155
+ min: {
156
+ type: NumberConstructor;
157
+ default: undefined;
158
+ };
159
+ max: {
160
+ type: NumberConstructor;
161
+ default: undefined;
162
+ };
163
+ step: {
164
+ type: NumberConstructor;
165
+ default: undefined;
166
+ };
167
+ precision: {
168
+ type: NumberConstructor;
169
+ default: undefined;
170
+ };
171
+ placeholder: {
172
+ type: StringConstructor;
173
+ default: undefined;
174
+ };
175
+ size: {
176
+ type: PropType<ControlSize>;
177
+ default: string;
178
+ };
179
+ disabled: {
180
+ type: BooleanConstructor;
181
+ default: boolean;
182
+ };
183
+ readonly: {
184
+ type: BooleanConstructor;
185
+ default: boolean;
186
+ };
187
+ invalid: {
188
+ type: BooleanConstructor;
189
+ default: boolean;
190
+ };
191
+ status: {
192
+ type: PropType<InputStatus>;
193
+ default: undefined;
194
+ };
195
+ /** 是否带边框(三档口径见 `Input` 的同名 prop:`true` 常有框 / `false` 无框 / `'focus'` 聚焦才显框) */
196
+ bordered: {
197
+ type: PropType<boolean | "focus">;
198
+ default: boolean;
199
+ };
200
+ controls: {
201
+ type: BooleanConstructor;
202
+ default: boolean;
203
+ };
204
+ clampOnBlur: {
205
+ type: BooleanConstructor;
206
+ default: boolean;
207
+ };
208
+ onChange: {
209
+ type: PropType<(v: number | null) => void>;
210
+ default: undefined;
211
+ };
212
+ onEnter: {
213
+ type: PropType<(v: number | null) => void>;
214
+ default: undefined;
215
+ };
216
+ }>> & Readonly<{
217
+ "onUpdate:modelValue"?: ((v: number | null) => any) | undefined;
218
+ }>, {
219
+ size: ControlSize;
220
+ disabled: boolean;
221
+ min: number;
222
+ max: number;
223
+ onChange: (v: number | null) => void;
224
+ invalid: boolean;
225
+ bordered: boolean | "focus";
226
+ defaultValue: number | null;
227
+ placeholder: string;
228
+ modelValue: number | null;
229
+ status: InputStatus;
230
+ step: number;
231
+ precision: number;
232
+ readonly: boolean;
233
+ controls: boolean;
234
+ clampOnBlur: boolean;
235
+ onEnter: (v: number | null) => void;
236
+ }, SlotsType<{
237
+ prefix?: () => VNodeChild;
238
+ suffix?: () => VNodeChild;
239
+ }>, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
@@ -0,0 +1,240 @@
1
+ import { defineComponent, ref, computed, watch, createVNode, mergeProps } from "vue";
2
+ import { Icon } from "@manohub/icon";
3
+ import { borderedClassOf } from "./bordered.js";
4
+ const NumberInput = /* @__PURE__ */ defineComponent({
5
+ name: "NumberInput",
6
+ inheritAttrs: false,
7
+ props: {
8
+ modelValue: {
9
+ type: Number,
10
+ default: void 0
11
+ },
12
+ defaultValue: {
13
+ type: Number,
14
+ default: null
15
+ },
16
+ min: {
17
+ type: Number,
18
+ default: void 0
19
+ },
20
+ max: {
21
+ type: Number,
22
+ default: void 0
23
+ },
24
+ step: {
25
+ type: Number,
26
+ default: void 0
27
+ },
28
+ precision: {
29
+ type: Number,
30
+ default: void 0
31
+ },
32
+ placeholder: {
33
+ type: String,
34
+ default: void 0
35
+ },
36
+ size: {
37
+ type: String,
38
+ default: "md"
39
+ },
40
+ disabled: {
41
+ type: Boolean,
42
+ default: false
43
+ },
44
+ readonly: {
45
+ type: Boolean,
46
+ default: false
47
+ },
48
+ invalid: {
49
+ type: Boolean,
50
+ default: false
51
+ },
52
+ status: {
53
+ type: String,
54
+ default: void 0
55
+ },
56
+ /** 是否带边框(三档口径见 `Input` 的同名 prop:`true` 常有框 / `false` 无框 / `'focus'` 聚焦才显框) */
57
+ bordered: {
58
+ type: [Boolean, String],
59
+ default: true
60
+ },
61
+ controls: {
62
+ type: Boolean,
63
+ default: true
64
+ },
65
+ clampOnBlur: {
66
+ type: Boolean,
67
+ default: true
68
+ },
69
+ onChange: {
70
+ type: Function,
71
+ default: void 0
72
+ },
73
+ onEnter: {
74
+ type: Function,
75
+ default: void 0
76
+ }
77
+ },
78
+ emits: {
79
+ "update:modelValue": (v) => true
80
+ },
81
+ slots: Object,
82
+ setup(props, {
83
+ emit,
84
+ slots,
85
+ attrs
86
+ }) {
87
+ const inner = ref(props.defaultValue ?? null);
88
+ const current = computed(() => props.modelValue === void 0 ? inner.value : props.modelValue);
89
+ const focused = ref(false);
90
+ const resolvedStep = computed(() => props.step !== void 0 && props.step > 0 ? props.step : 1);
91
+ const resolvedPrecision = computed(() => {
92
+ if (props.precision !== void 0 && props.precision >= 0) return Math.floor(props.precision);
93
+ const text = String(resolvedStep.value);
94
+ const dot = text.indexOf(".");
95
+ return dot < 0 ? 0 : text.length - dot - 1;
96
+ });
97
+ const roundTo = (value, precision) => {
98
+ const factor = 10 ** precision;
99
+ return Math.round(value * factor) / factor;
100
+ };
101
+ const clampValue = (value) => {
102
+ let next = value;
103
+ if (props.min !== void 0 && next < props.min) next = props.min;
104
+ if (props.max !== void 0 && next > props.max) next = props.max;
105
+ return next;
106
+ };
107
+ const normalize = (value) => clampValue(roundTo(value, resolvedPrecision.value));
108
+ const textOf = (value) => value === null || value === void 0 ? "" : String(roundTo(value, resolvedPrecision.value));
109
+ const parseInput = (raw) => {
110
+ const text = raw.trim();
111
+ if (!text) return null;
112
+ if (!/^[+-]?(\d+\.?\d*|\.\d+)$/.test(text)) return "invalid";
113
+ const value = Number(text);
114
+ return Number.isFinite(value) ? value : "invalid";
115
+ };
116
+ const draft = ref(textOf(current.value));
117
+ const display = computed(() => props.modelValue === void 0 ? draft.value : textOf(props.modelValue));
118
+ const inputRef = ref(null);
119
+ const syncDom = () => {
120
+ const el = inputRef.value;
121
+ if (el && el.value !== display.value) el.value = display.value;
122
+ };
123
+ const setModel = (value) => {
124
+ if (props.modelValue === void 0) inner.value = value;
125
+ emit("update:modelValue", value);
126
+ props.onChange?.(value);
127
+ };
128
+ const commit = (value) => {
129
+ setModel(value);
130
+ draft.value = textOf(value);
131
+ syncDom();
132
+ };
133
+ watch(current, (value) => {
134
+ if (!focused.value) draft.value = textOf(value);
135
+ });
136
+ watch(() => [props.min, props.max, props.precision, props.step], () => {
137
+ if (current.value === null) return;
138
+ const next = normalize(current.value);
139
+ if (next !== current.value) commit(next);
140
+ });
141
+ const forwardAttrs = computed(() => {
142
+ const rest = {};
143
+ for (const [key, value] of Object.entries(attrs)) {
144
+ if (key !== "class" && key !== "style") rest[key] = value;
145
+ }
146
+ return rest;
147
+ });
148
+ const visualStatus = computed(() => props.status ?? (props.invalid ? "error" : void 0));
149
+ const isInvalid = computed(() => visualStatus.value === "error");
150
+ const onInput = (event) => {
151
+ const el = event.target;
152
+ draft.value = el.value;
153
+ const parsed = parseInput(el.value);
154
+ if (parsed === "invalid") return;
155
+ setModel(parsed);
156
+ if (props.modelValue !== void 0 && props.modelValue !== parsed) syncDom();
157
+ };
158
+ const settle = () => {
159
+ const parsed = parseInput(draft.value);
160
+ if (parsed === "invalid") {
161
+ draft.value = textOf(current.value);
162
+ syncDom();
163
+ return current.value;
164
+ }
165
+ if (parsed === null) {
166
+ commit(null);
167
+ return null;
168
+ }
169
+ const next = props.clampOnBlur ? normalize(parsed) : roundTo(parsed, resolvedPrecision.value);
170
+ commit(next);
171
+ return next;
172
+ };
173
+ const onFocus = () => {
174
+ focused.value = true;
175
+ };
176
+ const onBlur = () => {
177
+ focused.value = false;
178
+ settle();
179
+ };
180
+ const onKeydown = (event) => {
181
+ if (event.isComposing) return;
182
+ if (event.key === "Enter") {
183
+ const value = settle();
184
+ props.onEnter?.(value);
185
+ return;
186
+ }
187
+ if (event.key === "ArrowUp" || event.key === "ArrowDown") {
188
+ if (props.disabled || props.readonly) return;
189
+ event.preventDefault();
190
+ stepBy(event.key === "ArrowUp" ? 1 : -1);
191
+ }
192
+ };
193
+ const stepBy = (direction) => {
194
+ if (props.disabled || props.readonly) return;
195
+ const base = current.value ?? (props.min !== void 0 ? props.min : 0);
196
+ commit(normalize(base + direction * resolvedStep.value));
197
+ };
198
+ const atMax = computed(() => props.max !== void 0 && current.value !== null && current.value >= props.max);
199
+ const atMin = computed(() => props.min !== void 0 && current.value !== null && current.value <= props.min);
200
+ const showControls = computed(() => props.controls && !props.disabled && !props.readonly);
201
+ const controlClasses = computed(() => ["mh-input", "mh-input--number", props.size === "md" ? "" : `mh-input--${props.size}`, borderedClassOf(props.bordered), visualStatus.value ? `is-${visualStatus.value}` : "", props.disabled ? "is-disabled" : ""].filter(Boolean).join(" "));
202
+ const stepButton = (direction) => createVNode("button", {
203
+ "type": "button",
204
+ "class": "mh-input__step-btn",
205
+ "aria-label": direction === 1 ? "增加" : "减少",
206
+ "tabindex": -1,
207
+ "disabled": direction === 1 ? atMax.value : atMin.value,
208
+ "onClick": () => stepBy(direction)
209
+ }, [createVNode(Icon, {
210
+ "name": direction === 1 ? "chevron-up" : "chevron-down"
211
+ }, null)]);
212
+ return () => createVNode("div", {
213
+ "class": ["mh-input__wrap", attrs.class].filter(Boolean).join(" "),
214
+ "style": attrs.style
215
+ }, [slots.prefix ? createVNode("span", {
216
+ "class": "mh-input__prefix"
217
+ }, [slots.prefix()]) : null, createVNode("input", mergeProps(forwardAttrs.value, {
218
+ "ref": inputRef,
219
+ "class": controlClasses.value,
220
+ "type": "text",
221
+ "inputmode": "decimal",
222
+ "value": display.value,
223
+ "placeholder": props.placeholder,
224
+ "disabled": props.disabled,
225
+ "readonly": props.readonly,
226
+ "aria-invalid": isInvalid.value ? "true" : void 0,
227
+ "onInput": onInput,
228
+ "onKeydown": onKeydown,
229
+ "onFocus": onFocus,
230
+ "onBlur": onBlur
231
+ }), null), showControls.value ? createVNode("span", {
232
+ "class": "mh-input__step"
233
+ }, [stepButton(1), stepButton(-1)]) : null, slots.suffix ? createVNode("span", {
234
+ "class": "mh-input__suffix"
235
+ }, [slots.suffix()]) : null]);
236
+ }
237
+ });
238
+ export {
239
+ NumberInput
240
+ };
@@ -136,7 +136,7 @@ export declare const Notice: import("vue").DefineComponent<import("vue").Extract
136
136
  default: undefined;
137
137
  };
138
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" | "info-circle" | "check-circle" | "alert-circle" | "list" | "calendar" | "clock" | "lock" | "unlock" | "users" | "archive" | "package" | "plug" | "branch" | "tag" | "ai" | "shield-check" | "shield-alert" | "history";
139
+ icon: boolean | "search" | "link" | "filter" | "copy" | "help" | "table" | "menu" | "delete" | "image" | "close" | "key" | "application" | "client" | "service" | "schema" | "compose" | "log" | "mcp" | "agent" | "server" | "exposure" | "openapi" | "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" | "page-title" | "favorite-filled" | "drag-handle" | "edit" | "refresh" | "upload" | "save" | "more" | "preview" | "external-link" | "minus" | "plus-circle" | "close-circle" | "info-circle" | "check-circle" | "alert-circle" | "list" | "calendar" | "clock" | "lock" | "unlock" | "users" | "archive" | "package" | "plug" | "branch" | "tag" | "ai" | "shield-check" | "shield-alert" | "history";
140
140
  onClose: () => void;
141
141
  message: string;
142
142
  closable: boolean;
@@ -102,7 +102,7 @@ export declare const Notification: import("vue").DefineComponent<import("vue").E
102
102
  default: undefined;
103
103
  };
104
104
  }>> & Readonly<{}>, {
105
- 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" | "info-circle" | "check-circle" | "alert-circle" | "list" | "calendar" | "clock" | "lock" | "unlock" | "users" | "archive" | "package" | "plug" | "branch" | "tag" | "ai" | "shield-check" | "shield-alert" | "history";
105
+ icon: boolean | "search" | "link" | "filter" | "copy" | "help" | "table" | "menu" | "delete" | "image" | "close" | "key" | "application" | "client" | "service" | "schema" | "compose" | "log" | "mcp" | "agent" | "server" | "exposure" | "openapi" | "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" | "page-title" | "favorite-filled" | "drag-handle" | "edit" | "refresh" | "upload" | "save" | "more" | "preview" | "external-link" | "minus" | "plus-circle" | "close-circle" | "info-circle" | "check-circle" | "alert-circle" | "list" | "calendar" | "clock" | "lock" | "unlock" | "users" | "archive" | "package" | "plug" | "branch" | "tag" | "ai" | "shield-check" | "shield-alert" | "history";
106
106
  title: string;
107
107
  onClose: () => void;
108
108
  closable: boolean;
@@ -132,6 +132,15 @@ export declare const Select: import("vue").DefineComponent<import("vue").Extract
132
132
  type: PropType<InputStatus>;
133
133
  default: undefined;
134
134
  };
135
+ /**
136
+ * 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 完全一致):
137
+ * `true`(缺省)常有框 / `false` 无框(常态、悬停、聚焦都不显)/ `'focus'` 聚焦(与悬停)才显框。
138
+ * 表格单元格里想要「常态像值、点进去才亮框」就用 `'focus'`。
139
+ */
140
+ bordered: {
141
+ type: PropType<boolean | "focus">;
142
+ default: boolean;
143
+ };
135
144
  /** 加载中(面板里出一行提示,不渲染选项) */
136
145
  loading: {
137
146
  type: BooleanConstructor;
@@ -221,6 +230,15 @@ export declare const Select: import("vue").DefineComponent<import("vue").Extract
221
230
  type: PropType<InputStatus>;
222
231
  default: undefined;
223
232
  };
233
+ /**
234
+ * 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 完全一致):
235
+ * `true`(缺省)常有框 / `false` 无框(常态、悬停、聚焦都不显)/ `'focus'` 聚焦(与悬停)才显框。
236
+ * 表格单元格里想要「常态像值、点进去才亮框」就用 `'focus'`。
237
+ */
238
+ bordered: {
239
+ type: PropType<boolean | "focus">;
240
+ default: boolean;
241
+ };
224
242
  /** 加载中(面板里出一行提示,不渲染选项) */
225
243
  loading: {
226
244
  type: BooleanConstructor;
@@ -248,6 +266,7 @@ export declare const Select: import("vue").DefineComponent<import("vue").Extract
248
266
  disabled: boolean;
249
267
  onChange: (v: SelectValue) => void;
250
268
  loading: boolean;
269
+ bordered: boolean | "focus";
251
270
  options: SelectItem[];
252
271
  defaultValue: SelectValue | undefined;
253
272
  placeholder: string;
@@ -74,6 +74,15 @@ const Select = /* @__PURE__ */ defineComponent({
74
74
  type: String,
75
75
  default: void 0
76
76
  },
77
+ /**
78
+ * 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 完全一致):
79
+ * `true`(缺省)常有框 / `false` 无框(常态、悬停、聚焦都不显)/ `'focus'` 聚焦(与悬停)才显框。
80
+ * 表格单元格里想要「常态像值、点进去才亮框」就用 `'focus'`。
81
+ */
82
+ bordered: {
83
+ type: [Boolean, String],
84
+ default: true
85
+ },
77
86
  /** 加载中(面板里出一行提示,不渲染选项) */
78
87
  loading: {
79
88
  type: Boolean,
@@ -239,6 +248,7 @@ const Select = /* @__PURE__ */ defineComponent({
239
248
  "size": props.size,
240
249
  "status": props.status,
241
250
  "disabled": props.disabled,
251
+ "bordered": props.bordered,
242
252
  "clearable": props.clearable,
243
253
  "hasValue": hasValue,
244
254
  "multiple": props.multiple,
@@ -129,6 +129,11 @@ export declare const SelectTree: import("vue").DefineComponent<import("vue").Ext
129
129
  type: PropType<InputStatus>;
130
130
  default: undefined;
131
131
  };
132
+ /** 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 一致) */
133
+ bordered: {
134
+ type: PropType<boolean | "focus">;
135
+ default: boolean;
136
+ };
132
137
  /** 值变更回调(选中叶子的主键) */
133
138
  onChange: {
134
139
  type: PropType<(v: string) => void>;
@@ -248,6 +253,11 @@ export declare const SelectTree: import("vue").DefineComponent<import("vue").Ext
248
253
  type: PropType<InputStatus>;
249
254
  default: undefined;
250
255
  };
256
+ /** 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 一致) */
257
+ bordered: {
258
+ type: PropType<boolean | "focus">;
259
+ default: boolean;
260
+ };
251
261
  /** 值变更回调(选中叶子的主键) */
252
262
  onChange: {
253
263
  type: PropType<(v: string) => void>;
@@ -283,6 +293,7 @@ export declare const SelectTree: import("vue").DefineComponent<import("vue").Ext
283
293
  defaultExpandedKeys: string[];
284
294
  defaultExpandAll: boolean;
285
295
  onExpandChange: (keys: string[]) => void;
296
+ bordered: boolean | "focus";
286
297
  defaultValue: string;
287
298
  placeholder: string;
288
299
  modelValue: string;
@@ -104,6 +104,11 @@ const SelectTree = /* @__PURE__ */ defineComponent({
104
104
  type: String,
105
105
  default: void 0
106
106
  },
107
+ /** 有无边框(框由触发器 `<Input as="button">` 带,三档口径与 `Input` 的同名 prop 一致) */
108
+ bordered: {
109
+ type: [Boolean, String],
110
+ default: true
111
+ },
107
112
  /** 值变更回调(选中叶子的主键) */
108
113
  onChange: {
109
114
  type: Function,
@@ -211,6 +216,7 @@ const SelectTree = /* @__PURE__ */ defineComponent({
211
216
  "size": props.size,
212
217
  "status": props.status,
213
218
  "disabled": props.disabled,
219
+ "bordered": props.bordered,
214
220
  "clearable": props.clearable,
215
221
  "hasValue": hasValue.value,
216
222
  "placeholder": props.placeholder,
@@ -21,6 +21,14 @@ export declare const SelectTrigger: import("vue").DefineComponent<import("vue").
21
21
  type: BooleanConstructor;
22
22
  default: boolean;
23
23
  };
24
+ /**
25
+ * 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):
26
+ * `true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。
27
+ */
28
+ bordered: {
29
+ type: PropType<boolean | "focus">;
30
+ default: boolean;
31
+ };
24
32
  clearable: {
25
33
  type: BooleanConstructor;
26
34
  default: boolean;
@@ -90,6 +98,14 @@ export declare const SelectTrigger: import("vue").DefineComponent<import("vue").
90
98
  type: BooleanConstructor;
91
99
  default: boolean;
92
100
  };
101
+ /**
102
+ * 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):
103
+ * `true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。
104
+ */
105
+ bordered: {
106
+ type: PropType<boolean | "focus">;
107
+ default: boolean;
108
+ };
93
109
  clearable: {
94
110
  type: BooleanConstructor;
95
111
  default: boolean;
@@ -145,6 +161,7 @@ export declare const SelectTrigger: import("vue").DefineComponent<import("vue").
145
161
  disabled: boolean;
146
162
  label: string;
147
163
  onKeydown: (event: KeyboardEvent) => void;
164
+ bordered: boolean | "focus";
148
165
  placeholder: string;
149
166
  status: InputStatus;
150
167
  clearable: boolean;
@@ -24,6 +24,14 @@ const SelectTrigger = /* @__PURE__ */ defineComponent({
24
24
  type: Boolean,
25
25
  default: false
26
26
  },
27
+ /**
28
+ * 有无边框(**直接透传给输入面**,三档口径与 `Input` 的同名 prop 完全一致):
29
+ * `true` 常有框 / `false` 无框(任何状态都不显)/ `'focus'` 聚焦(与悬停)才显框。
30
+ */
31
+ bordered: {
32
+ type: [Boolean, String],
33
+ default: true
34
+ },
27
35
  clearable: {
28
36
  type: Boolean,
29
37
  default: false
@@ -81,6 +89,7 @@ const SelectTrigger = /* @__PURE__ */ defineComponent({
81
89
  "size": props.size,
82
90
  "status": props.status,
83
91
  "disabled": props.disabled,
92
+ "bordered": props.bordered,
84
93
  "clearable": props.clearable,
85
94
  "hasValue": props.hasValue,
86
95
  "placeholder": props.placeholder,