@vadem/ui 0.0.0-stage → 0.0.2

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 (289) hide show
  1. package/LICENSE-lucide.txt +43 -0
  2. package/README.md +93 -2
  3. package/fesm2022/vadem-ui-accordion.mjs +139 -0
  4. package/fesm2022/vadem-ui-accordion.mjs.map +1 -0
  5. package/fesm2022/vadem-ui-active-filters.mjs +355 -0
  6. package/fesm2022/vadem-ui-active-filters.mjs.map +1 -0
  7. package/fesm2022/vadem-ui-alert-dialog.mjs +433 -0
  8. package/fesm2022/vadem-ui-alert-dialog.mjs.map +1 -0
  9. package/fesm2022/vadem-ui-alert.mjs +266 -0
  10. package/fesm2022/vadem-ui-alert.mjs.map +1 -0
  11. package/fesm2022/vadem-ui-autocomplete.mjs +715 -0
  12. package/fesm2022/vadem-ui-autocomplete.mjs.map +1 -0
  13. package/fesm2022/vadem-ui-avatar.mjs +219 -0
  14. package/fesm2022/vadem-ui-avatar.mjs.map +1 -0
  15. package/fesm2022/vadem-ui-badge.mjs +86 -0
  16. package/fesm2022/vadem-ui-badge.mjs.map +1 -0
  17. package/fesm2022/vadem-ui-breadcrumbs.mjs +61 -0
  18. package/fesm2022/vadem-ui-breadcrumbs.mjs.map +1 -0
  19. package/fesm2022/vadem-ui-button.mjs +220 -0
  20. package/fesm2022/vadem-ui-button.mjs.map +1 -0
  21. package/fesm2022/vadem-ui-calendar.mjs +1314 -0
  22. package/fesm2022/vadem-ui-calendar.mjs.map +1 -0
  23. package/fesm2022/vadem-ui-card.mjs +271 -0
  24. package/fesm2022/vadem-ui-card.mjs.map +1 -0
  25. package/fesm2022/vadem-ui-character-count.mjs +269 -0
  26. package/fesm2022/vadem-ui-character-count.mjs.map +1 -0
  27. package/fesm2022/vadem-ui-chart.mjs +1984 -0
  28. package/fesm2022/vadem-ui-chart.mjs.map +1 -0
  29. package/fesm2022/vadem-ui-checkbox.mjs +67 -0
  30. package/fesm2022/vadem-ui-checkbox.mjs.map +1 -0
  31. package/fesm2022/vadem-ui-color-picker.mjs +815 -0
  32. package/fesm2022/vadem-ui-color-picker.mjs.map +1 -0
  33. package/fesm2022/vadem-ui-command.mjs +735 -0
  34. package/fesm2022/vadem-ui-command.mjs.map +1 -0
  35. package/fesm2022/vadem-ui-copy-button.mjs +375 -0
  36. package/fesm2022/vadem-ui-copy-button.mjs.map +1 -0
  37. package/fesm2022/vadem-ui-date-range-picker.mjs +1011 -0
  38. package/fesm2022/vadem-ui-date-range-picker.mjs.map +1 -0
  39. package/fesm2022/vadem-ui-description-list.mjs +59 -0
  40. package/fesm2022/vadem-ui-description-list.mjs.map +1 -0
  41. package/fesm2022/vadem-ui-dialog.mjs +587 -0
  42. package/fesm2022/vadem-ui-dialog.mjs.map +1 -0
  43. package/fesm2022/vadem-ui-dropzone.mjs +176 -0
  44. package/fesm2022/vadem-ui-dropzone.mjs.map +1 -0
  45. package/fesm2022/vadem-ui-editable-text.mjs +641 -0
  46. package/fesm2022/vadem-ui-editable-text.mjs.map +1 -0
  47. package/fesm2022/vadem-ui-empty-state.mjs +175 -0
  48. package/fesm2022/vadem-ui-empty-state.mjs.map +1 -0
  49. package/fesm2022/vadem-ui-expandable-text.mjs +244 -0
  50. package/fesm2022/vadem-ui-expandable-text.mjs.map +1 -0
  51. package/fesm2022/vadem-ui-field.mjs +583 -0
  52. package/fesm2022/vadem-ui-field.mjs.map +1 -0
  53. package/fesm2022/vadem-ui-file-preview.mjs +532 -0
  54. package/fesm2022/vadem-ui-file-preview.mjs.map +1 -0
  55. package/fesm2022/vadem-ui-file-size.mjs +83 -0
  56. package/fesm2022/vadem-ui-file-size.mjs.map +1 -0
  57. package/fesm2022/vadem-ui-form-error-summary.mjs +201 -0
  58. package/fesm2022/vadem-ui-form-error-summary.mjs.map +1 -0
  59. package/fesm2022/vadem-ui-icon.mjs +303 -0
  60. package/fesm2022/vadem-ui-icon.mjs.map +1 -0
  61. package/fesm2022/vadem-ui-input.mjs +120 -0
  62. package/fesm2022/vadem-ui-input.mjs.map +1 -0
  63. package/fesm2022/vadem-ui-kbd.mjs +286 -0
  64. package/fesm2022/vadem-ui-kbd.mjs.map +1 -0
  65. package/fesm2022/vadem-ui-keyboard.mjs +105 -0
  66. package/fesm2022/vadem-ui-keyboard.mjs.map +1 -0
  67. package/fesm2022/vadem-ui-locale.mjs +443 -0
  68. package/fesm2022/vadem-ui-locale.mjs.map +1 -0
  69. package/fesm2022/vadem-ui-menu.mjs +657 -0
  70. package/fesm2022/vadem-ui-menu.mjs.map +1 -0
  71. package/fesm2022/vadem-ui-navigation-list.mjs +130 -0
  72. package/fesm2022/vadem-ui-navigation-list.mjs.map +1 -0
  73. package/fesm2022/vadem-ui-number-input.mjs +264 -0
  74. package/fesm2022/vadem-ui-number-input.mjs.map +1 -0
  75. package/fesm2022/vadem-ui-otp-input.mjs +86 -0
  76. package/fesm2022/vadem-ui-otp-input.mjs.map +1 -0
  77. package/fesm2022/vadem-ui-pagination.mjs +353 -0
  78. package/fesm2022/vadem-ui-pagination.mjs.map +1 -0
  79. package/fesm2022/vadem-ui-password-input.mjs +213 -0
  80. package/fesm2022/vadem-ui-password-input.mjs.map +1 -0
  81. package/fesm2022/vadem-ui-popover.mjs +178 -0
  82. package/fesm2022/vadem-ui-popover.mjs.map +1 -0
  83. package/fesm2022/vadem-ui-progress.mjs +331 -0
  84. package/fesm2022/vadem-ui-progress.mjs.map +1 -0
  85. package/fesm2022/vadem-ui-radio.mjs +39 -0
  86. package/fesm2022/vadem-ui-radio.mjs.map +1 -0
  87. package/fesm2022/vadem-ui-range-slider.mjs +561 -0
  88. package/fesm2022/vadem-ui-range-slider.mjs.map +1 -0
  89. package/fesm2022/vadem-ui-rating.mjs +404 -0
  90. package/fesm2022/vadem-ui-rating.mjs.map +1 -0
  91. package/fesm2022/vadem-ui-relative-time.mjs +217 -0
  92. package/fesm2022/vadem-ui-relative-time.mjs.map +1 -0
  93. package/fesm2022/vadem-ui-reorder-list.mjs +601 -0
  94. package/fesm2022/vadem-ui-reorder-list.mjs.map +1 -0
  95. package/fesm2022/vadem-ui-scroll-area.mjs +65 -0
  96. package/fesm2022/vadem-ui-scroll-area.mjs.map +1 -0
  97. package/fesm2022/vadem-ui-search-input.mjs +307 -0
  98. package/fesm2022/vadem-ui-search-input.mjs.map +1 -0
  99. package/fesm2022/vadem-ui-segmented.mjs +297 -0
  100. package/fesm2022/vadem-ui-segmented.mjs.map +1 -0
  101. package/fesm2022/vadem-ui-select.mjs +1462 -0
  102. package/fesm2022/vadem-ui-select.mjs.map +1 -0
  103. package/fesm2022/vadem-ui-sidebar.mjs +493 -0
  104. package/fesm2022/vadem-ui-sidebar.mjs.map +1 -0
  105. package/fesm2022/vadem-ui-skeleton.mjs +106 -0
  106. package/fesm2022/vadem-ui-skeleton.mjs.map +1 -0
  107. package/fesm2022/vadem-ui-slider.mjs +60 -0
  108. package/fesm2022/vadem-ui-slider.mjs.map +1 -0
  109. package/fesm2022/vadem-ui-splitter.mjs +438 -0
  110. package/fesm2022/vadem-ui-splitter.mjs.map +1 -0
  111. package/fesm2022/vadem-ui-stat.mjs +369 -0
  112. package/fesm2022/vadem-ui-stat.mjs.map +1 -0
  113. package/fesm2022/vadem-ui-stepper.mjs +483 -0
  114. package/fesm2022/vadem-ui-stepper.mjs.map +1 -0
  115. package/fesm2022/vadem-ui-switch.mjs +45 -0
  116. package/fesm2022/vadem-ui-switch.mjs.map +1 -0
  117. package/fesm2022/vadem-ui-table.mjs +593 -0
  118. package/fesm2022/vadem-ui-table.mjs.map +1 -0
  119. package/fesm2022/vadem-ui-tabs.mjs +405 -0
  120. package/fesm2022/vadem-ui-tabs.mjs.map +1 -0
  121. package/fesm2022/vadem-ui-tag-input.mjs +685 -0
  122. package/fesm2022/vadem-ui-tag-input.mjs.map +1 -0
  123. package/fesm2022/vadem-ui-text-highlight.mjs +126 -0
  124. package/fesm2022/vadem-ui-text-highlight.mjs.map +1 -0
  125. package/fesm2022/vadem-ui-time-input.mjs +430 -0
  126. package/fesm2022/vadem-ui-time-input.mjs.map +1 -0
  127. package/fesm2022/vadem-ui-timeline.mjs +313 -0
  128. package/fesm2022/vadem-ui-timeline.mjs.map +1 -0
  129. package/fesm2022/vadem-ui-toast.mjs +397 -0
  130. package/fesm2022/vadem-ui-toast.mjs.map +1 -0
  131. package/fesm2022/vadem-ui-toolbar.mjs +396 -0
  132. package/fesm2022/vadem-ui-toolbar.mjs.map +1 -0
  133. package/fesm2022/vadem-ui-tooltip.mjs +218 -0
  134. package/fesm2022/vadem-ui-tooltip.mjs.map +1 -0
  135. package/fesm2022/vadem-ui-tree.mjs +551 -0
  136. package/fesm2022/vadem-ui-tree.mjs.map +1 -0
  137. package/fesm2022/vadem-ui-upload-list.mjs +408 -0
  138. package/fesm2022/vadem-ui-upload-list.mjs.map +1 -0
  139. package/fesm2022/vadem-ui.mjs +4 -0
  140. package/fesm2022/vadem-ui.mjs.map +1 -0
  141. package/fonts/jetbrains-mono/OFL.txt +93 -0
  142. package/fonts/jetbrains-mono/jetbrains-mono-cyrillic.woff2 +0 -0
  143. package/fonts/jetbrains-mono/jetbrains-mono-latin.woff2 +0 -0
  144. package/fonts/manrope/OFL.txt +93 -0
  145. package/fonts/manrope/manrope-cyrillic.woff2 +0 -0
  146. package/fonts/manrope/manrope-latin.woff2 +0 -0
  147. package/package.json +329 -3
  148. package/styles/base.css +160 -0
  149. package/styles/components/accordion.css +130 -0
  150. package/styles/components/active-filters.css +42 -0
  151. package/styles/components/alert-dialog.css +34 -0
  152. package/styles/components/alert.css +159 -0
  153. package/styles/components/autocomplete.css +97 -0
  154. package/styles/components/avatar.css +90 -0
  155. package/styles/components/badge.css +91 -0
  156. package/styles/components/breadcrumbs.css +94 -0
  157. package/styles/components/button.css +174 -0
  158. package/styles/components/calendar.css +186 -0
  159. package/styles/components/card.css +206 -0
  160. package/styles/components/character-count.css +41 -0
  161. package/styles/components/chart.css +308 -0
  162. package/styles/components/checkbox.css +115 -0
  163. package/styles/components/color-picker.css +158 -0
  164. package/styles/components/command.css +175 -0
  165. package/styles/components/copy-button.css +58 -0
  166. package/styles/components/date-range-picker.css +153 -0
  167. package/styles/components/description-list.css +69 -0
  168. package/styles/components/dialog.css +334 -0
  169. package/styles/components/dropzone.css +89 -0
  170. package/styles/components/editable-text.css +58 -0
  171. package/styles/components/empty-state.css +72 -0
  172. package/styles/components/expandable-text.css +24 -0
  173. package/styles/components/field.css +148 -0
  174. package/styles/components/file-preview.css +65 -0
  175. package/styles/components/form-error-summary.css +71 -0
  176. package/styles/components/icon.css +38 -0
  177. package/styles/components/index.css +80 -0
  178. package/styles/components/input.css +171 -0
  179. package/styles/components/kbd.css +42 -0
  180. package/styles/components/menu.css +168 -0
  181. package/styles/components/multi-select.css +156 -0
  182. package/styles/components/navigation-list.css +147 -0
  183. package/styles/components/number-input.css +33 -0
  184. package/styles/components/otp-input.css +26 -0
  185. package/styles/components/pagination.css +127 -0
  186. package/styles/components/password-input.css +20 -0
  187. package/styles/components/popover.css +93 -0
  188. package/styles/components/progress-ring.css +112 -0
  189. package/styles/components/progress.css +162 -0
  190. package/styles/components/radio.css +117 -0
  191. package/styles/components/range-slider.css +158 -0
  192. package/styles/components/rating.css +100 -0
  193. package/styles/components/reorder-list.css +143 -0
  194. package/styles/components/scroll-area.css +39 -0
  195. package/styles/components/search-input.css +25 -0
  196. package/styles/components/segmented.css +136 -0
  197. package/styles/components/select.css +257 -0
  198. package/styles/components/sidebar.css +105 -0
  199. package/styles/components/skeleton.css +83 -0
  200. package/styles/components/slider.css +132 -0
  201. package/styles/components/splitter.css +83 -0
  202. package/styles/components/stat.css +62 -0
  203. package/styles/components/stepper.css +236 -0
  204. package/styles/components/switch.css +107 -0
  205. package/styles/components/table.css +195 -0
  206. package/styles/components/tabs.css +198 -0
  207. package/styles/components/tag-input.css +138 -0
  208. package/styles/components/text-highlight.css +22 -0
  209. package/styles/components/time-input.css +96 -0
  210. package/styles/components/timeline.css +182 -0
  211. package/styles/components/toast.css +146 -0
  212. package/styles/components/toolbar.css +72 -0
  213. package/styles/components/tooltip.css +93 -0
  214. package/styles/components/tree.css +88 -0
  215. package/styles/components/upload-list.css +113 -0
  216. package/styles/fonts.css +67 -0
  217. package/styles/index.css +14 -0
  218. package/styles/reset.css +57 -0
  219. package/styles/tokens/primitives.css +364 -0
  220. package/styles/tokens/semantic.css +233 -0
  221. package/types/vadem-ui-accordion.d.ts +43 -0
  222. package/types/vadem-ui-active-filters.d.ts +73 -0
  223. package/types/vadem-ui-alert-dialog.d.ts +87 -0
  224. package/types/vadem-ui-alert.d.ts +64 -0
  225. package/types/vadem-ui-autocomplete.d.ts +156 -0
  226. package/types/vadem-ui-avatar.d.ts +59 -0
  227. package/types/vadem-ui-badge.d.ts +25 -0
  228. package/types/vadem-ui-breadcrumbs.d.ts +22 -0
  229. package/types/vadem-ui-button.d.ts +52 -0
  230. package/types/vadem-ui-calendar.d.ts +327 -0
  231. package/types/vadem-ui-card.d.ts +58 -0
  232. package/types/vadem-ui-character-count.d.ts +71 -0
  233. package/types/vadem-ui-chart.d.ts +452 -0
  234. package/types/vadem-ui-checkbox.d.ts +20 -0
  235. package/types/vadem-ui-color-picker.d.ts +171 -0
  236. package/types/vadem-ui-command.d.ts +145 -0
  237. package/types/vadem-ui-copy-button.d.ts +90 -0
  238. package/types/vadem-ui-date-range-picker.d.ts +216 -0
  239. package/types/vadem-ui-description-list.d.ts +15 -0
  240. package/types/vadem-ui-dialog.d.ts +174 -0
  241. package/types/vadem-ui-dropzone.d.ts +73 -0
  242. package/types/vadem-ui-editable-text.d.ts +141 -0
  243. package/types/vadem-ui-empty-state.d.ts +34 -0
  244. package/types/vadem-ui-expandable-text.d.ts +52 -0
  245. package/types/vadem-ui-field.d.ts +180 -0
  246. package/types/vadem-ui-file-preview.d.ts +108 -0
  247. package/types/vadem-ui-file-size.d.ts +18 -0
  248. package/types/vadem-ui-form-error-summary.d.ts +46 -0
  249. package/types/vadem-ui-icon.d.ts +152 -0
  250. package/types/vadem-ui-input.d.ts +31 -0
  251. package/types/vadem-ui-kbd.d.ts +66 -0
  252. package/types/vadem-ui-keyboard.d.ts +61 -0
  253. package/types/vadem-ui-locale.d.ts +241 -0
  254. package/types/vadem-ui-menu.d.ts +134 -0
  255. package/types/vadem-ui-navigation-list.d.ts +28 -0
  256. package/types/vadem-ui-number-input.d.ts +39 -0
  257. package/types/vadem-ui-otp-input.d.ts +15 -0
  258. package/types/vadem-ui-pagination.d.ts +96 -0
  259. package/types/vadem-ui-password-input.d.ts +36 -0
  260. package/types/vadem-ui-popover.d.ts +48 -0
  261. package/types/vadem-ui-progress.d.ts +95 -0
  262. package/types/vadem-ui-radio.d.ts +11 -0
  263. package/types/vadem-ui-range-slider.d.ts +136 -0
  264. package/types/vadem-ui-rating.d.ts +95 -0
  265. package/types/vadem-ui-relative-time.d.ts +58 -0
  266. package/types/vadem-ui-reorder-list.d.ts +120 -0
  267. package/types/vadem-ui-scroll-area.d.ts +13 -0
  268. package/types/vadem-ui-search-input.d.ts +58 -0
  269. package/types/vadem-ui-segmented.d.ts +76 -0
  270. package/types/vadem-ui-select.d.ts +303 -0
  271. package/types/vadem-ui-sidebar.d.ts +70 -0
  272. package/types/vadem-ui-skeleton.d.ts +28 -0
  273. package/types/vadem-ui-slider.d.ts +17 -0
  274. package/types/vadem-ui-splitter.d.ts +99 -0
  275. package/types/vadem-ui-stat.d.ts +101 -0
  276. package/types/vadem-ui-stepper.d.ts +108 -0
  277. package/types/vadem-ui-switch.d.ts +10 -0
  278. package/types/vadem-ui-table.d.ts +172 -0
  279. package/types/vadem-ui-tabs.d.ts +101 -0
  280. package/types/vadem-ui-tag-input.d.ts +170 -0
  281. package/types/vadem-ui-text-highlight.d.ts +27 -0
  282. package/types/vadem-ui-time-input.d.ts +47 -0
  283. package/types/vadem-ui-timeline.d.ts +54 -0
  284. package/types/vadem-ui-toast.d.ts +104 -0
  285. package/types/vadem-ui-toolbar.d.ts +80 -0
  286. package/types/vadem-ui-tooltip.d.ts +71 -0
  287. package/types/vadem-ui-tree.d.ts +123 -0
  288. package/types/vadem-ui-upload-list.d.ts +70 -0
  289. package/types/vadem-ui.d.ts +1 -0
