Skip to content

fix: fixed error with no expected value in expandColumnTitle slot #7265

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 9 commits into from
Jan 16, 2024
11 changes: 11 additions & 0 deletions components/_util/__mocks__/RenderSlot.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { defineComponent } from 'vue';
import { customRenderSlot } from '../vnode';

export default defineComponent({
name: 'RenderSlot',
setup(_props, { slots }) {
return () => {
return customRenderSlot(slots, 'default', {}, () => ['default value']);
};
},
});
26 changes: 26 additions & 0 deletions components/_util/__tests__/vNode.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import RenderSlot from '../__mocks__/RenderSlot';
import { mount } from '@vue/test-utils';
import { nextTick } from 'vue';

describe('render slot content', () => {
it('renders slot content', () => {
const wrapper = mount(RenderSlot, {
slots: {
default: () => 'This is slot content',
},
});

expect(wrapper.html()).toContain('This is slot content');
});

it('render default value when slot is fragment', async () => {
const wrapper = mount(RenderSlot, {
slots: {
default: () => <></>,
},
});

await nextTick();
expect(wrapper.html()).toContain('default value');
});
});
29 changes: 27 additions & 2 deletions components/_util/vnode.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { filterEmpty } from './props-util';
import type { VNode, VNodeProps } from 'vue';
import { cloneVNode, isVNode, render as VueRender } from 'vue';
import type { Slots, VNode, VNodeArrayChildren, VNodeProps } from 'vue';
import { cloneVNode, isVNode, Comment, Fragment, render as VueRender } from 'vue';
import warning from './warning';
import type { RefObject } from './createRef';
type NodeProps = Record<string, any> &
Expand Down Expand Up @@ -55,3 +55,28 @@ export function deepCloneElement<T, U>(
export function triggerVNodeUpdate(vm: VNode, attrs: Record<string, any>, dom: any) {
VueRender(cloneVNode(vm, { ...attrs }), dom);
}

const ensureValidVNode = (slot: VNodeArrayChildren | null) => {
return (slot || []).some(child => {
if (!isVNode(child)) return true;
if (child.type === Comment) return false;
if (child.type === Fragment && !ensureValidVNode(child.children as VNodeArrayChildren))
return false;
return true;
})
? slot
: null;
};

export function customRenderSlot(
slots: Slots,
name: string,
props: Record<string, unknown>,
fallback?: () => VNodeArrayChildren,
) {
const slot = slots[name]?.(props);
if (ensureValidVNode(slot)) {
return slot;
}
return fallback?.();
}
6 changes: 4 additions & 2 deletions components/card/Card.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type { VNodeTypes, PropType, VNode, ExtractPropTypes, CSSProperties } from 'vue';
import { isVNode, defineComponent, renderSlot } from 'vue';
import { isVNode, defineComponent } from 'vue';
import Tabs from '../tabs';
import PropTypes from '../_util/vue-types';
import { flattenChildren, isEmptyElement, filterEmptyWithUndefined } from '../_util/props-util';
Expand All @@ -10,6 +10,8 @@ import devWarning from '../vc-util/devWarning';
import useStyle from './style';
import Skeleton from '../skeleton';
import type { CustomSlotsType } from '../_util/type';
import { customRenderSlot } from '../_util/vnode';

export interface CardTabListType {
key: string;
tab: any;
Expand Down Expand Up @@ -152,7 +154,7 @@ const Card = defineComponent({
`tabList slots is deprecated, Please use \`customTab\` instead.`,
);
let tab = temp !== undefined ? temp : slots[name] ? slots[name](item) : null;
tab = renderSlot(slots, 'customTab', item as any, () => [tab]);
tab = customRenderSlot(slots, 'customTab', item as any, () => [tab]);
return <TabPane tab={tab} key={item.key} disabled={item.disabled} />;
})}
</Tabs>
Expand Down
5 changes: 3 additions & 2 deletions components/vc-table/Cell/index.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import classNames from '../../_util/classNames';
import { filterEmpty, flattenChildren, isValidElement } from '../../_util/props-util';
import type { CSSProperties, VNodeArrayChildren } from 'vue';
import { Text, computed, defineComponent, isVNode, renderSlot } from 'vue';
import { Text, computed, defineComponent, isVNode } from 'vue';

import type {
DataIndex,
Expand All @@ -23,6 +23,7 @@ import { useInjectSticky } from '../context/StickyContext';
import { warning } from '../../vc-util/warning';
import type { MouseEventHandler } from '../../_util/EventInterface';
import eagerComputed from '../../_util/eagerComputed';
import { customRenderSlot } from 'ant-design-vue/es/_util/vnode';

/** Check if cell is in hover range */
function inHoverRange(cellStartRow: number, cellRowSpan: number, startRow: number, endRow: number) {
Expand Down Expand Up @@ -223,7 +224,7 @@ export default defineComponent<CellProps>({
contextSlots.value.bodyCell &&
!column.slots?.customRender
) {
const child = renderSlot(
const child = customRenderSlot(
contextSlots.value,
'bodyCell',
{
Expand Down
5 changes: 3 additions & 2 deletions components/vc-table/hooks/useColumns.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { warning } from '../../vc-util/warning';
import type { ComputedRef, Ref } from 'vue';
import { renderSlot, computed, watchEffect } from 'vue';
import { computed, watchEffect } from 'vue';
import type {
ColumnsType,
ColumnType,
Expand All @@ -14,6 +14,7 @@ import type {
import { INTERNAL_COL_DEFINE } from '../utils/legacyUtil';
import { EXPAND_COLUMN } from '../constant';
import { useInjectSlots } from '../../table/context';
import { customRenderSlot } from '../../_util/vnode';

function flatColumns<RecordType>(columns: ColumnsType<RecordType>): ColumnType<RecordType>[] {
return columns.reduce((list, column) => {
Expand Down Expand Up @@ -179,7 +180,7 @@ function useColumns<RecordType>(
class: `${prefixCls.value}-expand-icon-col`,
columnType: 'EXPAND_COLUMN',
},
title: renderSlot(contextSlots.value, 'expandColumnTitle', {}, () => ['']),
title: customRenderSlot(contextSlots.value, 'expandColumnTitle', {}, () => ['']),
fixed: fixedColumn,
class: `${prefixCls.value}-row-expand-icon-cell`,
width: expandColumnWidth.value,
Expand Down