Browse Source

refactor(layout): less to cssinjs (#6249)

pull/6247/head
bqy_fe 2 years ago committed by GitHub
parent
commit
7a34c99935
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 12
      components/layout/layout.tsx
  2. 145
      components/layout/style/index.less
  3. 225
      components/layout/style/index.ts
  4. 2
      components/layout/style/index.tsx
  5. 11
      components/layout/style/light.less
  6. 27
      components/layout/style/light.ts
  7. 10
      components/layout/style/rtl.less
  8. 2
      components/style.ts
  9. 4
      components/theme/interface/components.ts

12
components/layout/layout.tsx

@ -2,6 +2,7 @@ import type { ExtractPropTypes, HTMLAttributes } from 'vue';
import { computed, createVNode, defineComponent, provide, ref } from 'vue';
import useConfigInject from '../config-provider/hooks/useConfigInject';
import { SiderHookProviderKey } from './injectionKey';
import useStyle from './style';
export const basicProps = () => ({
prefixCls: String,
@ -18,7 +19,7 @@ type GeneratorArgument = {
};
function generator({ suffixCls, tagName, name }: GeneratorArgument) {
return (BasicComponent: typeof Basic) => {
return (BasicComponent: typeof BasicLayout) => {
const Adapter = defineComponent({
compatConfig: { MODE: 3 },
name,
@ -49,9 +50,11 @@ const Basic = defineComponent({
const BasicLayout = defineComponent({
compatConfig: { MODE: 3 },
inheritAttrs: false,
props: basicProps(),
setup(props, { slots }) {
const { direction } = useConfigInject('', props);
setup(props, { slots, attrs }) {
const { prefixCls, direction } = useConfigInject('', props);
const [wrapSSR, hashId] = useStyle(prefixCls);
const siders = ref<string[]>([]);
const siderHookProvider = {
addSider: (id: string) => {
@ -66,6 +69,7 @@ const BasicLayout = defineComponent({
const divCls = computed(() => {
const { prefixCls, hasSider } = props;
return {
[hashId.value]: true,
[`${prefixCls}`]: true,
[`${prefixCls}-has-sider`]:
typeof hasSider === 'boolean' ? hasSider : siders.value.length > 0,
@ -74,7 +78,7 @@ const BasicLayout = defineComponent({
});
return () => {
const { tagName } = props;
return createVNode(tagName, { class: divCls.value }, slots);
return wrapSSR(createVNode(tagName, { ...attrs, class: [divCls.value, attrs.class] }, slots));
};
},
});

145
components/layout/style/index.less

@ -1,145 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@layout-prefix-cls: ~'@{ant-prefix}-layout';
@layout-menu-prefix-cls: ~'@{ant-prefix}-menu';
.@{layout-prefix-cls} {
display: flex;
flex: auto;
flex-direction: column;
/* fix firefox can't set height smaller than content on flex item */
min-height: 0;
background: @layout-body-background;
&,
* {
box-sizing: border-box;
}
&&-has-sider {
flex-direction: row;
> .@{layout-prefix-cls},
> .@{layout-prefix-cls}-content {
width: 0; // https://segmentfault.com/a/1190000019498300
}
}
&-header,
&-footer {
flex: 0 0 auto;
}
&-header {
height: @layout-header-height;
padding: @layout-header-padding;
color: @layout-header-color;
line-height: @layout-header-height;
background: @layout-header-background;
}
&-footer {
padding: @layout-footer-padding;
color: @text-color;
font-size: @font-size-base;
background: @layout-footer-background;
}
&-content {
flex: auto;
/* fix firefox can't set height smaller than content on flex item */
min-height: 0;
}
&-sider {
position: relative;
/* fix firefox can't set width smaller than content on flex item */
min-width: 0;
background: @layout-sider-background;
transition: all 0.2s;
&-children {
height: 100%;
margin-top: -0.1px;
// Hack for fixing margin collaspe bug
// 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 {
padding-bottom: @layout-trigger-height;
}
&-right {
order: 1;
}
&-trigger {
position: fixed;
bottom: 0;
z-index: 1;
height: @layout-trigger-height;
color: @layout-trigger-color;
line-height: @layout-trigger-height;
text-align: center;
background: @layout-trigger-background;
cursor: pointer;
transition: all 0.2s;
}
&-zero-width {
> * {
overflow: hidden;
}
&-trigger {
position: absolute;
top: @layout-header-height;
right: -@layout-zero-trigger-width;
z-index: 1;
width: @layout-zero-trigger-width;
height: @layout-zero-trigger-height;
color: @layout-trigger-color;
font-size: (@layout-zero-trigger-width / 2);
line-height: @layout-zero-trigger-height;
text-align: center;
background: @layout-sider-background;
border-radius: 0 @border-radius-base @border-radius-base 0;
cursor: pointer;
transition: background 0.3s ease;
&::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 {
left: -@layout-zero-trigger-width;
border-radius: @border-radius-base 0 0 @border-radius-base;
}
}
}
}
}
@import './light';
@import './rtl';

225
components/layout/style/index.ts

@ -0,0 +1,225 @@
import type { CSSObject } from '../../_util/cssinjs';
import type { FullToken, GenerateStyle } from '../../theme/internal';
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
import genLayoutLightStyle from './light';
export interface ComponentToken {
colorBgHeader: string;
colorBgBody: string;
colorBgTrigger: string;
}
export interface LayoutToken extends FullToken<'Layout'> {
// Layout
layoutHeaderHeight: number;
layoutHeaderPaddingInline: number;
layoutHeaderColor: string;
layoutFooterPadding: string;
layoutTriggerHeight: number;
layoutZeroTriggerSize: number;
}
const genLayoutStyle: GenerateStyle<LayoutToken, CSSObject> = token => {
const {
antCls, // .ant
componentCls, // .ant-layout
colorText,
colorTextLightSolid,
colorBgHeader,
colorBgBody,
colorBgTrigger,
layoutHeaderHeight,
layoutHeaderPaddingInline,
layoutHeaderColor,
layoutFooterPadding,
layoutTriggerHeight,
layoutZeroTriggerSize,
motionDurationMid,
motionDurationSlow,
fontSize,
borderRadius,
} = token;
return {
[componentCls]: {
display: 'flex',
flex: 'auto',
flexDirection: 'column',
/* fix firefox can't set height smaller than content on flex item */
minHeight: 0,
background: colorBgBody,
'&, *': {
boxSizing: 'border-box',
},
[`&${componentCls}-has-sider`]: {
flexDirection: 'row',
[`> ${componentCls}, > ${componentCls}-content`]: {
// https://segmentfault.com/a/1190000019498300
width: 0,
},
},
[`${componentCls}-header, &${componentCls}-footer`]: {
flex: '0 0 auto',
},
[`${componentCls}-header`]: {
height: layoutHeaderHeight,
paddingInline: layoutHeaderPaddingInline,
color: layoutHeaderColor,
lineHeight: `${layoutHeaderHeight}px`,
background: colorBgHeader,
// Other components/menu/style/index.less line:686
// Integration with header element so menu items have the same height
[`${antCls}-menu`]: {
lineHeight: 'inherit',
},
},
[`${componentCls}-footer`]: {
padding: layoutFooterPadding,
color: colorText,
fontSize,
background: colorBgBody,
},
[`${componentCls}-content`]: {
flex: 'auto',
// fix firefox can't set height smaller than content on flex item
minHeight: 0,
},
[`${componentCls}-sider`]: {
position: 'relative',
// fix firefox can't set width smaller than content on flex item
minWidth: 0,
background: colorBgHeader,
transition: `all ${motionDurationMid}`,
'&-children': {
height: '100%',
// Hack for fixing margin collapse bug
// https://github.com/ant-design/ant-design/issues/7967
// solution from https://stackoverflow.com/a/33132624/3040605
marginTop: -0.1,
paddingTop: 0.1,
[`${antCls}-menu${antCls}-menu-inline-collapsed`]: {
width: 'auto',
},
},
'&-has-trigger': {
paddingBottom: layoutTriggerHeight,
},
'&-right': {
order: 1,
},
'&-trigger': {
position: 'fixed',
bottom: 0,
zIndex: 1,
height: layoutTriggerHeight,
color: colorTextLightSolid,
lineHeight: `${layoutTriggerHeight}px`,
textAlign: 'center',
background: colorBgTrigger,
cursor: 'pointer',
transition: `all ${motionDurationMid}`,
},
'&-zero-width': {
'> *': {
overflow: 'hidden',
},
'&-trigger': {
position: 'absolute',
top: layoutHeaderHeight,
insetInlineEnd: -layoutZeroTriggerSize,
zIndex: 1,
width: layoutZeroTriggerSize,
height: layoutZeroTriggerSize,
color: colorTextLightSolid,
fontSize: token.fontSizeXL,
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
background: colorBgHeader,
borderStartStartRadius: 0,
borderStartEndRadius: borderRadius,
borderEndEndRadius: borderRadius,
borderEndStartRadius: 0,
cursor: 'pointer',
transition: `background ${motionDurationSlow} ease`,
'&::after': {
position: 'absolute',
inset: 0,
background: 'transparent',
transition: `all ${motionDurationSlow}`,
content: '""',
},
'&:hover::after': {
// FIXME: Hardcode, but seems no need to create a token for this
background: `rgba(255, 255, 255, 0.2)`,
},
'&-right': {
insetInlineStart: -layoutZeroTriggerSize,
borderStartStartRadius: borderRadius,
borderStartEndRadius: 0,
borderEndEndRadius: 0,
borderEndStartRadius: borderRadius,
},
},
},
},
// Light
...genLayoutLightStyle(token),
// RTL
'&-rtl': {
direction: 'rtl',
},
},
};
};
// ============================== Export ==============================
export default genComponentStyleHook(
'Layout',
token => {
const { colorText, controlHeightSM, controlHeight, controlHeightLG, marginXXS } = token;
const layoutHeaderPaddingInline = controlHeightLG * 1.25;
const layoutToken = mergeToken<LayoutToken>(token, {
// Layout
layoutHeaderHeight: controlHeight * 2,
layoutHeaderPaddingInline,
layoutHeaderColor: colorText,
layoutFooterPadding: `${controlHeightSM}px ${layoutHeaderPaddingInline}px`,
layoutTriggerHeight: controlHeightLG + marginXXS * 2, // = item height + margin
layoutZeroTriggerSize: controlHeightLG,
});
return [genLayoutStyle(layoutToken)];
},
token => {
const { colorBgLayout } = token;
return {
colorBgHeader: '#001529',
colorBgBody: colorBgLayout,
colorBgTrigger: '#002140',
};
},
);

2
components/layout/style/index.tsx

@ -1,2 +0,0 @@
import '../../style/index.less';
import './index.less';

11
components/layout/style/light.less

@ -1,11 +0,0 @@
.@{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;
}
}

27
components/layout/style/light.ts

@ -0,0 +1,27 @@
import type { CSSObject } from '../../_util/cssinjs';
import type { LayoutToken } from '.';
import type { GenerateStyle } from '../../theme/internal';
const genLayoutLightStyle: GenerateStyle<LayoutToken, CSSObject> = token => {
const { componentCls, colorBgContainer, colorBgBody, colorText } = token;
return {
[`${componentCls}-sider-light`]: {
background: colorBgContainer,
[`${componentCls}-sider-trigger`]: {
color: colorText,
background: colorBgContainer,
},
[`${componentCls}-sider-zero-width-trigger`]: {
color: colorText,
background: colorBgContainer,
border: `1px solid ${colorBgBody}`, // Safe to modify to any other color
borderInlineStart: 0,
},
},
};
};
export default genLayoutLightStyle;

10
components/layout/style/rtl.less

@ -1,10 +0,0 @@
@import '../../style/themes/index';
@import '../../style/mixins/index';
@layout-prefix-cls: ~'@{ant-prefix}-layout';
.@{layout-prefix-cls} {
&-rtl {
direction: rtl;
}
}

2
components/style.ts

@ -44,7 +44,7 @@ import './input-number/style';
import './transfer/style';
import './tree/style';
import './upload/style';
import './layout/style';
// import './layout/style';
// import './anchor/style';
// import './list/style';
import './tree-select/style';

4
components/theme/interface/components.ts

@ -17,7 +17,7 @@ import type { ComponentToken as DropdownComponentToken } from '../../dropdown/st
import type { ComponentToken as EmptyComponentToken } from '../../empty/style';
// import type { ComponentToken as ImageComponentToken } from '../../image/style';
// import type { ComponentToken as InputNumberComponentToken } from '../../input-number/style';
// import type { ComponentToken as LayoutComponentToken } from '../../layout/style';
import type { ComponentToken as LayoutComponentToken } from '../../layout/style';
import type { ComponentToken as ListComponentToken } from '../../list/style';
// import type { ComponentToken as MentionsComponentToken } from '../../mentions/style';
import type { ComponentToken as MenuComponentToken } from '../../menu/style';
@ -77,7 +77,7 @@ export interface ComponentTokenMap {
// Image?: ImageComponentToken;
Input?: {};
// InputNumber?: InputNumberComponentToken;
// Layout?: LayoutComponentToken;
Layout?: LayoutComponentToken;
List?: ListComponentToken;
// Mentions?: MentionsComponentToken;
Notification?: NotificationComponentToken;

Loading…
Cancel
Save