完全跑通1.0版本

This commit is contained in:
2026-05-26 12:56:03 +08:00
parent 2ece5174a7
commit 93c714a93b
11557 changed files with 1648225 additions and 36 deletions

View File

@@ -0,0 +1,9 @@
import { SFCWithInstall } from "../../utils/vue/typescript.js";
import { InputOtpEmits, InputOtpProps, inputOtpEmits } from "./src/input-otp.js";
import _default from "./src/input-otp.vue.js";
import { InputOtpInstance } from "./src/instance.js";
//#region ../../packages/components/input-otp/index.d.ts
declare const ElInputOtp: SFCWithInstall<typeof _default>;
//#endregion
export { ElInputOtp, ElInputOtp as default, InputOtpEmits, type InputOtpInstance, InputOtpProps, inputOtpEmits };

View File

@@ -0,0 +1,15 @@
Object.defineProperties(exports, {
__esModule: { value: true },
[Symbol.toStringTag]: { value: "Module" }
});
const require_install = require("../../utils/vue/install.js");
const require_input_otp = require("./src/input-otp.js");
const require_input_otp$1 = require("./src/input-otp2.js");
//#region ../../packages/components/input-otp/index.ts
const ElInputOtp = require_install.withInstall(require_input_otp$1.default);
//#endregion
exports.ElInputOtp = ElInputOtp;
exports.default = ElInputOtp;
exports.inputOtpEmits = require_input_otp.inputOtpEmits;
//# sourceMappingURL=index.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["withInstall","InputOtp"],"sources":["../../../../../packages/components/input-otp/index.ts"],"sourcesContent":["import { withInstall } from '@element-plus/utils'\nimport InputOtp from './src/input-otp.vue'\n\nimport type { SFCWithInstall } from '@element-plus/utils'\n\nexport const ElInputOtp: SFCWithInstall<typeof InputOtp> = withInstall(InputOtp)\nexport default ElInputOtp\n\nexport * from './src/input-otp'\nexport type { InputOtpInstance } from './src/instance'\n"],"mappings":";;;;;;;;AAKA,MAAa,aAA8CA,gBAAAA,YAAYC,oBAAAA,QAAS"}

View File

@@ -0,0 +1,74 @@
import { ComponentSize } from "../../../constants/size.js";
import { AriaProps } from "../../../hooks/use-aria/index.js";
import { InputHTMLAttributes, VNode } from "vue";
//#region ../../packages/components/input-otp/src/input-otp.d.ts
interface InputOtpProps extends Pick<AriaProps, 'ariaLabel'> {
/**
* @description The value of the OTP fields.
*
* Since numbers must not have leading zeros, `modelValue` is allowed to be a number only during initialization.
*
* @default undefined
*/
modelValue?: string | number;
/**
* @description The OTP fields length
* @default 6
*/
length?: number;
/**
* @description Custom validator function
* @default () => true
*/
validator?: (char: string, index: number) => boolean;
/**
* @description Native input mode for virtual keyboards
*/
inputmode?: InputHTMLAttributes['inputmode'];
/**
* @description The type of the OTP fields
* @default 'outlined'
*/
type?: 'outlined' | 'filled' | 'underlined';
/**
* @description The size of the OTP fields
* @default 'default'
*/
size?: ComponentSize;
/**
* @description Whether to enable password mode
*/
mask?: boolean;
/**
* @description Whether the OTP fields are disabled
* @default undefined
*/
disabled?: boolean;
/**
* @description Same as `readonly` in native input
*/
readonly?: boolean;
/**
* @description Same as `id` in native input
*/
id?: string;
/**
* @description Whether to trigger form validation
*/
validateEvent?: boolean;
/**
* @description The separator between OTP fields
*/
separator?: string | VNode | ((index: number) => string | VNode);
}
declare const inputOtpEmits: {
"update:modelValue": (value: string) => boolean;
change: (value: string) => boolean;
finish: (value: string) => boolean;
focus: (eve: FocusEvent) => boolean;
blur: (eve: FocusEvent) => boolean;
};
type InputOtpEmits = typeof inputOtpEmits;
//#endregion
export { InputOtpEmits, InputOtpProps, inputOtpEmits };

