Skip to content

Commit

Permalink
feat: The tooltip and popover components add mouseEnterDelay and mous…
Browse files Browse the repository at this point in the history
…eLeaveDelay props (#439)

* feat: The tooltip and popover components add mouseEnterDelay and mouseLeaveDelay props

* test: updated unit test
  • Loading branch information
baiwusanyu-c committed Apr 21, 2024
1 parent 38768c5 commit 424b812
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 45 deletions.
22 changes: 11 additions & 11 deletions components/ColorPicker/__test__/color-picker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(300);
await vi.advanceTimersByTimeAsync(500);
expect(host!.innerHTML.includes('k-color-picker--test')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
});
Expand Down Expand Up @@ -153,7 +153,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);

const inputs = host.querySelectorAll('.k-input--inner');
expect(inputs[0].value).toBe('0');
Expand Down Expand Up @@ -195,7 +195,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);

expect(host!.innerHTML.includes('k-color-picker-clear')).toBeTruthy();
expect(host.innerHTML).matchSnapshot();
Expand Down Expand Up @@ -262,7 +262,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);

expect(host.querySelectorAll('.k-input--inner').length).toBe(3);
expect(host!.innerHTML.includes('k-color-picker--alpha')).not.toBeTruthy();
Expand Down Expand Up @@ -303,7 +303,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
const labelEl = host.querySelector('.k-color-picker-preset--label');
const checkBoxs = host.querySelectorAll('.k-checkbox--box');
expect(labelEl!.innerHTML.includes('primary')).toBeTruthy();
Expand All @@ -329,7 +329,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
expect(host.innerHTML).matchSnapshot();
});

Expand All @@ -342,7 +342,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
expect(host.innerHTML).matchSnapshot();
});

Expand All @@ -355,7 +355,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
expect(host.innerHTML).matchSnapshot();
});

Expand All @@ -368,7 +368,7 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('[slot="triggerEl"]');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(300);
await vi.advanceTimersByTimeAsync(500);
const resDom = host.querySelector('#format_test');
expect(resDom.innerHTML).toBe('hsv');
expect(host.innerHTML.includes('hsv(211, 59%, 100%)')).toBeTruthy();
Expand Down Expand Up @@ -482,13 +482,13 @@ describe('Test: KColorPicker', () => {
const btn = host.querySelector('#open');
await fireEvent.click(btn);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
expect(mockFn).toBeCalledTimes(1);
expect(host.innerHTML).matchSnapshot();
const close = host.querySelector('#close');
await fireEvent.click(close);
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
expect(mockFn).toBeCalledTimes(2);
});
// TODO: events change unit test
Expand Down
15 changes: 15 additions & 0 deletions components/Popover/__test__/fixture/popover.delay.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<script>
import KPopover from '../../src';
import { createEventDispatcher } from 'svelte';
const dispatcher = createEventDispatcher();
const handleChange = (e) => {
dispatcher('change', e.detail);
};
</script>

<KPopover placement="bottom" on:change={handleChange} mouseEnterDelay={1000} mouseLeaveDelay={1000}>
<div slot="triggerEl" cls="mx-2">top</div>
<div slot="contentEl" class="flex flex-col">
<p class="!my-2">有美一人,清扬婉兮</p>
</div>
</KPopover>
54 changes: 54 additions & 0 deletions components/Popover/__test__/popover.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import KPopoverSlots from './fixture/popover.slots.svelte';
import KPopoverDisabled from './fixture/popover.disabled.svelte';
import KPopoverChange from './fixture/popover.change.svelte';
import KPopoverArrow from './fixture/popover.arrow.svelte';
import KPopoverDelay from './fixture/popover.delay.svelte';
let host: HTMLElement;

