@king-design/intact 2.1.1 → 2.1.3

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.
@@ -295,7 +295,38 @@ describe('Dialog', () => {
295
295
  instance.refs.dialog.close();
296
296
 
297
297
  await wait();
298
- expect(document.body.getAttribute('style')).to.be.null;
298
+ const style = document.body.getAttribute('style');
299
+ expect(!!style).to.be.false;
300
+ });
301
+
302
+ it('should update position when change container', async () => {
303
+ class Demo extends Component<{show: boolean, container: any}> {
304
+ static template = `
305
+ var Dialog = this.Dialog;
306
+ <Dialog value={true} container={this.get('container')} ref="dialog">test</Dialog>
307
+ `;
308
+
309
+ private Dialog = Dialog;
310
+
311
+ static defaults() {
312
+ return {
313
+ container: (parentDom: HTMLElement) => parentDom,
314
+ };
315
+ }
316
+ }
317
+
318
+ const [instance, element] = mount(Demo);
319
+
320
+ await wait();
321
+ instance.set('container', undefined);
322
+ await wait();
323
+ const dialogDom = instance.refs.dialog.dialogRef.value;
324
+ const style = dialogDom.style;
325
+ expect(style.left).not.eql('');
326
+ expect(style.top).not.eql('');
327
+
328
+ // should append to body
329
+ expect(dialogDom.closest('.k-dialog-wrapper').parentElement).to.eql(document.body);
299
330
  });
300
331
 
301
332
  // it('should handle v-if and v-model at the same time correctly in Vue', async () => {
