Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions packages/x/components/sender/__tests__/slot.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -523,6 +523,46 @@ describe('Sender Slot Component', () => {
setupDOMMocks(customSelectionMock, customRangeMock);
fireEvent.keyDown(dom, { key: 'Backspace' });
});
it('should trigger closable.onClose when removing skill via Backspace', () => {
const onClose = jest.fn();
const ref = createRef<SenderRef>();
const { container } = render(
<Sender
ref={ref}
slotConfig={[]}
placeholder="Sender placeholder"
skill={{
value: 'test-skill',
title: 'Test Skill',
closable: { onClose },
}}
/>,
);
const dom = ref.current?.inputElement as HTMLElement;
const skillDom = container.querySelector('.ant-sender-skill') as HTMLElement;
expect(ref.current).not.toBeNull();
expect(skillDom).toBeInTheDocument();

const customSelectionMock = {
rangeCount: 1,
focusOffset: 0,
anchorNode: dom,
removeAllRanges: jest.fn(),
addRange: jest.fn(),
};

Object.defineProperty(dom, 'previousSibling', {
value: skillDom,
configurable: true,
});

const customRangeMock = createMockRange();
setupDOMMocks(customSelectionMock, customRangeMock);
fireEvent.keyDown(dom, { key: 'Backspace' });

expect(onClose).toHaveBeenCalledTimes(1);
expect(container.querySelector('.ant-sender-skill')).not.toBeInTheDocument();
});
it('should handle skill removal and addition', () => {
const { rerender, container } = render(
<Sender
Expand Down
2 changes: 1 addition & 1 deletion packages/x/components/sender/components/Skill.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import type { SkillType } from '../interface';

interface ClosableConfig {
closeIcon?: React.ReactNode;
onClose?: React.MouseEventHandler<HTMLDivElement>;
onClose?: (event: React.SyntheticEvent<HTMLDivElement>) => void;
disabled?: boolean;
}

Expand Down
4 changes: 4 additions & 0 deletions packages/x/components/sender/components/SlotTextArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -525,6 +525,10 @@ const SlotTextArea = React.forwardRef<SlotTextAreaRef>((_, ref) => {
if (skillKey) {
e.preventDefault();
removeSkill();
// 与点击关闭行为保持一致,删除后补发 closable.onClose
if (skill?.closable && typeof skill.closable === 'object') {
skill.closable.onClose?.(e);
}
return true;
}
Comment thread
coderabbitai[bot] marked this conversation as resolved.
}
Expand Down
3 changes: 2 additions & 1 deletion packages/x/components/sender/index.en-US.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,8 @@ interface SkillType {
| boolean
| {
closeIcon?: React.ReactNode;
onClose?: React.MouseEventHandler<HTMLDivElement>;
// Triggered when the skill is removed by clicking the close button or pressing Backspace
onClose?: (event: React.SyntheticEvent<HTMLDivElement>) => void;
disabled?: boolean;
};
}
Expand Down
3 changes: 2 additions & 1 deletion packages/x/components/sender/index.zh-CN.md
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,8 @@ interface SkillType {
| boolean
| {
closeIcon?: React.ReactNode;
onClose?: React.MouseEventHandler<HTMLDivElement>;
// 点击关闭按钮或使用 Backspace 删除时触发
onClose?: (event: React.SyntheticEvent<HTMLDivElement>) => void;
disabled?: boolean;
};
}
Expand Down
3 changes: 2 additions & 1 deletion packages/x/components/sender/interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ export interface SkillType {
| boolean
| {
closeIcon?: React.ReactNode;
onClose?: React.MouseEventHandler<HTMLDivElement>;
/** 点击关闭按钮或使用 Backspace 删除时触发 */
onClose?: (event: React.SyntheticEvent<HTMLDivElement>) => void;
disabled?: boolean;
};
}
Expand Down
Loading