UNPKG

@aplus-frontend/antdv

Version:

Vue basic component library maintained based on ant-design-vue

162 lines 5.23 kB
import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import { createVNode as _createVNode } from "vue"; import _extends from "@babel/runtime/helpers/esm/extends"; import { computed, defineComponent, ref, watchEffect } from 'vue'; import inputProps from '../inputProps'; import { FormItemInputContext } from '../../form/FormItemContext'; import useConfigInject from '../../config-provider/hooks/useConfigInject'; import classNames from '../../_util/classNames'; import useStyle from '../style/otp'; import OTPInput from './OTPInput'; import { getMergedStatus } from '../../_util/statusUtils'; import warning from '../../_util/warning'; export default defineComponent({ compatConfig: { MODE: 3 }, name: 'AOTP', inheritAttrs: false, props: _extends(_extends({}, inputProps()), { length: { type: Number, default: 6 }, onChange: { type: Function, default: undefined }, onInput: { type: Function, default: undefined }, formatter: { type: Function, default: undefined }, defaultValue: { type: String, default: undefined }, mask: { type: [String, Boolean], default: false }, status: { type: String, default: undefined } }), setup(props, _ref) { let { attrs } = _ref; const { prefixCls, direction, size } = useConfigInject('otp', props); // Style const [wrapSSR, hashId] = useStyle(prefixCls); // ==================== Provider ========================= const formItemInputContext = FormItemInputContext.useInject(); const mergedStatus = computed(() => getMergedStatus(formItemInputContext.status, props.status)); const refs = ref([]); const strToArr = str => (str || '').split(''); // keep reactive const internalFormatter = txt => props.formatter ? props.formatter(txt) : txt; const valueCells = ref(strToArr(internalFormatter(props.defaultValue || ''))); watchEffect(() => { if (typeof props.value !== 'undefined' && props.value !== null) { valueCells.value = strToArr(String(props.value)); } }); const patchValue = (index, txt) => { let nextCells = valueCells.value.slice(); for (let i = 0; i < index; i += 1) { if (!nextCells[i]) { nextCells[i] = ''; } } if (txt.length <= 1) { nextCells[index] = txt; } else { nextCells = nextCells.slice(0, index).concat(strToArr(txt)); } nextCells = nextCells.slice(0, props.length); for (let i = nextCells.length - 1; i >= 0; i -= 1) { if (nextCells[i]) { break; } nextCells.pop(); } const formattedValue = internalFormatter(nextCells.map(c => c || ' ').join('')); nextCells = strToArr(formattedValue).map((c, i) => { if (c === ' ' && !nextCells[i]) { return nextCells[i]; } return c; }); return nextCells; }; // ======================= Change handlers ================= const onInputActiveChange = nextIndex => { var _a; (_a = refs.value[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus(); }; const onInputChange = (index, value) => { var _a; const nextValueCells = patchValue(index, value); const nextIndex = Math.min(index + value.length, props.length); if (nextIndex !== index) { (_a = refs.value[nextIndex]) === null || _a === void 0 ? void 0 : _a.focus(); } if (props.onInput) { props.onInput(nextValueCells); } if (props.onChange && nextValueCells.length === props.length && nextValueCells.every(v => v) && nextValueCells.some((v, i) => v !== valueCells.value[i])) { props.onChange(nextValueCells.join('')); } valueCells.value = nextValueCells.slice(); }; return () => { const cls = classNames(prefixCls.value, { [`${prefixCls}-sm`]: size.value === 'small', [`${prefixCls}-lg`]: size.value === 'large', [`${prefixCls.value}-rtl`]: direction.value === 'rtl' }, attrs.class, hashId.value); const { length, autofocus, disabled, mask } = props; const inputShardProps = { disabled, mask }; if (process.env.NODE_ENV !== 'production') { warning(!(typeof mask === 'string' && mask.length > 1), 'Input.OTP', '`mask` prop should be a single character.'); } return wrapSSR(_createVNode("div", { "class": cls }, [Array.from({ length }).map((_, index) => { const key = `opt-${index}`; const singleValue = valueCells.value[index]; return _createVNode(OTPInput, _objectSpread({ "ref": ref => refs.value[index] = ref, "key": key, "index": index, "class": `${prefixCls.value}-input`, "value": singleValue, "htmlSize": 1, "onChange": onInputChange, "status": mergedStatus.value, "onActiveChange": onInputActiveChange, "autofocus": index === 0 && autofocus }, inputShardProps), null); })])); }; } });