Commit 093f3382 authored by eth3lbert's avatar eth3lbert Committed by 言肆

feat: add FooterToolbar

parent c1f17791
import { Button, Card, Space, Switch } from 'ant-design-vue';
import 'ant-design-vue/dist/antd.less';
import { createApp, reactive } from 'vue';
import FooterToolbar, { IFooterToolbarProps } from '../src/FooterToolbar';
import { createRouteContext } from '../src/RouteContext';
const DemoComponent = {
setup() {
const state = reactive({
name: 'value',
hasFooterToolbar: 'unset' as string | boolean,
toolbarProps: {} as IFooterToolbarProps,
});
const setToolbarProps = tProps => {
state.toolbarProps = { ...state.toolbarProps, ...tProps };
};
const { state: routeContext, provider: RouteContextProvider } = createRouteContext({
hasFooterToolbar: false,
setHasFooterToolbar: v => {
state.hasFooterToolbar = v;
routeContext.hasFooterToolbar = v;
},
});
return () => (
<div class="components">
<h2># Template</h2>
<Card style={{ marginBottom: '24px', background: 'rgb(244,244,244)' }}>
<Space size="middle">
<Button
type="primary"
onClick={() => {
state.name = new Date().getTime().toString();
routeContext.setHasFooterToolbar(!routeContext.hasFooterToolbar);
}}
>
{!routeContext.hasFooterToolbar ? 'Open' : 'Close'}
</Button>
<Switch
checkedChildren="w/ extra"
unCheckedChildren="w/o extra"
checked={!!state.toolbarProps.extra}
onClick={() => {
state.name = new Date().getTime().toString();
const extra = !state.toolbarProps.extra ? (
<img
src="https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg"
alt="logo"
width="32"
height="32"
/>
) : (
undefined
);
setToolbarProps({ extra });
}}
/>
<Switch
checkedChildren="w/ renderContent"
unCheckedChildren="w/o renderContent"
checked={!!state.toolbarProps.renderContent}
onClick={() => {
state.name = new Date().getTime().toString();
const renderContent = !state.toolbarProps.renderContent
? () => 'home_toolbar'
: undefined;
setToolbarProps({ renderContent });
}}
/>
</Space>
<div style={{ margin: '12px 0' }}>
state
<pre>
{JSON.stringify(
{
name: state.name,
toolbarProps: Object.fromEntries(
Object.entries(state.toolbarProps).map(([k, v]) => [k, typeof v]),
),
},
null,
2,
)}
</pre>
routeContext:
<pre>{JSON.stringify(routeContext, null, 2)}</pre>
</div>
</Card>
<div>
<RouteContextProvider>
{routeContext.hasFooterToolbar && (
<FooterToolbar {...state.toolbarProps}>
<button key="button" type="button">
right
</button>
</FooterToolbar>
)}
</RouteContextProvider>
</div>
</div>
);
},
};
const app = createApp(DemoComponent);
app.mount('#__vue-content>div');
import { VNodeChild } from 'vue'; import {
computed,
defineComponent,
inject,
onBeforeUnmount,
onMounted,
PropType,
VNodeChild,
} from 'vue';
import { defaultProProviderProps, injectProConfigKey } from '../ProProvider';
import { RouteContextProps, useRouteContext } from '../RouteContext';
import './index.less'; import './index.less';
export interface FooterToolbarProps { export interface IFooterToolbarProps {
extra?: VNodeChild; extra?: VNodeChild | JSX.Element;
renderContent?: ( renderContent?: (
props: FooterToolbarProps & { leftWidth?: string }, props: this & RouteContextProps & { leftWidth?: string },
dom: JSX.Element, dom: JSX.Element,
) => VNodeChild | JSX.Element; ) => VNodeChild | JSX.Element;
prefixCls?: string; prefixCls?: string;
} }
const FooterToolbar = (props, context) => { const FooterToolbarProps = {
const baseClassName = `${props.prefixCls}-footer-bar`; extra: { type: Object as PropType<VNodeChild> },
} renderContent: {
type: Function as PropType<IFooterToolbarProps['renderContent']>,
},
prefixCls: { type: String as PropType<string> },
};
const FooterToolbar = defineComponent({
name: 'FooterToolbar',
props: FooterToolbarProps,
setup(props, { slots }) {
const { getPrefixCls } = inject(injectProConfigKey, defaultProProviderProps);
const prefixCls = props.prefixCls || getPrefixCls();
const baseClassName = `${prefixCls}-footer-bar`;
const routeContext = useRouteContext();
const width = computed(() => {
const { hasSideMenu, isMobile, sideWidth } = routeContext;
if (!hasSideMenu) {
return undefined;
}
if (!sideWidth) {
return '100%';
}
return isMobile ? '100%' : `calc(100% - ${sideWidth}px)`;
});
const dom = () => {
return (
<>
<div class={`${baseClassName}-left`}>{props.extra}</div>
<div class={`${baseClassName}-right`}>{slots.default()}</div>
</>
);
};
onMounted(() => {
routeContext.setHasFooterToolbar && routeContext.setHasFooterToolbar(true);
});
onBeforeUnmount(() => {
routeContext.setHasFooterToolbar && routeContext.setHasFooterToolbar(false);
});
return () => (
<div class={baseClassName} style={{ width: width.value }}>
{props.renderContent
? props.renderContent(
{
...props,
...routeContext,
leftWidth: width.value,
},
dom(),
)
: dom()}
</div>
);
},
});
export default FooterToolbar;
import { defineComponent, reactive, toRefs, Ref, InjectionKey, provide, SetupContext, App, PropType } from 'vue'; import { App, defineComponent, InjectionKey, PropType, provide, reactive, SetupContext, toRefs } from 'vue';
import { ContentWidth } from '../typings'; import { ContentWidth } from '../typings';
export const defaultPrefixCls = 'ant-pro'; export const defaultPrefixCls = 'ant-pro';
...@@ -12,7 +12,7 @@ export interface ProProviderData { ...@@ -12,7 +12,7 @@ export interface ProProviderData {
export const defaultProProviderProps: ProProviderData = { export const defaultProProviderProps: ProProviderData = {
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => { getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls; if (customizePrefixCls) return customizePrefixCls;
return `${defaultPrefixCls}-${suffixCls}`; return suffixCls ? `${defaultPrefixCls}-${suffixCls}` : defaultPrefixCls;
}, },
i18n: (t: string): string => t, i18n: (t: string): string => t,
contentWidth: 'Fluid', contentWidth: 'Fluid',
......
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