@king-design/intact 2.0.13 → 2.0.15

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.
Files changed (75) hide show
  1. package/components/cascader/index.md +1 -0
  2. package/components/cascader/useValue.ts +1 -1
  3. package/components/colorpicker/index.md +1 -0
  4. package/components/colorpicker/index.ts +2 -0
  5. package/components/colorpicker/index.vdt +1 -0
  6. package/components/datepicker/index.md +1 -0
  7. package/components/dialog/alert.vdt +5 -3
  8. package/components/dialog/index.md +3 -0
  9. package/components/dialog/index.spec.ts +35 -0
  10. package/components/dialog/staticMethods.ts +14 -1
  11. package/components/dialog/useFixBody.ts +3 -1
  12. package/components/form/styles.ts +5 -2
  13. package/components/icon/demos/icons.md +158 -0
  14. package/components/pagination/demos/disable.md +51 -0
  15. package/components/pagination/index.md +2 -0
  16. package/components/pagination/index.spec.ts +14 -0
  17. package/components/pagination/index.ts +8 -0
  18. package/components/pagination/index.vdt +13 -3
  19. package/components/pagination/styles.ts +3 -0
  20. package/components/portal.ts +38 -28
  21. package/components/select/base.ts +5 -7
  22. package/components/select/base.vdt +5 -7
  23. package/components/select/demos/basic.md +1 -1
  24. package/components/select/index.md +1 -0
  25. package/components/select/useEqualWidth.ts +1 -1
  26. package/components/select/useFocusout.ts +1 -1
  27. package/components/select/useInput.ts +1 -1
  28. package/components/treeSelect/index.md +1 -0
  29. package/components/wave/index.ts +1 -1
  30. package/components/wave/styles.ts +2 -1
  31. package/es/components/cascader/useValue.js +1 -1
  32. package/es/components/colorpicker/index.d.ts +1 -0
  33. package/es/components/colorpicker/index.js +2 -1
  34. package/es/components/colorpicker/index.vdt.js +5 -1
  35. package/es/components/dialog/alert.vdt.js +6 -4
  36. package/es/components/dialog/index.spec.js +61 -1
  37. package/es/components/dialog/staticMethods.d.ts +4 -2
  38. package/es/components/dialog/staticMethods.js +16 -0
  39. package/es/components/dialog/useFixBody.js +3 -1
  40. package/es/components/form/styles.js +1 -1
  41. package/es/components/pagination/index.d.ts +2 -0
  42. package/es/components/pagination/index.js +12 -1
  43. package/es/components/pagination/index.spec.js +28 -0
  44. package/es/components/pagination/index.vdt.js +18 -3
  45. package/es/components/pagination/styles.js +1 -1
  46. package/es/components/portal.js +23 -11
  47. package/es/components/select/base.d.ts +1 -1
  48. package/es/components/select/base.js +4 -4
  49. package/es/components/select/base.vdt.js +6 -6
  50. package/es/components/select/useEqualWidth.js +1 -1
  51. package/es/components/select/useFocusout.js +1 -1
  52. package/es/components/select/useInput.js +1 -1
  53. package/es/components/wave/styles.js +1 -1
  54. package/es/index.d.ts +2 -2
  55. package/es/index.js +2 -2
  56. package/es/packages/kpc-react/__tests__/components/dialog.spec.d.ts +1 -0
  57. package/es/packages/kpc-react/__tests__/components/dialog.spec.js +45 -0
  58. package/es/packages/kpc-react/__tests__/components/drawer.spec.js +65 -10
  59. package/es/site/data/components/icon/demos/icons/index.d.ts +9 -0
  60. package/es/site/data/components/icon/demos/icons/index.js +24 -0
  61. package/es/site/data/components/{menu/demos/size → icon/demos/icons}/react.d.ts +4 -2
  62. package/es/site/data/components/icon/demos/icons/react.js +63 -0
  63. package/es/site/data/components/pagination/demos/disable/index.d.ts +16 -0
  64. package/es/site/data/components/pagination/demos/disable/index.js +35 -0
  65. package/es/site/data/components/pagination/demos/disable/react.d.ts +16 -0
  66. package/es/site/data/components/pagination/demos/disable/react.js +65 -0
  67. package/es/site/data/components/select/demos/basic/react.js +2 -1
  68. package/es/styles/global.js +1 -1
  69. package/index.ts +2 -2
  70. package/package.json +2 -2
  71. package/styles/fonts/demo.css +370 -0
  72. package/styles/fonts/demo.html +29 -0
  73. package/styles/fonts/iconfont.css +477 -0
  74. package/styles/global.ts +1 -1
  75. package/es/site/data/components/menu/demos/collapse/react.d.ts +0 -11