View File

@@ -0,0 +1,16 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
require("../../../_virtual/_rolldown/runtime.js");
const require_event = require("../../../constants/event.js");
let _vue_shared = require("@vue/shared");
//#region ../../packages/components/input-otp/src/input-otp.ts
const inputOtpEmits = {
[require_event.UPDATE_MODEL_EVENT]: (value) => (0, _vue_shared.isString)(value),
[require_event.CHANGE_EVENT]: (value) => (0, _vue_shared.isString)(value),
finish: (value) => (0, _vue_shared.isString)(value),
focus: (eve) => eve instanceof FocusEvent,
blur: (eve) => eve instanceof FocusEvent
};
//#endregion
exports.inputOtpEmits = inputOtpEmits;
//# sourceMappingURL=input-otp.js.map

View File

@@ -0,0 +1 @@
{"version":3,"file":"input-otp.js","names":["UPDATE_MODEL_EVENT","CHANGE_EVENT"],"sources":["../../../../../../packages/components/input-otp/src/input-otp.ts"],"sourcesContent":["import { CHANGE_EVENT, UPDATE_MODEL_EVENT } from '@element-plus/constants'\nimport { isString } from '@element-plus/utils'\n\nimport type { InputHTMLAttributes, VNode } from 'vue'\nimport type { ComponentSize } from '@element-plus/constants'\nimport type { AriaProps } from '@element-plus/hooks'\n\nexport interface InputOtpProps extends Pick<AriaProps, 'ariaLabel'> {\n /**\n * @description The value of the OTP fields.\n *\n * Since numbers must not have leading zeros, `modelValue` is allowed to be a number only during initialization.\n *\n * @default undefined\n */\n modelValue?: string | number\n /**\n * @description The OTP fields length\n * @default 6\n */\n length?: number\n /**\n * @description Custom validator function\n * @default () => true\n */\n validator?: (char: string, index: number) => boolean\n /**\n * @description Native input mode for virtual keyboards\n */\n inputmode?: InputHTMLAttributes['inputmode']\n /**\n * @description The type of the OTP fields\n * @default 'outlined'\n */\n type?: 'outlined' | 'filled' | 'underlined'\n /**\n * @description The size of the OTP fields\n * @default 'default'\n */\n size?: ComponentSize\n /**\n * @description Whether to enable password mode\n */\n mask?: boolean\n /**\n * @description Whether the OTP fields are disabled\n * @default undefined\n */\n disabled?: boolean\n /**\n * @description Same as `readonly` in native input\n */\n readonly?: boolean\n /**\n * @description Same as `id` in native input\n */\n id?: string\n /**\n * @description Whether to trigger form validation\n */\n validateEvent?: boolean\n /**\n * @description The separator between OTP fields\n */\n separator?: string | VNode | ((index: number) => string | VNode)\n}\n\nexport const inputOtpEmits = {\n [UPDATE_MODEL_EVENT]: (value: string) => isString(value),\n [CHANGE_EVENT]: (value: string) => isString(value),\n finish: (value: string) => isString(value),\n focus: (eve: FocusEvent) => eve instanceof FocusEvent,\n blur: (eve: FocusEvent) => eve instanceof FocusEvent,\n}\n\nexport type InputOtpEmits = typeof inputOtpEmits\n"],"mappings":";;;;;AAmEA,MAAa,gBAAgB;EAC1BA,cAAAA,sBAAsB,WAAA,GAAA,YAAA,UAA2B,MAAM;EACvDC,cAAAA,gBAAgB,WAAA,GAAA,YAAA,UAA2B,MAAM;CAClD,SAAS,WAAA,GAAA,YAAA,UAA2B,MAAM;CAC1C,QAAQ,QAAoB,eAAe;CAC3C,OAAO,QAAoB,eAAe;CAC3C"}

View File

