feat: initial commit - Phase 1 & 2 core features

This commit is contained in:
hiderfong
2026-04-22 17:07:33 +08:00
commit 1773bda06b
25005 changed files with 6252106 additions and 0 deletions
+21
View File
@@ -0,0 +1,21 @@
import { SFCWithInstall } from "../../utils/vue/typescript.js";
import "../../utils/index.js";
import { FormItemProp, FormItemProps, FormItemPropsPublic, FormItemValidateState, formItemProps, formItemValidateStates } from "./src/form-item.js";
import { FormContext, FormItemContext, FormItemRule, FormLabelWidthContext, FormRules, FormValidateCallback, FormValidateFailure, FormValidationResult } from "./src/types.js";
import { FormEmits, FormMetaProps, FormMetaPropsPublic, FormProps, FormPropsPublic, formEmits, formMetaProps, formProps } from "./src/form.js";
import { _default } from "./src/form.vue.js";
import { _default as _default$1 } from "./src/form-item.vue.js";
import { formContextKey, formItemContextKey } from "./src/constants.js";
import { useDisabled, useFormDisabled, useFormSize, useSize } from "./src/hooks/use-form-common-props.js";
import { IUseFormItemInputCommonProps, useFormItem, useFormItemInputId } from "./src/hooks/use-form-item.js";
import "./src/hooks/index.js";
//#region ../../packages/components/form/index.d.ts
declare const ElForm: SFCWithInstall<typeof _default> & {
FormItem: typeof _default$1;
};
declare const ElFormItem: SFCWithInstall<typeof _default$1>;
type FormInstance = InstanceType<typeof _default> & unknown;
type FormItemInstance = InstanceType<typeof _default$1> & unknown;
//#endregion
export { ElForm, ElForm as default, ElFormItem, FormContext, FormEmits, FormInstance, FormItemContext, FormItemInstance, FormItemProp, FormItemProps, FormItemPropsPublic, FormItemRule, FormItemValidateState, FormLabelWidthContext, FormMetaProps, FormMetaPropsPublic, FormProps, FormPropsPublic, FormRules, FormValidateCallback, FormValidateFailure, FormValidationResult, IUseFormItemInputCommonProps, formContextKey, formEmits, formItemContextKey, formItemProps, formItemValidateStates, formMetaProps, formProps, useDisabled, useFormDisabled, useFormItem, useFormItemInputId, useFormSize, useSize };
+32
View File
@@ -0,0 +1,32 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_install = require('../../utils/vue/install.js');
const require_form = require('./src/form.js');
const require_constants = require('./src/constants.js');
const require_use_form_common_props = require('./src/hooks/use-form-common-props.js');
const require_use_form_item = require('./src/hooks/use-form-item.js');
const require_form$1 = require('./src/form2.js');
const require_form_item = require('./src/form-item.js');
const require_form_item$1 = require('./src/form-item2.js');
//#region ../../packages/components/form/index.ts
const ElForm = require_install.withInstall(require_form$1.default, { FormItem: require_form_item$1.default });
const ElFormItem = require_install.withNoopInstall(require_form_item$1.default);
//#endregion
exports.ElForm = ElForm;
exports.default = ElForm;
exports.ElFormItem = ElFormItem;
exports.formContextKey = require_constants.formContextKey;
exports.formEmits = require_form.formEmits;
exports.formItemContextKey = require_constants.formItemContextKey;
exports.formItemProps = require_form_item.formItemProps;
exports.formItemValidateStates = require_form_item.formItemValidateStates;
exports.formMetaProps = require_form.formMetaProps;
exports.formProps = require_form.formProps;
exports.useDisabled = require_use_form_common_props.useDisabled;
exports.useFormDisabled = require_use_form_common_props.useFormDisabled;
exports.useFormItem = require_use_form_item.useFormItem;
exports.useFormItemInputId = require_use_form_item.useFormItemInputId;
exports.useFormSize = require_use_form_common_props.useFormSize;
exports.useSize = require_use_form_common_props.useSize;
//# sourceMappingURL=index.js.map
+1
View File
@@ -0,0 +1 @@
{"version":3,"file":"index.js","names":["withInstall","Form","withNoopInstall","FormItem"],"sources":["../../../../../packages/components/form/index.ts"],"sourcesContent":["import { withInstall, withNoopInstall } from '@element-plus/utils'\nimport Form from './src/form.vue'\nimport FormItem from './src/form-item.vue'\n\nimport type { SFCWithInstall } from '@element-plus/utils'\n\nexport const ElForm: SFCWithInstall<typeof Form> & {\n FormItem: typeof FormItem\n} = withInstall(Form, {\n FormItem,\n})\nexport default ElForm\nexport const ElFormItem: SFCWithInstall<typeof FormItem> =\n withNoopInstall(FormItem)\n\nexport * from './src/form'\nexport * from './src/form-item'\nexport * from './src/types'\nexport * from './src/constants'\nexport * from './src/hooks'\n\nexport type FormInstance = InstanceType<typeof Form> & unknown\nexport type FormItemInstance = InstanceType<typeof FormItem> & unknown\n"],"mappings":";;;;;;;;;;;AAMA,MAAa,SAETA,4BAAYC,wBAAM,EACpB,uCACD,CAAC;AAEF,MAAa,aACXC,gCAAgBC,4BAAS"}
@@ -0,0 +1,8 @@
import { FormContext, FormItemContext } from "./types.js";
import { InjectionKey } from "vue";
//#region ../../packages/components/form/src/constants.d.ts
declare const formContextKey: InjectionKey<FormContext>;
declare const formItemContextKey: InjectionKey<FormItemContext | undefined>;
//#endregion
export { formContextKey, formItemContextKey };
@@ -0,0 +1,10 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
//#region ../../packages/components/form/src/constants.ts
const formContextKey = Symbol("formContextKey");
const formItemContextKey = Symbol("formItemContextKey");
//#endregion
exports.formContextKey = formContextKey;
exports.formItemContextKey = formItemContextKey;
//# sourceMappingURL=constants.js.map
@@ -0,0 +1 @@
{"version":3,"file":"constants.js","names":[],"sources":["../../../../../../packages/components/form/src/constants.ts"],"sourcesContent":["import type { InjectionKey } from 'vue'\nimport type { FormContext, FormItemContext } from './types'\n\nexport const formContextKey: InjectionKey<FormContext> =\n Symbol('formContextKey')\nexport const formItemContextKey: InjectionKey<FormItemContext | undefined> =\n Symbol('formItemContextKey')\n"],"mappings":";;;AAGA,MAAa,iBACX,OAAO,iBAAiB;AAC1B,MAAa,qBACX,OAAO,qBAAqB"}
@@ -0,0 +1,110 @@
import { EpPropFinalized, EpPropMergeType } from "../../../utils/vue/props/types.js";
import { ComponentSize } from "../../../constants/size.js";
import { Arrayable } from "../../../utils/typescript.js";
import "../../../utils/index.js";
import { FormItemRule } from "./types.js";
import * as vue from "vue";
import { ExtractPublicPropTypes } from "vue";
//#region ../../packages/components/form/src/form-item.d.ts
declare const formItemValidateStates: readonly ["", "error", "validating", "success"];
type FormItemValidateState = (typeof formItemValidateStates)[number];
type FormItemProp = Arrayable<string>;
interface FormItemProps {
/**
* @description Label text.
*/
label?: string;
/**
* @description Width of label, e.g. `'50px'`. `'auto'` is supported.
*/
labelWidth?: string | number;
/**
* @description Position of label. If set to `'left'` or `'right'`, `label-width` prop is also required. The default is extend from `form label-position`.
*/
labelPosition?: 'left' | 'right' | 'top' | '';
/**
* @description A key of `model`. It could be an array of property paths (e.g `['a', 'b', '0']`). In the use of `validate` and `resetFields` method, the attribute is required.
*/
prop?: FormItemProp;
/**
* @description Whether the field is required or not, will be determined by validation rules if omitted.
*/
required?: boolean;
/**
* @description Validation rules of form, see the [following table](#formitemrule), more advanced usage at [async-validator](https://github.com/yiminghe/async-validator).
*/
rules?: Arrayable<FormItemRule>;
/**
* @description Field error message, set its value and the field will validate error and show this message immediately.
*/
error?: string;
/**
* @description Validation state of formItem.
*/
validateStatus?: FormItemValidateState;
/**
* @description Same as for in native label.
*/
for?: string;
/**
* @description Inline style validate message.
*/
inlineMessage?: boolean;
/**
* @description Whether to show the error message.
*/
showMessage?: boolean;
/**
* @description Control the size of components in this form-item.
*/
size?: ComponentSize;
}
/**
* @deprecated Removed after 3.0.0, Use `FormItemProps` instead.
*/
declare const formItemProps: {
readonly label: StringConstructor;
readonly labelWidth: {
readonly type: vue.PropType<EpPropMergeType<readonly [StringConstructor, NumberConstructor], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly labelPosition: EpPropFinalized<StringConstructor, "" | "top" | "left" | "right", unknown, "", boolean>;
readonly prop: {
readonly type: vue.PropType<EpPropMergeType<(new (...args: any[]) => string | string[]) | (() => FormItemProp) | (((new (...args: any[]) => string | string[]) | (() => FormItemProp)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly required: EpPropFinalized<BooleanConstructor, unknown, unknown, undefined, boolean>;
readonly rules: {
readonly type: vue.PropType<EpPropMergeType<(new (...args: any[]) => FormItemRule | FormItemRule[]) | (() => Arrayable<FormItemRule>) | (((new (...args: any[]) => FormItemRule | FormItemRule[]) | (() => Arrayable<FormItemRule>)) | null)[], unknown, unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly error: StringConstructor;
readonly validateStatus: {
readonly type: vue.PropType<EpPropMergeType<StringConstructor, "" | "error" | "success" | "validating", unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly for: StringConstructor;
readonly inlineMessage: EpPropFinalized<BooleanConstructor, unknown, unknown, undefined, boolean>;
readonly showMessage: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly size: {
readonly type: vue.PropType<EpPropMergeType<StringConstructor, "" | "default" | "small" | "large", unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
};
/**
* @deprecated Removed after 3.0.0, Use `FormItemProps` instead.
*/
type FormItemPropsPublic = ExtractPublicPropTypes<typeof formItemProps>;
//#endregion
export { FormItemProp, FormItemProps, FormItemPropsPublic, FormItemValidateState, formItemProps, formItemValidateStates };
@@ -0,0 +1,57 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_size = require('../../../constants/size.js');
const require_runtime = require('../../../utils/vue/props/runtime.js');
//#region ../../packages/components/form/src/form-item.ts
const formItemValidateStates = [
"",
"error",
"validating",
"success"
];
/**
* @deprecated Removed after 3.0.0, Use `FormItemProps` instead.
*/
const formItemProps = require_runtime.buildProps({
label: String,
labelWidth: { type: [String, Number] },
labelPosition: {
type: String,
values: [
"left",
"right",
"top",
""
],
default: ""
},
prop: { type: require_runtime.definePropType([String, Array]) },
required: {
type: Boolean,
default: void 0
},
rules: { type: require_runtime.definePropType([Object, Array]) },
error: String,
validateStatus: {
type: String,
values: formItemValidateStates
},
for: String,
inlineMessage: {
type: Boolean,
default: void 0
},
showMessage: {
type: Boolean,
default: true
},
size: {
type: String,
values: require_size.componentSizes
}
});
//#endregion
exports.formItemProps = formItemProps;
exports.formItemValidateStates = formItemValidateStates;
//# sourceMappingURL=form-item.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,61 @@
import { FormItemProps } from "./form-item.js";
import { FormValidateCallback, FormValidationResult } from "./types.js";
import * as vue from "vue";
//#region ../../packages/components/form/src/form-item.vue.d.ts
declare var __VLS_13: {
label: string;
}, __VLS_15: {}, __VLS_23: {
error: string;
};
type __VLS_Slots = {} & {
label?: (props: typeof __VLS_13) => any;
} & {
default?: (props: typeof __VLS_15) => any;
} & {
error?: (props: typeof __VLS_23) => any;
};
declare const __VLS_base: vue.DefineComponent<FormItemProps, {
/**
* @description Form item size.
*/
size: vue.ComputedRef<"" | "default" | "small" | "large">;
/**
* @description Validation message.
*/
validateMessage: vue.Ref<string, string>;
/**
* @description Validation state.
*/
validateState: vue.Ref<"" | "error" | "success" | "validating", "" | "error" | "success" | "validating">;
/**
* @description Validate form item.
*/
validate: (trigger: string, callback?: FormValidateCallback) => FormValidationResult;
/**
* @description Remove validation status of the field.
*/
clearValidate: () => void;
/**
* @description Reset current field and remove validation result.
*/
resetField: () => void;
/**
* @description Set initial value for this field. When `resetField` is called, the field will reset to this value.
*/
setInitialValue: (value: any) => void;
}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {}, string, vue.PublicProps, Readonly<FormItemProps> & Readonly<{}>, {
required: boolean;
labelPosition: "left" | "right" | "top" | "";
inlineMessage: boolean;
showMessage: 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 };
@@ -0,0 +1,285 @@
const require_runtime = require('../../../_virtual/_rolldown/runtime.js');
const require_types = require('../../../utils/types.js');
const require_objects = require('../../../utils/objects.js');
const require_style = require('../../../utils/dom/style.js');
const require_index = require('../../../hooks/use-namespace/index.js');
const require_index$1 = require('../../../hooks/use-id/index.js');
const require_constants = require('./constants.js');
const require_use_form_common_props = require('./hooks/use-form-common-props.js');
const require_form_item = require('./form-item.js');
const require_form_label_wrap = require('./form-label-wrap.js');
let _vueuse_core = require("@vueuse/core");
let lodash_unified = require("lodash-unified");
let vue = require("vue");
let async_validator = require("async-validator");
async_validator = require_runtime.__toESM(async_validator);
let _vue_shared = require("@vue/shared");
//#region ../../packages/components/form/src/form-item.vue?vue&type=script&setup=true&lang.ts
const _hoisted_1 = ["role", "aria-labelledby"];
var form_item_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
name: "ElFormItem",
__name: "form-item",
props: require_form_item.formItemProps,
setup(__props, { expose: __expose }) {
const props = __props;
const slots = (0, vue.useSlots)();
const formContext = (0, vue.inject)(require_constants.formContextKey, void 0);
const parentFormItemContext = (0, vue.inject)(require_constants.formItemContextKey, void 0);
const _size = require_use_form_common_props.useFormSize(void 0, { formItem: false });
const ns = require_index.useNamespace("form-item");
const labelId = require_index$1.useId().value;
const inputIds = (0, vue.ref)([]);
const validateState = (0, vue.ref)("");
const validateStateDebounced = (0, _vueuse_core.refDebounced)(validateState, 100);
const validateMessage = (0, vue.ref)("");
const formItemRef = (0, vue.ref)();
let initialValue = void 0;
let isResettingField = false;
const labelPosition = (0, vue.computed)(() => props.labelPosition || formContext?.labelPosition);
const labelStyle = (0, vue.computed)(() => {
if (labelPosition.value === "top") return {};
return { width: require_style.addUnit(props.labelWidth ?? formContext?.labelWidth) };
});
const contentStyle = (0, vue.computed)(() => {
if (labelPosition.value === "top" || formContext?.inline) return {};
if (!props.label && !props.labelWidth && isNested) return {};
const labelWidth = require_style.addUnit(props.labelWidth ?? formContext?.labelWidth);
if (!props.label && !slots.label) return { marginLeft: labelWidth };
return {};
});
const formItemClasses = (0, vue.computed)(() => [
ns.b(),
ns.m(_size.value),
ns.is("error", validateState.value === "error"),
ns.is("validating", validateState.value === "validating"),
ns.is("success", validateState.value === "success"),
ns.is("required", isRequired.value || props.required),
ns.is("no-asterisk", formContext?.hideRequiredAsterisk),
formContext?.requireAsteriskPosition === "right" ? "asterisk-right" : "asterisk-left",
{
[ns.m("feedback")]: formContext?.statusIcon,
[ns.m(`label-${labelPosition.value}`)]: labelPosition.value
}
]);
const _inlineMessage = (0, vue.computed)(() => require_types.isBoolean(props.inlineMessage) ? props.inlineMessage : formContext?.inlineMessage || false);
const validateClasses = (0, vue.computed)(() => [ns.e("error"), { [ns.em("error", "inline")]: _inlineMessage.value }]);
const propString = (0, vue.computed)(() => {
if (!props.prop) return "";
return (0, _vue_shared.isArray)(props.prop) ? props.prop.join(".") : props.prop;
});
const hasLabel = (0, vue.computed)(() => {
return !!(props.label || slots.label);
});
const labelFor = (0, vue.computed)(() => {
return props.for ?? (inputIds.value.length === 1 ? inputIds.value[0] : void 0);
});
const isGroup = (0, vue.computed)(() => {
return !labelFor.value && hasLabel.value;
});
const isNested = !!parentFormItemContext;
const fieldValue = (0, vue.computed)(() => {
const model = formContext?.model;
if (!model || !props.prop) return;
return require_objects.getProp(model, props.prop).value;
});
const normalizedRules = (0, vue.computed)(() => {
const { required } = props;
const rules = [];
if (props.rules) rules.push(...(0, lodash_unified.castArray)(props.rules));
const formRules = formContext?.rules;
if (formRules && props.prop) {
const _rules = require_objects.getProp(formRules, props.prop).value;
if (_rules) rules.push(...(0, lodash_unified.castArray)(_rules));
}
if (required !== void 0) {
const requiredRules = rules.map((rule, i) => [rule, i]).filter(([rule]) => "required" in rule);
if (requiredRules.length > 0) for (const [rule, i] of requiredRules) {
if (rule.required === required) continue;
rules[i] = {
...rule,
required
};
}
else rules.push({ required });
}
return rules;
});
const validateEnabled = (0, vue.computed)(() => normalizedRules.value.length > 0);
const getFilteredRule = (trigger) => {
return normalizedRules.value.filter((rule) => {
if (!rule.trigger || !trigger) return true;
if ((0, _vue_shared.isArray)(rule.trigger)) return rule.trigger.includes(trigger);
else return rule.trigger === trigger;
}).map(({ trigger, ...rule }) => rule);
};
const isRequired = (0, vue.computed)(() => normalizedRules.value.some((rule) => rule.required));
const shouldShowError = (0, vue.computed)(() => validateStateDebounced.value === "error" && props.showMessage && (formContext?.showMessage ?? true));
const currentLabel = (0, vue.computed)(() => `${props.label || ""}${formContext?.labelSuffix || ""}`);
const setValidationState = (state) => {
validateState.value = state;
};
const onValidationFailed = (error) => {
const { errors, fields } = error;
if (!errors || !fields) console.error(error);
setValidationState("error");
validateMessage.value = errors ? errors?.[0]?.message ?? `${props.prop} is required` : "";
formContext?.emit("validate", props.prop, false, validateMessage.value);
};
const onValidationSucceeded = () => {
setValidationState("success");
formContext?.emit("validate", props.prop, true, "");
};
const doValidate = async (rules) => {
const modelName = propString.value;
return new async_validator.default({ [modelName]: rules }).validate({ [modelName]: fieldValue.value }, { firstFields: true }).then(() => {
onValidationSucceeded();
return true;
}).catch((err) => {
onValidationFailed(err);
return Promise.reject(err);
});
};
const validate = async (trigger, callback) => {
if (isResettingField || !props.prop) return false;
const hasCallback = (0, _vue_shared.isFunction)(callback);
if (!validateEnabled.value) {
callback?.(false);
return false;
}
const rules = getFilteredRule(trigger);
if (rules.length === 0) {
callback?.(true);
return true;
}
setValidationState("validating");
return doValidate(rules).then(() => {
callback?.(true);
return true;
}).catch((err) => {
const { fields } = err;
callback?.(false, fields);
return hasCallback ? false : Promise.reject(fields);
});
};
const clearValidate = () => {
setValidationState("");
validateMessage.value = "";
isResettingField = false;
};
const resetField = async () => {
const model = formContext?.model;
if (!model || !props.prop) return;
const computedValue = require_objects.getProp(model, props.prop);
isResettingField = true;
computedValue.value = (0, lodash_unified.cloneDeep)(initialValue);
await (0, vue.nextTick)();
clearValidate();
isResettingField = false;
};
const addInputId = (id) => {
if (!inputIds.value.includes(id)) inputIds.value.push(id);
};
const removeInputId = (id) => {
inputIds.value = inputIds.value.filter((listId) => listId !== id);
};
const setInitialValue = (value) => {
initialValue = (0, lodash_unified.cloneDeep)(value);
};
const getInitialValue = () => initialValue;
(0, vue.watch)(() => props.error, (val) => {
validateMessage.value = val || "";
setValidationState(val ? "error" : "");
}, { immediate: true });
(0, vue.watch)(() => props.validateStatus, (val) => setValidationState(val || ""));
const context = (0, vue.reactive)({
...(0, vue.toRefs)(props),
$el: formItemRef,
size: _size,
validateMessage,
validateState,
labelId,
inputIds,
isGroup,
hasLabel,
fieldValue,
addInputId,
removeInputId,
resetField,
clearValidate,
validate,
propString,
setInitialValue,
getInitialValue
});
(0, vue.provide)(require_constants.formItemContextKey, context);
(0, vue.watch)(propString, (newPropString, oldPropString) => {
if (!formContext || !oldPropString) return;
formContext.removeField(context, oldPropString);
if (newPropString) {
setInitialValue(fieldValue.value);
formContext.addField(context);
}
});
(0, vue.onMounted)(() => {
if (props.prop) {
setInitialValue(fieldValue.value);
formContext?.addField(context);
}
});
(0, vue.onBeforeUnmount)(() => {
formContext?.removeField(context);
});
__expose({
size: _size,
validateMessage,
validateState,
validate,
clearValidate,
resetField,
setInitialValue
});
return (_ctx, _cache) => {
return (0, vue.openBlock)(), (0, vue.createElementBlock)("div", {
ref_key: "formItemRef",
ref: formItemRef,
class: (0, vue.normalizeClass)(formItemClasses.value),
role: isGroup.value ? "group" : void 0,
"aria-labelledby": isGroup.value ? (0, vue.unref)(labelId) : void 0
}, [(0, vue.createVNode)((0, vue.unref)(require_form_label_wrap.default), {
"is-auto-width": labelStyle.value.width === "auto",
"update-all": (0, vue.unref)(formContext)?.labelWidth === "auto"
}, {
default: (0, vue.withCtx)(() => [!!(__props.label || _ctx.$slots.label) ? ((0, vue.openBlock)(), (0, vue.createBlock)((0, vue.resolveDynamicComponent)(labelFor.value ? "label" : "div"), {
key: 0,
id: (0, vue.unref)(labelId),
for: labelFor.value,
class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("label")),
style: (0, vue.normalizeStyle)(labelStyle.value)
}, {
default: (0, vue.withCtx)(() => [(0, vue.renderSlot)(_ctx.$slots, "label", { label: currentLabel.value }, () => [(0, vue.createTextVNode)((0, vue.toDisplayString)(currentLabel.value), 1)])]),
_: 3
}, 8, [
"id",
"for",
"class",
"style"
])) : (0, vue.createCommentVNode)("v-if", true)]),
_: 3
}, 8, ["is-auto-width", "update-all"]), (0, vue.createElementVNode)("div", {
class: (0, vue.normalizeClass)((0, vue.unref)(ns).e("content")),
style: (0, vue.normalizeStyle)(contentStyle.value)
}, [(0, vue.renderSlot)(_ctx.$slots, "default"), (0, vue.createVNode)(vue.TransitionGroup, { name: `${(0, vue.unref)(ns).namespace.value}-zoom-in-top` }, {
default: (0, vue.withCtx)(() => [shouldShowError.value ? (0, vue.renderSlot)(_ctx.$slots, "error", {
key: 0,
error: validateMessage.value
}, () => [(0, vue.createElementVNode)("div", { class: (0, vue.normalizeClass)(validateClasses.value) }, (0, vue.toDisplayString)(validateMessage.value), 3)]) : (0, vue.createCommentVNode)("v-if", true)]),
_: 3
}, 8, ["name"])], 6)], 10, _hoisted_1);
};
}
});
//#endregion
exports.default = form_item_vue_vue_type_script_setup_true_lang_default;
//# sourceMappingURL=form-item.vue_vue_type_script_setup_true_lang.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,9 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_form_item_vue_vue_type_script_setup_true_lang = require('./form-item.vue_vue_type_script_setup_true_lang.js');
//#region ../../packages/components/form/src/form-item.vue
var form_item_default = require_form_item_vue_vue_type_script_setup_true_lang.default;
//#endregion
exports.default = form_item_default;
//# sourceMappingURL=form-item2.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,73 @@
const require_runtime = require('../../../_virtual/_rolldown/runtime.js');
const require_error = require('../../../utils/error.js');
const require_index = require('../../../hooks/use-namespace/index.js');
const require_constants = require('./constants.js');
let _vueuse_core = require("@vueuse/core");
let vue = require("vue");
//#region ../../packages/components/form/src/form-label-wrap.tsx
const COMPONENT_NAME = "ElLabelWrap";
var form_label_wrap_default = /* @__PURE__ */ (0, vue.defineComponent)({
name: COMPONENT_NAME,
props: {
isAutoWidth: Boolean,
updateAll: Boolean
},
setup(props, { slots }) {
const formContext = (0, vue.inject)(require_constants.formContextKey, void 0);
const formItemContext = (0, vue.inject)(require_constants.formItemContextKey);
if (!formItemContext) require_error.throwError(COMPONENT_NAME, "usage: <el-form-item><label-wrap /></el-form-item>");
const ns = require_index.useNamespace("form");
const el = (0, vue.ref)();
const computedWidth = (0, vue.ref)(0);
const getLabelWidth = () => {
if (el.value?.firstElementChild) {
const width = window.getComputedStyle(el.value.firstElementChild).width;
return Math.ceil(Number.parseFloat(width));
} else return 0;
};
const updateLabelWidth = (action = "update") => {
(0, vue.nextTick)(() => {
if (slots.default && props.isAutoWidth) {
if (action === "update") computedWidth.value = getLabelWidth();
else if (action === "remove") formContext?.deregisterLabelWidth(computedWidth.value);
}
});
};
const updateLabelWidthFn = () => updateLabelWidth("update");
(0, vue.onMounted)(() => {
updateLabelWidthFn();
});
(0, vue.onBeforeUnmount)(() => {
updateLabelWidth("remove");
});
(0, vue.onUpdated)(() => updateLabelWidthFn());
(0, vue.watch)(computedWidth, (val, oldVal) => {
if (props.updateAll) formContext?.registerLabelWidth(val, oldVal);
});
(0, _vueuse_core.useResizeObserver)((0, vue.computed)(() => el.value?.firstElementChild ?? null), updateLabelWidthFn);
return () => {
if (!slots) return null;
const { isAutoWidth } = props;
if (isAutoWidth) {
const autoLabelWidth = formContext?.autoLabelWidth;
const hasLabel = formItemContext?.hasLabel;
const style = {};
if (hasLabel && autoLabelWidth && autoLabelWidth !== "auto") {
const marginWidth = Math.max(0, Number.parseInt(autoLabelWidth, 10) - computedWidth.value);
const marginPosition = (formItemContext.labelPosition || formContext.labelPosition) === "left" ? "marginRight" : "marginLeft";
if (marginWidth) style[marginPosition] = `${marginWidth}px`;
}
return (0, vue.createVNode)("div", {
"ref": el,
"class": [ns.be("item", "label-wrap")],
"style": style
}, [slots.default?.()]);
} else return (0, vue.createVNode)(vue.Fragment, { "ref": el }, [slots.default?.()]);
};
}
});
//#endregion
exports.default = form_label_wrap_default;
//# sourceMappingURL=form-label-wrap.js.map
File diff suppressed because one or more lines are too long
+135
View File
@@ -0,0 +1,135 @@
import { EpPropFinalized, EpPropMergeType } from "../../../utils/vue/props/types.js";
import { ComponentSize } from "../../../constants/size.js";
import { Arrayable } from "../../../utils/typescript.js";
import "../../../utils/index.js";
import { FormItemProp } from "./form-item.js";
import { FormItemRule, FormRules } from "./types.js";
import * as vue from "vue";
import { ExtractPublicPropTypes } from "vue";
//#region ../../packages/components/form/src/form.d.ts
interface FormMetaProps {
/**
* @description Control the size of components in this form.
*/
size?: ComponentSize;
/**
* @description Whether to disable all components in this form. If set to `true`, it will override the `disabled` prop of the inner component.
*/
disabled?: boolean;
}
/**
* @deprecated Removed after 3.0.0, Use `FormMetaProps` instead.
*/
declare const formMetaProps: {
readonly size: {
readonly type: vue.PropType<EpPropMergeType<StringConstructor, "" | "default" | "small" | "large", unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly disabled: BooleanConstructor;
};
interface FormProps extends FormMetaProps {
/**
* @description Data of form component.
*/
model?: Record<string, any>;
/**
* @description Validation rules of form.
*/
rules?: FormRules;
/**
* @description Position of label. If set to `'left'` or `'right'`, `label-width` prop is also required.
*/
labelPosition?: 'left' | 'right' | 'top';
/**
* @description Position of asterisk.
*/
requireAsteriskPosition?: 'left' | 'right';
/**
* @description Width of label, e.g. `'50px'`. All its direct child form items will inherit this value. `auto` is supported.
*/
labelWidth?: string | number;
/**
* @description Suffix of the label.
*/
labelSuffix?: string;
/**
* @description Whether the form is inline.
*/
inline?: boolean;
/**
* @description Whether to display the error message inline with the form item.
*/
inlineMessage?: boolean;
/**
* @description Whether to display an icon indicating the validation result.
*/
statusIcon?: boolean;
/**
* @description Whether to show the error message.
*/
showMessage?: boolean;
/**
* @description Whether to trigger validation when the `rules` prop is changed.
*/
validateOnRuleChange?: boolean;
/**
* @description Whether to hide required fields should have a red asterisk (star) beside their labels.
*/
hideRequiredAsterisk?: boolean;
/**
* @description When validation fails, scroll to the first error form entry.
*/
scrollToError?: boolean;
/**
* @description When validation fails, it scrolls to the first error item based on the scrollIntoView option.
*/
scrollIntoViewOptions?: ScrollIntoViewOptions | boolean;
}
/**
* @deprecated Removed after 3.0.0, Use `FormProps` instead.
*/
declare const formProps: {
readonly model: ObjectConstructor;
readonly rules: {
readonly type: vue.PropType<Partial<Record<string, Record<string, any> | Arrayable<FormItemRule>>>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly labelPosition: EpPropFinalized<StringConstructor, "top" | "left" | "right", unknown, "right", boolean>;
readonly requireAsteriskPosition: EpPropFinalized<StringConstructor, "left" | "right", unknown, "left", boolean>;
readonly labelWidth: EpPropFinalized<readonly [StringConstructor, NumberConstructor], unknown, unknown, "", boolean>;
readonly labelSuffix: EpPropFinalized<StringConstructor, unknown, unknown, "", boolean>;
readonly inline: BooleanConstructor;
readonly inlineMessage: BooleanConstructor;
readonly statusIcon: BooleanConstructor;
readonly showMessage: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly validateOnRuleChange: EpPropFinalized<BooleanConstructor, unknown, unknown, true, boolean>;
readonly hideRequiredAsterisk: BooleanConstructor;
readonly scrollToError: BooleanConstructor;
readonly scrollIntoViewOptions: EpPropFinalized<(new (...args: any[]) => boolean | ScrollIntoViewOptions) | (() => boolean | ScrollIntoViewOptions) | (((new (...args: any[]) => boolean | ScrollIntoViewOptions) | (() => boolean | ScrollIntoViewOptions)) | null)[], unknown, unknown, true, boolean>;
readonly size: {
readonly type: vue.PropType<EpPropMergeType<StringConstructor, "" | "default" | "small" | "large", unknown>>;
readonly required: false;
readonly validator: ((val: unknown) => boolean) | undefined;
__epPropKey: true;
};
readonly disabled: BooleanConstructor;
};
/**
* @deprecated Removed after 3.0.0, Use `FormProps` instead.
*/
type FormPropsPublic = ExtractPublicPropTypes<typeof formProps>;
/**
* @deprecated Removed after 3.0.0, Use `FormMetaProps` instead.
*/
type FormMetaPropsPublic = ExtractPublicPropTypes<typeof formMetaProps>;
declare const formEmits: {
validate: (prop: FormItemProp, isValid: boolean, message: string) => boolean;
};
type FormEmits = typeof formEmits;
//#endregion
export { FormEmits, FormMetaProps, FormMetaPropsPublic, FormProps, FormPropsPublic, formEmits, formMetaProps, formProps };
+72
View File
@@ -0,0 +1,72 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../../../_virtual/_rolldown/runtime.js');
const require_size = require('../../../constants/size.js');
const require_types = require('../../../utils/types.js');
const require_runtime$1 = require('../../../utils/vue/props/runtime.js');
let _vue_shared = require("@vue/shared");
//#region ../../packages/components/form/src/form.ts
/**
* @deprecated Removed after 3.0.0, Use `FormMetaProps` instead.
*/
const formMetaProps = require_runtime$1.buildProps({
size: {
type: String,
values: require_size.componentSizes
},
disabled: Boolean
});
/**
* @deprecated Removed after 3.0.0, Use `FormProps` instead.
*/
const formProps = require_runtime$1.buildProps({
...formMetaProps,
model: Object,
rules: { type: require_runtime$1.definePropType(Object) },
labelPosition: {
type: String,
values: [
"left",
"right",
"top"
],
default: "right"
},
requireAsteriskPosition: {
type: String,
values: ["left", "right"],
default: "left"
},
labelWidth: {
type: [String, Number],
default: ""
},
labelSuffix: {
type: String,
default: ""
},
inline: Boolean,
inlineMessage: Boolean,
statusIcon: Boolean,
showMessage: {
type: Boolean,
default: true
},
validateOnRuleChange: {
type: Boolean,
default: true
},
hideRequiredAsterisk: Boolean,
scrollToError: Boolean,
scrollIntoViewOptions: {
type: require_runtime$1.definePropType([Object, Boolean]),
default: true
}
});
const formEmits = { validate: (prop, isValid, message) => ((0, _vue_shared.isArray)(prop) || (0, _vue_shared.isString)(prop)) && require_types.isBoolean(isValid) && (0, _vue_shared.isString)(message) };
//#endregion
exports.formEmits = formEmits;
exports.formMetaProps = formMetaProps;
exports.formProps = formProps;
//# sourceMappingURL=form.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,67 @@
import { Arrayable } from "../../../utils/typescript.js";
import "../../../utils/index.js";
import { FormItemProp } from "./form-item.js";
import { FormItemContext, FormValidateCallback, FormValidationResult } from "./types.js";
import { FormProps } from "./form.js";
import * as vue from "vue";
//#region ../../packages/components/form/src/form.vue.d.ts
declare var __VLS_1: {};
type __VLS_Slots = {} & {
default?: (props: typeof __VLS_1) => any;
};
declare const __VLS_base: vue.DefineComponent<FormProps, {
/**
* @description Validate the whole form. Receives a callback or returns `Promise`.
*/
validate: (callback?: FormValidateCallback) => FormValidationResult;
/**
* @description Validate specified fields.
*/
validateField: (props?: Arrayable<FormItemProp>, callback?: FormValidateCallback) => FormValidationResult;
/**
* @description Reset specified fields and remove validation result.
*/
resetFields: (props?: Arrayable<FormItemProp>) => void;
/**
* @description Clear validation message for specified fields.
*/
clearValidate: (props?: Arrayable<FormItemProp>) => void;
/**
* @description Scroll to the specified fields.
*/
scrollToField: (prop: FormItemProp) => void;
/**
* @description Get a field context.
*/
getField: (prop: FormItemProp) => FormItemContext | undefined;
/**
* @description All fields context.
*/
fields: vue.Reactive<FormItemContext[]>;
/**
* @description Set initial values for form fields. When `resetFields` is called, fields will reset to these values.
*/
setInitialValues: (initModel: Record<string, any>) => void;
}, {}, {}, {}, vue.ComponentOptionsMixin, vue.ComponentOptionsMixin, {
validate: (prop: FormItemProp, isValid: boolean, message: string) => void;
}, string, vue.PublicProps, Readonly<FormProps> & Readonly<{
onValidate?: ((prop: FormItemProp, isValid: boolean, message: string) => any) | undefined;
}>, {
labelWidth: string | number;
labelPosition: "left" | "right" | "top";
requireAsteriskPosition: "left" | "right";
labelSuffix: string;
showMessage: boolean;
validateOnRuleChange: boolean;
scrollIntoViewOptions: ScrollIntoViewOptions | 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 };
@@ -0,0 +1,178 @@
const require_runtime = require('../../../_virtual/_rolldown/runtime.js');
const require_objects = require('../../../utils/objects.js');
const require_error = require('../../../utils/error.js');
const require_index = require('../../../hooks/use-namespace/index.js');
const require_form = require('./form.js');
const require_constants = require('./constants.js');
const require_use_form_common_props = require('./hooks/use-form-common-props.js');
const require_utils = require('./utils.js');
let lodash_unified = require("lodash-unified");
let vue = require("vue");
let _vue_shared = require("@vue/shared");
//#region ../../packages/components/form/src/form.vue?vue&type=script&setup=true&lang.ts
const COMPONENT_NAME = "ElForm";
var form_vue_vue_type_script_setup_true_lang_default = /* @__PURE__ */ (0, vue.defineComponent)({
name: COMPONENT_NAME,
__name: "form",
props: require_form.formProps,
emits: require_form.formEmits,
setup(__props, { expose: __expose, emit: __emit }) {
const props = __props;
const emit = __emit;
const formRef = (0, vue.ref)();
const fields = (0, vue.reactive)([]);
const initialValues = /* @__PURE__ */ new Map();
const formSize = require_use_form_common_props.useFormSize();
const ns = require_index.useNamespace("form");
const formClasses = (0, vue.computed)(() => {
const { labelPosition, inline } = props;
return [
ns.b(),
ns.m(formSize.value || "default"),
{
[ns.m(`label-${labelPosition}`)]: labelPosition,
[ns.m("inline")]: inline
}
];
});
const getField = (prop) => {
return require_utils.filterFields(fields, [prop])[0];
};
const addField = (field) => {
if (!fields.includes(field)) fields.push(field);
if (field.propString) if (initialValues.has(field.propString)) field.setInitialValue(initialValues.get(field.propString));
else initialValues.set(field.propString, (0, lodash_unified.cloneDeep)(field.fieldValue));
};
const removeField = (field, oldPropString) => {
if (oldPropString) {
initialValues.delete(oldPropString);
return;
}
const idx = fields.indexOf(field);
if (idx > -1) {
fields.splice(idx, 1);
if (field.propString) initialValues.set(field.propString, (0, lodash_unified.cloneDeep)(field.getInitialValue()));
}
};
const setInitialValues = (initModel) => {
if (!props.model) {
require_error.debugWarn(COMPONENT_NAME, "model is required for setInitialValues to work.");
return;
}
if (!initModel) {
require_error.debugWarn(COMPONENT_NAME, "initModel is required for setInitialValues to work.");
return;
}
for (const key of initialValues.keys()) initialValues.set(key, (0, lodash_unified.cloneDeep)(require_objects.getProp(initModel, key).value));
fields.forEach((field) => {
if (field.prop) field.setInitialValue(require_objects.getProp(initModel, field.prop).value);
});
};
const resetFields = (properties = []) => {
if (!props.model) {
require_error.debugWarn(COMPONENT_NAME, "model is required for resetFields to work.");
return;
}
require_utils.filterFields(fields, properties).forEach((field) => field.resetField());
const activePropStrings = new Set(fields.map((f) => f.propString).filter(Boolean));
const propsToCheck = properties.length > 0 ? (0, lodash_unified.castArray)(properties).map((p) => (0, _vue_shared.isArray)(p) ? p.join(".") : p) : [...initialValues.keys()];
for (const propString of propsToCheck) if (!activePropStrings.has(propString) && initialValues.has(propString)) require_objects.getProp(props.model, propString).value = (0, lodash_unified.cloneDeep)(initialValues.get(propString));
};
const clearValidate = (props = []) => {
require_utils.filterFields(fields, props).forEach((field) => field.clearValidate());
};
const isValidatable = (0, vue.computed)(() => {
const hasModel = !!props.model;
if (!hasModel) require_error.debugWarn(COMPONENT_NAME, "model is required for validate to work.");
return hasModel;
});
const obtainValidateFields = (props) => {
if (fields.length === 0) return [];
const filteredFields = require_utils.filterFields(fields, props);
if (!filteredFields.length) {
require_error.debugWarn(COMPONENT_NAME, "please pass correct props!");
return [];
}
return filteredFields;
};
const validate = async (callback) => validateField(void 0, callback);
const doValidateField = async (props = []) => {
if (!isValidatable.value) return false;
const fields = obtainValidateFields(props);
if (fields.length === 0) return true;
let validationErrors = {};
for (const field of fields) try {
await field.validate("");
if (field.validateState === "error" && !field.error) field.resetField();
} catch (fields) {
validationErrors = {
...validationErrors,
...fields
};
}
if (Object.keys(validationErrors).length === 0) return true;
return Promise.reject(validationErrors);
};
const validateField = async (modelProps = [], callback) => {
let result = false;
const shouldThrow = !(0, _vue_shared.isFunction)(callback);
try {
result = await doValidateField(modelProps);
if (result === true) await callback?.(result);
return result;
} catch (e) {
if (e instanceof Error) throw e;
const invalidFields = e;
if (props.scrollToError) {
if (formRef.value) formRef.value.querySelector(`.${ns.b()}-item.is-error`)?.scrollIntoView(props.scrollIntoViewOptions);
}
!result && await callback?.(false, invalidFields);
return shouldThrow && Promise.reject(invalidFields);
}
};
const scrollToField = (prop) => {
const field = getField(prop);
if (field) field.$el?.scrollIntoView(props.scrollIntoViewOptions);
};
(0, vue.watch)(() => props.rules, () => {
if (props.validateOnRuleChange) validate().catch((err) => require_error.debugWarn(err));
}, {
deep: true,
flush: "post"
});
(0, vue.provide)(require_constants.formContextKey, (0, vue.reactive)({
...(0, vue.toRefs)(props),
emit,
resetFields,
clearValidate,
validateField,
getField,
addField,
removeField,
setInitialValues,
...require_utils.useFormLabelWidth()
}));
__expose({
validate,
validateField,
resetFields,
clearValidate,
scrollToField,
getField,
fields,
setInitialValues
});
return (_ctx, _cache) => {
return (0, vue.openBlock)(), (0, vue.createElementBlock)("form", {
ref_key: "formRef",
ref: formRef,
class: (0, vue.normalizeClass)(formClasses.value)
}, [(0, vue.renderSlot)(_ctx.$slots, "default")], 2);
};
}
});
//#endregion
exports.default = form_vue_vue_type_script_setup_true_lang_default;
//# sourceMappingURL=form.vue_vue_type_script_setup_true_lang.js.map
File diff suppressed because one or more lines are too long
+9
View File
@@ -0,0 +1,9 @@
Object.defineProperties(exports, { __esModule: { value: true }, [Symbol.toStringTag]: { value: 'Module' } });
const require_form_vue_vue_type_script_setup_true_lang = require('./form.vue_vue_type_script_setup_true_lang.js');
//#region ../../packages/components/form/src/form.vue
var form_default = require_form_vue_vue_type_script_setup_true_lang.default;
//#endregion
exports.default = form_default;
//# sourceMappingURL=form2.js.map
File diff suppressed because one or more lines are too long
@@ -0,0 +1,3 @@
import { useDisabled, useFormDisabled, useFormSize, useSize } from "./use-form-common-props.js";
import { IUseFormItemInputCommonProps, useFormItem, useFormItemInputId } from "./use-form-item.js";
export { IUseFormItemInputCommonProps, useDisabled, useFormDisabled, useFormItem, useFormItemInputId, useFormSize, useSize };
@@ -0,0 +1,10 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_use_form_common_props = require('./use-form-common-props.js');
const require_use_form_item = require('./use-form-item.js');
exports.useDisabled = require_use_form_common_props.useDisabled;
exports.useFormDisabled = require_use_form_common_props.useFormDisabled;
exports.useFormItem = require_use_form_item.useFormItem;
exports.useFormItemInputId = require_use_form_item.useFormItemInputId;
exports.useFormSize = require_use_form_common_props.useFormSize;
exports.useSize = require_use_form_common_props.useSize;
@@ -0,0 +1,11 @@
import { ComponentSize } from "../../../../constants/size.js";
import * as vue from "vue";
import { MaybeRef } from "@vueuse/core";
//#region ../../packages/components/form/src/hooks/use-form-common-props.d.ts
declare const useFormSize: (fallback?: MaybeRef<ComponentSize | undefined>, ignore?: Partial<Record<"prop" | "form" | "formItem" | "global", boolean>>) => vue.ComputedRef<"" | "default" | "small" | "large">;
declare const useFormDisabled: (fallback?: MaybeRef<boolean | undefined>) => vue.ComputedRef<boolean>;
declare const useSize: (fallback?: MaybeRef<ComponentSize | undefined>, ignore?: Partial<Record<"prop" | "form" | "formItem" | "global", boolean>>) => vue.ComputedRef<"" | "default" | "small" | "large">;
declare const useDisabled: (fallback?: MaybeRef<boolean | undefined>) => vue.ComputedRef<boolean>;
//#endregion
export { useDisabled, useFormDisabled, useFormSize, useSize };
@@ -0,0 +1,32 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../../../../_virtual/_rolldown/runtime.js');
const require_index = require('../../../../hooks/use-prop/index.js');
const require_index$1 = require('../../../../hooks/use-size/index.js');
const require_constants = require('../constants.js');
let vue = require("vue");
//#region ../../packages/components/form/src/hooks/use-form-common-props.ts
const useFormSize = (fallback, ignore = {}) => {
const emptyRef = (0, vue.ref)(void 0);
const size = ignore.prop ? emptyRef : require_index.useProp("size");
const globalConfig = ignore.global ? emptyRef : require_index$1.useGlobalSize();
const form = ignore.form ? { size: void 0 } : (0, vue.inject)(require_constants.formContextKey, void 0);
const formItem = ignore.formItem ? { size: void 0 } : (0, vue.inject)(require_constants.formItemContextKey, void 0);
return (0, vue.computed)(() => size.value || (0, vue.unref)(fallback) || formItem?.size || form?.size || globalConfig.value || "");
};
const useFormDisabled = (fallback) => {
const disabled = require_index.useProp("disabled");
const form = (0, vue.inject)(require_constants.formContextKey, void 0);
return (0, vue.computed)(() => {
return disabled.value ?? (0, vue.unref)(fallback) ?? form?.disabled ?? false;
});
};
const useSize = useFormSize;
const useDisabled = useFormDisabled;
//#endregion
exports.useDisabled = useDisabled;
exports.useFormDisabled = useFormDisabled;
exports.useFormSize = useFormSize;
exports.useSize = useSize;
//# sourceMappingURL=use-form-common-props.js.map
@@ -0,0 +1 @@
{"version":3,"file":"use-form-common-props.js","names":["useProp","useGlobalSize","formContextKey","formItemContextKey"],"sources":["../../../../../../../packages/components/form/src/hooks/use-form-common-props.ts"],"sourcesContent":["import { computed, inject, ref, unref } from 'vue'\nimport { useGlobalSize } from '@element-plus/hooks/use-size'\nimport { useProp } from '@element-plus/hooks/use-prop'\nimport { formContextKey, formItemContextKey } from '../constants'\n\nimport type { ComponentSize } from '@element-plus/constants'\nimport type { MaybeRef } from '@vueuse/core'\n\nexport const useFormSize = (\n fallback?: MaybeRef<ComponentSize | undefined>,\n ignore: Partial<Record<'prop' | 'form' | 'formItem' | 'global', boolean>> = {}\n) => {\n const emptyRef = ref(undefined)\n\n const size = ignore.prop ? emptyRef : useProp<ComponentSize>('size')\n const globalConfig = ignore.global ? emptyRef : useGlobalSize()\n const form = ignore.form\n ? { size: undefined }\n : inject(formContextKey, undefined)\n const formItem = ignore.formItem\n ? { size: undefined }\n : inject(formItemContextKey, undefined)\n\n return computed(\n (): ComponentSize =>\n size.value ||\n unref(fallback) ||\n formItem?.size ||\n form?.size ||\n globalConfig.value ||\n ''\n )\n}\n\nexport const useFormDisabled = (fallback?: MaybeRef<boolean | undefined>) => {\n const disabled = useProp<boolean>('disabled')\n const form = inject(formContextKey, undefined)\n\n return computed(() => {\n return disabled.value ?? unref(fallback) ?? form?.disabled ?? false\n })\n}\n\n// These exports are used for preventing breaking changes\nexport const useSize = useFormSize\nexport const useDisabled = useFormDisabled\n"],"mappings":";;;;;;;;AAQA,MAAa,eACX,UACA,SAA4E,EAAE,KAC3E;CACH,MAAM,wBAAe,OAAU;CAE/B,MAAM,OAAO,OAAO,OAAO,WAAWA,sBAAuB,OAAO;CACpE,MAAM,eAAe,OAAO,SAAS,WAAWC,+BAAe;CAC/D,MAAM,OAAO,OAAO,OAChB,EAAE,MAAM,QAAW,mBACZC,kCAAgB,OAAU;CACrC,MAAM,WAAW,OAAO,WACpB,EAAE,MAAM,QAAW,mBACZC,sCAAoB,OAAU;AAEzC,gCAEI,KAAK,wBACC,SAAS,IACf,UAAU,QACV,MAAM,QACN,aAAa,SACb,GACH;;AAGH,MAAa,mBAAmB,aAA6C;CAC3E,MAAM,WAAWH,sBAAiB,WAAW;CAC7C,MAAM,uBAAcE,kCAAgB,OAAU;AAE9C,gCAAsB;AACpB,SAAO,SAAS,wBAAe,SAAS,IAAI,MAAM,YAAY;GAC9D;;AAIJ,MAAa,UAAU;AACvB,MAAa,cAAc"}
@@ -0,0 +1,27 @@
import { FormContext, FormItemContext } from "../types.js";
import { ComputedRef, Ref } from "vue";
//#region ../../packages/components/form/src/hooks/use-form-item.d.ts
declare const useFormItem: () => {
form: FormContext | undefined;
formItem: FormItemContext | undefined;
};
type IUseFormItemInputCommonProps = {
id?: string;
label?: string | number | boolean | Record<string, any>;
ariaLabel?: string | number | boolean | Record<string, any>;
};
declare const useFormItemInputId: (props: Partial<IUseFormItemInputCommonProps>, {
formItemContext,
disableIdGeneration,
disableIdManagement
}: {
formItemContext?: FormItemContext;
disableIdGeneration?: ComputedRef<boolean> | Ref<boolean>;
disableIdManagement?: ComputedRef<boolean> | Ref<boolean>;
}) => {
isLabeledByFormItem: ComputedRef<boolean>;
inputId: Ref<string | undefined, string | undefined>;
};
//#endregion
export { IUseFormItemInputCommonProps, useFormItem, useFormItemInputId };
@@ -0,0 +1,57 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../../../../_virtual/_rolldown/runtime.js');
const require_index = require('../../../../hooks/use-id/index.js');
const require_constants = require('../constants.js');
let vue = require("vue");
//#region ../../packages/components/form/src/hooks/use-form-item.ts
const useFormItem = () => {
return {
form: (0, vue.inject)(require_constants.formContextKey, void 0),
formItem: (0, vue.inject)(require_constants.formItemContextKey, void 0)
};
};
const useFormItemInputId = (props, { formItemContext, disableIdGeneration, disableIdManagement }) => {
if (!disableIdGeneration) disableIdGeneration = (0, vue.ref)(false);
if (!disableIdManagement) disableIdManagement = (0, vue.ref)(false);
const instance = (0, vue.getCurrentInstance)();
const inLabel = () => {
let parent = instance?.parent;
while (parent) {
if (parent.type.name === "ElFormItem") return false;
if (parent.type.name === "ElLabelWrap") return true;
parent = parent.parent;
}
return false;
};
const inputId = (0, vue.ref)();
let idUnwatch = void 0;
const isLabeledByFormItem = (0, vue.computed)(() => {
return !!(!(props.label || props.ariaLabel) && formItemContext && formItemContext.inputIds && formItemContext.inputIds?.length <= 1);
});
(0, vue.onMounted)(() => {
idUnwatch = (0, vue.watch)([(0, vue.toRef)(props, "id"), disableIdGeneration], ([id, disableIdGeneration]) => {
const newId = id ?? (!disableIdGeneration ? require_index.useId().value : void 0);
if (newId !== inputId.value) {
if (formItemContext?.removeInputId && !inLabel()) {
inputId.value && formItemContext.removeInputId(inputId.value);
if (!disableIdManagement?.value && !disableIdGeneration && newId) formItemContext.addInputId(newId);
}
inputId.value = newId;
}
}, { immediate: true });
});
(0, vue.onUnmounted)(() => {
idUnwatch && idUnwatch();
if (formItemContext?.removeInputId) inputId.value && formItemContext.removeInputId(inputId.value);
});
return {
isLabeledByFormItem,
inputId
};
};
//#endregion
exports.useFormItem = useFormItem;
exports.useFormItemInputId = useFormItemInputId;
//# sourceMappingURL=use-form-item.js.map
@@ -0,0 +1 @@
{"version":3,"file":"use-form-item.js","names":["formContextKey","formItemContextKey","useId"],"sources":["../../../../../../../packages/components/form/src/hooks/use-form-item.ts"],"sourcesContent":["import {\n computed,\n getCurrentInstance,\n inject,\n onMounted,\n onUnmounted,\n ref,\n toRef,\n watch,\n} from 'vue'\nimport { useId } from '@element-plus/hooks/use-id'\nimport { formContextKey, formItemContextKey } from '../constants'\n\nimport type { ComputedRef, Ref, WatchStopHandle } from 'vue'\nimport type { FormItemContext } from '../types'\n\nexport const useFormItem = () => {\n const form = inject(formContextKey, undefined)\n const formItem = inject(formItemContextKey, undefined)\n return {\n form,\n formItem,\n }\n}\n\nexport type IUseFormItemInputCommonProps = {\n id?: string\n label?: string | number | boolean | Record<string, any>\n ariaLabel?: string | number | boolean | Record<string, any>\n}\n\nexport const useFormItemInputId = (\n props: Partial<IUseFormItemInputCommonProps>,\n {\n formItemContext,\n disableIdGeneration,\n disableIdManagement,\n }: {\n formItemContext?: FormItemContext\n disableIdGeneration?: ComputedRef<boolean> | Ref<boolean>\n disableIdManagement?: ComputedRef<boolean> | Ref<boolean>\n }\n) => {\n if (!disableIdGeneration) {\n disableIdGeneration = ref<boolean>(false)\n }\n if (!disableIdManagement) {\n disableIdManagement = ref<boolean>(false)\n }\n\n const instance = getCurrentInstance()\n\n const inLabel = () => {\n let parent = instance?.parent\n while (parent) {\n if (parent.type.name === 'ElFormItem') {\n return false\n }\n if (parent.type.name === 'ElLabelWrap') {\n return true\n }\n parent = parent.parent\n }\n return false\n }\n\n const inputId = ref<string>()\n let idUnwatch: WatchStopHandle | undefined = undefined\n\n const isLabeledByFormItem = computed<boolean>(() => {\n return !!(\n !(props.label || props.ariaLabel) &&\n formItemContext &&\n formItemContext.inputIds &&\n formItemContext.inputIds?.length <= 1\n )\n })\n\n // Generate id for ElFormItem label if not provided as prop\n onMounted(() => {\n idUnwatch = watch(\n [toRef(props, 'id'), disableIdGeneration] as any,\n ([id, disableIdGeneration]: [string, boolean]) => {\n const newId = id ?? (!disableIdGeneration ? useId().value : undefined)\n if (newId !== inputId.value) {\n if (formItemContext?.removeInputId && !inLabel()) {\n inputId.value && formItemContext.removeInputId(inputId.value)\n if (!disableIdManagement?.value && !disableIdGeneration && newId) {\n formItemContext.addInputId(newId)\n }\n }\n inputId.value = newId\n }\n },\n { immediate: true }\n )\n })\n\n onUnmounted(() => {\n idUnwatch && idUnwatch()\n if (formItemContext?.removeInputId) {\n inputId.value && formItemContext.removeInputId(inputId.value)\n }\n })\n\n return {\n isLabeledByFormItem,\n inputId,\n }\n}\n"],"mappings":";;;;;;;AAgBA,MAAa,oBAAoB;AAG/B,QAAO;EACL,sBAHkBA,kCAAgB,OAAU;EAI5C,0BAHsBC,sCAAoB,OAAU;EAIrD;;AASH,MAAa,sBACX,OACA,EACE,iBACA,qBACA,0BAMC;AACH,KAAI,CAAC,oBACH,oCAAmC,MAAM;AAE3C,KAAI,CAAC,oBACH,oCAAmC,MAAM;CAG3C,MAAM,wCAA+B;CAErC,MAAM,gBAAgB;EACpB,IAAI,SAAS,UAAU;AACvB,SAAO,QAAQ;AACb,OAAI,OAAO,KAAK,SAAS,aACvB,QAAO;AAET,OAAI,OAAO,KAAK,SAAS,cACvB,QAAO;AAET,YAAS,OAAO;;AAElB,SAAO;;CAGT,MAAM,wBAAuB;CAC7B,IAAI,YAAyC;CAE7C,MAAM,8CAA8C;AAClD,SAAO,CAAC,EACN,EAAE,MAAM,SAAS,MAAM,cACvB,mBACA,gBAAgB,YAChB,gBAAgB,UAAU,UAAU;GAEtC;AAGF,0BAAgB;AACd,6BACE,gBAAO,OAAO,KAAK,EAAE,oBAAoB,GACxC,CAAC,IAAI,yBAA4C;GAChD,MAAM,QAAQ,OAAO,CAAC,sBAAsBC,qBAAO,CAAC,QAAQ;AAC5D,OAAI,UAAU,QAAQ,OAAO;AAC3B,QAAI,iBAAiB,iBAAiB,CAAC,SAAS,EAAE;AAChD,aAAQ,SAAS,gBAAgB,cAAc,QAAQ,MAAM;AAC7D,SAAI,CAAC,qBAAqB,SAAS,CAAC,uBAAuB,MACzD,iBAAgB,WAAW,MAAM;;AAGrC,YAAQ,QAAQ;;KAGpB,EAAE,WAAW,MAAM,CACpB;GACD;AAEF,4BAAkB;AAChB,eAAa,WAAW;AACxB,MAAI,iBAAiB,cACnB,SAAQ,SAAS,gBAAgB,cAAc,QAAQ,MAAM;GAE/D;AAEF,QAAO;EACL;EACA;EACD"}
+54
View File
@@ -0,0 +1,54 @@
import { ComponentSize } from "../../../constants/size.js";
import { Arrayable, FieldPath } from "../../../utils/typescript.js";
import "../../../utils/index.js";
import { FormItemProp, FormItemProps, FormItemValidateState } from "./form-item.js";
import { useFormLabelWidth } from "./utils.js";
import { FormEmits, FormProps } from "./form.js";
import { SetupContext, UnwrapRef } from "vue";
import { MaybeRef } from "@vueuse/core";
import { RuleItem, ValidateError, ValidateFieldsError } from "async-validator";
//#region ../../packages/components/form/src/types.d.ts
type FormLabelWidthContext = ReturnType<typeof useFormLabelWidth>;
interface FormItemRule extends RuleItem {
trigger?: Arrayable<string>;
}
type FormRuleValue<V> = V extends any[] ? Arrayable<FormItemRule> : V extends Record<string, any> ? Arrayable<FormItemRule> | { [K in keyof V]?: FormRuleValue<V[K]> } : Arrayable<FormItemRule>;
type FormRules<T extends MaybeRef<Record<string, any> | string> = string> = UnwrapRef<T> extends Record<string, any> ? { [P in FieldPath<UnwrapRef<T>>]?: P extends keyof UnwrapRef<T> ? FormRuleValue<UnwrapRef<T>[P]> : Arrayable<FormItemRule> } : Partial<Record<string, Arrayable<FormItemRule> | Record<string, any>>>;
type FormValidationResult = Promise<boolean>;
type FormValidateCallback = (isValid: boolean, invalidFields?: ValidateFieldsError) => Promise<void> | void;
interface FormValidateFailure {
errors: ValidateError[] | null;
fields: ValidateFieldsError;
}
type FormContext = FormProps & UnwrapRef<FormLabelWidthContext> & {
emit: SetupContext<FormEmits>['emit'];
getField: (prop: FormItemProp) => FormItemContext | undefined;
addField: (field: FormItemContext) => void;
removeField: (field: FormItemContext, oldPropString?: string) => void;
resetFields: (props?: Arrayable<FormItemProp>) => void;
setInitialValues: (initModel: Record<string, any>) => void;
clearValidate: (props?: Arrayable<FormItemProp>) => void;
validateField: (props?: Arrayable<FormItemProp>, callback?: FormValidateCallback) => FormValidationResult;
};
interface FormItemContext extends FormItemProps {
$el: HTMLDivElement | undefined;
size: ComponentSize;
validateMessage: string;
validateState: FormItemValidateState;
isGroup: boolean;
labelId: string;
inputIds: string[];
hasLabel: boolean;
fieldValue: any;
propString: string;
addInputId: (id: string) => void;
removeInputId: (id: string) => void;
validate: (trigger: string, callback?: FormValidateCallback) => FormValidationResult;
resetField(): void;
clearValidate(): void;
setInitialValue: (value: any) => void;
getInitialValue: () => any;
}
//#endregion
export { FormContext, FormItemContext, FormItemRule, FormLabelWidthContext, FormRules, FormValidateCallback, FormValidateFailure, FormValidationResult };
+1
View File
@@ -0,0 +1 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
+13
View File
@@ -0,0 +1,13 @@
import "../../../utils/index.js";
import "./form-item.js";
import "./types.js";
import * as vue from "vue";
//#region ../../packages/components/form/src/utils.d.ts
declare function useFormLabelWidth(): {
autoLabelWidth: vue.ComputedRef<string>;
registerLabelWidth: (val: number, oldVal: number) => void;
deregisterLabelWidth: (val: number) => void;
};
//#endregion
export { useFormLabelWidth };
+46
View File
@@ -0,0 +1,46 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
const require_runtime = require('../../../_virtual/_rolldown/runtime.js');
const require_error = require('../../../utils/error.js');
let vue = require("vue");
let lodash_unified = require("lodash-unified");
let _vue_shared = require("@vue/shared");
//#region ../../packages/components/form/src/utils.ts
const SCOPE = "ElForm";
function useFormLabelWidth() {
const potentialLabelWidthArr = (0, vue.ref)([]);
const autoLabelWidth = (0, vue.computed)(() => {
if (!potentialLabelWidthArr.value.length) return "0";
const max = Math.max(...potentialLabelWidthArr.value);
return max ? `${max}px` : "";
});
function getLabelWidthIndex(width) {
const index = potentialLabelWidthArr.value.indexOf(width);
if (index === -1 && autoLabelWidth.value === "0") require_error.debugWarn(SCOPE, `unexpected width ${width}`);
return index;
}
function registerLabelWidth(val, oldVal) {
if (val && oldVal) {
const index = getLabelWidthIndex(oldVal);
potentialLabelWidthArr.value.splice(index, 1, val);
} else if (val) potentialLabelWidthArr.value.push(val);
}
function deregisterLabelWidth(val) {
const index = getLabelWidthIndex(val);
if (index > -1) potentialLabelWidthArr.value.splice(index, 1);
}
return {
autoLabelWidth,
registerLabelWidth,
deregisterLabelWidth
};
}
const filterFields = (fields, props) => {
const normalized = (0, lodash_unified.castArray)(props).map((prop) => (0, _vue_shared.isArray)(prop) ? prop.join(".") : prop);
return normalized.length > 0 ? fields.filter((field) => field.propString && normalized.includes(field.propString)) : fields;
};
//#endregion
exports.filterFields = filterFields;
exports.useFormLabelWidth = useFormLabelWidth;
//# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
{"version":3,"file":"utils.js","names":[],"sources":["../../../../../../packages/components/form/src/utils.ts"],"sourcesContent":["import { computed, ref } from 'vue'\nimport { debugWarn, ensureArray, isArray } from '@element-plus/utils'\n\nimport type { Arrayable } from '@element-plus/utils'\nimport type { FormItemContext } from './types'\nimport type { FormItemProp } from './form-item'\n\nconst SCOPE = 'ElForm'\n\nexport function useFormLabelWidth() {\n const potentialLabelWidthArr = ref<number[]>([])\n\n const autoLabelWidth = computed(() => {\n if (!potentialLabelWidthArr.value.length) return '0'\n const max = Math.max(...potentialLabelWidthArr.value)\n return max ? `${max}px` : ''\n })\n\n function getLabelWidthIndex(width: number) {\n const index = potentialLabelWidthArr.value.indexOf(width)\n if (index === -1 && autoLabelWidth.value === '0') {\n debugWarn(SCOPE, `unexpected width ${width}`)\n }\n return index\n }\n\n function registerLabelWidth(val: number, oldVal: number) {\n if (val && oldVal) {\n const index = getLabelWidthIndex(oldVal)\n potentialLabelWidthArr.value.splice(index, 1, val)\n } else if (val) {\n potentialLabelWidthArr.value.push(val)\n }\n }\n\n function deregisterLabelWidth(val: number) {\n const index = getLabelWidthIndex(val)\n if (index > -1) {\n potentialLabelWidthArr.value.splice(index, 1)\n }\n }\n\n return {\n autoLabelWidth,\n registerLabelWidth,\n deregisterLabelWidth,\n }\n}\n\nexport const filterFields = (\n fields: FormItemContext[],\n props: Arrayable<FormItemProp>\n) => {\n const normalized = ensureArray(props).map((prop) =>\n isArray(prop) ? prop.join('.') : prop\n )\n return normalized.length > 0\n ? fields.filter(\n (field) => field.propString && normalized.includes(field.propString)\n )\n : fields\n}\n"],"mappings":";;;;;;;;AAOA,MAAM,QAAQ;AAEd,SAAgB,oBAAoB;CAClC,MAAM,sCAAuC,EAAE,CAAC;CAEhD,MAAM,yCAAgC;AACpC,MAAI,CAAC,uBAAuB,MAAM,OAAQ,QAAO;EACjD,MAAM,MAAM,KAAK,IAAI,GAAG,uBAAuB,MAAM;AACrD,SAAO,MAAM,GAAG,IAAI,MAAM;GAC1B;CAEF,SAAS,mBAAmB,OAAe;EACzC,MAAM,QAAQ,uBAAuB,MAAM,QAAQ,MAAM;AACzD,MAAI,UAAU,MAAM,eAAe,UAAU,IAC3C,yBAAU,OAAO,oBAAoB,QAAQ;AAE/C,SAAO;;CAGT,SAAS,mBAAmB,KAAa,QAAgB;AACvD,MAAI,OAAO,QAAQ;GACjB,MAAM,QAAQ,mBAAmB,OAAO;AACxC,0BAAuB,MAAM,OAAO,OAAO,GAAG,IAAI;aACzC,IACT,wBAAuB,MAAM,KAAK,IAAI;;CAI1C,SAAS,qBAAqB,KAAa;EACzC,MAAM,QAAQ,mBAAmB,IAAI;AACrC,MAAI,QAAQ,GACV,wBAAuB,MAAM,OAAO,OAAO,EAAE;;AAIjD,QAAO;EACL;EACA;EACA;EACD;;AAGH,MAAa,gBACX,QACA,UACG;CACH,MAAM,2CAAyB,MAAM,CAAC,KAAK,kCACjC,KAAK,GAAG,KAAK,KAAK,IAAI,GAAG,KAClC;AACD,QAAO,WAAW,SAAS,IACvB,OAAO,QACJ,UAAU,MAAM,cAAc,WAAW,SAAS,MAAM,WAAW,CACrE,GACD"}
+3
View File
@@ -0,0 +1,3 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
require('../../base/style/css.js');
require("element-plus/theme-chalk/el-form.css");
@@ -0,0 +1,3 @@
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
require('../../base/style/index.js');
require("element-plus/theme-chalk/src/form.scss");