Skip to content

Commit 53dc5da

Browse files
aibayanyu20selicenstangjinzhou
authored
feat: add static-style-extract (#6713)
* docs: add ant-design-vue nuxt module * feat: add static-style-extract * docs: fix import defineProps and defineEmits * feat: add static-style extract test * fix: add ignore component * feat: calendar select support info.source param (#6697) * docs: add ant-design-vue nuxt module * feat: calendar select support info.source param * docs: synchronous config-provider demo (#6706) * revert: #6706 * feat: node error * fix: Handle the output of styles in Server Side Rendering mode * fix: fix value required error * chore: change tests dirname * fix: auchor warning * chore: add tests * chore: generate tests snap * docs: add ssr docs * docs: synchronous config-provider demo (#6706) * revert: #6706 * docs: add extract ssr doc * fix: Removing canUseDom does not have any effect. * fix: remove range picker in picker map * fix: watch source can only be a getter/effect function style warning * fix: styleContext props maybe ref * fix: remove black list component * feat: add compChildNameMap --------- Co-authored-by: selicens <1244620067@qq.com> Co-authored-by: tangjinzhou <415800467@qq.com>
1 parent 531ae16 commit 53dc5da

File tree

14 files changed

+276
-6
lines changed

14 files changed

+276
-6
lines changed

components/_util/PortalWrapper.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export default defineComponent({
8383
return true;
8484
};
8585
// attachToParent();
86-
const defaultContainer = document.createElement('div');
86+
const defaultContainer = canUseDom() && document.createElement('div');
8787
const getContainer = () => {
8888
if (!supportDom) {
8989
return null;

components/_util/cssinjs/StyleContext.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ export const useStyleProvider = (props: UseStyleProviderProps) => {
8888
const parentContext = useStyleInject();
8989
const context = shallowRef<Partial<StyleContextProps>>({ ...defaultStyleContext });
9090
watch(
91-
[props, parentContext],
91+
[() => unref(props), parentContext],
9292
() => {
9393
const mergedContext: Partial<StyleContextProps> = {
9494
...parentContext.value,

components/_util/cssinjs/hooks/useStyleRegister.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -413,7 +413,7 @@ export default function useStyleRegister(
413413
// ============================================================================
414414
// == SSR ==
415415
// ============================================================================
416-
export function extractStyle(cache: Cache) {
416+
export function extractStyle(cache: Cache, plain = false) {
417417
// prefix with `style` is used for `useStyleRegister` to cache style context
418418
const styleKeys = Array.from(cache.cache.keys()).filter(key => key.startsWith('style%'));
419419

@@ -424,7 +424,9 @@ export function extractStyle(cache: Cache) {
424424
styleKeys.forEach(key => {
425425
const [styleStr, tokenKey, styleId]: [string, string, string] = cache.cache.get(key)![1];
426426

427-
styleText += `<style ${ATTR_TOKEN}="${tokenKey}" ${ATTR_MARK}="${styleId}">${styleStr}</style>`;
427+
styleText += plain
428+
? styleStr
429+
: `<style ${ATTR_TOKEN}="${tokenKey}" ${ATTR_MARK}="${styleId}">${styleStr}</style>`;
428430
});
429431

430432
return styleText;

components/_util/hooks/useScrollLocker.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import type { Ref } from 'vue';
22
import { computed, watchEffect } from 'vue';
33
import { updateCSS, removeCSS } from '../../vc-util/Dom/dynamicCSS';
44
import getScrollBarSize from '../../_util/getScrollBarSize';
5+
import canUseDom from '../../_util/canUseDom';
56

67
const UNIQUE_ID = `vc-util-locker-${Date.now()}`;
78

@@ -24,6 +25,9 @@ export default function useScrollLocker(lock?: Ref<boolean>) {
2425

2526
watchEffect(
2627
onClear => {
28+
if (!canUseDom()) {
29+
return;
30+
}
2731
if (mergedLock.value) {
2832
const scrollbarSize = getScrollBarSize();
2933
const isOverflow = isBodyOverflowing();

components/_util/static-style-extract/__tests__/__snapshots__/index.test.js.snap

Lines changed: 5 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
// import { StyleProvider } from '../../cssinjs';
2+
import { extractStyle } from '../index';
3+
import { ConfigProvider } from '../../../components';
4+
5+
const testGreenColor = '#008000';
6+
describe('Static-Style-Extract', () => {
7+
it('should extract static styles', () => {
8+
const cssText = extractStyle();
9+
expect(cssText).not.toContain(testGreenColor);
10+
expect(cssText).toMatchSnapshot();
11+
});
12+
it('should extract static styles with customTheme', () => {
13+
const cssText = extractStyle(node => {
14+
return (
15+
<ConfigProvider
16+
theme={{
17+
token: {
18+
colorPrimary: testGreenColor,
19+
},
20+
}}
21+
>
22+
{node}
23+
</ConfigProvider>
24+
);
25+
});
26+
expect(cssText).toContain(testGreenColor);
27+
expect(cssText).toMatchSnapshot();
28+
});
29+
// it('with custom hashPriority', () => {
30+
// const cssText = extractStyle(
31+
// (node) => (
32+
// <StyleProvider hashPriority='high'>
33+
// <ConfigProvider
34+
// theme={{
35+
// token: {
36+
// colorPrimary: testGreenColor,
37+
// },
38+
// }}
39+
// >
40+
// {node}
41+
// </ConfigProvider>
42+
// </StyleProvider>
43+
// ),
44+
// );
45+
// expect(cssText).toContain(testGreenColor);
46+
// expect(cssText).not.toContain(':where');
47+
// expect(cssText).toMatchSnapshot();
48+
//
49+
// const cssText2 = extractStyle((node) => (
50+
// <ConfigProvider
51+
// theme={{
52+
// token: {
53+
// colorPrimary: testGreenColor,
54+
// },
55+
// }}
56+
// >
57+
// {node}
58+
// </ConfigProvider>
59+
// ));
60+
// expect(cssText2).toContain(':where');
61+
// });
62+
});
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
import { createCache, extractStyle as extStyle, StyleProvider } from '../cssinjs';
2+
import * as antd from '../../components';
3+
import { renderToString } from 'vue/server-renderer';
4+
import type { CustomRender } from './interface';
5+
const blackList: string[] = [
6+
'ConfigProvider',
7+
'Grid',
8+
'Tour',
9+
'SelectOptGroup',
10+
'SelectOption',
11+
'MentionsOption',
12+
'TreeNode',
13+
'TreeSelectNode',
14+
'LocaleProvider',
15+
];
16+
17+
const pickerMap = {
18+
MonthPicker: 'month',
19+
WeekPicker: 'week',
20+
QuarterPicker: 'quarter',
21+
};
22+
23+
const compChildNameMap = {
24+
MenuDivider: 'Menu',
25+
MenuItem: 'Menu',
26+
MenuItemGroup: 'Menu',
27+
SubMenu: 'Menu',
28+
TableColumn: 'Table',
29+
TableColumnGroup: 'Table',
30+
TableSummary: 'Table',
31+
TableSummaryRow: 'Table',
32+
TableSummaryCell: 'Table',
33+
TabPane: 'Tabs',
34+
TimelineItem: 'Timeline',
35+
};
36+
37+
const defaultNode = () => (
38+
<>
39+
{Object.keys(antd)
40+
.filter(name => !blackList.includes(name) && name[0] === name[0].toUpperCase())
41+
.map(compName => {
42+
const Comp = antd[compName];
43+
if (compName === 'Dropdown') {
44+
return (
45+
<Comp key={compName} menu={{ items: [] }}>
46+
<div />
47+
</Comp>
48+
);
49+
}
50+
if (compName === 'Anchor') {
51+
return <Comp key={compName} items={[]} />;
52+
}
53+
if (compName in pickerMap) {
54+
const Comp = antd['DatePicker'];
55+
const type = pickerMap[compName];
56+
return <Comp key={compName} picker={type} />;
57+
}
58+
if (compName in compChildNameMap) {
59+
const ParentComp = antd[compChildNameMap[compName]];
60+
return (
61+
<ParentComp>
62+
<Comp />
63+
</ParentComp>
64+
);
65+
}
66+
if (compName === 'QRCode' || compName === 'Segmented') {
67+
return (
68+
<Comp key={compName} value={''}>
69+
<div />
70+
</Comp>
71+
);
72+
}
73+
return <Comp key={compName} />;
74+
})}
75+
</>
76+
);
77+
78+
export function extractStyle(customTheme?: CustomRender): string {
79+
const cache = createCache();
80+
renderToString(
81+
<StyleProvider cache={cache}>
82+
{customTheme ? customTheme(defaultNode()) : defaultNode()}
83+
</StyleProvider>,
84+
);
85+
86+
// Grab style from cache
87+
const styleText = extStyle(cache, true);
88+
89+
return styleText;
90+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import type { VueNode } from '../type';
2+
3+
export type CustomRender = (node: VueNode) => VueNode;

components/drawer/demo/descriptionItem/index.vue

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@
1010
</div>
1111
</template>
1212
<script lang="ts" setup>
13-
import { defineProps } from 'vue';
1413
interface Props {
1514
title: string;
1615
content?: string;

components/float-button/FloatButtonGroup.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { useProvideFloatButtonGroupContext } from './context';
99
import { findDOMNode, initDefaultProps } from '../_util/props-util';
1010
import { floatButtonGroupProps } from './interface';
1111
import type { FloatButtonGroupProps } from './interface';
12+
import canUseDom from '../_util/canUseDom';
1213

1314
// CSSINJS
1415
import useStyle from './style';
@@ -74,6 +75,9 @@ const FloatButtonGroup = defineComponent({
7475
watch(
7576
computed(() => props.trigger),
7677
value => {
78+
if (!canUseDom()) {
79+
return;
80+
}
7781
document.removeEventListener('click', onClick);
7882
if (value === 'click') {
7983
document.addEventListener('click', onClick);

0 commit comments

Comments
 (0)