Skip to content

Commit a6d9d36

Browse files
committed
fix: api components support locale, close #4780
1 parent c76b46f commit a6d9d36

File tree

8 files changed

+78
-79
lines changed

8 files changed

+78
-79
lines changed

components/config-provider/index.tsx

+53-12
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type { PropType, ExtractPropTypes, UnwrapRef, App, Plugin, WatchStopHandle } from 'vue';
2-
import { reactive, provide, defineComponent, watch, ref, unref, watchEffect } from 'vue';
2+
import { reactive, provide, defineComponent, watch, watchEffect } from 'vue';
33
import PropTypes from '../_util/vue-types';
44
import defaultRenderEmpty from './renderEmpty';
55
import type { RenderEmptyHandler } from './renderEmpty';
@@ -58,7 +58,47 @@ export const configConsumerProps = [
5858
];
5959

6060
export const defaultPrefixCls = 'ant';
61-
const globalPrefixCls = ref<string>();
61+
62+
function getGlobalPrefixCls() {
63+
return globalConfigForApi.prefixCls || defaultPrefixCls;
64+
}
65+
const globalConfigByCom = reactive<ConfigProviderProps>({});
66+
const globalConfigBySet = reactive<ConfigProviderProps>({}); // 权重最大
67+
export const globalConfigForApi = reactive<
68+
ConfigProviderProps & {
69+
getRootPrefixCls?: (rootPrefixCls?: string, customizePrefixCls?: string) => string;
70+
}
71+
>({});
72+
73+
watchEffect(() => {
74+
Object.assign(globalConfigForApi, globalConfigByCom, globalConfigBySet);
75+
globalConfigForApi.prefixCls = getGlobalPrefixCls();
76+
globalConfigForApi.getPrefixCls = (suffixCls?: string, customizePrefixCls?: string) => {
77+
if (customizePrefixCls) return customizePrefixCls;
78+
return suffixCls
79+
? `${globalConfigForApi.prefixCls}-${suffixCls}`
80+
: globalConfigForApi.prefixCls;
81+
};
82+
globalConfigForApi.getRootPrefixCls = (rootPrefixCls?: string, customizePrefixCls?: string) => {
83+
// Customize rootPrefixCls is first priority
84+
if (rootPrefixCls) {
85+
return rootPrefixCls;
86+
}
87+
88+
// If Global prefixCls provided, use this
89+
if (globalConfigForApi.prefixCls) {
90+
return globalConfigForApi.prefixCls;
91+
}
92+
93+
// [Legacy] If customize prefixCls provided, we cut it to get the prefixCls
94+
if (customizePrefixCls && customizePrefixCls.includes('-')) {
95+
return customizePrefixCls.replace(/^(.*)-[^-]*$/, '$1');
96+
}
97+
98+
// Fallback to default prefixCls
99+
return getGlobalPrefixCls();
100+
};
101+
});
62102

63103
type GlobalConfigProviderProps = {
64104
prefixCls?: MaybeRef<ConfigProviderProps['prefixCls']>;
@@ -70,17 +110,10 @@ const setGlobalConfig = (params: GlobalConfigProviderProps) => {
70110
stopWatchEffect();
71111
}
72112
stopWatchEffect = watchEffect(() => {
73-
const prefixCls = unref(params.prefixCls);
74-
if (prefixCls !== undefined) {
75-
globalPrefixCls.value = prefixCls;
76-
}
113+
Object.assign(globalConfigBySet, reactive(params));
77114
});
78115
};
79116