@@ -0,0 +1,53 @@
import { ComponentSize } from "../../../constants/size.js";
import { InputOtpProps } from "./input-otp.js";
import * as _$vue from "vue";
//#region ../../packages/components/input-otp/src/input-otp.vue.d.ts
declare var __VLS_1: {
index: number;
};
type __VLS_Slots = {} & {
separator?: (props: typeof __VLS_1) => any;
};
declare const __VLS_base: _$vue.DefineComponent<InputOtpProps, {
/**
* @description HTML input elements array
*/
inputRefs: _$vue.Ref<(HTMLInputElement | undefined)[], (HTMLInputElement | undefined)[]>;
/**
* @description Focus an OTP input field
*/
focus: (index?: number) => void;
/**
* @description Blur the focused OTP input field
*/
blur: () => void;
}, {}, {}, {}, _$vue.ComponentOptionsMixin, _$vue.ComponentOptionsMixin, {
finish: (value: string) => void;
change: (value: string) => void;
"update:modelValue": (value: string) => void;
focus: (eve: FocusEvent) => void;
blur: (eve: FocusEvent) => void;
}, string, _$vue.PublicProps, Readonly<InputOtpProps> & Readonly<{
onFinish?: ((value: string) => any) | undefined;
"onUpdate:modelValue"?: ((value: string) => any) | undefined;
onChange?: ((value: string) => any) | undefined;
onFocus?: ((eve: FocusEvent) => any) | undefined;
onBlur?: ((eve: FocusEvent) => any) | undefined;
}>, {
length: number;
type: "outlined" | "filled" | "underlined";
validator: (char: string, index: number) => boolean;
disabled: boolean;
size: ComponentSize;
validateEvent: boolean;
}, {}, {}, {}, string, _$vue.ComponentProvideOptions, false, {}, any>;
declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
declare const _default: typeof __VLS_export;
type __VLS_WithSlots<T, S> = T & {
new (): {
$slots: S;
};
};
//#endregion
export { _default as default };

View File

