Commit a04462e8 authored by Sendya's avatar Sendya

fix: side menu wrapper

parent 71c634b8
import { createApp, reactive } from 'vue';
import 'ant-design-vue/dist/antd.less';
import { Button, message } from 'ant-design-vue';
import { default as BasicLayout } from '../src/BasicLayout';
import 'ant-design-vue/dist/antd.less';
import { menus } from './menus';
import BaseMenu, { useMenuState } from '../src/SiderMenu/BaseMenu';
import { useMenuState } from '../src/SiderMenu/BaseMenu';
import * as Icon from '@ant-design/icons-vue';
const SimpleDemo = {
......@@ -19,21 +18,25 @@ const SimpleDemo = {
<div class="components">
<h2># BasicLayout</h2>
<BasicLayout
menus={menus}
collapsed={menuState.collapsed}
v-model={[menuState.collapsed, 'collapsed']}
title={'Pro Layout'}
layout={'side'}
theme={'dark'}
isMobile={false}
menuData={menus}
matchMenuKeys={[]}
contentWidth={'Fixed'}
primaryColor={'#1890ff'}
siderWidth={208}
openKeys={menuState.openKeys}
selectedKeys={menuState.selectedKeys}
{...{
'onUpdate:collapsed': $event => {
menuState.collapsed = $event;
},
'onUpdate:openKeys': $event => {
onOpenChange={$event => {
menuState.openKeys = $event
},
'onUpdate:selectedKeys': $event => {
}}
onSelect={$event => {
menuState.selectedKeys = $event
}
}}
>
<Button
onClick={() => {
......
......@@ -31,17 +31,17 @@ export const menus: RouteProps[] = [
{
path: '/form/basic-form',
name: 'basic-form',
meta: { title: 'Basic Form' },
meta: { icon: 'SmileOutlined', title: 'Basic Form' },
},
{
path: '/form/step-form',
name: 'step-form',
meta: { title: 'Step Form' },
meta: { icon: 'SmileOutlined', title: 'Step Form' },
},
{
path: '/form/advanced-form',
name: 'advance-form',
meta: { title: 'Advanced Form' },
meta: { icon: 'SmileOutlined', title: 'Advanced Form' },
},
],
},
......
.side-menu-demo {
.ant-pro-basicLayout {
.trigger {
padding: 0 24px;
font-size: 18px;
}
}
}
import { createApp, reactive } from 'vue';
import 'ant-design-vue/dist/antd.less';
import './side-menu.less';
import { Card, Space, Button, Layout } from 'ant-design-vue';
import { menus } from './menus';
import 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';
const DemoComponent = {
setup() {
const {
state: menuState,
} = useMenuState({
collapsed: false,
openKeys: ['/dashboard'] as string[],
selectedKeys: ['/dashboard/monitor'] as string[],
});
const handleClick = () => {
menuState.collapsed = !menuState.collapsed;
console.log('handleClick', menuState.collapsed);
};
const handleOpenChange = (openKeys: string[]) => {
menuState.openKeys = openKeys;
}
const handleSelect = (selectedKeys: string[]) => {
menuState.selectedKeys = selectedKeys;
}
return () => (
<div class="components">
<h2># SideMenu</h2>
<div class="demo" style="background: rgb(244,244,244); min-height: 400px;">
<div class="container side-menu-demo">
<Layout class="ant-pro-basicLayout">
<SiderMenuWrapper
title={'Pro Layout'}
layout={'side'}
theme={'dark'}
isMobile={false}
collapsed={menuState.collapsed}
menuData={menus}
openKeys={menuState.openKeys}
selectedKeys={menuState.selectedKeys}
onOpenChange={handleOpenChange}
onSelect={handleSelect}
matchMenuKeys={[]}
contentWidth={'Fixed'}
primaryColor={'#1890ff'}
siderWidth={208}
/>
<Layout>
<Layout.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;">
{
menuState.collapsed
? <MenuUnfoldOutlined class="trigger" onClick={handleClick} />
: <MenuFoldOutlined class="trigger" onClick={handleClick} />
}
</Layout.Header>
<Layout.Content style={{ margin: '24px 16px', padding: '24px', background: '#fff', minHeight: '280px' }}>
<div>Context</div>
</Layout.Content>
</Layout>
</Layout>
</div>
</div>
</div>
);
},
};
const app = createApp(DemoComponent);
const filterIcons = ['default', 'createFromIconfontCN', 'getTwoToneColor', 'setTwoToneColor']
Object.keys(Icon)
.filter(k => !filterIcons.includes(k))
.forEach(k => {
app.component(Icon[k].displayName, Icon[k])
})
app.mount('#__vue-content>div');
import './BasicLayoutTest.less';
import { h, App } from 'vue';
import { App } from 'vue';
import { Layout, Menu } from 'ant-design-vue';
import { Layout } from 'ant-design-vue';
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
import { default as ProProvider } from './ProProvider';
import { default as SiderMenu } from './SiderMenu/SiderMenu';
import { createContext } from './RouteContext';
import { createRouteContext } from './RouteContext';
import SiderMenuWrapper from './SiderMenu';
const defaultI18nRender = (key: string) => key
const { state, provider: RouteContextProvider } = createContext({
const { state, provider: RouteContextProvider } = createRouteContext({
isMobile: false,
menuData: [],
hasSiderMenu: true,
sideWidth: 208,
hasSideMenu: true,
hasHeader: true,
siderWidth: 208,
})
const BasicLayout = (props, { emit, slots }) => {
......@@ -32,9 +32,9 @@ const BasicLayout = (props, { emit, slots }) => {
<ProProvider {...props} i18n={defaultI18nRender}>
<RouteContextProvider>
<Layout class="ant-pro-basicLayout">
<SiderMenu {...props} />
<SiderMenuWrapper {...props} />
<Layout>
<Layout.Header style="background: #fff; padding: 0">
<Layout.Header style="background: #fff; padding: 0; height: 48px; line-height: 48px;">
{
props.collapsed
? <MenuUnfoldOutlined class="trigger" onClick={handleClick} />
......
......@@ -8,8 +8,8 @@
.trigger {
font-size: 18px;
line-height: 64px;
padding: 0 24px;
line-height: 48px;
padding: 0 12px;
cursor: pointer;
transition: color 0.3s;
......
import { defineComponent, reactive, toRefs, Ref, InjectionKey, provide, SetupContext, App, PropType } from 'vue';
import { ContentWidth } from '../typings';
export const defaultPrefixCls = 'ant-pro';
export interface ProProviderData {
getPrefixCls?: (suffixCls?: string, customizePrefixCls?: string) => string;
i18n?: (t: string) => string;
......@@ -10,7 +12,7 @@ export interface ProProviderData {
export const defaultProProviderProps: ProProviderData = {
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls;
return `ant-pro-${suffixCls}`;
return `${defaultPrefixCls}-${suffixCls}`;
},
i18n: (t: string): string => t,
contentWidth: 'Fluid',
......
......@@ -4,8 +4,10 @@ import { defineComponent, h, resolveDynamicComponent, resolveComponent, VNode, r
// import * as Icon from '@ant-design/icons-vue';
import { createFromIconfontCN } from '@ant-design/icons-vue';
import 'ant-design-vue/es/menu/style'
import Menu from 'ant-design-vue/es/menu'
// import 'ant-design-vue/es/menu/style'
// import Menu from 'ant-design-vue/es/menu'
import { Menu } from 'ant-design-vue';
import defaultSettings, { PureSettings } from '../defaultSettings';
import { isImg, isUrl } from '../utils'
......
import './index.less';
import { computed, ref, VNodeChild, SetupContext, inject } from 'vue';
import { VNodeChild, SetupContext, inject } from 'vue';
import 'ant-design-vue/es/layout/style';
import Layout from 'ant-design-vue/es/layout';
// import 'ant-design-vue/es/layout/style';
// import Layout from 'ant-design-vue/es/layout';
import { Layout } from 'ant-design-vue';
import BaseMenu, { BaseMenuProps } from './BaseMenu';
import { WithFalse } from '../typings';
import { SiderProps } from './typings';
import { MenuUnfoldOutlined, MenuFoldOutlined } from '@ant-design/icons-vue';
import { menus } from '../../examples/menus';
import { defaultProProviderProps, injectProConfigKey } from '../ProProvider';
const { Sider } = Layout;
export type PrivateSiderMenuProps = {
matchMenuKeys: string[];
};
export interface SiderMenuProps extends Pick<BaseMenuProps, Exclude<keyof BaseMenuProps, ['onCollapse']>> {
logo?: VNodeChild | JSX.Element;
siderWidth?: number;
collapsedWidth?: number;
menuHeaderRender?: WithFalse<
(logo: VNodeChild | JSX.Element, title: VNodeChild | JSX.Element, props?: SiderMenuProps) => VNodeChild
>;
......@@ -25,6 +29,7 @@ export interface SiderMenuProps extends Pick<BaseMenuProps, Exclude<keyof BaseMe
collapsedButtonRender?: WithFalse<(collapsed?: boolean) => VNodeChild>;
breakpoint?: SiderProps['breakpoint'] | false;
onMenuHeaderClick?: (e: MouseEvent) => void;
fixed?: boolean;
hide?: boolean;
onOpenChange?: (openKeys: WithFalse<string[]>) => void;
onSelect?: (selectedKeys: WithFalse<string[]>) => void;
......@@ -75,6 +80,7 @@ export const defaultRenderCollapsedButton = (collapsed?: boolean) =>
const SiderMenu = (props: SiderMenuProps, context: SetupContext) => {
const {
menuData,
collapsed,
fixSiderbar,
menuFooterRender,
......@@ -92,32 +98,53 @@ const SiderMenu = (props: SiderMenuProps, context: SetupContext) => {
onOpenChange,
onSelect,
headerHeight,
collapsedWidth = 48,
} = props;
console.log('props', props)
const config = inject(injectProConfigKey, defaultProProviderProps)
const baseClassName = config.getPrefixCls('sider');
const { getPrefixCls } = inject(injectProConfigKey, defaultProProviderProps)
const baseClassName = getPrefixCls('sider');
const isMix = computed(() => props.layout === 'mix');
const fixed = computed(() => props.fixed);
const runtimeTheme = computed(() => props.layout === 'mix' && 'light' || 'dark');
const runtimeSideWidth = computed(() => props.collapsed ? props.collapsedWidth : props.siderWidth);
const siderClassName = {
const classNames = ref({
[baseClassName]: true,
[`${baseClassName}-fixed`]: fixSiderbar,
[`${baseClassName}-layout-${layout}`]: layout && !isMobile,
[`${baseClassName}-light`]: theme === 'light',
};
[`${baseClassName}-${runtimeTheme.value}`]: true,
[`${baseClassName}-${props.layout}`]: true,
[`${baseClassName}-fixed`]: fixed,
});
const headerDom = defaultRenderLogoAndTitle(props);
const extraDom = menuExtraRender && menuExtraRender(props);
return (
<>
{ fixed.value && (<div style={{
width: `${runtimeSideWidth.value}px`,
overflow: 'hidden',
flex: `0 0 ${runtimeSideWidth.value}px`,
maxWidth: `${runtimeSideWidth.value}px`,
minWidth: `${runtimeSideWidth.value}px`,
}}
/>)}
<Sider
class={siderClassName}
class={classNames.value}
width={siderWidth}
collapsed={collapsed}
collapsible={false}
collapsedWidth={collapsedWidth}
>
<div class="ant-pro-sider-logo">
{headerDom}
</div>
<div style="flex: 1 1 0%; overflow: hidden auto;">
<BaseMenu
{...props}
menus={menus}
menus={menuData}
theme={props.theme}
mode={props.mode}
mode="inline"
collapsed={props.collapsed}
openKeys={props.openKeys}
selectedKeys={props.selectedKeys}
......@@ -125,8 +152,18 @@ const SiderMenu = (props: SiderMenuProps, context: SetupContext) => {
width: '100%',
}}
class={`${baseClassName}-menu`}
{...{
'onUpdate:openKeys': $event => {
onOpenChange($event);
},
'onUpdate:selectedKeys': $event => {
onSelect($event);
}
}}
/>
</div>
</Sider>
</>
);
};
......
import { FunctionalComponent, toRefs } from "vue"
import 'ant-design-vue/es/drawer/style';
import Drawer from 'ant-design-vue/es/drawer';
import SiderMenu, { SiderMenuProps, PrivateSiderMenuProps } from './SiderMenu';
const SiderMenuWrapper: FunctionalComponent<SiderMenuProps & PrivateSiderMenuProps> =
(props, ctx) => {
return props.isMobile ? (
<Drawer>
<SiderMenu
{...props}
/>
</Drawer>
) : (
<SiderMenu
{...props}
/>
)
};
SiderMenuWrapper.inheritAttrs = false
export default SiderMenuWrapper;
......@@ -17,15 +17,6 @@ import {
export type ContextType<T> = any;
// VNode<RendererNode, RendererElement, {
// [key: string]: any;
// }>
/**
(props: any, ctx: SetupContext) => DefineComponent<{}, () => VNode<RendererNode, RendererElement, {
[key: string]: any;
}>>;
*/
export interface CreateContext<T> {
provider: DefineComponent<{}, () => VNode | VNode[]>;
state: UnwrapRef<T> | T;
......
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