@@ -8,6 +8,10 @@ export function usePosition(elementRef: RefObject<HTMLDivElement>) {
8
8
 
9
9
  instance.on(SHOW, center);
10
10
  instance.on('afterClose', onAfterLeave);
11
+ instance.watch('container', () => {
12
+ if (!instance.get('value')) return;
13
+ center();
14
+ }, { presented: true, inited: true });
11
15
 
12
16
  function center() {
13
17
  position(elementRef.value!, {
@@ -68,6 +68,7 @@ const typeDefs: Required<TypeDefs<DropdownProps>> = {
68
68
  const defaults = (): Partial<DropdownProps> => ({
69
69
  trigger: 'hover',
70
70
  of: 'self',
71
+ value: false,
71
72
  });
72
73
 
73
74
  const events: Events<DropdownEvents> = {
@@ -1,8 +1,8 @@
1
1
  import {useInstance, findDomFromVNode} from 'intact';
2
2
  import type {Dropdown} from './';
3
3
  import {Options, position, Feedback} from '../position';
4
- import {noop} from 'intact-shared';
5
- import {isObject} from 'intact-shared';
4
+ import {noop, isObject, isFunction} from 'intact-shared';
5
+ import { isEqualObject } from '../utils';
6
6
 
7
7
  export type FeedbackCallback = (feedback: Feedback) => void;
8
8
 
@@ -18,21 +18,32 @@ export function usePosition() {
18
18
 
19
19
  (['of', 'position'] as const).forEach(item => {
20
20
  instance.watch(item, (newValue, oldValue) => {
21
- // return if object is the same
22
21
  if (
22
+ !instance.get('value') ||
23
+ // return if object is the same
23
24
  isObject(newValue) && isObject(oldValue) &&
24
25
  // is not event object
25
26
  !(newValue instanceof Event) &&
26
- JSON.stringify(newValue) === JSON.stringify(oldValue)
27
- ) {
28
- return;
29
- }
30
- if (instance.get('value')) {
31
- handle(noop);
32
- }
27
+ isEqualObject(newValue, oldValue)
28
+ ) return;
29
+
30
+ handle(noop);
33
31
  }, {presented: true, inited: true});
34
32
  });
35
33
 
34
+ // watch container, it is not commonly used
35
+ instance.watch('container', (newValue, oldValue) => {
36
+ if (
37
+ !instance.get('value') ||
38
+ // return if function is the same. Not rigorous!
39
+ isFunction(newValue) &&
40
+ isFunction(oldValue) &&
41
+ newValue.toString() === oldValue.toString()
42
+ ) return;
43
+
44
+ handle(noop);
45
+ }, { presented: true, inited: true });
46
+
36
47
  // if the dropdown is nested, we must show child after parent has positioned
37
48
  function p(
38
49
  ofElement: HTMLElement | MouseEvent | undefined,
@@ -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
- // afterEach(() => unmount());
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
  });
@@ -10,6 +10,8 @@ import {
10
10
  remove,
11
11
  TypeDefs,
12
12
  inject,
13
+ unmount,
14
+ removeVNodeDom,
13
15
  } from 'intact';
14
16
  import {isString} from 'intact-shared';
15
17
  import {DIALOG} from './dialog/constants';
@@ -57,7 +59,9 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
57
59
  const fakeContainer = document.createDocumentFragment();
58
60
 
59
61
  (mountedQueue.priority || mountedQueue).push(() => {
60
- const parentDom = this.$lastInput!.dom!.parentElement!;
62
+ const parentDom = this.$lastInput!.dom!.parentElement;
63
+ // maybe the <!-- portal --> has been removed by react, #938
64
+ if (!parentDom) return;
61
65
  this.initContainer(nextProps.container, parentDom, anchor);
62
66
  this.container!.appendChild(fakeContainer);
63
67
  });
@@ -128,8 +132,13 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
128
132
  }
129
133
 
130
134
  $unmount(vNode: VNodeComponentClass<this>, nextVNode: VNodeComponentClass<this> | null) {
131
- remove(vNode.props!.children as VNode, this.container!, false);
132
- // removeVNodeDom(vNode.props!.children as VNode, this.container!);
135
+ const children = vNode.props!.children as VNode;
136
+ unmount(children, null);
137
+ if (this.container) {
138
+ // maybe the <!-- portal --> has been removed by react, #938
139
+ // remove(children, this.container, false);
140
+ removeVNodeDom(children, this.container);
141
+ }
133
142
  super.$unmount(vNode, nextVNode);
134
143
  }
135
144
 
@@ -140,7 +149,11 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
140
149
  } else {
141
150
  this.container = container(parentDom, anchor);
142
151
  }
152
+ } else {
153
+ // let below logic to set container to default if container does not exist.
154
+ this.container = null;
143
155
  }
156
+
144
157
  if (!this.container) {
145
158
  if (this.$senior instanceof BaseDialog) {
146
159
  // Dialog and Drawer must be inserted into document.body
@@ -12,6 +12,7 @@ import type {TableColumnProps} from './column';
12
12
  import type {TableProps, TableRowKey} from './table';
13
13
  import {bind} from '../utils';
14
14
  import type {TableGrid} from './useMerge';
15
+ import { isEqualObject } from '../utils';
15
16
 
16
17
  export interface TableRowProps {
17
18
  key: TableRowKey
@@ -65,7 +66,14 @@ export class TableRow extends Component<TableRowProps> {
65
66
  for (key in lastProps) {
66
67
  // ignore index
67
68
  if (key === 'index') continue;
68
- if (lastProps[key] !== nextProps[key]) {
69
+ const lastValue = lastProps[key];
70
+ const nextValue = nextProps[key];
71
+ // deeply compare for offsetMap
72
+ if (key === 'offsetMap' && isEqualObject(lastValue, nextValue)) {
73
+ continue;
74
+ }
75
+
76
+ if (lastValue !== nextValue) {
69
77
  isSame = false;
70
78
  break;
71
79
  }
@@ -9,6 +9,7 @@ import {Tooltip} from './';
9
9
  import {Dialog} from '../dialog';
10
10
  import {mount, unmount, dispatchEvent, getElement, wait} from '../../test/utils';
11
11
  import { tooltip as tooltipTheme } from './styles';
12
+ import { Select, Option } from '../select';
12
13
 
13
14
  describe('Tooltip', () => {
14
15
  afterEach((done) => {
@@ -408,4 +409,33 @@ describe('Tooltip', () => {
408
409
  const newWidth = content.offsetWidth;
409
410
  expect(newWidth).to.eql(width);
410
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
+ });
411
441
  });
@@ -86,6 +86,9 @@ export class Tooltip<
86
86
  if (this.get('hoverable')) {
87
87
  return super.hide(immediately);
88
88
  }
89
+ // tooltip can show any number sub-tooltips, we should not close the showed tooltip
90
+ // #885
91
+ this.showedDropdown = null;
89
92
  super.hide(true);
90
93
  }
91
94
  }
@@ -288,6 +288,21 @@ export function isEqualArray(a: EqualArrayValue, b: EqualArrayValue): boolean {
288
288
  return false;
289
289
  }
290
290
 
291
+ export function isEqualObject(a: Record<string, any>, b: Record<string, any>): boolean {
292
+ if (a === b) return true;
293
+ if (a && b) {
294
+ const keysA = Object.keys(a);
295
+ const keysB = Object.keys(b);
296
+ if (keysA.length !== keysB.length) return false;
297
+
298
+ return keysA.every((key) => {
299
+ return a[key] === b[key];
300
+ });
301
+ }
302
+
303
+ return false;
304
+ }
305
+
291
306
  export function last<T>(arr: T[]): T | undefined {
292
307
  return arr[arr.length - 1];
293
308
  }
@@ -64,13 +64,15 @@ export class Virtual extends Component<any> {
64
64
  return {...props, ...events, className: _props.className || _props.class /* vue-next */};
65
65
  } else if (hasOwn.call(vnode, 'componentOptions') /* vue2 vnode */) {
66
66
  const data = vnode.data;
67
- const on = data && data.on || EMPTY_OBJ;
67
+ if (!data) return props;
68
+
69
+ const on = data.on || EMPTY_OBJ;
68
70
  const events: Record<string, Function> = {};
69
71
  for (let key in on) {
70
72
  events[`ev-${key}`] = on[key];
71
73
  }
72
74
 
73
- return {...props, ...events};
75
+ return {...props, ...events, className: data.staticClass};
74
76
  }
75
77
 
76
78
  return props;
@@ -7,7 +7,7 @@ import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator";
7
7
 
8
8
  function _createForOfIteratorHelperLoose(o, allowArrayLike) { var it = typeof _Symbol !== "undefined" && _getIteratorMethod(o) || o["@@iterator"]; if (it) return (it = it.call(o)).next.bind(it); if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; return function () { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
9
 
10
- function _unsupportedIterableToArray(o, minLen) { var _context18; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty(_context18 = Object.prototype.toString.call(o)).call(_context18, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _unsupportedIterableToArray(o, minLen) { var _context20; if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = _sliceInstanceProperty(_context20 = Object.prototype.toString.call(o)).call(_context20, 8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return _Array$from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
11
11
 
12
12
  function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
13
13
 
@@ -594,7 +594,7 @@ describe('Dialog', function () {
594
594
  }, _callee12);
595
595
  })));
596
596
  it('should remove body style when destroy', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee13() {
597
- var Demo, _mount13, instance, element;
597
+ var Demo, _mount13, instance, element, style;
598
598
 
599
599
  return _regeneratorRuntime.wrap(function _callee13$(_context17) {
600
600
  while (1) {
@@ -642,14 +642,75 @@ describe('Dialog', function () {
642
642
  return wait();
643
643
 
644
644
  case 7:
645
- expect(document.body.getAttribute('style')).to.be.null;
645
+ style = document.body.getAttribute('style');
646
+ expect(!!style).to.be.false;
646
647
 
647
- case 8:
648
+ case 9:
648
649
  case "end":
649
650
  return _context17.stop();
650
651
  }
651
652
  }
652
653
  }, _callee13);
654
+ })));
655
+ it('should update position when change container', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee14() {
656
+ var Demo, _mount14, instance, element, dialogDom, style;
657
+
658
+ return _regeneratorRuntime.wrap(function _callee14$(_context19) {
659
+ while (1) {
660
+ switch (_context19.prev = _context19.next) {
661
+ case 0:
662
+ Demo = /*#__PURE__*/function (_Component5) {
663
+ _inheritsLoose(Demo, _Component5);
664
+
665
+ function Demo() {
666
+ var _context18;
667
+
668
+ var _this5;
669
+
670
+ for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
671
+ args[_key5] = arguments[_key5];
672
+ }
673
+
674
+ _this5 = _Component5.call.apply(_Component5, _concatInstanceProperty(_context18 = [this]).call(_context18, args)) || this;
675
+ _this5.Dialog = Dialog;
676
+ return _this5;
677
+ }
678
+
679
+ Demo.defaults = function defaults() {
680
+ return {
681
+ container: function container(parentDom) {
682
+ return parentDom;
683
+ }
684
+ };
685
+ };
686
+
687
+ return Demo;
688
+ }(Component);
689
+
690
+ Demo.template = "\n var Dialog = this.Dialog;\n <Dialog value={true} container={this.get('container')} ref=\"dialog\">test</Dialog>\n ";
691
+ _mount14 = mount(Demo), instance = _mount14[0], element = _mount14[1];
692
+ _context19.next = 5;
693
+ return wait();
694
+
695
+ case 5:
696
+ instance.set('container', undefined);
697
+ _context19.next = 8;
698
+ return wait();
699
+
700
+ case 8:
701
+ dialogDom = instance.refs.dialog.dialogRef.value;
702
+ style = dialogDom.style;
703
+ expect(style.left).not.eql('');
704
+ expect(style.top).not.eql(''); // should append to body
705
+
706
+ expect(dialogDom.closest('.k-dialog-wrapper').parentElement).to.eql(document.body);
707
+
708
+ case 13:
709
+ case "end":
710
+ return _context19.stop();
711
+ }
712
+ }
713
+ }, _callee14);
653
714
  }))); // it('should handle v-if and v-model at the same time correctly in Vue', async () => {
654
715
  // const Test = {
655
716
  // template: `<Dialog v-model="show" v-if="show" ref="dialog">test</Dialog>`,
@@ -5,6 +5,13 @@ export function usePosition(elementRef) {
5
5
  var instance = useInstance();
6
6
  instance.on(SHOW, center);
7
7
  instance.on('afterClose', onAfterLeave);
8
+ instance.watch('container', function () {
9
+ if (!instance.get('value')) return;
10
+ center();
11
+ }, {
12
+ presented: true,
13
+ inited: true
14
+ });
8
15
 
9
16
  function center() {
10
17
  position(elementRef.value, {
@@ -28,7 +28,8 @@ var typeDefs = {
28
28
  var defaults = function defaults() {
29
29
  return {
30
30
  trigger: 'hover',
31
- of: 'self'
31
+ of: 'self',
32
+ value: false
32
33
  };
33
34
  };
34
35
 
@@ -1,9 +1,8 @@
1
1
  import _extends from "@babel/runtime-corejs3/helpers/extends";
2
- import _JSON$stringify from "@babel/runtime-corejs3/core-js/json/stringify";
3
2
  import { useInstance, findDomFromVNode } from 'intact';
4
3
  import { position } from '../position';
5
- import { noop } from 'intact-shared';
6
- import { isObject } from 'intact-shared';
4
+ import { noop, isObject, isFunction } from 'intact-shared';
5
+ import { isEqualObject } from '../utils';
7
6
  export function usePosition() {
8
7
  var instance = useInstance();
9
8
  var positioned = {
@@ -16,19 +15,23 @@ export function usePosition() {
16
15
  });
17
16
  ['of', 'position'].forEach(function (item) {
18
17
  instance.watch(item, function (newValue, oldValue) {
19
- // return if object is the same
20
- if (isObject(newValue) && isObject(oldValue) && // is not event object
21
- !(newValue instanceof Event) && _JSON$stringify(newValue) === _JSON$stringify(oldValue)) {
22
- return;
23
- }
24
-
25
- if (instance.get('value')) {
26
- handle(noop);
27
- }
18
+ if (!instance.get('value') || // return if object is the same
19
+ isObject(newValue) && isObject(oldValue) && // is not event object
20
+ !(newValue instanceof Event) && isEqualObject(newValue, oldValue)) return;
21
+ handle(noop);
28
22
  }, {
29
23
  presented: true,
30
24
  inited: true
31
25
  });
26
+ }); // watch container, it is not commonly used
27
+
28
+ instance.watch('container', function (newValue, oldValue) {
29
+ if (!instance.get('value') || // return if function is the same. Not rigorous!
30
+ isFunction(newValue) && isFunction(oldValue) && newValue.toString() === oldValue.toString()) return;
31
+ handle(noop);
32
+ }, {
33
+ presented: true,
34
+ inited: true
32
35
  }); // if the dropdown is nested, we must show child after parent has positioned
33
36
 
34
37
  function p(ofElement, parentFeedback) {
@@ -8,10 +8,11 @@ import BasicDemo, { data as basicDemoData } from '~/components/form/demos/basic'
8
8
  import CustomDemo from '~/components/form/demos/custom';
9
9
  import VariableDemo from '~/components/form/demos/variable';
10
10
  import RemoteDemo from '~/components/form/demos/remote';
11
- import { mount, dispatchEvent, wait } from '../../test/utils';
11
+ import { mount, unmount, dispatchEvent, wait } from '../../test/utils';
12
12
  import { Component } from 'intact';
13
13
  import { Form, FormItem } from './';
14
14
  import { Input } from '../input';
15
+ import { Select } from '../select';
15
16
 
16
17
  RemoteDemo.prototype.validateUserName = function (value) {
17
18
  // mock api
@@ -29,7 +30,9 @@ RemoteDemo.prototype.validateUserName = function (value) {
29
30
  };
30
31
 
31
32
  describe('Form', function () {
32
- // afterEach(() => unmount());
33
+ afterEach(function () {
34
+ return unmount();
35
+ });
33
36
  it('validate', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
34
37
  var _mount, instance, element, form, item, input;
35
38
 
@@ -1315,4 +1318,48 @@ describe('Form', function () {
1315
1318
  }
1316
1319
  }, _callee7);
1317
1320
  })));
1321
+ it('should not validate when select is disabled on init', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
1322
+ var Demo, _mount8, instance, element;
1323
+
1324
+ return _regeneratorRuntime.wrap(function _callee8$(_context11) {
1325
+ while (1) {
1326
+ switch (_context11.prev = _context11.next) {
1327
+ case 0:
1328
+ Demo = /*#__PURE__*/function (_Component3) {
1329
+ _inheritsLoose(Demo, _Component3);
1330
+
1331
+ function Demo() {
1332
+ var _context10;
1333
+
1334
+ var _this3;
1335
+
1336
+ for (var _len3 = arguments.length, args = new Array(_len3), _key3 = 0; _key3 < _len3; _key3++) {
1337
+ args[_key3] = arguments[_key3];
1338
+ }
1339
+
1340
+ _this3 = _Component3.call.apply(_Component3, _concatInstanceProperty(_context10 = [this]).call(_context10, args)) || this;
1341
+ _this3.Form = Form;
1342
+ _this3.FormItem = FormItem;
1343
+ _this3.Select = Select;
1344
+ return _this3;
1345
+ }
1346
+
1347
+ return Demo;
1348
+ }(Component);
1349
+
1350
+ Demo.template = "\n const {Form, FormItem, Select} = this;\n <Form ref=\"form\">\n <FormItem rules={{required: true}}>\n <Select disabled />\n </FormItem>\n </Form>\n ";
1351
+ _mount8 = mount(Demo), instance = _mount8[0], element = _mount8[1];
1352
+ _context11.next = 5;
1353
+ return wait(500);
1354
+
1355
+ case 5:
1356
+ expect(element.querySelector('.k-form-error')).to.be.null;
1357
+
1358
+ case 6:
1359
+ case "end":
1360
+ return _context11.stop();
1361
+ }
1362
+ }
1363
+ }, _callee8);
1364
+ })));
1318
1365
  });
@@ -1,6 +1,6 @@
1
1
  import _inheritsLoose from "@babel/runtime-corejs3/helpers/inheritsLoose";
2
2
  import _concatInstanceProperty from "@babel/runtime-corejs3/core-js/instance/concat";
3
- import { Component, createCommentVNode, createTextVNode, mount, patch, remove, inject } from 'intact';
3
+ import { Component, createCommentVNode, createTextVNode, mount, patch, remove, inject, unmount, removeVNodeDom } from 'intact';
4
4
  import { isString } from 'intact-shared';
5
5
  import { DIALOG } from './dialog/constants';
6
6
  import { BaseDialog } from './dialog/base';
@@ -49,7 +49,9 @@ export var Portal = /*#__PURE__*/function (_Component) {
49
49
  var nextProps = nextVNode.props;
50
50
  var fakeContainer = document.createDocumentFragment();
51
51
  (mountedQueue.priority || mountedQueue).push(function () {
52
- var parentDom = _this2.$lastInput.dom.parentElement;
52
+ var parentDom = _this2.$lastInput.dom.parentElement; // maybe the <!-- portal --> has been removed by react, #938
53
+
54
+ if (!parentDom) return;
53
55
 
54
56
  _this2.initContainer(nextProps.container, parentDom, anchor);
55
57
 
@@ -95,7 +97,14 @@ export var Portal = /*#__PURE__*/function (_Component) {
95
97
  };
96
98
 
97
99
  _proto.$unmount = function $unmount(vNode, nextVNode) {
98
- remove(vNode.props.children, this.container, false); // removeVNodeDom(vNode.props!.children as VNode, this.container!);
100
+ var children = vNode.props.children;
101
+ unmount(children, null);
102
+
103
+ if (this.container) {
104
+ // maybe the <!-- portal --> has been removed by react, #938
105
+ // remove(children, this.container, false);
106
+ removeVNodeDom(children, this.container);
107
+ }
99
108
 
100
109
  _Component.prototype.$unmount.call(this, vNode, nextVNode);
101
110
  };
@@ -107,6 +116,9 @@ export var Portal = /*#__PURE__*/function (_Component) {
107
116
  } else {
108
117
  this.container = container(parentDom, anchor);
109
118
  }
119
+ } else {
120
+ // let below logic to set container to default if container does not exist.
121
+ this.container = null;
110
122
  }
111
123
 
112
124
  if (!this.container) {
@@ -3,6 +3,7 @@ import { __decorate } from "tslib";
3
3
  import { Component } from 'intact';
4
4
  import template from './row.vdt';
5
5
  import { bind } from '../utils';
6
+ import { isEqualObject } from '../utils';
6
7
  export var TableRow = /*#__PURE__*/function (_Component) {
7
8
  _inheritsLoose(TableRow, _Component);
8
9
 
@@ -21,8 +22,14 @@ export var TableRow = /*#__PURE__*/function (_Component) {
21
22
  for (key in lastProps) {
22
23
  // ignore index
23
24
  if (key === 'index') continue;
25
+ var lastValue = lastProps[key];
26
+ var nextValue = nextProps[key]; // deeply compare for offsetMap
24
27
 
25
- if (lastProps[key] !== nextProps[key]) {
28
+ if (key === 'offsetMap' && isEqualObject(lastValue, nextValue)) {
29
+ continue;
30
+ }
31
+
32
+ if (lastValue !== nextValue) {
26
33
  isSame = false;
27
34
  break;
28
35
  }
@@ -15,6 +15,7 @@ import { Tooltip } from './';
15
15
  import { Dialog } from '../dialog';
16
16
  import { mount, unmount, dispatchEvent, getElement, wait } from '../../test/utils';
17
17
  import { tooltip as tooltipTheme } from './styles';
18
+ import { Select, Option } from '../select';
18
19
  describe('Tooltip', function () {
19
20
  afterEach(function (done) {
20
21
  unmount();
@@ -685,4 +686,60 @@ describe('Tooltip', function () {
685
686
  }
686
687
  }, _callee11);
687
688
  })));
689
+ it('should not impact select when wrap select with tooltip', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee12() {
690
+ var Demo, _mount12, instance, element, menu;
691
+
692
+ return _regeneratorRuntime.wrap(function _callee12$(_context17) {
693
+ while (1) {
694
+ switch (_context17.prev = _context17.next) {
695
+ case 0:
696
+ Demo = /*#__PURE__*/function (_Component5) {
697
+ _inheritsLoose(Demo, _Component5);
698
+
699
+ function Demo() {
700
+ var _context16;
701
+
702
+ var _this5;
703
+
704
+ for (var _len5 = arguments.length, args = new Array(_len5), _key5 = 0; _key5 < _len5; _key5++) {
705
+ args[_key5] = arguments[_key5];
706
+ }
707
+
708
+ _this5 = _Component5.call.apply(_Component5, _concatInstanceProperty(_context16 = [this]).call(_context16, args)) || this;
709
+ _this5.Tooltip = Tooltip;
710
+ _this5.Select = Select;
711
+ _this5.Option = Option;
712
+ return _this5;
713
+ }
714
+
715
+ return Demo;
716
+ }(Component);
717
+
718
+ Demo.template = "\n const {Tooltip, Select, Option} = this;\n <Tooltip>\n <Select>\n <Option value=\"1\">Option 1</Option>\n <Option value=\"2\">Option 2</Option>\n </Select>\n </Tooltip>\n ";
719
+ _mount12 = mount(Demo), instance = _mount12[0], element = _mount12[1];
720
+ dispatchEvent(element, 'mouseenter');
721
+ _context17.next = 6;
722
+ return wait();
723
+
724
+ case 6:
725
+ dispatchEvent(element, 'click');
726
+ _context17.next = 9;
727
+ return wait();
728
+
729
+ case 9:
730
+ menu = getElement(".k-select-menu");
731
+ dispatchEvent(element, 'mouseleave');
732
+ _context17.next = 13;
733
+ return wait(500);
734
+
735
+ case 13:
736
+ expect(menu.style.display).to.eql('');
737
+
738
+ case 14:
739
+ case "end":
740
+ return _context17.stop();
741
+ }
742
+ }
743
+ }, _callee12);
744
+ })));
688
745
  });
@@ -64,7 +64,11 @@ export var Tooltip = /*#__PURE__*/function (_Dropdown) {
64
64
 
65
65
  if (this.get('hoverable')) {
66
66
  return _Dropdown.prototype.hide.call(this, immediately);
67
- }
67
+ } // tooltip can show any number sub-tooltips, we should not close the showed tooltip
68
+ // #885
69
+
70
+
71
+ this.showedDropdown = null;
68
72
 
69
73
  _Dropdown.prototype.hide.call(this, true);
70
74
  };
@@ -24,6 +24,7 @@ export declare function range(start: number, end: number): number[];
24
24
  export declare function strPad(str: number | string, length: number, pad?: string): string;
25
25
  declare type EqualArrayValue = any | EqualArrayValue[];
26
26
  export declare function isEqualArray(a: EqualArrayValue, b: EqualArrayValue): boolean;
27
+ export declare function isEqualObject(a: Record<string, any>, b: Record<string, any>): boolean;
27
28
  export declare function last<T>(arr: T[]): T | undefined;
28
29
  export declare const expandAnimationCallbacks: {
29
30
  name: string;
@@ -287,6 +287,22 @@ export function isEqualArray(a, b) {
287
287
 
288
288
  return false;
289
289
  }
290
+ export function isEqualObject(a, b) {
291
+ if (a === b) return true;
292
+
293
+ if (a && b) {
294
+ var keysA = _Object$keys(a);
295
+
296
+ var keysB = _Object$keys(b);
297
+
298
+ if (keysA.length !== keysB.length) return false;
299
+ return keysA.every(function (key) {
300
+ return a[key] === b[key];
301
+ });
302
+ }
303
+
304
+ return false;
305
+ }
290
306
  export function last(arr) {
291
307
  return arr[arr.length - 1];
292
308
  }
@@ -82,14 +82,17 @@ export var Virtual = /*#__PURE__*/function (_Component) {
82
82
  /* vue2 vnode */
83
83
  ) {
84
84
  var data = vnode.data;
85
- var on = data && data.on || EMPTY_OBJ;
85
+ if (!data) return props;
86
+ var on = data.on || EMPTY_OBJ;
86
87
  var _events = {};
87
88
 
88
89
  for (var _key2 in on) {
89
90
  _events["ev-" + _key2] = on[_key2];
90
91
  }
91
92
 
92
- return _extends({}, props, _events);
93
+ return _extends({}, props, _events, {
94
+ className: data.staticClass
95
+ });
93
96
  }
94
97
 
95
98
  return props;
package/es/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @king-design v2.1.1
2
+ * @king-design v2.1.3
3
3
  *
4
4
  * Copyright (c) Kingsoft Cloud
5
5
  * Released under the MIT License
@@ -57,4 +57,4 @@ export * from './components/tree';
57
57
  export * from './components/treeSelect';
58
58
  export * from './components/upload';
59
59
  export * from './components/wave';
60
- export declare const version = "2.1.1";
60
+ export declare const version = "2.1.3";
package/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @king-design v2.1.1
2
+ * @king-design v2.1.3
3
3
  *
4
4
  * Copyright (c) Kingsoft Cloud
5
5
  * Released under the MIT License
@@ -59,5 +59,5 @@ export * from './components/tree';
59
59
  export * from './components/treeSelect';
60
60
  export * from './components/upload';
61
61
  export * from './components/wave';
62
- export var version = '2.1.1';
62
+ export var version = '2.1.3';
63
63
  /* generate end */
@@ -60,9 +60,7 @@ var Layout = /*#__PURE__*/function (_Component) {
60
60
  };
61
61
 
62
62
  _proto.onChangeVersion = function onChangeVersion(version) {
63
- if (version === 'v1') {
64
- location.href = '/v1/';
65
- }
63
+ location.href = "/" + version + "/";
66
64
  };
67
65
 
68
66
  return Layout;
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @king-design v2.1.1
2
+ * @king-design v2.1.3
3
3
  *
4
4
  * Copyright (c) Kingsoft Cloud
5
5
  * Released under the MIT License
@@ -62,6 +62,6 @@ export * from './components/treeSelect';
62
62
  export * from './components/upload';
63
63
  export * from './components/wave';
64
64
 
65
- export const version = '2.1.1';
65
+ export const version = '2.1.3';
66
66
 
67
67
  /* generate end */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@king-design/intact",
3
- "version": "2.1.1",
3
+ "version": "2.1.3",
4
4
  "description": "A component library written in Intact for Intact, Vue, React and Angular",
5
5
  "main": "es/index.js",
6
6
  "scripts": {
@@ -117,7 +117,7 @@
117
117
  "highlight.js": "^10.4.1",
118
118
  "history": "^5.0.0",
119
119
  "html-webpack-plugin": "5.3.1",
120
- "intact-react": "^3.0.19",
120
+ "intact-react": "^3.0.26",
121
121
  "istanbul-instrumenter-loader": "^3.0.0",
122
122
  "js-yaml": "^4.1.0",
123
123
  "karma": "^6.3.2",
@@ -179,7 +179,7 @@
179
179
  "dayjs": "^1.10.7",
180
180
  "downloadjs": "^1.4.7",
181
181
  "enquire.js": "^2.1.6",
182
- "intact": "^3.0.19",
182
+ "intact": "^3.0.26",
183
183
  "monaco-editor": "^0.26.1",
184
184
  "mxgraphx": "^4.0.7",
185
185
  "resize-observer-polyfill": "^1.5.1",