@@ -0,0 +1,283 @@
require("../../../_virtual/_rolldown/runtime.js");
const require_aria = require("../../../constants/aria.js");
const require_event = require("../../../constants/event.js");
const require_event$1 = require("../../../utils/dom/event.js");
const require_raf = require("../../../utils/raf.js");
const require_index = require("../../../hooks/use-locale/index.js");
const require_index$1 = require("../../../hooks/use-namespace/index.js");
const require_use_form_common_props = require("../../form/src/hooks/use-form-common-props.js");
const require_use_form_item = require("../../form/src/hooks/use-form-item.js");
const require_input_otp = require("./input-otp.js");
let _vueuse_core = require("@vueuse/core");
let vue = require("vue");
let _vue_shared = require("@vue/shared");
//#region ../../packages/components/input-otp/src/input-otp.vue?vue&type=script&setup=true&lang.ts
const _hoisted_1 = [
"id",
"aria-label",
"aria-labelledby"
];
const _hoisted_2 = [
"value",
"type",
"disabled",
"readonly",
"inputmode",
"aria-label",
"onClick",
"onKeydown",
"onInput"
];
var input_otp_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
name: "ElInputOtp",
__name: "input-otp",
props: {
modelValue: {
type: [String, Number],
required: false
},
length: {
type: Number,
required: false,
default: 6
},
validator: {
type: Function,
required: false,
default: () => true
},
inputmode: {
type: null,
required: false
},
type: {
type: String,
required: false,
default: "outlined"
},
size: {
type: null,
required: false,
default: "default"
},
mask: {
type: Boolean,
required: false
},
disabled: {
type: Boolean,
required: false,
default: void 0
},
readonly: {
type: Boolean,
required: false
},
id: {
type: String,
required: false
},
validateEvent: {
type: Boolean,
required: false,
default: true
},
separator: {
type: [
String,
Object,
Function
],
required: false
},
ariaLabel: {
type: String,
required: false
}
},
emits: require_input_otp.inputOtpEmits,
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const emit = __emit;
const initialValue = (0, vue.computed)(() => {
const value = String(props.modelValue ?? "");
return Array.from({ length: props.length }, (_, i) => value.charAt(i));
});
const separators = (0, vue.computed)(() => {
const { separator } = props;
const _separator = (0, _vue_shared.isFunction)(separator) ? separator : () => separator;
return Array.from({ length: props.length - 1 }, (_, i) => _separator(i));
});
const innerValue = (0, vue.ref)(initialValue.value);
const isFocused = (0, vue.ref)(false);
const inputRefs = (0, vue.ref)([]);
const ns = require_index$1.useNamespace("input-otp");
const { t } = require_index.useLocale();
const { formItem } = require_use_form_item.useFormItem();
const { inputId, isLabeledByFormItem } = require_use_form_item.useFormItemInputId(props, { formItemContext: formItem });
const disabled = require_use_form_common_props.useFormDisabled();
let modelValueOnFocus = props.modelValue;
const getFirstIndex = (maxIndex) => {
const index = innerValue.value.findIndex((char, i) => !char && i <= maxIndex);
return index === -1 ? maxIndex : index;
};
const handleFocus = (event) => {
if (inputRefs.value?.includes(event.relatedTarget)) return;
isFocused.value = true;
emit("focus", event);
};
const handleBlur = (event) => {
if (inputRefs.value?.includes(event.relatedTarget)) return;
isFocused.value = false;
emit("blur", event);
if (props.validateEvent) formItem?.validate?.("blur").catch(_vue_shared.NOOP);
};
const updateModelValue = (emitFinish = true) => {
const value = innerValue.value.join("").slice(0, props.length);
if (value !== props.modelValue) {
emit(require_event.UPDATE_MODEL_EVENT, value);
if (emitFinish && value.length === props.length) emit("finish", value);
}
};
const handleKeydown = (event, index) => {
const code = require_event$1.getEventCode(event);
let preventDefault = true;
switch (code) {
case require_aria.EVENT_CODE.backspace:
if (props.readonly) break;
innerValue.value[index] = "";
focus(index - 1);
updateModelValue();
break;
case require_aria.EVENT_CODE.delete:
if (props.readonly) break;
innerValue.value[index] = "";
focus(index);
updateModelValue();
break;
case require_aria.EVENT_CODE.up:
case require_aria.EVENT_CODE.left:
focus(index - 1);
break;
case require_aria.EVENT_CODE.down:
case require_aria.EVENT_CODE.right:
focus(index + 1);
break;
default: preventDefault = false;
}
if (preventDefault) event.preventDefault();
};
const handleInput = (event, index) => {
const target = event.target;
const targetIndex = getFirstIndex(index);
let focusIndex = targetIndex + 1;
let value = target.value;
if (value.length > 1) {
const chars = castValues(value, targetIndex);
target.value = innerValue.value[index] ?? "";
chars.forEach((char, i) => innerValue.value[targetIndex + i] = char);
focus(targetIndex + chars.length);
updateModelValue();
return;
}
if (!props.validator(value, targetIndex)) {
target.value = innerValue.value[index] ?? "";
value = target.value;
focusIndex = targetIndex;
}
innerValue.value[targetIndex] = value;
if (targetIndex !== index) target.value = innerValue.value[index] ?? "";
focus(focusIndex);
updateModelValue();
};
const castValues = (value, startIndex = 0) => {
const chars = `${value ?? ""}`.split("");
const result = [];
for (const char of chars) {
if (result.length + startIndex >= props.length) break;
if (props.validator(char, result.length + startIndex)) result.push(char);
}
return result;
};
const focus = (index = 0) => {
const focusIndex = (0, _vueuse_core.clamp)(index, 0, props.length - 1);
const target = inputRefs.value?.[focusIndex];
if (document.activeElement !== target) target?.focus();
require_raf.rAF(() => {
if (!props.readonly && document.activeElement === target) target?.select();
});
};
const blur = () => {
(inputRefs.value?.find((input) => document.activeElement === input))?.blur();
};
(0, vue.watch)(() => props.modelValue, () => {
innerValue.value = initialValue.value;
if (props.validateEvent) formItem?.validate?.("change").catch(_vue_shared.NOOP);
});
(0, vue.watch)(() => props.length, () => {
innerValue.value = initialValue.value;
updateModelValue(false);
});
(0, vue.watch)(isFocused, (value) => {
if (value) {
modelValueOnFocus = props.modelValue;
return;
}
if (modelValueOnFocus !== props.modelValue) emit(require_event.CHANGE_EVENT, props.modelValue);
});
__expose({
/**
* @description HTML input elements array
*/
inputRefs,
/**
* @description Focus an OTP input field
*/
focus,
/**
* @description Blur the focused OTP input field
*/
blur
});
return (_ctx, _cache) => {
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
id: (0, vue.unref)(inputId),
class: (0, vue.normalizeClass)([
(0, vue.unref)(ns).b(),
(0, vue.unref)(ns).m(__props.size),
(0, vue.unref)(ns).m(__props.type),
(0, vue.unref)(ns).is("disabled", (0, vue.unref)(disabled))
]),
role: "group",
"aria-label": !(0, vue.unref)(isLabeledByFormItem) ? __props.ariaLabel || (0, vue.unref)(t)("el.inputOTP.groupLabel") : void 0,
"aria-labelledby": (0, vue.unref)(isLabeledByFormItem) ? (0, vue.unref)(formItem)?.labelId : void 0
}, [((0, vue.openBlock)(true), (0, vue.createElementBlock)(vue.Fragment, null, (0, vue.renderList)(__props.length, (_, index) => {
return (0, vue.openBlock)(), (0, vue.createElementBlock)(vue.Fragment, { key: index }, [(0, vue.createElementVNode)("label", { class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("input-field")) }, [(0, vue.createElementVNode)("input", {
ref_for: true,
ref_key: "inputRefs",
ref: inputRefs,
value: innerValue.value[index],
class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("input")),
type: __props.mask ? "password" : "text",
disabled: (0, vue.unref)(disabled),
readonly: __props.readonly,
inputmode: __props.inputmode,
autocomplete: "one-time-code",
"aria-label": (0, vue.unref)(t)("el.inputOTP.defaultLabel", { index: index + 1 }),
onFocus: handleFocus,
onBlur: handleBlur,
onClick: ($event) => focus(index),
onKeydown: ($event) => handleKeydown($event, index),
onInput: ($event) => handleInput($event, index)
}, null, 42, _hoisted_2)], 2), (_ctx.$slots.separator || separators.value[index]) && index < __props.length - 1 ? (0, vue.renderSlot)(_ctx.$slots, "separator", {
key: 0,
index
}, () => [((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(() => separators.value[index])))]) : (0, vue.createCommentVNode)("v-if", true)], 64);
}), 128))], 10, _hoisted_1);
};
}
});
//#endregion
exports.default = input_otp_vue_vue_type_script_setup_true_lang_default;
//# sourceMappingURL=input-otp.vue_vue_type_script_setup_true_lang.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,10 @@
Object.defineProperties(exports, {
__esModule: { value: true },
[Symbol.toStringTag]: { value: "Module" }
});
//#region ../../packages/components/input-otp/src/input-otp.vue
var input_otp_default = require("./input-otp.vue_vue_type_script_setup_true_lang.js").default;
//#endregion
exports.default = input_otp_default;
//# sourceMappingURL=input-otp2.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,6 @@
import _default from "./input-otp.vue.js";
//#region ../../packages/components/input-otp/src/instance.d.ts
type InputOtpInstance = InstanceType<typeof _default> & unknown;
//#endregion
export { InputOtpInstance };

View File

@@ -0,0 +1 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });

View File

@@ -0,0 +1,3 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
require("../../base/style/css.js");
require("element-plus/theme-chalk/el-input-otp.css");

View File

@@ -0,0 +1,3 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
require("../../base/style/index.js");
require("element-plus/theme-chalk/src/input-otp.scss");