refactor: form
parent
b68bb81652
commit
c2bba2eb28
|
@ -1,3 +1,4 @@
|
||||||
|
import { RequiredMark } from '../../form/Form';
|
||||||
import { computed, ComputedRef, inject, UnwrapRef } from 'vue';
|
import { computed, ComputedRef, inject, UnwrapRef } from 'vue';
|
||||||
import {
|
import {
|
||||||
ConfigProviderProps,
|
ConfigProviderProps,
|
||||||
|
@ -17,6 +18,9 @@ export default (
|
||||||
getTargetContainer: ComputedRef<() => HTMLElement>;
|
getTargetContainer: ComputedRef<() => HTMLElement>;
|
||||||
space: ComputedRef<{ size: SizeType | number }>;
|
space: ComputedRef<{ size: SizeType | number }>;
|
||||||
pageHeader: ComputedRef<{ ghost: boolean }>;
|
pageHeader: ComputedRef<{ ghost: boolean }>;
|
||||||
|
form?: ComputedRef<{
|
||||||
|
requiredMark?: RequiredMark;
|
||||||
|
}>;
|
||||||
} => {
|
} => {
|
||||||
const configProvider = inject<UnwrapRef<ConfigProviderProps>>(
|
const configProvider = inject<UnwrapRef<ConfigProviderProps>>(
|
||||||
'configProvider',
|
'configProvider',
|
||||||
|
@ -26,7 +30,17 @@ export default (
|
||||||
const direction = computed(() => configProvider.direction);
|
const direction = computed(() => configProvider.direction);
|
||||||
const space = computed(() => configProvider.space);
|
const space = computed(() => configProvider.space);
|
||||||
const pageHeader = computed(() => configProvider.pageHeader);
|
const pageHeader = computed(() => configProvider.pageHeader);
|
||||||
|
const form = computed(() => configProvider.form);
|
||||||
const size = computed(() => props.size || configProvider.componentSize);
|
const size = computed(() => props.size || configProvider.componentSize);
|
||||||
const getTargetContainer = computed(() => props.getTargetContainer);
|
const getTargetContainer = computed(() => props.getTargetContainer);
|
||||||
return { configProvider, prefixCls, direction, size, getTargetContainer, space, pageHeader };
|
return {
|
||||||
|
configProvider,
|
||||||
|
prefixCls,
|
||||||
|
direction,
|
||||||
|
size,
|
||||||
|
getTargetContainer,
|
||||||
|
space,
|
||||||
|
pageHeader,
|
||||||
|
form,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
|
@ -13,6 +13,7 @@ import LocaleProvider, { Locale, ANT_MARK } from '../locale-provider';
|
||||||
import { TransformCellTextProps } from '../table/interface';
|
import { TransformCellTextProps } from '../table/interface';
|
||||||
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
import LocaleReceiver from '../locale-provider/LocaleReceiver';
|
||||||
import { withInstall } from '../_util/type';
|
import { withInstall } from '../_util/type';
|
||||||
|
import { RequiredMark } from '../form/Form';
|
||||||
|
|
||||||
export type SizeType = 'small' | 'middle' | 'large' | undefined;
|
export type SizeType = 'small' | 'middle' | 'large' | undefined;
|
||||||
|
|
||||||
|
@ -99,6 +100,9 @@ export const configProviderProps = {
|
||||||
},
|
},
|
||||||
virtual: PropTypes.looseBool,
|
virtual: PropTypes.looseBool,
|
||||||
dropdownMatchSelectWidth: PropTypes.looseBool,
|
dropdownMatchSelectWidth: PropTypes.looseBool,
|
||||||
|
form: {
|
||||||
|
type: Object as PropType<{ requiredMark?: RequiredMark }>,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export type ConfigProviderProps = Partial<ExtractPropTypes<typeof configProviderProps>>;
|
export type ConfigProviderProps = Partial<ExtractPropTypes<typeof configProviderProps>>;
|
||||||
|
@ -159,7 +163,7 @@ const ConfigProvider = defineComponent({
|
||||||
export const defaultConfigProvider: UnwrapRef<ConfigProviderProps> = reactive({
|
export const defaultConfigProvider: UnwrapRef<ConfigProviderProps> = reactive({
|
||||||
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
|
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
|
||||||
if (customizePrefixCls) return customizePrefixCls;
|
if (customizePrefixCls) return customizePrefixCls;
|
||||||
return `ant-${suffixCls}`;
|
return suffixCls ? `ant-${suffixCls}` : 'ant';
|
||||||
},
|
},
|
||||||
renderEmpty: defaultRenderEmpty,
|
renderEmpty: defaultRenderEmpty,
|
||||||
direction: 'ltr',
|
direction: 'ltr',
|
||||||
|
|
|
@ -0,0 +1,53 @@
|
||||||
|
import { useInjectFormItemPrefix } from './context';
|
||||||
|
import { VueNode } from '../_util/type';
|
||||||
|
import { computed, defineComponent, ref, watch } from '@vue/runtime-core';
|
||||||
|
import classNames from '../_util/classNames';
|
||||||
|
import Transition, { getTransitionProps } from '../_util/transition';
|
||||||
|
|
||||||
|
export interface ErrorListProps {
|
||||||
|
errors?: VueNode[];
|
||||||
|
/** @private Internal Usage. Do not use in your production */
|
||||||
|
help?: VueNode;
|
||||||
|
/** @private Internal Usage. Do not use in your production */
|
||||||
|
onDomErrorVisibleChange?: (visible: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default defineComponent<ErrorListProps>({
|
||||||
|
name: 'ErrorList',
|
||||||
|
setup(props) {
|
||||||
|
const { prefixCls, status } = useInjectFormItemPrefix();
|
||||||
|
const visible = computed(() => props.errors && props.errors.length);
|
||||||
|
const innerStatus = ref(status.value);
|
||||||
|
// Memo status in same visible
|
||||||
|
watch([() => visible, () => status], () => {
|
||||||
|
if (visible.value && status.value) {
|
||||||
|
innerStatus.value = status.value;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return () => {
|
||||||
|
const baseClassName = `${prefixCls.value}-item-explain`;
|
||||||
|
const transitionProps = getTransitionProps('show-help', {
|
||||||
|
onAfterLeave: () => props.onDomErrorVisibleChange?.(false),
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<Transition {...transitionProps}>
|
||||||
|
{visible ? (
|
||||||
|
<div
|
||||||
|
class={classNames(baseClassName, {
|
||||||
|
[`${baseClassName}-${innerStatus}`]: innerStatus,
|
||||||
|
})}
|
||||||
|
key="help"
|
||||||
|
>
|
||||||
|
{props.errors?.map((error: any, index: number) => (
|
||||||
|
// eslint-disable-next-line react/no-array-index-key
|
||||||
|
<div key={index} role="alert">
|
||||||
|
{error}
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
|
</Transition>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
|
@ -1,4 +1,12 @@
|
||||||
import { defineComponent, inject, provide, PropType, computed, ExtractPropTypes } from 'vue';
|
import {
|
||||||
|
defineComponent,
|
||||||
|
inject,
|
||||||
|
provide,
|
||||||
|
PropType,
|
||||||
|
computed,
|
||||||
|
ExtractPropTypes,
|
||||||
|
HTMLAttributes,
|
||||||
|
} from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
|
@ -16,6 +24,9 @@ import { tuple, VueNode } from '../_util/type';
|
||||||
import { ColProps } from '../grid/Col';
|
import { ColProps } from '../grid/Col';
|
||||||
import { InternalNamePath, NamePath, ValidateErrorEntity, ValidateOptions } from './interface';
|
import { InternalNamePath, NamePath, ValidateErrorEntity, ValidateOptions } from './interface';
|
||||||
|
|
||||||
|
export type RequiredMark = boolean | 'optional';
|
||||||
|
export type FormLayout = 'horizontal' | 'inline' | 'vertical';
|
||||||
|
|
||||||
export type ValidationRule = {
|
export type ValidationRule = {
|
||||||
/** validation error message */
|
/** validation error message */
|
||||||
message?: VueNode;
|
message?: VueNode;
|
||||||
|
@ -45,11 +56,13 @@ export type ValidationRule = {
|
||||||
|
|
||||||
export const formProps = {
|
export const formProps = {
|
||||||
layout: PropTypes.oneOf(tuple('horizontal', 'inline', 'vertical')),
|
layout: PropTypes.oneOf(tuple('horizontal', 'inline', 'vertical')),
|
||||||
labelCol: { type: Object as PropType<ColProps> },
|
labelCol: { type: Object as PropType<ColProps & HTMLAttributes> },
|
||||||
wrapperCol: { type: Object as PropType<ColProps> },
|
wrapperCol: { type: Object as PropType<ColProps & HTMLAttributes> },
|
||||||
colon: PropTypes.looseBool,
|
colon: PropTypes.looseBool,
|
||||||
labelAlign: PropTypes.oneOf(tuple('left', 'right')),
|
labelAlign: PropTypes.oneOf(tuple('left', 'right')),
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
|
requiredMark: { type: [String, Boolean] as PropType<RequiredMark> },
|
||||||
|
/** @deprecated Will warning in future branch. Pls use `requiredMark` instead. */
|
||||||
hideRequiredMark: PropTypes.looseBool,
|
hideRequiredMark: PropTypes.looseBool,
|
||||||
model: PropTypes.object,
|
model: PropTypes.object,
|
||||||
rules: { type: Object as PropType<{ [k: string]: ValidationRule[] | ValidationRule }> },
|
rules: { type: Object as PropType<{ [k: string]: ValidationRule[] | ValidationRule }> },
|
||||||
|
|
|
@ -36,6 +36,9 @@ import find from 'lodash-es/find';
|
||||||
import { tuple, VueNode } from '../_util/type';
|
import { tuple, VueNode } from '../_util/type';
|
||||||
import { ValidateOptions } from './interface';
|
import { ValidateOptions } from './interface';
|
||||||
|
|
||||||
|
const ValidateStatuses = tuple('success', 'warning', 'error', 'validating', '');
|
||||||
|
export type ValidateStatus = typeof ValidateStatuses[number];
|
||||||
|
|
||||||
const iconMap = {
|
const iconMap = {
|
||||||
success: CheckCircleFilled,
|
success: CheckCircleFilled,
|
||||||
warning: ExclamationCircleFilled,
|
warning: ExclamationCircleFilled,
|
||||||
|
|
|
@ -0,0 +1,108 @@
|
||||||
|
import LoadingOutlined from '@ant-design/icons-vue/LoadingOutlined';
|
||||||
|
import CloseCircleFilled from '@ant-design/icons-vue/CloseCircleFilled';
|
||||||
|
import CheckCircleFilled from '@ant-design/icons-vue/CheckCircleFilled';
|
||||||
|
import ExclamationCircleFilled from '@ant-design/icons-vue/ExclamationCircleFilled';
|
||||||
|
|
||||||
|
import Col, { ColProps } from '../grid/col';
|
||||||
|
import { useProvideForm, useInjectForm, useProvideFormItemPrefix } from './context';
|
||||||
|
import ErrorList from './ErrorList';
|
||||||
|
import classNames from '../_util/classNames';
|
||||||
|
import { ValidateStatus } from './FormItem';
|
||||||
|
import { VueNode } from '../_util/type';
|
||||||
|
import { computed, defineComponent, HTMLAttributes, onUnmounted } from 'vue';
|
||||||
|
|
||||||
|
interface FormItemInputMiscProps {
|
||||||
|
prefixCls: string;
|
||||||
|
errors: VueNode[];
|
||||||
|
hasFeedback?: boolean;
|
||||||
|
validateStatus?: ValidateStatus;
|
||||||
|
onDomErrorVisibleChange: (visible: boolean) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface FormItemInputProps {
|
||||||
|
wrapperCol?: ColProps;
|
||||||
|
help?: VueNode;
|
||||||
|
extra?: VueNode;
|
||||||
|
status?: ValidateStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
const iconMap: { [key: string]: any } = {
|
||||||
|
success: CheckCircleFilled,
|
||||||
|
warning: ExclamationCircleFilled,
|
||||||
|
error: CloseCircleFilled,
|
||||||
|
validating: LoadingOutlined,
|
||||||
|
};
|
||||||
|
const FormItemInput = defineComponent<FormItemInputProps & FormItemInputMiscProps>({
|
||||||
|
slots: ['help', 'extra', 'errors'],
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const formContext = useInjectForm();
|
||||||
|
const { wrapperCol: contextWrapperCol } = formContext;
|
||||||
|
|
||||||
|
// Pass to sub FormItem should not with col info
|
||||||
|
const subFormContext = { ...formContext };
|
||||||
|
delete subFormContext.labelCol;
|
||||||
|
delete subFormContext.wrapperCol;
|
||||||
|
useProvideForm(subFormContext);
|
||||||
|
|
||||||
|
useProvideFormItemPrefix({
|
||||||
|
prefixCls: computed(() => props.prefixCls),
|
||||||
|
status: computed(() => props.status),
|
||||||
|
});
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
const {
|
||||||
|
prefixCls,
|
||||||
|
wrapperCol,
|
||||||
|
help = slots.help?.(),
|
||||||
|
errors = slots.errors?.(),
|
||||||
|
onDomErrorVisibleChange,
|
||||||
|
hasFeedback,
|
||||||
|
validateStatus,
|
||||||
|
extra = slots.extra?.(),
|
||||||
|
} = props;
|
||||||
|
const baseClassName = `${prefixCls}-item`;
|
||||||
|
|
||||||
|
const mergedWrapperCol: ColProps & HTMLAttributes =
|
||||||
|
wrapperCol || contextWrapperCol?.value || {};
|
||||||
|
|
||||||
|
const className = classNames(`${baseClassName}-control`, mergedWrapperCol.class);
|
||||||
|
|
||||||
|
onUnmounted(() => {
|
||||||
|
onDomErrorVisibleChange(false);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Should provides additional icon if `hasFeedback`
|
||||||
|
const IconNode = validateStatus && iconMap[validateStatus];
|
||||||
|
const icon =
|
||||||
|
hasFeedback && IconNode ? (
|
||||||
|
<span class={`${baseClassName}-children-icon`}>
|
||||||
|
<IconNode />
|
||||||
|
</span>
|
||||||
|
) : null;
|
||||||
|
|
||||||
|
const inputDom = (
|
||||||
|
<div class={`${baseClassName}-control-input`}>
|
||||||
|
<div class={`${baseClassName}-control-input-content`}>{slots.default?.()}</div>
|
||||||
|
{icon}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
const errorListDom = (
|
||||||
|
<ErrorList errors={errors} help={help} onDomErrorVisibleChange={onDomErrorVisibleChange} />
|
||||||
|
);
|
||||||
|
|
||||||
|
// If extra = 0, && will goes wrong
|
||||||
|
// 0&&error -> 0
|
||||||
|
const extraDom = extra ? <div class={`${baseClassName}-extra`}>{extra}</div> : null;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Col {...mergedWrapperCol} class={className}>
|
||||||
|
{inputDom}
|
||||||
|
{errorListDom}
|
||||||
|
{extraDom}
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export default FormItemInput;
|
|
@ -0,0 +1,92 @@
|
||||||
|
import Col, { ColProps } from '../grid/col';
|
||||||
|
import { FormLabelAlign } from './interface';
|
||||||
|
import { useInjectForm } from './context';
|
||||||
|
import { RequiredMark } from './Form';
|
||||||
|
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
|
||||||
|
import defaultLocale from '../locale/default';
|
||||||
|
import classNames from '../_util/classNames';
|
||||||
|
import { VueNode } from '../_util/type';
|
||||||
|
import { FunctionalComponent, HTMLAttributes } from 'vue';
|
||||||
|
|
||||||
|
export interface FormItemLabelProps {
|
||||||
|
colon?: boolean;
|
||||||
|
htmlFor?: string;
|
||||||
|
label?: VueNode;
|
||||||
|
labelAlign?: FormLabelAlign;
|
||||||
|
labelCol?: ColProps & HTMLAttributes;
|
||||||
|
requiredMark?: RequiredMark;
|
||||||
|
required?: boolean;
|
||||||
|
prefixCls: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const FormItemLabel: FunctionalComponent<FormItemLabelProps> = (props, { slots }) => {
|
||||||
|
const { prefixCls, htmlFor, labelCol, labelAlign, colon, required, requiredMark } = props;
|
||||||
|
const [formLocale] = useLocaleReceiver('Form');
|
||||||
|
const label = props.label ?? slots.label?.();
|
||||||
|
if (!label) return null;
|
||||||
|
const {
|
||||||
|
vertical,
|
||||||
|
labelAlign: contextLabelAlign,
|
||||||
|
labelCol: contextLabelCol,
|
||||||
|
colon: contextColon,
|
||||||
|
} = useInjectForm();
|
||||||
|
const mergedLabelCol: FormItemLabelProps['labelCol'] = labelCol || contextLabelCol?.value || {};
|
||||||
|
|
||||||
|
const mergedLabelAlign: FormLabelAlign | undefined = labelAlign || contextLabelAlign?.value;
|
||||||
|
|
||||||
|
const labelClsBasic = `${prefixCls}-item-label`;
|
||||||
|
const labelColClassName = classNames(
|
||||||
|
labelClsBasic,
|
||||||
|
mergedLabelAlign === 'left' && `${labelClsBasic}-left`,
|
||||||
|
mergedLabelCol.class,
|
||||||
|
);
|
||||||
|
|
||||||
|
let labelChildren = label;
|
||||||
|
// Keep label is original where there should have no colon
|
||||||
|
const computedColon = colon === true || (contextColon?.value !== false && colon !== false);
|
||||||
|
const haveColon = computedColon && !vertical.value;
|
||||||
|
// Remove duplicated user input colon
|
||||||
|
if (haveColon && typeof label === 'string' && (label as string).trim() !== '') {
|
||||||
|
labelChildren = (label as string).replace(/[:|:]\s*$/, '');
|
||||||
|
}
|
||||||
|
|
||||||
|
labelChildren = (
|
||||||
|
<>
|
||||||
|
{labelChildren}
|
||||||
|
{slots.tooltip?.({ class: `${prefixCls}-item-tooltip` })}
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add required mark if optional
|
||||||
|
if (requiredMark === 'optional' && !required) {
|
||||||
|
labelChildren = (
|
||||||
|
<>
|
||||||
|
{labelChildren}
|
||||||
|
<span class={`${prefixCls}-item-optional`}>
|
||||||
|
{formLocale.value?.optional || defaultLocale.Form?.optional}
|
||||||
|
</span>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const labelClassName = classNames({
|
||||||
|
[`${prefixCls}-item-required`]: required,
|
||||||
|
[`${prefixCls}-item-required-mark-optional`]: requiredMark === 'optional',
|
||||||
|
[`${prefixCls}-item-no-colon`]: !computedColon,
|
||||||
|
});
|
||||||
|
return (
|
||||||
|
<Col {...mergedLabelCol} class={labelColClassName}>
|
||||||
|
<label
|
||||||
|
html-for={htmlFor}
|
||||||
|
class={labelClassName}
|
||||||
|
title={typeof label === 'string' ? label : ''}
|
||||||
|
>
|
||||||
|
{labelChildren}
|
||||||
|
</label>
|
||||||
|
</Col>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
FormItemLabel.displayName = 'FormItemLabel';
|
||||||
|
|
||||||
|
export default FormItemLabel;
|
|
@ -0,0 +1,49 @@
|
||||||
|
import { inject, InjectionKey, provide, ComputedRef, computed } from 'vue';
|
||||||
|
import { ColProps } from '../grid';
|
||||||
|
import { RequiredMark } from './Form';
|
||||||
|
import { ValidateStatus } from './FormItem';
|
||||||
|
import { FormLabelAlign } from './interface';
|
||||||
|
|
||||||
|
export interface FormContextProps {
|
||||||
|
vertical: ComputedRef<boolean>;
|
||||||
|
name?: ComputedRef<string>;
|
||||||
|
colon?: ComputedRef<boolean>;
|
||||||
|
labelAlign?: ComputedRef<FormLabelAlign>;
|
||||||
|
labelCol?: ComputedRef<ColProps>;
|
||||||
|
wrapperCol?: ComputedRef<ColProps>;
|
||||||
|
requiredMark?: ComputedRef<RequiredMark>;
|
||||||
|
//itemRef: (name: (string | number)[]) => (node: React.ReactElement) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FormContextKey: InjectionKey<FormContextProps> = Symbol('formContextKey');
|
||||||
|
|
||||||
|
export const useProvideForm = (state: FormContextProps) => {
|
||||||
|
provide(FormContextKey, state);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useInjectForm = () => {
|
||||||
|
return inject(FormContextKey, {
|
||||||
|
labelAlign: computed(() => 'right' as FormLabelAlign),
|
||||||
|
vertical: computed(() => false),
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
/** Used for ErrorList only */
|
||||||
|
export interface FormItemPrefixContextProps {
|
||||||
|
prefixCls: ComputedRef<string>;
|
||||||
|
status?: ComputedRef<ValidateStatus>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const FormItemPrefixContextKey: InjectionKey<FormItemPrefixContextProps> = Symbol(
|
||||||
|
'formItemPrefixContextKey',
|
||||||
|
);
|
||||||
|
|
||||||
|
export const useProvideFormItemPrefix = (state: FormItemPrefixContextProps) => {
|
||||||
|
provide(FormItemPrefixContextKey, state);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useInjectFormItemPrefix = () => {
|
||||||
|
return inject(FormItemPrefixContextKey, {
|
||||||
|
prefixCls: computed(() => ''),
|
||||||
|
});
|
||||||
|
};
|
|
@ -1,5 +1,7 @@
|
||||||
import { VueNode } from '../_util/type';
|
import { VueNode } from '../_util/type';
|
||||||
|
|
||||||
|
export type FormLabelAlign = 'left' | 'right';
|
||||||
|
|
||||||
export type InternalNamePath = (string | number)[];
|
export type InternalNamePath = (string | number)[];
|
||||||
export type NamePath = string | number | InternalNamePath;
|
export type NamePath = string | number | InternalNamePath;
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ import interopDefault from '../_util/interopDefault';
|
||||||
import { ModalLocale, changeConfirmLocale } from '../modal/locale';
|
import { ModalLocale, changeConfirmLocale } from '../modal/locale';
|
||||||
import warning from '../_util/warning';
|
import warning from '../_util/warning';
|
||||||
import { withInstall } from '../_util/type';
|
import { withInstall } from '../_util/type';
|
||||||
|
import { ValidateMessages } from '../form/interface';
|
||||||
export interface Locale {
|
export interface Locale {
|
||||||
locale: string;
|
locale: string;
|
||||||
Pagination?: Object;
|
Pagination?: Object;
|
||||||
|
@ -17,6 +18,14 @@ export interface Locale {
|
||||||
Transfer?: Object;
|
Transfer?: Object;
|
||||||
Select?: Object;
|
Select?: Object;
|
||||||
Upload?: Object;
|
Upload?: Object;
|
||||||
|
|
||||||
|
Form?: {
|
||||||
|
optional?: string;
|
||||||
|
defaultValidateMessages: ValidateMessages;
|
||||||
|
};
|
||||||
|
Image?: {
|
||||||
|
preview: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LocaleProviderProps {
|
export interface LocaleProviderProps {
|
||||||
|
|
|
@ -3,14 +3,13 @@ import DatePicker from '../date-picker/locale/en_US';
|
||||||
import TimePicker from '../time-picker/locale/en_US';
|
import TimePicker from '../time-picker/locale/en_US';
|
||||||
import Calendar from '../calendar/locale/en_US';
|
import Calendar from '../calendar/locale/en_US';
|
||||||
// import ColorPicker from '../color-picker/locale/en_US';
|
// import ColorPicker from '../color-picker/locale/en_US';
|
||||||
|
const typeTemplate = '${label} is not a valid ${type}';
|
||||||
export default {
|
export default {
|
||||||
locale: 'en',
|
locale: 'en',
|
||||||
Pagination,
|
Pagination,
|
||||||
DatePicker,
|
DatePicker,
|
||||||
TimePicker,
|
TimePicker,
|
||||||
Calendar,
|
Calendar,
|
||||||
// ColorPicker,
|
|
||||||
global: {
|
global: {
|
||||||
placeholder: 'Please select',
|
placeholder: 'Please select',
|
||||||
},
|
},
|
||||||
|
@ -18,11 +17,18 @@ export default {
|
||||||
filterTitle: 'Filter menu',
|
filterTitle: 'Filter menu',
|
||||||
filterConfirm: 'OK',
|
filterConfirm: 'OK',
|
||||||
filterReset: 'Reset',
|
filterReset: 'Reset',
|
||||||
|
filterEmptyText: 'No filters',
|
||||||
|
emptyText: 'No data',
|
||||||
selectAll: 'Select current page',
|
selectAll: 'Select current page',
|
||||||
selectInvert: 'Invert current page',
|
selectInvert: 'Invert current page',
|
||||||
|
selectNone: 'Clear all data',
|
||||||
|
selectionAll: 'Select all data',
|
||||||
sortTitle: 'Sort',
|
sortTitle: 'Sort',
|
||||||
expand: 'Expand row',
|
expand: 'Expand row',
|
||||||
collapse: 'Collapse row',
|
collapse: 'Collapse row',
|
||||||
|
triggerDesc: 'Click to sort descending',
|
||||||
|
triggerAsc: 'Click to sort ascending',
|
||||||
|
cancelSort: 'Click to cancel sorting',
|
||||||
},
|
},
|
||||||
Modal: {
|
Modal: {
|
||||||
okText: 'OK',
|
okText: 'OK',
|
||||||
|
@ -38,6 +44,12 @@ export default {
|
||||||
searchPlaceholder: 'Search here',
|
searchPlaceholder: 'Search here',
|
||||||
itemUnit: 'item',
|
itemUnit: 'item',
|
||||||
itemsUnit: 'items',
|
itemsUnit: 'items',
|
||||||
|
remove: 'Remove',
|
||||||
|
selectCurrent: 'Select current page',
|
||||||
|
removeCurrent: 'Remove current page',
|
||||||
|
selectAll: 'Select all data',
|
||||||
|
removeAll: 'Remove all data',
|
||||||
|
selectInvert: 'Invert current page',
|
||||||
},
|
},
|
||||||
Upload: {
|
Upload: {
|
||||||
uploading: 'Uploading...',
|
uploading: 'Uploading...',
|
||||||
|
@ -61,4 +73,57 @@ export default {
|
||||||
PageHeader: {
|
PageHeader: {
|
||||||
back: 'Back',
|
back: 'Back',
|
||||||
},
|
},
|
||||||
|
Form: {
|
||||||
|
optional: '(optional)',
|
||||||
|
defaultValidateMessages: {
|
||||||
|
default: 'Field validation error for ${label}',
|
||||||
|
required: 'Please enter ${label}',
|
||||||
|
enum: '${label} must be one of [${enum}]',
|
||||||
|
whitespace: '${label} cannot be a blank character',
|
||||||
|
date: {
|
||||||
|
format: '${label} date format is invalid',
|
||||||
|
parse: '${label} cannot be converted to a date',
|
||||||
|
invalid: '${label} is an invalid date',
|
||||||
|
},
|
||||||
|
types: {
|
||||||
|
string: typeTemplate,
|
||||||
|
method: typeTemplate,
|
||||||
|
array: typeTemplate,
|
||||||
|
object: typeTemplate,
|
||||||
|
number: typeTemplate,
|
||||||
|
date: typeTemplate,
|
||||||
|
boolean: typeTemplate,
|
||||||
|
integer: typeTemplate,
|
||||||
|
float: typeTemplate,
|
||||||
|
regexp: typeTemplate,
|
||||||
|
email: typeTemplate,
|
||||||
|
url: typeTemplate,
|
||||||
|
hex: typeTemplate,
|
||||||
|
},
|
||||||
|
string: {
|
||||||
|
len: '${label} must be ${len} characters',
|
||||||
|
min: '${label} must be at least ${min} characters',
|
||||||
|
max: '${label} must be up to ${max} characters',
|
||||||
|
range: '${label} must be between ${min}-${max} characters',
|
||||||
|
},
|
||||||
|
number: {
|
||||||
|
len: '${label} must be equal to ${len}',
|
||||||
|
min: '${label} must be minimum ${min}',
|
||||||
|
max: '${label} must be maximum ${max}',
|
||||||
|
range: '${label} must be between ${min}-${max}',
|
||||||
|
},
|
||||||
|
array: {
|
||||||
|
len: 'Must be ${len} ${label}',
|
||||||
|
min: 'At least ${min} ${label}',
|
||||||
|
max: 'At most ${max} ${label}',
|
||||||
|
range: 'The amount of ${label} must be between ${min}-${max}',
|
||||||
|
},
|
||||||
|
pattern: {
|
||||||
|
mismatch: '${label} does not match the pattern ${pattern}',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Image: {
|
||||||
|
preview: 'Preview',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue