@portnet/ui 6.0.2 → 6.0.3

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 (980) hide show
  1. package/CHANGELOG.md +652 -0
  2. package/dist/esm/index.js +72 -3
  3. package/dist/esm/index.js.map +1 -1
  4. package/dist/esm/v2/__tests__/AppMain.test.js +130 -0
  5. package/dist/esm/v2/__tests__/AppMain.test.js.map +1 -0
  6. package/dist/esm/v2/__tests__/ChartFigure.test.js +180 -0
  7. package/dist/esm/v2/__tests__/ChartFigure.test.js.map +1 -0
  8. package/dist/esm/v2/__tests__/DataGridRowActionsPropagation.test.js +150 -0
  9. package/dist/esm/v2/__tests__/DataGridRowActionsPropagation.test.js.map +1 -0
  10. package/dist/esm/v2/__tests__/DrawerTactileTargets.test.js +93 -0
  11. package/dist/esm/v2/__tests__/DrawerTactileTargets.test.js.map +1 -0
  12. package/dist/esm/v2/__tests__/FieldError.test.js +71 -38
  13. package/dist/esm/v2/__tests__/FieldError.test.js.map +1 -1
  14. package/dist/esm/v2/__tests__/FieldNaming.test.js +160 -0
  15. package/dist/esm/v2/__tests__/FieldNaming.test.js.map +1 -0
  16. package/dist/esm/v2/__tests__/FieldWidth.test.js +11 -11
  17. package/dist/esm/v2/__tests__/FieldWidth.test.js.map +1 -1
  18. package/dist/esm/v2/__tests__/FileCard.test.js +18 -17
  19. package/dist/esm/v2/__tests__/FileCard.test.js.map +1 -1
  20. package/dist/esm/v2/__tests__/FormikCheckbox.test.js +87 -179
  21. package/dist/esm/v2/__tests__/FormikCheckbox.test.js.map +1 -1
  22. package/dist/esm/v2/__tests__/FormikDateTimePicker.test.js +32 -44
  23. package/dist/esm/v2/__tests__/FormikDateTimePicker.test.js.map +1 -1
  24. package/dist/esm/v2/__tests__/FormikDisplayWidth.test.js +101 -0
  25. package/dist/esm/v2/__tests__/FormikDisplayWidth.test.js.map +1 -0
  26. package/dist/esm/v2/__tests__/FormikRadioGroup.test.js +118 -199
  27. package/dist/esm/v2/__tests__/FormikRadioGroup.test.js.map +1 -1
  28. package/dist/esm/v2/__tests__/MobileRowCard.test.js +44 -42
  29. package/dist/esm/v2/__tests__/MobileRowCard.test.js.map +1 -1
  30. package/dist/esm/v2/__tests__/PreviewDrawer.test.js +165 -0
  31. package/dist/esm/v2/__tests__/PreviewDrawer.test.js.map +1 -0
  32. package/dist/esm/v2/__tests__/ReferentielFieldContainer.test.js +156 -0
  33. package/dist/esm/v2/__tests__/ReferentielFieldContainer.test.js.map +1 -0
  34. package/dist/esm/v2/__tests__/SectionErrorBoundary.test.js +37 -52
  35. package/dist/esm/v2/__tests__/SectionErrorBoundary.test.js.map +1 -1
  36. package/dist/esm/v2/__tests__/apiError.test.js +50 -69
  37. package/dist/esm/v2/__tests__/apiError.test.js.map +1 -1
  38. package/dist/esm/v2/__tests__/banned-patterns.test.js +41 -122
  39. package/dist/esm/v2/__tests__/banned-patterns.test.js.map +1 -1
  40. package/dist/esm/v2/__tests__/chart-palette.test.js +204 -0
  41. package/dist/esm/v2/__tests__/chart-palette.test.js.map +1 -0
  42. package/dist/esm/v2/__tests__/contrast-palette.test.js +42 -74
  43. package/dist/esm/v2/__tests__/contrast-palette.test.js.map +1 -1
  44. package/dist/esm/v2/__tests__/cssVariables.test.js +44 -51
  45. package/dist/esm/v2/__tests__/cssVariables.test.js.map +1 -1
  46. package/dist/esm/v2/__tests__/fileValidation.test.js +134 -0
  47. package/dist/esm/v2/__tests__/fileValidation.test.js.map +1 -0
  48. package/dist/esm/v2/__tests__/filterCriteria.test.js +321 -0
  49. package/dist/esm/v2/__tests__/filterCriteria.test.js.map +1 -0
  50. package/dist/esm/v2/__tests__/fmtDate.test.js +68 -0
  51. package/dist/esm/v2/__tests__/fmtDate.test.js.map +1 -0
  52. package/dist/esm/v2/__tests__/gap-leakage-refonte.test.js +218 -0
  53. package/dist/esm/v2/__tests__/gap-leakage-refonte.test.js.map +1 -0
  54. package/dist/esm/v2/__tests__/labels-merge.test.js +17 -21
  55. package/dist/esm/v2/__tests__/labels-merge.test.js.map +1 -1
  56. package/dist/esm/v2/__tests__/locale-fallback.test.js +35 -40
  57. package/dist/esm/v2/__tests__/locale-fallback.test.js.map +1 -1
  58. package/dist/esm/v2/__tests__/reviveSavedCriteria.test.js +143 -0
  59. package/dist/esm/v2/__tests__/reviveSavedCriteria.test.js.map +1 -0
  60. package/dist/esm/v2/__tests__/rowActions.test.js +182 -0
  61. package/dist/esm/v2/__tests__/rowActions.test.js.map +1 -0
  62. package/dist/esm/v2/__tests__/useFocusOnRouteChange.test.js +155 -0
  63. package/dist/esm/v2/__tests__/useFocusOnRouteChange.test.js.map +1 -0
  64. package/dist/esm/v2/__tests__/useFocusTrap.test.js +266 -402
  65. package/dist/esm/v2/__tests__/useFocusTrap.test.js.map +1 -1
  66. package/dist/esm/v2/__tests__/usePrefersReducedMotion.test.js +120 -0
  67. package/dist/esm/v2/__tests__/usePrefersReducedMotion.test.js.map +1 -0
  68. package/dist/esm/v2/components/Accordion.js +48 -70
  69. package/dist/esm/v2/components/Accordion.js.map +1 -1
  70. package/dist/esm/v2/components/ActionStrip.js +31 -43
  71. package/dist/esm/v2/components/ActionStrip.js.map +1 -1
  72. package/dist/esm/v2/components/Banner.js +25 -22
  73. package/dist/esm/v2/components/Banner.js.map +1 -1
  74. package/dist/esm/v2/components/Busy.js +14 -19
  75. package/dist/esm/v2/components/Busy.js.map +1 -1
  76. package/dist/esm/v2/components/Button.js +34 -45
  77. package/dist/esm/v2/components/Button.js.map +1 -1
  78. package/dist/esm/v2/components/CategoryTag.js +44 -27
  79. package/dist/esm/v2/components/CategoryTag.js.map +1 -1
  80. package/dist/esm/v2/components/Checkbox.js +32 -38
  81. package/dist/esm/v2/components/Checkbox.js.map +1 -1
  82. package/dist/esm/v2/components/Chip.js +23 -36
  83. package/dist/esm/v2/components/Chip.js.map +1 -1
  84. package/dist/esm/v2/components/Combobox.js +112 -136
  85. package/dist/esm/v2/components/Combobox.js.map +1 -1
  86. package/dist/esm/v2/components/CommandPalette.js +113 -198
  87. package/dist/esm/v2/components/CommandPalette.js.map +1 -1
  88. package/dist/esm/v2/components/ConfirmDialog.js +36 -45
  89. package/dist/esm/v2/components/ConfirmDialog.js.map +1 -1
  90. package/dist/esm/v2/components/DatePicker.js +78 -81
  91. package/dist/esm/v2/components/DatePicker.js.map +1 -1
  92. package/dist/esm/v2/components/DateRangePicker.js +63 -74
  93. package/dist/esm/v2/components/DateRangePicker.js.map +1 -1
  94. package/dist/esm/v2/components/DateTimePicker.js +81 -86
  95. package/dist/esm/v2/components/DateTimePicker.js.map +1 -1
  96. package/dist/esm/v2/components/Drawer.js +71 -65
  97. package/dist/esm/v2/components/Drawer.js.map +1 -1
  98. package/dist/esm/v2/components/Dropzone.js +130 -177
  99. package/dist/esm/v2/components/Dropzone.js.map +1 -1
  100. package/dist/esm/v2/components/EmptyState.js +9 -9
  101. package/dist/esm/v2/components/EmptyState.js.map +1 -1
  102. package/dist/esm/v2/components/FavoriteToggle.js +24 -33
  103. package/dist/esm/v2/components/FavoriteToggle.js.map +1 -1
  104. package/dist/esm/v2/components/Field.js +155 -59
  105. package/dist/esm/v2/components/Field.js.map +1 -1
  106. package/dist/esm/v2/components/FieldError.js +9 -13
  107. package/dist/esm/v2/components/FieldError.js.map +1 -1
  108. package/dist/esm/v2/components/FieldHelp.js +28 -49
  109. package/dist/esm/v2/components/FieldHelp.js.map +1 -1
  110. package/dist/esm/v2/components/FileCard.js +14 -19
  111. package/dist/esm/v2/components/FileCard.js.map +1 -1
  112. package/dist/esm/v2/components/FilterTab.js +22 -31
  113. package/dist/esm/v2/components/FilterTab.js.map +1 -1
  114. package/dist/esm/v2/components/ForbiddenPage.js +28 -8
  115. package/dist/esm/v2/components/ForbiddenPage.js.map +1 -1
  116. package/dist/esm/v2/components/FormGrid.js +48 -54
  117. package/dist/esm/v2/components/FormGrid.js.map +1 -1
  118. package/dist/esm/v2/components/FormikDisplay.js +98 -24
  119. package/dist/esm/v2/components/FormikDisplay.js.map +1 -1
  120. package/dist/esm/v2/components/Input.js +75 -34
  121. package/dist/esm/v2/components/Input.js.map +1 -1
  122. package/dist/esm/v2/components/KPICard.js +42 -51
  123. package/dist/esm/v2/components/KPICard.js.map +1 -1
  124. package/dist/esm/v2/components/KPIStrip.js +9 -15
  125. package/dist/esm/v2/components/KPIStrip.js.map +1 -1
  126. package/dist/esm/v2/components/KV.js +16 -23
  127. package/dist/esm/v2/components/KV.js.map +1 -1
  128. package/dist/esm/v2/components/KVGrid.js +15 -23
  129. package/dist/esm/v2/components/KVGrid.js.map +1 -1
  130. package/dist/esm/v2/components/Layout.js +81 -117
  131. package/dist/esm/v2/components/Layout.js.map +1 -1
  132. package/dist/esm/v2/components/MobileRowCard.js +64 -75
  133. package/dist/esm/v2/components/MobileRowCard.js.map +1 -1
  134. package/dist/esm/v2/components/Modal.js +44 -53
  135. package/dist/esm/v2/components/Modal.js.map +1 -1
  136. package/dist/esm/v2/components/NetworkErrorPage.js +28 -11
  137. package/dist/esm/v2/components/NetworkErrorPage.js.map +1 -1
  138. package/dist/esm/v2/components/NotFoundPage.js +28 -9
  139. package/dist/esm/v2/components/NotFoundPage.js.map +1 -1
  140. package/dist/esm/v2/components/NumberInput.js +77 -107
  141. package/dist/esm/v2/components/NumberInput.js.map +1 -1
  142. package/dist/esm/v2/components/OverflowMenu.js +24 -42
  143. package/dist/esm/v2/components/OverflowMenu.js.map +1 -1
  144. package/dist/esm/v2/components/PdfViewer.js +24 -33
  145. package/dist/esm/v2/components/PdfViewer.js.map +1 -1
  146. package/dist/esm/v2/components/ProgressBar.js +28 -36
  147. package/dist/esm/v2/components/ProgressBar.js.map +1 -1
  148. package/dist/esm/v2/components/Radio.js +49 -57
  149. package/dist/esm/v2/components/Radio.js.map +1 -1
  150. package/dist/esm/v2/components/SectionErrorBoundary.js +84 -130
  151. package/dist/esm/v2/components/SectionErrorBoundary.js.map +1 -1
  152. package/dist/esm/v2/components/SectionHeader.js +24 -31
  153. package/dist/esm/v2/components/SectionHeader.js.map +1 -1
  154. package/dist/esm/v2/components/Segmented.js +59 -84
  155. package/dist/esm/v2/components/Segmented.js.map +1 -1
  156. package/dist/esm/v2/components/Select.js +100 -138
  157. package/dist/esm/v2/components/Select.js.map +1 -1
  158. package/dist/esm/v2/components/ServerErrorPage.js +27 -10
  159. package/dist/esm/v2/components/ServerErrorPage.js.map +1 -1
  160. package/dist/esm/v2/components/Skeleton.js +81 -96
  161. package/dist/esm/v2/components/Skeleton.js.map +1 -1
  162. package/dist/esm/v2/components/SkipLink.js +6 -7
  163. package/dist/esm/v2/components/SkipLink.js.map +1 -1
  164. package/dist/esm/v2/components/Spinner.js +13 -22
  165. package/dist/esm/v2/components/Spinner.js.map +1 -1
  166. package/dist/esm/v2/components/Status.js +14 -25
  167. package/dist/esm/v2/components/Status.js.map +1 -1
  168. package/dist/esm/v2/components/Stepper.js +68 -71
  169. package/dist/esm/v2/components/Stepper.js.map +1 -1
  170. package/dist/esm/v2/components/Surface.js +25 -44
  171. package/dist/esm/v2/components/Surface.js.map +1 -1
  172. package/dist/esm/v2/components/Switch.js +21 -29
  173. package/dist/esm/v2/components/Switch.js.map +1 -1
  174. package/dist/esm/v2/components/TabPanel.js +84 -0
  175. package/dist/esm/v2/components/TabPanel.js.map +1 -0
  176. package/dist/esm/v2/components/Tabs.js +43 -19
  177. package/dist/esm/v2/components/Tabs.js.map +1 -1
  178. package/dist/esm/v2/components/TelInput.js +75 -108
  179. package/dist/esm/v2/components/TelInput.js.map +1 -1
  180. package/dist/esm/v2/components/Textarea.js +21 -30
  181. package/dist/esm/v2/components/Textarea.js.map +1 -1
  182. package/dist/esm/v2/components/TimePicker.js +59 -69
  183. package/dist/esm/v2/components/TimePicker.js.map +1 -1
  184. package/dist/esm/v2/components/Toast.js +109 -163
  185. package/dist/esm/v2/components/Toast.js.map +1 -1
  186. package/dist/esm/v2/components/Tooltip.js +18 -31
  187. package/dist/esm/v2/components/Tooltip.js.map +1 -1
  188. package/dist/esm/v2/components/_ErrorPageBody.js +6 -5
  189. package/dist/esm/v2/components/_ErrorPageBody.js.map +1 -1
  190. package/dist/esm/v2/components/_pickerShared.js +2 -2
  191. package/dist/esm/v2/components/_pickerShared.js.map +1 -1
  192. package/dist/esm/v2/components/index.js +37 -0
  193. package/dist/esm/v2/components/index.js.map +1 -1
  194. package/dist/esm/v2/hooks/index.js +62 -0
  195. package/dist/esm/v2/hooks/index.js.map +1 -1
  196. package/dist/esm/v2/hooks/useAppliedFilters.js +112 -0
  197. package/dist/esm/v2/hooks/useAppliedFilters.js.map +1 -0
  198. package/dist/esm/v2/hooks/useDebouncedCallback.js +82 -0
  199. package/dist/esm/v2/hooks/useDebouncedCallback.js.map +1 -0
  200. package/dist/esm/v2/hooks/useDelayedFlag.js +5 -19
  201. package/dist/esm/v2/hooks/useDelayedFlag.js.map +1 -1
  202. package/dist/esm/v2/hooks/useDensity.js +13 -17
  203. package/dist/esm/v2/hooks/useDensity.js.map +1 -1
  204. package/dist/esm/v2/hooks/useFocusFirstError.js +25 -33
  205. package/dist/esm/v2/hooks/useFocusFirstError.js.map +1 -1
  206. package/dist/esm/v2/hooks/useFocusOnRouteChange.js +81 -0
  207. package/dist/esm/v2/hooks/useFocusOnRouteChange.js.map +1 -0
  208. package/dist/esm/v2/hooks/useFocusTrap.js +19 -23
  209. package/dist/esm/v2/hooks/useFocusTrap.js.map +1 -1
  210. package/dist/esm/v2/hooks/useFormAutoSave.js +38 -53
  211. package/dist/esm/v2/hooks/useFormAutoSave.js.map +1 -1
  212. package/dist/esm/v2/hooks/useFormCompletionProgress.js +32 -51
  213. package/dist/esm/v2/hooks/useFormCompletionProgress.js.map +1 -1
  214. package/dist/esm/v2/hooks/useKeyboardShortcuts.js +125 -0
  215. package/dist/esm/v2/hooks/useKeyboardShortcuts.js.map +1 -0
  216. package/dist/esm/v2/hooks/usePrefersReducedMotion.js +99 -0
  217. package/dist/esm/v2/hooks/usePrefersReducedMotion.js.map +1 -0
  218. package/dist/esm/v2/hooks/useResolvedDensity.js +2 -10
  219. package/dist/esm/v2/hooks/useResolvedDensity.js.map +1 -1
  220. package/dist/esm/v2/hooks/useSortedRows.js +3 -5
  221. package/dist/esm/v2/hooks/useSortedRows.js.map +1 -1
  222. package/dist/esm/v2/hooks/useTabLoading.js +6 -21
  223. package/dist/esm/v2/hooks/useTabLoading.js.map +1 -1
  224. package/dist/esm/v2/index.js +2 -3
  225. package/dist/esm/v2/index.js.map +1 -1
  226. package/dist/esm/v2/modalContext.js +2 -2
  227. package/dist/esm/v2/modalContext.js.map +1 -1
  228. package/dist/esm/v2/models/favorite.js.map +1 -1
  229. package/dist/esm/v2/models/personalization.js.map +1 -1
  230. package/dist/esm/v2/models/referentiel.js.map +1 -1
  231. package/dist/esm/v2/models/savedFilter.js.map +1 -1
  232. package/dist/esm/v2/patterns/ActionBar.js +115 -159
  233. package/dist/esm/v2/patterns/ActionBar.js.map +1 -1
  234. package/dist/esm/v2/patterns/AppMain.js +108 -0
  235. package/dist/esm/v2/patterns/AppMain.js.map +1 -0
  236. package/dist/esm/v2/patterns/BulkActionBar.js +31 -34
  237. package/dist/esm/v2/patterns/BulkActionBar.js.map +1 -1
  238. package/dist/esm/v2/patterns/ChartFigure.js +151 -0
  239. package/dist/esm/v2/patterns/ChartFigure.js.map +1 -0
  240. package/dist/esm/v2/patterns/CollapsibleDataGrid.js +111 -152
  241. package/dist/esm/v2/patterns/CollapsibleDataGrid.js.map +1 -1
  242. package/dist/esm/v2/patterns/ColumnsToggle.js +43 -77
  243. package/dist/esm/v2/patterns/ColumnsToggle.js.map +1 -1
  244. package/dist/esm/v2/patterns/DataGrid.js +221 -255
  245. package/dist/esm/v2/patterns/DataGrid.js.map +1 -1
  246. package/dist/esm/v2/patterns/DataGridSettingsMenu.js +76 -94
  247. package/dist/esm/v2/patterns/DataGridSettingsMenu.js.map +1 -1
  248. package/dist/esm/v2/patterns/DataGridToolbar.js +85 -89
  249. package/dist/esm/v2/patterns/DataGridToolbar.js.map +1 -1
  250. package/dist/esm/v2/patterns/DataGridVirtualized.js +141 -182
  251. package/dist/esm/v2/patterns/DataGridVirtualized.js.map +1 -1
  252. package/dist/esm/v2/patterns/DeleteResourceConfirmDialog.js +26 -30
  253. package/dist/esm/v2/patterns/DeleteResourceConfirmDialog.js.map +1 -1
  254. package/dist/esm/v2/patterns/DetailSplit.js +108 -0
  255. package/dist/esm/v2/patterns/DetailSplit.js.map +1 -0
  256. package/dist/esm/v2/patterns/FavoriteColumn.js +15 -17
  257. package/dist/esm/v2/patterns/FavoriteColumn.js.map +1 -1
  258. package/dist/esm/v2/patterns/FavoritesFilter.js +30 -39
  259. package/dist/esm/v2/patterns/FavoritesFilter.js.map +1 -1
  260. package/dist/esm/v2/patterns/FilterTabBar.js +112 -0
  261. package/dist/esm/v2/patterns/FilterTabBar.js.map +1 -0
  262. package/dist/esm/v2/patterns/FormErrorSummary.js +12 -13
  263. package/dist/esm/v2/patterns/FormErrorSummary.js.map +1 -1
  264. package/dist/esm/v2/patterns/FormPageShell.js +43 -41
  265. package/dist/esm/v2/patterns/FormPageShell.js.map +1 -1
  266. package/dist/esm/v2/patterns/FormSection.js +30 -38
  267. package/dist/esm/v2/patterns/FormSection.js.map +1 -1
  268. package/dist/esm/v2/patterns/FormikCheckbox.js +29 -39
  269. package/dist/esm/v2/patterns/FormikCheckbox.js.map +1 -1
  270. package/dist/esm/v2/patterns/FormikCheckboxGroup.js +56 -60
  271. package/dist/esm/v2/patterns/FormikCheckboxGroup.js.map +1 -1
  272. package/dist/esm/v2/patterns/FormikCombobox.js +51 -69
  273. package/dist/esm/v2/patterns/FormikCombobox.js.map +1 -1
  274. package/dist/esm/v2/patterns/FormikDatePicker.js +44 -58
  275. package/dist/esm/v2/patterns/FormikDatePicker.js.map +1 -1
  276. package/dist/esm/v2/patterns/FormikDateTimePicker.js +44 -58
  277. package/dist/esm/v2/patterns/FormikDateTimePicker.js.map +1 -1
  278. package/dist/esm/v2/patterns/FormikErrorFocus.js +22 -23
  279. package/dist/esm/v2/patterns/FormikErrorFocus.js.map +1 -1
  280. package/dist/esm/v2/patterns/FormikErrorSummary.js +89 -0
  281. package/dist/esm/v2/patterns/FormikErrorSummary.js.map +1 -0
  282. package/dist/esm/v2/patterns/FormikFile.js +94 -78
  283. package/dist/esm/v2/patterns/FormikFile.js.map +1 -1
  284. package/dist/esm/v2/patterns/FormikInput.js +40 -53
  285. package/dist/esm/v2/patterns/FormikInput.js.map +1 -1
  286. package/dist/esm/v2/patterns/FormikRadioGroup.js +39 -51
  287. package/dist/esm/v2/patterns/FormikRadioGroup.js.map +1 -1
  288. package/dist/esm/v2/patterns/FormikReferentielField.js +49 -59
  289. package/dist/esm/v2/patterns/FormikReferentielField.js.map +1 -1
  290. package/dist/esm/v2/patterns/FormikSelect.js +64 -87
  291. package/dist/esm/v2/patterns/FormikSelect.js.map +1 -1
  292. package/dist/esm/v2/patterns/FormikTextarea.js +30 -46
  293. package/dist/esm/v2/patterns/FormikTextarea.js.map +1 -1
  294. package/dist/esm/v2/patterns/KeyboardShortcutsHelp.js +53 -71
  295. package/dist/esm/v2/patterns/KeyboardShortcutsHelp.js.map +1 -1
  296. package/dist/esm/v2/patterns/NetworkErrorBanner.js +6 -7
  297. package/dist/esm/v2/patterns/NetworkErrorBanner.js.map +1 -1
  298. package/dist/esm/v2/patterns/PageContent.js +10 -14
  299. package/dist/esm/v2/patterns/PageContent.js.map +1 -1
  300. package/dist/esm/v2/patterns/PreviewDrawer.js +153 -0
  301. package/dist/esm/v2/patterns/PreviewDrawer.js.map +1 -0
  302. package/dist/esm/v2/patterns/ReferentielField.js +327 -312
  303. package/dist/esm/v2/patterns/ReferentielField.js.map +1 -1
  304. package/dist/esm/v2/patterns/RowFavoriteToggle.js +27 -22
  305. package/dist/esm/v2/patterns/RowFavoriteToggle.js.map +1 -1
  306. package/dist/esm/v2/patterns/SaveFilterDialog.js +38 -66
  307. package/dist/esm/v2/patterns/SaveFilterDialog.js.map +1 -1
  308. package/dist/esm/v2/patterns/SavedFiltersMenu.js +62 -81
  309. package/dist/esm/v2/patterns/SavedFiltersMenu.js.map +1 -1
  310. package/dist/esm/v2/patterns/SkeletonPageShell.js +106 -129
  311. package/dist/esm/v2/patterns/SkeletonPageShell.js.map +1 -1
  312. package/dist/esm/v2/patterns/SortableHeader.js +22 -45
  313. package/dist/esm/v2/patterns/SortableHeader.js.map +1 -1
  314. package/dist/esm/v2/patterns/Tour.js +94 -120
  315. package/dist/esm/v2/patterns/Tour.js.map +1 -1
  316. package/dist/esm/v2/patterns/_dataGridShared.js +107 -128
  317. package/dist/esm/v2/patterns/_dataGridShared.js.map +1 -1
  318. package/dist/esm/v2/patterns/_pickerSerialisation.js +6 -8
  319. package/dist/esm/v2/patterns/_pickerSerialisation.js.map +1 -1
  320. package/dist/esm/v2/patterns/_sort.js +17 -33
  321. package/dist/esm/v2/patterns/_sort.js.map +1 -1
  322. package/dist/esm/v2/patterns/_useColumnReorder.js +122 -160
  323. package/dist/esm/v2/patterns/_useColumnReorder.js.map +1 -1
  324. package/dist/esm/v2/patterns/_useColumnResize.js +78 -96
  325. package/dist/esm/v2/patterns/_useColumnResize.js.map +1 -1
  326. package/dist/esm/v2/patterns/filterCriteria.js +102 -0
  327. package/dist/esm/v2/patterns/filterCriteria.js.map +1 -0
  328. package/dist/esm/v2/patterns/index.js +152 -0
  329. package/dist/esm/v2/patterns/index.js.map +1 -1
  330. package/dist/esm/v2/patterns/rowActions.js +223 -0
  331. package/dist/esm/v2/patterns/rowActions.js.map +1 -0
  332. package/dist/esm/v2/personalization/PersonalizationProvider.js +50 -47
  333. package/dist/esm/v2/personalization/PersonalizationProvider.js.map +1 -1
  334. package/dist/esm/v2/personalization/adapters/_storageKey.js +5 -5
  335. package/dist/esm/v2/personalization/adapters/_storageKey.js.map +1 -1
  336. package/dist/esm/v2/personalization/adapters/createLocalStorageAdapter.js +22 -23
  337. package/dist/esm/v2/personalization/adapters/createLocalStorageAdapter.js.map +1 -1
  338. package/dist/esm/v2/personalization/adapters/createMemoryAdapter.js +13 -13
  339. package/dist/esm/v2/personalization/adapters/createMemoryAdapter.js.map +1 -1
  340. package/dist/esm/v2/personalization/capabilities/favorites.js +36 -60
  341. package/dist/esm/v2/personalization/capabilities/favorites.js.map +1 -1
  342. package/dist/esm/v2/personalization/capabilities/favoritesView.js +22 -34
  343. package/dist/esm/v2/personalization/capabilities/favoritesView.js.map +1 -1
  344. package/dist/esm/v2/personalization/capabilities/gridPreferences.js +28 -34
  345. package/dist/esm/v2/personalization/capabilities/gridPreferences.js.map +1 -1
  346. package/dist/esm/v2/personalization/capabilities/reviveSavedCriteria.js +119 -0
  347. package/dist/esm/v2/personalization/capabilities/reviveSavedCriteria.js.map +1 -0
  348. package/dist/esm/v2/personalization/capabilities/savedFilters.js +90 -98
  349. package/dist/esm/v2/personalization/capabilities/savedFilters.js.map +1 -1
  350. package/dist/esm/v2/personalization/createPersonalizationStore.js +78 -181
  351. package/dist/esm/v2/personalization/createPersonalizationStore.js.map +1 -1
  352. package/dist/esm/v2/personalization/index.js +17 -0
  353. package/dist/esm/v2/personalization/index.js.map +1 -1
  354. package/dist/esm/v2/personalization/personalizationContext.js +9 -9
  355. package/dist/esm/v2/personalization/personalizationContext.js.map +1 -1
  356. package/dist/esm/v2/personalization/schema.js +8 -9
  357. package/dist/esm/v2/personalization/schema.js.map +1 -1
  358. package/dist/esm/v2/referentiel/ReferentielProvider.js +27 -42
  359. package/dist/esm/v2/referentiel/ReferentielProvider.js.map +1 -1
  360. package/dist/esm/v2/referentiel/types.js +2 -0
  361. package/dist/esm/v2/referentiel/types.js.map +1 -0
  362. package/dist/esm/v2/referentiel/useReferentielClient.js +10 -11
  363. package/dist/esm/v2/referentiel/useReferentielClient.js.map +1 -1
  364. package/dist/esm/v2/referentiel/useReferentielOptions.js +60 -117
  365. package/dist/esm/v2/referentiel/useReferentielOptions.js.map +1 -1
  366. package/dist/esm/v2/referentiel/useReferentielSearch.js +37 -91
  367. package/dist/esm/v2/referentiel/useReferentielSearch.js.map +1 -1
  368. package/dist/esm/v2/theme/_brand.js +8 -24
  369. package/dist/esm/v2/theme/_brand.js.map +1 -1
  370. package/dist/esm/v2/theme/_brandSecondary.js +8 -24
  371. package/dist/esm/v2/theme/_brandSecondary.js.map +1 -1
  372. package/dist/esm/v2/theme/createPortnetTheme.js +51 -61
  373. package/dist/esm/v2/theme/createPortnetTheme.js.map +1 -1
  374. package/dist/esm/v2/theme/cssVariables.js +62 -69
  375. package/dist/esm/v2/theme/cssVariables.js.map +1 -1
  376. package/dist/esm/v2/theme/index.js +5 -5
  377. package/dist/esm/v2/theme/index.js.map +1 -1
  378. package/dist/esm/v2/tokens/breakpoints.js +14 -14
  379. package/dist/esm/v2/tokens/breakpoints.js.map +1 -1
  380. package/dist/esm/v2/tokens/chart.js +261 -0
  381. package/dist/esm/v2/tokens/chart.js.map +1 -0
  382. package/dist/esm/v2/tokens/colors.js +22 -22
  383. package/dist/esm/v2/tokens/colors.js.map +1 -1
  384. package/dist/esm/v2/tokens/density.js +62 -7
  385. package/dist/esm/v2/tokens/density.js.map +1 -1
  386. package/dist/esm/v2/tokens/index.js +49 -34
  387. package/dist/esm/v2/tokens/index.js.map +1 -1
  388. package/dist/esm/v2/tokens/motion.js +12 -20
  389. package/dist/esm/v2/tokens/motion.js.map +1 -1
  390. package/dist/esm/v2/tokens/radius.js +1 -1
  391. package/dist/esm/v2/tokens/radius.js.map +1 -1
  392. package/dist/esm/v2/tokens/shadows.js +6 -6
  393. package/dist/esm/v2/tokens/shadows.js.map +1 -1
  394. package/dist/esm/v2/tokens/spacing.js +2 -2
  395. package/dist/esm/v2/tokens/spacing.js.map +1 -1
  396. package/dist/esm/v2/tokens/state.js +1 -1
  397. package/dist/esm/v2/tokens/state.js.map +1 -1
  398. package/dist/esm/v2/tokens/statusPalette.js +17 -21
  399. package/dist/esm/v2/tokens/statusPalette.js.map +1 -1
  400. package/dist/esm/v2/tokens/tokens.json +6 -1
  401. package/dist/esm/v2/tokens/typography.js +13 -13
  402. package/dist/esm/v2/tokens/typography.js.map +1 -1
  403. package/dist/esm/v2/tokens/zIndex.js +1 -1
  404. package/dist/esm/v2/tokens/zIndex.js.map +1 -1
  405. package/dist/esm/v2/types/datagrid.js.map +1 -1
  406. package/dist/esm/v2/utils/apiError.js +16 -37
  407. package/dist/esm/v2/utils/apiError.js.map +1 -1
  408. package/dist/esm/v2/utils/contrast.js +31 -32
  409. package/dist/esm/v2/utils/contrast.js.map +1 -1
  410. package/dist/esm/v2/utils/cx.js +5 -25
  411. package/dist/esm/v2/utils/cx.js.map +1 -1
  412. package/dist/esm/v2/utils/fileDownload.js +23 -26
  413. package/dist/esm/v2/utils/fileDownload.js.map +1 -1
  414. package/dist/esm/v2/utils/fileValidation.js +209 -0
  415. package/dist/esm/v2/utils/fileValidation.js.map +1 -0
  416. package/dist/esm/v2/utils/fmtDate.js +111 -0
  417. package/dist/esm/v2/utils/fmtDate.js.map +1 -0
  418. package/dist/esm/v2/utils/fmtMoney.js +8 -10
  419. package/dist/esm/v2/utils/fmtMoney.js.map +1 -1
  420. package/dist/esm/v2/utils/formikErrors.js +78 -0
  421. package/dist/esm/v2/utils/formikErrors.js.map +1 -0
  422. package/dist/esm/v2/utils/index.js +35 -2
  423. package/dist/esm/v2/utils/index.js.map +1 -1
  424. package/dist/esm/v2/utils/mergeLabels.js +7 -12
  425. package/dist/esm/v2/utils/mergeLabels.js.map +1 -1
  426. package/dist/esm/v2/utils/networkStatus.js +12 -12
  427. package/dist/esm/v2/utils/networkStatus.js.map +1 -1
  428. package/dist/index.d.ts +7 -1
  429. package/dist/index.d.ts.map +1 -1
  430. package/dist/index.js +110 -49
  431. package/dist/index.js.map +1 -1
  432. package/dist/v2/__tests__/AppMain.test.js +133 -0
  433. package/dist/v2/__tests__/AppMain.test.js.map +1 -0
  434. package/dist/v2/__tests__/ChartFigure.test.js +183 -0
  435. package/dist/v2/__tests__/ChartFigure.test.js.map +1 -0
  436. package/dist/v2/__tests__/DataGridRowActionsPropagation.test.js +153 -0
  437. package/dist/v2/__tests__/DataGridRowActionsPropagation.test.js.map +1 -0
  438. package/dist/v2/__tests__/DrawerTactileTargets.test.js +94 -0
  439. package/dist/v2/__tests__/DrawerTactileTargets.test.js.map +1 -0
  440. package/dist/v2/__tests__/FieldError.test.js +82 -49
  441. package/dist/v2/__tests__/FieldError.test.js.map +1 -1
  442. package/dist/v2/__tests__/FieldNaming.test.js +161 -0
  443. package/dist/v2/__tests__/FieldNaming.test.js.map +1 -0
  444. package/dist/v2/__tests__/FieldWidth.test.js +23 -25
  445. package/dist/v2/__tests__/FieldWidth.test.js.map +1 -1
  446. package/dist/v2/__tests__/FileCard.test.js +29 -28
  447. package/dist/v2/__tests__/FileCard.test.js.map +1 -1
  448. package/dist/v2/__tests__/FormikCheckbox.test.js +90 -183
  449. package/dist/v2/__tests__/FormikCheckbox.test.js.map +1 -1
  450. package/dist/v2/__tests__/FormikDateTimePicker.test.js +38 -48
  451. package/dist/v2/__tests__/FormikDateTimePicker.test.js.map +1 -1
  452. package/dist/v2/__tests__/FormikDisplayWidth.test.js +102 -0
  453. package/dist/v2/__tests__/FormikDisplayWidth.test.js.map +1 -0
  454. package/dist/v2/__tests__/FormikRadioGroup.test.js +123 -204
  455. package/dist/v2/__tests__/FormikRadioGroup.test.js.map +1 -1
  456. package/dist/v2/__tests__/MobileRowCard.test.js +63 -61
  457. package/dist/v2/__tests__/MobileRowCard.test.js.map +1 -1
  458. package/dist/v2/__tests__/PreviewDrawer.test.js +169 -0
  459. package/dist/v2/__tests__/PreviewDrawer.test.js.map +1 -0
  460. package/dist/v2/__tests__/ReferentielFieldContainer.test.js +159 -0
  461. package/dist/v2/__tests__/ReferentielFieldContainer.test.js.map +1 -0
  462. package/dist/v2/__tests__/SectionErrorBoundary.test.js +53 -68
  463. package/dist/v2/__tests__/SectionErrorBoundary.test.js.map +1 -1
  464. package/dist/v2/__tests__/apiError.test.js +50 -69
  465. package/dist/v2/__tests__/apiError.test.js.map +1 -1
  466. package/dist/v2/__tests__/banned-patterns.test.js +42 -123
  467. package/dist/v2/__tests__/banned-patterns.test.js.map +1 -1
  468. package/dist/v2/__tests__/chart-palette.test.js +205 -0
  469. package/dist/v2/__tests__/chart-palette.test.js.map +1 -0
  470. package/dist/v2/__tests__/contrast-palette.test.js +42 -74
  471. package/dist/v2/__tests__/contrast-palette.test.js.map +1 -1
  472. package/dist/v2/__tests__/cssVariables.test.js +44 -51
  473. package/dist/v2/__tests__/cssVariables.test.js.map +1 -1
  474. package/dist/v2/__tests__/fileValidation.test.js +136 -0
  475. package/dist/v2/__tests__/fileValidation.test.js.map +1 -0
  476. package/dist/v2/__tests__/filterCriteria.test.js +324 -0
  477. package/dist/v2/__tests__/filterCriteria.test.js.map +1 -0
  478. package/dist/v2/__tests__/fmtDate.test.js +69 -0
  479. package/dist/v2/__tests__/fmtDate.test.js.map +1 -0
  480. package/dist/v2/__tests__/gap-leakage-refonte.test.js +221 -0
  481. package/dist/v2/__tests__/gap-leakage-refonte.test.js.map +1 -0
  482. package/dist/v2/__tests__/labels-merge.test.js +23 -27
  483. package/dist/v2/__tests__/labels-merge.test.js.map +1 -1
  484. package/dist/v2/__tests__/locale-fallback.test.js +47 -52
  485. package/dist/v2/__tests__/locale-fallback.test.js.map +1 -1
  486. package/dist/v2/__tests__/reviveSavedCriteria.test.js +144 -0
  487. package/dist/v2/__tests__/reviveSavedCriteria.test.js.map +1 -0
  488. package/dist/v2/__tests__/rowActions.test.js +186 -0
  489. package/dist/v2/__tests__/rowActions.test.js.map +1 -0
  490. package/dist/v2/__tests__/useFocusOnRouteChange.test.js +156 -0
  491. package/dist/v2/__tests__/useFocusOnRouteChange.test.js.map +1 -0
  492. package/dist/v2/__tests__/useFocusTrap.test.js +270 -407
  493. package/dist/v2/__tests__/useFocusTrap.test.js.map +1 -1
  494. package/dist/v2/__tests__/usePrefersReducedMotion.test.js +123 -0
  495. package/dist/v2/__tests__/usePrefersReducedMotion.test.js.map +1 -0
  496. package/dist/v2/components/Accordion.js +60 -82
  497. package/dist/v2/components/Accordion.js.map +1 -1
  498. package/dist/v2/components/ActionStrip.js +40 -52
  499. package/dist/v2/components/ActionStrip.js.map +1 -1
  500. package/dist/v2/components/Banner.js +42 -41
  501. package/dist/v2/components/Banner.js.map +1 -1
  502. package/dist/v2/components/Busy.js +22 -27
  503. package/dist/v2/components/Busy.js.map +1 -1
  504. package/dist/v2/components/Button.js +39 -50
  505. package/dist/v2/components/Button.js.map +1 -1
  506. package/dist/v2/components/CategoryTag.d.ts.map +1 -1
  507. package/dist/v2/components/CategoryTag.js +49 -32
  508. package/dist/v2/components/CategoryTag.js.map +1 -1
  509. package/dist/v2/components/Checkbox.js +39 -45
  510. package/dist/v2/components/Checkbox.js.map +1 -1
  511. package/dist/v2/components/Chip.js +29 -42
  512. package/dist/v2/components/Chip.js.map +1 -1
  513. package/dist/v2/components/Combobox.js +122 -144
  514. package/dist/v2/components/Combobox.js.map +1 -1
  515. package/dist/v2/components/CommandPalette.js +138 -225
  516. package/dist/v2/components/CommandPalette.js.map +1 -1
  517. package/dist/v2/components/ConfirmDialog.js +46 -56
  518. package/dist/v2/components/ConfirmDialog.js.map +1 -1
  519. package/dist/v2/components/DatePicker.js +81 -86
  520. package/dist/v2/components/DatePicker.js.map +1 -1
  521. package/dist/v2/components/DateRangePicker.js +77 -87
  522. package/dist/v2/components/DateRangePicker.js.map +1 -1
  523. package/dist/v2/components/DateTimePicker.js +84 -91
  524. package/dist/v2/components/DateTimePicker.js.map +1 -1
  525. package/dist/v2/components/Drawer.d.ts.map +1 -1
  526. package/dist/v2/components/Drawer.js +93 -88
  527. package/dist/v2/components/Drawer.js.map +1 -1
  528. package/dist/v2/components/Dropzone.js +150 -196
  529. package/dist/v2/components/Dropzone.js.map +1 -1
  530. package/dist/v2/components/EmptyState.js +18 -20
  531. package/dist/v2/components/EmptyState.js.map +1 -1
  532. package/dist/v2/components/FavoriteToggle.js +28 -39
  533. package/dist/v2/components/FavoriteToggle.js.map +1 -1
  534. package/dist/v2/components/Field.d.ts +62 -4
  535. package/dist/v2/components/Field.d.ts.map +1 -1
  536. package/dist/v2/components/Field.js +169 -70
  537. package/dist/v2/components/Field.js.map +1 -1
  538. package/dist/v2/components/FieldError.js +18 -21
  539. package/dist/v2/components/FieldError.js.map +1 -1
  540. package/dist/v2/components/FieldHelp.js +40 -60
  541. package/dist/v2/components/FieldHelp.js.map +1 -1
  542. package/dist/v2/components/FileCard.js +27 -31
  543. package/dist/v2/components/FileCard.js.map +1 -1
  544. package/dist/v2/components/FilterTab.js +30 -38
  545. package/dist/v2/components/FilterTab.js.map +1 -1
  546. package/dist/v2/components/ForbiddenPage.d.ts +25 -1
  547. package/dist/v2/components/ForbiddenPage.d.ts.map +1 -1
  548. package/dist/v2/components/ForbiddenPage.js +37 -17
  549. package/dist/v2/components/ForbiddenPage.js.map +1 -1
  550. package/dist/v2/components/FormGrid.js +53 -59
  551. package/dist/v2/components/FormGrid.js.map +1 -1
  552. package/dist/v2/components/FormikDisplay.d.ts +50 -1
  553. package/dist/v2/components/FormikDisplay.d.ts.map +1 -1
  554. package/dist/v2/components/FormikDisplay.js +108 -33
  555. package/dist/v2/components/FormikDisplay.js.map +1 -1
  556. package/dist/v2/components/Input.d.ts +40 -0
  557. package/dist/v2/components/Input.d.ts.map +1 -1
  558. package/dist/v2/components/Input.js +81 -41
  559. package/dist/v2/components/Input.js.map +1 -1
  560. package/dist/v2/components/KPICard.js +57 -67
  561. package/dist/v2/components/KPICard.js.map +1 -1
  562. package/dist/v2/components/KPIStrip.js +16 -22
  563. package/dist/v2/components/KPIStrip.js.map +1 -1
  564. package/dist/v2/components/KV.js +25 -31
  565. package/dist/v2/components/KV.js.map +1 -1
  566. package/dist/v2/components/KVGrid.js +19 -26
  567. package/dist/v2/components/KVGrid.js.map +1 -1
  568. package/dist/v2/components/Layout.js +91 -120
  569. package/dist/v2/components/Layout.js.map +1 -1
  570. package/dist/v2/components/MobileRowCard.js +79 -91
  571. package/dist/v2/components/MobileRowCard.js.map +1 -1
  572. package/dist/v2/components/Modal.js +61 -69
  573. package/dist/v2/components/Modal.js.map +1 -1
  574. package/dist/v2/components/NetworkErrorPage.d.ts +19 -1
  575. package/dist/v2/components/NetworkErrorPage.d.ts.map +1 -1
  576. package/dist/v2/components/NetworkErrorPage.js +38 -21
  577. package/dist/v2/components/NetworkErrorPage.js.map +1 -1
  578. package/dist/v2/components/NotFoundPage.d.ts +17 -1
  579. package/dist/v2/components/NotFoundPage.d.ts.map +1 -1
  580. package/dist/v2/components/NotFoundPage.js +37 -18
  581. package/dist/v2/components/NotFoundPage.js.map +1 -1
  582. package/dist/v2/components/NumberInput.js +88 -118
  583. package/dist/v2/components/NumberInput.js.map +1 -1
  584. package/dist/v2/components/OverflowMenu.js +38 -56
  585. package/dist/v2/components/OverflowMenu.js.map +1 -1
  586. package/dist/v2/components/PdfViewer.js +34 -45
  587. package/dist/v2/components/PdfViewer.js.map +1 -1
  588. package/dist/v2/components/ProgressBar.js +42 -49
  589. package/dist/v2/components/ProgressBar.js.map +1 -1
  590. package/dist/v2/components/Radio.js +59 -67
  591. package/dist/v2/components/Radio.js.map +1 -1
  592. package/dist/v2/components/SectionErrorBoundary.js +90 -135
  593. package/dist/v2/components/SectionErrorBoundary.js.map +1 -1
  594. package/dist/v2/components/SectionHeader.js +34 -41
  595. package/dist/v2/components/SectionHeader.js.map +1 -1
  596. package/dist/v2/components/Segmented.js +69 -93
  597. package/dist/v2/components/Segmented.js.map +1 -1
  598. package/dist/v2/components/Select.d.ts +26 -2
  599. package/dist/v2/components/Select.d.ts.map +1 -1
  600. package/dist/v2/components/Select.js +120 -155
  601. package/dist/v2/components/Select.js.map +1 -1
  602. package/dist/v2/components/ServerErrorPage.d.ts +27 -1
  603. package/dist/v2/components/ServerErrorPage.d.ts.map +1 -1
  604. package/dist/v2/components/ServerErrorPage.js +37 -20
  605. package/dist/v2/components/ServerErrorPage.js.map +1 -1
  606. package/dist/v2/components/Skeleton.js +86 -100
  607. package/dist/v2/components/Skeleton.js.map +1 -1
  608. package/dist/v2/components/SkipLink.js +9 -12
  609. package/dist/v2/components/SkipLink.js.map +1 -1
  610. package/dist/v2/components/Spinner.js +16 -25
  611. package/dist/v2/components/Spinner.js.map +1 -1
  612. package/dist/v2/components/Status.js +18 -29
  613. package/dist/v2/components/Status.js.map +1 -1
  614. package/dist/v2/components/Stepper.js +80 -82
  615. package/dist/v2/components/Stepper.js.map +1 -1
  616. package/dist/v2/components/Surface.js +34 -49
  617. package/dist/v2/components/Surface.js.map +1 -1
  618. package/dist/v2/components/Switch.js +29 -37
  619. package/dist/v2/components/Switch.js.map +1 -1
  620. package/dist/v2/components/TabPanel.d.ts +17 -0
  621. package/dist/v2/components/TabPanel.d.ts.map +1 -0
  622. package/dist/v2/components/TabPanel.js +90 -0
  623. package/dist/v2/components/TabPanel.js.map +1 -0
  624. package/dist/v2/components/Tabs.d.ts +25 -0
  625. package/dist/v2/components/Tabs.d.ts.map +1 -1
  626. package/dist/v2/components/Tabs.js +53 -29
  627. package/dist/v2/components/Tabs.js.map +1 -1
  628. package/dist/v2/components/TelInput.js +80 -115
  629. package/dist/v2/components/TelInput.js.map +1 -1
  630. package/dist/v2/components/Textarea.js +26 -35
  631. package/dist/v2/components/Textarea.js.map +1 -1
  632. package/dist/v2/components/TimePicker.js +62 -74
  633. package/dist/v2/components/TimePicker.js.map +1 -1
  634. package/dist/v2/components/Toast.js +119 -174
  635. package/dist/v2/components/Toast.js.map +1 -1
  636. package/dist/v2/components/Tooltip.js +23 -38
  637. package/dist/v2/components/Tooltip.js.map +1 -1
  638. package/dist/v2/components/_ErrorPageBody.js +15 -16
  639. package/dist/v2/components/_ErrorPageBody.js.map +1 -1
  640. package/dist/v2/components/_pickerShared.js +5 -5
  641. package/dist/v2/components/_pickerShared.js.map +1 -1
  642. package/dist/v2/components/index.d.ts +40 -1
  643. package/dist/v2/components/index.d.ts.map +1 -1
  644. package/dist/v2/components/index.js +153 -136
  645. package/dist/v2/components/index.js.map +1 -1
  646. package/dist/v2/hooks/index.d.ts +65 -0
  647. package/dist/v2/hooks/index.d.ts.map +1 -1
  648. package/dist/v2/hooks/index.js +63 -24
  649. package/dist/v2/hooks/index.js.map +1 -1
  650. package/dist/v2/hooks/useAppliedFilters.d.ts +102 -0
  651. package/dist/v2/hooks/useAppliedFilters.d.ts.map +1 -0
  652. package/dist/v2/hooks/useAppliedFilters.js +117 -0
  653. package/dist/v2/hooks/useAppliedFilters.js.map +1 -0
  654. package/dist/v2/hooks/useDebouncedCallback.d.ts +64 -0
  655. package/dist/v2/hooks/useDebouncedCallback.d.ts.map +1 -0
  656. package/dist/v2/hooks/useDebouncedCallback.js +87 -0
  657. package/dist/v2/hooks/useDebouncedCallback.js.map +1 -0
  658. package/dist/v2/hooks/useDelayedFlag.js +6 -20
  659. package/dist/v2/hooks/useDelayedFlag.js.map +1 -1
  660. package/dist/v2/hooks/useDensity.d.ts.map +1 -1
  661. package/dist/v2/hooks/useDensity.js +14 -18
  662. package/dist/v2/hooks/useDensity.js.map +1 -1
  663. package/dist/v2/hooks/useFocusFirstError.js +26 -34
  664. package/dist/v2/hooks/useFocusFirstError.js.map +1 -1
  665. package/dist/v2/hooks/useFocusOnRouteChange.d.ts +65 -0
  666. package/dist/v2/hooks/useFocusOnRouteChange.d.ts.map +1 -0
  667. package/dist/v2/hooks/useFocusOnRouteChange.js +88 -0
  668. package/dist/v2/hooks/useFocusOnRouteChange.js.map +1 -0
  669. package/dist/v2/hooks/useFocusTrap.js +20 -24
  670. package/dist/v2/hooks/useFocusTrap.js.map +1 -1
  671. package/dist/v2/hooks/useFormAutoSave.d.ts +4 -4
  672. package/dist/v2/hooks/useFormAutoSave.d.ts.map +1 -1
  673. package/dist/v2/hooks/useFormAutoSave.js +39 -54
  674. package/dist/v2/hooks/useFormAutoSave.js.map +1 -1
  675. package/dist/v2/hooks/useFormCompletionProgress.d.ts +1 -1
  676. package/dist/v2/hooks/useFormCompletionProgress.d.ts.map +1 -1
  677. package/dist/v2/hooks/useFormCompletionProgress.js +33 -52
  678. package/dist/v2/hooks/useFormCompletionProgress.js.map +1 -1
  679. package/dist/v2/hooks/useKeyboardShortcuts.d.ts +25 -0
  680. package/dist/v2/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  681. package/dist/v2/hooks/useKeyboardShortcuts.js +132 -0
  682. package/dist/v2/hooks/useKeyboardShortcuts.js.map +1 -0
  683. package/dist/v2/hooks/usePrefersReducedMotion.d.ts +56 -0
  684. package/dist/v2/hooks/usePrefersReducedMotion.d.ts.map +1 -0
  685. package/dist/v2/hooks/usePrefersReducedMotion.js +105 -0
  686. package/dist/v2/hooks/usePrefersReducedMotion.js.map +1 -0
  687. package/dist/v2/hooks/useResolvedDensity.js +5 -13
  688. package/dist/v2/hooks/useResolvedDensity.js.map +1 -1
  689. package/dist/v2/hooks/useSortedRows.js +4 -6
  690. package/dist/v2/hooks/useSortedRows.js.map +1 -1
  691. package/dist/v2/hooks/useTabLoading.js +7 -22
  692. package/dist/v2/hooks/useTabLoading.js.map +1 -1
  693. package/dist/v2/index.js +143 -145
  694. package/dist/v2/index.js.map +1 -1
  695. package/dist/v2/modalContext.js +2 -2
  696. package/dist/v2/modalContext.js.map +1 -1
  697. package/dist/v2/models/favorite.d.ts +8 -9
  698. package/dist/v2/models/favorite.d.ts.map +1 -1
  699. package/dist/v2/models/favorite.js.map +1 -1
  700. package/dist/v2/models/index.js +4 -4
  701. package/dist/v2/models/index.js.map +1 -1
  702. package/dist/v2/models/personalization.d.ts +44 -48
  703. package/dist/v2/models/personalization.d.ts.map +1 -1
  704. package/dist/v2/models/personalization.js.map +1 -1
  705. package/dist/v2/models/referentiel.d.ts +32 -50
  706. package/dist/v2/models/referentiel.d.ts.map +1 -1
  707. package/dist/v2/models/referentiel.js.map +1 -1
  708. package/dist/v2/models/savedFilter.d.ts +8 -17
  709. package/dist/v2/models/savedFilter.d.ts.map +1 -1
  710. package/dist/v2/models/savedFilter.js.map +1 -1
  711. package/dist/v2/patterns/ActionBar.js +152 -187
  712. package/dist/v2/patterns/ActionBar.js.map +1 -1
  713. package/dist/v2/patterns/AppMain.d.ts +109 -0
  714. package/dist/v2/patterns/AppMain.d.ts.map +1 -0
  715. package/dist/v2/patterns/AppMain.js +115 -0
  716. package/dist/v2/patterns/AppMain.js.map +1 -0
  717. package/dist/v2/patterns/BulkActionBar.js +40 -42
  718. package/dist/v2/patterns/BulkActionBar.js.map +1 -1
  719. package/dist/v2/patterns/ChartFigure.d.ts +124 -0
  720. package/dist/v2/patterns/ChartFigure.d.ts.map +1 -0
  721. package/dist/v2/patterns/ChartFigure.js +159 -0
  722. package/dist/v2/patterns/ChartFigure.js.map +1 -0
  723. package/dist/v2/patterns/CollapsibleDataGrid.js +138 -174
  724. package/dist/v2/patterns/CollapsibleDataGrid.js.map +1 -1
  725. package/dist/v2/patterns/ColumnsToggle.js +60 -94
  726. package/dist/v2/patterns/ColumnsToggle.js.map +1 -1
  727. package/dist/v2/patterns/DataGrid.d.ts.map +1 -1
  728. package/dist/v2/patterns/DataGrid.js +262 -297
  729. package/dist/v2/patterns/DataGrid.js.map +1 -1
  730. package/dist/v2/patterns/DataGridSettingsMenu.d.ts +12 -0
  731. package/dist/v2/patterns/DataGridSettingsMenu.d.ts.map +1 -1
  732. package/dist/v2/patterns/DataGridSettingsMenu.js +104 -121
  733. package/dist/v2/patterns/DataGridSettingsMenu.js.map +1 -1
  734. package/dist/v2/patterns/DataGridToolbar.js +103 -106
  735. package/dist/v2/patterns/DataGridToolbar.js.map +1 -1
  736. package/dist/v2/patterns/DataGridVirtualized.js +179 -217
  737. package/dist/v2/patterns/DataGridVirtualized.js.map +1 -1
  738. package/dist/v2/patterns/DeleteResourceConfirmDialog.js +32 -35
  739. package/dist/v2/patterns/DeleteResourceConfirmDialog.js.map +1 -1
  740. package/dist/v2/patterns/DetailSplit.d.ts +87 -0
  741. package/dist/v2/patterns/DetailSplit.d.ts.map +1 -0
  742. package/dist/v2/patterns/DetailSplit.js +116 -0
  743. package/dist/v2/patterns/DetailSplit.js.map +1 -0
  744. package/dist/v2/patterns/FavoriteColumn.js +22 -23
  745. package/dist/v2/patterns/FavoriteColumn.js.map +1 -1
  746. package/dist/v2/patterns/FavoritesFilter.js +36 -44
  747. package/dist/v2/patterns/FavoritesFilter.js.map +1 -1
  748. package/dist/v2/patterns/FilterTabBar.d.ts +28 -0
  749. package/dist/v2/patterns/FilterTabBar.d.ts.map +1 -0
  750. package/dist/v2/patterns/FilterTabBar.js +120 -0
  751. package/dist/v2/patterns/FilterTabBar.js.map +1 -0
  752. package/dist/v2/patterns/FormErrorSummary.js +20 -23
  753. package/dist/v2/patterns/FormErrorSummary.js.map +1 -1
  754. package/dist/v2/patterns/FormPageShell.js +53 -50
  755. package/dist/v2/patterns/FormPageShell.js.map +1 -1
  756. package/dist/v2/patterns/FormSection.d.ts +8 -3
  757. package/dist/v2/patterns/FormSection.d.ts.map +1 -1
  758. package/dist/v2/patterns/FormSection.js +44 -51
  759. package/dist/v2/patterns/FormSection.js.map +1 -1
  760. package/dist/v2/patterns/FormikCheckbox.js +36 -45
  761. package/dist/v2/patterns/FormikCheckbox.js.map +1 -1
  762. package/dist/v2/patterns/FormikCheckboxGroup.d.ts +17 -1
  763. package/dist/v2/patterns/FormikCheckboxGroup.d.ts.map +1 -1
  764. package/dist/v2/patterns/FormikCheckboxGroup.js +62 -65
  765. package/dist/v2/patterns/FormikCheckboxGroup.js.map +1 -1
  766. package/dist/v2/patterns/FormikCombobox.js +55 -72
  767. package/dist/v2/patterns/FormikCombobox.js.map +1 -1
  768. package/dist/v2/patterns/FormikDatePicker.js +50 -64
  769. package/dist/v2/patterns/FormikDatePicker.js.map +1 -1
  770. package/dist/v2/patterns/FormikDateTimePicker.js +50 -64
  771. package/dist/v2/patterns/FormikDateTimePicker.js.map +1 -1
  772. package/dist/v2/patterns/FormikErrorFocus.js +25 -26
  773. package/dist/v2/patterns/FormikErrorFocus.js.map +1 -1
  774. package/dist/v2/patterns/FormikErrorSummary.d.ts +74 -0
  775. package/dist/v2/patterns/FormikErrorSummary.d.ts.map +1 -0
  776. package/dist/v2/patterns/FormikErrorSummary.js +97 -0
  777. package/dist/v2/patterns/FormikErrorSummary.js.map +1 -0
  778. package/dist/v2/patterns/FormikFile.d.ts +14 -1
  779. package/dist/v2/patterns/FormikFile.d.ts.map +1 -1
  780. package/dist/v2/patterns/FormikFile.js +99 -83
  781. package/dist/v2/patterns/FormikFile.js.map +1 -1
  782. package/dist/v2/patterns/FormikInput.js +45 -58
  783. package/dist/v2/patterns/FormikInput.js.map +1 -1
  784. package/dist/v2/patterns/FormikRadioGroup.js +45 -56
  785. package/dist/v2/patterns/FormikRadioGroup.js.map +1 -1
  786. package/dist/v2/patterns/FormikReferentielField.d.ts +12 -1
  787. package/dist/v2/patterns/FormikReferentielField.d.ts.map +1 -1
  788. package/dist/v2/patterns/FormikReferentielField.js +54 -64
  789. package/dist/v2/patterns/FormikReferentielField.js.map +1 -1
  790. package/dist/v2/patterns/FormikSelect.js +70 -92
  791. package/dist/v2/patterns/FormikSelect.js.map +1 -1
  792. package/dist/v2/patterns/FormikTextarea.js +35 -51
  793. package/dist/v2/patterns/FormikTextarea.js.map +1 -1
  794. package/dist/v2/patterns/KeyboardShortcutsHelp.js +60 -80
  795. package/dist/v2/patterns/KeyboardShortcutsHelp.js.map +1 -1
  796. package/dist/v2/patterns/NetworkErrorBanner.js +13 -16
  797. package/dist/v2/patterns/NetworkErrorBanner.js.map +1 -1
  798. package/dist/v2/patterns/PageContent.js +17 -20
  799. package/dist/v2/patterns/PageContent.js.map +1 -1
  800. package/dist/v2/patterns/PreviewDrawer.d.ts +49 -0
  801. package/dist/v2/patterns/PreviewDrawer.d.ts.map +1 -0
  802. package/dist/v2/patterns/PreviewDrawer.js +159 -0
  803. package/dist/v2/patterns/PreviewDrawer.js.map +1 -0
  804. package/dist/v2/patterns/ReferentielField.d.ts +86 -2
  805. package/dist/v2/patterns/ReferentielField.d.ts.map +1 -1
  806. package/dist/v2/patterns/ReferentielField.js +347 -327
  807. package/dist/v2/patterns/ReferentielField.js.map +1 -1
  808. package/dist/v2/patterns/RowFavoriteToggle.d.ts +6 -0
  809. package/dist/v2/patterns/RowFavoriteToggle.d.ts.map +1 -1
  810. package/dist/v2/patterns/RowFavoriteToggle.js +38 -30
  811. package/dist/v2/patterns/RowFavoriteToggle.js.map +1 -1
  812. package/dist/v2/patterns/SaveFilterDialog.js +50 -77
  813. package/dist/v2/patterns/SaveFilterDialog.js.map +1 -1
  814. package/dist/v2/patterns/SavedFiltersMenu.js +89 -107
  815. package/dist/v2/patterns/SavedFiltersMenu.js.map +1 -1
  816. package/dist/v2/patterns/SkeletonPageShell.js +122 -143
  817. package/dist/v2/patterns/SkeletonPageShell.js.map +1 -1
  818. package/dist/v2/patterns/SortableHeader.js +35 -57
  819. package/dist/v2/patterns/SortableHeader.js.map +1 -1
  820. package/dist/v2/patterns/Tour.js +121 -142
  821. package/dist/v2/patterns/Tour.js.map +1 -1
  822. package/dist/v2/patterns/_dataGridShared.d.ts.map +1 -1
  823. package/dist/v2/patterns/_dataGridShared.js +131 -147
  824. package/dist/v2/patterns/_dataGridShared.js.map +1 -1
  825. package/dist/v2/patterns/_pickerSerialisation.js +9 -10
  826. package/dist/v2/patterns/_pickerSerialisation.js.map +1 -1
  827. package/dist/v2/patterns/_sort.js +17 -33
  828. package/dist/v2/patterns/_sort.js.map +1 -1
  829. package/dist/v2/patterns/_useColumnReorder.js +124 -163
  830. package/dist/v2/patterns/_useColumnReorder.js.map +1 -1
  831. package/dist/v2/patterns/_useColumnResize.js +80 -99
  832. package/dist/v2/patterns/_useColumnResize.js.map +1 -1
  833. package/dist/v2/patterns/filterCriteria.d.ts +78 -0
  834. package/dist/v2/patterns/filterCriteria.d.ts.map +1 -0
  835. package/dist/v2/patterns/filterCriteria.js +110 -0
  836. package/dist/v2/patterns/filterCriteria.js.map +1 -0
  837. package/dist/v2/patterns/index.d.ts +160 -0
  838. package/dist/v2/patterns/index.d.ts.map +1 -1
  839. package/dist/v2/patterns/index.js +157 -79
  840. package/dist/v2/patterns/index.js.map +1 -1
  841. package/dist/v2/patterns/rowActions.d.ts +150 -0
  842. package/dist/v2/patterns/rowActions.d.ts.map +1 -0
  843. package/dist/v2/patterns/rowActions.js +232 -0
  844. package/dist/v2/patterns/rowActions.js.map +1 -0
  845. package/dist/v2/personalization/PersonalizationProvider.d.ts.map +1 -1
  846. package/dist/v2/personalization/PersonalizationProvider.js +57 -53
  847. package/dist/v2/personalization/PersonalizationProvider.js.map +1 -1
  848. package/dist/v2/personalization/adapters/_storageKey.js +5 -5
  849. package/dist/v2/personalization/adapters/_storageKey.js.map +1 -1
  850. package/dist/v2/personalization/adapters/createLocalStorageAdapter.js +25 -24
  851. package/dist/v2/personalization/adapters/createLocalStorageAdapter.js.map +1 -1
  852. package/dist/v2/personalization/adapters/createMemoryAdapter.js +14 -14
  853. package/dist/v2/personalization/adapters/createMemoryAdapter.js.map +1 -1
  854. package/dist/v2/personalization/adapters/index.js +5 -5
  855. package/dist/v2/personalization/adapters/index.js.map +1 -1
  856. package/dist/v2/personalization/capabilities/favorites.js +39 -62
  857. package/dist/v2/personalization/capabilities/favorites.js.map +1 -1
  858. package/dist/v2/personalization/capabilities/favoritesView.js +25 -37
  859. package/dist/v2/personalization/capabilities/favoritesView.js.map +1 -1
  860. package/dist/v2/personalization/capabilities/gridPreferences.js +31 -36
  861. package/dist/v2/personalization/capabilities/gridPreferences.js.map +1 -1
  862. package/dist/v2/personalization/capabilities/index.js +12 -12
  863. package/dist/v2/personalization/capabilities/reviveSavedCriteria.d.ts +88 -0
  864. package/dist/v2/personalization/capabilities/reviveSavedCriteria.d.ts.map +1 -0
  865. package/dist/v2/personalization/capabilities/reviveSavedCriteria.js +126 -0
  866. package/dist/v2/personalization/capabilities/reviveSavedCriteria.js.map +1 -0
  867. package/dist/v2/personalization/capabilities/savedFilters.js +93 -100
  868. package/dist/v2/personalization/capabilities/savedFilters.js.map +1 -1
  869. package/dist/v2/personalization/createPersonalizationStore.d.ts.map +1 -1
  870. package/dist/v2/personalization/createPersonalizationStore.js +81 -182
  871. package/dist/v2/personalization/createPersonalizationStore.js.map +1 -1
  872. package/dist/v2/personalization/index.d.ts +16 -0
  873. package/dist/v2/personalization/index.d.ts.map +1 -1
  874. package/dist/v2/personalization/index.js +30 -23
  875. package/dist/v2/personalization/index.js.map +1 -1
  876. package/dist/v2/personalization/personalizationContext.js +10 -12
  877. package/dist/v2/personalization/personalizationContext.js.map +1 -1
  878. package/dist/v2/personalization/schema.js +8 -9
  879. package/dist/v2/personalization/schema.js.map +1 -1
  880. package/dist/v2/referentiel/ReferentielProvider.js +31 -45
  881. package/dist/v2/referentiel/ReferentielProvider.js.map +1 -1
  882. package/dist/v2/referentiel/index.js +11 -13
  883. package/dist/v2/referentiel/index.js.map +1 -1
  884. package/dist/v2/referentiel/types.d.ts +105 -0
  885. package/dist/v2/referentiel/types.d.ts.map +1 -0
  886. package/dist/v2/referentiel/types.js +6 -0
  887. package/dist/v2/referentiel/types.js.map +1 -0
  888. package/dist/v2/referentiel/useReferentielClient.js +13 -16
  889. package/dist/v2/referentiel/useReferentielClient.js.map +1 -1
  890. package/dist/v2/referentiel/useReferentielOptions.d.ts +7 -17
  891. package/dist/v2/referentiel/useReferentielOptions.d.ts.map +1 -1
  892. package/dist/v2/referentiel/useReferentielOptions.js +63 -120
  893. package/dist/v2/referentiel/useReferentielOptions.js.map +1 -1
  894. package/dist/v2/referentiel/useReferentielSearch.d.ts +7 -48
  895. package/dist/v2/referentiel/useReferentielSearch.d.ts.map +1 -1
  896. package/dist/v2/referentiel/useReferentielSearch.js +40 -95
  897. package/dist/v2/referentiel/useReferentielSearch.js.map +1 -1
  898. package/dist/v2/theme/_brand.js +12 -26
  899. package/dist/v2/theme/_brand.js.map +1 -1
  900. package/dist/v2/theme/_brandSecondary.js +12 -26
  901. package/dist/v2/theme/_brandSecondary.js.map +1 -1
  902. package/dist/v2/theme/createPortnetTheme.js +41 -49
  903. package/dist/v2/theme/createPortnetTheme.js.map +1 -1
  904. package/dist/v2/theme/cssVariables.d.ts +3 -3
  905. package/dist/v2/theme/cssVariables.d.ts.map +1 -1
  906. package/dist/v2/theme/cssVariables.js +65 -70
  907. package/dist/v2/theme/cssVariables.js.map +1 -1
  908. package/dist/v2/theme/index.js +10 -10
  909. package/dist/v2/theme/index.js.map +1 -1
  910. package/dist/v2/tokens/breakpoints.js +16 -16
  911. package/dist/v2/tokens/breakpoints.js.map +1 -1
  912. package/dist/v2/tokens/chart.d.ts +103 -0
  913. package/dist/v2/tokens/chart.d.ts.map +1 -0
  914. package/dist/v2/tokens/chart.js +270 -0
  915. package/dist/v2/tokens/chart.js.map +1 -0
  916. package/dist/v2/tokens/colors.js +24 -24
  917. package/dist/v2/tokens/colors.js.map +1 -1
  918. package/dist/v2/tokens/density.d.ts +104 -0
  919. package/dist/v2/tokens/density.d.ts.map +1 -1
  920. package/dist/v2/tokens/density.js +67 -12
  921. package/dist/v2/tokens/density.js.map +1 -1
  922. package/dist/v2/tokens/index.d.ts +50 -1
  923. package/dist/v2/tokens/index.d.ts.map +1 -1
  924. package/dist/v2/tokens/index.js +116 -68
  925. package/dist/v2/tokens/index.js.map +1 -1
  926. package/dist/v2/tokens/motion.js +16 -22
  927. package/dist/v2/tokens/motion.js.map +1 -1
  928. package/dist/v2/tokens/radius.js +3 -3
  929. package/dist/v2/tokens/radius.js.map +1 -1
  930. package/dist/v2/tokens/shadows.js +8 -8
  931. package/dist/v2/tokens/shadows.js.map +1 -1
  932. package/dist/v2/tokens/spacing.js +4 -4
  933. package/dist/v2/tokens/spacing.js.map +1 -1
  934. package/dist/v2/tokens/state.js +3 -3
  935. package/dist/v2/tokens/state.js.map +1 -1
  936. package/dist/v2/tokens/statusPalette.js +21 -23
  937. package/dist/v2/tokens/statusPalette.js.map +1 -1
  938. package/dist/v2/tokens/tokens.json +6 -1
  939. package/dist/v2/tokens/typography.js +15 -15
  940. package/dist/v2/tokens/typography.js.map +1 -1
  941. package/dist/v2/tokens/zIndex.js +3 -3
  942. package/dist/v2/tokens/zIndex.js.map +1 -1
  943. package/dist/v2/types/datagrid.d.ts +9 -1
  944. package/dist/v2/types/datagrid.d.ts.map +1 -1
  945. package/dist/v2/types/datagrid.js.map +1 -1
  946. package/dist/v2/types/index.js +2 -2
  947. package/dist/v2/types/index.js.map +1 -1
  948. package/dist/v2/utils/apiError.js +16 -37
  949. package/dist/v2/utils/apiError.js.map +1 -1
  950. package/dist/v2/utils/contrast.js +31 -32
  951. package/dist/v2/utils/contrast.js.map +1 -1
  952. package/dist/v2/utils/cx.js +7 -27
  953. package/dist/v2/utils/cx.js.map +1 -1
  954. package/dist/v2/utils/fileDownload.js +25 -28
  955. package/dist/v2/utils/fileDownload.js.map +1 -1
  956. package/dist/v2/utils/fileValidation.d.ts +116 -0
  957. package/dist/v2/utils/fileValidation.d.ts.map +1 -0
  958. package/dist/v2/utils/fileValidation.js +220 -0
  959. package/dist/v2/utils/fileValidation.js.map +1 -0
  960. package/dist/v2/utils/fmtDate.d.ts +103 -0
  961. package/dist/v2/utils/fmtDate.d.ts.map +1 -0
  962. package/dist/v2/utils/fmtDate.js +119 -0
  963. package/dist/v2/utils/fmtDate.js.map +1 -0
  964. package/dist/v2/utils/fmtMoney.d.ts +3 -3
  965. package/dist/v2/utils/fmtMoney.d.ts.map +1 -1
  966. package/dist/v2/utils/fmtMoney.js +9 -11
  967. package/dist/v2/utils/fmtMoney.js.map +1 -1
  968. package/dist/v2/utils/formikErrors.d.ts +67 -0
  969. package/dist/v2/utils/formikErrors.d.ts.map +1 -0
  970. package/dist/v2/utils/formikErrors.js +85 -0
  971. package/dist/v2/utils/formikErrors.js.map +1 -0
  972. package/dist/v2/utils/index.d.ts +5 -0
  973. package/dist/v2/utils/index.d.ts.map +1 -1
  974. package/dist/v2/utils/index.js +67 -18
  975. package/dist/v2/utils/index.js.map +1 -1
  976. package/dist/v2/utils/mergeLabels.js +9 -14
  977. package/dist/v2/utils/mergeLabels.js.map +1 -1
  978. package/dist/v2/utils/networkStatus.js +14 -14
  979. package/dist/v2/utils/networkStatus.js.map +1 -1
  980. package/package.json +26 -9
