@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
package/CHANGELOG.md
CHANGED
|
@@ -10,6 +10,743 @@ The format is loosely based on [Keep a Changelog](https://keepachangelog.com/en/
|
|
|
10
10
|
|
|
11
11
|
### Added
|
|
12
12
|
|
|
13
|
+
- **`useFocusOnRouteChange` — le focus après une navigation (gap G-60).**
|
|
14
|
+
|
|
15
|
+
Dans une application à page unique, naviguer ne déplace **pas** le focus : le
|
|
16
|
+
navigateur ne le fait qu'au chargement d'un vrai document. Le focus reste
|
|
17
|
+
donc sur ce qui a été cliqué — ou tombe sur `document.body` quand cet élément
|
|
18
|
+
est démonté par la navigation qu'il vient de déclencher.
|
|
19
|
+
|
|
20
|
+
Depuis `document.body`, le Tab suivant repart du haut du **navigateur** et
|
|
21
|
+
non de la page : l'utilisateur au clavier retraverse la barre d'adresse et la
|
|
22
|
+
barre d'outils à chaque écran. Un utilisateur de lecteur d'écran, lui,
|
|
23
|
+
n'obtient aucune annonce — la nouvelle page existe, en silence, et il doit
|
|
24
|
+
partir à sa recherche. C'est WCAG 2.4.3 qui échoue, et rien à l'écran ne le
|
|
25
|
+
montre : les pixels sont parfaits.
|
|
26
|
+
|
|
27
|
+
Le défaut est à son maximum quand la navigation SUIT une action, puisque le
|
|
28
|
+
déclencheur a disparu au moment où le focus devrait y revenir. **Relevé depuis
|
|
29
|
+
`autorisation-admis-pour-conforme-fe` (Area 10)** : archiver un dossier ferme
|
|
30
|
+
un dialogue de confirmation puis navigue en arrière, si bien que le piège de
|
|
31
|
+
focus du dialogue restitue le focus à un bouton qui n'existe plus.
|
|
32
|
+
|
|
33
|
+
**Agnostique du routeur par construction** — aucun routeur importé, l'hôte
|
|
34
|
+
passe la clé qu'il veut surveiller :
|
|
35
|
+
|
|
36
|
+
const { pathname } = useLocation();
|
|
37
|
+
useFocusOnRouteChange(pathname);
|
|
38
|
+
|
|
39
|
+
Et la consigne compte autant que le hook : **passer le CHEMIN, pas
|
|
40
|
+
`location.key` ni l'URL complète.** Un écran de liste écrit ses filtres, sa
|
|
41
|
+
page et son tri dans la query string, et chacun produit une nouvelle clé —
|
|
42
|
+
la surveiller volerait le focus au champ dans lequel l'utilisateur est en
|
|
43
|
+
train de taper. Ce qui mérite un déplacement de focus est un changement de
|
|
44
|
+
PAGE, pas un changement d'état de page.
|
|
45
|
+
|
|
46
|
+
La library est le bon endroit même sans connaître de routeur : `AppMain` est
|
|
47
|
+
la cible, et c'est lui qui porte le `tabIndex={-1}` qui rend la région
|
|
48
|
+
focalisable. Un hôte qui câblerait cela à la main réimplementerait
|
|
49
|
+
l'appariement que `SkipLink` + `AppMain` possèdent déjà.
|
|
50
|
+
|
|
51
|
+
Le premier rendu est ignoré (le navigateur a déjà placé le focus, et le
|
|
52
|
+
déplacer alors casserait un lien profond vers une ancre), une cible absente
|
|
53
|
+
ne provoque rien plutôt qu'une exception, et `preventScroll` n'est pas posé :
|
|
54
|
+
amener le haut de la région dans le champ de vision fait partie de ce qu'on
|
|
55
|
+
attend d'un changement de page. Tests :
|
|
56
|
+
`__tests__/useFocusOnRouteChange.test.tsx`.
|
|
57
|
+
|
|
58
|
+
- **`AppMain` — `ariaLabel` et `ariaBusy` pour le landmark pré-contenu.**
|
|
59
|
+
|
|
60
|
+
Un hôte qui rend le landmark AVANT son routeur, comme R-Pp.1 l'exige
|
|
61
|
+
(« jamais d'écran blanc »), n'a rien à l'intérieur pour le nommer, et
|
|
62
|
+
« région principale » seul ne dit pas à l'utilisateur ce qui se passe. Le
|
|
63
|
+
couple compte : sans `aria-busy`, un landmark simplement VIDE est
|
|
64
|
+
indiscernable d'un landmark qui a échoué.
|
|
65
|
+
|
|
66
|
+
Pas de surface spéculative — le consommateur est nommé : la coque
|
|
67
|
+
pré-authentification d'`autorisation-admis-pour-conforme-fe` (Area 10)
|
|
68
|
+
écrivait le landmark **à la main** (`id`, `tabIndex`, `outline`, `minHeight`)
|
|
69
|
+
PARCE QU'ELLE ne pouvait pas exprimer ces deux attributs à travers ce
|
|
70
|
+
composant. Un pattern qui oblige un hôte à le réimplementer pour pouvoir le
|
|
71
|
+
nommer n'a pas fini son travail.
|
|
72
|
+
|
|
73
|
+
Aucun des deux attributs n'est émis par défaut : un `aria-busy="false"` sur
|
|
74
|
+
chaque page serait du bruit dans l'arbre d'accessibilité.
|
|
75
|
+
|
|
76
|
+
- **`chartChrome` (gap G-54) et `ChartFigure` (gap G-55) — le mobilier d'un
|
|
77
|
+
graphe, et son équivalent textuel.**
|
|
78
|
+
|
|
79
|
+
`tokens/chart` portait déjà la palette catégorielle (G-37) et énonçait, dans
|
|
80
|
+
son propre en-tête, l'obligation que la librairie ne permettait pas de tenir :
|
|
81
|
+
« COLOUR IS NEVER THE ONLY CHANNEL (WCAG 1.4.1). This palette makes slices
|
|
82
|
+
distinguishable; it does not make a chart accessible. Every consumer still
|
|
83
|
+
owes a legend with text labels, and a text equivalent of the data — 1.1.1 for
|
|
84
|
+
the chart as a whole. »
|
|
85
|
+
|
|
86
|
+
**`chartChrome` est une correspondance RÔLE → TOKEN, pas un magasin de
|
|
87
|
+
valeurs**, et la distinction est la justification. Chaque valeur existait
|
|
88
|
+
déjà, et un module qui lit `ink.fgMuted` pour ses étiquettes d'axe respecte
|
|
89
|
+
déjà R-2.3. Ce qu'aucun module ne peut trancher seul, c'est QUEL token joue
|
|
90
|
+
QUEL rôle : un titre de graphe est-il un `h2` ou un `h3` ? les étiquettes,
|
|
91
|
+
`xs` ou `sm` ? le fond, `surface` ou transparent ? Sans réponse de plateforme,
|
|
92
|
+
chaque écran répond à nouveau — trois écrans de bilan et cinq définitions de
|
|
93
|
+
graphes dans le module relevé, d'accord entre eux seulement parce qu'ils se
|
|
94
|
+
sont recopiés. La réponse, une fois : titre = titre de carte (`h3`, semibold,
|
|
95
|
+
encre pleine), étiquettes = indications (`xs`, encre atténuée), fond
|
|
96
|
+
TRANSPARENT — un fond blanc en dur est exactement ce qui casse un graphe en
|
|
97
|
+
mode sombre.
|
|
98
|
+
|
|
99
|
+
Agnostique de librairie par construction : des chaînes simples, aucune
|
|
100
|
+
librairie de graphes importée, aucune forme d'options supposée. Les tailles
|
|
101
|
+
de police y sont des chaînes AVEC UNITÉ, contrairement à `fontSize.*` qui
|
|
102
|
+
sont des entiers : un moteur de graphes passe ses objets de style à des
|
|
103
|
+
attributs SVG, qui ne reçoivent jamais d'unité gratuitement — un `16` nu est
|
|
104
|
+
ignoré par certains moteurs et lu comme `16px` par d'autres.
|
|
105
|
+
|
|
106
|
+
**`ChartFigure` porte l'équivalent textuel, et `caption` y est OBLIGATOIRE.**
|
|
107
|
+
C'est la seule décision de conception de ce composant : un graphe rendu à
|
|
108
|
+
travers lui ne peut pas partir sans ses chiffres en texte. Une règle énoncée
|
|
109
|
+
sans composant pour la porter est tenue par qui s'en souvient — et
|
|
110
|
+
l'équivalent textuel est la partie qui disparaît la première, parce que c'est
|
|
111
|
+
la seule que personne ne VOIT manquer : un graphe sans équivalent a l'air
|
|
112
|
+
fini.
|
|
113
|
+
|
|
114
|
+
Le canevas est `aria-hidden` : un moteur émet des dizaines de nœuds de texte
|
|
115
|
+
SVG — graduations, pourcentages, infobulles — qu'un lecteur d'écran parcourt
|
|
116
|
+
un par un, dans l'ordre visuel, sans structure. C'est du bruit, et c'est PIRE
|
|
117
|
+
que le silence. **Corollaire contraignant** : aucun contrôle interactif ne va
|
|
118
|
+
dedans — `aria-hidden` sur un ancêtre focalisable produit un élément
|
|
119
|
+
atteignable au clavier et inannonçable, ce qui échoue à WCAG 4.1.2 plus
|
|
120
|
+
franchement que le bruit évité. Un sélecteur de période se met À CÔTÉ.
|
|
121
|
+
`hideCanvasFromScreenReaders={false}` reste l'issue pour un moteur qui
|
|
122
|
+
construit sa propre table de données navigable.
|
|
123
|
+
|
|
124
|
+
Rendu à travers `Surface component="figure"`, dont le docblock pointait déjà
|
|
125
|
+
ici : « Surface deliberately has NO title, NO actions and NO header … Those
|
|
126
|
+
compose this. » La légende est un `figcaption` VISIBLE, pas une chaîne
|
|
127
|
+
masquée : les chiffres servent aussi au lecteur qui voit le graphe — c'est
|
|
128
|
+
l'objet même d'un `figcaption` — et une légende que personne ne voit est une
|
|
129
|
+
légende dont personne ne remarque qu'elle a vieilli.
|
|
130
|
+
|
|
131
|
+
**Relevé depuis `autorisation-admis-pour-conforme-fe` (Area 5)** : trois
|
|
132
|
+
écrans répétant `Surface` + `SectionHeader` + un canevas `aria-hidden` + un
|
|
133
|
+
paragraphe de légende, styles de légende (`--text-xs`, `--fg-subtle`) recopiés
|
|
134
|
+
avec.
|
|
135
|
+
|
|
136
|
+
Surface : `chartChrome` par `@portnet/ui/tokens` (le baril de tokens, qui est
|
|
137
|
+
la route que les modules utilisent déjà pour `chartCategorical` — il n'y a
|
|
138
|
+
pas de liste de noms explicite à tenir à jour de ce côté) ; `ChartFigure` +
|
|
139
|
+
`ChartFigureProps` par `patterns`, donc par la racine plate.
|
|
140
|
+
Purement additif. Tests : `__tests__/ChartFigure.test.tsx`.
|
|
141
|
+
|
|
142
|
+
- **`AppMain` — le landmark `<main>` (gap G-53).**
|
|
143
|
+
|
|
144
|
+
La librairie livrait **la moitié** d'un contrat en deux parties, et
|
|
145
|
+
prescrivait l'autre moitié sans la fournir. Le docblock de `SkipLink` dit,
|
|
146
|
+
mot pour mot :
|
|
147
|
+
|
|
148
|
+
<SkipLink href="#main-content" />
|
|
149
|
+
…
|
|
150
|
+
<main id="main-content">
|
|
151
|
+
|
|
152
|
+
Ce `<main>` n'a jamais existé ici. Chaque module l'écrivait donc, et ce n'est
|
|
153
|
+
pas une ligne : il porte trois choses faciles à rater subtilement —
|
|
154
|
+
`tabIndex={-1}`, sans quoi le lien d'évitement FAIT DÉFILER mais ne déplace
|
|
155
|
+
pas le focus sous Safari (`SkipLink` compense d'ailleurs en posant l'attribut
|
|
156
|
+
lui-même au clic, rustine pour un landmark qui aurait dû être focalisable
|
|
157
|
+
d'origine) ; `outline: none`, parce qu'un anneau de focus dessiné autour de
|
|
158
|
+
toute la page n'est pas ce que R-F.1 demande ; et **la mesure de contenu de
|
|
159
|
+
R-L.5**, un MUST que la librairie n'honorait nulle part — `PageContent` tient
|
|
160
|
+
le padding canonique et l'espacement des sections, et **ne plafonne rien**,
|
|
161
|
+
si bien qu'un module certifié étalait encore ses tableaux d'un bord à l'autre
|
|
162
|
+
d'un écran 1920 px.
|
|
163
|
+
|
|
164
|
+
Et le plafond a un compagnon que personne ne retient : **sans
|
|
165
|
+
`margin-inline: auto`**, le contenu plafonné se colle à gauche et laisse une
|
|
166
|
+
gouttière de 480 px à droite, ce qui paraît plus cassé que de ne pas
|
|
167
|
+
plafonner.
|
|
168
|
+
|
|
169
|
+
**Relevé depuis `autorisation-admis-pour-conforme-fe` (Area 5)** — et le
|
|
170
|
+
module de référence certifié `ms-ti-fe` porte le même landmark local : deux
|
|
171
|
+
copies des mêmes vingt lignes, plus un MUST non tenu.
|
|
172
|
+
|
|
173
|
+
Périmètre, puisque §07 est explicite : la Sidebar et la Topbar globale
|
|
174
|
+
relèvent du shell HÔTE, pas d'un module et pas de ce composant. `AppMain` est
|
|
175
|
+
la région de contenu À L'INTÉRIEUR de ce shell. Il ne rend ni fil d'Ariane ni
|
|
176
|
+
en-tête de page : ceux-là portent titre, sous-titre et actions propres à la
|
|
177
|
+
route, donc l'`ActionBar` de chaque page (R-L.1 / R-L.2).
|
|
178
|
+
|
|
179
|
+
Surface : `AppMain`, `AppMainProps`, `AppMainMeasure`. `measure` vaut `wide`
|
|
180
|
+
(`--content-max`) par défaut, `form` (`--form-max`) pour un formulaire
|
|
181
|
+
mono-colonne, `full` pour ne pas plafonner — à justifier au point d'appel,
|
|
182
|
+
R-L.5 étant un MUST et non un défaut. Tests :
|
|
183
|
+
`__tests__/AppMain.test.tsx`, dont l'appariement de bout en bout avec
|
|
184
|
+
`SkipLink`, qui n'avait jamais pu être exercé que dans du code de module.
|
|
185
|
+
|
|
186
|
+
- **Validation des téléversements — `getFileRejection`, `isForbiddenExecutable`,
|
|
187
|
+
`isAcceptedFile`, `describeAcceptedTypes`, `toAcceptAttribute` (gap G-52).**
|
|
188
|
+
|
|
189
|
+
`Dropzone` accepte un attribut `accept` et rapporte des rejets, mais **ne
|
|
190
|
+
valide rien** : `accept` est un filtre de SÉLECTEUR DE FICHIERS, pas un
|
|
191
|
+
contrôle — le glisser-déposer l'ignore, et « Tous les fichiers » dans le
|
|
192
|
+
sélecteur l'ignore aussi sur la plupart des plateformes. La librairie
|
|
193
|
+
demandait donc à chaque hôte de décider lui-même, et chaque hôte écrivait
|
|
194
|
+
trois choses côte à côte : sa liste blanche d'extensions (politique métier,
|
|
195
|
+
légitimement la sienne), **une liste de refus des exécutables et scripts**, et
|
|
196
|
+
**un contrôle croisé extension / type MIME** avec ses tolérances navigateur.
|
|
197
|
+
|
|
198
|
+
Les deux dernières ne sont pas de la politique métier. C'est UNE décision de
|
|
199
|
+
sécurité, et une décision de sécurité recopiée dans chaque module dérivera :
|
|
200
|
+
le jour où un type doit rejoindre la liste de refus, personne ne peut dire
|
|
201
|
+
lesquels des quinze modules GU l'ont reçu. Et la divergence y est SILENCIEUSE
|
|
202
|
+
— un module qui manque une entrée ressemble exactement à un module qui l'a,
|
|
203
|
+
jusqu'au téléversement.
|
|
204
|
+
|
|
205
|
+
D'où la découpe : **l'hôte décide quelles extensions son métier accepte ; la
|
|
206
|
+
librairie tient la liste de refus et le contrôle croisé.**
|
|
207
|
+
|
|
208
|
+
**Relevé depuis `autorisation-admis-pour-conforme-fe` (Area 5)**, qui portait
|
|
209
|
+
localement une liste de refus de 21 extensions et une table MIME de six
|
|
210
|
+
extensions.
|
|
211
|
+
|
|
212
|
+
Trois décisions inscrites dans le fichier :
|
|
213
|
+
- la table MIME **n'est pas** `getMimeType` de `./fileDownload`, bien que les
|
|
214
|
+
deux associent extensions et types. Celle-là répond « quel type estampiller
|
|
215
|
+
sur ce Blob » (UNE valeur canonique) ; celle-ci répond « quels types un
|
|
216
|
+
navigateur peut plausiblement annoncer » (un ENSEMBLE, incluant des
|
|
217
|
+
variantes non enregistrées comme `image/jpg`, que les navigateurs envoient
|
|
218
|
+
quand même). Les confondre refuserait des fichiers valides ;
|
|
219
|
+
- `application/octet-stream` est toléré pour les documents Office : sans cette
|
|
220
|
+
tolérance, un `.docx` légitime est refusé sur certains postes, et de façon
|
|
221
|
+
INTERMITTENTE — le pire cas à diagnostiquer depuis un ticket ;
|
|
222
|
+
- une extension inconnue de la table est acceptée sur sa seule extension : la
|
|
223
|
+
table est un contrôle croisé, pas une seconde liste blanche, et un hôte qui
|
|
224
|
+
ajoute un format à sa politique ne doit pas être refusé par une table qu'il
|
|
225
|
+
ne voit pas.
|
|
226
|
+
|
|
227
|
+
**Ne remplace pas la validation serveur**, et c'est écrit dans le fichier :
|
|
228
|
+
tout ceci s'exécute dans un navigateur que l'utilisateur contrôle. Le but est
|
|
229
|
+
de donner une raison claire et immédiate (R-4.1, R-4.4) au lieu d'un rejet
|
|
230
|
+
serveur après téléversement complet.
|
|
231
|
+
|
|
232
|
+
**Pas d'option de taille maximale**, alors qu'elle aurait été tentante :
|
|
233
|
+
aucun consommateur n'en a la même forme aujourd'hui, et la leçon de G-51 vient
|
|
234
|
+
d'être apprise — une option publique sans consommateur réel est de la surface
|
|
235
|
+
spéculative (§2.8).
|
|
236
|
+
|
|
237
|
+
Flat-only, ajouté à `lib/index.ts` dans le même commit (invariant G-34).
|
|
238
|
+
Tests : `__tests__/fileValidation.test.ts`.
|
|
239
|
+
|
|
240
|
+
- **`fmtDate` / `fmtDateTime` — rendu d'une date pour l'AFFICHAGE (gap G-51).**
|
|
241
|
+
|
|
242
|
+
La librairie tenait déjà le versant monétaire du même travail — `fmtMoney`,
|
|
243
|
+
même dossier, même « — » pour une valeur absente, pour la même raison : une
|
|
244
|
+
cellule de tableau ne doit jamais afficher « NaN ». Elle ne tenait RIEN pour
|
|
245
|
+
les dates, que les écrans GU rendent bien plus souvent que des montants.
|
|
246
|
+
Chaque module écrivait donc le sien, et toutes les copies partageaient le
|
|
247
|
+
même défaut :
|
|
248
|
+
|
|
249
|
+
const date = new Date(stringDate);
|
|
250
|
+
const day = formatIntoTwoDigits(date.getDate());
|
|
251
|
+
|
|
252
|
+
`new Date(undefined)` est une date INVALIDE dont tous les accesseurs rendent
|
|
253
|
+
`NaN` : le helper affichait littéralement **« NaN/NaN/NaN NaN:NaN »** sur
|
|
254
|
+
n'importe quel champ facultatif — date de mise à jour, de visite, de clôture,
|
|
255
|
+
c'est-à-dire la majorité d'entre eux.
|
|
256
|
+
|
|
257
|
+
**Relevé depuis `autorisation-admis-pour-conforme-fe` (Area 5)**, où la garde
|
|
258
|
+
avait été ajoutée à HUIT POINTS D'APPEL au fil de quatre lots avant d'être
|
|
259
|
+
remontée dans le helper du module : le formateur est le seul endroit où elle
|
|
260
|
+
ne peut pas être oubliée, et c'est l'argument pour qu'il vive ici.
|
|
261
|
+
|
|
262
|
+
Deux corrections mineures par construction : un helper à deux chiffres qui
|
|
263
|
+
rendait `"08"` (chaîne) ou `12` (nombre) selon la valeur, et une date absente
|
|
264
|
+
rendue en chaîne VIDE — indiscernable d'une cellule non rendue, là où « — »
|
|
265
|
+
dit « on a regardé, il n'y a rien ». L'option `absent` permet malgré tout la
|
|
266
|
+
chaîne vide là où c'est un choix délibéré (une colonne de grille qui doit
|
|
267
|
+
rester visuellement silencieuse).
|
|
268
|
+
|
|
269
|
+
**Une option retirée après vérification.** Le premier jet exposait aussi
|
|
270
|
+
`separator`, justifié par un helper du module documenté comme alimentant les
|
|
271
|
+
critères de recherche, « d'où le séparateur paramétrable ». Un `grep` du
|
|
272
|
+
module montre que ce helper n'a **aucun importateur** : la justification était
|
|
273
|
+
du code mort, et le réglage était donc de la surface spéculative sur une API
|
|
274
|
+
certifiée (§2.8 — minimum API surface). Retiré avant publication.
|
|
275
|
+
|
|
276
|
+
**Pas de `moment`, bien que le paquet en dépende déjà.** `moment` est là pour
|
|
277
|
+
les sélecteurs, et précisément pour du parsing STRICT contre un format
|
|
278
|
+
explicite (`patterns/_pickerSerialisation`) : c'est son bon usage. Rendre un
|
|
279
|
+
instant déjà parsé en deux nombres et une année n'en est pas un — ce dossier
|
|
280
|
+
est sans dépendance à dessein, et `moment(chaîne)` sans format retombe sur
|
|
281
|
+
`new Date` EN ÉMETTANT UN AVERTISSEMENT DE DÉPRÉCIATION en console, bruit
|
|
282
|
+
qu'un helper appelé une fois par cellule ne doit pas produire.
|
|
283
|
+
|
|
284
|
+
**Fuseau, énoncé plutôt que sous-entendu** : la sortie est dans le fuseau du
|
|
285
|
+
LECTEUR, comme le faisaient les helpers remplacés. Un instant `…T23:30:00Z`
|
|
286
|
+
se lit donc le lendemain à Casablanca. Si un écran a besoin du jour calendaire
|
|
287
|
+
du serveur, c'est une AUTRE fonction — basculer celle-ci en UTC décalerait
|
|
288
|
+
des dates d'un jour sur toute la plateforme.
|
|
289
|
+
|
|
290
|
+
Surface : `fmtDate`, `fmtDateTime`, `FmtDateInput`, `FmtDateOptions`, sur la
|
|
291
|
+
racine plate. Ajoutées à `lib/index.ts` DANS LE MÊME COMMIT que l'entrée du
|
|
292
|
+
baril — invariant G-34, ce baril étant re-exporté par liste de noms
|
|
293
|
+
explicite. Purement additif. Tests : `__tests__/fmtDate.test.ts`.
|
|
294
|
+
|
|
295
|
+
- **`reviveSavedCriteria` — relecture d'un `SavedFilter.criteria` persisté (gap G-50).**
|
|
296
|
+
|
|
297
|
+
`criteria` est OPAQUE à dessein, et ce choix est bon : `savedFilters` le
|
|
298
|
+
stocke et le réémet verbatim, ce qui rend le cadre utilisable par toutes les
|
|
299
|
+
listes quel que soit leur schéma de filtres. Mais **l'aller-retour n'est pas
|
|
300
|
+
symétrique, et l'asymétrie est celle de la librairie** :
|
|
301
|
+
`createLocalStorageAdapter` écrit avec `JSON.stringify` — donc une `Date`
|
|
302
|
+
part en chaîne ISO — et relit avec un `JSON.parse` **sans reviver**.
|
|
303
|
+
|
|
304
|
+
Tout hôte qui persiste une date récupérait donc une chaîne, dans un champ que
|
|
305
|
+
ses propres types déclarent `Date`. Deux conséquences, silencieuses toutes
|
|
306
|
+
les deux : la chaîne arrive telle quelle dans `<DatePicker value>`, et elle
|
|
307
|
+
part telle quelle dans les critères envoyés au back-end. Le typage ne pouvait
|
|
308
|
+
pas l'attraper, puisque la seule façon d'affecter la charge utile relue dans
|
|
309
|
+
un état de formulaire typé est une conversion — qui éteint précisément
|
|
310
|
+
l'erreur qui l'aurait révélée.
|
|
311
|
+
|
|
312
|
+
**Relevé depuis `autorisation-admis-pour-conforme-fe` (Area 5)** : NEUF
|
|
313
|
+
écrans de liste convertissaient la charge utile DEUX FOIS dans leur `onApply`
|
|
314
|
+
— une conversion simple ne compilait pas. C'est la forme que prend un manque
|
|
315
|
+
de la librairie sous un typecheck strict.
|
|
316
|
+
|
|
317
|
+
Ferme aussi un effet plus discret : un filtre enregistré sous une forme
|
|
318
|
+
ANTÉRIEURE (clé renommée, champ retiré) était étalé tel quel dans l'état du
|
|
319
|
+
formulaire, clés inconnues comprises ; les clés admises sont désormais celles
|
|
320
|
+
des valeurs par défaut fournies par l'appelant.
|
|
321
|
+
|
|
322
|
+
**Pas corrigé dans l'adaptateur, délibérément** : un reviver dans
|
|
323
|
+
`createLocalStorageAdapter` s'appliquerait à TOUTES les charges utiles de
|
|
324
|
+
capacité — préférences de grille, favoris — et devrait deviner quelles
|
|
325
|
+
chaînes sont des dates pour des données dont il ne sait rien. La relecture
|
|
326
|
+
appartient à l'endroit où la forme est connue, c'est-à-dire là où l'hôte
|
|
327
|
+
passe ses propres valeurs par défaut. L'adaptateur distant à venir en
|
|
328
|
+
bénéficie aussi.
|
|
329
|
+
|
|
330
|
+
Contrainte écrite `Record<keyof TValues, unknown>` et non
|
|
331
|
+
`Record<string, unknown>` : la seconde n'est satisfaite que par les ALIAS de
|
|
332
|
+
type, et cinq des neuf formulaires concernés déclarent leur forme en
|
|
333
|
+
`interface`. La contrainte mappée accepte les deux, donc aucune conversion ne
|
|
334
|
+
remonte au point d'appel — vérifié par un test de niveau type.
|
|
335
|
+
|
|
336
|
+
Surface : `reviveSavedCriteria`, racine plate et
|
|
337
|
+
`@portnet/ui/personalization`. Conformément à la politique de dépréciation de
|
|
338
|
+
`./v2`, la capacité n'est PAS ajoutée à `v2/index.ts`. Purement additif.
|
|
339
|
+
Tests : `__tests__/reviveSavedCriteria.test.ts`.
|
|
340
|
+
|
|
341
|
+
- **`usePrefersReducedMotion` — lecture RUNTIME de `prefers-reduced-motion` (gap G-49).**
|
|
342
|
+
|
|
343
|
+
R-7.5 / R-Tg.2 sont respectées partout où la librairie POSSÈDE l'animation
|
|
344
|
+
(`motion.ts`, feuille de base, `Skeleton` R-Sk.4). Ce qui manquait, c'est la
|
|
345
|
+
lecture en JS, pour l'animation qu'elle ne possède pas : un graphe, un
|
|
346
|
+
canvas, un défilement impératif, un widget tiers configuré par options. CSS
|
|
347
|
+
ne répond pas à ces cas — la décision est une valeur passée à une autre
|
|
348
|
+
librairie.
|
|
349
|
+
|
|
350
|
+
Chaque hôte écrivait donc le même helper, et **toutes les copies observées
|
|
351
|
+
portaient les deux mêmes défauts** : la valeur est lue UNE FOIS pendant un
|
|
352
|
+
rendu qui peut ne jamais se reproduire (activer la préférence en cours de
|
|
353
|
+
session ne coupait donc rien), et elle est lue PENDANT le rendu, hors de
|
|
354
|
+
l'état React, si bien que deux composants d'une même page peuvent diverger.
|
|
355
|
+
`useSyncExternalStore` traite les deux, et fournit un instantané serveur au
|
|
356
|
+
lieu d'un garde `typeof window` recopié à chaque appel.
|
|
357
|
+
|
|
358
|
+
**Relevé depuis `autorisation-admis-pour-conforme-fe` (Area 4 — détection
|
|
359
|
+
d'infrastructure UI locale)** : trois copies identiques du helper, une par
|
|
360
|
+
écran de bilan.
|
|
361
|
+
|
|
362
|
+
Surface : `usePrefersReducedMotion` (défaut) +
|
|
363
|
+
`PREFERS_REDUCED_MOTION_QUERY`, atteignables par la racine plate et par
|
|
364
|
+
`@portnet/ui/hooks`. Purement additif. Tests :
|
|
365
|
+
`__tests__/usePrefersReducedMotion.test.tsx` — dont la non-régression de
|
|
366
|
+
l'abonnement, que jsdom seul ne peut pas exercer (il n'évalue pas les
|
|
367
|
+
requêtes média).
|
|
368
|
+
|
|
369
|
+
> Numéro de gap **G-49** retenu comme premier libre au vu des en-têtes du
|
|
370
|
+
> dépôt (plus haut référencé : G-48). À confirmer par l'équipe DS si un
|
|
371
|
+
> registre central existe ailleurs.
|
|
372
|
+
|
|
373
|
+
### Fixed
|
|
374
|
+
|
|
375
|
+
- **`Field` — tout `Select` était SANS NOM ACCESSIBLE (R-I.1, WCAG 4.1.2 / 1.3.1).**
|
|
376
|
+
|
|
377
|
+
`Field` n'associait son libellé que par `htmlFor` / `id`. Cette paire ne nomme
|
|
378
|
+
que les éléments **étiquetables** — `input`, `select`, `textarea`, `button`,
|
|
379
|
+
`meter`, `output`, `progress`. `Select` rend sa surface visible en
|
|
380
|
+
`div[role="combobox"]`, qui n'en fait pas partie : l'association était donc
|
|
381
|
+
**nulle**, et un lecteur d'écran annonçait « liste déroulante, réduite » sans
|
|
382
|
+
jamais dire de quel champ il s'agissait.
|
|
383
|
+
|
|
384
|
+
Le code portait son hypothèse fautive en commentaire : « a single labelable
|
|
385
|
+
control is named by the htmlFor/id pair below » — vrai d'un `<input>`, faux de
|
|
386
|
+
la moitié des contrôles de cette librairie. **Tous les tiroirs de filtres et
|
|
387
|
+
tous les formulaires de tous les modules étaient concernés**, et rien à
|
|
388
|
+
l'écran ne le montrait : le libellé était là, au bon endroit, de la bonne
|
|
389
|
+
couleur.
|
|
390
|
+
|
|
391
|
+
**Trouvé par la suite axe-core d'`autorisation-admis-pour-conforme-fe`**
|
|
392
|
+
(Area 10), qui a échoué sur `aria-input-field-name` au premier `Select` rendu.
|
|
393
|
+
|
|
394
|
+
LE CORRECTIF PASSE PAR `labelId`, LE CANAL DE MUI. Une première tentative
|
|
395
|
+
passait `aria-labelledby` à tous les enfants : elle ne fonctionne pas et
|
|
396
|
+
casse autre chose. MUI répand les props inconnues sur son **wrapper racine**,
|
|
397
|
+
donc l'attribut atterrissait sur `div.MuiInputBase-root` et jamais sur le
|
|
398
|
+
contrôle — le combobox restait anonyme, tandis que pour `Input` le wrapper
|
|
399
|
+
devenait un SECOND élément porteur du libellé, ce qui est faux pour les
|
|
400
|
+
technologies d'assistance et suffit à casser n'importe quel `getByLabelText`
|
|
401
|
+
dans les tests d'un hôte (deux suites du socle sont tombées ainsi).
|
|
402
|
+
`SelectInput` fusionne `labelId` dans l'`aria-labelledby` du combobox : c'est
|
|
403
|
+
le seul chemin qui atteigne l'élément.
|
|
404
|
+
|
|
405
|
+
`labelId` n'est transmis qu'aux enfants qui **déclarent** le consommer, via le
|
|
406
|
+
marqueur statique `puiLabelTarget` porté par `Select`. Un `labelId` passé à
|
|
407
|
+
l'aveugle atteindrait `<input>` et les champs texte de MUI, qui ne le
|
|
408
|
+
connaissent pas : React avertirait alors d'un attribut DOM inconnu à chaque
|
|
409
|
+
rendu, dans la console de chaque hôte. **Tout composant de cette librairie
|
|
410
|
+
dont la surface visible n'est pas étiquetable doit porter ce marqueur.**
|
|
411
|
+
|
|
412
|
+
LIMITE CONNUE, énoncée parce qu'elle est asymétrique avec R-I.3 : un
|
|
413
|
+
`aria-labelledby` fourni par l'appelant sur un enfant non-`group` n'est pas
|
|
414
|
+
fusionné dans le nom. `aria-describedby`, lui, l'est. Rien n'est perdu en
|
|
415
|
+
silence — le champ est nommé par son propre libellé — mais un hôte qui veut
|
|
416
|
+
AJOUTER au nom doit passer par `label`.
|
|
417
|
+
|
|
418
|
+
Tests : `__tests__/FieldNaming.test.tsx`, qui couvre le contrôle natif (pour
|
|
419
|
+
que le correctif ne le régresse pas), le `Select`, l'astérisque des champs
|
|
420
|
+
requis exclu du nom, et le mode `group`.
|
|
421
|
+
|
|
422
|
+
- **Pagination de `DataGrid` — cibles tactiles des quatre boutons de navigation
|
|
423
|
+
(R-7.4 / WCAG 2.5.5).**
|
|
424
|
+
|
|
425
|
+
Les mêmes `IconButton size="small"` sans plancher que ceux de l'en-tête de
|
|
426
|
+
`Drawer`, corrigés juste avant — mais dans la barre de pagination de **chaque
|
|
427
|
+
liste** du portefeuille, quatre par barre. Environ 34 px là où
|
|
428
|
+
`tokens/density` impose 44.
|
|
429
|
+
|
|
430
|
+
Le rapprochement des deux est le vrai constat : la règle est écrite dans les
|
|
431
|
+
tokens (« Icon-only buttons MUST set min-width/min-height to `tactileMin` »)
|
|
432
|
+
et **aucun** composant de la librairie qui rend des boutons d'icône ne
|
|
433
|
+
l'appliquait. Le défaut est systémique, pas ponctuel : une règle que la
|
|
434
|
+
librairie impose à ses hôtes sans se l'imposer à elle-même.
|
|
435
|
+
|
|
436
|
+
`min-width`/`min-height` et non `width`/`height` : la zone d'appui grandit,
|
|
437
|
+
le dessin de l'icône ne change pas. Valeur lue sur `var(--tactile-min)`,
|
|
438
|
+
comme le voisin `HEADER_CHECKBOX_CELL_SX`, et non réécrite en dur.
|
|
439
|
+
|
|
440
|
+
Relevé depuis `autorisation-admis-pour-conforme-fe` (Area 10).
|
|
441
|
+
|
|
442
|
+
**Signalé sans correction** : le sélecteur « lignes par page » de cette même
|
|
443
|
+
barre porte `height: 28`. Pour lui, la boîte visuelle EST la zone d'appui,
|
|
444
|
+
donc la remonter à 44 px change le dessin de la barre dans toutes les listes
|
|
445
|
+
du portefeuille : c'est une décision de design et non une correction de
|
|
446
|
+
défaut. La note vit dans `_dataGridShared.tsx`, à l'endroit où elle se
|
|
447
|
+
prendra.
|
|
448
|
+
|
|
449
|
+
Vérifié au passage, et donc non modifié : la pagination annonce déjà ses
|
|
450
|
+
changements de page — région vivante `polite` et `atomic` sur l'intervalle,
|
|
451
|
+
si bien qu'un lecteur d'écran entend « 26–50 sur 100 » en paginant.
|
|
452
|
+
|
|
453
|
+
- **`Drawer` — cibles tactiles de l'en-tête sous le plancher (R-7.4 / WCAG 2.5.5).**
|
|
454
|
+
|
|
455
|
+
Le docblock de `tokens/density` énonce la règle sans ambiguïté : « Icon-only
|
|
456
|
+
buttons MUST set min-width/min-height to `tactileMin` », parce que la hauteur
|
|
457
|
+
VISUELLE d'un bouton peut descendre sous 44 px dans les paliers de densité
|
|
458
|
+
serrés sans que la zone d'appui le puisse. Les trois boutons d'icône de
|
|
459
|
+
l'en-tête de `Drawer` — précédent, suivant, fermer — étaient des
|
|
460
|
+
`IconButton size="small"` avec une seule règle de couleur : environ 34 px,
|
|
461
|
+
soit dix de moins que le minimum que cette librairie impose à ses hôtes.
|
|
462
|
+
|
|
463
|
+
**La librairie édictait la règle dans ses tokens et la violait dans son
|
|
464
|
+
propre composant.**
|
|
465
|
+
|
|
466
|
+
L'écart est resté invisible tant que la navigation entre items était peu
|
|
467
|
+
câblée : un tiroir de filtres ne rend que le bouton de fermeture. Relevé
|
|
468
|
+
depuis `autorisation-admis-pour-conforme-fe` (Area 9), qui vient d'équiper
|
|
469
|
+
ses dix aperçus de `onPrev`/`onNext` — trois cibles sous-dimensionnées par
|
|
470
|
+
tiroir, sur dix écrans.
|
|
471
|
+
|
|
472
|
+
`min-width`/`min-height` et non `width`/`height` : la zone d'appui grandit,
|
|
473
|
+
le dessin de l'icône ne change pas — exactement la distinction que fait la
|
|
474
|
+
note de `tokens/density`. Les valeurs viennent du token `layout.tactileMin`
|
|
475
|
+
et non d'un littéral, pour que le plancher suive le token s'il bouge.
|
|
476
|
+
|
|
477
|
+
Tests : `__tests__/DrawerTactileTargets.test.tsx`, dont le cas du bouton
|
|
478
|
+
DÉSACTIVÉ — une flèche inerte reste une cible que l'utilisateur vise, et la
|
|
479
|
+
rétrécir ferait sauter la rangée d'un tiroir à l'autre.
|
|
480
|
+
|
|
481
|
+
- **`--field-w-*` : cinq largeurs de champ annoncées comme révisables, jamais émises.**
|
|
482
|
+
|
|
483
|
+
`Field.FIELD_MAX_WIDTH` consomme `var(--field-w-s, 200px)` et le docblock de
|
|
484
|
+
`Field` affirme que les cinq valeurs sont « exposées en variables CSS pour
|
|
485
|
+
être revues sans toucher au code » — l'échappatoire prévue pour une décision
|
|
486
|
+
que ce même docblock signale comme à confirmer par l'équipe design.
|
|
487
|
+
|
|
488
|
+
`cssVariables` n'émettait aucune de ces variables. **Seuls les replis ont
|
|
489
|
+
jamais rendu**, donc les cinq gabarits étaient impossibles à réviser sans
|
|
490
|
+
modifier le code, et la promesse était fausse. Le rendu, lui, était correct :
|
|
491
|
+
c'est une lacune de révisabilité, pas un défaut visuel — ce qui explique
|
|
492
|
+
qu'elle ait survécu.
|
|
493
|
+
|
|
494
|
+
C'est la SEPTIÈME occurrence de la classe A7-02, dont la note dans
|
|
495
|
+
`cssVariables` dit exactement ceci : « six token names were referenced
|
|
496
|
+
fleet-wide that this emitter never emitted, so their var() fallbacks were the
|
|
497
|
+
only thing that ever rendered (R-2.3 / R-AI.1 magic values wearing a token's
|
|
498
|
+
name) ». Le correctif A7-02 avait traité l'interlettrage et laissé celle-ci.
|
|
499
|
+
|
|
500
|
+
Les valeurs sont promues dans `tokens.layout.fieldWidth` — une seule source —
|
|
501
|
+
et émises par `cssVariables`. Les replis de `Field` RESTENT : un hôte qui
|
|
502
|
+
n'appelle jamais `injectCssVariables` doit continuer à rendre des largeurs
|
|
503
|
+
correctes. Les deux doivent donc rester d'accord.
|
|
504
|
+
|
|
505
|
+
`xl` n'est délibérément pas tokenisé : ce gabarit vaut `100%`, une largeur
|
|
506
|
+
relative et non une valeur de la grille. En faire un token en pixels
|
|
507
|
+
inviterait à lui donner un plafond qu'il ne doit pas avoir.
|
|
508
|
+
|
|
509
|
+
**Relevé depuis `addm-fe` (Area 4 — détection d'infrastructure UI locale).**
|
|
510
|
+
Le module n'avait aucun token local ; c'est en vérifiant que chaque `var()`
|
|
511
|
+
qu'il consomme existe réellement côté socle que l'absence est apparue.
|
|
512
|
+
|
|
513
|
+
- **`DataGrid` : une action de ligne déclenchait AUSSI le clic de ligne.**
|
|
514
|
+
|
|
515
|
+
La cellule d'actions est un descendant de la ligne, qui porte
|
|
516
|
+
`onClick={() => onRowClick(row)}` et un `onKeyDown`. Elle n'arrêtait ni l'un
|
|
517
|
+
ni l'autre. Sur toute grille où `onRowClick` et `rowActions` coexistent —
|
|
518
|
+
c'est-à-dire tout listing de la plateforme, puisque §Row Interaction fait du
|
|
519
|
+
clic de ligne l'ouverture du drawer d'aperçu et des actions l'affordance
|
|
520
|
+
complémentaire — activer une action produisait l'action ET un drawer qui
|
|
521
|
+
s'ouvre par-dessus.
|
|
522
|
+
|
|
523
|
+
**Ce n'était pas rattrapable au niveau de l'action.** `buildRowActions` /
|
|
524
|
+
`buildRowActionMenu` décrivent une action comme `onClick: (row) => void` et
|
|
525
|
+
n'exposent délibérément pas l'événement DOM — un descripteur métier n'a pas à
|
|
526
|
+
connaître la propagation — et le déclencheur d'`OverflowMenu` est dans la
|
|
527
|
+
même position. La cellule est donc le seul endroit qui puisse tenir
|
|
528
|
+
l'invariant pour TOUTES les formes : le kebab, la rangée d'icônes
|
|
529
|
+
(`iconsUpTo`), et n'importe quel renderer `rowActions` écrit par un hôte.
|
|
530
|
+
|
|
531
|
+
La cellule de sélection, juste à côté, arrête ces deux événements depuis
|
|
532
|
+
toujours, et pour exactement cette raison. Des deux cellules interactives
|
|
533
|
+
d'une ligne, une seule était gardée.
|
|
534
|
+
|
|
535
|
+
`stopPropagation` et non `preventDefault` : l'activation propre des boutons,
|
|
536
|
+
Entrée/Espace sur une action focalisée comprise, est inchangée.
|
|
537
|
+
|
|
538
|
+
**Relevé depuis `addm-fe` (Area 3).** Ses deux listings avaient écrit leur
|
|
539
|
+
rangée d'icônes à la main spécifiquement pour appeler `stopPropagation()`
|
|
540
|
+
bouton par bouton — ce qui faisait passer l'adoption de `buildRowActions`
|
|
541
|
+
(G-41) pour une régression, et explique pourquoi cette fabrique était restée
|
|
542
|
+
non adoptée là-bas. Le défaut n'était donc pas seulement latent : il
|
|
543
|
+
BLOQUAIT la déduplication qu'il rendait nécessaire.
|
|
544
|
+
|
|
545
|
+
`DataGridVirtualized` n'est pas concerné : il n'expose pas `rowActions`.
|
|
546
|
+
|
|
547
|
+
Test de régression : `__tests__/DataGridRowActionsPropagation.test.tsx`,
|
|
548
|
+
qui couvre les deux formes et les deux chemins (souris et clavier), plus le
|
|
549
|
+
cas inverse — une cellule de données doit continuer à déclencher le clic de
|
|
550
|
+
ligne, sans quoi un containment posé trop haut passerait le test tout en
|
|
551
|
+
cassant §Row Interaction.
|
|
552
|
+
|
|
553
|
+
### Added
|
|
554
|
+
|
|
555
|
+
- **`ReferentielField` : `container="drawer"` et `searchOnOpen` — deux capacités qui bloquaient l'adoption du pattern (S-1, S-2).**
|
|
556
|
+
|
|
557
|
+
Ces deux absences n'étaient pas des manques de confort : elles rendaient le
|
|
558
|
+
pattern INADOPTABLE pour un hôte conforme, qui gardait donc sa propre
|
|
559
|
+
implémentation.
|
|
560
|
+
|
|
561
|
+
**S-1 — le conteneur était en dur.** R-M.5 est explicite : « Drawer plutôt que
|
|
562
|
+
Modal pour ≥ 3 champs ou contenu défilable long ». Un sélecteur à critères
|
|
563
|
+
PLUS une grille paginée satisfait les deux branches, et §Drawer Pattern
|
|
564
|
+
réserve par ailleurs le drawer à la « consultation rapide » — ce qu'est le
|
|
565
|
+
choix d'une ligne de référentiel. Le pattern rendait un `Modal`, et
|
|
566
|
+
`modalProps` étant un `Partial<ComponentProps<typeof Modal>>`, aucun réglage
|
|
567
|
+
ne pouvait le changer. Un hôte qui LIT R-M.5 devait donc choisir entre la
|
|
568
|
+
charte et le pattern.
|
|
569
|
+
|
|
570
|
+
Défaut inchangé (`"modal"`) : aucun appelant existant ne bouge. Le corps est
|
|
571
|
+
extrait en UNE expression partagée par les deux enveloppes, donc recherche,
|
|
572
|
+
sélection et pagination ne peuvent pas diverger entre conteneurs. Dans la
|
|
573
|
+
branche drawer, `footer` devient `actions` (même emplacement, autre nom),
|
|
574
|
+
`size` n'a pas d'équivalent — un drawer est borné par sa largeur — et
|
|
575
|
+
`modalProps` n'est délibérément PAS transmis : son type est celui de `Modal`,
|
|
576
|
+
le faire fuiter sur un `Drawer` serait un mensonge de typage.
|
|
577
|
+
|
|
578
|
+
**S-2 — pas de recherche à l'ouverture.** « Saisissez un critère puis lancez
|
|
579
|
+
la recherche » est le bon état initial quand la population est trop grande
|
|
580
|
+
pour être listée — le cas d'usage que décrit l'en-tête du fichier. Mais
|
|
581
|
+
certaines populations sont COURTES et CONNUES : les mandatants habilités d'un
|
|
582
|
+
transitaire, une nomenclature paginée par cinq. La réponse attendue y est la
|
|
583
|
+
liste. `initialCriteria` ne couvrait pas ce besoin — il sème les critères sans
|
|
584
|
+
déclencher d'appel.
|
|
585
|
+
|
|
586
|
+
La garde est un `ref` et non de l'état, et c'est le point délicat :
|
|
587
|
+
`runSearch` dépend de `draft`, donc un effet naïf repartirait à chaque frappe
|
|
588
|
+
dans un critère — une requête par caractère, exactement ce que le bouton
|
|
589
|
+
« Rechercher » existe pour éviter. Les critères semés sont par ailleurs
|
|
590
|
+
passés EXPLICITEMENT à `runSearch`, qui lirait sinon le `draft` du rendu
|
|
591
|
+
courant, non encore appliqué par l'effet d'ouverture.
|
|
592
|
+
|
|
593
|
+
Tests : `__tests__/ReferentielFieldContainer.test.tsx`. L'assertion centrale
|
|
594
|
+
n'est pas que la recherche initiale part, mais qu'elle part UNE SEULE FOIS —
|
|
595
|
+
une saisie dans un critère ne doit pas la rappeler.
|
|
596
|
+
|
|
597
|
+
**Relevé depuis `addm-fe` (Areas 3 et 5).** Ce module gardait deux sélecteurs
|
|
598
|
+
locaux de ~14 Ko chacun, et l'Area 3 avait conclu à tort que la raison était
|
|
599
|
+
une contrainte de valeur primitive — c'est celle de `FormikCombobox`, pas de
|
|
600
|
+
ce pattern, qui est objet par contrat. Les vraies raisons étaient ces deux-ci.
|
|
601
|
+
|
|
602
|
+
- **`TabPanel` + `tabDomId` / `tabPanelDomId` — l'autre moitié du contrat `Tabs` (G-46).**
|
|
603
|
+
|
|
604
|
+
`Tabs` émet la moitié ONGLET de R-Ar.6 : chaque onglet porte son `id` et un
|
|
605
|
+
`aria-controls` vers `pui-panel-<id>`. L'élément qui doit porter cet id — avec
|
|
606
|
+
`role="tabpanel"` et un `aria-labelledby` en retour — était laissé à l'hôte,
|
|
607
|
+
et la library ne fournissait rien pour lui.
|
|
608
|
+
|
|
609
|
+
Le format des ids était donc une connaissance PRIVÉE que chaque hôte
|
|
610
|
+
réécrivait en chaîne littérale. Une faute de frappe y est invisible : le
|
|
611
|
+
balisage reste valide et l'onglet annonce simplement un élément contrôlé qui
|
|
612
|
+
n'existe pas. **Un `aria-controls` cassé est pire que son absence** — la
|
|
613
|
+
technologie d'assistance propose à l'utilisateur une relation qu'elle ne peut
|
|
614
|
+
ensuite pas suivre.
|
|
615
|
+
|
|
616
|
+
`tabDomId` / `tabPanelDomId` sont exportées avec le composant, et `Tabs` les
|
|
617
|
+
consomme désormais lui aussi : la convention n'a plus qu'UNE définition, et un
|
|
618
|
+
hôte qui a besoin de son propre panneau (virtualisé, animé) en dérive les ids
|
|
619
|
+
au lieu d'en refaire une copie.
|
|
620
|
+
|
|
621
|
+
DEUX DÉCISIONS LAISSÉES À L'HÔTE, délibérément :
|
|
622
|
+
|
|
623
|
+
- **Le montage.** `TabPanel` ne connaît pas l'onglet actif et ne se masque pas
|
|
624
|
+
lui-même. Un hôte qui monte ses panneaux conditionnellement garde un DOM
|
|
625
|
+
léger ; un hôte qui doit préserver l'état des panneaux inactifs les rend
|
|
626
|
+
tous et masque lui-même. Imposer le second forcerait ce comportement sur
|
|
627
|
+
tout le monde, et un panneau `hidden` resté dans le DOM change ce qu'un
|
|
628
|
+
lecteur d'écran énumère.
|
|
629
|
+
- **`focusable`**, par défaut `true` : l'APG exige qu'un tabpanel soit
|
|
630
|
+
focalisable quand il ne contient AUCUN élément focalisable, pour qu'un
|
|
631
|
+
utilisateur clavier atteigne le contenu après avoir parcouru la tablist. Un
|
|
632
|
+
panneau de texte `KV` en lecture seule est exactement ce cas, et c'est le
|
|
633
|
+
cas courant sur une page de consultation.
|
|
634
|
+
|
|
635
|
+
**Relevé depuis `addm-fe` (Area 5).** Sa page de consultation rendait ses
|
|
636
|
+
panneaux en `{tab === "x" && <…/>}` nus — les deux onglets pointaient dans le
|
|
637
|
+
vide — puis un `TabPanel` local avait été écrit **en relisant la convention
|
|
638
|
+
dans la source de `Tabs`**. C'est la preuve même que la connaissance était
|
|
639
|
+
requise et non publiée.
|
|
640
|
+
|
|
641
|
+
- **`HStepperRichStep` / `HStepperStep` — une asymétrie de surface typée, fermée.**
|
|
642
|
+
|
|
643
|
+
Le bloc `StepStatus` du barrel surface l'union des statuts d'étape ET, du côté vertical, `VStepperItem` — avec cette justification : « le même consommateur construit les objets dans lesquels l'union vit ». Le côté HORIZONTAL n'avait reçu que l'union.
|
|
644
|
+
|
|
645
|
+
L'argument est pourtant mot pour mot le même : un hôte qui pilote `HStepper` en mode riche construit des objets `{ id, label, status }`, et dans un `.map()` le ternaire de statut s'élargit en `string` tant que le type de retour n'est pas annoté — la prop est alors refusée. Sans le type d'étape, il ne restait que deux issues : redéclarer la forme localement (la duplication que ce bloc existe précisément pour éviter), ou l'atteindre par `ComponentProps<typeof HStepper>["steps"][number]`, un accès indexé qui ne dit rien de l'intention.
|
|
646
|
+
|
|
647
|
+
`HStepperStep` accompagne : c'est ce que prend réellement la prop `steps` — l'union « libellé simple ou étape riche » — donc le type nécessaire à qui annote la VARIABLE tableau plutôt que le callback de `map`.
|
|
648
|
+
|
|
649
|
+
**Relevé depuis `addm-fe` (Area 2).** `DemandeStepper` pilote les trois étapes du wizard en mode riche ; la migration TypeScript a bloqué net sur cette absence. À noter que le module était en JavaScript jusque-là : la lacune existait depuis que le mode riche existe, et seul un consommateur typé pouvait la révéler.
|
|
650
|
+
|
|
651
|
+
Additif et type-only : aucun changement d'exécution, aucun export existant modifié.
|
|
652
|
+
|
|
653
|
+
- **`FormikDisplay.width` — le seul champ de la library qui ne portait pas de gabarit (G-H, suite).**
|
|
654
|
+
|
|
655
|
+
`Field.width` (entree ci-dessous) est relaye par tous les ponts de saisie. `FormikDisplay` ne passait pas — et ne pouvait pas passer — par ce relais : il ne s'appuie PAS sur `Field`, il rend sa propre boite, parce qu'un champ en lecture seule n'a ni controle a nommer par `htmlFor` ni erreur a decrire.
|
|
656
|
+
|
|
657
|
+
**Consequence concrete : un formulaire melant saisie et affichage produisait le defaut que le standard nomme.** Les `FormikInput` s'arretaient a leur plafond (400px en `m`), les `FormikDisplay` voisins remplissaient toute la cellule de grille — c'est-a-dire le « jagged right-side layout edge » explicitement interdit par la section « Form Field Width & Layout Standards », et la « Homogeneous Field Rule » violee entre deux champs du meme bloc logique.
|
|
658
|
+
|
|
659
|
+
`FIELD_MAX_WIDTH` est IMPORTE de `Field`, pas recopie : deux tables de largeurs finiraient par diverger, et le plafond reste pose au palier `sm` seulement, pour la meme raison qu'ailleurs (le standard impose 100 % de la largeur de grille sur mobile).
|
|
660
|
+
|
|
661
|
+
**Releve depuis `addm-fe` (Area 2 — certification TypeScript).** `EntrepriseStep` passait `width` a ses NEUF champs en lecture seule depuis sa modernisation UI, et la prop etait ignoree en silence : la conformite annoncee de cette section ne tenait en realite que pour ses trois champs saisissables. A noter, parce que l'entree `Field.width` ci-dessous affirme l'inverse — « une prop non declaree echoue a la compilation, donc rien ne se perd en silence » : c'est vrai du consommateur TYPESCRIPT. `addm-fe` etait en JavaScript, la prop se perdait donc bel et bien sans bruit, et c'est sa migration qui l'a fait apparaitre. La garantie vaut ce que vaut le typage du module qui consomme.
|
|
662
|
+
|
|
663
|
+
Retrocompatible : sans `width`, aucun plafond n'est pose.
|
|
664
|
+
|
|
665
|
+
- **`Field.width` — les cinq gabarits de largeur semantique du standard (G-H).**
|
|
666
|
+
|
|
667
|
+
La section « Form Field Width & Layout Standards » des Platform Mandatory UX Patterns impose de rattacher chaque champ a l'un de cinq gabarits d'apres sa contrainte de CARACTERES (`xs` 1-5, `s` 6-15, `m` 16-60, `l` 61-256, `xl` au-dela), et y interdit explicitement les « arbitrary input field widths » et les « jagged alignment fields within forms ».
|
|
668
|
+
|
|
669
|
+
**La library n'avait rien pour l'exprimer.** `FormGrid` raisonne en COLONNES (1/2/3/4, ou `minColumnWidth`), `FormGrid.Item span` en colonnes, et `Input` n'expose ni largeur ni taille. Un module voulant s'y conformer n'avait donc que le `sx` — c'est-a-dire precisement les « local UI tokens » que le meme document interdit. Releve depuis `refonte-frontend` (lot 8), ou l'audit de conformite a constate que la section entiere n'avait pas pu etre appliquee.
|
|
670
|
+
|
|
671
|
+
**Sur `Field`, et non sur chaque controle.** Le gabarit est une contrainte de MISE EN PAGE, pas une propriete de l'input : c'est la boite du champ — libelle, controle, indication, erreur — qui doit etre bornee, sinon le message d'erreur s'etale sur toute la cellule pendant que l'input est borne. `Field` est le seul endroit qui voit cette boite entiere.
|
|
672
|
+
|
|
673
|
+
**Un plafond, et seulement a partir de `sm`.** Le standard exige aussi l'empilement a 100 % de la largeur de grille sur mobile, et l'alignement des champs heterogenes sur des fractions de colonnes. Avec un `maxWidth` pose au palier tablette, la grille continue de decider des COLONNES et le gabarit borne le champ DANS sa cellule : les deux regles coexistent au lieu de se contredire.
|
|
674
|
+
|
|
675
|
+
**Les cinq valeurs sont une decision de design, pas une lecture.** Le standard donne des fourchettes (« ~80px to 120px max »). Le HAUT de chacune a ete retenu, ces largeurs etant des plafonds : prendre le bas tronquerait des valeurs qui tiennent dans la contrainte de caracteres annoncee. Elles passent par des variables CSS (`--field-w-xs` a `--field-w-l`) pour etre revues sans modification de code, et `FIELD_MAX_WIDTH` est exporte pour que le test les epingle — le plafond etant pose derriere une requete media, jsdom ne peut pas lire la largeur effective, seule la story le montre.
|
|
676
|
+
|
|
677
|
+
Relaye par `FormikInput`, `FormikTextarea`, `FormikSelect`, `FormikCombobox`, `FormikDatePicker` et `FormikDateTimePicker`, chacun documentant le gabarit que le standard associe a SON type de controle (les « simple dropdowns » en `m`, les « long dropdowns » et les « complex search auto-completes » en `l`, les dates en `s`). `FormikReferentielField` ne le relaie pas encore : une prop non declaree echoue a la compilation, donc rien ne se perd en silence.
|
|
678
|
+
|
|
679
|
+
Retrocompatible : sans `width`, aucun plafond n'est pose.
|
|
680
|
+
- **`FormikDateTimePicker` — le pont date + HEURE qui manquait (G-E).**
|
|
681
|
+
|
|
682
|
+
`FormikDatePicker` etait le SEUL pont de date de la library, et il est date-seule. Sa propre note d'audit le disait : « DateTimePicker, TimePicker and DateRangePicker are exposed as bare components ». Un hote ayant besoin de l'heure n'avait donc que deux options : la perdre, ou recabler `useField` + le `DateTimePicker` nu.
|
|
683
|
+
|
|
684
|
+
**Perdre l'heure n'est pas un compromis d'affichage : ca change ce que recoit le backend.** Releve depuis `refonte-frontend` (lot 7). Le formulaire de visite physique stocke une date de visite portant une heure et soumet `moment(valeur).format("YYYY-MM-DD HH:mm")`. Passe par le pont date-seule, toute visite aurait ete programmee a 00:00 — silencieusement, sans erreur nulle part, et seul l'agent se presentant a la mauvaise heure l'aurait fini par decouvrir. Le test unitaire epingle les deux comportements cote a cote, pour que la raison d'etre des deux ponts reste lisible.
|
|
685
|
+
|
|
686
|
+
Et recabler a la main, c'est la duplication interdite par R-2.1, dans la forme ou les messages de validation disparaissent — meme histoire que G-A et G-C.
|
|
687
|
+
|
|
688
|
+
**Au passage, `coerceToDate` / `serialiseDate` sortent en module interne partage** (`patterns/_pickerSerialisation`), consommees par les DEUX ponts. Aucun changement de comportement : le code est deplace, pas modifie.
|
|
689
|
+
|
|
690
|
+
Ce n'est pas du rangement. La note S-03 de `FormikDatePicker` documente ce qui arrive quand la LECTURE et l'ECRITURE d'une date divergent : un « 31-12-2026 » relu par `new Date()` devient Invalid Date, un « 05-03-2026 » devient le 3 mai au lieu du 5 mars. Le chemin d'ecriture fonctionne, donc le degat n'apparait qu'a la RELECTURE — en modification, le parcours qu'un test de fumee n'exerce jamais. Un module a livre ce defaut pendant sept lots sous un typecheck strict. Deux copies privees de ce couple auraient recree la meme classe de bug, sous une forme encore moins visible : deux ponts qui se ressemblent, que personne ne compare, et qui ont l'air corrects isolement.
|
|
691
|
+
|
|
692
|
+
- **`FormikRadioGroup` — le pont qui manquait pour un groupe de radios (G-C).**
|
|
693
|
+
|
|
694
|
+
R-Sel.2 est un MUST : 2-3 options -> Radio ou Segmented, jamais un Select. Toute question metier binaire passe donc obligatoirement par `RadioGroup` — qui n'avait aucun pont Formik, la ou `FormikSelect`, `FormikCombobox`, `FormikCheckboxGroup`, `FormikDatePicker`, `FormikTextarea`, `FormikFile` et `FormikInput` en ont tous un. Les hotes recablaient donc `useField` + `RadioGroup` a la main, avec la meme consequence que pour G-A : le controle est rendu, `FieldError` est oublie. Releve depuis `refonte-frontend` (lot 5), ou UN formulaire portait deux de ces groupes.
|
|
695
|
+
|
|
696
|
+
**Le contrat qui compte est invisible : la valeur ecrite est celle DECLAREE dans `options`, pas la chaine que rapporte le DOM.** Un `<input type="radio">` ne rapporte jamais qu'une chaine. Un hote dont les options sont numeriques — `{ value: 1 }`, `{ value: 2 }` — et dont le payload declare un nombre se mettrait a envoyer `"1"` des le premier clic. L'API l'accepte, ou le refuse trois jours plus tard ; rien dans l'interface ne le signale. Le pont reapparie donc la chaine du DOM contre la liste d'options et ecrit la valeur d'origine. La chaine brute ne passe qu'a defaut de correspondance — perdre le clic de l'utilisateur serait pire.
|
|
697
|
+
|
|
698
|
+
Symetriquement, la SELECTION se compare en chaine : un champ portant le booleen `false` selectionne l'option declaree `"false"`, un champ portant `2` selectionne `{ value: 2 }`. C'est le cas des hotes qui initialisent en booleen et transmettent du texte au backend. La valeur STOCKEE n'est jamais reecrite par cette comparaison — un formulaire ouvert puis ferme sans reponse transmet exactement ce dont il a ete amorce.
|
|
699
|
+
|
|
700
|
+
Le champ est marque touche AU CLIC : pour un groupe de radios, la premiere interaction EST la reponse, il n'y a pas de blur-avant-changement. Attendre un blur laisserait le message d'un groupe requis cache pendant que l'utilisateur clique.
|
|
701
|
+
|
|
702
|
+
`required` est porte par le CHAMP et non par les options : `Field` rend l'asterisque sur le libelle du groupe et injecte `aria-required`, valide sur `role="radiogroup"` — contrairement au cas de la case a cocher seule (G-A), ou l'injection atterrissait sur un conteneur qui ne la transmet pas.
|
|
703
|
+
|
|
704
|
+
- **`FormikCheckbox` — le pont qui manquait pour une case a cocher BOOLEENNE (G-A).**
|
|
705
|
+
|
|
706
|
+
`FormikCheckboxGroup` existait deja, et il porte un TABLEAU de valeurs selectionnees. C'est le bon modele pour « choisir plusieurs dans une liste », et le mauvais pour un drapeau seul. Un hote dont l'etat est `autreInfo.fabrication: boolean` ou `objectDeclaration.premiereDeclaration: boolean` ne peut pas l'adopter sans changer la forme de ce que son payload envoie au backend.
|
|
707
|
+
|
|
708
|
+
**Consequence observee** : faute de pont, les modules recablaient `Checkbox` + `useField` a la main. C'est la duplication que R-2.1 interdit, et elle a coute exactement ce que coutent les ponts artisanaux — le rendu de l'erreur. Releve depuis `refonte-frontend` (lot 5) : ses champs cables main n'affichaient AUCUN message de validation, si bien qu'une erreur sur un champ requis etait invisible pour l'utilisateur (R-4.1 MUST). Le defaut ne se voit ni a la relecture ni sur une capture : les pixels sont corrects, seul le message manque.
|
|
709
|
+
|
|
710
|
+
Trois details du contrat valent d'etre notes, parce qu'ils ne sont pas devinables :
|
|
711
|
+
|
|
712
|
+
La case est enveloppee dans un `CheckboxGroup`, comme le fait `FormikCheckboxGroup`, et pour la meme raison : `Field` clone son enfant avec `error` / `disabled`, que `MuiCheckbox` propagerait jusqu'a l'`<input>` natif (avertissement React, attribut DOM invalide). `CheckboxGroup` destructure ses props explicitement et absorbe le reste.
|
|
713
|
+
|
|
714
|
+
Le libelle nomme la CASE, via `FormControlLabel`, et non le champ : une case seule portant un libelle de champ ET un libelle de controle se lit comme deux questions. `Field` ne recoit donc pas de `label`, et `required` s'exprime la ou il compte — asterisque sur le libelle du controle, `aria-required` sur l'`<input>` (l'injection de `Field` atterrit sur le groupe, qui ne la transmet pas).
|
|
715
|
+
|
|
716
|
+
Le champ est marque touche AU CHANGEMENT, pas au blur. Une case n'a pas de blur-avant-changement significatif : attendre un blur garderait le message cache quel que soit le nombre de clics.
|
|
717
|
+
|
|
718
|
+
`checked` compare a `true` explicitement : les hotes initialisent ces drapeaux a `null` (« pas encore repondu »), et `checked={null}` rend l'input non controle le temps d'un rendu.
|
|
719
|
+
|
|
720
|
+
- **`RowFavoriteToggle` — the follow star, reachable outside a DataGrid column (G-36).**
|
|
721
|
+
|
|
722
|
+
This component already existed. It was `FavoriteCell`, private inside `makeFavoriteColumn`, which made the follow control reachable at exactly one composition point: as a DataGrid column definition.
|
|
723
|
+
|
|
724
|
+
The other place a row always appears is the mobile card. `DataGrid` swaps to `renderMobileCard` below its `mobileBreakpoint`, and `MobileRowCard` has a `leading` slot for precisely this kind of per-row control — but a column definition cannot be rendered into a slot, so every host re-derived the star by hand. `onssa-export-fe` carried a local `MobileFavoriteToggle`; `ms-ti-fe` destructures the same `MobileRowCard` + `FavoriteToggle` + `useIsFavorite` trio for the same reason.
|
|
725
|
+
|
|
726
|
+
**Same failure mode as G-10**, one level down: the library owned the behaviour but exposed it at a single composition point, so consumers reimplemented it at the others.
|
|
727
|
+
|
|
728
|
+
**And the copy drifted exactly where drift is hardest to notice.** The local twin announced itself as "Ajouter aux favoris" / "Retirer des favoris" while the grid column *in the same list* announced "Suivre" / "Ne plus suivre", and it omitted the status tooltip entirely. One affordance, one list, two accessible names — selected by viewport width. R-2.1 MUST is "un même concept = un même composant + un même libellé partout"; a sighted user could not have seen this, and a screen-reader user met a different control on a phone than on a desktop.
|
|
729
|
+
|
|
730
|
+
`makeFavoriteColumn` now renders this component rather than a private twin, so the column and the card agree **by construction instead of by review**. `FavoriteColumnLabels` extends `RowFavoriteToggleLabels` and the column's defaults spread the shared ones, so the label set has one definition too.
|
|
731
|
+
|
|
732
|
+
Behaviour is carried over unchanged: action-oriented accessible name with `aria-pressed` for state, visible status on hover/focus via `Tooltip`, and click/keydown propagation stopped so toggling never fires the row's `onRowClick`. No change for existing `makeFavoriteColumn` callers.
|
|
733
|
+
|
|
734
|
+
- **`useGridPreferences` — per-user hidden columns, because a bare `localStorage` key is not a user (G-35).**
|
|
735
|
+
|
|
736
|
+
`DataGridToolbar` owns the column-visibility UI (`hiddenColumns` + `onHiddenColumnsChange`) but deliberately holds no state, so *persisting* the choice was left to the host. Every listing screen therefore reached for raw `localStorage` — `onssa-export-fe` had `"onssaCertificates:listing:hiddenColumns"`, hand-written `JSON.parse` included.
|
|
737
|
+
|
|
738
|
+
**The defect is not the duplication, it is the key.** This foundation partitions every capability as `portnet-ui:perso:v1:{tenantId?}:{userId}:{capabilityId}`; a host-invented key has no user segment. Favorites and saved filters were already immune because they route through the store — column visibility was the one grid preference that bypassed it. On a shared workstation, which is the norm at a port, user B inherited user A's hidden columns: a column A had hidden was simply absent for B, with nothing on screen to explain why. A preference silently became a data-visibility rule for someone else.
|
|
739
|
+
|
|
740
|
+
**This could not be fixed in a host, and that is a second finding.** `registerCapability` is exported as a "capability registration seam — for custom/host-defined capabilities", but the two primitives every capability hook needs, `usePersonalizationStore` and `useStoreSelector`, are private by design (architecture doc §2.8, minimum API surface). A host could register a descriptor and then had no way to read or write its payload. The seam is advertised without being complete. Completing it was rejected as the fix here: it would widen a certified library's internal surface *and* leave every module re-authoring the same slice. Owning the slice does neither — but the incomplete seam should either be finished or stop advertising itself.
|
|
741
|
+
|
|
742
|
+
Payload is `{ [resourceKey]: { hiddenColumns: string[] } }`, with the entry object rather than a bare array so column order and widths can join it later without a `schemaVersion` bump. The pure helpers rebuild only the touched `resourceKey` and shallow-copy the map, so structural sharing keeps every other resource referentially stable; the exposed `Set` is memoised on the stored array so its identity survives re-renders and does not defeat `DataGrid`'s memoisation.
|
|
743
|
+
|
|
744
|
+
`migrate` normalises on load even though v1 has no predecessor version — it is the trust boundary for a payload coming back from storage, and a column key is used to *hide* grid columns, so a number or an object from an older build (or from hand-edited devtools storage) must not reach the grid as if it were one. This absorbs, once, the validation each host was writing for itself.
|
|
745
|
+
|
|
746
|
+
Density is deliberately **not** part of this: `useDensity` owns it as a global, non-resource-scoped value and applies `data-density` to `<html>`, and folding it in would give one preference two owners.
|
|
747
|
+
|
|
748
|
+
**Known related debt, not addressed here.** `useDensity` (`portnet-ui-density`) and `useFormAutoSave` (host-supplied `storageKey`) both persist outside this foundation on unscoped keys, for the same reason G-35 existed. `useFormAutoSave` is the more serious of the two — a draft is keyed by resource id only, so on a shared workstation one user is offered another's unsubmitted form, business data included. Neither is fixed here: `storageKey` is a required public prop, so scoping it is a signature change (MAJOR under §10.1) affecting every module with a create form, and moving density into the foundation would change its storage key and make it require a provider. Both need their own RFC.
|
|
749
|
+
|
|
13
750
|
- **`SkeletonPageShell` — the route-level `Suspense` fallback R-P.1 requires (G-02).**
|
|
14
751
|
|
|
15
752
|
R-P.1 MUST says "routing avec `React.lazy` + `Suspense`, **fallback skeleton page**". The library shipped every skeleton *part* — `Skeleton`, `SkeletonRow`, `SkeletonKPI`, `SkeletonDetailHero`, `SkeletonTabContent`, `SkeletonText` — plus `PageBusy`, and yet nothing that satisfies the rule: `PageBusy` is a full-viewport spinner, which R-8.1 MUST forbids for navigation, and the parts are shaped for the inside of a page rather than the page frame.
|