From 751edfc336abac25796484fe8a155550903ab23f Mon Sep 17 00:00:00 2001 From: MadCcc Date: Tue, 22 Jul 2025 10:20:29 +0800 Subject: [PATCH] feat: zeroRuntime (#54334) * feat: zeroRuntime * feat: generate full style * feat: add antd.css into global css * chore: revert site change * docs: add docs * chore: update scripts * chore: add test --- .antd-tools.config.js | 4 + .gitignore | 3 + components/badge/demo/_semantic_ribbon.tsx | 3 +- components/calendar/demo/_semantic.tsx | 3 +- components/collapse/demo/_semantic.tsx | 6 +- components/config-provider/context.ts | 7 ++ components/date-picker/demo/_semantic.tsx | 21 ++-- components/descriptions/demo/_semantic.tsx | 15 ++- components/drawer/demo/_semantic.tsx | 15 ++- .../float-button/demo/_semantic_group.tsx | 15 ++- components/image/demo/_semantic.tsx | 18 ++- components/input-number/demo/_semantic.tsx | 3 +- components/input/demo/_semantic_textarea.tsx | 6 +- components/mentions/demo/_semantic.tsx | 3 +- components/qr-code/demo/_semantic.tsx | 3 +- components/segmented/demo/_semantic.tsx | 3 +- components/slider/demo/_semantic.tsx | 12 +- components/spin/demo/_semantic.tsx | 3 +- components/splitter/demo/_semantic.tsx | 3 +- components/statistic/demo/_semantic.tsx | 9 +- components/theme/context.ts | 1 + components/theme/useToken.ts | 4 +- components/theme/util/genStyleUtils.ts | 4 +- components/transfer/demo/_semantic.tsx | 15 ++- components/tree-select/demo/_semantic.tsx | 12 +- docs/react/customize-theme.en-US.md | 3 +- docs/react/customize-theme.zh-CN.md | 3 +- package.json | 7 +- scripts/build-style.tsx | 113 ++++++++++++++++++ scripts/generate-cssinjs.ts | 2 +- scripts/tsconfig.json | 1 + tests/dekko/dist.test.ts | 1 + 32 files changed, 256 insertions(+), 65 deletions(-) create mode 100644 scripts/build-style.tsx diff --git a/.antd-tools.config.js b/.antd-tools.config.js index 36b9b75986..d4efebe6c0 100644 --- a/.antd-tools.config.js +++ b/.antd-tools.config.js @@ -2,18 +2,21 @@ const fs = require('fs'); const path = require('path'); const restCssPath = path.join(process.cwd(), 'components', 'style', 'reset.css'); +const antdCssPath = path.join(process.cwd(), 'components', 'style', 'antd.css'); const tokenStatisticPath = path.join(process.cwd(), 'components', 'version', 'token.json'); const tokenMetaPath = path.join(process.cwd(), 'components', 'version', 'token-meta.json'); function finalizeCompile() { if (fs.existsSync(path.join(__dirname, './es'))) { fs.copyFileSync(restCssPath, path.join(process.cwd(), 'es', 'style', 'reset.css')); + fs.copyFileSync(antdCssPath, path.join(process.cwd(), 'es', 'style', 'antd.css')); fs.copyFileSync(tokenStatisticPath, path.join(process.cwd(), 'es', 'version', 'token.json')); fs.copyFileSync(tokenMetaPath, path.join(process.cwd(), 'es', 'version', 'token-meta.json')); } if (fs.existsSync(path.join(__dirname, './lib'))) { fs.copyFileSync(restCssPath, path.join(process.cwd(), 'lib', 'style', 'reset.css')); + fs.copyFileSync(antdCssPath, path.join(process.cwd(), 'lib', 'style', 'antd.css')); fs.copyFileSync(tokenStatisticPath, path.join(process.cwd(), 'lib', 'version', 'token.json')); fs.copyFileSync(tokenMetaPath, path.join(process.cwd(), 'lib', 'version', 'token-meta.json')); } @@ -22,6 +25,7 @@ function finalizeCompile() { function finalizeDist() { if (fs.existsSync(path.join(__dirname, './dist'))) { fs.copyFileSync(restCssPath, path.join(process.cwd(), 'dist', 'reset.css')); + fs.copyFileSync(antdCssPath, path.join(process.cwd(), 'dist', 'antd.css')); } } diff --git a/.gitignore b/.gitignore index 2dd7290fd2..8dfaf62256 100644 --- a/.gitignore +++ b/.gitignore @@ -77,3 +77,6 @@ __image_snapshots__/ .env examples/ + +# generated css +components/style/antd.css diff --git a/components/badge/demo/_semantic_ribbon.tsx b/components/badge/demo/_semantic_ribbon.tsx index ce2e45b9de..020086b5e9 100644 --- a/components/badge/demo/_semantic_ribbon.tsx +++ b/components/badge/demo/_semantic_ribbon.tsx @@ -13,7 +13,8 @@ const locales = { }, en: { root: 'Root element, set relative positioning and wrapper container styles', - indicator: 'Indicator element, set absolute positioning, padding, background color, border radius and ribbon styles', + indicator: + 'Indicator element, set absolute positioning, padding, background color, border radius and ribbon styles', content: 'Content element, set text color and ribbon content display styles', }, }; diff --git a/components/calendar/demo/_semantic.tsx b/components/calendar/demo/_semantic.tsx index b7a0135171..cdbaec6a12 100644 --- a/components/calendar/demo/_semantic.tsx +++ b/components/calendar/demo/_semantic.tsx @@ -14,7 +14,8 @@ const locales = { }, en: { root: 'Root element containing background, border, border-radius and overall layout structure of the calendar component', - header: 'Header element with layout and style control for year selector, month selector and mode switcher', + header: + 'Header element with layout and style control for year selector, month selector and mode switcher', body: 'Body element with padding and layout control for the calendar table that contains the calendar grid', content: 'Content element with width, height and table styling control for the calendar table', item: 'Item element with background, border, hover state, selected state and other interactive styles for calendar cells', diff --git a/components/collapse/demo/_semantic.tsx b/components/collapse/demo/_semantic.tsx index 3bbfe0ca82..82889f4794 100644 --- a/components/collapse/demo/_semantic.tsx +++ b/components/collapse/demo/_semantic.tsx @@ -16,8 +16,10 @@ const locales = { }, en: { root: 'Root element with border, border-radius, background color and container styles that control the overall layout and appearance of collapse panels', - header: 'Header element with flex layout, padding, color, line-height, cursor style, transition animations and other interactive styles for panel headers', - title: 'Title element with flex auto layout and margin styles for title text layout and typography', + header: + 'Header element with flex layout, padding, color, line-height, cursor style, transition animations and other interactive styles for panel headers', + title: + 'Title element with flex auto layout and margin styles for title text layout and typography', body: 'Body element with padding, color, background color and other styles for panel content area display', icon: 'Icon element with font size, transition animations, rotation transforms and other styles and animations for expand/collapse arrows', }, diff --git a/components/config-provider/context.ts b/components/config-provider/context.ts index 6b5e5e8e39..c5043f82e9 100644 --- a/components/config-provider/context.ts +++ b/components/config-provider/context.ts @@ -142,6 +142,13 @@ export interface ThemeConfig { */ key?: string; }; + /** + * @descCN 是否关闭运行时样式生成 + * @descEN Disable runtime style generation. + * @default false + * @since 6.0.0 + */ + zeroRuntime?: boolean; } export interface ComponentStyleConfig { diff --git a/components/date-picker/demo/_semantic.tsx b/components/date-picker/demo/_semantic.tsx index 795117b67e..86ea302f3c 100644 --- a/components/date-picker/demo/_semantic.tsx +++ b/components/date-picker/demo/_semantic.tsx @@ -15,20 +15,27 @@ const locales = { 'popup.header': '弹出框头部元素,包含导航按钮、月份年份选择器等头部控制区域的布局和样式', 'popup.body': '弹出框主体元素,包含日期面板表格的容器布局和样式', 'popup.content': '弹出框内容元素,包含日期表格的宽度、边框、单元格等内容展示样式', - 'popup.item': '弹出框单项元素,包含日期单元格的尺寸、背景色、边框圆角、悬停态、选中态等交互样式', + 'popup.item': + '弹出框单项元素,包含日期单元格的尺寸、背景色、边框圆角、悬停态、选中态等交互样式', 'popup.footer': '弹出框底部元素,包含确认取消按钮、快捷选择等底部操作区域的布局样式', }, en: { root: 'Root element with relative positioning, inline-flex layout, padding, border-radius, transition animations and other basic styles for date picker container', prefix: 'Prefix element with flex layout and margin styles for prefix content layout', - input: 'Input element with relative positioning, width, color, font, line-height, transition animations and other core interactive styles for input field', - suffix: 'Suffix element with flex layout, color, line-height, pointer events, transition animations and other styles for suffix content', + input: + 'Input element with relative positioning, width, color, font, line-height, transition animations and other core interactive styles for input field', + suffix: + 'Suffix element with flex layout, color, line-height, pointer events, transition animations and other styles for suffix content', popup: 'Popup element', - 'popup.header': 'Popup header element with navigation buttons, month/year selectors and other header control area layout and styles', + 'popup.header': + 'Popup header element with navigation buttons, month/year selectors and other header control area layout and styles', 'popup.body': 'Popup body element with container layout and styles for date panel table', - 'popup.content': 'Popup content element with width, border, cell and other content display styles for date table', - 'popup.item': 'Popup item element with size, background, border-radius, hover state, selected state and other interactive styles for date cells', - 'popup.footer': 'Popup footer element with layout styles for bottom operation area including confirm/cancel buttons and shortcuts', + 'popup.content': + 'Popup content element with width, border, cell and other content display styles for date table', + 'popup.item': + 'Popup item element with size, background, border-radius, hover state, selected state and other interactive styles for date cells', + 'popup.footer': + 'Popup footer element with layout styles for bottom operation area including confirm/cancel buttons and shortcuts', }, }; diff --git a/components/descriptions/demo/_semantic.tsx b/components/descriptions/demo/_semantic.tsx index 688690cca1..3c1d508f9f 100644 --- a/components/descriptions/demo/_semantic.tsx +++ b/components/descriptions/demo/_semantic.tsx @@ -16,11 +16,16 @@ const locales = { }, en: { root: 'Root element with basic styles, reset styles, border styles, layout direction and other overall styles for description list container', - header: 'Header element with flex layout, alignment, bottom margin and other layout and style controls for header area', - title: 'Title element with text ellipsis, flex ratio, color, font weight, font size, line height and other title text styles', - extra: 'Extra content element with left margin, color, font size and other styles for additional operation area', - label: 'Label element with color, font weight, font size, line height, text align, colon styles and other label text styles', - content: 'Content element with table cell layout, color, font size, line height, word break and other content display styles', + header: + 'Header element with flex layout, alignment, bottom margin and other layout and style controls for header area', + title: + 'Title element with text ellipsis, flex ratio, color, font weight, font size, line height and other title text styles', + extra: + 'Extra content element with left margin, color, font size and other styles for additional operation area', + label: + 'Label element with color, font weight, font size, line height, text align, colon styles and other label text styles', + content: + 'Content element with table cell layout, color, font size, line height, word break and other content display styles', }, }; diff --git a/components/drawer/demo/_semantic.tsx b/components/drawer/demo/_semantic.tsx index c554fe729e..e0ec35d0a3 100644 --- a/components/drawer/demo/_semantic.tsx +++ b/components/drawer/demo/_semantic.tsx @@ -18,12 +18,17 @@ const locales = { en: { root: 'Root element with fixed positioning, z-index control, pointer events, color and other basic styles and layout control for drawer container', mask: 'Mask element with absolute positioning, z-index, background color, pointer events and other mask layer styles and interaction controls', - section: 'Drawer container element with flex layout, width/height, overflow control, background color, pointer events and other drawer body styles', - header: 'Header element with flex layout, alignment, padding, font size, line height, bottom border and other header area styles', + section: + 'Drawer container element with flex layout, width/height, overflow control, background color, pointer events and other drawer body styles', + header: + 'Header element with flex layout, alignment, padding, font size, line height, bottom border and other header area styles', body: 'Body element with flex ratio, minimum size, padding, overflow scroll and other content area display and layout styles', - footer: 'Footer element with flex shrink, padding, top border and other bottom operation area styles', - title: 'Title element with flex ratio, margin, font weight, font size, line height and other title text styles', - extra: 'Extra element with flex fixed layout and other additional operation content style controls', + footer: + 'Footer element with flex shrink, padding, top border and other bottom operation area styles', + title: + 'Title element with flex ratio, margin, font weight, font size, line height and other title text styles', + extra: + 'Extra element with flex fixed layout and other additional operation content style controls', }, }; diff --git a/components/float-button/demo/_semantic_group.tsx b/components/float-button/demo/_semantic_group.tsx index b859b46ba4..7aa2cb5ccf 100644 --- a/components/float-button/demo/_semantic_group.tsx +++ b/components/float-button/demo/_semantic_group.tsx @@ -20,11 +20,16 @@ const locales = { root: 'Root element with float button group container styles, fixed positioning, z-index, padding, gap, direction mode and other combined layout styles', list: 'List element with button group list flex layout, border radius, shadow, animation transition, vertical alignment and other list container styles', item: 'Item element with individual float button styles, size, shape, type, state, icon content and other button base styles', - itemIcon: 'Item icon element with float button icon size, color, alignment and other icon display styles', - itemContent: 'Item content element with float button text content, badge, description and other content area styles', - trigger: 'Trigger element with menu mode trigger button styles, shape, icon, hover state, expand/collapse state and other interaction styles', - triggerIcon: 'Trigger icon element with trigger button icon styles, rotation animation, toggle state and other icon interaction styles', - triggerContent: 'Trigger content element with trigger button content area text, identifier, state indicator and other content styles', + itemIcon: + 'Item icon element with float button icon size, color, alignment and other icon display styles', + itemContent: + 'Item content element with float button text content, badge, description and other content area styles', + trigger: + 'Trigger element with menu mode trigger button styles, shape, icon, hover state, expand/collapse state and other interaction styles', + triggerIcon: + 'Trigger icon element with trigger button icon styles, rotation animation, toggle state and other icon interaction styles', + triggerContent: + 'Trigger content element with trigger button content area text, identifier, state indicator and other content styles', }, }; diff --git a/components/image/demo/_semantic.tsx b/components/image/demo/_semantic.tsx index 7b75e02e90..e54934fa84 100644 --- a/components/image/demo/_semantic.tsx +++ b/components/image/demo/_semantic.tsx @@ -28,12 +28,18 @@ const locales = { en: { root: 'Root element, sets relative positioning and inline-block layout styles', image: 'Image element, sets width, height and vertical alignment styles', - cover: 'Image hover display prompt element, sets absolute positioning, background color, opacity and transition animation styles', - 'popup.root': 'Preview root element, sets fixed positioning, z-index and background mask styles', - 'popup.mask': 'Preview mask element, sets absolute positioning and semi-transparent background styles', - 'popup.body': 'Preview body element, sets flex layout, center alignment and pointer event styles', - 'popup.footer': 'Preview footer element, sets absolute positioning, center layout and bottom operation area styles', - 'popup.actions': 'Preview actions group element, sets flex layout, background color, border radius and action button styles', + cover: + 'Image hover display prompt element, sets absolute positioning, background color, opacity and transition animation styles', + 'popup.root': + 'Preview root element, sets fixed positioning, z-index and background mask styles', + 'popup.mask': + 'Preview mask element, sets absolute positioning and semi-transparent background styles', + 'popup.body': + 'Preview body element, sets flex layout, center alignment and pointer event styles', + 'popup.footer': + 'Preview footer element, sets absolute positioning, center layout and bottom operation area styles', + 'popup.actions': + 'Preview actions group element, sets flex layout, background color, border radius and action button styles', }, }; diff --git a/components/input-number/demo/_semantic.tsx b/components/input-number/demo/_semantic.tsx index 5adaea7c8b..e744b87b90 100644 --- a/components/input-number/demo/_semantic.tsx +++ b/components/input-number/demo/_semantic.tsx @@ -17,7 +17,8 @@ const locales = { input: 'Input element, sets font, line height, text input and interaction styles', prefix: 'Prefix wrapper element, sets flex layout, alignment and right margin styles', suffix: 'Suffix wrapper element, sets flex layout, margin and transition animation styles', - actions: 'Actions element, sets absolute positioning, width, flex layout and number adjustment button styles', + actions: + 'Actions element, sets absolute positioning, width, flex layout and number adjustment button styles', }, }; diff --git a/components/input/demo/_semantic_textarea.tsx b/components/input/demo/_semantic_textarea.tsx index 390414bd2a..d93cc1e628 100644 --- a/components/input/demo/_semantic_textarea.tsx +++ b/components/input/demo/_semantic_textarea.tsx @@ -12,8 +12,10 @@ const locales = { }, en: { root: 'Root element with textarea wrapper styles, border, border radius, transition animation and state control', - textarea: 'Textarea element with font, line height, padding, color, background, border, text input and multi-line text display styles', - count: 'Count element with character count display position, font, color and numeric statistics styles', + textarea: + 'Textarea element with font, line height, padding, color, background, border, text input and multi-line text display styles', + count: + 'Count element with character count display position, font, color and numeric statistics styles', }, }; diff --git a/components/mentions/demo/_semantic.tsx b/components/mentions/demo/_semantic.tsx index 51ec279c1f..f08a32db55 100644 --- a/components/mentions/demo/_semantic.tsx +++ b/components/mentions/demo/_semantic.tsx @@ -14,7 +14,8 @@ const locales = { en: { root: 'Root element, set inline flex layout, relative positioning, padding and border styles', textarea: 'Textarea element, set font, line height, text input and background styles', - popup: 'Popup element, set absolute positioning, z-index, background color, border radius, shadow and dropdown options styles', + popup: + 'Popup element, set absolute positioning, z-index, background color, border radius, shadow and dropdown options styles', }, }; diff --git a/components/qr-code/demo/_semantic.tsx b/components/qr-code/demo/_semantic.tsx index e777b517c3..857e1e15fb 100644 --- a/components/qr-code/demo/_semantic.tsx +++ b/components/qr-code/demo/_semantic.tsx @@ -11,7 +11,8 @@ const locales = { }, en: { root: 'Root element, set flex layout, padding, background color, border, border radius and relative positioning styles', - cover: 'Cover element, set absolute positioning, z-index, background color and loading state overlay styles', + cover: + 'Cover element, set absolute positioning, z-index, background color and loading state overlay styles', }, }; diff --git a/components/segmented/demo/_semantic.tsx b/components/segmented/demo/_semantic.tsx index e4791ee500..942f39b326 100644 --- a/components/segmented/demo/_semantic.tsx +++ b/components/segmented/demo/_semantic.tsx @@ -16,7 +16,8 @@ const locales = { root: 'Root element with inline-block layout, padding, background, border radius, transition and container styles', item: 'Option element with relative positioning, text alignment, cursor style, transition, selected state background and hover styles', icon: 'Icon element with icon size, color and text spacing styles', - label: 'Label content element with min height, line height, padding, text ellipsis and content layout styles', + label: + 'Label content element with min height, line height, padding, text ellipsis and content layout styles', }, }; diff --git a/components/slider/demo/_semantic.tsx b/components/slider/demo/_semantic.tsx index 935f3d1347..41cbc5322f 100644 --- a/components/slider/demo/_semantic.tsx +++ b/components/slider/demo/_semantic.tsx @@ -10,14 +10,18 @@ const locales = { track: '轨道选取条元素,设置绝对定位、背景色、圆角和过渡动画样式', tracks: '多段轨道容器元素,设置绝对定位和过渡动画样式', rail: '背景轨道元素,设置绝对定位、背景色、圆角和过渡动画样式', - handle: '滑块控制点元素,设置绝对定位、尺寸、轮廓线、用户选择、背景色、边框阴影、圆角、光标样式和过渡动画', + handle: + '滑块控制点元素,设置绝对定位、尺寸、轮廓线、用户选择、背景色、边框阴影、圆角、光标样式和过渡动画', }, en: { root: 'Root element with relative positioning, height, margin, padding, cursor style and touch action control', - track: 'Track selection bar element with absolute positioning, background color, border radius and transition animation styles', - tracks: 'Multi-segment track container element with absolute positioning and transition animation styles', + track: + 'Track selection bar element with absolute positioning, background color, border radius and transition animation styles', + tracks: + 'Multi-segment track container element with absolute positioning and transition animation styles', rail: 'Background rail element with absolute positioning, background color, border radius and transition animation styles', - handle: 'Slider handle control element with absolute positioning, size, outline, user selection, background color, border shadow, border radius, cursor style and transition animation', + handle: + 'Slider handle control element with absolute positioning, size, outline, user selection, background color, border shadow, border radius, cursor style and transition animation', }, }; diff --git a/components/spin/demo/_semantic.tsx b/components/spin/demo/_semantic.tsx index c688c2f60f..d3f151e4d1 100644 --- a/components/spin/demo/_semantic.tsx +++ b/components/spin/demo/_semantic.tsx @@ -12,7 +12,8 @@ const locales = { }, en: { root: 'Root element with absolute positioning, display control, color, font size, text alignment, vertical alignment, opacity and transition animation (effective when fullscreen is false)', - indicator: 'Indicator element with width, height, font size, inline-block display, transition animation, transform origin, line height and color', + indicator: + 'Indicator element with width, height, font size, inline-block display, transition animation, transform origin, line height and color', }, }; diff --git a/components/splitter/demo/_semantic.tsx b/components/splitter/demo/_semantic.tsx index 9a119a4968..aeeca4c9ef 100644 --- a/components/splitter/demo/_semantic.tsx +++ b/components/splitter/demo/_semantic.tsx @@ -15,7 +15,8 @@ const locales = { en: { root: 'Root element with flex layout, width and height, alignment and stretch styles', panel: 'Panel element with flex basis, grow ratio and panel container styles', - dragger: 'Drag control element with absolute positioning, user selection, z-index, center alignment, background color, hover and active states styles', + dragger: + 'Drag control element with absolute positioning, user selection, z-index, center alignment, background color, hover and active states styles', }, }; diff --git a/components/statistic/demo/_semantic.tsx b/components/statistic/demo/_semantic.tsx index 46e095b2c9..148c7a23b4 100644 --- a/components/statistic/demo/_semantic.tsx +++ b/components/statistic/demo/_semantic.tsx @@ -19,9 +19,12 @@ const locales = { root: 'Root element with reset styles and overall container styles for statistic component', header: 'Header element with bottom padding and title area layout styles', title: 'Title element with text color, font size and other title text display styles', - content: 'Content element with text color, font size, font family and other numeric content display styles', - prefix: 'Prefix element with inline-block display, right margin and other prefix content layout styles', - suffix: 'Suffix element with inline-block display, left margin and other suffix content layout styles', + content: + 'Content element with text color, font size, font family and other numeric content display styles', + prefix: + 'Prefix element with inline-block display, right margin and other prefix content layout styles', + suffix: + 'Suffix element with inline-block display, left margin and other suffix content layout styles', }, }; diff --git a/components/theme/context.ts b/components/theme/context.ts index 3d735a033a..9a7a242477 100644 --- a/components/theme/context.ts +++ b/components/theme/context.ts @@ -31,6 +31,7 @@ export interface DesignTokenProviderProps { prefix?: string; key?: string; }; + zeroRuntime?: boolean; } export const DesignTokenContext = React.createContext(defaultConfig); diff --git a/components/theme/useToken.ts b/components/theme/useToken.ts index 5ddfd03fa9..5248ab16ef 100644 --- a/components/theme/useToken.ts +++ b/components/theme/useToken.ts @@ -117,6 +117,7 @@ export default function useToken(): [ hashId: string, realToken: GlobalToken, cssVar: DesignTokenProviderProps['cssVar'], + zeroRuntime: boolean, ] { const { token: rootDesignToken, @@ -124,6 +125,7 @@ export default function useToken(): [ theme, override, cssVar: ctxCssVar, + zeroRuntime, } = React.useContext(DesignTokenContext); const cssVar = { @@ -151,5 +153,5 @@ export default function useToken(): [ }, ); - return [mergedTheme, realToken, hashed ? hashId : '', token, cssVar]; + return [mergedTheme, realToken, hashed ? hashId : '', token, cssVar, !!zeroRuntime]; } diff --git a/components/theme/util/genStyleUtils.ts b/components/theme/util/genStyleUtils.ts index c29844ed02..34e905086a 100644 --- a/components/theme/util/genStyleUtils.ts +++ b/components/theme/util/genStyleUtils.ts @@ -23,8 +23,8 @@ export const { genStyleHooks, genComponentStyleHook, genSubStyleComponent } = ge }; }, useToken: () => { - const [theme, realToken, hashId, token, cssVar] = useLocalToken(); - return { theme, realToken, hashId, token, cssVar }; + const [theme, realToken, hashId, token, cssVar, zeroRuntime] = useLocalToken(); + return { theme, realToken, hashId, token, cssVar, zeroRuntime }; }, useCSP: () => { const { csp } = useContext(ConfigContext); diff --git a/components/transfer/demo/_semantic.tsx b/components/transfer/demo/_semantic.tsx index e59cd83a7f..37dbcfc1b3 100644 --- a/components/transfer/demo/_semantic.tsx +++ b/components/transfer/demo/_semantic.tsx @@ -8,7 +8,8 @@ const locales = { cn: { root: '根元素,设置flex布局、穿梭框容器的基础样式和布局控制', section: '区域元素,设置flex布局、宽度、高度、最小高度、边框、圆角等单侧穿梭框的容器样式', - header: '头部元素,设置flex布局、对齐方式、高度、内边距、颜色、背景色、下边框、圆角等头部区域的样式', + header: + '头部元素,设置flex布局、对齐方式、高度、内边距、颜色、背景色、下边框、圆角等头部区域的样式', title: '标题元素,设置文本省略、flex占比、文本对齐、自动左边距等标题文字的布局和样式', body: '内容元素,设置列表主体区域的容器样式和布局控制', list: '列表元素,设置列表内容的样式、布局和滚动控制', @@ -20,14 +21,18 @@ const locales = { }, en: { root: 'Root element with flex layout, transfer container base styles and layout control', - section: 'Section element with flex layout, width, height, min height, border, border radius and other single-side transfer container styles', - header: 'Header element with flex layout, alignment, height, padding, color, background color, bottom border, border radius and other header area styles', - title: 'Title element with text ellipsis, flex ratio, text alignment, auto left margin and other title text layout and styles', + section: + 'Section element with flex layout, width, height, min height, border, border radius and other single-side transfer container styles', + header: + 'Header element with flex layout, alignment, height, padding, color, background color, bottom border, border radius and other header area styles', + title: + 'Title element with text ellipsis, flex ratio, text alignment, auto left margin and other title text layout and styles', body: 'Body element with list main area container styles and layout control', list: 'List element with list content styles, layout and scroll control', item: 'List item element with relative positioning, padding, border, hover state, selected state, disabled state and other list item interaction styles', itemIcon: 'List item icon element with checkbox and other icon styles and interaction states', - itemContent: 'List item content element with text ellipsis, padding and other list item text content display styles', + itemContent: + 'List item content element with text ellipsis, padding and other list item text content display styles', footer: 'Footer element with bottom operation area styles and layout', actions: 'Actions element with transfer button group styles, layout and interaction states', }, diff --git a/components/tree-select/demo/_semantic.tsx b/components/tree-select/demo/_semantic.tsx index 021c8af0d8..f86a968627 100644 --- a/components/tree-select/demo/_semantic.tsx +++ b/components/tree-select/demo/_semantic.tsx @@ -19,11 +19,15 @@ const locales = { en: { root: 'Root element with tree selector base styles, border, border radius container styles', prefix: 'Prefix element with prefix content layout and styles', - input: 'Input element with text input, search, selected value display and other input core interaction styles', - suffix: 'Suffix element with suffix content, clear button, dropdown arrow and other suffix area styles', - 'popup.item': 'Popup item element with tree node option styles, hover state, selected state and other interaction states', + input: + 'Input element with text input, search, selected value display and other input core interaction styles', + suffix: + 'Suffix element with suffix content, clear button, dropdown arrow and other suffix area styles', + 'popup.item': + 'Popup item element with tree node option styles, hover state, selected state and other interaction states', 'popup.itemTitle': 'Popup title element with tree node title text display styles', - 'popup.root': 'Popup element with dropdown tree selection panel positioning, z-index, background, border, shadow and other popup layer styles', + 'popup.root': + 'Popup element with dropdown tree selection panel positioning, z-index, background, border, shadow and other popup layer styles', }, }; const icon = ; diff --git a/docs/react/customize-theme.en-US.md b/docs/react/customize-theme.en-US.md index 1e47ae7080..bb9ff4f902 100644 --- a/docs/react/customize-theme.en-US.md +++ b/docs/react/customize-theme.en-US.md @@ -440,8 +440,9 @@ const theme = { | inherit | Inherit theme configured in upper ConfigProvider | boolean | true | | algorithm | Modify the algorithms of theme | `(token: SeedToken) => MapToken` \| `((token: SeedToken) => MapToken)[]` | `defaultAlgorithm` | | components | Modify Component Token and Alias Token applied to components | `ComponentsConfig` | - | -| cssVar | Toggle CSS Variables, refer [CSS Variables](/docs/react/css-variables#api) | `boolean \| { prefix?: string; key?: string }` | false | +| cssVar | CSS Variables Configuration, refer [CSS Variables](/docs/react/css-variables#api) | `boolean \| { prefix?: string; key?: string }` | false | | hashed | Component class Hash value, refer [CSS Variables](/docs/react/css-variables#disable-hash) | boolean | true | +| zeroRuntime | Enable zero-runtime mode, which will not generate style at runtime | boolean | true | ### ComponentsConfig diff --git a/docs/react/customize-theme.zh-CN.md b/docs/react/customize-theme.zh-CN.md index 845af01d59..619b14ae20 100644 --- a/docs/react/customize-theme.zh-CN.md +++ b/docs/react/customize-theme.zh-CN.md @@ -440,8 +440,9 @@ const theme = { | inherit | 继承上层 ConfigProvider 中配置的主题。 | boolean | true | | algorithm | 用于修改 Seed Token 到 Map Token 的算法 | `(token: SeedToken) => MapToken` \| `((token: SeedToken) => MapToken)[]` | `defaultAlgorithm` | | components | 用于修改各个组件的 Component Token 以及覆盖该组件消费的 Alias Token | `ComponentsConfig` | - | -| cssVar | 开启 CSS 变量,参考[使用 CSS 变量](/docs/react/css-variables-cn#api) | `boolean \| { prefix?: string; key?: string }` | false | +| cssVar | CSS 变量配置,参考[使用 CSS 变量](/docs/react/css-variables-cn#api) | `{ prefix?: string; key?: string }` | false | | hashed | 组件 class Hash 值,参考[使用 CSS 变量](/docs/react/css-variables-cn#关闭-hash) | boolean | true | +| zeroRuntime | 开启零运行时模式,不会在运行时产生样式,需要额外引入 | boolean | true | ### ComponentsConfig diff --git a/package.json b/package.json index 24d5850208..dbd3217909 100644 --- a/package.json +++ b/package.json @@ -54,7 +54,7 @@ "predeploy": "antd-tools run clean && npm run site && cp CNAME _site && npm run test:site", "deploy": "gh-pages -d _site -b gh-pages -f", "deploy:china-mirror": "git checkout gh-pages && git pull origin gh-pages && git push git@gitee.com:ant-design/ant-design.git gh-pages -f", - "predist": "npm run version && npm run token:statistic && npm run token:meta", + "predist": "npm run version && npm run token:statistic && npm run token:meta && npm run style", "dist": "antd-tools run dist", "format": "biome format --write .", "install-react-18": "npm i --no-save --legacy-peer-deps react@18 react-dom@18 @testing-library/react@16", @@ -80,7 +80,8 @@ "size-limit": "size-limit", "sort:api-table": "antd-tools run sort-api-table", "sort:package-json": "npx sort-package-json", - "prestart": "npm run version && npm run token:statistic && npm run token:meta && npm run lint:changelog", + "style": "tsx scripts/build-style.tsx", + "prestart": "npm run version && npm run token:statistic && npm run token:meta && npm run lint:changelog && npm run style", "start": "tsx ./scripts/set-node-options.ts cross-env PORT=8001 dumi dev", "pretest": "npm run version", "test": "jest --config .jest.js --no-cache", @@ -110,7 +111,7 @@ "dependencies": { "@ant-design/colors": "^8.0.0", "@ant-design/cssinjs": "^2.0.0-alpha.8", - "@ant-design/cssinjs-utils": "^2.0.0-alpha.1", + "@ant-design/cssinjs-utils": "^2.0.0-alpha.2", "@ant-design/fast-color": "^3.0.0", "@ant-design/icons": "^6.0.0", "@ant-design/react-slick": "~1.1.2", diff --git a/scripts/build-style.tsx b/scripts/build-style.tsx new file mode 100644 index 0000000000..ac382daf34 --- /dev/null +++ b/scripts/build-style.tsx @@ -0,0 +1,113 @@ +import path from 'path'; +import React from 'react'; +import { createCache, extractStyle as extStyle, StyleProvider } from '@ant-design/cssinjs'; +import fs from 'fs-extra'; +import { renderToString } from 'react-dom/server'; + +import * as antd from '../components'; + +const output = path.join(__dirname, '../components/style/antd.css'); + +const blackList: string[] = ['ConfigProvider', 'Grid']; + +const ComponentCustomizeRender: Record< + string, + (component: React.ComponentType) => React.ReactNode +> = { + Affix: (Affix) => ( + +
+ + ), + BackTop: () => , + Dropdown: (Dropdown) => ( + +
+ + ), + Menu: (Menu) => , + QRCode: (QRCode) => , + Tree: (Tree) => , + Tag: (Tag) => ( + <> + Tag + Tag + + ), + Badge: (Badge: any) => ( + <> + + + + ), + Space: (Space: any) => ( + <> + + + + + + ), + Modal: (Modal: any) => ( + <> + + + + ), + message: (message: any) => { + const { _InternalPanelDoNotUseOrYouWillBeFired: PurePanel } = message; + return ; + }, + notification: (notification: any) => { + const { _InternalPanelDoNotUseOrYouWillBeFired: PurePanel } = notification; + return ; + }, +}; + +const defaultNode = () => ( + <> + {Object.keys(antd) + .filter( + (name) => + !blackList.includes(name) && + (name[0] === name[0].toUpperCase() || ['message', 'notification'].includes(name)), + ) + .map((compName) => { + const Comp = (antd as any)[compName]; + + const renderFunc = ComponentCustomizeRender[compName]; + + if (renderFunc) { + return {renderFunc(Comp)}; + } + + return ; + })} + +); + +function extractStyle(customTheme?: any): string { + const cache = createCache(); + renderToString( + + {customTheme ? customTheme(defaultNode()) : defaultNode()} + , + ); + + // Grab style from cache + const styleText = extStyle(cache, { plain: true, types: 'style' }); + + return styleText; +} + +async function buildStyle() { + if (fs.existsSync(output)) { + // Remove the old file if it exists + fs.unlinkSync(output); + } + // fs.rmSync(output); + const styleStr = extractStyle(); + fs.writeFileSync(output, styleStr); +} + +buildStyle(); diff --git a/scripts/generate-cssinjs.ts b/scripts/generate-cssinjs.ts index 7b64d4ee51..1564075553 100644 --- a/scripts/generate-cssinjs.ts +++ b/scripts/generate-cssinjs.ts @@ -7,7 +7,7 @@ type StyleFn = (prefix?: string) => void; interface GenCssinjsOptions { key: string; - render: (Component: React.FC, filepath: string) => void; + render?: (Component: React.FC, filepath: string) => void; beforeRender?: (componentName: string) => void; } diff --git a/scripts/tsconfig.json b/scripts/tsconfig.json index de8bac4a7e..575ae358a0 100644 --- a/scripts/tsconfig.json +++ b/scripts/tsconfig.json @@ -2,6 +2,7 @@ "compilerOptions": { "incremental": true, "target": "ES2015", + "jsx": "react", "module": "commonjs", "resolveJsonModule": true, "typeRoots": ["../node_modules/@types"], diff --git a/tests/dekko/dist.test.ts b/tests/dekko/dist.test.ts index 4cf7e4145a..fe04ed2e80 100644 --- a/tests/dekko/dist.test.ts +++ b/tests/dekko/dist.test.ts @@ -11,6 +11,7 @@ $('dist') .hasFile('antd.js.map') .hasFile('antd.min.js') .hasFile('antd.min.js.map') + .hasFile('antd.css') .hasFile('reset.css'); console.log(chalk.green('✨ `dist` directory is valid.'));