refactor: configprovider

This commit is contained in:
tangjinzhou 2023-01-27 16:00:17 +08:00
parent 0399ce0ec7
commit b5d7d582cd
119 changed files with 523 additions and 393 deletions

View File

@ -1,87 +0,0 @@
import type { RequiredMark } from '../../form/Form';
import type { ComputedRef, UnwrapRef } from 'vue';
import { computed, inject } from 'vue';
import type { ConfigProviderProps, CSPConfig, Direction, SizeType } from '../../config-provider';
import { defaultConfigProvider } from '../../config-provider';
import type { VueNode } from '../type';
import type { ValidateMessages } from '../../form/interface';
export default (
name: string,
props: Record<any, any>,
): {
configProvider: UnwrapRef<ConfigProviderProps>;
prefixCls: ComputedRef<string>;
rootPrefixCls: ComputedRef<string>;
direction: ComputedRef<Direction>;
size: ComputedRef<SizeType>;
getTargetContainer: ComputedRef<() => HTMLElement>;
space: ComputedRef<{ size: SizeType | number }>;
pageHeader: ComputedRef<{ ghost: boolean }>;
form?: ComputedRef<{
requiredMark?: RequiredMark;
colon?: boolean;
validateMessages?: ValidateMessages;
}>;
autoInsertSpaceInButton: ComputedRef<boolean>;
renderEmpty?: ComputedRef<(componentName?: string) => VueNode>;
virtual: ComputedRef<boolean>;
dropdownMatchSelectWidth: ComputedRef<boolean | number>;
getPopupContainer: ComputedRef<ConfigProviderProps['getPopupContainer']>;
getPrefixCls: ConfigProviderProps['getPrefixCls'];
autocomplete: ComputedRef<string>;
csp: ComputedRef<CSPConfig>;
iconPrefixCls: ComputedRef<string>;
} => {
const configProvider = inject<UnwrapRef<ConfigProviderProps>>(
'configProvider',
defaultConfigProvider,
);
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
const direction = computed(() => props.direction ?? configProvider.direction);
const iconPrefixCls = computed(() => props.iconPrefixCls ?? configProvider.iconPrefixCls);
const rootPrefixCls = computed(() => configProvider.getPrefixCls());
const autoInsertSpaceInButton = computed(() => configProvider.autoInsertSpaceInButton);
const renderEmpty = computed(() => configProvider.renderEmpty);
const space = computed(() => configProvider.space);
const pageHeader = computed(() => configProvider.pageHeader);
const form = computed(() => configProvider.form);
const getTargetContainer = computed(
() => props.getTargetContainer || configProvider.getTargetContainer,
);
const getPopupContainer = computed(
() => props.getPopupContainer || configProvider.getPopupContainer,
);
const dropdownMatchSelectWidth = computed<boolean | number>(
() => props.dropdownMatchSelectWidth ?? configProvider.dropdownMatchSelectWidth,
);
const virtual = computed(
() =>
(props.virtual === undefined ? configProvider.virtual !== false : props.virtual !== false) &&
dropdownMatchSelectWidth.value !== false,
);
const size = computed(() => props.size || configProvider.componentSize);
const autocomplete = computed(() => props.autocomplete || configProvider.input?.autocomplete);
const csp = computed(() => configProvider.csp);
return {
configProvider,
prefixCls,
direction,
size,
getTargetContainer,
getPopupContainer,
space,
pageHeader,
form,
autoInsertSpaceInButton,
renderEmpty,
virtual,
dropdownMatchSelectWidth,
rootPrefixCls,
getPrefixCls: configProvider.getPrefixCls,
autocomplete,
csp,
iconPrefixCls,
};
};

View File

@ -1,30 +0,0 @@
import type { ComputedRef, UnwrapRef } from 'vue';
import { computed, inject, provide } from 'vue';
import type { ConfigProviderProps, SizeType } from '../../config-provider';
import { defaultConfigProvider } from '../../config-provider';
const sizeProvider = Symbol('SizeProvider');
const useProvideSize = <T = SizeType>(props: Record<any, any>): ComputedRef<T> => {
const configProvider = inject<UnwrapRef<ConfigProviderProps>>(
'configProvider',
defaultConfigProvider,
);
const size = computed<T>(() => props.size || configProvider.componentSize);
provide(sizeProvider, size);
return size;
};
const useInjectSize = <T = SizeType>(props?: Record<any, any>): ComputedRef<T> => {
const size: ComputedRef<T> = props
? computed(() => props.size)
: inject(
sizeProvider,
computed(() => 'default' as unknown as T),
);
return size;
};
export { useInjectSize, sizeProvider, useProvideSize };
export default useProvideSize;

View File

