@jmruthers/pace-core 0.2.7 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{DataTable-EEUDXPE5.js → DataTable-GX3XERFJ.js} +8 -4
- package/dist/{DataTable-C1AEm9Cx.d.ts → DataTable-ltTFXHS3.d.ts} +3 -1
- package/dist/{chunk-VYG4AXYW.js → chunk-5EL3KHOQ.js} +2 -2
- package/dist/{chunk-ETEJVKYK.js → chunk-6CR3MRZN.js} +1426 -62
- package/dist/chunk-6CR3MRZN.js.map +1 -0
- package/dist/chunk-AUE24LVR.js +268 -0
- package/dist/chunk-AUE24LVR.js.map +1 -0
- package/dist/chunk-COBPIXXQ.js +379 -0
- package/dist/chunk-COBPIXXQ.js.map +1 -0
- package/dist/{chunk-EWKPTNPO.js → chunk-GSNM5D6H.js} +388 -86
- package/dist/chunk-GSNM5D6H.js.map +1 -0
- package/dist/{chunk-2V3Y6YBC.js → chunk-OEGRKULD.js} +1 -42
- package/dist/chunk-OEGRKULD.js.map +1 -0
- package/dist/chunk-OYRY44Q2.js +62 -0
- package/dist/chunk-OYRY44Q2.js.map +1 -0
- package/dist/{chunk-RRUYHORU.js → chunk-T3XIA4AJ.js} +297 -433
- package/dist/chunk-T3XIA4AJ.js.map +1 -0
- package/dist/{chunk-HEMJ4SUJ.js → chunk-TGDCLPP2.js} +11 -7
- package/dist/{chunk-HEMJ4SUJ.js.map → chunk-TGDCLPP2.js.map} +1 -1
- package/dist/{chunk-HNDFPXUU.js → chunk-U6JDHVC2.js} +6 -4
- package/dist/{chunk-HNDFPXUU.js.map → chunk-U6JDHVC2.js.map} +1 -1
- package/dist/{chunk-TIVL4UQ7.js → chunk-XJK2J4N6.js} +6 -4
- package/dist/{chunk-TIVL4UQ7.js.map → chunk-XJK2J4N6.js.map} +1 -1
- package/dist/components.d.ts +2 -2
- package/dist/components.js +21 -20
- package/dist/components.js.map +1 -1
- package/dist/hooks.d.ts +1 -1
- package/dist/hooks.js +7 -7
- package/dist/index.d.ts +2 -2
- package/dist/index.js +26 -25
- package/dist/index.js.map +1 -1
- package/dist/providers.js +8 -7
- package/dist/rbac/index.d.ts +806 -806
- package/dist/rbac/index.js +937 -1179
- package/dist/rbac/index.js.map +1 -1
- package/dist/{types-DiRQsGJs.d.ts → types-BRDU7N6w.d.ts} +12 -1
- package/dist/utils.d.ts +2 -2
- package/dist/utils.js +6 -6
- package/docs/api/classes/ErrorBoundary.md +1 -1
- package/docs/api/classes/PublicErrorBoundary.md +1 -1
- package/docs/api/interfaces/AggregateConfig.md +4 -4
- package/docs/api/interfaces/ButtonProps.md +1 -1
- package/docs/api/interfaces/CardProps.md +1 -1
- package/docs/api/interfaces/ColorPalette.md +1 -1
- package/docs/api/interfaces/ColorShade.md +1 -1
- package/docs/api/interfaces/DataTableAction.md +21 -8
- package/docs/api/interfaces/DataTableColumn.md +1 -1
- package/docs/api/interfaces/DataTableProps.md +46 -33
- package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
- package/docs/api/interfaces/EmptyStateConfig.md +5 -5
- package/docs/api/interfaces/EventContextType.md +1 -1
- package/docs/api/interfaces/EventLogoProps.md +1 -1
- package/docs/api/interfaces/EventProviderProps.md +1 -1
- package/docs/api/interfaces/FileSizeLimits.md +1 -1
- package/docs/api/interfaces/FileUploadProps.md +1 -1
- package/docs/api/interfaces/FooterProps.md +1 -1
- package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
- package/docs/api/interfaces/InputProps.md +1 -1
- package/docs/api/interfaces/LabelProps.md +1 -1
- package/docs/api/interfaces/LoginFormProps.md +1 -1
- package/docs/api/interfaces/NavigationItem.md +1 -1
- package/docs/api/interfaces/NavigationMenuProps.md +1 -1
- package/docs/api/interfaces/Organisation.md +1 -1
- package/docs/api/interfaces/OrganisationContextType.md +1 -1
- package/docs/api/interfaces/OrganisationMembership.md +2 -2
- package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
- package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
- package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
- package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
- package/docs/api/interfaces/PaletteData.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
- package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
- package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
- package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
- package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
- package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
- package/docs/api/interfaces/StorageConfig.md +1 -1
- package/docs/api/interfaces/StorageFileInfo.md +1 -1
- package/docs/api/interfaces/StorageFileMetadata.md +1 -1
- package/docs/api/interfaces/StorageListOptions.md +1 -1
- package/docs/api/interfaces/StorageListResult.md +1 -1
- package/docs/api/interfaces/StorageUploadOptions.md +1 -1
- package/docs/api/interfaces/StorageUploadResult.md +1 -1
- package/docs/api/interfaces/StorageUrlOptions.md +1 -1
- package/docs/api/interfaces/StyleImport.md +1 -1
- package/docs/api/interfaces/ToastActionElement.md +1 -1
- package/docs/api/interfaces/ToastProps.md +1 -1
- package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
- package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
- package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
- package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
- package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
- package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
- package/docs/api/interfaces/UserEventAccess.md +1 -1
- package/docs/api/interfaces/UserMenuProps.md +1 -1
- package/docs/api/interfaces/UserProfile.md +1 -1
- package/docs/api/modules.md +3 -3
- package/package.json +5 -2
- package/src/__tests__/REBUILD_PLAN.md +223 -0
- package/src/__tests__/TESTING_GUIDELINES.md +341 -0
- package/src/__tests__/fixtures/mocks.ts +93 -0
- package/src/__tests__/helpers/component-test-utils.tsx +145 -0
- package/src/__tests__/helpers/test-utils.tsx +117 -0
- package/src/__tests__/integration/UserProfile.test.tsx +128 -0
- package/src/__tests__/setup.ts +37 -225
- package/src/__tests__/templates/component.test.template.tsx +97 -75
- package/src/__tests__/templates/hook.test.template.ts +173 -0
- package/src/__tests__/types/test.types.ts +106 -0
- package/src/components/Alert/Alert.test.tsx +496 -0
- package/src/components/Avatar/Avatar.test.tsx +484 -0
- package/src/components/Button/Button.test.tsx +662 -0
- package/src/components/Card/Card.test.tsx +593 -0
- package/src/components/Checkbox/Checkbox.test.tsx +461 -0
- package/src/components/DataTable/DataTable.tsx +9 -1
- package/src/components/DataTable/components/AccessDeniedPage.tsx +168 -0
- package/src/components/DataTable/components/ActionButtons.tsx +18 -1
- package/src/components/DataTable/components/DataTableCore.tsx +97 -11
- package/src/components/DataTable/components/DataTableToolbar.tsx +22 -10
- package/src/components/DataTable/components/UnifiedTableBody.tsx +33 -4
- package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -0
- package/src/components/DataTable/examples/HierarchicalExample.tsx +3 -0
- package/src/components/DataTable/examples/InitialPageSizeExample.tsx +3 -0
- package/src/components/DataTable/examples/PerformanceExample.tsx +3 -0
- package/src/components/DataTable/types.ts +39 -1
- package/src/components/Dialog/Dialog.test.tsx +1139 -0
- package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +752 -0
- package/src/components/FileUpload/FileUpload.test.tsx +665 -0
- package/src/hooks/useCounter.test.ts +135 -0
- package/src/rbac/index.ts +3 -3
- package/dist/chunk-2V3Y6YBC.js.map +0 -1
- package/dist/chunk-BEZRLNK3.js +0 -1744
- package/dist/chunk-BEZRLNK3.js.map +0 -1
- package/dist/chunk-ETEJVKYK.js.map +0 -1
- package/dist/chunk-EWKPTNPO.js.map +0 -1
- package/dist/chunk-OHXGNT3K.js +0 -21
- package/dist/chunk-OHXGNT3K.js.map +0 -1
- package/dist/chunk-RRUYHORU.js.map +0 -1
- package/src/__tests__/README.md +0 -404
- package/src/__tests__/debug-provider.unit.test.tsx +0 -67
- package/src/__tests__/e2e/workflows.test.tsx +0 -373
- package/src/__tests__/hybridPermissions.unit.test.tsx +0 -474
- package/src/__tests__/index.integration.test.ts +0 -491
- package/src/__tests__/mocks/MockAuthProvider-standalone.tsx +0 -47
- package/src/__tests__/mocks/MockAuthProvider.tsx +0 -63
- package/src/__tests__/mocks/enhancedSupabaseMock.ts +0 -252
- package/src/__tests__/mocks/index.test.ts +0 -23
- package/src/__tests__/mocks/index.ts +0 -16
- package/src/__tests__/mocks/mockAuth.ts +0 -155
- package/src/__tests__/mocks/mockSupabase.ts +0 -83
- package/src/__tests__/mocks/mockSupabaseClient.ts +0 -63
- package/src/__tests__/mocks/providers.tsx +0 -22
- package/src/__tests__/patterns/__tests__/testPatterns.test.ts +0 -394
- package/src/__tests__/patterns/testPatterns.ts +0 -124
- package/src/__tests__/performance/componentPerformance.performance.test.ts +0 -27
- package/src/__tests__/performance/index.ts +0 -24
- package/src/__tests__/performance/performanceValidation.performance.test.ts +0 -15
- package/src/__tests__/security/security.unit.test.tsx +0 -7
- package/src/__tests__/security/securityValidation.security.test.tsx +0 -153
- package/src/__tests__/setupTests.d.ts +0 -1
- package/src/__tests__/shared/componentTestUtils.tsx +0 -475
- package/src/__tests__/shared/errorHandlingTestUtils.ts +0 -107
- package/src/__tests__/shared/index.ts +0 -81
- package/src/__tests__/shared/integrationTestUtils.tsx +0 -375
- package/src/__tests__/shared/performanceTestUtils.tsx +0 -476
- package/src/__tests__/shared/testUtils.optimized.tsx +0 -685
- package/src/__tests__/simple.test.tsx +0 -20
- package/src/__tests__/test-utils/dataFactories.ts +0 -60
- package/src/__tests__/test-utils/index.ts +0 -6
- package/src/__tests__/typeSafety.unit.test.ts +0 -65
- package/src/__tests__/unifiedAuth.unit.test.tsx +0 -151
- package/src/__tests__/utils/accessibilityHelpers.ts +0 -254
- package/src/__tests__/utils/assertions.ts +0 -50
- package/src/__tests__/utils/deterministicHelpers.ts +0 -31
- package/src/__tests__/utils/edgeCaseConfig.test.ts +0 -75
- package/src/__tests__/utils/edgeCaseConfig.ts +0 -98
- package/src/__tests__/utils/mockHelpers.ts +0 -149
- package/src/__tests__/utils/mockLoader.ts +0 -101
- package/src/__tests__/utils/performanceHelpers.ts +0 -55
- package/src/__tests__/utils/performanceTestHelpers.ts +0 -68
- package/src/__tests__/utils/testDataFactories.ts +0 -28
- package/src/__tests__/utils/testIsolation.ts +0 -67
- package/src/__tests__/utils/visualTestHelpers.ts +0 -20
- package/src/__tests__/visual/__snapshots__/componentSnapshots.visual.test.tsx.snap +0 -68
- package/src/__tests__/visual/__snapshots__/componentVisuals.visual.test.tsx.snap +0 -14
- package/src/__tests__/visual/__snapshots__/visualRegression.test.tsx.snap +0 -217
- package/src/__tests__/visual/__snapshots__/visualRegression.visual.test.tsx.snap +0 -24
- package/src/__tests__/visual/componentSnapshots.visual.test.tsx +0 -33
- package/src/__tests__/visual/componentVisuals.visual.test.tsx +0 -12
- package/src/__tests__/visual/visualRegression.visual.test.tsx +0 -20
- package/src/components/Alert/__tests__/Alert.unit.test.tsx +0 -381
- package/src/components/Avatar/__tests__/Avatar.unit.test.tsx +0 -232
- package/src/components/Button/__tests__/Button.accessibility.test.tsx +0 -131
- package/src/components/Button/__tests__/Button.comprehensive.test.tsx +0 -721
- package/src/components/Button/__tests__/Button.unit.test.tsx +0 -189
- package/src/components/Button/__tests__/EventSelector.integration.test.tsx +0 -285
- package/src/components/Card/__tests__/Card.accessibility.test.tsx +0 -394
- package/src/components/Card/__tests__/Card.comprehensive.test.tsx +0 -599
- package/src/components/Card/__tests__/Card.integration.test.tsx +0 -673
- package/src/components/Card/__tests__/Card.performance.test.tsx +0 -546
- package/src/components/Card/__tests__/Card.unit.test.tsx +0 -330
- package/src/components/Card/__tests__/Card.visual.test.tsx +0 -599
- package/src/components/Card/__tests__/README.md +0 -211
- package/src/components/Checkbox/__tests__/Checkbox.unit.test.tsx +0 -520
- package/src/components/DataTable/__tests__/DataTable.errorHandling.test.tsx +0 -251
- package/src/components/DataTable/__tests__/DataTable.hierarchical.test.tsx +0 -680
- package/src/components/DataTable/__tests__/DataTable.infinite-loop.test.tsx +0 -323
- package/src/components/DataTable/__tests__/DataTable.integration.test.tsx +0 -716
- package/src/components/DataTable/__tests__/DataTable.performance.test.tsx +0 -589
- package/src/components/DataTable/__tests__/DataTable.permissions.test.tsx +0 -316
- package/src/components/DataTable/__tests__/DataTable.regressionFixes.test.tsx +0 -546
- package/src/components/DataTable/__tests__/DataTable.selection.controlled.test.tsx +0 -386
- package/src/components/DataTable/__tests__/DataTable.selection.test.tsx +0 -338
- package/src/components/DataTable/__tests__/DataTable.sorting.test.tsx +0 -321
- package/src/components/DataTable/__tests__/DataTable.userWorkflows.test.tsx +0 -320
- package/src/components/DataTable/__tests__/DataTable.workflowValidation.test.tsx +0 -583
- package/src/components/DataTable/__tests__/DataTable.workflows.test.tsx +0 -711
- package/src/components/DataTable/__tests__/performance-regression.test.tsx +0 -777
- package/src/components/DataTable/__tests__/performance.test.tsx +0 -365
- package/src/components/DataTable/components/__tests__/ActionButtons.unit.test.tsx +0 -150
- package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +0 -224
- package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.unit.test.tsx +0 -244
- package/src/components/DataTable/components/__tests__/DataTable.accessibility.test.tsx +0 -629
- package/src/components/DataTable/components/__tests__/DataTable.integration.test.tsx +0 -470
- package/src/components/DataTable/components/__tests__/DataTable.performance.test.tsx +0 -160
- package/src/components/DataTable/components/__tests__/DataTable.real.test.tsx +0 -251
- package/src/components/DataTable/components/__tests__/DataTable.security.test.tsx +0 -171
- package/src/components/DataTable/components/__tests__/DataTable.unit.test.tsx +0 -290
- package/src/components/DataTable/components/__tests__/DataTableBody.unit.test.tsx +0 -147
- package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.unit.test.tsx +0 -182
- package/src/components/DataTable/components/__tests__/DataTableModals.unit.test.tsx +0 -123
- package/src/components/DataTable/components/__tests__/EditableRow.unit.test.tsx +0 -660
- package/src/components/DataTable/components/__tests__/EmptyState.unit.test.tsx +0 -256
- package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -498
- package/src/components/DataTable/components/__tests__/FilterRow.unit.test.tsx +0 -112
- package/src/components/DataTable/components/__tests__/FilteringToggle.unit.test.tsx +0 -133
- package/src/components/DataTable/components/__tests__/GroupHeader.unit.test.tsx +0 -172
- package/src/components/DataTable/components/__tests__/GroupingDropdown.unit.test.tsx +0 -222
- package/src/components/DataTable/components/__tests__/ImportModal.unit.test.tsx +0 -780
- package/src/components/DataTable/components/__tests__/LoadingState.unit.test.tsx +0 -65
- package/src/components/DataTable/components/__tests__/PaginationControls.unit.test.tsx +0 -634
- package/src/components/DataTable/components/__tests__/StateComponents.unit.test.tsx +0 -48
- package/src/components/DataTable/components/__tests__/UnifiedTableBody.hierarchical.test.tsx +0 -541
- package/src/components/DataTable/components/__tests__/ViewRowModal.unit.test.tsx +0 -228
- package/src/components/DataTable/components/__tests__/VirtualizedDataTable.unit.test.tsx +0 -568
- package/src/components/DataTable/core/__tests__/ActionManager.unit.test.ts +0 -405
- package/src/components/DataTable/core/__tests__/ArchitectureIntegration.unit.test.tsx +0 -445
- package/src/components/DataTable/core/__tests__/ColumnFactory.unit.test.ts +0 -288
- package/src/components/DataTable/core/__tests__/ColumnManager.unit.test.ts +0 -623
- package/src/components/DataTable/core/__tests__/DataManager.unit.test.ts +0 -431
- package/src/components/DataTable/core/__tests__/DataTableContext.unit.test.tsx +0 -433
- package/src/components/DataTable/core/__tests__/LocalDataAdapter.unit.test.ts +0 -422
- package/src/components/DataTable/core/__tests__/PluginRegistry.unit.test.tsx +0 -207
- package/src/components/DataTable/core/__tests__/StateManager.unit.test.ts +0 -278
- package/src/components/DataTable/examples/__tests__/PerformanceExample.unit.test.tsx +0 -281
- package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.unit.test.ts +0 -407
- package/src/components/DataTable/hooks/__tests__/useColumnReordering.unit.test.ts +0 -679
- package/src/components/DataTable/utils/__tests__/debugTools.unit.test.ts +0 -267
- package/src/components/DataTable/utils/__tests__/errorHandling.unit.test.ts +0 -467
- package/src/components/DataTable/utils/__tests__/exportUtils.unit.test.ts +0 -380
- package/src/components/DataTable/utils/__tests__/flexibleImport.unit.test.ts +0 -233
- package/src/components/DataTable/utils/__tests__/performanceUtils.unit.test.ts +0 -414
- package/src/components/Dialog/__tests__/Dialog.accessibility.test.tsx +0 -521
- package/src/components/Dialog/__tests__/Dialog.auto-size.example.tsx +0 -157
- package/src/components/Dialog/__tests__/Dialog.enhanced.test.tsx +0 -538
- package/src/components/Dialog/__tests__/Dialog.unit.test.tsx +0 -1373
- package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +0 -151
- package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +0 -611
- package/src/components/ErrorBoundary/__tests__/ErrorBoundary.accessibility.test.tsx +0 -517
- package/src/components/ErrorBoundary/__tests__/ErrorBoundary.integration.test.tsx +0 -572
- package/src/components/ErrorBoundary/__tests__/ErrorBoundary.unit.test.tsx +0 -579
- package/src/components/EventSelector/__tests__/EventSelector.test.tsx +0 -528
- package/src/components/FileUpload/__tests__/FileUpload.integration.test.tsx +0 -992
- package/src/components/FileUpload/__tests__/FileUpload.real.test.tsx +0 -927
- package/src/components/FileUpload/__tests__/FileUpload.test.tsx +0 -855
- package/src/components/FileUpload/__tests__/FileUpload.unit.test.tsx +0 -1311
- package/src/components/FileUpload/__tests__/FileUpload.unmocked.test.tsx +0 -937
- package/src/components/Footer/__tests__/Footer.accessibility.test.tsx +0 -359
- package/src/components/Footer/__tests__/Footer.integration.test.tsx +0 -353
- package/src/components/Footer/__tests__/Footer.performance.test.tsx +0 -309
- package/src/components/Footer/__tests__/Footer.unit.test.tsx +0 -309
- package/src/components/Footer/__tests__/Footer.visual.test.tsx +0 -335
- package/src/components/Form/__tests__/Form.accessibility.test.tsx +0 -820
- package/src/components/Form/__tests__/Form.unit.test.tsx +0 -305
- package/src/components/Form/__tests__/FormErrorSummary.unit.test.tsx +0 -285
- package/src/components/Form/__tests__/FormFieldset.unit.test.tsx +0 -241
- package/src/components/Header/__tests__/Header.accessibility.test.tsx +0 -382
- package/src/components/Header/__tests__/Header.comprehensive.test.tsx +0 -509
- package/src/components/Header/__tests__/Header.unit.test.tsx +0 -335
- package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +0 -196
- package/src/components/InactivityWarningModal/__tests__/InactivityWarningModal.unit.test.tsx +0 -224
- package/src/components/Input/__tests__/Input.accessibility.test.tsx +0 -632
- package/src/components/Input/__tests__/Input.unit.test.tsx +0 -1121
- package/src/components/Label/__tests__/Label.accessibility.test.tsx +0 -239
- package/src/components/Label/__tests__/Label.unit.test.tsx +0 -331
- package/src/components/LoadingSpinner/__tests__/LoadingSpinner.accessibility.test.tsx +0 -116
- package/src/components/LoadingSpinner/__tests__/LoadingSpinner.unit.test.tsx +0 -144
- package/src/components/LoginForm/__tests__/LoginForm.accessibility.test.tsx +0 -201
- package/src/components/LoginForm/__tests__/LoginForm.unit.test.tsx +0 -119
- package/src/components/NavigationMenu/__tests__/NavigationMenu.accessibility.test.tsx +0 -378
- package/src/components/NavigationMenu/__tests__/NavigationMenu.enhanced.test.tsx +0 -768
- package/src/components/NavigationMenu/__tests__/NavigationMenu.integration.test.tsx +0 -576
- package/src/components/NavigationMenu/__tests__/NavigationMenu.performance.test.tsx +0 -585
- package/src/components/NavigationMenu/__tests__/NavigationMenu.real.component.test.tsx +0 -783
- package/src/components/NavigationMenu/__tests__/NavigationMenu.security.enhanced.test.tsx +0 -810
- package/src/components/NavigationMenu/__tests__/NavigationMenu.security.test.tsx +0 -494
- package/src/components/NavigationMenu/__tests__/NavigationMenu.unit.test.tsx +0 -331
- package/src/components/NavigationMenu/__tests__/NavigationMenu.userWorkflows.test.tsx +0 -347
- package/src/components/NavigationMenu/__tests__/NavigationMenu.workflows.test.tsx +0 -584
- package/src/components/OrganisationSelector/__tests__/OrganisationSelector.unit.test.tsx +0 -664
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +0 -288
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -893
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +0 -629
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -782
- package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -904
- package/src/components/PaceLoginPage/__tests__/PaceLoginPage.accessibility.test.tsx +0 -463
- package/src/components/PaceLoginPage/__tests__/PaceLoginPage.integration.test.tsx +0 -586
- package/src/components/PaceLoginPage/__tests__/PaceLoginPage.unit.test.tsx +0 -533
- package/src/components/PasswordReset/__tests__/PasswordChangeForm.accessibility.test.tsx +0 -408
- package/src/components/PasswordReset/__tests__/PasswordChangeForm.unit.test.tsx +0 -561
- package/src/components/PasswordReset/__tests__/PasswordReset.integration.test.tsx +0 -304
- package/src/components/PasswordReset/__tests__/PasswordResetForm.accessibility.test.tsx +0 -20
- package/src/components/PasswordReset/__tests__/PasswordResetForm.unit.test.tsx +0 -523
- package/src/components/PasswordReset/__tests__/__mocks__/UnifiedAuthProvider.ts +0 -29
- package/src/components/Print/__tests__/Print.comprehensive.test.tsx +0 -331
- package/src/components/PrintButton/__tests__/PrintButton.unit.test.tsx +0 -429
- package/src/components/PrintButton/__tests__/PrintButtonGroup.unit.test.tsx +0 -277
- package/src/components/PrintButton/__tests__/PrintToolbar.unit.test.tsx +0 -264
- package/src/components/PrintCard/__tests__/PrintCard.unit.test.tsx +0 -233
- package/src/components/PrintCard/__tests__/PrintCardContent.test.tsx +0 -284
- package/src/components/PrintCard/__tests__/PrintCardGrid.unit.test.tsx +0 -214
- package/src/components/PrintCard/__tests__/PrintCardImage.unit.test.tsx +0 -264
- package/src/components/PrintDataTable/__tests__/PrintDataTable.unit.test.tsx +0 -361
- package/src/components/PrintDataTable/__tests__/PrintTableGroup.unit.test.tsx +0 -314
- package/src/components/PrintDataTable/__tests__/PrintTableRow.unit.test.tsx +0 -362
- package/src/components/PrintFooter/__tests__/PrintFooter.unit.test.tsx +0 -500
- package/src/components/PrintFooter/__tests__/PrintFooterContent.unit.test.tsx +0 -321
- package/src/components/PrintFooter/__tests__/PrintFooterInfo.unit.test.tsx +0 -335
- package/src/components/PrintFooter/__tests__/PrintPageNumber.unit.test.tsx +0 -340
- package/src/components/PrintGrid/__tests__/PrintGrid.unit.test.tsx +0 -340
- package/src/components/PrintGrid/__tests__/PrintGridBreakpoint.unit.test.tsx +0 -261
- package/src/components/PrintGrid/__tests__/PrintGridContainer.unit.test.tsx +0 -338
- package/src/components/PrintGrid/__tests__/PrintGridItem.unit.test.tsx +0 -338
- package/src/components/PrintHeader/__tests__/PrintCoverHeader.unit.test.tsx +0 -309
- package/src/components/PrintHeader/__tests__/PrintHeader.unit.test.tsx +0 -202
- package/src/components/PrintLayout/__tests__/PrintLayout.unit.test.tsx +0 -238
- package/src/components/PrintPageBreak/__tests__/PrintPageBreak.unit.test.tsx +0 -263
- package/src/components/PrintPageBreak/__tests__/PrintPageBreakGroup.unit.test.tsx +0 -239
- package/src/components/PrintPageBreak/__tests__/PrintPageBreakIndicator.unit.test.tsx +0 -235
- package/src/components/PrintSection/__tests__/PrintColumn.unit.test.tsx +0 -385
- package/src/components/PrintSection/__tests__/PrintDivider.unit.test.tsx +0 -373
- package/src/components/PrintSection/__tests__/PrintSection.unit.test.tsx +0 -390
- package/src/components/PrintSection/__tests__/PrintSectionContent.unit.test.tsx +0 -321
- package/src/components/PrintSection/__tests__/PrintSectionHeader.unit.test.tsx +0 -334
- package/src/components/PrintText/__tests__/PrintText.unit.test.tsx +0 -351
- package/src/components/Progress/__tests__/Progress.accessibility.test.tsx +0 -240
- package/src/components/Progress/__tests__/Progress.unit.test.tsx +0 -242
- package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +0 -761
- package/src/components/PublicLayout/__tests__/PublicErrorBoundary.simplified.test.tsx +0 -228
- package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +0 -228
- package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +0 -459
- package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +0 -362
- package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +0 -522
- package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +0 -599
- package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +0 -513
- package/src/components/RBAC/__tests__/PagePermissionGuard.unit.test.tsx +0 -683
- package/src/components/RBAC/__tests__/RBAC.integration.test.tsx +0 -573
- package/src/components/RBAC/__tests__/RBACGuard.unit.test.tsx +0 -467
- package/src/components/RBAC/__tests__/RBACProvider.accessibility.test.tsx +0 -475
- package/src/components/RBAC/__tests__/RBACProvider.advanced.test.tsx +0 -569
- package/src/components/RBAC/__tests__/RBACProvider.integration.test.tsx +0 -352
- package/src/components/RBAC/__tests__/RBACProvider.unit.test.tsx +0 -128
- package/src/components/RBAC/__tests__/RoleBasedContent.unit.test.tsx +0 -657
- package/src/components/Select/__tests__/SearchableSelect.unit.test.tsx +0 -437
- package/src/components/Select/__tests__/Select.accessibility.test.tsx +0 -1202
- package/src/components/Select/__tests__/Select.actual.test.tsx +0 -774
- package/src/components/Select/__tests__/Select.comprehensive.test.tsx +0 -837
- package/src/components/Select/__tests__/Select.enhanced.test.tsx +0 -1101
- package/src/components/Select/__tests__/Select.integration.test.tsx +0 -772
- package/src/components/Select/__tests__/Select.performance.test.tsx +0 -695
- package/src/components/Select/__tests__/Select.real-world.test.tsx +0 -1046
- package/src/components/Select/__tests__/Select.search-algorithms.test.tsx +0 -968
- package/src/components/Select/__tests__/Select.unit.test.tsx +0 -647
- package/src/components/Select/__tests__/Select.utils.test.tsx +0 -890
- package/src/components/Table/__tests__/Table.accessibility.test.tsx +0 -233
- package/src/components/Table/__tests__/Table.unit.test.tsx +0 -235
- package/src/components/Toast/__tests__/Toast.accessibility.test.tsx +0 -238
- package/src/components/Toast/__tests__/Toast.integration.test.tsx +0 -699
- package/src/components/Toast/__tests__/Toast.unit.test.tsx +0 -750
- package/src/components/Tooltip/__tests__/Tooltip.accessibility.test.tsx +0 -121
- package/src/components/Tooltip/__tests__/Tooltip.unit.test.tsx +0 -185
- package/src/components/UserMenu/__tests__/UserMenu.accessibility.test.tsx +0 -139
- package/src/components/UserMenu/__tests__/UserMenu.integration.test.tsx +0 -188
- package/src/components/UserMenu/__tests__/UserMenu.unit.test.tsx +0 -458
- package/src/components/__tests__/EdgeCaseTesting.enhanced.test.tsx +0 -524
- package/src/components/__tests__/ErrorTesting.enhanced.test.tsx +0 -455
- package/src/components/__tests__/SuperAdminGuard.test.tsx +0 -456
- package/src/components/__tests__/SuperAdminGuard.unit.test.tsx +0 -456
- package/src/components/examples/__tests__/PermissionExample.unit.test.tsx +0 -360
- package/src/hooks/__tests__/hooks.integration.test.tsx +0 -575
- package/src/hooks/__tests__/useApiFetch.unit.test.ts +0 -115
- package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +0 -133
- package/src/hooks/__tests__/useDebounce.unit.test.ts +0 -82
- package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +0 -293
- package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +0 -385
- package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +0 -286
- package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +0 -838
- package/src/hooks/__tests__/usePermissionCache.unit.test.ts +0 -627
- package/src/hooks/__tests__/useRBAC.unit.test.ts +0 -911
- package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -537
- package/src/hooks/__tests__/useToast.unit.test.tsx +0 -62
- package/src/hooks/__tests__/useZodForm.unit.test.tsx +0 -37
- package/src/hooks/public/__tests__/usePublicEvent.test.tsx +0 -397
- package/src/hooks/public/__tests__/usePublicEventLogo.test.tsx +0 -690
- package/src/hooks/public/__tests__/usePublicRouteParams.test.tsx +0 -449
- package/src/providers/__tests__/EventProvider.unit.test.tsx +0 -768
- package/src/providers/__tests__/OrganisationProvider.basic.test.tsx +0 -116
- package/src/providers/__tests__/OrganisationProvider.unit.test.tsx +0 -1312
- package/src/providers/__tests__/UnifiedAuthProvider.inactivity.test.tsx +0 -601
- package/src/providers/__tests__/UnifiedAuthProvider.unit.test.tsx +0 -683
- package/src/providers/__tests__/index.unit.test.ts +0 -78
- package/src/rbac/__tests__/PagePermissionGuard.test.tsx +0 -673
- package/src/rbac/__tests__/README.md +0 -170
- package/src/rbac/__tests__/RoleBasedRouter.test.tsx +0 -709
- package/src/rbac/__tests__/TestContext.tsx +0 -72
- package/src/rbac/__tests__/__mocks__/cache.ts +0 -144
- package/src/rbac/__tests__/__mocks__/supabase.ts +0 -152
- package/src/rbac/__tests__/adapters-hooks-comprehensive.test.tsx +0 -782
- package/src/rbac/__tests__/adapters-hooks.test.tsx +0 -561
- package/src/rbac/__tests__/adapters.comprehensive.test.tsx +0 -963
- package/src/rbac/__tests__/adapters.test.tsx +0 -444
- package/src/rbac/__tests__/api.test.ts +0 -620
- package/src/rbac/__tests__/audit-observability-comprehensive.test.ts +0 -792
- package/src/rbac/__tests__/audit-observability.test.ts +0 -549
- package/src/rbac/__tests__/audit.test.ts +0 -616
- package/src/rbac/__tests__/build-contract-compliance-simple.test.ts +0 -230
- package/src/rbac/__tests__/cache-invalidation-comprehensive.test.ts +0 -889
- package/src/rbac/__tests__/cache-invalidation.test.ts +0 -457
- package/src/rbac/__tests__/cache.test.ts +0 -458
- package/src/rbac/__tests__/components-navigation-guard.enhanced.test.tsx +0 -859
- package/src/rbac/__tests__/components-navigation-guard.test.tsx +0 -895
- package/src/rbac/__tests__/components-navigation-provider.test.tsx +0 -692
- package/src/rbac/__tests__/components-page-permission-guard.test.tsx +0 -673
- package/src/rbac/__tests__/components-page-permission-provider.test.tsx +0 -614
- package/src/rbac/__tests__/components-permission-enforcer.enhanced.fixed.test.tsx +0 -836
- package/src/rbac/__tests__/components-permission-enforcer.enhanced.test.tsx +0 -837
- package/src/rbac/__tests__/components-permission-enforcer.test.tsx +0 -825
- package/src/rbac/__tests__/components-role-based-router.test.tsx +0 -709
- package/src/rbac/__tests__/components-secure-data-provider.test.tsx +0 -607
- package/src/rbac/__tests__/config.test.ts +0 -583
- package/src/rbac/__tests__/core-logic-unit.test.ts +0 -190
- package/src/rbac/__tests__/core-permission-logic-comprehensive.test.ts +0 -1467
- package/src/rbac/__tests__/core-permission-logic-fixed.test.ts +0 -151
- package/src/rbac/__tests__/core-permission-logic-simple.test.ts +0 -968
- package/src/rbac/__tests__/core-permission-logic.test.ts +0 -966
- package/src/rbac/__tests__/edge-cases-comprehensive.test.ts +0 -988
- package/src/rbac/__tests__/edge-cases.test.ts +0 -654
- package/src/rbac/__tests__/engine.test.ts +0 -361
- package/src/rbac/__tests__/engine.unit.test.ts +0 -361
- package/src/rbac/__tests__/hooks.enhanced.test.tsx +0 -979
- package/src/rbac/__tests__/hooks.fixed.test.tsx +0 -475
- package/src/rbac/__tests__/hooks.test.tsx +0 -385
- package/src/rbac/__tests__/index.test.ts +0 -269
- package/src/rbac/__tests__/integration.enhanced.test.tsx +0 -824
- package/src/rbac/__tests__/page-permission-guard-super-admin.test.tsx +0 -261
- package/src/rbac/__tests__/performance.enhanced.test.tsx +0 -724
- package/src/rbac/__tests__/permissions.test.ts +0 -383
- package/src/rbac/__tests__/requires-event.test.ts +0 -330
- package/src/rbac/__tests__/scope-isolation-comprehensive.test.ts +0 -1349
- package/src/rbac/__tests__/scope-isolation.test.ts +0 -755
- package/src/rbac/__tests__/secure-client-rls-comprehensive.test.ts +0 -592
- package/src/rbac/__tests__/secure-client-rls.test.ts +0 -377
- package/src/rbac/__tests__/security.test.ts +0 -296
- package/src/rbac/__tests__/setup.ts +0 -228
- package/src/rbac/__tests__/test-utils-enhanced.tsx +0 -400
- package/src/rbac/__tests__/types.test.ts +0 -685
- package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +0 -631
- package/src/rbac/components/__tests__/NavigationProvider.test.tsx +0 -667
- package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +0 -647
- package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +0 -496
- package/src/rbac/testing/__tests__/index.test.tsx +0 -342
- package/src/rbac/utils/__tests__/eventContext.test.ts +0 -428
- package/src/rbac/utils/__tests__/eventContext.unit.test.ts +0 -428
- package/src/styles/__tests__/styles.unit.test.ts +0 -164
- package/src/test-dom-cleanup.test.tsx +0 -38
- package/src/theming/__tests__/README.md +0 -335
- package/src/theming/__tests__/runtime.accessibility.test.ts +0 -474
- package/src/theming/__tests__/runtime.error.test.ts +0 -616
- package/src/theming/__tests__/runtime.integration.test.ts +0 -376
- package/src/theming/__tests__/runtime.performance.test.ts +0 -411
- package/src/theming/__tests__/runtime.unit.test.ts +0 -470
- package/src/types/__tests__/database.unit.test.ts +0 -489
- package/src/types/__tests__/guards.unit.test.ts +0 -146
- package/src/types/__tests__/index.unit.test.ts +0 -77
- package/src/types/__tests__/organisation.unit.test.ts +0 -713
- package/src/types/__tests__/rbac.unit.test.ts +0 -621
- package/src/types/__tests__/security.unit.test.ts +0 -347
- package/src/types/__tests__/supabase.unit.test.ts +0 -658
- package/src/types/__tests__/theme.unit.test.ts +0 -218
- package/src/types/__tests__/unified.unit.test.ts +0 -537
- package/src/types/__tests__/validation.unit.test.ts +0 -616
- package/src/utils/__tests__/appConfig.unit.test.ts +0 -55
- package/src/utils/__tests__/appNameResolver.unit.test.ts +0 -137
- package/src/utils/__tests__/audit.unit.test.ts +0 -69
- package/src/utils/__tests__/auth-utils.unit.test.ts +0 -70
- package/src/utils/__tests__/bundleAnalysis.unit.test.ts +0 -317
- package/src/utils/__tests__/cn.unit.test.ts +0 -34
- package/src/utils/__tests__/deviceFingerprint.unit.test.ts +0 -480
- package/src/utils/__tests__/dynamicUtils.unit.test.ts +0 -322
- package/src/utils/__tests__/formatDate.unit.test.ts +0 -109
- package/src/utils/__tests__/formatting.unit.test.ts +0 -66
- package/src/utils/__tests__/index.unit.test.ts +0 -251
- package/src/utils/__tests__/lazyLoad.unit.test.tsx +0 -304
- package/src/utils/__tests__/organisationContext.unit.test.ts +0 -192
- package/src/utils/__tests__/performanceBudgets.unit.test.ts +0 -259
- package/src/utils/__tests__/permissionTypes.unit.test.ts +0 -250
- package/src/utils/__tests__/permissionUtils.unit.test.ts +0 -362
- package/src/utils/__tests__/sanitization.unit.test.ts +0 -346
- package/src/utils/__tests__/schemaUtils.unit.test.ts +0 -441
- package/src/utils/__tests__/secureDataAccess.unit.test.ts +0 -334
- package/src/utils/__tests__/secureErrors.unit.test.ts +0 -377
- package/src/utils/__tests__/secureStorage.unit.test.ts +0 -293
- package/src/utils/__tests__/security.unit.test.ts +0 -127
- package/src/utils/__tests__/securityMonitor.unit.test.ts +0 -280
- package/src/utils/__tests__/sessionTracking.unit.test.ts +0 -370
- package/src/utils/__tests__/validation.unit.test.ts +0 -84
- package/src/utils/__tests__/validationUtils.unit.test.ts +0 -571
- package/src/utils/print/__tests__/PrintDataProcessor.unit.test.ts +0 -219
- package/src/utils/print/__tests__/usePrintOptimization.unit.test.tsx +0 -353
- package/src/utils/storage/__tests__/config.unit.test.ts +0 -206
- package/src/utils/storage/__tests__/helpers.unit.test.ts +0 -648
- package/src/utils/storage/__tests__/index.unit.test.ts +0 -167
- package/src/utils/storage/__tests__/types.unit.test.ts +0 -441
- package/src/validation/__tests__/common.unit.test.ts +0 -101
- package/src/validation/__tests__/csrf.unit.test.ts +0 -302
- package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -98
- package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -466
- /package/dist/{DataTable-EEUDXPE5.js.map → DataTable-GX3XERFJ.js.map} +0 -0
- /package/dist/{chunk-VYG4AXYW.js.map → chunk-5EL3KHOQ.js.map} +0 -0
|
@@ -1,837 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @file Comprehensive Select Component Tests
|
|
3
|
-
* @package @jmruthers/pace-core
|
|
4
|
-
* @module Components/Select/Select.comprehensive
|
|
5
|
-
* @since 0.1.0
|
|
6
|
-
*
|
|
7
|
-
* Comprehensive tests for the Select component that test actual functionality
|
|
8
|
-
* including search features, keyboard navigation, accessibility, and edge cases.
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
import React from 'react';
|
|
12
|
-
import { screen, fireEvent, waitFor } from '@testing-library/react';
|
|
13
|
-
import userEvent from '@testing-library/user-event';
|
|
14
|
-
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
|
|
15
|
-
import '@testing-library/jest-dom';
|
|
16
|
-
import { renderWithProviders } from '../../../__tests__/shared';
|
|
17
|
-
import {
|
|
18
|
-
Select,
|
|
19
|
-
SelectGroup,
|
|
20
|
-
SelectValue,
|
|
21
|
-
SelectTrigger,
|
|
22
|
-
SelectContent,
|
|
23
|
-
SelectLabel,
|
|
24
|
-
SelectItem,
|
|
25
|
-
SelectSeparator,
|
|
26
|
-
} from '../Select';
|
|
27
|
-
|
|
28
|
-
// Mock lucide-react icons
|
|
29
|
-
vi.mock('lucide-react', () => ({
|
|
30
|
-
Search: () => <div data-testid="search-icon">🔍</div>,
|
|
31
|
-
X: () => <div data-testid="clear-icon">✕</div>,
|
|
32
|
-
ChevronDown: () => <div data-testid="chevron-down-icon">▼</div>,
|
|
33
|
-
Check: () => <div data-testid="check-icon">✓</div>,
|
|
34
|
-
}));
|
|
35
|
-
|
|
36
|
-
// No need to mock Radix UI since we're using a custom Select component
|
|
37
|
-
|
|
38
|
-
describe('Select Component - Comprehensive Tests', () => {
|
|
39
|
-
const user = userEvent.setup();
|
|
40
|
-
|
|
41
|
-
beforeEach(() => {
|
|
42
|
-
vi.clearAllMocks();
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
afterEach(() => {
|
|
46
|
-
vi.clearAllTimers();
|
|
47
|
-
});
|
|
48
|
-
|
|
49
|
-
describe('Basic Select Functionality', () => {
|
|
50
|
-
it('renders basic select with trigger and content', async () => {
|
|
51
|
-
renderWithProviders(
|
|
52
|
-
<Select>
|
|
53
|
-
<SelectTrigger>
|
|
54
|
-
<SelectValue placeholder="Select an option" />
|
|
55
|
-
</SelectTrigger>
|
|
56
|
-
<SelectContent>
|
|
57
|
-
<SelectItem value="option1">Option 1</SelectItem>
|
|
58
|
-
<SelectItem value="option2">Option 2</SelectItem>
|
|
59
|
-
</SelectContent>
|
|
60
|
-
</Select>
|
|
61
|
-
);
|
|
62
|
-
|
|
63
|
-
expect(screen.getByTestId('select-trigger')).toBeInTheDocument();
|
|
64
|
-
expect(screen.getByTestId('select-value')).toBeInTheDocument();
|
|
65
|
-
|
|
66
|
-
// Click trigger to open the select
|
|
67
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
68
|
-
fireEvent.click(trigger);
|
|
69
|
-
|
|
70
|
-
expect(screen.getByTestId('select-content')).toBeInTheDocument();
|
|
71
|
-
});
|
|
72
|
-
|
|
73
|
-
it('handles value changes correctly', async () => {
|
|
74
|
-
const onValueChange = vi.fn();
|
|
75
|
-
|
|
76
|
-
// Listen for value change events
|
|
77
|
-
document.addEventListener('select-value-change', (e: any) => {
|
|
78
|
-
onValueChange(e.detail);
|
|
79
|
-
});
|
|
80
|
-
|
|
81
|
-
renderWithProviders(
|
|
82
|
-
<Select onValueChange={onValueChange}>
|
|
83
|
-
<SelectTrigger>
|
|
84
|
-
<SelectValue placeholder="Select an option" />
|
|
85
|
-
</SelectTrigger>
|
|
86
|
-
<SelectContent>
|
|
87
|
-
<SelectItem value="option1">Option 1</SelectItem>
|
|
88
|
-
<SelectItem value="option2">Option 2</SelectItem>
|
|
89
|
-
</SelectContent>
|
|
90
|
-
</Select>
|
|
91
|
-
);
|
|
92
|
-
|
|
93
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
94
|
-
fireEvent.click(trigger);
|
|
95
|
-
|
|
96
|
-
const options = screen.getAllByTestId('select-item');
|
|
97
|
-
await user.click(options[0]);
|
|
98
|
-
|
|
99
|
-
expect(onValueChange).toHaveBeenCalledWith('option1');
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it('supports controlled value', () => {
|
|
103
|
-
renderWithProviders(
|
|
104
|
-
<Select value="option1">
|
|
105
|
-
<SelectTrigger>
|
|
106
|
-
<SelectValue placeholder="Select an option" />
|
|
107
|
-
</SelectTrigger>
|
|
108
|
-
<SelectContent>
|
|
109
|
-
<SelectItem value="option1">Option 1</SelectItem>
|
|
110
|
-
<SelectItem value="option2">Option 2</SelectItem>
|
|
111
|
-
</SelectContent>
|
|
112
|
-
</Select>
|
|
113
|
-
);
|
|
114
|
-
|
|
115
|
-
expect(screen.getByTestId('select-root')).toHaveAttribute('data-value', 'option1');
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
it('supports default value', () => {
|
|
119
|
-
renderWithProviders(
|
|
120
|
-
<Select defaultValue="option2">
|
|
121
|
-
<SelectTrigger>
|
|
122
|
-
<SelectValue placeholder="Select an option" />
|
|
123
|
-
</SelectTrigger>
|
|
124
|
-
<SelectContent>
|
|
125
|
-
<SelectItem value="option1">Option 1</SelectItem>
|
|
126
|
-
<SelectItem value="option2">Option 2</SelectItem>
|
|
127
|
-
</SelectContent>
|
|
128
|
-
</Select>
|
|
129
|
-
);
|
|
130
|
-
|
|
131
|
-
expect(screen.getByTestId('select-root')).toHaveAttribute('data-value', 'option2');
|
|
132
|
-
});
|
|
133
|
-
});
|
|
134
|
-
|
|
135
|
-
describe('Searchable Select Functionality', () => {
|
|
136
|
-
it('renders search input when searchable is true', async () => {
|
|
137
|
-
renderWithProviders(
|
|
138
|
-
<Select>
|
|
139
|
-
<SelectTrigger>
|
|
140
|
-
<SelectValue placeholder="Select an option" />
|
|
141
|
-
</SelectTrigger>
|
|
142
|
-
<SelectContent searchable>
|
|
143
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
144
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
145
|
-
<SelectItem value="cherry">Cherry</SelectItem>
|
|
146
|
-
</SelectContent>
|
|
147
|
-
</Select>
|
|
148
|
-
);
|
|
149
|
-
|
|
150
|
-
// Click trigger to open the select
|
|
151
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
152
|
-
fireEvent.click(trigger);
|
|
153
|
-
|
|
154
|
-
expect(screen.getByTestId('select-search-input')).toBeInTheDocument();
|
|
155
|
-
expect(screen.getByTestId('search-icon')).toBeInTheDocument();
|
|
156
|
-
});
|
|
157
|
-
|
|
158
|
-
it('filters options based on search input', async () => {
|
|
159
|
-
renderWithProviders(
|
|
160
|
-
<Select>
|
|
161
|
-
<SelectTrigger>
|
|
162
|
-
<SelectValue placeholder="Select an option" />
|
|
163
|
-
</SelectTrigger>
|
|
164
|
-
<SelectContent searchable searchPlaceholder="Search fruits...">
|
|
165
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
166
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
167
|
-
<SelectItem value="cherry">Cherry</SelectItem>
|
|
168
|
-
<SelectItem value="orange">Orange</SelectItem>
|
|
169
|
-
</SelectContent>
|
|
170
|
-
</Select>
|
|
171
|
-
);
|
|
172
|
-
|
|
173
|
-
// Click trigger to open the select
|
|
174
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
175
|
-
fireEvent.click(trigger);
|
|
176
|
-
|
|
177
|
-
// Wait for the select to open and search input to appear
|
|
178
|
-
const searchInput = await waitFor(() => {
|
|
179
|
-
return screen.getByTestId('select-search-input');
|
|
180
|
-
});
|
|
181
|
-
|
|
182
|
-
fireEvent.input(searchInput, { target: { value: 'app' } });
|
|
183
|
-
|
|
184
|
-
// Wait for debounced search
|
|
185
|
-
await waitFor(() => {
|
|
186
|
-
expect(searchInput).toHaveValue('app');
|
|
187
|
-
});
|
|
188
|
-
});
|
|
189
|
-
|
|
190
|
-
it('supports different search strategies', async () => {
|
|
191
|
-
// Test contains search strategy
|
|
192
|
-
const { rerender } = renderWithProviders(
|
|
193
|
-
<Select>
|
|
194
|
-
<SelectTrigger>
|
|
195
|
-
<SelectValue placeholder="Select an option" />
|
|
196
|
-
</SelectTrigger>
|
|
197
|
-
<SelectContent searchable searchStrategy="contains">
|
|
198
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
199
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
200
|
-
<SelectItem value="pineapple">Pineapple</SelectItem>
|
|
201
|
-
</SelectContent>
|
|
202
|
-
</Select>
|
|
203
|
-
);
|
|
204
|
-
|
|
205
|
-
// Click trigger to open the select
|
|
206
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
207
|
-
fireEvent.click(trigger);
|
|
208
|
-
|
|
209
|
-
const searchInput = await waitFor(() => {
|
|
210
|
-
return screen.getByTestId('select-search-input');
|
|
211
|
-
});
|
|
212
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
213
|
-
|
|
214
|
-
await waitFor(() => {
|
|
215
|
-
expect(searchInput).toHaveValue('apple');
|
|
216
|
-
});
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
it('supports fuzzy search strategy', async () => {
|
|
220
|
-
// Test fuzzy search strategy in a separate test
|
|
221
|
-
renderWithProviders(
|
|
222
|
-
<Select>
|
|
223
|
-
<SelectTrigger>
|
|
224
|
-
<SelectValue placeholder="Select an option" />
|
|
225
|
-
</SelectTrigger>
|
|
226
|
-
<SelectContent searchable searchStrategy="fuzzy">
|
|
227
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
228
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
229
|
-
<SelectItem value="pineapple">Pineapple</SelectItem>
|
|
230
|
-
</SelectContent>
|
|
231
|
-
</Select>
|
|
232
|
-
);
|
|
233
|
-
|
|
234
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
235
|
-
fireEvent.click(trigger);
|
|
236
|
-
|
|
237
|
-
const searchInput = await waitFor(() => {
|
|
238
|
-
return screen.getByTestId('select-search-input');
|
|
239
|
-
});
|
|
240
|
-
fireEvent.input(searchInput, { target: { value: 'bnn' } }); // Fuzzy match for banana
|
|
241
|
-
|
|
242
|
-
await waitFor(() => {
|
|
243
|
-
expect(searchInput).toHaveValue('bnn');
|
|
244
|
-
});
|
|
245
|
-
});
|
|
246
|
-
|
|
247
|
-
it('shows no results message when no matches found', async () => {
|
|
248
|
-
renderWithProviders(
|
|
249
|
-
<Select>
|
|
250
|
-
<SelectTrigger>
|
|
251
|
-
<SelectValue placeholder="Select an option" />
|
|
252
|
-
</SelectTrigger>
|
|
253
|
-
<SelectContent searchable noResultsText="No fruits found">
|
|
254
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
255
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
256
|
-
</SelectContent>
|
|
257
|
-
</Select>
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
// Click trigger to open the select
|
|
261
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
262
|
-
fireEvent.click(trigger);
|
|
263
|
-
|
|
264
|
-
const searchInput = await waitFor(() => {
|
|
265
|
-
return screen.getByTestId('select-search-input');
|
|
266
|
-
});
|
|
267
|
-
fireEvent.input(searchInput, { target: { value: 'xyz' } });
|
|
268
|
-
|
|
269
|
-
await waitFor(() => {
|
|
270
|
-
expect(searchInput).toHaveValue('xyz');
|
|
271
|
-
});
|
|
272
|
-
});
|
|
273
|
-
|
|
274
|
-
it('supports case sensitive search', async () => {
|
|
275
|
-
renderWithProviders(
|
|
276
|
-
<Select>
|
|
277
|
-
<SelectTrigger>
|
|
278
|
-
<SelectValue placeholder="Select an option" />
|
|
279
|
-
</SelectTrigger>
|
|
280
|
-
<SelectContent searchable caseSensitive>
|
|
281
|
-
<SelectItem value="Apple">Apple</SelectItem>
|
|
282
|
-
<SelectItem value="apple">apple</SelectItem>
|
|
283
|
-
<SelectItem value="BANANA">BANANA</SelectItem>
|
|
284
|
-
</SelectContent>
|
|
285
|
-
</Select>
|
|
286
|
-
);
|
|
287
|
-
|
|
288
|
-
// Click trigger to open the select
|
|
289
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
290
|
-
fireEvent.click(trigger);
|
|
291
|
-
|
|
292
|
-
const searchInput = await waitFor(() => {
|
|
293
|
-
return screen.getByTestId('select-search-input');
|
|
294
|
-
});
|
|
295
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
296
|
-
|
|
297
|
-
await waitFor(() => {
|
|
298
|
-
expect(searchInput).toHaveValue('apple');
|
|
299
|
-
});
|
|
300
|
-
});
|
|
301
|
-
|
|
302
|
-
it('calls onSearchChange callback', async () => {
|
|
303
|
-
const onSearchChange = vi.fn();
|
|
304
|
-
renderWithProviders(
|
|
305
|
-
<Select>
|
|
306
|
-
<SelectTrigger>
|
|
307
|
-
<SelectValue placeholder="Select an option" />
|
|
308
|
-
</SelectTrigger>
|
|
309
|
-
<SelectContent searchable onSearchChange={onSearchChange}>
|
|
310
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
311
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
312
|
-
</SelectContent>
|
|
313
|
-
</Select>
|
|
314
|
-
);
|
|
315
|
-
|
|
316
|
-
// Click trigger to open the select
|
|
317
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
318
|
-
fireEvent.click(trigger);
|
|
319
|
-
|
|
320
|
-
const searchInput = await waitFor(() => {
|
|
321
|
-
return screen.getByTestId('select-search-input');
|
|
322
|
-
});
|
|
323
|
-
fireEvent.input(searchInput, { target: { value: 'test' } });
|
|
324
|
-
|
|
325
|
-
await waitFor(() => {
|
|
326
|
-
expect(searchInput).toHaveValue('test');
|
|
327
|
-
});
|
|
328
|
-
});
|
|
329
|
-
|
|
330
|
-
it('supports custom filter function', async () => {
|
|
331
|
-
const customFilter = vi.fn((options, searchTerm) =>
|
|
332
|
-
options.filter(option => option.label.includes(searchTerm.toUpperCase()))
|
|
333
|
-
);
|
|
334
|
-
|
|
335
|
-
renderWithProviders(
|
|
336
|
-
<Select>
|
|
337
|
-
<SelectTrigger>
|
|
338
|
-
<SelectValue placeholder="Select an option" />
|
|
339
|
-
</SelectTrigger>
|
|
340
|
-
<SelectContent searchable filterFunction={customFilter}>
|
|
341
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
342
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
343
|
-
<SelectItem value="cherry">Cherry</SelectItem>
|
|
344
|
-
</SelectContent>
|
|
345
|
-
</Select>
|
|
346
|
-
);
|
|
347
|
-
|
|
348
|
-
// Click trigger to open the select
|
|
349
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
350
|
-
fireEvent.click(trigger);
|
|
351
|
-
|
|
352
|
-
const searchInput = await waitFor(() => {
|
|
353
|
-
return screen.getByTestId('select-search-input');
|
|
354
|
-
});
|
|
355
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
356
|
-
|
|
357
|
-
await waitFor(() => {
|
|
358
|
-
expect(searchInput).toHaveValue('apple');
|
|
359
|
-
});
|
|
360
|
-
});
|
|
361
|
-
|
|
362
|
-
it('supports clear search functionality', async () => {
|
|
363
|
-
renderWithProviders(
|
|
364
|
-
<Select>
|
|
365
|
-
<SelectTrigger>
|
|
366
|
-
<SelectValue placeholder="Select an option" />
|
|
367
|
-
</SelectTrigger>
|
|
368
|
-
<SelectContent searchable showClearButton>
|
|
369
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
370
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
371
|
-
</SelectContent>
|
|
372
|
-
</Select>
|
|
373
|
-
);
|
|
374
|
-
|
|
375
|
-
// Click trigger to open the select
|
|
376
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
377
|
-
fireEvent.click(trigger);
|
|
378
|
-
|
|
379
|
-
const searchInput = await waitFor(() => {
|
|
380
|
-
return screen.getByTestId('select-search-input');
|
|
381
|
-
});
|
|
382
|
-
fireEvent.input(searchInput, { target: { value: 'test' } });
|
|
383
|
-
|
|
384
|
-
// Wait for the clear button to appear
|
|
385
|
-
const clearButton = await waitFor(() => {
|
|
386
|
-
return screen.getByTestId('select-clear-search');
|
|
387
|
-
});
|
|
388
|
-
|
|
389
|
-
fireEvent.click(clearButton);
|
|
390
|
-
|
|
391
|
-
await waitFor(() => {
|
|
392
|
-
expect(searchInput).toHaveValue('');
|
|
393
|
-
});
|
|
394
|
-
});
|
|
395
|
-
});
|
|
396
|
-
|
|
397
|
-
describe('Keyboard Navigation', () => {
|
|
398
|
-
it('supports global keyboard shortcuts', async () => {
|
|
399
|
-
renderWithProviders(
|
|
400
|
-
<Select>
|
|
401
|
-
<SelectTrigger>
|
|
402
|
-
<SelectValue placeholder="Select an option" />
|
|
403
|
-
</SelectTrigger>
|
|
404
|
-
<SelectContent searchable>
|
|
405
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
406
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
407
|
-
</SelectContent>
|
|
408
|
-
</Select>
|
|
409
|
-
);
|
|
410
|
-
|
|
411
|
-
// Click trigger to open the select first
|
|
412
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
413
|
-
fireEvent.click(trigger);
|
|
414
|
-
|
|
415
|
-
// Test / key to focus search
|
|
416
|
-
await user.keyboard('/');
|
|
417
|
-
|
|
418
|
-
const searchInput = await waitFor(() => {
|
|
419
|
-
return screen.getByTestId('select-search-input');
|
|
420
|
-
});
|
|
421
|
-
expect(searchInput).toBeInTheDocument();
|
|
422
|
-
});
|
|
423
|
-
|
|
424
|
-
it('supports Ctrl+F to focus search', async () => {
|
|
425
|
-
renderWithProviders(
|
|
426
|
-
<Select>
|
|
427
|
-
<SelectTrigger>
|
|
428
|
-
<SelectValue placeholder="Select an option" />
|
|
429
|
-
</SelectTrigger>
|
|
430
|
-
<SelectContent searchable>
|
|
431
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
432
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
433
|
-
</SelectContent>
|
|
434
|
-
</Select>
|
|
435
|
-
);
|
|
436
|
-
|
|
437
|
-
// Click trigger to open the select first
|
|
438
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
439
|
-
fireEvent.click(trigger);
|
|
440
|
-
|
|
441
|
-
// Test Ctrl+F to focus search
|
|
442
|
-
await user.keyboard('{Control>}f{/Control}');
|
|
443
|
-
|
|
444
|
-
const searchInput = await waitFor(() => {
|
|
445
|
-
return screen.getByTestId('select-search-input');
|
|
446
|
-
});
|
|
447
|
-
expect(searchInput).toBeInTheDocument();
|
|
448
|
-
});
|
|
449
|
-
|
|
450
|
-
it('supports Escape to clear search', async () => {
|
|
451
|
-
renderWithProviders(
|
|
452
|
-
<Select>
|
|
453
|
-
<SelectTrigger>
|
|
454
|
-
<SelectValue placeholder="Select an option" />
|
|
455
|
-
</SelectTrigger>
|
|
456
|
-
<SelectContent searchable>
|
|
457
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
458
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
459
|
-
</SelectContent>
|
|
460
|
-
</Select>
|
|
461
|
-
);
|
|
462
|
-
|
|
463
|
-
// Click trigger to open the select
|
|
464
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
465
|
-
fireEvent.click(trigger);
|
|
466
|
-
|
|
467
|
-
const searchInput = await waitFor(() => {
|
|
468
|
-
return screen.getByTestId('select-search-input');
|
|
469
|
-
});
|
|
470
|
-
fireEvent.input(searchInput, { target: { value: 'test' } });
|
|
471
|
-
searchInput.focus();
|
|
472
|
-
await user.keyboard('{Escape}');
|
|
473
|
-
|
|
474
|
-
await waitFor(() => {
|
|
475
|
-
expect(searchInput).toHaveValue('');
|
|
476
|
-
});
|
|
477
|
-
});
|
|
478
|
-
});
|
|
479
|
-
|
|
480
|
-
describe('Accessibility', () => {
|
|
481
|
-
it('provides proper ARIA attributes', () => {
|
|
482
|
-
renderWithProviders(
|
|
483
|
-
<Select>
|
|
484
|
-
<SelectTrigger>
|
|
485
|
-
<SelectValue placeholder="Select an option" />
|
|
486
|
-
</SelectTrigger>
|
|
487
|
-
<SelectContent>
|
|
488
|
-
<SelectItem value="option1">Option 1</SelectItem>
|
|
489
|
-
<SelectItem value="option2">Option 2</SelectItem>
|
|
490
|
-
</SelectContent>
|
|
491
|
-
</Select>
|
|
492
|
-
);
|
|
493
|
-
|
|
494
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
495
|
-
expect(trigger).toBeInTheDocument();
|
|
496
|
-
});
|
|
497
|
-
|
|
498
|
-
it('announces search results to screen readers', async () => {
|
|
499
|
-
renderWithProviders(
|
|
500
|
-
<Select>
|
|
501
|
-
<SelectTrigger>
|
|
502
|
-
<SelectValue placeholder="Select an option" />
|
|
503
|
-
</SelectTrigger>
|
|
504
|
-
<SelectContent searchable>
|
|
505
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
506
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
507
|
-
</SelectContent>
|
|
508
|
-
</Select>
|
|
509
|
-
);
|
|
510
|
-
|
|
511
|
-
// Click trigger to open the select
|
|
512
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
513
|
-
fireEvent.click(trigger);
|
|
514
|
-
|
|
515
|
-
const searchInput = await waitFor(() => {
|
|
516
|
-
return screen.getByTestId('select-search-input');
|
|
517
|
-
});
|
|
518
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
519
|
-
|
|
520
|
-
await waitFor(() => {
|
|
521
|
-
expect(searchInput).toHaveValue('apple');
|
|
522
|
-
});
|
|
523
|
-
});
|
|
524
|
-
|
|
525
|
-
it('provides proper labels for search input', async () => {
|
|
526
|
-
renderWithProviders(
|
|
527
|
-
<Select>
|
|
528
|
-
<SelectTrigger>
|
|
529
|
-
<SelectValue placeholder="Select an option" />
|
|
530
|
-
</SelectTrigger>
|
|
531
|
-
<SelectContent searchable>
|
|
532
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
533
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
534
|
-
</SelectContent>
|
|
535
|
-
</Select>
|
|
536
|
-
);
|
|
537
|
-
|
|
538
|
-
// Click trigger to open the select
|
|
539
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
540
|
-
fireEvent.click(trigger);
|
|
541
|
-
|
|
542
|
-
const searchInput = await waitFor(() => {
|
|
543
|
-
return screen.getByTestId('select-search-input');
|
|
544
|
-
});
|
|
545
|
-
expect(searchInput).toHaveAttribute('aria-label', 'Search options');
|
|
546
|
-
});
|
|
547
|
-
});
|
|
548
|
-
|
|
549
|
-
describe('Grouped Options', () => {
|
|
550
|
-
it('renders grouped options correctly', async () => {
|
|
551
|
-
renderWithProviders(
|
|
552
|
-
<Select>
|
|
553
|
-
<SelectTrigger>
|
|
554
|
-
<SelectValue placeholder="Select an option" />
|
|
555
|
-
</SelectTrigger>
|
|
556
|
-
<SelectContent>
|
|
557
|
-
<SelectGroup>
|
|
558
|
-
<SelectLabel>Fruits</SelectLabel>
|
|
559
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
560
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
561
|
-
</SelectGroup>
|
|
562
|
-
<SelectSeparator />
|
|
563
|
-
<SelectGroup>
|
|
564
|
-
<SelectLabel>Vegetables</SelectLabel>
|
|
565
|
-
<SelectItem value="carrot">Carrot</SelectItem>
|
|
566
|
-
<SelectItem value="lettuce">Lettuce</SelectItem>
|
|
567
|
-
</SelectGroup>
|
|
568
|
-
</SelectContent>
|
|
569
|
-
</Select>
|
|
570
|
-
);
|
|
571
|
-
|
|
572
|
-
// Click trigger to open the select
|
|
573
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
574
|
-
fireEvent.click(trigger);
|
|
575
|
-
|
|
576
|
-
expect(screen.getAllByTestId('select-label')).toHaveLength(2);
|
|
577
|
-
expect(screen.getAllByTestId('select-group')).toHaveLength(2);
|
|
578
|
-
expect(screen.getAllByTestId('select-item')).toHaveLength(4);
|
|
579
|
-
expect(screen.getByTestId('select-separator')).toBeInTheDocument();
|
|
580
|
-
});
|
|
581
|
-
|
|
582
|
-
it('filters grouped options correctly', async () => {
|
|
583
|
-
renderWithProviders(
|
|
584
|
-
<Select>
|
|
585
|
-
<SelectTrigger>
|
|
586
|
-
<SelectValue placeholder="Select an option" />
|
|
587
|
-
</SelectTrigger>
|
|
588
|
-
<SelectContent searchable>
|
|
589
|
-
<SelectGroup>
|
|
590
|
-
<SelectLabel>Fruits</SelectLabel>
|
|
591
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
592
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
593
|
-
</SelectGroup>
|
|
594
|
-
<SelectSeparator />
|
|
595
|
-
<SelectGroup>
|
|
596
|
-
<SelectLabel>Vegetables</SelectLabel>
|
|
597
|
-
<SelectItem value="carrot">Carrot</SelectItem>
|
|
598
|
-
<SelectItem value="lettuce">Lettuce</SelectItem>
|
|
599
|
-
</SelectGroup>
|
|
600
|
-
</SelectContent>
|
|
601
|
-
</Select>
|
|
602
|
-
);
|
|
603
|
-
|
|
604
|
-
// Click trigger to open the select
|
|
605
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
606
|
-
fireEvent.click(trigger);
|
|
607
|
-
|
|
608
|
-
const searchInput = await waitFor(() => {
|
|
609
|
-
return screen.getByTestId('select-search-input');
|
|
610
|
-
});
|
|
611
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
612
|
-
|
|
613
|
-
await waitFor(() => {
|
|
614
|
-
expect(searchInput).toHaveValue('apple');
|
|
615
|
-
});
|
|
616
|
-
});
|
|
617
|
-
});
|
|
618
|
-
|
|
619
|
-
describe('Performance and Edge Cases', () => {
|
|
620
|
-
it('handles large option sets efficiently', () => {
|
|
621
|
-
const manyOptions = Array.from({ length: 100 }, (_, i) => (
|
|
622
|
-
<SelectItem key={i} value={`option-${i}`}>
|
|
623
|
-
Option {i + 1}
|
|
624
|
-
</SelectItem>
|
|
625
|
-
));
|
|
626
|
-
|
|
627
|
-
expect(() => {
|
|
628
|
-
renderWithProviders(
|
|
629
|
-
<Select>
|
|
630
|
-
<SelectTrigger>
|
|
631
|
-
<SelectValue placeholder="Select an option" />
|
|
632
|
-
</SelectTrigger>
|
|
633
|
-
<SelectContent searchable debounceMs={100}>
|
|
634
|
-
{manyOptions}
|
|
635
|
-
</SelectContent>
|
|
636
|
-
</Select>
|
|
637
|
-
);
|
|
638
|
-
}).not.toThrow();
|
|
639
|
-
});
|
|
640
|
-
|
|
641
|
-
it('handles empty children gracefully', () => {
|
|
642
|
-
expect(() => {
|
|
643
|
-
renderWithProviders(
|
|
644
|
-
<Select>
|
|
645
|
-
<SelectTrigger>
|
|
646
|
-
<SelectValue placeholder="Select an option" />
|
|
647
|
-
</SelectTrigger>
|
|
648
|
-
<SelectContent>
|
|
649
|
-
{/* Empty content */}
|
|
650
|
-
</SelectContent>
|
|
651
|
-
</Select>
|
|
652
|
-
);
|
|
653
|
-
}).not.toThrow();
|
|
654
|
-
});
|
|
655
|
-
|
|
656
|
-
it('handles null and undefined values', () => {
|
|
657
|
-
expect(() => {
|
|
658
|
-
renderWithProviders(
|
|
659
|
-
<Select value={null as any}>
|
|
660
|
-
<SelectTrigger>
|
|
661
|
-
<SelectValue placeholder="Select an option" />
|
|
662
|
-
</SelectTrigger>
|
|
663
|
-
<SelectContent>
|
|
664
|
-
<SelectItem value="option1">Option 1</SelectItem>
|
|
665
|
-
</SelectContent>
|
|
666
|
-
</Select>
|
|
667
|
-
);
|
|
668
|
-
}).not.toThrow();
|
|
669
|
-
});
|
|
670
|
-
|
|
671
|
-
it('handles rapid search input changes', async () => {
|
|
672
|
-
renderWithProviders(
|
|
673
|
-
<Select>
|
|
674
|
-
<SelectTrigger>
|
|
675
|
-
<SelectValue placeholder="Select an option" />
|
|
676
|
-
</SelectTrigger>
|
|
677
|
-
<SelectContent searchable debounceMs={50}>
|
|
678
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
679
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
680
|
-
</SelectContent>
|
|
681
|
-
</Select>
|
|
682
|
-
);
|
|
683
|
-
|
|
684
|
-
// Click trigger to open the select
|
|
685
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
686
|
-
fireEvent.click(trigger);
|
|
687
|
-
|
|
688
|
-
const searchInput = await waitFor(() => {
|
|
689
|
-
return screen.getByTestId('select-search-input');
|
|
690
|
-
});
|
|
691
|
-
|
|
692
|
-
// Rapidly type and clear
|
|
693
|
-
fireEvent.input(searchInput, { target: { value: 'a' } });
|
|
694
|
-
fireEvent.input(searchInput, { target: { value: '' } });
|
|
695
|
-
fireEvent.input(searchInput, { target: { value: 'b' } });
|
|
696
|
-
fireEvent.input(searchInput, { target: { value: '' } });
|
|
697
|
-
fireEvent.input(searchInput, { target: { value: 'c' } });
|
|
698
|
-
|
|
699
|
-
// Should not throw errors
|
|
700
|
-
expect(searchInput).toBeInTheDocument();
|
|
701
|
-
});
|
|
702
|
-
|
|
703
|
-
it('handles custom max height', async () => {
|
|
704
|
-
renderWithProviders(
|
|
705
|
-
<Select>
|
|
706
|
-
<SelectTrigger>
|
|
707
|
-
<SelectValue placeholder="Select an option" />
|
|
708
|
-
</SelectTrigger>
|
|
709
|
-
<SelectContent searchable maxHeight="10rem">
|
|
710
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
711
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
712
|
-
</SelectContent>
|
|
713
|
-
</Select>
|
|
714
|
-
);
|
|
715
|
-
|
|
716
|
-
// Click trigger to open the select
|
|
717
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
718
|
-
fireEvent.click(trigger);
|
|
719
|
-
|
|
720
|
-
const content = screen.getByTestId('select-content');
|
|
721
|
-
expect(content).toBeInTheDocument();
|
|
722
|
-
});
|
|
723
|
-
});
|
|
724
|
-
|
|
725
|
-
describe('Search Highlighting', () => {
|
|
726
|
-
it('highlights matching text in search results', async () => {
|
|
727
|
-
renderWithProviders(
|
|
728
|
-
<Select>
|
|
729
|
-
<SelectTrigger>
|
|
730
|
-
<SelectValue placeholder="Select an option" />
|
|
731
|
-
</SelectTrigger>
|
|
732
|
-
<SelectContent searchable highlightMatches>
|
|
733
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
734
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
735
|
-
<SelectItem value="pineapple">Pineapple</SelectItem>
|
|
736
|
-
</SelectContent>
|
|
737
|
-
</Select>
|
|
738
|
-
);
|
|
739
|
-
|
|
740
|
-
// Click trigger to open the select
|
|
741
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
742
|
-
fireEvent.click(trigger);
|
|
743
|
-
|
|
744
|
-
const searchInput = await waitFor(() => {
|
|
745
|
-
return screen.getByTestId('select-search-input');
|
|
746
|
-
});
|
|
747
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
748
|
-
|
|
749
|
-
await waitFor(() => {
|
|
750
|
-
expect(searchInput).toHaveValue('apple');
|
|
751
|
-
});
|
|
752
|
-
});
|
|
753
|
-
|
|
754
|
-
it('disables highlighting when highlightMatches is false', async () => {
|
|
755
|
-
renderWithProviders(
|
|
756
|
-
<Select>
|
|
757
|
-
<SelectTrigger>
|
|
758
|
-
<SelectValue placeholder="Select an option" />
|
|
759
|
-
</SelectTrigger>
|
|
760
|
-
<SelectContent searchable highlightMatches={false}>
|
|
761
|
-
<SelectItem value="apple">Apple</SelectItem>
|
|
762
|
-
<SelectItem value="banana">Banana</SelectItem>
|
|
763
|
-
</SelectContent>
|
|
764
|
-
</Select>
|
|
765
|
-
);
|
|
766
|
-
|
|
767
|
-
// Click trigger to open the select
|
|
768
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
769
|
-
fireEvent.click(trigger);
|
|
770
|
-
|
|
771
|
-
const searchInput = await waitFor(() => {
|
|
772
|
-
return screen.getByTestId('select-search-input');
|
|
773
|
-
});
|
|
774
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
775
|
-
|
|
776
|
-
await waitFor(() => {
|
|
777
|
-
expect(searchInput).toHaveValue('apple');
|
|
778
|
-
});
|
|
779
|
-
});
|
|
780
|
-
});
|
|
781
|
-
|
|
782
|
-
describe('Search Field Configuration', () => {
|
|
783
|
-
it('searches in label field by default', async () => {
|
|
784
|
-
renderWithProviders(
|
|
785
|
-
<Select>
|
|
786
|
-
<SelectTrigger>
|
|
787
|
-
<SelectValue placeholder="Select an option" />
|
|
788
|
-
</SelectTrigger>
|
|
789
|
-
<SelectContent searchable>
|
|
790
|
-
<SelectItem value="fruit1">Apple</SelectItem>
|
|
791
|
-
<SelectItem value="fruit2">Banana</SelectItem>
|
|
792
|
-
</SelectContent>
|
|
793
|
-
</Select>
|
|
794
|
-
);
|
|
795
|
-
|
|
796
|
-
// Click trigger to open the select
|
|
797
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
798
|
-
fireEvent.click(trigger);
|
|
799
|
-
|
|
800
|
-
const searchInput = await waitFor(() => {
|
|
801
|
-
return screen.getByTestId('select-search-input');
|
|
802
|
-
});
|
|
803
|
-
fireEvent.input(searchInput, { target: { value: 'Apple' } });
|
|
804
|
-
|
|
805
|
-
await waitFor(() => {
|
|
806
|
-
expect(searchInput).toHaveValue('Apple');
|
|
807
|
-
});
|
|
808
|
-
});
|
|
809
|
-
|
|
810
|
-
it('searches in value field when configured', async () => {
|
|
811
|
-
renderWithProviders(
|
|
812
|
-
<Select>
|
|
813
|
-
<SelectTrigger>
|
|
814
|
-
<SelectValue placeholder="Select an option" />
|
|
815
|
-
</SelectTrigger>
|
|
816
|
-
<SelectContent searchable searchFields={['value']}>
|
|
817
|
-
<SelectItem value="apple">Red Fruit</SelectItem>
|
|
818
|
-
<SelectItem value="banana">Yellow Fruit</SelectItem>
|
|
819
|
-
</SelectContent>
|
|
820
|
-
</Select>
|
|
821
|
-
);
|
|
822
|
-
|
|
823
|
-
// Click trigger to open the select
|
|
824
|
-
const trigger = screen.getByTestId('select-trigger');
|
|
825
|
-
fireEvent.click(trigger);
|
|
826
|
-
|
|
827
|
-
const searchInput = await waitFor(() => {
|
|
828
|
-
return screen.getByTestId('select-search-input');
|
|
829
|
-
});
|
|
830
|
-
fireEvent.input(searchInput, { target: { value: 'apple' } });
|
|
831
|
-
|
|
832
|
-
await waitFor(() => {
|
|
833
|
-
expect(searchInput).toHaveValue('apple');
|
|
834
|
-
});
|
|
835
|
-
});
|
|
836
|
-
});
|
|
837
|
-
});
|