@@ -1 +1 @@
1
- {"version":3,"file":"apiError.js","names":["DEFAULT_API_ERROR_MESSAGE","exports","readPath","source","path","current","_iterator","_createForOfIteratorHelper","_step","s","n","done","key","value","_typeof","undefined","Reflect","get","err","e","f","asNonEmptyString","length","TRANSPORT_MESSAGE_PATTERNS","isTransportMessage","some","pattern","test","trim","asUserFacingMessage","text","getApiErrorMessage","error","_ref","_ref2","_ref3","_asNonEmptyString","fallback","arguments","getApiErrorDetail","getApiErrorStatus","bodyStatus","status"],"sources":["../../../src/lib/v2/utils/apiError.ts"],"sourcesContent":["/**\r\n * apiError — narrow an `unknown` rejection into something displayable.\r\n *\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n * WHY THIS BELONGS IN THE LIBRARY (capability gap G-04)\r\n *\r\n * The Platform TypeScript Guidelines mandate `useUnknownInCatchVariables`, so\r\n * `catch (e)` binds `unknown` in EVERY saga of EVERY consuming module. The same\r\n * guidelines forbid `any` and unsafe assertions. Between those two rules sits a\r\n * narrowing helper that the library did not provide — so each module wrote its\r\n * own, and the observed outcome was that they wrote it the forbidden way:\r\n *\r\n * (error as { response?: { data?: { message?: unknown } } }).response\r\n *\r\n * i.e. an unchecked assertion on an `unknown`, used to work around a flag the\r\n * platform imposes. Two modules audited (`procuration-portnet-fe`,\r\n * `procuration-fe`) had independently reached for exactly that construct.\r\n * A mandated strict-mode flag with no sanctioned escape hatch produces\r\n * unsanctioned ones.\r\n *\r\n * Implementation notes\r\n * --------------------\r\n * `readPath` walks nested objects using the `in` operator, which narrows without\r\n * an assertion, and `Reflect.get`, which returns the value as `unknown` rather\r\n * than widening anything to `any`. No assertion appears anywhere in this file.\r\n *\r\n * Deliberately DUCK-TYPED rather than built on `axios.isAxiosError`. Three\r\n * reasons: this library must not take a hard axios dependency for a string\r\n * helper; a plain object shaped like an axios error (a hand-rolled reject, a\r\n * test double, a non-axios transport) still resolves correctly; and the check\r\n * stays valid across axios majors.\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n *\r\n * getApiErrorMessage(err) → backend message, or the default\r\n * getApiErrorMessage(err, \"Échec de l'envoi.\") → custom fallback\r\n * getApiErrorStatus(err) → 404 | undefined\r\n *\r\n * Envelope keys read, in order: `data.body`, `data.message`, `data.error`.\r\n * Three keys because three PORTNET back-ends chose differently; see the\r\n * resolution-order note on `getApiErrorMessage` before adding a fourth.\r\n */\r\n\r\n/**\r\n * Default user-facing fallback. French per Charter §09 (voice, vouvoiement) and\r\n * §09.3 (no raw technical detail — never \"Erreur 422 Unprocessable Entity\").\r\n * Override per call site when a screen can say something more useful.\r\n */\r\nexport const DEFAULT_API_ERROR_MESSAGE =\r\n \"Une erreur est survenue. Veuillez réessayer.\";\r\n\r\n/**\r\n * Walk `path` through nested non-null objects, returning the value at the end,\r\n * or `undefined` if any hop is missing. Assertion-free.\r\n */\r\nconst readPath = (source: unknown, path: readonly string[]): unknown => {\r\n let current: unknown = source;\r\n\r\n for (const key of path) {\r\n if (typeof current !== \"object\" || current === null || !(key in current)) {\r\n return undefined;\r\n }\r\n current = Reflect.get(current, key);\r\n }\r\n\r\n return current;\r\n};\r\n\r\nconst asNonEmptyString = (value: unknown): string | undefined =>\r\n typeof value === \"string\" && value.length > 0 ? value : undefined;\r\n\r\n/**\r\n * Transport-layer phrasings that must NEVER reach a user — capability gap G-07.\r\n *\r\n * ──────────────────────────────────────────────────────────────────────\r\n * THE DEFECT THIS FIXES\r\n *\r\n * `getApiErrorMessage` resolved `error.message` BEFORE its fallback. An\r\n * `AxiosError` always has `.message`, so on any server error carrying no\r\n * `response.data.message` — a 500 with an empty body, a gateway error, a\r\n * timeout — step 3 won and the user was shown:\r\n *\r\n * \"Request failed with status code 500\"\r\n *\r\n * English, technical, and precisely the shape Charter §09.3 names as forbidden\r\n * (\"✗ « Erreur 422 — Unprocessable Entity »\"). Worse, it made every consuming\r\n * module's carefully-written French fallback effectively UNREACHABLE — the\r\n * argument was accepted and then almost never used. Found during the\r\n * `procuration-portnet-fe` Area 10 audit, where 12 call sites pass a considered\r\n * fallback that could essentially never render.\r\n *\r\n * WHY A DENY-LIST AND NOT SIMPLY DROPPING STEP 3\r\n *\r\n * Step 3 also carries LEGITIMATE messages: any `throw new Error(\"Ce titre ne\r\n * peut pas être supprimé car il est en cours de validation.\")` in module code\r\n * arrives through exactly the same path. Removing the hop would trade a leak of\r\n * technical strings for the loss of real business messages across the whole\r\n * platform — a worse outcome. So the hop stays and only transport phrasings are\r\n * suppressed.\r\n *\r\n * The list is deliberately CONSERVATIVE: anything not recognised passes through,\r\n * on the assumption a human wrote it. A false negative shows one ugly string; a\r\n * false positive silently replaces a real business message with a generic\r\n * fallback, which is the more damaging error.\r\n *\r\n * Sourced from axios's own message construction (`settle`, `AxiosError` codes\r\n * ECONNABORTED / ETIMEDOUT / ERR_NETWORK / ERR_CANCELED) plus the Node socket\r\n * phrasing that surfaces through SSR and test doubles.\r\n * ──────────────────────────────────────────────────────────────────────\r\n */\r\nconst TRANSPORT_MESSAGE_PATTERNS: readonly RegExp[] = [\r\n /^request failed with status code \\d+$/i,\r\n /^network error$/i,\r\n /^timeout of \\d+ms exceeded$/i,\r\n /^timeout exceeded$/i,\r\n /^request aborted$/i,\r\n /^canceled$/i,\r\n /^unsupported protocol/i,\r\n /^maximum content size exceeded$/i,\r\n /^socket hang up$/i,\r\n /* ── errno codes and axios error codes ── CASE-SENSITIVE, DELIBERATELY ─────\r\n *\r\n * These two are the only patterns here NOT marked `/i`, and the asymmetry is\r\n * load-bearing. errno constants are uppercase by universal convention\r\n * (`ETIMEDOUT`, `ECONNREFUSED`, `ENOTFOUND`, `EPIPE`), so an uppercase-only\r\n * match identifies them precisely. Matching case-insensitively would make\r\n * `/^e[a-z]+$/i` swallow ordinary French words beginning with \"e\" — \"erreur\",\r\n * \"expiré\", \"échec\" — turning a real business message into a generic fallback,\r\n * which is the more damaging failure this list is tuned against.\r\n *\r\n * ⚠ An earlier version of the first pattern was `/^ec[a-z]+$/i`, which matched\r\n * `ECONNREFUSED` (it begins \"EC\") but silently MISSED `ETIMEDOUT` (\"ET\"),\r\n * despite the comment claiming otherwise. The unit test caught it. Do not\r\n * narrow the prefix again: the family is \"E + uppercase word\", not \"EC...\".\r\n *\r\n * Residual, accepted: an all-caps single word like \"ERREUR\" is treated as an\r\n * errno code. A module should not be throwing all-caps single-word messages at\r\n * users, and replacing one with a proper French fallback is an improvement. */\r\n /^E[A-Z]{3,}$/, // errno: ETIMEDOUT, ECONNREFUSED, ECONNRESET, ENOTFOUND, EPIPE\r\n /^ERR_[A-Z_]+$/, // axios: ERR_NETWORK, ERR_CANCELED, ERR_BAD_RESPONSE\r\n];\r\n\r\n/** Is this string an axios/transport artefact rather than something for a user? */\r\nconst isTransportMessage = (value: string): boolean =>\r\n TRANSPORT_MESSAGE_PATTERNS.some((pattern) => pattern.test(value.trim()));\r\n\r\n/**\r\n * `error.message`, but only when it is fit to show a user.\r\n *\r\n * Suppresses transport phrasings (G-07) so the caller's French fallback is\r\n * reached instead. Module-thrown `Error` messages pass through untouched.\r\n */\r\nconst asUserFacingMessage = (value: unknown): string | undefined => {\r\n const text = asNonEmptyString(value);\r\n if (text === undefined) return undefined;\r\n return isTransportMessage(text) ? undefined : text;\r\n};\r\n\r\n/**\r\n * Best available human-readable message for a rejection of unknown shape.\r\n *\r\n * Resolution order, first match wins:\r\n * 1. the rejection itself, when it is a non-empty string;\r\n * 2. `error.response.data.body` — the SAME envelope's third key;\r\n * 3. `error.response.data.message` — the backend's own message;\r\n * 4. `error.response.data.error` — the SAME envelope's alternate key;\r\n * 5. `error.message` — **only when it is not a transport artefact** (G-07);\r\n * 6. `fallback`.\r\n *\r\n * Step 4 closes capability gap G-08. Several PORTNET back-ends populate\r\n * `data.error` rather than `data.message` (addpe-fe declares BOTH on its\r\n * `ApiErrorBody` and read both at seven call sites), so a helper that stopped at\r\n * `data.message` skipped a real business message and fell through to the generic\r\n * fallback — which made it non-substitutable for the module-local extractors it\r\n * exists to replace. Strictly additive: what step 4 now catches previously\r\n * reached step 5 or 6.\r\n *\r\n * Step 2 closes G-08bis — the same defect, a third key. `caution-ui`'s axios\r\n * interceptor reads `error.response.data.body ?? error.response.data.message`,\r\n * so on that back-end a helper stopping at `message` again skipped a real\r\n * business message. Without step 2 the helper was non-substitutable there and\r\n * the module would have had to keep its own assertion-based extractor.\r\n *\r\n * WHY STEP 2 SITS BEFORE `message` AND NOT AFTER `error`.\r\n * `caution-ui` uses `??`, which is direct evidence that a single response can\r\n * carry both keys and that `body` is the one that back-end means. Appending\r\n * `body` at the end of the envelope hops would therefore have SILENTLY FLIPPED\r\n * which message its users see. Placing it first preserves that precedence, and\r\n * is provably a no-op for every module that does not populate `body`: `readPath`\r\n * returns `undefined` and resolution falls straight through to `message`.\r\n *\r\n * The one case this perturbs is a back-end that populates BOTH `body` and\r\n * `message` while intending `message` to win. No such module exists in the\r\n * portfolio — addpe-fe's `ApiErrorBody` declares `message` and `error`, not\r\n * `body` — and a module in that position should say so here rather than have the\r\n * order guessed for it.\r\n *\r\n * Step 5 is filtered: `\"Request failed with status code 500\"`, `\"Network Error\"`,\r\n * timeouts and errno codes are SUPPRESSED so the caller's own French copy is\r\n * used instead (Charter §09.3 — no raw technical detail). A message a module\r\n * threw deliberately still passes through. Use `getApiErrorDetail` when you want\r\n * the unfiltered string for a log.\r\n *\r\n * Never throws and never returns an empty string, so it is safe to render\r\n * directly into a toast or a `Banner`.\r\n *\r\n * @param error The caught value. `unknown` by design.\r\n * @param fallback Message when nothing usable is found.\r\n */\r\nexport function getApiErrorMessage(\r\n error: unknown,\r\n fallback: string = DEFAULT_API_ERROR_MESSAGE\r\n): string {\r\n if (typeof error === \"string\" && error.length > 0) return error;\r\n\r\n return (\r\n asNonEmptyString(readPath(error, [\"response\", \"data\", \"body\"])) ??\r\n asNonEmptyString(readPath(error, [\"response\", \"data\", \"message\"])) ??\r\n asNonEmptyString(readPath(error, [\"response\", \"data\", \"error\"])) ??\r\n asUserFacingMessage(readPath(error, [\"message\"])) ??\r\n fallback\r\n );\r\n}\r\n\r\n/**\r\n * Unfiltered technical detail for LOGGING — never for display.\r\n *\r\n * `getApiErrorMessage` deliberately suppresses transport phrasings (G-07), which\r\n * is right for a toast and wrong for a console or an APM breadcrumb, where\r\n * `\"Request failed with status code 502\"` is exactly what an operator needs. This\r\n * is the escape hatch: it returns the raw `error.message` when there is one,\r\n * whatever its shape.\r\n *\r\n * Pair them:\r\n *\r\n * toast(getApiErrorMessage(err, \"Échec de l'envoi.\"), \"error\");\r\n * console.error(\"[submit]\", getApiErrorStatus(err), getApiErrorDetail(err));\r\n */\r\nexport function getApiErrorDetail(error: unknown): string | undefined {\r\n if (typeof error === \"string\" && error.length > 0) return error;\r\n return asNonEmptyString(readPath(error, [\"message\"]));\r\n}\r\n\r\n/**\r\n * HTTP status carried by a rejection, when there is one.\r\n *\r\n * Resolution order, first numeric match wins:\r\n * 1. `error.response.data.status` — a BODY-level status;\r\n * 2. `error.response.status` — the transport status.\r\n *\r\n * Returns `undefined` for a network drop, a timeout, or any non-HTTP rejection —\r\n * which is the signal callers use to distinguish \"the server answered with an\r\n * error\" from \"there was no answer at all\" (Charter R-4.3: a status-less failure\r\n * is a network banner, not a toast).\r\n *\r\n * Step 1 closes G-08ter, the status-side counterpart of the envelope-key gaps\r\n * G-08 / G-08bis. Several PORTNET back-ends put the meaningful status in the\r\n * BODY: caution-ui's axios interceptor reads\r\n * `error.response.data.status ?? error.response.status` and routes on the\r\n * result (404 -> not-found page, 500 -> server-error page, 401 -> re-login), and\r\n * its RESPONSE interceptor does the same for success handling. A helper reading\r\n * only the transport status was therefore not substitutable there — the module\r\n * had to keep a hand-written `HttpErrorLike` interface and assert onto it, which\r\n * is exactly the anti-pattern G-04 exists to end. Closing the message side\r\n * (G-08bis) without the status side would have left that assertion in place for\r\n * the sake of one field.\r\n *\r\n * Body-first ordering mirrors the module's own `??` and is provably a no-op for\r\n * every back-end that does not populate `data.status`: `readPath` returns\r\n * `undefined` and resolution falls through to the transport status.\r\n *\r\n * BOTH hops are numeric-guarded, which is a deliberate tightening over the\r\n * module code being replaced. That code did `String(status)` on whatever it\r\n * found, so a body carrying `status: \"ERROR\"` produced a `String` switch miss\r\n * and fell to the default toast branch; here a non-numeric `data.status` is\r\n * ignored and the real transport status is used instead. That is the more useful\r\n * answer, and it keeps the return type honest — the signature promises a number.\r\n */\r\nexport function getApiErrorStatus(error: unknown): number | undefined {\r\n const bodyStatus = readPath(error, [\"response\", \"data\", \"status\"]);\r\n if (typeof bodyStatus === \"number\") return bodyStatus;\r\n\r\n const status = readPath(error, [\"response\", \"status\"]);\r\n return typeof status === \"number\" ? status : undefined;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"apiError.js","names":["DEFAULT_API_ERROR_MESSAGE","exports","readPath","source","path","current","key","undefined","Reflect","get","asNonEmptyString","value","length","TRANSPORT_MESSAGE_PATTERNS","isTransportMessage","some","pattern","test","trim","asUserFacingMessage","text","getApiErrorMessage","error","fallback","getApiErrorDetail","getApiErrorStatus","bodyStatus","status"],"sources":["../../../src/lib/v2/utils/apiError.ts"],"sourcesContent":["/**\r\n * apiError — narrow an `unknown` rejection into something displayable.\r\n *\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n * WHY THIS BELONGS IN THE LIBRARY (capability gap G-04)\r\n *\r\n * The Platform TypeScript Guidelines mandate `useUnknownInCatchVariables`, so\r\n * `catch (e)` binds `unknown` in EVERY saga of EVERY consuming module. The same\r\n * guidelines forbid `any` and unsafe assertions. Between those two rules sits a\r\n * narrowing helper that the library did not provide — so each module wrote its\r\n * own, and the observed outcome was that they wrote it the forbidden way:\r\n *\r\n * (error as { response?: { data?: { message?: unknown } } }).response\r\n *\r\n * i.e. an unchecked assertion on an `unknown`, used to work around a flag the\r\n * platform imposes. Two modules audited (`procuration-portnet-fe`,\r\n * `procuration-fe`) had independently reached for exactly that construct.\r\n * A mandated strict-mode flag with no sanctioned escape hatch produces\r\n * unsanctioned ones.\r\n *\r\n * Implementation notes\r\n * --------------------\r\n * `readPath` walks nested objects using the `in` operator, which narrows without\r\n * an assertion, and `Reflect.get`, which returns the value as `unknown` rather\r\n * than widening anything to `any`. No assertion appears anywhere in this file.\r\n *\r\n * Deliberately DUCK-TYPED rather than built on `axios.isAxiosError`. Three\r\n * reasons: this library must not take a hard axios dependency for a string\r\n * helper; a plain object shaped like an axios error (a hand-rolled reject, a\r\n * test double, a non-axios transport) still resolves correctly; and the check\r\n * stays valid across axios majors.\r\n * ─────────────────────────────────────────────────────────────────────────────\r\n *\r\n * getApiErrorMessage(err) → backend message, or the default\r\n * getApiErrorMessage(err, \"Échec de l'envoi.\") → custom fallback\r\n * getApiErrorStatus(err) → 404 | undefined\r\n *\r\n * Envelope keys read, in order: `data.body`, `data.message`, `data.error`.\r\n * Three keys because three PORTNET back-ends chose differently; see the\r\n * resolution-order note on `getApiErrorMessage` before adding a fourth.\r\n */\r\n\r\n/**\r\n * Default user-facing fallback. French per Charter §09 (voice, vouvoiement) and\r\n * §09.3 (no raw technical detail — never \"Erreur 422 Unprocessable Entity\").\r\n * Override per call site when a screen can say something more useful.\r\n */\r\nexport const DEFAULT_API_ERROR_MESSAGE =\r\n \"Une erreur est survenue. Veuillez réessayer.\";\r\n\r\n/**\r\n * Walk `path` through nested non-null objects, returning the value at the end,\r\n * or `undefined` if any hop is missing. Assertion-free.\r\n */\r\nconst readPath = (source: unknown, path: readonly string[]): unknown => {\r\n let current: unknown = source;\r\n\r\n for (const key of path) {\r\n if (typeof current !== \"object\" || current === null || !(key in current)) {\r\n return undefined;\r\n }\r\n current = Reflect.get(current, key);\r\n }\r\n\r\n return current;\r\n};\r\n\r\nconst asNonEmptyString = (value: unknown): string | undefined =>\r\n typeof value === \"string\" && value.length > 0 ? value : undefined;\r\n\r\n/**\r\n * Transport-layer phrasings that must NEVER reach a user — capability gap G-07.\r\n *\r\n * ──────────────────────────────────────────────────────────────────────\r\n * THE DEFECT THIS FIXES\r\n *\r\n * `getApiErrorMessage` resolved `error.message` BEFORE its fallback. An\r\n * `AxiosError` always has `.message`, so on any server error carrying no\r\n * `response.data.message` — a 500 with an empty body, a gateway error, a\r\n * timeout — step 3 won and the user was shown:\r\n *\r\n * \"Request failed with status code 500\"\r\n *\r\n * English, technical, and precisely the shape Charter §09.3 names as forbidden\r\n * (\"✗ « Erreur 422 — Unprocessable Entity »\"). Worse, it made every consuming\r\n * module's carefully-written French fallback effectively UNREACHABLE — the\r\n * argument was accepted and then almost never used. Found during the\r\n * `procuration-portnet-fe` Area 10 audit, where 12 call sites pass a considered\r\n * fallback that could essentially never render.\r\n *\r\n * WHY A DENY-LIST AND NOT SIMPLY DROPPING STEP 3\r\n *\r\n * Step 3 also carries LEGITIMATE messages: any `throw new Error(\"Ce titre ne\r\n * peut pas être supprimé car il est en cours de validation.\")` in module code\r\n * arrives through exactly the same path. Removing the hop would trade a leak of\r\n * technical strings for the loss of real business messages across the whole\r\n * platform — a worse outcome. So the hop stays and only transport phrasings are\r\n * suppressed.\r\n *\r\n * The list is deliberately CONSERVATIVE: anything not recognised passes through,\r\n * on the assumption a human wrote it. A false negative shows one ugly string; a\r\n * false positive silently replaces a real business message with a generic\r\n * fallback, which is the more damaging error.\r\n *\r\n * Sourced from axios's own message construction (`settle`, `AxiosError` codes\r\n * ECONNABORTED / ETIMEDOUT / ERR_NETWORK / ERR_CANCELED) plus the Node socket\r\n * phrasing that surfaces through SSR and test doubles.\r\n * ──────────────────────────────────────────────────────────────────────\r\n */\r\nconst TRANSPORT_MESSAGE_PATTERNS: readonly RegExp[] = [\r\n /^request failed with status code \\d+$/i,\r\n /^network error$/i,\r\n /^timeout of \\d+ms exceeded$/i,\r\n /^timeout exceeded$/i,\r\n /^request aborted$/i,\r\n /^canceled$/i,\r\n /^unsupported protocol/i,\r\n /^maximum content size exceeded$/i,\r\n /^socket hang up$/i,\r\n /* ── errno codes and axios error codes ── CASE-SENSITIVE, DELIBERATELY ─────\r\n *\r\n * These two are the only patterns here NOT marked `/i`, and the asymmetry is\r\n * load-bearing. errno constants are uppercase by universal convention\r\n * (`ETIMEDOUT`, `ECONNREFUSED`, `ENOTFOUND`, `EPIPE`), so an uppercase-only\r\n * match identifies them precisely. Matching case-insensitively would make\r\n * `/^e[a-z]+$/i` swallow ordinary French words beginning with \"e\" — \"erreur\",\r\n * \"expiré\", \"échec\" — turning a real business message into a generic fallback,\r\n * which is the more damaging failure this list is tuned against.\r\n *\r\n * ⚠ An earlier version of the first pattern was `/^ec[a-z]+$/i`, which matched\r\n * `ECONNREFUSED` (it begins \"EC\") but silently MISSED `ETIMEDOUT` (\"ET\"),\r\n * despite the comment claiming otherwise. The unit test caught it. Do not\r\n * narrow the prefix again: the family is \"E + uppercase word\", not \"EC...\".\r\n *\r\n * Residual, accepted: an all-caps single word like \"ERREUR\" is treated as an\r\n * errno code. A module should not be throwing all-caps single-word messages at\r\n * users, and replacing one with a proper French fallback is an improvement. */\r\n /^E[A-Z]{3,}$/, // errno: ETIMEDOUT, ECONNREFUSED, ECONNRESET, ENOTFOUND, EPIPE\r\n /^ERR_[A-Z_]+$/, // axios: ERR_NETWORK, ERR_CANCELED, ERR_BAD_RESPONSE\r\n];\r\n\r\n/** Is this string an axios/transport artefact rather than something for a user? */\r\nconst isTransportMessage = (value: string): boolean =>\r\n TRANSPORT_MESSAGE_PATTERNS.some((pattern) => pattern.test(value.trim()));\r\n\r\n/**\r\n * `error.message`, but only when it is fit to show a user.\r\n *\r\n * Suppresses transport phrasings (G-07) so the caller's French fallback is\r\n * reached instead. Module-thrown `Error` messages pass through untouched.\r\n */\r\nconst asUserFacingMessage = (value: unknown): string | undefined => {\r\n const text = asNonEmptyString(value);\r\n if (text === undefined) return undefined;\r\n return isTransportMessage(text) ? undefined : text;\r\n};\r\n\r\n/**\r\n * Best available human-readable message for a rejection of unknown shape.\r\n *\r\n * Resolution order, first match wins:\r\n * 1. the rejection itself, when it is a non-empty string;\r\n * 2. `error.response.data.body` — the SAME envelope's third key;\r\n * 3. `error.response.data.message` — the backend's own message;\r\n * 4. `error.response.data.error` — the SAME envelope's alternate key;\r\n * 5. `error.message` — **only when it is not a transport artefact** (G-07);\r\n * 6. `fallback`.\r\n *\r\n * Step 4 closes capability gap G-08. Several PORTNET back-ends populate\r\n * `data.error` rather than `data.message` (addpe-fe declares BOTH on its\r\n * `ApiErrorBody` and read both at seven call sites), so a helper that stopped at\r\n * `data.message` skipped a real business message and fell through to the generic\r\n * fallback — which made it non-substitutable for the module-local extractors it\r\n * exists to replace. Strictly additive: what step 4 now catches previously\r\n * reached step 5 or 6.\r\n *\r\n * Step 2 closes G-08bis — the same defect, a third key. `caution-ui`'s axios\r\n * interceptor reads `error.response.data.body ?? error.response.data.message`,\r\n * so on that back-end a helper stopping at `message` again skipped a real\r\n * business message. Without step 2 the helper was non-substitutable there and\r\n * the module would have had to keep its own assertion-based extractor.\r\n *\r\n * WHY STEP 2 SITS BEFORE `message` AND NOT AFTER `error`.\r\n * `caution-ui` uses `??`, which is direct evidence that a single response can\r\n * carry both keys and that `body` is the one that back-end means. Appending\r\n * `body` at the end of the envelope hops would therefore have SILENTLY FLIPPED\r\n * which message its users see. Placing it first preserves that precedence, and\r\n * is provably a no-op for every module that does not populate `body`: `readPath`\r\n * returns `undefined` and resolution falls straight through to `message`.\r\n *\r\n * The one case this perturbs is a back-end that populates BOTH `body` and\r\n * `message` while intending `message` to win. No such module exists in the\r\n * portfolio — addpe-fe's `ApiErrorBody` declares `message` and `error`, not\r\n * `body` — and a module in that position should say so here rather than have the\r\n * order guessed for it.\r\n *\r\n * Step 5 is filtered: `\"Request failed with status code 500\"`, `\"Network Error\"`,\r\n * timeouts and errno codes are SUPPRESSED so the caller's own French copy is\r\n * used instead (Charter §09.3 — no raw technical detail). A message a module\r\n * threw deliberately still passes through. Use `getApiErrorDetail` when you want\r\n * the unfiltered string for a log.\r\n *\r\n * Never throws and never returns an empty string, so it is safe to render\r\n * directly into a toast or a `Banner`.\r\n *\r\n * @param error The caught value. `unknown` by design.\r\n * @param fallback Message when nothing usable is found.\r\n */\r\nexport function getApiErrorMessage(\r\n error: unknown,\r\n fallback: string = DEFAULT_API_ERROR_MESSAGE\r\n): string {\r\n if (typeof error === \"string\" && error.length > 0) return error;\r\n\r\n return (\r\n asNonEmptyString(readPath(error, [\"response\", \"data\", \"body\"])) ??\r\n asNonEmptyString(readPath(error, [\"response\", \"data\", \"message\"])) ??\r\n asNonEmptyString(readPath(error, [\"response\", \"data\", \"error\"])) ??\r\n asUserFacingMessage(readPath(error, [\"message\"])) ??\r\n fallback\r\n );\r\n}\r\n\r\n/**\r\n * Unfiltered technical detail for LOGGING — never for display.\r\n *\r\n * `getApiErrorMessage` deliberately suppresses transport phrasings (G-07), which\r\n * is right for a toast and wrong for a console or an APM breadcrumb, where\r\n * `\"Request failed with status code 502\"` is exactly what an operator needs. This\r\n * is the escape hatch: it returns the raw `error.message` when there is one,\r\n * whatever its shape.\r\n *\r\n * Pair them:\r\n *\r\n * toast(getApiErrorMessage(err, \"Échec de l'envoi.\"), \"error\");\r\n * console.error(\"[submit]\", getApiErrorStatus(err), getApiErrorDetail(err));\r\n */\r\nexport function getApiErrorDetail(error: unknown): string | undefined {\r\n if (typeof error === \"string\" && error.length > 0) return error;\r\n return asNonEmptyString(readPath(error, [\"message\"]));\r\n}\r\n\r\n/**\r\n * HTTP status carried by a rejection, when there is one.\r\n *\r\n * Resolution order, first numeric match wins:\r\n * 1. `error.response.data.status` — a BODY-level status;\r\n * 2. `error.response.status` — the transport status.\r\n *\r\n * Returns `undefined` for a network drop, a timeout, or any non-HTTP rejection —\r\n * which is the signal callers use to distinguish \"the server answered with an\r\n * error\" from \"there was no answer at all\" (Charter R-4.3: a status-less failure\r\n * is a network banner, not a toast).\r\n *\r\n * Step 1 closes G-08ter, the status-side counterpart of the envelope-key gaps\r\n * G-08 / G-08bis. Several PORTNET back-ends put the meaningful status in the\r\n * BODY: caution-ui's axios interceptor reads\r\n * `error.response.data.status ?? error.response.status` and routes on the\r\n * result (404 -> not-found page, 500 -> server-error page, 401 -> re-login), and\r\n * its RESPONSE interceptor does the same for success handling. A helper reading\r\n * only the transport status was therefore not substitutable there — the module\r\n * had to keep a hand-written `HttpErrorLike` interface and assert onto it, which\r\n * is exactly the anti-pattern G-04 exists to end. Closing the message side\r\n * (G-08bis) without the status side would have left that assertion in place for\r\n * the sake of one field.\r\n *\r\n * Body-first ordering mirrors the module's own `??` and is provably a no-op for\r\n * every back-end that does not populate `data.status`: `readPath` returns\r\n * `undefined` and resolution falls through to the transport status.\r\n *\r\n * BOTH hops are numeric-guarded, which is a deliberate tightening over the\r\n * module code being replaced. That code did `String(status)` on whatever it\r\n * found, so a body carrying `status: \"ERROR\"` produced a `String` switch miss\r\n * and fell to the default toast branch; here a non-numeric `data.status` is\r\n * ignored and the real transport status is used instead. That is the more useful\r\n * answer, and it keeps the return type honest — the signature promises a number.\r\n */\r\nexport function getApiErrorStatus(error: unknown): number | undefined {\r\n const bodyStatus = readPath(error, [\"response\", \"data\", \"status\"]);\r\n if (typeof bodyStatus === \"number\") return bodyStatus;\r\n\r\n const status = readPath(error, [\"response\", \"status\"]);\r\n return typeof status === \"number\" ? status : undefined;\r\n}\r\n"],"mappings":";;;;;;;;;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACO,MAAMA,yBAAyB,GAAAC,OAAA,CAAAD,yBAAA,GACpC,8CAA8C;;AAEhD;AACA;AACA;AACA;AACA,MAAME,QAAQ,GAAGA,CAACC,MAAe,EAAEC,IAAuB,KAAc;EACtE,IAAIC,OAAgB,GAAGF,MAAM;EAE7B,KAAK,MAAMG,GAAG,IAAIF,IAAI,EAAE;IACtB,IAAI,OAAOC,OAAO,KAAK,QAAQ,IAAIA,OAAO,KAAK,IAAI,IAAI,EAAEC,GAAG,IAAID,OAAO,CAAC,EAAE;MACxE,OAAOE,SAAS;IAClB;IACAF,OAAO,GAAGG,OAAO,CAACC,GAAG,CAACJ,OAAO,EAAEC,GAAG,CAAC;EACrC;EAEA,OAAOD,OAAO;AAChB,CAAC;AAED,MAAMK,gBAAgB,GAAIC,KAAc,IACtC,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACC,MAAM,GAAG,CAAC,GAAGD,KAAK,GAAGJ,SAAS;;AAEnE;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,MAAMM,0BAA6C,GAAG,CACpD,wCAAwC,EACxC,kBAAkB,EAClB,8BAA8B,EAC9B,qBAAqB,EACrB,oBAAoB,EACpB,aAAa,EACb,wBAAwB,EACxB,kCAAkC,EAClC,mBAAmB;AACnB;AACF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACE,cAAc;AAAE;AAChB,eAAe,CAAE;AAAA,CAClB;;AAED;AACA,MAAMC,kBAAkB,GAAIH,KAAa,IACvCE,0BAA0B,CAACE,IAAI,CAAEC,OAAO,IAAKA,OAAO,CAACC,IAAI,CAACN,KAAK,CAACO,IAAI,CAAC,CAAC,CAAC,CAAC;;AAE1E;AACA;AACA;AACA;AACA;AACA;AACA,MAAMC,mBAAmB,GAAIR,KAAc,IAAyB;EAClE,MAAMS,IAAI,GAAGV,gBAAgB,CAACC,KAAK,CAAC;EACpC,IAAIS,IAAI,KAAKb,SAAS,EAAE,OAAOA,SAAS;EACxC,OAAOO,kBAAkB,CAACM,IAAI,CAAC,GAAGb,SAAS,GAAGa,IAAI;AACpD,CAAC;;AAED;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,kBAAkBA,CAChCC,KAAc,EACdC,QAAgB,GAAGvB,yBAAyB,EACpC;EACR,IAAI,OAAOsB,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACV,MAAM,GAAG,CAAC,EAAE,OAAOU,KAAK;EAE/D,OACEZ,gBAAgB,CAACR,QAAQ,CAACoB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC,IAC/DZ,gBAAgB,CAACR,QAAQ,CAACoB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,IAClEZ,gBAAgB,CAACR,QAAQ,CAACoB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,IAChEH,mBAAmB,CAACjB,QAAQ,CAACoB,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC,IACjDC,QAAQ;AAEZ;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASC,iBAAiBA,CAACF,KAAc,EAAsB;EACpE,IAAI,OAAOA,KAAK,KAAK,QAAQ,IAAIA,KAAK,CAACV,MAAM,GAAG,CAAC,EAAE,OAAOU,KAAK;EAC/D,OAAOZ,gBAAgB,CAACR,QAAQ,CAACoB,KAAK,EAAE,CAAC,SAAS,CAAC,CAAC,CAAC;AACvD;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASG,iBAAiBA,CAACH,KAAc,EAAsB;EACpE,MAAMI,UAAU,GAAGxB,QAAQ,CAACoB,KAAK,EAAE,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC;EAClE,IAAI,OAAOI,UAAU,KAAK,QAAQ,EAAE,OAAOA,UAAU;EAErD,MAAMC,MAAM,GAAGzB,QAAQ,CAACoB,KAAK,EAAE,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;EACtD,OAAO,OAAOK,MAAM,KAAK,QAAQ,GAAGA,MAAM,GAAGpB,SAAS;AACxD","ignoreList":[]}
@@ -8,7 +8,6 @@ exports.contrastRatio = contrastRatio;
8
8
  exports.parseColor = parseColor;