80-
function getGlobalPrefixCls() {
81-
return globalPrefixCls.value || defaultPrefixCls;
82-
}
83-
84117
export const globalConfig = () => ({
85118
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
86119
if (customizePrefixCls) return customizePrefixCls;
@@ -93,8 +126,8 @@ export const globalConfig = () => ({
93126
}
94127

95128
// If Global prefixCls provided, use this
96-
if (globalPrefixCls.value) {
97-
return globalPrefixCls.value;
129+
if (globalConfigForApi.prefixCls) {
130+
return globalConfigForApi.prefixCls;
98131
}
99132

100133
// [Legacy] If customize prefixCls provided, we cut it to get the prefixCls
@@ -148,6 +181,8 @@ export const configProviderProps = {
148181
form: {
149182
type: Object as PropType<{ requiredMark?: RequiredMark }>,
150183
},
184+
// internal use
185+
notUpdateGlobalConfig: Boolean,
151186
};
152187

153188
export type ConfigProviderProps = Partial<ExtractPropTypes<typeof configProviderProps>>;
@@ -193,6 +228,12 @@ const ConfigProvider = defineComponent({
193228
},
194229
);
195230
});
231+
if (!props.notUpdateGlobalConfig) {
232+
Object.assign(globalConfigByCom, configProvider);
233+
watch(configProvider, () => {
234+
Object.assign(globalConfigByCom, configProvider);
235+
});
236+
}
196237

197238
provide('configProvider', configProvider);
198239

components/locale-provider/index.tsx

+2-7
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,7 @@
11
import type { App, VNode, PropType } from 'vue';
2-
import { provide, defineComponent, reactive, watch, onUnmounted } from 'vue';
2+
import { provide, defineComponent, reactive, watch } from 'vue';
33
import PropTypes from '../_util/vue-types';
44
import type { ModalLocale } from '../modal/locale';
5-
import { changeConfirmLocale } from '../modal/locale';
65
import warning from '../_util/warning';
76
import { withInstall } from '../_util/type';
87
import type { ValidateMessages } from '../form/interface';
@@ -72,18 +71,14 @@ const LocaleProvider = defineComponent({
7271
provide('localeData', state);
7372
watch(
7473
() => props.locale,
75-
val => {
74+
() => {
7675
state.antLocale = {
7776
...props.locale,
7877
exist: true,
7978
} as any;
80-
changeConfirmLocale(val && val.Modal);
8179
},
8280
{ immediate: true },
8381
);
84-
onUnmounted(() => {
85-
changeConfirmLocale();
86-
});
8782

8883
return () => {
8984
return slots.default?.();

components/modal/ConfirmDialog.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ import classNames from '../_util/classNames';
22
import type { ModalFuncProps } from './Modal';
33
import Dialog from './Modal';
44
import ActionButton from './ActionButton';
5-
import { getConfirmLocale } from './locale';
6-
import { defineComponent, computed } from 'vue';
5+
import { defineComponent } from 'vue';
6+
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
77

88
interface ConfirmDialogProps extends ModalFuncProps {
99
afterClose?: () => void;
@@ -52,7 +52,7 @@ export default defineComponent<ConfirmDialogProps>({
5252
'content',
5353
] as any,
5454
setup(props, { attrs }) {
55-
const runtimeLocale = computed(() => getConfirmLocale());
55+
const [locale] = useLocaleReceiver('Modal');
5656
return () => {
5757
const {
5858
icon,
@@ -86,9 +86,9 @@ export default defineComponent<ConfirmDialogProps>({
8686
const style = attrs.style || {};
8787
const okText =
8888
renderSomeContent('okText', props.okText) ||
89-
(okCancel ? runtimeLocale.value.okText : runtimeLocale.value.justOkText);
89+
(okCancel ? locale.value.okText : locale.value.justOkText);
9090
const cancelText =
91-
renderSomeContent('cancelText', props.cancelText) || runtimeLocale.value.cancelText;
91+
renderSomeContent('cancelText', props.cancelText) || locale.value.cancelText;
9292
const autoFocusButton =
9393
props.autoFocusButton === null ? false : props.autoFocusButton || 'ok';
9494

components/modal/Modal.tsx

+7-15
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,14 @@
11
import type { ExtractPropTypes, CSSProperties, PropType } from 'vue';
2-
import { defineComponent, inject, computed } from 'vue';
2+
import { defineComponent, inject } from 'vue';
33
import classNames from '../_util/classNames';
44
import Dialog from '../vc-dialog';
55
import PropTypes from '../_util/vue-types';
66
import addEventListener from '../vc-util/Dom/addEventListener';
7-
import { getConfirmLocale } from './locale';
87
import CloseOutlined from '@ant-design/icons-vue/CloseOutlined';
98
import Button from '../button';
109
import type { ButtonProps as ButtonPropsType, LegacyButtonType } from '../button/buttonTypes';
1110
import buttonTypes, { convertLegacyProps } from '../button/buttonTypes';
12-
import LocaleReceiver from '../locale-provider/LocaleReceiver';
11+
import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
1312
import { getComponent, getSlot } from '../_util/props-util';
1413
import initDefaultProps from '../_util/props-util/initDefaultProps';
1514
import { defaultConfigProvider } from '../config-provider';
@@ -158,9 +157,9 @@ export default defineComponent({
158157
}),
159158
emits: ['update:visible', 'cancel', 'change', 'ok'],
160159
setup() {
161-
const confirmLocale = computed(() => getConfirmLocale());
160+
const [locale] = useLocaleReceiver('Modal');
162161
return {
163-
confirmLocale,
162+
locale,
164163
configProvider: inject('configProvider', defaultConfigProvider),
165164
};
166165
},
@@ -184,8 +183,8 @@ export default defineComponent({
184183
handleOk(e: MouseEvent) {
185184
this.$emit('ok', e);
186185
},
187-
renderFooter(locale: ModalLocale) {
188-
const { okType, confirmLoading } = this;
186+
renderFooter() {
187+
const { okType, confirmLoading, locale } = this;
189188
const cancelBtnProps = { onClick: this.handleCancel, ...(this.cancelButtonProps || {}) };
190189
const okBtnProps = {
191190
onClick: this.handleOk,
@@ -213,19 +212,12 @@ export default defineComponent({
213212
centered,
214213
getContainer,
215214
$attrs,
216-
confirmLocale,
217215
} = this;
218216
const children = getSlot(this);
219217
const { getPrefixCls, getPopupContainer: getContextPopupContainer } = this.configProvider;
220218
const prefixCls = getPrefixCls('modal', customizePrefixCls);
221219

222-
const defaultFooter = (
223-
<LocaleReceiver
224-
componentName="Modal"
225-
defaultLocale={confirmLocale}
226-
children={this.renderFooter}
227-
/>
228-
);
220+
const defaultFooter = this.renderFooter();
229221
const closeIcon = getComponent(this, 'closeIcon');
230222
const closeIconToRender = (
231223
<span class={`${prefixCls}-close-x`}>

components/modal/confirm.tsx

+4-10
Original file line numberDiff line numberDiff line change
@@ -2,15 +2,9 @@ import { createVNode, render as vueRender } from 'vue';
22
import ConfirmDialog from './ConfirmDialog';
33
import type { ModalFuncProps } from './Modal';
44
import { destroyFns } from './Modal';
5-
import ConfigProvider, { globalConfig } from '../config-provider';
5+
import ConfigProvider, { globalConfigForApi } from '../config-provider';
66
import omit from '../_util/omit';
77

8-
const defaultRootPrefixCls = '';
9-
10-
function getRootPrefixCls() {
11-
return defaultRootPrefixCls;
12-
}
13-
148
const confirm = (config: ModalFuncProps) => {
159
const div = document.createElement('div');
1610
document.body.appendChild(div);
@@ -60,11 +54,11 @@ const confirm = (config: ModalFuncProps) => {
6054
}
6155
}
6256
const Wrapper = (p: ModalFuncProps) => {
63-
const { getPrefixCls } = globalConfig();
64-
const rootPrefixCls = getPrefixCls(undefined, getRootPrefixCls());
57+
const global = globalConfigForApi;
58+
const rootPrefixCls = global.prefixCls;
6559
const prefixCls = p.prefixCls || `${rootPrefixCls}-modal`;
6660
return (
67-
<ConfigProvider prefixCls={rootPrefixCls}>
61+
<ConfigProvider {...(global as any)} notUpdateGlobalConfig={true} prefixCls={rootPrefixCls}>
6862
<ConfirmDialog {...p} prefixCls={prefixCls}></ConfirmDialog>
6963
</ConfigProvider>
7064
);

components/modal/locale.ts

-24
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,5 @@
1-
import { ref } from 'vue';
2-
import defaultLocale from '../locale/default';
3-
41
export interface ModalLocale {
52
okText: string;
63
cancelText: string;
74
justOkText: string;
85
}
9-
10-
const runtimeLocale = ref({
11-
...defaultLocale.Modal,
12-
});
13-
14-
export function changeConfirmLocale(newLocale?: ModalLocale) {
15-
if (newLocale) {
16-
runtimeLocale.value = {
17-
...runtimeLocale,
18-
...newLocale,
19-
};
20-
} else {
21-
runtimeLocale.value = {
22-
...defaultLocale.Modal,
23-
};
24-
}
25-
}
26-
27-
export function getConfirmLocale() {
28-
return runtimeLocale.value;
29-
}

components/vc-notification/Notification.jsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import BaseMixin from '../_util/BaseMixin';
55
import createChainedFunction from '../_util/createChainedFunction';
66
import Notice from './Notice';
77
import { getTransitionGroupProps, TransitionGroup } from '../_util/transition';
8-
import ConfigProvider, { globalConfig } from '../config-provider';
8+
import ConfigProvider, { globalConfigForApi } from '../config-provider';
99

1010
function noop() {}
1111

@@ -158,11 +158,11 @@ Notification.newInstance = function newNotificationInstance(properties, callback
158158
});
159159
});
160160
return () => {
161-
const { getPrefixCls, getRootPrefixCls } = globalConfig();
162-
const prefixCls = getPrefixCls(name, customizePrefixCls);
163-
const rootPrefixCls = getRootPrefixCls(customRootPrefixCls, prefixCls);
161+
const global = globalConfigForApi;
162+
const prefixCls = global.getPrefixCls(name, customizePrefixCls);
163+
const rootPrefixCls = global.getRootPrefixCls(customRootPrefixCls, prefixCls);
164164
return (
165-
<ConfigProvider prefixCls={rootPrefixCls}>
165+
<ConfigProvider {...global} notUpdateGlobalConfig={true} prefixCls={rootPrefixCls}>
166166
<Notification ref={notiRef} {...attrs} prefixCls={prefixCls} />
167167
</ConfigProvider>
168168
);

site/debugger/index.tsx

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
// debugger tsx
2-
import Demo from '../../components/tabs/demo/card-top.vue';
2+
import Demo from './demo/demo.vue';
33

44
export default {
5+
setup() {},
56
render() {
67
return <Demo />;
78
},

0 commit comments

Comments
 (0)