Commit 80f3cfdd authored by Sendya's avatar Sendya

Merge branch 'dev/next/lint-check' into next

# Conflicts:
#	src/FooterToolbar/index.tsx
#	src/ProProvider/index.tsx
#	src/hooks/context/index.ts
parents e1885393 1dc50f77
......@@ -11,7 +11,8 @@ module.exports = {
'@vue/prettier/@typescript-eslint',
],
parserOptions: {
ecmaVersion: 2020,
// ecmaVersion: 2020,
parser: '@typescript-eslint/parser',
},
rules: {
'@typescript-eslint/no-explicit-any': 0,
......
......@@ -16,7 +16,7 @@
"scripts": {
"clean": "cross-env TS_NODE_PROJECT=scripts/tsconfig.json node -r ts-node/register ./scripts/cleanup.ts",
"start": "vc-tools run server",
"lint": "eslint src/ --ext .tsx,.ts",
"lint": "eslint src/ -c .eslintrc.js --ext .tsx,.ts",
"compile": "vc-tools run compile",
"test": "cross-env NODE_ENV=test jest --config .jest.js",
"prepublishOnly": "npm run lint && npm run generate && npm run compile && npm run test",
......@@ -28,7 +28,7 @@
"vue": ">=3.0.0"
},
"devDependencies": {
"@ant-design-vue/tools": "^3.0.2",
"@ant-design-vue/tools": "^3.0.3",
"@babel/runtime": "^7.11.2",
"@types/fs-extra": "^9.0.2",
"@types/jest": "^24.0.17",
......@@ -44,9 +44,7 @@
"@vue/eslint-config-prettier": "^6.0.0",
"@vue/eslint-config-typescript": "^5.0.2",
"@vue/test-utils": "^2.0.0-beta.2",
"babel-loader": "^8.1.0",
"cross-env": "^5.2.0",
"css-loader": "^5.0.0",
"eslint": "^6.7.2",
"eslint-config-prettier": "^6.4.0",
"eslint-plugin-prettier": "^3.1.3",
......@@ -54,10 +52,7 @@
"fs-extra": "^9.0.1",
"jest": "^25.4.0",
"jest-serializer-vue": "^2.0.2",
"less-loader": "^7.0.2",
"postcss-loader": "^4.0.4",
"prettier": "^1.19.1",
"ts-loader": "^8.0.6",
"ts-node": "^8.10.2",
"typescript": "~3.9.3",
"vue": "^3.0.0-0",
......
......@@ -8,7 +8,7 @@ import { default as ProProvider } from './ProProvider';
import { createRouteContext } from './RouteContext';
import SiderMenuWrapper from './SiderMenu';
const defaultI18nRender = (key: string) => key
const defaultI18nRender = (key: string) => key;
const { state, provider: RouteContextProvider } = createRouteContext({
isMobile: false,
......@@ -16,18 +16,18 @@ const { state, provider: RouteContextProvider } = createRouteContext({
sideWidth: 208,
hasSideMenu: true,
hasHeader: true,
})
});
const BasicLayout = (props, { emit, slots }) => {
const handleClick = () => {
emit('update:collapsed', !props.collapsed)
}
emit('update:collapsed', !props.collapsed);
};
const handleOpenChange = (openKeys): void => {
emit('update:openKeys', openKeys)
}
emit('update:openKeys', openKeys);
};
const handleSelect = (selectedKeys: string[]): void => {
emit('update:selectedKeys', selectedKeys)
}
emit('update:selectedKeys', selectedKeys);
};
return (
<ProProvider {...props} i18n={defaultI18nRender}>
<RouteContextProvider>
......@@ -35,24 +35,31 @@ const BasicLayout = (props, { emit, slots }) => {
<SiderMenuWrapper {...props} />
<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} />
}
{props.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' }}>
<Layout.Content
style={{
margin: '24px 16px',
padding: '24px',
background: '#fff',
minHeight: '280px',
}}
>
{slots.default && slots.default()}
</Layout.Content>
</Layout>
</Layout>
</RouteContextProvider>
</ProProvider>
)
);
};
BasicLayout.install = function (app: App) {
app.component('pro-layout', BasicLayout)
BasicLayout.install = function(app: App) {
app.component('pro-layout', BasicLayout);
};
export default BasicLayout
export default BasicLayout;
......@@ -4,13 +4,13 @@ import { WithFalse } from '../typings';
import { defineComponent, PropType, SetupContext, VNodeChild } from 'vue';
export type Links = WithFalse<
{
key?: string;
title: VNodeChild | JSX.Element;
href: string;
blankTarget?: boolean;
}[]
>
{
key?: string;
title: VNodeChild | JSX.Element;
href: string;
blankTarget?: boolean;
}[]
>;
export interface GlobalFooterProps {
links?: Links;
......@@ -25,12 +25,14 @@ export default defineComponent({
copyright: [Object, Function] as PropType<VNodeChild | JSX.Element>,
prefixCls: {
type: String,
default: 'ant-pro'
}
default: 'ant-pro',
},
},
setup (props: GlobalFooterProps, { slots }: SetupContext) {
setup(props: GlobalFooterProps, { slots }: SetupContext) {
if (
(props.links == null || props.links === false || (Array.isArray(props.links) && props.links.length === 0)) &&
(props.links == null ||
props.links === false ||
(Array.isArray(props.links) && props.links.length === 0)) &&
(props.copyright == null || props.copyright === false)
) {
return null;
......@@ -58,5 +60,5 @@ export default defineComponent({
{props.copyright && <div class={`${baseClassName}-copyright`}>{copyright}</div>}
</footer>
);
}
},
});
import './GridContent.less';
import { SetupContext, CSSProperties } from 'vue'
import { SetupContext, CSSProperties } from 'vue';
import { PureSettings } from '../defaultSettings';
interface GridContentProps {
......@@ -9,7 +9,10 @@ interface GridContentProps {
style?: CSSProperties;
}
const GridContent = ({ prefixCls = 'ant-pro', contentWidth }: GridContentProps, { slots }: SetupContext) => {
const GridContent = (
{ prefixCls = 'ant-pro', contentWidth }: GridContentProps,
{ slots }: SetupContext,
) => {
return (
<div
class={{
......
......@@ -16,9 +16,9 @@ export const defaultProProviderProps: ProProviderData = {
},
i18n: (t: string): string => t,
contentWidth: 'Fluid',
}
};
export const injectProConfigKey: InjectionKey<ProProviderData> = Symbol()
export const injectProConfigKey: InjectionKey<ProProviderData> = Symbol();
const ProProvider = defineComponent({
name: 'ProProvider',
......@@ -36,26 +36,26 @@ const ProProvider = defineComponent({
default: (t: string): string => t,
},
},
setup (props, { slots }: SetupContext) {
const { prefixCls, i18n, contentWidth } = toRefs(props)
setup(props, { slots }: SetupContext) {
const { prefixCls, i18n, contentWidth } = toRefs(props);
const getPrefixCls = (suffixCls?: string, customizePrefixCls?: string): string => {
if (customizePrefixCls) return customizePrefixCls;
return suffixCls ? `${prefixCls.value}-${suffixCls}` : prefixCls.value;
}
};
const proConfigProvider = reactive({
i18n,
contentWidth,
getPrefixCls,
})
provide(injectProConfigKey, proConfigProvider)
});
provide(injectProConfigKey, proConfigProvider);
return () => slots.default && slots.default()
return () => slots.default && slots.default();
},
})
});
ProProvider.install = function (app: App) {
app.component(ProProvider.name, ProProvider)
}
ProProvider.install = function(app: App) {
app.component(ProProvider.name, ProProvider);
};
export default ProProvider
export default ProProvider;
import './index.less';
import { defineComponent, h, resolveDynamicComponent, resolveComponent, VNode, ref, reactive, computed, Ref, watch, ComputedRef, VNodeChild, WatchStopHandle, PropType, isVNode, toRefs, defineAsyncComponent, Component } from 'vue';
import {
defineComponent,
h,
ref,
reactive,
computed,
Ref,
watch,
ComputedRef,
VNodeChild,
VNode,
WatchStopHandle,
PropType,
isVNode,
toRefs,
} from 'vue';
// import * as Icon from '@ant-design/icons-vue';
import { createFromIconfontCN } from '@ant-design/icons-vue';
......@@ -10,11 +25,11 @@ import { createFromIconfontCN } from '@ant-design/icons-vue';
import { Menu } from 'ant-design-vue';
import defaultSettings, { PureSettings } from '../defaultSettings';
import { isImg, isUrl } from '../utils'
import { isImg, isUrl } from '../utils';
import { MenuMode, SelectInfo, OpenEventHandler } from './typings';
import { RouteProps, MenuTheme, WithFalse } from '../typings';
export { MenuMode, SelectInfo, OpenEventHandler }
export { MenuMode, SelectInfo, OpenEventHandler };
export interface MenuState {
collapsed?: boolean | false;
......@@ -33,31 +48,38 @@ export interface MenuStateWatched {
watchRef: WatchStopHandle;
}
export function useMenuState ({ collapsed = false, openKeys = [] as string[], selectedKeys = [] as string[], }: MenuState): MenuStateWatched {
export function useMenuState({
collapsed = false,
openKeys = [] as string[],
selectedKeys = [] as string[],
}: MenuState): MenuStateWatched {
const state = reactive<MenuStated>({
collapsed,
selectedKeys,
openKeys,
})
const cachedOpenKeys: Ref<string[]> = ref([] as string[])
const watchRef = watch(() => state.collapsed, (collapsed) => {
if (collapsed) {
cachedOpenKeys.value = state.openKeys.concat()
state.openKeys = []
} else {
state.openKeys = cachedOpenKeys.value.concat()
}
})
});
const cachedOpenKeys: Ref<string[]> = ref([] as string[]);
const watchRef = watch(
() => state.collapsed,
collapsed => {
if (collapsed) {
cachedOpenKeys.value = state.openKeys.concat();
state.openKeys = [];
} else {
state.openKeys = cachedOpenKeys.value.concat();
}
},
);
return {
state,
watchRef,
}
};
}
export function useRootSubmenuKeys (menus: RouteProps[]): ComputedRef<string[]> {
return computed(() => menus.map(it => it.path))
export function useRootSubmenuKeys(menus: RouteProps[]): ComputedRef<string[]> {
return computed(() => menus.map(it => it.path));
}
// ts typo
......@@ -86,7 +108,7 @@ export const VueBaseMenuProps = {
default: 'inline',
},
theme: {
type: String as PropType<MenuTheme | 'realDark'>,
type: String as PropType<MenuTheme>,
default: 'dark',
},
collapsed: {
......@@ -101,46 +123,24 @@ export const VueBaseMenuProps = {
type: Array as PropType<WithFalse<string[]>>,
required: true,
},
}
};
const renderMenu = (item, i18nRender) => {
if (item && !item.hidden) {
const hasChild = item.children && !item.hideChildrenInMenu
return hasChild ? renderSubMenu(item, i18nRender) : renderMenuItem(item, i18nRender)
}
return null
}
const renderSubMenu = (item, i18nRender) => {
const renderMenuContent = (
<span>
<LazyIcon icon={item.meta.icon} />
<span>{renderTitle(item.meta.title, i18nRender)}</span>
</span>
)
return (
<Menu.SubMenu
key={item.path}
// @ts-ignore
title={renderMenuContent}
>
{!item.hideChildrenInMenu && item.children.map(cd => renderMenu(cd, i18nRender))}
</Menu.SubMenu>
)
}
const renderTitle = (title, i18nRender) => {
return <span>{(i18nRender && i18nRender(title)) || title}</span>;
};
const renderMenuItem = (item, i18nRender) => {
const meta = Object.assign({}, item.meta)
const target = meta.target || null
const CustomTag = target && 'a' || 'router-link'
const props = { to: { name: item.name }, href: item.path, target: target }
const meta = Object.assign({}, item.meta);
const target = meta.target || null;
const CustomTag = (target && 'a') || 'router-link';
const props = { to: { name: item.name }, href: item.path, target: target };
if (item.children && item.hideChildrenInMenu) {
// 把有子菜单的 并且 父菜单是要隐藏子菜单的
// 都给子菜单增加一个 hidden 属性
// 用来给刷新页面时, selectedKeys 做控制用
item.children.forEach(cd => {
cd.meta = Object.assign(cd.meta || {}, { hidden: true })
})
cd.meta = Object.assign(cd.meta || {}, { hidden: true });
});
}
return (
<Menu.Item key={item.path}>
......@@ -149,14 +149,36 @@ const renderMenuItem = (item, i18nRender) => {
{renderTitle(meta.title, i18nRender)}
</CustomTag>
</Menu.Item>
)
}
);
};
let IconFont = createFromIconfontCN({
const renderSubMenu = (item, i18nRender) => {
const renderMenuContent = (
<span>
<LazyIcon icon={item.meta.icon} />
<span>{renderTitle(item.meta.title, i18nRender)}</span>
</span>
) as string & VNode;
return (
<Menu.SubMenu key={item.path} title={renderMenuContent}>
{/* eslint-disable-next-line @typescript-eslint/no-use-before-define */}
{!item.hideChildrenInMenu && item.children.map(cd => renderMenu(cd, i18nRender))}
</Menu.SubMenu>
);
};
const renderMenu = (item, i18nRender) => {
if (item && !item.hidden) {
const hasChild = item.children && !item.hideChildrenInMenu;
return hasChild ? renderSubMenu(item, i18nRender) : renderMenuItem(item, i18nRender);
}
return null;
};
const IconFont = createFromIconfontCN({
scriptUrl: defaultSettings.iconfontUrl,
});
// const LazyIcon = (props, _) => {
// const { icon } = toRefs(props)
// if (typeof icon.value === 'string' && icon.value !== '') {
......@@ -173,61 +195,54 @@ let IconFont = createFromIconfontCN({
// const IconComponent = resolveComponent(`${icon.value}`)
// return h(IconComponent)
// }
const LazyIcon = defineComponent({
props: {
icon: {
type: [String, Function, Object] as PropType<string|Function|VNodeChild|JSX.Element>,
const LazyIcon = props => {
const { icon } = toRefs(props);
if (typeof icon.value === 'string' && icon.value !== '') {
if (isUrl(icon.value) || isImg(icon.value)) {
return <img src={icon.value} alt="icon" class="ant-pro-sider-menu-icon" />;
}
},
setup(props, _) {
const { icon } = toRefs(props)
if (typeof icon.value === 'string' && icon.value !== '') {
if (isUrl(icon.value) || isImg(icon.value)) {
return <img src={icon.value} alt="icon" class="ant-pro-sider-menu-icon" />
}
if (icon.value.startsWith('icon-')) {
return <IconFont type={icon.value} />
}
}
if (isVNode(icon.value)) {
return icon.value
if (icon.value.startsWith('icon-')) {
return <IconFont type={icon.value} />;
}
const ALazyIcon = resolveComponent(`${icon.value}`)
// return ALazyIcon && ALazyIcon
return ALazyIcon && (() => (
// @ts-ignore
<ALazyIcon />
)) || null
}
})
const renderTitle = (title, i18nRender) => {
return <span>{ i18nRender && i18nRender(title) || title }</span>
}
if (isVNode(icon.value)) {
return icon.value;
}
// const ALazyIcon = resolveComponent(`${icon.value}`);
// return ALazyIcon && ALazyIcon
return h(icon.value);
};
LazyIcon.icon = {
type: [String, Function, Object] as PropType<string | Function | VNodeChild | JSX.Element>,
};
export default defineComponent({
name: 'BaseMenu',
props: Object.assign({}, {
i18n: {
type: Function,
default: (t: string): string => t,
props: Object.assign(
{},
{
i18n: {
type: Function,
default: (t: string): string => t,
},
},
}, VueBaseMenuProps),
VueBaseMenuProps,
),
emits: ['update:openKeys', 'update:selectedKeys'],
setup (props, { emit } ) {
setup(props, { emit }) {
const { mode } = toRefs(props);
const isInline = computed(() => mode.value === 'inline')
const isInline = computed(() => mode.value === 'inline');
const handleOpenChange: OpenEventHandler = (openKeys): void => {
emit('update:openKeys', openKeys)
}
emit('update:openKeys', openKeys);
};
const handleSelect = ({ selectedKeys }: SelectInfo): void => {
emit('update:selectedKeys', selectedKeys)
}
emit('update:selectedKeys', selectedKeys);
};
return () => (
<Menu
inlineCollapsed={isInline.value && props.collapsed || undefined}
inlineCollapsed={(isInline.value && props.collapsed) || undefined}
mode={props.mode}
theme={props.theme}
openKeys={props.openKeys}
......@@ -235,13 +250,14 @@ export default defineComponent({
onOpenChange={handleOpenChange}
onSelect={handleSelect}
>
{props.menus && props.menus.map(menu => {
if (menu.hidden) {
return null
}
return renderMenu(menu, props.i18n)
})}
{props.menus &&
props.menus.map(menu => {
if (menu.hidden) {
return null;
}
return renderMenu(menu, props.i18n);
})}
</Menu>
)
}
})
);
},
});
import './index.less';
import { computed, ref, VNodeChild, SetupContext, inject } from 'vue';
import { computed, ref, VNodeChild, inject } from 'vue';
// import 'ant-design-vue/es/layout/style';
// import Layout from 'ant-design-vue/es/layout';
......@@ -16,15 +16,22 @@ export type PrivateSiderMenuProps = {
matchMenuKeys: string[];
};
export interface SiderMenuProps extends Pick<BaseMenuProps, Exclude<keyof BaseMenuProps, ['onCollapse']>> {
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
>;
(
logo: VNodeChild | JSX.Element,
title: VNodeChild | JSX.Element,
props?: SiderMenuProps,
) => VNodeChild
>;
menuFooterRender?: WithFalse<(props?: SiderMenuProps) => VNodeChild>;
menuContentRender?: WithFalse<(props: SiderMenuProps, defaultDom: VNodeChild | JSX.Element) => VNodeChild>;
menuContentRender?: WithFalse<
(props: SiderMenuProps, defaultDom: VNodeChild | JSX.Element) => VNodeChild
>;
menuExtraRender?: WithFalse<(props: SiderMenuProps) => VNodeChild>;
collapsedButtonRender?: WithFalse<(collapsed?: boolean) => VNodeChild>;
breakpoint?: SiderProps['breakpoint'] | false;
......@@ -43,7 +50,7 @@ export const defaultRenderLogo = (logo: VNodeChild | JSX.Element): VNodeChild |
return logo();
}
return logo;
}
};
export const defaultRenderLogoAndTitle = (
props: SiderMenuProps,
......@@ -53,7 +60,7 @@ export const defaultRenderLogoAndTitle = (
logo = 'https://gw.alipayobjects.com/zos/antfincdn/PmY%24TNNDBI/logo.svg',
title,
layout,
} = props
} = props;
const renderFunction = props[renderKey || ''];
if (renderFunction === false) {
return null;
......@@ -73,41 +80,31 @@ export const defaultRenderLogoAndTitle = (
{props.collapsed ? null : titleDom}
</a>
);
}
};
export const defaultRenderCollapsedButton = (collapsed?: boolean) =>
collapsed ? <MenuUnfoldOutlined /> : <MenuFoldOutlined />;
const SiderMenu = (props: SiderMenuProps, context: SetupContext) => {
const SiderMenu = (props: SiderMenuProps) => {
const {
menuData,
collapsed,
fixSiderbar,
menuFooterRender,
onCollapse,
theme,
siderWidth,
isMobile,
onMenuHeaderClick,
breakpoint = 'lg',
layout,
menuExtraRender = false,
collapsedButtonRender = defaultRenderCollapsedButton,
menuContentRender,
prefixCls,
onOpenChange,
onSelect,
headerHeight,
collapsedWidth = 48,
} = props;
console.log('props', props)
const { getPrefixCls } = inject(injectProConfigKey, defaultProProviderProps)
console.log('props', props);
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 runtimeTheme = computed(() => (props.layout === 'mix' && 'light') || 'dark');
const runtimeSideWidth = computed(() =>
props.collapsed ? props.collapsedWidth : props.siderWidth,
);
const classNames = ref({
[baseClassName]: true,
......@@ -122,14 +119,17 @@ const SiderMenu = (props: SiderMenuProps, context: SetupContext) => {
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`,
}}
/>)}
{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={classNames.value}
width={siderWidth}
......@@ -137,9 +137,7 @@ const SiderMenu = (props: SiderMenuProps, context: SetupContext) => {
collapsible={false}
collapsedWidth={collapsedWidth}
>
<div class="ant-pro-sider-logo">
{headerDom}
</div>
<div class="ant-pro-sider-logo">{headerDom}</div>
<div style="flex: 1 1 0%; overflow: hidden auto;">
<BaseMenu
menus={menuData}
......@@ -158,7 +156,7 @@ const SiderMenu = (props: SiderMenuProps, context: SetupContext) => {
},
'onUpdate:selectedKeys': $event => {
onSelect($event);
}
},
}}
/>
</div>
......
import { FunctionalComponent, toRefs } from "vue"
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}
/>
)
const SiderMenuWrapper: FunctionalComponent<SiderMenuProps & PrivateSiderMenuProps> = (
props,
ctx,
) => {
return props.isMobile ? (
<Drawer>
<SiderMenu {...props} />
</Drawer>
) : (
<SiderMenu {...props} />
);
};
SiderMenuWrapper.inheritAttrs = false
SiderMenuWrapper.inheritAttrs = false;
export default SiderMenuWrapper;
......@@ -6,12 +6,12 @@ export interface MenuInfo {
key: string;
keyPath: string[];
item: VNodeChild;
domEvent?: MouseEvent,
};
domEvent?: MouseEvent;
}
export interface SelectInfo extends MenuInfo {
selectedKeys?: string[];
};
}
export type OpenEventHandler = (
keys:
......@@ -24,7 +24,6 @@ export type OpenEventHandler = (
},
) => void;
export type CollapseType = 'clickTrigger' | 'responsive';
export type SiderTheme = 'light' | 'dark';
......
import { MenuTheme, ContentWidth } from './typings'
import { MenuTheme, ContentWidth } from './typings';
export interface RenderSetting {
headerRender?: false;
......
......@@ -18,10 +18,10 @@ export interface CreateContext<T> {
state: UnwrapRef<T> | T;
}
export const createContext = <T>(context: ContextType<T>,
contextInjectKey: InjectionKey<ContextType<T>> = Symbol(),
export const createContext = <T>(
context: ContextType<T>,
contextInjectKey: InjectionKey<ContextType<T>> = Symbol(),
): CreateContext<T> => {
const state = reactive<ContextType<T>>({
...context,
});
......@@ -41,8 +41,11 @@ export const createContext = <T>(context: ContextType<T>,
};
};
export const useContext = <T>(contextInjectKey: InjectionKey<ContextType<T>> = Symbol(), defaultValue?: ContextType<T>): T => {
return readonly(inject(contextInjectKey, defaultValue || {} as T));
export const useContext = <T>(
contextInjectKey: InjectionKey<ContextType<T>> = Symbol(),
defaultValue?: ContextType<T>,
): T => {
return readonly(inject(contextInjectKey, defaultValue || ({} as T)));
};
// :: examples ::
......
import { VNodeChild } from 'vue'
import { VNodeChild } from 'vue';
export type MenuTheme = 'dark' | 'light';
......
import isUrl from './isUrl';
import isImg from './isImg';
import isNil from './isNil';
import { nextTick, h } from 'vue';
import { AbstractNode, IconDefinition } from '@ant-design/icons-svg/lib/types';
import { generate as generateColor } from '@ant-design/colors';
import insertCss from '../insert-css';
export { default as isUrl } from './isUrl';
export { default as isImg } from './isImg';
export { default as isNil } from './isNil';
export function warn(valid: boolean, message: string) {
// Support uglify
if (process.env.NODE_ENV !== 'production' && !valid && console !== undefined) {
......@@ -164,9 +164,3 @@ export const useInsertStyles = (styleStr: string = iconStyles) => {
}
});
};
export {
isUrl,
isImg,
isNil,
}
// source by https://github.com/ant-design/pro-components/blob/master/packages/utils
/* eslint no-useless-escape:0 import/prefer-default-export:0 */
/* eslint no-useless-escape:0 */
const reg = /(((^https?:(?:\/\/)?)(?:[-;:&=\+\$,\w]+@)?[A-Za-z0-9.-]+(?::\d+)?|(?:www.|[-;:&=\+\$,\w]+@)[A-Za-z0-9.-]+)((?:\/[\+~%\/.\w-_]*)?\??(?:[-\+=&;%@.\w_]*)#?(?:[\w]*))?)$/;
const isUrl = (path: string): boolean => reg.test(path);
......
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