9
9
  exports.passesContrast = passesContrast;
10
10
  exports.relativeLuminance = relativeLuminance;
11
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
12
11
  /**
13
12
  * WCAG 2.1 contrast utilities — Portnet UI v2
14
13
  *
@@ -27,13 +26,13 @@ function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" =
27
26
  /* ── WCAG AA thresholds (exported for caller readability) ──────── */
28
27
 
29
28
  /** Normal text contrast ratio threshold (AA). */
30
- var WCAG_AA_NORMAL = exports.WCAG_AA_NORMAL = 4.5;
29
+ const WCAG_AA_NORMAL = exports.WCAG_AA_NORMAL = 4.5;
31
30
 
32
31
  /** Large text (≥ 18pt or ≥ 14pt bold) contrast ratio threshold (AA). */
33
- var WCAG_AA_LARGE = exports.WCAG_AA_LARGE = 3.0;
32
+ const WCAG_AA_LARGE = exports.WCAG_AA_LARGE = 3.0;
34
33
 
35
34
  /** UI components & graphical objects contrast ratio threshold (AA 1.4.11). */
36
- var WCAG_AA_UI_NON_TEXT = exports.WCAG_AA_UI_NON_TEXT = 3.0;
35
+ const WCAG_AA_UI_NON_TEXT = exports.WCAG_AA_UI_NON_TEXT = 3.0;
37
36
 
