@kine-design/core 0.0.1-beta.4 → 0.0.1-beta.6

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 (123) hide show
  1. package/.vlaude/last-session-id +1 -0
  2. package/components/base/affix/useAffix.ts +2 -1
  3. package/components/base/anchor/useAnchor.ts +2 -1
  4. package/components/base/autoComplete/useAutoComplete.ts +2 -1
  5. package/components/base/button/api.ts +1 -1
  6. package/components/base/button/props.d.ts +3 -1
  7. package/components/base/carousel/useCarousel.ts +2 -1
  8. package/components/base/cascader/useCascader.ts +2 -1
  9. package/components/base/checkbox/useCheckbox.ts +2 -1
  10. package/components/base/collapse/useCollapse.ts +2 -1
  11. package/components/base/datePicker/__tests__/useDatePicker.test.ts +239 -0
  12. package/components/base/datePicker/api.ts +4 -0
  13. package/components/base/datePicker/props.d.ts +26 -0
  14. package/components/base/dropdown/useDropdown.ts +2 -1
  15. package/components/base/image/__tests__/useImage.test.ts +174 -0
  16. package/components/base/input/api.ts +5 -1
  17. package/components/base/input/props.d.ts +26 -1
  18. package/components/base/input/useInput.ts +12 -2
  19. package/components/base/inputNumber/__tests__/useInputNumber.test.ts +153 -0
  20. package/components/base/inputNumber/api.ts +2 -1
  21. package/components/base/inputNumber/props.d.ts +9 -1
  22. package/components/base/inputNumber/useInputNumber.ts +53 -11
  23. package/components/base/loading/api.ts +1 -1
  24. package/components/base/loading/props.d.ts +3 -1
  25. package/components/base/popover/usePopover.ts +4 -3
  26. package/components/base/progress/api.ts +3 -1
  27. package/components/base/progress/props.d.ts +15 -0
  28. package/components/base/rate/useRate.ts +2 -1
  29. package/components/base/select/api.ts +3 -0
  30. package/components/base/select/props.d.ts +21 -1
  31. package/components/base/select/useSelect.ts +2 -1
  32. package/components/base/slider/api.ts +3 -1
  33. package/components/base/slider/props.d.ts +14 -0
  34. package/components/base/slider/useSlider.ts +6 -2
  35. package/components/base/steps/__tests__/useSteps.test.ts +46 -0
  36. package/components/base/switch/useSwitch.tsx +2 -1
  37. package/components/base/tabs/useTabs.ts +2 -1
  38. package/components/base/tag/api.ts +1 -1
  39. package/components/base/tag/props.d.ts +3 -1
  40. package/components/base/timePicker/__tests__/useTimePicker.test.ts +118 -0
  41. package/components/base/timePicker/api.ts +4 -1
  42. package/components/base/timePicker/props.d.ts +20 -0
  43. package/components/base/tooltip/api.ts +1 -0
  44. package/components/base/tooltip/props.d.ts +6 -0
  45. package/components/base/transfer/useTransfer.ts +2 -1
  46. package/components/base/tree/__tests__/tree.test.ts +214 -0
  47. package/components/message/dialog/api.ts +2 -1
  48. package/components/message/dialog/props.d.ts +7 -0
  49. package/components/message/drawer/api.ts +1 -0
  50. package/components/message/drawer/props.d.ts +7 -0
  51. package/components/message/notification/__tests__/useNotification.test.ts +129 -0
  52. package/components/message/popover/usePopover.ts +4 -4
  53. package/components/other/darkMode/useDarkMode.ts +2 -2
  54. package/components/template/menu/__tests__/useMenu.test.ts +157 -0
  55. package/components/template/pagination/__tests__/usePagination.test.ts +138 -0
  56. package/components/template/table/__tests__/useTable.test.ts +139 -0
  57. package/components/template/table/useTable.ts +2 -4
  58. package/components/types/hook.d.ts +11 -0
  59. package/components/types/props.d.ts +5 -0
  60. package/compositions/common/__tests__/useDebounceFn.test.ts +62 -0
  61. package/compositions/common/__tests__/useEventListener.test.ts +71 -0
  62. package/compositions/common/__tests__/usePopover.test.ts +38 -0
  63. package/compositions/common/__tests__/useTeleport.test.ts +25 -0
  64. package/compositions/common/useComponentSize.ts +17 -0
  65. package/compositions/common/useEventListener.ts +3 -3
  66. package/compositions/common/useResizeObserver.ts +6 -2
  67. package/compositions/input/__tests__/useBooleanInput.test.ts +73 -0
  68. package/compositions/modal/__tests__/useModal.test.ts +92 -0
  69. package/compositions/modal/useModal.ts +2 -2
  70. package/compositions/popper/useClickAway.ts +4 -4
  71. package/compositions/utils/__tests__/filters.test.ts +136 -0
  72. package/compositions/virtualList/__tests__/useHeightCache.test.ts +97 -0
  73. package/dist/components/base/affix/useAffix.d.ts +2 -1
  74. package/dist/components/base/anchor/useAnchor.d.ts +2 -1
  75. package/dist/components/base/autoComplete/useAutoComplete.d.ts +2 -1
  76. package/dist/components/base/carousel/useCarousel.d.ts +2 -1
  77. package/dist/components/base/cascader/useCascader.d.ts +2 -1
  78. package/dist/components/base/checkbox/useCheckbox.d.ts +2 -1
  79. package/dist/components/base/collapse/useCollapse.d.ts +2 -1
  80. package/dist/components/base/datePicker/__tests__/useDatePicker.test.d.ts +1 -0
  81. package/dist/components/base/dropdown/useDropdown.d.ts +2 -1
  82. package/dist/components/base/image/__tests__/useImage.test.d.ts +1 -0
  83. package/dist/components/base/input/useInput.d.ts +4 -1
  84. package/dist/components/base/inputNumber/__tests__/useInputNumber.test.d.ts +1 -0
  85. package/dist/components/base/inputNumber/useInputNumber.d.ts +2 -1
  86. package/dist/components/base/popover/usePopover.d.ts +2 -1
  87. package/dist/components/base/rate/useRate.d.ts +2 -1
  88. package/dist/components/base/select/useSelect.d.ts +2 -1
  89. package/dist/components/base/slider/useSlider.d.ts +2 -1
  90. package/dist/components/base/steps/__tests__/useSteps.test.d.ts +1 -0
  91. package/dist/components/base/switch/useSwitch.d.ts +2 -1
  92. package/dist/components/base/tabs/useTabs.d.ts +2 -1
  93. package/dist/components/base/timePicker/__tests__/useTimePicker.test.d.ts +1 -0
  94. package/dist/components/base/transfer/useTransfer.d.ts +2 -1
  95. package/dist/components/base/tree/__tests__/tree.test.d.ts +1 -0
  96. package/dist/components/message/notification/__tests__/useNotification.test.d.ts +1 -0
  97. package/dist/components/message/popover/usePopover.d.ts +1 -1
  98. package/dist/components/other/darkMode/useDarkMode.d.ts +2 -3
  99. package/dist/components/template/menu/__tests__/useMenu.test.d.ts +1 -0
  100. package/dist/components/template/pagination/__tests__/usePagination.test.d.ts +1 -0
  101. package/dist/components/template/table/__tests__/useTable.test.d.ts +1 -0
  102. package/dist/compositions/common/__tests__/useDebounceFn.test.d.ts +1 -0
  103. package/dist/compositions/common/__tests__/useEventListener.test.d.ts +1 -0
  104. package/dist/compositions/common/__tests__/usePopover.test.d.ts +1 -0
  105. package/dist/compositions/common/__tests__/useTeleport.test.d.ts +1 -0
  106. package/dist/compositions/common/useComponentSize.d.ts +6 -0
  107. package/dist/compositions/common/useEventListener.d.ts +2 -2
  108. package/dist/compositions/input/__tests__/useBooleanInput.test.d.ts +1 -0
  109. package/dist/compositions/modal/__tests__/useModal.test.d.ts +1 -0
  110. package/dist/compositions/modal/useModal.d.ts +2 -1
  111. package/dist/compositions/popper/useClickAway.d.ts +3 -3
  112. package/dist/compositions/utils/__tests__/filters.test.d.ts +1 -0
  113. package/dist/compositions/virtualList/__tests__/useHeightCache.test.d.ts +1 -0
  114. package/dist/core.js +153 -23
  115. package/dist/tools/__tests__/empty.test.d.ts +1 -0
  116. package/dist/tools/empty.d.ts +2 -2
  117. package/dist/tools/types.d.ts +1 -1
  118. package/dist/vitest.config.d.ts +10 -0
  119. package/package.json +6 -2
  120. package/tools/__tests__/empty.test.ts +72 -0
  121. package/tools/empty.ts +2 -2
  122. package/tools/types.ts +1 -1
  123. package/vitest.config.ts +17 -0
