@schukai/monster 3.51.5 → 3.52.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (360) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +15 -12
  3. package/example/components/form/button.mjs +10 -0
  4. package/example/components/form/select.mjs +25 -0
  5. package/example/components/form/tree-select.mjs +27 -0
  6. package/example/components/host/host.mjs +0 -0
  7. package/example/components/notify/message.mjs +4 -0
  8. package/example/components/notify/notify.mjs +4 -0
  9. package/example/components/state/log.mjs +0 -0
  10. package/example/components/state/state.mjs +0 -0
  11. package/package.json +6 -2
  12. package/source/components/constants.mjs +132 -0
  13. package/source/components/datatable/columnbar.mjs +310 -0
  14. package/source/components/datatable/constants.mjs +121 -0
  15. package/source/components/datatable/dataset.mjs +219 -0
  16. package/source/components/datatable/datasource/dom.mjs +186 -0
  17. package/source/components/datatable/datasource/namespace.mjs +13 -0
  18. package/source/components/datatable/datasource/rest.mjs +400 -0
  19. package/source/components/datatable/datasource.mjs +102 -0
  20. package/source/components/datatable/datatable/header.mjs +268 -0
  21. package/source/components/datatable/datatable/namespace.mjs +13 -0
  22. package/source/components/datatable/datatable.mjs +789 -0
  23. package/source/components/datatable/embedded-pagination.mjs +113 -0
  24. package/source/components/datatable/filter/abstract-base.mjs +31 -0
  25. package/source/components/datatable/filter/date-range.mjs +1041 -0
  26. package/source/components/datatable/filter/input.mjs +175 -0
  27. package/source/components/datatable/filter/namespace.mjs +13 -0
  28. package/source/components/datatable/filter/range.mjs +671 -0
  29. package/source/components/datatable/filter/select.mjs +65 -0
  30. package/source/components/datatable/filter/settings.mjs +116 -0
  31. package/source/components/datatable/filter-button.mjs +98 -0
  32. package/source/components/datatable/filter.mjs +929 -0
  33. package/source/components/datatable/namespace.mjs +11 -0
  34. package/source/components/datatable/pagination.mjs +456 -0
  35. package/source/components/datatable/style/column-bar.pcss +123 -0
  36. package/source/components/datatable/style/dataset.pcss +13 -0
  37. package/source/components/datatable/style/datasource.pcss +16 -0
  38. package/source/components/datatable/style/datatable.pcss +239 -0
  39. package/source/components/datatable/style/embedded-pagination.pcss +101 -0
  40. package/source/components/datatable/style/filter-button.pcss +22 -0
  41. package/source/components/datatable/style/filter-controls-defaults.pcss +46 -0
  42. package/source/components/datatable/style/filter-date-range.pcss +9 -0
  43. package/source/components/datatable/style/filter-range.pcss +5 -0
  44. package/source/components/datatable/style/filter.pcss +156 -0
  45. package/source/components/datatable/style/pagination.pcss +59 -0
  46. package/source/components/datatable/style/select-filter.pcss +27 -0
  47. package/source/components/datatable/stylesheet/column-bar.mjs +33 -0
  48. package/source/components/datatable/stylesheet/dataset.mjs +33 -0
  49. package/source/components/datatable/stylesheet/datasource.mjs +33 -0
  50. package/source/components/datatable/stylesheet/datatable.mjs +33 -0
  51. package/source/components/datatable/stylesheet/embedded-pagination.mjs +33 -0
  52. package/source/components/datatable/stylesheet/filter-button.mjs +33 -0
  53. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +33 -0
  54. package/source/components/datatable/stylesheet/filter-date-range.mjs +33 -0
  55. package/source/components/datatable/stylesheet/filter-range.mjs +33 -0
  56. package/source/components/datatable/stylesheet/filter.mjs +33 -0
  57. package/source/components/datatable/stylesheet/namespace.mjs +13 -0
  58. package/source/components/datatable/stylesheet/pagination.mjs +33 -0
  59. package/source/components/datatable/stylesheet/select-filter.mjs +33 -0
  60. package/source/components/datatable/util.mjs +60 -0
  61. package/source/components/form/action-button.mjs +262 -0
  62. package/source/components/form/api-button.mjs +515 -0
  63. package/source/components/form/button-bar.mjs +739 -0
  64. package/source/components/form/button.mjs +350 -0
  65. package/source/components/form/confirm-button.mjs +330 -0
  66. package/source/components/form/constants.mjs +111 -0
  67. package/source/components/form/context-help.mjs +123 -0
  68. package/source/components/form/events.mjs +84 -0
  69. package/source/components/form/form.mjs +601 -0
  70. package/source/components/form/message-state-button.mjs +396 -0
  71. package/source/components/form/namespace.mjs +13 -0
  72. package/source/components/form/popper-button.mjs +435 -0
  73. package/source/components/form/popper.mjs +487 -0
  74. package/source/components/form/reload.mjs +360 -0
  75. package/source/components/form/select.mjs +2314 -0
  76. package/source/components/form/shadow-reload.mjs +137 -0
  77. package/source/components/form/state-button.mjs +182 -0
  78. package/source/components/form/style/action-button.pcss +41 -0
  79. package/source/components/form/style/api-button.pcss +0 -0
  80. package/source/components/form/style/button-bar.pcss +51 -0
  81. package/source/components/form/style/button.pcss +8 -0
  82. package/source/components/form/style/confirm-button.pcss +17 -0
  83. package/source/components/form/style/context-help.pcss +16 -0
  84. package/source/components/form/style/form.pcss +10 -0
  85. package/source/components/form/style/message-state-button.pcss +10 -0
  86. package/source/components/form/style/popper-button.pcss +16 -0
  87. package/source/components/form/style/popper.pcss +8 -0
  88. package/source/components/form/style/select.pcss +265 -0
  89. package/source/components/form/style/state-button.pcss +116 -0
  90. package/source/components/form/style/tabs.pcss +170 -0
  91. package/source/components/form/style/tree-select.pcss +81 -0
  92. package/source/components/form/stylesheet/action-button.mjs +33 -0
  93. package/source/components/form/stylesheet/api-button.mjs +33 -0
  94. package/source/components/form/stylesheet/button-bar.mjs +33 -0
  95. package/source/components/form/stylesheet/button.mjs +33 -0
  96. package/source/components/form/stylesheet/confirm-button.mjs +33 -0
  97. package/source/components/form/stylesheet/context-help.mjs +33 -0
  98. package/source/components/form/stylesheet/form.mjs +33 -0
  99. package/source/components/form/stylesheet/message-state-button.mjs +33 -0
  100. package/source/components/form/stylesheet/namespace.mjs +13 -0
  101. package/source/components/form/stylesheet/popper-button.mjs +33 -0
  102. package/source/components/form/stylesheet/popper.mjs +33 -0
  103. package/source/components/form/stylesheet/select.mjs +33 -0
  104. package/source/components/form/stylesheet/state-button.mjs +33 -0
  105. package/source/components/form/stylesheet/tabs.mjs +33 -0
  106. package/source/components/form/stylesheet/tree-select.mjs +33 -0
  107. package/source/components/form/tabs.mjs +1011 -0
  108. package/source/components/form/template.mjs +373 -0
  109. package/source/components/form/tree-select.mjs +527 -0
  110. package/source/components/form/types/namespace.mjs +13 -0
  111. package/source/components/form/types/state.mjs +93 -0
  112. package/source/components/form/util/fetch.mjs +133 -0
  113. package/source/components/form/util/floating-ui.mjs +245 -0
  114. package/source/components/form/util/namespace.mjs +13 -0
  115. package/source/components/form/util/popper.mjs +49 -0
  116. package/source/components/host/call-button.mjs +236 -0
  117. package/source/components/host/collapse.mjs +526 -0
  118. package/source/components/host/config-manager.mjs +304 -0
  119. package/source/components/host/constants.mjs +18 -0
  120. package/source/components/host/details.mjs +268 -0
  121. package/source/components/host/events.mjs +131 -0
  122. package/source/components/host/host.mjs +420 -0
  123. package/source/components/host/namespace.mjs +13 -0
  124. package/source/components/host/overlay.mjs +339 -0
  125. package/source/components/host/style/call-button.pcss +36 -0
  126. package/source/components/host/style/collapse.pcss +67 -0
  127. package/source/components/host/style/config-manager.pcss +5 -0
  128. package/source/components/host/style/details.pcss +68 -0
  129. package/source/components/host/style/host.pcss +43 -0
  130. package/source/components/host/style/overlay.pcss +73 -0
  131. package/source/components/host/style/toggle-button.pcss +36 -0
  132. package/source/components/host/style/viewer.pcss +13 -0
  133. package/source/components/host/stylesheet/call-button.mjs +33 -0
  134. package/source/components/host/stylesheet/collapse.mjs +33 -0
  135. package/source/components/host/stylesheet/config-manager.mjs +33 -0
  136. package/source/components/host/stylesheet/details.mjs +33 -0
  137. package/source/components/host/stylesheet/host.mjs +33 -0
  138. package/source/components/host/stylesheet/namespace.mjs +13 -0
  139. package/source/components/host/stylesheet/overlay.mjs +33 -0
  140. package/source/components/host/stylesheet/toggle-button.mjs +33 -0
  141. package/source/components/host/stylesheet/viewer.mjs +33 -0
  142. package/source/components/host/toggle-button.mjs +88 -0
  143. package/source/components/host/util.mjs +23 -0
  144. package/source/components/host/viewer.mjs +309 -0
  145. package/source/components/namespace.mjs +14 -0
  146. package/source/components/notify/constants.mjs +15 -0
  147. package/source/components/notify/events.mjs +15 -0
  148. package/source/components/notify/message.mjs +374 -0
  149. package/source/components/notify/namespace.mjs +15 -0
  150. package/source/components/notify/notify.mjs +236 -0
  151. package/source/components/notify/style/message.pcss +57 -0
  152. package/source/components/notify/style/notify.pcss +118 -0
  153. package/source/components/notify/stylesheet/message.mjs +33 -0
  154. package/source/components/notify/stylesheet/namespace.mjs +15 -0
  155. package/source/components/notify/stylesheet/notify.mjs +33 -0
  156. package/source/components/state/log/entry.mjs +126 -0
  157. package/source/components/state/log/namespace.mjs +13 -0
  158. package/source/components/state/log.mjs +275 -0
  159. package/source/components/state/namespace.mjs +13 -0
  160. package/source/components/state/state.mjs +131 -0
  161. package/source/components/state/style/log.pcss +111 -0
  162. package/source/components/state/style/state.pcss +113 -0
  163. package/source/components/state/stylesheet/log.mjs +33 -0
  164. package/source/components/state/stylesheet/state.mjs +33 -0
  165. package/source/components/style/badge.pcss +92 -0
  166. package/source/components/style/border.pcss +77 -0
  167. package/source/components/style/button.pcss +105 -0
  168. package/source/components/style/card.pcss +108 -0
  169. package/source/components/style/color.pcss +257 -0
  170. package/source/components/style/common.pcss +103 -0
  171. package/source/components/style/control.pcss +11 -0
  172. package/source/components/style/data-grid.pcss +43 -0
  173. package/source/components/style/display.pcss +42 -0
  174. package/source/components/style/floating-ui.pcss +33 -0
  175. package/source/components/style/form.pcss +5 -0
  176. package/source/components/style/host.pcss +15 -0
  177. package/source/components/style/link.pcss +63 -0
  178. package/source/components/style/mixin/badge.pcss +18 -0
  179. package/source/components/style/mixin/button.pcss +54 -0
  180. package/source/components/style/mixin/form.pcss +247 -0
  181. package/source/components/style/mixin/hover.pcss +8 -0
  182. package/source/components/style/mixin/media.pcss +107 -0
  183. package/source/components/style/mixin/property.pcss +288 -0
  184. package/source/components/style/mixin/skeleton.pcss +26 -0
  185. package/source/components/style/mixin/spinner.pcss +24 -0
  186. package/source/components/style/mixin/typography.pcss +52 -0
  187. package/source/components/style/normalize.pcss +14 -0
  188. package/source/components/style/popper.pcss +78 -0
  189. package/source/components/style/property.pcss +17 -0
  190. package/source/components/style/ripple.pcss +14 -0
  191. package/source/components/style/skeleton.pcss +28 -0
  192. package/source/components/style/space.pcss +47 -0
  193. package/source/components/style/spinner.pcss +6 -0
  194. package/source/components/style/table.pcss +46 -0
  195. package/source/components/style/theme.pcss +119 -0
  196. package/source/components/style/typography.pcss +131 -0
  197. package/source/components/stylesheet/badge.mjs +33 -0
  198. package/source/components/stylesheet/border.mjs +33 -0
  199. package/source/components/stylesheet/button.mjs +33 -0
  200. package/source/components/stylesheet/card.mjs +33 -0
  201. package/source/components/stylesheet/color.mjs +33 -0
  202. package/source/components/stylesheet/common.mjs +33 -0
  203. package/source/components/stylesheet/control.mjs +33 -0
  204. package/source/components/stylesheet/data-grid.mjs +33 -0
  205. package/source/components/stylesheet/display.mjs +33 -0
  206. package/source/components/stylesheet/floating-ui.mjs +33 -0
  207. package/source/components/stylesheet/form.mjs +33 -0
  208. package/source/components/stylesheet/host.mjs +33 -0
  209. package/source/components/stylesheet/link.mjs +33 -0
  210. package/source/components/stylesheet/namespace.mjs +13 -0
  211. package/source/components/stylesheet/normalize.mjs +33 -0
  212. package/source/components/stylesheet/popper.mjs +33 -0
  213. package/source/components/stylesheet/property.mjs +33 -0
  214. package/source/components/stylesheet/ripple.mjs +33 -0
  215. package/source/components/stylesheet/skeleton.mjs +33 -0
  216. package/source/components/stylesheet/space.mjs +33 -0
  217. package/source/components/stylesheet/spinner.mjs +33 -0
  218. package/source/components/stylesheet/table.mjs +33 -0
  219. package/source/components/stylesheet/theme.mjs +33 -0
  220. package/source/components/stylesheet/tree-menu.mjs +33 -0
  221. package/source/components/stylesheet/typography.mjs +33 -0
  222. package/source/components/tree-menu/namespace.mjs +13 -0
  223. package/source/components/tree-menu/style/tree-menu.pcss +107 -0
  224. package/source/components/tree-menu/stylesheet/namespace.mjs +13 -0
  225. package/source/components/tree-menu/stylesheet/tree-menu.mjs +33 -0
  226. package/source/components/tree-menu/tree-menu.mjs +660 -0
  227. package/source/constraints/abstract.mjs +17 -24
  228. package/source/constraints/abstractoperator.mjs +27 -22
  229. package/source/constraints/andoperator.mjs +20 -17
  230. package/source/constraints/invalid.mjs +17 -17
  231. package/source/constraints/isarray.mjs +20 -20
  232. package/source/constraints/isobject.mjs +20 -20
  233. package/source/constraints/oroperator.mjs +45 -45
  234. package/source/constraints/valid.mjs +17 -17
  235. package/source/data/buildmap.mjs +108 -103
  236. package/source/data/buildtree.mjs +59 -57
  237. package/source/data/datasource/dom.mjs +80 -84
  238. package/source/data/datasource/namespace.mjs +1 -1
  239. package/source/data/datasource/server/restapi/data-fetch-error.mjs +27 -25
  240. package/source/data/datasource/server/restapi/writeerror.mjs +34 -32
  241. package/source/data/datasource/server/restapi.mjs +176 -177
  242. package/source/data/datasource/server/webconnect.mjs +150 -156
  243. package/source/data/datasource/server.mjs +58 -59
  244. package/source/data/datasource/storage/localstorage.mjs +25 -24
  245. package/source/data/datasource/storage/sessionstorage.mjs +28 -25
  246. package/source/data/datasource/storage.mjs +74 -73
  247. package/source/data/datasource.mjs +176 -167
  248. package/source/data/diff.mjs +98 -97
  249. package/source/data/extend.mjs +42 -42
  250. package/source/data/pathfinder.mjs +301 -288
  251. package/source/data/pipe.mjs +36 -36
  252. package/source/data/transformer.mjs +742 -726
  253. package/source/dom/assembler.mjs +44 -44
  254. package/source/dom/attributes.mjs +142 -122
  255. package/source/dom/constants.mjs +62 -58
  256. package/source/dom/customcontrol.mjs +299 -299
  257. package/source/dom/customelement.mjs +843 -806
  258. package/source/dom/dimension.mjs +56 -46
  259. package/source/dom/events.mjs +74 -69
  260. package/source/dom/focusmanager.mjs +175 -175
  261. package/source/dom/locale.mjs +28 -28
  262. package/source/dom/ready.mjs +13 -13
  263. package/source/dom/resource/data.mjs +117 -111
  264. package/source/dom/resource/link/stylesheet.mjs +16 -16
  265. package/source/dom/resource/link.mjs +94 -96
  266. package/source/dom/resource/script.mjs +72 -74
  267. package/source/dom/resource.mjs +174 -172
  268. package/source/dom/resourcemanager.mjs +152 -156
  269. package/source/dom/slotted.mjs +78 -80
  270. package/source/dom/template.mjs +126 -112
  271. package/source/dom/theme.mjs +35 -35
  272. package/source/dom/updater.mjs +673 -651
  273. package/source/dom/util/extract-keys.mjs +34 -22
  274. package/source/dom/util/init-options-from-attributes.mjs +46 -38
  275. package/source/dom/util/namespace.mjs +13 -0
  276. package/source/dom/util/set-option-from-attribute.mjs +35 -29
  277. package/source/dom/util.mjs +112 -81
  278. package/source/dom/worker/factory.mjs +83 -83
  279. package/source/i18n/formatter.mjs +75 -73
  280. package/source/i18n/locale.mjs +146 -144
  281. package/source/i18n/provider.mjs +70 -64
  282. package/source/i18n/providers/embed.mjs +136 -127
  283. package/source/i18n/providers/fetch.mjs +84 -76
  284. package/source/i18n/translations.mjs +205 -195
  285. package/source/logging/handler/console.mjs +36 -36
  286. package/source/logging/handler.mjs +140 -140
  287. package/source/logging/logentry.mjs +25 -25
  288. package/source/logging/logger.mjs +177 -175
  289. package/source/math/random.mjs +63 -59
  290. package/source/monster.mjs +223 -103
  291. package/source/net/webconnect/message.mjs +31 -31
  292. package/source/net/webconnect.mjs +278 -271
  293. package/source/text/bracketed-key-value-hash.mjs +182 -179
  294. package/source/text/formatter.mjs +235 -210
  295. package/source/text/generate-range-comparison-expression.mjs +56 -34
  296. package/source/text/namespace.mjs +1 -1
  297. package/source/types/base.mjs +69 -61
  298. package/source/types/basewithoptions.mjs +46 -46
  299. package/source/types/binary.mjs +20 -20
  300. package/source/types/dataurl.mjs +96 -90
  301. package/source/types/global.mjs +45 -39
  302. package/source/types/id.mjs +25 -25
  303. package/source/types/internal.mjs +115 -114
  304. package/source/types/is.mjs +56 -40
  305. package/source/types/mediatype.mjs +119 -119
  306. package/source/types/namespace.mjs +1 -1
  307. package/source/types/node.mjs +160 -150
  308. package/source/types/nodelist.mjs +94 -96
  309. package/source/types/noderecursiveiterator.mjs +50 -50
  310. package/source/types/observablequeue.mjs +73 -73
  311. package/source/types/observer.mjs +104 -104
  312. package/source/types/observerlist.mjs +66 -66
  313. package/source/types/proxyobserver.mjs +210 -210
  314. package/source/types/queue.mjs +63 -63
  315. package/source/types/randomid.mjs +13 -13
  316. package/source/types/regex.mjs +3 -1
  317. package/source/types/stack.mjs +64 -64
  318. package/source/types/tokenlist.mjs +206 -205
  319. package/source/types/typeof.mjs +12 -10
  320. package/source/types/uniquequeue.mjs +48 -48
  321. package/source/types/uuid.mjs +32 -32
  322. package/source/types/validate.mjs +67 -67
  323. package/source/types/version.mjs +115 -105
  324. package/source/util/clone.mjs +103 -91
  325. package/source/util/comparator.mjs +97 -97
  326. package/source/util/deadmansswitch.mjs +40 -44
  327. package/source/util/freeze.mjs +10 -9
  328. package/source/util/namespace.mjs +1 -1
  329. package/source/util/processing.mjs +104 -105
  330. package/source/util/runtime.mjs +56 -44
  331. package/source/util/trimspaces.mjs +24 -24
  332. package/test/cases/components/form/button.mjs +122 -0
  333. package/test/cases/components/form/confirm-button.mjs +127 -0
  334. package/test/cases/components/form/form.mjs +317 -0
  335. package/test/cases/components/form/reload.mjs +188 -0
  336. package/test/cases/components/form/select.mjs +229 -0
  337. package/test/cases/components/form/state-button.mjs +130 -0
  338. package/test/cases/components/form/tabs.mjs +98 -0
  339. package/test/cases/components/form/template.mjs +189 -0
  340. package/test/cases/components/form/tree-select.mjs +216 -0
  341. package/test/cases/components/host/details.mjs +68 -0
  342. package/test/cases/components/host/host.mjs +70 -0
  343. package/test/cases/components/host/overlay.mjs +60 -0
  344. package/test/cases/components/host/util.mjs +79 -0
  345. package/test/cases/components/notify/message.mjs +39 -0
  346. package/test/cases/components/notify/notify.mjs +89 -0
  347. package/test/cases/dom/customcontrol.mjs +5 -4
  348. package/test/cases/math/random.mjs +0 -1
  349. package/test/cases/monster.mjs +1 -1
  350. package/test/cases/net/webconnect/message.mjs +0 -1
  351. package/test/cases/types/node.mjs +1 -1
  352. package/test/util/chai-dom.mjs +2 -2
  353. package/test/util/intersection-mock.mjs +69 -0
  354. package/test/util/jsdom.mjs +41 -25
  355. package/test/util/localstorage.mjs +1 -0
  356. package/test/util/resize-observer.mjs +29 -0
  357. package/test/util/websocket.mjs +4 -1
  358. package/test/web/import.js +16 -1
  359. package/test/web/test.html +28 -5
  360. package/test/web/tests.js +30398 -17879
