@king-design/intact 2.0.8 → 2.0.10

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 (50) hide show
  1. package/components/datepicker/index.spec.ts +16 -10
  2. package/components/dialog/base.ts +3 -0
  3. package/components/dialog/index.md +1 -0
  4. package/components/dialog/useDraggable.ts +4 -2
  5. package/components/dialog/useEscClosable.ts +7 -3
  6. package/components/drawer/index.ts +1 -0
  7. package/components/portal.ts +30 -54
  8. package/components/select/base.ts +3 -0
  9. package/components/select/useBaseLabel.ts +6 -1
  10. package/dist/fonts/ionicons.eot +0 -0
  11. package/dist/fonts/ionicons.svg +2230 -0
  12. package/dist/fonts/ionicons.ttf +0 -0
  13. package/dist/fonts/ionicons.woff +0 -0
  14. package/dist/i18n/en-US.js +218 -0
  15. package/dist/i18n/en-US.min.js +1 -0
  16. package/dist/kpc.css +3 -0
  17. package/dist/kpc.js +39860 -0
  18. package/dist/kpc.min.js +1 -0
  19. package/dist/kpc.react.js +90483 -0
  20. package/dist/kpc.react.min.js +1 -0
  21. package/dist/kpc.vue.js +48096 -0
  22. package/dist/kpc.vue.min.js +1 -0
  23. package/dist/ksyun.css +3 -0
  24. package/es/components/datepicker/index.spec.js +28 -22
  25. package/es/components/dialog/base.d.ts +1 -0
  26. package/es/components/dialog/base.js +4 -2
  27. package/es/components/dialog/useDraggable.js +4 -1
  28. package/es/components/dialog/useEscClosable.js +9 -3
  29. package/es/components/drawer/index.js +2 -1
  30. package/es/components/portal.d.ts +1 -0
  31. package/es/components/portal.js +22 -48
  32. package/es/components/select/base.d.ts +1 -0
  33. package/es/components/select/base.js +1 -0
  34. package/es/components/select/useBaseLabel.d.ts +1 -0
  35. package/es/components/select/useBaseLabel.js +5 -1
  36. package/es/hooks/useDraggable.d.ts +1 -0
  37. package/es/hooks/useDraggable.js +2 -1
  38. package/es/index.d.ts +2 -2
  39. package/es/index.js +2 -2
  40. package/es/packages/kpc-react/__tests__/components/drawer.spec.js +53 -0
  41. package/es/packages/kpc-react/__tests__/components/dropdown.spec.js +107 -1
  42. package/es/packages/kpc-react/__tests__/components/{form.spec.d.ts → menu.spec.d.ts} +0 -0
  43. package/es/packages/kpc-react/__tests__/components/menu.spec.js +76 -0
  44. package/es/packages/kpc-react/__tests__/components/select.spec.d.ts +1 -0
  45. package/es/packages/kpc-react/__tests__/components/select.spec.js +64 -0
  46. package/es/packages/kpc-react/__tests__/components/tooltip.spec.d.ts +1 -0
  47. package/es/packages/kpc-react/__tests__/components/{form.spec.js → tooltip.spec.js} +1 -1
  48. package/hooks/useDraggable.ts +4 -1
  49. package/index.ts +2 -2
  50. package/package.json +3 -3
