@whitesev/pops 1.4.0 → 1.5.0

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 (105) hide show
  1. package/dist/index.amd.js.map +1 -1
  2. package/dist/index.cjs.js.map +1 -1
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.iife.js.map +1 -1
  5. package/dist/index.system.js.map +1 -1
  6. package/dist/index.umd.js.map +1 -1
  7. package/package.json +50 -48
  8. package/src/Config.ts +3 -0
  9. package/src/Core.ts +45 -0
  10. package/src/Pops.ts +340 -0
  11. package/src/components/alert/index.css +45 -0
  12. package/src/components/alert/index.ts +216 -0
  13. package/src/components/alert/indexType.ts +30 -0
  14. package/src/components/confirm/index.css +45 -0
  15. package/src/components/confirm/index.ts +264 -0
  16. package/src/components/confirm/indexType.ts +17 -0
  17. package/src/components/drawer/index.css +47 -0
  18. package/src/components/drawer/index.ts +338 -0
  19. package/src/components/drawer/indexType.ts +53 -0
  20. package/src/components/folder/folderIcon.ts +28 -0
  21. package/src/components/folder/index.css +291 -0
  22. package/src/components/folder/index.ts +1111 -0
  23. package/src/components/folder/indexType.ts +87 -0
  24. package/src/components/iframe/index.css +90 -0
  25. package/src/components/iframe/index.ts +415 -0
  26. package/src/components/iframe/indexType.ts +144 -0
  27. package/src/components/loading/index.css +60 -0
  28. package/src/components/loading/index.ts +123 -0
  29. package/src/components/loading/indexType.ts +31 -0
  30. package/src/components/panel/buttonType.ts +60 -0
  31. package/src/components/panel/commonType.ts +50 -0
  32. package/src/components/panel/deepMenuType.ts +59 -0
  33. package/src/components/panel/formsType.ts +32 -0
  34. package/src/components/panel/index.css +754 -0
  35. package/src/components/panel/index.ts +2435 -0
  36. package/src/components/panel/indexType.ts +107 -0
  37. package/src/components/panel/inputType.ts +65 -0
  38. package/src/components/panel/ownType.ts +28 -0
  39. package/src/components/panel/selectType.ts +80 -0
  40. package/src/components/panel/sliderType.ts +59 -0
  41. package/src/components/panel/switchType.ts +43 -0
  42. package/src/components/panel/textareaType.ts +54 -0
  43. package/src/components/prompt/index.css +60 -0
  44. package/src/components/prompt/index.ts +293 -0
  45. package/src/components/prompt/indexType.ts +47 -0
  46. package/src/components/rightClickMenu/index.ts +729 -0
  47. package/src/components/rightClickMenu/indexType.ts +89 -0
  48. package/src/components/searchSuggestion/index.css +0 -0
  49. package/src/components/searchSuggestion/index.ts +656 -0
  50. package/src/components/searchSuggestion/indexType.ts +238 -0
  51. package/src/components/tooltip/index.css +171 -0
  52. package/src/components/tooltip/index.ts +358 -0
  53. package/src/components/tooltip/indexType.ts +95 -0
  54. package/src/css/animation.css +2240 -0
  55. package/src/css/button.css +290 -0
  56. package/src/css/common.css +24 -0
  57. package/src/css/index.css +135 -0
  58. package/src/css/ninePalaceGridPosition.css +50 -0
  59. package/src/css/scrollbar.css +18 -0
  60. package/src/handler/PopsElementHandler.ts +353 -0
  61. package/src/handler/PopsHandler.ts +659 -0
  62. package/src/svg/arrowLeft.svg +4 -0
  63. package/src/svg/arrowRight.svg +4 -0
  64. package/src/svg/chromeFilled.svg +14 -0
  65. package/src/svg/circleClose.svg +8 -0
  66. package/src/svg/close.svg +5 -0
  67. package/src/svg/cpu.svg +8 -0
  68. package/src/svg/delete.svg +5 -0
  69. package/src/svg/documentCopy.svg +5 -0
  70. package/src/svg/edit.svg +8 -0
  71. package/src/svg/eleme.svg +5 -0
  72. package/src/svg/elemePlus.svg +5 -0
  73. package/src/svg/headset.svg +5 -0
  74. package/src/svg/hide.svg +8 -0
  75. package/src/svg/keyboard.svg +8 -0
  76. package/src/svg/loading.svg +5 -0
  77. package/src/svg/max.svg +5 -0
  78. package/src/svg/min.svg +5 -0
  79. package/src/svg/mise.svg +5 -0
  80. package/src/svg/monitor.svg +5 -0
  81. package/src/svg/next.svg +5 -0
  82. package/src/svg/picture.svg +8 -0
  83. package/src/svg/prev.svg +5 -0
  84. package/src/svg/search.svg +5 -0
  85. package/src/svg/share.svg +5 -0
  86. package/src/svg/upload.svg +5 -0
  87. package/src/svg/videoPause.svg +5 -0
  88. package/src/svg/videoPlay.svg +5 -0
  89. package/src/svg/view.svg +5 -0
  90. package/src/types/PopsDOMUtilsEventType.d.ts +246 -0
  91. package/src/types/animation.d.ts +19 -0
  92. package/src/types/button.d.ts +226 -0
  93. package/src/types/components.d.ts +197 -0
  94. package/src/types/event.d.ts +62 -0
  95. package/src/types/global.d.ts +11 -0
  96. package/src/types/icon.d.ts +32 -0
  97. package/src/types/layer.d.ts +20 -0
  98. package/src/types/main.d.ts +136 -0
  99. package/src/types/mask.d.ts +35 -0
  100. package/src/types/position.d.ts +60 -0
  101. package/src/utils/AnyTouch.js +1394 -0
  102. package/src/utils/PopsDOMUtils.ts +2013 -0
  103. package/src/utils/PopsInstanceUtils.ts +685 -0
  104. package/src/utils/PopsMathUtils.ts +77 -0
  105. package/src/utils/PopsUtils.ts +380 -0
