@schukai/monster 3.51.5 → 3.52.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (361) hide show
  1. package/CHANGELOG.md +25 -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/example/data/datasource/server/restapi.mjs +7 -1
  12. package/package.json +6 -2
  13. package/source/components/constants.mjs +132 -0
  14. package/source/components/datatable/columnbar.mjs +310 -0
  15. package/source/components/datatable/constants.mjs +121 -0
  16. package/source/components/datatable/dataset.mjs +219 -0
  17. package/source/components/datatable/datasource/dom.mjs +186 -0
  18. package/source/components/datatable/datasource/namespace.mjs +13 -0
  19. package/source/components/datatable/datasource/rest.mjs +400 -0
  20. package/source/components/datatable/datasource.mjs +102 -0
  21. package/source/components/datatable/datatable/header.mjs +268 -0
  22. package/source/components/datatable/datatable/namespace.mjs +13 -0
  23. package/source/components/datatable/datatable.mjs +789 -0
  24. package/source/components/datatable/embedded-pagination.mjs +113 -0
  25. package/source/components/datatable/filter/abstract-base.mjs +31 -0
  26. package/source/components/datatable/filter/date-range.mjs +1041 -0
  27. package/source/components/datatable/filter/input.mjs +175 -0
  28. package/source/components/datatable/filter/namespace.mjs +13 -0
  29. package/source/components/datatable/filter/range.mjs +671 -0
  30. package/source/components/datatable/filter/select.mjs +65 -0
  31. package/source/components/datatable/filter/settings.mjs +116 -0
  32. package/source/components/datatable/filter-button.mjs +98 -0
  33. package/source/components/datatable/filter.mjs +929 -0
  34. package/source/components/datatable/namespace.mjs +11 -0
  35. package/source/components/datatable/pagination.mjs +456 -0
  36. package/source/components/datatable/style/column-bar.pcss +123 -0
  37. package/source/components/datatable/style/dataset.pcss +13 -0
  38. package/source/components/datatable/style/datasource.pcss +16 -0
  39. package/source/components/datatable/style/datatable.pcss +239 -0
  40. package/source/components/datatable/style/embedded-pagination.pcss +101 -0
  41. package/source/components/datatable/style/filter-button.pcss +22 -0
  42. package/source/components/datatable/style/filter-controls-defaults.pcss +46 -0
  43. package/source/components/datatable/style/filter-date-range.pcss +9 -0
  44. package/source/components/datatable/style/filter-range.pcss +5 -0
  45. package/source/components/datatable/style/filter.pcss +156 -0
  46. package/source/components/datatable/style/pagination.pcss +59 -0
  47. package/source/components/datatable/style/select-filter.pcss +27 -0
  48. package/source/components/datatable/stylesheet/column-bar.mjs +27 -0
  49. package/source/components/datatable/stylesheet/dataset.mjs +27 -0
  50. package/source/components/datatable/stylesheet/datasource.mjs +27 -0
  51. package/source/components/datatable/stylesheet/datatable.mjs +27 -0
  52. package/source/components/datatable/stylesheet/embedded-pagination.mjs +27 -0
  53. package/source/components/datatable/stylesheet/filter-button.mjs +27 -0
  54. package/source/components/datatable/stylesheet/filter-controls-defaults.mjs +27 -0
  55. package/source/components/datatable/stylesheet/filter-date-range.mjs +27 -0
  56. package/source/components/datatable/stylesheet/filter-range.mjs +27 -0
  57. package/source/components/datatable/stylesheet/filter.mjs +27 -0
  58. package/source/components/datatable/stylesheet/namespace.mjs +13 -0
  59. package/source/components/datatable/stylesheet/pagination.mjs +27 -0
  60. package/source/components/datatable/stylesheet/select-filter.mjs +27 -0
  61. package/source/components/datatable/util.mjs +60 -0
  62. package/source/components/form/action-button.mjs +262 -0
  63. package/source/components/form/api-button.mjs +515 -0
  64. package/source/components/form/button-bar.mjs +739 -0
  65. package/source/components/form/button.mjs +350 -0
  66. package/source/components/form/confirm-button.mjs +330 -0
  67. package/source/components/form/constants.mjs +111 -0
  68. package/source/components/form/context-help.mjs +123 -0
  69. package/source/components/form/events.mjs +84 -0
  70. package/source/components/form/form.mjs +601 -0
  71. package/source/components/form/message-state-button.mjs +396 -0
  72. package/source/components/form/namespace.mjs +13 -0
  73. package/source/components/form/popper-button.mjs +435 -0
  74. package/source/components/form/popper.mjs +487 -0
  75. package/source/components/form/reload.mjs +360 -0
  76. package/source/components/form/select.mjs +2314 -0
  77. package/source/components/form/shadow-reload.mjs +137 -0
  78. package/source/components/form/state-button.mjs +182 -0
  79. package/source/components/form/style/action-button.pcss +41 -0
  80. package/source/components/form/style/api-button.pcss +0 -0
  81. package/source/components/form/style/button-bar.pcss +51 -0
  82. package/source/components/form/style/button.pcss +8 -0
  83. package/source/components/form/style/confirm-button.pcss +17 -0
  84. package/source/components/form/style/context-help.pcss +16 -0
  85. package/source/components/form/style/form.pcss +10 -0
  86. package/source/components/form/style/message-state-button.pcss +10 -0
  87. package/source/components/form/style/popper-button.pcss +16 -0
  88. package/source/components/form/style/popper.pcss +8 -0
  89. package/source/components/form/style/select.pcss +265 -0
  90. package/source/components/form/style/state-button.pcss +116 -0
  91. package/source/components/form/style/tabs.pcss +173 -0
  92. package/source/components/form/style/tree-select.pcss +81 -0
  93. package/source/components/form/stylesheet/action-button.mjs +27 -0
  94. package/source/components/form/stylesheet/api-button.mjs +27 -0
  95. package/source/components/form/stylesheet/button-bar.mjs +27 -0
  96. package/source/components/form/stylesheet/button.mjs +27 -0
  97. package/source/components/form/stylesheet/confirm-button.mjs +27 -0
  98. package/source/components/form/stylesheet/context-help.mjs +27 -0
  99. package/source/components/form/stylesheet/form.mjs +27 -0
  100. package/source/components/form/stylesheet/message-state-button.mjs +27 -0
  101. package/source/components/form/stylesheet/namespace.mjs +13 -0
  102. package/source/components/form/stylesheet/popper-button.mjs +27 -0
  103. package/source/components/form/stylesheet/popper.mjs +27 -0
  104. package/source/components/form/stylesheet/select.mjs +27 -0
  105. package/source/components/form/stylesheet/state-button.mjs +27 -0
  106. package/source/components/form/stylesheet/tabs.mjs +27 -0
  107. package/source/components/form/stylesheet/tree-select.mjs +27 -0
  108. package/source/components/form/tabs.mjs +1029 -0
  109. package/source/components/form/template.mjs +373 -0
  110. package/source/components/form/tree-select.mjs +527 -0
  111. package/source/components/form/types/namespace.mjs +13 -0
  112. package/source/components/form/types/state.mjs +93 -0
  113. package/source/components/form/util/fetch.mjs +133 -0
  114. package/source/components/form/util/floating-ui.mjs +245 -0
  115. package/source/components/form/util/namespace.mjs +13 -0
  116. package/source/components/form/util/popper.mjs +49 -0
  117. package/source/components/host/call-button.mjs +236 -0
  118. package/source/components/host/collapse.mjs +526 -0
  119. package/source/components/host/config-manager.mjs +304 -0
  120. package/source/components/host/constants.mjs +18 -0
  121. package/source/components/host/details.mjs +268 -0
  122. package/source/components/host/events.mjs +131 -0
  123. package/source/components/host/host.mjs +420 -0
  124. package/source/components/host/namespace.mjs +13 -0
  125. package/source/components/host/overlay.mjs +339 -0
  126. package/source/components/host/style/call-button.pcss +36 -0
  127. package/source/components/host/style/collapse.pcss +67 -0
  128. package/source/components/host/style/config-manager.pcss +5 -0
  129. package/source/components/host/style/details.pcss +68 -0
  130. package/source/components/host/style/host.pcss +43 -0
  131. package/source/components/host/style/overlay.pcss +73 -0
  132. package/source/components/host/style/toggle-button.pcss +36 -0
  133. package/source/components/host/style/viewer.pcss +13 -0
  134. package/source/components/host/stylesheet/call-button.mjs +27 -0
  135. package/source/components/host/stylesheet/collapse.mjs +27 -0
  136. package/source/components/host/stylesheet/config-manager.mjs +27 -0
  137. package/source/components/host/stylesheet/details.mjs +27 -0
  138. package/source/components/host/stylesheet/host.mjs +27 -0
  139. package/source/components/host/stylesheet/namespace.mjs +13 -0
  140. package/source/components/host/stylesheet/overlay.mjs +27 -0
  141. package/source/components/host/stylesheet/toggle-button.mjs +27 -0
  142. package/source/components/host/stylesheet/viewer.mjs +27 -0
  143. package/source/components/host/toggle-button.mjs +88 -0
  144. package/source/components/host/util.mjs +23 -0
  145. package/source/components/host/viewer.mjs +309 -0
  146. package/source/components/namespace.mjs +14 -0
  147. package/source/components/notify/constants.mjs +15 -0
  148. package/source/components/notify/events.mjs +15 -0
  149. package/source/components/notify/message.mjs +374 -0
  150. package/source/components/notify/namespace.mjs +15 -0
  151. package/source/components/notify/notify.mjs +236 -0
  152. package/source/components/notify/style/message.pcss +57 -0
  153. package/source/components/notify/style/notify.pcss +118 -0
  154. package/source/components/notify/stylesheet/message.mjs +27 -0
  155. package/source/components/notify/stylesheet/namespace.mjs +15 -0
  156. package/source/components/notify/stylesheet/notify.mjs +27 -0
  157. package/source/components/state/log/entry.mjs +126 -0
  158. package/source/components/state/log/namespace.mjs +13 -0
  159. package/source/components/state/log.mjs +275 -0
  160. package/source/components/state/namespace.mjs +13 -0
  161. package/source/components/state/state.mjs +131 -0
  162. package/source/components/state/style/log.pcss +111 -0
  163. package/source/components/state/style/state.pcss +113 -0
  164. package/source/components/state/stylesheet/log.mjs +27 -0
  165. package/source/components/state/stylesheet/state.mjs +27 -0
  166. package/source/components/style/badge.pcss +92 -0
  167. package/source/components/style/border.pcss +77 -0
  168. package/source/components/style/button.pcss +105 -0
  169. package/source/components/style/card.pcss +108 -0
  170. package/source/components/style/color.pcss +257 -0
  171. package/source/components/style/common.pcss +105 -0
  172. package/source/components/style/control.pcss +11 -0
  173. package/source/components/style/data-grid.pcss +43 -0
  174. package/source/components/style/display.pcss +42 -0
  175. package/source/components/style/floating-ui.pcss +33 -0
  176. package/source/components/style/form.pcss +5 -0
  177. package/source/components/style/host.pcss +15 -0
  178. package/source/components/style/link.pcss +63 -0
  179. package/source/components/style/mixin/badge.pcss +18 -0
  180. package/source/components/style/mixin/button.pcss +52 -0
  181. package/source/components/style/mixin/form.pcss +247 -0
  182. package/source/components/style/mixin/hover.pcss +8 -0
  183. package/source/components/style/mixin/media.pcss +107 -0
  184. package/source/components/style/mixin/property.pcss +292 -0
  185. package/source/components/style/mixin/skeleton.pcss +26 -0
  186. package/source/components/style/mixin/spinner.pcss +24 -0
  187. package/source/components/style/mixin/typography.pcss +52 -0
  188. package/source/components/style/normalize.pcss +14 -0
  189. package/source/components/style/popper.pcss +78 -0
  190. package/source/components/style/property.pcss +17 -0
  191. package/source/components/style/ripple.pcss +14 -0
  192. package/source/components/style/skeleton.pcss +28 -0
  193. package/source/components/style/space.pcss +47 -0
  194. package/source/components/style/spinner.pcss +6 -0
  195. package/source/components/style/table.pcss +46 -0
  196. package/source/components/style/theme.pcss +119 -0
  197. package/source/components/style/typography.pcss +131 -0
  198. package/source/components/stylesheet/badge.mjs +27 -0
  199. package/source/components/stylesheet/border.mjs +27 -0
  200. package/source/components/stylesheet/button.mjs +27 -0
  201. package/source/components/stylesheet/card.mjs +27 -0
  202. package/source/components/stylesheet/color.mjs +27 -0
  203. package/source/components/stylesheet/common.mjs +27 -0
  204. package/source/components/stylesheet/control.mjs +27 -0
  205. package/source/components/stylesheet/data-grid.mjs +27 -0
  206. package/source/components/stylesheet/display.mjs +27 -0
  207. package/source/components/stylesheet/floating-ui.mjs +27 -0
  208. package/source/components/stylesheet/form.mjs +27 -0
  209. package/source/components/stylesheet/host.mjs +27 -0
  210. package/source/components/stylesheet/link.mjs +27 -0
  211. package/source/components/stylesheet/namespace.mjs +13 -0
  212. package/source/components/stylesheet/normalize.mjs +27 -0
  213. package/source/components/stylesheet/popper.mjs +27 -0
  214. package/source/components/stylesheet/property.mjs +27 -0
  215. package/source/components/stylesheet/ripple.mjs +27 -0
  216. package/source/components/stylesheet/skeleton.mjs +27 -0
  217. package/source/components/stylesheet/space.mjs +27 -0
  218. package/source/components/stylesheet/spinner.mjs +27 -0
  219. package/source/components/stylesheet/table.mjs +27 -0
  220. package/source/components/stylesheet/theme.mjs +27 -0
  221. package/source/components/stylesheet/tree-menu.mjs +33 -0
  222. package/source/components/stylesheet/typography.mjs +27 -0
  223. package/source/components/tree-menu/namespace.mjs +13 -0
  224. package/source/components/tree-menu/style/tree-menu.pcss +107 -0
  225. package/source/components/tree-menu/stylesheet/namespace.mjs +13 -0
  226. package/source/components/tree-menu/stylesheet/tree-menu.mjs +27 -0
  227. package/source/components/tree-menu/tree-menu.mjs +660 -0
  228. package/source/constraints/abstract.mjs +17 -24
  229. package/source/constraints/abstractoperator.mjs +27 -22
  230. package/source/constraints/andoperator.mjs +20 -17
  231. package/source/constraints/invalid.mjs +17 -17
  232. package/source/constraints/isarray.mjs +20 -20
  233. package/source/constraints/isobject.mjs +20 -20
  234. package/source/constraints/oroperator.mjs +45 -45
  235. package/source/constraints/valid.mjs +17 -17
  236. package/source/data/buildmap.mjs +108 -103
  237. package/source/data/buildtree.mjs +59 -57
  238. package/source/data/datasource/dom.mjs +80 -84
  239. package/source/data/datasource/namespace.mjs +1 -1
  240. package/source/data/datasource/server/restapi/data-fetch-error.mjs +27 -25
  241. package/source/data/datasource/server/restapi/writeerror.mjs +35 -32
  242. package/source/data/datasource/server/restapi.mjs +176 -177
  243. package/source/data/datasource/server/webconnect.mjs +150 -156
  244. package/source/data/datasource/server.mjs +62 -63
  245. package/source/data/datasource/storage/localstorage.mjs +25 -24
  246. package/source/data/datasource/storage/sessionstorage.mjs +28 -25
  247. package/source/data/datasource/storage.mjs +74 -73
  248. package/source/data/datasource.mjs +177 -168
  249. package/source/data/diff.mjs +98 -97
  250. package/source/data/extend.mjs +42 -42
  251. package/source/data/pathfinder.mjs +301 -288
  252. package/source/data/pipe.mjs +36 -36
  253. package/source/data/transformer.mjs +742 -726
  254. package/source/dom/assembler.mjs +44 -44
  255. package/source/dom/attributes.mjs +142 -122
  256. package/source/dom/constants.mjs +62 -58
  257. package/source/dom/customcontrol.mjs +299 -299
  258. package/source/dom/customelement.mjs +843 -806
  259. package/source/dom/dimension.mjs +56 -46
  260. package/source/dom/events.mjs +74 -69
  261. package/source/dom/focusmanager.mjs +175 -175
  262. package/source/dom/locale.mjs +28 -28
  263. package/source/dom/ready.mjs +13 -13
  264. package/source/dom/resource/data.mjs +117 -111
  265. package/source/dom/resource/link/stylesheet.mjs +16 -16
  266. package/source/dom/resource/link.mjs +94 -96
  267. package/source/dom/resource/script.mjs +72 -74
  268. package/source/dom/resource.mjs +174 -172
  269. package/source/dom/resourcemanager.mjs +152 -156
  270. package/source/dom/slotted.mjs +78 -80
  271. package/source/dom/template.mjs +126 -112
  272. package/source/dom/theme.mjs +35 -35
  273. package/source/dom/updater.mjs +673 -651
  274. package/source/dom/util/extract-keys.mjs +34 -22
  275. package/source/dom/util/init-options-from-attributes.mjs +46 -38
  276. package/source/dom/util/namespace.mjs +13 -0
  277. package/source/dom/util/set-option-from-attribute.mjs +35 -29
  278. package/source/dom/util.mjs +112 -81
  279. package/source/dom/worker/factory.mjs +83 -83
  280. package/source/i18n/formatter.mjs +75 -73
  281. package/source/i18n/locale.mjs +146 -144
  282. package/source/i18n/provider.mjs +70 -64
  283. package/source/i18n/providers/embed.mjs +136 -127
  284. package/source/i18n/providers/fetch.mjs +84 -76
  285. package/source/i18n/translations.mjs +205 -195
  286. package/source/logging/handler/console.mjs +36 -36
  287. package/source/logging/handler.mjs +140 -140
  288. package/source/logging/logentry.mjs +25 -25
  289. package/source/logging/logger.mjs +177 -175
  290. package/source/math/random.mjs +63 -59
  291. package/source/monster.mjs +223 -103
  292. package/source/net/webconnect/message.mjs +31 -31
  293. package/source/net/webconnect.mjs +278 -271
  294. package/source/text/bracketed-key-value-hash.mjs +182 -179
  295. package/source/text/formatter.mjs +235 -210
  296. package/source/text/generate-range-comparison-expression.mjs +56 -34
  297. package/source/text/namespace.mjs +1 -1
  298. package/source/types/base.mjs +69 -61
  299. package/source/types/basewithoptions.mjs +46 -46
  300. package/source/types/binary.mjs +20 -20
  301. package/source/types/dataurl.mjs +96 -90
  302. package/source/types/global.mjs +45 -39
  303. package/source/types/id.mjs +25 -25
  304. package/source/types/internal.mjs +115 -114
  305. package/source/types/is.mjs +56 -40
  306. package/source/types/mediatype.mjs +119 -119
  307. package/source/types/namespace.mjs +1 -1
  308. package/source/types/node.mjs +160 -150
  309. package/source/types/nodelist.mjs +94 -96
  310. package/source/types/noderecursiveiterator.mjs +50 -50
  311. package/source/types/observablequeue.mjs +73 -73
  312. package/source/types/observer.mjs +114 -106
  313. package/source/types/observerlist.mjs +66 -66
  314. package/source/types/proxyobserver.mjs +210 -210
  315. package/source/types/queue.mjs +63 -63
  316. package/source/types/randomid.mjs +13 -13
  317. package/source/types/regex.mjs +3 -1
  318. package/source/types/stack.mjs +64 -64
  319. package/source/types/tokenlist.mjs +206 -205
  320. package/source/types/typeof.mjs +12 -10
  321. package/source/types/uniquequeue.mjs +48 -48
  322. package/source/types/uuid.mjs +32 -32
  323. package/source/types/validate.mjs +67 -67
  324. package/source/types/version.mjs +115 -105
  325. package/source/util/clone.mjs +103 -91
  326. package/source/util/comparator.mjs +97 -97
  327. package/source/util/deadmansswitch.mjs +40 -44
  328. package/source/util/freeze.mjs +10 -9
  329. package/source/util/namespace.mjs +1 -1
  330. package/source/util/processing.mjs +104 -105
  331. package/source/util/runtime.mjs +56 -44
  332. package/source/util/trimspaces.mjs +24 -24
  333. package/test/cases/components/form/button.mjs +122 -0
  334. package/test/cases/components/form/confirm-button.mjs +127 -0
  335. package/test/cases/components/form/form.mjs +317 -0
  336. package/test/cases/components/form/reload.mjs +188 -0
  337. package/test/cases/components/form/select.mjs +229 -0
  338. package/test/cases/components/form/state-button.mjs +130 -0
  339. package/test/cases/components/form/tabs.mjs +98 -0
  340. package/test/cases/components/form/template.mjs +189 -0
  341. package/test/cases/components/form/tree-select.mjs +216 -0
  342. package/test/cases/components/host/details.mjs +68 -0
  343. package/test/cases/components/host/host.mjs +70 -0
  344. package/test/cases/components/host/overlay.mjs +60 -0
  345. package/test/cases/components/host/util.mjs +79 -0
  346. package/test/cases/components/notify/message.mjs +39 -0
  347. package/test/cases/components/notify/notify.mjs +89 -0
  348. package/test/cases/dom/customcontrol.mjs +5 -4
  349. package/test/cases/math/random.mjs +0 -1
  350. package/test/cases/monster.mjs +1 -1
  351. package/test/cases/net/webconnect/message.mjs +0 -1
  352. package/test/cases/types/node.mjs +1 -1
  353. package/test/util/chai-dom.mjs +2 -2
  354. package/test/util/intersection-mock.mjs +69 -0
  355. package/test/util/jsdom.mjs +41 -25
  356. package/test/util/localstorage.mjs +1 -0
  357. package/test/util/resize-observer.mjs +29 -0
  358. package/test/util/websocket.mjs +4 -1
  359. package/test/web/import.js +16 -1
  360. package/test/web/test.html +28 -5
  361. package/test/web/tests.js +30398 -17879
