diff --git a/components/page-header/index.tsx b/components/page-header/index.tsx index 24bb676e20..9075e447a5 100644 --- a/components/page-header/index.tsx +++ b/components/page-header/index.tsx @@ -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 { @@ -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, { - 'has-breadcrumb': hasBreadcrumb, - 'has-footer': hasFooter, - [`${prefixCls.value}-ghost`]: ghost.value, - [`${prefixCls.value}-rtl`]: direction.value === 'rtl', - [`${prefixCls.value}-compact`]: compact.value, - }); - return ( + 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, + }, + attrs.class, + hashId.value, + ); + return wrapSSR( -
+
{renderBreadcrumb()} {renderTitle()} {children.length ? renderChildren(children) : null} {renderFooter()}
- + , ); }; }, diff --git a/components/page-header/style/index.less b/components/page-header/style/index.less deleted file mode 100644 index 074145756c..0000000000 --- a/components/page-header/style/index.less +++ /dev/null @@ -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'; diff --git a/components/page-header/style/index.tsx b/components/page-header/style/index.tsx index cd4e5ba32d..4181694b71 100644 --- a/components/page-header/style/index.tsx +++ b/components/page-header/style/index.tsx @@ -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 = 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(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)]; +}); diff --git a/components/page-header/style/rtl.less b/components/page-header/style/rtl.less deleted file mode 100644 index 33e5c0d86b..0000000000 --- a/components/page-header/style/rtl.less +++ /dev/null @@ -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; - } - } - } - } -} diff --git a/components/style.ts b/components/style.ts index 0ab8e11ce1..2e583f5fc5 100644 --- a/components/style.ts +++ b/components/style.ts @@ -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'; diff --git a/components/theme/interface/components.ts b/components/theme/interface/components.ts index cc63641b75..d50cb83f7d 100644 --- a/components/theme/interface/components.ts +++ b/components/theme/interface/components.ts @@ -80,6 +80,7 @@ export interface ComponentTokenMap { // List?: ListComponentToken; // Mentions?: MentionsComponentToken; Notification?: NotificationComponentToken; + PageHeader?: {}; Pagination?: {}; Popover?: PopoverComponentToken; Popconfirm?: PopconfirmComponentToken;