@multiplatform.one/frappe-ui 6.7.0 → 7.1.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/dist/cjs/FrappeAssignment.cjs +2 -0
- package/dist/cjs/FrappeAssignment.native.js +2 -0
- package/dist/cjs/FrappeAssignment.native.js.map +1 -1
- package/dist/cjs/FrappeCalendar.cjs +5 -7
- package/dist/cjs/FrappeCalendar.native.js +5 -9
- package/dist/cjs/FrappeCalendar.native.js.map +1 -1
- package/dist/cjs/FrappeChartCard.cjs +2 -0
- package/dist/cjs/FrappeChartCard.native.js +2 -0
- package/dist/cjs/FrappeChartCard.native.js.map +1 -1
- package/dist/cjs/FrappeDashboard.cjs +11 -22
- package/dist/cjs/FrappeDashboard.native.js +20 -22
- package/dist/cjs/FrappeDashboard.native.js.map +1 -1
- package/dist/cjs/FrappeForm.cjs +3 -1
- package/dist/cjs/FrappeForm.native.js +3 -1
- package/dist/cjs/FrappeForm.native.js.map +1 -1
- package/dist/cjs/FrappeGantt.cjs +5 -7
- package/dist/cjs/FrappeGantt.native.js +5 -9
- package/dist/cjs/FrappeGantt.native.js.map +1 -1
- package/dist/cjs/FrappeImageView.cjs +3 -1
- package/dist/cjs/FrappeImageView.native.js +3 -1
- package/dist/cjs/FrappeImageView.native.js.map +1 -1
- package/dist/cjs/FrappeKPICard.cjs +2 -0
- package/dist/cjs/FrappeKPICard.native.js +2 -0
- package/dist/cjs/FrappeKPICard.native.js.map +1 -1
- package/dist/cjs/FrappeKanban.cjs +3 -1
- package/dist/cjs/FrappeKanban.native.js +3 -1
- package/dist/cjs/FrappeKanban.native.js.map +1 -1
- package/dist/cjs/FrappeLikedBy.cjs +2 -0
- package/dist/cjs/FrappeLikedBy.native.js +2 -0
- package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
- package/dist/cjs/FrappeList.cjs +3 -1
- package/dist/cjs/FrappeList.native.js +3 -1
- package/dist/cjs/FrappeList.native.js.map +1 -1
- package/dist/cjs/FrappeListView.cjs +6 -12
- package/dist/cjs/FrappeListView.native.js +13 -12
- package/dist/cjs/FrappeListView.native.js.map +1 -1
- package/dist/cjs/FrappeProvider.cjs +5 -1
- package/dist/cjs/FrappeProvider.native.js +5 -1
- package/dist/cjs/FrappeProvider.native.js.map +1 -1
- package/dist/cjs/FrappeReportBuilder.cjs +2 -0
- package/dist/cjs/FrappeReportBuilder.native.js +2 -0
- package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
- package/dist/cjs/FrappeReportView.cjs +23 -45
- package/dist/cjs/FrappeReportView.native.js +35 -50
- package/dist/cjs/FrappeReportView.native.js.map +1 -1
- package/dist/cjs/FrappeTable.cjs +105 -31
- package/dist/cjs/FrappeTable.native.js +140 -42
- package/dist/cjs/FrappeTable.native.js.map +1 -1
- package/dist/cjs/FrappeTreeView.cjs +3 -1
- package/dist/cjs/FrappeTreeView.native.js +3 -1
- package/dist/cjs/FrappeTreeView.native.js.map +1 -1
- package/dist/cjs/SyncErrorNotice.cjs +76 -0
- package/dist/cjs/SyncErrorNotice.native.js +92 -0
- package/dist/cjs/SyncErrorNotice.native.js.map +1 -0
- package/dist/cjs/commentActions.cjs +120 -0
- package/dist/cjs/commentActions.native.js +129 -0
- package/dist/cjs/commentActions.native.js.map +1 -0
- package/dist/cjs/components/attachments.cjs +2 -0
- package/dist/cjs/components/attachments.native.js +2 -0
- package/dist/cjs/components/attachments.native.js.map +1 -1
- package/dist/cjs/components/tags.cjs +5 -0
- package/dist/cjs/components/tags.native.js +5 -0
- package/dist/cjs/components/tags.native.js.map +1 -1
- package/dist/cjs/components/timeline.cjs +29 -2
- package/dist/cjs/components/timeline.native.js +33 -2
- package/dist/cjs/components/timeline.native.js.map +1 -1
- package/dist/cjs/desk/DeskFormSidebar.cjs +2 -0
- package/dist/cjs/desk/DeskFormSidebar.native.js +2 -0
- package/dist/cjs/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/cjs/fieldRegistry.cjs +2 -0
- package/dist/cjs/fieldRegistry.native.js +2 -0
- package/dist/cjs/fieldRegistry.native.js.map +1 -1
- package/dist/cjs/fields/Date/index.cjs +71 -7
- package/dist/cjs/fields/Date/index.native.js +325 -37
- package/dist/cjs/fields/Date/index.native.js.map +1 -1
- package/dist/cjs/fields/Date/types.cjs +18 -0
- package/dist/cjs/fields/Date/types.native.js +21 -0
- package/dist/cjs/fields/Date/types.native.js.map +1 -0
- package/dist/cjs/fields/Date/wire.cjs +4 -8
- package/dist/cjs/fields/Date/wire.native.js +4 -11
- package/dist/cjs/fields/Date/wire.native.js.map +1 -1
- package/dist/cjs/fields/DynamicLink.cjs +2 -0
- package/dist/cjs/fields/DynamicLink.native.js +2 -0
- package/dist/cjs/fields/DynamicLink.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload.cjs +2 -0
- package/dist/cjs/fields/FileUpload.native.js +2 -0
- package/dist/cjs/fields/FileUpload.native.js.map +1 -1
- package/dist/cjs/fields/TableMultiSelect.cjs +6 -1
- package/dist/cjs/fields/TableMultiSelect.native.js +6 -1
- package/dist/cjs/fields/TableMultiSelect.native.js.map +1 -1
- package/dist/cjs/frappeStoryTarget.cjs +88 -0
- package/dist/cjs/frappeStoryTarget.native.js +100 -0
- package/dist/cjs/frappeStoryTarget.native.js.map +1 -1
- package/dist/cjs/frappeUsers.cjs +2 -0
- package/dist/cjs/frappeUsers.native.js +2 -0
- package/dist/cjs/frappeUsers.native.js.map +1 -1
- package/dist/cjs/index.cjs +17 -4
- package/dist/cjs/index.native.js +17 -4
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/liveErrors.cjs +5 -1
- package/dist/cjs/liveErrors.native.js +5 -1
- package/dist/cjs/liveErrors.native.js.map +1 -1
- package/dist/cjs/useFrappeAggregate.cjs +13 -1
- package/dist/cjs/useFrappeAggregate.native.js +14 -1
- package/dist/cjs/useFrappeAggregate.native.js.map +1 -1
- package/dist/cjs/useFrappeFacets.cjs +329 -0
- package/dist/cjs/useFrappeFacets.native.js +632 -0
- package/dist/cjs/useFrappeFacets.native.js.map +1 -0
- package/dist/esm/FrappeAssignment.mjs +2 -0
- package/dist/esm/FrappeAssignment.mjs.map +1 -1
- package/dist/esm/FrappeAssignment.native.js +2 -0
- package/dist/esm/FrappeAssignment.native.js.map +1 -1
- package/dist/esm/FrappeCalendar.mjs +6 -8
- package/dist/esm/FrappeCalendar.mjs.map +1 -1
- package/dist/esm/FrappeCalendar.native.js +6 -10
- package/dist/esm/FrappeCalendar.native.js.map +1 -1
- package/dist/esm/FrappeChartCard.mjs +2 -0
- package/dist/esm/FrappeChartCard.mjs.map +1 -1
- package/dist/esm/FrappeChartCard.native.js +2 -0
- package/dist/esm/FrappeChartCard.native.js.map +1 -1
- package/dist/esm/FrappeDashboard.mjs +12 -19
- package/dist/esm/FrappeDashboard.mjs.map +1 -1
- package/dist/esm/FrappeDashboard.native.js +23 -21
- package/dist/esm/FrappeDashboard.native.js.map +1 -1
- package/dist/esm/FrappeForm.mjs +3 -1
- package/dist/esm/FrappeForm.mjs.map +1 -1
- package/dist/esm/FrappeForm.native.js +3 -1
- package/dist/esm/FrappeForm.native.js.map +1 -1
- package/dist/esm/FrappeGantt.mjs +6 -8
- package/dist/esm/FrappeGantt.mjs.map +1 -1
- package/dist/esm/FrappeGantt.native.js +6 -10
- package/dist/esm/FrappeGantt.native.js.map +1 -1
- package/dist/esm/FrappeImageView.mjs +3 -1
- package/dist/esm/FrappeImageView.mjs.map +1 -1
- package/dist/esm/FrappeImageView.native.js +3 -1
- package/dist/esm/FrappeImageView.native.js.map +1 -1
- package/dist/esm/FrappeKPICard.mjs +2 -0
- package/dist/esm/FrappeKPICard.mjs.map +1 -1
- package/dist/esm/FrappeKPICard.native.js +2 -0
- package/dist/esm/FrappeKPICard.native.js.map +1 -1
- package/dist/esm/FrappeKanban.mjs +3 -1
- package/dist/esm/FrappeKanban.mjs.map +1 -1
- package/dist/esm/FrappeKanban.native.js +3 -1
- package/dist/esm/FrappeKanban.native.js.map +1 -1
- package/dist/esm/FrappeLikedBy.mjs +2 -0
- package/dist/esm/FrappeLikedBy.mjs.map +1 -1
- package/dist/esm/FrappeLikedBy.native.js +2 -0
- package/dist/esm/FrappeLikedBy.native.js.map +1 -1
- package/dist/esm/FrappeList.mjs +3 -1
- package/dist/esm/FrappeList.mjs.map +1 -1
- package/dist/esm/FrappeList.native.js +3 -1
- package/dist/esm/FrappeList.native.js.map +1 -1
- package/dist/esm/FrappeListView.mjs +7 -13
- package/dist/esm/FrappeListView.mjs.map +1 -1
- package/dist/esm/FrappeListView.native.js +15 -14
- package/dist/esm/FrappeListView.native.js.map +1 -1
- package/dist/esm/FrappeProvider.mjs +5 -1
- package/dist/esm/FrappeProvider.mjs.map +1 -1
- package/dist/esm/FrappeProvider.native.js +5 -1
- package/dist/esm/FrappeProvider.native.js.map +1 -1
- package/dist/esm/FrappeReportBuilder.mjs +2 -0
- package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
- package/dist/esm/FrappeReportBuilder.native.js +2 -0
- package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
- package/dist/esm/FrappeReportView.mjs +26 -49
- package/dist/esm/FrappeReportView.mjs.map +1 -1
- package/dist/esm/FrappeReportView.native.js +38 -54
- package/dist/esm/FrappeReportView.native.js.map +1 -1
- package/dist/esm/FrappeTable.mjs +107 -33
- package/dist/esm/FrappeTable.mjs.map +1 -1
- package/dist/esm/FrappeTable.native.js +142 -44
- package/dist/esm/FrappeTable.native.js.map +1 -1
- package/dist/esm/FrappeTreeView.mjs +3 -1
- package/dist/esm/FrappeTreeView.mjs.map +1 -1
- package/dist/esm/FrappeTreeView.native.js +3 -1
- package/dist/esm/FrappeTreeView.native.js.map +1 -1
- package/dist/esm/SyncErrorNotice.mjs +51 -0
- package/dist/esm/SyncErrorNotice.mjs.map +1 -0
- package/dist/esm/SyncErrorNotice.native.js +53 -0
- package/dist/esm/SyncErrorNotice.native.js.map +1 -0
- package/dist/esm/commentActions.mjs +95 -0
- package/dist/esm/commentActions.mjs.map +1 -0
- package/dist/esm/commentActions.native.js +101 -0
- package/dist/esm/commentActions.native.js.map +1 -0
- package/dist/esm/components/attachments.mjs +2 -0
- package/dist/esm/components/attachments.mjs.map +1 -1
- package/dist/esm/components/attachments.native.js +2 -0
- package/dist/esm/components/attachments.native.js.map +1 -1
- package/dist/esm/components/tags.mjs +5 -0
- package/dist/esm/components/tags.mjs.map +1 -1
- package/dist/esm/components/tags.native.js +5 -0
- package/dist/esm/components/tags.native.js.map +1 -1
- package/dist/esm/components/timeline.mjs +31 -4
- package/dist/esm/components/timeline.mjs.map +1 -1
- package/dist/esm/components/timeline.native.js +35 -4
- package/dist/esm/components/timeline.native.js.map +1 -1
- package/dist/esm/desk/DeskFormSidebar.mjs +2 -0
- package/dist/esm/desk/DeskFormSidebar.mjs.map +1 -1
- package/dist/esm/desk/DeskFormSidebar.native.js +2 -0
- package/dist/esm/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/esm/fieldRegistry.mjs +2 -0
- package/dist/esm/fieldRegistry.mjs.map +1 -1
- package/dist/esm/fieldRegistry.native.js +2 -0
- package/dist/esm/fieldRegistry.native.js.map +1 -1
- package/dist/esm/fields/Date/index.mjs +73 -9
- package/dist/esm/fields/Date/index.mjs.map +1 -1
- package/dist/esm/fields/Date/index.native.js +315 -38
- package/dist/esm/fields/Date/index.native.js.map +1 -1
- package/dist/esm/fields/Date/types.mjs +2 -0
- package/dist/esm/fields/Date/types.mjs.map +1 -0
- package/dist/esm/fields/Date/types.native.js +2 -0
- package/dist/esm/fields/Date/types.native.js.map +1 -0
- package/dist/esm/fields/Date/wire.mjs +4 -8
- package/dist/esm/fields/Date/wire.mjs.map +1 -1
- package/dist/esm/fields/Date/wire.native.js +4 -11
- package/dist/esm/fields/Date/wire.native.js.map +1 -1
- package/dist/esm/fields/DynamicLink.mjs +2 -0
- package/dist/esm/fields/DynamicLink.mjs.map +1 -1
- package/dist/esm/fields/DynamicLink.native.js +2 -0
- package/dist/esm/fields/DynamicLink.native.js.map +1 -1
- package/dist/esm/fields/FileUpload.mjs +2 -0
- package/dist/esm/fields/FileUpload.mjs.map +1 -1
- package/dist/esm/fields/FileUpload.native.js +2 -0
- package/dist/esm/fields/FileUpload.native.js.map +1 -1
- package/dist/esm/fields/TableMultiSelect.mjs +7 -2
- package/dist/esm/fields/TableMultiSelect.mjs.map +1 -1
- package/dist/esm/fields/TableMultiSelect.native.js +7 -2
- package/dist/esm/fields/TableMultiSelect.native.js.map +1 -1
- package/dist/esm/frappeStoryTarget.mjs +88 -2
- package/dist/esm/frappeStoryTarget.mjs.map +1 -1
- package/dist/esm/frappeStoryTarget.native.js +100 -2
- package/dist/esm/frappeStoryTarget.native.js.map +1 -1
- package/dist/esm/frappeUsers.mjs +2 -0
- package/dist/esm/frappeUsers.mjs.map +1 -1
- package/dist/esm/frappeUsers.native.js +2 -0
- package/dist/esm/frappeUsers.native.js.map +1 -1
- package/dist/esm/index.mjs +7 -3
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +7 -3
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/liveErrors.mjs +5 -1
- package/dist/esm/liveErrors.mjs.map +1 -1
- package/dist/esm/liveErrors.native.js +5 -1
- package/dist/esm/liveErrors.native.js.map +1 -1
- package/dist/esm/useFrappeAggregate.mjs +13 -1
- package/dist/esm/useFrappeAggregate.mjs.map +1 -1
- package/dist/esm/useFrappeAggregate.native.js +14 -1
- package/dist/esm/useFrappeAggregate.native.js.map +1 -1
- package/dist/esm/useFrappeFacets.mjs +299 -0
- package/dist/esm/useFrappeFacets.mjs.map +1 -0
- package/dist/esm/useFrappeFacets.native.js +599 -0
- package/dist/esm/useFrappeFacets.native.js.map +1 -0
- package/dist/jsx/FrappeAssignment.mjs +2 -0
- package/dist/jsx/FrappeAssignment.mjs.map +1 -1
- package/dist/jsx/FrappeAssignment.native.js +2 -0
- package/dist/jsx/FrappeAssignment.native.js.map +1 -1
- package/dist/jsx/FrappeCalendar.mjs +6 -8
- package/dist/jsx/FrappeCalendar.mjs.map +1 -1
- package/dist/jsx/FrappeCalendar.native.js +5 -9
- package/dist/jsx/FrappeCalendar.native.js.map +1 -1
- package/dist/jsx/FrappeChartCard.mjs +2 -0
- package/dist/jsx/FrappeChartCard.mjs.map +1 -1
- package/dist/jsx/FrappeChartCard.native.js +2 -0
- package/dist/jsx/FrappeChartCard.native.js.map +1 -1
- package/dist/jsx/FrappeDashboard.mjs +12 -19
- package/dist/jsx/FrappeDashboard.mjs.map +1 -1
- package/dist/jsx/FrappeDashboard.native.js +20 -22
- package/dist/jsx/FrappeDashboard.native.js.map +1 -1
- package/dist/jsx/FrappeForm.mjs +3 -1
- package/dist/jsx/FrappeForm.mjs.map +1 -1
- package/dist/jsx/FrappeForm.native.js +3 -1
- package/dist/jsx/FrappeForm.native.js.map +1 -1
- package/dist/jsx/FrappeGantt.mjs +6 -8
- package/dist/jsx/FrappeGantt.mjs.map +1 -1
- package/dist/jsx/FrappeGantt.native.js +5 -9
- package/dist/jsx/FrappeGantt.native.js.map +1 -1
- package/dist/jsx/FrappeImageView.mjs +3 -1
- package/dist/jsx/FrappeImageView.mjs.map +1 -1
- package/dist/jsx/FrappeImageView.native.js +3 -1
- package/dist/jsx/FrappeImageView.native.js.map +1 -1
- package/dist/jsx/FrappeKPICard.mjs +2 -0
- package/dist/jsx/FrappeKPICard.mjs.map +1 -1
- package/dist/jsx/FrappeKPICard.native.js +2 -0
- package/dist/jsx/FrappeKPICard.native.js.map +1 -1
- package/dist/jsx/FrappeKanban.mjs +3 -1
- package/dist/jsx/FrappeKanban.mjs.map +1 -1
- package/dist/jsx/FrappeKanban.native.js +3 -1
- package/dist/jsx/FrappeKanban.native.js.map +1 -1
- package/dist/jsx/FrappeLikedBy.mjs +2 -0
- package/dist/jsx/FrappeLikedBy.mjs.map +1 -1
- package/dist/jsx/FrappeLikedBy.native.js +2 -0
- package/dist/jsx/FrappeLikedBy.native.js.map +1 -1
- package/dist/jsx/FrappeList.mjs +3 -1
- package/dist/jsx/FrappeList.mjs.map +1 -1
- package/dist/jsx/FrappeList.native.js +3 -1
- package/dist/jsx/FrappeList.native.js.map +1 -1
- package/dist/jsx/FrappeListView.mjs +7 -13
- package/dist/jsx/FrappeListView.mjs.map +1 -1
- package/dist/jsx/FrappeListView.native.js +13 -12
- package/dist/jsx/FrappeListView.native.js.map +1 -1
- package/dist/jsx/FrappeProvider.mjs +5 -1
- package/dist/jsx/FrappeProvider.mjs.map +1 -1
- package/dist/jsx/FrappeProvider.native.js +5 -1
- package/dist/jsx/FrappeProvider.native.js.map +1 -1
- package/dist/jsx/FrappeReportBuilder.mjs +2 -0
- package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
- package/dist/jsx/FrappeReportBuilder.native.js +2 -0
- package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
- package/dist/jsx/FrappeReportView.mjs +26 -49
- package/dist/jsx/FrappeReportView.mjs.map +1 -1
- package/dist/jsx/FrappeReportView.native.js +35 -50
- package/dist/jsx/FrappeReportView.native.js.map +1 -1
- package/dist/jsx/FrappeTable.mjs +107 -33
- package/dist/jsx/FrappeTable.mjs.map +1 -1
- package/dist/jsx/FrappeTable.native.js +140 -42
- package/dist/jsx/FrappeTable.native.js.map +1 -1
- package/dist/jsx/FrappeTreeView.mjs +3 -1
- package/dist/jsx/FrappeTreeView.mjs.map +1 -1
- package/dist/jsx/FrappeTreeView.native.js +3 -1
- package/dist/jsx/FrappeTreeView.native.js.map +1 -1
- package/dist/jsx/SyncErrorNotice.mjs +51 -0
- package/dist/jsx/SyncErrorNotice.mjs.map +1 -0
- package/dist/jsx/SyncErrorNotice.native.js +92 -0
- package/dist/jsx/SyncErrorNotice.native.js.map +1 -0
- package/dist/jsx/commentActions.mjs +95 -0
- package/dist/jsx/commentActions.mjs.map +1 -0
- package/dist/jsx/commentActions.native.js +129 -0
- package/dist/jsx/commentActions.native.js.map +1 -0
- package/dist/jsx/components/attachments.mjs +2 -0
- package/dist/jsx/components/attachments.mjs.map +1 -1
- package/dist/jsx/components/attachments.native.js +2 -0
- package/dist/jsx/components/attachments.native.js.map +1 -1
- package/dist/jsx/components/tags.mjs +5 -0
- package/dist/jsx/components/tags.mjs.map +1 -1
- package/dist/jsx/components/tags.native.js +5 -0
- package/dist/jsx/components/tags.native.js.map +1 -1
- package/dist/jsx/components/timeline.mjs +31 -4
- package/dist/jsx/components/timeline.mjs.map +1 -1
- package/dist/jsx/components/timeline.native.js +33 -2
- package/dist/jsx/components/timeline.native.js.map +1 -1
- package/dist/jsx/desk/DeskFormSidebar.mjs +2 -0
- package/dist/jsx/desk/DeskFormSidebar.mjs.map +1 -1
- package/dist/jsx/desk/DeskFormSidebar.native.js +2 -0
- package/dist/jsx/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/jsx/fieldRegistry.mjs +2 -0
- package/dist/jsx/fieldRegistry.mjs.map +1 -1
- package/dist/jsx/fieldRegistry.native.js +2 -0
- package/dist/jsx/fieldRegistry.native.js.map +1 -1
- package/dist/jsx/fields/Date/index.mjs +73 -9
- package/dist/jsx/fields/Date/index.mjs.map +1 -1
- package/dist/jsx/fields/Date/index.native.js +325 -37
- package/dist/jsx/fields/Date/index.native.js.map +1 -1
- package/dist/jsx/fields/Date/types.mjs +2 -0
- package/dist/jsx/fields/Date/types.mjs.map +1 -0
- package/dist/jsx/fields/Date/types.native.js +21 -0
- package/dist/jsx/fields/Date/types.native.js.map +1 -0
- package/dist/jsx/fields/Date/wire.mjs +4 -8
- package/dist/jsx/fields/Date/wire.mjs.map +1 -1
- package/dist/jsx/fields/Date/wire.native.js +4 -11
- package/dist/jsx/fields/Date/wire.native.js.map +1 -1
- package/dist/jsx/fields/DynamicLink.mjs +2 -0
- package/dist/jsx/fields/DynamicLink.mjs.map +1 -1
- package/dist/jsx/fields/DynamicLink.native.js +2 -0
- package/dist/jsx/fields/DynamicLink.native.js.map +1 -1
- package/dist/jsx/fields/FileUpload.mjs +2 -0
- package/dist/jsx/fields/FileUpload.mjs.map +1 -1
- package/dist/jsx/fields/FileUpload.native.js +2 -0
- package/dist/jsx/fields/FileUpload.native.js.map +1 -1
- package/dist/jsx/fields/TableMultiSelect.mjs +7 -2
- package/dist/jsx/fields/TableMultiSelect.mjs.map +1 -1
- package/dist/jsx/fields/TableMultiSelect.native.js +6 -1
- package/dist/jsx/fields/TableMultiSelect.native.js.map +1 -1
- package/dist/jsx/frappeStoryTarget.mjs +88 -2
- package/dist/jsx/frappeStoryTarget.mjs.map +1 -1
- package/dist/jsx/frappeStoryTarget.native.js +100 -0
- package/dist/jsx/frappeStoryTarget.native.js.map +1 -1
- package/dist/jsx/frappeUsers.mjs +2 -0
- package/dist/jsx/frappeUsers.mjs.map +1 -1
- package/dist/jsx/frappeUsers.native.js +2 -0
- package/dist/jsx/frappeUsers.native.js.map +1 -1
- package/dist/jsx/index.js +7 -3
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +7 -3
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +17 -4
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/liveErrors.mjs +5 -1
- package/dist/jsx/liveErrors.mjs.map +1 -1
- package/dist/jsx/liveErrors.native.js +5 -1
- package/dist/jsx/liveErrors.native.js.map +1 -1
- package/dist/jsx/useFrappeAggregate.mjs +13 -1
- package/dist/jsx/useFrappeAggregate.mjs.map +1 -1
- package/dist/jsx/useFrappeAggregate.native.js +14 -1
- package/dist/jsx/useFrappeAggregate.native.js.map +1 -1
- package/dist/jsx/useFrappeFacets.mjs +299 -0
- package/dist/jsx/useFrappeFacets.mjs.map +1 -0
- package/dist/jsx/useFrappeFacets.native.js +632 -0
- package/dist/jsx/useFrappeFacets.native.js.map +1 -0
- package/package.json +20 -20
- package/src/FormSidebar.stories.tsx +88 -10
- package/src/FrappeAssignment.tsx +2 -0
- package/src/FrappeCalendar.tsx +12 -7
- package/src/FrappeChartCard.tsx +9 -2
- package/src/FrappeDashboard.spec.tsx +95 -0
- package/src/FrappeDashboard.tsx +20 -41
- package/src/FrappeForm.stories.tsx +53 -46
- package/src/FrappeForm.tsx +11 -1
- package/src/FrappeGantt.tsx +12 -7
- package/src/FrappeImageView.tsx +11 -1
- package/src/FrappeKPICard.stories.tsx +4 -1
- package/src/FrappeKPICard.tsx +2 -0
- package/src/FrappeKanban.tsx +4 -0
- package/src/FrappeLikedBy.stories.tsx +26 -10
- package/src/FrappeLikedBy.tsx +2 -0
- package/src/FrappeList.tsx +11 -1
- package/src/FrappeListView.spec.tsx +144 -0
- package/src/FrappeListView.tsx +11 -23
- package/src/FrappeProvider.tsx +30 -2
- package/src/FrappeReportBuilder.tsx +2 -0
- package/src/FrappeReportView.spec.tsx +140 -16
- package/src/FrappeReportView.stories.tsx +12 -6
- package/src/FrappeReportView.tsx +62 -61
- package/src/FrappeTable.keepRows.spec.tsx +200 -0
- package/src/FrappeTable.retryStorm.spec.tsx +140 -0
- package/src/FrappeTable.spec.tsx +222 -0
- package/src/FrappeTable.tsx +211 -54
- package/src/FrappeTreeView.tsx +11 -1
- package/src/SyncErrorNotice.spec.tsx +60 -0
- package/src/SyncErrorNotice.tsx +81 -0
- package/src/commentActions.ts +157 -0
- package/src/components/attachments.tsx +2 -0
- package/src/components/tags.tsx +14 -1
- package/src/components/timeline.optimistic.spec.tsx +106 -0
- package/src/components/timeline.tsx +36 -4
- package/src/desk/DeskFormSidebar.tsx +2 -0
- package/src/fieldRegistry.ts +2 -0
- package/src/fields/Date/index.native.tsx +410 -0
- package/src/fields/Date/index.tsx +138 -57
- package/src/fields/Date/nativePresentation.spec.tsx +251 -0
- package/src/fields/Date/typeParity.spec.tsx +480 -0
- package/src/fields/Date/types.ts +53 -0
- package/src/fields/Date/wire.spec.ts +63 -1
- package/src/fields/Date/wire.ts +17 -17
- package/src/fields/DynamicLink.tsx +2 -0
- package/src/fields/FileUpload.tsx +2 -0
- package/src/fields/TableMultiSelect.tsx +6 -3
- package/src/frappeStoryTarget.tsx +104 -1
- package/src/frappeUsers.ts +2 -0
- package/src/index.spec.ts +62 -0
- package/src/index.ts +36 -2
- package/src/liveErrors.spec.ts +50 -0
- package/src/liveErrors.ts +11 -1
- package/src/useFrappeAggregate.ts +20 -1
- package/src/useFrappeFacets.spec.tsx +436 -0
- package/src/useFrappeFacets.ts +568 -0
- package/types/FrappeAssignment.d.ts.map +1 -1
- package/types/FrappeCalendar.d.ts.map +1 -1
- package/types/FrappeChartCard.d.ts +1 -2
- package/types/FrappeChartCard.d.ts.map +1 -1
- package/types/FrappeDashboard.d.ts +0 -1
- package/types/FrappeDashboard.d.ts.map +1 -1
- package/types/FrappeForm.d.ts.map +1 -1
- package/types/FrappeGantt.d.ts.map +1 -1
- package/types/FrappeKPICard.d.ts.map +1 -1
- package/types/FrappeKanban.d.ts.map +1 -1
- package/types/FrappeLikedBy.d.ts.map +1 -1
- package/types/FrappeList.d.ts.map +1 -1
- package/types/FrappeListView.d.ts.map +1 -1
- package/types/FrappeProvider.d.ts +18 -1
- package/types/FrappeProvider.d.ts.map +1 -1
- package/types/FrappeReportBuilder.d.ts.map +1 -1
- package/types/FrappeReportView.d.ts +22 -15
- package/types/FrappeReportView.d.ts.map +1 -1
- package/types/FrappeTable.d.ts +21 -2
- package/types/FrappeTable.d.ts.map +1 -1
- package/types/FrappeTreeView.d.ts.map +1 -1
- package/types/SyncErrorNotice.d.ts +38 -0
- package/types/SyncErrorNotice.d.ts.map +1 -0
- package/types/commentActions.d.ts +46 -0
- package/types/commentActions.d.ts.map +1 -0
- package/types/components/attachments.d.ts.map +1 -1
- package/types/components/tags.d.ts.map +1 -1
- package/types/components/timeline.d.ts.map +1 -1
- package/types/desk/DeskFormSidebar.d.ts.map +1 -1
- package/types/fieldRegistry.d.ts.map +1 -1
- package/types/fields/Date/index.d.ts +22 -12
- package/types/fields/Date/index.d.ts.map +1 -1
- package/types/fields/Date/index.native.d.ts +14 -0
- package/types/fields/Date/index.native.d.ts.map +1 -0
- package/types/fields/Date/types.d.ts +27 -0
- package/types/fields/Date/types.d.ts.map +1 -0
- package/types/fields/Date/wire.d.ts +13 -9
- package/types/fields/Date/wire.d.ts.map +1 -1
- package/types/fields/DynamicLink.d.ts.map +1 -1
- package/types/fields/FileUpload.d.ts.map +1 -1
- package/types/fields/TableMultiSelect.d.ts.map +1 -1
- package/types/frappeStoryTarget.d.ts +19 -1
- package/types/frappeStoryTarget.d.ts.map +1 -1
- package/types/frappeUsers.d.ts.map +1 -1
- package/types/index.d.ts +6 -2
- package/types/index.d.ts.map +1 -1
- package/types/liveErrors.d.ts +4 -0
- package/types/liveErrors.d.ts.map +1 -1
- package/types/useFrappeAggregate.d.ts +4 -0
- package/types/useFrappeAggregate.d.ts.map +1 -1
- package/types/useFrappeFacets.d.ts +143 -0
- package/types/useFrappeFacets.d.ts.map +1 -0
- package/dist/cjs/fields/Date/date.native.js +0 -277
- package/dist/cjs/fields/Date/date.native.js.map +0 -1
- package/dist/esm/fields/Date/date.native.js +0 -238
- package/dist/esm/fields/Date/date.native.js.map +0 -1
- package/dist/jsx/fields/Date/date.native.js +0 -277
- package/dist/jsx/fields/Date/date.native.js.map +0 -1
- package/src/fields/Date/date.native.tsx +0 -299
- package/types/fields/Date/date.native.d.ts +0 -19
- package/types/fields/Date/date.native.d.ts.map +0 -1
|
@@ -0,0 +1,410 @@
|
|
|
1
|
+
import {
|
|
2
|
+
formatAbsoluteDate,
|
|
3
|
+
formatAbsoluteDateTime,
|
|
4
|
+
formatTimeOfDay,
|
|
5
|
+
} from "@multiplatform.one/theme";
|
|
6
|
+
import {
|
|
7
|
+
Field,
|
|
8
|
+
FieldLayout,
|
|
9
|
+
Skeleton,
|
|
10
|
+
formCommonColors,
|
|
11
|
+
getFieldError,
|
|
12
|
+
mergeFieldHandler,
|
|
13
|
+
useFormField,
|
|
14
|
+
useResolvedValidators,
|
|
15
|
+
} from "@multiplatform.one/forms";
|
|
16
|
+
import { useState } from "react";
|
|
17
|
+
import { Modal, Pressable, StyleSheet, useColorScheme } from "react-native";
|
|
18
|
+
import { platform } from "@multiplatform.one/platform";
|
|
19
|
+
import DateTimePicker, { type DateTimePickerEvent } from "@react-native-community/datetimepicker";
|
|
20
|
+
import { Button, Text, View, XStack, YStack, useProps, useTheme, useThemeName } from "tamagui";
|
|
21
|
+
import type { DateProps } from "./types";
|
|
22
|
+
import { fromFrappeDateValue, toFrappeDateValue } from "./wire";
|
|
23
|
+
|
|
24
|
+
export type { DateProps } from "./types";
|
|
25
|
+
|
|
26
|
+
type FieldType = "date" | "datetime" | "time";
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Display value for the trigger — the house registers (LC-12 render channel),
|
|
30
|
+
* so the native picker reads the same voice as the web picker, table date
|
|
31
|
+
* cells and the timeline. A picker is an editing surface, so the year is
|
|
32
|
+
* always shown.
|
|
33
|
+
*/
|
|
34
|
+
function formatDisplayValue(value: string, type: FieldType): string {
|
|
35
|
+
if (!value) return "";
|
|
36
|
+
try {
|
|
37
|
+
const date = fromFrappeDateValue(value, type);
|
|
38
|
+
if (type === "time") return formatTimeOfDay(date);
|
|
39
|
+
if (type === "datetime") return formatAbsoluteDateTime(date, { year: "always" });
|
|
40
|
+
return formatAbsoluteDate(date, { year: "always" });
|
|
41
|
+
} catch {
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* The form branch stores what the picker committed (a `Date`, matching the
|
|
48
|
+
* web half); the standalone branch is handed the Frappe wire string. Both
|
|
49
|
+
* arrive here so the rest of the component reads one shape.
|
|
50
|
+
*/
|
|
51
|
+
function toWireValue(raw: unknown, type: FieldType): string {
|
|
52
|
+
if (raw == null || raw === "") return "";
|
|
53
|
+
if (raw instanceof Date) return Number.isNaN(raw.getTime()) ? "" : toFrappeDateValue(raw, type);
|
|
54
|
+
return String(raw);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** What the picker opens on: the current value, else now. */
|
|
58
|
+
function seedDate(wire: string, type: FieldType): Date {
|
|
59
|
+
if (!wire) return new Date();
|
|
60
|
+
try {
|
|
61
|
+
const parsed = fromFrappeDateValue(wire, type);
|
|
62
|
+
return Number.isNaN(parsed.getTime()) ? new Date() : parsed;
|
|
63
|
+
} catch {
|
|
64
|
+
return new Date();
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* The OS picker renders itself, so the only styling channel it exposes is
|
|
70
|
+
* light/dark plus an accent — see the R-IDENTITY declaration for this part.
|
|
71
|
+
* Read the app theme first and fall back to the OS scheme, the same order
|
|
72
|
+
* the native rich-text editor uses.
|
|
73
|
+
*/
|
|
74
|
+
function useNativePickerScheme(): "light" | "dark" {
|
|
75
|
+
const themeName = useThemeName();
|
|
76
|
+
const osScheme = useColorScheme();
|
|
77
|
+
if (themeName) return String(themeName).startsWith("dark") ? "dark" : "light";
|
|
78
|
+
return osScheme === "dark" ? "dark" : "light";
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Native `Date` field for iOS and Android.
|
|
83
|
+
*
|
|
84
|
+
* Resolution picks this file over `index.tsx` on native, so the field is the
|
|
85
|
+
* real OS picker: the iOS 14+ calendar for dates (`inline`), the wheel for
|
|
86
|
+
* times, and the Material dialog on Android. Declared as `Date` rather than
|
|
87
|
+
* written as `function Date` so the global `Date` constructor stays reachable
|
|
88
|
+
* inside this module.
|
|
89
|
+
*/
|
|
90
|
+
function DateField<
|
|
91
|
+
TData extends Record<string, unknown> = Record<string, unknown>,
|
|
92
|
+
TName extends string = string,
|
|
93
|
+
>(props: DateProps<TData, TName>) {
|
|
94
|
+
const {
|
|
95
|
+
compact,
|
|
96
|
+
defaultValue,
|
|
97
|
+
disabled,
|
|
98
|
+
error: errorProp,
|
|
99
|
+
form,
|
|
100
|
+
helperText,
|
|
101
|
+
id: idProp,
|
|
102
|
+
inputProps: _inputProps,
|
|
103
|
+
label,
|
|
104
|
+
labelProps,
|
|
105
|
+
maxDate,
|
|
106
|
+
minDate,
|
|
107
|
+
mode,
|
|
108
|
+
name,
|
|
109
|
+
onBlur,
|
|
110
|
+
onChange,
|
|
111
|
+
placeholder,
|
|
112
|
+
preserveValue,
|
|
113
|
+
readOnly,
|
|
114
|
+
required,
|
|
115
|
+
size,
|
|
116
|
+
skeleton,
|
|
117
|
+
type = "date",
|
|
118
|
+
validators,
|
|
119
|
+
value,
|
|
120
|
+
} = useProps(props) as DateProps<TData, TName> & Record<string, unknown>;
|
|
121
|
+
|
|
122
|
+
const { resolvedForm, knobProps, id } = useFormField({ form, id: idProp, compact });
|
|
123
|
+
const resolvedValidators = useResolvedValidators(required, validators, label, name);
|
|
124
|
+
const themeVariant = useNativePickerScheme();
|
|
125
|
+
const theme = useTheme();
|
|
126
|
+
const accentColor = theme.accentBackground?.val;
|
|
127
|
+
|
|
128
|
+
const [showPicker, setShowPicker] = useState(false);
|
|
129
|
+
const [showTimePicker, setShowTimePicker] = useState(false);
|
|
130
|
+
const [tempDate, setTempDate] = useState<Date | null>(null);
|
|
131
|
+
|
|
132
|
+
const fieldType = type as FieldType;
|
|
133
|
+
const isIOS = platform.isIos;
|
|
134
|
+
const pickerMode: "date" | "time" =
|
|
135
|
+
fieldType === "time" || (fieldType === "datetime" && showTimePicker) ? "time" : "date";
|
|
136
|
+
// iOS 14 made the calendar the date presentation and left the wheel to time;
|
|
137
|
+
// `spinner` for a date is Apple's legacy style. `inline` rather than
|
|
138
|
+
// `compact` because the picker already lives in a sheet with its own
|
|
139
|
+
// Cancel/Done — `compact` would be a field that opens a second popover.
|
|
140
|
+
const iosDisplay = pickerMode === "time" ? "spinner" : "inline";
|
|
141
|
+
|
|
142
|
+
function closePicker() {
|
|
143
|
+
setShowPicker(false);
|
|
144
|
+
setShowTimePicker(false);
|
|
145
|
+
setTempDate(null);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
function renderControl(
|
|
149
|
+
wire: string,
|
|
150
|
+
hasError: boolean,
|
|
151
|
+
commit?: (value: unknown) => void,
|
|
152
|
+
blur?: () => void,
|
|
153
|
+
) {
|
|
154
|
+
const seed = seedDate(wire, fieldType);
|
|
155
|
+
const displayValue = formatDisplayValue(wire, fieldType);
|
|
156
|
+
const resolvedPlaceholder =
|
|
157
|
+
placeholder ??
|
|
158
|
+
(fieldType === "time"
|
|
159
|
+
? "Select time"
|
|
160
|
+
: fieldType === "datetime"
|
|
161
|
+
? "Select date & time"
|
|
162
|
+
: "Select date");
|
|
163
|
+
|
|
164
|
+
function emit(picked: Date) {
|
|
165
|
+
// No `previousValue`: the native picker chooses date and time itself,
|
|
166
|
+
// so there is no earlier time part to preserve (the web half's case).
|
|
167
|
+
commit?.(picked);
|
|
168
|
+
(onChange as ((v: string) => void) | undefined)?.(toFrappeDateValue(picked, fieldType));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
function openPicker() {
|
|
172
|
+
if (disabled || readOnly) return;
|
|
173
|
+
setTempDate(seed);
|
|
174
|
+
setShowPicker(true);
|
|
175
|
+
setShowTimePicker(false);
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
function cancel() {
|
|
179
|
+
closePicker();
|
|
180
|
+
blur?.();
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
/** Android commits on the dialog's own OK; datetime runs date then time. */
|
|
184
|
+
function handleAndroidChange(event: DateTimePickerEvent, selected?: Date) {
|
|
185
|
+
if (event.type === "dismissed") {
|
|
186
|
+
cancel();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
if (event.type !== "set" || !selected) return;
|
|
190
|
+
if (fieldType === "datetime" && !showTimePicker) {
|
|
191
|
+
setTempDate(selected);
|
|
192
|
+
setShowPicker(false);
|
|
193
|
+
setShowTimePicker(true);
|
|
194
|
+
setTimeout(() => setShowPicker(true), 100);
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
const picked =
|
|
198
|
+
fieldType === "datetime" && tempDate
|
|
199
|
+
? new Date(
|
|
200
|
+
tempDate.getFullYear(),
|
|
201
|
+
tempDate.getMonth(),
|
|
202
|
+
tempDate.getDate(),
|
|
203
|
+
selected.getHours(),
|
|
204
|
+
selected.getMinutes(),
|
|
205
|
+
)
|
|
206
|
+
: selected;
|
|
207
|
+
emit(picked);
|
|
208
|
+
closePicker();
|
|
209
|
+
blur?.();
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/** iOS stages into `tempDate`; the sheet's Done commits. */
|
|
213
|
+
function handleIOSChange(_event: DateTimePickerEvent, selected?: Date) {
|
|
214
|
+
if (!selected) return;
|
|
215
|
+
if (fieldType === "datetime" && showTimePicker && tempDate) {
|
|
216
|
+
setTempDate(
|
|
217
|
+
new Date(
|
|
218
|
+
tempDate.getFullYear(),
|
|
219
|
+
tempDate.getMonth(),
|
|
220
|
+
tempDate.getDate(),
|
|
221
|
+
selected.getHours(),
|
|
222
|
+
selected.getMinutes(),
|
|
223
|
+
),
|
|
224
|
+
);
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
setTempDate(selected);
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
function confirm() {
|
|
231
|
+
emit(tempDate ?? seed);
|
|
232
|
+
closePicker();
|
|
233
|
+
blur?.();
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
return (
|
|
237
|
+
<YStack {...knobProps.gap}>
|
|
238
|
+
<Button
|
|
239
|
+
onPress={openPicker}
|
|
240
|
+
disabled={disabled || readOnly}
|
|
241
|
+
justifyContent="flex-start"
|
|
242
|
+
size={size || knobProps.sizeToken}
|
|
243
|
+
{...knobProps.borderRadius}
|
|
244
|
+
borderColor={hasError ? "$red8" : "$borderColor"}
|
|
245
|
+
backgroundColor={disabled ? "$color4" : "$background"}
|
|
246
|
+
aria-label={typeof label === "string" ? label : undefined}
|
|
247
|
+
aria-invalid={hasError || undefined}
|
|
248
|
+
aria-required={required || undefined}
|
|
249
|
+
>
|
|
250
|
+
<Text color={displayValue ? formCommonColors.text : formCommonColors.muted}>
|
|
251
|
+
{displayValue || resolvedPlaceholder}
|
|
252
|
+
</Text>
|
|
253
|
+
</Button>
|
|
254
|
+
|
|
255
|
+
{/* Android: the Material dialog is its own window. */}
|
|
256
|
+
{showPicker && !isIOS && (
|
|
257
|
+
<DateTimePicker
|
|
258
|
+
value={tempDate || seed}
|
|
259
|
+
mode={pickerMode}
|
|
260
|
+
display="default"
|
|
261
|
+
onChange={handleAndroidChange}
|
|
262
|
+
minimumDate={fieldType !== "time" ? minDate : undefined}
|
|
263
|
+
maximumDate={fieldType !== "time" ? maxDate : undefined}
|
|
264
|
+
/>
|
|
265
|
+
)}
|
|
266
|
+
|
|
267
|
+
{/* iOS: the picker has no chrome of its own, so it rides a sheet. */}
|
|
268
|
+
{showPicker && isIOS && (
|
|
269
|
+
<Modal transparent animationType="slide" visible={showPicker} onRequestClose={cancel}>
|
|
270
|
+
<Pressable style={styles.modalOverlay} onPress={cancel}>
|
|
271
|
+
<View
|
|
272
|
+
pointerEvents="none"
|
|
273
|
+
position="absolute"
|
|
274
|
+
top={0}
|
|
275
|
+
right={0}
|
|
276
|
+
bottom={0}
|
|
277
|
+
left={0}
|
|
278
|
+
backgroundColor="$shadow6"
|
|
279
|
+
/>
|
|
280
|
+
<Pressable onPress={(e) => e.stopPropagation()}>
|
|
281
|
+
<YStack
|
|
282
|
+
{...knobProps.elevatedSurface}
|
|
283
|
+
// Bottom sheet: the two off-screen corners eject from the
|
|
284
|
+
// surface fragment's radius, the visible pair keeps it.
|
|
285
|
+
borderBottomLeftRadius={0}
|
|
286
|
+
borderBottomRightRadius={0}
|
|
287
|
+
>
|
|
288
|
+
<XStack justifyContent="space-between" {...knobProps.panelPadding}>
|
|
289
|
+
<Button size="$3" chromeless onPress={cancel}>
|
|
290
|
+
<Text color={formCommonColors.text}>Cancel</Text>
|
|
291
|
+
</Button>
|
|
292
|
+
|
|
293
|
+
{fieldType === "datetime" && !showTimePicker && (
|
|
294
|
+
<Button size="$3" chromeless onPress={() => setShowTimePicker(true)}>
|
|
295
|
+
<Text color="$accentBackground">Next</Text>
|
|
296
|
+
</Button>
|
|
297
|
+
)}
|
|
298
|
+
|
|
299
|
+
{(fieldType !== "datetime" || showTimePicker) && (
|
|
300
|
+
<Button size="$3" chromeless onPress={confirm}>
|
|
301
|
+
<Text color="$accentBackground">Done</Text>
|
|
302
|
+
</Button>
|
|
303
|
+
)}
|
|
304
|
+
</XStack>
|
|
305
|
+
|
|
306
|
+
<YStack {...knobProps.panelPadding}>
|
|
307
|
+
<DateTimePicker
|
|
308
|
+
value={tempDate || seed}
|
|
309
|
+
mode={pickerMode}
|
|
310
|
+
display={iosDisplay}
|
|
311
|
+
themeVariant={themeVariant}
|
|
312
|
+
accentColor={accentColor}
|
|
313
|
+
onChange={handleIOSChange}
|
|
314
|
+
minimumDate={fieldType !== "time" ? minDate : undefined}
|
|
315
|
+
maximumDate={fieldType !== "time" ? maxDate : undefined}
|
|
316
|
+
style={pickerMode === "time" ? styles.wheel : styles.calendar}
|
|
317
|
+
/>
|
|
318
|
+
</YStack>
|
|
319
|
+
</YStack>
|
|
320
|
+
</Pressable>
|
|
321
|
+
</Pressable>
|
|
322
|
+
</Modal>
|
|
323
|
+
)}
|
|
324
|
+
</YStack>
|
|
325
|
+
);
|
|
326
|
+
}
|
|
327
|
+
|
|
328
|
+
if (skeleton) {
|
|
329
|
+
return (
|
|
330
|
+
<FieldLayout id={id} label={label} size={size} knobProps={knobProps}>
|
|
331
|
+
<Skeleton variant="rounded" width="100%" height={knobProps.sizeToken} />
|
|
332
|
+
</FieldLayout>
|
|
333
|
+
);
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
if (!resolvedForm || !name) {
|
|
337
|
+
return (
|
|
338
|
+
<FieldLayout
|
|
339
|
+
id={id}
|
|
340
|
+
label={label}
|
|
341
|
+
labelProps={labelProps}
|
|
342
|
+
error={errorProp}
|
|
343
|
+
helperText={helperText}
|
|
344
|
+
required={required}
|
|
345
|
+
size={size}
|
|
346
|
+
knobProps={knobProps}
|
|
347
|
+
onBlur={onBlur}
|
|
348
|
+
// LC-40: FieldLayout owns the dimWhole assembly dim (keepLabel pins
|
|
349
|
+
// the sibling label/helper readable) — it needs the disabled state.
|
|
350
|
+
disabled={disabled}
|
|
351
|
+
>
|
|
352
|
+
{renderControl(toWireValue(value, fieldType), !!errorProp, undefined, onBlur)}
|
|
353
|
+
</FieldLayout>
|
|
354
|
+
);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
return (
|
|
358
|
+
<Field
|
|
359
|
+
defaultValue={defaultValue}
|
|
360
|
+
form={resolvedForm}
|
|
361
|
+
mode={mode}
|
|
362
|
+
name={name as string}
|
|
363
|
+
preserveValue={preserveValue}
|
|
364
|
+
validators={resolvedValidators}
|
|
365
|
+
>
|
|
366
|
+
{(field) => {
|
|
367
|
+
const resolvedError = getFieldError(field, errorProp);
|
|
368
|
+
return (
|
|
369
|
+
<FieldLayout
|
|
370
|
+
id={id}
|
|
371
|
+
label={label}
|
|
372
|
+
labelProps={labelProps}
|
|
373
|
+
error={resolvedError}
|
|
374
|
+
helperText={helperText}
|
|
375
|
+
required={required}
|
|
376
|
+
size={size}
|
|
377
|
+
knobProps={knobProps}
|
|
378
|
+
disabled={disabled}
|
|
379
|
+
>
|
|
380
|
+
{renderControl(
|
|
381
|
+
toWireValue(value ?? field.state.value, fieldType),
|
|
382
|
+
!!resolvedError,
|
|
383
|
+
mergeFieldHandler(field, "handleChange"),
|
|
384
|
+
mergeFieldHandler(field, "handleBlur", onBlur),
|
|
385
|
+
)}
|
|
386
|
+
</FieldLayout>
|
|
387
|
+
);
|
|
388
|
+
}}
|
|
389
|
+
</Field>
|
|
390
|
+
);
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
export { DateField as Date };
|
|
394
|
+
|
|
395
|
+
const styles = StyleSheet.create({
|
|
396
|
+
modalOverlay: {
|
|
397
|
+
flex: 1,
|
|
398
|
+
justifyContent: "flex-end",
|
|
399
|
+
},
|
|
400
|
+
// The OS picker sizes itself from its presentation: the inline calendar
|
|
401
|
+
// needs a grid's worth of height, the wheel needs a wheel's.
|
|
402
|
+
calendar: {
|
|
403
|
+
height: 360,
|
|
404
|
+
width: "100%",
|
|
405
|
+
},
|
|
406
|
+
wheel: {
|
|
407
|
+
height: 200,
|
|
408
|
+
width: "100%",
|
|
409
|
+
},
|
|
410
|
+
});
|
|
@@ -1,45 +1,62 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Web `Date` field for the three Frappe date fieldtypes.
|
|
3
|
+
*
|
|
4
|
+
* The field used to render ONE date-only calendar for all three types, with
|
|
5
|
+
* only the placeholder varying — so a `Datetime` silently dropped its time
|
|
6
|
+
* component from the picker and a `Time` rendered EMPTY, because the calendar
|
|
7
|
+
* adopts its value through `coerceToDate`, for which a bare `HH:mm` is not a
|
|
8
|
+
* date (SB-M-617). Each type now gets the house primitive that matches it:
|
|
9
|
+
*
|
|
10
|
+
* date → forms `DatePicker` (month grid)
|
|
11
|
+
* datetime → forms `DatetimePicker` (Date/Time tabs — grid, then columns)
|
|
12
|
+
* time → the package's own `TimePicker`, which is also what the field
|
|
13
|
+
* registry routes the Frappe `Time` fieldtype to, so a
|
|
14
|
+
* `Date type="time"` and a `Time` field are one control
|
|
15
|
+
*
|
|
16
|
+
* This mirrors what the native half already does (calendar / wheel /
|
|
17
|
+
* calendar-then-wheel), and every branch serializes through the one shared
|
|
18
|
+
* `wire.ts` body, so a web pick and a native pick of the same moment persist
|
|
19
|
+
* byte-identical strings.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import {
|
|
23
|
+
DatePicker as FormsDatePicker,
|
|
24
|
+
DatetimePicker as FormsDatetimePicker,
|
|
25
|
+
} from "@multiplatform.one/forms";
|
|
26
|
+
import { useMemo } from "react";
|
|
4
27
|
import { useProps } from "tamagui";
|
|
5
|
-
import {
|
|
28
|
+
import { TimePicker, type TimePickerProps } from "../TimePicker";
|
|
29
|
+
import type { DateProps } from "./types";
|
|
30
|
+
import { fromFrappeDateValue, toFrappeDateValue } from "./wire";
|
|
6
31
|
|
|
7
|
-
export type DateProps
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
onChange?: (value: string) => void;
|
|
36
|
-
type?: "date" | "datetime" | "time";
|
|
37
|
-
disabled?: boolean;
|
|
38
|
-
readOnly?: boolean;
|
|
39
|
-
skeleton?: boolean;
|
|
40
|
-
compact?: boolean;
|
|
41
|
-
inputProps?: Record<string, unknown>;
|
|
42
|
-
};
|
|
32
|
+
export type { DateProps } from "./types";
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Adopt a Frappe datetime wire string through the shared read body rather
|
|
36
|
+
* than handing the raw string to the picker, whose `coerceToDate` falls
|
|
37
|
+
* through to `new Date(string)` for anything that is not date-only —
|
|
38
|
+
* implementation-defined for the space-separated shape Frappe writes.
|
|
39
|
+
* Memoized by the caller so the Date identity is stable across renders: the
|
|
40
|
+
* picker re-seeds its display state from every new `value` identity, which
|
|
41
|
+
* would otherwise discard an in-progress edit on an unrelated re-render.
|
|
42
|
+
*/
|
|
43
|
+
function toPickerDate(value: string | undefined): Date | null {
|
|
44
|
+
if (!value) return null;
|
|
45
|
+
const date = fromFrappeDateValue(value, "datetime");
|
|
46
|
+
return Number.isNaN(date.getTime()) ? null : date;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* `TimePicker` speaks `HH:mm`; Frappe stores `HH:mm:ss`. Round-tripping
|
|
51
|
+
* through the shared wire body — rather than padding the string here — is
|
|
52
|
+
* what keeps the two platform halves byte-identical, since the native half
|
|
53
|
+
* serializes its wheel pick through exactly this call.
|
|
54
|
+
*/
|
|
55
|
+
function toTimeWireValue(picked: string): string {
|
|
56
|
+
if (!picked) return "";
|
|
57
|
+
const date = fromFrappeDateValue(picked, "time");
|
|
58
|
+
return Number.isNaN(date.getTime()) ? "" : toFrappeDateValue(date, "time");
|
|
59
|
+
}
|
|
43
60
|
|
|
44
61
|
export function Date<
|
|
45
62
|
TData extends Record<string, unknown> = Record<string, unknown>,
|
|
@@ -61,6 +78,82 @@ export function Date<
|
|
|
61
78
|
...fieldProps
|
|
62
79
|
} = useProps(props) as DateProps<TData, TName> & Record<string, unknown>;
|
|
63
80
|
|
|
81
|
+
const wireValue = value as string | undefined;
|
|
82
|
+
const emit = onChange as ((v: string) => void) | undefined;
|
|
83
|
+
const datetimeValue = useMemo(
|
|
84
|
+
() => (type === "datetime" ? toPickerDate(wireValue) : null),
|
|
85
|
+
[type, wireValue],
|
|
86
|
+
);
|
|
87
|
+
|
|
88
|
+
const placeholder =
|
|
89
|
+
(fieldProps.placeholder as string | undefined) ??
|
|
90
|
+
(type === "time" ? "Select time" : type === "datetime" ? "Select date & time" : "Select date");
|
|
91
|
+
|
|
92
|
+
if (type === "time") {
|
|
93
|
+
return (
|
|
94
|
+
<TimePicker
|
|
95
|
+
// `TimePicker` is not generic over the form's data shape, so the
|
|
96
|
+
// three form props are re-cast to its own non-generic surface.
|
|
97
|
+
name={name as TimePickerProps["name"]}
|
|
98
|
+
form={form as TimePickerProps["form"]}
|
|
99
|
+
validators={validators as TimePickerProps["validators"]}
|
|
100
|
+
// The wire shape is what this control already speaks: `HH:mm[:ss]`,
|
|
101
|
+
// 24h. It adopts the string directly, so nothing has to widen the
|
|
102
|
+
// shared date parser to let a Time field display its own value.
|
|
103
|
+
value={wireValue}
|
|
104
|
+
onChange={(picked) => emit?.(toTimeWireValue(picked))}
|
|
105
|
+
defaultValue={defaultValue as string | undefined}
|
|
106
|
+
label={fieldProps.label}
|
|
107
|
+
labelProps={fieldProps.labelProps}
|
|
108
|
+
error={fieldProps.error}
|
|
109
|
+
helperText={fieldProps.helperText}
|
|
110
|
+
readOnly={fieldProps.readOnly}
|
|
111
|
+
skeleton={fieldProps.skeleton}
|
|
112
|
+
compact={fieldProps.compact}
|
|
113
|
+
required={fieldProps.required}
|
|
114
|
+
id={fieldProps.id}
|
|
115
|
+
size={fieldProps.size}
|
|
116
|
+
disabled={disabled}
|
|
117
|
+
placeholder={placeholder}
|
|
118
|
+
onBlur={onBlur}
|
|
119
|
+
/>
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if (type === "datetime") {
|
|
124
|
+
return (
|
|
125
|
+
<FormsDatetimePicker
|
|
126
|
+
name={name}
|
|
127
|
+
form={form}
|
|
128
|
+
validators={validators}
|
|
129
|
+
value={datetimeValue}
|
|
130
|
+
// No `previousValue`: this picker owns both halves of the value and
|
|
131
|
+
// preserves an existing time across a day change itself, so carrying
|
|
132
|
+
// the old time part here would overwrite a time the user just set.
|
|
133
|
+
// The native half passes nothing for the same reason.
|
|
134
|
+
onChange={(date) => emit?.(date ? toFrappeDateValue(date, "datetime") : "")}
|
|
135
|
+
defaultValue={defaultValue as string}
|
|
136
|
+
label={fieldProps.label}
|
|
137
|
+
labelProps={fieldProps.labelProps}
|
|
138
|
+
error={fieldProps.error}
|
|
139
|
+
helperText={fieldProps.helperText}
|
|
140
|
+
readOnly={fieldProps.readOnly}
|
|
141
|
+
skeleton={fieldProps.skeleton}
|
|
142
|
+
compact={fieldProps.compact}
|
|
143
|
+
required={fieldProps.required}
|
|
144
|
+
id={fieldProps.id}
|
|
145
|
+
size={fieldProps.size}
|
|
146
|
+
disabled={disabled}
|
|
147
|
+
minDate={fieldProps.minDate}
|
|
148
|
+
maxDate={fieldProps.maxDate}
|
|
149
|
+
placeholder={placeholder}
|
|
150
|
+
onBlur={onBlur}
|
|
151
|
+
mode={mode}
|
|
152
|
+
preserveValue={preserveValue}
|
|
153
|
+
/>
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
|
|
64
157
|
return (
|
|
65
158
|
<FormsDatePicker
|
|
66
159
|
name={name}
|
|
@@ -71,20 +164,8 @@ export function Date<
|
|
|
71
164
|
// engine seeding) never displayed — and `onChange` was dropped, so
|
|
72
165
|
// picks never reached the consumer doc. `undefined` stays undefined so
|
|
73
166
|
// uncontrolled (defaultValue-only) use keeps its semantics.
|
|
74
|
-
value={
|
|
75
|
-
onChange={(date) =>
|
|
76
|
-
const emit = onChange as ((v: string) => void) | undefined;
|
|
77
|
-
if (!emit) return;
|
|
78
|
-
emit(
|
|
79
|
-
date
|
|
80
|
-
? toFrappeDateValue(
|
|
81
|
-
date,
|
|
82
|
-
type as "date" | "datetime" | "time",
|
|
83
|
-
value as string | undefined,
|
|
84
|
-
)
|
|
85
|
-
: "",
|
|
86
|
-
);
|
|
87
|
-
}}
|
|
167
|
+
value={wireValue}
|
|
168
|
+
onChange={(date) => emit?.(date ? toFrappeDateValue(date, "date") : "")}
|
|
88
169
|
defaultValue={defaultValue as string}
|
|
89
170
|
label={fieldProps.label}
|
|
90
171
|
labelProps={fieldProps.labelProps}
|
|
@@ -97,9 +178,9 @@ export function Date<
|
|
|
97
178
|
id={fieldProps.id}
|
|
98
179
|
size={fieldProps.size}
|
|
99
180
|
disabled={disabled}
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
}
|
|
181
|
+
minDate={fieldProps.minDate}
|
|
182
|
+
maxDate={fieldProps.maxDate}
|
|
183
|
+
placeholder={placeholder}
|
|
103
184
|
onBlur={onBlur}
|
|
104
185
|
mode={mode}
|
|
105
186
|
preserveValue={preserveValue}
|