@whitesev/pops 2.4.6 → 2.4.7

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 (142) hide show
  1. package/dist/index.amd.js +578 -571
  2. package/dist/index.amd.js.map +1 -1
  3. package/dist/index.cjs.js +578 -571
  4. package/dist/index.cjs.js.map +1 -1
  5. package/dist/index.esm.js +578 -571
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.iife.js +578 -571
  8. package/dist/index.iife.js.map +1 -1
  9. package/dist/index.system.js +578 -571
  10. package/dist/index.system.js.map +1 -1
  11. package/dist/index.umd.js +578 -571
  12. package/dist/index.umd.js.map +1 -1
  13. package/dist/types/src/types/PopsDOMUtilsEventType.d.ts +252 -252
  14. package/dist/types/src/types/animation.d.ts +19 -19
  15. package/dist/types/src/types/button.d.ts +187 -187
  16. package/dist/types/src/types/components.d.ts +210 -210
  17. package/dist/types/src/types/event.d.ts +63 -63
  18. package/dist/types/src/types/global.d.ts +25 -25
  19. package/dist/types/src/types/icon.d.ts +32 -32
  20. package/dist/types/src/types/inst.d.ts +24 -24
  21. package/dist/types/src/types/main.d.ts +111 -111
  22. package/dist/types/src/types/mask.d.ts +49 -49
  23. package/dist/types/src/types/position.d.ts +60 -60
  24. package/index.ts +3 -0
  25. package/package.json +4 -2
  26. package/src/Pops.ts +206 -0
  27. package/src/PopsAnimation.ts +32 -0
  28. package/src/PopsCSS.ts +51 -0
  29. package/src/PopsCore.ts +64 -0
  30. package/src/PopsIcon.ts +95 -0
  31. package/src/PopsInst.ts +21 -0
  32. package/src/components/alert/config.ts +62 -0
  33. package/src/components/alert/index.css +0 -0
  34. package/src/components/alert/index.ts +163 -0
  35. package/src/components/alert/types/index.ts +23 -0
  36. package/src/components/confirm/config.ts +90 -0
  37. package/src/components/confirm/index.css +0 -0
  38. package/src/components/confirm/index.ts +166 -0
  39. package/src/components/confirm/types/index.ts +17 -0
  40. package/src/components/drawer/config.ts +89 -0
  41. package/src/components/drawer/index.css +37 -0
  42. package/src/components/drawer/index.ts +237 -0
  43. package/src/components/drawer/types/index.ts +61 -0
  44. package/src/components/folder/config.ts +147 -0
  45. package/src/components/folder/folderIcon.ts +28 -0
  46. package/src/components/folder/index.css +303 -0
  47. package/src/components/folder/index.ts +929 -0
  48. package/src/components/folder/types/index.ts +97 -0
  49. package/src/components/iframe/config.ts +60 -0
  50. package/src/components/iframe/index.css +76 -0
  51. package/src/components/iframe/index.ts +334 -0
  52. package/src/components/iframe/types/index.ts +139 -0
  53. package/src/components/loading/config.ts +29 -0
  54. package/src/components/loading/index.css +66 -0
  55. package/src/components/loading/index.ts +99 -0
  56. package/src/components/loading/types/index.ts +34 -0
  57. package/src/components/panel/config.ts +519 -0
  58. package/src/components/panel/handlerComponents.ts +2900 -0
  59. package/src/components/panel/index.css +1222 -0
  60. package/src/components/panel/index.ts +207 -0
  61. package/src/components/panel/types/components-button.ts +68 -0
  62. package/src/components/panel/types/components-common.ts +50 -0
  63. package/src/components/panel/types/components-deepMenu.ts +84 -0
  64. package/src/components/panel/types/components-forms.ts +44 -0
  65. package/src/components/panel/types/components-input.ts +78 -0
  66. package/src/components/panel/types/components-own.ts +30 -0
  67. package/src/components/panel/types/components-select.ts +93 -0
  68. package/src/components/panel/types/components-selectMultiple.ts +130 -0
  69. package/src/components/panel/types/components-slider.ts +77 -0
  70. package/src/components/panel/types/components-switch.ts +56 -0
  71. package/src/components/panel/types/components-textarea.ts +68 -0
  72. package/src/components/panel/types/index.ts +177 -0
  73. package/src/components/prompt/config.ts +94 -0
  74. package/src/components/prompt/index.css +34 -0
  75. package/src/components/prompt/index.ts +216 -0
  76. package/src/components/prompt/types/index.ts +55 -0
  77. package/src/components/rightClickMenu/config.ts +98 -0
  78. package/src/components/rightClickMenu/index.css +112 -0
  79. package/src/components/rightClickMenu/index.ts +602 -0
  80. package/src/components/rightClickMenu/types/index.ts +97 -0
  81. package/src/components/searchSuggestion/config.ts +56 -0
  82. package/src/components/searchSuggestion/index.ts +856 -0
  83. package/src/components/searchSuggestion/types/index.ts +239 -0
  84. package/src/components/tooltip/config.ts +34 -0
  85. package/src/components/tooltip/index.css +199 -0
  86. package/src/components/tooltip/index.ts +604 -0
  87. package/src/components/tooltip/types/index.ts +117 -0
  88. package/src/config/CommonCSSClassName.ts +17 -0
  89. package/src/config/GlobalConfig.ts +63 -0
  90. package/src/css/animation.css +987 -0
  91. package/src/css/button.css +551 -0
  92. package/src/css/common.css +48 -0
  93. package/src/css/index.css +253 -0
  94. package/src/css/ninePalaceGridPosition.css +50 -0
  95. package/src/css/scrollbar.css +22 -0
  96. package/src/handler/PopsElementHandler.ts +304 -0
  97. package/src/handler/PopsHandler.ts +589 -0
  98. package/src/svg/arrowLeft.svg +4 -0
  99. package/src/svg/arrowRight.svg +4 -0
  100. package/src/svg/chromeFilled.svg +11 -0
  101. package/src/svg/circleClose.svg +8 -0
  102. package/src/svg/close.svg +5 -0
  103. package/src/svg/cpu.svg +8 -0
  104. package/src/svg/delete.svg +5 -0
  105. package/src/svg/documentCopy.svg +5 -0
  106. package/src/svg/edit.svg +8 -0
  107. package/src/svg/eleme.svg +5 -0
  108. package/src/svg/elemePlus.svg +5 -0
  109. package/src/svg/headset.svg +5 -0
  110. package/src/svg/hide.svg +8 -0
  111. package/src/svg/keyboard.svg +8 -0
  112. package/src/svg/loading.svg +5 -0
  113. package/src/svg/max.svg +5 -0
  114. package/src/svg/min.svg +5 -0
  115. package/src/svg/mise.svg +5 -0
  116. package/src/svg/monitor.svg +5 -0
  117. package/src/svg/next.svg +5 -0
  118. package/src/svg/picture.svg +8 -0
  119. package/src/svg/prev.svg +5 -0
  120. package/src/svg/search.svg +5 -0
  121. package/src/svg/share.svg +5 -0
  122. package/src/svg/upload.svg +5 -0
  123. package/src/svg/videoPause.svg +5 -0
  124. package/src/svg/videoPlay.svg +5 -0
  125. package/src/svg/view.svg +5 -0
  126. package/src/types/PopsDOMUtilsEventType.d.ts +252 -0
  127. package/src/types/animation.d.ts +19 -0
  128. package/src/types/button.d.ts +187 -0
  129. package/src/types/components.d.ts +210 -0
  130. package/src/types/event.d.ts +63 -0
  131. package/src/types/global.d.ts +25 -0
  132. package/src/types/icon.d.ts +32 -0
  133. package/src/types/inst.d.ts +24 -0
  134. package/src/types/main.d.ts +111 -0
  135. package/src/types/mask.d.ts +49 -0
  136. package/src/types/position.d.ts +60 -0
  137. package/src/utils/PopsDOMUtils.ts +2408 -0
  138. package/src/utils/PopsDOMUtilsEventsConfig.ts +4 -0
  139. package/src/utils/PopsInstanceUtils.ts +688 -0
  140. package/src/utils/PopsMathUtils.ts +71 -0
  141. package/src/utils/PopsSafeUtils.ts +22 -0
  142. package/src/utils/PopsUtils.ts +406 -0
