diff --git a/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap b/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap index eeef2ff6f6f0..a15962b36264 100644 --- a/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap +++ b/components/layout/__tests__/__snapshots__/demo-extend.test.ts.snap @@ -159,6 +159,965 @@ exports[`renders components/layout/demo/basic.tsx extend context correctly 1`] = exports[`renders components/layout/demo/basic.tsx extend context correctly 2`] = `[]`; +exports[`renders components/layout/demo/component-token.tsx extend context correctly 1`] = ` +
+
+
+
+ +
+ +
+ Content +
+
+
+
+`; + +exports[`renders components/layout/demo/component-token.tsx extend context correctly 2`] = ` +[ + "Warning: [antd: Breadcrumb] \`Breadcrumb.Item and Breadcrumb.Separator\` is deprecated. Please use \`items\` instead.", +] +`; + exports[`renders components/layout/demo/custom-trigger.tsx extend context correctly 1`] = `
`; +exports[`renders components/layout/demo/component-token.tsx correctly 1`] = ` +
+
+
+
+ +
+ +
+ Content +
+
+
+
+`; + exports[`renders components/layout/demo/custom-trigger.tsx correctly 1`] = `
{ + const key = String(index + 1); + + return { + key: `sub${key}`, + icon: React.createElement(icon), + label: `subnav ${key}`, + + children: new Array(4).fill(null).map((_, j) => { + const subKey = index * 4 + j + 1; + return { + key: subKey, + label: `option${subKey}`, + }; + }), + }; + }, +); + +const App: React.FC = () => { + const { + token: { colorBgContainer }, + } = theme.useToken(); + + return ( + + +
+
+
Ant Design
+
+ + + + + + + Home + List + App + + + Content + + + + + + ); +}; + +export default App; diff --git a/components/layout/index.en-US.md b/components/layout/index.en-US.md index ea141269a296..3c15fe6cdbe6 100644 --- a/components/layout/index.en-US.md +++ b/components/layout/index.en-US.md @@ -69,6 +69,7 @@ Style of a navigation should conform to its level. Fixed Header Fixed Sider Custom trigger debug +Component Token ## API diff --git a/components/layout/index.zh-CN.md b/components/layout/index.zh-CN.md index 7d7527bd6be0..3e4c8064f91c 100644 --- a/components/layout/index.zh-CN.md +++ b/components/layout/index.zh-CN.md @@ -70,6 +70,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*HdS6Q5vUCDcAAA 固定头部 固定侧边栏 自定义触发器 Debug +组件 Token ## API diff --git a/components/layout/style/index.ts b/components/layout/style/index.ts index 8aee8327038c..7905a4be3d04 100644 --- a/components/layout/style/index.ts +++ b/components/layout/style/index.ts @@ -1,43 +1,123 @@ import type { CSSObject } from '@ant-design/cssinjs'; +import type { CSSProperties } from 'react'; import type { FullToken, GenerateStyle } from '../../theme/internal'; -import { genComponentStyleHook, mergeToken } from '../../theme/internal'; +import { genComponentStyleHook } from '../../theme/internal'; import genLayoutLightStyle from './light'; export interface ComponentToken { + /** @deprecated Use headerBg instead */ colorBgHeader: string; + /** @deprecated Use bodyBg instead */ colorBgBody: string; + /** @deprecated Use triggerBg instead */ colorBgTrigger: string; -} -export interface LayoutToken extends FullToken<'Layout'> { - // Layout - layoutHeaderHeight: number; - layoutHeaderPaddingInline: number; - layoutHeaderColor: string; - layoutFooterPadding: string; - layoutTriggerHeight: number; - layoutZeroTriggerSize: number; + /** + * @desc 主体部分背景色 + * @descEN Background Color of body + */ + bodyBg: string; + /** + * @desc 顶部背景色 + * @descEN Background Color of header + */ + headerBg: string; + /** + * @desc 顶部高度 + * @descEN Height of header + */ + headerHeight: number; + /** + * @desc 顶部内边距 + * @descEN Padding of header + */ + headerPadding: CSSProperties['padding']; + /** + * @desc 顶部文字颜色 + * @descEN Text color of header + */ + headerColor: string; + /** + * @desc 页脚内边距 + * @descEN Padding of footer + */ + footerPadding: CSSProperties['padding']; + /** + * @desc 页脚背景色 + * @descEN Background Color of footer + */ + footerBg: string; + /** + * @desc 侧边栏背景色 + * @descEN Background Color of sider + */ + siderBg: string; + /** + * @desc 侧边栏开关高度 + * @descEN Height of sider trigger + */ + triggerHeight: number; + /** + * @desc 侧边栏开关背景色 + * @descEN Background Color of sider trigger + */ + triggerBg: string; + /** + * @desc 侧边栏开关颜色 + * @descEN Color of sider trigger + */ + triggerColor: string; + /** + * @desc collapse 为 0 时侧边栏开关宽度 + * @descEN Width of sider trigger when collapse is 0 + */ + zeroTriggerWidth: number; + /** + * @desc collapse 为 0 时侧边栏开关高度 + * @descEN Height of sider trigger when collapse is 0 + */ + zeroTriggerHeight: number; + /** + * @desc 亮色主题侧边栏背景色 + * @descEN Background Color of light theme sider + */ + lightSiderBg: string; + /** + * @desc 亮色主题侧边栏开关背景色 + * @descEN Background Color of light theme sider trigger + */ + lightTriggerBg: string; + /** + * @desc 亮色主题侧边栏开关颜色 + * @descEN Color of light theme sider trigger + */ + lightTriggerColor: string; } +export interface LayoutToken extends FullToken<'Layout'> {} + const genLayoutStyle: GenerateStyle = (token) => { const { antCls, // .ant componentCls, // .ant-layout colorText, - colorTextLightSolid, - colorBgHeader, - colorBgBody, - colorBgTrigger, - layoutHeaderHeight, - layoutHeaderPaddingInline, - layoutHeaderColor, - layoutFooterPadding, - layoutTriggerHeight, - layoutZeroTriggerSize, + triggerColor, + footerBg, + triggerBg, + headerHeight, + headerPadding, + headerColor, + footerPadding, + triggerHeight, + zeroTriggerHeight, + zeroTriggerWidth, motionDurationMid, motionDurationSlow, fontSize, borderRadius, + bodyBg, + headerBg, + siderBg, } = token; return { @@ -48,7 +128,7 @@ const genLayoutStyle: GenerateStyle = (token) => { /* fix firefox can't set height smaller than content on flex item */ minHeight: 0, - background: colorBgBody, + background: bodyBg, '&, *': { boxSizing: 'border-box', @@ -71,7 +151,7 @@ const genLayoutStyle: GenerateStyle = (token) => { // fix firefox can't set width smaller than content on flex item minWidth: 0, - background: colorBgHeader, + background: siderBg, transition: `all ${motionDurationMid}, background 0s`, '&-children': { @@ -88,7 +168,7 @@ const genLayoutStyle: GenerateStyle = (token) => { }, '&-has-trigger': { - paddingBottom: layoutTriggerHeight, + paddingBottom: triggerHeight, }, '&-right': { @@ -99,11 +179,11 @@ const genLayoutStyle: GenerateStyle = (token) => { position: 'fixed', bottom: 0, zIndex: 1, - height: layoutTriggerHeight, - color: colorTextLightSolid, - lineHeight: `${layoutTriggerHeight}px`, + height: triggerHeight, + color: triggerColor, + lineHeight: `${triggerHeight}px`, textAlign: 'center', - background: colorBgTrigger, + background: triggerBg, cursor: 'pointer', transition: `all ${motionDurationMid}`, }, @@ -115,17 +195,17 @@ const genLayoutStyle: GenerateStyle = (token) => { '&-trigger': { position: 'absolute', - top: layoutHeaderHeight, - insetInlineEnd: -layoutZeroTriggerSize, + top: headerHeight, + insetInlineEnd: -zeroTriggerWidth, zIndex: 1, - width: layoutZeroTriggerSize, - height: layoutZeroTriggerSize, - color: colorTextLightSolid, + width: zeroTriggerWidth, + height: zeroTriggerHeight, + color: triggerColor, fontSize: token.fontSizeXL, display: 'flex', alignItems: 'center', justifyContent: 'center', - background: colorBgHeader, + background: siderBg, borderStartStartRadius: 0, borderStartEndRadius: borderRadius, borderEndEndRadius: borderRadius, @@ -143,12 +223,11 @@ const genLayoutStyle: GenerateStyle = (token) => { }, '&:hover::after': { - // FIXME: Hardcode, but seems no need to create a token for this background: `rgba(255, 255, 255, 0.2)`, }, '&-right': { - insetInlineStart: -layoutZeroTriggerSize, + insetInlineStart: -zeroTriggerWidth, borderStartStartRadius: borderRadius, borderStartEndRadius: 0, borderEndEndRadius: 0, @@ -167,11 +246,11 @@ const genLayoutStyle: GenerateStyle = (token) => { // ==================== Header ==================== [`${componentCls}-header`]: { - height: layoutHeaderHeight, - paddingInline: layoutHeaderPaddingInline, - color: layoutHeaderColor, - lineHeight: `${layoutHeaderHeight}px`, - background: colorBgHeader, + height: headerHeight, + padding: headerPadding, + color: headerColor, + lineHeight: `${headerHeight}px`, + background: headerBg, // Other components/menu/style/index.less line:686 // Integration with header element so menu items have the same height @@ -182,10 +261,10 @@ const genLayoutStyle: GenerateStyle = (token) => { // ==================== Footer ==================== [`${componentCls}-footer`]: { - padding: layoutFooterPadding, + padding: footerPadding, color: colorText, fontSize, - background: colorBgBody, + background: footerBg, }, // =================== Content ==================== @@ -201,29 +280,50 @@ const genLayoutStyle: GenerateStyle = (token) => { // ============================== Export ============================== export default genComponentStyleHook( 'Layout', + (token) => [genLayoutStyle(token)], (token) => { - const { colorText, controlHeightSM, controlHeight, controlHeightLG, marginXXS } = token; - const layoutHeaderPaddingInline = controlHeightLG * 1.25; - - const layoutToken = mergeToken(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; + const { + colorBgLayout, + controlHeight, + controlHeightLG, + colorText, + controlHeightSM, + marginXXS, + colorTextLightSolid, + colorBgContainer, + } = token; + + const paddingInline = controlHeightLG * 1.25; return { + // Deprecated colorBgHeader: '#001529', colorBgBody: colorBgLayout, colorBgTrigger: '#002140', + + bodyBg: colorBgLayout, + headerBg: '#001529', + headerHeight: controlHeight * 2, + headerPadding: `0 ${paddingInline}px`, + headerColor: colorText, + footerPadding: `${controlHeightSM}px ${paddingInline}px`, + footerBg: colorBgLayout, + siderBg: '#001529', + triggerHeight: controlHeightLG + marginXXS * 2, + triggerBg: '#002140', + triggerColor: colorTextLightSolid, + zeroTriggerWidth: controlHeightLG, + zeroTriggerHeight: controlHeightLG, + lightSiderBg: colorBgContainer, + lightTriggerBg: colorBgContainer, + lightTriggerColor: colorText, }; }, + { + deprecatedTokens: [ + ['colorBgBody', 'bodyBg'], + ['colorBgHeader', 'headerBg'], + ['colorBgTrigger', 'triggerBg'], + ], + }, ); diff --git a/components/layout/style/light.ts b/components/layout/style/light.ts index 8213f1e3f452..da2aa7435fd2 100644 --- a/components/layout/style/light.ts +++ b/components/layout/style/light.ts @@ -3,21 +3,21 @@ import type { LayoutToken } from '.'; import type { GenerateStyle } from '../../theme/internal'; const genLayoutLightStyle: GenerateStyle = (token) => { - const { componentCls, colorBgContainer, colorBgBody, colorText } = token; + const { componentCls, bodyBg, lightSiderBg, lightTriggerBg, lightTriggerColor } = token; return { [`${componentCls}-sider-light`]: { - background: colorBgContainer, + background: lightSiderBg, [`${componentCls}-sider-trigger`]: { - color: colorText, - background: colorBgContainer, + color: lightTriggerColor, + background: lightTriggerBg, }, [`${componentCls}-sider-zero-width-trigger`]: { - color: colorText, - background: colorBgContainer, - border: `1px solid ${colorBgBody}`, // Safe to modify to any other color + color: lightTriggerColor, + background: lightTriggerBg, + border: `1px solid ${bodyBg}`, // Safe to modify to any other color borderInlineStart: 0, }, }, diff --git a/docs/react/migrate-less-variables.en-US.md b/docs/react/migrate-less-variables.en-US.md index 26b9d0776f41..f64cce6e1da4 100644 --- a/docs/react/migrate-less-variables.en-US.md +++ b/docs/react/migrate-less-variables.en-US.md @@ -276,7 +276,27 @@ export default App; - +### Layout + + +| Less variables | Component Token | Note | +| --- | --- | --- | +| `@layout-body-background` | `bodyBg` | - | +| `@layout-header-background` | `headerBg` | - | +| `@layout-header-height` | `headerHeight` | - | +| `@layout-header-padding` | `headerPadding` | - | +| `@layout-header-color` | `headerColor` | - | +| `@layout-footer-padding` | `footerPadding` | - | +| `@layout-footer-background` | `footerBg` | - | +| `@layout-sider-background` | `siderBg` | - | +| `@layout-trigger-height` | `triggerHeight` | - | +| `@layout-trigger-background` | `triggerBg` | - | +| `@layout-trigger-color` | `triggerColor` | - | +| `@layout-zero-trigger-width` | `zeroTriggerWidth` | - | +| `@layout-zero-trigger-height` | `zeroTriggerHeight` | - | +| `@layout-sider-background-light` | `lightSiderBg` | - | +| `@layout-trigger-background-light` | `lightTriggerBg` | - | +| `@layout-trigger-color-light` | `lightTriggerColor` | - | ### List diff --git a/docs/react/migrate-less-variables.zh-CN.md b/docs/react/migrate-less-variables.zh-CN.md index 05b06b30e4d5..b221488d7e0e 100644 --- a/docs/react/migrate-less-variables.zh-CN.md +++ b/docs/react/migrate-less-variables.zh-CN.md @@ -273,7 +273,27 @@ export default App; - +### Layout 布局 + + +| less 变量 | Component Token | 备注 | +| --- | --- | --- | +| `@layout-body-background` | `bodyBg` | - | +| `@layout-header-background` | `headerBg` | - | +| `@layout-header-height` | `headerHeight` | - | +| `@layout-header-padding` | `headerPadding` | - | +| `@layout-header-color` | `headerColor` | - | +| `@layout-footer-padding` | `footerPadding` | - | +| `@layout-footer-background` | `footerBg` | - | +| `@layout-sider-background` | `siderBg` | - | +| `@layout-trigger-height` | `triggerHeight` | - | +| `@layout-trigger-background` | `triggerBg` | - | +| `@layout-trigger-color` | `triggerColor` | - | +| `@layout-zero-trigger-width` | `zeroTriggerWidth` | - | +| `@layout-zero-trigger-height` | `zeroTriggerHeight` | - | +| `@layout-sider-background-light` | `lightSiderBg` | - | +| `@layout-trigger-background-light` | `lightTriggerBg` | - | +| `@layout-trigger-color-light` | `lightTriggerColor` | - | ### List 列表