Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions site/mobile/mobile.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -292,5 +292,10 @@ export default {
name: 'color-picker',
component: () => import('tdesign-mobile-react/color-picker/_example/index.tsx'),
},
{
title: 'ConfigProvider 全局特性配置',
name: 'config-provider',
component: () => import('tdesign-mobile-react/config-provider/_example/index.tsx'),
},
],
};
2 changes: 1 addition & 1 deletion site/plugin-tdoc/md-to-react.js
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ function customRender({ source, file, md }) {
let [demoMd = '', apiMd = ''] = content.split(pageData.apiFlag);

// fix table | render error
demoMd = demoMd.replace(/`([^`]+)`/g, (str, codeStr) => {
demoMd = demoMd.replace(/`([^`\r\n]+)`/g, (str, codeStr) => {
codeStr = codeStr.replace(/"/g, "'");
return `<td-code text="${codeStr}"></td-code>`;
});
Expand Down
1 change: 1 addition & 0 deletions site/vite.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ export default ({ mode }) =>
'@doc': path.resolve(__dirname, './doc'),
'@components': path.resolve(__dirname, './src/components'),
'@common': path.resolve(__dirname, '../src/_common'),
'tdesign-mobile-react/es': path.resolve(__dirname, '../src'),
'tdesign-mobile-react': path.resolve(__dirname, '../src'),
'@test/utils': path.resolve(__dirname, '../test/utils'),
},
Expand Down
12 changes: 12 additions & 0 deletions site/web/site.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@ export default {
},
],
},
{
title: '全局配置',
type: 'component',
children: [
{
title: '全局特性配置',
name: 'button',
path: '/mobile-react/components/config-provider',
component: () => import('tdesign-mobile-react/config-provider/config-provider.md'),
},
],
},
{
title: '基础组件',
type: 'component', // 组件文档
Expand Down
4 changes: 0 additions & 4 deletions src/_util/useConfig.ts

This file was deleted.

2 changes: 1 addition & 1 deletion src/back-top/Backtop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import smoothscroll from 'smoothscroll-polyfill';
import { isString } from 'lodash-es';
import { Icon } from 'tdesign-icons-react';
import withNativeProps, { NativeProps } from '../_util/withNativeProps';
import useConfig from '../_util/useConfig';
import useConfig from '../hooks/useConfig';
import { TdBackTopProps } from './type';

export type ThemeList = 'round' | 'half-round' | 'round-dark' | 'half-round-dark';
Expand Down
2 changes: 1 addition & 1 deletion src/button/Button.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React, { forwardRef } from 'react';
import classnames from 'classnames';
import TLoading from '../loading';
import useConfig from '../_util/useConfig';
import useConfig from '../hooks/useConfig';
import parseTNode from '../_util/parseTNode';
import { TdButtonProps } from './type';
import { buttonDefaultProps } from './defaultProps';
Expand Down
2 changes: 1 addition & 1 deletion src/cell/Cell.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { cellDefaultProps } from './defaultProps';
import withNativeProps, { NativeProps } from '../_util/withNativeProps';
import useDefaultProps from '../hooks/useDefaultProps';
import useHover from '../hooks/useHover';
import useConfig from '../_util/useConfig';
import useConfig from '../hooks/useConfig';

export interface CellProps extends TdCellProps, NativeProps {}

Expand Down
2 changes: 1 addition & 1 deletion src/cell/CellGroup.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useMemo } from 'react';
import classnames from 'classnames';
import useConfig from '../_util/useConfig';
import useConfig from '../hooks/useConfig';
import { TdCellGroupProps } from './type';
import { cellGroupDefaultProps } from './defaultProps';
import withNativeProps, { NativeProps } from '../_util/withNativeProps';
Expand Down
2 changes: 1 addition & 1 deletion src/checkbox/Checkbox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import {
import { TdCheckboxProps } from './type';
import forwardRefWithStatics from '../_util/forwardRefWithStatics';
import CheckboxGroup from './CheckboxGroup';
import useConfig from '../_util/useConfig';
import useConfig from '../hooks/useConfig';
import useDefault from '../_util/useDefault';
import { parseContentTNode } from '../_util/parseTNode';
import { usePrefixClass } from '../hooks/useClass';
Expand Down
30 changes: 13 additions & 17 deletions src/config-provider/ConfigContext.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,26 @@
import { createContext } from 'react';
import merge from 'lodash/merge';
import { merge } from 'lodash-es';
import defaultLocale from '../locale/zh_CN';
import defaultConfig from '../_common/js/global-config/default-config';
import defaultConfig from '../_common/js/global-config/mobile/default-config';
import { GlobalConfigProvider } from './type';

export const defaultClassPrefix = 't';

export interface Config {
/**
* 组件类名前缀
*
* @default 't'
*/
classPrefix?: string;
/**
* 全局配置
*/
globalConfig?: Locale;
}
type DefaultGlobalConfig = Partial<GlobalConfigProvider>;

export const defaultContext = {
export const defaultGlobalConfig: DefaultGlobalConfig = {
classPrefix: defaultClassPrefix,
globalConfig: merge({}, defaultConfig, defaultLocale),
...merge({}, defaultLocale, defaultConfig),
};

export type Locale = typeof defaultLocale;

const ConfigContext = createContext<Config>(defaultContext);
export const defaultContext = {
globalConfig: defaultGlobalConfig,
};

export type Config = typeof defaultContext;

const ConfigContext = createContext(defaultContext);

export default ConfigContext;
17 changes: 14 additions & 3 deletions src/config-provider/ConfigProvider.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@
import React from 'react';
import ConfigContext, { Config, defaultContext } from './ConfigContext';
import { mergeWith as _mergeWith } from 'lodash-es';
import ConfigContext, { defaultGlobalConfig, Config } from './ConfigContext';
import { GlobalConfigProvider } from './type';

export interface ConfigProviderProps extends Config {
children: React.ReactNode;
}

export default function ConfigProvider({ children, ...configProps }: ConfigProviderProps) {
return <ConfigContext.Provider value={{ ...defaultContext, ...configProps }}>{children}</ConfigContext.Provider>;
// deal with https://github.com/lodash/lodash/issues/1313
export const merge = (src: GlobalConfigProvider, config: GlobalConfigProvider) =>
_mergeWith(src, config, (objValue, srcValue) => {
if (Array.isArray(objValue)) {
return srcValue;
}
});

export default function ConfigProvider({ children, globalConfig }: ConfigProviderProps) {
const mergedGlobalConfig = merge({ ...defaultGlobalConfig }, globalConfig);
return <ConfigContext.Provider value={{ globalConfig: mergedGlobalConfig }}>{children}</ConfigContext.Provider>;
}

ConfigProvider.displayName = 'ConfigProvider';
28 changes: 28 additions & 0 deletions src/config-provider/_example/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import TDemoBlock from '../../../site/mobile/components/DemoBlock';
import TDemoHeader from '../../../site/mobile/components/DemoHeader';
import OtherEn from './other-en';
import TableEn from './table-en';
import UploadEn from './upload-en';

import './style/index.less';

export default function EmptyDemo() {
return (
<div className="tdesign-mobile-demo">
<TDemoHeader
title="ConfigProvider 全局配置"
summary="全局特性配置包含各个组件的文本语言配置及其他通用配置,可以减少重复的通用配置。"
/>
<TDemoBlock summary="Upload">
<UploadEn />
</TDemoBlock>
<TDemoBlock summary="Table">
<TableEn />
</TDemoBlock>
<TDemoBlock summary="其他组件">
<OtherEn />
</TDemoBlock>
</div>
);
}
50 changes: 50 additions & 0 deletions src/config-provider/_example/other-en.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React, { useState } from 'react';
import { ConfigProvider, Rate, Calendar, Cell } from 'tdesign-mobile-react';
import { merge } from 'lodash-es';
import enConfig from 'tdesign-mobile-react/es/locale/en_US';

export default function OtherEn() {
// 全局特性配置,可以引入英文默认配置 enConfig,还可以在默认配置的基础上进行自定义配置
const globalConfig = merge(enConfig, {});

const [rateValue, setRateValue] = useState(3);
const [dataNote, setDataNote] = useState('');
const [visible, setVisible] = useState(false);

const format = (val: Date) => {
const date = new Date(val);
return `${date.getFullYear()}-${date.getMonth() + 1}-${date.getDate()}`;
};

const handleConfirm = (val: Date) => {
console.log(val);
setDataNote(format(val));
setVisible(false);
};

const handleSelect = (val: Date) => {
console.log(val);
};

const onClose = (trigger: string) => {
setVisible(false);
console.log('closed by', trigger);
};

return (
<ConfigProvider globalConfig={globalConfig}>
<div className="rate-demo-cell rate-demo-cell--space">
<div className="rate-demo-cell__label">Rating</div>
<Rate
value={rateValue}
showText={true}
onChange={(value) => {
setRateValue(value);
}}
/>
</div>
<Calendar visible={visible} onConfirm={handleConfirm} onSelect={handleSelect} onClose={onClose}></Calendar>
<Cell title="Single select date" arrow note={dataNote} onClick={() => setVisible(true)}></Cell>
</ConfigProvider>
);
}
33 changes: 33 additions & 0 deletions src/config-provider/_example/style/index.less
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
.rate-demo-cell {
background-color: var(--bg-color-demo, #fff);
padding: 12px 16px;
line-height: 1;
display: flex;
align-items: center;
justify-content: space-between;

&__label {
font-size: 16px;
margin-right: 16px;
min-width: 80px;
color: var(--td-text-color-primary, rgba(0, 0, 0, 0.9));
}

&--space {
margin-bottom: 16px;
}
}

.upload-demo {
background: var(--bg-color-demo, #fff);

& + & {
margin-top: 16px;
}

&__title {
font-size: 14px;
margin: 24px 16px 16px;
color: var(--td-text-color-secondary, rgba(0, 0, 0, 0.6));
}
}
35 changes: 35 additions & 0 deletions src/config-provider/_example/table-en.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import React from 'react';
import { ConfigProvider, Table } from 'tdesign-mobile-react';
import { merge } from 'lodash-es';
import enConfig from 'tdesign-mobile-react/es/locale/en_US';

export default function TableEn() {
// 全局特性配置,可以引入英文默认配置 enConfig,还可以在默认配置的基础上进行自定义配置
const globalConfig = merge(enConfig, {});

const columns = [
{
colKey: 'type',
title: 'Type',
sorter: true,
},
{
colKey: 'platform',
title: 'Platform',
},
{
colKey: 'property',
title: 'Property',
sorter: true,
filter: {
type: 'single',
},
},
];

return (
<ConfigProvider globalConfig={globalConfig}>
<Table columns={columns} data={[]} bordered={true} rowKey="property"></Table>
</ConfigProvider>
);
}
48 changes: 48 additions & 0 deletions src/config-provider/_example/upload-en.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React, { useState } from 'react';
import { ConfigProvider, Upload } from 'tdesign-mobile-react';
import type { UploadRemoveContext } from 'tdesign-mobile-react';
import { merge } from 'lodash-es';
import enConfig from 'tdesign-mobile-react/es/locale/en_US';

export default function TableEn() {
// 全局特性配置,可以引入英文默认配置 enConfig,还可以在默认配置的基础上进行自定义配置
const globalConfig = merge(enConfig, {});

const [files, setFiles] = useState([
{
url: 'https://tdesign.gtimg.com/mobile/demos/upload6.png',
name: 'uploaded1.png',
type: 'image',
},
{
url: 'https://tdesign.gtimg.com/mobile/demos/upload4.png',
name: 'uploaded1.png',
type: 'image',
percent: 68,
},
{
url: 'https://tdesign.gtimg.com/mobile/demos/upload4.png',
name: 'uploaded1.png',
type: 'image',
},
]);

const handleRemove = (context: UploadRemoveContext) => {
const { index } = context;
setFiles(files.filter((item, idx) => index !== idx));
};

return (
<ConfigProvider globalConfig={globalConfig}>
<div className="upload-demo">
<Upload
accept="image/jpeg"
files={files}
action="//service-bv448zsw-1257786608.gz.apigw.tencentcs.com/api/upload-demo"
multiple
onRemove={handleRemove}
/>
</div>
</ConfigProvider>
);
}
Loading