const initHost = () => {
Expand All @@ -24,6 +25,7 @@ afterEach(() => {
// TODO E2E test
describe('Test: KPopover', () => {
test('props: placement', async () => {
//@ts-ignore
const instance = new KPopoverPlacement({
target: host
});
Expand All @@ -43,6 +45,7 @@ describe('Test: KPopover', () => {
});

test('props: disabled', async () => {
//@ts-ignore
const instance = new KPopoverDisabled({
target: host
});
Expand All @@ -62,6 +65,7 @@ describe('Test: KPopover', () => {
});

test('props: arrow', async () => {
//@ts-ignore
const instance = new KPopoverArrow({
target: host
});
Expand All @@ -81,6 +85,7 @@ describe('Test: KPopover', () => {
});

test('props: trigger', async () => {
//@ts-ignore
const instance = new KPopoverTrigger({
target: host
});
Expand All @@ -94,7 +99,54 @@ describe('Test: KPopover', () => {
expect(host.innerHTML).matchSnapshot();
});

test('props: mouseEnterDelay & mouseLeaveDelay', async () => {
//@ts-ignore
let show = false;
//@ts-ignore
const instance = new KPopoverDelay({
target: host
});
expect(instance).toBeTruthy();
//@ts-ignore
instance.$on('change', (e) => {
show = e.detail;
});
await tick();
const Elm = host.children[0];
Elm.dispatchEvent(
new MouseEvent('mouseenter', {
cancelable: true
})
);

await tick();
await vi.advanceTimersByTimeAsync(300);
expect(host.innerHTML.includes('有美一人,清扬婉兮')).not.toBeTruthy();
expect(host.innerHTML.includes('data-popper-arrow-bottom')).not.toBeTruthy();
expect(show).not.toBeTruthy();
await vi.advanceTimersByTimeAsync(1000);
expect(host.innerHTML.includes('有美一人,清扬婉兮')).toBeTruthy();
expect(host.innerHTML.includes('data-popper-arrow-bottom')).toBeTruthy();
expect(show).toBeTruthy();

Elm.dispatchEvent(
new MouseEvent('mouseleave', {
cancelable: true
})
);

await tick();
await vi.advanceTimersByTimeAsync(300);
expect(host.innerHTML.includes('有美一人,清扬婉兮')).toBeTruthy();
expect(host.innerHTML.includes('data-popper-arrow-bottom')).toBeTruthy();
expect(show).toBeTruthy();
await vi.advanceTimersByTimeAsync(1000);
await tick();
expect(show).not.toBeTruthy();
});

test('slots: triggerEl & contentEl', async () => {
//@ts-ignore
const instance = new KPopoverSlots({
target: host
});
Expand All @@ -117,10 +169,12 @@ describe('Test: KPopover', () => {
test('events: change', async () => {
let show = false;
const mockFn = vi.fn();
//@ts-ignore
const instance = new KPopoverChange({
target: host
});
expect(instance).toBeTruthy();
//@ts-ignore
instance.$on('change', (e) => {
show = e.detail;
mockFn();
Expand Down
30 changes: 15 additions & 15 deletions components/Popover/src/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
export let attrs: KPopoverProps['attrs'] = {};
export let disabled: KPopoverProps['disabled'] = false;
export let arrow: KPopoverProps['arrow'] = true;
export let mouseEnterDelay: KPopoverProps['mouseEnterDelay'] = 200;
export let mouseLeaveDelay: KPopoverProps['mouseLeaveDelay'] = 200;
export let cls: KPopoverProps['cls'] = undefined;
export let clsTrigger: KPopoverProps['clsTrigger'] = undefined;
/**
Expand Down Expand Up @@ -91,21 +93,19 @@
}
export function doUpdateShow(show: boolean) {
if (disabled && show) return;
setTimeout(
async () => {
if (isEnter) {
if (isShow) return;
isShow = true;
dispatch('change', isShow);
return;
}
if (show !== isShow) {
isShow = show;
dispatch('change', isShow);
}
},
trigger === 'hover' ? 200 : 0
);
const delay = show ? mouseEnterDelay : mouseLeaveDelay;
setTimeout(async () => {
if (isEnter) {
if (isShow) return;
isShow = true;
dispatch('change', isShow);
return;
}
if (show !== isShow) {
isShow = show;
dispatch('change', isShow);
}
}, delay);
}
function updateArrow() {
Expand Down
2 changes: 2 additions & 0 deletions components/Popover/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ export type KPopoverProps = {
arrow: boolean;
cls: ClassValue;
clsTrigger: ClassValue;
mouseEnterDelay: number;
mouseLeaveDelay: number;
width: string | null | undefined;
attrs: Record<string, string>;
};
6 changes: 3 additions & 3 deletions components/Select/__test__/select.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -147,16 +147,16 @@ describe('Test: KSelect', () => {
inputEl.value = 'ikun';
inputEl.dispatchEvent(new Event('input', { cancelable: true }));
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
expect(host.innerHTML.includes('no data')).toBeTruthy();
inputEl.value = 'Alabama';
inputEl.dispatchEvent(new Event('input', { cancelable: true }));
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
const optionEl = host?.querySelectorAll('.k-virtual-list--item')[0].children[0];
(optionEl as HTMLElement)?.click();
await tick();
await vi.advanceTimersByTimeAsync(400);
await vi.advanceTimersByTimeAsync(500);
expect(valueEl?.innerHTML).toBe('{"label":"Alabama","value":"Alabama","id":"Alabama"}');
});

Expand Down
4 changes: 3 additions & 1 deletion components/Tooltip/src/index.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,13 @@
export let attrs: KTooltipProps['attrs'] = {};
export let content: KTooltipProps['content'] = '';
export let disabled: KTooltipProps['disabled'] = false;
export let mouseEnterDelay: KTooltipProps['mouseEnterDelay'] = 200;
export let mouseLeaveDelay: KTooltipProps['mouseLeaveDelay'] = 200;
$: cnames = clsx(cls);
</script>

<KPopover cls={cnames} {disabled} {trigger} {placement} {attrs}>
<KPopover cls={cnames} {disabled} {trigger} {mouseEnterDelay} {mouseLeaveDelay} {placement} {attrs}>
<span slot="contentEl">{content}</span>
<slot name="triggerEl" slot="triggerEl" />
</KPopover>
2 changes: 2 additions & 0 deletions components/Tooltip/src/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export type KTooltipProps = {
trigger: IKunTrigger;
content: string;
disabled: boolean;
mouseEnterDelay: number;
mouseLeaveDelay: number;
cls: ClassValue;
attrs: Record<string, string>;
};
18 changes: 10 additions & 8 deletions docs/components/KPopover.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,14 +43,16 @@ Specify different trigger methods through the `trigger` attribute

## Popover Props

| Name | Type | Default | Description |
| --------- | ------------------------------------- | ------- | --------------------------- |
| placement | `'top' / 'left' / 'right' / 'bottom'` | `top` | Where the `popover` appears |
| trigger | `'manual' / 'click' / 'hover'` | `hover` | How popovers are triggered |
| disabled | `boolean` | `false` | Disabled the popover |
| arrow | `boolean` | `true` | Display the arrow |
| cls | `string` | `-` | Additional class |
| attrs | `Record<string, string>` | `{}` | Additional attributes |
| Name | Type | Default | Description |
| --------------- | ------------------------------------- | ------- | --------------------------------------------------------------------- |
| placement | `'top' / 'left' / 'right' / 'bottom'` | `top` | Where the `popover` appears |
| trigger | `'manual' / 'click' / 'hover'` | `hover` | How popovers are triggered |
| disabled | `boolean` | `false` | Disabled the popover |
| mouseEnterDelay | `number` | `200` | Delay in seconds, before `popover` is shown on mouse enter, unit `ms` |
| mouseLeaveDelay | `number` | `200` | Delay in seconds, before `popover` is shown on mouse enter, unit `ms` |
| arrow | `boolean` | `true` | Display the arrow |
| cls | `string` | `-` | Additional class |
| attrs | `Record<string, string>` | `{}` | Additional attributes |

## Popover Events

Expand Down
16 changes: 9 additions & 7 deletions docs/components/KTooltip.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ Specify different trigger methods through the `trigger` attribute

## Tooltip Props

| Name | Type | Default | Description |
| --------- | ------------------------------------- | ------- | --------------------------- |
| placement | `'top' / 'left' / 'right' / 'bottom'` | `top` | Where the `tooltip` appears |
| trigger | `'manual' / 'click' / 'hover'` | `hover` | How `tooltip` are triggered |
| cls | `string` | `-` | Additional class |
| attrs | `Record<string, string>` | `{}` | Additional attributes |
| content | `string` | `-` | `tooltip`'s content |
| Name | Type | Default | Description |
| --------------- | ------------------------------------- | ------- | --------------------------------------------------------------------- |
| placement | `'top' / 'left' / 'right' / 'bottom'` | `top` | Where the `tooltip` appears |
| trigger | `'manual' / 'click' / 'hover'` | `hover` | How `tooltip` are triggered |
| mouseEnterDelay | `number` | `200` | Delay in seconds, before `tooltip` is shown on mouse enter, unit `ms` |
| mouseLeaveDelay | `number` | `200` | Delay in seconds, before `tooltip` is shown on mouse enter, unit `ms` |
| cls | `string` | `-` | Additional class |
| attrs | `Record<string, string>` | `{}` | Additional attributes |
| content | `string` | `-` | `tooltip`'s content |

## Tooltip Slots

Expand Down

0 comments on commit 424b812

Please sign in to comment.