@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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cssVariables.test.js","names":["_cssVariables","require","describe","css","beforeAll","getCssVariables","test","expect","toMatch","matches","match","toBeNull","not","required","_i","_required","length","v","toContain","concat","_i2","_required2","_i3","_required3","_i4","_arr","i","aliases","_i5","_aliases","a","polluters","_i6","_polluters","re","_i7","_required4","customCss","brand","accent"],"sources":["../../../src/lib/v2/__tests__/cssVariables.test.ts"],"sourcesContent":["import { getCssVariables } from \"../theme/cssVariables\";\r\n\r\n/**\r\n * Regression coverage for the v2 CSS variable emission.\r\n *\r\n * These invariants are established by Batch 1 (token refactor) and\r\n * Batch 2 (cssVariables refactor). A failure here means a future\r\n * change has either:\r\n * - re-introduced a deleted token (e.g. --fw-black),\r\n * - emitted an undefined value (the silent bug class that broke\r\n * KPICard and FormSection visually before Batch 6+7 caught it),\r\n * - dropped a critical variable downstream consumers rely on, or\r\n * - leaked an alias name (--md / --lg) into the global namespace.\r\n */\r\ndescribe(\"getCssVariables() — Batch 1 + 2 invariants\", () => {\r\n let css: string;\r\n beforeAll(() => {\r\n css = getCssVariables();\r\n });\r\n\r\n test(\"emits a :root block\", () => {\r\n expect(css).toMatch(/:root\\s*\\{/);\r\n });\r\n\r\n test(\"never emits ': undefined' values (the ghost-token bug class)\", () => {\r\n // Match `--anything: undefined;` with optional whitespace.\r\n // This catches the regression that produced --fw-black resolving\r\n // to undefined in :root after Batch 1 removed fontWeight.black.\r\n const matches = css.match(/--[\\w-]+\\s*:\\s*undefined\\b/g);\r\n expect(matches).toBeNull();\r\n });\r\n\r\n test(\"does NOT emit --fw-black (Batch 1 removed fontWeight.black)\", () => {\r\n expect(css).not.toMatch(/--fw-black/);\r\n });\r\n\r\n test(\"emits all critical brand + ink + surface variables\", () => {\r\n const required = [\r\n \"--accent\", \"--accent-soft\", \"--accent-hover\", \"--accent-fg\",\r\n \"--fg\", \"--fg-muted\", \"--fg-subtle\", \"--fg-inverse\",\r\n \"--bg\", \"--bg-elev\", \"--bg-subtle\", \"--bg-hover\", \"--surface\",\r\n \"--border\", \"--border-strong\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits all semantic + status palette variables\", () => {\r\n const required = [\r\n \"--success\", \"--success-fg\", \"--success-soft\",\r\n \"--danger\", \"--danger-fg\", \"--danger-soft\",\r\n \"--warning\", \"--warning-fg\", \"--warning-soft\",\r\n \"--info\", \"--info-fg\", \"--info-soft\",\r\n \"--status-new-soft\", \"--status-new-fg\",\r\n \"--status-sent-soft\", \"--status-sent-fg\",\r\n \"--status-pending-soft\", \"--status-pending-fg\",\r\n \"--status-approved-soft\", \"--status-approved-fg\",\r\n \"--status-rejected-soft\", \"--status-rejected-fg\",\r\n \"--status-neutral-soft\", \"--status-neutral-fg\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits the typography variables\", () => {\r\n const required = [\r\n \"--font-sans\", \"--font-mono\",\r\n \"--text-display\", \"--text-h2\", \"--text-h3\", \"--text-h4\",\r\n \"--text-body\", \"--text-sm\", \"--text-xs\",\r\n \"--fw-regular\", \"--fw-medium\", \"--fw-semibold\", \"--fw-bold\",\r\n \"--lh-tight\", \"--lh-snug\", \"--lh-normal\", \"--lh-loose\",\r\n // A7-02 — letter-spacing scale.\r\n \"--ls-tight\", \"--ls-normal\", \"--ls-wide\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n /**\r\n * A7-02 regression guard — the PHANTOM TOKEN class.\r\n *\r\n * The ms-dfd-fe Area 7 audit found six token names referenced across two\r\n * certified modules that this emitter never emitted: --ls-tight, --ls-wide,\r\n * --border-subtle, --r-xs, --icon-sm, --icon-xl. Because every consumer wrote\r\n * `var(--x, <literal>)`, the literal was the ONLY thing that ever rendered —\r\n * a hard-coded magic value wearing a token's name, invisible to review and\r\n * undetectable by tsc (R-2.3 / R-AI.1).\r\n *\r\n * The two letter-spacing names had a real platform basis and are now emitted\r\n * (asserted above). The other four were local inventions with no basis in the\r\n * Charter's token tables; asserting their ABSENCE here stops someone\r\n * \"resolving\" a phantom reference by inventing the token instead of fixing the\r\n * call site. Adding any of them is a Charter §02 amendment and must arrive\r\n * with its table entry, not via a failing consumer.\r\n */\r\n test(\"does NOT emit the four rejected phantom tokens (A7-02)\", () => {\r\n for (const v of [\"--border-subtle\", \"--r-xs\", \"--icon-sm\", \"--icon-xl\"]) {\r\n expect(css).not.toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits the spacing grid (--s-1 through --s-10)\", () => {\r\n for (let i = 1; i <= 10; i += 1) {\r\n expect(css).toContain(`--s-${i}:`);\r\n }\r\n });\r\n\r\n test(\"emits the spacing aliases under --space-* prefix\", () => {\r\n const aliases = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"xxl\"];\r\n for (const a of aliases) {\r\n expect(css).toContain(`--space-${a}:`);\r\n }\r\n });\r\n\r\n test(\"does NOT emit unprefixed alias names that would pollute the global CSS namespace\", () => {\r\n // Bare --md / --lg / --xl would collide with consumer stylesheets.\r\n // Batch 2 explicitly partitioned spacing into numeric grid (--s-N)\r\n // and semantic aliases (--space-X) to prevent this.\r\n // Use word boundaries so we don't false-match --r-md, --space-md, etc.\r\n const polluters = [\r\n /[^\\w-]--xs\\s*:/,\r\n /[^\\w-]--sm\\s*:/,\r\n /[^\\w-]--md\\s*:/,\r\n /[^\\w-]--lg\\s*:/,\r\n /[^\\w-]--xl\\s*:/,\r\n /[^\\w-]--xxl\\s*:/,\r\n ];\r\n for (const re of polluters) {\r\n expect(css).not.toMatch(re);\r\n }\r\n });\r\n\r\n test(\"emits radius, shadow, motion, easing, layout, density\", () => {\r\n const required = [\r\n \"--r-sm\", \"--r-md\", \"--r-lg\", \"--r-xl\", \"--r-full\", \"--r-none\",\r\n \"--shadow-xs\", \"--shadow-sm\", \"--shadow-md\", \"--shadow-lg\", \"--shadow-focus\",\r\n \"--duration-fast\", \"--duration-base\", \"--duration-slow\",\r\n \"--easing-out\", \"--easing-in\", \"--easing-soft\",\r\n \"--sidebar-w\", \"--topbar-h\", \"--content-max\", \"--form-max\", \"--tactile-min\",\r\n \"--row-h\", \"--input-h\", \"--btn-h\", \"--text-fs\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits z-index variables\", () => {\r\n // Iterates the full zIndex object in cssVariables, so any\r\n // future zIndex slot (popover, snackbar, tooltip from Batch 1)\r\n // surfaces here without code change.\r\n expect(css).toMatch(/--z-modal\\s*:/);\r\n expect(css).toMatch(/--z-sticky\\s*:/);\r\n });\r\n\r\n test(\"emits the dark-mode override block with derived soft variants\", () => {\r\n expect(css).toContain('[data-theme=\"dark\"]');\r\n // Soft semantic fills are color-mix-derived in dark, not static hex\r\n // (Batch 2 contrast fix for WCAG 1.4.11 non-text on dark surfaces).\r\n expect(css).toMatch(/--success-soft:\\s*color-mix/);\r\n expect(css).toMatch(/--danger-soft:\\s*color-mix/);\r\n expect(css).toMatch(/--warning-soft:\\s*color-mix/);\r\n expect(css).toMatch(/--info-soft:\\s*color-mix/);\r\n });\r\n\r\n test(\"emits the compact density override block\", () => {\r\n expect(css).toContain('[data-density=\"compact\"]');\r\n // Compact override shrinks the row/input/btn heights.\r\n expect(css).toMatch(/\\[data-density=\"compact\"\\][\\s\\S]*--btn-h:/);\r\n });\r\n\r\n test(\"emits the collapsed-sidebar override\", () => {\r\n expect(css).toContain('[data-nav-collapsed=\"true\"]');\r\n });\r\n\r\n test(\"brand override propagates through resolveBrand\", () => {\r\n const customCss = getCssVariables({ brand: { accent: \"#FF0000\" } });\r\n expect(customCss).toContain(\"--accent: #FF0000;\");\r\n // Default also still emits its accent\r\n expect(css).toMatch(/--accent:\\s*#[0-9a-fA-F]{3,8}/);\r\n });\r\n\r\n test(\"brand override does NOT pollute other brand fields when omitted\", () => {\r\n // Partial brand override — accentSoft should fall back to default,\r\n // not to undefined or an empty string.\r\n const customCss = getCssVariables({ brand: { accent: \"#FF0000\" } });\r\n expect(customCss).not.toMatch(/--accent-soft:\\s*undefined/);\r\n expect(customCss).not.toMatch(/--accent-soft:\\s*;/);\r\n expect(customCss).toMatch(/--accent-soft:\\s*\\S+/);\r\n });\r\n});\r\n"],"mappings":"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","ignoreList":[]}
|
|
1
|
+
{"version":3,"file":"cssVariables.test.js","names":["_cssVariables","require","describe","css","beforeAll","getCssVariables","test","expect","toMatch","matches","match","toBeNull","not","required","v","toContain","i","aliases","a","polluters","re","customCss","brand","accent"],"sources":["../../../src/lib/v2/__tests__/cssVariables.test.ts"],"sourcesContent":["import { getCssVariables } from \"../theme/cssVariables\";\r\n\r\n/**\r\n * Regression coverage for the v2 CSS variable emission.\r\n *\r\n * These invariants are established by Batch 1 (token refactor) and\r\n * Batch 2 (cssVariables refactor). A failure here means a future\r\n * change has either:\r\n * - re-introduced a deleted token (e.g. --fw-black),\r\n * - emitted an undefined value (the silent bug class that broke\r\n * KPICard and FormSection visually before Batch 6+7 caught it),\r\n * - dropped a critical variable downstream consumers rely on, or\r\n * - leaked an alias name (--md / --lg) into the global namespace.\r\n */\r\ndescribe(\"getCssVariables() — Batch 1 + 2 invariants\", () => {\r\n let css: string;\r\n beforeAll(() => {\r\n css = getCssVariables();\r\n });\r\n\r\n test(\"emits a :root block\", () => {\r\n expect(css).toMatch(/:root\\s*\\{/);\r\n });\r\n\r\n test(\"never emits ': undefined' values (the ghost-token bug class)\", () => {\r\n // Match `--anything: undefined;` with optional whitespace.\r\n // This catches the regression that produced --fw-black resolving\r\n // to undefined in :root after Batch 1 removed fontWeight.black.\r\n const matches = css.match(/--[\\w-]+\\s*:\\s*undefined\\b/g);\r\n expect(matches).toBeNull();\r\n });\r\n\r\n test(\"does NOT emit --fw-black (Batch 1 removed fontWeight.black)\", () => {\r\n expect(css).not.toMatch(/--fw-black/);\r\n });\r\n\r\n test(\"emits all critical brand + ink + surface variables\", () => {\r\n const required = [\r\n \"--accent\", \"--accent-soft\", \"--accent-hover\", \"--accent-fg\",\r\n \"--fg\", \"--fg-muted\", \"--fg-subtle\", \"--fg-inverse\",\r\n \"--bg\", \"--bg-elev\", \"--bg-subtle\", \"--bg-hover\", \"--surface\",\r\n \"--border\", \"--border-strong\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits all semantic + status palette variables\", () => {\r\n const required = [\r\n \"--success\", \"--success-fg\", \"--success-soft\",\r\n \"--danger\", \"--danger-fg\", \"--danger-soft\",\r\n \"--warning\", \"--warning-fg\", \"--warning-soft\",\r\n \"--info\", \"--info-fg\", \"--info-soft\",\r\n \"--status-new-soft\", \"--status-new-fg\",\r\n \"--status-sent-soft\", \"--status-sent-fg\",\r\n \"--status-pending-soft\", \"--status-pending-fg\",\r\n \"--status-approved-soft\", \"--status-approved-fg\",\r\n \"--status-rejected-soft\", \"--status-rejected-fg\",\r\n \"--status-neutral-soft\", \"--status-neutral-fg\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits the typography variables\", () => {\r\n const required = [\r\n \"--font-sans\", \"--font-mono\",\r\n \"--text-display\", \"--text-h2\", \"--text-h3\", \"--text-h4\",\r\n \"--text-body\", \"--text-sm\", \"--text-xs\",\r\n \"--fw-regular\", \"--fw-medium\", \"--fw-semibold\", \"--fw-bold\",\r\n \"--lh-tight\", \"--lh-snug\", \"--lh-normal\", \"--lh-loose\",\r\n // A7-02 — letter-spacing scale.\r\n \"--ls-tight\", \"--ls-normal\", \"--ls-wide\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n /**\r\n * A7-02 regression guard — the PHANTOM TOKEN class.\r\n *\r\n * The ms-dfd-fe Area 7 audit found six token names referenced across two\r\n * certified modules that this emitter never emitted: --ls-tight, --ls-wide,\r\n * --border-subtle, --r-xs, --icon-sm, --icon-xl. Because every consumer wrote\r\n * `var(--x, <literal>)`, the literal was the ONLY thing that ever rendered —\r\n * a hard-coded magic value wearing a token's name, invisible to review and\r\n * undetectable by tsc (R-2.3 / R-AI.1).\r\n *\r\n * The two letter-spacing names had a real platform basis and are now emitted\r\n * (asserted above). The other four were local inventions with no basis in the\r\n * Charter's token tables; asserting their ABSENCE here stops someone\r\n * \"resolving\" a phantom reference by inventing the token instead of fixing the\r\n * call site. Adding any of them is a Charter §02 amendment and must arrive\r\n * with its table entry, not via a failing consumer.\r\n */\r\n test(\"does NOT emit the four rejected phantom tokens (A7-02)\", () => {\r\n for (const v of [\"--border-subtle\", \"--r-xs\", \"--icon-sm\", \"--icon-xl\"]) {\r\n expect(css).not.toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits the spacing grid (--s-1 through --s-10)\", () => {\r\n for (let i = 1; i <= 10; i += 1) {\r\n expect(css).toContain(`--s-${i}:`);\r\n }\r\n });\r\n\r\n test(\"emits the spacing aliases under --space-* prefix\", () => {\r\n const aliases = [\"xs\", \"sm\", \"md\", \"lg\", \"xl\", \"xxl\"];\r\n for (const a of aliases) {\r\n expect(css).toContain(`--space-${a}:`);\r\n }\r\n });\r\n\r\n test(\"does NOT emit unprefixed alias names that would pollute the global CSS namespace\", () => {\r\n // Bare --md / --lg / --xl would collide with consumer stylesheets.\r\n // Batch 2 explicitly partitioned spacing into numeric grid (--s-N)\r\n // and semantic aliases (--space-X) to prevent this.\r\n // Use word boundaries so we don't false-match --r-md, --space-md, etc.\r\n const polluters = [\r\n /[^\\w-]--xs\\s*:/,\r\n /[^\\w-]--sm\\s*:/,\r\n /[^\\w-]--md\\s*:/,\r\n /[^\\w-]--lg\\s*:/,\r\n /[^\\w-]--xl\\s*:/,\r\n /[^\\w-]--xxl\\s*:/,\r\n ];\r\n for (const re of polluters) {\r\n expect(css).not.toMatch(re);\r\n }\r\n });\r\n\r\n test(\"emits radius, shadow, motion, easing, layout, density\", () => {\r\n const required = [\r\n \"--r-sm\", \"--r-md\", \"--r-lg\", \"--r-xl\", \"--r-full\", \"--r-none\",\r\n \"--shadow-xs\", \"--shadow-sm\", \"--shadow-md\", \"--shadow-lg\", \"--shadow-focus\",\r\n \"--duration-fast\", \"--duration-base\", \"--duration-slow\",\r\n \"--easing-out\", \"--easing-in\", \"--easing-soft\",\r\n \"--sidebar-w\", \"--topbar-h\", \"--content-max\", \"--form-max\", \"--tactile-min\",\r\n \"--row-h\", \"--input-h\", \"--btn-h\", \"--text-fs\",\r\n ];\r\n for (const v of required) {\r\n expect(css).toContain(`${v}:`);\r\n }\r\n });\r\n\r\n test(\"emits z-index variables\", () => {\r\n // Iterates the full zIndex object in cssVariables, so any\r\n // future zIndex slot (popover, snackbar, tooltip from Batch 1)\r\n // surfaces here without code change.\r\n expect(css).toMatch(/--z-modal\\s*:/);\r\n expect(css).toMatch(/--z-sticky\\s*:/);\r\n });\r\n\r\n test(\"emits the dark-mode override block with derived soft variants\", () => {\r\n expect(css).toContain('[data-theme=\"dark\"]');\r\n // Soft semantic fills are color-mix-derived in dark, not static hex\r\n // (Batch 2 contrast fix for WCAG 1.4.11 non-text on dark surfaces).\r\n expect(css).toMatch(/--success-soft:\\s*color-mix/);\r\n expect(css).toMatch(/--danger-soft:\\s*color-mix/);\r\n expect(css).toMatch(/--warning-soft:\\s*color-mix/);\r\n expect(css).toMatch(/--info-soft:\\s*color-mix/);\r\n });\r\n\r\n test(\"emits the compact density override block\", () => {\r\n expect(css).toContain('[data-density=\"compact\"]');\r\n // Compact override shrinks the row/input/btn heights.\r\n expect(css).toMatch(/\\[data-density=\"compact\"\\][\\s\\S]*--btn-h:/);\r\n });\r\n\r\n test(\"emits the collapsed-sidebar override\", () => {\r\n expect(css).toContain('[data-nav-collapsed=\"true\"]');\r\n });\r\n\r\n test(\"brand override propagates through resolveBrand\", () => {\r\n const customCss = getCssVariables({ brand: { accent: \"#FF0000\" } });\r\n expect(customCss).toContain(\"--accent: #FF0000;\");\r\n // Default also still emits its accent\r\n expect(css).toMatch(/--accent:\\s*#[0-9a-fA-F]{3,8}/);\r\n });\r\n\r\n test(\"brand override does NOT pollute other brand fields when omitted\", () => {\r\n // Partial brand override — accentSoft should fall back to default,\r\n // not to undefined or an empty string.\r\n const customCss = getCssVariables({ brand: { accent: \"#FF0000\" } });\r\n expect(customCss).not.toMatch(/--accent-soft:\\s*undefined/);\r\n expect(customCss).not.toMatch(/--accent-soft:\\s*;/);\r\n expect(customCss).toMatch(/--accent-soft:\\s*\\S+/);\r\n });\r\n});\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,136 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _fileValidation = require("../utils/fileValidation");
|
|
4
|
+
/** The policy of the module this capability was raised from, verbatim. */
|
|
5
|
+
const DAAC = {
|
|
6
|
+
extensions: ["pdf", "png", "jpg", "jpeg", "doc", "docx"]
|
|
7
|
+
};
|
|
8
|
+
const file = (name, type = "") => new File(["contenu"], name, {
|
|
9
|
+
type
|
|
10
|
+
});
|
|
11
|
+
describe("isForbiddenExecutable", () => {
|
|
12
|
+
it("recognises executables, scripts and installers", () => {
|
|
13
|
+
for (const name of ["setup.exe", "run.bat", "x.ps1", "pkg.msi", "a.hta"]) {
|
|
14
|
+
expect((0, _fileValidation.isForbiddenExecutable)(file(name))).toBe(true);
|
|
15
|
+
}
|
|
16
|
+
});
|
|
17
|
+
it("is case-insensitive", () => {
|
|
18
|
+
expect((0, _fileValidation.isForbiddenExecutable)(file("SETUP.EXE"))).toBe(true);
|
|
19
|
+
});
|
|
20
|
+
it("leaves ordinary documents alone", () => {
|
|
21
|
+
expect((0, _fileValidation.isForbiddenExecutable)(file("titre.pdf"))).toBe(false);
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
/* Callers pass items straight out of a FileList; nothing may throw. */
|
|
25
|
+
it("tolerates a missing file", () => {
|
|
26
|
+
expect((0, _fileValidation.isForbiddenExecutable)(null)).toBe(false);
|
|
27
|
+
expect((0, _fileValidation.isForbiddenExecutable)(undefined)).toBe(false);
|
|
28
|
+
});
|
|
29
|
+
});
|
|
30
|
+
describe("getFileRejection", () => {
|
|
31
|
+
it("accepts a file the policy allows", () => {
|
|
32
|
+
expect((0, _fileValidation.getFileRejection)(file("titre.pdf", "application/pdf"), DAAC)).toBeNull();
|
|
33
|
+
expect((0, _fileValidation.isAcceptedFile)(file("scan.PNG", "image/png"), DAAC)).toBe(true);
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
/* THE ORDER IS THE POINT: a dangerous file is named as such, not reported as
|
|
37
|
+
* an unsupported type — those are not the same information for the user. */
|
|
38
|
+
it("refuses an executable BEFORE any type consideration", () => {
|
|
39
|
+
const rejection = (0, _fileValidation.getFileRejection)(file("setup.exe"), DAAC);
|
|
40
|
+
expect(rejection?.reason).toBe("executable");
|
|
41
|
+
expect(rejection?.message).toBe("Les fichiers exécutables, scripts et installeurs ne sont pas autorisés.");
|
|
42
|
+
});
|
|
43
|
+
|
|
44
|
+
/* The deny-list is the LIBRARY's, not the host's: a host cannot opt into
|
|
45
|
+
* accepting executables by listing the extension. */
|
|
46
|
+
it("refuses an executable even when the policy lists it", () => {
|
|
47
|
+
const reckless = {
|
|
48
|
+
extensions: ["pdf", "exe"]
|
|
49
|
+
};
|
|
50
|
+
expect((0, _fileValidation.getFileRejection)(file("setup.exe"), reckless)?.reason).toBe("executable");
|
|
51
|
+
});
|
|
52
|
+
it("refuses an extension outside the policy", () => {
|
|
53
|
+
const rejection = (0, _fileValidation.getFileRejection)(file("archive.zip"), DAAC);
|
|
54
|
+
expect(rejection?.reason).toBe("extension");
|
|
55
|
+
expect(rejection?.message).toBe("Types autorisés : PDF, PNG, JPG, JPEG, DOC, DOCX.");
|
|
56
|
+
});
|
|
57
|
+
|
|
58
|
+
/* "rapport" has NO extension; a bare split().pop() would read the whole name
|
|
59
|
+
* as one, and "rapport" is not in any allow-list, so the bug would hide. */
|
|
60
|
+
it("refuses a name with no extension", () => {
|
|
61
|
+
expect((0, _fileValidation.getFileRejection)(file("rapport"), DAAC)?.reason).toBe("extension");
|
|
62
|
+
});
|
|
63
|
+
it("refuses a MIME type that contradicts the extension", () => {
|
|
64
|
+
const rejection = (0, _fileValidation.getFileRejection)(file("titre.pdf", "text/html"), DAAC);
|
|
65
|
+
expect(rejection?.reason).toBe("mime");
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
/* Some browsers report no type at all, and the extension has just been
|
|
69
|
+
* checked against the host's list. */
|
|
70
|
+
it("accepts an empty MIME type", () => {
|
|
71
|
+
expect((0, _fileValidation.getFileRejection)(file("titre.pdf", ""), DAAC)).toBeNull();
|
|
72
|
+
});
|
|
73
|
+
|
|
74
|
+
/* WITHOUT THIS, A LEGITIMATE .docx IS REFUSED on some machines — and
|
|
75
|
+
* intermittently, which is the hardest kind of report to act on. */
|
|
76
|
+
it("tolerates application/octet-stream for Office documents", () => {
|
|
77
|
+
expect((0, _fileValidation.getFileRejection)(file("courrier.docx", "application/octet-stream"), DAAC)).toBeNull();
|
|
78
|
+
expect((0, _fileValidation.getFileRejection)(file("courrier.doc", "application/octet-stream"), DAAC)).toBeNull();
|
|
79
|
+
});
|
|
80
|
+
it("does NOT extend that tolerance to a PDF", () => {
|
|
81
|
+
expect((0, _fileValidation.getFileRejection)(file("titre.pdf", "application/octet-stream"), DAAC)?.reason).toBe("mime");
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
/* `image/jpg` is not a registered type; browsers send it anyway. A canonical
|
|
85
|
+
* one-type-per-extension table would reject a valid photo. */
|
|
86
|
+
it("accepts the unregistered image/jpg variant", () => {
|
|
87
|
+
expect((0, _fileValidation.getFileRejection)(file("photo.jpg", "image/jpg"), DAAC)).toBeNull();
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
/* The MIME table is a cross-check, not a second allow-list: a host adding a
|
|
91
|
+
* format to its policy must not be refused by a table it cannot see. */
|
|
92
|
+
it("accepts an allowed extension the MIME table does not know", () => {
|
|
93
|
+
const withDwg = {
|
|
94
|
+
extensions: ["dwg"]
|
|
95
|
+
};
|
|
96
|
+
expect((0, _fileValidation.getFileRejection)(file("plan.dwg", "application/acad"), withDwg)).toBeNull();
|
|
97
|
+
});
|
|
98
|
+
it("matches the policy case-insensitively on both sides", () => {
|
|
99
|
+
const upper = {
|
|
100
|
+
extensions: ["PDF"]
|
|
101
|
+
};
|
|
102
|
+
expect((0, _fileValidation.getFileRejection)(file("TITRE.Pdf", "application/pdf"), upper)).toBeNull();
|
|
103
|
+
});
|
|
104
|
+
it("accepts nothing when the policy lists nothing", () => {
|
|
105
|
+
expect((0, _fileValidation.getFileRejection)(file("titre.pdf"), {
|
|
106
|
+
extensions: []
|
|
107
|
+
})?.reason).toBe("extension");
|
|
108
|
+
});
|
|
109
|
+
it("uses host labels when given", () => {
|
|
110
|
+
const rejection = (0, _fileValidation.getFileRejection)(file("archive.zip"), {
|
|
111
|
+
extensions: ["pdf"],
|
|
112
|
+
labels: {
|
|
113
|
+
type: "Seuls les PDF sont acceptés."
|
|
114
|
+
}
|
|
115
|
+
});
|
|
116
|
+
expect(rejection?.message).toBe("Seuls les PDF sont acceptés.");
|
|
117
|
+
});
|
|
118
|
+
it("treats an absent file as refused rather than throwing", () => {
|
|
119
|
+
expect((0, _fileValidation.getFileRejection)(null, DAAC)?.reason).toBe("extension");
|
|
120
|
+
expect((0, _fileValidation.isAcceptedFile)(undefined, DAAC)).toBe(false);
|
|
121
|
+
});
|
|
122
|
+
});
|
|
123
|
+
describe("describeAcceptedTypes / toAcceptAttribute", () => {
|
|
124
|
+
/* Order is the HOST's — it lists its most common format first on purpose, and
|
|
125
|
+
* sorting here would silently reorder copy someone wrote deliberately. */
|
|
126
|
+
it("keeps the host's order", () => {
|
|
127
|
+
expect((0, _fileValidation.describeAcceptedTypes)(DAAC.extensions)).toBe("PDF, PNG, JPG, JPEG, DOC, DOCX.");
|
|
128
|
+
});
|
|
129
|
+
it("builds the accept attribute", () => {
|
|
130
|
+
expect((0, _fileValidation.toAcceptAttribute)(DAAC.extensions)).toBe(".pdf,.png,.jpg,.jpeg,.doc,.docx");
|
|
131
|
+
});
|
|
132
|
+
it("lowercases the accept attribute", () => {
|
|
133
|
+
expect((0, _fileValidation.toAcceptAttribute)(["PDF", "Docx"])).toBe(".pdf,.docx");
|
|
134
|
+
});
|
|
135
|
+
});
|
|
136
|
+
//# sourceMappingURL=fileValidation.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fileValidation.test.js","names":["_fileValidation","require","DAAC","extensions","file","name","type","File","describe","it","expect","isForbiddenExecutable","toBe","undefined","getFileRejection","toBeNull","isAcceptedFile","rejection","reason","message","reckless","withDwg","upper","labels","describeAcceptedTypes","toAcceptAttribute"],"sources":["../../../src/lib/v2/__tests__/fileValidation.test.ts"],"sourcesContent":["import {\r\n describeAcceptedTypes,\r\n getFileRejection,\r\n isAcceptedFile,\r\n isForbiddenExecutable,\r\n toAcceptAttribute,\r\n} from \"../utils/fileValidation\";\r\nimport type { FileAcceptPolicy } from \"../utils/fileValidation\";\r\n\r\n/** The policy of the module this capability was raised from, verbatim. */\r\nconst DAAC: FileAcceptPolicy = {\r\n extensions: [\"pdf\", \"png\", \"jpg\", \"jpeg\", \"doc\", \"docx\"],\r\n};\r\n\r\nconst file = (name: string, type = \"\"): File =>\r\n new File([\"contenu\"], name, { type });\r\n\r\ndescribe(\"isForbiddenExecutable\", () => {\r\n it(\"recognises executables, scripts and installers\", () => {\r\n for (const name of [\"setup.exe\", \"run.bat\", \"x.ps1\", \"pkg.msi\", \"a.hta\"]) {\r\n expect(isForbiddenExecutable(file(name))).toBe(true);\r\n }\r\n });\r\n\r\n it(\"is case-insensitive\", () => {\r\n expect(isForbiddenExecutable(file(\"SETUP.EXE\"))).toBe(true);\r\n });\r\n\r\n it(\"leaves ordinary documents alone\", () => {\r\n expect(isForbiddenExecutable(file(\"titre.pdf\"))).toBe(false);\r\n });\r\n\r\n /* Callers pass items straight out of a FileList; nothing may throw. */\r\n it(\"tolerates a missing file\", () => {\r\n expect(isForbiddenExecutable(null)).toBe(false);\r\n expect(isForbiddenExecutable(undefined)).toBe(false);\r\n });\r\n});\r\n\r\ndescribe(\"getFileRejection\", () => {\r\n it(\"accepts a file the policy allows\", () => {\r\n expect(getFileRejection(file(\"titre.pdf\", \"application/pdf\"), DAAC)).toBeNull();\r\n expect(isAcceptedFile(file(\"scan.PNG\", \"image/png\"), DAAC)).toBe(true);\r\n });\r\n\r\n /* THE ORDER IS THE POINT: a dangerous file is named as such, not reported as\r\n * an unsupported type — those are not the same information for the user. */\r\n it(\"refuses an executable BEFORE any type consideration\", () => {\r\n const rejection = getFileRejection(file(\"setup.exe\"), DAAC);\r\n expect(rejection?.reason).toBe(\"executable\");\r\n expect(rejection?.message).toBe(\r\n \"Les fichiers exécutables, scripts et installeurs ne sont pas autorisés.\"\r\n );\r\n });\r\n\r\n /* The deny-list is the LIBRARY's, not the host's: a host cannot opt into\r\n * accepting executables by listing the extension. */\r\n it(\"refuses an executable even when the policy lists it\", () => {\r\n const reckless: FileAcceptPolicy = { extensions: [\"pdf\", \"exe\"] };\r\n expect(getFileRejection(file(\"setup.exe\"), reckless)?.reason).toBe(\r\n \"executable\"\r\n );\r\n });\r\n\r\n it(\"refuses an extension outside the policy\", () => {\r\n const rejection = getFileRejection(file(\"archive.zip\"), DAAC);\r\n expect(rejection?.reason).toBe(\"extension\");\r\n expect(rejection?.message).toBe(\r\n \"Types autorisés : PDF, PNG, JPG, JPEG, DOC, DOCX.\"\r\n );\r\n });\r\n\r\n /* \"rapport\" has NO extension; a bare split().pop() would read the whole name\r\n * as one, and \"rapport\" is not in any allow-list, so the bug would hide. */\r\n it(\"refuses a name with no extension\", () => {\r\n expect(getFileRejection(file(\"rapport\"), DAAC)?.reason).toBe(\"extension\");\r\n });\r\n\r\n it(\"refuses a MIME type that contradicts the extension\", () => {\r\n const rejection = getFileRejection(file(\"titre.pdf\", \"text/html\"), DAAC);\r\n expect(rejection?.reason).toBe(\"mime\");\r\n });\r\n\r\n /* Some browsers report no type at all, and the extension has just been\r\n * checked against the host's list. */\r\n it(\"accepts an empty MIME type\", () => {\r\n expect(getFileRejection(file(\"titre.pdf\", \"\"), DAAC)).toBeNull();\r\n });\r\n\r\n /* WITHOUT THIS, A LEGITIMATE .docx IS REFUSED on some machines — and\r\n * intermittently, which is the hardest kind of report to act on. */\r\n it(\"tolerates application/octet-stream for Office documents\", () => {\r\n expect(\r\n getFileRejection(file(\"courrier.docx\", \"application/octet-stream\"), DAAC)\r\n ).toBeNull();\r\n expect(\r\n getFileRejection(file(\"courrier.doc\", \"application/octet-stream\"), DAAC)\r\n ).toBeNull();\r\n });\r\n\r\n it(\"does NOT extend that tolerance to a PDF\", () => {\r\n expect(\r\n getFileRejection(file(\"titre.pdf\", \"application/octet-stream\"), DAAC)\r\n ?.reason\r\n ).toBe(\"mime\");\r\n });\r\n\r\n /* `image/jpg` is not a registered type; browsers send it anyway. A canonical\r\n * one-type-per-extension table would reject a valid photo. */\r\n it(\"accepts the unregistered image/jpg variant\", () => {\r\n expect(getFileRejection(file(\"photo.jpg\", \"image/jpg\"), DAAC)).toBeNull();\r\n });\r\n\r\n /* The MIME table is a cross-check, not a second allow-list: a host adding a\r\n * format to its policy must not be refused by a table it cannot see. */\r\n it(\"accepts an allowed extension the MIME table does not know\", () => {\r\n const withDwg: FileAcceptPolicy = { extensions: [\"dwg\"] };\r\n expect(\r\n getFileRejection(file(\"plan.dwg\", \"application/acad\"), withDwg)\r\n ).toBeNull();\r\n });\r\n\r\n it(\"matches the policy case-insensitively on both sides\", () => {\r\n const upper: FileAcceptPolicy = { extensions: [\"PDF\"] };\r\n expect(getFileRejection(file(\"TITRE.Pdf\", \"application/pdf\"), upper)).toBeNull();\r\n });\r\n\r\n it(\"accepts nothing when the policy lists nothing\", () => {\r\n expect(getFileRejection(file(\"titre.pdf\"), { extensions: [] })?.reason).toBe(\r\n \"extension\"\r\n );\r\n });\r\n\r\n it(\"uses host labels when given\", () => {\r\n const rejection = getFileRejection(file(\"archive.zip\"), {\r\n extensions: [\"pdf\"],\r\n labels: { type: \"Seuls les PDF sont acceptés.\" },\r\n });\r\n expect(rejection?.message).toBe(\"Seuls les PDF sont acceptés.\");\r\n });\r\n\r\n it(\"treats an absent file as refused rather than throwing\", () => {\r\n expect(getFileRejection(null, DAAC)?.reason).toBe(\"extension\");\r\n expect(isAcceptedFile(undefined, DAAC)).toBe(false);\r\n });\r\n});\r\n\r\ndescribe(\"describeAcceptedTypes / toAcceptAttribute\", () => {\r\n /* Order is the HOST's — it lists its most common format first on purpose, and\r\n * sorting here would silently reorder copy someone wrote deliberately. */\r\n it(\"keeps the host's order\", () => {\r\n expect(describeAcceptedTypes(DAAC.extensions)).toBe(\r\n \"PDF, PNG, JPG, JPEG, DOC, DOCX.\"\r\n );\r\n });\r\n\r\n it(\"builds the accept attribute\", () => {\r\n expect(toAcceptAttribute(DAAC.extensions)).toBe(\r\n \".pdf,.png,.jpg,.jpeg,.doc,.docx\"\r\n );\r\n });\r\n\r\n it(\"lowercases the accept attribute\", () => {\r\n expect(toAcceptAttribute([\"PDF\", \"Docx\"])).toBe(\".pdf,.docx\");\r\n });\r\n});\r\n"],"mappings":"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","ignoreList":[]}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
var _react = require("@testing-library/react");
|
|
4
|
+
var _filterCriteria = require("../patterns/filterCriteria");
|
|
5
|
+
var _useAppliedFilters = _interopRequireDefault(require("../hooks/useAppliedFilters"));
|
|
6
|
+
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
|
+
/**
|
|
8
|
+
* @jest-environment jsdom
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* filterCriteria (G-42) + useAppliedFilters (G-43) — promoted from
|
|
13
|
+
* `refonte-frontend` (Area 5).
|
|
14
|
+
*
|
|
15
|
+
* THE CASES BELOW ARE THE HOSTS' OWN, not invented ones. Each was read off the
|
|
16
|
+
* nine listings that consumed these two capabilities, which is why this file
|
|
17
|
+
* was written last: a test built on imagined descriptors would have covered
|
|
18
|
+
* the easy half and missed all four things that actually differ between
|
|
19
|
+
* screens.
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
describe("isCriterionSet", () => {
|
|
23
|
+
/**
|
|
24
|
+
* CASE 1 — `0` MEANS UNSET. Four payloads in the promoting module carry
|
|
25
|
+
* `villeEntreeId: 0` / `importateurId: 0` as their "no selection" value. A
|
|
26
|
+
* chip appearing for `0` announces a criterion nobody chose.
|
|
27
|
+
*/
|
|
28
|
+
test("0 is not set — it is the unset value of a reference mirror", () => {
|
|
29
|
+
expect((0, _filterCriteria.isCriterionSet)(0)).toBe(false);
|
|
30
|
+
});
|
|
31
|
+
test("null, undefined, empty string and empty array are not set", () => {
|
|
32
|
+
expect((0, _filterCriteria.isCriterionSet)(null)).toBe(false);
|
|
33
|
+
expect((0, _filterCriteria.isCriterionSet)(undefined)).toBe(false);
|
|
34
|
+
expect((0, _filterCriteria.isCriterionSet)("")).toBe(false);
|
|
35
|
+
expect((0, _filterCriteria.isCriterionSet)([])).toBe(false);
|
|
36
|
+
});
|
|
37
|
+
test("a reference object, a non-empty string and a non-zero id are set", () => {
|
|
38
|
+
expect((0, _filterCriteria.isCriterionSet)({
|
|
39
|
+
id: 42,
|
|
40
|
+
description: "SOFRANE SA"
|
|
41
|
+
})).toBe(true);
|
|
42
|
+
expect((0, _filterCriteria.isCriterionSet)("2025-IM-0042")).toBe(true);
|
|
43
|
+
expect((0, _filterCriteria.isCriterionSet)(42)).toBe(true);
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
describe("buildFilterChips", () => {
|
|
47
|
+
test("only SET criteria produce a chip", () => {
|
|
48
|
+
const criteria = [{
|
|
49
|
+
key: "identifiant",
|
|
50
|
+
label: "Référence"
|
|
51
|
+
}, {
|
|
52
|
+
key: "villeEntreeId",
|
|
53
|
+
label: "DPCI"
|
|
54
|
+
}];
|
|
55
|
+
const chips = (0, _filterCriteria.buildFilterChips)({
|
|
56
|
+
identifiant: "2025-IM-0042",
|
|
57
|
+
villeEntreeId: 0
|
|
58
|
+
}, criteria, jest.fn());
|
|
59
|
+
expect(chips).toHaveLength(1);
|
|
60
|
+
expect(chips[0]?.key).toBe("identifiant");
|
|
61
|
+
});
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* "Label: value" and not the value alone: "AFFECTE" does not say WHICH
|
|
65
|
+
* criterion it is when three chips sit side by side.
|
|
66
|
+
*/
|
|
67
|
+
test("the chip reads « label : value »", () => {
|
|
68
|
+
const chips = (0, _filterCriteria.buildFilterChips)({
|
|
69
|
+
statut: {
|
|
70
|
+
id: 3,
|
|
71
|
+
description: "Affecté"
|
|
72
|
+
}
|
|
73
|
+
}, [{
|
|
74
|
+
key: "statut",
|
|
75
|
+
label: "Statut"
|
|
76
|
+
}], jest.fn());
|
|
77
|
+
expect(chips[0]?.label).toBe("Statut : Affecté");
|
|
78
|
+
});
|
|
79
|
+
test("a reference object renders through its description by default", () => {
|
|
80
|
+
const chips = (0, _filterCriteria.buildFilterChips)({
|
|
81
|
+
importateurCode: {
|
|
82
|
+
id: 7,
|
|
83
|
+
description: "NOVATIS"
|
|
84
|
+
}
|
|
85
|
+
}, [{
|
|
86
|
+
key: "importateurCode",
|
|
87
|
+
label: "Importateur"
|
|
88
|
+
}], jest.fn());
|
|
89
|
+
expect(chips[0]?.label).toBe("Importateur : NOVATIS");
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* CASE 4 — `format`. `typeReponse` stores the id DIRECTLY, with no object
|
|
94
|
+
* mirror, so without a formatter the chip would read "Réponse ministère : 3".
|
|
95
|
+
*/
|
|
96
|
+
test("format renders a scalar id through the host's lookup", () => {
|
|
97
|
+
const lookup = {
|
|
98
|
+
"3": "Favorable"
|
|
99
|
+
};
|
|
100
|
+
const chips = (0, _filterCriteria.buildFilterChips)({
|
|
101
|
+
typeReponse: 3
|
|
102
|
+
}, [{
|
|
103
|
+
key: "typeReponse",
|
|
104
|
+
label: "Réponse ministère",
|
|
105
|
+
format: v => lookup[String(v)] ?? String(v)
|
|
106
|
+
}], jest.fn());
|
|
107
|
+
expect(chips[0]?.label).toBe("Réponse ministère : Favorable");
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* CASE 2 — THE PAIR. Reference criteria are held as two fields: an object for
|
|
112
|
+
* display and a scalar mirror for the payload. Clearing only the displayed
|
|
113
|
+
* key removes the chip from the screen while the criterion STAYS IN THE
|
|
114
|
+
* PAYLOAD — an invisible filter that still filters.
|
|
115
|
+
*/
|
|
116
|
+
test("removing a paired criterion clears its mirror too", () => {
|
|
117
|
+
const onRemove = jest.fn();
|
|
118
|
+
const chips = (0, _filterCriteria.buildFilterChips)({
|
|
119
|
+
importateurCode: {
|
|
120
|
+
id: 7,
|
|
121
|
+
description: "NOVATIS"
|
|
122
|
+
}
|
|
123
|
+
}, [{
|
|
124
|
+
key: "importateurCode",
|
|
125
|
+
label: "Importateur",
|
|
126
|
+
linkedKeys: ["importateurId"]
|
|
127
|
+
}], onRemove);
|
|
128
|
+
chips[0]?.onRemove?.();
|
|
129
|
+
expect(onRemove).toHaveBeenCalledWith(["importateurCode", "importateurId"]);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
/**
|
|
133
|
+
* CASE 3 — TWO NOMENCLATURES, not one mirror. One host's persisted filter
|
|
134
|
+
* suffixes its objects with `_obj` while its form names them plainly, so
|
|
135
|
+
* `linkedKeys` reconciles the two vocabularies: the chip READS
|
|
136
|
+
* `categorie_obj` and CLEARS all three keys.
|
|
137
|
+
*/
|
|
138
|
+
test("linkedKeys can reconcile two key nomenclatures, not just a mirror", () => {
|
|
139
|
+
const onRemove = jest.fn();
|
|
140
|
+
const chips = (0, _filterCriteria.buildFilterChips)({
|
|
141
|
+
categorie_obj: {
|
|
142
|
+
id: 1,
|
|
143
|
+
description: "Balances"
|
|
144
|
+
}
|
|
145
|
+
}, [{
|
|
146
|
+
key: "categorie_obj",
|
|
147
|
+
label: "Catégorie d'IM",
|
|
148
|
+
linkedKeys: ["categorie", "categorieId"]
|
|
149
|
+
}], onRemove);
|
|
150
|
+
chips[0]?.onRemove?.();
|
|
151
|
+
expect(onRemove).toHaveBeenCalledWith(["categorie_obj", "categorie", "categorieId"]);
|
|
152
|
+
});
|
|
153
|
+
test("filterCriteriaKeys lists every key, mirrors included — for a clear-all", () => {
|
|
154
|
+
expect((0, _filterCriteria.filterCriteriaKeys)([{
|
|
155
|
+
key: "identifiant",
|
|
156
|
+
label: "Référence"
|
|
157
|
+
}, {
|
|
158
|
+
key: "delegation",
|
|
159
|
+
label: "DPCI",
|
|
160
|
+
linkedKeys: ["delegationId", "villeEntreeId"]
|
|
161
|
+
}])).toEqual(["identifiant", "delegation", "delegationId", "villeEntreeId"]);
|
|
162
|
+
});
|
|
163
|
+
});
|
|
164
|
+
describe("useAppliedFilters", () => {
|
|
165
|
+
const makeForm = values => ({
|
|
166
|
+
values,
|
|
167
|
+
setFieldValue: jest.fn()
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* THE DEFECT THIS HOOK EXISTS FOR. `DataGridToolbar`'s search input writes
|
|
172
|
+
* into the form on every keystroke; the snapshot must not follow it, or a
|
|
173
|
+
* chip appears mid-typing announcing a filter that filters nothing.
|
|
174
|
+
*/
|
|
175
|
+
test("the snapshot ignores typing until apply() is called", () => {
|
|
176
|
+
const form = makeForm({
|
|
177
|
+
identifiant: "202"
|
|
178
|
+
});
|
|
179
|
+
const {
|
|
180
|
+
result
|
|
181
|
+
} = (0, _react.renderHook)(() => (0, _useAppliedFilters.default)(form, {
|
|
182
|
+
onApply: jest.fn(),
|
|
183
|
+
onReset: jest.fn(),
|
|
184
|
+
onRemove: jest.fn()
|
|
185
|
+
}));
|
|
186
|
+
expect(result.current.appliedFilters).toEqual({});
|
|
187
|
+
(0, _react.act)(() => {
|
|
188
|
+
result.current.apply();
|
|
189
|
+
});
|
|
190
|
+
expect(result.current.appliedFilters).toEqual({
|
|
191
|
+
identifiant: "202"
|
|
192
|
+
});
|
|
193
|
+
});
|
|
194
|
+
test("apply() runs the screen's search, resetAll() clears and resets", () => {
|
|
195
|
+
const onApply = jest.fn();
|
|
196
|
+
const onReset = jest.fn();
|
|
197
|
+
const form = makeForm({
|
|
198
|
+
identifiant: "2025-IM-0042"
|
|
199
|
+
});
|
|
200
|
+
const {
|
|
201
|
+
result
|
|
202
|
+
} = (0, _react.renderHook)(() => (0, _useAppliedFilters.default)(form, {
|
|
203
|
+
onApply,
|
|
204
|
+
onReset,
|
|
205
|
+
onRemove: jest.fn()
|
|
206
|
+
}));
|
|
207
|
+
(0, _react.act)(() => {
|
|
208
|
+
result.current.apply();
|
|
209
|
+
});
|
|
210
|
+
expect(onApply).toHaveBeenCalled();
|
|
211
|
+
(0, _react.act)(() => {
|
|
212
|
+
result.current.resetAll();
|
|
213
|
+
});
|
|
214
|
+
expect(onReset).toHaveBeenCalled();
|
|
215
|
+
/* The mirror-image defect: a snapshot left full after "clear criteria"
|
|
216
|
+
* shows chips for criteria that no longer filter anything. */
|
|
217
|
+
expect(result.current.appliedFilters).toEqual({});
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The payload is rebuilt from the AMPUTATED SNAPSHOT and never re-read from
|
|
222
|
+
* the form: `setFieldValue` is asynchronous, so reading values back would
|
|
223
|
+
* give the criteria as they were BEFORE the removal.
|
|
224
|
+
*/
|
|
225
|
+
test("removeCriteria clears the fields and hands back the REMAINING criteria", () => {
|
|
226
|
+
const onRemove = jest.fn();
|
|
227
|
+
const form = makeForm({
|
|
228
|
+
identifiant: "2025-IM-0042",
|
|
229
|
+
importateurCode: {
|
|
230
|
+
id: 7
|
|
231
|
+
},
|
|
232
|
+
importateurId: 7
|
|
233
|
+
});
|
|
234
|
+
const {
|
|
235
|
+
result
|
|
236
|
+
} = (0, _react.renderHook)(() => (0, _useAppliedFilters.default)(form, {
|
|
237
|
+
onApply: jest.fn(),
|
|
238
|
+
onReset: jest.fn(),
|
|
239
|
+
onRemove
|
|
240
|
+
}));
|
|
241
|
+
(0, _react.act)(() => {
|
|
242
|
+
result.current.apply();
|
|
243
|
+
});
|
|
244
|
+
(0, _react.act)(() => {
|
|
245
|
+
result.current.removeCriteria(["importateurCode", "importateurId"]);
|
|
246
|
+
});
|
|
247
|
+
expect(form.setFieldValue).toHaveBeenCalledWith("importateurCode", null);
|
|
248
|
+
expect(form.setFieldValue).toHaveBeenCalledWith("importateurId", null);
|
|
249
|
+
expect(onRemove).toHaveBeenCalledWith({
|
|
250
|
+
identifiant: "2025-IM-0042",
|
|
251
|
+
importateurCode: null,
|
|
252
|
+
importateurId: null
|
|
253
|
+
});
|
|
254
|
+
expect(result.current.appliedFilters["importateurCode"]).toBeNull();
|
|
255
|
+
});
|
|
256
|
+
|
|
257
|
+
/**
|
|
258
|
+
* Hosts disagree on what "empty" means, per field — which is why this is a
|
|
259
|
+
* parameter and not a library convention. One real host clears id mirrors to
|
|
260
|
+
* `0` and everything else to `null`, because that is what ITS reset payload
|
|
261
|
+
* uses.
|
|
262
|
+
*/
|
|
263
|
+
test("emptyValueFor lets the host decide what empty means, per field", () => {
|
|
264
|
+
const onRemove = jest.fn();
|
|
265
|
+
const form = makeForm({
|
|
266
|
+
categorie: {
|
|
267
|
+
id: 1
|
|
268
|
+
},
|
|
269
|
+
categorieId: 1
|
|
270
|
+
});
|
|
271
|
+
const {
|
|
272
|
+
result
|
|
273
|
+
} = (0, _react.renderHook)(() => (0, _useAppliedFilters.default)(form, {
|
|
274
|
+
onApply: jest.fn(),
|
|
275
|
+
onReset: jest.fn(),
|
|
276
|
+
onRemove,
|
|
277
|
+
emptyValueFor: key => key.endsWith("Id") ? 0 : null
|
|
278
|
+
}));
|
|
279
|
+
(0, _react.act)(() => {
|
|
280
|
+
result.current.apply();
|
|
281
|
+
});
|
|
282
|
+
(0, _react.act)(() => {
|
|
283
|
+
result.current.removeCriteria(["categorie", "categorieId"]);
|
|
284
|
+
});
|
|
285
|
+
expect(form.setFieldValue).toHaveBeenCalledWith("categorie", null);
|
|
286
|
+
expect(form.setFieldValue).toHaveBeenCalledWith("categorieId", 0);
|
|
287
|
+
expect(onRemove).toHaveBeenCalledWith({
|
|
288
|
+
categorie: null,
|
|
289
|
+
categorieId: 0
|
|
290
|
+
});
|
|
291
|
+
});
|
|
292
|
+
|
|
293
|
+
/**
|
|
294
|
+
* THE THREE PATHS THAT BYPASS apply(). Restoring a saved filter or clicking
|
|
295
|
+
* a status chip changes what actually filters the list without going through
|
|
296
|
+
* the form's submit — and both used to leave the chips lying: the list was
|
|
297
|
+
* filtered and NO chip appeared.
|
|
298
|
+
*/
|
|
299
|
+
test("setApplied covers the paths that never go through apply()", () => {
|
|
300
|
+
const form = makeForm({});
|
|
301
|
+
const {
|
|
302
|
+
result
|
|
303
|
+
} = (0, _react.renderHook)(() => (0, _useAppliedFilters.default)(form, {
|
|
304
|
+
onApply: jest.fn(),
|
|
305
|
+
onReset: jest.fn(),
|
|
306
|
+
onRemove: jest.fn()
|
|
307
|
+
}));
|
|
308
|
+
(0, _react.act)(() => {
|
|
309
|
+
result.current.setApplied({
|
|
310
|
+
statut: {
|
|
311
|
+
id: 3,
|
|
312
|
+
description: "Affecté"
|
|
313
|
+
}
|
|
314
|
+
});
|
|
315
|
+
});
|
|
316
|
+
expect(result.current.appliedFilters).toEqual({
|
|
317
|
+
statut: {
|
|
318
|
+
id: 3,
|
|
319
|
+
description: "Affecté"
|
|
320
|
+
}
|
|
321
|
+
});
|
|
322
|
+
});
|
|
323
|
+
});
|
|
324
|
+
//# sourceMappingURL=filterCriteria.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filterCriteria.test.js","names":["_react","require","_filterCriteria","_useAppliedFilters","_interopRequireDefault","e","__esModule","default","describe","test","expect","isCriterionSet","toBe","undefined","id","description","criteria","key","label","chips","buildFilterChips","identifiant","villeEntreeId","jest","fn","toHaveLength","statut","importateurCode","lookup","typeReponse","format","v","String","onRemove","linkedKeys","toHaveBeenCalledWith","categorie_obj","filterCriteriaKeys","toEqual","makeForm","values","setFieldValue","form","result","renderHook","useAppliedFilters","onApply","onReset","current","appliedFilters","act","apply","toHaveBeenCalled","resetAll","importateurId","removeCriteria","toBeNull","categorie","categorieId","emptyValueFor","endsWith","setApplied"],"sources":["../../../src/lib/v2/__tests__/filterCriteria.test.tsx"],"sourcesContent":["/**\r\n * @jest-environment jsdom\r\n */\r\nimport { renderHook, act } from \"@testing-library/react\";\r\nimport {\r\n buildFilterChips,\r\n filterCriteriaKeys,\r\n isCriterionSet,\r\n} from \"../patterns/filterCriteria\";\r\nimport type { FilterCriterion } from \"../patterns/filterCriteria\";\r\nimport useAppliedFilters from \"../hooks/useAppliedFilters\";\r\n\r\n/**\r\n * filterCriteria (G-42) + useAppliedFilters (G-43) — promoted from\r\n * `refonte-frontend` (Area 5).\r\n *\r\n * THE CASES BELOW ARE THE HOSTS' OWN, not invented ones. Each was read off the\r\n * nine listings that consumed these two capabilities, which is why this file\r\n * was written last: a test built on imagined descriptors would have covered\r\n * the easy half and missed all four things that actually differ between\r\n * screens.\r\n */\r\n\r\ndescribe(\"isCriterionSet\", () => {\r\n /**\r\n * CASE 1 — `0` MEANS UNSET. Four payloads in the promoting module carry\r\n * `villeEntreeId: 0` / `importateurId: 0` as their \"no selection\" value. A\r\n * chip appearing for `0` announces a criterion nobody chose.\r\n */\r\n test(\"0 is not set — it is the unset value of a reference mirror\", () => {\r\n expect(isCriterionSet(0)).toBe(false);\r\n });\r\n\r\n test(\"null, undefined, empty string and empty array are not set\", () => {\r\n expect(isCriterionSet(null)).toBe(false);\r\n expect(isCriterionSet(undefined)).toBe(false);\r\n expect(isCriterionSet(\"\")).toBe(false);\r\n expect(isCriterionSet([])).toBe(false);\r\n });\r\n\r\n test(\"a reference object, a non-empty string and a non-zero id are set\", () => {\r\n expect(isCriterionSet({ id: 42, description: \"SOFRANE SA\" })).toBe(true);\r\n expect(isCriterionSet(\"2025-IM-0042\")).toBe(true);\r\n expect(isCriterionSet(42)).toBe(true);\r\n });\r\n});\r\n\r\ndescribe(\"buildFilterChips\", () => {\r\n test(\"only SET criteria produce a chip\", () => {\r\n const criteria: FilterCriterion[] = [\r\n { key: \"identifiant\", label: \"Référence\" },\r\n { key: \"villeEntreeId\", label: \"DPCI\" },\r\n ];\r\n const chips = buildFilterChips(\r\n { identifiant: \"2025-IM-0042\", villeEntreeId: 0 },\r\n criteria,\r\n jest.fn()\r\n );\r\n expect(chips).toHaveLength(1);\r\n expect(chips[0]?.key).toBe(\"identifiant\");\r\n });\r\n\r\n /**\r\n * \"Label: value\" and not the value alone: \"AFFECTE\" does not say WHICH\r\n * criterion it is when three chips sit side by side.\r\n */\r\n test(\"the chip reads « label : value »\", () => {\r\n const chips = buildFilterChips(\r\n { statut: { id: 3, description: \"Affecté\" } },\r\n [{ key: \"statut\", label: \"Statut\" }],\r\n jest.fn()\r\n );\r\n expect(chips[0]?.label).toBe(\"Statut : Affecté\");\r\n });\r\n\r\n test(\"a reference object renders through its description by default\", () => {\r\n const chips = buildFilterChips(\r\n { importateurCode: { id: 7, description: \"NOVATIS\" } },\r\n [{ key: \"importateurCode\", label: \"Importateur\" }],\r\n jest.fn()\r\n );\r\n expect(chips[0]?.label).toBe(\"Importateur : NOVATIS\");\r\n });\r\n\r\n /**\r\n * CASE 4 — `format`. `typeReponse` stores the id DIRECTLY, with no object\r\n * mirror, so without a formatter the chip would read \"Réponse ministère : 3\".\r\n */\r\n test(\"format renders a scalar id through the host's lookup\", () => {\r\n const lookup: Record<string, string> = { \"3\": \"Favorable\" };\r\n const chips = buildFilterChips(\r\n { typeReponse: 3 },\r\n [\r\n {\r\n key: \"typeReponse\",\r\n label: \"Réponse ministère\",\r\n format: (v) => lookup[String(v)] ?? String(v),\r\n },\r\n ],\r\n jest.fn()\r\n );\r\n expect(chips[0]?.label).toBe(\"Réponse ministère : Favorable\");\r\n });\r\n\r\n /**\r\n * CASE 2 — THE PAIR. Reference criteria are held as two fields: an object for\r\n * display and a scalar mirror for the payload. Clearing only the displayed\r\n * key removes the chip from the screen while the criterion STAYS IN THE\r\n * PAYLOAD — an invisible filter that still filters.\r\n */\r\n test(\"removing a paired criterion clears its mirror too\", () => {\r\n const onRemove = jest.fn();\r\n const chips = buildFilterChips(\r\n { importateurCode: { id: 7, description: \"NOVATIS\" } },\r\n [\r\n {\r\n key: \"importateurCode\",\r\n label: \"Importateur\",\r\n linkedKeys: [\"importateurId\"],\r\n },\r\n ],\r\n onRemove\r\n );\r\n chips[0]?.onRemove?.();\r\n expect(onRemove).toHaveBeenCalledWith([\"importateurCode\", \"importateurId\"]);\r\n });\r\n\r\n /**\r\n * CASE 3 — TWO NOMENCLATURES, not one mirror. One host's persisted filter\r\n * suffixes its objects with `_obj` while its form names them plainly, so\r\n * `linkedKeys` reconciles the two vocabularies: the chip READS\r\n * `categorie_obj` and CLEARS all three keys.\r\n */\r\n test(\"linkedKeys can reconcile two key nomenclatures, not just a mirror\", () => {\r\n const onRemove = jest.fn();\r\n const chips = buildFilterChips(\r\n { categorie_obj: { id: 1, description: \"Balances\" } },\r\n [\r\n {\r\n key: \"categorie_obj\",\r\n label: \"Catégorie d'IM\",\r\n linkedKeys: [\"categorie\", \"categorieId\"],\r\n },\r\n ],\r\n onRemove\r\n );\r\n chips[0]?.onRemove?.();\r\n expect(onRemove).toHaveBeenCalledWith([\r\n \"categorie_obj\",\r\n \"categorie\",\r\n \"categorieId\",\r\n ]);\r\n });\r\n\r\n test(\"filterCriteriaKeys lists every key, mirrors included — for a clear-all\", () => {\r\n expect(\r\n filterCriteriaKeys([\r\n { key: \"identifiant\", label: \"Référence\" },\r\n { key: \"delegation\", label: \"DPCI\", linkedKeys: [\"delegationId\", \"villeEntreeId\"] },\r\n ])\r\n ).toEqual([\"identifiant\", \"delegation\", \"delegationId\", \"villeEntreeId\"]);\r\n });\r\n});\r\n\r\ndescribe(\"useAppliedFilters\", () => {\r\n interface Form {\r\n values: Record<string, unknown>;\r\n setFieldValue: jest.Mock;\r\n }\r\n\r\n const makeForm = (values: Record<string, unknown>): Form => ({\r\n values,\r\n setFieldValue: jest.fn(),\r\n });\r\n\r\n /**\r\n * THE DEFECT THIS HOOK EXISTS FOR. `DataGridToolbar`'s search input writes\r\n * into the form on every keystroke; the snapshot must not follow it, or a\r\n * chip appears mid-typing announcing a filter that filters nothing.\r\n */\r\n test(\"the snapshot ignores typing until apply() is called\", () => {\r\n const form = makeForm({ identifiant: \"202\" });\r\n const { result } = renderHook(() =>\r\n useAppliedFilters(form, {\r\n onApply: jest.fn(),\r\n onReset: jest.fn(),\r\n onRemove: jest.fn(),\r\n })\r\n );\r\n\r\n expect(result.current.appliedFilters).toEqual({});\r\n\r\n act(() => {\r\n result.current.apply();\r\n });\r\n expect(result.current.appliedFilters).toEqual({ identifiant: \"202\" });\r\n });\r\n\r\n test(\"apply() runs the screen's search, resetAll() clears and resets\", () => {\r\n const onApply = jest.fn();\r\n const onReset = jest.fn();\r\n const form = makeForm({ identifiant: \"2025-IM-0042\" });\r\n const { result } = renderHook(() =>\r\n useAppliedFilters(form, { onApply, onReset, onRemove: jest.fn() })\r\n );\r\n\r\n act(() => {\r\n result.current.apply();\r\n });\r\n expect(onApply).toHaveBeenCalled();\r\n\r\n act(() => {\r\n result.current.resetAll();\r\n });\r\n expect(onReset).toHaveBeenCalled();\r\n /* The mirror-image defect: a snapshot left full after \"clear criteria\"\r\n * shows chips for criteria that no longer filter anything. */\r\n expect(result.current.appliedFilters).toEqual({});\r\n });\r\n\r\n /**\r\n * The payload is rebuilt from the AMPUTATED SNAPSHOT and never re-read from\r\n * the form: `setFieldValue` is asynchronous, so reading values back would\r\n * give the criteria as they were BEFORE the removal.\r\n */\r\n test(\"removeCriteria clears the fields and hands back the REMAINING criteria\", () => {\r\n const onRemove = jest.fn();\r\n const form = makeForm({\r\n identifiant: \"2025-IM-0042\",\r\n importateurCode: { id: 7 },\r\n importateurId: 7,\r\n });\r\n const { result } = renderHook(() =>\r\n useAppliedFilters(form, {\r\n onApply: jest.fn(),\r\n onReset: jest.fn(),\r\n onRemove,\r\n })\r\n );\r\n\r\n act(() => {\r\n result.current.apply();\r\n });\r\n act(() => {\r\n result.current.removeCriteria([\"importateurCode\", \"importateurId\"]);\r\n });\r\n\r\n expect(form.setFieldValue).toHaveBeenCalledWith(\"importateurCode\", null);\r\n expect(form.setFieldValue).toHaveBeenCalledWith(\"importateurId\", null);\r\n expect(onRemove).toHaveBeenCalledWith({\r\n identifiant: \"2025-IM-0042\",\r\n importateurCode: null,\r\n importateurId: null,\r\n });\r\n expect(result.current.appliedFilters[\"importateurCode\"]).toBeNull();\r\n });\r\n\r\n /**\r\n * Hosts disagree on what \"empty\" means, per field — which is why this is a\r\n * parameter and not a library convention. One real host clears id mirrors to\r\n * `0` and everything else to `null`, because that is what ITS reset payload\r\n * uses.\r\n */\r\n test(\"emptyValueFor lets the host decide what empty means, per field\", () => {\r\n const onRemove = jest.fn();\r\n const form = makeForm({ categorie: { id: 1 }, categorieId: 1 });\r\n const { result } = renderHook(() =>\r\n useAppliedFilters(form, {\r\n onApply: jest.fn(),\r\n onReset: jest.fn(),\r\n onRemove,\r\n emptyValueFor: (key) => (key.endsWith(\"Id\") ? 0 : null),\r\n })\r\n );\r\n\r\n act(() => {\r\n result.current.apply();\r\n });\r\n act(() => {\r\n result.current.removeCriteria([\"categorie\", \"categorieId\"]);\r\n });\r\n\r\n expect(form.setFieldValue).toHaveBeenCalledWith(\"categorie\", null);\r\n expect(form.setFieldValue).toHaveBeenCalledWith(\"categorieId\", 0);\r\n expect(onRemove).toHaveBeenCalledWith({ categorie: null, categorieId: 0 });\r\n });\r\n\r\n /**\r\n * THE THREE PATHS THAT BYPASS apply(). Restoring a saved filter or clicking\r\n * a status chip changes what actually filters the list without going through\r\n * the form's submit — and both used to leave the chips lying: the list was\r\n * filtered and NO chip appeared.\r\n */\r\n test(\"setApplied covers the paths that never go through apply()\", () => {\r\n const form = makeForm({});\r\n const { result } = renderHook(() =>\r\n useAppliedFilters(form, {\r\n onApply: jest.fn(),\r\n onReset: jest.fn(),\r\n onRemove: jest.fn(),\r\n })\r\n );\r\n\r\n act(() => {\r\n result.current.setApplied({ statut: { id: 3, description: \"Affecté\" } });\r\n });\r\n\r\n expect(result.current.appliedFilters).toEqual({\r\n statut: { id: 3, description: \"Affecté\" },\r\n });\r\n });\r\n});\r\n"],"mappings":"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","ignoreList":[]}
|