nhanh-pure-function 1.1.0 → 1.2.1

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.
package/lib/Index.d.ts CHANGED
@@ -1,3 +1,7 @@
1
1
  export * from "./Utility";
2
2
  export * from "./User";
3
-
3
+
4
+ // 提取单个函数的参数类型
5
+ export type ExtractParameters<T> = T extends (...args: infer P) => any
6
+ ? P
7
+ : never;
package/lib/Index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import "./index.css";
2
+
1
3
  export * from "./Utility";
2
4
  export * from "./User";
3
-
package/lib/User.d.ts CHANGED
@@ -1,26 +1,10 @@
1
1
  /**
2
- * 添加滚动触底事件
3
- * @param {滚动标签} element
2
+ * 滚动触底事件
4
3
  * @param {触底事件} callback
5
4
  */
6
- export function _AddScrollBottomListener(
7
- element: HTMLElement,
5
+ export function _ScrollBottomListener(
8
6
  callback: Function
9
- ): void;
10
-
11
- /**
12
- * 自动处理 currentPage * pageSize > total
13
- * @param ask 请求方法
14
- * @param config 请求参数
15
- */
16
- export function _PagingQuery<Ask extends Function>(
17
- ask: Ask,
18
- config: {
19
- currentPage: number;
20
- pageSize: number;
21
- [key: string]: any;
22
- }
23
- ): ReturnType<Ask> & { currentPage?: number };
7
+ ): (payload: Event) => void;
24
8
 
25
9
  /**
26
10
  * 纯数字转 数字加单位
@@ -70,10 +54,10 @@ export function _SetQuantifierAttribute<T>(
70
54
  */
71
55
  export function _SetDefaultValue<T>(
72
56
  data: T,
73
- options: {
57
+ options?: {
74
58
  defaultValue?: string;
75
59
  fieldsNotRequiringAction?: (string | number | symbol)[];
76
- } = {}
60
+ }
77
61
  ): T;
78
62
 
79
63
  /**
@@ -116,7 +100,7 @@ export function _SetPhoto<T>(
116
100
  */
