@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
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
createVNode,
|
|
12
12
|
nextTick,
|
|
13
13
|
} from 'intact';
|
|
14
|
-
import {bind, isTextChildren} from '../utils';
|
|
14
|
+
import {bind, isTextChildren, getRestProps} from '../utils';
|
|
15
15
|
import {EMPTY_OBJ, isFunction, noop} from 'intact-shared';
|
|
16
16
|
import {Options, position, Feedback} from '../position';
|
|
17
17
|
import {cx} from '@emotion/css';
|
|
@@ -21,6 +21,7 @@ import {Portal, PortalProps} from '../portal';
|
|
|
21
21
|
import {useShowHideEvents} from '../../hooks/useShowHideEvents';
|
|
22
22
|
import {usePosition, FeedbackCallback} from './usePosition';
|
|
23
23
|
import type {Events} from '../types';
|
|
24
|
+
import { Virtual } from '../virtual';
|
|
24
25
|
|
|
25
26
|
export type Position = Options
|
|
26
27
|
export type PositionShorthand = 'left' | 'bottom' | 'right' | 'top'
|
|
@@ -35,6 +36,7 @@ export interface DropdownProps {
|
|
|
35
36
|
disabled?: boolean
|
|
36
37
|
value?: boolean
|
|
37
38
|
position?: Position | 'left' | 'bottom' | 'right' | 'top'
|
|
39
|
+
collison?: Position['collision']
|
|
38
40
|
of?: 'self' | 'parent' | Event
|
|
39
41
|
container?: PortalProps['container']
|
|
40
42
|
}
|
|
@@ -45,6 +47,8 @@ export interface DropdownEvents {
|
|
|
45
47
|
hide: []
|
|
46
48
|
mouseenter: [MouseEvent]
|
|
47
49
|
mouseleave: [MouseEvent]
|
|
50
|
+
click: [MouseEvent]
|
|
51
|
+
contextmenu: [MouseEvent]
|
|
48
52
|
positioned: [Feedback]
|
|
49
53
|
}
|
|
50
54
|
|
|
@@ -58,11 +62,13 @@ const typeDefs: Required<TypeDefs<DropdownProps>> = {
|
|
|
58
62
|
// Event is undefined in NodeJs
|
|
59
63
|
of: ['self', 'parent', typeof Event === 'undefined' ? undefined : Event],
|
|
60
64
|
container: [String, Function],
|
|
65
|
+
collison: ['none', 'fit', 'flip', 'flipfit', Array],
|
|
61
66
|
};
|
|
62
67
|
|
|
63
68
|
const defaults = (): Partial<DropdownProps> => ({
|
|
64
69
|
trigger: 'hover',
|
|
65
70
|
of: 'self',
|
|
71
|
+
value: false,
|
|
66
72
|
});
|
|
67
73
|
|
|
68
74
|
const events: Events<DropdownEvents> = {
|
|
@@ -71,6 +77,8 @@ const events: Events<DropdownEvents> = {
|
|
|
71
77
|
hide: true,
|
|
72
78
|
mouseenter: true,
|
|
73
79
|
mouseleave: true,
|
|
80
|
+
click: true,
|
|
81
|
+
contextmenu: true,
|
|
74
82
|
positioned: true,
|
|
75
83
|
};
|
|
76
84
|
|
|
@@ -104,28 +112,18 @@ export class Dropdown<
|
|
|
104
112
|
}
|
|
105
113
|
|
|
106
114
|
const [trigger, menu] = children as DropdownChildren;
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
const clonedTrigger = isTextChildren(trigger) ?
|
|
111
|
-
createVNode('span', null, trigger) :
|
|
112
|
-
directClone(trigger);
|
|
113
|
-
const triggerProps = this.triggerProps = this.normalizeTriggerProps(trigger.props || EMPTY_OBJ);
|
|
114
|
-
// add a className for opening status
|
|
115
|
-
let className = trigger.className || triggerProps.className;
|
|
115
|
+
const props = this.initEventCallbacks();
|
|
116
|
+
let {className, value, container} = this.get();
|
|
116
117
|
className = cx({
|
|
117
|
-
|
|
118
|
-
|
|
118
|
+
'k-dropdown-open': value,
|
|
119
|
+
[className!]: !!className,
|
|
119
120
|
});
|
|
120
|
-
|
|
121
|
-
clonedTrigger.props = {...triggerProps, ...props, className};
|
|
122
|
-
clonedTrigger.className = className;
|
|
123
|
-
|
|
121
|
+
|
|
124
122
|
this.menuVNode = menu;
|
|
125
123
|
|
|
126
124
|
return [
|
|
127
|
-
|
|
128
|
-
h(Portal, {children: menu, container
|
|
125
|
+
h(Virtual, {...props, ...getRestProps(this), className}, trigger),
|
|
126
|
+
h(Portal, {children: menu, container})
|
|
129
127
|
];
|
|
130
128
|
};
|
|
131
129
|
|
|
@@ -135,8 +133,7 @@ export class Dropdown<
|
|
|
135
133
|
public showedDropdown: Dropdown | null = null;
|
|
136
134
|
public positionHook = usePosition();
|
|
137
135
|
|
|
138
|
-
|
|
139
|
-
private triggerProps: any = null;
|
|
136
|
+
protected timer: number | undefined = undefined;
|
|
140
137
|
|
|
141
138
|
init() {
|
|
142
139
|
provide(DROPDOWN, this);
|
|
@@ -167,6 +164,12 @@ export class Dropdown<
|
|
|
167
164
|
clearTimeout(this.timer);
|
|
168
165
|
this.set('value', true);
|
|
169
166
|
|
|
167
|
+
// should show parent dropdown
|
|
168
|
+
const parentDropdown = this.dropdown;
|
|
169
|
+
if (parentDropdown) {
|
|
170
|
+
parentDropdown.show();
|
|
171
|
+
}
|
|
172
|
+
|
|
170
173
|
if (shouldFocus) {
|
|
171
174
|
nextTick(() => {
|
|
172
175
|
this.focusFirst();
|
|
@@ -178,9 +181,15 @@ export class Dropdown<
|
|
|
178
181
|
if (this.get('disabled')) return;
|
|
179
182
|
if (!this.get('value')) return;
|
|
180
183
|
|
|
184
|
+
const showedDropdown = this.showedDropdown;
|
|
185
|
+
if (showedDropdown) {
|
|
186
|
+
showedDropdown.hide(immediately);
|
|
187
|
+
}
|
|
188
|
+
|
|
181
189
|
if (immediately) {
|
|
182
190
|
this.set('value', false);
|
|
183
191
|
} else {
|
|
192
|
+
clearTimeout(this.timer);
|
|
184
193
|
this.timer = window.setTimeout(() => {
|
|
185
194
|
this.set('value', false);
|
|
186
195
|
}, 200);
|
|
@@ -198,29 +207,27 @@ export class Dropdown<
|
|
|
198
207
|
|
|
199
208
|
@bind
|
|
200
209
|
private onEnter(e: MouseEvent) {
|
|
201
|
-
this.callOriginalCallback(e.type === 'click' ? 'ev-click' : 'ev-mouseenter', e);
|
|
202
|
-
|
|
203
210
|
this.show();
|
|
211
|
+
this.trigger(e.type as 'mouseenter', e);
|
|
204
212
|
}
|
|
205
213
|
|
|
206
214
|
@bind
|
|
207
215
|
private onContextMenu(e: MouseEvent) {
|
|
208
|
-
this.callOriginalCallback('ev-contextmenu', e);
|
|
209
|
-
|
|
210
216
|
e.preventDefault();
|
|
211
217
|
this.set('of', e);
|
|
212
218
|
this.show();
|
|
219
|
+
this.trigger('contextmenu', e);
|
|
213
220
|
}
|
|
214
221
|
|
|
215
222
|
@bind
|
|
216
223
|
private onLeave(e: MouseEvent) {
|
|
217
|
-
this.callOriginalCallback('ev-mouseleave', e);
|
|
218
|
-
|
|
219
224
|
this.hide();
|
|
225
|
+
this.trigger(e.type as 'mouseleave', e);
|
|
220
226
|
}
|
|
221
227
|
|
|
222
|
-
private initEventCallbacks(
|
|
223
|
-
const
|
|
228
|
+
private initEventCallbacks() {
|
|
229
|
+
const trigger = this.get('trigger');
|
|
230
|
+
const props: Record<string, Function | string> = {};
|
|
224
231
|
|
|
225
232
|
switch (trigger) {
|
|
226
233
|
case 'focus':
|
|
@@ -241,48 +248,6 @@ export class Dropdown<
|
|
|
241
248
|
|
|
242
249
|
return props;
|
|
243
250
|
}
|
|
244
|
-
|
|
245
|
-
private callOriginalCallback(name: string, e: MouseEvent) {
|
|
246
|
-
const callback = this.triggerProps[name];
|
|
247
|
-
const callbackOnDropdown = this.get<Function>(name);
|
|
248
|
-
if (isFunction(callback)) callback(e);
|
|
249
|
-
if (isFunction(callbackOnDropdown)) callbackOnDropdown(e);
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
private normalizeTriggerProps(props: any) {
|
|
253
|
-
// if use kpc in react or vue, normalize props by Wrapper.props.vnode;
|
|
254
|
-
const vnode = props.vnode;
|
|
255
|
-
if (!vnode) return props;
|
|
256
|
-
|
|
257
|
-
// maybe we render the intact component in react slot property, in this case
|
|
258
|
-
// the $isReact is false. so use the vnode $$typeof field as gauge
|
|
259
|
-
if (vnode.$$typeof || (this as any).$isVueNext) {
|
|
260
|
-
const _props = vnode.props;
|
|
261
|
-
if (!_props) return props;
|
|
262
|
-
|
|
263
|
-
return {
|
|
264
|
-
vnode,
|
|
265
|
-
'ev-click': _props.onClick,
|
|
266
|
-
'ev-mouseenter': _props.onMouseEnter,
|
|
267
|
-
'ev-mouseleave': _props.onMouseLeave,
|
|
268
|
-
'ev-contextmenu': _props.onContextMenu,
|
|
269
|
-
className: _props.className || _props.class /* vue-next */,
|
|
270
|
-
};
|
|
271
|
-
} else if ((this as any).$isVue) {
|
|
272
|
-
const data = vnode.data;
|
|
273
|
-
const on = data && data.on || EMPTY_OBJ;
|
|
274
|
-
const ret: Record<string, any> = {vnode};
|
|
275
|
-
['click', 'mouseenter', 'mouseleave', 'contextmenu'].forEach(event => {
|
|
276
|
-
const method = on[event];
|
|
277
|
-
if (method) {
|
|
278
|
-
ret[`ev-${event}`] = method;
|
|
279
|
-
}
|
|
280
|
-
});
|
|
281
|
-
return ret;
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
return props;
|
|
285
|
-
}
|
|
286
251
|
}
|
|
287
252
|
|
|
288
253
|
function useDocumentClickForDropdown(dropdown: Dropdown) {
|
|
@@ -4,6 +4,7 @@ import {Dropdown, DropdownMenu, DropdownItem} from '../dropdown';
|
|
|
4
4
|
import BasicDemo from '~/components/dropdown/demos/basic';
|
|
5
5
|
import NestedDemo from '~/components/dropdown/demos/nested';
|
|
6
6
|
import ContextMenuDemo from '~/components/dropdown/demos/contextmenu';
|
|
7
|
+
import TooltipDemo from '~/components/dropdown/demos/tooltip';
|
|
7
8
|
|
|
8
9
|
describe('Dropdown', () => {
|
|
9
10
|
afterEach((done) => {
|
|
@@ -72,7 +73,8 @@ describe('Dropdown', () => {
|
|
|
72
73
|
expect(dropdown.parentNode).to.exist;
|
|
73
74
|
});
|
|
74
75
|
|
|
75
|
-
it('nested dropdown', async ()
|
|
76
|
+
it('nested dropdown', async function() {
|
|
77
|
+
this.timeout(0);
|
|
76
78
|
const [instance, element] = mount(NestedDemo);
|
|
77
79
|
|
|
78
80
|
(element.firstElementChild as HTMLElement).click();
|
|
@@ -89,6 +91,20 @@ describe('Dropdown', () => {
|
|
|
89
91
|
await wait(500);
|
|
90
92
|
const hoverSubDropdown = getElement('.k-dropdown-menu')!;
|
|
91
93
|
expect(hoverSubDropdown.innerHTML).to.matchSnapshot();
|
|
94
|
+
|
|
95
|
+
const [hoverItem1] = hoverSubDropdown.querySelectorAll<HTMLElement>('.k-dropdown-item');
|
|
96
|
+
dispatchEvent(hoverItem, 'mouseleave');
|
|
97
|
+
dispatchEvent(hoverItem1, 'mouseenter');
|
|
98
|
+
await wait(500);
|
|
99
|
+
const hoverSubDropdown1 = getElement('.k-dropdown-menu')!;
|
|
100
|
+
expect(hoverSubDropdown1.textContent).to.eql('item 1item 2');
|
|
101
|
+
|
|
102
|
+
const [hoverItem2] = hoverSubDropdown1.querySelectorAll<HTMLElement>('.k-dropdown-item');
|
|
103
|
+
dispatchEvent(hoverItem1, 'mouseleave');
|
|
104
|
+
dispatchEvent(hoverItem2, 'mouseenter');
|
|
105
|
+
await wait(1000);
|
|
106
|
+
const hoverSubDropdown2 = getElement('.k-dropdown-menu')!;
|
|
107
|
+
expect(hoverSubDropdown2 === hoverSubDropdown1).to.be.true;
|
|
92
108
|
});
|
|
93
109
|
|
|
94
110
|
it('hide on click document', async () => {
|
|
@@ -281,13 +297,13 @@ describe('Dropdown', () => {
|
|
|
281
297
|
expect(parent.scrollTop).to.eql(item.offsetHeight * 2 - 40);
|
|
282
298
|
});
|
|
283
299
|
|
|
284
|
-
it('trigger
|
|
300
|
+
it('focus trigger type', async () => {
|
|
285
301
|
class Demo extends Component {
|
|
286
302
|
static template = `
|
|
287
303
|
const {Dropdown, DropdownMenu, DropdownItem} = this;
|
|
288
304
|
<div>
|
|
289
305
|
<Dropdown trigger="focus">
|
|
290
|
-
<input ref="trigger" />
|
|
306
|
+
<input ref="trigger" ev-focusin={this.onFocus} />
|
|
291
307
|
<DropdownMenu>
|
|
292
308
|
<DropdownItem>test1</DropdownItem>
|
|
293
309
|
<DropdownItem>test2</DropdownItem>
|
|
@@ -298,12 +314,14 @@ describe('Dropdown', () => {
|
|
|
298
314
|
private Dropdown = Dropdown;
|
|
299
315
|
private DropdownItem = DropdownItem;
|
|
300
316
|
private DropdownMenu = DropdownMenu;
|
|
317
|
+
public onFocus = sinon.spy((e: MouseEvent) => console.log(e));
|
|
301
318
|
}
|
|
302
319
|
const [instance] = mount(Demo);
|
|
303
320
|
|
|
304
321
|
dispatchEvent(instance.refs.trigger, 'focusin');
|
|
305
322
|
await wait(500);
|
|
306
323
|
expect(getElement('.k-dropdown-menu')).to.be.exist;
|
|
324
|
+
expect(instance.onFocus.callCount).to.eql(1);
|
|
307
325
|
|
|
308
326
|
// clicking anywhere should not hide menu
|
|
309
327
|
dispatchEvent(document, 'click');
|
|
@@ -314,4 +332,35 @@ describe('Dropdown', () => {
|
|
|
314
332
|
await wait(700);
|
|
315
333
|
expect(getElement('.k-dropdown-menu')).to.not.be.exist;
|
|
316
334
|
});
|
|
317
|
-
|
|
335
|
+
|
|
336
|
+
it('wrap by tooltip', async () => {
|
|
337
|
+
const [instance, element] = mount(TooltipDemo);
|
|
338
|
+
|
|
339
|
+
dispatchEvent(element.firstChild as HTMLElement, 'mouseenter');
|
|
340
|
+
await wait();
|
|
341
|
+
const dropdown = getElement('.k-dropdown-menu')!;
|
|
342
|
+
const [item1, item2, item3, item4] = dropdown.querySelectorAll('.k-dropdown-item');
|
|
343
|
+
|
|
344
|
+
dispatchEvent(item1, 'mouseenter');
|
|
345
|
+
await wait();
|
|
346
|
+
expect(getElement('.k-tooltip-content')!.textContent).to.eql('item 1')
|
|
347
|
+
|
|
348
|
+
dispatchEvent(item1, 'mouseleave');
|
|
349
|
+
dispatchEvent(item3, 'mouseenter');
|
|
350
|
+
await wait();
|
|
351
|
+
expect(getElement('.k-tooltip-content')!.textContent).to.eql('disabled')
|
|
352
|
+
|
|
353
|
+
dispatchEvent(item3, 'mouseleave');
|
|
354
|
+
dispatchEvent(item4, 'mouseenter');
|
|
355
|
+
await wait();
|
|
356
|
+
expect(getElement('.k-tooltip-content')!.textContent).to.eql('This is a nested Dropdown.');
|
|
357
|
+
|
|
358
|
+
dispatchEvent(item4, 'click');
|
|
359
|
+
await wait();
|
|
360
|
+
expect(getElement('.k-dropdown-menu')!.textContent).to.eql('item 1item 2');
|
|
361
|
+
|
|
362
|
+
dispatchEvent(item4, 'mouseleave');
|
|
363
|
+
await wait(800);
|
|
364
|
+
expect(getElement('.k-dropdown-menu')).to.not.be.exist;
|
|
365
|
+
});
|
|
366
|
+
});
|
|
@@ -5,6 +5,7 @@ import {useItemKeyboard, MenuKeyboardMethods} from './useKeyboard';
|
|
|
5
5
|
import {Dropdown, DROPDOWN} from './dropdown';
|
|
6
6
|
import {DropdownMenu, DROPDOWN_MENU} from './menu';
|
|
7
7
|
import {IgnoreClickEvent} from '../../hooks/useDocumentClick';
|
|
8
|
+
import { Dropdown as ExportDropdown, DropdownMenu as ExportDropdownMenu } from '.';
|
|
8
9
|
|
|
9
10
|
export interface DropdownItemProps {
|
|
10
11
|
disabled?: boolean
|
|
@@ -64,10 +65,19 @@ export class DropdownItem extends Component<DropdownItemProps, DropdownItemEvent
|
|
|
64
65
|
}
|
|
65
66
|
|
|
66
67
|
hasSubMenu() {
|
|
67
|
-
//
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
68
|
+
// wrapped by Dropdown rather than DropdownMenu
|
|
69
|
+
let parent = this.$senior;
|
|
70
|
+
while (parent) {
|
|
71
|
+
// Tooltip extends Dropdown, it's also a instance of Dropdown
|
|
72
|
+
// so use constructor to detect
|
|
73
|
+
// if (parent instanceof DropdownMenu) {
|
|
74
|
+
if (parent.constructor === ExportDropdownMenu) {
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (parent.constructor === ExportDropdown) {
|
|
78
|
+
return parent;
|
|
79
|
+
}
|
|
80
|
+
parent = parent.$senior;
|
|
71
81
|
}
|
|
72
82
|
}
|
|
73
83
|
|
|
@@ -105,4 +115,4 @@ function useKeyboardForDropdownItem(instance: DropdownItem) {
|
|
|
105
115
|
instance.select();
|
|
106
116
|
},
|
|
107
117
|
});
|
|
108
|
-
}
|
|
118
|
+
}
|
|
@@ -35,8 +35,8 @@ export class DropdownMenu<
|
|
|
35
35
|
@bind
|
|
36
36
|
protected onMouseEnter(e: MouseEvent) {
|
|
37
37
|
const dropdown = this.dropdown!;
|
|
38
|
-
dropdown
|
|
39
|
-
dropdown
|
|
38
|
+
dropdown.show();
|
|
39
|
+
dropdown.trigger('mouseenter', e);
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
@bind
|
|
@@ -78,4 +78,4 @@ function useKeyboardForDropdownMenu(dropdown: Dropdown) {
|
|
|
78
78
|
});
|
|
79
79
|
|
|
80
80
|
return {lock};
|
|
81
|
-
}
|
|
81
|
+
}
|
|
@@ -21,6 +21,8 @@ export function usePosition() {
|
|
|
21
21
|
// return if object is the same
|
|
22
22
|
if (
|
|
23
23
|
isObject(newValue) && isObject(oldValue) &&
|
|
24
|
+
// is not event object
|
|
25
|
+
!(newValue instanceof Event) &&
|
|
24
26
|
JSON.stringify(newValue) === JSON.stringify(oldValue)
|
|
25
27
|
) {
|
|
26
28
|
return;
|
|
@@ -56,6 +58,7 @@ export function usePosition() {
|
|
|
56
58
|
position(findDomFromVNode(instance.menuVNode!, true) as HTMLElement, {
|
|
57
59
|
my: 'left top+8',
|
|
58
60
|
at: 'left bottom',
|
|
61
|
+
collision: instance.get('collison'),
|
|
59
62
|
...pos,
|
|
60
63
|
of: ofElement,
|
|
61
64
|
using: _feedback => {
|
|
@@ -6,6 +6,7 @@ import {mount, unmount, dispatchEvent, wait} from '../../test/utils';
|
|
|
6
6
|
import {Component, findDomFromVNode} from 'intact';
|
|
7
7
|
import {Form, FormItem} from './';
|
|
8
8
|
import {Input} from '../input';
|
|
9
|
+
import { Select } from '../select';
|
|
9
10
|
|
|
10
11
|
RemoteDemo.prototype.validateUserName = function(value) {
|
|
11
12
|
// mock api
|
|
@@ -21,7 +22,7 @@ RemoteDemo.prototype.validateUserName = function(value) {
|
|
|
21
22
|
};
|
|
22
23
|
|
|
23
24
|
describe('Form', () => {
|
|
24
|
-
|
|
25
|
+
afterEach(() => unmount());
|
|
25
26
|
|
|
26
27
|
it('validate', async () => {
|
|
27
28
|
const [instance, element] = mount(BasicDemo, null, basicDemoData);
|
|
@@ -440,4 +441,24 @@ describe('Form', () => {
|
|
|
440
441
|
await wait();
|
|
441
442
|
expect(classList.contains('k-ellipsis')).to.be.true;
|
|
442
443
|
});
|
|
444
|
+
|
|
445
|
+
it('should not validate when select is disabled on init', async () => {
|
|
446
|
+
class Demo extends Component {
|
|
447
|
+
static template = `
|
|
448
|
+
const {Form, FormItem, Select} = this;
|
|
449
|
+
<Form ref="form">
|
|
450
|
+
<FormItem rules={{required: true}}>
|
|
451
|
+
<Select disabled />
|
|
452
|
+
</FormItem>
|
|
453
|
+
</Form>
|
|
454
|
+
`;
|
|
455
|
+
Form = Form;
|
|
456
|
+
FormItem = FormItem;
|
|
457
|
+
Select = Select;
|
|
458
|
+
}
|
|
459
|
+
const [instance, element] = mount(Demo);
|
|
460
|
+
|
|
461
|
+
await wait(500);
|
|
462
|
+
expect(element.querySelector('.k-form-error')).to.be.null;
|
|
463
|
+
});
|
|
443
464
|
});
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import {Component} from 'intact';
|
|
2
|
+
import BasicDemo from '~/components/menu/demos/basic';
|
|
2
3
|
import CollapseDemo from '~/components/menu/demos/collapse';
|
|
3
4
|
import AccordionDemo from '~/components/menu/demos/accordion';
|
|
4
5
|
import {mount, unmount, dispatchEvent, getElement, wait} from '../../test/utils';
|
|
@@ -8,13 +9,17 @@ describe('Menu', () => {
|
|
|
8
9
|
afterEach(() => unmount());
|
|
9
10
|
|
|
10
11
|
it('expand and shrink sub menu', async () => {
|
|
11
|
-
const [instance, element] = mount(
|
|
12
|
+
const [instance, element] = mount(BasicDemo);
|
|
13
|
+
|
|
14
|
+
await wait();
|
|
12
15
|
|
|
16
|
+
// shrink
|
|
13
17
|
const title = element.querySelector('.k-expanded .k-menu-title') as HTMLElement;
|
|
14
18
|
title.click();
|
|
15
19
|
await wait(500);
|
|
16
20
|
expect(element.outerHTML).to.matchSnapshot();
|
|
17
21
|
expect(instance.get('expandedKeys')).to.eql([]);
|
|
22
|
+
|
|
18
23
|
title.click();
|
|
19
24
|
await wait(500);
|
|
20
25
|
expect(element.outerHTML).to.matchSnapshot();
|
|
@@ -24,6 +29,9 @@ describe('Menu', () => {
|
|
|
24
29
|
it('select', async () => {
|
|
25
30
|
const [instance, element] = mount(CollapseDemo);
|
|
26
31
|
|
|
32
|
+
instance.set('collapse', false);
|
|
33
|
+
await wait();
|
|
34
|
+
|
|
27
35
|
expect(element.innerHTML).to.matchSnapshot();
|
|
28
36
|
|
|
29
37
|
const [title, disabledTitle] = element.querySelectorAll<HTMLElement>('.k-menu-title');
|
package/components/menu/item.ts
CHANGED
|
@@ -9,6 +9,7 @@ import {useDropdown} from './useDropdown';
|
|
|
9
9
|
import {useRouter, navigate} from '../../hooks/useRouter';
|
|
10
10
|
import {useRecordItem} from '../../hooks/useRecordComponent';
|
|
11
11
|
import {MENU_RECORD_KEY, useHighlightItem} from './useHighlight';
|
|
12
|
+
import {Events} from '../types';
|
|
12
13
|
|
|
13
14
|
export interface MenuItemProps {
|
|
14
15
|
key: Key
|
|
@@ -32,11 +33,17 @@ const typeDefs: Required<TypeDefs<MenuItemProps>> = {
|
|
|
32
33
|
disabled: Boolean,
|
|
33
34
|
};
|
|
34
35
|
|
|
36
|
+
const events: Events<MenuItemEvents> = {
|
|
37
|
+
click: true,
|
|
38
|
+
select: true,
|
|
39
|
+
};
|
|
40
|
+
|
|
35
41
|
export const MENU_ITEM = 'MenuItem';
|
|
36
42
|
|
|
37
43
|
export class MenuItem extends Component<MenuItemProps, MenuItemEvents> {
|
|
38
44
|
static template = template;
|
|
39
45
|
static typeDefs = typeDefs;
|
|
46
|
+
static events = events;
|
|
40
47
|
|
|
41
48
|
public rootMenu = inject<Menu>(ROOT_MENU)!;
|
|
42
49
|
public parentMenu = inject<Menu>(MENU)!;
|
|
@@ -3,6 +3,8 @@ import GotoDemo from '~/components/pagination/demos/goto';
|
|
|
3
3
|
import CurrentDemo from '~/components/pagination/demos/current';
|
|
4
4
|
import DisableDemo from '~/components/pagination/demos/disable';
|
|
5
5
|
import {mount, unmount, dispatchEvent, wait} from '../../test/utils';
|
|
6
|
+
import { Component } from 'intact';
|
|
7
|
+
import { Pagination } from '.';
|
|
6
8
|
|
|
7
9
|
describe('Pagination', () => {
|
|
8
10
|
// afterEach(() => unmount());
|
|
@@ -89,4 +91,25 @@ describe('Pagination', () => {
|
|
|
89
91
|
expect(input.value).to.eql('10');
|
|
90
92
|
expect(instance.get('value2')).to.eql(10);
|
|
91
93
|
});
|
|
94
|
+
|
|
95
|
+
it('should not set value to 0 when total is 0 on intialization', async () => {
|
|
96
|
+
class Demo extends Component {
|
|
97
|
+
static template = `
|
|
98
|
+
const { Pagination } = this;
|
|
99
|
+
<Pagination total={0} v-model="page" />
|
|
100
|
+
`;
|
|
101
|
+
|
|
102
|
+
static defaults() {
|
|
103
|
+
return {
|
|
104
|
+
page: 1,
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
private Pagination = Pagination;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
const [instance] = mount(Demo);
|
|
112
|
+
// await wait();
|
|
113
|
+
expect(instance.get('page')).to.eql(1);
|
|
114
|
+
});
|
|
92
115
|
});
|
|
@@ -9,6 +9,7 @@ import template from './content.vdt';
|
|
|
9
9
|
import {bind} from '../utils';
|
|
10
10
|
import {Tooltip} from './tooltip';
|
|
11
11
|
import {useArrow} from './useArrow';
|
|
12
|
+
import { tooltip as tooltipTheme } from './styles';
|
|
12
13
|
|
|
13
14
|
export interface TooltipContentProps extends DropdownMenuProps { }
|
|
14
15
|
export interface TooltipContentEvents extends DropdownMenuEvents { }
|
|
@@ -35,10 +36,23 @@ export class TooltipContent extends DropdownMenu<
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
@bind
|
|
38
|
-
private onEnter() {
|
|
39
|
+
private onEnter(elem: HTMLElement) {
|
|
40
|
+
// fix the width, https://github.com/ksc-fe/kpc/issues/873
|
|
41
|
+
const maxWidth = parseInt(tooltipTheme.maxWidth);
|
|
42
|
+
const width = elem.offsetWidth;
|
|
43
|
+
if (width === maxWidth) {
|
|
44
|
+
elem.style.width = `${width}px`;
|
|
45
|
+
}
|
|
39
46
|
this.dropdown!.position();
|
|
40
47
|
}
|
|
41
48
|
|
|
49
|
+
@bind
|
|
50
|
+
private onAfterLeave(elem: HTMLElement) {
|
|
51
|
+
// remove the position after leave, https://github.com/ksc-fe/kpc/issues/873
|
|
52
|
+
const style = elem.style;
|
|
53
|
+
style.left = style.top = style.width = '';
|
|
54
|
+
}
|
|
55
|
+
|
|
42
56
|
@bind
|
|
43
57
|
protected onMouseEnter(e: MouseEvent) {
|
|
44
58
|
const dropdown = this.dropdown as Tooltip;
|
|
@@ -22,7 +22,12 @@ const classNameObj = {
|
|
|
22
22
|
|
|
23
23
|
<t:super
|
|
24
24
|
value={!!value && !this.isEmptyChildren}
|
|
25
|
-
transition={{
|
|
25
|
+
transition={{
|
|
26
|
+
name: 'k-fade',
|
|
27
|
+
onEnter: this.onEnter,
|
|
28
|
+
onAfterLeave: this.onAfterLeave,
|
|
29
|
+
onLeaveCancelled: this.onAfterLeave,
|
|
30
|
+
}}
|
|
26
31
|
class={classNameObj}
|
|
27
32
|
>
|
|
28
33
|
<b:children>
|