@king-design/intact 2.0.1 → 2.0.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.
@@ -5,6 +5,7 @@ import LoadDataDemo from '~/components/cascader/demos/loadData';
5
5
  import FilterDemo from '~/components/cascader/demos/filterable';
6
6
  import {mount, unmount, dispatchEvent, getElement, getElements, wait} from '../../test/utils';
7
7
  import {Cascader} from './';
8
+ import {Component} from 'intact';
8
9
 
9
10
  describe('Cascader', () => {
10
11
  afterEach(async () => {
@@ -146,4 +147,62 @@ describe('Cascader', () => {
146
147
  expect(dropdown.innerHTML).to.matchSnapshot();
147
148
  expect(dropdown.innerText).to.eql('无数据');
148
149
  });
150
+
151
+ it('duplicated sub data', async () => {
152
+ class Demo extends Component {
153
+ static template = `const {Cascader} = this; <Cascader data={this.get('data')} v-model="value" />`;
154
+ static defaults() {
155
+ return {
156
+ value: ['beijing', 'haidian'],
157
+ data: [
158
+ {
159
+ value: 'beijing',
160
+ label: '北京',
161
+ children: [
162
+ {
163
+ value: 'haidian',
164
+ label: '海淀区'
165
+ },
166
+ ]
167
+ },
168
+ {
169
+ value: 'hunan',
170
+ label: '湖南',
171
+ children: [
172
+ {
173
+ value: 'haidian',
174
+ label: '海淀区'
175
+ },
176
+ ]
177
+ },
178
+ ]
179
+ }
180
+ }
181
+ private Cascader = Cascader;
182
+ }
183
+
184
+ const [instance, element] = mount(Demo);
185
+ dispatchEvent(element, 'click');
186
+ await wait();
187
+
188
+ const [dropdown1, dropdown2] = getElements('.k-cascader-menu');
189
+ const [item1, item2] = dropdown1.querySelectorAll(':scope > .k-dropdown-item');
190
+ expect(item1.classList.contains('k-selected')).to.be.true;
191
+ expect(item2.classList.contains('k-selected')).to.be.false;
192
+ const [item21] = dropdown2.querySelectorAll(':scope > .k-dropdown-item');
193
+ expect(item21.classList.contains('k-selected')).to.be.true;
194
+
195
+ dispatchEvent(item2, 'click');
196
+ await wait();
197
+
198
+ const dropdown3 = getElement('.k-cascader-menu')!;
199
+ const [item31] = dropdown3.querySelectorAll(':scope > .k-dropdown-item');
200
+ expect(item31.classList.contains('k-selected')).to.be.false;
201
+
202
+ dispatchEvent(item31, 'click');
203
+ await wait();
204
+
205
+ expect(instance.get('value')).to.eql(['hunan', 'haidian']);
206
+ expect(element.textContent).to.eql('湖南 / 海淀区');
207
+ });
149
208
  });
@@ -11,7 +11,7 @@ const classNameObj = {
11
11
  };
12
12
 
13
13
  const {values, isShowed, isSelected, onSelect, toggleShowedValue} = this.value;
14
- const Options = (data, level, loaded) => {
14
+ const Options = (data, level, loaded, parentSelected) => {
15
15
  if (!data.length) {
16
16
  if (!loaded) {
17
17
  return <Icon class="ion-load-c k-cascader-loading" rotate />
@@ -23,7 +23,7 @@ const Options = (data, level, loaded) => {
23
23
  return data.map((item, index) => {
24
24
  const value = item.value;
25
25
  const showed = isShowed(value, level);
26
- const selected = isSelected(value, level);
26
+ const selected = parentSelected && isSelected(value, level);
27
27
  const children = item.children;
28
28
 
29
29
  const Item = () => {
@@ -58,7 +58,7 @@ const Options = (data, level, loaded) => {
58
58
  >
59
59
  {Item()}
60
60
  <DropdownMenu class={classNameObj}>
61
- {showed ? Options(children, level + 1, item.loaded) : null}
61
+ {showed ? Options(children, level + 1, item.loaded, selected) : null}
62
62
  </DropdownMenu>
63
63
  </Dropdown> :
64
64
  Item()
@@ -74,7 +74,7 @@ const {filter, keywords: {value: keywords}, selectByFilter} = this.filterable;
74
74
  class={classNameObj}
75
75
  key="common"
76
76
  >
77
- {Options(data, 0, true)}
77
+ {Options(data, 0, true, true)}
78
78
  </DropdownMenu>
79
79
  <DropdownMenu v-else
80
80
  key="filter"
@@ -14,23 +14,23 @@ export function useLabel() {
14
14
  const {format} = instance.get();
15
15
  const labels: string[] = [];
16
16
  const length = value.length;
17
- const loop = (data: CascaderStringData[]) => {
17
+ const loop = (data: CascaderStringData[], level: number) => {
18
+ if (level === length) return;
19
+
18
20
  for (let i = 0; i < data.length; i++) {
19
21
  const item = data[i];
20
- if (value.includes(item.value)) {
22
+ if (item.value === value[level]) {
21
23
  labels.push(item.label);
22
- if (labels.length === length) {
23
- return;
24
+
25
+ const children = item.children;
26
+ if (children) {
27
+ loop(children, level + 1);
24
28
  }
25
29
  }
26
- const children = item.children;
27
- if (children) {
28
- loop(children);
29
- }
30
30
  }
31
31
  };
32
32
 
33
- loop(data);
33
+ loop(data, 0);
34
34
 
35
35
  return labels.length ? format!(labels) : null;
36
36
  }
@@ -21,7 +21,7 @@ RemoteDemo.prototype.validateUserName = function(value) {
21
21
  };
22
22
 
23
23
  describe('Form', () => {
24
- afterEach(() => unmount());
24
+ // afterEach(() => unmount());
25
25
 
26
26
  it('validate', async () => {
27
27
  const [instance, element] = mount(BasicDemo, null, basicDemoData);
@@ -24,7 +24,8 @@ import {Menu, MenuItem, Switch, Icon} from 'kpc';
24
24
  falseValue="dark"
25
25
  />
26
26
  <br /><br />
27
- <Menu v-model:expandedKeys="expandedKeys"
27
+ <Menu v-model:expandedKeys="expandedKeys"
28
+ v-model:selectedKey="selectedKey"
28
29
  collapse={this.get('collapse')}
29
30
  theme={this.get('theme')}
30
31
  ref="__test"
@@ -62,6 +63,7 @@ export default class extends Component<Props> {
62
63
  static defaults() {
63
64
  return {
64
65
  expandedKeys: ['3'],
66
+ selectedKey: '3-2',
65
67
  collapse: false,
66
68
  theme: 'dark'
67
69
  } as MenuProps;
@@ -22,23 +22,29 @@ describe('Menu', () => {
22
22
 
23
23
  it('select', async () => {
24
24
  const [instance, element] = mount(CollapseDemo);
25
- const menu = instance.refs.__test as Menu;
25
+
26
+ expect(element.innerHTML).to.matchSnapshot();
26
27
 
27
28
  const [title, disabledTitle] = element.querySelectorAll<HTMLElement>('.k-menu-title');
28
29
  title.click();
29
30
  await wait();
30
31
  expect(element.outerHTML).to.matchSnapshot();
31
- expect(menu.get('selectedKey')).to.eql('1');
32
+ expect(instance.get('selectedKey')).to.eql('1');
32
33
  disabledTitle.click();
33
34
  await wait();
34
35
  expect(element.outerHTML).to.matchSnapshot();
35
- expect(menu.get('selectedKey')).to.eql('1');
36
+ expect(instance.get('selectedKey')).to.eql('1');
36
37
 
37
38
  const subTitle = element.querySelector('.k-expanded .k-menu .k-menu-title') as HTMLElement;
38
39
  subTitle.click();
39
40
  await wait();
40
41
  expect(element.outerHTML).to.matchSnapshot();
41
- expect(menu.get('selectedKey')).to.eql('3-1');
42
+ expect(instance.get('selectedKey')).to.eql('3-1');
43
+
44
+ // clear
45
+ instance.set('selectedKey', '');
46
+ await wait();
47
+ expect(element.querySelector('.k-highlighted')).to.be.null;
42
48
  });
43
49
 
44
50
  it('collapse', async () => {
@@ -4,10 +4,11 @@ import {Dropdown, DropdownMenu} from '../dropdown';
4
4
  import template from './item.vdt';
5
5
  import {bind} from '../utils';
6
6
  import {useState} from '../../hooks/useState';
7
- import {useHighlight} from './useHighlight';
8
7
  import {useExpanded} from './useExpanded';
9
8
  import {useDropdown} from './useDropdown';
10
9
  import {useRouter, navigate} from '../../hooks/useRouter';
10
+ import {useRecordItem} from '../../hooks/useRecordComponent';
11
+ import {MENU_RECORD_KEY} from './useHighlight';
11
12
 
12
13
  export interface MenuItemProps {
13
14
  key: Key
@@ -42,23 +43,23 @@ export class MenuItem extends Component<MenuItemProps, MenuItemEvents> {
42
43
  public parentMenuItem = inject<MenuItem | null>(MENU_ITEM, null);
43
44
 
44
45
  private expanded = useExpanded(this.rootMenu, this.parentMenu);
45
- private highlight = useHighlight(this.rootMenu, this.parentMenuItem);
46
46
  private dropdown = useDropdown(this.rootMenu, this.parentMenu);
47
47
  private router = useRouter();
48
48
 
49
49
  init() {
50
50
  provide(MENU_ITEM, this);
51
+ useRecordItem(MENU_RECORD_KEY);
51
52
  }
52
53
 
53
54
  @bind
54
55
  public onClick(hasSubMenu: Menu, e: MouseEvent) {
55
- const {disabled, to} = this.get();
56
+ const {disabled, to, key} = this.get();
56
57
  if (disabled) return;
57
58
 
58
59
  if (hasSubMenu) {
59
60
  this.expanded.toggle();
60
61
  } else {
61
- this.highlight.select();
62
+ this.rootMenu.highlight!.select(key);
62
63
  }
63
64
 
64
65
  this.trigger('click', e);
@@ -10,7 +10,7 @@ import {makeItemStyles, makeTitleStyles} from './styles';
10
10
  const rootMenu = this.rootMenu;
11
11
  const {theme, type, dot: rootDot} = rootMenu.get();
12
12
  const {children, key, className, disabled, dot} = this.get();
13
- const {isHighlighted, isSelected} = this.highlight;
13
+ const {isHighlighted, isSelected} = rootMenu.highlight;
14
14
  const {isExpanded: isExpandedKey} = this.expanded;
15
15
  const isExpanded = isExpandedKey(key);
16
16
  const {
@@ -23,8 +23,8 @@ const classNameObj = {
23
23
  [className]: className,
24
24
  'k-expanded': isExpanded,
25
25
  'k-disabled': disabled,
26
- 'k-active': isSelected(),
27
- 'k-highlighted': isHighlighted(),
26
+ 'k-active': isSelected(key),
27
+ 'k-highlighted': isHighlighted(key),
28
28
  [makeItemStyles()]: true,
29
29
  };
30
30
 
@@ -1,5 +1,6 @@
1
1
  import {Component, TypeDefs, provide, inject, Key} from 'intact';
2
2
  import template from './menu.vdt';
3
+ import {useHighlight} from './useHighlight';
3
4
 
4
5
  export interface MenuProps<K extends Key = Key> {
5
6
  expandedKeys?: K[]
@@ -46,6 +47,8 @@ export class Menu<K extends Key = Key> extends Component<MenuProps<K>, MenuEvent
46
47
 
47
48
  public rootMenu = inject<Menu | null>(ROOT_MENU, null);
48
49
  public parentMenu = inject<Menu | null>(MENU, null);
50
+ public subExpandedKeys?: Set<K>;
51
+ public highlight?: ReturnType<typeof useHighlight>;
49
52
 
50
53
  init() {
51
54
  provide(MENU, this);
@@ -53,6 +56,7 @@ export class Menu<K extends Key = Key> extends Component<MenuProps<K>, MenuEvent
53
56
  // is root menu or not
54
57
  if (!this.rootMenu) {
55
58
  provide(ROOT_MENU, this);
59
+ this.highlight = useHighlight();
56
60
  }
57
61
  }
58
62
  }
@@ -3,7 +3,7 @@ import type {Menu, MenuItem} from './';
3
3
  import {inArray, addOrRemove} from '../table/useChecked';
4
4
  import {isDropdown} from './useDropdown';
5
5
 
6
- export function useExpanded(rootMenu: Menu, parentMenu: Menu & {subExpandedKeys?: Set<Key>}) {
6
+ export function useExpanded(rootMenu: Menu, parentMenu: Menu) {
7
7
  const instance = useInstance() as MenuItem;
8
8
 
9
9
  onBeforeUnmount(removeSubExpandedKey);
@@ -1,52 +1,57 @@
1
- import {useInstance, createRef, onMounted, onUpdated, onUnmounted, Key} from 'intact';
1
+ import {useInstance, Key} from 'intact';
2
2
  import type {Menu, MenuItem} from './';
3
+ import {useRecordParent} from '../../hooks/useRecordComponent';
3
4
  import {inArray} from '../table/useChecked';
4
- // import {isEqualArray} from '../utils';
5
-
6
- export function useHighlight(
7
- rootMenu: Menu & {highlightedKeys?: Key[]},
8
- parentMenuItem: MenuItem | null
9
- ) {
10
- const instance = useInstance() as MenuItem;
11
-
12
- // we can not watch selectedKey on before initializing rootMenu
13
- // because rootMenu has initialized
14
- // so call updateStatus here
15
- updateStatus(rootMenu.get('selectedKey'));
16
- rootMenu.watch('selectedKey', updateStatus);
17
-
18
- function updateStatus(v: Key | undefined) {
19
- const {key} = instance.get();
20
- if (v !== key) return;
21
-
22
- const items = [];
23
- let parentItem = parentMenuItem;
24
- while (parentItem) {
25
- items.push(parentItem);
26
- parentItem = parentItem.parentMenuItem;
5
+ import {useState} from '../../hooks/useState';
6
+
7
+ export const MENU_RECORD_KEY = 'MenuKeys';
8
+
9
+ export function useHighlight() {
10
+ const instance = useInstance() as Menu;
11
+ const menuItems = useRecordParent<MenuItem>(MENU_RECORD_KEY);
12
+ const highlightedKeys = useState<Key[]>([]);
13
+
14
+ instance.watch('selectedKey', updateStatus, {presented: true});
15
+
16
+ function updateStatus(newValue: Key | undefined) {
17
+ for (let i = 0; i < menuItems.length; i++) {
18
+ const menuItem = menuItems[i];
19
+ const key = menuItem.get('key');
20
+
21
+ if (newValue !== key) continue;
22
+
23
+ const items = [];
24
+ let parentItem = menuItem.parentMenuItem;
25
+ while (parentItem) {
26
+ items.push(parentItem);
27
+ parentItem = parentItem.parentMenuItem;
28
+ }
29
+
30
+ const expandedKeys = new Set(instance.get('expandedKeys'));
31
+ highlightedKeys.set(items.map(item => {
32
+ const key = item.get('key');
33
+ expandedKeys.add(key);
34
+ return key;
35
+ }));
36
+ instance.set('expandedKeys', Array.from(expandedKeys))
37
+
38
+ return;
27
39
  }
28
-
29
- const expandedKeys = new Set(rootMenu.get('expandedKeys'));
30
- const highlightedKeys = items.map(item => {
31
- const key = item.get('key');
32
- expandedKeys.add(key);
33
- return key;
34
- });
35
- rootMenu.highlightedKeys = highlightedKeys;
36
- rootMenu.set('expandedKeys', Array.from(expandedKeys))
40
+
41
+ highlightedKeys.set([]);
37
42
  }
38
43
 
39
- function isHighlighted() {
40
- return inArray(rootMenu.highlightedKeys, instance.get('key'));
44
+ function isHighlighted(key: Key) {
45
+ return inArray(highlightedKeys.value, key);
41
46
  }
42
47
 
43
- function select() {
44
- rootMenu.set('selectedKey', instance.get('key'));
48
+ function select(key: Key) {
49
+ instance.set('selectedKey', key);
45
50
  }
46
51
 
47
- function isSelected() {
48
- return rootMenu.get('selectedKey') === instance.get('key');
52
+ function isSelected(key: Key) {
53
+ return instance.get('selectedKey') === key;
49
54
  }
50
55
 
51
- return {isHighlighted, updateStatus, select, isSelected};
56
+ return {isHighlighted, select, isSelected};
52
57
  }
@@ -1,4 +1,6 @@
1
+ import _inheritsLoose from "@babel/runtime-corejs3/helpers/inheritsLoose";
1
2
  import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator";
3
+ import _concatInstanceProperty from "@babel/runtime-corejs3/core-js/instance/concat";
2
4
  import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator";
3
5
  import BasicDemo from '~/components/cascader/demos/basic';
4
6
  import CustomDemo from '~/components/cascader/demos/custom';
@@ -6,6 +8,8 @@ import ChangeOnSelectDemo from '~/components/cascader/demos/changeOnSelect';
6
8
  import LoadDataDemo from '~/components/cascader/demos/loadData';
7
9
  import FilterDemo from '~/components/cascader/demos/filterable';
8
10
  import { mount, unmount, dispatchEvent, getElement, getElements, wait } from '../../test/utils';
11
+ import { Cascader } from './';
12
+ import { Component } from 'intact';
9
13
  describe('Cascader', function () {
10
14
  afterEach( /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
11
15
  return _regeneratorRuntime.wrap(function _callee$(_context) {
@@ -278,4 +282,88 @@ describe('Cascader', function () {
278
282
  }
279
283
  }, _callee7);
280
284
  })));
285
+ it('duplicated sub data', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee8() {
286
+ var Demo, _mount7, instance, element, _getElements2, dropdown1, dropdown2, _dropdown1$querySelec4, item1, item2, _dropdown2$querySelec3, item21, dropdown3, _dropdown3$querySelec2, item31;
287
+
288
+ return _regeneratorRuntime.wrap(function _callee8$(_context9) {
289
+ while (1) {
290
+ switch (_context9.prev = _context9.next) {
291
+ case 0:
292
+ Demo = /*#__PURE__*/function (_Component) {
293
+ _inheritsLoose(Demo, _Component);
294
+
295
+ function Demo() {
296
+ var _context8;
297
+
298
+ var _this;
299
+
300
+ for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
301
+ args[_key] = arguments[_key];
302
+ }
303
+
304
+ _this = _Component.call.apply(_Component, _concatInstanceProperty(_context8 = [this]).call(_context8, args)) || this;
305
+ _this.Cascader = Cascader;
306
+ return _this;
307
+ }
308
+
309
+ Demo.defaults = function defaults() {
310
+ return {
311
+ value: ['beijing', 'haidian'],
312
+ data: [{
313
+ value: 'beijing',
314
+ label: '北京',
315
+ children: [{
316
+ value: 'haidian',
317
+ label: '海淀区'
318
+ }]
319
+ }, {
320
+ value: 'hunan',
321
+ label: '湖南',
322
+ children: [{
323
+ value: 'haidian',
324
+ label: '海淀区'
325
+ }]
326
+ }]
327
+ };
328
+ };
329
+
330
+ return Demo;
331
+ }(Component);
332
+
333
+ Demo.template = "const {Cascader} = this; <Cascader data={this.get('data')} v-model=\"value\" />";
334
+ _mount7 = mount(Demo), instance = _mount7[0], element = _mount7[1];
335
+ dispatchEvent(element, 'click');
336
+ _context9.next = 6;
337
+ return wait();
338
+
339
+ case 6:
340
+ _getElements2 = getElements('.k-cascader-menu'), dropdown1 = _getElements2[0], dropdown2 = _getElements2[1];
341
+ _dropdown1$querySelec4 = dropdown1.querySelectorAll(':scope > .k-dropdown-item'), item1 = _dropdown1$querySelec4[0], item2 = _dropdown1$querySelec4[1];
342
+ expect(item1.classList.contains('k-selected')).to.be.true;
343
+ expect(item2.classList.contains('k-selected')).to.be.false;
344
+ _dropdown2$querySelec3 = dropdown2.querySelectorAll(':scope > .k-dropdown-item'), item21 = _dropdown2$querySelec3[0];
345
+ expect(item21.classList.contains('k-selected')).to.be.true;
346
+ dispatchEvent(item2, 'click');
347
+ _context9.next = 15;
348
+ return wait();
349
+
350
+ case 15:
351
+ dropdown3 = getElement('.k-cascader-menu');
352
+ _dropdown3$querySelec2 = dropdown3.querySelectorAll(':scope > .k-dropdown-item'), item31 = _dropdown3$querySelec2[0];
353
+ expect(item31.classList.contains('k-selected')).to.be.false;
354
+ dispatchEvent(item31, 'click');
355
+ _context9.next = 21;
356
+ return wait();
357
+
358
+ case 21:
359
+ expect(instance.get('value')).to.eql(['hunan', 'haidian']);
360
+ expect(element.textContent).to.eql('湖南 / 海淀区');
361
+
362
+ case 23:
363
+ case "end":
364
+ return _context9.stop();
365
+ }
366
+ }
367
+ }, _callee8);
368
+ })));
281
369
  });
@@ -41,7 +41,7 @@ export default function ($props, $blocks, $__proto__) {
41
41
  onSelect = _this$value.onSelect,
42
42
  toggleShowedValue = _this$value.toggleShowedValue;
43
43
 
44
- var Options = function Options(data, level, loaded) {
44
+ var Options = function Options(data, level, loaded, parentSelected) {
45
45
  if (!data.length) {
46
46
  if (!loaded) {
47
47
  return _$cc(Icon, _$tmp0);
@@ -53,7 +53,7 @@ export default function ($props, $blocks, $__proto__) {
53
53
  return _mapInstanceProperty(data).call(data, function (item, index) {
54
54
  var value = item.value;
55
55
  var showed = isShowed(value, level);
56
- var selected = isSelected(value, level);
56
+ var selected = parentSelected && isSelected(value, level);
57
57
  var children = item.children;
58
58
 
59
59
  var Item = function Item() {
@@ -79,7 +79,7 @@ export default function ($props, $blocks, $__proto__) {
79
79
  'ev-show': _this.load.bind(null, item),
80
80
  'children': [Item(), _$cc(DropdownMenu, {
81
81
  'className': _$cn(classNameObj),
82
- 'children': showed ? Options(children, level + 1, item.loaded) : null
82
+ 'children': showed ? Options(children, level + 1, item.loaded, selected) : null
83
83
  })]
84
84
  }) : Item();
85
85
  });
@@ -100,7 +100,7 @@ export default function ($props, $blocks, $__proto__) {
100
100
  return !filterable || !keywords ? _$cc(DropdownMenu, {
101
101
  'className': _$cn(classNameObj),
102
102
  'key': 'common',
103
- 'children': Options(data, 0, true)
103
+ 'children': Options(data, 0, true, true)
104
104
  }, 'common') : _$cc(DropdownMenu, {
105
105
  'key': 'filter',
106
106
  'className': _$cn((_$cn2 = {
@@ -1,4 +1,3 @@
1
- import _includesInstanceProperty from "@babel/runtime-corejs3/core-js/instance/includes";
2
1
  import { useInstance } from 'intact';
3
2
  import { useBaseLabel } from '../select/useBaseLabel';
4
3
  export function useLabel() {
@@ -11,27 +10,24 @@ export function useLabel() {
11
10
  var labels = [];
12
11
  var length = value.length;
13
12
 
14
- var loop = function loop(data) {
13
+ var loop = function loop(data, level) {
14
+ if (level === length) return;
15
+
15
16
  for (var i = 0; i < data.length; i++) {
16
17
  var item = data[i];
17
18
 
18
- if (_includesInstanceProperty(value).call(value, item.value)) {
19
+ if (item.value === value[level]) {
19
20
  labels.push(item.label);
21
+ var children = item.children;
20
22
 
21
- if (labels.length === length) {
22
- return;
23
+ if (children) {
24
+ loop(children, level + 1);
23
25
  }
24
26
  }
25
-
26
- var children = item.children;
27
-
28
- if (children) {
29
- loop(children);
30
- }
31
27
  }
32
28
  };
33
29
 
34
- loop(data);
30
+ loop(data, 0);
35
31
  return labels.length ? format(labels) : null;
36
32
  }
37
33
 
@@ -8,7 +8,7 @@ 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, unmount, dispatchEvent, wait } from '../../test/utils';
11
+ import { mount, dispatchEvent, wait } from '../../test/utils';
12
12
  import { Component } from 'intact';
13
13
  import { Form, FormItem } from './';
14
14
  import { Input } from '../input';
@@ -29,9 +29,7 @@ RemoteDemo.prototype.validateUserName = function (value) {
29
29
  };
30
30
 
31
31
  describe('Form', function () {
32
- afterEach(function () {
33
- return unmount();
34
- });
32
+ // afterEach(() => unmount());
35
33
  it('validate', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee() {
36
34
  var _mount, instance, element, form, item, input;
37
35
 
@@ -39,14 +39,14 @@ describe('Menu', function () {
39
39
  }, _callee);
40
40
  })));
41
41
  it('select', /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime.mark(function _callee2() {
42
- var _mount2, instance, element, menu, _element$querySelecto, title, disabledTitle, subTitle;
42
+ var _mount2, instance, element, _element$querySelecto, title, disabledTitle, subTitle;
43
43
 
44
44
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
45
45
  while (1) {
46
46
  switch (_context2.prev = _context2.next) {
47
47
  case 0:
48
48
  _mount2 = mount(CollapseDemo), instance = _mount2[0], element = _mount2[1];
49
- menu = instance.refs.__test;
49
+ expect(element.innerHTML).to.matchSnapshot();
50
50
  _element$querySelecto = element.querySelectorAll('.k-menu-title'), title = _element$querySelecto[0], disabledTitle = _element$querySelecto[1];
51
51
  title.click();
52
52
  _context2.next = 6;
@@ -54,14 +54,14 @@ describe('Menu', function () {
54
54
 
55
55
  case 6:
56
56
  expect(element.outerHTML).to.matchSnapshot();
57
- expect(menu.get('selectedKey')).to.eql('1');
57
+ expect(instance.get('selectedKey')).to.eql('1');
58
58
  disabledTitle.click();
59
59
  _context2.next = 11;
60
60
  return wait();
61
61
 
62
62
  case 11:
63
63
  expect(element.outerHTML).to.matchSnapshot();
64
- expect(menu.get('selectedKey')).to.eql('1');
64
+ expect(instance.get('selectedKey')).to.eql('1');
65
65
  subTitle = element.querySelector('.k-expanded .k-menu .k-menu-title');
66
66
  subTitle.click();
67
67
  _context2.next = 17;
@@ -69,9 +69,16 @@ describe('Menu', function () {
69
69
 
70
70
  case 17:
71
71
  expect(element.outerHTML).to.matchSnapshot();
72
- expect(menu.get('selectedKey')).to.eql('3-1');
72
+ expect(instance.get('selectedKey')).to.eql('3-1'); // clear
73
73
 
74
- case 19:
74
+ instance.set('selectedKey', '');
75
+ _context2.next = 22;
76
+ return wait();
77
+
78
+ case 22:
79
+ expect(element.querySelector('.k-highlighted')).to.be.null;
80
+
81
+ case 23:
75
82
  case "end":
76
83
  return _context2.stop();
77
84
  }
@@ -18,7 +18,6 @@ export declare class MenuItem extends Component<MenuItemProps, MenuItemEvents> {
18
18
  parentMenu: Menu<Key>;
19
19
  parentMenuItem: MenuItem | null;
20
20
  private expanded;
21
- private highlight;
22
21
  private dropdown;
23
22
  private router;
24
23
  init(): void;
@@ -5,10 +5,11 @@ import { Component, inject, provide } from 'intact';
5
5
  import { ROOT_MENU, MENU } from './menu';
6
6
  import template from './item.vdt';
7
7
  import { bind } from '../utils';
8
- import { useHighlight } from './useHighlight';
9
8
  import { useExpanded } from './useExpanded';
10
9
  import { useDropdown } from './useDropdown';
11
10
  import { useRouter, navigate } from '../../hooks/useRouter';
11
+ import { useRecordItem } from '../../hooks/useRecordComponent';
12
+ import { MENU_RECORD_KEY } from './useHighlight';
12
13
  var typeDefs = {
13
14
  key: {
14
15
  type: [String, Number],
@@ -36,7 +37,6 @@ export var MenuItem = /*#__PURE__*/function (_Component) {
36
37
  _this.parentMenu = inject(MENU);
37
38
  _this.parentMenuItem = inject(MENU_ITEM, null);
38
39
  _this.expanded = useExpanded(_this.rootMenu, _this.parentMenu);
39
- _this.highlight = useHighlight(_this.rootMenu, _this.parentMenuItem);
40
40
  _this.dropdown = useDropdown(_this.rootMenu, _this.parentMenu);
41
41
  _this.router = useRouter();
42
42
  return _this;
@@ -46,19 +46,21 @@ export var MenuItem = /*#__PURE__*/function (_Component) {
46
46
 
47
47
  _proto.init = function init() {
48
48
  provide(MENU_ITEM, this);
49
+ useRecordItem(MENU_RECORD_KEY);
49
50
  };
50
51
 
51
52
  _proto.onClick = function onClick(hasSubMenu, e) {
52
53
  var _this$get = this.get(),
53
54
  disabled = _this$get.disabled,
54
- to = _this$get.to;
55
+ to = _this$get.to,
56
+ key = _this$get.key;
55
57
 
56
58
  if (disabled) return;
57
59
 
58
60
  if (hasSubMenu) {
59
61
  this.expanded.toggle();
60
62
  } else {
61
- this.highlight.select();
63
+ this.rootMenu.highlight.select(key);
62
64
  }
63
65
 
64
66
  this.trigger('click', e);
@@ -32,9 +32,9 @@ export default function ($props, $blocks, $__proto__) {
32
32
  disabled = _this$get.disabled,
33
33
  dot = _this$get.dot;
34
34
 
35
- var _this$highlight = this.highlight,
36
- isHighlighted = _this$highlight.isHighlighted,
37
- isSelected = _this$highlight.isSelected;
35
+ var _rootMenu$highlight = rootMenu.highlight,
36
+ isHighlighted = _rootMenu$highlight.isHighlighted,
37
+ isSelected = _rootMenu$highlight.isSelected;
38
38
  var isExpandedKey = this.expanded.isExpanded;
39
39
  var isExpanded = isExpandedKey(key);
40
40
 
@@ -50,7 +50,7 @@ export default function ($props, $blocks, $__proto__) {
50
50
 
51
51
  var classNameObj = (_classNameObj = {
52
52
  'k-menu-item': true
53
- }, _classNameObj[className] = className, _classNameObj['k-expanded'] = isExpanded, _classNameObj['k-disabled'] = disabled, _classNameObj['k-active'] = isSelected(), _classNameObj['k-highlighted'] = isHighlighted(), _classNameObj[makeItemStyles()] = true, _classNameObj);
53
+ }, _classNameObj[className] = className, _classNameObj['k-expanded'] = isExpanded, _classNameObj['k-disabled'] = disabled, _classNameObj['k-active'] = isSelected(key), _classNameObj['k-highlighted'] = isHighlighted(key), _classNameObj[makeItemStyles()] = true, _classNameObj);
54
54
  var showDot = isTopItem && !iconVNode && isNullOrUndefined(dot) ? rootDot : dot;
55
55
 
56
56
  var title = function title(children) {
@@ -1,4 +1,5 @@
1
1
  import { Component, TypeDefs, Key } from 'intact';
2
+ import { useHighlight } from './useHighlight';
2
3
  export interface MenuProps<K extends Key = Key> {
3
4
  expandedKeys?: K[];
4
5
  selectedKey?: K;
@@ -22,5 +23,7 @@ export declare class Menu<K extends Key = Key> extends Component<MenuProps<K>, M
22
23
  static defaults: () => Partial<MenuProps<Key>>;
23
24
  rootMenu: Menu<Key> | null;
24
25
  parentMenu: Menu<Key> | null;
26
+ subExpandedKeys?: Set<K>;
27
+ highlight?: ReturnType<typeof useHighlight>;
25
28
  init(): void;
26
29
  }
@@ -2,6 +2,7 @@ import _inheritsLoose from "@babel/runtime-corejs3/helpers/inheritsLoose";
2
2
  import _concatInstanceProperty from "@babel/runtime-corejs3/core-js/instance/concat";
3
3
  import { Component, provide, inject } from 'intact';
4
4
  import template from './menu.vdt';
5
+ import { useHighlight } from './useHighlight';
5
6
  var typeDefs = {
6
7
  expandedKeys: Array,
7
8
  selectedKey: [String, Number],
@@ -39,6 +40,8 @@ export var Menu = /*#__PURE__*/function (_Component) {
39
40
  _this = _Component.call.apply(_Component, _concatInstanceProperty(_context = [this]).call(_context, args)) || this;
40
41
  _this.rootMenu = inject(ROOT_MENU, null);
41
42
  _this.parentMenu = inject(MENU, null);
43
+ _this.subExpandedKeys = void 0;
44
+ _this.highlight = void 0;
42
45
  return _this;
43
46
  }
44
47
 
@@ -49,6 +52,7 @@ export var Menu = /*#__PURE__*/function (_Component) {
49
52
 
50
53
  if (!this.rootMenu) {
51
54
  provide(ROOT_MENU, this);
55
+ this.highlight = useHighlight();
52
56
  }
53
57
  };
54
58
 
@@ -1,8 +1,5 @@
1
- import { Key } from 'intact';
2
1
  import type { Menu } from './';
3
- export declare function useExpanded(rootMenu: Menu, parentMenu: Menu & {
4
- subExpandedKeys?: Set<Key>;
5
- }): {
2
+ export declare function useExpanded(rootMenu: Menu, parentMenu: Menu): {
6
3
  isExpanded: () => boolean;
7
4
  expand: () => void;
8
5
  shrink: () => void;
@@ -1,10 +1,7 @@
1
1
  import { Key } from 'intact';
2
- import type { Menu, MenuItem } from './';
3
- export declare function useHighlight(rootMenu: Menu & {
4
- highlightedKeys?: Key[];
5
- }, parentMenuItem: MenuItem | null): {
6
- isHighlighted: () => boolean;
7
- updateStatus: (v: Key | undefined) => void;
8
- select: () => void;
9
- isSelected: () => boolean;
2
+ export declare const MENU_RECORD_KEY = "MenuKeys";
3
+ export declare function useHighlight(): {
4
+ isHighlighted: (key: Key) => boolean;
5
+ select: (key: Key) => void;
6
+ isSelected: (key: Key) => boolean;
10
7
  };
@@ -2,56 +2,67 @@ import _Set from "@babel/runtime-corejs3/core-js/set";
2
2
  import _mapInstanceProperty from "@babel/runtime-corejs3/core-js/instance/map";
3
3
  import _Array$from from "@babel/runtime-corejs3/core-js/array/from";
4
4
  import { useInstance } from 'intact';
5
- import { inArray } from '../table/useChecked'; // import {isEqualArray} from '../utils';
5
+ import { useRecordParent } from '../../hooks/useRecordComponent';
6
+ import { inArray } from '../table/useChecked';
7
+ import { useState } from '../../hooks/useState';
8
+ export var MENU_RECORD_KEY = 'MenuKeys';
9
+ export function useHighlight() {
10
+ var instance = useInstance();
11
+ var menuItems = useRecordParent(MENU_RECORD_KEY);
12
+ var highlightedKeys = useState([]);
13
+ instance.watch('selectedKey', updateStatus, {
14
+ presented: true
15
+ });
6
16
 
7
- export function useHighlight(rootMenu, parentMenuItem) {
8
- var instance = useInstance(); // we can not watch selectedKey on before initializing rootMenu
9
- // because rootMenu has initialized
10
- // so call updateStatus here
17
+ function updateStatus(newValue) {
18
+ var _loop = function _loop(i) {
19
+ var menuItem = menuItems[i];
20
+ var key = menuItem.get('key');
21
+ if (newValue !== key) return "continue";
22
+ var items = [];
23
+ var parentItem = menuItem.parentMenuItem;
11
24
 
12
- updateStatus(rootMenu.get('selectedKey'));
13
- rootMenu.watch('selectedKey', updateStatus);
25
+ while (parentItem) {
26
+ items.push(parentItem);
27
+ parentItem = parentItem.parentMenuItem;
28
+ }
14
29
 
15
- function updateStatus(v) {
16
- var _instance$get = instance.get(),
17
- key = _instance$get.key;
30
+ var expandedKeys = new _Set(instance.get('expandedKeys'));
31
+ highlightedKeys.set(_mapInstanceProperty(items).call(items, function (item) {
32
+ var key = item.get('key');
33
+ expandedKeys.add(key);
34
+ return key;
35
+ }));
36
+ instance.set('expandedKeys', _Array$from(expandedKeys));
37
+ return {
38
+ v: void 0
39
+ };
40
+ };
18
41
 
19
- if (v !== key) return;
20
- var items = [];
21
- var parentItem = parentMenuItem;
42
+ for (var i = 0; i < menuItems.length; i++) {
43
+ var _ret = _loop(i);
22
44
 
23
- while (parentItem) {
24
- items.push(parentItem);
25
- parentItem = parentItem.parentMenuItem;
45
+ if (_ret === "continue") continue;
46
+ if (typeof _ret === "object") return _ret.v;
26
47
  }
27
48
 
28
- var expandedKeys = new _Set(rootMenu.get('expandedKeys'));
29
-
30
- var highlightedKeys = _mapInstanceProperty(items).call(items, function (item) {
31
- var key = item.get('key');
32
- expandedKeys.add(key);
33
- return key;
34
- });
35
-
36
- rootMenu.highlightedKeys = highlightedKeys;
37
- rootMenu.set('expandedKeys', _Array$from(expandedKeys));
49
+ highlightedKeys.set([]);
38
50
  }
39
51
 
40
- function isHighlighted() {
41
- return inArray(rootMenu.highlightedKeys, instance.get('key'));
52
+ function isHighlighted(key) {
53
+ return inArray(highlightedKeys.value, key);
42
54
  }
43
55
 
44
- function select() {
45
- rootMenu.set('selectedKey', instance.get('key'));
56
+ function select(key) {
57
+ instance.set('selectedKey', key);
46
58
  }
47
59
 
48
- function isSelected() {
49
- return rootMenu.get('selectedKey') === instance.get('key');
60
+ function isSelected(key) {
61
+ return instance.get('selectedKey') === key;
50
62
  }
51
63
 
52
64
  return {
53
65
  isHighlighted: isHighlighted,
54
- updateStatus: updateStatus,
55
66
  select: select,
56
67
  isSelected: isSelected
57
68
  };
package/es/index.d.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @king-design v2.0.1
2
+ * @king-design v2.0.2
3
3
  *
4
4
  * Copyright (c) Kingsoft Cloud
5
5
  * Released under the MIT License
@@ -56,4 +56,4 @@ export * from './components/tree';
56
56
  export * from './components/treeSelect';
57
57
  export * from './components/upload';
58
58
  export * from './components/wave';
59
- export declare const version = "2.0.1";
59
+ export declare const version = "2.0.2";
package/es/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @king-design v2.0.1
2
+ * @king-design v2.0.2
3
3
  *
4
4
  * Copyright (c) Kingsoft Cloud
5
5
  * Released under the MIT License
@@ -58,5 +58,5 @@ export * from './components/tree';
58
58
  export * from './components/treeSelect';
59
59
  export * from './components/upload';
60
60
  export * from './components/wave';
61
- export var version = '2.0.1';
61
+ export var version = '2.0.2';
62
62
  /* generate end */
@@ -15,6 +15,7 @@ var default_1 = /*#__PURE__*/function (_Component) {
15
15
  default_1.defaults = function defaults() {
16
16
  return {
17
17
  expandedKeys: ['3'],
18
+ selectedKey: '3-2',
18
19
  collapse: false,
19
20
  theme: 'dark'
20
21
  };
@@ -20,6 +20,7 @@ var Demo = /*#__PURE__*/function (_React$Component) {
20
20
  _this = _React$Component.call.apply(_React$Component, _concatInstanceProperty(_context = [this]).call(_context, args)) || this;
21
21
  _this.state = {
22
22
  expandedKeys: ['3'],
23
+ selectedKey: '3-2',
23
24
  collapse: false,
24
25
  theme: 'dark'
25
26
  };
@@ -66,6 +67,12 @@ var Demo = /*#__PURE__*/function (_React$Component) {
66
67
  expandedKeys: expandedKeys
67
68
  });
68
69
  },
70
+ selectedKey: this.state.selectedKey,
71
+ onChangeSelectedKey: function onChangeSelectedKey(selectedKey) {
72
+ return _this2.setState({
73
+ selectedKey: selectedKey
74
+ });
75
+ },
69
76
  collapse: this.state.collapse,
70
77
  theme: this.state.theme,
71
78
  ref: function ref(i) {
@@ -2,10 +2,10 @@ import _asyncToGenerator from "@babel/runtime-corejs3/helpers/asyncToGenerator";
2
2
  import _regeneratorRuntime from "@babel/runtime-corejs3/regenerator";
3
3
  import router from './router';
4
4
  import { render, createVNode as h } from 'intact';
5
- import { history } from './history';
6
- import { localize } from 'kpc';
7
- import i18n from 'kpc/i18n/en-US';
8
- localize(i18n);
5
+ import { history } from './history'; // import {localize} from 'kpc';
6
+ // import i18n from 'kpc/i18n/en-US';
7
+ // localize(i18n);
8
+
9
9
  var container = document.getElementById('page');
10
10
  var unlisten;
11
11
 
package/index.ts CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * @king-design v2.0.1
2
+ * @king-design v2.0.2
3
3
  *
4
4
  * Copyright (c) Kingsoft Cloud
5
5
  * Released under the MIT License
@@ -61,6 +61,6 @@ export * from './components/treeSelect';
61
61
  export * from './components/upload';
62
62
  export * from './components/wave';
63
63
 
64
- export const version = '2.0.1';
64
+ export const version = '2.0.2';
65
65
 
66
66
  /* generate end */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@king-design/intact",
3
- "version": "2.0.1",
3
+ "version": "2.0.2",
4
4
  "description": "A component library written in Intact for Intact, Vue, React and Angular",
5
5
  "main": "es/index.js",
6
6
  "scripts": {
@@ -113,7 +113,7 @@
113
113
  "highlight.js": "^10.4.1",
114
114
  "history": "^5.0.0",
115
115
  "html-webpack-plugin": "5.3.1",
116
- "intact-react": "^3.0.1",
116
+ "intact-react": "^3.0.3",
117
117
  "istanbul-instrumenter-loader": "^3.0.0",
118
118
  "js-yaml": "^4.1.0",
119
119
  "karma": "^6.3.2",
@@ -175,7 +175,7 @@
175
175
  "dayjs": "^1.10.7",
176
176
  "downloadjs": "^1.4.7",
177
177
  "enquire.js": "^2.1.6",
178
- "intact": "^3.0.1",
178
+ "intact": "^3.0.3",
179
179
  "monaco-editor": "^0.26.1",
180
180
  "mxgraphx": "^4.0.7",
181
181
  "resize-observer-polyfill": "^1.5.1",