@portnet/ui 6.0.1 → 6.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +737 -0
- package/dist/esm/index.js +90 -3
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/v2/__tests__/AppMain.test.js +130 -0
- package/dist/esm/v2/__tests__/AppMain.test.js.map +1 -0
- package/dist/esm/v2/__tests__/ChartFigure.test.js +180 -0
- package/dist/esm/v2/__tests__/ChartFigure.test.js.map +1 -0
- package/dist/esm/v2/__tests__/DataGridRowActionsPropagation.test.js +150 -0
- package/dist/esm/v2/__tests__/DataGridRowActionsPropagation.test.js.map +1 -0
- package/dist/esm/v2/__tests__/DrawerTactileTargets.test.js +93 -0
- package/dist/esm/v2/__tests__/DrawerTactileTargets.test.js.map +1 -0
- package/dist/esm/v2/__tests__/FieldError.test.js +71 -39
- package/dist/esm/v2/__tests__/FieldError.test.js.map +1 -1
- package/dist/esm/v2/__tests__/FieldNaming.test.js +160 -0
- package/dist/esm/v2/__tests__/FieldNaming.test.js.map +1 -0
- package/dist/esm/v2/__tests__/FieldWidth.test.js +146 -0
- package/dist/esm/v2/__tests__/FieldWidth.test.js.map +1 -0
- package/dist/esm/v2/__tests__/FileCard.test.js +18 -18
- package/dist/esm/v2/__tests__/FileCard.test.js.map +1 -1
- package/dist/esm/v2/__tests__/FormikCheckbox.test.js +173 -0
- package/dist/esm/v2/__tests__/FormikCheckbox.test.js.map +1 -0
- package/dist/esm/v2/__tests__/FormikDateTimePicker.test.js +236 -0
- package/dist/esm/v2/__tests__/FormikDateTimePicker.test.js.map +1 -0
- package/dist/esm/v2/__tests__/FormikDisplayWidth.test.js +101 -0
- package/dist/esm/v2/__tests__/FormikDisplayWidth.test.js.map +1 -0
- package/dist/esm/v2/__tests__/FormikRadioGroup.test.js +299 -0
- package/dist/esm/v2/__tests__/FormikRadioGroup.test.js.map +1 -0
- package/dist/esm/v2/__tests__/MobileRowCard.test.js +44 -43
- package/dist/esm/v2/__tests__/MobileRowCard.test.js.map +1 -1
- package/dist/esm/v2/__tests__/PreviewDrawer.test.js +165 -0
- package/dist/esm/v2/__tests__/PreviewDrawer.test.js.map +1 -0
- package/dist/esm/v2/__tests__/ReferentielFieldContainer.test.js +156 -0
- package/dist/esm/v2/__tests__/ReferentielFieldContainer.test.js.map +1 -0
- package/dist/esm/v2/__tests__/SectionErrorBoundary.test.js +37 -52
- package/dist/esm/v2/__tests__/SectionErrorBoundary.test.js.map +1 -1
- package/dist/esm/v2/__tests__/apiError.test.js +50 -69
- package/dist/esm/v2/__tests__/apiError.test.js.map +1 -1
- package/dist/esm/v2/__tests__/banned-patterns.test.js +41 -122
- package/dist/esm/v2/__tests__/banned-patterns.test.js.map +1 -1
- package/dist/esm/v2/__tests__/chart-palette.test.js +204 -0
- package/dist/esm/v2/__tests__/chart-palette.test.js.map +1 -0
- package/dist/esm/v2/__tests__/contrast-palette.test.js +42 -74
- package/dist/esm/v2/__tests__/contrast-palette.test.js.map +1 -1
- package/dist/esm/v2/__tests__/cssVariables.test.js +44 -51
- package/dist/esm/v2/__tests__/cssVariables.test.js.map +1 -1
- package/dist/esm/v2/__tests__/fileValidation.test.js +134 -0
- package/dist/esm/v2/__tests__/fileValidation.test.js.map +1 -0
- package/dist/esm/v2/__tests__/filterCriteria.test.js +321 -0
- package/dist/esm/v2/__tests__/filterCriteria.test.js.map +1 -0
- package/dist/esm/v2/__tests__/fmtDate.test.js +68 -0
- package/dist/esm/v2/__tests__/fmtDate.test.js.map +1 -0
- package/dist/esm/v2/__tests__/gap-leakage-refonte.test.js +218 -0
- package/dist/esm/v2/__tests__/gap-leakage-refonte.test.js.map +1 -0
- package/dist/esm/v2/__tests__/labels-merge.test.js +17 -22
- package/dist/esm/v2/__tests__/labels-merge.test.js.map +1 -1
- package/dist/esm/v2/__tests__/locale-fallback.test.js +35 -40
- package/dist/esm/v2/__tests__/locale-fallback.test.js.map +1 -1
- package/dist/esm/v2/__tests__/reviveSavedCriteria.test.js +143 -0
- package/dist/esm/v2/__tests__/reviveSavedCriteria.test.js.map +1 -0
- package/dist/esm/v2/__tests__/rowActions.test.js +182 -0
- package/dist/esm/v2/__tests__/rowActions.test.js.map +1 -0
- package/dist/esm/v2/__tests__/useFocusOnRouteChange.test.js +155 -0
- package/dist/esm/v2/__tests__/useFocusOnRouteChange.test.js.map +1 -0
- package/dist/esm/v2/__tests__/useFocusTrap.test.js +266 -402
- package/dist/esm/v2/__tests__/useFocusTrap.test.js.map +1 -1
- package/dist/esm/v2/__tests__/usePrefersReducedMotion.test.js +120 -0
- package/dist/esm/v2/__tests__/usePrefersReducedMotion.test.js.map +1 -0
- package/dist/esm/v2/components/Accordion.js +48 -70
- package/dist/esm/v2/components/Accordion.js.map +1 -1
- package/dist/esm/v2/components/ActionStrip.js +31 -43
- package/dist/esm/v2/components/ActionStrip.js.map +1 -1
- package/dist/esm/v2/components/Banner.js +25 -22
- package/dist/esm/v2/components/Banner.js.map +1 -1
- package/dist/esm/v2/components/Busy.js +14 -19
- package/dist/esm/v2/components/Busy.js.map +1 -1
- package/dist/esm/v2/components/Button.js +34 -45
- package/dist/esm/v2/components/Button.js.map +1 -1
- package/dist/esm/v2/components/CategoryTag.js +44 -27
- package/dist/esm/v2/components/CategoryTag.js.map +1 -1
- package/dist/esm/v2/components/Checkbox.js +32 -38
- package/dist/esm/v2/components/Checkbox.js.map +1 -1
- package/dist/esm/v2/components/Chip.js +23 -36
- package/dist/esm/v2/components/Chip.js.map +1 -1
- package/dist/esm/v2/components/Combobox.js +112 -136
- package/dist/esm/v2/components/Combobox.js.map +1 -1
- package/dist/esm/v2/components/CommandPalette.js +113 -198
- package/dist/esm/v2/components/CommandPalette.js.map +1 -1
- package/dist/esm/v2/components/ConfirmDialog.js +36 -45
- package/dist/esm/v2/components/ConfirmDialog.js.map +1 -1
- package/dist/esm/v2/components/DatePicker.js +78 -81
- package/dist/esm/v2/components/DatePicker.js.map +1 -1
- package/dist/esm/v2/components/DateRangePicker.js +63 -74
- package/dist/esm/v2/components/DateRangePicker.js.map +1 -1
- package/dist/esm/v2/components/DateTimePicker.js +118 -90
- package/dist/esm/v2/components/DateTimePicker.js.map +1 -1
- package/dist/esm/v2/components/Drawer.js +71 -65
- package/dist/esm/v2/components/Drawer.js.map +1 -1
- package/dist/esm/v2/components/Dropzone.js +130 -177
- package/dist/esm/v2/components/Dropzone.js.map +1 -1
- package/dist/esm/v2/components/EmptyState.js +9 -9
- package/dist/esm/v2/components/EmptyState.js.map +1 -1
- package/dist/esm/v2/components/FavoriteToggle.js +24 -33
- package/dist/esm/v2/components/FavoriteToggle.js.map +1 -1
- package/dist/esm/v2/components/Field.js +210 -52
- package/dist/esm/v2/components/Field.js.map +1 -1
- package/dist/esm/v2/components/FieldError.js +9 -13
- package/dist/esm/v2/components/FieldError.js.map +1 -1
- package/dist/esm/v2/components/FieldHelp.js +28 -49
- package/dist/esm/v2/components/FieldHelp.js.map +1 -1
- package/dist/esm/v2/components/FileCard.js +14 -19
- package/dist/esm/v2/components/FileCard.js.map +1 -1
- package/dist/esm/v2/components/FilterTab.js +22 -31
- package/dist/esm/v2/components/FilterTab.js.map +1 -1
- package/dist/esm/v2/components/ForbiddenPage.js +28 -8
- package/dist/esm/v2/components/ForbiddenPage.js.map +1 -1
- package/dist/esm/v2/components/FormGrid.js +48 -54
- package/dist/esm/v2/components/FormGrid.js.map +1 -1
- package/dist/esm/v2/components/FormikDisplay.js +98 -24
- package/dist/esm/v2/components/FormikDisplay.js.map +1 -1
- package/dist/esm/v2/components/Input.js +75 -34
- package/dist/esm/v2/components/Input.js.map +1 -1
- package/dist/esm/v2/components/KPICard.js +42 -51
- package/dist/esm/v2/components/KPICard.js.map +1 -1
- package/dist/esm/v2/components/KPIStrip.js +9 -15
- package/dist/esm/v2/components/KPIStrip.js.map +1 -1
- package/dist/esm/v2/components/KV.js +16 -23
- package/dist/esm/v2/components/KV.js.map +1 -1
- package/dist/esm/v2/components/KVGrid.js +15 -23
- package/dist/esm/v2/components/KVGrid.js.map +1 -1
- package/dist/esm/v2/components/Layout.js +81 -117
- package/dist/esm/v2/components/Layout.js.map +1 -1
- package/dist/esm/v2/components/MobileRowCard.js +64 -75
- package/dist/esm/v2/components/MobileRowCard.js.map +1 -1
- package/dist/esm/v2/components/Modal.js +44 -53
- package/dist/esm/v2/components/Modal.js.map +1 -1
- package/dist/esm/v2/components/NetworkErrorPage.js +28 -11
- package/dist/esm/v2/components/NetworkErrorPage.js.map +1 -1
- package/dist/esm/v2/components/NotFoundPage.js +28 -9
- package/dist/esm/v2/components/NotFoundPage.js.map +1 -1
- package/dist/esm/v2/components/NumberInput.js +77 -107
- package/dist/esm/v2/components/NumberInput.js.map +1 -1
- package/dist/esm/v2/components/OverflowMenu.js +24 -42
- package/dist/esm/v2/components/OverflowMenu.js.map +1 -1
- package/dist/esm/v2/components/PdfViewer.js +24 -33
- package/dist/esm/v2/components/PdfViewer.js.map +1 -1
- package/dist/esm/v2/components/ProgressBar.js +28 -36
- package/dist/esm/v2/components/ProgressBar.js.map +1 -1
- package/dist/esm/v2/components/Radio.js +49 -57
- package/dist/esm/v2/components/Radio.js.map +1 -1
- package/dist/esm/v2/components/SectionErrorBoundary.js +84 -130
- package/dist/esm/v2/components/SectionErrorBoundary.js.map +1 -1
- package/dist/esm/v2/components/SectionHeader.js +24 -31
- package/dist/esm/v2/components/SectionHeader.js.map +1 -1
- package/dist/esm/v2/components/Segmented.js +59 -84
- package/dist/esm/v2/components/Segmented.js.map +1 -1
- package/dist/esm/v2/components/Select.js +100 -138
- package/dist/esm/v2/components/Select.js.map +1 -1
- package/dist/esm/v2/components/ServerErrorPage.js +27 -10
- package/dist/esm/v2/components/ServerErrorPage.js.map +1 -1
- package/dist/esm/v2/components/Skeleton.js +81 -96
- package/dist/esm/v2/components/Skeleton.js.map +1 -1
- package/dist/esm/v2/components/SkipLink.js +6 -7
- package/dist/esm/v2/components/SkipLink.js.map +1 -1
- package/dist/esm/v2/components/Spinner.js +13 -22
- package/dist/esm/v2/components/Spinner.js.map +1 -1
- package/dist/esm/v2/components/Status.js +14 -25
- package/dist/esm/v2/components/Status.js.map +1 -1
- package/dist/esm/v2/components/Stepper.js +68 -71
- package/dist/esm/v2/components/Stepper.js.map +1 -1
- package/dist/esm/v2/components/Surface.js +25 -44
- package/dist/esm/v2/components/Surface.js.map +1 -1
- package/dist/esm/v2/components/Switch.js +21 -29
- package/dist/esm/v2/components/Switch.js.map +1 -1
- package/dist/esm/v2/components/TabPanel.js +84 -0
- package/dist/esm/v2/components/TabPanel.js.map +1 -0
- package/dist/esm/v2/components/Tabs.js +43 -19
- package/dist/esm/v2/components/Tabs.js.map +1 -1
- package/dist/esm/v2/components/TelInput.js +75 -108
- package/dist/esm/v2/components/TelInput.js.map +1 -1
- package/dist/esm/v2/components/Textarea.js +21 -30
- package/dist/esm/v2/components/Textarea.js.map +1 -1
- package/dist/esm/v2/components/TimePicker.js +59 -69
- package/dist/esm/v2/components/TimePicker.js.map +1 -1
- package/dist/esm/v2/components/Toast.js +109 -163
- package/dist/esm/v2/components/Toast.js.map +1 -1
- package/dist/esm/v2/components/Tooltip.js +18 -31
- package/dist/esm/v2/components/Tooltip.js.map +1 -1
- package/dist/esm/v2/components/_ErrorPageBody.js +6 -5
- package/dist/esm/v2/components/_ErrorPageBody.js.map +1 -1
- package/dist/esm/v2/components/_pickerShared.js +2 -2
- package/dist/esm/v2/components/_pickerShared.js.map +1 -1
- package/dist/esm/v2/components/index.js +64 -0
- package/dist/esm/v2/components/index.js.map +1 -1
- package/dist/esm/v2/hooks/index.js +62 -0
- package/dist/esm/v2/hooks/index.js.map +1 -1
- package/dist/esm/v2/hooks/useAppliedFilters.js +112 -0
- package/dist/esm/v2/hooks/useAppliedFilters.js.map +1 -0
- package/dist/esm/v2/hooks/useDebouncedCallback.js +82 -0
- package/dist/esm/v2/hooks/useDebouncedCallback.js.map +1 -0
- package/dist/esm/v2/hooks/useDelayedFlag.js +5 -19
- package/dist/esm/v2/hooks/useDelayedFlag.js.map +1 -1
- package/dist/esm/v2/hooks/useDensity.js +13 -17
- package/dist/esm/v2/hooks/useDensity.js.map +1 -1
- package/dist/esm/v2/hooks/useFocusFirstError.js +25 -33
- package/dist/esm/v2/hooks/useFocusFirstError.js.map +1 -1
- package/dist/esm/v2/hooks/useFocusOnRouteChange.js +81 -0
- package/dist/esm/v2/hooks/useFocusOnRouteChange.js.map +1 -0
- package/dist/esm/v2/hooks/useFocusTrap.js +19 -23
- package/dist/esm/v2/hooks/useFocusTrap.js.map +1 -1
- package/dist/esm/v2/hooks/useFormAutoSave.js +38 -53
- package/dist/esm/v2/hooks/useFormAutoSave.js.map +1 -1
- package/dist/esm/v2/hooks/useFormCompletionProgress.js +32 -51
- package/dist/esm/v2/hooks/useFormCompletionProgress.js.map +1 -1
- package/dist/esm/v2/hooks/useKeyboardShortcuts.js +125 -0
- package/dist/esm/v2/hooks/useKeyboardShortcuts.js.map +1 -0
- package/dist/esm/v2/hooks/usePrefersReducedMotion.js +99 -0
- package/dist/esm/v2/hooks/usePrefersReducedMotion.js.map +1 -0
- package/dist/esm/v2/hooks/useResolvedDensity.js +2 -10
- package/dist/esm/v2/hooks/useResolvedDensity.js.map +1 -1
- package/dist/esm/v2/hooks/useSortedRows.js +3 -5
- package/dist/esm/v2/hooks/useSortedRows.js.map +1 -1
- package/dist/esm/v2/hooks/useTabLoading.js +6 -21
- package/dist/esm/v2/hooks/useTabLoading.js.map +1 -1
- package/dist/esm/v2/index.js +14 -4
- package/dist/esm/v2/index.js.map +1 -1
- package/dist/esm/v2/modalContext.js +2 -2
- package/dist/esm/v2/modalContext.js.map +1 -1
- package/dist/esm/v2/models/favorite.js.map +1 -1
- package/dist/esm/v2/models/personalization.js.map +1 -1
- package/dist/esm/v2/models/referentiel.js.map +1 -1
- package/dist/esm/v2/models/savedFilter.js.map +1 -1
- package/dist/esm/v2/patterns/ActionBar.js +115 -159
- package/dist/esm/v2/patterns/ActionBar.js.map +1 -1
- package/dist/esm/v2/patterns/AppMain.js +108 -0
- package/dist/esm/v2/patterns/AppMain.js.map +1 -0
- package/dist/esm/v2/patterns/BulkActionBar.js +31 -34
- package/dist/esm/v2/patterns/BulkActionBar.js.map +1 -1
- package/dist/esm/v2/patterns/ChartFigure.js +151 -0
- package/dist/esm/v2/patterns/ChartFigure.js.map +1 -0
- package/dist/esm/v2/patterns/CollapsibleDataGrid.js +111 -152
- package/dist/esm/v2/patterns/CollapsibleDataGrid.js.map +1 -1
- package/dist/esm/v2/patterns/ColumnsToggle.js +43 -77
- package/dist/esm/v2/patterns/ColumnsToggle.js.map +1 -1
- package/dist/esm/v2/patterns/DataGrid.js +221 -255
- package/dist/esm/v2/patterns/DataGrid.js.map +1 -1
- package/dist/esm/v2/patterns/DataGridSettingsMenu.js +76 -94
- package/dist/esm/v2/patterns/DataGridSettingsMenu.js.map +1 -1
- package/dist/esm/v2/patterns/DataGridToolbar.js +85 -89
- package/dist/esm/v2/patterns/DataGridToolbar.js.map +1 -1
- package/dist/esm/v2/patterns/DataGridVirtualized.js +141 -182
- package/dist/esm/v2/patterns/DataGridVirtualized.js.map +1 -1
- package/dist/esm/v2/patterns/DeleteResourceConfirmDialog.js +26 -30
- package/dist/esm/v2/patterns/DeleteResourceConfirmDialog.js.map +1 -1
- package/dist/esm/v2/patterns/DetailSplit.js +108 -0
- package/dist/esm/v2/patterns/DetailSplit.js.map +1 -0
- package/dist/esm/v2/patterns/FavoriteColumn.js +26 -75
- package/dist/esm/v2/patterns/FavoriteColumn.js.map +1 -1
- package/dist/esm/v2/patterns/FavoritesFilter.js +30 -39
- package/dist/esm/v2/patterns/FavoritesFilter.js.map +1 -1
- package/dist/esm/v2/patterns/FilterTabBar.js +112 -0
- package/dist/esm/v2/patterns/FilterTabBar.js.map +1 -0
- package/dist/esm/v2/patterns/FormErrorSummary.js +12 -13
- package/dist/esm/v2/patterns/FormErrorSummary.js.map +1 -1
- package/dist/esm/v2/patterns/FormPageShell.js +43 -41
- package/dist/esm/v2/patterns/FormPageShell.js.map +1 -1
- package/dist/esm/v2/patterns/FormSection.js +30 -38
- package/dist/esm/v2/patterns/FormSection.js.map +1 -1
- package/dist/esm/v2/patterns/FormikCheckbox.js +130 -0
- package/dist/esm/v2/patterns/FormikCheckbox.js.map +1 -0
- package/dist/esm/v2/patterns/FormikCheckboxGroup.js +56 -60
- package/dist/esm/v2/patterns/FormikCheckboxGroup.js.map +1 -1
- package/dist/esm/v2/patterns/FormikCombobox.js +51 -66
- package/dist/esm/v2/patterns/FormikCombobox.js.map +1 -1
- package/dist/esm/v2/patterns/FormikDatePicker.js +51 -99
- package/dist/esm/v2/patterns/FormikDatePicker.js.map +1 -1
- package/dist/esm/v2/patterns/FormikDateTimePicker.js +136 -0
- package/dist/esm/v2/patterns/FormikDateTimePicker.js.map +1 -0
- package/dist/esm/v2/patterns/FormikErrorFocus.js +22 -23
- package/dist/esm/v2/patterns/FormikErrorFocus.js.map +1 -1
- package/dist/esm/v2/patterns/FormikErrorSummary.js +89 -0
- package/dist/esm/v2/patterns/FormikErrorSummary.js.map +1 -0
- package/dist/esm/v2/patterns/FormikFile.js +94 -78
- package/dist/esm/v2/patterns/FormikFile.js.map +1 -1
- package/dist/esm/v2/patterns/FormikInput.js +40 -50
- package/dist/esm/v2/patterns/FormikInput.js.map +1 -1
- package/dist/esm/v2/patterns/FormikRadioGroup.js +129 -0
- package/dist/esm/v2/patterns/FormikRadioGroup.js.map +1 -0
- package/dist/esm/v2/patterns/FormikReferentielField.js +49 -59
- package/dist/esm/v2/patterns/FormikReferentielField.js.map +1 -1
- package/dist/esm/v2/patterns/FormikSelect.js +64 -84
- package/dist/esm/v2/patterns/FormikSelect.js.map +1 -1
- package/dist/esm/v2/patterns/FormikTextarea.js +30 -43
- package/dist/esm/v2/patterns/FormikTextarea.js.map +1 -1
- package/dist/esm/v2/patterns/KeyboardShortcutsHelp.js +64 -65
- package/dist/esm/v2/patterns/KeyboardShortcutsHelp.js.map +1 -1
- package/dist/esm/v2/patterns/NetworkErrorBanner.js +6 -7
- package/dist/esm/v2/patterns/NetworkErrorBanner.js.map +1 -1
- package/dist/esm/v2/patterns/PageContent.js +10 -14
- package/dist/esm/v2/patterns/PageContent.js.map +1 -1
- package/dist/esm/v2/patterns/PreviewDrawer.js +153 -0
- package/dist/esm/v2/patterns/PreviewDrawer.js.map +1 -0
- package/dist/esm/v2/patterns/ReferentielField.js +327 -312
- package/dist/esm/v2/patterns/ReferentielField.js.map +1 -1
- package/dist/esm/v2/patterns/RowFavoriteToggle.js +127 -0
- package/dist/esm/v2/patterns/RowFavoriteToggle.js.map +1 -0
- package/dist/esm/v2/patterns/SaveFilterDialog.js +38 -66
- package/dist/esm/v2/patterns/SaveFilterDialog.js.map +1 -1
- package/dist/esm/v2/patterns/SavedFiltersMenu.js +62 -81
- package/dist/esm/v2/patterns/SavedFiltersMenu.js.map +1 -1
- package/dist/esm/v2/patterns/SkeletonPageShell.js +106 -129
- package/dist/esm/v2/patterns/SkeletonPageShell.js.map +1 -1
- package/dist/esm/v2/patterns/SortableHeader.js +22 -45
- package/dist/esm/v2/patterns/SortableHeader.js.map +1 -1
- package/dist/esm/v2/patterns/Tour.js +94 -120
- package/dist/esm/v2/patterns/Tour.js.map +1 -1
- package/dist/esm/v2/patterns/_dataGridShared.js +107 -128
- package/dist/esm/v2/patterns/_dataGridShared.js.map +1 -1
- package/dist/esm/v2/patterns/_pickerSerialisation.js +72 -0
- package/dist/esm/v2/patterns/_pickerSerialisation.js.map +1 -0
- package/dist/esm/v2/patterns/_sort.js +17 -33
- package/dist/esm/v2/patterns/_sort.js.map +1 -1
- package/dist/esm/v2/patterns/_useColumnReorder.js +122 -160
- package/dist/esm/v2/patterns/_useColumnReorder.js.map +1 -1
- package/dist/esm/v2/patterns/_useColumnResize.js +78 -96
- package/dist/esm/v2/patterns/_useColumnResize.js.map +1 -1
- package/dist/esm/v2/patterns/filterCriteria.js +102 -0
- package/dist/esm/v2/patterns/filterCriteria.js.map +1 -0
- package/dist/esm/v2/patterns/index.js +235 -0
- package/dist/esm/v2/patterns/index.js.map +1 -1
- package/dist/esm/v2/patterns/rowActions.js +223 -0
- package/dist/esm/v2/patterns/rowActions.js.map +1 -0
- package/dist/esm/v2/personalization/PersonalizationProvider.js +50 -47
- package/dist/esm/v2/personalization/PersonalizationProvider.js.map +1 -1
- package/dist/esm/v2/personalization/adapters/_storageKey.js +5 -5
- package/dist/esm/v2/personalization/adapters/_storageKey.js.map +1 -1
- package/dist/esm/v2/personalization/adapters/createLocalStorageAdapter.js +22 -23
- package/dist/esm/v2/personalization/adapters/createLocalStorageAdapter.js.map +1 -1
- package/dist/esm/v2/personalization/adapters/createMemoryAdapter.js +13 -13
- package/dist/esm/v2/personalization/adapters/createMemoryAdapter.js.map +1 -1
- package/dist/esm/v2/personalization/capabilities/favorites.js +36 -60
- package/dist/esm/v2/personalization/capabilities/favorites.js.map +1 -1
- package/dist/esm/v2/personalization/capabilities/favoritesView.js +22 -34
- package/dist/esm/v2/personalization/capabilities/favoritesView.js.map +1 -1
- package/dist/esm/v2/personalization/capabilities/gridPreferences.js +203 -0
- package/dist/esm/v2/personalization/capabilities/gridPreferences.js.map +1 -0
- package/dist/esm/v2/personalization/capabilities/index.js +5 -0
- package/dist/esm/v2/personalization/capabilities/index.js.map +1 -1
- package/dist/esm/v2/personalization/capabilities/reviveSavedCriteria.js +119 -0
- package/dist/esm/v2/personalization/capabilities/reviveSavedCriteria.js.map +1 -0
- package/dist/esm/v2/personalization/capabilities/savedFilters.js +90 -98
- package/dist/esm/v2/personalization/capabilities/savedFilters.js.map +1 -1
- package/dist/esm/v2/personalization/createPersonalizationStore.js +78 -181
- package/dist/esm/v2/personalization/createPersonalizationStore.js.map +1 -1
- package/dist/esm/v2/personalization/index.js +35 -0
- package/dist/esm/v2/personalization/index.js.map +1 -1
- package/dist/esm/v2/personalization/personalizationContext.js +9 -9
- package/dist/esm/v2/personalization/personalizationContext.js.map +1 -1
- package/dist/esm/v2/personalization/schema.js +8 -9
- package/dist/esm/v2/personalization/schema.js.map +1 -1
- package/dist/esm/v2/referentiel/ReferentielProvider.js +27 -42
- package/dist/esm/v2/referentiel/ReferentielProvider.js.map +1 -1
- package/dist/esm/v2/referentiel/types.js +2 -0
- package/dist/esm/v2/referentiel/types.js.map +1 -0
- package/dist/esm/v2/referentiel/useReferentielClient.js +10 -11
- package/dist/esm/v2/referentiel/useReferentielClient.js.map +1 -1
- package/dist/esm/v2/referentiel/useReferentielOptions.js +60 -117
- package/dist/esm/v2/referentiel/useReferentielOptions.js.map +1 -1
- package/dist/esm/v2/referentiel/useReferentielSearch.js +37 -91
- package/dist/esm/v2/referentiel/useReferentielSearch.js.map +1 -1
- package/dist/esm/v2/theme/_brand.js +8 -24
- package/dist/esm/v2/theme/_brand.js.map +1 -1
- package/dist/esm/v2/theme/_brandSecondary.js +8 -24
- package/dist/esm/v2/theme/_brandSecondary.js.map +1 -1
- package/dist/esm/v2/theme/createPortnetTheme.js +51 -61
- package/dist/esm/v2/theme/createPortnetTheme.js.map +1 -1
- package/dist/esm/v2/theme/cssVariables.js +62 -69
- package/dist/esm/v2/theme/cssVariables.js.map +1 -1
- package/dist/esm/v2/theme/index.js +5 -5
- package/dist/esm/v2/theme/index.js.map +1 -1
- package/dist/esm/v2/tokens/breakpoints.js +14 -14
- package/dist/esm/v2/tokens/breakpoints.js.map +1 -1
- package/dist/esm/v2/tokens/chart.js +261 -0
- package/dist/esm/v2/tokens/chart.js.map +1 -0
- package/dist/esm/v2/tokens/colors.js +22 -22
- package/dist/esm/v2/tokens/colors.js.map +1 -1
- package/dist/esm/v2/tokens/density.js +62 -7
- package/dist/esm/v2/tokens/density.js.map +1 -1
- package/dist/esm/v2/tokens/index.js +49 -34
- package/dist/esm/v2/tokens/index.js.map +1 -1
- package/dist/esm/v2/tokens/motion.js +12 -20
- package/dist/esm/v2/tokens/motion.js.map +1 -1
- package/dist/esm/v2/tokens/radius.js +1 -1
- package/dist/esm/v2/tokens/radius.js.map +1 -1
- package/dist/esm/v2/tokens/shadows.js +6 -6
- package/dist/esm/v2/tokens/shadows.js.map +1 -1
- package/dist/esm/v2/tokens/spacing.js +2 -2
- package/dist/esm/v2/tokens/spacing.js.map +1 -1
- package/dist/esm/v2/tokens/state.js +1 -1
- package/dist/esm/v2/tokens/state.js.map +1 -1
- package/dist/esm/v2/tokens/statusPalette.js +17 -21
- package/dist/esm/v2/tokens/statusPalette.js.map +1 -1
- package/dist/esm/v2/tokens/tokens.json +6 -1
- package/dist/esm/v2/tokens/typography.js +13 -13
- package/dist/esm/v2/tokens/typography.js.map +1 -1
- package/dist/esm/v2/tokens/zIndex.js +1 -1
- package/dist/esm/v2/tokens/zIndex.js.map +1 -1
- package/dist/esm/v2/types/datagrid.js.map +1 -1
- package/dist/esm/v2/utils/apiError.js +16 -37
- package/dist/esm/v2/utils/apiError.js.map +1 -1
- package/dist/esm/v2/utils/contrast.js +31 -32
- package/dist/esm/v2/utils/contrast.js.map +1 -1
- package/dist/esm/v2/utils/cx.js +5 -25
- package/dist/esm/v2/utils/cx.js.map +1 -1
- package/dist/esm/v2/utils/fileDownload.js +23 -26
- package/dist/esm/v2/utils/fileDownload.js.map +1 -1
- package/dist/esm/v2/utils/fileValidation.js +209 -0
- package/dist/esm/v2/utils/fileValidation.js.map +1 -0
- package/dist/esm/v2/utils/fmtDate.js +111 -0
- package/dist/esm/v2/utils/fmtDate.js.map +1 -0
- package/dist/esm/v2/utils/fmtMoney.js +8 -10
- package/dist/esm/v2/utils/fmtMoney.js.map +1 -1
- package/dist/esm/v2/utils/formikErrors.js +78 -0
- package/dist/esm/v2/utils/formikErrors.js.map +1 -0
- package/dist/esm/v2/utils/index.js +35 -2
- package/dist/esm/v2/utils/index.js.map +1 -1
- package/dist/esm/v2/utils/mergeLabels.js +7 -12
- package/dist/esm/v2/utils/mergeLabels.js.map +1 -1
- package/dist/esm/v2/utils/networkStatus.js +12 -12
- package/dist/esm/v2/utils/networkStatus.js.map +1 -1
- package/dist/index.d.ts +9 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +122 -47
- package/dist/index.js.map +1 -1
- package/dist/v2/__tests__/AppMain.test.js +133 -0
- package/dist/v2/__tests__/AppMain.test.js.map +1 -0
- package/dist/v2/__tests__/ChartFigure.test.js +183 -0
- package/dist/v2/__tests__/ChartFigure.test.js.map +1 -0
- package/dist/v2/__tests__/DataGridRowActionsPropagation.test.js +153 -0
- package/dist/v2/__tests__/DataGridRowActionsPropagation.test.js.map +1 -0
- package/dist/v2/__tests__/DrawerTactileTargets.test.js +94 -0
- package/dist/v2/__tests__/DrawerTactileTargets.test.js.map +1 -0
- package/dist/v2/__tests__/FieldError.test.js +98 -69
- package/dist/v2/__tests__/FieldError.test.js.map +1 -1
- package/dist/v2/__tests__/FieldNaming.test.js +161 -0
- package/dist/v2/__tests__/FieldNaming.test.js.map +1 -0
- package/dist/v2/__tests__/FieldWidth.test.js +148 -0
- package/dist/v2/__tests__/FieldWidth.test.js.map +1 -0
- package/dist/v2/__tests__/FileCard.test.js +45 -48
- package/dist/v2/__tests__/FileCard.test.js.map +1 -1
- package/dist/v2/__tests__/FormikCheckbox.test.js +175 -0
- package/dist/v2/__tests__/FormikCheckbox.test.js.map +1 -0
- package/dist/v2/__tests__/FormikDateTimePicker.test.js +237 -0
- package/dist/v2/__tests__/FormikDateTimePicker.test.js.map +1 -0
- package/dist/v2/__tests__/FormikDisplayWidth.test.js +102 -0
- package/dist/v2/__tests__/FormikDisplayWidth.test.js.map +1 -0
- package/dist/v2/__tests__/FormikRadioGroup.test.js +300 -0
- package/dist/v2/__tests__/FormikRadioGroup.test.js.map +1 -0
- package/dist/v2/__tests__/MobileRowCard.test.js +100 -102
- package/dist/v2/__tests__/MobileRowCard.test.js.map +1 -1
- package/dist/v2/__tests__/PreviewDrawer.test.js +169 -0
- package/dist/v2/__tests__/PreviewDrawer.test.js.map +1 -0
- package/dist/v2/__tests__/ReferentielFieldContainer.test.js +159 -0
- package/dist/v2/__tests__/ReferentielFieldContainer.test.js.map +1 -0
- package/dist/v2/__tests__/SectionErrorBoundary.test.js +53 -68
- package/dist/v2/__tests__/SectionErrorBoundary.test.js.map +1 -1
- package/dist/v2/__tests__/apiError.test.js +50 -69
- package/dist/v2/__tests__/apiError.test.js.map +1 -1
- package/dist/v2/__tests__/banned-patterns.test.js +42 -123
- package/dist/v2/__tests__/banned-patterns.test.js.map +1 -1
- package/dist/v2/__tests__/chart-palette.test.js +205 -0
- package/dist/v2/__tests__/chart-palette.test.js.map +1 -0
- package/dist/v2/__tests__/contrast-palette.test.js +42 -74
- package/dist/v2/__tests__/contrast-palette.test.js.map +1 -1
- package/dist/v2/__tests__/cssVariables.test.js +44 -51
- package/dist/v2/__tests__/cssVariables.test.js.map +1 -1
- package/dist/v2/__tests__/fileValidation.test.js +136 -0
- package/dist/v2/__tests__/fileValidation.test.js.map +1 -0
- package/dist/v2/__tests__/filterCriteria.test.js +324 -0
- package/dist/v2/__tests__/filterCriteria.test.js.map +1 -0
- package/dist/v2/__tests__/fmtDate.test.js +69 -0
- package/dist/v2/__tests__/fmtDate.test.js.map +1 -0
- package/dist/v2/__tests__/gap-leakage-refonte.test.js +221 -0
- package/dist/v2/__tests__/gap-leakage-refonte.test.js.map +1 -0
- package/dist/v2/__tests__/labels-merge.test.js +38 -46
- package/dist/v2/__tests__/labels-merge.test.js.map +1 -1
- package/dist/v2/__tests__/locale-fallback.test.js +47 -52
- package/dist/v2/__tests__/locale-fallback.test.js.map +1 -1
- package/dist/v2/__tests__/reviveSavedCriteria.test.js +144 -0
- package/dist/v2/__tests__/reviveSavedCriteria.test.js.map +1 -0
- package/dist/v2/__tests__/rowActions.test.js +186 -0
- package/dist/v2/__tests__/rowActions.test.js.map +1 -0
- package/dist/v2/__tests__/useFocusOnRouteChange.test.js +156 -0
- package/dist/v2/__tests__/useFocusOnRouteChange.test.js.map +1 -0
- package/dist/v2/__tests__/useFocusTrap.test.js +270 -407
- package/dist/v2/__tests__/useFocusTrap.test.js.map +1 -1
- package/dist/v2/__tests__/usePrefersReducedMotion.test.js +123 -0
- package/dist/v2/__tests__/usePrefersReducedMotion.test.js.map +1 -0
- package/dist/v2/components/Accordion.js +60 -82
- package/dist/v2/components/Accordion.js.map +1 -1
- package/dist/v2/components/ActionStrip.js +40 -52
- package/dist/v2/components/ActionStrip.js.map +1 -1
- package/dist/v2/components/Banner.js +42 -41
- package/dist/v2/components/Banner.js.map +1 -1
- package/dist/v2/components/Busy.js +22 -27
- package/dist/v2/components/Busy.js.map +1 -1
- package/dist/v2/components/Button.js +39 -50
- package/dist/v2/components/Button.js.map +1 -1
- package/dist/v2/components/CategoryTag.d.ts.map +1 -1
- package/dist/v2/components/CategoryTag.js +49 -32
- package/dist/v2/components/CategoryTag.js.map +1 -1
- package/dist/v2/components/Checkbox.js +39 -45
- package/dist/v2/components/Checkbox.js.map +1 -1
- package/dist/v2/components/Chip.js +29 -42
- package/dist/v2/components/Chip.js.map +1 -1
- package/dist/v2/components/Combobox.js +122 -144
- package/dist/v2/components/Combobox.js.map +1 -1
- package/dist/v2/components/CommandPalette.js +138 -225
- package/dist/v2/components/CommandPalette.js.map +1 -1
- package/dist/v2/components/ConfirmDialog.js +46 -56
- package/dist/v2/components/ConfirmDialog.js.map +1 -1
- package/dist/v2/components/DatePicker.js +81 -86
- package/dist/v2/components/DatePicker.js.map +1 -1
- package/dist/v2/components/DateRangePicker.js +77 -87
- package/dist/v2/components/DateRangePicker.js.map +1 -1
- package/dist/v2/components/DateTimePicker.d.ts.map +1 -1
- package/dist/v2/components/DateTimePicker.js +121 -95
- package/dist/v2/components/DateTimePicker.js.map +1 -1
- package/dist/v2/components/Drawer.d.ts.map +1 -1
- package/dist/v2/components/Drawer.js +93 -88
- package/dist/v2/components/Drawer.js.map +1 -1
- package/dist/v2/components/Dropzone.js +150 -196
- package/dist/v2/components/Dropzone.js.map +1 -1
- package/dist/v2/components/EmptyState.js +18 -20
- package/dist/v2/components/EmptyState.js.map +1 -1
- package/dist/v2/components/FavoriteToggle.js +28 -39
- package/dist/v2/components/FavoriteToggle.js.map +1 -1
- package/dist/v2/components/Field.d.ts +121 -5
- package/dist/v2/components/Field.d.ts.map +1 -1
- package/dist/v2/components/Field.js +221 -62
- package/dist/v2/components/Field.js.map +1 -1
- package/dist/v2/components/FieldError.js +18 -21
- package/dist/v2/components/FieldError.js.map +1 -1
- package/dist/v2/components/FieldHelp.js +40 -60
- package/dist/v2/components/FieldHelp.js.map +1 -1
- package/dist/v2/components/FileCard.js +27 -31
- package/dist/v2/components/FileCard.js.map +1 -1
- package/dist/v2/components/FilterTab.js +30 -38
- package/dist/v2/components/FilterTab.js.map +1 -1
- package/dist/v2/components/ForbiddenPage.d.ts +25 -1
- package/dist/v2/components/ForbiddenPage.d.ts.map +1 -1
- package/dist/v2/components/ForbiddenPage.js +37 -17
- package/dist/v2/components/ForbiddenPage.js.map +1 -1
- package/dist/v2/components/FormGrid.js +53 -59
- package/dist/v2/components/FormGrid.js.map +1 -1
- package/dist/v2/components/FormikDisplay.d.ts +50 -1
- package/dist/v2/components/FormikDisplay.d.ts.map +1 -1
- package/dist/v2/components/FormikDisplay.js +108 -33
- package/dist/v2/components/FormikDisplay.js.map +1 -1
- package/dist/v2/components/Input.d.ts +40 -0
- package/dist/v2/components/Input.d.ts.map +1 -1
- package/dist/v2/components/Input.js +81 -41
- package/dist/v2/components/Input.js.map +1 -1
- package/dist/v2/components/KPICard.js +57 -67
- package/dist/v2/components/KPICard.js.map +1 -1
- package/dist/v2/components/KPIStrip.js +16 -22
- package/dist/v2/components/KPIStrip.js.map +1 -1
- package/dist/v2/components/KV.js +25 -31
- package/dist/v2/components/KV.js.map +1 -1
- package/dist/v2/components/KVGrid.js +19 -26
- package/dist/v2/components/KVGrid.js.map +1 -1
- package/dist/v2/components/Layout.js +91 -120
- package/dist/v2/components/Layout.js.map +1 -1
- package/dist/v2/components/MobileRowCard.js +79 -91
- package/dist/v2/components/MobileRowCard.js.map +1 -1
- package/dist/v2/components/Modal.js +61 -69
- package/dist/v2/components/Modal.js.map +1 -1
- package/dist/v2/components/NetworkErrorPage.d.ts +19 -1
- package/dist/v2/components/NetworkErrorPage.d.ts.map +1 -1
- package/dist/v2/components/NetworkErrorPage.js +38 -21
- package/dist/v2/components/NetworkErrorPage.js.map +1 -1
- package/dist/v2/components/NotFoundPage.d.ts +17 -1
- package/dist/v2/components/NotFoundPage.d.ts.map +1 -1
- package/dist/v2/components/NotFoundPage.js +37 -18
- package/dist/v2/components/NotFoundPage.js.map +1 -1
- package/dist/v2/components/NumberInput.js +88 -118
- package/dist/v2/components/NumberInput.js.map +1 -1
- package/dist/v2/components/OverflowMenu.js +38 -56
- package/dist/v2/components/OverflowMenu.js.map +1 -1
- package/dist/v2/components/PdfViewer.js +34 -45
- package/dist/v2/components/PdfViewer.js.map +1 -1
- package/dist/v2/components/ProgressBar.js +42 -49
- package/dist/v2/components/ProgressBar.js.map +1 -1
- package/dist/v2/components/Radio.js +59 -67
- package/dist/v2/components/Radio.js.map +1 -1
- package/dist/v2/components/SectionErrorBoundary.js +90 -135
- package/dist/v2/components/SectionErrorBoundary.js.map +1 -1
- package/dist/v2/components/SectionHeader.js +34 -41
- package/dist/v2/components/SectionHeader.js.map +1 -1
- package/dist/v2/components/Segmented.js +69 -93
- package/dist/v2/components/Segmented.js.map +1 -1
- package/dist/v2/components/Select.d.ts +26 -2
- package/dist/v2/components/Select.d.ts.map +1 -1
- package/dist/v2/components/Select.js +120 -155
- package/dist/v2/components/Select.js.map +1 -1
- package/dist/v2/components/ServerErrorPage.d.ts +27 -1
- package/dist/v2/components/ServerErrorPage.d.ts.map +1 -1
- package/dist/v2/components/ServerErrorPage.js +37 -20
- package/dist/v2/components/ServerErrorPage.js.map +1 -1
- package/dist/v2/components/Skeleton.js +86 -100
- package/dist/v2/components/Skeleton.js.map +1 -1
- package/dist/v2/components/SkipLink.js +9 -12
- package/dist/v2/components/SkipLink.js.map +1 -1
- package/dist/v2/components/Spinner.js +16 -25
- package/dist/v2/components/Spinner.js.map +1 -1
- package/dist/v2/components/Status.js +18 -29
- package/dist/v2/components/Status.js.map +1 -1
- package/dist/v2/components/Stepper.js +80 -82
- package/dist/v2/components/Stepper.js.map +1 -1
- package/dist/v2/components/Surface.js +34 -49
- package/dist/v2/components/Surface.js.map +1 -1
- package/dist/v2/components/Switch.js +29 -37
- package/dist/v2/components/Switch.js.map +1 -1
- package/dist/v2/components/TabPanel.d.ts +17 -0
- package/dist/v2/components/TabPanel.d.ts.map +1 -0
- package/dist/v2/components/TabPanel.js +90 -0
- package/dist/v2/components/TabPanel.js.map +1 -0
- package/dist/v2/components/Tabs.d.ts +25 -0
- package/dist/v2/components/Tabs.d.ts.map +1 -1
- package/dist/v2/components/Tabs.js +53 -29
- package/dist/v2/components/Tabs.js.map +1 -1
- package/dist/v2/components/TelInput.js +80 -115
- package/dist/v2/components/TelInput.js.map +1 -1
- package/dist/v2/components/Textarea.js +26 -35
- package/dist/v2/components/Textarea.js.map +1 -1
- package/dist/v2/components/TimePicker.js +62 -74
- package/dist/v2/components/TimePicker.js.map +1 -1
- package/dist/v2/components/Toast.js +119 -174
- package/dist/v2/components/Toast.js.map +1 -1
- package/dist/v2/components/Tooltip.js +23 -38
- package/dist/v2/components/Tooltip.js.map +1 -1
- package/dist/v2/components/_ErrorPageBody.js +15 -16
- package/dist/v2/components/_ErrorPageBody.js.map +1 -1
- package/dist/v2/components/_pickerShared.js +5 -5
- package/dist/v2/components/_pickerShared.js.map +1 -1
- package/dist/v2/components/index.d.ts +67 -1
- package/dist/v2/components/index.d.ts.map +1 -1
- package/dist/v2/components/index.js +153 -136
- package/dist/v2/components/index.js.map +1 -1
- package/dist/v2/hooks/index.d.ts +65 -0
- package/dist/v2/hooks/index.d.ts.map +1 -1
- package/dist/v2/hooks/index.js +63 -24
- package/dist/v2/hooks/index.js.map +1 -1
- package/dist/v2/hooks/useAppliedFilters.d.ts +102 -0
- package/dist/v2/hooks/useAppliedFilters.d.ts.map +1 -0
- package/dist/v2/hooks/useAppliedFilters.js +117 -0
- package/dist/v2/hooks/useAppliedFilters.js.map +1 -0
- package/dist/v2/hooks/useDebouncedCallback.d.ts +64 -0
- package/dist/v2/hooks/useDebouncedCallback.d.ts.map +1 -0
- package/dist/v2/hooks/useDebouncedCallback.js +87 -0
- package/dist/v2/hooks/useDebouncedCallback.js.map +1 -0
- package/dist/v2/hooks/useDelayedFlag.js +6 -20
- package/dist/v2/hooks/useDelayedFlag.js.map +1 -1
- package/dist/v2/hooks/useDensity.d.ts.map +1 -1
- package/dist/v2/hooks/useDensity.js +14 -18
- package/dist/v2/hooks/useDensity.js.map +1 -1
- package/dist/v2/hooks/useFocusFirstError.js +26 -34
- package/dist/v2/hooks/useFocusFirstError.js.map +1 -1
- package/dist/v2/hooks/useFocusOnRouteChange.d.ts +65 -0
- package/dist/v2/hooks/useFocusOnRouteChange.d.ts.map +1 -0
- package/dist/v2/hooks/useFocusOnRouteChange.js +88 -0
- package/dist/v2/hooks/useFocusOnRouteChange.js.map +1 -0
- package/dist/v2/hooks/useFocusTrap.js +20 -24
- package/dist/v2/hooks/useFocusTrap.js.map +1 -1
- package/dist/v2/hooks/useFormAutoSave.d.ts +4 -4
- package/dist/v2/hooks/useFormAutoSave.d.ts.map +1 -1
- package/dist/v2/hooks/useFormAutoSave.js +39 -54
- package/dist/v2/hooks/useFormAutoSave.js.map +1 -1
- package/dist/v2/hooks/useFormCompletionProgress.d.ts +1 -1
- package/dist/v2/hooks/useFormCompletionProgress.d.ts.map +1 -1
- package/dist/v2/hooks/useFormCompletionProgress.js +33 -52
- package/dist/v2/hooks/useFormCompletionProgress.js.map +1 -1
- package/dist/v2/hooks/useKeyboardShortcuts.d.ts +25 -0
- package/dist/v2/hooks/useKeyboardShortcuts.d.ts.map +1 -0
- package/dist/v2/hooks/useKeyboardShortcuts.js +132 -0
- package/dist/v2/hooks/useKeyboardShortcuts.js.map +1 -0
- package/dist/v2/hooks/usePrefersReducedMotion.d.ts +56 -0
- package/dist/v2/hooks/usePrefersReducedMotion.d.ts.map +1 -0
- package/dist/v2/hooks/usePrefersReducedMotion.js +105 -0
- package/dist/v2/hooks/usePrefersReducedMotion.js.map +1 -0
- package/dist/v2/hooks/useResolvedDensity.js +5 -13
- package/dist/v2/hooks/useResolvedDensity.js.map +1 -1
- package/dist/v2/hooks/useSortedRows.js +4 -6
- package/dist/v2/hooks/useSortedRows.js.map +1 -1
- package/dist/v2/hooks/useTabLoading.js +7 -22
- package/dist/v2/hooks/useTabLoading.js.map +1 -1
- package/dist/v2/index.d.ts.map +1 -1
- package/dist/v2/index.js +143 -145
- package/dist/v2/index.js.map +1 -1
- package/dist/v2/modalContext.js +2 -2
- package/dist/v2/modalContext.js.map +1 -1
- package/dist/v2/models/favorite.d.ts +8 -9
- package/dist/v2/models/favorite.d.ts.map +1 -1
- package/dist/v2/models/favorite.js.map +1 -1
- package/dist/v2/models/index.js +4 -4
- package/dist/v2/models/index.js.map +1 -1
- package/dist/v2/models/personalization.d.ts +44 -48
- package/dist/v2/models/personalization.d.ts.map +1 -1
- package/dist/v2/models/personalization.js.map +1 -1
- package/dist/v2/models/referentiel.d.ts +32 -50
- package/dist/v2/models/referentiel.d.ts.map +1 -1
- package/dist/v2/models/referentiel.js.map +1 -1
- package/dist/v2/models/savedFilter.d.ts +8 -17
- package/dist/v2/models/savedFilter.d.ts.map +1 -1
- package/dist/v2/models/savedFilter.js.map +1 -1
- package/dist/v2/patterns/ActionBar.js +152 -187
- package/dist/v2/patterns/ActionBar.js.map +1 -1
- package/dist/v2/patterns/AppMain.d.ts +109 -0
- package/dist/v2/patterns/AppMain.d.ts.map +1 -0
- package/dist/v2/patterns/AppMain.js +115 -0
- package/dist/v2/patterns/AppMain.js.map +1 -0
- package/dist/v2/patterns/BulkActionBar.js +40 -42
- package/dist/v2/patterns/BulkActionBar.js.map +1 -1
- package/dist/v2/patterns/ChartFigure.d.ts +124 -0
- package/dist/v2/patterns/ChartFigure.d.ts.map +1 -0
- package/dist/v2/patterns/ChartFigure.js +159 -0
- package/dist/v2/patterns/ChartFigure.js.map +1 -0
- package/dist/v2/patterns/CollapsibleDataGrid.js +138 -174
- package/dist/v2/patterns/CollapsibleDataGrid.js.map +1 -1
- package/dist/v2/patterns/ColumnsToggle.js +60 -94
- package/dist/v2/patterns/ColumnsToggle.js.map +1 -1
- package/dist/v2/patterns/DataGrid.d.ts.map +1 -1
- package/dist/v2/patterns/DataGrid.js +262 -297
- package/dist/v2/patterns/DataGrid.js.map +1 -1
- package/dist/v2/patterns/DataGridSettingsMenu.d.ts +12 -0
- package/dist/v2/patterns/DataGridSettingsMenu.d.ts.map +1 -1
- package/dist/v2/patterns/DataGridSettingsMenu.js +104 -121
- package/dist/v2/patterns/DataGridSettingsMenu.js.map +1 -1
- package/dist/v2/patterns/DataGridToolbar.js +103 -106
- package/dist/v2/patterns/DataGridToolbar.js.map +1 -1
- package/dist/v2/patterns/DataGridVirtualized.js +179 -217
- package/dist/v2/patterns/DataGridVirtualized.js.map +1 -1
- package/dist/v2/patterns/DeleteResourceConfirmDialog.js +32 -35
- package/dist/v2/patterns/DeleteResourceConfirmDialog.js.map +1 -1
- package/dist/v2/patterns/DetailSplit.d.ts +87 -0
- package/dist/v2/patterns/DetailSplit.d.ts.map +1 -0
- package/dist/v2/patterns/DetailSplit.js +116 -0
- package/dist/v2/patterns/DetailSplit.js.map +1 -0
- package/dist/v2/patterns/FavoriteColumn.d.ts +9 -9
- package/dist/v2/patterns/FavoriteColumn.d.ts.map +1 -1
- package/dist/v2/patterns/FavoriteColumn.js +32 -80
- package/dist/v2/patterns/FavoriteColumn.js.map +1 -1
- package/dist/v2/patterns/FavoritesFilter.js +36 -44
- package/dist/v2/patterns/FavoritesFilter.js.map +1 -1
- package/dist/v2/patterns/FilterTabBar.d.ts +28 -0
- package/dist/v2/patterns/FilterTabBar.d.ts.map +1 -0
- package/dist/v2/patterns/FilterTabBar.js +120 -0
- package/dist/v2/patterns/FilterTabBar.js.map +1 -0
- package/dist/v2/patterns/FormErrorSummary.js +20 -23
- package/dist/v2/patterns/FormErrorSummary.js.map +1 -1
- package/dist/v2/patterns/FormPageShell.js +53 -50
- package/dist/v2/patterns/FormPageShell.js.map +1 -1
- package/dist/v2/patterns/FormSection.d.ts +8 -3
- package/dist/v2/patterns/FormSection.d.ts.map +1 -1
- package/dist/v2/patterns/FormSection.js +44 -51
- package/dist/v2/patterns/FormSection.js.map +1 -1
- package/dist/v2/patterns/FormikCheckbox.d.ts +77 -0
- package/dist/v2/patterns/FormikCheckbox.d.ts.map +1 -0
- package/dist/v2/patterns/FormikCheckbox.js +138 -0
- package/dist/v2/patterns/FormikCheckbox.js.map +1 -0
- package/dist/v2/patterns/FormikCheckboxGroup.d.ts +17 -1
- package/dist/v2/patterns/FormikCheckboxGroup.d.ts.map +1 -1
- package/dist/v2/patterns/FormikCheckboxGroup.js +62 -65
- package/dist/v2/patterns/FormikCheckboxGroup.js.map +1 -1
- package/dist/v2/patterns/FormikCombobox.d.ts +7 -1
- package/dist/v2/patterns/FormikCombobox.d.ts.map +1 -1
- package/dist/v2/patterns/FormikCombobox.js +55 -69
- package/dist/v2/patterns/FormikCombobox.js.map +1 -1
- package/dist/v2/patterns/FormikDatePicker.d.ts +13 -1
- package/dist/v2/patterns/FormikDatePicker.d.ts.map +1 -1
- package/dist/v2/patterns/FormikDatePicker.js +59 -106
- package/dist/v2/patterns/FormikDatePicker.js.map +1 -1
- package/dist/v2/patterns/FormikDateTimePicker.d.ts +111 -0
- package/dist/v2/patterns/FormikDateTimePicker.d.ts.map +1 -0
- package/dist/v2/patterns/FormikDateTimePicker.js +144 -0
- package/dist/v2/patterns/FormikDateTimePicker.js.map +1 -0
- package/dist/v2/patterns/FormikErrorFocus.js +25 -26
- package/dist/v2/patterns/FormikErrorFocus.js.map +1 -1
- package/dist/v2/patterns/FormikErrorSummary.d.ts +74 -0
- package/dist/v2/patterns/FormikErrorSummary.d.ts.map +1 -0
- package/dist/v2/patterns/FormikErrorSummary.js +97 -0
- package/dist/v2/patterns/FormikErrorSummary.js.map +1 -0
- package/dist/v2/patterns/FormikFile.d.ts +14 -1
- package/dist/v2/patterns/FormikFile.d.ts.map +1 -1
- package/dist/v2/patterns/FormikFile.js +99 -83
- package/dist/v2/patterns/FormikFile.js.map +1 -1
- package/dist/v2/patterns/FormikInput.d.ts +11 -1
- package/dist/v2/patterns/FormikInput.d.ts.map +1 -1
- package/dist/v2/patterns/FormikInput.js +45 -55
- package/dist/v2/patterns/FormikInput.js.map +1 -1
- package/dist/v2/patterns/FormikRadioGroup.d.ts +80 -0
- package/dist/v2/patterns/FormikRadioGroup.d.ts.map +1 -0
- package/dist/v2/patterns/FormikRadioGroup.js +137 -0
- package/dist/v2/patterns/FormikRadioGroup.js.map +1 -0
- package/dist/v2/patterns/FormikReferentielField.d.ts +12 -1
- package/dist/v2/patterns/FormikReferentielField.d.ts.map +1 -1
- package/dist/v2/patterns/FormikReferentielField.js +54 -64
- package/dist/v2/patterns/FormikReferentielField.js.map +1 -1
- package/dist/v2/patterns/FormikSelect.d.ts +9 -1
- package/dist/v2/patterns/FormikSelect.d.ts.map +1 -1
- package/dist/v2/patterns/FormikSelect.js +70 -89
- package/dist/v2/patterns/FormikSelect.js.map +1 -1
- package/dist/v2/patterns/FormikTextarea.d.ts +9 -1
- package/dist/v2/patterns/FormikTextarea.d.ts.map +1 -1
- package/dist/v2/patterns/FormikTextarea.js +35 -48
- package/dist/v2/patterns/FormikTextarea.js.map +1 -1
- package/dist/v2/patterns/KeyboardShortcutsHelp.d.ts +14 -1
- package/dist/v2/patterns/KeyboardShortcutsHelp.d.ts.map +1 -1
- package/dist/v2/patterns/KeyboardShortcutsHelp.js +71 -74
- package/dist/v2/patterns/KeyboardShortcutsHelp.js.map +1 -1
- package/dist/v2/patterns/NetworkErrorBanner.js +13 -16
- package/dist/v2/patterns/NetworkErrorBanner.js.map +1 -1
- package/dist/v2/patterns/PageContent.js +17 -20
- package/dist/v2/patterns/PageContent.js.map +1 -1
- package/dist/v2/patterns/PreviewDrawer.d.ts +49 -0
- package/dist/v2/patterns/PreviewDrawer.d.ts.map +1 -0
- package/dist/v2/patterns/PreviewDrawer.js +159 -0
- package/dist/v2/patterns/PreviewDrawer.js.map +1 -0
- package/dist/v2/patterns/ReferentielField.d.ts +86 -2
- package/dist/v2/patterns/ReferentielField.d.ts.map +1 -1
- package/dist/v2/patterns/ReferentielField.js +347 -327
- package/dist/v2/patterns/ReferentielField.js.map +1 -1
- package/dist/v2/patterns/RowFavoriteToggle.d.ts +98 -0
- package/dist/v2/patterns/RowFavoriteToggle.d.ts.map +1 -0
- package/dist/v2/patterns/RowFavoriteToggle.js +135 -0
- package/dist/v2/patterns/RowFavoriteToggle.js.map +1 -0
- package/dist/v2/patterns/SaveFilterDialog.js +50 -77
- package/dist/v2/patterns/SaveFilterDialog.js.map +1 -1
- package/dist/v2/patterns/SavedFiltersMenu.js +89 -107
- package/dist/v2/patterns/SavedFiltersMenu.js.map +1 -1
- package/dist/v2/patterns/SkeletonPageShell.js +122 -143
- package/dist/v2/patterns/SkeletonPageShell.js.map +1 -1
- package/dist/v2/patterns/SortableHeader.js +35 -57
- package/dist/v2/patterns/SortableHeader.js.map +1 -1
- package/dist/v2/patterns/Tour.js +121 -142
- package/dist/v2/patterns/Tour.js.map +1 -1
- package/dist/v2/patterns/_dataGridShared.d.ts.map +1 -1
- package/dist/v2/patterns/_dataGridShared.js +131 -147
- package/dist/v2/patterns/_dataGridShared.js.map +1 -1
- package/dist/v2/patterns/_pickerSerialisation.d.ts +44 -0
- package/dist/v2/patterns/_pickerSerialisation.d.ts.map +1 -0
- package/dist/v2/patterns/_pickerSerialisation.js +80 -0
- package/dist/v2/patterns/_pickerSerialisation.js.map +1 -0
- package/dist/v2/patterns/_sort.js +17 -33
- package/dist/v2/patterns/_sort.js.map +1 -1
- package/dist/v2/patterns/_useColumnReorder.js +124 -163
- package/dist/v2/patterns/_useColumnReorder.js.map +1 -1
- package/dist/v2/patterns/_useColumnResize.js +80 -99
- package/dist/v2/patterns/_useColumnResize.js.map +1 -1
- package/dist/v2/patterns/filterCriteria.d.ts +78 -0
- package/dist/v2/patterns/filterCriteria.d.ts.map +1 -0
- package/dist/v2/patterns/filterCriteria.js +110 -0
- package/dist/v2/patterns/filterCriteria.js.map +1 -0
- package/dist/v2/patterns/index.d.ts +247 -0
- package/dist/v2/patterns/index.d.ts.map +1 -1
- package/dist/v2/patterns/index.js +182 -70
- package/dist/v2/patterns/index.js.map +1 -1
- package/dist/v2/patterns/rowActions.d.ts +150 -0
- package/dist/v2/patterns/rowActions.d.ts.map +1 -0
- package/dist/v2/patterns/rowActions.js +232 -0
- package/dist/v2/patterns/rowActions.js.map +1 -0
- package/dist/v2/personalization/PersonalizationProvider.d.ts.map +1 -1
- package/dist/v2/personalization/PersonalizationProvider.js +57 -53
- package/dist/v2/personalization/PersonalizationProvider.js.map +1 -1
- package/dist/v2/personalization/adapters/_storageKey.js +5 -5
- package/dist/v2/personalization/adapters/_storageKey.js.map +1 -1
- package/dist/v2/personalization/adapters/createLocalStorageAdapter.js +25 -24
- package/dist/v2/personalization/adapters/createLocalStorageAdapter.js.map +1 -1
- package/dist/v2/personalization/adapters/createMemoryAdapter.js +14 -14
- package/dist/v2/personalization/adapters/createMemoryAdapter.js.map +1 -1
- package/dist/v2/personalization/adapters/index.js +5 -5
- package/dist/v2/personalization/adapters/index.js.map +1 -1
- package/dist/v2/personalization/capabilities/favorites.js +39 -62
- package/dist/v2/personalization/capabilities/favorites.js.map +1 -1
- package/dist/v2/personalization/capabilities/favoritesView.js +25 -37
- package/dist/v2/personalization/capabilities/favoritesView.js.map +1 -1
- package/dist/v2/personalization/capabilities/gridPreferences.d.ts +100 -0
- package/dist/v2/personalization/capabilities/gridPreferences.d.ts.map +1 -0
- package/dist/v2/personalization/capabilities/gridPreferences.js +210 -0
- package/dist/v2/personalization/capabilities/gridPreferences.js.map +1 -0
- package/dist/v2/personalization/capabilities/index.d.ts +6 -0
- package/dist/v2/personalization/capabilities/index.d.ts.map +1 -1
- package/dist/v2/personalization/capabilities/index.js +23 -10
- package/dist/v2/personalization/capabilities/index.js.map +1 -1
- package/dist/v2/personalization/capabilities/reviveSavedCriteria.d.ts +88 -0
- package/dist/v2/personalization/capabilities/reviveSavedCriteria.d.ts.map +1 -0
- package/dist/v2/personalization/capabilities/reviveSavedCriteria.js +126 -0
- package/dist/v2/personalization/capabilities/reviveSavedCriteria.js.map +1 -0
- package/dist/v2/personalization/capabilities/savedFilters.js +93 -100
- package/dist/v2/personalization/capabilities/savedFilters.js.map +1 -1
- package/dist/v2/personalization/createPersonalizationStore.d.ts.map +1 -1
- package/dist/v2/personalization/createPersonalizationStore.js +81 -182
- package/dist/v2/personalization/createPersonalizationStore.js.map +1 -1
- package/dist/v2/personalization/index.d.ts +34 -0
- package/dist/v2/personalization/index.d.ts.map +1 -1
- package/dist/v2/personalization/index.js +41 -21
- package/dist/v2/personalization/index.js.map +1 -1
- package/dist/v2/personalization/personalizationContext.js +10 -12
- package/dist/v2/personalization/personalizationContext.js.map +1 -1
- package/dist/v2/personalization/schema.js +8 -9
- package/dist/v2/personalization/schema.js.map +1 -1
- package/dist/v2/referentiel/ReferentielProvider.js +31 -45
- package/dist/v2/referentiel/ReferentielProvider.js.map +1 -1
- package/dist/v2/referentiel/index.js +11 -13
- package/dist/v2/referentiel/index.js.map +1 -1
- package/dist/v2/referentiel/types.d.ts +105 -0
- package/dist/v2/referentiel/types.d.ts.map +1 -0
- package/dist/v2/referentiel/types.js +6 -0
- package/dist/v2/referentiel/types.js.map +1 -0
- package/dist/v2/referentiel/useReferentielClient.js +13 -16
- package/dist/v2/referentiel/useReferentielClient.js.map +1 -1
- package/dist/v2/referentiel/useReferentielOptions.d.ts +7 -17
- package/dist/v2/referentiel/useReferentielOptions.d.ts.map +1 -1
- package/dist/v2/referentiel/useReferentielOptions.js +63 -120
- package/dist/v2/referentiel/useReferentielOptions.js.map +1 -1
- package/dist/v2/referentiel/useReferentielSearch.d.ts +7 -48
- package/dist/v2/referentiel/useReferentielSearch.d.ts.map +1 -1
- package/dist/v2/referentiel/useReferentielSearch.js +40 -95
- package/dist/v2/referentiel/useReferentielSearch.js.map +1 -1
- package/dist/v2/theme/_brand.js +12 -26
- package/dist/v2/theme/_brand.js.map +1 -1
- package/dist/v2/theme/_brandSecondary.js +12 -26
- package/dist/v2/theme/_brandSecondary.js.map +1 -1
- package/dist/v2/theme/createPortnetTheme.js +41 -49
- package/dist/v2/theme/createPortnetTheme.js.map +1 -1
- package/dist/v2/theme/cssVariables.d.ts +3 -3
- package/dist/v2/theme/cssVariables.d.ts.map +1 -1
- package/dist/v2/theme/cssVariables.js +65 -70
- package/dist/v2/theme/cssVariables.js.map +1 -1
- package/dist/v2/theme/index.js +10 -10
- package/dist/v2/theme/index.js.map +1 -1
- package/dist/v2/tokens/breakpoints.js +16 -16
- package/dist/v2/tokens/breakpoints.js.map +1 -1
- package/dist/v2/tokens/chart.d.ts +103 -0
- package/dist/v2/tokens/chart.d.ts.map +1 -0
- package/dist/v2/tokens/chart.js +270 -0
- package/dist/v2/tokens/chart.js.map +1 -0
- package/dist/v2/tokens/colors.js +24 -24
- package/dist/v2/tokens/colors.js.map +1 -1
- package/dist/v2/tokens/density.d.ts +104 -0
- package/dist/v2/tokens/density.d.ts.map +1 -1
- package/dist/v2/tokens/density.js +67 -12
- package/dist/v2/tokens/density.js.map +1 -1
- package/dist/v2/tokens/index.d.ts +50 -1
- package/dist/v2/tokens/index.d.ts.map +1 -1
- package/dist/v2/tokens/index.js +116 -68
- package/dist/v2/tokens/index.js.map +1 -1
- package/dist/v2/tokens/motion.js +16 -22
- package/dist/v2/tokens/motion.js.map +1 -1
- package/dist/v2/tokens/radius.js +3 -3
- package/dist/v2/tokens/radius.js.map +1 -1
- package/dist/v2/tokens/shadows.js +8 -8
- package/dist/v2/tokens/shadows.js.map +1 -1
- package/dist/v2/tokens/spacing.js +4 -4
- package/dist/v2/tokens/spacing.js.map +1 -1
- package/dist/v2/tokens/state.js +3 -3
- package/dist/v2/tokens/state.js.map +1 -1
- package/dist/v2/tokens/statusPalette.js +21 -23
- package/dist/v2/tokens/statusPalette.js.map +1 -1
- package/dist/v2/tokens/tokens.json +6 -1
- package/dist/v2/tokens/typography.js +15 -15
- package/dist/v2/tokens/typography.js.map +1 -1
- package/dist/v2/tokens/zIndex.js +3 -3
- package/dist/v2/tokens/zIndex.js.map +1 -1
- package/dist/v2/types/datagrid.d.ts +9 -1
- package/dist/v2/types/datagrid.d.ts.map +1 -1
- package/dist/v2/types/datagrid.js.map +1 -1
- package/dist/v2/types/index.js +2 -2
- package/dist/v2/types/index.js.map +1 -1
- package/dist/v2/utils/apiError.js +16 -37
- package/dist/v2/utils/apiError.js.map +1 -1
- package/dist/v2/utils/contrast.js +31 -32
- package/dist/v2/utils/contrast.js.map +1 -1
- package/dist/v2/utils/cx.js +7 -27
- package/dist/v2/utils/cx.js.map +1 -1
- package/dist/v2/utils/fileDownload.js +25 -28
- package/dist/v2/utils/fileDownload.js.map +1 -1
- package/dist/v2/utils/fileValidation.d.ts +116 -0
- package/dist/v2/utils/fileValidation.d.ts.map +1 -0
- package/dist/v2/utils/fileValidation.js +220 -0
- package/dist/v2/utils/fileValidation.js.map +1 -0
- package/dist/v2/utils/fmtDate.d.ts +103 -0
- package/dist/v2/utils/fmtDate.d.ts.map +1 -0
- package/dist/v2/utils/fmtDate.js +119 -0
- package/dist/v2/utils/fmtDate.js.map +1 -0
- package/dist/v2/utils/fmtMoney.d.ts +3 -3
- package/dist/v2/utils/fmtMoney.d.ts.map +1 -1
- package/dist/v2/utils/fmtMoney.js +9 -11
- package/dist/v2/utils/fmtMoney.js.map +1 -1
- package/dist/v2/utils/formikErrors.d.ts +67 -0
- package/dist/v2/utils/formikErrors.d.ts.map +1 -0
- package/dist/v2/utils/formikErrors.js +85 -0
- package/dist/v2/utils/formikErrors.js.map +1 -0
- package/dist/v2/utils/index.d.ts +5 -0
- package/dist/v2/utils/index.d.ts.map +1 -1
- package/dist/v2/utils/index.js +67 -18
- package/dist/v2/utils/index.js.map +1 -1
- package/dist/v2/utils/mergeLabels.js +9 -14
- package/dist/v2/utils/mergeLabels.js.map +1 -1
- package/dist/v2/utils/networkStatus.js +14 -14
- package/dist/v2/utils/networkStatus.js.map +1 -1
- package/package.json +26 -9
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
import { reviveSavedCriteria } from "../personalization/capabilities/reviveSavedCriteria";
|
|
2
|
+
|
|
3
|
+
/* ── What this file protects ────────────────────────────────────────────────
|
|
4
|
+
*
|
|
5
|
+
* The saved-filters round trip is asymmetrical: the local-storage adapter
|
|
6
|
+
* writes with `JSON.stringify` (a `Date` becomes an ISO string) and reads with
|
|
7
|
+
* a bare `JSON.parse`. Hosts could not see the consequence, because assigning
|
|
8
|
+
* the parsed payload into typed form state requires an assertion — which
|
|
9
|
+
* silences the very error that would have revealed it.
|
|
10
|
+
*
|
|
11
|
+
* So the assertions below stand in for a type error the compiler cannot raise
|
|
12
|
+
* on the host side. */
|
|
13
|
+
|
|
14
|
+
/** Declared with `interface` DELIBERATELY — see the type-level test at the end. */
|
|
15
|
+
|
|
16
|
+
const EMPTY = {
|
|
17
|
+
reference: "",
|
|
18
|
+
dateFrom: null,
|
|
19
|
+
dateTo: null,
|
|
20
|
+
importateur: null
|
|
21
|
+
};
|
|
22
|
+
describe("reviveSavedCriteria", () => {
|
|
23
|
+
it("returns the defaults when there is no payload", () => {
|
|
24
|
+
expect(reviveSavedCriteria(EMPTY, null)).toBe(EMPTY);
|
|
25
|
+
expect(reviveSavedCriteria(EMPTY, undefined)).toBe(EMPTY);
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
/* THE DEFECT THIS EXISTS FOR. */
|
|
29
|
+
it("turns an ISO string back into a Date", () => {
|
|
30
|
+
const saved = JSON.parse(JSON.stringify({
|
|
31
|
+
...EMPTY,
|
|
32
|
+
dateFrom: new Date("2026-03-05T00:00:00Z")
|
|
33
|
+
}));
|
|
34
|
+
|
|
35
|
+
// Precondition: the payload really did lose the Date on the way in.
|
|
36
|
+
expect(typeof saved["dateFrom"]).toBe("string");
|
|
37
|
+
const revived = reviveSavedCriteria(EMPTY, saved);
|
|
38
|
+
expect(revived.dateFrom).toBeInstanceOf(Date);
|
|
39
|
+
expect(revived.dateFrom.toISOString()).toBe("2026-03-05T00:00:00.000Z");
|
|
40
|
+
});
|
|
41
|
+
it("round-trips a full form through stringify / parse", () => {
|
|
42
|
+
const original = {
|
|
43
|
+
reference: "2026-IM-0042",
|
|
44
|
+
dateFrom: new Date("2026-01-01T00:00:00.000Z"),
|
|
45
|
+
dateTo: new Date("2026-12-31T23:59:59.000Z"),
|
|
46
|
+
importateur: {
|
|
47
|
+
id: 7,
|
|
48
|
+
description: "SOFRANE SA"
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
const revived = reviveSavedCriteria(EMPTY, JSON.parse(JSON.stringify(original)));
|
|
52
|
+
expect(revived).toEqual(original);
|
|
53
|
+
});
|
|
54
|
+
|
|
55
|
+
/* The regex is strict for this reason: DAAC references, customs codes and
|
|
56
|
+
* nomenclatures are date-ish strings that must NOT become dates. */
|
|
57
|
+
it("leaves business strings alone", () => {
|
|
58
|
+
const revived = reviveSavedCriteria(EMPTY, {
|
|
59
|
+
reference: "2026-IM-0042"
|
|
60
|
+
});
|
|
61
|
+
expect(revived.reference).toBe("2026-IM-0042");
|
|
62
|
+
});
|
|
63
|
+
it("does not revive a bare date without a time part", () => {
|
|
64
|
+
const revived = reviveSavedCriteria({
|
|
65
|
+
...EMPTY,
|
|
66
|
+
reference: ""
|
|
67
|
+
}, {
|
|
68
|
+
reference: "2026-03-05"
|
|
69
|
+
});
|
|
70
|
+
expect(revived.reference).toBe("2026-03-05");
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
/* ISO-SHAPED but impossible: the shape passes the regex, the value does not
|
|
74
|
+
* exist. `null` is returned rather than an Invalid Date, because an absent
|
|
75
|
+
* date is recoverable by the user and a NaN date silently poisons a payload. */
|
|
76
|
+
it("yields null for an ISO-shaped impossible instant", () => {
|
|
77
|
+
const revived = reviveSavedCriteria(EMPTY, {
|
|
78
|
+
dateFrom: "2026-13-45T00:00:00Z"
|
|
79
|
+
});
|
|
80
|
+
expect(revived.dateFrom).toBeNull();
|
|
81
|
+
});
|
|
82
|
+
it("ignores keys the form no longer declares", () => {
|
|
83
|
+
const revived = reviveSavedCriteria(EMPTY, {
|
|
84
|
+
reference: "X",
|
|
85
|
+
champRetireEnV2: "valeur héritée"
|
|
86
|
+
});
|
|
87
|
+
expect(revived.reference).toBe("X");
|
|
88
|
+
expect(Object.keys(revived).sort()).toEqual(Object.keys(EMPTY).sort());
|
|
89
|
+
});
|
|
90
|
+
it("keeps the default when a key is absent", () => {
|
|
91
|
+
const revived = reviveSavedCriteria({
|
|
92
|
+
...EMPTY,
|
|
93
|
+
reference: "défaut"
|
|
94
|
+
}, {
|
|
95
|
+
dateFrom: null
|
|
96
|
+
});
|
|
97
|
+
expect(revived.reference).toBe("défaut");
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
/* Under `exactOptionalPropertyTypes` a present key holding `undefined` is
|
|
101
|
+
* not an absent key, so it must not win over the default. */
|
|
102
|
+
it("does not let an explicit undefined overwrite a default", () => {
|
|
103
|
+
const revived = reviveSavedCriteria({
|
|
104
|
+
...EMPTY,
|
|
105
|
+
reference: "défaut"
|
|
106
|
+
}, {
|
|
107
|
+
reference: undefined
|
|
108
|
+
});
|
|
109
|
+
expect(revived.reference).toBe("défaut");
|
|
110
|
+
});
|
|
111
|
+
it("passes referentiel objects through untouched", () => {
|
|
112
|
+
const importateur = {
|
|
113
|
+
id: 7,
|
|
114
|
+
description: "SOFRANE SA"
|
|
115
|
+
};
|
|
116
|
+
const revived = reviveSavedCriteria(EMPTY, {
|
|
117
|
+
importateur
|
|
118
|
+
});
|
|
119
|
+
expect(revived.importateur).toEqual(importateur);
|
|
120
|
+
});
|
|
121
|
+
it("does not mutate the defaults it is given", () => {
|
|
122
|
+
const defaults = {
|
|
123
|
+
...EMPTY
|
|
124
|
+
};
|
|
125
|
+
reviveSavedCriteria(defaults, {
|
|
126
|
+
reference: "X"
|
|
127
|
+
});
|
|
128
|
+
expect(defaults.reference).toBe("");
|
|
129
|
+
});
|
|
130
|
+
|
|
131
|
+
/* TYPE-LEVEL — the reason the constraint is `Record<keyof T, unknown>` and
|
|
132
|
+
* not `Record<string, unknown>`. `ListFilters` is an INTERFACE, which has no
|
|
133
|
+
* implicit index signature: under the looser constraint this file would not
|
|
134
|
+
* compile, and the host would be pushed back into an assertion. The
|
|
135
|
+
* assignment below is the assertion-free call site the constraint buys. */
|
|
136
|
+
it("preserves the caller's type for interface-declared forms", () => {
|
|
137
|
+
const typed = reviveSavedCriteria(EMPTY, {
|
|
138
|
+
reference: "X"
|
|
139
|
+
});
|
|
140
|
+
expect(typed.reference).toBe("X");
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
//# sourceMappingURL=reviveSavedCriteria.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reviveSavedCriteria.test.js","names":["reviveSavedCriteria","EMPTY","reference","dateFrom","dateTo","importateur","describe","it","expect","toBe","undefined","saved","JSON","parse","stringify","Date","revived","toBeInstanceOf","toISOString","original","id","description","toEqual","toBeNull","champRetireEnV2","Object","keys","sort","defaults","typed"],"sources":["../../../../src/lib/v2/__tests__/reviveSavedCriteria.test.ts"],"sourcesContent":["import { reviveSavedCriteria } from \"../personalization/capabilities/reviveSavedCriteria\";\r\n\r\n/* ── What this file protects ────────────────────────────────────────────────\r\n *\r\n * The saved-filters round trip is asymmetrical: the local-storage adapter\r\n * writes with `JSON.stringify` (a `Date` becomes an ISO string) and reads with\r\n * a bare `JSON.parse`. Hosts could not see the consequence, because assigning\r\n * the parsed payload into typed form state requires an assertion — which\r\n * silences the very error that would have revealed it.\r\n *\r\n * So the assertions below stand in for a type error the compiler cannot raise\r\n * on the host side. */\r\n\r\n/** Declared with `interface` DELIBERATELY — see the type-level test at the end. */\r\ninterface ListFilters {\r\n reference: string;\r\n dateFrom: Date | null;\r\n dateTo: Date | null;\r\n importateur: { id?: number; description?: string } | null;\r\n}\r\n\r\nconst EMPTY: ListFilters = {\r\n reference: \"\",\r\n dateFrom: null,\r\n dateTo: null,\r\n importateur: null,\r\n};\r\n\r\ndescribe(\"reviveSavedCriteria\", () => {\r\n it(\"returns the defaults when there is no payload\", () => {\r\n expect(reviveSavedCriteria(EMPTY, null)).toBe(EMPTY);\r\n expect(reviveSavedCriteria(EMPTY, undefined)).toBe(EMPTY);\r\n });\r\n\r\n /* THE DEFECT THIS EXISTS FOR. */\r\n it(\"turns an ISO string back into a Date\", () => {\r\n const saved = JSON.parse(\r\n JSON.stringify({ ...EMPTY, dateFrom: new Date(\"2026-03-05T00:00:00Z\") })\r\n ) as Record<string, unknown>;\r\n\r\n // Precondition: the payload really did lose the Date on the way in.\r\n expect(typeof saved[\"dateFrom\"]).toBe(\"string\");\r\n\r\n const revived = reviveSavedCriteria(EMPTY, saved);\r\n\r\n expect(revived.dateFrom).toBeInstanceOf(Date);\r\n expect((revived.dateFrom as Date).toISOString()).toBe(\r\n \"2026-03-05T00:00:00.000Z\"\r\n );\r\n });\r\n\r\n it(\"round-trips a full form through stringify / parse\", () => {\r\n const original: ListFilters = {\r\n reference: \"2026-IM-0042\",\r\n dateFrom: new Date(\"2026-01-01T00:00:00.000Z\"),\r\n dateTo: new Date(\"2026-12-31T23:59:59.000Z\"),\r\n importateur: { id: 7, description: \"SOFRANE SA\" },\r\n };\r\n\r\n const revived = reviveSavedCriteria(\r\n EMPTY,\r\n JSON.parse(JSON.stringify(original)) as Record<string, unknown>\r\n );\r\n\r\n expect(revived).toEqual(original);\r\n });\r\n\r\n /* The regex is strict for this reason: DAAC references, customs codes and\r\n * nomenclatures are date-ish strings that must NOT become dates. */\r\n it(\"leaves business strings alone\", () => {\r\n const revived = reviveSavedCriteria(EMPTY, {\r\n reference: \"2026-IM-0042\",\r\n });\r\n expect(revived.reference).toBe(\"2026-IM-0042\");\r\n });\r\n\r\n it(\"does not revive a bare date without a time part\", () => {\r\n const revived = reviveSavedCriteria(\r\n { ...EMPTY, reference: \"\" },\r\n { reference: \"2026-03-05\" }\r\n );\r\n expect(revived.reference).toBe(\"2026-03-05\");\r\n });\r\n\r\n /* ISO-SHAPED but impossible: the shape passes the regex, the value does not\r\n * exist. `null` is returned rather than an Invalid Date, because an absent\r\n * date is recoverable by the user and a NaN date silently poisons a payload. */\r\n it(\"yields null for an ISO-shaped impossible instant\", () => {\r\n const revived = reviveSavedCriteria(EMPTY, {\r\n dateFrom: \"2026-13-45T00:00:00Z\",\r\n });\r\n expect(revived.dateFrom).toBeNull();\r\n });\r\n\r\n it(\"ignores keys the form no longer declares\", () => {\r\n const revived = reviveSavedCriteria(EMPTY, {\r\n reference: \"X\",\r\n champRetireEnV2: \"valeur héritée\",\r\n });\r\n\r\n expect(revived.reference).toBe(\"X\");\r\n expect(Object.keys(revived).sort()).toEqual(Object.keys(EMPTY).sort());\r\n });\r\n\r\n it(\"keeps the default when a key is absent\", () => {\r\n const revived = reviveSavedCriteria(\r\n { ...EMPTY, reference: \"défaut\" },\r\n { dateFrom: null }\r\n );\r\n expect(revived.reference).toBe(\"défaut\");\r\n });\r\n\r\n /* Under `exactOptionalPropertyTypes` a present key holding `undefined` is\r\n * not an absent key, so it must not win over the default. */\r\n it(\"does not let an explicit undefined overwrite a default\", () => {\r\n const revived = reviveSavedCriteria(\r\n { ...EMPTY, reference: \"défaut\" },\r\n { reference: undefined }\r\n );\r\n expect(revived.reference).toBe(\"défaut\");\r\n });\r\n\r\n it(\"passes referentiel objects through untouched\", () => {\r\n const importateur = { id: 7, description: \"SOFRANE SA\" };\r\n const revived = reviveSavedCriteria(EMPTY, { importateur });\r\n expect(revived.importateur).toEqual(importateur);\r\n });\r\n\r\n it(\"does not mutate the defaults it is given\", () => {\r\n const defaults: ListFilters = { ...EMPTY };\r\n reviveSavedCriteria(defaults, { reference: \"X\" });\r\n expect(defaults.reference).toBe(\"\");\r\n });\r\n\r\n /* TYPE-LEVEL — the reason the constraint is `Record<keyof T, unknown>` and\r\n * not `Record<string, unknown>`. `ListFilters` is an INTERFACE, which has no\r\n * implicit index signature: under the looser constraint this file would not\r\n * compile, and the host would be pushed back into an assertion. The\r\n * assignment below is the assertion-free call site the constraint buys. */\r\n it(\"preserves the caller's type for interface-declared forms\", () => {\r\n const typed: ListFilters = reviveSavedCriteria(EMPTY, { reference: \"X\" });\r\n expect(typed.reference).toBe(\"X\");\r\n });\r\n});\r\n"],"mappings":"AAAA,SAASA,mBAAmB,QAAQ,qDAAqD;;AAEzF;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAQA,MAAMC,KAAkB,GAAG;EACzBC,SAAS,EAAE,EAAE;EACbC,QAAQ,EAAE,IAAI;EACdC,MAAM,EAAE,IAAI;EACZC,WAAW,EAAE;AACf,CAAC;AAEDC,QAAQ,CAAC,qBAAqB,EAAE,MAAM;EACpCC,EAAE,CAAC,+CAA+C,EAAE,MAAM;IACxDC,MAAM,CAACR,mBAAmB,CAACC,KAAK,EAAE,IAAI,CAAC,CAAC,CAACQ,IAAI,CAACR,KAAK,CAAC;IACpDO,MAAM,CAACR,mBAAmB,CAACC,KAAK,EAAES,SAAS,CAAC,CAAC,CAACD,IAAI,CAACR,KAAK,CAAC;EAC3D,CAAC,CAAC;;EAEF;EACAM,EAAE,CAAC,sCAAsC,EAAE,MAAM;IAC/C,MAAMI,KAAK,GAAGC,IAAI,CAACC,KAAK,CACtBD,IAAI,CAACE,SAAS,CAAC;MAAE,GAAGb,KAAK;MAAEE,QAAQ,EAAE,IAAIY,IAAI,CAAC,sBAAsB;IAAE,CAAC,CACzE,CAA4B;;IAE5B;IACAP,MAAM,CAAC,OAAOG,KAAK,CAAC,UAAU,CAAC,CAAC,CAACF,IAAI,CAAC,QAAQ,CAAC;IAE/C,MAAMO,OAAO,GAAGhB,mBAAmB,CAACC,KAAK,EAAEU,KAAK,CAAC;IAEjDH,MAAM,CAACQ,OAAO,CAACb,QAAQ,CAAC,CAACc,cAAc,CAACF,IAAI,CAAC;IAC7CP,MAAM,CAAEQ,OAAO,CAACb,QAAQ,CAAUe,WAAW,CAAC,CAAC,CAAC,CAACT,IAAI,CACnD,0BACF,CAAC;EACH,CAAC,CAAC;EAEFF,EAAE,CAAC,mDAAmD,EAAE,MAAM;IAC5D,MAAMY,QAAqB,GAAG;MAC5BjB,SAAS,EAAE,cAAc;MACzBC,QAAQ,EAAE,IAAIY,IAAI,CAAC,0BAA0B,CAAC;MAC9CX,MAAM,EAAE,IAAIW,IAAI,CAAC,0BAA0B,CAAC;MAC5CV,WAAW,EAAE;QAAEe,EAAE,EAAE,CAAC;QAAEC,WAAW,EAAE;MAAa;IAClD,CAAC;IAED,MAAML,OAAO,GAAGhB,mBAAmB,CACjCC,KAAK,EACLW,IAAI,CAACC,KAAK,CAACD,IAAI,CAACE,SAAS,CAACK,QAAQ,CAAC,CACrC,CAAC;IAEDX,MAAM,CAACQ,OAAO,CAAC,CAACM,OAAO,CAACH,QAAQ,CAAC;EACnC,CAAC,CAAC;;EAEF;AACF;EACEZ,EAAE,CAAC,+BAA+B,EAAE,MAAM;IACxC,MAAMS,OAAO,GAAGhB,mBAAmB,CAACC,KAAK,EAAE;MACzCC,SAAS,EAAE;IACb,CAAC,CAAC;IACFM,MAAM,CAACQ,OAAO,CAACd,SAAS,CAAC,CAACO,IAAI,CAAC,cAAc,CAAC;EAChD,CAAC,CAAC;EAEFF,EAAE,CAAC,iDAAiD,EAAE,MAAM;IAC1D,MAAMS,OAAO,GAAGhB,mBAAmB,CACjC;MAAE,GAAGC,KAAK;MAAEC,SAAS,EAAE;IAAG,CAAC,EAC3B;MAAEA,SAAS,EAAE;IAAa,CAC5B,CAAC;IACDM,MAAM,CAACQ,OAAO,CAACd,SAAS,CAAC,CAACO,IAAI,CAAC,YAAY,CAAC;EAC9C,CAAC,CAAC;;EAEF;AACF;AACA;EACEF,EAAE,CAAC,kDAAkD,EAAE,MAAM;IAC3D,MAAMS,OAAO,GAAGhB,mBAAmB,CAACC,KAAK,EAAE;MACzCE,QAAQ,EAAE;IACZ,CAAC,CAAC;IACFK,MAAM,CAACQ,OAAO,CAACb,QAAQ,CAAC,CAACoB,QAAQ,CAAC,CAAC;EACrC,CAAC,CAAC;EAEFhB,EAAE,CAAC,0CAA0C,EAAE,MAAM;IACnD,MAAMS,OAAO,GAAGhB,mBAAmB,CAACC,KAAK,EAAE;MACzCC,SAAS,EAAE,GAAG;MACdsB,eAAe,EAAE;IACnB,CAAC,CAAC;IAEFhB,MAAM,CAACQ,OAAO,CAACd,SAAS,CAAC,CAACO,IAAI,CAAC,GAAG,CAAC;IACnCD,MAAM,CAACiB,MAAM,CAACC,IAAI,CAACV,OAAO,CAAC,CAACW,IAAI,CAAC,CAAC,CAAC,CAACL,OAAO,CAACG,MAAM,CAACC,IAAI,CAACzB,KAAK,CAAC,CAAC0B,IAAI,CAAC,CAAC,CAAC;EACxE,CAAC,CAAC;EAEFpB,EAAE,CAAC,wCAAwC,EAAE,MAAM;IACjD,MAAMS,OAAO,GAAGhB,mBAAmB,CACjC;MAAE,GAAGC,KAAK;MAAEC,SAAS,EAAE;IAAS,CAAC,EACjC;MAAEC,QAAQ,EAAE;IAAK,CACnB,CAAC;IACDK,MAAM,CAACQ,OAAO,CAACd,SAAS,CAAC,CAACO,IAAI,CAAC,QAAQ,CAAC;EAC1C,CAAC,CAAC;;EAEF;AACF;EACEF,EAAE,CAAC,wDAAwD,EAAE,MAAM;IACjE,MAAMS,OAAO,GAAGhB,mBAAmB,CACjC;MAAE,GAAGC,KAAK;MAAEC,SAAS,EAAE;IAAS,CAAC,EACjC;MAAEA,SAAS,EAAEQ;IAAU,CACzB,CAAC;IACDF,MAAM,CAACQ,OAAO,CAACd,SAAS,CAAC,CAACO,IAAI,CAAC,QAAQ,CAAC;EAC1C,CAAC,CAAC;EAEFF,EAAE,CAAC,8CAA8C,EAAE,MAAM;IACvD,MAAMF,WAAW,GAAG;MAAEe,EAAE,EAAE,CAAC;MAAEC,WAAW,EAAE;IAAa,CAAC;IACxD,MAAML,OAAO,GAAGhB,mBAAmB,CAACC,KAAK,EAAE;MAAEI;IAAY,CAAC,CAAC;IAC3DG,MAAM,CAACQ,OAAO,CAACX,WAAW,CAAC,CAACiB,OAAO,CAACjB,WAAW,CAAC;EAClD,CAAC,CAAC;EAEFE,EAAE,CAAC,0CAA0C,EAAE,MAAM;IACnD,MAAMqB,QAAqB,GAAG;MAAE,GAAG3B;IAAM,CAAC;IAC1CD,mBAAmB,CAAC4B,QAAQ,EAAE;MAAE1B,SAAS,EAAE;IAAI,CAAC,CAAC;IACjDM,MAAM,CAACoB,QAAQ,CAAC1B,SAAS,CAAC,CAACO,IAAI,CAAC,EAAE,CAAC;EACrC,CAAC,CAAC;;EAEF;AACF;AACA;AACA;AACA;EACEF,EAAE,CAAC,0DAA0D,EAAE,MAAM;IACnE,MAAMsB,KAAkB,GAAG7B,mBAAmB,CAACC,KAAK,EAAE;MAAEC,SAAS,EAAE;IAAI,CAAC,CAAC;IACzEM,MAAM,CAACqB,KAAK,CAAC3B,SAAS,CAAC,CAACO,IAAI,CAAC,GAAG,CAAC;EACnC,CAAC,CAAC;AACJ,CAAC,CAAC","ignoreList":[]}
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @jest-environment jsdom
|
|
3
|
+
*/
|
|
4
|
+
import "@testing-library/jest-dom";
|
|
5
|
+
import { render, screen } from "@testing-library/react";
|
|
6
|
+
import userEvent from "@testing-library/user-event";
|
|
7
|
+
import { buildRowActions, buildRowActionMenu, MAX_ROW_ACTIONS } from "../patterns/rowActions";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* rowActions (G-41) — promoted from `refonte-frontend` (Area 5).
|
|
11
|
+
*
|
|
12
|
+
* Each assertion pins a Charter rule the descriptor layer carries, or a defect
|
|
13
|
+
* the promoted implementation had been written to prevent. The per-row
|
|
14
|
+
* evaluation of the predicates is the load-bearing part: a boolean would force
|
|
15
|
+
* the host to rebuild the array per row, which is how a table row and a mobile
|
|
16
|
+
* card end up offering different actions for the same record.
|
|
17
|
+
*/
|
|
18
|
+
import { Fragment as _Fragment, jsx as _jsx } from "react/jsx-runtime";
|
|
19
|
+
const BROUILLON = {
|
|
20
|
+
id: 1,
|
|
21
|
+
status: "DRAFT"
|
|
22
|
+
};
|
|
23
|
+
const SOUMIS = {
|
|
24
|
+
id: 2,
|
|
25
|
+
status: "SOUMIS"
|
|
26
|
+
};
|
|
27
|
+
describe("buildRowActionMenu", () => {
|
|
28
|
+
test("hidden is evaluated PER ROW, not once for the array", () => {
|
|
29
|
+
const descriptors = [{
|
|
30
|
+
id: "open",
|
|
31
|
+
label: "Consulter",
|
|
32
|
+
onClick: jest.fn()
|
|
33
|
+
}, {
|
|
34
|
+
id: "del",
|
|
35
|
+
label: "Supprimer",
|
|
36
|
+
onClick: jest.fn(),
|
|
37
|
+
hidden: row => row.status !== "DRAFT"
|
|
38
|
+
}];
|
|
39
|
+
expect(buildRowActionMenu(descriptors, BROUILLON)).toHaveLength(2);
|
|
40
|
+
expect(buildRowActionMenu(descriptors, SOUMIS)).toHaveLength(1);
|
|
41
|
+
});
|
|
42
|
+
test("disabled is evaluated per row too, and keeps the item visible", () => {
|
|
43
|
+
const items = buildRowActionMenu([{
|
|
44
|
+
id: "edit",
|
|
45
|
+
label: "Modifier",
|
|
46
|
+
onClick: jest.fn(),
|
|
47
|
+
disabled: row => row.status !== "DRAFT"
|
|
48
|
+
}], SOUMIS);
|
|
49
|
+
expect(items).toHaveLength(1);
|
|
50
|
+
expect(items[0]?.disabled).toBe(true);
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
/** R-B.6 — a destructive action is separated and marked, not merely last. */
|
|
54
|
+
test("a divider precedes the first destructive action", () => {
|
|
55
|
+
const items = buildRowActionMenu([{
|
|
56
|
+
id: "open",
|
|
57
|
+
label: "Consulter",
|
|
58
|
+
onClick: jest.fn()
|
|
59
|
+
}, {
|
|
60
|
+
id: "del",
|
|
61
|
+
label: "Supprimer",
|
|
62
|
+
onClick: jest.fn(),
|
|
63
|
+
danger: true
|
|
64
|
+
}, {
|
|
65
|
+
id: "purge",
|
|
66
|
+
label: "Purger",
|
|
67
|
+
onClick: jest.fn(),
|
|
68
|
+
danger: true
|
|
69
|
+
}], BROUILLON);
|
|
70
|
+
expect(items.map(i => Boolean(i.divider))).toEqual([false, true, false, false]);
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* A menu does not open on a rule. The separator only appears if something
|
|
75
|
+
* precedes it — a row whose ONLY action is destructive gets no divider.
|
|
76
|
+
*/
|
|
77
|
+
test("no leading divider when the destructive action comes first", () => {
|
|
78
|
+
const items = buildRowActionMenu([{
|
|
79
|
+
id: "del",
|
|
80
|
+
label: "Supprimer",
|
|
81
|
+
onClick: jest.fn(),
|
|
82
|
+
danger: true
|
|
83
|
+
}], BROUILLON);
|
|
84
|
+
expect(items).toHaveLength(1);
|
|
85
|
+
expect(items[0]?.divider).toBeUndefined();
|
|
86
|
+
});
|
|
87
|
+
test("nothing visible yields an empty list, so a caller can skip the trigger", () => {
|
|
88
|
+
expect(buildRowActionMenu([{
|
|
89
|
+
id: "del",
|
|
90
|
+
label: "Supprimer",
|
|
91
|
+
onClick: jest.fn(),
|
|
92
|
+
hidden: () => true
|
|
93
|
+
}], BROUILLON)).toEqual([]);
|
|
94
|
+
});
|
|
95
|
+
test("onClick is bound to the row it was built for", () => {
|
|
96
|
+
const onClick = jest.fn();
|
|
97
|
+
const items = buildRowActionMenu([{
|
|
98
|
+
id: "open",
|
|
99
|
+
label: "Consulter",
|
|
100
|
+
onClick
|
|
101
|
+
}], SOUMIS);
|
|
102
|
+
items[0]?.onClick?.();
|
|
103
|
+
expect(onClick).toHaveBeenCalledWith(SOUMIS);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* R-3.3 caps what one screen may offer at once, and `OverflowMenu`'s own
|
|
108
|
+
* contract recommends ≤ 7 items. Exceeding it is a host decision, so it warns
|
|
109
|
+
* in development rather than truncating — silently dropping an action would
|
|
110
|
+
* hide a business capability.
|
|
111
|
+
*/
|
|
112
|
+
test(`warns past ${MAX_ROW_ACTIONS} visible actions, without dropping any`, () => {
|
|
113
|
+
const warn = jest.spyOn(console, "warn").mockImplementation(() => undefined);
|
|
114
|
+
const descriptors = Array.from({
|
|
115
|
+
length: MAX_ROW_ACTIONS + 1
|
|
116
|
+
}, (_, i) => ({
|
|
117
|
+
id: `a${i}`,
|
|
118
|
+
label: `Action ${i}`,
|
|
119
|
+
onClick: jest.fn()
|
|
120
|
+
}));
|
|
121
|
+
const items = buildRowActionMenu(descriptors, BROUILLON);
|
|
122
|
+
expect(items).toHaveLength(MAX_ROW_ACTIONS + 1);
|
|
123
|
+
expect(warn).toHaveBeenCalled();
|
|
124
|
+
warn.mockRestore();
|
|
125
|
+
});
|
|
126
|
+
});
|
|
127
|
+
describe("buildRowActions", () => {
|
|
128
|
+
/**
|
|
129
|
+
* R-K.1 — the reason this layer exists. The implementation it replaced
|
|
130
|
+
* revealed its actions on hover, with a `mouseup` listener on `document` and
|
|
131
|
+
* no keyboard equivalent: consulting or deleting a record was unreachable
|
|
132
|
+
* without a mouse. `OverflowMenu` is an ARIA menu, so the trigger is a
|
|
133
|
+
* button and the items are reachable by keyboard.
|
|
134
|
+
*/
|
|
135
|
+
test("renders a keyboard-reachable trigger, named by the caller", async () => {
|
|
136
|
+
const onClick = jest.fn();
|
|
137
|
+
const render$ = buildRowActions([{
|
|
138
|
+
id: "open",
|
|
139
|
+
label: "Consulter le dossier",
|
|
140
|
+
onClick
|
|
141
|
+
}], "Actions sur le dossier");
|
|
142
|
+
render(/*#__PURE__*/_jsx(_Fragment, {
|
|
143
|
+
children: render$(SOUMIS)
|
|
144
|
+
}));
|
|
145
|
+
const trigger = screen.getByRole("button", {
|
|
146
|
+
name: "Actions sur le dossier"
|
|
147
|
+
});
|
|
148
|
+
await userEvent.click(trigger);
|
|
149
|
+
await userEvent.click(screen.getByRole("menuitem", {
|
|
150
|
+
name: "Consulter le dossier"
|
|
151
|
+
}));
|
|
152
|
+
expect(onClick).toHaveBeenCalledWith(SOUMIS);
|
|
153
|
+
});
|
|
154
|
+
test("renders nothing when no action applies to the row", () => {
|
|
155
|
+
const render$ = buildRowActions([{
|
|
156
|
+
id: "del",
|
|
157
|
+
label: "Supprimer",
|
|
158
|
+
onClick: jest.fn(),
|
|
159
|
+
hidden: () => true
|
|
160
|
+
}]);
|
|
161
|
+
const {
|
|
162
|
+
container
|
|
163
|
+
} = render(/*#__PURE__*/_jsx(_Fragment, {
|
|
164
|
+
children: render$(BROUILLON)
|
|
165
|
+
}));
|
|
166
|
+
expect(container).toBeEmptyDOMElement();
|
|
167
|
+
});
|
|
168
|
+
test("the default trigger name is generic, so hosts localise it per resource", () => {
|
|
169
|
+
const render$ = buildRowActions([{
|
|
170
|
+
id: "open",
|
|
171
|
+
label: "Consulter",
|
|
172
|
+
onClick: jest.fn()
|
|
173
|
+
}]);
|
|
174
|
+
render(/*#__PURE__*/_jsx(_Fragment, {
|
|
175
|
+
children: render$(SOUMIS)
|
|
176
|
+
}));
|
|
177
|
+
expect(screen.getByRole("button", {
|
|
178
|
+
name: "Actions"
|
|
179
|
+
})).toBeInTheDocument();
|
|
180
|
+
});
|
|
181
|
+
});
|
|
182
|
+
//# sourceMappingURL=rowActions.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"rowActions.test.js","names":["render","screen","userEvent","buildRowActions","buildRowActionMenu","MAX_ROW_ACTIONS","Fragment","_Fragment","jsx","_jsx","BROUILLON","id","status","SOUMIS","describe","test","descriptors","label","onClick","jest","fn","hidden","row","expect","toHaveLength","items","disabled","toBe","danger","map","i","Boolean","divider","toEqual","toBeUndefined","toHaveBeenCalledWith","warn","spyOn","console","mockImplementation","undefined","Array","from","length","_","toHaveBeenCalled","mockRestore","render$","children","trigger","getByRole","name","click","container","toBeEmptyDOMElement","toBeInTheDocument"],"sources":["../../../../src/lib/v2/__tests__/rowActions.test.tsx"],"sourcesContent":["/**\r\n * @jest-environment jsdom\r\n */\r\nimport \"@testing-library/jest-dom\";\r\nimport { render, screen } from \"@testing-library/react\";\r\nimport userEvent from \"@testing-library/user-event\";\r\nimport {\r\n buildRowActions,\r\n buildRowActionMenu,\r\n MAX_ROW_ACTIONS,\r\n} from \"../patterns/rowActions\";\r\nimport type { RowActionDescriptor } from \"../patterns/rowActions\";\r\n\r\n/**\r\n * rowActions (G-41) — promoted from `refonte-frontend` (Area 5).\r\n *\r\n * Each assertion pins a Charter rule the descriptor layer carries, or a defect\r\n * the promoted implementation had been written to prevent. The per-row\r\n * evaluation of the predicates is the load-bearing part: a boolean would force\r\n * the host to rebuild the array per row, which is how a table row and a mobile\r\n * card end up offering different actions for the same record.\r\n */\r\n\r\ninterface Dossier {\r\n id: number;\r\n status: string;\r\n}\r\n\r\nconst BROUILLON: Dossier = { id: 1, status: \"DRAFT\" };\r\nconst SOUMIS: Dossier = { id: 2, status: \"SOUMIS\" };\r\n\r\ndescribe(\"buildRowActionMenu\", () => {\r\n test(\"hidden is evaluated PER ROW, not once for the array\", () => {\r\n const descriptors: RowActionDescriptor<Dossier>[] = [\r\n { id: \"open\", label: \"Consulter\", onClick: jest.fn() },\r\n {\r\n id: \"del\",\r\n label: \"Supprimer\",\r\n onClick: jest.fn(),\r\n hidden: (row) => row.status !== \"DRAFT\",\r\n },\r\n ];\r\n\r\n expect(buildRowActionMenu(descriptors, BROUILLON)).toHaveLength(2);\r\n expect(buildRowActionMenu(descriptors, SOUMIS)).toHaveLength(1);\r\n });\r\n\r\n test(\"disabled is evaluated per row too, and keeps the item visible\", () => {\r\n const items = buildRowActionMenu<Dossier>(\r\n [\r\n {\r\n id: \"edit\",\r\n label: \"Modifier\",\r\n onClick: jest.fn(),\r\n disabled: (row) => row.status !== \"DRAFT\",\r\n },\r\n ],\r\n SOUMIS\r\n );\r\n expect(items).toHaveLength(1);\r\n expect(items[0]?.disabled).toBe(true);\r\n });\r\n\r\n /** R-B.6 — a destructive action is separated and marked, not merely last. */\r\n test(\"a divider precedes the first destructive action\", () => {\r\n const items = buildRowActionMenu<Dossier>(\r\n [\r\n { id: \"open\", label: \"Consulter\", onClick: jest.fn() },\r\n { id: \"del\", label: \"Supprimer\", onClick: jest.fn(), danger: true },\r\n { id: \"purge\", label: \"Purger\", onClick: jest.fn(), danger: true },\r\n ],\r\n BROUILLON\r\n );\r\n expect(items.map((i) => Boolean(i.divider))).toEqual([false, true, false, false]);\r\n });\r\n\r\n /**\r\n * A menu does not open on a rule. The separator only appears if something\r\n * precedes it — a row whose ONLY action is destructive gets no divider.\r\n */\r\n test(\"no leading divider when the destructive action comes first\", () => {\r\n const items = buildRowActionMenu<Dossier>(\r\n [{ id: \"del\", label: \"Supprimer\", onClick: jest.fn(), danger: true }],\r\n BROUILLON\r\n );\r\n expect(items).toHaveLength(1);\r\n expect(items[0]?.divider).toBeUndefined();\r\n });\r\n\r\n test(\"nothing visible yields an empty list, so a caller can skip the trigger\", () => {\r\n expect(\r\n buildRowActionMenu<Dossier>(\r\n [{ id: \"del\", label: \"Supprimer\", onClick: jest.fn(), hidden: () => true }],\r\n BROUILLON\r\n )\r\n ).toEqual([]);\r\n });\r\n\r\n test(\"onClick is bound to the row it was built for\", () => {\r\n const onClick = jest.fn();\r\n const items = buildRowActionMenu<Dossier>(\r\n [{ id: \"open\", label: \"Consulter\", onClick }],\r\n SOUMIS\r\n );\r\n items[0]?.onClick?.();\r\n expect(onClick).toHaveBeenCalledWith(SOUMIS);\r\n });\r\n\r\n /**\r\n * R-3.3 caps what one screen may offer at once, and `OverflowMenu`'s own\r\n * contract recommends ≤ 7 items. Exceeding it is a host decision, so it warns\r\n * in development rather than truncating — silently dropping an action would\r\n * hide a business capability.\r\n */\r\n test(`warns past ${MAX_ROW_ACTIONS} visible actions, without dropping any`, () => {\r\n const warn = jest.spyOn(console, \"warn\").mockImplementation(() => undefined);\r\n const descriptors: RowActionDescriptor<Dossier>[] = Array.from(\r\n { length: MAX_ROW_ACTIONS + 1 },\r\n (_, i) => ({ id: `a${i}`, label: `Action ${i}`, onClick: jest.fn() })\r\n );\r\n\r\n const items = buildRowActionMenu(descriptors, BROUILLON);\r\n\r\n expect(items).toHaveLength(MAX_ROW_ACTIONS + 1);\r\n expect(warn).toHaveBeenCalled();\r\n warn.mockRestore();\r\n });\r\n});\r\n\r\ndescribe(\"buildRowActions\", () => {\r\n /**\r\n * R-K.1 — the reason this layer exists. The implementation it replaced\r\n * revealed its actions on hover, with a `mouseup` listener on `document` and\r\n * no keyboard equivalent: consulting or deleting a record was unreachable\r\n * without a mouse. `OverflowMenu` is an ARIA menu, so the trigger is a\r\n * button and the items are reachable by keyboard.\r\n */\r\n test(\"renders a keyboard-reachable trigger, named by the caller\", async () => {\r\n const onClick = jest.fn();\r\n const render$ = buildRowActions<Dossier>(\r\n [{ id: \"open\", label: \"Consulter le dossier\", onClick }],\r\n \"Actions sur le dossier\"\r\n );\r\n\r\n render(<>{render$(SOUMIS)}</>);\r\n\r\n const trigger = screen.getByRole(\"button\", { name: \"Actions sur le dossier\" });\r\n await userEvent.click(trigger);\r\n await userEvent.click(\r\n screen.getByRole(\"menuitem\", { name: \"Consulter le dossier\" })\r\n );\r\n\r\n expect(onClick).toHaveBeenCalledWith(SOUMIS);\r\n });\r\n\r\n test(\"renders nothing when no action applies to the row\", () => {\r\n const render$ = buildRowActions<Dossier>([\r\n { id: \"del\", label: \"Supprimer\", onClick: jest.fn(), hidden: () => true },\r\n ]);\r\n const { container } = render(<>{render$(BROUILLON)}</>);\r\n expect(container).toBeEmptyDOMElement();\r\n });\r\n\r\n test(\"the default trigger name is generic, so hosts localise it per resource\", () => {\r\n const render$ = buildRowActions<Dossier>([\r\n { id: \"open\", label: \"Consulter\", onClick: jest.fn() },\r\n ]);\r\n render(<>{render$(SOUMIS)}</>);\r\n expect(screen.getByRole(\"button\", { name: \"Actions\" })).toBeInTheDocument();\r\n });\r\n});\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import "@testing-library/jest-dom";
|
|
2
|
+
import { render, screen } from "@testing-library/react";
|
|
3
|
+
import AppMain from "../patterns/AppMain";
|
|
4
|
+
import useFocusOnRouteChange from "../hooks/useFocusOnRouteChange";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* G-60 — focus on page change.
|
|
8
|
+
*
|
|
9
|
+
* What this guards is invisible by construction: after a route change in a
|
|
10
|
+
* single-page application the pixels are perfect and the focus is on
|
|
11
|
+
* `document.body`, so the next Tab starts at the top of the BROWSER rather than
|
|
12
|
+
* the page. Only an assertion catches it.
|
|
13
|
+
*
|
|
14
|
+
* The harness mirrors the real arrangement — the hook is called by a component
|
|
15
|
+
* INSIDE the landmark it targets, because that is where a router puts it — and
|
|
16
|
+
* drives the key by prop rather than importing a router: the hook is
|
|
17
|
+
* router-agnostic and its tests should be too.
|
|
18
|
+
*/
|
|
19
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
20
|
+
function Page({
|
|
21
|
+
routeKey
|
|
22
|
+
}) {
|
|
23
|
+
useFocusOnRouteChange(routeKey);
|
|
24
|
+
return /*#__PURE__*/_jsx("button", {
|
|
25
|
+
type: "button",
|
|
26
|
+
children: "Action de la page"
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
function Harness({
|
|
30
|
+
routeKey
|
|
31
|
+
}) {
|
|
32
|
+
return /*#__PURE__*/_jsx(AppMain, {
|
|
33
|
+
children: /*#__PURE__*/_jsx(Page, {
|
|
34
|
+
routeKey: routeKey
|
|
35
|
+
})
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
describe("useFocusOnRouteChange", () => {
|
|
39
|
+
/* The browser already places focus at the start of the document on load.
|
|
40
|
+
* Moving it then would fight the browser and scroll a deep-linked page away
|
|
41
|
+
* from its anchor. */
|
|
42
|
+
it("leaves focus alone on the first render", () => {
|
|
43
|
+
render(/*#__PURE__*/_jsx(Harness, {
|
|
44
|
+
routeKey: "/demandes"
|
|
45
|
+
}));
|
|
46
|
+
expect(screen.getByRole("main")).not.toHaveFocus();
|
|
47
|
+
});
|
|
48
|
+
it("moves focus to the landmark when the key changes", () => {
|
|
49
|
+
const {
|
|
50
|
+
rerender
|
|
51
|
+
} = render(/*#__PURE__*/_jsx(Harness, {
|
|
52
|
+
routeKey: "/demandes"
|
|
53
|
+
}));
|
|
54
|
+
|
|
55
|
+
/* Focus somewhere inside the old page, as a user would have it after
|
|
56
|
+
clicking the action that navigates. */
|
|
57
|
+
screen.getByRole("button").focus();
|
|
58
|
+
expect(screen.getByRole("button")).toHaveFocus();
|
|
59
|
+
rerender(/*#__PURE__*/_jsx(Harness, {
|
|
60
|
+
routeKey: "/demandes/42"
|
|
61
|
+
}));
|
|
62
|
+
expect(screen.getByRole("main")).toHaveFocus();
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
/* A re-render with the SAME key must not steal focus — a listing re-renders
|
|
66
|
+
* on every keystroke of its search field, and the host is told to watch the
|
|
67
|
+
* pathname precisely so that state changes are not page changes. */
|
|
68
|
+
it("does not move focus when the key is unchanged", () => {
|
|
69
|
+
const {
|
|
70
|
+
rerender
|
|
71
|
+
} = render(/*#__PURE__*/_jsx(Harness, {
|
|
72
|
+
routeKey: "/demandes"
|
|
73
|
+
}));
|
|
74
|
+
screen.getByRole("button").focus();
|
|
75
|
+
rerender(/*#__PURE__*/_jsx(Harness, {
|
|
76
|
+
routeKey: "/demandes"
|
|
77
|
+
}));
|
|
78
|
+
expect(screen.getByRole("button")).toHaveFocus();
|
|
79
|
+
});
|
|
80
|
+
it("honours a custom target id", () => {
|
|
81
|
+
function CustomPage({
|
|
82
|
+
routeKey
|
|
83
|
+
}) {
|
|
84
|
+
useFocusOnRouteChange(routeKey, {
|
|
85
|
+
targetId: "zone-principale"
|
|
86
|
+
});
|
|
87
|
+
return null;
|
|
88
|
+
}
|
|
89
|
+
const {
|
|
90
|
+
rerender
|
|
91
|
+
} = render(/*#__PURE__*/_jsx(AppMain, {
|
|
92
|
+
id: "zone-principale",
|
|
93
|
+
children: /*#__PURE__*/_jsx(CustomPage, {
|
|
94
|
+
routeKey: "/a"
|
|
95
|
+
})
|
|
96
|
+
}));
|
|
97
|
+
rerender(/*#__PURE__*/_jsx(AppMain, {
|
|
98
|
+
id: "zone-principale",
|
|
99
|
+
children: /*#__PURE__*/_jsx(CustomPage, {
|
|
100
|
+
routeKey: "/b"
|
|
101
|
+
})
|
|
102
|
+
}));
|
|
103
|
+
expect(screen.getByRole("main")).toHaveFocus();
|
|
104
|
+
});
|
|
105
|
+
it("can be suspended", () => {
|
|
106
|
+
function DisabledPage({
|
|
107
|
+
routeKey
|
|
108
|
+
}) {
|
|
109
|
+
useFocusOnRouteChange(routeKey, {
|
|
110
|
+
enabled: false
|
|
111
|
+
});
|
|
112
|
+
return /*#__PURE__*/_jsx("button", {
|
|
113
|
+
type: "button",
|
|
114
|
+
children: "Action"
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
const {
|
|
118
|
+
rerender
|
|
119
|
+
} = render(/*#__PURE__*/_jsx(AppMain, {
|
|
120
|
+
children: /*#__PURE__*/_jsx(DisabledPage, {
|
|
121
|
+
routeKey: "/a"
|
|
122
|
+
})
|
|
123
|
+
}));
|
|
124
|
+
screen.getByRole("button").focus();
|
|
125
|
+
rerender(/*#__PURE__*/_jsx(AppMain, {
|
|
126
|
+
children: /*#__PURE__*/_jsx(DisabledPage, {
|
|
127
|
+
routeKey: "/b"
|
|
128
|
+
})
|
|
129
|
+
}));
|
|
130
|
+
expect(screen.getByRole("button")).toHaveFocus();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
/* A host may render the hook on a shell that mounts before its landmark —
|
|
134
|
+
* a pre-auth screen, an error boundary. Throwing there would replace a
|
|
135
|
+
* missing focus move with a crash. */
|
|
136
|
+
it("does nothing when the target is absent", () => {
|
|
137
|
+
function Orphan({
|
|
138
|
+
routeKey
|
|
139
|
+
}) {
|
|
140
|
+
useFocusOnRouteChange(routeKey);
|
|
141
|
+
return /*#__PURE__*/_jsx("span", {
|
|
142
|
+
children: "sans landmark"
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
const {
|
|
146
|
+
rerender
|
|
147
|
+
} = render(/*#__PURE__*/_jsx(Orphan, {
|
|
148
|
+
routeKey: "/a"
|
|
149
|
+
}));
|
|
150
|
+
expect(() => rerender(/*#__PURE__*/_jsx(Orphan, {
|
|
151
|
+
routeKey: "/b"
|
|
152
|
+
}))).not.toThrow();
|
|
153
|
+
});
|
|
154
|
+
});
|
|
155
|
+
//# sourceMappingURL=useFocusOnRouteChange.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useFocusOnRouteChange.test.js","names":["render","screen","AppMain","useFocusOnRouteChange","jsx","_jsx","Page","routeKey","type","children","Harness","describe","it","expect","getByRole","not","toHaveFocus","rerender","focus","CustomPage","targetId","id","DisabledPage","enabled","Orphan","toThrow"],"sources":["../../../../src/lib/v2/__tests__/useFocusOnRouteChange.test.tsx"],"sourcesContent":["import \"@testing-library/jest-dom\";\r\nimport { render, screen } from \"@testing-library/react\";\r\n\r\nimport AppMain from \"../patterns/AppMain\";\r\nimport useFocusOnRouteChange from \"../hooks/useFocusOnRouteChange\";\r\n\r\n/**\r\n * G-60 — focus on page change.\r\n *\r\n * What this guards is invisible by construction: after a route change in a\r\n * single-page application the pixels are perfect and the focus is on\r\n * `document.body`, so the next Tab starts at the top of the BROWSER rather than\r\n * the page. Only an assertion catches it.\r\n *\r\n * The harness mirrors the real arrangement — the hook is called by a component\r\n * INSIDE the landmark it targets, because that is where a router puts it — and\r\n * drives the key by prop rather than importing a router: the hook is\r\n * router-agnostic and its tests should be too.\r\n */\r\n\r\nfunction Page({ routeKey }: { routeKey: string }) {\r\n useFocusOnRouteChange(routeKey);\r\n return <button type=\"button\">Action de la page</button>;\r\n}\r\n\r\nfunction Harness({ routeKey }: { routeKey: string }) {\r\n return (\r\n <AppMain>\r\n <Page routeKey={routeKey} />\r\n </AppMain>\r\n );\r\n}\r\n\r\ndescribe(\"useFocusOnRouteChange\", () => {\r\n /* The browser already places focus at the start of the document on load.\r\n * Moving it then would fight the browser and scroll a deep-linked page away\r\n * from its anchor. */\r\n it(\"leaves focus alone on the first render\", () => {\r\n render(<Harness routeKey=\"/demandes\" />);\r\n expect(screen.getByRole(\"main\")).not.toHaveFocus();\r\n });\r\n\r\n it(\"moves focus to the landmark when the key changes\", () => {\r\n const { rerender } = render(<Harness routeKey=\"/demandes\" />);\r\n\r\n /* Focus somewhere inside the old page, as a user would have it after\r\n clicking the action that navigates. */\r\n screen.getByRole(\"button\").focus();\r\n expect(screen.getByRole(\"button\")).toHaveFocus();\r\n\r\n rerender(<Harness routeKey=\"/demandes/42\" />);\r\n\r\n expect(screen.getByRole(\"main\")).toHaveFocus();\r\n });\r\n\r\n /* A re-render with the SAME key must not steal focus — a listing re-renders\r\n * on every keystroke of its search field, and the host is told to watch the\r\n * pathname precisely so that state changes are not page changes. */\r\n it(\"does not move focus when the key is unchanged\", () => {\r\n const { rerender } = render(<Harness routeKey=\"/demandes\" />);\r\n\r\n screen.getByRole(\"button\").focus();\r\n rerender(<Harness routeKey=\"/demandes\" />);\r\n\r\n expect(screen.getByRole(\"button\")).toHaveFocus();\r\n });\r\n\r\n it(\"honours a custom target id\", () => {\r\n function CustomPage({ routeKey }: { routeKey: string }) {\r\n useFocusOnRouteChange(routeKey, { targetId: \"zone-principale\" });\r\n return null;\r\n }\r\n\r\n const { rerender } = render(\r\n <AppMain id=\"zone-principale\">\r\n <CustomPage routeKey=\"/a\" />\r\n </AppMain>\r\n );\r\n rerender(\r\n <AppMain id=\"zone-principale\">\r\n <CustomPage routeKey=\"/b\" />\r\n </AppMain>\r\n );\r\n\r\n expect(screen.getByRole(\"main\")).toHaveFocus();\r\n });\r\n\r\n it(\"can be suspended\", () => {\r\n function DisabledPage({ routeKey }: { routeKey: string }) {\r\n useFocusOnRouteChange(routeKey, { enabled: false });\r\n return <button type=\"button\">Action</button>;\r\n }\r\n\r\n const { rerender } = render(\r\n <AppMain>\r\n <DisabledPage routeKey=\"/a\" />\r\n </AppMain>\r\n );\r\n screen.getByRole(\"button\").focus();\r\n rerender(\r\n <AppMain>\r\n <DisabledPage routeKey=\"/b\" />\r\n </AppMain>\r\n );\r\n\r\n expect(screen.getByRole(\"button\")).toHaveFocus();\r\n });\r\n\r\n /* A host may render the hook on a shell that mounts before its landmark —\r\n * a pre-auth screen, an error boundary. Throwing there would replace a\r\n * missing focus move with a crash. */\r\n it(\"does nothing when the target is absent\", () => {\r\n function Orphan({ routeKey }: { routeKey: string }) {\r\n useFocusOnRouteChange(routeKey);\r\n return <span>sans landmark</span>;\r\n }\r\n\r\n const { rerender } = render(<Orphan routeKey=\"/a\" />);\r\n expect(() => rerender(<Orphan routeKey=\"/b\" />)).not.toThrow();\r\n });\r\n});\r\n"],"mappings":"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","ignoreList":[]}
|