@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.
- package/LICENSE +21 -0
- package/README.md +475 -2
- package/dist/component/atom/AppMain/App.module.js +7 -0
- package/dist/component/atom/AppMain/App.module.js.map +1 -0
- package/dist/component/atom/AppMain/AppMain.d.ts +7 -0
- package/dist/component/atom/AppMain/AppMain.js +14 -0
- package/dist/component/atom/AppMain/AppMain.js.map +1 -0
- package/dist/component/atom/CancelEditButton/CancelEditButton.d.ts +6 -0
- package/dist/component/atom/CancelEditButton/CancelEditButton.js +24 -0
- package/dist/component/atom/CancelEditButton/CancelEditButton.js.map +1 -0
- package/dist/component/atom/ConfirmEditButton/ConfirmEditButton.d.ts +13 -0
- package/dist/component/atom/ConfirmEditButton/ConfirmEditButton.js +30 -0
- package/dist/component/atom/ConfirmEditButton/ConfirmEditButton.js.map +1 -0
- package/dist/component/atom/DateField/DateField.d.ts +7 -0
- package/dist/component/atom/DateField/DateField.js +21 -0
- package/dist/component/atom/DateField/DateField.js.map +1 -0
- package/dist/component/atom/EditValueButton/EditValueButton.d.ts +6 -0
- package/dist/component/atom/EditValueButton/EditValueButton.js +24 -0
- package/dist/component/atom/EditValueButton/EditValueButton.js.map +1 -0
- package/dist/component/atom/ErrorAlert/ErrorAlert.d.ts +8 -0
- package/dist/component/atom/ErrorAlert/ErrorAlert.js +21 -0
- package/dist/component/atom/ErrorAlert/ErrorAlert.js.map +1 -0
- package/dist/component/atom/Surface/Surface.d.ts +20 -0
- package/dist/component/atom/Surface/Surface.js +15 -0
- package/dist/component/atom/Surface/Surface.js.map +1 -0
- package/dist/component/molecule/Breadcrumb/Breadcrumb.d.ts +12 -0
- package/dist/component/molecule/Breadcrumb/Breadcrumb.js +38 -0
- package/dist/component/molecule/Breadcrumb/Breadcrumb.js.map +1 -0
- package/dist/component/molecule/ExportMenuButton/ExportMenuButton.d.ts +25 -0
- package/dist/component/molecule/ExportMenuButton/ExportMenuButton.js +49 -0
- package/dist/component/molecule/ExportMenuButton/ExportMenuButton.js.map +1 -0
- package/dist/component/molecule/PaperCard/PaperCard.d.ts +7 -0
- package/dist/component/molecule/PaperCard/PaperCard.js +17 -0
- package/dist/component/molecule/PaperCard/PaperCard.js.map +1 -0
- package/dist/component/molecule/PrintSection/PrintSection.d.ts +14 -0
- package/dist/component/molecule/PrintSection/PrintSection.js +29 -0
- package/dist/component/molecule/PrintSection/PrintSection.js.map +1 -0
- package/dist/component/molecule/SelectField/SelectField.d.ts +32 -0
- package/dist/component/molecule/SelectField/SelectField.js +38 -0
- package/dist/component/molecule/SelectField/SelectField.js.map +1 -0
- package/dist/component/molecule/StatsCard/Stats.module.js +15 -0
- package/dist/component/molecule/StatsCard/Stats.module.js.map +1 -0
- package/dist/component/molecule/StatsCard/StatsCard.d.ts +18 -0
- package/dist/component/molecule/StatsCard/StatsCard.js +60 -0
- package/dist/component/molecule/StatsCard/StatsCard.js.map +1 -0
- package/dist/component/organism/DataForm/DataForm.d.ts +26 -0
- package/dist/component/organism/DataForm/DataForm.js +83 -0
- package/dist/component/organism/DataForm/DataForm.js.map +1 -0
- package/dist/component/organism/DataTabList/DataTabList.d.ts +24 -0
- package/dist/component/organism/DataTabList/DataTabList.js +37 -0
- package/dist/component/organism/DataTabList/DataTabList.js.map +1 -0
- package/dist/component/organism/DataTabList/DataTabList.module.js +13 -0
- package/dist/component/organism/DataTabList/DataTabList.module.js.map +1 -0
- package/dist/component/organism/EChart/EChart.d.ts +47 -0
- package/dist/component/organism/EChart/EChart.js +37 -0
- package/dist/component/organism/EChart/EChart.js.map +1 -0
- package/dist/component/organism/EChart/buildEChartOption.d.ts +40 -0
- package/dist/component/organism/EChart/buildEChartOption.js +57 -0
- package/dist/component/organism/EChart/buildEChartOption.js.map +1 -0
- package/dist/component/organism/EChart/chart/BarChart.d.ts +22 -0
- package/dist/component/organism/EChart/chart/BarChart.js +34 -0
- package/dist/component/organism/EChart/chart/BarChart.js.map +1 -0
- package/dist/component/organism/EChart/chart/CartesianChart.d.ts +48 -0
- package/dist/component/organism/EChart/chart/CartesianChart.js +63 -0
- package/dist/component/organism/EChart/chart/CartesianChart.js.map +1 -0
- package/dist/component/organism/EChart/chart/ChartHeader.d.ts +36 -0
- package/dist/component/organism/EChart/chart/ChartHeader.js +105 -0
- package/dist/component/organism/EChart/chart/ChartHeader.js.map +1 -0
- package/dist/component/organism/EChart/chart/ChartSeries.d.ts +50 -0
- package/dist/component/organism/EChart/chart/ChartSeries.js +23 -0
- package/dist/component/organism/EChart/chart/ChartSeries.js.map +1 -0
- package/dist/component/organism/EChart/chart/ChartTexts.d.ts +12 -0
- package/dist/component/organism/EChart/chart/ChartTexts.js +21 -0
- package/dist/component/organism/EChart/chart/ChartTexts.js.map +1 -0
- package/dist/component/organism/EChart/chart/ChartType.d.ts +50 -0
- package/dist/component/organism/EChart/chart/ChartType.js +1 -0
- package/dist/component/organism/EChart/chart/ChartTypeId.d.ts +2 -0
- package/dist/component/organism/EChart/chart/ChartTypeId.js +1 -0
- package/dist/component/organism/EChart/chart/ChartTypes.d.ts +15 -0
- package/dist/component/organism/EChart/chart/ChartTypes.js +24 -0
- package/dist/component/organism/EChart/chart/ChartTypes.js.map +1 -0
- package/dist/component/organism/EChart/chart/DonutChart.d.ts +32 -0
- package/dist/component/organism/EChart/chart/DonutChart.js +111 -0
- package/dist/component/organism/EChart/chart/DonutChart.js.map +1 -0
- package/dist/component/organism/EChart/chart/LineChart.d.ts +11 -0
- package/dist/component/organism/EChart/chart/LineChart.js +20 -0
- package/dist/component/organism/EChart/chart/LineChart.js.map +1 -0
- package/dist/component/organism/EChart/chart/StackedBarChart.d.ts +15 -0
- package/dist/component/organism/EChart/chart/StackedBarChart.js +30 -0
- package/dist/component/organism/EChart/chart/StackedBarChart.js.map +1 -0
- package/dist/component/organism/EChart/chart/UnitPanels.d.ts +63 -0
- package/dist/component/organism/EChart/chart/UnitPanels.js +127 -0
- package/dist/component/organism/EChart/chart/UnitPanels.js.map +1 -0
- package/dist/component/organism/EChart/echartDefaults.d.ts +32 -0
- package/dist/component/organism/EChart/echartDefaults.js +47 -0
- package/dist/component/organism/EChart/echartDefaults.js.map +1 -0
- package/dist/component/organism/EChart/useEChart.d.ts +35 -0
- package/dist/component/organism/EChart/useEChart.js +112 -0
- package/dist/component/organism/EChart/useEChart.js.map +1 -0
- package/dist/component/organism/Navbar/NavItem.d.ts +16 -0
- package/dist/component/organism/Navbar/NavItem.js +1 -0
- package/dist/component/organism/Navbar/Navbar.d.ts +20 -0
- package/dist/component/organism/Navbar/Navbar.js +64 -0
- package/dist/component/organism/Navbar/Navbar.js.map +1 -0
- package/dist/component/organism/Navbar/Navbar.module.js +19 -0
- package/dist/component/organism/Navbar/Navbar.module.js.map +1 -0
- package/dist/component/organism/PageHeader/PageHeader.d.ts +14 -0
- package/dist/component/organism/PageHeader/PageHeader.js +55 -0
- package/dist/component/organism/PageHeader/PageHeader.js.map +1 -0
- package/dist/component/organism/StatsGrid/StatsGrid.d.ts +12 -0
- package/dist/component/organism/StatsGrid/StatsGrid.js +46 -0
- package/dist/component/organism/StatsGrid/StatsGrid.js.map +1 -0
- package/dist/component/organism/StatsGrid/StatsGrid.module.js +17 -0
- package/dist/component/organism/StatsGrid/StatsGrid.module.js.map +1 -0
- package/dist/component/organism/Table/RowActions.d.ts +23 -0
- package/dist/component/organism/Table/RowActions.js +121 -0
- package/dist/component/organism/Table/RowActions.js.map +1 -0
- package/dist/component/organism/Table/Table.d.ts +51 -0
- package/dist/component/organism/Table/Table.js +110 -0
- package/dist/component/organism/Table/Table.js.map +1 -0
- package/dist/component/organism/ViewTable/ColumnComparator.d.ts +11 -0
- package/dist/component/organism/ViewTable/ColumnComparator.js +25 -0
- package/dist/component/organism/ViewTable/ColumnComparator.js.map +1 -0
- package/dist/component/organism/ViewTable/ViewTable.d.ts +53 -0
- package/dist/component/organism/ViewTable/ViewTable.js +115 -0
- package/dist/component/organism/ViewTable/ViewTable.js.map +1 -0
- package/dist/component/organism/ViewTable/useRowKey.d.ts +8 -0
- package/dist/component/organism/ViewTable/useRowKey.js +24 -0
- package/dist/component/organism/ViewTable/useRowKey.js.map +1 -0
- package/dist/component/template/CreateFormPage/CreateFormPage.d.ts +19 -0
- package/dist/component/template/CreateFormPage/CreateFormPage.js +41 -0
- package/dist/component/template/CreateFormPage/CreateFormPage.js.map +1 -0
- package/dist/component/template/EditFormPage/EditFormPage.d.ts +19 -0
- package/dist/component/template/EditFormPage/EditFormPage.js +42 -0
- package/dist/component/template/EditFormPage/EditFormPage.js.map +1 -0
- package/dist/component/template/FormPage/FormPage.d.ts +25 -0
- package/dist/component/template/FormPage/FormPage.js +130 -0
- package/dist/component/template/FormPage/FormPage.js.map +1 -0
- package/dist/component/template/FormPage/FormType.d.ts +6 -0
- package/dist/component/template/FormPage/FormType.js +12 -0
- package/dist/component/template/FormPage/FormType.js.map +1 -0
- package/dist/component/template/Layout/Layout.d.ts +21 -0
- package/dist/component/template/Layout/Layout.js +121 -0
- package/dist/component/template/Layout/Layout.js.map +1 -0
- package/dist/component/template/Layout/Layout.module.js +19 -0
- package/dist/component/template/Layout/Layout.module.js.map +1 -0
- package/dist/component/template/ListPage/ListPage.d.ts +32 -0
- package/dist/component/template/ListPage/ListPage.js +47 -0
- package/dist/component/template/ListPage/ListPage.js.map +1 -0
- package/dist/component/template/PrintPage/PrintPage.d.ts +25 -0
- package/dist/component/template/PrintPage/PrintPage.js +115 -0
- package/dist/component/template/PrintPage/PrintPage.js.map +1 -0
- package/dist/component/template/ViewPage/ViewPage.d.ts +11 -0
- package/dist/component/template/ViewPage/ViewPage.js +49 -0
- package/dist/component/template/ViewPage/ViewPage.js.map +1 -0
- package/dist/data/ListDataSource.d.ts +12 -0
- package/dist/data/ListDataSource.js +1 -0
- package/dist/data/SaveDataSource.d.ts +16 -0
- package/dist/data/SaveDataSource.js +1 -0
- package/dist/export/ExportCellText.d.ts +18 -0
- package/dist/export/ExportCellText.js +60 -0
- package/dist/export/ExportCellText.js.map +1 -0
- package/dist/export/ExportDocument.d.ts +127 -0
- package/dist/export/ExportDocument.js +59 -0
- package/dist/export/ExportDocument.js.map +1 -0
- package/dist/export/ExportDownload.d.ts +9 -0
- package/dist/export/ExportDownload.js +19 -0
- package/dist/export/ExportDownload.js.map +1 -0
- package/dist/export/ExportFileName.d.ts +11 -0
- package/dist/export/ExportFileName.js +24 -0
- package/dist/export/ExportFileName.js.map +1 -0
- package/dist/export/ExportFormat.d.ts +30 -0
- package/dist/export/ExportFormat.js +1 -0
- package/dist/export/ExportFormats.d.ts +12 -0
- package/dist/export/ExportFormats.js +16 -0
- package/dist/export/ExportFormats.js.map +1 -0
- package/dist/export/ExportTexts.d.ts +14 -0
- package/dist/export/ExportTexts.js +23 -0
- package/dist/export/ExportTexts.js.map +1 -0
- package/dist/export/csv/CsvFormat.d.ts +41 -0
- package/dist/export/csv/CsvFormat.js +91 -0
- package/dist/export/csv/CsvFormat.js.map +1 -0
- package/dist/export/xlsx/XlsxFormat.d.ts +35 -0
- package/dist/export/xlsx/XlsxFormat.js +66 -0
- package/dist/export/xlsx/XlsxFormat.js.map +1 -0
- package/dist/export/xlsx/XlsxNumberFormat.d.ts +8 -0
- package/dist/export/xlsx/XlsxNumberFormat.js +15 -0
- package/dist/export/xlsx/XlsxNumberFormat.js.map +1 -0
- package/dist/export/xlsx/XlsxSheetName.d.ts +12 -0
- package/dist/export/xlsx/XlsxSheetName.js +62 -0
- package/dist/export/xlsx/XlsxSheetName.js.map +1 -0
- package/dist/export/xlsx/XlsxSheetWriter.d.ts +67 -0
- package/dist/export/xlsx/XlsxSheetWriter.js +215 -0
- package/dist/export/xlsx/XlsxSheetWriter.js.map +1 -0
- package/dist/export/xlsx/XlsxStyle.d.ts +51 -0
- package/dist/export/xlsx/XlsxStyle.js +87 -0
- package/dist/export/xlsx/XlsxStyle.js.map +1 -0
- package/dist/hook/useIsMobile.d.ts +5 -0
- package/dist/hook/useIsMobile.js +16 -0
- package/dist/hook/useIsMobile.js.map +1 -0
- package/dist/hook/useKeyedService.d.ts +22 -0
- package/dist/hook/useKeyedService.js +38 -0
- package/dist/hook/useKeyedService.js.map +1 -0
- package/dist/hook/useLightColorSchemeOnPrint.d.ts +9 -0
- package/dist/hook/useLightColorSchemeOnPrint.js +36 -0
- package/dist/hook/useLightColorSchemeOnPrint.js.map +1 -0
- package/dist/hook/useService.d.ts +27 -0
- package/dist/hook/useService.js +23 -0
- package/dist/hook/useService.js.map +1 -0
- package/dist/http/ApiError.d.ts +13 -0
- package/dist/http/ApiError.js +22 -0
- package/dist/http/ApiError.js.map +1 -0
- package/dist/http/AxiosHttpClient.d.ts +21 -0
- package/dist/http/AxiosHttpClient.js +67 -0
- package/dist/http/AxiosHttpClient.js.map +1 -0
- package/dist/http/AxiosHttpClientConfig.d.ts +37 -0
- package/dist/http/AxiosHttpClientConfig.js +19 -0
- package/dist/http/AxiosHttpClientConfig.js.map +1 -0
- package/dist/i18n/KitLocale.d.ts +4 -0
- package/dist/i18n/KitLocale.js +7 -0
- package/dist/i18n/KitLocale.js.map +1 -0
- package/dist/i18n/KitMessages.d.ts +146 -0
- package/dist/i18n/KitMessages.js +1 -0
- package/dist/i18n/messages/enUS.d.ts +3 -0
- package/dist/i18n/messages/enUS.js +112 -0
- package/dist/i18n/messages/enUS.js.map +1 -0
- package/dist/i18n/messages/ptBR.d.ts +3 -0
- package/dist/i18n/messages/ptBR.js +97 -0
- package/dist/i18n/messages/ptBR.js.map +1 -0
- package/dist/i18n/resolveMessages.d.ts +13 -0
- package/dist/i18n/resolveMessages.js +29 -0
- package/dist/i18n/resolveMessages.js.map +1 -0
- package/dist/model/Identifiable.d.ts +7 -0
- package/dist/model/Identifiable.js +1 -0
- package/dist/provider/KitConfig.d.ts +26 -0
- package/dist/provider/KitConfig.js +1 -0
- package/dist/provider/KitContext.d.ts +9 -0
- package/dist/provider/KitContext.js +27 -0
- package/dist/provider/KitContext.js.map +1 -0
- package/dist/provider/KitProvider.d.ts +7 -0
- package/dist/provider/KitProvider.js +31 -0
- package/dist/provider/KitProvider.js.map +1 -0
- package/dist/provider/useKit.d.ts +15 -0
- package/dist/provider/useKit.js +28 -0
- package/dist/provider/useKit.js.map +1 -0
- package/dist/router/FormRouteSegments.d.ts +16 -0
- package/dist/router/FormRouteSegments.js +19 -0
- package/dist/router/FormRouteSegments.js.map +1 -0
- package/dist/router/RouterAdapter.d.ts +24 -0
- package/dist/router/RouterAdapter.js +1 -0
- package/dist/router/anchorRouter.d.ts +7 -0
- package/dist/router/anchorRouter.js +23 -0
- package/dist/router/anchorRouter.js.map +1 -0
- package/dist/styles/print.css +93 -0
- package/dist/styles.css +188 -0
- package/dist/util/ArrayUtil.d.ts +39 -0
- package/dist/util/ArrayUtil.js +48 -0
- package/dist/util/ArrayUtil.js.map +1 -0
- package/dist/util/ColorUtil.d.ts +7 -0
- package/dist/util/ColorUtil.js +16 -0
- package/dist/util/ColorUtil.js.map +1 -0
- package/dist/util/CompareUtil.d.ts +19 -0
- package/dist/util/CompareUtil.js +51 -0
- package/dist/util/CompareUtil.js.map +1 -0
- package/dist/util/DateUtil.d.ts +38 -0
- package/dist/util/DateUtil.js +55 -0
- package/dist/util/DateUtil.js.map +1 -0
- package/dist/util/DownloadUtil.d.ts +6 -0
- package/dist/util/DownloadUtil.js +25 -0
- package/dist/util/DownloadUtil.js.map +1 -0
- package/dist/util/EnumUtil.d.ts +19 -0
- package/dist/util/EnumUtil.js +32 -0
- package/dist/util/EnumUtil.js.map +1 -0
- package/dist/util/FormUtil.d.ts +8 -0
- package/dist/util/FormUtil.js +14 -0
- package/dist/util/FormUtil.js.map +1 -0
- package/dist/util/HtmlUtil.d.ts +8 -0
- package/dist/util/HtmlUtil.js +23 -0
- package/dist/util/HtmlUtil.js.map +1 -0
- package/dist/util/Notifications.d.ts +30 -0
- package/dist/util/Notifications.js +59 -0
- package/dist/util/Notifications.js.map +1 -0
- package/dist/util/NumberUtil.d.ts +19 -0
- package/dist/util/NumberUtil.js +33 -0
- package/dist/util/NumberUtil.js.map +1 -0
- package/dist/util/ObjectUtil.d.ts +22 -0
- package/dist/util/ObjectUtil.js +34 -0
- package/dist/util/ObjectUtil.js.map +1 -0
- package/dist/util/SearchParamsUtil.d.ts +23 -0
- package/dist/util/SearchParamsUtil.js +29 -0
- package/dist/util/SearchParamsUtil.js.map +1 -0
- package/dist/util/TransformData.d.ts +14 -0
- package/dist/util/TransformData.js +31 -0
- package/dist/util/TransformData.js.map +1 -0
- package/dist/util/ValidationUtil.d.ts +9 -0
- package/dist/util/ValidationUtil.js +16 -0
- package/dist/util/ValidationUtil.js.map +1 -0
- package/dist/util/parseActionsPageParams.d.ts +14 -0
- package/dist/util/parseActionsPageParams.js +29 -0
- package/dist/util/parseActionsPageParams.js.map +1 -0
- package/package.json +158 -5
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Instituto Federal do Tocantins (IFTO) - Campus Palmas
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,476 @@
|
|
|
1
|
-
#
|
|
1
|
+
# @ifto/mantine-kit
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/iftopalmas/mantine-kit/actions/workflows/build.yml)
|
|
4
|
+
[](https://www.npmjs.com/package/@ifto/mantine-kit)
|
|
5
|
+
[](https://iftopalmas.github.io/mantine-kit/)
|
|
6
|
+
[](LICENSE)
|
|
7
|
+
|
|
8
|
+
General purpose [Mantine](https://mantine.dev) components for business React apps: CRUD tables and forms, an app
|
|
9
|
+
layout with a side menu, [Apache ECharts](https://echarts.apache.org) charts, Excel/CSV export, print-ready reports and
|
|
10
|
+
a REST HTTP client.
|
|
11
|
+
|
|
12
|
+
- **Works with any router.** Components never import a router: they navigate through a small adapter you give to the
|
|
13
|
+
`KitProvider` (examples for Next.js and React Router below). Without one, plain links are used.
|
|
14
|
+
- **Internationalized.** Every text comes from a typed message catalog, with American English (`en-US`, the default)
|
|
15
|
+
and Brazilian Portuguese (`pt-BR`). Numbers, dates and sorting follow the locale. You can override any text.
|
|
16
|
+
- **Bound to data by contracts, not classes.** Tables and forms accept any object with `findAll`/`delete` or `save`
|
|
17
|
+
methods, so they work with REST services, GraphQL clients or in-memory data alike.
|
|
18
|
+
- **Pay only for what you use.** Each component is imported from its own file, so optional dependencies (ECharts,
|
|
19
|
+
ExcelJS, Axios, mantine-datatable) only enter your bundle if you use the components that need them. ECharts and
|
|
20
|
+
ExcelJS are loaded on demand.
|
|
21
|
+
- **Ready for the Next.js App Router.** Every module is marked as a Client Component.
|
|
22
|
+
|
|
23
|
+
**Documentation of every component, with live examples: [Storybook](https://iftopalmas.github.io/mantine-kit/).**
|
|
24
|
+
|
|
25
|
+
## Contents
|
|
26
|
+
|
|
27
|
+
- [How to use](#how-to-use)
|
|
28
|
+
- [Examples](#examples)
|
|
29
|
+
- [Configuration](#configuration)
|
|
30
|
+
- [Components](#components)
|
|
31
|
+
- [Internationalization](#internationalization)
|
|
32
|
+
- [Storybook](#storybook)
|
|
33
|
+
- [Development](#development)
|
|
34
|
+
- [Publishing](#publishing)
|
|
35
|
+
|
|
36
|
+
## How to use
|
|
37
|
+
|
|
38
|
+
**1. Install** the library and its required peer dependencies:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
yarn add @ifto/mantine-kit @mantine/core @mantine/hooks @mantine/notifications @tabler/icons-react clsx dayjs \
|
|
42
|
+
react react-dom
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
Install the optional ones only if you use the components that need them:
|
|
46
|
+
|
|
47
|
+
| Package | Needed by |
|
|
48
|
+
|---|---|
|
|
49
|
+
| `@mantine/form` | the form templates (`FormPage`, `CreateFormPage`, `EditFormPage`) and `DataForm`, which take a `useForm` form |
|
|
50
|
+
| `@mantine/modals` | the confirmations of `Table` (delete), `ListPage` and `DataForm` |
|
|
51
|
+
| `@mantine/dates` | `DateField` |
|
|
52
|
+
| `mantine-datatable` | `Table`, `ViewTable`, `ListPage` |
|
|
53
|
+
| `echarts` | `EChart` and the chart types |
|
|
54
|
+
| `exceljs` | Excel export |
|
|
55
|
+
| `axios` | `AxiosHttpClient` |
|
|
56
|
+
| `zod` | `selectedId` validation helper |
|
|
57
|
+
|
|
58
|
+
**2. Import the CSS** once, after the Mantine CSS (e.g. in the root layout of the app):
|
|
59
|
+
|
|
60
|
+
```ts
|
|
61
|
+
import '@mantine/core/styles.css';
|
|
62
|
+
import '@mantine/notifications/styles.css';
|
|
63
|
+
import 'mantine-datatable/styles.css';
|
|
64
|
+
import '@ifto/mantine-kit/styles.css';
|
|
65
|
+
import '@ifto/mantine-kit/print.css'; // only if you use PrintPage
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
**3. Wrap the app** with the Mantine providers and the `KitProvider`:
|
|
69
|
+
|
|
70
|
+
```tsx
|
|
71
|
+
import { MantineProvider } from '@mantine/core';
|
|
72
|
+
import { ModalsProvider } from '@mantine/modals';
|
|
73
|
+
import { Notifications } from '@mantine/notifications';
|
|
74
|
+
import { KitProvider } from '@ifto/mantine-kit/provider/KitProvider';
|
|
75
|
+
|
|
76
|
+
export function Providers({ children }: { children: React.ReactNode }) {
|
|
77
|
+
return (
|
|
78
|
+
<MantineProvider>
|
|
79
|
+
<ModalsProvider>
|
|
80
|
+
<Notifications />
|
|
81
|
+
<KitProvider appName="My System" locale="en-US">
|
|
82
|
+
{children}
|
|
83
|
+
</KitProvider>
|
|
84
|
+
</ModalsProvider>
|
|
85
|
+
</MantineProvider>
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
Give your router to the `KitProvider` (`router={nextRouter}`) so links do not reload the page; see
|
|
91
|
+
[Router adapter](#router-adapter).
|
|
92
|
+
|
|
93
|
+
**4. Import each component from its own file** and use it:
|
|
94
|
+
|
|
95
|
+
```tsx
|
|
96
|
+
import { SelectField } from '@ifto/mantine-kit/component/molecule/SelectField/SelectField';
|
|
97
|
+
|
|
98
|
+
<SelectField label="City" data={cities} getId={city => city.id} getDescription={city => city.name} />;
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
The path is the one of the file inside `src`, without the extension (see [Components](#components)). There is no
|
|
102
|
+
`index` with everything, so you only bundle what you import.
|
|
103
|
+
|
|
104
|
+
## Examples
|
|
105
|
+
|
|
106
|
+
### CRUD list page
|
|
107
|
+
|
|
108
|
+
`ListPage` shows the records in a sortable, paginated table with view, edit and delete actions. Its `service` is any
|
|
109
|
+
object with `findAll` and `delete`:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import ListPage from '@ifto/mantine-kit/component/template/ListPage/ListPage';
|
|
113
|
+
import type { ListDataSource } from '@ifto/mantine-kit/data/ListDataSource';
|
|
114
|
+
|
|
115
|
+
type Region = { id?: number; name: string };
|
|
116
|
+
|
|
117
|
+
const regions: ListDataSource<Region> = {
|
|
118
|
+
findAll: () => fetch('/api/region').then(response => response.json()),
|
|
119
|
+
delete: id => fetch(`/api/region/${id}`, { method: 'DELETE' }).then(() => undefined)
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
export function RegionsPage() {
|
|
123
|
+
return (
|
|
124
|
+
<ListPage
|
|
125
|
+
title="Regions"
|
|
126
|
+
titlePlural="Regions"
|
|
127
|
+
breadcrumbItems={[{ title: 'Regions', href: '/region' }]}
|
|
128
|
+
addActionRoute="/region/create"
|
|
129
|
+
service={regions}
|
|
130
|
+
resourceBasePath="/region"
|
|
131
|
+
tableColumns={[{ accessor: 'name', title: 'Name', sortable: true }]}
|
|
132
|
+
/>
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
### CRUD form page
|
|
138
|
+
|
|
139
|
+
`FormPage` creates, edits or views a record and saves it with any object that has a `save(id, data)` method:
|
|
140
|
+
|
|
141
|
+
```tsx
|
|
142
|
+
import { TextInput } from '@mantine/core';
|
|
143
|
+
import { useForm } from '@mantine/form';
|
|
144
|
+
import FormPage from '@ifto/mantine-kit/component/template/FormPage/FormPage';
|
|
145
|
+
import { FormType } from '@ifto/mantine-kit/component/template/FormPage/FormType';
|
|
146
|
+
import type { SaveDataSource } from '@ifto/mantine-kit/data/SaveDataSource';
|
|
147
|
+
|
|
148
|
+
const regionService: SaveDataSource<Region, Region> = {
|
|
149
|
+
save: (id, data) =>
|
|
150
|
+
fetch(id ? `/api/region/${id}` : '/api/region', {
|
|
151
|
+
method: id ? 'PUT' : 'POST',
|
|
152
|
+
headers: { 'Content-Type': 'application/json' },
|
|
153
|
+
body: JSON.stringify(data)
|
|
154
|
+
}).then(response => response.json())
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
export function NewRegionPage() {
|
|
158
|
+
const form = useForm<Region>({ initialValues: { name: '' } });
|
|
159
|
+
|
|
160
|
+
return (
|
|
161
|
+
<FormPage service={regionService} title="Region" form={form} formType={FormType.Create} backRoute="/region">
|
|
162
|
+
<TextInput label="Name" {...form.getInputProps('name')} />
|
|
163
|
+
</FormPage>
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
To read the action from a catch-all route (`/region/create`, `/region/edit/5`), use
|
|
169
|
+
`parseActionsPageParams(segments)` (`util/parseActionsPageParams`).
|
|
170
|
+
|
|
171
|
+
### App layout with a side menu
|
|
172
|
+
|
|
173
|
+
```tsx
|
|
174
|
+
import { Menu, Title } from '@mantine/core';
|
|
175
|
+
import { IconHome, IconMap } from '@tabler/icons-react';
|
|
176
|
+
import { Layout } from '@ifto/mantine-kit/component/template/Layout/Layout';
|
|
177
|
+
|
|
178
|
+
const menu = [
|
|
179
|
+
{ link: '/', label: 'Home', icon: IconHome },
|
|
180
|
+
{ link: '/region', label: 'Regions', icon: IconMap }
|
|
181
|
+
];
|
|
182
|
+
|
|
183
|
+
export function AppLayout({ children }: { children: React.ReactNode }) {
|
|
184
|
+
return (
|
|
185
|
+
<Layout logo={<Title order={4}>My System</Title>} navItems={menu} userMenu={<Menu.Item>Log out</Menu.Item>}>
|
|
186
|
+
{children}
|
|
187
|
+
</Layout>
|
|
188
|
+
);
|
|
189
|
+
}
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### Chart
|
|
193
|
+
|
|
194
|
+
`EChart` builds the series from your data with `getName`/`getValue`. ECharts is loaded only when a chart is shown:
|
|
195
|
+
|
|
196
|
+
```tsx
|
|
197
|
+
import { EChart } from '@ifto/mantine-kit/component/organism/EChart/EChart';
|
|
198
|
+
|
|
199
|
+
const coverage = [
|
|
200
|
+
{ region: 'North', rate: 0.82 },
|
|
201
|
+
{ region: 'South', rate: 0.64 }
|
|
202
|
+
];
|
|
203
|
+
|
|
204
|
+
<EChart
|
|
205
|
+
data={coverage}
|
|
206
|
+
getName={item => item.region}
|
|
207
|
+
getValue={item => item.rate}
|
|
208
|
+
option={{ xAxis: { type: 'category', data: coverage.map(item => item.region) }, yAxis: {}, series: [{ type: 'bar' }] }}
|
|
209
|
+
style={{ height: 360 }}
|
|
210
|
+
/>;
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
The chart types in `component/organism/EChart/chart` (`LINE_CHART`, `BAR_CHART`, `STACKED_BAR_CHART`, `DONUT_CHART`)
|
|
214
|
+
build a complete option, with one panel per unit, from generic series:
|
|
215
|
+
`option={LINE_CHART.buildOption(data, { title: 'Revenue', locale: 'en-US' })}`.
|
|
216
|
+
|
|
217
|
+
### Export to Excel or CSV
|
|
218
|
+
|
|
219
|
+
```tsx
|
|
220
|
+
import ExportMenuButton from '@ifto/mantine-kit/component/molecule/ExportMenuButton/ExportMenuButton';
|
|
221
|
+
import { downloadExport } from '@ifto/mantine-kit/export/ExportDownload';
|
|
222
|
+
import { EXPORT_FORMATS } from '@ifto/mantine-kit/export/ExportFormats';
|
|
223
|
+
|
|
224
|
+
<ExportMenuButton
|
|
225
|
+
formats={EXPORT_FORMATS}
|
|
226
|
+
onExport={format =>
|
|
227
|
+
downloadExport(
|
|
228
|
+
{
|
|
229
|
+
title: 'Sales report',
|
|
230
|
+
fileName: 'sales',
|
|
231
|
+
info: [{ label: 'Period', value: '2026' }],
|
|
232
|
+
generatedAt: new Date(),
|
|
233
|
+
branding: { systemName: 'My System', siteUrl: window.location.origin },
|
|
234
|
+
sheets: [{ name: 'Sales', columns: [{ header: 'Product' }, { header: 'Total' }], rows: [['Water', 10]] }],
|
|
235
|
+
locale: 'en-US'
|
|
236
|
+
},
|
|
237
|
+
format
|
|
238
|
+
)
|
|
239
|
+
}
|
|
240
|
+
/>;
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
The CSV uses the decimal separator of the locale and a column separator that does not clash with it (`;` in `pt-BR`,
|
|
244
|
+
`,` in `en-US`), as Excel in that language expects.
|
|
245
|
+
|
|
246
|
+
The menu offers the formats you give: the built-in ones (`EXPORT_FORMATS`, `XLSX_FORMAT`, `CSV_FORMAT`), an Excel
|
|
247
|
+
format with your brand colors (`new XlsxFormat({ colors: { primary: 'FF2B8A3E' } })`) or any format of your own, by
|
|
248
|
+
implementing the `ExportFormat` interface (e.g. PDF or JSON).
|
|
249
|
+
|
|
250
|
+
### Printable report
|
|
251
|
+
|
|
252
|
+
```tsx
|
|
253
|
+
import PrintSection from '@ifto/mantine-kit/component/molecule/PrintSection/PrintSection';
|
|
254
|
+
import PrintPage from '@ifto/mantine-kit/component/template/PrintPage/PrintPage';
|
|
255
|
+
|
|
256
|
+
<PrintPage title="Regions report" systemName="My System" info={[{ label: 'Period', value: '2026' }]}>
|
|
257
|
+
<PrintSection title="Regions">{regionsTable}</PrintSection>
|
|
258
|
+
<PrintSection title="Summary" newPage>
|
|
259
|
+
{summary}
|
|
260
|
+
</PrintSection>
|
|
261
|
+
</PrintPage>;
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
### HTTP client
|
|
265
|
+
|
|
266
|
+
```ts
|
|
267
|
+
import { AxiosHttpClient } from '@ifto/mantine-kit/http/AxiosHttpClient';
|
|
268
|
+
import { ApiError } from '@ifto/mantine-kit/http/ApiError';
|
|
269
|
+
|
|
270
|
+
const httpClient = new AxiosHttpClient({ baseURL: 'https://api.example.com', timeout: 10_000, locale: 'en-US' });
|
|
271
|
+
// Interceptors, e.g. for the authentication token
|
|
272
|
+
httpClient.axiosInstance.interceptors.request.use(config => config);
|
|
273
|
+
|
|
274
|
+
try {
|
|
275
|
+
await httpClient.put('/region/1', data);
|
|
276
|
+
} catch (e) {
|
|
277
|
+
if (e instanceof ApiError && e.code === 'CONCURRENT_UPDATE') {
|
|
278
|
+
// another user changed the record
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
```
|
|
282
|
+
|
|
283
|
+
By default, the message and the code of an error are read from the `message` and `code` fields of the response body
|
|
284
|
+
(the error format of a Spring API). For another format, give an `errorParser` in the configuration.
|
|
285
|
+
|
|
286
|
+
More examples, with every state of each component, are in the [Storybook](https://iftopalmas.github.io/mantine-kit/).
|
|
287
|
+
|
|
288
|
+
## Configuration
|
|
289
|
+
|
|
290
|
+
Options of the `KitProvider`:
|
|
291
|
+
|
|
292
|
+
| Option | Default | Description |
|
|
293
|
+
|---|---|---|
|
|
294
|
+
| `router` | plain `<a>` links | Adapter to the router of the app (see below). |
|
|
295
|
+
| `appName` | none | Shown in the browser tab title by the page templates (e.g. "Regions - My System"). |
|
|
296
|
+
| `locale` | `en-US` | Language of the texts and format of numbers and dates: `en-US` or `pt-BR`. |
|
|
297
|
+
| `messages` | none | Texts that replace the ones of the locale, by section (see [Internationalization](#internationalization)). |
|
|
298
|
+
| `formRouteSegments` | `create`, `edit`, `view` | URL segments of the create, edit and view pages of a record (e.g. `/region/edit/5`), independent of the locale: `ENGLISH_FORM_ROUTE_SEGMENTS` (default), `PORTUGUESE_FORM_ROUTE_SEGMENTS` (`criar`, `editar`, `visualizar`) or your own, from `router/FormRouteSegments`. |
|
|
299
|
+
|
|
300
|
+
### Router adapter
|
|
301
|
+
|
|
302
|
+
A `RouterAdapter` has a `Link` component (receiving `href`), a `usePathname` hook and a `useNavigate` hook.
|
|
303
|
+
|
|
304
|
+
**Next.js (App Router):**
|
|
305
|
+
|
|
306
|
+
```tsx
|
|
307
|
+
'use client';
|
|
308
|
+
|
|
309
|
+
import NextLink from 'next/link';
|
|
310
|
+
import { usePathname, useRouter } from 'next/navigation';
|
|
311
|
+
|
|
312
|
+
import type { RouterAdapter } from '@ifto/mantine-kit/router/RouterAdapter';
|
|
313
|
+
|
|
314
|
+
export const nextRouter: RouterAdapter = {
|
|
315
|
+
Link: NextLink,
|
|
316
|
+
usePathname,
|
|
317
|
+
useNavigate: () => useRouter().push
|
|
318
|
+
};
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
**React Router:**
|
|
322
|
+
|
|
323
|
+
```tsx
|
|
324
|
+
import { forwardRef } from 'react';
|
|
325
|
+
import { Link, useLocation, useNavigate } from 'react-router';
|
|
326
|
+
|
|
327
|
+
import type { RouterAdapter, RouterLinkProps } from '@ifto/mantine-kit/router/RouterAdapter';
|
|
328
|
+
|
|
329
|
+
const RouterLink = forwardRef<HTMLAnchorElement, RouterLinkProps>(({ href, ...props }, ref) => (
|
|
330
|
+
<Link ref={ref} to={href} {...props} />
|
|
331
|
+
));
|
|
332
|
+
|
|
333
|
+
export const reactRouter: RouterAdapter = {
|
|
334
|
+
Link: RouterLink,
|
|
335
|
+
usePathname: () => useLocation().pathname,
|
|
336
|
+
useNavigate: () => {
|
|
337
|
+
const navigate = useNavigate();
|
|
338
|
+
return (url: string) => navigate(url);
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
```
|
|
342
|
+
|
|
343
|
+
## Components
|
|
344
|
+
|
|
345
|
+
Every file is imported by its path inside `src`, without the extension, e.g.
|
|
346
|
+
`@ifto/mantine-kit/component/organism/Table/Table`. The components follow the
|
|
347
|
+
[atomic design](https://atomicdesign.bradfrost.com) layers.
|
|
348
|
+
|
|
349
|
+
### Atoms (`component/atom`)
|
|
350
|
+
|
|
351
|
+
| Component | What it does |
|
|
352
|
+
|---|---|
|
|
353
|
+
| `AppMain` | Main content area of the `Layout`, with the page background in light and dark color schemes. |
|
|
354
|
+
| `CancelEditButton` | Icon button that cancels the in-place editing of a table row. |
|
|
355
|
+
| `ConfirmEditButton` | Icon button that confirms the in-place editing of a table row (keeps its tooltip when disabled). |
|
|
356
|
+
| `EditValueButton` | Icon button that starts the in-place editing of a table row. |
|
|
357
|
+
| `DateField` | Clearable date input in the date format of the locale. |
|
|
358
|
+
| `ErrorAlert` | Red alert that shows an error message. |
|
|
359
|
+
| `Surface` | Polymorphic container, the base of cards and page headers. |
|
|
360
|
+
|
|
361
|
+
### Molecules (`component/molecule`)
|
|
362
|
+
|
|
363
|
+
| Component | What it does |
|
|
364
|
+
|---|---|
|
|
365
|
+
| `Breadcrumb` | Navigation path to the current page, with links to the previous ones. |
|
|
366
|
+
| `ExportMenuButton` | "Export" button with a menu of file formats (Excel, CSV); shows a notification if the export fails. |
|
|
367
|
+
| `PaperCard` | Bordered card that groups the content of a page. |
|
|
368
|
+
| `PrintSection` | Titled section of a report that can start on a new printed page and never leaves its title alone. |
|
|
369
|
+
| `SelectField` | Select built from any array of objects, with placeholder and "not found" texts built from the label. |
|
|
370
|
+
| `StatsCard` | Card with a key value, its change from the previous period and the period. |
|
|
371
|
+
|
|
372
|
+
### Organisms (`component/organism`)
|
|
373
|
+
|
|
374
|
+
| Component | What it does |
|
|
375
|
+
|---|---|
|
|
376
|
+
| `DataForm` | Form in a card with back and submit buttons, optional confirmation, notifications and navigation. |
|
|
377
|
+
| `DataTabList` | Tabs built from an array of objects, one tab per object, wrapping in rows. |
|
|
378
|
+
| `EChart` | React wrapper of Apache ECharts: builds the series from raw data, loads ECharts on demand, resizes and prints. |
|
|
379
|
+
| `Navbar` | Side menu with links and collapsible groups, highlighting the current page. |
|
|
380
|
+
| `PageHeader` | Page title with the breadcrumb and, in list pages, the "Add" button. |
|
|
381
|
+
| `StatsGrid` | Responsive grid of `StatsCard`s, with placeholders while loading. |
|
|
382
|
+
| `Table` | Table of the records of a data source, with view, edit and delete (with confirmation) actions. |
|
|
383
|
+
| `RowActions` | View, edit and delete buttons of a `Table` row. |
|
|
384
|
+
| `ViewTable` | Sortable and paginated table (on top of mantine-datatable), with locale-aware sorting. |
|
|
385
|
+
|
|
386
|
+
The `EChart/chart` folder has chart types that build the ECharts option from generic series: `LineChart`, `BarChart`
|
|
387
|
+
(negative values highlighted), `StackedBarChart` and `DonutChart`, with one panel per unit of measure.
|
|
388
|
+
|
|
389
|
+
### Templates (`component/template`)
|
|
390
|
+
|
|
391
|
+
| Component | What it does |
|
|
392
|
+
|---|---|
|
|
393
|
+
| `Layout` | App shell: header with the brand, color scheme toggle and user menu, collapsible side menu and content area. |
|
|
394
|
+
| `ListPage` | List page of records: header with the "Add" button, optional filters and the `Table`. |
|
|
395
|
+
| `FormPage` | Create, edit or view form page that saves the record in a `SaveDataSource`. |
|
|
396
|
+
| `CreateFormPage` | Form page to create a record with a given function. |
|
|
397
|
+
| `EditFormPage` | Form page to update a record with a given function. |
|
|
398
|
+
| `ViewPage` | Page that shows a record, with a back button. |
|
|
399
|
+
| `PrintPage` | Report page formatted to be printed or saved as PDF by the browser. |
|
|
400
|
+
|
|
401
|
+
### Other modules
|
|
402
|
+
|
|
403
|
+
| Module | What it does |
|
|
404
|
+
|---|---|
|
|
405
|
+
| `provider/KitProvider`, `provider/useKit` | Configuration of the library (router, app name, locale, texts) and the hooks to read it. |
|
|
406
|
+
| `router/RouterAdapter`, `router/anchorRouter` | Contract of the router adapter and the default one, with plain links. |
|
|
407
|
+
| `data/ListDataSource`, `data/SaveDataSource` | Contracts of the data sources of the tables and forms. |
|
|
408
|
+
| `i18n/*` | Message catalog type, the `en-US` and `pt-BR` catalogs and `resolveMessages`. |
|
|
409
|
+
| `export/*` | Export model (`ExportDocument`), the Excel and CSV formats and `downloadExport`. |
|
|
410
|
+
| `http/AxiosHttpClient`, `http/ApiError` | REST client that turns backend errors into `ApiError`s with message and code. |
|
|
411
|
+
| `hook/*` | `useService` and `useKeyedService` (fetch data, ignoring stale responses), `useIsMobile`, `useLightColorSchemeOnPrint`. |
|
|
412
|
+
| `util/*` | Notifications, sorting, number and date formatting, URL building, form helpers and more. |
|
|
413
|
+
|
|
414
|
+
## Internationalization
|
|
415
|
+
|
|
416
|
+
All texts the components show are in a typed catalog (`i18n/KitMessages.ts`), grouped by component: `common`, `form`,
|
|
417
|
+
`table`, `rowEdit`, `select`, `layout`, `print`, `stats`, `export`, `chart` and `http`. Each locale is an object of
|
|
418
|
+
this type (`i18n/messages/ptBR.ts`, `i18n/messages/enUS.ts`), so a missing translation is a compile error. Texts with
|
|
419
|
+
variables are functions, such as `table.pagination({ from, to, totalRecords })`.
|
|
420
|
+
|
|
421
|
+
Choose the locale and override any text in the `KitProvider`. An app that already uses an i18n library (e.g.
|
|
422
|
+
`react-i18next`, `next-intl`) passes its translations the same way:
|
|
423
|
+
|
|
424
|
+
```tsx
|
|
425
|
+
<KitProvider locale="en-US" messages={{ common: { back: t('back') }, table: { noRecords: t('empty') } }}>
|
|
426
|
+
```
|
|
427
|
+
|
|
428
|
+
Code outside React receives the locale (and, optionally, texts) directly: `ExportDocument.locale`,
|
|
429
|
+
`ChartContext.locale` and `AxiosHttpClientConfig.locale`. URLs are not translated: the CRUD route segments are a
|
|
430
|
+
separate option (`formRouteSegments`).
|
|
431
|
+
|
|
432
|
+
## Storybook
|
|
433
|
+
|
|
434
|
+
The [Storybook](https://iftopalmas.github.io/mantine-kit/) documents every component: a **Docs** page per component,
|
|
435
|
+
generated from its props types and JSDoc, and stories with examples of its states, whose props can be changed in the
|
|
436
|
+
**Controls** panel. The toolbar switches the locale (`en-US`/`pt-BR`) and the theme (light/dark) of all stories.
|
|
437
|
+
|
|
438
|
+
```bash
|
|
439
|
+
yarn storybook # development server at http://localhost:6006
|
|
440
|
+
yarn storybook:build # static site in storybook-static/
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
The stories live in `stories/`, mirroring `src/`. The [`storybook.yml`](.github/workflows/storybook.yml) workflow
|
|
444
|
+
publishes the site to GitHub Pages on every push to `main`.
|
|
445
|
+
|
|
446
|
+
## Development
|
|
447
|
+
|
|
448
|
+
See [AGENTS.md](AGENTS.md) for the architecture and the conventions of the code.
|
|
449
|
+
|
|
450
|
+
```bash
|
|
451
|
+
nvm use # Node version of .nvmrc
|
|
452
|
+
corepack enable
|
|
453
|
+
yarn install
|
|
454
|
+
yarn test # Prettier, lint, typecheck and tests with coverage
|
|
455
|
+
yarn build # generates dist/
|
|
456
|
+
```
|
|
457
|
+
|
|
458
|
+
## Publishing
|
|
459
|
+
|
|
460
|
+
The [`publish.yml`](.github/workflows/publish.yml) workflow publishes to npm when a tag equal to the version in
|
|
461
|
+
`package.json` is pushed:
|
|
462
|
+
|
|
463
|
+
```bash
|
|
464
|
+
# After updating "version" in package.json and merging it into main
|
|
465
|
+
git tag v0.1.0
|
|
466
|
+
git push origin v0.1.0
|
|
467
|
+
```
|
|
468
|
+
|
|
469
|
+
Versions with a suffix (e.g. `v0.2.0-beta.1`) are published with the `next` dist-tag. The workflow authenticates
|
|
470
|
+
with [npm trusted publishing](https://docs.npmjs.com/trusted-publishers): the package trusts this workflow, which uses a
|
|
471
|
+
short-lived token from GitHub, so no npm token is stored in the repository, and every release has a provenance
|
|
472
|
+
statement.
|
|
473
|
+
|
|
474
|
+
## License
|
|
475
|
+
|
|
476
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"App.module.js","names":[],"sources":["../../../../src/component/atom/AppMain/App.module.css"],"sourcesContent":[".main {\n min-height: 95vh;\n\n @mixin light {\n background-color: var(--mantine-color-gray-0);\n }\n\n @mixin dark {\n background-color: var(--mantine-color-dark-6);\n }\n\n /* On paper, the page is white and only as tall as its content (see styles/print.css). */\n @media print {\n min-height: 0;\n background-color: #fff !important;\n }\n}\n"],"mappings":""}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
type AppMainProps = {
|
|
3
|
+
children: ReactNode;
|
|
4
|
+
};
|
|
5
|
+
/** Main content area of the {@link Layout}, with the page background in the light and dark color schemes. */
|
|
6
|
+
declare const AppMain: ({ children }: AppMainProps) => import("react/jsx-runtime").JSX.Element;
|
|
7
|
+
export default AppMain;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import App_module_default from "./App.module.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { Box } from "@mantine/core";
|
|
5
|
+
// src/component/atom/AppMain/AppMain.tsx
|
|
6
|
+
/** Main content area of the {@link Layout}, with the page background in the light and dark color schemes. */
|
|
7
|
+
var AppMain = ({ children }) => /* @__PURE__ */ jsx(Box, {
|
|
8
|
+
p: 0,
|
|
9
|
+
className: App_module_default.main,
|
|
10
|
+
children
|
|
11
|
+
});
|
|
12
|
+
export { AppMain as default };
|
|
13
|
+
|
|
14
|
+
//# sourceMappingURL=AppMain.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AppMain.js","names":["classes"],"sources":["../../../../src/component/atom/AppMain/AppMain.tsx"],"sourcesContent":["import { ReactNode } from 'react';\n\nimport { Box } from '@mantine/core';\n\nimport classes from './App.module.css';\n\ntype AppMainProps = {\n children: ReactNode;\n};\n\n/** Main content area of the {@link Layout}, with the page background in the light and dark color schemes. */\nconst AppMain = ({ children }: AppMainProps) => (\n <Box p={0} className={classes.main}>\n {children}\n </Box>\n);\n\nexport default AppMain;\n"],"mappings":";;;;;;AAWA,IAAM,WAAW,EAAE,eACf,oBAAC,KAAD;CAAK,GAAG;CAAG,WAAWA,mBAAQ;CACzB;AACA,CAAA"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useKitMessages } from "../../../provider/useKit.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { ActionIcon, Tooltip } from "@mantine/core";
|
|
5
|
+
import { IconX } from "@tabler/icons-react";
|
|
6
|
+
// src/component/atom/CancelEditButton/CancelEditButton.tsx
|
|
7
|
+
/** Button that cancels the editing of a table row edited in place. */
|
|
8
|
+
var CancelEditButton = ({ onClick }) => {
|
|
9
|
+
const label = useKitMessages().rowEdit.cancel;
|
|
10
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
11
|
+
label,
|
|
12
|
+
children: /* @__PURE__ */ jsx(ActionIcon, {
|
|
13
|
+
size: "sm",
|
|
14
|
+
variant: "subtle",
|
|
15
|
+
color: "red",
|
|
16
|
+
onClick,
|
|
17
|
+
"aria-label": label,
|
|
18
|
+
children: /* @__PURE__ */ jsx(IconX, { size: 16 })
|
|
19
|
+
})
|
|
20
|
+
});
|
|
21
|
+
};
|
|
22
|
+
export { CancelEditButton as default };
|
|
23
|
+
|
|
24
|
+
//# sourceMappingURL=CancelEditButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CancelEditButton.js","names":[],"sources":["../../../../src/component/atom/CancelEditButton/CancelEditButton.tsx"],"sourcesContent":["import { ActionIcon, Tooltip } from '@mantine/core';\nimport { IconX } from '@tabler/icons-react';\n\nimport { useKitMessages } from '../../../provider/useKit';\n\ntype Props = {\n onClick: () => void;\n};\n\n/** Button that cancels the editing of a table row edited in place. */\nconst CancelEditButton = ({ onClick }: Props) => {\n const label = useKitMessages().rowEdit.cancel;\n\n return (\n <Tooltip label={label}>\n <ActionIcon size=\"sm\" variant=\"subtle\" color=\"red\" onClick={onClick} aria-label={label}>\n <IconX size={16} />\n </ActionIcon>\n </Tooltip>\n );\n};\n\nexport default CancelEditButton;\n"],"mappings":";;;;;;;AAUA,IAAM,oBAAoB,EAAE,cAAqB;CAC7C,MAAM,QAAQ,eAAe,CAAC,CAAC,QAAQ;CAEvC,OACI,oBAAC,SAAD;EAAgB;EACZ,UAAA,oBAAC,YAAD;GAAY,MAAK;GAAK,SAAQ;GAAS,OAAM;GAAe;GAAS,cAAY;GAC7E,UAAA,oBAAC,OAAD,EAAO,MAAM,GAAK,CAAA;EACV,CAAA;CACP,CAAA;AAEjB"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
type Props = {
|
|
2
|
+
onClick: () => void;
|
|
3
|
+
/** Disabled while no value of the row was changed (nothing to confirm). */
|
|
4
|
+
disabled?: boolean;
|
|
5
|
+
};
|
|
6
|
+
/**
|
|
7
|
+
* Button that confirms the editing of a table row edited in place.
|
|
8
|
+
*
|
|
9
|
+
* The `<span>` around the `ActionIcon` keeps the `Tooltip` working while the button is `disabled`: a disabled native
|
|
10
|
+
* HTML element fires no pointer events, so the `Tooltip` could not detect the hover on the button itself.
|
|
11
|
+
*/
|
|
12
|
+
declare const ConfirmEditButton: ({ onClick, disabled }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
13
|
+
export default ConfirmEditButton;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useKitMessages } from "../../../provider/useKit.js";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
import { ActionIcon, Tooltip } from "@mantine/core";
|
|
5
|
+
import { IconCheck } from "@tabler/icons-react";
|
|
6
|
+
// src/component/atom/ConfirmEditButton/ConfirmEditButton.tsx
|
|
7
|
+
/**
|
|
8
|
+
* Button that confirms the editing of a table row edited in place.
|
|
9
|
+
*
|
|
10
|
+
* The `<span>` around the `ActionIcon` keeps the `Tooltip` working while the button is `disabled`: a disabled native
|
|
11
|
+
* HTML element fires no pointer events, so the `Tooltip` could not detect the hover on the button itself.
|
|
12
|
+
*/
|
|
13
|
+
var ConfirmEditButton = ({ onClick, disabled }) => {
|
|
14
|
+
const label = useKitMessages().rowEdit.confirm;
|
|
15
|
+
return /* @__PURE__ */ jsx(Tooltip, {
|
|
16
|
+
label,
|
|
17
|
+
children: /* @__PURE__ */ jsx("span", { children: /* @__PURE__ */ jsx(ActionIcon, {
|
|
18
|
+
size: "sm",
|
|
19
|
+
variant: "subtle",
|
|
20
|
+
color: "green",
|
|
21
|
+
onClick,
|
|
22
|
+
disabled,
|
|
23
|
+
"aria-label": label,
|
|
24
|
+
children: /* @__PURE__ */ jsx(IconCheck, { size: 16 })
|
|
25
|
+
}) })
|
|
26
|
+
});
|
|
27
|
+
};
|
|
28
|
+
export { ConfirmEditButton as default };
|
|
29
|
+
|
|
30
|
+
//# sourceMappingURL=ConfirmEditButton.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ConfirmEditButton.js","names":[],"sources":["../../../../src/component/atom/ConfirmEditButton/ConfirmEditButton.tsx"],"sourcesContent":["import { ActionIcon, Tooltip } from '@mantine/core';\nimport { IconCheck } from '@tabler/icons-react';\n\nimport { useKitMessages } from '../../../provider/useKit';\n\ntype Props = {\n onClick: () => void;\n\n /** Disabled while no value of the row was changed (nothing to confirm). */\n disabled?: boolean;\n};\n\n/**\n * Button that confirms the editing of a table row edited in place.\n *\n * The `<span>` around the `ActionIcon` keeps the `Tooltip` working while the button is `disabled`: a disabled native\n * HTML element fires no pointer events, so the `Tooltip` could not detect the hover on the button itself.\n */\nconst ConfirmEditButton = ({ onClick, disabled }: Props) => {\n const label = useKitMessages().rowEdit.confirm;\n\n return (\n <Tooltip label={label}>\n <span>\n <ActionIcon\n size=\"sm\"\n variant=\"subtle\"\n color=\"green\"\n onClick={onClick}\n disabled={disabled}\n aria-label={label}\n >\n <IconCheck size={16} />\n </ActionIcon>\n </span>\n </Tooltip>\n );\n};\n\nexport default ConfirmEditButton;\n"],"mappings":";;;;;;;;;;;;AAkBA,IAAM,qBAAqB,EAAE,SAAS,eAAsB;CACxD,MAAM,QAAQ,eAAe,CAAC,CAAC,QAAQ;CAEvC,OACI,oBAAC,SAAD;EAAgB;EACZ,UAAA,oBAAC,QAAD,EAAA,UACI,oBAAC,YAAD;GACI,MAAK;GACL,SAAQ;GACR,OAAM;GACG;GACC;GACV,cAAY;GAEZ,UAAA,oBAAC,WAAD,EAAW,MAAM,GAAK,CAAA;EACd,CAAA,EACV,CAAA;CACD,CAAA;AAEjB"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { ReactElement } from 'react';
|
|
2
|
+
import { DateInputProps } from '@mantine/dates';
|
|
3
|
+
export interface DateProps extends DateInputProps {
|
|
4
|
+
label: string;
|
|
5
|
+
}
|
|
6
|
+
/** Clearable date input in the date format of the locale (e.g. `DD/MM/YYYY` in `pt-BR`). */
|
|
7
|
+
export declare function DateField({ label, value, ...rest }: DateProps): ReactElement;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useKitMessages } from "../../../provider/useKit.js";
|
|
3
|
+
import { parseDate } from "../../../util/DateUtil.js";
|
|
4
|
+
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { DateInput } from "@mantine/dates";
|
|
6
|
+
// src/component/atom/DateField/DateField.tsx
|
|
7
|
+
/** Clearable date input in the date format of the locale (e.g. `DD/MM/YYYY` in `pt-BR`). */
|
|
8
|
+
function DateField({ label, value, ...rest }) {
|
|
9
|
+
const { dateFormat } = useKitMessages().common;
|
|
10
|
+
return /* @__PURE__ */ jsx(DateInput, {
|
|
11
|
+
label,
|
|
12
|
+
placeholder: dateFormat,
|
|
13
|
+
valueFormat: dateFormat,
|
|
14
|
+
value: parseDate(value, dateFormat),
|
|
15
|
+
clearable: true,
|
|
16
|
+
...rest
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
export { DateField };
|
|
20
|
+
|
|
21
|
+
//# sourceMappingURL=DateField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DateField.js","names":[],"sources":["../../../../src/component/atom/DateField/DateField.tsx"],"sourcesContent":["import { ReactElement } from 'react';\nimport { DateInput, DateInputProps } from '@mantine/dates';\n\nimport { useKitMessages } from '../../../provider/useKit';\nimport { parseDate } from '../../../util/DateUtil';\n\nexport interface DateProps extends DateInputProps {\n label: string;\n}\n\n/** Clearable date input in the date format of the locale (e.g. `DD/MM/YYYY` in `pt-BR`). */\nexport function DateField({ label, value, ...rest }: DateProps): ReactElement {\n const { dateFormat } = useKitMessages().common;\n\n return (\n <DateInput\n label={label}\n placeholder={dateFormat}\n valueFormat={dateFormat}\n value={parseDate(value, dateFormat)}\n clearable\n {...rest}\n />\n );\n}\n"],"mappings":";;;;;;;AAWA,SAAgB,UAAU,EAAE,OAAO,OAAO,GAAG,QAAiC;CAC1E,MAAM,EAAE,eAAe,eAAe,CAAC,CAAC;CAExC,OACI,oBAAC,WAAD;EACW;EACP,aAAa;EACb,aAAa;EACb,OAAO,UAAU,OAAO,UAAU;EAClC,WAAA;EACA,GAAI;CACP,CAAA;AAET"}
|