Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,4 +39,5 @@ bun.lockb

# dumi
.dumi/tmp
.dumi/tmp-production
.dumi/tmp-production
dist/
7 changes: 6 additions & 1 deletion src/UniqueProvider/FloatBg.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ export interface FloatBgProps {
offsetY: number;
popupSize?: { width: number; height: number };
motion?: CSSMotionProps;
uniqueBgClassName?: string;
uniqueBgStyle?: React.CSSProperties;
}

const FloatBg = (props: FloatBgProps) => {
Expand All @@ -32,6 +34,8 @@ const FloatBg = (props: FloatBgProps) => {
offsetY,
popupSize,
motion,
uniqueBgClassName,
uniqueBgStyle,
} = props;

const floatBgCls = `${prefixCls}-float-bg`;
Expand Down Expand Up @@ -72,7 +76,7 @@ const FloatBg = (props: FloatBgProps) => {
}}
>
{({ className: motionClassName, style: motionStyle }) => {
const cls = classNames(floatBgCls, motionClassName, {
const cls = classNames(floatBgCls, motionClassName, uniqueBgClassName, {
[`${floatBgCls}-visible`]: motionVisible,
});

Expand All @@ -83,6 +87,7 @@ const FloatBg = (props: FloatBgProps) => {
...offsetStyle,
...sizeStyle,
...motionStyle,
...uniqueBgStyle,
}}
/>
);
Expand Down
2 changes: 2 additions & 0 deletions src/UniqueProvider/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -216,6 +216,8 @@ const UniqueProvider = ({ children }: UniqueProviderProps) => {
offsetY={offsetY}
popupSize={popupSize}
motion={options.popupMotion}
uniqueBgClassName={options.uniqueBgClassName}
uniqueBgStyle={options.uniqueBgStyle}
/>
</Popup>
</TriggerContext.Provider>
Expand Down
2 changes: 2 additions & 0 deletions src/context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ export interface UniqueShowOptions {
delay: number;
prefixCls?: string;
popupClassName?: string;
uniqueBgClassName?: string;
uniqueBgStyle?: React.CSSProperties;
popupStyle?: React.CSSProperties;
popupPlacement?: string;
builtinPlacements?: BuildInPlacements;
Expand Down
8 changes: 8 additions & 0 deletions src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ export interface TriggerProps {
builtinPlacements?: BuildInPlacements;
popupAlign?: AlignType;
popupClassName?: string;
/** Pass to `UniqueProvider` FloatBg */
uniqueBgClassName?: string;
/** Pass to `UniqueProvider` FloatBg */
uniqueBgStyle?: React.CSSProperties;
popupStyle?: React.CSSProperties;
getPopupClassNameFromAlign?: (align: AlignType) => string;
onPopupClick?: React.MouseEventHandler<HTMLDivElement>;
Expand Down Expand Up @@ -169,6 +173,8 @@ export function generateTrigger(
// Popup
popup,
popupClassName,
uniqueBgClassName,
uniqueBgStyle,
popupStyle,

popupPlacement,
Expand Down Expand Up @@ -323,6 +329,8 @@ export function generateTrigger(
delay,
prefixCls,
popupClassName,
uniqueBgClassName,
uniqueBgStyle,
popupStyle,
popupPlacement,
builtinPlacements,
Expand Down
95 changes: 95 additions & 0 deletions tests/unique.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -152,4 +152,99 @@ describe('Trigger.Unique', () => {
expect(popup.className).toContain('custom-align');
expect(popup.className).toContain('rc-trigger-popup-unique-controlled');
});

it('should apply uniqueBgClassName to FloatBg component', async () => {
const { container } = render(
<UniqueProvider>
<Trigger
action={['click']}
popup={<strong className="x-content">tooltip</strong>}
unique
uniqueBgClassName="custom-bg-class"
>
<div className="target">click me</div>
</Trigger>
</UniqueProvider>,
);

// Initially no popup should be visible
expect(document.querySelector('.rc-trigger-popup')).toBeFalsy();

// Click trigger to show popup
fireEvent.click(container.querySelector('.target'));
await awaitFakeTimer();

// Check that popup exists
const popup = document.querySelector('.rc-trigger-popup');
expect(popup).toBeTruthy();

// Check that FloatBg has the custom background className
const floatBg = document.querySelector('.rc-trigger-popup-float-bg');
expect(floatBg).toBeTruthy();
expect(floatBg.className).toContain('custom-bg-class');
});

it('should apply uniqueBgStyle to FloatBg component', async () => {
const { container } = render(
<UniqueProvider>
<Trigger
action={['click']}
popup={<strong className="x-content">tooltip</strong>}
unique
uniqueBgStyle={{ backgroundColor: 'red', border: '1px solid blue' }}
>
<div className="target">click me</div>
</Trigger>
</UniqueProvider>,
);

// Initially no popup should be visible
expect(document.querySelector('.rc-trigger-popup')).toBeFalsy();

// Click trigger to show popup
fireEvent.click(container.querySelector('.target'));
await awaitFakeTimer();

// Check that popup exists
const popup = document.querySelector('.rc-trigger-popup');
expect(popup).toBeTruthy();

// Check that FloatBg has the custom background style
const floatBg = document.querySelector('.rc-trigger-popup-float-bg');
expect(floatBg).toBeTruthy();
expect(floatBg).toHaveStyle({
backgroundColor: 'red',
border: '1px solid blue',
});
});

it('should not apply any additional className to FloatBg when uniqueBgClassName is not provided', async () => {
const { container } = render(
<UniqueProvider>
<Trigger
action={['click']}
popup={<strong className="x-content">tooltip</strong>}
unique
>
<div className="target">click me</div>
</Trigger>
</UniqueProvider>,
);

// Initially no popup should be visible
expect(document.querySelector('.rc-trigger-popup')).toBeFalsy();

// Click trigger to show popup
fireEvent.click(container.querySelector('.target'));
await awaitFakeTimer();

// Check that popup exists
const popup = document.querySelector('.rc-trigger-popup');
expect(popup).toBeTruthy();

// Check that FloatBg exists but does not have custom background className
const floatBg = document.querySelector('.rc-trigger-popup-float-bg');
expect(floatBg).toBeTruthy();
expect(floatBg.className).not.toContain('undefined');
});
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

这三个新的测试用例 (should apply uniqueBgClassName..., should apply uniqueBgStyle..., should not apply any additional className...) 中存在较多重复的设置代码,例如渲染组件、触发弹窗和检查弹窗是否可见的逻辑。

为了提高测试代码的可读性和可维护性,建议将这部分通用的设置逻辑提取到一个辅助函数中。这样可以让每个测试用例更专注于其核心的断言逻辑,使代码更简洁。

例如,可以创建一个这样的辅助函数:

async function setupAndOpenPopup(triggerProps: Partial<TriggerProps> = {}) {
  const { container } = render(
    <UniqueProvider>
      <Trigger
        action={['click']}
        popup={<strong className="x-content">tooltip</strong>}
        unique
        {...triggerProps}
      >
        <div className="target">click me</div>
      </Trigger>
    </UniqueProvider>,
  );

  // Initially no popup should be visible
  expect(document.querySelector('.rc-trigger-popup')).toBeFalsy();

  // Click trigger to show popup
  fireEvent.click(container.querySelector('.target'));
  await awaitFakeTimer();

  // Check that popup exists
  const popup = document.querySelector('.rc-trigger-popup');
  expect(popup).toBeTruthy();

  return { container, popup };
}

然后测试用例可以简化为:

it('should apply uniqueBgClassName to FloatBg component', async () => {
  await setupAndOpenPopup({ uniqueBgClassName: 'custom-bg-class' });

  const floatBg = document.querySelector('.rc-trigger-popup-float-bg');
  expect(floatBg).toBeTruthy();
  expect(floatBg.className).toContain('custom-bg-class');
});

});
Loading