@ifto/mantine-kit 0.0.0-stage → 0.2.0

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 (301) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +475 -2
  3. package/dist/component/atom/AppMain/App.module.js +7 -0
  4. package/dist/component/atom/AppMain/App.module.js.map +1 -0
  5. package/dist/component/atom/AppMain/AppMain.d.ts +7 -0
  6. package/dist/component/atom/AppMain/AppMain.js +14 -0
  7. package/dist/component/atom/AppMain/AppMain.js.map +1 -0
  8. package/dist/component/atom/CancelEditButton/CancelEditButton.d.ts +6 -0
  9. package/dist/component/atom/CancelEditButton/CancelEditButton.js +24 -0
  10. package/dist/component/atom/CancelEditButton/CancelEditButton.js.map +1 -0
  11. package/dist/component/atom/ConfirmEditButton/ConfirmEditButton.d.ts +13 -0
  12. package/dist/component/atom/ConfirmEditButton/ConfirmEditButton.js +30 -0
  13. package/dist/component/atom/ConfirmEditButton/ConfirmEditButton.js.map +1 -0
  14. package/dist/component/atom/DateField/DateField.d.ts +7 -0
  15. package/dist/component/atom/DateField/DateField.js +21 -0
  16. package/dist/component/atom/DateField/DateField.js.map +1 -0
  17. package/dist/component/atom/EditValueButton/EditValueButton.d.ts +6 -0
  18. package/dist/component/atom/EditValueButton/EditValueButton.js +24 -0
  19. package/dist/component/atom/EditValueButton/EditValueButton.js.map +1 -0
  20. package/dist/component/atom/ErrorAlert/ErrorAlert.d.ts +8 -0
  21. package/dist/component/atom/ErrorAlert/ErrorAlert.js +21 -0
  22. package/dist/component/atom/ErrorAlert/ErrorAlert.js.map +1 -0
  23. package/dist/component/atom/Surface/Surface.d.ts +20 -0
  24. package/dist/component/atom/Surface/Surface.js +15 -0
  25. package/dist/component/atom/Surface/Surface.js.map +1 -0
  26. package/dist/component/molecule/Breadcrumb/Breadcrumb.d.ts +12 -0
  27. package/dist/component/molecule/Breadcrumb/Breadcrumb.js +38 -0
  28. package/dist/component/molecule/Breadcrumb/Breadcrumb.js.map +1 -0
  29. package/dist/component/molecule/ExportMenuButton/ExportMenuButton.d.ts +25 -0
  30. package/dist/component/molecule/ExportMenuButton/ExportMenuButton.js +49 -0
  31. package/dist/component/molecule/ExportMenuButton/ExportMenuButton.js.map +1 -0
  32. package/dist/component/molecule/PaperCard/PaperCard.d.ts +7 -0
  33. package/dist/component/molecule/PaperCard/PaperCard.js +17 -0
  34. package/dist/component/molecule/PaperCard/PaperCard.js.map +1 -0
  35. package/dist/component/molecule/PrintSection/PrintSection.d.ts +14 -0
  36. package/dist/component/molecule/PrintSection/PrintSection.js +29 -0
  37. package/dist/component/molecule/PrintSection/PrintSection.js.map +1 -0
  38. package/dist/component/molecule/SelectField/SelectField.d.ts +32 -0
  39. package/dist/component/molecule/SelectField/SelectField.js +38 -0
  40. package/dist/component/molecule/SelectField/SelectField.js.map +1 -0
  41. package/dist/component/molecule/StatsCard/Stats.module.js +15 -0
  42. package/dist/component/molecule/StatsCard/Stats.module.js.map +1 -0
  43. package/dist/component/molecule/StatsCard/StatsCard.d.ts +18 -0
  44. package/dist/component/molecule/StatsCard/StatsCard.js +60 -0
  45. package/dist/component/molecule/StatsCard/StatsCard.js.map +1 -0
  46. package/dist/component/organism/DataForm/DataForm.d.ts +26 -0
  47. package/dist/component/organism/DataForm/DataForm.js +83 -0
  48. package/dist/component/organism/DataForm/DataForm.js.map +1 -0
  49. package/dist/component/organism/DataTabList/DataTabList.d.ts +24 -0
  50. package/dist/component/organism/DataTabList/DataTabList.js +37 -0
  51. package/dist/component/organism/DataTabList/DataTabList.js.map +1 -0
  52. package/dist/component/organism/DataTabList/DataTabList.module.js +13 -0
  53. package/dist/component/organism/DataTabList/DataTabList.module.js.map +1 -0
  54. package/dist/component/organism/EChart/EChart.d.ts +47 -0
  55. package/dist/component/organism/EChart/EChart.js +37 -0
  56. package/dist/component/organism/EChart/EChart.js.map +1 -0
  57. package/dist/component/organism/EChart/buildEChartOption.d.ts +40 -0
  58. package/dist/component/organism/EChart/buildEChartOption.js +57 -0
  59. package/dist/component/organism/EChart/buildEChartOption.js.map +1 -0
  60. package/dist/component/organism/EChart/chart/BarChart.d.ts +22 -0
  61. package/dist/component/organism/EChart/chart/BarChart.js +34 -0
  62. package/dist/component/organism/EChart/chart/BarChart.js.map +1 -0
  63. package/dist/component/organism/EChart/chart/CartesianChart.d.ts +48 -0
  64. package/dist/component/organism/EChart/chart/CartesianChart.js +63 -0
  65. package/dist/component/organism/EChart/chart/CartesianChart.js.map +1 -0
  66. package/dist/component/organism/EChart/chart/ChartHeader.d.ts +36 -0
  67. package/dist/component/organism/EChart/chart/ChartHeader.js +105 -0
  68. package/dist/component/organism/EChart/chart/ChartHeader.js.map +1 -0
  69. package/dist/component/organism/EChart/chart/ChartSeries.d.ts +50 -0
  70. package/dist/component/organism/EChart/chart/ChartSeries.js +23 -0
  71. package/dist/component/organism/EChart/chart/ChartSeries.js.map +1 -0
  72. package/dist/component/organism/EChart/chart/ChartTexts.d.ts +12 -0
  73. package/dist/component/organism/EChart/chart/ChartTexts.js +21 -0
  74. package/dist/component/organism/EChart/chart/ChartTexts.js.map +1 -0
  75. package/dist/component/organism/EChart/chart/ChartType.d.ts +50 -0
  76. package/dist/component/organism/EChart/chart/ChartType.js +1 -0
  77. package/dist/component/organism/EChart/chart/ChartTypeId.d.ts +2 -0
  78. package/dist/component/organism/EChart/chart/ChartTypeId.js +1 -0
  79. package/dist/component/organism/EChart/chart/ChartTypes.d.ts +15 -0
  80. package/dist/component/organism/EChart/chart/ChartTypes.js +24 -0
  81. package/dist/component/organism/EChart/chart/ChartTypes.js.map +1 -0
  82. package/dist/component/organism/EChart/chart/DonutChart.d.ts +32 -0
  83. package/dist/component/organism/EChart/chart/DonutChart.js +111 -0
  84. package/dist/component/organism/EChart/chart/DonutChart.js.map +1 -0
  85. package/dist/component/organism/EChart/chart/LineChart.d.ts +11 -0
  86. package/dist/component/organism/EChart/chart/LineChart.js +20 -0
  87. package/dist/component/organism/EChart/chart/LineChart.js.map +1 -0
  88. package/dist/component/organism/EChart/chart/StackedBarChart.d.ts +15 -0
  89. package/dist/component/organism/EChart/chart/StackedBarChart.js +30 -0
  90. package/dist/component/organism/EChart/chart/StackedBarChart.js.map +1 -0
  91. package/dist/component/organism/EChart/chart/UnitPanels.d.ts +63 -0
  92. package/dist/component/organism/EChart/chart/UnitPanels.js +127 -0
  93. package/dist/component/organism/EChart/chart/UnitPanels.js.map +1 -0
  94. package/dist/component/organism/EChart/echartDefaults.d.ts +32 -0
  95. package/dist/component/organism/EChart/echartDefaults.js +47 -0
  96. package/dist/component/organism/EChart/echartDefaults.js.map +1 -0
  97. package/dist/component/organism/EChart/useEChart.d.ts +35 -0
  98. package/dist/component/organism/EChart/useEChart.js +112 -0
  99. package/dist/component/organism/EChart/useEChart.js.map +1 -0
  100. package/dist/component/organism/Navbar/NavItem.d.ts +16 -0
  101. package/dist/component/organism/Navbar/NavItem.js +1 -0
  102. package/dist/component/organism/Navbar/Navbar.d.ts +20 -0
  103. package/dist/component/organism/Navbar/Navbar.js +64 -0
  104. package/dist/component/organism/Navbar/Navbar.js.map +1 -0
  105. package/dist/component/organism/Navbar/Navbar.module.js +19 -0
  106. package/dist/component/organism/Navbar/Navbar.module.js.map +1 -0
  107. package/dist/component/organism/PageHeader/PageHeader.d.ts +14 -0
  108. package/dist/component/organism/PageHeader/PageHeader.js +55 -0
  109. package/dist/component/organism/PageHeader/PageHeader.js.map +1 -0
  110. package/dist/component/organism/StatsGrid/StatsGrid.d.ts +12 -0
  111. package/dist/component/organism/StatsGrid/StatsGrid.js +46 -0
  112. package/dist/component/organism/StatsGrid/StatsGrid.js.map +1 -0
  113. package/dist/component/organism/StatsGrid/StatsGrid.module.js +17 -0
  114. package/dist/component/organism/StatsGrid/StatsGrid.module.js.map +1 -0
  115. package/dist/component/organism/Table/RowActions.d.ts +23 -0
  116. package/dist/component/organism/Table/RowActions.js +121 -0
  117. package/dist/component/organism/Table/RowActions.js.map +1 -0
  118. package/dist/component/organism/Table/Table.d.ts +51 -0
  119. package/dist/component/organism/Table/Table.js +110 -0
  120. package/dist/component/organism/Table/Table.js.map +1 -0
  121. package/dist/component/organism/ViewTable/ColumnComparator.d.ts +11 -0
  122. package/dist/component/organism/ViewTable/ColumnComparator.js +25 -0
  123. package/dist/component/organism/ViewTable/ColumnComparator.js.map +1 -0
  124. package/dist/component/organism/ViewTable/ViewTable.d.ts +53 -0
  125. package/dist/component/organism/ViewTable/ViewTable.js +115 -0
  126. package/dist/component/organism/ViewTable/ViewTable.js.map +1 -0
  127. package/dist/component/organism/ViewTable/useRowKey.d.ts +8 -0
  128. package/dist/component/organism/ViewTable/useRowKey.js +24 -0
  129. package/dist/component/organism/ViewTable/useRowKey.js.map +1 -0
  130. package/dist/component/template/CreateFormPage/CreateFormPage.d.ts +19 -0
  131. package/dist/component/template/CreateFormPage/CreateFormPage.js +41 -0
  132. package/dist/component/template/CreateFormPage/CreateFormPage.js.map +1 -0
  133. package/dist/component/template/EditFormPage/EditFormPage.d.ts +19 -0
  134. package/dist/component/template/EditFormPage/EditFormPage.js +42 -0
  135. package/dist/component/template/EditFormPage/EditFormPage.js.map +1 -0
  136. package/dist/component/template/FormPage/FormPage.d.ts +25 -0
  137. package/dist/component/template/FormPage/FormPage.js +130 -0
  138. package/dist/component/template/FormPage/FormPage.js.map +1 -0
  139. package/dist/component/template/FormPage/FormType.d.ts +6 -0
  140. package/dist/component/template/FormPage/FormType.js +12 -0
  141. package/dist/component/template/FormPage/FormType.js.map +1 -0
  142. package/dist/component/template/Layout/Layout.d.ts +21 -0
  143. package/dist/component/template/Layout/Layout.js +121 -0
  144. package/dist/component/template/Layout/Layout.js.map +1 -0
  145. package/dist/component/template/Layout/Layout.module.js +19 -0
  146. package/dist/component/template/Layout/Layout.module.js.map +1 -0
  147. package/dist/component/template/ListPage/ListPage.d.ts +32 -0
  148. package/dist/component/template/ListPage/ListPage.js +47 -0
  149. package/dist/component/template/ListPage/ListPage.js.map +1 -0
  150. package/dist/component/template/PrintPage/PrintPage.d.ts +25 -0
  151. package/dist/component/template/PrintPage/PrintPage.js +115 -0
  152. package/dist/component/template/PrintPage/PrintPage.js.map +1 -0
  153. package/dist/component/template/ViewPage/ViewPage.d.ts +11 -0
  154. package/dist/component/template/ViewPage/ViewPage.js +49 -0
  155. package/dist/component/template/ViewPage/ViewPage.js.map +1 -0
  156. package/dist/data/ListDataSource.d.ts +12 -0
  157. package/dist/data/ListDataSource.js +1 -0
  158. package/dist/data/SaveDataSource.d.ts +16 -0
  159. package/dist/data/SaveDataSource.js +1 -0
  160. package/dist/export/ExportCellText.d.ts +18 -0
  161. package/dist/export/ExportCellText.js +60 -0
  162. package/dist/export/ExportCellText.js.map +1 -0
  163. package/dist/export/ExportDocument.d.ts +127 -0
  164. package/dist/export/ExportDocument.js +59 -0
  165. package/dist/export/ExportDocument.js.map +1 -0
  166. package/dist/export/ExportDownload.d.ts +9 -0
  167. package/dist/export/ExportDownload.js +19 -0
  168. package/dist/export/ExportDownload.js.map +1 -0
  169. package/dist/export/ExportFileName.d.ts +11 -0
  170. package/dist/export/ExportFileName.js +24 -0
  171. package/dist/export/ExportFileName.js.map +1 -0
  172. package/dist/export/ExportFormat.d.ts +30 -0
  173. package/dist/export/ExportFormat.js +1 -0
  174. package/dist/export/ExportFormats.d.ts +12 -0
  175. package/dist/export/ExportFormats.js +16 -0
  176. package/dist/export/ExportFormats.js.map +1 -0
  177. package/dist/export/ExportTexts.d.ts +14 -0
  178. package/dist/export/ExportTexts.js +23 -0
  179. package/dist/export/ExportTexts.js.map +1 -0
  180. package/dist/export/csv/CsvFormat.d.ts +41 -0
  181. package/dist/export/csv/CsvFormat.js +91 -0
  182. package/dist/export/csv/CsvFormat.js.map +1 -0
  183. package/dist/export/xlsx/XlsxFormat.d.ts +35 -0
  184. package/dist/export/xlsx/XlsxFormat.js +66 -0
  185. package/dist/export/xlsx/XlsxFormat.js.map +1 -0
  186. package/dist/export/xlsx/XlsxNumberFormat.d.ts +8 -0
  187. package/dist/export/xlsx/XlsxNumberFormat.js +15 -0
  188. package/dist/export/xlsx/XlsxNumberFormat.js.map +1 -0
  189. package/dist/export/xlsx/XlsxSheetName.d.ts +12 -0
  190. package/dist/export/xlsx/XlsxSheetName.js +62 -0
  191. package/dist/export/xlsx/XlsxSheetName.js.map +1 -0
  192. package/dist/export/xlsx/XlsxSheetWriter.d.ts +67 -0
  193. package/dist/export/xlsx/XlsxSheetWriter.js +215 -0
  194. package/dist/export/xlsx/XlsxSheetWriter.js.map +1 -0
  195. package/dist/export/xlsx/XlsxStyle.d.ts +51 -0
  196. package/dist/export/xlsx/XlsxStyle.js +87 -0
  197. package/dist/export/xlsx/XlsxStyle.js.map +1 -0
  198. package/dist/hook/useIsMobile.d.ts +5 -0
  199. package/dist/hook/useIsMobile.js +16 -0
  200. package/dist/hook/useIsMobile.js.map +1 -0
  201. package/dist/hook/useKeyedService.d.ts +22 -0
  202. package/dist/hook/useKeyedService.js +38 -0
  203. package/dist/hook/useKeyedService.js.map +1 -0
  204. package/dist/hook/useLightColorSchemeOnPrint.d.ts +9 -0
  205. package/dist/hook/useLightColorSchemeOnPrint.js +36 -0
  206. package/dist/hook/useLightColorSchemeOnPrint.js.map +1 -0
  207. package/dist/hook/useService.d.ts +27 -0
  208. package/dist/hook/useService.js +23 -0
  209. package/dist/hook/useService.js.map +1 -0
  210. package/dist/http/ApiError.d.ts +13 -0
  211. package/dist/http/ApiError.js +22 -0
  212. package/dist/http/ApiError.js.map +1 -0
  213. package/dist/http/AxiosHttpClient.d.ts +21 -0
  214. package/dist/http/AxiosHttpClient.js +67 -0
  215. package/dist/http/AxiosHttpClient.js.map +1 -0
  216. package/dist/http/AxiosHttpClientConfig.d.ts +37 -0
  217. package/dist/http/AxiosHttpClientConfig.js +19 -0
  218. package/dist/http/AxiosHttpClientConfig.js.map +1 -0
  219. package/dist/i18n/KitLocale.d.ts +4 -0
  220. package/dist/i18n/KitLocale.js +7 -0
  221. package/dist/i18n/KitLocale.js.map +1 -0
  222. package/dist/i18n/KitMessages.d.ts +146 -0
  223. package/dist/i18n/KitMessages.js +1 -0
  224. package/dist/i18n/messages/enUS.d.ts +3 -0
  225. package/dist/i18n/messages/enUS.js +112 -0
  226. package/dist/i18n/messages/enUS.js.map +1 -0
  227. package/dist/i18n/messages/ptBR.d.ts +3 -0
  228. package/dist/i18n/messages/ptBR.js +97 -0
  229. package/dist/i18n/messages/ptBR.js.map +1 -0
  230. package/dist/i18n/resolveMessages.d.ts +13 -0
  231. package/dist/i18n/resolveMessages.js +29 -0
  232. package/dist/i18n/resolveMessages.js.map +1 -0
  233. package/dist/model/Identifiable.d.ts +7 -0
  234. package/dist/model/Identifiable.js +1 -0
  235. package/dist/provider/KitConfig.d.ts +26 -0
  236. package/dist/provider/KitConfig.js +1 -0
  237. package/dist/provider/KitContext.d.ts +9 -0
  238. package/dist/provider/KitContext.js +27 -0
  239. package/dist/provider/KitContext.js.map +1 -0
  240. package/dist/provider/KitProvider.d.ts +7 -0
  241. package/dist/provider/KitProvider.js +31 -0
  242. package/dist/provider/KitProvider.js.map +1 -0
  243. package/dist/provider/useKit.d.ts +15 -0
  244. package/dist/provider/useKit.js +28 -0
  245. package/dist/provider/useKit.js.map +1 -0
  246. package/dist/router/FormRouteSegments.d.ts +16 -0
  247. package/dist/router/FormRouteSegments.js +19 -0
  248. package/dist/router/FormRouteSegments.js.map +1 -0
  249. package/dist/router/RouterAdapter.d.ts +24 -0
  250. package/dist/router/RouterAdapter.js +1 -0
  251. package/dist/router/anchorRouter.d.ts +7 -0
  252. package/dist/router/anchorRouter.js +23 -0
  253. package/dist/router/anchorRouter.js.map +1 -0
  254. package/dist/styles/print.css +93 -0
  255. package/dist/styles.css +188 -0
  256. package/dist/util/ArrayUtil.d.ts +39 -0
  257. package/dist/util/ArrayUtil.js +48 -0
  258. package/dist/util/ArrayUtil.js.map +1 -0
  259. package/dist/util/ColorUtil.d.ts +7 -0
  260. package/dist/util/ColorUtil.js +16 -0
  261. package/dist/util/ColorUtil.js.map +1 -0
  262. package/dist/util/CompareUtil.d.ts +19 -0
  263. package/dist/util/CompareUtil.js +51 -0
  264. package/dist/util/CompareUtil.js.map +1 -0
  265. package/dist/util/DateUtil.d.ts +38 -0
  266. package/dist/util/DateUtil.js +55 -0
  267. package/dist/util/DateUtil.js.map +1 -0
  268. package/dist/util/DownloadUtil.d.ts +6 -0
  269. package/dist/util/DownloadUtil.js +25 -0
  270. package/dist/util/DownloadUtil.js.map +1 -0
  271. package/dist/util/EnumUtil.d.ts +19 -0
  272. package/dist/util/EnumUtil.js +32 -0
  273. package/dist/util/EnumUtil.js.map +1 -0
  274. package/dist/util/FormUtil.d.ts +8 -0
  275. package/dist/util/FormUtil.js +14 -0
  276. package/dist/util/FormUtil.js.map +1 -0
  277. package/dist/util/HtmlUtil.d.ts +8 -0
  278. package/dist/util/HtmlUtil.js +23 -0
  279. package/dist/util/HtmlUtil.js.map +1 -0
  280. package/dist/util/Notifications.d.ts +30 -0
  281. package/dist/util/Notifications.js +59 -0
  282. package/dist/util/Notifications.js.map +1 -0
  283. package/dist/util/NumberUtil.d.ts +19 -0
  284. package/dist/util/NumberUtil.js +33 -0
  285. package/dist/util/NumberUtil.js.map +1 -0
  286. package/dist/util/ObjectUtil.d.ts +22 -0
  287. package/dist/util/ObjectUtil.js +34 -0
  288. package/dist/util/ObjectUtil.js.map +1 -0
  289. package/dist/util/SearchParamsUtil.d.ts +23 -0
  290. package/dist/util/SearchParamsUtil.js +29 -0
  291. package/dist/util/SearchParamsUtil.js.map +1 -0
  292. package/dist/util/TransformData.d.ts +14 -0
  293. package/dist/util/TransformData.js +31 -0
  294. package/dist/util/TransformData.js.map +1 -0
  295. package/dist/util/ValidationUtil.d.ts +9 -0
  296. package/dist/util/ValidationUtil.js +16 -0
  297. package/dist/util/ValidationUtil.js.map +1 -0
  298. package/dist/util/parseActionsPageParams.d.ts +14 -0
  299. package/dist/util/parseActionsPageParams.js +29 -0
  300. package/dist/util/parseActionsPageParams.js.map +1 -0
  301. package/package.json +158 -5
