diff --git a/.dumirc.ts b/.dumirc.ts index cba719be0..a19c09d21 100644 --- a/.dumirc.ts +++ b/.dumirc.ts @@ -189,6 +189,10 @@ export default defineConfig({ { title: 'Welcome 欢迎页', link: '/biz-components/welcome' }, ], }, + { + title: 'ProComponents 组件', + children: [{ title: 'ProTable 高级表格', link: '/biz-components/pro-table' }], + }, { title: '可视化', children: [ diff --git a/packages/design/src/config-provider/index.tsx b/packages/design/src/config-provider/index.tsx index e11ba0529..ab9bcc567 100644 --- a/packages/design/src/config-provider/index.tsx +++ b/packages/design/src/config-provider/index.tsx @@ -6,6 +6,7 @@ import type { ThemeConfig as AntThemeConfig, } from 'antd/es/config-provider'; import type { ComponentStyleConfig } from 'antd/es/config-provider/context'; +import type { PaginationConfig } from 'antd/es/pagination'; import type { SpinIndicator } from 'antd/es/spin'; import { StyleProvider } from '@ant-design/cssinjs'; import type { StyleProviderProps } from '@ant-design/cssinjs'; @@ -58,6 +59,7 @@ export interface ConfigProviderProps extends AntConfigProviderProps { // for react-router-dom v6: navigate navigate?: NavigateFunction; hideOnSinglePage?: boolean; + pagination?: PaginationConfig; spin?: SpinConfig; table?: TableConfig; // inject static function to consume ConfigProvider diff --git a/packages/design/src/form/index.tsx b/packages/design/src/form/index.tsx index 98bebc91a..5e34322e5 100644 --- a/packages/design/src/form/index.tsx +++ b/packages/design/src/form/index.tsx @@ -20,22 +20,16 @@ type CompoundedComponent = React.FC & { create: typeof AntForm.create; }; -const Form: CompoundedComponent = ({ hideRequiredMark, ...restProps }) => { +const Form: CompoundedComponent = props => { const { form: contextForm } = useContext(ConfigProvider.ConfigContext); return ( // @ts-ignore to ignore children type error ); }; diff --git a/packages/design/src/locale/en-US.ts b/packages/design/src/locale/en-US.ts index 4c35b4416..a62c877b3 100644 --- a/packages/design/src/locale/en-US.ts +++ b/packages/design/src/locale/en-US.ts @@ -7,6 +7,10 @@ export default { ...enUS.global, inputPlaceholder: 'Please enter', }, + Pagination: { + ...enUS.Pagination, + total: '${total} in Total', + }, Drawer: { okText: 'OK', cancelText: 'Cancel', diff --git a/packages/design/src/locale/index.ts b/packages/design/src/locale/index.ts index 39116cc09..6356f6d32 100644 --- a/packages/design/src/locale/index.ts +++ b/packages/design/src/locale/index.ts @@ -1,4 +1,5 @@ import type { Locale as AntLocale } from 'antd/es/locale'; +import type { PaginationLocale as AntPaginationLocale } from 'antd/es/pagination/Pagination'; import type { DrawerLocale } from '../drawer'; import type { InputLocale } from '../input'; import type { InputNumberLocale } from '../input-number'; @@ -12,8 +13,13 @@ export type GlobalLocale = AntLocale['global'] & { inputPlaceholder?: string; }; +export interface PaginationLocale extends AntPaginationLocale { + total?: string; +} + export interface Locale extends AntLocale { global?: GlobalLocale; + Pagination?: PaginationLocale; Drawer?: DrawerLocale; Input?: InputLocale; InputNumber?: InputNumberLocale; diff --git a/packages/design/src/locale/zh-CN.ts b/packages/design/src/locale/zh-CN.ts index 4db3fd287..85451c12c 100644 --- a/packages/design/src/locale/zh-CN.ts +++ b/packages/design/src/locale/zh-CN.ts @@ -7,6 +7,10 @@ export default { ...zhCN.global, inputPlaceholder: '请输入', }, + Pagination: { + ...zhCN.Pagination, + total: '共 ${total} 条', + }, Drawer: { okText: '确定', cancelText: '取消', diff --git a/packages/design/src/locale/zh-TW.ts b/packages/design/src/locale/zh-TW.ts index d63908d51..985e6fd6f 100644 --- a/packages/design/src/locale/zh-TW.ts +++ b/packages/design/src/locale/zh-TW.ts @@ -7,6 +7,10 @@ export default { ...zhTW.global, inputPlaceholder: '請輸入', }, + Pagination: { + ...zhTW.Pagination, + total: '共 ${total} 條', + }, Drawer: { okText: '确定', cancelText: '取消', diff --git a/packages/design/src/table/__tests__/__snapshots__/index.test.tsx.snap b/packages/design/src/table/__tests__/__snapshots__/index.test.tsx.snap index 059e8d381..05531056f 100644 --- a/packages/design/src/table/__tests__/__snapshots__/index.test.tsx.snap +++ b/packages/design/src/table/__tests__/__snapshots__/index.test.tsx.snap @@ -1,5 +1,944 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`Table > ConfigProvider pagination should work 1`] = ` +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Age + + Address +
+ John 1 + + 32 + + 1 Road, Hangzhou, Zhejiang Province +
+ John 2 + + 32 + + 2 Road, Hangzhou, Zhejiang Province +
+ John 3 + + 32 + + 3 Road, Hangzhou, Zhejiang Province +
+ John 4 + + 32 + + 4 Road, Hangzhou, Zhejiang Province +
+ John 5 + + 32 + + 5 Road, Hangzhou, Zhejiang Province +
+ John 6 + + 32 + + 6 Road, Hangzhou, Zhejiang Province +
+ John 7 + + 32 + + 7 Road, Hangzhou, Zhejiang Province +
+ John 8 + + 32 + + 8 Road, Hangzhou, Zhejiang Province +
+ John 9 + + 32 + + 9 Road, Hangzhou, Zhejiang Province +
+ John 10 + + 32 + + 10 Road, Hangzhou, Zhejiang Province +
+
+
+
+ +
+
+
+`; + +exports[`Table > default pagination should work 1`] = ` +
+
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Name + + Age + + Address +
+ John 1 + + 32 + + 1 Road, Hangzhou, Zhejiang Province +
+ John 2 + + 32 + + 2 Road, Hangzhou, Zhejiang Province +
+ John 3 + + 32 + + 3 Road, Hangzhou, Zhejiang Province +
+ John 4 + + 32 + + 4 Road, Hangzhou, Zhejiang Province +
+ John 5 + + 32 + + 5 Road, Hangzhou, Zhejiang Province +
+ John 6 + + 32 + + 6 Road, Hangzhou, Zhejiang Province +
+ John 7 + + 32 + + 7 Road, Hangzhou, Zhejiang Province +
+ John 8 + + 32 + + 8 Road, Hangzhou, Zhejiang Province +
+ John 9 + + 32 + + 9 Road, Hangzhou, Zhejiang Province +
+ John 10 + + 32 + + 10 Road, Hangzhou, Zhejiang Province +
+
+
+
+ +
+
+
+`; + exports[`Table > hideOnSinglePage could be changed 1`] = `
hideOnSinglePage should be false by default 1`] = `
  • - + + 10 in Total +
  • hideOnSinglePage should be false by default 1`] = `
  • +
  • + +
  • @@ -865,7 +1869,9 @@ exports[`Table > render 1`] = `
  • - + + 99 in Total +
  • { @@ -57,4 +59,31 @@ describe('Table', () => { expect(container.querySelector('.ant-pagination')).toBeFalsy(); expect(asFragment().firstChild).toMatchSnapshot(); }); + + it('default pagination should work', () => { + const { container, asFragment } = render(); + // pagination.showTotal + expect(container.querySelector('.ant-pagination-total-text').textContent).toBe('99 in Total'); + // pagination.showSizeChanger + expect(container.querySelector('.ant-pagination-options')).toBeTruthy(); + expect(asFragment().firstChild).toMatchSnapshot(); + }); + + it('ConfigProvider pagination should work', () => { + const { container, asFragment } = render( + + + + ); + // pagination.showTotal + expect(container.querySelector('.ant-pagination-total-text').textContent).toBe(''); + // pagination.showSizeChanger + expect(container.querySelector('.ant-pagination-options')).toBeFalsy(); + expect(asFragment().firstChild).toMatchSnapshot(); + }); }); diff --git a/packages/design/src/table/demo/multiple-nesting-tables.tsx b/packages/design/src/table/demo/multiple-nesting-tables.tsx index 5205669ef..baea9ed92 100644 --- a/packages/design/src/table/demo/multiple-nesting-tables.tsx +++ b/packages/design/src/table/demo/multiple-nesting-tables.tsx @@ -145,9 +145,6 @@ const App: React.FC = () => { setSelectedRowKeys(keys); }, }} - pagination={{ - showTotal: total => `共 ${total} 条`, - }} /> ); diff --git a/packages/design/src/table/demo/row-selection.tsx b/packages/design/src/table/demo/row-selection.tsx index 97e733d47..67a8b4d26 100644 --- a/packages/design/src/table/demo/row-selection.tsx +++ b/packages/design/src/table/demo/row-selection.tsx @@ -92,9 +92,6 @@ const App: React.FC = () => { setSelectedRowKeys(keys); }, }} - pagination={{ - showTotal: total => `共 ${total} 条`, - }} /> ); }; diff --git a/packages/design/src/table/hooks/useDefaultPagination.ts b/packages/design/src/table/hooks/useDefaultPagination.ts new file mode 100644 index 000000000..6a6c3e74d --- /dev/null +++ b/packages/design/src/table/hooks/useDefaultPagination.ts @@ -0,0 +1,26 @@ +import { useContext } from 'react'; +import type { TablePaginationConfig } from 'antd'; +import ConfigProvider from '../../config-provider'; +import type { ConfigConsumerProps } from '../../config-provider'; +import defaultLocale from '../../locale/en-US'; +import type { PaginationLocale } from '../../locale'; + +export default (pagination?: false | TablePaginationConfig): false | TablePaginationConfig => { + const { locale: contextLocale, pagination: contextPagination } = useContext( + ConfigProvider.ConfigContext + ); + const paginationLocale: PaginationLocale = { + ...defaultLocale.Pagination, + ...contextLocale?.Pagination, + }; + return pagination === false + ? pagination + : { + defaultPageSize: 10, + showSizeChanger: true, + pageSizeOptions: ['10', '20', '50', '100'], + showTotal: total => paginationLocale.total?.replaceAll('${total}', total?.toString()), + ...contextPagination, + ...pagination, + }; +}; diff --git a/packages/design/src/table/index.md b/packages/design/src/table/index.md index f8b20a94a..88846780f 100644 --- a/packages/design/src/table/index.md +++ b/packages/design/src/table/index.md @@ -46,6 +46,7 @@ nav: | 参数 | 说明 | 类型 | 默认值 | 版本 | | :-- | :-- | :-- | :-- | :-- | +| pagination | 分页配置 | ReactNode | {} | - | | cancelText | 选择表格中 取消 按钮文案 | ReactNode | - | - | | collapseText | 选择表格中 收起 按钮文案 | ReactNode | - | - | | openText | 选择表格中 展开 按钮文案 | ReactNode | - | - | diff --git a/packages/design/src/table/index.tsx b/packages/design/src/table/index.tsx index 89a5b0496..77393f477 100644 --- a/packages/design/src/table/index.tsx +++ b/packages/design/src/table/index.tsx @@ -11,8 +11,9 @@ import React, { useContext, useEffect, useState } from 'react'; import ConfigProvider from '../config-provider'; import Typography from '../typography'; import enUS from '../locale/en-US'; -import useStyle from './style'; +import useStyle, { genTableStyle } from './style'; import type { AnyObject } from '../_util/type'; +import useDefaultPagination from './hooks/useDefaultPagination'; export * from 'antd/es/table'; @@ -39,7 +40,7 @@ function Table(props: TableProps, ref: React.Ref) { const { locale: customLocale, columns, - pagination, + pagination: customPagination, rowSelection, toolAlertRender, toolOptionsRender, @@ -50,6 +51,7 @@ function Table(props: TableProps, ref: React.Ref) { className, } = props; const extendedContext = useContext(ConfigProvider.ExtendedConfigContext); + const pagination = useDefaultPagination(customPagination); const { batchOperationBar, ...restLocale } = { ...customLocale, @@ -244,4 +246,6 @@ export default Object.assign(ForwardTable, { Column: AntTable.Column, ColumnGroup: AntTable.ColumnGroup, Summary: AntTable.Summary as typeof Summary, + genTableStyle, + useDefaultPagination, }); diff --git a/packages/ui/src/ProTable/demo/basic.tsx b/packages/ui/src/ProTable/demo/basic.tsx new file mode 100644 index 000000000..50a3dc080 --- /dev/null +++ b/packages/ui/src/ProTable/demo/basic.tsx @@ -0,0 +1,36 @@ +import React from 'react'; +import { ProTable } from '@oceanbase/ui'; + +const App: React.FC = () => { + const columns = [ + { + title: '姓名', + dataIndex: 'name', + key: 'name', + }, + { + title: '年龄', + dataIndex: 'age', + key: 'age', + }, + { + title: '住址', + dataIndex: 'address', + key: 'address', + }, + ]; + + const dataSource = []; + for (let i = 1; i < 100; i++) { + dataSource.push({ + key: i, + name: '胡彦斌' + i, + age: 32, + address: `西湖区湖底公园${i}号`, + }); + } + + return ; +}; + +export default App; diff --git a/packages/ui/src/ProTable/index.md b/packages/ui/src/ProTable/index.md new file mode 100644 index 000000000..ad91d2def --- /dev/null +++ b/packages/ui/src/ProTable/index.md @@ -0,0 +1,22 @@ +--- +title: ProTable 高级表格 +nav: + title: 业务组件 + path: /biz-components +--- + +- 🔥 完全继承 pro-components [ProTable](https://procomponents.ant.design/components/pro-table) 的能力和 API,可无缝切换。 +- 💄 定制主题和样式,符合 OceanBase Design 设计规范。 +- 📢 ProTable 的默认尺寸改为 `large`。 + +## 代码演示 + + + +## API + +| 参数 | 说明 | 类型 | 默认值 | 版本 | +| :---------- | :------- | :----------------------------- | :------ | :--- | +| defaultSize | 默认尺寸 | `large` \| `middle` \| `small` | `large` | - | + +- 更多 API 详见 pro-components ProTable 文档: https://procomponents.ant.design/components/pro-table diff --git a/packages/ui/src/ProTable/index.tsx b/packages/ui/src/ProTable/index.tsx new file mode 100644 index 000000000..89f80182f --- /dev/null +++ b/packages/ui/src/ProTable/index.tsx @@ -0,0 +1,44 @@ +import React, { useContext } from 'react'; +import { ProTable as AntProTable } from '@ant-design/pro-components'; +import type { ProTableProps } from '@ant-design/pro-components'; +import classNames from 'classnames'; +import { ConfigProvider, Table } from '@oceanbase/design'; +import LocaleWrapper from '../locale/LocaleWrapper'; +import useStyle from './style'; + +export { ProTableProps }; + +const ProTable: typeof AntProTable = ({ + pagination: customPagination, + form, + prefixCls: customizePrefixCls, + className, + ...restProps +}) => { + const { getPrefixCls } = useContext(ConfigProvider.ConfigContext); + const prefixCls = getPrefixCls('pro-table', customizePrefixCls); + const { wrapSSR } = useStyle(prefixCls); + const proTableCls = classNames(className); + + const pagination = Table.useDefaultPagination(customPagination); + + return wrapSSR( + + ); +}; + +ProTable.Summary = AntProTable.Summary; + +export default ProTable; diff --git a/packages/ui/src/ProTable/style/index.ts b/packages/ui/src/ProTable/style/index.ts new file mode 100644 index 000000000..4b17201b0 --- /dev/null +++ b/packages/ui/src/ProTable/style/index.ts @@ -0,0 +1,22 @@ +import type { CSSObject } from '@ant-design/cssinjs'; +import { Table } from '@oceanbase/design'; +import type { GenerateStyle } from '@oceanbase/design/es/theme'; +import { genComponentStyleHook } from '../../_util/genComponentStyleHook'; +import type { OBToken } from '../../_util/genComponentStyleHook'; + +export const genProTableStyle: GenerateStyle = (token: OBToken): CSSObject => { + return {}; +}; + +export default (prefixCls: string) => { + const useStyle = genComponentStyleHook('ProTable', token => { + return [ + Table.genTableStyle({ + ...token, + componentCls: `${token.antCls}-table`, + } as any), + genProTableStyle(token as OBToken), + ]; + }); + return useStyle(prefixCls); +}; diff --git a/packages/ui/src/index.ts b/packages/ui/src/index.ts index 65543e3c4..b0e537ca7 100644 --- a/packages/ui/src/index.ts +++ b/packages/ui/src/index.ts @@ -61,6 +61,9 @@ export type { PageLoadingProps } from './PageLoading'; export { default as FooterToolbar } from './FooterToolbar'; export type { FooterToolbarProps } from './FooterToolbar'; +export { default as ProTable } from './ProTable'; +export type { ProTableProps } from './ProTable'; + export { default as Password } from './Password'; export type { PasswordProps } from './Password';