@@ -0,0 +1,2314 @@
1
+ /**
2
+ * Copyright schukai GmbH and contributors 2023. All Rights Reserved.
3
+ * Node module: @schukai/monster
4
+ * This file is licensed under the AGPLv3 License.
5
+ * License text available at https://www.gnu.org/licenses/agpl-3.0.en.html
6
+ */
7
+ import { instanceSymbol } from "../../constants.mjs";
8
+ import { internalSymbol } from "../../constants.mjs";
9
+ import { buildMap } from "../../data/buildmap.mjs";
10
+ import { DeadMansSwitch } from "../../util/deadmansswitch.mjs";
11
+ import { positionPopper } from "./util/floating-ui.mjs";
12
+ import {
13
+ addAttributeToken,
14
+ findClosestByAttribute,
15
+ removeAttributeToken,
16
+ } from "../../dom/attributes.mjs";
17
+ import {
18
+ ATTRIBUTE_ERRORMESSAGE,
19
+ ATTRIBUTE_PREFIX,
20
+ ATTRIBUTE_ROLE,
21
+ } from "../../dom/constants.mjs";
22
+ import { CustomControl } from "../../dom/customcontrol.mjs";
23
+ import {
24
+ assembleMethodSymbol,
25
+ getSlottedElements,
26
+ registerCustomElement,
27
+ } from "../../dom/customelement.mjs";
28
+ import {
29
+ findTargetElementFromEvent,
30
+ fireCustomEvent,
31
+ fireEvent,
32
+ } from "../../dom/events.mjs";
33
+ import { getDocument } from "../../dom/util.mjs";
34
+ import { Formatter } from "../../text/formatter.mjs";
35
+ import { getGlobal } from "../../types/global.mjs";
36
+ import { ID } from "../../types/id.mjs";
37
+ import {
38
+ isArray,
39
+ isFunction,
40
+ isInteger,
41
+ isIterable,
42
+ isObject,
43
+ isPrimitive,
44
+ isString,
45
+ } from "../../types/is.mjs";
46
+ import { Observer } from "../../types/observer.mjs";
47
+ import { ProxyObserver } from "../../types/proxyobserver.mjs";
48
+ import { validateArray, validateString } from "../../types/validate.mjs";
49
+ import { Processing } from "../../util/processing.mjs";
50
+ import { STYLE_DISPLAY_MODE_BLOCK } from "./constants.mjs";
51
+ import { SelectStyleSheet } from "./stylesheet/select.mjs";
52
+ import {
53
+ getDocumentTranslations,
54
+ Translations,
55
+ } from "../../i18n/translations.mjs";
56
+
57
+ export {
58
+ Select,
59
+ popperElementSymbol,
60
+ getSummaryTemplate,
61
+ getSelectionTemplate,
62
+ };
63
+
64
+ /**
65
+ * @private
66
+ * @type {string}
67
+ */
68
+ const noOptionsAvailableMessage = "No options available.";
69
+
70
+ /**
71
+ * @private
72
+ * @type {symbol}
73
+ */
74
+ const timerCallbackSymbol = Symbol("timerCallback");
75
+
76
+ /**
77
+ * local symbol
78
+ * @private
79
+ * @type {symbol}
80
+ */
81
+ const closeEventHandler = Symbol("closeEventHandler");
82
+
83
+ /**
84
+ * local symbol
85
+ * @private
86
+ * @type {symbol}
87
+ */
88
+ const clearOptionEventHandler = Symbol("clearOptionEventHandler");
89
+
90
+ /**
91
+ * local symbol
92
+ * @private
93
+ * @type {symbol}
94
+ */
95
+ const resizeObserverSymbol = Symbol("resizeObserver");
96
+
97
+ /**
98
+ * local symbol
99
+ * @private
100
+ * @type {symbol}
101
+ */
102
+ const keyEventHandler = Symbol("keyEventHandler");
103
+ /**
104
+ * local symbol
105
+ * @private
106
+ * @type {symbol}
107
+ */
108
+ const inputEventHandler = Symbol("inputEventHandler");
109
+
110
+ /**
111
+ * local symbol
112
+ * @private
113
+ * @type {symbol}
114
+ */
115
+ const changeEventHandler = Symbol("changeEventHandler");
116
+
117
+ /**
118
+ * local symbol
119
+ * @private
120
+ * @type {symbol}
121
+ */
122
+ const controlElementSymbol = Symbol("controlElement");
123
+
124
+ /**
125
+ * local symbol
126
+ * @private
127
+ * @type {symbol}
128
+ */
129
+ const selectionElementSymbol = Symbol("selectionElement");
130
+
131
+ /**
132
+ * local symbol
133
+ * @private
134
+ * @type {symbol}
135
+ */
136
+ const containerElementSymbol = Symbol("containerElement");
137
+
138
+ /**
139
+ * local symbol
140
+ * @private
141
+ * @type {symbol}
142
+ */
143
+ const popperElementSymbol = Symbol("popperElement");
144
+
145
+ /**
146
+ * local symbol
147
+ * @private
148
+ * @type {symbol}
149
+ */
150
+ const inlineFilterElementSymbol = Symbol("inlineFilterElement");
151
+ /**
152
+ * local symbol
153
+ * @private
154
+ * @type {symbol}
155
+ */
156
+ const popperFilterElementSymbol = Symbol("popperFilterElement");
157
+ /**
158
+ * local symbol
159
+ * @private
160
+ * @type {symbol}
161
+ */
162
+ const popperFilterContainerElementSymbol = Symbol(
163
+ "popperFilterContainerElement",
164
+ );
165
+
166
+ /**
167
+ * local symbol
168
+ * @private
169
+ * @type {symbol}
170
+ */
171
+ const optionsElementSymbol = Symbol("optionsElement");
172
+
173
+ /**
174
+ * local symbol
175
+ * @private
176
+ * @type {symbol}
177
+ */
178
+ const noOptionsAvailableElementSymbol = Symbol("noOptionsAvailableElement");
179
+
180
+ /**
181
+ * local symbol
182
+ * @private
183
+ * @type {symbol}
184
+ */
185
+ const statusOrRemoveBadgesElementSymbol = Symbol("statusOrRemoveBadgesElement");
186
+
187
+ /**
188
+ * @private
189
+ * @type {symbol}
190
+ */
191
+ const areOptionsAvailableAndInitSymbol = Symbol("@@areOptionsAvailableAndInit");
192
+
193
+ /**
194
+ * @private
195
+ * @type {number}
196
+ */
197
+ const FOCUS_DIRECTION_UP = 1;
198
+ /**
199
+ * @private
200
+ * @type {number}
201
+ */
202
+ const FOCUS_DIRECTION_DOWN = 2;
203
+
204
+ /**
205
+ * @private
206
+ * @type {string}
207
+ */
208
+ const FILTER_MODE_REMOTE = "remote";
209
+
210
+ /**
211
+ * @private
212
+ * @type {string}
213
+ */
214
+ const FILTER_MODE_OPTIONS = "options";
215
+
216
+ /**
217
+ * @private
218
+ * @type {string}
219
+ */
220
+ const FILTER_MODE_DISABLED = "disabled";
221
+
222
+ /**
223
+ * @private
224
+ * @type {string}
225
+ */
226
+ const FILTER_POSITION_POPPER = "popper";
227
+ /**
228
+ * @private
229
+ * @type {string}
230
+ */
231
+ const FILTER_POSITION_INLINE = "inline";
232
+
233
+ /**
234
+ * @typedef {Object} Selection
235
+ * @property {*} value
236
+ * @property {String} label
237
+ * @memberOf Monster.Components.Form
238
+ * @since 1.2.0
239
+ */
240
+
241
+ /**
242
+ * This CustomControl creates a select element with a variety of options.
243
+ * It supports filtering, local and remote, multiple selection and has a
244
+ * template system for displaying the options.
245
+ *
246
+ * <img src="./images/select.png">
247
+ *
248
+ * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library
249
+ * as well as [pooperjs](https://popper.js.org/docs/v2/).
250
+ *
251
+ * You can create this control either by specifying the HTML tag `<monster-select />` directly in the HTML or using
252
+ * Javascript via the `document.createElement('monster-select');` method.
253
+ *
254
+ * ```html
255
+ * <monster-select></monster-select>
256
+ * ```
257
+ *
258
+ * Or you can create this CustomControl directly in Javascript:
259
+ *
260
+ * ```js
261
+ * import {Select} from '@schukai/component-form/source/select.js';
262
+ * document.createElement('monster-select');
263
+ * ```
264
+ *
265
+ * ## Events
266
+ *
267
+ * The event `monster-change` is sent as soon as someone has clicked on a input control.
268
+ * `monster-changed` is sent as soon as the control has processed this input.
269
+ * The `monster-changed` event is sent when setting a selection. If the options have been set, the `monster-options-set` event is sent.
270
+ *
271
+ * The CustomEvent has the property [`detail`](https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/detail).
272
+ *
273
+ * ```
274
+ * node.addEventListener('monster-change',(e)=>console.log(e.detail))
275
+ * node.addEventListener('monster-changed',(e)=>console.log(e.detail))
276
+ * node.addEventListener('monster-selected',(e)=>console.log(e.detail))
277
+ * node.addEventListener('monster-options-set',(e)=>console.log(e.detail))
278
+ * ```
279
+ *
280
+ * @externalExample ../../../example/components/form/select.mjs
281
+ * @startuml select.png
282
+ * skinparam monochrome true
283
+ * skinparam shadowing false
284
+ * HTMLElement <|-- CustomElement
285
+ * CustomElement <|-- CustomControl
286
+ * CustomControl <|-- Select
287
+ * @enduml
288
+ *
289
+ * @since 1.0.0
290
+ * @copyright schukai GmbH
291
+ * @memberOf Monster.Components.Form
292
+ * @summary A highly configurable select control
293
+ * @fires Monster.Components.Form.event:monster-options-set
294
+ * @fires Monster.Components.Form.event:monster-selected
295
+ * @fires Monster.Components.Form.event:monster-change
296
+ * @fires Monster.Components.Form.event:monster-changed
297
+ */
298
+ class Select extends CustomControl {
299
+ /**
300
+ * @extends CustomControl
301
+ */
302
+ constructor() {
303
+ super();
304
+ initOptionObserver.call(this);
305
+ }
306
+
307
+ /**
308
+ * This method is called by the `instanceof` operator.
309
+ * @returns {symbol}
310
+ * @since 2.1.0
311
+ */
312
+ static get [instanceSymbol]() {
313
+ return Symbol.for("@schukai/component-form/select@@instance");
314
+ }
315
+
316
+ /**
317
+ * The current selection of the Select
318
+ *
319
+ * ```
320
+ * e = document.querySelector('monster-select');
321
+ * console.log(e.value)
322
+ * // ↦ 1
323
+ * // ↦ ['1','2']
324
+ * ```
325
+ *
326
+ * @property {string|array}
327
+ */
328
+ get value() {
329
+ return convertSelectionToValue.call(this, this.getOption("selection"));
330
+ }
331
+
332
+ /**
333
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/attachInternals}
334
+ * @return {boolean}
335
+ */
336
+ static get formAssociated() {
337
+ return true;
338
+ }
339
+
340
+ /**
341
+ * Set selection
342
+ *
343
+ * ```
344
+ * e = document.querySelector('monster-select');
345
+ * e.value=1
346
+ * ```
347
+ *
348
+ * @property {string|array} value
349
+ * @since 1.2.0
350
+ * @throws {Error} unsupported type
351
+ */
352
+ set value(value) {;
353
+
354
+ const result = convertValueToSelection.call(this, value);
355
+ setSelection
356
+ .call(this, result.selection)
357
+ .then(() => {})
358
+ .catch((e) => {
359
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
360
+ });
361
+ }
362
+
363
+ /**
364
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
365
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
366
+ *
367
+ * The individual configuration values can be found in the table.
368
+ *
369
+ * @property {Object} toggleEventType=click,touch List of event types to be observed for opening the dropdown
370
+ * @property {boolean} delegatesFocus=false lorem [see mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/ShadowRoot/delegatesFocus)
371
+ * @property {Object[]} options Selection of key identifier pairs available for selection and displayed in the dropdown.
372
+ * @property {string} options[].label Label
373
+ * @property {string} options[].value Value
374
+ * @property {string} options[].visibility hidden or visible
375
+ * @property {Array} selection Selected options
376
+ * @property {Integer} showMaxOptions=10 Maximum number of visible options before a scroll bar should be displayed.
377
+ * @property {string} type=radio Multiple (checkbox) or single selection (radio)
378
+ * @property {string} name=(random id) Name of the form field
379
+ * @property {string} url Load options from server per url
380
+ * @property {Object} fetch Fetch [see Using Fetch mozilla.org](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)
381
+ * @property {String} fetch.redirect=error
382
+ * @property {String} fetch.method=GET
383
+ * @property {String} fetch.mode=same-origin
384
+ * @property {String} fetch.credentials=same-origin
385
+ * @property {Object} fetch.headers={"accept":"application/json"}}
386
+ * @property {Object} labels
387
+ * @property {string} labels.cannot-be-loaded cannot be loaded
388
+ * @property {string} labels.no-options-available no options available
389
+ * @property {string} labels.select-an-option select an option
390
+ * @property {string} labels.no-option no option in the list, maybe you have to change the filter
391
+ * @property {Object} features List with features
392
+ * @property {Boolean} features.clearAll=true Display of a delete button to delete the entire selection
393
+ * @property {Boolean} features.clear=true Display of a delete key for deleting the specific selection
394
+ * @property {Boolean} features.loadOnOpen=false Load options when opening the dropdown
395
+ * @property {Boolean} filter.defaultValue=* Default filter value, if the filter is empty
396
+ * @property {Boolean} filter.mode=options Filter mode, values: options, remote, disabled
397
+ * @property {Object} templates Template definitions
398
+ * @property {string} templates.main Main template
399
+ * @property {string} templateMapping Mapping of the template placeholders
400
+ * @property {string} templateMapping.selected Selected Template
401
+ * @property {Object} popper [PopperJS Options](https://popper.js.org/docs/v2/)
402
+ * @property {string} popper.placement=bottom PopperJS placement
403
+ * @property {Object[]} modifiers={name:offset} PopperJS placement
404
+ * @property {Object} mapping
405
+ * @property {String} mapping.selector=* Path to select the appropriate entries
406
+ * @property {String} mapping.labelTemplate="" template with the label placeholders in the form ${name}, where name is the key (**)
407
+ * @property {String} mapping.valueTemplate="" template with the value placeholders in the form ${name}, where name is the key
408
+ * @property {Monster.Components.Form~exampleFilterCallback|undefined} mapping.filter Filtering of values via a function
409
+ * @property {Object} formatter
410
+ * @property {Monster.Components.Form~formatterSelectionCallback|undefined} formatter.selection format selection label
411
+ */
412
+ get defaults() {
413
+ return Object.assign(
414
+ {},
415
+ super.defaults,
416
+ {
417
+ toggleEventType: ["click", "touch"],
418
+ delegatesFocus: false,
419
+ options: [],
420
+ selection: [],
421
+ showMaxOptions: 10,
422
+ type: "radio",
423
+ name: new ID("s").toString(),
424
+ features: {
425
+ clearAll: true,
426
+ clear: true,
427
+ loadOnOpen: false,
428
+ },
429
+ url: null,
430
+ labels: {
431
+ "cannot-be-loaded": "Cannot be loaded",
432
+ "no-options-available": "No options available",
433
+ "select-an-option": "Select an option",
434
+ "summary-text": {
435
+ zero: "No entries were selected",
436
+ one: '<span class="monster-badge-primary-pill">1</span> entry was selected',
437
+ other:
438
+ '<span class="monster-badge-primary-pill">${count}</span> entries were selected',
439
+ },
440
+ "no-options":
441
+ "Unfortunately, there are no options available in the list.",
442
+ "no-options-found":
443
+ "No options are available in the list. Please consider modifying the filter.",
444
+ },
445
+ messages: {
446
+ control: null,
447
+ selected: null,
448
+ emptyOptions: null,
449
+ },
450
+ fetch: {
451
+ redirect: "error",
452
+ method: "GET",
453
+ mode: "same-origin",
454
+ credentials: "same-origin",
455
+ headers: {
456
+ accept: "application/json",
457
+ },
458
+ },
459
+ filter: {
460
+ defaultValue: "*",
461
+ mode: "disabled",
462
+ position: "inline",
463
+ },
464
+ classes: {
465
+ badge: "monster-badge-primary",
466
+ statusOrRemoveBadge: "empty",
467
+ },
468
+ mapping: {
469
+ selector: "*",
470
+ labelTemplate: "",
471
+ valueTemplate: "",
472
+ filter: null,
473
+ },
474
+ formatter: {
475
+ selection: buildSelectionLabel,
476
+ },
477
+ templates: {
478
+ main: getTemplate(),
479
+ },
480
+ templateMapping: {
481
+ /** with the attribute `data-monster-selected-template` the template for the selected options can be defined. */
482
+ selected: getSelectionTemplate(),
483
+ },
484
+
485
+ popper: {
486
+ placement: "bottom",
487
+ middleware: ["flip", "offset:1"],
488
+ },
489
+ },
490
+ initOptionsFromArguments.call(this),
491
+ );
492
+ }
493
+
494
+ /**
495
+ *
496
+ * @return {Monster.Components.Form.Select}
497
+ */
498
+ [assembleMethodSymbol]() {
499
+ const self = this;
500
+ super[assembleMethodSymbol]();
501
+
502
+ initControlReferences.call(self);
503
+ initEventhandler.call(self);
504
+
505
+ if (
506
+ self.getOption("url") !== null &&
507
+ self.getOption("features.loadOnOpen") !== true
508
+ ) {
509
+ self
510
+ .fetch()
511
+ .then(() => {
512
+ let result;
513
+ if (self.hasAttribute("value")) {
514
+ result = setSelection.call(self, self.getAttribute("value"));
515
+ } else {
516
+ result = setSelection.call(self, []);
517
+ }
518
+
519
+ result
520
+ .then(() => {})
521
+ .catch((e) => {
522
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
523
+ });
524
+ })
525
+ .catch((e) => {
526
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
527
+ throw e;
528
+ });
529
+ }
530
+
531
+ let lastValue = self.value;
532
+ self[internalSymbol].attachObserver(
533
+ new Observer(function () {
534
+ if (isObject(this) && this instanceof ProxyObserver) {
535
+ const n = this.getSubject()?.options?.value;
536
+
537
+ if (lastValue !== n) {
538
+ lastValue = n;
539
+ setSelection
540
+ .call(self, n)
541
+ .then(() => {})
542
+ .catch((e) => {
543
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, `${e}`);
544
+ });
545
+ }
546
+ }
547
+ }),
548
+ );
549
+
550
+ areOptionsAvailableAndInit.call(self);
551
+
552
+ return this;
553
+ }
554
+
555
+ /**
556
+ * The Button.click() method simulates a click on the internal button element.
557
+ *
558
+ * @since 3.27.0
559
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/click}
560
+ */
561
+ click() {;
562
+ if (this.getOption("disabled") === true) {
563
+ return;
564
+ }
565
+
566
+ toggle.call(this);
567
+ }
568
+
569
+ /**
570
+ * The Button.focus() method sets focus on the internal button element.
571
+ *
572
+ * @since 3.27.0
573
+ * @see {@link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus}
574
+ */
575
+ focus(options) {;
576
+ if (this.getOption("disabled") === true) {
577
+ return;
578
+ }
579
+
580
+ new Processing(() => {
581
+ gatherState.call(this);
582
+ focusFilter.call(this, options);
583
+ })
584
+ .run()
585
+ .catch((e) => {
586
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
587
+ });
588
+ }
589
+
590
+ /**
591
+ * The Button.blur() method removes focus from the internal button element.
592
+ * @link https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/blur
593
+ */
594
+ blur() {;
595
+ new Processing(() => {
596
+ gatherState.call(this);
597
+ blurFilter.call(this);
598
+ })
599
+ .run()
600
+ .catch((e) => {
601
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
602
+ });
603
+ }
604
+
605
+ /**
606
+ * If no url is specified, the options are taken from the Component itself.
607
+ *
608
+ * @param {string|URL} url URL to fetch the options
609
+ * @return {Promise}
610
+ */
611
+ fetch(url) {;
612
+
613
+ if (url instanceof URL) {
614
+ url = url.toString();
615
+ }
616
+
617
+ if (url !== undefined && url !== null) {
618
+ url = validateString(url);
619
+ }
620
+
621
+ return fetchData.call(this, url).then((map) => {
622
+ if (
623
+ isObject(map) ||
624
+ isArray(map) | (map instanceof Set) ||
625
+ map instanceof Map
626
+ ) {
627
+ this.importOptions(map);
628
+ }
629
+ });
630
+ }
631
+
632
+ /**
633
+ * @return {void}
634
+ */
635
+ connectedCallback() {
636
+ super.connectedCallback();
637
+ const document = getDocument();;
638
+
639
+ for (const [, type] of Object.entries(["click", "touch"])) {
640
+ // close on outside ui-events
641
+ document.addEventListener(type, this[closeEventHandler]);
642
+ }
643
+
644
+ parseSlotsToOptions.call(this);
645
+ attachResizeObserver.call(this);
646
+ updatePopper.call(this);
647
+
648
+ new Processing(() => {
649
+ gatherState.call(this);
650
+ focusFilter.call(this);
651
+ }).run();
652
+ }
653
+
654
+ /**
655
+ * @return {void}
656
+ */
657
+ disconnectedCallback() {
658
+ super.disconnectedCallback();
659
+ const document = getDocument();;
660
+
661
+ // close on outside ui-events
662
+ for (const [, type] of Object.entries(["click", "touch"])) {
663
+ document.removeEventListener(type, this[closeEventHandler]);
664
+ }
665
+
666
+ disconnectResizeObserver.call(this);
667
+ }
668
+
669
+ /**
670
+ * Import Select Options from dataset
671
+ * Not to be confused with the control defaults/options
672
+ *
673
+ * @since 0.16.0
674
+ * @param {array|object|Map|Set} data
675
+ * @return {Select}
676
+ * @throws {Error} map is not iterable
677
+ * @throws {Error} missing label configuration
678
+ */
679
+ importOptions(data) {;
680
+
681
+ const mappingOptions = this.getOption("mapping", {});
682
+ const selector = mappingOptions?.["selector"];
683
+ const labelTemplate = mappingOptions?.["labelTemplate"];
684
+ const valueTemplate = mappingOptions?.["valueTemplate"];
685
+ const filter = mappingOptions?.["filter"];
686
+
687
+ let flag = false;
688
+ if (labelTemplate === "") {
689
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "empty label template");
690
+ flag = true;
691
+ }
692
+
693
+ if (valueTemplate === "") {
694
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, "empty value template");
695
+ flag = true;
696
+ }
697
+
698
+ if (flag === true) {
699
+ throw new Error("missing label configuration");
700
+ }
701
+
702
+ const map = buildMap(data, selector, labelTemplate, valueTemplate, filter);
703
+
704
+ const options = [];
705
+ if (!isIterable(map)) {
706
+ throw new Error("map is not iterable");
707
+ }
708
+
709
+ const visibility = "visible";
710
+
711
+ map.forEach((label, value) => {
712
+ options.push({
713
+ value,
714
+ label,
715
+ visibility,
716
+ });
717
+ });
718
+
719
+ runAsOptionLengthChanged.call(this, map.size);
720
+ this.setOption("options", options);
721
+
722
+ fireCustomEvent(this, "monster-options-set", {
723
+ options,
724
+ });
725
+
726
+ return this;
727
+ }
728
+
729
+ /**
730
+ * @private
731
+ * @return {Monster.Components.Form.Select}
732
+ */
733
+ calcAndSetOptionsDimension() {
734
+ calcAndSetOptionsDimension.call(this);
735
+ return this;
736
+ }
737
+
738
+ /**
739
+ *
740
+ * @return {string}
741
+ */
742
+ static getTag() {
743
+ return "monster-select";
744
+ }
745
+
746
+ /**
747
+ *
748
+ * @return {CSSStyleSheet[]}
749
+ */
750
+ static getCSSStyleSheet() {
751
+ return [SelectStyleSheet];
752
+ }
753
+ }
754
+
755
+ /**
756
+ * This attribute can be used to pass a URL to this select.
757
+ *
758
+ * ```
759
+ * <monster-select data-monster-url="https://example.com/"></monster-select>
760
+ * ```
761
+ *
762
+ * @private
763
+ * @return {object}
764
+ */
765
+ function initOptionsFromArguments() {;
766
+ const options = {};
767
+
768
+ const template = this.getAttribute("data-monster-selected-template");
769
+ if (isString(template)) {
770
+ if (!options["templateMapping"]) options["templateMapping"] = {};
771
+
772
+ switch (template) {
773
+ case "summary":
774
+ case "default":
775
+ options["templateMapping"]["selected"] = getSummaryTemplate();
776
+ break;
777
+ case "selected":
778
+ options["templateMapping"]["selected"] = getSelectionTemplate();
779
+ break;
780
+ default:
781
+ addAttributeToken(
782
+ this,
783
+ ATTRIBUTE_ERRORMESSAGE,
784
+ "invalid template, use summary or selected",
785
+ );
786
+ }
787
+ }
788
+
789
+ return options;
790
+ }
791
+
792
+ /**
793
+ * @private
794
+ */
795
+ function attachResizeObserver() {;
796
+
797
+ // against flickering
798
+ this[resizeObserverSymbol] = new ResizeObserver((entries) => {
799
+ if (this[timerCallbackSymbol] instanceof DeadMansSwitch) {
800
+ try {
801
+ this[timerCallbackSymbol].touch();
802
+ return;
803
+ } catch (e) {
804
+ delete this[timerCallbackSymbol];
805
+ }
806
+ }
807
+
808
+ this[timerCallbackSymbol] = new DeadMansSwitch(200, () => {
809
+ updatePopper.call(this);
810
+ delete this[timerCallbackSymbol];
811
+ });
812
+ });
813
+
814
+ this[resizeObserverSymbol].observe(this.parentElement);
815
+ }
816
+
817
+ function disconnectResizeObserver() {;
818
+ if (this[resizeObserverSymbol] instanceof ResizeObserver) {
819
+ this[resizeObserverSymbol].disconnect();
820
+ }
821
+ }
822
+
823
+ function getSelectionTemplate() {
824
+ return `<div data-monster-role="selection"
825
+ data-monster-insert="selection path:selection" role="search"
826
+ ><input type="text" role="searchbox"
827
+ part="inline-filter" name="inline-filter"
828
+ data-monster-role="filter"
829
+ autocomplete="off"
830
+ tabindex="0"
831
+ ><div data-monster-replace="path:messages.control"></div>
832
+ </div>`;
833
+ }
834
+
835
+ function getSummaryTemplate() {
836
+ return `<div data-monster-role="selection" role="search">
837
+ <input type="text" role="searchbox"
838
+ part="inline-filter" name="inline-filter"
839
+ data-monster-role="filter"
840
+ autocomplete="off"
841
+ tabindex="0"
842
+ >
843
+ <div data-monster-replace="path:messages.selected"></div>
844
+ </div>`;
845
+ }
846
+
847
+ /**
848
+ * @return {void}
849
+ * @private
850
+ */
851
+ function parseSlotsToOptions() {;
852
+
853
+ let options = this.getOption("options");
854
+ if (!isIterable(options)) {
855
+ options = [];
856
+ }
857
+
858
+ let counter = 1;
859
+ getSlottedElements.call(this, "div").forEach((node) => {
860
+ let value = String(counter++);
861
+ let visibility = "visible";
862
+
863
+ if (node.hasAttribute("data-monster-value")) {
864
+ value = node.getAttribute("data-monster-value");
865
+ }
866
+
867
+ if (node.style.display === "none") {
868
+ visibility = "hidden";
869
+ }
870
+
871
+ const label = node.outerHTML;
872
+
873
+ options.push({
874
+ value,
875
+ label,
876
+ visibility,
877
+ });
878
+ });
879
+
880
+ runAsOptionLengthChanged.call(this, options.length);
881
+ this.setOption("options", options);
882
+ }
883
+
884
+ /**
885
+ * wait until all options are finished rendering
886
+ *
887
+ * @private
888
+ * @param {int} targetLength
889
+ */
890
+ function runAsOptionLengthChanged(targetLength) {
891
+ const self = this;
892
+
893
+ if (!self[optionsElementSymbol]) {
894
+ return;
895
+ }
896
+
897
+ const callback = function (mutationsList, observer) {
898
+ const run = false;
899
+ for (const mutation of mutationsList) {
900
+ if (mutation.type === "childList") {
901
+ const run = true;
902
+ break;
903
+ }
904
+ }
905
+
906
+ if (run === true) {
907
+ const nodes = self[optionsElementSymbol].querySelectorAll(
908
+ `div[${ATTRIBUTE_ROLE}=option]`,
909
+ );
910
+
911
+ if (nodes.length === targetLength) {
912
+ checkOptionState.call(self);
913
+ observer.disconnect();
914
+ }
915
+ }
916
+ };
917
+
918
+ const observer = new MutationObserver(callback);
919
+ observer.observe(self[optionsElementSymbol], {
920
+ attributes: false,
921
+ childList: true,
922
+ subtree: true,
923
+ });
924
+ }
925
+
926
+ /**
927
+ * @private
928
+ * @param {*} value
929
+ * @return {*}
930
+ */
931
+ function buildSelectionLabel(value) {;
932
+ const options = this.getOption("options");
933
+
934
+ for (let i = 0; i < options.length; i++) {
935
+ const o = options?.[i];
936
+ if (isObject(o) && o?.["value"] === value) {
937
+ return o?.["label"];
938
+ } else if (isPrimitive(o) && o === value) {
939
+ return o;
940
+ }
941
+ }
942
+
943
+ return undefined;
944
+ }
945
+
946
+ /**
947
+ * @private
948
+ * @param {*} value
949
+ * @return {string}
950
+ * @throws {Error} no value found
951
+ */
952
+ function getSelectionLabel(value) {;
953
+
954
+ const callback = this.getOption("formatter.selection");
955
+ if (isFunction(callback)) {
956
+ const label = callback.call(this, value);
957
+ if (isString(label)) return label;
958
+ }
959
+
960
+ if (isString(value) || isInteger(value)) {
961
+ return `${value}`;
962
+ }
963
+
964
+ return this.getOption("labels.cannot-be-loaded", value);
965
+ }
966
+
967
+ /**
968
+ * @private
969
+ * @param {Event} event
970
+ */
971
+ function handleToggleKeyboardEvents(event) {;
972
+
973
+ switch (event?.["code"]) {
974
+ case "Escape":
975
+ toggle.call(this);
976
+ event.preventDefault();
977
+ break;
978
+ case "Space":
979
+ toggle.call(this);
980
+ event.preventDefault();
981
+ break;
982
+ }
983
+ }
984
+
985
+ /**
986
+ * @license AGPLv3
987
+ * @since 1.15.0
988
+ * @private
989
+ * @this CustomElement
990
+ */
991
+ function initOptionObserver() {
992
+ const self = this;
993
+
994
+ self.attachObserver(
995
+ new Observer(function () {
996
+ new Processing(() => {
997
+ try {
998
+ self.updateI18n();
999
+ } catch (e) {}
1000
+ try {
1001
+ areOptionsAvailableAndInit.call(self);
1002
+ } catch (e) {}
1003
+
1004
+ setSummaryAndControlText.call(self);
1005
+ }).run();
1006
+ }),
1007
+ );
1008
+ }
1009
+
1010
+ function getDefaultTranslation() {;
1011
+
1012
+ const translation = new Translations("en").assignTranslations(
1013
+ this.getOption("labels", {}),
1014
+ );
1015
+
1016
+ try {
1017
+ const doc = getDocumentTranslations();
1018
+ translation.locale = doc.locale;
1019
+ } catch (e) {}
1020
+
1021
+ return translation;
1022
+ }
1023
+
1024
+ /**
1025
+ * @private
1026
+ * @returns {string|*}
1027
+ */
1028
+ function setSummaryAndControlText() {;
1029
+
1030
+ const translations = getDefaultTranslation.call(this);
1031
+ const selections = this.getOption("selection");
1032
+
1033
+ const text = translations.getPluralRuleText(
1034
+ "summary-text",
1035
+ selections.length,
1036
+ "",
1037
+ );
1038
+
1039
+ const selectedText = new Formatter({
1040
+ count: String(selections.length),
1041
+ }).format(text);
1042
+
1043
+ this.setOption("messages.selected", selectedText);
1044
+
1045
+ const current = this.getOption("messages.control");
1046
+ const msg = this.getOption("labels.select-an-option");
1047
+
1048
+ if (
1049
+ current === "" ||
1050
+ current === undefined ||
1051
+ current === msg ||
1052
+ current === null
1053
+ ) {
1054
+ if (selections === undefined || selections.length === 0) {
1055
+ this.setOption("messages.control", msg);
1056
+ } else {
1057
+ this.setOption("messages.control", "");
1058
+ }
1059
+ }
1060
+ }
1061
+
1062
+ /**
1063
+ * @private
1064
+ * @return {NodeList}
1065
+ */
1066
+ function getOptionElements() {
1067
+ return this[optionsElementSymbol].querySelectorAll(
1068
+ `[${ATTRIBUTE_ROLE}=option]`,
1069
+ );
1070
+ }
1071
+
1072
+ /**
1073
+ * With the help of this filter callback, values can be filtered out. Only if the filter function returns true, the value is taken for the map.
1074
+ *
1075
+ * @callback Monster.Components.Form~exampleFilterCallback
1076
+ * @param {*} value Value
1077
+ * @param {string} key Key
1078
+ * @memberOf Monster.Components.Form
1079
+ * @see Monster.Data.buildMap
1080
+ */
1081
+
1082
+ /**
1083
+ *
1084
+ * @callback Monster.Components.Form~formatterSelectionCallback
1085
+ * @param {*} value Value
1086
+ * @return {string|undefined}
1087
+ * @memberOf Monster.Components.Form
1088
+ * @see Monster.Data.buildMap
1089
+ */
1090
+
1091
+ /**
1092
+ * @private
1093
+ */
1094
+ function calcAndSetOptionsDimension() {;
1095
+
1096
+ const options = getOptionElements.call(this);
1097
+ const container = this[optionsElementSymbol];
1098
+ if (!(container instanceof HTMLElement && options instanceof NodeList)) {
1099
+ return;
1100
+ }
1101
+
1102
+ let visible = 0;
1103
+ let optionHeight = 0;
1104
+ const max = this.getOption("showMaxOptions", 10);
1105
+
1106
+ let scrollFlag = false;
1107
+ for (const [, option] of Object.entries(options)) {
1108
+ const computedStyle = getGlobal().getComputedStyle(option);
1109
+ if (computedStyle.display === "none") continue;
1110
+
1111
+ let h = option.getBoundingClientRect().height;
1112
+ h += parseInt(computedStyle.getPropertyValue("margin-top"), 10);
1113
+ h += parseInt(computedStyle.getPropertyValue("margin-bottom"), 10);
1114
+ optionHeight = Math.max(optionHeight, h);
1115
+
1116
+ visible++;
1117
+ if (visible > max) {
1118
+ break;
1119
+ }
1120
+ }
1121
+
1122
+ if (visible > max) {
1123
+ visible = max;
1124
+ scrollFlag = true;
1125
+ }
1126
+
1127
+ if (visible === 0) {
1128
+ if (this.getOption("options").length === 0) {
1129
+ this.setOption(
1130
+ "messages.emptyOptions",
1131
+ this.getOption("labels.no-options-available"),
1132
+ );
1133
+ } else {
1134
+ this.setOption(
1135
+ "messages.emptyOptions",
1136
+ this.getOption("labels.no-options-found"),
1137
+ );
1138
+ }
1139
+ this[noOptionsAvailableElementSymbol].classList.remove("d-none");
1140
+ } else {
1141
+ this[noOptionsAvailableElementSymbol].classList.add("d-none");
1142
+ }
1143
+
1144
+ const styles = getGlobal().getComputedStyle(this[optionsElementSymbol]);
1145
+ let padding = parseInt(styles.getPropertyValue("padding-top"), 10);
1146
+ padding += parseInt(styles.getPropertyValue("padding-bottom"), 10);
1147
+
1148
+ let margin = parseInt(styles.getPropertyValue("margin-top"), 10);
1149
+ margin += parseInt(styles.getPropertyValue("margin-bottom"), 10);
1150
+
1151
+ const containerHeight = optionHeight * visible + padding + margin;
1152
+ container.style.height = `${containerHeight}px`;
1153
+
1154
+ if (scrollFlag === true) {
1155
+ container.style.overflowY = "scroll";
1156
+ } else {
1157
+ container.style.overflowY = "auto";
1158
+ }
1159
+
1160
+ const domRect = this[controlElementSymbol].getBoundingClientRect();
1161
+
1162
+ this[popperElementSymbol].style.width = `${domRect.width}px`;
1163
+ container.style.overflowX = "auto";
1164
+ }
1165
+
1166
+ /**
1167
+ * @private
1168
+ * @param {number} direction
1169
+ * @throws {Error} no shadow-root is defined
1170
+ */
1171
+ function activateCurrentOption(direction) {;
1172
+
1173
+ if (!this.shadowRoot) {
1174
+ throw new Error("no shadow-root is defined");
1175
+ }
1176
+
1177
+ let focused = this.shadowRoot.querySelector(`[${ATTRIBUTE_PREFIX}focused]`);
1178
+
1179
+ if (
1180
+ !(focused instanceof HTMLElement) ||
1181
+ focused.matches("[data-monster-visibility=hidden]")
1182
+ ) {
1183
+ for (const [, e] of Object.entries(
1184
+ this.shadowRoot.querySelectorAll(`[${ATTRIBUTE_ROLE}=option]`),
1185
+ )) {
1186
+ if (e.matches("[data-monster-visibility=visible]")) {
1187
+ focused = e;
1188
+ break;
1189
+ }
1190
+ }
1191
+ } else {
1192
+ if (direction === FOCUS_DIRECTION_DOWN) {
1193
+ while (focused.nextSibling) {
1194
+ focused = focused.nextSibling;
1195
+
1196
+ if (
1197
+ focused instanceof HTMLElement &&
1198
+ focused.hasAttribute(ATTRIBUTE_ROLE) &&
1199
+ focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
1200
+ focused.matches("[data-monster-visibility=visible]") &&
1201
+ focused.matches(":not([data-monster-filtered=true])")
1202
+ ) {
1203
+ break;
1204
+ }
1205
+ }
1206
+ } else {
1207
+ while (focused.previousSibling) {
1208
+ focused = focused.previousSibling;
1209
+
1210
+ if (
1211
+ focused instanceof HTMLElement &&
1212
+ focused.hasAttribute(ATTRIBUTE_ROLE) &&
1213
+ focused.getAttribute(ATTRIBUTE_ROLE) === "option" &&
1214
+ focused.matches("[data-monster-visibility=visible]") &&
1215
+ focused.matches(":not([data-monster-filtered=true])")
1216
+ ) {
1217
+ break;
1218
+ }
1219
+ }
1220
+ }
1221
+ }
1222
+
1223
+ new Processing(() => {
1224
+ if (focused instanceof HTMLElement) {
1225
+ this.shadowRoot
1226
+ .querySelectorAll(`[${ATTRIBUTE_PREFIX}focused]`)
1227
+ .forEach((e) => {
1228
+ e.removeAttribute(`${ATTRIBUTE_PREFIX}focused`);
1229
+ });
1230
+
1231
+ focused.focus();
1232
+ focused.setAttribute(`${ATTRIBUTE_PREFIX}focused`, true);
1233
+ }
1234
+ }).run();
1235
+ }
1236
+
1237
+ /**
1238
+ * @private
1239
+ */
1240
+ function filterOptions() {;
1241
+
1242
+ new Processing(() => {
1243
+ let filterValue;
1244
+
1245
+ switch (this.getOption("filter.position")) {
1246
+ case FILTER_POSITION_INLINE:
1247
+ if (this[inlineFilterElementSymbol] instanceof HTMLElement) {
1248
+ filterValue = this[inlineFilterElementSymbol].value.toLowerCase();
1249
+ } else {
1250
+ return;
1251
+ }
1252
+
1253
+ break;
1254
+ case FILTER_POSITION_POPPER:
1255
+ default:
1256
+ if (this[popperFilterElementSymbol] instanceof HTMLInputElement) {
1257
+ filterValue = this[popperFilterElementSymbol].value.toLowerCase();
1258
+ } else {
1259
+ return;
1260
+ }
1261
+ }
1262
+
1263
+ const options = this.getOption("options");
1264
+ for (const [i, option] of Object.entries(options)) {
1265
+ if (option.label.toLowerCase().indexOf(filterValue) === -1) {
1266
+ this.setOption(`options.${i}.filtered`, "true");
1267
+ } else {
1268
+ this.setOption(`options.${i}.filtered`, undefined);
1269
+ }
1270
+ }
1271
+ })
1272
+ .run()
1273
+ .then(() => {
1274
+ new Processing(10, () => {
1275
+ calcAndSetOptionsDimension.call(this);
1276
+ focusFilter.call(this);
1277
+ }).run();
1278
+ })
1279
+ .catch((e) => {
1280
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1281
+ });
1282
+ }
1283
+
1284
+ /**
1285
+ * @private
1286
+ * @param {Event} event
1287
+ */
1288
+ function handleFilterKeyboardEvents(event) {;
1289
+
1290
+ const shiftKey = event?.["shiftKey"];
1291
+
1292
+ switch (event?.["code"]) {
1293
+ case "Tab":
1294
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1295
+ event.preventDefault();
1296
+ break;
1297
+ case "Escape":
1298
+ toggle.call(this);
1299
+ event.preventDefault();
1300
+ break;
1301
+ case "Tab" && shiftKey === true:
1302
+ case "ArrowUp":
1303
+ activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
1304
+ event.preventDefault();
1305
+ break;
1306
+ case "Tab" && !shiftKey:
1307
+ case "ArrowDown":
1308
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1309
+ event.preventDefault();
1310
+ break;
1311
+ default:
1312
+ if (this.getOption("filter.mode") !== FILTER_MODE_REMOTE) {
1313
+ filterOptions.call(this);
1314
+ } else {
1315
+ filterFromRemote.call(this).catch((e) => {
1316
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1317
+ });
1318
+ }
1319
+ }
1320
+ }
1321
+
1322
+ /**
1323
+ * @private
1324
+ */
1325
+ function filterFromRemote() {;
1326
+
1327
+ if (!(this[inlineFilterElementSymbol] instanceof HTMLElement)) {
1328
+ return;
1329
+ }
1330
+
1331
+ const optionUrl = this.getOption("url");
1332
+ if (!optionUrl) {
1333
+ addAttributeToken(
1334
+ this,
1335
+ ATTRIBUTE_ERRORMESSAGE,
1336
+ "Missing URL for Remote Filter.",
1337
+ );
1338
+ return;
1339
+ }
1340
+
1341
+ return new Processing(() => {
1342
+ const filterValue = encodeURI(
1343
+ this[inlineFilterElementSymbol].value.toLowerCase(),
1344
+ );
1345
+ let url = optionUrl;
1346
+ if (filterValue.length > 0) {
1347
+ url = new Formatter({ filter: filterValue }).format(optionUrl);
1348
+ }
1349
+
1350
+ this
1351
+ .fetch(url)
1352
+ .then(() => {
1353
+ checkOptionState.call(this);
1354
+ })
1355
+ .catch((e) => {
1356
+ throw e;
1357
+ });
1358
+ }).run();
1359
+ }
1360
+
1361
+ /**
1362
+ *
1363
+ * @param {Event} event
1364
+ * @private
1365
+ */
1366
+ function handleOptionKeyboardEvents(event) {;
1367
+
1368
+ const shiftKey = event?.["shiftKey"];
1369
+
1370
+ switch (event?.["code"]) {
1371
+ case "Escape":
1372
+ toggle.call(this);
1373
+ event.preventDefault();
1374
+ break;
1375
+ case "Enter":
1376
+ case "Space":
1377
+ const path = event.composedPath();
1378
+ const element = path?.[0];
1379
+
1380
+ fireEvent(element.getElementsByTagName("input"), "click");
1381
+ event.preventDefault();
1382
+ break;
1383
+
1384
+ case "Tab" && shiftKey === true:
1385
+ case "ArrowUp":
1386
+ activateCurrentOption.call(this, FOCUS_DIRECTION_UP);
1387
+ event.preventDefault();
1388
+ break;
1389
+
1390
+ case "Tab" && !shiftKey:
1391
+ case "ArrowLeft":
1392
+ case "ArrowRight":
1393
+ // handled by tree select
1394
+ break;
1395
+ case "ArrowDown":
1396
+ activateCurrentOption.call(this, FOCUS_DIRECTION_DOWN);
1397
+ event.preventDefault();
1398
+ break;
1399
+ default:
1400
+ const p = event.composedPath();
1401
+ if (p?.[0] instanceof HTMLInputElement) {
1402
+ return;
1403
+ }
1404
+ focusFilter.call(this);
1405
+ break;
1406
+ }
1407
+ }
1408
+
1409
+ /**
1410
+ * @private
1411
+ * @returns {string}
1412
+ */
1413
+ function getFilterMode() {;
1414
+
1415
+ switch (this.getOption("filter.mode")) {
1416
+ case FILTER_MODE_OPTIONS:
1417
+ return FILTER_MODE_OPTIONS;
1418
+ case FILTER_MODE_REMOTE:
1419
+ return FILTER_MODE_REMOTE;
1420
+ default:
1421
+ return FILTER_MODE_DISABLED;
1422
+ }
1423
+ }
1424
+
1425
+ /**
1426
+ * @private
1427
+ */
1428
+ function blurFilter() {;
1429
+
1430
+ if (!(this[inlineFilterElementSymbol] instanceof HTMLElement)) {
1431
+ return;
1432
+ }
1433
+
1434
+ if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
1435
+ return;
1436
+ }
1437
+
1438
+ this[popperFilterContainerElementSymbol].classList.remove("active");
1439
+ this[popperFilterContainerElementSymbol].blur();
1440
+
1441
+ this[inlineFilterElementSymbol].classList.remove("active");
1442
+ this[inlineFilterElementSymbol].blur();
1443
+ }
1444
+
1445
+ /**
1446
+ * @private
1447
+ * @param focusOptions
1448
+ */
1449
+ function focusPopperFilter(focusOptions) {;
1450
+
1451
+ this[popperFilterContainerElementSymbol].classList.remove("d-none");
1452
+ this[popperFilterElementSymbol].classList.add("active");
1453
+ this[inlineFilterElementSymbol].classList.remove("active");
1454
+ this[inlineFilterElementSymbol].classList.add("d-none");
1455
+
1456
+ if (!(this[popperFilterElementSymbol] instanceof HTMLElement)) {
1457
+ addAttributeToken(
1458
+ this,
1459
+ ATTRIBUTE_ERRORMESSAGE,
1460
+ "Missing Popper Filter Element.",
1461
+ );
1462
+ return;
1463
+ }
1464
+
1465
+ // visibility is set to visible, because focus() does not work on invisible elements
1466
+ // and the class definition is assigned later in the processing
1467
+ setTimeout(() => {
1468
+ if (focusOptions === undefined || focusOptions === null) {
1469
+ this[popperFilterElementSymbol].focus();
1470
+ } else {
1471
+ this[popperFilterElementSymbol].focus(focusOptions);
1472
+ }
1473
+ }, 100);
1474
+ }
1475
+
1476
+ /**
1477
+ * @private
1478
+ * @param focusOptions
1479
+ */
1480
+ function focusInlineFilter(focusOptions) {;
1481
+
1482
+ const options = this.getOption("options");
1483
+ if (
1484
+ (!isArray(options) || options.length === 0) &&
1485
+ this.getOption("filter.mode") !== FILTER_MODE_REMOTE
1486
+ ) {
1487
+ return;
1488
+ }
1489
+
1490
+ this[popperFilterContainerElementSymbol].classList.add("d-none");
1491
+ this[inlineFilterElementSymbol].classList.add("active");
1492
+ this[inlineFilterElementSymbol].classList.remove("d-none");
1493
+
1494
+ // visibility is set to visible, because focus() does not work on invisible elements
1495
+ // and the class definition is assigned later in the processing
1496
+ setTimeout(() => {
1497
+ if (focusOptions === undefined || focusOptions === null) {
1498
+ this[inlineFilterElementSymbol].focus();
1499
+ } else {
1500
+ this[inlineFilterElementSymbol].focus(focusOptions);
1501
+ }
1502
+ }, 100);
1503
+ }
1504
+
1505
+ /**
1506
+ * @private
1507
+ */
1508
+ function focusFilter(focusOptions) {;
1509
+
1510
+ if (getFilterMode.call(this) === FILTER_MODE_DISABLED) {
1511
+ this[popperFilterContainerElementSymbol].classList.add("d-none");
1512
+ this[inlineFilterElementSymbol].classList.add("d-none");
1513
+ return;
1514
+ }
1515
+
1516
+ if (this.getOption("filter.position") === FILTER_POSITION_INLINE) {
1517
+ return focusInlineFilter.call(this, focusOptions);
1518
+ }
1519
+
1520
+ return focusPopperFilter.call(this, focusOptions);
1521
+ }
1522
+
1523
+ /**
1524
+ * @private
1525
+ * @return {array}
1526
+ * @throws {Error} no shadow-root is defined
1527
+ * @throws {Error} unsupported type
1528
+ */
1529
+ function gatherState() {;
1530
+
1531
+ const type = this.getOption("type");
1532
+ if (["radio", "checkbox"].indexOf(type) === -1) {
1533
+ throw new Error("unsupported type");
1534
+ }
1535
+
1536
+ if (!this.shadowRoot) {
1537
+ throw new Error("no shadow-root is defined");
1538
+ }
1539
+
1540
+ const selection = [];
1541
+ const elements = this.shadowRoot.querySelectorAll(
1542
+ `input[type=${type}]:checked`,
1543
+ );
1544
+ for (const e of elements) {
1545
+ selection.push({
1546
+ label: getSelectionLabel.call(this, e.value),
1547
+ value: e.value,
1548
+ });
1549
+ }
1550
+
1551
+ setSelection
1552
+ .call(this, selection)
1553
+ .then(() => {})
1554
+ .catch((e) => {
1555
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
1556
+ });
1557
+
1558
+ return this;
1559
+ }
1560
+
1561
+ /**
1562
+ * @private
1563
+ * @throws {Error} no shadow-root is defined
1564
+ * @throws {Error} unsupported type
1565
+ */
1566
+ function clearSelection() {;
1567
+
1568
+ const type = this.getOption("type");
1569
+ if (["radio", "checkbox"].indexOf(type) === -1) {
1570
+ throw new Error("unsupported type");
1571
+ }
1572
+
1573
+ if (!this.shadowRoot) {
1574
+ throw new Error("no shadow-root is defined");
1575
+ }
1576
+
1577
+ setSelection
1578
+ .call(this, [])
1579
+ .then(() => {})
1580
+ .catch((e) => {
1581
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, `${e}`);
1582
+ });
1583
+ }
1584
+
1585
+ /**
1586
+ * @private
1587
+ */
1588
+ function areOptionsAvailableAndInit() {;
1589
+
1590
+ // prevent multiple calls
1591
+ if (this[areOptionsAvailableAndInitSymbol] === undefined) {
1592
+ this[areOptionsAvailableAndInitSymbol] = 0;
1593
+ }
1594
+
1595
+ if (this[areOptionsAvailableAndInitSymbol] > 0) {
1596
+ this[areOptionsAvailableAndInitSymbol]--;
1597
+ return true;
1598
+ }
1599
+
1600
+ this[areOptionsAvailableAndInitSymbol]++;
1601
+
1602
+ const options = this.getOption("options");
1603
+
1604
+ if (
1605
+ options === undefined ||
1606
+ options === null ||
1607
+ (isArray(options) && options.length === 0)
1608
+ ) {
1609
+ setStatusOrRemoveBadges.call(this, "empty");
1610
+
1611
+ hide.call(this);
1612
+
1613
+ this.setOption(
1614
+ "messages.control",
1615
+ this.getOption("labels.no-options-available"),
1616
+ );
1617
+ this.setOption("messages.summary", "");
1618
+ this.setOption("selection", []);
1619
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, noOptionsAvailableMessage);
1620
+ return false;
1621
+ }
1622
+
1623
+ const selections = this.getOption("selection");
1624
+ if (
1625
+ selections === undefined ||
1626
+ selections === null ||
1627
+ selections.length === 0
1628
+ ) {
1629
+ this.setOption(
1630
+ "messages.control",
1631
+ this.getOption("labels.select-an-option"),
1632
+ );
1633
+ } else {
1634
+ this.setOption("messages.control", "");
1635
+ }
1636
+
1637
+ this.setOption("messages.summary", setSummaryAndControlText.call(this));
1638
+
1639
+ let updated = false;
1640
+ let valueCounter = 1;
1641
+ for (const option of options) {
1642
+ if (option?.visibility === undefined) {
1643
+ option.visibility = "visible";
1644
+ updated = true;
1645
+ }
1646
+
1647
+ if (option?.value === undefined && option?.label === undefined) {
1648
+ option.value = `${valueCounter++}`;
1649
+ option.label = option.value;
1650
+ updated = true;
1651
+ continue;
1652
+ }
1653
+
1654
+ if (option?.value === undefined) {
1655
+ option.value = option.label;
1656
+ updated = true;
1657
+ }
1658
+
1659
+ if (option?.label === undefined) {
1660
+ option.label = option.value;
1661
+ updated = true;
1662
+ }
1663
+ }
1664
+
1665
+ if (updated) {
1666
+ this.setOption("options", options);
1667
+ }
1668
+
1669
+ setStatusOrRemoveBadges.call(this, "status");
1670
+
1671
+ removeAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, noOptionsAvailableMessage);
1672
+ return true;
1673
+ }
1674
+
1675
+ /**
1676
+ * @private
1677
+ * @throws {Error} no shadow-root is defined
1678
+ */
1679
+ function checkOptionState() {;
1680
+
1681
+ if (!this.shadowRoot) {
1682
+ throw new Error("no shadow-root is defined");
1683
+ }
1684
+
1685
+ const elements = this.shadowRoot.querySelectorAll(
1686
+ `[${ATTRIBUTE_ROLE}=option] input`,
1687
+ );
1688
+
1689
+ let selection = this.getOption("selection");
1690
+ if (!isArray(selection)) {
1691
+ selection = [];
1692
+ }
1693
+
1694
+ const checkedValues = selection.map((a) => {
1695
+ return a.value;
1696
+ });
1697
+
1698
+ for (const e of elements) {
1699
+ if (checkedValues.indexOf(e.value) !== -1) {
1700
+ if (e.checked !== true) e.checked = true;
1701
+ } else {
1702
+ if (e.checked !== false) e.checked = false;
1703
+ }
1704
+ }
1705
+ }
1706
+
1707
+ /**
1708
+ * @private
1709
+ * @param {*} value
1710
+ * @return {Object}
1711
+ */
1712
+ function convertValueToSelection(value) {;
1713
+ const selection = [];
1714
+
1715
+ if (isString(value)) {
1716
+ value = value
1717
+ .split(",")
1718
+ .map((a) => {
1719
+ return a.trim();
1720
+ })
1721
+ .filter((a) => {
1722
+ return a !== "";
1723
+ });
1724
+ }
1725
+
1726
+ if (isString(value) || isInteger(value)) {
1727
+ selection.push({
1728
+ label: getSelectionLabel.call(this, value),
1729
+ value: value,
1730
+ });
1731
+ } else if (isArray(value)) {
1732
+ for (const v of value) {
1733
+ selection.push({
1734
+ label: getSelectionLabel.call(this, v),
1735
+ value: v,
1736
+ });
1737
+ }
1738
+
1739
+ value = value.join(",");
1740
+ } else {
1741
+ throw new Error("unsupported type");
1742
+ }
1743
+
1744
+ return {
1745
+ selection: selection,
1746
+ value: value,
1747
+ };
1748
+ }
1749
+
1750
+ /**
1751
+ * @private
1752
+ * @param {array} selection
1753
+ * @return {string}
1754
+ */
1755
+ function convertSelectionToValue(selection) {;
1756
+
1757
+ const value = [];
1758
+
1759
+ if (isArray(selection)) {
1760
+ for (const obj of selection) {
1761
+ const v = obj?.["value"];
1762
+ if (v !== undefined) value.push(v);
1763
+ }
1764
+ }
1765
+
1766
+ if (value.length === 0) {
1767
+ return "";
1768
+ } else if (value.length === 1) {
1769
+ return value.pop();
1770
+ }
1771
+
1772
+ return value.join(",");
1773
+ }
1774
+
1775
+ /**
1776
+ * @private
1777
+ * @param {array} selection
1778
+ * @return {Promise}
1779
+ * @throws {Error} no shadow-root is defined
1780
+ */
1781
+ function setSelection(selection) {;
1782
+
1783
+ if (isString(selection)) {
1784
+ const result = convertValueToSelection.call(this, selection);
1785
+ selection = result?.selection;
1786
+ } else if (selection === undefined) {
1787
+ selection = [];
1788
+ }
1789
+
1790
+ this.setOption("selection", validateArray(selection));
1791
+ checkOptionState.call(this);
1792
+
1793
+ try {
1794
+ this?.setFormValue(this.value);
1795
+ } catch (e) {
1796
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1797
+ }
1798
+
1799
+ fireCustomEvent(this, "monster-selected", {
1800
+ selection,
1801
+ });
1802
+
1803
+ return new Processing(() => {
1804
+ const CLASSNAME = "selected";
1805
+
1806
+ if (!this.shadowRoot) {
1807
+ throw new Error("no shadow-root is defined");
1808
+ }
1809
+
1810
+ const notSelected = this.shadowRoot.querySelectorAll(":not(:checked)");
1811
+
1812
+ if (notSelected) {
1813
+ notSelected.forEach((node) => {
1814
+ const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
1815
+ if (parent) {
1816
+ parent.classList.remove(CLASSNAME);
1817
+ }
1818
+ });
1819
+ }
1820
+
1821
+ const selected = this.shadowRoot.querySelectorAll(":checked");
1822
+ if (selected) {
1823
+ selected.forEach((node) => {
1824
+ const parent = node.closest(`[${ATTRIBUTE_ROLE}=option]`);
1825
+ if (parent) {
1826
+ parent.classList.add(CLASSNAME);
1827
+ }
1828
+ });
1829
+ }
1830
+ }).run();
1831
+ }
1832
+
1833
+ /**
1834
+ * @private
1835
+ * @param {string} url
1836
+ * @return {Promise}
1837
+ * @throws {TypeError} the result cannot be parsed
1838
+ * @throws {TypeError} unsupported response
1839
+ */
1840
+ function fetchData(url) {;
1841
+
1842
+ if (!url) url = this.getOption("url");
1843
+ if (!url) return Promise.resolve();
1844
+
1845
+ const fetchOptions = this.getOption("fetch", {});
1846
+
1847
+ setStatusOrRemoveBadges.call(this, "loading");
1848
+ url = new Formatter({ filter: this.getOption("filter.defaultValue") }).format(
1849
+ url,
1850
+ );
1851
+
1852
+ const global = getGlobal();
1853
+ return global
1854
+ .fetch(url, fetchOptions)
1855
+ .then((response) => {
1856
+ const contentType = response.headers.get("content-type");
1857
+ if (contentType && contentType.indexOf("application/json") !== -1) {
1858
+ return response.text();
1859
+ }
1860
+
1861
+ throw new TypeError(`unsupported response ${contentType}`);
1862
+ })
1863
+ .then((text) => {
1864
+ try {
1865
+ return Promise.resolve(JSON.parse(String(text)));
1866
+ } catch (e) {
1867
+ throw new TypeError("the result cannot be parsed");
1868
+ }
1869
+ });
1870
+ }
1871
+
1872
+ /**
1873
+ * @private
1874
+ */
1875
+ function hide() {;
1876
+
1877
+ this[popperElementSymbol].style.display = "none";
1878
+ setStatusOrRemoveBadges.call(this, "status");
1879
+ removeAttributeToken(this[controlElementSymbol], "class", "open");
1880
+ }
1881
+
1882
+ /**
1883
+ * @private
1884
+ */
1885
+ function show() {;
1886
+
1887
+ if (this.getOption("disabled", undefined) === true) {
1888
+ return;
1889
+ }
1890
+
1891
+ if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
1892
+ return;
1893
+ }
1894
+
1895
+ focusFilter.call(this);
1896
+ const optionsAvailable = areOptionsAvailableAndInit.call(this);
1897
+ const remoteFilterFlag = this.getOption("filter.mode") === FILTER_MODE_REMOTE;
1898
+
1899
+ if (optionsAvailable === false && remoteFilterFlag !== true) {
1900
+ const loadOnOpenFlag = this.getOption("features.loadOnOpen");
1901
+ if (loadOnOpenFlag === true) {
1902
+ this.setOption("features.loadOnOpen", false);
1903
+ this.setOption("classes.statusOrRemoveBadge", "loading");
1904
+ this.fetch().then(() => {
1905
+ show.call(this);
1906
+ });
1907
+ }
1908
+
1909
+ return;
1910
+ }
1911
+
1912
+ this[popperElementSymbol].style.visibility = "hidden";
1913
+ this[popperElementSymbol].style.display = STYLE_DISPLAY_MODE_BLOCK;
1914
+ setStatusOrRemoveBadges.call(this, "open");
1915
+
1916
+ addAttributeToken(this[controlElementSymbol], "class", "open");
1917
+
1918
+ new Processing(() => {
1919
+ calcAndSetOptionsDimension.call(this);
1920
+ focusFilter.call(this);
1921
+ this[popperElementSymbol].style.removeProperty("visibility");
1922
+ updatePopper.call(this);
1923
+ })
1924
+ .run()
1925
+ .catch((e) => {
1926
+ addAttributeToken(this, ATTRIBUTE_ERRORMESSAGE, e.message);
1927
+ });
1928
+ }
1929
+
1930
+ /**
1931
+ * @private
1932
+ */
1933
+ function toggle() {
1934
+ if (this[popperElementSymbol].style.display === STYLE_DISPLAY_MODE_BLOCK) {
1935
+ hide.call(this);
1936
+ } else {
1937
+ show.call(this);
1938
+ }
1939
+ }
1940
+
1941
+ /**
1942
+ * @private
1943
+ * @fires Monster.Components.Form.event:monster-selection-removed
1944
+ * @fires Monster.Components.Form.event:monster-selection-cleared
1945
+ */
1946
+ function initEventhandler() {
1947
+ const self = this;
1948
+
1949
+ /**
1950
+ * @param {Event} event
1951
+ */
1952
+ self[clearOptionEventHandler] = (event) => {
1953
+ const element = findTargetElementFromEvent(
1954
+ event,
1955
+ ATTRIBUTE_ROLE,
1956
+ "remove-badge",
1957
+ );
1958
+ if (element instanceof HTMLElement) {
1959
+ const badge = findClosestByAttribute(element, ATTRIBUTE_ROLE, "badge");
1960
+ if (badge instanceof HTMLElement) {
1961
+ const value = badge.getAttribute(`${ATTRIBUTE_PREFIX}value`);
1962
+
1963
+ let selection = self.getOption("selection");
1964
+ selection = selection.filter((b) => {
1965
+ return value !== b.value;
1966
+ });
1967
+
1968
+ setSelection
1969
+ .call(self, selection)
1970
+ .then(() => {
1971
+ fireCustomEvent(self, "monster-selection-removed", {
1972
+ value,
1973
+ });
1974
+ })
1975
+ .catch((e) => {
1976
+ addAttributeToken(self, ATTRIBUTE_ERRORMESSAGE, e.message);
1977
+ });
1978
+ }
1979
+ }
1980
+ };
1981
+
1982
+ /**
1983
+ * @param {Event} event
1984
+ */
1985
+ self[closeEventHandler] = (event) => {
1986
+ const path = event.composedPath();
1987
+
1988
+ for (const [, element] of Object.entries(path)) {
1989
+ if (element === self) {
1990
+ return;
1991
+ }
1992
+ }
1993
+ hide.call(self);
1994
+ };
1995
+
1996
+ /**
1997
+ * @param {Event} event
1998
+ */
1999
+ self[inputEventHandler] = (event) => {
2000
+ const path = event.composedPath();
2001
+ const element = path?.[0];
2002
+
2003
+ if (element instanceof HTMLElement) {
2004
+ if (
2005
+ element.hasAttribute(ATTRIBUTE_ROLE) &&
2006
+ element.getAttribute(ATTRIBUTE_ROLE) === "option-control"
2007
+ ) {
2008
+ fireCustomEvent(self, "monster-change", {
2009
+ type: event.type,
2010
+ value: element.value,
2011
+ checked: element.checked,
2012
+ });
2013
+ } else if (
2014
+ element.hasAttribute(ATTRIBUTE_ROLE) &&
2015
+ element.getAttribute(ATTRIBUTE_ROLE) === "filter"
2016
+ ) {
2017
+ }
2018
+ }
2019
+ };
2020
+
2021
+ /**
2022
+ * @param {Event} event
2023
+ */
2024
+ self[changeEventHandler] = (event) => {
2025
+ gatherState.call(self);
2026
+ fireCustomEvent(self, "monster-changed", event?.detail);
2027
+ };
2028
+
2029
+ self[keyEventHandler] = (event) => {
2030
+ const path = event.composedPath();
2031
+ const element = path.shift();
2032
+
2033
+ let role;
2034
+
2035
+ if (element instanceof HTMLElement) {
2036
+ if (element.hasAttribute(ATTRIBUTE_ROLE)) {
2037
+ role = element.getAttribute(ATTRIBUTE_ROLE);
2038
+ } else if (element === this) {
2039
+ show.call(this);
2040
+ // focusFilter.call(self);
2041
+ } else {
2042
+ const e = element.closest(`[${ATTRIBUTE_ROLE}]`);
2043
+ if (e instanceof HTMLElement && e.hasAttribute(ATTRIBUTE_ROLE)) {
2044
+ role = e.getAttribute(ATTRIBUTE_ROLE);
2045
+ }
2046
+ }
2047
+ } else {
2048
+ return;
2049
+ }
2050
+
2051
+ switch (role) {
2052
+ case "filter":
2053
+ handleFilterKeyboardEvents.call(self, event);
2054
+ break;
2055
+ case "option-label":
2056
+ case "option-control":
2057
+ case "option":
2058
+ handleOptionKeyboardEvents.call(self, event);
2059
+ break;
2060
+ case "control":
2061
+ case "toggle":
2062
+ handleToggleKeyboardEvents.call(self, event);
2063
+ break;
2064
+ }
2065
+ };
2066
+
2067
+ const types = self.getOption("toggleEventType", ["click"]);
2068
+
2069
+ for (const [, type] of Object.entries(types)) {
2070
+ self[controlElementSymbol]
2071
+ .querySelector(`[${ATTRIBUTE_ROLE}="container"]`)
2072
+ .addEventListener(type, function (event) {
2073
+ const element = findTargetElementFromEvent(
2074
+ event,
2075
+ ATTRIBUTE_ROLE,
2076
+ "remove-badge",
2077
+ );
2078
+ if (element instanceof HTMLElement) {
2079
+ return;
2080
+ }
2081
+
2082
+ toggle.call(self);
2083
+ });
2084
+
2085
+ self[controlElementSymbol]
2086
+ .querySelector(`[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`)
2087
+ .addEventListener(type, function (event) {
2088
+ if (self.getOption("disabled", undefined) === true) {
2089
+ return;
2090
+ }
2091
+
2092
+ const path = event.composedPath();
2093
+ const element = path?.[0];
2094
+ if (element instanceof HTMLElement) {
2095
+ const control = element.closest(
2096
+ `[${ATTRIBUTE_ROLE}="status-or-remove-badges"]`,
2097
+ );
2098
+ if (control instanceof HTMLElement) {
2099
+ if (control.classList.contains("clear")) {
2100
+ clearSelection.call(self);
2101
+
2102
+ fireCustomEvent(self, "monster-selection-cleared", {});
2103
+ } else {
2104
+ const element = findTargetElementFromEvent(
2105
+ event,
2106
+ ATTRIBUTE_ROLE,
2107
+ "remove-badge",
2108
+ );
2109
+ if (element instanceof HTMLElement) {
2110
+ return;
2111
+ }
2112
+
2113
+ toggle.call(self);
2114
+ }
2115
+ }
2116
+ }
2117
+ });
2118
+
2119
+ // badge, selection
2120
+ self.addEventListener(type, self[clearOptionEventHandler]);
2121
+ }
2122
+
2123
+ self.addEventListener("monster-change", self[changeEventHandler]);
2124
+ self.addEventListener("input", self[inputEventHandler]);
2125
+ self.addEventListener("keydown", self[keyEventHandler]);
2126
+
2127
+ return self;
2128
+ }
2129
+
2130
+ /**
2131
+ * @private
2132
+ * @return {Select}
2133
+ */
2134
+ function setStatusOrRemoveBadges(suggestion) {;
2135
+ setTimeout(() => {
2136
+ const selection = this.getOption("selection");
2137
+ const clearAllFlag =
2138
+ isArray(selection) &&
2139
+ selection.length > 0 &&
2140
+ this.getOption("features.clearAll") === true;
2141
+
2142
+ if (clearAllFlag) {
2143
+ //this[statusOrRemoveBadgesElementSymbol].classList.remove("status");
2144
+ //this[statusOrRemoveBadgesElementSymbol].classList.add("clear");
2145
+ this.setOption("classes.statusOrRemoveBadge", "clear");
2146
+ return;
2147
+ }
2148
+
2149
+ if (suggestion === "loading") {
2150
+ this.setOption("classes.statusOrRemoveBadge", "loading");
2151
+ return;
2152
+ }
2153
+
2154
+ if (this[controlElementSymbol].classList.contains("open")) {
2155
+ this.setOption("classes.statusOrRemoveBadge", "open");
2156
+ return;
2157
+ }
2158
+
2159
+ const options = this.getOption("options");
2160
+ if (
2161
+ options === undefined ||
2162
+ options === null ||
2163
+ (isArray(options) && options.length === 0)
2164
+ ) {
2165
+ this.setOption("classes.statusOrRemoveBadge", "empty");
2166
+ return;
2167
+ }
2168
+
2169
+ if (suggestion) {
2170
+ this.setOption("classes.statusOrRemoveBadge", suggestion);
2171
+ return;
2172
+ }
2173
+ }, 2);
2174
+ }
2175
+
2176
+ /**
2177
+ * @private
2178
+ * @return {Select}
2179
+ * @throws {Error} no shadow-root is defined
2180
+ */
2181
+ function initControlReferences() {;
2182
+
2183
+ if (!this.shadowRoot) {
2184
+ throw new Error("no shadow-root is defined");
2185
+ }
2186
+
2187
+ this[controlElementSymbol] = this.shadowRoot.querySelector(
2188
+ `[${ATTRIBUTE_ROLE}=control]`,
2189
+ );
2190
+ this[selectionElementSymbol] = this.shadowRoot.querySelector(
2191
+ `[${ATTRIBUTE_ROLE}=selection]`,
2192
+ );
2193
+ this[containerElementSymbol] = this.shadowRoot.querySelector(
2194
+ `[${ATTRIBUTE_ROLE}=container]`,
2195
+ );
2196
+ this[popperElementSymbol] = this.shadowRoot.querySelector(
2197
+ `[${ATTRIBUTE_ROLE}=popper]`,
2198
+ );
2199
+ this[inlineFilterElementSymbol] = this.shadowRoot.querySelector(
2200
+ `[${ATTRIBUTE_ROLE}=filter][name="inline-filter"]`,
2201
+ );
2202
+ this[popperFilterElementSymbol] = this.shadowRoot.querySelector(
2203
+ `[${ATTRIBUTE_ROLE}=filter][name="popper-filter"]`,
2204
+ );
2205
+ this[popperFilterContainerElementSymbol] =
2206
+ this[popperFilterElementSymbol].parentElement;
2207
+ this[optionsElementSymbol] = this.shadowRoot.querySelector(
2208
+ `[${ATTRIBUTE_ROLE}=options]`,
2209
+ );
2210
+ this[noOptionsAvailableElementSymbol] = this.shadowRoot.querySelector(
2211
+ `[${ATTRIBUTE_ROLE}="no-options"]`,
2212
+ );
2213
+ this[statusOrRemoveBadgesElementSymbol] = this.shadowRoot.querySelector(
2214
+ `[${ATTRIBUTE_ROLE}=status-or-remove-badges]`,
2215
+ );
2216
+ }
2217
+
2218
+ /**
2219
+ * @private
2220
+ */
2221
+ function updatePopper() {;
2222
+
2223
+ if (this[popperElementSymbol].style.display !== STYLE_DISPLAY_MODE_BLOCK) {
2224
+ return;
2225
+ }
2226
+
2227
+ if (this.getOption("disabled", false) === true) {
2228
+ return;
2229
+ }
2230
+
2231
+ new Processing(() => {
2232
+ calcAndSetOptionsDimension.call(this);
2233
+ positionPopper.call(
2234
+ this,
2235
+ this[controlElementSymbol],
2236
+ this[popperElementSymbol],
2237
+ this.getOption("popper", {}),
2238
+ );
2239
+ }).run();
2240
+
2241
+ return this;
2242
+ }
2243
+
2244
+ /**
2245
+ * @private
2246
+ * @return {string}
2247
+ */
2248
+ function getTemplate() {
2249
+ // language=HTML
2250
+ return `
2251
+ <template id="options">
2252
+ <div data-monster-role="option" tabindex="-1"
2253
+ data-monster-attributes="
2254
+ data-monster-filtered path:options.filtered,
2255
+ data-monster-visibility path:options.visibility">
2256
+ <label part="option" role="option">
2257
+ <input data-monster-role="option-control"
2258
+ data-monster-attributes="
2259
+ type path:type,
2260
+ role path:role,
2261
+ value path:options | index:value,
2262
+ name path:name,
2263
+ part path:type | prefix:option- | suffix: form,
2264
+ class path:options.class
2265
+ " tabindex="-1">
2266
+ <div data-monster-replace="path:options | index:label" part="option-label"></div>
2267
+ </label>
2268
+ </div>
2269
+ </template>
2270
+
2271
+ <template id="selection">
2272
+ <div data-monster-role="badge"
2273
+ part="badge"
2274
+ data-monster-attributes="
2275
+ data-monster-value path:selection | index:value,
2276
+ class path:classes | index:badge,
2277
+ part path:type | suffix:-option | prefix: form-" tabindex="-1">
2278
+ <div data-monster-replace="path:selection | index:label" part="badge-label"
2279
+ data-monster-role="badge-label"></div>
2280
+ <div part="remove-badge" data-monster-select-this
2281
+ data-monster-attributes="class path:features.clear | ?::hidden "
2282
+ data-monster-role="remove-badge" tabindex="-1"></div>
2283
+ </div>
2284
+ </template>
2285
+
2286
+ <slot class="hidden"></slot>
2287
+
2288
+ <div data-monster-role="control" part="control" tabindex="0">
2289
+ <div data-monster-role="container">
2290
+ \${selected}
2291
+ </div>
2292
+
2293
+ <div data-monster-role="popper" part="popper" tabindex="-1" class="monster-color-primary-1">
2294
+ <div class="option-filter-control" role="search">
2295
+ <input type="text" role="searchbox"
2296
+ part="popper-filter" name="popper-filter"
2297
+ data-monster-role="filter"
2298
+ autocomplete="off"
2299
+ tabindex="0">
2300
+ </div>
2301
+ <div part="content" class="flex" data-monster-replace="path:content">
2302
+ <div part="options" data-monster-role="options" data-monster-insert="options path:options"
2303
+ tabindex="-1"></div>
2304
+ </div>
2305
+ <div part="no-options" data-monster-role="no-options"
2306
+ data-monster-replace="path:messages.emptyOptions"></div>
2307
+ </div>
2308
+ <div part="status-or-remove-badges" data-monster-role="status-or-remove-badges"
2309
+ data-monster-attributes="class path:classes.statusOrRemoveBadge | suffix:\\ status-or-remove-badges"></div>
2310
+ </div>
2311
+ `;
2312
+ }
2313
+
2314
+ registerCustomElement(Select);