Commit 172c0c09 authored by Sendya's avatar Sendya

fix: global footer

parent f81a668f
...@@ -12,7 +12,7 @@ const SimpleDemo = { ...@@ -12,7 +12,7 @@ const SimpleDemo = {
collapsed: false, collapsed: false,
openKeys: [], openKeys: [],
selectedKeys: [], selectedKeys: [],
}) });
return () => ( return () => (
<div class="components"> <div class="components">
...@@ -31,12 +31,11 @@ const SimpleDemo = { ...@@ -31,12 +31,11 @@ const SimpleDemo = {
openKeys={menuState.openKeys} openKeys={menuState.openKeys}
selectedKeys={menuState.selectedKeys} selectedKeys={menuState.selectedKeys}
onOpenChange={$event => { onOpenChange={$event => {
menuState.openKeys = $event menuState.openKeys = $event;
}} }}
onSelect={$event => { onSelect={$event => {
menuState.selectedKeys = $event menuState.selectedKeys = $event;
}} }}
> >
<Button <Button
onClick={() => { onClick={() => {
...@@ -53,11 +52,11 @@ const SimpleDemo = { ...@@ -53,11 +52,11 @@ const SimpleDemo = {
const app = createApp(SimpleDemo); const app = createApp(SimpleDemo);
const filterIcons = ['default', 'createFromIconfontCN', 'getTwoToneColor', 'setTwoToneColor'] const filterIcons = ['default', 'createFromIconfontCN', 'getTwoToneColor', 'setTwoToneColor'];
Object.keys(Icon) Object.keys(Icon)
.filter(k => !filterIcons.includes(k)) .filter(k => !filterIcons.includes(k))
.forEach(k => { .forEach(k => {
app.component(Icon[k].displayName, Icon[k]) app.component(Icon[k].displayName, Icon[k]);
}) });
app.use(BasicLayout).mount('#__vue-content>div'); app.use(BasicLayout).mount('#__vue-content>div');
import { RouteProps } from '../src/typings'; import { RouteProps } from '../src/typings';
export const menus: RouteProps[] = [ export const menus: RouteProps[] = [
{
path: '/welcome',
name: 'welcome',
meta: { icon: 'SmileOutlined', title: 'Welcome' },
},
{ {
path: '/dashboard', path: '/dashboard',
name: 'Dashboard', name: 'Dashboard',
......
import { createApp, reactive } from 'vue'; import { createApp } from 'vue';
import 'ant-design-vue/dist/antd.less'; import 'ant-design-vue/dist/antd.less';
import './side-menu.less'; import './side-menu.less';
import { Card, Space, Button, Layout } from 'ant-design-vue'; import { Layout } from 'ant-design-vue';
import { menus } from './menus'; import { menus } from './menus';
import SiderMenuWrapper from '../src/SiderMenu'; import { default as SiderMenuWrapper } from '../src/SiderMenu';
import * as Icon from '@ant-design/icons-vue';
import { MenuFoldOutlined, MenuUnfoldOutlined } from '@ant-design/icons-vue';
import { useMenuState } from '../src/SiderMenu/BaseMenu'; import { useMenuState } from '../src/SiderMenu/BaseMenu';
import * as Icon from '@ant-design/icons-vue';
const DemoComponent = { const DemoComponent = {
setup() { setup() {
const { const { state: menuState } = useMenuState({
state: menuState,
} = useMenuState({
collapsed: false, collapsed: false,
openKeys: ['/dashboard'] as string[], openKeys: [''],
selectedKeys: ['/dashboard/monitor'] as string[], selectedKeys: ['/welcome'],
}); });
const handleClick = () => { const handleCollapse = (collapsed: boolean) => {
menuState.collapsed = !menuState.collapsed; menuState.collapsed = collapsed;
console.log('handleClick', menuState.collapsed);
}; };
const handleOpenChange = (openKeys: string[]) => { const handleOpenChange = (openKeys: string[]) => {
menuState.openKeys = openKeys; menuState.openKeys = openKeys;
} };
const handleSelect = (selectedKeys: string[]) => { const handleSelect = (selectedKeys: string[]) => {
menuState.selectedKeys = selectedKeys; menuState.selectedKeys = selectedKeys;
} };
return () => ( return () => (
<div class="components"> <div class="components">
...@@ -47,25 +43,26 @@ const DemoComponent = { ...@@ -47,25 +43,26 @@ const DemoComponent = {
selectedKeys={menuState.selectedKeys} selectedKeys={menuState.selectedKeys}
onOpenChange={handleOpenChange} onOpenChange={handleOpenChange}
onSelect={handleSelect} onSelect={handleSelect}
onCollapse={handleCollapse}
matchMenuKeys={[]} matchMenuKeys={[]}
contentWidth={'Fixed'} contentWidth={'Fixed'}
primaryColor={'#1890ff'} primaryColor={'#1890ff'}
siderWidth={208} siderWidth={208}
/> />
<Layout> <Layout>
<Layout.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;"> <Layout.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;"></Layout.Header>
{ <Layout.Content
menuState.collapsed style={{
? <MenuUnfoldOutlined class="trigger" onClick={handleClick} /> margin: '24px 16px',
: <MenuFoldOutlined class="trigger" onClick={handleClick} /> padding: '24px',
} background: '#fff',
</Layout.Header> minHeight: '280px',
<Layout.Content style={{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }}> }}
>
<div>Context</div> <div>Context</div>
</Layout.Content> </Layout.Content>
</Layout> </Layout>
</Layout> </Layout>
</div> </div>
</div> </div>
</div> </div>
...@@ -75,11 +72,11 @@ const DemoComponent = { ...@@ -75,11 +72,11 @@ const DemoComponent = {
const app = createApp(DemoComponent); const app = createApp(DemoComponent);
const filterIcons = ['default', 'createFromIconfontCN', 'getTwoToneColor', 'setTwoToneColor'] const filterIcons = ['default', 'createFromIconfontCN', 'getTwoToneColor', 'setTwoToneColor'];
Object.keys(Icon) Object.keys(Icon)
.filter(k => !filterIcons.includes(k)) .filter(k => !filterIcons.includes(k))
.forEach(k => { .forEach(k => {
app.component(Icon[k].displayName, Icon[k]) app.component(Icon[k].displayName, Icon[k]);
}) });
app.mount('#__vue-content>div'); app.mount('#__vue-content>div');
...@@ -6,11 +6,13 @@ import { Layout } from 'ant-design-vue'; ...@@ -6,11 +6,13 @@ import { Layout } from 'ant-design-vue';
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue'; import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
import { default as ProProvider } from './ProProvider'; import { default as ProProvider } from './ProProvider';
import { createRouteContext } from './RouteContext'; import { createRouteContext } from './RouteContext';
import { WrapContent } from './WrapContent';
import { default as GlobalFooter } from './GlobalFooter';
import SiderMenuWrapper from './SiderMenu'; import SiderMenuWrapper from './SiderMenu';
const defaultI18nRender = (key: string) => key; const defaultI18nRender = (key: string) => key;
const { state, provider: RouteContextProvider } = createRouteContext({ const { state: routeContext, Provider: RouteContextProvider } = createRouteContext({
isMobile: false, isMobile: false,
menuData: [], menuData: [],
sideWidth: 208, sideWidth: 208,
...@@ -32,7 +34,10 @@ const BasicLayout = (props, { emit, slots }) => { ...@@ -32,7 +34,10 @@ const BasicLayout = (props, { emit, slots }) => {
<ProProvider {...props} i18n={defaultI18nRender}> <ProProvider {...props} i18n={defaultI18nRender}>
<RouteContextProvider> <RouteContextProvider>
<Layout class="ant-pro-basicLayout"> <Layout class="ant-pro-basicLayout">
<SiderMenuWrapper {...props} /> <SiderMenuWrapper
{...props}
onCollapse={(collapsed: boolean) => emit('update:collapsed', collapsed)}
/>
<Layout> <Layout>
<Layout.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;"> <Layout.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;">
{props.collapsed ? ( {props.collapsed ? (
...@@ -41,7 +46,7 @@ const BasicLayout = (props, { emit, slots }) => { ...@@ -41,7 +46,7 @@ const BasicLayout = (props, { emit, slots }) => {
<MenuFoldOutlined class="trigger" onClick={handleClick} /> <MenuFoldOutlined class="trigger" onClick={handleClick} />
)} )}
</Layout.Header> </Layout.Header>
<Layout.Content <WrapContent
style={{ style={{
margin: '24px 16px', margin: '24px 16px',
padding: '24px', padding: '24px',
...@@ -49,8 +54,31 @@ const BasicLayout = (props, { emit, slots }) => { ...@@ -49,8 +54,31 @@ const BasicLayout = (props, { emit, slots }) => {
minHeight: '280px', minHeight: '280px',
}} }}
> >
{slots.default?.()} <div>Context</div>
</Layout.Content> </WrapContent>
<GlobalFooter
links={[
{
key: '1',
title: 'Pro Layout',
href: 'https://www.github.com/vueComponent/pro-layout',
blankTarget: true,
},
{
key: '2',
title: 'Github',
href: 'https://www.github.com/vueComponent/ant-design-vue-pro',
blankTarget: true,
},
{
key: '3',
title: '@Sendya',
href: 'https://www.github.com/sendya/',
blankTarget: true,
}
]}
copyright={(<a href="https://github.com/vueComponent" target="_blank">vueComponent</a>)}
/>
</Layout> </Layout>
</Layout> </Layout>
</RouteContextProvider> </RouteContextProvider>
......
import './index.less'; import './index.less';
import { computed, ref, VNodeChild, inject } from 'vue'; import { FunctionalComponent, computed, ref, VNodeChild } from 'vue';
// import 'ant-design-vue/es/layout/style'; // import 'ant-design-vue/es/layout/style';
// import Layout from 'ant-design-vue/es/layout'; // import Layout from 'ant-design-vue/es/layout';
import { Layout } from 'ant-design-vue'; import { Layout, Menu } from 'ant-design-vue';
import BaseMenu, { BaseMenuProps } from './BaseMenu'; import BaseMenu, { BaseMenuProps } from './BaseMenu';
import { WithFalse } from '../typings'; import { WithFalse } from '../typings';
import { SiderProps } from './typings'; import { SiderProps } from './typings';
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue'; import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
import { defaultProProviderProps, injectProConfigKey } from '../ProProvider'; import { useProProvider } from '../ProProvider';
const { Sider } = Layout; const { Sider } = Layout;
...@@ -85,7 +85,7 @@ export const defaultRenderLogoAndTitle = ( ...@@ -85,7 +85,7 @@ export const defaultRenderLogoAndTitle = (
export const defaultRenderCollapsedButton = (collapsed?: boolean) => export const defaultRenderCollapsedButton = (collapsed?: boolean) =>
collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />; collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />;
const SiderMenu = (props: SiderMenuProps) => { const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) => {
const { const {
menuData, menuData,
collapsed, collapsed,
...@@ -94,8 +94,11 @@ const SiderMenu = (props: SiderMenuProps) => { ...@@ -94,8 +94,11 @@ const SiderMenu = (props: SiderMenuProps) => {
onOpenChange, onOpenChange,
onSelect, onSelect,
collapsedWidth = 48, collapsedWidth = 48,
onCollapse,
menuFooterRender = false,
collapsedButtonRender = defaultRenderCollapsedButton,
} = props; } = props;
const { getPrefixCls } = inject(injectProConfigKey, defaultProProviderProps); const { getPrefixCls } = useProProvider();
const baseClassName = getPrefixCls('sider'); const baseClassName = getPrefixCls('sider');
const isMix = computed(() => props.layout === 'mix'); const isMix = computed(() => props.layout === 'mix');
...@@ -136,8 +139,13 @@ const SiderMenu = (props: SiderMenuProps) => { ...@@ -136,8 +139,13 @@ const SiderMenu = (props: SiderMenuProps) => {
collapsible={false} collapsible={false}
collapsedWidth={collapsedWidth} collapsedWidth={collapsedWidth}
> >
<div class="ant-pro-sider-logo">{headerDom}</div> <div class={`${baseClassName}-logo`}>{headerDom}</div>
<div style="flex: 1 1 0%; overflow: hidden auto;"> {extraDom && (
<div class={`${baseClassName}-extra ${!headerDom && `${baseClassName}-extra-no-logo`}`}>
{extraDom}
</div>
)}
<div style="flex: 1; overflow: hidden auto;">
<BaseMenu <BaseMenu
menus={menuData} menus={menuData}
theme={props.theme} theme={props.theme}
...@@ -159,6 +167,29 @@ const SiderMenu = (props: SiderMenuProps) => { ...@@ -159,6 +167,29 @@ const SiderMenu = (props: SiderMenuProps) => {
}} }}
/> />
</div> </div>
<div class={`${baseClassName}-links`}>
<Menu
class={`${baseClassName}-link-menu`}
inlineIndent={16}
theme={runtimeTheme.value}
selectedKeys={[]}
openKeys={[]}
mode="inline"
>
<Menu.Item
class={`${baseClassName}-collapsed-button`}
title={false}
onClick={() => {
if (onCollapse) {
onCollapse(!props.collapsed);
}
}}
>
{collapsedButtonRender(collapsed)}
</Menu.Item>
</Menu>
</div>
{menuFooterRender && <div class={`${baseClassName}-footer`}>{menuFooterRender(props)}</div>}
</Sider> </Sider>
</> </>
); );
......
...@@ -7,6 +7,7 @@ import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu'; ...@@ -7,6 +7,7 @@ import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu';
const SiderMenuWrapper: FunctionalComponent<SiderMenuProps & PrivateSiderMenuProps> = ( const SiderMenuWrapper: FunctionalComponent<SiderMenuProps & PrivateSiderMenuProps> = (
props, props,
{ emit },
) => { ) => {
return props.isMobile ? ( return props.isMobile ? (
<Drawer> <Drawer>
......
import { FunctionalComponent, ref, toRefs } from 'vue';
import { Layout } from 'ant-design-vue';
import { useProProvider } from './ProProvider';
import { ContentWidth } from './typings';
const { Content } = Layout;
export interface WrapContentProps {
isChildrenLayout?: boolean;
location?: string | string[] | any;
contentHeight?: number;
contentWidth?: ContentWidth;
}
export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slots }) => {
const { getPrefixCls } = toRefs(useProProvider());
const prefixCls = getPrefixCls.value('basicLayout');
const classNames = ref({
[`${prefixCls}-content`]: true,
[`${prefixCls}-has-header`]: true,
});
return <Content class={classNames.value}>{slots.default?.()}</Content>;
};
export default WrapContent;
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