Skip to content

Commit d67c2e0

Browse files
authored
feat: support render icon in tab title (#447)
* feat: tab support to set icon * test: add unit test for icon rendering * fix: improve the layer of icon
1 parent 9ac1962 commit d67c2e0

File tree

5 files changed

+37
-1
lines changed

5 files changed

+37
-1
lines changed

src/components/tabs/__tests__/tab.test.tsx

+13-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import React from 'react';
22
import { cleanup, fireEvent, render, waitFor } from '@testing-library/react';
3+
import '@testing-library/jest-dom';
34
import {
45
ITabEvent,
56
ITabProps,
@@ -44,7 +45,18 @@ describe('The Tab Component', () => {
4445
test('Should render name in tab', () => {
4546
const { container } = render(<DTab />);
4647
const wrapper = container.querySelector(`.${tabItemClassName}`)!;
47-
expect(wrapper.innerHTML).toBe('test');
48+
expect(wrapper.innerHTML).toContain('test');
49+
});
50+
51+
test('Should render icon in tab', () => {
52+
const { container, getByTestId, rerender } = render(
53+
<DTab icon="placeholder" />
54+
);
55+
56+
expect(container.querySelector('.codicon-placeholder')).not.toBeNull();
57+
58+
rerender(<DTab icon={<i data-testid="icon" />} />);
59+
expect(getByTestId('icon')).toBeInTheDocument();
4860
});
4961

5062
test('Should active classNames when active tab', () => {

src/components/tabs/index.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ export function Tabs<T>(props: ITabsProps<T>) {
7373
active={activeTab === tab.id}
7474
index={index}
7575
name={tab.name}
76+
icon={tab.icon}
7677
data={tab.data}
7778
closable={tab.closable}
7879
onMoveTab={onChangeTab}

src/components/tabs/style.scss

+8
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@
4242
position: relative;
4343
user-select: none;
4444

45+
&__label {
46+
font-size: 0;
47+
48+
&:not(&:empty) {
49+
padding-right: 6px;
50+
}
51+
}
52+
4553
&__op {
4654
color: var(--icon-foreground);
4755
margin-left: 10px;

src/components/tabs/tab.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import {
1515
prefixClaName,
1616
} from 'mo/common/className';
1717
import TabExtra from './tabExtra';
18+
import { Icon } from '../icon';
1819

1920
export interface ITabEvent {
2021
onMoveTab?: (dragIndex: number, hoverIndex: number) => void;
@@ -29,6 +30,7 @@ export interface ITabProps<T = any, P = any> extends ITabEvent {
2930
active?: boolean;
3031
closable?: boolean;
3132
editable?: boolean;
33+
icon?: string | JSX.Element;
3234
index?: number;
3335
id?: string;
3436
name?: string;
@@ -42,6 +44,7 @@ export const tabItemActiveClassName = getBEMModifier(
4244
tabItemClassName,
4345
'active'
4446
);
47+
export const tabItemLabelClassName = getBEMElement(tabItemClassName, 'label');
4548

4649
export function Tab<T>(props: ITabProps) {
4750
const {
@@ -52,6 +55,7 @@ export function Tab<T>(props: ITabProps) {
5255
data,
5356
id,
5457
index,
58+
icon,
5559
onCloseTab,
5660
onMoveTab,
5761
onSelectTab,
@@ -118,6 +122,11 @@ export function Tab<T>(props: ITabProps) {
118122
});
119123

120124
drag(drop(ref));
125+
126+
const renderIcon = (icon: string | JSX.Element) => {
127+
return typeof icon === 'string' ? <Icon type={icon} /> : icon;
128+
};
129+
121130
return (
122131
<div
123132
ref={ref}
@@ -129,6 +138,11 @@ export function Tab<T>(props: ITabProps) {
129138
onMouseOut={handleMouseOut}
130139
onContextMenu={handleOnContextMenu}
131140
>
141+
{icon && (
142+
<span className={tabItemLabelClassName}>
143+
{renderIcon(icon)}
144+
</span>
145+
)}
132146
{name}
133147
{editable && (
134148
<TabExtra

stories/extensions/test/testPane.tsx

+1
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,7 @@ export default class TestPane extends React.Component {
168168
const tabData: IEditorTab = {
169169
id: `${key}`,
170170
name: `editor${key}.ts`,
171+
icon: Math.random() >= 0.5 ? 'selection' : undefined,
171172
data: {
172173
value: `${key}export interface Type<T> { new(...args: any[]): T;}
173174
export type GenericClassDecorator<T> = (target: T) => void;`,

0 commit comments

Comments
 (0)