@@ -0,0 +1,2900 @@
1
+ import { PopsIcon } from "../../PopsIcon";
2
+ import { popsDOMUtils } from "../../utils/PopsDOMUtils";
3
+ import { PopsInstanceUtils } from "../../utils/PopsInstanceUtils";
4
+ import { PopsMathFloatUtils } from "../../utils/PopsMathUtils";
5
+ import { PopsSafeUtils } from "../../utils/PopsSafeUtils";
6
+ import { popsUtils } from "../../utils/PopsUtils";
7
+ import { PopsAlert } from "../alert";
8
+ import { PopsTooltip } from "../tooltip";
9
+ import { PopsCommonCSSClassName } from "../../config/CommonCSSClassName";
10
+ import type { PopsAlertDetails } from "../alert/types";
11
+ import type { PopsPanelButtonDetails } from "./types/components-button";
12
+ import type { PopsPanelRightAsideContainerOptions } from "./types/components-common";
13
+ import type { PopsPanelDeepMenuDetails } from "./types/components-deepMenu";
14
+ import type { PopsPanelFormsDetails } from "./types/components-forms";
15
+ import type { PopsPanelContentConfig, PopsPanelDetails, PopsPanelEventType, PopsPanelFormsTotalDetails } from "./types";
16
+ import type { PopsPanelInputDetails } from "./types/components-input";
17
+ import type { PopsPanelOwnDetails } from "./types/components-own";
18
+ import type {
19
+ PopsPanelSelectMultipleDataOption,
20
+ PopsPanelSelectMultipleDetails,
21
+ } from "./types/components-selectMultiple";
22
+ import type { PopsPanelSelectDetails } from "./types/components-select";
23
+ import type { PopsPanelSliderDetails } from "./types/components-slider";
24
+ import type { PopsPanelSwitchDetails } from "./types/components-switch";
25
+ import type { PopsPanelTextAreaDetails } from "./types/components-textarea";
26
+ /**
27
+ * 处理组件(把组件配置转为组件元素)
28
+ */
29
+ export const PanelHandlerComponents = () => {
30
+ return {
31
+ /**
32
+ * 左侧上方的的ul容器
33
+ */
34
+ asideULElement: null as any as HTMLUListElement,
35
+ /**
36
+ * 左侧下方的ul容器
37
+ */
38
+ asideBottomULElement: null as any as HTMLUListElement,
39
+ /**
40
+ * 右侧主内容的顶部文字ul容器
41
+ */
42
+ sectionContainerHeaderULElement: null as any as HTMLUListElement,
43
+ /**
44
+ * 右侧主内容的ul容器
45
+ */
46
+ sectionContainerULElement: null as any as HTMLUListElement,
47
+ /**
48
+ * 元素
49
+ */
50
+ $el: {
51
+ /** pops主元素 */
52
+ $pops: null as any as HTMLElement,
53
+ /** 内容 */
54
+ $content: null as any as HTMLElement,
55
+ /** section元素的包裹容器 */
56
+ $sectionWrapper: null as any as HTMLElement,
57
+ /** 左侧容器 */
58
+ $contentAside: null as any as HTMLElement,
59
+ /** 右侧容器 */
60
+ $contentSectionContainer: null as any as HTMLElement,
61
+ },
62
+ $config: {} as Required<PopsPanelDetails>,
63
+ /**
64
+ * 初始化
65
+ * @param details
66
+ */
67
+ init(details: {
68
+ config: Required<PopsPanelDetails>;
69
+ $el: {
70
+ $pops: HTMLElement;
71
+ $content: HTMLElement;
72
+ $sectionWrapper: HTMLElement;
73
+ $contentAside: HTMLElement;
74
+ $contentSectionContainer: HTMLElement;
75
+ };
76
+ }) {
77
+ const PopsType = "panel";
78
+ this.$el = {
79
+ ...details.$el,
80
+ };
81
+ this.$config = details.config;
82
+
83
+ this.asideULElement = this.$el.$contentAside.querySelector<HTMLUListElement>(
84
+ `ul.pops-${PopsType}-aside-top-container`
85
+ )!;
86
+ this.asideBottomULElement = this.$el.$contentAside.querySelector<HTMLUListElement>(
87
+ `ul.pops-${PopsType}-aside-bottom-container`
88
+ )!;
89
+ this.sectionContainerHeaderULElement = this.$el.$contentSectionContainer.querySelector<HTMLUListElement>(
90
+ `ul.pops-${PopsType}-container-header-ul`
91
+ )!;
92
+ this.sectionContainerULElement = this.$el.$contentSectionContainer.querySelector<HTMLUListElement>(
93
+ `ul.pops-${PopsType}-container-main-ul`
94
+ )!;
95
+ /**
96
+ * 默认点击的左侧容器项
97
+ */
98
+ let $defaultAsideItem: HTMLLIElement | null = null;
99
+ /** 是否滚动到默认位置(第一个项) */
100
+ let isScrollToDefaultView = false;
101
+ // 初始化配置
102
+ details.config.content.forEach((asideItemConfig) => {
103
+ const $asideLiElement = this.createAsideItem(asideItemConfig);
104
+ this.setAsideItemClickEvent($asideLiElement, asideItemConfig);
105
+ // 是否处于底部
106
+ const isBottom =
107
+ typeof asideItemConfig.isBottom === "function" ? asideItemConfig.isBottom() : asideItemConfig.isBottom;
108
+ if (isBottom) {
109
+ this.asideBottomULElement.appendChild($asideLiElement);
110
+ } else {
111
+ this.asideULElement.appendChild($asideLiElement);
112
+ }
113
+ if ($defaultAsideItem == null) {
114
+ let flag = false;
115
+ if (typeof asideItemConfig.isDefault === "function") {
116
+ flag = Boolean(asideItemConfig.isDefault());
117
+ } else {
118
+ flag = Boolean(asideItemConfig.isDefault);
119
+ }
120
+ if (flag) {
121
+ $defaultAsideItem = $asideLiElement;
122
+ isScrollToDefaultView = Boolean(asideItemConfig.scrollToDefaultView);
123
+ }
124
+ }
125
+ if (typeof asideItemConfig.afterRender === "function") {
126
+ // 执行渲染完毕的回调
127
+ asideItemConfig.afterRender({
128
+ asideConfig: asideItemConfig,
129
+ $asideLiElement: $asideLiElement,
130
+ });
131
+ }
132
+ });
133
+
134
+ /* 点击左侧列表 */
135
+ if ($defaultAsideItem == null && this.asideULElement.children.length) {
136
+ /* 默认第一个 */
137
+ $defaultAsideItem = <HTMLLIElement>this.asideULElement.children[0];
138
+ }
139
+ if ($defaultAsideItem) {
140
+ /* 点击选择的那一项 */
141
+ $defaultAsideItem.click();
142
+ if (isScrollToDefaultView) {
143
+ $defaultAsideItem?.scrollIntoView();
144
+ }
145
+ } else {
146
+ console.error("pops.panel:左侧容器没有项");
147
+ }
148
+ },
149
+ /**
150
+ * 清空container容器的元素
151
+ */
152
+ clearContainer() {
153
+ Reflect.deleteProperty(this.$el.$contentSectionContainer, "__formConfig__");
154
+ PopsSafeUtils.setSafeHTML(this.sectionContainerHeaderULElement, "");
155
+ PopsSafeUtils.setSafeHTML(this.sectionContainerULElement, "");
156
+ this.clearDeepMenuContainer();
157
+ },
158
+ /**
159
+ * 清空deepMenu的容器元素
160
+ */
161
+ clearDeepMenuContainer() {
162
+ this.$el.$sectionWrapper
163
+ ?.querySelectorAll("section.pops-panel-deepMenu-container")
164
+ .forEach(($el) => $el.remove());
165
+ },
166
+ /**
167
+ * 清空左侧容器已访问记录
168
+ */
169
+ clearAsideItemIsVisited() {
170
+ this.$el.$contentAside.querySelectorAll<HTMLDivElement>(".pops-is-visited").forEach(($el) => {
171
+ popsDOMUtils.removeClassName($el, "pops-is-visited");
172
+ });
173
+ },
174
+ /**
175
+ * 设置左侧容器已访问记录
176
+ * @param element
177
+ */
178
+ setAsideItemIsVisited(element: HTMLElement) {
179
+ popsDOMUtils.addClassName(element, "pops-is-visited");
180
+ },
181
+ /**
182
+ * 为元素添加自定义属性
183
+ * @param element
184
+ * @param attributes
185
+ */
186
+ setElementAttributes(element: HTMLElement, attributes?: any) {
187
+ if (attributes == null) {
188
+ return;
189
+ }
190
+ if (Array.isArray(attributes)) {
191
+ attributes.forEach((attrObject) => {
192
+ this.setElementAttributes(element, attrObject);
193
+ });
194
+ } else {
195
+ Object.keys(attributes).forEach((attributeName) => {
196
+ element.setAttribute(attributeName, attributes[attributeName]);
197
+ });
198
+ }
199
+ },
200
+ /**
201
+ * 为元素设置(自定义)属性
202
+ * @param element
203
+ * @param props
204
+ */
205
+ setElementProps(element: HTMLElement, props?: any) {
206
+ if (props == null) {
207
+ return;
208
+ }
209
+ Object.keys(props).forEach((propName) => {
210
+ const value = props[propName];
211
+ if (propName === "innerHTML") {
212
+ PopsSafeUtils.setSafeHTML(element, value);
213
+ return;
214
+ }
215
+ Reflect.set(element, propName, value);
216
+ });
217
+ },
218
+ /**
219
+ * 为元素设置classname
220
+ * @param element
221
+ * @param className
222
+ */
223
+ setElementClassName(element: HTMLElement, className?: string | string[] | (() => string | string[])) {
224
+ if (className == null) {
225
+ return;
226
+ }
227
+ if (typeof className === "function") {
228
+ className = className();
229
+ }
230
+ if (typeof className === "string") {
231
+ const splitClassName = className.split(" ");
232
+ splitClassName.forEach((classNameStr) => {
233
+ element.classList.add(classNameStr);
234
+ });
235
+ } else if (Array.isArray(className)) {
236
+ className.forEach((classNameStr) => {
237
+ this.setElementClassName(element, classNameStr);
238
+ });
239
+ }
240
+ },
241
+ /**
242
+ * 创建左侧容器元素<li>
243
+ * @param asideConfig
244
+ */
245
+ createAsideItem(asideConfig: PopsPanelContentConfig) {
246
+ const $li = document.createElement("li");
247
+ $li.id = asideConfig.id;
248
+ Reflect.set($li, "__forms__", asideConfig.forms);
249
+ const title = typeof asideConfig.title === "function" ? asideConfig.title() : asideConfig.title;
250
+ PopsSafeUtils.setSafeHTML($li, title);
251
+ /* 处理className */
252
+ this.setElementClassName($li, "pops-panel-aside-item");
253
+ this.setElementClassName($li, asideConfig.className);
254
+ this.setElementAttributes($li, asideConfig.attributes);
255
+ this.setElementProps($li, asideConfig.props);
256
+ /** 禁用左侧项的hover的CSS样式的类名 */
257
+ const disableAsideItemHoverCSSClassName = "pops-panel-disabled-aside-hover-css";
258
+ /** 是否禁用左侧项的hover的CSS样式 */
259
+ const disableAsideItemHoverCSS =
260
+ typeof asideConfig.disableAsideItemHoverCSS === "function"
261
+ ? asideConfig.disableAsideItemHoverCSS()
262
+ : asideConfig.disableAsideItemHoverCSS;
263
+ if (disableAsideItemHoverCSS) {
264
+ $li.classList.add(disableAsideItemHoverCSSClassName);
265
+ } else {
266
+ $li.classList.remove(disableAsideItemHoverCSSClassName);
267
+ }
268
+ return $li;
269
+ },
270
+ /**
271
+ * type ==> switch
272
+ * 创建中间容器的元素<li>
273
+ * @param formConfig
274
+ */
275
+ createSectionContainerItem_switch(formConfig: PopsPanelSwitchDetails) {
276
+ const $li = document.createElement("li");
277
+ Reflect.set($li, "__formConfig__", formConfig);
278
+ this.setElementClassName($li, formConfig.className);
279
+ this.setElementAttributes($li, formConfig.attributes);
280
+ this.setElementProps($li, formConfig.props);
281
+ /* 左边底部的描述的文字 */
282
+ let leftDescriptionText = "";
283
+ if (formConfig.description) {
284
+ leftDescriptionText = /*html*/ `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
285
+ }
286
+ PopsSafeUtils.setSafeHTML(
287
+ $li,
288
+ /*html*/ `
289
+ <div class="pops-panel-item-left-text">
290
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
291
+ <div class="pops-panel-switch">
292
+ <input class="pops-panel-switch__input" type="checkbox">
293
+ <span class="pops-panel-switch__core">
294
+ <div class="pops-panel-switch__action">
295
+ </div>
296
+ </span>
297
+ </div>`
298
+ );
299
+ const PopsPanelSwitch = {
300
+ [Symbol.toStringTag]: "PopsPanelSwitch",
301
+ $data: {
302
+ value: Boolean(formConfig.getValue()),
303
+ },
304
+ $ele: {
305
+ itemLeftTextContainer: $li.querySelector<HTMLElement>(".pops-panel-item-left-text"),
306
+ switch: $li.querySelector<HTMLDivElement>(".pops-panel-switch")!,
307
+ input: $li.querySelector<HTMLInputElement>(".pops-panel-switch__input")!,
308
+ core: $li.querySelector<HTMLSpanElement>(".pops-panel-switch__core")!,
309
+ },
310
+ init() {
311
+ this.setStatus(this.$data.value);
312
+ const disabled = typeof formConfig.disabled === "function" ? formConfig.disabled() : formConfig.disabled;
313
+ if (disabled) {
314
+ this.disable();
315
+ }
316
+ this.setClickEvent();
317
+ },
318
+ /**
319
+ * 设置点击事件
320
+ */
321
+ setClickEvent() {
322
+ const that = this;
323
+ popsDOMUtils.on(this.$ele.core, "click", function (event) {
324
+ if (that.$ele.input.disabled || that.$ele.switch.hasAttribute("data-disabled")) {
325
+ return;
326
+ }
327
+ that.$data.value = that.getStatus();
328
+ that.setStatus(that.$data.value);
329
+ if (typeof formConfig.callback === "function") {
330
+ formConfig.callback(event, that.$data.value);
331
+ }
332
+ });
333
+ },
334
+ /**
335
+ * 设置状态
336
+ */
337
+ setStatus(isChecked = false) {
338
+ isChecked = Boolean(isChecked);
339
+ this.$ele.input.checked = isChecked;
340
+ if (isChecked) {
341
+ popsDOMUtils.addClassName(this.$ele.switch, "pops-panel-switch-is-checked");
342
+ } else {
343
+ popsDOMUtils.removeClassName(this.$ele.switch, "pops-panel-switch-is-checked");
344
+ }
345
+ },
346
+ /**
347
+ * 根据className来获取逆反值
348
+ */
349
+ getStatus() {
350
+ let checkedValue = false;
351
+ if (!popsDOMUtils.containsClassName(this.$ele.switch, "pops-panel-switch-is-checked")) {
352
+ checkedValue = true;
353
+ }
354
+ return checkedValue;
355
+ },
356
+ /**
357
+ * 禁用复选框
358
+ */
359
+ disable() {
360
+ this.$ele.input.disabled = true;
361
+ this.$ele.switch.setAttribute("data-disabled", "true");
362
+ popsDOMUtils.addClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
363
+ },
364
+ /**
365
+ * 取消禁用复选框
366
+ */
367
+ notDisable() {
368
+ this.$ele.input.disabled = false;
369
+ this.$ele.switch.removeAttribute("data-disabled");
370
+ popsDOMUtils.removeClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
371
+ },
372
+ };
373
+
374
+ PopsPanelSwitch.init();
375
+ Reflect.set($li, "data-switch", PopsPanelSwitch);
376
+ return $li;
377
+ },
378
+ /**
379
+ * type ==> slider
380
+ * 获取中间容器的元素<li>
381
+ * @param formConfig
382
+ */
383
+ createSectionContainerItem_slider(formConfig: PopsPanelSliderDetails) {
384
+ const $li = document.createElement("li");
385
+ Reflect.set($li, "__formConfig__", formConfig);
386
+ this.setElementClassName($li, formConfig.className);
387
+ this.setElementAttributes($li, formConfig.attributes);
388
+ this.setElementProps($li, formConfig.props);
389
+ /* 左边底部的描述的文字 */
390
+ let leftDescriptionText = "";
391
+ if (formConfig.description) {
392
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
393
+ }
394
+ PopsSafeUtils.setSafeHTML(
395
+ $li,
396
+ /*html*/ `
397
+ <div class="pops-panel-item-left-text">
398
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
399
+ <div class="pops-panel-slider">
400
+ <input type="range" min="${formConfig.min}" max="${formConfig.max}">
401
+ </div>
402
+ `
403
+ );
404
+ const $rangeInput = $li.querySelector<HTMLInputElement>(".pops-panel-slider input[type=range]")!;
405
+ if (formConfig.step) {
406
+ $rangeInput.setAttribute("step", formConfig.step.toString());
407
+ }
408
+ $rangeInput.value = formConfig.getValue().toString();
409
+ /**
410
+ * 获取提示的内容
411
+ * @param value
412
+ */
413
+ const getToolTipContent = function (value: number | string) {
414
+ if (typeof formConfig.getToolTipContent === "function") {
415
+ return formConfig.getToolTipContent(value as number);
416
+ } else {
417
+ return value as string;
418
+ }
419
+ };
420
+ const tooltip = PopsTooltip.init({
421
+ target: $rangeInput.parentElement!,
422
+ content: () => {
423
+ return getToolTipContent($rangeInput.value);
424
+ },
425
+ zIndex: () => {
426
+ return PopsInstanceUtils.getPopsMaxZIndex().zIndex;
427
+ },
428
+ className: "github-tooltip",
429
+ alwaysShow: false,
430
+ only: false,
431
+ position: "top",
432
+ arrowDistance: 10,
433
+ });
434
+ popsDOMUtils.on<InputEvent>($rangeInput, ["input", "propertychange"], void 0, function (event) {
435
+ tooltip.toolTip.changeContent(getToolTipContent($rangeInput.value));
436
+ if (typeof formConfig.callback === "function") {
437
+ formConfig.callback(event, $rangeInput.valueAsNumber);
438
+ }
439
+ });
440
+ return $li;
441
+ },
442
+ /**
443
+ * type ==> slider
444
+ * 获取中间容器的元素<li>
445
+ * @param formConfig
446
+ */
447
+ createSectionContainerItem_slider_new(formConfig: PopsPanelSliderDetails) {
448
+ const $li = document.createElement("li");
449
+ Reflect.set($li, "__formConfig__", formConfig);
450
+ this.setElementClassName($li, formConfig.className);
451
+ this.setElementAttributes($li, formConfig.attributes);
452
+ this.setElementProps($li, formConfig.props);
453
+ /* 左边底部的描述的文字 */
454
+ let leftDescriptionText = "";
455
+ if (formConfig.description) {
456
+ leftDescriptionText = /*html*/ `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
457
+ }
458
+ PopsSafeUtils.setSafeHTML(
459
+ $li,
460
+ /*html*/ `
461
+ <div class="pops-panel-item-left-text" style="flex: 1;">
462
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
463
+ <div class="pops-slider pops-slider-width">
464
+ <div class="pops-slider__runway">
465
+ <div class="pops-slider__bar" style="width: 0%; left: 0%"></div>
466
+ <div class="pops-slider__button-wrapper" style="left: 0%">
467
+ <div class="pops-slider__button"></div>
468
+ </div>
469
+ </div>
470
+ </div>`
471
+ );
472
+ const PopsPanelSlider = {
473
+ [Symbol.toStringTag]: "PopsPanelSlider",
474
+ /**
475
+ * 值
476
+ */
477
+ value: formConfig.getValue(),
478
+ /**
479
+ * 最小值
480
+ */
481
+ min: formConfig.min,
482
+ /**
483
+ * 最大值
484
+ */
485
+ max: formConfig.max,
486
+ /**
487
+ * 间隔
488
+ */
489
+ step: formConfig.step || 1,
490
+ $data: {
491
+ /**
492
+ * 是否正在移动
493
+ */
494
+ isMove: false,
495
+ /**
496
+ * 是否已初始化已拖拽的距离
497
+ */
498
+ isInitDragPosition: false,
499
+ /**
500
+ * 是否正在检测是否停止拖拽
501
+ */
502
+ isCheckingStopDragMove: false,
503
+ /**
504
+ * 总宽度(px)
505
+ */
506
+ totalWidth: 0,
507
+ /**
508
+ * 每一块的间隔(px)
509
+ */
510
+ stepPx: 0,
511
+ /**
512
+ * 已拖拽的距离(px)
513
+ */
514
+ dragWidth: 0,
515
+ /**
516
+ * 已拖拽的百分比
517
+ */
518
+ dragPercent: 0,
519
+ /**
520
+ * 每一次块的信息
521
+ * 例如:当最小值是2,最大值是10,step为2
522
+ * 那么生成[2,4,6,8,10] 共计5个
523
+ * 又获取到当前滑块总长度是200px
524
+ * 那么生成映射
525
+ * 2 => 0px~40px
526
+ * 4 => 40px~80px
527
+ * 6 => 80px~120px
528
+ * 8 => 120px~160px
529
+ * 10 => 160px~200px
530
+ */
531
+ stepBlockMap: new Map<
532
+ number,
533
+ {
534
+ value: number;
535
+ px: number;
536
+ pxLeft: number;
537
+ pxRight: number;
538
+ percent: number;
539
+ }
540
+ >(),
541
+ tooltip: null as any as ReturnType<typeof PopsTooltip.init>,
542
+ },
543
+ $ele: {
544
+ itemLeftTextContainer: $li.querySelector<HTMLElement>(".pops-panel-item-left-text"),
545
+ slider: $li.querySelector<HTMLElement>(".pops-slider")!,
546
+ runAway: $li.querySelector<HTMLElement>(".pops-slider__runway")!,
547
+ bar: $li.querySelector<HTMLElement>(".pops-slider__bar")!,
548
+ buttonWrapper: $li.querySelector<HTMLElement>(".pops-slider__button-wrapper")!,
549
+ button: $li.querySelector<HTMLElement>(".pops-slider__button")!,
550
+ },
551
+ $interval: {
552
+ isCheck: false,
553
+ },
554
+ $tooltip: null as any as ReturnType<typeof popsUtils.AnyTouch>["prototype"],
555
+ init() {
556
+ this.initEleData();
557
+ this.setToolTipEvent();
558
+ this.setPanEvent();
559
+ this.setRunAwayClickEvent();
560
+ this.intervalInit();
561
+ if (this.isFormConfigDisabledDrag()) {
562
+ this.disableDrag();
563
+ }
564
+ },
565
+ /**
566
+ * 10s内循环获取slider的宽度等信息
567
+ * 获取到了就可以初始化left的值
568
+ * @param [checkStepTime=200] 每次检测的间隔时间
569
+ * @param [maxTime=10000] 最大的检测时间
570
+ */
571
+ intervalInit(checkStepTime = 200, maxTime = 10000) {
572
+ if (this.$interval.isCheck) {
573
+ return;
574
+ }
575
+ this.$interval.isCheck = true;
576
+ let isSuccess = false;
577
+ const oldTotalWidth = this.$data.totalWidth;
578
+ let timer: number | undefined = void 0;
579
+ const interval = setInterval(() => {
580
+ if (isSuccess) {
581
+ this.$interval.isCheck = false;
582
+ clearTimeout(timer);
583
+ clearInterval(interval);
584
+ } else {
585
+ this.initTotalWidth();
586
+ if (this.$data.totalWidth !== 0) {
587
+ isSuccess = true;
588
+ if (this.$data.totalWidth !== oldTotalWidth) {
589
+ /* slider的总宽度改变了 */
590
+ if (PopsMathFloatUtils.isFloat(this.step)) {
591
+ this.initFloatStepMap();
592
+ } else {
593
+ this.initStepMap();
594
+ }
595
+ this.initSliderPosition();
596
+ }
597
+ }
598
+ }
599
+ }, checkStepTime);
600
+ /* 最长检测时间是10s */
601
+ timer = setTimeout(() => {
602
+ clearInterval(interval);
603
+ }, maxTime);
604
+ },
605
+ /**
606
+ * 把数据添加到元素上
607
+ */
608
+ initEleData() {
609
+ this.$ele.slider.setAttribute("data-min", this.min.toString());
610
+ this.$ele.slider.setAttribute("data-max", this.max.toString());
611
+ this.$ele.slider.setAttribute("data-value", this.value.toString());
612
+ this.$ele.slider.setAttribute("data-step", this.step.toString());
613
+ Reflect.set(this.$ele.slider, "data-min", this.min);
614
+ Reflect.set(this.$ele.slider, "data-max", this.max);
615
+ Reflect.set(this.$ele.slider, "data-value", this.value);
616
+ Reflect.set(this.$ele.slider, "data-step", this.step);
617
+ },
618
+ /**
619
+ * 初始化滑块的总长度的数据(px)
620
+ */
621
+ initTotalWidth() {
622
+ this.$data.totalWidth = popsDOMUtils.width(this.$ele.runAway);
623
+ },
624
+ /**
625
+ * 初始化每一个块的具体数据信息
626
+ */
627
+ initStepMap() {
628
+ let index = 0;
629
+ // 计算出份数
630
+ const blockNums = (this.max - this.min) / this.step;
631
+ // 计算出每一份占据的px
632
+ this.$data.stepPx = this.$data.totalWidth / blockNums;
633
+ let widthPx = 0;
634
+ for (let stepValue = this.min; stepValue <= this.max; stepValue += this.step) {
635
+ const value = this.formatValue(stepValue);
636
+ let info;
637
+ if (value === this.min) {
638
+ /* 起始 */
639
+ info = {
640
+ value: value,
641
+ px: 0,
642
+ pxLeft: 0,
643
+ pxRight: this.$data.stepPx / 2,
644
+ percent: 0,
645
+ };
646
+ } else {
647
+ info = {
648
+ value: value,
649
+ px: widthPx,
650
+ pxLeft: widthPx - this.$data.stepPx / 2,
651
+ pxRight: widthPx + this.$data.stepPx / 2,
652
+ percent: widthPx / this.$data.totalWidth,
653
+ };
654
+ //if (value === this.max) {
655
+ // info["pxLeft"] = this.$data.stepBlockMap.get(
656
+ // index - 1
657
+ // ).pxRight;
658
+ // info["pxRight"] = this.$data.totalWidth;
659
+ //}
660
+ }
661
+ this.$data.stepBlockMap.set(index, info);
662
+ index++;
663
+ widthPx += this.$data.stepPx;
664
+ }
665
+ },
666
+ /**
667
+ * 初始化每一个块的具体数据信息(浮点)
668
+ */
669
+ initFloatStepMap() {
670
+ let index = 0;
671
+ // 计算出份数
672
+ const blockNums = (this.max - this.min) / this.step;
673
+ // 计算出每一份占据的px
674
+ this.$data.stepPx = this.$data.totalWidth / blockNums;
675
+ let widthPx = 0;
676
+ for (
677
+ let stepValue = this.min;
678
+ stepValue <= this.max;
679
+ stepValue = PopsMathFloatUtils.add(stepValue, this.step)
680
+ ) {
681
+ const value = this.formatValue(stepValue);
682
+ let info;
683
+ if (value === this.min) {
684
+ /* 起始 */
685
+ info = {
686
+ value: value,
687
+ px: 0,
688
+ pxLeft: 0,
689
+ pxRight: this.$data.stepPx / 2,
690
+ percent: 0,
691
+ };
692
+ } else {
693
+ info = {
694
+ value: value,
695
+ px: widthPx,
696
+ pxLeft: widthPx - this.$data.stepPx / 2,
697
+ pxRight: widthPx + this.$data.stepPx / 2,
698
+ percent: widthPx / this.$data.totalWidth,
699
+ };
700
+ //if (value === this.max) {
701
+ // info["pxLeft"] = this.$data.stepBlockMap.get(
702
+ // index - 1
703
+ // ).pxRight;
704
+ // info["pxRight"] = this.$data.totalWidth;
705
+ //}
706
+ }
707
+ this.$data.stepBlockMap.set(index, info);
708
+ index++;
709
+ widthPx += this.$data.stepPx;
710
+ }
711
+ },
712
+ /**
713
+ * 初始化slider的默认起始left的百分比值
714
+ */
715
+ initSliderPosition() {
716
+ /* 设置起始默认style的left值 */
717
+ let percent = 0;
718
+ for (const [, stepBlockInfo] of this.$data.stepBlockMap.entries()) {
719
+ /* 判断值是否和区域内的值相等 */
720
+ if (stepBlockInfo.value == this.value) {
721
+ percent = stepBlockInfo.percent;
722
+ this.$data.dragWidth = stepBlockInfo.px;
723
+ break;
724
+ }
725
+ }
726
+ percent = this.formatValue(percent * 100);
727
+ this.setSliderPosition(percent);
728
+ },
729
+ /**
730
+ * 判断数字是否是浮点数
731
+ * @param num
732
+ */
733
+ isFloat(num: number) {
734
+ return Number(num) === num && num % 1 !== 0;
735
+ },
736
+ /**
737
+ * 值改变的回调
738
+ * @param event
739
+ * @param value
740
+ */
741
+ valueChangeCallBack(event: any, value: number) {
742
+ if (typeof formConfig.callback === "function") {
743
+ formConfig.callback(event, value);
744
+ }
745
+ },
746
+ /**
747
+ * 根据拖拽距离获取滑块应该在的区间和值
748
+ * @param dragX
749
+ */
750
+ getDragInfo(dragX: number) {
751
+ let result = this.$data.stepBlockMap.get(0);
752
+ for (const [, stepBlockInfo] of this.$data.stepBlockMap.entries()) {
753
+ if (stepBlockInfo.pxLeft <= dragX && dragX < stepBlockInfo.pxRight) {
754
+ result = stepBlockInfo;
755
+ break;
756
+ }
757
+ }
758
+ return result;
759
+ },
760
+ /**
761
+ * 获取滑块的当前脱拖拽占据的百分比
762
+ * @param dragWidth
763
+ */
764
+ getSliderPositonPercent(dragWidth: number) {
765
+ return dragWidth / this.$data.totalWidth;
766
+ },
767
+ /**
768
+ * 根据step格式化value
769
+ * @param num
770
+ */
771
+ formatValue(num: number) {
772
+ if (PopsMathFloatUtils.isFloat(this.step)) {
773
+ num = parseFloat(num.toFixed(2));
774
+ } else {
775
+ num = parseInt(num.toString());
776
+ }
777
+ return num;
778
+ },
779
+ /**
780
+ * 设置滑块的位置偏移(left)
781
+ * @param percent 百分比
782
+ */
783
+ setSliderPosition(percent: number) {
784
+ if (parseInt(percent.toString()) === 1) {
785
+ percent = 1;
786
+ }
787
+ if (percent > 1) {
788
+ percent = percent / 100;
789
+ }
790
+ /* 滑块按钮的偏移 */
791
+ this.$ele.buttonWrapper.style.left = `${percent * 100}%`;
792
+ /* 滑块进度的宽度 */
793
+ this.$ele.bar.style.width = `${percent * 100}%`;
794
+ },
795
+ /**
796
+ * 禁止拖拽
797
+ */
798
+ disableDrag() {
799
+ popsDOMUtils.addClassName(this.$ele.runAway, "pops-slider-is-disabled");
800
+ popsDOMUtils.addClassName(this.$ele.runAway, PopsCommonCSSClassName.textIsDisabled);
801
+ },
802
+ /**
803
+ * 允许拖拽
804
+ */
805
+ allowDrag() {
806
+ popsDOMUtils.removeClassName(this.$ele.runAway, "pops-slider-is-disabled");
807
+ popsDOMUtils.removeClassName(this.$ele.runAway, PopsCommonCSSClassName.textIsDisabled);
808
+ },
809
+ /**
810
+ * 判断当前滑块是否被禁用
811
+ */
812
+ isDisabledDrag() {
813
+ return popsDOMUtils.containsClassName(this.$ele.runAway, "pops-slider-is-disabled");
814
+ },
815
+ /**
816
+ * 判断当前滑块是否被禁用(配置中判断)
817
+ */
818
+ isFormConfigDisabledDrag() {
819
+ const isDisabled = typeof formConfig.disabled === "function" ? formConfig.disabled() : formConfig.disabled;
820
+ if (typeof isDisabled === "boolean") {
821
+ return isDisabled;
822
+ } else {
823
+ return false;
824
+ }
825
+ },
826
+ /**
827
+ * 设置进度条点击定位的事件
828
+ */
829
+ setRunAwayClickEvent() {
830
+ popsDOMUtils.on<PointerEvent | MouseEvent>(
831
+ this.$ele.runAway,
832
+ "click",
833
+ (event) => {
834
+ if (event.target !== this.$ele.runAway && event.target !== this.$ele.bar) {
835
+ return;
836
+ }
837
+ const clickX = parseFloat(event.offsetX.toString());
838
+ const dragStartResult = this.dragStartCallBack();
839
+ if (!dragStartResult) {
840
+ return;
841
+ }
842
+ this.dragMoveCallBack(event, clickX, this.value);
843
+ this.dragEndCallBack(clickX);
844
+ },
845
+ {
846
+ capture: false,
847
+ }
848
+ );
849
+ },
850
+ /**
851
+ * 拖拽开始的回调,如果返回false,禁止拖拽
852
+ */
853
+ dragStartCallBack() {
854
+ if (this.isFormConfigDisabledDrag()) {
855
+ // 禁止
856
+ this.disableDrag();
857
+ return false;
858
+ }
859
+ if (!this.$data.isMove) {
860
+ // 非移动中
861
+ if (this.isDisabledDrag()) {
862
+ // 允许
863
+ this.allowDrag();
864
+ }
865
+
866
+ this.$data.isMove = true;
867
+ }
868
+ return true;
869
+ },
870
+ /**
871
+ * 拖拽中的回调
872
+ * @param event 事件
873
+ * @param dragX 当前拖拽的距离
874
+ * @param oldValue 旧的值
875
+ */
876
+ dragMoveCallBack(event: any, dragX: number, oldValue: number) {
877
+ let dragPercent = 0;
878
+ if (dragX <= 0) {
879
+ dragPercent = 0;
880
+ this.value = this.min;
881
+ } else if (dragX >= this.$data.totalWidth) {
882
+ dragPercent = 1;
883
+ this.value = this.max;
884
+ } else {
885
+ const dragInfo = this.getDragInfo(dragX)!;
886
+ dragPercent = dragInfo.percent;
887
+ this.value = this.formatValue(dragInfo.value);
888
+ }
889
+ this.$data.dragPercent = dragPercent;
890
+ this.setSliderPosition(this.$data.dragPercent);
891
+ this.showToolTip();
892
+ if (oldValue !== this.value) {
893
+ this.valueChangeCallBack(event, this.value);
894
+ }
895
+ },
896
+ /**
897
+ * 拖拽结束的回调
898
+ */
899
+ dragEndCallBack(dragX: number) {
900
+ this.$data.isMove = false;
901
+ if (dragX <= 0) {
902
+ this.$data.dragWidth = 0;
903
+ } else if (dragX >= this.$data.totalWidth) {
904
+ this.$data.dragWidth = this.$data.totalWidth;
905
+ } else {
906
+ this.$data.dragWidth = dragX;
907
+ }
908
+ this.closeToolTip();
909
+ },
910
+ /**
911
+ * 设置点击拖拽事件
912
+ */
913
+ setPanEvent() {
914
+ const AnyTouch = popsUtils.AnyTouch();
915
+ this.$tooltip = new AnyTouch(this.$ele.button, {
916
+ preventDefault() {
917
+ return false;
918
+ },
919
+ });
920
+ /**
921
+ * 当前的拖拽的距离px
922
+ */
923
+ let currentDragX = 0;
924
+ /* 监听拖拽 */
925
+ this.$tooltip.on("at:move", (event) => {
926
+ if (!this.dragStartCallBack()) {
927
+ return;
928
+ }
929
+ const oldValue = this.value;
930
+ const runAwayRect = this.$ele.runAway.getBoundingClientRect();
931
+ let displacementX = event.x - (runAwayRect.left + globalThis.screenX);
932
+ if (displacementX <= 0) {
933
+ displacementX = 0;
934
+ } else if (displacementX >= runAwayRect.width) {
935
+ displacementX = runAwayRect.width;
936
+ }
937
+ currentDragX = displacementX;
938
+ /* 拖拽移动 */
939
+ this.dragMoveCallBack(event, currentDragX, oldValue);
940
+ });
941
+ /* 监听触点离开,处理某些情况下,拖拽松开,但是未触发pan事件,可以通过设置这个来关闭tooltip */
942
+ this.$tooltip.on("at:end", () => {
943
+ this.dragEndCallBack(currentDragX);
944
+ });
945
+ },
946
+ /**
947
+ * 显示悬浮的
948
+ */
949
+ showToolTip() {
950
+ this.$data.tooltip.toolTip.show();
951
+ },
952
+ /**
953
+ * 关闭悬浮的
954
+ */
955
+ closeToolTip() {
956
+ this.$data.tooltip.toolTip.close();
957
+ },
958
+ /**
959
+ * 检测在1000ms内,是否停止了拖拽
960
+ */
961
+ checkStopDragMove() {
962
+ if (this.$data.isCheckingStopDragMove) {
963
+ return;
964
+ }
965
+ this.$data.isCheckingStopDragMove = true;
966
+ const interval = setInterval(() => {
967
+ if (!this.$data.isMove) {
968
+ this.$data.isCheckingStopDragMove = false;
969
+ this.closeToolTip();
970
+ clearInterval(interval);
971
+ }
972
+ }, 200);
973
+ setTimeout(() => {
974
+ this.$data.isCheckingStopDragMove = false;
975
+ clearInterval(interval);
976
+ }, 2000);
977
+ },
978
+ /**
979
+ * 设置拖拽按钮的悬浮事件
980
+ */
981
+ setToolTipEvent() {
982
+ /**
983
+ * 获取提示的内容
984
+ */
985
+ function getToolTipContent() {
986
+ if (typeof formConfig.getToolTipContent === "function") {
987
+ return formConfig.getToolTipContent(PopsPanelSlider.value);
988
+ } else {
989
+ return PopsPanelSlider.value.toString();
990
+ }
991
+ }
992
+
993
+ const tooltip = PopsTooltip.init({
994
+ target: this.$ele.button,
995
+ content: getToolTipContent,
996
+ zIndex: () => {
997
+ return PopsInstanceUtils.getPopsMaxZIndex().zIndex;
998
+ },
999
+ isFixed: true,
1000
+ className: "github-tooltip",
1001
+ only: false,
1002
+ eventOption: {
1003
+ capture: true,
1004
+ passive: true,
1005
+ },
1006
+ showBeforeCallBack: () => {
1007
+ const isShowHoverTip =
1008
+ typeof formConfig.isShowHoverTip === "function"
1009
+ ? formConfig.isShowHoverTip()
1010
+ : typeof formConfig.isShowHoverTip === "boolean"
1011
+ ? formConfig.isShowHoverTip
1012
+ : true;
1013
+ if (!isShowHoverTip) {
1014
+ return false;
1015
+ }
1016
+ this.intervalInit();
1017
+ },
1018
+ showAfterCallBack: () => {
1019
+ tooltip.toolTip.changeContent(getToolTipContent());
1020
+ },
1021
+ closeBeforeCallBack: () => {
1022
+ if (this.$data.isMove) {
1023
+ this.checkStopDragMove();
1024
+ return false;
1025
+ }
1026
+ },
1027
+ alwaysShow: false,
1028
+ position: "top",
1029
+ arrowDistance: 10,
1030
+ });
1031
+ this.$data.tooltip = tooltip;
1032
+ },
1033
+ };
1034
+ PopsPanelSlider.init();
1035
+ Reflect.set($li, "data-slider", PopsPanelSlider);
1036
+ return $li;
1037
+ },
1038
+ /**
1039
+ * type ==> input
1040
+ * 获取中间容器的元素<li>
1041
+ * @param formConfig
1042
+ */
1043
+ createSectionContainerItem_input(formConfig: PopsPanelInputDetails) {
1044
+ const $li = document.createElement("li");
1045
+ Reflect.set($li, "__formConfig__", formConfig);
1046
+ this.setElementClassName($li, formConfig.className);
1047
+ this.setElementAttributes($li, formConfig.attributes);
1048
+ this.setElementProps($li, formConfig.props);
1049
+ let inputType = "text";
1050
+ if (formConfig.isPassword) {
1051
+ inputType = "password";
1052
+ } else if (formConfig.isNumber) {
1053
+ inputType = "number";
1054
+ }
1055
+ /* 左边底部的描述的文字 */
1056
+ let leftDescriptionText = "";
1057
+ if (formConfig.description) {
1058
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1059
+ }
1060
+ PopsSafeUtils.setSafeHTML(
1061
+ $li,
1062
+ /*html*/ `
1063
+ <div class="pops-panel-item-left-text">
1064
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
1065
+ <div class="pops-panel-input">
1066
+ <input type="${inputType}" placeholder="${formConfig.placeholder ?? ""}">
1067
+ </div>
1068
+ `
1069
+ );
1070
+ const PopsPanelInput = {
1071
+ [Symbol.toStringTag]: "PopsPanelInput",
1072
+ $ele: {
1073
+ itemLeftTextContainer: $li.querySelector<HTMLElement>(".pops-panel-item-left-text"),
1074
+ panelInput: $li.querySelector<HTMLDivElement>(".pops-panel-input")!,
1075
+ input: $li.querySelector<HTMLInputElement>("input")!,
1076
+ inputSpanIcon: document.createElement("span"),
1077
+ inputSpanIconInner: null as any as HTMLSpanElement,
1078
+ icon: null as any as HTMLElement,
1079
+ },
1080
+ $data: {
1081
+ value: formConfig.getValue(),
1082
+ isView: false,
1083
+ },
1084
+ init() {
1085
+ this.initEle();
1086
+ this.setInputValue(this.$data.value);
1087
+ /* 如果是密码框,放进图标 */
1088
+ if (formConfig.isPassword) {
1089
+ this.setCircleIcon(PopsIcon.getIcon("view")!);
1090
+ this.setCircleIconClickEvent();
1091
+ } else {
1092
+ /* 先判断预设值是否为空,不为空添加清空图标按钮 */
1093
+ if (this.$ele.input.value != "") {
1094
+ this.setCircleIcon(PopsIcon.getIcon("circleClose")!);
1095
+ this.setCircleIconClickEvent();
1096
+ }
1097
+ }
1098
+
1099
+ this.setInputChangeEvent();
1100
+ // 是否禁用复选框
1101
+ const disabled = typeof formConfig.disabled === "function" ? formConfig.disabled() : formConfig.disabled;
1102
+ if (disabled) {
1103
+ this.disable();
1104
+ }
1105
+ if (typeof formConfig.handlerCallBack === "function") {
1106
+ formConfig.handlerCallBack($li, this.$ele.input);
1107
+ }
1108
+ },
1109
+ /**
1110
+ * 初始化$ele的配置
1111
+ */
1112
+ initEle() {
1113
+ this.$ele.input.parentElement!.insertBefore(this.$ele.inputSpanIcon, this.$ele.input.nextSibling);
1114
+ this.$ele.inputSpanIcon.className = "pops-panel-input__suffix";
1115
+ PopsSafeUtils.setSafeHTML(
1116
+ this.$ele.inputSpanIcon,
1117
+ /*html*/ `
1118
+ <span class="pops-panel-input__suffix-inner">
1119
+ <i class="pops-panel-icon"></i>
1120
+ </span>
1121
+ `
1122
+ );
1123
+ this.$ele.inputSpanIconInner = this.$ele.inputSpanIcon.querySelector<HTMLElement>(
1124
+ ".pops-panel-input__suffix-inner"
1125
+ )!;
1126
+ this.$ele.icon = this.$ele.inputSpanIcon.querySelector<HTMLElement>(".pops-panel-icon")!;
1127
+ popsDOMUtils.addClassName(this.$ele.panelInput, PopsCommonCSSClassName.userSelectNone);
1128
+ },
1129
+ /**
1130
+ * 禁用
1131
+ */
1132
+ disable() {
1133
+ this.$ele.input.disabled = true;
1134
+ popsDOMUtils.addClassName(this.$ele.panelInput, "pops-input-disabled");
1135
+ popsDOMUtils.addClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
1136
+ },
1137
+ /**
1138
+ * 取消禁用
1139
+ */
1140
+ notDisable() {
1141
+ this.$ele.input.disabled = false;
1142
+ popsDOMUtils.removeClassName(this.$ele.panelInput, "pops-input-disabled");
1143
+ popsDOMUtils.removeClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
1144
+ },
1145
+ /**
1146
+ * 判断是否已被禁用
1147
+ */
1148
+ isDisabled() {
1149
+ return this.$ele.input.disabled;
1150
+ },
1151
+ /**
1152
+ * 设置输入框内容
1153
+ * @param {string} [value=""] 值
1154
+ */
1155
+ setInputValue(value = "") {
1156
+ this.$ele.input.value = value;
1157
+ },
1158
+ /**
1159
+ * 设置input元素的type
1160
+ * @param [typeValue="text"] type值
1161
+ */
1162
+ setInputType(typeValue = "text") {
1163
+ this.$ele.input.setAttribute("type", typeValue);
1164
+ },
1165
+ /**
1166
+ * 删除图标按钮
1167
+ */
1168
+ removeCircleIcon() {
1169
+ PopsSafeUtils.setSafeHTML(this.$ele.icon, "");
1170
+ },
1171
+ /**
1172
+ * 添加清空图标按钮
1173
+ * @param [svgHTML=PopsIcon.getIcon("circleClose")] svg图标,默认为清空的图标
1174
+ */
1175
+ setCircleIcon(svgHTML = PopsIcon.getIcon("circleClose")!) {
1176
+ PopsSafeUtils.setSafeHTML(this.$ele.icon, svgHTML);
1177
+ },
1178
+ /**
1179
+ * 添加图标按钮的点击事件
1180
+ */
1181
+ setCircleIconClickEvent() {
1182
+ popsDOMUtils.on(this.$ele.icon, "click", void 0, () => {
1183
+ if (this.isDisabled()) {
1184
+ return;
1185
+ }
1186
+ /* 删除图标 */
1187
+ this.removeCircleIcon();
1188
+ if (formConfig.isPassword) {
1189
+ /* 密码输入框 */
1190
+ if (this.$data.isView) {
1191
+ /* 当前可见 => 点击改变为隐藏 */
1192
+ this.$data.isView = false;
1193
+ /* 显示输入框内容,且更换图标为隐藏图标 */
1194
+ this.setInputType("text");
1195
+ this.setCircleIcon(PopsIcon.getIcon("hide")!);
1196
+ } else {
1197
+ /* 当前不可见 => 点击改变为显示 */
1198
+ this.$data.isView = true;
1199
+ /* 隐藏输入框内容,且更换图标为显示图标 */
1200
+ this.setInputType("password");
1201
+ this.setCircleIcon(PopsIcon.getIcon("view")!);
1202
+ }
1203
+ } else {
1204
+ /* 普通输入框 */
1205
+ /* 清空内容 */
1206
+ this.setInputValue("");
1207
+ /* 获取焦点 */
1208
+ this.$ele.input.focus();
1209
+ /* 触发内容改变事件 */
1210
+ this.$ele.input.dispatchEvent(new Event("input"));
1211
+ }
1212
+ });
1213
+ },
1214
+ /**
1215
+ * 监听输入框内容改变
1216
+ */
1217
+ setInputChangeEvent() {
1218
+ popsDOMUtils.on<InputEvent>(this.$ele.input, ["input", "propertychange"], void 0, (event) => {
1219
+ this.$data.value = this.$ele.input.value;
1220
+ if (!formConfig.isPassword) {
1221
+ /* 不是密码框 */
1222
+ if (this.$ele.input.value !== "" && this.$ele.icon.innerHTML === "") {
1223
+ /* 不为空,显示清空图标 */
1224
+ this.setCircleIcon(PopsIcon.getIcon("circleClose")!);
1225
+ this.setCircleIconClickEvent();
1226
+ } else if (this.$ele.input.value === "") {
1227
+ this.removeCircleIcon();
1228
+ }
1229
+ }
1230
+ if (typeof formConfig.callback === "function") {
1231
+ if (formConfig.isNumber) {
1232
+ formConfig.callback(event, this.$ele.input.value, this.$ele.input.valueAsNumber);
1233
+ } else {
1234
+ formConfig.callback(event, this.$ele.input.value);
1235
+ }
1236
+ }
1237
+ });
1238
+ },
1239
+ };
1240
+ PopsPanelInput.init();
1241
+ Reflect.set($li, "data-input", PopsPanelInput);
1242
+ return $li;
1243
+ },
1244
+ /**
1245
+ * type ==> textarea
1246
+ * 获取中间容器的元素<li>
1247
+ * @param formConfig
1248
+ */
1249
+ createSectionContainerItem_textarea(formConfig: PopsPanelTextAreaDetails) {
1250
+ const $li = document.createElement("li");
1251
+ Reflect.set($li, "__formConfig__", formConfig);
1252
+ this.setElementClassName($li, formConfig.className);
1253
+ this.setElementAttributes($li, formConfig.attributes);
1254
+ this.setElementProps($li, formConfig.props);
1255
+
1256
+ /* 左边底部的描述的文字 */
1257
+ let leftDescriptionText = "";
1258
+ if (formConfig.description) {
1259
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1260
+ }
1261
+ PopsSafeUtils.setSafeHTML(
1262
+ $li,
1263
+ /*html*/ `
1264
+ <div class="pops-panel-item-left-text">
1265
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
1266
+ <div class="pops-panel-textarea">
1267
+ <textarea placeholder="${formConfig.placeholder ?? ""}"></textarea>
1268
+ </div>
1269
+ `
1270
+ );
1271
+
1272
+ const PopsPanelTextArea = {
1273
+ [Symbol.toStringTag]: "PopsPanelTextArea",
1274
+ $ele: {
1275
+ itemLeftTextContainer: $li.querySelector<HTMLElement>(".pops-panel-item-left-text"),
1276
+ panelTextarea: $li.querySelector<HTMLDivElement>(".pops-panel-textarea")!,
1277
+ textarea: $li.querySelector<HTMLTextAreaElement>(".pops-panel-textarea textarea")!,
1278
+ },
1279
+ $data: {
1280
+ value: formConfig.getValue(),
1281
+ },
1282
+ init() {
1283
+ this.setValue(this.$data.value);
1284
+ this.setChangeEvent();
1285
+ const disabled = typeof formConfig.disabled === "function" ? formConfig.disabled() : formConfig.disabled;
1286
+ if (disabled) {
1287
+ this.disable();
1288
+ }
1289
+ },
1290
+ disable() {
1291
+ this.$ele.textarea.setAttribute("disabled", "true");
1292
+ popsDOMUtils.addClassName(this.$ele.panelTextarea, "pops-panel-textarea-disable");
1293
+ popsDOMUtils.addClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
1294
+ },
1295
+ notDisable() {
1296
+ this.$ele.textarea.removeAttribute("disabled");
1297
+ popsDOMUtils.removeClassName(this.$ele.panelTextarea, "pops-panel-textarea-disable");
1298
+ popsDOMUtils.removeClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
1299
+ },
1300
+ isDisabled() {
1301
+ return (
1302
+ this.$ele.textarea.hasAttribute("disabled") ||
1303
+ popsDOMUtils.containsClassName(this.$ele.panelTextarea, "pops-panel-textarea-disable")
1304
+ );
1305
+ },
1306
+ setValue(value: string) {
1307
+ this.$ele.textarea.value = value;
1308
+ },
1309
+ /**
1310
+ * 监听选择内容改变
1311
+ */
1312
+ setChangeEvent() {
1313
+ popsDOMUtils.on<InputEvent>(this.$ele.textarea, ["input", "propertychange"], (event) => {
1314
+ const value = this.$ele.textarea.value;
1315
+ this.$data.value = value;
1316
+ if (typeof formConfig.callback === "function") {
1317
+ formConfig.callback(
1318
+ event as InputEvent & {
1319
+ target: HTMLTextAreaElement;
1320
+ },
1321
+ value
1322
+ );
1323
+ }
1324
+ });
1325
+ },
1326
+ };
1327
+
1328
+ PopsPanelTextArea.init();
1329
+ Reflect.set($li, "data-textarea", PopsPanelTextArea);
1330
+
1331
+ return $li;
1332
+ },
1333
+ /**
1334
+ * type ==> select
1335
+ * 获取中间容器的元素<li>
1336
+ * @param formConfig
1337
+ */
1338
+ createSectionContainerItem_select(formConfig: PopsPanelSelectDetails<any>) {
1339
+ const that = this;
1340
+ const $li = document.createElement("li");
1341
+ Reflect.set($li, "__formConfig__", formConfig);
1342
+ this.setElementClassName($li, formConfig.className);
1343
+ this.setElementAttributes($li, formConfig.attributes);
1344
+ this.setElementProps($li, formConfig.props);
1345
+ /* 左边底部的描述的文字 */
1346
+ let leftDescriptionText = "";
1347
+ if (formConfig.description) {
1348
+ leftDescriptionText = /*html*/ `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1349
+ }
1350
+ PopsSafeUtils.setSafeHTML(
1351
+ $li,
1352
+ /*html*/ `
1353
+ <div class="pops-panel-item-left-text">
1354
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
1355
+ <div class="pops-panel-select">
1356
+ <select></select>
1357
+ </div>
1358
+ `
1359
+ );
1360
+
1361
+ const PopsPanelSelect = {
1362
+ [Symbol.toStringTag]: "PopsPanelSelect",
1363
+ $ele: {
1364
+ itemLeftTextContainer: $li.querySelector<HTMLElement>(".pops-panel-item-left-text"),
1365
+ panelSelect: $li.querySelector<HTMLDivElement>(".pops-panel-select")!,
1366
+ select: $li.querySelector<HTMLSelectElement>(".pops-panel-select select")!,
1367
+ },
1368
+ $eleKey: {
1369
+ disable: "__disable__",
1370
+ value: "__value__",
1371
+ forms: "__forms__",
1372
+ },
1373
+ $data: {
1374
+ defaultValue: formConfig.getValue(),
1375
+ },
1376
+ init() {
1377
+ popsDOMUtils.addClassName(this.$ele.panelSelect, PopsCommonCSSClassName.userSelectNone);
1378
+ this.initOption();
1379
+ this.setChangeEvent();
1380
+ this.setClickEvent();
1381
+ const disabled = typeof formConfig.disabled === "function" ? formConfig.disabled() : formConfig.disabled;
1382
+ if (disabled) {
1383
+ this.disable();
1384
+ }
1385
+ },
1386
+ /**
1387
+ * 给option元素设置属性
1388
+ * @param $ele
1389
+ * @param key
1390
+ * @param value
1391
+ */
1392
+ setNodeValue($ele: HTMLElement, key: string, value: any) {
1393
+ Reflect.set($ele, key, value);
1394
+ },
1395
+ /**
1396
+ * 获取option元素上设置的属性
1397
+ * @param $ele
1398
+ * @param value
1399
+ * @param key
1400
+ */
1401
+ getNodeValue($ele: HTMLElement, key: string) {
1402
+ return Reflect.get($ele, key);
1403
+ },
1404
+ /**
1405
+ * 禁用选项
1406
+ */
1407
+ disable() {
1408
+ this.$ele.select.setAttribute("disabled", "true");
1409
+ popsDOMUtils.addClassName(this.$ele.panelSelect, "pops-panel-select-disable");
1410
+ popsDOMUtils.addClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
1411
+ },
1412
+ /**
1413
+ * 取消禁用
1414
+ */
1415
+ notDisable() {
1416
+ this.$ele.select.removeAttribute("disabled");
1417
+ popsDOMUtils.removeClassName(this.$ele.panelSelect, "pops-panel-select-disable");
1418
+ popsDOMUtils.removeClassName(this.$ele.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
1419
+ },
1420
+ /**
1421
+ * 判断是否禁用
1422
+ */
1423
+ isDisabled() {
1424
+ return (
1425
+ this.$ele.select.hasAttribute("disabled") ||
1426
+ popsDOMUtils.containsClassName(this.$ele.panelSelect, "pops-panel-select-disable")
1427
+ );
1428
+ },
1429
+ /**
1430
+ * 初始化选项
1431
+ */
1432
+ initOption() {
1433
+ formConfig.data.forEach((dataItem) => {
1434
+ // 初始化默认选中
1435
+ const optionElement = document.createElement("option");
1436
+ this.setNodeValue(optionElement, this.$eleKey.value, dataItem.value);
1437
+ this.setNodeValue(optionElement, this.$eleKey.disable, dataItem.disable);
1438
+ this.setNodeValue(optionElement, this.$eleKey.forms, dataItem.forms);
1439
+ if (dataItem.value === this.$data.defaultValue) {
1440
+ this.setOptionSelected(optionElement);
1441
+ }
1442
+ optionElement.innerText = dataItem.text;
1443
+ this.$ele.select.appendChild(optionElement);
1444
+ });
1445
+ },
1446
+ /**
1447
+ * 设置选项选中
1448
+ */
1449
+ setOptionSelected($option: HTMLOptionElement) {
1450
+ $option.setAttribute("selected", "true");
1451
+ },
1452
+ /** 检测所有option并设置禁用状态 */
1453
+ setSelectOptionsDisableStatus() {
1454
+ if (this.$ele.select.options && this.$ele.select.options.length) {
1455
+ Array.from(this.$ele.select.options).forEach((optionItem) => {
1456
+ this.setOptionDisableStatus(optionItem);
1457
+ });
1458
+ }
1459
+ },
1460
+ /** 设置禁用状态 */
1461
+ setOptionDisableStatus(optionElement: HTMLOptionElement) {
1462
+ let disable = false;
1463
+ const optionDisableAttr = this.getNodeValue(optionElement, this.$eleKey.disable);
1464
+ if (optionDisableAttr === "function") {
1465
+ const value = this.getNodeValue(optionElement, this.$eleKey.value);
1466
+ disable = Boolean(optionDisableAttr(value));
1467
+ }
1468
+ if (disable) {
1469
+ optionElement.setAttribute("disabled", "true");
1470
+ } else {
1471
+ optionElement.removeAttribute("disabled");
1472
+ }
1473
+ },
1474
+ /** 获取option上的信息 */
1475
+ getSelectOptionInfo($option: HTMLOptionElement) {
1476
+ const optionValue = this.getNodeValue($option, this.$eleKey.value);
1477
+ const optionText = $option.innerText || $option.textContent!;
1478
+ const optionForms = this.getNodeValue($option, this.$eleKey.forms) as (typeof formConfig.data)[0]["forms"];
1479
+ return {
1480
+ value: optionValue,
1481
+ text: optionText,
1482
+ forms: optionForms,
1483
+ $option: $option,
1484
+ };
1485
+ },
1486
+ /**
1487
+ * 监听选择内容改变
1488
+ */
1489
+ setChangeEvent() {
1490
+ popsDOMUtils.on<PointerEvent | TouchEvent>(this.$ele.select, "change", void 0, (event) => {
1491
+ const $isSelectedElement = this.$ele.select[this.$ele.select.selectedIndex] as HTMLOptionElement;
1492
+ const selectInfo = this.getSelectOptionInfo($isSelectedElement);
1493
+ this.setSelectOptionsDisableStatus();
1494
+ if (typeof formConfig.callback === "function") {
1495
+ formConfig.callback(event, selectInfo.value, selectInfo.text);
1496
+ }
1497
+ const forms = typeof selectInfo.forms === "function" ? selectInfo.forms() : selectInfo.forms;
1498
+ if (Array.isArray(forms)) {
1499
+ /* 如果成功创建,加入到中间容器中 */
1500
+ const childUListClassName = "pops-panel-select-child-forms";
1501
+ // 移除旧的元素
1502
+ while ($li.nextElementSibling) {
1503
+ if ($li.nextElementSibling.classList.contains(childUListClassName)) {
1504
+ $li.nextElementSibling.remove();
1505
+ } else {
1506
+ break;
1507
+ }
1508
+ }
1509
+ const $childUList = document.createElement("ul");
1510
+ $childUList.className = childUListClassName;
1511
+ popsDOMUtils.after($li, $childUList);
1512
+ that.uListContainerAddItem(formConfig, {
1513
+ ulElement: $childUList,
1514
+ });
1515
+ }
1516
+ });
1517
+ },
1518
+ /**
1519
+ * 监听点击事件
1520
+ */
1521
+ setClickEvent() {
1522
+ popsDOMUtils.on(this.$ele.select, "click", void 0, (event) => {
1523
+ this.setSelectOptionsDisableStatus();
1524
+ if (typeof formConfig.clickCallBack === "function") {
1525
+ formConfig.clickCallBack(event, this.$ele.select);
1526
+ }
1527
+ });
1528
+ },
1529
+ };
1530
+
1531
+ PopsPanelSelect.init();
1532
+ Reflect.set($li, "data-select", PopsPanelSelect);
1533
+ return $li;
1534
+ },
1535
+ /**
1536
+ * type ==> select-multiple
1537
+ * 获取中间容器的元素<li>
1538
+ * @param formConfig
1539
+ */
1540
+ createSectionContainerItem_select_multiple_new(formConfig: PopsPanelSelectMultipleDetails<any>) {
1541
+ const $li = document.createElement("li");
1542
+ Reflect.set($li, "__formConfig__", formConfig);
1543
+ this.setElementClassName($li, formConfig.className);
1544
+ this.setElementAttributes($li, formConfig.attributes);
1545
+ this.setElementProps($li, formConfig.props);
1546
+ /* 左边底部的描述的文字 */
1547
+ let leftDescriptionText = "";
1548
+ if (formConfig.description) {
1549
+ leftDescriptionText = /*html*/ `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
1550
+ }
1551
+ PopsSafeUtils.setSafeHTML(
1552
+ $li,
1553
+ /*html*/ `
1554
+ <div class="pops-panel-item-left-text">
1555
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
1556
+ <div class="pops-panel-select-multiple">
1557
+ <div class="el-select__wrapper">
1558
+ <div class="el-select__selection">
1559
+ <!-- 这个是用于手动输入的,这里暂不适配 -->
1560
+ <div class="el-select__selected-item el-select__input-wrapper">
1561
+
1562
+ </div>
1563
+ <!-- 这个是placeholder -->
1564
+ <div class="el-select__selected-item el-select__placeholder">
1565
+ </div>
1566
+ </div>
1567
+ <!-- 下拉箭头 -->
1568
+ <div class="el-select__suffix">
1569
+ <i class="el-icon el-select__caret el-select__icon">
1570
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
1571
+ <path fill="currentColor" d="M831.872 340.864 512 652.672 192.128 340.864a30.592 30.592 0 0 0-42.752 0 29.12 29.12 0 0 0 0 41.6L489.664 714.24a32 32 0 0 0 44.672 0l340.288-331.712a29.12 29.12 0 0 0 0-41.728 30.592 30.592 0 0 0-42.752 0z"></path>
1572
+ </svg>
1573
+ </i>
1574
+ </div>
1575
+ </div>
1576
+ </div>
1577
+ `
1578
+ );
1579
+ const PopsPanelSelectMultiple = {
1580
+ [Symbol.toStringTag]: "PopsPanelSelectMultiple",
1581
+ $el: {
1582
+ /** 左侧文本容器 */
1583
+ itemLeftTextContainer: $li.querySelector<HTMLElement>(".pops-panel-item-left-text"),
1584
+ /** 容器 */
1585
+ $container: void 0 as any as HTMLElement,
1586
+ /** 包括的容器 */
1587
+ $wrapper: void 0 as any as HTMLElement,
1588
+ /** 内容区域 */
1589
+ $section: void 0 as any as HTMLElement,
1590
+ /** 手动输入 */
1591
+ $selectedInputWrapper: void 0 as any as HTMLElement,
1592
+ /** 灰色提示语 */
1593
+ $selectedPlaceHolderWrapper: void 0 as any as HTMLElement,
1594
+ /** 下拉箭头区域 */
1595
+ $suffix: void 0 as any as HTMLElement,
1596
+ /** 下拉箭头图标 */
1597
+ $suffixIcon: void 0 as any as HTMLElement,
1598
+ /** 下拉列表弹窗的下拉列表容器 */
1599
+ $selectContainer: void 0 as any as HTMLElement | null,
1600
+ },
1601
+ $data: {
1602
+ /** 默认值 */
1603
+ defaultValue: formConfig.getValue(),
1604
+ selectInfo: [] as any as PopsPanelSelectMultipleDataOption<any>[],
1605
+ },
1606
+ /** 初始化 */
1607
+ init() {
1608
+ this.initDefault();
1609
+ this.inintEl();
1610
+ this.initPlaceHolder();
1611
+ this.initTagElement();
1612
+ this.setSelectContainerClickEvent();
1613
+
1614
+ const disabled = typeof formConfig.disabled === "function" ? formConfig.disabled() : formConfig.disabled;
1615
+ if (disabled) {
1616
+ this.disable();
1617
+ }
1618
+ },
1619
+ /** 初始化默认值 */
1620
+ initDefault() {
1621
+ formConfig.data.forEach((dataItem) => {
1622
+ if (this.$data.defaultValue.includes(dataItem.value)) {
1623
+ // 初始化选中的配置
1624
+ this.$data.selectInfo.push({
1625
+ text: dataItem.text,
1626
+ value: dataItem.value,
1627
+ isHTML: Boolean(dataItem.isHTML),
1628
+ disable: dataItem.disable?.bind(dataItem),
1629
+ });
1630
+ }
1631
+ });
1632
+ },
1633
+ /** 初始化$el变量 */
1634
+ inintEl() {
1635
+ this.$el.$container = $li.querySelector<HTMLElement>(".pops-panel-select-multiple")!;
1636
+ this.$el.$wrapper = $li.querySelector<HTMLElement>(".el-select__wrapper")!;
1637
+ this.$el.$section = $li.querySelector<HTMLElement>(".el-select__selection")!;
1638
+ this.$el.$selectedInputWrapper = $li.querySelector<HTMLElement>(
1639
+ ".el-select__selected-item.el-select__input-wrapper"
1640
+ )!;
1641
+ this.$el.$selectedPlaceHolderWrapper = $li.querySelector<HTMLElement>(
1642
+ ".el-select__selected-item.el-select__placeholder"
1643
+ )!;
1644
+ this.$el.$suffix = $li.querySelector<HTMLElement>(".el-select__suffix")!;
1645
+ this.$el.$suffixIcon = $li.querySelector<HTMLElement>(".el-select__suffix .el-icon")!;
1646
+
1647
+ // 先把手动输入框隐藏
1648
+ this.hideInputWrapper();
1649
+ },
1650
+ /** 初始化提示文字 */
1651
+ initPlaceHolder() {
1652
+ let placeholder = "";
1653
+ if (typeof formConfig.placeholder === "string") {
1654
+ placeholder = formConfig.placeholder;
1655
+ } else if (typeof formConfig.placeholder === "function") {
1656
+ const placeholderResult = formConfig.placeholder();
1657
+ if (typeof placeholderResult === "string") {
1658
+ placeholder = placeholderResult;
1659
+ }
1660
+ }
1661
+ const $placeholder = popsDOMUtils.createElement("span", {
1662
+ innerText: placeholder,
1663
+ });
1664
+ this.$el.$selectedPlaceHolderWrapper.appendChild($placeholder);
1665
+ },
1666
+ /** 初始化tag元素 */
1667
+ initTagElement() {
1668
+ // 遍历数据,寻找对应的值
1669
+ formConfig.data.forEach((dataItem) => {
1670
+ const findValue = this.$data.selectInfo.find((item) => item.value === dataItem.value);
1671
+ if (findValue) {
1672
+ // 存在对应的值
1673
+ const selectedInfo = this.createSelectedTagItem(dataItem);
1674
+ this.addSelectedTagItem(selectedInfo.$tag);
1675
+ this.setSelectedItemCloseIconClickEvent({
1676
+ $tag: selectedInfo.$tag,
1677
+ $closeIcon: selectedInfo.$closeIcon,
1678
+ value: dataItem.value,
1679
+ text: dataItem.text,
1680
+ });
1681
+ }
1682
+ });
1683
+ this.checkTagEmpty();
1684
+ },
1685
+ /**
1686
+ * 生成一个tag项
1687
+ * @param data 配置
1688
+ */
1689
+ createSelectedTagItem(data: PopsPanelSelectMultipleDataOption<any>) {
1690
+ const $selectedItem = popsDOMUtils.createElement("div", {
1691
+ className: "el-select__selected-item el-select__choose_tag",
1692
+ innerHTML: /*html*/ `
1693
+ <span class="el-tag is-closable el-tag--info el-tag--default el-tag--light">
1694
+ <span class="el-tag__content">
1695
+ <span class="el-select__tags-text"></span>
1696
+ </span>
1697
+ <!-- 关闭tag的图标 -->
1698
+ <i class="el-icon el-tag__close">
1699
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
1700
+ <path fill="currentColor" d="M764.288 214.592 512 466.88 259.712 214.592a31.936 31.936 0 0 0-45.12 45.12L466.752 512 214.528 764.224a31.936 31.936 0 1 0 45.12 45.184L512 557.184l252.288 252.288a31.936 31.936 0 0 0 45.12-45.12L557.12 512.064l252.288-252.352a31.936 31.936 0 1 0-45.12-45.184z"></path>
1701
+ </svg>
1702
+ </i>
1703
+ </span>
1704
+ `,
1705
+ });
1706
+ /** 标签 */
1707
+ const $tagText = $selectedItem.querySelector<HTMLSpanElement>(".el-select__tags-text")!;
1708
+ /** 关闭图标 */
1709
+ const $closeIcon = $selectedItem.querySelector<HTMLElement>(".el-icon.el-tag__close")!;
1710
+ const text = typeof data.text === "function" ? data.text(data, this.$data.selectInfo) : data.text;
1711
+ if (data.isHTML) {
1712
+ PopsSafeUtils.setSafeHTML($tagText, text);
1713
+ } else {
1714
+ $tagText.innerText = text;
1715
+ }
1716
+
1717
+ return {
1718
+ $tag: $selectedItem,
1719
+ $tagText: $tagText,
1720
+ $closeIcon: $closeIcon,
1721
+ };
1722
+ },
1723
+ /**
1724
+ * 添加选中项的tag元素
1725
+ * @param $tag 添加的元素
1726
+ */
1727
+ addSelectedTagItem($tag: HTMLElement) {
1728
+ // 往前添加
1729
+ // 去除前面的空白
1730
+ this.setSectionIsNear();
1731
+ if (this.$el.$section.contains(this.$el.$selectedInputWrapper)) {
1732
+ const $prev = this.$el.$selectedInputWrapper.previousElementSibling;
1733
+ if ($prev) {
1734
+ // 存在前一个元素,添加到前面的元素的后面
1735
+ popsDOMUtils.after($prev, $tag);
1736
+ } else {
1737
+ // 不存在前一个元素,添加到最前面
1738
+ popsDOMUtils.before(this.$el.$selectedInputWrapper, $tag);
1739
+ }
1740
+ } else if (this.$el.$section.contains(this.$el.$selectedPlaceHolderWrapper)) {
1741
+ const $prev = this.$el.$selectedPlaceHolderWrapper.previousElementSibling;
1742
+ if ($prev) {
1743
+ // 存在前一个元素,添加到前面的元素的后面
1744
+ popsDOMUtils.after($prev, $tag);
1745
+ } else {
1746
+ // 不存在前一个元素,添加到最前面
1747
+ popsDOMUtils.before(this.$el.$selectedPlaceHolderWrapper, $tag);
1748
+ }
1749
+ } else {
1750
+ this.$el.$section.appendChild($tag);
1751
+ }
1752
+ // 隐藏元素
1753
+ this.hideInputWrapper();
1754
+ this.hidePlaceHolderWrapper();
1755
+ },
1756
+ /** 更新tag信息 */
1757
+ updateSelectTagItem() {
1758
+ this.$el.$section.querySelectorAll<HTMLElement>(".el-select__choose_tag").forEach(($ele) => {
1759
+ $ele.remove();
1760
+ });
1761
+ this.initTagElement();
1762
+ },
1763
+ /**
1764
+ * 选中的值改变的回调
1765
+ * @param selectedDataList 当前的选中信息
1766
+ */
1767
+ selectValueChangeCallBack(selectedDataList?: PopsPanelSelectMultipleDataOption<any>[]) {
1768
+ // 动态更新禁用状态
1769
+ this.updateSelectItem();
1770
+ if (typeof formConfig.callback === "function") {
1771
+ formConfig.callback(selectedDataList || this.$data.selectInfo);
1772
+ }
1773
+ },
1774
+ /**
1775
+ * 更新选项弹窗内的所有选项元素的状态
1776
+ *
1777
+ * + 更新禁用状态
1778
+ * + 更新选中状态
1779
+ */
1780
+ updateSelectItem() {
1781
+ this.getAllSelectItemInfo(false).forEach(($selectInfo) => {
1782
+ const { data, $select } = $selectInfo;
1783
+ // 更新文字
1784
+ this.setSelectItemText(data, $selectInfo.$select);
1785
+ // 更新禁用状态
1786
+ if (typeof data.disable === "function" && data.disable(data.value, this.$data.selectInfo)) {
1787
+ // 禁用
1788
+ this.setSelectItemDisabled($select);
1789
+ // 移除选中信息
1790
+ this.removeSelectedInfo(data, false);
1791
+ // 移除选中状态
1792
+ this.removeSelectItemSelected($select);
1793
+ } else {
1794
+ // 取消禁用
1795
+ this.removeSelectItemDisabled($select);
1796
+ }
1797
+ // 更新选中状态
1798
+ const findValue = this.$data.selectInfo.find((it) => it.value === data.value);
1799
+ if (findValue) {
1800
+ this.setSelectItemSelected($select);
1801
+ } else {
1802
+ this.removeSelectItemSelected($select);
1803
+ }
1804
+ });
1805
+ },
1806
+ /**
1807
+ * 设置选项元素选中
1808
+ * @param $select 选项元素
1809
+ */
1810
+ setSelectItemSelected($select: HTMLElement) {
1811
+ if (this.isSelectItemSelected($select)) return;
1812
+ $select.classList.add("select-item-is-selected");
1813
+ },
1814
+ /**
1815
+ * 移除选项元素选中
1816
+ * @param $select 选项元素
1817
+ */
1818
+ removeSelectItemSelected($select: HTMLElement) {
1819
+ $select.classList.remove("select-item-is-selected");
1820
+ },
1821
+ /**
1822
+ * 判断选项元素是否选中
1823
+ * @param $select
1824
+ */
1825
+ isSelectItemSelected($select: HTMLElement): boolean {
1826
+ return $select.classList.contains("select-item-is-selected");
1827
+ },
1828
+ /**
1829
+ * 添加选中信息
1830
+ * @param dataList 选择项列表的数据
1831
+ * @param $select 选项元素
1832
+ */
1833
+ addSelectedItemInfo(dataList: PopsPanelSelectMultipleDataOption<any>[], $select: HTMLElement) {
1834
+ const info = this.getSelectedItemInfo($select);
1835
+ const findValue = dataList.find((item) => item.value === info.value);
1836
+ if (!findValue) {
1837
+ dataList.push({
1838
+ value: info.value,
1839
+ text: info.text,
1840
+ isHTML: Boolean(info.isHTML),
1841
+ disable: info.disable?.bind(info),
1842
+ });
1843
+ }
1844
+ this.selectValueChangeCallBack(dataList);
1845
+ },
1846
+ /**
1847
+ * 获取选中的项的信息
1848
+ * @param $select 选项元素
1849
+ */
1850
+ getSelectedItemInfo($select: HTMLElement) {
1851
+ return Reflect.get($select, "data-info") as PopsPanelSelectMultipleDataOption<any>;
1852
+ },
1853
+ /**
1854
+ * 移除选中信息
1855
+ * @param dataList 选择项的数据
1856
+ * @param $select 选项元素
1857
+ */
1858
+ removeSelectedItemInfo(dataList: PopsPanelSelectMultipleDataOption<any>[], $select: HTMLElement) {
1859
+ const info = this.getSelectedItemInfo($select);
1860
+ const findIndex = dataList.findIndex((item) => item.value === info.value);
1861
+ if (findIndex !== -1) {
1862
+ dataList.splice(findIndex, 1);
1863
+ }
1864
+ this.selectValueChangeCallBack(dataList);
1865
+ },
1866
+ /**
1867
+ * 获取所有选项的信息
1868
+ * @param [onlySelected=true] 是否仅获取选中的项的信息
1869
+ * + true (默认)仅获取选中项的信息
1870
+ * + false 获取所有选择项的信息
1871
+ */
1872
+ getAllSelectItemInfo(onlySelected: boolean = true) {
1873
+ return Array.from(this.$el.$selectContainer?.querySelectorAll<HTMLElement>(".select-item") ?? [])
1874
+ .map(($select) => {
1875
+ const data = this.getSelectedItemInfo($select);
1876
+ const result = {
1877
+ /** 选项信息数据 */
1878
+ data: data,
1879
+ /** 选项元素 */
1880
+ $select: $select,
1881
+ };
1882
+ if (onlySelected) {
1883
+ // 仅选中
1884
+ const isSelected = this.isSelectItemSelected($select);
1885
+ if (isSelected) {
1886
+ return result;
1887
+ }
1888
+ return;
1889
+ } else {
1890
+ return result;
1891
+ }
1892
+ })
1893
+ .filter((item) => {
1894
+ return item != null;
1895
+ });
1896
+ },
1897
+ /**
1898
+ * 创建一个选择项元素
1899
+ * @param data 选择项的数据
1900
+ */
1901
+ createSelectItemElement(data: PopsPanelSelectMultipleDataOption<any>) {
1902
+ const $select = popsDOMUtils.createElement("li", {
1903
+ className: "select-item",
1904
+ innerHTML: /*html*/ `
1905
+ <span class="select-item-text"></span>
1906
+ `,
1907
+ });
1908
+ this.setSelectItemText(data, $select);
1909
+ Reflect.set($select, "data-info", data);
1910
+ return $select;
1911
+ },
1912
+ /**
1913
+ * 设置选择项的文字
1914
+ * @param data 选择项的数据
1915
+ * @param $select 选择项元素
1916
+ */
1917
+ setSelectItemText(data: PopsPanelSelectMultipleDataOption<any>, $select: HTMLElement) {
1918
+ const text = typeof data.text === "function" ? data.text(data.value, this.$data.selectInfo) : data.text;
1919
+ const $selectSpan = $select.querySelector<HTMLElement>(".select-item-text")!;
1920
+ if (data.isHTML) {
1921
+ PopsSafeUtils.setSafeHTML($selectSpan, text);
1922
+ } else {
1923
+ $selectSpan.innerText = text;
1924
+ }
1925
+ },
1926
+ /**
1927
+ * 设置选择项的禁用状态
1928
+ * @param $select 选择项元素
1929
+ */
1930
+ setSelectItemDisabled($select: HTMLElement) {
1931
+ $select.setAttribute("aria-disabled", "true");
1932
+ $select.setAttribute("disabled", "true");
1933
+ },
1934
+ /**
1935
+ * 移除选择项的禁用状态
1936
+ * @param $select 选择项元素
1937
+ */
1938
+ removeSelectItemDisabled($select: HTMLElement) {
1939
+ $select.removeAttribute("aria-disabled");
1940
+ $select.removeAttribute("disabled");
1941
+ },
1942
+ /**
1943
+ * 判断选择项是否禁用
1944
+ * @param $select 选择项元素
1945
+ */
1946
+ isSelectItemDisabled($select: HTMLElement) {
1947
+ return $select.hasAttribute("disabled") || $select.ariaDisabled;
1948
+ },
1949
+ /**
1950
+ * 设置选择项的点击事件
1951
+ * @param dataList 选中的信息列表
1952
+ * @param $select 选择项元素
1953
+ */
1954
+ setSelectElementClickEvent(dataList: PopsPanelSelectMultipleDataOption<any>[], $select: HTMLElement) {
1955
+ popsDOMUtils.on<PointerEvent | MouseEvent>($select, "click", (event) => {
1956
+ popsDOMUtils.preventEvent(event);
1957
+ if (this.isSelectItemDisabled($select)) {
1958
+ return;
1959
+ }
1960
+ if (typeof formConfig.clickCallBack === "function") {
1961
+ const allSelectedInfo = this.getAllSelectItemInfo().map((it) => it.data);
1962
+ const clickResult = formConfig.clickCallBack(event, allSelectedInfo);
1963
+ if (typeof clickResult === "boolean" && !clickResult) {
1964
+ return;
1965
+ }
1966
+ }
1967
+ // 修改选中状态
1968
+ if (this.isSelectItemSelected($select)) {
1969
+ this.removeSelectItemSelected($select);
1970
+ this.removeSelectedItemInfo(dataList, $select);
1971
+ } else {
1972
+ this.setSelectItemSelected($select);
1973
+ this.addSelectedItemInfo(dataList, $select);
1974
+ }
1975
+ });
1976
+ },
1977
+ /**
1978
+ * 设置下拉列表的点击事件
1979
+ */
1980
+ setSelectContainerClickEvent() {
1981
+ const that = this;
1982
+ popsDOMUtils.on(this.$el.$container, "click", () => {
1983
+ if (this.isDisabled()) {
1984
+ return;
1985
+ }
1986
+ /** 弹窗的选中的值 */
1987
+ const selectedInfo = that.$data.selectInfo;
1988
+ const { style, ...userConfirmDetails } = formConfig.selectConfirmDialogDetails || {};
1989
+ const confirmDetails = popsUtils.assign(
1990
+ <PopsAlertDetails>{
1991
+ title: {
1992
+ text: "请勾选需要选择的选项",
1993
+ position: "center",
1994
+ },
1995
+ content: {
1996
+ text: /*html*/ `
1997
+ <ul class="select-container"></ul>
1998
+ `,
1999
+ html: true,
2000
+ },
2001
+ btn: {
2002
+ ok: {
2003
+ enable: false,
2004
+ },
2005
+ close: {
2006
+ enable: true,
2007
+ callback(details) {
2008
+ that.$data.selectInfo = [...selectedInfo];
2009
+ that.updateSelectTagItem();
2010
+ that.$el.$selectContainer = null;
2011
+ details.close();
2012
+ },
2013
+ },
2014
+ },
2015
+ mask: {
2016
+ enable: true,
2017
+ clickCallBack(originalRun) {
2018
+ originalRun();
2019
+ that.$data.selectInfo = [...selectedInfo];
2020
+ that.updateSelectTagItem();
2021
+ that.$el.$selectContainer = null;
2022
+ },
2023
+ clickEvent: {
2024
+ toClose: true,
2025
+ },
2026
+ },
2027
+ drag: true,
2028
+ dragLimit: true,
2029
+ width: "300px",
2030
+ height: "300px",
2031
+ style: /*css*/ `
2032
+ .select-container{
2033
+ --el-font-size-base: 14px;
2034
+ --el-text-color-regular: #606266;
2035
+ --el-color-primary: #409eff;
2036
+ --el-fill-color-light: #f5f7fa;
2037
+ --el-disable-color: #a8abb2;
2038
+ }
2039
+ .select-item{
2040
+ cursor: pointer;
2041
+ font-size: var(--el-font-size-base);
2042
+ padding: 0 32px 0 20px;
2043
+ position: relative;
2044
+ white-space: nowrap;
2045
+ overflow: hidden;
2046
+ text-overflow: ellipsis;
2047
+ color: var(--el-text-color-regular);
2048
+ height: 34px;
2049
+ line-height: 34px;
2050
+ box-sizing: border-box;
2051
+ }
2052
+ .select-item[aria-disabled],
2053
+ .select-item[disabled]{
2054
+ cursor: not-allowed;
2055
+ color: var(--el-disable-color);
2056
+ background: unset;
2057
+ }
2058
+ .select-item:hover{
2059
+ background-color: var(--el-fill-color-light);
2060
+ }
2061
+ .select-item.select-item-is-selected{
2062
+ color: var(--el-color-primary);
2063
+ font-weight: 700;
2064
+ }
2065
+ .select-item.select-item-is-selected::after{
2066
+ content: "";
2067
+ position: absolute;
2068
+ top: 50%;
2069
+ right: 20px;
2070
+ border-top: none;
2071
+ border-right: none;
2072
+ background-repeat: no-repeat;
2073
+ background-position: center;
2074
+ background-color: var(--el-color-primary);
2075
+ mask: url("data:image/svg+xml;utf8,%3Csvg class='icon' width='200' height='200' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='currentColor' d='M406.656 706.944L195.84 496.256a32 32 0 10-45.248 45.248l256 256 512-512a32 32 0 00-45.248-45.248L406.592 706.944z'%3E%3C/path%3E%3C/svg%3E") no-repeat;
2076
+ mask-size: 100% 100%;
2077
+ -webkit-mask: url("data:image/svg+xml;utf8,%3Csvg class='icon' width='200' height='200' viewBox='0 0 1024 1024' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='currentColor' d='M406.656 706.944L195.84 496.256a32 32 0 10-45.248 45.248l256 256 512-512a32 32 0 00-45.248-45.248L406.592 706.944z'%3E%3C/path%3E%3C/svg%3E") no-repeat;
2078
+ -webkit-mask-size: 100% 100%;
2079
+ transform: translateY(-50%);
2080
+ width: 12px;
2081
+ height: 12px;
2082
+ }
2083
+
2084
+
2085
+ @media (prefers-color-scheme: dark) {
2086
+ .select-container{
2087
+ --el-text-color-regular: #f2f2f2;
2088
+ --el-disable-color: #8D9095;
2089
+ --el-fill-color-light: #262727;
2090
+ }
2091
+ }
2092
+
2093
+ ${style || ""}
2094
+ `,
2095
+ },
2096
+ userConfirmDetails
2097
+ );
2098
+ const $dialog = PopsAlert.init(confirmDetails);
2099
+ const $selectContainer = $dialog.$shadowRoot.querySelector<HTMLUListElement>(".select-container")!;
2100
+ this.$el.$selectContainer = $selectContainer;
2101
+ // 配置选项元素
2102
+ formConfig.data.forEach((item) => {
2103
+ const $select = this.createSelectItemElement(item);
2104
+ // 添加到confirm中
2105
+ $selectContainer.appendChild($select);
2106
+ // 设置每一项的点击事件
2107
+ this.setSelectElementClickEvent(selectedInfo, $select);
2108
+ });
2109
+ // 动态更新禁用状态
2110
+ this.updateSelectItem();
2111
+ });
2112
+ },
2113
+ /**
2114
+ * 设置关闭图标的点击事件
2115
+ * @param data 选中的信息
2116
+ */
2117
+ setSelectedItemCloseIconClickEvent(data: {
2118
+ /** 关闭图标的元素 */
2119
+ $closeIcon: HTMLElement;
2120
+ /** tag元素 */
2121
+ $tag: HTMLElement;
2122
+ /** 值 */
2123
+ value: PopsPanelSelectMultipleDataOption<any>["value"];
2124
+ /** 显示的文字 */
2125
+ text: PopsPanelSelectMultipleDataOption<any>["text"];
2126
+ }) {
2127
+ popsDOMUtils.on<PointerEvent | MouseEvent>(
2128
+ data.$closeIcon,
2129
+ "click",
2130
+ (event) => {
2131
+ popsDOMUtils.preventEvent(event);
2132
+ if (this.isDisabled()) {
2133
+ return;
2134
+ }
2135
+ if (typeof formConfig.closeIconClickCallBack === "function") {
2136
+ const result = formConfig.closeIconClickCallBack(event, {
2137
+ $tag: data.$tag,
2138
+ $closeIcon: data.$closeIcon,
2139
+ value: data.value,
2140
+ text: typeof data.text === "function" ? data.text.bind(data) : data.text,
2141
+ });
2142
+ if (typeof result === "boolean" && !result) {
2143
+ return;
2144
+ }
2145
+ }
2146
+ this.removeSelectedTagItem(data.$tag);
2147
+ this.removeSelectedInfo({
2148
+ value: data.value,
2149
+ text: data.text,
2150
+ });
2151
+ },
2152
+ {
2153
+ capture: true,
2154
+ }
2155
+ );
2156
+ },
2157
+ /**
2158
+ * 检测tag是否为空,为空显示placeholder
2159
+ */
2160
+ checkTagEmpty() {
2161
+ if (!this.$el.$section.querySelectorAll(".el-select__choose_tag").length) {
2162
+ // 没有tag了
2163
+ // this.showInputWrapper();
2164
+ this.showPlaceHolderWrapper();
2165
+ this.removeSectionIsNear();
2166
+ }
2167
+ },
2168
+ /**
2169
+ * 移除选中项元素
2170
+ */
2171
+ removeSelectedTagItem($tag: HTMLElement) {
2172
+ $tag.remove();
2173
+ this.checkTagEmpty();
2174
+ },
2175
+ /**
2176
+ * 从保存的已选中的信息列表中移除目标信息
2177
+ * @param data 需要移除的信息
2178
+ * @param [triggerValueChangeCallBack=true] 是否触发值改变的回调
2179
+ * + true (默认)触发值改变的回调
2180
+ * + false 不触发值改变的回调
2181
+ */
2182
+ removeSelectedInfo(data: PopsPanelSelectMultipleDataOption<any>, triggerValueChangeCallBack: boolean = true) {
2183
+ for (let index = 0; index < this.$data.selectInfo.length; index++) {
2184
+ const selectInfo = this.$data.selectInfo[index];
2185
+ if (selectInfo.value === data.value) {
2186
+ this.$data.selectInfo.splice(index, 1);
2187
+ break;
2188
+ }
2189
+ }
2190
+ triggerValueChangeCallBack && this.selectValueChangeCallBack();
2191
+ },
2192
+ /** 显示输入框 */
2193
+ showInputWrapper() {
2194
+ popsDOMUtils.cssShow(this.$el.$selectedInputWrapper);
2195
+ },
2196
+ /** 隐藏输入框 */
2197
+ hideInputWrapper() {
2198
+ popsDOMUtils.cssHide(this.$el.$selectedInputWrapper, true);
2199
+ },
2200
+ /** 显示palceholder */
2201
+ showPlaceHolderWrapper() {
2202
+ popsDOMUtils.cssShow(this.$el.$selectedPlaceHolderWrapper);
2203
+ },
2204
+ /** 隐藏palceholder */
2205
+ hidePlaceHolderWrapper() {
2206
+ popsDOMUtils.cssHide(this.$el.$selectedPlaceHolderWrapper, true);
2207
+ },
2208
+ /** 设置隐藏section的前面的空白 */
2209
+ setSectionIsNear() {
2210
+ this.$el.$section.classList.add("is-near");
2211
+ },
2212
+ /** 取消设置隐藏section的前面的空白 */
2213
+ removeSectionIsNear() {
2214
+ this.$el.$section.classList.remove("is-near");
2215
+ },
2216
+ /**
2217
+ * 禁用标签
2218
+ */
2219
+ disable() {
2220
+ popsDOMUtils.addClassName(this.$el.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
2221
+ popsDOMUtils.addClassName(this.$el.$container, "pops-panel-select-multiple-disable");
2222
+ },
2223
+ /**
2224
+ * 判断是否被禁用
2225
+ */
2226
+ isDisabled() {
2227
+ return popsDOMUtils.containsClassName(this.$el.$container, "pops-panel-select-multiple-disable");
2228
+ },
2229
+ /**
2230
+ * 取消禁用标签
2231
+ */
2232
+ cancleDisable() {
2233
+ popsDOMUtils.removeClassName(this.$el.itemLeftTextContainer, PopsCommonCSSClassName.textIsDisabled);
2234
+ popsDOMUtils.removeClassName(this.$el.$container, "pops-panel-select-multiple-disable");
2235
+ },
2236
+ };
2237
+
2238
+ PopsPanelSelectMultiple.init();
2239
+ Reflect.set($li, "data-select-multiple", PopsPanelSelectMultiple);
2240
+ return $li;
2241
+ },
2242
+ /**
2243
+ * type ==> button
2244
+ * 获取中间容器的元素<li>
2245
+ * @param formConfig
2246
+ */
2247
+ createSectionContainerItem_button(formConfig: PopsPanelButtonDetails) {
2248
+ const $li = document.createElement("li");
2249
+ Reflect.set($li, "__formConfig__", formConfig);
2250
+ this.setElementClassName($li, formConfig.className);
2251
+ this.setElementAttributes($li, formConfig.attributes);
2252
+ this.setElementProps($li, formConfig.props);
2253
+
2254
+ /* 左边底部的描述的文字 */
2255
+ let leftDescriptionText = "";
2256
+ if (formConfig.description) {
2257
+ leftDescriptionText = /*html*/ `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
2258
+ }
2259
+ PopsSafeUtils.setSafeHTML(
2260
+ $li,
2261
+ /*html*/ `
2262
+ <div class="pops-panel-item-left-text">
2263
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
2264
+ <div class="pops-panel-button">
2265
+ <button class="pops-panel-button_inner" type="button">
2266
+ <i class="pops-bottom-icon"></i>
2267
+ <span class="pops-panel-button-text"></span>
2268
+ </button>
2269
+ </div>
2270
+ `
2271
+ );
2272
+
2273
+ const PopsPanelButton = {
2274
+ [Symbol.toStringTag]: "PopsPanelButton",
2275
+ $ele: {
2276
+ panelButton: $li.querySelector<HTMLDivElement>(".pops-panel-button")!,
2277
+ button: $li.querySelector<HTMLDivElement>(".pops-panel-button .pops-panel-button_inner")!,
2278
+ icon: $li.querySelector<HTMLDivElement>(".pops-panel-button .pops-bottom-icon")!,
2279
+ spanText: $li.querySelector<HTMLDivElement>(".pops-panel-button .pops-panel-button-text")!,
2280
+ },
2281
+ $data: {},
2282
+ init() {
2283
+ this.$ele.panelButton.appendChild(this.$ele.button);
2284
+ this.initButton();
2285
+ this.setClickEvent();
2286
+ },
2287
+ initButton() {
2288
+ if (typeof formConfig.buttonIcon === "string" && formConfig.buttonIcon.trim() !== "") {
2289
+ /* 存在icon图标且不为空 */
2290
+ if (PopsIcon.hasIcon(formConfig.buttonIcon)) {
2291
+ this.setIconSVG(PopsIcon.getIcon(formConfig.buttonIcon)!);
2292
+ } else {
2293
+ this.setIconSVG(formConfig.buttonIcon);
2294
+ }
2295
+ this.showIcon();
2296
+ } else {
2297
+ this.hideIcon();
2298
+ }
2299
+ /* 按钮文字 */
2300
+ let buttonText = formConfig.buttonText;
2301
+ if (typeof formConfig.buttonText === "function") {
2302
+ buttonText = formConfig.buttonText();
2303
+ }
2304
+ this.setButtonType(formConfig.buttonType);
2305
+ if (formConfig.buttonIsRightIcon) {
2306
+ this.setIconRight();
2307
+ } else {
2308
+ this.setIconLeft();
2309
+ }
2310
+ if (formConfig.disable) {
2311
+ this.disable();
2312
+ }
2313
+ this.setButtonText(buttonText as string);
2314
+ this.setIconLoadingStatus(formConfig.buttonIconIsLoading);
2315
+ },
2316
+ disable() {
2317
+ this.$ele.button.setAttribute("disabled", "true");
2318
+ },
2319
+ notDisable() {
2320
+ this.$ele.button.removeAttribute("disabled");
2321
+ },
2322
+ /**
2323
+ * 隐藏icon图标
2324
+ */
2325
+ hideIcon() {
2326
+ this.$ele.panelButton.classList.add("pops-panel-button-no-icon");
2327
+ },
2328
+ /**
2329
+ * 显示icon图标
2330
+ */
2331
+ showIcon() {
2332
+ this.$ele.panelButton.classList.remove("pops-panel-button-no-icon");
2333
+ },
2334
+ /**
2335
+ * 设置icon图标的svg
2336
+ */
2337
+ setIconSVG(svgHTML: string) {
2338
+ PopsSafeUtils.setSafeHTML(this.$ele.icon, svgHTML);
2339
+ },
2340
+ /**
2341
+ * 设置icon图标是否旋转
2342
+ * @param status
2343
+ */
2344
+ setIconLoadingStatus(status: any) {
2345
+ this.$ele.icon.setAttribute("is-loading", Boolean(status).toString());
2346
+ },
2347
+ /**
2348
+ * 设置属性上是否存在icon图标
2349
+ */
2350
+ setHasIcon(value: any) {
2351
+ this.$ele.button.setAttribute("data-icon", Boolean(value).toString());
2352
+ },
2353
+ /**
2354
+ * 设置按钮类型
2355
+ * @param typeValue
2356
+ */
2357
+ setButtonType(typeValue: string) {
2358
+ this.$ele.button.setAttribute("data-type", typeValue);
2359
+ },
2360
+ /**
2361
+ * 添加按钮的图标在右边
2362
+ */
2363
+ setIconRight() {
2364
+ this.$ele.button.classList.add("pops-panel-button-right-icon");
2365
+ },
2366
+ /**
2367
+ * (默认)添加按钮的图标在左边
2368
+ */
2369
+ setIconLeft() {
2370
+ this.$ele.button.classList.remove("pops-panel-button-right-icon");
2371
+ },
2372
+ /**
2373
+ * 设置按钮文本
2374
+ * @param text
2375
+ */
2376
+ setButtonText(text: string) {
2377
+ PopsSafeUtils.setSafeHTML(this.$ele.spanText, text);
2378
+ },
2379
+ setClickEvent() {
2380
+ popsDOMUtils.on(this.$ele.button, "click", void 0, (event) => {
2381
+ if (typeof formConfig.callback === "function") {
2382
+ formConfig.callback(event);
2383
+ }
2384
+ });
2385
+ },
2386
+ };
2387
+ PopsPanelButton.init();
2388
+ Reflect.set($li, "data-button", PopsPanelButton);
2389
+ return $li;
2390
+ },
2391
+ /**
2392
+ * type ==> deepMenu
2393
+ * 获取深层容器的元素<li>
2394
+ * @param formConfig
2395
+ */
2396
+ createSectionContainerItem_deepMenu(formConfig: PopsPanelDeepMenuDetails) {
2397
+ const that = this;
2398
+ const $li = document.createElement("li");
2399
+ popsDOMUtils.addClassName($li, "pops-panel-deepMenu-nav-item");
2400
+ Reflect.set($li, "__formConfig__", formConfig);
2401
+ this.setElementClassName($li, formConfig.className);
2402
+ // 设置属性
2403
+ this.setElementAttributes($li, formConfig.attributes);
2404
+ // 设置元素上的属性
2405
+ this.setElementProps($li, formConfig.props);
2406
+
2407
+ /* 左边底部的描述的文字 */
2408
+ let leftDescriptionText = "";
2409
+ if (formConfig.description) {
2410
+ // 设置描述
2411
+ leftDescriptionText = `<p class="pops-panel-item-left-desc-text">${formConfig.description}</p>`;
2412
+ }
2413
+ // 箭头图标
2414
+ const arrowRightIcon = typeof formConfig.arrowRightIcon === "boolean" ? formConfig.arrowRightIcon : true;
2415
+ let arrowRightIconHTML = "";
2416
+ if (arrowRightIcon) {
2417
+ arrowRightIconHTML = `<i class="pops-panel-deepMenu-arrowRight-icon">${PopsIcon.getIcon("arrowRight")}</i>`;
2418
+ }
2419
+ let rightText = "";
2420
+ if (formConfig.rightText) {
2421
+ rightText = /*html*/ `<p class="pops-panel-item-right-text">${formConfig.rightText}</p>`;
2422
+ }
2423
+ PopsSafeUtils.setSafeHTML(
2424
+ $li,
2425
+ /*html*/ `
2426
+ <div class="pops-panel-item-left-text">
2427
+ <p class="pops-panel-item-left-main-text">${formConfig.text}</p>${leftDescriptionText}</div>
2428
+ <div class="pops-panel-deepMenu">${rightText}${arrowRightIconHTML}</div>
2429
+ `
2430
+ );
2431
+ const PopsPanelDeepMenu = {
2432
+ [Symbol.toStringTag]: "PopsPanelDeepMenu",
2433
+ $ele: {
2434
+ get parentSection() {
2435
+ return that.$el.$contentSectionContainer;
2436
+ },
2437
+ },
2438
+ init() {
2439
+ this.setLiClickEvent();
2440
+ },
2441
+ /**
2442
+ * 生成配置每一项的元素
2443
+ * @param $container
2444
+ * @param formItemConfig
2445
+ */
2446
+ initFormItem($container: HTMLElement, formItemConfig: PopsPanelFormsTotalDetails | PopsPanelFormsDetails) {
2447
+ const formConfig_forms = formItemConfig as PopsPanelFormsDetails;
2448
+ if (formConfig_forms.type === "forms") {
2449
+ const childForms = formConfig_forms["forms"];
2450
+ /* 每一项<li>元素 */
2451
+ const formContainerListElement = document.createElement("li");
2452
+ /* 每一项<li>内的子<ul>元素 */
2453
+ const formContainerULElement = document.createElement("ul");
2454
+ formContainerULElement.classList.add("pops-panel-forms-container-item-formlist");
2455
+ formContainerListElement.classList.add("pops-panel-forms-container-item");
2456
+ /* 区域头部的文字 */
2457
+ const formHeaderDivElement = popsDOMUtils.createElement("div", {
2458
+ className: "pops-panel-forms-container-item-header-text",
2459
+ });
2460
+ PopsSafeUtils.setSafeHTML(formHeaderDivElement, formConfig_forms["text"]);
2461
+
2462
+ if (formConfig_forms.isFold) {
2463
+ /* 添加第一个 */
2464
+ /* 加进容器内 */
2465
+ PopsSafeUtils.setSafeHTML(
2466
+ formHeaderDivElement,
2467
+ /*html*/ `
2468
+ <p>${formConfig_forms.text}</p>
2469
+ <i class="pops-panel-forms-fold-container-icon">
2470
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
2471
+ <path d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z"></path>
2472
+ </svg>
2473
+ </i>
2474
+ `
2475
+ );
2476
+ // 添加点击事件
2477
+ popsDOMUtils.on(formHeaderDivElement, "click", () => {
2478
+ if (formContainerListElement.hasAttribute("data-fold-enable")) {
2479
+ formContainerListElement.removeAttribute("data-fold-enable");
2480
+ } else {
2481
+ formContainerListElement.setAttribute("data-fold-enable", "");
2482
+ }
2483
+ });
2484
+ popsDOMUtils.addClassName(formHeaderDivElement, "pops-panel-forms-fold-container");
2485
+ popsDOMUtils.addClassName(formHeaderDivElement, PopsCommonCSSClassName.userSelectNone);
2486
+ formContainerListElement.setAttribute("data-fold-enable", "");
2487
+ popsDOMUtils.addClassName(formHeaderDivElement, "pops-panel-forms-fold");
2488
+ formContainerListElement.appendChild(formHeaderDivElement);
2489
+ } else {
2490
+ /* 加进容器内 */
2491
+ formContainerListElement.appendChild(formHeaderDivElement);
2492
+ }
2493
+
2494
+ that.setElementClassName(formContainerListElement, formItemConfig.className);
2495
+ that.setElementAttributes(formContainerListElement, formItemConfig.attributes);
2496
+ that.setElementProps(formContainerListElement, formItemConfig.props);
2497
+ childForms.forEach((childFormConfig) => {
2498
+ that.uListContainerAddItem(childFormConfig, {
2499
+ ulElement: formContainerULElement,
2500
+ sectionContainerULElement: that.sectionContainerULElement,
2501
+ formContainerListElement: formContainerListElement,
2502
+ formHeaderDivElement: formHeaderDivElement,
2503
+ });
2504
+ });
2505
+ formContainerListElement.appendChild(formContainerULElement);
2506
+ $container.appendChild(formContainerListElement);
2507
+ if (typeof formConfig_forms.afterAddToUListCallBack === "function") {
2508
+ formConfig_forms.afterAddToUListCallBack(formConfig as any as PopsPanelFormsDetails, {
2509
+ target: formContainerListElement,
2510
+ ulElement: formContainerULElement,
2511
+ sectionContainerULElement: that.sectionContainerULElement,
2512
+ formContainerListElement: formContainerListElement,
2513
+ formHeaderDivElement: formHeaderDivElement,
2514
+ });
2515
+ }
2516
+ } else {
2517
+ /* 如果成功创建,加入到中间容器中 */
2518
+ that.uListContainerAddItem(formConfig, {
2519
+ ulElement: that.sectionContainerULElement,
2520
+ });
2521
+ }
2522
+ },
2523
+ /**
2524
+ * 前往子菜单
2525
+ * @param event 点击事件
2526
+ * @param liElement 当前的<li>元素
2527
+ */
2528
+ async gotoDeepMenu(event: Event, liElement: HTMLLIElement) {
2529
+ /** 当前所在的容器 */
2530
+ const $currentSection = liElement.closest<HTMLElement>("section.pops-panel-container")!;
2531
+ // 子菜单的容器
2532
+ const $deepMenuSection = popsDOMUtils.createElement("section", {
2533
+ className: "pops-panel-container pops-panel-deepMenu-container",
2534
+ });
2535
+ Reflect.set($deepMenuSection, "__formConfig__", formConfig);
2536
+ const $deepMenuHeaderUL = popsDOMUtils.createElement("ul", {
2537
+ className: "pops-panel-container-header-ul pops-panel-deepMenu-container-header-ul",
2538
+ });
2539
+ const $deepMenuMain = popsDOMUtils.createElement("ul", {
2540
+ className: "pops-panel-container-main-ul",
2541
+ });
2542
+ // 标题文字
2543
+ const headerTitleText = formConfig.headerTitle ?? formConfig.text;
2544
+ const $header = popsDOMUtils.createElement("li", {
2545
+ className: "pops-panel-container-header-title-text pops-panel-deepMenu-container-header",
2546
+ innerHTML: /*html*/ `<p class="pops-panel-deepMenu-container-header-title-text">${headerTitleText}</p>`,
2547
+ });
2548
+ // 返回箭头
2549
+ const $headerLeftArrow = popsDOMUtils.createElement("i", {
2550
+ className: "pops-panel-deepMenu-container-left-arrow-icon",
2551
+ innerHTML: PopsIcon.getIcon("arrowLeft")!,
2552
+ });
2553
+ // 动画配置
2554
+ const animOptions: KeyframeAnimationOptions = {
2555
+ // 150 220 300
2556
+ duration: 220,
2557
+ easing: "ease-in-out",
2558
+ };
2559
+ // 进入动画
2560
+ const enterViewTransition = () => {
2561
+ // 隐藏旧的容器
2562
+ popsDOMUtils.cssHide($currentSection, true);
2563
+ popsDOMUtils.on(
2564
+ $headerLeftArrow,
2565
+ "click",
2566
+ async (event) => {
2567
+ popsDOMUtils.preventEvent(event);
2568
+ // 返回动画
2569
+ const leaveViewTransition = () => {
2570
+ const $prev = $currentSection;
2571
+ popsDOMUtils.cssShow($prev);
2572
+ $deepMenuSection.remove();
2573
+ };
2574
+ // 返回上一层菜单
2575
+ if (that.$config.useDeepMenuSwtichAnimation && document.startViewTransition) {
2576
+ const leaveTransition = document.startViewTransition(leaveViewTransition);
2577
+ await leaveTransition.ready;
2578
+ // 向右移出
2579
+ await Promise.all([
2580
+ $deepMenuSection.animate(
2581
+ [
2582
+ {
2583
+ // from
2584
+ transform: "translateX(0)",
2585
+ },
2586
+ {
2587
+ // to
2588
+ transform: "translateX(100%)",
2589
+ },
2590
+ ],
2591
+ animOptions
2592
+ ).finished,
2593
+ // 向右移入
2594
+ $currentSection.animate(
2595
+ [
2596
+ {
2597
+ // from
2598
+ transform: "translateX(-100%)",
2599
+ },
2600
+ {
2601
+ // to
2602
+ transform: "translateX(0)",
2603
+ },
2604
+ ],
2605
+ animOptions
2606
+ ).finished,
2607
+ ]);
2608
+ await leaveTransition.finished;
2609
+ } else {
2610
+ leaveViewTransition();
2611
+ }
2612
+ that.triggerRenderRightContainer($currentSection);
2613
+ },
2614
+ {
2615
+ once: true,
2616
+ }
2617
+ );
2618
+ popsDOMUtils.before($header.firstElementChild!, $headerLeftArrow);
2619
+ $deepMenuHeaderUL.appendChild($header);
2620
+ $deepMenuSection.appendChild($deepMenuHeaderUL);
2621
+ $deepMenuSection.appendChild($deepMenuMain);
2622
+
2623
+ if (formConfig.forms && Array.isArray(formConfig.forms)) {
2624
+ for (let index = 0; index < formConfig.forms.length; index++) {
2625
+ const formItemConfig = formConfig.forms[index];
2626
+ this.initFormItem($deepMenuMain, formItemConfig);
2627
+ }
2628
+ }
2629
+ that.$el.$sectionWrapper.appendChild($deepMenuSection);
2630
+ };
2631
+ if (that.$config.useDeepMenuSwtichAnimation && document.startViewTransition) {
2632
+ const transition = document.startViewTransition(enterViewTransition);
2633
+ await transition.ready;
2634
+ await $deepMenuSection.animate(
2635
+ [
2636
+ {
2637
+ // from
2638
+ transform: "translateX(100%)",
2639
+ },
2640
+ {
2641
+ // to
2642
+ transform: "translateX(0)",
2643
+ },
2644
+ ],
2645
+ animOptions
2646
+ ).finished;
2647
+ await transition.finished;
2648
+ } else {
2649
+ enterViewTransition();
2650
+ }
2651
+ if (typeof formConfig.afterEnterDeepMenuCallBack === "function") {
2652
+ formConfig.afterEnterDeepMenuCallBack(formConfig, {
2653
+ sectionContainer: $deepMenuSection,
2654
+ sectionContainerHeaderContainer: $deepMenuHeaderUL,
2655
+ sectionContainerHeader: $header,
2656
+ sectionBodyContainer: $deepMenuMain,
2657
+ });
2658
+ }
2659
+ that.triggerRenderRightContainer($deepMenuSection);
2660
+ },
2661
+ /** 设置项的点击事件 */
2662
+ setLiClickEvent() {
2663
+ popsDOMUtils.on($li, "click", void 0, async (event) => {
2664
+ if (typeof formConfig.clickCallBack === "function") {
2665
+ const result = await formConfig.clickCallBack(event, formConfig);
2666
+ if (result) {
2667
+ return;
2668
+ }
2669
+ }
2670
+ await this.gotoDeepMenu(event, $li);
2671
+ });
2672
+ },
2673
+ };
2674
+
2675
+ PopsPanelDeepMenu.init();
2676
+ Reflect.set($li, "data-deepMenu", PopsPanelDeepMenu);
2677
+
2678
+ return $li;
2679
+ },
2680
+ /**
2681
+ * type ===> own
2682
+ * 获取中间容器的元素<li>
2683
+ * @param formConfig
2684
+ */
2685
+ createSectionContainerItem_own(formConfig: PopsPanelOwnDetails) {
2686
+ let $li = document.createElement("li");
2687
+ Reflect.set($li, "__formConfig__", formConfig);
2688
+ if (formConfig.className) {
2689
+ $li.className = formConfig.className;
2690
+ }
2691
+ $li = formConfig.getLiElementCallBack($li);
2692
+ return $li;
2693
+ },
2694
+ /**
2695
+ * 获取中间容器的元素<li>
2696
+ * @param formConfig
2697
+ */
2698
+ createSectionContainerItem(formConfig: PopsPanelFormsTotalDetails) {
2699
+ /** 配置项的类型 */
2700
+ const formType = formConfig.type;
2701
+
2702
+ if (formType === "switch") {
2703
+ return this.createSectionContainerItem_switch(formConfig as PopsPanelSwitchDetails);
2704
+ } else if (formType === "slider") {
2705
+ return this.createSectionContainerItem_slider_new(formConfig as PopsPanelSliderDetails);
2706
+ } else if (formType === "input") {
2707
+ return this.createSectionContainerItem_input(formConfig as PopsPanelInputDetails);
2708
+ } else if (formType === "textarea") {
2709
+ return this.createSectionContainerItem_textarea(formConfig as PopsPanelTextAreaDetails);
2710
+ } else if (formType === "select") {
2711
+ return this.createSectionContainerItem_select(formConfig as PopsPanelSelectDetails);
2712
+ } else if (formType === "select-multiple") {
2713
+ return this.createSectionContainerItem_select_multiple_new(formConfig as PopsPanelSelectMultipleDetails<any>);
2714
+ } else if (formType === "button") {
2715
+ return this.createSectionContainerItem_button(formConfig as PopsPanelButtonDetails);
2716
+ } else if (formType === "deepMenu") {
2717
+ return this.createSectionContainerItem_deepMenu(formConfig as PopsPanelDeepMenuDetails);
2718
+ } else if (formType === "own") {
2719
+ return this.createSectionContainerItem_own(formConfig as PopsPanelOwnDetails);
2720
+ } else {
2721
+ console.error("尚未实现的type类型", formConfig);
2722
+ }
2723
+ },
2724
+ /**
2725
+ * 生成配置项forms
2726
+ * 生成配置每一项的元素
2727
+ * @param formConfig
2728
+ */
2729
+ createSectionContainerItem_forms(formConfig: PopsPanelContentConfig | PopsPanelFormsDetails) {
2730
+ const that = this;
2731
+ const formConfig_forms = formConfig as PopsPanelFormsDetails;
2732
+ if (formConfig_forms.type === "forms") {
2733
+ const childForms = formConfig["forms"];
2734
+ /* 每一项<li>元素 */
2735
+ const formContainerListElement = document.createElement("li");
2736
+ /* 每一项<li>内的子<ul>元素 */
2737
+ const formContainerULElement = document.createElement("ul");
2738
+ formContainerListElement.classList.add("pops-panel-forms-container-item");
2739
+ formContainerULElement.classList.add("pops-panel-forms-container-item-formlist");
2740
+ /* 区域头部的文字 */
2741
+ const formHeaderDivElement = popsDOMUtils.createElement("div", {
2742
+ className: "pops-panel-forms-container-item-header-text",
2743
+ });
2744
+ PopsSafeUtils.setSafeHTML(formHeaderDivElement, formConfig_forms["text"]);
2745
+ if (formConfig_forms.isFold) {
2746
+ /* 加进容器内 */
2747
+ PopsSafeUtils.setSafeHTML(
2748
+ formHeaderDivElement,
2749
+ /*html*/ `
2750
+ <p>${formConfig_forms.text}</p>
2751
+ <i class="pops-panel-forms-fold-container-icon">
2752
+ <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1024 1024">
2753
+ <path d="M340.864 149.312a30.592 30.592 0 0 0 0 42.752L652.736 512 340.864 831.872a30.592 30.592 0 0 0 0 42.752 29.12 29.12 0 0 0 41.728 0L714.24 534.336a32 32 0 0 0 0-44.672L382.592 149.376a29.12 29.12 0 0 0-41.728 0z"></path>
2754
+ </svg>
2755
+ </i>
2756
+ `
2757
+ );
2758
+ // 添加点击事件
2759
+ popsDOMUtils.on(formHeaderDivElement, "click", () => {
2760
+ if (formContainerListElement.hasAttribute("data-fold-enable")) {
2761
+ formContainerListElement.removeAttribute("data-fold-enable");
2762
+ } else {
2763
+ formContainerListElement.setAttribute("data-fold-enable", "");
2764
+ }
2765
+ });
2766
+ popsDOMUtils.addClassName(formHeaderDivElement, "pops-panel-forms-fold-container");
2767
+ popsDOMUtils.addClassName(formHeaderDivElement, PopsCommonCSSClassName.userSelectNone);
2768
+ formContainerListElement.setAttribute("data-fold-enable", "");
2769
+ popsDOMUtils.addClassName(formContainerListElement, "pops-panel-forms-fold");
2770
+ formContainerListElement.appendChild(formHeaderDivElement);
2771
+ } else {
2772
+ /* 加进容器内 */
2773
+ formContainerListElement.appendChild(formHeaderDivElement);
2774
+ }
2775
+ that.setElementClassName(formContainerListElement, formConfig.className);
2776
+ that.setElementAttributes(formContainerListElement, formConfig.attributes);
2777
+ that.setElementProps(formContainerListElement, formConfig.props);
2778
+ childForms.forEach((childFormConfig) => {
2779
+ that.uListContainerAddItem(childFormConfig as PopsPanelFormsTotalDetails, {
2780
+ ulElement: formContainerULElement,
2781
+ sectionContainerULElement: that.sectionContainerULElement,
2782
+ formContainerListElement: formContainerListElement,
2783
+ formHeaderDivElement: formHeaderDivElement,
2784
+ });
2785
+ });
2786
+ formContainerListElement.appendChild(formContainerULElement);
2787
+ that.sectionContainerULElement.appendChild(formContainerListElement);
2788
+
2789
+ if (typeof formConfig_forms.afterAddToUListCallBack === "function") {
2790
+ formConfig_forms.afterAddToUListCallBack(formConfig_forms, {
2791
+ target: formContainerListElement,
2792
+ ulElement: formContainerULElement,
2793
+ sectionContainerULElement: that.sectionContainerULElement,
2794
+ formContainerListElement: formContainerListElement,
2795
+ formHeaderDivElement: formHeaderDivElement,
2796
+ });
2797
+ }
2798
+ } else {
2799
+ /* 如果成功创建,加入到中间容器中 */
2800
+ that.uListContainerAddItem(formConfig as any as PopsPanelFormsTotalDetails, {
2801
+ ulElement: that.sectionContainerULElement,
2802
+ });
2803
+ }
2804
+ },
2805
+ /**
2806
+ * 触发触发渲染右侧容器的事件
2807
+ */
2808
+ triggerRenderRightContainer($container: HTMLElement) {
2809
+ const __formConfig__: PopsPanelEventType["pops:renderRightContainer"]["formConfig"] = Reflect.get(
2810
+ $container,
2811
+ "__formConfig__"
2812
+ );
2813
+ this.$el.$pops.dispatchEvent(
2814
+ new CustomEvent<PopsPanelEventType["pops:renderRightContainer"]>(
2815
+ <keyof PopsPanelEventType>"pops:renderRightContainer",
2816
+ {
2817
+ detail: {
2818
+ formConfig: __formConfig__,
2819
+ },
2820
+ }
2821
+ )
2822
+ );
2823
+ },
2824
+ /**
2825
+ *
2826
+ * @param formConfig
2827
+ * @param containerOptions
2828
+ */
2829
+ uListContainerAddItem(
2830
+ formConfig: PopsPanelFormsTotalDetails,
2831
+ containerOptions: Omit<PopsPanelRightAsideContainerOptions, "target">
2832
+ ) {
2833
+ const itemLiElement = this.createSectionContainerItem(formConfig);
2834
+ if (itemLiElement) {
2835
+ containerOptions["ulElement"].appendChild(itemLiElement);
2836
+ }
2837
+ if (typeof formConfig.afterAddToUListCallBack === "function") {
2838
+ formConfig.afterAddToUListCallBack(formConfig as any, {
2839
+ ...containerOptions,
2840
+ target: itemLiElement,
2841
+ });
2842
+ }
2843
+ },
2844
+ /**
2845
+ * 为左侧容器元素添加点击事件
2846
+ * @param asideLiElement 左侧的容器<li>元素
2847
+ * @param asideConfig 配置
2848
+ */
2849
+ setAsideItemClickEvent(asideLiElement: HTMLElement, asideConfig: PopsPanelContentConfig) {
2850
+ popsDOMUtils.on<MouseEvent | PointerEvent>(asideLiElement, "click", async (event) => {
2851
+ if (typeof asideConfig.clickFirstCallback === "function") {
2852
+ const clickFirstCallbackResult = await asideConfig.clickFirstCallback(
2853
+ event,
2854
+ this.sectionContainerHeaderULElement,
2855
+ this.sectionContainerULElement
2856
+ );
2857
+ if (typeof clickFirstCallbackResult === "boolean" && !clickFirstCallbackResult) {
2858
+ return;
2859
+ }
2860
+ }
2861
+ this.clearContainer();
2862
+ const rightContainerFormConfig: PopsPanelContentConfig[] = Reflect.get(asideLiElement, "__forms__");
2863
+
2864
+ Reflect.set(this.$el.$contentSectionContainer, "__formConfig__", rightContainerFormConfig);
2865
+ popsDOMUtils.cssShow(this.$el.$contentSectionContainer);
2866
+ this.clearAsideItemIsVisited();
2867
+ this.setAsideItemIsVisited(asideLiElement);
2868
+ /* 顶部标题栏,存在就设置 */
2869
+ const title = typeof asideConfig.title === "function" ? asideConfig.title() : asideConfig.title;
2870
+ let headerTitleText =
2871
+ typeof asideConfig.headerTitle === "function" ? asideConfig.headerTitle() : asideConfig.headerTitle;
2872
+ headerTitleText = headerTitleText ?? title;
2873
+ if (typeof headerTitleText === "string" && headerTitleText.trim() !== "") {
2874
+ const $containerHeaderTitle = document.createElement("li");
2875
+ $containerHeaderTitle.classList.add("pops-panel-container-header-title-text");
2876
+ Reflect.set($containerHeaderTitle, "__asideConfig__", asideConfig);
2877
+ PopsSafeUtils.setSafeHTML($containerHeaderTitle, headerTitleText);
2878
+ this.sectionContainerHeaderULElement.appendChild($containerHeaderTitle);
2879
+ }
2880
+
2881
+ rightContainerFormConfig.forEach((formConfig) => {
2882
+ this.createSectionContainerItem_forms(formConfig);
2883
+ });
2884
+
2885
+ if (typeof asideConfig.clickCallback === "function") {
2886
+ /* 执行回调 */
2887
+ const asideClickCallbackResult = await asideConfig.clickCallback(
2888
+ event,
2889
+ this.sectionContainerHeaderULElement,
2890
+ this.sectionContainerULElement
2891
+ );
2892
+ if (typeof asideClickCallbackResult === "boolean" && !asideClickCallbackResult) {
2893
+ return;
2894
+ }
2895
+ }
2896
+ this.triggerRenderRightContainer(this.$el.$contentSectionContainer);
2897
+ });
2898
+ },
2899
+ };
2900
+ };