38
37
  /* ── Color parsing ───────────────────────── */
39
38
 
@@ -55,11 +54,11 @@ var WCAG_AA_UI_NON_TEXT = exports.WCAG_AA_UI_NON_TEXT = 3.0;
55
54
  */
56
55
  function parseColor(input) {
57
56
  if (typeof input !== "string") return null;
58
- var s = input.trim();
57
+ const s = input.trim();
59
58
 
60
59
  // Hex (3, 6, or 8 digits; alpha dropped if present)
61
- var hexMatch = s.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/);
62
- var hex = hexMatch === null || hexMatch === void 0 ? void 0 : hexMatch[1];
60
+ const hexMatch = s.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/);
61
+ const hex = hexMatch?.[1];
63
62
  if (hex) {
64
63
  if (hex.length === 3) {
65
64
  return {
@@ -77,17 +76,16 @@ function parseColor(input) {
77
76
  }
78
77
 
79
78
  // rgb() / rgba() — alpha dropped
80
- var rgbMatch = s.match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})/);
79
+ const rgbMatch = s.match(/^rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})/);
81
80
  if (rgbMatch) {
82
- var _rgbMatch$, _rgbMatch$2, _rgbMatch$3;
83
- var r = parseInt((_rgbMatch$ = rgbMatch[1]) !== null && _rgbMatch$ !== void 0 ? _rgbMatch$ : "", 10);
84
- var g = parseInt((_rgbMatch$2 = rgbMatch[2]) !== null && _rgbMatch$2 !== void 0 ? _rgbMatch$2 : "", 10);
85
- var b = parseInt((_rgbMatch$3 = rgbMatch[3]) !== null && _rgbMatch$3 !== void 0 ? _rgbMatch$3 : "", 10);
81
+ const r = parseInt(rgbMatch[1] ?? "", 10);
82
+ const g = parseInt(rgbMatch[2] ?? "", 10);
83
+ const b = parseInt(rgbMatch[3] ?? "", 10);
86
84
  if (Number.isFinite(r) && r >= 0 && r <= 255 && Number.isFinite(g) && g >= 0 && g <= 255 && Number.isFinite(b) && b >= 0 && b <= 255) {
87
85
  return {
88
- r: r,
89
- g: g,
90
- b: b
86
+ r,
87
+ g,
88
+ b
91
89
  };
92
90
  }
93
91
  }
