index.js 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427
  1. "use client";
  2. var __rest = this && this.__rest || function (s, e) {
  3. var t = {};
  4. for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) t[p] = s[p];
  5. if (s != null && typeof Object.getOwnPropertySymbols === "function") for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
  6. if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i])) t[p[i]] = s[p[i]];
  7. }
  8. return t;
  9. };
  10. import * as React from 'react';
  11. import { createTheme, StyleContext as CssInJsStyleContext } from '@ant-design/cssinjs';
  12. import IconContext from "@ant-design/icons/es/components/Context";
  13. import useMemo from "rc-util/es/hooks/useMemo";
  14. import { merge } from "rc-util/es/utils/set";
  15. import warning, { devUseWarning, WarningContext } from '../_util/warning';
  16. import ValidateMessagesContext from '../form/validateMessagesContext';
  17. import LocaleProvider, { ANT_MARK } from '../locale';
  18. import LocaleContext from '../locale/context';
  19. import defaultLocale from '../locale/en_US';
  20. import { defaultTheme, DesignTokenContext } from '../theme/context';
  21. import defaultSeedToken from '../theme/themes/seed';
  22. import { ConfigConsumer, ConfigContext, defaultIconPrefixCls, defaultPrefixCls, Variants } from './context';
  23. import { registerTheme } from './cssVariables';
  24. import { DisabledContextProvider } from './DisabledContext';
  25. import useConfig from './hooks/useConfig';
  26. import useTheme from './hooks/useTheme';
  27. import MotionWrapper from './MotionWrapper';
  28. import PropWarning from './PropWarning';
  29. import SizeContext, { SizeContextProvider } from './SizeContext';
  30. import useStyle from './style';
  31. export { Variants };
  32. /**
  33. * Since too many feedback using static method like `Modal.confirm` not getting theme, we record the
  34. * theme register info here to help developer get warning info.
  35. */
  36. let existThemeConfig = false;
  37. export const warnContext = process.env.NODE_ENV !== 'production' ? componentName => {
  38. process.env.NODE_ENV !== "production" ? warning(!existThemeConfig, componentName, `Static function can not consume context like dynamic theme. Please use 'App' component instead.`) : void 0;
  39. } : /* istanbul ignore next */
  40. null;
  41. export { ConfigConsumer, ConfigContext, defaultPrefixCls, defaultIconPrefixCls };
  42. export const configConsumerProps = ['getTargetContainer', 'getPopupContainer', 'rootPrefixCls', 'getPrefixCls', 'renderEmpty', 'csp', 'autoInsertSpaceInButton', 'locale'];
  43. // These props is used by `useContext` directly in sub component
  44. const PASSED_PROPS = ['getTargetContainer', 'getPopupContainer', 'renderEmpty', 'input', 'pagination', 'form', 'select', 'button'];
  45. let globalPrefixCls;
  46. let globalIconPrefixCls;
  47. let globalTheme;
  48. let globalHolderRender;
  49. function getGlobalPrefixCls() {
  50. return globalPrefixCls || defaultPrefixCls;
  51. }
  52. function getGlobalIconPrefixCls() {
  53. return globalIconPrefixCls || defaultIconPrefixCls;
  54. }
  55. function isLegacyTheme(theme) {
  56. return Object.keys(theme).some(key => key.endsWith('Color'));
  57. }
  58. const setGlobalConfig = props => {
  59. const {
  60. prefixCls,
  61. iconPrefixCls,
  62. theme,
  63. holderRender
  64. } = props;
  65. if (prefixCls !== undefined) {
  66. globalPrefixCls = prefixCls;
  67. }
  68. if (iconPrefixCls !== undefined) {
  69. globalIconPrefixCls = iconPrefixCls;
  70. }
  71. if ('holderRender' in props) {
  72. globalHolderRender = holderRender;
  73. }
  74. if (theme) {
  75. if (isLegacyTheme(theme)) {
  76. process.env.NODE_ENV !== "production" ? warning(false, 'ConfigProvider', '`config` of css variable theme is not work in v5. Please use new `theme` config instead.') : void 0;
  77. registerTheme(getGlobalPrefixCls(), theme);
  78. } else {
  79. globalTheme = theme;
  80. }
  81. }
  82. };
  83. export const globalConfig = () => ({
  84. getPrefixCls: (suffixCls, customizePrefixCls) => {
  85. if (customizePrefixCls) {
  86. return customizePrefixCls;
  87. }
  88. return suffixCls ? `${getGlobalPrefixCls()}-${suffixCls}` : getGlobalPrefixCls();
  89. },
  90. getIconPrefixCls: getGlobalIconPrefixCls,
  91. getRootPrefixCls: () => {
  92. // If Global prefixCls provided, use this
  93. if (globalPrefixCls) {
  94. return globalPrefixCls;
  95. }
  96. // Fallback to default prefixCls
  97. return getGlobalPrefixCls();
  98. },
  99. getTheme: () => globalTheme,
  100. holderRender: globalHolderRender
  101. });
  102. const ProviderChildren = props => {
  103. const {
  104. children,
  105. csp: customCsp,
  106. autoInsertSpaceInButton,
  107. alert,
  108. anchor,
  109. form,
  110. locale,
  111. componentSize,
  112. direction,
  113. space,
  114. splitter,
  115. virtual,
  116. dropdownMatchSelectWidth,
  117. popupMatchSelectWidth,
  118. popupOverflow,
  119. legacyLocale,
  120. parentContext,
  121. iconPrefixCls: customIconPrefixCls,
  122. theme,
  123. componentDisabled,
  124. segmented,
  125. statistic,
  126. spin,
  127. calendar,
  128. carousel,
  129. cascader,
  130. collapse,
  131. typography,
  132. checkbox,
  133. descriptions,
  134. divider,
  135. drawer,
  136. skeleton,
  137. steps,
  138. image,
  139. layout,
  140. list,
  141. mentions,
  142. modal,
  143. progress,
  144. result,
  145. slider,
  146. breadcrumb,
  147. menu,
  148. pagination,
  149. input,
  150. textArea,
  151. empty,
  152. badge,
  153. radio,
  154. rate,
  155. switch: SWITCH,
  156. transfer,
  157. avatar,
  158. message,
  159. tag,
  160. table,
  161. card,
  162. tabs,
  163. timeline,
  164. timePicker,
  165. upload,
  166. notification,
  167. tree,
  168. colorPicker,
  169. datePicker,
  170. rangePicker,
  171. flex,
  172. wave,
  173. dropdown,
  174. warning: warningConfig,
  175. tour,
  176. tooltip,
  177. popover,
  178. popconfirm,
  179. floatButton,
  180. floatButtonGroup,
  181. variant,
  182. inputNumber,
  183. treeSelect
  184. } = props;
  185. // =================================== Context ===================================
  186. const getPrefixCls = React.useCallback((suffixCls, customizePrefixCls) => {
  187. const {
  188. prefixCls
  189. } = props;
  190. if (customizePrefixCls) {
  191. return customizePrefixCls;
  192. }
  193. const mergedPrefixCls = prefixCls || parentContext.getPrefixCls('');
  194. return suffixCls ? `${mergedPrefixCls}-${suffixCls}` : mergedPrefixCls;
  195. }, [parentContext.getPrefixCls, props.prefixCls]);
  196. const iconPrefixCls = customIconPrefixCls || parentContext.iconPrefixCls || defaultIconPrefixCls;
  197. const csp = customCsp || parentContext.csp;
  198. useStyle(iconPrefixCls, csp);
  199. const mergedTheme = useTheme(theme, parentContext.theme, {
  200. prefixCls: getPrefixCls('')
  201. });
  202. if (process.env.NODE_ENV !== 'production') {
  203. existThemeConfig = existThemeConfig || !!mergedTheme;
  204. }
  205. const baseConfig = {
  206. csp,
  207. autoInsertSpaceInButton,
  208. alert,
  209. anchor,
  210. locale: locale || legacyLocale,
  211. direction,
  212. space,
  213. splitter,
  214. virtual,
  215. popupMatchSelectWidth: popupMatchSelectWidth !== null && popupMatchSelectWidth !== void 0 ? popupMatchSelectWidth : dropdownMatchSelectWidth,
  216. popupOverflow,
  217. getPrefixCls,
  218. iconPrefixCls,
  219. theme: mergedTheme,
  220. segmented,
  221. statistic,
  222. spin,
  223. calendar,
  224. carousel,
  225. cascader,
  226. collapse,
  227. typography,
  228. checkbox,
  229. descriptions,
  230. divider,
  231. drawer,
  232. skeleton,
  233. steps,
  234. image,
  235. input,
  236. textArea,
  237. layout,
  238. list,
  239. mentions,
  240. modal,
  241. progress,
  242. result,
  243. slider,
  244. breadcrumb,
  245. menu,
  246. pagination,
  247. empty,
  248. badge,
  249. radio,
  250. rate,
  251. switch: SWITCH,
  252. transfer,
  253. avatar,
  254. message,
  255. tag,
  256. table,
  257. card,
  258. tabs,
  259. timeline,
  260. timePicker,
  261. upload,
  262. notification,
  263. tree,
  264. colorPicker,
  265. datePicker,
  266. rangePicker,
  267. flex,
  268. wave,
  269. dropdown,
  270. warning: warningConfig,
  271. tour,
  272. tooltip,
  273. popover,
  274. popconfirm,
  275. floatButton,
  276. floatButtonGroup,
  277. variant,
  278. inputNumber,
  279. treeSelect
  280. };
  281. if (process.env.NODE_ENV !== 'production') {
  282. const warningFn = devUseWarning('ConfigProvider');
  283. warningFn(!('autoInsertSpaceInButton' in props), 'deprecated', '`autoInsertSpaceInButton` is deprecated. Please use `{ button: { autoInsertSpace: boolean }}` instead.');
  284. }
  285. const config = Object.assign({}, parentContext);
  286. Object.keys(baseConfig).forEach(key => {
  287. if (baseConfig[key] !== undefined) {
  288. config[key] = baseConfig[key];
  289. }
  290. });
  291. // Pass the props used by `useContext` directly with child component.
  292. // These props should merged into `config`.
  293. PASSED_PROPS.forEach(propName => {
  294. const propValue = props[propName];
  295. if (propValue) {
  296. config[propName] = propValue;
  297. }
  298. });
  299. if (typeof autoInsertSpaceInButton !== 'undefined') {
  300. // merge deprecated api
  301. config.button = Object.assign({
  302. autoInsertSpace: autoInsertSpaceInButton
  303. }, config.button);
  304. }
  305. // https://github.com/ant-design/ant-design/issues/27617
  306. const memoedConfig = useMemo(() => config, config, (prevConfig, currentConfig) => {
  307. const prevKeys = Object.keys(prevConfig);
  308. const currentKeys = Object.keys(currentConfig);
  309. return prevKeys.length !== currentKeys.length || prevKeys.some(key => prevConfig[key] !== currentConfig[key]);
  310. });
  311. const {
  312. layer
  313. } = React.useContext(CssInJsStyleContext);
  314. const memoIconContextValue = React.useMemo(() => ({
  315. prefixCls: iconPrefixCls,
  316. csp,
  317. layer: layer ? 'antd' : undefined
  318. }), [iconPrefixCls, csp, layer]);
  319. let childNode = /*#__PURE__*/React.createElement(React.Fragment, null, /*#__PURE__*/React.createElement(PropWarning, {
  320. dropdownMatchSelectWidth: dropdownMatchSelectWidth
  321. }), children);
  322. const validateMessages = React.useMemo(() => {
  323. var _a, _b, _c, _d;
  324. return merge(((_a = defaultLocale.Form) === null || _a === void 0 ? void 0 : _a.defaultValidateMessages) || {}, ((_c = (_b = memoedConfig.locale) === null || _b === void 0 ? void 0 : _b.Form) === null || _c === void 0 ? void 0 : _c.defaultValidateMessages) || {}, ((_d = memoedConfig.form) === null || _d === void 0 ? void 0 : _d.validateMessages) || {}, (form === null || form === void 0 ? void 0 : form.validateMessages) || {});
  325. }, [memoedConfig, form === null || form === void 0 ? void 0 : form.validateMessages]);
  326. if (Object.keys(validateMessages).length > 0) {
  327. childNode = /*#__PURE__*/React.createElement(ValidateMessagesContext.Provider, {
  328. value: validateMessages
  329. }, childNode);
  330. }
  331. if (locale) {
  332. childNode = /*#__PURE__*/React.createElement(LocaleProvider, {
  333. locale: locale,
  334. _ANT_MARK__: ANT_MARK
  335. }, childNode);
  336. }
  337. if (iconPrefixCls || csp) {
  338. childNode = /*#__PURE__*/React.createElement(IconContext.Provider, {
  339. value: memoIconContextValue
  340. }, childNode);
  341. }
  342. if (componentSize) {
  343. childNode = /*#__PURE__*/React.createElement(SizeContextProvider, {
  344. size: componentSize
  345. }, childNode);
  346. }
  347. // =================================== Motion ===================================
  348. childNode = /*#__PURE__*/React.createElement(MotionWrapper, null, childNode);
  349. // ================================ Dynamic theme ================================
  350. const memoTheme = React.useMemo(() => {
  351. const _a = mergedTheme || {},
  352. {
  353. algorithm,
  354. token,
  355. components,
  356. cssVar
  357. } = _a,
  358. rest = __rest(_a, ["algorithm", "token", "components", "cssVar"]);
  359. const themeObj = algorithm && (!Array.isArray(algorithm) || algorithm.length > 0) ? createTheme(algorithm) : defaultTheme;
  360. const parsedComponents = {};
  361. Object.entries(components || {}).forEach(([componentName, componentToken]) => {
  362. const parsedToken = Object.assign({}, componentToken);
  363. if ('algorithm' in parsedToken) {
  364. if (parsedToken.algorithm === true) {
  365. parsedToken.theme = themeObj;
  366. } else if (Array.isArray(parsedToken.algorithm) || typeof parsedToken.algorithm === 'function') {
  367. parsedToken.theme = createTheme(parsedToken.algorithm);
  368. }
  369. delete parsedToken.algorithm;
  370. }
  371. parsedComponents[componentName] = parsedToken;
  372. });
  373. const mergedToken = Object.assign(Object.assign({}, defaultSeedToken), token);
  374. return Object.assign(Object.assign({}, rest), {
  375. theme: themeObj,
  376. token: mergedToken,
  377. components: parsedComponents,
  378. override: Object.assign({
  379. override: mergedToken
  380. }, parsedComponents),
  381. cssVar: cssVar
  382. });
  383. }, [mergedTheme]);
  384. if (theme) {
  385. childNode = /*#__PURE__*/React.createElement(DesignTokenContext.Provider, {
  386. value: memoTheme
  387. }, childNode);
  388. }
  389. // ================================== Warning ===================================
  390. if (memoedConfig.warning) {
  391. childNode = /*#__PURE__*/React.createElement(WarningContext.Provider, {
  392. value: memoedConfig.warning
  393. }, childNode);
  394. }
  395. // =================================== Render ===================================
  396. if (componentDisabled !== undefined) {
  397. childNode = /*#__PURE__*/React.createElement(DisabledContextProvider, {
  398. disabled: componentDisabled
  399. }, childNode);
  400. }
  401. return /*#__PURE__*/React.createElement(ConfigContext.Provider, {
  402. value: memoedConfig
  403. }, childNode);
  404. };
  405. const ConfigProvider = props => {
  406. const context = React.useContext(ConfigContext);
  407. const antLocale = React.useContext(LocaleContext);
  408. return /*#__PURE__*/React.createElement(ProviderChildren, Object.assign({
  409. parentContext: context,
  410. legacyLocale: antLocale
  411. }, props));
  412. };
  413. ConfigProvider.ConfigContext = ConfigContext;
  414. ConfigProvider.SizeContext = SizeContext;
  415. ConfigProvider.config = setGlobalConfig;
  416. ConfigProvider.useConfig = useConfig;
  417. Object.defineProperty(ConfigProvider, 'SizeContext', {
  418. get: () => {
  419. process.env.NODE_ENV !== "production" ? warning(false, 'ConfigProvider', 'ConfigProvider.SizeContext is deprecated. Please use `ConfigProvider.useConfig().componentSize` instead.') : void 0;
  420. return SizeContext;
  421. }
  422. });
  423. if (process.env.NODE_ENV !== 'production') {
  424. ConfigProvider.displayName = 'ConfigProvider';
  425. }
  426. export default ConfigProvider;