@@ -29,6 +29,7 @@ sidebar: doc
29
29
  | format | 自定义结果显示,组件会将当前选择的所有数据项以数组的格式作为参数传入 | `Function` | `(values: string[]) => values.map(value => value.label).join(' / ')` |
30
30
  | loadData | 如果`data`中的`children`属性值为空数组`[]`,则可以使用该属性定义动态加载逻辑,组件会将当前选中的数据项作为参数传入 | `(data: CascaderData<V>) => any` | `undefined` |
31
31
  | filter | 如果可搜索,你可以传入`filter`改变搜索逻辑,组件会将搜索关键词和数据项作为参数传入 | `(keywords: string, data: CascaderData<V>) => boolean` | `(keywords: string, data: CascaderData<V>) => data.label.includes(keywords)` |
32
+ | show | 是否展示菜单项 | `boolean` | `false` |
32
33
 
33
34
  ```ts
34
35
  export type CascaderData<V> = {
@@ -36,7 +36,7 @@ export function useValue() {
36
36
  }
37
37
  });
38
38
 
39
- instance.watch('_show', value => {
39
+ instance.watch('show', value => {
40
40
  if (value) {
41
41
  showedValue.set(last(values.value) || []);
42
42
  }
@@ -13,3 +13,4 @@ sidebar: doc
13
13
  | presets | 预选颜色 | `string[]` | `['#D0021B', '#F5A623', '#F8E71C', '#8B572A', '#7ED321', '#417505', '#BD10E0', '#9013FE', '#4A90E2', '#50E3C2', '#B8E986', '#000000', '#4A4A4A', '#9B9B9B', '#FFFFFF']` |
14
14
  | size | 组件尺寸 | `"large"` &#124; `"default"` &#124; `"small"` &#124; `"mini"` | `"default"` |
15
15
  | disabled | 是否禁用 | `boolean` | `false` |
16
+ | show | 是否展示颜色选择面板 | `boolean` | `false` |
@@ -9,6 +9,7 @@ export interface ColorpickerProps {
9
9
  size?: Sizes
10
10
  disabled?: boolean
11
11
  container?: Container
12
+ show?: boolean
12
13
  }
13
14
 
14
15
  export interface ColorpickerEvents { }
@@ -22,6 +23,7 @@ const typeDefs: Required<TypeDefs<ColorpickerProps>> = {
22
23
  size: sizes,
23
24
  disabled: Boolean,
24
25
  container: [Function, String],
26
+ show: Boolean,
25
27
  };
26
28
 
27
29
  const defaults = (): Partial<ColorpickerProps> => ({
@@ -23,6 +23,7 @@ const classNameObj = {
23
23
  trigger="click"
24
24
  disabled={disabled}
25
25
  container={container}
26
+ v-model:value="show"
26
27
  >
27
28
  <div class="k-colorpicker-color">
28
29
  <div class="k-colorpicker-inner" style={{backgroundColor: value}}></div>
@@ -30,6 +30,7 @@ sidebar: doc
30
30
  | disabledDate | 该属性值是一个函数,用于定义那些日期被禁止选择,函数参数为日期字符串,返回`true`则表示禁用该日期 | `(v: Dayjs) => boolean` | `undefined` |
31
31
  | type | 组件类型:`"date"` 只选择日期;`"datetime"` 选择日期和时间;`"year"` 选择年份;`"month"` 选择月份 | `"date"` &#124; `"datetime"` &#124; `"year"` &#124; `"month"` | `"date"` |
32
32
  | shortcuts | 指定快捷方式 | `Shortcut[]` | `undefined` |
33
+ | show | 是否展示菜单项 | `boolean` | `false` |
33
34
 
34
35
  ```ts
35
36
  import {Dayjs} from 'dayjs';