@@ -0,0 +1,127 @@
1
+ /**
2
+ * Model of the exported data, independent of the file format (see `ExportFormat`). An export is a document with one
3
+ * or more sheets, and each sheet is a matrix (an array of arrays) of cells, with the title of each column.
4
+ * It depends on no domain: whoever exports converts their data to this model.
5
+ * @author Manoel Campos
6
+ */
7
+ import { KitLocale } from '../i18n/KitLocale';
8
+ import { ExportMessages } from '../i18n/KitMessages';
9
+ /** Format of a numeric value. Percentages are in the 0..1 scale and converted only for display. */
10
+ export type NumberFormat = {
11
+ /** Decimal places shown. */
12
+ decimals: number;
13
+ /** Whether the value is a percentage in the 0..1 scale (e.g. 0.85 is shown as 85%). */
14
+ percent?: boolean;
15
+ };
16
+ /** Number with its own format, for when the format changes from one row to another (e.g. the unit of each row). */
17
+ export type NumberCell = {
18
+ value: number;
19
+ format: NumberFormat;
20
+ };
21
+ /** Cell whose value could not be computed (e.g. a calculation error), unlike an empty (absent) cell. */
22
+ export type InvalidCell = {
23
+ invalid: true;
24
+ /** Text shown instead of the value. */
25
+ text: string;
26
+ };
27
+ /**
28
+ * Value of a cell:
29
+ * - `string`: text;
30
+ * - `number`: number, in the format of the column (`NaN` is treated as an absent value);
31
+ * - {@link NumberCell}: number with its own format;
32
+ * - {@link InvalidCell}: invalid result;
33
+ * - `undefined`: absent value (empty cell), which is different from zero.
34
+ */
35
+ export type ExportCell = string | number | NumberCell | InvalidCell | undefined;
36
+ /** Column of a sheet. */
37
+ export type ExportColumn = {
38
+ /** Title (header) of the column. */
39
+ header: string;
40
+ /** Format of the numbers of the column, used when the cell has none; absent for {@link DEFAULT_NUMBER_FORMAT}. */
41
+ format?: NumberFormat;
42
+ };
43
+ /** Sheet of the file: a table with the columns and the rows. */
44
+ export type ExportSheet = {
45
+ /** Name of the sheet. Each format adapts it to its rules (e.g. the maximum length in Excel). */
46
+ name: string;
47
+ columns: ExportColumn[];
48
+ /**
49
+ * One array per row, with one cell per column, in the order of {@link columns}. A shorter row is completed with
50
+ * empty cells; a row with more cells than columns is an error, since the extra data would be lost.
51
+ */
52
+ rows: ExportCell[][];
53
+ };
54
+ /** Information about the context of the data, shown at the beginning of the file (e.g. the period and the filters). */
55
+ export type ExportInfo = {
56
+ label: string;
57
+ value: string;
58
+ };
59
+ /** Visual identity of the system that generated the file, shown in the header and in the footer. */
60
+ export type ExportBranding = {
61
+ /** Name of the system, shown in the footer (e.g. "Data generated by My System"). */
62
+ systemName: string;
63
+ /** Address of the system, shown as a link in the footer. */
64
+ siteUrl: string;
65
+ /** Logo shown in the header; absent to show no logo (e.g. if it could not be loaded). */
66
+ logo?: ExportImage;
67
+ };
68
+ /** PNG image embedded in the file. */
69
+ export type ExportImage = {
70
+ /** Content of the image, as a base64 data URL (`data:image/png;base64,...`). */
71
+ pngDataUrl: string;
72
+ /** Original width and height (px), to keep the aspect ratio when resizing. */
73
+ width: number;
74
+ height: number;
75
+ };
76
+ /** Document to export: the data and its context. */
77
+ export type ExportDocument = {
78
+ /** Title shown at the top of the file. */
79
+ title: string;
80
+ /** Name of the file, without the date and the extension, which are added on export. */
81
+ fileName: string;
82
+ info: ExportInfo[];
83
+ /** Date and time the data was generated. */
84
+ generatedAt: Date;
85
+ branding: ExportBranding;
86
+ sheets: ExportSheet[];
87
+ /** Locale of the texts and of the number format of the file. Default: `en-US`. */
88
+ locale?: KitLocale;
89
+ /** Texts that replace the ones of the locale (e.g. the ones the app overrides in the `KitProvider`). */
90
+ messages?: Partial<ExportMessages>;
91
+ };
92
+ /** Format of the numbers of a column that defines none. */
93
+ export declare const DEFAULT_NUMBER_FORMAT: NumberFormat;
94
+ /** Types of cell, after being normalized by {@link classifyCell}. */
95
+ export type ClassifiedCell = {
96
+ kind: 'empty';
97
+ } | {
98
+ kind: 'text';
99
+ text: string;
100
+ } | {
101
+ kind: 'number';
102
+ value: number;
103
+ format: NumberFormat;
104
+ } | {
105
+ kind: 'invalid';
106
+ text: string;
107
+ };
108
+ /**
109
+ * Creates a cell with an invalid result.
110
+ * @param text text shown instead of the value; defaults to the text of the default locale
111
+ * @return the invalid cell
112
+ */
113
+ export declare function invalidCell(text?: string): InvalidCell;
114
+ /**
115
+ * Tells whether the cell is an invalid result.
116
+ * @param cell cell to check
117
+ */
118
+ export declare function isInvalidCell(cell: ExportCell): cell is InvalidCell;
119
+ /**
120
+ * Classifies a cell, so that every format handles each type of value the same way. A `NaN` number is treated as
121
+ * absent (empty cell), and `Infinity` as invalid (e.g. a division by zero).
122
+ * @param cell cell to classify
123
+ * @param columnFormat format of the column of the cell, used when the cell is a number without its own format
124
+ * @param invalidText text of an infinite number; defaults to the text of the default locale
125
+ * @return the type and the value of the cell
126
+ */
127
+ export declare function classifyCell(cell: ExportCell, columnFormat?: NumberFormat, invalidText?: string): ClassifiedCell;
@@ -0,0 +1,59 @@
1
+ "use client";
2
+ import { DEFAULT_MESSAGES } from "../i18n/resolveMessages.js";
3
+ // src/export/ExportDocument.ts
4
+ /** Format of the numbers of a column that defines none. */
5
+ var DEFAULT_NUMBER_FORMAT = { decimals: 2 };
6
+ /**
7
+ * Creates a cell with an invalid result.
8
+ * @param text text shown instead of the value; defaults to the text of the default locale
9
+ * @return the invalid cell
10
+ */
11
+ function invalidCell(text = DEFAULT_MESSAGES.export.invalidCell) {
12
+ return {
13
+ invalid: true,
14
+ text
15
+ };
16
+ }
17
+ /**
18
+ * Tells whether the cell is an invalid result.
19
+ * @param cell cell to check
20
+ */
21
+ function isInvalidCell(cell) {
22
+ return typeof cell === "object" && "invalid" in cell;
23
+ }
24
+ /**
25
+ * Classifies a cell, so that every format handles each type of value the same way. A `NaN` number is treated as
26
+ * absent (empty cell), and `Infinity` as invalid (e.g. a division by zero).
27
+ * @param cell cell to classify
28
+ * @param columnFormat format of the column of the cell, used when the cell is a number without its own format
29
+ * @param invalidText text of an infinite number; defaults to the text of the default locale
30
+ * @return the type and the value of the cell
31
+ */
32
+ function classifyCell(cell, columnFormat = DEFAULT_NUMBER_FORMAT, invalidText = DEFAULT_MESSAGES.export.invalidCell) {
33
+ if (cell === void 0) return { kind: "empty" };
34
+ if (typeof cell === "string") return {
35
+ kind: "text",
36
+ text: cell
37
+ };
38
+ if (isInvalidCell(cell)) return {
39
+ kind: "invalid",
40
+ text: cell.text
41
+ };
42
+ const { value, format } = typeof cell === "number" ? {
43
+ value: cell,
44
+ format: columnFormat
45
+ } : cell;
46
+ if (Number.isNaN(value)) return { kind: "empty" };
47
+ if (!Number.isFinite(value)) return {
48
+ kind: "invalid",
49
+ text: invalidText
50
+ };
51
+ return {
52
+ kind: "number",
53
+ value,
54
+ format
55
+ };
56
+ }
57
+ export { DEFAULT_NUMBER_FORMAT, classifyCell, invalidCell, isInvalidCell };
58
+
59
+ //# sourceMappingURL=ExportDocument.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportDocument.js","names":[],"sources":["../../src/export/ExportDocument.ts"],"sourcesContent":["/**\n * Model of the exported data, independent of the file format (see `ExportFormat`). An export is a document with one\n * or more sheets, and each sheet is a matrix (an array of arrays) of cells, with the title of each column.\n * It depends on no domain: whoever exports converts their data to this model.\n * @author Manoel Campos\n */\n\nimport { KitLocale } from '../i18n/KitLocale';\nimport { ExportMessages } from '../i18n/KitMessages';\nimport { DEFAULT_MESSAGES } from '../i18n/resolveMessages';\n\n/** Format of a numeric value. Percentages are in the 0..1 scale and converted only for display. */\nexport type NumberFormat = {\n /** Decimal places shown. */\n decimals: number;\n\n /** Whether the value is a percentage in the 0..1 scale (e.g. 0.85 is shown as 85%). */\n percent?: boolean;\n};\n\n/** Number with its own format, for when the format changes from one row to another (e.g. the unit of each row). */\nexport type NumberCell = {\n value: number;\n format: NumberFormat;\n};\n\n/** Cell whose value could not be computed (e.g. a calculation error), unlike an empty (absent) cell. */\nexport type InvalidCell = {\n invalid: true;\n\n /** Text shown instead of the value. */\n text: string;\n};\n\n/**\n * Value of a cell:\n * - `string`: text;\n * - `number`: number, in the format of the column (`NaN` is treated as an absent value);\n * - {@link NumberCell}: number with its own format;\n * - {@link InvalidCell}: invalid result;\n * - `undefined`: absent value (empty cell), which is different from zero.\n */\nexport type ExportCell = string | number | NumberCell | InvalidCell | undefined;\n\n/** Column of a sheet. */\nexport type ExportColumn = {\n /** Title (header) of the column. */\n header: string;\n\n /** Format of the numbers of the column, used when the cell has none; absent for {@link DEFAULT_NUMBER_FORMAT}. */\n format?: NumberFormat;\n};\n\n/** Sheet of the file: a table with the columns and the rows. */\nexport type ExportSheet = {\n /** Name of the sheet. Each format adapts it to its rules (e.g. the maximum length in Excel). */\n name: string;\n columns: ExportColumn[];\n\n /**\n * One array per row, with one cell per column, in the order of {@link columns}. A shorter row is completed with\n * empty cells; a row with more cells than columns is an error, since the extra data would be lost.\n */\n rows: ExportCell[][];\n};\n\n/** Information about the context of the data, shown at the beginning of the file (e.g. the period and the filters). */\nexport type ExportInfo = {\n label: string;\n value: string;\n};\n\n/** Visual identity of the system that generated the file, shown in the header and in the footer. */\nexport type ExportBranding = {\n /** Name of the system, shown in the footer (e.g. \"Data generated by My System\"). */\n systemName: string;\n\n /** Address of the system, shown as a link in the footer. */\n siteUrl: string;\n\n /** Logo shown in the header; absent to show no logo (e.g. if it could not be loaded). */\n logo?: ExportImage;\n};\n\n/** PNG image embedded in the file. */\nexport type ExportImage = {\n /** Content of the image, as a base64 data URL (`data:image/png;base64,...`). */\n pngDataUrl: string;\n\n /** Original width and height (px), to keep the aspect ratio when resizing. */\n width: number;\n height: number;\n};\n\n/** Document to export: the data and its context. */\nexport type ExportDocument = {\n /** Title shown at the top of the file. */\n title: string;\n\n /** Name of the file, without the date and the extension, which are added on export. */\n fileName: string;\n info: ExportInfo[];\n\n /** Date and time the data was generated. */\n generatedAt: Date;\n branding: ExportBranding;\n sheets: ExportSheet[];\n\n /** Locale of the texts and of the number format of the file. Default: `en-US`. */\n locale?: KitLocale;\n\n /** Texts that replace the ones of the locale (e.g. the ones the app overrides in the `KitProvider`). */\n messages?: Partial<ExportMessages>;\n};\n\n/** Format of the numbers of a column that defines none. */\nexport const DEFAULT_NUMBER_FORMAT: NumberFormat = { decimals: 2 };\n\n/** Types of cell, after being normalized by {@link classifyCell}. */\nexport type ClassifiedCell =\n | { kind: 'empty' }\n | { kind: 'text'; text: string }\n | { kind: 'number'; value: number; format: NumberFormat }\n | { kind: 'invalid'; text: string };\n\n/**\n * Creates a cell with an invalid result.\n * @param text text shown instead of the value; defaults to the text of the default locale\n * @return the invalid cell\n */\nexport function invalidCell(text: string = DEFAULT_MESSAGES.export.invalidCell): InvalidCell {\n return { invalid: true, text };\n}\n\n/**\n * Tells whether the cell is an invalid result.\n * @param cell cell to check\n */\nexport function isInvalidCell(cell: ExportCell): cell is InvalidCell {\n return typeof cell === 'object' && 'invalid' in cell;\n}\n\n/**\n * Classifies a cell, so that every format handles each type of value the same way. A `NaN` number is treated as\n * absent (empty cell), and `Infinity` as invalid (e.g. a division by zero).\n * @param cell cell to classify\n * @param columnFormat format of the column of the cell, used when the cell is a number without its own format\n * @param invalidText text of an infinite number; defaults to the text of the default locale\n * @return the type and the value of the cell\n */\nexport function classifyCell(\n cell: ExportCell,\n columnFormat: NumberFormat = DEFAULT_NUMBER_FORMAT,\n invalidText: string = DEFAULT_MESSAGES.export.invalidCell\n): ClassifiedCell {\n if (cell === undefined) return { kind: 'empty' };\n if (typeof cell === 'string') return { kind: 'text', text: cell };\n if (isInvalidCell(cell)) return { kind: 'invalid', text: cell.text };\n\n const { value, format } = typeof cell === 'number' ? { value: cell, format: columnFormat } : cell;\n if (Number.isNaN(value)) return { kind: 'empty' };\n if (!Number.isFinite(value)) return { kind: 'invalid', text: invalidText };\n\n return { kind: 'number', value, format };\n}\n"],"mappings":";;;;AAoHA,IAAa,wBAAsC,EAAE,UAAU,EAAE;;;;;;AAcjE,SAAgB,YAAY,OAAe,iBAAiB,OAAO,aAA0B;CACzF,OAAO;EAAE,SAAS;EAAM;CAAK;AACjC;;;;;AAMA,SAAgB,cAAc,MAAuC;CACjE,OAAO,OAAO,SAAS,YAAY,aAAa;AACpD;;;;;;;;;AAUA,SAAgB,aACZ,MACA,eAA6B,uBAC7B,cAAsB,iBAAiB,OAAO,aAChC;CACd,IAAI,SAAS,KAAA,GAAW,OAAO,EAAE,MAAM,QAAQ;CAC/C,IAAI,OAAO,SAAS,UAAU,OAAO;EAAE,MAAM;EAAQ,MAAM;CAAK;CAChE,IAAI,cAAc,IAAI,GAAG,OAAO;EAAE,MAAM;EAAW,MAAM,KAAK;CAAK;CAEnE,MAAM,EAAE,OAAO,WAAW,OAAO,SAAS,WAAW;EAAE,OAAO;EAAM,QAAQ;CAAa,IAAI;CAC7F,IAAI,OAAO,MAAM,KAAK,GAAG,OAAO,EAAE,MAAM,QAAQ;CAChD,IAAI,CAAC,OAAO,SAAS,KAAK,GAAG,OAAO;EAAE,MAAM;EAAW,MAAM;CAAY;CAEzE,OAAO;EAAE,MAAM;EAAU;EAAO;CAAO;AAC3C"}
@@ -0,0 +1,9 @@
1
+ import { ExportDocument } from './ExportDocument';
2
+ import { ExportFormat } from './ExportFormat';
3
+ /**
4
+ * Generates the file of a document in the chosen format and makes the browser download it, named after the document,
5
+ * with the generation date and the extension of the format.
6
+ * @param document data to export
7
+ * @param format format of the file
8
+ */
9
+ export declare function downloadExport(document: ExportDocument, format: ExportFormat): Promise<void>;
@@ -0,0 +1,19 @@
1
+ "use client";
2
+ import { exportFileName } from "./ExportFileName.js";
3
+ import { exportMessages } from "./ExportTexts.js";
4
+ import { downloadBlob } from "../util/DownloadUtil.js";
5
+ // src/export/ExportDownload.ts
6
+ /**
7
+ * Generates the file of a document in the chosen format and makes the browser download it, named after the document,
8
+ * with the generation date and the extension of the format.
9
+ * @param document data to export
10
+ * @param format format of the file
11
+ */
12
+ async function downloadExport(document, format) {
13
+ const blob = await format.generate(document);
14
+ const defaultName = exportMessages(document).defaultFileName;
15
+ downloadBlob(blob, exportFileName(document.fileName, document.generatedAt, format.extension, defaultName));
16
+ }
17
+ export { downloadExport };
18
+
19
+ //# sourceMappingURL=ExportDownload.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportDownload.js","names":[],"sources":["../../src/export/ExportDownload.ts"],"sourcesContent":["import { ExportDocument } from './ExportDocument';\nimport { exportFileName } from './ExportFileName';\nimport { ExportFormat } from './ExportFormat';\nimport { exportMessages } from './ExportTexts';\nimport { downloadBlob } from '../util/DownloadUtil';\n\n/**\n * Generates the file of a document in the chosen format and makes the browser download it, named after the document,\n * with the generation date and the extension of the format.\n * @param document data to export\n * @param format format of the file\n */\nexport async function downloadExport(document: ExportDocument, format: ExportFormat): Promise<void> {\n const blob = await format.generate(document);\n const defaultName = exportMessages(document).defaultFileName;\n downloadBlob(blob, exportFileName(document.fileName, document.generatedAt, format.extension, defaultName));\n}\n"],"mappings":";;;;;;;;;;;AAYA,eAAsB,eAAe,UAA0B,QAAqC;CAChG,MAAM,OAAO,MAAM,OAAO,SAAS,QAAQ;CAC3C,MAAM,cAAc,eAAe,QAAQ,CAAC,CAAC;CAC7C,aAAa,MAAM,eAAe,SAAS,UAAU,SAAS,aAAa,OAAO,WAAW,WAAW,CAAC;AAC7G"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Builds the name of the exported file: the base name without accents or invalid characters, the generation date and
3
+ * the extension (e.g. "sales-north-2026-10-20.xlsx"). Without accents, the name works in any system and e-mail
4
+ * attachment.
5
+ * @param baseName desired name, without date or extension
6
+ * @param generatedAt date the data was generated
7
+ * @param extension extension of the format, without the dot
8
+ * @param defaultName name used when the base name has no valid character; defaults to the one of the default locale
9
+ * @return the name of the file
10
+ */
11
+ export declare function exportFileName(baseName: string, generatedAt: Date, extension: string, defaultName?: string): string;
@@ -0,0 +1,24 @@
1
+ "use client";
2
+ import { DEFAULT_MESSAGES } from "../i18n/resolveMessages.js";
3
+ import { formatDateToISO } from "../util/DateUtil.js";
4
+ // src/export/ExportFileName.ts
5
+ /** Characters not accepted in file names by some operating system, plus the spaces. */
6
+ var INVALID_FILE_NAME_CHARS = /[\s/\\:*?"<>|]+/g;
7
+ /** Accent marks, separated from the letters by the NFD normalization. */
8
+ var DIACRITICS = /\p{Diacritic}/gu;
9
+ /**
10
+ * Builds the name of the exported file: the base name without accents or invalid characters, the generation date and
11
+ * the extension (e.g. "sales-north-2026-10-20.xlsx"). Without accents, the name works in any system and e-mail
12
+ * attachment.
13
+ * @param baseName desired name, without date or extension
14
+ * @param generatedAt date the data was generated
15
+ * @param extension extension of the format, without the dot
16
+ * @param defaultName name used when the base name has no valid character; defaults to the one of the default locale
17
+ * @return the name of the file
18
+ */
19
+ function exportFileName(baseName, generatedAt, extension, defaultName = DEFAULT_MESSAGES.export.defaultFileName) {
20
+ return `${baseName.normalize("NFD").replace(DIACRITICS, "").replace(INVALID_FILE_NAME_CHARS, "-").replace(/-+/g, "-").replace(/^-|-$/g, "").toLowerCase() || defaultName}-${formatDateToISO(generatedAt)}.${extension}`;
21
+ }
22
+ export { exportFileName };
23
+
24
+ //# sourceMappingURL=ExportFileName.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportFileName.js","names":[],"sources":["../../src/export/ExportFileName.ts"],"sourcesContent":["import { DEFAULT_MESSAGES } from '../i18n/resolveMessages';\nimport { formatDateToISO } from '../util/DateUtil';\n\n/** Characters not accepted in file names by some operating system, plus the spaces. */\nconst INVALID_FILE_NAME_CHARS = /[\\s/\\\\:*?\"<>|]+/g;\n\n/** Accent marks, separated from the letters by the NFD normalization. */\nconst DIACRITICS = /\\p{Diacritic}/gu;\n\n/**\n * Builds the name of the exported file: the base name without accents or invalid characters, the generation date and\n * the extension (e.g. \"sales-north-2026-10-20.xlsx\"). Without accents, the name works in any system and e-mail\n * attachment.\n * @param baseName desired name, without date or extension\n * @param generatedAt date the data was generated\n * @param extension extension of the format, without the dot\n * @param defaultName name used when the base name has no valid character; defaults to the one of the default locale\n * @return the name of the file\n */\nexport function exportFileName(\n baseName: string,\n generatedAt: Date,\n extension: string,\n defaultName: string = DEFAULT_MESSAGES.export.defaultFileName\n): string {\n const name = baseName\n .normalize('NFD')\n .replace(DIACRITICS, '')\n .replace(INVALID_FILE_NAME_CHARS, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '')\n .toLowerCase();\n\n return `${name || defaultName}-${formatDateToISO(generatedAt)}.${extension}`;\n}\n"],"mappings":";;;;;AAIA,IAAM,0BAA0B;;AAGhC,IAAM,aAAa;;;;;;;;;;;AAYnB,SAAgB,eACZ,UACA,aACA,WACA,cAAsB,iBAAiB,OAAO,iBACxC;CASN,OAAO,GARM,SACR,UAAU,KAAK,CAAC,CAChB,QAAQ,YAAY,EAAE,CAAC,CACvB,QAAQ,yBAAyB,GAAG,CAAC,CACrC,QAAQ,OAAO,GAAG,CAAC,CACnB,QAAQ,UAAU,EAAE,CAAC,CACrB,YAEK,KAAQ,YAAY,GAAG,gBAAgB,WAAW,EAAE,GAAG;AACrE"}
@@ -0,0 +1,30 @@
1
+ import { ExportDocument } from './ExportDocument';
2
+ /**
3
+ * Contract every export format must follow (Strategy pattern). Each format generates the file from the same
4
+ * {@link ExportDocument}, so whoever exports chooses the format without knowing the details of each one. To add a
5
+ * format, create the implementation and register it in `ExportFormats.ts`.
6
+ * @author Manoel Campos
7
+ */
8
+ export interface ExportFormat {
9
+ /** Unique id of the format (e.g. `xlsx`), used as the key of the format in menus. */
10
+ readonly id: string;
11
+ /** Name of the format shown to the user (e.g. "Excel (.xlsx)"), the same in every language. */
12
+ readonly label: string;
13
+ /** Extension of the file, without the dot. */
14
+ readonly extension: string;
15
+ /** MIME type of the file. */
16
+ readonly mimeType: string;
17
+ /**
18
+ * Whether the format stores many sheets in a single file. A format without sheets (e.g. CSV) accepts only
19
+ * documents with one sheet, so whoever exports must build the document according to this value.
20
+ */
21
+ readonly multipleSheets: boolean;
22
+ /**
23
+ * Generates the file.
24
+ * @param document data to export
25
+ * @return the content of the file
26
+ * @throws Error if the document cannot be exported in the format: without any sheet, with many sheets in a
27
+ * format without sheets, or with a row with more cells than columns
28
+ */
29
+ generate(document: ExportDocument): Promise<Blob>;
30
+ }
@@ -0,0 +1 @@
1
+ "use client";
@@ -0,0 +1,12 @@
1
+ import { CsvFormat } from './csv/CsvFormat';
2
+ import { ExportFormat } from './ExportFormat';
3
+ import { XlsxFormat } from './xlsx/XlsxFormat';
4
+ /**
5
+ * Single instances of the export formats. The formats have no state, so they can be shared by all screens.
6
+ * @author Manoel Campos
7
+ */
8
+ /** Excel format (`.xlsx`), with a sheet in the file for each sheet of the document. */
9
+ export declare const XLSX_FORMAT: XlsxFormat;
10
+ export declare const CSV_FORMAT: CsvFormat;
11
+ /** All built-in export formats, in the order they appear in an export menu. */
12
+ export declare const EXPORT_FORMATS: readonly ExportFormat[];
@@ -0,0 +1,16 @@
1
+ "use client";
2
+ import { CsvFormat } from "./csv/CsvFormat.js";
3
+ import { XlsxFormat } from "./xlsx/XlsxFormat.js";
4
+ // src/export/ExportFormats.ts
5
+ /**
6
+ * Single instances of the export formats. The formats have no state, so they can be shared by all screens.
7
+ * @author Manoel Campos
8
+ */
9
+ /** Excel format (`.xlsx`), with a sheet in the file for each sheet of the document. */
10
+ var XLSX_FORMAT = new XlsxFormat();
11
+ var CSV_FORMAT = new CsvFormat();
12
+ /** All built-in export formats, in the order they appear in an export menu. */
13
+ var EXPORT_FORMATS = [XLSX_FORMAT, CSV_FORMAT];
14
+ export { CSV_FORMAT, EXPORT_FORMATS, XLSX_FORMAT };
15
+
16
+ //# sourceMappingURL=ExportFormats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportFormats.js","names":[],"sources":["../../src/export/ExportFormats.ts"],"sourcesContent":["import { CsvFormat } from './csv/CsvFormat';\nimport { ExportFormat } from './ExportFormat';\nimport { XlsxFormat } from './xlsx/XlsxFormat';\n\n/**\n * Single instances of the export formats. The formats have no state, so they can be shared by all screens.\n * @author Manoel Campos\n */\n\n/** Excel format (`.xlsx`), with a sheet in the file for each sheet of the document. */\nexport const XLSX_FORMAT = new XlsxFormat();\nexport const CSV_FORMAT = new CsvFormat();\n\n/** All built-in export formats, in the order they appear in an export menu. */\nexport const EXPORT_FORMATS: readonly ExportFormat[] = [XLSX_FORMAT, CSV_FORMAT];\n"],"mappings":";;;;;;;;;AAUA,IAAa,cAAc,IAAI,WAAW;AAC1C,IAAa,aAAa,IAAI,UAAU;;AAGxC,IAAa,iBAA0C,CAAC,aAAa,UAAU"}
@@ -0,0 +1,14 @@
1
+ import { ExportMessages } from '../i18n/KitMessages';
2
+ import { ExportDocument } from './ExportDocument';
3
+ /**
4
+ * Returns the texts of an exported document: the ones of its locale, with the ones the document overrides.
5
+ * @param document exported document
6
+ * @return the texts shown in the file
7
+ */
8
+ export declare function exportMessages(document: Pick<ExportDocument, 'locale' | 'messages'>): ExportMessages;
9
+ /**
10
+ * Returns the locale of an exported document.
11
+ * @param document exported document
12
+ * @return the locale of the document, or the default one
13
+ */
14
+ export declare function exportLocale(document: Pick<ExportDocument, 'locale'>): string;
@@ -0,0 +1,23 @@
1
+ "use client";
2
+ import "../i18n/KitLocale.js";
3
+ import { resolveMessages } from "../i18n/resolveMessages.js";
4
+ // src/export/ExportTexts.ts
5
+ /**
6
+ * Returns the texts of an exported document: the ones of its locale, with the ones the document overrides.
7
+ * @param document exported document
8
+ * @return the texts shown in the file
9
+ */
10
+ function exportMessages(document) {
11
+ return resolveMessages(document.locale, { export: document.messages }).export;
12
+ }
13
+ /**
14
+ * Returns the locale of an exported document.
15
+ * @param document exported document
16
+ * @return the locale of the document, or the default one
17
+ */
18
+ function exportLocale(document) {
19
+ return document.locale ?? "en-US";
20
+ }
21
+ export { exportLocale, exportMessages };
22
+
23
+ //# sourceMappingURL=ExportTexts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ExportTexts.js","names":[],"sources":["../../src/export/ExportTexts.ts"],"sourcesContent":["import { DEFAULT_LOCALE } from '../i18n/KitLocale';\nimport { ExportMessages } from '../i18n/KitMessages';\nimport { resolveMessages } from '../i18n/resolveMessages';\nimport { ExportDocument } from './ExportDocument';\n\n/**\n * Returns the texts of an exported document: the ones of its locale, with the ones the document overrides.\n * @param document exported document\n * @return the texts shown in the file\n */\nexport function exportMessages(document: Pick<ExportDocument, 'locale' | 'messages'>): ExportMessages {\n return resolveMessages(document.locale, { export: document.messages }).export;\n}\n\n/**\n * Returns the locale of an exported document.\n * @param document exported document\n * @return the locale of the document, or the default one\n */\nexport function exportLocale(document: Pick<ExportDocument, 'locale'>): string {\n return document.locale ?? DEFAULT_LOCALE;\n}\n"],"mappings":";;;;;;;;;AAUA,SAAgB,eAAe,UAAuE;CAClG,OAAO,gBAAgB,SAAS,QAAQ,EAAE,QAAQ,SAAS,SAAS,CAAC,CAAC,CAAC;AAC3E;;;;;;AAOA,SAAgB,aAAa,UAAkD;CAC3E,OAAO,SAAS,UAAA;AACpB"}
@@ -0,0 +1,41 @@
1
+ import { ExportDocument, ExportSheet } from '../ExportDocument';
2
+ import { ExportFormat } from '../ExportFormat';
3
+ /**
4
+ * Column separator used when the decimal separator of the locale is the comma (e.g. `pt-BR`), which is what Excel
5
+ * expects in these languages.
6
+ */
7
+ export declare const CSV_SEPARATOR = ";";
8
+ /** Column separator used when the decimal separator of the locale is not the comma (e.g. `en-US`). */
9
+ export declare const CSV_COMMA_SEPARATOR = ",";
10
+ /**
11
+ * Returns the column separator of the CSV for a locale: `;` when the decimal separator is the comma, so numbers do not
12
+ * clash with the separator, or `,` otherwise.
13
+ * @param locale locale of the number format
14
+ */
15
+ export declare function csvSeparator(locale: string): string;
16
+ /**
17
+ * Exports to CSV, as Excel in the language of the locale expects: the decimal separator of the locale, a column
18
+ * separator that does not clash with it (see {@link csvSeparator}), no thousands separator and UTF-8 with BOM. The CSV
19
+ * has only the table (header and rows), without the title or the context, so other programs can also read the
20
+ * columns. Having no sheets, it accepts only documents with one sheet.
21
+ *
22
+ * The CSV is text, so each number has the decimal places of its format (the same as on the screen), rounded. The
23
+ * `.xlsx` stores the full value and just shows it with these places.
24
+ * @author Manoel Campos
25
+ */
26
+ export declare class CsvFormat implements ExportFormat {
27
+ readonly id = "csv";
28
+ readonly label = "CSV";
29
+ readonly extension = "csv";
30
+ readonly mimeType = "text/csv;charset=utf-8";
31
+ readonly multipleSheets = false;
32
+ generate(document: ExportDocument): Promise<Blob>;
33
+ }
34
+ /**
35
+ * Builds the CSV text of a sheet.
36
+ * @param sheet columns and rows of the table
37
+ * @param locale locale of the number format, which also defines the column separator; defaults to `en-US`
38
+ * @param invalidText text of an infinite number
39
+ * @return the header and the rows, each one ended by a line break
40
+ */
41
+ export declare function csvText(sheet: ExportSheet, locale?: string, invalidText?: string): string;
@@ -0,0 +1,91 @@
1
+ "use client";
2
+ import { cellText } from "../ExportCellText.js";
3
+ import { classifyCell } from "../ExportDocument.js";
4
+ import { DEFAULT_LOCALE } from "../../i18n/KitLocale.js";
5
+ import { exportLocale, exportMessages } from "../ExportTexts.js";
6
+ // src/export/csv/CsvFormat.ts
7
+ /**
8
+ * Column separator used when the decimal separator of the locale is the comma (e.g. `pt-BR`), which is what Excel
9
+ * expects in these languages.
10
+ */
11
+ var CSV_SEPARATOR = ";";
12
+ /** Column separator used when the decimal separator of the locale is not the comma (e.g. `en-US`). */
13
+ var CSV_COMMA_SEPARATOR = ",";
14
+ /** Line break of the CSV ({@link https://www.rfc-editor.org/rfc/rfc4180 RFC 4180}). */
15
+ var LINE_BREAK = "\r\n";
16
+ /** UTF-8 byte order mark (BOM): without it, Excel opens the file with garbled accents. */
17
+ var UTF8_BOM = "";
18
+ /**
19
+ * Start of a text that Excel would read as a formula (`=`, `+`, `-`, `@`, tab or CR). A name typed by a user as
20
+ * `=HYPERLINK(...)` would become a formula when the file is opened (CSV injection), so the text gets a leading
21
+ * apostrophe.
22
+ */
23
+ var FORMULA_START = /^[=+\-@\t\r]/;
24
+ /**
25
+ * Returns the column separator of the CSV for a locale: `;` when the decimal separator is the comma, so numbers do not
26
+ * clash with the separator, or `,` otherwise.
27
+ * @param locale locale of the number format
28
+ */
29
+ function csvSeparator(locale) {
30
+ return new Intl.NumberFormat(locale).formatToParts(1.1).find((part) => part.type === "decimal")?.value === "," ? ";" : ",";
31
+ }
32
+ /**
33
+ * Exports to CSV, as Excel in the language of the locale expects: the decimal separator of the locale, a column
34
+ * separator that does not clash with it (see {@link csvSeparator}), no thousands separator and UTF-8 with BOM. The CSV
35
+ * has only the table (header and rows), without the title or the context, so other programs can also read the
36
+ * columns. Having no sheets, it accepts only documents with one sheet.
37
+ *
38
+ * The CSV is text, so each number has the decimal places of its format (the same as on the screen), rounded. The
39
+ * `.xlsx` stores the full value and just shows it with these places.
40
+ * @author Manoel Campos
41
+ */
42
+ var CsvFormat = class {
43
+ id = "csv";
44
+ label = "CSV";
45
+ extension = "csv";
46
+ mimeType = "text/csv;charset=utf-8";
47
+ multipleSheets = false;
48
+ async generate(document) {
49
+ if (document.sheets.length !== 1) throw new Error(`A CSV file has a single sheet, but the document has ${document.sheets.length}.`);
50
+ const text = csvText(document.sheets[0], exportLocale(document), exportMessages(document).invalidCell);
51
+ return new Blob([UTF8_BOM + text], { type: this.mimeType });
52
+ }
53
+ };
54
+ /**
55
+ * Builds the CSV text of a sheet.
56
+ * @param sheet columns and rows of the table
57
+ * @param locale locale of the number format, which also defines the column separator; defaults to `en-US`
58
+ * @param invalidText text of an infinite number
59
+ * @return the header and the rows, each one ended by a line break
60
+ */
61
+ function csvText(sheet, locale = DEFAULT_LOCALE, invalidText) {
62
+ const separator = csvSeparator(locale);
63
+ const field = (text) => csvField(text, separator);
64
+ return [sheet.columns.map((column) => field(column.header)), ...sheet.rows.map((row) => sheet.columns.map((column, i) => csvCell(classifyCell(row[i], column.format, invalidText), locale, field)))].map((fields) => fields.join(separator) + LINE_BREAK).join("");
65
+ }
66
+ /**
67
+ * Converts a cell to the CSV field. Numbers have the decimal separator of the locale and no thousands separator, which
68
+ * Excel in that language reads as a number (and a percentage, such as "85,5%", as 0.855). Texts, including the one of
69
+ * an invalid cell, go through the text field function.
70
+ * @param cell cell already classified
71
+ * @param locale locale of the number format
72
+ * @param field function that prepares a text field
73
+ * @return the CSV field
74
+ */
75
+ function csvCell(cell, locale, field) {
76
+ const text = cellText(cell, false, locale);
77
+ return cell.kind === "number" ? text : field(text);
78
+ }
79
+ /**
80
+ * Prepares a text for the CSV: prevents it from becoming a formula and quotes it if needed.
81
+ * @param text text of the field
82
+ * @param separator column separator, which requires quotes when present in the text
83
+ * @return the CSV field
84
+ */
85
+ function csvField(text, separator) {
86
+ const safeText = FORMULA_START.test(text) ? `'${text}` : text;
87
+ return safeText.includes(separator) || /["\r\n]/.test(safeText) ? `"${safeText.replaceAll("\"", "\"\"")}"` : safeText;
88
+ }
89
+ export { CSV_COMMA_SEPARATOR, CSV_SEPARATOR, CsvFormat, csvSeparator, csvText };
90
+
91
+ //# sourceMappingURL=CsvFormat.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CsvFormat.js","names":[],"sources":["../../../src/export/csv/CsvFormat.ts"],"sourcesContent":["import { cellText } from '../ExportCellText';\nimport { ClassifiedCell, classifyCell, ExportDocument, ExportSheet } from '../ExportDocument';\nimport { ExportFormat } from '../ExportFormat';\nimport { DEFAULT_LOCALE } from '../../i18n/KitLocale';\nimport { exportLocale, exportMessages } from '../ExportTexts';\n\n/**\n * Column separator used when the decimal separator of the locale is the comma (e.g. `pt-BR`), which is what Excel\n * expects in these languages.\n */\nexport const CSV_SEPARATOR = ';';\n\n/** Column separator used when the decimal separator of the locale is not the comma (e.g. `en-US`). */\nexport const CSV_COMMA_SEPARATOR = ',';\n\n/** Line break of the CSV ({@link https://www.rfc-editor.org/rfc/rfc4180 RFC 4180}). */\nconst LINE_BREAK = '\\r\\n';\n\n/** UTF-8 byte order mark (BOM): without it, Excel opens the file with garbled accents. */\nconst UTF8_BOM = '';\n\n/**\n * Start of a text that Excel would read as a formula (`=`, `+`, `-`, `@`, tab or CR). A name typed by a user as\n * `=HYPERLINK(...)` would become a formula when the file is opened (CSV injection), so the text gets a leading\n * apostrophe.\n */\nconst FORMULA_START = /^[=+\\-@\\t\\r]/;\n\n/**\n * Returns the column separator of the CSV for a locale: `;` when the decimal separator is the comma, so numbers do not\n * clash with the separator, or `,` otherwise.\n * @param locale locale of the number format\n */\nexport function csvSeparator(locale: string): string {\n const decimal = new Intl.NumberFormat(locale).formatToParts(1.1).find(part => part.type === 'decimal')?.value;\n\n return decimal === ',' ? CSV_SEPARATOR : CSV_COMMA_SEPARATOR;\n}\n\n/**\n * Exports to CSV, as Excel in the language of the locale expects: the decimal separator of the locale, a column\n * separator that does not clash with it (see {@link csvSeparator}), no thousands separator and UTF-8 with BOM. The CSV\n * has only the table (header and rows), without the title or the context, so other programs can also read the\n * columns. Having no sheets, it accepts only documents with one sheet.\n *\n * The CSV is text, so each number has the decimal places of its format (the same as on the screen), rounded. The\n * `.xlsx` stores the full value and just shows it with these places.\n * @author Manoel Campos\n */\nexport class CsvFormat implements ExportFormat {\n readonly id = 'csv';\n readonly label = 'CSV';\n readonly extension = 'csv';\n readonly mimeType = 'text/csv;charset=utf-8';\n readonly multipleSheets = false;\n\n async generate(document: ExportDocument): Promise<Blob> {\n if (document.sheets.length !== 1) {\n throw new Error(`A CSV file has a single sheet, but the document has ${document.sheets.length}.`);\n }\n\n const text = csvText(document.sheets[0], exportLocale(document), exportMessages(document).invalidCell);\n return new Blob([UTF8_BOM + text], { type: this.mimeType });\n }\n}\n\n/**\n * Builds the CSV text of a sheet.\n * @param sheet columns and rows of the table\n * @param locale locale of the number format, which also defines the column separator; defaults to `en-US`\n * @param invalidText text of an infinite number\n * @return the header and the rows, each one ended by a line break\n */\nexport function csvText(sheet: ExportSheet, locale: string = DEFAULT_LOCALE, invalidText?: string): string {\n const separator = csvSeparator(locale);\n const field = (text: string) => csvField(text, separator);\n const header = sheet.columns.map(column => field(column.header));\n const rows = sheet.rows.map(row =>\n sheet.columns.map((column, i) => csvCell(classifyCell(row[i], column.format, invalidText), locale, field))\n );\n\n return [header, ...rows].map(fields => fields.join(separator) + LINE_BREAK).join('');\n}\n\n/**\n * Converts a cell to the CSV field. Numbers have the decimal separator of the locale and no thousands separator, which\n * Excel in that language reads as a number (and a percentage, such as \"85,5%\", as 0.855). Texts, including the one of\n * an invalid cell, go through the text field function.\n * @param cell cell already classified\n * @param locale locale of the number format\n * @param field function that prepares a text field\n * @return the CSV field\n */\nfunction csvCell(cell: ClassifiedCell, locale: string, field: (text: string) => string): string {\n const text = cellText(cell, false, locale);\n\n return cell.kind === 'number' ? text : field(text);\n}\n\n/**\n * Prepares a text for the CSV: prevents it from becoming a formula and quotes it if needed.\n * @param text text of the field\n * @param separator column separator, which requires quotes when present in the text\n * @return the CSV field\n */\nfunction csvField(text: string, separator: string): string {\n const safeText = FORMULA_START.test(text) ? `'${text}` : text;\n const needsQuotes = safeText.includes(separator) || /[\"\\r\\n]/.test(safeText);\n\n return needsQuotes ? `\"${safeText.replaceAll('\"', '\"\"')}\"` : safeText;\n}\n"],"mappings":";;;;;;;;;;AAUA,IAAa,gBAAgB;;AAG7B,IAAa,sBAAsB;;AAGnC,IAAM,aAAa;;AAGnB,IAAM,WAAW;;;;;;AAOjB,IAAM,gBAAgB;;;;;;AAOtB,SAAgB,aAAa,QAAwB;CAGjD,OAFgB,IAAI,KAAK,aAAa,MAAM,CAAC,CAAC,cAAc,GAAG,CAAC,CAAC,MAAK,SAAQ,KAAK,SAAS,SAAS,CAAC,EAAE,UAErF,MAAA,MAAA;AACvB;;;;;;;;;;;AAYA,IAAa,YAAb,MAA+C;CAC3C,KAAc;CACd,QAAiB;CACjB,YAAqB;CACrB,WAAoB;CACpB,iBAA0B;CAE1B,MAAM,SAAS,UAAyC;EACpD,IAAI,SAAS,OAAO,WAAW,GAC3B,MAAM,IAAI,MAAM,uDAAuD,SAAS,OAAO,OAAO,EAAE;EAGpG,MAAM,OAAO,QAAQ,SAAS,OAAO,IAAI,aAAa,QAAQ,GAAG,eAAe,QAAQ,CAAC,CAAC,WAAW;EACrG,OAAO,IAAI,KAAK,CAAC,WAAW,IAAI,GAAG,EAAE,MAAM,KAAK,SAAS,CAAC;CAC9D;AACJ;;;;;;;;AASA,SAAgB,QAAQ,OAAoB,SAAiB,gBAAgB,aAA8B;CACvG,MAAM,YAAY,aAAa,MAAM;CACrC,MAAM,SAAS,SAAiB,SAAS,MAAM,SAAS;CAMxD,OAAO,CALQ,MAAM,QAAQ,KAAI,WAAU,MAAM,OAAO,MAAM,CAKtD,GAAQ,GAJH,MAAM,KAAK,KAAI,QACxB,MAAM,QAAQ,KAAK,QAAQ,MAAM,QAAQ,aAAa,IAAI,IAAI,OAAO,QAAQ,WAAW,GAAG,QAAQ,KAAK,CAAC,CAG1F,CAAI,CAAC,CAAC,KAAI,WAAU,OAAO,KAAK,SAAS,IAAI,UAAU,CAAC,CAAC,KAAK,EAAE;AACvF;;;;;;;;;;AAWA,SAAS,QAAQ,MAAsB,QAAgB,OAAyC;CAC5F,MAAM,OAAO,SAAS,MAAM,OAAO,MAAM;CAEzC,OAAO,KAAK,SAAS,WAAW,OAAO,MAAM,IAAI;AACrD;;;;;;;AAQA,SAAS,SAAS,MAAc,WAA2B;CACvD,MAAM,WAAW,cAAc,KAAK,IAAI,IAAI,IAAI,SAAS;CAGzD,OAFoB,SAAS,SAAS,SAAS,KAAK,UAAU,KAAK,QAAQ,IAEtD,IAAI,SAAS,WAAW,MAAK,MAAI,EAAE,KAAK;AACjE"}
@@ -0,0 +1,35 @@
1
+ import type { Workbook } from 'exceljs';
2
+ import { ExportDocument } from '../ExportDocument';
3
+ import { ExportFormat } from '../ExportFormat';
4
+ import { XlsxColors } from './XlsxStyle';
5
+ /** Options of an {@link XlsxFormat}. */
6
+ export type XlsxFormatOptions = {
7
+ /** Colors of the file (e.g. the brand colors of the app); the ones not given use the defaults. */
8
+ colors?: Partial<XlsxColors>;
9
+ };
10
+ /**
11
+ * Exports to Excel (`.xlsx`) with [ExcelJS](https://github.com/exceljs/exceljs): a sheet in the file for each sheet
12
+ * of the document, with styles, the logo and the numbers in a numeric format (not text).
13
+ *
14
+ * ExcelJS is loaded on demand (dynamic `import()`), like ECharts: imported statically, it would be in the bundle of
15
+ * every page that can export, even if the user exports nothing.
16
+ * @author Manoel Campos
17
+ */
18
+ export declare class XlsxFormat implements ExportFormat {
19
+ readonly id = "xlsx";
20
+ readonly label = "Excel (.xlsx)";
21
+ readonly extension = "xlsx";
22
+ readonly mimeType = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
23
+ readonly multipleSheets = true;
24
+ private readonly styles;
25
+ /** @param options options of the format, such as the colors of the file */
26
+ constructor(options?: XlsxFormatOptions);
27
+ generate(document: ExportDocument): Promise<Blob>;
28
+ /**
29
+ * Builds the workbook with a sheet for each sheet of the document.
30
+ * @param document data to export
31
+ * @return the workbook ready to be written
32
+ * @throws Error if the document has no sheets
33
+ */
34
+ buildWorkbook(document: ExportDocument): Promise<Workbook>;
35
+ }