117
101
  export function _Exhibit_details<T>(
118
102
  data: T,
119
- options: {
103
+ options?: {
120
104
  dictionaryOptions?: { [key in keyof T]: { [key: string | number]: any } };
121
105
  dictionaryLabel?: (keyof T)[];
122
106
  dictionaryLabelJoin?: (keyof T)[];
@@ -141,7 +125,7 @@ export function _Exhibit_details<T>(
141
125
  filterLabel?: (keyof T)[];
142
126
 
143
127
  defaultValue?: string;
144
- } = {}
128
+ }
145
129
  ): T;
146
130
 
147
131
  // 定义加载状态更新函数类型
@@ -149,7 +133,7 @@ type LoadingStateUpdater = (newState: boolean) => void;
149
133
  // 定义加载控制器的类型
150
134
  interface LoadingController {
151
135
  invokers: Set<any>; // 假设invoker可以是任何类型
152
- timer: NodeJS.Timeout | null;
136
+ timer: number | null;
153
137
  startTime: number;
154
138
  loadingState: LoadingStateUpdater;
155
139
  delayTime: number;
@@ -159,11 +143,9 @@ interface LoadingController {
159
143
  export class _LoadingController {
160
144
  #controllersCollection: Map<string, LoadingController>;
161
145
 
162
- constructor() {}
163
-
164
146
  // addController方法的类型定义
165
147
  addController(
166
- key?: string,
148
+ key: string,
167
149
  config: {
168
150
  loadingState: LoadingStateUpdater;
169
151
  delayTime?: number;
@@ -190,14 +172,20 @@ export class _LoadingController {
190
172
  type UiLibrary = "naiveUI" | "ElementPlus" | "Element";
191
173
  /**
192
174
  * 点击非指定dom(包含子级dom)时执行 callback
193
- * @param clickableSelector 允许点击的 dom 选择器
175
+ * @param querySelector 允许点击的 dom 顶层祖先元素选择器
194
176
  * @param callback 满足条件时执行的回调
195
- * @param uiLibrary 项目使用的 ui库 , 用于排除 ui库 创建的元素 , 避免点击 ui库 创建的元素时意外的执行 callback
177
+ *
178
+ * @param options 其他配置
179
+ * @param options.uiLibrary 项目使用的 ui库 , 用于排除 ui库 创建的元素 , 避免点击 ui库 创建的元素时意外的执行 callback
180
+ * @param options.isClickAllowed 是否允许该点击 ( 如果不确定可以返回 undefined )
196
181
  */
197
182
  export function _CloseOnOutsideClick(
198
- clickableSelector: string[],
183
+ querySelector: string[],
199
184
  callback: Function,
200
- uiLibrary?: UiLibrary[]
185
+ options?: {
186
+ uiLibrary?: UiLibrary[];
187
+ isClickAllowed?: (event: MouseEvent) => boolean | undefined;
188
+ }
201
189
  ): void;
202
190
 
203
191
  /** 拖拽配置 */
@@ -250,7 +238,7 @@ export class LocalDrag {
250
238
  * @param parentDom 被拖拽元素的祖先元素
251
239
  * @param option 局部拖拽配置
252
240
  */
253
- init(parentDom: HTMLElement, options: LocalDragOptions = {}): void;
241
+ init(parentDom: HTMLElement, options?: LocalDragOptions): void;
254
242
  /** 结束拖拽 */
255
243
  finish(): void;
256
244
  }
package/lib/User.js CHANGED
@@ -1,48 +1,18 @@
1
- import { _IsObject, _IsWithinErrorMargin, _NotNull } from "./Utility";
1
+ import { _IsObject, _NotNull } from "./Utility";
2
2
 
3
3
  /**
4
- * 添加滚动触底事件
5
- * @param {滚动标签} element
4
+ * 滚动触底事件
6
5
  * @param {触底事件} callback
7
6
  */
8
- export function _AddScrollBottomListener(element, callback) {
9
- element.addEventListener("scroll", function () {
10
- if (
11
- _IsWithinErrorMargin(
12
- element.scrollTop + element.clientHeight,
13
- element.scrollHeight,
14
- 2
15
- )
16
- ) {
7
+ export function _ScrollBottomListener(callback) {
8
+ return function (payload) {
9
+ const target = payload.target;
10
+ const { scrollTop, scrollHeight, clientHeight } = target;
11
+ const bottom = scrollHeight - scrollTop - clientHeight;
12
+ if (bottom <= 1) {
17
13
  callback();
18
14
  }
19
- });
20
- }
21
-
22
- /**
23
- * 自动处理 currentPage * pageSize > total
24
- * @param ask 请求方法
25
- * @param config 请求参数
26
- */
27
- export function _PagingQuery(ask, config) {
28
- return new Promise(function (resolve, reject) {
29
- ask(config)
30
- .then((data) => {
31
- const { rows, total } = data;
32
- if (rows.length == 0 && total > 0) {
33
- config.currentPage = Math.ceil(total / config.pageSize);
34
- ask(config)
35
- .then((data) => {
36
- data.currentPage = config.currentPage;
37
- resolve(data);
38
- })
39
- .catch(reject);
40
- } else {
41
- resolve(data);
42
- }
43
- })
44
- .catch(reject);
45
- });
15
+ };
46
16
  }
47
17
 
48
18
  /**
@@ -413,17 +383,38 @@ export class _LoadingController {
413
383
 
414
384
  /**
415
385
  * 点击非指定dom(包含子级dom)时执行 callback
416
- * @param clickableSelector 允许点击的 dom 选择器
386
+ * @param querySelector 允许点击的 dom 顶层祖先元素选择器
417
387
  * @param callback 满足条件时执行的回调
418
- * @param uiLibrary 项目使用的 ui库 , 用于排除 ui库 创建的元素 , 避免点击 ui库 创建的元素时意外的执行 callback
388
+ *
389
+ * @param options 其他配置
390
+ * @param options.uiLibrary 项目使用的 ui库 , 用于排除 ui库 创建的元素 , 避免点击 ui库 创建的元素时意外的执行 callback
391
+ * @param options.isClickAllowed 是否允许该点击 ( 如果不确定可以返回 undefined )
419
392
  */
420
393
  export function _CloseOnOutsideClick(
421
- clickableSelector,
394
+ querySelector,
422
395
  callback,
423
- uiLibrary = ["naiveUI", "ElementPlus", "Element"]
396
+ options = {
397
+ uiLibrary: ["naiveUI", "ElementPlus", "Element"],
398
+ }
424
399
  ) {
400
+ function end() {
401
+ callback();
402
+ document.removeEventListener("mousedown", mousedown);
403
+ }
425
404
  function mousedown(event) {
405
+ const { isClickAllowed, uiLibrary } = options;
406
+
407
+ if (isClickAllowed) {
408
+ const bool = isClickAllowed(event);
409
+ if (bool) return;
410
+ if (bool === false) return end();
411
+ }
412
+
426
413
  const target = event.target;
414
+
415
+ /** 元素这时可能已经被删除了 */
416
+ if (!target?.closest("body")) return;
417
+
427
418
  const UI = (function (obj) {
428
419
  const arr = [];
429
420
  for (const key in obj) {
@@ -433,18 +424,19 @@ export function _CloseOnOutsideClick(
433
424
  }
434
425
  return arr;
435
426
  })({
436
- naiveUI: [".v-binder-follower-container"],
427
+ naiveUI: [
428
+ ".v-binder-follower-container",
429
+ ".n-image-preview-container",
430
+ ".n-modal-container",
431
+ ],
437
432
  ElementPlus: ["el-popper"],
438
433
  Element: ["el-popper"],
439
434
  });
440
- const isClickable = clickableSelector
435
+ const isClickable = querySelector
441
436
  .concat(UI)
442
437
  .some((className) => Boolean(target?.closest(className)));
443
438
 
444
- if (!isClickable) {
445
- callback();
446
- document.removeEventListener("mousedown", mousedown);
447
- }
439
+ if (!isClickable) end();
448
440
  }
449
441
  requestAnimationFrame(() =>
450
442
  document.addEventListener("mousedown", mousedown)
package/lib/Utility.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { ExtractParameters } from "./Index";
2
+
1
3
  /**
2
4
  * 非null | undefined判断
3
5
  * @param value any
@@ -40,7 +42,7 @@ export function _ConvertToPercentage(
40
42
  export function _WaitForCondition(
41
43
  conditionChecker: () => boolean,
42
44
  timeoutMillis: number
43
- ): Promise;
45
+ ): Promise<"完成" | "超时">;
44
46
 
45
47
  /**
46
48
  * 排除子串
@@ -116,7 +118,7 @@ export function _DownloadFile(href: string, fileName?: string): void;
116
118
  */
117
119
  export function _GetFrameRate(
118
120
  callback: (fps: number, frameTime: number) => void,
119
- referenceNode: number = 10
121
+ referenceNode: number
120
122
  ): void;
121
123
 
122
124
  /**
@@ -126,7 +128,7 @@ export function _GetFrameRate(
126
128
  */
127
129
  export function _Schedule(
128
130
  callback: (schedule: number) => void,
129
- TIME: number = 500
131
+ TIME: number
130
132
  ): void;
131
133
 
132
134
  /**
@@ -165,3 +167,38 @@ export function _CreateAndDownloadFile(
165
167
  fileName: string,
166
168
  options?: BlobPropertyBag
167
169
  ): void;
170
+
171
+ /**
172
+ * 获取url参数
173
+ * @param {string} url
174
+ * @returns {Object}
175
+ */
176
+ export function _GetQueryParams(url: string): void;
177
+
178
+ /**
179
+ * 生成uuid
180
+ * @returns {string}
181
+ */
182
+ export function _GenerateUUID(): string;
183
+
184
+ /**
185
+ * 防抖
186
+ * @param {Function} fn
187
+ * @param {number} delay
188
+ * @returns {Function}
189
+ */
190
+ export function _Debounce<T extends Function>(
191
+ fn: T,
192
+ delay: number
193
+ ): (...args: ExtractParameters<T>) => void;
194
+
195
+ /**
196
+ * 节流
197
+ * @param {Function} fn
198
+ * @param {number} delay
199
+ * @returns {Function}
200
+ */
201
+ export function _Throttle<T extends Function>(
202
+ fn: T,
203
+ delay: number
204
+ ): (...args: ExtractParameters<T>) => void;
package/lib/Utility.js CHANGED
@@ -328,3 +328,56 @@ export function _CreateAndDownloadFile(content, fileName, options) {
328
328
  // 最后,别忘了撤销 Blob 对象的 URL,以释放资源
329
329
  URL.revokeObjectURL(url);
330
330
  }
331
+
332
+ /**
333
+ * 获取url参数
334
+ * @param {string} url
335
+ * @returns {Object}
336
+ */
337
+ export function _GetQueryParams(url) {
338
+ return Object.fromEntries(new URL(url).searchParams);
339
+ }
340
+
341
+ /**
342
+ * 生成uuid
343
+ * @returns {string}
344
+ */
345
+ export function _GenerateUUID() {
346
+ return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function (c) {
347
+ const r = (Math.random() * 16) | 0; // 随机生成一个0到15的数
348
+ const v = c === "x" ? r : (r & 0x3) | 0x8; // 对于'y'位, v = (r & 0x3 | 0x8) 确保变体正确
349
+ return v.toString(16); // 将数字转换为16进制
350
+ });
351
+ }
352
+
353
+ /**
354
+ * 防抖
355
+ * @param {Function} fn
356
+ * @param {number} delay
357
+ * @returns {Function}
358
+ */
359
+ export function _Debounce(fn, delay) {
360
+ let timeoutId;
361
+ return function (...args) {
362
+ clearTimeout(timeoutId);
363
+ timeoutId = setTimeout(() => fn.apply(this, args), delay);
364
+ };
365
+ }
366
+
367
+ /**
368
+ * 节流
369
+ * @param {Function} fn
370
+ * @param {number} delay
371
+ * @returns {Function}
372
+ */
373
+ export function _Throttle(fn, delay) {
374
+ let timer;
375
+ return function (...args) {
376
+ if (!timer) {
377
+ timer = setTimeout(() => {
378
+ fn.apply(this, args);
379
+ timer = null;
380
+ }, delay);
381
+ }
382
+ };
383
+ }
package/lib/index.css ADDED
@@ -0,0 +1,8 @@
1
+ .no-select {
2
+ -webkit-user-select: none;
3
+ /* Safari */
4
+ -ms-user-select: none;
5
+ /* IE10+/Edge */
6
+ user-select: none;
7
+ /* Standard syntax */
8
+ }
package/lib/index.less ADDED
@@ -0,0 +1,5 @@
1
+ .no-select {
2
+ -webkit-user-select: none; /* Safari */
3
+ -ms-user-select: none; /* IE10+/Edge */
4
+ user-select: none; /* Standard syntax */
5
+ }
package/lib/test.ts ADDED
@@ -0,0 +1 @@
1
+ /** 用于测试 js / ts 功能实现及类型是否正确 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nhanh-pure-function",
3
- "version": "1.1.0",
3
+ "version": "1.2.1",
4
4
  "description": "纯函数工具",
5
5
  "main": "lib/Index.js",
6
6
  "scripts": {