Commit 4ecee35a authored by Sendya's avatar Sendya Committed by 言肆

fix: layout props effects

parent 2f9d0e8d
@import '~ant-design-vue/es/style/themes/default.less';
.right-content {
height: 48px;
min-width: 100px;
padding: 0 12px;
float: right;
display: flex;
margin-left: auto;
overflow: hidden;
text-align: right;
> * {
height: 100%;
}
&.mix-dark,
&.mix-light {
color: @text-color-dark;
}
&.side-dark,
&.side-light,
&.top-light {
color: @text-color;
}
&.top-dark {
color: @text-color-dark;
}
.action {
display: flex;
align-items: center;
padding: 0 12px;
cursor: pointer;
transition: all 0.3s;
&:hover {
background: rgba(0, 0, 0, 0.055);
}
}
}
.action-overlay {
.ant-dropdown-menu-item {
min-width: 160px;
> span {
margin-right: 6px;
}
}
}
import { defineComponent } from 'vue'; import { defineComponent } from 'vue';
import { Button, Space, Select, Switch } from 'ant-design-vue';
import { globalState as state } from '../state'; import { globalState as state } from '../state';
export default defineComponent({ export default defineComponent({
...@@ -7,51 +7,7 @@ export default defineComponent({ ...@@ -7,51 +7,7 @@ export default defineComponent({
return () => ( return () => (
<div> <div>
<div>Welcome</div> <div>Welcome</div>
<Space>
<Button
onClick={() => {
state.navTheme = state.navTheme === 'dark' ? 'light' : 'dark';
}}
>
Theme Switch
</Button>
<Select
value={state.layout}
onChange={val => {
state.layout = val;
}}
style={{ width: '150px' }}
>
<Select.Option value="side">Side</Select.Option>
<Select.Option value="top">Top</Select.Option>
<Select.Option value="mix">Mix</Select.Option>
</Select>
<Switch
checkedChildren="Fixed Header"
unCheckedChildren="UnFixed Header"
checked={state.fixedHeader}
onChange={() => {
state.fixedHeader = !state.fixedHeader;
}}
/>
<Switch
checkedChildren="Fixed SideBar"
unCheckedChildren="UnFixed SideBar"
checked={state.fixSiderbar}
onChange={() => {
state.fixSiderbar = !state.fixSiderbar;
}}
/>
<Switch
checkedChildren="Split Menus"
unCheckedChildren="Un Split Menus"
checked={state.splitMenus}
onChange={() => {
state.splitMenus = !state.splitMenus;
}}
/>
</Space>
<pre>{JSON.stringify(state, null, 2)}</pre>
<p> <p>
<p>block</p> <p>block</p>
... ...
......
This diff is collapsed.
...@@ -73,6 +73,7 @@ ...@@ -73,6 +73,7 @@
"@babel/runtime": "^7.11.2", "@babel/runtime": "^7.11.2",
"ant-design-vue": "^2.0.0", "ant-design-vue": "^2.0.0",
"lodash-es": "^4.17.20", "lodash-es": "^4.17.20",
"omit.js": "^2.0.2",
"vue-types": "^3.0.1" "vue-types": "^3.0.1"
}, },
"files": [ "files": [
......
import { import { computed, CSSProperties, reactive, unref, provide, defineComponent, toRefs } from 'vue';
computed,
FunctionalComponent,
CSSProperties,
reactive,
unref,
provide,
defineComponent,
} 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 { withInstall } from 'ant-design-vue/es/_util/type'; import { withInstall } from 'ant-design-vue/es/_util/type';
import RouteContext, { RouteContextProps } from './RouteContext'; import { RouteContextProps } from './RouteContext';
import { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu'; import { default as SiderMenuWrapper, SiderMenuWrapperProps } from './SiderMenu';
import { WrapContent } from './WrapContent'; import { WrapContent } from './WrapContent';
import { default as Header, HeaderViewProps } from './Header'; import { default as Header, HeaderViewProps } from './Header';
import { VNodeType, CustomRender, WithFalse } from './typings'; import { VNodeType, CustomRender, WithFalse } from './typings';
import { getCustomRender, PropRenderType, PropTypes } from './utils'; import { getCustomRender, PropRenderType, PropTypes } from './utils';
import omit from 'omit.js';
import useMediaQuery from './hooks/useMediaQuery'; import useMediaQuery from './hooks/useMediaQuery';
import './BasicLayout.less'; import './BasicLayout.less';
export const defaultPrefixCls = 'ant-pro'; export const defaultPrefixCls = 'ant-pro';
const defaultI18nRender = (key: string) => key;
export type BasicLayoutProps = SiderMenuWrapperProps & export type BasicLayoutProps = SiderMenuWrapperProps &
HeaderViewProps & { HeaderViewProps & {
pure?: boolean; pure?: boolean;
...@@ -60,34 +51,23 @@ export type BasicLayoutProps = SiderMenuWrapperProps & ...@@ -60,34 +51,23 @@ export type BasicLayoutProps = SiderMenuWrapperProps &
const ProLayout = defineComponent({ const ProLayout = defineComponent({
setup(props: BasicLayoutProps, { emit, slots }) { setup(props: BasicLayoutProps, { emit, slots }) {
const { const isTop = computed(() => props.layout === 'top');
onCollapse: propsOnCollapse,
onOpenKeys: propsOnOpenKeys,
onSelect: propsOnSelect,
contentStyle,
disableContentMargin,
isChildrenLayout: propsIsChildrenLayout,
// loading,
layout,
matchMenuKeys,
navTheme,
menuData,
// defaultCollapsed,
} = props;
const isTop = computed(() => layout === 'top');
// const isSide = computed(() => layout === 'side'); // const isSide = computed(() => layout === 'side');
// const isMix = computed(() => layout === 'mix'); // const isMix = computed(() => layout === 'mix');
const pure = computed(() => props.pure); const pure = computed(() => props.pure);
const siderWidth = computed(() => (props.collapsed ? props.collapsedWidth : props.siderWidth));
// if on event and @event // if on event and @event
const onCollapse = const onCollapse = (collapsed: boolean) => {
(propsOnCollapse && propsOnCollapse) || (props.onCollapse && props.onCollapse(collapsed)) || emit('update:collapsed', collapsed);
((collapsed: boolean) => emit('update:collapsed', collapsed)); };
const onOpenKeys = const onOpenKeys = (openKeys: string[] | false) => {
(propsOnOpenKeys && propsOnOpenKeys) || (props.onOpenKeys && props.onOpenKeys(openKeys)) || emit('update:open-keys', openKeys);
((openKeys: string[] | false) => emit('update:open-keys', openKeys)); };
const onSelect = const onSelect = (selectedKeys: string[] | false) => {
(propsOnSelect && propsOnSelect) || (props.onSelect && props.onSelect(selectedKeys)) ||
((selectedKeys: string[] | false) => emit('update:selected-keys', selectedKeys)); emit('update:selected-keys', selectedKeys);
};
const colSize = useMediaQuery(); const colSize = useMediaQuery();
const isMobile = computed( const isMobile = computed(
() => (colSize.value === 'sm' || colSize.value === 'xs') && !props.disableMobile, () => (colSize.value === 'sm' || colSize.value === 'xs') && !props.disableMobile,
...@@ -106,12 +86,12 @@ const ProLayout = defineComponent({ ...@@ -106,12 +86,12 @@ const ProLayout = defineComponent({
}); });
// siderMenuDom 为空的时候,不需要 padding // siderMenuDom 为空的时候,不需要 padding
const genLayoutStyle: CSSProperties = { const genLayoutStyle = reactive<CSSProperties>({
position: 'relative', position: 'relative',
}; });
// if is some layout children, don't need min height // if is some layout children, don't need min height
if (propsIsChildrenLayout || (contentStyle && contentStyle.minHeight)) { if (props.isChildrenLayout || (props.contentStyle && props.contentStyle.minHeight)) {
genLayoutStyle.minHeight = 0; genLayoutStyle.minHeight = 0;
} }
...@@ -120,17 +100,17 @@ const ProLayout = defineComponent({ ...@@ -120,17 +100,17 @@ const ProLayout = defineComponent({
// onChange: propsOnCollapse, // onChange: propsOnCollapse,
// }); // });
const headerRender = ( const headerRender = (
props: BasicLayoutProps & { p: BasicLayoutProps & {
hasSiderMenu: boolean; hasSiderMenu: boolean;
customHeaderRender: WithFalse<CustomRender>; customHeaderRender: WithFalse<CustomRender>;
rightContentRender: WithFalse<CustomRender>; rightContentRender: WithFalse<CustomRender>;
}, },
matchMenuKeys: string[], matchMenuKeys?: string[],
): VNodeType => { ): VNodeType | null => {
if (props.headerRender === false || props.pure) { if (p.headerRender === false || p.pure) {
return null; return null;
} }
return <Header matchMenuKeys={matchMenuKeys} {...props} headerHeight={48} />; return <Header matchMenuKeys={matchMenuKeys || []} {...p} headerHeight={48} />;
}; };
const rightContentRender = getCustomRender(props, slots, 'rightContentRender'); const rightContentRender = getCustomRender(props, slots, 'rightContentRender');
const customHeaderRender = getCustomRender(props, slots, 'headerRender'); const customHeaderRender = getCustomRender(props, slots, 'headerRender');
...@@ -138,37 +118,49 @@ const ProLayout = defineComponent({ ...@@ -138,37 +118,49 @@ const ProLayout = defineComponent({
const footerRender = getCustomRender(props, slots, 'footerRender'); const footerRender = getCustomRender(props, slots, 'footerRender');
// const menuRender = getCustomRender(props, slots, 'menuRender'); // const menuRender = getCustomRender(props, slots, 'menuRender');
const headerDom = headerRender( const headerDom = computed(() =>
{ headerRender(
...props, {
hasSiderMenu: !isTop.value, ...props,
menuData, hasSiderMenu: !isTop.value,
isMobile: unref(isMobile), menuData: props.menuData,
onCollapse, isMobile: unref(isMobile),
onOpenKeys, onCollapse,
onSelect, onOpenKeys,
customHeaderRender, onSelect,
rightContentRender, customHeaderRender,
headerTitleRender: menuHeaderRender, rightContentRender,
theme: (navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light', headerTitleRender: menuHeaderRender,
}, theme: (props.navTheme || 'dark').toLocaleLowerCase().includes('dark') ? 'dark' : 'light',
matchMenuKeys, },
props.matchMenuKeys,
),
); );
const routeContext: RouteContextProps = { const propRefs = toRefs(props);
// @ts-ignore
const routeContext: RouteContextProps = reactive({
getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => { getPrefixCls: (suffixCls?: string, customizePrefixCls?: string) => {
if (customizePrefixCls) return customizePrefixCls; if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `${defaultPrefixCls}-${suffixCls}` : defaultPrefixCls; return suffixCls ? `${defaultPrefixCls}-${suffixCls}` : defaultPrefixCls;
}, },
i18n: (t: string): string => t, i18n: (t: string): string => t,
contentWidth: 'Fluid', contentWidth: 'Fluid',
menuData, layout: propRefs.layout,
selectedKeys: props.selectedKeys || [], navTheme: propRefs.navTheme,
openKeys: props.openKeys || [], splitMenus: propRefs.splitMenus,
}; fixedHeader: propRefs.fixSiderbar,
fixSiderbar: propRefs.fixSiderbar,
sideWidth: siderWidth,
hasSideMenu: true,
hasFooterToolbar: false,
menuData: propRefs.menuData,
selectedKeys: propRefs.selectedKeys || [],
openKeys: propRefs.openKeys || [],
});
console.log('BasicLayout.routeContext', routeContext); const restProps = computed(() => omit(props, ['onCollapse', 'onOpenKeys', 'onSelect']));
console.log('pure', pure.value);
provide('route-context', routeContext); provide('route-context', routeContext);
return () => ( return () => (
...@@ -180,7 +172,7 @@ const ProLayout = defineComponent({ ...@@ -180,7 +172,7 @@ const ProLayout = defineComponent({
<Layout class={baseClassName.value}> <Layout class={baseClassName.value}>
{!isTop.value && ( {!isTop.value && (
<SiderMenuWrapper <SiderMenuWrapper
{...props} {...restProps.value}
isMobile={isMobile.value} isMobile={isMobile.value}
menuHeaderRender={menuHeaderRender} menuHeaderRender={menuHeaderRender}
onCollapse={onCollapse} onCollapse={onCollapse}
...@@ -189,10 +181,10 @@ const ProLayout = defineComponent({ ...@@ -189,10 +181,10 @@ const ProLayout = defineComponent({
/> />
)} )}
<Layout style={genLayoutStyle}> <Layout style={genLayoutStyle}>
{headerDom} {headerDom.value}
<WrapContent <WrapContent
isChildrenLayout={propsIsChildrenLayout} isChildrenLayout={props.isChildrenLayout}
style={disableContentMargin ? null : contentStyle} style={props.disableContentMargin ? undefined : props.contentStyle}
> >
{slots.default?.()} {slots.default?.()}
</WrapContent> </WrapContent>
...@@ -218,7 +210,7 @@ ProLayout.props = { ...@@ -218,7 +210,7 @@ ProLayout.props = {
/* layout 的加载态 */ /* layout 的加载态 */
loading: PropTypes.bool, loading: PropTypes.bool,
/* 用于生成菜单和面包屑 请从 RouterContext 注入 */ /* 用于生成菜单和面包屑 请从 RouterContext 注入 */
// menuData: PropTypes.array, menuData: PropTypes.array,
// location: PropTypes.string, // location: PropTypes.string,
// Custom render // Custom render
...@@ -279,8 +271,6 @@ ProLayout.props = { ...@@ -279,8 +271,6 @@ ProLayout.props = {
menu: PropTypes.object, menu: PropTypes.object,
/* 传递到 antd menu 组件的 props */ /* 传递到 antd menu 组件的 props */
menuProps: PropTypes.object, menuProps: PropTypes.object,
/* 菜单数组 */
menuData: PropTypes.object,
/* 是否分割菜单 (仅 mix 模式有效) */ /* 是否分割菜单 (仅 mix 模式有效) */
splitMenus: PropTypes.bool, splitMenus: PropTypes.bool,
selectedKeys: PropTypes.array, selectedKeys: PropTypes.array,
...@@ -294,6 +284,7 @@ ProLayout.props = { ...@@ -294,6 +284,7 @@ ProLayout.props = {
// onPageChange // 请使用 vue-router 监听 // onPageChange // 请使用 vue-router 监听
/* 禁止自动切换到移动页面 */ /* 禁止自动切换到移动页面 */
disableMobile: PropTypes.bool, disableMobile: PropTypes.bool,
isChildrenLayout: PropTypes.bool,
} as any; } as any;
export default withInstall(ProLayout); export default withInstall(ProLayout);
...@@ -14,7 +14,8 @@ ...@@ -14,7 +14,8 @@
line-height: 48px; line-height: 48px;
background: @component-background; background: @component-background;
border-top: 1px solid @border-color-split; border-top: 1px solid @border-color-split;
box-shadow: @box-shadow-base; box-shadow: 0 -6px 16px -8px rgb(0 0 0 / 8%), 0 -9px 28px 0 rgb(0 0 0 / 5%),
0 -12px 48px 16px rgb(0 0 0 / 3%);
&-left { &-left {
flex: 1; flex: 1;
} }
...@@ -27,4 +28,4 @@ ...@@ -27,4 +28,4 @@
} }
} }
} }
} }
\ No newline at end of file
...@@ -29,16 +29,16 @@ const FooterToolbar = defineComponent({ ...@@ -29,16 +29,16 @@ const FooterToolbar = defineComponent({
props: FooterToolbarProps, props: FooterToolbarProps,
setup(props, ctx) { setup(props, ctx) {
const { slots } = ctx; const { slots } = ctx;
const { getPrefixCls } = useProProvider(); const routeContext = useRouteContext();
const { getPrefixCls } = routeContext;
const baseClassName = props.prefixCls || getPrefixCls('footer-bar'); const baseClassName = props.prefixCls || getPrefixCls('footer-bar');
const routeContext = useRouteContext();
const width = computed(() => { const width = computed(() => {
const { hasSideMenu, isMobile, sideWidth } = routeContext; const { hasSideMenu, isMobile, sideWidth, layout } = routeContext;
if (!hasSideMenu) { if (!hasSideMenu) {
return undefined; return undefined;
} }
if (!sideWidth) { if (!sideWidth || layout === 'top') {
return '100%'; return '100%';
} }
return isMobile ? '100%' : `calc(100% - ${sideWidth}px)`; return isMobile ? '100%' : `calc(100% - ${sideWidth}px)`;
......
...@@ -38,7 +38,7 @@ export interface RouteContextProps extends Partial<PureSettings>, MenuState { ...@@ -38,7 +38,7 @@ export interface RouteContextProps extends Partial<PureSettings>, MenuState {
i18n: (t: string) => string; i18n: (t: string) => string;
breadcrumb?: BreadcrumbListReturn; breadcrumb?: BreadcrumbListReturn;
menuData?: MenuDataItem[]; menuData: MenuDataItem[];
isMobile?: boolean; isMobile?: boolean;
prefixCls?: string; prefixCls?: string;
collapsed?: boolean; collapsed?: boolean;
......
import { FunctionalComponent, computed, watch } from 'vue'; import { FunctionalComponent, computed } 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 'ant-design-vue/es/menu/style'; import 'ant-design-vue/es/menu/style';
...@@ -51,7 +51,7 @@ export const defaultRenderLogo = (logo: VNodeType): VNodeType => { ...@@ -51,7 +51,7 @@ export const defaultRenderLogo = (logo: VNodeType): VNodeType => {
export const defaultRenderLogoAndTitle = ( export const defaultRenderLogoAndTitle = (
props: SiderMenuProps, props: SiderMenuProps,
renderKey: string | undefined = 'menuHeaderRender', renderKey: string | undefined = 'menuHeaderRender',
): VNodeType => { ): VNodeType | null => {
const { const {
logo = 'https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg', logo = 'https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg',
title, title,
...@@ -100,7 +100,6 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -100,7 +100,6 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
const context = useRouteContext(); const context = useRouteContext();
const { getPrefixCls } = context; const { getPrefixCls } = context;
const baseClassName = getPrefixCls('sider'); const baseClassName = getPrefixCls('sider');
console.log('useRouteContext', context);
// const isMix = computed(() => props.layout === 'mix'); // const isMix = computed(() => props.layout === 'mix');
// const fixed = computed(() => context.fixSiderbar); // const fixed = computed(() => context.fixSiderbar);
const runtimeTheme = computed(() => (props.layout === 'mix' && 'light') || props.navTheme); const runtimeTheme = computed(() => (props.layout === 'mix' && 'light') || props.navTheme);
...@@ -115,9 +114,9 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -115,9 +114,9 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
[`${baseClassName}-fixed`]: context.fixSiderbar, [`${baseClassName}-fixed`]: context.fixSiderbar,
}; };
}); });
const hasSide = computed(() => props.layout === 'mix' && props.splitMenus); const hasSide = computed(() => (props.layout === 'mix' && props.splitMenus) || false);
const flatMenuData = computed(() => { const flatMenuData = computed(() => {
return hasSide.value && getMenuFirstChildren(context.menuData, context.selectedKeys[0]); return (hasSide.value && getMenuFirstChildren(context.menuData, context.selectedKeys[0])) || [];
}); });
// call menuHeaderRender // call menuHeaderRender
const headerDom = defaultRenderLogoAndTitle(props); const headerDom = defaultRenderLogoAndTitle(props);
...@@ -125,12 +124,6 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) = ...@@ -125,12 +124,6 @@ const SiderMenu: FunctionalComponent<SiderMenuProps> = (props: SiderMenuProps) =
if (hasSide.value && flatMenuData.value.length === 0) { if (hasSide.value && flatMenuData.value.length === 0) {
return null; return null;
} }
watch(
() => context.selectedKeys,
n => {
console.log('watch:context', n);
},
);
const defaultMenuDom = ( const defaultMenuDom = (
<BaseMenu <BaseMenu
prefixCls={getPrefixCls()} prefixCls={getPrefixCls()}
......
@import '~ant-design-vue/es/style/themes/default.less';
@import '../BasicLayout.less'; @import '../BasicLayout.less';
@pro-layout-sider-menu-prefix-cls: ~'@{ant-prefix}-pro-sider'; @pro-layout-sider-menu-prefix-cls: ~'@{ant-prefix}-pro-sider';
...@@ -9,8 +8,10 @@ ...@@ -9,8 +8,10 @@
position: relative; position: relative;
background-color: @layout-sider-background; background-color: @layout-sider-background;
border-right: 0; border-right: 0;
transition: background-color 0.3s, min-width 0.3s, box-shadow: 2px 0 8px 0 rgba(29, 35, 41, 0.05);
max-width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1); transition: background-color 0.3s
/* , min-width 0.3s,
max-width 0.3s cubic-bezier(0.645, 0.045, 0.355, 1) */;
z-index: 100; z-index: 100;
&.@{ant-prefix}-menu-vertical .@{ant-prefix}-menu-item:not(:last-child), &.@{ant-prefix}-menu-vertical .@{ant-prefix}-menu-item:not(:last-child),
......
...@@ -17,7 +17,7 @@ const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = props => { ...@@ -17,7 +17,7 @@ const SiderMenuWrapper: FunctionalComponent<SiderMenuWrapperProps> = props => {
padding: 0, padding: 0,
height: '100vh', height: '100vh',
}} }}
onClose={() => props.onCollapse(true)} onClose={() => props.onCollapse && props.onCollapse(true)}
width={props.siderWidth} width={props.siderWidth}
bodyStyle={{ height: '100vh', padding: 0, display: 'flex', flexDirection: 'row' }} bodyStyle={{ height: '100vh', padding: 0, display: 'flex', flexDirection: 'row' }}
> >
......
...@@ -4,8 +4,9 @@ ...@@ -4,8 +4,9 @@
"declaration": true, "declaration": true,
"module": "esnext", "module": "esnext",
"target": "ES2018", "target": "ES2018",
"moduleResolution": "node", "strict": true,
"jsx": "preserve", "jsx": "preserve",
"moduleResolution": "node",
"esModuleInterop": true, "esModuleInterop": true,
"skipLibCheck": true, "skipLibCheck": true,
"lib": [ "lib": [
......
...@@ -11893,6 +11893,11 @@ omit.js@^2.0.0: ...@@ -11893,6 +11893,11 @@ omit.js@^2.0.0:
resolved "https://registry.yarnpkg.com/omit.js/-/omit.js-2.0.2.tgz#dd9b8436fab947a5f3ff214cb2538631e313ec2f" resolved "https://registry.yarnpkg.com/omit.js/-/omit.js-2.0.2.tgz#dd9b8436fab947a5f3ff214cb2538631e313ec2f"
integrity sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg== integrity sha512-hJmu9D+bNB40YpL9jYebQl4lsTW6yEHRTroJzNLqQJYHm7c+NQnJGfZmIWh8S3q3KoaxV1aLhV6B3+0N0/kyJg==
omit.js@^2.0.2:
version "2.0.2"
resolved "https://registry.npm.taobao.org/omit.js/download/omit.js-2.0.2.tgz#dd9b8436fab947a5f3ff214cb2538631e313ec2f"
integrity sha1-3ZuENvq5R6Xz/yFMslOGMeMT7C8=
on-finished@^2.3.0, on-finished@~2.3.0: on-finished@^2.3.0, on-finished@~2.3.0:
version "2.3.0" version "2.3.0"
resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947"
......
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