@@ -142,32 +142,38 @@ describe('Datepicker', () => {
142
142
  const [monthValues1, monthValues2]= content.querySelectorAll<HTMLElement>('.k-month-values');
143
143
 
144
144
  nextMonth.click();
145
+ const monthStart = (month + 1) % 12 + 1;
146
+ const yearStart = year + Math.floor((month + 1) / 12);
147
+ const monthEnd = (month + 2) % 12 + 1;
148
+ const yearEnd = year + Math.floor((month + 2) / 12);
145
149
  await wait();
146
- expect(monthValues1.textContent).to.eql(`${year}年${month + 1 + 1}月`);
147
- expect(monthValues2.textContent).to.eql(`${year}年${month + 1 + 2}月`);
150
+ expect(monthValues1.textContent).to.eql(`${yearStart}年${monthStart}月`);
151
+ expect(monthValues2.textContent).to.eql(`${yearEnd}年${monthEnd}月`);
148
152
 
149
153
  nextYear.click();
150
154
  await wait();
151
- expect(monthValues1.textContent).to.eql(`${year + 1}年${month + 1 + 1}月`);
152
- expect(monthValues2.textContent).to.eql(`${year + 1}年${month + 1 + 2}月`);
155
+ expect(monthValues1.textContent).to.eql(`${yearStart + 1}年${monthStart}月`);
156
+ expect(monthValues2.textContent).to.eql(`${yearEnd + 1}年${monthEnd}月`);
153
157
 
154
158
  const [prevYear] = panel2.querySelectorAll<HTMLElement>('.k-prev');
155
159
  prevYear.click();
156
160
  await wait();
157
- expect(monthValues1.textContent).to.eql(`${year}年${month + 1 + 1}月`);
158
- expect(monthValues2.textContent).to.eql(`${year}年${month + 1 + 2}月`);
161
+ expect(monthValues1.textContent).to.eql(`${yearStart}年${monthStart}月`);
162
+ expect(monthValues2.textContent).to.eql(`${yearEnd}年${monthEnd}月`);
159
163
 
160
164
  // year panel
161
165
  dispatchEvent(monthValues1.firstElementChild!, 'click');
162
166
  dispatchEvent(monthValues2.firstElementChild!, 'click');
163
167
  await wait();
164
- expect(monthValues1.textContent).to.eql(`${startYear}年 - ${startYear + 9}年`);
165
- expect(monthValues1.textContent).to.eql(monthValues2.textContent);
168
+ const firstDecadeStart = Math.floor(yearStart / 10) * 10;
169
+ const secondDecadeStart = Math.floor(yearEnd / 10) * 10;
170
+ expect(monthValues1.textContent).to.eql(`${firstDecadeStart}年 - ${firstDecadeStart + 9}年`);
171
+ expect(monthValues1.textContent).to.eql(`${secondDecadeStart}年 - ${secondDecadeStart + 9}年`);
166
172
 
167
173
  nextYear.click();
168
174
  await wait();
169
- expect(monthValues1.textContent).to.eql(`${startYear + 10}年 - ${startYear + 19}年`);
170
- expect(monthValues1.textContent).to.eql(monthValues2.textContent);
175
+ expect(monthValues1.textContent).to.eql(`${firstDecadeStart + 10}年 - ${secondDecadeStart + 19}年`);
176
+ expect(monthValues1.textContent).to.eql(`${secondDecadeStart + 10}年 - ${secondDecadeStart + 19}年`);
171
177
  });
172
178
 