@@ -0,0 +1,2435 @@
1
+ import { PopsElementHandler } from "../../handler/PopsElementHandler";
2
+ import { PopsHandler } from "../../handler/PopsHandler";
3
+ import { pops } from "../../Pops";
4
+ import { popsDOMUtils } from "../../utils/PopsDOMUtils";
5
+ import { PopsMathFloatUtils } from "../../utils/PopsMathUtils";
6
+ import { PopsInstanceUtils } from "../../utils/PopsInstanceUtils";
7
+ import { popsUtils } from "../../utils/PopsUtils";
8
+ import type { PopsToolTipDetails } from "../tooltip/indexType";
9
+ import type { PopsPanelButtonDetails } from "./buttonType";
10
+ import type { PopsPanelRightAsideContainerOptions } from "./commonType";
11
+ import type { PopsPanelDeepMenuDetails } from "./deepMenuType";
12
+ import type { PopsPanelFormsDetails } from "./formsType";
13
+ import type {
14
+ PopsPanelContentConfig,
15
+ PopsPanelDetails,
16
+ PopsPanelFormsTotalDetails,
17
+ } from "./indexType";
18
+ import { PopsPanelInputDetails } from "./inputType";
19
+ import type { PopsPanelOwnDetails } from "./ownType";
20
+ import type { PopsPanelSelectDetails } from "./selectType";
21
+ import type { PopsPanelSliderDetails } from "./sliderType";
22
+ import type { PopsPanelSwitchDetails } from "./switchType";
23
+ import type { PopsPanelTextAreaDetails } from "./textareaType";
24
+
25
+ export class PopsPanel {
26
+ constructor(details: PopsPanelDetails) {
27
+ const { $shadowContainer, $shadowRoot } = PopsHandler.handlerShadow();
28
+ PopsHandler.handleInit($shadowRoot, [
29
+ pops.config.cssText.index,
30
+ pops.config.cssText.ninePalaceGridPosition,
31
+ pops.config.cssText.scrollbar,
32
+ pops.config.cssText.button,
33
+ pops.config.cssText.anim,
34
+ pops.config.cssText.common,
35
+ pops.config.cssText.panelCSS,
36
+ ]);
37
+
38
+ let config: Required<PopsPanelDetails> = {
39
+ title: {
40
+ text: "默认标题",
41
+ position: "center",
42
+ html: false,
43
+ style: "",
44
+ },
45
+ content: [
46
+ {
47
+ id: "whitesev-panel-config-1",
48
+ title: "菜单配置1",
49
+ headerTitle: "菜单配置1",
50
+ isDefault: false,
51
+ attributes: [
52
+ {
53
+ "data-test": "test",
54
+ "data-test-2": "test2",
55
+ },
56
+ ],
57
+ forms: [
58
+ {
59
+ className: "forms-1",
60
+ text: "区域设置",
61
+ type: "forms",
62
+ attributes: [],
63
+ forms: [
64
+ {
65
+ className: "panel-switch",
66
+ text: "switch",
67
+ type: "switch",
68
+ attributes: [],
69
+ getValue() {
70
+ return true;
71
+ },
72
+ callback(event, value) {
73
+ console.log("按钮开启状态:", value);
74
+ },
75
+ },
76
+ {
77
+ className: "panel-slider",
78
+ text: "slider",
79
+ type: "slider",
80
+ attributes: [],
81
+ getValue() {
82
+ return 50;
83
+ },
84
+ callback(event, value) {
85
+ console.log("滑块当前数值:", value);
86
+ },
87
+ min: 1,
88
+ max: 100,
89
+ },
90
+ {
91
+ className: "panel-button",
92
+ text: "button",
93
+ type: "button",
94
+ attributes: [],
95
+ buttonIcon: "eleme",
96
+ buttonIconIsLoading: true,
97
+ buttonType: "warning",
98
+ buttonText: "warning按钮",
99
+ callback(event) {
100
+ console.log("点击按钮", event);
101
+ },
102
+ },
103
+ {
104
+ className: "panel-button",
105
+ text: "button",
106
+ type: "button",
107
+ attributes: [],
108
+ buttonIcon: "chromeFilled",
109
+ buttonIconIsLoading: true,
110
+ buttonType: "danger",
111
+ buttonText: "danger按钮",
112
+ callback(event) {
113
+ console.log("点击按钮", event);
114
+ },
115
+ },
116
+ {
117
+ className: "panel-button",
118
+ text: "button",
119
+ type: "button",
120
+ attributes: [],
121
+ buttonIcon: "upload",
122
+ buttonIconIsLoading: false,
123
+ buttonType: "info",
124
+ buttonText: "info按钮",
125
+ callback(event) {
126
+ console.log("点击按钮", event);
127
+ },
128
+ },
129
+ ],
130
+ },
131
+ ],
132
+ },
133
+ {
134
+ id: "whitesev-panel-config-2",
135
+ title: "菜单配置2",
136
+ headerTitle: "菜单配置2",
137
+ isDefault: true,
138
+ attributes: [
139
+ {
140
+ "data-value": "value",
141
+ "data-value-2": "value2",
142
+ },
143
+ ],
144
+ forms: [
145
+ {
146
+ className: "panel-input",
147
+ text: "input",
148
+ type: "input",
149
+ attributes: [],
150
+ getValue() {
151
+ return "50";
152
+ },
153
+ callback(event, value) {
154
+ console.log("输入框内容改变:", value);
155
+ },
156
+ placeholder: "请输入内容",
157
+ },
158
+ {
159
+ className: "panel-input-password",
160
+ text: "input-password",
161
+ type: "input",
162
+ attributes: [],
163
+ getValue() {
164
+ return "123456";
165
+ },
166
+ callback(event, value) {
167
+ console.log("密码输入框内容改变:", value);
168
+ },
169
+ isPassword: true,
170
+ placeholder: "请输入密码",
171
+ },
172
+ {
173
+ className: "panel-textarea",
174
+ text: "textarea",
175
+ type: "textarea",
176
+ attributes: [],
177
+ getValue() {
178
+ return "50";
179
+ },
180
+ callback(event, value) {
181
+ console.log("textarea输入框内容改变:", value);
182
+ },
183
+ placeholder: "请输入内容",
184
+ },
185
+ {
186
+ className: "panel-select",
187
+ text: "select",
188
+ type: "select",
189
+ attributes: [],
190
+ getValue() {
191
+ return 50;
192
+ },
193
+ callback(event, isSelectedValue, isSelectedText) {
194
+ console.log(
195
+ `select当前选项:${isSelectedValue},当前选项文本:${isSelectedText}`
196
+ );
197
+ },
198
+ data: [
199
+ {
200
+ value: "all",
201
+ text: "所有",
202
+ },
203
+ {
204
+ value: "text",
205
+ text: "文本",
206
+ },
207
+ {
208
+ value: "html",
209
+ text: "超文本",
210
+ },
211
+ ],
212
+ },
213
+ {
214
+ type: "forms",
215
+ text: "deep菜单",
216
+ forms: [
217
+ {
218
+ type: "deepMenu",
219
+ className: "panel-deepMenu",
220
+ text: "deepMenu",
221
+ description: "二级菜单",
222
+ rightText: "自定义配置",
223
+ arrowRightIcon: true,
224
+ clickCallBack(event, formConfig) {
225
+ console.log("进入子配置", event, formConfig);
226
+ },
227
+ forms: [
228
+ {
229
+ className: "forms-1",
230
+ text: "区域设置",
231
+ type: "forms",
232
+ attributes: [],
233
+ forms: [
234
+ {
235
+ className: "panel-switch",
236
+ text: "switch",
237
+ type: "switch",
238
+ attributes: [],
239
+ getValue() {
240
+ return true;
241
+ },
242
+ callback(event, value) {
243
+ console.log("按钮开启状态:", value);
244
+ },
245
+ },
246
+ {
247
+ className: "panel-slider",
248
+ text: "slider",
249
+ type: "slider",
250
+ attributes: [],
251
+ getValue() {
252
+ return 50;
253
+ },
254
+ callback(event, value) {
255
+ console.log("滑块当前数值:", value);
256
+ },
257
+ min: 1,
258
+ max: 100,
259
+ },
260
+ {
261
+ className: "panel-button",
262
+ text: "button",
263
+ type: "button",
264
+ attributes: [],
265
+ buttonIcon: "eleme",
266
+ buttonIconIsLoading: true,
267
+ buttonType: "warning",
268
+ buttonText: "warning按钮",
269
+ callback(event) {
270
+ console.log("点击按钮", event);
271
+ },
272
+ },
273
+ {
274
+ className: "panel-button",
275
+ text: "button",
276
+ type: "button",
277
+ attributes: [],
278
+ buttonIcon: "chromeFilled",
279
+ buttonIconIsLoading: true,
280
+ buttonType: "danger",
281
+ buttonText: "danger按钮",
282
+ callback(event) {
283
+ console.log("点击按钮", event);
284
+ },
285
+ },
286
+ {
287
+ className: "panel-button",
288
+ text: "button",
289
+ type: "button",
290
+ attributes: [],
291
+ buttonIcon: "upload",
292
+ buttonIconIsLoading: false,
293
+ buttonType: "info",
294
+ buttonText: "info按钮",
295
+ callback(event) {
296
+ console.log("点击按钮", event);
297
+ },
298
+ },
299
+ ],
300
+ },
301
+ ],
302
+ },
303
+ ],
304
+ },
305
+ ],
306
+ },
307
+ ],
308
+ btn: {
309
+ close: {
310
+ enable: true,
311
+ callback(event) {
312
+ event.close();
313
+ },
314
+ },
315
+ },
316
+ mask: {
317
+ enable: false,
318
+ clickEvent: {
319
+ toClose: false,
320
+ toHide: false,
321
+ },
322
+ clickCallBack: void 0,
323
+ },
324
+ class: "",
325
+ mobileClassName: "pops-panel-is-mobile",
326
+ isMobile: false,
327
+ only: false,
328
+ width: "700px",
329
+ height: "500px",
330
+ position: "center",
331
+ animation: "pops-anim-fadein-zoom",
332
+ zIndex: 10000,
333
+ drag: false,
334
+ dragLimit: true,
335
+ dragExtraDistance: 3,
336
+ dragMoveCallBack() {},
337
+ dragEndCallBack() {},
338
+ forbiddenScroll: false,
339
+ style: null,
340
+ beforeAppendToPageCallBack() {},
341
+ };
342
+ config = popsUtils.assign(config, details);
343
+ if (details && Array.isArray(details.content)) {
344
+ config.content = details.content;
345
+ }
346
+ let guid = popsUtils.getRandomGUID();
347
+ const PopsType = "panel";
348
+ config = PopsHandler.handleOnly(PopsType, config);
349
+ let maskHTML = PopsElementHandler.getMaskHTML(guid, config.zIndex);
350
+ let headerBtnHTML = PopsElementHandler.getHeaderBtnHTML(PopsType, config);
351
+ let { headerStyle, headerPStyle } = PopsElementHandler.getHeaderStyle(
352
+ PopsType,
353
+ config
354
+ );
355
+
356
+ let animHTML = PopsElementHandler.getAnimHTML(
357
+ guid,
358
+ PopsType,
359
+ config,
360
+ `
361
+ <div
362
+ class="pops-${PopsType}-title"
363
+ style="text-align: ${config.title.position};
364
+ ${headerStyle}">
365
+ ${
366
+ config.title.html
367
+ ? config.title.text
368
+ : `<p pops style="${headerPStyle}">${config.title.text}</p>`
369
+ }
370
+ ${headerBtnHTML}
371
+ </div>
372
+ <div class="pops-${PopsType}-content">
373
+ <aside class="pops-${PopsType}-aside">
374
+ <ul></ul>
375
+ </aside>
376
+ <section class="pops-${PopsType}-container">
377
+ <ul class="pops-panel-container-header-ul"></ul>
378
+ <ul></ul>
379
+ </section>
380
+ </div>`,
381
+ ""
382
+ );
383
+ /**
384
+ * 弹窗的主元素,包括动画层
385
+ */
386
+ let $anim = PopsElementHandler.parseElement<HTMLDivElement>(animHTML);
387
+ /* 结构元素 */
388
+ let {
389
+ popsElement: $pops,
390
+ headerCloseBtnElement: $headerCloseBtn,
391
+ titleElement: $title,
392
+ contentElement: $content,
393
+ contentAsideElement: $contentAside,
394
+ contentSectionContainerElement: $contentSectionContainer,
395
+ } = PopsHandler.handleQueryElement($anim, PopsType);
396
+ if (config.isMobile || pops.isPhone()) {
397
+ popsDOMUtils.addClassName($pops, config.mobileClassName);
398
+ }
399
+ /**
400
+ * 遮罩层元素
401
+ */
402
+ let $mask: HTMLDivElement | null = null;
403
+ /**
404
+ * 已创建的元素列表
405
+ */
406
+ let elementList: HTMLElement[] = [$anim];
407
+
408
+ /* 遮罩层元素 */
409
+ if (config.mask.enable) {
410
+ let _handleMask_ = PopsHandler.handleMask({
411
+ type: PopsType,
412
+ guid: guid,
413
+ config: config,
414
+ animElement: $anim,
415
+ maskHTML: maskHTML,
416
+ });
417
+ $mask = _handleMask_.maskElement;
418
+ elementList.push($mask);
419
+ }
420
+
421
+ /* 处理返回的配置 */
422
+ let eventDetails = PopsHandler.handleEventDetails(
423
+ guid,
424
+ $shadowContainer,
425
+ $shadowRoot,
426
+ PopsType,
427
+ $anim,
428
+ $pops,
429
+ $mask!,
430
+ config
431
+ );
432
+ /* 为顶部右边的关闭按钮添加点击事件 */
433
+ PopsHandler.handleClickEvent(
434
+ "close",
435
+ $headerCloseBtn,
436
+ eventDetails,
437
+ config.btn.close!.callback!
438
+ );
439
+
440
+ /* 创建到页面中 */
441
+ popsDOMUtils.append($shadowRoot, elementList);
442
+ if (typeof config.beforeAppendToPageCallBack === "function") {
443
+ config.beforeAppendToPageCallBack($shadowRoot, $shadowContainer);
444
+ }
445
+ popsDOMUtils.appendBody($shadowContainer);
446
+ /* 追加遮罩层元素 */
447
+ if ($mask != null) {
448
+ $anim.after($mask);
449
+ }
450
+
451
+ /**
452
+ * 处理内部配置
453
+ */
454
+ const HandleContetDetails = {
455
+ /**
456
+ * 左侧的ul容器
457
+ */
458
+ asideULElement: null as any as HTMLUListElement,
459
+ /**
460
+ * 右侧主内容的顶部文字ul容器
461
+ */
462
+ sectionContainerHeaderULElement: null as any as HTMLUListElement,
463
+ /**
464
+ * 右侧主内容的ul容器
465
+ */
466
+ sectionContainerULElement: null as any as HTMLUListElement,
467
+ init() {
468
+ this.asideULElement =
469
+ $contentAside.querySelector<HTMLUListElement>("ul")!;
470
+ this.sectionContainerHeaderULElement =
471
+ $contentSectionContainer.querySelectorAll<HTMLUListElement>("ul")[0];
472
+ this.sectionContainerULElement =
473
+ $contentSectionContainer.querySelectorAll<HTMLUListElement>("ul")[1];
474
+ /**
475
+ * 默认点击的左侧容器
476
+ */
477
+ let asideDefaultItemElement: HTMLLIElement | null = null;
478
+ let isScrollToDefaultView = false;
479
+ config.content.forEach((asideItem) => {
480
+ let asideLiElement = this.getAsideItem(asideItem);
481
+ this.setAsideItemClickEvent(asideLiElement, asideItem);
482
+ this.asideULElement.appendChild(asideLiElement);
483
+ if (asideDefaultItemElement == null) {
484
+ let flag = false;
485
+ if (typeof asideItem.isDefault === "function") {
486
+ flag = Boolean(asideItem.isDefault());
487
+ } else {
488
+ flag = Boolean(asideItem.isDefault);
489
+ }
490
+ if (flag) {
491
+ asideDefaultItemElement = asideLiElement;
492
+ isScrollToDefaultView = Boolean(asideItem.scrollToDefaultView);
493
+ }
494
+ }
495
+ });
496
+
497
+ /* 点击左侧列表 */
498
+ if (
499
+ asideDefaultItemElement == null &&
500
+ this.asideULElement.children.length
501
+ ) {
502
+ /* 默认第一个 */
503
+ asideDefaultItemElement = this.asideULElement
504
+ .children[0] as HTMLLIElement;
505
+ }
506
+ if (asideDefaultItemElement) {
507
+ /* 点击选择的那一项 */
508
+ asideDefaultItemElement.click();
509
+ if (isScrollToDefaultView) {
510
+ asideDefaultItemElement?.scrollIntoView();
511
+ }
512
+ } else {
513
+ console.error("pops.panel:左侧容器没有项");
514
+ }
515
+ },
516
+ /**
517
+ * 清空container容器的元素
518
+ */
519
+ clearContainer() {
520
+ this.sectionContainerHeaderULElement.innerHTML = "";
521
+ this.sectionContainerULElement.innerHTML = "";
522
+ $content
523
+ ?.querySelectorAll("section.pops-panel-deepMenu-container")
524
+ .forEach((ele) => ele.remove());
525
+ },
526
+ /**
527
+ * 清空左侧容器已访问记录
528
+ */
529
+ clearAsideItemIsVisited() {
530
+ $contentAside
531
+ .querySelectorAll<HTMLDivElement>(".pops-is-visited")
532
+ .forEach((element) => {
533
+ popsDOMUtils.removeClassName(element, "pops-is-visited");
534
+ });
535
+ },
536
+ /**
537
+ * 设置左侧容器已访问记录
538
+ * @param element
539
+ */
540
+ setAsideItemIsVisited(element: HTMLElement) {
541
+ popsDOMUtils.addClassName(element, "pops-is-visited");
542
+ },
543
+ /**
544
+ * 为元素添加自定义属性
545
+ * @param element
546
+ * @param attributes
547
+ */
548
+ addElementAttributes(element: HTMLElement, attributes?: any) {
549
+ if (attributes == null) {
550
+ return;
551
+ }
552
+ if (Array.isArray(attributes)) {
553
+ attributes.forEach((attrObject) => {
554
+ this.addElementAttributes(element, attrObject);
555
+ });
556
+ } else {
557
+ Object.keys(attributes).forEach((attributeName) => {
558
+ element.setAttribute(attributeName, attributes[attributeName]);
559
+ });
560
+ }
561
+ },
562
+ /**
563
+ * 为元素设置(自定义)属性
564
+ * @param element
565
+ * @param props
566
+ */
567
+ setElementProps(element: HTMLElement, props?: any) {
568
+ if (props == null) {
569
+ return;
570
+ }
571
+ Object.keys(props).forEach((propName) => {
572
+ (element as any)[propName] = props[propName];
573
+ });
574
+ },
575
+ /**
576
+ * 获取左侧容器元素<li>
577
+ * @param asideConfig
578
+ * @returns
579
+ */
580
+ getAsideItem(asideConfig: PopsPanelContentConfig) {
581
+ let liElement = document.createElement("li");
582
+ liElement.id = asideConfig.id;
583
+ (liElement as any)["__forms__"] = asideConfig.forms;
584
+ liElement.innerHTML = asideConfig.title;
585
+ this.addElementAttributes(liElement, asideConfig.attributes);
586
+ this.setElementProps(liElement, asideConfig.props);
587
+ return liElement;
588
+ },
589
+ /**
590
+ * 获取中间容器的元素<li>
591
+ * type ==> switch
592
+ * @param formConfig
593
+ * @returns
594
+ */
595
+ getSectionContainerItem_switch(formConfig: PopsPanelSwitchDetails) {
596
+ let liElement = document.createElement("li");
597
+ (liElement as any)["__formConfig__"] = formConfig;
598
+ if (formConfig.className) {
599
+ liElement.className = formConfig.className;
600
+ }
601
+ this.addElementAttributes(liElement, formConfig.attributes);
602
+ this.setElementProps(liElement, formConfig.props);
603
+ /* 左边底部的描述的文字 */
604
+ let leftDescriptionText = "";
605
+ if (Boolean(formConfig.description)) {
606
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
607
+ }
608
+ liElement.innerHTML = `
609
+ <div class="pops-panel-item-left-text">
610
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
611
+ ${leftDescriptionText}
612
+ </div>
613
+ <div class="pops-panel-switch">
614
+ <input class="pops-panel-switch__input" type="checkbox">
615
+ <span class="pops-panel-switch__core">
616
+ <div class="pops-panel-switch__action">
617
+ </div>
618
+ </span>
619
+ </div>`;
620
+ const PopsPanelSwitch = {
621
+ [Symbol.toStringTag]: "PopsPanelSwitch",
622
+ $data: {
623
+ value: Boolean(formConfig.getValue()),
624
+ },
625
+ $ele: {
626
+ switch:
627
+ liElement.querySelector<HTMLDivElement>(".pops-panel-switch")!,
628
+ input: liElement.querySelector<HTMLInputElement>(
629
+ ".pops-panel-switch__input"
630
+ )!,
631
+ core: liElement.querySelector<HTMLSpanElement>(
632
+ ".pops-panel-switch__core"
633
+ )!,
634
+ },
635
+ init() {
636
+ this.setStatus(this.$data.value);
637
+ if (formConfig.disabled) {
638
+ this.disable();
639
+ }
640
+ this.setClickEvent();
641
+ },
642
+ setClickEvent() {
643
+ let that = this;
644
+ popsDOMUtils.on(this.$ele.core, "click", void 0, function (event) {
645
+ if (
646
+ that.$ele.input.disabled ||
647
+ that.$ele.switch.hasAttribute("data-disabled")
648
+ ) {
649
+ return;
650
+ }
651
+ that.$data.value = that.getStatus();
652
+ that.setStatus(that.$data.value);
653
+ if (typeof formConfig.callback === "function") {
654
+ formConfig.callback(event, that.$data.value);
655
+ }
656
+ });
657
+ },
658
+ /**
659
+ * 设置状态
660
+ */
661
+ setStatus(isChecked = false) {
662
+ isChecked = Boolean(isChecked);
663
+ this.$ele.input.checked = isChecked;
664
+ if (isChecked) {
665
+ popsDOMUtils.addClassName(
666
+ this.$ele.switch,
667
+ "pops-panel-switch-is-checked"
668
+ );
669
+ } else {
670
+ popsDOMUtils.removeClassName(
671
+ this.$ele.switch,
672
+ "pops-panel-switch-is-checked"
673
+ );
674
+ }
675
+ },
676
+ /**
677
+ * 根据className来获取逆反值
678
+ */
679
+ getStatus() {
680
+ let checkedValue = false;
681
+ if (
682
+ !popsDOMUtils.containsClassName(
683
+ this.$ele.switch,
684
+ "pops-panel-switch-is-checked"
685
+ )
686
+ ) {
687
+ checkedValue = true;
688
+ }
689
+ return checkedValue;
690
+ },
691
+ /**
692
+ * 禁用复选框
693
+ */
694
+ disable() {
695
+ this.$ele.input.disabled = true;
696
+ this.$ele.switch.setAttribute("data-disabled", "true");
697
+ },
698
+ /**
699
+ * 启用复选框
700
+ */
701
+ notDisable() {
702
+ this.$ele.input.disabled = false;
703
+ this.$ele.switch.removeAttribute("data-disabled");
704
+ },
705
+ };
706
+
707
+ PopsPanelSwitch.init();
708
+ (liElement as any)["data-switch"] = PopsPanelSwitch;
709
+ return liElement;
710
+ },
711
+ /**
712
+ * 获取中间容器的元素<li>
713
+ * type ==> slider
714
+ * @param formConfig
715
+ * @returns
716
+ */
717
+ getSectionContainerItem_slider(formConfig: PopsPanelSliderDetails) {
718
+ let liElement = document.createElement("li");
719
+ (liElement as any)["__formConfig__"] = formConfig;
720
+ if (formConfig.className) {
721
+ liElement.className = formConfig.className;
722
+ }
723
+ this.addElementAttributes(liElement, formConfig.attributes);
724
+ this.setElementProps(liElement, formConfig.props);
725
+ /* 左边底部的描述的文字 */
726
+ let leftDescriptionText = "";
727
+ if (Boolean(formConfig.description)) {
728
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
729
+ }
730
+ liElement.innerHTML = `
731
+ <div class="pops-panel-item-left-text">
732
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
733
+ ${leftDescriptionText}
734
+ </div>
735
+ <div class="pops-panel-slider">
736
+ <input type="range" min="${formConfig.min}" max="${formConfig.max}">
737
+ </div>`;
738
+
739
+ let rangeInputElement = liElement.querySelector<HTMLInputElement>(
740
+ ".pops-panel-slider input[type=range]"
741
+ )!;
742
+ if (formConfig.step) {
743
+ rangeInputElement.setAttribute("step", formConfig.step.toString());
744
+ }
745
+ rangeInputElement.value = formConfig.getValue().toString();
746
+ /**
747
+ * 获取提示的内容
748
+ * @param value
749
+ */
750
+ let getToolTipContent = function (value: number | string) {
751
+ if (typeof formConfig.getToolTipContent === "function") {
752
+ return formConfig.getToolTipContent(value as number);
753
+ } else {
754
+ return value as string;
755
+ }
756
+ };
757
+ let tooltip = pops.tooltip({
758
+ target: rangeInputElement.parentElement!,
759
+ content: getToolTipContent(rangeInputElement.value),
760
+ zIndex: 1000000,
761
+ className: "github-tooltip",
762
+ showBeforeCallBack() {
763
+ tooltip.toolTipNode.querySelector("div")!.innerText =
764
+ getToolTipContent(rangeInputElement.value);
765
+ },
766
+ alwaysShow: false,
767
+ only: false,
768
+ position: "top",
769
+ arrowDistance: 10,
770
+ });
771
+ popsDOMUtils.on(
772
+ rangeInputElement,
773
+ ["input", "propertychange"],
774
+ void 0,
775
+ function (event) {
776
+ tooltip.toolTipNode.querySelector("div")!.innerText =
777
+ getToolTipContent(rangeInputElement.value);
778
+ if (typeof formConfig.callback === "function") {
779
+ formConfig.callback(
780
+ event as InputEvent,
781
+ (event as any).target.value
782
+ );
783
+ }
784
+ }
785
+ );
786
+ return liElement;
787
+ },
788
+ /**
789
+ * 获取中间容器的元素<li>
790
+ * type ==> slider
791
+ * @param formConfig
792
+ * @returns
793
+ */
794
+ getSectionContainerItem_slider_new(formConfig: PopsPanelSliderDetails) {
795
+ let liElement = document.createElement("li");
796
+ (liElement as any)["__formConfig__"] = formConfig;
797
+ if (formConfig.className) {
798
+ liElement.className = formConfig.className;
799
+ }
800
+ this.addElementAttributes(liElement, formConfig.attributes);
801
+ this.setElementProps(liElement, formConfig.props);
802
+ /* 左边底部的描述的文字 */
803
+ let leftDescriptionText = "";
804
+ if (Boolean(formConfig.description)) {
805
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
806
+ }
807
+ liElement.innerHTML = `
808
+ <div class="pops-panel-item-left-text" style="flex: 1;">
809
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
810
+ ${leftDescriptionText}
811
+ </div>
812
+ <div class="pops-slider pops-slider-width">
813
+ <div class="pops-slider__runway">
814
+ <div class="pops-slider__bar" style="width: 0%; left: 0%"></div>
815
+ <div class="pops-slider__button-wrapper" style="left: 0%">
816
+ <div class="pops-slider__button"></div>
817
+ </div>
818
+ </div>
819
+ </div>`;
820
+ const PopsPanelSlider = {
821
+ [Symbol.toStringTag]: "PopsPanelSlider",
822
+ /**
823
+ * 值
824
+ */
825
+ value: formConfig.getValue(),
826
+ /**
827
+ * 最小值
828
+ */
829
+ min: formConfig.min,
830
+ /**
831
+ * 最大值
832
+ */
833
+ max: formConfig.max,
834
+ /**
835
+ * 间隔
836
+ */
837
+ step: formConfig.step || 1,
838
+ $data: {
839
+ /**
840
+ * 是否正在移动
841
+ */
842
+ isMove: false,
843
+ /**
844
+ * 是否已初始化已拖拽的距离
845
+ */
846
+ isInitDragPosition: false,
847
+ /**
848
+ * 是否正在检测是否停止拖拽
849
+ */
850
+ isCheckingStopDragMove: false,
851
+ /**
852
+ * 总宽度(px)
853
+ */
854
+ totalWidth: 0,
855
+ /**
856
+ * 每一块的间隔(px)
857
+ */
858
+ stepPx: 0,
859
+ /**
860
+ * 已拖拽的距离(px)
861
+ */
862
+ dragWidth: 0,
863
+ /**
864
+ * 已拖拽的百分比
865
+ */
866
+ dragPercent: 0,
867
+ /**
868
+ * 每一次块的信息
869
+ * 例如:当最小值是2,最大值是10,step为2
870
+ * 那么生成[2,4,6,8,10] 共计5个
871
+ * 又获取到当前滑块总长度是200px
872
+ * 那么生成映射
873
+ * 2 => 0px~40px
874
+ * 4 => 40px~80px
875
+ * 6 => 80px~120px
876
+ * 8 => 120px~160px
877
+ * 10 => 160px~200px
878
+ */
879
+ stepBlockMap: new Map<
880
+ number,
881
+ {
882
+ value: number;
883
+ px: number;
884
+ pxLeft: number;
885
+ pxRight: number;
886
+ percent: number;
887
+ }
888
+ >(),
889
+ },
890
+ $ele: {
891
+ slider: liElement.querySelector<HTMLDivElement>(".pops-slider")!,
892
+ runAway: liElement.querySelector<HTMLDivElement>(
893
+ ".pops-slider__runway"
894
+ )!,
895
+ bar: liElement.querySelector<HTMLDivElement>(".pops-slider__bar")!,
896
+ buttonWrapper: liElement.querySelector<HTMLDivElement>(
897
+ ".pops-slider__button-wrapper"
898
+ )!,
899
+ button: liElement.querySelector<HTMLDivElement>(
900
+ ".pops-slider__button"
901
+ )!,
902
+ tooltip: null as any as {
903
+ $shadowContainer: HTMLDivElement;
904
+ $shadowRoot: ShadowRoot;
905
+ guid: string;
906
+ config: Required<PopsToolTipDetails>;
907
+ toolTipNode: HTMLDivElement;
908
+ show: () => void;
909
+ close: () => void;
910
+ off: () => void;
911
+ on: () => void;
912
+ },
913
+ },
914
+ $interval: {
915
+ isCheck: false,
916
+ },
917
+ $tooltip: null as any,
918
+ init() {
919
+ this.initEleData();
920
+ this.setToolTipEvent();
921
+ this.setPanEvent();
922
+ this.setRunAwayClickEvent();
923
+ this.intervalInit();
924
+ if (formConfig.disabled) {
925
+ this.disableDrag();
926
+ }
927
+ },
928
+ /**
929
+ * 10s内循环获取slider的宽度等信息
930
+ * 获取到了就可以初始化left的值
931
+ * @param {number} [checkStepTime=200] 每次检测的间隔时间
932
+ * @param {number} [maxTime=10000] 最大的检测时间
933
+ */
934
+ intervalInit(checkStepTime = 200, maxTime = 10000) {
935
+ if (this.$interval.isCheck) {
936
+ return;
937
+ }
938
+ this.$interval.isCheck = true;
939
+ let isSuccess = false;
940
+ let oldTotalWidth = this.$data.totalWidth;
941
+ let timer: number | undefined = void 0;
942
+ let interval = setInterval(() => {
943
+ if (isSuccess) {
944
+ this.$interval.isCheck = false;
945
+ clearTimeout(timer);
946
+ clearInterval(interval);
947
+ } else {
948
+ this.initTotalWidth();
949
+ if (this.$data.totalWidth !== 0) {
950
+ isSuccess = true;
951
+ if (this.$data.totalWidth !== oldTotalWidth) {
952
+ /* slider的总宽度改变了 */
953
+ if (PopsMathFloatUtils.isFloat(this.step)) {
954
+ this.initFloatStepMap();
955
+ } else {
956
+ this.initStepMap();
957
+ }
958
+ this.initSliderPosition();
959
+ }
960
+ }
961
+ }
962
+ }, checkStepTime);
963
+ /* 最长检测时间是10s */
964
+ timer = setTimeout(() => {
965
+ clearInterval(interval);
966
+ }, maxTime);
967
+ },
968
+ /**
969
+ * 把数据添加到元素上
970
+ */
971
+ initEleData() {
972
+ this.$ele.slider.setAttribute("data-min", this.min.toString());
973
+ this.$ele.slider.setAttribute("data-max", this.max.toString());
974
+ this.$ele.slider.setAttribute("data-value", this.value.toString());
975
+ this.$ele.slider.setAttribute("data-step", this.step.toString());
976
+ (this.$ele.slider as any)["data-min"] = this.min;
977
+ (this.$ele.slider as any)["data-max"] = this.max;
978
+ (this.$ele.slider as any)["data-value"] = this.value;
979
+ (this.$ele.slider as any)["data-step"] = this.step;
980
+ },
981
+ /**
982
+ * 初始化滑块的总长度的数据(px)
983
+ */
984
+ initTotalWidth() {
985
+ this.$data.totalWidth = popsDOMUtils.width(this.$ele.runAway);
986
+ },
987
+ /**
988
+ * 初始化每一个块的具体数据信息
989
+ */
990
+ initStepMap() {
991
+ let index = 0;
992
+ // 计算出份数
993
+ let blockNums = (this.max - this.min) / this.step;
994
+ // 计算出每一份占据的px
995
+ this.$data.stepPx = this.$data.totalWidth / blockNums;
996
+ let widthPx = 0;
997
+ for (
998
+ let stepValue = this.min;
999
+ stepValue <= this.max;
1000
+ stepValue += this.step
1001
+ ) {
1002
+ let value = this.formatValue(stepValue);
1003
+ let info = {};
1004
+ if (value === this.min) {
1005
+ /* 起始 */
1006
+ info = {
1007
+ value: value,
1008
+ px: 0,
1009
+ pxLeft: 0,
1010
+ pxRight: this.$data.stepPx / 2,
1011
+ percent: 0,
1012
+ };
1013
+ } else {
1014
+ info = {
1015
+ value: value,
1016
+ px: widthPx,
1017
+ pxLeft: widthPx - this.$data.stepPx / 2,
1018
+ pxRight: widthPx + this.$data.stepPx / 2,
1019
+ percent: widthPx / this.$data.totalWidth,
1020
+ };
1021
+ //if (value === this.max) {
1022
+ // info["pxLeft"] = this.$data.stepBlockMap.get(
1023
+ // index - 1
1024
+ // ).pxRight;
1025
+ // info["pxRight"] = this.$data.totalWidth;
1026
+ //}
1027
+ }
1028
+ this.$data.stepBlockMap.set(index, info as any);
1029
+ index++;
1030
+ widthPx += this.$data.stepPx;
1031
+ }
1032
+ },
1033
+ /**
1034
+ * 初始化每一个块的具体数据信息(浮点)
1035
+ */
1036
+ initFloatStepMap() {
1037
+ let index = 0;
1038
+ // 计算出份数
1039
+ let blockNums = (this.max - this.min) / this.step;
1040
+ // 计算出每一份占据的px
1041
+ this.$data.stepPx = this.$data.totalWidth / blockNums;
1042
+ let widthPx = 0;
1043
+ for (
1044
+ let stepValue = this.min;
1045
+ stepValue <= this.max;
1046
+ stepValue = PopsMathFloatUtils.add(stepValue, this.step)
1047
+ ) {
1048
+ let value = this.formatValue(stepValue);
1049
+ let info = {};
1050
+ if (value === this.min) {
1051
+ /* 起始 */
1052
+ info = {
1053
+ value: value,
1054
+ px: 0,
1055
+ pxLeft: 0,
1056
+ pxRight: this.$data.stepPx / 2,
1057
+ percent: 0,
1058
+ };
1059
+ } else {
1060
+ info = {
1061
+ value: value,
1062
+ px: widthPx,
1063
+ pxLeft: widthPx - this.$data.stepPx / 2,
1064
+ pxRight: widthPx + this.$data.stepPx / 2,
1065
+ percent: widthPx / this.$data.totalWidth,
1066
+ };
1067
+ //if (value === this.max) {
1068
+ // info["pxLeft"] = this.$data.stepBlockMap.get(
1069
+ // index - 1
1070
+ // ).pxRight;
1071
+ // info["pxRight"] = this.$data.totalWidth;
1072
+ //}
1073
+ }
1074
+ this.$data.stepBlockMap.set(index, info as any);
1075
+ index++;
1076
+ widthPx += this.$data.stepPx;
1077
+ }
1078
+ },
1079
+ /**
1080
+ * 初始化slider的默认起始left的百分比值
1081
+ */
1082
+ initSliderPosition() {
1083
+ /* 设置起始默认style的left值 */
1084
+ let percent = 0;
1085
+ for (const [, stepBlockInfo] of this.$data.stepBlockMap.entries()) {
1086
+ /* 判断值是否和区域内的值相等 */
1087
+ if (stepBlockInfo.value == this.value) {
1088
+ percent = stepBlockInfo.percent;
1089
+ this.$data.dragWidth = stepBlockInfo.px;
1090
+ break;
1091
+ }
1092
+ }
1093
+ percent = this.formatValue(percent * 100);
1094
+ this.setSliderPosition(percent);
1095
+ },
1096
+ /**
1097
+ * 判断数字是否是浮点数
1098
+ * @param num
1099
+ * @returns
1100
+ */
1101
+ isFloat(num: number) {
1102
+ return Number(num) === num && num % 1 !== 0;
1103
+ },
1104
+ /**
1105
+ * 值改变的回调
1106
+ * @param event
1107
+ * @param value
1108
+ */
1109
+ valueChangeCallBack(event: any, value: number) {
1110
+ if (typeof formConfig.callback === "function") {
1111
+ formConfig.callback(event, value);
1112
+ }
1113
+ },
1114
+ /**
1115
+ * 根据拖拽距离获取滑块应该在的区间和值
1116
+ */
1117
+ getDragInfo(dragX: number) {
1118
+ let result = this.$data.stepBlockMap.get(0);
1119
+ for (const [, stepBlockInfo] of this.$data.stepBlockMap.entries()) {
1120
+ if (
1121
+ stepBlockInfo.pxLeft <= dragX &&
1122
+ dragX < stepBlockInfo.pxRight
1123
+ ) {
1124
+ result = stepBlockInfo;
1125
+ break;
1126
+ }
1127
+ }
1128
+ return result;
1129
+ },
1130
+ /**
1131
+ * 获取滑块的当前脱拖拽占据的百分比
1132
+ * @param {number} dragWidth
1133
+ */
1134
+ getSliderPositonPercent(dragWidth: number) {
1135
+ return dragWidth / this.$data.totalWidth;
1136
+ },
1137
+ /**
1138
+ * 根据step格式化value
1139
+ * @param num
1140
+ */
1141
+ formatValue(num: number) {
1142
+ if (PopsMathFloatUtils.isFloat(this.step)) {
1143
+ num = parseFloat(num.toFixed(2));
1144
+ } else {
1145
+ num = parseInt(num.toString());
1146
+ }
1147
+ return num;
1148
+ },
1149
+ /**
1150
+ * 设置滑块的位置偏移(left)
1151
+ * @param percent 百分比
1152
+ */
1153
+ setSliderPosition(percent: number) {
1154
+ if (parseInt(percent.toString()) === 1) {
1155
+ percent = 1;
1156
+ }
1157
+ if (percent > 1) {
1158
+ percent = percent / 100;
1159
+ }
1160
+ /* 滑块按钮的偏移 */
1161
+ this.$ele.buttonWrapper.style.left = `${percent * 100}%`;
1162
+ /* 滑块进度的宽度 */
1163
+ this.$ele.bar.style.width = `${percent * 100}%`;
1164
+ },
1165
+ /**
1166
+ * 禁止拖拽
1167
+ */
1168
+ disableDrag() {
1169
+ this.$ele.runAway.classList.add("pops-slider-is-disabled");
1170
+ },
1171
+ /**
1172
+ * 允许拖拽
1173
+ */
1174
+ allowDrag() {
1175
+ this.$ele.runAway.classList.remove("pops-slider-is-disabled");
1176
+ },
1177
+ /**
1178
+ * 判断当前滑块是否被禁用
1179
+ */
1180
+ isDisabledDrag() {
1181
+ return this.$ele.runAway.classList.contains(
1182
+ "pops-slider-is-disabled"
1183
+ );
1184
+ },
1185
+ /**
1186
+ * 设置进度条点击定位的事件
1187
+ */
1188
+ setRunAwayClickEvent() {
1189
+ popsDOMUtils.on(
1190
+ this.$ele.runAway,
1191
+ "click",
1192
+ void 0,
1193
+ (event) => {
1194
+ if (
1195
+ event.target !== this.$ele.runAway &&
1196
+ event.target !== this.$ele.bar
1197
+ ) {
1198
+ return;
1199
+ }
1200
+ let clickX = parseFloat((event as any).offsetX);
1201
+ this.dragStartCallBack();
1202
+ this.dragMoveCallBack(event, clickX, this.value);
1203
+ this.dragEndCallBack(clickX);
1204
+ },
1205
+ {
1206
+ capture: false,
1207
+ }
1208
+ );
1209
+ },
1210
+ /**
1211
+ * 拖拽开始的回调,如果返回false,禁止拖拽
1212
+ */
1213
+ dragStartCallBack() {
1214
+ if (!this.$data.isMove) {
1215
+ if (this.isDisabledDrag()) {
1216
+ return false;
1217
+ }
1218
+ this.$data.isMove = true;
1219
+ }
1220
+ return true;
1221
+ },
1222
+ /**
1223
+ * 拖拽中的回调
1224
+ * @param event 事件
1225
+ * @param dragX 当前拖拽的距离
1226
+ * @param oldValue 旧的值
1227
+ */
1228
+ dragMoveCallBack(
1229
+ event: MouseEvent | TouchEvent,
1230
+ dragX: number,
1231
+ oldValue: number
1232
+ ) {
1233
+ let dragPercent = 0;
1234
+ if (dragX <= 0) {
1235
+ dragPercent = 0;
1236
+ this.value = this.min;
1237
+ } else if (dragX >= this.$data.totalWidth) {
1238
+ dragPercent = 1;
1239
+ this.value = this.max;
1240
+ } else {
1241
+ const dragInfo = this.getDragInfo(dragX)!;
1242
+ dragPercent = dragInfo.percent;
1243
+ this.value = this.formatValue(dragInfo.value);
1244
+ }
1245
+ this.$data.dragPercent = dragPercent;
1246
+ this.setSliderPosition(this.$data.dragPercent);
1247
+ this.showToolTip();
1248
+ if (oldValue !== this.value) {
1249
+ this.valueChangeCallBack(event, this.value);
1250
+ }
1251
+ },
1252
+ /**
1253
+ * 拖拽结束的回调
1254
+ */
1255
+ dragEndCallBack(dragX: number) {
1256
+ this.$data.isMove = false;
1257
+ if (dragX <= 0) {
1258
+ this.$data.dragWidth = 0;
1259
+ } else if (dragX >= this.$data.totalWidth) {
1260
+ this.$data.dragWidth = this.$data.totalWidth;
1261
+ } else {
1262
+ this.$data.dragWidth = dragX;
1263
+ }
1264
+ this.closeToolTip();
1265
+ },
1266
+ /**
1267
+ * 设置点击拖拽事件
1268
+ */
1269
+ setPanEvent() {
1270
+ const AnyTouch = popsUtils.AnyTouch();
1271
+ this.$tooltip = new AnyTouch(this.$ele.button, {
1272
+ preventEvent() {
1273
+ return false;
1274
+ },
1275
+ });
1276
+ /**
1277
+ * 当前的拖拽的距离px
1278
+ */
1279
+ let currentDragX = 0;
1280
+ /* 监听拖拽 */
1281
+ this.$tooltip.on("at:move", (event: any) => {
1282
+ if (!this.dragStartCallBack()) {
1283
+ return;
1284
+ }
1285
+ let oldValue = this.value;
1286
+ const runAwayRect = this.$ele.runAway.getBoundingClientRect();
1287
+ let displacementX =
1288
+ event.x - (runAwayRect.left + globalThis.screenX);
1289
+ if (displacementX <= 0) {
1290
+ displacementX = 0;
1291
+ } else if (displacementX >= runAwayRect.width) {
1292
+ displacementX = runAwayRect.width;
1293
+ }
1294
+ currentDragX = displacementX;
1295
+ /* 拖拽移动 */
1296
+ this.dragMoveCallBack(event, currentDragX, oldValue);
1297
+ });
1298
+ /* 监听触点离开,处理某些情况下,拖拽松开,但是未触发pan事件,可以通过设置这个来关闭tooltip */
1299
+ this.$tooltip.on("at:end", (event: any) => {
1300
+ this.dragEndCallBack(currentDragX);
1301
+ });
1302
+ },
1303
+ /**
1304
+ * 显示悬浮的
1305
+ */
1306
+ showToolTip() {
1307
+ this.$ele.tooltip.show();
1308
+ },
1309
+ /**
1310
+ * 关闭悬浮的
1311
+ */
1312
+ closeToolTip() {
1313
+ this.$ele.tooltip.close();
1314
+ },
1315
+ /**
1316
+ * 检测在1000ms内,是否停止了拖拽
1317
+ */
1318
+ checkStopDragMove() {
1319
+ if (this.$data.isCheckingStopDragMove) {
1320
+ return;
1321
+ }
1322
+ this.$data.isCheckingStopDragMove = true;
1323
+ let interval = setInterval(() => {
1324
+ if (!this.$data.isMove) {
1325
+ this.$data.isCheckingStopDragMove = false;
1326
+ this.closeToolTip();
1327
+ clearInterval(interval);
1328
+ }
1329
+ }, 200);
1330
+ setTimeout(() => {
1331
+ this.$data.isCheckingStopDragMove = false;
1332
+ clearInterval(interval);
1333
+ }, 2000);
1334
+ },
1335
+ /**
1336
+ * 设置拖拽按钮的悬浮事件
1337
+ */
1338
+ setToolTipEvent() {
1339
+ /**
1340
+ * 获取提示的内容
1341
+ */
1342
+ function getToolTipContent() {
1343
+ if (typeof formConfig.getToolTipContent === "function") {
1344
+ return formConfig.getToolTipContent(PopsPanelSlider.value);
1345
+ } else {
1346
+ return PopsPanelSlider.value as any as string;
1347
+ }
1348
+ }
1349
+ let tooltipContent = null as any as HTMLElement;
1350
+
1351
+ this.$ele.tooltip = pops.tooltip({
1352
+ target: this.$ele.button,
1353
+ content: getToolTipContent,
1354
+ zIndex: 1000000,
1355
+ className: "github-tooltip",
1356
+ only: false,
1357
+ eventOption: {
1358
+ capture: true,
1359
+ passive: true,
1360
+ },
1361
+ showBeforeCallBack: () => {
1362
+ this.intervalInit();
1363
+ },
1364
+ showAfterCallBack: (toolTipNode) => {
1365
+ tooltipContent.innerText = getToolTipContent();
1366
+ },
1367
+ closeBeforeCallBack: () => {
1368
+ if (this.$data.isMove) {
1369
+ this.checkStopDragMove();
1370
+ return false;
1371
+ } else {
1372
+ }
1373
+ },
1374
+ alwaysShow: false,
1375
+ // only: false,
1376
+ position: "top",
1377
+ arrowDistance: 10,
1378
+ }) as any;
1379
+ tooltipContent =
1380
+ this.$ele.tooltip.toolTipNode.querySelector<HTMLDivElement>(
1381
+ "div"
1382
+ )!;
1383
+ },
1384
+ };
1385
+ PopsPanelSlider.init();
1386
+ (liElement as any)["data-slider"] = PopsPanelSlider;
1387
+ return liElement;
1388
+ },
1389
+ /**
1390
+ * 获取中间容器的元素<li>
1391
+ * type ==> input
1392
+ * @param formConfig
1393
+ * @returns
1394
+ */
1395
+ getSectionContainerItem_input(formConfig: PopsPanelInputDetails) {
1396
+ let liElement = document.createElement("li");
1397
+ (liElement as any)["__formConfig__"] = formConfig;
1398
+ if (formConfig.className) {
1399
+ liElement.className = formConfig.className;
1400
+ }
1401
+ this.addElementAttributes(liElement, formConfig.attributes);
1402
+ this.setElementProps(liElement, formConfig.props);
1403
+ let inputType = "text";
1404
+ if (formConfig.isPassword) {
1405
+ inputType = "password";
1406
+ } else if (formConfig.isNumber) {
1407
+ inputType = "number";
1408
+ }
1409
+ /* 左边底部的描述的文字 */
1410
+ let leftDescriptionText = "";
1411
+ if (Boolean(formConfig.description)) {
1412
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1413
+ }
1414
+ liElement.innerHTML = `
1415
+ <div class="pops-panel-item-left-text">
1416
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
1417
+ ${leftDescriptionText}
1418
+ </div>
1419
+ <div class="pops-panel-input">
1420
+ <input type="${inputType}" placeholder="${formConfig.placeholder}">
1421
+ </div>
1422
+ `;
1423
+ const PopsPanelInput = {
1424
+ [Symbol.toStringTag]: "PopsPanelInput",
1425
+ $ele: {
1426
+ panelInput:
1427
+ liElement.querySelector<HTMLDivElement>(".pops-panel-input")!,
1428
+ input: liElement.querySelector<HTMLInputElement>("input")!,
1429
+ inputSpanIcon: document.createElement("span"),
1430
+ inputSpanIconInner: null as any as HTMLSpanElement,
1431
+ icon: null as any as HTMLElement,
1432
+ },
1433
+ $data: {
1434
+ value: formConfig.getValue(),
1435
+ isView: false,
1436
+ },
1437
+ init() {
1438
+ this.initEle();
1439
+ this.setInputValue(this.$data.value);
1440
+ /* 如果是密码框,放进图标 */
1441
+ if (formConfig.isPassword) {
1442
+ this.setCircleIcon(pops.config.iconSVG.view);
1443
+ this.setCircleIconClickEvent();
1444
+ } else {
1445
+ /* 先判断预设值是否为空,不为空添加清空图标按钮 */
1446
+ if (this.$ele.input.value != "") {
1447
+ this.setCircleIcon(pops.config.iconSVG.circleClose);
1448
+ this.setCircleIconClickEvent();
1449
+ }
1450
+ }
1451
+
1452
+ this.setInputChangeEvent();
1453
+ if (formConfig.disabled) {
1454
+ this.disable();
1455
+ }
1456
+ if (typeof formConfig.handlerCallBack === "function") {
1457
+ formConfig.handlerCallBack(liElement, this.$ele.input);
1458
+ }
1459
+ },
1460
+ /**
1461
+ * 初始化$ele的配置
1462
+ */
1463
+ initEle() {
1464
+ this.$ele.input.parentElement!.insertBefore(
1465
+ this.$ele.inputSpanIcon,
1466
+ this.$ele.input.nextSibling
1467
+ );
1468
+ this.$ele.inputSpanIcon.className = "pops-panel-input__suffix";
1469
+ this.$ele.inputSpanIcon.innerHTML = `
1470
+ <span class="pops-panel-input__suffix-inner">
1471
+ <i class="pops-panel-icon"></i>
1472
+ </span>
1473
+ `;
1474
+ this.$ele.inputSpanIconInner =
1475
+ this.$ele.inputSpanIcon.querySelector<HTMLElement>(
1476
+ ".pops-panel-input__suffix-inner"
1477
+ )!;
1478
+ this.$ele.icon =
1479
+ this.$ele.inputSpanIcon.querySelector<HTMLElement>(
1480
+ ".pops-panel-icon"
1481
+ )!;
1482
+ },
1483
+ /**
1484
+ * 禁用
1485
+ */
1486
+ disable() {
1487
+ this.$ele.input.disabled = true;
1488
+ this.$ele.panelInput.classList.add("pops-input-disabled");
1489
+ },
1490
+ /**
1491
+ * 取消禁用
1492
+ */
1493
+ notDisable() {
1494
+ this.$ele.input.disabled = false;
1495
+ this.$ele.panelInput.classList.remove("pops-input-disabled");
1496
+ },
1497
+ /**
1498
+ * 判断是否已被禁用
1499
+ */
1500
+ isDisabled() {
1501
+ return this.$ele.input.disabled;
1502
+ },
1503
+ /**
1504
+ * 设置输入框内容
1505
+ * @param {string} [value=""] 值
1506
+ */
1507
+ setInputValue(value = "") {
1508
+ this.$ele.input.value = value;
1509
+ },
1510
+ /**
1511
+ * 设置input元素的type
1512
+ * @param {string} [typeValue="text"] type值
1513
+ */
1514
+ setInputType(typeValue = "text") {
1515
+ this.$ele.input.setAttribute("type", typeValue);
1516
+ },
1517
+ /**
1518
+ * 删除图标按钮
1519
+ */
1520
+ removeCircleIcon() {
1521
+ this.$ele.icon.innerHTML = "";
1522
+ },
1523
+ /**
1524
+ * 添加清空图标按钮
1525
+ * @param {string} [svgHTML=pops.config.iconSVG.circleClose] svg图标,默认为清空的图标
1526
+ */
1527
+ setCircleIcon(svgHTML = pops.config.iconSVG.circleClose) {
1528
+ this.$ele.icon.innerHTML = svgHTML;
1529
+ },
1530
+ /**
1531
+ * 添加图标按钮的点击事件
1532
+ */
1533
+ setCircleIconClickEvent() {
1534
+ popsDOMUtils.on(this.$ele.icon, "click", void 0, () => {
1535
+ if (this.isDisabled()) {
1536
+ return;
1537
+ }
1538
+ /* 删除图标 */
1539
+ this.removeCircleIcon();
1540
+ if (formConfig.isPassword) {
1541
+ /* 密码输入框 */
1542
+ if (this.$data.isView) {
1543
+ /* 当前可见 => 点击改变为隐藏 */
1544
+ this.$data.isView = false;
1545
+ /* 显示输入框内容,且更换图标为隐藏图标 */
1546
+ this.setInputType("text");
1547
+ this.setCircleIcon(pops.config.iconSVG.hide);
1548
+ } else {
1549
+ /* 当前不可见 => 点击改变为显示 */
1550
+ this.$data.isView = true;
1551
+ /* 隐藏输入框内容,且更换图标为显示图标 */
1552
+ this.setInputType("password");
1553
+ this.setCircleIcon(pops.config.iconSVG.view);
1554
+ }
1555
+ } else {
1556
+ /* 普通输入框 */
1557
+ /* 清空内容 */
1558
+ this.setInputValue("");
1559
+ /* 获取焦点 */
1560
+ this.$ele.input.focus();
1561
+ /* 触发内容改变事件 */
1562
+ this.$ele.input.dispatchEvent(new Event("input"));
1563
+ }
1564
+ });
1565
+ },
1566
+ /**
1567
+ * 监听输入框内容改变
1568
+ */
1569
+ setInputChangeEvent() {
1570
+ popsDOMUtils.on(
1571
+ this.$ele.input,
1572
+ ["input", "propertychange"],
1573
+ void 0,
1574
+ (event) => {
1575
+ this.$data.value = this.$ele.input.value;
1576
+ if (!formConfig.isPassword) {
1577
+ /* 不是密码框 */
1578
+ if (
1579
+ this.$ele.input.value !== "" &&
1580
+ this.$ele.icon.innerHTML === ""
1581
+ ) {
1582
+ /* 不为空,显示清空图标 */
1583
+ this.setCircleIcon(pops.config.iconSVG.circleClose);
1584
+ this.setCircleIconClickEvent();
1585
+ } else if (this.$ele.input.value === "") {
1586
+ this.removeCircleIcon();
1587
+ }
1588
+ }
1589
+ if (typeof formConfig.callback === "function") {
1590
+ if (formConfig.isNumber) {
1591
+ formConfig.callback(
1592
+ event as any,
1593
+ this.$ele.input.value,
1594
+ this.$ele.input.valueAsNumber
1595
+ );
1596
+ } else {
1597
+ formConfig.callback(event as any, this.$ele.input.value);
1598
+ }
1599
+ }
1600
+ }
1601
+ );
1602
+ },
1603
+ };
1604
+ PopsPanelInput.init();
1605
+ (liElement as any)["data-input"] = PopsPanelInput;
1606
+ return liElement;
1607
+ },
1608
+ /**
1609
+ * 获取中间容器的元素<li>
1610
+ * type ==> textarea
1611
+ * @param formConfig
1612
+ * @returns
1613
+ */
1614
+ getSectionContainerItem_textarea(formConfig: PopsPanelTextAreaDetails) {
1615
+ let liElement = document.createElement("li");
1616
+ (liElement as any)["__formConfig__"] = formConfig;
1617
+ if (formConfig.className) {
1618
+ liElement.className = formConfig.className;
1619
+ }
1620
+ this.addElementAttributes(liElement, formConfig.attributes);
1621
+ this.setElementProps(liElement, formConfig.props);
1622
+
1623
+ /* 左边底部的描述的文字 */
1624
+ let leftDescriptionText = "";
1625
+ if (Boolean(formConfig.description)) {
1626
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1627
+ }
1628
+ liElement.innerHTML = `
1629
+ <div class="pops-panel-item-left-text">
1630
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
1631
+ ${leftDescriptionText}
1632
+ </div>
1633
+ <div class="pops-panel-textarea">
1634
+ <textarea placeholder="${formConfig.placeholder ?? ""}">
1635
+ </textarea>
1636
+ </div>
1637
+ `;
1638
+
1639
+ const PopsPanelTextArea = {
1640
+ [Symbol.toStringTag]: "PopsPanelTextArea",
1641
+ $ele: {
1642
+ panelTextarea: liElement.querySelector<HTMLDivElement>(
1643
+ ".pops-panel-textarea"
1644
+ )!,
1645
+ textarea: liElement.querySelector<HTMLTextAreaElement>(
1646
+ ".pops-panel-textarea textarea"
1647
+ )!,
1648
+ },
1649
+ $data: {
1650
+ value: formConfig.getValue(),
1651
+ },
1652
+ init() {
1653
+ this.setValue(this.$data.value);
1654
+ this.setChangeEvent();
1655
+ if (formConfig.disabled) {
1656
+ this.disable();
1657
+ }
1658
+ },
1659
+ disable() {
1660
+ this.$ele.textarea.setAttribute("disabled", "true");
1661
+ this.$ele.panelTextarea.classList.add(
1662
+ "pops-panel-textarea-disable"
1663
+ );
1664
+ },
1665
+ notDisable() {
1666
+ this.$ele.textarea.removeAttribute("disabled");
1667
+ this.$ele.panelTextarea.classList.remove(
1668
+ "pops-panel-textarea-disable"
1669
+ );
1670
+ },
1671
+ isDisabled() {
1672
+ return (
1673
+ this.$ele.textarea.hasAttribute("disabled") ||
1674
+ this.$ele.panelTextarea.classList.contains(
1675
+ "pops-panel-textarea-disable"
1676
+ )
1677
+ );
1678
+ },
1679
+ setValue(value: string) {
1680
+ this.$ele.textarea.value = value;
1681
+ },
1682
+ /**
1683
+ * 监听选择内容改变
1684
+ */
1685
+ setChangeEvent() {
1686
+ popsDOMUtils.on(
1687
+ this.$ele.textarea,
1688
+ ["input", "propertychange"],
1689
+ void 0,
1690
+ (event) => {
1691
+ this.$data.value = (event as any).target.value;
1692
+ if (typeof formConfig.callback === "function") {
1693
+ formConfig.callback(
1694
+ event as any,
1695
+ (event as any).target.value
1696
+ );
1697
+ }
1698
+ }
1699
+ );
1700
+ },
1701
+ };
1702
+
1703
+ PopsPanelTextArea.init();
1704
+ (liElement as any)["data-textarea"] = PopsPanelTextArea;
1705
+
1706
+ return liElement;
1707
+ },
1708
+ /**
1709
+ * 获取中间容器的元素<li>
1710
+ * type ==> select
1711
+ * @param formConfig
1712
+ * @returns
1713
+ */
1714
+ getSectionContainerItem_select(formConfig: PopsPanelSelectDetails<any>) {
1715
+ let liElement = document.createElement("li");
1716
+ (liElement as any)["__formConfig__"] = formConfig;
1717
+ if (formConfig.className) {
1718
+ liElement.className = formConfig.className;
1719
+ }
1720
+ this.addElementAttributes(liElement, formConfig.attributes);
1721
+ this.setElementProps(liElement, formConfig.props);
1722
+ /* 左边底部的描述的文字 */
1723
+ let leftDescriptionText = "";
1724
+ if (Boolean(formConfig.description)) {
1725
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1726
+ }
1727
+ liElement.innerHTML = `
1728
+ <div class="pops-panel-item-left-text">
1729
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
1730
+ ${leftDescriptionText}
1731
+ </div>
1732
+ <div class="pops-panel-select">
1733
+ <select></select>
1734
+ </div>
1735
+ `;
1736
+
1737
+ const PopsPanelSelect = {
1738
+ [Symbol.toStringTag]: "PopsPanelSelect",
1739
+ $ele: {
1740
+ panelSelect:
1741
+ liElement.querySelector<HTMLDivElement>(".pops-panel-select")!,
1742
+ select: liElement.querySelector<HTMLSelectElement>(
1743
+ ".pops-panel-select select"
1744
+ )!,
1745
+ },
1746
+ $data: {
1747
+ defaultValue: formConfig.getValue(),
1748
+ },
1749
+ init() {
1750
+ this.initOption();
1751
+ this.setChangeEvent();
1752
+ this.setClickEvent();
1753
+ if (formConfig.disabled) {
1754
+ this.disable();
1755
+ }
1756
+ },
1757
+ disable() {
1758
+ this.$ele.select.setAttribute("disabled", "true");
1759
+ this.$ele.panelSelect.classList.add("pops-panel-select-disable");
1760
+ },
1761
+ notDisable() {
1762
+ this.$ele.select.removeAttribute("disabled");
1763
+ this.$ele.panelSelect.classList.remove("pops-panel-select-disable");
1764
+ },
1765
+ isDisabled() {
1766
+ return (
1767
+ this.$ele.select.hasAttribute("disabled") ||
1768
+ this.$ele.panelSelect.classList.contains(
1769
+ "pops-panel-select-disable"
1770
+ )
1771
+ );
1772
+ },
1773
+ initOption() {
1774
+ formConfig.data.forEach((dataItem) => {
1775
+ let optionElement = document.createElement("option");
1776
+ (optionElement as any)["__value__"] = dataItem.value;
1777
+ (optionElement as any)["__disable__"] = dataItem.disable;
1778
+ if (dataItem.value === this.$data.defaultValue) {
1779
+ optionElement.setAttribute("selected", "true");
1780
+ }
1781
+ optionElement.innerText = dataItem.text;
1782
+ this.$ele.select.appendChild(optionElement);
1783
+ });
1784
+ },
1785
+ setSelectOptionsDisableStatus() {
1786
+ if (this.$ele.select.options && this.$ele.select.options.length) {
1787
+ Array.from(this.$ele.select.options).forEach((optionItem) => {
1788
+ this.setOptionDisableStatus(optionItem);
1789
+ });
1790
+ }
1791
+ },
1792
+ setOptionDisableStatus(optionElement: HTMLOptionElement) {
1793
+ if (typeof (optionElement as any)["__disable__"] === "function") {
1794
+ let disableStatus = (optionElement as any)["__disable__"](
1795
+ (optionElement as any)["__value__"]
1796
+ );
1797
+ if (disableStatus) {
1798
+ optionElement.setAttribute("disabled", "true");
1799
+ } else {
1800
+ optionElement.removeAttribute("disabled");
1801
+ }
1802
+ }
1803
+ },
1804
+ /**
1805
+ * 监听选择内容改变
1806
+ */
1807
+ setChangeEvent() {
1808
+ popsDOMUtils.on(this.$ele.select, "change", void 0, (event) => {
1809
+ this.setSelectOptionsDisableStatus();
1810
+ if (typeof formConfig.callback === "function") {
1811
+ let isSelectedElement = (event as any).target[
1812
+ (event as any).target.selectedIndex
1813
+ ] as HTMLOptionElement;
1814
+ let isSelectedValue = (isSelectedElement as any)["__value__"];
1815
+ let isSelectedText =
1816
+ isSelectedElement.innerText || isSelectedElement.textContent!;
1817
+ formConfig.callback(
1818
+ event as any,
1819
+ isSelectedValue,
1820
+ isSelectedText
1821
+ );
1822
+ }
1823
+ });
1824
+ },
1825
+ /**
1826
+ * 监听点击事件
1827
+ */
1828
+ setClickEvent() {
1829
+ popsDOMUtils.on(this.$ele.select, "click", void 0, (event) => {
1830
+ this.setSelectOptionsDisableStatus();
1831
+ if (typeof formConfig.clickCallBack === "function") {
1832
+ formConfig.clickCallBack(event, this.$ele.select);
1833
+ }
1834
+ });
1835
+ },
1836
+ };
1837
+
1838
+ PopsPanelSelect.init();
1839
+ (liElement as any)["data-select"] = PopsPanelSelect;
1840
+ return liElement;
1841
+ },
1842
+ /**
1843
+ * 获取中间容器的元素<li>
1844
+ * type ==> button
1845
+ * @param formConfig
1846
+ * @returns
1847
+ */
1848
+ getSectionContainerItem_button(formConfig: PopsPanelButtonDetails) {
1849
+ let liElement = document.createElement("li");
1850
+ (liElement as any)["__formConfig__"] = formConfig;
1851
+ if (formConfig.className) {
1852
+ liElement.className = formConfig.className;
1853
+ }
1854
+ this.addElementAttributes(liElement, formConfig.attributes);
1855
+ this.setElementProps(liElement, formConfig.props);
1856
+
1857
+ /* 左边底部的描述的文字 */
1858
+ let leftDescriptionText = "";
1859
+ if (Boolean(formConfig.description)) {
1860
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1861
+ }
1862
+ liElement.innerHTML = `
1863
+ <div class="pops-panel-item-left-text">
1864
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
1865
+ ${leftDescriptionText}
1866
+ </div>
1867
+ <div class="pops-panel-button">
1868
+ <button class="pops-panel-button_inner">
1869
+ <i class="pops-bottom-icon"></i>
1870
+ <span class="pops-panel-button-text"></span>
1871
+ </button>
1872
+ </div>
1873
+ `;
1874
+
1875
+ const PopsPanelButton = {
1876
+ [Symbol.toStringTag]: "PopsPanelButton",
1877
+ $ele: {
1878
+ panelButton:
1879
+ liElement.querySelector<HTMLDivElement>(".pops-panel-button")!,
1880
+ button: liElement.querySelector<HTMLDivElement>(
1881
+ ".pops-panel-button .pops-panel-button_inner"
1882
+ )!,
1883
+ icon: liElement.querySelector<HTMLDivElement>(
1884
+ ".pops-panel-button .pops-bottom-icon"
1885
+ )!,
1886
+ spanText: liElement.querySelector<HTMLDivElement>(
1887
+ ".pops-panel-button .pops-panel-button-text"
1888
+ )!,
1889
+ },
1890
+ $data: {},
1891
+ init() {
1892
+ this.$ele.panelButton.appendChild(this.$ele.button);
1893
+ this.initButton();
1894
+ this.setClickEvent();
1895
+ },
1896
+ initButton() {
1897
+ if (
1898
+ typeof formConfig.buttonIcon === "string" &&
1899
+ formConfig.buttonIcon.trim() !== ""
1900
+ ) {
1901
+ /* 存在icon图标且不为空 */
1902
+ if (formConfig.buttonIcon in pops.config.iconSVG) {
1903
+ this.setIconSVG(pops.config.iconSVG[formConfig.buttonIcon]);
1904
+ } else {
1905
+ this.setIconSVG(formConfig.buttonIcon);
1906
+ }
1907
+ this.showIcon();
1908
+ } else {
1909
+ this.hideIcon();
1910
+ }
1911
+ /* 按钮文字 */
1912
+ let buttonText = formConfig.buttonText;
1913
+ if (typeof formConfig.buttonText === "function") {
1914
+ buttonText = formConfig.buttonText();
1915
+ }
1916
+ this.setButtonType(formConfig.buttonType);
1917
+ if (formConfig.buttonIsRightIcon) {
1918
+ this.setIconRight();
1919
+ } else {
1920
+ this.setIconLeft();
1921
+ }
1922
+ if (formConfig.disable) {
1923
+ this.disable();
1924
+ }
1925
+ this.setButtonText(buttonText as string);
1926
+ this.setIconLoadingStatus(formConfig.buttonIconIsLoading);
1927
+ },
1928
+ disable() {
1929
+ this.$ele.button.setAttribute("disabled", "true");
1930
+ },
1931
+ notDisable() {
1932
+ this.$ele.button.removeAttribute("disabled");
1933
+ },
1934
+ /**
1935
+ * 隐藏icon图标
1936
+ */
1937
+ hideIcon() {
1938
+ this.$ele.panelButton.classList.add("pops-panel-button-no-icon");
1939
+ },
1940
+ /**
1941
+ * 显示icon图标
1942
+ */
1943
+ showIcon() {
1944
+ this.$ele.panelButton.classList.remove("pops-panel-button-no-icon");
1945
+ },
1946
+ /**
1947
+ * 设置icon图标的svg
1948
+ */
1949
+ setIconSVG(svgHTML: string) {
1950
+ this.$ele.icon.innerHTML = svgHTML;
1951
+ },
1952
+ /**
1953
+ * 设置icon图标是否旋转
1954
+ * @param status
1955
+ */
1956
+ setIconLoadingStatus(status: any) {
1957
+ this.$ele.icon.setAttribute(
1958
+ "is-loading",
1959
+ Boolean(status).toString()
1960
+ );
1961
+ },
1962
+ /**
1963
+ * 设置属性上是否存在icon图标
1964
+ */
1965
+ setHasIcon(value: any) {
1966
+ this.$ele.button.setAttribute(
1967
+ "data-icon",
1968
+ Boolean(value).toString()
1969
+ );
1970
+ },
1971
+ /**
1972
+ * 设置按钮类型
1973
+ * @param typeValue
1974
+ */
1975
+ setButtonType(typeValue: string) {
1976
+ this.$ele.button.setAttribute("type", typeValue);
1977
+ },
1978
+ /**
1979
+ * 添加按钮的图标在右边
1980
+ */
1981
+ setIconRight() {
1982
+ this.$ele.button.classList.add("pops-panel-button-right-icon");
1983
+ },
1984
+ /**
1985
+ * (默认)添加按钮的图标在左边
1986
+ */
1987
+ setIconLeft() {
1988
+ this.$ele.button.classList.remove("pops-panel-button-right-icon");
1989
+ },
1990
+ /**
1991
+ * 设置按钮文本
1992
+ * @param text
1993
+ */
1994
+ setButtonText(text: string) {
1995
+ this.$ele.spanText.innerHTML = text;
1996
+ },
1997
+ setClickEvent() {
1998
+ popsDOMUtils.on(this.$ele.button, "click", void 0, (event) => {
1999
+ if (typeof formConfig.callback === "function") {
2000
+ formConfig.callback(event);
2001
+ }
2002
+ });
2003
+ },
2004
+ };
2005
+ PopsPanelButton.init();
2006
+ (liElement as any)["data-button"] = PopsPanelButton;
2007
+ return liElement;
2008
+ },
2009
+ /**
2010
+ * 获取深层容器的元素<li>
2011
+ * @param formConfig
2012
+ */
2013
+ getSectionContainerItem_deepMenu(formConfig: PopsPanelDeepMenuDetails) {
2014
+ let liElement = document.createElement("li");
2015
+ liElement.classList.add("pops-panel-deepMenu-nav-item");
2016
+ (liElement as any)["__formConfig__"] = formConfig;
2017
+ if (formConfig.className) {
2018
+ liElement.classList.add(formConfig.className);
2019
+ }
2020
+ // 设置属性
2021
+ this.addElementAttributes(liElement, formConfig.attributes);
2022
+ // 设置元素上的属性
2023
+ this.setElementProps(liElement, formConfig.props);
2024
+
2025
+ /* 左边底部的描述的文字 */
2026
+ let leftDescriptionText = "";
2027
+ if (Boolean(formConfig.description)) {
2028
+ // 设置描述
2029
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
2030
+ }
2031
+ // 箭头图标
2032
+ let arrowRightIcon =
2033
+ typeof formConfig.arrowRightIcon === "boolean"
2034
+ ? formConfig.arrowRightIcon
2035
+ : true;
2036
+ let arrowRightIconHTML = "";
2037
+ if (arrowRightIcon) {
2038
+ arrowRightIconHTML = `<i class="pops-panel-deepMenu-arrowRight-icon">${pops.config.iconSVG.arrowRight}</i>`;
2039
+ }
2040
+ let rightText = "";
2041
+ if (formConfig.rightText) {
2042
+ rightText = `<p class="pops-panel-item-right-text">${formConfig.rightText}</p>`;
2043
+ }
2044
+ liElement.innerHTML = `
2045
+ <div class="pops-panel-item-left-text">
2046
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>
2047
+ ${leftDescriptionText}
2048
+ </div>
2049
+ <div class="pops-panel-deepMenu">
2050
+ ${rightText}
2051
+ ${arrowRightIconHTML}
2052
+ </div>
2053
+ `;
2054
+ const PopsPanelDeepMenu = {
2055
+ [Symbol.toStringTag]: "PopsPanelDeepMenu",
2056
+ $ele: {
2057
+ get parentSection() {
2058
+ return $contentSectionContainer;
2059
+ },
2060
+ },
2061
+ init() {
2062
+ this.setLiClickEvent();
2063
+ },
2064
+ /**
2065
+ * 生成配置每一项的元素
2066
+ * @param $container
2067
+ * @param formItemConfig
2068
+ */
2069
+ initFormItem(
2070
+ $container: HTMLElement,
2071
+ formItemConfig: PopsPanelFormsTotalDetails | PopsPanelFormsDetails
2072
+ ) {
2073
+ if (formItemConfig["type"] === "forms") {
2074
+ let childForms = formItemConfig["forms"];
2075
+ /* 每一项<li>元素 */
2076
+ let formContainerListElement = document.createElement("li");
2077
+ /* 每一项<li>内的子<ul>元素 */
2078
+ let formContainerULElement = document.createElement("ul");
2079
+ formContainerListElement.className =
2080
+ "pops-panel-forms-container-item";
2081
+ /* 区域头部的文字 */
2082
+ let formHeaderDivElement = popsDOMUtils.createElement("div", {
2083
+ className: "pops-panel-forms-container-item-header-text",
2084
+ });
2085
+ formHeaderDivElement.innerHTML = formItemConfig["text"];
2086
+ /* 加进容器内 */
2087
+ formContainerListElement.appendChild(formHeaderDivElement);
2088
+ if (formItemConfig.className) {
2089
+ popsDOMUtils.addClassName(
2090
+ formContainerListElement,
2091
+ formItemConfig.className
2092
+ );
2093
+ }
2094
+ HandleContetDetails.addElementAttributes(
2095
+ formContainerListElement,
2096
+ formItemConfig.attributes
2097
+ );
2098
+ HandleContetDetails.setElementProps(
2099
+ formContainerListElement,
2100
+ formItemConfig.props
2101
+ );
2102
+ childForms.forEach((childFormConfig) => {
2103
+ HandleContetDetails.uListContainerAddItem(childFormConfig, {
2104
+ ulElement: formContainerULElement,
2105
+ sectionContainerULElement:
2106
+ HandleContetDetails.sectionContainerULElement,
2107
+ formContainerListElement: formContainerListElement,
2108
+ formHeaderDivElement: formHeaderDivElement,
2109
+ });
2110
+ });
2111
+ formContainerListElement.appendChild(formContainerULElement);
2112
+ $container.appendChild(formContainerListElement);
2113
+ } else {
2114
+ /* 如果成功创建,加入到中间容器中 */
2115
+ HandleContetDetails.uListContainerAddItem(formConfig, {
2116
+ ulElement: HandleContetDetails.sectionContainerULElement,
2117
+ });
2118
+ }
2119
+ },
2120
+ /**
2121
+ * 前往子菜单
2122
+ * @param event 点击事件
2123
+ * @param liElement 当前的<li>元素
2124
+ */
2125
+ gotoDeepMenu(event: Event, liElement: HTMLLIElement) {
2126
+ /** 当前所在的容器 */
2127
+ let currentSection = liElement.closest(
2128
+ "section.pops-panel-container"
2129
+ ) as HTMLElement | null;
2130
+ if (currentSection) {
2131
+ popsDOMUtils.cssHide(currentSection);
2132
+ }
2133
+ // 子菜单的容器
2134
+ let $deepMenuContainer = popsDOMUtils.createElement("section", {
2135
+ className: "pops-panel-container pops-panel-deepMenu-container",
2136
+ });
2137
+ let $deepMenuHeaderUL = popsDOMUtils.createElement("ul", {
2138
+ className: "pops-panel-deepMenu-container-header-ul",
2139
+ });
2140
+ let $deepMenuChildMenuUL = popsDOMUtils.createElement("ul");
2141
+ // 标题文字
2142
+ let headerTitleText = formConfig.headerTitle ?? formConfig.text;
2143
+ let $header = popsDOMUtils.createElement("div", {
2144
+ className: "pops-panel-deepMenu-container-header",
2145
+ innerHTML: `<p>${headerTitleText}</p>`,
2146
+ });
2147
+ let $headerLeftArrow = popsDOMUtils.createElement("i", {
2148
+ className: "pops-panel-deepMenu-container-left-arrow-icon",
2149
+ innerHTML: pops.config.iconSVG.arrowLeft,
2150
+ });
2151
+ popsDOMUtils.on(
2152
+ $headerLeftArrow,
2153
+ "click",
2154
+ void 0,
2155
+ (event) => {
2156
+ event?.preventDefault();
2157
+ event?.stopPropagation();
2158
+ // 返回上一层菜单
2159
+ let $prev = $deepMenuContainer.previousElementSibling;
2160
+ popsDOMUtils.cssShow($prev);
2161
+ $deepMenuContainer.remove();
2162
+ },
2163
+ {
2164
+ once: true,
2165
+ }
2166
+ );
2167
+ $header.firstElementChild?.insertAdjacentElement(
2168
+ "beforebegin",
2169
+ $headerLeftArrow
2170
+ );
2171
+ $deepMenuHeaderUL.appendChild($header);
2172
+ $deepMenuContainer.appendChild($deepMenuHeaderUL);
2173
+ $deepMenuContainer.appendChild($deepMenuChildMenuUL);
2174
+
2175
+ if (formConfig.forms && Array.isArray(formConfig.forms)) {
2176
+ for (let index = 0; index < formConfig.forms.length; index++) {
2177
+ let formItemConfig = formConfig.forms[index];
2178
+ this.initFormItem($deepMenuChildMenuUL, formItemConfig);
2179
+ }
2180
+ }
2181
+ $content?.appendChild($deepMenuContainer);
2182
+
2183
+ /* 根据标题的高度来自适应内容高度,默认开启 */
2184
+ /* 中间容器的偏移量,看设置的section.pops-panel-container的padding,默认0 */
2185
+ let contentContainerOffset = 0;
2186
+ /* 获取标题的<ul>元素的高度 */
2187
+ let sectionContainerHeaderULElementHeight =
2188
+ popsDOMUtils.height($deepMenuHeaderUL);
2189
+ $deepMenuChildMenuUL.style.setProperty(
2190
+ "height",
2191
+ `calc( 100% - ${
2192
+ sectionContainerHeaderULElementHeight + contentContainerOffset
2193
+ }px )`
2194
+ );
2195
+ },
2196
+ /** 设置项的点击事件 */
2197
+ setLiClickEvent() {
2198
+ popsDOMUtils.on(liElement, "click", void 0, async (event) => {
2199
+ if (typeof formConfig.clickCallBack === "function") {
2200
+ let result = await formConfig.clickCallBack(event, formConfig);
2201
+ if (result) {
2202
+ return;
2203
+ }
2204
+ }
2205
+ this.gotoDeepMenu(event, liElement);
2206
+ });
2207
+ },
2208
+ };
2209
+
2210
+ PopsPanelDeepMenu.init();
2211
+ (liElement as any)["data-deepMenu"] = PopsPanelDeepMenu;
2212
+
2213
+ return liElement;
2214
+ },
2215
+ /**
2216
+ * 获取中间容器的元素<li>
2217
+ * type ===> own
2218
+ * @param formConfig
2219
+ */
2220
+ getSectionContainerItem_own(formConfig: PopsPanelOwnDetails) {
2221
+ let liElement = document.createElement("li");
2222
+ (liElement as any)["__formConfig__"] = formConfig;
2223
+ if (formConfig.className) {
2224
+ liElement.className = formConfig.className;
2225
+ }
2226
+ liElement = formConfig.getLiElementCallBack(liElement);
2227
+ return liElement;
2228
+ },
2229
+ /**
2230
+ * 获取中间容器的元素<li>
2231
+ * @param formConfig
2232
+ */
2233
+ getSectionContainerItem(formConfig: PopsPanelFormsTotalDetails) {
2234
+ /** 配置项的类型 */
2235
+ let formType = formConfig["type"];
2236
+
2237
+ if (formType === "switch") {
2238
+ return this.getSectionContainerItem_switch(
2239
+ formConfig as PopsPanelSwitchDetails
2240
+ );
2241
+ } else if (formType === "slider") {
2242
+ return this.getSectionContainerItem_slider_new(
2243
+ formConfig as PopsPanelSliderDetails
2244
+ );
2245
+ } else if (formType === "input") {
2246
+ return this.getSectionContainerItem_input(
2247
+ formConfig as PopsPanelInputDetails
2248
+ );
2249
+ } else if (formType === "textarea") {
2250
+ return this.getSectionContainerItem_textarea(
2251
+ formConfig as PopsPanelTextAreaDetails
2252
+ );
2253
+ } else if (formType === "select") {
2254
+ return this.getSectionContainerItem_select(
2255
+ formConfig as PopsPanelSelectDetails
2256
+ );
2257
+ } else if (formType === "button") {
2258
+ return this.getSectionContainerItem_button(
2259
+ formConfig as PopsPanelButtonDetails
2260
+ );
2261
+ } else if (formType === "deepMenu") {
2262
+ return this.getSectionContainerItem_deepMenu(
2263
+ formConfig as PopsPanelDeepMenuDetails
2264
+ );
2265
+ } else if (formType === "own") {
2266
+ return this.getSectionContainerItem_own(
2267
+ formConfig as PopsPanelOwnDetails
2268
+ );
2269
+ } else {
2270
+ console.error("尚未实现的type类型", formConfig);
2271
+ }
2272
+ },
2273
+ /**
2274
+ * 生成配置每一项的元素
2275
+ * @param formConfig
2276
+ */
2277
+ initFormItem(formConfig: PopsPanelContentConfig) {
2278
+ let that = this;
2279
+ if ((formConfig as any)["type"] === "forms") {
2280
+ let __formConfig_forms = formConfig as any as PopsPanelFormsDetails;
2281
+ let childForms = formConfig["forms"];
2282
+ /* 每一项<li>元素 */
2283
+ let formContainerListElement = document.createElement("li");
2284
+ /* 每一项<li>内的子<ul>元素 */
2285
+ let formContainerULElement = document.createElement("ul");
2286
+ formContainerListElement.className =
2287
+ "pops-panel-forms-container-item";
2288
+ /* 区域头部的文字 */
2289
+ let formHeaderDivElement = popsDOMUtils.createElement("div", {
2290
+ className: "pops-panel-forms-container-item-header-text",
2291
+ });
2292
+ formHeaderDivElement.innerHTML = __formConfig_forms["text"];
2293
+ /* 加进容器内 */
2294
+ formContainerListElement.appendChild(formHeaderDivElement);
2295
+ if (__formConfig_forms.className) {
2296
+ popsDOMUtils.addClassName(
2297
+ formContainerListElement,
2298
+ __formConfig_forms.className
2299
+ );
2300
+ }
2301
+ that.addElementAttributes(
2302
+ formContainerListElement,
2303
+ formConfig.attributes
2304
+ );
2305
+ that.setElementProps(formContainerListElement, formConfig.props);
2306
+ childForms.forEach((childFormConfig) => {
2307
+ that.uListContainerAddItem(childFormConfig as any, {
2308
+ ulElement: formContainerULElement,
2309
+ sectionContainerULElement: that.sectionContainerULElement,
2310
+ formContainerListElement: formContainerListElement,
2311
+ formHeaderDivElement: formHeaderDivElement,
2312
+ });
2313
+ });
2314
+ formContainerListElement.appendChild(formContainerULElement);
2315
+ that.sectionContainerULElement.appendChild(formContainerListElement);
2316
+ } else {
2317
+ /* 如果成功创建,加入到中间容器中 */
2318
+ that.uListContainerAddItem(formConfig as any, {
2319
+ ulElement: that.sectionContainerULElement,
2320
+ });
2321
+ }
2322
+ },
2323
+ /**
2324
+ *
2325
+ * @param formConfig
2326
+ * @param containerOptions
2327
+ */
2328
+ uListContainerAddItem(
2329
+ formConfig: PopsPanelFormsTotalDetails,
2330
+ containerOptions: PopsPanelRightAsideContainerOptions
2331
+ ) {
2332
+ let itemLiElement = this.getSectionContainerItem(formConfig);
2333
+ if (itemLiElement) {
2334
+ containerOptions["ulElement"].appendChild(itemLiElement);
2335
+ }
2336
+ if (typeof formConfig.afterAddToUListCallBack === "function") {
2337
+ formConfig.afterAddToUListCallBack(formConfig, containerOptions);
2338
+ }
2339
+ },
2340
+ /**
2341
+ * 为左侧容器元素添加点击事件
2342
+ * @param asideLiElement 左侧的容器<li>元素
2343
+ * @param asideConfig 配置
2344
+ */
2345
+ setAsideItemClickEvent(
2346
+ asideLiElement: HTMLElement,
2347
+ asideConfig: PopsPanelContentConfig
2348
+ ) {
2349
+ popsDOMUtils.on<MouseEvent | PointerEvent>(
2350
+ asideLiElement,
2351
+ "click",
2352
+ void 0,
2353
+ (event) => {
2354
+ this.clearContainer();
2355
+ popsDOMUtils.cssShow($contentSectionContainer);
2356
+ this.clearAsideItemIsVisited();
2357
+ this.setAsideItemIsVisited(asideLiElement);
2358
+ /* 顶部标题栏,存在就设置 */
2359
+ let headerTitleText = asideConfig.headerTitle ?? asideConfig.title;
2360
+ if (
2361
+ typeof headerTitleText === "string" &&
2362
+ headerTitleText.trim() !== ""
2363
+ ) {
2364
+ let containerHeaderTitleLIElement = document.createElement("li");
2365
+ (containerHeaderTitleLIElement as any)["__asideConfig__"] =
2366
+ asideConfig;
2367
+ containerHeaderTitleLIElement.innerHTML = headerTitleText;
2368
+ this.sectionContainerHeaderULElement.appendChild(
2369
+ containerHeaderTitleLIElement
2370
+ );
2371
+ }
2372
+
2373
+ let __forms__ = (asideLiElement as any)[
2374
+ "__forms__"
2375
+ ] as PopsPanelContentConfig[];
2376
+
2377
+ __forms__.forEach((formConfig) => {
2378
+ this.initFormItem(formConfig);
2379
+ });
2380
+
2381
+ let autoAdaptionContentHeight =
2382
+ asideConfig.autoAdaptionContentHeight ?? true;
2383
+ if (autoAdaptionContentHeight) {
2384
+ /* 根据标题的高度来自适应内容高度,默认开启 */
2385
+ /* 中间容器的偏移量,看设置的section.pops-panel-container的padding,默认0 */
2386
+ let contentContainerOffset =
2387
+ (asideConfig as any).contentContainerOffset ?? 0;
2388
+ /* 获取标题的<ul>元素的高度 */
2389
+ let sectionContainerHeaderULElementHeight = popsDOMUtils.height(
2390
+ this.sectionContainerHeaderULElement
2391
+ );
2392
+ this.sectionContainerULElement.style.setProperty(
2393
+ "height",
2394
+ `calc( 100% - ${
2395
+ sectionContainerHeaderULElementHeight + contentContainerOffset
2396
+ }px )`
2397
+ );
2398
+ }
2399
+
2400
+ if (typeof asideConfig.callback === "function") {
2401
+ /* 执行回调 */
2402
+ asideConfig.callback(
2403
+ event,
2404
+ this.sectionContainerHeaderULElement,
2405
+ this.sectionContainerULElement
2406
+ );
2407
+ }
2408
+ }
2409
+ );
2410
+ },
2411
+ };
2412
+
2413
+ HandleContetDetails.init();
2414
+
2415
+ PopsHandler.handlePush(PopsType, {
2416
+ guid: guid,
2417
+ animElement: $anim,
2418
+ popsElement: $pops,
2419
+ maskElement: $mask!,
2420
+ $shadowContainer: $shadowContainer,
2421
+ $shadowRoot: $shadowRoot,
2422
+ });
2423
+ /* 拖拽 */
2424
+ if (config.drag) {
2425
+ PopsInstanceUtils.drag($pops, {
2426
+ dragElement: $title,
2427
+ limit: config.dragLimit,
2428
+ extraDistance: config.dragExtraDistance,
2429
+ moveCallBack: config.dragMoveCallBack,
2430
+ endCallBack: config.dragEndCallBack,
2431
+ });
2432
+ }
2433
+ return PopsHandler.handleResultDetails(eventDetails);
2434
+ }
2435
+ }