Commit 97eec8a4 authored by Sendya's avatar Sendya

fix: ProLayout props

parent 172c0c09
import { createApp, reactive } from 'vue'; import { createApp, defineComponent, reactive } from 'vue';
import 'ant-design-vue/dist/antd.less'; import 'ant-design-vue/dist/antd.less';
import { Button, message } from 'ant-design-vue'; import { Button, message } from 'ant-design-vue';
import { default as BasicLayout } from '../src/BasicLayout'; import { default as ProLayout } from '../src/BasicLayout';
import { menus } from './menus'; import { menus } from './menus';
import { useMenuState } from '../src/SiderMenu/BaseMenu'; import { useMenuState } from '../src/SiderMenu/BaseMenu';
import * as Icon from '@ant-design/icons-vue'; import * as Icon from '@ant-design/icons-vue';
import { createRouteContext } from '../src/RouteContext';
const SimpleDemo = { const BasicLayout = defineComponent({
setup() { name: 'BasicLayout',
inheritAttrs: false,
setup(_, { slots, attrs }) {
const { state: menuState } = useMenuState({ const { state: menuState } = useMenuState({
collapsed: false, collapsed: false,
openKeys: [], openKeys: [],
selectedKeys: [], selectedKeys: ['/welcome'],
});
const { state: routeContext, Provider: RouteContextProvider } = createRouteContext({
isMobile: false,
menuData: [],
sideWidth: 208,
hasSideMenu: true,
hasHeader: true,
hasFooterToolbar: false,
setHasFooterToolbar: (has: boolean) => (routeContext.hasFooterToolbar = has),
}); });
return () => ( return () => (
<div class="components"> <RouteContextProvider>
<h2># BasicLayout</h2> <ProLayout
<BasicLayout {...attrs}
v-model={[menuState.collapsed, 'collapsed']} v-model={[menuState.collapsed, 'collapsed']}
title={'Pro Layout'} title={'Pro Layout'}
layout={'side'} layout={'side'}
...@@ -31,10 +44,10 @@ const SimpleDemo = { ...@@ -31,10 +44,10 @@ const SimpleDemo = {
openKeys={menuState.openKeys} openKeys={menuState.openKeys}
selectedKeys={menuState.selectedKeys} selectedKeys={menuState.selectedKeys}
onOpenChange={$event => { onOpenChange={$event => {
menuState.openKeys = $event; $event && (menuState.openKeys = $event);
}} }}
onSelect={$event => { onSelect={$event => {
menuState.selectedKeys = $event; $event && (menuState.selectedKeys = $event);
}} }}
> >
<Button <Button
...@@ -44,7 +57,18 @@ const SimpleDemo = { ...@@ -44,7 +57,18 @@ const SimpleDemo = {
> >
Click Me!! Click Me!!
</Button> </Button>
</BasicLayout> </ProLayout>
</RouteContextProvider>
);
},
});
const SimpleDemo = {
setup() {
return () => (
<div class="components">
<h2># BasicLayout</h2>
<BasicLayout />
</div> </div>
); );
}, },
......
...@@ -28,7 +28,7 @@ ...@@ -28,7 +28,7 @@
"vue": ">=3.0.0" "vue": ">=3.0.0"
}, },
"devDependencies": { "devDependencies": {
"@ant-design-vue/tools": "^3.0.3", "@ant-design-vue/tools": "^3.0.4",
"@babel/runtime": "^7.11.2", "@babel/runtime": "^7.11.2",
"@types/fs-extra": "^9.0.2", "@types/fs-extra": "^9.0.2",
"@types/jest": "^24.0.17", "@types/jest": "^24.0.17",
......
import './BasicLayoutTest.less'; import './BasicLayoutTest.less';
import { App } from 'vue'; import { App, FunctionalComponent } from 'vue';
import { Layout } from 'ant-design-vue'; 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 { default as GlobalFooter } from './GlobalFooter';
import { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu';
import { createRouteContext } from './RouteContext'; import { createRouteContext } from './RouteContext';
import { WrapContent } from './WrapContent'; import { WrapContent } from './WrapContent';
import { default as GlobalFooter } from './GlobalFooter';
import SiderMenuWrapper from './SiderMenu';
const defaultI18nRender = (key: string) => key; const defaultI18nRender = (key: string) => key;
...@@ -20,7 +20,9 @@ const { state: routeContext, Provider: RouteContextProvider } = createRouteConte ...@@ -20,7 +20,9 @@ const { state: routeContext, Provider: RouteContextProvider } = createRouteConte
hasHeader: true, hasHeader: true,
}); });
const BasicLayout = (props, { emit, slots }) => { export type ProLayoutProps = SiderMenuWrapperProps;
const ProLayout: FunctionalComponent<ProLayoutProps> = (props, { emit, slots }) => {
const handleClick = () => { const handleClick = () => {
emit('update:collapsed', !props.collapsed); emit('update:collapsed', !props.collapsed);
}; };
...@@ -32,62 +34,64 @@ const BasicLayout = (props, { emit, slots }) => { ...@@ -32,62 +34,64 @@ const BasicLayout = (props, { emit, slots }) => {
}; };
return ( return (
<ProProvider {...props} i18n={defaultI18nRender}> <ProProvider {...props} i18n={defaultI18nRender}>
<RouteContextProvider> <Layout class="ant-pro-basicLayout">
<Layout class="ant-pro-basicLayout"> <SiderMenuWrapper
<SiderMenuWrapper {...props}
{...props} onCollapse={(collapsed: boolean) => emit('update:collapsed', collapsed)}
onCollapse={(collapsed: boolean) => emit('update:collapsed', collapsed)} />
<Layout>
<Layout.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;">
{props.collapsed ? (
<MenuUnfoldOutlined class="trigger" onClick={handleClick} />
) : (
<MenuFoldOutlined class="trigger" onClick={handleClick} />
)}
</Layout.Header>
<WrapContent
style={{
margin: '24px 16px',
padding: '24px',
background: '#fff',
minHeight: '280px',
}}
>
{slots.default?.()}
</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.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;">
{props.collapsed ? (
<MenuUnfoldOutlined class="trigger" onClick={handleClick} />
) : (
<MenuFoldOutlined class="trigger" onClick={handleClick} />
)}
</Layout.Header>
<WrapContent
style={{
margin: '24px 16px',
padding: '24px',
background: '#fff',
minHeight: '280px',
}}
>
<div>Context</div>
</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>
</RouteContextProvider> </Layout>
</ProProvider> </ProProvider>
); );
}; };
BasicLayout.install = function(app: App) { ProLayout.install = function(app: App) {
app.component('pro-layout', BasicLayout); app.component('pro-layout', ProLayout);
}; };
export default BasicLayout; export default ProLayout;
...@@ -17,6 +17,7 @@ export interface FooterToolbarProps { ...@@ -17,6 +17,7 @@ export interface FooterToolbarProps {
props: FooterToolbarProps & RouteContextProps & { leftWidth?: string }, props: FooterToolbarProps & RouteContextProps & { leftWidth?: string },
dom: JSX.Element, dom: JSX.Element,
) => VNodeChild | JSX.Element; ) => VNodeChild | JSX.Element;
getContainer?: (triggerNode: HTMLElement) => HTMLElement | null;
prefixCls?: string; prefixCls?: string;
} }
...@@ -25,6 +26,9 @@ const FooterToolbarProps = { ...@@ -25,6 +26,9 @@ const FooterToolbarProps = {
renderContent: { renderContent: {
type: Function as PropType<FooterToolbarProps['renderContent']>, type: Function as PropType<FooterToolbarProps['renderContent']>,
}, },
getContainer: {
type: Function as PropType<FooterToolbarProps['getContainer']>,
},
prefixCls: { type: String as PropType<string> }, prefixCls: { type: String as PropType<string> },
}; };
...@@ -33,11 +37,13 @@ const FooterToolbar = defineComponent({ ...@@ -33,11 +37,13 @@ const FooterToolbar = defineComponent({
props: FooterToolbarProps, props: FooterToolbarProps,
setup(props, { slots }) { setup(props, { slots }) {
const { getPrefixCls } = inject(injectProConfigKey, defaultProProviderProps); const { getPrefixCls } = inject(injectProConfigKey, defaultProProviderProps);
const baseClassName = props.prefixCls || getPrefixCls('footer-bar');
// const container = typeof props.getContainer === 'function' ? props.getContainer()
const baseClassName = computed(() => { // const baseClassName = computed(() => {
const prefixCls = props.prefixCls || getPrefixCls(); // const prefixCls = props.prefixCls || getPrefixCls();
return `${prefixCls}-footer-bar`; // return `${prefixCls}-footer-bar`;
}); // });
const routeContext = useRouteContext(); const routeContext = useRouteContext();
const width = computed(() => { const width = computed(() => {
const { hasSideMenu, isMobile, sideWidth } = routeContext; const { hasSideMenu, isMobile, sideWidth } = routeContext;
......
import { InjectionKey } from 'vue'; import { InjectionKey } from 'vue';
import { createContext, useContext } from './hooks/context'; import { createContext, useContext } from './hooks/context';
import { PureSettings } from './defaultSettings'; import { PureSettings } from './defaultSettings';
import { useProProvider } from './ProProvider';
export interface RouteContextProps extends Partial<PureSettings> { export interface RouteContextProps extends Partial<PureSettings> {
breadcrumb?: any; breadcrumb?: any;
......
...@@ -218,8 +218,8 @@ export default defineComponent({ ...@@ -218,8 +218,8 @@ export default defineComponent({
const handleOpenChange: OpenEventHandler = (openKeys): void => { const handleOpenChange: OpenEventHandler = (openKeys): void => {
emit('update:openKeys', openKeys); emit('update:openKeys', openKeys);
}; };
const handleSelect = ({ selectedKeys }: SelectInfo & MenuInfo) => { const handleSelect = (params: SelectInfo): void => {
emit('update:selectedKeys', selectedKeys); emit('update:selectedKeys', params.selectedKeys);
}; };
return () => ( return () => (
...@@ -230,7 +230,9 @@ export default defineComponent({ ...@@ -230,7 +230,9 @@ export default defineComponent({
openKeys={props.openKeys || []} openKeys={props.openKeys || []}
selectedKeys={props.selectedKeys || []} selectedKeys={props.selectedKeys || []}
onOpenChange={handleOpenChange} onOpenChange={handleOpenChange}
onSelect={handleSelect} onSelect={({ selectedKeys }) => {
emit('update:selectedKeys', selectedKeys);
}}
> >
{props.menus && {props.menus &&
props.menus.map(menu => { props.menus.map(menu => {
......
...@@ -33,7 +33,7 @@ export interface SiderMenuProps ...@@ -33,7 +33,7 @@ export interface SiderMenuProps
(props: SiderMenuProps, defaultDom: VNodeChild | JSX.Element) => VNodeChild (props: SiderMenuProps, defaultDom: VNodeChild | JSX.Element) => VNodeChild
>; >;
menuExtraRender?: WithFalse<(props: SiderMenuProps) => VNodeChild>; menuExtraRender?: WithFalse<(props: SiderMenuProps) => VNodeChild>;
collapsedButtonRender?: WithFalse<(collapsed?: boolean) => VNodeChild>; collapsedButtonRender?: WithFalse<(collapsed?: boolean) => JSX.Element | VNodeChild>;
breakpoint?: SiderProps['breakpoint'] | false; breakpoint?: SiderProps['breakpoint'] | false;
onMenuHeaderClick?: (e: MouseEvent) => void; onMenuHeaderClick?: (e: MouseEvent) => void;
fixed?: boolean; fixed?: boolean;
...@@ -82,7 +82,7 @@ export const defaultRenderLogoAndTitle = ( ...@@ -82,7 +82,7 @@ export const defaultRenderLogoAndTitle = (
); );
}; };
export const defaultRenderCollapsedButton = (collapsed?: boolean) => export const defaultRenderCollapsedButton = (collapsed?: boolean): JSX.Element | VNodeChild =>
collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />; collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />;
const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) => { const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) => {
...@@ -148,7 +148,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -148,7 +148,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
<div style="flex: 1; overflow: hidden auto;"> <div style="flex: 1; overflow: hidden auto;">
<BaseMenu <BaseMenu
menus={menuData} menus={menuData}
theme={props.theme} theme={props.theme === 'realDark' ? 'dark' : props.theme}
mode="inline" mode="inline"
collapsed={props.collapsed} collapsed={props.collapsed}
openKeys={props.openKeys} openKeys={props.openKeys}
...@@ -177,6 +177,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -177,6 +177,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
mode="inline" mode="inline"
> >
<Menu.Item <Menu.Item
key={'collapsed-button'}
class={`${baseClassName}-collapsed-button`} class={`${baseClassName}-collapsed-button`}
title={false} title={false}
onClick={() => { onClick={() => {
...@@ -185,7 +186,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -185,7 +186,7 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
} }
}} }}
> >
{collapsedButtonRender(collapsed)} {collapsedButtonRender && collapsedButtonRender(collapsed)}
</Menu.Item> </Menu.Item>
</Menu> </Menu>
</div> </div>
......
...@@ -5,10 +5,9 @@ import Drawer from 'ant-design-vue/es/drawer'; ...@@ -5,10 +5,9 @@ import Drawer from 'ant-design-vue/es/drawer';
import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu'; import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu';
const SiderMenuWrapper: FunctionalComponent<SiderMenuProps & PrivateSiderMenuProps> = ( export type SiderMenuWrapperProps = SiderMenuProps & PrivateSiderMenuProps;
props,
{ emit }, const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = (props, { emit }) => {
) => {
return props.isMobile ? ( return props.isMobile ? (
<Drawer> <Drawer>
<SiderMenu {...props} /> <SiderMenu {...props} />
......
...@@ -9,7 +9,7 @@ export interface MenuInfo { ...@@ -9,7 +9,7 @@ export interface MenuInfo {
domEvent: MouseEvent; domEvent: MouseEvent;
} }
export interface SelectInfo { export interface SelectInfo extends MenuInfo {
selectedKeys: string[]; selectedKeys: string[];
} }
......
import { FunctionalComponent, ref, toRefs } from 'vue'; import { FunctionalComponent, reactive, toRefs, CSSProperties } from 'vue';
import { Layout } from 'ant-design-vue'; import { Layout } from 'ant-design-vue';
import { useProProvider } from './ProProvider'; import { useProProvider } from './ProProvider';
import { ContentWidth } from './typings'; import { ContentWidth } from './typings';
...@@ -6,21 +6,27 @@ import { ContentWidth } from './typings'; ...@@ -6,21 +6,27 @@ import { ContentWidth } from './typings';
const { Content } = Layout; const { Content } = Layout;
export interface WrapContentProps { export interface WrapContentProps {
style?: CSSProperties;
class?: string | string[] | object;
isChildrenLayout?: boolean; isChildrenLayout?: boolean;
location?: string | string[] | any; location?: string | string[] | any;
contentHeight?: number; contentHeight?: number;
contentWidth?: ContentWidth; contentWidth?: ContentWidth;
} }
export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slots }) => { export const WrapContent: FunctionalComponent<WrapContentProps> = (props, { slots, attrs }) => {
const { getPrefixCls } = toRefs(useProProvider()); const { getPrefixCls } = toRefs(useProProvider());
const prefixCls = getPrefixCls.value('basicLayout'); const prefixCls = getPrefixCls.value('basicLayout');
const classNames = ref({ const classNames = reactive({
[`${prefixCls}-content`]: true, [`${prefixCls}-content`]: true,
[`${prefixCls}-has-header`]: true, [`${prefixCls}-has-header`]: true,
}); });
return <Content class={classNames.value}>{slots.default?.()}</Content>; return (
<Content class={classNames} {...attrs}>
{slots.default?.()}
</Content>
);
}; };
export default WrapContent; WrapContent.inheritAttrs = false;
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