@multiplatform.one/frappe-ui 7.66.0 → 7.68.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/FileBrowser/index.cjs +15 -25
- package/dist/cjs/FileBrowser/index.native.js +15 -25
- package/dist/cjs/FileBrowser/index.native.js.map +1 -1
- package/dist/cjs/FormSidebar.cjs +107 -194
- package/dist/cjs/FormSidebar.native.js +120 -216
- package/dist/cjs/FormSidebar.native.js.map +1 -1
- package/dist/cjs/FrappeAssignment.cjs +0 -3
- package/dist/cjs/FrappeAssignment.native.js +0 -3
- package/dist/cjs/FrappeAssignment.native.js.map +1 -1
- package/dist/cjs/FrappeConnectionIndicator.cjs +5 -24
- package/dist/cjs/FrappeConnectionIndicator.native.js +5 -24
- package/dist/cjs/FrappeConnectionIndicator.native.js.map +1 -1
- package/dist/cjs/FrappeDashboard.cjs +0 -2
- package/dist/cjs/FrappeDashboard.native.js +0 -2
- package/dist/cjs/FrappeDashboard.native.js.map +1 -1
- package/dist/cjs/FrappeForm.cjs +6 -5
- package/dist/cjs/FrappeForm.native.js +6 -5
- package/dist/cjs/FrappeForm.native.js.map +1 -1
- package/dist/cjs/FrappeFormActions.cjs +20 -30
- package/dist/cjs/FrappeFormActions.native.js +23 -31
- package/dist/cjs/FrappeFormActions.native.js.map +1 -1
- package/dist/cjs/FrappeImageView.cjs +46 -65
- package/dist/cjs/FrappeImageView.native.js +46 -68
- package/dist/cjs/FrappeImageView.native.js.map +1 -1
- package/dist/cjs/FrappeKanban.cjs +0 -1
- package/dist/cjs/FrappeKanban.native.js +0 -1
- package/dist/cjs/FrappeKanban.native.js.map +1 -1
- package/dist/cjs/FrappeLikedBy.cjs +1 -1
- package/dist/cjs/FrappeLikedBy.native.js +1 -1
- package/dist/cjs/FrappeLikedBy.native.js.map +1 -1
- package/dist/cjs/FrappeListView.cjs +24 -68
- package/dist/cjs/FrappeListView.native.js +25 -72
- package/dist/cjs/FrappeListView.native.js.map +1 -1
- package/dist/cjs/FrappeRecordView.cjs +4 -0
- package/dist/cjs/FrappeRecordView.native.js +4 -0
- package/dist/cjs/FrappeRecordView.native.js.map +1 -1
- package/dist/cjs/FrappeReportBuilder.cjs +21 -18
- package/dist/cjs/FrappeReportBuilder.native.js +21 -18
- package/dist/cjs/FrappeReportBuilder.native.js.map +1 -1
- package/dist/cjs/FrappeReportView.cjs +2 -4
- package/dist/cjs/FrappeReportView.native.js +2 -4
- package/dist/cjs/FrappeReportView.native.js.map +1 -1
- package/dist/cjs/SyncErrorNotice.cjs +8 -36
- package/dist/cjs/SyncErrorNotice.native.js +8 -36
- package/dist/cjs/SyncErrorNotice.native.js.map +1 -1
- package/dist/cjs/desk/DeskFormSidebar.cjs +1 -6
- package/dist/cjs/desk/DeskFormSidebar.native.js +1 -6
- package/dist/cjs/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/cjs/desk/DeskShell.cjs +0 -1
- package/dist/cjs/desk/DeskShell.native.js +0 -1
- package/dist/cjs/desk/DeskShell.native.js.map +1 -1
- package/dist/cjs/fields/Date/catalog.native.js +0 -1
- package/dist/cjs/fields/Date/catalog.native.js.map +1 -1
- package/dist/cjs/fields/Date/index.native.js +4 -363
- package/dist/cjs/fields/Date/index.native.js.map +1 -1
- package/dist/cjs/fields/FileUpload.cjs +50 -58
- package/dist/cjs/fields/FileUpload.native.js +50 -56
- package/dist/cjs/fields/FileUpload.native.js.map +1 -1
- package/dist/cjs/insights/InsightsFacetTags.cjs +16 -92
- package/dist/cjs/insights/InsightsFacetTags.native.js +15 -97
- package/dist/cjs/insights/InsightsFacetTags.native.js.map +1 -1
- package/dist/cjs/list/FacetBadge.cjs +4 -28
- package/dist/cjs/list/FacetBadge.native.js +4 -28
- package/dist/cjs/list/FacetBadge.native.js.map +1 -1
- package/dist/cjs/list/FacetRail.cjs +37 -128
- package/dist/cjs/list/FacetRail.native.js +32 -130
- package/dist/cjs/list/FacetRail.native.js.map +1 -1
- package/dist/cjs/list/ListControls.cjs +1 -3
- package/dist/cjs/list/ListControls.native.js +1 -3
- package/dist/cjs/list/ListControls.native.js.map +1 -1
- package/dist/cjs/list/ListControlsSheet.cjs +5 -15
- package/dist/cjs/list/ListControlsSheet.native.js +7 -17
- package/dist/cjs/list/ListControlsSheet.native.js.map +1 -1
- package/dist/cjs/list/ListSidebarToolbar.cjs +5 -20
- package/dist/cjs/list/ListSidebarToolbar.native.js +7 -22
- package/dist/cjs/list/ListSidebarToolbar.native.js.map +1 -1
- package/dist/cjs/list/RecordCard.cjs +95 -127
- package/dist/cjs/list/RecordCard.native.js +78 -96
- package/dist/cjs/list/RecordCard.native.js.map +1 -1
- package/dist/cjs/list/ShufflePanel.cjs +55 -36
- package/dist/cjs/list/ShufflePanel.native.js +62 -39
- package/dist/cjs/list/ShufflePanel.native.js.map +1 -1
- package/dist/cjs/list/listColumns.cjs +1 -1
- package/dist/cjs/list/listColumns.native.js +1 -1
- package/dist/cjs/list/listColumns.native.js.map +1 -1
- package/dist/cjs/record/RecordHero.cjs +7 -85
- package/dist/cjs/record/RecordHero.native.js +7 -85
- package/dist/cjs/record/RecordHero.native.js.map +1 -1
- package/dist/cjs/record/RecordPage.cjs +5 -10
- package/dist/cjs/record/RecordPage.native.js +5 -10
- package/dist/cjs/record/RecordPage.native.js.map +1 -1
- package/dist/cjs/report/ReportViewToolbar.cjs +76 -47
- package/dist/cjs/report/ReportViewToolbar.native.js +79 -48
- package/dist/cjs/report/ReportViewToolbar.native.js.map +1 -1
- package/dist/esm/FileBrowser/index.mjs +16 -26
- package/dist/esm/FileBrowser/index.mjs.map +1 -1
- package/dist/esm/FileBrowser/index.native.js +16 -26
- package/dist/esm/FileBrowser/index.native.js.map +1 -1
- package/dist/esm/FormSidebar.mjs +110 -197
- package/dist/esm/FormSidebar.mjs.map +1 -1
- package/dist/esm/FormSidebar.native.js +123 -219
- package/dist/esm/FormSidebar.native.js.map +1 -1
- package/dist/esm/FrappeAssignment.mjs +0 -3
- package/dist/esm/FrappeAssignment.mjs.map +1 -1
- package/dist/esm/FrappeAssignment.native.js +0 -3
- package/dist/esm/FrappeAssignment.native.js.map +1 -1
- package/dist/esm/FrappeConnectionIndicator.mjs +7 -26
- package/dist/esm/FrappeConnectionIndicator.mjs.map +1 -1
- package/dist/esm/FrappeConnectionIndicator.native.js +7 -26
- package/dist/esm/FrappeConnectionIndicator.native.js.map +1 -1
- package/dist/esm/FrappeDashboard.mjs +0 -2
- package/dist/esm/FrappeDashboard.mjs.map +1 -1
- package/dist/esm/FrappeDashboard.native.js +0 -2
- package/dist/esm/FrappeDashboard.native.js.map +1 -1
- package/dist/esm/FrappeForm.mjs +7 -6
- package/dist/esm/FrappeForm.mjs.map +1 -1
- package/dist/esm/FrappeForm.native.js +7 -6
- package/dist/esm/FrappeForm.native.js.map +1 -1
- package/dist/esm/FrappeFormActions.mjs +22 -32
- package/dist/esm/FrappeFormActions.mjs.map +1 -1
- package/dist/esm/FrappeFormActions.native.js +25 -33
- package/dist/esm/FrappeFormActions.native.js.map +1 -1
- package/dist/esm/FrappeImageView.mjs +48 -67
- package/dist/esm/FrappeImageView.mjs.map +1 -1
- package/dist/esm/FrappeImageView.native.js +48 -70
- package/dist/esm/FrappeImageView.native.js.map +1 -1
- package/dist/esm/FrappeKanban.mjs +0 -1
- package/dist/esm/FrappeKanban.mjs.map +1 -1
- package/dist/esm/FrappeKanban.native.js +0 -1
- package/dist/esm/FrappeKanban.native.js.map +1 -1
- package/dist/esm/FrappeLikedBy.mjs +1 -1
- package/dist/esm/FrappeLikedBy.mjs.map +1 -1
- package/dist/esm/FrappeLikedBy.native.js +1 -1
- package/dist/esm/FrappeLikedBy.native.js.map +1 -1
- package/dist/esm/FrappeListView.mjs +25 -69
- package/dist/esm/FrappeListView.mjs.map +1 -1
- package/dist/esm/FrappeListView.native.js +26 -73
- package/dist/esm/FrappeListView.native.js.map +1 -1
- package/dist/esm/FrappeRecordView.mjs +4 -0
- package/dist/esm/FrappeRecordView.mjs.map +1 -1
- package/dist/esm/FrappeRecordView.native.js +4 -0
- package/dist/esm/FrappeRecordView.native.js.map +1 -1
- package/dist/esm/FrappeReportBuilder.mjs +21 -18
- package/dist/esm/FrappeReportBuilder.mjs.map +1 -1
- package/dist/esm/FrappeReportBuilder.native.js +21 -18
- package/dist/esm/FrappeReportBuilder.native.js.map +1 -1
- package/dist/esm/FrappeReportView.mjs +3 -5
- package/dist/esm/FrappeReportView.mjs.map +1 -1
- package/dist/esm/FrappeReportView.native.js +3 -5
- package/dist/esm/FrappeReportView.native.js.map +1 -1
- package/dist/esm/SyncErrorNotice.mjs +10 -38
- package/dist/esm/SyncErrorNotice.mjs.map +1 -1
- package/dist/esm/SyncErrorNotice.native.js +10 -38
- package/dist/esm/SyncErrorNotice.native.js.map +1 -1
- package/dist/esm/desk/DeskFormSidebar.mjs +1 -6
- package/dist/esm/desk/DeskFormSidebar.mjs.map +1 -1
- package/dist/esm/desk/DeskFormSidebar.native.js +1 -6
- package/dist/esm/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/esm/desk/DeskShell.mjs +0 -1
- package/dist/esm/desk/DeskShell.mjs.map +1 -1
- package/dist/esm/desk/DeskShell.native.js +0 -1
- package/dist/esm/desk/DeskShell.native.js.map +1 -1
- package/dist/esm/fields/Date/catalog.mjs.map +1 -1
- package/dist/esm/fields/Date/catalog.native.js +0 -1
- package/dist/esm/fields/Date/catalog.native.js.map +1 -1
- package/dist/esm/fields/Date/index.native.js +2 -361
- package/dist/esm/fields/Date/index.native.js.map +1 -1
- package/dist/esm/fields/FileUpload.mjs +53 -61
- package/dist/esm/fields/FileUpload.mjs.map +1 -1
- package/dist/esm/fields/FileUpload.native.js +53 -59
- package/dist/esm/fields/FileUpload.native.js.map +1 -1
- package/dist/esm/insights/InsightsFacetTags.mjs +18 -94
- package/dist/esm/insights/InsightsFacetTags.mjs.map +1 -1
- package/dist/esm/insights/InsightsFacetTags.native.js +17 -99
- package/dist/esm/insights/InsightsFacetTags.native.js.map +1 -1
- package/dist/esm/list/FacetBadge.mjs +5 -29
- package/dist/esm/list/FacetBadge.mjs.map +1 -1
- package/dist/esm/list/FacetBadge.native.js +5 -29
- package/dist/esm/list/FacetBadge.native.js.map +1 -1
- package/dist/esm/list/FacetRail.mjs +40 -131
- package/dist/esm/list/FacetRail.mjs.map +1 -1
- package/dist/esm/list/FacetRail.native.js +35 -133
- package/dist/esm/list/FacetRail.native.js.map +1 -1
- package/dist/esm/list/ListControls.mjs +1 -3
- package/dist/esm/list/ListControls.mjs.map +1 -1
- package/dist/esm/list/ListControls.native.js +1 -3
- package/dist/esm/list/ListControls.native.js.map +1 -1
- package/dist/esm/list/ListControlsSheet.mjs +6 -16
- package/dist/esm/list/ListControlsSheet.mjs.map +1 -1
- package/dist/esm/list/ListControlsSheet.native.js +8 -18
- package/dist/esm/list/ListControlsSheet.native.js.map +1 -1
- package/dist/esm/list/ListSidebarToolbar.mjs +6 -21
- package/dist/esm/list/ListSidebarToolbar.mjs.map +1 -1
- package/dist/esm/list/ListSidebarToolbar.native.js +8 -23
- package/dist/esm/list/ListSidebarToolbar.native.js.map +1 -1
- package/dist/esm/list/RecordCard.mjs +95 -127
- package/dist/esm/list/RecordCard.mjs.map +1 -1
- package/dist/esm/list/RecordCard.native.js +78 -96
- package/dist/esm/list/RecordCard.native.js.map +1 -1
- package/dist/esm/list/ShufflePanel.mjs +57 -38
- package/dist/esm/list/ShufflePanel.mjs.map +1 -1
- package/dist/esm/list/ShufflePanel.native.js +64 -41
- package/dist/esm/list/ShufflePanel.native.js.map +1 -1
- package/dist/esm/list/listColumns.mjs +1 -1
- package/dist/esm/list/listColumns.mjs.map +1 -1
- package/dist/esm/list/listColumns.native.js +1 -1
- package/dist/esm/list/listColumns.native.js.map +1 -1
- package/dist/esm/record/RecordHero.mjs +8 -86
- package/dist/esm/record/RecordHero.mjs.map +1 -1
- package/dist/esm/record/RecordHero.native.js +8 -86
- package/dist/esm/record/RecordHero.native.js.map +1 -1
- package/dist/esm/record/RecordPage.mjs +6 -11
- package/dist/esm/record/RecordPage.mjs.map +1 -1
- package/dist/esm/record/RecordPage.native.js +6 -11
- package/dist/esm/record/RecordPage.native.js.map +1 -1
- package/dist/esm/report/ReportViewToolbar.mjs +78 -49
- package/dist/esm/report/ReportViewToolbar.mjs.map +1 -1
- package/dist/esm/report/ReportViewToolbar.native.js +81 -50
- package/dist/esm/report/ReportViewToolbar.native.js.map +1 -1
- package/dist/jsx/FileBrowser/index.mjs +16 -26
- package/dist/jsx/FileBrowser/index.mjs.map +1 -1
- package/dist/jsx/FileBrowser/index.native.js +15 -25
- package/dist/jsx/FileBrowser/index.native.js.map +1 -1
- package/dist/jsx/FormSidebar.mjs +110 -197
- package/dist/jsx/FormSidebar.mjs.map +1 -1
- package/dist/jsx/FormSidebar.native.js +120 -216
- package/dist/jsx/FormSidebar.native.js.map +1 -1
- package/dist/jsx/FrappeAssignment.mjs +0 -3
- package/dist/jsx/FrappeAssignment.mjs.map +1 -1
- package/dist/jsx/FrappeAssignment.native.js +0 -3
- package/dist/jsx/FrappeAssignment.native.js.map +1 -1
- package/dist/jsx/FrappeConnectionIndicator.mjs +7 -26
- package/dist/jsx/FrappeConnectionIndicator.mjs.map +1 -1
- package/dist/jsx/FrappeConnectionIndicator.native.js +5 -24
- package/dist/jsx/FrappeConnectionIndicator.native.js.map +1 -1
- package/dist/jsx/FrappeDashboard.mjs +0 -2
- package/dist/jsx/FrappeDashboard.mjs.map +1 -1
- package/dist/jsx/FrappeDashboard.native.js +0 -2
- package/dist/jsx/FrappeDashboard.native.js.map +1 -1
- package/dist/jsx/FrappeForm.mjs +7 -6
- package/dist/jsx/FrappeForm.mjs.map +1 -1
- package/dist/jsx/FrappeForm.native.js +6 -5
- package/dist/jsx/FrappeForm.native.js.map +1 -1
- package/dist/jsx/FrappeFormActions.mjs +22 -32
- package/dist/jsx/FrappeFormActions.mjs.map +1 -1
- package/dist/jsx/FrappeFormActions.native.js +23 -31
- package/dist/jsx/FrappeFormActions.native.js.map +1 -1
- package/dist/jsx/FrappeImageView.mjs +48 -67
- package/dist/jsx/FrappeImageView.mjs.map +1 -1
- package/dist/jsx/FrappeImageView.native.js +46 -68
- package/dist/jsx/FrappeImageView.native.js.map +1 -1
- package/dist/jsx/FrappeKanban.mjs +0 -1
- package/dist/jsx/FrappeKanban.mjs.map +1 -1
- package/dist/jsx/FrappeKanban.native.js +0 -1
- package/dist/jsx/FrappeKanban.native.js.map +1 -1
- package/dist/jsx/FrappeLikedBy.mjs +1 -1
- package/dist/jsx/FrappeLikedBy.mjs.map +1 -1
- package/dist/jsx/FrappeLikedBy.native.js +1 -1
- package/dist/jsx/FrappeLikedBy.native.js.map +1 -1
- package/dist/jsx/FrappeListView.mjs +25 -69
- package/dist/jsx/FrappeListView.mjs.map +1 -1
- package/dist/jsx/FrappeListView.native.js +25 -72
- package/dist/jsx/FrappeListView.native.js.map +1 -1
- package/dist/jsx/FrappeRecordView.mjs +4 -0
- package/dist/jsx/FrappeRecordView.mjs.map +1 -1
- package/dist/jsx/FrappeRecordView.native.js +4 -0
- package/dist/jsx/FrappeRecordView.native.js.map +1 -1
- package/dist/jsx/FrappeReportBuilder.mjs +21 -18
- package/dist/jsx/FrappeReportBuilder.mjs.map +1 -1
- package/dist/jsx/FrappeReportBuilder.native.js +21 -18
- package/dist/jsx/FrappeReportBuilder.native.js.map +1 -1
- package/dist/jsx/FrappeReportView.mjs +3 -5
- package/dist/jsx/FrappeReportView.mjs.map +1 -1
- package/dist/jsx/FrappeReportView.native.js +2 -4
- package/dist/jsx/FrappeReportView.native.js.map +1 -1
- package/dist/jsx/SyncErrorNotice.mjs +10 -38
- package/dist/jsx/SyncErrorNotice.mjs.map +1 -1
- package/dist/jsx/SyncErrorNotice.native.js +8 -36
- package/dist/jsx/SyncErrorNotice.native.js.map +1 -1
- package/dist/jsx/desk/DeskFormSidebar.mjs +1 -6
- package/dist/jsx/desk/DeskFormSidebar.mjs.map +1 -1
- package/dist/jsx/desk/DeskFormSidebar.native.js +1 -6
- package/dist/jsx/desk/DeskFormSidebar.native.js.map +1 -1
- package/dist/jsx/desk/DeskShell.mjs +0 -1
- package/dist/jsx/desk/DeskShell.mjs.map +1 -1
- package/dist/jsx/desk/DeskShell.native.js +0 -1
- package/dist/jsx/desk/DeskShell.native.js.map +1 -1
- package/dist/jsx/fields/Date/catalog.mjs.map +1 -1
- package/dist/jsx/fields/Date/catalog.native.js +0 -1
- package/dist/jsx/fields/Date/catalog.native.js.map +1 -1
- package/dist/jsx/fields/Date/index.native.js +4 -363
- package/dist/jsx/fields/Date/index.native.js.map +1 -1
- package/dist/jsx/fields/FileUpload.mjs +53 -61
- package/dist/jsx/fields/FileUpload.mjs.map +1 -1
- package/dist/jsx/fields/FileUpload.native.js +50 -56
- package/dist/jsx/fields/FileUpload.native.js.map +1 -1
- package/dist/jsx/insights/InsightsFacetTags.mjs +18 -94
- package/dist/jsx/insights/InsightsFacetTags.mjs.map +1 -1
- package/dist/jsx/insights/InsightsFacetTags.native.js +15 -97
- package/dist/jsx/insights/InsightsFacetTags.native.js.map +1 -1
- package/dist/jsx/list/FacetBadge.mjs +5 -29
- package/dist/jsx/list/FacetBadge.mjs.map +1 -1
- package/dist/jsx/list/FacetBadge.native.js +4 -28
- package/dist/jsx/list/FacetBadge.native.js.map +1 -1
- package/dist/jsx/list/FacetRail.mjs +40 -131
- package/dist/jsx/list/FacetRail.mjs.map +1 -1
- package/dist/jsx/list/FacetRail.native.js +32 -130
- package/dist/jsx/list/FacetRail.native.js.map +1 -1
- package/dist/jsx/list/ListControls.mjs +1 -3
- package/dist/jsx/list/ListControls.mjs.map +1 -1
- package/dist/jsx/list/ListControls.native.js +1 -3
- package/dist/jsx/list/ListControls.native.js.map +1 -1
- package/dist/jsx/list/ListControlsSheet.mjs +6 -16
- package/dist/jsx/list/ListControlsSheet.mjs.map +1 -1
- package/dist/jsx/list/ListControlsSheet.native.js +7 -17
- package/dist/jsx/list/ListControlsSheet.native.js.map +1 -1
- package/dist/jsx/list/ListSidebarToolbar.mjs +6 -21
- package/dist/jsx/list/ListSidebarToolbar.mjs.map +1 -1
- package/dist/jsx/list/ListSidebarToolbar.native.js +7 -22
- package/dist/jsx/list/ListSidebarToolbar.native.js.map +1 -1
- package/dist/jsx/list/RecordCard.mjs +95 -127
- package/dist/jsx/list/RecordCard.mjs.map +1 -1
- package/dist/jsx/list/RecordCard.native.js +78 -96
- package/dist/jsx/list/RecordCard.native.js.map +1 -1
- package/dist/jsx/list/ShufflePanel.mjs +57 -38
- package/dist/jsx/list/ShufflePanel.mjs.map +1 -1
- package/dist/jsx/list/ShufflePanel.native.js +62 -39
- package/dist/jsx/list/ShufflePanel.native.js.map +1 -1
- package/dist/jsx/list/listColumns.mjs +1 -1
- package/dist/jsx/list/listColumns.mjs.map +1 -1
- package/dist/jsx/list/listColumns.native.js +1 -1
- package/dist/jsx/list/listColumns.native.js.map +1 -1
- package/dist/jsx/record/RecordHero.mjs +8 -86
- package/dist/jsx/record/RecordHero.mjs.map +1 -1
- package/dist/jsx/record/RecordHero.native.js +7 -85
- package/dist/jsx/record/RecordHero.native.js.map +1 -1
- package/dist/jsx/record/RecordPage.mjs +6 -11
- package/dist/jsx/record/RecordPage.mjs.map +1 -1
- package/dist/jsx/record/RecordPage.native.js +5 -10
- package/dist/jsx/record/RecordPage.native.js.map +1 -1
- package/dist/jsx/report/ReportViewToolbar.mjs +78 -49
- package/dist/jsx/report/ReportViewToolbar.mjs.map +1 -1
- package/dist/jsx/report/ReportViewToolbar.native.js +79 -48
- package/dist/jsx/report/ReportViewToolbar.native.js.map +1 -1
- package/package.json +16 -16
- package/src/FileBrowser/index.tsx +11 -15
- package/src/FormSidebar.stories.tsx +1 -1
- package/src/FormSidebar.tsx +146 -251
- package/src/FrappeAssignment.tsx +0 -3
- package/src/FrappeConnectionIndicator.tsx +6 -28
- package/src/FrappeDashboard.spec.tsx +7 -3
- package/src/FrappeDashboard.tsx +0 -2
- package/src/FrappeForm.connections.spec.tsx +2 -2
- package/src/FrappeForm.deskSemantics.spec.tsx +2 -2
- package/src/FrappeForm.lifecycle.spec.tsx +27 -27
- package/src/FrappeForm.tsx +11 -7
- package/src/FrappeFormActions.tsx +24 -38
- package/src/FrappeImageView.stories.tsx +1 -6
- package/src/FrappeImageView.tsx +52 -66
- package/src/FrappeKanban.tsx +0 -1
- package/src/FrappeLikedBy.tsx +1 -1
- package/src/FrappeListView.controls.spec.tsx +3 -2
- package/src/FrappeListView.spec.tsx +7 -3
- package/src/FrappeListView.tsx +23 -56
- package/src/FrappeRecordView.tsx +16 -3
- package/src/FrappeReportBuilder.tsx +21 -19
- package/src/FrappeReportView.tsx +3 -6
- package/src/SyncErrorNotice.spec.tsx +7 -12
- package/src/SyncErrorNotice.stories.tsx +2 -4
- package/src/SyncErrorNotice.tsx +13 -41
- package/src/desk/DeskFormSidebar.tsx +1 -2
- package/src/desk/DeskShell.tsx +1 -1
- package/src/desk/deskDocumentRoutes.spec.tsx +7 -4
- package/src/fields/Date/catalog.tsx +6 -7
- package/src/fields/Date/nativeIsCatalog.spec.tsx +26 -0
- package/src/fields/Date/typeParity.spec.tsx +26 -102
- package/src/fields/FileUpload.spec.tsx +18 -3
- package/src/fields/FileUpload.tsx +64 -68
- package/src/frappeRemainder.designLaw.spec.ts +8 -7
- package/src/insights/InsightsFacetTags.tsx +21 -102
- package/src/list/FacetBadge.tsx +7 -29
- package/src/list/FacetRail.spec.tsx +11 -10
- package/src/list/FacetRail.tsx +49 -161
- package/src/list/ListControls.tsx +1 -3
- package/src/list/ListControlsSheet.tsx +10 -12
- package/src/list/ListSidebarToolbar.tsx +7 -18
- package/src/list/RecordCard.native.tsx +65 -71
- package/src/list/RecordCard.spec.tsx +8 -5
- package/src/list/RecordCard.tsx +110 -129
- package/src/list/ShufflePanel.tsx +63 -38
- package/src/list/listColumns.tsx +1 -1
- package/src/record/RecordHero.tsx +11 -51
- package/src/record/RecordPage.tsx +8 -11
- package/src/report/ReportViewToolbar.spec.tsx +45 -3
- package/src/report/ReportViewToolbar.tsx +113 -62
- package/src/useFrappeForm.spec.tsx +1 -1
- package/types/FileBrowser/index.d.ts.map +1 -1
- package/types/FormSidebar.d.ts +13 -3
- package/types/FormSidebar.d.ts.map +1 -1
- package/types/FrappeAssignment.d.ts.map +1 -1
- package/types/FrappeConnectionIndicator.d.ts +2 -1
- package/types/FrappeConnectionIndicator.d.ts.map +1 -1
- package/types/FrappeDashboard.d.ts.map +1 -1
- package/types/FrappeFormActions.d.ts.map +1 -1
- package/types/FrappeImageView.d.ts.map +1 -1
- package/types/FrappeKanban.d.ts.map +1 -1
- package/types/FrappeListView.d.ts.map +1 -1
- package/types/FrappeRecordView.d.ts.map +1 -1
- package/types/FrappeReportBuilder.d.ts.map +1 -1
- package/types/FrappeReportView.d.ts.map +1 -1
- package/types/SyncErrorNotice.d.ts +4 -6
- package/types/SyncErrorNotice.d.ts.map +1 -1
- package/types/desk/DeskFormSidebar.d.ts.map +1 -1
- package/types/desk/DeskShell.d.ts.map +1 -1
- package/types/fields/Date/catalog.d.ts +5 -4
- package/types/fields/Date/catalog.d.ts.map +1 -1
- package/types/fields/FileUpload.d.ts.map +1 -1
- package/types/insights/InsightsFacetTags.d.ts +4 -1
- package/types/insights/InsightsFacetTags.d.ts.map +1 -1
- package/types/list/FacetBadge.d.ts +3 -3
- package/types/list/FacetBadge.d.ts.map +1 -1
- package/types/list/FacetRail.d.ts +7 -5
- package/types/list/FacetRail.d.ts.map +1 -1
- package/types/list/ListControls.d.ts.map +1 -1
- package/types/list/ListControlsSheet.d.ts.map +1 -1
- package/types/list/ListSidebarToolbar.d.ts.map +1 -1
- package/types/list/RecordCard.d.ts +6 -6
- package/types/list/RecordCard.d.ts.map +1 -1
- package/types/list/RecordCard.native.d.ts +4 -3
- package/types/list/RecordCard.native.d.ts.map +1 -1
- package/types/list/ShufflePanel.d.ts +8 -3
- package/types/list/ShufflePanel.d.ts.map +1 -1
- package/types/record/RecordHero.d.ts +5 -1
- package/types/record/RecordHero.d.ts.map +1 -1
- package/types/record/RecordPage.d.ts.map +1 -1
- package/types/report/ReportViewToolbar.d.ts.map +1 -1
- package/dist/cjs/fields/Date/dateTimePickerLoader.cjs +0 -38
- package/dist/cjs/fields/Date/dateTimePickerLoader.native.js +0 -42
- package/dist/cjs/fields/Date/dateTimePickerLoader.native.js.map +0 -1
- package/dist/cjs/fields/Date/sheetKeyboard.cjs +0 -54
- package/dist/cjs/fields/Date/sheetKeyboard.native.js +0 -57
- package/dist/cjs/fields/Date/sheetKeyboard.native.js.map +0 -1
- package/dist/esm/fields/Date/dateTimePickerLoader.mjs +0 -13
- package/dist/esm/fields/Date/dateTimePickerLoader.mjs.map +0 -1
- package/dist/esm/fields/Date/dateTimePickerLoader.native.js +0 -14
- package/dist/esm/fields/Date/dateTimePickerLoader.native.js.map +0 -1
- package/dist/esm/fields/Date/sheetKeyboard.mjs +0 -21
- package/dist/esm/fields/Date/sheetKeyboard.mjs.map +0 -1
- package/dist/esm/fields/Date/sheetKeyboard.native.js +0 -21
- package/dist/esm/fields/Date/sheetKeyboard.native.js.map +0 -1
- package/dist/jsx/fields/Date/dateTimePickerLoader.mjs +0 -13
- package/dist/jsx/fields/Date/dateTimePickerLoader.mjs.map +0 -1
- package/dist/jsx/fields/Date/dateTimePickerLoader.native.js +0 -42
- package/dist/jsx/fields/Date/dateTimePickerLoader.native.js.map +0 -1
- package/dist/jsx/fields/Date/sheetKeyboard.mjs +0 -21
- package/dist/jsx/fields/Date/sheetKeyboard.mjs.map +0 -1
- package/dist/jsx/fields/Date/sheetKeyboard.native.js +0 -57
- package/dist/jsx/fields/Date/sheetKeyboard.native.js.map +0 -1
- package/src/fields/Date/dateTimePickerLoader.ts +0 -25
- package/src/fields/Date/index.native.tsx +0 -445
- package/src/fields/Date/nativeFallback.spec.tsx +0 -21
- package/src/fields/Date/nativePresentation.spec.tsx +0 -278
- package/src/fields/Date/sheetKeyboard.spec.ts +0 -60
- package/src/fields/Date/sheetKeyboard.ts +0 -45
- package/types/fields/Date/dateTimePickerLoader.d.ts +0 -11
- package/types/fields/Date/dateTimePickerLoader.d.ts.map +0 -1
- package/types/fields/Date/index.native.d.ts +0 -14
- package/types/fields/Date/index.native.d.ts.map +0 -1
- package/types/fields/Date/sheetKeyboard.d.ts +0 -20
- package/types/fields/Date/sheetKeyboard.d.ts.map +0 -1
|
@@ -5,16 +5,12 @@
|
|
|
5
5
|
* The web field used to render ONE date-only calendar whatever the type
|
|
6
6
|
* (SB-M-617): a `Datetime` dropped its time component from the picker, and a
|
|
7
7
|
* `Time` rendered EMPTY, because the calendar adopts its value through
|
|
8
|
-
* `coerceToDate` and `new Date("09:00")` is an Invalid Date.
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* The suite runs on web, so the native half's two native-only edges are mocked
|
|
16
|
-
* exactly as `nativePresentation.spec.tsx` mocks them: the OS picker (recorded
|
|
17
|
-
* rather than rendered) and the platform flags. The web half imports neither.
|
|
8
|
+
* `coerceToDate` and `new Date("09:00")` is an Invalid Date. These cases pin
|
|
9
|
+
* the three web controls — display, edit, and the exact wire string — and
|
|
10
|
+
* then assert the moment an OS sheet commits on native serializes to the same
|
|
11
|
+
* bytes. Native has no fork of this field (FZ-8000): the same catalog field
|
|
12
|
+
* runs there, forms' pickers commit a `Date` from `OsDateTimeSheet`, and the
|
|
13
|
+
* catalog writes it through the one `wire.ts` body.
|
|
18
14
|
*/
|
|
19
15
|
|
|
20
16
|
import { describe, it, expect, vi, beforeAll, beforeEach } from "vitest";
|
|
@@ -23,38 +19,6 @@ import { describe, it, expect, vi, beforeAll, beforeEach } from "vitest";
|
|
|
23
19
|
// import transforms the whole fields graph.
|
|
24
20
|
vi.setConfig({ testTimeout: 240_000 });
|
|
25
21
|
|
|
26
|
-
const mockState = vi.hoisted(() => ({
|
|
27
|
-
isIos: true,
|
|
28
|
-
isAndroid: false,
|
|
29
|
-
/** Props of every mounted OS picker, newest last. */
|
|
30
|
-
picks: [] as Record<string, unknown>[],
|
|
31
|
-
}));
|
|
32
|
-
|
|
33
|
-
vi.mock("./dateTimePickerLoader", () => ({
|
|
34
|
-
loadDateTimePicker: () => (props: Record<string, unknown>) => {
|
|
35
|
-
mockState.picks.push(props);
|
|
36
|
-
return null;
|
|
37
|
-
},
|
|
38
|
-
}));
|
|
39
|
-
|
|
40
|
-
vi.mock("@multiplatform.one/platform", async (importOriginal) => {
|
|
41
|
-
const actual = (await importOriginal()) as Record<string, unknown>;
|
|
42
|
-
const real = actual.platform as Record<string, unknown>;
|
|
43
|
-
return {
|
|
44
|
-
...actual,
|
|
45
|
-
platform: new Proxy(
|
|
46
|
-
{},
|
|
47
|
-
{
|
|
48
|
-
get(_target, prop) {
|
|
49
|
-
if (prop === "isIos") return mockState.isIos;
|
|
50
|
-
if (prop === "isAndroid") return mockState.isAndroid;
|
|
51
|
-
return real[prop as string];
|
|
52
|
-
},
|
|
53
|
-
},
|
|
54
|
-
),
|
|
55
|
-
};
|
|
56
|
-
});
|
|
57
|
-
|
|
58
22
|
// Mock react-native-reanimated to prevent ESM module resolution failures
|
|
59
23
|
// (same shim as tests/fieldRenderers.spec.tsx).
|
|
60
24
|
vi.mock("react-native-reanimated", () => ({
|
|
@@ -95,9 +59,9 @@ vi.mock("react-native-reanimated", () => ({
|
|
|
95
59
|
import { renderWithProviders } from "@multiplatform.one/test-utils";
|
|
96
60
|
import { act, cleanup, fireEvent, waitFor } from "@testing-library/react";
|
|
97
61
|
import React from "react";
|
|
62
|
+
import { toFrappeDateValue } from "./wire";
|
|
98
63
|
|
|
99
64
|
const loadWebDateField = async () => (await import(".")).Date;
|
|
100
|
-
const loadNativeDateField = async () => (await import("./index.native")).Date;
|
|
101
65
|
|
|
102
66
|
/** Intl puts a narrow no-break space before the meridiem; no test should care. */
|
|
103
67
|
const norm = (value: string) => value.replace(/\s+/gu, " ").trim();
|
|
@@ -155,10 +119,12 @@ async function pressText(root: ParentNode, text: string) {
|
|
|
155
119
|
let target: Element | null = null;
|
|
156
120
|
await waitFor(
|
|
157
121
|
() => {
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
122
|
+
// LC-260: Next and Done are icon buttons, named by their label.
|
|
123
|
+
const node =
|
|
124
|
+
Array.from(root.querySelectorAll("*")).find(
|
|
125
|
+
(el) => el.children.length === 0 && norm(el.textContent ?? "") === norm(text),
|
|
126
|
+
) ?? root.querySelector(`[aria-label="${text}"]`);
|
|
127
|
+
if (!node) throw new Error(`no element with text or label "${text}"`);
|
|
162
128
|
target = node;
|
|
163
129
|
},
|
|
164
130
|
{ timeout: 30_000 },
|
|
@@ -180,16 +146,13 @@ async function selectPeriod(period: "AM" | "PM") {
|
|
|
180
146
|
// (110-155s quiet, past 240s under load), and charging it to an assertion made
|
|
181
147
|
// whichever case ran first time out.
|
|
182
148
|
beforeAll(async () => {
|
|
183
|
-
await
|
|
149
|
+
await loadWebDateField();
|
|
184
150
|
}, 900_000);
|
|
185
151
|
|
|
186
152
|
beforeEach(() => {
|
|
187
153
|
// Both halves portal their surfaces, so a previous case's chrome would
|
|
188
154
|
// otherwise still be in the document when the next one queries it.
|
|
189
155
|
cleanup();
|
|
190
|
-
mockState.picks.length = 0;
|
|
191
|
-
mockState.isIos = true;
|
|
192
|
-
mockState.isAndroid = false;
|
|
193
156
|
});
|
|
194
157
|
|
|
195
158
|
// ---------------------------------------------------------------------------
|
|
@@ -356,41 +319,14 @@ describe("web Date field — type=datetime renders date AND time", () => {
|
|
|
356
319
|
// Cross-half parity — the reason one `wire.ts` body is shared
|
|
357
320
|
// ---------------------------------------------------------------------------
|
|
358
321
|
|
|
359
|
-
/**
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
):
|
|
366
|
-
|
|
367
|
-
const onChange = vi.fn();
|
|
368
|
-
const result = renderWithProviders(
|
|
369
|
-
<DateField label="Field" value={value} onChange={onChange} type={type} />,
|
|
370
|
-
);
|
|
371
|
-
await pressText(result.container, triggerText);
|
|
372
|
-
await waitFor(() => expect(mockState.picks.length).toBeGreaterThan(0), { timeout: 30_000 });
|
|
373
|
-
|
|
374
|
-
for (const [index, step] of steps.entries()) {
|
|
375
|
-
const onPickerChange = mockState.picks[mockState.picks.length - 1].onChange as (
|
|
376
|
-
event: unknown,
|
|
377
|
-
date?: Date,
|
|
378
|
-
) => void;
|
|
379
|
-
await act(async () => {
|
|
380
|
-
onPickerChange({ type: "set" }, step);
|
|
381
|
-
});
|
|
382
|
-
// A datetime runs calendar → Next → wheel; the sheet's Next is the seam.
|
|
383
|
-
if (index === 0 && steps.length > 1) {
|
|
384
|
-
await pressText(document.body, "Next");
|
|
385
|
-
await waitFor(() => expect(mockState.picks[mockState.picks.length - 1].mode).toBe("time"), {
|
|
386
|
-
timeout: 30_000,
|
|
387
|
-
});
|
|
388
|
-
}
|
|
389
|
-
}
|
|
390
|
-
await pressText(document.body, "Done");
|
|
391
|
-
|
|
392
|
-
expect(onChange).toHaveBeenCalledTimes(1);
|
|
393
|
-
return onChange.mock.calls[0][0] as string;
|
|
322
|
+
/**
|
|
323
|
+
* What the catalog writes for the moment an OS sheet commits on native: forms'
|
|
324
|
+
* native `DatePicker` and `DatetimePicker` hand the field a `Date`, and its
|
|
325
|
+
* `TimePicker` an `HH:mm:ss` string, through the same `onChange` the web
|
|
326
|
+
* pickers use.
|
|
327
|
+
*/
|
|
328
|
+
function nativeWrite(type: "date" | "datetime" | "time", committed: Date): string {
|
|
329
|
+
return toFrappeDateValue(committed, type);
|
|
394
330
|
}
|
|
395
331
|
|
|
396
332
|
/** Drive the web half through the equivalent pick and return the last string. */
|
|
@@ -419,9 +355,7 @@ describe("web and native persist byte-identical wire strings", () => {
|
|
|
419
355
|
fireEvent.click(dayCell(15)!);
|
|
420
356
|
});
|
|
421
357
|
});
|
|
422
|
-
|
|
423
|
-
mockState.picks.length = 0;
|
|
424
|
-
const native = await nativePick("date", "2026-03-05", "Mar 5, 2026", [new Date(2026, 2, 15)]);
|
|
358
|
+
const native = nativeWrite("date", new Date(2026, 2, 15));
|
|
425
359
|
|
|
426
360
|
expect({ web, native }).toEqual({ web: "2026-03-15", native: "2026-03-15" });
|
|
427
361
|
expect(web).toBe(native);
|
|
@@ -431,11 +365,7 @@ describe("web and native persist byte-identical wire strings", () => {
|
|
|
431
365
|
const web = await webPick("time", "09:00:00", async () => {
|
|
432
366
|
await selectPeriod("PM");
|
|
433
367
|
});
|
|
434
|
-
|
|
435
|
-
mockState.picks.length = 0;
|
|
436
|
-
const native = await nativePick("time", "09:00:00", "9:00 AM", [
|
|
437
|
-
new Date(2026, 2, 5, 21, 0, 0),
|
|
438
|
-
]);
|
|
368
|
+
const native = nativeWrite("time", new Date(2026, 2, 5, 21, 0, 0));
|
|
439
369
|
|
|
440
370
|
expect({ web, native }).toEqual({ web: "21:00:00", native: "21:00:00" });
|
|
441
371
|
expect(web).toBe(native);
|
|
@@ -448,14 +378,8 @@ describe("web and native persist byte-identical wire strings", () => {
|
|
|
448
378
|
fireEvent.click(dayCell(20)!);
|
|
449
379
|
});
|
|
450
380
|
});
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
// The native two-step: the calendar commits the day (dropping the clock,
|
|
454
|
-
// which is why the wheel step re-supplies it), then the wheel commits it.
|
|
455
|
-
const native = await nativePick("datetime", "2026-03-05 14:30:00", "Mar 5, 2026, 2:30 PM", [
|
|
456
|
-
new Date(2026, 2, 20),
|
|
457
|
-
new Date(2026, 0, 1, 14, 30),
|
|
458
|
-
]);
|
|
381
|
+
// The OS sheet's calendar-then-wheel commits one moment from both halves.
|
|
382
|
+
const native = nativeWrite("datetime", new Date(2026, 2, 20, 14, 30));
|
|
459
383
|
|
|
460
384
|
expect({ web, native }).toEqual({
|
|
461
385
|
web: "2026-03-20 14:30:00",
|
|
@@ -123,7 +123,7 @@ describe("FileUpload size gate", () => {
|
|
|
123
123
|
* `aria-label` still fails. Recorded on MPO-123.
|
|
124
124
|
*/
|
|
125
125
|
const buttonLabelled = (container: HTMLElement, prefix: string) =>
|
|
126
|
-
Array.from(container.querySelectorAll("button")).find((b) =>
|
|
126
|
+
Array.from(container.querySelectorAll('button, [role="button"]')).find((b) =>
|
|
127
127
|
(b.getAttribute("aria-label") ?? "").startsWith(prefix),
|
|
128
128
|
);
|
|
129
129
|
|
|
@@ -226,8 +226,9 @@ describe("FileUpload transfer", () => {
|
|
|
226
226
|
/^Retry \S/,
|
|
227
227
|
);
|
|
228
228
|
expect(remove?.getAttribute("aria-label")).toMatch(/^Remove \S/);
|
|
229
|
-
//
|
|
230
|
-
expect(buttonLabelled(result.container, "Retry ")?.textContent).
|
|
229
|
+
// LC-260: the button shows only its glyph; the name lives on the label.
|
|
230
|
+
expect(buttonLabelled(result.container, "Retry ")?.textContent).toBe("");
|
|
231
|
+
expect(buttonLabelled(result.container, "Retry ")?.querySelector("svg")).toBeTruthy();
|
|
231
232
|
|
|
232
233
|
await act(async () => {
|
|
233
234
|
fireEvent.click(buttonLabelled(result.container, "Retry ") as Element);
|
|
@@ -292,6 +293,20 @@ describe("FileUpload with a value", () => {
|
|
|
292
293
|
expect(onChange).toHaveBeenCalledWith("");
|
|
293
294
|
});
|
|
294
295
|
|
|
296
|
+
it("an image's Replace and Remove are glyphs on the media plate over it (LC-260, LC-176)", () => {
|
|
297
|
+
const result = renderWithProviders(
|
|
298
|
+
<FileUpload label="Photo" value="/files/sprite.png" isImage onChange={() => {}} />,
|
|
299
|
+
);
|
|
300
|
+
const actions = result.container.querySelector('[data-file-upload="preview-actions"]');
|
|
301
|
+
expect(actions).toBeTruthy();
|
|
302
|
+
const buttons = Array.from(actions!.querySelectorAll("[data-mp-action]"));
|
|
303
|
+
expect(buttons.map((b) => b.getAttribute("aria-label"))).toEqual(["Replace", "Remove"]);
|
|
304
|
+
for (const button of buttons) {
|
|
305
|
+
expect(button.getAttribute("data-mp-icon-button")).toBe("media");
|
|
306
|
+
expect(button.textContent).toBe("");
|
|
307
|
+
}
|
|
308
|
+
});
|
|
309
|
+
|
|
295
310
|
it("readOnly hides Replace and Remove — the value is visible, not editable", () => {
|
|
296
311
|
const result = renderWithProviders(
|
|
297
312
|
<FileUpload label="Attachment" value="/files/report.pdf" readOnly onChange={() => {}} />,
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
import { useFrappeCollection } from "@multiplatform.one/frappe";
|
|
2
2
|
import { Skeleton } from "@multiplatform.one/forms";
|
|
3
|
-
import { FileIcon, UploadIcon
|
|
3
|
+
import { FileIcon, UploadIcon } from "@phosphor-icons/react";
|
|
4
4
|
import { sizeRecipeForToken, useResolvedKnobs, sizeTokenStep } from "@multiplatform.one/theme";
|
|
5
5
|
import type React from "react";
|
|
6
6
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
7
7
|
import { useTranslation } from "react-i18next";
|
|
8
8
|
import { Button, Image, Label, Text as TamaguiText, XStack, YStack } from "tamagui";
|
|
9
9
|
import { useFrappeConfig } from "../FrappeProvider";
|
|
10
|
-
import { Text } from "@multiplatform.one/components";
|
|
10
|
+
import { Text, ActionButton } from "@multiplatform.one/components";
|
|
11
11
|
|
|
12
12
|
export type FrappeFileUploadHandler = (
|
|
13
13
|
file: File,
|
|
@@ -291,6 +291,28 @@ export function FileUpload({
|
|
|
291
291
|
);
|
|
292
292
|
}
|
|
293
293
|
|
|
294
|
+
// LC-260 ICONS-OVER-WORDS: Replace and Remove are their symbols, floating
|
|
295
|
+
// over an image on the LC-176 media plate.
|
|
296
|
+
const fileActions =
|
|
297
|
+
!readOnly && !transfer
|
|
298
|
+
? (overMedia: boolean) => (
|
|
299
|
+
<>
|
|
300
|
+
<ActionButton
|
|
301
|
+
kind="replace"
|
|
302
|
+
overMedia={overMedia}
|
|
303
|
+
disabled={isLocked}
|
|
304
|
+
onPress={handleClick}
|
|
305
|
+
/>
|
|
306
|
+
<ActionButton
|
|
307
|
+
kind="remove"
|
|
308
|
+
overMedia={overMedia}
|
|
309
|
+
disabled={isLocked}
|
|
310
|
+
onPress={handleRemove}
|
|
311
|
+
/>
|
|
312
|
+
</>
|
|
313
|
+
)
|
|
314
|
+
: undefined;
|
|
315
|
+
|
|
294
316
|
return (
|
|
295
317
|
<YStack {...knobProps.gap}>
|
|
296
318
|
{label && (
|
|
@@ -325,17 +347,12 @@ export function FileUpload({
|
|
|
325
347
|
</Text>
|
|
326
348
|
</YStack>
|
|
327
349
|
{transfer.status === "uploading" ? (
|
|
328
|
-
<
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
icon={XIcon}
|
|
332
|
-
aria-label={t("Cancel {{name}}", { name: transfer.file.name })}
|
|
350
|
+
<ActionButton
|
|
351
|
+
kind="cancel"
|
|
352
|
+
label={t("Cancel {{name}}", { name: transfer.file.name })}
|
|
333
353
|
disabled={isLocked}
|
|
334
354
|
onPress={handleCancel}
|
|
335
|
-
|
|
336
|
-
>
|
|
337
|
-
{t("Cancel")}
|
|
338
|
-
</Button>
|
|
355
|
+
/>
|
|
339
356
|
) : null}
|
|
340
357
|
</XStack>
|
|
341
358
|
{transfer.status === "uploading" ? (
|
|
@@ -364,27 +381,18 @@ export function FileUpload({
|
|
|
364
381
|
{transfer.action}
|
|
365
382
|
</Text>
|
|
366
383
|
<XStack {...knobProps.gap}>
|
|
367
|
-
<
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
aria-label={t("Retry {{name}}", { name: transfer.file.name })}
|
|
384
|
+
<ActionButton
|
|
385
|
+
kind="retry"
|
|
386
|
+
label={t("Retry {{name}}", { name: transfer.file.name })}
|
|
371
387
|
disabled={isLocked}
|
|
372
388
|
onPress={handleRetry}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
<Button
|
|
378
|
-
size="$2"
|
|
379
|
-
variant="outlined"
|
|
380
|
-
icon={XIcon}
|
|
381
|
-
aria-label={t("Remove {{name}}", { name: transfer.file.name })}
|
|
389
|
+
/>
|
|
390
|
+
<ActionButton
|
|
391
|
+
kind="remove"
|
|
392
|
+
label={t("Remove {{name}}", { name: transfer.file.name })}
|
|
382
393
|
disabled={isLocked}
|
|
383
394
|
onPress={handleRemoveFailed}
|
|
384
|
-
|
|
385
|
-
>
|
|
386
|
-
{t("Remove")}
|
|
387
|
-
</Button>
|
|
395
|
+
/>
|
|
388
396
|
</XStack>
|
|
389
397
|
</YStack>
|
|
390
398
|
) : null}
|
|
@@ -404,8 +412,8 @@ export function FileUpload({
|
|
|
404
412
|
) : null}
|
|
405
413
|
|
|
406
414
|
{value ? (
|
|
407
|
-
|
|
408
|
-
|
|
415
|
+
isImage ? (
|
|
416
|
+
<YStack position="relative" alignSelf="flex-start">
|
|
409
417
|
<Image
|
|
410
418
|
// src (string), not source: the RN source object leaks onto the
|
|
411
419
|
// DOM <img> as source="[object Object]" on web
|
|
@@ -416,45 +424,33 @@ export function FileUpload({
|
|
|
416
424
|
{...knobProps.borderRadius}
|
|
417
425
|
objectFit="cover"
|
|
418
426
|
/>
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
<Text flex={1} numberOfLines={1}>
|
|
428
|
-
{value.split("/").pop() || value}
|
|
429
|
-
</Text>
|
|
430
|
-
</XStack>
|
|
431
|
-
)}
|
|
432
|
-
|
|
433
|
-
{!readOnly && !transfer ? (
|
|
434
|
-
<XStack {...knobProps.gap}>
|
|
435
|
-
<Button
|
|
436
|
-
size="$2"
|
|
437
|
-
variant="outlined"
|
|
438
|
-
icon={UploadIcon}
|
|
439
|
-
disabled={isLocked}
|
|
440
|
-
onPress={handleClick}
|
|
441
|
-
{...knobProps.borderRadius}
|
|
427
|
+
{fileActions ? (
|
|
428
|
+
<XStack
|
|
429
|
+
data-file-upload="preview-actions"
|
|
430
|
+
position="absolute"
|
|
431
|
+
top="$2"
|
|
432
|
+
right="$2"
|
|
433
|
+
zIndex={1}
|
|
434
|
+
{...knobProps.gap}
|
|
442
435
|
>
|
|
443
|
-
{
|
|
444
|
-
</
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
436
|
+
{fileActions(true)}
|
|
437
|
+
</XStack>
|
|
438
|
+
) : null}
|
|
439
|
+
</YStack>
|
|
440
|
+
) : (
|
|
441
|
+
<XStack
|
|
442
|
+
gap="$2"
|
|
443
|
+
alignItems="center"
|
|
444
|
+
{...knobProps.panelPadding}
|
|
445
|
+
{...{ backgroundColor: "$color2" }}
|
|
446
|
+
>
|
|
447
|
+
<FileIcon size={20} />
|
|
448
|
+
<Text flex={1} numberOfLines={1}>
|
|
449
|
+
{value.split("/").pop() || value}
|
|
450
|
+
</Text>
|
|
451
|
+
{fileActions?.(false)}
|
|
452
|
+
</XStack>
|
|
453
|
+
)
|
|
458
454
|
) : null}
|
|
459
455
|
|
|
460
456
|
{helperText && !error && !transfer ? (
|
|
@@ -84,13 +84,14 @@ describe("Frappe remainder wrappers — design-law 100%", () => {
|
|
|
84
84
|
expect(stories).toMatch(/from ["']\.\/ChartCard["']/);
|
|
85
85
|
});
|
|
86
86
|
|
|
87
|
-
it("FrappeImageView
|
|
87
|
+
it("FrappeImageView is the MPO ImageGrid photos grid, controlIcon icons, and no media pip (R11/R12, LC-264)", () => {
|
|
88
88
|
const source = read("FrappeImageView.tsx");
|
|
89
|
-
expect(source).
|
|
89
|
+
expect(source).toMatch(/ImageGrid[\s\S]*from "@multiplatform.one\/components"/);
|
|
90
|
+
expect(source).toContain('variant="photos"');
|
|
90
91
|
expect(source).toContain("controlIcon");
|
|
91
92
|
expect(source).not.toMatch(/size=\{48\}/);
|
|
92
93
|
expect(source).not.toContain("<Tint");
|
|
93
|
-
expect(source).
|
|
94
|
+
expect(source).toMatch(/no pip/i);
|
|
94
95
|
});
|
|
95
96
|
|
|
96
97
|
it("FrappeTreeView uses label fragment and controlIcon, not 12/14px", () => {
|
|
@@ -156,10 +157,10 @@ describe("Frappe remainder wrappers — design-law 100%", () => {
|
|
|
156
157
|
expect(list).toContain("formCommonColors.muted");
|
|
157
158
|
});
|
|
158
159
|
|
|
159
|
-
it("native Date
|
|
160
|
-
const source = read("fields/Date/
|
|
161
|
-
expect(source).toMatch(/
|
|
162
|
-
expect(
|
|
160
|
+
it("native Date is the catalog field on the forms pickers, not a fork (LC-175)", () => {
|
|
161
|
+
const source = read("fields/Date/catalog.tsx");
|
|
162
|
+
expect(source).toMatch(/DatePicker[\s\S]*from "@multiplatform.one\/forms"/);
|
|
163
|
+
expect(read("fields/Date/index.tsx")).toContain('export { Date } from "./catalog"');
|
|
163
164
|
});
|
|
164
165
|
|
|
165
166
|
it("fieldRegistry TextEditor fallback is Skeleton; SmallText/LongText use textAreaProps", () => {
|
|
@@ -1,97 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
ensureFocusVisibleRing,
|
|
4
|
-
ensureKeyboardModalityTracking,
|
|
5
|
-
keyboardFocusRingProps,
|
|
6
|
-
useResolvedKnobs,
|
|
7
|
-
wasKeyboardFocus,
|
|
8
|
-
} from "@multiplatform.one/theme";
|
|
9
|
-
import { useState } from "react";
|
|
1
|
+
import { Chip, Tags } from "@multiplatform.one/components";
|
|
10
2
|
import { useTranslation } from "react-i18next";
|
|
11
3
|
import type { InsightsCount } from "./insightsData";
|
|
12
4
|
|
|
13
|
-
const chipFocusRing = ensureFocusVisibleRing(keyboardFocusRingProps);
|
|
14
|
-
|
|
15
|
-
interface FacetTagChipProps {
|
|
16
|
-
value: string;
|
|
17
|
-
count: number;
|
|
18
|
-
label: string;
|
|
19
|
-
tint?: string;
|
|
20
|
-
onPress: () => void;
|
|
21
|
-
testID?: string;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* A pressable facet value painted from its tint's ramp (DF-04), at the
|
|
26
|
-
* compact nestedControl height with the press target restored by hitSlop
|
|
27
|
-
* (LC-54, LC-73); the keyboard ring rides the whole chip (LC-71).
|
|
28
|
-
*/
|
|
29
|
-
function FacetTagChip({ value, count, label, tint = "gray", onPress, testID }: FacetTagChipProps) {
|
|
30
|
-
const { t } = useTranslation();
|
|
31
|
-
const { knobProps } = useResolvedKnobs();
|
|
32
|
-
const nested = knobProps.nestedControl;
|
|
33
|
-
const [kbFocus, setKbFocus] = useState(false);
|
|
34
|
-
if (isWeb) ensureKeyboardModalityTracking();
|
|
35
|
-
return (
|
|
36
|
-
<XStack
|
|
37
|
-
{...knobProps.borderRadius}
|
|
38
|
-
role="button"
|
|
39
|
-
tabIndex={0}
|
|
40
|
-
aria-label={t("{{value}}, {{count}} records", { value: label, count })}
|
|
41
|
-
cursor="pointer"
|
|
42
|
-
alignItems="center"
|
|
43
|
-
gap="$1.5"
|
|
44
|
-
paddingHorizontal="$2"
|
|
45
|
-
minHeight={nested.px}
|
|
46
|
-
height={nested.px}
|
|
47
|
-
hitSlop={nested.hitSlop}
|
|
48
|
-
data-nested-px={nested.px}
|
|
49
|
-
backgroundColor={`$${tint}3` as never}
|
|
50
|
-
hoverStyle={{ backgroundColor: `$${tint}4` as never }}
|
|
51
|
-
pressStyle={{ backgroundColor: `$${tint}5` as never }}
|
|
52
|
-
outlineWidth={0}
|
|
53
|
-
focusStyle={{ outlineWidth: 0 }}
|
|
54
|
-
focusVisibleStyle={chipFocusRing}
|
|
55
|
-
{...(isWeb
|
|
56
|
-
? {
|
|
57
|
-
onFocus: () => {
|
|
58
|
-
if (wasKeyboardFocus()) setKbFocus(true);
|
|
59
|
-
},
|
|
60
|
-
onBlur: () => setKbFocus(false),
|
|
61
|
-
onKeyDown: (event: { key?: string; preventDefault?: () => void }) => {
|
|
62
|
-
if (event.key === "Enter" || event.key === " ") {
|
|
63
|
-
event.preventDefault?.();
|
|
64
|
-
onPress();
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
}
|
|
68
|
-
: undefined)}
|
|
69
|
-
{...(kbFocus ? keyboardFocusRingProps : undefined)}
|
|
70
|
-
onPress={onPress}
|
|
71
|
-
testID={testID ? `${testID}-${value}` : undefined}
|
|
72
|
-
>
|
|
73
|
-
<XStack
|
|
74
|
-
width="$1"
|
|
75
|
-
height="$1"
|
|
76
|
-
borderRadius={1000}
|
|
77
|
-
backgroundColor={`$${tint}9` as never}
|
|
78
|
-
flexShrink={0}
|
|
79
|
-
/>
|
|
80
|
-
<Text
|
|
81
|
-
{...knobProps.label}
|
|
82
|
-
color={`$${tint}11` as never}
|
|
83
|
-
textTransform="capitalize"
|
|
84
|
-
userSelect="none"
|
|
85
|
-
>
|
|
86
|
-
{label}
|
|
87
|
-
</Text>
|
|
88
|
-
<Text {...knobProps.label} color={`$${tint}11` as never} opacity={0.7} userSelect="none">
|
|
89
|
-
{count}
|
|
90
|
-
</Text>
|
|
91
|
-
</XStack>
|
|
92
|
-
);
|
|
93
|
-
}
|
|
94
|
-
|
|
95
5
|
export interface InsightsFacetTagsProps {
|
|
96
6
|
distribution: readonly InsightsCount[];
|
|
97
7
|
label: (value: string) => string;
|
|
@@ -100,7 +10,10 @@ export interface InsightsFacetTagsProps {
|
|
|
100
10
|
testID?: string;
|
|
101
11
|
}
|
|
102
12
|
|
|
103
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* A facet's values with their record counts as MPO `Chip`s painted from each
|
|
15
|
+
* value's ramp (DF-04, LC-175), each opening the list narrowed to it.
|
|
16
|
+
*/
|
|
104
17
|
export function InsightsFacetTags({
|
|
105
18
|
distribution,
|
|
106
19
|
label,
|
|
@@ -115,16 +28,22 @@ export function InsightsFacetTags({
|
|
|
115
28
|
enableAdd={false}
|
|
116
29
|
enableRemove={false}
|
|
117
30
|
labels={{ noTags: t("No values yet") }}
|
|
118
|
-
renderTag={(tag) =>
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
31
|
+
renderTag={(tag) => {
|
|
32
|
+
const count = distribution.find((entry) => entry.value === tag.id)?.count ?? 0;
|
|
33
|
+
const hue = tint?.(tag.id) ?? "gray";
|
|
34
|
+
return (
|
|
35
|
+
<Chip
|
|
36
|
+
color={hue}
|
|
37
|
+
swatch={`$${hue}9` as never}
|
|
38
|
+
count={count}
|
|
39
|
+
aria-label={t("{{value}}, {{count}} records", { value: tag.label, count })}
|
|
40
|
+
onPress={() => onSelect(tag.id)}
|
|
41
|
+
testID={testID ? `${testID}-${tag.id}` : undefined}
|
|
42
|
+
>
|
|
43
|
+
{tag.label}
|
|
44
|
+
</Chip>
|
|
45
|
+
);
|
|
46
|
+
}}
|
|
128
47
|
/>
|
|
129
48
|
);
|
|
130
49
|
}
|
package/src/list/FacetBadge.tsx
CHANGED
|
@@ -1,44 +1,22 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { hairlineWidth, sizeTokenStep, useResolvedKnobs } from "@multiplatform.one/theme";
|
|
1
|
+
import { Chip, type ChipSize } from "@multiplatform.one/components";
|
|
3
2
|
import type { SizeTokens } from "tamagui";
|
|
4
|
-
import { facetBadgeSteps } from "./facetBadgeSteps";
|
|
5
3
|
|
|
6
4
|
export interface FacetBadgeProps {
|
|
7
5
|
label: string;
|
|
8
6
|
/** Theme ramp (`"green"`) painting the badge (LC-147). */
|
|
9
7
|
tint?: string;
|
|
10
|
-
/** Size token (Tamagui's own `size`);
|
|
8
|
+
/** Size token (Tamagui's own `size`); omitted, the chip takes the ambient size. */
|
|
11
9
|
size?: SizeTokens;
|
|
12
10
|
}
|
|
13
11
|
|
|
14
12
|
/**
|
|
15
|
-
* One facet value as a static
|
|
16
|
-
* step-4 fill
|
|
13
|
+
* One facet value as a static MPO `Chip` tinted from its ramp: the ramp's
|
|
14
|
+
* step-4 fill and step-12 ink, AA in both schemes (DF-04, LC-175).
|
|
17
15
|
*/
|
|
18
16
|
export function FacetBadge({ label, tint = "gray", size }: FacetBadgeProps) {
|
|
19
|
-
const { knobProps } = useResolvedKnobs({ size });
|
|
20
|
-
const small = sizeTokenStep(knobProps.sizeToken) < 0;
|
|
21
17
|
return (
|
|
22
|
-
<
|
|
23
|
-
{
|
|
24
|
-
|
|
25
|
-
paddingVertical={small ? "$0.5" : "$1"}
|
|
26
|
-
backgroundColor={`$${tint}${facetBadgeSteps.fill}` as never}
|
|
27
|
-
borderColor={`$${tint}${facetBadgeSteps.border}` as never}
|
|
28
|
-
borderWidth={hairlineWidth}
|
|
29
|
-
alignItems="center"
|
|
30
|
-
>
|
|
31
|
-
<Text
|
|
32
|
-
{...knobProps.label}
|
|
33
|
-
{...knobProps.body}
|
|
34
|
-
textTransform="capitalize"
|
|
35
|
-
fontWeight="700"
|
|
36
|
-
color={`$${tint}${facetBadgeSteps.ink}` as never}
|
|
37
|
-
{...(small ? { fontSize: "$1" as const } : null)}
|
|
38
|
-
letterSpacing={0.3}
|
|
39
|
-
>
|
|
40
|
-
{label}
|
|
41
|
-
</Text>
|
|
42
|
-
</XStack>
|
|
18
|
+
<Chip color={tint} size={size as ChipSize | undefined}>
|
|
19
|
+
{label}
|
|
20
|
+
</Chip>
|
|
43
21
|
);
|
|
44
22
|
}
|