refactor:pageheader (#6239)
* refactor:pageheader * fix inheritAttrs: false & attrs.classpull/6245/head
parent
fee7c04d67
commit
a9fbf98f0e
|
@ -16,6 +16,9 @@ import useDestroyed from '../_util/hooks/useDestroyed';
|
|||
import type { MouseEventHandler } from '../_util/EventInterface';
|
||||
import Space from '../space';
|
||||
|
||||
// CSSINJS
|
||||
import useStyle from './style';
|
||||
|
||||
export const pageHeaderProps = () => ({
|
||||
backIcon: PropTypes.any,
|
||||
prefixCls: String,
|
||||
|
@ -35,11 +38,16 @@ export type PageHeaderProps = Partial<ExtractPropTypes<ReturnType<typeof pageHea
|
|||
const PageHeader = defineComponent({
|
||||
compatConfig: { MODE: 3 },
|
||||
name: 'APageHeader',
|
||||
inheritAttrs: false,
|
||||
props: pageHeaderProps(),
|
||||
// emits: ['back'],
|
||||
slots: ['backIcon', 'avatar', 'breadcrumb', 'title', 'subTitle', 'tags', 'extra', 'footer'],
|
||||
setup(props, { emit, slots }) {
|
||||
setup(props, { emit, slots, attrs }) {
|
||||
const { prefixCls, direction, pageHeader } = useConfigInject('page-header', props);
|
||||
|
||||
// style
|
||||
const [wrapSSR, hashId] = useStyle(prefixCls);
|
||||
|
||||
const compact = ref(false);
|
||||
const isDestroyed = useDestroyed();
|
||||
const onResize = ({ width }: { width: number }) => {
|
||||
|
@ -148,22 +156,27 @@ const PageHeader = defineComponent({
|
|||
const hasBreadcrumb = props.breadcrumb?.routes || slots.breadcrumb;
|
||||
const hasFooter = props.footer || slots.footer;
|
||||
const children = flattenChildren(slots.default?.());
|
||||
const className = classNames(prefixCls.value, {
|
||||
const className = classNames(
|
||||
prefixCls.value,
|
||||
{
|
||||
'has-breadcrumb': hasBreadcrumb,
|
||||
'has-footer': hasFooter,
|
||||
[`${prefixCls.value}-ghost`]: ghost.value,
|
||||
[`${prefixCls.value}-rtl`]: direction.value === 'rtl',
|
||||
[`${prefixCls.value}-compact`]: compact.value,
|
||||
});
|
||||
return (
|
||||
},
|
||||
attrs.class,
|
||||
hashId.value,
|
||||
);
|
||||
return wrapSSR(
|
||||
<ResizeObserver onResize={onResize}>
|
||||
<div class={className}>
|
||||
<div {...attrs} class={className}>
|
||||
{renderBreadcrumb()}
|
||||
{renderTitle()}
|
||||
{children.length ? renderChildren(children) : null}
|
||||
{renderFooter()}
|
||||
</div>
|
||||
</ResizeObserver>
|
||||
</ResizeObserver>,
|
||||
);
|
||||
};
|
||||
},
|
||||
|
|
|
@ -1,123 +0,0 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
|
||||
@pageheader-prefix-cls: ~'@{ant-prefix}-page-header';
|
||||
|
||||
.@{pageheader-prefix-cls} {
|
||||
.reset-component();
|
||||
position: relative;
|
||||
padding: @page-header-padding-vertical @page-header-padding;
|
||||
background-color: @component-background;
|
||||
|
||||
&-ghost {
|
||||
background-color: @page-header-ghost-bg;
|
||||
}
|
||||
|
||||
&.has-breadcrumb {
|
||||
padding-top: @page-header-padding-breadcrumb;
|
||||
}
|
||||
|
||||
&.has-footer {
|
||||
padding-bottom: 0;
|
||||
}
|
||||
|
||||
&-back {
|
||||
margin-right: @margin-md;
|
||||
font-size: 16px;
|
||||
line-height: 1;
|
||||
|
||||
&-button {
|
||||
.operation-unit();
|
||||
color: @page-header-back-color;
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
|
||||
.@{ant-prefix}-divider-vertical {
|
||||
height: 14px;
|
||||
margin: 0 @margin-sm;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.@{ant-prefix}-breadcrumb + &-heading {
|
||||
margin-top: @margin-xs;
|
||||
}
|
||||
|
||||
.text-overflow-ellipsis() {
|
||||
overflow: hidden;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
}
|
||||
|
||||
&-heading {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
|
||||
&-left {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin: (@margin-xs / 2) 0;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
&-title {
|
||||
margin-right: @margin-sm;
|
||||
margin-bottom: 0;
|
||||
color: @heading-color;
|
||||
font-weight: 600;
|
||||
font-size: @page-header-heading-title;
|
||||
line-height: @height-base;
|
||||
.text-overflow-ellipsis();
|
||||
}
|
||||
|
||||
.@{ant-prefix}-avatar {
|
||||
margin-right: @margin-sm;
|
||||
}
|
||||
|
||||
&-sub-title {
|
||||
margin-right: @margin-sm;
|
||||
color: @text-color-secondary;
|
||||
font-size: @page-header-heading-sub-title;
|
||||
line-height: @line-height-base;
|
||||
.text-overflow-ellipsis();
|
||||
}
|
||||
|
||||
&-extra {
|
||||
margin: (@margin-xs / 2) 0;
|
||||
white-space: nowrap;
|
||||
|
||||
> * {
|
||||
white-space: unset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-content {
|
||||
padding-top: @page-header-content-padding-vertical;
|
||||
}
|
||||
|
||||
&-footer {
|
||||
margin-top: @margin-md;
|
||||
.@{ant-prefix}-tabs {
|
||||
> .@{ant-prefix}-tabs-nav {
|
||||
margin: 0;
|
||||
|
||||
&::before {
|
||||
border: none;
|
||||
}
|
||||
}
|
||||
|
||||
.@{ant-prefix}-tabs-tab {
|
||||
padding-top: @padding-xs;
|
||||
padding-bottom: @padding-xs;
|
||||
font-size: @page-header-tabs-tab-font-size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-compact &-heading {
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
}
|
||||
|
||||
@import './rtl';
|
|
@ -1,6 +1,156 @@
|
|||
import './index.less';
|
||||
import type { CSSObject } from '../../_util/cssinjs';
|
||||
import type { FullToken, GenerateStyle } from '../../theme/internal';
|
||||
import { genComponentStyleHook, mergeToken } from '../../theme/internal';
|
||||
import { resetComponent, textEllipsis } from '../../_style';
|
||||
import { operationUnit } from '../../_style';
|
||||
|
||||
// style dependencies
|
||||
import '../../breadcrumb/style';
|
||||
import '../../avatar/style';
|
||||
import '../../space/style';
|
||||
interface PageHeaderToken extends FullToken<'PageHeader'> {
|
||||
pageHeaderPadding: number;
|
||||
pageHeaderPaddingVertical: number;
|
||||
pageHeaderPaddingBreadcrumb: number;
|
||||
pageHeaderGhostBg: string;
|
||||
pageHeaderBackColor: string;
|
||||
pageHeaderHeadingTitle: number;
|
||||
pageHeaderHeadingSubTitle: number;
|
||||
pageHeaderContentPaddingVertical: number;
|
||||
pageHeaderTabFontSize: number;
|
||||
}
|
||||
|
||||
const genPageHeaderStyle: GenerateStyle<PageHeaderToken, CSSObject> = token => {
|
||||
const { componentCls, antCls } = token;
|
||||
|
||||
return {
|
||||
[componentCls]: {
|
||||
...resetComponent(token),
|
||||
position: 'relative',
|
||||
padding: `${token.pageHeaderPaddingVertical}px ${token.pageHeaderPadding}px`,
|
||||
backgroundColor: token.colorBgLayout,
|
||||
|
||||
[`${componentCls}-ghost`]: {
|
||||
backgroundColor: token.pageHeaderGhostBg,
|
||||
},
|
||||
|
||||
[`&.has-footer`]: {
|
||||
paddingBottom: 0,
|
||||
},
|
||||
|
||||
[`${componentCls}-back`]: {
|
||||
marginRight: token.marginMD,
|
||||
fontZize: token.fontSizeLG,
|
||||
lineHeight: 1,
|
||||
|
||||
[`&-button`]: {
|
||||
...operationUnit(token),
|
||||
color: token.pageHeaderBackColor,
|
||||
cursor: 'pointer',
|
||||
},
|
||||
},
|
||||
|
||||
[`${antCls}-divider-vertical`]: {
|
||||
height: '14px',
|
||||
margin: `0 ${token.marginSM}`,
|
||||
verticalAlign: 'middle',
|
||||
},
|
||||
|
||||
[`${antCls}-breadcrumb + &-heading`]: {
|
||||
marginTop: token.marginXS,
|
||||
},
|
||||
|
||||
[`${componentCls}-heading`]: {
|
||||
display: 'flex',
|
||||
justifyContent: 'space-between',
|
||||
|
||||
[`&-left`]: {
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
margin: `${token.marginXS / 2}px 0`,
|
||||
overflow: 'hidden',
|
||||
},
|
||||
|
||||
[`&-title`]: {
|
||||
marginRight: token.marginSM,
|
||||
marginBottom: 0,
|
||||
color: token.colorTextHeading,
|
||||
fontWeight: 600,
|
||||
fontSize: token.pageHeaderHeadingTitle,
|
||||
lineHeight: `${token.controlHeight}px`,
|
||||
...textEllipsis,
|
||||
},
|
||||
|
||||
[`${antCls}-avatar`]: {
|
||||
marginRight: token.marginSM,
|
||||
},
|
||||
|
||||
[`&-sub-title`]: {
|
||||
marginRight: token.marginSM,
|
||||
color: token.colorTextDescription,
|
||||
fontSize: token.pageHeaderHeadingSubTitle,
|
||||
lineHeight: token.lineHeight,
|
||||
...textEllipsis,
|
||||
},
|
||||
|
||||
[`&-extra`]: {
|
||||
margin: `${token.marginXS / 2}px 0`,
|
||||
whiteSpace: 'nowrap',
|
||||
|
||||
[`> *`]: {
|
||||
marginLeft: token.marginSM,
|
||||
whiteSpace: 'unset',
|
||||
},
|
||||
|
||||
[`> *:first-child`]: {
|
||||
marginLeft: 0,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-content`]: {
|
||||
paddingTop: token.pageHeaderContentPaddingVertical,
|
||||
},
|
||||
|
||||
[`${componentCls}-footer`]: {
|
||||
marginTop: token.marginMD,
|
||||
[`${antCls}-tabs`]: {
|
||||
[`> ${antCls}-tabs-nav`]: {
|
||||
margin: 0,
|
||||
|
||||
[`&::before`]: {
|
||||
border: 'none',
|
||||
},
|
||||
},
|
||||
[`${antCls}-tabs-tab`]: {
|
||||
paddingTop: token.paddingXS,
|
||||
paddingBottom: token.paddingXS,
|
||||
fontSize: token.pageHeaderTabFontSize,
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
[`${componentCls}-compact ${componentCls}-heading`]: {
|
||||
flexWrap: 'wrap',
|
||||
},
|
||||
|
||||
// rtl style
|
||||
[`&${token.componentCls}-rtl`]: {
|
||||
direction: 'rtl',
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
// ============================== Export ==============================
|
||||
export default genComponentStyleHook('PageHeader', token => {
|
||||
const PageHeaderToken = mergeToken<PageHeaderToken>(token, {
|
||||
pageHeaderPadding: token.paddingLG,
|
||||
pageHeaderPaddingVertical: token.paddingMD,
|
||||
pageHeaderPaddingBreadcrumb: token.paddingSM,
|
||||
pageHeaderContentPaddingVertical: token.paddingSM,
|
||||
pageHeaderBackColor: token.colorTextBase,
|
||||
pageHeaderGhostBg: 'inherit',
|
||||
pageHeaderHeadingTitle: token.fontSizeHeading4,
|
||||
pageHeaderHeadingSubTitle: token.fontSize,
|
||||
pageHeaderTabFontSize: token.fontSizeLG,
|
||||
});
|
||||
|
||||
return [genPageHeaderStyle(PageHeaderToken)];
|
||||
});
|
||||
|
|
|
@ -1,77 +0,0 @@
|
|||
@import '../../style/themes/index';
|
||||
@import '../../style/mixins/index';
|
||||
|
||||
@pageheader-prefix-cls: ~'@{ant-prefix}-page-header';
|
||||
|
||||
.@{pageheader-prefix-cls} {
|
||||
&-rtl {
|
||||
direction: rtl;
|
||||
}
|
||||
|
||||
&-back {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
float: right;
|
||||
margin-right: 0;
|
||||
margin-left: 16px;
|
||||
}
|
||||
}
|
||||
|
||||
&-heading {
|
||||
&-title {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
margin-right: 0;
|
||||
margin-left: @margin-sm;
|
||||
}
|
||||
}
|
||||
|
||||
.@{ant-prefix}-avatar {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
margin-right: 0;
|
||||
margin-left: @margin-sm;
|
||||
}
|
||||
}
|
||||
|
||||
&-sub-title {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
float: right;
|
||||
margin-right: 0;
|
||||
margin-left: 12px;
|
||||
}
|
||||
}
|
||||
|
||||
&-tags {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
|
||||
&-extra {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
float: left;
|
||||
}
|
||||
|
||||
> * {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
margin-right: @margin-sm;
|
||||
margin-left: 0;
|
||||
}
|
||||
}
|
||||
|
||||
> *:first-child {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
margin-right: 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&-footer {
|
||||
.@{ant-prefix}-tabs-bar {
|
||||
.@{ant-prefix}-tabs-nav {
|
||||
.@{pageheader-prefix-cls}-rtl & {
|
||||
float: right;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -56,7 +56,7 @@ import './empty/style';
|
|||
import './statistic/style';
|
||||
import './result/style';
|
||||
// import './descriptions/style';
|
||||
import './page-header/style';
|
||||
// import './page-header/style';
|
||||
import './form/style';
|
||||
import './space/style';
|
||||
import './image/style';
|
||||
|
|
|
@ -81,6 +81,7 @@ export interface ComponentTokenMap {
|
|||
// List?: ListComponentToken;
|
||||
// Mentions?: MentionsComponentToken;
|
||||
Notification?: NotificationComponentToken;
|
||||
PageHeader?: {};
|
||||
Pagination?: {};
|
||||
Popover?: PopoverComponentToken;
|
||||
Popconfirm?: PopconfirmComponentToken;
|
||||
|
|
Loading…
Reference in New Issue