@@ -0,0 +1,715 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, DestroyRef, Directive, ElementRef, ViewEncapsulation, afterEveryRender, afterRenderEffect, booleanAttribute, computed, inject, input, output, signal, untracked, viewChild } from "@angular/core";
3
+ import { vdUniqueId } from "@vadem/ui/field";
4
+ import { vdListTarget } from "@vadem/ui/keyboard";
5
+ import { vdTexts } from "@vadem/ui/locale";
6
+ import { VdTextHighlight } from "@vadem/ui/text-highlight";
7
+ import { FormResetEvent, NgControl } from "@angular/forms";
8
+ import { FormField } from "@angular/forms/signals";
9
+ import { VdInput } from "@vadem/ui/input";
10
+ function vdAutocompleteActive(options, id) {
11
+ return options.find((option) => option.id === id && !option.disabled);
12
+ }
13
+ function vdAutocompleteMove(options, id, key) {
14
+ const index = vdListTarget(key, options.findIndex((option) => option.id === id), options.map((option) => !!option.disabled), {
15
+ loop: false,
16
+ pageSize: 10
17
+ });
18
+ return index === null ? null : options[index]?.id ?? null;
19
+ }
20
+ function vdAutocompletePlacement(anchor, viewport, height, gap, rtl) {
21
+ const width = Math.max(0, Math.min(anchor.width, viewport.width - gap * 2));
22
+ const below = Math.max(0, viewport.height - anchor.bottom - gap * 2);
23
+ const above = Math.max(0, anchor.top - gap * 2);
24
+ const flip = height > below && above > below;
25
+ const available = flip ? above : below;
26
+ const top = Math.max(gap, flip ? anchor.top - Math.min(height, available) - gap : anchor.bottom + gap);
27
+ const start = rtl ? viewport.width - anchor.right : anchor.left;
28
+ return {
29
+ width,
30
+ top,
31
+ inline: Math.max(gap, Math.min(start, viewport.width - width - gap)),
32
+ available
33
+ };
34
+ }
35
+ var VdAutocomplete = class VdAutocomplete {
36
+ options = input([], ...ngDevMode ? [{ debugName: "options" }] : /* istanbul ignore next */ []);
37
+ highlightQuery = input("", ...ngDevMode ? [{ debugName: "highlightQuery" }] : /* istanbul ignore next */ []);
38
+ loading = input(false, {
39
+ ...ngDevMode ? { debugName: "loading" } : /* istanbul ignore next */ {},
40
+ transform: booleanAttribute
41
+ });
42
+ errorText = input("", ...ngDevMode ? [{ debugName: "errorText" }] : /* istanbul ignore next */ []);
43
+ label = input(...ngDevMode ? [void 0, { debugName: "label" }] : /* istanbul ignore next */ []);
44
+ loadingText = input(...ngDevMode ? [void 0, { debugName: "loadingText" }] : /* istanbul ignore next */ []);
45
+ emptyText = input(...ngDevMode ? [void 0, { debugName: "emptyText" }] : /* istanbul ignore next */ []);
46
+ resultsText = input(...ngDevMode ? [void 0, { debugName: "resultsText" }] : /* istanbul ignore next */ []);
47
+ t = vdTexts("autocomplete", {
48
+ label: this.label,
49
+ loadingText: this.loadingText,
50
+ emptyText: this.emptyText,
51
+ resultsText: this.resultsText
52
+ });
53
+ optionSelected = output();
54
+ listboxId = vdUniqueId("vd-autocomplete");
55
+ expanded = signal(false, ...ngDevMode ? [{ debugName: "expanded" }] : /* istanbul ignore next */ []);
56
+ fallback = signal(false, ...ngDevMode ? [{ debugName: "fallback" }] : /* istanbul ignore next */ []);
57
+ popup = viewChild.required("popup", ...ngDevMode ? [{ debugName: "popup" }] : /* istanbul ignore next */ []);
58
+ activeKey = signal(null, ...ngDevMode ? [{ debugName: "activeKey" }] : /* istanbul ignore next */ []);
59
+ owner = null;
60
+ cleanup = null;
61
+ availableOptions = computed(() => this.loading() || this.errorText() ? [] : this.options(), ...ngDevMode ? [{ debugName: "availableOptions" }] : /* istanbul ignore next */ []);
62
+ active = computed(() => vdAutocompleteActive(this.availableOptions(), this.activeKey()), ...ngDevMode ? [{ debugName: "active" }] : /* istanbul ignore next */ []);
63
+ activeId = computed(() => this.expanded() && this.active() ? this.optionId(this.active()) : null, ...ngDevMode ? [{ debugName: "activeId" }] : /* istanbul ignore next */ []);
64
+ message = computed(() => this.loading() ? this.t().loadingText : this.errorText() || (this.availableOptions().length ? this.t().resultsText(this.availableOptions().filter((o) => !o.disabled).length) : this.t().emptyText), ...ngDevMode ? [{ debugName: "message" }] : /* istanbul ignore next */ []);
65
+ constructor() {
66
+ inject(DestroyRef).onDestroy(() => {
67
+ this.close();
68
+ this.cleanup?.();
69
+ this.owner = null;
70
+ });
71
+ afterRenderEffect(() => {
72
+ const active = this.active();
73
+ if (!active && this.activeKey() !== null) this.activeKey.set(null);
74
+ if (this.expanded() && active) this.popup().nativeElement.ownerDocument.getElementById(this.optionId(active))?.scrollIntoView({
75
+ block: "nearest",
76
+ inline: "nearest"
77
+ });
78
+ });
79
+ afterEveryRender(() => {
80
+ if (this.expanded()) this.position();
81
+ });
82
+ }
83
+ connect(owner) {
84
+ if (this.owner && this.owner !== owner) throw new Error("An autocomplete panel requires a single input.");
85
+ this.owner = owner;
86
+ const popup = this.popup().nativeElement;
87
+ const doc = owner.element.ownerDocument;
88
+ const win = doc.defaultView;
89
+ this.fallback.set(typeof popup.showPopover !== "function");
90
+ const outside = (event) => {
91
+ const path = event.composedPath();
92
+ if (!path.includes(owner.element) && !path.includes(popup)) this.close();
93
+ };
94
+ const reposition = () => {
95
+ if (this.expanded()) this.position();
96
+ };
97
+ doc.addEventListener("pointerdown", outside, true);
98
+ doc.addEventListener("scroll", reposition, true);
99
+ win?.addEventListener("resize", reposition);
100
+ win?.visualViewport?.addEventListener("resize", reposition);
101
+ const observer = win?.ResizeObserver ? new win.ResizeObserver(reposition) : null;
102
+ observer?.observe(owner.element);
103
+ const cleanup = () => {
104
+ doc.removeEventListener("pointerdown", outside, true);
105
+ doc.removeEventListener("scroll", reposition, true);
106
+ win?.removeEventListener("resize", reposition);
107
+ win?.visualViewport?.removeEventListener("resize", reposition);
108
+ observer?.disconnect();
109
+ };
110
+ this.cleanup = cleanup;
111
+ return () => {
112
+ if (this.owner !== owner) return;
113
+ this.close();
114
+ cleanup();
115
+ this.cleanup = null;
116
+ this.owner = null;
117
+ };
118
+ }
119
+ open() {
120
+ if (!this.owner || this.owner.locked() || this.expanded()) return;
121
+ this.activeKey.set(null);
122
+ this.expanded.set(true);
123
+ const popup = this.popup().nativeElement;
124
+ if (!this.fallback()) popup.showPopover({ source: this.owner.element });
125
+ this.position();
126
+ }
127
+ close() {
128
+ if (!this.expanded()) return;
129
+ this.expanded.set(false);
130
+ this.activeKey.set(null);
131
+ const popup = this.popup().nativeElement;
132
+ if (!this.fallback() && popup.matches(":popover-open")) popup.hidePopover();
133
+ }
134
+ resetActive() {
135
+ this.activeKey.set(null);
136
+ }
137
+ navigate(key) {
138
+ this.open();
139
+ if (!this.expanded() || this.owner?.locked()) return;
140
+ if (!this.availableOptions().some((option) => !option.disabled)) {
141
+ const popup = this.popup().nativeElement;
142
+ const line = Number.parseFloat(popup.ownerDocument.defaultView.getComputedStyle(popup).lineHeight);
143
+ popup.scrollBy?.({ top: (key === "ArrowDown" ? 1 : -1) * line });
144
+ }
145
+ this.activeKey.set(vdAutocompleteMove(this.availableOptions(), this.active()?.id ?? null, key));
146
+ }
147
+ choose(id) {
148
+ if (!this.expanded() || !this.owner || this.owner.locked()) return;
149
+ const option = vdAutocompleteActive(this.availableOptions(), id);
150
+ if (!option) return;
151
+ this.close();
152
+ this.owner.accept(option);
153
+ this.optionSelected.emit(option);
154
+ }
155
+ hover(option) {
156
+ if (!option.disabled) this.activeKey.set(option.id);
157
+ }
158
+ optionId(option) {
159
+ return `${this.listboxId}-${encodeURIComponent(option.id)}`;
160
+ }
161
+ syncToggle() {
162
+ if (!this.fallback() && !this.popup().nativeElement.matches(":popover-open")) this.close();
163
+ }
164
+ position() {
165
+ const input = this.owner?.element;
166
+ const popup = this.popup().nativeElement;
167
+ const win = input?.ownerDocument.defaultView;
168
+ if (!input || !win) return;
169
+ popup.dir = win.getComputedStyle(input).direction;
170
+ const style = win.getComputedStyle(popup);
171
+ const gap = Number.parseFloat(style.paddingInlineStart) || 0;
172
+ popup.style.removeProperty("--vd-autocomplete-available-block");
173
+ const cap = Number.parseFloat(win.getComputedStyle(popup).maxBlockSize);
174
+ const rect = vdAutocompletePlacement(input.getBoundingClientRect(), {
175
+ width: input.ownerDocument.documentElement.getBoundingClientRect().width,
176
+ height: win.visualViewport?.height ?? win.innerHeight
177
+ }, Math.min(popup.scrollHeight, Number.isFinite(cap) ? cap : popup.scrollHeight), gap, win.getComputedStyle(input).direction === "rtl");
178
+ popup.style.setProperty("inset-block-start", `${rect.top}px`);
179
+ popup.style.setProperty("inset-inline-start", `${rect.inline}px`);
180
+ popup.style.setProperty("inline-size", `${rect.width}px`);
181
+ popup.style.setProperty("--vd-autocomplete-available-block", `${rect.available}px`);
182
+ }
183
+ static ɵfac = i0.ɵɵngDeclareFactory({
184
+ minVersion: "12.0.0",
185
+ version: "22.2.1",
186
+ ngImport: i0,
187
+ type: VdAutocomplete,
188
+ deps: [],
189
+ target: i0.ɵɵFactoryTarget.Component
190
+ });
191
+ static ɵcmp = i0.ɵɵngDeclareComponent({
192
+ minVersion: "17.0.0",
193
+ version: "22.2.1",
194
+ type: VdAutocomplete,
195
+ isStandalone: true,
196
+ selector: "vd-autocomplete",
197
+ inputs: {
198
+ options: {
199
+ classPropertyName: "options",
200
+ publicName: "options",
201
+ isSignal: true,
202
+ isRequired: false,
203
+ transformFunction: null
204
+ },
205
+ highlightQuery: {
206
+ classPropertyName: "highlightQuery",
207
+ publicName: "highlightQuery",
208
+ isSignal: true,
209
+ isRequired: false,
210
+ transformFunction: null
211
+ },
212
+ loading: {
213
+ classPropertyName: "loading",
214
+ publicName: "loading",
215
+ isSignal: true,
216
+ isRequired: false,
217
+ transformFunction: null
218
+ },
219
+ errorText: {
220
+ classPropertyName: "errorText",
221
+ publicName: "errorText",
222
+ isSignal: true,
223
+ isRequired: false,
224
+ transformFunction: null
225
+ },
226
+ label: {
227
+ classPropertyName: "label",
228
+ publicName: "label",
229
+ isSignal: true,
230
+ isRequired: false,
231
+ transformFunction: null
232
+ },
233
+ loadingText: {
234
+ classPropertyName: "loadingText",
235
+ publicName: "loadingText",
236
+ isSignal: true,
237
+ isRequired: false,
238
+ transformFunction: null
239
+ },
240
+ emptyText: {
241
+ classPropertyName: "emptyText",
242
+ publicName: "emptyText",
243
+ isSignal: true,
244
+ isRequired: false,
245
+ transformFunction: null
246
+ },
247
+ resultsText: {
248
+ classPropertyName: "resultsText",
249
+ publicName: "resultsText",
250
+ isSignal: true,
251
+ isRequired: false,
252
+ transformFunction: null
253
+ }
254
+ },
255
+ outputs: { optionSelected: "optionSelected" },
256
+ host: { classAttribute: "vd-autocomplete" },
257
+ viewQueries: [{
258
+ propertyName: "popup",
259
+ first: true,
260
+ predicate: ["popup"],
261
+ descendants: true,
262
+ isSignal: true
263
+ }],
264
+ ngImport: i0,
265
+ template: `
266
+ <div
267
+ #popup
268
+ class="vd-autocomplete__popup"
269
+ popover="auto"
270
+ role="listbox"
271
+ [id]="listboxId"
272
+ [attr.aria-label]="t().label"
273
+ [attr.aria-busy]="loading()"
274
+ [attr.data-open]="expanded() ? '' : null"
275
+ [attr.data-fallback]="fallback() ? '' : null"
276
+ [attr.data-state]="loading() ? 'loading' : errorText() ? 'error' : 'ready'"
277
+ (toggle)="syncToggle()"
278
+ (mousedown)="$event.preventDefault()"
279
+ >
280
+ @for (option of availableOptions(); track option.id) {
281
+ <!-- Options are operated from the input through aria-activedescendant. -->
282
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
283
+ <div
284
+ class="vd-autocomplete__option"
285
+ role="option"
286
+ [id]="optionId(option)"
287
+ [attr.aria-label]="option.label"
288
+ [attr.aria-describedby]="option.description ? optionId(option) + '-description' : null"
289
+ [attr.aria-selected]="active()?.id === option.id"
290
+ [attr.aria-disabled]="option.disabled || null"
291
+ [attr.data-active]="active()?.id === option.id ? '' : null"
292
+ (pointermove)="hover(option)"
293
+ (click)="choose(option.id)"
294
+ >
295
+ <span class="vd-autocomplete__label">
296
+ @if (highlightQuery()) {
297
+ <vd-text-highlight [text]="option.label" [query]="highlightQuery()" />
298
+ } @else {
299
+ <ng-container>{{ option.label }}</ng-container>
300
+ }
301
+ </span>
302
+ @if (option.description) {
303
+ <span class="vd-autocomplete__description" [id]="optionId(option) + '-description'">{{
304
+ option.description
305
+ }}</span>
306
+ }
307
+ </div>
308
+ }
309
+ @if (loading() || errorText() || !availableOptions().length) {
310
+ <p class="vd-autocomplete__message" aria-hidden="true">{{ message() }}</p>
311
+ }
312
+ </div>
313
+ <p class="vd-visually-hidden" role="status" aria-atomic="true">
314
+ {{ expanded() ? message() : '' }}
315
+ </p>
316
+ `,
317
+ isInline: true,
318
+ dependencies: [{
319
+ kind: "component",
320
+ type: VdTextHighlight,
321
+ selector: "vd-text-highlight",
322
+ inputs: ["text", "query"]
323
+ }],
324
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
325
+ encapsulation: i0.ViewEncapsulation.None
326
+ });
327
+ };
328
+ i0.ɵɵngDeclareClassMetadata({
329
+ minVersion: "12.0.0",
330
+ version: "22.2.1",
331
+ ngImport: i0,
332
+ type: VdAutocomplete,
333
+ decorators: [{
334
+ type: Component,
335
+ args: [{
336
+ selector: "vd-autocomplete",
337
+ imports: [VdTextHighlight],
338
+ template: `
339
+ <div
340
+ #popup
341
+ class="vd-autocomplete__popup"
342
+ popover="auto"
343
+ role="listbox"
344
+ [id]="listboxId"
345
+ [attr.aria-label]="t().label"
346
+ [attr.aria-busy]="loading()"
347
+ [attr.data-open]="expanded() ? '' : null"
348
+ [attr.data-fallback]="fallback() ? '' : null"
349
+ [attr.data-state]="loading() ? 'loading' : errorText() ? 'error' : 'ready'"
350
+ (toggle)="syncToggle()"
351
+ (mousedown)="$event.preventDefault()"
352
+ >
353
+ @for (option of availableOptions(); track option.id) {
354
+ <!-- Options are operated from the input through aria-activedescendant. -->
355
+ <!-- eslint-disable-next-line @angular-eslint/template/click-events-have-key-events, @angular-eslint/template/interactive-supports-focus -->
356
+ <div
357
+ class="vd-autocomplete__option"
358
+ role="option"
359
+ [id]="optionId(option)"
360
+ [attr.aria-label]="option.label"
361
+ [attr.aria-describedby]="option.description ? optionId(option) + '-description' : null"
362
+ [attr.aria-selected]="active()?.id === option.id"
363
+ [attr.aria-disabled]="option.disabled || null"
364
+ [attr.data-active]="active()?.id === option.id ? '' : null"
365
+ (pointermove)="hover(option)"
366
+ (click)="choose(option.id)"
367
+ >
368
+ <span class="vd-autocomplete__label">
369
+ @if (highlightQuery()) {
370
+ <vd-text-highlight [text]="option.label" [query]="highlightQuery()" />
371
+ } @else {
372
+ <ng-container>{{ option.label }}</ng-container>
373
+ }
374
+ </span>
375
+ @if (option.description) {
376
+ <span class="vd-autocomplete__description" [id]="optionId(option) + '-description'">{{
377
+ option.description
378
+ }}</span>
379
+ }
380
+ </div>
381
+ }
382
+ @if (loading() || errorText() || !availableOptions().length) {
383
+ <p class="vd-autocomplete__message" aria-hidden="true">{{ message() }}</p>
384
+ }
385
+ </div>
386
+ <p class="vd-visually-hidden" role="status" aria-atomic="true">
387
+ {{ expanded() ? message() : '' }}
388
+ </p>
389
+ `,
390
+ host: { class: "vd-autocomplete" },
391
+ changeDetection: ChangeDetectionStrategy.OnPush,
392
+ encapsulation: ViewEncapsulation.None
393
+ }]
394
+ }],
395
+ ctorParameters: () => [],
396
+ propDecorators: {
397
+ options: [{
398
+ type: i0.Input,
399
+ args: [{
400
+ isSignal: true,
401
+ alias: "options",
402
+ required: false
403
+ }]
404
+ }],
405
+ highlightQuery: [{
406
+ type: i0.Input,
407
+ args: [{
408
+ isSignal: true,
409
+ alias: "highlightQuery",
410
+ required: false
411
+ }]
412
+ }],
413
+ loading: [{
414
+ type: i0.Input,
415
+ args: [{
416
+ isSignal: true,
417
+ alias: "loading",
418
+ required: false
419
+ }]
420
+ }],
421
+ errorText: [{
422
+ type: i0.Input,
423
+ args: [{
424
+ isSignal: true,
425
+ alias: "errorText",
426
+ required: false
427
+ }]
428
+ }],
429
+ label: [{
430
+ type: i0.Input,
431
+ args: [{
432
+ isSignal: true,
433
+ alias: "label",
434
+ required: false
435
+ }]
436
+ }],
437
+ loadingText: [{
438
+ type: i0.Input,
439
+ args: [{
440
+ isSignal: true,
441
+ alias: "loadingText",
442
+ required: false
443
+ }]
444
+ }],
445
+ emptyText: [{
446
+ type: i0.Input,
447
+ args: [{
448
+ isSignal: true,
449
+ alias: "emptyText",
450
+ required: false
451
+ }]
452
+ }],
453
+ resultsText: [{
454
+ type: i0.Input,
455
+ args: [{
456
+ isSignal: true,
457
+ alias: "resultsText",
458
+ required: false
459
+ }]
460
+ }],
461
+ optionSelected: [{
462
+ type: i0.Output,
463
+ args: ["optionSelected"]
464
+ }],
465
+ popup: [{
466
+ type: i0.ViewChild,
467
+ args: ["popup", { isSignal: true }]
468
+ }]
469
+ }
470
+ });
471
+ var VdAutocompleteInput = class VdAutocompleteInput extends VdInput {
472
+ vdAutocomplete = input.required(...ngDevMode ? [{ debugName: "vdAutocomplete" }] : /* istanbul ignore next */ []);
473
+ queryChange = output();
474
+ element = inject(ElementRef).nativeElement;
475
+ autocompleteNgControl = inject(NgControl, {
476
+ self: true,
477
+ optional: true
478
+ });
479
+ autocompleteFormField = inject(FormField, {
480
+ self: true,
481
+ optional: true
482
+ });
483
+ autocompleteDestroyRef = inject(DestroyRef);
484
+ composing = false;
485
+ accepting = false;
486
+ lastQuery = null;
487
+ snapshot = null;
488
+ constructor() {
489
+ super();
490
+ afterRenderEffect((cleanup) => {
491
+ const panel = this.vdAutocomplete();
492
+ const disconnect = untracked(() => panel.connect(this));
493
+ const form = this.element.form;
494
+ const reset = () => panel.close();
495
+ form?.addEventListener("reset", reset);
496
+ cleanup(() => {
497
+ form?.removeEventListener("reset", reset);
498
+ disconnect();
499
+ });
500
+ });
501
+ afterEveryRender(() => {
502
+ const snapshot = JSON.stringify([
503
+ this.element.value,
504
+ this.element.disabled,
505
+ this.element.readOnly
506
+ ]);
507
+ if (this.snapshot !== null && this.snapshot !== snapshot) {
508
+ this.vdAutocomplete().close();
509
+ this.lastQuery = null;
510
+ }
511
+ this.snapshot = snapshot;
512
+ });
513
+ inject(DestroyRef).onDestroy(() => {
514
+ this.composing = false;
515
+ });
516
+ }
517
+ ngOnInit() {
518
+ super.ngOnInit();
519
+ if (this.autocompleteFormField) return;
520
+ const subscription = this.autocompleteNgControl?.control?.events.subscribe((event) => {
521
+ if (event instanceof FormResetEvent) {
522
+ this.lastQuery = null;
523
+ this.vdAutocomplete().close();
524
+ }
525
+ });
526
+ this.autocompleteDestroyRef.onDestroy(() => subscription?.unsubscribe());
527
+ }
528
+ locked() {
529
+ return this.element.disabled || this.element.readOnly;
530
+ }
531
+ accept(option) {
532
+ if (this.locked()) return;
533
+ this.element.value = option.label;
534
+ this.remember();
535
+ this.lastQuery = option.label;
536
+ this.accepting = true;
537
+ try {
538
+ const EventType = this.element.ownerDocument.defaultView.Event;
539
+ this.element.dispatchEvent(new EventType("input", { bubbles: true }));
540
+ this.element.dispatchEvent(new EventType("change", { bubbles: true }));
541
+ } finally {
542
+ this.accepting = false;
543
+ }
544
+ this.element.focus({ preventScroll: true });
545
+ if ([
546
+ "text",
547
+ "search",
548
+ "tel",
549
+ "url",
550
+ "password"
551
+ ].includes(this.element.type)) this.element.setSelectionRange(this.element.value.length, this.element.value.length);
552
+ }
553
+ show() {
554
+ if (!this.composing && !this.locked()) this.vdAutocomplete().open();
555
+ }
556
+ onInput(event) {
557
+ this.remember();
558
+ if (this.accepting || this.composing || event.isComposing || this.locked()) return;
559
+ this.publish();
560
+ }
561
+ startComposition() {
562
+ this.composing = true;
563
+ this.vdAutocomplete().close();
564
+ }
565
+ endComposition() {
566
+ this.composing = false;
567
+ this.remember();
568
+ if (!this.locked()) this.publish();
569
+ }
570
+ onKeydown(event) {
571
+ if (this.locked() || this.composing || event.isComposing || event.keyCode === 229) return;
572
+ const panel = this.vdAutocomplete();
573
+ if (event.key === "Tab") {
574
+ panel.close();
575
+ return;
576
+ }
577
+ if (event.key === "Escape" && panel.expanded()) {
578
+ event.preventDefault();
579
+ panel.close();
580
+ return;
581
+ }
582
+ if (event.altKey && event.key === "ArrowUp") {
583
+ event.preventDefault();
584
+ panel.close();
585
+ return;
586
+ }
587
+ if (event.ctrlKey || event.metaKey || event.shiftKey) return;
588
+ if (event.altKey && event.key === "ArrowDown") {
589
+ event.preventDefault();
590
+ panel.open();
591
+ return;
592
+ }
593
+ if (event.altKey) return;
594
+ if (event.key === "ArrowDown" || event.key === "ArrowUp") {
595
+ event.preventDefault();
596
+ panel.navigate(event.key);
597
+ } else if (event.key === "Enter" && panel.expanded() && panel.active()) {
598
+ event.preventDefault();
599
+ panel.choose(panel.active().id);
600
+ }
601
+ }
602
+ remember() {
603
+ this.snapshot = JSON.stringify([
604
+ this.element.value,
605
+ this.element.disabled,
606
+ this.element.readOnly
607
+ ]);
608
+ }
609
+ publish() {
610
+ const panel = this.vdAutocomplete();
611
+ panel.resetActive();
612
+ const value = this.element.value;
613
+ if (value !== this.lastQuery) {
614
+ this.lastQuery = value;
615
+ this.queryChange.emit(value);
616
+ }
617
+ panel.open();
618
+ }
619
+ static ɵfac = i0.ɵɵngDeclareFactory({
620
+ minVersion: "12.0.0",
621
+ version: "22.2.1",
622
+ ngImport: i0,
623
+ type: VdAutocompleteInput,
624
+ deps: [],
625
+ target: i0.ɵɵFactoryTarget.Directive
626
+ });
627
+ static ɵdir = i0.ɵɵngDeclareDirective({
628
+ minVersion: "17.1.0",
629
+ version: "22.2.1",
630
+ type: VdAutocompleteInput,
631
+ isStandalone: true,
632
+ selector: "input[vdAutocomplete]",
633
+ inputs: { vdAutocomplete: {
634
+ classPropertyName: "vdAutocomplete",
635
+ publicName: "vdAutocomplete",
636
+ isSignal: true,
637
+ isRequired: true,
638
+ transformFunction: null
639
+ } },
640
+ outputs: { queryChange: "queryChange" },
641
+ host: {
642
+ attributes: {
643
+ "role": "combobox",
644
+ "aria-autocomplete": "list",
645
+ "aria-haspopup": "listbox",
646
+ "autocomplete": "off"
647
+ },
648
+ listeners: {
649
+ "input": "onInput($event)",
650
+ "focus": "show()",
651
+ "click": "show()",
652
+ "blur": "vdAutocomplete().close()",
653
+ "keydown": "onKeydown($event)",
654
+ "compositionstart": "startComposition()",
655
+ "compositionend": "endComposition()"
656
+ },
657
+ properties: {
658
+ "attr.aria-expanded": "vdAutocomplete().expanded()",
659
+ "attr.aria-controls": "vdAutocomplete().listboxId",
660
+ "attr.aria-activedescendant": "vdAutocomplete().activeId()"
661
+ },
662
+ classAttribute: "vd-autocomplete-input"
663
+ },
664
+ usesInheritance: true,
665
+ ngImport: i0
666
+ });
667
+ };
668
+ i0.ɵɵngDeclareClassMetadata({
669
+ minVersion: "12.0.0",
670
+ version: "22.2.1",
671
+ ngImport: i0,
672
+ type: VdAutocompleteInput,
673
+ decorators: [{
674
+ type: Directive,
675
+ args: [{
676
+ selector: "input[vdAutocomplete]",
677
+ host: {
678
+ class: "vd-autocomplete-input",
679
+ role: "combobox",
680
+ "aria-autocomplete": "list",
681
+ "aria-haspopup": "listbox",
682
+ autocomplete: "off",
683
+ "[attr.aria-expanded]": "vdAutocomplete().expanded()",
684
+ "[attr.aria-controls]": "vdAutocomplete().listboxId",
685
+ "[attr.aria-activedescendant]": "vdAutocomplete().activeId()",
686
+ "(input)": "onInput($event)",
687
+ "(focus)": "show()",
688
+ "(click)": "show()",
689
+ "(blur)": "vdAutocomplete().close()",
690
+ "(keydown)": "onKeydown($event)",
691
+ "(compositionstart)": "startComposition()",
692
+ "(compositionend)": "endComposition()"
693
+ }
694
+ }]
695
+ }],
696
+ ctorParameters: () => [],
697
+ propDecorators: {
698
+ vdAutocomplete: [{
699
+ type: i0.Input,
700
+ args: [{
701
+ isSignal: true,
702
+ alias: "vdAutocomplete",
703
+ required: true
704
+ }]
705
+ }],
706
+ queryChange: [{
707
+ type: i0.Output,
708
+ args: ["queryChange"]
709
+ }]
710
+ }
711
+ });
712
+ const VD_AUTOCOMPLETE = [VdAutocomplete, VdAutocompleteInput];
713
+ export { VD_AUTOCOMPLETE, VdAutocomplete, VdAutocompleteInput };
714
+
715
+ //# sourceMappingURL=vadem-ui-autocomplete.mjs.map