mirror of
https://gitee.com/ant-design-vue/ant-design-vue.git
synced 2024-12-05 05:29:01 +08:00
refactor: layout
This commit is contained in:
parent
fe99051b55
commit
3825c6507f
@ -1,17 +1,25 @@
|
||||
import classNames from '../_util/classNames';
|
||||
import { inject, provide, PropType, defineComponent, nextTick } from 'vue';
|
||||
import {
|
||||
inject,
|
||||
PropType,
|
||||
defineComponent,
|
||||
ExtractPropTypes,
|
||||
ref,
|
||||
watch,
|
||||
onMounted,
|
||||
onBeforeUnmount,
|
||||
CSSProperties,
|
||||
provide,
|
||||
} from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import { tuple } from '../_util/type';
|
||||
import { getOptionProps, hasProp, getComponent, getSlot } from '../_util/props-util';
|
||||
import initDefaultProps from '../_util/props-util/initDefaultProps';
|
||||
import BaseMixin from '../_util/BaseMixin';
|
||||
import isNumeric from '../_util/isNumeric';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import BarsOutlined from '@ant-design/icons-vue/BarsOutlined';
|
||||
import RightOutlined from '@ant-design/icons-vue/RightOutlined';
|
||||
import LeftOutlined from '@ant-design/icons-vue/LeftOutlined';
|
||||
import omit from 'omit.js';
|
||||
import { SiderHookProvider } from './layout';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import { SiderCollapsedKey, SiderHookProviderKey } from './injectionKey';
|
||||
|
||||
const dimensionMaxMap = {
|
||||
xs: '479.98px',
|
||||
@ -24,7 +32,7 @@ const dimensionMaxMap = {
|
||||
|
||||
export type CollapseType = 'clickTrigger' | 'responsive';
|
||||
|
||||
export const SiderProps = {
|
||||
export const siderProps = {
|
||||
prefixCls: PropTypes.string,
|
||||
collapsible: PropTypes.looseBool,
|
||||
collapsed: PropTypes.looseBool,
|
||||
@ -40,6 +48,7 @@ export const SiderProps = {
|
||||
onCollapse: Function as PropType<(collapsed: boolean, type: CollapseType) => void>,
|
||||
};
|
||||
|
||||
export type SiderProps = Partial<ExtractPropTypes<typeof siderProps>>;
|
||||
// export interface SiderState {
|
||||
// collapsed?: boolean;
|
||||
// below: boolean;
|
||||
@ -61,10 +70,8 @@ const generateId = (() => {
|
||||
|
||||
export default defineComponent({
|
||||
name: 'ALayoutSider',
|
||||
mixins: [BaseMixin],
|
||||
inheritAttrs: false,
|
||||
__ANT_LAYOUT_SIDER: true,
|
||||
props: initDefaultProps(SiderProps, {
|
||||
props: initDefaultProps(siderProps, {
|
||||
collapsible: false,
|
||||
defaultCollapsed: false,
|
||||
reverseArrow: false,
|
||||
@ -72,173 +79,141 @@ export default defineComponent({
|
||||
collapsedWidth: 80,
|
||||
}),
|
||||
emits: ['breakpoint', 'update:collapsed', 'collapse'],
|
||||
setup() {
|
||||
return {
|
||||
siderHook: inject<SiderHookProvider>('siderHook', {}),
|
||||
configProvider: inject('configProvider', defaultConfigProvider),
|
||||
};
|
||||
},
|
||||
data() {
|
||||
const uniqueId = generateId('ant-sider-');
|
||||
let matchMedia: typeof window.matchMedia;
|
||||
if (typeof window !== 'undefined') {
|
||||
matchMedia = window.matchMedia;
|
||||
}
|
||||
const props = getOptionProps(this) as any;
|
||||
let mql: MediaQueryList;
|
||||
if (matchMedia && props.breakpoint && props.breakpoint in dimensionMaxMap) {
|
||||
mql = matchMedia(`(max-width: ${dimensionMaxMap[props.breakpoint]})`);
|
||||
}
|
||||
let sCollapsed: boolean;
|
||||
if ('collapsed' in props) {
|
||||
sCollapsed = props.collapsed;
|
||||
} else {
|
||||
sCollapsed = props.defaultCollapsed;
|
||||
}
|
||||
return {
|
||||
sCollapsed,
|
||||
below: false,
|
||||
belowShow: false,
|
||||
uniqueId,
|
||||
mql,
|
||||
};
|
||||
},
|
||||
watch: {
|
||||
collapsed(val) {
|
||||
this.setState({
|
||||
sCollapsed: val,
|
||||
});
|
||||
},
|
||||
},
|
||||
created() {
|
||||
provide('layoutSiderContext', this); // menu组件中使用
|
||||
},
|
||||
|
||||
mounted() {
|
||||
nextTick(() => {
|
||||
if (this.mql) {
|
||||
this.mql.addListener(this.responsiveHandler);
|
||||
this.responsiveHandler(this.mql);
|
||||
}
|
||||
|
||||
if (this.siderHook.addSider) {
|
||||
this.siderHook.addSider(this.uniqueId);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
beforeUnmount() {
|
||||
if (this.mql) {
|
||||
this.mql.removeListener(this.responsiveHandler);
|
||||
}
|
||||
|
||||
if (this.siderHook.removeSider) {
|
||||
this.siderHook.removeSider(this.uniqueId);
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
responsiveHandler(mql: MediaQueryListEvent | MediaQueryList) {
|
||||
this.setState({ below: mql.matches });
|
||||
this.$emit('breakpoint', mql.matches);
|
||||
if (this.sCollapsed !== mql.matches) {
|
||||
this.setCollapsed(mql.matches, 'responsive');
|
||||
}
|
||||
},
|
||||
|
||||
setCollapsed(collapsed: boolean, type: CollapseType) {
|
||||
if (!hasProp(this, 'collapsed')) {
|
||||
this.setState({
|
||||
sCollapsed: collapsed,
|
||||
});
|
||||
}
|
||||
this.$emit('update:collapsed', collapsed);
|
||||
this.$emit('collapse', collapsed, type);
|
||||
},
|
||||
|
||||
toggle() {
|
||||
const collapsed = !this.sCollapsed;
|
||||
this.setCollapsed(collapsed, 'clickTrigger');
|
||||
},
|
||||
|
||||
belowShowChange() {
|
||||
this.setState({ belowShow: !this.belowShow });
|
||||
},
|
||||
},
|
||||
|
||||
render() {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
class: className,
|
||||
theme,
|
||||
collapsible,
|
||||
reverseArrow,
|
||||
style,
|
||||
width,
|
||||
collapsedWidth,
|
||||
zeroWidthTriggerStyle,
|
||||
...others
|
||||
} = { ...getOptionProps(this), ...this.$attrs } as any;
|
||||
const getPrefixCls = this.configProvider.getPrefixCls;
|
||||
const prefixCls = getPrefixCls('layout-sider', customizePrefixCls);
|
||||
const divProps = omit(others, [
|
||||
'collapsed',
|
||||
'defaultCollapsed',
|
||||
'onCollapse',
|
||||
'breakpoint',
|
||||
'onBreakpoint',
|
||||
'siderHook',
|
||||
'zeroWidthTriggerStyle',
|
||||
'trigger',
|
||||
]);
|
||||
const trigger = getComponent(this, 'trigger');
|
||||
const rawWidth = this.sCollapsed ? collapsedWidth : width;
|
||||
// use "px" as fallback unit for width
|
||||
const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth);
|
||||
// special trigger when collapsedWidth == 0
|
||||
const zeroWidthTrigger =
|
||||
parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
||||
<span
|
||||
onClick={this.toggle}
|
||||
class={`${prefixCls}-zero-width-trigger ${prefixCls}-zero-width-trigger-${
|
||||
reverseArrow ? 'right' : 'left'
|
||||
}`}
|
||||
style={zeroWidthTriggerStyle}
|
||||
>
|
||||
<BarsOutlined />
|
||||
</span>
|
||||
) : null;
|
||||
const iconObj = {
|
||||
expanded: reverseArrow ? <RightOutlined /> : <LeftOutlined />,
|
||||
collapsed: reverseArrow ? <LeftOutlined /> : <RightOutlined />,
|
||||
};
|
||||
const status = this.sCollapsed ? 'collapsed' : 'expanded';
|
||||
const defaultTrigger = iconObj[status];
|
||||
const triggerDom =
|
||||
trigger !== null
|
||||
? zeroWidthTrigger || (
|
||||
<div class={`${prefixCls}-trigger`} onClick={this.toggle} style={{ width: siderWidth }}>
|
||||
{trigger || defaultTrigger}
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
const divStyle = {
|
||||
...style,
|
||||
flex: `0 0 ${siderWidth}`,
|
||||
maxWidth: siderWidth, // Fix width transition bug in IE11
|
||||
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
|
||||
width: siderWidth,
|
||||
};
|
||||
const siderCls = classNames(className, prefixCls, `${prefixCls}-${theme}`, {
|
||||
[`${prefixCls}-collapsed`]: !!this.sCollapsed,
|
||||
[`${prefixCls}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
|
||||
[`${prefixCls}-below`]: !!this.below,
|
||||
[`${prefixCls}-zero-width`]: parseFloat(siderWidth) === 0,
|
||||
});
|
||||
return (
|
||||
<aside class={siderCls} {...divProps} style={divStyle}>
|
||||
<div class={`${prefixCls}-children`}>{getSlot(this)}</div>
|
||||
{collapsible || (this.below && zeroWidthTrigger) ? triggerDom : null}
|
||||
</aside>
|
||||
setup(props, { emit, attrs, slots }) {
|
||||
const { prefixCls } = useConfigInject('layout-sider', props);
|
||||
const siderHook = inject(SiderHookProviderKey);
|
||||
const collapsed = ref(
|
||||
!!(props.collapsed !== undefined ? props.collapsed : props.defaultCollapsed),
|
||||
);
|
||||
const below = ref(false);
|
||||
|
||||
watch(
|
||||
() => props.collapsed,
|
||||
() => {
|
||||
collapsed.value = !!props.collapsed;
|
||||
},
|
||||
);
|
||||
|
||||
provide(SiderCollapsedKey, collapsed);
|
||||
|
||||
const handleSetCollapsed = (value: boolean, type: CollapseType) => {
|
||||
if (props.collapsed === undefined) {
|
||||
collapsed.value = value;
|
||||
}
|
||||
emit('update:collapsed', value);
|
||||
emit('collapse', value, type);
|
||||
};
|
||||
|
||||
// ========================= Responsive =========================
|
||||
const responsiveHandlerRef = ref<(mql: MediaQueryListEvent | MediaQueryList) => void>(
|
||||
(mql: MediaQueryListEvent | MediaQueryList) => {
|
||||
below.value = mql.matches;
|
||||
emit('breakpoint', mql.matches);
|
||||
|
||||
if (collapsed.value !== mql.matches) {
|
||||
handleSetCollapsed(mql.matches, 'responsive');
|
||||
}
|
||||
},
|
||||
);
|
||||
let mql: MediaQueryList;
|
||||
function responsiveHandler(mql: MediaQueryListEvent | MediaQueryList) {
|
||||
return responsiveHandlerRef.value!(mql);
|
||||
}
|
||||
const uniqueId = generateId('ant-sider-');
|
||||
onMounted(() => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const { matchMedia } = window;
|
||||
if (matchMedia! && props.breakpoint && props.breakpoint in dimensionMaxMap) {
|
||||
mql = matchMedia(`(max-width: ${dimensionMaxMap[props.breakpoint]})`);
|
||||
try {
|
||||
mql.addEventListener('change', responsiveHandler);
|
||||
} catch (error) {
|
||||
mql.addListener(responsiveHandler);
|
||||
}
|
||||
responsiveHandler(mql);
|
||||
}
|
||||
}
|
||||
siderHook && siderHook.addSider(uniqueId);
|
||||
});
|
||||
onBeforeUnmount(() => {
|
||||
try {
|
||||
mql?.removeEventListener('change', responsiveHandler);
|
||||
} catch (error) {
|
||||
mql?.removeListener(responsiveHandler);
|
||||
}
|
||||
siderHook && siderHook.removeSider(uniqueId);
|
||||
});
|
||||
|
||||
const toggle = () => {
|
||||
handleSetCollapsed(!collapsed.value, 'clickTrigger');
|
||||
};
|
||||
|
||||
return () => {
|
||||
const pre = prefixCls.value;
|
||||
const {
|
||||
collapsedWidth,
|
||||
width,
|
||||
reverseArrow,
|
||||
zeroWidthTriggerStyle,
|
||||
trigger,
|
||||
collapsible,
|
||||
theme,
|
||||
} = props;
|
||||
const rawWidth = collapsed.value ? collapsedWidth : width;
|
||||
// use "px" as fallback unit for width
|
||||
const siderWidth = isNumeric(rawWidth) ? `${rawWidth}px` : String(rawWidth);
|
||||
// special trigger when collapsedWidth == 0
|
||||
const zeroWidthTrigger =
|
||||
parseFloat(String(collapsedWidth || 0)) === 0 ? (
|
||||
<span
|
||||
onClick={toggle}
|
||||
class={classNames(
|
||||
`${pre}-zero-width-trigger`,
|
||||
`${pre}-zero-width-trigger-${reverseArrow ? 'right' : 'left'}`,
|
||||
)}
|
||||
style={zeroWidthTriggerStyle}
|
||||
>
|
||||
{trigger || <BarsOutlined />}
|
||||
</span>
|
||||
) : null;
|
||||
const iconObj = {
|
||||
expanded: reverseArrow ? <RightOutlined /> : <LeftOutlined />,
|
||||
collapsed: reverseArrow ? <LeftOutlined /> : <RightOutlined />,
|
||||
};
|
||||
const status = collapsed.value ? 'collapsed' : 'expanded';
|
||||
const defaultTrigger = iconObj[status];
|
||||
const triggerDom =
|
||||
trigger !== null
|
||||
? zeroWidthTrigger || (
|
||||
<div class={`${pre}-trigger`} onClick={toggle} style={{ width: siderWidth }}>
|
||||
{trigger || defaultTrigger}
|
||||
</div>
|
||||
)
|
||||
: null;
|
||||
const divStyle = {
|
||||
...(attrs.style as CSSProperties),
|
||||
flex: `0 0 ${siderWidth}`,
|
||||
maxWidth: siderWidth, // Fix width transition bug in IE11
|
||||
minWidth: siderWidth, // https://github.com/ant-design/ant-design/issues/6349
|
||||
width: siderWidth,
|
||||
};
|
||||
const siderCls = classNames(
|
||||
pre,
|
||||
`${pre}-${theme}`,
|
||||
{
|
||||
[`${pre}-collapsed`]: !!collapsed.value,
|
||||
[`${pre}-has-trigger`]: collapsible && trigger !== null && !zeroWidthTrigger,
|
||||
[`${pre}-below`]: !!below.value,
|
||||
[`${pre}-zero-width`]: parseFloat(siderWidth) === 0,
|
||||
},
|
||||
attrs.class,
|
||||
);
|
||||
return (
|
||||
<aside {...attrs} class={siderCls} style={divStyle} ref={ref}>
|
||||
<div class={`${pre}-children`}>{slots.default?.()}</div>
|
||||
{collapsible || (below && zeroWidthTrigger) ? triggerDom : null}
|
||||
</aside>
|
||||
);
|
||||
};
|
||||
},
|
||||
});
|
||||
|
@ -2,6 +2,9 @@ import { App, Plugin } from 'vue';
|
||||
import Layout from './layout';
|
||||
import Sider from './Sider';
|
||||
|
||||
export { BasicProps as LayoutProps } from './layout';
|
||||
export { SiderProps } from './Sider';
|
||||
|
||||
Layout.Sider = Sider;
|
||||
|
||||
/* istanbul ignore next */
|
||||
|
12
components/layout/injectionKey.ts
Normal file
12
components/layout/injectionKey.ts
Normal file
@ -0,0 +1,12 @@
|
||||
import { Ref, InjectionKey } from 'vue';
|
||||
|
||||
export type SiderCollapsed = Ref<boolean>;
|
||||
|
||||
export const SiderCollapsedKey: InjectionKey<SiderCollapsed> = Symbol('siderCollapsed');
|
||||
|
||||
export interface SiderHookProvider {
|
||||
addSider?: (id: string) => void;
|
||||
removeSider?: (id: string) => void;
|
||||
}
|
||||
|
||||
export const SiderHookProviderKey: InjectionKey<SiderHookProvider> = Symbol('siderHookProvider');
|
@ -1,17 +1,8 @@
|
||||
import {
|
||||
createVNode,
|
||||
defineComponent,
|
||||
inject,
|
||||
provide,
|
||||
toRefs,
|
||||
ref,
|
||||
ExtractPropTypes,
|
||||
HTMLAttributes,
|
||||
} from 'vue';
|
||||
import { createVNode, defineComponent, provide, ref, ExtractPropTypes, HTMLAttributes } from 'vue';
|
||||
import PropTypes from '../_util/vue-types';
|
||||
import classNames from '../_util/classNames';
|
||||
import { defaultConfigProvider } from '../config-provider';
|
||||
import { flattenChildren } from '../_util/props-util';
|
||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||
import { SiderHookProviderKey } from './injectionKey';
|
||||
|
||||
export const basicProps = {
|
||||
prefixCls: PropTypes.string,
|
||||
@ -21,40 +12,29 @@ export const basicProps = {
|
||||
|
||||
export type BasicProps = Partial<ExtractPropTypes<typeof basicProps>> & HTMLAttributes;
|
||||
|
||||
export interface SiderHookProvider {
|
||||
addSider?: (id: string) => void;
|
||||
removeSider?: (id: string) => void;
|
||||
}
|
||||
|
||||
type GeneratorArgument = {
|
||||
suffixCls: string;
|
||||
tagName: string;
|
||||
tagName: 'header' | 'footer' | 'main' | 'section';
|
||||
name: string;
|
||||
};
|
||||
|
||||
function generator({ suffixCls, tagName, name }: GeneratorArgument) {
|
||||
return (BasicComponent: typeof Basic) => {
|
||||
const Adapter = defineComponent<BasicProps>({
|
||||
const Adapter = defineComponent({
|
||||
name,
|
||||
props: basicProps,
|
||||
setup(props, { slots }) {
|
||||
const { getPrefixCls } = inject('configProvider', defaultConfigProvider);
|
||||
const { prefixCls } = useConfigInject(suffixCls, props);
|
||||
return () => {
|
||||
const { prefixCls: customizePrefixCls } = props;
|
||||
const prefixCls = getPrefixCls(suffixCls, customizePrefixCls);
|
||||
const basicComponentProps = {
|
||||
prefixCls,
|
||||
...props,
|
||||
prefixCls: prefixCls.value,
|
||||
tagName,
|
||||
...props,
|
||||
};
|
||||
return (
|
||||
<BasicComponent {...basicComponentProps}>
|
||||
{flattenChildren(slots.default?.())}
|
||||
</BasicComponent>
|
||||
);
|
||||
return <BasicComponent {...basicComponentProps}>{slots.default?.()}</BasicComponent>;
|
||||
};
|
||||
},
|
||||
});
|
||||
Adapter.props = basicProps;
|
||||
return Adapter;
|
||||
};
|
||||
}
|
||||
@ -62,30 +42,32 @@ function generator({ suffixCls, tagName, name }: GeneratorArgument) {
|
||||
const Basic = defineComponent({
|
||||
props: basicProps,
|
||||
setup(props, { slots }) {
|
||||
const { prefixCls, tagName } = toRefs(props);
|
||||
return () => createVNode(tagName.value, { class: prefixCls.value }, slots.default?.());
|
||||
return () => createVNode(props.tagName, { class: props.prefixCls }, slots.default?.());
|
||||
},
|
||||
});
|
||||
|
||||
const BasicLayout = defineComponent({
|
||||
props: basicProps,
|
||||
setup(props, { slots }) {
|
||||
const { direction } = useConfigInject('', props);
|
||||
const siders = ref<string[]>([]);
|
||||
const siderHookProvider: SiderHookProvider = {
|
||||
addSider: id => {
|
||||
const siderHookProvider = {
|
||||
addSider: (id: string) => {
|
||||
siders.value = [...siders.value, id];
|
||||
},
|
||||
removeSider: id => {
|
||||
removeSider: (id: string) => {
|
||||
siders.value = siders.value.filter(currentId => currentId !== id);
|
||||
},
|
||||
};
|
||||
provide('siderHook', siderHookProvider);
|
||||
|
||||
provide(SiderHookProviderKey, siderHookProvider);
|
||||
|
||||
return () => {
|
||||
const { prefixCls, hasSider, tagName } = props;
|
||||
const divCls = classNames(prefixCls, {
|
||||
[`${prefixCls}-has-sider`]:
|
||||
typeof hasSider === 'boolean' ? hasSider : siders.value.length > 0,
|
||||
[`${prefixCls}-rtl`]: direction.value === 'rtl',
|
||||
});
|
||||
return createVNode(tagName, { class: divCls }, slots.default?.());
|
||||
};
|
||||
|
@ -2,6 +2,7 @@
|
||||
@import '../../style/mixins/index';
|
||||
|
||||
@layout-prefix-cls: ~'@{ant-prefix}-layout';
|
||||
@layout-menu-prefix-cls: ~'@{ant-prefix}-menu';
|
||||
|
||||
.@{layout-prefix-cls} {
|
||||
display: flex;
|
||||
@ -18,9 +19,10 @@
|
||||
|
||||
&&-has-sider {
|
||||
flex-direction: row;
|
||||
|
||||
> .@{layout-prefix-cls},
|
||||
> .@{layout-prefix-cls}-content {
|
||||
overflow-x: hidden;
|
||||
width: 0; // https://segmentfault.com/a/1190000019498300
|
||||
}
|
||||
}
|
||||
|
||||
@ -32,6 +34,7 @@
|
||||
&-header {
|
||||
height: @layout-header-height;
|
||||
padding: @layout-header-padding;
|
||||
color: @layout-header-color;
|
||||
line-height: @layout-header-height;
|
||||
background: @layout-header-background;
|
||||
}
|
||||
@ -64,6 +67,10 @@
|
||||
// https://github.com/ant-design/ant-design/issues/7967
|
||||
// solution from https://stackoverflow.com/a/33132624/3040605
|
||||
padding-top: 0.1px;
|
||||
|
||||
.@{layout-menu-prefix-cls}.@{layout-menu-prefix-cls}-inline-collapsed {
|
||||
width: auto;
|
||||
}
|
||||
}
|
||||
|
||||
&-has-trigger {
|
||||
@ -88,7 +95,7 @@
|
||||
}
|
||||
|
||||
&-zero-width {
|
||||
& > * {
|
||||
> * {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
@ -108,8 +115,19 @@
|
||||
cursor: pointer;
|
||||
transition: background 0.3s ease;
|
||||
|
||||
&:hover {
|
||||
background: tint(@layout-sider-background, 10%);
|
||||
&::after {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
background: transparent;
|
||||
transition: all 0.3s;
|
||||
content: '';
|
||||
}
|
||||
|
||||
&:hover::after {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
}
|
||||
|
||||
&-right {
|
||||
@ -122,3 +140,4 @@
|
||||
}
|
||||
|
||||
@import './light';
|
||||
@import './rtl';
|
||||
|
@ -1,15 +1,11 @@
|
||||
.@{layout-prefix-cls} {
|
||||
&-sider {
|
||||
&-light {
|
||||
background: @layout-sider-background-light;
|
||||
}
|
||||
&-light &-trigger {
|
||||
color: @layout-trigger-color-light;
|
||||
background: @layout-trigger-background-light;
|
||||
}
|
||||
&-light &-zero-width-trigger {
|
||||
color: @layout-trigger-color-light;
|
||||
background: @layout-trigger-background-light;
|
||||
}
|
||||
.@{layout-prefix-cls}-sider-light {
|
||||
background: @layout-sider-background-light;
|
||||
.@{layout-prefix-cls}-sider-trigger {
|
||||
color: @layout-trigger-color-light;
|
||||
background: @layout-trigger-background-light;
|
||||
}
|
||||
.@{layout-prefix-cls}-sider-zero-width-trigger {
|
||||
color: @layout-trigger-color-light;
|
||||
background: @layout-trigger-background-light;
|
||||
}
|
||||
}
|
||||
|
10
components/layout/style/rtl.less
Normal file
10
components/layout/style/rtl.less
Normal file
@ -0,0 +1,10 @@
|
||||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
|
||||
@layout-prefix-cls: ~'@{ant-prefix}-layout';
|
||||
|
||||
.@{layout-prefix-cls} {
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
}
|
@ -27,6 +27,7 @@ import {
|
||||
import devWarning from '../../vc-util/devWarning';
|
||||
import { collapseMotion, CSSMotionProps } from '../../_util/transition';
|
||||
import uniq from 'lodash-es/uniq';
|
||||
import { SiderCollapsedKey } from '../../layout/injectionKey';
|
||||
|
||||
export const menuProps = {
|
||||
prefixCls: String,
|
||||
@ -72,10 +73,7 @@ export default defineComponent({
|
||||
setup(props, { slots, emit }) {
|
||||
const { prefixCls, direction } = useConfigInject('menu', props);
|
||||
const store = reactive<Record<string, StoreMenuInfo>>({});
|
||||
const siderCollapsed = inject(
|
||||
'layoutSiderCollapsed',
|
||||
computed(() => undefined),
|
||||
);
|
||||
const siderCollapsed = inject(SiderCollapsedKey, ref(undefined));
|
||||
const inlineCollapsed = computed(() => {
|
||||
if (siderCollapsed.value !== undefined) {
|
||||
return siderCollapsed.value;
|
||||
|
@ -300,10 +300,11 @@
|
||||
// Layout
|
||||
@layout-body-background: #f0f2f5;
|
||||
@layout-header-background: #001529;
|
||||
@layout-footer-background: @layout-body-background;
|
||||
@layout-header-height: 64px;
|
||||
@layout-header-padding: 0 50px;
|
||||
@layout-header-color: @text-color;
|
||||
@layout-footer-padding: 24px 50px;
|
||||
@layout-footer-background: @layout-body-background;
|
||||
@layout-sider-background: @layout-header-background;
|
||||
@layout-trigger-height: 48px;
|
||||
@layout-trigger-background: #002140;
|
||||
|
Loading…
Reference in New Issue
Block a user