173
179
  it('range year', async () => {
@@ -31,6 +31,7 @@ export interface BaseDialogProps {
31
31
  escClosable?: boolean
32
32
  width?: string | number
33
33
  mode?: 'destroy' | 'hide'
34
+ draggable?: boolean
34
35
  }
35
36
 
36
37
  export interface BaseDialogEvents {
@@ -68,6 +69,7 @@ const typeDefs: Required<TypeDefs<BaseDialogProps>> = {
68
69
  escClosable: Boolean,
69
70
  width: [String, Number],
70
71
  mode: ['destroy', 'hide'],
72
+ draggable: Boolean,
71
73
  };
72
74
 
73
75
  const defaults = (): Partial<BaseDialogProps> => ({
@@ -80,6 +82,7 @@ const defaults = (): Partial<BaseDialogProps> => ({
80
82
  closable: true,
81
83
  escClosable: true,
82
84
  mode: 'hide',
85
+ draggable: true,
83
86
  });
84
87
 
85
88
  const events: Events<BaseDialogEvents> = {
@@ -53,6 +53,7 @@ sidebar: doc
53
53
  | escClosable | 是否按ESC时关闭弹窗 | `boolean` | `true` |
54
54
  | width | 指定弹窗宽度,`number`类型时,单位为`px`;`string`类型时,需要指定单位 | `number` &#124; `string` | `undefined` |
55
55
  | mode | 指定主体元素在关闭状态下的渲染方式,`"destroy"`代表直接销毁,`"hide"`代表只是隐藏 | `"destroy"` &#124; `"hide"` | `"hide"` |
56
+ | draggable | 弹窗是否可拖拽 | `boolean` | `true` |
56
57
 
57
58
  ```ts
58
59
  export type Container = string | ((parentDom: Element, anchor: Node | null) => Element)
@@ -5,7 +5,7 @@ import type {Dialog} from './index';
5
5
 
6
6
  export function useDraggable(
7
7
  dialogRef: RefObject<HTMLDivElement>,
8
- areaRef: RefObject<HTMLDivElement>
8
+ areaRef: RefObject<HTMLDivElement>,
9
9
  ) {
10
10
  const component = useInstance() as Dialog;
11
11
  let x = 0;
@@ -60,5 +60,7 @@ export function useDraggable(
60
60
  style.top = `${top}px`;
61
61
  }
62
62
 
63
- return useBaseDraggable({onStart, onMove});
63
+ return useBaseDraggable({onStart, onMove, disable() {
64
+ return !component.get('draggable');
65
+ }});
64
66
  }
@@ -22,13 +22,17 @@ export function useEscClosable() {
22
22
  });
23
23
 
24
24
  function onHide() {
25
- const dialog = dialogs.pop();
25
+ // the order is uncertain in different frameworks
26
+ const index = dialogs.indexOf(instance);
27
+ // const dialog = dialogs.pop();
26
28
  // const dialog = dialogs.shift();
27
29
  if (process.env.NODE_ENV !== 'production') {
28
- if (dialog !== instance) {
29
- throw new Error('The dialog has handled hide callback. It is a bug of KPC');
30
+ // if (dialog !== instance) {
31
+ if (index === -1) {
32
+ throw new Error('The dialog has handled hide callback. Maybe it is a bug of KPC');
30
33
  }
31
34
  }
35
+ dialogs.splice(0, index);
32
36
 
33
37
  if (!dialogs.length) {
34
38
  document.removeEventListener('keydown', escClose);
@@ -15,6 +15,7 @@ const typeDefs: Required<TypeDefs<DrawerProps>> = {
15
15
  const defaults = (): Partial<DrawerProps> => ({
16
16
  ...BaseDialog.defaults(),
17
17
  placement: 'right',
18
+ draggable: false,
18
19
  });
19
20
 
20
21
  export class Drawer extends BaseDialog<DrawerProps> {
@@ -6,14 +6,10 @@ import {
6
6
  createCommentVNode,
7
7
  createTextVNode,
8
8
  mount,
9
- removeVNodeDom,
10
9
  patch,
11
10
  remove,
12
11
  TypeDefs,
13
- provide,
14
12
  inject,
15
- nextTick,
16
- callAll,
17
13
  } from 'intact';
18
14
  import {isString} from 'intact-shared';
19
15
  import {DIALOG} from './dialog/constants';
@@ -42,6 +38,7 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
42
38
  private dialog: Dialog | null = inject(DIALOG, null);
43
39
  public mountedQueue?: Function[];
44
40
  public mountedDone?: boolean;
41
+ public $isPortal = true;
45
42
 
46
43
  $render(
47
44
  lastVNode: VNodeComponentClass<this> | null,
@@ -50,46 +47,29 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
50
47
  anchor: IntactDom | null,
51
48
  mountedQueue: Function[]
52
49
  ) {
50
+ /**
51
+ * In React, we cannot render real elements in mountedQueue.
52
+ * Because the rendering time of react element is uncontrollable
53
+ */
54
+
55
+ const nextProps = nextVNode.props!;
56
+ const fakeContainer = document.createDocumentFragment();
57
+
53
58
  mountedQueue.push(() => {
54
- const nextProps = nextVNode.props!;
55
59
  const parentDom = this.$lastInput!.dom!.parentElement!;
56
- /**
57
- * initialize a new mountedQueue to place the callbacks of sub-components to it,
58
- * so that we can call them before the sibling components of the Portal
59
- */
60
- const mountedQueue: Function[] = [];
61
60
  this.initContainer(nextProps.container, parentDom, anchor);
62
-
63
- /**
64
- * Because we render real elements following parent has rendered.
65
- * In React, the $promises have done. Then we cannot add any promise to it.
66
- * We should find the parent component who holds the $promises object, and
67
- * reset it to let remaining element children add promise to it.
68
- */
69
- const parent = getParent(this) as any;
70
- if (parent) {
71
- parent.$promises.reset();
72
- }
73
-
74
- mount(
75
- nextProps.children as VNode,
76
- this.container!,
77
- this,
78
- this.$SVG,
79
- null,
80
- mountedQueue,
81
- );
82
-
83
- // in react, we should wait for all promises to resolve
84
- if (parent) {
85
- (Component as any).FakePromise.all(parent.$promises).then(() => {
86
- callAll(mountedQueue);
87
- });
88
- } else {
89
- callAll(mountedQueue);
90
- }
61
+ this.container!.appendChild(fakeContainer);
91
62
  });
92
63
 
64
+ mount(
65
+ nextProps.children as VNode,
66
+ fakeContainer as any,
67
+ this,
68
+ this.$SVG,
69
+ null,
70
+ mountedQueue,
71
+ );
72
+
93
73
  super.$render(lastVNode, nextVNode, parentDom, anchor, mountedQueue);
94
74
  }
95
75
 
@@ -152,22 +132,18 @@ export class Portal<T extends PortalProps = PortalProps> extends Component<T> {
152
132
  }
153
133
  if (!this.container) {
154
134
  // find the closest dialog if exists
155
- let tmp;
156
- if ((tmp = this.dialog) && (tmp = tmp.dialogRef.value)) {
157
- this.container = tmp;
158
- } else {
159
- this.container = document.body;
160
- }
161
- }
162
- }
163
- }
135
+ this.container = parentDom.closest('.k-dialog') || document.body;
164
136
 
165
- function getParent($senior: Component): Component | null {
166
- while ($senior = $senior.$senior as Component) {
167
- if (($senior as any)._reactInternals) {
168
- return $senior;
137
+ /**
138
+ * @FIXME: We cannot get parent ref from sub component in Vue
139
+ */
140
+ // find the closest dialog if exists
141
+ // let tmp;
142
+ // if ((tmp = this.dialog) && (tmp !== this.$senior) && (tmp = tmp.dialogRef.value)) {
143
+ // this.container = tmp;
144
+ // } else {
145
+ // this.container = document.body;
146
+ // }
169
147
  }
170
148
  }
171
- return null;
172
149
  }
173
-
@@ -88,6 +88,9 @@ export abstract class BaseSelect<
88
88
  E extends BaseSelectEvents = BaseSelectEvents,
89
89
  B extends BaseSelectBlocks<any> = BaseSelectBlocks<any>,
90
90
  > extends Component<T, E, B> {
91
+ // for intact-react, intact-vue-next and intact-vue
92
+ static $doubleVNodes = true;
93
+
91
94
  static template = template;
92
95
  static typeDefs = typeDefs;
93
96
  static defaults = defaults;
@@ -1,10 +1,11 @@
1
1
  import {Children, useInstance, Component} from 'intact';
2
2
  import {isNullOrUndefined, isStringOrNumber} from 'intact-shared';
3
- import {isEmptyString} from '../utils';
3
+ import {isEmptyString, getTextByChildren} from '../utils';
4
4
 
5
5
  type BaseLabelProps = {
6
6
  value: any,
7
7
  multiple: boolean,
8
+ filterable: boolean,
8
9
  }
9
10
 
10
11
  export function useBaseLabel<T, C extends Component<P>, P extends BaseLabelProps>(
@@ -41,6 +42,10 @@ export function useBaseLabel<T, C extends Component<P>, P extends BaseLabelProps
41
42
  if (isNullOrUndefined(label)) {
42
43
  label = labelMap.get(value);
43
44
  } else {
45
+ if (instance.get('filterable')) {
46
+ label = getTextByChildren(label);
47
+ }
48
+
44
49
  labelMap.set(value, label);
45
50
  }
46
51
 
Binary file