@@ -98,7 +96,7 @@ function parseColor(input) {
98
96
 
99
97
  /** sRGB channel → linear-light conversion per WCAG 2.1. */
100
98
  function srgbChannelToLinear(c) {
101
- var cs = c / 255;
99
+ const cs = c / 255;
102
100
  return cs <= 0.03928 ? cs / 12.92 : Math.pow((cs + 0.055) / 1.055, 2.4);
103
101
  }
104
102
 
@@ -108,14 +106,16 @@ function srgbChannelToLinear(c) {
108
106
  * Returns a number in 0..1, or null if input is invalid.
109
107
  */
110
108
  function relativeLuminance(rgb) {
111
- if (!rgb || _typeof(rgb) !== "object") return null;
112
- var r = rgb.r,
113
- g = rgb.g,
114
- b = rgb.b;
109
+ if (!rgb || typeof rgb !== "object") return null;
110
+ const {
111
+ r,
112
+ g,
113
+ b
114
+ } = rgb;
115
115
  if (!Number.isFinite(r) || !Number.isFinite(g) || !Number.isFinite(b)) return null;
116
- var R = srgbChannelToLinear(r);
117
- var G = srgbChannelToLinear(g);
118
- var B = srgbChannelToLinear(b);
116
+ const R = srgbChannelToLinear(r);
117
+ const G = srgbChannelToLinear(g);
118
+ const B = srgbChannelToLinear(b);
119
119
  return 0.2126 * R + 0.7152 * G + 0.0722 * B;
120
120
  }
121
121
 
@@ -127,13 +127,13 @@ function relativeLuminance(rgb) {
127
127
  * [1.0, 21.0], or null if either input is unparseable.
128
128
  */
129
129
  function contrastRatio(c1, c2) {
130
- var rgb1 = typeof c1 === "string" ? parseColor(c1) : c1;
131
- var rgb2 = typeof c2 === "string" ? parseColor(c2) : c2;
132
- var L1 = relativeLuminance(rgb1);
133
- var L2 = relativeLuminance(rgb2);
130
+ const rgb1 = typeof c1 === "string" ? parseColor(c1) : c1;
131
+ const rgb2 = typeof c2 === "string" ? parseColor(c2) : c2;
132
+ const L1 = relativeLuminance(rgb1);
133
+ const L2 = relativeLuminance(rgb2);
134
134
  if (L1 == null || L2 == null) return null;
135
- var lighter = Math.max(L1, L2);
136
- var darker = Math.min(L1, L2);
135
+ const lighter = Math.max(L1, L2);
136
+ const darker = Math.min(L1, L2);
137
137
  return (lighter + 0.05) / (darker + 0.05);
138
138
  }
139
139
 
@@ -146,10 +146,9 @@ function contrastRatio(c1, c2) {
146
146
  * `level` accepts "normal" | "large" | "ui". Unknown levels default
147
147
  * to the strictest threshold.
148
148
  */
149
- function passesContrast(ratio) {
150
- var level = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : "normal";
149
+ function passesContrast(ratio, level = "normal") {
151
150
  if (ratio == null || !Number.isFinite(ratio)) return false;
152
- var threshold;
151
+ let threshold;
153
152
  switch (level) {
154
153
  case "large":
155
154
  threshold = WCAG_AA_LARGE;
@@ -1 +1 @@
1
- {"version":3,"file":"contrast.js","names":["WCAG_AA_NORMAL","exports","WCAG_AA_LARGE","WCAG_AA_UI_NON_TEXT","parseColor","input","s","trim","hexMatch","match","hex","length","r","parseInt","charAt","g","b","slice","rgbMatch","_rgbMatch$","_rgbMatch$2","_rgbMatch$3","Number","isFinite","srgbChannelToLinear","c","cs","Math","pow","relativeLuminance","rgb","_typeof","R","G","B","contrastRatio","c1","c2","rgb1","rgb2","L1","L2","lighter","max","darker","min","passesContrast","ratio","level","arguments","undefined","threshold"],"sources":["../../../src/lib/v2/utils/contrast.ts"],"sourcesContent":["/**\r\n * WCAG 2.1 contrast utilities — Portnet UI v2\r\n *\r\n * Reference: https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio\r\n *\r\n * Pure functions, framework-agnostic, no deps. Reusable by any\r\n * host module that needs to validate a runtime brand override\r\n * against WCAG 1.4.3 AA (typical scenario: a host-shell event\r\n * injects a tenant brand and the consumer wants to dev-warn when\r\n * the resulting accent/foreground pair drops below 4.5:1).\r\n *\r\n * Also used by the dark-mode work (F29) to audit dual-mode token\r\n * pairs and by Storybook contrast stories.\r\n */\r\n\r\n/* ── WCAG AA thresholds (exported for caller readability) ──────── */\r\n\r\n/** Normal text contrast ratio threshold (AA). */\r\nexport const WCAG_AA_NORMAL = 4.5;\r\n\r\n/** Large text (≥ 18pt or ≥ 14pt bold) contrast ratio threshold (AA). */\r\nexport const WCAG_AA_LARGE = 3.0;\r\n\r\n/** UI components & graphical objects contrast ratio threshold (AA 1.4.11). */\r\nexport const WCAG_AA_UI_NON_TEXT = 3.0;\r\n\r\n/* ── Color parsing ───────────────────────── */\r\n\r\ntype RGB = { r: number; g: number; b: number };\r\n\r\n/**\r\n * Parse a CSS color string into an { r, g, b } object with 0..255\r\n * channels. Returns null for unparseable input.\r\n *\r\n * Supported formats:\r\n * - \"#RGB\" (3-digit hex shorthand)\r\n * - \"#RRGGBB\" (6-digit hex)\r\n * - \"#RRGGBBAA\" (8-digit hex; alpha channel is dropped)\r\n * - \"rgb(r, g, b)\"\r\n * - \"rgba(r, g, b, a)\" (alpha dropped)\r\n *\r\n * HSL / HWB / LAB / named-colors are NOT supported — the v2 token\r\n * surface and observed host-shell brand payloads are always hex\r\n * or rgb(). A wider parser can be swapped in later without\r\n * changing the public API of this function.\r\n */\r\nexport function parseColor(input: unknown): RGB | null {\r\n if (typeof input !== \"string\") return null;\r\n const s = input.trim();\r\n\r\n // Hex (3, 6, or 8 digits; alpha dropped if present)\r\n const hexMatch = s.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/);\r\n const hex = hexMatch?.[1];\r\n if (hex) {\r\n if (hex.length === 3) {\r\n return {\r\n r: parseInt(hex.charAt(0) + hex.charAt(0), 16),\r\n g: parseInt(hex.charAt(1) + hex.charAt(1), 16),\r\n b: parseInt(hex.charAt(2) + hex.charAt(2), 16),\r\n };\r\n }\r\n // 6 or 8 digit — first 6 chars are RGB\r\n return {\r\n r: parseInt(hex.slice(0, 2), 16),\r\n g: parseInt(hex.slice(2, 4), 16),\r\n b: parseInt(hex.slice(4, 6), 16),\r\n };\r\n }\r\n\r\n // rgb() / rgba() — alpha dropped\r\n const rgbMatch = s.match(\r\n /^rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})/\r\n );\r\n if (rgbMatch) {\r\n const r = parseInt(rgbMatch[1] ?? \"\", 10);\r\n const g = parseInt(rgbMatch[2] ?? \"\", 10);\r\n const b = parseInt(rgbMatch[3] ?? \"\", 10);\r\n if (\r\n Number.isFinite(r) && r >= 0 && r <= 255 &&\r\n Number.isFinite(g) && g >= 0 && g <= 255 &&\r\n Number.isFinite(b) && b >= 0 && b <= 255\r\n ) {\r\n return { r, g, b };\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/* ── Luminance & ratio ───────────────────── */\r\n\r\n/** sRGB channel → linear-light conversion per WCAG 2.1. */\r\nfunction srgbChannelToLinear(c: number): number {\r\n const cs = c / 255;\r\n return cs <= 0.03928 ? cs / 12.92 : Math.pow((cs + 0.055) / 1.055, 2.4);\r\n}\r\n\r\n/**\r\n * Compute relative luminance of an sRGB color per WCAG 2.1.\r\n * Accepts an { r, g, b } object (channels in 0..255).\r\n * Returns a number in 0..1, or null if input is invalid.\r\n */\r\nexport function relativeLuminance(rgb: RGB | null | undefined): number | null {\r\n if (!rgb || typeof rgb !== \"object\") return null;\r\n const { r, g, b } = rgb;\r\n if (\r\n !Number.isFinite(r) || !Number.isFinite(g) || !Number.isFinite(b)\r\n ) return null;\r\n const R = srgbChannelToLinear(r);\r\n const G = srgbChannelToLinear(g);\r\n const B = srgbChannelToLinear(b);\r\n return 0.2126 * R + 0.7152 * G + 0.0722 * B;\r\n}\r\n\r\n/**\r\n * WCAG contrast ratio between two colors.\r\n *\r\n * Accepts either CSS color strings (parsed via parseColor) or\r\n * already-parsed { r, g, b } objects. Returns a number in\r\n * [1.0, 21.0], or null if either input is unparseable.\r\n */\r\nexport function contrastRatio(\r\n c1: string | RGB,\r\n c2: string | RGB\r\n): number | null {\r\n const rgb1 = typeof c1 === \"string\" ? parseColor(c1) : c1;\r\n const rgb2 = typeof c2 === \"string\" ? parseColor(c2) : c2;\r\n const L1 = relativeLuminance(rgb1);\r\n const L2 = relativeLuminance(rgb2);\r\n if (L1 == null || L2 == null) return null;\r\n const lighter = Math.max(L1, L2);\r\n const darker = Math.min(L1, L2);\r\n return (lighter + 0.05) / (darker + 0.05);\r\n}\r\n\r\n/**\r\n * Verdict helper — `passesContrast(ratio, \"normal\")` returns true\r\n * if the ratio meets the requested WCAG AA threshold. Returns\r\n * false on null ratios so callers can treat unparseable inputs as\r\n * failures.\r\n *\r\n * `level` accepts \"normal\" | \"large\" | \"ui\". Unknown levels default\r\n * to the strictest threshold.\r\n */\r\nexport function passesContrast(\r\n ratio: number | null | undefined,\r\n level: \"normal\" | \"large\" | \"ui\" = \"normal\"\r\n): boolean {\r\n if (ratio == null || !Number.isFinite(ratio)) return false;\r\n let threshold: number;\r\n switch (level) {\r\n case \"large\":\r\n threshold = WCAG_AA_LARGE;\r\n break;\r\n case \"ui\":\r\n threshold = WCAG_AA_UI_NON_TEXT;\r\n break;\r\n case \"normal\":\r\n default:\r\n threshold = WCAG_AA_NORMAL;\r\n break;\r\n }\r\n return ratio >= threshold;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"contrast.js","names":["WCAG_AA_NORMAL","exports","WCAG_AA_LARGE","WCAG_AA_UI_NON_TEXT","parseColor","input","s","trim","hexMatch","match","hex","length","r","parseInt","charAt","g","b","slice","rgbMatch","Number","isFinite","srgbChannelToLinear","c","cs","Math","pow","relativeLuminance","rgb","R","G","B","contrastRatio","c1","c2","rgb1","rgb2","L1","L2","lighter","max","darker","min","passesContrast","ratio","level","threshold"],"sources":["../../../src/lib/v2/utils/contrast.ts"],"sourcesContent":["/**\r\n * WCAG 2.1 contrast utilities — Portnet UI v2\r\n *\r\n * Reference: https://www.w3.org/TR/WCAG21/#dfn-contrast-ratio\r\n *\r\n * Pure functions, framework-agnostic, no deps. Reusable by any\r\n * host module that needs to validate a runtime brand override\r\n * against WCAG 1.4.3 AA (typical scenario: a host-shell event\r\n * injects a tenant brand and the consumer wants to dev-warn when\r\n * the resulting accent/foreground pair drops below 4.5:1).\r\n *\r\n * Also used by the dark-mode work (F29) to audit dual-mode token\r\n * pairs and by Storybook contrast stories.\r\n */\r\n\r\n/* ── WCAG AA thresholds (exported for caller readability) ──────── */\r\n\r\n/** Normal text contrast ratio threshold (AA). */\r\nexport const WCAG_AA_NORMAL = 4.5;\r\n\r\n/** Large text (≥ 18pt or ≥ 14pt bold) contrast ratio threshold (AA). */\r\nexport const WCAG_AA_LARGE = 3.0;\r\n\r\n/** UI components & graphical objects contrast ratio threshold (AA 1.4.11). */\r\nexport const WCAG_AA_UI_NON_TEXT = 3.0;\r\n\r\n/* ── Color parsing ───────────────────────── */\r\n\r\ntype RGB = { r: number; g: number; b: number };\r\n\r\n/**\r\n * Parse a CSS color string into an { r, g, b } object with 0..255\r\n * channels. Returns null for unparseable input.\r\n *\r\n * Supported formats:\r\n * - \"#RGB\" (3-digit hex shorthand)\r\n * - \"#RRGGBB\" (6-digit hex)\r\n * - \"#RRGGBBAA\" (8-digit hex; alpha channel is dropped)\r\n * - \"rgb(r, g, b)\"\r\n * - \"rgba(r, g, b, a)\" (alpha dropped)\r\n *\r\n * HSL / HWB / LAB / named-colors are NOT supported — the v2 token\r\n * surface and observed host-shell brand payloads are always hex\r\n * or rgb(). A wider parser can be swapped in later without\r\n * changing the public API of this function.\r\n */\r\nexport function parseColor(input: unknown): RGB | null {\r\n if (typeof input !== \"string\") return null;\r\n const s = input.trim();\r\n\r\n // Hex (3, 6, or 8 digits; alpha dropped if present)\r\n const hexMatch = s.match(/^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6}|[0-9a-fA-F]{8})$/);\r\n const hex = hexMatch?.[1];\r\n if (hex) {\r\n if (hex.length === 3) {\r\n return {\r\n r: parseInt(hex.charAt(0) + hex.charAt(0), 16),\r\n g: parseInt(hex.charAt(1) + hex.charAt(1), 16),\r\n b: parseInt(hex.charAt(2) + hex.charAt(2), 16),\r\n };\r\n }\r\n // 6 or 8 digit — first 6 chars are RGB\r\n return {\r\n r: parseInt(hex.slice(0, 2), 16),\r\n g: parseInt(hex.slice(2, 4), 16),\r\n b: parseInt(hex.slice(4, 6), 16),\r\n };\r\n }\r\n\r\n // rgb() / rgba() — alpha dropped\r\n const rgbMatch = s.match(\r\n /^rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})/\r\n );\r\n if (rgbMatch) {\r\n const r = parseInt(rgbMatch[1] ?? \"\", 10);\r\n const g = parseInt(rgbMatch[2] ?? \"\", 10);\r\n const b = parseInt(rgbMatch[3] ?? \"\", 10);\r\n if (\r\n Number.isFinite(r) && r >= 0 && r <= 255 &&\r\n Number.isFinite(g) && g >= 0 && g <= 255 &&\r\n Number.isFinite(b) && b >= 0 && b <= 255\r\n ) {\r\n return { r, g, b };\r\n }\r\n }\r\n\r\n return null;\r\n}\r\n\r\n/* ── Luminance & ratio ───────────────────── */\r\n\r\n/** sRGB channel → linear-light conversion per WCAG 2.1. */\r\nfunction srgbChannelToLinear(c: number): number {\r\n const cs = c / 255;\r\n return cs <= 0.03928 ? cs / 12.92 : Math.pow((cs + 0.055) / 1.055, 2.4);\r\n}\r\n\r\n/**\r\n * Compute relative luminance of an sRGB color per WCAG 2.1.\r\n * Accepts an { r, g, b } object (channels in 0..255).\r\n * Returns a number in 0..1, or null if input is invalid.\r\n */\r\nexport function relativeLuminance(rgb: RGB | null | undefined): number | null {\r\n if (!rgb || typeof rgb !== \"object\") return null;\r\n const { r, g, b } = rgb;\r\n if (\r\n !Number.isFinite(r) || !Number.isFinite(g) || !Number.isFinite(b)\r\n ) return null;\r\n const R = srgbChannelToLinear(r);\r\n const G = srgbChannelToLinear(g);\r\n const B = srgbChannelToLinear(b);\r\n return 0.2126 * R + 0.7152 * G + 0.0722 * B;\r\n}\r\n\r\n/**\r\n * WCAG contrast ratio between two colors.\r\n *\r\n * Accepts either CSS color strings (parsed via parseColor) or\r\n * already-parsed { r, g, b } objects. Returns a number in\r\n * [1.0, 21.0], or null if either input is unparseable.\r\n */\r\nexport function contrastRatio(\r\n c1: string | RGB,\r\n c2: string | RGB\r\n): number | null {\r\n const rgb1 = typeof c1 === \"string\" ? parseColor(c1) : c1;\r\n const rgb2 = typeof c2 === \"string\" ? parseColor(c2) : c2;\r\n const L1 = relativeLuminance(rgb1);\r\n const L2 = relativeLuminance(rgb2);\r\n if (L1 == null || L2 == null) return null;\r\n const lighter = Math.max(L1, L2);\r\n const darker = Math.min(L1, L2);\r\n return (lighter + 0.05) / (darker + 0.05);\r\n}\r\n\r\n/**\r\n * Verdict helper — `passesContrast(ratio, \"normal\")` returns true\r\n * if the ratio meets the requested WCAG AA threshold. Returns\r\n * false on null ratios so callers can treat unparseable inputs as\r\n * failures.\r\n *\r\n * `level` accepts \"normal\" | \"large\" | \"ui\". Unknown levels default\r\n * to the strictest threshold.\r\n */\r\nexport function passesContrast(\r\n ratio: number | null | undefined,\r\n level: \"normal\" | \"large\" | \"ui\" = \"normal\"\r\n): boolean {\r\n if (ratio == null || !Number.isFinite(ratio)) return false;\r\n let threshold: number;\r\n switch (level) {\r\n case \"large\":\r\n threshold = WCAG_AA_LARGE;\r\n break;\r\n case \"ui\":\r\n threshold = WCAG_AA_UI_NON_TEXT;\r\n break;\r\n case \"normal\":\r\n default:\r\n threshold = WCAG_AA_NORMAL;\r\n break;\r\n }\r\n return ratio >= threshold;\r\n}\r\n"],"mappings":"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","ignoreList":[]}
@@ -4,42 +4,22 @@ Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
6
  exports.cx = cx;
7
- exports["default"] = void 0;
8
- function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
9
- function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
10
- function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0) { ; } } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i["return"] && (_r = _i["return"](), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
11
- function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
12
- function _typeof(obj) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (obj) { return typeof obj; } : function (obj) { return obj && "function" == typeof Symbol && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }, _typeof(obj); }
13
- function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _unsupportedIterableToArray(arr) || _nonIterableSpread(); }
14
- function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
15
- function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
16
- function _iterableToArray(iter) { if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter); }
17
- function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) return _arrayLikeToArray(arr); }
18
- function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) { arr2[i] = arr[i]; } return arr2; }
7
+ exports.default = void 0;
19
8
  /**
20
9
  * cx — minimal classnames composer
21
10
  *
22
11
  * cx("a", cond && "b", { "c": isC }) → "a b c"
23
12
  */
24
13
 
25
- function cx() {
26
- var out = [];
27
- for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
28
- args[_key] = arguments[_key];
29
- }
30
- for (var _i = 0, _args = args; _i < _args.length; _i++) {
31
- var a = _args[_i];
14
+ function cx(...args) {
15
+ const out = [];
16
+ for (const a of args) {
32
17
  if (!a) continue;
33
- if (typeof a === "string" || typeof a === "number") out.push(String(a));else if (Array.isArray(a)) out.push(cx.apply(void 0, _toConsumableArray(a)));else if (_typeof(a) === "object") {
34
- for (var _i2 = 0, _Object$entries = Object.entries(a); _i2 < _Object$entries.length; _i2++) {
35
- var _Object$entries$_i = _slicedToArray(_Object$entries[_i2], 2),
36
- k = _Object$entries$_i[0],
37
- v = _Object$entries$_i[1];
38
- if (v) out.push(k);
39
- }
18
+ if (typeof a === "string" || typeof a === "number") out.push(String(a));else if (Array.isArray(a)) out.push(cx(...a));else if (typeof a === "object") {
19
+ for (const [k, v] of Object.entries(a)) if (v) out.push(k);
40
20
  }
41
21
  }
42
22
  return out.join(" ");
43
23
  }
44
- var _default = exports["default"] = cx;
24
+ var _default = exports.default = cx;
45
25
  //# sourceMappingURL=cx.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"cx.js","names":["cx","out","_len","arguments","length","args","Array","_key","_i","_args","a","push","String","isArray","apply","_toConsumableArray","_typeof","_i2","_Object$entries","Object","entries","_Object$entries$_i","_slicedToArray","k","v","join","_default","exports"],"sources":["../../../src/lib/v2/utils/cx.ts"],"sourcesContent":["/**\r\n * cx — minimal classnames composer\r\n *\r\n * cx(\"a\", cond && \"b\", { \"c\": isC }) → \"a b c\"\r\n */\r\ntype ClassValue =\r\n | string\r\n | number\r\n | null\r\n | undefined\r\n | boolean\r\n | ClassValue[]\r\n | Record<string, unknown>;\r\n\r\nexport function cx(...args: ClassValue[]): string {\r\n const out: string[] = [];\r\n for (const a of args) {\r\n if (!a) continue;\r\n if (typeof a === \"string\" || typeof a === \"number\") out.push(String(a));\r\n else if (Array.isArray(a)) out.push(cx(...a));\r\n else if (typeof a === \"object\") {\r\n for (const [k, v] of Object.entries(a)) if (v) out.push(k);\r\n }\r\n }\r\n return out.join(\" \");\r\n}\r\n\r\nexport default cx;\r\n"],"mappings":";;;;;;;;;;;;;;;;;;AAAA;AACA;AACA;AACA;AACA;;AAUO,SAASA,EAAEA,CAAA,EAAgC;EAChD,IAAMC,GAAa,GAAG,EAAE;EAAC,SAAAC,IAAA,GAAAC,SAAA,CAAAC,MAAA,EADLC,IAAI,OAAAC,KAAA,CAAAJ,IAAA,GAAAK,IAAA,MAAAA,IAAA,GAAAL,IAAA,EAAAK,IAAA;IAAJF,IAAI,CAAAE,IAAA,IAAAJ,SAAA,CAAAI,IAAA;EAAA;EAExB,SAAAC,EAAA,MAAAC,KAAA,GAAgBJ,IAAI,EAAAG,EAAA,GAAAC,KAAA,CAAAL,MAAA,EAAAI,EAAA,IAAE;IAAjB,IAAME,CAAC,GAAAD,KAAA,CAAAD,EAAA;IACV,IAAI,CAACE,CAAC,EAAE;IACR,IAAI,OAAOA,CAAC,KAAK,QAAQ,IAAI,OAAOA,CAAC,KAAK,QAAQ,EAAET,GAAG,CAACU,IAAI,CAACC,MAAM,CAACF,CAAC,CAAC,CAAC,CAAC,KACnE,IAAIJ,KAAK,CAACO,OAAO,CAACH,CAAC,CAAC,EAAET,GAAG,CAACU,IAAI,CAACX,EAAE,CAAAc,KAAA,SAAAC,kBAAA,CAAIL,CAAC,EAAC,CAAC,CAAC,KACzC,IAAIM,OAAA,CAAON,CAAC,MAAK,QAAQ,EAAE;MAC9B,SAAAO,GAAA,MAAAC,eAAA,GAAqBC,MAAM,CAACC,OAAO,CAACV,CAAC,CAAC,EAAAO,GAAA,GAAAC,eAAA,CAAAd,MAAA,EAAAa,GAAA;QAAjC,IAAAI,kBAAA,GAAAC,cAAA,CAAAJ,eAAA,CAAAD,GAAA;UAAOM,CAAC,GAAAF,kBAAA;UAAEG,CAAC,GAAAH,kBAAA;QAAwB,IAAIG,CAAC,EAAEvB,GAAG,CAACU,IAAI,CAACY,CAAC,CAAC;MAAC;IAC7D;EACF;EACA,OAAOtB,GAAG,CAACwB,IAAI,CAAC,GAAG,CAAC;AACtB;AAAC,IAAAC,QAAA,GAAAC,OAAA,cAEc3B,EAAE","ignoreList":[]}
1
+ {"version":3,"file":"cx.js","names":["cx","args","out","a","push","String","Array","isArray","k","v","Object","entries","join","_default","exports","default"],"sources":["../../../src/lib/v2/utils/cx.ts"],"sourcesContent":["/**\r\n * cx — minimal classnames composer\r\n *\r\n * cx(\"a\", cond && \"b\", { \"c\": isC }) → \"a b c\"\r\n */\r\ntype ClassValue =\r\n | string\r\n | number\r\n | null\r\n | undefined\r\n | boolean\r\n | ClassValue[]\r\n | Record<string, unknown>;\r\n\r\nexport function cx(...args: ClassValue[]): string {\r\n const out: string[] = [];\r\n for (const a of args) {\r\n if (!a) continue;\r\n if (typeof a === \"string\" || typeof a === \"number\") out.push(String(a));\r\n else if (Array.isArray(a)) out.push(cx(...a));\r\n else if (typeof a === \"object\") {\r\n for (const [k, v] of Object.entries(a)) if (v) out.push(k);\r\n }\r\n }\r\n return out.join(\" \");\r\n}\r\n\r\nexport default cx;\r\n"],"mappings":";;;;;;;AAAA;AACA;AACA;AACA;AACA;;AAUO,SAASA,EAAEA,CAAC,GAAGC,IAAkB,EAAU;EAChD,MAAMC,GAAa,GAAG,EAAE;EACxB,KAAK,MAAMC,CAAC,IAAIF,IAAI,EAAE;IACpB,IAAI,CAACE,CAAC,EAAE;IACR,IAAI,OAAOA,CAAC,KAAK,QAAQ,IAAI,OAAOA,CAAC,KAAK,QAAQ,EAAED,GAAG,CAACE,IAAI,CAACC,MAAM,CAACF,CAAC,CAAC,CAAC,CAAC,KACnE,IAAIG,KAAK,CAACC,OAAO,CAACJ,CAAC,CAAC,EAAED,GAAG,CAACE,IAAI,CAACJ,EAAE,CAAC,GAAGG,CAAC,CAAC,CAAC,CAAC,KACzC,IAAI,OAAOA,CAAC,KAAK,QAAQ,EAAE;MAC9B,KAAK,MAAM,CAACK,CAAC,EAAEC,CAAC,CAAC,IAAIC,MAAM,CAACC,OAAO,CAACR,CAAC,CAAC,EAAE,IAAIM,CAAC,EAAEP,GAAG,CAACE,IAAI,CAACI,CAAC,CAAC;IAC5D;EACF;EACA,OAAON,GAAG,CAACU,IAAI,CAAC,GAAG,CAAC;AACtB;AAAC,IAAAC,QAAA,GAAAC,OAAA,CAAAC,OAAA,GAEcf,EAAE","ignoreList":[]}
@@ -3,7 +3,7 @@
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
- exports["default"] = void 0;
6
+ exports.default = void 0;
7
7
  exports.downloadBase64File = downloadBase64File;
8
8
  exports.downloadBlobFile = downloadBlobFile;
9
9
  exports.getMimeType = getMimeType;
@@ -37,7 +37,7 @@ exports.openBase64FileInTab = openBase64FileInTab;
37
37
  * browser download the file rather than attempt to render it — the safe
38
38
  * default for an unknown payload.
39
39
  */
40
- var MIME_TYPES = Object.freeze({
40
+ const MIME_TYPES = Object.freeze({
41
41
  // Documents
42
42
  pdf: "application/pdf",
43
43
  doc: "application/msword",
@@ -66,8 +66,7 @@ var MIME_TYPES = Object.freeze({
66
66
  * @returns The mapped MIME type, or "application/octet-stream".
67
67
  */
68
68
  function getMimeType(extension) {
69
- var _MIME_TYPES$extension;
70
- return (_MIME_TYPES$extension = MIME_TYPES[extension.toLowerCase()]) !== null && _MIME_TYPES$extension !== void 0 ? _MIME_TYPES$extension : "application/octet-stream";
69
+ return MIME_TYPES[extension.toLowerCase()] ?? "application/octet-stream";
71
70
  }
72
71
 
73
72
  /**
@@ -91,15 +90,15 @@ function downloadBase64File(base64Data, fileName, extension) {
91
90
  if (typeof document === "undefined" || typeof atob === "undefined") {
92
91
  return false;
93
92
  }
94
- var url = null;
95
- var link = null;
93
+ let url = null;
94
+ let link = null;
96
95
  try {
97
- var binary = atob(base64Data);
98
- var bytes = new Uint8Array(binary.length);
99
- for (var i = 0; i < binary.length; i += 1) {
96
+ const binary = atob(base64Data);
97
+ const bytes = new Uint8Array(binary.length);
98
+ for (let i = 0; i < binary.length; i += 1) {
100
99
  bytes[i] = binary.charCodeAt(i);
101
100
  }
102
- var blob = new Blob([bytes], {
101
+ const blob = new Blob([bytes], {
103
102
  type: getMimeType(extension)
104
103
  });
105
104
  url = URL.createObjectURL(blob);
@@ -130,7 +129,7 @@ function downloadBase64File(base64Data, fileName, extension) {
130
129
  * revoking early shows the user a blank tab, while being late costs one
131
130
  * short-lived blob.
132
131
  */
133
- var PREVIEW_REVOKE_DELAY_MS = 60000;
132
+ const PREVIEW_REVOKE_DELAY_MS = 60_000;
134
133
 
135
134
  /**
136
135
  * Decode a base64 payload and open it in a new tab for preview.
@@ -160,22 +159,20 @@ function openBase64FileInTab(base64Data, extension) {
160
159
  if (typeof window === "undefined" || typeof atob === "undefined") {
161
160
  return false;
162
161
  }
163
- var url = null;
162
+ let url = null;
164
163
  try {
165
- var binary = atob(base64Data);
166
- var bytes = new Uint8Array(binary.length);
167
- for (var i = 0; i < binary.length; i += 1) {
164
+ const binary = atob(base64Data);
165
+ const bytes = new Uint8Array(binary.length);
166
+ for (let i = 0; i < binary.length; i += 1) {
168
167
  bytes[i] = binary.charCodeAt(i);
169
168
  }
170
- var blob = new Blob([bytes], {
169
+ const blob = new Blob([bytes], {
171
170
  type: getMimeType(extension)
172
171
  });
173
172
  url = URL.createObjectURL(blob);
174
173
  window.open(url, "_blank", "noopener,noreferrer");
175
- var revokeTarget = url;
176
- window.setTimeout(function () {
177
- return URL.revokeObjectURL(revokeTarget);
178
- }, PREVIEW_REVOKE_DELAY_MS);
174
+ const revokeTarget = url;
175
+ window.setTimeout(() => URL.revokeObjectURL(revokeTarget), PREVIEW_REVOKE_DELAY_MS);
179
176
  return true;
180
177
  } catch (error) {
181
178
  // Revoke straight away here: nothing consumed the URL on this path.
@@ -207,8 +204,8 @@ function downloadBlobFile(blob, fileName) {
207
204
  if (typeof document === "undefined" || typeof URL === "undefined") {
208
205
  return false;
209
206
  }
210
- var url = null;
211
- var link = null;
207
+ let url = null;
208
+ let link = null;
212
209
  try {
213
210
  url = URL.createObjectURL(blob);
214
211
  link = document.createElement("a");
@@ -226,11 +223,11 @@ function downloadBlobFile(blob, fileName) {
226
223
  if (url) URL.revokeObjectURL(url);
227
224
  }
228
225
  }
229
- var fileDownloadApi = {
230
- getMimeType: getMimeType,
231
- downloadBase64File: downloadBase64File,
232
- openBase64FileInTab: openBase64FileInTab,
233
- downloadBlobFile: downloadBlobFile
226
+ const fileDownloadApi = {
227
+ getMimeType,
228
+ downloadBase64File,
229
+ openBase64FileInTab,
230
+ downloadBlobFile
234
231
  };
235
- var _default = exports["default"] = fileDownloadApi;
232
+ var _default = exports.default = fileDownloadApi;
236
233
  //# sourceMappingURL=fileDownload.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"fileDownload.js","names":["MIME_TYPES","Object","freeze","pdf","doc","docx","xls","xlsx","csv","txt","png","jpg","jpeg","gif","bmp","webp","svg","ico","tiff","tif","getMimeType","extension","_MIME_TYPES$extension","toLowerCase","downloadBase64File","base64Data","fileName","document","atob","url","link","binary","bytes","Uint8Array","length","i","charCodeAt","blob","Blob","type","URL","createObjectURL","createElement","href","download","body","appendChild","click","error","console","parentNode","removeChild","revokeObjectURL","PREVIEW_REVOKE_DELAY_MS","openBase64FileInTab","window","open","revokeTarget","setTimeout","downloadBlobFile","fileDownloadApi","_default","exports"],"sources":["../../../src/lib/v2/utils/fileDownload.ts"],"sourcesContent":["/**\r\n * File download utilities — Portnet UI v2\r\n *\r\n * Turns a base64 payload from the API into a browser download. Every GU\r\n * module that lets a user retrieve an attached document needs this, and\r\n * before this file each one carried its own copy of the same\r\n * atob → Uint8Array → Blob → anchor sequence plus its own MIME map.\r\n *\r\n * DEPENDENCY-FREE ON PURPOSE. Multi-file (zip) bundling is deliberately NOT\r\n * here: it needs a zip library, and making that a hard dependency of the\r\n * design system would put it in every module's bundle against the\r\n * R-8.2 budget (180 KB gz initial JS) for a capability only\r\n * document-heavy modules use. If it is promoted later it belongs behind an\r\n * OPTIONAL peer dependency, the way PdfViewer sits behind pdfjs-dist and\r\n * @react-pdf-viewer/* in peerDependenciesMeta.\r\n *\r\n * Charter ref: §09.3 — the caller owns the user-facing message; these\r\n * return a boolean rather than throwing so a failure surfaces as copy\r\n * (R-4.4) instead of an unhandled rejection.\r\n */\r\n\r\n/**\r\n * Extension → MIME type for the formats the platform accepts as\r\n * attachments.\r\n *\r\n * Anything unmapped resolves to application/octet-stream, which makes the\r\n * browser download the file rather than attempt to render it — the safe\r\n * default for an unknown payload.\r\n */\r\nconst MIME_TYPES: Readonly<Record<string, string>> = Object.freeze({\r\n // Documents\r\n pdf: \"application/pdf\",\r\n doc: \"application/msword\",\r\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\r\n xls: \"application/vnd.ms-excel\",\r\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\r\n csv: \"text/csv\",\r\n txt: \"text/plain\",\r\n\r\n // Images\r\n png: \"image/png\",\r\n jpg: \"image/jpeg\",\r\n jpeg: \"image/jpeg\",\r\n gif: \"image/gif\",\r\n bmp: \"image/bmp\",\r\n webp: \"image/webp\",\r\n svg: \"image/svg+xml\",\r\n ico: \"image/x-icon\",\r\n tiff: \"image/tiff\",\r\n tif: \"image/tiff\",\r\n});\r\n\r\n/**\r\n * Resolve the MIME type for a file extension.\r\n *\r\n * @param extension - Extension WITHOUT a leading dot. Case-insensitive.\r\n * @returns The mapped MIME type, or \"application/octet-stream\".\r\n */\r\nexport function getMimeType(extension: string): string {\r\n return MIME_TYPES[extension.toLowerCase()] ?? \"application/octet-stream\";\r\n}\r\n\r\n/**\r\n * Decode a base64 payload and hand it to the browser as a download.\r\n *\r\n * @param base64Data - Base64 WITHOUT a `data:` prefix, as the getFile /\r\n * downloadFile endpoints return it.\r\n * @param fileName - Filename offered to the user. The extension is NOT\r\n * appended automatically; pass it already suffixed if\r\n * you want one.\r\n * @param extension - Used only to resolve the Blob's MIME type.\r\n * @returns true on success; false if decoding failed or there is no DOM.\r\n *\r\n * @example\r\n * const ok = downloadBase64File(body.content, body.fileName, body.extension);\r\n * if (!ok) toast(\"Le téléchargement a échoué. Veuillez réessayer.\", \"error\");\r\n */\r\nexport function downloadBase64File(\r\n base64Data: string,\r\n fileName: string,\r\n extension: string,\r\n): boolean {\r\n // Guarded rather than assumed: this runs in jsdom under test and could be\r\n // reached during SSR. The host modules' copies of this threw in both.\r\n if (typeof document === \"undefined\" || typeof atob === \"undefined\") {\r\n return false;\r\n }\r\n\r\n let url: string | null = null;\r\n let link: HTMLAnchorElement | null = null;\r\n\r\n try {\r\n const binary = atob(base64Data);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i += 1) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n\r\n const blob = new Blob([bytes], { type: getMimeType(extension) });\r\n\r\n url = URL.createObjectURL(blob);\r\n link = document.createElement(\"a\");\r\n link.href = url;\r\n link.download = fileName;\r\n document.body.appendChild(link);\r\n link.click();\r\n return true;\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n console.error(\"[@portnet/ui] downloadBase64File failed:\", error);\r\n return false;\r\n } finally {\r\n // finally, not the happy path: the host copies leaked both the anchor\r\n // and the object URL whenever click() or appendChild threw.\r\n if (link && link.parentNode) link.parentNode.removeChild(link);\r\n if (url) URL.revokeObjectURL(url);\r\n }\r\n}\r\n\r\n/**\r\n * Delay before revoking a preview's object URL.\r\n *\r\n * It CANNOT be revoked synchronously: the newly opened tab still has to fetch\r\n * the blob. There is no portable \"that tab finished loading\" signal for a blob\r\n * URL, so a timeout is the only cross-browser option. Deliberately generous:\r\n * revoking early shows the user a blank tab, while being late costs one\r\n * short-lived blob.\r\n */\r\nconst PREVIEW_REVOKE_DELAY_MS = 60_000;\r\n\r\n/**\r\n * Decode a base64 payload and open it in a new tab for preview.\r\n *\r\n * Companion to downloadBase64File: every document-bearing GU module offers a\r\n * « Visualiser » action next to « Télécharger », and each carried its own copy of\r\n * this atob -> Uint8Array -> Blob -> window.open sequence. NONE of those copies\r\n * revoked the object URL, so every preview leaked a blob for the lifetime of the\r\n * page.\r\n *\r\n * RETURN VALUE — read this before relying on it. `window.open` returns null BY\r\n * SPECIFICATION when \"noopener\" is set, so a blocked popup is indistinguishable\r\n * from a successful one. `true` therefore means \"decoded and the open call was\r\n * issued without throwing\" — NOT \"the tab is on screen\". Do not use it to claim\r\n * success to the user; use `false` to report a genuine failure (bad payload, no\r\n * DOM). Dropping \"noopener\" would make blocked-popup detection possible but\r\n * would hand the opened tab a window.opener reference — not a trade worth making\r\n * for a diagnostic.\r\n *\r\n * @param base64Data - Base64 WITHOUT a `data:` prefix.\r\n * @param extension - Resolves the Blob MIME type. Required for inline\r\n * rendering: with the wrong type the browser downloads the\r\n * file instead of displaying it.\r\n * @returns false if there is no DOM or the payload could not be decoded.\r\n */\r\nexport function openBase64FileInTab(base64Data: string, extension: string): boolean {\r\n if (typeof window === \"undefined\" || typeof atob === \"undefined\") {\r\n return false;\r\n }\r\n let url: string | null = null;\r\n try {\r\n const binary = atob(base64Data);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i += 1) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n const blob = new Blob([bytes], { type: getMimeType(extension) });\r\n url = URL.createObjectURL(blob);\r\n window.open(url, \"_blank\", \"noopener,noreferrer\");\r\n const revokeTarget = url;\r\n window.setTimeout(() => URL.revokeObjectURL(revokeTarget), PREVIEW_REVOKE_DELAY_MS);\r\n return true;\r\n } catch (error) {\r\n // Revoke straight away here: nothing consumed the URL on this path.\r\n if (url) URL.revokeObjectURL(url);\r\n // eslint-disable-next-line no-console\r\n console.error(\"[@portnet/ui] openBase64FileInTab failed:\", error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Hand an already-materialised Blob to the browser as a download.\r\n *\r\n * Companion to downloadBase64File for endpoints that return a binary body\r\n * directly (axios `responseType: \"blob\"`) instead of base64 — Excel exports,\r\n * server-generated PDFs. Host modules built the anchor by hand for this too,\r\n * and every copy found so far never revoked the object URL.\r\n *\r\n * Revoked synchronously in `finally`, unlike openBase64FileInTab: a download is\r\n * snapshotted by the browser at click() time, so nothing needs the URL\r\n * afterwards — only a preview in another tab does.\r\n *\r\n * @param blob - The payload. Its own `type` is used as-is; no MIME lookup,\r\n * the server already declared it.\r\n * @param fileName - Filename offered to the user, extension included.\r\n * @returns true on success; false if there is no DOM.\r\n */\r\nexport function downloadBlobFile(blob: Blob, fileName: string): boolean {\r\n if (typeof document === \"undefined\" || typeof URL === \"undefined\") {\r\n return false;\r\n }\r\n let url: string | null = null;\r\n let link: HTMLAnchorElement | null = null;\r\n try {\r\n url = URL.createObjectURL(blob);\r\n link = document.createElement(\"a\");\r\n link.href = url;\r\n link.download = fileName;\r\n document.body.appendChild(link);\r\n link.click();\r\n return true;\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n console.error(\"[@portnet/ui] downloadBlobFile failed:\", error);\r\n return false;\r\n } finally {\r\n if (link && link.parentNode) link.parentNode.removeChild(link);\r\n if (url) URL.revokeObjectURL(url);\r\n }\r\n}\r\n\r\nconst fileDownloadApi = {\r\n getMimeType,\r\n downloadBase64File,\r\n openBase64FileInTab,\r\n downloadBlobFile,\r\n};\r\nexport default fileDownloadApi;\r\n"],"mappings":"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","ignoreList":[]}
1
+ {"version":3,"file":"fileDownload.js","names":["MIME_TYPES","Object","freeze","pdf","doc","docx","xls","xlsx","csv","txt","png","jpg","jpeg","gif","bmp","webp","svg","ico","tiff","tif","getMimeType","extension","toLowerCase","downloadBase64File","base64Data","fileName","document","atob","url","link","binary","bytes","Uint8Array","length","i","charCodeAt","blob","Blob","type","URL","createObjectURL","createElement","href","download","body","appendChild","click","error","console","parentNode","removeChild","revokeObjectURL","PREVIEW_REVOKE_DELAY_MS","openBase64FileInTab","window","open","revokeTarget","setTimeout","downloadBlobFile","fileDownloadApi","_default","exports","default"],"sources":["../../../src/lib/v2/utils/fileDownload.ts"],"sourcesContent":["/**\r\n * File download utilities — Portnet UI v2\r\n *\r\n * Turns a base64 payload from the API into a browser download. Every GU\r\n * module that lets a user retrieve an attached document needs this, and\r\n * before this file each one carried its own copy of the same\r\n * atob → Uint8Array → Blob → anchor sequence plus its own MIME map.\r\n *\r\n * DEPENDENCY-FREE ON PURPOSE. Multi-file (zip) bundling is deliberately NOT\r\n * here: it needs a zip library, and making that a hard dependency of the\r\n * design system would put it in every module's bundle against the\r\n * R-8.2 budget (180 KB gz initial JS) for a capability only\r\n * document-heavy modules use. If it is promoted later it belongs behind an\r\n * OPTIONAL peer dependency, the way PdfViewer sits behind pdfjs-dist and\r\n * @react-pdf-viewer/* in peerDependenciesMeta.\r\n *\r\n * Charter ref: §09.3 — the caller owns the user-facing message; these\r\n * return a boolean rather than throwing so a failure surfaces as copy\r\n * (R-4.4) instead of an unhandled rejection.\r\n */\r\n\r\n/**\r\n * Extension → MIME type for the formats the platform accepts as\r\n * attachments.\r\n *\r\n * Anything unmapped resolves to application/octet-stream, which makes the\r\n * browser download the file rather than attempt to render it — the safe\r\n * default for an unknown payload.\r\n */\r\nconst MIME_TYPES: Readonly<Record<string, string>> = Object.freeze({\r\n // Documents\r\n pdf: \"application/pdf\",\r\n doc: \"application/msword\",\r\n docx: \"application/vnd.openxmlformats-officedocument.wordprocessingml.document\",\r\n xls: \"application/vnd.ms-excel\",\r\n xlsx: \"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet\",\r\n csv: \"text/csv\",\r\n txt: \"text/plain\",\r\n\r\n // Images\r\n png: \"image/png\",\r\n jpg: \"image/jpeg\",\r\n jpeg: \"image/jpeg\",\r\n gif: \"image/gif\",\r\n bmp: \"image/bmp\",\r\n webp: \"image/webp\",\r\n svg: \"image/svg+xml\",\r\n ico: \"image/x-icon\",\r\n tiff: \"image/tiff\",\r\n tif: \"image/tiff\",\r\n});\r\n\r\n/**\r\n * Resolve the MIME type for a file extension.\r\n *\r\n * @param extension - Extension WITHOUT a leading dot. Case-insensitive.\r\n * @returns The mapped MIME type, or \"application/octet-stream\".\r\n */\r\nexport function getMimeType(extension: string): string {\r\n return MIME_TYPES[extension.toLowerCase()] ?? \"application/octet-stream\";\r\n}\r\n\r\n/**\r\n * Decode a base64 payload and hand it to the browser as a download.\r\n *\r\n * @param base64Data - Base64 WITHOUT a `data:` prefix, as the getFile /\r\n * downloadFile endpoints return it.\r\n * @param fileName - Filename offered to the user. The extension is NOT\r\n * appended automatically; pass it already suffixed if\r\n * you want one.\r\n * @param extension - Used only to resolve the Blob's MIME type.\r\n * @returns true on success; false if decoding failed or there is no DOM.\r\n *\r\n * @example\r\n * const ok = downloadBase64File(body.content, body.fileName, body.extension);\r\n * if (!ok) toast(\"Le téléchargement a échoué. Veuillez réessayer.\", \"error\");\r\n */\r\nexport function downloadBase64File(\r\n base64Data: string,\r\n fileName: string,\r\n extension: string,\r\n): boolean {\r\n // Guarded rather than assumed: this runs in jsdom under test and could be\r\n // reached during SSR. The host modules' copies of this threw in both.\r\n if (typeof document === \"undefined\" || typeof atob === \"undefined\") {\r\n return false;\r\n }\r\n\r\n let url: string | null = null;\r\n let link: HTMLAnchorElement | null = null;\r\n\r\n try {\r\n const binary = atob(base64Data);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i += 1) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n\r\n const blob = new Blob([bytes], { type: getMimeType(extension) });\r\n\r\n url = URL.createObjectURL(blob);\r\n link = document.createElement(\"a\");\r\n link.href = url;\r\n link.download = fileName;\r\n document.body.appendChild(link);\r\n link.click();\r\n return true;\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n console.error(\"[@portnet/ui] downloadBase64File failed:\", error);\r\n return false;\r\n } finally {\r\n // finally, not the happy path: the host copies leaked both the anchor\r\n // and the object URL whenever click() or appendChild threw.\r\n if (link && link.parentNode) link.parentNode.removeChild(link);\r\n if (url) URL.revokeObjectURL(url);\r\n }\r\n}\r\n\r\n/**\r\n * Delay before revoking a preview's object URL.\r\n *\r\n * It CANNOT be revoked synchronously: the newly opened tab still has to fetch\r\n * the blob. There is no portable \"that tab finished loading\" signal for a blob\r\n * URL, so a timeout is the only cross-browser option. Deliberately generous:\r\n * revoking early shows the user a blank tab, while being late costs one\r\n * short-lived blob.\r\n */\r\nconst PREVIEW_REVOKE_DELAY_MS = 60_000;\r\n\r\n/**\r\n * Decode a base64 payload and open it in a new tab for preview.\r\n *\r\n * Companion to downloadBase64File: every document-bearing GU module offers a\r\n * « Visualiser » action next to « Télécharger », and each carried its own copy of\r\n * this atob -> Uint8Array -> Blob -> window.open sequence. NONE of those copies\r\n * revoked the object URL, so every preview leaked a blob for the lifetime of the\r\n * page.\r\n *\r\n * RETURN VALUE — read this before relying on it. `window.open` returns null BY\r\n * SPECIFICATION when \"noopener\" is set, so a blocked popup is indistinguishable\r\n * from a successful one. `true` therefore means \"decoded and the open call was\r\n * issued without throwing\" — NOT \"the tab is on screen\". Do not use it to claim\r\n * success to the user; use `false` to report a genuine failure (bad payload, no\r\n * DOM). Dropping \"noopener\" would make blocked-popup detection possible but\r\n * would hand the opened tab a window.opener reference — not a trade worth making\r\n * for a diagnostic.\r\n *\r\n * @param base64Data - Base64 WITHOUT a `data:` prefix.\r\n * @param extension - Resolves the Blob MIME type. Required for inline\r\n * rendering: with the wrong type the browser downloads the\r\n * file instead of displaying it.\r\n * @returns false if there is no DOM or the payload could not be decoded.\r\n */\r\nexport function openBase64FileInTab(base64Data: string, extension: string): boolean {\r\n if (typeof window === \"undefined\" || typeof atob === \"undefined\") {\r\n return false;\r\n }\r\n let url: string | null = null;\r\n try {\r\n const binary = atob(base64Data);\r\n const bytes = new Uint8Array(binary.length);\r\n for (let i = 0; i < binary.length; i += 1) {\r\n bytes[i] = binary.charCodeAt(i);\r\n }\r\n const blob = new Blob([bytes], { type: getMimeType(extension) });\r\n url = URL.createObjectURL(blob);\r\n window.open(url, \"_blank\", \"noopener,noreferrer\");\r\n const revokeTarget = url;\r\n window.setTimeout(() => URL.revokeObjectURL(revokeTarget), PREVIEW_REVOKE_DELAY_MS);\r\n return true;\r\n } catch (error) {\r\n // Revoke straight away here: nothing consumed the URL on this path.\r\n if (url) URL.revokeObjectURL(url);\r\n // eslint-disable-next-line no-console\r\n console.error(\"[@portnet/ui] openBase64FileInTab failed:\", error);\r\n return false;\r\n }\r\n}\r\n\r\n/**\r\n * Hand an already-materialised Blob to the browser as a download.\r\n *\r\n * Companion to downloadBase64File for endpoints that return a binary body\r\n * directly (axios `responseType: \"blob\"`) instead of base64 — Excel exports,\r\n * server-generated PDFs. Host modules built the anchor by hand for this too,\r\n * and every copy found so far never revoked the object URL.\r\n *\r\n * Revoked synchronously in `finally`, unlike openBase64FileInTab: a download is\r\n * snapshotted by the browser at click() time, so nothing needs the URL\r\n * afterwards — only a preview in another tab does.\r\n *\r\n * @param blob - The payload. Its own `type` is used as-is; no MIME lookup,\r\n * the server already declared it.\r\n * @param fileName - Filename offered to the user, extension included.\r\n * @returns true on success; false if there is no DOM.\r\n */\r\nexport function downloadBlobFile(blob: Blob, fileName: string): boolean {\r\n if (typeof document === \"undefined\" || typeof URL === \"undefined\") {\r\n return false;\r\n }\r\n let url: string | null = null;\r\n let link: HTMLAnchorElement | null = null;\r\n try {\r\n url = URL.createObjectURL(blob);\r\n link = document.createElement(\"a\");\r\n link.href = url;\r\n link.download = fileName;\r\n document.body.appendChild(link);\r\n link.click();\r\n return true;\r\n } catch (error) {\r\n // eslint-disable-next-line no-console\r\n console.error(\"[@portnet/ui] downloadBlobFile failed:\", error);\r\n return false;\r\n } finally {\r\n if (link && link.parentNode) link.parentNode.removeChild(link);\r\n if (url) URL.revokeObjectURL(url);\r\n }\r\n}\r\n\r\nconst fileDownloadApi = {\r\n getMimeType,\r\n downloadBase64File,\r\n openBase64FileInTab,\r\n downloadBlobFile,\r\n};\r\nexport default fileDownloadApi;\r\n"],"mappings":"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","ignoreList":[]}