@vadem/ui 0.0.0-stage → 0.0.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 (289) hide show
  1. package/LICENSE-lucide.txt +43 -0
  2. package/README.md +19 -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 +637 -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 +306 -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 +132 -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,532 @@
1
+ import * as i0 from "@angular/core";
2
+ import { ChangeDetectionStrategy, Component, DOCUMENT, DestroyRef, ViewEncapsulation, afterRenderEffect, computed, inject, input, model, signal } from "@angular/core";
3
+ import { DomSanitizer } from "@angular/platform-browser";
4
+ import { VdButton } from "@vadem/ui/button";
5
+ import { VdFileSizePipe } from "@vadem/ui/file-size";
6
+ import * as i1 from "@vadem/ui/dialog";
7
+ import { VD_DIALOG } from "@vadem/ui/dialog";
8
+ import { vdTexts } from "@vadem/ui/locale";
9
+ var VdFilePreview = class VdFilePreview {
10
+ open = model(false, ...ngDevMode ? [{ debugName: "open" }] : /* istanbul ignore next */ []);
11
+ file = input(null, ...ngDevMode ? [{ debugName: "file" }] : /* istanbul ignore next */ []);
12
+ name = input(...ngDevMode ? [void 0, { debugName: "name" }] : /* istanbul ignore next */ []);
13
+ alt = input(...ngDevMode ? [void 0, { debugName: "alt" }] : /* istanbul ignore next */ []);
14
+ closeLabel = input(...ngDevMode ? [void 0, { debugName: "closeLabel" }] : /* istanbul ignore next */ []);
15
+ downloadLabel = input(...ngDevMode ? [void 0, { debugName: "downloadLabel" }] : /* istanbul ignore next */ []);
16
+ loadingText = input(...ngDevMode ? [void 0, { debugName: "loadingText" }] : /* istanbul ignore next */ []);
17
+ errorText = input(...ngDevMode ? [void 0, { debugName: "errorText" }] : /* istanbul ignore next */ []);
18
+ emptyText = input(...ngDevMode ? [void 0, { debugName: "emptyText" }] : /* istanbul ignore next */ []);
19
+ unsupportedText = input(...ngDevMode ? [void 0, { debugName: "unsupportedText" }] : /* istanbul ignore next */ []);
20
+ pdfText = input(...ngDevMode ? [void 0, { debugName: "pdfText" }] : /* istanbul ignore next */ []);
21
+ titleText = input(...ngDevMode ? [void 0, { debugName: "titleText" }] : /* istanbul ignore next */ []);
22
+ t = vdTexts("filePreview", {
23
+ title: this.titleText,
24
+ closeLabel: this.closeLabel,
25
+ downloadLabel: this.downloadLabel,
26
+ loadingText: this.loadingText,
27
+ errorText: this.errorText,
28
+ emptyText: this.emptyText,
29
+ unsupportedText: this.unsupportedText,
30
+ pdfText: this.pdfText
31
+ });
32
+ title = computed(() => this.t().title, ...ngDevMode ? [{ debugName: "title" }] : /* istanbul ignore next */ []);
33
+ filename = computed(() => this.name()?.trim() || this.file()?.name?.trim() || this.title(), ...ngDevMode ? [{ debugName: "filename" }] : /* istanbul ignore next */ []);
34
+ kind = computed(() => {
35
+ const type = this.file()?.type.toLowerCase();
36
+ return type === "application/pdf" ? "pdf" : [
37
+ "image/png",
38
+ "image/jpeg",
39
+ "image/gif",
40
+ "image/webp",
41
+ "image/avif"
42
+ ].includes(type ?? "") ? "image" : "unsupported";
43
+ }, ...ngDevMode ? [{ debugName: "kind" }] : /* istanbul ignore next */ []);
44
+ allocated = signal(null, ...ngDevMode ? [{ debugName: "allocated" }] : /* istanbul ignore next */ []);
45
+ source = computed(() => {
46
+ const source = this.allocated();
47
+ return this.open() && source?.file === this.file() ? source : null;
48
+ }, ...ngDevMode ? [{ debugName: "source" }] : /* istanbul ignore next */ []);
49
+ sources = computed(() => this.source() ? [this.source()] : [], ...ngDevMode ? [{ debugName: "sources" }] : /* istanbul ignore next */ []);
50
+ imageResult = signal("loading", ...ngDevMode ? [{ debugName: "imageResult" }] : /* istanbul ignore next */ []);
51
+ state = computed(() => !this.file() ? "empty" : !this.source() ? "preparing" : this.kind() === "image" ? this.imageResult() : this.kind() === "pdf" ? "pdf" : "unsupported", ...ngDevMode ? [{ debugName: "state" }] : /* istanbul ignore next */ []);
52
+ constructor() {
53
+ const document = inject(DOCUMENT);
54
+ const sanitizer = inject(DomSanitizer);
55
+ let release;
56
+ inject(DestroyRef).onDestroy(() => release?.());
57
+ afterRenderEffect(() => {
58
+ const file = this.file();
59
+ const open = this.open();
60
+ release?.();
61
+ release = void 0;
62
+ this.allocated.set(null);
63
+ this.imageResult.set("loading");
64
+ const urlApi = document.defaultView?.URL;
65
+ if (!open || !file || !urlApi?.createObjectURL) return;
66
+ const blob = file.type.toLowerCase() === "application/pdf" ? file.slice(0, file.size, "application/pdf") : file;
67
+ const url = urlApi.createObjectURL(blob);
68
+ release = () => urlApi.revokeObjectURL(url);
69
+ this.allocated.set({
70
+ file,
71
+ url,
72
+ pdf: file.type.toLowerCase() === "application/pdf" ? sanitizer.bypassSecurityTrustResourceUrl(url) : null
73
+ });
74
+ });
75
+ }
76
+ imageState(source, state) {
77
+ if (this.source() === source) this.imageResult.set(state);
78
+ }
79
+ static ɵfac = i0.ɵɵngDeclareFactory({
80
+ minVersion: "12.0.0",
81
+ version: "22.2.1",
82
+ ngImport: i0,
83
+ type: VdFilePreview,
84
+ deps: [],
85
+ target: i0.ɵɵFactoryTarget.Component
86
+ });
87
+ static ɵcmp = i0.ɵɵngDeclareComponent({
88
+ minVersion: "17.0.0",
89
+ version: "22.2.1",
90
+ type: VdFilePreview,
91
+ isStandalone: true,
92
+ selector: "vd-file-preview",
93
+ inputs: {
94
+ open: {
95
+ classPropertyName: "open",
96
+ publicName: "open",
97
+ isSignal: true,
98
+ isRequired: false,
99
+ transformFunction: null
100
+ },
101
+ file: {
102
+ classPropertyName: "file",
103
+ publicName: "file",
104
+ isSignal: true,
105
+ isRequired: false,
106
+ transformFunction: null
107
+ },
108
+ name: {
109
+ classPropertyName: "name",
110
+ publicName: "name",
111
+ isSignal: true,
112
+ isRequired: false,
113
+ transformFunction: null
114
+ },
115
+ alt: {
116
+ classPropertyName: "alt",
117
+ publicName: "alt",
118
+ isSignal: true,
119
+ isRequired: false,
120
+ transformFunction: null
121
+ },
122
+ closeLabel: {
123
+ classPropertyName: "closeLabel",
124
+ publicName: "closeLabel",
125
+ isSignal: true,
126
+ isRequired: false,
127
+ transformFunction: null
128
+ },
129
+ downloadLabel: {
130
+ classPropertyName: "downloadLabel",
131
+ publicName: "downloadLabel",
132
+ isSignal: true,
133
+ isRequired: false,
134
+ transformFunction: null
135
+ },
136
+ loadingText: {
137
+ classPropertyName: "loadingText",
138
+ publicName: "loadingText",
139
+ isSignal: true,
140
+ isRequired: false,
141
+ transformFunction: null
142
+ },
143
+ errorText: {
144
+ classPropertyName: "errorText",
145
+ publicName: "errorText",
146
+ isSignal: true,
147
+ isRequired: false,
148
+ transformFunction: null
149
+ },
150
+ emptyText: {
151
+ classPropertyName: "emptyText",
152
+ publicName: "emptyText",
153
+ isSignal: true,
154
+ isRequired: false,
155
+ transformFunction: null
156
+ },
157
+ unsupportedText: {
158
+ classPropertyName: "unsupportedText",
159
+ publicName: "unsupportedText",
160
+ isSignal: true,
161
+ isRequired: false,
162
+ transformFunction: null
163
+ },
164
+ pdfText: {
165
+ classPropertyName: "pdfText",
166
+ publicName: "pdfText",
167
+ isSignal: true,
168
+ isRequired: false,
169
+ transformFunction: null
170
+ },
171
+ titleText: {
172
+ classPropertyName: "titleText",
173
+ publicName: "titleText",
174
+ isSignal: true,
175
+ isRequired: false,
176
+ transformFunction: null
177
+ }
178
+ },
179
+ outputs: { open: "openChange" },
180
+ host: { classAttribute: "vd-file-preview" },
181
+ ngImport: i0,
182
+ template: `
183
+ <dialog
184
+ vdDialog
185
+ size="lg"
186
+ class="vd-file-preview__dialog"
187
+ [open]="open()"
188
+ (openChange)="open.set($event)"
189
+ >
190
+ <header vdDialogHeader>
191
+ <span class="vd-file-preview__heading">{{ title() }}</span>
192
+ <button
193
+ vdButton
194
+ variant="ghost"
195
+ size="sm"
196
+ type="button"
197
+ autofocus
198
+ (click)="open.set(false)"
199
+ >
200
+ {{ t().closeLabel }}
201
+ </button>
202
+ </header>
203
+ <div
204
+ vdDialogBody
205
+ class="vd-file-preview__body"
206
+ tabindex="0"
207
+ role="region"
208
+ [attr.aria-label]="filename()"
209
+ [attr.data-state]="state()"
210
+ >
211
+ <h2 vdDialogTitle class="vd-file-preview__filename">
212
+ <bdi>{{ filename() }}</bdi>
213
+ </h2>
214
+ @if (file(); as file) {
215
+ <p class="vd-file-preview__size">
216
+ <bdi>{{ file.size | vdFileSize }}</bdi>
217
+ </p>
218
+ }
219
+ @if (open()) {
220
+ @for (source of sources(); track source.url) {
221
+ @if (kind() === 'image') {
222
+ <p class="vd-file-preview__notice" role="status">
223
+ {{
224
+ state() === 'loading' ? t().loadingText : state() === 'error' ? t().errorText : ''
225
+ }}
226
+ </p>
227
+ @if (state() !== 'error') {
228
+ <img
229
+ class="vd-file-preview__image"
230
+ [src]="source.url"
231
+ [alt]="alt() ?? filename()"
232
+ [hidden]="state() !== 'ready'"
233
+ (load)="imageState(source, 'ready')"
234
+ (error)="imageState(source, 'error')"
235
+ />
236
+ }
237
+ } @else if (kind() === 'pdf') {
238
+ <p class="vd-file-preview__notice">{{ t().pdfText }}</p>
239
+ <object
240
+ class="vd-file-preview__pdf"
241
+ [data]="source.pdf"
242
+ type="application/pdf"
243
+ [attr.aria-label]="filename()"
244
+ >
245
+ <p>{{ t().pdfText }}</p>
246
+ </object>
247
+ } @else {
248
+ <p class="vd-file-preview__notice">{{ t().unsupportedText }}</p>
249
+ }
250
+ } @empty {
251
+ <p class="vd-file-preview__notice" role="status">
252
+ {{ file() ? t().loadingText : t().emptyText }}
253
+ </p>
254
+ }
255
+ }
256
+ </div>
257
+ @if (source(); as source) {
258
+ <footer vdDialogFooter>
259
+ <a vdButton variant="secondary" [href]="source.url" [download]="filename()">{{
260
+ t().downloadLabel
261
+ }}</a>
262
+ </footer>
263
+ }
264
+ </dialog>
265
+ `,
266
+ isInline: true,
267
+ dependencies: [
268
+ {
269
+ kind: "component",
270
+ type: VdButton,
271
+ selector: "button[vdButton], a[vdButton]",
272
+ inputs: [
273
+ "variant",
274
+ "size",
275
+ "disabled",
276
+ "loading",
277
+ "iconOnly",
278
+ "type"
279
+ ]
280
+ },
281
+ {
282
+ kind: "directive",
283
+ type: i1.VdDialog,
284
+ selector: "dialog[vdDialog]",
285
+ inputs: [
286
+ "open",
287
+ "size",
288
+ "placement",
289
+ "dismissible"
290
+ ],
291
+ outputs: ["openChange", "closed"],
292
+ exportAs: ["vdDialog"]
293
+ },
294
+ {
295
+ kind: "directive",
296
+ type: i1.VdDialogHeader,
297
+ selector: "[vdDialogHeader]"
298
+ },
299
+ {
300
+ kind: "directive",
301
+ type: i1.VdDialogTitle,
302
+ selector: "[vdDialogTitle]"
303
+ },
304
+ {
305
+ kind: "directive",
306
+ type: i1.VdDialogBody,
307
+ selector: "[vdDialogBody]"
308
+ },
309
+ {
310
+ kind: "directive",
311
+ type: i1.VdDialogFooter,
312
+ selector: "[vdDialogFooter]"
313
+ },
314
+ {
315
+ kind: "pipe",
316
+ type: VdFileSizePipe,
317
+ name: "vdFileSize"
318
+ }
319
+ ],
320
+ changeDetection: i0.ChangeDetectionStrategy.OnPush,
321
+ encapsulation: i0.ViewEncapsulation.None
322
+ });
323
+ };
324
+ i0.ɵɵngDeclareClassMetadata({
325
+ minVersion: "12.0.0",
326
+ version: "22.2.1",
327
+ ngImport: i0,
328
+ type: VdFilePreview,
329
+ decorators: [{
330
+ type: Component,
331
+ args: [{
332
+ selector: "vd-file-preview",
333
+ imports: [
334
+ VdButton,
335
+ VD_DIALOG,
336
+ VdFileSizePipe
337
+ ],
338
+ template: `
339
+ <dialog
340
+ vdDialog
341
+ size="lg"
342
+ class="vd-file-preview__dialog"
343
+ [open]="open()"
344
+ (openChange)="open.set($event)"
345
+ >
346
+ <header vdDialogHeader>
347
+ <span class="vd-file-preview__heading">{{ title() }}</span>
348
+ <button
349
+ vdButton
350
+ variant="ghost"
351
+ size="sm"
352
+ type="button"
353
+ autofocus
354
+ (click)="open.set(false)"
355
+ >
356
+ {{ t().closeLabel }}
357
+ </button>
358
+ </header>
359
+ <div
360
+ vdDialogBody
361
+ class="vd-file-preview__body"
362
+ tabindex="0"
363
+ role="region"
364
+ [attr.aria-label]="filename()"
365
+ [attr.data-state]="state()"
366
+ >
367
+ <h2 vdDialogTitle class="vd-file-preview__filename">
368
+ <bdi>{{ filename() }}</bdi>
369
+ </h2>
370
+ @if (file(); as file) {
371
+ <p class="vd-file-preview__size">
372
+ <bdi>{{ file.size | vdFileSize }}</bdi>
373
+ </p>
374
+ }
375
+ @if (open()) {
376
+ @for (source of sources(); track source.url) {
377
+ @if (kind() === 'image') {
378
+ <p class="vd-file-preview__notice" role="status">
379
+ {{
380
+ state() === 'loading' ? t().loadingText : state() === 'error' ? t().errorText : ''
381
+ }}
382
+ </p>
383
+ @if (state() !== 'error') {
384
+ <img
385
+ class="vd-file-preview__image"
386
+ [src]="source.url"
387
+ [alt]="alt() ?? filename()"
388
+ [hidden]="state() !== 'ready'"
389
+ (load)="imageState(source, 'ready')"
390
+ (error)="imageState(source, 'error')"
391
+ />
392
+ }
393
+ } @else if (kind() === 'pdf') {
394
+ <p class="vd-file-preview__notice">{{ t().pdfText }}</p>
395
+ <object
396
+ class="vd-file-preview__pdf"
397
+ [data]="source.pdf"
398
+ type="application/pdf"
399
+ [attr.aria-label]="filename()"
400
+ >
401
+ <p>{{ t().pdfText }}</p>
402
+ </object>
403
+ } @else {
404
+ <p class="vd-file-preview__notice">{{ t().unsupportedText }}</p>
405
+ }
406
+ } @empty {
407
+ <p class="vd-file-preview__notice" role="status">
408
+ {{ file() ? t().loadingText : t().emptyText }}
409
+ </p>
410
+ }
411
+ }
412
+ </div>
413
+ @if (source(); as source) {
414
+ <footer vdDialogFooter>
415
+ <a vdButton variant="secondary" [href]="source.url" [download]="filename()">{{
416
+ t().downloadLabel
417
+ }}</a>
418
+ </footer>
419
+ }
420
+ </dialog>
421
+ `,
422
+ host: { class: "vd-file-preview" },
423
+ changeDetection: ChangeDetectionStrategy.OnPush,
424
+ encapsulation: ViewEncapsulation.None
425
+ }]
426
+ }],
427
+ ctorParameters: () => [],
428
+ propDecorators: {
429
+ open: [{
430
+ type: i0.Input,
431
+ args: [{
432
+ isSignal: true,
433
+ alias: "open",
434
+ required: false
435
+ }]
436
+ }, {
437
+ type: i0.Output,
438
+ args: ["openChange"]
439
+ }],
440
+ file: [{
441
+ type: i0.Input,
442
+ args: [{
443
+ isSignal: true,
444
+ alias: "file",
445
+ required: false
446
+ }]
447
+ }],
448
+ name: [{
449
+ type: i0.Input,
450
+ args: [{
451
+ isSignal: true,
452
+ alias: "name",
453
+ required: false
454
+ }]
455
+ }],
456
+ alt: [{
457
+ type: i0.Input,
458
+ args: [{
459
+ isSignal: true,
460
+ alias: "alt",
461
+ required: false
462
+ }]
463
+ }],
464
+ closeLabel: [{
465
+ type: i0.Input,
466
+ args: [{
467
+ isSignal: true,
468
+ alias: "closeLabel",
469
+ required: false
470
+ }]
471
+ }],
472
+ downloadLabel: [{
473
+ type: i0.Input,
474
+ args: [{
475
+ isSignal: true,
476
+ alias: "downloadLabel",
477
+ required: false
478
+ }]
479
+ }],
480
+ loadingText: [{
481
+ type: i0.Input,
482
+ args: [{
483
+ isSignal: true,
484
+ alias: "loadingText",
485
+ required: false
486
+ }]
487
+ }],
488
+ errorText: [{
489
+ type: i0.Input,
490
+ args: [{
491
+ isSignal: true,
492
+ alias: "errorText",
493
+ required: false
494
+ }]
495
+ }],
496
+ emptyText: [{
497
+ type: i0.Input,
498
+ args: [{
499
+ isSignal: true,
500
+ alias: "emptyText",
501
+ required: false
502
+ }]
503
+ }],
504
+ unsupportedText: [{
505
+ type: i0.Input,
506
+ args: [{
507
+ isSignal: true,
508
+ alias: "unsupportedText",
509
+ required: false
510
+ }]
511
+ }],
512
+ pdfText: [{
513
+ type: i0.Input,
514
+ args: [{
515
+ isSignal: true,
516
+ alias: "pdfText",
517
+ required: false
518
+ }]
519
+ }],
520
+ titleText: [{
521
+ type: i0.Input,
522
+ args: [{
523
+ isSignal: true,
524
+ alias: "titleText",
525
+ required: false
526
+ }]
527
+ }]
528
+ }
529
+ });
530
+ export { VdFilePreview };
531
+
532
+ //# sourceMappingURL=vadem-ui-file-preview.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vadem-ui-file-preview.mjs","names":[],"sources":["../../../projects/ui/file-preview/src/file-preview.ts"],"sourcesContent":["import {\n ChangeDetectionStrategy,\n Component,\n DestroyRef,\n DOCUMENT,\n ViewEncapsulation,\n afterRenderEffect,\n computed,\n inject,\n input,\n model,\n signal,\n} from '@angular/core';\nimport { DomSanitizer, type SafeResourceUrl } from '@angular/platform-browser';\nimport { VdButton } from '@vadem/ui/button';\nimport { VdFileSizePipe } from '@vadem/ui/file-size';\nimport { VD_DIALOG } from '@vadem/ui/dialog';\nimport { vdTexts } from '@vadem/ui/locale';\n\ntype PreviewState = 'empty' | 'preparing' | 'loading' | 'ready' | 'error' | 'unsupported' | 'pdf';\ninterface PreviewSource {\n file: Blob;\n url: string;\n pdf: SafeResourceUrl | null;\n}\n\n/** Local file presentation. The caller owns file acquisition and validation. */\n@Component({\n selector: 'vd-file-preview',\n imports: [VdButton, VD_DIALOG, VdFileSizePipe],\n template: `\n <dialog\n vdDialog\n size=\"lg\"\n class=\"vd-file-preview__dialog\"\n [open]=\"open()\"\n (openChange)=\"open.set($event)\"\n >\n <header vdDialogHeader>\n <span class=\"vd-file-preview__heading\">{{ title() }}</span>\n <button\n vdButton\n variant=\"ghost\"\n size=\"sm\"\n type=\"button\"\n autofocus\n (click)=\"open.set(false)\"\n >\n {{ t().closeLabel }}\n </button>\n </header>\n <div\n vdDialogBody\n class=\"vd-file-preview__body\"\n tabindex=\"0\"\n role=\"region\"\n [attr.aria-label]=\"filename()\"\n [attr.data-state]=\"state()\"\n >\n <h2 vdDialogTitle class=\"vd-file-preview__filename\">\n <bdi>{{ filename() }}</bdi>\n </h2>\n @if (file(); as file) {\n <p class=\"vd-file-preview__size\">\n <bdi>{{ file.size | vdFileSize }}</bdi>\n </p>\n }\n @if (open()) {\n @for (source of sources(); track source.url) {\n @if (kind() === 'image') {\n <p class=\"vd-file-preview__notice\" role=\"status\">\n {{\n state() === 'loading' ? t().loadingText : state() === 'error' ? t().errorText : ''\n }}\n </p>\n @if (state() !== 'error') {\n <img\n class=\"vd-file-preview__image\"\n [src]=\"source.url\"\n [alt]=\"alt() ?? filename()\"\n [hidden]=\"state() !== 'ready'\"\n (load)=\"imageState(source, 'ready')\"\n (error)=\"imageState(source, 'error')\"\n />\n }\n } @else if (kind() === 'pdf') {\n <p class=\"vd-file-preview__notice\">{{ t().pdfText }}</p>\n <object\n class=\"vd-file-preview__pdf\"\n [data]=\"source.pdf\"\n type=\"application/pdf\"\n [attr.aria-label]=\"filename()\"\n >\n <p>{{ t().pdfText }}</p>\n </object>\n } @else {\n <p class=\"vd-file-preview__notice\">{{ t().unsupportedText }}</p>\n }\n } @empty {\n <p class=\"vd-file-preview__notice\" role=\"status\">\n {{ file() ? t().loadingText : t().emptyText }}\n </p>\n }\n }\n </div>\n @if (source(); as source) {\n <footer vdDialogFooter>\n <a vdButton variant=\"secondary\" [href]=\"source.url\" [download]=\"filename()\">{{\n t().downloadLabel\n }}</a>\n </footer>\n }\n </dialog>\n `,\n host: { class: 'vd-file-preview' },\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n})\nexport class VdFilePreview {\n readonly open = model(false);\n readonly file = input<Blob | null>(null);\n readonly name = input<string>();\n readonly alt = input<string>();\n readonly closeLabel = input<string>();\n readonly downloadLabel = input<string>();\n readonly loadingText = input<string>();\n readonly errorText = input<string>();\n readonly emptyText = input<string>();\n readonly unsupportedText = input<string>();\n readonly pdfText = input<string>();\n readonly titleText = input<string>();\n protected readonly t = vdTexts('filePreview', {\n title: this.titleText,\n closeLabel: this.closeLabel,\n downloadLabel: this.downloadLabel,\n loadingText: this.loadingText,\n errorText: this.errorText,\n emptyText: this.emptyText,\n unsupportedText: this.unsupportedText,\n pdfText: this.pdfText,\n });\n protected readonly title = computed(() => this.t().title);\n protected readonly filename = computed(\n () =>\n this.name()?.trim() ||\n (this.file() as (Blob & { name?: string }) | null)?.name?.trim() ||\n this.title(),\n );\n protected readonly kind = computed(() => {\n const type = this.file()?.type.toLowerCase();\n return type === 'application/pdf'\n ? 'pdf'\n : ['image/png', 'image/jpeg', 'image/gif', 'image/webp', 'image/avif'].includes(type ?? '')\n ? 'image'\n : 'unsupported';\n });\n private readonly allocated = signal<PreviewSource | null>(null);\n protected readonly source = computed(() => {\n const source = this.allocated();\n return this.open() && source?.file === this.file() ? source : null;\n });\n protected readonly sources = computed(() => (this.source() ? [this.source()!] : []));\n private readonly imageResult = signal<PreviewState>('loading');\n protected readonly state = computed<PreviewState>(() =>\n !this.file()\n ? 'empty'\n : !this.source()\n ? 'preparing'\n : this.kind() === 'image'\n ? this.imageResult()\n : this.kind() === 'pdf'\n ? 'pdf'\n : 'unsupported',\n );\n\n constructor() {\n const document = inject(DOCUMENT);\n const sanitizer = inject(DomSanitizer);\n let release: (() => void) | undefined;\n inject(DestroyRef).onDestroy(() => release?.());\n afterRenderEffect(() => {\n const file = this.file();\n const open = this.open();\n release?.();\n release = undefined;\n this.allocated.set(null);\n this.imageResult.set('loading');\n const urlApi = document.defaultView?.URL;\n if (!open || !file || !urlApi?.createObjectURL) return;\n // Explicit PDF MIME prevents resource embedding as HTML, including mislabeled input.\n const blob =\n file.type.toLowerCase() === 'application/pdf'\n ? file.slice(0, file.size, 'application/pdf')\n : file;\n const url = urlApi.createObjectURL(blob);\n release = () => urlApi.revokeObjectURL(url);\n this.allocated.set({\n file,\n url,\n pdf:\n file.type.toLowerCase() === 'application/pdf'\n ? sanitizer.bypassSecurityTrustResourceUrl(url)\n : null,\n });\n });\n }\n protected imageState(source: PreviewSource, state: 'ready' | 'error'): void {\n if (this.source() === source) this.imageResult.set(state);\n }\n}\n"],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ import * as i0 from "@angular/core";
2
+ import { Pipe, inject } from "@angular/core";
3
+ import { VD_LOCALE } from "@vadem/ui/locale";
4
+ const UNITS = [
5
+ "byte",
6
+ "kilobyte",
7
+ "megabyte",
8
+ "gigabyte",
9
+ "terabyte",
10
+ "petabyte"
11
+ ];
12
+ const BINARY = [
13
+ "",
14
+ "KiB",
15
+ "MiB",
16
+ "GiB",
17
+ "TiB",
18
+ "PiB"
19
+ ];
20
+ function vdFormatFileSize(bytes, options = {}) {
21
+ if (typeof bytes !== "number" || !Number.isSafeInteger(bytes) || bytes < 0) return options.unknownText ?? "Unknown size";
22
+ const requested = options.maximumFractionDigits ?? 1;
23
+ const digits = Number.isInteger(requested) && requested >= 0 && requested <= 3 ? requested : 1;
24
+ const base = options.system === "binary" ? 1024 : 1e3;
25
+ let index = 0;
26
+ while (index < UNITS.length - 1 && bytes >= base ** (index + 1)) index++;
27
+ if (index < UNITS.length - 1 && Number((bytes / base ** index).toFixed(digits)) >= base) index++;
28
+ const value = bytes / base ** index;
29
+ const numberOptions = { maximumFractionDigits: digits };
30
+ const binary = options.system === "binary" && index > 0;
31
+ if (!binary) Object.assign(numberOptions, {
32
+ style: "unit",
33
+ unit: UNITS[index],
34
+ unitDisplay: "short"
35
+ });
36
+ let formatter;
37
+ try {
38
+ formatter = new Intl.NumberFormat(options.locale ?? "en", numberOptions);
39
+ } catch {
40
+ formatter = new Intl.NumberFormat("en", numberOptions);
41
+ }
42
+ return binary ? `${formatter.format(value)}\u00a0${BINARY[index]}` : formatter.format(value);
43
+ }
44
+ var VdFileSizePipe = class VdFileSizePipe {
45
+ texts = inject(VD_LOCALE);
46
+ transform(bytes, system = "decimal", maximumFractionDigits = 1, locale = this.texts.code, unknownText = this.texts.fileSize.unknownText) {
47
+ return vdFormatFileSize(bytes, {
48
+ system,
49
+ maximumFractionDigits,
50
+ locale,
51
+ unknownText
52
+ });
53
+ }
54
+ static ɵfac = i0.ɵɵngDeclareFactory({
55
+ minVersion: "12.0.0",
56
+ version: "22.2.1",
57
+ ngImport: i0,
58
+ type: VdFileSizePipe,
59
+ deps: [],
60
+ target: i0.ɵɵFactoryTarget.Pipe
61
+ });
62
+ static ɵpipe = i0.ɵɵngDeclarePipe({
63
+ minVersion: "14.0.0",
64
+ version: "22.2.1",
65
+ ngImport: i0,
66
+ type: VdFileSizePipe,
67
+ isStandalone: true,
68
+ name: "vdFileSize"
69
+ });
70
+ };
71
+ i0.ɵɵngDeclareClassMetadata({
72
+ minVersion: "12.0.0",
73
+ version: "22.2.1",
74
+ ngImport: i0,
75
+ type: VdFileSizePipe,
76
+ decorators: [{
77
+ type: Pipe,
78
+ args: [{ name: "vdFileSize" }]
79
+ }]
80
+ });
81
+ export { VdFileSizePipe, vdFormatFileSize };
82
+
83
+ //# sourceMappingURL=vadem-ui-file-size.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vadem-ui-file-size.mjs","names":[],"sources":["../../../projects/ui/file-size/src/core/file-size.ts","../../../projects/ui/file-size/src/file-size.ts"],"sourcesContent":["export type VdFileSizeSystem = 'decimal' | 'binary';\nexport interface VdFileSizeOptions {\n readonly locale?: string;\n readonly system?: VdFileSizeSystem;\n readonly maximumFractionDigits?: number;\n readonly unknownText?: string;\n}\nconst UNITS = ['byte', 'kilobyte', 'megabyte', 'gigabyte', 'terabyte', 'petabyte'];\nconst BINARY = ['', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB'];\n\n/** Formats byte counts only; display strings are never parsed back into values. */\nexport function vdFormatFileSize(\n bytes: number | null | undefined,\n options: VdFileSizeOptions = {},\n): string {\n if (typeof bytes !== 'number' || !Number.isSafeInteger(bytes) || bytes < 0)\n return options.unknownText ?? 'Unknown size';\n const requested = options.maximumFractionDigits ?? 1;\n const digits = Number.isInteger(requested) && requested >= 0 && requested <= 3 ? requested : 1;\n const base = options.system === 'binary' ? 1024 : 1000;\n let index = 0;\n while (index < UNITS.length - 1 && bytes >= base ** (index + 1)) index++;\n if (index < UNITS.length - 1 && Number((bytes / base ** index).toFixed(digits)) >= base) index++;\n const value = bytes / base ** index;\n const numberOptions: Intl.NumberFormatOptions = { maximumFractionDigits: digits };\n const binary = options.system === 'binary' && index > 0;\n if (!binary)\n Object.assign(numberOptions, { style: 'unit', unit: UNITS[index], unitDisplay: 'short' });\n let formatter: Intl.NumberFormat;\n try {\n formatter = new Intl.NumberFormat(options.locale ?? 'en', numberOptions);\n } catch {\n formatter = new Intl.NumberFormat('en', numberOptions);\n }\n return binary ? `${formatter.format(value)}\\u00a0${BINARY[index]}` : formatter.format(value);\n}\n","import { Pipe, inject, type PipeTransform } from '@angular/core';\nimport { VD_LOCALE } from '@vadem/ui/locale';\nimport { vdFormatFileSize, type VdFileSizeSystem } from './core/file-size';\n\n@Pipe({ name: 'vdFileSize' })\nexport class VdFileSizePipe implements PipeTransform {\n private readonly texts = inject(VD_LOCALE);\n transform(\n bytes: number | null | undefined,\n system: VdFileSizeSystem = 'decimal',\n maximumFractionDigits = 1,\n locale = this.texts.code,\n unknownText = this.texts.fileSize.unknownText,\n ): string {\n return vdFormatFileSize(bytes, { system, maximumFractionDigits, locale, unknownText });\n }\n}\n"],"mappings":";;;AAOA,MAAM,QAAQ;CAAC;CAAQ;CAAY;CAAY;CAAY;CAAY;AAAU;AACjF,MAAM,SAAS;CAAC;CAAI;CAAO;CAAO;CAAO;CAAO;AAAK;AAGrD,SAAgB,iBACd,OACA,UAA6B,CAAA,GAAE;CAE/B,IAAI,OAAO,UAAU,YAAY,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,GACvE,OAAO,QAAQ,eAAe;CAChC,MAAM,YAAY,QAAQ,yBAAyB;CACnD,MAAM,SAAS,OAAO,UAAU,SAAS,KAAK,aAAa,KAAK,aAAa,IAAI,YAAY;CAC7F,MAAM,OAAO,QAAQ,WAAW,WAAW,OAAO;CAClD,IAAI,QAAQ;CACZ,OAAO,QAAQ,MAAM,SAAS,KAAK,SAAS,SAAS,QAAQ,IAAI;CACjE,IAAI,QAAQ,MAAM,SAAS,KAAK,QAAQ,QAAQ,QAAQ,MAAA,CAAO,QAAQ,MAAM,CAAC,KAAK,MAAM;CACzF,MAAM,QAAQ,QAAQ,QAAQ;CAC9B,MAAM,gBAA0C,EAAE,uBAAuB,OAAM;CAC/E,MAAM,SAAS,QAAQ,WAAW,YAAY,QAAQ;CACtD,IAAI,CAAC,QACH,OAAO,OAAO,eAAe;EAAE,OAAO;EAAQ,MAAM,MAAM;EAAQ,aAAa;CAAO,CAAE;CAC1F,IAAI;CACJ,IAAI;EACF,YAAY,IAAI,KAAK,aAAa,QAAQ,UAAU,MAAM,aAAa;CACzE,QAAQ;EACN,YAAY,IAAI,KAAK,aAAa,MAAM,aAAa;CACvD;CACA,OAAO,SAAS,GAAG,UAAU,OAAO,KAAK,EAAC,QAAS,OAAO,WAAW,UAAU,OAAO,KAAK;AAC7F;AC9BA,IAAa,iBAAb,MAAa,eAAc;CACR,QAAQ,OAAO,SAAS;CACzC,UACE,OACA,SAA2B,WAC3B,wBAAwB,GACxB,SAAS,KAAK,MAAM,MACpB,cAAc,KAAK,MAAM,SAAS,aAAW;EAE7C,OAAO,iBAAiB,OAAO;GAAE;GAAQ;GAAuB;GAAQ;EAAW,CAAE;CACvF;CAVW,OAAA,OAAA,GAAA,mBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,MAAA,CAAA;EAAA,QAAA,GAAA,gBAAA;CAAA,CAAA;CAAd,OAAA,QAAA,GAAA,gBAAA;EAAA,YAAA;EAAA,SAAA;EAAA,UAAA;EAAA,MAAA;EAAc,cAAA;EAAA,MAAA;CAAA,CAAA;;AAAd,GAAA,yBAAA;CAAA,YAAA;CAAA,SAAA;CAAA,UAAA;CAAA,MAAA;CAAc,YAAA,CAAA;EAD1B,MAAA;EAAK,MAAA,CAAA,EAAE,MAAM,aAAY,CAAE"}