niuma-ui 1.2.9 → 1.3.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/CHANGELOG.md +28 -0
- package/dist/components/RsButton.css +119 -61
- package/dist/components/RsButton.d.ts +3 -3
- package/dist/components/RsButton.impl.js +4 -12
- package/dist/components/RsButton.js +1 -1
- package/dist/components/RsDialog.css +1 -0
- package/dist/components/RsDialog.d.ts +5 -0
- package/dist/components/RsDialog.impl.js +4 -0
- package/dist/components/RsDrawer.css +1 -0
- package/dist/components/RsFieldset.css +92 -0
- package/dist/components/RsFieldset.d.ts +61 -0
- package/dist/components/RsFieldset.impl.js +78 -0
- package/dist/components/RsFieldset.js +8 -0
- package/dist/components/RsFormItem.css +19 -19
- package/dist/components/RsFormItem.d.ts +6 -4
- package/dist/components/RsFormItem.impl.js +12 -2
- package/dist/components/RsFormItem.js +1 -1
- package/dist/components/RsInput.css +78 -69
- package/dist/components/RsInput.js +1 -1
- package/dist/components/RsLog.css +198 -0
- package/dist/components/RsLog.d.ts +126 -0
- package/dist/components/RsLog.impl.js +619 -0
- package/dist/components/RsLog.js +8 -0
- package/dist/components/RsTable.impl.js +2 -1
- package/dist/components/RsTerminal.css +59 -18
- package/dist/components/RsTerminal.d.ts +17 -1
- package/dist/components/RsTerminal.impl.js +115 -8
- package/dist/components/RsTerminal.js +1 -1
- package/dist/components/RsTextarea.css +126 -0
- package/dist/components/RsTextarea.d.ts +114 -0
- package/dist/components/RsTextarea.impl.js +385 -0
- package/dist/components/RsTextarea.js +8 -0
- package/dist/components/RsTooltip.css +4 -3
- package/dist/components/RsTooltip.d.ts +2 -0
- package/dist/components/RsTooltip.impl.js +5 -2
- package/dist/components/RsVirtualList.css +6 -6
- package/dist/components/RsVirtualList.d.ts +1 -1
- package/dist/components/RsVirtualList.impl.js +9 -4
- package/dist/components/RsVirtualList.js +1 -1
- package/dist/components/button-utils.d.ts +19 -10
- package/dist/components/button-utils.js +22 -7
- package/dist/components/dialog-window.d.ts +2 -0
- package/dist/components/dialog-window.js +2 -1
- package/dist/components/fieldset-utils.d.ts +29 -0
- package/dist/components/fieldset-utils.js +12 -0
- package/dist/components/log-utils.d.ts +105 -0
- package/dist/components/log-utils.js +354 -0
- package/dist/components/table/rs-table-props.d.ts +8 -0
- package/dist/components/table/rs-table-props.js +1 -0
- package/dist/components/table/rs-table.css +7 -0
- package/dist/components/terminal-utils.d.ts +1 -1
- package/dist/dev/vite-xterm-deps.d.ts +1 -0
- package/dist/dev/vite-xterm-deps.js +1 -0
- package/dist/index.d.ts +10 -2
- package/dist/index.js +24 -0
- package/dist/locale/messages.js +52 -0
- package/dist/styles.css +37 -0
- package/package.json +2 -1
|
@@ -0,0 +1,385 @@
|
|
|
1
|
+
import { useRsI18n } from "../composables/useRsI18n.js";
|
|
2
|
+
import RsIcon_default from "./RsIcon.js";
|
|
3
|
+
import { buildLocalInputRules, runFormFieldRules } from "./form-rules.js";
|
|
4
|
+
import { isRsFormItemBoundControl, useRsFormContext, useRsFormField, useRsFormItemContext } from "./form-utils.js";
|
|
5
|
+
import { useResolvedRsComponentSize } from "./resolve-size.js";
|
|
6
|
+
import { rsRadiusCss, useResolvedRsRadius } from "./resolve-radius.js";
|
|
7
|
+
import { computed, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, mergeModels, mergeProps, nextTick, normalizeClass, normalizeStyle, onMounted, openBlock, ref, renderSlot, toDisplayString, unref, useAttrs, useId, useModel, watch, withModifiers } from "vue";
|
|
8
|
+
//#region src/components/RsTextarea.vue?vue&type=script&setup=true&lang.ts
|
|
9
|
+
var _hoisted_1 = {
|
|
10
|
+
key: 0,
|
|
11
|
+
class: "rs-field__label"
|
|
12
|
+
};
|
|
13
|
+
var _hoisted_2 = ["for"];
|
|
14
|
+
var _hoisted_3 = {
|
|
15
|
+
key: 0,
|
|
16
|
+
class: "rs-field__required",
|
|
17
|
+
"aria-hidden": "true"
|
|
18
|
+
};
|
|
19
|
+
var _hoisted_4 = { class: "rs-textarea" };
|
|
20
|
+
var _hoisted_5 = [
|
|
21
|
+
"id",
|
|
22
|
+
"value",
|
|
23
|
+
"rows",
|
|
24
|
+
"placeholder",
|
|
25
|
+
"disabled",
|
|
26
|
+
"readonly",
|
|
27
|
+
"minlength",
|
|
28
|
+
"maxlength",
|
|
29
|
+
"aria-invalid",
|
|
30
|
+
"aria-describedby"
|
|
31
|
+
];
|
|
32
|
+
var _hoisted_6 = ["aria-label"];
|
|
33
|
+
var _hoisted_7 = ["id"];
|
|
34
|
+
var _hoisted_8 = {
|
|
35
|
+
key: 1,
|
|
36
|
+
class: "rs-field__hint"
|
|
37
|
+
};
|
|
38
|
+
var RsTextarea_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ defineComponent({
|
|
39
|
+
inheritAttrs: false,
|
|
40
|
+
__name: "RsTextarea",
|
|
41
|
+
props: /*@__PURE__*/ mergeModels({
|
|
42
|
+
id: {},
|
|
43
|
+
placeholder: {},
|
|
44
|
+
disabled: {
|
|
45
|
+
type: Boolean,
|
|
46
|
+
default: false
|
|
47
|
+
},
|
|
48
|
+
readonly: {
|
|
49
|
+
type: Boolean,
|
|
50
|
+
default: false
|
|
51
|
+
},
|
|
52
|
+
invalid: {
|
|
53
|
+
type: Boolean,
|
|
54
|
+
default: false
|
|
55
|
+
},
|
|
56
|
+
errorMessage: {},
|
|
57
|
+
size: {},
|
|
58
|
+
radius: {},
|
|
59
|
+
rows: { default: 3 },
|
|
60
|
+
resize: { default: "vertical" },
|
|
61
|
+
autosize: {
|
|
62
|
+
type: [Boolean, Object],
|
|
63
|
+
default: false
|
|
64
|
+
},
|
|
65
|
+
rule: {},
|
|
66
|
+
validator: {},
|
|
67
|
+
required: {
|
|
68
|
+
type: Boolean,
|
|
69
|
+
default: false
|
|
70
|
+
},
|
|
71
|
+
validateTrigger: { default: "blur" },
|
|
72
|
+
name: {},
|
|
73
|
+
minlength: {},
|
|
74
|
+
maxlength: {},
|
|
75
|
+
showCount: {
|
|
76
|
+
type: Boolean,
|
|
77
|
+
default: false
|
|
78
|
+
},
|
|
79
|
+
clearable: {
|
|
80
|
+
type: Boolean,
|
|
81
|
+
default: false
|
|
82
|
+
},
|
|
83
|
+
showValidateMessage: {
|
|
84
|
+
type: Boolean,
|
|
85
|
+
default: true
|
|
86
|
+
},
|
|
87
|
+
label: {},
|
|
88
|
+
hint: {},
|
|
89
|
+
labelPosition: {}
|
|
90
|
+
}, {
|
|
91
|
+
"modelValue": { default: "" },
|
|
92
|
+
"modelModifiers": {}
|
|
93
|
+
}),
|
|
94
|
+
emits: /*@__PURE__*/ mergeModels([
|
|
95
|
+
"validate",
|
|
96
|
+
"blur",
|
|
97
|
+
"focus",
|
|
98
|
+
"pressEnter",
|
|
99
|
+
"clear"
|
|
100
|
+
], ["update:modelValue"]),
|
|
101
|
+
setup(__props, { expose: __expose, emit: __emit }) {
|
|
102
|
+
const { t } = useRsI18n();
|
|
103
|
+
const model = useModel(__props, "modelValue", {
|
|
104
|
+
get(value) {
|
|
105
|
+
return value == null ? "" : String(value);
|
|
106
|
+
},
|
|
107
|
+
set(value) {
|
|
108
|
+
return value == null ? "" : String(value);
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
const props = __props;
|
|
112
|
+
const emit = __emit;
|
|
113
|
+
const attrs = useAttrs();
|
|
114
|
+
const formContext = useRsFormContext();
|
|
115
|
+
const formItem = useRsFormItemContext();
|
|
116
|
+
const boundToItem = computed(() => isRsFormItemBoundControl(formItem, {
|
|
117
|
+
id: props.id,
|
|
118
|
+
name: props.name
|
|
119
|
+
}));
|
|
120
|
+
const fieldId = useId();
|
|
121
|
+
const textareaRef = ref(null);
|
|
122
|
+
const touched = ref(false);
|
|
123
|
+
const autoInvalid = ref(false);
|
|
124
|
+
const autoMessage = ref("");
|
|
125
|
+
const composing = ref(false);
|
|
126
|
+
const resolvedId = computed(() => props.id ?? fieldId);
|
|
127
|
+
const resolvedLabelPosition = computed(() => props.labelPosition ?? formContext?.labelPosition.value ?? "top");
|
|
128
|
+
const resolvedLabelAlign = computed(() => formContext?.labelAlign.value ?? "start");
|
|
129
|
+
const errorId = computed(() => `${resolvedId.value}-error`);
|
|
130
|
+
const displayMessage = computed(() => {
|
|
131
|
+
if (boundToItem.value) return "";
|
|
132
|
+
if (props.errorMessage) return props.errorMessage;
|
|
133
|
+
if (props.showValidateMessage && autoInvalid.value) return autoMessage.value;
|
|
134
|
+
return "";
|
|
135
|
+
});
|
|
136
|
+
const isInvalid = computed(() => {
|
|
137
|
+
if (boundToItem.value) return Boolean(formItem?.invalid.value || props.invalid);
|
|
138
|
+
return props.invalid || autoInvalid.value;
|
|
139
|
+
});
|
|
140
|
+
const describedBy = computed(() => {
|
|
141
|
+
if (boundToItem.value) return formItem?.describedBy.value;
|
|
142
|
+
return displayMessage.value ? errorId.value : void 0;
|
|
143
|
+
});
|
|
144
|
+
const resolvedDisabled = computed(() => props.disabled || formContext?.disabled.value || false);
|
|
145
|
+
const resolvedSize = useResolvedRsComponentSize(() => props.size);
|
|
146
|
+
const resolvedRadius = useResolvedRsRadius(() => props.radius, "sm");
|
|
147
|
+
const radiusStyle = computed(() => ({ "--rs-input-radius": rsRadiusCss(resolvedRadius.value) }));
|
|
148
|
+
const fieldStyle = computed(() => {
|
|
149
|
+
if (resolvedLabelPosition.value !== "left") return void 0;
|
|
150
|
+
const labelWidth = formContext?.labelWidth.value;
|
|
151
|
+
if (!labelWidth) return void 0;
|
|
152
|
+
return { "--rs-field-label-width": labelWidth };
|
|
153
|
+
});
|
|
154
|
+
const autosizeEnabled = computed(() => Boolean(props.autosize));
|
|
155
|
+
const autosizeSpec = computed(() => typeof props.autosize === "object" && props.autosize ? props.autosize : {});
|
|
156
|
+
const displayRows = computed(() => autosizeSpec.value.minRows ?? props.rows);
|
|
157
|
+
const resolvedResize = computed(() => autosizeEnabled.value ? "none" : props.resize);
|
|
158
|
+
const countText = computed(() => {
|
|
159
|
+
const n = model.value.length;
|
|
160
|
+
return props.maxlength != null ? `${n} / ${props.maxlength}` : String(n);
|
|
161
|
+
});
|
|
162
|
+
const countLimitReached = computed(() => props.maxlength != null && model.value.length >= props.maxlength);
|
|
163
|
+
const showClearButton = computed(() => props.clearable && !resolvedDisabled.value && !props.readonly && model.value.length > 0);
|
|
164
|
+
function parseLineHeight(el) {
|
|
165
|
+
const style = getComputedStyle(el);
|
|
166
|
+
const lh = Number.parseFloat(style.lineHeight);
|
|
167
|
+
if (Number.isFinite(lh) && lh > 0) return lh;
|
|
168
|
+
return (Number.parseFloat(style.fontSize) || 14) * 1.5;
|
|
169
|
+
}
|
|
170
|
+
function autosizePadding(el) {
|
|
171
|
+
const style = getComputedStyle(el);
|
|
172
|
+
const pad = Number.parseFloat(style.paddingTop) + Number.parseFloat(style.paddingBottom);
|
|
173
|
+
if (style.boxSizing !== "border-box") return 0;
|
|
174
|
+
const border = Number.parseFloat(style.borderTopWidth) + Number.parseFloat(style.borderBottomWidth);
|
|
175
|
+
return (Number.isFinite(pad) ? pad : 0) + (Number.isFinite(border) ? border : 0);
|
|
176
|
+
}
|
|
177
|
+
function adjustHeight() {
|
|
178
|
+
const el = textareaRef.value;
|
|
179
|
+
if (!el) return;
|
|
180
|
+
if (!autosizeEnabled.value) {
|
|
181
|
+
el.style.height = "";
|
|
182
|
+
el.style.overflowY = "";
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
el.style.height = "auto";
|
|
186
|
+
el.style.overflowY = "hidden";
|
|
187
|
+
const lineHeight = parseLineHeight(el);
|
|
188
|
+
const extra = autosizePadding(el);
|
|
189
|
+
const minRows = autosizeSpec.value.minRows ?? props.rows;
|
|
190
|
+
const maxRows = autosizeSpec.value.maxRows;
|
|
191
|
+
const min = lineHeight * minRows + extra;
|
|
192
|
+
const max = maxRows != null ? lineHeight * maxRows + extra : void 0;
|
|
193
|
+
let height = el.scrollHeight;
|
|
194
|
+
if (height < min) height = min;
|
|
195
|
+
if (max != null && height > max) {
|
|
196
|
+
height = max;
|
|
197
|
+
el.style.overflowY = "auto";
|
|
198
|
+
}
|
|
199
|
+
el.style.height = `${height}px`;
|
|
200
|
+
}
|
|
201
|
+
function scheduleAdjustHeight() {
|
|
202
|
+
nextTick(adjustHeight);
|
|
203
|
+
}
|
|
204
|
+
async function runValidate(trigger = "submit") {
|
|
205
|
+
const formRules = formContext?.getFieldRules(props.name) ?? [];
|
|
206
|
+
const localRules = buildLocalInputRules({
|
|
207
|
+
required: props.required,
|
|
208
|
+
rule: props.rule,
|
|
209
|
+
validator: props.validator
|
|
210
|
+
});
|
|
211
|
+
const rules = [...formRules, ...localRules];
|
|
212
|
+
if (!rules.length) {
|
|
213
|
+
autoInvalid.value = false;
|
|
214
|
+
autoMessage.value = "";
|
|
215
|
+
emit("validate", { valid: true });
|
|
216
|
+
return true;
|
|
217
|
+
}
|
|
218
|
+
const result = await runFormFieldRules(model.value, rules, {
|
|
219
|
+
trigger,
|
|
220
|
+
t
|
|
221
|
+
});
|
|
222
|
+
autoInvalid.value = !result.valid;
|
|
223
|
+
autoMessage.value = result.message ?? "";
|
|
224
|
+
emit("validate", result);
|
|
225
|
+
return result.valid;
|
|
226
|
+
}
|
|
227
|
+
function setError(message) {
|
|
228
|
+
autoInvalid.value = true;
|
|
229
|
+
autoMessage.value = message;
|
|
230
|
+
}
|
|
231
|
+
function setValue(value) {
|
|
232
|
+
model.value = String(value ?? "");
|
|
233
|
+
scheduleAdjustHeight();
|
|
234
|
+
}
|
|
235
|
+
function clearValidation() {
|
|
236
|
+
touched.value = false;
|
|
237
|
+
autoInvalid.value = false;
|
|
238
|
+
autoMessage.value = "";
|
|
239
|
+
}
|
|
240
|
+
function focus() {
|
|
241
|
+
textareaRef.value?.focus();
|
|
242
|
+
}
|
|
243
|
+
function blur() {
|
|
244
|
+
textareaRef.value?.blur();
|
|
245
|
+
}
|
|
246
|
+
function onNativeInput(event) {
|
|
247
|
+
const el = event.target;
|
|
248
|
+
model.value = el?.value ?? "";
|
|
249
|
+
scheduleAdjustHeight();
|
|
250
|
+
if (composing.value) return;
|
|
251
|
+
if (touched.value && (props.validateTrigger === "input" || props.validateTrigger === "both")) runValidate("change");
|
|
252
|
+
}
|
|
253
|
+
function onCompositionStart() {
|
|
254
|
+
composing.value = true;
|
|
255
|
+
}
|
|
256
|
+
function onCompositionEnd(event) {
|
|
257
|
+
composing.value = false;
|
|
258
|
+
onNativeInput(event);
|
|
259
|
+
}
|
|
260
|
+
function onBlur(event) {
|
|
261
|
+
touched.value = true;
|
|
262
|
+
if (props.validateTrigger === "blur" || props.validateTrigger === "both") runValidate("blur");
|
|
263
|
+
emit("blur", event);
|
|
264
|
+
}
|
|
265
|
+
function onKeydown(event) {
|
|
266
|
+
if (event.key !== "Enter" || composing.value) return;
|
|
267
|
+
emit("pressEnter", event);
|
|
268
|
+
}
|
|
269
|
+
function onClear() {
|
|
270
|
+
if (resolvedDisabled.value || props.readonly) return;
|
|
271
|
+
model.value = "";
|
|
272
|
+
emit("clear");
|
|
273
|
+
nextTick(() => {
|
|
274
|
+
textareaRef.value?.focus();
|
|
275
|
+
adjustHeight();
|
|
276
|
+
if (props.validateTrigger === "input" || props.validateTrigger === "both") runValidate("change");
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
watch([
|
|
280
|
+
model,
|
|
281
|
+
() => props.autosize,
|
|
282
|
+
() => props.rows,
|
|
283
|
+
() => props.size,
|
|
284
|
+
() => props.showCount
|
|
285
|
+
], scheduleAdjustHeight);
|
|
286
|
+
onMounted(adjustHeight);
|
|
287
|
+
useRsFormField(() => ({
|
|
288
|
+
get name() {
|
|
289
|
+
return props.name;
|
|
290
|
+
},
|
|
291
|
+
getValue: () => model.value,
|
|
292
|
+
setValue,
|
|
293
|
+
validate: async (trigger) => {
|
|
294
|
+
return {
|
|
295
|
+
valid: await runValidate(trigger ?? "submit"),
|
|
296
|
+
message: autoMessage.value || void 0,
|
|
297
|
+
name: props.name
|
|
298
|
+
};
|
|
299
|
+
},
|
|
300
|
+
clearValidation,
|
|
301
|
+
setError
|
|
302
|
+
}));
|
|
303
|
+
__expose({
|
|
304
|
+
validate: runValidate,
|
|
305
|
+
clearValidation,
|
|
306
|
+
setValue,
|
|
307
|
+
setError,
|
|
308
|
+
focus,
|
|
309
|
+
blur
|
|
310
|
+
});
|
|
311
|
+
return (_ctx, _cache) => {
|
|
312
|
+
return openBlock(), createElementBlock("div", {
|
|
313
|
+
class: normalizeClass(["rs-field", [
|
|
314
|
+
`rs-field--label-${resolvedLabelPosition.value}`,
|
|
315
|
+
resolvedLabelPosition.value === "left" && resolvedLabelAlign.value === "end" ? "rs-field--label-align-end" : void 0,
|
|
316
|
+
`rs-input-field--${unref(resolvedSize)}`
|
|
317
|
+
]]),
|
|
318
|
+
style: normalizeStyle([fieldStyle.value, radiusStyle.value])
|
|
319
|
+
}, [__props.label ? (openBlock(), createElementBlock("span", _hoisted_1, [createElementVNode("label", { for: resolvedId.value }, toDisplayString(__props.label), 9, _hoisted_2), __props.required ? (openBlock(), createElementBlock("span", _hoisted_3, "*")) : createCommentVNode("", true)])) : createCommentVNode("", true), createElementVNode("div", _hoisted_4, [
|
|
320
|
+
createElementVNode("div", { class: normalizeClass(["rs-textarea__shell", {
|
|
321
|
+
"is-invalid": isInvalid.value,
|
|
322
|
+
"is-disabled": resolvedDisabled.value,
|
|
323
|
+
"is-readonly": __props.readonly,
|
|
324
|
+
"is-autosize": autosizeEnabled.value,
|
|
325
|
+
"has-count": __props.showCount,
|
|
326
|
+
"has-clear": showClearButton.value
|
|
327
|
+
}]) }, [
|
|
328
|
+
createElementVNode("textarea", mergeProps({
|
|
329
|
+
ref_key: "textareaRef",
|
|
330
|
+
ref: textareaRef
|
|
331
|
+
}, unref(attrs), {
|
|
332
|
+
id: resolvedId.value,
|
|
333
|
+
value: model.value,
|
|
334
|
+
class: "rs-textarea__control",
|
|
335
|
+
rows: displayRows.value,
|
|
336
|
+
style: { resize: resolvedResize.value },
|
|
337
|
+
placeholder: __props.placeholder,
|
|
338
|
+
disabled: resolvedDisabled.value,
|
|
339
|
+
readonly: __props.readonly,
|
|
340
|
+
minlength: __props.minlength,
|
|
341
|
+
maxlength: __props.maxlength,
|
|
342
|
+
"aria-invalid": isInvalid.value || void 0,
|
|
343
|
+
"aria-describedby": describedBy.value,
|
|
344
|
+
onInput: onNativeInput,
|
|
345
|
+
onCompositionstart: onCompositionStart,
|
|
346
|
+
onCompositionend: onCompositionEnd,
|
|
347
|
+
onKeydown,
|
|
348
|
+
onBlur,
|
|
349
|
+
onFocus: _cache[0] || (_cache[0] = ($event) => emit("focus", $event))
|
|
350
|
+
}), null, 16, _hoisted_5),
|
|
351
|
+
showClearButton.value ? (openBlock(), createElementBlock("button", {
|
|
352
|
+
key: 0,
|
|
353
|
+
type: "button",
|
|
354
|
+
class: "rs-textarea__clear",
|
|
355
|
+
tabindex: "-1",
|
|
356
|
+
"aria-label": unref(t)("input.clear"),
|
|
357
|
+
onPointerdown: _cache[1] || (_cache[1] = withModifiers(() => {}, ["prevent"])),
|
|
358
|
+
onClick: onClear
|
|
359
|
+
}, [createVNode(RsIcon_default, {
|
|
360
|
+
name: "x",
|
|
361
|
+
size: 14
|
|
362
|
+
})], 40, _hoisted_6)) : createCommentVNode("", true),
|
|
363
|
+
__props.showCount ? (openBlock(), createElementBlock("span", {
|
|
364
|
+
key: 1,
|
|
365
|
+
class: normalizeClass(["rs-textarea__count", { "is-limit": countLimitReached.value }]),
|
|
366
|
+
"aria-hidden": "true"
|
|
367
|
+
}, [renderSlot(_ctx.$slots, "count", {
|
|
368
|
+
value: model.value,
|
|
369
|
+
count: model.value.length,
|
|
370
|
+
maxlength: __props.maxlength
|
|
371
|
+
}, () => [createTextVNode(toDisplayString(countText.value), 1)], true)], 2)) : createCommentVNode("", true)
|
|
372
|
+
], 2),
|
|
373
|
+
displayMessage.value ? (openBlock(), createElementBlock("p", {
|
|
374
|
+
key: 0,
|
|
375
|
+
id: errorId.value,
|
|
376
|
+
class: "rs-field__error",
|
|
377
|
+
role: "alert"
|
|
378
|
+
}, [renderSlot(_ctx.$slots, "error", { message: displayMessage.value }, () => [createTextVNode(toDisplayString(displayMessage.value), 1)], true)], 8, _hoisted_7)) : createCommentVNode("", true),
|
|
379
|
+
__props.hint ? (openBlock(), createElementBlock("span", _hoisted_8, toDisplayString(__props.hint), 1)) : createCommentVNode("", true)
|
|
380
|
+
])], 6);
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
});
|
|
384
|
+
//#endregion
|
|
385
|
+
export { RsTextarea_vue_vue_type_script_setup_true_lang_default as default };
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import './RsTextarea.css'
|
|
2
|
+
import _plugin_vue_export_helper_default from "../_virtual/_plugin-vue_export-helper.js";
|
|
3
|
+
import RsTextarea_vue_vue_type_script_setup_true_lang_default from "./RsTextarea.impl.js";
|
|
4
|
+
|
|
5
|
+
//#region src/components/RsTextarea.vue
|
|
6
|
+
var RsTextarea_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsTextarea_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-f75ef1a0"]]);
|
|
7
|
+
//#endregion
|
|
8
|
+
export { RsTextarea_default as default };
|
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
|
|
2
2
|
.rs-tooltip__with-icon {
|
|
3
3
|
display: inline-flex;
|
|
4
|
+
flex-wrap: nowrap;
|
|
4
5
|
align-items: center;
|
|
5
6
|
gap: 0.25rem;
|
|
7
|
+
width: max-content;
|
|
6
8
|
max-width: 100%;
|
|
7
|
-
vertical-align:
|
|
9
|
+
vertical-align: middle;
|
|
8
10
|
}
|
|
9
11
|
.rs-tooltip__label {
|
|
10
|
-
display: inline
|
|
12
|
+
display: inline;
|
|
11
13
|
min-width: 0;
|
|
12
|
-
max-width: 100%;
|
|
13
14
|
}
|
|
14
15
|
.rs-tooltip__icon-trigger {
|
|
15
16
|
display: inline-flex;
|
|
@@ -18,6 +18,8 @@ type __VLS_Props = {
|
|
|
18
18
|
icon?: boolean;
|
|
19
19
|
/** 后缀图标名,默认 info(问号/说明圆标;对齐表单帮助惯用) */
|
|
20
20
|
iconName?: string;
|
|
21
|
+
/** 帮助图标的无障碍名称;缺省用 content,再回退 locale `tooltip.help` */
|
|
22
|
+
ariaLabel?: string;
|
|
21
23
|
};
|
|
22
24
|
declare var __VLS_8: {}, __VLS_27: {}, __VLS_41: {};
|
|
23
25
|
type __VLS_Slots = {} & {
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { useRsI18n } from "../composables/useRsI18n.js";
|
|
1
2
|
import RsIcon_default from "./RsIcon.js";
|
|
2
3
|
import { TooltipContent, TooltipPortal, TooltipRoot, TooltipTrigger } from "./reka.js";
|
|
3
4
|
import { computed, createBlock, createCommentVNode, createElementBlock, createElementVNode, createTextVNode, createVNode, defineComponent, normalizeClass, openBlock, renderSlot, toDisplayString, unref, useSlots, withCtx } from "vue";
|
|
@@ -34,13 +35,15 @@ var RsTooltip_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ define
|
|
|
34
35
|
type: Boolean,
|
|
35
36
|
default: false
|
|
36
37
|
},
|
|
37
|
-
iconName: { default: "info" }
|
|
38
|
+
iconName: { default: "info" },
|
|
39
|
+
ariaLabel: {}
|
|
38
40
|
},
|
|
39
41
|
setup(__props) {
|
|
40
42
|
const props = __props;
|
|
41
43
|
const slots = useSlots();
|
|
44
|
+
const { t } = useRsI18n();
|
|
42
45
|
const hasLabelSlot = computed(() => Boolean(slots.default));
|
|
43
|
-
const iconAriaLabel = computed(() => props.content?.trim() || "Help");
|
|
46
|
+
const iconAriaLabel = computed(() => props.ariaLabel?.trim() || props.content?.trim() || t("tooltip.help", "Help"));
|
|
44
47
|
return (_ctx, _cache) => {
|
|
45
48
|
return openBlock(), createBlock(unref(TooltipRoot), {
|
|
46
49
|
disabled: __props.disabled,
|
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
|
|
2
|
-
.rs-virtual-list[data-v-
|
|
2
|
+
.rs-virtual-list[data-v-808bf3fd] {
|
|
3
3
|
overflow: auto;
|
|
4
4
|
border: 1px solid var(--rs-border-subtle);
|
|
5
5
|
border-radius: var(--rs-virtual-list-radius, var(--rs-radius-sm));
|
|
6
6
|
}
|
|
7
|
-
.rs-virtual-list--fill[data-v-
|
|
7
|
+
.rs-virtual-list--fill[data-v-808bf3fd] {
|
|
8
8
|
flex: 1;
|
|
9
9
|
align-self: stretch;
|
|
10
10
|
width: 100%;
|
|
11
11
|
min-height: 0;
|
|
12
12
|
height: 0;
|
|
13
13
|
}
|
|
14
|
-
.rs-virtual-list__spacer[data-v-
|
|
14
|
+
.rs-virtual-list__spacer[data-v-808bf3fd] {
|
|
15
15
|
position: relative;
|
|
16
16
|
}
|
|
17
|
-
.rs-virtual-list__items[data-v-
|
|
17
|
+
.rs-virtual-list__items[data-v-808bf3fd] {
|
|
18
18
|
position: absolute;
|
|
19
19
|
left: 0;
|
|
20
20
|
right: 0;
|
|
21
21
|
top: 0;
|
|
22
22
|
}
|
|
23
|
-
.rs-virtual-list__item[data-v-
|
|
23
|
+
.rs-virtual-list__item[data-v-808bf3fd] {
|
|
24
24
|
box-sizing: border-box;
|
|
25
25
|
}
|
|
26
|
-
.rs-virtual-list__item--active[data-v-
|
|
26
|
+
.rs-virtual-list__item--active[data-v-808bf3fd] {
|
|
27
27
|
background: color-mix(in srgb, var(--rs-primary) 14%, var(--rs-surface));
|
|
28
28
|
box-shadow: inset 2px 0 0 var(--rs-primary);
|
|
29
29
|
}
|
|
@@ -15,7 +15,7 @@ declare const __VLS_export: <T>(__VLS_props: NonNullable<Awaited<typeof __VLS_se
|
|
|
15
15
|
__VLS_PROPS_FALLBACK: infer P;
|
|
16
16
|
} ? P : {});
|
|
17
17
|
expose: (exposed: import("vue").ShallowUnwrapRef<{
|
|
18
|
-
scrollToIndex: (index: number) => void;
|
|
18
|
+
scrollToIndex: (index: number, align?: "nearest" | "center" | "start" | "end") => void;
|
|
19
19
|
}>) => void;
|
|
20
20
|
attrs: any;
|
|
21
21
|
slots: {
|
|
@@ -89,17 +89,22 @@ var RsVirtualList_vue_vue_type_script_setup_true_lang_default = /*@__PURE__*/ de
|
|
|
89
89
|
})));
|
|
90
90
|
const totalHeight = computed(() => props.items.length * fixedItemSize.value);
|
|
91
91
|
const offsetY = computed(() => startIndex.value * fixedItemSize.value);
|
|
92
|
-
function scrollToIndex(index) {
|
|
92
|
+
function scrollToIndex(index, align = "center") {
|
|
93
93
|
const el = rootRef.value;
|
|
94
94
|
if (!el || index < 0 || index >= props.items.length) return;
|
|
95
95
|
const itemTop = index * fixedItemSize.value;
|
|
96
96
|
const itemBottom = itemTop + fixedItemSize.value;
|
|
97
97
|
const viewTop = el.scrollTop;
|
|
98
98
|
const viewBottom = viewTop + el.clientHeight;
|
|
99
|
-
if (itemTop >= viewTop && itemBottom <= viewBottom) return;
|
|
99
|
+
if (align === "nearest" && itemTop >= viewTop && itemBottom <= viewBottom) return;
|
|
100
100
|
const maxScroll = Math.max(0, totalHeight.value - el.clientHeight);
|
|
101
|
-
|
|
102
|
-
|
|
101
|
+
let next = itemTop - (el.clientHeight - fixedItemSize.value) / 2;
|
|
102
|
+
if (align === "start") next = itemTop;
|
|
103
|
+
if (align === "end") next = itemBottom - el.clientHeight;
|
|
104
|
+
if (align === "nearest") if (itemTop < viewTop) next = itemTop;
|
|
105
|
+
else if (itemBottom > viewBottom) next = itemBottom - el.clientHeight;
|
|
106
|
+
else return;
|
|
107
|
+
el.scrollTop = Math.min(maxScroll, Math.max(0, next));
|
|
103
108
|
scrollTop.value = el.scrollTop;
|
|
104
109
|
}
|
|
105
110
|
watch(() => [props.activeIndex, props.items.length], async ([index, length]) => {
|
|
@@ -3,6 +3,6 @@ import _plugin_vue_export_helper_default from "../_virtual/_plugin-vue_export-he
|
|
|
3
3
|
import RsVirtualList_vue_vue_type_script_setup_true_lang_default from "./RsVirtualList.impl.js";
|
|
4
4
|
|
|
5
5
|
//#region src/components/RsVirtualList.vue
|
|
6
|
-
var RsVirtualList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsVirtualList_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-
|
|
6
|
+
var RsVirtualList_default = /*#__PURE__*/ _plugin_vue_export_helper_default(RsVirtualList_vue_vue_type_script_setup_true_lang_default, [["__scopeId", "data-v-808bf3fd"]]);
|
|
7
7
|
//#endregion
|
|
8
8
|
export { RsVirtualList_default as default };
|
|
@@ -1,17 +1,26 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* RsButton
|
|
3
|
-
* - primary
|
|
4
|
-
* -
|
|
5
|
-
* -
|
|
2
|
+
* RsButton 外观变体(形态,与 tone 正交)
|
|
3
|
+
* - primary:实心
|
|
4
|
+
* - default / secondary:轮廓 + 浅底(secondary 等价 default)
|
|
5
|
+
* - ghost:透明底 + 描边
|
|
6
|
+
* - text:无底无边
|
|
7
|
+
* - link:行内链接
|
|
8
|
+
* - danger:兼容别名,等价 primary + tone="danger" 的历史实心底(保留独立样式)
|
|
6
9
|
*/
|
|
7
10
|
export type RsButtonVariant = 'primary' | 'default' | 'secondary' | 'ghost' | 'danger' | 'link' | 'text';
|
|
8
11
|
/**
|
|
9
|
-
* RsButton
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
+
* RsButton 语义色(色相,与 variant 正交)
|
|
13
|
+
* 对齐 Ant Design color / Element Plus type / Naive UI type:
|
|
14
|
+
* `variant="default" tone="warning"` → 描边 + 浅底 + 警告色。
|
|
12
15
|
*/
|
|
13
16
|
export type RsButtonTone = 'neutral' | 'primary' | 'danger' | 'success' | 'warning' | 'info';
|
|
14
|
-
/**
|
|
17
|
+
/** 规范化变体:未传为 primary;secondary 视为 default。 */
|
|
18
|
+
export declare function resolveRsButtonVariant(variant?: RsButtonVariant): Exclude<RsButtonVariant, 'secondary'>;
|
|
19
|
+
/**
|
|
20
|
+
* 解析语义色。未传 tone 时:primary/link 用 primary,danger 变体用 danger,其余 neutral。
|
|
21
|
+
*/
|
|
22
|
+
export declare function resolveRsButtonTone(variant?: RsButtonVariant, tone?: RsButtonTone): RsButtonTone;
|
|
23
|
+
/** 实心/轮廓填充类变体(相对 text / ghost / link)。 */
|
|
15
24
|
export declare function isRsButtonFilledVariant(variant: RsButtonVariant): boolean;
|
|
16
|
-
/**
|
|
17
|
-
export declare function supportsRsButtonTone(
|
|
25
|
+
/** 所有变体都可叠加 tone(形态 × 色相)。 */
|
|
26
|
+
export declare function supportsRsButtonTone(_variant?: RsButtonVariant): boolean;
|
|
@@ -1,13 +1,28 @@
|
|
|
1
1
|
//#region src/components/button-utils.ts
|
|
2
|
-
/**
|
|
2
|
+
/** 规范化变体:未传为 primary;secondary 视为 default。 */
|
|
3
|
+
function resolveRsButtonVariant(variant) {
|
|
4
|
+
if (variant === "secondary") return "default";
|
|
5
|
+
if (!variant) return "primary";
|
|
6
|
+
return variant;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* 解析语义色。未传 tone 时:primary/link 用 primary,danger 变体用 danger,其余 neutral。
|
|
10
|
+
*/
|
|
11
|
+
function resolveRsButtonTone(variant, tone) {
|
|
12
|
+
if (tone) return tone;
|
|
13
|
+
const resolved = resolveRsButtonVariant(variant);
|
|
14
|
+
if (resolved === "danger") return "danger";
|
|
15
|
+
if (resolved === "primary" || resolved === "link") return "primary";
|
|
16
|
+
return "neutral";
|
|
17
|
+
}
|
|
18
|
+
/** 实心/轮廓填充类变体(相对 text / ghost / link)。 */
|
|
3
19
|
function isRsButtonFilledVariant(variant) {
|
|
4
|
-
const resolved = variant
|
|
20
|
+
const resolved = resolveRsButtonVariant(variant);
|
|
5
21
|
return resolved === "primary" || resolved === "default" || resolved === "danger";
|
|
6
22
|
}
|
|
7
|
-
/**
|
|
8
|
-
function supportsRsButtonTone(
|
|
9
|
-
|
|
10
|
-
return resolved === "text" || resolved === "ghost" || resolved === "link";
|
|
23
|
+
/** 所有变体都可叠加 tone(形态 × 色相)。 */
|
|
24
|
+
function supportsRsButtonTone(_variant) {
|
|
25
|
+
return true;
|
|
11
26
|
}
|
|
12
27
|
//#endregion
|
|
13
|
-
export { isRsButtonFilledVariant, supportsRsButtonTone };
|
|
28
|
+
export { isRsButtonFilledVariant, resolveRsButtonTone, resolveRsButtonVariant, supportsRsButtonTone };
|
|
@@ -14,6 +14,8 @@ export declare function useRsDialogWindow(options: {
|
|
|
14
14
|
widthPreset: Ref<RsDialogWidthPreset>;
|
|
15
15
|
/** 自定义初始宽度(px);有值时优先于预设/比例 */
|
|
16
16
|
initialWidth?: Ref<number | undefined>;
|
|
17
|
+
/** 自定义初始高度(px);有值时优先于默认 75% 视口高 */
|
|
18
|
+
initialHeight?: Ref<number | undefined>;
|
|
17
19
|
draggable: Ref<boolean>;
|
|
18
20
|
resizable: Ref<boolean>;
|
|
19
21
|
compact?: Ref<boolean>;
|
|
@@ -62,9 +62,10 @@ function useRsDialogWindow(options) {
|
|
|
62
62
|
function defaultWindowSize() {
|
|
63
63
|
const { width: maxW, height: maxH } = dialogViewportSize();
|
|
64
64
|
const customW = options.initialWidth?.value;
|
|
65
|
+
const customH = options.initialHeight?.value;
|
|
65
66
|
return {
|
|
66
67
|
width: customW != null && Number.isFinite(customW) && customW > 0 ? Math.min(maxW, Math.max(minWidth, Math.round(customW))) : Math.min(maxW, Math.max(minWidth, Math.round(maxW * defaultWidthRatio))),
|
|
67
|
-
height: Math.min(maxH, Math.max(minHeight, Math.round(maxH * defaultHeightRatio)))
|
|
68
|
+
height: customH != null && Number.isFinite(customH) && customH > 0 ? Math.min(maxH, Math.max(minHeight, Math.round(customH))) : Math.min(maxH, Math.max(minHeight, Math.round(maxH * defaultHeightRatio)))
|
|
68
69
|
};
|
|
69
70
|
}
|
|
70
71
|
function refreshCachedInsets() {
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { RsFontSize, RsFontWeight } from '../theme/types';
|
|
2
|
+
/**
|
|
3
|
+
* 表单分组密度。只影响内边距与组内间距,不改变控件高度。
|
|
4
|
+
*/
|
|
5
|
+
export type RsFieldsetSize = 'sm' | 'md';
|
|
6
|
+
/**
|
|
7
|
+
* 边框线型。对齐 CSS `border-style`(solid / dashed / dotted)。
|
|
8
|
+
*/
|
|
9
|
+
export type RsFieldsetBorderStyle = 'solid' | 'dashed' | 'dotted';
|
|
10
|
+
/**
|
|
11
|
+
* 边框浓度。
|
|
12
|
+
* - default:主题分隔线
|
|
13
|
+
* - subtle:弱分隔
|
|
14
|
+
* - faded:虚化(降低不透明度)
|
|
15
|
+
*/
|
|
16
|
+
export type RsFieldsetBorderTone = 'default' | 'subtle' | 'faded';
|
|
17
|
+
/**
|
|
18
|
+
* 标题对比(清晰度)。
|
|
19
|
+
* - strong:最高对比
|
|
20
|
+
* - default:正文色
|
|
21
|
+
* - muted:次要说明色
|
|
22
|
+
*/
|
|
23
|
+
export type RsFieldsetTitleTone = 'strong' | 'default' | 'muted';
|
|
24
|
+
/** 分组标题字号,只开放 caption / 次要 / 正文三档。 */
|
|
25
|
+
export type RsFieldsetTitleSize = Extract<RsFontSize, 'xs' | 'sm' | 'base'>;
|
|
26
|
+
/** 解析标题字号 token。 */
|
|
27
|
+
export declare function resolveFieldsetTitleSize(size: RsFieldsetTitleSize): string;
|
|
28
|
+
/** 解析标题字重 token。 */
|
|
29
|
+
export declare function resolveFieldsetTitleWeight(weight: RsFontWeight): string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { RS_FONT_SIZE_CSS, RS_FONT_WEIGHT_CSS } from "../theme/types.js";
|
|
2
|
+
//#region src/components/fieldset-utils.ts
|
|
3
|
+
/** 解析标题字号 token。 */
|
|
4
|
+
function resolveFieldsetTitleSize(size) {
|
|
5
|
+
return RS_FONT_SIZE_CSS[size];
|
|
6
|
+
}
|
|
7
|
+
/** 解析标题字重 token。 */
|
|
8
|
+
function resolveFieldsetTitleWeight(weight) {
|
|
9
|
+
return RS_FONT_WEIGHT_CSS[weight];
|
|
10
|
+
}
|
|
11
|
+
//#endregion
|
|
12
|
+
export { resolveFieldsetTitleSize, resolveFieldsetTitleWeight };
|