@king-design/intact 2.1.0 → 2.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/components/dropdown/dropdown.ts +35 -70
- package/components/dropdown/index.spec.ts +53 -4
- package/components/dropdown/item.ts +15 -5
- package/components/dropdown/menu.ts +3 -3
- package/components/dropdown/usePosition.ts +3 -0
- package/components/form/index.spec.ts +22 -1
- package/components/menu/demos/collapse.md +1 -1
- package/components/menu/index.spec.ts +9 -1
- package/components/menu/item.ts +7 -0
- package/components/pagination/index.spec.ts +23 -0
- package/components/pagination/index.ts +3 -1
- package/components/tooltip/content.ts +15 -1
- package/components/tooltip/content.vdt +6 -1
- package/components/tooltip/index.spec.ts +87 -1
- package/components/tooltip/styles.ts +1 -1
- package/components/tooltip/tooltip.ts +11 -0
- package/components/virtual.ts +98 -0
- package/es/components/dropdown/dropdown.d.ts +6 -5
- package/es/components/dropdown/dropdown.js +42 -69
- package/es/components/dropdown/index.spec.js +96 -17
- package/es/components/dropdown/item.d.ts +1 -1
- package/es/components/dropdown/item.js +16 -4
- package/es/components/dropdown/usePosition.js +4 -2
- package/es/components/form/index.spec.js +49 -2
- package/es/components/menu/index.spec.js +26 -15
- package/es/components/menu/item.d.ts +2 -0
- package/es/components/menu/item.js +5 -0
- package/es/components/pagination/index.js +4 -1
- package/es/components/pagination/index.spec.js +49 -0
- package/es/components/tooltip/content.d.ts +1 -0
- package/es/components/tooltip/content.js +18 -1
- package/es/components/tooltip/content.vdt.js +3 -1
- package/es/components/tooltip/index.spec.js +165 -0
- package/es/components/tooltip/styles.d.ts +22 -0
- package/es/components/tooltip/styles.js +1 -1
- package/es/components/tooltip/tooltip.d.ts +1 -0
- package/es/components/tooltip/tooltip.js +16 -1
- package/es/components/virtual.d.ts +8 -0
- package/es/components/virtual.js +126 -0
- package/es/index.d.ts +2 -2
- package/es/index.js +2 -2
- package/es/site/data/components/copy/demos/basic/index.d.ts +5 -0
- package/es/site/data/components/copy/demos/basic/index.js +17 -0
- package/es/site/data/components/copy/demos/basic/react.d.ts +4 -0
- package/es/site/data/components/copy/demos/basic/react.js +23 -0
- package/es/site/data/components/copy/demos/children/index.d.ts +6 -0
- package/es/site/data/components/copy/demos/children/index.js +18 -0
- package/es/site/data/components/copy/demos/children/react.d.ts +5 -0
- package/es/site/data/components/copy/demos/children/react.js +44 -0
- package/es/site/data/components/copy/index.d.ts +57 -0
- package/es/site/data/components/copy/index.js +42 -0
- package/es/site/data/components/dialog/demos/basic/react.js +1 -4
- package/es/site/data/components/icon/demos/disabled/index.d.ts +6 -0
- package/es/site/data/components/icon/demos/disabled/index.js +18 -0
- package/es/site/data/components/icon/demos/disabled/react.d.ts +5 -0
- package/es/site/data/components/icon/demos/disabled/react.js +33 -0
- package/es/site/data/components/input/demos/flat/index.d.ts +5 -0
- package/es/site/data/components/input/demos/flat/index.js +17 -0
- package/es/site/data/components/input/demos/flat/react.d.ts +4 -0
- package/es/site/data/components/input/demos/flat/react.js +29 -0
- package/es/site/data/components/input/demos/showCount/index.d.ts +5 -0
- package/es/site/data/components/input/demos/showCount/index.js +17 -0
- package/es/site/data/components/input/demos/showCount/react.d.ts +4 -0
- package/es/site/data/components/input/demos/showCount/react.js +33 -0
- package/es/site/data/components/menu/demos/collapse/index.js +1 -1
- package/es/site/data/components/menu/demos/collapse/react.js +1 -1
- package/es/site/data/components/pagination/demos/flat/index.d.ts +6 -0
- package/es/site/data/components/pagination/demos/flat/index.js +18 -0
- package/es/site/data/components/pagination/demos/flat/react.d.ts +5 -0
- package/es/site/data/components/pagination/demos/flat/react.js +41 -0
- package/es/site/data/components/popover/demos/basic/index.d.ts +7 -0
- package/es/site/data/components/popover/demos/basic/index.js +28 -0
- package/es/site/data/components/popover/demos/basic/react.d.ts +8 -0
- package/es/site/data/components/popover/demos/basic/react.js +59 -0
- package/es/site/data/components/popover/demos/button/index.d.ts +8 -0
- package/es/site/data/components/popover/demos/button/index.js +42 -0
- package/es/site/data/components/popover/demos/button/react.d.ts +8 -0
- package/es/site/data/components/popover/demos/button/react.js +73 -0
- package/es/site/data/components/popover/demos/content/index.d.ts +7 -0
- package/es/site/data/components/popover/demos/content/index.js +28 -0
- package/es/site/data/components/popover/demos/content/react.d.ts +6 -0
- package/es/site/data/components/popover/demos/content/react.js +43 -0
- package/es/site/data/components/popover/demos/text/index.d.ts +7 -0
- package/es/site/data/components/popover/demos/text/index.js +28 -0
- package/es/site/data/components/popover/demos/text/react.d.ts +6 -0
- package/es/site/data/components/popover/demos/text/react.js +36 -0
- package/es/site/data/components/popover/demos/type/index.d.ts +11 -0
- package/es/site/data/components/popover/demos/type/index.js +34 -0
- package/es/site/data/components/popover/demos/type/react.d.ts +11 -0
- package/es/site/data/components/popover/demos/type/react.js +58 -0
- package/es/site/data/components/popover/index.d.ts +57 -0
- package/es/site/data/components/popover/index.js +42 -0
- package/es/site/data/components/progress/demos/circleSize/index.d.ts +14 -0
- package/es/site/data/components/progress/demos/circleSize/index.js +43 -0
- package/es/site/data/components/progress/demos/circleSize/react.d.ts +14 -0
- package/es/site/data/components/progress/demos/circleSize/react.js +98 -0
- package/es/site/data/components/select/demos/draggable/index.d.ts +10 -0
- package/es/site/data/components/select/demos/draggable/index.js +24 -0
- package/es/site/data/components/select/demos/draggable/react.d.ts +10 -0
- package/es/site/data/components/select/demos/draggable/react.js +85 -0
- package/es/site/data/components/select/demos/flat/index.d.ts +5 -0
- package/es/site/data/components/select/demos/flat/index.js +17 -0
- package/es/site/data/components/select/demos/flat/react.d.ts +4 -0
- package/es/site/data/components/select/demos/flat/react.js +73 -0
- package/es/site/data/components/select/demos/inline/index.d.ts +5 -0
- package/es/site/data/components/select/demos/inline/index.js +17 -0
- package/es/site/data/components/select/demos/inline/react.d.ts +4 -0
- package/es/site/data/components/select/demos/inline/react.js +27 -0
- package/es/site/data/components/select/demos/nowrap/index.d.ts +5 -0
- package/es/site/data/components/select/demos/nowrap/index.js +17 -0
- package/es/site/data/components/select/demos/nowrap/react.d.ts +4 -0
- package/es/site/data/components/select/demos/nowrap/react.js +41 -0
- package/es/site/data/components/steps/demos/vertical/index.d.ts +14 -0
- package/es/site/data/components/steps/demos/vertical/index.js +40 -0
- package/es/site/data/components/steps/demos/vertical/react.d.ts +14 -0
- package/es/site/data/components/steps/demos/vertical/react.js +124 -0
- package/es/site/data/components/switch/demos/disabled/index.d.ts +6 -0
- package/es/site/data/components/switch/demos/disabled/index.js +18 -0
- package/es/site/data/components/switch/demos/disabled/react.d.ts +5 -0
- package/es/site/data/components/switch/demos/disabled/react.js +27 -0
- package/es/site/data/components/tabs/demos/scroll/index.d.ts +18 -0
- package/es/site/data/components/tabs/demos/scroll/index.js +87 -0
- package/es/site/data/components/tabs/demos/scroll/react.d.ts +18 -0
- package/es/site/data/components/tabs/demos/scroll/react.js +166 -0
- package/es/site/data/components/tag/demos/draggable/index.d.ts +11 -0
- package/es/site/data/components/tag/demos/draggable/index.js +24 -0
- package/es/site/data/components/tag/demos/draggable/react.d.ts +11 -0
- package/es/site/data/components/tag/demos/draggable/react.js +62 -0
- package/es/site/data/components/tag/demos/tags/index.d.ts +12 -0
- package/es/site/data/components/tag/demos/tags/index.js +39 -0
- package/es/site/data/components/tag/demos/tags/react.d.ts +12 -0
- package/es/site/data/components/tag/demos/tags/react.js +83 -0
- package/index.ts +2 -2
- package/package.json +4 -3
|
@@ -6,8 +6,10 @@ import ContentDemo from '~/components/tooltip/demos/content';
|
|
|
6
6
|
import ConfirmDemo from '~/components/tooltip/demos/confirm';
|
|
7
7
|
import AlwaysDemo from '~/components/tooltip/demos/always';
|
|
8
8
|
import {Tooltip} from './';
|
|
9
|
-
import {
|
|
9
|
+
import {Dialog} from '../dialog';
|
|
10
10
|
import {mount, unmount, dispatchEvent, getElement, wait} from '../../test/utils';
|
|
11
|
+
import { tooltip as tooltipTheme } from './styles';
|
|
12
|
+
import { Select, Option } from '../select';
|
|
11
13
|
|
|
12
14
|
describe('Tooltip', () => {
|
|
13
15
|
afterEach((done) => {
|
|
@@ -352,4 +354,88 @@ describe('Tooltip', () => {
|
|
|
352
354
|
console.log(JSON.stringify(content.getBoundingClientRect()));
|
|
353
355
|
expect(content.getBoundingClientRect().top < 0).to.be.true;
|
|
354
356
|
});
|
|
357
|
+
|
|
358
|
+
it('should add className', async () => {
|
|
359
|
+
class Demo extends Component {
|
|
360
|
+
static template = `
|
|
361
|
+
const Tooltip = this.Tooltip;
|
|
362
|
+
<div>
|
|
363
|
+
<Tooltip content="hello" class="a">
|
|
364
|
+
<div ref="test" class="b">test</div>
|
|
365
|
+
</Tooltip>
|
|
366
|
+
</div>
|
|
367
|
+
`;
|
|
368
|
+
Tooltip = Tooltip;
|
|
369
|
+
}
|
|
370
|
+
|
|
371
|
+
const [instance, element] = mount(Demo);
|
|
372
|
+
const trigger = instance.refs.test;
|
|
373
|
+
expect(trigger.className).to.eql('b a');
|
|
374
|
+
|
|
375
|
+
dispatchEvent(trigger, 'mouseenter');
|
|
376
|
+
await wait();
|
|
377
|
+
const dropdown = getElement('.k-tooltip-content')!;
|
|
378
|
+
expect(dropdown.classList.contains('a')).to.be.true;
|
|
379
|
+
});
|
|
380
|
+
|
|
381
|
+
it('should fix the width in small container', async () => {
|
|
382
|
+
class Demo extends Component {
|
|
383
|
+
static template = `
|
|
384
|
+
const {Tooltip, Dialog} = this;
|
|
385
|
+
<div style="text-align: right; position: relative; width: 300px;">
|
|
386
|
+
<Tooltip content="这是一段很长的描述文字,这是一段很长的描述文字" container={dom => dom}>
|
|
387
|
+
<span class="trigger">test</span>
|
|
388
|
+
</Tooltip>
|
|
389
|
+
</div>
|
|
390
|
+
`
|
|
391
|
+
private Tooltip = Tooltip;
|
|
392
|
+
private Dialog = Dialog;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
const [instance, element] = mount(Demo);
|
|
396
|
+
const trigger = element.querySelector<HTMLDivElement>('.trigger')!;
|
|
397
|
+
const expecedWidth = parseInt(tooltipTheme.maxWidth);
|
|
398
|
+
|
|
399
|
+
dispatchEvent(trigger, 'mouseenter');
|
|
400
|
+
await wait();
|
|
401
|
+
const content = getElement('.k-tooltip-content')!;
|
|
402
|
+
const width = content.offsetWidth;
|
|
403
|
+
expect(width).to.eql(expecedWidth);
|
|
404
|
+
|
|
405
|
+
dispatchEvent(trigger, 'mouseleave');
|
|
406
|
+
await wait();
|
|
407
|
+
dispatchEvent(trigger, 'mouseenter');
|
|
408
|
+
await wait();
|
|
409
|
+
const newWidth = content.offsetWidth;
|
|
410
|
+
expect(newWidth).to.eql(width);
|
|
411
|
+
});
|
|
412
|
+
|
|
413
|
+
it('should not impact select when wrap select with tooltip', async () => {
|
|
414
|
+
class Demo extends Component {
|
|
415
|
+
static template = `
|
|
416
|
+
const {Tooltip, Select, Option} = this;
|
|
417
|
+
<Tooltip>
|
|
418
|
+
<Select>
|
|
419
|
+
<Option value="1">Option 1</Option>
|
|
420
|
+
<Option value="2">Option 2</Option>
|
|
421
|
+
</Select>
|
|
422
|
+
</Tooltip>
|
|
423
|
+
`
|
|
424
|
+
private Tooltip = Tooltip;
|
|
425
|
+
private Select = Select;
|
|
426
|
+
private Option = Option;
|
|
427
|
+
}
|
|
428
|
+
|
|
429
|
+
const [instance, element] = mount(Demo);
|
|
430
|
+
dispatchEvent(element, 'mouseenter');
|
|
431
|
+
await wait();
|
|
432
|
+
dispatchEvent(element, 'click');
|
|
433
|
+
await wait();
|
|
434
|
+
|
|
435
|
+
const menu = getElement(".k-select-menu")!;
|
|
436
|
+
dispatchEvent(element, 'mouseleave');
|
|
437
|
+
await wait(500);
|
|
438
|
+
|
|
439
|
+
expect(menu.style.display).to.eql('');
|
|
440
|
+
});
|
|
355
441
|
});
|
|
@@ -49,6 +49,7 @@ const defaults = (): Partial<TooltipProps> => ({
|
|
|
49
49
|
showArrow: true,
|
|
50
50
|
theme: 'dark',
|
|
51
51
|
position: {my: 'center bottom-10', at: 'center top', collision: 'flipfit'},
|
|
52
|
+
collison: 'flipfit',
|
|
52
53
|
hoverable: false,
|
|
53
54
|
always: false,
|
|
54
55
|
confirm: false,
|
|
@@ -72,12 +73,22 @@ export class Tooltip<
|
|
|
72
73
|
static defaults = defaults;
|
|
73
74
|
static events = events;
|
|
74
75
|
|
|
76
|
+
show(shouldFocus: boolean = false) {
|
|
77
|
+
if (this.get('disabled')) return;
|
|
78
|
+
|
|
79
|
+
clearTimeout(this.timer);
|
|
80
|
+
this.set('value', true);
|
|
81
|
+
}
|
|
82
|
+
|
|
75
83
|
hide(immediately: boolean) {
|
|
76
84
|
if (this.get('always')) return;
|
|
77
85
|
|
|
78
86
|
if (this.get('hoverable')) {
|
|
79
87
|
return super.hide(immediately);
|
|
80
88
|
}
|
|
89
|
+
// tooltip can show any number sub-tooltips, we should not close the showed tooltip
|
|
90
|
+
// #885
|
|
91
|
+
this.showedDropdown = null;
|
|
81
92
|
super.hide(true);
|
|
82
93
|
}
|
|
83
94
|
}
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Component,
|
|
3
|
+
VNode,
|
|
4
|
+
directClone,
|
|
5
|
+
createVNode,
|
|
6
|
+
} from 'intact';
|
|
7
|
+
import { isTextChildren } from './utils';
|
|
8
|
+
import { EMPTY_OBJ, isFunction, hasOwn } from 'intact-shared';
|
|
9
|
+
import { cx } from '@emotion/css';
|
|
10
|
+
|
|
11
|
+
const reactEventReg = /on[A-Z]/;
|
|
12
|
+
|
|
13
|
+
export class Virtual extends Component<any> {
|
|
14
|
+
static template(this: Virtual) {
|
|
15
|
+
const { children, ...props } = this.get();
|
|
16
|
+
|
|
17
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
18
|
+
if (!children || (Array.isArray(children) && children.length !== 1)) {
|
|
19
|
+
throw new Error('Component must receive one children');
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const vNode = Array.isArray(children) ? children[0] : children;
|
|
24
|
+
const clonedVNode = isTextChildren(vNode)
|
|
25
|
+
? createVNode('span', null, vNode)
|
|
26
|
+
: directClone(vNode as VNode);
|
|
27
|
+
|
|
28
|
+
const vNodeProps = this.vNodeProps = this.getVNodeProps(clonedVNode.props || EMPTY_OBJ);
|
|
29
|
+
const eventProps = this.getEventProps();
|
|
30
|
+
|
|
31
|
+
// merge className
|
|
32
|
+
let className = clonedVNode.className || vNodeProps.className;
|
|
33
|
+
className = cx({
|
|
34
|
+
[className!]: !!className,
|
|
35
|
+
[props.className!]: !!props.className,
|
|
36
|
+
});
|
|
37
|
+
|
|
38
|
+
clonedVNode.props = { ...props, ...vNodeProps, ...eventProps, className };
|
|
39
|
+
clonedVNode.className = className;
|
|
40
|
+
|
|
41
|
+
return clonedVNode;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
private vNodeProps: any = null;
|
|
45
|
+
|
|
46
|
+
private getVNodeProps(props: any) {
|
|
47
|
+
const vnode = props.vnode;
|
|
48
|
+
|
|
49
|
+
if (!vnode) return props;
|
|
50
|
+
|
|
51
|
+
// maybe we render the intact component in react slot property, in this case
|
|
52
|
+
// the $isReact is false. so use the vnode $$typeof field as gauge
|
|
53
|
+
if (vnode.$$typeof || vnode.__v_isVNode /* vue3 vnode */) {
|
|
54
|
+
const _props = vnode.props;
|
|
55
|
+
if (!_props) return props;
|
|
56
|
+
|
|
57
|
+
const events: Record<string, Function> = {};
|
|
58
|
+
for (let key in _props) {
|
|
59
|
+
if (reactEventReg.test(key)) {
|
|
60
|
+
events[`ev-${key.substring(2).toLowerCase()}`] = _props[key];
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
return {...props, ...events, className: _props.className || _props.class /* vue-next */};
|
|
65
|
+
} else if (hasOwn.call(vnode, 'componentOptions') /* vue2 vnode */) {
|
|
66
|
+
const data = vnode.data;
|
|
67
|
+
const on = data && data.on || EMPTY_OBJ;
|
|
68
|
+
const events: Record<string, Function> = {};
|
|
69
|
+
for (let key in on) {
|
|
70
|
+
events[`ev-${key}`] = on[key];
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
return {...props, ...events};
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return props;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
private getEventProps() {
|
|
80
|
+
const props: Record<string, Function> = {};
|
|
81
|
+
|
|
82
|
+
for (let prop in this.get()) {
|
|
83
|
+
if (prop.startsWith('ev-')) {
|
|
84
|
+
props[prop] = (e: MouseEvent) => this.callEvent(prop, e);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
return props;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
private callEvent(name: string, e: MouseEvent) {
|
|
93
|
+
const callback = this.vNodeProps[name];
|
|
94
|
+
const callbackOnVirtual = this.get<Function>(name);
|
|
95
|
+
if (isFunction(callback)) callback(e);
|
|
96
|
+
if (isFunction(callbackOnVirtual)) callbackOnVirtual(e);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
@@ -3,6 +3,7 @@ import { Options, Feedback } from '../position';
|
|
|
3
3
|
import { Portal, PortalProps } from '../portal';
|
|
4
4
|
import { FeedbackCallback } from './usePosition';
|
|
5
5
|
import type { Events } from '../types';
|
|
6
|
+
import { Virtual } from '../virtual';
|
|
6
7
|
export declare type Position = Options;
|
|
7
8
|
export declare type PositionShorthand = 'left' | 'bottom' | 'right' | 'top';
|
|
8
9
|
export declare const DROPDOWN = "Dropdown";
|
|
@@ -12,6 +13,7 @@ export interface DropdownProps {
|
|
|
12
13
|
disabled?: boolean;
|
|
13
14
|
value?: boolean;
|
|
14
15
|
position?: Position | 'left' | 'bottom' | 'right' | 'top';
|
|
16
|
+
collison?: Position['collision'];
|
|
15
17
|
of?: 'self' | 'parent' | Event;
|
|
16
18
|
container?: PortalProps['container'];
|
|
17
19
|
}
|
|
@@ -21,6 +23,8 @@ export interface DropdownEvents {
|
|
|
21
23
|
hide: [];
|
|
22
24
|
mouseenter: [MouseEvent];
|
|
23
25
|
mouseleave: [MouseEvent];
|
|
26
|
+
click: [MouseEvent];
|
|
27
|
+
contextmenu: [MouseEvent];
|
|
24
28
|
positioned: [Feedback];
|
|
25
29
|
}
|
|
26
30
|
export interface DropdownBlocks {
|
|
@@ -30,7 +34,7 @@ export declare class Dropdown<T extends DropdownProps = DropdownProps, E extends
|
|
|
30
34
|
static typeDefs: Required<TypeDefs<DropdownProps>>;
|
|
31
35
|
static defaults: () => Partial<DropdownProps>;
|
|
32
36
|
static events: Events<DropdownEvents>;
|
|
33
|
-
static template: (this: Dropdown) => (VNode<
|
|
37
|
+
static template: (this: Dropdown) => (VNode<typeof Virtual> | VNode<typeof Portal>)[];
|
|
34
38
|
menuVNode: VNode | null;
|
|
35
39
|
dropdown: Dropdown | null;
|
|
36
40
|
rootDropdown: Dropdown | null;
|
|
@@ -41,8 +45,7 @@ export declare class Dropdown<T extends DropdownProps = DropdownProps, E extends
|
|
|
41
45
|
value: boolean;
|
|
42
46
|
};
|
|
43
47
|
};
|
|
44
|
-
|
|
45
|
-
private triggerProps;
|
|
48
|
+
protected timer: number | undefined;
|
|
46
49
|
init(): void;
|
|
47
50
|
show(shouldFocus?: boolean): void;
|
|
48
51
|
hide(immediately?: boolean): void;
|
|
@@ -52,6 +55,4 @@ export declare class Dropdown<T extends DropdownProps = DropdownProps, E extends
|
|
|
52
55
|
private onContextMenu;
|
|
53
56
|
private onLeave;
|
|
54
57
|
private initEventCallbacks;
|
|
55
|
-
private callOriginalCallback;
|
|
56
|
-
private normalizeTriggerProps;
|
|
57
58
|
}
|
|
@@ -3,14 +3,15 @@ import _inheritsLoose from "@babel/runtime-corejs3/helpers/inheritsLoose";
|
|
|
3
3
|
import _concatInstanceProperty from "@babel/runtime-corejs3/core-js/instance/concat";
|
|
4
4
|
import _filterInstanceProperty from "@babel/runtime-corejs3/core-js/instance/filter";
|
|
5
5
|
import { __decorate } from "tslib";
|
|
6
|
-
import { Component, createVNode as h,
|
|
7
|
-
import { bind,
|
|
8
|
-
import {
|
|
6
|
+
import { Component, createVNode as h, provide, inject, findDomFromVNode, nextTick } from 'intact';
|
|
7
|
+
import { bind, getRestProps } from '../utils';
|
|
8
|
+
import { noop } from 'intact-shared';
|
|
9
9
|
import { cx } from '@emotion/css';
|
|
10
10
|
import { useDocumentClick, containsOrEqual } from '../../hooks/useDocumentClick';
|
|
11
11
|
import { Portal } from '../portal';
|
|
12
12
|
import { useShowHideEvents } from '../../hooks/useShowHideEvents';
|
|
13
13
|
import { usePosition } from './usePosition';
|
|
14
|
+
import { Virtual } from '../virtual';
|
|
14
15
|
export var DROPDOWN = 'Dropdown';
|
|
15
16
|
export var ROOT_DROPDOWN = 'RootDropdown';
|
|
16
17
|
var typeDefs = {
|
|
@@ -20,13 +21,15 @@ var typeDefs = {
|
|
|
20
21
|
position: [Object, 'left', 'bottom', 'right', 'top'],
|
|
21
22
|
// Event is undefined in NodeJs
|
|
22
23
|
of: ['self', 'parent', typeof Event === 'undefined' ? undefined : Event],
|
|
23
|
-
container: [String, Function]
|
|
24
|
+
container: [String, Function],
|
|
25
|
+
collison: ['none', 'fit', 'flip', 'flipfit', Array]
|
|
24
26
|
};
|
|
25
27
|
|
|
26
28
|
var defaults = function defaults() {
|
|
27
29
|
return {
|
|
28
30
|
trigger: 'hover',
|
|
29
|
-
of: 'self'
|
|
31
|
+
of: 'self',
|
|
32
|
+
value: false
|
|
30
33
|
};
|
|
31
34
|
};
|
|
32
35
|
|
|
@@ -36,6 +39,8 @@ var events = {
|
|
|
36
39
|
hide: true,
|
|
37
40
|
mouseenter: true,
|
|
38
41
|
mouseleave: true,
|
|
42
|
+
click: true,
|
|
43
|
+
contextmenu: true,
|
|
39
44
|
positioned: true
|
|
40
45
|
};
|
|
41
46
|
export var Dropdown = /*#__PURE__*/function (_Component) {
|
|
@@ -57,7 +62,6 @@ export var Dropdown = /*#__PURE__*/function (_Component) {
|
|
|
57
62
|
_this.showedDropdown = null;
|
|
58
63
|
_this.positionHook = usePosition();
|
|
59
64
|
_this.timer = undefined;
|
|
60
|
-
_this.triggerProps = null;
|
|
61
65
|
return _this;
|
|
62
66
|
}
|
|
63
67
|
|
|
@@ -95,7 +99,13 @@ export var Dropdown = /*#__PURE__*/function (_Component) {
|
|
|
95
99
|
|
|
96
100
|
if (this.get('disabled')) return;
|
|
97
101
|
clearTimeout(this.timer);
|
|
98
|
-
this.set('value', true);
|
|
102
|
+
this.set('value', true); // should show parent dropdown
|
|
103
|
+
|
|
104
|
+
var parentDropdown = this.dropdown;
|
|
105
|
+
|
|
106
|
+
if (parentDropdown) {
|
|
107
|
+
parentDropdown.show();
|
|
108
|
+
}
|
|
99
109
|
|
|
100
110
|
if (shouldFocus) {
|
|
101
111
|
nextTick(function () {
|
|
@@ -113,10 +123,16 @@ export var Dropdown = /*#__PURE__*/function (_Component) {
|
|
|
113
123
|
|
|
114
124
|
if (this.get('disabled')) return;
|
|
115
125
|
if (!this.get('value')) return;
|
|
126
|
+
var showedDropdown = this.showedDropdown;
|
|
127
|
+
|
|
128
|
+
if (showedDropdown) {
|
|
129
|
+
showedDropdown.hide(immediately);
|
|
130
|
+
}
|
|
116
131
|
|
|
117
132
|
if (immediately) {
|
|
118
133
|
this.set('value', false);
|
|
119
134
|
} else {
|
|
135
|
+
clearTimeout(this.timer);
|
|
120
136
|
this.timer = window.setTimeout(function () {
|
|
121
137
|
_this4.set('value', false);
|
|
122
138
|
}, 200);
|
|
@@ -136,23 +152,24 @@ export var Dropdown = /*#__PURE__*/function (_Component) {
|
|
|
136
152
|
};
|
|
137
153
|
|
|
138
154
|
_proto.onEnter = function onEnter(e) {
|
|
139
|
-
this.callOriginalCallback(e.type === 'click' ? 'ev-click' : 'ev-mouseenter', e);
|
|
140
155
|
this.show();
|
|
156
|
+
this.trigger(e.type, e);
|
|
141
157
|
};
|
|
142
158
|
|
|
143
159
|
_proto.onContextMenu = function onContextMenu(e) {
|
|
144
|
-
this.callOriginalCallback('ev-contextmenu', e);
|
|
145
160
|
e.preventDefault();
|
|
146
161
|
this.set('of', e);
|
|
147
162
|
this.show();
|
|
163
|
+
this.trigger('contextmenu', e);
|
|
148
164
|
};
|
|
149
165
|
|
|
150
166
|
_proto.onLeave = function onLeave(e) {
|
|
151
|
-
this.callOriginalCallback('ev-mouseleave', e);
|
|
152
167
|
this.hide();
|
|
168
|
+
this.trigger(e.type, e);
|
|
153
169
|
};
|
|
154
170
|
|
|
155
|
-
_proto.initEventCallbacks = function initEventCallbacks(
|
|
171
|
+
_proto.initEventCallbacks = function initEventCallbacks() {
|
|
172
|
+
var trigger = this.get('trigger');
|
|
156
173
|
var props = {};
|
|
157
174
|
|
|
158
175
|
switch (trigger) {
|
|
@@ -179,51 +196,6 @@ export var Dropdown = /*#__PURE__*/function (_Component) {
|
|
|
179
196
|
return props;
|
|
180
197
|
};
|
|
181
198
|
|
|
182
|
-
_proto.callOriginalCallback = function callOriginalCallback(name, e) {
|
|
183
|
-
var callback = this.triggerProps[name];
|
|
184
|
-
var callbackOnDropdown = this.get(name);
|
|
185
|
-
if (isFunction(callback)) callback(e);
|
|
186
|
-
if (isFunction(callbackOnDropdown)) callbackOnDropdown(e);
|
|
187
|
-
};
|
|
188
|
-
|
|
189
|
-
_proto.normalizeTriggerProps = function normalizeTriggerProps(props) {
|
|
190
|
-
// if use kpc in react or vue, normalize props by Wrapper.props.vnode;
|
|
191
|
-
var vnode = props.vnode;
|
|
192
|
-
if (!vnode) return props; // maybe we render the intact component in react slot property, in this case
|
|
193
|
-
// the $isReact is false. so use the vnode $$typeof field as gauge
|
|
194
|
-
|
|
195
|
-
if (vnode.$$typeof || this.$isVueNext) {
|
|
196
|
-
var _props = vnode.props;
|
|
197
|
-
if (!_props) return props;
|
|
198
|
-
return {
|
|
199
|
-
vnode: vnode,
|
|
200
|
-
'ev-click': _props.onClick,
|
|
201
|
-
'ev-mouseenter': _props.onMouseEnter,
|
|
202
|
-
'ev-mouseleave': _props.onMouseLeave,
|
|
203
|
-
'ev-contextmenu': _props.onContextMenu,
|
|
204
|
-
className: _props.className || _props.class
|
|
205
|
-
/* vue-next */
|
|
206
|
-
|
|
207
|
-
};
|
|
208
|
-
} else if (this.$isVue) {
|
|
209
|
-
var data = vnode.data;
|
|
210
|
-
var on = data && data.on || EMPTY_OBJ;
|
|
211
|
-
var ret = {
|
|
212
|
-
vnode: vnode
|
|
213
|
-
};
|
|
214
|
-
['click', 'mouseenter', 'mouseleave', 'contextmenu'].forEach(function (event) {
|
|
215
|
-
var method = on[event];
|
|
216
|
-
|
|
217
|
-
if (method) {
|
|
218
|
-
ret["ev-" + event] = method;
|
|
219
|
-
}
|
|
220
|
-
});
|
|
221
|
-
return ret;
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
return props;
|
|
225
|
-
};
|
|
226
|
-
|
|
227
199
|
return Dropdown;
|
|
228
200
|
}(Component);
|
|
229
201
|
Dropdown.$doubleVNodes = true;
|
|
@@ -253,21 +225,22 @@ Dropdown.template = function () {
|
|
|
253
225
|
var _children = children,
|
|
254
226
|
trigger = _children[0],
|
|
255
227
|
menu = _children[1];
|
|
256
|
-
var
|
|
257
|
-
|
|
258
|
-
var
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
});
|
|
266
|
-
clonedTrigger.className = className;
|
|
228
|
+
var props = this.initEventCallbacks();
|
|
229
|
+
|
|
230
|
+
var _this$get = this.get(),
|
|
231
|
+
className = _this$get.className,
|
|
232
|
+
value = _this$get.value,
|
|
233
|
+
container = _this$get.container;
|
|
234
|
+
|
|
235
|
+
className = cx((_cx = {
|
|
236
|
+
'k-dropdown-open': value
|
|
237
|
+
}, _cx[className] = !!className, _cx));
|
|
267
238
|
this.menuVNode = menu;
|
|
268
|
-
return [
|
|
239
|
+
return [h(Virtual, _extends({}, props, getRestProps(this), {
|
|
240
|
+
className: className
|
|
241
|
+
}), trigger), h(Portal, {
|
|
269
242
|
children: menu,
|
|
270
|
-
container:
|
|
243
|
+
container: container
|
|
271
244
|
})];
|
|
272
245
|
};
|
|
273
246
|
|
|
@@ -8,6 +8,7 @@ import { Dropdown, DropdownMenu, DropdownItem } from '../dropdown';
|
|
|
8
8
|
import BasicDemo from '~/components/dropdown/demos/basic';
|
|
9
9
|
import NestedDemo from '~/components/dropdown/demos/nested';
|
|
10
10
|
import ContextMenuDemo from '~/components/dropdown/demos/contextmenu';
|
|
11
|
+
import TooltipDemo from '~/components/dropdown/demos/tooltip';
|
|
11
12
|
describe('Dropdown', function () {
|
|
12
13
|
afterEach(function (done) {
|
|
13
14
|
unmount();
|
|
@@ -113,42 +114,61 @@ describe('Dropdown', function () {
|
|
|
113
114
|
}, _callee2);
|
|
114
115
|
})));
|
|
115
116
|
it('nested dropdown', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee3() {
|
|
116
|
-
var _mount3, instance, element, dropdown, _dropdown$querySelect, hoverItem, clickItem, clickSubDropdown, hoverSubDropdown;
|
|
117
|
+
var _mount3, instance, element, dropdown, _dropdown$querySelect, hoverItem, clickItem, clickSubDropdown, hoverSubDropdown, _hoverSubDropdown$que, hoverItem1, hoverSubDropdown1, _hoverSubDropdown1$qu, hoverItem2, hoverSubDropdown2;
|
|
117
118
|
|
|
118
119
|
return _regeneratorRuntime.wrap(function _callee3$(_context4) {
|
|
119
120
|
while (1) {
|
|
120
121
|
switch (_context4.prev = _context4.next) {
|
|
121
122
|
case 0:
|
|
123
|
+
this.timeout(0);
|
|
122
124
|
_mount3 = mount(NestedDemo), instance = _mount3[0], element = _mount3[1];
|
|
123
125
|
element.firstElementChild.click();
|
|
124
|
-
_context4.next =
|
|
126
|
+
_context4.next = 5;
|
|
125
127
|
return wait();
|
|
126
128
|
|
|
127
|
-
case
|
|
129
|
+
case 5:
|
|
128
130
|
dropdown = getElement('.k-dropdown-menu');
|
|
129
131
|
_dropdown$querySelect = dropdown.querySelectorAll(':scope > .k-dropdown-item'), hoverItem = _dropdown$querySelect[3], clickItem = _dropdown$querySelect[4];
|
|
130
132
|
clickItem.click();
|
|
131
|
-
_context4.next =
|
|
133
|
+
_context4.next = 10;
|
|
132
134
|
return wait(500);
|
|
133
135
|
|
|
134
|
-
case
|
|
136
|
+
case 10:
|
|
135
137
|
clickSubDropdown = getElement('.k-dropdown-menu');
|
|
136
138
|
expect(clickSubDropdown.innerHTML).to.matchSnapshot(); // should hide last sub-dropdown and show next
|
|
137
139
|
|
|
138
140
|
dispatchEvent(hoverItem, 'mouseenter');
|
|
139
|
-
_context4.next =
|
|
141
|
+
_context4.next = 15;
|
|
140
142
|
return wait(500);
|
|
141
143
|
|
|
142
|
-
case
|
|
144
|
+
case 15:
|
|
143
145
|
hoverSubDropdown = getElement('.k-dropdown-menu');
|
|
144
146
|
expect(hoverSubDropdown.innerHTML).to.matchSnapshot();
|
|
147
|
+
_hoverSubDropdown$que = hoverSubDropdown.querySelectorAll('.k-dropdown-item'), hoverItem1 = _hoverSubDropdown$que[0];
|
|
148
|
+
dispatchEvent(hoverItem, 'mouseleave');
|
|
149
|
+
dispatchEvent(hoverItem1, 'mouseenter');
|
|
150
|
+
_context4.next = 22;
|
|
151
|
+
return wait(500);
|
|
145
152
|
|
|
146
|
-
case
|
|
153
|
+
case 22:
|
|
154
|
+
hoverSubDropdown1 = getElement('.k-dropdown-menu');
|
|
155
|
+
expect(hoverSubDropdown1.textContent).to.eql('item 1item 2');
|
|
156
|
+
_hoverSubDropdown1$qu = hoverSubDropdown1.querySelectorAll('.k-dropdown-item'), hoverItem2 = _hoverSubDropdown1$qu[0];
|
|
157
|
+
dispatchEvent(hoverItem1, 'mouseleave');
|
|
158
|
+
dispatchEvent(hoverItem2, 'mouseenter');
|
|
159
|
+
_context4.next = 29;
|
|
160
|
+
return wait(1000);
|
|
161
|
+
|
|
162
|
+
case 29:
|
|
163
|
+
hoverSubDropdown2 = getElement('.k-dropdown-menu');
|
|
164
|
+
expect(hoverSubDropdown2 === hoverSubDropdown1).to.be.true;
|
|
165
|
+
|
|
166
|
+
case 31:
|
|
147
167
|
case "end":
|
|
148
168
|
return _context4.stop();
|
|
149
169
|
}
|
|
150
170
|
}
|
|
151
|
-
}, _callee3);
|
|
171
|
+
}, _callee3, this);
|
|
152
172
|
})));
|
|
153
173
|
it('hide on click document', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee4() {
|
|
154
174
|
var _mount4, instance, element;
|
|
@@ -483,7 +503,7 @@ describe('Dropdown', function () {
|
|
|
483
503
|
}
|
|
484
504
|
}, _callee9);
|
|
485
505
|
})));
|
|
486
|
-
it('trigger
|
|
506
|
+
it('focus trigger type', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee10() {
|
|
487
507
|
var Demo, _mount9, instance;
|
|
488
508
|
|
|
489
509
|
return _regeneratorRuntime.wrap(function _callee10$(_context14) {
|
|
@@ -506,39 +526,98 @@ describe('Dropdown', function () {
|
|
|
506
526
|
_this4.Dropdown = Dropdown;
|
|
507
527
|
_this4.DropdownItem = DropdownItem;
|
|
508
528
|
_this4.DropdownMenu = DropdownMenu;
|
|
529
|
+
_this4.onFocus = sinon.spy(function (e) {
|
|
530
|
+
return console.log(e);
|
|
531
|
+
});
|
|
509
532
|
return _this4;
|
|
510
533
|
}
|
|
511
534
|
|
|
512
535
|
return Demo;
|
|
513
536
|
}(Component);
|
|
514
537
|
|
|
515
|
-
Demo.template = "\n const {Dropdown, DropdownMenu, DropdownItem} = this;\n <div>\n <Dropdown trigger=\"focus\">\n <input ref=\"trigger\" />\n <DropdownMenu>\n <DropdownItem>test1</DropdownItem>\n <DropdownItem>test2</DropdownItem>\n </DropdownMenu>\n </Dropdown>\n </div>\n ";
|
|
538
|
+
Demo.template = "\n const {Dropdown, DropdownMenu, DropdownItem} = this;\n <div>\n <Dropdown trigger=\"focus\">\n <input ref=\"trigger\" ev-focusin={this.onFocus} />\n <DropdownMenu>\n <DropdownItem>test1</DropdownItem>\n <DropdownItem>test2</DropdownItem>\n </DropdownMenu>\n </Dropdown>\n </div>\n ";
|
|
516
539
|
_mount9 = mount(Demo), instance = _mount9[0];
|
|
517
540
|
dispatchEvent(instance.refs.trigger, 'focusin');
|
|
518
541
|
_context14.next = 6;
|
|
519
542
|
return wait(500);
|
|
520
543
|
|
|
521
544
|
case 6:
|
|
522
|
-
expect(getElement('.k-dropdown-menu')).to.be.exist;
|
|
545
|
+
expect(getElement('.k-dropdown-menu')).to.be.exist;
|
|
546
|
+
expect(instance.onFocus.callCount).to.eql(1); // clicking anywhere should not hide menu
|
|
523
547
|
|
|
524
548
|
dispatchEvent(document, 'click');
|
|
525
|
-
_context14.next =
|
|
549
|
+
_context14.next = 11;
|
|
526
550
|
return wait(500);
|
|
527
551
|
|
|
528
|
-
case
|
|
552
|
+
case 11:
|
|
529
553
|
expect(getElement('.k-dropdown-menu')).to.be.exist;
|
|
530
554
|
dispatchEvent(instance.refs.trigger, 'focusout');
|
|
531
|
-
_context14.next =
|
|
555
|
+
_context14.next = 15;
|
|
532
556
|
return wait(700);
|
|
533
557
|
|
|
534
|
-
case
|
|
558
|
+
case 15:
|
|
535
559
|
expect(getElement('.k-dropdown-menu')).to.not.be.exist;
|
|
536
560
|
|
|
537
|
-
case
|
|
561
|
+
case 16:
|
|
538
562
|
case "end":
|
|
539
563
|
return _context14.stop();
|
|
540
564
|
}
|
|
541
565
|
}
|
|
542
566
|
}, _callee10);
|
|
543
567
|
})));
|
|
568
|
+
it('wrap by tooltip', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee11() {
|
|
569
|
+
var _mount10, instance, element, dropdown, _dropdown$querySelect4, item1, item2, item3, item4;
|
|
570
|
+
|
|
571
|
+
return _regeneratorRuntime.wrap(function _callee11$(_context15) {
|
|
572
|
+
while (1) {
|
|
573
|
+
switch (_context15.prev = _context15.next) {
|
|
574
|
+
case 0:
|
|
575
|
+
_mount10 = mount(TooltipDemo), instance = _mount10[0], element = _mount10[1];
|
|
576
|
+
dispatchEvent(element.firstChild, 'mouseenter');
|
|
577
|
+
_context15.next = 4;
|
|
578
|
+
return wait();
|
|
579
|
+
|
|
580
|
+
case 4:
|
|
581
|
+
dropdown = getElement('.k-dropdown-menu');
|
|
582
|
+
_dropdown$querySelect4 = dropdown.querySelectorAll('.k-dropdown-item'), item1 = _dropdown$querySelect4[0], item2 = _dropdown$querySelect4[1], item3 = _dropdown$querySelect4[2], item4 = _dropdown$querySelect4[3];
|
|
583
|
+
dispatchEvent(item1, 'mouseenter');
|
|
584
|
+
_context15.next = 9;
|
|
585
|
+
return wait();
|
|
586
|
+
|
|
587
|
+
case 9:
|
|
588
|
+
expect(getElement('.k-tooltip-content').textContent).to.eql('item 1');
|
|
589
|
+
dispatchEvent(item1, 'mouseleave');
|
|
590
|
+
dispatchEvent(item3, 'mouseenter');
|
|
591
|
+
_context15.next = 14;
|
|
592
|
+
return wait();
|
|
593
|
+
|
|
594
|
+
case 14:
|
|
595
|
+
expect(getElement('.k-tooltip-content').textContent).to.eql('disabled');
|
|
596
|
+
dispatchEvent(item3, 'mouseleave');
|
|
597
|
+
dispatchEvent(item4, 'mouseenter');
|
|
598
|
+
_context15.next = 19;
|
|
599
|
+
return wait();
|
|
600
|
+
|
|
601
|
+
case 19:
|
|
602
|
+
expect(getElement('.k-tooltip-content').textContent).to.eql('This is a nested Dropdown.');
|
|
603
|
+
dispatchEvent(item4, 'click');
|
|
604
|
+
_context15.next = 23;
|
|
605
|
+
return wait();
|
|
606
|
+
|
|
607
|
+
case 23:
|
|
608
|
+
expect(getElement('.k-dropdown-menu').textContent).to.eql('item 1item 2');
|
|
609
|
+
dispatchEvent(item4, 'mouseleave');
|
|
610
|
+
_context15.next = 27;
|
|
611
|
+
return wait(800);
|
|
612
|
+
|
|
613
|
+
case 27:
|
|
614
|
+
expect(getElement('.k-dropdown-menu')).to.not.be.exist;
|
|
615
|
+
|
|
616
|
+
case 28:
|
|
617
|
+
case "end":
|
|
618
|
+
return _context15.stop();
|
|
619
|
+
}
|
|
620
|
+
}
|
|
621
|
+
}, _callee11);
|
|
622
|
+
})));
|
|
544
623
|
});
|