@@ -1,5 +1,6 @@
1
1
  import { SliderProps } from './props';
2
- export declare function useSlider(props: Required<SliderProps>, ctx: any): {
2
+ import { HookContext } from '../../types/hook';
3
+ export declare function useSlider(props: Required<SliderProps>, ctx: HookContext): {
3
4
  btnRef: import('vue').Ref<HTMLElement | null | undefined, HTMLElement | null | undefined>;
4
5
  sliderRef: import('vue').Ref<HTMLElement | null, HTMLElement | null>;
5
6
  perRef: import('vue').Ref<number, number>;
@@ -1,7 +1,8 @@
1
1
  import { SwitchProps } from './props';
2
+ import { HookContext } from '../../types/hook';
2
3
  export declare const switchIsBoolean: (value: SwitchProps["modelValue"]) => value is boolean;
3
4
  export declare const getIsActive: (value: SwitchProps["modelValue"], activeValue: SwitchProps["activeValue"]) => boolean;
4
- export declare function useSwitch<Props extends Record<string, any>>(props: Props, ctx: any): {
5
+ export declare function useSwitch<Props extends Record<string, any>>(props: Props, ctx: HookContext): {
5
6
  getInfo: (key: keyof Pick<SwitchProps, "activeInfo" | "inactiveInfo">) => any;
6
7
  changeSwitch: () => void;
7
8
  switchClass: import('vue').ComputedRef<(string | {
@@ -1,4 +1,5 @@
1
- export declare function useTabs<Props extends Record<string, unknown>>(props: Props, ctx: any): {
1
+ import { HookContext } from '../../types/hook';
2
+ export declare function useTabs<Props extends Record<string, unknown>>(props: Props, ctx: HookContext): {
2
3
  activeTab: import('vue').ComputedRef<string | number>;
3
4
  isActive: (name: string | number) => boolean;
4
5
  switchTab: (name: string | number, disabled?: boolean) => void;
@@ -1,5 +1,6 @@
1
1
  import { TransferItem, TransferProps } from './props';
2
- export declare function useTransfer(props: TransferProps, ctx: any): {
2
+ import { HookContext } from '../../types/hook';
3
+ export declare function useTransfer(props: TransferProps, ctx: HookContext): {
3
4
  leftSearch: import('vue').Ref<string, string>;
4
5
  rightSearch: import('vue').Ref<string, string>;
5
6
  leftData: import('vue').ComputedRef<TransferItem[]>;
@@ -0,0 +1 @@
1
+ export {};
@@ -50,7 +50,7 @@ export declare function usePopover(options: Options<{
50
50
  style: Ref<any, any>;
51
51
  arrowStyle: Ref<any, any>;
52
52
  lifecycle: {
53
- onBeforeDestroyEvents: Function[];
53
+ onBeforeUnmountEvents: Function[];
54
54
  };
55
55
  };
56
56
  export {};
@@ -1,9 +1,8 @@
1
+ import { HookContext } from '../../types/hook';
1
2
  import { DarkModeProps } from './props';
2
3
  /** 将暗色状态同步到 html[dark] attribute */
3
4
  declare function applyDarkAttr(isDark: boolean): void;
4
- export declare function useDarkMode(props: DarkModeProps, ctx: {
5
- emit: (event: string, ...args: any[]) => void;
6
- }): {
5
+ export declare function useDarkMode(props: DarkModeProps, ctx: Pick<HookContext, 'emit'>): {
7
6
  isDark: import('vue').Ref<boolean, boolean>;
8
7
  toggle: () => void;
9
8
  applyDarkAttr: typeof applyDarkAttr;
@@ -0,0 +1,6 @@
1
+ import { InjectionKey, Ref } from 'vue';
2
+ import { KineSize } from '../../components/types/props';
3
+ export declare const KINE_SIZE_KEY: InjectionKey<Ref<KineSize>>;
4
+ export declare function useComponentSize(props: {
5
+ size?: KineSize;
6
+ }): Ref<KineSize>;
@@ -7,7 +7,7 @@
7
7
  * 江湖的业务千篇一律,复杂的代码好几百行。
8
8
  */
9
9
  export type EventListenerOptions = {
10
- target: any;
10
+ target: EventTarget | (() => EventTarget);
11
11
  event: string;
12
12
  handler: EventListenerOrEventListenerObject;
13
13
  };
@@ -15,5 +15,5 @@ export default function useEventListener(options: EventListenerOptions): {
15
15
  add: () => void;
16
16
  remove: () => void;
17
17
  onMounted: () => void;
18
- onBeforeDestroy: () => void;
18
+ onBeforeUnmount: () => void;
19
19
  };
@@ -1,9 +1,10 @@
1
+ import { HookContext } from '../../components/types/hook';
1
2
  import { ModelMask } from '../../types/common/model';
2
3
  export interface UseModalProps {
3
4
  visible?: boolean;
4
5
  mask?: ModelMask;
5
6
  }
6
- export declare function useModal(props: UseModalProps, emit: (...args: any[]) => void): {
7
+ export declare function useModal(props: UseModalProps, emit: HookContext['emit']): {
7
8
  visible: import('vue').Ref<boolean, boolean>;
8
9
  open: () => void;
9
10
  close: () => void;
@@ -1,9 +1,9 @@
1
1
  export default function useClickAway(options: {
2
- target: any;
3
- handler: (event: any) => void;
2
+ target: EventTarget | (() => EventTarget | null | undefined);
3
+ handler: (event: PointerEvent) => void;
4
4
  }): {
5
5
  add: () => void;
6
6
  remove: () => void;
7
7
  onMounted: () => void;
8
- onBeforeDestroy: () => void;
8
+ onBeforeUnmount: () => void;
9
9
  } | undefined;
package/dist/core.js CHANGED
@@ -56,6 +56,22 @@ var props$49 = {
56
56
  autofocus: {
57
57
  type: Boolean,
58
58
  default: false
59
+ },
60
+ clearable: {
61
+ type: Boolean,
62
+ default: false
63
+ },
64
+ size: {
65
+ type: String,
66
+ default: void 0
67
+ },
68
+ maxlength: {
69
+ type: Number,
70
+ default: void 0
71
+ },
72
+ showWordLimit: {
73
+ type: Boolean,
74
+ default: false
59
75
  }
60
76
  };
61
77
  //#endregion
@@ -71,7 +87,8 @@ function useInput(props, ctx) {
71
87
  placeholder: props.placeholder,
72
88
  disabled: props.disabled,
73
89
  type: props.type,
74
- readOnly: props.readonly
90
+ readOnly: props.readonly,
91
+ maxLength: props.maxlength
75
92
  };
76
93
  const onInput = (e) => {
77
94
  ctx.emit("update:modelValue", e.target.value);
@@ -83,6 +100,11 @@ function useInput(props, ctx) {
83
100
  const onBlur = (e) => {
84
101
  ctx.emit("blur", e);
85
102
  };
103
+ const onClear = () => {
104
+ ctx.emit("update:modelValue", "");
105
+ ctx.emit("input", "");
106
+ ctx.emit("clear");
107
+ };
86
108
  return {
87
109
  baseProps,
88
110
  inputType,
@@ -90,7 +112,8 @@ function useInput(props, ctx) {
90
112
  rowInfo,
91
113
  onInput,
92
114
  onFocus,
93
- onBlur
115
+ onBlur,
116
+ onClear
94
117
  };
95
118
  }
96
119
  //#endregion
@@ -144,7 +167,7 @@ var props$48 = {
144
167
  },
145
168
  size: {
146
169
  type: String,
147
- default: "medium",
170
+ default: void 0,
148
171
  enum: [
149
172
  "large",
150
173
  "medium",
@@ -255,6 +278,18 @@ var props$47 = {
255
278
  fetch: {
256
279
  type: Function,
257
280
  default: void 0
281
+ },
282
+ clearable: {
283
+ type: Boolean,
284
+ default: false
285
+ },
286
+ size: {
287
+ type: String,
288
+ default: void 0
289
+ },
290
+ loading: {
291
+ type: Boolean,
292
+ default: false
258
293
  }
259
294
  };
260
295
  //#endregion
@@ -799,7 +834,7 @@ var TagCore = { props: {
799
834
  },
800
835
  size: {
801
836
  type: String,
802
- default: "medium"
837
+ default: void 0
803
838
  },
804
839
  closable: {
805
840
  type: Boolean,
@@ -813,6 +848,10 @@ var TagCore = { props: {
813
848
  //#endregion
814
849
  //#region components/base/progress/api.ts
815
850
  var props$43 = {
851
+ type: {
852
+ type: String,
853
+ default: "line"
854
+ },
816
855
  value: {
817
856
  type: Number,
818
857
  default: 0
@@ -832,6 +871,10 @@ var props$43 = {
832
871
  strokeWidth: {
833
872
  type: Number,
834
873
  default: 4
874
+ },
875
+ width: {
876
+ type: Number,
877
+ default: 80
835
878
  }
836
879
  };
837
880
  //#endregion
@@ -1036,6 +1079,10 @@ var props$39 = {
1036
1079
  controls: {
1037
1080
  type: Boolean,
1038
1081
  default: true
1082
+ },
1083
+ size: {
1084
+ type: String,
1085
+ default: void 0
1039
1086
  }
1040
1087
  };
1041
1088
  //#endregion
@@ -1044,20 +1091,58 @@ var props$39 = {
1044
1091
  * @description inputNumber composable
1045
1092
  * @author 阿怪
1046
1093
  * @date 2026/2/25 00:00
1047
- * @version v1.1.0
1094
+ * @version v1.2.0
1048
1095
  *
1049
1096
  * 江湖的业务千篇一律,复杂的代码好几百行。
1097
+ *
1098
+ * v1.2.0 changelog:
1099
+ * - emit 类型保真:string 入 string 出,number 入 number 出;空值一律 emit null
1100
+ * - 内部 currentValue 保留中间态('-' / '0.' / ''),仅在 emit 时归一
1101
+ */
1102
+ /** 用户输入中间态:不构成可 emit 的数字,emit null */
1103
+ var MID_STATES = new Set([
1104
+ "",
1105
+ "-",
1106
+ ".",
1107
+ "-."
1108
+ ]);
1109
+ /**
1110
+ * 把任意内部值归一为 number | null。
1111
+ * 规则:
1112
+ * - null/undefined/中间态 → null
1113
+ * - 末尾小数点去掉('1.' → '1')
1114
+ * - 非法 NaN → null
1115
+ * - 其他 → Number(v)
1050
1116
  */
1117
+ var normalize = (v) => {
1118
+ if (v === null || v === void 0) return null;
1119
+ const s = String(v);
1120
+ if (MID_STATES.has(s)) return null;
1121
+ const cleaned = s.endsWith(".") ? s.slice(0, -1) : s;
1122
+ const n = Number(cleaned);
1123
+ return Number.isNaN(n) ? null : n;
1124
+ };
1051
1125
  function useInputNumber(props, ctx) {
1052
1126
  const currentValue = ref(props.modelValue ?? "");
1127
+ /**
1128
+ * 按外部 modelValue 的当前 typeof 决定出参类型,保真 v-model 声明。
1129
+ * - null/undefined → null
1130
+ * - 外部当前是 string → emit String(n)
1131
+ * - 否则 → emit n(默认 number)
1132
+ */
1133
+ const toEmitValue = (n) => {
1134
+ if (n === null) return null;
1135
+ return typeof props.modelValue === "string" ? String(n) : n;
1136
+ };
1053
1137
  const updateInput = (oldVal) => {
1054
- ctx.emit("update:modelValue", currentValue.value);
1055
- ctx.emit("change", currentValue.value, oldVal);
1138
+ const out = toEmitValue(normalize(currentValue.value));
1139
+ ctx.emit("update:modelValue", out);
1140
+ ctx.emit("change", out, oldVal);
1056
1141
  };
1057
1142
  const setCurrentValue = (newVal, e) => {
1058
1143
  const oldVal = currentValue.value;
1059
1144
  const { min, max, precision } = props;
1060
- if (oldVal === newVal) return;
1145
+ if (String(oldVal) === String(newVal)) return;
1061
1146
  else if (+newVal >= +max) newVal = max;
1062
1147
  else if (+newVal <= +min) newVal = min;
1063
1148
  else if (precision !== 0 && String(newVal).includes(".") && `${newVal}`.length - (`${newVal}`.indexOf(".") + 1) >= precision) newVal = Number(`${newVal}`.substring(0, `${newVal}`.indexOf(".") + (precision + 1)));
@@ -1085,11 +1170,15 @@ function useInputNumber(props, ctx) {
1085
1170
  validate(val, e);
1086
1171
  };
1087
1172
  const handleInputBlur = () => {
1173
+ const oldVal = currentValue.value;
1088
1174
  if (currentValue.value === "-") currentValue.value = "";
1089
1175
  else if (currentValue.value === "-0") currentValue.value = 0;
1090
- const oldVal = currentValue.value;
1091
- const str = String(currentValue.value);
1092
- currentValue.value = str.indexOf(".") === str.length - 1 ? str.replace(/\.$/g, "") : currentValue.value;
1176
+ else {
1177
+ const str = String(currentValue.value);
1178
+ if (str.indexOf(".") === str.length - 1 && str.length > 0) currentValue.value = str.replace(/\.$/g, "");
1179
+ }
1180
+ const n = normalize(currentValue.value);
1181
+ currentValue.value = n === null ? "" : n;
1093
1182
  updateInput(oldVal);
1094
1183
  };
1095
1184
  /**
@@ -1175,6 +1264,14 @@ var props$38 = {
1175
1264
  showStops: {
1176
1265
  type: Boolean,
1177
1266
  default: false
1267
+ },
1268
+ readonly: {
1269
+ type: Boolean,
1270
+ default: false
1271
+ },
1272
+ size: {
1273
+ type: String,
1274
+ default: void 0
1178
1275
  }
1179
1276
  };
1180
1277
  //#endregion
@@ -1197,13 +1294,17 @@ function useResizeObserver(target, callback, options = {}) {
1197
1294
  observer = void 0;
1198
1295
  }
1199
1296
  };
1200
- watch(target, () => {
1297
+ const stopWatch = watch(target, () => {
1201
1298
  if (target.value) {
1202
1299
  cleanup();
1203
1300
  observer = new ResizeObserver(callback);
1204
1301
  observer.observe(target.value, options);
1205
1302
  }
1206
1303
  });
1304
+ onBeforeUnmount(() => {
1305
+ cleanup();
1306
+ stopWatch();
1307
+ });
1207
1308
  return { cleanup };
1208
1309
  }
1209
1310
  //#endregion
@@ -1297,6 +1398,7 @@ function useSlider(props, ctx) {
1297
1398
  const btnW = 20;
1298
1399
  const sub = props.max - props.min;
1299
1400
  const movePositionHandler = (event, position) => {
1401
+ if (props.readonly) return position;
1300
1402
  const totalW = sliderSize.w.value - btnW;
1301
1403
  let positionX = position.x + event.dx;
1302
1404
  if (positionX > totalW) positionX = totalW;
@@ -1586,14 +1688,14 @@ function useEventListener(options) {
1586
1688
  const onMounted = () => {
1587
1689
  add();
1588
1690
  };
1589
- const onBeforeDestroy = () => {
1691
+ const onBeforeUnmount = () => {
1590
1692
  remove();
1591
1693
  };
1592
1694
  return {
1593
1695
  add,
1594
1696
  remove,
1595
1697
  onMounted,
1596
- onBeforeDestroy
1698
+ onBeforeUnmount
1597
1699
  };
1598
1700
  }
1599
1701
  //#endregion
@@ -1751,8 +1853,8 @@ function usePopover$1(props, ctx) {
1751
1853
  });
1752
1854
  onBeforeUnmount(() => {
1753
1855
  if (clickAwayInstance) {
1754
- const { onBeforeDestroy } = clickAwayInstance;
1755
- onBeforeDestroy();
1856
+ const { onBeforeUnmount } = clickAwayInstance;
1857
+ onBeforeUnmount();
1756
1858
  }
1757
1859
  instance?.destroy();
1758
1860
  });
@@ -1796,6 +1898,10 @@ var props$36 = {
1796
1898
  disabled: {
1797
1899
  type: Boolean,
1798
1900
  default: false
1901
+ },
1902
+ maxWidth: {
1903
+ type: String,
1904
+ default: void 0
1799
1905
  }
1800
1906
  };
1801
1907
  //#endregion
@@ -1917,7 +2023,7 @@ var LoadingCore = { props: {
1917
2023
  },
1918
2024
  size: {
1919
2025
  type: String,
1920
- default: "medium"
2026
+ default: void 0
1921
2027
  },
1922
2028
  mask: {
1923
2029
  type: Boolean,
@@ -1965,6 +2071,10 @@ var DialogCore = { props: {
1965
2071
  width: {
1966
2072
  type: String,
1967
2073
  default: void 0
2074
+ },
2075
+ beforeClose: {
2076
+ type: Function,
2077
+ default: void 0
1968
2078
  }
1969
2079
  } };
1970
2080
  //#endregion
@@ -2012,6 +2122,10 @@ var DrawerCore = { props: {
2012
2122
  height: {
2013
2123
  type: String,
2014
2124
  default: void 0
2125
+ },
2126
+ beforeClose: {
2127
+ type: Function,
2128
+ default: void 0
2015
2129
  }
2016
2130
  } };
2017
2131
  //#endregion
@@ -2602,6 +2716,22 @@ var props$25 = {
2602
2716
  disabled: {
2603
2717
  type: Boolean,
2604
2718
  default: false
2719
+ },
2720
+ readonly: {
2721
+ type: Boolean,
2722
+ default: false
2723
+ },
2724
+ clearable: {
2725
+ type: Boolean,
2726
+ default: false
2727
+ },
2728
+ size: {
2729
+ type: String,
2730
+ default: void 0
2731
+ },
2732
+ disabledDate: {
2733
+ type: Function,
2734
+ default: void 0
2605
2735
  }
2606
2736
  };
2607
2737
  //#endregion
@@ -3334,8 +3464,8 @@ function useTable() {
3334
3464
  });
3335
3465
  /** 从 data[i] 中安全取值 */
3336
3466
  const getData = (i, param) => {
3337
- if (data[i] && data[i][param]) return data[i][param];
3338
- return "";
3467
+ if (data[i] == null) return "";
3468
+ return data[i][param] ?? "";
3339
3469
  };
3340
3470
  /** 向每行的 td 列表中追加一列 */
3341
3471
  const pushTd = (param, bodySlot, style) => {
@@ -3925,7 +4055,7 @@ function usePopover(options, lifecycle) {
3925
4055
  const popoverLeave = () => {
3926
4056
  if (props.hover) instance?.hide();
3927
4057
  };
3928
- const onBeforeDestroyEvents = [];
4058
+ const onBeforeUnmountEvents = [];
3929
4059
  onMounted(() => {
3930
4060
  if (!popoverRef.value || !contentRef.value) return;
3931
4061
  popperInstance.value = createPopover(popoverRef.value, contentRef.value, arrowRef.value, {
@@ -3942,8 +4072,8 @@ function usePopover(options, lifecycle) {
3942
4072
  });
3943
4073
  onBeforeUnmount(() => {
3944
4074
  if (clickAwayInstance) {
3945
- const { onBeforeDestroy } = clickAwayInstance;
3946
- onBeforeDestroy();
4075
+ const { onBeforeUnmount } = clickAwayInstance;
4076
+ onBeforeUnmount();
3947
4077
  }
3948
4078
  instance?.destroy();
3949
4079
  });
@@ -3969,7 +4099,7 @@ function usePopover(options, lifecycle) {
3969
4099
  popperInstance,
3970
4100
  style,
3971
4101
  arrowStyle,
3972
- lifecycle: { onBeforeDestroyEvents }
4102
+ lifecycle: { onBeforeUnmountEvents }
3973
4103
  };
3974
4104
  }
3975
4105
  //#endregion
@@ -0,0 +1 @@
1
+ export {};
@@ -10,9 +10,9 @@
10
10
  * 支持稍多类型的判断非空的方法
11
11
  * @param value
12
12
  */
13
- export declare const notEmpty: (value: any) => number | boolean | undefined;
13
+ export declare const notEmpty: (value: unknown) => number | boolean | undefined;
14
14
  /**
15
15
  * 判断为空的方法,即notEmpty的取反
16
16
  * @param value
17
17
  */
18
- export declare const isEmpty: (value: any) => boolean;
18
+ export declare const isEmpty: (value: unknown) => boolean;
@@ -6,4 +6,4 @@
6
6
  *
7
7
  * 江湖的业务千篇一律,复杂的代码好几百行。
8
8
  */
9
- export declare const isBoolean: (val: any) => val is boolean;
9
+ export declare const isBoolean: (val: unknown) => val is boolean;
@@ -0,0 +1,10 @@
1
+ /**
2
+ * @description @kine-design/core 单元测试配置
3
+ * @author 阿怪
4
+ * @date 2026/3/23
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+ declare const _default: import('vite').UserConfig;
10
+ export default _default;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kine-design/core",
3
- "version": "0.0.1-beta.4",
3
+ "version": "0.0.1-beta.6",
4
4
  "description": "",
5
5
  "type": "module",
6
6
  "main": "./dist/core.js",
@@ -19,8 +19,12 @@
19
19
  "dist"
20
20
  ]
21
21
  },
22
+ "devDependencies": {
23
+ "vitest": "^4.1.0"
24
+ },
22
25
  "scripts": {
23
- "build": "vite build --config vite.config.build.ts"
26
+ "build": "vite build --config vite.config.build.ts",
27
+ "test": "vitest --config vitest.config.ts --run"
24
28
  },
25
29
  "module": "./dist/core.js",
26
30
  "exports": {
@@ -0,0 +1,72 @@
1
+ /**
2
+ * @description notEmpty / isEmpty 工具函数测试
3
+ * @author 阿怪
4
+ * @date 2026/3/23
5
+ * @version v1.0.0
6
+ *
7
+ * 江湖的业务千篇一律,复杂的代码好几百行。
8
+ */
9
+ import { describe, expect, it } from 'vitest';
10
+ import { notEmpty, isEmpty } from '../empty';
11
+
12
+ describe('notEmpty', () => {
13
+ // 基本空值
14
+ it('null 为空', () => expect(notEmpty(null)).toBe(false));
15
+ it('undefined 为空', () => expect(notEmpty(undefined)).toBe(false));
16
+
17
+ // 字符串
18
+ it('空字符串为空', () => expect(notEmpty('')).toBe(false));
19
+ it('非空字符串非空', () => expect(notEmpty('hello')).toBe(true));
20
+
21
+ // 数字
22
+ it('0 非空', () => expect(notEmpty(0)).toBe(true));
23
+ it('正数非空', () => expect(notEmpty(42)).toBe(true));
24
+ it('NaN 非空(数字类型)', () => expect(notEmpty(NaN)).toBe(true));
25
+
26
+ // 布尔
27
+ it('false 非空', () => expect(notEmpty(false)).toBe(true));
28
+ it('true 非空', () => expect(notEmpty(true)).toBe(true));
29
+
30
+ // 函数
31
+ it('函数非空', () => expect(notEmpty(() => {})).toBe(true));
32
+
33
+ // Symbol
34
+ it('空 Symbol 为空', () => expect(notEmpty(Symbol())).toBe(false));
35
+ it('有描述的 Symbol 非空', () => expect(notEmpty(Symbol('desc'))).toBe(true));
36
+
37
+ // 数组
38
+ it('空数组为空', () => expect(notEmpty([])).toBe(false));
39
+ it('非空数组非空', () => expect(notEmpty([1])).toBe(true));
40
+
41
+ // 对象
42
+ it('空对象为空', () => expect(notEmpty({})).toBe(false));
43
+ it('非空对象非空', () => expect(notEmpty({ a: 1 })).toBe(true));
44
+
45
+ // Map / Set
46
+ it('空 Map 为空', () => expect(notEmpty(new Map())).toBe(false));
47
+ it('非空 Map 非空', () => expect(notEmpty(new Map([['a', 1]]))).toBe(true));
48
+ it('空 Set 为空', () => expect(notEmpty(new Set())).toBe(false));
49
+ it('非空 Set 非空', () => expect(notEmpty(new Set([1]))).toBe(true));
50
+
51
+ // Date
52
+ it('有效 Date 非空', () => expect(notEmpty(new Date())).toBe(true));
53
+ it('Invalid Date 为空', () => expect(notEmpty(new Date('invalid'))).toBe(false));
54
+
55
+ // RegExp
56
+ it('空正则为空', () => expect(notEmpty(new RegExp(''))).toBe(false));
57
+ it('非空正则非空', () => expect(notEmpty(/abc/)).toBe(true));
58
+
59
+ // TypedArray
60
+ it('空 Uint8Array 为空', () => expect(notEmpty(new Uint8Array(0))).toBe(0));
61
+ it('非空 Float64Array 非空', () => expect(notEmpty(new Float64Array([1.5]))).toBe(1));
62
+ });
63
+
64
+ describe('isEmpty', () => {
65
+ it('是 notEmpty 的取反', () => {
66
+ expect(isEmpty(null)).toBe(true);
67
+ expect(isEmpty('hello')).toBe(false);
68
+ expect(isEmpty(0)).toBe(false);
69
+ expect(isEmpty([])).toBe(true);
70
+ expect(isEmpty({})).toBe(true);
71
+ });
72
+ });