@@ -4,7 +4,8 @@ import {makeAlertStyles} from './styles';
4
4
 
5
5
  const {
6
6
  type, content, hideIcon,
7
- hideFooter, hideClose, title
7
+ hideFooter, hideClose, title,
8
+ iconClassName, icon
8
9
  } = this.get();
9
10
 
10
11
  const classNameObj = {
@@ -18,12 +19,13 @@ const classNameObj = {
18
19
  <b:header />
19
20
  <b:body>
20
21
  <div class="k-dialog-tip-icon">
21
- <Icon class={{
22
+ <Icon class={iconClassName || {
22
23
  "ion-ios-checkmark": type === 'success',
23
24
  "ion-ios-information": type === 'warning',
24
25
  "ion-ios-close": type === 'error',
25
26
  "ion-ios-help": type === 'confirm',
26
- }} v-if={!hideIcon} />
27
+ }} v-if={!hideIcon && !icon} />
28
+ {icon}
27
29
  </div>
28
30
  <div class="k-alert-dialog-wrapper">
29
31
  <div class="k-alert-dialog-title" v-if={title}>{title}</div>
@@ -103,6 +103,9 @@ export type Container = string | ((parentDom: Element, anchor: Node | null) => E
103
103
  | hideIcon | 是否隐藏提示图标 | `boolean` | `false` |
104
104
  | hideFooter | 是否隐藏底部按钮 | `boolean` | `false` |
105
105
  | ref | 传入一个函数,组件会调用该函数,将当前`Dialog`实例传入 | `(i: Dialog) => void` | `undefined` |
106
+ | className | 样式类名 | `string` | `undefined` |
107
+ | iconClassName | 指定icon样式名 | `string` | `undefined` |
108
+ | icon | 自定义icon内容 | `VNode` | `undefined` |
106
109
 
107
110
  其中`Promise`对象会在点击“确定”按钮时`resolve()`,在点击“取消”按钮时`reject()`,你可以在`then()`
108
111
  中书写用户点击不同按钮的逻辑
@@ -1,5 +1,6 @@
1
1
  import {Component} from 'intact';
2
2
  import {Dialog, BaseDialog, DialogProps} from './';
3
+ import {bind} from '../utils';
3
4
  import {getElement, mount, unmount, dispatchEvent, wait} from '../../test/utils';
4
5
  import BasicDemo from '~/components/dialog/demos/basic';
5
6
  import AsyncCloseDemo from '~/components/dialog/demos/asyncClose';
@@ -263,6 +264,40 @@ describe('Dialog', () => {
263
264
  expectDialog();
264
265
  });
265
266
 
267
+ it('should remove body style when destroy', async () => {
268
+ class Demo extends Component<{content: string, show: boolean, onClose: Function}> {
269
+ static template = `
270
+ var Dialog = this.Dialog;
271
+ <div>
272
+ <Dialog v-if={this.get('show')}
273
+ value={this.get('show')}
274
+ ev-close={this.onClose}
275
+ ref="dialog"
276
+ >test</Dialog>
277
+ </div>
278
+ `;
279
+
280
+ private Dialog = Dialog;
281
+
282
+ static defaults() {
283
+ return {
284
+ show: true,
285
+ };
286
+ }
287
+
288
+ @bind
289
+ onClose() {
290
+ this.set('show', false);
291
+ }
292
+ }
293
+
294
+ const [instance, element] = mount(Demo);
295
+ instance.refs.dialog.close();
296
+
297
+ await wait();
298
+ expect(document.body.getAttribute('style')).to.be.null;
299
+ });
300
+
266
301
  // it('should handle v-if and v-model at the same time correctly in Vue', async () => {
267
302
  // const Test = {
268
303
  // template: `<Dialog v-model="show" v-if="show" ref="dialog">test</Dialog>`,
@@ -3,11 +3,14 @@ import type {Dialog, DialogProps} from './';
3
3
  import template from './alert.vdt';
4
4
 
5
5
  export interface AlertDialogProps extends DialogProps {
6
- content?: string | VNode
6
+ content?: string | object
7
7
  type?: 'success' | 'warning' | 'error' | 'confirm'
8
8
  hideIcon?: boolean
9
9
  hideFooter?: boolean
10
10
  ref?: (i: Dialog) => void
11
+ className?: string
12
+ iconClassName?: string
13
+ icon?: object
11
14
  }
12
15
 
13
16
  export type StaticMethod = (options?: AlertDialogProps) => Promise<void>
@@ -25,6 +28,16 @@ export function addStaticMethods(Component: typeof Dialog) {
25
28
  }
26
29
 
27
30
  function show(options: AlertDialogProps = {}) {
31
+ const normalize = (Component as any).normalize;
32
+ if (normalize) {
33
+ if (options.content) {
34
+ options = {...options, content: normalize(options.content)};
35
+ }
36
+ if (options.icon) {
37
+ options = {...options, icon: normalize(options.icon)};
38
+ }
39
+ }
40
+
28
41
  const dialog = new AlertDialog(options);
29
42
  dialog.show();
30
43
 
@@ -21,7 +21,9 @@ export function useFixBody(elementRef: RefObject<HTMLDivElement>) {
21
21
  instance.on('afterClose', onAfterLeave);
22
22
 
23
23
  onBeforeUnmount(() => {
24
- if (fixedBody && instance.get('value')) {
24
+ // should also remove body style when dialog is removed, #805
25
+ // if (fixedBody && instance.get('value')) {
26
+ if (fixedBody) {
25
27
  // maybe HIDE event has not triggered
26
28
  onClosed(instance);
27
29
  }
@@ -107,8 +107,11 @@ export function makeItemStyles() {
107
107
 
108
108
  // nested
109
109
  .k-form-item {
110
- display: block;
111
- width: auto;
110
+ &,
111
+ .k-form-content {
112
+ display: block;
113
+ width: auto;
114
+ }
112
115
  }
113
116
 
114
117
  // append
@@ -0,0 +1,158 @@
1
+ ---
2
+ title: King-Design Icons
3
+ order: 1
4
+ ---
5
+
6
+
7
+
8
+ ```vdt
9
+ import {Icon} from 'kpc';
10
+
11
+ <div class="icons">
12
+ <div class="icon" v-for={this.get('fonts')}>
13
+ <Icon
14
+ class={'k-icon-' + $value}
15
+ size="large"
16
+ />
17
+ <div>{'k-icon-' + $value}</div>
18
+ </div>
19
+ </div>
20
+ ```
21
+
22
+ ```styl
23
+ .icons
24
+ display flex
25
+ flex-wrap wrap
26
+ gap 10px
27
+ text-align center
28
+ .icon
29
+ width 100px
30
+ ```
31
+
32
+ ```ts
33
+ export default class extends Component {
34
+ static template = template;
35
+
36
+ static defaults() {
37
+ return {
38
+ fonts: [
39
+ 'alert',
40
+ 'alarm',
41
+ 'calendar',
42
+ 'application',
43
+ 'arrow-right',
44
+ 'arrow-up',
45
+ 'arrow-left',
46
+ 'arrow-down',
47
+ 'arrow-expand',
48
+ 'arrow-left-circled',
49
+ 'arrow-right-circled',
50
+ 'close',
51
+ 'bill',
52
+ 'change',
53
+ 'cloud-download',
54
+ 'content-squared',
55
+ 'cloud',
56
+ 'arrow-move',
57
+ 'code-download',
58
+ 'cloud-server',
59
+ 'arrow-shrink',
60
+ 'clone',
61
+ 'cloud-servers',
62
+ 'cart',
63
+ 'delete',
64
+ 'fault-outline',
65
+ 'calculate',
66
+ 'arrow-swap',
67
+ 'download',
68
+ 'information',
69
+ 'internet',
70
+ 'edit',
71
+ 'search',
72
+ 'code-working',
73
+ 'heart',
74
+ 'content',
75
+ 'cut',
76
+ 'money-square',
77
+ 'logout',
78
+ 'cloud-upload',
79
+ 'lock',
80
+ 'corporate',
81
+ 'truth-none',
82
+ 'resize',
83
+ 'protect',
84
+ 'time',
85
+ 'date',
86
+ 'document-change',
87
+ 'scanner',
88
+ 'notification',
89
+ 'notification-outline',
90
+ 'silent',
91
+ 'heart-outline',
92
+ 'share',
93
+ 'pay',
94
+ 'picture',
95
+ 'desktop',
96
+ 'earphone',
97
+ 'cube',
98
+ 'user-verify',
99
+ 'fault',
100
+ 'location',
101
+ 'down-squared',
102
+ 'pay-dollar',
103
+ 'paperclip',
104
+ 'settings',
105
+ 'home',
106
+ 'more',
107
+ 'phonecall',
108
+ 'tag',
109
+ 'truth-circled',
110
+ 'refresh',
111
+ 'watch',
112
+ 'images',
113
+ 'sort',
114
+ 'money-circled',
115
+ 'trade',
116
+ 'star-outline',
117
+ 'minus-circled',
118
+ 'right',
119
+ 'left',
120
+ 'up',
121
+ 'down',
122
+ 'upward',
123
+ 'up-circled',
124
+ 'pin',
125
+ 'hide',
126
+ 'users',
127
+ 'user',
128
+ 'return-right',
129
+ 'message',
130
+ 'paper',
131
+ 'phonecall-prohibit',
132
+ 'speedometer',
133
+ 'settings-horizontal',
134
+ 'phone',
135
+ 'star',
136
+ 'play',
137
+ 'refresh-lock',
138
+ 'shield',
139
+ 'panel',
140
+ 'structure',
141
+ 'settings-vertical',
142
+ 'printer',
143
+ 'stop',
144
+ 'return-left',
145
+ 'question',
146
+ 'unlock',
147
+ 'sound-off',
148
+ 'up-squared',
149
+ 'sound-on',
150
+ 'upload',
151
+ 'tool',
152
+ 'visible',
153
+ 'truth',
154
+ ]
155
+ }
156
+ }
157
+ }
158
+ ```
@@ -0,0 +1,51 @@
1
+ ---
2
+ title: 禁用某些按钮和页码
3
+ order: 7
4
+ ---
5
+
6
+ 禁用按钮和页码有两种方式
7
+
8
+ 1. `disableBtn`只禁用页码按钮,“上一页”“下一页”按钮依然可点
9
+ 2. `disablePage`同时禁用页码按钮和“上一页”“下一页”按钮
10
+
11
+ 两个属性类型为:`(page: number, limit: number) => boolean`,返回`true`则禁用
12
+
13
+ ```vdt
14
+ import {Pagination} from 'kpc';
15
+
16
+ <div>
17
+ <Pagination v-model="value1" total={200} disableBtn={this.disableBtn} />
18
+ <Pagination v-model="value2" total={200} showGoto disablePage={this.disablePage} />
19
+ </div>
20
+ ```
21
+
22
+ ```styl
23
+ .k-pagination
24
+ margin-bottom 20px
25
+ ```
26
+
27
+ ```ts
28
+ interface Props {
29
+ value1?: number
30
+ value2?: number
31
+ }
32
+
33
+ export default class extends Component<Props> {
34
+ static template = template;
35
+
36
+ static defaults() {
37
+ return {
38
+ value1: 10,
39
+ value2: 10,
40
+ };
41
+ }
42
+
43
+ disableBtn(page: number, limit: number) {
44
+ return page > 10;
45
+ }
46
+
47
+ disablePage(page: number, limit: number) {
48
+ return page > 10;
49
+ }
50
+ }
51
+ ```
@@ -20,6 +20,8 @@ sidebar: doc
20
20
  | showTotal | 显示总条数 | `boolean` | `true` |
21
21
  | showGoto | 显示快速跳转框 | `boolean` | `false` |
22
22
  | showLimits | 是否显示每页条数选择框 | `boolean` | `true` |
23
+ | disableBtn | 只禁用页码按钮,“上一页”“下一页”按钮依然可点 | `(page: number, limit: number) => boolean` | `undefined` |
24
+ | disablePage | 同时禁用页码按钮和“上一页”“下一页”按钮 | `(page: number, limit: number) => boolean` | `undefined` |
23
25
 
24
26
  # 事件
25
27
 
@@ -1,6 +1,7 @@
1
1
  import BasicDemo from '~/components/pagination/demos/basic';
2
2
  import GotoDemo from '~/components/pagination/demos/goto';
3
3
  import CurrentDemo from '~/components/pagination/demos/current';
4
+ import DisableDemo from '~/components/pagination/demos/disable';
4
5
  import {mount, unmount, dispatchEvent, wait} from '../../test/utils';
5
6
 
6
7
  describe('Pagination', () => {
@@ -75,4 +76,17 @@ describe('Pagination', () => {
75
76
  expect(fn.callCount).to.eql(2);
76
77
  expect(fn.lastCall.lastArg).to.eql({value: 1, limit: 50});
77
78
  });
79
+
80
+ it('should not goto disabled page', async () => {
81
+ const [instance, element] = mount(DisableDemo);
82
+
83
+ const input = element.querySelector('.k-input-inner') as HTMLInputElement;
84
+ dispatchEvent(input, 'focus');
85
+ input.value = '11';
86
+ dispatchEvent(input, 'change');
87
+ dispatchEvent(input, 'blur');
88
+ await wait();
89
+ expect(input.value).to.eql('10');
90
+ expect(instance.get('value2')).to.eql(10);
91
+ });
78
92
  });
@@ -16,6 +16,8 @@ export interface PaginationProps {
16
16
  showTotal?: boolean,
17
17
  showGoto?: boolean,
18
18
  showLimits?: boolean,
19
+ disableBtn?: (page: number, limit: number) => boolean,
20
+ disablePage?: (page: number, limit: number) => boolean,
19
21
  }
20
22
 
21
23
  export interface PaginationEvents {
@@ -39,6 +41,8 @@ const typeDefs: Required<TypeDefs<PaginationProps>> = {
39
41
  showTotal: Boolean,
40
42
  showGoto: Boolean,
41
43
  showLimits: Boolean,
44
+ disableBtn: Function,
45
+ disablePage: Function,
42
46
  };
43
47
 
44
48
  const defaults = (): Partial<PaginationProps> => ({
@@ -132,7 +136,11 @@ export class Pagination extends Component<PaginationProps, PaginationEvents> {
132
136
 
133
137
  @bind
134
138
  private goto(e: InputEvent) {
139
+ const {disablePage, limit} = this.get();
135
140
  const value = parseInt((e.target as HTMLInputElement).value) || 1;
141
+ if (disablePage && disablePage(value, limit!)) {
142
+ return;
143
+ }
136
144
  this.changePage(value);
137
145
  }
138
146
  }
@@ -10,7 +10,7 @@ const {
10
10
  total, size, noBorder, simple,
11
11
  className, showTotal, showGoto,
12
12
  counts, value, limit, limits,
13
- showLimits
13
+ showLimits, disableBtn, disablePage
14
14
  } = this.get();
15
15
 
16
16
  if (!total) return <!-- pagination -->
@@ -32,11 +32,21 @@ if (noBorder || simple) {
32
32
  const totalPages = (Math.ceil(total / limit)) || 0;
33
33
 
34
34
  const paginationButton = function(page) {
35
+ let disabled = false;
36
+ if (page !== value) {
37
+ if (disablePage) {
38
+ disabled ||= !!disablePage(page, limit);
39
+ }
40
+ if (disableBtn) {
41
+ disabled ||= !!disableBtn(page, limit);
42
+ }
43
+ }
35
44
  return (
36
45
  <Button type={type}
37
46
  size={size}
38
47
  icon
39
48
  value={page}
49
+ disabled={disabled}
40
50
  >{page}</Button>
41
51
  );
42
52
  };
@@ -108,13 +118,13 @@ let nextPage = value + 1;
108
118
  <ButtonGroup checkType="radio" v-model="value">
109
119
  <Button icon size={size}
110
120
  type={type}
111
- disabled={value <= 1}
121
+ disabled={value <= 1 || !!(disablePage && disablePage(value - 1, limit))}
112
122
  ev-click={this.prev}
113
123
  ><Icon class="ion-ios-arrow-left" /></Button>
114
124
  <template>{paginationItems}</template>
115
125
  <Button icon size={size}
116
126
  type={type}
117
- disabled={value >= totalPages}
127
+ disabled={value >= totalPages || !!(disablePage && disablePage(value + 1, limit))}
118
128
  ev-click={this.next}
119
129
  ><Icon class="ion-ios-arrow-right" /></Button>
120
130
  </ButtonGroup>
@@ -93,6 +93,9 @@ export function makeStyles() {
93
93
  width: ${pagination.goto.width};
94
94
  margin: ${pagination.goto.gap};
95
95
  }
96
+ .k-input-inner {
97
+ text-align: center;
98
+ }
96
99
  }
97
100
 
98
101
  .k-select {
@@ -85,36 +85,46 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
85
85
  // update container if it has changed
86
86
  const lastProps = lastVNode.props!;
87
87
  const nextProps = nextVNode.props!;
88
- const lastContainer = this.container!;
89
- if (lastProps.container !== nextProps.container) {
90
- this.initContainer(nextProps.container, parentDom, anchor);
91
- }
92
- const nextContainer = this.container!;
93
-
94
- if (lastContainer === nextContainer) {
95
- patch(
96
- lastProps.children as VNode,
97
- nextProps.children as VNode,
98
- nextContainer,
99
- this,
100
- this.$SVG,
101
- anchor,
102
- mountedQueue,
103
- false,
104
- );
88
+ const update = () => {
89
+ const lastContainer = this.container!;
90
+
91
+ if (lastProps.container !== nextProps.container) {
92
+ this.initContainer(nextProps.container, parentDom, anchor);
93
+ }
94
+ const nextContainer = this.container!;
95
+
96
+ if (lastContainer === nextContainer) {
97
+ patch(
98
+ lastProps.children as VNode,
99
+ nextProps.children as VNode,
100
+ nextContainer,
101
+ this,
102
+ this.$SVG,
103
+ anchor,
104
+ mountedQueue,
105
+ false,
106
+ );
107
+ } else {
108
+ remove(lastProps.children as VNode, lastContainer, false);
109
+ mount(
110
+ nextProps.children as VNode,
111
+ nextContainer,
112
+ this,
113
+ this.$SVG,
114
+ anchor,
115
+ mountedQueue,
116
+ );
117
+ }
118
+
119
+ super.$update(lastVNode, nextVNode, parentDom, anchor, mountedQueue, force);
120
+ };
121
+
122
+ if (!this.container) {
123
+ // in react, sometimes $update will be called before mountedQueue in $render
124
+ mountedQueue.push(update);
105
125
  } else {
106
- remove(lastProps.children as VNode, lastContainer, false);
107
- mount(
108
- nextProps.children as VNode,
109
- nextContainer,
110
- this,
111
- this.$SVG,
112
- anchor,
113
- mountedQueue,
114
- );
126
+ update();
115
127
  }
116
-
117
- super.$update(lastVNode, nextVNode, parentDom, anchor, mountedQueue, force);
118
128
  }
119
129
 
120
130
  $unmount(vNode: VNodeComponentClass<this>, nextVNode: VNodeComponentClass<this> | null) {
@@ -35,8 +35,7 @@ export interface BaseSelectProps<V, Multipe extends boolean = boolean, Attach =
35
35
  placeholder?: Children
36
36
  container?: Container
37
37
  width?: string | number
38
-
39
- _show?: boolean
38
+ show?: boolean
40
39
  }
41
40
 
42
41
  export interface BaseSelectEvents {
@@ -68,8 +67,7 @@ const typeDefs: Required<TypeDefs<BaseSelectProps<any>>> = {
68
67
  placeholder: [String, Number],
69
68
  container: [Function, String],
70
69
  width: [String, Number],
71
-
72
- _show: Boolean,
70
+ show: Boolean,
73
71
  };
74
72
 
75
73
  const defaults = (): Partial<BaseSelectProps<any>> => ({
@@ -102,7 +100,7 @@ export abstract class BaseSelect<
102
100
 
103
101
  init() {
104
102
  provide(SELECT, this);
105
- useShowHideEvents('_show');
103
+ useShowHideEvents('show');
106
104
  // this.input = useInput();
107
105
 
108
106
  this.watch('value', this.position, {presented: true});
@@ -121,12 +119,12 @@ export abstract class BaseSelect<
121
119
 
122
120
  @bind
123
121
  show() {
124
- this.set('_show', true);
122
+ this.set('show', true);
125
123
  }
126
124
 
127
125
  @bind
128
126
  hide() {
129
- this.set('_show', false);
127
+ this.set('show', false);
130
128
  }
131
129
 
132
130
  public resetKeywords(keywords: State<string>) {