@ -2,7 +2,7 @@ import { nextTick, defineComponent, getCurrentInstance, onMounted, onBeforeUnmou
import TransitionEvents from './css-animation/Event';
import raf from './raf';
import { findDOMNode } from './props-util';
import useConfigInject from './hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
let styleForPesudo: HTMLStyleElement;
// Where el is the DOM element you'd like to test for visibility

View File

@ -21,7 +21,7 @@ import {
getFixedTop,
getFixedBottom,
} from './utils';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
import useStyle from './style';
function getDefaultTarget() {

View File

@ -16,7 +16,7 @@ import { isValidElement } from '../_util/props-util';
import { tuple, withInstall } from '../_util/type';
import { cloneElement } from '../_util/vnode';
import type { NodeMouseEventHandler } from '../vc-tree/contextTypes';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style';
const iconMapFilled = {

View File

@ -14,7 +14,7 @@ import addEventListener from '../vc-util/Dom/addEventListener';
import Affix from '../affix';
import scrollTo from '../_util/scrollTo';
import getScroll from '../_util/getScroll';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useProvideAnchor from './context';
import useStyle from './style';
import type { AnchorLinkProps } from './AnchorLink';

View File

@ -3,7 +3,7 @@ import { defineComponent, nextTick, onBeforeUnmount, onMounted, watch } from 'vu
import PropTypes from '../_util/vue-types';
import { getPropsSlot, initDefaultProps } from '../_util/props-util';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useInjectAnchor } from './context';
export const anchorLinkProps = () => ({

View File

@ -6,7 +6,7 @@ import warning from '../_util/warning';
import Option from './Option';
import OptGroup from './OptGroup';
import omit from '../_util/omit';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { InputStatus } from '../_util/statusUtils';
function isSelectOptionOrSelectOptGroup(child: any): boolean {

View File

@ -7,11 +7,11 @@ import PropTypes from '../_util/vue-types';
import useBreakpoint from '../_util/hooks/useBreakpoint';
import type { Breakpoint, ScreenSizeMap } from '../_util/responsiveObserve';
import { responsiveArray } from '../_util/responsiveObserve';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import ResizeObserver from '../vc-resize-observer';
import { useInjectSize } from '../_util/hooks/useSize';
import eagerComputed from '../_util/eagerComputed';
import useStyle from './style';
import { useInjectSize } from './SizeContext';
export type AvatarSize = 'large' | 'small' | 'default' | number | ScreenSizeMap;

View File

@ -5,9 +5,9 @@ import Popover from '../popover';
import type { PropType, ExtractPropTypes, CSSProperties } from 'vue';
import { computed, defineComponent } from 'vue';
import { flattenChildren, getPropsSlot } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useProvideSize from '../_util/hooks/useSize';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style';
import { useProviderSize } from './SizeContext';
export const groupProps = () => ({
prefixCls: String,
@ -36,7 +36,7 @@ const Group = defineComponent({
const { prefixCls, direction } = useConfigInject('avatar', props);
const groupPrefixCls = computed(() => `${prefixCls.value}-group`);
const [wrapSSR, hashId] = useStyle(prefixCls);
useProvideSize<AvatarSize>(props);
useProviderSize(computed(() => props.size));
return () => {
const {
maxPopoverPlacement = 'top',

View File

@ -0,0 +1,17 @@
import type { InjectionKey, Ref } from 'vue';
import { computed, inject, ref, provide } from 'vue';
import type { ScreenSizeMap } from '../_util/responsiveObserve';
export type AvatarSize = 'large' | 'small' | 'default' | number | ScreenSizeMap;
const SizeContextKey: InjectionKey<Ref<AvatarSize>> = Symbol('SizeContextKey');
export const useInjectSize = () => {
return inject(SizeContextKey, ref('default' as AvatarSize));
};
export const useProviderSize = (size: Ref<AvatarSize>) => {
const parentSize = useInjectSize();
provide(
SizeContextKey,
computed(() => size.value || parentSize.value),
);
return size;
};

View File

@ -16,7 +16,7 @@ import { getTransitionProps, Transition } from '../_util/transition';
import scrollTo from '../_util/scrollTo';
import { withInstall, eventType } from '../_util/type';
import throttleByAnimationFrame from '../_util/throttleByAnimationFrame';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { MouseEventHandler } from '../_util/EventInterface';
import useStyle from './style';

View File

@ -7,7 +7,7 @@ import { getTransitionProps, Transition } from '../_util/transition';
import type { ExtractPropTypes, CSSProperties, PropType } from 'vue';
import { defineComponent, computed, ref, watch } from 'vue';
import Ribbon from './Ribbon';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import isNumeric from '../_util/isNumeric';
import useStyle from './style';
import type { PresetColorKey } from '../theme/interface';

View File

@ -5,7 +5,7 @@ import { isPresetColor } from '../_util/colors';
import type { CSSProperties, PropType, ExtractPropTypes } from 'vue';
import { defineComponent, computed } from 'vue';
import PropTypes from '../_util/vue-types';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const ribbonProps = () => ({
prefix: String,

View File

@ -3,7 +3,7 @@ import PropTypes from '../_util/vue-types';
import { cloneElement } from '../_util/vnode';
import type { ExtractPropTypes, CSSProperties, DefineComponent, HTMLAttributes } from 'vue';
import { defineComponent } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import SingleNumber from './SingleNumber';
import { filterEmpty } from '../_util/props-util';

View File

@ -7,7 +7,7 @@ import type { BreadcrumbItemProps } from './BreadcrumbItem';
import BreadcrumbItem from './BreadcrumbItem';
import Menu from '../menu';
import type { VueNode } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useStyle from './style';
export interface Route {
path: string;

View File

@ -5,7 +5,7 @@ import { getPropsSlot } from '../_util/props-util';
import type { DropdownProps } from '../dropdown/dropdown';
import Dropdown from '../dropdown/dropdown';
import DownOutlined from '@ant-design/icons-vue/DownOutlined';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { MouseEventHandler } from '../_util/EventInterface';
import { eventType, objectType } from '../_util/type';

View File

@ -1,7 +1,7 @@
import type { ExtractPropTypes } from 'vue';
import { defineComponent } from 'vue';
import { flattenChildren } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const breadcrumbSeparatorProps = () => ({
prefixCls: String,

View File

@ -1,6 +1,6 @@
import { computed, defineComponent } from 'vue';
import { flattenChildren } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useToken } from '../theme/internal';
import type { ExtractPropTypes, PropType, ComputedRef } from 'vue';
import type { SizeType } from '../config-provider';

View File

@ -12,7 +12,7 @@ import {
import Wave from '../_util/wave';
import buttonProps from './buttonTypes';
import { flattenChildren, initDefaultProps } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import devWarning from '../vc-util/devWarning';
import LoadingIcon from './LoadingIcon';
import useStyle from './style';

View File

@ -14,7 +14,7 @@ import CalendarHeader from './Header';
import type { VueNode } from '../_util/type';
import type { App } from 'vue';
import { computed, defineComponent, toRef } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import classNames from '../_util/classNames';
type InjectDefaultProps<Props> = Omit<

View File

@ -7,7 +7,7 @@ import PropTypes from '../_util/vue-types';
import { flattenChildren, isEmptyElement, filterEmptyWithUndefined } from '../_util/props-util';
import type { SizeType } from '../config-provider';
import isPlainObject from 'lodash-es/isPlainObject';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import devWarning from '../vc-util/devWarning';
export interface CardTabListType {
key: string;

View File

@ -1,6 +1,6 @@
import type { ExtractPropTypes } from 'vue';
import { defineComponent, computed } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const cardGridProps = () => ({
prefixCls: String,

View File

@ -2,7 +2,7 @@ import type { ExtractPropTypes } from 'vue';
import { defineComponent } from 'vue';
import PropTypes from '../_util/vue-types';
import { getPropsSlot } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const cardMetaProps = () => ({
prefixCls: String,

View File

@ -5,7 +5,7 @@ import warning from '../_util/warning';
import classNames from '../_util/classNames';
import SlickCarousel from '../vc-slick';
import { withInstall } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export type SwipeDirection = 'left' | 'down' | 'right' | 'up' | string;

View File

@ -15,7 +15,7 @@ import { computed, defineComponent, ref, watchEffect } from 'vue';
import type { ExtractPropTypes, PropType } from 'vue';
import PropTypes from '../_util/vue-types';
import { initDefaultProps } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import classNames from '../_util/classNames';
import type { SizeType } from '../config-provider';
import devWarning from '../vc-util/devWarning';
@ -227,7 +227,7 @@ const Cascader = defineComponent({
...restProps
} = props;
// =================== No Found ====================
const mergedNotFoundContent = notFoundContent || renderEmpty.value('Cascader');
const mergedNotFoundContent = notFoundContent || renderEmpty('Cascader');
// ===================== Icon ======================
let mergedExpandIcon = expandIcon;

View File

@ -6,7 +6,7 @@ import { flattenChildren } from '../_util/props-util';
import warning from '../_util/warning';
import type { EventHandler } from '../_util/EventInterface';
import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { CheckboxChangeEvent, CheckboxProps } from './interface';
import { CheckboxGroupContextKey, checkboxProps } from './interface';

View File

@ -1,7 +1,7 @@
import { computed, ref, watch, defineComponent, provide } from 'vue';
import Checkbox from './Checkbox';
import { useInjectFormItemContext } from '../form/FormItemContext';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { CheckboxOptionType } from './interface';
import { CheckboxGroupContextKey, checkboxGroupProps } from './interface';

View File

@ -13,7 +13,7 @@ import { computed, defineComponent, ref, watch } from 'vue';
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
import firstNotUndefined from '../_util/firstNotUndefined';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { CollapsePanelProps } from './CollapsePanel';
import collapseMotion from '../_util/collapseMotion';

View File

@ -6,7 +6,7 @@ import { defineComponent } from 'vue';
import Transition from '../_util/transition';
import classNames from '../_util/classNames';
import devWarning from '../vc-util/devWarning';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export { collapsePanelProps };
export type CollapsePanelProps = Partial<ExtractPropTypes<ReturnType<typeof collapsePanelProps>>>;

View File

@ -4,7 +4,7 @@ import PropTypes from '../_util/vue-types';
import { flattenChildren } from '../_util/props-util';
import type { VueNode } from '../_util/type';
import { withInstall } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const commentProps = () => ({
actions: Array,
/** The element to display as the comment author. */

View File

@ -0,0 +1,17 @@
import type { InjectionKey, Ref } from 'vue';
import { computed, inject, ref, provide } from 'vue';
export type DisabledType = boolean | undefined;
const DisabledContextKey: InjectionKey<Ref<DisabledType>> = Symbol('DisabledContextKey');
export const useInjectDisabled = () => {
return inject(DisabledContextKey, ref(undefined));
};
export const useProviderDisabled = (disabled: Ref<DisabledType>) => {
const parentDisabled = useInjectDisabled();
provide(
DisabledContextKey,
computed(() => disabled.value ?? parentDisabled.value),
);
return disabled;
};

View File

@ -0,0 +1,16 @@
import type { InjectionKey, Ref } from 'vue';
import { computed, inject, ref, provide } from 'vue';
export type SizeType = 'small' | 'middle' | 'large' | undefined;
const SizeContextKey: InjectionKey<Ref<SizeType>> = Symbol('SizeContextKey');
export const useInjectSize = () => {
return inject(SizeContextKey, ref(undefined));
};
export const useProviderSize = (size: Ref<SizeType>) => {
const parentSize = useInjectSize();
provide(
SizeContextKey,
computed(() => size.value || parentSize.value),
);
return size;
};

View File

@ -1,10 +1,17 @@
import type { ExtractPropTypes, InjectionKey, PropType, Ref } from 'vue';
import type { ComputedRef, ExtractPropTypes, InjectionKey, PropType, Ref } from 'vue';
import { computed, inject, provide } from 'vue';
import type { ValidateMessages } from '../form/interface';
import type { RequiredMark } from '../form/Form';
import type { RenderEmptyHandler } from './renderEmpty';
import type { TransformCellTextProps } from '../table/interface';
import type { Locale } from '../locale-provider';
import type { DerivativeFunc } from '../_util/cssinjs';
import type { AliasToken, SeedToken } from '../theme/internal';
import type { MapToken, OverrideToken } from '../theme/interface';
import type { VueNode } from '../_util/type';
import { objectType } from '../_util/type';
export const defaultIconPrefixCls = 'anticon';
type GlobalFormCOntextProps = {
validateMessages?: Ref<ValidateMessages>;
@ -42,39 +49,20 @@ export type SizeType = 'small' | 'middle' | 'large' | undefined;
export type Direction = 'ltr' | 'rtl';
export interface ConfigConsumerProps {
getTargetContainer?: () => HTMLElement;
getPopupContainer?: (triggerNode?: HTMLElement) => HTMLElement;
rootPrefixCls?: string;
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;
renderEmpty: RenderEmptyHandler;
transformCellText?: (tableProps: TransformCellTextProps) => any;
csp?: CSPConfig;
autoInsertSpaceInButton?: boolean;
input?: {
autocomplete?: string;
};
locale?: Locale;
pageHeader?: {
ghost: boolean;
};
componentSize?: SizeType;
direction?: 'ltr' | 'rtl';
space?: {
size?: SizeType | number;
};
virtual?: boolean;
dropdownMatchSelectWidth?: boolean | number;
form?: {
requiredMark?: RequiredMark;
colon?: boolean;
};
export type MappingAlgorithm = DerivativeFunc<SeedToken, MapToken>;
export interface ThemeConfig {
token?: Partial<AliasToken>;
components?: OverrideToken;
algorithm?: MappingAlgorithm | MappingAlgorithm[];
hashed?: boolean;
inherit?: boolean;
}
export const configProviderProps = () => ({
iconPrefixCls: String,
getTargetContainer: {
type: Function as PropType<() => HTMLElement>,
type: Function as PropType<() => HTMLElement | Window>,
},
getPopupContainer: {
type: Function as PropType<(triggerNode?: HTMLElement) => HTMLElement>,
@ -89,46 +77,81 @@ export const configProviderProps = () => ({
transformCellText: {
type: Function as PropType<(tableProps: TransformCellTextProps) => any>,
},
csp: {
type: Object as PropType<CSPConfig>,
default: undefined as CSPConfig,
},
input: {
type: Object as PropType<{ autocomplete: string }>,
},
csp: objectType<CSPConfig>(),
input: objectType<{ autocomplete?: string }>(),
autoInsertSpaceInButton: { type: Boolean, default: undefined },
locale: {
type: Object as PropType<Locale>,
default: undefined as Locale,
},
pageHeader: {
type: Object as PropType<{ ghost: boolean }>,
},
locale: objectType<Locale>(),
pageHeader: objectType<{ ghost?: boolean }>(),
componentSize: {
type: String as PropType<SizeType>,
},
componentDisabled: { type: Boolean, default: undefined },
direction: {
type: String as PropType<'ltr' | 'rtl'>,
},
space: {
type: Object as PropType<{ size: SizeType | number }>,
},
space: objectType<{ size?: SizeType | number }>(),
virtual: { type: Boolean, default: undefined },
dropdownMatchSelectWidth: { type: [Number, Boolean], default: true },
form: {
type: Object as PropType<{
validateMessages?: ValidateMessages;
requiredMark?: RequiredMark;
colon?: boolean;
}>,
default: undefined as {
validateMessages?: ValidateMessages;
requiredMark?: RequiredMark;
colon?: boolean;
},
},
// internal use
notUpdateGlobalConfig: Boolean,
form: objectType<{
validateMessages?: ValidateMessages;
requiredMark?: RequiredMark;
colon?: boolean;
}>(),
pagination: objectType<{
showSizeChanger?: boolean;
}>(),
theme: objectType<ThemeConfig>(),
select: objectType<{
showSearch?: boolean;
}>(),
});
export type ConfigProviderProps = Partial<ExtractPropTypes<ReturnType<typeof configProviderProps>>>;
export interface ConfigProviderInnerProps {
csp?: ComputedRef<CSPConfig>;
autoInsertSpaceInButton?: ComputedRef<boolean>;
locale?: ComputedRef<Locale>;
direction?: ComputedRef<'ltr' | 'rtl'>;
space?: ComputedRef<{
size?: number | SizeType;
}>;
virtual?: ComputedRef<boolean>;
dropdownMatchSelectWidth?: ComputedRef<number | boolean>;
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => string;
iconPrefixCls: ComputedRef<string>;
theme?: ComputedRef<ThemeConfig>;
renderEmpty?: (name?: string) => VueNode;
getTargetContainer?: ComputedRef<() => HTMLElement | Window>;
getPopupContainer?: ComputedRef<(triggerNode?: HTMLElement) => HTMLElement>;
pageHeader?: ComputedRef<{
ghost?: boolean;
}>;
input?: ComputedRef<{
autocomplete?: string;
}>;
pagination?: ComputedRef<{
showSizeChanger?: boolean;
}>;
form?: ComputedRef<{
validateMessages?: ValidateMessages;
requiredMark?: RequiredMark;
colon?: boolean;
}>;
select?: ComputedRef<{
showSearch?: boolean;
}>;
componentSize?: ComputedRef<SizeType>;
componentDisabled?: ComputedRef<boolean>;
transformCellText?: ComputedRef<(tableProps: TransformCellTextProps) => any>;
}
export const configProviderKey: InjectionKey<ConfigProviderInnerProps> = Symbol('configProvider');
export const defaultConfigProvider: ConfigProviderInnerProps = {
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `ant-${suffixCls}` : 'ant';
},
iconPrefixCls: computed(() => defaultIconPrefixCls),
};

View File

@ -5,17 +5,14 @@ import { generate } from '@ant-design/colors';
import type { Theme } from './context';
import { updateCSS } from '../vc-util/Dom/dynamicCSS';
import canUseDom from '../_util/canUseDom';
import devWarning from '../vc-util/devWarning';
import warning from '../_util/warning';
const dynamicStyleMark = `-ant-${Date.now()}-${Math.random()}`;
export function getStyle(globalPrefixCls: string, theme: Theme) {
const variables: Record<string, string> = {};
const formatColor = (
color: TinyColor,
updater?: (cloneColor: TinyColor) => TinyColor | undefined,
) => {
const formatColor = (color: TinyColor, updater?: (cloneColor: TinyColor) => TinyColor) => {
let clone = color.clone();
clone = updater?.(clone) || clone;
return clone.toRgbString();
@ -30,8 +27,8 @@ export function getStyle(globalPrefixCls: string, theme: Theme) {
variables[`${type}-color-hover`] = colorPalettes[4];
variables[`${type}-color-active`] = colorPalettes[6];
variables[`${type}-color-outline`] = baseColor.clone().setAlpha(0.2).toRgbString();
variables[`${type}-color-deprecated-bg`] = colorPalettes[1];
variables[`${type}-color-deprecated-border`] = colorPalettes[3];
variables[`${type}-color-deprecated-bg`] = colorPalettes[0];
variables[`${type}-color-deprecated-border`] = colorPalettes[2];
};
// ================ Primary Color ================
@ -101,6 +98,6 @@ export function registerTheme(globalPrefixCls: string, theme: Theme) {
if (canUseDom()) {
updateCSS(style, `${dynamicStyleMark}-dynamic-theme`);
} else {
devWarning(false, 'ConfigProvider', 'SSR do not support dynamic theme with css variables.');
warning(false, 'ConfigProvider', 'SSR do not support dynamic theme with css variables.');
}
}

View File

@ -0,0 +1,56 @@
import { computed, inject } from 'vue';
import { defaultConfigProvider, configProviderKey } from '../context';
export default (name: string, props: Record<any, any>) => {
const configProvider = inject(configProviderKey, {
...defaultConfigProvider,
renderEmpty: () => null,
});
const prefixCls = computed(() => configProvider.getPrefixCls(name, props.prefixCls));
const direction = computed(() => props.direction ?? configProvider.direction.value);
const iconPrefixCls = computed(() => props.iconPrefixCls ?? configProvider.iconPrefixCls.value);
const rootPrefixCls = computed(() => configProvider.getPrefixCls());
const autoInsertSpaceInButton = computed(() => configProvider.autoInsertSpaceInButton.value);
const renderEmpty = configProvider.renderEmpty;
const space = configProvider.space;
const pageHeader = configProvider.pageHeader;
const form = configProvider.form;
const getTargetContainer = configProvider.getTargetContainer;
const getPopupContainer = configProvider.getPopupContainer;
const dropdownMatchSelectWidth = computed<boolean | number>(
() => props.dropdownMatchSelectWidth ?? configProvider.dropdownMatchSelectWidth.value,
);
const virtual = computed(
() =>
(props.virtual === undefined
? configProvider.virtual.value !== false
: props.virtual !== false) && dropdownMatchSelectWidth.value !== false,
);
const size = computed(() => props.size || configProvider.componentSize.value);
const autocomplete = computed(
() => props.autocomplete ?? configProvider.input.value?.autocomplete,
);
const disabled = computed(() => props.disabled || configProvider.componentDisabled.value);
const csp = computed(() => props.csp ?? configProvider.csp);
return {
configProvider,
prefixCls,
direction,
size,
getTargetContainer,
getPopupContainer,
space,
pageHeader,
form,
autoInsertSpaceInButton,
renderEmpty,
virtual,
dropdownMatchSelectWidth,
rootPrefixCls,
getPrefixCls: configProvider.getPrefixCls,
autocomplete,
csp,
iconPrefixCls,
disabled,
};
};

View File

@ -0,0 +1,43 @@
import type { ThemeConfig } from '../context';
import { defaultConfig } from '../../theme/internal';
import type { Ref } from 'vue';
import { computed } from 'vue';
export default function useTheme(theme?: Ref<ThemeConfig>, parentTheme?: Ref<ThemeConfig>) {
const themeConfig = computed(() => theme?.value || {});
const parentThemeConfig = computed<ThemeConfig>(() =>
themeConfig.value.inherit === false || !parentTheme?.value ? defaultConfig : parentTheme.value,
);
const mergedTheme = computed(() => {
if (!theme?.value) {
return parentTheme?.value;
}
// Override
const mergedComponents = {
...parentThemeConfig.value.components,
};
Object.keys(theme.value.components || {}).forEach(componentName => {
mergedComponents[componentName] = {
...mergedComponents[componentName],
...theme.value.components![componentName],
} as any;
});
// Base token
return {
...parentThemeConfig.value,
...themeConfig.value,
token: {
...parentThemeConfig.value.token,
...themeConfig.value.token,
},
components: mergedComponents,
};
});
return mergedTheme;
}

View File

@ -107,3 +107,7 @@ When you config `getPopupContainer` to parentNode globally, Modal will throw err
<App />
</ConfigProvider>
```
#### Why can't ConfigProvider props (like `prefixCls` and `theme`) affect VueNode inside `message.info`, `notification.open`, `Modal.confirm`?
antd will dynamic create Vue instance by `Vue.render` when call message methods. Whose context is different with origin code located context.

View File

@ -1,5 +1,5 @@
import type { UnwrapRef, App, Plugin, WatchStopHandle } from 'vue';
import { computed, reactive, provide, defineComponent, watch, watchEffect } from 'vue';
import type { App, Plugin, WatchStopHandle } from 'vue';
import { inject, computed, reactive, provide, defineComponent, watchEffect } from 'vue';
import defaultRenderEmpty from './renderEmpty';
import type { RenderEmptyHandler } from './renderEmpty';
import type { Locale } from '../locale-provider';
@ -13,9 +13,18 @@ import notification from '../notification';
import { registerTheme } from './cssVariables';
import defaultLocale from '../locale/default';
import type { ValidateMessages } from '../form/interface';
import type { ConfigProviderProps, Theme } from './context';
import { configProviderProps, useProvideGlobalForm } from './context';
import useStyle from './style';
import useTheme from './hooks/useTheme';
import type { ConfigProviderInnerProps, ConfigProviderProps, Theme } from './context';
import {
defaultConfigProvider,
configProviderKey,
configProviderProps,
useProvideGlobalForm,
defaultIconPrefixCls,
} from './context';
import { useProviderSize } from './SizeContext';
import { useProviderDisabled } from './DisabledContext';
export type {
ConfigProviderProps,
@ -26,10 +35,14 @@ export type {
DirectionType,
} from './context';
export const defaultPrefixCls = 'ant';
export { defaultIconPrefixCls };
function getGlobalPrefixCls() {
return globalConfigForApi.prefixCls || defaultPrefixCls;
}
const globalConfigByCom = reactive<ConfigProviderProps>({});
function getGlobalIconPrefixCls() {
return globalConfigForApi.iconPrefixCls || defaultIconPrefixCls;
}
const globalConfigBySet = reactive<ConfigProviderProps>({}); //
export const globalConfigForApi = reactive<
ConfigProviderProps & {
@ -37,31 +50,34 @@ export const globalConfigForApi = reactive<
}
>({});
export const configConsumerProps = [
'getTargetContainer',
'getPopupContainer',
'rootPrefixCls',
'getPrefixCls',
'renderEmpty',
'csp',
'autoInsertSpaceInButton',
'locale',
'pageHeader',
];
watchEffect(() => {
Object.assign(globalConfigForApi, globalConfigByCom, globalConfigBySet);
Object.assign(globalConfigForApi, globalConfigBySet);
globalConfigForApi.prefixCls = getGlobalPrefixCls();
globalConfigForApi.iconPrefixCls = getGlobalIconPrefixCls();
globalConfigForApi.getPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return suffixCls
? `${globalConfigForApi.prefixCls}-${suffixCls}`
: globalConfigForApi.prefixCls;
};
globalConfigForApi.getRootPrefixCls = (rootPrefixCls?: string, customizePrefixCls?: string) => {
// Customize rootPrefixCls is first priority
if (rootPrefixCls) {
return rootPrefixCls;
}
globalConfigForApi.getRootPrefixCls = () => {
// If Global prefixCls provided, use this
if (globalConfigForApi.prefixCls) {
return globalConfigForApi.prefixCls;
}
// [Legacy] If customize prefixCls provided, we cut it to get the prefixCls
if (customizePrefixCls && customizePrefixCls.includes('-')) {
return customizePrefixCls.replace(/^(.*)-[^-]*$/, '$1');
}
// Fallback to default prefixCls
return getGlobalPrefixCls();
};
@ -69,6 +85,7 @@ watchEffect(() => {
type GlobalConfigProviderProps = {
prefixCls?: MaybeRef<ConfigProviderProps['prefixCls']>;
iconPrefixCls?: MaybeRef<ConfigProviderProps['iconPrefixCls']>;
getPopupContainer?: ConfigProviderProps['getPopupContainer'];
};
@ -91,22 +108,13 @@ export const globalConfig = () => ({
if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `${getGlobalPrefixCls()}-${suffixCls}` : getGlobalPrefixCls();
},
getRootPrefixCls: (rootPrefixCls?: string, customizePrefixCls?: string) => {
// Customize rootPrefixCls is first priority
if (rootPrefixCls) {
return rootPrefixCls;
}
getIconPrefixCls: getGlobalIconPrefixCls,
getRootPrefixCls: () => {
// If Global prefixCls provided, use this
if (globalConfigForApi.prefixCls) {
return globalConfigForApi.prefixCls;
}
// [Legacy] If customize prefixCls provided, we cut it to get the prefixCls
if (customizePrefixCls && customizePrefixCls.includes('-')) {
return customizePrefixCls.replace(/^(.*)-[^-]*$/, '$1');
}
// Fallback to default prefixCls
return getGlobalPrefixCls();
},
@ -118,55 +126,99 @@ const ConfigProvider = defineComponent({
inheritAttrs: false,
props: configProviderProps(),
setup(props, { slots }) {
const parentContext = inject(configProviderKey, defaultConfigProvider);
const getPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {
const { prefixCls = 'ant' } = props;
if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `${prefixCls}-${suffixCls}` : prefixCls;
const mergedPrefixCls = prefixCls || parentContext.getPrefixCls('');
return suffixCls ? `${mergedPrefixCls}-${suffixCls}` : mergedPrefixCls;
};
const iconPrefixCls = computed(
() => props.iconPrefixCls || parentContext.iconPrefixCls.value || defaultIconPrefixCls,
);
const shouldWrapSSR = computed(() => iconPrefixCls.value !== parentContext.iconPrefixCls.value);
const csp = computed(() => props.csp || parentContext.csp?.value);
const wrapSSR = useStyle(iconPrefixCls);
const mergedTheme = useTheme(
computed(() => props.theme),
computed(() => parentContext.theme?.value),
);
const renderEmptyComponent = (name?: string) => {
const renderEmpty = (props.renderEmpty ||
slots.renderEmpty ||
parentContext.renderEmpty ||
defaultRenderEmpty) as RenderEmptyHandler;
return renderEmpty(name);
};
const getPrefixClsWrapper = (suffixCls: string, customizePrefixCls?: string) => {
const { prefixCls } = props;
if (customizePrefixCls) return customizePrefixCls;
const mergedPrefixCls = prefixCls || getPrefixCls('');
return suffixCls ? `${mergedPrefixCls}-${suffixCls}` : mergedPrefixCls;
};
const configProvider = reactive({
...props,
getPrefixCls: getPrefixClsWrapper,
const autoInsertSpaceInButton = computed(
() => props.autoInsertSpaceInButton ?? parentContext.autoInsertSpaceInButton?.value,
);
const locale = computed(() => props.locale || parentContext.locale?.value);
const direction = computed(() => props.direction || parentContext.direction?.value);
const space = computed(() => props.space ?? parentContext.space?.value);
const virtual = computed(() => props.virtual ?? parentContext.virtual?.value);
const dropdownMatchSelectWidth = computed(
() => props.dropdownMatchSelectWidth ?? parentContext.dropdownMatchSelectWidth?.value,
);
const getTargetContainer = computed(() =>
props.getTargetContainer !== undefined
? props.getTargetContainer
: parentContext.getTargetContainer?.value,
);
const getPopupContainer = computed(() =>
props.getPopupContainer !== undefined
? props.getPopupContainer
: parentContext.getPopupContainer?.value,
);
const pageHeader = computed(() =>
props.pageHeader !== undefined ? props.pageHeader : parentContext.pageHeader?.value,
);
const input = computed(() =>
props.input !== undefined ? props.input : parentContext.input?.value,
);
const pagination = computed(() =>
props.pagination !== undefined ? props.pagination : parentContext.pagination?.value,
);
const form = computed(() =>
props.form !== undefined ? props.form : parentContext.form?.value,
);
const select = computed(() =>
props.select !== undefined ? props.select : parentContext.select?.value,
);
const componentSize = computed(() => props.componentSize);
const componentDisabled = computed(() => props.componentDisabled);
const configProvider: ConfigProviderInnerProps = {
csp,
autoInsertSpaceInButton,
locale,
direction,
space,
virtual,
dropdownMatchSelectWidth,
getPrefixCls,
iconPrefixCls,
theme: mergedTheme,
renderEmpty: renderEmptyComponent,
});
Object.keys(props).forEach(key => {
watch(
() => props[key],
() => {
configProvider[key] = props[key];
},
);
});
if (!props.notUpdateGlobalConfig) {
Object.assign(globalConfigByCom, configProvider);
watch(configProvider, () => {
Object.assign(globalConfigByCom, configProvider);
});
}
getTargetContainer,
getPopupContainer,
pageHeader,
input,
pagination,
form,
select,
componentSize,
componentDisabled,
transformCellText: computed(() => props.transformCellText),
};
const validateMessagesRef = computed(() => {
// Additional Form provider
let validateMessages: ValidateMessages = {};
if (props.locale) {
if (locale.value) {
validateMessages =
props.locale.Form?.defaultValidateMessages ||
locale.value.Form?.defaultValidateMessages ||
defaultLocale.Form?.defaultValidateMessages ||
{};
}
@ -175,24 +227,27 @@ const ConfigProvider = defineComponent({
}
return validateMessages;
});
provide(configProviderKey, configProvider);
useProvideGlobalForm({ validateMessages: validateMessagesRef });
provide('configProvider', configProvider);
useProviderSize(componentSize);
useProviderDisabled(componentDisabled);
const renderProvider = (legacyLocale: Locale) => {
return (
<LocaleProvider locale={props.locale || legacyLocale} ANT_MARK__={ANT_MARK}>
{slots.default?.()}
<LocaleProvider locale={locale.value || legacyLocale} ANT_MARK__={ANT_MARK}>
{shouldWrapSSR.value ? wrapSSR(slots.default?.()) : slots.default?.()}
</LocaleProvider>
);
};
watchEffect(() => {
if (props.direction) {
if (direction.value) {
message.config({
rtl: props.direction === 'rtl',
rtl: direction.value === 'rtl',
});
notification.config({
rtl: props.direction === 'rtl',
rtl: direction.value === 'rtl',
});
}
});
@ -202,18 +257,7 @@ const ConfigProvider = defineComponent({
);
},
});
export const defaultIconPrefixCls = 'anticon';
export const defaultConfigProvider: UnwrapRef<ConfigProviderProps> = reactive({
getPrefixCls: (suffixCls: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `ant-${suffixCls}` : 'ant';
},
renderEmpty: defaultRenderEmpty,
direction: 'ltr',
iconPrefixCls: defaultIconPrefixCls,
});
ConfigProvider.config = setGlobalConfig;
ConfigProvider.install = function (app: App) {
app.component(ConfigProvider.name, ConfigProvider);
};

View File

@ -108,3 +108,7 @@ ConfigProvider.config({
<App />
</ConfigProvider>
```
#### 为什么 message.info、notification.open 或 Modal.confirm 等方法内的 VueNode 无法继承 ConfigProvider 的属性?比如 `prefixCls``theme`
静态方法是使用 Vue.render 重新渲染一个 Vue 根节点上,和主应用的 Vue 节点是脱离的。

View File

@ -1,6 +1,6 @@
import Empty from '../empty';
import type { VueNode } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from './hooks/useConfigInject';
export interface RenderEmptyProps {
componentName?: string;
@ -13,14 +13,12 @@ const RenderEmpty = (props: RenderEmptyProps) => {
case 'Table':
case 'List':
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} />;
case 'Select':
case 'TreeSelect':
case 'Cascader':
case 'Transfer':
case 'Mentions':
return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} class={`${prefixCls.value}-small`} />;
default:
return <Empty />;
}

View File

@ -1,2 +0,0 @@
// placeholder
@import '../../style/themes/index';

View File

@ -0,0 +1,29 @@
import { useStyleRegister } from '../../_util/cssinjs';
import { resetIcon } from '../../_style';
import { useToken } from '../../theme/internal';
import { computed, Ref } from 'vue';
const useStyle = (iconPrefixCls: Ref<string>) => {
const [theme, token] = useToken();
// Generate style for icons
return useStyleRegister(
computed(() => ({
theme: theme.value,
token: token.value,
hashId: '',
path: ['ant-design-icons', iconPrefixCls.value],
})),
() => [
{
[`.${iconPrefixCls.value}`]: {
...resetIcon(),
[`.${iconPrefixCls.value} .${iconPrefixCls.value}-icon`]: {
display: 'block',
},
},
},
],
);
};
export default useStyle;

View File

@ -1 +0,0 @@
import './index.less';

View File

@ -9,7 +9,7 @@ import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver';
import { getRangePlaceholder, transPlacement2DropdownAlign } from '../util';
import { getTimeProps, Components } from '.';
import { computed, defineComponent, ref } from 'vue';
import useConfigInject from '../../_util/hooks/useConfigInject';
import useConfigInject from '../../config-provider/hooks/useConfigInject';
import classNames from '../../_util/classNames';
import type { CommonProps, RangePickerProps } from './props';
import { commonProps, rangePickerProps } from './props';

View File

@ -9,7 +9,7 @@ import { getPlaceholder, transPlacement2DropdownAlign } from '../util';
import { useLocaleReceiver } from '../../locale-provider/LocaleReceiver';
import { getTimeProps, Components } from '.';
import { computed, defineComponent, ref } from 'vue';
import useConfigInject from '../../_util/hooks/useConfigInject';
import useConfigInject from '../../config-provider/hooks/useConfigInject';
import classNames from '../../_util/classNames';
import type { CommonProps, DatePickerProps } from './props';
import { commonProps, datePickerProps } from './props';

View File

@ -25,7 +25,7 @@ import Row from './Row';
import PropTypes from '../_util/vue-types';
import { cloneElement } from '../_util/vnode';
import { flattenChildren } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const DescriptionsItemProps = {
prefixCls: String,

View File

@ -2,7 +2,7 @@ import { flattenChildren } from '../_util/props-util';
import type { ExtractPropTypes, PropType } from 'vue';
import { computed, defineComponent } from 'vue';
import { withInstall } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const dividerProps = () => ({
prefixCls: String,

View File

@ -15,7 +15,7 @@ import classnames from '../_util/classNames';
import VcDrawer from '../vc-drawer';
import PropTypes from '../_util/vue-types';
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { tuple, withInstall } from '../_util/type';
import omit from '../_util/omit';
import devWarning from '../vc-util/devWarning';

View File

@ -6,7 +6,7 @@ import Dropdown from './dropdown';
import { initDefaultProps } from '../_util/props-util';
import { dropdownButtonProps } from './props';
import EllipsisOutlined from '@ant-design/icons-vue/EllipsisOutlined';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
const ButtonGroup = Button.Group;
export type DropdownButtonProps = Partial<ExtractPropTypes<ReturnType<typeof dropdownButtonProps>>>;

View File

@ -7,7 +7,7 @@ import classNames from '../_util/classNames';
import { isValidElement, initDefaultProps } from '../_util/props-util';
import { dropdownProps } from './props';
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import devWarning from '../vc-util/devWarning';
import omit from '../_util/omit';
import getPlacements from '../tooltip/placements';

View File

@ -1,4 +1,4 @@
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
const Empty = () => {
const { getPrefixCls } = useConfigInject('empty', {});

View File

@ -7,7 +7,7 @@ import { filterEmpty } from '../_util/props-util';
import PropTypes from '../_util/vue-types';
import type { VueNode } from '../_util/type';
import { withInstall } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
const defaultEmptyImg = <DefaultEmptyImg />;
const simpleEmptyImg = <SimpleEmptyImg />;

View File

@ -1,4 +1,4 @@
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
const Simple = () => {
const { getPrefixCls } = useConfigInject('empty', {});

View File

@ -2,7 +2,7 @@ import { useInjectFormItemPrefix } from './context';
import type { VueNode } from '../_util/type';
import { computed, defineComponent, ref, watch } from 'vue';
import { getTransitionGroupProps, TransitionGroup } from '../_util/transition';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import collapseMotion from '../_util/collapseMotion';
export interface ErrorListProps {

View File

@ -25,8 +25,7 @@ import type {
ValidateMessages,
Rule,
} from './interface';
import { useInjectSize } from '../_util/hooks/useSize';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useProvideForm } from './context';
import type { SizeType } from '../config-provider';
import useForm from './useForm';
@ -111,8 +110,7 @@ const Form = defineComponent({
useForm,
// emits: ['finishFailed', 'submit', 'finish', 'validate'],
setup(props, { emit, slots, expose, attrs }) {
const size = useInjectSize(props);
const { prefixCls, direction, form: contextForm } = useConfigInject('form', props);
const { prefixCls, direction, form: contextForm, size } = useConfigInject('form', props);
const requiredMark = computed(() => props.requiredMark === '' || props.requiredMark);
const mergedRequiredMark = computed(() => {
if (requiredMark.value !== undefined) {

View File

@ -33,7 +33,7 @@ import { warning } from '../vc-util/warning';
import find from 'lodash-es/find';
import { tuple } from '../_util/type';
import type { InternalNamePath, Rule, RuleError, RuleObject, ValidateOptions } from './interface';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useInjectForm } from './context';
import FormItemLabel from './FormItemLabel';
import FormItemInput from './FormItemInput';

View File

@ -1,7 +1,7 @@
import type { CSSProperties, ExtractPropTypes, PropType } from 'vue';
import { defineComponent, computed } from 'vue';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useInjectRow } from './context';
type ColSpanType = number | string;

View File

@ -4,7 +4,7 @@ import classNames from '../_util/classNames';
import { tuple } from '../_util/type';
import type { Breakpoint, ScreenMap } from '../_util/responsiveObserve';
import ResponsiveObserve, { responsiveArray } from '../_util/responsiveObserve';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
import useProvideRow from './context';

View File

@ -1,6 +1,6 @@
import PreviewGroup from '../vc-image/src/PreviewGroup';
import { computed, defineComponent } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import RotateLeftOutlined from '@ant-design/icons-vue/RotateLeftOutlined';
import RotateRightOutlined from '@ant-design/icons-vue/RotateRightOutlined';

View File

@ -3,7 +3,7 @@ import { defineComponent, computed } from 'vue';
import ImageInternal from '../vc-image';
import { imageProps } from '../vc-image/src/Image';
import defaultLocale from '../locale/en_US';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import PreviewGroup, { icons } from './PreviewGroup';
import EyeOutlined from '@ant-design/icons-vue/EyeOutlined';
import { getTransitionName } from '../_util/transition';
@ -40,7 +40,7 @@ const Image = defineComponent<ImageProps>({
});
return () => {
const imageLocale = configProvider.locale?.Image || defaultLocale.Image;
const imageLocale = configProvider.locale.value?.Image || defaultLocale.Image;
const defaultPreviewMask = () => (
<div class={`${prefixCls.value}-mask-info`}>
<EyeOutlined />

View File

@ -10,7 +10,7 @@ import {
NoFormStatus,
useInjectFormItemContext,
} from '../form/FormItemContext';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { cloneElement } from '../_util/vnode';
import omit from '../_util/omit';
import PropTypes from '../_util/vue-types';

View File

@ -3,7 +3,7 @@ import { computed, defineComponent } from 'vue';
import type { SizeType } from '../config-provider';
import { FormItemInputContext } from '../form/FormItemContext';
import type { FocusEventHandler, MouseEventHandler } from '../_util/EventInterface';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export default defineComponent({
compatConfig: { MODE: 3 },

View File

@ -5,7 +5,7 @@ import {
NoFormStatus,
useInjectFormItemContext,
} from '../form/FormItemContext';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';
import type { InputFocusOptions } from '../vc-input/utils/commonUtils';
import { hasPrefixSuffix } from '../vc-input/utils/commonUtils';

View File

@ -7,7 +7,7 @@ import EyeInvisibleOutlined from '@ant-design/icons-vue/EyeInvisibleOutlined';
import type { InputProps } from './inputProps';
import inputProps from './inputProps';
import { computed, defineComponent, ref } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
const ActionMap = {

View File

@ -12,7 +12,7 @@ import type {
CompositionEventHandler,
MouseEventHandler,
} from '../_util/EventInterface';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
import isMobile from '../_util/isMobile';
import inputProps from './inputProps';

View File

@ -16,7 +16,7 @@ import { fixControlledValue, resolveOnChange, triggerFocus } from '../vc-input/u
import classNames from '../_util/classNames';
import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
import type { FocusEventHandler } from '../_util/EventInterface';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
import type { VueNode } from '../_util/type';
import { getMergedStatus, getStatusClassNames } from '../_util/statusUtils';

View File

@ -8,7 +8,7 @@ import isNumeric from '../_util/isNumeric';
import BarsOutlined from '@ant-design/icons-vue/BarsOutlined';
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { SiderCollapsedKey, SiderHookProviderKey } from './injectionKey';
const dimensionMaxMap = {

View File

@ -1,6 +1,6 @@
import type { ExtractPropTypes, HTMLAttributes } from 'vue';
import { computed, createVNode, defineComponent, provide, ref } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { SiderHookProviderKey } from './injectionKey';
export const basicProps = () => ({

View File

@ -6,7 +6,7 @@ import { cloneElement } from '../_util/vnode';
import type { CSSProperties, ExtractPropTypes, PropType } from 'vue';
import { defineComponent, inject, ref } from 'vue';
import ItemMeta from './ItemMeta';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { ListContextKey } from './contextKey';
import type { ListGridType } from '.';

View File

@ -1,6 +1,6 @@
import type { ExtractPropTypes } from 'vue';
import { defineComponent } from 'vue';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import PropTypes from '../_util/vue-types';
export const listItemMetaProps = () => ({

View File

@ -13,7 +13,7 @@ import { flattenChildren } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import type { Key } from '../_util/type';
import ItemMeta from './ItemMeta';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useBreakpoint from '../_util/hooks/useBreakpoint';
import type { Breakpoint } from '../_util/responsiveObserve';
import { responsiveArray } from '../_util/responsiveObserve';
@ -291,7 +291,7 @@ const List = defineComponent({
<ul class={`${prefixCls.value}-items`}>{items}</ul>
);
} else if (!children.length && !isLoading.value) {
childrenContent = renderEmptyFunc(renderEmpty.value);
childrenContent = renderEmptyFunc(renderEmpty);
}
const paginationPosition = paginationProps.value.position || 'bottom';

View File

@ -4,7 +4,7 @@ import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import VcMentions, { Option } from '../vc-mentions';
import { mentionsProps as baseMentionsProps } from '../vc-mentions/src/mentionsProps';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { flattenChildren, getOptionProps } from '../_util/props-util';
import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
import omit from '../_util/omit';
@ -143,7 +143,7 @@ const Mentions = defineComponent({
if (slots.notFoundContent) {
return slots.notFoundContent();
}
return renderEmpty.value('Select');
return renderEmpty('Select');
};
const getOptions = () => {

View File

@ -1,4 +1,4 @@
import useConfigInject from '../../_util/hooks/useConfigInject';
import useConfigInject from '../../config-provider/hooks/useConfigInject';
import type { ExtractPropTypes } from 'vue';
import { computed, defineComponent } from 'vue';

View File

@ -15,7 +15,7 @@ import {
import shallowEqual from '../../_util/shallowequal';
import type { StoreMenuInfo } from './hooks/useMenuContext';
import useProvideMenu, { MenuContextProvider, useProvideFirstLevel } from './hooks/useMenuContext';
import useConfigInject from '../../_util/hooks/useConfigInject';
import useConfigInject from '../../config-provider/hooks/useConfigInject';
import type {
MenuTheme,
MenuMode,

View File

@ -13,7 +13,7 @@ import initDefaultProps from '../_util/props-util/initDefaultProps';
import type { Direction } from '../config-provider';
import type { VueNode } from '../_util/type';
import { canUseDocElement } from '../_util/styleChecker';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { getTransitionName } from '../_util/transition';
let mousePosition: { x: number; y: number } | null = null;

View File

@ -77,7 +77,7 @@ const confirm = (config: ModalFuncProps) => {
const rootPrefixCls = global.prefixCls;
const prefixCls = p.prefixCls || `${rootPrefixCls}-modal`;
return (
<ConfigProvider {...(global as any)} notUpdateGlobalConfig={true} prefixCls={rootPrefixCls}>
<ConfigProvider {...(global as any)} prefixCls={rootPrefixCls}>
<ConfirmDialog {...p} rootPrefixCls={rootPrefixCls} prefixCls={prefixCls}></ConfirmDialog>
</ConfigProvider>
);

View File

@ -9,7 +9,7 @@ import Avatar from '../avatar';
import TransButton from '../_util/transButton';
import LocaleReceiver from '../locale-provider/LocaleReceiver';
import { withInstall } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import classNames from '../_util/classNames';
import ResizeObserver from '../vc-resize-observer';
import useDestroyed from '../_util/hooks/useDestroyed';

View File

@ -9,7 +9,7 @@ import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
import VcPagination from '../vc-pagination';
import enUS from '../vc-pagination/locale/en_US';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useBreakpoint from '../_util/hooks/useBreakpoint';
export const paginationProps = () => ({

View File

@ -14,7 +14,7 @@ import { withInstall } from '../_util/type';
import useMergedState from '../_util/hooks/useMergedState';
import devWarning from '../vc-util/devWarning';
import KeyCode from '../_util/KeyCode';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import classNames from '../_util/classNames';
import { getTransitionName } from '../_util/transition';
import { cloneVNodes } from '../_util/vnode';

View File

@ -5,7 +5,7 @@ import abstractTooltipProps from '../tooltip/abstractTooltipProps';
import PropTypes from '../_util/vue-types';
import { filterEmpty, initDefaultProps } from '../_util/props-util';
import { withInstall } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
import { getTransitionName } from '../_util/transition';
import { tooltipDefaultProps } from '../tooltip/Tooltip';

View File

@ -8,7 +8,7 @@ import Line from './Line';
import Circle from './Circle';
import Steps from './Steps';
import { getSuccessPercent, validProgress } from './utils';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import devWarning from '../vc-util/devWarning';
import { progressProps, progressStatuses } from './props';
import type { VueNode } from '../_util/type';

View File

@ -3,7 +3,7 @@ import type { PropType, ExtractPropTypes } from 'vue';
import classNames from '../_util/classNames';
import PropTypes from '../_util/vue-types';
import Radio from './Radio';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { tuple } from '../_util/type';
import type { RadioChangeEvent, RadioGroupButtonStyle, RadioGroupOptionType } from './interface';
import { useInjectFormItemContext } from '../form/FormItemContext';

View File

@ -3,7 +3,7 @@ import { computed, defineComponent, ref } from 'vue';
import PropTypes from '../_util/vue-types';
import VcCheckbox from '../vc-checkbox/Checkbox';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { RadioChangeEvent } from './interface';
import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
import omit from '../_util/omit';

View File

@ -1,6 +1,6 @@
import { defineComponent } from 'vue';
import Radio, { radioProps } from './Radio';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useProvideRadioOptionTypeContext } from './context';
export default defineComponent({

View File

@ -8,7 +8,7 @@ import PropTypes from '../_util/vue-types';
import KeyCode from '../_util/KeyCode';
import StarFilled from '@ant-design/icons-vue/StarFilled';
import Tooltip from '../tooltip';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import Star from './Star';
import useRefs from '../_util/hooks/useRefs';

View File

@ -8,7 +8,7 @@ import WarningFilled from '@ant-design/icons-vue/WarningFilled';
import noFound from './noFound';
import serverError from './serverError';
import unauthorized from './unauthorized';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import classNames from '../_util/classNames';
export const IconMap = {

View File

@ -7,7 +7,7 @@ import type { BaseOptionType, DefaultOptionType } from '../vc-select/Select';
import type { OptionProps } from '../vc-select/Option';
import getIcons from './utils/iconUtil';
import PropTypes from '../_util/vue-types';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
import { FormItemInputContext, useInjectFormItemContext } from '../form/FormItemContext';
import type { SelectCommonPlacement } from '../_util/transition';
@ -114,10 +114,15 @@ const Select = defineComponent({
return mode;
});
const { prefixCls, direction, configProvider, size, getPrefixCls } = useConfigInject(
'select',
props,
);
const {
prefixCls,
direction,
configProvider,
renderEmpty,
size,
getPrefixCls,
getPopupContainer,
} = useConfigInject('select', props);
const rootPrefixCls = computed(() => getPrefixCls());
// ===================== Placement =====================
const placement = computed(() => {
@ -173,7 +178,6 @@ const Select = defineComponent({
notFoundContent,
listHeight = 256,
listItemHeight = 24,
getPopupContainer,
dropdownClassName,
virtual,
dropdownMatchSelectWidth,
@ -182,7 +186,7 @@ const Select = defineComponent({
showArrow,
} = props;
const { hasFeedback, feedbackIcon } = formItemInputContext;
const { renderEmpty, getPopupContainer: getContextPopupContainer } = configProvider;
const {} = configProvider;
// ===================== Empty =====================
let mergedNotFound: any;
@ -242,7 +246,7 @@ const Select = defineComponent({
clearIcon={clearIcon}
notFoundContent={mergedNotFound}
class={[mergedClassName.value, attrs.class]}
getPopupContainer={getPopupContainer || getContextPopupContainer}
getPopupContainer={getPopupContainer.value}
dropdownClassName={rcSelectRtlDropdownClassName}
onChange={triggerChange}
onBlur={handleBlur}

View File

@ -2,7 +2,7 @@ import type { ExtractPropTypes, PropType } from 'vue';
import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import Element, { skeletonElementProps } from './Element';
export const avatarProps = () => {

View File

@ -1,7 +1,7 @@
import type { ExtractPropTypes, PropType } from 'vue';
import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { initDefaultProps } from '../_util/props-util';
import Element, { skeletonElementProps } from './Element';

View File

@ -1,6 +1,6 @@
import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import omit from '../_util/omit';
import type { SkeletonElementProps } from './Element';
import { skeletonElementProps } from './Element';

View File

@ -1,7 +1,7 @@
import type { PropType } from 'vue';
import { computed, defineComponent } from 'vue';
import classNames from '../_util/classNames';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import type { SkeletonElementProps } from './Element';
import Element, { skeletonElementProps } from './Element';
import omit from '../_util/omit';

View File

@ -7,7 +7,7 @@ import type { SkeletonTitleProps } from './Title';
import Title from './Title';
import type { SkeletonParagraphProps } from './Paragraph';
import Paragraph from './Paragraph';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import Element from './Element';
/* This only for skeleton internal. */

View File

@ -6,7 +6,7 @@ import VcHandle from '../vc-slider/src/Handle';
import type { VueNode } from '../_util/type';
import { withInstall } from '../_util/type';
import type { TooltipPlacement } from '../tooltip/Tooltip';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import SliderTooltip from './SliderTooltip';
import classNames from '../_util/classNames';
import { useInjectFormItemContext } from '../form/FormItemContext';

View File

@ -4,7 +4,7 @@ import PropTypes from '../_util/vue-types';
import { filterEmpty } from '../_util/props-util';
import type { SizeType } from '../config-provider';
import { tuple, withInstall } from '../_util/type';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useFlexGapSupport from '../_util/hooks/useFlexGapSupport';
import classNames from '../_util/classNames';

View File

@ -4,7 +4,7 @@ import debounce from 'lodash-es/debounce';
import PropTypes from '../_util/vue-types';
import { getComponent, getSlot } from '../_util/props-util';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import { defaultConfigProvider } from '../config-provider';
import { defaultConfigProvider, configProviderKey } from '../config-provider/context';
export type SpinSize = 'small' | 'default' | 'large';
export const spinProps = () => ({
@ -43,7 +43,7 @@ export default defineComponent({
setup() {
return {
originalUpdateSpinning: null,
configProvider: inject('configProvider', defaultConfigProvider),
configProvider: inject(configProviderKey, defaultConfigProvider),
};
},
data() {

View File

@ -5,7 +5,7 @@ import initDefaultProps from '../_util/props-util/initDefaultProps';
import StatisticNumber from './Number';
import type { valueType } from './utils';
import Skeleton from '../skeleton/Skeleton';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
export const statisticProps = () => ({
prefixCls: String,

View File

@ -5,7 +5,7 @@ import CheckOutlined from '@ant-design/icons-vue/CheckOutlined';
import PropTypes from '../_util/vue-types';
import initDefaultProps from '../_util/props-util/initDefaultProps';
import VcSteps, { Step as VcStep } from '../vc-steps';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import useBreakpoint from '../_util/hooks/useBreakpoint';
import classNames from '../_util/classNames';
import Progress from '../progress';

View File

@ -51,7 +51,7 @@ import './tree-select/style';
import './drawer/style';
import './skeleton/style';
import './comment/style';
import './config-provider/style';
// import './config-provider/style';
import './empty/style';
import './statistic/style';
import './result/style';

View File

@ -7,7 +7,7 @@ import Wave from '../_util/wave';
import warning from '../_util/warning';
import { tuple, withInstall } from '../_util/type';
import { getPropsSlot } from '../_util/props-util';
import useConfigInject from '../_util/hooks/useConfigInject';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { useInjectFormItemContext } from '../form/FormItemContext';
import omit from '../_util/omit';
import type { FocusEventHandler } from '../_util/EventInterface';

Some files were not shown because too many files have changed in this diff Show More