Merge branch 'next' of https://github.com/vueComponent/ant-design-vue into next
commit
34b3e6366f
|
@ -36,9 +36,7 @@ export function withUndefined<T extends { default?: any }>(type: T): T {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default PropTypes as VueTypesInterface & {
|
export default PropTypes as VueTypesInterface & {
|
||||||
readonly looseBool: VueTypeValidableDef<boolean> & {
|
readonly looseBool: VueTypeValidableDef<boolean>;
|
||||||
default: undefined;
|
|
||||||
};
|
|
||||||
readonly style: VueTypeValidableDef<CSSProperties>;
|
readonly style: VueTypeValidableDef<CSSProperties>;
|
||||||
readonly VNodeChild: VueTypeValidableDef<VNodeTypes>;
|
readonly VNodeChild: VueTypeValidableDef<VNodeTypes>;
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,13 +1,9 @@
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import { inject, provide } from 'vue';
|
import { inject, provide, PropType, defineComponent } from 'vue';
|
||||||
import PropTypes from '../_util/vue-types';
|
import PropTypes from '../_util/vue-types';
|
||||||
import {
|
import { tuple } from '../_util/type';
|
||||||
initDefaultProps,
|
import { getOptionProps, hasProp, getComponent, getSlot } from '../_util/props-util';
|
||||||
getOptionProps,
|
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||||
hasProp,
|
|
||||||
getComponent,
|
|
||||||
getSlot,
|
|
||||||
} from '../_util/props-util';
|
|
||||||
import BaseMixin from '../_util/BaseMixin';
|
import BaseMixin from '../_util/BaseMixin';
|
||||||
import isNumeric from '../_util/isNumeric';
|
import isNumeric from '../_util/isNumeric';
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
import { defaultConfigProvider } from '../config-provider';
|
||||||
|
@ -15,6 +11,7 @@ import BarsOutlined from '@ant-design/icons-vue/BarsOutlined';
|
||||||
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
|
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
|
||||||
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
|
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
|
||||||
import omit from 'omit.js';
|
import omit from 'omit.js';
|
||||||
|
import { SiderHookProvider } from './layout';
|
||||||
|
|
||||||
const dimensionMaxMap = {
|
const dimensionMaxMap = {
|
||||||
xs: '479.98px',
|
xs: '479.98px',
|
||||||
|
@ -25,7 +22,7 @@ const dimensionMaxMap = {
|
||||||
xxl: '1599.98px',
|
xxl: '1599.98px',
|
||||||
};
|
};
|
||||||
|
|
||||||
// export type CollapseType = 'clickTrigger' | 'responsive';
|
export type CollapseType = 'clickTrigger' | 'responsive';
|
||||||
|
|
||||||
export const SiderProps = {
|
export const SiderProps = {
|
||||||
prefixCls: PropTypes.string,
|
prefixCls: PropTypes.string,
|
||||||
|
@ -33,16 +30,14 @@ export const SiderProps = {
|
||||||
collapsed: PropTypes.looseBool,
|
collapsed: PropTypes.looseBool,
|
||||||
defaultCollapsed: PropTypes.looseBool,
|
defaultCollapsed: PropTypes.looseBool,
|
||||||
reverseArrow: PropTypes.looseBool,
|
reverseArrow: PropTypes.looseBool,
|
||||||
// onCollapse?: (collapsed: boolean, type: CollapseType) => void;
|
zeroWidthTriggerStyle: PropTypes.style,
|
||||||
zeroWidthTriggerStyle: PropTypes.object,
|
trigger: PropTypes.VNodeChild,
|
||||||
trigger: PropTypes.any,
|
|
||||||
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||||
collapsedWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
collapsedWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
|
||||||
breakpoint: PropTypes.oneOf(['xs', 'sm', 'md', 'lg', 'xl', 'xxl']),
|
breakpoint: PropTypes.oneOf(tuple('xs', 'sm', 'md', 'lg', 'xl', 'xxl')),
|
||||||
theme: PropTypes.oneOf(['light', 'dark']).def('dark'),
|
theme: PropTypes.oneOf(tuple('light', 'dark')).def('dark'),
|
||||||
onBreakpoint: PropTypes.func,
|
onBreakpoint: Function as PropType<(broken: boolean) => void>,
|
||||||
onCollapse: PropTypes.func,
|
onCollapse: Function as PropType<(collapsed: boolean, type: CollapseType) => void>,
|
||||||
'onUpdate:collapsed': PropTypes.func,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// export interface SiderState {
|
// export interface SiderState {
|
||||||
|
@ -63,7 +58,7 @@ const generateId = (() => {
|
||||||
};
|
};
|
||||||
})();
|
})();
|
||||||
|
|
||||||
export default {
|
export default defineComponent({
|
||||||
name: 'ALayoutSider',
|
name: 'ALayoutSider',
|
||||||
__ANT_LAYOUT_SIDER: true,
|
__ANT_LAYOUT_SIDER: true,
|
||||||
mixins: [BaseMixin],
|
mixins: [BaseMixin],
|
||||||
|
@ -74,17 +69,19 @@ export default {
|
||||||
width: 200,
|
width: 200,
|
||||||
collapsedWidth: 80,
|
collapsedWidth: 80,
|
||||||
}),
|
}),
|
||||||
|
emits: ['breakpoint', 'update:collapsed', 'collapse'],
|
||||||
data() {
|
data() {
|
||||||
this.uniqueId = generateId('ant-sider-');
|
const uniqueId = generateId('ant-sider-');
|
||||||
let matchMedia;
|
let matchMedia: typeof window.matchMedia;
|
||||||
if (typeof window !== 'undefined') {
|
if (typeof window !== 'undefined') {
|
||||||
matchMedia = window.matchMedia;
|
matchMedia = window.matchMedia;
|
||||||
}
|
}
|
||||||
const props = getOptionProps(this);
|
const props = getOptionProps(this) as any;
|
||||||
|
let mql: MediaQueryList;
|
||||||
if (matchMedia && props.breakpoint && props.breakpoint in dimensionMaxMap) {
|
if (matchMedia && props.breakpoint && props.breakpoint in dimensionMaxMap) {
|
||||||
this.mql = matchMedia(`(max-width: ${dimensionMaxMap[props.breakpoint]})`);
|
mql = matchMedia(`(max-width: ${dimensionMaxMap[props.breakpoint]})`);
|
||||||
}
|
}
|
||||||
let sCollapsed;
|
let sCollapsed: boolean;
|
||||||
if ('collapsed' in props) {
|
if ('collapsed' in props) {
|
||||||
sCollapsed = props.collapsed;
|
sCollapsed = props.collapsed;
|
||||||
} else {
|
} else {
|
||||||
|
@ -94,6 +91,8 @@ export default {
|
||||||
sCollapsed,
|
sCollapsed,
|
||||||
below: false,
|
below: false,
|
||||||
belowShow: false,
|
belowShow: false,
|
||||||
|
uniqueId,
|
||||||
|
mql,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
watch: {
|
watch: {
|
||||||
|
@ -108,7 +107,7 @@ export default {
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
return {
|
return {
|
||||||
siderHook: inject('siderHook', {}),
|
siderHook: inject<SiderHookProvider>('siderHook', {}),
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
configProvider: inject('configProvider', defaultConfigProvider),
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
@ -136,7 +135,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
responsiveHandler(mql) {
|
responsiveHandler(mql: MediaQueryListEvent | MediaQueryList) {
|
||||||
this.setState({ below: mql.matches });
|
this.setState({ below: mql.matches });
|
||||||
this.$emit('breakpoint', mql.matches);
|
this.$emit('breakpoint', mql.matches);
|
||||||
if (this.sCollapsed !== mql.matches) {
|
if (this.sCollapsed !== mql.matches) {
|
||||||
|
@ -144,7 +143,7 @@ export default {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setCollapsed(collapsed, type) {
|
setCollapsed(collapsed: boolean, type: CollapseType) {
|
||||||
if (!hasProp(this, 'collapsed')) {
|
if (!hasProp(this, 'collapsed')) {
|
||||||
this.setState({
|
this.setState({
|
||||||
sCollapsed: collapsed,
|
sCollapsed: collapsed,
|
||||||
|
@ -176,7 +175,7 @@ export default {
|
||||||
collapsedWidth,
|
collapsedWidth,
|
||||||
zeroWidthTriggerStyle,
|
zeroWidthTriggerStyle,
|
||||||
...others
|
...others
|
||||||
} = { ...getOptionProps(this), ...this.$attrs };
|
} = { ...getOptionProps(this), ...this.$attrs } as any;
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||||
const prefixCls = getPrefixCls('layout-sider', customizePrefixCls);
|
const prefixCls = getPrefixCls('layout-sider', customizePrefixCls);
|
||||||
const divProps = omit(others, [
|
const divProps = omit(others, [
|
||||||
|
@ -188,7 +187,6 @@ export default {
|
||||||
'siderHook',
|
'siderHook',
|
||||||
'zeroWidthTriggerStyle',
|
'zeroWidthTriggerStyle',
|
||||||
'trigger',
|
'trigger',
|
||||||
'onUpdate:collapse',
|
|
||||||
]);
|
]);
|
||||||
const trigger = getComponent(this, 'trigger');
|
const trigger = getComponent(this, 'trigger');
|
||||||
const rawWidth = this.sCollapsed ? collapsedWidth : width;
|
const rawWidth = this.sCollapsed ? collapsedWidth : width;
|
||||||
|
@ -241,4 +239,4 @@ export default {
|
||||||
</aside>
|
</aside>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
};
|
});
|
|
@ -1,10 +1,11 @@
|
||||||
|
import { App } from 'vue';
|
||||||
import Layout from './layout';
|
import Layout from './layout';
|
||||||
import Sider from './Sider';
|
import Sider from './Sider';
|
||||||
|
|
||||||
Layout.Sider = Sider;
|
Layout.Sider = Sider;
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
Layout.install = function(app) {
|
Layout.install = function(app: App) {
|
||||||
app.component(Layout.name, Layout);
|
app.component(Layout.name, Layout);
|
||||||
app.component(Layout.Header.name, Layout.Header);
|
app.component(Layout.Header.name, Layout.Header);
|
||||||
app.component(Layout.Footer.name, Layout.Footer);
|
app.component(Layout.Footer.name, Layout.Footer);
|
||||||
|
@ -12,4 +13,6 @@ Layout.install = function(app) {
|
||||||
app.component(Layout.Content.name, Layout.Content);
|
app.component(Layout.Content.name, Layout.Content);
|
||||||
return app;
|
return app;
|
||||||
};
|
};
|
||||||
export default Layout;
|
export default Layout as typeof Layout & {
|
||||||
|
readonly Sider: typeof Sider;
|
||||||
|
};
|
|
@ -1,107 +0,0 @@
|
||||||
import { inject, provide } from 'vue';
|
|
||||||
import PropTypes from '../_util/vue-types';
|
|
||||||
import classNames from '../_util/classNames';
|
|
||||||
import { getOptionProps, getSlot } from '../_util/props-util';
|
|
||||||
import { defaultConfigProvider } from '../config-provider';
|
|
||||||
|
|
||||||
export const BasicProps = {
|
|
||||||
prefixCls: PropTypes.string,
|
|
||||||
hasSider: PropTypes.looseBool,
|
|
||||||
tagName: PropTypes.string,
|
|
||||||
};
|
|
||||||
|
|
||||||
function generator({ suffixCls, tagName, name }) {
|
|
||||||
return BasicComponent => {
|
|
||||||
return {
|
|
||||||
name,
|
|
||||||
props: BasicComponent.props,
|
|
||||||
setup() {
|
|
||||||
return {
|
|
||||||
configProvider: inject('configProvider', defaultConfigProvider),
|
|
||||||
};
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
const { prefixCls: customizePrefixCls } = this.$props;
|
|
||||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
|
||||||
const prefixCls = getPrefixCls(suffixCls, customizePrefixCls);
|
|
||||||
|
|
||||||
const basicComponentProps = {
|
|
||||||
prefixCls,
|
|
||||||
...getOptionProps(this),
|
|
||||||
tagName,
|
|
||||||
};
|
|
||||||
return <BasicComponent {...basicComponentProps}>{getSlot(this)}</BasicComponent>;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
const Basic = {
|
|
||||||
props: BasicProps,
|
|
||||||
render() {
|
|
||||||
const { prefixCls, tagName: Tag } = this;
|
|
||||||
const divProps = {
|
|
||||||
class: prefixCls,
|
|
||||||
};
|
|
||||||
return <Tag {...divProps}>{getSlot(this)}</Tag>;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const BasicLayout = {
|
|
||||||
props: BasicProps,
|
|
||||||
data() {
|
|
||||||
return {
|
|
||||||
siders: [],
|
|
||||||
};
|
|
||||||
},
|
|
||||||
created() {
|
|
||||||
provide('siderHook', {
|
|
||||||
addSider: id => {
|
|
||||||
this.siders = [...this.siders, id];
|
|
||||||
},
|
|
||||||
removeSider: id => {
|
|
||||||
this.siders = this.siders.filter(currentId => currentId !== id);
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
render() {
|
|
||||||
const { prefixCls, hasSider, tagName: Tag } = this;
|
|
||||||
const divCls = classNames(prefixCls, {
|
|
||||||
[`${prefixCls}-has-sider`]: typeof hasSider === 'boolean' ? hasSider : this.siders.length > 0,
|
|
||||||
});
|
|
||||||
const divProps = {
|
|
||||||
class: divCls,
|
|
||||||
};
|
|
||||||
return <Tag {...divProps}>{getSlot(this)}</Tag>;
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const Layout = generator({
|
|
||||||
suffixCls: 'layout',
|
|
||||||
tagName: 'section',
|
|
||||||
name: 'ALayout',
|
|
||||||
})(BasicLayout);
|
|
||||||
|
|
||||||
const Header = generator({
|
|
||||||
suffixCls: 'layout-header',
|
|
||||||
tagName: 'header',
|
|
||||||
name: 'ALayoutHeader',
|
|
||||||
})(Basic);
|
|
||||||
|
|
||||||
const Footer = generator({
|
|
||||||
suffixCls: 'layout-footer',
|
|
||||||
tagName: 'footer',
|
|
||||||
name: 'ALayoutFooter',
|
|
||||||
})(Basic);
|
|
||||||
|
|
||||||
const Content = generator({
|
|
||||||
suffixCls: 'layout-content',
|
|
||||||
tagName: 'main',
|
|
||||||
name: 'ALayoutContent',
|
|
||||||
})(Basic);
|
|
||||||
|
|
||||||
Layout.Header = Header;
|
|
||||||
Layout.Footer = Footer;
|
|
||||||
Layout.Content = Content;
|
|
||||||
|
|
||||||
export default Layout;
|
|
|
@ -0,0 +1,110 @@
|
||||||
|
import { createVNode, defineComponent, inject, provide, toRefs, ref } from 'vue';
|
||||||
|
import PropTypes from '../_util/vue-types';
|
||||||
|
import classNames from '../_util/classNames';
|
||||||
|
import { defaultConfigProvider } from '../config-provider';
|
||||||
|
|
||||||
|
export const BasicProps = {
|
||||||
|
prefixCls: PropTypes.string,
|
||||||
|
hasSider: PropTypes.looseBool,
|
||||||
|
tagName: PropTypes.string,
|
||||||
|
};
|
||||||
|
|
||||||
|
export interface SiderHookProvider {
|
||||||
|
addSider?: (id: string) => void;
|
||||||
|
removeSider?: (id: string) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
type GeneratorArgument = {
|
||||||
|
suffixCls: string;
|
||||||
|
tagName: string;
|
||||||
|
name: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
function generator({ suffixCls, tagName, name }: GeneratorArgument) {
|
||||||
|
return (BasicComponent: typeof Basic) => {
|
||||||
|
return defineComponent({
|
||||||
|
name,
|
||||||
|
props: BasicProps,
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const { getPrefixCls } = inject('configProvider', defaultConfigProvider);
|
||||||
|
return () => {
|
||||||
|
const { prefixCls: customizePrefixCls } = props;
|
||||||
|
const prefixCls = getPrefixCls(suffixCls, customizePrefixCls);
|
||||||
|
const basicComponentProps = {
|
||||||
|
prefixCls,
|
||||||
|
...props,
|
||||||
|
tagName,
|
||||||
|
};
|
||||||
|
return <BasicComponent {...basicComponentProps}>{slots.default?.()}</BasicComponent>;
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const Basic = defineComponent({
|
||||||
|
props: BasicProps,
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const { prefixCls, tagName } = toRefs(props);
|
||||||
|
return () => createVNode(tagName.value, { class: prefixCls.value }, slots.default?.());
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const BasicLayout = defineComponent({
|
||||||
|
props: BasicProps,
|
||||||
|
setup(props, { slots }) {
|
||||||
|
const siders = ref<string[]>([]);
|
||||||
|
const siderHookProvider: SiderHookProvider = {
|
||||||
|
addSider: id => {
|
||||||
|
siders.value = [...siders.value, id];
|
||||||
|
},
|
||||||
|
removeSider: id => {
|
||||||
|
siders.value = siders.value.filter(currentId => currentId !== id);
|
||||||
|
},
|
||||||
|
};
|
||||||
|
provide('siderHook', siderHookProvider);
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
const { prefixCls, hasSider, tagName } = props;
|
||||||
|
const divCls = classNames(prefixCls, {
|
||||||
|
[`${prefixCls}-has-sider`]:
|
||||||
|
typeof hasSider === 'boolean' ? hasSider : siders.value.length > 0,
|
||||||
|
});
|
||||||
|
return createVNode(tagName, { class: divCls }, slots.default?.());
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const Layout = generator({
|
||||||
|
suffixCls: 'layout',
|
||||||
|
tagName: 'section',
|
||||||
|
name: 'ALayout',
|
||||||
|
})(BasicLayout);
|
||||||
|
|
||||||
|
const Header = generator({
|
||||||
|
suffixCls: 'layout-header',
|
||||||
|
tagName: 'header',
|
||||||
|
name: 'ALayoutHeader',
|
||||||
|
})(Basic);
|
||||||
|
|
||||||
|
const Footer = generator({
|
||||||
|
suffixCls: 'layout-footer',
|
||||||
|
tagName: 'footer',
|
||||||
|
name: 'ALayoutFooter',
|
||||||
|
})(Basic);
|
||||||
|
|
||||||
|
const Content = generator({
|
||||||
|
suffixCls: 'layout-content',
|
||||||
|
tagName: 'main',
|
||||||
|
name: 'ALayoutContent',
|
||||||
|
})(Basic);
|
||||||
|
|
||||||
|
Layout.Header = Header;
|
||||||
|
Layout.Footer = Footer;
|
||||||
|
Layout.Content = Content;
|
||||||
|
|
||||||
|
export default Layout as typeof Layout & {
|
||||||
|
readonly Header: typeof Header;
|
||||||
|
readonly Footer: typeof Footer;
|
||||||
|
readonly Content: typeof Content;
|
||||||
|
};
|
Loading…
Reference in New Issue