Commit 7982cb1b authored by Sendya's avatar Sendya

fix: PageContainer

parent 5367b895
import { createApp, defineComponent, reactive } from 'vue';
import 'ant-design-vue/dist/antd.less';
import { Button, Descriptions, Space, Statistic, Tabs } from 'ant-design-vue';
import { PageContainer } from '../src/PageContainer';
import { default as ProProvider } from '../src/ProProvider';
import { createRouteContext } from '../src/RouteContext';
import { LikeOutlined } from '@ant-design/icons-vue';
const { Item: DescriptionsItem } = Descriptions;
const App = defineComponent({
name: 'App',
setup: function() {
const { state: routeContext, Provider: RouteContextProvider } = createRouteContext({
hasSideMenu: true,
collapsed: true,
isMobile: false,
menuData: [],
});
const routes = [
{
path: 'index',
breadcrumbName: 'First-level Menu',
},
{
path: 'first',
breadcrumbName: 'Second-level Menu',
},
{
path: 'second',
breadcrumbName: 'Third-level Menu',
},
];
const state = reactive({
tabActiveKey: '2',
});
return () => (
<div>
<ProProvider prefixCls={'ant-pro'} contentWidth={'Fixed'}>
<RouteContextProvider>
<PageContainer
title="Title"
subTitle="This is a subtitle"
breadcrumb={{ routes }}
onBack={() => null}
extra={[
<Button key="3">操作</Button>,
<Button key="2">操作</Button>,
<Button key="1" type="primary">
主操作
</Button>,
]}
content={
<Descriptions size="small" column={2}>
<Descriptions.Item label="创建人">张三</Descriptions.Item>
<Descriptions.Item label="联系方式">
<a>421421</a>
</Descriptions.Item>
<Descriptions.Item label="创建时间">2017-01-10</Descriptions.Item>
<Descriptions.Item label="更新时间">2017-10-10</Descriptions.Item>
<Descriptions.Item label="备注">中国浙江省杭州市西湖区古翠路</Descriptions.Item>
</Descriptions>
}
extraContent={
<Space size={24}>
<Statistic title="Feedback" value={1128} prefix={<LikeOutlined />} />
<Statistic title="Unmerged" value={93} suffix="/ 100" />
</Space>
}
tabList={[
{ key: '1', tab: 'Details' },
{ key: '2', tab: 'Rule' },
]}
tabActiveKey={state.tabActiveKey}
onTabChange={(key: string) => {
console.log('onTabChange', key);
state.tabActiveKey = key;
}}
footer={[
<Button key="3">重置</Button>,
<Button key="2" type="primary">
提交
</Button>,
]}
>
<div>Page Content</div>
</PageContainer>
</RouteContextProvider>
</ProProvider>
</div>
);
},
});
const app = createApp(App);
app.mount('#__vue-content>div');
......@@ -5,7 +5,10 @@ import { PageHeaderProps } from './interfaces/PageHeader';
import { AffixProps } from './interfaces/Affix';
import { useRouteContext, RouteContextProps } from '../RouteContext';
import { useProProvider } from '../ProProvider';
import { PageHeader } from 'ant-design-vue';
import { Affix, PageHeader, Tabs } from 'ant-design-vue';
import GridContent from '../GridContent';
import FooterToolbar from '../FooterToolbar';
import './index.less';
export interface Tab {
key: string;
......@@ -16,7 +19,7 @@ export interface PageHeaderTabConfig {
/**
* @name tabs 的列表
*/
tabList?: TabPaneProps & Tab & { key?: string | VNodeChild };
tabList?: (Omit<TabPaneProps, 'id'> & { key?: string })[];
/**
* @name 当前选中 tab 的 key
*/
......@@ -24,7 +27,7 @@ export interface PageHeaderTabConfig {
/**
* @name tab 修改时触发
*/
onTabChange?: () => void;
onTabChange?: (key: string | number | any) => void;
/**
* @name tab 上多余的区域
*/
......@@ -57,21 +60,71 @@ export interface PageContainerProps extends PageHeaderTabConfig, Omit<PageHeader
loading?: boolean;
}
const renderFooter = (
props: Omit<
PageContainerProps & {
prefixedClassName: string;
},
'title'
>,
) => {
const {
tabList,
tabActiveKey,
onTabChange,
tabBarExtraContent,
tabProps,
prefixedClassName,
} = props;
if (tabList && tabList.length) {
return (
<Tabs
class={`${prefixedClassName}-tabs`}
activeKey={tabActiveKey}
onChange={key => {
if (onTabChange) {
onTabChange(key);
}
}}
tabBarExtraContent={tabBarExtraContent}
{...tabProps}
>
{tabList.map((item, index) => (
<Tabs.TabPane {...item} tab={item.tab} key={item.key} />
))}
</Tabs>
);
}
return null;
};
const renderPageHeader = (
content: VNodeChild | JSX.Element,
extraContent: VNodeChild | JSX.Element,
prefixedClassName: string,
): VNodeChild | JSX.Element => {
if (!content && !extraContent) {
return null;
}
return (
<div class={`${prefixedClassName}-detail`}>
<div class={`${prefixedClassName}-main`}>
<div class={`${prefixedClassName}-row`}>
{content && <div class={`${prefixedClassName}-content`}>{content}</div>}
{extraContent && <div class={`${prefixedClassName}-extraContent`}>{extraContent}</div>}
</div>
</div>
</div>
);
};
const defaultPageHeaderRender = (
props: PageContainerProps,
value: RouteContextProps & { prefixedClassName: string },
): VNodeChild | JSX.Element => {
const {
title,
content,
pageHeaderRender,
header,
extraContent,
style,
prefixCls,
...restProps
} = props;
const { title, content, pageHeaderRender, header, extraContent, prefixCls, ...restProps } = props;
console.log('restProps', restProps);
console.log('routeContext.value', value);
if (pageHeaderRender) {
return pageHeaderRender({ ...props, ...value });
}
......@@ -79,10 +132,9 @@ const defaultPageHeaderRender = (
if (!title && title !== false) {
pageHeaderTitle = value.title;
}
if
// inject value
return (
<PageHeader
{...value}
title={pageHeaderTitle}
{...restProps}
footer={renderFooter({
......@@ -92,13 +144,13 @@ const defaultPageHeaderRender = (
{...header}
preifxCls={prefixCls}
>
{header ||}
{header || renderPageHeader(content, extraContent, value.prefixedClassName)}
</PageHeader>
);
};
export const PageContainer: FunctionalComponent<PageContainerProps> = (props, { slots }) => {
const { loading, style, footer, affixProps, ghost, fixedHeader } = toRefs(props);
const { loading, footer, affixProps, ghost, fixedHeader } = props; // toRefs(props);
const { getPrefixCls } = useProProvider();
const value = useRouteContext();
......@@ -124,5 +176,30 @@ export const PageContainer: FunctionalComponent<PageContainerProps> = (props, {
</div>
) : null;
const headerDom = <div class={`${prefixedClassName}-warp`}></div>;
const headerDom = (
<div class={`${prefixedClassName}-warp`}>
{defaultPageHeaderRender(props, {
...value,
prefixCls: undefined,
prefixedClassName,
})}
</div>
);
return (
<div class={classNames}>
{fixedHeader ? (
<Affix
offsetTop={value.hasHeader && value.fixedHeader ? value.headerHeight : 0}
{...affixProps}
>
{headerDom}
</Affix>
) : (
headerDom
)}
<GridContent>{loading ? <Spin /> : content}</GridContent>
{footer && <FooterToolbar>{footer}</FooterToolbar>}
</div>
);
};
import { VNodeChild, CSSProperties } from 'vue';
export interface TabPaneProps {
tab?: VNodeChild | JSX.Element;
tab?: string | VNodeChild | JSX.Element;
class?: string | string[];
style?: CSSProperties;
disabled?: boolean;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment