Skip to content
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

feat: The tooltip and popover components add mouseEnterDelay and mouseLeaveDelay props #439

Merged
merged 2 commits into from
Apr 21, 2024
Merged
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
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
Loading