@@ -0,0 +1,527 @@
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
+
8
+ import { buildTree } from "../../data/buildtree.mjs";
9
+ import { findClosestByAttribute } from "../../dom/attributes.mjs";
10
+ import {
11
+ ATTRIBUTE_ROLE,
12
+ ATTRIBUTE_UPDATER_INSERT_REFERENCE,
13
+ } from "../../dom/constants.mjs";
14
+ import { instanceSymbol } from "../../constants.mjs";
15
+ import {
16
+ assembleMethodSymbol,
17
+ registerCustomElement,
18
+ } from "../../dom/customelement.mjs";
19
+ import { findTargetElementFromEvent, fireEvent } from "../../dom/events.mjs";
20
+ import { Formatter } from "../../text/formatter.mjs";
21
+ import { isString } from "../../types/is.mjs";
22
+ import { Node } from "../../types/node.mjs";
23
+ import { NodeRecursiveIterator } from "../../types/noderecursiveiterator.mjs";
24
+ import { validateInstance } from "../../types/validate.mjs";
25
+ import { ATTRIBUTE_FORM_URL, ATTRIBUTE_INTEND } from "./constants.mjs";
26
+ import { Select } from "./select.mjs";
27
+ import { SelectStyleSheet } from "./stylesheet/select.mjs";
28
+ import { TreeSelectStyleSheet } from "./stylesheet/tree-select.mjs";
29
+
30
+ export { TreeSelect, formatHierarchicalSelection };
31
+
32
+ /**
33
+ * @private
34
+ * @type {symbol}
35
+ */
36
+ const internalNodesSymbol = Symbol("internalNodes");
37
+
38
+ /**
39
+ * @private
40
+ * @type {symbol}
41
+ */
42
+ const keyEventHandler = Symbol("keyEventHandler");
43
+
44
+ /**
45
+ * This CustomControl creates a select element with a variety of options.
46
+ * It supports filtering, local and remote, multiple selection and has a
47
+ * template system for displaying the options.
48
+ *
49
+ * <img src="./images/treeselect.png">
50
+ *
51
+ * Dependencies: the system uses functions of the [monsterjs](https://monsterjs.org/) library
52
+ * as well as [pooperjs](https://popper.js.org/docs/v2/).
53
+ *
54
+ * You can create this control either by specifying the HTML tag `<monster-select />` directly in the HTML or using
55
+ * Javascript via the `document.createElement('monster-select');` method.
56
+ *
57
+ * ```html
58
+ * <monster-select></monster-select>
59
+ * ```
60
+ *
61
+ * Or you can create this CustomControl directly in Javascript:
62
+ *
63
+ * ```js
64
+ * import {TreeSelect} from '@schukai/component-form/source/treeselect.js';
65
+ * document.createElement('monster-tree-select');
66
+ * ```
67
+ *
68
+ * @externalExample ../../../example/components/form/tree-select.mjs
69
+ * @startuml treeselect.png
70
+ * skinparam monochrome true
71
+ * skinparam shadowing false
72
+ * HTMLElement <|-- CustomElement
73
+ * CustomElement <|-- CustomControl
74
+ * CustomControl <|-- Select
75
+ * Select <|-- TreeSelect
76
+ * @enduml
77
+ *
78
+ * @since 1.9.0
79
+ * @copyright schukai GmbH
80
+ * @memberOf Monster.Components.Form
81
+ * @summary A highly configurable select control
82
+ */
83
+ class TreeSelect extends Select {
84
+ /**
85
+ * This method is called by the `instanceof` operator.
86
+ * @returns {symbol}
87
+ * @since 2.1.0
88
+ */
89
+ static get [instanceSymbol]() {
90
+ return Symbol.for("@schukai/component-form/tree-select@@instance");
91
+ }
92
+
93
+ /**
94
+ * To set the options via the html tag the attribute `data-monster-options` must be used.
95
+ * @see {@link https://monsterjs.org/en/doc/#configurate-a-monster-control}
96
+ *
97
+ * The individual configuration values can be found in the table.
98
+ *
99
+ * @extends Monster.Components.Form.Select
100
+ * @property {String} mapping.rootReferences=['0', undefined, null]
101
+ * @property {String} mapping.idTemplate=id
102
+ * @property {String} mapping.parentTemplate=parent
103
+ * @property {String} mapping.selection
104
+ * @property {Object} formatter
105
+ * @property {String} formatter.separator=" / "
106
+ */
107
+ get defaults() {
108
+ return Object.assign(
109
+ {},
110
+ super.defaults,
111
+ {
112
+ mapping: {
113
+ rootReferences: ["0", undefined, null],
114
+ idTemplate: "id",
115
+ parentTemplate: "parent",
116
+ },
117
+ formatter: {
118
+ selection: formatHierarchicalSelection,
119
+ separator: " / ",
120
+ },
121
+ templates: {
122
+ main: getTemplate(),
123
+ },
124
+ },
125
+ initOptionsFromArguments.call(this),
126
+ );
127
+ }
128
+
129
+ /**
130
+ *
131
+ * @return {string}
132
+ */
133
+ static getTag() {
134
+ return "monster-tree-select";
135
+ }
136
+
137
+ /**
138
+ *
139
+ * @return {CSSStyleSheet[]}
140
+ */
141
+ static getCSSStyleSheet() {
142
+ return [SelectStyleSheet, TreeSelectStyleSheet];
143
+ }
144
+
145
+ /**
146
+ * Import Select Options from dataset
147
+ * Not to be confused with the control defaults/options
148
+ *
149
+ * @since 0.16.0
150
+ * @param {array|object|Map|Set} data
151
+ * @return {Select}
152
+ * @throws {Error} map is not iterable
153
+ */
154
+ importOptions(data) {;
155
+
156
+ this[internalNodesSymbol] = new Map();
157
+
158
+ const mappingOptions = this.getOption("mapping", {});
159
+
160
+ const filter = mappingOptions?.["filter"];
161
+ const rootReferences = mappingOptions?.["rootReferences"];
162
+
163
+ const id = this.getOption("mapping.idTemplate", "id");
164
+ const parentID = this.getOption("mapping.parentTemplate", "parent");
165
+
166
+ const selector = mappingOptions?.["selector"];
167
+
168
+ const nodes = buildTree(data, selector, id, parentID, {
169
+ filter,
170
+ rootReferences,
171
+ });
172
+
173
+ const options = [];
174
+ for (const node of nodes) {
175
+ const iterator = new NodeRecursiveIterator(node);
176
+ for (const n of iterator) {
177
+ const formattedValues = formatKeyLabel.call(this, n);
178
+
179
+ const label = formattedValues.label;
180
+ const value = formattedValues.value;
181
+ const intend = n.level;
182
+
183
+ const visibility = intend > 0 ? "hidden" : "visible";
184
+ const state = "close";
185
+
186
+ this[internalNodesSymbol].set(value, n);
187
+
188
+ options.push({
189
+ value,
190
+ label,
191
+ intend,
192
+ state,
193
+ visibility,
194
+ ["has-children"]: n.hasChildNodes(),
195
+ });
196
+ }
197
+ }
198
+
199
+ this.setOption("options", options);
200
+ return this;
201
+ }
202
+
203
+ /**
204
+ *
205
+ * @return {Monster.Components.Form.Select}
206
+ */
207
+ [assembleMethodSymbol]() {
208
+ super[assembleMethodSymbol]();
209
+ initEventhandler.call(this);
210
+ }
211
+ }
212
+
213
+ /**
214
+ * @private
215
+ * @param event
216
+ */
217
+ function handleOptionKeyboardEvents(event) {;
218
+
219
+ switch (event?.["code"]) {
220
+ case "ArrowLeft":
221
+ closeOrOpenCurrentOption.call(this, event, "close");
222
+ event.preventDefault();
223
+ break;
224
+ case "ArrowRight":
225
+ closeOrOpenCurrentOption.call(this, event, "open");
226
+ event.preventDefault();
227
+ break;
228
+ }
229
+ }
230
+
231
+ /**
232
+ * @private
233
+ * @param {event} event
234
+ */
235
+ function closeOrOpenCurrentOption(event, mode) {
236
+ validateInstance(event, Event);
237
+
238
+ if (typeof event.composedPath !== "function") {
239
+ throw new Error("unsupported event");
240
+ }
241
+
242
+ const path = event.composedPath();
243
+ const optionNode = path.shift();
244
+
245
+ const state = optionNode.getAttribute("data-monster-state");
246
+ if (state !== mode) {
247
+ const handler = optionNode.querySelector(
248
+ "[data-monster-role=folder-handler]",
249
+ );
250
+ if (handler instanceof HTMLElement) {
251
+ fireEvent(handler, "click");
252
+ }
253
+ }
254
+ }
255
+
256
+ /**
257
+ *
258
+ * @param {Node} node
259
+ * @return {array<label, value>}
260
+ * @memberOf Monster.Components.Form
261
+ * @private
262
+ */
263
+ function formatKeyLabel(node) {;
264
+ validateInstance(node, Node);
265
+
266
+ const label = new Formatter(node.value).format(
267
+ this.getOption("mapping.labelTemplate", ""),
268
+ );
269
+ const value = new Formatter(node.value).format(
270
+ this.getOption("mapping.valueTemplate", ""),
271
+ );
272
+
273
+ return {
274
+ value,
275
+ label,
276
+ };
277
+ }
278
+
279
+ /**
280
+ * @private
281
+ * @param {string} value
282
+ * @return {Array}
283
+ */
284
+ function buildTreeLabels(value) {;
285
+ let node = this[internalNodesSymbol].get(value);
286
+ if (node === undefined) {
287
+ node = this[internalNodesSymbol].get(parseInt(value));
288
+ }
289
+
290
+ const parts = [];
291
+
292
+ if (node instanceof Node) {
293
+ let ptr = node;
294
+ while (ptr) {
295
+ const formattedValues = formatKeyLabel.call(this, ptr);
296
+ parts.unshift(formattedValues.label);
297
+ ptr = ptr.parent;
298
+ }
299
+ }
300
+
301
+ return parts;
302
+ }
303
+
304
+ /**
305
+ * This formatter can format a label hierarchically.
306
+ * The option `formatter.separator` determines the separator.
307
+ *
308
+ * ```
309
+ * a / b / c
310
+ * ```
311
+ *
312
+ * This function can be passed as argument of the option `formatter.selection:`.
313
+ *
314
+ * @since 1.9.0
315
+ * @param {*} value
316
+ * @return {string}
317
+ * @memberOf Monster.Components.Form
318
+ */
319
+ function formatHierarchicalSelection(value) {;
320
+ return buildTreeLabels
321
+ .call(this, value)
322
+ .join(this.getOption("formatter.separator", " / "));
323
+ }
324
+
325
+ /**
326
+ * @private
327
+ * @type {symbol}
328
+ */
329
+ const openOptionEventHandler = Symbol("openOptionEventHandler");
330
+
331
+ /**
332
+ * @private
333
+ * @throws {Error} no shadow-root is defined
334
+ */
335
+ function initEventhandler() {;
336
+
337
+ if (!this.shadowRoot) {
338
+ throw new Error("no shadow-root is defined");
339
+ }
340
+
341
+ this[openOptionEventHandler] = (event) => {
342
+ const element = findTargetElementFromEvent(
343
+ event,
344
+ ATTRIBUTE_ROLE,
345
+ "folder-handler",
346
+ );
347
+ if (!(element instanceof HTMLElement)) {
348
+ return;
349
+ }
350
+
351
+ const container = findClosestByAttribute(element, ATTRIBUTE_ROLE, "option");
352
+ const index = container
353
+ .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
354
+ .split("-")
355
+ .pop();
356
+
357
+ const currentState = this.getOption(`options.${index}.state`);
358
+
359
+ const newState = currentState === "close" ? "open" : "close";
360
+ this.setOption(`options.${index}.state`, newState);
361
+
362
+ const newVisibility = newState === "open" ? "visible" : "hidden";
363
+
364
+ if (container.hasAttribute(ATTRIBUTE_INTEND)) {
365
+ const intend = container.getAttribute(ATTRIBUTE_INTEND);
366
+
367
+ let ref = container.nextElementSibling;
368
+ const childIntend = parseInt(intend) + 1;
369
+
370
+ const cmp = (a, b) => {
371
+ if (newState === "open") {
372
+ return a === b;
373
+ }
374
+
375
+ return a >= b;
376
+ };
377
+
378
+ while (
379
+ ref?.hasAttribute(ATTRIBUTE_INTEND) &&
380
+ cmp(parseInt(ref.getAttribute(ATTRIBUTE_INTEND)), childIntend)
381
+ ) {
382
+ const refIndex = ref
383
+ .getAttribute(ATTRIBUTE_UPDATER_INSERT_REFERENCE)
384
+ .split("-")
385
+ .pop();
386
+ this.setOption(`options.${refIndex}.visibility`, newVisibility);
387
+
388
+ if (newState === "close") {
389
+ this.setOption(`options.${refIndex}.state`, "close");
390
+ }
391
+
392
+ ref = ref.nextElementSibling;
393
+ }
394
+ }
395
+ };
396
+
397
+ this[keyEventHandler] = (event) => {
398
+ const path = event.composedPath();
399
+ const element = path?.[0];
400
+
401
+ let role;
402
+
403
+ if (element instanceof HTMLElement) {
404
+ if (element.hasAttribute(ATTRIBUTE_ROLE)) {
405
+ role = element.getAttribute(ATTRIBUTE_ROLE);
406
+ } else if (element === this) {
407
+ show.call(this);
408
+ focusFilter.call(this);
409
+ } else {
410
+ const e = element.closest(`[${ATTRIBUTE_ROLE}]`);
411
+ if (e instanceof HTMLElement && e.hasAttribute()) {
412
+ role = e.getAttribute(ATTRIBUTE_ROLE);
413
+ }
414
+ }
415
+ } else {
416
+ return;
417
+ }
418
+
419
+ switch (role) {
420
+ case "option-label":
421
+ case "option-control":
422
+ case "option":
423
+ handleOptionKeyboardEvents.call(this, event);
424
+ break;
425
+ }
426
+ };
427
+
428
+ this.shadowRoot.addEventListener("keydown", this[keyEventHandler]);
429
+ this.shadowRoot.addEventListener("click", this[openOptionEventHandler]);
430
+ }
431
+
432
+ /**
433
+ * This attribute can be used to pass a URL to this select.
434
+ *
435
+ * ```html
436
+ * <monster-select data-monster-url="https://example.com/"></monster-select>
437
+ * ```
438
+ *
439
+ * @private
440
+ * @return {object}
441
+ */
442
+ function initOptionsFromArguments() {;
443
+ const options = {};
444
+
445
+ const url = this.getAttribute(ATTRIBUTE_FORM_URL);
446
+ if (isString(url)) {
447
+ options["url"] = new URL(url).toString();
448
+ }
449
+
450
+ return options;
451
+ }
452
+
453
+ /**
454
+ * @private
455
+ * @return {string}
456
+ */
457
+ function getTemplate() {
458
+ // language=HTML
459
+ return `
460
+ <template id="options">
461
+ <div data-monster-role="option"
462
+ tabindex="-1"
463
+ data-monster-attributes="
464
+ data-monster-intend path:options.intend,
465
+ data-monster-state path:options.state,
466
+ data-monster-visibility path:options.visibility,
467
+ data-monster-filtered path:options.filtered,
468
+ data-monster-has-children path:options.has-children">
469
+ <div data-monster-role="folder-handler"></div>
470
+ <label part="option" role="option">
471
+ <input data-monster-role="option-control"
472
+ data-monster-attributes="
473
+ type path:type,
474
+ role path:role,
475
+ value path:options.value,
476
+ name path:name,
477
+ part path:type | prefix:option- | suffix: form
478
+ " tabindex="-1">
479
+ <span data-monster-replace="path:options | index:label" part="option-label"></span>
480
+ </label>
481
+ </div>
482
+ </template>
483
+
484
+ <template id="selection">
485
+ <div data-monster-role="badge"
486
+ part="badge"
487
+ data-monster-attributes="
488
+ data-monster-value path:selection | index:value,
489
+ class path:classes | index:badge,
490
+ part path:type | suffix:-option | prefix: form-" tabindex="-1">
491
+ <div data-monster-replace="path:selection | index:label" part="badge-label"
492
+ data-monster-role="badge-label"></div>
493
+ <div part="remove-badge" data-monster-select-this
494
+ data-monster-attributes="class path:features.clear | ?::hidden "
495
+ data-monster-role="remove-badge" tabindex="-1"></div>
496
+ </div>
497
+ </template>
498
+
499
+ <slot class="hidden"></slot>
500
+
501
+ <div data-monster-role="control" part="control" tabindex="0">
502
+ <div data-monster-role="container">
503
+ \${selected}
504
+ </div>
505
+
506
+ <div data-monster-role="popper" part="popper" tabindex="-1" class="monster-color-primary-1">
507
+ <div class="option-filter-control" role="search">
508
+ <input type="text" role="searchbox"
509
+ part="popper-filter" name="popper-filter"
510
+ data-monster-role="filter"
511
+ autocomplete="off"
512
+ tabindex="0">
513
+ </div>
514
+ <div part="content" class="flex" data-monster-replace="path:content">
515
+ <div part="options" data-monster-role="options" data-monster-insert="options path:options"
516
+ tabindex="-1"></div>
517
+ </div>
518
+ <div part="no-options" data-monster-role="no-options"
519
+ data-monster-replace="path:messages.emptyOptions"></div>
520
+ </div>
521
+ <div part="status-or-remove-badges" data-monster-role="status-or-remove-badges"
522
+ data-monster-attributes="class path:classes.statusOrRemoveBadge | suffix:\\ status-or-remove-badges"></div>
523
+ </div>
524
+ `;
525
+ }
526
+
527
+ registerCustomElement(TreeSelect);
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Copyright 2023 schukai GmbH
3
+ * SPDX-License-Identifier: AGPL-3.0
4
+ */
5
+
6
+ /**
7
+ * Namespace for all form related functions.
8
+ *
9
+ * @namespace Monster.Components.Form.Types
10
+ * @memberOf Monster
11
+ * @author schukai GmbH
12
+ */
13
+ const ns = {};
@@ -0,0 +1,93 @@
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
+
8
+ import { Base } from "../../../types/base.mjs";
9
+ import { validateString } from "../../../types/validate.mjs";
10
+
11
+ export { State, getStateInstanceFor };
12
+
13
+ /**
14
+ * @private
15
+ * @type {symbol}
16
+ */
17
+ const internalSymbol = Symbol("internalSymbol");
18
+
19
+ /**
20
+ * This State class represent a State with presentation
21
+ *
22
+ * @since 1.5.0
23
+ * @copyright schukai GmbH
24
+ * @memberOf Monster.Components.Form.Types
25
+ */
26
+ class State extends Base {
27
+ /**
28
+ *
29
+ * @param {string} state
30
+ * @param {string} presentation
31
+ * @throws {TypeError} value is not a string
32
+ */
33
+ constructor(state, presentation) {
34
+ super();
35
+ this[internalSymbol] = {};
36
+ this[internalSymbol].state = validateString(state);
37
+ this[internalSymbol].presentation = validateString(presentation);
38
+ }
39
+
40
+ /**
41
+ * @property {String} state
42
+ */
43
+ get state() {
44
+ return this[internalSymbol].state;
45
+ }
46
+
47
+ /**
48
+ * @property {String} presentation
49
+ */
50
+ get presentation() {
51
+ return this[internalSymbol].presentation;
52
+ }
53
+
54
+ /**
55
+ * @return {Monster.Components.Form.Types.State}
56
+ */
57
+ getClone() {
58
+ return new State(
59
+ this[internalSymbol].state,
60
+ this[internalSymbol].presentation,
61
+ );
62
+ }
63
+ }
64
+
65
+ /**
66
+ * @since 1.5.0
67
+ * @param state
68
+ * @return {Monster.Components.Form.Types.State}
69
+ * @memberOf Monster.Components.Form.Types
70
+ */
71
+ function getStateInstanceFor(state) {
72
+ switch (state) {
73
+ case "stateless":
74
+ return new State("stateless", "");
75
+ case "successful":
76
+ return new State(
77
+ "successful",
78
+ '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="successful" viewBox="0 0 16 16"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/><path d="M10.97 4.97a.235.235 0 0 0-.02.022L7.477 9.417 5.384 7.323a.75.75 0 0 0-1.06 1.06L6.97 11.03a.75.75 0 0 0 1.079-.02l3.992-4.99a.75.75 0 0 0-1.071-1.05z"/></svg>',
79
+ );
80
+ case "activity":
81
+ return new State(
82
+ "activity",
83
+ '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="activity" viewBox="0 0 16 16"><circle cx="8" cy="8" r="8"/></svg>',
84
+ );
85
+ case "failed": // https://icons.getbootstrap.com/icons/exclamation-circle/
86
+ return new State(
87
+ "failed",
88
+ '<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" fill="currentColor" class="failed" viewBox="0 0 16 16"><path d="M8 15A7 7 0 1 1 8 1a7 7 0 0 1 0 14zm0 1A8 8 0 1 0 8 0a8 8 0 0 0 0 16z"/><path d="M7.002 11a1 1 0 1 1 2 0 1 1 0 0 1-2 0zM7.1 4.995a.905.905 0 1 1 1.8 0l-.35 3.507a.552.552 0 0 1-1.1 0L7.1 4.995z"/></svg>',
89
+ );
90
+ default:
91
+ return new State(state, "");
92
+ }
93
+ }