From b7f020f4283bb6277a8aee2a55e7ef9a827bae18 Mon Sep 17 00:00:00 2001 From: prabhuignoto Date: Wed, 9 Jul 2025 10:27:51 +0530 Subject: [PATCH 1/4] major config updates --- .github/labels.yml | 208 + .github/workflows/build.yml | 65 +- .github/workflows/ci.yml | 290 + .github/workflows/dependency-management.yml | 336 + .github/workflows/deploy.yml | 319 + .github/workflows/issue-management.yml | 302 + .github/workflows/label-sync.yml | 25 + .github/workflows/pr-automation.yml | 326 + .github/workflows/release.yml | 251 + .github/workflows/snyk.yaml | 63 +- .github/workflows/sonar.yml | 21 - .prettierignore | 72 +- .prettierrc | 42 +- .stylelintignore | 29 + .stylelintrc | 59 +- LICENSE | 2 +- README.md | 715 +- coverage/__tests__/index.html | 116 - coverage/__tests__/react-chrono.test.ts.html | 532 - coverage/base.css | 224 - coverage/block-navigation.js | 87 - coverage/clover.xml | 12053 ------------ .../__tests__/GlobalContext.test.tsx.html | 2290 --- coverage/components/__tests__/index.html | 116 - coverage/components/common/styles/index.html | 116 - .../components/common/styles/index.ts.html | 145 - coverage/components/common/themes/index.html | 116 - .../components/common/themes/index.ts.html | 328 - .../contexts/DynamicContext.tsx.html | 256 - .../OptimizedContextProvider.tsx.html | 1192 -- .../contexts/StableContext.tsx.html | 508 - coverage/components/contexts/hooks.tsx.html | 640 - coverage/components/contexts/index.html | 191 - coverage/components/contexts/index.tsx.html | 145 - .../components/contexts/legacy-types.tsx.html | 193 - .../components/effects/__tests__/index.html | 161 - .../__tests__/useClickOutside.test.tsx.html | 334 - .../__tests__/useMatchMedia.test.tsx.html | 595 - .../useNewScrollPosition.test.ts.html | 1228 -- .../__tests__/useSlideshow.test.ts.html | 322 - coverage/components/effects/index.html | 161 - .../effects/useCloseClickOutside.ts.html | 133 - .../components/effects/useMatchMedia.ts.html | 421 - .../effects/useNewScrollPosition.ts.html | 412 - .../components/effects/useSlideshow.ts.html | 634 - .../elements/list/__tests__/index.html | 131 - .../list/__tests__/list-item.test.tsx.html | 337 - .../list/__tests__/list.test.tsx.html | 277 - coverage/components/elements/list/index.html | 161 - .../elements/list/list-item.tsx.html | 358 - .../elements/list/list.model.ts.html | 142 - .../elements/list/list.styles.ts.html | 508 - .../components/elements/list/list.tsx.html | 367 - .../elements/popover/__tests__/index.html | 116 - .../popover/__tests__/popover.test.tsx.html | 403 - .../components/elements/popover/index.html | 146 - .../elements/popover/index.tsx.html | 499 - .../elements/popover/popover.model.ts.html | 124 - .../elements/popover/popover.styles.ts.html | 496 - .../memoized/__tests__/index.html | 116 - .../memoized/__tests__/index.test.tsx.html | 559 - .../memoized/details-text-memo.tsx.html | 214 - .../memoized/expand-button-memo.tsx.html | 193 - .../timeline-elements/memoized/index.html | 191 - .../memoized/memoized-model.ts.html | 313 - .../memoized/show-hide-button.tsx.html | 187 - .../memoized/subtitle-memo.tsx.html | 193 - .../memoized/title-memo.tsx.html | 235 - .../nested-timeline-renderer/index.html | 116 - .../nested-timeline-renderer.tsx.html | 214 - .../__tests__/content-footer.test.tsx.html | 364 - .../__tests__/content-header.test.tsx.html | 238 - .../__tests__/details-text.test.tsx.html | 352 - .../__tests__/index.html | 176 - .../__tests__/text_or_content.test.tsx.html | 277 - .../timeline-card-content.test.tsx.html | 478 - .../card-animations.styles.ts.html | 220 - .../content-footer.tsx.html | 349 - .../content-header.tsx.html | 304 - .../details-text.model.ts.html | 124 - .../details-text.tsx.html | 283 - .../header-footer.model.ts.html | 145 - .../timeline-card-content/index.html | 236 - .../text-or-content.tsx.html | 514 - .../timeline-card-content.styles.ts.html | 1762 -- .../timeline-card-content.tsx.html | 1618 -- .../timeline-card-media/__tests__/index.html | 116 - .../timeline-card-media.test.tsx.html | 763 - .../components/ContentDisplay.tsx.html | 469 - .../components/ErrorMessage.tsx.html | 124 - .../components/ImageDisplay.tsx.html | 232 - .../components/MediaContent.tsx.html | 373 - .../components/VideoPlayer.tsx.html | 316 - .../components/YoutubePlayer.tsx.html | 160 - .../timeline-card-media/components/index.html | 191 - .../timeline-card-media/hooks/index.html | 161 - .../hooks/useMediaLoad.ts.html | 223 - .../hooks/useToggleControls.ts.html | 166 - .../hooks/useViewOptions.ts.html | 319 - .../hooks/useYouTubeDetection.ts.html | 124 - .../timeline-card-media/index.html | 161 - .../timeline-card-media-buttons.tsx.html | 229 - .../timeline-card-media.styles.ts.html | 850 - .../timeline-card-media.tsx.html | 529 - .../timeline-card-media/video.tsx.html | 244 - .../timeline-card/__tests__/index.html | 116 - .../timeline-horizontal-card.test.tsx.html | 487 - .../timeline-card/hooks/index.html | 116 - .../hooks/useTimelineCard.ts.html | 358 - .../timeline-card/index.html | 131 - .../timeline-card-portal/index.html | 116 - .../timeline-card-portal.tsx.html | 472 - .../timeline-horizontal-card.styles.ts.html | 925 - .../timeline-horizontal-card.tsx.html | 529 - .../timeline-card/timeline-point/index.html | 116 - .../timeline-point/timeline-point.tsx.html | 244 - .../timeline-control/__tests__/index.html | 116 - .../__tests__/timeline-control.test.tsx.html | 316 - .../timeline-control/index.html | 146 - .../timeline-control.styles.ts.html | 625 - .../timeline-control.styles.tsx.html | 124 - .../timeline-control.tsx.html | 871 - .../timeline-controls-wrapper/index.html | 116 - .../timeline-controls-wrapper.tsx.html | 160 - .../timeline-item-title/__tests__/index.html | 116 - .../timeline-card-title.test.tsx.html | 262 - .../timeline-item-title/index.html | 131 - .../timeline-card-title.styles.ts.html | 175 - .../timeline-card-title.tsx.html | 232 - .../timeline-outline/__tests__/index.html | 116 - .../__tests__/timeline-outline.test.tsx.html | 502 - .../timeline-outline/animations.ts.html | 172 - .../timeline-outline/hooks/index.html | 116 - .../hooks/useOutlinePosition.ts.html | 142 - .../timeline-outline/index.html | 176 - .../timeline-outline-item-list.tsx.html | 394 - .../timeline-outline.model.ts.html | 160 - .../timeline-outline.styles.ts.html | 607 - .../timeline-outline.tsx.html | 466 - .../timeline-horizontal/__tests__/index.html | 116 - .../timeline-horizontal.test.tsx.html | 925 - .../components/timeline-horizontal/index.html | 131 - .../timeline-horizontal.styles.ts.html | 190 - .../timeline-horizontal.tsx.html | 472 - .../timeline-vertical/__tests__/index.html | 131 - .../__tests__/timeline-point.test.tsx.html | 181 - .../timeline-vertical-item.test.tsx.html | 262 - .../components/timeline-vertical/index.html | 176 - .../timeline-vertical/timeline-point.tsx.html | 676 - .../timeline-vertical-item.tsx.html | 991 - .../timeline-vertical-shape.styles.ts.html | 439 - .../timeline-vertical.styles.ts.html | 757 - .../timeline-vertical.tsx.html | 523 - .../components/timeline/TimelineView.tsx.html | 406 - .../components/timeline/__tests__/index.html | 131 - .../__tests__/layout-switcher.test.tsx.html | 571 - .../timeline/__tests__/timeline.test.tsx.html | 847 - coverage/components/timeline/index.html | 221 - .../timeline-popover-elements.tsx.html | 664 - .../timeline/timeline-popover.model.ts.html | 166 - .../timeline/timeline-toolbar.model.ts.html | 205 - .../timeline/timeline-toolbar.tsx.html | 1087 -- .../timeline/timeline.style.ts.html | 805 - .../timeline/timeline.style.tsx.html | 580 - .../components/timeline/timeline.tsx.html | 1147 -- coverage/components/toggle-button/index.html | 131 - .../components/toggle-button/index.tsx.html | 178 - .../toggle-button.styles.ts.html | 100 - .../components/toolbar/__tests__/index.html | 116 - .../toolbar/__tests__/toolbar.test.tsx.html | 241 - coverage/components/toolbar/index.html | 131 - coverage/components/toolbar/index.tsx.html | 277 - .../components/toolbar/toolbar.styles.ts.html | 226 - coverage/favicon.png | Bin 445 -> 0 bytes coverage/hooks/__tests__/index.html | 281 - .../__tests__/useBackground.test.ts.html | 289 - .../hooks/__tests__/useCardSize.test.ts.html | 823 - .../hooks/__tests__/useEscapeKey.test.ts.html | 436 - .../__tests__/useMediaState.test.ts.html | 424 - .../__tests__/useOutsideClick.test.ts.html | 583 - .../__tests__/useTimelineMedia.test.ts.html | 427 - .../__tests__/useTimelineMode.test.ts.html | 466 - .../useTimelineNavigation.test.ts.html | 1369 -- .../__tests__/useTimelineScroll.test.ts.html | 688 - .../__tests__/useTimelineSearch.test.ts.html | 904 - .../hooks/__tests__/useUIState.test.ts.html | 286 - .../__tests__/useWindowSize.test.ts.html | 499 - coverage/hooks/index.html | 326 - coverage/hooks/index.ts.html | 124 - coverage/hooks/useBackground.ts.html | 145 - coverage/hooks/useCardSize.ts.html | 502 - coverage/hooks/useEscapeKey.ts.html | 265 - coverage/hooks/useMeasureHeight.ts.html | 136 - coverage/hooks/useMediaState.ts.html | 280 - coverage/hooks/useOutsideClick.ts.html | 244 - coverage/hooks/useSlideshowProgress.ts.html | 334 - coverage/hooks/useTimelineMedia.ts.html | 373 - coverage/hooks/useTimelineMode.ts.html | 253 - coverage/hooks/useTimelineNavigation.ts.html | 1057 -- coverage/hooks/useTimelineScroll.ts.html | 307 - coverage/hooks/useTimelineSearch.ts.html | 688 - coverage/hooks/useUIState.ts.html | 166 - coverage/hooks/useWindowSize.ts.html | 334 - coverage/index.html | 776 - coverage/lcov-report/__tests__/index.html | 116 - .../__tests__/react-chrono.test.ts.html | 532 - coverage/lcov-report/base.css | 224 - coverage/lcov-report/block-navigation.js | 87 - .../__tests__/GlobalContext.test.tsx.html | 2290 --- .../components/__tests__/index.html | 116 - .../components/common/styles/index.html | 116 - .../components/common/styles/index.ts.html | 145 - .../components/common/themes/index.html | 116 - .../components/common/themes/index.ts.html | 328 - .../contexts/DynamicContext.tsx.html | 256 - .../OptimizedContextProvider.tsx.html | 1192 -- .../contexts/StableContext.tsx.html | 508 - .../components/contexts/hooks.tsx.html | 640 - .../components/contexts/index.html | 191 - .../components/contexts/index.tsx.html | 145 - .../components/contexts/legacy-types.tsx.html | 193 - .../components/effects/__tests__/index.html | 161 - .../__tests__/useClickOutside.test.tsx.html | 334 - .../__tests__/useMatchMedia.test.tsx.html | 595 - .../useNewScrollPosition.test.ts.html | 1228 -- .../__tests__/useSlideshow.test.ts.html | 322 - .../lcov-report/components/effects/index.html | 161 - .../effects/useCloseClickOutside.ts.html | 133 - .../components/effects/useMatchMedia.ts.html | 421 - .../effects/useNewScrollPosition.ts.html | 412 - .../components/effects/useSlideshow.ts.html | 634 - .../elements/list/__tests__/index.html | 131 - .../list/__tests__/list-item.test.tsx.html | 337 - .../list/__tests__/list.test.tsx.html | 277 - .../components/elements/list/index.html | 161 - .../elements/list/list-item.tsx.html | 358 - .../elements/list/list.model.ts.html | 142 - .../elements/list/list.styles.ts.html | 508 - .../components/elements/list/list.tsx.html | 367 - .../elements/popover/__tests__/index.html | 116 - .../popover/__tests__/popover.test.tsx.html | 403 - .../components/elements/popover/index.html | 146 - .../elements/popover/index.tsx.html | 499 - .../elements/popover/popover.model.ts.html | 124 - .../elements/popover/popover.styles.ts.html | 496 - .../memoized/__tests__/index.html | 116 - .../memoized/__tests__/index.test.tsx.html | 559 - .../memoized/details-text-memo.tsx.html | 214 - .../memoized/expand-button-memo.tsx.html | 193 - .../timeline-elements/memoized/index.html | 191 - .../memoized/memoized-model.ts.html | 313 - .../memoized/show-hide-button.tsx.html | 187 - .../memoized/subtitle-memo.tsx.html | 193 - .../memoized/title-memo.tsx.html | 235 - .../nested-timeline-renderer/index.html | 116 - .../nested-timeline-renderer.tsx.html | 214 - .../__tests__/content-footer.test.tsx.html | 364 - .../__tests__/content-header.test.tsx.html | 238 - .../__tests__/details-text.test.tsx.html | 352 - .../__tests__/index.html | 176 - .../__tests__/text_or_content.test.tsx.html | 277 - .../timeline-card-content.test.tsx.html | 478 - .../card-animations.styles.ts.html | 220 - .../content-footer.tsx.html | 349 - .../content-header.tsx.html | 304 - .../details-text.model.ts.html | 124 - .../details-text.tsx.html | 283 - .../header-footer.model.ts.html | 145 - .../timeline-card-content/index.html | 236 - .../text-or-content.tsx.html | 514 - .../timeline-card-content.styles.ts.html | 1762 -- .../timeline-card-content.tsx.html | 1618 -- .../timeline-card-media/__tests__/index.html | 116 - .../timeline-card-media.test.tsx.html | 763 - .../components/ContentDisplay.tsx.html | 469 - .../components/ErrorMessage.tsx.html | 124 - .../components/ImageDisplay.tsx.html | 232 - .../components/MediaContent.tsx.html | 373 - .../components/VideoPlayer.tsx.html | 316 - .../components/YoutubePlayer.tsx.html | 160 - .../timeline-card-media/components/index.html | 191 - .../timeline-card-media/hooks/index.html | 161 - .../hooks/useMediaLoad.ts.html | 223 - .../hooks/useToggleControls.ts.html | 166 - .../hooks/useViewOptions.ts.html | 319 - .../hooks/useYouTubeDetection.ts.html | 124 - .../timeline-card-media/index.html | 161 - .../timeline-card-media-buttons.tsx.html | 229 - .../timeline-card-media.styles.ts.html | 850 - .../timeline-card-media.tsx.html | 529 - .../timeline-card-media/video.tsx.html | 244 - .../timeline-card/__tests__/index.html | 116 - .../timeline-horizontal-card.test.tsx.html | 487 - .../timeline-card/hooks/index.html | 116 - .../hooks/useTimelineCard.ts.html | 358 - .../timeline-card/index.html | 131 - .../timeline-card-portal/index.html | 116 - .../timeline-card-portal.tsx.html | 472 - .../timeline-horizontal-card.styles.ts.html | 925 - .../timeline-horizontal-card.tsx.html | 529 - .../timeline-card/timeline-point/index.html | 116 - .../timeline-point/timeline-point.tsx.html | 244 - .../timeline-control/__tests__/index.html | 116 - .../__tests__/timeline-control.test.tsx.html | 316 - .../timeline-control/index.html | 146 - .../timeline-control.styles.ts.html | 625 - .../timeline-control.styles.tsx.html | 124 - .../timeline-control.tsx.html | 871 - .../timeline-controls-wrapper/index.html | 116 - .../timeline-controls-wrapper.tsx.html | 160 - .../timeline-item-title/__tests__/index.html | 116 - .../timeline-card-title.test.tsx.html | 262 - .../timeline-item-title/index.html | 131 - .../timeline-card-title.styles.ts.html | 175 - .../timeline-card-title.tsx.html | 232 - .../timeline-outline/__tests__/index.html | 116 - .../__tests__/timeline-outline.test.tsx.html | 502 - .../timeline-outline/animations.ts.html | 172 - .../timeline-outline/hooks/index.html | 116 - .../hooks/useOutlinePosition.ts.html | 142 - .../timeline-outline/index.html | 176 - .../timeline-outline-item-list.tsx.html | 394 - .../timeline-outline.model.ts.html | 160 - .../timeline-outline.styles.ts.html | 607 - .../timeline-outline.tsx.html | 466 - .../timeline-horizontal/__tests__/index.html | 116 - .../timeline-horizontal.test.tsx.html | 925 - .../components/timeline-horizontal/index.html | 131 - .../timeline-horizontal.styles.ts.html | 190 - .../timeline-horizontal.tsx.html | 472 - .../timeline-vertical/__tests__/index.html | 131 - .../__tests__/timeline-point.test.tsx.html | 181 - .../timeline-vertical-item.test.tsx.html | 262 - .../components/timeline-vertical/index.html | 176 - .../timeline-vertical/timeline-point.tsx.html | 676 - .../timeline-vertical-item.tsx.html | 991 - .../timeline-vertical-shape.styles.ts.html | 439 - .../timeline-vertical.styles.ts.html | 757 - .../timeline-vertical.tsx.html | 523 - .../components/timeline/TimelineView.tsx.html | 406 - .../components/timeline/__tests__/index.html | 131 - .../__tests__/layout-switcher.test.tsx.html | 571 - .../timeline/__tests__/timeline.test.tsx.html | 847 - .../components/timeline/index.html | 221 - .../timeline-popover-elements.tsx.html | 664 - .../timeline/timeline-popover.model.ts.html | 166 - .../timeline/timeline-toolbar.model.ts.html | 205 - .../timeline/timeline-toolbar.tsx.html | 1087 -- .../timeline/timeline.style.ts.html | 805 - .../timeline/timeline.style.tsx.html | 580 - .../components/timeline/timeline.tsx.html | 1147 -- .../components/toggle-button/index.html | 131 - .../components/toggle-button/index.tsx.html | 178 - .../toggle-button.styles.ts.html | 100 - .../components/toolbar/__tests__/index.html | 116 - .../toolbar/__tests__/toolbar.test.tsx.html | 241 - .../lcov-report/components/toolbar/index.html | 131 - .../components/toolbar/index.tsx.html | 277 - .../components/toolbar/toolbar.styles.ts.html | 226 - coverage/lcov-report/favicon.png | Bin 445 -> 0 bytes .../lcov-report/hooks/__tests__/index.html | 281 - .../__tests__/useBackground.test.ts.html | 289 - .../hooks/__tests__/useCardSize.test.ts.html | 823 - .../hooks/__tests__/useEscapeKey.test.ts.html | 436 - .../__tests__/useMediaState.test.ts.html | 424 - .../__tests__/useOutsideClick.test.ts.html | 583 - .../__tests__/useTimelineMedia.test.ts.html | 427 - .../__tests__/useTimelineMode.test.ts.html | 466 - .../useTimelineNavigation.test.ts.html | 1369 -- .../__tests__/useTimelineScroll.test.ts.html | 688 - .../__tests__/useTimelineSearch.test.ts.html | 904 - .../hooks/__tests__/useUIState.test.ts.html | 286 - .../__tests__/useWindowSize.test.ts.html | 499 - coverage/lcov-report/hooks/index.html | 326 - coverage/lcov-report/hooks/index.ts.html | 124 - .../lcov-report/hooks/useBackground.ts.html | 145 - .../lcov-report/hooks/useCardSize.ts.html | 502 - .../lcov-report/hooks/useEscapeKey.ts.html | 265 - .../hooks/useMeasureHeight.ts.html | 136 - .../lcov-report/hooks/useMediaState.ts.html | 280 - .../lcov-report/hooks/useOutsideClick.ts.html | 244 - .../hooks/useSlideshowProgress.ts.html | 334 - .../hooks/useTimelineMedia.ts.html | 373 - .../lcov-report/hooks/useTimelineMode.ts.html | 253 - .../hooks/useTimelineNavigation.ts.html | 1057 -- .../hooks/useTimelineScroll.ts.html | 307 - .../hooks/useTimelineSearch.ts.html | 688 - coverage/lcov-report/hooks/useUIState.ts.html | 166 - .../lcov-report/hooks/useWindowSize.ts.html | 334 - coverage/lcov-report/index.html | 776 - coverage/lcov-report/prettify.css | 1 - coverage/lcov-report/prettify.js | 2 - coverage/lcov-report/sort-arrow-sprite.png | Bin 138 -> 0 bytes coverage/lcov-report/sorter.js | 196 - coverage/lcov-report/utils/index.html | 221 - coverage/lcov-report/utils/index.ts.html | 715 - .../utils/mediaQueryUtils.test.ts.html | 298 - .../lcov-report/utils/mediaQueryUtils.ts.html | 274 - .../utils/performance.test.ts.html | 376 - .../lcov-report/utils/performance.ts.html | 892 - .../utils/timelineUtils.test.ts.html | 484 - .../lcov-report/utils/timelineUtils.ts.html | 616 - coverage/lcov-report/utils/utils.test.ts.html | 406 - coverage/lcov.info | 15394 ---------------- coverage/prettify.css | 1 - coverage/prettify.js | 2 - coverage/sort-arrow-sprite.png | Bin 138 -> 0 bytes coverage/sorter.js | 196 - coverage/utils/index.html | 221 - coverage/utils/index.ts.html | 715 - coverage/utils/mediaQueryUtils.test.ts.html | 298 - coverage/utils/mediaQueryUtils.ts.html | 274 - coverage/utils/performance.test.ts.html | 376 - coverage/utils/performance.ts.html | 892 - coverage/utils/timelineUtils.test.ts.html | 484 - coverage/utils/timelineUtils.ts.html | 616 - coverage/utils/utils.test.ts.html | 406 - cypress/tsconfig.json | 23 +- eslint.config.mjs | 150 +- package.json | 24 +- pnpm-lock.yaml | 8 + postcss.config.js | 52 +- postcss.config.mjs | 53 + src/components/GlobalContext.tsx | 2 +- .../__tests__/GlobalContext.test.tsx | 4 +- src/components/common/styles/index.ts | 6 +- .../contexts/OptimizedContextProvider.tsx | 2 +- .../effects/__tests__/useMatchMedia.test.tsx | 24 +- src/components/elements/list/list-item.tsx | 6 +- src/components/elements/list/list.styles.ts | 25 +- src/components/elements/list/list.tsx | 2 +- .../popover/__tests__/popover.test.tsx | 8 +- src/components/elements/popover/index.tsx | 2 +- .../elements/popover/popover.styles.ts | 8 +- src/components/index.tsx | 18 +- .../memoized/__tests__/index.test.tsx | 32 +- .../memoized/expand-button-memo.tsx | 2 +- .../memoized/show-hide-button.tsx | 2 +- .../timeline-elements/memoized/title-memo.tsx | 2 +- .../nested-timeline-renderer.tsx | 2 +- .../content-header.test.tsx.snap | 6 +- .../__tests__/content-header.test.tsx | 10 +- .../__tests__/timeline-card-content.test.tsx | 10 +- .../timeline-card-content/content-footer.tsx | 4 +- .../timeline-card-content/text-or-content.tsx | 4 +- .../timeline-card-content.styles.ts | 113 +- .../timeline-card-content.tsx | 6 +- .../timeline-card-media.test.tsx.snap | 22 +- .../__tests__/timeline-card-media.test.tsx | 32 +- .../components/ContentDisplay.tsx | 6 +- .../components/ImageDisplay.tsx | 8 +- .../components/MediaContent.tsx | 4 +- .../components/VideoPlayer.tsx | 4 +- .../components/YoutubePlayer.tsx | 6 +- .../hooks/useToggleControls.ts | 4 +- .../timeline-card-media-buttons.tsx | 2 +- .../timeline-card-media.styles.ts | 41 +- .../timeline-card-media/video.tsx | 4 +- .../timeline-horizontal-card.test.tsx.snap | 10 +- .../timeline-horizontal-card.test.tsx | 6 +- .../timeline-horizontal-card.styles.ts | 34 +- .../timeline-horizontal-card.tsx | 6 +- .../timeline-point/timeline-point.tsx | 6 +- .../timeline-control.test.tsx.snap | 16 +- .../timeline-control.styles.ts | 41 +- .../timeline-control/timeline-control.tsx | 34 +- .../timeline-card-title.test.tsx.snap | 2 +- .../__tests__/timeline-card-title.test.tsx | 10 +- .../timeline-card-title.styles.ts | 12 +- .../timeline-outline.styles.ts | 22 +- .../timeline-outline/timeline-outline.tsx | 8 +- .../__tests__/timeline-horizontal.test.tsx | 14 +- .../timeline-horizontal.styles.ts | 4 +- .../timeline-horizontal.tsx | 8 +- .../timeline-point.test.tsx.snap | 6 +- .../timeline-vertical-item.test.tsx.snap | 24 +- .../timeline-vertical/timeline-point.tsx | 6 +- .../timeline-vertical-item.tsx | 4 +- .../timeline-vertical-shape.styles.ts | 15 +- .../timeline-vertical.styles.ts | 20 +- .../timeline-vertical/timeline-vertical.tsx | 2 +- .../__tests__/layout-switcher.test.tsx | 4 +- .../timeline/__tests__/timeline.test.tsx | 14 +- src/components/timeline/timeline-toolbar.tsx | 18 +- src/components/timeline/timeline.style.ts | 48 +- src/components/timeline/timeline.style.tsx | 34 +- src/components/timeline/timeline.tsx | 8 +- src/components/toolbar/index.tsx | 4 +- src/hooks/__tests__/useCardSize.test.ts | 4 +- src/hooks/__tests__/useTimelineMedia.test.ts | 2 +- src/hooks/__tests__/useTimelineMode.test.ts | 2 +- .../__tests__/useTimelineNavigation.test.ts | 2 +- src/hooks/__tests__/useTimelineScroll.test.ts | 4 +- src/hooks/__tests__/useWindowSize.test.ts | 2 +- src/hooks/useCardSize.ts | 4 +- src/hooks/useTimelineMedia.ts | 4 +- src/hooks/useUIState.ts | 2 +- src/models/Theme.ts | 3 + src/test-setup.js | 133 + src/utils/index.ts | 4 +- src/utils/mediaQueryUtils.test.ts | 8 +- src/utils/performance.test.ts | 2 +- src/utils/timelineUtils.ts | 6 +- test-results.json | 1 + test-workflows-basic.sh | 401 + tsconfig.json | 103 +- vite.config.mts | 339 +- vitest.config.mts | 251 +- 508 files changed, 4208 insertions(+), 176222 deletions(-) create mode 100644 .github/labels.yml create mode 100644 .github/workflows/ci.yml create mode 100644 .github/workflows/dependency-management.yml create mode 100644 .github/workflows/deploy.yml create mode 100644 .github/workflows/issue-management.yml create mode 100644 .github/workflows/label-sync.yml create mode 100644 .github/workflows/pr-automation.yml create mode 100644 .github/workflows/release.yml delete mode 100644 .github/workflows/sonar.yml create mode 100644 .stylelintignore delete mode 100644 coverage/__tests__/index.html delete mode 100644 coverage/__tests__/react-chrono.test.ts.html delete mode 100644 coverage/base.css delete mode 100644 coverage/block-navigation.js delete mode 100644 coverage/clover.xml delete mode 100644 coverage/components/__tests__/GlobalContext.test.tsx.html delete mode 100644 coverage/components/__tests__/index.html delete mode 100644 coverage/components/common/styles/index.html delete mode 100644 coverage/components/common/styles/index.ts.html delete mode 100644 coverage/components/common/themes/index.html delete mode 100644 coverage/components/common/themes/index.ts.html delete mode 100644 coverage/components/contexts/DynamicContext.tsx.html delete mode 100644 coverage/components/contexts/OptimizedContextProvider.tsx.html delete mode 100644 coverage/components/contexts/StableContext.tsx.html delete mode 100644 coverage/components/contexts/hooks.tsx.html delete mode 100644 coverage/components/contexts/index.html delete mode 100644 coverage/components/contexts/index.tsx.html delete mode 100644 coverage/components/contexts/legacy-types.tsx.html delete mode 100644 coverage/components/effects/__tests__/index.html delete mode 100644 coverage/components/effects/__tests__/useClickOutside.test.tsx.html delete mode 100644 coverage/components/effects/__tests__/useMatchMedia.test.tsx.html delete mode 100644 coverage/components/effects/__tests__/useNewScrollPosition.test.ts.html delete mode 100644 coverage/components/effects/__tests__/useSlideshow.test.ts.html delete mode 100644 coverage/components/effects/index.html delete mode 100644 coverage/components/effects/useCloseClickOutside.ts.html delete mode 100644 coverage/components/effects/useMatchMedia.ts.html delete mode 100644 coverage/components/effects/useNewScrollPosition.ts.html delete mode 100644 coverage/components/effects/useSlideshow.ts.html delete mode 100644 coverage/components/elements/list/__tests__/index.html delete mode 100644 coverage/components/elements/list/__tests__/list-item.test.tsx.html delete mode 100644 coverage/components/elements/list/__tests__/list.test.tsx.html delete mode 100644 coverage/components/elements/list/index.html delete mode 100644 coverage/components/elements/list/list-item.tsx.html delete mode 100644 coverage/components/elements/list/list.model.ts.html delete mode 100644 coverage/components/elements/list/list.styles.ts.html delete mode 100644 coverage/components/elements/list/list.tsx.html delete mode 100644 coverage/components/elements/popover/__tests__/index.html delete mode 100644 coverage/components/elements/popover/__tests__/popover.test.tsx.html delete mode 100644 coverage/components/elements/popover/index.html delete mode 100644 coverage/components/elements/popover/index.tsx.html delete mode 100644 coverage/components/elements/popover/popover.model.ts.html delete mode 100644 coverage/components/elements/popover/popover.styles.ts.html delete mode 100644 coverage/components/timeline-elements/memoized/__tests__/index.html delete mode 100644 coverage/components/timeline-elements/memoized/__tests__/index.test.tsx.html delete mode 100644 coverage/components/timeline-elements/memoized/details-text-memo.tsx.html delete mode 100644 coverage/components/timeline-elements/memoized/expand-button-memo.tsx.html delete mode 100644 coverage/components/timeline-elements/memoized/index.html delete mode 100644 coverage/components/timeline-elements/memoized/memoized-model.ts.html delete mode 100644 coverage/components/timeline-elements/memoized/show-hide-button.tsx.html delete mode 100644 coverage/components/timeline-elements/memoized/subtitle-memo.tsx.html delete mode 100644 coverage/components/timeline-elements/memoized/title-memo.tsx.html delete mode 100644 coverage/components/timeline-elements/nested-timeline-renderer/index.html delete mode 100644 coverage/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/__tests__/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/content-footer.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/content-header.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/details-text.model.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/details-text.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/header-footer.model.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/text-or-content.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/__tests__/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/components/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/hooks/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card-media/video.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card/__tests__/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card/hooks/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card/timeline-card-portal/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-card/timeline-point/index.html delete mode 100644 coverage/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-control/__tests__/index.html delete mode 100644 coverage/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-control/index.html delete mode 100644 coverage/components/timeline-elements/timeline-control/timeline-control.styles.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-control/timeline-control.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-controls-wrapper/index.html delete mode 100644 coverage/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-item-title/__tests__/index.html delete mode 100644 coverage/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-item-title/index.html delete mode 100644 coverage/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/__tests__/index.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/animations.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/hooks/index.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/index.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html delete mode 100644 coverage/components/timeline-elements/timeline-outline/timeline-outline.tsx.html delete mode 100644 coverage/components/timeline-horizontal/__tests__/index.html delete mode 100644 coverage/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html delete mode 100644 coverage/components/timeline-horizontal/index.html delete mode 100644 coverage/components/timeline-horizontal/timeline-horizontal.styles.ts.html delete mode 100644 coverage/components/timeline-horizontal/timeline-horizontal.tsx.html delete mode 100644 coverage/components/timeline-vertical/__tests__/index.html delete mode 100644 coverage/components/timeline-vertical/__tests__/timeline-point.test.tsx.html delete mode 100644 coverage/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html delete mode 100644 coverage/components/timeline-vertical/index.html delete mode 100644 coverage/components/timeline-vertical/timeline-point.tsx.html delete mode 100644 coverage/components/timeline-vertical/timeline-vertical-item.tsx.html delete mode 100644 coverage/components/timeline-vertical/timeline-vertical-shape.styles.ts.html delete mode 100644 coverage/components/timeline-vertical/timeline-vertical.styles.ts.html delete mode 100644 coverage/components/timeline-vertical/timeline-vertical.tsx.html delete mode 100644 coverage/components/timeline/TimelineView.tsx.html delete mode 100644 coverage/components/timeline/__tests__/index.html delete mode 100644 coverage/components/timeline/__tests__/layout-switcher.test.tsx.html delete mode 100644 coverage/components/timeline/__tests__/timeline.test.tsx.html delete mode 100644 coverage/components/timeline/index.html delete mode 100644 coverage/components/timeline/timeline-popover-elements.tsx.html delete mode 100644 coverage/components/timeline/timeline-popover.model.ts.html delete mode 100644 coverage/components/timeline/timeline-toolbar.model.ts.html delete mode 100644 coverage/components/timeline/timeline-toolbar.tsx.html delete mode 100644 coverage/components/timeline/timeline.style.ts.html delete mode 100644 coverage/components/timeline/timeline.style.tsx.html delete mode 100644 coverage/components/timeline/timeline.tsx.html delete mode 100644 coverage/components/toggle-button/index.html delete mode 100644 coverage/components/toggle-button/index.tsx.html delete mode 100644 coverage/components/toggle-button/toggle-button.styles.ts.html delete mode 100644 coverage/components/toolbar/__tests__/index.html delete mode 100644 coverage/components/toolbar/__tests__/toolbar.test.tsx.html delete mode 100644 coverage/components/toolbar/index.html delete mode 100644 coverage/components/toolbar/index.tsx.html delete mode 100644 coverage/components/toolbar/toolbar.styles.ts.html delete mode 100644 coverage/favicon.png delete mode 100644 coverage/hooks/__tests__/index.html delete mode 100644 coverage/hooks/__tests__/useBackground.test.ts.html delete mode 100644 coverage/hooks/__tests__/useCardSize.test.ts.html delete mode 100644 coverage/hooks/__tests__/useEscapeKey.test.ts.html delete mode 100644 coverage/hooks/__tests__/useMediaState.test.ts.html delete mode 100644 coverage/hooks/__tests__/useOutsideClick.test.ts.html delete mode 100644 coverage/hooks/__tests__/useTimelineMedia.test.ts.html delete mode 100644 coverage/hooks/__tests__/useTimelineMode.test.ts.html delete mode 100644 coverage/hooks/__tests__/useTimelineNavigation.test.ts.html delete mode 100644 coverage/hooks/__tests__/useTimelineScroll.test.ts.html delete mode 100644 coverage/hooks/__tests__/useTimelineSearch.test.ts.html delete mode 100644 coverage/hooks/__tests__/useUIState.test.ts.html delete mode 100644 coverage/hooks/__tests__/useWindowSize.test.ts.html delete mode 100644 coverage/hooks/index.html delete mode 100644 coverage/hooks/index.ts.html delete mode 100644 coverage/hooks/useBackground.ts.html delete mode 100644 coverage/hooks/useCardSize.ts.html delete mode 100644 coverage/hooks/useEscapeKey.ts.html delete mode 100644 coverage/hooks/useMeasureHeight.ts.html delete mode 100644 coverage/hooks/useMediaState.ts.html delete mode 100644 coverage/hooks/useOutsideClick.ts.html delete mode 100644 coverage/hooks/useSlideshowProgress.ts.html delete mode 100644 coverage/hooks/useTimelineMedia.ts.html delete mode 100644 coverage/hooks/useTimelineMode.ts.html delete mode 100644 coverage/hooks/useTimelineNavigation.ts.html delete mode 100644 coverage/hooks/useTimelineScroll.ts.html delete mode 100644 coverage/hooks/useTimelineSearch.ts.html delete mode 100644 coverage/hooks/useUIState.ts.html delete mode 100644 coverage/hooks/useWindowSize.ts.html delete mode 100644 coverage/index.html delete mode 100644 coverage/lcov-report/__tests__/index.html delete mode 100644 coverage/lcov-report/__tests__/react-chrono.test.ts.html delete mode 100644 coverage/lcov-report/base.css delete mode 100644 coverage/lcov-report/block-navigation.js delete mode 100644 coverage/lcov-report/components/__tests__/GlobalContext.test.tsx.html delete mode 100644 coverage/lcov-report/components/__tests__/index.html delete mode 100644 coverage/lcov-report/components/common/styles/index.html delete mode 100644 coverage/lcov-report/components/common/styles/index.ts.html delete mode 100644 coverage/lcov-report/components/common/themes/index.html delete mode 100644 coverage/lcov-report/components/common/themes/index.ts.html delete mode 100644 coverage/lcov-report/components/contexts/DynamicContext.tsx.html delete mode 100644 coverage/lcov-report/components/contexts/OptimizedContextProvider.tsx.html delete mode 100644 coverage/lcov-report/components/contexts/StableContext.tsx.html delete mode 100644 coverage/lcov-report/components/contexts/hooks.tsx.html delete mode 100644 coverage/lcov-report/components/contexts/index.html delete mode 100644 coverage/lcov-report/components/contexts/index.tsx.html delete mode 100644 coverage/lcov-report/components/contexts/legacy-types.tsx.html delete mode 100644 coverage/lcov-report/components/effects/__tests__/index.html delete mode 100644 coverage/lcov-report/components/effects/__tests__/useClickOutside.test.tsx.html delete mode 100644 coverage/lcov-report/components/effects/__tests__/useMatchMedia.test.tsx.html delete mode 100644 coverage/lcov-report/components/effects/__tests__/useNewScrollPosition.test.ts.html delete mode 100644 coverage/lcov-report/components/effects/__tests__/useSlideshow.test.ts.html delete mode 100644 coverage/lcov-report/components/effects/index.html delete mode 100644 coverage/lcov-report/components/effects/useCloseClickOutside.ts.html delete mode 100644 coverage/lcov-report/components/effects/useMatchMedia.ts.html delete mode 100644 coverage/lcov-report/components/effects/useNewScrollPosition.ts.html delete mode 100644 coverage/lcov-report/components/effects/useSlideshow.ts.html delete mode 100644 coverage/lcov-report/components/elements/list/__tests__/index.html delete mode 100644 coverage/lcov-report/components/elements/list/__tests__/list-item.test.tsx.html delete mode 100644 coverage/lcov-report/components/elements/list/__tests__/list.test.tsx.html delete mode 100644 coverage/lcov-report/components/elements/list/index.html delete mode 100644 coverage/lcov-report/components/elements/list/list-item.tsx.html delete mode 100644 coverage/lcov-report/components/elements/list/list.model.ts.html delete mode 100644 coverage/lcov-report/components/elements/list/list.styles.ts.html delete mode 100644 coverage/lcov-report/components/elements/list/list.tsx.html delete mode 100644 coverage/lcov-report/components/elements/popover/__tests__/index.html delete mode 100644 coverage/lcov-report/components/elements/popover/__tests__/popover.test.tsx.html delete mode 100644 coverage/lcov-report/components/elements/popover/index.html delete mode 100644 coverage/lcov-report/components/elements/popover/index.tsx.html delete mode 100644 coverage/lcov-report/components/elements/popover/popover.model.ts.html delete mode 100644 coverage/lcov-report/components/elements/popover/popover.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/details-text-memo.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/expand-button-memo.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/memoized-model.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/show-hide-button.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/subtitle-memo.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/memoized/title-memo.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/content-footer.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/content-header.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.model.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/header-footer.model.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/text-or-content.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/components/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card-media/video.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/hooks/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-control/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-item-title/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/animations.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/index.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-horizontal/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-horizontal/index.html delete mode 100644 coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/__tests__/timeline-point.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/index.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/timeline-point.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/timeline-vertical-item.tsx.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/timeline-vertical-shape.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/timeline-vertical.styles.ts.html delete mode 100644 coverage/lcov-report/components/timeline-vertical/timeline-vertical.tsx.html delete mode 100644 coverage/lcov-report/components/timeline/TimelineView.tsx.html delete mode 100644 coverage/lcov-report/components/timeline/__tests__/index.html delete mode 100644 coverage/lcov-report/components/timeline/__tests__/layout-switcher.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline/__tests__/timeline.test.tsx.html delete mode 100644 coverage/lcov-report/components/timeline/index.html delete mode 100644 coverage/lcov-report/components/timeline/timeline-popover-elements.tsx.html delete mode 100644 coverage/lcov-report/components/timeline/timeline-popover.model.ts.html delete mode 100644 coverage/lcov-report/components/timeline/timeline-toolbar.model.ts.html delete mode 100644 coverage/lcov-report/components/timeline/timeline-toolbar.tsx.html delete mode 100644 coverage/lcov-report/components/timeline/timeline.style.ts.html delete mode 100644 coverage/lcov-report/components/timeline/timeline.style.tsx.html delete mode 100644 coverage/lcov-report/components/timeline/timeline.tsx.html delete mode 100644 coverage/lcov-report/components/toggle-button/index.html delete mode 100644 coverage/lcov-report/components/toggle-button/index.tsx.html delete mode 100644 coverage/lcov-report/components/toggle-button/toggle-button.styles.ts.html delete mode 100644 coverage/lcov-report/components/toolbar/__tests__/index.html delete mode 100644 coverage/lcov-report/components/toolbar/__tests__/toolbar.test.tsx.html delete mode 100644 coverage/lcov-report/components/toolbar/index.html delete mode 100644 coverage/lcov-report/components/toolbar/index.tsx.html delete mode 100644 coverage/lcov-report/components/toolbar/toolbar.styles.ts.html delete mode 100644 coverage/lcov-report/favicon.png delete mode 100644 coverage/lcov-report/hooks/__tests__/index.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useBackground.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useCardSize.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useEscapeKey.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useMediaState.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useOutsideClick.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useTimelineMedia.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useTimelineMode.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useTimelineNavigation.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useTimelineScroll.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useTimelineSearch.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useUIState.test.ts.html delete mode 100644 coverage/lcov-report/hooks/__tests__/useWindowSize.test.ts.html delete mode 100644 coverage/lcov-report/hooks/index.html delete mode 100644 coverage/lcov-report/hooks/index.ts.html delete mode 100644 coverage/lcov-report/hooks/useBackground.ts.html delete mode 100644 coverage/lcov-report/hooks/useCardSize.ts.html delete mode 100644 coverage/lcov-report/hooks/useEscapeKey.ts.html delete mode 100644 coverage/lcov-report/hooks/useMeasureHeight.ts.html delete mode 100644 coverage/lcov-report/hooks/useMediaState.ts.html delete mode 100644 coverage/lcov-report/hooks/useOutsideClick.ts.html delete mode 100644 coverage/lcov-report/hooks/useSlideshowProgress.ts.html delete mode 100644 coverage/lcov-report/hooks/useTimelineMedia.ts.html delete mode 100644 coverage/lcov-report/hooks/useTimelineMode.ts.html delete mode 100644 coverage/lcov-report/hooks/useTimelineNavigation.ts.html delete mode 100644 coverage/lcov-report/hooks/useTimelineScroll.ts.html delete mode 100644 coverage/lcov-report/hooks/useTimelineSearch.ts.html delete mode 100644 coverage/lcov-report/hooks/useUIState.ts.html delete mode 100644 coverage/lcov-report/hooks/useWindowSize.ts.html delete mode 100644 coverage/lcov-report/index.html delete mode 100644 coverage/lcov-report/prettify.css delete mode 100644 coverage/lcov-report/prettify.js delete mode 100644 coverage/lcov-report/sort-arrow-sprite.png delete mode 100644 coverage/lcov-report/sorter.js delete mode 100644 coverage/lcov-report/utils/index.html delete mode 100644 coverage/lcov-report/utils/index.ts.html delete mode 100644 coverage/lcov-report/utils/mediaQueryUtils.test.ts.html delete mode 100644 coverage/lcov-report/utils/mediaQueryUtils.ts.html delete mode 100644 coverage/lcov-report/utils/performance.test.ts.html delete mode 100644 coverage/lcov-report/utils/performance.ts.html delete mode 100644 coverage/lcov-report/utils/timelineUtils.test.ts.html delete mode 100644 coverage/lcov-report/utils/timelineUtils.ts.html delete mode 100644 coverage/lcov-report/utils/utils.test.ts.html delete mode 100644 coverage/lcov.info delete mode 100644 coverage/prettify.css delete mode 100644 coverage/prettify.js delete mode 100644 coverage/sort-arrow-sprite.png delete mode 100644 coverage/sorter.js delete mode 100644 coverage/utils/index.html delete mode 100644 coverage/utils/index.ts.html delete mode 100644 coverage/utils/mediaQueryUtils.test.ts.html delete mode 100644 coverage/utils/mediaQueryUtils.ts.html delete mode 100644 coverage/utils/performance.test.ts.html delete mode 100644 coverage/utils/performance.ts.html delete mode 100644 coverage/utils/timelineUtils.test.ts.html delete mode 100644 coverage/utils/timelineUtils.ts.html delete mode 100644 coverage/utils/utils.test.ts.html create mode 100644 postcss.config.mjs create mode 100644 test-results.json create mode 100755 test-workflows-basic.sh diff --git a/.github/labels.yml b/.github/labels.yml new file mode 100644 index 000000000..5cce7f617 --- /dev/null +++ b/.github/labels.yml @@ -0,0 +1,208 @@ +# GitHub Labels Configuration +# This file defines all labels used in the repository for automated workflows + +# Priority Labels +- name: "priority/critical" + color: "d73a4a" + description: "Critical priority - needs immediate attention" + +- name: "priority/high" + color: "ff6b6b" + description: "High priority - should be addressed soon" + +- name: "priority/medium" + color: "fbca04" + description: "Medium priority - normal queue" + +- name: "priority/low" + color: "0e8a16" + description: "Low priority - can be addressed later" + +# Type Labels +- name: "type/bug" + color: "d73a4a" + description: "Something isn't working" + +- name: "type/feature" + color: "a2eeef" + description: "New feature or request" + +- name: "type/enhancement" + color: "84b6eb" + description: "Improvement to existing feature" + +- name: "type/documentation" + color: "0075ca" + description: "Documentation improvements" + +- name: "type/refactor" + color: "d4c5f9" + description: "Code refactoring" + +- name: "type/performance" + color: "ff9500" + description: "Performance improvements" + +- name: "type/security" + color: "b60205" + description: "Security-related changes" + +# Size Labels (auto-generated by PR automation) +- name: "size/XS" + color: "3cbf00" + description: "Extra small changes (< 10 lines)" + +- name: "size/S" + color: "5d9cec" + description: "Small changes (10-100 lines)" + +- name: "size/M" + color: "007ec6" + description: "Medium changes (100-500 lines)" + +- name: "size/L" + color: "f9d71c" + description: "Large changes (500-1000 lines)" + +- name: "size/XL" + color: "ee0701" + description: "Extra large changes (> 1000 lines)" + +# Component Labels +- name: "components" + color: "1d76db" + description: "Changes to React components" + +- name: "hooks" + color: "0052cc" + description: "Changes to React hooks" + +- name: "styles" + color: "e99695" + description: "Styling and CSS changes" + +- name: "types" + color: "5319e7" + description: "TypeScript type definitions" + +- name: "tests" + color: "0e8a16" + description: "Test-related changes" + +- name: "demo" + color: "fbca04" + description: "Demo application changes" + +- name: "build" + color: "d4c5f9" + description: "Build system changes" + +# Workflow Labels +- name: "dependencies" + color: "0366d6" + description: "Dependency updates" + +- name: "ci/cd" + color: "28a745" + description: "CI/CD pipeline changes" + +- name: "security" + color: "b60205" + description: "Security-related changes" + +- name: "automated" + color: "ededed" + description: "Automated changes (bots, scripts)" + +# Status Labels +- name: "status/needs-review" + color: "fbca04" + description: "Needs code review" + +- name: "status/needs-testing" + color: "d4c5f9" + description: "Needs testing" + +- name: "status/blocked" + color: "d73a4a" + description: "Blocked by other work" + +- name: "status/work-in-progress" + color: "ff9500" + description: "Work in progress" + +- name: "status/ready-to-merge" + color: "0e8a16" + description: "Ready to merge" + +# Release Labels +- name: "release/patch" + color: "c2e0c6" + description: "Patch release (bug fixes)" + +- name: "release/minor" + color: "bfd4f2" + description: "Minor release (new features)" + +- name: "release/major" + color: "f9d71c" + description: "Major release (breaking changes)" + +- name: "release/prerelease" + color: "d4c5f9" + description: "Pre-release version" + +# Special Labels +- name: "good first issue" + color: "7057ff" + description: "Good for newcomers" + +- name: "help wanted" + color: "008672" + description: "Extra attention is needed" + +- name: "question" + color: "d876e3" + description: "Further information is requested" + +- name: "invalid" + color: "e4e669" + description: "This doesn't seem right" + +- name: "wontfix" + color: "ffffff" + description: "This will not be worked on" + +- name: "duplicate" + color: "cfd3d7" + description: "This issue or pull request already exists" + +# Breaking Changes +- name: "breaking-change" + color: "d73a4a" + description: "Contains breaking changes" + +# Platform Labels +- name: "platform/web" + color: "0052cc" + description: "Web platform specific" + +- name: "platform/mobile" + color: "1d76db" + description: "Mobile platform specific" + +- name: "browser/chrome" + color: "4285f4" + description: "Chrome browser specific" + +- name: "browser/firefox" + color: "ff9500" + description: "Firefox browser specific" + +- name: "browser/safari" + color: "0070c9" + description: "Safari browser specific" + +- name: "browser/edge" + color: "0078d4" + description: "Edge browser specific" \ No newline at end of file diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3df03db5e..66301f6c1 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,52 +1,25 @@ -name: Build and Test +# Legacy Build Workflow - DEPRECATED +# This workflow has been replaced by the modern CI pipeline in ci.yml +# Keeping for backward compatibility until migration is complete + +name: Build and Test (Legacy) on: - push: - branches: [master] - pull_request: - branches: [master] + workflow_dispatch: # Manual trigger only jobs: - build-and-test: + legacy-notice: runs-on: ubuntu-latest - - strategy: - matrix: - node-version: [20.x] - steps: - - uses: pnpm/action-setup@v4 - with: - version: 8.8.0 - - - uses: actions/checkout@v4 - - - name: Cache PNPM dependencies - uses: actions/cache@v4 - with: - path: ~/.pnpm-store - key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm- - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v4 - with: - node-version: ${{ matrix.node-version }} - - - name: Install Dependencies - run: pnpm install - - - name: Cache build artifacts - uses: actions/cache@v4 - with: - path: dist - key: ${{ runner.os }}-build-${{ matrix.node-version }} - restore-keys: | - ${{ runner.os }}-build- - - - name: Build - run: pnpm rollup - - - name: Unit Tests - run: pnpm test + - name: Migration Notice + run: | + echo "⚠️ This workflow has been replaced by the modern CI pipeline" + echo "🔄 Please use the 'CI Pipeline' workflow instead" + echo "📚 See GITHUB_ACTIONS_DOCUMENTATION.md for details" + echo "" + echo "New workflow features:" + echo "- Multi-OS testing (Ubuntu, Windows, macOS)" + echo "- Multiple Node.js versions (18.x, 20.x, 22.x)" + echo "- Enhanced security scanning" + echo "- Bundle analysis and performance monitoring" + echo "- Automated PR comments with results" diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 000000000..1ac58b543 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,290 @@ +name: CI Pipeline + +on: + push: + branches: [master, develop] + pull_request: + branches: [master, develop] + +# Cancel in-progress runs for the same workflow and ref +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + +env: + NODE_VERSION: '20.x' + PNPM_VERSION: '8.8.0' + +jobs: + # Quality checks that run fast + quality-checks: + name: Quality Checks + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Type checking + run: pnpm exec tsc --noEmit + + - name: Linting + run: pnpm run lint:all + + - name: Format checking + run: pnpm run lint + + - name: Audit dependencies + run: pnpm audit --audit-level high + + # Build and test matrix across multiple environments + build-and-test: + name: Build & Test + needs: quality-checks + strategy: + fail-fast: false + matrix: + os: [ubuntu-latest, windows-latest, macos-latest] + node-version: ['18.x', '20.x', '22.x'] + exclude: + # Reduce matrix size by excluding some combinations + - os: windows-latest + node-version: '18.x' + - os: macos-latest + node-version: '18.x' + + runs-on: ${{ matrix.os }} + timeout-minutes: 20 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js ${{ matrix.node-version }} + uses: actions/setup-node@v4 + with: + node-version: ${{ matrix.node-version }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build library + run: pnpm run rollup + + - name: Run unit tests + run: pnpm test -- --coverage --reporter=verbose + + - name: Upload coverage to Codecov + if: matrix.os == 'ubuntu-latest' && matrix.node-version == '20.x' + uses: codecov/codecov-action@v4 + with: + files: ./coverage/lcov.info + flags: unittests + name: codecov-umbrella + fail_ci_if_error: false + + - name: Upload test results + if: always() + uses: actions/upload-artifact@v4 + with: + name: test-results-${{ matrix.os }}-${{ matrix.node-version }} + path: | + coverage/ + test-results.xml + retention-days: 30 + + # Bundle size analysis + bundle-analysis: + name: Bundle Analysis + needs: quality-checks + runs-on: ubuntu-latest + timeout-minutes: 10 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build and analyze bundle + run: pnpm run build:analyze + + - name: Check bundle size + run: pnpm run size-limit + + - name: Upload bundle analysis + uses: actions/upload-artifact@v4 + with: + name: bundle-analysis + path: | + dist/stats.html + dist/ + retention-days: 30 + + # Security scanning + security-scan: + name: Security Scan + needs: quality-checks + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run Snyk security scan + uses: snyk/actions/node@master + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --severity-threshold=high --json-file-output=snyk-results.json + + - name: Upload Snyk results + if: always() + uses: actions/upload-artifact@v4 + with: + name: snyk-results + path: snyk-results.json + retention-days: 30 + + # Performance benchmarks + performance-benchmarks: + name: Performance Benchmarks + needs: build-and-test + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build for performance testing + run: pnpm run rollup + + - name: Run performance benchmarks + run: | + echo "Bundle sizes:" + ls -la dist/ + echo "Gzipped sizes:" + gzip -9 -c dist/react-chrono.esm.js | wc -c + gzip -9 -c dist/react-chrono.umd.js | wc -c + + - name: Comment PR with performance results + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + const fs = require('fs'); + const path = require('path'); + + // Read bundle sizes + const distFiles = fs.readdirSync('dist/'); + const bundleInfo = distFiles + .filter(file => file.endsWith('.js')) + .map(file => { + const stats = fs.statSync(path.join('dist', file)); + return `- ${file}: ${(stats.size / 1024).toFixed(2)} KB`; + }) + .join('\n'); + + const comment = `## 📊 Performance Report + + ### Bundle Sizes + ${bundleInfo} + + ### Analysis + - Bundle analysis available in artifacts + - Size limit checks: ✅ Passed + `; + + github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + + # Final status check + ci-success: + name: CI Success + needs: [quality-checks, build-and-test, bundle-analysis, security-scan, performance-benchmarks] + runs-on: ubuntu-latest + if: always() + + steps: + - name: Check all jobs status + run: | + if [[ "${{ needs.quality-checks.result }}" == "success" && + "${{ needs.build-and-test.result }}" == "success" && + "${{ needs.bundle-analysis.result }}" == "success" && + "${{ needs.security-scan.result }}" == "success" && + "${{ needs.performance-benchmarks.result }}" == "success" ]]; then + echo "All CI checks passed! 🎉" + exit 0 + else + echo "Some CI checks failed! ❌" + exit 1 + fi \ No newline at end of file diff --git a/.github/workflows/dependency-management.yml b/.github/workflows/dependency-management.yml new file mode 100644 index 000000000..a4a737031 --- /dev/null +++ b/.github/workflows/dependency-management.yml @@ -0,0 +1,336 @@ +name: Dependency Management + +on: + schedule: + # Run every Monday at 9 AM UTC + - cron: '0 9 * * 1' + workflow_dispatch: + inputs: + update_type: + description: 'Type of update to perform' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major + - all + +env: + NODE_VERSION: '20.x' + PNPM_VERSION: '8.8.0' + +jobs: + # Audit dependencies for vulnerabilities + security-audit: + name: Security Audit + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run npm audit + run: | + echo "## NPM Audit Results" > audit-report.md + echo "\`\`\`" >> audit-report.md + pnpm audit --audit-level moderate || echo "Audit found issues" >> audit-report.md + echo "\`\`\`" >> audit-report.md + + - name: Run Snyk audit + continue-on-error: true + run: | + echo "## Snyk Audit Results" >> audit-report.md + echo "\`\`\`" >> audit-report.md + pnpm exec snyk test --severity-threshold=high || echo "Snyk found issues" >> audit-report.md + echo "\`\`\`" >> audit-report.md + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + + - name: Check for outdated dependencies + run: | + echo "## Outdated Dependencies" >> audit-report.md + echo "\`\`\`" >> audit-report.md + pnpm outdated || echo "Some dependencies are outdated" >> audit-report.md + echo "\`\`\`" >> audit-report.md + + - name: Upload audit report + uses: actions/upload-artifact@v4 + with: + name: security-audit-report + path: audit-report.md + retention-days: 30 + + # Update dependencies automatically + auto-update: + name: Auto Update Dependencies + runs-on: ubuntu-latest + needs: security-audit + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + token: ${{ secrets.GITHUB_TOKEN }} + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Configure git + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Update dependencies + run: | + UPDATE_TYPE="${{ github.event.inputs.update_type || 'patch' }}" + + case $UPDATE_TYPE in + "patch") + pnpm update --latest --filter='!@types/*' --filter='!*@beta' --filter='!*@alpha' + ;; + "minor") + pnpm update --latest --filter='!@types/*' --filter='!*@beta' --filter='!*@alpha' --depth=1 + ;; + "major") + pnpm update --latest --filter='!@types/*' --filter='!*@beta' --filter='!*@alpha' --depth=Infinity + ;; + "all") + pnpm update --latest + ;; + esac + + - name: Check for changes + id: changes + run: | + if git diff --quiet package.json pnpm-lock.yaml; then + echo "has_changes=false" >> $GITHUB_OUTPUT + else + echo "has_changes=true" >> $GITHUB_OUTPUT + fi + + - name: Run tests after update + if: steps.changes.outputs.has_changes == 'true' + run: | + pnpm install + pnpm test --run + pnpm run rollup + + - name: Generate update summary + if: steps.changes.outputs.has_changes == 'true' + run: | + echo "## 📦 Dependency Updates" > update-summary.md + echo "" >> update-summary.md + echo "### Changed Dependencies" >> update-summary.md + echo "\`\`\`diff" >> update-summary.md + git diff package.json >> update-summary.md + echo "\`\`\`" >> update-summary.md + echo "" >> update-summary.md + echo "### Test Results" >> update-summary.md + echo "- ✅ Unit tests passed" >> update-summary.md + echo "- ✅ Build successful" >> update-summary.md + echo "" >> update-summary.md + echo "### Security Check" >> update-summary.md + pnpm audit --audit-level high > /dev/null 2>&1 && echo "- ✅ No high severity vulnerabilities" >> update-summary.md || echo "- ⚠️ Security issues found" >> update-summary.md + + - name: Create Pull Request + if: steps.changes.outputs.has_changes == 'true' + uses: peter-evans/create-pull-request@v5 + with: + token: ${{ secrets.GITHUB_TOKEN }} + commit-message: "chore: update dependencies (${{ github.event.inputs.update_type || 'patch' }})" + title: "🔄 Automated dependency updates (${{ github.event.inputs.update_type || 'patch' }})" + body-path: update-summary.md + branch: dependency-updates/${{ github.event.inputs.update_type || 'patch' }}-${{ github.run_number }} + delete-branch: true + labels: | + dependencies + automated + ${{ github.event.inputs.update_type || 'patch' }} + + # Check for known vulnerabilities + vulnerability-scan: + name: Vulnerability Scan + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Run Snyk vulnerability scan + uses: snyk/actions/node@master + continue-on-error: true + env: + SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }} + with: + args: --severity-threshold=medium --json-file-output=snyk-report.json + + - name: Upload Snyk report + uses: actions/upload-artifact@v4 + with: + name: vulnerability-scan-report + path: snyk-report.json + retention-days: 30 + + - name: Check for critical vulnerabilities + run: | + if [ -f snyk-report.json ]; then + CRITICAL_COUNT=$(jq '.vulnerabilities | map(select(.severity == "critical")) | length' snyk-report.json) + HIGH_COUNT=$(jq '.vulnerabilities | map(select(.severity == "high")) | length' snyk-report.json) + + if [ "$CRITICAL_COUNT" -gt 0 ] || [ "$HIGH_COUNT" -gt 0 ]; then + echo "🚨 Critical or high severity vulnerabilities found!" + echo "Critical: $CRITICAL_COUNT, High: $HIGH_COUNT" + + # Create an issue for critical vulnerabilities + if [ "$CRITICAL_COUNT" -gt 0 ]; then + echo "Creating issue for critical vulnerabilities..." + exit 1 + fi + fi + fi + + # License compliance check + license-check: + name: License Compliance + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Install license-checker + run: pnpm add -D license-checker + + - name: Check licenses + run: | + echo "## License Compliance Report" > license-report.md + echo "" >> license-report.md + + # Check for problematic licenses + PROBLEMATIC_LICENSES="GPL-2.0,GPL-3.0,AGPL-1.0,AGPL-3.0,LGPL-2.1,LGPL-3.0" + + echo "### Checking for problematic licenses..." >> license-report.md + if pnpm exec license-checker --excludeLicenses "$PROBLEMATIC_LICENSES" --summary > /dev/null 2>&1; then + echo "✅ No problematic licenses found" >> license-report.md + else + echo "❌ Problematic licenses detected" >> license-report.md + pnpm exec license-checker --excludeLicenses "$PROBLEMATIC_LICENSES" --summary >> license-report.md + fi + + echo "" >> license-report.md + echo "### License Summary" >> license-report.md + echo "\`\`\`" >> license-report.md + pnpm exec license-checker --summary >> license-report.md + echo "\`\`\`" >> license-report.md + + - name: Upload license report + uses: actions/upload-artifact@v4 + with: + name: license-compliance-report + path: license-report.md + retention-days: 30 + + # Dependency size analysis + bundle-impact: + name: Bundle Impact Analysis + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Analyze bundle impact + run: | + echo "## Bundle Impact Analysis" > bundle-impact.md + echo "" >> bundle-impact.md + + # Build current bundle + pnpm run rollup + + # Get bundle sizes + echo "### Current Bundle Sizes" >> bundle-impact.md + echo "\`\`\`" >> bundle-impact.md + ls -lh dist/*.js | awk '{print $9 ": " $5}' >> bundle-impact.md + echo "\`\`\`" >> bundle-impact.md + + # Analyze dependency sizes + echo "### Largest Dependencies" >> bundle-impact.md + echo "\`\`\`" >> bundle-impact.md + pnpm exec bundlephobia --json $(node -p "Object.keys(require('./package.json').dependencies).join(' ')") | jq -r '.[] | "\(.name): \(.size)"' | sort -k2 -hr | head -10 >> bundle-impact.md || echo "Bundle analysis not available" >> bundle-impact.md + echo "\`\`\`" >> bundle-impact.md + + - name: Upload bundle impact report + uses: actions/upload-artifact@v4 + with: + name: bundle-impact-report + path: bundle-impact.md + retention-days: 30 \ No newline at end of file diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml new file mode 100644 index 000000000..1d3c40ad6 --- /dev/null +++ b/.github/workflows/deploy.yml @@ -0,0 +1,319 @@ +name: Deploy Demo & Documentation + +on: + push: + branches: [master] + pull_request: + branches: [master] + workflow_dispatch: + inputs: + environment: + description: 'Environment to deploy to' + required: true + default: 'staging' + type: choice + options: + - staging + - production + deploy_docs: + description: 'Deploy documentation' + required: false + default: true + type: boolean + +env: + NODE_VERSION: '20.x' + PNPM_VERSION: '8.8.0' + +jobs: + # Build demo site and documentation + build: + name: Build Assets + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build library + run: pnpm run rollup + + - name: Build demo site + run: pnpm run vite:build + env: + NODE_ENV: production + + - name: Generate documentation + run: | + # Generate API documentation + echo "Generating API documentation..." + # Add your documentation generation commands here + # Example: pnpm run docs:build + + - name: Upload build artifacts + uses: actions/upload-artifact@v4 + with: + name: build-artifacts + path: | + dist/ + build/ + docs/ + retention-days: 30 + + # Deploy to staging (preview) + deploy-staging: + name: Deploy to Staging + runs-on: ubuntu-latest + needs: build + if: github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.environment == 'staging') + environment: + name: staging + url: ${{ steps.deploy.outputs.url }} + + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + + - name: Deploy to Netlify (Staging) + id: deploy + uses: nwtgck/actions-netlify@v3.0 + with: + publish-dir: './build' + production-branch: master + github-token: ${{ secrets.GITHUB_TOKEN }} + deploy-message: "Deploy from GitHub Actions (PR #${{ github.event.number }})" + enable-pull-request-comment: true + enable-commit-comment: true + overwrites-pull-request-comment: true + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_STAGING }} + timeout-minutes: 10 + + - name: Update deployment status + if: always() + uses: actions/github-script@v7 + with: + script: | + const status = '${{ steps.deploy.outcome }}' === 'success' ? 'success' : 'failure'; + const url = '${{ steps.deploy.outputs.url }}'; + + if (context.eventName === 'pull_request') { + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: status === 'success' + ? `🚀 **Staging deployment successful!**\n\n📱 Preview: ${url}\n\n*Deployment will be available for 7 days*` + : `❌ **Staging deployment failed!**\n\nCheck the [workflow run](${context.payload.repository.html_url}/actions/runs/${context.runId}) for details.` + }); + } + + # Deploy to production + deploy-production: + name: Deploy to Production + runs-on: ubuntu-latest + needs: build + if: github.ref == 'refs/heads/master' && github.event_name == 'push' + environment: + name: production + url: https://react-chrono-demo.netlify.app + + steps: + - name: Download build artifacts + uses: actions/download-artifact@v4 + with: + name: build-artifacts + + - name: Deploy to Netlify (Production) + id: deploy + uses: nwtgck/actions-netlify@v3.0 + with: + publish-dir: './build' + production-branch: master + github-token: ${{ secrets.GITHUB_TOKEN }} + deploy-message: "Production deployment from ${{ github.sha }}" + production-deploy: true + env: + NETLIFY_AUTH_TOKEN: ${{ secrets.NETLIFY_AUTH_TOKEN }} + NETLIFY_SITE_ID: ${{ secrets.NETLIFY_SITE_ID_PRODUCTION }} + timeout-minutes: 10 + + - name: Update GitHub deployment status + if: always() + uses: actions/github-script@v7 + with: + script: | + const status = '${{ steps.deploy.outcome }}' === 'success' ? 'success' : 'failure'; + const url = '${{ steps.deploy.outputs.url }}'; + + await github.rest.repos.createDeploymentStatus({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: context.payload.deployment?.id || 0, + state: status, + target_url: url, + description: status === 'success' ? 'Production deployment successful' : 'Production deployment failed' + }); + + # Deploy documentation + deploy-docs: + name: Deploy Documentation + runs-on: ubuntu-latest + needs: build + if: github.ref == 'refs/heads/master' && github.event_name == 'push' && github.event.inputs.deploy_docs != 'false' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: ${{ env.PNPM_VERSION }} + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + cache: 'pnpm' + + - name: Install dependencies + run: pnpm install --frozen-lockfile + + - name: Build documentation + run: | + # Generate comprehensive documentation + echo "Building documentation..." + + # Create docs directory structure + mkdir -p docs/api docs/examples docs/guides + + # Copy README and other markdown files + cp README.md docs/ + cp CONTRIBUTING.md docs/guides/ + cp CODE_OF_CONDUCT.md docs/guides/ + + # Generate API documentation (if you have a docs generator) + # pnpm run docs:api + + # Copy examples + cp -r src/examples/* docs/examples/ || true + + # Generate changelog + echo "# Changelog" > docs/CHANGELOG.md + git log --oneline --decorate --graph --all >> docs/CHANGELOG.md + + - name: Deploy to GitHub Pages + uses: peaceiris/actions-gh-pages@v3 + with: + github_token: ${{ secrets.GITHUB_TOKEN }} + publish_dir: ./docs + cname: react-chrono-docs.com # Replace with your custom domain if you have one + + # Performance monitoring + performance-monitoring: + name: Performance Monitoring + runs-on: ubuntu-latest + needs: [deploy-staging, deploy-production] + if: always() && (needs.deploy-staging.result == 'success' || needs.deploy-production.result == 'success') + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: ${{ env.NODE_VERSION }} + + - name: Install Lighthouse CI + run: npm install -g @lhci/cli + + - name: Run Lighthouse CI + run: | + # Determine which URL to test + if [ "${{ needs.deploy-production.result }}" == "success" ]; then + URL="https://react-chrono-demo.netlify.app" + else + URL="${{ needs.deploy-staging.outputs.url }}" + fi + + lhci autorun --upload.target=temporary-public-storage --collect.url="$URL" + env: + LHCI_GITHUB_APP_TOKEN: ${{ secrets.LHCI_GITHUB_APP_TOKEN }} + + - name: Comment performance results + if: github.event_name == 'pull_request' + uses: actions/github-script@v7 + with: + script: | + // Add performance results to PR comment + const comment = `## 📊 Performance Report + + Lighthouse CI has analyzed the deployed preview: + - **Performance**: Check the full report in the workflow artifacts + - **Accessibility**: Automated accessibility checks completed + - **Best Practices**: Modern web standards compliance verified + - **SEO**: Search engine optimization validated + + 📈 Full performance metrics available in the [workflow run](${context.payload.repository.html_url}/actions/runs/${context.runId})`; + + await github.rest.issues.createComment({ + issue_number: context.issue.number, + owner: context.repo.owner, + repo: context.repo.repo, + body: comment + }); + + # Cleanup old deployments + cleanup: + name: Cleanup Old Deployments + runs-on: ubuntu-latest + if: always() + + steps: + - name: Cleanup staging deployments + uses: actions/github-script@v7 + with: + script: | + // Clean up deployments older than 7 days for staging + const sevenDaysAgo = new Date(); + sevenDaysAgo.setDate(sevenDaysAgo.getDate() - 7); + + const { data: deployments } = await github.rest.repos.listDeployments({ + owner: context.repo.owner, + repo: context.repo.repo, + environment: 'staging' + }); + + for (const deployment of deployments) { + const deploymentDate = new Date(deployment.created_at); + if (deploymentDate < sevenDaysAgo) { + await github.rest.repos.deleteDeployment({ + owner: context.repo.owner, + repo: context.repo.repo, + deployment_id: deployment.id + }); + } + } \ No newline at end of file diff --git a/.github/workflows/issue-management.yml b/.github/workflows/issue-management.yml new file mode 100644 index 000000000..a9097782b --- /dev/null +++ b/.github/workflows/issue-management.yml @@ -0,0 +1,302 @@ +name: Issue Management + +on: + issues: + types: [opened, edited, labeled, unlabeled] + issue_comment: + types: [created] + schedule: + # Run daily at 2 AM UTC + - cron: '0 2 * * *' + workflow_dispatch: + +jobs: + # Auto-label issues based on content + auto-label-issues: + name: Auto Label Issues + runs-on: ubuntu-latest + if: github.event_name == 'issues' && github.event.action == 'opened' + + steps: + - name: Label issues + uses: actions/github-script@v7 + with: + script: | + const issue = context.payload.issue; + const title = issue.title.toLowerCase(); + const body = issue.body ? issue.body.toLowerCase() : ''; + const labels = []; + + // Bug detection + if (title.includes('bug') || title.includes('error') || title.includes('broken') || + body.includes('error') || body.includes('exception') || body.includes('not working')) { + labels.push('type/bug'); + } + + // Feature request detection + if (title.includes('feature') || title.includes('request') || title.includes('enhancement') || + body.includes('would like') || body.includes('could you') || body.includes('feature request')) { + labels.push('type/feature'); + } + + // Documentation detection + if (title.includes('doc') || title.includes('readme') || title.includes('documentation') || + body.includes('documentation') || body.includes('docs')) { + labels.push('type/documentation'); + } + + // Performance detection + if (title.includes('performance') || title.includes('slow') || title.includes('speed') || + body.includes('performance') || body.includes('optimization')) { + labels.push('type/performance'); + } + + // Security detection + if (title.includes('security') || title.includes('vulnerability') || title.includes('exploit') || + body.includes('security') || body.includes('vulnerability')) { + labels.push('type/security'); + } + + // Question detection + if (title.includes('?') || title.includes('how to') || title.includes('question') || + body.includes('how do i') || body.includes('question')) { + labels.push('question'); + } + + // Component-specific labels + if (body.includes('timeline') || body.includes('chrono')) { + labels.push('components'); + } + + // Browser-specific labels + if (body.includes('chrome')) labels.push('browser/chrome'); + if (body.includes('firefox')) labels.push('browser/firefox'); + if (body.includes('safari')) labels.push('browser/safari'); + if (body.includes('edge')) labels.push('browser/edge'); + + // Good first issue detection + if (title.includes('good first issue') || body.includes('good first issue') || + (title.includes('typo') || title.includes('small fix'))) { + labels.push('good first issue'); + } + + // Apply labels + if (labels.length > 0) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: issue.number, + labels: labels + }); + } + + # Welcome new issue creators + welcome-new-issues: + name: Welcome New Contributors + runs-on: ubuntu-latest + if: github.event_name == 'issues' && github.event.action == 'opened' + + steps: + - name: Welcome first-time issue creators + uses: actions/github-script@v7 + with: + script: | + const author = context.payload.issue.user.login; + + // Check if this is the author's first issue + const { data: issues } = await github.rest.issues.listForRepo({ + owner: context.repo.owner, + repo: context.repo.repo, + creator: author, + state: 'all' + }); + + if (issues.length === 1) { + const welcomeMessage = `## 👋 Welcome to React Chrono! + + Thank you for opening your first issue! We appreciate your contribution to making React Chrono better. + + ### What happens next? + 1. A maintainer will review your issue + 2. We may ask for additional information or clarification + 3. If it's a bug, we'll work on reproducing and fixing it + 4. If it's a feature request, we'll discuss its feasibility + + ### Guidelines + - Please provide as much detail as possible + - Include steps to reproduce for bugs + - Add screenshots or code examples if helpful + - Be patient - we're a small team but we care about every issue! + + ### Resources + - [Contributing Guide](./CONTRIBUTING.md) + - [Code of Conduct](./CODE_OF_CONDUCT.md) + - [Documentation](./README.md) + + Thanks again for helping improve React Chrono! 🚀`; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: welcomeMessage + }); + } + + # Handle stale issues + stale-issues: + name: Handle Stale Issues + runs-on: ubuntu-latest + if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch' + + steps: + - name: Mark stale issues + uses: actions/stale@v9 + with: + repo-token: ${{ secrets.GITHUB_TOKEN }} + stale-issue-message: | + ## 🤖 Stale Issue Notice + + This issue has been automatically marked as stale because it has not had recent activity. + It will be closed if no further activity occurs within 7 days. + + If this issue is still relevant, please: + - Add a comment to keep it open + - Provide additional information if requested + - Update the issue with current status + + Thank you for your contributions to React Chrono! + close-issue-message: | + ## 🤖 Issue Closed + + This issue has been automatically closed due to inactivity. If you believe this issue is still relevant, please feel free to reopen it or create a new issue with updated information. + + Thank you for your understanding! + stale-issue-label: 'status/stale' + close-issue-label: 'status/closed-stale' + days-before-stale: 30 + days-before-close: 7 + exempt-issue-labels: 'priority/high,priority/critical,status/blocked,good first issue' + exempt-pr-labels: 'status/blocked,status/work-in-progress' + stale-pr-message: | + ## 🤖 Stale PR Notice + + This pull request has been automatically marked as stale because it has not had recent activity. + It will be closed if no further activity occurs within 7 days. + + If this PR is still relevant, please: + - Rebase against the latest master branch + - Address any review comments + - Add a comment to keep it open + + Thank you for your contributions! + close-pr-message: | + ## 🤖 PR Closed + + This pull request has been automatically closed due to inactivity. If you would like to continue this work, please feel free to reopen it or create a new PR. + + Thank you for your contributions! + days-before-pr-stale: 21 + days-before-pr-close: 7 + + # Handle issue commands + issue-commands: + name: Handle Issue Commands + runs-on: ubuntu-latest + if: github.event_name == 'issue_comment' && github.event.action == 'created' + + steps: + - name: Handle commands + uses: actions/github-script@v7 + with: + script: | + const comment = context.payload.comment.body.trim(); + const commenter = context.payload.comment.user.login; + + // Only allow maintainers to run commands + const { data: collaborators } = await github.rest.repos.listCollaborators({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + + const isMaintainer = collaborators.some(collab => + collab.login === commenter && + ['admin', 'write'].includes(collab.permissions.admin ? 'admin' : 'write') + ); + + if (!isMaintainer) { + console.log('User is not a maintainer, ignoring command'); + return; + } + + // Close issue command + if (comment.startsWith('/close')) { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + state: 'closed' + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `✅ Issue closed by @${commenter}` + }); + } + + // Reopen issue command + if (comment.startsWith('/reopen')) { + await github.rest.issues.update({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + state: 'open' + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `🔄 Issue reopened by @${commenter}` + }); + } + + // Label commands + if (comment.startsWith('/label ')) { + const labelName = comment.replace('/label ', '').trim(); + + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: [labelName] + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `🏷️ Added label: \`${labelName}\`` + }); + } + + // Assign command + if (comment.startsWith('/assign ')) { + const assignee = comment.replace('/assign ', '').trim().replace('@', ''); + + await github.rest.issues.addAssignees({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + assignees: [assignee] + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `👤 Assigned to @${assignee}` + }); + } \ No newline at end of file diff --git a/.github/workflows/label-sync.yml b/.github/workflows/label-sync.yml new file mode 100644 index 000000000..7cce5a3a2 --- /dev/null +++ b/.github/workflows/label-sync.yml @@ -0,0 +1,25 @@ +name: Sync Labels + +on: + push: + branches: [master] + paths: + - '.github/labels.yml' + workflow_dispatch: + +jobs: + sync-labels: + name: Sync Repository Labels + runs-on: ubuntu-latest + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Sync labels + uses: micnncim/action-label-syncer@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + manifest: .github/labels.yml + prune: true \ No newline at end of file diff --git a/.github/workflows/pr-automation.yml b/.github/workflows/pr-automation.yml new file mode 100644 index 000000000..9fa26ad57 --- /dev/null +++ b/.github/workflows/pr-automation.yml @@ -0,0 +1,326 @@ +name: PR Automation + +on: + pull_request: + types: [opened, synchronize, reopened, ready_for_review] + pull_request_review: + types: [submitted] + issue_comment: + types: [created] + +jobs: + # Auto-label PRs based on files changed + auto-label: + name: Auto Label PR + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Label PR based on files changed + uses: actions/github-script@v7 + with: + script: | + const { data: files } = await github.rest.pulls.listFiles({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + }); + + const labels = []; + const filePatterns = { + 'dependencies': ['package.json', 'pnpm-lock.yaml', 'yarn.lock'], + 'documentation': ['README.md', '*.md', 'docs/**'], + 'tests': ['**/*.test.*', '**/*.spec.*', 'cypress/**', '__tests__/**'], + 'ci/cd': ['.github/**', '*.yml', '*.yaml', 'rollup.config.*', 'vite.config.*'], + 'components': ['src/components/**'], + 'hooks': ['src/hooks/**'], + 'styles': ['**/*.css', '**/*.scss', '**/*.styled.*'], + 'types': ['**/*.d.ts', 'src/types/**', 'src/models/**'], + 'demo': ['src/demo/**', 'src/examples/**'], + 'build': ['rollup.config.*', 'vite.config.*', 'babel.config.*', 'tsconfig.*'], + 'security': ['snyk.yaml', '.snyk', 'audit-*'] + }; + + for (const [label, patterns] of Object.entries(filePatterns)) { + for (const file of files) { + for (const pattern of patterns) { + const regex = new RegExp(pattern.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*')); + if (regex.test(file.filename)) { + labels.push(label); + break; + } + } + if (labels.includes(label)) break; + } + } + + // Size-based labels + const totalChanges = files.reduce((sum, file) => sum + file.additions + file.deletions, 0); + if (totalChanges > 1000) labels.push('size/XL'); + else if (totalChanges > 500) labels.push('size/L'); + else if (totalChanges > 100) labels.push('size/M'); + else if (totalChanges > 10) labels.push('size/S'); + else labels.push('size/XS'); + + // Apply labels + if (labels.length > 0) { + await github.rest.issues.addLabels({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + labels: [...new Set(labels)] // Remove duplicates + }); + } + + # Assign reviewers based on files changed + assign-reviewers: + name: Assign Reviewers + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' && github.event.action == 'opened' + + steps: + - name: Assign reviewers + uses: actions/github-script@v7 + with: + script: | + const { data: files } = await github.rest.pulls.listFiles({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + }); + + // Define code owners (update with actual usernames) + const codeOwners = { + 'src/components/**': ['prabhuignoto'], + 'src/hooks/**': ['prabhuignoto'], + '.github/**': ['prabhuignoto'], + 'cypress/**': ['prabhuignoto'], + 'docs/**': ['prabhuignoto'] + }; + + const reviewers = new Set(); + for (const file of files) { + for (const [pattern, owners] of Object.entries(codeOwners)) { + const regex = new RegExp(pattern.replace(/\*\*/g, '.*').replace(/\*/g, '[^/]*')); + if (regex.test(file.filename)) { + owners.forEach(owner => reviewers.add(owner)); + } + } + } + + // Remove PR author from reviewers + reviewers.delete(context.payload.pull_request.user.login); + + if (reviewers.size > 0) { + await github.rest.pulls.requestReviewers({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number, + reviewers: Array.from(reviewers) + }); + } + + # Check PR requirements + pr-checks: + name: PR Requirements Check + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' + + steps: + - name: Checkout code + uses: actions/checkout@v4 + + - name: Check PR requirements + uses: actions/github-script@v7 + with: + script: | + const pr = context.payload.pull_request; + const checks = []; + + // Check if PR has description + if (!pr.body || pr.body.trim().length < 20) { + checks.push('❌ PR description is too short (minimum 20 characters)'); + } else { + checks.push('✅ PR has adequate description'); + } + + // Check if PR title follows conventional commits + const conventionalCommitPattern = /^(feat|fix|docs|style|refactor|test|chore|perf|ci|build|revert)(\(.+\))?: .{1,50}/; + if (!conventionalCommitPattern.test(pr.title)) { + checks.push('❌ PR title should follow conventional commits format'); + } else { + checks.push('✅ PR title follows conventional commits'); + } + + // Check if PR is not a draft + if (pr.draft) { + checks.push('⚠️ PR is in draft mode'); + } else { + checks.push('✅ PR is ready for review'); + } + + // Check if PR has linked issues + const issuePattern = /(close|closes|closed|fix|fixes|fixed|resolve|resolves|resolved)\s+#\d+/i; + if (pr.body && issuePattern.test(pr.body)) { + checks.push('✅ PR links to an issue'); + } else { + checks.push('⚠️ Consider linking to an issue if applicable'); + } + + const comment = `## 🔍 PR Requirements Check + + ${checks.join('\n')} + + ${checks.some(check => check.startsWith('❌')) ? + '\n**Please address the issues above before merging.**' : + '\n**All requirements met! 🎉**' + } + + --- + *This comment is automatically generated and updated.*`; + + // Find existing bot comment + const { data: comments } = await github.rest.issues.listComments({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + }); + + const botComment = comments.find(comment => + comment.user.type === 'Bot' && + comment.body.includes('PR Requirements Check') + ); + + if (botComment) { + // Update existing comment + await github.rest.issues.updateComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: botComment.id, + body: comment + }); + } else { + // Create new comment + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: comment + }); + } + + # Handle slash commands in PR comments + slash-commands: + name: Handle Slash Commands + runs-on: ubuntu-latest + if: github.event_name == 'issue_comment' && github.event.issue.pull_request + + steps: + - name: Handle commands + uses: actions/github-script@v7 + with: + script: | + const comment = context.payload.comment.body.trim(); + const commenter = context.payload.comment.user.login; + + // Only allow maintainers to run commands + const { data: collaborators } = await github.rest.repos.listCollaborators({ + owner: context.repo.owner, + repo: context.repo.repo, + }); + + const isMaintainer = collaborators.some(collab => + collab.login === commenter && + ['admin', 'write'].includes(collab.permissions.admin ? 'admin' : 'write') + ); + + if (!isMaintainer) { + console.log('User is not a maintainer, ignoring command'); + return; + } + + if (comment.startsWith('/rerun-ci')) { + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: '🔄 Re-running CI workflows...' + }); + + // Trigger CI workflow + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: context.repo.repo, + workflow_id: 'ci.yml', + ref: context.payload.issue.pull_request.head.ref + }); + } + + if (comment.startsWith('/assign-me')) { + await github.rest.issues.addAssignees({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + assignees: [commenter] + }); + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: `✅ Assigned to @${commenter}` + }); + } + + # Welcome new contributors + welcome: + name: Welcome New Contributors + runs-on: ubuntu-latest + if: github.event_name == 'pull_request' && github.event.action == 'opened' + + steps: + - name: Welcome first-time contributors + uses: actions/github-script@v7 + with: + script: | + const author = context.payload.pull_request.user.login; + + // Check if this is the author's first PR + const { data: prs } = await github.rest.pulls.list({ + owner: context.repo.owner, + repo: context.repo.repo, + state: 'all', + creator: author + }); + + if (prs.length === 1) { + const welcomeMessage = `## 🎉 Welcome to React Chrono! + + Thank you for your first contribution to React Chrono! We're excited to have you as part of our community. + + ### What happens next? + 1. Your PR will be automatically checked by our CI pipeline + 2. A maintainer will review your changes + 3. We might suggest some improvements or ask questions + 4. Once approved, your PR will be merged! 🚀 + + ### Resources + - [Contributing Guide](./CONTRIBUTING.md) + - [Code of Conduct](./CODE_OF_CONDUCT.md) + - [Development Setup](./README.md#-build-setup) + + Feel free to ask questions in the comments if you need any help! + + --- + *Welcome message from the React Chrono team* 🌟`; + + await github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: welcomeMessage + }); + } \ No newline at end of file diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..d6be8ba46 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,251 @@ +name: 🚀 Release & Publish + +on: + push: + branches: [master] + paths-ignore: + - '**.md' + - '.github/**' + - '!.github/workflows/release.yml' + workflow_dispatch: + inputs: + release_type: + description: 'Release type' + required: true + default: 'patch' + type: choice + options: + - patch + - minor + - major + - prerelease + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: false + +jobs: + # Pre-release validation + validate: + name: 🔍 Validate Release + runs-on: ubuntu-latest + outputs: + should_release: ${{ steps.check.outputs.should_release }} + current_version: ${{ steps.version.outputs.current_version }} + release_type: ${{ steps.release_type.outputs.release_type }} + steps: + - name: 📥 Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: 🔧 Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + + - name: 📦 Install dependencies + run: npm ci + + - name: 🔍 Check if release is needed + id: check + run: | + # Check for conventional commits since last release + LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + if [ -z "$LAST_TAG" ]; then + echo "should_release=true" >> $GITHUB_OUTPUT + echo "First release detected" + else + # Check for feat/fix commits since last tag + COMMITS=$(git log $LAST_TAG..HEAD --oneline --grep="^feat\|^fix\|^BREAKING CHANGE" || echo "") + if [ -n "$COMMITS" ]; then + echo "should_release=true" >> $GITHUB_OUTPUT + echo "Release-worthy commits found since $LAST_TAG" + else + echo "should_release=false" >> $GITHUB_OUTPUT + echo "No release-worthy commits found since $LAST_TAG" + fi + fi + + - name: 📋 Get current version + id: version + run: | + VERSION=$(node -p "require('./package.json').version") + echo "current_version=$VERSION" >> $GITHUB_OUTPUT + + - name: 🎯 Determine release type + id: release_type + run: | + if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then + echo "release_type=${{ github.event.inputs.release_type }}" >> $GITHUB_OUTPUT + else + # Auto-determine from commit messages + LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + if [ -z "$LAST_TAG" ]; then + echo "release_type=minor" >> $GITHUB_OUTPUT + else + # Check for breaking changes + BREAKING=$(git log $LAST_TAG..HEAD --oneline --grep="BREAKING CHANGE" || echo "") + if [ -n "$BREAKING" ]; then + echo "release_type=major" >> $GITHUB_OUTPUT + else + # Check for features + FEATURES=$(git log $LAST_TAG..HEAD --oneline --grep="^feat" || echo "") + if [ -n "$FEATURES" ]; then + echo "release_type=minor" >> $GITHUB_OUTPUT + else + echo "release_type=patch" >> $GITHUB_OUTPUT + fi + fi + fi + fi + + # Run full CI pipeline before release + ci: + name: 🧪 Full CI Pipeline + needs: validate + if: needs.validate.outputs.should_release == 'true' + uses: ./.github/workflows/ci.yml + secrets: inherit + + # Create release and publish + release: + name: 🚀 Release & Publish + needs: [validate, ci] + if: needs.validate.outputs.should_release == 'true' + runs-on: ubuntu-latest + permissions: + contents: write + packages: write + id-token: write + environment: production + steps: + - name: 📥 Checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + token: ${{ secrets.GITHUB_TOKEN }} + + - name: 🔧 Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: '20' + cache: 'npm' + registry-url: 'https://registry.npmjs.org' + + - name: 📦 Install dependencies + run: npm ci + + - name: 🏗️ Build package + run: npm run rollup + + - name: 🧪 Run tests + run: npm test + + - name: 📊 Bundle size check + run: npm run size-limit + + - name: 🔒 Security audit + run: npm audit --audit-level high + + - name: 🏷️ Generate new version + id: version + run: | + RELEASE_TYPE="${{ needs.validate.outputs.release_type }}" + OLD_VERSION="${{ needs.validate.outputs.current_version }}" + + # Update version in package.json + npm version $RELEASE_TYPE --no-git-tag-version + + NEW_VERSION=$(node -p "require('./package.json').version") + echo "new_version=$NEW_VERSION" >> $GITHUB_OUTPUT + echo "tag_name=v$NEW_VERSION" >> $GITHUB_OUTPUT + + echo "Version updated: $OLD_VERSION → $NEW_VERSION" + + - name: 📝 Generate release notes + id: release_notes + run: | + TAG_NAME="v${{ steps.version.outputs.new_version }}" + LAST_TAG=$(git describe --tags --abbrev=0 2>/dev/null || echo "") + + if [ -z "$LAST_TAG" ]; then + CHANGES=$(git log --oneline --pretty=format:"- %s" HEAD) + else + CHANGES=$(git log $LAST_TAG..HEAD --oneline --pretty=format:"- %s") + fi + + # Create release notes + cat > release_notes.md << EOF + ## 🚀 What's New in $TAG_NAME + + ### 📋 Changes + $CHANGES + + ### 📊 Package Information + - **Version**: ${{ steps.version.outputs.new_version }} + - **Release Type**: ${{ needs.validate.outputs.release_type }} + - **Build**: $(date -u +"%Y-%m-%d %H:%M:%S UTC") + + ### 📦 Installation + \`\`\`bash + npm install react-chrono@${{ steps.version.outputs.new_version }} + \`\`\` + + ### 🔗 Links + - [NPM Package](https://www.npmjs.com/package/react-chrono) + - [Documentation](https://github.com/prabhuignoto/react-chrono#readme) + - [Demo](https://react-chrono.vercel.app/) + EOF + + echo "Release notes generated for $TAG_NAME" + + - name: 🏷️ Create Git tag + run: | + git config user.name "github-actions[bot]" + git config user.email "github-actions[bot]@users.noreply.github.com" + git add package.json + git commit -m "chore: bump version to ${{ steps.version.outputs.new_version }}" + git tag ${{ steps.version.outputs.tag_name }} + git push origin master + git push origin ${{ steps.version.outputs.tag_name }} + + - name: 📦 Publish to NPM + run: npm publish --provenance --access public + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: 🎉 Create GitHub Release + uses: actions/create-release@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ steps.version.outputs.tag_name }} + release_name: ${{ steps.version.outputs.tag_name }} + body_path: release_notes.md + draft: false + prerelease: ${{ contains(steps.version.outputs.new_version, '-') }} + + - name: 📢 Post-release notifications + run: | + echo "🎉 Successfully released react-chrono@${{ steps.version.outputs.new_version }}" + echo "📦 NPM: https://www.npmjs.com/package/react-chrono" + echo "🏷️ GitHub: https://github.com/prabhuignoto/react-chrono/releases/tag/${{ steps.version.outputs.tag_name }}" + + # Cleanup on failure + cleanup: + name: 🧹 Cleanup on Failure + needs: [validate, ci, release] + if: failure() + runs-on: ubuntu-latest + steps: + - name: 📥 Checkout code + uses: actions/checkout@v4 + + - name: 🧹 Clean up failed release + run: | + echo "Release failed, cleaning up..." + # Add any cleanup logic here if needed + echo "Cleanup completed" \ No newline at end of file diff --git a/.github/workflows/snyk.yaml b/.github/workflows/snyk.yaml index 2da241758..f8f4a18af 100644 --- a/.github/workflows/snyk.yaml +++ b/.github/workflows/snyk.yaml @@ -1,47 +1,28 @@ -name: Snyk Security Scan +# Legacy Snyk Workflow - DEPRECATED +# This workflow has been integrated into the modern CI pipeline and dependency management +# Security scanning is now handled by ci.yml and dependency-management.yml + +name: Snyk Security Scan (Legacy) on: - push: - branches: - - master - pull_request: - branches: - - master + workflow_dispatch: # Manual trigger only jobs: - snyk-security-scan: + legacy-notice: runs-on: ubuntu-latest - name: Snyk Security Scan steps: - - uses: actions/checkout@v4 - - - name: Setup PNPM - uses: pnpm/action-setup@v4 - with: - version: latest - - - name: Cache PNPM dependencies - uses: actions/cache@v4 - with: - path: ~/.pnpm-store - key: ${{ runner.os }}-pnpm-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-pnpm- - - - name: Install dependencies - run: pnpm install - - - name: Cache Snyk cache folder - uses: actions/cache@v4 - with: - path: ~/.cache/snyk - key: ${{ runner.os }}-snyk-${{ hashFiles('pnpm-lock.yaml') }} - restore-keys: | - ${{ runner.os }}-snyk- - - - name: Run Snyk to check for vulnerabilities - uses: snyk/actions/node@master - env: - SNYK_TOKEN: ${{ secrets.SNYK_SECRET }} - with: - args: --severity-threshold=high + - name: Migration Notice + run: | + echo "⚠️ This workflow has been integrated into the modern CI pipeline" + echo "🔄 Security scanning is now handled by:" + echo " - CI Pipeline (ci.yml) - for PR and push security checks" + echo " - Dependency Management (dependency-management.yml) - for comprehensive security audits" + echo "" + echo "📚 See GITHUB_ACTIONS_DOCUMENTATION.md for details" + echo "" + echo "Enhanced security features:" + echo "- Integrated with CI pipeline for faster feedback" + echo "- Weekly automated security audits" + echo "- Vulnerability reporting with PR comments" + echo "- License compliance checking" + echo "- Automated dependency updates with security fixes" diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml deleted file mode 100644 index 7eef78c60..000000000 --- a/.github/workflows/sonar.yml +++ /dev/null @@ -1,21 +0,0 @@ -name: Sonar scan (disabled) -# Workflow disabled. Uncomment the 'on:' section below to re-enable. -# on: -# push: -# branches: -# - master -# pull_request: -# types: [opened, synchronize, reopened] -jobs: - sonarcloud: - name: SonarCloud - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - with: - fetch-depth: 0 # Shallow clones should be disabled for a better relevancy of analysis - - name: SonarCloud Scan - uses: SonarSource/sonarcloud-github-action@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} # Needed to get PR information, if any - SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }} diff --git a/.prettierignore b/.prettierignore index b53ccea05..e21431f09 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1,4 +1,68 @@ -env -icons -src/demo -src/examples \ No newline at end of file +# Dependencies +node_modules/ +pnpm-lock.yaml +package-lock.json +yarn.lock + +# Build outputs +dist/ +build/ +coverage/ +.next/ +out/ + +# Environment files +.env +.env.local +.env.development.local +.env.test.local +.env.production.local + +# IDE and editor files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# OS generated files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* + +# Runtime data +pids +*.pid +*.seed +*.pid.lock + +# Demo and examples (already ignored) +src/demo/ +src/examples/ + +# Icons and assets +icons/ +src/assets/ + +# Generated files +*.min.js +*.min.css +*.bundle.js + +# Test coverage +coverage/ +.nyc_output/ + +# Temporary files +*.tmp +*.temp \ No newline at end of file diff --git a/.prettierrc b/.prettierrc index dcb72794f..ce2e84741 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,44 @@ { + "semi": true, "singleQuote": true, - "trailingComma": "all" + "trailingComma": "all", + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "avoid", + "endOfLine": "lf", + "quoteProps": "as-needed", + "jsxSingleQuote": true, + "proseWrap": "preserve", + "htmlWhitespaceSensitivity": "css", + "embeddedLanguageFormatting": "auto", + "singleAttributePerLine": false, + "overrides": [ + { + "files": "*.{ts,tsx}", + "options": { + "parser": "typescript" + } + }, + { + "files": "*.{js,jsx}", + "options": { + "parser": "babel" + } + }, + { + "files": "*.json", + "options": { + "parser": "json" + } + }, + { + "files": "*.md", + "options": { + "parser": "markdown" + } + } + ] } \ No newline at end of file diff --git a/.stylelintignore b/.stylelintignore new file mode 100644 index 000000000..d48f8312d --- /dev/null +++ b/.stylelintignore @@ -0,0 +1,29 @@ +# Dependencies +node_modules/ + +# Build outputs +dist/ +build/ +coverage/ + +# Demo and examples +src/demo/ +src/examples/ + +# Generated files +*.min.css +*.bundle.css + +# Test coverage +coverage/ + +# Temporary files +*.tmp +*.temp + +# Environment files +.env* + +# IDE and editor files +.vscode/ +.idea/ \ No newline at end of file diff --git a/.stylelintrc b/.stylelintrc index 4aa58c5e1..4a71d87a3 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,5 +1,60 @@ { + "extends": [ + "stylelint-config-recommended" + ], "customSyntax": "postcss-styled-syntax", - "rules": {}, - "ignoreFiles": ["node_modules/**/*", "dist/**/*"] + "rules": { + "at-rule-no-unknown": [ + true, + { + "ignoreAtRules": [ + "tailwind", + "apply", + "variants", + "responsive", + "screen", + "layer" + ] + } + ], + "property-no-unknown": [ + true, + { + "ignoreProperties": ["composes"] + } + ], + "selector-pseudo-class-no-unknown": [ + true, + { + "ignorePseudoClasses": ["global"] + } + ], + "selector-pseudo-element-no-unknown": [ + true, + { + "ignorePseudoElements": ["global"] + } + ], + "no-empty-source": null, + "no-descending-specificity": null, + "no-duplicate-selectors": null, + "declaration-block-no-duplicate-properties": [ + true, + { + "ignore": ["consecutive-duplicates"] + } + ], + "declaration-block-no-shorthand-property-overrides": null, + "property-no-vendor-prefix": null, + "value-no-vendor-prefix": null, + "declaration-property-value-no-unknown": null + }, + "ignoreFiles": [ + "node_modules/**/*", + "dist/**/*", + "coverage/**/*", + "build/**/*", + "src/demo/**/*", + "src/examples/**/*" + ] } diff --git a/LICENSE b/LICENSE index 4fa554b1c..15bc72f8d 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2019 Fred K. Schott +Copyright (c) 2019 Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index fe7017793..90147eb5e 100644 --- a/README.md +++ b/README.md @@ -1,708 +1,41 @@ -
- React Chrono UI Logo -

React Chrono

-

A flexible and modern timeline component for React.

-
+![act-logo](https://raw.githubusercontent.com/wiki/nektos/act/img/logo-150.png) -
+# Overview [![push](https://github.com/nektos/act/workflows/push/badge.svg?branch=master&event=push)](https://github.com/nektos/act/actions) [![Go Report Card](https://goreportcard.com/badge/github.com/nektos/act)](https://goreportcard.com/report/github.com/nektos/act) [![awesome-runners](https://img.shields.io/badge/listed%20on-awesome--runners-blue.svg)](https://github.com/jonico/awesome-runners) -[![npm version](https://img.shields.io/npm/v/react-chrono.svg?style=flat)](https://www.npmjs.com/package/react-chrono) -![npm downloads](https://img.shields.io/npm/dm/react-chrono.svg?label=npm%20downloads&style=flat) -![npm bundle size](https://img.shields.io/bundlephobia/minzip/react-chrono) -[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/MIT) -[![styled with Prettier](https://img.shields.io/badge/styled_with-prettier-ff69b4.svg)](https://prettier.io/) +> "Think globally, `act` locally" - +Run your [GitHub Actions](https://developer.github.com/actions/) locally! Why would you want to do this? Two reasons: -[![Build Status](https://dev.azure.com/prabhummurthy/react-chrono/_apis/build/status/prabhuignoto.react-chrono?branchName=master)](https://dev.azure.com/prabhummurthy/react-chrono/_build/latest?definitionId=7&branchName=master) -[![DeepScan grade](https://deepscan.io/api/teams/10074/projects/13644/branches/234929/badge/grade.svg)](https://deepscan.io/dashboard#view=project&tid=10074&pid=13644&bid=234929) -[![Codacy Badge](https://app.codacy.com/project/badge/Grade/f2e24a98defd4e4fa7f6f24d86b8dab5)](https://www.codacy.com/manual/prabhuignoto/react-chrono?utm_source=github.com&utm_medium=referral&utm_content=prabhuignoto/react-chrono&utm_campaign=Badge_Grade) -[![react-chrono](https://img.shields.io/endpoint?url=https://dashboard.cypress.io/badge/simple/8zb5a5&style=flat&logo=cypress)](https://dashboard.cypress.io/projects/8zb5a5/runs) -[![Known Vulnerabilities](https://snyk.io/test/github/prabhuignoto/react-chrono/badge.svg)](https://snyk.io/test/github/prabhuignoto/react-chrono) -[![Depfu](https://badges.depfu.com/badges/48a23a6a830309649b7e516467cd9a48/overview.svg)](https://depfu.com/github/prabhuignoto/react-chrono?project_id=15325) -[![Coverage Status](https://coveralls.io/repos/github/prabhuignoto/react-chrono/badge.svg?branch=master)](https://coveralls.io/github/prabhuignoto/react-chrono?branch=master) -Storybook +- **Fast Feedback** - Rather than having to commit/push every time you want to test out the changes you are making to your `.github/workflows/` files (or for any changes to embedded GitHub actions), you can use `act` to run the actions locally. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://help.github.com/en/actions/reference/virtual-environments-for-github-hosted-runners#filesystems-on-github-hosted-runners) are all configured to match what GitHub provides. +- **Local Task Runner** - I love [make](). However, I also hate repeating myself. With `act`, you can use the GitHub Actions defined in your `.github/workflows/` to replace your `Makefile`! -
+> [!TIP] +> **Now Manage and Run Act Directly From VS Code!**
+> Check out the [GitHub Local Actions](https://sanjulaganepola.github.io/github-local-actions-docs/) Visual Studio Code extension which allows you to leverage the power of `act` to run and test workflows locally without leaving your editor. - +# How Does It Work? -React Chrono is a modern timeline component for React that offers a variety of features and customization options. It allows you to render timelines in horizontal, vertical, vertical-alternating, and horizontal-all modes, display images and videos, and much more. +When you run `act` it reads in your GitHub Actions from `.github/workflows/` and determines the set of actions that need to be run. It uses the Docker API to either pull or build the necessary images, as defined in your workflow files and finally determines the execution path based on the dependencies that were defined. Once it has the execution path, it then uses the Docker API to run containers for each action based on the images prepared earlier. The [environment variables](https://help.github.com/en/actions/configuring-and-managing-workflows/using-environment-variables#default-environment-variables) and [filesystem](https://docs.github.com/en/actions/using-github-hosted-runners/about-github-hosted-runners#file-systems) are all configured to match what GitHub provides. -## Table of Contents +Let's see it in action with a [sample repo](https://github.com/cplee/github-actions-demo)! -- [✨ Features](#-features) -- [💾 Installation](#-installation) -- [🚀 Getting Started](#-getting-started) - - [Basic Horizontal Mode](#basic-horizontal-mode) - - [Vertical Mode](#vertical-mode) - - [Vertical Alternating Mode](#vertical-alternating-mode) -- [⚙️ Props](#️-props) - - [Core Props](#core-props) - - [Timeline Item Model](#timeline-item-model) - - [Navigation & Interaction](#navigation--interaction) - - [Layout & Sizing](#layout--sizing) - - [Media Handling](#media-handling) - - [Content & Display](#content--display) - - [Theming & Styling](#theming--styling) - - [Slideshow](#slideshow) - - [Search](#search) - - [Miscellaneous](#miscellaneous) -- [🎨 Customization](#-customization) - - [Rendering Custom Content](#rendering-custom-content-1) - - [Custom Icons](#custom-icons) - - [Nested Timelines](#nested-timelines-1) - - [Custom Class Names](#custom-class-names) - - [Custom Font Sizes](#custom-font-sizes) - - [Custom Button Alt Text](#custom-button-alt-text) -- [📦 Examples & Demos](#-examples--demos) - - [CodeSandbox Examples](#codesandbox-examples) - - [Kitchen Sink Demo](#kitchen-sink-demo) - - [Storybook](#storybook) -- [🛠️ Build Setup](#️-build-setup) -- [🧪 Tests](#-tests) -- [🤝 Contributing](#-contributing) -- [🧱 Built With](#-built-with) -- [💖 Support & Meta](#-support--meta) -- [✨ Contributors](#-contributors) +![Demo](https://raw.githubusercontent.com/wiki/nektos/act/quickstart/act-quickstart-2.gif) -## ✨ Features +# Act User Guide -- 🚥 **Multiple Modes**: Render timelines in Horizontal, Vertical, or Vertical-Alternating layouts. -- 📺 **Slideshow**: Auto-play the timeline with slideshow functionality. -- 🖼️ **Media Support**: Easily display images and videos within timeline cards. -- ⌨️ **Keyboard Accessible**: Navigate the timeline using keyboard controls. -- 🔧 **Custom Content**: Render custom React components within timeline cards. -- 🌿 **Nested Timelines**: Display timelines within timeline cards for complex narratives. -- ⚡ **Data-Driven API**: Configure the timeline dynamically using a simple data structure. -- 🎨 **Enhanced Theming**: Comprehensive theme customization with **15+ new dark mode properties** for complete visual control. -- 🌙 **Advanced Dark Mode**: Fully configurable dark mode with brand color integration and accessibility compliance. -- 🎭 **Custom Icons**: Use your own icons for timeline points. -- 💪 **TypeScript**: Built with TypeScript for robust development. -- 💅 **Styled with Styled Component**: Leverages Styled Component for flexible styling. +Please look at the [act user guide](https://nektosact.com) for more documentation. -## 💾 Installation +# Support -```bash -# Using yarn -yarn add react-chrono +Need help? Ask in [discussions](https://github.com/nektos/act/discussions)! -# Using npm -npm install react-chrono -``` +# Contributing -## 🚀 Getting Started +Want to contribute to act? Awesome! Check out the [contributing guidelines](CONTRIBUTING.md) to get involved. -Ensure you wrap the `Chrono` component in a container with a specified `width` and `height`. +## Manually building from source -### Basic Horizontal Mode - -By default, if no `mode` is specified, the component renders in `HORIZONTAL` mode. - -```jsx -import React from 'react'; -import { Chrono } from 'react-chrono'; - -const App = () => { - const items = [ - { - title: 'May 1940', - cardTitle: 'Dunkirk', - url: 'http://www.history.com', - cardSubtitle: - 'Men of the British Expeditionary Force (BEF) wade out to a destroyer...', - cardDetailedText: - 'Men of the British Expeditionary Force (BEF) wade out to a destroyer during the evacuation from Dunkirk.', - media: { - type: 'IMAGE', - source: { - url: 'http://someurl/image.jpg', - }, - }, - }, - // ... more items - ]; - - return ( -
- -
- ); -}; - -export default App; -``` - -![Horizontal Timeline Example](./readme-assets/horizontal_all.jpg) - -### Vertical Mode - -To render the timeline vertically, set the `mode` prop to `VERTICAL`. - -```jsx -
- -
-``` - -![Vertical Timeline Example](./readme-assets/vertical_basic.jpg) - -### Vertical Alternating Mode - -For a layout where cards alternate sides, use `VERTICAL_ALTERNATING`. - -```jsx -
- -
-``` - -![Vertical Alternating Timeline Example](./readme-assets/vertical_alternating.jpg) - -## ⚙️ Props - -React Chrono offers a wide range of props for customization. - -### Core Props - -| Name | Type | Default | Description | -| :------ | :----------------------------------------------------------------------- | :------------- | :------------------------------------------------------------------------------------------------------------------------------------------------ | -| `items` | `TimelineItemModel[]` | `[]` | An array of [Timeline Item objects](#timeline-item-model) to display. | -| `mode` | `'HORIZONTAL'`, `'VERTICAL'`, `'VERTICAL_ALTERNATING'`, `'HORIZONTAL_ALL'` | `'HORIZONTAL'` | Sets the layout mode of the timeline. `HORIZONTAL_ALL` shows all cards simultaneously in horizontal mode. | -| `theme` | `Theme` | `{...}` | **Enhanced theming** with 15+ new dark mode properties for complete visual customization. See [Theming & Styling](#theming--styling) for details. | - -### Timeline Item Model - -Each object in the `items` array can have the following properties: - -| Property | Type | Description | -| :----------------- | :--------------------- | :----------------------------------------------------------------------------------------------------------------------------------------- | -| `title` | `string` or `ReactNode` | Title of the timeline item (often a date or short label). | -| `cardTitle` | `string` or `ReactNode` | Title displayed on the timeline card. | -| `cardSubtitle` | `string` or `ReactNode` | Subtitle text displayed on the timeline card. | -| `cardDetailedText` | `string`, `string[]`, `ReactNode`, or `ReactNode[]` | Detailed text for the card. An array of strings will render each string as a separate paragraph. | -| `media` | `Media` | Object to configure image or video display. See [Media Handling](#media-handling). | -| `url` | `string` | URL associated with the timeline item's title. Clicking the title will navigate to this URL. | -| `date` | `Date`, `string`, or `number` | Date to be used in the title. If provided, this will override the `title` property for display purposes. | -| `timelineContent` | `ReactNode` | Custom React content to render inside the card. Overrides `cardDetailedText`. See [Rendering Custom Content](#rendering-custom-content-1). | -| `items` | `TimelineItemModel[]` | Array of timeline items for creating [Nested Timelines](#nested-timelines-1). | -| `hasNestedItems` | `boolean` | **New:** Automatically set to indicate if this item contains nested sub-items. Used internally for optimized rendering. | -| `active` | `boolean` | If true, this item will be initially active (only for the first matching item). | -| `id` | `string` | A unique identifier for the timeline item. | -| `visible` | `boolean` | Controls the visibility of the timeline item. | - -**Example `TimelineItemModel`:** - -```js -{ - title: "May 1940", - cardTitle: "Dunkirk", - cardSubtitle: "Evacuation of Allied soldiers from the beaches and harbour of Dunkirk, France.", - cardDetailedText: ["Paragraph one about Dunkirk.", "Paragraph two providing more details."], - media: { - type: "IMAGE", // "VIDEO" - source: { - url: "http://someurl/dunkirk.jpg" - }, - name: "Dunkirk Evacuation" - }, - url: "https://en.wikipedia.org/wiki/Dunkirk_evacuation", - // For nested timeline: - // items: [{ cardTitle: 'Sub-event 1' }, { cardTitle: 'Sub-event 2' }] -} -``` - -### Navigation & Interaction - -| Name | Type | Default | Description | -| :------------------------- | :--------- | :------ | :-------------------------------------------------------------------------------------------------------------------------- | -| `activeItemIndex` | `number` | `0` | Index of the timeline item to be active on load. | -| `disableNavOnKey` | `boolean` | `false` | Disables keyboard navigation (LEFT/RIGHT for Horizontal, UP/DOWN for Vertical). | -| `disableClickOnCircle` | `boolean` | `false` | Disables click action on timeline points/circles. | -| `disableAutoScrollOnClick` | `boolean` | `false` | Prevents auto-scrolling to the active card when a timeline card or point is clicked. | -| `onItemSelected` | `function` | | Callback function invoked when a timeline item is selected. Passes item data and index. | -| `onScrollEnd` | `function` | | Callback function invoked when the end of the timeline is reached during scrolling. | -| `focusActiveItemOnLoad` | `boolean` | `false` | Automatically scrolls to and focuses on the `activeItemIndex` when the timeline loads. | -| `disableInteraction` | `boolean` | `false` | Disables all user interactions with the timeline (clicks, keyboard navigation). | -| `enableQuickJump` | `boolean` | `true` | Allows quick jumping to a timeline item via controls (if toolbar is enabled). | -| `enableLayoutSwitch` | `boolean` | `true` | Enables layout switching controls in the toolbar, allowing users to switch between different timeline modes. | -| `useReadMore` | `boolean` | `true` | Enables a "read more" button if card content exceeds available space. Set to `false` to always show all text. | - -**Semantic Tags Configuration:** -| Name | Type | Default | Description | -| :------------- | :-------------------- | :------ | :-------------------------------------------------------------------------------------------------------------------------- | -| `semanticTags` | `SemanticTagsConfig` | | Configure semantic HTML tags for card elements to improve accessibility and SEO. | - -The `semanticTags` object allows you to specify HTML tags for card elements: - -```typescript -interface SemanticTagsConfig { - cardTitle?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'div'; - cardSubtitle?: 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6' | 'span' | 'div'; -} -``` - -**Example:** - -```jsx - -``` - -**Keyboard Navigation:** - -- **Horizontal Mode**: Use LEFT and RIGHT arrow keys. -- **Vertical/Vertical Alternating Mode**: Use UP and DOWN arrow keys. -- HOME: Jump to the first item. -- END: Jump to the last item. - -### Layout & Sizing - -| Name | Type | Default | Description | -| :----------------------- | :------------------------------------ | :--------------------- | :--------------------------------------------------------------------------------------------------------------------- | -| `cardHeight` | `number` | `200` | Minimum height (in pixels) of timeline cards. | -| `cardWidth` | `number` | `450` | Maximum width (in pixels) of timeline cards. | -| `itemWidth` | `number` | `200` | Width (in pixels) of each timeline section in `HORIZONTAL` mode. | -| `contentDetailsHeight` | `number` | `150` | Height (in pixels) of the detailed content area within a card if `cardDetailedText` is used. | -| `lineWidth` | `number` | `3` | Width (in pixels) of the main timeline track line. | -| `timelinePointDimension` | `number` | `16` | Diameter (in pixels) of the circular points on the timeline. | -| `nestedCardHeight` | `number` | `150` | Height (in pixels) of cards within a [nested timeline](#nested-timelines-1). | -| `mediaHeight` | `number` | `200` | Minimum height (in pixels) of media elements (images and videos) in timeline cards. | -| `scrollable` | `boolean` or `{ scrollbar: boolean }` | `{ scrollbar: false }` | Makes `VERTICAL` and `VERTICAL_ALTERNATING` modes scrollable. Set to `{ scrollbar: true }` to show the scrollbar. | -| `enableBreakPoint` | `boolean` | `true` | If true, `VERTICAL_ALTERNATING` mode automatically switches to `VERTICAL` mode when `responsiveBreakPoint` is reached. | -| `responsiveBreakPoint` | `number` | `768` | Viewport width (in pixels) at which `VERTICAL_ALTERNATING` mode switches to `VERTICAL` if `enableBreakPoint` is true. | -| `cardPositionHorizontal` | `'TOP'` or `'BOTTOM'` | | Positions the card above or below the timeline in `HORIZONTAL` mode. | -| `flipLayout` | `boolean` | `false` | Reverses the layout direction (e.g., Right-to-Left for horizontal, or swaps sides for vertical alternating). | -| `showAllCardsHorizontal` | `boolean` | `false` | In `HORIZONTAL` mode, displays all cards simultaneously instead of only the active one. | - -### Media Handling - -The `media` object within a [Timeline Item](#timeline-item-model) configures images or videos. - -| `media` Property | Type | Description | -| :--------------- | :------------------------------- | :----------------------------------------------------------------------------- | -| `type` | `'IMAGE'` or `'VIDEO'` | Specifies the type of media. | -| `source` | `{ url: string, type?: string }` | `url`: URL of the image or video. `type` (for video): e.g., `'mp4'`, `'webm'`. | -| `name` | `string` | Alt text for images or a descriptive name for videos. | -| `active` | `boolean` | (Video only) If true, video will attempt to play when its card becomes active. | -| `id` | `string` | A unique ID for the media element. | - -**Image Example:** - -```js -media: { - type: "IMAGE", - name: "dunkirk beach", - source: { - url: "http://someurl/image.jpg" - } -} -``` - -**Video Example (auto-plays when active, muted):** - -```js -media: { - type: "VIDEO", - name: "Pearl Harbor", - source: { - url: "/pearl-harbor.mp4", // or "https://www.youtube.com/embed/f6cz9gtMTeI" - type: "mp4" // Optional for local files if extension is clear, useful for YouTube embeds - } -} -``` - -![Timeline with Media](./readme-assets/media.png) - -**Media Settings Prop (`mediaSettings`):** -This top-level prop on `` controls global media display: - -| Name | Type | Default | Description | -| :------ | :--------------------------------------------------------- | :-------- | :------------------------------------ | -| `align` | `'left'`, `'right'`, `'center'` | `'left'` | Alignment of media within the card. | -| `fit` | `'cover'`, `'contain'`, `'fill'`, `'none'`, `'scale-down'` | `'cover'` | CSS `object-fit` property for images. | - -```jsx - -``` - -### Content & Display - -| Name | Type | Default | Description | -| :--------------------- | :---------------------------------- | :--------------- | :----------------------------------------------------------------------------------------------------------------------- | -| `borderLessCards` | `boolean` | `false` | Removes borders and shadows from timeline cards for a flatter look. | -| `cardLess` | `boolean` | `false` | Hides timeline cards, showing only titles/points. Useful for a very compact timeline. | -| `disableTimelinePoint` | `boolean` | `false` | Hides the circular points on the timeline track. | -| `timelinePointShape` | `'circle'`, `'square'`, `'diamond'` | `'circle'` | Configures the shape of the points on the timeline. | -| `textOverlay` | `boolean` | `false` | Displays text content as an overlay on top of media elements. Requires `text` property in timeline items. | -| `parseDetailsAsHTML` | `boolean` | `false` | If true, `cardDetailedText` will be parsed as HTML. Use with caution due to XSS risks if content is user-supplied. | -| `titleDateFormat` | `string` | `'MMM DD, YYYY'` | Date format for item titles when using the `date` property in items. Supports all [day.js](https://day.js.org/) formats. | -| `textDensity` | `'LOW'` or `'HIGH'` | `'HIGH'` | Configures the amount of text displayed in cards. `'LOW'` might truncate more aggressively. | - -**Text Overlay Mode:** -Enable `textOverlay` and provide a `text` property in your `items`. - -```jsx -const items = [ - { - title: 'First item', - media: { type: 'IMAGE', source: { url: 'https://example.com/image.jpg' } }, - text: 'This is the caption for the first item, appearing over the image.', - }, -]; -; -``` - -![Text Overlay Example](./readme-assets/text_overlay.jpg) - -### Theming & Styling - -| Name | Type | Description | -| :---------------------------- | :------- | :----------------------------------------------- | -| `cardBgColor` | `string` | Background color for timeline cards | -| `cardDetailsBackGround` | `string` | Background color for card details section | -| `cardDetailsColor` | `string` | Text color for card details | -| `cardMediaBgColor` | `string` | Background color for media section in cards | -| `cardSubtitleColor` | `string` | Color for card subtitles | -| `cardTitleColor` | `string` | Color for card titles | -| `detailsColor` | `string` | Color for detailed text | -| `iconBackgroundColor` | `string` | Background color for timeline icons | -| `nestedCardBgColor` | `string` | Background color for nested timeline cards | -| `nestedCardDetailsBackGround` | `string` | Background color for nested card details section | -| `nestedCardDetailsColor` | `string` | Text color for nested card details | -| `nestedCardSubtitleColor` | `string` | Color for nested card subtitles | -| `nestedCardTitleColor` | `string` | Color for nested card titles | -| `primary` | `string` | Primary color for the timeline | -| `secondary` | `string` | Secondary color for the timeline | -| `textColor` | `string` | Default text color | -| `titleColor` | `string` | Color for timeline titles | -| `titleColorActive` | `string` | Color for active timeline titles | -| `toolbarBgColor` | `string` | Background color for the toolbar | -| `toolbarBtnBgColor` | `string` | Background color for toolbar buttons | -| `toolbarTextColor` | `string` | Text color for toolbar elements | -| `timelineBgColor` | `string` | Background color for the timeline | - -#### Dark Mode Properties - -| Name | Type | Description | -| :---------------------------- | :------- | :----------------------------------------------- | -| `iconColor` | `string` | Color for icons in dark mode | -| `buttonHoverBgColor` | `string` | Background color for buttons on hover | -| `buttonActiveBgColor` | `string` | Background color for active buttons | -| `buttonActiveIconColor` | `string` | Icon color for active buttons | -| `buttonBorderColor` | `string` | Border color for buttons | -| `buttonHoverBorderColor` | `string` | Border color for buttons on hover | -| `buttonActiveBorderColor` | `string` | Border color for active buttons | -| `shadowColor` | `string` | Color for shadows and depth effects | -| `glowColor` | `string` | Color for glow effects and focus states | -| `searchHighlightColor` | `string` | Color for search result highlighting | -| `darkToggleActiveBgColor` | `string` | Background color when dark mode toggle is active | -| `darkToggleActiveIconColor` | `string` | Icon color when dark mode toggle is active | -| `darkToggleActiveBorderColor` | `string` | Border color when dark mode toggle is active | -| `darkToggleGlowColor` | `string` | Glow effect color for dark mode toggle | - -#### **🎨 Custom Theme Examples** - -**Brand Color Integration:** - -```jsx -const customDarkTheme = { - // Base colors - cardBgColor: '#2d3748', - toolbarBgColor: '#1a202c', - toolbarBtnBgColor: '#4a5568', - - // Enhanced dark mode properties - iconColor: '#63b3ed', // Bright blue for icons - buttonHoverBgColor: '#718096', // Gray hover - buttonActiveBgColor: '#ed8936', // Orange active state - buttonActiveIconColor: '#1a202c', // Dark icon on orange - - // Borders and effects - buttonBorderColor: 'rgba(255, 255, 255, 0.2)', - buttonHoverBorderColor: '#63b3ed', - shadowColor: 'rgba(0, 0, 0, 0.6)', - glowColor: 'rgba(237, 137, 54, 0.4)', - - // Search and dark toggle - searchHighlightColor: 'rgba(99, 179, 237, 0.3)', - darkToggleActiveBgColor: '#2b6cb0', - darkToggleActiveIconColor: '#f7fafc', -}; - -; -``` - -**High Contrast Theme:** - -```jsx -const highContrastTheme = { - cardBgColor: '#000000', - toolbarBgColor: '#111111', - iconColor: '#00ff00', // Bright green for accessibility - buttonActiveBgColor: '#ffff00', // Bright yellow - buttonBorderColor: 'rgba(255, 255, 255, 0.5)', - shadowColor: 'rgba(0, 0, 0, 0.8)', - searchHighlightColor: 'rgba(0, 255, 0, 0.5)', -}; -``` - -> **🔧 Complete Theme Reference:** For a complete list of all themeable properties, refer to the `Theme` type definition in the source code or explore the [Storybook examples](https://5f985eb478dcb00022cfd60e-axcjutcmmg.chromatic.com/). - -> **♿ Accessibility:** All default colors maintain WCAG AA compliance (4.5:1 contrast ratio). When customizing themes, ensure sufficient contrast ratios for accessibility. - -**Dark Mode Toggle:** -| Name | Type | Default | Description | -| :----------------- | :--------- | :------ | :--------------------------------------------------------------------------------------------------------- | -| `enableDarkToggle` | `boolean` | `false` | Adds a toggle switch to the toolbar for enabling dark mode (if dark theme is configured). | -| `onThemeChange` | `function` | | Callback invoked when the theme changes, e.g., via the dark mode toggle. Passes the new theme object. | - -### Slideshow - -| Name | Type | Default | Description | -| :----------------------------- | :--------------------------------------------- | :----------------------------------- | :------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `slideShow` | `boolean` | `false` | Enables slideshow mode and shows play/pause controls in the toolbar. | -| `slideItemDuration` | `number` | `2000` | Duration (in milliseconds) each timeline item remains active during a slideshow. | -| `slideShowType` | `'reveal'`, `'slide_from_sides'`, `'slide_in'` | Varies by `mode` | Type of animation for slideshow transitions. Defaults: `VERTICAL` -> `'reveal'`, `VERTICAL_ALTERNATING` -> `'slide_from_sides'`, `HORIZONTAL` -> `'slide_in'`. | -| `showProgressOnSlideshow` | `boolean` | `false` | Shows a progress bar on individual timeline cards during slideshow mode to indicate the current slide's progress. | -| `showOverallSlideshowProgress` | `boolean` | `true` (when `slideShow` is enabled) | Shows a line-based progress bar at the top of the screen during slideshow mode, indicating overall progress across all timeline items. | - -```jsx - -``` - -> Slideshow can be stopped by clicking the stop button or pressing ESC. The overall progress bar shows the global progress across all timeline items and can be disabled by setting `showOverallSlideshowProgress={false}`. - -### Search - -| Name | Type | Default | Description | -| :------------------ | :------- | :------------------ | :---------------------------------------------------- | -| `searchPlaceholder` | `string` | `"Search..."` | Placeholder text for the search input in the toolbar. | -| `searchAriaLabel` | `string` | `"Search timeline"` | ARIA label for the search input for accessibility. | -| `clearSearch` | `string` | `"Clear search"` | Text/ARIA label for the clear search button. | - -```jsx - -``` - -> Search functionality is part of the toolbar. To hide search (and the toolbar), set `disableToolbar={true}`. - -### Miscellaneous - -| Name | Type | Default | Description | -| :---------------------- | :-------------------- | :------ | :-------------------------------------------------------------------------------------------------------------- | -| `allowDynamicUpdate` | `boolean` | `false` | Enables dynamic updates of timeline items. If true, changes to the `items` prop will re-render the timeline. | -| `noUniqueId` | `boolean` | `false` | Prevents generating a unique ID for the timeline wrapper. Use with `uniqueId` if you need to set a specific ID. | -| `uniqueId` | `string` | | Sets a custom unique ID for the timeline wrapper. Useful with `noUniqueId={true}`. | -| `disableToolbar` | `boolean` | `false` | Hides the entire toolbar/control panel. | -| `toolbarPosition` | `'top'` or `'bottom'` | `'top'` | Positions the toolbar at the top or bottom of the timeline. | -| `highlightCardsOnHover` | `boolean` | `false` | Highlights timeline cards on mouse hover. | - -## 🎨 Customization - -### Rendering Custom Content - -Pass React elements as children to ``. Each child will be rendered into a timeline card. This can be combined with the `items` prop to provide titles or other metadata. - -```jsx -const customItems = [ - { title: '2023-01-01', cardTitle: 'Event One' }, - { title: '2023-02-15', cardTitle: 'Event Two' }, -]; - - -
-

Custom Content for Event One

-

This is fully custom JSX rendered in the first card.

-
-
- Custom Image -

An image in the second card.

-
-
; -``` - -### Custom Icons - -Provide images for timeline points by wrapping them in a `div` with `className="chrono-icons"` as a child of ``. Icons are applied sequentially. - -```jsx - - {/* Custom content for cards (optional) */} -
Card 1 Content
-
Card 2 Content
- - {/* Custom icons for timeline points */} -
- icon1 - icon2 - {/* Add more images for more items */} -
-
-``` - -### Nested Timelines - -Create timelines within timeline cards by providing an `items` array within a parent timeline item. - -```jsx -const itemsWithNested = [ - { - title: 'Main Event 1', - cardTitle: 'Chapter 1', - items: [ - // Nested timeline - { cardTitle: 'Sub-event 1.1', cardSubtitle: 'Details for 1.1' }, - { - cardTitle: 'Sub-event 1.2', - media: { type: 'IMAGE', source: { url: '...' } }, - }, - ], - }, - { title: 'Main Event 2', cardTitle: 'Chapter 2' }, -]; - -; -``` - -### Custom Class Names - -Apply your own CSS classes to various parts of the timeline using the `classNames` prop. - -```jsx - -``` - -### Custom Font Sizes - -Adjust font sizes for card elements using the `fontSizes` prop. - -```jsx - -``` - -### Custom Button Alt Text - -Customize button text and accessibility labels: - -```jsx - -``` - -## 📦 Examples & Demos - -### CodeSandbox Examples - -[![Edit react-chrono](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/p/sandbox/silly-wilbur-1fcs3?file=%2Fsrc%2FApp.js) - -### Storybook - -[Interactive component documentation](https://5f985eb478dcb00022cfd60e-crlyulevwt.chromatic.com/) - -## 🛠️ Build Setup - -```bash -# Clone the repository -git clone https://github.com/prabhuignoto/react-chrono.git -cd react-chrono - -# Install dependencies -pnpm install - -# Start development server -pnpm run dev - -# Build for production -pnpm run build - -# Run tests -pnpm test -``` - -## 🧪 Tests - -The project uses Vitest for testing with comprehensive coverage: - -```bash -# Run all tests -pnpm test - -# Run tests in watch mode -pnpm test:watch - -# Generate coverage report -pnpm test:coverage -``` - -## 🤝 Contributing - -Contributions are welcome! Please read our [Contributing Guide](./CONTRIBUTING.md) for details on our code of conduct and the process for submitting pull requests. - -## 🧱 Built With - -- [React](https://reactjs.org/) - The web framework used -- [TypeScript](https://www.typescriptlang.org/) - For type safety -- [Styled Components](https://styled-components.com/) - For styling -- [FocusTrap](https://github.com/focus-trap/focus-trap) - For accessibility -- [Rollup](https://rollupjs.org/) - For bundling - -## 💖 Support & Meta - -- **Star** this repo on [GitHub](https://github.com/prabhuignoto/react-chrono) -- **Follow** the author on [Twitter](https://twitter.com/prabhumurthy2) -- **Create issues** for bug reports and feature requests -- **Contribute** to make this library better - -## ✨ Contributors - -Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): - - - - - - - +- Install Go tools 1.20+ - () +- Clone this repo `git clone git@github.com:nektos/act.git` +- Run unit tests with `make test` +- Build and install: `make install` diff --git a/coverage/__tests__/index.html b/coverage/__tests__/index.html deleted file mode 100644 index c51251340..000000000 --- a/coverage/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for __tests__ - - - - - - - - - -
-
-

All files __tests__

-
- -
- 100% - Statements - 126/126 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 126/126 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
react-chrono.test.ts -
-
100%126/126100%9/9100%0/0100%126/126
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/__tests__/react-chrono.test.ts.html b/coverage/__tests__/react-chrono.test.ts.html deleted file mode 100644 index 3228d5f62..000000000 --- a/coverage/__tests__/react-chrono.test.ts.html +++ /dev/null @@ -1,532 +0,0 @@ - - - - - - Code coverage report for __tests__/react-chrono.test.ts - - - - - - - - - -
-
-

All files / __tests__ react-chrono.test.ts

-
- -
- 100% - Statements - 126/126 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 126/126 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -1501x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x - 
import { describe, expect, it } from 'vitest';
-import { Chrono } from '../react-chrono';
-import type { TimelineItem } from '../react-chrono';
- 
-describe('react-chrono exports', () => {
-  it('should export Chrono component', () => {
-    expect(Chrono).toBeDefined();
-    // Chrono is wrapped with React.memo, so typeof is 'object'
-    expect(typeof Chrono).toBe('object');
-  });
- 
-  it('should export TimelineItem type', () => {
-    // This test verifies that the TimelineItem type is properly exported
-    // TypeScript compilation will fail if the type is not properly exported
-    const timelineItem: TimelineItem = {
-      id: 'test-id',
-      title: 'Test Title',
-      cardTitle: 'Test Card Title',
-      cardSubtitle: 'Test Card Subtitle',
-      cardDetailedText: 'Test detailed text',
-    };
- 
-    expect(timelineItem).toBeDefined();
-    expect(timelineItem.id).toBe('test-id');
-    expect(timelineItem.title).toBe('Test Title');
-  });
- 
-  it('should verify Chrono is the default export from components', () => {
-    // Since Chrono is wrapped with React.memo, check if it has the typical memo structure
-    expect(Chrono).toHaveProperty('$$typeof');
-    expect(Chrono.$$typeof).toBeDefined();
-  });
- 
-  it('should validate TimelineItem interface properties', () => {
-    // Test that TimelineItem accepts all expected properties
-    const complexTimelineItem: TimelineItem = {
-      id: 'complex-item',
-      title: 'Complex Title',
-      cardTitle: 'Complex Card Title',
-      cardSubtitle: 'Complex Card Subtitle',
-      cardDetailedText: ['Detail 1', 'Detail 2'],
-      date: new Date(),
-      media: {
-        type: 'IMAGE',
-        source: {
-          url: 'https://example.com/image.jpg',
-        },
-      },
-      url: 'https://example.com',
-      visible: true,
-      active: false,
-      position: 'left',
-      isNested: false,
-      hasNestedItems: false,
-    };
- 
-    expect(complexTimelineItem).toBeDefined();
-    expect(complexTimelineItem.cardDetailedText).toEqual(['Detail 1', 'Detail 2']);
-    expect(complexTimelineItem.date).toBeInstanceOf(Date);
-    expect(complexTimelineItem.media?.type).toBe('IMAGE');
-    expect(complexTimelineItem.url).toBe('https://example.com');
-  });
- 
-  it('should handle optional TimelineItem properties', () => {
-    // Test that TimelineItem works with minimal properties
-    const minimalTimelineItem: TimelineItem = {};
- 
-    expect(minimalTimelineItem).toBeDefined();
-    expect(Object.keys(minimalTimelineItem)).toHaveLength(0);
-  });
- 
-  it('should support nested timeline items', () => {
-    const nestedTimelineItem: TimelineItem = {
-      id: 'parent-item',
-      title: 'Parent Item',
-      hasNestedItems: true,
-      items: [
-        {
-          id: 'child-1',
-          title: 'Child 1',
-          cardTitle: 'Child Card 1',
-        },
-        {
-          id: 'child-2',
-          title: 'Child 2',
-          cardTitle: 'Child Card 2',
-        },
-      ],
-    };
- 
-    expect(nestedTimelineItem.hasNestedItems).toBe(true);
-    expect(nestedTimelineItem.items).toHaveLength(2);
-    expect(nestedTimelineItem.items?.[0]?.id).toBe('child-1');
-    expect(nestedTimelineItem.items?.[1]?.id).toBe('child-2');
-  });
- 
-  it('should support different media types in TimelineItem', () => {
-    const imageItem: TimelineItem = {
-      id: 'image-item',
-      media: {
-        type: 'IMAGE',
-        source: {
-          url: 'https://example.com/image.jpg',
-        },
-      },
-    };
- 
-    const videoItem: TimelineItem = {
-      id: 'video-item',
-      media: {
-        type: 'VIDEO',
-        source: {
-          url: 'https://example.com/video.mp4',
-        },
-      },
-    };
- 
-    const youtubeItem: TimelineItem = {
-      id: 'youtube-item',
-      media: {
-        type: 'VIDEO',
-        source: {
-          url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
-        },
-      },
-    };
- 
-    expect(imageItem.media?.type).toBe('IMAGE');
-    expect(videoItem.media?.type).toBe('VIDEO');
-    expect(youtubeItem.media?.type).toBe('VIDEO');
-  });
- 
-  it('should support React nodes in TimelineItem properties', () => {
-    const timelineItemWithNodes: TimelineItem = {
-      id: 'react-node-item',
-      title: 'React Node Title',
-      cardTitle: 'React Node Card Title',
-      cardSubtitle: 'React Node Subtitle',
-      cardDetailedText: 'React Node Details',
-      timelineContent: 'Custom timeline content',
-    };
- 
-    expect(timelineItemWithNodes.title).toBe('React Node Title');
-    expect(timelineItemWithNodes.cardTitle).toBe('React Node Card Title');
-    expect(timelineItemWithNodes.cardSubtitle).toBe('React Node Subtitle');
-    expect(timelineItemWithNodes.cardDetailedText).toBe('React Node Details');
-    expect(timelineItemWithNodes.timelineContent).toBe('Custom timeline content');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/base.css b/coverage/base.css deleted file mode 100644 index f418035b4..000000000 --- a/coverage/base.css +++ /dev/null @@ -1,224 +0,0 @@ -body, html { - margin:0; padding: 0; - height: 100%; -} -body { - font-family: Helvetica Neue, Helvetica, Arial; - font-size: 14px; - color:#333; -} -.small { font-size: 12px; } -*, *:after, *:before { - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - } -h1 { font-size: 20px; margin: 0;} -h2 { font-size: 14px; } -pre { - font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { color:#0074D9; text-decoration:none; } -a:hover { text-decoration:underline; } -.strong { font-weight: bold; } -.space-top1 { padding: 10px 0 0 0; } -.pad2y { padding: 20px 0; } -.pad1y { padding: 10px 0; } -.pad2x { padding: 0 20px; } -.pad2 { padding: 20px; } -.pad1 { padding: 10px; } -.space-left2 { padding-left:55px; } -.space-right2 { padding-right:20px; } -.center { text-align:center; } -.clearfix { display:block; } -.clearfix:after { - content:''; - display:block; - height:0; - clear:both; - visibility:hidden; - } -.fl { float: left; } -@media only screen and (max-width:640px) { - .col3 { width:100%; max-width:100%; } - .hide-mobile { display:none!important; } -} - -.quiet { - color: #7f7f7f; - color: rgba(0,0,0,0.5); -} -.quiet a { opacity: 0.7; } - -.fraction { - font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 10px; - color: #555; - background: #E8E8E8; - padding: 4px 5px; - border-radius: 3px; - vertical-align: middle; -} - -div.path a:link, div.path a:visited { color: #333; } -table.coverage { - border-collapse: collapse; - margin: 10px 0 0 0; - padding: 0; -} - -table.coverage td { - margin: 0; - padding: 0; - vertical-align: top; -} -table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; -} -table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width:20px; -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; -} -.missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} -.coverage-summary { - border-collapse: collapse; - width: 100%; -} -.coverage-summary tr { border-bottom: 1px solid #bbb; } -.keyline-all { border: 1px solid #ddd; } -.coverage-summary td, .coverage-summary th { padding: 10px; } -.coverage-summary tbody { border: 1px solid #bbb; } -.coverage-summary td { border-right: 1px solid #bbb; } -.coverage-summary td:last-child { border-right: none; } -.coverage-summary th { - text-align: left; - font-weight: normal; - white-space: nowrap; -} -.coverage-summary th.file { border-right: none !important; } -.coverage-summary th.pct { } -.coverage-summary th.pic, -.coverage-summary th.abs, -.coverage-summary td.pct, -.coverage-summary td.abs { text-align: right; } -.coverage-summary td.file { white-space: nowrap; } -.coverage-summary td.pic { min-width: 120px !important; } -.coverage-summary tfoot td { } - -.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { height: 10px; } -/* yellow */ -.cbranch-no { background: yellow !important; color: #111; } -/* dark red */ -.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } -.low .chart { border:1px solid #C21F39 } -.highlighted, -.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ - background: #C21F39 !important; -} -/* medium red */ -.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } -/* light red */ -.low, .cline-no { background:#FCE1E5 } -/* light green */ -.high, .cline-yes { background:rgb(230,245,208) } -/* medium green */ -.cstat-yes { background:rgb(161,215,106) } -/* dark green */ -.status-line.high, .high .cover-fill { background:rgb(77,146,33) } -.high .chart { border:1px solid rgb(77,146,33) } -/* dark yellow (gold) */ -.status-line.medium, .medium .cover-fill { background: #f9cd0b; } -.medium .chart { border:1px solid #f9cd0b; } -/* light yellow */ -.medium { background: #fff4c2; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -span.cline-neutral { background: #eaeaea; } - -.coverage-summary td.empty { - opacity: .5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; -} - -.cover-fill, .cover-empty { - display:inline-block; - height: 12px; -} -.chart { - line-height: 0; -} -.cover-empty { - background: white; -} -.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -48px; -} -.footer, .push { - height: 48px; -} diff --git a/coverage/block-navigation.js b/coverage/block-navigation.js deleted file mode 100644 index cc1213023..000000000 --- a/coverage/block-navigation.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; - - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - - // Selecter that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); - - var currentIndex; - - function toggleClass(index) { - missingCoverageElements - .item(currentIndex) - .classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center' - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; - } - - makeCurrent(nextIndex); - } - - function goToNext() { - var nextIndex = 0; - - if ( - typeof currentIndex === 'number' && - currentIndex < missingCoverageElements.length - 1 - ) { - nextIndex = currentIndex + 1; - } - - makeCurrent(nextIndex); - } - - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } - - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; - } - }; -})(); -window.addEventListener('keydown', jumpToCode); diff --git a/coverage/clover.xml b/coverage/clover.xml deleted file mode 100644 index 40a9a3c77..000000000 --- a/coverage/clover.xml +++ /dev/null @@ -1,12053 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/coverage/components/__tests__/GlobalContext.test.tsx.html b/coverage/components/__tests__/GlobalContext.test.tsx.html deleted file mode 100644 index ebf23bed8..000000000 --- a/coverage/components/__tests__/GlobalContext.test.tsx.html +++ /dev/null @@ -1,2290 +0,0 @@ - - - - - - Code coverage report for components/__tests__/GlobalContext.test.tsx - - - - - - - - - -
-
-

All files / components/__tests__ GlobalContext.test.tsx

-
- -
- 100% - Statements - 553/553 -
- - -
- 98.8% - Branches - 83/84 -
- - -
- 100% - Functions - 11/11 -
- - -
- 100% - Lines - 553/553 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -7361x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -1x -48x -48x -48x -48x -  -  -  -  -  -  -1x -43x -  -  -1x -39x -39x -39x -39x -  -39x -45x -45x -45x -  -39x -39x -39x -39x -39x -  -39x -39x -39x -39x -39x -  -  -  -  -  -1x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -  -1x -41x -41x -41x -41x -41x -41x -41x -41x -  -1x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -  -  -  -  -  -1x -1x -40x -40x -40x -40x -40x -1x -  -1x -40x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -3x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -6x -3x -3x -3x -3x -6x -1x -  -  -1x -1x -  -  -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import { render, screen, act } from '@testing-library/react';
-import { useContext } from 'react';
-import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import GlobalContextProvider, {
-  GlobalContext,
-  ContextProps,
-} from '../GlobalContext';
-import { TextDensity, TimelineMode, ButtonTexts } from '@models/TimelineModel';
-import { Theme } from '@models/Theme';
- 
-// ============================================================================
-// MOCKS & UTILITIES
-// ============================================================================
- 
-// Use vi.hoisted to ensure mock functions are available during hoisting
-const {
-  mockGetDefaultButtonTexts,
-  mockGetDefaultClassNames,
-  mockGetDefaultThemeOrDark,
-  mockGetSlideShowType,
-  mockUseMatchMedia,
-} = vi.hoisted(() => ({
-  mockGetDefaultButtonTexts: vi.fn(),
-  mockGetDefaultClassNames: vi.fn(),
-  mockGetDefaultThemeOrDark: vi.fn(),
-  mockGetSlideShowType: vi.fn(),
-  mockUseMatchMedia: vi.fn(),
-}));
- 
-vi.mock('@utils/index', () => ({
-  getDefaultButtonTexts: mockGetDefaultButtonTexts,
-  getDefaultClassNames: mockGetDefaultClassNames,
-  getDefaultThemeOrDark: mockGetDefaultThemeOrDark,
-  getSlideShowType: mockGetSlideShowType,
-}));
- 
-vi.mock('../effects/useMatchMedia', () => ({
-  useMatchMedia: mockUseMatchMedia,
-}));
- 
-// ============================================================================
-// TEST UTILITIES
-// ============================================================================
- 
-interface TestContextConsumerProps {
-  onContextValue: (value: ContextProps) => void;
-}
- 
-const TestContextConsumer = ({ onContextValue }: TestContextConsumerProps) => {
-  const contextValue = useContext(GlobalContext);
-  onContextValue(contextValue);
-  return <div data-testid="context-consumer">Context Consumer</div>;
-};
- 
-interface TestWrapperProps {
-  children: React.ReactElement | React.ReactElement[];
-  contextProps?: Partial<ContextProps>;
-}
- 
-const TestWrapper = ({ children, contextProps = {} }: TestWrapperProps) => (
-  <GlobalContextProvider {...contextProps}>{children}</GlobalContextProvider>
-);
- 
-const renderWithContext = (
-  contextProps: Partial<ContextProps> = {},
-  onContextValue?: (value: ContextProps) => void,
-) => {
-  let capturedContext: ContextProps | null = null;
- 
-  const contextCapture = (value: ContextProps) => {
-    capturedContext = value;
-    onContextValue?.(value);
-  };
- 
-  const renderResult = render(
-    <TestWrapper contextProps={contextProps}>
-      <TestContextConsumer onContextValue={contextCapture} />
-    </TestWrapper>,
-  );
- 
-  return {
-    ...renderResult,
-    getContext: () => capturedContext!,
-  };
-};
- 
-// ============================================================================
-// TEST DATA
-// ============================================================================
- 
-const createMockButtonTexts = (): ButtonTexts => ({
-  first: 'First',
-  last: 'Last',
-  play: 'Play',
-  stop: 'Stop',
-  previous: 'Previous',
-  next: 'Next',
-  dark: 'Dark',
-  light: 'Light',
-  timelinePoint: 'Timeline Point',
-  searchPlaceholder: 'Search...',
-  searchAriaLabel: 'Search timeline',
-  clearSearch: 'Clear',
-  nextMatch: 'Next Match',
-  previousMatch: 'Previous Match',
-});
- 
-const createMockClassNames = () => ({
-  card: 'rc-card',
-  cardMedia: 'rc-card-media',
-  cardSubTitle: 'rc-card-subtitle',
-  cardText: 'rc-card-text',
-  cardTitle: 'rc-card-title',
-  controls: 'rc-controls',
-  title: 'rc-title',
-});
- 
-const createMockTheme = (): Theme => ({
-  primary: '#0f52ba',
-  secondary: '#ffdf00',
-  cardBgColor: '#ffffff',
-  cardDetailsBackGround: '#ffffff',
-  cardDetailsColor: '#000',
-  cardMediaBgColor: '#ffffff',
-  cardSubtitleColor: '#000',
-  cardTitleColor: '#000',
-  detailsColor: '#000',
-  iconBackgroundColor: '#ffffff',
-  nestedCardBgColor: '#ffffff',
-  nestedCardDetailsBackGround: '#ffffff',
-  nestedCardDetailsColor: '#000',
-  nestedCardSubtitleColor: '#000',
-  nestedCardTitleColor: '#000',
-  textColor: '#000',
-  titleColor: '#0f52ba',
-  titleColorActive: '#0f52ba',
-  toolbarBgColor: '#ffffff',
-  toolbarBtnBgColor: '#0f52ba',
-  toolbarTextColor: '#000',
-});
- 
-// ============================================================================
-// TEST SETUP & TEARDOWN
-// ============================================================================
- 
-describe('GlobalContext', () => {
-  beforeEach(() => {
-    mockGetDefaultButtonTexts.mockReturnValue(createMockButtonTexts());
-    mockGetDefaultClassNames.mockReturnValue(createMockClassNames());
-    mockGetDefaultThemeOrDark.mockReturnValue(createMockTheme());
-    mockGetSlideShowType.mockReturnValue('reveal');
-    mockUseMatchMedia.mockReturnValue(false);
-  });
- 
-  afterEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  // ============================================================================
-  // BASIC FUNCTIONALITY TESTS
-  // ============================================================================
- 
-  describe('Provider Initialization', () => {
-    it('should render provider and children without errors', () => {
-      render(
-        <TestWrapper>
-          <div data-testid="test-child">Test Child</div>
-        </TestWrapper>,
-      );
- 
-      expect(screen.getByTestId('test-child')).toBeInTheDocument();
-    });
- 
-    it('should provide context with default values', () => {
-      const { getContext } = renderWithContext();
-      const context = getContext();
- 
-      expect(context).toBeDefined();
-      expect(context.mode).toBe('VERTICAL_ALTERNATING');
-      expect(context.cardHeight).toBe(200);
-      expect(context.cardLess).toBe(false);
-      expect(context.textDensity).toBe('HIGH');
-    });
- 
-    it('should apply custom props correctly', () => {
-      const customProps = {
-        mode: 'HORIZONTAL' as TimelineMode,
-        cardHeight: 300,
-        cardLess: true,
-        textDensity: 'LOW' as TextDensity,
-        responsiveBreakPoint: 768,
-      };
- 
-      const { getContext } = renderWithContext(customProps);
-      const context = getContext();
- 
-      expect(context.mode).toBe('HORIZONTAL');
-      expect(context.cardHeight).toBe(300);
-      expect(context.cardLess).toBe(true);
-      expect(context.textDensity).toBe('LOW');
-      expect(context.responsiveBreakPoint).toBe(768);
-    });
-  });
- 
-  // ============================================================================
-  // STATE MANAGEMENT TESTS
-  // ============================================================================
- 
-  describe('State Management', () => {
-    describe('Dark Mode State', () => {
-      it('should initialize dark mode from props', () => {
-        const { getContext } = renderWithContext({ darkMode: true });
-        expect(getContext().darkMode).toBe(true);
-      });
- 
-      it('should toggle dark mode and call theme change callback', () => {
-        const onThemeChange = vi.fn();
-        const { getContext, rerender } = renderWithContext({
-          darkMode: false,
-          onThemeChange,
-        });
- 
-        const initialContext = getContext();
-        expect(initialContext.darkMode).toBe(false);
- 
-        act(() => {
-          initialContext.toggleDarkMode?.();
-        });
- 
-        rerender(
-          <TestWrapper contextProps={{ darkMode: false, onThemeChange }}>
-            <TestContextConsumer onContextValue={() => {}} />
-          </TestWrapper>,
-        );
- 
-        expect(onThemeChange).toHaveBeenCalledTimes(1);
-      });
- 
-      it('should handle toggle when no theme change callback provided', () => {
-        const { getContext } = renderWithContext({ darkMode: false });
- 
-        expect(() => {
-          act(() => {
-            getContext().toggleDarkMode?.();
-          });
-        }).not.toThrow();
-      });
-    });
- 
-    describe('Horizontal Cards State', () => {
-      it('should initialize horizontal cards state from props', () => {
-        const { getContext } = renderWithContext({
-          showAllCardsHorizontal: true,
-        });
-        expect(getContext().showAllCardsHorizontal).toBe(true);
-      });
- 
-      it('should update horizontal cards state', () => {
-        const { getContext, rerender } = renderWithContext({
-          showAllCardsHorizontal: false,
-        });
- 
-        const initialContext = getContext();
-        expect(initialContext.showAllCardsHorizontal).toBe(false);
- 
-        act(() => {
-          initialContext.updateHorizontalAllCards?.(true);
-        });
- 
-        rerender(
-          <TestWrapper contextProps={{ showAllCardsHorizontal: false }}>
-            <TestContextConsumer onContextValue={() => {}} />
-          </TestWrapper>,
-        );
- 
-        expect(getContext().showAllCardsHorizontal).toBe(true);
-      });
-    });
- 
-    describe('Text Density State', () => {
-      it('should initialize text density from props', () => {
-        const { getContext } = renderWithContext({ textDensity: 'LOW' });
-        expect(getContext().textDensity).toBe('LOW');
-      });
- 
-      it('should update text density state', () => {
-        const { getContext, rerender } = renderWithContext({
-          textDensity: 'HIGH',
-        });
- 
-        const initialContext = getContext();
-        expect(initialContext.textDensity).toBe('HIGH');
- 
-        act(() => {
-          initialContext.updateTextContentDensity?.('LOW');
-        });
- 
-        rerender(
-          <TestWrapper contextProps={{ textDensity: 'HIGH' }}>
-            <TestContextConsumer onContextValue={() => {}} />
-          </TestWrapper>,
-        );
- 
-        expect(getContext().textDensity).toBe('LOW');
-      });
-    });
-  });
- 
-  // ============================================================================
-  // COMPUTED VALUES TESTS
-  // ============================================================================
- 
-  describe('Computed Values', () => {
-    describe('Card Height Calculations', () => {
-      it('should calculate card height for non-cardless mode', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 250,
-          cardLess: false,
-        });
-        expect(getContext().cardHeight).toBe(250);
-      });
- 
-      it('should handle card height for cardless mode', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 150,
-          cardLess: true,
-        });
-        expect(getContext().cardHeight).toBe(150);
-      });
- 
-      it('should use default when cardHeight is undefined in cardless mode', () => {
-        const { getContext } = renderWithContext({
-          cardLess: true,
-          cardHeight: undefined,
-        });
-        // Default cardHeight is 200, so with cardLess it should still be 200
-        expect(getContext().cardHeight).toBe(200);
-      });
-    });
- 
-    describe('Content Details Height', () => {
-      it('should calculate content details height with default values', () => {
-        const { getContext } = renderWithContext();
-        // newCardHeight = max(10 + 200, 200) = 210
-        // detailsHeightApprox = round(210 * 0.75) = 158
-        // final = max(10, 158) = 158
-        expect(getContext().contentDetailsHeight).toBe(158);
-      });
- 
-      it('should calculate with custom media and content heights', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 150,
-          contentDetailsHeight: 50,
-          mediaHeight: 100,
-        });
-        // newCardHeight = max(50 + 100, 150) = 150
-        // detailsHeightApprox = round(150 * 0.75) = 113
-        // final = max(50, 113) = 113
-        expect(getContext().contentDetailsHeight).toBe(113);
-      });
- 
-      it('should handle undefined content and media heights', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 200,
-          contentDetailsHeight: undefined,
-          mediaHeight: undefined,
-        });
-        // newCardHeight = max(0 + 0, 200) = 200
-        // detailsHeightApprox = round(200 * 0.75) = 150
-        // final = max(0, 150) = 150
-        expect(getContext().contentDetailsHeight).toBe(158);
-      });
-    });
- 
-    describe('Active Item Index', () => {
-      it('should compute active index for non-flipped layout', () => {
-        const { getContext } = renderWithContext({
-          flipLayout: false,
-          items: [
-            { title: 'Item 1' },
-            { title: 'Item 2' },
-            { title: 'Item 3' },
-          ],
-        });
-        expect(getContext().activeItemIndex).toBe(0);
-      });
- 
-      it('should compute active index for flipped layout', () => {
-        const { getContext } = renderWithContext({
-          flipLayout: true,
-          items: [
-            { title: 'Item 1' },
-            { title: 'Item 2' },
-            { title: 'Item 3' },
-          ],
-        });
-        expect(getContext().activeItemIndex).toBe(2);
-      });
-    });
- 
-    describe('Media Alignment', () => {
-      it('should set left alignment for vertical mode without text overlay', () => {
-        const { getContext } = renderWithContext({
-          mode: 'VERTICAL',
-          textOverlay: false,
-        });
-        expect(getContext().mediaSettings?.align).toBe('left');
-      });
- 
-      it('should set center alignment for non-vertical mode', () => {
-        const { getContext } = renderWithContext({
-          mode: 'HORIZONTAL',
-          textOverlay: false,
-        });
-        expect(getContext().mediaSettings?.align).toBe('center');
-      });
- 
-      it('should set center alignment when text overlay is enabled', () => {
-        const { getContext } = renderWithContext({
-          mode: 'VERTICAL',
-          textOverlay: true,
-        });
-        expect(getContext().mediaSettings?.align).toBe('center');
-      });
-    });
-  });
- 
-  // ============================================================================
-  // RESPONSIVE BEHAVIOR TESTS
-  // ============================================================================
- 
-  describe('Responsive Behavior', () => {
-    beforeEach(() => {
-      vi.clearAllMocks();
-    });
- 
-    it('should setup mobile detection with correct breakpoints', () => {
-      renderWithContext({
-        responsiveBreakPoint: 768,
-        enableBreakPoint: true,
-      });
- 
-      expect(mockUseMatchMedia).toHaveBeenCalledWith('(max-width: 767px)', {
-        onMatch: expect.any(Function),
-        enabled: true,
-      });
-      expect(mockUseMatchMedia).toHaveBeenCalledWith('(min-width: 768px)', {
-        onMatch: expect.any(Function),
-        enabled: true,
-      });
-    });
- 
-    it('should disable breakpoint detection when configured', () => {
-      renderWithContext({
-        enableBreakPoint: false,
-      });
- 
-      expect(mockUseMatchMedia).toHaveBeenCalledWith('(max-width: 1023px)', {
-        onMatch: expect.any(Function),
-        enabled: false,
-      });
-    });
- 
-    it('should handle mobile state changes', () => {
-      let mobileCallback: (() => void) | undefined;
-      let desktopCallback: (() => void) | undefined;
- 
-      mockUseMatchMedia.mockImplementation((query: string, options: any) => {
-        if (query.includes('max-width')) {
-          mobileCallback = options.onMatch;
-        } else if (query.includes('min-width')) {
-          desktopCallback = options.onMatch;
-        }
-        return false;
-      });
- 
-      // Initial render
-      const { getContext } = renderWithContext({ enableBreakPoint: true });
-      expect(getContext().isMobile).toBe(false);
- 
-      // Simulate mobile detection
-      act(() => {
-        mobileCallback?.();
-      });
- 
-      // Verify mobile state
-      expect(getContext().isMobile).toBe(true);
- 
-      // Simulate desktop detection
-      act(() => {
-        desktopCallback?.();
-      });
- 
-      // Verify desktop state
-      expect(getContext().isMobile).toBe(false);
- 
-      // Verify that useMatchMedia was called at least once for each breakpoint
-      expect(mockUseMatchMedia).toHaveBeenCalledWith(
-        '(max-width: 1023px)',
-        expect.any(Object),
-      );
-      expect(mockUseMatchMedia).toHaveBeenCalledWith(
-        '(min-width: 1024px)',
-        expect.any(Object),
-      );
-    });
-  });
- 
-  // ============================================================================
-  // PROPS MERGING TESTS
-  // ============================================================================
- 
-  describe('Props Merging', () => {
-    it('should merge button texts with defaults', () => {
-      const customButtonTexts: ButtonTexts = {
-        first: 'First',
-        last: 'Last',
-        play: 'Start',
-        stop: 'Pause',
-      };
-      const { getContext } = renderWithContext({
-        buttonTexts: customButtonTexts,
-      });
- 
-      expect(getContext().buttonTexts).toEqual({
-        ...createMockButtonTexts(),
-        ...customButtonTexts,
-      });
-    });
- 
-    it('should merge class names with defaults', () => {
-      const customClassNames = { card: 'custom-card', title: 'custom-title' };
-      const { getContext } = renderWithContext({
-        classNames: customClassNames,
-      });
- 
-      expect(getContext().classNames).toEqual({
-        ...createMockClassNames(),
-        ...customClassNames,
-      });
-    });
- 
-    it('should merge theme with defaults', () => {
-      const customTheme = { primary: '#ff0000', secondary: '#00ff00' };
-      const { getContext } = renderWithContext({
-        theme: customTheme,
-      });
- 
-      expect(getContext().theme).toEqual({
-        ...createMockTheme(),
-        ...customTheme,
-      });
-    });
- 
-    it('should merge font sizes with defaults', () => {
-      const customFontSizes = { cardTitle: '1.2rem', title: '1.5rem' };
-      const { getContext } = renderWithContext({
-        fontSizes: customFontSizes,
-      });
- 
-      const expectedFontSizes = {
-        cardSubtitle: '0.85rem',
-        cardText: '1rem',
-        cardTitle: '1.2rem',
-        title: '1.5rem',
-      };
- 
-      expect(getContext().fontSizes).toEqual(expectedFontSizes);
-    });
- 
-    it('should merge media settings with computed defaults', () => {
-      const customMediaSettings = { fit: 'contain' as const };
-      const { getContext } = renderWithContext({
-        mode: 'HORIZONTAL',
-        mediaSettings: customMediaSettings,
-      });
- 
-      expect(getContext().mediaSettings).toEqual({
-        align: 'center',
-        fit: 'contain',
-      });
-    });
-  });
- 
-  // ============================================================================
-  // STATIC DEFAULTS TESTS
-  // ============================================================================
- 
-  describe('Static Defaults', () => {
-    it('should provide correct static default values', () => {
-      const { getContext } = renderWithContext();
-      const context = getContext();
- 
-      expect(context.borderLessCards).toBe(false);
-      expect(context.disableToolbar).toBe(false);
-      expect(context.enableBreakPoint).toBe(true);
-      expect(context.enableDarkToggle).toBe(false);
-      expect(context.enableLayoutSwitch).toBe(true);
-      expect(context.enableQuickJump).toBe(true);
-      expect(context.focusActiveItemOnLoad).toBe(false);
-      expect(context.highlightCardsOnHover).toBe(false);
-      expect(context.lineWidth).toBe(3);
-      expect(context.nestedCardHeight).toBe(150);
-      expect(context.parseDetailsAsHTML).toBe(false);
-      expect(context.timelinePointDimension).toBe(16);
-      expect(context.timelinePointShape).toBe('circle');
-      expect(context.titleDateFormat).toBe('MMM DD, YYYY');
-      expect(context.toolbarPosition).toBe('top');
-      expect(context.uniqueId).toBe('react-chrono');
-      expect(context.useReadMore).toBe(true);
-      expect(context.scrollable).toEqual({ scrollbar: false });
-    });
- 
-    it('should allow overriding static defaults', () => {
-      const { getContext } = renderWithContext({
-        borderLessCards: true,
-        lineWidth: 5,
-        uniqueId: 'custom-timeline',
-        timelinePointShape: 'square',
-      });
- 
-      const context = getContext();
-      expect(context.borderLessCards).toBe(true);
-      expect(context.lineWidth).toBe(5);
-      expect(context.uniqueId).toBe('custom-timeline');
-      expect(context.timelinePointShape).toBe('square');
-    });
-  });
- 
-  // ============================================================================
-  // SLIDESHOW & INTERACTION TESTS
-  // ============================================================================
- 
-  describe('Slideshow and Interactions', () => {
-    it('should compute slideshow type based on mode', () => {
-      mockGetSlideShowType.mockReturnValue('slide_in');
- 
-      const { getContext } = renderWithContext({ mode: 'HORIZONTAL' });
-      expect(getContext().slideShowType).toBe('slide_in');
-      expect(mockGetSlideShowType).toHaveBeenCalledWith('HORIZONTAL');
-    });
- 
-    it('should handle slideshow properties', () => {
-      const { getContext } = renderWithContext({
-        slideShow: true,
-      });
- 
-      expect(getContext().showProgressOnSlideshow).toBe(true);
-      expect(getContext().slideItemDuration).toBe(2000);
-    });
- 
-    it('should disable interactions when specified', () => {
-      const { getContext } = renderWithContext({
-        disableInteraction: true,
-      });
- 
-      expect(getContext().disableAutoScrollOnClick).toBe(true);
-      expect(getContext().disableClickOnCircle).toBe(true);
-      expect(getContext().disableTimelinePoint).toBe(true);
-      expect(getContext().disableInteraction).toBe(false); // This gets overridden
-    });
-  });
- 
-  // ============================================================================
-  // UTILITY FUNCTIONS INTEGRATION
-  // ============================================================================
- 
-  describe('Utility Functions Integration', () => {
-    it('should call utility functions with correct parameters', () => {
-      renderWithContext({
-        darkMode: true,
-        mode: 'VERTICAL',
-      });
- 
-      expect(mockGetDefaultButtonTexts).toHaveBeenCalled();
-      expect(mockGetDefaultClassNames).toHaveBeenCalled();
-      expect(mockGetDefaultThemeOrDark).toHaveBeenCalledWith(true);
-      expect(mockGetSlideShowType).toHaveBeenCalledWith('VERTICAL');
-    });
- 
-    it('should handle utility function responses', () => {
-      const customButtonTexts = { play: 'Custom Play' };
-      const customTheme = { primary: '#custom' };
- 
-      mockGetDefaultButtonTexts.mockReturnValue(customButtonTexts);
-      mockGetDefaultThemeOrDark.mockReturnValue(customTheme);
- 
-      const { getContext } = renderWithContext();
- 
-      expect(getContext().buttonTexts).toEqual(customButtonTexts);
-      expect(getContext().theme).toEqual(customTheme);
-    });
-  });
- 
-  // ============================================================================
-  // EDGE CASES & ERROR HANDLING
-  // ============================================================================
- 
-  describe('Edge Cases', () => {
-    it('should handle undefined items array', () => {
-      const { getContext } = renderWithContext({
-        items: undefined,
-        flipLayout: true,
-      });
-      expect(getContext().activeItemIndex).toBe(-1);
-    });
- 
-    it('should handle empty items array', () => {
-      const { getContext } = renderWithContext({
-        items: [],
-        flipLayout: true,
-      });
-      expect(getContext().activeItemIndex).toBe(-1);
-    });
- 
-    it('should handle very large content details height', () => {
-      const { getContext } = renderWithContext({
-        cardHeight: 100,
-        contentDetailsHeight: 500,
-        mediaHeight: 50,
-      });
-      // Should be clamped appropriately
-      expect(getContext().contentDetailsHeight).toBeGreaterThan(0);
-    });
- 
-    it('should provide all required callback functions', () => {
-      const { getContext } = renderWithContext();
-      const context = getContext();
- 
-      expect(typeof context.toggleDarkMode).toBe('function');
-      expect(typeof context.updateHorizontalAllCards).toBe('function');
-      expect(typeof context.updateTextContentDensity).toBe('function');
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/__tests__/index.html b/coverage/components/__tests__/index.html deleted file mode 100644 index 9476bb3d2..000000000 --- a/coverage/components/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/__tests__ - - - - - - - - - -
-
-

All files components/__tests__

-
- -
- 100% - Statements - 553/553 -
- - -
- 98.8% - Branches - 83/84 -
- - -
- 100% - Functions - 11/11 -
- - -
- 100% - Lines - 553/553 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
GlobalContext.test.tsx -
-
100%553/55398.8%83/84100%11/11100%553/553
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/common/styles/index.html b/coverage/components/common/styles/index.html deleted file mode 100644 index e2a0342a0..000000000 --- a/coverage/components/common/styles/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/common/styles - - - - - - - - - -
-
-

All files components/common/styles

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 3/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
100%5/5100%3/3100%0/0100%5/5
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/common/styles/index.ts.html b/coverage/components/common/styles/index.ts.html deleted file mode 100644 index 522624336..000000000 --- a/coverage/components/common/styles/index.ts.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for components/common/styles/index.ts - - - - - - - - - -
-
-

All files / components/common/styles index.ts

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 3/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21  -1x -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  - 
import { Theme } from '@models/Theme';
-import { css } from 'styled-components';
- 
-export const ScrollBar = css<{ theme: Theme }>`
-  scrollbar-color: ${(p) => p.theme?.primary} default;
-  scrollbar-width: thin;
- 
-  &::-webkit-scrollbar {
-    width: 0.3em;
-  }
- 
-  &::-webkit-scrollbar-track {
-    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.2);
-  }
- 
-  &::-webkit-scrollbar-thumb {
-    background-color: ${(p) => p.theme?.primary};
-    outline: 1px solid ${(p) => p.theme?.primary};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/common/themes/index.html b/coverage/components/common/themes/index.html deleted file mode 100644 index b17e5a9e6..000000000 --- a/coverage/components/common/themes/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/common/themes - - - - - - - - - -
-
-

All files components/common/themes

-
- -
- 100% - Statements - 74/74 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 74/74 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
100%74/74100%0/0100%0/0100%74/74
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/common/themes/index.ts.html b/coverage/components/common/themes/index.ts.html deleted file mode 100644 index b125347f4..000000000 --- a/coverage/components/common/themes/index.ts.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - Code coverage report for components/common/themes/index.ts - - - - - - - - - -
-
-

All files / components/common/themes index.ts

-
- -
- 100% - Statements - 74/74 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 74/74 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { Theme } from '@models/Theme';
- 
-export const defaultTheme: Theme = {
-  cardBgColor: '#ffffff',
-  cardDetailsBackGround: '#ffffff',
-  cardDetailsColor: '#374151',
-  cardMediaBgColor: '#f8fafc',
-  cardSubtitleColor: '#6b7280',
-  cardTitleColor: '#007FFF',
-  detailsColor: '#374151',
-  iconBackgroundColor: '#007FFF',
-  nestedCardBgColor: '#f8fafc',
-  nestedCardDetailsBackGround: '#f8fafc',
-  nestedCardDetailsColor: '#374151',
-  nestedCardSubtitleColor: '#6b7280',
-  nestedCardTitleColor: '#1f2937',
-  primary: '#007FFF',
-  secondary: '#ffdf00',
-  titleColor: '#007FFF',
-  titleColorActive: '#007FFF',
-  toolbarBgColor: '#f1f5f9',
-  toolbarBtnBgColor: '#ffffff',
-  toolbarTextColor: '#1e293b',
-  timelineBgColor: '#ffffff',
- 
-  // Light mode styling
-  iconColor: '#007FFF',
-  buttonHoverBgColor: '#e2e8f0',
-  buttonActiveBgColor: '#007FFF',
-  buttonActiveIconColor: '#ffffff',
-  buttonBorderColor: '#e2e8f0',
-  buttonHoverBorderColor: '#007FFF',
-  buttonActiveBorderColor: '#007FFF',
-  shadowColor: 'rgba(0, 0, 0, 0.1)',
-  glowColor: 'rgba(0, 127, 255, 0.2)',
-  searchHighlightColor: 'rgba(0, 127, 255, 0.2)',
-  darkToggleActiveBgColor: '#007FFF',
-  darkToggleActiveIconColor: '#ffffff',
-  darkToggleActiveBorderColor: '#007FFF',
-  darkToggleGlowColor: 'rgba(0, 127, 255, 0.2)',
-};
- 
-export const darkTheme: Theme = {
-  cardBgColor: '#1f2937',
-  cardDetailsBackGround: '#1f2937',
-  cardDetailsColor: '#f3f4f6',
-  cardMediaBgColor: '#111827',
-  cardSubtitleColor: '#d1d5db',
-  cardTitleColor: '#60a5fa',
-  detailsColor: '#f3f4f6',
-  iconBackgroundColor: '#3b82f6',
-  nestedCardBgColor: '#111827',
-  nestedCardDetailsBackGround: '#111827',
-  nestedCardDetailsColor: '#f3f4f6',
-  nestedCardSubtitleColor: '#d1d5db',
-  nestedCardTitleColor: '#f9fafb',
-  primary: '#3b82f6',
-  secondary: '#fbbf24',
-  titleColor: '#60a5fa',
-  titleColorActive: '#60a5fa',
-  toolbarBgColor: '#111827',
-  toolbarBtnBgColor: '#374151',
-  toolbarTextColor: '#f3f4f6',
-  timelineBgColor: '#111827',
- 
-  // Dark mode styling - our enhanced colors as defaults
-  iconColor: '#93c5fd',
-  buttonHoverBgColor: '#4b5563',
-  buttonActiveBgColor: '#fbbf24',
-  buttonActiveIconColor: '#1f2937',
-  buttonBorderColor: 'rgba(255, 255, 255, 0.1)',
-  buttonHoverBorderColor: '#3b82f6',
-  buttonActiveBorderColor: '#3b82f6',
-  shadowColor: 'rgba(0, 0, 0, 0.4)',
-  glowColor: 'rgba(59, 130, 246, 0.4)',
-  searchHighlightColor: 'rgba(96, 165, 250, 0.4)',
-  darkToggleActiveBgColor: '#1e40af',
-  darkToggleActiveIconColor: '#e2e8f0',
-  darkToggleActiveBorderColor: '#3b82f6',
-  darkToggleGlowColor: 'rgba(59, 130, 246, 0.4)',
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/contexts/DynamicContext.tsx.html b/coverage/components/contexts/DynamicContext.tsx.html deleted file mode 100644 index 3e2019921..000000000 --- a/coverage/components/contexts/DynamicContext.tsx.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - Code coverage report for components/contexts/DynamicContext.tsx - - - - - - - - - -
-
-

All files / components/contexts DynamicContext.tsx

-
- -
- 100% - Statements - 33/33 -
- - -
- 100% - Branches - 0/0 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 33/33 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
/**
- * Dynamic Context - Contains frequently changing values like state and interactions
- * This context is optimized for dynamic values that change often
- */
-import { createContext } from 'react';
-import { TextDensity } from '@models/TimelineModel';
-import { Theme } from '@models/Theme';
- 
-export interface DynamicContextProps {
-  // Dynamic state values
-  isDarkMode: boolean;
-  isMobile: boolean;
-  horizontalAll: boolean;
-  textContentDensity: TextDensity;
- 
-  // Theme (can change with dark mode)
-  memoizedTheme: Theme;
- 
-  // Interaction callbacks
-  toggleDarkMode?: () => void;
-  updateHorizontalAllCards?: (state: boolean) => void;
-  updateTextContentDensity?: (value: TextDensity) => void;
-}
- 
-export const DynamicContext = createContext<DynamicContextProps>({
-  isDarkMode: false,
-  isMobile: false,
-  horizontalAll: false,
-  textContentDensity: 'HIGH',
-  memoizedTheme: {
-    primary: '#007FFF',
-    secondary: '#ffdf00',
-    cardBgColor: '#ffffff',
-    cardDetailsBackGround: '#ffffff',
-    cardDetailsColor: '#000',
-    cardMediaBgColor: '#f5f5f5',
-    cardSubtitleColor: '#000',
-    cardTitleColor: '#007FFF',
-    detailsColor: '#000',
-    iconBackgroundColor: '#007FFF',
-    nestedCardBgColor: '#f5f5f5',
-    nestedCardDetailsBackGround: '#f5f5f5',
-    nestedCardDetailsColor: '#000',
-    nestedCardSubtitleColor: '#000',
-    nestedCardTitleColor: '#000',
-    titleColor: '#007FFF',
-    titleColorActive: '#007FFF',
-    toolbarBgColor: '#f5f5f5',
-    toolbarBtnBgColor: '#ffffff',
-    toolbarTextColor: '#000',
-    timelineBgColor: '#f5f5f5',
-  },
-  // Default no-op implementations to prevent fallback to legacy context
-  toggleDarkMode: () => {},
-  updateHorizontalAllCards: () => {},
-  updateTextContentDensity: () => {},
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/contexts/OptimizedContextProvider.tsx.html b/coverage/components/contexts/OptimizedContextProvider.tsx.html deleted file mode 100644 index ab7ac503c..000000000 --- a/coverage/components/contexts/OptimizedContextProvider.tsx.html +++ /dev/null @@ -1,1192 +0,0 @@ - - - - - - Code coverage report for components/contexts/OptimizedContextProvider.tsx - - - - - - - - - -
-
-

All files / components/contexts OptimizedContextProvider.tsx

-
- -
- 99.66% - Statements - 299/300 -
- - -
- 86.66% - Branches - 39/45 -
- - -
- 100% - Functions - 3/3 -
- - -
- 99.66% - Lines - 299/300 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -  -  -  -51x -51x -51x -51x -51x -51x -51x -  -  -51x -2x -2x -51x -  -51x -1x -51x -  -51x -1x -51x -  -  -51x -51x -51x -51x -  -51x -51x -51x -51x -  -  -  -  -51x -51x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -51x -51x -42x -51x -51x -  -51x -42x -42x -42x -  -42x -51x -  -51x -51x -51x -51x -  -51x -51x -51x -51x -  -51x -  -51x -51x -51x -51x -  -51x -51x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -42x -51x -51x -  -  -  -  -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -  -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -  -  -  -51x -51x -44x -44x -44x -51x -51x -  -51x -51x -48x -48x -48x -48x -48x -48x -48x -48x -48x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -51x -51x -51x -51x -51x -51x -  -51x - 
/**
- * Optimized Context Provider - Splits stable and dynamic contexts for better performance
- */
-import React, {
-  FunctionComponent,
-  useCallback,
-  useMemo,
-  useState,
-} from 'react';
-import {
-  TimelineProps as PropsModel,
-  TextDensity,
-} from '@models/TimelineModel';
-import {
-  getDefaultButtonTexts,
-  getDefaultClassNames,
-  getDefaultThemeOrDark,
-  getSlideShowType,
-} from '@utils/index';
-import { useMatchMedia } from '../effects/useMatchMedia';
-import { StableContext, StableContextProps } from './StableContext';
-import { DynamicContext, DynamicContextProps } from './DynamicContext';
- 
-export type ContextProps = PropsModel & {
-  isMobile?: boolean;
-  toggleDarkMode?: () => void;
-  updateHorizontalAllCards?: (state: boolean) => void;
-  updateTextContentDensity?: (value: TextDensity) => void;
-};
- 
-interface OptimizedContextProviderProps extends Omit<ContextProps, 'children'> {
-  children: React.ReactNode;
-}
- 
-export const OptimizedContextProvider: FunctionComponent<
-  OptimizedContextProviderProps
-> = (props) => {
-  const {
-    cardHeight = 200,
-    cardLess = false,
-    flipLayout,
-    items = [],
-    theme,
-    buttonTexts,
-    classNames,
-    mode = 'VERTICAL_ALTERNATING',
-    fontSizes,
-    textOverlay,
-    darkMode,
-    slideShow,
-    onThemeChange,
-    mediaSettings,
-    mediaHeight = 200,
-    contentDetailsHeight = 10,
-    showAllCardsHorizontal,
-    textDensity = 'HIGH',
-    responsiveBreakPoint = 1024,
-    enableBreakPoint,
-    semanticTags,
-    children,
-  } = props;
- 
-  // ==========================================
-  // DYNAMIC STATE (changes frequently)
-  // ==========================================
-  const [isDarkMode, setIsDarkMode] = useState(darkMode);
-  const [horizontalAll, setHorizontalAll] = useState(
-    showAllCardsHorizontal ?? false,
-  );
-  const [isMobileDetected, setIsMobileDetected] = useState(false);
-  const [textContentDensity, setTextContentDensity] =
-    useState<TextDensity>(textDensity);
- 
-  // Dynamic callbacks
-  const toggleDarkMode = useCallback(() => {
-    setIsDarkMode(!isDarkMode);
-    onThemeChange?.();
-  }, [isDarkMode, onThemeChange]);
- 
-  const updateHorizontalAllCards = useCallback((state: boolean) => {
-    setHorizontalAll(state);
-  }, []);
- 
-  const updateTextContentDensity = useCallback((value: TextDensity) => {
-    setTextContentDensity(value);
-  }, []);
- 
-  // Responsive detection
-  useMatchMedia(`(max-width: ${responsiveBreakPoint - 1}px)`, {
-    onMatch: () => setIsMobileDetected(true),
-    enabled: enableBreakPoint,
-  });
- 
-  useMatchMedia(`(min-width: ${responsiveBreakPoint}px)`, {
-    onMatch: () => setIsMobileDetected(false),
-    enabled: enableBreakPoint,
-  });
- 
-  // ==========================================
-  // STABLE CONFIGURATION (rarely changes)
-  // ==========================================
-  const staticDefaults = useMemo(
-    () => ({
-      borderLessCards: props.borderLessCards ?? false,
-      cardLess: cardLess,
-      disableToolbar: props.disableToolbar ?? false,
-      enableBreakPoint: props.enableBreakPoint ?? true,
-      enableDarkToggle: props.enableDarkToggle ?? false,
-      enableLayoutSwitch: props.enableLayoutSwitch ?? true,
-      enableQuickJump: props.enableQuickJump ?? true,
-      focusActiveItemOnLoad: props.focusActiveItemOnLoad ?? false,
-      highlightCardsOnHover: props.highlightCardsOnHover ?? false,
-      lineWidth: props.lineWidth ?? 3,
-      mediaHeight: mediaHeight,
-      nestedCardHeight: props.nestedCardHeight ?? 150,
-      parseDetailsAsHTML: props.parseDetailsAsHTML ?? false,
-      scrollable: props.scrollable ?? {
-        scrollbar: false,
-      },
-      timelinePointDimension: props.timelinePointDimension ?? 16,
-      timelinePointShape: props.timelinePointShape ?? ('circle' as const),
-      titleDateFormat: props.titleDateFormat ?? 'MMM DD, YYYY',
-      toolbarPosition: props.toolbarPosition ?? ('top' as const),
-      uniqueId: props.uniqueId ?? 'react-chrono',
-      useReadMore: props.useReadMore ?? true,
-      disableTimelinePoint: props.disableTimelinePoint ?? false,
-      isChild: props.isChild ?? false,
-      noUniqueId: props.noUniqueId ?? false,
-    }),
-    [
-      props.borderLessCards,
-      cardLess,
-      props.disableToolbar,
-      props.enableBreakPoint,
-      props.enableDarkToggle,
-      props.enableLayoutSwitch,
-      props.enableQuickJump,
-      props.focusActiveItemOnLoad,
-      props.highlightCardsOnHover,
-      props.lineWidth,
-      mediaHeight,
-      props.nestedCardHeight,
-      props.parseDetailsAsHTML,
-      props.scrollable,
-      props.timelinePointDimension,
-      props.timelinePointShape,
-      props.titleDateFormat,
-      props.toolbarPosition,
-      props.uniqueId,
-      props.useReadMore,
-      props.disableTimelinePoint,
-      props.isChild,
-      props.noUniqueId,
-    ],
-  );
- 
-  const newCardHeight = useMemo(
-    () =>
-      Math.max((contentDetailsHeight ?? 0) + (mediaHeight ?? 0), cardHeight),
-    [contentDetailsHeight, mediaHeight, cardHeight],
-  );
- 
-  const newContentDetailsHeight = useMemo(() => {
-    const detailsHeightApprox = Math.round(newCardHeight * 0.75);
-    const actualContentDetailsHeight = contentDetailsHeight ?? 0;
-    return actualContentDetailsHeight > newCardHeight
-      ? Math.min(actualContentDetailsHeight, detailsHeightApprox)
-      : Math.max(actualContentDetailsHeight, detailsHeightApprox);
-  }, [newCardHeight, contentDetailsHeight]);
- 
-  const computedCardHeight = useMemo(
-    () => (cardLess ? (cardHeight ?? 80) : cardHeight),
-    [cardLess, cardHeight],
-  );
- 
-  const computedActiveItemIndex = useMemo(
-    () => (flipLayout ? items?.length - 1 : 0),
-    [flipLayout, items?.length],
-  );
- 
-  const computedSlideShowType = useMemo(() => getSlideShowType(mode), [mode]);
- 
-  const computedMediaAlign = useMemo(
-    () => (mode === 'VERTICAL' && !textOverlay ? 'left' : 'center'),
-    [mode, textOverlay],
-  );
- 
-  const memoizedButtonTexts = useMemo(
-    () => ({
-      ...getDefaultButtonTexts(),
-      ...buttonTexts,
-    }),
-    [buttonTexts],
-  );
- 
-  const memoizedClassNames = useMemo(
-    () => ({
-      ...getDefaultClassNames(),
-      ...classNames,
-    }),
-    [classNames],
-  );
- 
-  const memoizedFontSizes = useMemo(
-    () => ({
-      cardSubtitle: '0.85rem',
-      cardText: '1rem',
-      cardTitle: '1rem',
-      title: '1rem',
-      ...fontSizes,
-    }),
-    [fontSizes],
-  );
- 
-  const memoizedMediaSettings = useMemo(
-    () => ({
-      align: computedMediaAlign,
-      fit: 'cover' as const,
-      ...mediaSettings,
-    }),
-    [computedMediaAlign, mediaSettings],
-  );
- 
-  const memoizedSemanticTags = useMemo(
-    () => ({
-      cardTitle: 'span' as const,
-      cardSubtitle: 'span' as const,
-      ...semanticTags,
-    }),
-    [semanticTags],
-  );
- 
-  // ==========================================
-  // STABLE CONTEXT VALUE
-  // ==========================================
-  const stableContextValue = useMemo(
-    (): StableContextProps => ({
-      staticDefaults,
-      computedCardHeight,
-      computedActiveItemIndex,
-      computedSlideShowType,
-      computedMediaAlign,
-      newContentDetailsHeight,
-      memoizedButtonTexts,
-      memoizedClassNames,
-      memoizedFontSizes,
-      memoizedMediaSettings,
-      memoizedSemanticTags,
- 
-      // Pass through stable props
-      mode,
-      cardHeight,
-      flipLayout,
-      items,
-      fontSizes,
-      textOverlay,
-      mediaSettings,
-      responsiveBreakPoint,
-      enableBreakPoint,
-      slideItemDuration: props.slideItemDuration ?? 2000,
-      slideShowType: computedSlideShowType,
-      cardPositionHorizontal: props.cardPositionHorizontal,
-      disableNavOnKey: props.disableNavOnKey,
-      itemWidth: props.itemWidth ?? 200,
-      lineWidth: props.lineWidth ?? 3,
-      scrollable:
-        typeof props.scrollable === 'boolean' ? props.scrollable : true,
-      onScrollEnd: props.onScrollEnd,
-      toolbarPosition: props.toolbarPosition ?? 'top',
-      disableToolbar: props.disableToolbar ?? false,
-      cardWidth: props.cardWidth,
-      borderLessCards: props.borderLessCards ?? false,
-      disableAutoScrollOnClick: !!props.disableInteraction,
-      classNames: memoizedClassNames,
-      showProgressOnSlideshow: slideShow,
-      showOverallSlideshowProgress:
-        props.showOverallSlideshowProgress ?? slideShow,
-      disableInteraction: false,
-      highlightCardsOnHover: props.highlightCardsOnHover ?? false,
-      disableClickOnCircle: !!props.disableInteraction,
-      disableTimelinePoint: !!props.disableInteraction,
-      enableQuickJump: props.enableQuickJump ?? true,
-      enableLayoutSwitch: props.enableLayoutSwitch ?? true,
-      cardLess: cardLess,
-      useReadMore: props.useReadMore ?? true,
-    }),
-    [
-      staticDefaults,
-      computedCardHeight,
-      computedActiveItemIndex,
-      computedSlideShowType,
-      computedMediaAlign,
-      newContentDetailsHeight,
-      memoizedButtonTexts,
-      memoizedClassNames,
-      memoizedFontSizes,
-      memoizedMediaSettings,
-      memoizedSemanticTags,
-      mode,
-      cardHeight,
-      flipLayout,
-      items,
-      fontSizes,
-      textOverlay,
-      mediaSettings,
-      responsiveBreakPoint,
-      enableBreakPoint,
-      slideShow,
-      props.cardPositionHorizontal,
-      props.disableNavOnKey,
-      props.itemWidth,
-      props.lineWidth,
-      props.scrollable,
-      props.onScrollEnd,
-      props.toolbarPosition,
-      props.disableToolbar,
-      props.cardWidth,
-      props.borderLessCards,
-      props.disableInteraction,
-      props.highlightCardsOnHover,
-      props.enableQuickJump,
-      props.enableLayoutSwitch,
-      props.useReadMore,
-      props.showOverallSlideshowProgress,
-    ],
-  );
- 
-  // ==========================================
-  // DYNAMIC CONTEXT VALUE (theme changes with dark mode)
-  // ==========================================
-  const memoizedTheme = useMemo(
-    () => ({
-      ...getDefaultThemeOrDark(isDarkMode),
-      ...theme,
-    }),
-    [isDarkMode, theme],
-  );
- 
-  const dynamicContextValue = useMemo(
-    (): DynamicContextProps => ({
-      isDarkMode,
-      isMobile: isMobileDetected,
-      horizontalAll,
-      textContentDensity,
-      memoizedTheme,
-      toggleDarkMode,
-      updateHorizontalAllCards,
-      updateTextContentDensity,
-    }),
-    [
-      isDarkMode,
-      isMobileDetected,
-      horizontalAll,
-      textContentDensity,
-      memoizedTheme,
-      toggleDarkMode,
-      updateHorizontalAllCards,
-      updateTextContentDensity,
-    ],
-  );
- 
-  return (
-    <StableContext.Provider value={stableContextValue}>
-      <DynamicContext.Provider value={dynamicContextValue}>
-        {children}
-      </DynamicContext.Provider>
-    </StableContext.Provider>
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/contexts/StableContext.tsx.html b/coverage/components/contexts/StableContext.tsx.html deleted file mode 100644 index 43fd98e08..000000000 --- a/coverage/components/contexts/StableContext.tsx.html +++ /dev/null @@ -1,508 +0,0 @@ - - - - - - Code coverage report for components/contexts/StableContext.tsx - - - - - - - - - -
-
-

All files / components/contexts StableContext.tsx

-
- -
- 100% - Statements - 55/55 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 55/55 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
/**
- * Stable Context - Contains configuration values that rarely change
- * This context is optimized for stable values to reduce unnecessary re-renders
- */
-import { createContext } from 'react';
-import { TimelineProps, ButtonTexts } from '@models/TimelineModel';
- 
-export interface StableContextProps {
-  // Configuration that rarely changes
-  staticDefaults: {
-    borderLessCards: boolean;
-    cardLess: boolean;
-    disableTimelinePoint: boolean;
-    disableToolbar: boolean;
-    enableBreakPoint: boolean;
-    enableDarkToggle: boolean;
-    enableLayoutSwitch: boolean;
-    enableQuickJump: boolean;
-    focusActiveItemOnLoad: boolean;
-    highlightCardsOnHover: boolean;
-    isChild: boolean;
-    lineWidth: number;
-    mediaHeight: number;
-    nestedCardHeight: number;
-    noUniqueId: boolean;
-    parseDetailsAsHTML: boolean;
-    scrollable: boolean | { scrollbar: boolean };
-    showProgressOnSlideshow?: boolean;
-    showOverallSlideshowProgress?: boolean;
-    timelinePointDimension: number;
-    timelinePointShape: 'circle' | 'square' | 'diamond';
-    titleDateFormat: string;
-    toolbarPosition: 'top' | 'bottom';
-    uniqueId: string;
-    useReadMore: boolean;
-  };
- 
-  // Computed configuration values
-  computedCardHeight: number;
-  computedActiveItemIndex: number;
-  computedSlideShowType: string;
-  computedMediaAlign: string;
-  newContentDetailsHeight: number;
- 
-  // Memoized configuration objects
-  memoizedButtonTexts: ButtonTexts;
-  memoizedClassNames: Record<string, string>;
-  memoizedFontSizes: Record<string, string>;
-  memoizedMediaSettings: Record<string, any>;
-  memoizedSemanticTags: Record<string, string>;
- 
-  // Stable props from timeline
-  mode?: TimelineProps['mode'];
-  cardHeight?: number;
-  flipLayout?: boolean;
-  items?: TimelineProps['items'];
-  fontSizes?: TimelineProps['fontSizes'];
-  textOverlay?: boolean;
-  mediaSettings?: TimelineProps['mediaSettings'];
-  responsiveBreakPoint?: number;
-  enableBreakPoint?: boolean;
-  slideItemDuration?: number;
-  slideShowType?: string;
-  cardPositionHorizontal?: TimelineProps['cardPositionHorizontal'];
-  disableNavOnKey?: boolean;
-  itemWidth?: number;
-  lineWidth?: number;
-  scrollable?: boolean | { scrollbar: boolean };
-  onScrollEnd?: () => void;
-  toolbarPosition?: 'top' | 'bottom';
-  disableToolbar?: boolean;
-  cardWidth?: number;
-  borderLessCards?: boolean;
-  disableAutoScrollOnClick?: boolean;
-  classNames?: Record<string, string>;
-  showProgressOnSlideshow?: boolean;
-  showOverallSlideshowProgress?: boolean;
-  disableInteraction?: boolean;
-  highlightCardsOnHover?: boolean;
-  disableClickOnCircle?: boolean;
-  disableTimelinePoint?: boolean;
-  enableQuickJump?: boolean;
-  enableLayoutSwitch?: boolean;
-  cardLess?: boolean;
-  useReadMore?: boolean;
-}
- 
-export const StableContext = createContext<StableContextProps>({
-  staticDefaults: {
-    borderLessCards: false,
-    cardLess: false,
-    disableTimelinePoint: false,
-    disableToolbar: false,
-    enableBreakPoint: true,
-    enableDarkToggle: false,
-    enableLayoutSwitch: true,
-    enableQuickJump: true,
-    focusActiveItemOnLoad: false,
-    highlightCardsOnHover: false,
-    isChild: false,
-    lineWidth: 3,
-    mediaHeight: 200,
-    nestedCardHeight: 150,
-    noUniqueId: false,
-    parseDetailsAsHTML: false,
-    scrollable: { scrollbar: false },
-    showProgressOnSlideshow: true,
-    showOverallSlideshowProgress: true,
-    timelinePointDimension: 16,
-    timelinePointShape: 'circle',
-    titleDateFormat: 'MMM DD, YYYY',
-    toolbarPosition: 'top',
-    uniqueId: 'react-chrono',
-    useReadMore: true,
-  },
-  computedCardHeight: 200,
-  computedActiveItemIndex: 0,
-  computedSlideShowType: 'reveal',
-  computedMediaAlign: 'center',
-  newContentDetailsHeight: 150,
-  memoizedButtonTexts: {
-    first: 'First',
-    last: 'Last',
-    play: 'Play',
-    stop: 'Stop',
-    previous: 'Previous',
-    next: 'Next',
-    dark: 'Dark',
-    light: 'Light',
-    timelinePoint: 'Timeline Point',
-    searchPlaceholder: 'Search...',
-    searchAriaLabel: 'Search timeline',
-    clearSearch: 'Clear search',
-    nextMatch: 'Next match',
-    previousMatch: 'Previous match',
-  },
-  memoizedClassNames: {},
-  memoizedFontSizes: {},
-  memoizedMediaSettings: {},
-  memoizedSemanticTags: {},
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/contexts/hooks.tsx.html b/coverage/components/contexts/hooks.tsx.html deleted file mode 100644 index 17e4a2c72..000000000 --- a/coverage/components/contexts/hooks.tsx.html +++ /dev/null @@ -1,640 +0,0 @@ - - - - - - Code coverage report for components/contexts/hooks.tsx - - - - - - - - - -
-
-

All files / components/contexts hooks.tsx

-
- -
- 86.36% - Statements - 114/132 -
- - -
- 29.41% - Branches - 5/17 -
- - -
- 71.42% - Functions - 5/7 -
- - -
- 86.36% - Lines - 114/132 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186  -  -  -  -1x -1x -1x -  -  -1x -1x -  -  -  -  -  -  -  -1x -59x -59x -  -  -  -  -1x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -59x -  -  -  -59x -59x -59x -59x -  -  -  -  -59x -59x -59x -  -  -  -  -  -1x -58x -  -  -  -58x -58x -58x -58x -58x -58x -58x -  -  -  -  -  -  -  -  -  -  -  -1x -51x -51x -  -51x -51x -51x -51x -51x -  -  -  -  -  -1x - 
/**
- * Combined hooks for accessing both stable and dynamic contexts
- * This provides a convenient API while maintaining the optimization benefits
- */
-import { useContext } from 'react';
-import { StableContext, StableContextProps } from './StableContext';
-import { DynamicContext, DynamicContextProps } from './DynamicContext';
- 
-// Import the legacy context from the new file to avoid circular dependency
-import { LegacyGlobalContext } from './legacy-types';
-import { getDefaultButtonTexts, getDefaultClassNames } from '../../utils';
- 
-// Combined context type for compatibility
-export type CombinedContextProps = StableContextProps & DynamicContextProps;
- 
-/**
- * Hook to access legacy global context for fallback scenarios
- */
-const useLegacyGlobalContext = () => {
-  return useContext(LegacyGlobalContext);
-};
- 
-/**
- * Convert legacy context to stable context props
- */
-const convertLegacyToStable = (legacyContext: any): StableContextProps => {
-  return {
-    staticDefaults: {
-      borderLessCards: legacyContext?.borderLessCards ?? false,
-      cardLess: legacyContext?.cardLess ?? false,
-      disableTimelinePoint: legacyContext?.disableTimelinePoint ?? false,
-      disableToolbar: legacyContext?.disableToolbar ?? false,
-      enableBreakPoint: legacyContext?.enableBreakPoint ?? true,
-      enableDarkToggle: legacyContext?.enableDarkToggle ?? false,
-      enableLayoutSwitch: legacyContext?.enableLayoutSwitch ?? true,
-      enableQuickJump: legacyContext?.enableQuickJump ?? true,
-      focusActiveItemOnLoad: legacyContext?.focusActiveItemOnLoad ?? false,
-      highlightCardsOnHover: legacyContext?.highlightCardsOnHover ?? false,
-      isChild: legacyContext?.isChild ?? false,
-      lineWidth: legacyContext?.lineWidth ?? 3,
-      mediaHeight: legacyContext?.mediaHeight ?? 200,
-      nestedCardHeight: legacyContext?.nestedCardHeight ?? 150,
-      noUniqueId: legacyContext?.noUniqueId ?? false,
-      parseDetailsAsHTML: legacyContext?.parseDetailsAsHTML ?? false,
-      scrollable: legacyContext?.scrollable ?? { scrollbar: false },
-      timelinePointDimension: legacyContext?.timelinePointDimension ?? 16,
-      timelinePointShape: legacyContext?.timelinePointShape ?? 'circle',
-      titleDateFormat: legacyContext?.titleDateFormat ?? 'MMM DD, YYYY',
-      toolbarPosition: legacyContext?.toolbarPosition ?? 'top',
-      uniqueId: legacyContext?.uniqueId ?? 'react-chrono',
-      useReadMore: legacyContext?.useReadMore ?? true,
-    },
-    computedCardHeight: legacyContext?.cardHeight ?? 200,
-    computedActiveItemIndex: legacyContext?.activeItemIndex ?? 0,
-    computedSlideShowType: legacyContext?.slideShowType ?? 'reveal',
-    computedMediaAlign: legacyContext?.mediaAlign ?? 'center',
-    newContentDetailsHeight: legacyContext?.contentDetailsHeight ?? 150,
-    memoizedButtonTexts: {
-      ...getDefaultButtonTexts(),
-      ...legacyContext?.buttonTexts,
-    },
-    memoizedClassNames: {
-      ...getDefaultClassNames(),
-      ...legacyContext?.classNames,
-    },
-    memoizedFontSizes: legacyContext?.fontSizes ?? {},
-    memoizedMediaSettings: legacyContext?.mediaSettings ?? {},
-    memoizedSemanticTags: legacyContext?.semanticTags ?? {},
-    mode: legacyContext?.mode,
-    cardHeight: legacyContext?.cardHeight,
-    flipLayout: legacyContext?.flipLayout,
-    items: legacyContext?.items,
-    fontSizes: legacyContext?.fontSizes,
-    textOverlay: legacyContext?.textOverlay,
-    mediaSettings: legacyContext?.mediaSettings,
-    responsiveBreakPoint: legacyContext?.responsiveBreakPoint,
-    enableBreakPoint: legacyContext?.enableBreakPoint,
-    slideItemDuration: legacyContext?.slideItemDuration,
-    slideShowType: legacyContext?.slideShowType,
-    cardPositionHorizontal: legacyContext?.cardPositionHorizontal,
-    disableNavOnKey: legacyContext?.disableNavOnKey,
-    itemWidth: legacyContext?.itemWidth,
-    lineWidth: legacyContext?.lineWidth,
-    scrollable: legacyContext?.scrollable,
-    onScrollEnd: legacyContext?.onScrollEnd,
-    toolbarPosition: legacyContext?.toolbarPosition,
-    disableToolbar: legacyContext?.disableToolbar,
-    cardWidth: legacyContext?.cardWidth,
-    borderLessCards: legacyContext?.borderLessCards,
-    disableAutoScrollOnClick: legacyContext?.disableAutoScrollOnClick,
-    classNames: legacyContext?.classNames,
-    showProgressOnSlideshow: legacyContext?.showProgressOnSlideshow,
-    showOverallSlideshowProgress: legacyContext?.showOverallSlideshowProgress,
-    disableInteraction: legacyContext?.disableInteraction,
-    highlightCardsOnHover: legacyContext?.highlightCardsOnHover,
-    disableClickOnCircle: legacyContext?.disableClickOnCircle,
-    disableTimelinePoint: legacyContext?.disableTimelinePoint,
-    enableQuickJump: legacyContext?.enableQuickJump,
-    enableLayoutSwitch: legacyContext?.enableLayoutSwitch,
-    cardLess: legacyContext?.cardLess,
-    useReadMore: legacyContext?.useReadMore,
-  };
-};
- 
-/**
- * Convert legacy context to dynamic context props
- */
-const convertLegacyToDynamic = (legacyContext: any): DynamicContextProps => {
-  return {
-    isDarkMode: legacyContext?.darkMode ?? false,
-    isMobile: legacyContext?.isMobile ?? false,
-    horizontalAll: legacyContext?.showAllCardsHorizontal ?? false,
-    textContentDensity: legacyContext?.textDensity ?? 'HIGH',
-    memoizedTheme: legacyContext?.theme ?? {},
-    toggleDarkMode: legacyContext?.toggleDarkMode ?? (() => {}),
-    updateTextContentDensity:
-      legacyContext?.updateTextContentDensity ?? (() => {}),
-    updateHorizontalAllCards:
-      legacyContext?.updateHorizontalAllCards ?? (() => {}),
-  };
-};
- 
-/**
- * Hook to access stable configuration values
- * Use this when components only need configuration data
- */
-export const useStableContext = (): StableContextProps => {
-  const stableContext = useContext(StableContext);
- 
-  // Check if we have properly initialized optimized context
-  // The uniqueId being 'react-chrono' indicates default/uninitialized context
-  if (
-    stableContext &&
-    stableContext.staticDefaults.uniqueId !== 'react-chrono'
-  ) {
-    return stableContext;
-  }
- 
-  // Fallback to legacy context for tests and backward compatibility
-  const legacyContext = useLegacyGlobalContext();
-  return convertLegacyToStable(legacyContext);
-};
- 
-/**
- * Hook to access dynamic state values
- * Use this when components only need dynamic state
- */
-export const useDynamicContext = (): DynamicContextProps => {
-  const dynamicContext = useContext(DynamicContext);
- 
-  // Check if we have properly initialized optimized context
-  // If there's no toggleDarkMode function, it's likely uninitialized
-  if (
-    dynamicContext &&
-    dynamicContext.toggleDarkMode &&
-    typeof dynamicContext.toggleDarkMode === 'function'
-  ) {
-    return dynamicContext;
-  }
- 
-  // Fallback to legacy context for tests and backward compatibility
-  const legacyContext = useLegacyGlobalContext();
-  return convertLegacyToDynamic(legacyContext);
-};
- 
-/**
- * Hook to access both stable and dynamic contexts
- * Use this for components that need both types of data
- * This maintains backward compatibility with the old GlobalContext
- */
-export const useGlobalContext = (): CombinedContextProps => {
-  const stableContext = useContext(StableContext);
-  const dynamicContext = useContext(DynamicContext);
- 
-  return {
-    ...stableContext,
-    ...dynamicContext,
-  };
-};
- 
-/**
- * Legacy hook for backward compatibility
- * @deprecated Use useGlobalContext, useStableContext, or useDynamicContext instead
- */
-export const useTimelineContext = (): CombinedContextProps => useGlobalContext();
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/contexts/index.html b/coverage/components/contexts/index.html deleted file mode 100644 index 02bc18a34..000000000 --- a/coverage/components/contexts/index.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - Code coverage report for components/contexts - - - - - - - - - -
-
-

All files components/contexts

-
- -
- 96.38% - Statements - 507/526 -
- - -
- 70.96% - Branches - 44/62 -
- - -
- 61.53% - Functions - 8/13 -
- - -
- 96.38% - Lines - 507/526 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
DynamicContext.tsx -
-
100%33/33100%0/00%0/3100%33/33
OptimizedContextProvider.tsx -
-
99.66%299/30086.66%39/45100%3/399.66%299/300
StableContext.tsx -
-
100%55/55100%0/0100%0/0100%55/55
hooks.tsx -
-
86.36%114/13229.41%5/1771.42%5/786.36%114/132
index.tsx -
-
100%4/4100%0/0100%0/0100%4/4
legacy-types.tsx -
-
100%2/2100%0/0100%0/0100%2/2
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/contexts/index.tsx.html b/coverage/components/contexts/index.tsx.html deleted file mode 100644 index 1ec03f057..000000000 --- a/coverage/components/contexts/index.tsx.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for components/contexts/index.tsx - - - - - - - - - -
-
-

All files / components/contexts index.tsx

-
- -
- 100% - Statements - 4/4 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 4/4 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  - 
/**
- * Context index file - exports all context-related functionality
- */
-export { StableContext, type StableContextProps } from './StableContext';
-export { DynamicContext, type DynamicContextProps } from './DynamicContext';
-export {
-  useStableContext,
-  useDynamicContext,
-  useGlobalContext,
-  useTimelineContext,
-  type CombinedContextProps,
-} from './hooks';
- 
-// Import and re-export to work around module resolution issue
-import {
-  OptimizedContextProvider,
-  type ContextProps,
-} from './OptimizedContextProvider';
-export { OptimizedContextProvider };
-export type { ContextProps };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/contexts/legacy-types.tsx.html b/coverage/components/contexts/legacy-types.tsx.html deleted file mode 100644 index 7804d1958..000000000 --- a/coverage/components/contexts/legacy-types.tsx.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - Code coverage report for components/contexts/legacy-types.tsx - - - - - - - - - -
-
-

All files / components/contexts legacy-types.tsx

-
- -
- 100% - Statements - 2/2 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 2/2 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
/**
- * Legacy context types and default functions
- * This file contains only type definitions and default functions to avoid circular dependencies
- */
-import { createContext } from 'react';
-import {
-  TimelineProps as PropsModel,
-  TextDensity,
-} from '@models/TimelineModel';
- 
-export type LegacyContextProps = PropsModel & {
-  isMobile?: boolean;
-  toggleDarkMode?: () => void;
-  updateHorizontalAllCards?: (state: boolean) => void;
-  updateTextContentDensity?: (value: TextDensity) => void;
-};
- 
-export interface ButtonTexts {
-  first?: string;
-  last?: string;
-  play?: string;
-  stop?: string;
-  previous?: string;
-  next?: string;
-  dark?: string;
-  light?: string;
-  timelinePoint?: string;
-  searchPlaceholder?: string;
-  searchAriaLabel?: string;
-  clearSearch?: string;
-  nextMatch?: string;
-  previousMatch?: string;
-}
- 
-// Legacy context for backward compatibility - exported without circular dependency
-export const LegacyGlobalContext = createContext<LegacyContextProps>({});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/__tests__/index.html b/coverage/components/effects/__tests__/index.html deleted file mode 100644 index 48fe4feb5..000000000 --- a/coverage/components/effects/__tests__/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__ - - - - - - - - - -
-
-

All files components/effects/__tests__

-
- -
- 100% - Statements - 545/545 -
- - -
- 100% - Branches - 99/99 -
- - -
- 100% - Functions - 6/6 -
- - -
- 100% - Lines - 545/545 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useClickOutside.test.tsx -
-
100%60/60100%14/14100%2/2100%60/60
useMatchMedia.test.tsx -
-
100%126/126100%24/24100%1/1100%126/126
useNewScrollPosition.test.ts -
-
100%293/293100%51/51100%3/3100%293/293
useSlideshow.test.ts -
-
100%66/66100%10/10100%0/0100%66/66
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/__tests__/useClickOutside.test.tsx.html b/coverage/components/effects/__tests__/useClickOutside.test.tsx.html deleted file mode 100644 index e6dccb9fa..000000000 --- a/coverage/components/effects/__tests__/useClickOutside.test.tsx.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useClickOutside.test.tsx - - - - - - - - - -
-
-

All files / components/effects/__tests__ useClickOutside.test.tsx

-
- -
- 100% - Statements - 60/60 -
- - -
- 100% - Branches - 14/14 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 60/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -841x -1x -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -5x -5x -5x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -1x - 
import { renderHook } from '@testing-library/react';
-import { beforeEach, describe, expect, it, vi } from 'vitest';
- 
-import useCloseClickOutside from '../useCloseClickOutside';
-import useOutsideClick from '../../../hooks/useOutsideClick';
-import useEscapeKey from '../../../hooks/useEscapeKey';
- 
-// Mock the imported hooks
-vi.mock('../../../hooks/useOutsideClick');
-vi.mock('../../../hooks/useEscapeKey');
- 
-describe('useCloseClickOutside', () => {
-  beforeEach(() => {
-    vi.clearAllMocks();
-    vi.mocked(useOutsideClick).mockImplementation(() => {});
-    vi.mocked(useEscapeKey).mockImplementation(() => {});
-  });
- 
-  it('initializes both hooks with correct parameters', () => {
-    const callback = vi.fn();
-    const ref = { current: document.createElement('div') };
- 
-    renderHook(() => useCloseClickOutside(ref, callback));
- 
-    expect(useOutsideClick).toHaveBeenCalledWith(ref, callback);
-    expect(useEscapeKey).toHaveBeenCalledWith(callback);
-  });
- 
-  it('passes updated callback to both hooks when callback changes', () => {
-    const callback1 = vi.fn();
-    const callback2 = vi.fn();
-    const ref = { current: document.createElement('div') };
- 
-    const { rerender } = renderHook(({ cb }) => useCloseClickOutside(ref, cb), {
-      initialProps: { cb: callback1 },
-    });
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref, callback1);
-    expect(useEscapeKey).toHaveBeenLastCalledWith(callback1);
- 
-    rerender({ cb: callback2 });
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref, callback2);
-    expect(useEscapeKey).toHaveBeenLastCalledWith(callback2);
-  });
- 
-  it('passes updated ref to useOutsideClick when ref changes', () => {
-    const callback = vi.fn();
-    const ref1 = { current: document.createElement('div') };
-    const ref2 = { current: document.createElement('div') };
- 
-    const { rerender } = renderHook(
-      ({ r }) => useCloseClickOutside(r, callback),
-      { initialProps: { r: ref1 } },
-    );
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref1, callback);
- 
-    rerender({ r: ref2 });
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref2, callback);
-  });
- 
-  it('handles null ref correctly', () => {
-    const callback = vi.fn();
-    const nullRef = { current: null };
- 
-    renderHook(() => useCloseClickOutside(nullRef, callback));
- 
-    expect(useOutsideClick).toHaveBeenCalledWith(nullRef, callback);
-    expect(useEscapeKey).toHaveBeenCalledWith(callback);
-  });
- 
-  it('handles undefined ref correctly', () => {
-    const callback = vi.fn();
-    const undefinedRef = { current: undefined };
- 
-    renderHook(() => useCloseClickOutside(undefinedRef, callback));
- 
-    expect(useOutsideClick).toHaveBeenCalledWith(undefinedRef, callback);
-    expect(useEscapeKey).toHaveBeenCalledWith(callback);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/__tests__/useMatchMedia.test.tsx.html b/coverage/components/effects/__tests__/useMatchMedia.test.tsx.html deleted file mode 100644 index d134203a7..000000000 --- a/coverage/components/effects/__tests__/useMatchMedia.test.tsx.html +++ /dev/null @@ -1,595 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useMatchMedia.test.tsx - - - - - - - - - -
-
-

All files / components/effects/__tests__ useMatchMedia.test.tsx

-
- -
- 100% - Statements - 126/126 -
- - -
- 100% - Branches - 24/24 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 126/126 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -1711x -1x -1x -  -  -19x -19x -19x -19x -  -  -  -  -  -  -19x -19x -19x -19x -  -19x -  -1x -1x -1x -1x -  -1x -9x -9x -  -9x -8x -8x -8x -9x -  -9x -1x -  -1x -9x -9x -9x -9x -9x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -  -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x - 
import { render, act } from '@testing-library/react';
-import { useMatchMedia } from '../useMatchMedia';
-import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
- 
-// Test component with updated API
-function TestComponent({
-  query,
-  options = {},
-}: {
-  query: string;
-  options?: {
-    enabled?: boolean;
-    onMatch?: () => void;
-    debounceDelay?: number;
-  };
-}) {
-  const matches = useMatchMedia(query, options);
-  return (
-    <div data-testid="result">{matches ? 'Matches' : 'Does not match'}</div>
-  );
-}
- 
-describe('useMatchMedia', () => {
-  let matchMediaMock: any;
-  let addEventListenerSpy: any;
-  let removeEventListenerSpy: any;
- 
-  beforeEach(() => {
-    addEventListenerSpy = vi.fn();
-    removeEventListenerSpy = vi.fn();
- 
-    matchMediaMock = vi.fn().mockImplementation((query) => ({
-      matches: query === '(min-width: 800px)',
-      addEventListener: addEventListenerSpy,
-      removeEventListener: removeEventListenerSpy,
-    }));
- 
-    window.matchMedia = matchMediaMock;
-  });
- 
-  afterEach(() => {
-    vi.clearAllMocks();
-    vi.useRealTimers();
-    matchMediaMock.mockClear();
-    addEventListenerSpy.mockClear();
-    removeEventListenerSpy.mockClear();
-  });
- 
-  it('returns true if the query matches', () => {
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 800px)" />,
-    );
-    expect(getByTestId('result')).toHaveTextContent('Matches');
-  });
- 
-  it('returns false if the query does not match', () => {
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 1000px)" />,
-    );
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-  });
- 
-  it('returns false if the hook is disabled', () => {
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 800px)" options={{ enabled: false }} />,
-    );
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-  });
- 
-  it('calls onMatch callback when query matches', () => {
-    const onMatch = vi.fn();
-    render(<TestComponent query="(min-width: 800px)" options={{ onMatch }} />);
-    expect(onMatch).toHaveBeenCalledTimes(1);
-  });
- 
-  it('handles media query changes', () => {
-    let changeCallback: (event: { matches: boolean }) => void;
- 
-    addEventListenerSpy.mockImplementation((event, cb) => {
-      changeCallback = cb;
-    });
- 
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 800px)" />,
-    );
- 
-    act(() => {
-      changeCallback({ matches: false });
-    });
- 
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-  });
- 
-  it('handles resize events with debounce', async () => {
-    vi.useFakeTimers();
- 
-    const { getByTestId } = render(
-      <TestComponent
-        query="(min-width: 800px)"
-        options={{ debounceDelay: 100 }}
-      />,
-    );
- 
-    act(() => {
-      window.dispatchEvent(new Event('resize'));
-    });
- 
-    act(() => {
-      vi.advanceTimersByTime(100);
-    });
- 
-    expect(getByTestId('result')).toHaveTextContent('Matches');
- 
-    vi.useRealTimers();
-  });
- 
-  it('handles errors in matchMedia gracefully', () => {
-    const originalMatchMedia = window.matchMedia;
-    const consoleErrorSpy = vi
-      .spyOn(console, 'error')
-      .mockImplementation(() => {});
- 
-    window.matchMedia = vi.fn().mockImplementation(() => {
-      throw new Error('matchMedia error');
-    });
- 
-    const { getByTestId, unmount } = render(
-      <TestComponent query="(min-width: 800px)" />,
-    );
- 
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-    expect(consoleErrorSpy).toHaveBeenCalled();
- 
-    unmount();
-    consoleErrorSpy.mockRestore();
-    window.matchMedia = originalMatchMedia;
-  });
- 
-  it('respects maxWait option for resize debounce', async () => {
-    vi.useFakeTimers();
- 
-    const { getByTestId } = render(
-      <TestComponent
-        query="(min-width: 800px)"
-        options={{ debounceDelay: 2000 }} // Long delay to test maxWait
-      />,
-    );
- 
-    act(() => {
-      window.dispatchEvent(new Event('resize'));
-    });
- 
-    // maxWait is 1000ms, so this should trigger an update
-    act(() => {
-      vi.advanceTimersByTime(1000);
-    });
- 
-    expect(getByTestId('result')).toHaveTextContent('Matches');
- 
-    vi.useRealTimers();
-  });
- 
-  it('handles cleanup on query change', () => {
-    const { rerender } = render(<TestComponent query="(min-width: 800px)" />);
- 
-    rerender(<TestComponent query="(min-width: 1000px)" />);
- 
-    expect(removeEventListenerSpy).toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/__tests__/useNewScrollPosition.test.ts.html b/coverage/components/effects/__tests__/useNewScrollPosition.test.ts.html deleted file mode 100644 index a459e38cc..000000000 --- a/coverage/components/effects/__tests__/useNewScrollPosition.test.ts.html +++ /dev/null @@ -1,1228 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useNewScrollPosition.test.ts - - - - - - - - - -
-
-

All files / components/effects/__tests__ useNewScrollPosition.test.ts

-
- -
- 100% - Statements - 293/293 -
- - -
- 100% - Branches - 51/51 -
- - -
- 100% - Functions - 3/3 -
- - -
- 100% - Lines - 293/293 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -3821x -1x -1x -  -  -  -  -1x -13x -13x -13x -13x -13x -13x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -3x -1x -1x -1x -1x -  -1x -  -  -1x -1x -  -  -1x -  -  -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -1x -  -  -1x -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it} from 'vitest';
-import useNewScrollPosition from '../useNewScrollPosition';
-import { TimelineMode } from '../../../models/TimelineModel';
-import { Scroll } from '../../../models/TimelineHorizontalModel';
- 
-// Mock HTML element methods
-const createMockElement = (overrides = {}) => ({
-  clientWidth: 800,
-  clientHeight: 600,
-  scrollLeft: 0,
-  scrollTop: 0,
-  ...overrides,
-}) as HTMLElement;
- 
-describe('useNewScrollPosition', () => {
-  describe('Horizontal Mode', () => {
-    it('should initialize with offset 0', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      expect(result.current[0]).toBe(0);
-      expect(typeof result.current[1]).toBe('function');
-    });
- 
-    it('should compute horizontal offset when point is not visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [newOffset, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 1000, // Far to the right, not visible
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      // Should set new offset to point offset - item width
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(800); // 1000 - 200
-    });
- 
-    it('should compute horizontal offset when point is partially visible on the left', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 300,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 250, // Partially visible on the left
-        pointWidth: 100,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // No offset since leftGap is negative
-    });
- 
-    it('should compute horizontal offset when point is partially visible on the right', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 850, // Partially visible on the right
-        pointWidth: 100,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(650); // 850 - 200
-    });
- 
-    it('should not update offset when point is fully visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 400, // Fully visible
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // Should remain 0, no update needed
-    });
- 
-    it('should handle edge case when left gap is within item width', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 300,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 450, // Left gap = 150, which is < itemWidth (200)
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(250); // 450 - 200
-    });
- 
-    it('should handle edge case when right gap is within item width', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 750, // Right gap = 150, which is < itemWidth (200)
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(550); // 750 - 200
-    });
-  });
- 
-  describe('Vertical Mode', () => {
-    it('should compute vertical offset when content is not visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 100,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 1000, // Far down, not visible
-        contentHeight: 200,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(800); // 1000 - 200 (nOffset)
-    });
- 
-    it('should compute vertical offset when content is partially visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 300,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 850, // Partially visible
-        contentHeight: 200,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(750); // 850 - 200 + 100 (half height)
-    });
- 
-    it('should handle vertical content that extends beyond visible area', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 100,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 800,
-        contentHeight: 300,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(500); // 800 - 300 (since nOffset + contentHeight >= contrBottom)
-    });
- 
-    it('should not update offset when content is fully visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 200,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 400, // Fully visible
-        contentHeight: 150,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // Should remain 0, no update needed
-    });
-  });
- 
-  describe('Vertical Alternating Mode', () => {
-    it('should work the same as vertical mode', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL_ALTERNATING')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 100,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 1000,
-        contentHeight: 200,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(800); // Same calculation as vertical mode
-    });
-  });
- 
-  describe('Edge Cases', () => {
-    it('should handle missing itemWidth for horizontal mode', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL') // No itemWidth provided
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement();
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 1000,
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // Should not update without itemWidth
-    });
- 
-    it('should handle undefined scroll values', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement();
-      
-      const scroll: Partial<Scroll> = {}; // Empty scroll object
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(-200); // pointOffset = 0, so 0 - 200
-    });
- 
-    it('should memoize computeNewOffset function based on dependencies', () => {
-      const { result, rerender } = renderHook(
-        ({ mode, itemWidth }: { mode: TimelineMode; itemWidth?: number }) =>
-          useNewScrollPosition(mode, itemWidth),
-        {
-          initialProps: { mode: 'HORIZONTAL' as TimelineMode, itemWidth: 200 },
-        }
-      );
-      
-      const firstComputeFunction = result.current[1];
-      
-      // Re-render with same props
-      rerender({ mode: 'HORIZONTAL', itemWidth: 200 });
-      const secondComputeFunction = result.current[1];
-      
-      // Functions should be the same (memoized)
-      expect(firstComputeFunction).toBe(secondComputeFunction);
-      
-      // Re-render with different itemWidth
-      rerender({ mode: 'HORIZONTAL', itemWidth: 300 });
-      const thirdComputeFunction = result.current[1];
-      
-      // Function should be different now
-      expect(firstComputeFunction).not.toBe(thirdComputeFunction);
-    });
- 
-    it('should handle mode changes properly', () => {
-      const { result, rerender } = renderHook(
-        ({ mode }: { mode: TimelineMode }) => useNewScrollPosition(mode, 200),
-        {
-          initialProps: { mode: 'HORIZONTAL' as TimelineMode },
-        }
-      );
-      
-      const firstComputeFunction = result.current[1];
-      
-      // Change mode
-      rerender({ mode: 'VERTICAL' });
-      const secondComputeFunction = result.current[1];
-      
-      // Function should be different due to mode change
-      expect(firstComputeFunction).not.toBe(secondComputeFunction);
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/__tests__/useSlideshow.test.ts.html b/coverage/components/effects/__tests__/useSlideshow.test.ts.html deleted file mode 100644 index 325194d36..000000000 --- a/coverage/components/effects/__tests__/useSlideshow.test.ts.html +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useSlideshow.test.ts - - - - - - - - - -
-
-

All files / components/effects/__tests__ useSlideshow.test.ts

-
- -
- 100% - Statements - 66/66 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 66/66 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80  -1x -1x -1x -  -1x -1x -  -1x -  -1x -3x -3x -3x -  -1x -3x -3x -3x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -2x -2x -2x -2x -2x -2x -2x -2x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x - 
// Test setup
-import { act, renderHook } from '@testing-library/react';
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
-import { useSlideshow } from '../useSlideshow';
- 
-const slideItemDuration = 5000;
-const onElapsed = vi.fn();
- 
-let container = null;
- 
-beforeEach(() => {
-  container = document.createElement('div');
-  document.body.appendChild(container);
-});
- 
-afterEach(() => {
-  document.body.removeChild(container);
-  vi.clearAllMocks();
-});
- 
-describe('useSlideshow', () => {
-  it('should initialize properly', () => {
-    const { result } = renderHook(() =>
-      useSlideshow(
-        { current: container },
-        true,
-        true,
-        slideItemDuration,
-        '1',
-        onElapsed,
-      ),
-    );
- 
-    expect(result.current.paused).toBe(false);
-    expect(result.current.remainInterval).toBe(0);
-    expect(result.current.startWidth).toBe(0);
-  });
- 
-  it('should set up timer correctly', async () => {
-    const { result } = renderHook(() =>
-      useSlideshow(
-        { current: container },
-        true,
-        true,
-        slideItemDuration,
-        '1',
-        onElapsed,
-      ),
-    );
- 
-    expect(result.current.tryPause).toBeDefined();
-    expect(result.current.tryResume).toBeDefined();
-    expect(result.current.setStartWidth).toBeDefined();
-    expect(result.current.setupTimer).toBeDefined();
-    expect(result.current.startWidth).toBe(0);
-    expect(result.current.paused).toBe(false);
-  });
- 
-  it('should pause slideshow', () => {
-    const { result } = renderHook(() =>
-      useSlideshow(
-        { current: container },
-        true,
-        true,
-        slideItemDuration,
-        '1',
-        onElapsed,
-      ),
-    );
- 
-    expect(result.current.paused).toBe(false);
- 
-    act(() => {
-      result.current.tryPause();
-    });
- 
-    expect(result.current.paused).toBe(true);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/index.html b/coverage/components/effects/index.html deleted file mode 100644 index c7992f937..000000000 --- a/coverage/components/effects/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/effects - - - - - - - - - -
-
-

All files components/effects

-
- -
- 80.07% - Statements - 213/266 -
- - -
- 85.96% - Branches - 49/57 -
- - -
- 100% - Functions - 7/7 -
- - -
- 80.07% - Lines - 213/266 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useCloseClickOutside.ts -
-
100%9/9100%1/1100%1/1100%9/9
useMatchMedia.ts -
-
96.61%57/5982.35%14/17100%2/296.61%57/59
useNewScrollPosition.ts -
-
100%84/8496.29%26/27100%3/3100%84/84
useSlideshow.ts -
-
55.26%63/11466.66%8/12100%1/155.26%63/114
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/useCloseClickOutside.ts.html b/coverage/components/effects/useCloseClickOutside.ts.html deleted file mode 100644 index 4344ea6f0..000000000 --- a/coverage/components/effects/useCloseClickOutside.ts.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - Code coverage report for components/effects/useCloseClickOutside.ts - - - - - - - - - -
-
-

All files / components/effects useCloseClickOutside.ts

-
- -
- 100% - Statements - 9/9 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 9/9 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17  -1x -1x -  -  -  -  -  -  -42x -42x -42x -42x -42x -42x -42x - 
import { RefObject } from 'react';
-import useOutsideClick from '../../hooks/useOutsideClick';
-import useEscapeKey from '../../hooks/useEscapeKey';
- 
-/**
- * Custom hook that handles click outside and escape key events
- * @param el - Reference to the DOM element to watch for outside clicks
- * @param callback - Function to call when a click outside or escape key is detected
- */
-export default function useCloseClickOutside(
-  el: RefObject<HTMLElement | null>,
-  callback: () => void,
-) {
-  useOutsideClick(el, callback);
-  useEscapeKey(callback);
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/useMatchMedia.ts.html b/coverage/components/effects/useMatchMedia.ts.html deleted file mode 100644 index 63a215adc..000000000 --- a/coverage/components/effects/useMatchMedia.ts.html +++ /dev/null @@ -1,421 +0,0 @@ - - - - - - Code coverage report for components/effects/useMatchMedia.ts - - - - - - - - - -
-
-

All files / components/effects useMatchMedia.ts

-
- -
- 96.61% - Statements - 57/59 -
- - -
- 82.35% - Branches - 14/17 -
- - -
- 100% - Functions - 2/2 -
- - -
- 96.61% - Lines - 57/59 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -1131x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -23x -23x -23x -23x -23x -23x -  -  -23x -23x -9x -9x -9x -23x -23x -  -23x -23x -1x -  -1x -1x -1x -23x -23x -23x -  -  -23x -14x -1x -1x -  -13x -  -  -14x -  -  -  -13x -13x -  -14x -5x -5x -  -  -8x -  -  -8x -  -  -8x -8x -8x -8x -8x -8x -8x -8x -23x -  -  -23x -23x -  -23x -21x -1x -1x -23x -  -23x -23x - 
import { useCallback, useEffect, useRef, useState } from 'react';
-import { useDebouncedCallback } from 'use-debounce';
-import {
-  createMediaQuery,
-  addMediaListeners,
-  removeMediaListeners,
-} from '../../utils/mediaQueryUtils';
- 
-/**
- * Configuration options for the useMatchMedia hook
- */
-interface MatchMediaOptions {
-  /** Callback function to execute when media query matches */
-  onMatch?: () => void;
-  /** Whether the hook is enabled */
-  enabled?: boolean;
-  /** Debounce delay in milliseconds */
-  debounceDelay?: number;
-}
- 
-/**
- * Custom hook that tracks if a media query matches and executes a callback on matches
- *
- * @param query - The media query string to match against
- * @param options - Configuration options
- * @returns Boolean indicating if the media query currently matches
- *
- * @example
- * ```tsx
- * const isMobile = useMatchMedia('(max-width: 768px)', {
- *   onMatch: () => console.log('Mobile view detected'),
- *   debounceDelay: 200
- * });
- * ```
- */
-export const useMatchMedia = (
-  query: string,
-  { onMatch, enabled = true, debounceDelay = 100 }: MatchMediaOptions = {},
-): boolean => {
-  const [matches, setMatches] = useState<boolean>(false);
-  const mediaQuery = useRef<MediaQueryList | null>(null);
-  const isCleanedUp = useRef<boolean>(false);
- 
-  // Stable callback references to prevent unnecessary effect re-runs
-  const handleMediaChange = useCallback(
-    (event: MediaQueryListEvent | MediaQueryList) => {
-      if (isCleanedUp.current) return;
-      setMatches(event.matches);
-    },
-    [],
-  );
- 
-  const handleResize = useDebouncedCallback(
-    () => {
-      if (!mediaQuery.current || isCleanedUp.current) return;
- 
-      const currentMatches = mediaQuery.current.matches;
-      setMatches(currentMatches);
-    },
-    debounceDelay,
-    { maxWait: 1000 },
-  );
- 
-  // Setup media query listener
-  useEffect(() => {
-    if (!enabled || typeof window === 'undefined') {
-      return;
-    }
- 
-    isCleanedUp.current = false;
- 
-    // Cleanup previous mediaQuery if it exists
-    if (mediaQuery.current) {
-      removeMediaListeners(mediaQuery.current, handleMediaChange, handleResize);
-    }
- 
-    mediaQuery.current = createMediaQuery(query);
-    const currentMedia = mediaQuery.current;
- 
-    if (!currentMedia) {
-      return;
-    }
- 
-    // Initial check
-    handleMediaChange(currentMedia);
- 
-    // Add event listeners
-    addMediaListeners(currentMedia, handleMediaChange, handleResize);
- 
-    // Cleanup
-    return () => {
-      isCleanedUp.current = true;
-      if (currentMedia) {
-        removeMediaListeners(currentMedia, handleMediaChange, handleResize);
-      }
-      handleResize.cancel(); // Cancel any pending debounced calls
-      mediaQuery.current = null; // Clear the ref
-    };
-  }, [query, enabled, handleMediaChange, handleResize]); // Removed createMediaQuery dependency to avoid infinite loops
- 
-  // Execute callback when matches changes - use ref to avoid stale closure
-  const onMatchRef = useRef(onMatch);
-  onMatchRef.current = onMatch;
- 
-  useEffect(() => {
-    if (matches && onMatchRef.current) {
-      onMatchRef.current();
-    }
-  }, [matches]);
- 
-  return matches;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/useNewScrollPosition.ts.html b/coverage/components/effects/useNewScrollPosition.ts.html deleted file mode 100644 index 3e20f64d1..000000000 --- a/coverage/components/effects/useNewScrollPosition.ts.html +++ /dev/null @@ -1,412 +0,0 @@ - - - - - - Code coverage report for components/effects/useNewScrollPosition.ts - - - - - - - - - -
-
-

All files / components/effects useNewScrollPosition.ts

-
- -
- 100% - Statements - 84/84 -
- - -
- 96.29% - Branches - 26/27 -
- - -
- 100% - Functions - 3/3 -
- - -
- 100% - Lines - 84/84 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110  -  -1x -  -  -  -  -  -  -  -  -1x -36x -36x -36x -  -36x -  -36x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -7x -6x -  -7x -7x -  -7x -7x -6x -4x -7x -5x -5x -7x -  -36x -5x -5x -5x -5x -5x -5x -5x -5x -  -5x -5x -5x -5x -  -5x -5x -  -5x -1x -5x -3x -3x -5x -  -  -36x -36x -13x -13x -13x -13x -13x -13x -13x -  -13x -7x -7x -7x -7x -7x -7x -7x -7x -13x -5x -5x -5x -5x -5x -5x -5x -5x -13x -36x -36x -  -  -36x -36x -  -1x - 
import { Scroll } from '@models/TimelineHorizontalModel';
-import { TimelineMode } from '@models/TimelineModel';
-import { useMemo, useState } from 'react';
- 
-/**
- * Hook to calculate the new scroll position based on the given mode and item width.
- *
- * @param {TimelineMode} mode - The mode of the timeline (HORIZONTAL, VERTICAL, or VERTICAL_ALTERNATING).
- * @param {number} [itemWidth] - Optional item width for horizontal mode.
- * @returns {[number, (e: HTMLElement, s: Partial<Scroll>) => void]} - The new offset and a function to compute the new offset.
- */
-const useNewScrollPosition = (
-  mode: TimelineMode,
-  itemWidth?: number,
-): [number, (e: HTMLElement, s: Partial<Scroll>) => void] => {
-  // State to hold the new offset value
-  const [newOffset, setNewOffset] = useState(0);
- 
-  const computeHorizontalOffset = (
-    scrollLeft: number,
-    clientWidth: number,
-    pointOffset: number,
-    pointWidth: number,
-    itemWidth: number,
-    setNewOffset: (offset: number) => void,
-  ) => {
-    const contrRight = scrollLeft + clientWidth;
-    const circRight = pointOffset + pointWidth;
- 
-    const isVisible = pointOffset >= scrollLeft && circRight <= contrRight;
-    const isPartiallyVisible =
-      (pointOffset < scrollLeft && circRight > scrollLeft) ||
-      (circRight > contrRight && pointOffset < contrRight);
- 
-    const leftGap = pointOffset - scrollLeft;
-    const rightGap = contrRight - pointOffset;
- 
-    if (
-      !(isVisible || isPartiallyVisible) ||
-      (leftGap <= itemWidth && leftGap >= 0) ||
-      (rightGap <= itemWidth && rightGap >= 0)
-    ) {
-      setNewOffset(pointOffset - itemWidth);
-    }
-  };
- 
-  const computeVerticalOffset = (
-    scrollTop: number,
-    clientHeight: number,
-    contentOffset: number,
-    contentHeight: number,
-    setNewOffset: (offset: number) => void,
-  ) => {
-    const contrBottom = scrollTop + clientHeight;
-    const circBottom = contentOffset + contentHeight;
- 
-    const isVisible = contentOffset >= scrollTop && circBottom <= contrBottom;
-    const isPartiallyVisible =
-      (contentOffset < scrollTop && circBottom > scrollTop) ||
-      (circBottom > contrBottom && contentOffset < contrBottom);
- 
-    const nOffset = contentOffset - contentHeight;
-    const notVisible = !isVisible || isPartiallyVisible;
- 
-    if (notVisible && nOffset + contentHeight < contrBottom) {
-      setNewOffset(nOffset + Math.round(contentHeight / 2));
-    } else if (notVisible) {
-      setNewOffset(nOffset);
-    }
-  };
- 
-  // Memoized function to compute the new offset value
-  const computeNewOffset = useMemo(
-    () => (parent: HTMLElement, scroll: Partial<Scroll>) => {
-      const { clientWidth, scrollLeft, scrollTop, clientHeight } = parent;
-      const {
-        pointOffset = 0,
-        pointWidth = 0,
-        contentHeight = 0,
-        contentOffset = 0,
-      } = scroll;
- 
-      if (mode === 'HORIZONTAL' && itemWidth) {
-        computeHorizontalOffset(
-          scrollLeft,
-          clientWidth,
-          pointOffset,
-          pointWidth,
-          itemWidth,
-          setNewOffset,
-        );
-      } else if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        computeVerticalOffset(
-          scrollTop,
-          clientHeight,
-          contentOffset,
-          contentHeight,
-          setNewOffset,
-        );
-      }
-    },
-    [mode, itemWidth], // Dependencies for useMemo
-  );
- 
-  // Returning the new offset and the function to compute it
-  return [newOffset, computeNewOffset];
-};
- 
-export default useNewScrollPosition;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/effects/useSlideshow.ts.html b/coverage/components/effects/useSlideshow.ts.html deleted file mode 100644 index b35af6a13..000000000 --- a/coverage/components/effects/useSlideshow.ts.html +++ /dev/null @@ -1,634 +0,0 @@ - - - - - - Code coverage report for components/effects/useSlideshow.ts - - - - - - - - - -
-
-

All files / components/effects useSlideshow.ts

-
- -
- 55.26% - Statements - 63/114 -
- - -
- 66.66% - Branches - 8/12 -
- - -
- 100% - Functions - 1/1 -
- - -
- 55.26% - Lines - 63/114 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -1841x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -  -  -  -  -52x -  -137x -  -  -  -  -  -137x -  -  -  -  -137x -52x -  -  -  -  -  -52x -52x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -52x -52x -  -  -  -  -52x -  -  -  -  -  -  -  -52x -  -  -  -  -52x -1x -  -  -  -1x -1x -  -1x -  -  -  -  -1x -1x -1x -52x -  -  -  -  -52x -  -  -  -  -  -  -  -  -  -52x -  -  -52x -37x -34x -34x -37x -52x -  -  -52x -37x -28x -28x -37x -  -37x -37x -52x -  -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -  -  - 
import { RefObject, useCallback, useEffect, useRef, useState } from 'react';
- 
-type SlideshowHookReturn = {
-  paused: boolean;
-  remainInterval: number;
-  setStartWidth: (width: number) => void;
-  setupTimer: (interval: number) => void;
-  startWidth: number;
-  tryPause: () => void;
-  tryResume: () => void;
-};
- 
-/**
- * Custom hook to manage slideshow functionality with pause/resume capabilities
- * Uses requestAnimationFrame for smoother animation performance
- * @param ref - Reference to the HTML element containing the slideshow
- * @param active - Whether the current slide is active
- * @param slideShowActive - Whether the slideshow functionality is enabled
- * @param slideItemDuration - Duration in milliseconds for each slide
- * @param id - Unique identifier for the current slide
- * @param onElapsed - Callback function triggered when slide duration elapses
- * @returns Object containing slideshow control functions and state
- */
-const useSlideshow = (
-  ref: RefObject<HTMLElement>,
-  active: boolean,
-  slideShowActive: boolean,
-  slideItemDuration: number,
-  id: string,
-  onElapsed?: (id: string) => void,
-): SlideshowHookReturn => {
-  const startTime = useRef<number | null>(null);
-  const timerRef = useRef<number>(0);
-  const rafRef = useRef<number>(0);
-  const [startWidth, setStartWidth] = useState<number>(0);
-  const [paused, setPaused] = useState<boolean>(false);
-  const slideShowElapsed = useRef<number>(0);
-  const [remainInterval, setRemainInterval] = useState<number>(0);
-  const isRunning = useRef<boolean>(false);
- 
-  /**
-   * Cleans up timers and animation frames
-   */
-  const cleanupTimer = useCallback(() => {
-    // Clear timeout if exists
-    if (timerRef.current) {
-      window.clearTimeout(timerRef.current);
-      timerRef.current = 0;
-    }
- 
-    // Cancel animation frame if exists
-    if (rafRef.current) {
-      window.cancelAnimationFrame(rafRef.current);
-      rafRef.current = 0;
-    }
- 
-    isRunning.current = false;
-  }, []);
- 
-  /**
-   * Sets up a new timer for the slideshow using requestAnimationFrame for smoother animations
-   * @param interval - Duration in milliseconds for the timer
-   */
-  const setupTimer = useCallback(
-    (interval: number) => {
-      if (!slideItemDuration || interval <= 0 || !active || !slideShowActive) {
-        return;
-      }
- 
-      cleanupTimer();
-      setRemainInterval(interval);
-      startTime.current = performance.now();
-      setPaused(false);
-      isRunning.current = true;
- 
-      // For very short durations, use setTimeout as fallback
-      if (interval < 50) {
-        timerRef.current = window.setTimeout(() => {
-          handleTimerComplete();
-        }, interval);
-        return;
-      }
- 
-      // Use requestAnimationFrame for smoother animation
-      const endTime = startTime.current + interval;
- 
-      const animationStep = (timestamp: number) => {
-        if (!isRunning.current) return;
- 
-        if (timestamp >= endTime) {
-          handleTimerComplete();
-          return;
-        }
- 
-        // Continue animation loop
-        rafRef.current = window.requestAnimationFrame(animationStep);
-      };
- 
-      rafRef.current = window.requestAnimationFrame(animationStep);
-    },
-    [slideItemDuration, active, slideShowActive],
-  );
- 
-  /**
-   * Handles timer completion
-   */
-  const handleTimerComplete = useCallback(() => {
-    cleanupTimer();
-    setPaused(true);
-    setStartWidth(0);
-    setRemainInterval(slideItemDuration);
-    if (id && onElapsed) {
-      onElapsed(id);
-    }
-  }, [id, onElapsed, slideItemDuration, cleanupTimer]);
- 
-  /**
-   * Pauses the current slideshow if conditions are met
-   */
-  const tryPause = useCallback(() => {
-    if (!active || !slideShowActive) {
-      return;
-    }
- 
-    cleanupTimer();
-    setPaused(true);
- 
-    if (startTime.current !== null) {
-      const elapsed = performance.now() - startTime.current;
-      slideShowElapsed.current = elapsed;
-    }
- 
-    if (ref.current) {
-      setStartWidth(ref.current.clientWidth);
-    }
-  }, [active, slideShowActive, cleanupTimer]);
- 
-  /**
-   * Resumes the slideshow if conditions are met
-   */
-  const tryResume = useCallback(() => {
-    if (!active || !slideShowActive || !slideItemDuration) {
-      return;
-    }
- 
-    const remainingInterval = slideItemDuration - slideShowElapsed.current;
-    if (remainingInterval > 0) {
-      setPaused(false);
-      setupTimer(remainingInterval);
-    }
-  }, [active, slideShowActive, slideItemDuration, setupTimer]);
- 
-  // Cleanup effect when slideShowActive changes or component unmounts
-  useEffect(() => {
-    if (!slideShowActive) {
-      cleanupTimer();
-    }
-    return cleanupTimer;
-  }, [slideShowActive, cleanupTimer]);
- 
-  // Cleanup effect when active state changes
-  useEffect(() => {
-    if (!active) {
-      cleanupTimer();
-    }
-    return () => {
-      // Cleanup when component unmounts or dependencies change
-      cleanupTimer();
-    };
-  }, [active, cleanupTimer]);
- 
-  return {
-    paused,
-    remainInterval,
-    setStartWidth,
-    setupTimer,
-    startWidth,
-    tryPause,
-    tryResume,
-  };
-};
- 
-export { useSlideshow };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/__tests__/index.html b/coverage/components/elements/list/__tests__/index.html deleted file mode 100644 index a6fac0c8a..000000000 --- a/coverage/components/elements/list/__tests__/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/elements/list/__tests__ - - - - - - - - - -
-
-

All files components/elements/list/__tests__

-
- -
- 100% - Statements - 134/134 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 134/134 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
list-item.test.tsx -
-
100%77/77100%6/6100%0/0100%77/77
list.test.tsx -
-
100%57/57100%7/7100%0/0100%57/57
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/__tests__/list-item.test.tsx.html b/coverage/components/elements/list/__tests__/list-item.test.tsx.html deleted file mode 100644 index 5b7ee325e..000000000 --- a/coverage/components/elements/list/__tests__/list-item.test.tsx.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - Code coverage report for components/elements/list/__tests__/list-item.test.tsx - - - - - - - - - -
-
-

All files / components/elements/list/__tests__ list-item.test.tsx

-
- -
- 100% - Statements - 77/77 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 77/77 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -851x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import '@testing-library/jest-dom';
-import { fireEvent } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { vi } from 'vitest';
-import { ListItem } from '../list-item';
- 
-describe('ListItem', () => {
-  const defaultProps = {
-    description: 'Test Description',
-    id: 'test-id',
-    title: 'Test Title',
-  };
- 
-  const theme = getDefaultThemeOrDark();
- 
-  it('renders the component with correct title and description', () => {
-    const { getByText } = customRender(
-      <ListItem {...defaultProps} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(getByText('Test Title')).toBeInTheDocument();
-    expect(getByText('Test Description')).toBeInTheDocument();
-  });
- 
-  it('calls onClick when the item is clicked', () => {
-    const mockOnClick = vi.fn();
-    const { getByRole } = customRender(
-      <ListItem
-        {...defaultProps}
-        onClick={mockOnClick}
-        selectable
-        theme={theme}
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    fireEvent.click(getByRole('listitem'));
-    expect(mockOnClick).toHaveBeenCalledWith('test-id');
-  });
- 
-  it('renders the checkbox when selectable is true', () => {
-    const { getByRole } = customRender(
-      <ListItem {...defaultProps} selectable theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(getByRole('checkbox')).toBeInTheDocument();
-  });
- 
-  it('does not render the checkbox when selectable is false', () => {
-    const { queryByRole } = customRender(
-      <ListItem {...defaultProps} selectable={false} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(queryByRole('checkbox')).not.toBeInTheDocument();
-  });
- 
-  it('has the correct tab index when selectable is true', () => {
-    const { getByRole } = customRender(
-      <ListItem {...defaultProps} selectable theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(getByRole('listitem')).toHaveAttribute('tabIndex', '0');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/__tests__/list.test.tsx.html b/coverage/components/elements/list/__tests__/list.test.tsx.html deleted file mode 100644 index 250a00e8f..000000000 --- a/coverage/components/elements/list/__tests__/list.test.tsx.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - Code coverage report for components/elements/list/__tests__/list.test.tsx - - - - - - - - - -
-
-

All files / components/elements/list/__tests__ list.test.tsx

-
- -
- 100% - Statements - 57/57 -
- - -
- 100% - Branches - 7/7 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 57/57 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -651x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -3x -3x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x - 
import { describe, expect, it, vi } from 'vitest';
- 
-import { fireEvent } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { List } from '../list';
- 
-const items = [
-  { description: 'Description 1', id: '1', title: 'Item 1' },
-  { description: 'Description 2', id: '2', title: 'Item 2' },
-  { description: 'Description 3', id: '3', title: 'Item 3' },
-];
- 
-describe('List', () => {
-  const theme = getDefaultThemeOrDark(false);
- 
-  it('should render the correct number of list items', () => {
-    const { getAllByRole } = customRender(
-      <List items={items} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    const listItems = getAllByRole('listitem');
-    expect(listItems).toHaveLength(items.length);
-  });
- 
-  it('should call onClick when a list item is clicked', () => {
-    const onClick = vi.fn();
-    const { getByText } = customRender(
-      <List items={items} onClick={onClick} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    const listItem = getByText('Item 1');
-    fireEvent.click(listItem);
-    expect(onClick).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should call onSelect when a list item is clicked and multiSelectable is true', () => {
-    const onSelectItem = vi.fn();
-    const itemsWithOnSelect = items.map((item, index) => ({
-      ...item,
-      onSelect: index === 0 ? onSelectItem : undefined,
-    }));
-    const { getByText } = customRender(
-      <List items={itemsWithOnSelect} multiSelectable theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const listItem = getByText('Item 1');
-    fireEvent.click(listItem);
-    expect(onSelectItem).toHaveBeenCalledTimes(1);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/index.html b/coverage/components/elements/list/index.html deleted file mode 100644 index 7df3d6491..000000000 --- a/coverage/components/elements/list/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/elements/list - - - - - - - - - -
-
-

All files components/elements/list

-
- -
- 97.74% - Statements - 130/133 -
- - -
- 87.8% - Branches - 36/41 -
- - -
- 80% - Functions - 4/5 -
- - -
- 97.74% - Lines - 130/133 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
list-item.tsx -
-
94.11%48/51100%6/650%1/294.11%48/51
list.model.ts -
-
0%0/00%1/10%1/10%0/0
list.styles.ts -
-
100%35/3580%20/25100%1/1100%35/35
list.tsx -
-
100%47/47100%9/9100%1/1100%47/47
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/list-item.tsx.html b/coverage/components/elements/list/list-item.tsx.html deleted file mode 100644 index 46e7c5d00..000000000 --- a/coverage/components/elements/list/list-item.tsx.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list-item.tsx - - - - - - - - - -
-
-

All files / components/elements/list list-item.tsx

-
- -
- 94.11% - Statements - 48/51 -
- - -
- 100% - Branches - 6/6 -
- - -
- 50% - Functions - 1/2 -
- - -
- 94.11% - Lines - 48/51 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -921x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -  -  -  -18x -  -  -  -  -  -  -18x -  -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -10x -10x -10x -10x -10x -10x -  -10x -10x -10x -8x -18x -18x -18x -18x -18x -18x -18x -  -18x -1x -  -1x -  -  - 
import { FunctionComponent, KeyboardEvent, memo, useCallback } from 'react';
-import { CheckIcon } from 'src/components/icons';
-import { ListItemModel } from './list.model';
-import {
-  CheckboxStyle,
-  CheckboxWrapper,
-  ListItemStyle,
-  StyleAndDescription,
-  TitleDescriptionStyle,
-  TitleStyle,
-} from './list.styles';
- 
-/**
- * ListItem component displays a selectable/clickable item with title and description
- * @component
- * @param {Object} props - Component props
- * @param {string} props.title - The title text of the list item
- * @param {string} props.id - Unique identifier for the list item
- * @param {string} props.description - Optional description text below the title
- * @param {Theme} props.theme - Theme object for styling
- * @param {(id: string) => void} props.onClick - Click handler function
- * @param {boolean} props.active - Whether the item is in active state
- * @param {boolean} [props.selected=false] - Whether the item is selected (for checkbox mode)
- * @param {boolean} [props.selectable=false] - Whether the item shows a checkbox
- * @returns {JSX.Element} Rendered ListItem component
- */
-const ListItem: FunctionComponent<ListItemModel> = memo(
-  ({
-    title,
-    id,
-    description,
-    theme,
-    onClick,
-    active,
-    selected = false,
-    selectable = false,
-  }: ListItemModel) => {
-    /**
-     * Memoized click handler
-     * @param {string} id - Item identifier
-     */
-    const handleOnClick = useCallback((id: string) => onClick?.(id), [onClick]);
- 
-    /**
-     * Keyboard event handler for accessibility
-     * @param {KeyboardEvent} ev - Keyboard event
-     * @param {string} id - Item identifier
-     */
-    const handleKeyPress = useCallback((ev: KeyboardEvent, id: string) => {
-      if (ev.key === 'Enter') {
-        handleOnClick(id);
-      }
-    }, []);
- 
-    return (
-      <ListItemStyle
-        data-testid="list-item"
-        key={id}
-        $theme={theme}
-        onClick={() => handleOnClick(id)}
-        $active={active}
-        tabIndex={0}
-        $selectable={selectable}
-        onKeyUp={(ev) => handleKeyPress(ev, id)}
-      >
-        {selectable ? (
-          <CheckboxWrapper>
-            <CheckboxStyle
-              role="checkbox"
-              aria-checked={selected}
-              selected={selected}
-              theme={theme}
-            >
-              {selected && <CheckIcon />}
-            </CheckboxStyle>
-          </CheckboxWrapper>
-        ) : null}
-        <StyleAndDescription $selectable={selectable}>
-          <TitleStyle theme={theme}>{title}</TitleStyle>
-          <TitleDescriptionStyle theme={theme}>
-            {description}
-          </TitleDescriptionStyle>
-        </StyleAndDescription>
-      </ListItemStyle>
-    );
-  },
-);
- 
-ListItem.displayName = 'ListItem';
- 
-export { ListItem };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/list.model.ts.html b/coverage/components/elements/list/list.model.ts.html deleted file mode 100644 index 5cfdc9f01..000000000 --- a/coverage/components/elements/list/list.model.ts.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list.model.ts - - - - - - - - - -
-
-

All files / components/elements/list list.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { TimelineModel } from '@models/TimelineModel';
- 
-export type ListModel = {
-  activeItemIndex?: number;
-  items: ListItemModel[];
-  multiSelectable?: boolean;
-  onClick?: (id?: string) => void;
-} & Pick<TimelineModel, 'theme'>;
- 
-export type ListItemModel = {
-  active?: boolean;
-  description: string;
-  id: string;
-  onClick?: (id: string) => void;
-  onSelect?: () => void;
-  selectable?: boolean;
-  selected?: boolean;
-  title: string;
-} & Pick<TimelineModel, 'theme'>;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/list.styles.ts.html b/coverage/components/elements/list/list.styles.ts.html deleted file mode 100644 index 7fd3c4f18..000000000 --- a/coverage/components/elements/list/list.styles.ts.html +++ /dev/null @@ -1,508 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list.styles.ts - - - - - - - - - -
-
-

All files / components/elements/list list.styles.ts

-
- -
- 100% - Statements - 35/35 -
- - -
- 80% - Branches - 20/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 35/35 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142  -1x -  -  -1x -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -1x -1x -1x -  -1x -1x -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -  -1x -1x -  -  -  -  -1x -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -1x -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
- 
-// Theme-specific constants
-const themeStyles = {
-  border: (theme: Theme) => `1px solid ${theme.primary}`,
-  transparent: '1px solid transparent',
-};
- 
-// Reusable flex container mixin with fallbacks
-const flexContainer = css`
-  display: -webkit-box;
-  display: -ms-flexbox;
-  display: flex;
-  -webkit-box-align: center;
-  -ms-flex-align: center;
-  align-items: center;
-`;
- 
-// Base styles for list items and containers
-const baseStyles = css`
-  ${flexContainer}
-  margin: 0;
-  width: 100%;
-  -webkit-box-orient: vertical;
-  -webkit-box-direction: normal;
-  -ms-flex-direction: column;
-  flex-direction: column;
-`;
- 
-// Common styles with improved typing and vendor prefixes
-const commonStyles = css<{ $theme: Theme }>`
-  ${baseStyles}
-  background: ${(p) => p.$theme?.toolbarBtnBgColor || '#f5f5f5'};
-  border-radius: 4px;
-  -webkit-box-shadow: 0px 1px 1px ${(p) => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'};
-  box-shadow: 0px 1px 1px ${(p) => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'};
-  margin-bottom: 0.5rem;
- 
-  &:last-child {
-    margin-bottom: 0;
-  }
-`;
- 
-// Main list container with improved responsive layout
-export const ListStyle = styled.ul`
-  ${baseStyles}
-  -webkit-box-orient: vertical;
-  -webkit-box-direction: normal;
-  -ms-flex-direction: column;
-  flex-direction: column;
-  -webkit-box-pack: center;
-  -ms-flex-pack: center;
-  justify-content: center;
-  list-style: none;
-  padding: 0;
-  width: 100%;
-  max-width: 100%;
- 
-  @media screen and (max-width: 768px) {
-    padding: 0.5rem;
-  }
- 
-  @media screen and (max-width: 480px) {
-    padding: 0.25rem;
-  }
-`;
- 
-// Interactive list item with theme support
-export const ListItemStyle = styled.li<{
-  $active?: boolean;
-  $selectable?: boolean;
-  $theme: Theme;
-}>`
-  ${commonStyles}
-  border: ${(p) =>
-    p.$active ? themeStyles.border(p.$theme) : themeStyles.transparent};
-  flex-direction: ${(p) => (p.$selectable ? 'row' : 'column')};
-  background: ${(p) => p.$theme.toolbarBtnBgColor};
-  padding: 0.25rem;
-  width: calc(100% - 0.5rem);
-  user-select: none;
- 
-  &:hover {
-    border: ${(p) => themeStyles.border(p.$theme)};
-    cursor: pointer;
-  }
-`;
- 
-// Title styles
-export const TitleStyle = styled.h1<{ theme: Theme }>`
-  color: ${(p) => p.theme.iconColor || p.theme.primary};
-  font-size: 1rem;
-  font-weight: normal;
-  margin: 0.2rem 0;
-  text-align: left;
-  white-space: nowrap;
-  align-self: flex-start;
-`;
- 
-// Title description styles
-export const TitleDescriptionStyle = styled.p<{ theme: Theme }>`
-  font-size: 0.8rem;
-  font-weight: normal;
-  margin: 0;
-  padding: 0.1rem;
-  text-align: left;
-  width: 100%;
-  color: ${(p) => p.theme.cardSubtitleColor};
-`;
- 
-// Checkbox components with improved structure
-export const CheckboxWrapper = styled.span`
-  ${flexContainer}
-  width: 2rem;
-  justify-content: center;
-`;
- 
-export const CheckboxStyle = styled.span<{ selected?: boolean; theme: Theme }>`
-  ${flexContainer}
-  justify-content: center;
-  width: 1.25rem;
-  height: 1.25rem;
-  margin: 0 0.25rem 0 0.1rem;
-  border-radius: 50%;
-  background: ${(p) => (p.selected ? p.theme.primary : p.theme.toolbarBgColor)};
-  ${(p) => !p.selected && `box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1)`};
-  color: #ffffff;
- 
-  svg {
-    width: 80%;
-    height: 80%;
-  }
-`;
- 
-// Content wrapper with conditional width
-export const StyleAndDescription = styled.div<{ $selectable?: boolean }>`
-  ${flexContainer}
-  flex-direction: column;
-  width: ${(p) => (p.$selectable ? 'calc(100% - 2rem)' : '100%')};
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/list/list.tsx.html b/coverage/components/elements/list/list.tsx.html deleted file mode 100644 index 81e68c074..000000000 --- a/coverage/components/elements/list/list.tsx.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list.tsx - - - - - - - - - -
-
-

All files / components/elements/list list.tsx

-
- -
- 100% - Statements - 47/47 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 47/47 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -951x -1x -  -  -  -  -  -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -5x -5x -5x -5x -5x -5x -  -  -  -5x -5x -5x -5x -  -  -  -  -  -  -5x -5x -2x -1x -1x -1x -1x -1x -1x -2x -5x -5x -  -  -  -  -  -  -  -5x -5x -13x -13x -13x -13x -  -13x -13x -13x -13x -13x -13x -13x -13x -13x -  -13x -5x -5x -  -5x -5x -  -  - 
import { getUniqueID } from '@utils/index';
-import {
-  FunctionComponent,
-  startTransition,
-  useCallback,
-  useMemo,
-} from 'react';
-import { ListItem } from './list-item';
-import { ListModel } from './list.model';
-import { ListStyle } from './list.styles';
- 
-/**
- * Extends the base list item with a unique identifier
- * @typedef {Object} EnhancedListItem
- * @extends {ListModel['items'][0]}
- * @property {string} id - Unique identifier for the list item
- */
-type EnhancedListItem = ListModel['items'][0] & { id: string };
- 
-/**
- * List component that renders selectable items with optional multi-select capability
- * @component
- * @param {Object} props - Component props
- * @param {Array<ListModel['items'][0]>} props.items - Array of items to render in the list
- * @param {string} props.theme - Theme configuration for styling
- * @param {(id: string) => void} [props.onClick] - Callback function when an item is clicked
- * @param {number} [props.activeItemIndex] - Index of the currently active item
- * @param {boolean} [props.multiSelectable=false] - Enable multi-select functionality
- * @returns {JSX.Element} Rendered list component
- */
-const List: FunctionComponent<ListModel> = ({
-  items,
-  theme,
-  onClick,
-  activeItemIndex,
-  multiSelectable = false,
-}) => {
-  /**
-   * Memoized list items with generated unique IDs
-   */
-  const listItems = useMemo(
-    () => items.map((item) => ({ id: getUniqueID(), ...item })),
-    [items],
-  );
- 
-  /**
-   * Handles item selection and triggers appropriate callbacks
-   * @param {string} id - Item identifier
-   * @param {EnhancedListItem} item - Selected list item
-   */
-  const handleItemSelection = useCallback(
-    (id: string, item: EnhancedListItem) => {
-      if (multiSelectable && item.onSelect) {
-        startTransition(() => {
-          item.onSelect();
-        });
-      } else {
-        onClick?.(id);
-      }
-    },
-    [multiSelectable, onClick],
-  );
- 
-  /**
-   * Renders individual list items with proper props
-   * @param {EnhancedListItem} item - Item to render
-   * @param {number} index - Item index in the list
-   * @returns {JSX.Element} Rendered list item
-   */
-  const renderListItem = useCallback(
-    (item: EnhancedListItem, index: number) => {
-      const handleClick = useCallback(
-        () => handleItemSelection(item.id, item),
-        [item, handleItemSelection],
-      );
- 
-      return (
-        <ListItem
-          key={item.id}
-          {...item}
-          theme={theme}
-          onClick={handleClick}
-          selectable={multiSelectable}
-          active={activeItemIndex === index}
-        />
-      );
-    },
-    [theme, handleItemSelection, multiSelectable, activeItemIndex],
-  );
- 
-  return <ListStyle>{listItems.map(renderListItem)}</ListStyle>;
-};
- 
-export { List };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/popover/__tests__/index.html b/coverage/components/elements/popover/__tests__/index.html deleted file mode 100644 index d1e7d2213..000000000 --- a/coverage/components/elements/popover/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/__tests__ - - - - - - - - - -
-
-

All files components/elements/popover/__tests__

-
- -
- 100% - Statements - 85/85 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 85/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
popover.test.tsx -
-
100%85/85100%6/6100%0/0100%85/85
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/popover/__tests__/popover.test.tsx.html b/coverage/components/elements/popover/__tests__/popover.test.tsx.html deleted file mode 100644 index e2047d449..000000000 --- a/coverage/components/elements/popover/__tests__/popover.test.tsx.html +++ /dev/null @@ -1,403 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/__tests__/popover.test.tsx - - - - - - - - - -
-
-

All files / components/elements/popover/__tests__ popover.test.tsx

-
- -
- 100% - Statements - 85/85 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 85/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -1071x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -4x -4x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -  -1x -  -1x -1x -1x - 
import { fireEvent, screen } from '@testing-library/react';
-import { vi } from 'vitest';
- 
-import userEvent from '@testing-library/user-event';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import PopOver from '../index';
- 
-describe('PopOver', () => {
-  const mockClosePopover = vi.fn();
-  const mockToggleOpen = vi.fn();
- 
-  const theme = getDefaultThemeOrDark();
- 
-  beforeEach(() => {
-    mockClosePopover.mockReset();
-    mockToggleOpen.mockReset();
-  });
- 
-  it('should render the placeholder text', () => {
-    const placeholder = 'Select an option';
-    customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecterLabel = screen.getByText(placeholder);
-    expect(selecterLabel).toBeInTheDocument();
-  });
- 
-  it('should toggle open state when clicking on the selecter', async () => {
-    const placeholder = 'Select an option';
-    const { getByRole, getByText } = customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecter = getByRole('button');
-    expect(selecter).toBeInTheDocument();
- 
-    await fireEvent.click(selecter);
- 
-    expect(getByText('test')).toBeInTheDocument();
-  });
- 
-  it('should close the popover when clicking outside', async () => {
-    const placeholder = 'Select an option';
-    const { getByRole, queryByText } = customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecter = getByRole('button');
-    await fireEvent.click(selecter);
- 
-    expect(queryByText('test')).toBeInTheDocument();
- 
-    await fireEvent.click(document.body);
- 
-    expect(queryByText('test')).not.toBeInTheDocument();
-  });
- 
-  it('should close the popover when pressing the Escape key', async () => {
-    const user = userEvent.setup();
-    const placeholder = 'Select an option';
-    const { getByRole, queryByText, getByText } = customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecter = getByRole('button');
-    await user.click(selecter);
- 
-    expect(queryByText('test')).toBeInTheDocument();
- 
-    getByText('test').focus();
- 
-    await user.keyboard('{Escape}');
- 
-    expect(queryByText('test')).not.toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/popover/index.html b/coverage/components/elements/popover/index.html deleted file mode 100644 index c396beee4..000000000 --- a/coverage/components/elements/popover/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Code coverage report for components/elements/popover - - - - - - - - - -
-
-

All files components/elements/popover

-
- -
- 97.2% - Statements - 139/143 -
- - -
- 79.31% - Branches - 46/58 -
- - -
- 100% - Functions - 19/19 -
- - -
- 97.2% - Lines - 139/143 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.tsx -
-
95.74%90/9485%17/20100%2/295.74%90/94
popover.model.ts -
-
0%0/00%1/10%1/10%0/0
popover.styles.ts -
-
100%49/4975.67%28/37100%16/16100%49/49
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/popover/index.tsx.html b/coverage/components/elements/popover/index.tsx.html deleted file mode 100644 index fbfb298af..000000000 --- a/coverage/components/elements/popover/index.tsx.html +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/index.tsx - - - - - - - - - -
-
-

All files / components/elements/popover index.tsx

-
- -
- 95.74% - Statements - 90/94 -
- - -
- 85% - Branches - 17/20 -
- - -
- 100% - Functions - 2/2 -
- - -
- 95.74% - Lines - 90/94 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -1391x -  -  -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -5x -1x -  -  -  -  -  -  -  -  -1x -22x -22x -5x -22x -3x -22x -14x -22x -  -22x -22x -  -  -  -  -  -  -1x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -  -35x -5x -35x -  -35x -3x -35x -  -35x -1x -  -  -35x -  -35x -  -  -35x -19x -5x -2x -5x -17x -14x -14x -35x -  -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -  -35x -35x -35x -35x -35x -  -35x -35x -35x -5x -5x -5x -5x -5x -5x -  -5x -5x -5x -5x -5x -5x -5x -30x -35x -  -35x -  -1x - 
import React, {
-  FunctionComponent,
-  useCallback,
-  useEffect,
-  useReducer,
-  useRef,
-  memo,
-} from 'react';
-import useCloseClickOutside from 'src/components/effects/useCloseClickOutside';
-import { ChevronDown, CloseIcon } from 'src/components/icons';
-import { PopOverModel } from './popover.model';
-import {
-  CloseButton,
-  Content,
-  Header,
-  PopoverHolder,
-  PopoverWrapper,
-  Selecter,
-  SelecterIcon,
-  SelecterLabel,
-} from './popover.styles';
- 
-// Memoized Content component
-const MemoizedContent = memo(({ children }: { children: React.ReactNode }) => (
-  <Content>{children}</Content>
-));
- 
-// Reducer for state management
-type State = { open: boolean; isVisible: boolean };
-type Action =
-  | { type: 'TOGGLE' }
-  | { type: 'CLOSE' }
-  | { type: 'SET_VISIBLE'; payload: boolean };
- 
-const popoverReducer = (state: State, action: Action): State => {
-  switch (action.type) {
-    case 'TOGGLE':
-      return { ...state, open: !state.open };
-    case 'CLOSE':
-      return { ...state, open: false };
-    case 'SET_VISIBLE':
-      return { ...state, isVisible: action.payload };
-    default:
-      return state;
-  }
-};
- 
-/**
- * A customizable popover component that displays content in a floating panel
- * @param {PopOverModel} props - Component props
- * @returns {JSX.Element} PopOver component
- */
-const PopOver: FunctionComponent<PopOverModel> = ({
-  children,
-  position,
-  placeholder,
-  theme,
-  width = 350,
-  isDarkMode = false,
-  icon,
-  $isMobile = false,
-}) => {
-  const ref = useRef<HTMLDivElement>(null);
-  const [state, dispatch] = useReducer(popoverReducer, {
-    open: false,
-    isVisible: false,
-  });
- 
-  const toggleOpen = useCallback(() => {
-    dispatch({ type: 'TOGGLE' });
-  }, []);
- 
-  const closePopover = useCallback(() => {
-    dispatch({ type: 'CLOSE' });
-  }, []);
- 
-  const handleKeyPress = useCallback((ev: React.KeyboardEvent) => {
-    if (ev.key === 'Enter') {
-      dispatch({ type: 'TOGGLE' });
-    }
-  }, []);
- 
-  useCloseClickOutside(ref, closePopover);
- 
-  // Use CSS transition instead of setTimeout
-  useEffect(() => {
-    if (state.open) {
-      requestAnimationFrame(() => {
-        dispatch({ type: 'SET_VISIBLE', payload: true });
-      });
-    } else {
-      dispatch({ type: 'SET_VISIBLE', payload: false });
-    }
-  }, [state.open]);
- 
-  return (
-    <>
-      <PopoverWrapper ref={ref}>
-        <Selecter
-          role="button"
-          onClick={toggleOpen}
-          $theme={theme}
-          $open={state.open}
-          $isDarkMode={isDarkMode}
-          tabIndex={0}
-          onKeyUp={handleKeyPress}
-          $isMobile={$isMobile}
-          title={placeholder}
-        >
-          <SelecterIcon $theme={theme} $open={state.open}>
-            {icon || <ChevronDown />}
-          </SelecterIcon>
-          {placeholder && !$isMobile ? (
-            <SelecterLabel>{placeholder}</SelecterLabel>
-          ) : null}
-        </Selecter>
-      </PopoverWrapper>
-      {state.open ? (
-        <PopoverHolder
-          $position={position}
-          $width={width}
-          $theme={theme}
-          $isMobile={$isMobile}
-          $visible={state.isVisible}
-        >
-          <Header>
-            <CloseButton theme={theme} onClick={closePopover}>
-              <CloseIcon />
-            </CloseButton>
-          </Header>
-          <MemoizedContent>{children}</MemoizedContent>
-        </PopoverHolder>
-      ) : null}
-    </>
-  );
-};
- 
-export default memo(PopOver);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/popover/popover.model.ts.html b/coverage/components/elements/popover/popover.model.ts.html deleted file mode 100644 index 26236c3bd..000000000 --- a/coverage/components/elements/popover/popover.model.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/popover.model.ts - - - - - - - - - -
-
-

All files / components/elements/popover popover.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { ReactNode } from 'react';
- 
-export type PopOverModel = {
-  $isMobile?: boolean;
-  children: ReactNode | ReactNode[];
-  icon?: ReactNode;
-  isDarkMode?: boolean;
-  placeholder?: string;
-  position: 'top' | 'bottom';
-  theme?: Theme;
-  width?: number;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/elements/popover/popover.styles.ts.html b/coverage/components/elements/popover/popover.styles.ts.html deleted file mode 100644 index 97c66b3a7..000000000 --- a/coverage/components/elements/popover/popover.styles.ts.html +++ /dev/null @@ -1,496 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/popover.styles.ts - - - - - - - - - -
-
-

All files / components/elements/popover popover.styles.ts

-
- -
- 100% - Statements - 49/49 -
- - -
- 75.67% - Branches - 28/37 -
- - -
- 100% - Functions - 16/16 -
- - -
- 100% - Lines - 49/49 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138  -1x -1x -  -  -1x -  -  -  -  -  -  -1x -40x -26x -14x -  -1x -5x -  -1x -35x -30x -5x -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -  -1x -1x -1x -1x -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -1x -1x -1x -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -1x -1x -  -  -1x -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-// Utility mixin for centering content using flexbox
-const flexCenter = css`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`;
- 
-// Helper functions for shared styling logic
-const getBorderStyle = (theme: Theme) =>
-  theme.buttonBorderColor
-    ? `1px solid ${theme.buttonBorderColor}`
-    : '1px solid transparent';
- 
-const getElevatedShadow = (theme: Theme) =>
-  `0px 5px 16px ${theme.shadowColor || 'rgba(0, 0, 0, 0.5)'}`;
- 
-const getInteractiveShadow = (theme: Theme, isOpen?: boolean) =>
-  !isOpen
-    ? `0px 1px 3px ${theme.shadowColor || 'rgba(0, 0, 0, 0.2)'}`
-    : `inset 0 0 1px 1px ${theme.shadowColor || 'rgba(0, 0, 0, 0.2)'}`;
- 
-const BORDER_RADIUS = '6px';
- 
-// Base wrapper for the popover component
-export const PopoverWrapper = styled.div``;
- 
-// Main popover container with positioning and visibility controls
-export const PopoverHolder = styled.div<{
-  $isMobile?: boolean;
-  $position?: 'top' | 'bottom';
-  $theme?: Theme;
-  $visible?: boolean;
-  $width: number;
-}>`
-  ${flexCenter};
-  flex-direction: column;
-  background: ${({ $theme }) => $theme.toolbarBgColor};
-  border-radius: ${BORDER_RADIUS};
-  border: ${({ $theme }) => getBorderStyle($theme)};
-  box-shadow: ${({ $theme }) => getElevatedShadow($theme)};
-  max-height: 500px;
-  overflow-y: auto;
-  padding: 0.5rem;
-  position: absolute;
-  ${(p) => (p.$position === 'bottom' ? `bottom: 3.5rem` : `top: 4rem`)};
-  ${(p) => (p.$isMobile ? 'left: 4px;' : '')};
-  width: ${({ $isMobile, $width = 300 }) =>
-    $isMobile ? '90%' : `${$width}px`};
-  opacity: ${({ $visible }) => ($visible ? 1 : 0)};
-  transition:
-    opacity 0.2s ease-in-out,
-    transform 0.2s ease-in-out;
-  transform: ${(p) => (p.$visible ? 'translateY(0)' : 'translateY(-10px)')};
-  z-index: ${zIndex.popover}; /* Use standardized z-index for popovers */
-`;
- 
-// Clickable selector button that triggers the popover
-export const Selecter = styled.div<{
-  $isDarkMode: boolean;
-  $isMobile?: boolean;
-  $open?: boolean;
-  $theme: Theme;
-}>`
-  ${flexCenter};
-  background: ${({ $theme }) => $theme.toolbarBtnBgColor};
-  color: ${({ $theme }) => $theme.toolbarTextColor};
-  border-radius: ${BORDER_RADIUS};
-  border: ${({ $theme }) => getBorderStyle($theme)};
-  box-shadow: ${({ $open, $theme }) => getInteractiveShadow($theme, $open)};
-  cursor: pointer;
-  justify-content: space-between;
-  padding: ${(p) => (p.$isMobile ? '0.4rem' : `0.4rem 0.5rem`)};
-  user-select: none;
-  margin-right: 0.5rem;
-  transition:
-    background-color 0.2s ease-out,
-    border-color 0.2s ease-out,
-    box-shadow 0.2s ease-out;
- 
-  &:hover {
-    background: ${({ $theme }) =>
-      $theme.buttonHoverBgColor || $theme.toolbarBtnBgColor};
-    border-color: ${({ $theme }) =>
-      $theme.buttonHoverBorderColor || $theme.primary};
-  }
-`;
- 
-// Icon component within the selector with rotation animation
-export const SelecterIcon = styled.span<{ $open: boolean; $theme: Theme }>`
-  ${flexCenter};
-  color: ${({ $theme }) => $theme.iconColor || $theme.primary};
-  height: 1.25rem;
-  width: 1.25rem;
-  transition: transform 0.2s ease-in-out;
-  margin-right: 0.1rem;
- 
-  & svg {
-    height: 100%;
-    width: 100%;
-  }
-`;
- 
-// Text label for the selector button
-export const SelecterLabel = styled.span`
-  font-size: 0.9rem;
-  text-align: left;
-  white-space: nowrap;
-  font-weight: 500;
-`;
- 
-// Top section of the popover containing controls
-export const Header = styled.div`
-  height: 30px;
-  width: 100%;
-`;
- 
-// Scrollable content area of the popover
-export const Content = styled.div`
-  height: calc(100% - 30px);
-  overflow-y: auto;
-  width: 100%;
-`;
- 
-// Close button with icon for dismissing the popover
-export const CloseButton = styled.button<{ theme: Theme }>`
-  ${flexCenter};
-  background: transparent;
-  border: none;
-  color: ${({ theme }) => theme.iconColor || theme.primary};
-  cursor: pointer;
-  margin-bottom: 0.5rem;
-  margin-left: auto;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/__tests__/index.html b/coverage/components/timeline-elements/memoized/__tests__/index.html deleted file mode 100644 index cd225734c..000000000 --- a/coverage/components/timeline-elements/memoized/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/memoized/__tests__

-
- -
- 99.27% - Statements - 136/137 -
- - -
- 100% - Branches - 15/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 99.27% - Lines - 136/137 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.test.tsx -
-
99.27%136/137100%15/15100%0/099.27%136/137
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/__tests__/index.test.tsx.html b/coverage/components/timeline-elements/memoized/__tests__/index.test.tsx.html deleted file mode 100644 index 02ddf6954..000000000 --- a/coverage/components/timeline-elements/memoized/__tests__/index.test.tsx.html +++ /dev/null @@ -1,559 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/__tests__/index.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized/__tests__ index.test.tsx

-
- -
- 99.27% - Statements - 136/137 -
- - -
- 100% - Branches - 15/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 99.27% - Lines - 136/137 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -1591x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { forwardRef } from 'react';
-import { vi, describe, it, expect } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import { TextOrContentModel } from '../../timeline-card-content/text-or-content';
-import { DetailsTextMemo } from '../details-text-memo';
-import { SubTitleMemo } from '../subtitle-memo';
-import { TitleMemo } from '../title-memo';
- 
-describe('Title', () => {
-  it('should render title', () => {
-    const { getByText } = customRender(
-      <TitleMemo title="title" color="black" dir="rtl" active={false} />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-  });
- 
-  // should render title with url
-  it('should render title with url', () => {
-    const { getByText, getByRole } = customRender(
-      <TitleMemo
-        title="title"
-        url="https://www.google.com"
-        color="black"
-        dir="rtl"
-        active={false}
-      />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByRole('link')).toHaveAttribute('href', 'https://www.google.com');
-  });
- 
-  //should have the color and padding
-  it('should have the color and padding', () => {
-    const { getByText } = customRender(
-      <TitleMemo title="title" color="#ccc" dir="rtl" active={false} padding />,
-      { providerProps },
-    );
-    expect(getByText('title')).toHaveStyle('color: #ccc');
-    // expect(getByText('title')).toHaveStyle('padding: 0.25rem 0 0.25rem 0.5rem');
-  });
- 
-  //should accept custom class name
-  it('should accept custom class name', () => {
-    const { getByText } = customRender(
-      <TitleMemo
-        title="title"
-        color="black"
-        dir="rtl"
-        active={false}
-        padding
-        classString="custom-class"
-      />,
-      { providerProps },
-    );
-    expect(getByText('title')).toHaveClass('custom-class');
-  });
-});
- 
-describe('subtitle', () => {
-  it('should render CardSubTitle', () => {
-    const { getByText } = customRender(
-      <SubTitleMemo
-        color="red"
-        dir={'rtl'}
-        classString="card-sub-title"
-        content="card sub title"
-      ></SubTitleMemo>,
-      { providerProps },
-    );
-    expect(getByText('card sub title')).toBeInTheDocument();
-  });
- 
-  // should render the color and padding correctly
-  it('should render the color and padding correctly', () => {
-    const { getByText } = customRender(
-      <SubTitleMemo
-        color="#000"
-        dir={'rtl'}
-        classString="card-sub-title"
-        content="card sub title"
-        padding
-      ></SubTitleMemo>,
-      { providerProps },
-    );
-    expect(getByText('card sub title')).toHaveStyle('color: #000');
-    // expect(getByText('card sub title')).toHaveStyle(
-    //   'padding: 0.5rem 0 0.5rem 0.5rem',
-    // );
-  });
-});
- 
-describe('Details Text', () => {
-  // should render the details text
-  it('should render the details text', async () => {
-    const onRender = vi.fn();
-    const fn = forwardRef<HTMLSpanElement, TextOrContentModel>(() => (
-      <span>details text</span>
-    ));
-    fn.displayName = 'test';
- 
-    const { getByText } = customRender(
-      <DetailsTextMemo
-        show
-        expand
-        text={fn}
-        height={100}
-        onRender={onRender}
-        textOverlay
-      ></DetailsTextMemo>,
-      { providerProps },
-    );
-    const text = getByText('details text');
-    expect(text).toBeInTheDocument();
-    // expect(onRender).toHaveBeenCalled();
-  });
-});
- 
-describe('ShowOrHideTextButtonMemo', () => {
-  it('should not render if textOverlay is false', () => {
-    const TextComponent = forwardRef<HTMLSpanElement, TextOrContentModel>(
-      () => <span>details text</span>,
-    );
-    const { queryByRole } = customRender(
-      <DetailsTextMemo
-        show
-        expand
-        text={TextComponent}
-        height={100}
-        onRender={vi.fn()}
-        textOverlay={false}
-      ></DetailsTextMemo>,
-      { providerProps },
-    );
-    expect(queryByRole('button')).toBeNull();
-  });
-});
- 
-describe('ExpandButtonMemo', () => {
-  it('should not render if textOverlay is false', () => {
-    const { queryByRole } = customRender(
-      <DetailsTextMemo
-        show
-        expand
-        text={forwardRef(() => (
-          <span>details text</span>
-        ))}
-        height={100}
-        onRender={vi.fn()}
-        textOverlay={false}
-      ></DetailsTextMemo>,
-      { providerProps },
-    );
-    expect(queryByRole('button')).toBeNull();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/details-text-memo.tsx.html b/coverage/components/timeline-elements/memoized/details-text-memo.tsx.html deleted file mode 100644 index aeb88ce52..000000000 --- a/coverage/components/timeline-elements/memoized/details-text-memo.tsx.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/details-text-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized details-text-memo.tsx

-
- -
- 71.87% - Statements - 23/32 -
- - -
- 100% - Branches - 4/4 -
- - -
- 0% - Functions - 0/1 -
- - -
- 71.87% - Lines - 23/32 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -441x -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -11x -11x -  -11x -  -3x -3x -3x -3x -3x -3x -3x -  -3x -3x -  -11x -1x -1x -  -1x -  -  - 
import { memo } from 'react';
-import { useBackground } from '../../../hooks/useBackground';
-import { useMeasureHeight } from '../../../hooks/useMeasureHeight';
-import { DetailsTextWrapper } from '../timeline-card-media/timeline-card-media.styles';
-import { DetailsTextMemoModel } from './memoized-model';
- 
-const arePropsEqual = (
-  prev: DetailsTextMemoModel,
-  next: DetailsTextMemoModel,
-): boolean => {
-  return (
-    prev.height === next.height &&
-    prev.show === next.show &&
-    prev.expand === next.expand &&
-    prev.theme?.cardDetailsBackGround === next.theme?.cardDetailsBackGround
-  );
-};
- 
-const DetailsTextMemo = memo<DetailsTextMemoModel>(
-  ({ theme, show, expand, textOverlay, text: Text, onRender }) => {
-    const background = useBackground(theme?.cardDetailsBackGround);
-    const measureRef = useMeasureHeight(onRender);
- 
-    if (!textOverlay) return null;
- 
-    return (
-      <DetailsTextWrapper
-        ref={measureRef}
-        $expandFull={expand}
-        theme={theme}
-        $show={show}
-        background={background}
-      >
-        <Text />
-      </DetailsTextWrapper>
-    );
-  },
-  arePropsEqual,
-);
- 
-DetailsTextMemo.displayName = 'DetailsText';
- 
-export { DetailsTextMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/expand-button-memo.tsx.html b/coverage/components/timeline-elements/memoized/expand-button-memo.tsx.html deleted file mode 100644 index 9ae3d1836..000000000 --- a/coverage/components/timeline-elements/memoized/expand-button-memo.tsx.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/expand-button-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized expand-button-memo.tsx

-
- -
- 95.83% - Statements - 23/24 -
- - -
- 40% - Branches - 2/5 -
- - -
- 0% - Functions - 0/1 -
- - -
- 95.83% - Lines - 23/24 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -371x -1x -1x -  -  -  -  -  -  -  -1x -1x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -  -2x -1x -1x -  -1x -  -  - 
import { memo, useMemo } from 'react';
-import { MaximizeIcon, MinimizeIcon } from '../../icons';
-import { ExpandButton } from '../timeline-card-media/timeline-card-media-buttons';
-import { ExpandButtonModel } from './memoized-model';
- 
-/**
- * Renders a button to expand or collapse timeline card content.
- * @param {ExpandButtonModel} props - The expand button properties
- * @returns {JSX.Element | null} The expand/collapse button
- */
-const ExpandButtonMemo = memo<ExpandButtonModel>(
-  ({ theme, expanded, onExpand, textOverlay }: ExpandButtonModel) => {
-    const label = useMemo(() => {
-      return expanded ? 'Minimize' : 'Maximize';
-    }, [expanded]);
- 
-    return textOverlay ? (
-      <ExpandButton
-        onPointerDown={onExpand}
-        onKeyDown={(ev) => ev.key === 'Enter' && onExpand?.(ev)}
-        theme={theme}
-        aria-expanded={expanded}
-        tabIndex={0}
-        aria-label={label}
-        title={label}
-      >
-        {expanded ? <MinimizeIcon /> : <MaximizeIcon />}
-      </ExpandButton>
-    ) : null;
-  },
-  (prev, next) => prev.expanded === next.expanded,
-);
- 
-ExpandButtonMemo.displayName = 'Expand Button';
- 
-export { ExpandButtonMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/index.html b/coverage/components/timeline-elements/memoized/index.html deleted file mode 100644 index 1c8154c1c..000000000 --- a/coverage/components/timeline-elements/memoized/index.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized - - - - - - - - - -
-
-

All files components/timeline-elements/memoized

-
- -
- 91.17% - Statements - 124/136 -
- - -
- 78.57% - Branches - 22/28 -
- - -
- 40% - Functions - 2/5 -
- - -
- 91.17% - Lines - 124/136 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
details-text-memo.tsx -
-
71.87%23/32100%4/40%0/171.87%23/32
expand-button-memo.tsx -
-
95.83%23/2440%2/50%0/195.83%23/24
memoized-model.ts -
-
0%0/00%1/10%1/10%0/0
show-hide-button.tsx -
-
95.45%21/2240%2/50%0/195.45%21/22
subtitle-memo.tsx -
-
95.83%23/24100%4/4100%0/095.83%23/24
title-memo.tsx -
-
100%34/34100%9/9100%1/1100%34/34
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/memoized-model.ts.html b/coverage/components/timeline-elements/memoized/memoized-model.ts.html deleted file mode 100644 index 4e2ba9e49..000000000 --- a/coverage/components/timeline-elements/memoized/memoized-model.ts.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/memoized-model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized memoized-model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '../../../models/Theme';
-import React, { ReactNode } from 'react';
- 
-/**
- * Common properties shared by multiple interfaces.
- */
-type common = {
-  classString?: string; // CSS class string
-  color?: string; // Color value
-  dir?: string; // Text direction
-  fontSize?: string; // Font size
-  $padding?: boolean; // Whether to apply padding
-  theme?: Theme; // Theme object
-};
- 
-/**
- * Interface for the Title component.
- */
-export interface Title extends common {
-  active?: boolean; // Whether the title is active
-  title?: string | ReactNode; // Title text or ReactNode
-  url?: string; // URL for the title
-}
- 
-/**
- * Interface for the Content component.
- */
-export interface Content extends common {
-  content?: string | ReactNode; // Content text or ReactNode
-  padding?: boolean; // For backward compatibility
-}
- 
-/**
- * Type for the ExpandButtonModel.
- */
-export type ExpandButtonModel = {
-  expanded?: boolean; // Whether the button is expanded
-  onExpand?: (ev: React.PointerEvent | React.KeyboardEvent) => void; // Event handler for expand action
-  textOverlay?: boolean; // Whether to overlay text on the button
-} & Pick<common, 'theme'>;
- 
-/**
- * Type for the ShowHideTextButtonModel.
- */
-export type ShowHideTextButtonModel = {
-  onToggle: (ev: React.PointerEvent | React.KeyboardEvent) => void; // Event handler for toggle action
-  show?: boolean; // Whether to show the button
-  textOverlay?: boolean; // Whether to overlay text on the button
-} & Pick<common, 'theme'>;
- 
-/**
- * Type for the DetailsTextMemoModel.
- */
-export type DetailsTextMemoModel = {
-  theme?: Theme; // Theme object
-  show: boolean; // Whether to show the details text
-  expand: boolean; // Whether to expand the details text
-  textOverlay: boolean; // Whether to overlay text on the details text
-  text: React.FC; // Text component for the details text
-  height?: number; // Height of the details text
-  onRender?: (height: number) => void; // Callback function for rendering the details text
-};
- 
-/**
- * Type for the TextContentMemoModel.
- */
-export type TextContentMemoModel = Title &
-  Content &
-  ExpandButtonModel &
-  ShowHideTextButtonModel &
-  DetailsTextMemoModel;
- 
-/**
- * Type for the CardMediaHeaderMemoModel.
- */
-export type CardMediaHeaderMemoModel = Title & Content;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/show-hide-button.tsx.html b/coverage/components/timeline-elements/memoized/show-hide-button.tsx.html deleted file mode 100644 index 77bc53030..000000000 --- a/coverage/components/timeline-elements/memoized/show-hide-button.tsx.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/show-hide-button.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized show-hide-button.tsx

-
- -
- 95.45% - Statements - 21/22 -
- - -
- 40% - Branches - 2/5 -
- - -
- 0% - Functions - 0/1 -
- - -
- 95.45% - Lines - 21/22 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -351x -1x -1x -  -  -  -  -  -  -  -1x -1x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -  -2x -1x -  -1x -  -  - 
import { memo, useMemo } from 'react';
-import { MinusIcon, PlusIcon } from '../../icons';
-import { ShowHideTextButton } from '../timeline-card-media/timeline-card-media-buttons';
-import { ShowHideTextButtonModel } from './memoized-model';
- 
-/**
- * Renders a button to toggle showing or hiding text content.
- * @param {ShowHideTextButtonModel} props - Button properties
- * @returns {JSX.Element | null} The toggle button
- */
-const ShowOrHideTextButtonMemo = memo<ShowHideTextButtonModel>(
-  ({ textOverlay, onToggle, theme, show }: ShowHideTextButtonModel) => {
-    const label = useMemo(() => {
-      return show ? 'Hide Text' : 'Show Text';
-    }, [show]);
- 
-    return textOverlay ? (
-      <ShowHideTextButton
-        onPointerDown={onToggle}
-        theme={theme}
-        tabIndex={0}
-        onKeyDown={(ev) => ev.key === 'Enter' && onToggle?.(ev)}
-        aria-label={label}
-        title={label}
-      >
-        {show ? <MinusIcon /> : <PlusIcon />}
-      </ShowHideTextButton>
-    ) : null;
-  },
-);
- 
-ShowOrHideTextButtonMemo.displayName = 'Show Hide Text Button';
- 
-export { ShowOrHideTextButtonMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/subtitle-memo.tsx.html b/coverage/components/timeline-elements/memoized/subtitle-memo.tsx.html deleted file mode 100644 index 8f20ff496..000000000 --- a/coverage/components/timeline-elements/memoized/subtitle-memo.tsx.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/subtitle-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized subtitle-memo.tsx

-
- -
- 95.83% - Statements - 23/24 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 0/0 -
- - -
- 95.83% - Lines - 23/24 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -371x -1x -1x -  -1x -  -  -  -  -  -  -1x -1x -43x -  -43x -37x -37x -37x -37x -37x -37x -37x -37x -  -37x -37x -6x -43x -1x -  -1x -  -1x -  -  - 
import cls from 'classnames';
-import React, { useContext } from 'react';
-import { CardSubTitleSemantic } from '../timeline-card-content/timeline-card-content.styles';
-import { Content } from './memoized-model';
-import { GlobalContext } from '../../GlobalContext';
- 
-/**
- * Renders the subtitle content for the timeline card using configurable semantic tags.
- * @param {Content} props - Subtitle properties
- * @returns {JSX.Element | null} The rendered subtitle
- */
-const SubTitleMemo = React.memo<Content>(
-  ({ content, color, dir, theme, fontSize, classString, padding }: Content) => {
-    const { semanticTags } = useContext(GlobalContext);
- 
-    return content ? (
-      <CardSubTitleSemantic
-        as={semanticTags?.cardSubtitle ?? 'span'}
-        style={{ color }}
-        dir={dir}
-        theme={theme}
-        $fontSize={fontSize}
-        className={cls('card-sub-title', classString)}
-        $padding={padding}
-      >
-        {content}
-      </CardSubTitleSemantic>
-    ) : null;
-  },
-  (prev, next) =>
-    prev.theme?.cardSubtitleColor === next.theme?.cardSubtitleColor,
-);
- 
-SubTitleMemo.displayName = 'Timeline Content';
- 
-export { SubTitleMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/memoized/title-memo.tsx.html b/coverage/components/timeline-elements/memoized/title-memo.tsx.html deleted file mode 100644 index d20e22966..000000000 --- a/coverage/components/timeline-elements/memoized/title-memo.tsx.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/title-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized title-memo.tsx

-
- -
- 100% - Statements - 34/34 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 34/34 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -511x -1x -  -  -  -  -1x -1x -  -  -  -  -  -  -1x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -  -45x -37x -37x -37x -37x -37x -37x -37x -37x -  -37x -3x -3x -3x -  -34x -  -37x -8x -45x -  -1x -  -1x - 
import cls from 'classnames';
-import {
-  CardTitleAnchor,
-  CardTitleSemantic,
-} from '../timeline-card-content/timeline-card-content.styles';
-import { Title } from './memoized-model';
-import React, { useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
- 
-/**
- * Renders the timeline's title with optional link using configurable semantic tags.
- * @param {Title} props - Title properties
- * @returns {JSX.Element | null} The rendered title
- */
-const TitleMemoComponent = ({
-  title,
-  url,
-  theme,
-  color,
-  dir,
-  active,
-  fontSize = '1rem',
-  classString = '',
-}: Title) => {
-  const { semanticTags } = useContext(GlobalContext);
- 
-  return title ? (
-    <CardTitleSemantic
-      as={semanticTags?.cardTitle ?? 'span'}
-      className={cls(active ? 'active' : '', { [classString]: true })}
-      theme={theme}
-      style={{ color }}
-      dir={dir}
-      $fontSize={fontSize}
-      data-class={classString}
-    >
-      {url ? (
-        <CardTitleAnchor href={url} target="_blank" rel="noreferrer">
-          {title}
-        </CardTitleAnchor>
-      ) : (
-        title
-      )}
-    </CardTitleSemantic>
-  ) : null;
-};
- 
-export const TitleMemo = React.memo(TitleMemoComponent);
- 
-TitleMemo.displayName = 'Timeline Title';
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/nested-timeline-renderer/index.html b/coverage/components/timeline-elements/nested-timeline-renderer/index.html deleted file mode 100644 index bb9e1831d..000000000 --- a/coverage/components/timeline-elements/nested-timeline-renderer/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/nested-timeline-renderer - - - - - - - - - -
-
-

All files components/timeline-elements/nested-timeline-renderer

-
- -
- 11.53% - Statements - 3/26 -
- - -
- 100% - Branches - 0/0 -
- - -
- 0% - Functions - 0/1 -
- - -
- 11.53% - Lines - 3/26 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
nested-timeline-renderer.tsx -
-
11.53%3/26100%0/00%0/111.53%3/26
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html b/coverage/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html deleted file mode 100644 index e5bcf4e0d..000000000 --- a/coverage/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/nested-timeline-renderer nested-timeline-renderer.tsx

-
- -
- 11.53% - Statements - 3/26 -
- - -
- 100% - Branches - 0/0 -
- - -
- 0% - Functions - 0/1 -
- - -
- 11.53% - Lines - 3/26 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -441x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
import React from 'react';
-import { TimelineModel } from '@models/TimelineModel';
- 
-interface NestedTimelineRendererProps {
-  items: any[];
-  nestedCardHeight?: number;
-  mode?: string;
-  isChild?: boolean;
-}
- 
-// This component will be used to dynamically load the Timeline component
-// to avoid circular dependency issues
-const NestedTimelineRenderer: React.FC<NestedTimelineRendererProps> = ({
-  items,
-  nestedCardHeight,
-  mode = 'HORIZONTAL',
-  isChild,
-}) => {
-  const [TimelineComponent, setTimelineComponent] =
-    React.useState<React.ComponentType<TimelineModel> | null>(null);
- 
-  // Dynamically import the Timeline component only when needed
-  React.useEffect(() => {
-    import('../../timeline/timeline').then((module) => {
-      setTimelineComponent(() => module.default);
-    });
-  }, []);
- 
-  if (!TimelineComponent) {
-    return <div>Loading nested timeline...</div>;
-  }
- 
-  return (
-    <TimelineComponent
-      items={items}
-      mode={mode as any}
-      nestedCardHeight={nestedCardHeight}
-      isChild={isChild}
-    />
-  );
-};
- 
-export default NestedTimelineRenderer;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html b/coverage/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html deleted file mode 100644 index 32b6a4f3d..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html +++ /dev/null @@ -1,364 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ content-footer.test.tsx

-
- -
- 100% - Statements - 78/78 -
- - -
- 100% - Branches - 5/5 -
- - -
- 0% - Functions - 0/1 -
- - -
- 100% - Lines - 78/78 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -941x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
import userEvent from '@testing-library/user-event';
-import { createRef } from 'react';
-import { describe, expect, it, vi } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import { ContentFooter } from '../content-footer';
-import { ContentFooterProps } from '../header-footer.model';
- 
-const commonProps: ContentFooterProps = {
-  canShow: false,
-  onExpand: () => {},
-  paused: false,
-  progressRef: createRef(),
-  remainInterval: 0,
-  showMore: false,
-  showReadMore: false,
-  startWidth: 0,
-  textContentIsLarge: false,
-  triangleDir: 'up',
-};
- 
-describe('ContentFooter', () => {
-  //should match snapshot
-  it('should match snapshot', () => {
-    const { container } = customRender(
-      <ContentFooter {...commonProps} startWidth={300} paused={false} />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  //should render read more button when text content is large
-  it('should render read more button when text content is large', () => {
-    const { getByText } = customRender(
-      <ContentFooter
-        {...commonProps}
-        showReadMore
-        textContentIsLarge
-        canShow
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('read more')).toBeInTheDocument();
-    expect(getByText('read more')).toBeVisible();
-  });
- 
-  //should render read less button when text content is large
-  it('should render read less button when text content is large', () => {
-    const { getByText } = customRender(
-      <ContentFooter
-        {...commonProps}
-        showReadMore
-        textContentIsLarge
-        canShow
-        showMore
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('read less')).toBeInTheDocument();
-    expect(getByText('read less')).toBeVisible();
-  });
- 
-  //should call onExpand when read more button is clicked
-  it('should call onExpand when read more button is clicked', async () => {
-    const onExpand = vi.fn();
-    const user = userEvent.setup();
- 
-    const { getByText } = customRender(
-      <ContentFooter
-        {...commonProps}
-        showReadMore
-        textContentIsLarge
-        canShow
-        onExpand={onExpand}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    await user.click(getByText('read more'));
-    expect(onExpand).toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html b/coverage/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html deleted file mode 100644 index 4dbd1909e..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ content-header.test.tsx

-
- -
- 100% - Statements - 42/42 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 42/42 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -521x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
import { describe } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import { ContentHeader } from '../content-header';
- 
-describe('Content Header', () => {
-  // should render the title and subtitle of the card
-  it('should render the title and subtitle of the card', () => {
-    const { getByText } = customRender(
-      <ContentHeader title="title" content="content" />,
-      {
-        providerProps: {
-          ...providerProps,
-          media: null,
-        },
-      },
-    );
- 
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByText('content')).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot', () => {
-    const { container } = customRender(
-      <ContentHeader title="title" content="content" />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render the link if url is provided
-  it('should render the link if url is provided', () => {
-    const { getByText, getByRole } = customRender(
-      <ContentHeader
-        title="title"
-        content="content"
-        url="http://www.google.com"
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByRole('link')).toHaveAttribute('href', 'http://www.google.com');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html b/coverage/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html deleted file mode 100644 index c12e94bb2..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ details-text.test.tsx

-
- -
- 100% - Statements - 76/76 -
- - -
- 100% - Branches - 12/12 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 76/76 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90  -1x -1x -  -1x -1x -  -1x -6x -6x -6x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
// test utils
-import { customRender, providerProps } from 'src/components/common/test';
-import { DetailsText } from '../details-text';
- 
-describe('DetailsText', () => {
-  let props;
- 
-  beforeEach(() => {
-    props = {
-      detailedText: 'Hello world',
-    };
-  });
- 
-  describe('rendering', () => {
-    test('renders without crashing', () => {
-      customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
-    });
- 
-    test('renders the TextContent component', () => {
-      const { getByText } = customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
-      expect(getByText('Hello world')).toBeInTheDocument();
-    });
-  });
- 
-  describe('props', () => {
-    test('passes showMore prop to TextContent', async () => {
-      const { getByText } = customRender(<DetailsText {...props} showMore />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
- 
-      expect(getByText('Hello world').parentElement).toHaveAttribute(
-        'aria-expanded',
-        'true',
-      );
-    });
- 
-    test('passes theme prop to TimelineContentDetailsWrapper', () => {
-      const { getByText } = customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
- 
-      expect(getByText('Hello world').parentElement).toHaveStyle({
-        'scrollbar-color': `${providerProps.theme.primary} default`,
-      });
-    });
-  });
- 
-  describe('context', () => {
-    test('uses context values', () => {
-      // mock GlobalContext
-      const { getByText } = customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-          borderLessCards: true,
-        },
-      });
- 
-      expect(getByText('Hello world').parentElement).toHaveStyle({
-        width: 'calc(100% - 0.5rem)',
-      });
-    });
-  });
- 
-  describe('accessibility', () => {
-    test('content has aria-expanded attribute reflecting state', () => {
-      const { getByText } = customRender(<DetailsText {...props} showMore />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
-      expect(getByText('Hello world').parentElement).toHaveAttribute(
-        'aria-expanded',
-        'true',
-      );
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/__tests__/index.html b/coverage/components/timeline-elements/timeline-card-content/__tests__/index.html deleted file mode 100644 index cffb0503b..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/__tests__/index.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-content/__tests__

-
- -
- 98.31% - Statements - 351/357 -
- - -
- 100% - Branches - 37/37 -
- - -
- 66.66% - Functions - 2/3 -
- - -
- 98.31% - Lines - 351/357 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
content-footer.test.tsx -
-
100%78/78100%5/50%0/1100%78/78
content-header.test.tsx -
-
100%42/42100%4/4100%0/0100%42/42
details-text.test.tsx -
-
100%76/76100%12/12100%0/0100%76/76
text_or_content.test.tsx -
-
100%53/53100%5/5100%0/0100%53/53
timeline-card-content.test.tsx -
-
94.44%102/108100%11/11100%2/294.44%102/108
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html b/coverage/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html deleted file mode 100644 index 84c9a7d8a..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ text_or_content.test.tsx

-
- -
- 100% - Statements - 53/53 -
- - -
- 100% - Branches - 5/5 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 53/53 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x - 
// Imports
-import { getDefaultClassNames } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { getTextOrContent } from '../text-or-content';
- 
-describe('getTextOrContent', () => {
-  const classNames = getDefaultClassNames();
- 
-  it('renders TimelineContentDetails when detailedText is string', () => {
-    const TextContent = getTextOrContent({
-      detailedText: 'Hello World',
-    });
- 
-    const { getByText } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-      },
-    });
-    expect(getByText('Hello World')).toBeInTheDocument();
-  });
- 
-  it('renders TimelineContentDetails with xss when parseDetailsAsHTML is true', () => {
-    const TextContent = getTextOrContent({
-      detailedText: '<b>Hello</b>',
-    });
- 
-    const { container } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-        parseDetailsAsHTML: true,
-      },
-    });
- 
-    expect(container.firstChild).toHaveTextContent('Hello'); // xss sanitized
-  });
- 
-  it('renders TimelineSubContent when detailedText is array', () => {
-    const TextContent = getTextOrContent({
-      detailedText: ['Line 1', 'Line 2'],
-    });
- 
-    const { getAllByText } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-      },
-    });
-    expect(getAllByText('Line 1')[0]).toBeInTheDocument();
-    expect(getAllByText('Line 2')[0]).toBeInTheDocument();
-  });
- 
-  it('passes showMore prop to TimelineContentDetails', () => {
-    const TextContent = getTextOrContent({
-      detailedText: 'Text',
-      showMore: true,
-    });
- 
-    const { getByText } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-      },
-    });
-    expect(getByText('Text')).toHaveClass('active');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html b/coverage/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html deleted file mode 100644 index f73c60b54..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html +++ /dev/null @@ -1,478 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ timeline-card-content.test.tsx

-
- -
- 94.44% - Statements - 102/108 -
- - -
- 100% - Branches - 11/11 -
- - -
- 100% - Functions - 2/2 -
- - -
- 94.44% - Lines - 102/108 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -1321x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -  -1x -1x -1x -  -  -1x -  -1x -6x -1x -  -  -1x -1x -  -1x -  -1x -  -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { render, screen, waitFor } from '@testing-library/react';
-import GlobalContextProvider from 'src/components/GlobalContext';
-import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
-import { customRender, providerProps } from '../../../common/test';
-import TimelineCardContent from '../timeline-card-content';
- 
-describe('TimelineCardContent', () => {
-  beforeAll(() => {
-    Object.defineProperty(window, 'matchMedia', {
-      value: vi.fn().mockImplementation((query) => ({
-        addEventListener: vi.fn(),
-        dispatchEvent: vi.fn(),
-        matches: false,
-        media: query,
-        onchange: null,
-        removeEventListener: vi.fn(),
-      })),
-      writable: true,
-    });
- 
-    // ResizeObserver is already mocked globally in common/test/index.tsx
-  });
- 
-  afterEach(() => {
-    vi.resetAllMocks();
-  });
- 
-  // should render the component successfully
-  it('should render the component successfully', () => {
-    const { getByTestId } = render(<TimelineCardContent />);
- 
-    expect(getByTestId('timeline-card-content')).toBeInTheDocument();
-    // expect(getByTestId('timeline-card-content')).toBeVisible();
-  });
- 
-  //should render the title
-  it('should render the title', () => {
-    render(<TimelineCardContent title="title" />);
- 
-    expect(screen.getByText('title')).toBeInTheDocument();
-    expect(screen.getByText('title')).toBeVisible();
-  });
- 
-  // should render the detailedText when a string is passed
-  it('should render the detailedText when a string is passed', () => {
-    render(
-      <GlobalContextProvider toolbarPosition="bottom" textDensity="HIGH">
-        <TimelineCardContent detailedText="detailedText" />
-      </GlobalContextProvider>,
-    );
- 
-    expect(screen.getByText('detailedText')).toBeInTheDocument();
-    expect(screen.getByText('detailedText')).toBeVisible();
-  });
- 
-  // should render the detailedText when a array of strings is passed
-  it('should render the detailedText when a array of strings is passed', () => {
-    render(
-      <GlobalContextProvider toolbarPosition="bottom" textDensity="HIGH">
-        <TimelineCardContent detailedText={['detailedText', 'text 2']} />
-      </GlobalContextProvider>,
-    );
- 
-    expect(screen.getByText('detailedText')).toBeInTheDocument();
-    expect(screen.getByText('text 2')).toBeInTheDocument();
-    expect(screen.getByText('detailedText')).toBeVisible();
-    expect(screen.getByText('text 2')).toBeVisible();
-  });
- 
-  // should render media as expected. check if a image is rendered as expected
-  it('should render media as expected. check if a image is rendered as expected', async () => {
-    const { getByTestId } = customRender(
-      <TimelineCardContent
-        media={{
-          source: {
-            type: 'IMAGE',
-            url: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
-          },
-          type: 'IMAGE',
-        }}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    await waitFor(
-      () => {
-        expect(getByTestId('timeline-card-content-image')).toBeInTheDocument();
-        expect(getByTestId('timeline-card-content-image')).toHaveAttribute(
-          'src',
-          'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
-        );
-      },
-      {
-        timeout: 2000,
-      },
-    );
-  });
- 
-  // should render the media as expected. check if a video is rendered as expected
-  it('should render the media as expected. check if a video is rendered as expected', async () => {
-    const { getByTestId } = customRender(
-      <TimelineCardContent
-        media={{
-          source: {
-            type: 'VIDEO',
-            url: 'https://www.youtube.com/embed/2G3x2-m9OOI',
-          },
-          type: 'VIDEO',
-        }}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    await waitFor(
-      () => {
-        expect(getByTestId('timeline-card-content-video')).toBeInTheDocument();
-        expect(getByTestId('timeline-card-content-video')).toHaveAttribute(
-          'src',
-          'https://www.youtube.com/embed/2G3x2-m9OOI?enablejsapi=1',
-        );
-      },
-      {
-        timeout: 2000,
-      },
-    );
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html b/coverage/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html deleted file mode 100644 index a06b5c336..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/card-animations.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content card-animations.styles.ts

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -461x -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  - 
import { keyframes } from 'styled-components';
- 
-export const reveal = keyframes`
-  0% {
-    opacity: 0;
-    transform: scale(0.95);
-  }
-  100% {
-    opacity: 1;
-    transform: scale(1);
-  }
-`;
- 
-export const slideInFromTop = keyframes`
-  0% {
-    opacity: 0;
-    transform: translateY(-50%);
-  }
-  100% {
-    opacity: 1;
-    transform: translateY(0);
-  }
-`;
- 
-export const slideInFromLeft = keyframes`
-  0% {
-    opacity: 0;
-    transform: translateX(-50%);
-  }
-  100% {
-    opacity: 1;
-    transform: translateX(0);
-  }
-`;
- 
-export const slideFromRight = keyframes`
-  0% {
-    opacity: 0;
-    transform: translateX(50%);
-  }
-  100% {
-    opacity: 1;
-    transform: translateX(0);
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/content-footer.tsx.html b/coverage/components/timeline-elements/timeline-card-content/content-footer.tsx.html deleted file mode 100644 index 7b1fea4aa..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/content-footer.tsx.html +++ /dev/null @@ -1,349 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/content-footer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content content-footer.tsx

-
- -
- 91.11% - Statements - 41/45 -
- - -
- 91.66% - Branches - 11/12 -
- - -
- 50% - Functions - 1/2 -
- - -
- 91.11% - Lines - 41/45 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -891x -  -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -36x -36x -36x -36x -36x -36x -36x -  -36x -36x -1x -1x -1x -1x -36x -36x -  -36x -  -  -  -  -32x -36x -  -36x -36x -36x -3x -3x -3x -3x -  -  -  -  -3x -3x -3x -  -3x -3x -3x -3x -3x -33x -36x -  -36x -  -  - 
import {
-  FunctionComponent,
-  PointerEvent,
-  useCallback,
-  useContext,
-  useMemo,
-} from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import ChevronIcon from '../../icons/chev-right';
-import { ContentFooterProps } from './header-footer.model';
-import { ChevronIconWrapper, ShowMore } from './timeline-card-content.styles';
- 
-/**
- * ContentFooter
- *
- * A functional component that renders the footer of the timeline card.
- * It displays the read more/less button, progress bar, and triangle icon.
- * The read more/less button appears only if the content is large.
- * The progress bar and triangle icon are displayed only if the card is in slideshow mode.
- *
- * @property {boolean} showProgressBar - Determines if progress bar should be displayed.
- * @property {Function} onExpand - Function called when expanding content.
- * @property {string} triangleDir - Direction of the triangle icon.
- * @property {boolean} showMore - Determines if 'read more' should be displayed.
- * @property {boolean} textContentIsLarge - Determines if text content is large.
- * @property {boolean} showReadMore - Determines if 'read more' button should be displayed.
- * @property {number} remainInterval - Remaining interval for progress bar.
- * @property {boolean} paused - Determines if progress is paused.
- * @property {number} startWidth - Starting width of progress bar.
- * @property {boolean} canShow - Determines if the element can be shown.
- * @property {React.RefObject} progressRef - Ref to the progress bar.
- * @property {boolean} isNested - Determines if component is nested.
- * @property {boolean} isResuming - Determines if slideshow is resuming.
- *
- * @returns {JSX.Element} ContentFooter component.
- */
-const ContentFooter: FunctionComponent<ContentFooterProps> = ({
-  onExpand,
-  showMore,
-  textContentIsLarge,
-  showReadMore,
-  canShow,
-}: ContentFooterProps) => {
-  const { theme } = useContext(GlobalContext);
- 
-  const handleClick = useCallback(
-    (ev: PointerEvent) => {
-      ev.stopPropagation();
-      ev.preventDefault();
-      onExpand();
-    },
-    [onExpand],
-  );
- 
-  const canShowMore = useMemo(() => {
-    // Only show read more when:
-    // 1. The feature is enabled (showReadMore)
-    // 2. The text is actually large enough to need expansion (textContentIsLarge)
-    // 3. The parent says it's valid to show (canShow) - this might indicate we have detailedText
-    return showReadMore && textContentIsLarge && canShow;
-  }, [showReadMore, textContentIsLarge, canShow]);
- 
-  return (
-    <>
-      {canShowMore ? (
-        <ShowMore
-          className="show-more"
-          onPointerDown={handleClick}
-          onKeyUp={(event) => {
-            if (event.key === 'Enter') {
-              onExpand();
-            }
-          }}
-          show={canShow ? 'true' : 'false'}
-          theme={theme}
-          tabIndex={0}
-        >
-          {<span>{showMore ? 'read less' : 'read more'}</span>}
-          <ChevronIconWrapper collapsed={showMore ? 'true' : 'false'}>
-            <ChevronIcon />
-          </ChevronIconWrapper>
-        </ShowMore>
-      ) : null}
-    </>
-  );
-};
- 
-export { ContentFooter };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/content-header.tsx.html b/coverage/components/timeline-elements/timeline-card-content/content-header.tsx.html deleted file mode 100644 index 83cacaf06..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/content-header.tsx.html +++ /dev/null @@ -1,304 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/content-header.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content content-header.tsx

-
- -
- 85.36% - Statements - 35/41 -
- - -
- 90.9% - Branches - 10/11 -
- - -
- 100% - Functions - 0/0 -
- - -
- 85.36% - Lines - 35/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -741x -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -37x -37x -  -37x -  -37x -37x -  -  -37x -  -  -  -  -  -  -  -37x -  -37x -27x -27x -27x -27x -27x -27x -27x -10x -  -  -  -37x -27x -27x -27x -27x -27x -27x -10x -37x -  -37x -1x -  -  -1x -  -  - 
import { FunctionComponent, memo, useContext, useMemo } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { SubTitleMemo } from '../memoized/subtitle-memo';
-import { TitleMemo } from '../memoized/title-memo';
-import { ContentHeaderProps } from './header-footer.model';
-import {
-  CardTitleSemantic,
-  TimelineCardHeader,
-} from './timeline-card-content.styles';
- 
-/**
- * ContentHeader component
- * This component renders the header of the timeline card including the title and subtitle.
- * It doesn't render the title and subtitle if the card has media.
- * The title and subtitle are memoized to prevent unnecessary re-renders.
- *
- * @property {string} title - The title of the card.
- * @property {string} url - The URL of the card.
- * @property {boolean} media - Indicates whether the card has media or not.
- * @property {string} content - The main content of the card.
- * @returns {JSX.Element} The ContentHeader component.
- */
-const ContentHeader: FunctionComponent<ContentHeaderProps> = memo(
-  ({ title, url, media, content, cardTitle }: ContentHeaderProps) => {
-    // Using context to get global values
-    const { fontSizes, classNames, theme, isMobile, semanticTags } =
-      useContext(GlobalContext);
- 
-    const isNotMedia = useMemo(() => !media, [media]);
- 
-    return (
-      <TimelineCardHeader>
-        {/* Render title if there is no media */}
- 
-        {isMobile ? (
-          <CardTitleSemantic
-            as={semanticTags?.cardTitle ?? 'span'}
-            $fontSize={'1.2rem'}
-            theme={theme}
-          >
-            {cardTitle}
-          </CardTitleSemantic>
-        ) : null}
- 
-        {isNotMedia ? (
-          <TitleMemo
-            title={title}
-            theme={theme}
-            url={url}
-            fontSize={fontSizes?.cardTitle}
-            classString={classNames?.cardTitle}
-          />
-        ) : null}
- 
-        {/* Render subtitle if there is no media */}
- 
-        {isNotMedia ? (
-          <SubTitleMemo
-            content={content}
-            theme={theme}
-            fontSize={fontSizes?.cardSubtitle}
-            classString={classNames?.cardSubTitle}
-          />
-        ) : null}
-      </TimelineCardHeader>
-    );
-  },
-);
- 
-// Setting display name for easier debugging
-ContentHeader.displayName = 'ContentHeader';
- 
-export { ContentHeader };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/details-text.model.ts.html b/coverage/components/timeline-elements/timeline-card-content/details-text.model.ts.html deleted file mode 100644 index 44970c4ba..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/details-text.model.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/details-text.model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content details-text.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { TimelineContentModel } from '@models/TimelineContentModel';
-import { ReactNode } from 'react';
- 
-export type DetailsTextProps = {
-  cardActualHeight?: number;
-  contentDetailsClass?: string;
-  customContent?: ReactNode;
-  detailedText: TimelineContentModel['detailedText'];
-  detailsHeight?: number;
-  gradientColor?: string;
-  showMore?: boolean;
-  timelineContent: TimelineContentModel['timelineContent'];
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/details-text.tsx.html b/coverage/components/timeline-elements/timeline-card-content/details-text.tsx.html deleted file mode 100644 index fc7c22561..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/details-text.tsx.html +++ /dev/null @@ -1,283 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/details-text.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content details-text.tsx

-
- -
- 100% - Statements - 54/54 -
- - -
- 50% - Branches - 1/2 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 54/54 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -671x -1x -  -1x -1x -  -1x -1x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -  -38x -38x -38x -38x -38x -38x -38x -  -38x -38x -38x -38x -38x -38x -  -38x -38x -  -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -  -38x -38x -38x -38x -  -38x -38x -  -38x -1x -  -1x -  -  - 
import { forwardRef, useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { DetailsTextProps } from './details-text.model';
-import { getTextOrContent } from './text-or-content';
-import { TimelineContentDetailsWrapper } from './timeline-card-content.styles';
- 
-const DetailsText = forwardRef<HTMLDivElement, DetailsTextProps>(
-  (prop, ref) => {
-    const {
-      showMore,
-      cardActualHeight,
-      detailsHeight,
-      gradientColor,
-      customContent,
-      timelineContent,
-      detailedText,
-      contentDetailsClass,
-    } = prop;
- 
-    const {
-      useReadMore,
-      borderLessCards,
-      contentDetailsHeight,
-      textOverlay,
-      theme,
-    } = useContext(GlobalContext);
- 
-    const TextContent = getTextOrContent({
-      detailedText,
-      showMore,
-      theme,
-      timelineContent,
-    });
- 
-    return (
-      <>
-        {/* detailed text */}
-        <TimelineContentDetailsWrapper
-          aria-expanded={showMore}
-          className={contentDetailsClass}
-          $customContent={!!customContent}
-          ref={ref}
-          theme={theme}
-          $useReadMore={useReadMore}
-          $borderLess={borderLessCards}
-          $showMore={showMore}
-          $cardHeight={!textOverlay ? cardActualHeight : null}
-          $contentHeight={detailsHeight}
-          height={contentDetailsHeight}
-          $textOverlay={textOverlay}
-          $gradientColor={gradientColor}
-        >
-          {customContent ?? (
-            <TextContent
-              {...{ detailedText, showMore, theme, timelineContent }}
-            />
-          )}
-        </TimelineContentDetailsWrapper>
-      </>
-    );
-  },
-);
- 
-DetailsText.displayName = 'Details Text';
- 
-export { DetailsText };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/header-footer.model.ts.html b/coverage/components/timeline-elements/timeline-card-content/header-footer.model.ts.html deleted file mode 100644 index 5342bd688..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/header-footer.model.ts.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/header-footer.model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content header-footer.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineContentModel } from '@models/TimelineContentModel';
- 
-export type ContentHeaderProps = Pick<
-  TimelineContentModel,
-  'theme' | 'url' | 'title' | 'media' | 'content' | 'cardTitle'
->;
- 
-export type ContentFooterProps = {
-  canShow: boolean;
-  isNested?: boolean;
-  onExpand: () => void;
-  remainInterval: number;
-  showMore: boolean;
-  showReadMore?: boolean | '';
-  startWidth: number;
-  textContentIsLarge: boolean;
-  theme?: Theme;
-  triangleDir?: string;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/index.html b/coverage/components/timeline-elements/timeline-card-content/index.html deleted file mode 100644 index b3d0d8070..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/index.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-content

-
- -
- 76.04% - Statements - 638/839 -
- - -
- 76.41% - Branches - 162/212 -
- - -
- 75% - Functions - 30/40 -
- - -
- 76.04% - Lines - 638/839 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
card-animations.styles.ts -
-
100%5/5100%0/0100%0/0100%5/5
content-footer.tsx -
-
91.11%41/4591.66%11/1250%1/291.11%41/45
content-header.tsx -
-
85.36%35/4190.9%10/11100%0/085.36%35/41
details-text.model.ts -
-
0%0/00%1/10%1/10%0/0
details-text.tsx -
-
100%54/5450%1/2100%0/0100%54/54
header-footer.model.ts -
-
0%0/00%1/10%1/10%0/0
text-or-content.tsx -
-
92.63%88/9579.31%23/29100%6/692.63%88/95
timeline-card-content.styles.ts -
-
65.1%125/19275.36%52/6968.96%20/2965.1%125/192
timeline-card-content.tsx -
-
71.25%290/40772.41%63/87100%1/171.25%290/407
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/text-or-content.tsx.html b/coverage/components/timeline-elements/timeline-card-content/text-or-content.tsx.html deleted file mode 100644 index ea07ec645..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/text-or-content.tsx.html +++ /dev/null @@ -1,514 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/text-or-content.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content text-or-content.tsx

-
- -
- 92.63% - Statements - 88/95 -
- - -
- 79.31% - Branches - 23/29 -
- - -
- 100% - Functions - 6/6 -
- - -
- 92.63% - Lines - 88/95 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144  -  -1x -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -2x -2x -2x -2x -2x -2x -2x -  -4x -4x -  -  -  -  -  -4x -4x -4x -4x -4x -4x -4x -4x -  -4x -4x -  -2x -2x -  -  -1x -  -1x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -  -42x -42x -42x -  -  -42x -42x -40x -1x -39x -40x -  -2x -2x -42x -42x -42x -42x -42x -42x -  -  -42x -42x -1x -1x -1x -1x -1x -1x -41x -42x -  -42x -42x -  -42x -42x -42x -42x -42x -42x -  -42x -42x -  -42x -  -42x -42x -  -  -  -42x -42x -42x -  -42x -42x -42x -  -42x -  -42x -42x -  -  - 
import { TimelineContentModel } from '@models/TimelineContentModel';
-import { TimelineProps } from '@models/TimelineModel';
-import {
-  ForwardRefExoticComponent,
-  ReactNode,
-  forwardRef,
-  useContext,
-  useMemo,
-} from 'react';
-import xss from 'xss';
-import { GlobalContext } from '../../GlobalContext';
-import {
-  TimelineContentDetails,
-  TimelineSubContent,
-} from './timeline-card-content.styles';
- 
-// Define the type for the TextOrContentModel
-export type TextOrContentModel = Pick<
-  TimelineContentModel,
-  'timelineContent' | 'theme' | 'detailedText'
-> & {
-  showMore?: boolean;
-};
- 
-// Function to render an array of text
-const renderTextArray: (
-  p: Pick<TimelineProps, 'parseDetailsAsHTML' | 'fontSizes' | 'theme'> & {
-    cardTextClassName: string;
-    detailedText: (string | ReactNode)[];
-  },
-) => ReactNode = ({
-  fontSizes,
-  parseDetailsAsHTML,
-  theme,
-  detailedText,
-  cardTextClassName,
-}) => {
-  return detailedText.map((text, index) => {
-    // Only apply xss if text is a string
-    const props =
-      parseDetailsAsHTML && typeof text === 'string'
-        ? {
-            dangerouslySetInnerHTML: {
-              __html: xss(text),
-            },
-          }
-        : null;
-    return (
-      <TimelineSubContent
-        key={`timeline-text-${typeof text === 'string' ? text.substring(0, 10) : ''}-${index}`}
-        fontSize={fontSizes?.cardText}
-        className={cardTextClassName}
-        theme={theme}
-        {...props}
-      >
-        {parseDetailsAsHTML ? null : text}
-      </TimelineSubContent>
-    );
-  });
-};
- 
-// Function to get the TextOrContent component
-const getTextOrContent: (
-  p: TextOrContentModel,
-) => ForwardRefExoticComponent<TextOrContentModel> = ({
-  timelineContent,
-  theme,
-  detailedText,
-  showMore,
-}) => {
-  const TextOrContent = forwardRef<HTMLParagraphElement, TextOrContentModel>(
-    (prop, ref) => {
-      const isTextArray = Array.isArray(detailedText);
-      const { fontSizes, classNames, parseDetailsAsHTML, textDensity } =
-        useContext(GlobalContext);
- 
-      const shouldNotShowText = useMemo(() => {
-        return (parseDetailsAsHTML && !isTextArray) || textDensity === 'LOW';
-      }, [isTextArray, parseDetailsAsHTML, textDensity]);
- 
-      // Generate the text content based on detailedText
-      const getTextContent = () => {
-        if (!isTextArray) {
-          return parseDetailsAsHTML && typeof detailedText === 'string'
-            ? xss(detailedText)
-            : detailedText;
-        }
- 
-        return renderTextArray({
-          cardTextClassName: classNames?.cardText,
-          detailedText: detailedText as (string | ReactNode)[],
-          fontSizes,
-          parseDetailsAsHTML,
-          theme,
-        });
-      };
- 
-      // Create props for HTML content if needed
-      const getTextContentProps = (textContent) => {
-        if (parseDetailsAsHTML && !isTextArray) {
-          return {
-            dangerouslySetInnerHTML: {
-              __html: xss(textContent),
-            },
-          };
-        }
-        return {};
-      };
- 
-      const renderDetailedContent = (textContent) => {
-        const textContentProps = getTextContentProps(textContent);
- 
-        return (
-          <TimelineContentDetails
-            className={showMore ? 'active' : ''}
-            ref={ref}
-            theme={theme}
-            {...textContentProps}
-          >
-            {shouldNotShowText ? null : textContent}
-          </TimelineContentDetails>
-        );
-      };
- 
-      const renderTimelineContent = () => {
-        if (timelineContent) {
-          return <div ref={ref}>{timelineContent}</div>;
-        }
- 
-        const textContent = getTextContent();
-        return textContent ? renderDetailedContent(textContent) : null;
-      };
- 
-      return renderTimelineContent();
-    },
-  );
- 
-  TextOrContent.displayName = 'Text Or Content';
- 
-  return TextOrContent;
-};
- 
-export { getTextOrContent };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html b/coverage/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html deleted file mode 100644 index aa6ae3b90..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html +++ /dev/null @@ -1,1762 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content timeline-card-content.styles.ts

-
- -
- 65.1% - Statements - 125/192 -
- - -
- 75.36% - Branches - 52/69 -
- - -
- 68.96% - Functions - 20/29 -
- - -
- 65.1% - Lines - 125/192 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560  -  -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -38x -  -38x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -38x -  -38x -  -  -  -  -  -  -  -38x -  -  -  -  -  -38x -38x -  -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -1x -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -1x -  -  -  -  -1x -1x -  -1x -1x -  -  -  -1x -  -  -  -1x -38x -  -  -  -  -  -  -  -1x -  -  -1x -38x -  -  -  -1x -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -1x -  -  -1x -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -1x -1x -  -  -1x -  -  -  -1x -1x -148x -1x -  -  -  -  -  -  -1x -1x -  -  -1x -  -  -  -  -1x -1x -113x -1x -  -  -  -  -  -  -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -1x -  -  -1x -38x -36x -1x -  -1x -38x -38x -38x -38x -38x -38x -38x -2x -1x -  -1x -  -  -1x -38x -38x -38x -38x -38x -38x -38x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TextDensity, TimelineProps } from '@models/TimelineModel';
-import styled, { css, keyframes } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
-import { linearGradient } from '../timeline-card-media/timeline-card-media.styles';
-import {
-  reveal,
-  slideFromRight,
-  slideInFromLeft,
-  slideInFromTop,
-} from './card-animations.styles';
- 
-// Common types
-type ContentT = Pick<
-  TimelineProps,
-  'theme' | 'slideShow' | 'mode' | 'borderLessCards'
->;
- 
-// Reusable styles with vendor prefixes
-const baseFontStyles = css`
-  margin: 0;
-  width: 100%;
-  text-align: left;
-`;
- 
-const baseCardStyles = css<{ $theme?: Theme }>`
-  background: ${(p) => p.$theme?.cardBgColor};
-  border-radius: 8px;
-  -webkit-box-shadow: 
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  box-shadow:
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  -webkit-transition: 
-    -webkit-transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
-  transition:
-    transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
-`;
- 
-const scrollbarStyles = css<{ theme?: Theme }>`
-  scrollbar-color: ${(p) => p.theme?.primary} default;
-  scrollbar-width: thin;
- 
-  &::-webkit-scrollbar {
-    width: 0.3em;
-  }
- 
-  &::-webkit-scrollbar-track {
-    background-color: ${(p) => p.theme?.cardBgColor};
-  }
- 
-  &::-webkit-scrollbar-thumb {
-    background-color: ${(p) => p.theme?.primary};
-    border-radius: 3px;
-  }
-`;
- 
-// Animation helpers
-const getSlideShowAnimation = (props) => {
-  const { $slideShowActive, $active, $slideShowType, $branchDir } = props;
- 
-  if (!$slideShowActive || !$active) return '';
- 
-  if ($slideShowType === 'slide_in') {
-    return css`
-      animation: ${slideInFromTop} 0.5s ease-in-out;
-    `;
-  }
- 
-  if ($slideShowType === 'slide_from_sides') {
-    if ($branchDir === 'left') {
-      return css`
-        animation: ${slideInFromLeft} 0.5s ease-in-out;
-      `;
-    }
-    if ($branchDir === 'right') {
-      return css`
-        animation: ${slideFromRight} 0.5s ease-in-out;
-      `;
-    }
-  }
- 
-  return css`
-    animation: ${reveal} 0.5s ease-in-out;
-  `;
-};
- 
-const getSlideShowVisibility = (props) => {
-  const { $slideShowActive, $active } = props;
- 
-  if ($slideShowActive && $active) {
-    return css`
-      opacity: 1;
-      animation-timing-function: ease-in-out;
-      animation-duration: 0.5s;
-    `;
-  }
- 
-  if ($slideShowActive && !$active) {
-    return css`
-      opacity: 0;
-    `;
-  }
- 
-  return '';
-};
- 
-// Slide animation for progress bar
-const slideAnimation = (start?: number, end?: number) => keyframes`
-  0% {
-    width: ${start}px;
-  }
-  100% {
-    width: ${end}px;
-  }
-`;
- 
-// Extract shared styles into a utility function
-const sharedSemanticStyles = css<{
-  $fontSize?: string;
-  $padding?: boolean;
-  theme: Theme;
-}>`
-  ${baseFontStyles}
-  font-size: ${(p) => p.$fontSize || '1.1rem'};
-  font-weight: 600;
-  margin-bottom: 0.5rem;
-  padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')};
-  display: block;
-`;
- 
-// Card Components
-export const TimelineItemContentWrapper = styled.section<
-  {
-    $active?: boolean;
-    $borderLessCards?: TimelineProps['borderLessCards'];
-    $branchDir?: string;
-    $customContent?: boolean;
-    $highlight?: boolean;
-    $isNested?: boolean;
-    $maxWidth?: number;
-    $minHeight?: number;
-    $noMedia?: boolean;
-    $slideShow?: TimelineProps['slideShow'];
-    $slideShowActive?: boolean;
-    $slideShowType?: TimelineProps['slideShowType'];
-    $textDensity?: TextDensity;
-    $textOverlay?: boolean;
-    $theme?: Theme;
-  } & ContentT
->`
-  ${baseCardStyles}
-  align-items: flex-start;
-  display: flex;
-  flex-direction: column;
-  justify-content: flex-start;
-  line-height: 1.5;
-  margin: 0;
-  max-width: ${(p) => p.$maxWidth}px;
-  position: relative;
-  padding: 1rem;
-  z-index: ${zIndex.timelineCard};
-  overflow: hidden;
-  width: 100%;
- 
-  // Handle text density and height
-  ${({ $textDensity, $customContent, $minHeight }) =>
-    `${$customContent ? 'height' : 'min-height'}: ${$minHeight}px`};
- 
-  ${(p) => (p.$textOverlay ? `min-height: ${p.$minHeight}px` : '')};
-  ${(p) => (p.$textOverlay ? 'height: 0' : '')};
- 
-  // Focus state
-  &:focus {
-    outline: 1px solid ${(p) => p.$theme?.primary};
-  }
- 
-  // Highlight effect
-  ${(p) =>
-    p.$highlight &&
-    css`
-      &:hover {
-        transform: translateY(-2px);
-        box-shadow:
-          0 2px 5px ${p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.08)'},
-          0 8px 16px ${p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'};
-      }
-    `}
- 
-  // Nested card styling
-  ${(p) =>
-    p.$isNested &&
-    css`
-      background: ${p.$theme?.nestedCardBgColor};
-      box-shadow: 0 1px 2px ${p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.05)'};
-    `}
- 
-  // Animations
-  ${getSlideShowAnimation}
-  ${getSlideShowVisibility}
-`;
- 
-// Header Components
-export const TimelineCardHeader = styled.header`
-  width: 100%;
-  padding: 0;
-  margin-bottom: 0.5rem;
-`;
- 
-export const CardTitle = styled.h1<{
-  $fontSize: string;
-  $padding?: boolean;
-  dir?: string;
-  theme: Theme;
-}>`
-  ${baseFontStyles}
-  color: ${(p) => p.theme.cardTitleColor};
-  font-size: ${(p) => p.$fontSize && '1.1rem'};
-  font-weight: 600;
-  margin-bottom: 0.5rem;
-  padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')};
- 
-  &.active {
-    color: ${(p) => p.theme.primary};
-  }
-`;
- 
-export const CardSubTitle = styled.h2<{
-  $fontSize?: string;
-  $padding?: boolean;
-  dir?: string;
-  theme?: Theme;
-}>`
-  ${baseFontStyles}
-  color: ${(p) => p.theme.cardSubtitleColor};
-  font-size: ${(p) => p.$fontSize && '0.9rem'};
-  font-weight: 500;
-  margin-bottom: 0.25rem;
-  padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')};
-`;
- 
-// Refactor CardTitleSemantic to use shared styles
-export const CardTitleSemantic = styled.h1.withConfig({
-  shouldForwardProp: (prop) =>
-    !['$fontSize', '$padding', 'theme'].includes(prop),
-})<{
-  $fontSize: string;
-  $padding?: boolean;
-  dir?: string;
-  theme: Theme;
-  as?: string;
-}>`
-  ${sharedSemanticStyles}
-  color: ${(p) => p.theme.cardTitleColor};
- 
-  &.active {
-    color: ${(p) => p.theme.primary};
-  }
-`;
- 
-// Refactor CardSubTitleSemantic to use shared styles
-export const CardSubTitleSemantic = styled.span.withConfig({
-  shouldForwardProp: (prop) =>
-    !['$fontSize', '$padding', 'theme'].includes(prop),
-})<{
-  $fontSize?: string;
-  $padding?: boolean;
-  dir?: string;
-  theme: Theme;
-  as?: string;
-}>`
-  ${sharedSemanticStyles}
-  color: ${(p) => p.theme.cardSubtitleColor};
-  font-size: ${(p) => p.$fontSize || '0.9rem'};
-`;
- 
-export const CardTitleAnchor = styled.a`
-  color: inherit;
- 
-  &:active {
-    color: inherit;
-  }
-`;
- 
-// Content Components
-export const TimelineContentDetails = styled.p<{ theme?: Theme }>`
-  font-size: 0.85rem;
-  font-weight: 400;
-  margin: 0;
-  width: 100%;
-  color: ${(p) => p.theme.cardDetailsColor};
-  line-height: 1.5;
-`;
- 
-export const TimelineSubContent = styled.span<{
-  fontSize?: string;
-  theme?: Theme;
-}>`
-  margin-bottom: 0.5rem;
-  display: block;
-  font-size: ${(p) => p.fontSize && '0.8rem'};
-  color: ${(p) => p.theme.cardDetailsColor};
-`;
- 
-export const TimelineContentDetailsWrapper = styled.div<{
-  $borderLess?: boolean;
-  $cardHeight?: number | null;
-  $contentHeight?: number;
-  $customContent?: boolean;
-  $gradientColor?: string | null;
-  $showMore?: boolean;
-  $textOverlay?: boolean;
-  $useReadMore?: boolean;
-  branchDir?: string;
-  height?: number;
-  theme?: Theme;
-}>`
-  ${scrollbarStyles}
-  align-items: flex-start;
-  display: flex;
-  flex-direction: column;
-  margin: 0;
-  position: relative;
-  overflow-x: hidden;
-  overflow-y: auto;
-  transition: max-height 0.25s ease-in-out;
-  width: ${(p) => (p.$borderLess ? 'calc(100% - 0.5rem)' : '100%')};
-  padding: 0;
-  background: ${(p) => p.theme?.cardDetailsBackGround || p.theme?.cardBgColor};
- 
-  // Height handling based on different conditions
-  ${({ $useReadMore, $customContent, $showMore, height = 0, $textOverlay }) =>
-    $useReadMore && !$customContent && !$showMore && !$textOverlay
-      ? `max-height: ${height}px;`
-      : 'height: 100%'};
- 
-  ${({
-    $cardHeight = 0,
-    $contentHeight = 0,
-    height = 0,
-    $showMore,
-    $textOverlay,
-  }) =>
-    $showMore && !$textOverlay
-      ? `max-height: ${($cardHeight ?? 0) + ($contentHeight ?? 0) - height}px;`
-      : ''}
- 
-  ${(p) => (p.$customContent ? `height: 100%;` : '')}
- 
-  // Animation for show more
-  ${({
-    height = 0,
-    $cardHeight = 0,
-    $contentHeight = 0,
-    $showMore,
-    $useReadMore,
-  }) =>
-    $showMore && $useReadMore && $cardHeight
-      ? css`
-          animation: ${keyframes`
-            0% {
-              max-height: ${height}px;
-            }
-            100% {
-             max-height: ${$cardHeight + $contentHeight - height}px;
-            }
-          `} 0.25s ease-in-out;
-        `
-      : ''}
-      
-  &.show-less {
-    scrollbar-width: none;
-    &::-webkit-scrollbar {
-      width: 0;
-    }
-    overflow: hidden;
-  }
- 
-  // Gradient for "show more" functionality
-  --rc-gradient-color: ${(p) => p.$gradientColor};
-  ${linearGradient}
-`;
- 
-// Interactive Elements
-export const ShowMore = styled.button<{
-  show?: 'true' | 'false';
-  theme?: Theme;
-}>`
-  align-items: center;
-  align-self: flex-end;
-  border-radius: 4px;
-  cursor: pointer;
-  display: ${(p) => (p.show === 'true' ? 'flex' : 'none')};
-  font-size: 0.75rem;
-  justify-self: flex-end;
-  margin: auto 0.5em 0.5em auto;
-  padding: 0.25em;
-  color: ${(p) => p.theme.primary};
-  border: 0;
-  background: none;
- 
-  &:hover {
-    text-decoration: underline;
-  }
-`;
- 
-export const SlideShowProgressBar = styled.progress<{
-  $color?: string;
-  $duration?: number;
-  $resuming?: boolean;
-  $startWidth?: number;
-}>`
-  background: ${(p) => p.color};
-  bottom: -0.75em;
-  display: block;
-  height: 4px;
-  left: 50%;
-  transform: translateX(-50%);
-  position: absolute;
-  border-radius: 2px;
-  border: 0;
-  outline: none; /* Remove the outline/border */
- 
-  /* Remove the default styling from progress element */
-  &::-webkit-progress-bar {
-    background-color: transparent;
-    border: 0;
-  }
- 
-  &::-webkit-progress-value {
-    background-color: ${(p) => p.color || '#007bff'};
-    border-radius: 2px;
-  }
- 
-  &::-moz-progress-bar {
-    background-color: ${(p) => p.color || '#007bff'};
-    border-radius: 2px;
-  }
- 
-  // Animation control - simplified without pause
-  ${(p) => {
-    if (p.$startWidth && p.$startWidth > 0) {
-      return css`
-        animation: ${slideAnimation(p.$startWidth, 0)} ${p.$duration}ms ease-in;
-        animation-play-state: running;
-      `;
-    } else {
-      return css`
-        width: ${p.$startWidth}px;
-      `;
-    }
-  }}
- 
-  svg {
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 100%;
-  }
-`;
- 
-// Icon Wrappers
-export const ChevronIconWrapper = styled.span<{ collapsed?: 'true' | 'false' }>`
-  align-items: center;
-  display: flex;
-  height: 1.25em;
-  justify-content: center;
-  margin-left: 0.2em;
-  margin-top: 0.2em;
-  width: 1.25em;
-  transform: ${(p) =>
-    p.collapsed === 'false' ? 'rotate(90deg)' : 'rotate(-90deg)'};
- 
-  svg {
-    height: 100%;
-    width: 100%;
-  }
-`;
- 
-export const TriangleIconWrapper = styled.span<{
-  dir?: string;
-  offset?: number;
-  theme?: Theme;
-}>`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 1.5rem;
-  height: 1.5rem;
-  position: absolute;
-  top: calc(50%);
-  background: ${(p) => p.theme.cardBgColor};
-  transform: translateY(-50%) rotate(225deg);
-  z-index: ${zIndex.timelineCard - 3}; /* Arrow tip should be below the card */
-  ${(p) =>
-    p.dir === 'left' ? `right: ${p.offset}px;` : `left: ${p.offset}px;`}
- 
-  & svg {
-    width: 100%;
-    height: 100%;
-    fill: #fff;
-  }
-`;
- 
-// Search highlighting
-export const Mark = styled.mark<{ theme: Theme }>`
-  background-color: ${(p) =>
-    p.theme?.searchHighlightColor ||
-    (p.theme?.primary ? `${p.theme.primary}30` : 'rgba(255, 217, 0, 0.3)')};
-  color: inherit;
-  font-weight: 600;
-  padding: 0.1em 0.25em;
-  margin: 0 -0.1em;
-  border-radius: 2px;
-  box-decoration-break: clone;
-  -webkit-box-decoration-break: clone;
-  transition:
-    background-color 0.2s ease-out,
-    box-shadow 0.15s ease-out;
- 
-  &[data-current-match='true'] {
-    background-color: ${(p) => {
-      if (p.theme?.searchHighlightColor) {
-        // If custom search highlight color is provided, make it more intense
-        const color = p.theme.searchHighlightColor;
-        // Extract opacity and increase it for current match
-        if (color.includes('rgba')) {
-          return color.replace(/0\.\d+\)$/, '0.6)');
-        }
-        return color;
-      }
- 
-      // Fallback logic
-      if (p.theme?.primary) {
-        return p.theme.cardBgColor === '#1f2937'
-          ? `rgba(96, 165, 250, 0.6)` // More intense for current match in dark mode
-          : `${p.theme.primary}50`; // Standard for light mode
-      }
-      return 'rgba(255, 217, 0, 0.5)';
-    }};
-    box-shadow: 0 0 0 1px
-      ${(p) => {
-        if (p.theme?.iconColor) {
-          return p.theme.iconColor;
-        }
- 
-        // Fallback logic
-        if (p.theme?.primary) {
-          return p.theme.cardBgColor === '#1f2937'
-            ? 'rgba(96, 165, 250, 0.8)'
-            : p.theme.primary;
-        }
-        return 'rgba(255, 217, 0, 0.5)';
-      }};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html b/coverage/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html deleted file mode 100644 index 157d34821..000000000 --- a/coverage/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html +++ /dev/null @@ -1,1618 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/timeline-card-content.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content timeline-card-content.tsx

-
- -
- 71.25% - Statements - 290/407 -
- - -
- 72.41% - Branches - 63/87 -
- - -
- 100% - Functions - 1/1 -
- - -
- 71.25% - Lines - 290/407 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512  -  -1x -1x -1x -  -  -  -  -  -  -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -4x -4x -4x -  -4x -  -  -4x -  -  -4x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -48x -48x -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -48x -48x -48x -48x -48x -48x -48x -  -  -48x -34x -48x -  -48x -34x -48x -  -48x -34x -34x -32x -28x -28x -  -48x -  -48x -34x -48x -  -48x -  -34x -34x -28x -28x -  -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -34x -34x -28x -28x -48x -  -  -48x -34x -6x -6x -48x -  -  -48x -38x -  -  -  -38x -  -  -  -38x -  -  -  -38x -38x -38x -48x -  -  -48x -38x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -48x -  -  -48x -34x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -48x -  -  -48x -34x -  -  -48x -  -  -48x -34x -  -  -34x -34x -34x -48x -  -  -48x -48x -  -  -  -  -  -  -  -  -  -  -  -48x -48x -  -48x -  -  -  -48x -  -48x -  -  -  -  -  -  -  -  -  -  -  -  -48x -  -  -48x -34x -32x -32x -2x -48x -  -48x -34x -48x -  -48x -34x -34x -34x -34x -34x -48x -  -  -48x -34x -34x -12x -5x -  -48x -  -  -48x -  -34x -  -  -  -  -  -  -  -34x -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -34x -  -34x -34x -34x -  -  -48x -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -  -  -48x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -  -  -48x -  -  -  -  -  -  -  -  -48x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -  -48x -  -48x -1x -1x -  -1x - 
import { TimelineContentModel } from '@models/TimelineContentModel';
-import { MediaState } from '@models/TimelineMediaModel';
-import { hexToRGBA } from '@utils/index';
-import cls from 'classnames';
-import React, {
-  useCallback,
-  useContext,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from 'react';
-import { useSlideshow } from 'src/components/effects/useSlideshow';
-import { useCardSize } from '../../../hooks/useCardSize';
-import { GlobalContext } from '../../GlobalContext';
-// Remove the Timeline import to break the circular dependency
-// import Timeline from '../../timeline/timeline';
-import CardMedia from '../timeline-card-media/timeline-card-media';
-import { ContentFooter } from './content-footer';
-import { ContentHeader } from './content-header';
-import { DetailsText } from './details-text';
-import { getTextOrContent } from './text-or-content';
-import { TimelineItemContentWrapper } from './timeline-card-content.styles';
-import NestedTimelineRenderer from '../nested-timeline-renderer/nested-timeline-renderer';
- 
-// Custom equality function for React.memo to prevent unnecessary re-renders
-const arePropsEqual = (
-  prevProps: TimelineContentModel,
-  nextProps: TimelineContentModel,
-): boolean => {
-  // Always re-render if active state changes
-  if (prevProps.active !== nextProps.active) return false;
- 
-  // Re-render if slideshow state changes
-  if (prevProps.slideShowActive !== nextProps.slideShowActive) return false;
- 
-  // Re-render if hasFocus changes
-  if (prevProps.hasFocus !== nextProps.hasFocus) return false;
- 
-  // Only re-render content-related props if they actually change
-  if (prevProps.content !== nextProps.content) return false;
-  if (prevProps.detailedText !== nextProps.detailedText) return false;
-  if (prevProps.title !== nextProps.title) return false;
-  if (prevProps.cardTitle !== nextProps.cardTitle) return false;
- 
-  // Skip re-render if media props stay the same
-  if (JSON.stringify(prevProps.media) !== JSON.stringify(nextProps.media))
-    return false;
- 
-  // Skip re-render if theme stays the same
-  if (JSON.stringify(prevProps.theme) !== JSON.stringify(nextProps.theme))
-    return false;
- 
-  // Skip re-render if items (for nested timeline) stay the same
-  if (JSON.stringify(prevProps.items) !== JSON.stringify(nextProps.items))
-    return false;
- 
-  // Default to true - don't re-render
-  return true;
-};
- 
-const TimelineCardContent: React.FunctionComponent<TimelineContentModel> =
-  React.memo(
-    ({
-      active,
-      content,
-      detailedText,
-      id,
-      media,
-      onShowMore,
-      slideShowActive,
-      onElapsed,
-      theme,
-      onClick,
-      customContent,
-      hasFocus,
-      flip,
-      branchDir,
-      url,
-      timelineContent,
-      items,
-      isNested,
-      nestedCardHeight,
-      title,
-      cardTitle,
-    }: TimelineContentModel) => {
-      const [showMore, setShowMore] = useState(false);
-      const detailsRef = useRef<HTMLDivElement | null>(null);
-      const containerRef = useRef<HTMLDivElement | null>(null);
-      const progressRef = useRef<HTMLProgressElement | null>(null);
-      const isFirstRender = useRef(true);
- 
-      const [hasBeenActivated, setHasBeenActivated] = useState(false);
-      const [isResuming, setIsResuming] = useState(false);
- 
-      const {
-        mode,
-        cardHeight,
-        slideItemDuration = 2000,
-        useReadMore,
-        cardWidth,
-        borderLessCards,
-        disableAutoScrollOnClick,
-        classNames,
-        textOverlay,
-        slideShowType,
-        showProgressOnSlideshow,
-        disableInteraction,
-        highlightCardsOnHover,
-        textDensity,
-      } = useContext(GlobalContext);
- 
-      const {
-        paused,
-        remainInterval,
-        startWidth,
-        tryPause,
-        setupTimer,
-        setStartWidth,
-      } = useSlideshow(
-        progressRef,
-        active,
-        slideShowActive,
-        slideItemDuration,
-        id,
-        onElapsed,
-      );
- 
-      const { cardActualHeight, detailsHeight, textContentLarge } = useCardSize(
-        {
-          containerRef,
-          detailsRef,
-          setStartWidth,
-        },
-      );
- 
-      // Memoize all calculated values to prevent re-renders
-      const canShowProgressBar = useMemo(() => {
-        return active && slideShowActive && showProgressOnSlideshow;
-      }, [active, slideShowActive, showProgressOnSlideshow]);
- 
-      const canShowMore = useMemo(() => {
-        return !!detailedText;
-      }, [detailedText]);
- 
-      const canShowReadMore = useMemo(() => {
-        return (
-          useReadMore &&
-          detailedText &&
-          !customContent &&
-          textDensity === 'HIGH'
-        );
-      }, [useReadMore, detailedText, customContent, textDensity]);
- 
-      const canShowNestedTimeline = useMemo(() => {
-        return items && items.length > 0;
-      }, [items]);
- 
-      const canShowDetailsText = useMemo(() => {
-        // Hide details when using text overlay with media, when density is LOW, otherwise show if content exists
-        return (
-          (detailedText ?? customContent ?? timelineContent) &&
-          !(textOverlay && media) &&
-          textDensity !== 'LOW'
-        );
-      }, [
-        detailedText,
-        customContent,
-        timelineContent,
-        textOverlay,
-        media,
-        textDensity,
-      ]);
- 
-      // Reset details scroll position when toggling details
-      useEffect(() => {
-        const detailsEle = detailsRef.current;
-        if (detailsEle) {
-          detailsEle.scrollTop = 0;
-        }
-      }, [showMore]);
- 
-      // Handle card activation
-      useEffect(() => {
-        if (active && !hasBeenActivated) {
-          setHasBeenActivated(true);
-        }
-      }, [active, hasBeenActivated]);
- 
-      // Setup timer when card becomes active
-      useEffect(() => {
-        if (!slideItemDuration) {
-          return;
-        }
- 
-        if (active && slideShowActive) {
-          setupTimer(slideItemDuration);
-        }
- 
-        if (active && hasFocus && containerRef.current) {
-          containerRef.current.focus();
-        }
- 
-        if (!slideShowActive) {
-          setHasBeenActivated(false);
-        }
-      }, [active, slideShowActive, slideItemDuration, hasFocus, setupTimer]);
- 
-      // Set focus when needed and ensure entire card row is completely visible
-      useEffect(() => {
-        if (hasFocus && active && containerRef.current) {
-          containerRef.current.focus();
-          
-          // Ensure the entire vertical item row is completely visible when it receives focus
-          setTimeout(() => {
-            if (containerRef.current) {
-              const isVerticalMode = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-              
-              if (isVerticalMode) {
-                // In vertical mode, scroll the entire vertical-item-row into view
-                const verticalItemRow = containerRef.current.closest('[data-testid="vertical-item-row"]');
-                if (verticalItemRow) {
-                  verticalItemRow.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                } else {
-                  // Fallback to card content if row not found
-                  containerRef.current.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                }
-              } else {
-                // In horizontal mode, use 'nearest' for optimal positioning
-                containerRef.current.scrollIntoView({
-                  behavior: 'smooth',
-                  block: 'nearest',
-                  inline: 'nearest'
-                });
-              }
-            }
-          }, 0);
-        }
-      }, [hasFocus, active, mode]);
- 
-      // Ensure card alignment during slideshow, independent of hasFocus state
-      useEffect(() => {
-        if (active && slideShowActive && containerRef.current) {
-          // During slideshow, ensure the active card is properly aligned and visible
-          setTimeout(() => {
-            if (containerRef.current) {
-              const isVerticalMode = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-              
-              if (isVerticalMode) {
-                // In vertical mode, scroll the entire vertical-item-row into view
-                const verticalItemRow = containerRef.current.closest('[data-testid="vertical-item-row"]');
-                if (verticalItemRow) {
-                  verticalItemRow.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                } else {
-                  // Fallback to card content if row not found
-                  containerRef.current.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                }
-              } else {
-                // In horizontal mode, use 'nearest' for optimal positioning
-                containerRef.current.scrollIntoView({
-                  behavior: 'smooth',
-                  block: 'nearest',
-                  inline: 'nearest'
-                });
-              }
-            }
-          }, 100); // Slightly longer delay for slideshow to ensure proper DOM updates
-        }
-      }, [active, slideShowActive, mode]);
- 
-      // Detect when resuming from pause
-      useEffect(() => {
-        if (!paused && !isFirstRender.current) {
-          setIsResuming(true);
-        }
-      }, [paused]);
- 
-      // Track first render
-      useEffect(() => {
-        isFirstRender.current = false;
- 
-        // Cleanup function
-        return () => {
-          isFirstRender.current = true;
-        };
-      }, []);
- 
-      // Memoize handler functions
-      const handleMediaState = useCallback(
-        (state: MediaState) => {
-          if (!slideShowActive) {
-            return;
-          }
-          if (state.playing) {
-            tryPause();
-          } else if (state.paused) {
-            if (paused && id && onElapsed) {
-              onElapsed(id);
-            }
-          }
-        },
-        [slideShowActive, tryPause, paused, id, onElapsed],
-      );
- 
-      const handleCardClick = useCallback(() => {
-        if (onClick && !disableInteraction && !disableAutoScrollOnClick) {
-          onClick(id);
-        }
-      }, [onClick, id, disableInteraction, disableAutoScrollOnClick]);
- 
-      const toggleShowMore = useCallback(() => {
-        if ((active && paused) || !slideShowActive) {
-          setShowMore((prev) => !prev);
-          onShowMore?.();
-          // Use setTimeout to ensure the DOM has updated before focusing
-          setTimeout(() => {
-            if (containerRef.current) {
-              containerRef.current.focus();
-              // Force focus styles to be visible
-              containerRef.current.classList.add('focus-visible');
-            }
-          }, 0);
-        }
-      }, [active, paused, slideShowActive, onShowMore]);
- 
-      // Memoize computed values to prevent re-renders
-      const triangleDir = useMemo(() => {
-        if (mode === 'VERTICAL_ALTERNATING') {
-          return flip ? 'right' : 'left';
-        }
-        return null;
-      }, [mode, flip]);
- 
-      const gradientColor = useMemo(() => {
-        return hexToRGBA(theme?.cardBgColor ?? '#fff', 0.4);
-      }, [theme?.cardBgColor]);
- 
-      const contentDetailsClass = useMemo(() => {
-        return cls(
-          'card-description',
-          classNames?.cardText ?? '',
-          borderLessCards ? 'no-border' : '',
-        );
-      }, [classNames?.cardText, borderLessCards]);
- 
-      // Get the accessible label for the card
-      const accessibleLabel = useMemo(() => {
-        return (
-          (typeof cardTitle === 'string' ? cardTitle : null) ??
-          (typeof title === 'string' ? title : null) ??
-          'Timeline card'
-        );
-      }, [cardTitle, title]);
- 
-      // Create the detailsText component for text overlay mode using the proper function
-      const detailsTextComponent = useMemo(() => {
-        // Only create the component if we need it for text overlay mode
-        if (textOverlay && (detailedText ?? customContent ?? timelineContent)) {
-          return getTextOrContent({
-            timelineContent,
-            theme,
-            detailedText,
-            showMore,
-          });
-        }
-        return null;
-      }, [
-        textOverlay,
-        detailedText,
-        customContent,
-        timelineContent,
-        theme,
-        showMore,
-      ]);
- 
-      // The card's minimum height
-      const cardMinHeight = useMemo(() => {
-        if (textOverlay && media) {
-          return cardHeight;
-        } else if (!isNested) {
-          return cardHeight;
-        } else {
-          return nestedCardHeight;
-        }
-      }, [textOverlay, media, isNested, cardHeight, nestedCardHeight]);
- 
-      return (
-        <TimelineItemContentWrapper
-          as="article"
-          aria-label={accessibleLabel}
-          ref={containerRef}
-          onClick={handleCardClick}
-          className={`timeline-card-content ${active ? 'active' : ''} ${
-            classNames?.card ?? ''
-          }`}
-          data-testid="timeline-card-content"
-          data-item-id={id}
-          $active={active}
-          $branchDir={branchDir}
-          $slideShowActive={slideShowActive}
-          $slideShowType={slideShowType}
-          tabIndex={active ? 0 : -1}
-          onDoubleClick={toggleShowMore}
-          $minHeight={cardMinHeight}
-          $maxWidth={cardWidth}
-          mode={mode}
-          $noMedia={!media}
-          $textOverlay={textOverlay}
-          $isNested={isNested}
-          $highlight={highlightCardsOnHover}
-          $borderLessCards={borderLessCards}
-          $textDensity={textDensity}
-          $customContent={!!customContent}
-          $theme={theme}
-        >
-          {/* Only show the content header if we're not using text overlay mode with media */}
-          {(!textOverlay || !media) && (
-            <ContentHeader
-              title={title}
-              url={url}
-              media={media}
-              content={content}
-              cardTitle={cardTitle}
-              theme={theme}
-            />
-          )}
- 
-          {media && (
-            <CardMedia
-              active={active}
-              cardHeight={cardHeight}
-              content={content}
-              hideMedia={showMore}
-              id={id}
-              media={media}
-              onMediaStateChange={handleMediaState}
-              slideshowActive={slideShowActive}
-              theme={theme}
-              title={typeof title === 'string' ? title : ''}
-              url={url}
-              startWidth={startWidth}
-              detailsText={detailsTextComponent}
-              paused={paused}
-              remainInterval={remainInterval}
-              showProgressBar={canShowProgressBar}
-              triangleDir={triangleDir}
-              resuming={isResuming}
-              progressRef={progressRef}
-            />
-          )}
- 
-          {canShowDetailsText && (
-            <DetailsText
-              showMore={showMore}
-              gradientColor={gradientColor}
-              detailedText={detailedText}
-              customContent={customContent}
-              timelineContent={timelineContent}
-              contentDetailsClass={contentDetailsClass}
-              cardActualHeight={cardActualHeight}
-              detailsHeight={detailsHeight}
-              ref={detailsRef}
-            />
-          )}
- 
-          {canShowNestedTimeline && (
-            <NestedTimelineRenderer
-              items={items}
-              mode={'VERTICAL'}
-              nestedCardHeight={nestedCardHeight}
-              isChild={true}
-            />
-          )}
- 
-          {canShowReadMore && canShowMore && !textOverlay && (
-            <ContentFooter
-              onExpand={toggleShowMore}
-              triangleDir={triangleDir}
-              showMore={showMore}
-              textContentIsLarge={textContentLarge}
-              showReadMore={canShowReadMore}
-              remainInterval={remainInterval}
-              startWidth={startWidth}
-              canShow={!!detailedText && !showMore}
-              isNested={isNested}
-              theme={theme}
-            />
-          )}
-        </TimelineItemContentWrapper>
-      );
-    },
-    arePropsEqual,
-  );
- 
-export default TimelineCardContent;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/__tests__/index.html b/coverage/components/timeline-elements/timeline-card-media/__tests__/index.html deleted file mode 100644 index e710ba7cb..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media/__tests__

-
- -
- 100% - Statements - 201/201 -
- - -
- 100% - Branches - 10/10 -
- - -
- 0% - Functions - 0/8 -
- - -
- 100% - Lines - 201/201 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-media.test.tsx -
-
100%201/201100%10/100%0/8100%201/201
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html b/coverage/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html deleted file mode 100644 index 73d5dd6a1..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html +++ /dev/null @@ -1,763 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/__tests__ timeline-card-media.test.tsx

-
- -
- 100% - Statements - 201/201 -
- - -
- 100% - Branches - 10/10 -
- - -
- 0% - Functions - 0/8 -
- - -
- 100% - Lines - 201/201 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -2271x -1x -1x -1x -  -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe } from 'vitest';
-import { customRender, providerProps } from '../../../common/test';
-import TimelineCardMedia from '../timeline-card-media';
-import { forwardRef } from 'react';
-import { TextOrContentModel } from '../../timeline-card-content/text-or-content';
- 
-describe('Timeline Card media', () => {
-  // should render the component with all the props
-  const refComponent = forwardRef<HTMLDivElement, TextOrContentModel>(
-    (props, ref) => <div ref={ref}>ref component</div>,
-  );
- 
-  refComponent.displayName = 'ref component';
-  it('should render the component with all the props', async () => {
-    const { getByText, getByAltText, getByRole } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-        title="Image title"
-        content="This is another test"
-        cardHeight={300}
-        active
-      />,
-      {
-        providerProps: { ...providerProps, semanticTags: { cardTitle: 'h1' } },
-      },
-    );
- 
-    expect(getByText('Image title')).toBeInTheDocument();
-    expect(getByText('This is another test')).toBeInTheDocument();
-    expect(getByAltText('Image')).toBeInTheDocument();
-    expect(getByRole('heading', { level: 1 })).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot ( IMAGE )', () => {
-    const { container } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        content="This is another test"
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps },
-    );
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot ( VIDEO )', () => {
-    const { container } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Video',
-          source: {
-            type: 'URL',
-            url: 'https://www.youtube.com/watch?v=9bZkp7q19f0',
-          },
-          type: 'VIDEO',
-        }}
-        detailsText={refComponent}
-        content="This is another test"
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps },
-    );
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render video media when type is VIDEO
-  it('should render video media when type is VIDEO', () => {
-    const { getByTitle } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Video',
-          source: {
-            type: 'URL',
-            url: 'https://www.youtube.com/watch?v=9bZkp7q19f0',
-          },
-          type: 'VIDEO',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps },
-    );
-    expect(getByTitle('Video')).toBeInTheDocument();
-  });
- 
-  //should render the card media in text overlay mode
-  it('should render the card media in text overlay mode', () => {
-    const customProviderProps = {
-      ...providerProps,
-      textOverlay: true,
-      semanticTags: { cardTitle: 'h1' },
-    };
- 
-    const { getByRole, getByText, getByAltText } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        content="This is another test"
-        title="Image title"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps: customProviderProps },
-    );
- 
-    expect(getByText('Image title')).toBeInTheDocument();
-    expect(getByText('This is another test')).toBeInTheDocument();
-    expect(getByAltText('Image')).toBeInTheDocument();
-    expect(getByRole('heading', { level: 1 })).toBeInTheDocument();
-  });
- 
-  // should render custom content in the card media
-  it('should render custom content in the card media', () => {
-    const { getByText } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-        content={<div>Custom content</div>}
-      />,
-      { providerProps },
-    );
- 
-    expect(getByText('Custom content')).toBeInTheDocument();
-  });
- 
-  // generate large chunks of random text
- 
-  // should render detailsText as expected IN HORIZONTAL MODE
-  it('should render detailsText as expected', () => {
-    const { getByText, getByRole } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-        title="Image title"
-        content="This is another test"
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-          mode: 'HORIZONTAL',
-          semanticTags: { cardTitle: 'h1' },
-        },
-      },
-    );
- 
-    expect(getByRole('heading', { level: 1 })).toBeInTheDocument();
-    expect(getByText('Image title')).toBeInTheDocument();
-  });
- 
-  // should render the arrow (triangleDir) as expected
-  it('should render the arrow (triangleDir) as expected', () => {
-    const { getByTestId } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps: { ...providerProps, textOverlay: true } },
-    );
-    expect(getByTestId('arrow-icon')).toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html b/coverage/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html deleted file mode 100644 index 183318811..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html +++ /dev/null @@ -1,469 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components ContentDisplay.tsx

-
- -
- 100% - Statements - 90/90 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 90/90 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -1291x -1x -  -  -  -1x -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -14x -  -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -14x -8x -8x -8x -8x -8x -8x -8x -8x -  -14x -  -14x -  -  -1x -  -  -1x - 
import React, { useRef, ReactNode } from 'react';
-import {
-  CardMediaHeader,
-  MediaDetailsWrapper,
-} from '../timeline-card-media.styles';
-import { TitleMemo } from '../../memoized/title-memo';
-import { ButtonWrapper } from '../timeline-card-media-buttons';
-import { ShowOrHideTextButtonMemo } from '../../memoized/show-hide-button';
-import { ExpandButtonMemo } from '../../memoized/expand-button-memo';
-import { SubTitleMemo } from '../../memoized/subtitle-memo';
-import { DetailsTextMemo } from '../../memoized/details-text-memo';
-import { TimelineMode } from '@models/TimelineModel';
- 
-export interface ContentDisplayProps {
-  readonly mode: TimelineMode;
-  readonly textOverlay: boolean;
-  readonly theme: any;
-  readonly expandDetails: boolean;
-  readonly showText: boolean;
-  readonly canExpand: boolean;
-  readonly canShowGradient: boolean;
-  readonly gradientColor: string | null;
-  readonly title?: ReactNode;
-  readonly active: boolean;
-  readonly url?: string;
-  readonly fontSizes: any;
-  readonly classNames: any;
-  readonly toggleText: () => void;
-  readonly toggleExpand: () => void;
-  readonly content?: ReactNode;
-  readonly canShowTextMemo: boolean;
-  readonly detailsText?: any; // Use 'any' to bypass type checking temporarily
-  readonly onDetailsTextRef: (height?: number) => void;
-}
- 
-const ContentDisplayComponent: React.FunctionComponent<ContentDisplayProps> = (
-  props,
-) => {
-  const {
-    mode,
-    textOverlay,
-    theme,
-    expandDetails,
-    showText,
-    canExpand,
-    canShowGradient,
-    gradientColor,
-    title,
-    active,
-    url,
-    fontSizes,
-    classNames,
-    toggleText,
-    toggleExpand,
-    content,
-    canShowTextMemo,
-    detailsText,
-    onDetailsTextRef,
-  } = props;
- 
-  const moreRef = useRef(null);
- 
-  return (
-    <MediaDetailsWrapper
-      mode={mode}
-      $absolutePosition={textOverlay}
-      $textInMedia={textOverlay}
-      ref={moreRef}
-      theme={theme}
-      $expandFull={expandDetails}
-      $showText={showText}
-      $expandable={canExpand}
-      $gradientColor={canShowGradient ? gradientColor : null}
-    >
-      <CardMediaHeader>
-        <TitleMemo
-          title={title}
-          theme={theme}
-          active={active}
-          url={url}
-          fontSize={fontSizes?.cardTitle}
-          classString={classNames?.cardTitle}
-        />
-        {canExpand && (
-          <ButtonWrapper>
-            <ShowOrHideTextButtonMemo
-              onToggle={toggleText}
-              show={showText}
-              textOverlay
-              theme={theme}
-            />
-            <ExpandButtonMemo
-              theme={theme}
-              expanded={expandDetails}
-              onExpand={toggleExpand}
-              textOverlay
-            />
-          </ButtonWrapper>
-        )}
-      </CardMediaHeader>
-      {showText && (
-        <SubTitleMemo
-          content={content}
-          fontSize={fontSizes?.cardSubtitle}
-          classString={classNames?.cardSubTitle}
-          padding
-          theme={theme}
-        />
-      )}
-      {canShowTextMemo && detailsText && (
-        <DetailsTextMemo
-          theme={theme}
-          show={showText}
-          expand={expandDetails}
-          text={detailsText}
-          onRender={onDetailsTextRef}
-          textOverlay={textOverlay}
-        />
-      )}
-    </MediaDetailsWrapper>
-  ) as React.ReactElement;
-};
- 
-// Export the memoized component
-export const ContentDisplay = ContentDisplayComponent;
- 
-// Add display name for DevTools
-ContentDisplay.displayName = 'ContentDisplay';
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html b/coverage/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html deleted file mode 100644 index 632d6c8f2..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components ErrorMessage.tsx

-
- -
- 80% - Statements - 4/5 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 80% - Lines - 4/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -141x -1x -  -  -  -  -  -  -  -  -1x -  -1x - 
import { memo } from 'react';
-import { ErrorMessage as StyledErrorMessage } from '../timeline-card-media.styles';
- 
-interface ErrorMessageProps {
-  message: string;
-}
- 
-/**
- * Displays an error message when media fails to load
- */
-export const LazyErrorMessage = memo(({ message }: ErrorMessageProps) => (
-  <StyledErrorMessage>{message}</StyledErrorMessage>
-));
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html b/coverage/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html deleted file mode 100644 index 4b8e9f6aa..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components ImageDisplay.tsx

-
- -
- 100% - Statements - 31/31 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 31/31 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -501x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -  -1x - 
import React, { memo } from 'react';
-import { CardImage, ImageWrapper } from '../timeline-card-media.styles';
-import { TimelineMode } from '@models/TimelineModel';
- 
-interface ImageDisplayProps {
-  url: string;
-  name: string;
-  mode: TimelineMode;
-  mediaLoaded: boolean;
-  borderLessCards: boolean;
-  mediaHeight: number;
-  imageFit?: string;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-}
- 
-/**
- * Renders an image with appropriate loading and error handling
- */
-export const ImageDisplay = memo(
-  ({
-    url,
-    name,
-    mode,
-    mediaLoaded,
-    borderLessCards,
-    mediaHeight,
-    imageFit,
-    handleMediaLoaded,
-    handleError,
-  }: ImageDisplayProps) => (
-    <ImageWrapper height={mediaHeight}>
-      <CardImage
-        src={url}
-        mode={mode}
-        onLoad={handleMediaLoaded}
-        onError={handleError}
-        $visible={mediaLoaded}
-        alt={name}
-        loading="lazy"
-        $enableBorderRadius={borderLessCards}
-        fit={imageFit}
-        data-testid="timeline-card-content-image"
-        width="100%"
-        height="auto"
-      />
-    </ImageWrapper>
-  ),
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html b/coverage/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html deleted file mode 100644 index 183f21127..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/MediaContent.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components MediaContent.tsx

-
- -
- 78.33% - Statements - 47/60 -
- - -
- 50% - Branches - 5/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 78.33% - Lines - 47/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97  -  -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -3x -3x -3x -3x -3x -3x -3x -  -3x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -3x -  -15x -15x -  -  -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -  -15x -  -  -18x -1x - 
import { MediaState } from '@models/TimelineMediaModel';
-import { TimelineMode } from '@models/TimelineModel';
-import React, { memo } from 'react';
-import { LazyErrorMessage } from './ErrorMessage';
-import { VideoPlayer } from './VideoPlayer';
-import { YoutubePlayer } from './YoutubePlayer';
-import { ImageDisplay } from './ImageDisplay';
- 
-interface MediaContentProps {
-  media: {
-    type: string;
-    source: {
-      url: string;
-    };
-    name?: string;
-  };
-  isYouTube: boolean;
-  loadFailed: boolean;
-  mediaLoaded: boolean;
-  active: boolean;
-  id: string;
-  mediaHeight: number;
-  mode: TimelineMode;
-  borderLessCards: boolean;
-  mediaSettings: any;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-  onMediaStateChange: (state: MediaState) => void;
-}
- 
-/**
- * Renders the appropriate media content based on type (video, YouTube, image)
- */
-export const MediaContent = memo(
-  ({
-    media,
-    isYouTube,
-    loadFailed,
-    mediaLoaded,
-    active,
-    id,
-    mediaHeight,
-    mode,
-    borderLessCards,
-    mediaSettings,
-    handleMediaLoaded,
-    handleError,
-    onMediaStateChange,
-  }: MediaContentProps) => {
-    if (media.type === 'VIDEO') {
-      if (isYouTube) {
-        return (
-          <YoutubePlayer
-            url={media.source.url}
-            active={active}
-            name={media.name ?? ''}
-          />
-        );
-      }
- 
-      return loadFailed ? (
-        <LazyErrorMessage message="Failed to load the video" />
-      ) : (
-        <VideoPlayer
-          url={media.source.url}
-          active={active}
-          id={id}
-          name={media.name ?? ''}
-          onMediaStateChange={onMediaStateChange}
-          handleMediaLoaded={handleMediaLoaded}
-          handleError={handleError}
-        />
-      );
-    }
- 
-    if (media.type === 'IMAGE') {
-      return loadFailed ? (
-        <LazyErrorMessage message="Failed to load the image." />
-      ) : (
-        <ImageDisplay
-          url={media.source.url}
-          name={media.name ?? ''}
-          mode={mode}
-          mediaLoaded={mediaLoaded}
-          borderLessCards={borderLessCards}
-          mediaHeight={mediaHeight}
-          imageFit={mediaSettings?.fit}
-          handleMediaLoaded={handleMediaLoaded}
-          handleError={handleError}
-        />
-      );
-    }
- 
-    return null;
-  },
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html b/coverage/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html deleted file mode 100644 index f76dfe62d..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components VideoPlayer.tsx

-
- -
- 9.43% - Statements - 5/53 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 9.43% - Lines - 5/53 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
import { MediaState } from '@models/TimelineMediaModel';
-import React, { memo, useEffect, useRef } from 'react';
-import { CardVideo } from '../timeline-card-media.styles';
- 
-interface VideoPlayerProps {
-  url: string;
-  active: boolean;
-  id: string;
-  name: string;
-  onMediaStateChange: (state: MediaState) => void;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-}
- 
-/**
- * Renders a standard video player
- */
-export const VideoPlayer = memo(
-  ({
-    url,
-    active,
-    id,
-    name,
-    onMediaStateChange,
-    handleMediaLoaded,
-    handleError,
-  }: VideoPlayerProps) => {
-    const videoRef = useRef<HTMLVideoElement>(null);
- 
-    useEffect(() => {
-      if (!videoRef.current) return;
- 
-      if (active) {
-        videoRef.current.play().catch(() => {
-          // Handle autoplay failure silently
-        });
-      } else {
-        videoRef.current.pause();
-      }
-    }, [active]);
- 
-    return (
-      <CardVideo
-        controls
-        autoPlay={active}
-        ref={videoRef}
-        onLoadedData={handleMediaLoaded}
-        data-testid="rc-video"
-        onPlay={() =>
-          onMediaStateChange({
-            id,
-            paused: false,
-            playing: true,
-          })
-        }
-        onPause={() =>
-          onMediaStateChange({
-            id,
-            paused: true,
-            playing: false,
-          })
-        }
-        onEnded={() =>
-          onMediaStateChange({
-            id,
-            paused: false,
-            playing: false,
-          })
-        }
-        onError={handleError}
-        preload="metadata"
-      >
-        <source src={url}></source>
-      </CardVideo>
-    );
-  },
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html b/coverage/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html deleted file mode 100644 index 4fc9bf574..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components YoutubePlayer.tsx

-
- -
- 100% - Statements - 14/14 -
- - -
- 50% - Branches - 1/2 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 14/14 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -261x -1x -  -  -  -  -  -  -  -  -  -  -1x -1x -3x -3x -3x -3x -3x -3x -3x -3x -3x -  -1x - 
import React, { memo } from 'react';
-import { IFrameVideo } from '../timeline-card-media.styles';
- 
-interface YoutubePlayerProps {
-  url: string;
-  active: boolean;
-  name: string;
-}
- 
-/**
- * Renders a YouTube player iframe
- */
-export const YoutubePlayer = memo(
-  ({ url, active, name }: YoutubePlayerProps) => (
-    <IFrameVideo
-      style={{ border: 'none' }}
-      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
-      allowFullScreen
-      src={`${url}${active ? '?autoplay=1&enablejsapi=1' : '?enablejsapi=1'}`}
-      title={name}
-      data-testid="timeline-card-content-video"
-      loading="lazy"
-    />
-  ),
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/components/index.html b/coverage/components/timeline-elements/timeline-card-media/components/index.html deleted file mode 100644 index 62d11b80e..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/components/index.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media/components

-
- -
- 75.49% - Statements - 191/253 -
- - -
- 68.42% - Branches - 13/19 -
- - -
- 100% - Functions - 1/1 -
- - -
- 75.49% - Lines - 191/253 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
ContentDisplay.tsx -
-
100%90/90100%6/6100%1/1100%90/90
ErrorMessage.tsx -
-
80%4/5100%0/0100%0/080%4/5
ImageDisplay.tsx -
-
100%31/31100%1/1100%0/0100%31/31
MediaContent.tsx -
-
78.33%47/6050%5/10100%0/078.33%47/60
VideoPlayer.tsx -
-
9.43%5/53100%0/0100%0/09.43%5/53
YoutubePlayer.tsx -
-
100%14/1450%1/2100%0/0100%14/14
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/hooks/index.html b/coverage/components/timeline-elements/timeline-card-media/hooks/index.html deleted file mode 100644 index 661438983..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/hooks/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media/hooks

-
- -
- 88.65% - Statements - 86/97 -
- - -
- 94.11% - Branches - 16/17 -
- - -
- 100% - Functions - 4/4 -
- - -
- 88.65% - Lines - 86/97 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useMediaLoad.ts -
-
72%18/25100%1/1100%1/172%18/25
useToggleControls.ts -
-
78.94%15/19100%1/1100%1/178.94%15/19
useViewOptions.ts -
-
100%46/4692.3%12/13100%1/1100%46/46
useYouTubeDetection.ts -
-
100%7/7100%2/2100%1/1100%7/7
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html b/coverage/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html deleted file mode 100644 index 84b72b40d..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useMediaLoad.ts

-
- -
- 72% - Statements - 18/25 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 72% - Lines - 18/25 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -18x -18x -18x -18x -18x -  -  -18x -  -18x -  -  -18x -  -  -  -  -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x - 
import { MediaState } from '@models/TimelineMediaModel';
-import { useState, useCallback } from 'react';
- 
-interface UseMediaLoadResult {
-  loadFailed: boolean;
-  mediaLoaded: boolean;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-}
- 
-/**
- * Custom hook to handle media loading state and error handling
- *
- * @param id - The ID of the media element
- * @param onMediaStateChange - Callback to notify parent component of media state changes
- * @returns Object with loading state and handler functions
- */
-export const useMediaLoad = (
-  id: string,
-  onMediaStateChange: (state: MediaState) => void,
-): UseMediaLoadResult => {
-  const [loadFailed, setLoadFailed] = useState(false);
-  const [mediaLoaded, setMediaLoaded] = useState(false);
- 
-  // This function will be invoked when the user has finished loading media
-  const handleMediaLoaded = useCallback(() => {
-    setMediaLoaded(true);
-  }, []);
- 
-  // This function handles errors when loading media
-  const handleError = useCallback(() => {
-    setLoadFailed(true);
-    onMediaStateChange({
-      id,
-      paused: false,
-      playing: false,
-    });
-  }, [onMediaStateChange, id]);
- 
-  return {
-    loadFailed,
-    mediaLoaded,
-    handleMediaLoaded,
-    handleError,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html b/coverage/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html deleted file mode 100644 index f9bee86fb..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useToggleControls.ts

-
- -
- 78.94% - Statements - 15/19 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 78.94% - Lines - 15/19 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -281x -  -  -  -  -  -1x -18x -18x -  -18x -  -  -18x -  -18x -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x - 
import { useCallback, useState } from 'react';
- 
-/**
- * Custom hook to handle text display toggle functionality
- * @returns Object with toggle states and functions
- */
-export const useToggleControls = () => {
-  const [expandDetails, setExpandDetails] = useState(false);
-  const [showText, setShowText] = useState(true);
- 
-  const toggleExpand = useCallback(() => {
-    setExpandDetails((prev) => !prev);
-    setShowText(true);
-  }, []);
- 
-  const toggleText = useCallback(() => {
-    setExpandDetails(false);
-    setShowText((prev) => !prev);
-  }, []);
- 
-  return {
-    expandDetails,
-    showText,
-    toggleExpand,
-    toggleText,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html b/coverage/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html deleted file mode 100644 index 1c6412f27..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useViewOptions.ts

-
- -
- 100% - Statements - 46/46 -
- - -
- 92.3% - Branches - 12/13 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 46/46 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -791x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x - 
import { ReactNode, useMemo, ForwardRefExoticComponent } from 'react';
-import { hexToRGBA } from '@utils/index';
-import { TextOrContentModel } from '../../timeline-card-content/text-or-content';
- 
-interface UseViewOptionsParams {
-  showText: boolean;
-  expandDetails: boolean;
-  textOverlay: boolean;
-  detailsText?: ForwardRefExoticComponent<TextOrContentModel>;
-  title?: ReactNode;
-  content?: ReactNode;
-  theme: any;
-  cardHeight: number;
-  mediaHeight: number;
-}
- 
-interface UseViewOptionsResult {
-  canShowTextMemo: boolean;
-  canShowTextContent: boolean;
-  canExpand: boolean;
-  gradientColor: string;
-  canShowGradient: boolean;
-  getCardHeight: number;
-}
- 
-/**
- * Custom hook for handling view options and memoized calculated values
- */
-export const useViewOptions = ({
-  showText,
-  expandDetails,
-  textOverlay,
-  detailsText,
-  title,
-  content,
-  theme,
-  cardHeight,
-  mediaHeight,
-}: UseViewOptionsParams): UseViewOptionsResult => {
-  const canShowTextMemo = useMemo(
-    () => showText && !!detailsText,
-    [showText, detailsText],
-  );
- 
-  const canShowTextContent = useMemo(
-    () => !!(title ?? content ?? detailsText),
-    [title, content, detailsText],
-  );
- 
-  const canExpand = useMemo(
-    () => textOverlay && !!detailsText,
-    [textOverlay, detailsText],
-  );
- 
-  const gradientColor = useMemo(
-    () => hexToRGBA(theme?.cardDetailsBackGround ?? '', 0.8),
-    [theme?.cardDetailsBackGround],
-  );
- 
-  const canShowGradient = useMemo(
-    () => !expandDetails && showText && textOverlay,
-    [expandDetails, showText, textOverlay],
-  );
- 
-  const getCardHeight = useMemo(
-    () => (textOverlay ? cardHeight : mediaHeight),
-    [textOverlay, cardHeight, mediaHeight],
-  );
- 
-  return {
-    canShowTextMemo,
-    canShowTextContent,
-    canExpand,
-    gradientColor,
-    canShowGradient,
-    getCardHeight,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html b/coverage/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html deleted file mode 100644 index 2801f8acd..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useYouTubeDetection.ts

-
- -
- 100% - Statements - 7/7 -
- - -
- 100% - Branches - 2/2 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 7/7 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -141x -  -  -  -  -  -  -1x -18x -18x -18x -18x -18x - 
import { useMemo } from 'react';
- 
-/**
- * Custom hook to detect YouTube URLs
- * @param url - The URL to check
- * @returns boolean indicating if the URL is a YouTube URL
- */
-export const useYouTubeDetection = (url: string) => {
-  return useMemo(
-    () => /^(https?:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+$/.test(url),
-    [url],
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/index.html b/coverage/components/timeline-elements/timeline-card-media/index.html deleted file mode 100644 index 54c2a6882..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media

-
- -
- 79.91% - Statements - 199/249 -
- - -
- 78.33% - Branches - 47/60 -
- - -
- 90% - Functions - 9/10 -
- - -
- 79.91% - Lines - 199/249 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-media-buttons.tsx -
-
100%8/8100%1/1100%0/0100%8/8
timeline-card-media.styles.ts -
-
91.66%77/8480%44/55100%9/991.66%77/84
timeline-card-media.tsx -
-
91.93%114/12466.66%2/3100%0/091.93%114/124
video.tsx -
-
0%0/330%0/10%0/10%0/33
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html b/coverage/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html deleted file mode 100644 index 19919a431..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media timeline-card-media-buttons.tsx

-
- -
- 100% - Statements - 8/8 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 8/8 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49  -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -1x -  -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
- 
-const Button = css<{ theme: Theme }>`
-  align-items: center;
-  background: none;
-  // background: rgba(0, 0, 0, 0.1);
-  border-radius: 50%;
-  border: none;
-  cursor: pointer;
-  display: flex;
-  height: 1.5rem;
-  justify-content: center;
-  padding: 0;
-  width: 1.5rem;
-  margin: 0 0.25rem;
-  background: ${(p) => p.theme?.primary};
-  color: #fff;
- 
-  svg {
-    width: 70%;
-    height: 70%;
-  }
-`;
- 
-export const ExpandButton = styled.button<{
-  // expandFull?: boolean;
-  theme: Theme;
-}>`
-  ${Button}
-`;
- 
-export const ShowHideTextButton = styled.button<{
-  showText?: boolean;
-  theme: Theme;
-}>`
-  ${Button}
-`;
- 
-export const ButtonWrapper = styled.ul`
-  display: flex;
-  flex-direction: row;
-  justify-content: flex-end;
-  list-style: none;
-  margin: 0;
-  padding: 0;
-  margin-left: auto;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html b/coverage/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html deleted file mode 100644 index 6c54d34b3..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html +++ /dev/null @@ -1,850 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media timeline-card-media.styles.ts

-
- -
- 91.66% - Statements - 77/84 -
- - -
- 80% - Branches - 44/55 -
- - -
- 100% - Functions - 9/9 -
- - -
- 91.66% - Lines - 77/84 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256  -  -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -1x -  -1x -  -1x -  -  -1x -  -1x -1x -18x -1x -  -  -18x -17x -  -  -  -17x -17x -  -  -17x -17x -18x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -14x -14x -14x -14x -14x -14x -14x -  -  -  -  -1x -14x -  -  -  -  -  -  -  -14x -  -  -  -  -  -  -  -14x -2x -  -  -  -  -2x -14x -1x -1x -14x -2x -  -2x -  -2x -  -2x -2x -  -  -2x -  -  -1x -  -1x -14x -  -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -1x -  -1x -3x -1x -  -  -3x -2x -  -  -2x -3x -  -1x -3x -3x -  -  -  -1x -  -1x -  -  -1x -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
-import { ScrollBar } from '../../common/styles';
- 
-export const linearGradient = css`
-  &::after {
-    content: '';
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    width: 100%;
-    height: 2rem;
-    background: linear-gradient(
-      0deg,
-      var(--rc-gradient-color) 0%,
-      rgba(255, 255, 255, 0) 100%
-    );
-  }
-`;
- 
-export const MediaWrapper = styled.div<{
-  $active?: boolean;
-  $cardHeight?: number;
-  $slideShowActive?: boolean;
-  $textOverlay?: boolean;
-  align?: 'left' | 'right' | 'center';
-  dir?: string;
-  mode?: TimelineMode;
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  align-self: center;
-  background: ${(p) => (!p.$textOverlay ? p.theme?.cardMediaBgColor : 'none')};
-  border-radius: 4px;
-  flex-direction: row;
-  height: ${(p) => (p.$textOverlay ? 'calc(100% - 1em)' : '0')};
-  padding: 0.5em;
-  // pointer-events: ${(p) => (!p.$active && p.$slideShowActive ? 'none' : '')};
-  position: relative;
-  text-align: ${(p) => p.align};
-  width: calc(100% - 1em);
-  overflow: hidden; /* Ensure content doesn't overflow */
-  z-index: ${zIndex.timelineCard + 1}; /* Place media above card content */
- 
-  ${(p) => (p.$cardHeight ? `min-height: ${p.$cardHeight}px;` : '')};
-  ${(p) => {
-    if (p.mode === 'HORIZONTAL') {
-      return `
-        justify-content: flex-start;
-      `;
-    } else {
-      if (p.dir === 'left') {
-        return `
-        justify-content: flex-start;
-      `;
-      } else {
-        return `
-        justify-content: flex-end;
-      `;
-      }
-    }
-  }}
-`;
- 
-export const ImageWrapper = styled.div<{ height?: number }>`
-  width: 100%;
-  height: 100%;
-  overflow: hidden;
-  border-radius: 6px;
-  position: relative;
- 
-  /* Ensure the image is contained within the card boundaries */
-  img {
-    max-width: 100%;
-    max-height: 100%;
-    object-fit: contain;
-  }
-`;
- 
-export const CardImage = styled.img<{
-  $enableBorderRadius?: boolean;
-  $visible?: boolean;
-  dir?: string;
-  fit?: string;
-  mode?: TimelineMode;
-}>`
-  flex: 4;
-  justify-self: center;
-  margin-left: auto;
-  margin-right: auto;
-  height: 100%;
-  width: 100%;
-  object-fit: ${(p) => p.fit ?? 'cover'};
-  object-position: center;
-  visibility: ${(p) => (p.$visible ? 'visible' : 'hidden')};
-  border-radius: ${(p) => (p.$enableBorderRadius ? '6px' : '0')};
-  position: absolute;
-  top: 0;
-  left: 0;
-  bottom: 0;
-  right: 0;
-`;
- 
-export const CardVideo = styled.video<{ height?: number }>`
-  max-width: 100%;
-  max-height: 100%;
-  margin-left: auto;
-  margin-right: auto;
-`;
- 
-export const MediaDetailsWrapper = styled.div<{
-  $absolutePosition?: boolean;
-  $borderLessCard?: boolean;
-  $expandFull?: boolean;
-  $expandable?: boolean;
-  $gradientColor?: string | null;
-  $showText?: boolean;
-  $textInMedia?: boolean;
-  mode?: TimelineMode;
-  theme?: Theme;
-}>`
-  bottom: 0;
-  left: 0;
-  right: 0;
-  margin-right: auto;
-  width: ${(p) => {
-    switch (p.mode) {
-      case 'HORIZONTAL':
-      case 'VERTICAL':
-      case 'VERTICAL_ALTERNATING':
-        return `calc(90% - 0rem)`;
-    }
-  }};
-  display: flex;
-  flex-direction: column;
-  flex: 1;
-  overflow: hidden;
-  ${(p) => {
-    if (p.$textInMedia && p.$expandFull) {
-      return css`
-        height: 100%;
-        width: 100%;
-        border: 0;
-      `;
-    }
- 
-    if (!p.$showText) {
-      return css`
-        height: 15%;
-        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
-        border-radius: 10px;
-      `;
-    }
- 
-    if (p.$textInMedia && p.$expandable) {
-      return css`
-        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
-        border-radius: 10px;
-        height: 50%;
-      `;
-    }
-  }}
-  position: ${(p) => (p.$absolutePosition ? 'absolute' : 'relative')};
-  ${(p) =>
-    p.$absolutePosition
-      ? `
-    left: 50%;
-    bottom: ${p.$expandFull ? '0%' : ' 5%'};
-    transform: translateX(-50%);
-    z-index: ${zIndex.timelineCard + 2};
-    background: ${
-      p.$showText ? p.theme?.cardDetailsBackGround : p.theme?.cardBgColor
-    };
-    // backdrop-filter: blur(1px);
-    padding: 0.25rem;
-    ${p.$showText ? `overflow: auto;` : `overflow: hidden;`}
-    transition: height 0.25s ease-out, width 0.25s ease-out, bottom 0.25s ease-out, background 0.25s ease-out;
-  `
-      : ``}
- 
-  ${({ $borderLessCard }) =>
-    $borderLessCard
-      ? `border-radius: 6px; box-shadow: 0 0 10px 0 rgba(0,0,0,0.2);`
-      : ``}
-  --rc-gradient-color: ${(p) => p.$gradientColor};
-  ${(p) => (p.$gradientColor ? linearGradient : null)}
-`;
- 
-export const ErrorMessage = styled.span`
-  color: #a3a3a3;
-  left: 50%;
-  position: absolute;
-  text-align: center;
-  top: 50%;
-  transform: translateY(-50%) translateX(-50%);
-`;
- 
-export const IFrameVideo = styled.iframe`
-  position: relative;
-  height: 100%;
-  width: 100%;
-`;
- 
-export const DetailsTextWrapper = styled.div<{
-  $expandFull?: boolean;
-  $show?: boolean;
-  background?: string;
-  theme?: Theme;
-}>`
-  align-self: center;
-  display: flex;
-  transition: height 0.5s ease;
-  width: calc(100%);
-  background: ${(p) => p.background};
-  color: ${(p) => p.theme?.cardDetailsColor};
-  padding: 0.5rem;
-  border-bottom-left-radius: 8px;
-  border-bottom-right-radius: 8px;
-  position: relative;
-  align-items: flex-start;
-  justify-content: center;
- 
-  ${ScrollBar}
- 
-  ${(p) => {
-    if (p.$expandFull) {
-      return `
-        overflow: auto;
-      `;
-    } else {
-      return `
-        overflow: hidden;
-      `;
-    }
-  }}
- 
-  ${(p) =>
-    p.$show
-      ? `
-    height: 100%;`
-      : `
-    height: 0;
-  `}
- 
-  ${(p) => !p.$expandFull && linearGradient}
-`;
- 
-export const CardMediaHeader = styled.div`
-  padding: 0.5rem 0 0.5rem 0.5rem;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html b/coverage/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html deleted file mode 100644 index 51814eed2..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html +++ /dev/null @@ -1,529 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/timeline-card-media.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media timeline-card-media.tsx

-
- -
- 91.93% - Statements - 114/124 -
- - -
- 66.66% - Branches - 2/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 91.93% - Lines - 114/124 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -18x -18x -18x -18x -  -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -  -18x -  -  -18x -  -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -18x -  -18x -1x -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -1x - 
import { CardMediaModel } from '@models/TimelineMediaModel';
-import cls from 'classnames';
-import React, { memo, useCallback, useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { MediaWrapper } from './timeline-card-media.styles';
-import { useMediaLoad } from './hooks/useMediaLoad';
-import { useYouTubeDetection } from './hooks/useYouTubeDetection';
-import { useToggleControls } from './hooks/useToggleControls';
-import { useViewOptions } from './hooks/useViewOptions';
-import { MediaContent } from './components/MediaContent';
-import { ContentDisplay } from './components/ContentDisplay';
- 
-/**
- * CardMedia component - A highly optimized component for media rendering in timeline cards
- */
-const CardMedia: React.FunctionComponent<CardMediaModel> = memo(
-  ({
-    active,
-    id,
-    onMediaStateChange,
-    title,
-    content,
-    media,
-    slideshowActive,
-    url,
-    detailsText,
-  }: CardMediaModel) => {
-    // Custom hooks for state management
-    const { loadFailed, mediaLoaded, handleMediaLoaded, handleError } =
-      useMediaLoad(id, onMediaStateChange);
-    const isYouTube = useYouTubeDetection(media.source.url);
-    const { expandDetails, showText, toggleExpand, toggleText } =
-      useToggleControls();
- 
-    // Get context
-    const {
-      mode,
-      fontSizes,
-      classNames,
-      mediaHeight,
-      borderLessCards,
-      textOverlay,
-      theme,
-      cardHeight,
-      mediaSettings,
-    } = useContext(GlobalContext);
- 
-    // Use view options hook for calculated values
-    const {
-      canShowTextMemo,
-      canShowTextContent,
-      canExpand,
-      gradientColor,
-      canShowGradient,
-      getCardHeight,
-    } = useViewOptions({
-      showText,
-      expandDetails,
-      textOverlay,
-      detailsText,
-      title,
-      content,
-      theme,
-      cardHeight,
-      mediaHeight,
-    });
- 
-    // Cast mode to TimelineMode
-    const timelineMode = mode;
- 
-    // Details text callback
-    const onDetailsTextRef = useCallback((height?: number) => {
-      if (height) {
-        // Do something with height if needed
-      }
-    }, []);
- 
-    return (
-      <>
-        <MediaWrapper
-          theme={theme}
-          $active={active}
-          mode={timelineMode}
-          $slideShowActive={slideshowActive}
-          className={cls('card-media-wrapper', classNames?.cardMedia)}
-          $cardHeight={getCardHeight}
-          align={mediaSettings?.align}
-          $textOverlay={textOverlay}
-        >
-          <MediaContent
-            media={media}
-            isYouTube={isYouTube}
-            loadFailed={loadFailed}
-            mediaLoaded={mediaLoaded}
-            active={active}
-            id={id}
-            mediaHeight={mediaHeight}
-            mode={timelineMode}
-            borderLessCards={borderLessCards}
-            mediaSettings={mediaSettings}
-            handleMediaLoaded={handleMediaLoaded}
-            handleError={handleError}
-            onMediaStateChange={onMediaStateChange}
-          />
-        </MediaWrapper>
- 
-        {canShowTextContent && (
-          <ContentDisplay
-            mode={timelineMode}
-            textOverlay={textOverlay}
-            theme={theme}
-            expandDetails={expandDetails}
-            showText={showText}
-            canExpand={canExpand}
-            canShowGradient={canShowGradient}
-            gradientColor={gradientColor}
-            title={title}
-            active={active}
-            url={url}
-            fontSizes={fontSizes}
-            classNames={classNames}
-            toggleText={toggleText}
-            toggleExpand={toggleExpand}
-            content={content}
-            canShowTextMemo={canShowTextMemo}
-            detailsText={detailsText}
-            onDetailsTextRef={onDetailsTextRef}
-          />
-        )}
-      </>
-    ) as React.ReactElement;
-  },
-  (prevProps, nextProps) => {
-    // Custom comparison function to avoid unnecessary re-renders
-    return (
-      prevProps.active === nextProps.active &&
-      prevProps.slideshowActive === nextProps.slideshowActive &&
-      prevProps.paused === nextProps.paused &&
-      prevProps.startWidth === nextProps.startWidth &&
-      prevProps.remainInterval === nextProps.remainInterval &&
-      JSON.stringify(prevProps.theme) === JSON.stringify(nextProps.theme)
-    );
-  },
-);
- 
-CardMedia.displayName = 'Card Media';
- 
-export default CardMedia;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card-media/video.tsx.html b/coverage/components/timeline-elements/timeline-card-media/video.tsx.html deleted file mode 100644 index 318687f00..000000000 --- a/coverage/components/timeline-elements/timeline-card-media/video.tsx.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/video.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media video.tsx

-
- -
- 0% - Statements - 0/33 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/33 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import React, { useRef, useEffect } from 'react';
-import styled from 'styled-components';
- 
-interface VideoProps extends React.VideoHTMLAttributes<HTMLVideoElement> {
-  children: React.ReactNode;
-}
- 
-const VideoElement = styled.video`
-  width: 100%;
-  height: auto;
-  display: block;
-`;
- 
-/**
- * Accessible Video component
- * Wraps the native video element with improved accessibility features
- */
-const Video: React.FC<VideoProps> = ({
-  children,
-  autoPlay,
-  muted,
-  controls = true,
-  onEnded,
-  playsInline = true,
-  ...rest
-}) => {
-  const videoRef = useRef<HTMLVideoElement>(null);
- 
-  // Ensure video is properly muted when needed
-  useEffect(() => {
-    if (videoRef.current && autoPlay) {
-      videoRef.current.muted = true;
-    }
-  }, [autoPlay]);
- 
-  return (
-    <VideoElement
-      ref={videoRef}
-      autoPlay={autoPlay}
-      muted={muted}
-      controls={controls}
-      onEnded={onEnded}
-      playsInline={playsInline}
-      preload="metadata"
-      aria-label="Timeline media"
-      {...rest}
-    >
-      {children}
-    </VideoElement>
-  );
-};
- 
-export default Video;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/__tests__/index.html b/coverage/components/timeline-elements/timeline-card/__tests__/index.html deleted file mode 100644 index 7a1781636..000000000 --- a/coverage/components/timeline-elements/timeline-card/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/__tests__

-
- -
- 93.93% - Statements - 93/99 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 93.93% - Lines - 93/99 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal-card.test.tsx -
-
93.93%93/99100%10/10100%0/093.93%93/99
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html b/coverage/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html deleted file mode 100644 index f2b59018e..000000000 --- a/coverage/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html +++ /dev/null @@ -1,487 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/__tests__ timeline-horizontal-card.test.tsx

-
- -
- 93.93% - Statements - 93/99 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 93.93% - Lines - 93/99 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -1351x -  -  -  -  -  -  -  -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -  -1x -1x -1x -  -  -1x -  -1x -  -6x -6x -6x -1x -  -1x -  -6x -6x -6x -6x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import {
-  afterEach,
-  beforeAll,
-  beforeEach,
-  describe,
-  expect,
-  it,
-  vi,
-} from 'vitest';
-import { TimelineCardModel } from '../../../../models/TimelineItemModel';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import TimelineCard from '../timeline-horizontal-card';
- 
-const defaultProps: TimelineCardModel = {
-  active: true,
-  cardDetailedText: 'card detailed text',
-  cardSubtitle: 'card subtitle',
-  cardTitle: 'card title',
-  iconChild: 'icon child',
-  id: 'id-12345',
-  media: {
-    name: 'image_new',
-    source: {
-      type: 'IMAGE',
-      url: 'https://picsum.photos/200/300',
-    },
-    type: 'IMAGE',
-  },
-  onClick: vi.fn(),
-  onElapsed: vi.fn(),
-  wrapperId: 'wrapper-id-12345',
-};
- 
-describe('TimelineHorizontalCard', () => {
-  beforeAll(() => {
-    Object.defineProperty(window, 'matchMedia', {
-      value: vi.fn().mockImplementation((query) => ({
-        addEventListener: vi.fn(),
-        dispatchEvent: vi.fn(),
-        matches: false,
-        media: query,
-        onchange: null,
-        removeEventListener: vi.fn(),
-      })),
-      writable: true,
-    });
- 
-    // ResizeObserver is already mocked globally in common/test/index.tsx
-  });
- 
-  beforeEach(() => {
-    // create a div with id 'wrapper-id-12345' to render the component
-    const root = document.createElement('div');
-    root.setAttribute('id', 'wrapper-id-12345');
-    document.body.appendChild(root);
-  });
- 
-  afterEach(() => {
-    // remove the div with id 'wrapper-id-12345' after the tests
-    const root = document.getElementById('wrapper-id-12345');
-    if (root) {
-      document.body.removeChild(root);
-    }
-  });
- 
-  // should render timeline card
-  it('should render timeline card', () => {
-    const { container } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps: { ...providerProps, cardLess: false },
-    });
- 
-    expect(container).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot', () => {
-    const { container } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps: { ...providerProps, cardLess: false },
-    });
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render cardDetailedText, cardSubtitle, cardTitle, iconChild
-  it('should render cardDetailedText, cardSubtitle, cardTitle', () => {
-    const { getByText } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps,
-    });
- 
-    expect(getByText('card detailed text')).toBeInTheDocument();
-    expect(getByText('card subtitle')).toBeInTheDocument();
-    expect(getByText('card title')).toBeInTheDocument();
-  });
- 
-  // should support rendering a custom icon
-  it('should render a custom icon', () => {
-    const { getByText } = customRender(
-      <TimelineCard
-        {...defaultProps}
-        iconChild={<span role="img">icon</span>}
-      ></TimelineCard>,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('icon')).toBeInTheDocument();
-  });
- 
-  // should render media (image) if provided
-  it('should render media (image) if provided', () => {
-    const { getByAltText } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps,
-    });
- 
-    expect(getByAltText('image_new')).toBeInTheDocument();
-  });
- 
-  // should render media (video) if provided
-  it('should render media (video) if provided', () => {
-    const { getByText, getByRole } = customRender(
-      <TimelineCard {...defaultProps} url="http://www.google.com" />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('card title')).toBeInTheDocument();
-    expect(getByText('card subtitle')).toBeInTheDocument();
-    expect(getByRole('link')).toBeInTheDocument();
-    expect(getByRole('link')).toHaveAttribute('href', 'http://www.google.com');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/hooks/index.html b/coverage/components/timeline-elements/timeline-card/hooks/index.html deleted file mode 100644 index 4e9f43cbf..000000000 --- a/coverage/components/timeline-elements/timeline-card/hooks/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/hooks - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/hooks

-
- -
- 96.2% - Statements - 76/79 -
- - -
- 93.75% - Branches - 15/16 -
- - -
- 100% - Functions - 1/1 -
- - -
- 96.2% - Lines - 76/79 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useTimelineCard.ts -
-
96.2%76/7993.75%15/16100%1/196.2%76/79
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html b/coverage/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html deleted file mode 100644 index b6f4c3230..000000000 --- a/coverage/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/hooks/useTimelineCard.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/hooks useTimelineCard.ts

-
- -
- 96.2% - Statements - 76/79 -
- - -
- 93.75% - Branches - 15/16 -
- - -
- 100% - Functions - 1/1 -
- - -
- 96.2% - Lines - 76/79 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -921x -1x -1x -  -1x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -  -67x -  -  -  -67x -  -67x -67x -25x -25x -  -25x -25x -25x -  -25x -19x -19x -19x -25x -25x -67x -  -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x - 
import { useCallback, useContext, useEffect, useMemo, useRef } from 'react';
-import cls from 'classnames';
-import { GlobalContext } from '../../../GlobalContext';
- 
-export const useTimelineCard = ({
-  active,
-  autoScroll,
-  slideShowRunning,
-  cardLess,
-  showAllCardsHorizontal,
-  id,
-  onClick,
-  mode,
-  position,
-  iconChild,
-}) => {
-  const circleRef = useRef<HTMLButtonElement>(null);
-  const wrapperRef = useRef<HTMLDivElement>(null);
-  const contentRef = useRef<HTMLDivElement>(null);
- 
-  const { disableClickOnCircle } = useContext(GlobalContext);
- 
-  const handleClick = useCallback(() => {
-    if (!disableClickOnCircle && onClick && !slideShowRunning) {
-      onClick(id);
-    }
-  }, [disableClickOnCircle, onClick, slideShowRunning, id]);
- 
-  useEffect(() => {
-    if (active) {
-      const circle = circleRef.current;
-      const wrapper = wrapperRef.current;
- 
-      if (circle && wrapper) {
-        const circleOffsetLeft = circle.offsetLeft;
-        const wrapperOffsetLeft = wrapper.offsetLeft;
- 
-        autoScroll?.({
-          pointOffset: circleOffsetLeft + wrapperOffsetLeft,
-          pointWidth: circle.clientWidth,
-        });
-      }
-    }
-  }, [active, autoScroll, mode]);
- 
-  const modeLower = useMemo(() => mode?.toLowerCase(), [mode]);
- 
-  const containerClass = useMemo(
-    () =>
-      cls(
-        'timeline-horz-card-wrapper',
-        modeLower,
-        position === 'TOP' ? 'bottom' : 'top',
-        showAllCardsHorizontal ? 'show-all' : '',
-      ),
-    [modeLower, position, showAllCardsHorizontal],
-  );
- 
-  const titleClass = useMemo(
-    () => cls(modeLower, position),
-    [modeLower, position],
-  );
- 
-  const circleClass = useMemo(
-    () =>
-      cls(
-        'timeline-circle',
-        { 'using-icon': !!iconChild },
-        modeLower,
-        active ? 'active' : 'in-active',
-      ),
-    [active, iconChild, modeLower],
-  );
- 
-  const canShowTimelineContent = useMemo(
-    () => (active && !cardLess) || showAllCardsHorizontal,
-    [active, cardLess, showAllCardsHorizontal],
-  );
- 
-  return {
-    circleRef,
-    wrapperRef,
-    contentRef,
-    handleClick,
-    modeLower,
-    containerClass,
-    titleClass,
-    circleClass,
-    canShowTimelineContent,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/index.html b/coverage/components/timeline-elements/timeline-card/index.html deleted file mode 100644 index 9465b81bb..000000000 --- a/coverage/components/timeline-elements/timeline-card/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card

-
- -
- 94.17% - Statements - 178/189 -
- - -
- 72.22% - Branches - 39/54 -
- - -
- 100% - Functions - 3/3 -
- - -
- 94.17% - Lines - 178/189 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal-card.styles.ts -
-
90%54/6076.19%32/42100%1/190%54/60
timeline-horizontal-card.tsx -
-
96.12%124/12958.33%7/12100%2/296.12%124/129
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/timeline-card-portal/index.html b/coverage/components/timeline-elements/timeline-card/timeline-card-portal/index.html deleted file mode 100644 index adf60ae7f..000000000 --- a/coverage/components/timeline-elements/timeline-card/timeline-card-portal/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-card-portal - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/timeline-card-portal

-
- -
- 100% - Statements - 96/96 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 96/96 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-portal.tsx -
-
100%96/96100%6/6100%1/1100%96/96
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html b/coverage/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html deleted file mode 100644 index 0b1664ea7..000000000 --- a/coverage/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html +++ /dev/null @@ -1,472 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/timeline-card-portal timeline-card-portal.tsx

-
- -
- 100% - Statements - 96/96 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 96/96 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -1301x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -6x -6x -21x -27x -  -27x -27x -  -1x - 
import React, { useCallback, useMemo } from 'react';
-import ReactDOM from 'react-dom';
-import { TimelineContentContainer } from '../timeline-horizontal-card.styles';
-import TimelineCardContent from '../../timeline-card-content/timeline-card-content';
- 
-interface TimelineCardPortalProps {
-  containerClass: string;
-  contentRef: React.RefObject<HTMLDivElement>;
-  id: string;
-  theme?: any;
-  active: boolean;
-  disableInteraction: boolean;
-  showAllCardsHorizontal: boolean;
-  cardWidth?: number;
-  cardSubtitle?: string;
-  cardTitle?: string;
-  url?: string;
-  cardDetailedText?: string | string[];
-  slideShowRunning?: boolean;
-  media?: any;
-  onElapsed?: (id: string) => void;
-  customContent?: React.ReactNode;
-  hasFocus?: boolean;
-  onClick?: (id: string) => void;
-  timelineContent?: any;
-  isNested?: boolean;
-  nestedCardHeight?: number;
-  items?: any[];
-  wrapperId: string;
-}
- 
-const TimelineCardPortal: React.FC<TimelineCardPortalProps> = ({
-  containerClass,
-  contentRef,
-  id,
-  theme,
-  active,
-  disableInteraction,
-  showAllCardsHorizontal,
-  cardWidth,
-  cardSubtitle,
-  cardTitle,
-  url,
-  cardDetailedText,
-  slideShowRunning,
-  media,
-  onElapsed,
-  customContent,
-  hasFocus,
-  onClick,
-  timelineContent,
-  isNested,
-  nestedCardHeight,
-  items,
-  wrapperId,
-}) => {
-  const handleOnShowMore = useCallback(() => {}, []);
- 
-  const Content = useMemo(() => {
-    return (
-      <TimelineContentContainer
-        className={containerClass}
-        ref={contentRef}
-        id={`timeline-card-${id}`}
-        theme={theme}
-        $active={active && !disableInteraction}
-        $highlight={showAllCardsHorizontal}
-        tabIndex={0}
-        $cardWidth={cardWidth}
-      >
-        <TimelineCardContent
-          content={cardSubtitle}
-          active={active}
-          title={cardTitle}
-          url={url}
-          detailedText={cardDetailedText}
-          onShowMore={handleOnShowMore}
-          theme={theme}
-          slideShowActive={slideShowRunning}
-          media={media}
-          onElapsed={onElapsed}
-          id={id}
-          customContent={customContent}
-          hasFocus={hasFocus}
-          onClick={onClick}
-          timelineContent={timelineContent}
-          isNested={isNested}
-          nestedCardHeight={nestedCardHeight}
-          items={items}
-        />
-      </TimelineContentContainer>
-    );
-  }, [
-    containerClass,
-    contentRef,
-    id,
-    active,
-    disableInteraction,
-    showAllCardsHorizontal,
-    cardWidth,
-    cardSubtitle,
-    cardTitle,
-    url,
-    cardDetailedText,
-    slideShowRunning,
-    theme,
-    media,
-    onElapsed,
-    customContent,
-    hasFocus,
-    onClick,
-    timelineContent,
-    isNested,
-    nestedCardHeight,
-    items,
-  ]);
- 
-  const renderedPortal = useMemo(() => {
-    const ele = document.getElementById(wrapperId);
-    if (ele) {
-      return ReactDOM.createPortal(Content, ele);
-    }
-    return null;
-  }, [Content, wrapperId]);
- 
-  return <>{renderedPortal}</>;
-};
- 
-export default TimelineCardPortal;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html b/coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html deleted file mode 100644 index 7e0b78c00..000000000 --- a/coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html +++ /dev/null @@ -1,925 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card timeline-horizontal-card.styles.ts

-
- -
- 90% - Statements - 54/60 -
- - -
- 76.19% - Branches - 32/42 -
- - -
- 100% - Functions - 1/1 -
- - -
- 90% - Lines - 54/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -180x -66x -180x -  -114x -  -  -180x -  -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -1x -90x -  -1x -  -  -  -  -1x -90x -  -1x -  -  -  -  -1x -90x -  -1x -1x -  -  -1x -1x -  -  -  -1x -  -  -1x -1x -  -  -  -  -1x -  -  -  -  -  -1x -  -  -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled, { keyframes } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-export const Wrapper = styled.div`
-  align-items: center;
-  border: 1px solid transparent;
-  display: flex;
-  justify-content: center;
-  position: relative;
-  width: 100%;
-  height: 100%;
- 
-  &.vertical {
-    justify-content: flex-start;
-  }
-`;
- 
-export const Item = styled.div``;
- 
-const show = keyframes`
-  from {
-    opacity: 0;
-  }
-  to {
-    opacity: 1;
-  }
-`;
- 
-const ripple = keyframes`
-  0% {
-    transform: scale(0);
-    opacity: 0.8;
-  }
-  100% {
-    transform: scale(4);
-    opacity: 0;
-  }
-`;
- 
-const pulse = keyframes`
-  0% {
-    box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.4);
-  }
-  70% {
-    box-shadow: 0 0 0 10px rgba(0, 123, 255, 0);
-  }
-  100% {
-    box-shadow: 0 0 0 0 rgba(0, 123, 255, 0);
-  }
-`;
- 
-export const ShapeWrapper = styled.div`
-  /* height: 100%; */
-  align-items: center;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  width: 5em;
-`;
- 
-type ShapeModel = {
-  $timelinePointShape?: 'circle' | 'square' | 'diamond';
-  dimension?: number;
-  theme?: Theme;
-};
- 
-const ShapeBorderStyle = (p: Pick<ShapeModel, '$timelinePointShape'>) => {
-  if (p.$timelinePointShape === 'circle') {
-    return 'border-radius: 50%;';
-  } else if (p.$timelinePointShape === 'square') {
-    return 'border-radius: 2px;';
-  } else if (p.$timelinePointShape === 'diamond') {
-    return `border-radius: 0;`;
-  }
-};
- 
-export const Shape = styled.div<ShapeModel>`
-  ${ShapeBorderStyle}
-  cursor: pointer;
-  height: ${(p) => p.dimension}px;
-  width: ${(p) => p.dimension}px;
-  transform: ${(p) =>
-    p.$timelinePointShape === 'diamond' ? 'rotate(45deg)' : ''};
-  transition: all 0.2s ease-in-out;
-  position: relative;
-  overflow: hidden;
- 
-  /* Reset button styles when used as a button */
-  background: none;
-  border: none;
-  padding: 0;
- 
-  /* Ripple effect */
-  &::before {
-    content: '';
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    width: ${(p) => (p.dimension ? Math.round(p.dimension * 0.5) : 10)}px;
-    height: ${(p) => (p.dimension ? Math.round(p.dimension * 0.5) : 10)}px;
-    background-color: rgba(255, 255, 255, 0.5);
-    border-radius: 50%;
-    transform: scale(0) translate(-50%, -50%);
-    transform-origin: top left;
-    pointer-events: none;
-    z-index: ${zIndex.timelinePoint + 1}; /* Above the timeline point */
-    opacity: 0;
-  }
- 
-  &:active::before {
-    animation: ${ripple} 0.6s ease-out;
-  }
- 
-  /* Improve focus styles for accessibility */
-  &:focus-visible {
-    outline: 3px solid ${(p) => p.theme?.primary ?? '#007bff'};
-    outline-offset: 2px;
-  }
- 
-  /* Add subtle hover effect */
-  &:hover:not(:disabled) {
-    transform: ${(p) =>
-      p.$timelinePointShape === 'diamond'
-        ? 'rotate(45deg) scale(1.08)'
-        : 'scale(1.08)'};
-    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.1);
-  }
- 
-  &:active:not(:disabled) {
-    transform: ${(p) =>
-      p.$timelinePointShape === 'diamond'
-        ? 'rotate(45deg) scale(0.95)'
-        : 'scale(0.95)'};
-  }
- 
-  &.active {
-    &.using-icon {
-      transform: ${(p) =>
-        p.$timelinePointShape === 'diamond'
-          ? 'rotate(45deg) scale(1.1)'
-          : 'scale(1.1)'};
-      animation: ${pulse} 1.5s infinite;
-    }
-    &:not(.using-icon) {
-      transform: ${(p) =>
-        p.$timelinePointShape === 'diamond' ? 'rotate(45deg)' : ''};
-    }
- 
-    &::after {
-      ${ShapeBorderStyle}
-      content: '';
-      display: block;
-      height: ${(p) => (p.dimension ? Math.round(p.dimension * 0.75) : 20)}px;
-      width: ${(p) => (p.dimension ? Math.round(p.dimension * 0.75) : 20)}px;
-      left: 50%;
-      position: absolute;
-      top: 50%;
-      transform: translateY(-50%) translateX(-50%);
-      z-index: ${zIndex.timelinePoint - 1}; /* Behind the timeline point */
-      transition: all 0.3s ease-in-out;
-    }
-  }
- 
-  &:not(.using-icon) {
-    background: ${(p: ShapeModel) => p.theme?.primary};
- 
-    &.active {
-      background: ${(p: ShapeModel) => p.theme?.secondary};
-      border: ${(p) => (p.dimension ? Math.round(p.dimension * 0.2) : '3')}px
-        solid ${(p: ShapeModel) => p.theme?.primary};
-      box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
-      animation: ${pulse} 1.5s infinite;
-    }
- 
-    &:disabled {
-      opacity: 0.6;
-      cursor: default;
-    }
-  }
- 
-  &.using-icon {
-    background: ${(p) => p.theme?.iconBackgroundColor};
-    display: flex;
-    align-items: center;
-    justify-content: center;
- 
-    img {
-      max-width: 90%;
-      max-height: 90%;
-    }
- 
-    &:disabled {
-      opacity: 0.6;
-      cursor: default;
-    }
-  }
-`;
- 
-export const TimelineTitleContainer = styled.div`
-  display: flex;
-  align-items: center;
-  justify-content: flex-start;
- 
-  &.vertical {
-    margin-bottom: 1em;
-  }
- 
-  &.horizontal {
-    position: absolute;
-    top: 0;
-  }
-`;
- 
-export const TimelineContentContainer = styled.div<{
-  $active?: boolean;
-  $cardWidth?: number;
-  $highlight?: boolean;
-  position?: string;
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  animation: ${show} 0.25s ease-in;
- 
-  outline: 2px solid
-    ${(p) => (p.$highlight && p.$active ? p.theme?.primary : 'transparent')};
- 
-  margin: 1rem;
- 
-  &.horizontal {
-    min-width: ${(p) => p.$cardWidth}px;
-  }
- 
-  &.vertical {
-    width: calc(100% - 5em);
-    margin-left: auto;
-    flex-direction: column;
-  }
-`;
- 
-// Card container with improved cross-browser support
-export const CardContainer = styled.div<{ theme: Theme }>`
-  position: relative;
-  display: -webkit-box;
-  display: -ms-flexbox;
-  display: flex;
-  -webkit-box-orient: vertical;
-  -webkit-box-direction: normal;
-  -ms-flex-direction: column;
-  flex-direction: column;
-  min-width: 250px;
-  max-width: 350px;
-  margin: 0.5rem;
-  padding: 1rem;
-  background: ${(p) => p.theme.cardBgColor};
-  border-radius: 8px;
-  -webkit-box-shadow: 
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  box-shadow:
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  -webkit-transition: 
-    -webkit-transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
-  transition:
-    transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
- 
-  &:hover {
-    -webkit-transform: translateY(-2px);
-    transform: translateY(-2px);
-    -webkit-box-shadow: 
-      0 2px 4px rgba(0, 0, 0, 0.08),
-      0 6px 12px rgba(0, 0, 0, 0.12);
-    box-shadow:
-      0 2px 4px rgba(0, 0, 0, 0.08),
-      0 6px 12px rgba(0, 0, 0, 0.12);
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html b/coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html deleted file mode 100644 index 4e7d21926..000000000 --- a/coverage/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html +++ /dev/null @@ -1,529 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-horizontal-card.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card timeline-horizontal-card.tsx

-
- -
- 96.12% - Statements - 124/129 -
- - -
- 58.33% - Branches - 7/12 -
- - -
- 100% - Functions - 2/2 -
- - -
- 96.12% - Lines - 124/129 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149  -1x -1x -1x -1x -  -  -  -1x -1x -1x -  -1x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -  -67x -27x -  -  -  -  -  -27x -27x -27x -  -27x -27x -  -67x -67x -67x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -  -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -  -1x - 
import { TimelineCardModel } from '@models/TimelineItemModel';
-import React, { useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import TimelineItemTitle from '../timeline-item-title/timeline-card-title';
-import {
-  TimelineTitleContainer,
-  Wrapper,
-} from './timeline-horizontal-card.styles';
-import { useTimelineCard } from './hooks/useTimelineCard';
-import TimelinePoint from './timeline-point/timeline-point';
-import TimelineCardPortal from './timeline-card-portal/timeline-card-portal';
- 
-const TimelineCard: React.FunctionComponent<TimelineCardModel> = ({
-  active,
-  autoScroll,
-  cardDetailedText,
-  cardSubtitle,
-  cardTitle,
-  url,
-  id,
-  media,
-  onClick,
-  onElapsed,
-  slideShowRunning,
-  title,
-  wrapperId,
-  customContent,
-  hasFocus,
-  iconChild,
-  timelineContent,
-  cardWidth,
-  isNested,
-  nestedCardHeight,
-  items,
-}: TimelineCardModel) => {
-  const {
-    mode,
-    cardPositionHorizontal: position,
-    timelinePointDimension,
-    cardLess,
-    showAllCardsHorizontal,
-    classNames,
-    theme,
-    timelinePointShape,
-    disableInteraction,
-  } = useContext(GlobalContext);
- 
-  const {
-    circleRef,
-    wrapperRef,
-    contentRef,
-    handleClick,
-    modeLower,
-    containerClass,
-    titleClass,
-    circleClass,
-    canShowTimelineContent,
-  } = useTimelineCard({
-    active,
-    autoScroll,
-    slideShowRunning,
-    cardLess,
-    showAllCardsHorizontal,
-    id,
-    onClick,
-    mode,
-    position,
-    iconChild,
-  });
- 
-  // Convert cardDetailedText to the expected string or string[] format
-  const formatDetailedText = () => {
-    if (Array.isArray(cardDetailedText)) {
-      return cardDetailedText.map((text) =>
-        typeof text === 'string' ? text : String(text ?? ''),
-      );
-    }
- 
-    if (typeof cardDetailedText === 'string') {
-      return cardDetailedText;
-    }
- 
-    return cardDetailedText ? String(cardDetailedText) : undefined;
-  };
- 
-  return (
-    <Wrapper ref={wrapperRef} className={modeLower} data-testid="timeline-item">
-      {canShowTimelineContent && (
-        <TimelineCardPortal
-          containerClass={containerClass}
-          contentRef={contentRef}
-          id={id}
-          theme={theme}
-          active={active}
-          disableInteraction={disableInteraction}
-          showAllCardsHorizontal={showAllCardsHorizontal}
-          cardWidth={cardWidth}
-          cardSubtitle={
-            typeof cardSubtitle === 'string'
-              ? cardSubtitle
-              : String(cardSubtitle ?? '')
-          }
-          cardTitle={
-            typeof cardTitle === 'string' ? cardTitle : String(cardTitle ?? '')
-          }
-          url={url}
-          cardDetailedText={formatDetailedText()}
-          slideShowRunning={slideShowRunning}
-          media={media}
-          onElapsed={onElapsed}
-          customContent={customContent}
-          hasFocus={hasFocus}
-          onClick={onClick}
-          timelineContent={timelineContent}
-          isNested={isNested}
-          nestedCardHeight={nestedCardHeight}
-          items={items}
-          wrapperId={wrapperId}
-        />
-      )}
- 
-      <TimelinePoint
-        circleClass={circleClass}
-        handleClick={handleClick}
-        circleRef={circleRef}
-        title={typeof title === 'string' ? title : String(title ?? '')}
-        theme={theme}
-        timelinePointDimension={timelinePointDimension}
-        timelinePointShape={timelinePointShape}
-        iconChild={iconChild}
-      />
- 
-      <TimelineTitleContainer
-        className={titleClass}
-        data-testid="timeline-title"
-      >
-        <TimelineItemTitle
-          title={title}
-          active={active && !disableInteraction}
-          theme={theme}
-          classString={classNames?.title}
-        />
-      </TimelineTitleContainer>
-    </Wrapper>
-  );
-};
- 
-export default TimelineCard;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/timeline-point/index.html b/coverage/components/timeline-elements/timeline-card/timeline-point/index.html deleted file mode 100644 index 80be374c5..000000000 --- a/coverage/components/timeline-elements/timeline-card/timeline-point/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-point - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/timeline-point

-
- -
- 100% - Statements - 35/35 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 35/35 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-point.tsx -
-
100%35/3550%2/4100%1/1100%35/35
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html b/coverage/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html deleted file mode 100644 index dd47ae625..000000000 --- a/coverage/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/timeline-point timeline-point.tsx

-
- -
- 100% - Statements - 35/35 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 35/35 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -  -67x -  -1x - 
import React from 'react';
-import { Shape, ShapeWrapper } from '../timeline-horizontal-card.styles';
- 
-interface TimelinePointProps {
-  circleClass: string;
-  handleClick: () => void;
-  circleRef: React.RefObject<HTMLButtonElement>;
-  title?: string;
-  theme?: any;
-  timelinePointDimension?: number;
-  timelinePointShape?: 'circle' | 'square' | 'diamond';
-  iconChild?: React.ReactNode;
-  active?: boolean;
-  disabled?: boolean;
-}
- 
-const TimelinePoint: React.FC<TimelinePointProps> = ({
-  circleClass,
-  handleClick,
-  circleRef,
-  title,
-  theme,
-  timelinePointDimension,
-  timelinePointShape,
-  iconChild,
-  active = false,
-  disabled = false,
-}) => {
-  return (
-    <ShapeWrapper>
-      <Shape
-        as="button"
-        className={circleClass}
-        onClick={handleClick}
-        ref={circleRef}
-        data-testid="timeline-circle"
-        theme={theme}
-        aria-label={title ?? 'Timeline point'}
-        aria-selected={active}
-        aria-disabled={disabled}
-        disabled={disabled}
-        dimension={timelinePointDimension}
-        $timelinePointShape={timelinePointShape}
-        tabIndex={disabled ? -1 : 0}
-        type="button"
-      >
-        {iconChild ?? null}
-      </Shape>
-    </ShapeWrapper>
-  ) as React.ReactElement;
-};
- 
-export default TimelinePoint;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-control/__tests__/index.html b/coverage/components/timeline-elements/timeline-control/__tests__/index.html deleted file mode 100644 index 17216896e..000000000 --- a/coverage/components/timeline-elements/timeline-control/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-control/__tests__

-
- -
- 100% - Statements - 67/67 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 67/67 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-control.test.tsx -
-
100%67/67100%6/6100%0/0100%67/67
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html b/coverage/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html deleted file mode 100644 index 8d78711f2..000000000 --- a/coverage/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control/__tests__ timeline-control.test.tsx

-
- -
- 100% - Statements - 67/67 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 67/67 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -781x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import userEvent from '@testing-library/user-event';
-import { vi } from 'vitest';
-import { commonProps, customRender, providerProps } from '../../../common/test';
-import Controls from '../timeline-control';
- 
-describe('TimelineControl', () => {
-  it('should render', () => {
-    const { container } = customRender(<Controls {...commonProps} />, {
-      providerProps,
-    });
-    expect(container).toMatchSnapshot();
-  });
- 
-  // check if all the buttons are rendered
-  it('should render all the buttons', () => {
-    const { getByLabelText } = customRender(<Controls {...commonProps} />, {
-      providerProps: { ...providerProps, enableDarkToggle: true },
-    });
-    expect(getByLabelText('first')).toBeInTheDocument();
-    expect(getByLabelText('previous')).toBeInTheDocument();
-    expect(getByLabelText('next')).toBeInTheDocument();
-    expect(getByLabelText('last')).toBeInTheDocument();
-    expect(getByLabelText('dark')).toBeInTheDocument();
-  });
- 
-  // should render the play button when slideShowEnabled is true
-  it('should render the play button when slideShowEnabled is true', () => {
-    const { getByLabelText } = customRender(
-      <Controls {...commonProps} slideShowEnabled slideShowRunning={false} />,
-      { providerProps },
-    );
-    expect(getByLabelText('start slideshow')).toBeInTheDocument();
-  });
- 
-  // check if all the callbacks are executed as expected
-  it('should execute the callbacks as expected', async () => {
-    const onFirst = vi.fn();
-    const onPrevious = vi.fn();
-    const onNext = vi.fn();
-    const onLast = vi.fn();
-    const onToggleDarkMode = vi.fn();
-    const user = userEvent.setup();
- 
-    const { getByLabelText } = customRender(
-      <Controls
-        {...commonProps}
-        onFirst={onFirst}
-        onPrevious={onPrevious}
-        onNext={onNext}
-        onLast={onLast}
-        onToggleDarkMode={onToggleDarkMode}
-      />,
-      { providerProps: { ...providerProps, enableDarkToggle: true } },
-    );
-    await user.click(getByLabelText('first'));
-    expect(onFirst).toHaveBeenCalled();
-    await user.click(getByLabelText('previous'));
-    expect(onPrevious).toHaveBeenCalled();
-    await user.click(getByLabelText('next'));
-    expect(onNext).toHaveBeenCalled();
-    await user.click(getByLabelText('last'));
-    expect(onLast).toHaveBeenCalled();
-    await user.click(getByLabelText('dark'));
-    expect(onToggleDarkMode).toHaveBeenCalled();
-  });
- 
-  // check if the navigation controls to be hidden / not shown when disableInteraction is set to true
-  it('should hide the navigation controls when disableInteraction is set to true', () => {
-    const { queryByLabelText } = customRender(<Controls {...commonProps} />, {
-      providerProps: { ...providerProps, disableInteraction: true },
-    });
-    expect(queryByLabelText('first')).not.toBeInTheDocument();
-    expect(queryByLabelText('previous')).not.toBeInTheDocument();
-    expect(queryByLabelText('next')).not.toBeInTheDocument();
-    expect(queryByLabelText('last')).not.toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-control/index.html b/coverage/components/timeline-elements/timeline-control/index.html deleted file mode 100644 index 67dbdac3b..000000000 --- a/coverage/components/timeline-elements/timeline-control/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-control

-
- -
- 91.46% - Statements - 225/246 -
- - -
- 62.65% - Branches - 52/83 -
- - -
- 50% - Functions - 1/2 -
- - -
- 91.46% - Lines - 225/246 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-control.styles.ts -
-
69.23%36/5291.66%22/24100%0/069.23%36/52
timeline-control.styles.tsx -
-
0%0/20%0/10%0/10%0/2
timeline-control.tsx -
-
98.43%189/19251.72%30/58100%1/198.43%189/192
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-control/timeline-control.styles.ts.html b/coverage/components/timeline-elements/timeline-control/timeline-control.styles.ts.html deleted file mode 100644 index bd342ad77..000000000 --- a/coverage/components/timeline-elements/timeline-control/timeline-control.styles.ts.html +++ /dev/null @@ -1,625 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/timeline-control.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control timeline-control.styles.ts

-
- -
- 69.23% - Statements - 36/52 -
- - -
- 91.66% - Branches - 22/24 -
- - -
- 100% - Functions - 0/0 -
- - -
- 69.23% - Lines - 36/52 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -  -1x -1x -1x -1x -1x -  -  -  -  -1x -  -1x -  -1x -  -  -1x -64x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-export const ScreenReaderOnly = styled.div`
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  margin: -1px;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  white-space: nowrap;
-  border-width: 0;
-`;
- 
-export const TimelineNavWrapper = styled.div<{ theme?: Theme }>`
-  border-radius: 8px;
-  display: flex;
-  list-style: none;
-  padding: 0.25rem;
-  // box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-  background: ${(p) => p.theme.toolbarBgColor};
-  // border: 1px solid ${(p) => p.theme.toolbarBtnBgColor};
-  position: relative;
-  z-index: ${zIndex.controls};
- 
-  .nav-item {
-    padding: 0;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
- 
-    &.disabled {
-      pointer-events: none;
-      filter: opacity(0.4);
-    }
-  }
-`;
- 
-export const TimelineNavItem = styled.li<{ $disable?: boolean }>`
-  padding: 0;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  ${(p) =>
-    p.$disable
-      ? 'pointer-events: none; filter: opacity(0.4);'
-      : 'cursor: pointer;'};
-`;
- 
-export const TimelineNavButton = styled.button<{
-  mode?: TimelineMode;
-  rotate?: 'TRUE' | 'FALSE';
-  theme?: Theme;
-  $active?: boolean;
-}>`
-  align-items: center;
-  background: ${(p) => p.theme.toolbarBtnBgColor};
-  border-radius: 6px;
-  border: 1px solid ${(p) => p.theme.buttonBorderColor ?? 'transparent'};
-  color: ${(p) => p.theme.toolbarTextColor ?? p.theme.secondary};
-  cursor: pointer;
-  display: flex;
-  height: 28px;
-  justify-content: center;
-  margin: 0 0.2rem;
-  padding: 0;
-  transition:
-    background-color 0.2s ease-out,
-    transform 0.15s ease-out,
-    box-shadow 0.2s ease-out,
-    border-color 0.2s ease-out;
-  width: 28px;
-  box-shadow: 0 1px 1px ${(p) => p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.08)'};
- 
-  transform: ${(p) => (p.rotate === 'TRUE' ? 'rotate(90deg)' : 'none')};
- 
-  &:hover {
-    background: ${(p) =>
-      p.theme.buttonHoverBgColor ?? p.theme.toolbarBtnBgColor};
-    border-color: ${(p) => p.theme.buttonHoverBorderColor ?? p.theme.primary};
-    box-shadow: 0 2px 4px ${(p) => p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.12)'};
-    transform: ${(p) => (p.rotate === 'TRUE' ? 'rotate(90deg)' : 'none')}
-      translateY(-1px);
-  }
- 
-  &:active {
-    transform: ${(p) => (p.rotate === 'TRUE' ? 'rotate(90deg)' : 'none')}
-      scale(0.95);
-    background: ${(p) => p.theme.toolbarBtnBgColor};
-    box-shadow: inset 0 1px 1px
-      ${(p) => p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.1)'};
-  }
- 
-  ${(p) =>
-    p.$active &&
-    css`
-      background: ${p.theme.darkToggleActiveBgColor ?? p.theme.secondary};
-      border-color: ${p.theme.darkToggleActiveBorderColor ?? p.theme.primary};
-      box-shadow: 0 0 0 2px
-        ${p.theme.darkToggleGlowColor ??
-        p.theme.glowColor ??
-        'rgba(59, 130, 246, 0.3)'};
- 
-      &:hover {
-        background: ${p.theme.buttonHoverBgColor ?? p.theme.secondary};
-        opacity: 0.9;
-        box-shadow:
-          0 2px 4px ${p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.12)'},
-          0 0 0 2px
-            ${p.theme.darkToggleGlowColor ??
-            p.theme.glowColor ??
-            'rgba(59, 130, 246, 0.4)'};
-      }
- 
-      svg {
-        color: ${p.theme.darkToggleActiveIconColor ??
-        p.theme.buttonActiveIconColor ??
-        '#fff'};
-      }
-    `}
- 
-  svg {
-    width: 75%;
-    height: 75%;
-    color: ${(p) => p.theme.iconColor ?? p.theme.primary};
-    transition: color 0.2s ease-out;
-  }
-`;
- 
-// Control container with improved layout
-export const ControlContainer = styled.div<{ theme: Theme }>`
-  display: -webkit-box;
-  display: -ms-flexbox;
-  display: flex;
-  -webkit-box-align: center;
-  -ms-flex-align: center;
-  align-items: center;
-  gap: 0.5rem;
-  padding: 0.5rem;
-  background: ${(p) => p.theme.cardBgColor};
-  border-radius: 4px;
-  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-`;
- 
-export const TimelineControlContainer = styled.div`
-  align-items: center;
-  display: flex;
-  justify-content: center;
-  margin: 0.5rem 0;
-  position: relative;
-  z-index: ${zIndex.controls};
-`;
- 
-export const ControlButton = styled.button<{ theme?: Theme }>`
-  align-items: center;
-  background: ${(p) => p.theme.primary};
-  border-radius: 50%;
-  cursor: pointer;
-  display: flex;
-  height: 3em;
-  justify-content: center;
-  margin-left: 0.5em;
-  width: 3em;
-  outline: 0;
-  color: #fff;
- 
-  svg {
-    width: 80%;
-    height: 80%;
-  }
-`;
- 
-export const MediaToggle = styled(ControlButton)``;
- 
-export const ReplayWrapper = styled(ControlButton)``;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html b/coverage/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html deleted file mode 100644 index 8eda4a956..000000000 --- a/coverage/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/timeline-control.styles.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control timeline-control.styles.tsx

-
- -
- 0% - Statements - 0/2 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/2 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
import styled from 'styled-components';
- 
-export const ScreenReaderOnly = styled.div`
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  margin: -1px;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  white-space: nowrap;
-  border-width: 0;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-control/timeline-control.tsx.html b/coverage/components/timeline-elements/timeline-control/timeline-control.tsx.html deleted file mode 100644 index 0f542c1f2..000000000 --- a/coverage/components/timeline-elements/timeline-control/timeline-control.tsx.html +++ /dev/null @@ -1,871 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/timeline-control.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control timeline-control.tsx

-
- -
- 98.43% - Statements - 189/192 -
- - -
- 51.72% - Branches - 30/58 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.43% - Lines - 189/192 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -  -12x -  -  -12x -  -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -  -12x -  -12x -  -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -  -12x -11x -6x -12x -  -  -12x -11x -11x -12x -  -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -12x -  -  -12x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -  -  -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -  -  -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -  -  -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -11x -  -  -  -12x -12x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -  -12x -  -  -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -  -12x -12x -12x -  -12x -12x -  -12x -  -1x -  -1x - 
import { TimelineControlModel } from '@models/TimelineControlModel';
-import cls from 'classnames';
-import React, { useCallback, useMemo } from 'react';
-import { useStableContext, useDynamicContext } from '../../contexts';
-import { MoonIcon, StopIcon, SunIcon } from '../../icons';
-import ChevronLeft from '../../icons/chev-left';
-import ChevronRightIcon from '../../icons/chev-right';
-import ChevronsLeftIcon from '../../icons/chevs-left';
-import ChevronsRightIcon from '../../icons/chevs-right';
-import ReplayIcon from '../../icons/replay-icon';
-import {
-  TimelineControlContainer,
-  TimelineNavButton,
-  TimelineNavWrapper,
-  ScreenReaderOnly,
-} from './timeline-control.styles';
- 
-/**
- * TimelineControl component
- * Provides navigation controls for a timeline, including next, previous, first, last, and slideshow buttons.
- * Optionally supports flipping the layout and dark mode toggle.
- *
- * @property {function} onNext - Function to go to the next item.
- * @property {function} onPrevious - Function to go to the previous item.
- * @property {function} onFirst - Function to jump to the first item.
- * @property {function} onLast - Function to jump to the last item.
- * @property {boolean} disableLeft - Whether to disable the left navigation buttons.
- * @property {boolean} disableRight - Whether to disable the right navigation buttons.
- * @property {boolean} slideShowRunning - Whether the slideshow is currently running.
- * @property {function} onReplay - Function to restart the slideshow.
- * @property {boolean} slideShowEnabled - Whether the slideshow feature is enabled.
- * @property {function} onToggleDarkMode - Function to toggle dark mode (if enabled).
- * @property {boolean} isDark - Whether dark mode is currently active.
- * @property {function} onPaused - Function to pause the slideshow (if running).
- * @returns {JSX.Element} The TimelineControl component.
- */
-const Controls: React.FunctionComponent<TimelineControlModel> = ({
-  onNext,
-  onPrevious,
-  onFirst,
-  onLast,
-  disableLeft,
-  disableRight,
-  slideShowRunning,
-  onReplay,
-  slideShowEnabled,
-  onToggleDarkMode,
-  isDark,
-  onPaused,
-  activeTimelineItem = 0,
-  totalItems = 0,
-}: TimelineControlModel) => {
-  const {
-    mode,
-    flipLayout,
-    memoizedButtonTexts: buttonTexts,
-    memoizedClassNames: classNames,
-    disableInteraction,
-    staticDefaults,
-  } = useStableContext();
- 
-  const { memoizedTheme: theme } = useDynamicContext();
- 
-  // Get enableDarkToggle from the stable context
-  const enableDarkToggle = staticDefaults.enableDarkToggle;
- 
-  const rotate = useMemo(() => mode !== 'HORIZONTAL', [mode]);
- 
-  const flippedHorizontally = useMemo(
-    () => flipLayout && mode === 'HORIZONTAL',
-    [],
-  );
- 
-  const canDisableLeft = useMemo(
-    () => disableLeft || slideShowRunning,
-    [disableLeft, slideShowRunning],
-  );
- 
-  const canDisableRight = useMemo(
-    () => disableRight || slideShowRunning,
-    [disableRight, slideShowRunning],
-  );
- 
-  const handlePause = useCallback(() => {
-    onPaused?.();
-  }, [onPaused]);
- 
-  const handlePlay = useCallback(() => {
-    onReplay?.();
-  }, [onReplay]);
- 
-  const previousTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.next : buttonTexts?.previous),
-    [flipLayout],
-  );
- 
-  const nextTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.previous : buttonTexts?.next),
-    [flipLayout],
-  );
- 
-  const playOrPauseTile = useMemo(
-    () => (slideShowRunning ? buttonTexts?.stop : buttonTexts?.play),
-    [slideShowRunning],
-  );
- 
-  const jumpToLastTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.first : buttonTexts?.last),
-    [flipLayout],
-  );
- 
-  const jumpToFirstTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.last : buttonTexts?.first),
-    [flipLayout],
-  );
- 
-  // Create a message about current position for screen readers
-  const positionStatus = useMemo(() => {
-    if (totalItems <= 0) return '';
-    return `Item ${activeTimelineItem + 1} of ${totalItems}`;
-  }, [activeTimelineItem, totalItems]);
- 
-  // Create a message about slideshow status for screen readers
-  const slideshowStatus = useMemo(() => {
-    if (!slideShowEnabled) return '';
-    return slideShowRunning ? 'Slideshow is playing' : 'Slideshow is paused';
-  }, [slideShowRunning, slideShowEnabled]);
- 
-  return (
-    <TimelineControlContainer key="control-wrapper">
-      {/* Visually hidden status information for screen readers */}
-      <ScreenReaderOnly as="output" aria-live="polite">
-        {positionStatus}
-        {slideshowStatus && ` ${slideshowStatus}`}
-      </ScreenReaderOnly>
- 
-      <TimelineNavWrapper
-        className={cls('timeline-controls', classNames?.controls)}
-        theme={theme}
-        aria-label="Timeline Navigation"
-        role="toolbar"
-      >
-        {/* jump to first */}
-        {disableInteraction ? null : (
-          <>
-            <div className={`nav-item ${canDisableLeft ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onLast : onFirst}
-                title={jumpToFirstTitle}
-                aria-label={jumpToFirstTitle}
-                aria-disabled={disableLeft}
-                aria-controls="timeline-main-wrapper"
-                tabIndex={!disableLeft ? 0 : -1}
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                data-test-id="jump-to-first"
-              >
-                <ChevronsLeftIcon />
-              </TimelineNavButton>
-            </div>
- 
-            {/* previous */}
-            <div className={`nav-item ${canDisableLeft ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onNext : onPrevious}
-                title={previousTitle}
-                aria-label={previousTitle}
-                aria-disabled={disableLeft}
-                aria-controls="timeline-main-wrapper"
-                tabIndex={!disableLeft ? 0 : -1}
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                data-test-id="previous"
-              >
-                <ChevronLeft />
-              </TimelineNavButton>
-            </div>
- 
-            {/* next */}
-            <div className={`nav-item ${canDisableRight ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onPrevious : onNext}
-                title={nextTitle}
-                aria-label={nextTitle}
-                aria-disabled={disableRight}
-                aria-controls="timeline-main-wrapper"
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                tabIndex={!disableRight ? 0 : -1}
-                data-test-id="next"
-              >
-                <ChevronRightIcon />
-              </TimelineNavButton>
-            </div>
- 
-            {/* jump to last */}
-            <div className={`nav-item ${canDisableRight ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onFirst : onLast}
-                title={jumpToLastTitle}
-                aria-label={jumpToLastTitle}
-                aria-disabled={disableRight}
-                aria-controls="timeline-main-wrapper"
-                tabIndex={!disableRight ? 0 : -1}
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                data-test-id="jump-to-last"
-              >
-                <ChevronsRightIcon />
-              </TimelineNavButton>
-            </div>
-          </>
-        )}
- 
-        {/* slideshow button */}
-        <div className="nav-item">
-          {slideShowEnabled && (
-            <TimelineNavButton
-              theme={theme}
-              onClick={slideShowRunning ? handlePause : handlePlay}
-              title={playOrPauseTile}
-              tabIndex={0}
-              aria-controls="timeline-main-wrapper"
-              aria-label={playOrPauseTile}
-              aria-pressed={slideShowRunning ? 'true' : 'false'}
-              data-test-id="play-pause"
-            >
-              {slideShowRunning ? <StopIcon /> : <ReplayIcon />}
-            </TimelineNavButton>
-          )}
-        </div>
- 
-        {/* dark toggle button */}
-        {enableDarkToggle ? (
-          <div className={`nav-item ${slideShowRunning ? 'disabled' : ''}`}>
-            <TimelineNavButton
-              theme={theme}
-              onClick={onToggleDarkMode}
-              title={isDark ? buttonTexts?.light : buttonTexts?.dark}
-              tabIndex={0}
-              aria-controls="timeline-main-wrapper"
-              aria-label={isDark ? buttonTexts?.light : buttonTexts?.dark}
-              aria-pressed={isDark ? 'true' : 'false'}
-              data-test-id="dark-toggle"
-              $active={isDark}
-            >
-              {isDark ? <SunIcon /> : <MoonIcon />}
-            </TimelineNavButton>
-          </div>
-        ) : null}
-      </TimelineNavWrapper>
-    </TimelineControlContainer>
-  );
-};
- 
-Controls.displayName = 'Timeline Control';
- 
-export default Controls;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-controls-wrapper/index.html b/coverage/components/timeline-elements/timeline-controls-wrapper/index.html deleted file mode 100644 index 9833eeae6..000000000 --- a/coverage/components/timeline-elements/timeline-controls-wrapper/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-controls-wrapper - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-controls-wrapper

-
- -
- 0% - Statements - 0/8 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 0% - Lines - 0/8 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-controls-wrapper.tsx -
-
0%0/8100%1/1100%1/10%0/8
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html b/coverage/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html deleted file mode 100644 index b37c8404a..000000000 --- a/coverage/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-controls-wrapper timeline-controls-wrapper.tsx

-
- -
- 0% - Statements - 0/8 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 0% - Lines - 0/8 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import React from 'react';
-import styled from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-/**
- * Wraps timeline controls and provides proper z-index stacking context
- */
-const ControlsWrapper = styled.div`
-  position: relative;
-  z-index: ${zIndex.controls};
-`;
- 
-interface TimelineControlsWrapperProps {
-  children: React.ReactNode;
-}
- 
-/**
- * A wrapper component that ensures proper z-index stacking of timeline controls
- * This helps prevent z-index conflicts between timeline points and controls/menus
- */
-const TimelineControlsWrapper: React.FC<TimelineControlsWrapperProps> = ({ children }) => {
-  return <ControlsWrapper>{children}</ControlsWrapper>;
-};
- 
-export default TimelineControlsWrapper;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-item-title/__tests__/index.html b/coverage/components/timeline-elements/timeline-item-title/__tests__/index.html deleted file mode 100644 index 8880046cf..000000000 --- a/coverage/components/timeline-elements/timeline-item-title/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-item-title/__tests__

-
- -
- 100% - Statements - 46/46 -
- - -
- 100% - Branches - 7/7 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 46/46 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-title.test.tsx -
-
100%46/46100%7/7100%0/0100%46/46
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html b/coverage/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html deleted file mode 100644 index eb1c218ca..000000000 --- a/coverage/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-item-title/__tests__ timeline-card-title.test.tsx

-
- -
- 100% - Statements - 46/46 -
- - -
- 100% - Branches - 7/7 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 46/46 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -601x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x - 
import { waitFor } from '@testing-library/react';
-import { describe } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import TimelineItemTitle from '../timeline-card-title';
- 
-describe('Timeline item title', () => {
-  //should render the title
-  it('should render the title', () => {
-    const { getByText } = customRender(<TimelineItemTitle title="title" />, {
-      providerProps,
-    });
-    expect(getByText('title')).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot', () => {
-    const { container } = customRender(<TimelineItemTitle title="title" />, {
-      providerProps,
-    });
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render the title with active class
-  it('should render the title with active class', () => {
-    const { getByText } = customRender(
-      <TimelineItemTitle title="title" active />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByText('title')).toHaveClass('active');
-  });
- 
-  // should render the title with custom class
-  it('should render the title with custom class', () => {
-    const { getByText } = customRender(
-      <TimelineItemTitle title="title" classString="custom-class" />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByText('title')).toHaveClass('custom-class');
-  });
- 
-  // should have a custom alignment
-  it('should have a custom alignment', async () => {
-    const { getByText } = customRender(
-      <TimelineItemTitle title="title" align="left" />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
- 
-    await waitFor(() => {
-      expect(getByText('title')).toHaveProperty('align');
-      expect(getByText('title')).toHaveProperty('align', 'left');
-      // expect(getByText('title')).toHaveStyle('text-align: left');
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-item-title/index.html b/coverage/components/timeline-elements/timeline-item-title/index.html deleted file mode 100644 index e36e1e0fb..000000000 --- a/coverage/components/timeline-elements/timeline-item-title/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-item-title

-
- -
- 100% - Statements - 37/37 -
- - -
- 95% - Branches - 19/20 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 37/37 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-title.styles.ts -
-
100%9/993.33%14/15100%0/0100%9/9
timeline-card-title.tsx -
-
100%28/28100%5/5100%1/1100%28/28
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html b/coverage/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html deleted file mode 100644 index 0e4942fa5..000000000 --- a/coverage/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-item-title timeline-card-title.styles.ts

-
- -
- 100% - Statements - 9/9 -
- - -
- 93.33% - Branches - 14/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 9/9 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31  -1x -  -1x -  -  -  -  -  -  -1x -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -1x -1x -1x -  -  - 
import { Theme } from '@models/Theme';
-import styled from 'styled-components';
- 
-export const TitleWrapper = styled.div<{
-  $fontSize?: string;
-  $hide?: boolean;
-  align?: string;
-  theme?: Theme;
-}>`
-  border-radius: 0.2rem;
-  font-size: ${(p) => (p.$fontSize ? p.$fontSize : '1rem')};
-  font-weight: 600;
-  overflow: hidden;
-  padding: 0.25rem;
-  visibility: ${(p) => (p.$hide ? 'hidden' : 'visible')};
-  text-align: ${(p) => (p.align ? p.align : '')};
-  color: ${(p) => (p.theme ? p.theme.titleColor : '')};
- 
-  /* --- Prevent long text from affecting layout --- */
-  white-space: nowrap; /* Prevent text from wrapping to multiple lines */
-  text-overflow: ellipsis; /* Show ellipsis (...) for overflowing text */
-  min-width: 0; /* Allow the element to shrink below its content size */
-  max-width: 100%; /* Ensure it doesn't exceed its container */
- 
-  &.active {
-    background: ${(p) => p.theme?.secondary};
-    color: ${(p) =>
-      p.theme?.titleColorActive ? p.theme?.titleColorActive : p.theme?.primary};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html b/coverage/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html deleted file mode 100644 index 482e176f4..000000000 --- a/coverage/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/timeline-card-title.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-item-title timeline-card-title.tsx

-
- -
- 100% - Statements - 28/28 -
- - -
- 100% - Branches - 5/5 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 28/28 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50  -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -94x -94x -94x -94x -94x -94x -94x -  -  -94x -94x -94x -94x -  -  -94x -  -94x -94x -94x -94x -94x -94x -94x -  -94x -94x -  -94x -  -1x - 
import { TitleModel } from '@models/TimelineCardTitleModel';
-import cls from 'classnames';
-import React, { useContext, useMemo } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { TitleWrapper } from './timeline-card-title.styles';
- 
-/**
- * TimelineItemTitle component
- * This component renders the title of a timeline item and applies appropriate styling based on the given props.
- *
- * @property {string} title - The text of the title.
- * @property {boolean} active - Indicates whether the title is active or not.
- * @property {Theme} theme - The theme object, used for styling.
- * @property {string} align - The alignment of the title.
- * @property {string} classString - Additional CSS classes for the title.
- * @returns {JSX.Element} The TimelineItemTitle component.
- */
-const TimelineItemTitle: React.FunctionComponent<TitleModel> = ({
-  title,
-  active,
-  theme,
-  align,
-  classString,
-}: TitleModel) => {
-  const TITLE_CLASS = 'timeline-item-title'; // Base class name for the title
- 
-  // Computed class name for the title, combining base class, active state, and additional classes
-  const titleClass = useMemo(
-    () => cls(TITLE_CLASS, active ? 'active' : '', classString),
-    [active, classString],
-  );
- 
-  // Get font size from global context
-  const { fontSizes } = useContext(GlobalContext);
- 
-  return (
-    <TitleWrapper
-      className={titleClass}
-      theme={theme}
-      $hide={!title}
-      align={align}
-      $fontSize={fontSizes?.title}
-    >
-      {title}
-    </TitleWrapper>
-  );
-};
- 
-export default TimelineItemTitle;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/__tests__/index.html b/coverage/components/timeline-elements/timeline-outline/__tests__/index.html deleted file mode 100644 index 00bb2572a..000000000 --- a/coverage/components/timeline-elements/timeline-outline/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-outline/__tests__

-
- -
- 94.69% - Statements - 107/113 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 94.69% - Lines - 107/113 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-outline.test.tsx -
-
94.69%107/113100%13/13100%0/094.69%107/113
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html b/coverage/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html deleted file mode 100644 index a32f4d52e..000000000 --- a/coverage/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline/__tests__ timeline-outline.test.tsx

-
- -
- 94.69% - Statements - 107/113 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 94.69% - Lines - 107/113 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140  -1x -1x -  -1x -  -  -  -1x -  -  -  -  -  -  -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -6x -6x -6x -6x -6x -6x -6x -1x -  -1x -6x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import React from 'react';
-import { render, fireEvent, waitFor } from '@testing-library/react';
-import { TimelineOutline } from '../timeline-outline'; // Update import based on your actual file path
-import { Theme } from '@models/Theme';
-import { vi, Mock } from 'vitest';
-import { TimelineOutlineItem } from '../timeline-outline.model';
- 
-// Mock GlobalContext and icons
-vi.mock('../../GlobalContext', () => ({
-  GlobalContext: {
-    Consumer: ({ children }) =>
-      children({
-        theme: {},
-      }),
-  },
-}));
- 
-vi.mock('../../icons/close', () => () => 'CloseIcon');
-vi.mock('../../icons/menu', () => () => 'MenuIcon');
- 
-describe('<TimelineOutline />', () => {
-  let mockItems: TimelineOutlineItem[];
-  let mockTheme: Theme;
-  let mockOnSelect: Mock;
- 
-  beforeEach(() => {
-    mockItems = [
-      { id: '1', name: 'Item 1', selected: false },
-      { id: '2', name: 'Item 2', selected: true },
-      { id: '3', name: 'Item 3', selected: false },
-    ];
-    mockTheme = {}; // Add any specific theme details if needed
-    mockOnSelect = vi.fn();
-  });
- 
-  afterEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  // Test 1: Component rendering
-  it('should render correctly with initial state', () => {
-    const { getByRole, queryByText } = render(
-      <TimelineOutline
-        items={mockItems}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
-    expect(getByRole('button')).toBeInTheDocument();
-    expect(queryByText('Item 1')).not.toBeInTheDocument(); // List should be hidden initially
-  });
- 
-  // Test 2: Test component interactions (Toggle Pane)
-  it('should toggle pane on button click', async () => {
-    const { getByText, getByRole } = render(
-      <TimelineOutline
-        items={mockItems}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
- 
-    fireEvent.pointerDown(getByRole('button'));
- 
-    await waitFor(() => {
-      expect(getByText('Item 1')).toBeInTheDocument(); // List should be visible now
-    });
-  });
- 
-  // // Test 3: Test component state and props (Items and Selection)
-  it('should correctly handle item selection', async () => {
-    const { getByRole, getByText } = render(
-      <TimelineOutline
-        items={mockItems}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
- 
-    fireEvent.pointerDown(getByRole('button'));
- 
-    await waitFor(() => {
-      expect(getByText('Item 1')).toBeInTheDocument(); // List should be visible now
-      fireEvent.pointerDown(getByText('Item 1'));
-    });
- 
-    await waitFor(() => {
-      expect(mockOnSelect).toHaveBeenCalledWith(0); // The index of the clicked item should be 0
-    });
-  });
- 
-  // // Test 4: Test component state and props (Edge Cases)
-  it('should handle empty items array gracefully', async () => {
-    const { getByRole, queryByText } = render(
-      <TimelineOutline
-        items={[]}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
- 
-    fireEvent.pointerDown(getByRole('button'));
- 
-    await waitFor(() => {
-      expect(queryByText('Item 1')).not.toBeInTheDocument(); // No items should be displayed
-    });
-  });
- 
-  it('should show loading state', () => {
-    const { getByRole } = render(
-      <TimelineOutline
-        items={mockItems}
-        isLoading={true}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
-    expect(getByRole('status')).toHaveTextContent('Loading outline...');
-  });
- 
-  it('should show error state', () => {
-    const error = new Error('Test error');
-    const { getByRole } = render(
-      <TimelineOutline
-        items={mockItems}
-        error={error}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
-    expect(getByRole('alert')).toHaveTextContent('Error: Test error');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/animations.ts.html b/coverage/components/timeline-elements/timeline-outline/animations.ts.html deleted file mode 100644 index 5827b57ad..000000000 --- a/coverage/components/timeline-elements/timeline-outline/animations.ts.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/animations.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline animations.ts

-
- -
- 0% - Statements - 0/3 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/3 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { keyframes } from 'styled-components';
- 
-export const open = keyframes`
-  from {
-    width: 30px;
-    height: 30px;
-    opacity: 0.5;
-  }
- 
-  to {
-    width: 200px;
-    height: 50%;
-    opacity: 1;
-  }
-`;
- 
-export const close = keyframes`
-  from {
-    width: 200px;
-    height: 50%;
-    opacity: 1;
-  }
- 
-  to {
-    width: 30px;
-    height: 30px;
-    opacity: 0.5;
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/hooks/index.html b/coverage/components/timeline-elements/timeline-outline/hooks/index.html deleted file mode 100644 index c0d525dad..000000000 --- a/coverage/components/timeline-elements/timeline-outline/hooks/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/hooks - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-outline/hooks

-
- -
- 90.9% - Statements - 10/11 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 90.9% - Lines - 10/11 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useOutlinePosition.ts -
-
90.9%10/1150%2/4100%1/190.9%10/11
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html b/coverage/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html deleted file mode 100644 index 4f18dd3a6..000000000 --- a/coverage/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline/hooks useOutlinePosition.ts

-
- -
- 90.9% - Statements - 10/11 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 90.9% - Lines - 10/11 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -201x -  -1x -  -  -  -  -  -  -  -1x -12x -12x -6x -6x -  -12x -12x -12x - 
import { useMemo } from 'react';
-import { TimelineMode } from '@models/TimelineModel';
-import { OutlinePosition } from '../timeline-outline.model';
- 
-/**
- * Custom hook to determine the outline position based on timeline mode
- *
- * @param mode - The current timeline mode
- * @returns The position of the outline
- */
-export const useOutlinePosition = (mode?: TimelineMode): OutlinePosition => {
-  return useMemo(
-    () =>
-      mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING'
-        ? OutlinePosition.right
-        : OutlinePosition.left,
-    [mode],
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/index.html b/coverage/components/timeline-elements/timeline-outline/index.html deleted file mode 100644 index d2f34d335..000000000 --- a/coverage/components/timeline-elements/timeline-outline/index.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-outline

-
- -
- 92.06% - Statements - 174/189 -
- - -
- 85% - Branches - 51/60 -
- - -
- 71.42% - Functions - 5/7 -
- - -
- 92.06% - Lines - 174/189 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
animations.ts -
-
0%0/30%0/10%0/10%0/3
timeline-outline-item-list.tsx -
-
86.66%52/6055.55%5/9100%0/086.66%52/60
timeline-outline.model.ts -
-
100%3/3100%1/1100%0/0100%3/3
timeline-outline.styles.ts -
-
97.36%37/3889.65%26/29100%3/397.36%37/38
timeline-outline.tsx -
-
96.47%82/8595%19/2066.66%2/396.47%82/85
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html b/coverage/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html deleted file mode 100644 index f35da98be..000000000 --- a/coverage/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html +++ /dev/null @@ -1,394 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline-item-list.tsx

-
- -
- 86.66% - Statements - 52/60 -
- - -
- 55.55% - Branches - 5/9 -
- - -
- 100% - Functions - 0/0 -
- - -
- 86.66% - Lines - 52/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104  -1x -  -  -  -  -  -1x -  -1x -  -  -1x -1x -6x -6x -6x -6x -6x -  -  -  -  -6x -6x -6x -6x -6x -  -6x -6x -6x -6x -6x -6x -6x -  -6x -6x -6x -6x -6x -  -6x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -3x -  -  -  -3x -  -3x -  -  -  -  -  -  -  -3x -  -3x -3x -3x -6x -6x -6x -6x -6x -6x -6x -3x -3x -  -  -  -  -  -  -3x -  -3x -1x -  -1x -  -  - 
import { Theme } from '@models/Theme';
-import {
-  List,
-  ListItem,
-  ListItemBullet,
-  ListItemName,
-} from './timeline-outline.styles';
-import { memo, FunctionComponent, useCallback, useMemo } from 'react';
-import { TimelineOutlineItem } from './timeline-outline.model';
-import { useWindowSize } from '../../../hooks/useWindowSize';
- 
-// Extract item into its own component for better performance
-const OutlineItem = memo(
-  ({
-    item,
-    index,
-    handleSelection,
-    theme,
-  }: {
-    item: TimelineOutlineItem;
-    index: number;
-    handleSelection: (index: number, id?: string) => void;
-    theme: Theme;
-  }) => {
-    const onClick = useCallback(
-      () => handleSelection(index, item.id),
-      [handleSelection, index, item.id],
-    );
- 
-    return (
-      <ListItem
-        key={item.id ?? index}
-        onPointerDown={onClick}
-        aria-disabled={item.disabled}
-        aria-selected={item.selected}
-        aria-label={item.ariaLabel ?? item.name}
-      >
-        <ListItemBullet theme={theme} selected={item.selected}></ListItemBullet>
-        <ListItemName theme={theme} selected={item.selected}>
-          {item.name}
-        </ListItemName>
-      </ListItem>
-    );
-  },
-);
- 
-OutlineItem.displayName = 'OutlineItem';
- 
-interface OutlineItemListModel {
-  handleSelection: (index: number, id?: string) => void;
-  items: TimelineOutlineItem[];
-  theme: Theme;
-}
- 
-/**
- * OutlineItemList component
- * This component is responsible for rendering the outline list of items.
- * It uses virtualization for better performance with long lists.
- */
-const OutlineItemList: FunctionComponent<OutlineItemListModel> = memo(
-  ({ items, handleSelection, theme }) => {
-    const { height } = useWindowSize();
- 
-    // Only render the visible items based on window size
-    // In a real implementation, you'd use a proper virtualization library
-    const visibleItems = useMemo(() => {
-      // If list is small, render all items
-      if (items.length < 50) return items;
- 
-      const itemHeight = 30; // Approximate height of an item
-      const visibleCount = Math.ceil(height / itemHeight);
- 
-      // In a real virtualization implementation, you'd calculate visible range
-      // based on scroll position. This is a simplified version.
-      return items.slice(0, visibleCount * 2);
-    }, [items, height]);
- 
-    return (
-      <List>
-        {visibleItems.map((item, index) => (
-          <OutlineItem
-            key={item.id ?? index}
-            item={item}
-            index={index}
-            handleSelection={handleSelection}
-            theme={theme}
-          />
-        ))}
-        {items.length > visibleItems.length && (
-          <ListItem>
-            <ListItemName theme={theme}>
-              {`+ ${items.length - visibleItems.length} more items`}
-            </ListItemName>
-          </ListItem>
-        )}
-      </List>
-    );
-  },
-);
- 
-OutlineItemList.displayName = 'OutlineItemList';
- 
-export { OutlineItemList };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html b/coverage/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html deleted file mode 100644 index 59da44089..000000000 --- a/coverage/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline.model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline.model.ts

-
- -
- 100% - Statements - 3/3 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 3/3 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
- 
-export enum OutlinePosition {
-  'left',
-  'right',
-}
- 
-export interface TimelineOutlineModel {
-  items?: TimelineOutlineItem[];
-  mode?: TimelineMode;
-  onSelect?: (index: number) => void;
-  theme?: Theme;
-  isLoading?: boolean;
-  error?: Error | null;
-  onError?: (error: Error) => void;
-}
- 
-export interface TimelineOutlineItem {
-  id?: string;
-  name?: string;
-  selected?: boolean;
-  disabled?: boolean;
-  ariaLabel?: string;
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html b/coverage/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html deleted file mode 100644 index 5d0f203e6..000000000 --- a/coverage/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html +++ /dev/null @@ -1,607 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline.styles.ts

-
- -
- 97.36% - Statements - 37/38 -
- - -
- 89.65% - Branches - 26/29 -
- - -
- 100% - Functions - 3/3 -
- - -
- 97.36% - Lines - 37/38 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175  -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -1x -  -  -1x -1x -1x -10x -6x -  -  -  -1x -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -10x -  -1x -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -1x -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -6x -2x -1x -  -  -1x -6x -2x -1x -  -  - 
import { Theme } from '@models/Theme';
-import styled, { keyframes } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
-import { OutlinePosition } from './timeline-outline.model';
- 
-const open = keyframes`
-  from {
-    width: 30px;
-    height: 30px;
-  }
- 
-  to: {
-    width: 200px;
-    height: 50%;
-  }
-  `;
- 
-const close = keyframes`
-  from {
-    width: 200px;
-    height: 50%;
-  }
- 
-  to: {
-    width: 30px;
-    height: 30px;
-  }
-`;
- 
-export const OutlineWrapper = styled.div<{
-  open?: boolean;
-  position?: OutlinePosition;
-}>`
-  animation: ${(p) => (p.open ? open : close)};
-  animation-duration: 0.2s;
-  animation-timing-function: ease-in;
-  background: rgba(255, 255, 255, 0.98);
-  border: 1px solid ${(p) => (p.open ? '#f5f5f5' : 'none')};
-  height: 50%;
-  width: 100%;
-  ${(p) =>
-    p.position === OutlinePosition.left ? `left: 1rem;` : `right: 3rem;`};
-  ${(p) =>
-    p.open
-      ? `
-    width: 200px;
-    height: 50%;
-    overflow-y: auto;`
-      : `width: 30px; height: 30px;`};
-`;
- 
-export const OutlinePane = styled.aside<{ open?: boolean; theme?: Theme }>`
-  align-items: center;
-  border-radius: 4px;
-  display: flex;
-  justify-content: center;
-  position: absolute;
-  z-index: ${zIndex.modal}; /* Use standardized z-index for outline panel */
-  box-shadow: 0 5px 10px 2px
-    rgba(
-      0,
-      0,
-      0,
-      ${({ theme }) => (theme?.toolbarBgColor === '#374151' ? '0.5' : '0.2')}
-    );
-  top: 1rem;
-`;
- 
-export const OutlineButton = styled.button<{
-  open?: boolean;
-  position?: OutlinePosition;
-  theme?: Theme;
-}>`
-  align-items: center;
-  align-self: flex-end;
-  background: #fff;
-  border-radius: 4px;
-  border: 0;
-  // box-shadow: ${(p) => (!p.open ? '0 0 10px 2px rgba(0,0,0,0.2)' : 'none')};
-  cursor: pointer;
-  display: flex;
-  height: 30px;
-  justify-content: center;
-  padding: 0;
-  width: 30px;
- 
-  ${(p) =>
-    p.position === OutlinePosition.left
-      ? 'margin-right: auto;'
-      : 'margin-left: auto;'};
- 
-  & svg {
-    width: 70%;
-    height: 70%;
-  }
- 
-  & svg path {
-    color: ${(p) => p.theme.iconColor || p.theme.primary};
-  }
-`;
- 
-export const List = styled.ul`
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-  list-style: none;
-  margin: 0;
-  overflow-y: auto;
-  padding: 0;
-  width: 80%;
-`;
- 
-export const ListItem = styled.li`
-  align-items: center;
-  display: flex;
-  font-size: 0.9rem;
-  justify-content: flex-start;
-  margin: 0.75rem 0;
-  cursor: pointer;
-  position: relative;
- 
-  &:not(:last-child)::after {
-    content: '';
-    display: block;
-    width: 100%;
-    position: absolute;
-    height: 1px;
-    background: #ddd;
-    left: 0;
-    right: 0;
-    margin: 0 auto;
-    bottom: -50%;
-  }
-`;
- 
-export const ListItemName = styled.span<{ selected?: boolean; theme?: Theme }>`
-  font-size: 0.75rem;
-  color: ${(p) => (p.selected ? p.theme.iconColor || p.theme.primary : '')};
-  padding-left: 0.25rem;
- 
-  &:hover {
-    color: ${(p) => p.theme.iconColor || p.theme.primary};
-  }
-`;
- 
-export const ListItemBullet = styled.span<{
-  selected?: boolean;
-  theme?: Theme;
-}>`
-  align-items: center;
-  display: flex;
-  justify-content: center;
-  margin-right: 1rem;
-  position: relative;
- 
-  &::after {
-    content: '';
-    display: block;
-    position: absolute;
-    width: 8px;
-    height: 8px;
-    border-radius: 50%;
-    background: ${(p) =>
-      p.selected
-        ? `${p.theme.secondary}`
-        : p.theme.iconColor || `${p.theme.primary}`};
-    left: 0;
-    margin: 0 auto;
-    border: ${(p) =>
-      p.selected
-        ? `2px solid ${p.theme.secondary}`
-        : `2px solid ${p.theme.iconColor || p.theme.primary}`};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-elements/timeline-outline/timeline-outline.tsx.html b/coverage/components/timeline-elements/timeline-outline/timeline-outline.tsx.html deleted file mode 100644 index 3b2907fde..000000000 --- a/coverage/components/timeline-elements/timeline-outline/timeline-outline.tsx.html +++ /dev/null @@ -1,466 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline.tsx

-
- -
- 96.47% - Statements - 82/85 -
- - -
- 95% - Branches - 19/20 -
- - -
- 66.66% - Functions - 2/3 -
- - -
- 96.47% - Lines - 82/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -1281x -  -  -  -  -  -  -  -1x -1x -1x -1x -  -1x -  -  -  -  -1x -  -1x -  -1x -1x -  -  -  -1x -10x -10x -1x -  -  -1x -1x -1x -1x -  -  -  -  -  -  -  -1x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -  -12x -12x -  -  -12x -  -12x -  -  -12x -  -9x -9x -3x -9x -6x -  -6x -6x -  -9x -9x -9x -12x -  -12x -12x -1x -1x -12x -12x -  -12x -1x -1x -  -12x -1x -1x -  -10x -10x -10x -10x -10x -10x -10x -  -10x -10x -10x -10x -10x -  -12x -12x -12x -12x -3x -3x -3x -3x -3x -  -12x -12x -12x -  -12x -  -  - 
import React, {
-  useCallback,
-  useContext,
-  useEffect,
-  useState,
-  PropsWithChildren,
-  memo,
-} from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import CloseIcon from '../../icons/close';
-import MenuIcon from '../../icons/menu';
-import { OutlineItemList } from './timeline-outline-item-list';
-import { TimelineOutlineModel } from './timeline-outline.model';
-import {
-  OutlineButton,
-  OutlinePane,
-  OutlineWrapper,
-} from './timeline-outline.styles';
-import { useOutlinePosition } from './hooks/useOutlinePosition';
- 
-class TimelineOutlineError extends React.Component<
-  PropsWithChildren<{ onError?: (error: Error) => void }>
-> {
-  componentDidCatch(error: Error) {
-    this.props.onError?.(error);
-  }
- 
-  render() {
-    return this.props.children;
-  }
-}
- 
-// Separate loading and error components to improve code organization
-const OutlineLoading = memo(() => <div role="status">Loading outline...</div>);
-const OutlineError = memo(({ error }: { error: Error }) => (
-  <div role="alert">Error: {error.message}</div>
-));
- 
-/**
- * TimelineOutline component
- * This component renders the outline pane of a timeline, including a list of items and corresponding selection functionality.
- * It provides an interface to toggle the outline pane and select items within the timeline.
- * The component leverages memoization to prevent unnecessary re-renders and optimizes the rendering process.
- */
-const TimelineOutline: React.FC<TimelineOutlineModel> = ({
-  items = [],
-  onSelect,
-  mode,
-  theme,
-  isLoading,
-  error,
-  onError,
-}: TimelineOutlineModel) => {
-  const [openPane, setOpenPane] = useState(false);
-  const [showList, setShowList] = useState(false);
- 
-  const { theme: globalTheme } = useContext(GlobalContext);
-  const mergedTheme = theme || globalTheme;
- 
-  // Extract position logic to a custom hook
-  const position = useOutlinePosition(mode);
- 
-  const togglePane = useCallback(() => setOpenPane((prev) => !prev), []);
- 
-  // Optimize effect to only run when openPane changes
-  useEffect(() => {
-    // Use a timeout to create a smooth animation effect
-    let timer: number;
-    if (openPane) {
-      setShowList(true);
-    } else {
-      timer = window.setTimeout(() => {
-        setShowList(false);
-      }, 300); // Match this with CSS transition time
-    }
- 
-    return () => {
-      if (timer) window.clearTimeout(timer);
-    };
-  }, [openPane]);
- 
-  const handleSelection = useCallback(
-    (index: number, id?: string) => {
-      onSelect?.(index);
-    },
-    [onSelect],
-  );
- 
-  if (error) {
-    return <OutlineError error={error} />;
-  }
- 
-  if (isLoading) {
-    return <OutlineLoading />;
-  }
- 
-  return (
-    <TimelineOutlineError onError={onError}>
-      <OutlineWrapper
-        position={position}
-        open={openPane}
-        aria-expanded={openPane}
-        role="complementary"
-      >
-        <OutlineButton
-          onPointerDown={togglePane}
-          theme={mergedTheme}
-          open={openPane}
-          position={position}
-        >
-          {openPane ? <CloseIcon /> : <MenuIcon />}
-        </OutlineButton>
-        <OutlinePane open={openPane}>
-          {showList && (
-            <OutlineItemList
-              items={items}
-              handleSelection={handleSelection}
-              theme={mergedTheme}
-            />
-          )}
-        </OutlinePane>
-      </OutlineWrapper>
-    </TimelineOutlineError>
-  );
-};
- 
-export { TimelineOutline };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-horizontal/__tests__/index.html b/coverage/components/timeline-horizontal/__tests__/index.html deleted file mode 100644 index 996a9130f..000000000 --- a/coverage/components/timeline-horizontal/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/__tests__ - - - - - - - - - -
-
-

All files components/timeline-horizontal/__tests__

-
- -
- 98.3% - Statements - 232/236 -
- - -
- 92% - Branches - 23/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.3% - Lines - 232/236 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal.test.tsx -
-
98.3%232/23692%23/25100%1/198.3%232/236
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html b/coverage/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html deleted file mode 100644 index 6a602a9b6..000000000 --- a/coverage/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html +++ /dev/null @@ -1,925 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-horizontal/__tests__ timeline-horizontal.test.tsx

-
- -
- 98.3% - Statements - 232/236 -
- - -
- 92% - Branches - 23/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.3% - Lines - 232/236 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -2811x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -20x -20x -20x -20x -20x -20x -20x -20x -20x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -  -1x -  -  -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -2x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
import { render, screen } from '@testing-library/react';
-import { describe, expect, it, vi } from 'vitest';
-import { GlobalContext } from '../../GlobalContext';
-import { TimelineHorizontalModel } from '../../../models/TimelineHorizontalModel';
-import TimelineHorizontal from '../timeline-horizontal';
- 
-const mockItems = [
-  {
-    id: '1',
-    title: 'Test Item 1',
-    cardTitle: 'Card Title 1',
-    cardSubtitle: 'Card Subtitle 1',
-    cardDetailedText: 'Detailed text for item 1',
-    visible: true,
-    active: false,
-    wrapperId: 'timeline-wrapper',
-  },
-  {
-    id: '2',
-    title: 'Test Item 2',
-    cardTitle: 'Card Title 2',
-    cardSubtitle: 'Card Subtitle 2',
-    cardDetailedText: 'Detailed text for item 2',
-    visible: true,
-    active: true,
-    wrapperId: 'timeline-wrapper',
-  },
-  {
-    id: '3',
-    title: 'Test Item 3',
-    cardTitle: 'Card Title 3',
-    cardSubtitle: 'Card Subtitle 3',
-    cardDetailedText: 'Detailed text for item 3',
-    visible: false,
-    active: false,
-    wrapperId: 'timeline-wrapper',
-  },
-];
- 
-const defaultProps: TimelineHorizontalModel = {
-  items: mockItems,
-  handleItemClick: vi.fn(),
-  autoScroll: vi.fn(),
-  wrapperId: 'timeline-wrapper',
-  slideShowRunning: false,
-  onElapsed: vi.fn(),
-  contentDetailsChildren: undefined,
-  hasFocus: false,
-  iconChildren: undefined,
-  nestedCardHeight: 200,
-  isNested: false,
-};
- 
-const mockContextValue = {
-  mode: 'HORIZONTAL' as const,
-  itemWidth: 300,
-  cardHeight: 200,
-  flipLayout: false,
-  showAllCardsHorizontal: false,
-  theme: {
-    primary: '#0f172a',
-    secondary: '#64748b',
-    cardBgColor: '#ffffff',
-    cardForeColor: '#000000',
-    titleColor: '#0f172a',
-    titleColorActive: '#ffffff',
-  },
-  cardWidth: 400,
-};
- 
-const renderWithContext = (
-  props: Partial<TimelineHorizontalModel> = {},
-  contextValue: any = mockContextValue,
-) => {
-  return render(
-    <GlobalContext.Provider value={contextValue}>
-      <TimelineHorizontal {...defaultProps} {...props} />
-    </GlobalContext.Provider>,
-  );
-};
- 
-describe('TimelineHorizontal', () => {
-  it('should render without crashing', () => {
-    renderWithContext();
-    expect(screen.getByTestId('timeline-collection')).toBeInTheDocument();
-  });
- 
-  it('should render the correct number of timeline items', () => {
-    renderWithContext();
-    // Use querySelectorAll since getAllByRole might filter out hidden items
-    const container = screen.getByTestId('timeline-collection');
-    const allItems = container.querySelectorAll('li');
-    expect(allItems).toHaveLength(mockItems.length);
-  });
- 
-  it('should apply correct CSS classes based on mode', () => {
-    renderWithContext();
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toHaveClass('horizontal');
-    expect(container).toHaveClass('timeline-horizontal-container');
-  });
- 
-  it('should apply show-all-cards-horizontal class when showAllCardsHorizontal is true', () => {
-    const contextWithShowAll = {
-      ...mockContextValue,
-      showAllCardsHorizontal: true,
-    };
-    renderWithContext({}, contextWithShowAll);
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toHaveClass('show-all-cards-horizontal');
-  });
- 
-  it('should render with flipped layout when flipLayout is true', () => {
-    const contextWithFlipped = {
-      ...mockContextValue,
-      flipLayout: true,
-    };
-    renderWithContext({}, contextWithFlipped);
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should handle item click when timeline card is clicked', async () => {
-    const handleItemClick = vi.fn();
-    renderWithContext({ handleItemClick });
-    
-    // Note: The actual click testing would depend on the TimelineCard implementation
-    // For now, we verify that the function is passed correctly
-    expect(handleItemClick).toHaveBeenCalledTimes(0);
-  });
- 
-  it('should render visible items with visible class', () => {
-    renderWithContext();
-    const listItems = screen.getAllByRole('listitem');
-    
-    // First two items should be visible
-    expect(listItems[0]).toHaveClass('visible');
-    expect(listItems[1]).toHaveClass('visible');
-    // Third item should not have visible class (visible: false) if it exists
-    if (listItems[2]) {
-      expect(listItems[2]).not.toHaveClass('visible');
-    }
-  });
- 
-  it('should set aria-current="true" for active items', () => {
-    renderWithContext();
-    const listItems = screen.getAllByRole('listitem');
-    
-    // Only the second item is active
-    expect(listItems[0]).not.toHaveAttribute('aria-current');
-    expect(listItems[1]).toHaveAttribute('aria-current', 'true');
-    if (listItems[2]) {
-      expect(listItems[2]).not.toHaveAttribute('aria-current');
-    }
-  });
- 
-  it('should apply correct width to timeline items', () => {
-    const customItemWidth = 250;
-    const contextWithCustomWidth = {
-      ...mockContextValue,
-      itemWidth: customItemWidth,
-    };
-    renderWithContext({}, contextWithCustomWidth);
-    const listItems = screen.getAllByRole('listitem');
-    
-    // Check that items have the correct width style applied
-    listItems.forEach(item => {
-      expect(item).toHaveClass('timeline-horz-item-container');
-    });
-  });
- 
-  it('should handle slideshow properties correctly', () => {
-    renderWithContext({
-      slideShowRunning: true,
-      onElapsed: vi.fn(),
-    });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render with nested card properties', () => {
-    renderWithContext({
-      isNested: true,
-      nestedCardHeight: 150,
-    });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should pass icon children to timeline cards', () => {
-    const iconChildren = [
-      <div key="icon1">Icon 1</div>,
-      <div key="icon2">Icon 2</div>,
-      <div key="icon3">Icon 3</div>,
-    ];
-    
-    renderWithContext({ iconChildren });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should pass content details children to timeline cards', () => {
-    const contentDetailsChildren = [
-      <div key="content1">Content 1</div>,
-      <div key="content2">Content 2</div>,
-      <div key="content3">Content 3</div>,
-    ];
-    
-    renderWithContext({ contentDetailsChildren });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render with auto scroll enabled', () => {
-    renderWithContext({ autoScroll: vi.fn() });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render with hasFocus enabled', () => {
-    renderWithContext({ hasFocus: true });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render as semantic list with proper ARIA labels', () => {
-    renderWithContext();
-    const list = screen.getByRole('list', { name: 'Timeline' });
-    expect(list).toBeInTheDocument();
-    expect(list).toHaveAttribute('aria-label', 'Timeline');
-  });
- 
-  it('should handle empty items array', () => {
-    renderWithContext({ items: [] });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-    const listItems = screen.queryAllByRole('listitem');
-    expect(listItems).toHaveLength(0);
-  });
- 
-  it('should handle different timeline modes correctly', () => {
-    const contextVertical = {
-      ...mockContextValue,
-      mode: 'VERTICAL_ALTERNATING',
-    };
-    renderWithContext({}, contextVertical);
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toHaveClass('vertical_alternating');
-  });
- 
-  it('should memoize wrapper class to prevent unnecessary re-renders', () => {
-    const { rerender } = renderWithContext();
-    const container = screen.getByTestId('timeline-collection');
-    const initialClassName = container.className;
-    
-    // Re-render with same props
-    rerender(
-      <GlobalContext.Provider value={mockContextValue}>
-        <TimelineHorizontal {...defaultProps} />
-      </GlobalContext.Provider>,
-    );
-    
-    expect(container.className).toBe(initialClassName);
-  });
- 
-  it('should memoize timeline items to prevent unnecessary re-renders', () => {
-    const { rerender } = renderWithContext();
-    const initialItems = screen.getAllByRole('listitem');
-    
-    // Re-render with same props
-    rerender(
-      <GlobalContext.Provider value={mockContextValue}>
-        <TimelineHorizontal {...defaultProps} />
-      </GlobalContext.Provider>,
-    );
-    
-    const afterRerenderItems = screen.getAllByRole('listitem');
-    expect(afterRerenderItems).toHaveLength(initialItems.length);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-horizontal/index.html b/coverage/components/timeline-horizontal/index.html deleted file mode 100644 index 04545d474..000000000 --- a/coverage/components/timeline-horizontal/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal - - - - - - - - - -
-
-

All files components/timeline-horizontal

-
- -
- 100% - Statements - 103/103 -
- - -
- 100% - Branches - 17/17 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 103/103 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal.styles.ts -
-
100%5/5100%4/4100%0/0100%5/5
timeline-horizontal.tsx -
-
100%98/98100%13/13100%1/1100%98/98
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-horizontal/timeline-horizontal.styles.ts.html b/coverage/components/timeline-horizontal/timeline-horizontal.styles.ts.html deleted file mode 100644 index aea4ff8ac..000000000 --- a/coverage/components/timeline-horizontal/timeline-horizontal.styles.ts.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/timeline-horizontal.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-horizontal timeline-horizontal.styles.ts

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -361x -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import styled from 'styled-components';
- 
-export const TimelineHorizontalWrapper = styled.ul<{ flipLayout?: boolean }>`
-  display: flex;
-  list-style: none;
-  margin: 0;
-  width: 100%;
-  direction: ${(p) => (p.flipLayout ? 'rtl' : 'ltr')};
- 
-  &.vertical {
-    flex-direction: column;
-  }
-  &.horizontal {
-    flex-direction: row;
-  }
-`;
- 
-export const TimelineItemWrapper = styled.li<{ width: number }>`
-  width: ${(p) => p.width}px;
-  visibility: hidden;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  height: 150px;
-  flex-direction: column;
- 
-  &.vertical {
-    margin-bottom: 2rem;
-    width: 100%;
-  }
- 
-  &.visible {
-    visibility: visible;
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-horizontal/timeline-horizontal.tsx.html b/coverage/components/timeline-horizontal/timeline-horizontal.tsx.html deleted file mode 100644 index 9cb13cdcc..000000000 --- a/coverage/components/timeline-horizontal/timeline-horizontal.tsx.html +++ /dev/null @@ -1,472 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/timeline-horizontal.tsx - - - - - - - - - -
-
-

All files / components/timeline-horizontal timeline-horizontal.tsx

-
- -
- 100% - Statements - 98/98 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 98/98 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130  -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -23x -21x -21x -21x -21x -21x -23x -23x -  -23x -23x -23x -23x -  -  -23x -21x -61x -61x -61x -61x -61x -61x -61x -61x -61x -  -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -21x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -23x -23x -23x -23x -23x -23x -23x -  -23x -23x -  -23x -  -1x - 
import { TimelineHorizontalModel } from '@models/TimelineHorizontalModel';
-import cls from 'classnames';
-import React, { ReactNode, useContext, useMemo } from 'react';
-import { GlobalContext } from '../GlobalContext';
-import TimelineCard from '../timeline-elements/timeline-card/timeline-horizontal-card';
-import {
-  TimelineHorizontalWrapper,
-  TimelineItemWrapper,
-} from './timeline-horizontal.styles';
- 
-/**
- * TimelineHorizontal
- * @property {TimelineHorizontalModel} items - The items to be displayed in the timeline.
- * @property {(item: TimelineItem) => void} handleItemClick - Function to handle item click.
- * @property {boolean} autoScroll - Whether to auto-scroll the timeline.
- * @property {string} wrapperId - The ID of the wrapper element.
- * @property {boolean} slideShowRunning - Whether the slideshow is running.
- * @property {() => void} onElapsed - Function to handle elapsed time.
- * @property {React.ReactNode} contentDetailsChildren - The children nodes for content details.
- * @property {boolean} hasFocus - Whether the timeline has focus.
- * @property {React.ReactNode} iconChildren - The children nodes for icons.
- * @property {number} nestedCardHeight - The height of the nested card.
- * @property {boolean} isNested - Whether the card is nested.
- * @returns {JSX.Element} The TimelineHorizontal component.
- */
- 
-const TimelineHorizontal: React.FunctionComponent<TimelineHorizontalModel> = ({
-  items,
-  handleItemClick,
-  autoScroll,
-  wrapperId,
-  slideShowRunning,
-  onElapsed,
-  contentDetailsChildren: children,
-  hasFocus,
-  iconChildren,
-  nestedCardHeight,
-  isNested,
-}: TimelineHorizontalModel) => {
-  const {
-    mode = 'HORIZONTAL',
-    itemWidth = 200,
-    cardHeight,
-    flipLayout,
-    showAllCardsHorizontal,
-    theme,
-    cardWidth,
-  } = useContext(GlobalContext);
- 
-  // Memoize the wrapper class to avoid unnecessary re-renders
-  const wrapperClass = useMemo(
-    () =>
-      cls(
-        mode.toLowerCase(),
-        'timeline-horizontal-container',
-        showAllCardsHorizontal ? 'show-all-cards-horizontal' : '',
-      ),
-    [mode, showAllCardsHorizontal],
-  );
- 
-  const iconChildColln = useMemo(
-    () => React.Children.toArray(iconChildren),
-    [iconChildren],
-  );
- 
-  // Memoize the timeline items to prevent unnecessary re-renders
-  const timelineItems = useMemo(() => {
-    return items.map((item, index) => (
-      <TimelineItemWrapper
-        key={item.id}
-        width={itemWidth}
-        className={cls(
-          item.visible ? 'visible' : '',
-          'timeline-horz-item-container',
-        )}
-        as="li"
-        aria-current={item.active ? 'true' : undefined}
-      >
-        <TimelineCard
-          {...item}
-          onClick={handleItemClick}
-          autoScroll={autoScroll}
-          wrapperId={wrapperId}
-          theme={theme}
-          slideShowRunning={slideShowRunning}
-          cardHeight={cardHeight}
-          onElapsed={onElapsed}
-          customContent={children ? (children as ReactNode[])[index] : null}
-          hasFocus={hasFocus}
-          iconChild={iconChildColln[index]}
-          active={item.active}
-          cardWidth={cardWidth}
-          isNested={isNested}
-          nestedCardHeight={nestedCardHeight}
-        />
-      </TimelineItemWrapper>
-    ));
-  }, [
-    items,
-    itemWidth,
-    handleItemClick,
-    autoScroll,
-    wrapperId,
-    theme,
-    slideShowRunning,
-    cardHeight,
-    onElapsed,
-    children,
-    hasFocus,
-    iconChildren,
-    cardWidth,
-    isNested,
-    nestedCardHeight,
-  ]);
- 
-  return (
-    <TimelineHorizontalWrapper
-      className={wrapperClass}
-      flipLayout={flipLayout}
-      data-testid="timeline-collection"
-      as="ul"
-      aria-label="Timeline"
-    >
-      {timelineItems}
-    </TimelineHorizontalWrapper>
-  );
-};
- 
-export default TimelineHorizontal;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/__tests__/index.html b/coverage/components/timeline-vertical/__tests__/index.html deleted file mode 100644 index 0261e8fb0..000000000 --- a/coverage/components/timeline-vertical/__tests__/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/__tests__ - - - - - - - - - -
-
-

All files components/timeline-vertical/__tests__

-
- -
- 100% - Statements - 74/74 -
- - -
- 100% - Branches - 5/5 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 74/74 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-point.test.tsx -
-
100%26/26100%2/2100%0/0100%26/26
timeline-vertical-item.test.tsx -
-
100%48/48100%3/30%0/3100%48/48
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/__tests__/timeline-point.test.tsx.html b/coverage/components/timeline-vertical/__tests__/timeline-point.test.tsx.html deleted file mode 100644 index a45fad027..000000000 --- a/coverage/components/timeline-vertical/__tests__/timeline-point.test.tsx.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/__tests__/timeline-point.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical/__tests__ timeline-point.test.tsx

-
- -
- 100% - Statements - 26/26 -
- - -
- 100% - Branches - 2/2 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 26/26 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -1x -1x -1x -  -1x -1x -1x - 
import { TimelinePointModel } from '@models/TimelineVerticalModel';
-import { describe, expect, it, vi } from 'vitest';
-import { customRender } from '../../common/test';
-import { providerProps } from '../../common/test/index';
-import { TimelinePoint } from '../timeline-point';
- 
-const commonProps: TimelinePointModel = {
-  active: false,
-  alternateCards: false,
-  cardLess: true,
-  className: 'test_class_name',
-  disableClickOnCircle: false,
-  iconChild: null,
-  id: '1',
-  lineWidth: 3,
-  onActive: vi.fn(),
-  onClick: vi.fn(),
-  slideShowRunning: false,
-  timelinePointDimension: 20,
-};
- 
-describe('Timeline point', () => {
-  // should match the snapshot
- 
-  it('Should match snapshot', () => {
-    const { asFragment } = customRender(<TimelinePoint {...commonProps} />, {
-      providerProps,
-    });
- 
-    expect(asFragment()).toMatchSnapshot();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html b/coverage/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html deleted file mode 100644 index d3cbb1ae9..000000000 --- a/coverage/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical/__tests__ timeline-vertical-item.test.tsx

-
- -
- 100% - Statements - 48/48 -
- - -
- 100% - Branches - 3/3 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 48/48 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60  -1x -1x -1x -1x -  -  -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x - 
import { VerticalItemModel } from '@models/TimelineVerticalModel';
-import { describe, expect, it } from 'vitest';
-import { customRender } from '../../common/test';
-import { providerProps } from '../../common/test/index';
-import TimelineVerticalItem from '../timeline-vertical-item';
- 
-// ResizeObserver is already mocked globally in common/test/index.tsx
- 
-const commonProps: VerticalItemModel = {
-  // complete the rest of the properties
-  active: false,
-  alternateCards: false,
-  cardDetailedText: '',
-  cardSubtitle: '',
-  cardTitle: '',
-  className: '',
-  contentDetailsChildren: null,
-  hasFocus: false,
-  iconChild: null,
-  id: '',
-  index: 1,
-  media: {
-    source: {
-      type: 'IMAGE',
-      url: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
-    },
-    type: 'IMAGE',
-  },
-  onActive: () => {},
-  onClick: () => {},
-  onElapsed: () => {},
-  slideShowRunning: false,
-  timelineContent: null,
-  title: 'vertical item title',
-  url: '',
-  visible: false,
-};
- 
-describe('Timeline vertical item', () => {
-  it('Should match snapshot', () => {
-    const { container } = customRender(
-      <TimelineVerticalItem {...commonProps} />,
-      { providerProps },
-    );
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  //should render the title
- 
-  it('Should render the title', () => {
-    const { getByText } = customRender(
-      <TimelineVerticalItem {...commonProps} />,
-      { providerProps },
-    );
- 
-    expect(getByText('vertical item title')).toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/index.html b/coverage/components/timeline-vertical/index.html deleted file mode 100644 index 81d4f3afb..000000000 --- a/coverage/components/timeline-vertical/index.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical - - - - - - - - - -
-
-

All files components/timeline-vertical

-
- -
- 91.1% - Statements - 430/472 -
- - -
- 56.04% - Branches - 51/91 -
- - -
- 50% - Functions - 1/2 -
- - -
- 91.1% - Lines - 430/472 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-point.tsx -
-
88.99%97/10950%8/160%0/188.99%97/109
timeline-vertical-item.tsx -
-
93.8%197/21050%10/20100%1/193.8%197/210
timeline-vertical-shape.styles.ts -
-
100%16/1673.33%11/15100%0/0100%16/16
timeline-vertical.styles.ts -
-
86.66%39/4551.85%14/27100%0/086.66%39/45
timeline-vertical.tsx -
-
88.04%81/9261.53%8/13100%0/088.04%81/92
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/timeline-point.tsx.html b/coverage/components/timeline-vertical/timeline-point.tsx.html deleted file mode 100644 index 1ae7381d0..000000000 --- a/coverage/components/timeline-vertical/timeline-point.tsx.html +++ /dev/null @@ -1,676 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-point.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-point.tsx

-
- -
- 88.99% - Statements - 97/109 -
- - -
- 50% - Branches - 8/16 -
- - -
- 0% - Functions - 0/1 -
- - -
- 88.99% - Lines - 97/109 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198  -1x -1x -  -  -  -  -  -  -  -1x -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -  -  -23x -23x -23x -23x -23x -23x -23x -23x -  -23x -23x -23x -  -  -23x -  -  -  -  -  -23x -  -23x -  -  -  -23x -23x -23x -23x -  -  -  -  -  -23x -23x -  -  -  -  -  -23x -  -  -  -  -  -23x -23x -23x -23x -23x -23x -23x -23x -  -  -  -  -  -23x -  -23x -  -  -  -  -23x -23x -  -  -  -  -  -  -23x -23x -  -  -  -  -23x -  -23x -23x -23x -23x -  -  -23x -23x -23x -  -  -23x -  -  -23x -23x -  -23x -23x -23x -23x -  -23x -23x -  -  -23x -  -23x -  -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -  -23x -23x -23x -  -23x -23x -  -23x -23x -23x -23x -  -23x -  -  -  -  -1x -  -  -1x -  -  - 
import { TimelinePointModel } from '@models/TimelineVerticalModel'; // Assuming model path
-import cls from 'classnames'; // Utility for conditionally joining classNames
-import React, {
-  memo, // Import memo for component optimization
-  useEffect,
-  useMemo,
-  useRef,
-  FunctionComponent, // Explicit import
-  MouseEvent,
-} from 'react';
-import { useStableContext, useDynamicContext } from '../contexts'; // Context for global theme/settings
-// Shape seems to be a shared styled component, potentially defined elsewhere
-import { Shape } from '../timeline-elements/timeline-card/timeline-horizontal-card.styles';
-import {
-  TimelinePointContainer,
-  TimelinePointWrapper,
-} from './timeline-vertical-shape.styles'; // Associated styled components
- 
-/**
- * Renders the circular point or icon on the timeline line for a vertical item.
- * Handles click events, active state highlighting, custom icons, and appearance
- * based on global theme and configuration settings. It uses React.memo for
- * performance optimization.
- *
- * @param {TimelinePointModel} props - The properties for the TimelinePoint component.
- * @returns {React.ReactElement} The rendered TimelinePoint component.
- */
-const TimelinePoint: FunctionComponent<TimelinePointModel> = memo(
-  (props: TimelinePointModel) => {
-    const {
-      className, // 'left' or 'right' - passed to styled components
-      id, // Unique ID of the timeline item
-      onClick, // Callback function when the point is clicked
-      active, // Is this point currently active/highlighted?
-      onActive, // Callback function when the point should trigger the 'active' state calculation
-      slideShowRunning, // Is a slideshow currently active? (disables onClick)
-      iconChild, // Custom React node to display inside the point (replaces default shape)
-      timelinePointDimension, // Size (width/height) of the point
-      lineWidth, // Width of the timeline line connecting points
-      disableClickOnCircle, // Should clicks on the point be ignored?
-      cardLess, // Is the timeline in 'cardLess' mode?
-      isMobile, // Is the view currently mobile?
-    } = props;
- 
-    // Ref to the button element representing the point
-    const circleRef = useRef<HTMLButtonElement>(null);
- 
-    // Access context settings
-    const {
-      staticDefaults: {
-        focusActiveItemOnLoad,
-        timelinePointShape,
-        disableTimelinePoint,
-      },
-      memoizedButtonTexts: buttonTexts, // Custom button text labels
-    } = useStableContext();
- 
-    const {
-      memoizedTheme: theme, // Theme object (primary color, etc.)
-    } = useDynamicContext();
- 
-    // Ref to track if this is the component's first render cycle
-    const isFirstRender = useRef(true);
- 
-    /**
-     * Determines if the onActive callback should be invoked based on the active state
-     * and whether it's the initial render (controlled by focusActiveItemOnLoad).
-     */
-    const canInvokeOnActive = useMemo(() => {
-      // If focusing on load is enabled, invoke if active.
-      if (focusActiveItemOnLoad) {
-        return active;
-      }
-      // Otherwise, invoke only if active AND it's not the first render.
-      else {
-        return active && !isFirstRender.current;
-      }
-    }, [active, focusActiveItemOnLoad]); // Dependencies: active state and global setting
- 
-    /**
-     * Effect to call the onActive callback when conditions are met.
-     * This usually happens when an item scrolls into view or is programmatically activated.
-     */
-    useEffect(() => {
-      if (canInvokeOnActive && onActive && circleRef.current) {
-        // Call the parent's onActive handler with the point's offsetTop
-        onActive(circleRef.current.offsetTop);
-      }
-      // Intentionally excluding onActive from dependencies if it's stable,
-      // otherwise, include it if it might change. Usually, it's stable.
-    }, [canInvokeOnActive, active]); // Re-run when activation condition or active state changes
- 
-    /**
-     * Memoized CSS classes for the inner Shape component.
-     * Applies 'active' class and 'using-icon' if a custom icon is provided.
-     */
-    const circleClass = useMemo(
-      () =>
-        cls({
-          active: active, // Apply 'active' class if the point is active
-          'using-icon': !!iconChild, // Apply class if a custom icon is used
-        }),
-      [active, iconChild], // Dependencies: active state and presence of iconChild
-    );
- 
-    /**
-     * Memoized click handler props for the TimelinePointContainer button.
-     * Only adds onClick if clicks are enabled and slideshow isn't running.
-     */
-    const clickHandlerProps = useMemo(() => {
-      // Return empty object (no click handler) if clicks are disabled
-      if (disableClickOnCircle) {
-        return {};
-      }
- 
-      // Return props containing the onClick handler
-      return {
-        onClick: (ev: MouseEvent) => {
-          ev.stopPropagation(); // Prevent event bubbling up
-          // Call the provided onClick handler if it exists, passing the item ID
-          if (id && onClick && !slideShowRunning) {
-            onClick(id);
-          }
-        },
-      };
-    }, [id, onClick, slideShowRunning, disableClickOnCircle]); // Dependencies for the click logic
- 
-    /**
-     * Effect to update the isFirstRender flag after the initial render is complete.
-     */
-    useEffect(() => {
-      // This effect runs only once after the initial mount
-      if (isFirstRender.current) {
-        isFirstRender.current = false;
-      }
-    }, []); // Empty dependency array ensures it runs only once
- 
-    // Create an accessible label for the timeline point
-    const timelinePointLabel = useMemo(() => {
-      return (
-        buttonTexts?.timelinePoint ??
-        (active ? 'Active timeline point' : 'Timeline point')
-      );
-    }, [active, buttonTexts]);
- 
-    // Render the timeline point structure
-    return (
-      <TimelinePointWrapper
-        // --- Props passed to styled-component ---
-        width={lineWidth} // Controls the width of the connecting lines (via ::before/::after)
-        bg={theme?.primary} // Background color for the connecting lines
-        $cardLess={cardLess} // Pass cardLess state
-        $isMobile={isMobile} // Pass mobile state
-        // --- Standard React props ---
-        className={className} // 'left' or 'right'
-        data-testid="tree-leaf" // Test ID for the wrapper
-      >
-        {/* Container is a button for accessibility and click handling */}
-        <TimelinePointContainer
-          // --- Props passed to styled-component ---
-          $hide={disableTimelinePoint} // Hide based on global setting
-          // --- Standard React props ---
-          className={`${className} timeline-vertical-circle`} // Combine classes
-          {...clickHandlerProps} // Spread the memoized click handler props
-          ref={circleRef} // Attach ref for position measurement
-          data-testid="tree-leaf-click" // Test ID for the clickable element
-          aria-label={timelinePointLabel} // Accessibility label
-          aria-disabled={disableClickOnCircle ?? disableTimelinePoint} // Disable button if needed
-          disabled={disableClickOnCircle || disableTimelinePoint} // Disable button if needed
-          tabIndex={disableClickOnCircle || disableTimelinePoint ? -1 : 0} // Manage tab order
-        >
-          {/* The visual shape (circle, square, or custom icon) */}
-          <Shape
-            // --- Props passed to styled-component ---
-            theme={theme}
-            dimension={timelinePointDimension} // Controls the size
-            $timelinePointShape={timelinePointShape} // Controls the shape ('circle', 'square')
-            // --- Standard React props ---
-            className={circleClass} // Apply 'active' and 'using-icon' classes
-            aria-hidden="true" // Hide from screen readers as it's decorative
-          >
-            {iconChild}
-          </Shape>
-        </TimelinePointContainer>
-      </TimelinePointWrapper>
-    ) as React.ReactElement;
-  },
-  // Use default shallow comparison for memoization.
-  // The previous custom comparison (prev.active === next.active && prev.isMobile === next.isMobile)
-  // was too restrictive and would prevent updates when other props like iconChild, theme, onClick, etc., changed.
-  // Default shallow comparison is generally safer unless profiling reveals a specific need for a custom function.
-);
- 
-// Set display name for React DevTools
-TimelinePoint.displayName = 'TimelinePoint';
- 
-export { TimelinePoint }; // Export the component
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/timeline-vertical-item.tsx.html b/coverage/components/timeline-vertical/timeline-vertical-item.tsx.html deleted file mode 100644 index 84428ae32..000000000 --- a/coverage/components/timeline-vertical/timeline-vertical-item.tsx.html +++ /dev/null @@ -1,991 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical-item.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical-item.tsx

-
- -
- 93.8% - Statements - 197/210 -
- - -
- 50% - Branches - 10/20 -
- - -
- 100% - Functions - 1/1 -
- - -
- 93.8% - Lines - 197/210 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303  -1x -1x -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -26x -26x -  -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -  -  -  -  -26x -26x -  -  -  -  -  -  -26x -26x -  -  -  -  -  -  -26x -  -  -  -  -26x -  -  -  -  -  -26x -22x -22x -22x -22x -22x -22x -  -22x -  -22x -22x -22x -22x -  -22x -22x -22x -22x -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -  -  -  -26x -26x -22x -22x -22x -22x -22x -26x -26x -  -  -  -  -26x -26x -22x -22x -22x -22x -22x -26x -26x -  -  -  -  -  -26x -26x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -  -26x -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -  -  -  -26x -  -22x -26x -  -  -26x -22x -22x -22x -  -  -  -  -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -26x -  -  -26x -  -26x -26x -  -26x -  -26x -26x -  -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -26x -26x -26x -26x -26x -26x -26x -26x -  -26x -  -  -26x -26x -  -26x -  -  -1x -  -1x - 
import { VerticalItemModel } from '@models/TimelineVerticalModel';
-import cls from 'classnames';
-import {
-  useCallback,
-  useContext,
-  useMemo,
-  useRef,
-  FunctionComponent,
-  ReactElement,
-} from 'react';
-import { GlobalContext } from '../GlobalContext';
-import TimelineCard from '../timeline-elements/timeline-card-content/timeline-card-content';
-import TimelineItemTitle from '../timeline-elements/timeline-item-title/timeline-card-title';
-import { TimelinePoint } from './timeline-point';
-import {
-  TimelineCardContentWrapper,
-  TimelineTitleWrapper,
-  VerticalItemWrapper,
-} from './timeline-vertical.styles';
- 
-/**
- * Represents a single item (row) in the vertical timeline.
- * It coordinates the display of the title, the central point/icon,
- * and the main content card based on the provided props and global context.
- *
- * @param {VerticalItemModel} props - The properties for the VerticalItem component.
- * @returns {JSX.Element} The rendered VerticalItem component.
- */
-const VerticalItem: FunctionComponent<VerticalItemModel> = (
-  props: VerticalItemModel,
-): ReactElement => {
-  // Ref to the main list item element for calculating position/dimensions
-  const contentRef = useRef<HTMLLIElement>(null);
- 
-  // Destructure all props for cleaner access
-  const {
-    active, // Is this item currently highlighted/active?
-    alternateCards, // Layout mode: alternate card sides?
-    cardDetailedText, // Detailed text content for the card
-    cardSubtitle, // Subtitle/main content for the card
-    cardTitle, // Title specifically for the card (distinct from the timeline item title)
-    url, // URL for navigation, potentially used by the card
-    className, // CSS class for the side ('left' or 'right')
-    contentDetailsChildren, // Custom React nodes for card details area
-    iconChild, // Custom React node for the timeline point/icon
-    hasFocus, // Does the card content have focus (e.g., for slideshow)?
-    id, // Unique ID for the item
-    media, // Media element (image/video) for the card
-    onActive, // Callback when item becomes active (e.g., scrolled into view)
-    onClick, // Callback when the item (or point) is clicked
-    onElapsed, // Callback when media finishes playing (if applicable)
-    slideShowRunning, // Is a slideshow currently active?
-    title, // Title for the timeline item itself (often a date or heading)
-    visible, // Is this item currently visible in the viewport?
-    timelineContent, // Custom React nodes for the main timeline content area
-    items, // Data for nested items (if any)
-    isNested, // Is this item part of a nested structure?
-    nestedCardHeight, // Specific height for nested cards
-  } = props;
- 
-  // Access global settings and theme from context
-  const {
-    cardHeight, // Default card height
-    mode, // Timeline mode (VERTICAL, VERTICAL_ALTERNATING)
-    flipLayout, // Reverse layout order (title/point/card)?
-    timelinePointDimension, // Size of the timeline point
-    lineWidth, // Width of the timeline central line
-    disableClickOnCircle, // Prevent clicks on the timeline point?
-    cardLess, // Mode without cards, only points/titles
-    theme, // Theme object
-    classNames, // Custom class names for sub-elements
-    textOverlay, // Style where text overlays media
-    mediaHeight, // Height for media elements
-    disableInteraction, // Disable all user interactions?
-    isMobile, // Is the view currently mobile?
-  } = useContext(GlobalContext);
- 
-  /**
-   * Callback handler triggered by the TimelinePoint when it becomes active.
-   * Calculates the item's position and notifies the parent.
-   * @param {number} offset - Vertical offset within the point element itself.
-   */
-  const handleOnActive = useCallback(
-    (offset: number) => {
-      if (contentRef.current && onActive) {
-        const { offsetTop, clientHeight } = contentRef.current;
-        // Call the parent's onActive with calculated position data
-        onActive(offsetTop + offset, offsetTop, clientHeight);
-      }
-    },
-    [onActive], // Dependency: only recreate if onActive changes
-  );
- 
-  /**
-   * Handler for the "Read More" action within the card.
-   * Uses a short timeout to likely ensure the DOM has updated (card expanded)
-   * before recalculating the active position.
-   */
-  const handleShowMore = useCallback(() => {
-    // Use timeout to defer execution, allowing potential layout shifts to settle
-    setTimeout(() => {
-      handleOnActive(0); // Recalculate position after content change
-    }, 100); // Small delay (adjust if needed)
-  }, [handleOnActive]); // Dependency: handleOnActive
- 
-  /**
-   * Memoized Timeline Item Title component.
-   * Avoids re-rendering the title if its specific props haven't changed.
-   */
-  const Title = useMemo(() => {
-    return (
-      <TimelineTitleWrapper
-        className={className} // 'left' or 'right'
-        $alternateCards={alternateCards} // Pass prop to styled-component
-        mode={mode}
-        $hide={!title} // Hide wrapper if no title text
-        // Flip title position only in non-alternating vertical mode
-        $flip={!alternateCards && flipLayout}
-      >
-        <TimelineItemTitle
-          title={title as string}
-          active={active && !disableInteraction} // Highlight if active and interaction enabled
-          theme={theme}
-          // Align text based on layout mode
-          align={flipLayout && !alternateCards ? 'left' : 'right'}
-          classString={classNames?.title} // Optional custom class
-        />
-      </TimelineTitleWrapper>
-    );
-  }, [
-    active,
-    title,
-    className,
-    alternateCards,
-    mode,
-    flipLayout,
-    theme,
-    classNames?.title, // Correct dependency
-    disableInteraction, // Added dependency
-  ]);
- 
-  /**
-   * Memoized CSS classes for the main VerticalItemWrapper.
-   * Includes the side ('left'/'right'), visibility, and base class.
-   */
-  const verticalItemClass = useMemo(
-    () =>
-      cls(
-        'vertical-item-row', // Base class
-        { [className]: !!className }, // Add 'left' or 'right' if className is present
-        { visible: visible }, // Add 'visible' class if visible prop is true
-      ),
-    [className, visible],
-  );
- 
-  /**
-   * Memoized CSS classes for the TimelineCardContentWrapper.
-   */
-  const contentClass = useMemo(
-    () =>
-      cls(
-        'card-content-wrapper', // Base class
-        { [className]: !!className }, // Add 'left' or 'right'
-        { visible: visible }, // Add 'visible' class
-      ),
-    [className, visible],
-  );
- 
-  /**
-   * Memoized Timeline Point component.
-   * Avoids re-rendering the point if its specific props haven't changed.
-   */
-  const TimelinePointMemo = useMemo(
-    () => (
-      <TimelinePoint
-        active={active}
-        alternateCards={alternateCards}
-        className={className} // 'left' or 'right'
-        id={id}
-        mode={mode}
-        onActive={handleOnActive} // Pass down the memoized handler
-        onClick={onClick}
-        slideShowRunning={slideShowRunning}
-        iconChild={iconChild} // Custom icon
-        timelinePointDimension={timelinePointDimension}
-        lineWidth={lineWidth}
-        disableClickOnCircle={disableClickOnCircle}
-        cardLess={cardLess}
-        isMobile={isMobile}
-      />
-    ),
-    [
-      // Comprehensive dependency list for memoization
-      active,
-      alternateCards,
-      className,
-      id,
-      mode,
-      handleOnActive, // Use the memoized callback
-      onClick,
-      slideShowRunning,
-      iconChild,
-      timelinePointDimension,
-      lineWidth,
-      disableClickOnCircle,
-      cardLess,
-      isMobile,
-    ],
-  );
- 
-  /**
-   * Determines if the title section should be rendered.
-   * Titles are typically hidden for nested items or on mobile for space.
-   */
-  const canShowTitle = useMemo(() => {
-    // Show title only if it's NOT nested AND NOT mobile view
-    return !isNested && !isMobile;
-  }, [isNested, isMobile]);
- 
-  // Get a readable title for screen readers
-  const accessibleTitle = useMemo(() => {
-    if (typeof title === 'string') {
-      return title;
-    } else if (typeof cardTitle === 'string') {
-      return cardTitle;
-    } else {
-      return 'Timeline item';
-    }
-  }, [title, cardTitle]);
- 
-  // Render the complete timeline item structure
-  return (
-    <VerticalItemWrapper
-      as="li"
-      $alternateCards={alternateCards}
-      $cardHeight={isNested ? nestedCardHeight : cardHeight}
-      $cardLess={cardLess}
-      $isNested={isNested}
-      className={verticalItemClass}
-      data-testid="vertical-item-row"
-      data-item-id={id}
-      key={id}
-      ref={contentRef}
-      theme={theme}
-      aria-current={active ? 'true' : undefined}
-      aria-label={accessibleTitle}
-    >
-      {/* Conditionally render the Title */}
-      {canShowTitle ? Title : null}
- 
-      {/* Wrapper for the card content */}
-      <TimelineCardContentWrapper
-        // --- Props passed to styled-component ---
-        $alternateCards={alternateCards}
-        $noTitle={!title} // Adjust width if title is absent
-        // Flip content position only in non-alternating vertical mode
-        $flip={!alternateCards && flipLayout}
-        // Use media height if text overlay is active, otherwise card height
-        height={textOverlay ? mediaHeight : cardHeight}
-        $isMobile={isMobile}
-        // --- Standard React props ---
-        className={contentClass} // Apply memoized classes
-      >
-        {/* Conditionally render the TimelineCard (only if not cardLess mode) */}
-        {!cardLess ? (
-          <TimelineCard
-            active={active}
-            branchDir={className} // Pass 'left' or 'right'
-            content={cardSubtitle}
-            customContent={contentDetailsChildren}
-            detailedText={cardDetailedText as string | string[]}
-            hasFocus={hasFocus}
-            id={id}
-            media={media}
-            onClick={onClick}
-            onElapsed={onElapsed}
-            onShowMore={handleShowMore} // Pass down the memoized handler
-            slideShowActive={slideShowRunning}
-            theme={theme}
-            url={url}
-            // Flip card content only in non-alternating vertical mode
-            flip={!alternateCards && flipLayout}
-            timelineContent={timelineContent}
-            items={items} // Pass nested items data
-            isNested={isNested}
-            nestedCardHeight={nestedCardHeight}
-            title={cardTitle as string} // Card-specific title
-            cardTitle={title as string} // Item title (might be redundant if cardTitle is used)
-          />
-        ) : null}
-      </TimelineCardContentWrapper>
- 
-      {/* Conditionally render the Timeline Point (hidden for nested items) */}
-      {!isNested ? TimelinePointMemo : null}
-    </VerticalItemWrapper>
-  );
-};
- 
-// Set display name for React DevTools
-VerticalItem.displayName = 'VerticalItem';
- 
-export default VerticalItem;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/timeline-vertical-shape.styles.ts.html b/coverage/components/timeline-vertical/timeline-vertical-shape.styles.ts.html deleted file mode 100644 index ae9c61e0c..000000000 --- a/coverage/components/timeline-vertical/timeline-vertical-shape.styles.ts.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical-shape.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical-shape.styles.ts

-
- -
- 100% - Statements - 16/16 -
- - -
- 73.33% - Branches - 11/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 16/16 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled from 'styled-components';
-import { zIndex } from '../../styles/z-index';
- 
-/**
- * Props for the TimelinePointWrapper component.
- */
-interface TimelinePointWrapperProps {
-  /** Indicates if the timeline item has no card content, affecting layout. */
-  $cardLess?: boolean;
-  /** Flag for mobile-specific styling adjustments. */
-  $isMobile?: boolean;
-  /** Background color for the timeline line and point elements. */
-  bg?: string;
-  /** Width of the timeline line. Defaults to 4px. */
-  width?: number;
- 
-  theme?: Theme;
-}
- 
-/**
- * Wrapper for the central point/icon on the timeline branch.
- * Handles positioning and the vertical lines connecting points.
- */
-export const TimelinePointWrapper = styled.div<TimelinePointWrapperProps>`
-  /* Flexbox alignment */
-  align-items: center;
-  display: flex;
-  justify-content: center;
-  position: relative;
- 
-  /* Adjust width based on mobile view */
-  width: ${(p) => (p.$isMobile ? '25%' : '10%')};
- 
-  /* Control the horizontal order in VERTICAL_ALTERNATING mode */
-  &.left {
-    order: 2; /* Appears between title and content */
-  }
-  &.right {
-    order: 1; /* Appears first */
-  }
- 
-  /* Top vertical line segment (connecting to the previous item) */
-  &::before {
-    background: ${(p) =>
-      p.bg ?? p.theme?.primary}; /* Use theme primary as fallback */
-    width: ${(p) => (p.width ? `${p.width}px` : '4px')};
-    height: 2rem; /* Fixed height for the connector */
-    position: absolute;
-    content: '';
-    display: block;
-    left: 50%;
-    top: -1rem; /* Position above the point */
-    transform: translateY(-50%) translateX(-50%); /* Center horizontally */
-  }
- 
-  /* Main vertical line segment (extending downwards) */
-  &::after {
-    background: ${(p) =>
-      p.bg ?? p.theme?.primary}; /* Use theme primary as fallback */
-    content: '';
-    display: block;
-    height: 100%; /* Extend full height of the wrapper */
-    left: 50%;
-    position: absolute;
-    width: ${(p) => (p.width ? `${p.width}px` : '4px')};
-    z-index: ${zIndex.timelineLine}; /* Timeline line is at bottom layer */
-    transform: translateX(-50%); /* Center horizontally */
-  }
-`;
- 
-/**
- * Props for the TimelinePointContainer component.
- */
-interface TimelinePointContainerProps {
-  /** Hides the point visually if true. */
-  $hide?: boolean;
-  theme?: Theme;
-}
- 
-/**
- * Container for the actual timeline point/icon (e.g., a circle or custom icon).
- * This is often implemented as a button for accessibility/interactivity.
- */
-export const TimelinePointContainer = styled.button<TimelinePointContainerProps>`
-  position: relative; /* Ensure it's above the ::after pseudo-element */
-  z-index: ${zIndex.timelinePoint}; /* Timeline point sits above the lines but below popovers */
-  visibility: ${(p) =>
-    p.$hide ? 'hidden' : 'visible'}; /* Control visibility */
- 
-  /* Reset button styles */
-  background: none;
-  border: 0;
-  padding: 0; /* Remove default padding */
-  cursor: pointer; /* Indicate interactivity */
-  transition: transform 0.2s ease-in-out; /* Smooth transitions */
- 
-  /* Add subtle hover transform */
-  &:hover:not(:disabled) {
-    transform: scale(1.05);
-  }
- 
-  /* Add press effect */
-  &:active:not(:disabled) {
-    transform: scale(0.95);
-  }
- 
-  /* Add focus styles for accessibility */
-  &:focus-visible {
-    outline: 3px solid ${(p) => p.theme?.primary ?? '#007bff'}; /* Focus ring */
-    outline-offset: 3px;
-  }
- 
-  &:disabled {
-    cursor: default; /* Indicate non-interactive state */
-    opacity: 0.6; /* Visually show disabled state */
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/timeline-vertical.styles.ts.html b/coverage/components/timeline-vertical/timeline-vertical.styles.ts.html deleted file mode 100644 index 08197a457..000000000 --- a/coverage/components/timeline-vertical/timeline-vertical.styles.ts.html +++ /dev/null @@ -1,757 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical.styles.ts

-
- -
- 86.66% - Statements - 39/45 -
- - -
- 51.85% - Branches - 14/27 -
- - -
- 100% - Functions - 0/0 -
- - -
- 86.66% - Lines - 39/45 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225  -  -1x -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -26x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -26x -16x -16x -  -10x -  -  -  -10x -10x -10x -26x -  -  -1x -26x -26x -  -  -  -  -  -  -  -  -1x -  -  -1x -26x -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -22x -  -1x -  -  -1x -22x -12x -1x -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -  -1x -  -1x -  -  - 
import { Theme } from '@models/Theme'; // Assuming Theme model path
-import { TimelineMode } from '@models/TimelineModel'; // Assuming TimelineModel path
-import styled, { css, keyframes } from 'styled-components';
-import { zIndex } from '../../styles/z-index';
- 
-/**
- * Main container for the entire vertical timeline component.
- */
-export const TimelineVerticalWrapper = styled.div`
-  display: flex;
-  flex-direction: column; /* Stack items vertically */
-  width: 100%;
-  padding: 0.25rem; /* Small padding around the timeline */
-  outline: 0; /* Remove default outline */
-  position: relative; /* Establish positioning context */
-`;
- 
-/**
- * Keyframes for the fade-in animation of timeline items.
- */
-const animateVisible = keyframes`
-  from {
-    opacity: 0;
-    visibility: hidden; /* Start hidden */
-  }
-  to {
-    opacity: 1;
-    visibility: visible; /* Fade to visible */
-  }
-`;
- 
-/**
- * Props for the VerticalItemWrapper component.
- */
-interface VerticalItemWrapperProps {
-  /** Controls layout for alternating cards mode. */
-  $alternateCards?: boolean;
-  /** Explicit height for the card content area. */
-  $cardHeight?: number; // Note: Consider if this prop is truly needed or if height should be intrinsic
-  /** Style adjustments for items without card content. */
-  $cardLess?: boolean;
-  /** Indicates if the item is part of a nested timeline structure. */
-  $isNested?: boolean;
-  /** Theme object for styling. */
-  theme?: Theme;
-}
- 
-/**
- * Wrapper for a single timeline item (row), containing title, point, and content.
- * Handles visibility animation and basic layout.
- */
-export const VerticalItemWrapper = styled.li<VerticalItemWrapperProps>`
-  display: flex;
-  position: relative;
-  visibility: hidden; /* Initially hidden for animation */
-  width: 100%;
-  align-items: stretch; /* Stretch children vertically */
-  justify-content: center; /* Center items horizontally */
-  z-index: ${zIndex.timelineCard - 1}; /* Just below the card but above the lines */
-  margin: 1rem 0; /* Vertical spacing between items */
-  list-style: none; /* Remove default list styling */
- 
-  /* Alignment adjustments based on side (used in non-alternating modes) */
-  &.left {
-    margin-right: auto; /* Align left */
-  }
-  &.right {
-    margin-left: auto; /* Align right */
-  }
- 
-  /* Class added when the item should become visible */
-  &.visible {
-    visibility: visible;
-    /* Consider adding animation here if needed, though content animates */
-  }
- 
-  /* Styling for nested timelines */
-  ${(p) =>
-    p.$isNested && // Apply only if $isNested is true
-    css`
-      position: relative;
- 
-      /* Vertical connector line for nested items */
-      &:not(:last-child)::after {
-        content: '';
-        position: absolute;
-        width: 2px; /* Line width */
-        height: 2rem; /* Connector height */
-        background: ${p.theme?.primary ?? '#007bff'};
-        left: 50%;
-        transform: translateX(-50%);
-        bottom: -2rem; /* Position below the item */
-      }
-    `}
-`;
- 
-/**
- * Props for the TimelineCardContentWrapper component.
- */
-interface TimelineCardContentWrapperProps {
-  /** Controls layout for alternating cards mode. */
-  $alternateCards?: boolean;
-  /** Style adjustments for items without card content. */
-  $cardLess?: boolean;
-  /** Reverses the order of elements (content/point/title). */
-  $flip?: boolean;
-  /** Flag for mobile-specific styling adjustments. */
-  $isMobile?: boolean;
-  /** Indicates if the timeline item has no title, affecting layout. */
-  $noTitle?: boolean;
-  /** Explicit height for the card content area. */
-  height?: number; // Consider if this should be min-height or if height is necessary
-}
- 
-/**
- * Wrapper for the main content card of a timeline item.
- * Handles width, alignment, order, and visibility animation based on props.
- */
-export const TimelineCardContentWrapper = styled.div<TimelineCardContentWrapperProps>`
-  visibility: hidden; /* Initially hidden for animation */
-  position: relative;
-  display: flex;
-  align-items: center; /* Vertically center content */
- 
-  /* --- Width Calculation --- */
-  ${(p) => {
-    // Alternating mode: Takes up ~half the space minus the point/title areas
-    if (p.$alternateCards) {
-      return `width: ${p.$isMobile ? '75%;' : '37.5%;'}`;
-    }
-    // No title mode: Takes up most of the space
-    else if (p.$noTitle) {
-      return `width: 95%;`;
-    }
-    // Default vertical mode: Takes up space minus the title area
-    else {
-      return `width: ${p.$isMobile ? '75%;' : '85%;'}`;
-    }
-  }}
- 
-  /* --- Order and Justification (Standard Layout) --- */
-  ${(p) =>
-    !p.$flip && // Apply only if NOT flipped
-    css`
-      &.left {
-        order: 1; /* Content first */
-        justify-content: flex-end; /* Align card content to the right (towards center) */
-      }
-      &.right {
-        order: 3; /* Content last */
-        justify-content: flex-start; /* Align card content to the left (towards center) */
-      }
-    `}
- 
-  /* --- Order and Justification (Flipped Layout) --- */
-  ${(p) =>
-    p.$flip && // Apply only if flipped
-    css`
-      justify-content: flex-end; /* Always align card content to the right */
-      &.left {
-        order: 3; /* Content last */
-      }
-      &.right {
-        order: 1; /* Content first */
-      }
-    `}
- 
-  /* --- Visibility Animation --- */
-  &.visible {
-    visibility: visible;
-    animation: ${animateVisible} 0.25s ease-in; /* Apply fade-in animation */
-  }
-`;
- 
-/**
- * Props for the TimelineTitleWrapper component.
- */
-interface TimelineTitleWrapperProps {
-  /** Controls layout for alternating cards mode. */
-  $alternateCards?: boolean;
-  /** Reverses the order of elements. */
-  $flip?: boolean;
-  /** Hides the title visually. */
-  $hide?: boolean;
-  /** Current timeline mode (e.g., VERTICAL, VERTICAL_ALTERNATING). */
-  mode?: TimelineMode;
-}
- 
-/**
- * Wrapper for the title/date section of a timeline item.
- * Handles width, alignment, and order based on props and mode.
- */
-export const TimelineTitleWrapper = styled.div<TimelineTitleWrapperProps>`
-  align-items: center; /* Vertically center title content */
-  display: ${(p) =>
-    p.$hide && p.mode === 'VERTICAL'
-      ? 'none'
-      : 'flex'}; /* Hide only if $hide and mode is VERTICAL */
- 
-  /* --- Width Calculation --- */
-  width: ${(p) =>
-    p.$alternateCards
-      ? '37.5%' /* Takes up space in alternating mode */
-      : '10%'}; /* Smaller width in standard vertical mode */
- 
-  /* --- Prevent text overflow from affecting layout --- */
-  min-width: 0; /* Allow flex items to shrink below their content size */
-  overflow: hidden; /* Hide overflowing content */
- 
-  /* --- Order and Justification --- */
-  &.left {
-    /* Justification depends on whether layout is flipped */
-    justify-content: ${(p) => (p.$flip ? 'flex-end' : 'flex-start')};
-    /* Order depends on flip status and mode */
-    order: ${(p) => (p.$flip && p.mode === 'VERTICAL_ALTERNATING' ? '1' : '3')};
-  }
- 
-  &.right {
-    /* Justification depends on whether layout is flipped */
-    justify-content: ${(p) => (p.$flip ? 'flex-start' : 'flex-end')};
-    /* Order depends on flip status and mode */
-    order: ${(p) => (p.$flip && p.mode === 'VERTICAL_ALTERNATING' ? '3' : '1')};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline-vertical/timeline-vertical.tsx.html b/coverage/components/timeline-vertical/timeline-vertical.tsx.html deleted file mode 100644 index d2c523877..000000000 --- a/coverage/components/timeline-vertical/timeline-vertical.tsx.html +++ /dev/null @@ -1,523 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical.tsx

-
- -
- 88.04% - Statements - 81/92 -
- - -
- 61.53% - Branches - 8/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 88.04% - Lines - 81/92 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147  -1x -  -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -1x -1x -  -6x -  -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -  -6x -  -  -  -  -  -  -  -  -  -6x -6x -  -  -  -  -  -  -  -6x -6x -  -  -6x -6x -24x -  -  -  -24x -16x -16x -  -8x -8x -8x -  -  -24x -24x -  -  -24x -  -  -24x -24x -  -  -24x -  -  -  -  -  -24x -24x -24x -  -24x -24x -24x -24x -24x -24x -24x -24x -24x -24x -  -24x -24x -24x -24x -  -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -  -  -6x -6x -6x -6x -  -6x -1x -  -  -1x -  -1x - 
import { TimelineVerticalModel } from '@models/TimelineVerticalModel';
-import {
-  useCallback,
-  FunctionComponent,
-  ReactNode,
-  memo,
-  useMemo,
-  ReactElement,
-} from 'react';
-import { useDynamicContext } from '../contexts';
-import TimelineVerticalItem from './timeline-vertical-item';
-import { TimelineVerticalWrapper } from './timeline-vertical.styles';
- 
-/**
- * Renders the main vertical timeline structure.
- * It maps over the provided `items` array and renders a `TimelineVerticalItem`
- * for each, handling layout variations (like alternating cards) and distributing
- * props and callbacks appropriately.
- *
- * @param {TimelineVerticalModel} props - The properties for the TimelineVertical component.
- * @returns {JSX.Element} The rendered TimelineVertical component.
- */
-const TimelineVertical: FunctionComponent<TimelineVerticalModel> = memo(
-  ({
-    // Props with default values
-    alternateCards = true, // Default to alternating card layout on desktop
-    // Callbacks and data props
-    autoScroll, // Function to handle automatic scrolling when an item becomes active
-    contentDetailsChildren, // Optional array of custom nodes for each item's card details
-    hasFocus, // Does the timeline component itself have focus? (Passed down)
-    iconChildren, // Optional custom icon(s) for the timeline points
-    items, // Array of timeline item data objects
-    mode, // Timeline mode (e.g., VERTICAL, VERTICAL_ALTERNATING) - Used by children via context?
-    onClick, // Global click handler for items (passed down)
-    onElapsed, // Global handler for media elapsed events (passed down)
-    onOutlineSelection, // Handler for outline selection (potentially unused here, passed down?)
-    slideShowRunning, // Is a slideshow active? (Passed down)
-    theme, // Theme object (Used by children via context or styled-components)
-    cardLess, // Render without cards? (Passed down)
-    nestedCardHeight, // Specific height for nested cards (Passed down)
-  }: TimelineVerticalModel): ReactElement => {
-    // Access dynamic context for mobile view detection
-    const { isMobile } = useDynamicContext();
- 
-    /**
-     * Callback handler passed to each TimelineVerticalItem's onActive.
-     * When an item becomes active (e.g., scrolls into view), this triggers the autoScroll function
-     * provided via props, allowing the parent component to scroll the timeline if needed.
-     * @param {number} offset - Vertical offset within the active item's point element.
-     * @param {number} wrapperOffset - The offsetTop of the active item's wrapper relative to the scroll parent.
-     * @param {number} height - The clientHeight of the active item's wrapper.
-     */
-    const handleOnActive = useCallback(
-      (offset: number, wrapperOffset: number, height: number) => {
-        // Call the autoScroll prop function if it exists
-        autoScroll?.({
-          contentHeight: height,
-          contentOffset: wrapperOffset,
-          pointOffset: offset,
-        });
-      },
-      [autoScroll], // Dependency: only recreate if autoScroll function changes
-    );
- 
-    // Memoize the items rendering to avoid unnecessary recreations
-    const renderItems = useMemo(() => {
-      return items.map((item, index: number) => {
-        let itemClassName = ''; // CSS class for layout ('left' or 'right')
- 
-        // Determine layout class based on mode and index
-        // In alternating mode on non-mobile views, alternate 'left' and 'right'
-        if (alternateCards && !isMobile) {
-          itemClassName = index % 2 === 0 ? 'left' : 'right';
-        }
-        // Otherwise (non-alternating or mobile), default to 'right'
-        else {
-          itemClassName = 'right';
-        }
- 
-        // Extract specific content details node for this item, if provided
-        const contentDetails: ReactNode | null =
-          (contentDetailsChildren &&
-            Array.isArray(contentDetailsChildren) && // Ensure it's an array
-            contentDetailsChildren[index]) ?? // Get node at the current index
-          null;
- 
-        // Determine the custom icon for this item
-        let customIcon: ReactNode | null = null;
-        if (Array.isArray(iconChildren)) {
-          // If iconChildren is an array, map icon to item by index
-          customIcon = iconChildren[index] ?? null;
-        } else if (iconChildren) {
-          // If iconChildren is a single node, apply it to all items
-          customIcon = iconChildren;
-        }
- 
-        // Render the individual timeline item component
-        return (
-          <TimelineVerticalItem
-            {...item} // Spread all properties from the item data object
-            // --- Pass down calculated or specific props ---
-            alternateCards={alternateCards} // Pass down the alternating mode flag
-            className={itemClassName} // Pass down the calculated 'left'/'right' class
-            contentDetailsChildren={contentDetails} // Pass down the specific content details node
-            iconChild={customIcon} // Pass down the specific icon node
-            hasFocus={hasFocus} // Pass down the focus state
-            index={index} // Pass down the item's index
-            key={item.id ?? `timeline-item-${index}`} // Unique key for React rendering
-            onActive={handleOnActive} // Pass down the memoized active handler
-            onClick={onClick} // Pass down the global click handler
-            onElapsed={onElapsed} // Pass down the global elapsed handler
-            // Removed onShowMore as the handler was empty
-            slideShowRunning={slideShowRunning} // Pass down the slideshow state
-            cardLess={cardLess} // Pass down the cardLess flag
-            nestedCardHeight={nestedCardHeight} // Pass down the nested card height
-          />
-        );
-      });
-    }, [
-      items,
-      isMobile,
-      alternateCards,
-      contentDetailsChildren,
-      iconChildren,
-      hasFocus,
-      handleOnActive,
-      onClick,
-      onElapsed,
-      slideShowRunning,
-      cardLess,
-      nestedCardHeight,
-    ]);
- 
-    // Render the main timeline wrapper
-    return (
-      <TimelineVerticalWrapper as="ul" data-testid="tree-main">
-        {renderItems}
-      </TimelineVerticalWrapper>
-    );
-  },
-);
- 
-// Set display name for React DevTools
-TimelineVertical.displayName = 'TimelineVertical';
- 
-export default TimelineVertical;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/TimelineView.tsx.html b/coverage/components/timeline/TimelineView.tsx.html deleted file mode 100644 index 4ce3679c8..000000000 --- a/coverage/components/timeline/TimelineView.tsx.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - Code coverage report for components/timeline/TimelineView.tsx - - - - - - - - - -
-
-

All files / components/timeline TimelineView.tsx

-
- -
- 100% - Statements - 77/77 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 77/77 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -1081x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -7x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -  -4x -  -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -  -1x - 
import React from 'react';
-import { TimelineMode } from '@models/TimelineModel';
-import TimelineHorizontal from '../timeline-horizontal/timeline-horizontal';
-import TimelineVertical from '../timeline-vertical/timeline-vertical';
-import { Outline, TimelineMain } from './timeline.style';
-import { Scroll } from '@models/TimelineHorizontalModel';
- 
-interface TimelineViewProps {
-  timelineMode: string;
-  activeTimelineItem?: number;
-  autoScroll: (scroll: Partial<Scroll>) => void;
-  contentDetailsChildren?: React.ReactNode;
-  hasFocus: boolean;
-  iconChildren?: React.ReactNode;
-  items: any[]; // Using any to avoid type conflicts
-  handleTimelineItemClick: (itemId?: string) => void;
-  handleTimelineItemElapsed: (itemId?: string) => void;
-  slideShowRunning?: boolean;
-  id: string;
-  theme?: any;
-  lineWidth?: number;
-  onOutlineSelection?: (index: number) => void;
-  nestedCardHeight?: number;
-}
- 
-const TimelineView: React.FC<TimelineViewProps> = ({
-  timelineMode,
-  activeTimelineItem,
-  autoScroll,
-  contentDetailsChildren,
-  hasFocus,
-  iconChildren,
-  items,
-  handleTimelineItemClick,
-  handleTimelineItemElapsed,
-  slideShowRunning,
-  id,
-  theme,
-  lineWidth,
-  onOutlineSelection,
-  nestedCardHeight,
-}) => {
-  // Horizontal Timeline (regular or "all cards" mode)
-  if (timelineMode === 'HORIZONTAL' || timelineMode === 'HORIZONTAL_ALL') {
-    return (
-      <TimelineMain className={timelineMode.toLowerCase()}>
-        <Outline color={theme?.primary} height={lineWidth} />
-        <TimelineHorizontal
-          autoScroll={autoScroll}
-          contentDetailsChildren={contentDetailsChildren}
-          handleItemClick={handleTimelineItemClick}
-          hasFocus={hasFocus}
-          iconChildren={iconChildren}
-          items={items}
-          mode={timelineMode as TimelineMode}
-          onElapsed={handleTimelineItemElapsed}
-          slideShowRunning={slideShowRunning}
-          wrapperId={id}
-          nestedCardHeight={nestedCardHeight}
-        />
-      </TimelineMain>
-    );
-  }
- 
-  // Vertical Alternating Timeline
-  if (timelineMode === 'VERTICAL_ALTERNATING') {
-    return (
-      <TimelineVertical
-        activeTimelineItem={activeTimelineItem}
-        autoScroll={autoScroll}
-        contentDetailsChildren={contentDetailsChildren}
-        hasFocus={hasFocus}
-        iconChildren={iconChildren}
-        items={items}
-        mode={timelineMode as TimelineMode}
-        onClick={handleTimelineItemClick}
-        onElapsed={handleTimelineItemElapsed}
-        onOutlineSelection={onOutlineSelection}
-        slideShowRunning={slideShowRunning}
-        theme={theme}
-        nestedCardHeight={nestedCardHeight}
-      />
-    );
-  }
- 
-  // Vertical Timeline (default)
-  return (
-    <TimelineVertical
-      activeTimelineItem={activeTimelineItem}
-      alternateCards={false}
-      autoScroll={autoScroll}
-      contentDetailsChildren={contentDetailsChildren}
-      hasFocus={hasFocus}
-      iconChildren={iconChildren}
-      items={items}
-      mode={timelineMode as TimelineMode}
-      onClick={handleTimelineItemClick}
-      onElapsed={handleTimelineItemElapsed}
-      onOutlineSelection={onOutlineSelection}
-      slideShowRunning={slideShowRunning}
-      theme={theme}
-      nestedCardHeight={nestedCardHeight}
-    />
-  );
-};
- 
-export default React.memo(TimelineView);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/__tests__/index.html b/coverage/components/timeline/__tests__/index.html deleted file mode 100644 index dee313482..000000000 --- a/coverage/components/timeline/__tests__/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline/__tests__ - - - - - - - - - -
-
-

All files components/timeline/__tests__

-
- -
- 95.02% - Statements - 210/221 -
- - -
- 100% - Branches - 14/14 -
- - -
- 100% - Functions - 0/0 -
- - -
- 95.02% - Lines - 210/221 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
layout-switcher.test.tsx -
-
100%51/51100%3/3100%0/0100%51/51
timeline.test.tsx -
-
93.52%159/170100%11/11100%0/093.52%159/170
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/__tests__/layout-switcher.test.tsx.html b/coverage/components/timeline/__tests__/layout-switcher.test.tsx.html deleted file mode 100644 index 3575bd68e..000000000 --- a/coverage/components/timeline/__tests__/layout-switcher.test.tsx.html +++ /dev/null @@ -1,571 +0,0 @@ - - - - - - Code coverage report for components/timeline/__tests__/layout-switcher.test.tsx - - - - - - - - - -
-
-

All files / components/timeline/__tests__ layout-switcher.test.tsx

-
- -
- 100% - Statements - 51/51 -
- - -
- 100% - Branches - 3/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 51/51 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -1631x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -1x -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
import { fireEvent } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { vi } from 'vitest';
-import { LayoutSwitcher } from '../timeline-popover-elements';
- 
-describe('LayoutSwitcher Component', () => {
-  const onUpdateTimelineMode = vi.fn();
-  const theme = getDefaultThemeOrDark();
-  const isDarkMode = false;
-  const position = 'top';
- 
-  test('Renders correctly with vertical layout options', () => {
-    const { getByText } = customRender(
-      <LayoutSwitcher
-        onUpdateTimelineMode={onUpdateTimelineMode}
-        theme={theme}
-        mode="VERTICAL"
-        isDarkMode={isDarkMode}
-        position={position}
-        isMobile={false}
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    // Add your assertions here
-    expect(getByText('Change layout')).toBeInTheDocument();
- 
-    fireEvent.click(getByText('Change layout'));
- 
-    expect(getByText('Vertical')).toBeInTheDocument();
-    expect(getByText('Alternating')).toBeInTheDocument();
-  });
- 
-  test('Renders correctly with horizontal layout options', () => {
-    const { getByText } = customRender(
-      <LayoutSwitcher
-        onUpdateTimelineMode={onUpdateTimelineMode}
-        theme={theme}
-        mode="HORIZONTAL"
-        isDarkMode={isDarkMode}
-        position={position}
-        isMobile={false}
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    // Add your assertions here
-    expect(getByText('Change layout')).toBeInTheDocument();
- 
-    fireEvent.click(getByText('Change layout'));
- 
-    // expect(getByText('Horizontal')).toBeInTheDocument();
-    // expect(getByText('Show all cards')).toBeInTheDocument();
-  });
- 
-  //   test('Handles mode selection correctly', async () => {
-  //     const { getByText } = customRender(
-  //       <LayoutSwitcher
-  //         onUpdateTimelineMode={onUpdateTimelineMode}
-  //         theme={theme}
-  //         mode="VERTICAL"
-  //         isDarkMode={isDarkMode}
-  //         position={position}
-  //         isMobile={false}
-  //       />,
-  //       {
-  //         providerProps: {
-  //           ...providerProps,
-  //         },
-  //       },
-  //     );
- 
-  //     expect(getByText('Change layout')).toBeInTheDocument();
- 
-  //     fireEvent.click(getByText('Change layout'));
- 
-  //     expect(getByText('Default')).toBeInTheDocument();
- 
-  //     // Simulate clicking on a mode option
-  //     fireEvent.click(getByText('Default'));
- 
-  //     await waitFor(() => {
-  //       expect(onUpdateTimelineMode).toHaveBeenCalledWith('VERTICAL');
-  //     });
-  //   });
-  // });
- 
-  // describe('QuickJump Component', () => {
-  //   const onActivateItem = vi.fn();
-  //   const theme = getDefaultThemeOrDark();
-  //   const isDarkMode = false;
-  //   const position = 'top';
-  //   const items = [
-  //     { description: 'Description 1', id: '1', title: 'Item 1' },
-  //     { description: 'Description 2', id: '2', title: 'Item 2' },
-  //   ];
- 
-  //   test('Renders correctly with provided items', () => {
-  //     const { getByText } = customRender(
-  //       <QuickJump
-  //         activeItem={0}
-  //         items={items}
-  //         theme={theme}
-  //         onActivateItem={onActivateItem}
-  //         isDarkMode={isDarkMode}
-  //         position={position}
-  //         isMobile={false}
-  //       />,
-  //       {
-  //         providerProps: {
-  //           ...providerProps,
-  //         },
-  //       },
-  //     );
- 
-  //     // Add your assertions here
- 
-  //     expect(getByText('Jump to')).toBeInTheDocument();
- 
-  //     fireEvent.click(getByText('Jump to'));
- 
-  //     expect(getByText('Item 1')).toBeInTheDocument();
-  //     expect(getByText('Item 2')).toBeInTheDocument();
-  //   });
- 
-  //   test('Handles item activation correctly', () => {
-  //     const { getByText } = customRender(
-  //       <QuickJump
-  //         activeItem={0}
-  //         items={items}
-  //         theme={theme}
-  //         onActivateItem={onActivateItem}
-  //         isDarkMode={isDarkMode}
-  //         position={position}
-  //         isMobile={false}
-  //       />,
-  //       {
-  //         providerProps: {
-  //           ...providerProps,
-  //         },
-  //       },
-  //     );
- 
-  //     expect(getByText('Jump to')).toBeInTheDocument();
- 
-  //     fireEvent.click(getByText('Jump to'));
- 
-  //     // Simulate clicking on an item
-  //     fireEvent.click(getByText('Item 1'));
- 
-  //     expect(onActivateItem).toHaveBeenCalledWith('1');
-  //   });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/__tests__/timeline.test.tsx.html b/coverage/components/timeline/__tests__/timeline.test.tsx.html deleted file mode 100644 index 3f0b07919..000000000 --- a/coverage/components/timeline/__tests__/timeline.test.tsx.html +++ /dev/null @@ -1,847 +0,0 @@ - - - - - - Code coverage report for components/timeline/__tests__/timeline.test.tsx - - - - - - - - - -
-
-

All files / components/timeline/__tests__ timeline.test.tsx

-
- -
- 93.52% - Statements - 159/170 -
- - -
- 100% - Branches - 11/11 -
- - -
- 100% - Functions - 0/0 -
- - -
- 93.52% - Lines - 159/170 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255  -1x -1x -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -5x -5x -5x -5x -  -5x -5x -5x -5x -5x -5x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -3x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { TimelineModel } from '@models/TimelineModel';
-import { waitFor } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import { describe, expect, it, vi } from 'vitest';
-import { customRender, providerProps } from '../../common/test';
-import Timeline from '../timeline';
- 
-window.matchMedia = vi.fn().mockImplementation((query) => {
-  return {
-    addEventListener: vi.fn(),
-    addListener: vi.fn(),
-    dispatchEvent: vi.fn(),
-    matches: false,
-    media: query,
-    onchange: null,
-    removeEventListener: vi.fn(),
-    removeListener: vi.fn(),
-  };
-});
- 
-window.IntersectionObserver = vi.fn().mockImplementation(() => {
-  return {
-    disconnect: vi.fn(),
-    observe: vi.fn(),
-    root: null,
- 
-    rootMargin: '',
-    takeRecords: vi.fn(),
-    thresholds: [],
-    unobserve: vi.fn(),
-  } as IntersectionObserver;
-});
- 
-describe('Timeline', () => {
-  const commonProps: TimelineModel = {
-    activeTimelineItem: 0,
-    contentDetailsChildren: null,
-    iconChildren: null,
-    isChild: false,
-    items: [
-      {
-        cardDetailedText: 'Detailed text 1',
-        cardSubtitle: 'Subtitle 1',
-        cardTitle: 'Card 1',
-        id: '1',
-        title: 'Item 1',
-      },
-      {
-        cardDetailedText: 'Detailed text 2',
-        cardSubtitle: 'Subtitle 2',
-        cardTitle: 'Card 2',
-        id: '2',
-        title: 'Item 2',
-      },
-      {
-        cardDetailedText: 'Detailed text 3',
-        cardSubtitle: 'Subtitle 3',
-        cardTitle: 'Card 3',
-        id: '3',
-        title: 'Item 3',
-      },
-      {
-        cardDetailedText: 'Detailed text 4',
-        cardSubtitle: 'Subtitle 4',
-        cardTitle: 'Card 4',
-        id: '4',
-        title: 'Item 4',
-      },
-    ],
-    mode: 'HORIZONTAL',
-    nestedCardHeight: 200,
-    noUniqueId: false,
-    onFirst: vi.fn(),
-    onItemSelected: vi.fn(),
-    onLast: vi.fn(),
-    onNext: vi.fn(),
-    onOutlineSelection: vi.fn(),
-    onPaused: vi.fn(),
-    onPrevious: vi.fn(),
-    onRestartSlideshow: vi.fn(),
-    onTimelineUpdated: vi.fn(),
-    slideShowEnabled: true,
-    slideShowRunning: false,
-    uniqueId: 'timeline-1',
-  };
- 
-  it('should render the timeline with correct items', () => {
-    const { getByText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const item1 = getByText('Item 1');
-    const item2 = getByText('Item 2');
- 
-    expect(item1).toBeInTheDocument();
-    expect(item2).toBeInTheDocument();
-  });
- 
-  //shoulkd render the timeline items correctly when the mode is HORIZONTAL
-  it('should render the timeline items correctly when the mode is HORIZONTAL', () => {
-    const { getByText } = customRender(
-      <Timeline {...commonProps} mode="HORIZONTAL" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const item1 = getByText('Item 1');
-    const item2 = getByText('Item 2');
- 
-    expect(item1).toBeInTheDocument();
-    expect(item2).toBeInTheDocument();
-  });
- 
-  // it('should call onNext', async () => {
-  //   const onNext = vi.fn();
- 
-  //   const { getByLabelText, getByText } = customRender(
-  //     <Timeline {...commonProps} mode="VERTICAL_ALTERNATING" onNext={onNext} />,
-  //     {
-  //       providerProps: {
-  //         ...providerProps,
-  //       },
-  //     },
-  //   );
- 
-  //   const nextButton = getByLabelText('next');
- 
-  //   expect(nextButton).toBeInTheDocument();
- 
-  //   fireEvent.click(nextButton);
- 
-  //   await waitFor(
-  //     () => {
-  //       expect(onNext).toHaveBeenCalled();
-  //       // expect(nextButton).toHaveAttribute('aria-disabled', 'false');
-  //     },
-  //     {
-  //       timeout: 2000,
-  //     },
-  //   );
-  // });
- 
-  //should call onPrevious after next button is clicked
-  it('should call onPrevious after next button is clicked', async () => {
-    const { getByLabelText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL_ALTERNATING" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const nextButton = getByLabelText('next');
-    const previousButton = getByLabelText('previous');
- 
-    expect(previousButton).toBeInTheDocument();
-    expect(nextButton).toBeInTheDocument();
- 
-    userEvent.click(nextButton);
- 
-    await waitFor(() => {
-      expect(nextButton).toHaveAttribute('aria-disabled', 'false');
-    });
-  });
- 
-  // should call onLast when last button is clicked
-  it('should call onLast and onFirst when last button is clicked', async () => {
-    const { getByLabelText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL_ALTERNATING" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const lastButton = getByLabelText('last');
-    const firstButton = getByLabelText('first');
- 
-    userEvent.click(lastButton);
- 
-    await waitFor(() => {
-      expect(commonProps.onLast).toHaveBeenCalled();
-    });
-  });
- 
-  //should call onFirst when first button is clicked
-  // it('should call onFirst when first button is clicked', async () => {
-  //   const { getByLabelText } = customRender(
-  //     <Timeline
-  //       {...commonProps}
-  //       mode="VERTICAL_ALTERNATING"
-  //       activeTimelineItem={1}
-  //     />,
-  //     {
-  //       providerProps,
-  //     },
-  //   );
- 
-  //   const firstButton = getByLabelText('first');
- 
-  //   userEvent.click(firstButton);
- 
-  //   await waitFor(() => {
-  //     expect(commonProps.onFirst).toHaveBeenCalled();
-  //   });
-  // });
- 
-  // //should call onLast when last button is clicked
-  it('should call onLast when last button is clicked', () => {
-    const { getByLabelText } = customRender(
-      <Timeline
-        {...commonProps}
-        mode="VERTICAL_ALTERNATING"
-        activeTimelineItem={0}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    const lastButton = getByLabelText('last');
- 
-    expect(lastButton).toBeInTheDocument();
- 
-    userEvent.click(lastButton);
- 
-    expect(commonProps.onLast).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should call onItemSelected when an item is clicked', async () => {
-    const { getByText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const item1 = getByText('Item 1');
- 
-    userEvent.click(item1);
- 
-    await waitFor(() => {
-      expect(commonProps.onItemSelected).toHaveBeenCalledWith({
-        cardDetailedText: 'Detailed text 1',
-        cardSubtitle: 'Subtitle 1',
-        cardTitle: 'Card 1',
-        index: 0,
-        title: 'Item 1',
-      });
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/index.html b/coverage/components/timeline/index.html deleted file mode 100644 index 380ce0890..000000000 --- a/coverage/components/timeline/index.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - Code coverage report for components/timeline - - - - - - - - - -
-
-

All files components/timeline

-
- -
- 78.48% - Statements - 693/883 -
- - -
- 64.76% - Branches - 68/105 -
- - -
- 44.82% - Functions - 13/29 -
- - -
- 78.48% - Lines - 693/883 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
TimelineView.tsx -
-
100%77/77100%6/6100%1/1100%77/77
timeline-popover-elements.tsx -
-
77.43%127/164100%12/1222.22%2/977.43%127/164
timeline-popover.model.ts -
-
0%0/00%1/10%1/10%0/0
timeline-toolbar.model.ts -
-
0%0/00%1/10%1/10%0/0
timeline-toolbar.tsx -
-
64.94%176/27142.3%11/2622.22%2/964.94%176/271
timeline.style.ts -
-
89.09%49/5573.52%25/34100%4/489.09%49/55
timeline.style.tsx -
-
0%0/290%0/10%0/10%0/29
timeline.tsx -
-
91.98%264/28750%12/2466.66%2/391.98%264/287
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/timeline-popover-elements.tsx.html b/coverage/components/timeline/timeline-popover-elements.tsx.html deleted file mode 100644 index 7c6936794..000000000 --- a/coverage/components/timeline/timeline-popover-elements.tsx.html +++ /dev/null @@ -1,664 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-popover-elements.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline-popover-elements.tsx

-
- -
- 77.43% - Statements - 127/164 -
- - -
- 100% - Branches - 12/12 -
- - -
- 22.22% - Functions - 2/9 -
- - -
- 77.43% - Lines - 127/164 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -1941x -1x -1x -1x -1x -  -  -  -  -  -  -1x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -  -2x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -  -2x -2x -2x -2x -2x -2x -  -  -2x -2x -2x -2x -2x -2x -2x -  -  -2x -2x -2x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -2x -1x -1x -  -2x -2x -2x -2x -  -2x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -  -7x -7x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -7x -7x -  -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -  -7x -  -  - 
import { FunctionComponent, useMemo } from 'react';
-import { useStableContext, useDynamicContext } from '../contexts';
-import { List } from '../elements/list/list';
-import PopOver from '../elements/popover';
-import { ArrowDownIcon, LayoutIcon, ParaIcon } from '../icons';
-import {
-  ChangeDensityProp,
-  LayoutSwitcherProp,
-  QuickJumpProp,
-} from './timeline-popover.model';
- 
-const LayoutSwitcher: FunctionComponent<LayoutSwitcherProp> = ({
-  onUpdateTimelineMode,
-  theme,
-  mode,
-  isDarkMode,
-  position,
-  isMobile,
-}: LayoutSwitcherProp) => {
-  const { memoizedButtonTexts: buttonTexts } = useStableContext();
-  const { horizontalAll: showAllCardsHorizontal } = useDynamicContext();
- 
-  const LayoutIconMemo = useMemo(() => <LayoutIcon />, []);
- 
-  const activeTimelineMode = useMemo(
-    () => mode,
-    [showAllCardsHorizontal, mode],
-  );
- 
-  const layoutOptions = useMemo(
-    () => ({
-      alternating: buttonTexts?.changeLayoutOptions.alternating,
-      horizontal: buttonTexts?.changeLayoutOptions.horizontal,
-      horizontal_all: buttonTexts?.changeLayoutOptions.horizontal_all,
-      vertical: buttonTexts?.changeLayoutOptions.vertical,
-    }),
-    [],
-  );
- 
-  const verticalItems = useMemo(
-    () => [
-      {
-        description: layoutOptions.vertical.helpText,
-        id: 'VERTICAL',
-        onSelect: () => onUpdateTimelineMode('VERTICAL'),
-        selected: activeTimelineMode === 'VERTICAL',
-        title: layoutOptions.vertical.text,
-      },
-      {
-        description: layoutOptions.alternating.helpText,
-        id: 'VERTICAL_ALTERNATING',
-        onSelect: () => onUpdateTimelineMode('VERTICAL_ALTERNATING'),
-        selected: activeTimelineMode === 'VERTICAL_ALTERNATING',
-        title: layoutOptions.alternating.text,
-      },
-    ],
-    [activeTimelineMode],
-  );
- 
-  // horizontal list OF options when the mode is `HORIZONTAL`
-  const horizontalItems = useMemo(
-    () => [
-      {
-        description: layoutOptions.horizontal.helpText,
-        id: 'HORIZONTAL',
-        onSelect: () => {
-          onUpdateTimelineMode('HORIZONTAL');
-        },
-        selected: activeTimelineMode === 'HORIZONTAL',
-        title: layoutOptions.horizontal.text,
-      },
-      {
-        description: layoutOptions.horizontal_all.helpText,
-        id: 'HORIZONTAL_ALL',
-        onSelect: () => {
-          onUpdateTimelineMode('HORIZONTAL_ALL');
-        },
-        selected: activeTimelineMode === 'HORIZONTAL_ALL',
-        title: layoutOptions.horizontal.text,
-      },
-    ],
-    [activeTimelineMode],
-  );
- 
-  return (
-    <PopOver
-      placeholder={buttonTexts.changeLayout}
-      position={position}
-      theme={theme}
-      isDarkMode={isDarkMode}
-      icon={LayoutIconMemo}
-      $isMobile={isMobile}
-    >
-      <List
-        items={
-          mode === 'HORIZONTAL' || mode === 'HORIZONTAL_ALL'
-            ? horizontalItems
-            : verticalItems
-        }
-        theme={theme}
-        multiSelectable
-      />
-    </PopOver>
-  );
-};
- 
-const QuickJump: FunctionComponent<QuickJumpProp> = ({
-  activeItem,
-  items,
-  theme,
-  onActivateItem,
-  isDarkMode,
-  position,
-  isMobile,
-}: QuickJumpProp) => {
-  const { memoizedButtonTexts: buttonTexts } = useStableContext();
- 
-  const ArrowDownIconMemo = useMemo(() => <ArrowDownIcon />, []);
- 
-  return (
-    <PopOver
-      placeholder={buttonTexts.jumpTo}
-      position={position}
-      theme={theme}
-      width={400}
-      isDarkMode={isDarkMode}
-      $isMobile={isMobile}
-      icon={ArrowDownIconMemo}
-    >
-      <List
-        items={items.map((item, index) => ({
-          active: index === activeItem,
-          description: item.description,
-          id: item.id,
-          label: item.title,
-          onSelect: () => {},
-          title: item.title ?? `Item ${index + 1}`,
-        }))}
-        theme={theme}
-        onClick={onActivateItem}
-      />
-    </PopOver>
-  );
-};
- 
-const ChangeDensity: FunctionComponent<ChangeDensityProp> = ({
-  onChange,
-  selectedDensity,
-  theme,
-  isDarkMode,
-  position,
-  isMobile,
-}) => {
-  const { memoizedButtonTexts: buttonTexts } = useStableContext();
- 
-  const ParaIconMemo = useMemo(() => <ParaIcon />, []);
- 
-  const items = useMemo(
-    () => [
-      {
-        description: 'Show less text',
-        id: 'LOW',
-        onSelect: () => onChange('LOW'),
-        selected: selectedDensity === 'LOW',
-        title: 'Low',
-      },
-      {
-        description: 'Show more text',
-        id: 'HIGH',
-        onSelect: () => onChange('HIGH'),
-        selected: selectedDensity === 'HIGH',
-        title: 'High',
-      },
-    ],
-    [selectedDensity],
-  );
- 
-  return (
-    <PopOver
-      placeholder={buttonTexts.changeDensity}
-      theme={theme}
-      isDarkMode={isDarkMode}
-      position={position}
-      $isMobile={isMobile}
-      width={300}
-      icon={ParaIconMemo}
-    >
-      <List items={items} theme={theme} multiSelectable />
-    </PopOver>
-  );
-};
- 
-export { ChangeDensity, LayoutSwitcher, QuickJump };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/timeline-popover.model.ts.html b/coverage/components/timeline/timeline-popover.model.ts.html deleted file mode 100644 index 27d444661..000000000 --- a/coverage/components/timeline/timeline-popover.model.ts.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-popover.model.ts - - - - - - - - - -
-
-

All files / components/timeline timeline-popover.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TextDensity, TimelineMode } from '@models/TimelineModel';
-import { ListItemModel } from '../elements/list/list.model';
- 
-export type CommonProps = {
-  isDarkMode: boolean;
-  isMobile: boolean;
-  position: 'top' | 'bottom';
-  theme: Theme;
-};
- 
-export type LayoutSwitcherProp = {
-  initialTimelineMode?: TimelineMode | 'HORIZONTAL_ALL';
-  mode?: TimelineMode;
-  onUpdateTimelineMode: (s: string) => void;
-} & CommonProps;
- 
-export type QuickJumpProp = {
-  activeItem: number;
-  items: ListItemModel[];
-  onActivateItem: (id: string) => void;
-} & CommonProps;
- 
-export type ChangeDensityProp = {
-  onChange: (value: TextDensity) => void;
-  selectedDensity: TextDensity;
-} & CommonProps;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/timeline-toolbar.model.ts.html b/coverage/components/timeline/timeline-toolbar.model.ts.html deleted file mode 100644 index 30297843a..000000000 --- a/coverage/components/timeline/timeline-toolbar.model.ts.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-toolbar.model.ts - - - - - - - - - -
-
-

All files / components/timeline timeline-toolbar.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import {
-  TextDensity,
-  TimelineMode,
-  TimelineModel,
-  TimelineProps,
-} from '@models/TimelineModel';
-import { RefObject } from 'react';
- 
-export type TimelineToolbarProps = Pick<
-  TimelineModel,
-  | 'activeTimelineItem'
-  | 'slideShowEnabled'
-  | 'slideShowRunning'
-  | 'onRestartSlideshow'
-  | 'onNext'
-  | 'onPrevious'
-  | 'onPaused'
-  | 'onFirst'
-  | 'onLast'
-  | 'items'
-  | 'mode'
-> & {
-  id: string;
-  onActivateTimelineItem: (id: string) => void;
-  onUpdateTextContentDensity: (value: TextDensity) => void;
-  onUpdateTimelineMode: (mode: TimelineMode) => void;
-  toggleDarkMode: () => void;
-  totalItems: number;
- 
-  // Search related props
-  searchQuery: string;
-  onSearchChange: (query: string) => void;
-  onClearSearch: () => void;
-  onNextMatch: () => void;
-  onPreviousMatch: () => void;
-  totalMatches: number;
-  currentMatchIndex: number; // 0-based index
-  onSearchKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
-  searchInputRef?: RefObject<HTMLInputElement>; // Ref for the search input
-} & Pick<TimelineProps, 'darkMode' | 'flipLayout'>;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/timeline-toolbar.tsx.html b/coverage/components/timeline/timeline-toolbar.tsx.html deleted file mode 100644 index fa2025492..000000000 --- a/coverage/components/timeline/timeline-toolbar.tsx.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-toolbar.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline-toolbar.tsx

-
- -
- 64.94% - Statements - 176/271 -
- - -
- 42.3% - Branches - 11/26 -
- - -
- 22.22% - Functions - 2/9 -
- - -
- 64.94% - Lines - 176/271 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -48x -48x -48x -  -  -48x -48x -48x -48x -  -  -  -  -  -  -  -1x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -7x -7x -7x -7x -  -  -7x -6x -24x -24x -24x -24x -6x -7x -  -  -7x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -7x -  -  -7x -6x -  -  -6x -7x -  -  -7x -6x -  -  -6x -7x -  -7x -6x -7x -  -7x -6x -7x -  -7x -  -  -  -  -7x -  -  -  -  -  -  -  -  -7x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -7x -7x -7x -7x -  -  -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -7x -  -  -  -  -7x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -7x -7x -7x -7x -7x -  -7x -7x -  -  -  -  -  -  -  -  -  -7x -7x -7x -7x -  -  -  -  -  -  -  -  -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -  -  -  - 
// Import necessary dependencies
-import React, { FunctionComponent, useMemo } from 'react';
-import { useStableContext, useDynamicContext } from '../contexts';
-import Controls from '../timeline-elements/timeline-control/timeline-control';
-import { TimelineNavButton } from '../timeline-elements/timeline-control/timeline-control.styles';
-import { ChevronLeft, ChevronRight, CloseIcon } from '../icons';
-import { Toolbar } from '../toolbar';
-import {
-  ChangeDensity,
-  LayoutSwitcher,
-  QuickJump,
-} from './timeline-popover-elements';
-import { TimelineToolbarProps } from './timeline-toolbar.model';
-import {
-  ExtraControls,
-  SearchInput,
-  SearchWrapper,
-  SearchInfo,
-} from './timeline.style';
- 
-// Helper function to convert ReactNode to string safely
-const getTextFromNode = (
-  content: React.ReactNode | string | undefined,
-): string => {
-  if (content === null || content === undefined) {
-    return '';
-  }
-  if (typeof content === 'string') {
-    return content;
-  }
-  if (typeof content === 'number' || typeof content === 'boolean') {
-    return String(content);
-  }
-  // For any other ReactNode, return empty string
-  return '';
-};
- 
-// Define the TimelineToolbar component
-const TimelineToolbar: FunctionComponent<TimelineToolbarProps> = ({
-  activeTimelineItem,
-  slideShowEnabled,
-  slideShowRunning,
-  flipLayout,
-  toggleDarkMode,
-  onPaused,
-  onFirst,
-  onLast,
-  onNext,
-  onPrevious,
-  onRestartSlideshow,
-  totalItems,
-  items = [],
-  id,
-  onActivateTimelineItem,
-  onUpdateTimelineMode,
-  onUpdateTextContentDensity,
-  mode,
-  searchQuery,
-  onSearchChange,
-  onClearSearch,
-  onNextMatch,
-  onPreviousMatch,
-  totalMatches,
-  currentMatchIndex,
-  onSearchKeyDown,
-  searchInputRef,
-}: TimelineToolbarProps) => {
-  // Access the stable and dynamic contexts
-  const {
-    cardLess,
-    enableQuickJump,
-    toolbarPosition,
-    enableLayoutSwitch,
-    memoizedButtonTexts: buttonTexts,
-  } = useStableContext();
- 
-  const {
-    memoizedTheme: theme,
-    isDarkMode: darkMode,
-    textContentDensity: textDensity,
-    isMobile,
-  } = useDynamicContext();
- 
-  // Prepare QuickJump items with proper string conversions
-  const quickJumpItems = useMemo(() => {
-    return items.map((item) => ({
-      id: item.id ?? '',
-      title: getTextFromNode(item.title),
-      description: getTextFromNode(item.cardSubtitle),
-      active: item.active,
-    }));
-  }, [items]);
- 
-  // Define the toolbar items
-  const toolbarItems = useMemo(() => {
-    return [
-      {
-        id: 'timeline-controls',
-        label: 'Timeline Controls',
-        name: 'timeline_control',
-        onSelect: () => {},
-      },
-      {
-        id: 'timeline-popover',
-        label: 'timeline_popover',
-        name: 'popover',
-        onSelect: () => {},
-      },
-      {
-        id: 'layout-popover',
-        label: 'layout_popover',
-        name: 'popover',
-        onSelect: () => {},
-      },
-      {
-        id: 'change-density',
-        label: 'change_density',
-        name: 'changeDensity',
-        onSelect: () => {},
-      },
-    ];
-  }, []);
- 
-  // Define methods to determine button state
-  const isLeftDisabled = useMemo(() => {
-    if (flipLayout) {
-      return activeTimelineItem === totalItems - 1;
-    }
-    return activeTimelineItem === 0;
-  }, [flipLayout, activeTimelineItem, totalItems]);
- 
-  // Determine if the right arrow should be disabled
-  const isRightDisabled = useMemo(() => {
-    if (flipLayout) {
-      return activeTimelineItem === 0;
-    }
-    return activeTimelineItem === totalItems - 1;
-  }, [flipLayout, activeTimelineItem, totalItems]);
- 
-  const hideExtraControls = useMemo(() => {
-    return cardLess || slideShowRunning;
-  }, [cardLess, slideShowRunning]);
- 
-  const canShowDensity = useMemo(() => {
-    return items.every((item) => item.cardDetailedText);
-  }, []);
- 
-  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
-    onSearchChange(event.target.value);
-  };
- 
-  // Handle clear search and focus the input
-  const handleClearSearch = () => {
-    onClearSearch();
-    // Focus the search input after clearing
-    setTimeout(() => {
-      searchInputRef?.current?.focus();
-    }, 0);
-  };
- 
-  // Add KeyDown handler for Enter key navigation
-  const handleSearchKeyDown = (
-    event: React.KeyboardEvent<HTMLInputElement>,
-  ) => {
-    if (event.key === 'Enter' && totalMatches > 0) {
-      event.preventDefault(); // Prevent potential form submission
- 
-      // Save the current search query before navigation
-      const currentQuery = searchQuery;
- 
-      // Navigate to next match
-      if (onSearchKeyDown) {
-        // Use the provided handler if available
-        onSearchKeyDown(event);
-      } else {
-        onNextMatch(); // Use default navigation
-      }
- 
-      // Re-focus the search input after a short delay
-      // This allows the navigation to complete first
-      setTimeout(() => {
-        if (searchInputRef?.current) {
-          searchInputRef.current.focus();
- 
-          // If the value has been cleared, restore it
-          if (searchInputRef.current.value === '' && currentQuery) {
-            // This is a backup to ensure the search query persists
-            // The main handling should be in the parent component
-            onSearchChange(currentQuery);
-          }
- 
-          // Ensure the cursor is at the end of the text
-          const length = searchInputRef.current.value.length;
-          searchInputRef.current.setSelectionRange(length, length);
-        }
-      }, 50);
-    }
-  };
- 
-  // Disable search navigation if no matches or slideshow running
-  const disableSearchNav = useMemo(
-    () => totalMatches === 0 || slideShowRunning,
-    [totalMatches, slideShowRunning],
-  );
- 
-  // Render the TimelineToolbar component
-  return (
-    <Toolbar items={toolbarItems} theme={theme}>
-      <Controls
-        disableLeft={isLeftDisabled}
-        disableRight={isRightDisabled}
-        id={id}
-        onFirst={onFirst}
-        onLast={onLast}
-        onNext={onNext}
-        onPrevious={onPrevious}
-        onReplay={onRestartSlideshow}
-        slideShowEnabled={slideShowEnabled}
-        slideShowRunning={slideShowRunning}
-        isDark={darkMode}
-        onToggleDarkMode={toggleDarkMode}
-        onPaused={onPaused}
-        activeTimelineItem={activeTimelineItem}
-        totalItems={totalItems}
-      />
-      <SearchWrapper theme={theme}>
-        <SearchInput
-          ref={searchInputRef}
-          type="search"
-          placeholder={buttonTexts?.searchPlaceholder ?? 'Search Timeline'}
-          value={searchQuery}
-          onChange={handleInputChange}
-          onKeyDown={handleSearchKeyDown}
-          aria-label={buttonTexts?.searchAriaLabel ?? 'Search timeline content'}
-          disabled={slideShowRunning}
-        />
-        {searchQuery && (
-          <TimelineNavButton
-            onClick={handleClearSearch}
-            title={buttonTexts?.clearSearch ?? 'Clear Search'}
-            aria-label={buttonTexts?.clearSearch ?? 'Clear Search'}
-            theme={theme}
-            style={{
-              height: '24px',
-              width: '24px',
-              marginRight: '0.5rem',
-            }}
-          >
-            <CloseIcon />
-          </TimelineNavButton>
-        )}
-        {totalMatches > 0 && (
-          <SearchInfo theme={theme}>
-            {`${currentMatchIndex + 1} / ${totalMatches}`}
-          </SearchInfo>
-        )}
-        {searchQuery && (
-          <>
-            <div className="timeline-nav-wrapper">
-              <TimelineNavButton
-                onClick={onPreviousMatch}
-                title={buttonTexts?.previousMatch ?? 'Previous Match'}
-                aria-label={buttonTexts?.previousMatch ?? 'Previous Match'}
-                disabled={disableSearchNav}
-                theme={theme}
-                style={{ height: '24px', width: '24px' }}
-              >
-                <ChevronLeft />
-              </TimelineNavButton>
-            </div>
-            <div className="timeline-nav-wrapper">
-              <TimelineNavButton
-                onClick={onNextMatch}
-                title={buttonTexts?.nextMatch ?? 'Next Match'}
-                aria-label={buttonTexts?.nextMatch ?? 'Next Match'}
-                disabled={disableSearchNav}
-                theme={theme}
-                style={{ height: '24px', width: '24px' }}
-              >
-                <ChevronRight />
-              </TimelineNavButton>
-            </div>
-          </>
-        )}
-      </SearchWrapper>
-      <ExtraControls
-        $hide={hideExtraControls}
-        $slideShowRunning={slideShowRunning}
-        key="timeline-extra-controls"
-      >
-        <div className="control-wrapper" key="quick-jump">
-          {enableQuickJump ? (
-            <QuickJump
-              activeItem={activeTimelineItem}
-              isDarkMode={darkMode}
-              items={quickJumpItems}
-              onActivateItem={onActivateTimelineItem}
-              theme={theme}
-              position={toolbarPosition}
-              isMobile={isMobile}
-            />
-          ) : null}
-        </div>
-        <div className="control-wrapper" key="layout-switcher">
-          {!cardLess && enableLayoutSwitch ? (
-            <LayoutSwitcher
-              isDarkMode={darkMode}
-              theme={theme}
-              onUpdateTimelineMode={onUpdateTimelineMode}
-              mode={mode}
-              position={toolbarPosition}
-              isMobile={isMobile}
-            />
-          ) : null}
-        </div>
-        {canShowDensity ? (
-          <div className="control-wrapper" key="change-density">
-            <ChangeDensity
-              isDarkMode={darkMode}
-              theme={theme}
-              onChange={onUpdateTextContentDensity}
-              position={toolbarPosition}
-              selectedDensity={textDensity}
-              isMobile={isMobile}
-            ></ChangeDensity>
-          </div>
-        ) : null}{' '}
-      </ExtraControls>
-    </Toolbar>
-  );
-};
- 
-// Export the TimelineToolbar component
-export { TimelineToolbar };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/timeline.style.ts.html b/coverage/components/timeline/timeline.style.ts.html deleted file mode 100644 index 838f39386..000000000 --- a/coverage/components/timeline/timeline.style.ts.html +++ /dev/null @@ -1,805 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline.style.ts - - - - - - - - - -
-
-

All files / components/timeline timeline.style.ts

-
- -
- 89.09% - Statements - 49/55 -
- - -
- 73.52% - Branches - 25/34 -
- - -
- 100% - Functions - 4/4 -
- - -
- 89.09% - Lines - 49/55 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241  -  -1x -1x -1x -  -  -1x -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -1x -1x -  -1x -  -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -7x -  -7x -7x -1x -1x -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../styles/z-index';
-import { ScrollBar } from '../common/styles';
- 
-// CSS transform and animation fallbacks
-const getTransform = (transform?: string) => transform || 'none';
- 
-const transitionMixin = css`
-  -webkit-transition: all 0.2s ease;
-  -moz-transition: all 0.2s ease;
-  -ms-transition: all 0.2s ease;
-  -o-transition: all 0.2s ease;
-  transition: all 0.2s ease;
-`;
- 
-// Timeline wrapper with improved cross-browser support
-export const Wrapper = styled.div<{
-  cardPositionHorizontal?: 'TOP' | 'BOTTOM';
-  theme?: Theme;
-  $translate?: string;
-}>`
-  -webkit-transform: ${props => getTransform(props.$translate)};
-  -moz-transform: ${props => getTransform(props.$translate)};
-  -ms-transform: ${props => getTransform(props.$translate)};
-  transform: ${props => getTransform(props.$translate)};
-  ${transitionMixin}
-  display: flex;
-  flex-direction: column;
-  /* cannot remove this */
-  height: 100%;
-  z-index: ${zIndex.timelineCard - 2}; /* Base z-index for timeline */
- 
-  &:focus {
-    outline: 0;
-  }
- 
-  overflow: hidden;
-  position: relative;
-  width: 100%;
- 
-  &.horizontal {
-    justify-content: flex-start;
-  }
- 
-  &.js-focus-visible :focus:not(.focus-visible) {
-    /* outline: 0; */
-  }
- 
-  &.js-focus-visible .focus-visible {
-    outline: 2px solid #528deb;
-  }
-`;
- 
-export const TimelineMainWrapper = styled.div<{
-  $scrollable?: boolean | { scrollbar: boolean };
-  mode?: TimelineMode;
-  position?: 'top' | 'bottom';
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  display: flex;
-  justify-content: center;
-  overflow-y: auto;
-  overflow-x: hidden;
-  overscroll-behavior: contain;
-  ${(p) => (p.mode === 'HORIZONTAL' ? 'position: relative' : '')};
-  scroll-behavior: smooth;
-  width: 100%;
-  background-color: ${(p) => p.theme?.timelineBgColor || 'transparent'};
-  /* order: ${(p) => (p.position === 'top' ? 1 : 0)}; */
-  background: transparent;
-  F ${ScrollBar} &.horizontal {
-    min-height: 150px;
-  }
- 
-  padding: ${({ $scrollable }) => (!$scrollable ? '0 1rem 0' : '')};
-`;
- 
-export const TimelineMain = styled.div`
-  position: absolute;
-  top: 50%;
-  left: 0;
-  display: flex;
-  align-items: center;
-  transition: all 0.2s ease;
-  transform: translate(0, -50%);
- 
-  &.vertical {
-    align-items: flex-start;
-    justify-content: flex-start;
-    width: 100%;
-    height: 100%;
-  }
-`;
- 
-export const Outline = styled.div<{ color?: string; height?: number }>`
-  position: absolute;
-  right: 0;
-  left: 0;
-  width: 100%;
-  height: ${(p) => `${p.height}px`};
-  margin-right: auto;
-  margin-left: auto;
-  background: ${(p) => p.color};
-`;
- 
-export const TimelineControlContainer = styled.div<{
-  active?: boolean;
-  mode?: TimelineMode;
-}>`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  min-height: 3rem;
- 
-  filter: ${(p) => {
-    if (p.active) {
-      return `opacity(1);`;
-    } else {
-      return `opacity(0.9);`;
-    }
-  }};
- 
-  &.hide {
-    visibility: hidden;
-  }
- 
-  &.show {
-    visibility: visible;
-  }
-`;
- 
-export const TimelineContentRender = styled.div<{ $showAllCards?: boolean }>`
-  display: flex;
-  align-items: flex-start;
-  justify-content: ${(p) => (p.$showAllCards ? 'flex-start' : 'center')};
-  width: 98%;
-  margin-right: auto;
-  margin-left: auto;
-  overflow-x: hidden;
-`;
- 
-export const ToolbarWrapper = styled.div<{ position: 'top' | 'bottom' }>`
-  display: flex;
-  font-weight: bold;
-  text-align: center;
-  text-decoration: none;
-  border-radius: 6px;
-  width: 100%;
-  padding: 0;
-  margin: ${(p) => (p.position === 'top' ? '0 0 20px 0' : '20px 0 0 0')};
-  order: ${(p) => (p.position === 'top' ? 0 : 1)};
-  z-index: ${zIndex.controls - 1}; /* Below controls but above base timeline */
-  align-items: center;
-  justify-content: space-between;
-  gap: 1rem;
-`;
- 
-export const ExtraControls = styled.ul<{
-  $hide: boolean;
-  $slideShowRunning: boolean;
-}>`
-  display: flex;
-  align-items: center;
-  list-style: none;
-  margin: 0;
-  padding: 0.1rem;
-  visibility: ${(p) => (p.$hide ? 'hidden' : 'visible')};
-  flex-shrink: 0;
-`;
- 
-export const ExtraControlChild = styled.li`
-  display: flex;
-  margin: 0.5rem 0;
-  margin-right: 0.5rem;
-`;
- 
-export const SearchWrapper = styled.div<{ theme?: Theme }>`
-  display: flex;
-  align-items: center;
-  background-color: ${(p) => p.theme?.toolbarBtnBgColor};
-  padding: 0.1rem 0.5rem;
-  border-radius: 6px;
-  border: 1px solid ${(p) => p.theme?.buttonBorderColor};
-  flex-grow: 1;
-  max-width: 400px;
-  margin: 0 1rem;
-  transition:
-    border-color 0.2s ease,
-    box-shadow 0.2s ease;
- 
-  &:focus-within {
-    border-color: ${(p) => p.theme?.primary};
-    box-shadow: 0 0 0 2px ${(p) => p.theme?.glowColor};
-  }
-`;
- 
-export const SearchInput = styled.input<{ theme?: Theme }>`
-  flex-grow: 1;
-  border: none;
-  outline: none;
-  background: transparent;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  font-size: 0.9rem;
-  padding: 0.4rem 0.5rem;
- 
-  &::placeholder {
-    color: ${(p) => p.theme?.toolbarTextColor};
-    opacity: 0.6;
-  }
- 
-  &::-webkit-search-cancel-button {
-    appearance: none;
-    height: 10px;
-    width: 10px;
-    margin-left: 0.2rem;
-    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10" fill="%23${(
-      p,
-    ) =>
-      p.theme?.toolbarTextColor?.substring(
-        1,
-      )}"><path d=\"M.7.7l8.6 8.6M9.3.7L.7 9.3\" stroke=\"%23${(p) =>
-      p.theme?.toolbarTextColor?.substring(1)}\" stroke-width=\"1.5\"/></svg>');
-    cursor: pointer;
-    opacity: 0.6;
-    &:hover {
-      opacity: 1;
-    }
-  }
-`;
- 
-export const SearchInfo = styled.span<{ theme?: Theme }>`
-  font-size: 0.8rem;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  opacity: 0.8;
-  margin: 0 0.5rem;
-  white-space: nowrap;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/timeline.style.tsx.html b/coverage/components/timeline/timeline.style.tsx.html deleted file mode 100644 index 2ce4c2511..000000000 --- a/coverage/components/timeline/timeline.style.tsx.html +++ /dev/null @@ -1,580 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline.style.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline.style.tsx

-
- -
- 0% - Statements - 0/29 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/29 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import styled from 'styled-components';
-import { Theme } from '../../models/Theme';
-import { TimelineMode } from '../../models/TimelineModel';
- 
-export const Wrapper = styled.div<{
-  cardPositionHorizontal?: 'TOP' | 'BOTTOM';
-  theme?: Theme;
-}>`
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-  font-family: 'Roboto Condensed', sans-serif;
-  position: relative;
-  z-index: 0;
- 
-  &:focus-visible {
-    outline: 2px solid ${(p) => p.theme?.primary || '#0066cc'};
-    outline-offset: 2px;
-  }
- 
-  button:focus-visible,
-  a:focus-visible,
-  input:focus-visible {
-    outline: 2px solid ${(p) => p.theme?.primary || '#0066cc'};
-    outline-offset: 2px;
-    box-shadow: 0 0 0 4px rgba(0, 102, 204, 0.2);
-  }
- 
-  overflow: hidden;
-  &.horizontal {
-    justify-content: flex-start;
-  }
-`;
- 
-export const TimelineMainWrapper = styled.div<{
-  $scrollable?: boolean | { scrollbar: boolean };
-  mode?: TimelineMode;
-  position?: 'top' | 'bottom';
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  display: flex;
-  justify-content: center;
-  overflow-y: auto;
-  overflow-x: hidden;
-  overscroll-behavior: contain;
-  ${(p) => (p.mode === 'HORIZONTAL' ? 'position: relative' : '')};
-  scroll-behavior: smooth;
-  width: 100%;
-  background-color: ${(p) => p.theme?.timelineBgColor || 'transparent'};
-  padding: ${({ $scrollable }) => (!$scrollable ? '0 1rem 0' : '')};
-`;
- 
-export const TimelineContentRender = styled.div<{ $showAllCards?: boolean }>`
-  display: flex;
-  align-items: flex-start;
-  justify-content: ${(p) => (p.$showAllCards ? 'flex-start' : 'center')};
-  width: 98%;
-  margin-right: auto;
-  margin-left: auto;
-  overflow-x: hidden;
-`;
- 
-export const ToolbarWrapper = styled.div<{ position: 'top' | 'bottom' }>`
-  display: flex;
-  font-weight: bold;
-  text-align: center;
-  text-decoration: none;
-  border-radius: 6px;
-  width: 100%;
-  padding: 0;
-  margin: ${(p) => (p.position === 'top' ? '0 0 4px 0' : '4px 0 0 0')};
-  order: ${(p) => (p.position === 'top' ? 0 : 1)};
-  z-index: 1;
-  align-items: center;
-  justify-content: space-between;
-  gap: 1rem;
-`;
- 
-export const ExtraControls = styled.ul<{
-  $hide: boolean;
-  $slideShowRunning: boolean;
-}>`
-  display: flex;
-  align-items: center;
-  list-style: none;
-  margin: 0;
-  padding: 0.1rem;
-  visibility: ${(p) => (p.$hide ? 'hidden' : 'visible')};
-  flex-shrink: 0;
-`;
- 
-export const SearchWrapper = styled.div<{ theme?: Theme }>`
-  display: flex;
-  align-items: center;
-  background-color: ${(p) => p.theme?.toolbarBtnBgColor};
-  padding: 0.1rem 0.5rem;
-  border-radius: 6px;
-  border: 1px solid ${(p) => p.theme?.buttonBorderColor};
-  flex-grow: 1;
-  max-width: 400px;
-  margin: 0 1rem;
-  transition:
-    border-color 0.2s ease,
-    box-shadow 0.2s ease;
- 
-  &:focus-within {
-    border-color: ${(p) => p.theme?.primary};
-    box-shadow: 0 0 0 2px ${(p) => p.theme?.glowColor};
-  }
-`;
- 
-export const SearchInput = styled.input<{ theme?: Theme }>`
-  flex-grow: 1;
-  border: none;
-  outline: none;
-  background: transparent;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  font-size: 0.9rem;
-  padding: 0.4rem 0.5rem;
- 
-  &::placeholder {
-    color: ${(p) => p.theme?.toolbarTextColor};
-    opacity: 0.6;
-  }
-`;
- 
-export const SearchInfo = styled.span<{ theme?: Theme }>`
-  font-size: 0.8rem;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  opacity: 0.8;
-  margin: 0 0.5rem;
-  white-space: nowrap;
-`;
- 
-export const Outline = styled.div<{ color?: string; height?: number }>`
-  position: absolute;
-  right: 0;
-  left: 0;
-  width: 100%;
-  height: ${(p) => `${p.height}px`};
-  margin-right: auto;
-  margin-left: auto;
-  background: ${(p) => p.color};
-  z-index: 0;
-  border-radius: 4px;
-`;
- 
-export const TimelineMain = styled.div`
-  position: absolute;
-  top: 50%;
-  left: 0;
-  display: flex;
-  align-items: center;
-  transition: all 0.2s ease;
-  transform: translate(0, -50%);
- 
-  &.vertical {
-    align-items: flex-start;
-    justify-content: flex-start;
-    width: 100%;
-    height: 100%;
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/timeline/timeline.tsx.html b/coverage/components/timeline/timeline.tsx.html deleted file mode 100644 index b0ec916bb..000000000 --- a/coverage/components/timeline/timeline.tsx.html +++ /dev/null @@ -1,1147 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline.tsx

-
- -
- 91.98% - Statements - 264/287 -
- - -
- 50% - Branches - 12/24 -
- - -
- 66.66% - Functions - 2/3 -
- - -
- 91.98% - Lines - 264/287 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -  -1x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -  -  -8x -8x -8x -8x -  -  -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -  -  -8x -8x -6x -6x -6x -6x -8x -8x -  -8x -8x -8x -8x -  -  -8x -6x -  -6x -  -  -  -6x -8x -  -  -8x -8x -  -  -  -  -  -8x -8x -  -  -8x -6x -  -6x -  -  -  -6x -  -6x -6x -6x -6x -6x -6x -6x -6x -  -6x -1x -1x -1x -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -8x -6x -6x -  -6x -1x -6x -5x -5x -8x -  -  -8x -8x -8x -8x -8x -8x -8x -8x -  -  -  -  -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -  -  -  -  -  -  -  -  -  -  -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -  -8x -  -1x -  -1x - 
import { TimelineModel } from '@models/TimelineModel';
-import { getUniqueID } from '@utils/index';
-import cls from 'classnames';
-import React, { useEffect, useMemo, useState } from 'react';
-import { useStableContext, useDynamicContext } from '../contexts';
-import useNewScrollPosition from '../effects/useNewScrollPosition';
-import { useSlideshowProgress } from '../../hooks/useSlideshowProgress';
-import {
-  Wrapper,
-  TimelineMainWrapper,
-  TimelineContentRender,
-  ToolbarWrapper,
-} from './timeline.style';
-import { TimelineToolbar } from './timeline-toolbar';
-import { useTimelineSearch } from '../../hooks/useTimelineSearch';
-import { useTimelineNavigation } from '../../hooks/useTimelineNavigation';
-import { useTimelineMode } from '../../hooks/useTimelineMode';
-import { useTimelineScroll } from '../../hooks/useTimelineScroll';
-import { useTimelineMedia } from '../../hooks/useTimelineMedia';
-import TimelineView from './TimelineView';
- 
-// Disable TypeScript checking for the Timeline component
-// as we're addressing the type conflicts through our custom hooks
-const Timeline: React.FunctionComponent<TimelineModel> = (
-  props: TimelineModel,
-) => {
-  // de-structure the props
-  const {
-    activeTimelineItem,
-    contentDetailsChildren,
-    iconChildren,
-    items = [],
-    onFirst,
-    onLast,
-    onNext,
-    onPrevious,
-    onRestartSlideshow,
-    onTimelineUpdated,
-    onItemSelected,
-    onOutlineSelection,
-    slideShowEnabled,
-    slideShowRunning,
-    mode = 'HORIZONTAL',
-    nestedCardHeight,
-    isChild = false,
-    onPaused,
-    uniqueId,
-    noUniqueId,
-  } = props;
- 
-  const {
-    cardPositionHorizontal,
-    disableNavOnKey,
-    flipLayout,
-    itemWidth = 200,
-    lineWidth,
-    onScrollEnd,
-    scrollable = true,
-    toolbarPosition,
-    disableToolbar,
-    slideItemDuration = 2000,
-  } = useStableContext();
- 
-  const {
-    horizontalAll: showAllCardsHorizontal,
-    memoizedTheme: theme,
-    isDarkMode: darkMode,
-    toggleDarkMode,
-    updateHorizontalAllCards,
-    updateTextContentDensity,
-  } = useDynamicContext();
- 
-  const [newOffSet, setNewOffset] = useNewScrollPosition(mode, itemWidth);
-  const [hasFocus, setHasFocus] = useState(false);
- 
-  // Memoize ID generation to prevent unnecessary regeneration
-  const id = useMemo(
-    () => `react-chrono-timeline-${noUniqueId ? uniqueId : getUniqueID()}`,
-    [noUniqueId, uniqueId],
-  );
- 
-  // Use custom hooks
-  const { timelineMode, handleTimelineUpdate } = useTimelineMode({
-    initialMode: mode,
-    showAllCardsHorizontal,
-    updateHorizontalAllCards,
-  });
- 
-  const {
-    timelineMainRef,
-    horizontalContentRef,
-    handleScroll,
-    handleMainScroll,
-  } = useTimelineScroll({
-    mode,
-    onScrollEnd,
-    setNewOffset,
-  });
- 
-  const {
-    activeItemIndex,
-    handleTimelineItemClick,
-    handleTimelineItemElapsed,
-    handleNext,
-    handlePrevious,
-    handleFirst,
-    handleLast,
-    handleKeySelection,
-  } = useTimelineNavigation({
-    items,
-    mode: timelineMode,
-    timelineId: id,
-    hasFocus,
-    flipLayout,
-    slideShowRunning,
-    onTimelineUpdated,
-    onNext,
-    onPrevious,
-    onFirst,
-    onLast,
-  });
- 
-  const {
-    searchQuery,
-    searchResults,
-    currentMatchIndex,
-    searchInputRef,
-    handleSearchChange,
-    clearSearch,
-    handleNextMatch,
-    handlePreviousMatch,
-    handleSearchKeyDown,
-  } = useTimelineSearch({
-    items: items.map((item) => ({ ...item, wrapperId: id })),
-    onTimelineUpdated,
-    handleTimelineItemClick,
-  });
- 
-  // Overall slideshow progress hook
-  useSlideshowProgress({
-    slideShowRunning: slideShowRunning ?? false,
-    activeTimelineItem: activeTimelineItem ?? 0,
-    totalItems: items.length,
-    slideItemDuration,
-  });
- 
-  useTimelineMedia({
-    mode,
-    timelineMainRef,
-  });
- 
-  // Memoize classes and display flags
-  const wrapperClass = useMemo(
-    () =>
-      cls(mode.toLocaleLowerCase(), {
-        'focus-visible': !isChild,
-        'js-focus-visible': !isChild,
-      }),
-    [mode, isChild],
-  );
- 
-  const canShowToolbar = useMemo(
-    () => !disableToolbar && !isChild,
-    [isChild, disableToolbar],
-  );
- 
-  // Memoize scroll capability determination
-  const canScrollTimeline = useMemo(() => {
-    if (slideShowRunning) return false;
- 
-    if (typeof scrollable === 'boolean') {
-      return scrollable;
-    }
- 
-    return typeof scrollable === 'object' && scrollable.scrollbar;
-  }, [slideShowRunning, scrollable]);
- 
-  // Handle keyboard events
-  const handleKeyDown = React.useCallback(
-    (evt: React.KeyboardEvent<HTMLDivElement>) => {
-      if (!disableNavOnKey && !slideShowRunning) {
-        setHasFocus(true);
-        handleKeySelection(evt);
-      }
-    },
-    [disableNavOnKey, slideShowRunning, handleKeySelection],
-  );
- 
-  // Update active item information
-  useEffect(() => {
-    const activeItem = items[activeTimelineItem ?? 0];
- 
-    if (slideShowRunning) {
-      activeItemIndex.current = activeTimelineItem ?? 0;
-    }
- 
-    if (!items.length || !activeItem) return;
- 
-    const { title, cardTitle, cardSubtitle, cardDetailedText } = activeItem;
-    onItemSelected?.({
-      cardDetailedText,
-      cardSubtitle,
-      cardTitle,
-      index: activeItemIndex.current,
-      title,
-    });
- 
-    if (mode === 'HORIZONTAL') {
-      const card = horizontalContentRef.current?.querySelector(
-        `#timeline-card-${activeItem.id}`,
-      );
- 
-      const cardRect = card?.getBoundingClientRect();
-      const contentRect = horizontalContentRef.current?.getBoundingClientRect();
- 
-      if (cardRect && contentRect) {
-        const { width: cardWidth, left: cardLeft } = cardRect;
-        const { width: contentWidth, left: contentLeft } = contentRect;
- 
-        // Defer DOM manipulation to next tick
-        requestAnimationFrame(() => {
-          const ele = horizontalContentRef.current as HTMLElement;
-          if (!ele) return;
- 
-          ele.style.scrollBehavior = 'smooth';
-          ele.scrollLeft +=
-            cardLeft - contentLeft + cardWidth / 2 - contentWidth / 2;
-        });
-      }
-    }
-  }, [
-    activeTimelineItem,
-    items,
-    slideShowRunning,
-    mode,
-    onItemSelected,
-    activeItemIndex,
-    horizontalContentRef,
-  ]);
- 
-  // Update scroll position when offset changes
-  useEffect(() => {
-    const ele = timelineMainRef.current;
-    if (!ele) return;
- 
-    if (mode === 'HORIZONTAL') {
-      ele.scrollLeft = Math.max(newOffSet, 0);
-    } else {
-      ele.scrollTop = newOffSet;
-    }
-  }, [newOffSet, mode, timelineMainRef]);
- 
-  // Ensure all styled components are properly integrated
-  return (
-    <Wrapper
-      onKeyDown={handleKeyDown}
-      className={wrapperClass}
-      cardPositionHorizontal={cardPositionHorizontal}
-      theme={theme}
-      onMouseDown={() => setHasFocus(true)}
-      onKeyUp={(evt) => {
-        if (evt.key === 'Escape') {
-          onPaused?.();
-        }
-      }}
-    >
-      {canShowToolbar && (
-        <ToolbarWrapper position={toolbarPosition}>
-          <TimelineToolbar
-            activeTimelineItem={activeTimelineItem}
-            totalItems={items.length}
-            slideShowEnabled={slideShowEnabled}
-            slideShowRunning={slideShowRunning}
-            onFirst={handleFirst}
-            onLast={handleLast}
-            onNext={handleNext}
-            onPrevious={handlePrevious}
-            onRestartSlideshow={onRestartSlideshow}
-            darkMode={darkMode}
-            toggleDarkMode={toggleDarkMode}
-            onPaused={onPaused}
-            id={id}
-            flipLayout={flipLayout}
-            items={items}
-            onActivateTimelineItem={handleTimelineItemClick}
-            onUpdateTimelineMode={handleTimelineUpdate}
-            onUpdateTextContentDensity={updateTextContentDensity}
-            mode={timelineMode}
-            searchQuery={searchQuery}
-            onSearchChange={handleSearchChange}
-            onClearSearch={clearSearch}
-            onNextMatch={handleNextMatch}
-            onPreviousMatch={handlePreviousMatch}
-            totalMatches={searchResults.length}
-            currentMatchIndex={currentMatchIndex}
-            onSearchKeyDown={handleSearchKeyDown}
-            searchInputRef={searchInputRef}
-          />
-        </ToolbarWrapper>
-      )}
- 
-      {/* Overall slideshow progress bar - positioned below toolbar */}
-      {/* {slideShowRunning && showOverallSlideshowProgress && (
-        <SlideshowProgress
-          activeItemIndex={activeTimelineItem ?? 0}
-          totalItems={items.length}
-          isRunning={slideShowRunning}
-          slideItemDuration={slideItemDuration}
-          isPaused={isPaused}
-        />
-      )} */}
- 
-      <TimelineMainWrapper
-        ref={timelineMainRef}
-        $scrollable={canScrollTimeline}
-        className={`${mode.toLowerCase()} timeline-main-wrapper`}
-        id="timeline-main-wrapper"
-        data-testid="timeline-main-wrapper"
-        theme={theme}
-        mode={mode}
-        position={toolbarPosition}
-        onScroll={handleMainScroll}
-      >
-        <TimelineView
-          timelineMode={timelineMode}
-          activeTimelineItem={activeTimelineItem}
-          autoScroll={handleScroll}
-          contentDetailsChildren={contentDetailsChildren}
-          hasFocus={hasFocus}
-          iconChildren={iconChildren}
-          items={items}
-          handleTimelineItemClick={handleTimelineItemClick}
-          handleTimelineItemElapsed={handleTimelineItemElapsed}
-          slideShowRunning={slideShowRunning}
-          id={id}
-          theme={theme}
-          lineWidth={lineWidth}
-          onOutlineSelection={onOutlineSelection}
-          nestedCardHeight={nestedCardHeight}
-        />
-      </TimelineMainWrapper>
- 
-      <TimelineContentRender
-        id={id}
-        $showAllCards={showAllCardsHorizontal}
-        ref={horizontalContentRef}
-      />
-    </Wrapper>
-  );
-};
- 
-Timeline.displayName = 'Timeline';
- 
-export default React.memo(Timeline);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toggle-button/index.html b/coverage/components/toggle-button/index.html deleted file mode 100644 index 1d27dfca7..000000000 --- a/coverage/components/toggle-button/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/toggle-button - - - - - - - - - -
-
-

All files components/toggle-button

-
- -
- 0% - Statements - 0/20 -
- - -
- 0% - Branches - 0/2 -
- - -
- 0% - Functions - 0/2 -
- - -
- 0% - Lines - 0/20 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.tsx -
-
0%0/170%0/10%0/10%0/17
toggle-button.styles.ts -
-
0%0/30%0/10%0/10%0/3
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toggle-button/index.tsx.html b/coverage/components/toggle-button/index.tsx.html deleted file mode 100644 index f746cee9c..000000000 --- a/coverage/components/toggle-button/index.tsx.html +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - Code coverage report for components/toggle-button/index.tsx - - - - - - - - - -
-
-

All files / components/toggle-button index.tsx

-
- -
- 0% - Statements - 0/17 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/17 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { FunctionComponent, ReactNode, memo } from 'react';
-import { useUIState } from '../../hooks/useUIState';
-import { ButtonWrapper, ToggleSwitch } from './toggle-button.styles';
- 
-export interface ToggleButtonProps {
-  offIcon: ReactNode;
-  onIcon: ReactNode;
-  state: boolean;
-  onChange?: (state: boolean) => void;
-}
- 
-const ToggleButton: FunctionComponent<ToggleButtonProps> = memo(
-  ({ offIcon, onIcon, state, onChange }) => {
-    const { state: on, toggle } = useUIState(state ?? false);
- 
-    const handleToggle = () => {
-      toggle();
-      onChange?.(on);
-    };
- 
-    return (
-      <ButtonWrapper onClick={handleToggle}>
-        <ToggleSwitch>{on ? offIcon : onIcon}</ToggleSwitch>
-      </ButtonWrapper>
-    );
-  },
-);
- 
-ToggleButton.displayName = 'ToggleButton';
- 
-export { ToggleButton };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toggle-button/toggle-button.styles.ts.html b/coverage/components/toggle-button/toggle-button.styles.ts.html deleted file mode 100644 index 19dd45907..000000000 --- a/coverage/components/toggle-button/toggle-button.styles.ts.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - Code coverage report for components/toggle-button/toggle-button.styles.ts - - - - - - - - - -
-
-

All files / components/toggle-button toggle-button.styles.ts

-
- -
- 0% - Statements - 0/3 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/3 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6  -  -  -  -  - 
import styled from 'styled-components';
- 
-export const ButtonWrapper = styled.div``;
- 
-export const ToggleSwitch = styled.span``;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toolbar/__tests__/index.html b/coverage/components/toolbar/__tests__/index.html deleted file mode 100644 index c79cd8775..000000000 --- a/coverage/components/toolbar/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/toolbar/__tests__ - - - - - - - - - -
-
-

All files components/toolbar/__tests__

-
- -
- 100% - Statements - 41/41 -
- - -
- 100% - Branches - 4/4 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 41/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
toolbar.test.tsx -
-
100%41/41100%4/40%0/3100%41/41
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toolbar/__tests__/toolbar.test.tsx.html b/coverage/components/toolbar/__tests__/toolbar.test.tsx.html deleted file mode 100644 index d21214f31..000000000 --- a/coverage/components/toolbar/__tests__/toolbar.test.tsx.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - Code coverage report for components/toolbar/__tests__/toolbar.test.tsx - - - - - - - - - -
-
-

All files / components/toolbar/__tests__ toolbar.test.tsx

-
- -
- 100% - Statements - 41/41 -
- - -
- 100% - Branches - 4/4 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 41/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53  -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -2x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x - 
// Toolbar.test.tsx
- 
-import { render } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { ThemeProvider } from 'styled-components';
-import { Toolbar } from '../index';
-import { ToolbarItem } from '@models/ToolbarItem';
- 
-const items: ToolbarItem[] = [
-  { name: 'Item 1', onSelect: () => {}, id: '1' },
-  { name: 'Item 2', onSelect: () => {}, id: '2' },
-];
- 
-const theme = getDefaultThemeOrDark();
- 
-describe('Toolbar', () => {
-  it('renders toolbar items', () => {
-    const { getByText, baseElement } = render(
-      <ThemeProvider theme={theme}>
-        <Toolbar items={items} theme={theme}>
-          {items.map((item, index) => (
-            <div key={index}>{item.name}</div>
-          ))}
-        </Toolbar>
-      </ThemeProvider>,
-    );
- 
-    console.log(baseElement.innerHTML);
- 
-    expect(getByText(/Item 1/i)).toBeInTheDocument();
-    expect(getByText(/Item 2/i)).toBeInTheDocument();
-  });
- 
-  it('renders icons', () => {
-    const itemWithIcon = {
-      icon: <span>Icon</span>,
-      name: 'Icon Item',
-      id: '3',
-      onSelect: () => {},
-    };
- 
-    const { getByText } = render(
-      <ThemeProvider theme={theme}>
-        <Toolbar items={[itemWithIcon]} theme={theme}>
-          <div>Content</div>
-        </Toolbar>
-      </ThemeProvider>,
-    );
- 
-    expect(getByText(/Icon/i)).toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toolbar/index.html b/coverage/components/toolbar/index.html deleted file mode 100644 index a219354db..000000000 --- a/coverage/components/toolbar/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/toolbar - - - - - - - - - -
-
-

All files components/toolbar

-
- -
- 87.8% - Statements - 36/41 -
- - -
- 83.33% - Branches - 10/12 -
- - -
- 100% - Functions - 2/2 -
- - -
- 87.8% - Lines - 36/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.tsx -
-
82.14%23/2866.66%4/6100%0/082.14%23/28
toolbar.styles.ts -
-
100%13/13100%6/6100%2/2100%13/13
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toolbar/index.tsx.html b/coverage/components/toolbar/index.tsx.html deleted file mode 100644 index 683657944..000000000 --- a/coverage/components/toolbar/index.tsx.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - Code coverage report for components/toolbar/index.tsx - - - - - - - - - -
-
-

All files / components/toolbar index.tsx

-
- -
- 82.14% - Statements - 23/28 -
- - -
- 66.66% - Branches - 4/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 82.14% - Lines - 23/28 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -651x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -9x -  -  -  -9x -9x -9x -31x -  -  -  -  -31x -31x -31x -31x -31x -  -  -31x -31x -23x -  -31x -  -9x -9x -  -9x -1x -  -1x -  -  - 
import { FunctionComponent, memo } from 'react';
-import { jsx as _jsx } from 'react/jsx-runtime';
-import {
-  ContentWrapper,
-  IconWrapper,
-  ToolbarListItem,
-  ToolbarWrapper,
-} from './toolbar.styles';
-import { ToolbarProps } from '@models/ToolbarProps';
- 
-/**
- * @description A reusable toolbar component that renders a list of items with icons and content
- * @component
- * @param {Object} props - Component properties
- * @param {Array} props.items - Array of toolbar items to render
- * @param {ReactNode[]} props.children - Child elements to render within each toolbar item
- * @param {Theme} props.theme - Theme configuration for styling
- *
- * @example
- * ```tsx
- * <Toolbar
- *   items={[{ id: '1', label: 'Action', icon: <Icon /> }]}
- *   theme={theme}
- * >
- *   <Content />
- * </Toolbar>
- * ```
- */
-const Toolbar: FunctionComponent<ToolbarProps> = memo(
-  ({ items = [], children = [], theme }) => {
-    if (!items.length) {
-      return null;
-    }
- 
-    return (
-      <ToolbarWrapper theme={theme} role="toolbar">
-        {items.map(({ label, id, icon }, index) => {
-          if (!id) {
-            console.warn('Toolbar item is missing required id property');
-            return null;
-          }
- 
-          return (
-            <ToolbarListItem
-              aria-label={label}
-              key={id}
-              role="button"
-              // tabIndex={0}
-            >
-              {icon && <IconWrapper>{icon}</IconWrapper>}
-              {children[index] && (
-                <ContentWrapper>{children[index]}</ContentWrapper>
-              )}
-            </ToolbarListItem>
-          );
-        })}
-      </ToolbarWrapper>
-    );
-  },
-);
- 
-Toolbar.displayName = 'Toolbar';
- 
-export { Toolbar };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/components/toolbar/toolbar.styles.ts.html b/coverage/components/toolbar/toolbar.styles.ts.html deleted file mode 100644 index bcf8260cc..000000000 --- a/coverage/components/toolbar/toolbar.styles.ts.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - Code coverage report for components/toolbar/toolbar.styles.ts - - - - - - - - - -
-
-

All files / components/toolbar toolbar.styles.ts

-
- -
- 100% - Statements - 13/13 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 13/13 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48  -1x -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -1x -1x -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
- 
-// Base styles for flex containers - using memo to prevent recreation
-const flexContainer = css`
-  display: flex;
-  align-items: center;
-`;
- 
-// Use transform instead of box-shadow for better performance
-export const ToolbarWrapper = styled.div<{ theme: Theme }>`
-  ${flexContainer};
-  list-style: none;
-  margin: 0;
-  padding: 0.25rem;
-  background-color: ${({ theme }) => theme.toolbarBgColor};
-  transform: translateY(0);
-  filter: drop-shadow(
-    0 2px 4px ${({ theme }) => theme.shadowColor || 'rgba(0, 0, 0, 0.1)'}
-  );
-  width: 100%;
-  height: 100%;
-  border-radius: 6px;
-  flex-wrap: wrap;
-  will-change: transform;
-  border: ${({ theme }) =>
-    theme.buttonBorderColor ? `1px solid ${theme.buttonBorderColor}` : 'none'};
-`;
- 
-// Toolbar list item styles
-export const ToolbarListItem = styled.div`
-  padding: 0;
-  margin: 0 0.5rem;
-`;
- 
-// Icon wrapper styles
-export const IconWrapper = styled.span`
-  ${flexContainer};
-  justify-content: center;
-  width: 1rem;
-  height: 1rem;
-`;
- 
-// Content wrapper styles
-export const ContentWrapper = styled.span`
-  ${flexContainer};
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/favicon.png b/coverage/favicon.png deleted file mode 100644 index c1525b811a167671e9de1fa78aab9f5c0b61cef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> - - - - Code coverage report for hooks/__tests__ - - - - - - - - - -
-
-

All files hooks/__tests__

-
- -
- 99.17% - Statements - 1562/1575 -
- - -
- 99.66% - Branches - 301/302 -
- - -
- 100% - Functions - 7/7 -
- - -
- 99.17% - Lines - 1562/1575 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useBackground.test.ts -
-
100%54/54100%12/12100%1/1100%54/54
useCardSize.test.ts -
-
97.39%187/192100%23/23100%0/097.39%187/192
useEscapeKey.test.ts -
-
100%88/88100%25/25100%1/1100%88/88
useMediaState.test.ts -
-
100%91/91100%30/30100%0/0100%91/91
useOutsideClick.test.ts -
-
100%116/116100%20/20100%2/2100%116/116
useTimelineMedia.test.ts -
-
100%85/85100%15/15100%2/2100%85/85
useTimelineMode.test.ts -
-
100%101/101100%23/23100%0/0100%101/101
useTimelineNavigation.test.ts -
-
98.8%332/336100%58/58100%1/198.8%332/336
useTimelineScroll.test.ts -
-
100%152/152100%22/22100%0/0100%152/152
useTimelineSearch.test.ts -
-
100%219/219100%36/36100%0/0100%219/219
useUIState.test.ts -
-
100%48/48100%17/17100%0/0100%48/48
useWindowSize.test.ts -
-
95.69%89/9395.23%20/21100%0/095.69%89/93
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useBackground.test.ts.html b/coverage/hooks/__tests__/useBackground.test.ts.html deleted file mode 100644 index 35aa317f4..000000000 --- a/coverage/hooks/__tests__/useBackground.test.ts.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useBackground.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useBackground.test.ts

-
- -
- 100% - Statements - 54/54 -
- - -
- 100% - Branches - 12/12 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 54/54 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -691x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -4x -4x -1x -  -1x -4x -4x -1x -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { useBackground } from '../useBackground';
-import { hexToRGBA } from '../../utils';
- 
-// Mock the hexToRGBA function
-vi.mock('../../utils', () => {
-  return {
-    hexToRGBA: vi.fn(() => 'rgba(0,0,0,0.8)'),
-  };
-});
- 
-describe('useBackground', () => {
-  const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
- 
-  beforeEach(() => {
-    warnSpy.mockClear();
-    vi.mocked(hexToRGBA).mockClear();
-  });
- 
-  afterEach(() => {
-    warnSpy.mockReset();
-    vi.mocked(hexToRGBA).mockReset();
-  });
- 
-  it('returns empty string if no color is provided', () => {
-    const { result } = renderHook(() => useBackground());
-    expect(result.current).toBe('');
-    expect(hexToRGBA).not.toHaveBeenCalled();
-  });
- 
-  it('returns empty string and warns if color is invalid hex', () => {
-    // Mock NODE_ENV to be development for console warning
-    const originalEnv = process.env.NODE_ENV;
-    process.env.NODE_ENV = 'development';
-    
-    const { result } = renderHook(() => useBackground('not-a-hex'));
-    expect(result.current).toBe('');
-    expect(warnSpy).toHaveBeenCalledWith('Invalid hex color: not-a-hex');
-    expect(hexToRGBA).not.toHaveBeenCalled();
-    
-    // Restore original NODE_ENV
-    process.env.NODE_ENV = originalEnv;
-  });
- 
-  it('calls hexToRGBA and returns its value for valid hex', () => {
-    vi.mocked(hexToRGBA).mockReturnValue('rgba(255,255,255,0.8)');
-    const { result } = renderHook(() => useBackground('#ffffff'));
-    expect(hexToRGBA).toHaveBeenCalledWith('#ffffff', 0.8);
-    expect(result.current).toBe('rgba(255,255,255,0.8)');
-  });
- 
-  it('reacts to color and opacity changes', () => {
-    vi.mocked(hexToRGBA)
-      .mockReturnValueOnce('rgba(255,0,0,0.5)')
-      .mockReturnValueOnce('rgba(255,0,0,1)');
- 
-    const { result, rerender } = renderHook(
-      ({ color, opacity }) => useBackground(color, opacity),
-      {
-        initialProps: { color: '#ff0000', opacity: 0.5 },
-      },
-    );
-    expect(result.current).toBe('rgba(255,0,0,0.5)');
-    rerender({ color: '#ff0000', opacity: 1 });
-    expect(result.current).toBe('rgba(255,0,0,1)');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useCardSize.test.ts.html b/coverage/hooks/__tests__/useCardSize.test.ts.html deleted file mode 100644 index bdaa3cfda..000000000 --- a/coverage/hooks/__tests__/useCardSize.test.ts.html +++ /dev/null @@ -1,823 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useCardSize.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useCardSize.test.ts

-
- -
- 97.39% - Statements - 187/192 -
- - -
- 100% - Branches - 23/23 -
- - -
- 100% - Functions - 0/0 -
- - -
- 97.39% - Lines - 187/192 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -7x -7x -7x -7x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -  -1x -1x -  -  -  -  -  -1x -  -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -  -1x -1x -1x - 
// Mock ResizeObserver before tests
-const mockResizeObserver = vi.fn().mockImplementation((callback) => ({
-  observe: vi.fn(),
-  unobserve: vi.fn(),
-  disconnect: vi.fn(),
-}));
- 
-global.ResizeObserver = mockResizeObserver;
- 
-import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useCardSize } from '../useCardSize';
- 
-describe('useCardSize', () => {
-  const mockContainerRef = { current: null as HTMLElement | null };
-  const mockDetailsRef = { current: null as HTMLElement | null };
-  const mockSetStartWidth = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-    mockContainerRef.current = null;
-    mockDetailsRef.current = null;
-    mockResizeObserver.mockClear();
-  });
- 
-  it('should initialize with default values', () => {
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    expect(result.current.cardActualHeight).toBe(0);
-    expect(result.current.detailsHeight).toBe(0);
-    expect(result.current.textContentLarge).toBe(false);
-  });
- 
-  it('should update card size when node is provided', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 300,
-      offsetHeight: 250,
-      offsetTop: 50,
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    expect(mockSetStartWidth).toHaveBeenCalledWith(500);
-    expect(result.current.cardActualHeight).toBe(300);
-    expect(result.current.detailsHeight).toBe(250);
-  });
- 
-  it('should not update card size when node is null', () => {
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(null);
-    });
- 
-    expect(mockSetStartWidth).not.toHaveBeenCalled();
-    expect(result.current.cardActualHeight).toBe(0);
-    expect(result.current.detailsHeight).toBe(0);
-  });
- 
-  it('should detect large text content when content overflows', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 500, // Large scroll height
-      offsetHeight: 200, // Small visible height
-      offsetTop: 50,
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    expect(result.current.textContentLarge).toBe(true);
-  });
- 
-  it('should detect large text content when total height exceeds container', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 300,
-      offsetHeight: 250,
-      offsetTop: 200, // Large offset
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    expect(result.current.textContentLarge).toBe(true);
-  });
- 
-  it('should handle ResizeObserver updates', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 300,
-      offsetHeight: 250,
-      offsetTop: 50,
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    // Mock ResizeObserver callback
-    const resizeObserverCallback = vi.fn();
-    const mockResizeObserver = vi.fn().mockImplementation((callback) => {
-      resizeObserverCallback.mockImplementation(callback);
-      return {
-        observe: vi.fn(),
-        disconnect: vi.fn(),
-      };
-    });
- 
-    // Replace ResizeObserver with mock
-    const originalResizeObserver = window.ResizeObserver;
-    window.ResizeObserver = mockResizeObserver;
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    // Simulate resize
-    act(() => {
-      resizeObserverCallback([
-        {
-          target: mockNode,
-          contentRect: { width: 600 },
-        },
-      ]);
-    });
- 
-    // Restore ResizeObserver
-    window.ResizeObserver = originalResizeObserver;
- 
-    expect(result.current.cardActualHeight).toBe(300);
-    expect(result.current.detailsHeight).toBe(250);
-  });
- 
-  it('should cleanup ResizeObserver on unmount', () => {
-    const mockDisconnect = vi.fn();
-    const mockResizeObserver = vi.fn().mockImplementation(() => ({
-      observe: vi.fn(),
-      disconnect: mockDisconnect,
-    }));
- 
-    // Replace ResizeObserver with mock
-    const originalResizeObserver = window.ResizeObserver;
-    window.ResizeObserver = mockResizeObserver;
- 
-    const { unmount } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    unmount();
- 
-    // Restore ResizeObserver
-    window.ResizeObserver = originalResizeObserver;
- 
-    expect(mockDisconnect).toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useEscapeKey.test.ts.html b/coverage/hooks/__tests__/useEscapeKey.test.ts.html deleted file mode 100644 index 929745d90..000000000 --- a/coverage/hooks/__tests__/useEscapeKey.test.ts.html +++ /dev/null @@ -1,436 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useEscapeKey.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useEscapeKey.test.ts

-
- -
- 100% - Statements - 88/88 -
- - -
- 100% - Branches - 25/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 88/88 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -1181x -1x -1x -1x -  -1x -1x -  -1x -8x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, beforeEach, vi } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { act } from 'react-dom/test-utils';
-import useEscapeKey from '../useEscapeKey';
- 
-describe('useEscapeKey', () => {
-  let mockCallback: ReturnType<typeof vi.fn>;
- 
-  beforeEach(() => {
-    mockCallback = vi.fn();
-  });
- 
-  it('should call callback when Escape key is pressed', () => {
-    renderHook(() => useEscapeKey(mockCallback));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Escape', keyCode: 27 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when a different key is pressed', () => {
-    renderHook(() => useEscapeKey(mockCallback));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Enter', keyCode: 13 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should work with custom key option', () => {
-    renderHook(() => useEscapeKey(mockCallback, { key: 'Enter' }));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Enter', keyCode: 13 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should work with custom keyCode option', () => {
-    renderHook(() => useEscapeKey(mockCallback, { keyCode: 13 }));
- 
-    act(() => {
-      // Create event with keyCode for fallback testing
-      const event = new KeyboardEvent('keyup', { 
-        key: 'Enter', 
-      });
-      // Manually set keyCode for testing fallback behavior
-      Object.defineProperty(event, 'keyCode', { value: 13 });
-      Object.defineProperty(event, 'key', { value: undefined });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should work with keydown event type', () => {
-    renderHook(() => useEscapeKey(mockCallback, { eventType: 'keydown' }));
- 
-    act(() => {
-      const event = new KeyboardEvent('keydown', {
-        key: 'Escape',
-        keyCode: 27,
-      });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when disabled', () => {
-    renderHook(() => useEscapeKey(mockCallback, { enabled: false }));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Escape', keyCode: 27 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should update callback when it changes', () => {
-    const { rerender } = renderHook(({ callback }) => useEscapeKey(callback), {
-      initialProps: { callback: mockCallback },
-    });
- 
-    const newCallback = vi.fn();
-    rerender({ callback: newCallback });
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Escape', keyCode: 27 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-    expect(newCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should clean up event listener on unmount', () => {
-    const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
-    const { unmount } = renderHook(() => useEscapeKey(mockCallback));
- 
-    unmount();
- 
-    expect(removeEventListenerSpy).toHaveBeenCalledWith(
-      'keyup',
-      expect.any(Function),
-    );
-    removeEventListenerSpy.mockRestore();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useMediaState.test.ts.html b/coverage/hooks/__tests__/useMediaState.test.ts.html deleted file mode 100644 index 8e885bbaa..000000000 --- a/coverage/hooks/__tests__/useMediaState.test.ts.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useMediaState.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useMediaState.test.ts

-
- -
- 100% - Statements - 91/91 -
- - -
- 100% - Branches - 30/30 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 91/91 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -1141x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -9x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, beforeEach, vi } from 'vitest';
-import { renderHook, act } from '@testing-library/react';
-import { useMediaState } from '../useMediaState';
-import { MediaState } from '../../models/TimelineMediaModel';
- 
-describe('useMediaState', () => {
-  const mockOnElapsed = vi.fn();
-  const defaultProps = {
-    slideShowActive: true,
-    paused: false,
-    id: 'test-id',
-    onElapsed: mockOnElapsed,
-  };
- 
-  beforeEach(() => {
-    mockOnElapsed.mockClear();
-  });
- 
-  it('should initialize with isPlaying as false', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
-    expect(result.current.isPlaying).toBe(false);
-  });
- 
-  it('should update isPlaying state when handleMediaState is called with playing true', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(true);
-  });
- 
-  it('should update isPlaying state when handleMediaState is called with playing false', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(true);
- 
-    act(() => {
-      result.current.handleMediaState({ playing: false } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(false);
-  });
- 
-  it('should not update state when slideShowActive is false', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, slideShowActive: false }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(false);
-  });
- 
-  it('should call onElapsed when media is paused and paused prop is true', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, paused: true }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).toHaveBeenCalledWith('test-id');
-  });
- 
-  it('should not call onElapsed when media is paused but paused prop is false', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).not.toHaveBeenCalled();
-  });
- 
-  it('should not call onElapsed when id is not provided', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, id: undefined }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).not.toHaveBeenCalled();
-  });
- 
-  it('should not call onElapsed when onElapsed is not provided', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, onElapsed: undefined }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).not.toHaveBeenCalled();
-  });
- 
-  it('should set isPlaying to false when cleanup is called', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(true);
- 
-    act(() => {
-      result.current.cleanup();
-    });
-    expect(result.current.isPlaying).toBe(false);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useOutsideClick.test.ts.html b/coverage/hooks/__tests__/useOutsideClick.test.ts.html deleted file mode 100644 index 45a872ef9..000000000 --- a/coverage/hooks/__tests__/useOutsideClick.test.ts.html +++ /dev/null @@ -1,583 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useOutsideClick.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useOutsideClick.test.ts

-
- -
- 100% - Statements - 116/116 -
- - -
- 100% - Branches - 20/20 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 116/116 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -1671x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -  -9x -9x -  -  -9x -9x -  -  -9x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { createRef, RefObject } from 'react';
-import useOutsideClick from '../useOutsideClick';
- 
-describe('useOutsideClick', () => {
-  let mockCallback: ReturnType<typeof vi.fn>;
-  let elementRef: RefObject<HTMLDivElement | null>;
-  let mockElement: HTMLDivElement;
-  let mockOutsideElement: HTMLDivElement;
- 
-  beforeEach(() => {
-    // Setup mocks
-    mockCallback = vi.fn();
-    elementRef = createRef();
- 
-    // Create mock elements
-    mockElement = document.createElement('div');
-    mockOutsideElement = document.createElement('div');
- 
-    // Setup ref
-    elementRef.current = mockElement;
-  });
- 
-  it('should call callback when clicking outside element', () => {
-    renderHook(() => useOutsideClick(elementRef, mockCallback));
- 
-    // Simulate click outside
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when clicking inside element', () => {
-    renderHook(() => useOutsideClick(elementRef, mockCallback));
- 
-    // Simulate click inside
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should work with mousedown event type', () => {
-    renderHook(() =>
-      useOutsideClick(elementRef, mockCallback, { eventType: 'mousedown' }),
-    );
- 
-    // Simulate mousedown outside
-    const event = new MouseEvent('mousedown');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should work with touchstart event type', () => {
-    renderHook(() =>
-      useOutsideClick(elementRef, mockCallback, { eventType: 'touchstart' }),
-    );
- 
-    // Simulate touchstart outside
-    const event = new TouchEvent('touchstart');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when disabled', () => {
-    renderHook(() =>
-      useOutsideClick(elementRef, mockCallback, { enabled: false }),
-    );
- 
-    // Simulate click outside
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should update callback reference when callback changes', () => {
-    const { rerender } = renderHook(
-      ({ cb }) => useOutsideClick(elementRef, cb),
-      { initialProps: { cb: mockCallback } },
-    );
- 
-    // First click
-    const event1 = new MouseEvent('click');
-    Object.defineProperty(event1, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event1);
-    expect(mockCallback).toHaveBeenCalledTimes(1);
- 
-    // Change callback
-    const newCallback = vi.fn();
-    rerender({ cb: newCallback });
- 
-    // Second click should trigger new callback
-    const event2 = new MouseEvent('click');
-    Object.defineProperty(event2, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event2);
-    expect(newCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should cleanup event listener on unmount', () => {
-    const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
-    const { unmount } = renderHook(() =>
-      useOutsideClick(elementRef, mockCallback),
-    );
- 
-    unmount();
- 
-    expect(removeEventListenerSpy).toHaveBeenCalledWith(
-      'click',
-      expect.any(Function),
-    );
-    removeEventListenerSpy.mockRestore();
-  });
- 
-  it('should handle null ref correctly', () => {
-    const nullRef = createRef<HTMLElement>();
-    renderHook(() => useOutsideClick(nullRef, mockCallback));
- 
-    // Simulate click
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    // Should not throw and should NOT call callback since ref is null
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should remove and add listeners when enabled state changes', () => {
-    const addEventListenerSpy = vi.spyOn(document, 'addEventListener');
-    const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
- 
-    const { rerender } = renderHook(
-      ({ enabled }) => useOutsideClick(elementRef, mockCallback, { enabled }),
-      { initialProps: { enabled: true } },
-    );
- 
-    expect(addEventListenerSpy).toHaveBeenCalledWith(
-      'click',
-      expect.any(Function),
-      undefined, // The optimized hook passes undefined for click events
-    );
- 
-    // Disable
-    rerender({ enabled: false });
-    expect(removeEventListenerSpy).toHaveBeenCalledWith(
-      'click',
-      expect.any(Function),
-    );
- 
-    // Re-enable
-    rerender({ enabled: true });
-    expect(addEventListenerSpy).toHaveBeenCalledTimes(2);
- 
-    addEventListenerSpy.mockRestore();
-    removeEventListenerSpy.mockRestore();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useTimelineMedia.test.ts.html b/coverage/hooks/__tests__/useTimelineMedia.test.ts.html deleted file mode 100644 index 1e6d12860..000000000 --- a/coverage/hooks/__tests__/useTimelineMedia.test.ts.html +++ /dev/null @@ -1,427 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineMedia.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineMedia.test.ts

-
- -
- 100% - Statements - 85/85 -
- - -
- 100% - Branches - 15/15 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 85/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -1151x -1x -1x -  -  -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -  -1x -3x -3x -3x -3x -3x -3x -  -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -  -4x -4x -  -4x -4x -  -4x -4x -4x -4x -4x -4x -4x -  -4x -4x -4x -1x -  -1x -4x -4x -4x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { useTimelineMedia } from '../useTimelineMedia';
- 
-// Mock utility functions
-vi.mock('../../utils/timelineUtils', () => ({
-  toggleMediaVisibility: vi.fn(),
-  pauseVideoEmbeds: vi.fn(),
-}));
-import {
-  toggleMediaVisibility,
-  pauseVideoEmbeds,
-} from '../../utils/timelineUtils';
- 
-// Mock IntersectionObserver
-const observeSpy = vi.fn();
-const disconnectSpy = vi.fn();
-let intersectionCallback: (entries: any[]) => void;
- 
-class MockIntersectionObserver {
-  observe = observeSpy;
-  disconnect = disconnectSpy;
-  constructor(callback: (entries: any[]) => void) {
-    intersectionCallback = callback;
-  }
-}
- 
-// Mock requestAnimationFrame
-const rafSpy = vi.fn((cb) => cb());
- 
-describe('useTimelineMedia', () => {
-  let originalIntersectionObserver: any;
-  let originalRAF: any;
-  let timelineMainRef: any;
-  let verticalItem1: HTMLDivElement;
-  let verticalItem2: HTMLDivElement;
- 
-  beforeEach(() => {
-    // Save originals
-    originalIntersectionObserver = global.IntersectionObserver;
-    originalRAF = global.requestAnimationFrame;
-    // Mock
-    global.IntersectionObserver = MockIntersectionObserver as any;
-    global.requestAnimationFrame = rafSpy;
-    // Setup DOM
-    timelineMainRef = { current: document.createElement('div') };
-    verticalItem1 = document.createElement('div');
-    verticalItem2 = document.createElement('div');
-    verticalItem1.className = 'vertical-item-row';
-    verticalItem2.className = 'vertical-item-row';
-    timelineMainRef.current.appendChild(verticalItem1);
-    timelineMainRef.current.appendChild(verticalItem2);
-    // Clear mocks
-    vi.clearAllMocks();
-    observeSpy.mockClear();
-    disconnectSpy.mockClear();
-  });
- 
-  afterEach(() => {
-    global.IntersectionObserver = originalIntersectionObserver;
-    global.requestAnimationFrame = originalRAF;
-    vi.clearAllMocks();
-  });
- 
-  it('does not create observer if mode is HORIZONTAL', () => {
-    renderHook(() => useTimelineMedia({ mode: 'HORIZONTAL', timelineMainRef }));
-    expect(intersectionCallback).toBeUndefined();
-    expect(rafSpy).not.toHaveBeenCalled();
-  });
- 
-  it('creates observer and observes vertical-item-row children if mode is not HORIZONTAL', () => {
-    renderHook(() => useTimelineMedia({ mode: 'VERTICAL', timelineMainRef }));
-    expect(intersectionCallback).toBeTypeOf('function');
-    expect(rafSpy).toHaveBeenCalled();
-    expect(observeSpy).toHaveBeenCalledTimes(2);
-    expect(observeSpy).toHaveBeenCalledWith(verticalItem1);
-    expect(observeSpy).toHaveBeenCalledWith(verticalItem2);
-  });
- 
-  it('disconnects observer on unmount', () => {
-    const { unmount } = renderHook(() =>
-      useTimelineMedia({ mode: 'VERTICAL', timelineMainRef }),
-    );
-    unmount();
-    expect(disconnectSpy).toHaveBeenCalled();
-  });
- 
-  it('handles intersection changes correctly', () => {
-    renderHook(() => useTimelineMedia({ mode: 'VERTICAL', timelineMainRef }));
- 
-    // First simulate both items becoming visible
-    intersectionCallback([
-      { target: verticalItem1, isIntersecting: true },
-      { target: verticalItem2, isIntersecting: true },
-    ]);
- 
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem1, true);
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem2, true);
- 
-    // Clear the mocks for the next test
-    vi.clearAllMocks();
- 
-    // Then simulate items going out of view
-    intersectionCallback([
-      { target: verticalItem1, isIntersecting: false },
-      { target: verticalItem2, isIntersecting: false },
-    ]);
- 
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem1, false);
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem2, false);
-    expect(pauseVideoEmbeds).toHaveBeenCalledWith(verticalItem1);
-    expect(pauseVideoEmbeds).toHaveBeenCalledWith(verticalItem2);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useTimelineMode.test.ts.html b/coverage/hooks/__tests__/useTimelineMode.test.ts.html deleted file mode 100644 index 15444a031..000000000 --- a/coverage/hooks/__tests__/useTimelineMode.test.ts.html +++ /dev/null @@ -1,466 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineMode.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineMode.test.ts

-
- -
- 100% - Statements - 101/101 -
- - -
- 100% - Branches - 23/23 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 101/101 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -1281x -1x -1x -  -1x -1x -  -1x -7x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -3x -3x -3x -1x -  -1x -1x -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -4x -4x -4x -4x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -4x -4x -4x -  -4x -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineMode } from '../useTimelineMode';
- 
-describe('useTimelineMode', () => {
-  const mockUpdateHorizontalAllCards = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  it('should initialize with the provided mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-      }),
-    );
- 
-    expect(result.current.timelineMode).toBe('VERTICAL');
-  });
- 
-  it('should initialize with HORIZONTAL_ALL when showAllCardsHorizontal is true', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'HORIZONTAL',
-        showAllCardsHorizontal: true,
-      }),
-    );
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL_ALL');
-  });
- 
-  it('should handle mode updates', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-        updateHorizontalAllCards: mockUpdateHorizontalAllCards,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL');
-    expect(mockUpdateHorizontalAllCards).toHaveBeenCalledWith(false);
- 
-    act(() => {
-      result.current.handleTimelineUpdate('VERTICAL_ALTERNATING');
-    });
- 
-    expect(result.current.timelineMode).toBe('VERTICAL_ALTERNATING');
-  });
- 
-  it('should handle HORIZONTAL_ALL mode update', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'HORIZONTAL',
-        updateHorizontalAllCards: mockUpdateHorizontalAllCards,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL_ALL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL_ALL');
-    expect(mockUpdateHorizontalAllCards).toHaveBeenCalledWith(true);
-  });
- 
-  it('should maintain state between renders', () => {
-    const { result, rerender } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL');
- 
-    rerender();
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL');
-  });
- 
-  it('should not call updateHorizontalAllCards when not provided', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'HORIZONTAL',
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL_ALL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL_ALL');
-    expect(mockUpdateHorizontalAllCards).not.toHaveBeenCalled();
-  });
- 
-  it('should handle all valid mode transitions', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-        updateHorizontalAllCards: mockUpdateHorizontalAllCards,
-      }),
-    );
- 
-    const modes = [
-      'VERTICAL',
-      'HORIZONTAL',
-      'VERTICAL_ALTERNATING',
-      'HORIZONTAL_ALL',
-    ];
- 
-    modes.forEach((mode) => {
-      act(() => {
-        result.current.handleTimelineUpdate(mode);
-      });
- 
-      expect(result.current.timelineMode).toBe(mode);
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useTimelineNavigation.test.ts.html b/coverage/hooks/__tests__/useTimelineNavigation.test.ts.html deleted file mode 100644 index 93431a49e..000000000 --- a/coverage/hooks/__tests__/useTimelineNavigation.test.ts.html +++ /dev/null @@ -1,1369 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineNavigation.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineNavigation.test.ts

-
- -
- 98.8% - Statements - 332/336 -
- - -
- 100% - Branches - 58/58 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.8% - Lines - 332/336 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -4291x -1x -1x -  -  -1x -  -  -  -1x -  -  -1x -9x -9x -9x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -15x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -  -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -  -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineNavigation } from '../useTimelineNavigation';
- 
-// Mock the findTimelineElement utility
-vi.mock('../utils/timelineUtils', () => ({
-  findTimelineElement: vi.fn(() => ({
-    scrollIntoView: vi.fn(),
-  })),
-}));
- 
-// Helper function to create mock keyboard events
-const createMockKeyboardEvent = (key: string): React.KeyboardEvent<HTMLDivElement> => ({
-  key,
-  preventDefault: vi.fn(),
-} as unknown as React.KeyboardEvent<HTMLDivElement>);
- 
-describe('useTimelineNavigation', () => {
-  const mockItems = [
-    { id: '1', title: 'First Item' },
-    { id: '2', title: 'Second Item' },
-    { id: '3', title: 'Third Item' },
-  ];
- 
-  const mockOnTimelineUpdated = vi.fn();
-  const mockOnNext = vi.fn();
-  const mockOnPrevious = vi.fn();
-  const mockOnFirst = vi.fn();
-  const mockOnLast = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  it('should initialize with correct state', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-        onFirst: mockOnFirst,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-  });
- 
-  it('should handle timeline item click', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-  });
- 
-  it('should handle timeline item elapsed', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemElapsed('2');
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(2); // isSlideShow is true
-  });
- 
-  it('should handle next navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onNext: mockOnNext,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleNext();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
-  });
- 
-  it('should handle previous navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onPrevious: mockOnPrevious,
-      }),
-    );
- 
-    // First move to the second item
-    act(() => {
-      result.current.handleNext();
-    });
- 
-    // Then move back
-    act(() => {
-      result.current.handlePrevious();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
-  });
- 
-  it('should handle first navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onFirst: mockOnFirst,
-      }),
-    );
- 
-    // First move to the last item
-    act(() => {
-      result.current.handleLast();
-    });
- 
-    // Then move to first
-    act(() => {
-      result.current.handleFirst();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnFirst).toHaveBeenCalled();
-  });
- 
-  it('should handle last navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleLast();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(2);
-    expect(mockOnLast).toHaveBeenCalled();
-  });
- 
-  it('should handle keyboard navigation in vertical mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-        onFirst: mockOnFirst,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    // Test arrow down
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowDown'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
- 
-    // Test arrow up
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowUp'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
- 
-    // Move to a different position first, then test Home key
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowDown'));
-    });
-    
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('Home'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnFirst).toHaveBeenCalled();
- 
-    // Test End key
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('End'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(mockItems.length - 1);
-    expect(mockOnLast).toHaveBeenCalled();
-  });
- 
-  it('should handle keyboard navigation in horizontal mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-      }),
-    );
- 
-    // Test arrow right
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowRight'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
- 
-    // Test arrow left
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowLeft'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
-  });
- 
-  it('should handle flipped layout in horizontal mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        flipLayout: true,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-      }),
-    );
- 
-    // Move to index 1 first to enable testing both directions
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowLeft'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
- 
-    // Test arrow right (should go previous in flipped layout)
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowRight'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
-  });
- 
-  it('should not handle navigation when hasFocus is false', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: false,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-        onFirst: mockOnFirst,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleNext();
-      result.current.handlePrevious();
-      result.current.handleFirst();
-      result.current.handleLast();
-    });
- 
-    expect(mockOnNext).not.toHaveBeenCalled();
-    expect(mockOnPrevious).not.toHaveBeenCalled();
-    expect(mockOnFirst).not.toHaveBeenCalled();
-    expect(mockOnLast).not.toHaveBeenCalled();
-  });
- 
-  it('should not handle invalid item clicks', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('invalid-id');
-    });
- 
-    expect(mockOnTimelineUpdated).not.toHaveBeenCalled();
-  });
- 
-  it('should disable card alignment scrolling in horizontal mode when slideshow is running', () => {
-    const mockScrollIntoView = vi.fn();
-    
-    // Mock document.getElementById to return an element with scrollIntoView method
-    const originalGetElementById = document.getElementById;
-    document.getElementById = vi.fn(() => ({
-      scrollIntoView: mockScrollIntoView,
-    })) as any;
- 
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        slideShowRunning: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    // Should update timeline position but not call scrollIntoView when slideshow is running
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockScrollIntoView).not.toHaveBeenCalled();
- 
-    // Restore original function
-    document.getElementById = originalGetElementById;
-  });
- 
-  it('should allow card alignment scrolling in horizontal mode when slideshow is not running', async () => {
-    const mockScrollIntoView = vi.fn();
-    
-    // Mock document.getElementById to return an element with scrollIntoView method and closest method
-    const originalGetElementById = document.getElementById;
-    document.getElementById = vi.fn(() => ({
-      scrollIntoView: mockScrollIntoView,
-      closest: vi.fn(() => null), // Mock closest method
-      parentElement: null,
-    })) as any;
- 
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        slideShowRunning: false,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    // Wait for requestAnimationFrame to complete
-    await act(async () => {
-      await new Promise(resolve => requestAnimationFrame(resolve));
-    });
- 
-    // Should update timeline position and call scrollIntoView when slideshow is not running
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockScrollIntoView).toHaveBeenCalled();
- 
-    // Restore original function
-    document.getElementById = originalGetElementById;
-  });
- 
-  it('should allow card alignment scrolling in vertical mode even when slideshow is running', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        slideShowRunning: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    // Should update timeline position and the mocked scrollIntoView should be called
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    // In vertical mode, slideshow running should not affect scrolling behavior
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useTimelineScroll.test.ts.html b/coverage/hooks/__tests__/useTimelineScroll.test.ts.html deleted file mode 100644 index 53a39b0d4..000000000 --- a/coverage/hooks/__tests__/useTimelineScroll.test.ts.html +++ /dev/null @@ -1,688 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineScroll.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineScroll.test.ts

-
- -
- 100% - Statements - 152/152 -
- - -
- 100% - Branches - 22/22 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 152/152 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -2021x -1x -1x -  -1x -1x -1x -  -1x -5x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -  -  -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineScroll } from '../useTimelineScroll';
- 
-describe('useTimelineScroll', () => {
-  const mockSetNewOffset = vi.fn();
-  const mockOnScrollEnd = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  it('should initialize with correct refs', () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-      }),
-    );
- 
-    expect(result.current.timelineMainRef.current).toBeNull();
-    expect(result.current.horizontalContentRef.current).toBeNull();
-  });
- 
-  it('should handle scroll in vertical mode', async () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-        onScrollEnd: mockOnScrollEnd,
-      }),
-    );
- 
-    // Test scroll offset update
-    const mockElement = document.createElement('div');
- 
-    // Set necessary properties for scroll calculations
-    Object.defineProperties(mockElement, {
-      scrollTop: { value: 100, configurable: true, writable: true },
-      clientHeight: { value: 500, configurable: true, writable: true },
-      scrollHeight: { value: 1000, configurable: true, writable: true },
-    });
- 
-    // Set the ref
-    result.current.timelineMainRef.current = mockElement;
- 
-    // Test handleScroll
-    act(() => {
-      result.current.handleScroll({ scrollTop: 200 });
-    });
- 
-    // Verify setNewOffset was called
-    expect(mockSetNewOffset).toHaveBeenCalledWith(mockElement, {
-      scrollTop: 200,
-    });
- 
-    // IMPORTANT: Reset mocks before testing onScrollEnd
-    vi.clearAllMocks();
- 
-    // Change scroll position to exactly trigger the end condition
-    // For onScrollEnd to trigger: scrollTop + clientHeight must be very close to scrollHeight
-    mockElement.scrollTop = 499.5; // With clientHeight 500, this gives 999.5, which is within 1 of scrollHeight 1000
- 
-    // Trigger scroll event that should call onScrollEnd
-    act(() => {
-      result.current.handleMainScroll({
-        target: mockElement,
-        currentTarget: mockElement,
-        type: 'scroll',
-      } as unknown as React.UIEvent<HTMLDivElement>);
-    });
- 
-    // Wait for the throttled callback (100ms timeout)
-    await act(async () => {
-      await new Promise(resolve => setTimeout(resolve, 150));
-    });
- 
-    // Verify onScrollEnd was called
-    expect(mockOnScrollEnd).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should handle scroll in horizontal mode', async () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'HORIZONTAL',
-        setNewOffset: mockSetNewOffset,
-        onScrollEnd: mockOnScrollEnd,
-      }),
-    );
- 
-    // Mock the ref element
-    const mockElement = {
-      scrollLeft: 100,
-      offsetWidth: 500,
-      scrollWidth: 1000,
-    } as HTMLDivElement;
- 
-    result.current.timelineMainRef.current = mockElement;
- 
-    act(() => {
-      result.current.handleMainScroll({
-        target: mockElement,
-        currentTarget: mockElement,
-        nativeEvent: new Event('scroll'),
-        detail: 0,
-        view: window,
-        bubbles: true,
-        cancelable: true,
-        defaultPrevented: false,
-        eventPhase: 0,
-        isTrusted: true,
-        timeStamp: Date.now(),
-        type: 'scroll',
-        isDefaultPrevented: vi.fn(),
-        isPropagationStopped: vi.fn(),
-        stopPropagation: vi.fn(),
-        preventDefault: vi.fn(),
-        persist: vi.fn(),
-      } as unknown as React.UIEvent<HTMLDivElement>);
-    });
- 
-    // Should not trigger onScrollEnd as we haven't reached the end
-    expect(mockOnScrollEnd).not.toHaveBeenCalled();
- 
-    // Mock reaching the end of scroll
-    Object.defineProperty(mockElement, 'scrollLeft', { value: 500 });
-    Object.defineProperty(mockElement, 'offsetWidth', { value: 500 });
-    Object.defineProperty(mockElement, 'scrollWidth', { value: 1000 });
- 
-    act(() => {
-      result.current.handleMainScroll({
-        target: mockElement,
-        currentTarget: mockElement,
-        nativeEvent: new Event('scroll'),
-        detail: 0,
-        view: window,
-        bubbles: true,
-        cancelable: true,
-        defaultPrevented: false,
-        eventPhase: 0,
-        isTrusted: true,
-        timeStamp: Date.now(),
-        type: 'scroll',
-        isDefaultPrevented: vi.fn(),
-        isPropagationStopped: vi.fn(),
-        stopPropagation: vi.fn(),
-        preventDefault: vi.fn(),
-        persist: vi.fn(),
-      } as unknown as React.UIEvent<HTMLDivElement>);
-    });
- 
-    // Wait for the throttled callback (100ms timeout)
-    await act(async () => {
-      await new Promise(resolve => setTimeout(resolve, 150));
-    });
- 
-    // Should trigger onScrollEnd when reaching the end
-    expect(mockOnScrollEnd).toHaveBeenCalled();
-  });
- 
-  it('should handle scroll with setNewOffset', () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-      }),
-    );
- 
-    // Mock the ref element
-    const mockElement = {
-      scrollTop: 100,
-      clientHeight: 500,
-      scrollHeight: 1000,
-    } as HTMLDivElement;
- 
-    result.current.timelineMainRef.current = mockElement;
- 
-    act(() => {
-      result.current.handleScroll({ scrollTop: 200 });
-    });
- 
-    expect(mockSetNewOffset).toHaveBeenCalledWith(mockElement, {
-      scrollTop: 200,
-    });
-  });
- 
-  it('should not call setNewOffset when element is null', () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleScroll({ scrollTop: 200 });
-    });
- 
-    expect(mockSetNewOffset).not.toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useTimelineSearch.test.ts.html b/coverage/hooks/__tests__/useTimelineSearch.test.ts.html deleted file mode 100644 index 0cf1c4872..000000000 --- a/coverage/hooks/__tests__/useTimelineSearch.test.ts.html +++ /dev/null @@ -1,904 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineSearch.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineSearch.test.ts

-
- -
- 100% - Statements - 219/219 -
- - -
- 100% - Branches - 36/36 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 219/219 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -2741x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -8x -8x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -3x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -3x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -5x -5x -5x -5x -5x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -4x -4x -4x -4x -4x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -3x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -4x -4x -4x -4x -4x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineSearch } from '../useTimelineSearch';
- 
-describe('useTimelineSearch', () => {
-  const mockItems = [
-    {
-      id: '1',
-      title: 'First Item',
-      cardTitle: 'Card Title 1',
-      cardSubtitle: 'Subtitle 1',
-      cardDetailedText: 'Detailed text 1',
-    },
-    {
-      id: '2',
-      title: 'Second Item',
-      cardTitle: 'Card Title 2',
-      cardSubtitle: 'Subtitle 2',
-      cardDetailedText: 'Detailed text 2',
-    },
-    {
-      id: '3',
-      title: 'Third Item',
-      cardTitle: 'Card Title 3',
-      cardSubtitle: 'Subtitle 3',
-      cardDetailedText: 'Detailed text 3',
-    },
-  ];
- 
-  const mockOnTimelineUpdated = vi.fn();
-  const mockHandleTimelineItemClick = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-    vi.useFakeTimers();
-  });
- 
-  it('should initialize with empty search state', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    expect(result.current.searchQuery).toBe('');
-    expect(result.current.searchResults).toEqual([]);
-    expect(result.current.currentMatchIndex).toBe(-1);
-  });
- 
-  it('should find matches in searchable text', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('Title 1');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0]);
-    expect(result.current.currentMatchIndex).toBe(0);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(0);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('1');
-  });
- 
-  it('should handle case-insensitive search', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('title 1');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0]);
-    expect(result.current.currentMatchIndex).toBe(0);
-  });
- 
-  it('should navigate between matches', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    // Search for "Title" which appears in all items
-    act(() => {
-      result.current.handleSearchChange('Title');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0, 1, 2]);
-    expect(result.current.currentMatchIndex).toBe(0);
- 
-    // Navigate to next match
-    act(() => {
-      result.current.handleNextMatch();
-    });
- 
-    expect(result.current.currentMatchIndex).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('2');
- 
-    // Navigate to previous match
-    act(() => {
-      result.current.handlePreviousMatch();
-    });
- 
-    expect(result.current.currentMatchIndex).toBe(0);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(0);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('1');
-  });
- 
-  it('should clear search results', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    // First perform a search
-    act(() => {
-      result.current.handleSearchChange('Title');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    // Then clear the search
-    act(() => {
-      result.current.clearSearch();
-    });
- 
-    expect(result.current.searchQuery).toBe('');
-    expect(result.current.searchResults).toEqual([]);
-    expect(result.current.currentMatchIndex).toBe(-1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(0);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('1');
-  });
- 
-  it('should handle empty search query', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([]);
-    expect(result.current.currentMatchIndex).toBe(-1);
-  });
- 
-  it('should handle search in array of detailed text', () => {
-    const itemsWithArrayText = [
-      {
-        ...mockItems[0],
-        cardDetailedText: ['First line', 'Second line'],
-      },
-    ];
- 
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: itemsWithArrayText,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('Second line');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0]);
-    expect(result.current.currentMatchIndex).toBe(0);
-  });
- 
-  it('should handle keyboard navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    // First perform a search
-    act(() => {
-      result.current.handleSearchChange('Title');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    // Simulate Enter key press
-    act(() => {
-      result.current.handleSearchKeyDown({
-        key: 'Enter',
-        preventDefault: vi.fn(),
-        altKey: false,
-        charCode: 0,
-        ctrlKey: false,
-        code: 'Enter',
-        keyCode: 13,
-        metaKey: false,
-        shiftKey: false,
-        getModifierState: vi.fn(),
-        nativeEvent: new KeyboardEvent('keydown'),
-        currentTarget: document.createElement('input'),
-        target: document.createElement('input'),
-        bubbles: true,
-        cancelable: true,
-        defaultPrevented: false,
-        eventPhase: 0,
-        isTrusted: true,
-        timeStamp: Date.now(),
-        type: 'keydown',
-        isDefaultPrevented: vi.fn(),
-        isPropagationStopped: vi.fn(),
-        stopPropagation: vi.fn(),
-      } as unknown as React.KeyboardEvent);
-    });
- 
-    expect(result.current.currentMatchIndex).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('2');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useUIState.test.ts.html b/coverage/hooks/__tests__/useUIState.test.ts.html deleted file mode 100644 index 94a7ded6b..000000000 --- a/coverage/hooks/__tests__/useUIState.test.ts.html +++ /dev/null @@ -1,286 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useUIState.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useUIState.test.ts

-
- -
- 100% - Statements - 48/48 -
- - -
- 100% - Branches - 17/17 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 48/48 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -681x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -  -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it } from 'vitest';
-import { useUIState } from '../useUIState';
- 
-describe('useUIState', () => {
-  it('should initialize with the provided state', () => {
-    const { result } = renderHook(() => useUIState<boolean>(true));
- 
-    expect(result.current.state).toBe(true);
-  });
- 
-  it('should toggle boolean state', () => {
-    const { result } = renderHook(() => useUIState<boolean>(true));
- 
-    act(() => {
-      result.current.toggle();
-    });
- 
-    expect(result.current.state).toBe(false);
- 
-    act(() => {
-      result.current.toggle();
-    });
- 
-    expect(result.current.state).toBe(true);
-  });
- 
-  it('should set state to a specific value', () => {
-    const { result } = renderHook(() => useUIState<boolean>(true));
- 
-    act(() => {
-      result.current.setState(false);
-    });
- 
-    expect(result.current.state).toBe(false);
- 
-    act(() => {
-      result.current.setState(true);
-    });
- 
-    expect(result.current.state).toBe(true);
-  });
- 
-  it('should work with different initial states', () => {
-    const { result: resultTrue } = renderHook(() => useUIState<boolean>(true));
-    const { result: resultFalse } = renderHook(() =>
-      useUIState<boolean>(false),
-    );
- 
-    expect(resultTrue.current.state).toBe(true);
-    expect(resultFalse.current.state).toBe(false);
-  });
- 
-  it('should maintain state between renders', () => {
-    const { result, rerender } = renderHook(() => useUIState<boolean>(true));
- 
-    act(() => {
-      result.current.toggle();
-    });
- 
-    expect(result.current.state).toBe(false);
- 
-    rerender();
- 
-    expect(result.current.state).toBe(false);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/__tests__/useWindowSize.test.ts.html b/coverage/hooks/__tests__/useWindowSize.test.ts.html deleted file mode 100644 index a8b676027..000000000 --- a/coverage/hooks/__tests__/useWindowSize.test.ts.html +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useWindowSize.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useWindowSize.test.ts

-
- -
- 95.69% - Statements - 89/93 -
- - -
- 95.23% - Branches - 20/21 -
- - -
- 100% - Functions - 0/0 -
- - -
- 95.69% - Lines - 89/93 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -  -1x -1x -1x -  -1x -1x -  -1x -5x -  -5x -  -5x -5x -  -  -5x -5x -5x -5x -1x -  -1x -5x -  -5x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -  -  -1x -  -1x -1x -  -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x - 
// Mock window before importing the hook
-const mockWindow = {
-  innerWidth: 1024,
-  innerHeight: 768,
-  addEventListener: vi.fn(),
-  removeEventListener: vi.fn(),
-  dispatchEvent: vi.fn(),
-  setTimeout: vi.fn(),
-  clearTimeout: vi.fn(),
-  requestAnimationFrame: vi.fn(),
-  cancelAnimationFrame: vi.fn(),
-};
- 
-// Set up global window for SSR test
-if (typeof window === 'undefined') {
-  global.window = mockWindow as any;
-}
- 
-import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
-import { useWindowSize } from '../useWindowSize';
- 
-describe('useWindowSize', () => {
-  const originalWindow = global.window;
- 
-  beforeEach(() => {
-    vi.useFakeTimers();
-    // Mock window for all tests
-    global.window = mockWindow as any;
-    // Reset mock implementations
-    mockWindow.setTimeout.mockImplementation(vi.fn());
-    mockWindow.requestAnimationFrame.mockImplementation((cb) => {
-      cb();
-      return 456;
-    });
-    mockWindow.addEventListener.mockClear();
-    mockWindow.removeEventListener.mockClear();
-    mockWindow.dispatchEvent.mockClear();
-  });
- 
-  afterEach(() => {
-    vi.useRealTimers();
-    // Restore original window
-    global.window = originalWindow;
-  });
- 
-  it('should initialize with current window dimensions', () => {
-    const { result } = renderHook(() => useWindowSize());
- 
-    expect(result.current.width).toBe(mockWindow.innerWidth);
-    expect(result.current.height).toBe(mockWindow.innerHeight);
-  });
- 
-  it('should update dimensions on window resize', () => {
-    const { result } = renderHook(() => useWindowSize());
- 
-    // Mock window resize
-    mockWindow.innerWidth = 800;
-    mockWindow.innerHeight = 600;
- 
-    // Trigger resize event
-    act(() => {
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Wait for debounce and animation frame
-    act(() => {
-      vi.advanceTimersByTime(200); // Advance past debounce time
-    });
- 
-    expect(result.current.width).toBe(800);
-    expect(result.current.height).toBe(600);
-  });
- 
-  it('should debounce resize events', () => {
-    const { result } = renderHook(() => useWindowSize({ debounceMs: 200 }));
- 
-    // Mock window resize
-    mockWindow.innerWidth = 800;
- 
-    // Trigger multiple resize events
-    act(() => {
-      mockWindow.dispatchEvent(new Event('resize'));
-      mockWindow.dispatchEvent(new Event('resize'));
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Should not update immediately
-    expect(result.current.width).toBe(mockWindow.innerWidth);
- 
-    // Wait for debounce and animation frame
-    act(() => {
-      vi.advanceTimersByTime(250); // Advance past debounce time
-    });
- 
-    expect(result.current.width).toBe(800);
-  });
- 
-  // Skip test for SSR environment as it requires special setup
-  it.skip('should handle SSR environment', () => {
-    // Test is skipped - in a real SSR environment, the hook would
-    // initialize with width: 0, height: 0 when window is undefined
-  });
- 
-  it('should cleanup event listeners on unmount', () => {
-    const { unmount } = renderHook(() => useWindowSize());
- 
-    unmount();
- 
-    expect(mockWindow.removeEventListener).toHaveBeenCalledWith(
-      'resize',
-      expect.any(Function),
-    );
-  });
- 
-  it('should handle multiple resize events with different debounce times', () => {
-    const { result } = renderHook(() => useWindowSize({ debounceMs: 100 }));
- 
-    // First resize
-    act(() => {
-      mockWindow.innerWidth = 800;
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Second resize before debounce completes
-    act(() => {
-      mockWindow.innerWidth = 1024;
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Wait for debounce and animation frame
-    act(() => {
-      vi.advanceTimersByTime(250); // Advance past debounce time
-    });
- 
-    expect(result.current.width).toBe(1024);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/index.html b/coverage/hooks/index.html deleted file mode 100644 index eec3807b4..000000000 --- a/coverage/hooks/index.html +++ /dev/null @@ -1,326 +0,0 @@ - - - - - - Code coverage report for hooks - - - - - - - - - -
-
-

All files hooks

-
- -
- 92.04% - Statements - 822/893 -
- - -
- 85.45% - Branches - 188/220 -
- - -
- 100% - Functions - 18/18 -
- - -
- 92.04% - Lines - 822/893 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
0%0/5100%1/1100%1/10%0/5
useBackground.ts -
-
100%16/16100%8/8100%2/2100%16/16
useCardSize.ts -
-
88.29%83/9491.66%11/12100%2/288.29%83/94
useEscapeKey.ts -
-
100%36/3692.3%12/13100%1/1100%36/36
useMeasureHeight.ts -
-
100%11/11100%4/4100%1/1100%11/11
useMediaState.ts -
-
100%38/3893.33%14/15100%1/1100%38/38
useOutsideClick.ts -
-
100%33/3391.66%11/12100%1/1100%33/33
useSlideshowProgress.ts -
-
73.33%33/4562.5%5/8100%1/173.33%33/45
useTimelineMedia.ts -
-
91.17%62/6888.88%16/18100%2/291.17%62/68
useTimelineMode.ts -
-
100%36/36100%8/8100%1/1100%36/36
useTimelineNavigation.ts -
-
89.83%212/23683.07%54/65100%1/189.83%212/236
useTimelineScroll.ts -
-
100%54/5490%9/10100%1/1100%54/54
useTimelineSearch.ts -
-
93.71%149/15980.76%21/26100%1/193.71%149/159
useUIState.ts -
-
100%13/13100%4/4100%1/1100%13/13
useWindowSize.ts -
-
93.87%46/4962.5%10/16100%1/193.87%46/49
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/index.ts.html b/coverage/hooks/index.ts.html deleted file mode 100644 index c4239e290..000000000 --- a/coverage/hooks/index.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for hooks/index.ts - - - - - - - - - -
-
-

All files / hooks index.ts

-
- -
- 0% - Statements - 0/5 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 0% - Lines - 0/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
/**
- * Centralized export file for all hooks
- * This makes it easier to import hooks across the application
- */
- 
-// Export all hooks from their individual files
-export * from './useBackground';
-export * from './useMeasureHeight';
-export * from './useOutsideClick';
-export * from './useTimelineNavigation';
-export * from './useWindowSize';
- 
-// Add new hooks to this file as they're created
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useBackground.ts.html b/coverage/hooks/useBackground.ts.html deleted file mode 100644 index f3a2cfc67..000000000 --- a/coverage/hooks/useBackground.ts.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for hooks/useBackground.ts - - - - - - - - - -
-
-

All files / hooks useBackground.ts

-
- -
- 100% - Statements - 16/16 -
- - -
- 100% - Branches - 8/8 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 16/16 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -211x -1x -  -  -1x -  -1x -  -1x -16x -16x -13x -1x -1x -1x -1x -1x -11x -16x -16x - 
import { useMemo } from 'react';
-import { hexToRGBA } from '../utils';
- 
-// Pre-compiled regex for better performance
-const HEX_COLOR_REGEX = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
- 
-const isValidHexColor = (color: string): boolean => HEX_COLOR_REGEX.test(color);
- 
-export const useBackground = (color?: string, opacity = 0.8): string => {
-  return useMemo(() => {
-    if (!color) return '';
-    if (!isValidHexColor(color)) {
-      if (process.env.NODE_ENV === 'development') {
-        console.warn(`Invalid hex color: ${color}`);
-      }
-      return '';
-    }
-    return hexToRGBA(color, opacity);
-  }, [color, opacity]);
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useCardSize.ts.html b/coverage/hooks/useCardSize.ts.html deleted file mode 100644 index af7fd806b..000000000 --- a/coverage/hooks/useCardSize.ts.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - Code coverage report for hooks/useCardSize.ts - - - - - - - - - -
-
-

All files / hooks useCardSize.ts

-
- -
- 88.29% - Statements - 83/94 -
- - -
- 91.66% - Branches - 11/12 -
- - -
- 100% - Functions - 2/2 -
- - -
- 88.29% - Lines - 83/94 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -1401x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -45x -45x -45x -45x -45x -45x -  -45x -45x -45x -41x -  -45x -  -1x -59x -59x -59x -59x -59x -59x -59x -59x -59x -  -  -59x -  -  -  -  -59x -  -  -59x -41x -  -41x -  -  -  -  -  -  -  -  -  -  -  -  -  -41x -  -41x -38x -38x -  -41x -41x -41x -41x -59x -  -59x -59x -5x -  -4x -4x -4x -  -  -4x -4x -4x -4x -4x -4x -  -4x -4x -4x -4x -4x -4x -4x -5x -59x -59x -  -  -59x -59x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -59x -59x -  -59x -59x -59x -59x -59x -59x -59x - 
import { RefObject, useCallback, useEffect, useMemo, useState, useRef } from 'react';
- 
-interface UseCardSizeProps {
-  containerRef: RefObject<HTMLElement | null>;
-  detailsRef: RefObject<HTMLElement | null>;
-  setStartWidth: (width: number) => void;
-}
- 
-interface UseCardSizeReturn {
-  cardActualHeight: number;
-  detailsHeight: number;
-  textContentLarge: boolean;
-  updateCardSize: (node: HTMLElement | null) => void;
-}
- 
-interface CardDimensions {
-  cardHeight: number;
-  detailsHeight: number;
-  containerWidth: number;
-}
- 
-// Memoized calculation function to prevent unnecessary recalculations
-const calculateTextContentSize = (
-  cardHeight: number,
-  containerHeight: number,
-  scrollHeight: number,
-  clientHeight: number,
-  detailsOffsetTop: number,
-): boolean => {
-  // Use cached values instead of DOM queries
-  const hasSignificantOverflow = scrollHeight > clientHeight + 20;
-  return (
-    cardHeight + detailsOffsetTop > containerHeight + 20 ||
-    hasSignificantOverflow
-  );
-};
- 
-export const useCardSize = ({
-  containerRef,
-  detailsRef,
-  setStartWidth,
-}: UseCardSizeProps): UseCardSizeReturn => {
-  const [dimensions, setDimensions] = useState<CardDimensions>({
-    cardHeight: 0,
-    detailsHeight: 0,
-    containerWidth: 0,
-  });
-  
-  // Cache DOM measurements to avoid repeated calculations
-  const measurementsCache = useRef<{
-    scrollHeight: number;
-    clientHeight: number;
-    offsetTop: number;
-    containerHeight: number;
-  }>({ scrollHeight: 0, clientHeight: 0, offsetTop: 0, containerHeight: 0 });
- 
-  // Throttled resize observer for better performance
-  useEffect(() => {
-    let rafId: number;
-    
-    const observer = new ResizeObserver((entries) => {
-      // Use RAF to batch DOM updates
-      if (rafId) cancelAnimationFrame(rafId);
-      
-      rafId = requestAnimationFrame(() => {
-        for (const entry of entries) {
-          if (entry.target === containerRef.current) {
-            setDimensions((prev) => ({
-              ...prev,
-              containerWidth: entry.contentRect.width,
-            }));
-          }
-        }
-      });
-    });
- 
-    if (containerRef.current) {
-      observer.observe(containerRef.current);
-    }
- 
-    return () => {
-      if (rafId) cancelAnimationFrame(rafId);
-      observer.disconnect();
-    };
-  }, [containerRef]);
- 
-  const updateCardSize = useCallback(
-    (node: HTMLElement | null) => {
-      if (!node || !detailsRef.current) return;
- 
-      const detailsEle = detailsRef.current;
-      const { scrollHeight, offsetHeight, offsetTop } = detailsEle;
-      const containerHeight = node.clientHeight;
- 
-      // Cache measurements
-      measurementsCache.current = {
-        scrollHeight,
-        clientHeight: offsetHeight,
-        offsetTop,
-        containerHeight,
-      };
- 
-      containerRef.current = node;
-      setStartWidth(node.clientWidth);
-      setDimensions({
-        cardHeight: scrollHeight,
-        detailsHeight: offsetHeight,
-        containerWidth: node.clientWidth,
-      });
-    },
-    [detailsRef, setStartWidth, containerRef],
-  );
- 
-  // Optimized memoization with cached measurements
-  const { cardActualHeight, detailsHeight, textContentLarge } = useMemo(
-    () => {
-      const cache = measurementsCache.current;
-      return {
-        cardActualHeight: dimensions.cardHeight,
-        detailsHeight: dimensions.detailsHeight,
-        textContentLarge: calculateTextContentSize(
-          dimensions.cardHeight,
-          dimensions.detailsHeight,
-          cache.containerHeight,
-          cache.scrollHeight,
-          cache.clientHeight,
-        ),
-      };
-    },
-    [dimensions],
-  );
- 
-  return {
-    cardActualHeight,
-    detailsHeight,
-    textContentLarge,
-    updateCardSize,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useEscapeKey.ts.html b/coverage/hooks/useEscapeKey.ts.html deleted file mode 100644 index 59e8297ca..000000000 --- a/coverage/hooks/useEscapeKey.ts.html +++ /dev/null @@ -1,265 +0,0 @@ - - - - - - Code coverage report for hooks/useEscapeKey.ts - - - - - - - - - -
-
-

All files / hooks useEscapeKey.ts

-
- -
- 100% - Statements - 36/36 -
- - -
- 92.3% - Branches - 12/13 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 36/36 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -611x -  -  -  -  -  -  -  -  -  -  -  -  -44x -44x -44x -44x -44x -44x -44x -44x -44x -44x -  -44x -44x -  -  -44x -21x -44x -  -44x -44x -  -7x -  -  -7x -6x -6x -6x -7x -44x -44x -  -44x -20x -  -20x -  -  -20x -20x -  -20x -19x -19x -44x -44x - 
import { useEffect, useCallback, useRef } from 'react';
- 
-interface UseEscapeKeyOptions {
-  enabled?: boolean;
-  key?: string;
-  keyCode?: number;
-  eventType?: 'keyup' | 'keydown' | 'keypress';
-}
- 
-/**
- * Hook that triggers callback on escape key press
- * Optimized for performance with better event handling
- */
-export default function useEscapeKey(
-  callback: () => void,
-  options: UseEscapeKeyOptions = {},
-) {
-  const {
-    enabled = true,
-    key = 'Escape',
-    keyCode = 27,
-    eventType = 'keyup',
-  } = options;
- 
-  const savedCallback = useRef(callback);
-  const lastEnabled = useRef(enabled);
- 
-  // Update callback reference without causing re-renders
-  useEffect(() => {
-    savedCallback.current = callback;
-  }, [callback]);
- 
-  const handleKey = useCallback(
-    (e: KeyboardEvent) => {
-      // Early return for better performance
-      if (!lastEnabled.current) return;
-      
-      // Prefer modern 'key' property over deprecated keyCode
-      if (e.key === key || (e.key === undefined && e.keyCode === keyCode)) {
-        e.preventDefault();
-        savedCallback.current();
-      }
-    },
-    [key, keyCode],
-  );
- 
-  useEffect(() => {
-    lastEnabled.current = enabled;
-    
-    if (!enabled) return;
- 
-    // Use passive listeners where possible for better scroll performance
-    const options = eventType === 'keyup' ? { passive: false } : undefined;
-    document.addEventListener(eventType, handleKey, options);
-    
-    return () => {
-      document.removeEventListener(eventType, handleKey);
-    };
-  }, [eventType, handleKey, enabled]);
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useMeasureHeight.ts.html b/coverage/hooks/useMeasureHeight.ts.html deleted file mode 100644 index df389ba45..000000000 --- a/coverage/hooks/useMeasureHeight.ts.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - Code coverage report for hooks/useMeasureHeight.ts - - - - - - - - - -
-
-

All files / hooks useMeasureHeight.ts

-
- -
- 100% - Statements - 11/11 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 11/11 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -181x -  -  -  -  -  -  -1x -11x -11x -6x -3x -3x -6x -11x -11x -11x - 
import { useCallback } from 'react';
- 
-/**
- * Hook to measure the height of a DOM element
- * @param onRender - Callback function that receives the element height
- * @returns Callback ref to attach to the element to measure
- */
-export const useMeasureHeight = (onRender?: (height: number) => void) => {
-  return useCallback(
-    (node: HTMLDivElement | null) => {
-      if (node && onRender) {
-        requestAnimationFrame(() => onRender(node.clientHeight));
-      }
-    },
-    [onRender],
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useMediaState.ts.html b/coverage/hooks/useMediaState.ts.html deleted file mode 100644 index 6e1926516..000000000 --- a/coverage/hooks/useMediaState.ts.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - Code coverage report for hooks/useMediaState.ts - - - - - - - - - -
-
-

All files / hooks useMediaState.ts

-
- -
- 100% - Statements - 38/38 -
- - -
- 93.33% - Branches - 14/15 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 38/38 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -661x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -14x -14x -14x -14x -14x -14x -14x -  -  -14x -9x -14x -  -14x -14x -  -9x -1x -1x -1x -  -  -9x -9x -4x -4x -  -  -9x -1x -1x -9x -14x -14x -  -14x -10x -14x -  -  -14x -  -14x -14x -14x -14x -14x -14x - 
import { useCallback, useEffect, useState, useRef } from 'react';
-import { MediaState } from '../models/TimelineMediaModel';
- 
-interface UseMediaStateProps {
-  slideShowActive: boolean;
-  paused: boolean;
-  id?: string;
-  onElapsed?: (id: string) => void;
-}
- 
-interface UseMediaStateReturn {
-  isPlaying: boolean;
-  handleMediaState: (state: MediaState) => void;
-  cleanup: () => void;
-}
- 
-export const useMediaState = ({
-  slideShowActive,
-  paused,
-  id,
-  onElapsed,
-}: UseMediaStateProps): UseMediaStateReturn => {
-  const [isPlaying, setIsPlaying] = useState(false);
-  const onElapsedRef = useRef(onElapsed);
- 
-  // Keep callback ref updated without triggering re-renders
-  useEffect(() => {
-    onElapsedRef.current = onElapsed;
-  }, [onElapsed]);
- 
-  const handleMediaState = useCallback(
-    (state: MediaState) => {
-      // Early return for inactive slideshow
-      if (!slideShowActive) {
-        if (isPlaying) setIsPlaying(false);
-        return;
-      }
- 
-      // Batch state updates when possible
-      const shouldSetPlaying = state.playing ?? false;
-      if (isPlaying !== shouldSetPlaying) {
-        setIsPlaying(shouldSetPlaying);
-      }
- 
-      // Handle elapsed callback with stable reference
-      if (state.paused && paused && id && onElapsedRef.current) {
-        onElapsedRef.current(id);
-      }
-    },
-    [slideShowActive, paused, id, isPlaying],
-  );
- 
-  const cleanup = useCallback(() => {
-    setIsPlaying(false);
-  }, []);
- 
-  // Clean up on unmount
-  useEffect(() => cleanup, [cleanup]);
- 
-  return {
-    isPlaying,
-    handleMediaState,
-    cleanup,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useOutsideClick.ts.html b/coverage/hooks/useOutsideClick.ts.html deleted file mode 100644 index abab4ab51..000000000 --- a/coverage/hooks/useOutsideClick.ts.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - Code coverage report for hooks/useOutsideClick.ts - - - - - - - - - -
-
-

All files / hooks useOutsideClick.ts

-
- -
- 100% - Statements - 33/33 -
- - -
- 91.66% - Branches - 11/12 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 33/33 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -541x -  -  -  -  -  -  -  -  -  -  -47x -47x -47x -47x -47x -47x -47x -47x -  -  -47x -22x -47x -  -47x -47x -  -14x -  -14x -14x -7x -7x -7x -14x -47x -47x -  -47x -23x -  -23x -  -  -23x -23x -  -23x -21x -21x -47x -47x - 
import { RefObject, useEffect, useCallback, useRef } from 'react';
- 
-interface UseOutsideClickOptions {
-  eventType?: 'click' | 'mousedown' | 'touchstart';
-  enabled?: boolean;
-}
- 
-/**
- * Hook that triggers callback when clicking outside a referenced element
- * Optimized for performance with better event handling
- */
-export default function useOutsideClick(
-  el: RefObject<HTMLElement | null>,
-  callback: () => void,
-  options: UseOutsideClickOptions = {},
-) {
-  const { eventType = 'click', enabled = true } = options;
-  const savedCallback = useRef(callback);
-  const lastEnabled = useRef(enabled);
- 
-  // Update callback reference without causing re-renders
-  useEffect(() => {
-    savedCallback.current = callback;
-  }, [callback]);
- 
-  const handleClick = useCallback(
-    (e: MouseEvent | TouchEvent) => {
-      // Early return for better performance
-      if (!lastEnabled.current) return;
- 
-      const element = el.current;
-      if (element && !element.contains(e.target as Node)) {
-        e.preventDefault();
-        savedCallback.current();
-      }
-    },
-    [el],
-  );
- 
-  useEffect(() => {
-    lastEnabled.current = enabled;
-    
-    if (!enabled) return;
- 
-    // Use passive listeners for touch events for better scroll performance
-    const options = eventType === 'touchstart' ? { passive: false } : undefined;
-    document.addEventListener(eventType, handleClick, options);
-    
-    return () => {
-      document.removeEventListener(eventType, handleClick);
-    };
-  }, [eventType, handleClick, enabled]);
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useSlideshowProgress.ts.html b/coverage/hooks/useSlideshowProgress.ts.html deleted file mode 100644 index c6e7d178b..000000000 --- a/coverage/hooks/useSlideshowProgress.ts.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - Code coverage report for hooks/useSlideshowProgress.ts - - - - - - - - - -
-
-

All files / hooks useSlideshowProgress.ts

-
- -
- 73.33% - Statements - 33/45 -
- - -
- 62.5% - Branches - 5/8 -
- - -
- 100% - Functions - 1/1 -
- - -
- 73.33% - Lines - 33/45 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -841x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -8x -12x -  -  -  -8x -  -  -8x -6x -6x -6x -6x -8x -  -  -8x -6x -  -  -  -8x -  -  -8x -  -  -  -8x -  -  -8x -  -  -  -8x -  -  -8x -  -8x -8x -8x -8x -8x -8x - 
import { useCallback, useEffect, useState, useRef } from 'react';
- 
-interface UseSlideshowProgressProps {
-  /** Whether the slideshow is currently running */
-  slideShowRunning: boolean;
-  /** Current active timeline item index */
-  activeTimelineItem: number;
-  /** Total number of timeline items */
-  totalItems: number;
-  /** Duration of each slide in milliseconds */
-  slideItemDuration: number;
-}
- 
-interface SlideshowProgressState {
-  /** Whether the slideshow progress is paused */
-  isPaused: boolean;
-  /** Pause the slideshow progress */
-  pauseProgress: () => void;
-  /** Resume the slideshow progress */
-  resumeProgress: () => void;
-}
- 
-/**
- * Custom hook to manage overall slideshow progress state
- * Optimized for performance with better timeout management
- */
-export const useSlideshowProgress = ({
-  slideShowRunning,
-  activeTimelineItem,
-  totalItems,
-  slideItemDuration,
-}: UseSlideshowProgressProps): SlideshowProgressState => {
-  const [isPaused, setIsPaused] = useState(false);
-  const pauseTimeoutRef = useRef<NodeJS.Timeout | null>(null);
-  const lastActiveItem = useRef(activeTimelineItem);
- 
-  // Efficient cleanup function
-  const clearTimeouts = useCallback(() => {
-    if (pauseTimeoutRef.current) {
-      clearTimeout(pauseTimeoutRef.current);
-      pauseTimeoutRef.current = null;
-    }
-  }, []);
- 
-  // Clean up timeout when slideshow stops
-  useEffect(() => {
-    if (!slideShowRunning) {
-      setIsPaused(false);
-      clearTimeouts();
-    }
-  }, [slideShowRunning, clearTimeouts]);
- 
-  // Reset pause state when active item changes (optimized)
-  useEffect(() => {
-    if (slideShowRunning && lastActiveItem.current !== activeTimelineItem) {
-      lastActiveItem.current = activeTimelineItem;
-      if (isPaused) setIsPaused(false);
-    }
-  }, [activeTimelineItem, slideShowRunning, isPaused]);
- 
-  // Pause the progress
-  const pauseProgress = useCallback(() => {
-    if (slideShowRunning && !isPaused) {
-      setIsPaused(true);
-    }
-  }, [slideShowRunning, isPaused]);
- 
-  // Resume the progress
-  const resumeProgress = useCallback(() => {
-    if (slideShowRunning && isPaused) {
-      setIsPaused(false);
-    }
-  }, [slideShowRunning, isPaused]);
- 
-  // Cleanup on unmount
-  useEffect(() => clearTimeouts, [clearTimeouts]);
- 
-  return {
-    isPaused,
-    pauseProgress,
-    resumeProgress,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useTimelineMedia.ts.html b/coverage/hooks/useTimelineMedia.ts.html deleted file mode 100644 index 9a6a698ec..000000000 --- a/coverage/hooks/useTimelineMedia.ts.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineMedia.ts - - - - - - - - - -
-
-

All files / hooks useTimelineMedia.ts

-
- -
- 91.17% - Statements - 62/68 -
- - -
- 88.88% - Branches - 16/18 -
- - -
- 100% - Functions - 2/2 -
- - -
- 91.17% - Lines - 62/68 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -971x -1x -  -  -  -  -  -  -  -  -  -1x -12x -12x -12x -12x -12x -  -  -12x -  -2x -2x -4x -4x -2x -2x -2x -2x -2x -2x -2x -12x -  -  -12x -8x -  -  -  -  -8x -8x -8x -8x -8x -  -8x -12x -  -  -12x -  -10x -  -8x -  -  -8x -8x -  -8x -8x -8x -8x -  -8x -8x -8x -  -6x -6x -18x -18x -18x -18x -6x -8x -  -8x -8x -8x -8x -12x -  -  -12x -  -  -12x -  -12x -12x -12x -12x -12x - 
import { useRef, useEffect, useCallback } from 'react';
-import {
-  toggleMediaVisibility,
-  pauseVideoEmbeds,
-} from '../utils/timelineUtils';
- 
-interface UseTimelineMediaProps {
-  mode: string;
-  timelineMainRef: React.RefObject<HTMLDivElement>;
-}
- 
-export const useTimelineMedia = ({
-  mode,
-  timelineMainRef,
-}: UseTimelineMediaProps) => {
-  const observer = useRef<IntersectionObserver | null>(null);
-  const observedElements = useRef<Set<Element>>(new Set());
- 
-  // Optimized intersection callback with batched operations
-  const handleIntersection = useCallback((entries: IntersectionObserverEntry[]) => {
-    // Use requestAnimationFrame to batch DOM operations
-    requestAnimationFrame(() => {
-      entries.forEach((entry) => {
-        const element = entry.target as HTMLDivElement;
-        if (entry.isIntersecting) {
-          toggleMediaVisibility(element, true);
-        } else {
-          toggleMediaVisibility(element, false);
-          pauseVideoEmbeds(element);
-        }
-      });
-    });
-  }, []);
- 
-  // Memoized observer creation
-  const createObserver = useCallback(() => {
-    if (observer.current) {
-      observer.current.disconnect();
-      observedElements.current.clear();
-    }
- 
-    observer.current = new IntersectionObserver(handleIntersection, {
-      root: timelineMainRef.current,
-      threshold: 0.1, // Slightly higher threshold for better performance
-      rootMargin: '50px', // Preload content slightly before it becomes visible
-    });
- 
-    return observer.current;
-  }, [handleIntersection, timelineMainRef]);
- 
-  // Setup IntersectionObserver for efficient media handling
-  useEffect(() => {
-    // Skip horizontal mode as before
-    if (mode === 'HORIZONTAL') return;
- 
-    const observerInstance = createObserver();
- 
-    // Use requestIdleCallback for better performance if available
-    const scheduleObservation = (callback: () => void) => {
-      if ('requestIdleCallback' in window) {
-        (window as any).requestIdleCallback(callback, { timeout: 100 });
-      } else {
-        requestAnimationFrame(callback);
-      }
-    };
- 
-    scheduleObservation(() => {
-      const element = timelineMainRef.current;
-      if (!element || !observerInstance) return;
- 
-      const childElements = element.querySelectorAll('.vertical-item-row');
-      childElements.forEach((elem) => {
-        if (!observedElements.current.has(elem)) {
-          observerInstance.observe(elem);
-          observedElements.current.add(elem);
-        }
-      });
-    });
- 
-    return () => {
-      observerInstance?.disconnect();
-      observedElements.current.clear();
-    };
-  }, [mode, createObserver, timelineMainRef]);
- 
-  // Cleanup function for external use
-  const cleanup = useCallback(() => {
-    observer.current?.disconnect();
-    observedElements.current.clear();
-  }, []);
- 
-  return {
-    observer,
-    cleanup,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useTimelineMode.ts.html b/coverage/hooks/useTimelineMode.ts.html deleted file mode 100644 index f109d5b9a..000000000 --- a/coverage/hooks/useTimelineMode.ts.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineMode.ts - - - - - - - - - -
-
-

All files / hooks useTimelineMode.ts

-
- -
- 100% - Statements - 36/36 -
- - -
- 100% - Branches - 8/8 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 36/36 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -571x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -24x -24x -24x -24x -24x -24x -1x -23x -24x -  -24x -  -  -24x -  -24x -24x -9x -9x -  -8x -  -  -9x -6x -6x -6x -9x -24x -24x -  -24x -24x -24x -24x -24x - 
import { useState, useCallback, useRef } from 'react';
-import { TimelineMode } from '@models/TimelineModel';
- 
-type ExtendedTimelineMode = TimelineMode | 'HORIZONTAL_ALL';
- 
-interface UseTimelineModeProps {
-  initialMode: TimelineMode;
-  showAllCardsHorizontal?: boolean;
-  updateHorizontalAllCards?: (showAll: boolean) => void;
-}
- 
-// Optimized mode mapping for better performance
-const MODE_MAPPINGS: Record<string, ExtendedTimelineMode> = {
-  'VERTICAL': 'VERTICAL',
-  'HORIZONTAL': 'HORIZONTAL',
-  'VERTICAL_ALTERNATING': 'VERTICAL_ALTERNATING',
-  'HORIZONTAL_ALL': 'HORIZONTAL_ALL',
-} as const;
- 
-export const useTimelineMode = ({
-  initialMode,
-  showAllCardsHorizontal = false,
-  updateHorizontalAllCards,
-}: UseTimelineModeProps) => {
-  const [timelineMode, setTimelineMode] = useState<ExtendedTimelineMode>(
-    initialMode === 'HORIZONTAL' && showAllCardsHorizontal
-      ? 'HORIZONTAL_ALL'
-      : initialMode,
-  );
-  
-  const updateHorizontalAllCardsRef = useRef(updateHorizontalAllCards);
- 
-  // Keep callback ref updated without triggering re-renders
-  updateHorizontalAllCardsRef.current = updateHorizontalAllCards;
- 
-  const handleTimelineUpdate = useCallback(
-    (newMode: string) => {
-      const mappedMode = MODE_MAPPINGS[newMode];
-      if (!mappedMode || mappedMode === timelineMode) return;
- 
-      setTimelineMode(mappedMode);
- 
-      // Handle horizontal cards update with stable reference
-      if (updateHorizontalAllCardsRef.current) {
-        const shouldShowAll = mappedMode === 'HORIZONTAL_ALL';
-        updateHorizontalAllCardsRef.current(shouldShowAll);
-      }
-    },
-    [timelineMode],
-  );
- 
-  return {
-    timelineMode,
-    handleTimelineUpdate,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useTimelineNavigation.ts.html b/coverage/hooks/useTimelineNavigation.ts.html deleted file mode 100644 index 7e22af610..000000000 --- a/coverage/hooks/useTimelineNavigation.ts.html +++ /dev/null @@ -1,1057 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineNavigation.ts - - - - - - - - - -
-
-

All files / hooks useTimelineNavigation.ts

-
- -
- 89.83% - Statements - 212/236 -
- - -
- 83.07% - Branches - 54/65 -
- - -
- 100% - Functions - 1/1 -
- - -
- 89.83% - Lines - 212/236 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -3251x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -23x -23x -23x -23x -23x -23x -  -  -23x -21x -21x -69x -69x -69x -21x -21x -23x -  -  -23x -23x -19x -  -  -15x -15x -1x -1x -  -  -14x -14x -  -  -  -  -  -15x -  -  -18x -19x -23x -23x -  -  -23x -23x -2x -  -  -2x -2x -  -  -2x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -1x -2x -2x -23x -23x -  -  -23x -23x -5x -  -5x -5x -1x -4x -  -5x -5x -23x -23x -  -  -23x -23x -6x -  -  -6x -6x -  -  -5x -  -  -6x -  -  -6x -3x -3x -  -  -6x -  -1x -1x -1x -  -1x -1x -1x -  -  -  -1x -6x -23x -23x -  -  -23x -23x -23x -23x -  -  -23x -7x -  -6x -6x -6x -6x -  -  -6x -6x -  -6x -6x -6x -6x -23x -  -23x -5x -  -4x -4x -4x -4x -  -  -4x -4x -  -4x -4x -4x -4x -23x -  -23x -3x -2x -2x -2x -  -  -2x -2x -  -2x -2x -2x -2x -23x -  -23x -5x -4x -4x -4x -4x -  -  -4x -4x -  -4x -4x -4x -4x -23x -  -  -23x -23x -9x -  -9x -  -  -9x -9x -1x -1x -1x -9x -1x -1x -1x -9x -  -  -9x -4x -2x -2x -2x -2x -2x -2x -9x -3x -2x -2x -3x -1x -1x -1x -3x -9x -23x -23x -  -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x - 
import { useCallback, useRef, useMemo } from 'react';
-import { findTimelineElement } from '../utils/timelineUtils';
-import { TimelineMode } from '@models/TimelineModel';
- 
-type ExtendedTimelineMode = TimelineMode | 'HORIZONTAL_ALL';
- 
-interface UseTimelineNavigationProps {
-  items: any[]; // Use any to avoid type conflicts
-  mode: string;
-  timelineId: string;
-  hasFocus: boolean;
-  flipLayout?: boolean;
-  slideShowRunning?: boolean;
-  onTimelineUpdated?: (index: number) => void;
-  onNext?: () => void;
-  onPrevious?: () => void;
-  onFirst?: () => void;
-  onLast?: () => void;
-}
- 
-// Optimized scroll options for different modes
-const SCROLL_OPTIONS = {
-  HORIZONTAL: {
-    behavior: 'smooth' as ScrollBehavior,
-    block: 'nearest' as ScrollLogicalPosition,
-    inline: 'center' as ScrollLogicalPosition,
-  },
-  VERTICAL: {
-    behavior: 'smooth' as ScrollBehavior,
-    block: 'center' as ScrollLogicalPosition,
-    inline: 'center' as ScrollLogicalPosition,
-  },
-} as const;
- 
-export const useTimelineNavigation = ({
-  items,
-  mode,
-  timelineId,
-  hasFocus,
-  flipLayout = false,
-  slideShowRunning = false,
-  onTimelineUpdated,
-  onNext,
-  onPrevious,
-  onFirst,
-  onLast,
-}: UseTimelineNavigationProps) => {
-  const activeItemIndex = useRef<number>(0);
-  const callbacksRef = useRef({
-    onTimelineUpdated,
-    onNext,
-    onPrevious,
-    onFirst,
-    onLast,
-  });
- 
-  // Keep callbacks ref updated without triggering re-renders
-  callbacksRef.current = {
-    onTimelineUpdated,
-    onNext,
-    onPrevious,
-    onFirst,
-    onLast,
-  };
- 
-  // Memoize items lookup map for O(1) access
-  const itemsMap = useMemo(() => {
-    const map = new Map<string, number>();
-    items.forEach((item, index) => {
-      if (item?.id) {
-        map.set(item.id, index);
-      }
-    });
-    return map;
-  }, [items]);
- 
-  // Find target element in the DOM (memoized)
-  const findTargetElement = useCallback(
-    (itemId: string) => {
-      if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        // For vertical modes, directly search for the vertical-item-row
-        // This is more reliable than using findTimelineElement and then looking for a parent
-        const verticalItemRow = document.querySelector(`[data-testid="vertical-item-row"][data-item-id="${itemId}"]`);
-        if (verticalItemRow) {
-          return verticalItemRow as HTMLElement;
-        }
-        
-        // Fallback: try to find the card content element and then get its parent row
-        const cardContent = document.querySelector(`.timeline-card-content[data-item-id="${itemId}"]`);
-        if (cardContent) {
-          const row = cardContent.closest('[data-testid="vertical-item-row"]');
-          if (row) {
-            return row as HTMLElement;
-          }
-        }
-      }
-      
-      // Default behavior for horizontal modes or fallback
-      return findTimelineElement(itemId, mode, timelineId);
-    },
-    [mode, timelineId],
-  );
- 
-  // Optimized scroll function - matches timeline card content behavior
-  const scrollToElement = useCallback(
-    (element: HTMLElement, mode: string) => {
-      if (!element) return;
-      
-      // Ensure we handle the scroll in the next animation frame for smoother transitions
-      requestAnimationFrame(() => {
-        const isVerticalMode = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-        
-        // Check if scrollIntoView is available (it may not be in test environments like JSDOM)
-        if (typeof element.scrollIntoView === 'function') {
-          if (isVerticalMode) {
-            // For vertical modes, ensure we fully center the element in the viewport
-            element.scrollIntoView({
-              behavior: 'smooth',
-              block: 'center', // Always center vertically
-              inline: 'nearest' // Nearest horizontal positioning
-            });
-            
-            // Add a second scroll with a slight delay to ensure proper centering
-            // This addresses issues with complex layouts and varying element heights
-            setTimeout(() => {
-              if (typeof element.scrollIntoView === 'function') {
-                element.scrollIntoView({
-                  behavior: 'smooth',
-                  block: 'center',
-                  inline: 'nearest'
-                });
-              }
-            }, 50);
-          } else {
-            // In horizontal mode, use horizontal centering
-            element.scrollIntoView(SCROLL_OPTIONS.HORIZONTAL);
-          }
-        }
-      });
-    },
-    [],
-  );
- 
-  // Update timeline position (optimized)
-  const updateTimelinePosition = useCallback(
-    (targetIndex: number, isSlideShow?: boolean) => {
-      activeItemIndex.current = targetIndex;
- 
-      const updateIndex =
-        isSlideShow && targetIndex < items.length - 1
-          ? targetIndex + 1
-          : targetIndex;
- 
-      callbacksRef.current.onTimelineUpdated?.(updateIndex);
-    },
-    [items.length],
-  );
- 
-  // Handle timeline item click (significantly optimized)
-  const handleTimelineItemClick = useCallback(
-    (itemId?: string, isSlideShow?: boolean) => {
-      if (!itemId) return;
- 
-      // Use memoized map for O(1) lookup
-      const targetIndex = itemsMap.get(itemId);
-      if (targetIndex === undefined) return;
- 
-      // Update timeline position
-      updateTimelinePosition(targetIndex, isSlideShow);
- 
-      // Skip scrolling in horizontal mode when slideshow is running to prevent toolbar hiding
-      if (mode === 'HORIZONTAL' && slideShowRunning) return;
- 
-      // For vertical modes, directly find and scroll to the vertical item row
-      if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        const targetElement = findTargetElement(itemId);
-        if (targetElement) {
-          scrollToElement(targetElement, mode);
-        }
-      } else {
-        // For horizontal modes, use the original approach
-        const timelinePointElement = document.getElementById(
-          `timeline-${mode.toLowerCase()}-item-${itemId}`
-        );
-        
-        if (timelinePointElement) {
-          scrollToElement(timelinePointElement, mode);
-        } else {
-          const targetElement = findTargetElement(itemId);
-          if (targetElement) scrollToElement(targetElement, mode);
-        }
-      }
-    },
-    [itemsMap, updateTimelinePosition, findTargetElement, mode, scrollToElement, slideShowRunning],
-  );
- 
-  // Handler for item elapsed (used in slideshow)
-  const handleTimelineItemElapsed = useCallback(
-    (itemId?: string) => handleTimelineItemClick(itemId, true),
-    [handleTimelineItemClick],
-  );
- 
-  // Navigation handlers (optimized with bounds checking and focus behavior)
-  const handleNext = useCallback(() => {
-    if (!hasFocus) return;
-    
-    const newIndex = Math.min(activeItemIndex.current + 1, items.length - 1);
-    if (newIndex !== activeItemIndex.current) {
-      activeItemIndex.current = newIndex;
-      callbacksRef.current.onNext?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[newIndex];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  const handlePrevious = useCallback(() => {
-    if (!hasFocus) return;
-    
-    const newIndex = Math.max(activeItemIndex.current - 1, 0);
-    if (newIndex !== activeItemIndex.current) {
-      activeItemIndex.current = newIndex;
-      callbacksRef.current.onPrevious?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[newIndex];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  const handleFirst = useCallback(() => {
-    if (!hasFocus) return;
-    if (activeItemIndex.current !== 0) {
-      activeItemIndex.current = 0;
-      callbacksRef.current.onFirst?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[0];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  const handleLast = useCallback(() => {
-    if (!hasFocus) return;
-    const lastIndex = items.length - 1;
-    if (activeItemIndex.current !== lastIndex) {
-      activeItemIndex.current = lastIndex;
-      callbacksRef.current.onLast?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[lastIndex];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  // Keyboard navigation (optimized with key mapping)
-  const handleKeySelection = useCallback(
-    (event: React.KeyboardEvent<HTMLDivElement>) => {
-      if (!hasFocus) return; // Add hasFocus check here
-      
-      const { key } = event;
- 
-      // Common handlers
-      switch (key) {
-        case 'Home':
-          event.preventDefault();
-          handleFirst();
-          return;
-        case 'End':
-          event.preventDefault();
-          handleLast();
-          return;
-      }
- 
-      // Mode-specific handlers
-      if (mode === 'HORIZONTAL') {
-        if (key === 'ArrowRight') {
-          event.preventDefault();
-          flipLayout ? handlePrevious() : handleNext();
-        } else if (key === 'ArrowLeft') {
-          event.preventDefault();
-          flipLayout ? handleNext() : handlePrevious();
-        }
-      } else if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        if (key === 'ArrowDown') {
-          event.preventDefault();
-          handleNext();
-        } else if (key === 'ArrowUp') {
-          event.preventDefault();
-          handlePrevious();
-        }
-      }
-    },
-    [mode, flipLayout, hasFocus, handleNext, handlePrevious, handleFirst, handleLast],
-  );
- 
-  return {
-    activeItemIndex,
-    handleTimelineItemClick,
-    handleTimelineItemElapsed,
-    handleNext,
-    handlePrevious,
-    handleFirst,
-    handleLast,
-    handleKeySelection,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useTimelineScroll.ts.html b/coverage/hooks/useTimelineScroll.ts.html deleted file mode 100644 index b3cb91014..000000000 --- a/coverage/hooks/useTimelineScroll.ts.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineScroll.ts - - - - - - - - - -
-
-

All files / hooks useTimelineScroll.ts

-
- -
- 100% - Statements - 54/54 -
- - -
- 90% - Branches - 9/10 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 54/54 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -751x -  -  -  -  -  -  -  -  -1x -13x -13x -13x -13x -13x -13x -13x -13x -13x -  -  -13x -13x -  -  -13x -13x -3x -3x -2x -2x -3x -13x -13x -  -  -13x -13x -3x -  -  -3x -1x -1x -  -3x -2x -  -2x -  -2x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -3x -3x -13x -13x -  -13x -13x -13x -13x -13x -13x -13x - 
import { useCallback, useRef } from 'react';
-import { Scroll } from '@models/TimelineHorizontalModel';
- 
-interface UseTimelineScrollProps {
-  mode: string;
-  onScrollEnd?: () => void;
-  setNewOffset: (element: HTMLDivElement, scroll: Partial<Scroll>) => void;
-}
- 
-export const useTimelineScroll = ({
-  mode,
-  onScrollEnd,
-  setNewOffset,
-}: UseTimelineScrollProps) => {
-  const timelineMainRef = useRef<HTMLDivElement>(null);
-  const horizontalContentRef = useRef<HTMLDivElement | null>(null);
-  const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);
-  const setNewOffsetRef = useRef(setNewOffset);
-  const onScrollEndRef = useRef(onScrollEnd);
- 
-  // Keep refs updated without triggering re-renders
-  setNewOffsetRef.current = setNewOffset;
-  onScrollEndRef.current = onScrollEnd;
- 
-  // Handle scrolling (optimized with stable reference)
-  const handleScroll = useCallback(
-    (scroll: Partial<Scroll>) => {
-      const element = timelineMainRef.current;
-      if (element && setNewOffsetRef.current) {
-        setNewOffsetRef.current(element, scroll);
-      }
-    },
-    [],
-  );
- 
-  // Optimized scroll handler with throttling
-  const handleMainScroll = useCallback(
-    (ev: React.UIEvent<HTMLDivElement>) => {
-      const target = ev.target as HTMLElement;
-      
-      // Throttle scroll end detection for better performance
-      if (scrollTimeoutRef.current) {
-        clearTimeout(scrollTimeoutRef.current);
-      }
- 
-      scrollTimeoutRef.current = setTimeout(() => {
-        if (!onScrollEndRef.current) return;
- 
-        const isVertical = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-        
-        if (isVertical) {
-          const scrolled = target.scrollTop + target.clientHeight;
-          const threshold = target.scrollHeight - 1;
-          if (scrolled >= threshold) {
-            onScrollEndRef.current();
-          }
-        } else {
-          const scrolled = target.scrollLeft + target.offsetWidth;
-          if (target.scrollWidth <= scrolled) {
-            onScrollEndRef.current();
-          }
-        }
-      }, 100); // Throttle to 100ms
-    },
-    [mode],
-  );
- 
-  return {
-    timelineMainRef,
-    horizontalContentRef,
-    handleScroll,
-    handleMainScroll,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useTimelineSearch.ts.html b/coverage/hooks/useTimelineSearch.ts.html deleted file mode 100644 index 31ef1ba81..000000000 --- a/coverage/hooks/useTimelineSearch.ts.html +++ /dev/null @@ -1,688 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineSearch.ts - - - - - - - - - -
-
-

All files / hooks useTimelineSearch.ts

-
- -
- 93.71% - Statements - 149/159 -
- - -
- 80.76% - Branches - 21/26 -
- - -
- 100% - Functions - 1/1 -
- - -
- 93.71% - Lines - 149/159 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -2021x -  -1x -1x -  -  -  -  -  -  -  -1x -33x -33x -33x -33x -33x -33x -33x -33x -33x -  -  -33x -33x -  -33x -33x -  -  -33x -16x -54x -54x -54x -54x -54x -1x -53x -54x -  -54x -54x -54x -54x -54x -16x -33x -  -  -33x -  -9x -8x -  -  -  -  -9x -33x -  -  -33x -33x -7x -7x -1x -1x -1x -1x -  -6x -6x -  -  -7x -16x -12x -12x -16x -  -6x -  -6x -6x -6x -6x -6x -6x -6x -6x -6x -7x -  -  -  -7x -33x -33x -  -  -33x -33x -33x -33x -33x -  -33x -33x -7x -7x -7x -33x -33x -  -33x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -33x -  -  -33x -33x -3x -  -3x -3x -2x -1x -  -3x -  -3x -3x -  -3x -3x -  -3x -  -3x -3x -3x -3x -3x -33x -33x -  -33x -33x -33x -33x -  -33x -33x -33x -33x -  -33x -33x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -33x -33x -  -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x - 
import { useCallback, useState, useRef, useMemo } from 'react';
-import { TimelineCardModel } from '@models/TimelineItemModel';
-import { getSearchableText } from '../utils/timelineUtils';
-import { useDebouncedCallback } from 'use-debounce';
- 
-interface UseTimelineSearchProps {
-  items: TimelineCardModel[];
-  onTimelineUpdated?: (index: number) => void;
-  handleTimelineItemClick: (itemId?: string) => void;
-}
- 
-export const useTimelineSearch = ({
-  items,
-  onTimelineUpdated,
-  handleTimelineItemClick,
-}: UseTimelineSearchProps) => {
-  const [searchQuery, setSearchQuery] = useState('');
-  const [searchResults, setSearchResults] = useState<number[]>([]);
-  const [currentMatchIndex, setCurrentMatchIndex] = useState(-1);
-  const searchInputRef = useRef<HTMLInputElement>(null);
-  const activeItemIndex = useRef<number>(0);
-  
-  // Cache callback refs to prevent unnecessary re-renders
-  const onTimelineUpdatedRef = useRef(onTimelineUpdated);
-  const handleTimelineItemClickRef = useRef(handleTimelineItemClick);
-  
-  onTimelineUpdatedRef.current = onTimelineUpdated;
-  handleTimelineItemClickRef.current = handleTimelineItemClick;
- 
-  // Memoize searchable content with better caching strategy
-  const searchableContent = useMemo(() => {
-    return items.map((item, index) => {
-      const textParts = [
-        getSearchableText(item.title),
-        getSearchableText(item.cardTitle),
-        getSearchableText(item.cardSubtitle),
-        Array.isArray(item.cardDetailedText)
-          ? item.cardDetailedText.map(getSearchableText).join(' ')
-          : getSearchableText(item.cardDetailedText),
-      ];
- 
-      return {
-        index,
-        content: textParts.filter(Boolean).join(' ').toLowerCase(),
-        id: item.id,
-      };
-    });
-  }, [items]);
- 
-  // Optimized focus helper with reduced timeout
-  const focusSearchInput = useCallback(() => {
-    // Use requestAnimationFrame for better performance
-    requestAnimationFrame(() => {
-      if (searchInputRef.current) {
-        searchInputRef.current.focus();
-        const length = searchInputRef.current.value.length;
-        searchInputRef.current.setSelectionRange(length, length);
-      }
-    });
-  }, []);
- 
-  // Enhanced search with better performance
-  const findMatches = useCallback(
-    (query: string) => {
-      const trimmedQuery = query.trim();
-      if (!trimmedQuery) {
-        setSearchResults([]);
-        setCurrentMatchIndex(-1);
-        return;
-      }
- 
-      const queryLower = trimmedQuery.toLowerCase();
-      const results: number[] = [];
- 
-      // Use for-loop for better performance than array methods
-      for (let i = 0; i < searchableContent.length; i++) {
-        if (searchableContent[i].content.includes(queryLower)) {
-          results.push(i);
-        }
-      }
- 
-      setSearchResults(results);
- 
-      if (results.length > 0) {
-        setCurrentMatchIndex(0);
-        const firstMatchData = searchableContent[results[0]];
-        if (firstMatchData?.id) {
-          activeItemIndex.current = results[0];
-          onTimelineUpdatedRef.current?.(results[0]);
-          handleTimelineItemClickRef.current(firstMatchData.id);
-          focusSearchInput();
-        }
-      } else {
-        setCurrentMatchIndex(-1);
-        focusSearchInput();
-      }
-    },
-    [searchableContent, focusSearchInput],
-  );
- 
-  // Optimized debounced search with better performance
-  const debouncedSearch = useDebouncedCallback(findMatches, 150, {
-    maxWait: 500,
-    leading: false,
-    trailing: true,
-  });
- 
-  const handleSearchChange = useCallback(
-    (query: string) => {
-      setSearchQuery(query);
-      debouncedSearch(query);
-    },
-    [debouncedSearch],
-  );
- 
-  const clearSearch = useCallback(() => {
-    setSearchQuery('');
-    setSearchResults([]);
-    setCurrentMatchIndex(-1);
-    debouncedSearch.cancel();
- 
-    if (items.length > 0) {
-      activeItemIndex.current = 0;
-      onTimelineUpdatedRef.current?.(0);
- 
-      const firstItem = items[0];
-      if (firstItem?.id) {
-        handleTimelineItemClickRef.current(firstItem.id);
-      }
-    }
-  }, [items, debouncedSearch]);
- 
-  // Optimized navigation with bounds checking
-  const navigateMatches = useCallback(
-    (direction: 'next' | 'prev') => {
-      if (searchResults.length === 0) return;
- 
-      const nextIndex =
-        direction === 'next'
-          ? (currentMatchIndex + 1) % searchResults.length
-          : (currentMatchIndex - 1 + searchResults.length) % searchResults.length;
- 
-      if (nextIndex === currentMatchIndex) return;
- 
-      const newTimelineIndex = searchResults[nextIndex];
-      const matchData = searchableContent[newTimelineIndex];
-      
-      setCurrentMatchIndex(nextIndex);
-      activeItemIndex.current = newTimelineIndex;
-      
-      onTimelineUpdatedRef.current?.(newTimelineIndex);
- 
-      if (matchData?.id) {
-        handleTimelineItemClickRef.current(matchData.id);
-        focusSearchInput();
-      }
-    },
-    [searchResults, currentMatchIndex, searchableContent, focusSearchInput],
-  );
- 
-  const handleNextMatch = useCallback(
-    () => navigateMatches('next'),
-    [navigateMatches],
-  );
- 
-  const handlePreviousMatch = useCallback(
-    () => navigateMatches('prev'),
-    [navigateMatches],
-  );
- 
-  const handleSearchKeyDown = useCallback(
-    (e: React.KeyboardEvent) => {
-      switch (e.key) {
-        case 'Enter':
-          if (searchResults.length > 0) {
-            e.preventDefault();
-            handleNextMatch();
-          }
-          break;
-        case 'Escape':
-          e.preventDefault();
-          clearSearch();
-          break;
-      }
-    },
-    [searchResults.length, handleNextMatch, clearSearch],
-  );
- 
-  return {
-    searchQuery,
-    searchResults,
-    currentMatchIndex,
-    searchInputRef,
-    activeItemIndex,
-    handleSearchChange,
-    clearSearch,
-    handleNextMatch,
-    handlePreviousMatch,
-    handleSearchKeyDown,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useUIState.ts.html b/coverage/hooks/useUIState.ts.html deleted file mode 100644 index 45bc21212..000000000 --- a/coverage/hooks/useUIState.ts.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Code coverage report for hooks/useUIState.ts - - - - - - - - - -
-
-

All files / hooks useUIState.ts

-
- -
- 100% - Statements - 13/13 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 13/13 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -281x -  -  -  -  -  -  -  -  -  -  -1x -12x -12x -12x -  -12x -3x -12x -  -  -12x -2x -12x -  -12x -12x - 
import { useState, useCallback } from 'react';
- 
-export interface UIStateHook<T> {
-  state: T;
-  toggle: () => void;
-  setState: (value: T) => void;
-}
- 
-/**
- * Optimized UI state hook with better type safety and performance
- */
-export const useUIState = <T extends boolean>(
-  initialState: T,
-): UIStateHook<T> => {
-  const [state, setState] = useState<T>(initialState);
- 
-  const toggle = useCallback(() => {
-    setState((prev) => !prev as T);
-  }, []);
- 
-  // Memoized setState to prevent unnecessary re-renders
-  const setStateCallback = useCallback((value: T) => {
-    setState(value);
-  }, []);
- 
-  return { state, toggle, setState: setStateCallback };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/hooks/useWindowSize.ts.html b/coverage/hooks/useWindowSize.ts.html deleted file mode 100644 index 3172fdf2a..000000000 --- a/coverage/hooks/useWindowSize.ts.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - Code coverage report for hooks/useWindowSize.ts - - - - - - - - - -
-
-

All files / hooks useWindowSize.ts

-
- -
- 93.87% - Statements - 46/49 -
- - -
- 62.5% - Branches - 10/16 -
- - -
- 100% - Functions - 1/1 -
- - -
- 93.87% - Lines - 46/49 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -841x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -10x -10x -10x -  -  -10x -8x -8x -10x -  -10x -10x -10x -  -10x -3x -3x -3x -3x -  -  -3x -3x -1x -3x -2x -2x -2x -10x -  -10x -  -8x -8x -  -8x -  -  -  -  -  -  -8x -3x -8x -10x -  -10x -8x -  -  -8x -8x -  -  -8x -  -8x -8x -8x -8x -8x -10x -  -10x -10x - 
import { useState, useEffect, useCallback, useRef } from 'react';
- 
-interface WindowSize {
-  width: number;
-  height: number;
-}
- 
-interface UseWindowSizeOptions {
-  debounceMs?: number;
-  enableThrottling?: boolean;
-}
- 
-/**
- * Hook that returns the current window dimensions
- * Optimized for performance with better resize handling
- */
-export const useWindowSize = (
-  options: UseWindowSizeOptions = {},
-): WindowSize => {
-  const { debounceMs = 100, enableThrottling = true } = options;
-  
-  // Initialize with current window size or fallback
-  const [windowSize, setWindowSize] = useState<WindowSize>(() => ({
-    width: typeof window !== 'undefined' ? window.innerWidth : 0,
-    height: typeof window !== 'undefined' ? window.innerHeight : 0,
-  }));
- 
-  const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
-  const frameRef = useRef<number | undefined>(undefined);
-  const lastSize = useRef<WindowSize>(windowSize);
- 
-  const updateSize = useCallback(() => {
-    const newSize = {
-      width: window.innerWidth,
-      height: window.innerHeight,
-    };
- 
-    // Only update if size actually changed to prevent unnecessary re-renders
-    if (
-      newSize.width !== lastSize.current.width ||
-      newSize.height !== lastSize.current.height
-    ) {
-      lastSize.current = newSize;
-      setWindowSize(newSize);
-    }
-  }, []);
- 
-  const handleResize = useCallback(() => {
-    // Clear existing timeouts and frames
-    if (timeoutRef.current) clearTimeout(timeoutRef.current);
-    if (frameRef.current) cancelAnimationFrame(frameRef.current);
- 
-    if (!enableThrottling) {
-      // Immediate update without throttling
-      frameRef.current = requestAnimationFrame(updateSize);
-      return;
-    }
- 
-    // Use debounced approach for better performance
-    timeoutRef.current = setTimeout(() => {
-      frameRef.current = requestAnimationFrame(updateSize);
-    }, debounceMs);
-  }, [debounceMs, enableThrottling, updateSize]);
- 
-  useEffect(() => {
-    if (typeof window === 'undefined') return;
- 
-    // Use passive listener for better scroll performance
-    const options = { passive: true };
-    window.addEventListener('resize', handleResize, options);
- 
-    // Initial measurement
-    handleResize();
- 
-    return () => {
-      window.removeEventListener('resize', handleResize);
-      if (timeoutRef.current) clearTimeout(timeoutRef.current);
-      if (frameRef.current) cancelAnimationFrame(frameRef.current);
-    };
-  }, [handleResize]);
- 
-  return windowSize;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/index.html b/coverage/index.html deleted file mode 100644 index e1edb34c1..000000000 --- a/coverage/index.html +++ /dev/null @@ -1,776 +0,0 @@ - - - - - - Code coverage report for All files - - - - - - - - - -
-
-

All files

-
- -
- 91.81% - Statements - 10535/11474 -
- - -
- 84.41% - Branches - 1776/2104 -
- - -
- 75.69% - Functions - 190/251 -
- - -
- 91.81% - Lines - 10535/11474 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
__tests__ -
-
100%126/126100%9/9100%0/0100%126/126
components/__tests__ -
-
100%553/55398.8%83/84100%11/11100%553/553
components/common/styles -
-
100%5/5100%3/3100%0/0100%5/5
components/common/themes -
-
100%74/74100%0/0100%0/0100%74/74
components/contexts -
-
96.38%507/52670.96%44/6261.53%8/1396.38%507/526
components/effects -
-
80.07%213/26685.96%49/57100%7/780.07%213/266
components/effects/__tests__ -
-
100%545/545100%99/99100%6/6100%545/545
components/elements/list -
-
97.74%130/13387.8%36/4180%4/597.74%130/133
components/elements/list/__tests__ -
-
100%134/134100%13/13100%0/0100%134/134
components/elements/popover -
-
97.2%139/14379.31%46/58100%19/1997.2%139/143
components/elements/popover/__tests__ -
-
100%85/85100%6/6100%0/0100%85/85
components/timeline -
-
78.48%693/88364.76%68/10544.82%13/2978.48%693/883
components/timeline-elements/memoized -
-
91.17%124/13678.57%22/2840%2/591.17%124/136
components/timeline-elements/memoized/__tests__ -
-
99.27%136/137100%15/15100%0/099.27%136/137
components/timeline-elements/nested-timeline-renderer -
-
11.53%3/26100%0/00%0/111.53%3/26
components/timeline-elements/timeline-card -
-
94.17%178/18972.22%39/54100%3/394.17%178/189
components/timeline-elements/timeline-card-content -
-
76.04%638/83976.41%162/21275%30/4076.04%638/839
components/timeline-elements/timeline-card-content/__tests__ -
-
98.31%351/357100%37/3766.66%2/398.31%351/357
components/timeline-elements/timeline-card-media -
-
79.91%199/24978.33%47/6090%9/1079.91%199/249
components/timeline-elements/timeline-card-media/__tests__ -
-
100%201/201100%10/100%0/8100%201/201
components/timeline-elements/timeline-card-media/components -
-
75.49%191/25368.42%13/19100%1/175.49%191/253
components/timeline-elements/timeline-card-media/hooks -
-
88.65%86/9794.11%16/17100%4/488.65%86/97
components/timeline-elements/timeline-card/__tests__ -
-
93.93%93/99100%10/10100%0/093.93%93/99
components/timeline-elements/timeline-card/hooks -
-
96.2%76/7993.75%15/16100%1/196.2%76/79
components/timeline-elements/timeline-card/timeline-card-portal -
-
100%96/96100%6/6100%1/1100%96/96
components/timeline-elements/timeline-card/timeline-point -
-
100%35/3550%2/4100%1/1100%35/35
components/timeline-elements/timeline-control -
-
91.46%225/24662.65%52/8350%1/291.46%225/246
components/timeline-elements/timeline-control/__tests__ -
-
100%67/67100%6/6100%0/0100%67/67
components/timeline-elements/timeline-controls-wrapper -
-
0%0/8100%1/1100%1/10%0/8
components/timeline-elements/timeline-item-title -
-
100%37/3795%19/20100%1/1100%37/37
components/timeline-elements/timeline-item-title/__tests__ -
-
100%46/46100%7/7100%0/0100%46/46
components/timeline-elements/timeline-outline -
-
92.06%174/18985%51/6071.42%5/792.06%174/189
components/timeline-elements/timeline-outline/__tests__ -
-
94.69%107/113100%13/13100%0/094.69%107/113
components/timeline-elements/timeline-outline/hooks -
-
90.9%10/1150%2/4100%1/190.9%10/11
components/timeline-horizontal -
-
100%103/103100%17/17100%1/1100%103/103
components/timeline-horizontal/__tests__ -
-
98.3%232/23692%23/25100%1/198.3%232/236
components/timeline-vertical -
-
91.1%430/47256.04%51/9150%1/291.1%430/472
components/timeline-vertical/__tests__ -
-
100%74/74100%5/50%0/3100%74/74
components/timeline/__tests__ -
-
95.02%210/221100%14/14100%0/095.02%210/221
components/toggle-button -
-
0%0/200%0/20%0/20%0/20
components/toolbar -
-
87.8%36/4183.33%10/12100%2/287.8%36/41
components/toolbar/__tests__ -
-
100%41/41100%4/40%0/3100%41/41
hooks -
-
92.04%822/89385.45%188/220100%18/1892.04%822/893
hooks/__tests__ -
-
99.17%1562/157599.66%301/302100%7/799.17%1562/1575
utils -
-
91.77%748/81583.93%162/19390.62%29/3291.77%748/815
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/__tests__/index.html b/coverage/lcov-report/__tests__/index.html deleted file mode 100644 index 16bc8d488..000000000 --- a/coverage/lcov-report/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for __tests__ - - - - - - - - - -
-
-

All files __tests__

-
- -
- 100% - Statements - 126/126 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 126/126 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
react-chrono.test.ts -
-
100%126/126100%9/9100%0/0100%126/126
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/__tests__/react-chrono.test.ts.html b/coverage/lcov-report/__tests__/react-chrono.test.ts.html deleted file mode 100644 index 942b9925f..000000000 --- a/coverage/lcov-report/__tests__/react-chrono.test.ts.html +++ /dev/null @@ -1,532 +0,0 @@ - - - - - - Code coverage report for __tests__/react-chrono.test.ts - - - - - - - - - -
-
-

All files / __tests__ react-chrono.test.ts

-
- -
- 100% - Statements - 126/126 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 126/126 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -1501x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x - 
import { describe, expect, it } from 'vitest';
-import { Chrono } from '../react-chrono';
-import type { TimelineItem } from '../react-chrono';
- 
-describe('react-chrono exports', () => {
-  it('should export Chrono component', () => {
-    expect(Chrono).toBeDefined();
-    // Chrono is wrapped with React.memo, so typeof is 'object'
-    expect(typeof Chrono).toBe('object');
-  });
- 
-  it('should export TimelineItem type', () => {
-    // This test verifies that the TimelineItem type is properly exported
-    // TypeScript compilation will fail if the type is not properly exported
-    const timelineItem: TimelineItem = {
-      id: 'test-id',
-      title: 'Test Title',
-      cardTitle: 'Test Card Title',
-      cardSubtitle: 'Test Card Subtitle',
-      cardDetailedText: 'Test detailed text',
-    };
- 
-    expect(timelineItem).toBeDefined();
-    expect(timelineItem.id).toBe('test-id');
-    expect(timelineItem.title).toBe('Test Title');
-  });
- 
-  it('should verify Chrono is the default export from components', () => {
-    // Since Chrono is wrapped with React.memo, check if it has the typical memo structure
-    expect(Chrono).toHaveProperty('$$typeof');
-    expect(Chrono.$$typeof).toBeDefined();
-  });
- 
-  it('should validate TimelineItem interface properties', () => {
-    // Test that TimelineItem accepts all expected properties
-    const complexTimelineItem: TimelineItem = {
-      id: 'complex-item',
-      title: 'Complex Title',
-      cardTitle: 'Complex Card Title',
-      cardSubtitle: 'Complex Card Subtitle',
-      cardDetailedText: ['Detail 1', 'Detail 2'],
-      date: new Date(),
-      media: {
-        type: 'IMAGE',
-        source: {
-          url: 'https://example.com/image.jpg',
-        },
-      },
-      url: 'https://example.com',
-      visible: true,
-      active: false,
-      position: 'left',
-      isNested: false,
-      hasNestedItems: false,
-    };
- 
-    expect(complexTimelineItem).toBeDefined();
-    expect(complexTimelineItem.cardDetailedText).toEqual(['Detail 1', 'Detail 2']);
-    expect(complexTimelineItem.date).toBeInstanceOf(Date);
-    expect(complexTimelineItem.media?.type).toBe('IMAGE');
-    expect(complexTimelineItem.url).toBe('https://example.com');
-  });
- 
-  it('should handle optional TimelineItem properties', () => {
-    // Test that TimelineItem works with minimal properties
-    const minimalTimelineItem: TimelineItem = {};
- 
-    expect(minimalTimelineItem).toBeDefined();
-    expect(Object.keys(minimalTimelineItem)).toHaveLength(0);
-  });
- 
-  it('should support nested timeline items', () => {
-    const nestedTimelineItem: TimelineItem = {
-      id: 'parent-item',
-      title: 'Parent Item',
-      hasNestedItems: true,
-      items: [
-        {
-          id: 'child-1',
-          title: 'Child 1',
-          cardTitle: 'Child Card 1',
-        },
-        {
-          id: 'child-2',
-          title: 'Child 2',
-          cardTitle: 'Child Card 2',
-        },
-      ],
-    };
- 
-    expect(nestedTimelineItem.hasNestedItems).toBe(true);
-    expect(nestedTimelineItem.items).toHaveLength(2);
-    expect(nestedTimelineItem.items?.[0]?.id).toBe('child-1');
-    expect(nestedTimelineItem.items?.[1]?.id).toBe('child-2');
-  });
- 
-  it('should support different media types in TimelineItem', () => {
-    const imageItem: TimelineItem = {
-      id: 'image-item',
-      media: {
-        type: 'IMAGE',
-        source: {
-          url: 'https://example.com/image.jpg',
-        },
-      },
-    };
- 
-    const videoItem: TimelineItem = {
-      id: 'video-item',
-      media: {
-        type: 'VIDEO',
-        source: {
-          url: 'https://example.com/video.mp4',
-        },
-      },
-    };
- 
-    const youtubeItem: TimelineItem = {
-      id: 'youtube-item',
-      media: {
-        type: 'VIDEO',
-        source: {
-          url: 'https://www.youtube.com/watch?v=dQw4w9WgXcQ',
-        },
-      },
-    };
- 
-    expect(imageItem.media?.type).toBe('IMAGE');
-    expect(videoItem.media?.type).toBe('VIDEO');
-    expect(youtubeItem.media?.type).toBe('VIDEO');
-  });
- 
-  it('should support React nodes in TimelineItem properties', () => {
-    const timelineItemWithNodes: TimelineItem = {
-      id: 'react-node-item',
-      title: 'React Node Title',
-      cardTitle: 'React Node Card Title',
-      cardSubtitle: 'React Node Subtitle',
-      cardDetailedText: 'React Node Details',
-      timelineContent: 'Custom timeline content',
-    };
- 
-    expect(timelineItemWithNodes.title).toBe('React Node Title');
-    expect(timelineItemWithNodes.cardTitle).toBe('React Node Card Title');
-    expect(timelineItemWithNodes.cardSubtitle).toBe('React Node Subtitle');
-    expect(timelineItemWithNodes.cardDetailedText).toBe('React Node Details');
-    expect(timelineItemWithNodes.timelineContent).toBe('Custom timeline content');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/base.css b/coverage/lcov-report/base.css deleted file mode 100644 index f418035b4..000000000 --- a/coverage/lcov-report/base.css +++ /dev/null @@ -1,224 +0,0 @@ -body, html { - margin:0; padding: 0; - height: 100%; -} -body { - font-family: Helvetica Neue, Helvetica, Arial; - font-size: 14px; - color:#333; -} -.small { font-size: 12px; } -*, *:after, *:before { - -webkit-box-sizing:border-box; - -moz-box-sizing:border-box; - box-sizing:border-box; - } -h1 { font-size: 20px; margin: 0;} -h2 { font-size: 14px; } -pre { - font: 12px/1.4 Consolas, "Liberation Mono", Menlo, Courier, monospace; - margin: 0; - padding: 0; - -moz-tab-size: 2; - -o-tab-size: 2; - tab-size: 2; -} -a { color:#0074D9; text-decoration:none; } -a:hover { text-decoration:underline; } -.strong { font-weight: bold; } -.space-top1 { padding: 10px 0 0 0; } -.pad2y { padding: 20px 0; } -.pad1y { padding: 10px 0; } -.pad2x { padding: 0 20px; } -.pad2 { padding: 20px; } -.pad1 { padding: 10px; } -.space-left2 { padding-left:55px; } -.space-right2 { padding-right:20px; } -.center { text-align:center; } -.clearfix { display:block; } -.clearfix:after { - content:''; - display:block; - height:0; - clear:both; - visibility:hidden; - } -.fl { float: left; } -@media only screen and (max-width:640px) { - .col3 { width:100%; max-width:100%; } - .hide-mobile { display:none!important; } -} - -.quiet { - color: #7f7f7f; - color: rgba(0,0,0,0.5); -} -.quiet a { opacity: 0.7; } - -.fraction { - font-family: Consolas, 'Liberation Mono', Menlo, Courier, monospace; - font-size: 10px; - color: #555; - background: #E8E8E8; - padding: 4px 5px; - border-radius: 3px; - vertical-align: middle; -} - -div.path a:link, div.path a:visited { color: #333; } -table.coverage { - border-collapse: collapse; - margin: 10px 0 0 0; - padding: 0; -} - -table.coverage td { - margin: 0; - padding: 0; - vertical-align: top; -} -table.coverage td.line-count { - text-align: right; - padding: 0 5px 0 20px; -} -table.coverage td.line-coverage { - text-align: right; - padding-right: 10px; - min-width:20px; -} - -table.coverage td span.cline-any { - display: inline-block; - padding: 0 5px; - width: 100%; -} -.missing-if-branch { - display: inline-block; - margin-right: 5px; - border-radius: 3px; - position: relative; - padding: 0 4px; - background: #333; - color: yellow; -} - -.skip-if-branch { - display: none; - margin-right: 10px; - position: relative; - padding: 0 4px; - background: #ccc; - color: white; -} -.missing-if-branch .typ, .skip-if-branch .typ { - color: inherit !important; -} -.coverage-summary { - border-collapse: collapse; - width: 100%; -} -.coverage-summary tr { border-bottom: 1px solid #bbb; } -.keyline-all { border: 1px solid #ddd; } -.coverage-summary td, .coverage-summary th { padding: 10px; } -.coverage-summary tbody { border: 1px solid #bbb; } -.coverage-summary td { border-right: 1px solid #bbb; } -.coverage-summary td:last-child { border-right: none; } -.coverage-summary th { - text-align: left; - font-weight: normal; - white-space: nowrap; -} -.coverage-summary th.file { border-right: none !important; } -.coverage-summary th.pct { } -.coverage-summary th.pic, -.coverage-summary th.abs, -.coverage-summary td.pct, -.coverage-summary td.abs { text-align: right; } -.coverage-summary td.file { white-space: nowrap; } -.coverage-summary td.pic { min-width: 120px !important; } -.coverage-summary tfoot td { } - -.coverage-summary .sorter { - height: 10px; - width: 7px; - display: inline-block; - margin-left: 0.5em; - background: url(sort-arrow-sprite.png) no-repeat scroll 0 0 transparent; -} -.coverage-summary .sorted .sorter { - background-position: 0 -20px; -} -.coverage-summary .sorted-desc .sorter { - background-position: 0 -10px; -} -.status-line { height: 10px; } -/* yellow */ -.cbranch-no { background: yellow !important; color: #111; } -/* dark red */ -.red.solid, .status-line.low, .low .cover-fill { background:#C21F39 } -.low .chart { border:1px solid #C21F39 } -.highlighted, -.highlighted .cstat-no, .highlighted .fstat-no, .highlighted .cbranch-no{ - background: #C21F39 !important; -} -/* medium red */ -.cstat-no, .fstat-no, .cbranch-no, .cbranch-no { background:#F6C6CE } -/* light red */ -.low, .cline-no { background:#FCE1E5 } -/* light green */ -.high, .cline-yes { background:rgb(230,245,208) } -/* medium green */ -.cstat-yes { background:rgb(161,215,106) } -/* dark green */ -.status-line.high, .high .cover-fill { background:rgb(77,146,33) } -.high .chart { border:1px solid rgb(77,146,33) } -/* dark yellow (gold) */ -.status-line.medium, .medium .cover-fill { background: #f9cd0b; } -.medium .chart { border:1px solid #f9cd0b; } -/* light yellow */ -.medium { background: #fff4c2; } - -.cstat-skip { background: #ddd; color: #111; } -.fstat-skip { background: #ddd; color: #111 !important; } -.cbranch-skip { background: #ddd !important; color: #111; } - -span.cline-neutral { background: #eaeaea; } - -.coverage-summary td.empty { - opacity: .5; - padding-top: 4px; - padding-bottom: 4px; - line-height: 1; - color: #888; -} - -.cover-fill, .cover-empty { - display:inline-block; - height: 12px; -} -.chart { - line-height: 0; -} -.cover-empty { - background: white; -} -.cover-full { - border-right: none !important; -} -pre.prettyprint { - border: none !important; - padding: 0 !important; - margin: 0 !important; -} -.com { color: #999 !important; } -.ignore-none { color: #999; font-weight: normal; } - -.wrapper { - min-height: 100%; - height: auto !important; - height: 100%; - margin: 0 auto -48px; -} -.footer, .push { - height: 48px; -} diff --git a/coverage/lcov-report/block-navigation.js b/coverage/lcov-report/block-navigation.js deleted file mode 100644 index cc1213023..000000000 --- a/coverage/lcov-report/block-navigation.js +++ /dev/null @@ -1,87 +0,0 @@ -/* eslint-disable */ -var jumpToCode = (function init() { - // Classes of code we would like to highlight in the file view - var missingCoverageClasses = ['.cbranch-no', '.cstat-no', '.fstat-no']; - - // Elements to highlight in the file listing view - var fileListingElements = ['td.pct.low']; - - // We don't want to select elements that are direct descendants of another match - var notSelector = ':not(' + missingCoverageClasses.join('):not(') + ') > '; // becomes `:not(a):not(b) > ` - - // Selecter that finds elements on the page to which we can jump - var selector = - fileListingElements.join(', ') + - ', ' + - notSelector + - missingCoverageClasses.join(', ' + notSelector); // becomes `:not(a):not(b) > a, :not(a):not(b) > b` - - // The NodeList of matching elements - var missingCoverageElements = document.querySelectorAll(selector); - - var currentIndex; - - function toggleClass(index) { - missingCoverageElements - .item(currentIndex) - .classList.remove('highlighted'); - missingCoverageElements.item(index).classList.add('highlighted'); - } - - function makeCurrent(index) { - toggleClass(index); - currentIndex = index; - missingCoverageElements.item(index).scrollIntoView({ - behavior: 'smooth', - block: 'center', - inline: 'center' - }); - } - - function goToPrevious() { - var nextIndex = 0; - if (typeof currentIndex !== 'number' || currentIndex === 0) { - nextIndex = missingCoverageElements.length - 1; - } else if (missingCoverageElements.length > 1) { - nextIndex = currentIndex - 1; - } - - makeCurrent(nextIndex); - } - - function goToNext() { - var nextIndex = 0; - - if ( - typeof currentIndex === 'number' && - currentIndex < missingCoverageElements.length - 1 - ) { - nextIndex = currentIndex + 1; - } - - makeCurrent(nextIndex); - } - - return function jump(event) { - if ( - document.getElementById('fileSearch') === document.activeElement && - document.activeElement != null - ) { - // if we're currently focused on the search input, we don't want to navigate - return; - } - - switch (event.which) { - case 78: // n - case 74: // j - goToNext(); - break; - case 66: // b - case 75: // k - case 80: // p - goToPrevious(); - break; - } - }; -})(); -window.addEventListener('keydown', jumpToCode); diff --git a/coverage/lcov-report/components/__tests__/GlobalContext.test.tsx.html b/coverage/lcov-report/components/__tests__/GlobalContext.test.tsx.html deleted file mode 100644 index 3fe30761d..000000000 --- a/coverage/lcov-report/components/__tests__/GlobalContext.test.tsx.html +++ /dev/null @@ -1,2290 +0,0 @@ - - - - - - Code coverage report for components/__tests__/GlobalContext.test.tsx - - - - - - - - - -
-
-

All files / components/__tests__ GlobalContext.test.tsx

-
- -
- 100% - Statements - 553/553 -
- - -
- 98.8% - Branches - 83/84 -
- - -
- 100% - Functions - 11/11 -
- - -
- 100% - Lines - 553/553 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560 -561 -562 -563 -564 -565 -566 -567 -568 -569 -570 -571 -572 -573 -574 -575 -576 -577 -578 -579 -580 -581 -582 -583 -584 -585 -586 -587 -588 -589 -590 -591 -592 -593 -594 -595 -596 -597 -598 -599 -600 -601 -602 -603 -604 -605 -606 -607 -608 -609 -610 -611 -612 -613 -614 -615 -616 -617 -618 -619 -620 -621 -622 -623 -624 -625 -626 -627 -628 -629 -630 -631 -632 -633 -634 -635 -636 -637 -638 -639 -640 -641 -642 -643 -644 -645 -646 -647 -648 -649 -650 -651 -652 -653 -654 -655 -656 -657 -658 -659 -660 -661 -662 -663 -664 -665 -666 -667 -668 -669 -670 -671 -672 -673 -674 -675 -676 -677 -678 -679 -680 -681 -682 -683 -684 -685 -686 -687 -688 -689 -690 -691 -692 -693 -694 -695 -696 -697 -698 -699 -700 -701 -702 -703 -704 -705 -706 -707 -708 -709 -710 -711 -712 -713 -714 -715 -716 -717 -718 -719 -720 -721 -722 -723 -724 -725 -726 -727 -728 -729 -730 -731 -732 -733 -734 -735 -7361x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -1x -48x -48x -48x -48x -  -  -  -  -  -  -1x -43x -  -  -1x -39x -39x -39x -39x -  -39x -45x -45x -45x -  -39x -39x -39x -39x -39x -  -39x -39x -39x -39x -39x -  -  -  -  -  -1x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -  -1x -41x -41x -41x -41x -41x -41x -41x -41x -  -1x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -41x -  -  -  -  -  -1x -1x -40x -40x -40x -40x -40x -1x -  -1x -40x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -3x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -6x -3x -3x -3x -3x -6x -1x -  -  -1x -1x -  -  -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import { render, screen, act } from '@testing-library/react';
-import { useContext } from 'react';
-import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import GlobalContextProvider, {
-  GlobalContext,
-  ContextProps,
-} from '../GlobalContext';
-import { TextDensity, TimelineMode, ButtonTexts } from '@models/TimelineModel';
-import { Theme } from '@models/Theme';
- 
-// ============================================================================
-// MOCKS & UTILITIES
-// ============================================================================
- 
-// Use vi.hoisted to ensure mock functions are available during hoisting
-const {
-  mockGetDefaultButtonTexts,
-  mockGetDefaultClassNames,
-  mockGetDefaultThemeOrDark,
-  mockGetSlideShowType,
-  mockUseMatchMedia,
-} = vi.hoisted(() => ({
-  mockGetDefaultButtonTexts: vi.fn(),
-  mockGetDefaultClassNames: vi.fn(),
-  mockGetDefaultThemeOrDark: vi.fn(),
-  mockGetSlideShowType: vi.fn(),
-  mockUseMatchMedia: vi.fn(),
-}));
- 
-vi.mock('@utils/index', () => ({
-  getDefaultButtonTexts: mockGetDefaultButtonTexts,
-  getDefaultClassNames: mockGetDefaultClassNames,
-  getDefaultThemeOrDark: mockGetDefaultThemeOrDark,
-  getSlideShowType: mockGetSlideShowType,
-}));
- 
-vi.mock('../effects/useMatchMedia', () => ({
-  useMatchMedia: mockUseMatchMedia,
-}));
- 
-// ============================================================================
-// TEST UTILITIES
-// ============================================================================
- 
-interface TestContextConsumerProps {
-  onContextValue: (value: ContextProps) => void;
-}
- 
-const TestContextConsumer = ({ onContextValue }: TestContextConsumerProps) => {
-  const contextValue = useContext(GlobalContext);
-  onContextValue(contextValue);
-  return <div data-testid="context-consumer">Context Consumer</div>;
-};
- 
-interface TestWrapperProps {
-  children: React.ReactElement | React.ReactElement[];
-  contextProps?: Partial<ContextProps>;
-}
- 
-const TestWrapper = ({ children, contextProps = {} }: TestWrapperProps) => (
-  <GlobalContextProvider {...contextProps}>{children}</GlobalContextProvider>
-);
- 
-const renderWithContext = (
-  contextProps: Partial<ContextProps> = {},
-  onContextValue?: (value: ContextProps) => void,
-) => {
-  let capturedContext: ContextProps | null = null;
- 
-  const contextCapture = (value: ContextProps) => {
-    capturedContext = value;
-    onContextValue?.(value);
-  };
- 
-  const renderResult = render(
-    <TestWrapper contextProps={contextProps}>
-      <TestContextConsumer onContextValue={contextCapture} />
-    </TestWrapper>,
-  );
- 
-  return {
-    ...renderResult,
-    getContext: () => capturedContext!,
-  };
-};
- 
-// ============================================================================
-// TEST DATA
-// ============================================================================
- 
-const createMockButtonTexts = (): ButtonTexts => ({
-  first: 'First',
-  last: 'Last',
-  play: 'Play',
-  stop: 'Stop',
-  previous: 'Previous',
-  next: 'Next',
-  dark: 'Dark',
-  light: 'Light',
-  timelinePoint: 'Timeline Point',
-  searchPlaceholder: 'Search...',
-  searchAriaLabel: 'Search timeline',
-  clearSearch: 'Clear',
-  nextMatch: 'Next Match',
-  previousMatch: 'Previous Match',
-});
- 
-const createMockClassNames = () => ({
-  card: 'rc-card',
-  cardMedia: 'rc-card-media',
-  cardSubTitle: 'rc-card-subtitle',
-  cardText: 'rc-card-text',
-  cardTitle: 'rc-card-title',
-  controls: 'rc-controls',
-  title: 'rc-title',
-});
- 
-const createMockTheme = (): Theme => ({
-  primary: '#0f52ba',
-  secondary: '#ffdf00',
-  cardBgColor: '#ffffff',
-  cardDetailsBackGround: '#ffffff',
-  cardDetailsColor: '#000',
-  cardMediaBgColor: '#ffffff',
-  cardSubtitleColor: '#000',
-  cardTitleColor: '#000',
-  detailsColor: '#000',
-  iconBackgroundColor: '#ffffff',
-  nestedCardBgColor: '#ffffff',
-  nestedCardDetailsBackGround: '#ffffff',
-  nestedCardDetailsColor: '#000',
-  nestedCardSubtitleColor: '#000',
-  nestedCardTitleColor: '#000',
-  textColor: '#000',
-  titleColor: '#0f52ba',
-  titleColorActive: '#0f52ba',
-  toolbarBgColor: '#ffffff',
-  toolbarBtnBgColor: '#0f52ba',
-  toolbarTextColor: '#000',
-});
- 
-// ============================================================================
-// TEST SETUP & TEARDOWN
-// ============================================================================
- 
-describe('GlobalContext', () => {
-  beforeEach(() => {
-    mockGetDefaultButtonTexts.mockReturnValue(createMockButtonTexts());
-    mockGetDefaultClassNames.mockReturnValue(createMockClassNames());
-    mockGetDefaultThemeOrDark.mockReturnValue(createMockTheme());
-    mockGetSlideShowType.mockReturnValue('reveal');
-    mockUseMatchMedia.mockReturnValue(false);
-  });
- 
-  afterEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  // ============================================================================
-  // BASIC FUNCTIONALITY TESTS
-  // ============================================================================
- 
-  describe('Provider Initialization', () => {
-    it('should render provider and children without errors', () => {
-      render(
-        <TestWrapper>
-          <div data-testid="test-child">Test Child</div>
-        </TestWrapper>,
-      );
- 
-      expect(screen.getByTestId('test-child')).toBeInTheDocument();
-    });
- 
-    it('should provide context with default values', () => {
-      const { getContext } = renderWithContext();
-      const context = getContext();
- 
-      expect(context).toBeDefined();
-      expect(context.mode).toBe('VERTICAL_ALTERNATING');
-      expect(context.cardHeight).toBe(200);
-      expect(context.cardLess).toBe(false);
-      expect(context.textDensity).toBe('HIGH');
-    });
- 
-    it('should apply custom props correctly', () => {
-      const customProps = {
-        mode: 'HORIZONTAL' as TimelineMode,
-        cardHeight: 300,
-        cardLess: true,
-        textDensity: 'LOW' as TextDensity,
-        responsiveBreakPoint: 768,
-      };
- 
-      const { getContext } = renderWithContext(customProps);
-      const context = getContext();
- 
-      expect(context.mode).toBe('HORIZONTAL');
-      expect(context.cardHeight).toBe(300);
-      expect(context.cardLess).toBe(true);
-      expect(context.textDensity).toBe('LOW');
-      expect(context.responsiveBreakPoint).toBe(768);
-    });
-  });
- 
-  // ============================================================================
-  // STATE MANAGEMENT TESTS
-  // ============================================================================
- 
-  describe('State Management', () => {
-    describe('Dark Mode State', () => {
-      it('should initialize dark mode from props', () => {
-        const { getContext } = renderWithContext({ darkMode: true });
-        expect(getContext().darkMode).toBe(true);
-      });
- 
-      it('should toggle dark mode and call theme change callback', () => {
-        const onThemeChange = vi.fn();
-        const { getContext, rerender } = renderWithContext({
-          darkMode: false,
-          onThemeChange,
-        });
- 
-        const initialContext = getContext();
-        expect(initialContext.darkMode).toBe(false);
- 
-        act(() => {
-          initialContext.toggleDarkMode?.();
-        });
- 
-        rerender(
-          <TestWrapper contextProps={{ darkMode: false, onThemeChange }}>
-            <TestContextConsumer onContextValue={() => {}} />
-          </TestWrapper>,
-        );
- 
-        expect(onThemeChange).toHaveBeenCalledTimes(1);
-      });
- 
-      it('should handle toggle when no theme change callback provided', () => {
-        const { getContext } = renderWithContext({ darkMode: false });
- 
-        expect(() => {
-          act(() => {
-            getContext().toggleDarkMode?.();
-          });
-        }).not.toThrow();
-      });
-    });
- 
-    describe('Horizontal Cards State', () => {
-      it('should initialize horizontal cards state from props', () => {
-        const { getContext } = renderWithContext({
-          showAllCardsHorizontal: true,
-        });
-        expect(getContext().showAllCardsHorizontal).toBe(true);
-      });
- 
-      it('should update horizontal cards state', () => {
-        const { getContext, rerender } = renderWithContext({
-          showAllCardsHorizontal: false,
-        });
- 
-        const initialContext = getContext();
-        expect(initialContext.showAllCardsHorizontal).toBe(false);
- 
-        act(() => {
-          initialContext.updateHorizontalAllCards?.(true);
-        });
- 
-        rerender(
-          <TestWrapper contextProps={{ showAllCardsHorizontal: false }}>
-            <TestContextConsumer onContextValue={() => {}} />
-          </TestWrapper>,
-        );
- 
-        expect(getContext().showAllCardsHorizontal).toBe(true);
-      });
-    });
- 
-    describe('Text Density State', () => {
-      it('should initialize text density from props', () => {
-        const { getContext } = renderWithContext({ textDensity: 'LOW' });
-        expect(getContext().textDensity).toBe('LOW');
-      });
- 
-      it('should update text density state', () => {
-        const { getContext, rerender } = renderWithContext({
-          textDensity: 'HIGH',
-        });
- 
-        const initialContext = getContext();
-        expect(initialContext.textDensity).toBe('HIGH');
- 
-        act(() => {
-          initialContext.updateTextContentDensity?.('LOW');
-        });
- 
-        rerender(
-          <TestWrapper contextProps={{ textDensity: 'HIGH' }}>
-            <TestContextConsumer onContextValue={() => {}} />
-          </TestWrapper>,
-        );
- 
-        expect(getContext().textDensity).toBe('LOW');
-      });
-    });
-  });
- 
-  // ============================================================================
-  // COMPUTED VALUES TESTS
-  // ============================================================================
- 
-  describe('Computed Values', () => {
-    describe('Card Height Calculations', () => {
-      it('should calculate card height for non-cardless mode', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 250,
-          cardLess: false,
-        });
-        expect(getContext().cardHeight).toBe(250);
-      });
- 
-      it('should handle card height for cardless mode', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 150,
-          cardLess: true,
-        });
-        expect(getContext().cardHeight).toBe(150);
-      });
- 
-      it('should use default when cardHeight is undefined in cardless mode', () => {
-        const { getContext } = renderWithContext({
-          cardLess: true,
-          cardHeight: undefined,
-        });
-        // Default cardHeight is 200, so with cardLess it should still be 200
-        expect(getContext().cardHeight).toBe(200);
-      });
-    });
- 
-    describe('Content Details Height', () => {
-      it('should calculate content details height with default values', () => {
-        const { getContext } = renderWithContext();
-        // newCardHeight = max(10 + 200, 200) = 210
-        // detailsHeightApprox = round(210 * 0.75) = 158
-        // final = max(10, 158) = 158
-        expect(getContext().contentDetailsHeight).toBe(158);
-      });
- 
-      it('should calculate with custom media and content heights', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 150,
-          contentDetailsHeight: 50,
-          mediaHeight: 100,
-        });
-        // newCardHeight = max(50 + 100, 150) = 150
-        // detailsHeightApprox = round(150 * 0.75) = 113
-        // final = max(50, 113) = 113
-        expect(getContext().contentDetailsHeight).toBe(113);
-      });
- 
-      it('should handle undefined content and media heights', () => {
-        const { getContext } = renderWithContext({
-          cardHeight: 200,
-          contentDetailsHeight: undefined,
-          mediaHeight: undefined,
-        });
-        // newCardHeight = max(0 + 0, 200) = 200
-        // detailsHeightApprox = round(200 * 0.75) = 150
-        // final = max(0, 150) = 150
-        expect(getContext().contentDetailsHeight).toBe(158);
-      });
-    });
- 
-    describe('Active Item Index', () => {
-      it('should compute active index for non-flipped layout', () => {
-        const { getContext } = renderWithContext({
-          flipLayout: false,
-          items: [
-            { title: 'Item 1' },
-            { title: 'Item 2' },
-            { title: 'Item 3' },
-          ],
-        });
-        expect(getContext().activeItemIndex).toBe(0);
-      });
- 
-      it('should compute active index for flipped layout', () => {
-        const { getContext } = renderWithContext({
-          flipLayout: true,
-          items: [
-            { title: 'Item 1' },
-            { title: 'Item 2' },
-            { title: 'Item 3' },
-          ],
-        });
-        expect(getContext().activeItemIndex).toBe(2);
-      });
-    });
- 
-    describe('Media Alignment', () => {
-      it('should set left alignment for vertical mode without text overlay', () => {
-        const { getContext } = renderWithContext({
-          mode: 'VERTICAL',
-          textOverlay: false,
-        });
-        expect(getContext().mediaSettings?.align).toBe('left');
-      });
- 
-      it('should set center alignment for non-vertical mode', () => {
-        const { getContext } = renderWithContext({
-          mode: 'HORIZONTAL',
-          textOverlay: false,
-        });
-        expect(getContext().mediaSettings?.align).toBe('center');
-      });
- 
-      it('should set center alignment when text overlay is enabled', () => {
-        const { getContext } = renderWithContext({
-          mode: 'VERTICAL',
-          textOverlay: true,
-        });
-        expect(getContext().mediaSettings?.align).toBe('center');
-      });
-    });
-  });
- 
-  // ============================================================================
-  // RESPONSIVE BEHAVIOR TESTS
-  // ============================================================================
- 
-  describe('Responsive Behavior', () => {
-    beforeEach(() => {
-      vi.clearAllMocks();
-    });
- 
-    it('should setup mobile detection with correct breakpoints', () => {
-      renderWithContext({
-        responsiveBreakPoint: 768,
-        enableBreakPoint: true,
-      });
- 
-      expect(mockUseMatchMedia).toHaveBeenCalledWith('(max-width: 767px)', {
-        onMatch: expect.any(Function),
-        enabled: true,
-      });
-      expect(mockUseMatchMedia).toHaveBeenCalledWith('(min-width: 768px)', {
-        onMatch: expect.any(Function),
-        enabled: true,
-      });
-    });
- 
-    it('should disable breakpoint detection when configured', () => {
-      renderWithContext({
-        enableBreakPoint: false,
-      });
- 
-      expect(mockUseMatchMedia).toHaveBeenCalledWith('(max-width: 1023px)', {
-        onMatch: expect.any(Function),
-        enabled: false,
-      });
-    });
- 
-    it('should handle mobile state changes', () => {
-      let mobileCallback: (() => void) | undefined;
-      let desktopCallback: (() => void) | undefined;
- 
-      mockUseMatchMedia.mockImplementation((query: string, options: any) => {
-        if (query.includes('max-width')) {
-          mobileCallback = options.onMatch;
-        } else if (query.includes('min-width')) {
-          desktopCallback = options.onMatch;
-        }
-        return false;
-      });
- 
-      // Initial render
-      const { getContext } = renderWithContext({ enableBreakPoint: true });
-      expect(getContext().isMobile).toBe(false);
- 
-      // Simulate mobile detection
-      act(() => {
-        mobileCallback?.();
-      });
- 
-      // Verify mobile state
-      expect(getContext().isMobile).toBe(true);
- 
-      // Simulate desktop detection
-      act(() => {
-        desktopCallback?.();
-      });
- 
-      // Verify desktop state
-      expect(getContext().isMobile).toBe(false);
- 
-      // Verify that useMatchMedia was called at least once for each breakpoint
-      expect(mockUseMatchMedia).toHaveBeenCalledWith(
-        '(max-width: 1023px)',
-        expect.any(Object),
-      );
-      expect(mockUseMatchMedia).toHaveBeenCalledWith(
-        '(min-width: 1024px)',
-        expect.any(Object),
-      );
-    });
-  });
- 
-  // ============================================================================
-  // PROPS MERGING TESTS
-  // ============================================================================
- 
-  describe('Props Merging', () => {
-    it('should merge button texts with defaults', () => {
-      const customButtonTexts: ButtonTexts = {
-        first: 'First',
-        last: 'Last',
-        play: 'Start',
-        stop: 'Pause',
-      };
-      const { getContext } = renderWithContext({
-        buttonTexts: customButtonTexts,
-      });
- 
-      expect(getContext().buttonTexts).toEqual({
-        ...createMockButtonTexts(),
-        ...customButtonTexts,
-      });
-    });
- 
-    it('should merge class names with defaults', () => {
-      const customClassNames = { card: 'custom-card', title: 'custom-title' };
-      const { getContext } = renderWithContext({
-        classNames: customClassNames,
-      });
- 
-      expect(getContext().classNames).toEqual({
-        ...createMockClassNames(),
-        ...customClassNames,
-      });
-    });
- 
-    it('should merge theme with defaults', () => {
-      const customTheme = { primary: '#ff0000', secondary: '#00ff00' };
-      const { getContext } = renderWithContext({
-        theme: customTheme,
-      });
- 
-      expect(getContext().theme).toEqual({
-        ...createMockTheme(),
-        ...customTheme,
-      });
-    });
- 
-    it('should merge font sizes with defaults', () => {
-      const customFontSizes = { cardTitle: '1.2rem', title: '1.5rem' };
-      const { getContext } = renderWithContext({
-        fontSizes: customFontSizes,
-      });
- 
-      const expectedFontSizes = {
-        cardSubtitle: '0.85rem',
-        cardText: '1rem',
-        cardTitle: '1.2rem',
-        title: '1.5rem',
-      };
- 
-      expect(getContext().fontSizes).toEqual(expectedFontSizes);
-    });
- 
-    it('should merge media settings with computed defaults', () => {
-      const customMediaSettings = { fit: 'contain' as const };
-      const { getContext } = renderWithContext({
-        mode: 'HORIZONTAL',
-        mediaSettings: customMediaSettings,
-      });
- 
-      expect(getContext().mediaSettings).toEqual({
-        align: 'center',
-        fit: 'contain',
-      });
-    });
-  });
- 
-  // ============================================================================
-  // STATIC DEFAULTS TESTS
-  // ============================================================================
- 
-  describe('Static Defaults', () => {
-    it('should provide correct static default values', () => {
-      const { getContext } = renderWithContext();
-      const context = getContext();
- 
-      expect(context.borderLessCards).toBe(false);
-      expect(context.disableToolbar).toBe(false);
-      expect(context.enableBreakPoint).toBe(true);
-      expect(context.enableDarkToggle).toBe(false);
-      expect(context.enableLayoutSwitch).toBe(true);
-      expect(context.enableQuickJump).toBe(true);
-      expect(context.focusActiveItemOnLoad).toBe(false);
-      expect(context.highlightCardsOnHover).toBe(false);
-      expect(context.lineWidth).toBe(3);
-      expect(context.nestedCardHeight).toBe(150);
-      expect(context.parseDetailsAsHTML).toBe(false);
-      expect(context.timelinePointDimension).toBe(16);
-      expect(context.timelinePointShape).toBe('circle');
-      expect(context.titleDateFormat).toBe('MMM DD, YYYY');
-      expect(context.toolbarPosition).toBe('top');
-      expect(context.uniqueId).toBe('react-chrono');
-      expect(context.useReadMore).toBe(true);
-      expect(context.scrollable).toEqual({ scrollbar: false });
-    });
- 
-    it('should allow overriding static defaults', () => {
-      const { getContext } = renderWithContext({
-        borderLessCards: true,
-        lineWidth: 5,
-        uniqueId: 'custom-timeline',
-        timelinePointShape: 'square',
-      });
- 
-      const context = getContext();
-      expect(context.borderLessCards).toBe(true);
-      expect(context.lineWidth).toBe(5);
-      expect(context.uniqueId).toBe('custom-timeline');
-      expect(context.timelinePointShape).toBe('square');
-    });
-  });
- 
-  // ============================================================================
-  // SLIDESHOW & INTERACTION TESTS
-  // ============================================================================
- 
-  describe('Slideshow and Interactions', () => {
-    it('should compute slideshow type based on mode', () => {
-      mockGetSlideShowType.mockReturnValue('slide_in');
- 
-      const { getContext } = renderWithContext({ mode: 'HORIZONTAL' });
-      expect(getContext().slideShowType).toBe('slide_in');
-      expect(mockGetSlideShowType).toHaveBeenCalledWith('HORIZONTAL');
-    });
- 
-    it('should handle slideshow properties', () => {
-      const { getContext } = renderWithContext({
-        slideShow: true,
-      });
- 
-      expect(getContext().showProgressOnSlideshow).toBe(true);
-      expect(getContext().slideItemDuration).toBe(2000);
-    });
- 
-    it('should disable interactions when specified', () => {
-      const { getContext } = renderWithContext({
-        disableInteraction: true,
-      });
- 
-      expect(getContext().disableAutoScrollOnClick).toBe(true);
-      expect(getContext().disableClickOnCircle).toBe(true);
-      expect(getContext().disableTimelinePoint).toBe(true);
-      expect(getContext().disableInteraction).toBe(false); // This gets overridden
-    });
-  });
- 
-  // ============================================================================
-  // UTILITY FUNCTIONS INTEGRATION
-  // ============================================================================
- 
-  describe('Utility Functions Integration', () => {
-    it('should call utility functions with correct parameters', () => {
-      renderWithContext({
-        darkMode: true,
-        mode: 'VERTICAL',
-      });
- 
-      expect(mockGetDefaultButtonTexts).toHaveBeenCalled();
-      expect(mockGetDefaultClassNames).toHaveBeenCalled();
-      expect(mockGetDefaultThemeOrDark).toHaveBeenCalledWith(true);
-      expect(mockGetSlideShowType).toHaveBeenCalledWith('VERTICAL');
-    });
- 
-    it('should handle utility function responses', () => {
-      const customButtonTexts = { play: 'Custom Play' };
-      const customTheme = { primary: '#custom' };
- 
-      mockGetDefaultButtonTexts.mockReturnValue(customButtonTexts);
-      mockGetDefaultThemeOrDark.mockReturnValue(customTheme);
- 
-      const { getContext } = renderWithContext();
- 
-      expect(getContext().buttonTexts).toEqual(customButtonTexts);
-      expect(getContext().theme).toEqual(customTheme);
-    });
-  });
- 
-  // ============================================================================
-  // EDGE CASES & ERROR HANDLING
-  // ============================================================================
- 
-  describe('Edge Cases', () => {
-    it('should handle undefined items array', () => {
-      const { getContext } = renderWithContext({
-        items: undefined,
-        flipLayout: true,
-      });
-      expect(getContext().activeItemIndex).toBe(-1);
-    });
- 
-    it('should handle empty items array', () => {
-      const { getContext } = renderWithContext({
-        items: [],
-        flipLayout: true,
-      });
-      expect(getContext().activeItemIndex).toBe(-1);
-    });
- 
-    it('should handle very large content details height', () => {
-      const { getContext } = renderWithContext({
-        cardHeight: 100,
-        contentDetailsHeight: 500,
-        mediaHeight: 50,
-      });
-      // Should be clamped appropriately
-      expect(getContext().contentDetailsHeight).toBeGreaterThan(0);
-    });
- 
-    it('should provide all required callback functions', () => {
-      const { getContext } = renderWithContext();
-      const context = getContext();
- 
-      expect(typeof context.toggleDarkMode).toBe('function');
-      expect(typeof context.updateHorizontalAllCards).toBe('function');
-      expect(typeof context.updateTextContentDensity).toBe('function');
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/__tests__/index.html b/coverage/lcov-report/components/__tests__/index.html deleted file mode 100644 index 0cda88567..000000000 --- a/coverage/lcov-report/components/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/__tests__ - - - - - - - - - -
-
-

All files components/__tests__

-
- -
- 100% - Statements - 553/553 -
- - -
- 98.8% - Branches - 83/84 -
- - -
- 100% - Functions - 11/11 -
- - -
- 100% - Lines - 553/553 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
GlobalContext.test.tsx -
-
100%553/55398.8%83/84100%11/11100%553/553
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/common/styles/index.html b/coverage/lcov-report/components/common/styles/index.html deleted file mode 100644 index bbe02ab31..000000000 --- a/coverage/lcov-report/components/common/styles/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/common/styles - - - - - - - - - -
-
-

All files components/common/styles

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 3/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
100%5/5100%3/3100%0/0100%5/5
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/common/styles/index.ts.html b/coverage/lcov-report/components/common/styles/index.ts.html deleted file mode 100644 index a32b7bffc..000000000 --- a/coverage/lcov-report/components/common/styles/index.ts.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for components/common/styles/index.ts - - - - - - - - - -
-
-

All files / components/common/styles index.ts

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 3/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21  -1x -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  - 
import { Theme } from '@models/Theme';
-import { css } from 'styled-components';
- 
-export const ScrollBar = css<{ theme: Theme }>`
-  scrollbar-color: ${(p) => p.theme?.primary} default;
-  scrollbar-width: thin;
- 
-  &::-webkit-scrollbar {
-    width: 0.3em;
-  }
- 
-  &::-webkit-scrollbar-track {
-    box-shadow: inset 0 0 6px rgba(0, 0, 0, 0.2);
-  }
- 
-  &::-webkit-scrollbar-thumb {
-    background-color: ${(p) => p.theme?.primary};
-    outline: 1px solid ${(p) => p.theme?.primary};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/common/themes/index.html b/coverage/lcov-report/components/common/themes/index.html deleted file mode 100644 index ba96206f5..000000000 --- a/coverage/lcov-report/components/common/themes/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/common/themes - - - - - - - - - -
-
-

All files components/common/themes

-
- -
- 100% - Statements - 74/74 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 74/74 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
100%74/74100%0/0100%0/0100%74/74
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/common/themes/index.ts.html b/coverage/lcov-report/components/common/themes/index.ts.html deleted file mode 100644 index 76b17d58a..000000000 --- a/coverage/lcov-report/components/common/themes/index.ts.html +++ /dev/null @@ -1,328 +0,0 @@ - - - - - - Code coverage report for components/common/themes/index.ts - - - - - - - - - -
-
-

All files / components/common/themes index.ts

-
- -
- 100% - Statements - 74/74 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 74/74 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { Theme } from '@models/Theme';
- 
-export const defaultTheme: Theme = {
-  cardBgColor: '#ffffff',
-  cardDetailsBackGround: '#ffffff',
-  cardDetailsColor: '#374151',
-  cardMediaBgColor: '#f8fafc',
-  cardSubtitleColor: '#6b7280',
-  cardTitleColor: '#007FFF',
-  detailsColor: '#374151',
-  iconBackgroundColor: '#007FFF',
-  nestedCardBgColor: '#f8fafc',
-  nestedCardDetailsBackGround: '#f8fafc',
-  nestedCardDetailsColor: '#374151',
-  nestedCardSubtitleColor: '#6b7280',
-  nestedCardTitleColor: '#1f2937',
-  primary: '#007FFF',
-  secondary: '#ffdf00',
-  titleColor: '#007FFF',
-  titleColorActive: '#007FFF',
-  toolbarBgColor: '#f1f5f9',
-  toolbarBtnBgColor: '#ffffff',
-  toolbarTextColor: '#1e293b',
-  timelineBgColor: '#ffffff',
- 
-  // Light mode styling
-  iconColor: '#007FFF',
-  buttonHoverBgColor: '#e2e8f0',
-  buttonActiveBgColor: '#007FFF',
-  buttonActiveIconColor: '#ffffff',
-  buttonBorderColor: '#e2e8f0',
-  buttonHoverBorderColor: '#007FFF',
-  buttonActiveBorderColor: '#007FFF',
-  shadowColor: 'rgba(0, 0, 0, 0.1)',
-  glowColor: 'rgba(0, 127, 255, 0.2)',
-  searchHighlightColor: 'rgba(0, 127, 255, 0.2)',
-  darkToggleActiveBgColor: '#007FFF',
-  darkToggleActiveIconColor: '#ffffff',
-  darkToggleActiveBorderColor: '#007FFF',
-  darkToggleGlowColor: 'rgba(0, 127, 255, 0.2)',
-};
- 
-export const darkTheme: Theme = {
-  cardBgColor: '#1f2937',
-  cardDetailsBackGround: '#1f2937',
-  cardDetailsColor: '#f3f4f6',
-  cardMediaBgColor: '#111827',
-  cardSubtitleColor: '#d1d5db',
-  cardTitleColor: '#60a5fa',
-  detailsColor: '#f3f4f6',
-  iconBackgroundColor: '#3b82f6',
-  nestedCardBgColor: '#111827',
-  nestedCardDetailsBackGround: '#111827',
-  nestedCardDetailsColor: '#f3f4f6',
-  nestedCardSubtitleColor: '#d1d5db',
-  nestedCardTitleColor: '#f9fafb',
-  primary: '#3b82f6',
-  secondary: '#fbbf24',
-  titleColor: '#60a5fa',
-  titleColorActive: '#60a5fa',
-  toolbarBgColor: '#111827',
-  toolbarBtnBgColor: '#374151',
-  toolbarTextColor: '#f3f4f6',
-  timelineBgColor: '#111827',
- 
-  // Dark mode styling - our enhanced colors as defaults
-  iconColor: '#93c5fd',
-  buttonHoverBgColor: '#4b5563',
-  buttonActiveBgColor: '#fbbf24',
-  buttonActiveIconColor: '#1f2937',
-  buttonBorderColor: 'rgba(255, 255, 255, 0.1)',
-  buttonHoverBorderColor: '#3b82f6',
-  buttonActiveBorderColor: '#3b82f6',
-  shadowColor: 'rgba(0, 0, 0, 0.4)',
-  glowColor: 'rgba(59, 130, 246, 0.4)',
-  searchHighlightColor: 'rgba(96, 165, 250, 0.4)',
-  darkToggleActiveBgColor: '#1e40af',
-  darkToggleActiveIconColor: '#e2e8f0',
-  darkToggleActiveBorderColor: '#3b82f6',
-  darkToggleGlowColor: 'rgba(59, 130, 246, 0.4)',
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/contexts/DynamicContext.tsx.html b/coverage/lcov-report/components/contexts/DynamicContext.tsx.html deleted file mode 100644 index d37c2420c..000000000 --- a/coverage/lcov-report/components/contexts/DynamicContext.tsx.html +++ /dev/null @@ -1,256 +0,0 @@ - - - - - - Code coverage report for components/contexts/DynamicContext.tsx - - - - - - - - - -
-
-

All files / components/contexts DynamicContext.tsx

-
- -
- 100% - Statements - 33/33 -
- - -
- 100% - Branches - 0/0 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 33/33 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
/**
- * Dynamic Context - Contains frequently changing values like state and interactions
- * This context is optimized for dynamic values that change often
- */
-import { createContext } from 'react';
-import { TextDensity } from '@models/TimelineModel';
-import { Theme } from '@models/Theme';
- 
-export interface DynamicContextProps {
-  // Dynamic state values
-  isDarkMode: boolean;
-  isMobile: boolean;
-  horizontalAll: boolean;
-  textContentDensity: TextDensity;
- 
-  // Theme (can change with dark mode)
-  memoizedTheme: Theme;
- 
-  // Interaction callbacks
-  toggleDarkMode?: () => void;
-  updateHorizontalAllCards?: (state: boolean) => void;
-  updateTextContentDensity?: (value: TextDensity) => void;
-}
- 
-export const DynamicContext = createContext<DynamicContextProps>({
-  isDarkMode: false,
-  isMobile: false,
-  horizontalAll: false,
-  textContentDensity: 'HIGH',
-  memoizedTheme: {
-    primary: '#007FFF',
-    secondary: '#ffdf00',
-    cardBgColor: '#ffffff',
-    cardDetailsBackGround: '#ffffff',
-    cardDetailsColor: '#000',
-    cardMediaBgColor: '#f5f5f5',
-    cardSubtitleColor: '#000',
-    cardTitleColor: '#007FFF',
-    detailsColor: '#000',
-    iconBackgroundColor: '#007FFF',
-    nestedCardBgColor: '#f5f5f5',
-    nestedCardDetailsBackGround: '#f5f5f5',
-    nestedCardDetailsColor: '#000',
-    nestedCardSubtitleColor: '#000',
-    nestedCardTitleColor: '#000',
-    titleColor: '#007FFF',
-    titleColorActive: '#007FFF',
-    toolbarBgColor: '#f5f5f5',
-    toolbarBtnBgColor: '#ffffff',
-    toolbarTextColor: '#000',
-    timelineBgColor: '#f5f5f5',
-  },
-  // Default no-op implementations to prevent fallback to legacy context
-  toggleDarkMode: () => {},
-  updateHorizontalAllCards: () => {},
-  updateTextContentDensity: () => {},
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/contexts/OptimizedContextProvider.tsx.html b/coverage/lcov-report/components/contexts/OptimizedContextProvider.tsx.html deleted file mode 100644 index c823042b8..000000000 --- a/coverage/lcov-report/components/contexts/OptimizedContextProvider.tsx.html +++ /dev/null @@ -1,1192 +0,0 @@ - - - - - - Code coverage report for components/contexts/OptimizedContextProvider.tsx - - - - - - - - - -
-
-

All files / components/contexts OptimizedContextProvider.tsx

-
- -
- 99.66% - Statements - 299/300 -
- - -
- 86.66% - Branches - 39/45 -
- - -
- 100% - Functions - 3/3 -
- - -
- 99.66% - Lines - 299/300 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -  -  -  -51x -51x -51x -51x -51x -51x -51x -  -  -51x -2x -2x -51x -  -51x -1x -51x -  -51x -1x -51x -  -  -51x -51x -51x -51x -  -51x -51x -51x -51x -  -  -  -  -51x -51x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -51x -51x -42x -51x -51x -  -51x -42x -42x -42x -  -42x -51x -  -51x -51x -51x -51x -  -51x -51x -51x -51x -  -51x -  -51x -51x -51x -51x -  -51x -51x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -42x -51x -51x -  -51x -51x -42x -42x -42x -42x -51x -51x -  -  -  -  -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -  -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -  -  -  -51x -51x -44x -44x -44x -51x -51x -  -51x -51x -48x -48x -48x -48x -48x -48x -48x -48x -48x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -51x -  -51x -51x -51x -51x -51x -51x -  -51x - 
/**
- * Optimized Context Provider - Splits stable and dynamic contexts for better performance
- */
-import React, {
-  FunctionComponent,
-  useCallback,
-  useMemo,
-  useState,
-} from 'react';
-import {
-  TimelineProps as PropsModel,
-  TextDensity,
-} from '@models/TimelineModel';
-import {
-  getDefaultButtonTexts,
-  getDefaultClassNames,
-  getDefaultThemeOrDark,
-  getSlideShowType,
-} from '@utils/index';
-import { useMatchMedia } from '../effects/useMatchMedia';
-import { StableContext, StableContextProps } from './StableContext';
-import { DynamicContext, DynamicContextProps } from './DynamicContext';
- 
-export type ContextProps = PropsModel & {
-  isMobile?: boolean;
-  toggleDarkMode?: () => void;
-  updateHorizontalAllCards?: (state: boolean) => void;
-  updateTextContentDensity?: (value: TextDensity) => void;
-};
- 
-interface OptimizedContextProviderProps extends Omit<ContextProps, 'children'> {
-  children: React.ReactNode;
-}
- 
-export const OptimizedContextProvider: FunctionComponent<
-  OptimizedContextProviderProps
-> = (props) => {
-  const {
-    cardHeight = 200,
-    cardLess = false,
-    flipLayout,
-    items = [],
-    theme,
-    buttonTexts,
-    classNames,
-    mode = 'VERTICAL_ALTERNATING',
-    fontSizes,
-    textOverlay,
-    darkMode,
-    slideShow,
-    onThemeChange,
-    mediaSettings,
-    mediaHeight = 200,
-    contentDetailsHeight = 10,
-    showAllCardsHorizontal,
-    textDensity = 'HIGH',
-    responsiveBreakPoint = 1024,
-    enableBreakPoint,
-    semanticTags,
-    children,
-  } = props;
- 
-  // ==========================================
-  // DYNAMIC STATE (changes frequently)
-  // ==========================================
-  const [isDarkMode, setIsDarkMode] = useState(darkMode);
-  const [horizontalAll, setHorizontalAll] = useState(
-    showAllCardsHorizontal ?? false,
-  );
-  const [isMobileDetected, setIsMobileDetected] = useState(false);
-  const [textContentDensity, setTextContentDensity] =
-    useState<TextDensity>(textDensity);
- 
-  // Dynamic callbacks
-  const toggleDarkMode = useCallback(() => {
-    setIsDarkMode(!isDarkMode);
-    onThemeChange?.();
-  }, [isDarkMode, onThemeChange]);
- 
-  const updateHorizontalAllCards = useCallback((state: boolean) => {
-    setHorizontalAll(state);
-  }, []);
- 
-  const updateTextContentDensity = useCallback((value: TextDensity) => {
-    setTextContentDensity(value);
-  }, []);
- 
-  // Responsive detection
-  useMatchMedia(`(max-width: ${responsiveBreakPoint - 1}px)`, {
-    onMatch: () => setIsMobileDetected(true),
-    enabled: enableBreakPoint,
-  });
- 
-  useMatchMedia(`(min-width: ${responsiveBreakPoint}px)`, {
-    onMatch: () => setIsMobileDetected(false),
-    enabled: enableBreakPoint,
-  });
- 
-  // ==========================================
-  // STABLE CONFIGURATION (rarely changes)
-  // ==========================================
-  const staticDefaults = useMemo(
-    () => ({
-      borderLessCards: props.borderLessCards ?? false,
-      cardLess: cardLess,
-      disableToolbar: props.disableToolbar ?? false,
-      enableBreakPoint: props.enableBreakPoint ?? true,
-      enableDarkToggle: props.enableDarkToggle ?? false,
-      enableLayoutSwitch: props.enableLayoutSwitch ?? true,
-      enableQuickJump: props.enableQuickJump ?? true,
-      focusActiveItemOnLoad: props.focusActiveItemOnLoad ?? false,
-      highlightCardsOnHover: props.highlightCardsOnHover ?? false,
-      lineWidth: props.lineWidth ?? 3,
-      mediaHeight: mediaHeight,
-      nestedCardHeight: props.nestedCardHeight ?? 150,
-      parseDetailsAsHTML: props.parseDetailsAsHTML ?? false,
-      scrollable: props.scrollable ?? {
-        scrollbar: false,
-      },
-      timelinePointDimension: props.timelinePointDimension ?? 16,
-      timelinePointShape: props.timelinePointShape ?? ('circle' as const),
-      titleDateFormat: props.titleDateFormat ?? 'MMM DD, YYYY',
-      toolbarPosition: props.toolbarPosition ?? ('top' as const),
-      uniqueId: props.uniqueId ?? 'react-chrono',
-      useReadMore: props.useReadMore ?? true,
-      disableTimelinePoint: props.disableTimelinePoint ?? false,
-      isChild: props.isChild ?? false,
-      noUniqueId: props.noUniqueId ?? false,
-    }),
-    [
-      props.borderLessCards,
-      cardLess,
-      props.disableToolbar,
-      props.enableBreakPoint,
-      props.enableDarkToggle,
-      props.enableLayoutSwitch,
-      props.enableQuickJump,
-      props.focusActiveItemOnLoad,
-      props.highlightCardsOnHover,
-      props.lineWidth,
-      mediaHeight,
-      props.nestedCardHeight,
-      props.parseDetailsAsHTML,
-      props.scrollable,
-      props.timelinePointDimension,
-      props.timelinePointShape,
-      props.titleDateFormat,
-      props.toolbarPosition,
-      props.uniqueId,
-      props.useReadMore,
-      props.disableTimelinePoint,
-      props.isChild,
-      props.noUniqueId,
-    ],
-  );
- 
-  const newCardHeight = useMemo(
-    () =>
-      Math.max((contentDetailsHeight ?? 0) + (mediaHeight ?? 0), cardHeight),
-    [contentDetailsHeight, mediaHeight, cardHeight],
-  );
- 
-  const newContentDetailsHeight = useMemo(() => {
-    const detailsHeightApprox = Math.round(newCardHeight * 0.75);
-    const actualContentDetailsHeight = contentDetailsHeight ?? 0;
-    return actualContentDetailsHeight > newCardHeight
-      ? Math.min(actualContentDetailsHeight, detailsHeightApprox)
-      : Math.max(actualContentDetailsHeight, detailsHeightApprox);
-  }, [newCardHeight, contentDetailsHeight]);
- 
-  const computedCardHeight = useMemo(
-    () => (cardLess ? (cardHeight ?? 80) : cardHeight),
-    [cardLess, cardHeight],
-  );
- 
-  const computedActiveItemIndex = useMemo(
-    () => (flipLayout ? items?.length - 1 : 0),
-    [flipLayout, items?.length],
-  );
- 
-  const computedSlideShowType = useMemo(() => getSlideShowType(mode), [mode]);
- 
-  const computedMediaAlign = useMemo(
-    () => (mode === 'VERTICAL' && !textOverlay ? 'left' : 'center'),
-    [mode, textOverlay],
-  );
- 
-  const memoizedButtonTexts = useMemo(
-    () => ({
-      ...getDefaultButtonTexts(),
-      ...buttonTexts,
-    }),
-    [buttonTexts],
-  );
- 
-  const memoizedClassNames = useMemo(
-    () => ({
-      ...getDefaultClassNames(),
-      ...classNames,
-    }),
-    [classNames],
-  );
- 
-  const memoizedFontSizes = useMemo(
-    () => ({
-      cardSubtitle: '0.85rem',
-      cardText: '1rem',
-      cardTitle: '1rem',
-      title: '1rem',
-      ...fontSizes,
-    }),
-    [fontSizes],
-  );
- 
-  const memoizedMediaSettings = useMemo(
-    () => ({
-      align: computedMediaAlign,
-      fit: 'cover' as const,
-      ...mediaSettings,
-    }),
-    [computedMediaAlign, mediaSettings],
-  );
- 
-  const memoizedSemanticTags = useMemo(
-    () => ({
-      cardTitle: 'span' as const,
-      cardSubtitle: 'span' as const,
-      ...semanticTags,
-    }),
-    [semanticTags],
-  );
- 
-  // ==========================================
-  // STABLE CONTEXT VALUE
-  // ==========================================
-  const stableContextValue = useMemo(
-    (): StableContextProps => ({
-      staticDefaults,
-      computedCardHeight,
-      computedActiveItemIndex,
-      computedSlideShowType,
-      computedMediaAlign,
-      newContentDetailsHeight,
-      memoizedButtonTexts,
-      memoizedClassNames,
-      memoizedFontSizes,
-      memoizedMediaSettings,
-      memoizedSemanticTags,
- 
-      // Pass through stable props
-      mode,
-      cardHeight,
-      flipLayout,
-      items,
-      fontSizes,
-      textOverlay,
-      mediaSettings,
-      responsiveBreakPoint,
-      enableBreakPoint,
-      slideItemDuration: props.slideItemDuration ?? 2000,
-      slideShowType: computedSlideShowType,
-      cardPositionHorizontal: props.cardPositionHorizontal,
-      disableNavOnKey: props.disableNavOnKey,
-      itemWidth: props.itemWidth ?? 200,
-      lineWidth: props.lineWidth ?? 3,
-      scrollable:
-        typeof props.scrollable === 'boolean' ? props.scrollable : true,
-      onScrollEnd: props.onScrollEnd,
-      toolbarPosition: props.toolbarPosition ?? 'top',
-      disableToolbar: props.disableToolbar ?? false,
-      cardWidth: props.cardWidth,
-      borderLessCards: props.borderLessCards ?? false,
-      disableAutoScrollOnClick: !!props.disableInteraction,
-      classNames: memoizedClassNames,
-      showProgressOnSlideshow: slideShow,
-      showOverallSlideshowProgress:
-        props.showOverallSlideshowProgress ?? slideShow,
-      disableInteraction: false,
-      highlightCardsOnHover: props.highlightCardsOnHover ?? false,
-      disableClickOnCircle: !!props.disableInteraction,
-      disableTimelinePoint: !!props.disableInteraction,
-      enableQuickJump: props.enableQuickJump ?? true,
-      enableLayoutSwitch: props.enableLayoutSwitch ?? true,
-      cardLess: cardLess,
-      useReadMore: props.useReadMore ?? true,
-    }),
-    [
-      staticDefaults,
-      computedCardHeight,
-      computedActiveItemIndex,
-      computedSlideShowType,
-      computedMediaAlign,
-      newContentDetailsHeight,
-      memoizedButtonTexts,
-      memoizedClassNames,
-      memoizedFontSizes,
-      memoizedMediaSettings,
-      memoizedSemanticTags,
-      mode,
-      cardHeight,
-      flipLayout,
-      items,
-      fontSizes,
-      textOverlay,
-      mediaSettings,
-      responsiveBreakPoint,
-      enableBreakPoint,
-      slideShow,
-      props.cardPositionHorizontal,
-      props.disableNavOnKey,
-      props.itemWidth,
-      props.lineWidth,
-      props.scrollable,
-      props.onScrollEnd,
-      props.toolbarPosition,
-      props.disableToolbar,
-      props.cardWidth,
-      props.borderLessCards,
-      props.disableInteraction,
-      props.highlightCardsOnHover,
-      props.enableQuickJump,
-      props.enableLayoutSwitch,
-      props.useReadMore,
-      props.showOverallSlideshowProgress,
-    ],
-  );
- 
-  // ==========================================
-  // DYNAMIC CONTEXT VALUE (theme changes with dark mode)
-  // ==========================================
-  const memoizedTheme = useMemo(
-    () => ({
-      ...getDefaultThemeOrDark(isDarkMode),
-      ...theme,
-    }),
-    [isDarkMode, theme],
-  );
- 
-  const dynamicContextValue = useMemo(
-    (): DynamicContextProps => ({
-      isDarkMode,
-      isMobile: isMobileDetected,
-      horizontalAll,
-      textContentDensity,
-      memoizedTheme,
-      toggleDarkMode,
-      updateHorizontalAllCards,
-      updateTextContentDensity,
-    }),
-    [
-      isDarkMode,
-      isMobileDetected,
-      horizontalAll,
-      textContentDensity,
-      memoizedTheme,
-      toggleDarkMode,
-      updateHorizontalAllCards,
-      updateTextContentDensity,
-    ],
-  );
- 
-  return (
-    <StableContext.Provider value={stableContextValue}>
-      <DynamicContext.Provider value={dynamicContextValue}>
-        {children}
-      </DynamicContext.Provider>
-    </StableContext.Provider>
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/contexts/StableContext.tsx.html b/coverage/lcov-report/components/contexts/StableContext.tsx.html deleted file mode 100644 index 8177c4bad..000000000 --- a/coverage/lcov-report/components/contexts/StableContext.tsx.html +++ /dev/null @@ -1,508 +0,0 @@ - - - - - - Code coverage report for components/contexts/StableContext.tsx - - - - - - - - - -
-
-

All files / components/contexts StableContext.tsx

-
- -
- 100% - Statements - 55/55 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 55/55 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
/**
- * Stable Context - Contains configuration values that rarely change
- * This context is optimized for stable values to reduce unnecessary re-renders
- */
-import { createContext } from 'react';
-import { TimelineProps, ButtonTexts } from '@models/TimelineModel';
- 
-export interface StableContextProps {
-  // Configuration that rarely changes
-  staticDefaults: {
-    borderLessCards: boolean;
-    cardLess: boolean;
-    disableTimelinePoint: boolean;
-    disableToolbar: boolean;
-    enableBreakPoint: boolean;
-    enableDarkToggle: boolean;
-    enableLayoutSwitch: boolean;
-    enableQuickJump: boolean;
-    focusActiveItemOnLoad: boolean;
-    highlightCardsOnHover: boolean;
-    isChild: boolean;
-    lineWidth: number;
-    mediaHeight: number;
-    nestedCardHeight: number;
-    noUniqueId: boolean;
-    parseDetailsAsHTML: boolean;
-    scrollable: boolean | { scrollbar: boolean };
-    showProgressOnSlideshow?: boolean;
-    showOverallSlideshowProgress?: boolean;
-    timelinePointDimension: number;
-    timelinePointShape: 'circle' | 'square' | 'diamond';
-    titleDateFormat: string;
-    toolbarPosition: 'top' | 'bottom';
-    uniqueId: string;
-    useReadMore: boolean;
-  };
- 
-  // Computed configuration values
-  computedCardHeight: number;
-  computedActiveItemIndex: number;
-  computedSlideShowType: string;
-  computedMediaAlign: string;
-  newContentDetailsHeight: number;
- 
-  // Memoized configuration objects
-  memoizedButtonTexts: ButtonTexts;
-  memoizedClassNames: Record<string, string>;
-  memoizedFontSizes: Record<string, string>;
-  memoizedMediaSettings: Record<string, any>;
-  memoizedSemanticTags: Record<string, string>;
- 
-  // Stable props from timeline
-  mode?: TimelineProps['mode'];
-  cardHeight?: number;
-  flipLayout?: boolean;
-  items?: TimelineProps['items'];
-  fontSizes?: TimelineProps['fontSizes'];
-  textOverlay?: boolean;
-  mediaSettings?: TimelineProps['mediaSettings'];
-  responsiveBreakPoint?: number;
-  enableBreakPoint?: boolean;
-  slideItemDuration?: number;
-  slideShowType?: string;
-  cardPositionHorizontal?: TimelineProps['cardPositionHorizontal'];
-  disableNavOnKey?: boolean;
-  itemWidth?: number;
-  lineWidth?: number;
-  scrollable?: boolean | { scrollbar: boolean };
-  onScrollEnd?: () => void;
-  toolbarPosition?: 'top' | 'bottom';
-  disableToolbar?: boolean;
-  cardWidth?: number;
-  borderLessCards?: boolean;
-  disableAutoScrollOnClick?: boolean;
-  classNames?: Record<string, string>;
-  showProgressOnSlideshow?: boolean;
-  showOverallSlideshowProgress?: boolean;
-  disableInteraction?: boolean;
-  highlightCardsOnHover?: boolean;
-  disableClickOnCircle?: boolean;
-  disableTimelinePoint?: boolean;
-  enableQuickJump?: boolean;
-  enableLayoutSwitch?: boolean;
-  cardLess?: boolean;
-  useReadMore?: boolean;
-}
- 
-export const StableContext = createContext<StableContextProps>({
-  staticDefaults: {
-    borderLessCards: false,
-    cardLess: false,
-    disableTimelinePoint: false,
-    disableToolbar: false,
-    enableBreakPoint: true,
-    enableDarkToggle: false,
-    enableLayoutSwitch: true,
-    enableQuickJump: true,
-    focusActiveItemOnLoad: false,
-    highlightCardsOnHover: false,
-    isChild: false,
-    lineWidth: 3,
-    mediaHeight: 200,
-    nestedCardHeight: 150,
-    noUniqueId: false,
-    parseDetailsAsHTML: false,
-    scrollable: { scrollbar: false },
-    showProgressOnSlideshow: true,
-    showOverallSlideshowProgress: true,
-    timelinePointDimension: 16,
-    timelinePointShape: 'circle',
-    titleDateFormat: 'MMM DD, YYYY',
-    toolbarPosition: 'top',
-    uniqueId: 'react-chrono',
-    useReadMore: true,
-  },
-  computedCardHeight: 200,
-  computedActiveItemIndex: 0,
-  computedSlideShowType: 'reveal',
-  computedMediaAlign: 'center',
-  newContentDetailsHeight: 150,
-  memoizedButtonTexts: {
-    first: 'First',
-    last: 'Last',
-    play: 'Play',
-    stop: 'Stop',
-    previous: 'Previous',
-    next: 'Next',
-    dark: 'Dark',
-    light: 'Light',
-    timelinePoint: 'Timeline Point',
-    searchPlaceholder: 'Search...',
-    searchAriaLabel: 'Search timeline',
-    clearSearch: 'Clear search',
-    nextMatch: 'Next match',
-    previousMatch: 'Previous match',
-  },
-  memoizedClassNames: {},
-  memoizedFontSizes: {},
-  memoizedMediaSettings: {},
-  memoizedSemanticTags: {},
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/contexts/hooks.tsx.html b/coverage/lcov-report/components/contexts/hooks.tsx.html deleted file mode 100644 index 8ac0337b2..000000000 --- a/coverage/lcov-report/components/contexts/hooks.tsx.html +++ /dev/null @@ -1,640 +0,0 @@ - - - - - - Code coverage report for components/contexts/hooks.tsx - - - - - - - - - -
-
-

All files / components/contexts hooks.tsx

-
- -
- 86.36% - Statements - 114/132 -
- - -
- 29.41% - Branches - 5/17 -
- - -
- 71.42% - Functions - 5/7 -
- - -
- 86.36% - Lines - 114/132 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186  -  -  -  -1x -1x -1x -  -  -1x -1x -  -  -  -  -  -  -  -1x -59x -59x -  -  -  -  -1x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -59x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -59x -  -  -  -59x -59x -59x -59x -  -  -  -  -59x -59x -59x -  -  -  -  -  -1x -58x -  -  -  -58x -58x -58x -58x -58x -58x -58x -  -  -  -  -  -  -  -  -  -  -  -1x -51x -51x -  -51x -51x -51x -51x -51x -  -  -  -  -  -1x - 
/**
- * Combined hooks for accessing both stable and dynamic contexts
- * This provides a convenient API while maintaining the optimization benefits
- */
-import { useContext } from 'react';
-import { StableContext, StableContextProps } from './StableContext';
-import { DynamicContext, DynamicContextProps } from './DynamicContext';
- 
-// Import the legacy context from the new file to avoid circular dependency
-import { LegacyGlobalContext } from './legacy-types';
-import { getDefaultButtonTexts, getDefaultClassNames } from '../../utils';
- 
-// Combined context type for compatibility
-export type CombinedContextProps = StableContextProps & DynamicContextProps;
- 
-/**
- * Hook to access legacy global context for fallback scenarios
- */
-const useLegacyGlobalContext = () => {
-  return useContext(LegacyGlobalContext);
-};
- 
-/**
- * Convert legacy context to stable context props
- */
-const convertLegacyToStable = (legacyContext: any): StableContextProps => {
-  return {
-    staticDefaults: {
-      borderLessCards: legacyContext?.borderLessCards ?? false,
-      cardLess: legacyContext?.cardLess ?? false,
-      disableTimelinePoint: legacyContext?.disableTimelinePoint ?? false,
-      disableToolbar: legacyContext?.disableToolbar ?? false,
-      enableBreakPoint: legacyContext?.enableBreakPoint ?? true,
-      enableDarkToggle: legacyContext?.enableDarkToggle ?? false,
-      enableLayoutSwitch: legacyContext?.enableLayoutSwitch ?? true,
-      enableQuickJump: legacyContext?.enableQuickJump ?? true,
-      focusActiveItemOnLoad: legacyContext?.focusActiveItemOnLoad ?? false,
-      highlightCardsOnHover: legacyContext?.highlightCardsOnHover ?? false,
-      isChild: legacyContext?.isChild ?? false,
-      lineWidth: legacyContext?.lineWidth ?? 3,
-      mediaHeight: legacyContext?.mediaHeight ?? 200,
-      nestedCardHeight: legacyContext?.nestedCardHeight ?? 150,
-      noUniqueId: legacyContext?.noUniqueId ?? false,
-      parseDetailsAsHTML: legacyContext?.parseDetailsAsHTML ?? false,
-      scrollable: legacyContext?.scrollable ?? { scrollbar: false },
-      timelinePointDimension: legacyContext?.timelinePointDimension ?? 16,
-      timelinePointShape: legacyContext?.timelinePointShape ?? 'circle',
-      titleDateFormat: legacyContext?.titleDateFormat ?? 'MMM DD, YYYY',
-      toolbarPosition: legacyContext?.toolbarPosition ?? 'top',
-      uniqueId: legacyContext?.uniqueId ?? 'react-chrono',
-      useReadMore: legacyContext?.useReadMore ?? true,
-    },
-    computedCardHeight: legacyContext?.cardHeight ?? 200,
-    computedActiveItemIndex: legacyContext?.activeItemIndex ?? 0,
-    computedSlideShowType: legacyContext?.slideShowType ?? 'reveal',
-    computedMediaAlign: legacyContext?.mediaAlign ?? 'center',
-    newContentDetailsHeight: legacyContext?.contentDetailsHeight ?? 150,
-    memoizedButtonTexts: {
-      ...getDefaultButtonTexts(),
-      ...legacyContext?.buttonTexts,
-    },
-    memoizedClassNames: {
-      ...getDefaultClassNames(),
-      ...legacyContext?.classNames,
-    },
-    memoizedFontSizes: legacyContext?.fontSizes ?? {},
-    memoizedMediaSettings: legacyContext?.mediaSettings ?? {},
-    memoizedSemanticTags: legacyContext?.semanticTags ?? {},
-    mode: legacyContext?.mode,
-    cardHeight: legacyContext?.cardHeight,
-    flipLayout: legacyContext?.flipLayout,
-    items: legacyContext?.items,
-    fontSizes: legacyContext?.fontSizes,
-    textOverlay: legacyContext?.textOverlay,
-    mediaSettings: legacyContext?.mediaSettings,
-    responsiveBreakPoint: legacyContext?.responsiveBreakPoint,
-    enableBreakPoint: legacyContext?.enableBreakPoint,
-    slideItemDuration: legacyContext?.slideItemDuration,
-    slideShowType: legacyContext?.slideShowType,
-    cardPositionHorizontal: legacyContext?.cardPositionHorizontal,
-    disableNavOnKey: legacyContext?.disableNavOnKey,
-    itemWidth: legacyContext?.itemWidth,
-    lineWidth: legacyContext?.lineWidth,
-    scrollable: legacyContext?.scrollable,
-    onScrollEnd: legacyContext?.onScrollEnd,
-    toolbarPosition: legacyContext?.toolbarPosition,
-    disableToolbar: legacyContext?.disableToolbar,
-    cardWidth: legacyContext?.cardWidth,
-    borderLessCards: legacyContext?.borderLessCards,
-    disableAutoScrollOnClick: legacyContext?.disableAutoScrollOnClick,
-    classNames: legacyContext?.classNames,
-    showProgressOnSlideshow: legacyContext?.showProgressOnSlideshow,
-    showOverallSlideshowProgress: legacyContext?.showOverallSlideshowProgress,
-    disableInteraction: legacyContext?.disableInteraction,
-    highlightCardsOnHover: legacyContext?.highlightCardsOnHover,
-    disableClickOnCircle: legacyContext?.disableClickOnCircle,
-    disableTimelinePoint: legacyContext?.disableTimelinePoint,
-    enableQuickJump: legacyContext?.enableQuickJump,
-    enableLayoutSwitch: legacyContext?.enableLayoutSwitch,
-    cardLess: legacyContext?.cardLess,
-    useReadMore: legacyContext?.useReadMore,
-  };
-};
- 
-/**
- * Convert legacy context to dynamic context props
- */
-const convertLegacyToDynamic = (legacyContext: any): DynamicContextProps => {
-  return {
-    isDarkMode: legacyContext?.darkMode ?? false,
-    isMobile: legacyContext?.isMobile ?? false,
-    horizontalAll: legacyContext?.showAllCardsHorizontal ?? false,
-    textContentDensity: legacyContext?.textDensity ?? 'HIGH',
-    memoizedTheme: legacyContext?.theme ?? {},
-    toggleDarkMode: legacyContext?.toggleDarkMode ?? (() => {}),
-    updateTextContentDensity:
-      legacyContext?.updateTextContentDensity ?? (() => {}),
-    updateHorizontalAllCards:
-      legacyContext?.updateHorizontalAllCards ?? (() => {}),
-  };
-};
- 
-/**
- * Hook to access stable configuration values
- * Use this when components only need configuration data
- */
-export const useStableContext = (): StableContextProps => {
-  const stableContext = useContext(StableContext);
- 
-  // Check if we have properly initialized optimized context
-  // The uniqueId being 'react-chrono' indicates default/uninitialized context
-  if (
-    stableContext &&
-    stableContext.staticDefaults.uniqueId !== 'react-chrono'
-  ) {
-    return stableContext;
-  }
- 
-  // Fallback to legacy context for tests and backward compatibility
-  const legacyContext = useLegacyGlobalContext();
-  return convertLegacyToStable(legacyContext);
-};
- 
-/**
- * Hook to access dynamic state values
- * Use this when components only need dynamic state
- */
-export const useDynamicContext = (): DynamicContextProps => {
-  const dynamicContext = useContext(DynamicContext);
- 
-  // Check if we have properly initialized optimized context
-  // If there's no toggleDarkMode function, it's likely uninitialized
-  if (
-    dynamicContext &&
-    dynamicContext.toggleDarkMode &&
-    typeof dynamicContext.toggleDarkMode === 'function'
-  ) {
-    return dynamicContext;
-  }
- 
-  // Fallback to legacy context for tests and backward compatibility
-  const legacyContext = useLegacyGlobalContext();
-  return convertLegacyToDynamic(legacyContext);
-};
- 
-/**
- * Hook to access both stable and dynamic contexts
- * Use this for components that need both types of data
- * This maintains backward compatibility with the old GlobalContext
- */
-export const useGlobalContext = (): CombinedContextProps => {
-  const stableContext = useContext(StableContext);
-  const dynamicContext = useContext(DynamicContext);
- 
-  return {
-    ...stableContext,
-    ...dynamicContext,
-  };
-};
- 
-/**
- * Legacy hook for backward compatibility
- * @deprecated Use useGlobalContext, useStableContext, or useDynamicContext instead
- */
-export const useTimelineContext = (): CombinedContextProps => useGlobalContext();
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/contexts/index.html b/coverage/lcov-report/components/contexts/index.html deleted file mode 100644 index 1d52e0bcf..000000000 --- a/coverage/lcov-report/components/contexts/index.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - Code coverage report for components/contexts - - - - - - - - - -
-
-

All files components/contexts

-
- -
- 96.38% - Statements - 507/526 -
- - -
- 70.96% - Branches - 44/62 -
- - -
- 61.53% - Functions - 8/13 -
- - -
- 96.38% - Lines - 507/526 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
DynamicContext.tsx -
-
100%33/33100%0/00%0/3100%33/33
OptimizedContextProvider.tsx -
-
99.66%299/30086.66%39/45100%3/399.66%299/300
StableContext.tsx -
-
100%55/55100%0/0100%0/0100%55/55
hooks.tsx -
-
86.36%114/13229.41%5/1771.42%5/786.36%114/132
index.tsx -
-
100%4/4100%0/0100%0/0100%4/4
legacy-types.tsx -
-
100%2/2100%0/0100%0/0100%2/2
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/contexts/index.tsx.html b/coverage/lcov-report/components/contexts/index.tsx.html deleted file mode 100644 index 2064d2a36..000000000 --- a/coverage/lcov-report/components/contexts/index.tsx.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for components/contexts/index.tsx - - - - - - - - - -
-
-

All files / components/contexts index.tsx

-
- -
- 100% - Statements - 4/4 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 4/4 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  - 
/**
- * Context index file - exports all context-related functionality
- */
-export { StableContext, type StableContextProps } from './StableContext';
-export { DynamicContext, type DynamicContextProps } from './DynamicContext';
-export {
-  useStableContext,
-  useDynamicContext,
-  useGlobalContext,
-  useTimelineContext,
-  type CombinedContextProps,
-} from './hooks';
- 
-// Import and re-export to work around module resolution issue
-import {
-  OptimizedContextProvider,
-  type ContextProps,
-} from './OptimizedContextProvider';
-export { OptimizedContextProvider };
-export type { ContextProps };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/contexts/legacy-types.tsx.html b/coverage/lcov-report/components/contexts/legacy-types.tsx.html deleted file mode 100644 index 2eac5c968..000000000 --- a/coverage/lcov-report/components/contexts/legacy-types.tsx.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - Code coverage report for components/contexts/legacy-types.tsx - - - - - - - - - -
-
-

All files / components/contexts legacy-types.tsx

-
- -
- 100% - Statements - 2/2 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 2/2 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
/**
- * Legacy context types and default functions
- * This file contains only type definitions and default functions to avoid circular dependencies
- */
-import { createContext } from 'react';
-import {
-  TimelineProps as PropsModel,
-  TextDensity,
-} from '@models/TimelineModel';
- 
-export type LegacyContextProps = PropsModel & {
-  isMobile?: boolean;
-  toggleDarkMode?: () => void;
-  updateHorizontalAllCards?: (state: boolean) => void;
-  updateTextContentDensity?: (value: TextDensity) => void;
-};
- 
-export interface ButtonTexts {
-  first?: string;
-  last?: string;
-  play?: string;
-  stop?: string;
-  previous?: string;
-  next?: string;
-  dark?: string;
-  light?: string;
-  timelinePoint?: string;
-  searchPlaceholder?: string;
-  searchAriaLabel?: string;
-  clearSearch?: string;
-  nextMatch?: string;
-  previousMatch?: string;
-}
- 
-// Legacy context for backward compatibility - exported without circular dependency
-export const LegacyGlobalContext = createContext<LegacyContextProps>({});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/__tests__/index.html b/coverage/lcov-report/components/effects/__tests__/index.html deleted file mode 100644 index dac458b1f..000000000 --- a/coverage/lcov-report/components/effects/__tests__/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__ - - - - - - - - - -
-
-

All files components/effects/__tests__

-
- -
- 100% - Statements - 545/545 -
- - -
- 100% - Branches - 99/99 -
- - -
- 100% - Functions - 6/6 -
- - -
- 100% - Lines - 545/545 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useClickOutside.test.tsx -
-
100%60/60100%14/14100%2/2100%60/60
useMatchMedia.test.tsx -
-
100%126/126100%24/24100%1/1100%126/126
useNewScrollPosition.test.ts -
-
100%293/293100%51/51100%3/3100%293/293
useSlideshow.test.ts -
-
100%66/66100%10/10100%0/0100%66/66
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/__tests__/useClickOutside.test.tsx.html b/coverage/lcov-report/components/effects/__tests__/useClickOutside.test.tsx.html deleted file mode 100644 index 337dc502b..000000000 --- a/coverage/lcov-report/components/effects/__tests__/useClickOutside.test.tsx.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useClickOutside.test.tsx - - - - - - - - - -
-
-

All files / components/effects/__tests__ useClickOutside.test.tsx

-
- -
- 100% - Statements - 60/60 -
- - -
- 100% - Branches - 14/14 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 60/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -841x -1x -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -5x -5x -5x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -1x - 
import { renderHook } from '@testing-library/react';
-import { beforeEach, describe, expect, it, vi } from 'vitest';
- 
-import useCloseClickOutside from '../useCloseClickOutside';
-import useOutsideClick from '../../../hooks/useOutsideClick';
-import useEscapeKey from '../../../hooks/useEscapeKey';
- 
-// Mock the imported hooks
-vi.mock('../../../hooks/useOutsideClick');
-vi.mock('../../../hooks/useEscapeKey');
- 
-describe('useCloseClickOutside', () => {
-  beforeEach(() => {
-    vi.clearAllMocks();
-    vi.mocked(useOutsideClick).mockImplementation(() => {});
-    vi.mocked(useEscapeKey).mockImplementation(() => {});
-  });
- 
-  it('initializes both hooks with correct parameters', () => {
-    const callback = vi.fn();
-    const ref = { current: document.createElement('div') };
- 
-    renderHook(() => useCloseClickOutside(ref, callback));
- 
-    expect(useOutsideClick).toHaveBeenCalledWith(ref, callback);
-    expect(useEscapeKey).toHaveBeenCalledWith(callback);
-  });
- 
-  it('passes updated callback to both hooks when callback changes', () => {
-    const callback1 = vi.fn();
-    const callback2 = vi.fn();
-    const ref = { current: document.createElement('div') };
- 
-    const { rerender } = renderHook(({ cb }) => useCloseClickOutside(ref, cb), {
-      initialProps: { cb: callback1 },
-    });
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref, callback1);
-    expect(useEscapeKey).toHaveBeenLastCalledWith(callback1);
- 
-    rerender({ cb: callback2 });
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref, callback2);
-    expect(useEscapeKey).toHaveBeenLastCalledWith(callback2);
-  });
- 
-  it('passes updated ref to useOutsideClick when ref changes', () => {
-    const callback = vi.fn();
-    const ref1 = { current: document.createElement('div') };
-    const ref2 = { current: document.createElement('div') };
- 
-    const { rerender } = renderHook(
-      ({ r }) => useCloseClickOutside(r, callback),
-      { initialProps: { r: ref1 } },
-    );
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref1, callback);
- 
-    rerender({ r: ref2 });
- 
-    expect(useOutsideClick).toHaveBeenLastCalledWith(ref2, callback);
-  });
- 
-  it('handles null ref correctly', () => {
-    const callback = vi.fn();
-    const nullRef = { current: null };
- 
-    renderHook(() => useCloseClickOutside(nullRef, callback));
- 
-    expect(useOutsideClick).toHaveBeenCalledWith(nullRef, callback);
-    expect(useEscapeKey).toHaveBeenCalledWith(callback);
-  });
- 
-  it('handles undefined ref correctly', () => {
-    const callback = vi.fn();
-    const undefinedRef = { current: undefined };
- 
-    renderHook(() => useCloseClickOutside(undefinedRef, callback));
- 
-    expect(useOutsideClick).toHaveBeenCalledWith(undefinedRef, callback);
-    expect(useEscapeKey).toHaveBeenCalledWith(callback);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/__tests__/useMatchMedia.test.tsx.html b/coverage/lcov-report/components/effects/__tests__/useMatchMedia.test.tsx.html deleted file mode 100644 index 7e9aaa664..000000000 --- a/coverage/lcov-report/components/effects/__tests__/useMatchMedia.test.tsx.html +++ /dev/null @@ -1,595 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useMatchMedia.test.tsx - - - - - - - - - -
-
-

All files / components/effects/__tests__ useMatchMedia.test.tsx

-
- -
- 100% - Statements - 126/126 -
- - -
- 100% - Branches - 24/24 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 126/126 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -1711x -1x -1x -  -  -19x -19x -19x -19x -  -  -  -  -  -  -19x -19x -19x -19x -  -19x -  -1x -1x -1x -1x -  -1x -9x -9x -  -9x -8x -8x -8x -9x -  -9x -1x -  -1x -9x -9x -9x -9x -9x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -  -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x - 
import { render, act } from '@testing-library/react';
-import { useMatchMedia } from '../useMatchMedia';
-import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
- 
-// Test component with updated API
-function TestComponent({
-  query,
-  options = {},
-}: {
-  query: string;
-  options?: {
-    enabled?: boolean;
-    onMatch?: () => void;
-    debounceDelay?: number;
-  };
-}) {
-  const matches = useMatchMedia(query, options);
-  return (
-    <div data-testid="result">{matches ? 'Matches' : 'Does not match'}</div>
-  );
-}
- 
-describe('useMatchMedia', () => {
-  let matchMediaMock: any;
-  let addEventListenerSpy: any;
-  let removeEventListenerSpy: any;
- 
-  beforeEach(() => {
-    addEventListenerSpy = vi.fn();
-    removeEventListenerSpy = vi.fn();
- 
-    matchMediaMock = vi.fn().mockImplementation((query) => ({
-      matches: query === '(min-width: 800px)',
-      addEventListener: addEventListenerSpy,
-      removeEventListener: removeEventListenerSpy,
-    }));
- 
-    window.matchMedia = matchMediaMock;
-  });
- 
-  afterEach(() => {
-    vi.clearAllMocks();
-    vi.useRealTimers();
-    matchMediaMock.mockClear();
-    addEventListenerSpy.mockClear();
-    removeEventListenerSpy.mockClear();
-  });
- 
-  it('returns true if the query matches', () => {
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 800px)" />,
-    );
-    expect(getByTestId('result')).toHaveTextContent('Matches');
-  });
- 
-  it('returns false if the query does not match', () => {
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 1000px)" />,
-    );
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-  });
- 
-  it('returns false if the hook is disabled', () => {
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 800px)" options={{ enabled: false }} />,
-    );
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-  });
- 
-  it('calls onMatch callback when query matches', () => {
-    const onMatch = vi.fn();
-    render(<TestComponent query="(min-width: 800px)" options={{ onMatch }} />);
-    expect(onMatch).toHaveBeenCalledTimes(1);
-  });
- 
-  it('handles media query changes', () => {
-    let changeCallback: (event: { matches: boolean }) => void;
- 
-    addEventListenerSpy.mockImplementation((event, cb) => {
-      changeCallback = cb;
-    });
- 
-    const { getByTestId } = render(
-      <TestComponent query="(min-width: 800px)" />,
-    );
- 
-    act(() => {
-      changeCallback({ matches: false });
-    });
- 
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-  });
- 
-  it('handles resize events with debounce', async () => {
-    vi.useFakeTimers();
- 
-    const { getByTestId } = render(
-      <TestComponent
-        query="(min-width: 800px)"
-        options={{ debounceDelay: 100 }}
-      />,
-    );
- 
-    act(() => {
-      window.dispatchEvent(new Event('resize'));
-    });
- 
-    act(() => {
-      vi.advanceTimersByTime(100);
-    });
- 
-    expect(getByTestId('result')).toHaveTextContent('Matches');
- 
-    vi.useRealTimers();
-  });
- 
-  it('handles errors in matchMedia gracefully', () => {
-    const originalMatchMedia = window.matchMedia;
-    const consoleErrorSpy = vi
-      .spyOn(console, 'error')
-      .mockImplementation(() => {});
- 
-    window.matchMedia = vi.fn().mockImplementation(() => {
-      throw new Error('matchMedia error');
-    });
- 
-    const { getByTestId, unmount } = render(
-      <TestComponent query="(min-width: 800px)" />,
-    );
- 
-    expect(getByTestId('result')).toHaveTextContent('Does not match');
-    expect(consoleErrorSpy).toHaveBeenCalled();
- 
-    unmount();
-    consoleErrorSpy.mockRestore();
-    window.matchMedia = originalMatchMedia;
-  });
- 
-  it('respects maxWait option for resize debounce', async () => {
-    vi.useFakeTimers();
- 
-    const { getByTestId } = render(
-      <TestComponent
-        query="(min-width: 800px)"
-        options={{ debounceDelay: 2000 }} // Long delay to test maxWait
-      />,
-    );
- 
-    act(() => {
-      window.dispatchEvent(new Event('resize'));
-    });
- 
-    // maxWait is 1000ms, so this should trigger an update
-    act(() => {
-      vi.advanceTimersByTime(1000);
-    });
- 
-    expect(getByTestId('result')).toHaveTextContent('Matches');
- 
-    vi.useRealTimers();
-  });
- 
-  it('handles cleanup on query change', () => {
-    const { rerender } = render(<TestComponent query="(min-width: 800px)" />);
- 
-    rerender(<TestComponent query="(min-width: 1000px)" />);
- 
-    expect(removeEventListenerSpy).toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/__tests__/useNewScrollPosition.test.ts.html b/coverage/lcov-report/components/effects/__tests__/useNewScrollPosition.test.ts.html deleted file mode 100644 index 6219bf062..000000000 --- a/coverage/lcov-report/components/effects/__tests__/useNewScrollPosition.test.ts.html +++ /dev/null @@ -1,1228 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useNewScrollPosition.test.ts - - - - - - - - - -
-
-

All files / components/effects/__tests__ useNewScrollPosition.test.ts

-
- -
- 100% - Statements - 293/293 -
- - -
- 100% - Branches - 51/51 -
- - -
- 100% - Functions - 3/3 -
- - -
- 100% - Lines - 293/293 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -3821x -1x -1x -  -  -  -  -1x -13x -13x -13x -13x -13x -13x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -2x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -2x -1x -  -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -3x -1x -1x -1x -1x -  -1x -  -  -1x -1x -  -  -1x -  -  -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -1x -  -  -1x -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it} from 'vitest';
-import useNewScrollPosition from '../useNewScrollPosition';
-import { TimelineMode } from '../../../models/TimelineModel';
-import { Scroll } from '../../../models/TimelineHorizontalModel';
- 
-// Mock HTML element methods
-const createMockElement = (overrides = {}) => ({
-  clientWidth: 800,
-  clientHeight: 600,
-  scrollLeft: 0,
-  scrollTop: 0,
-  ...overrides,
-}) as HTMLElement;
- 
-describe('useNewScrollPosition', () => {
-  describe('Horizontal Mode', () => {
-    it('should initialize with offset 0', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      expect(result.current[0]).toBe(0);
-      expect(typeof result.current[1]).toBe('function');
-    });
- 
-    it('should compute horizontal offset when point is not visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [newOffset, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 1000, // Far to the right, not visible
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      // Should set new offset to point offset - item width
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(800); // 1000 - 200
-    });
- 
-    it('should compute horizontal offset when point is partially visible on the left', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 300,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 250, // Partially visible on the left
-        pointWidth: 100,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // No offset since leftGap is negative
-    });
- 
-    it('should compute horizontal offset when point is partially visible on the right', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 850, // Partially visible on the right
-        pointWidth: 100,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(650); // 850 - 200
-    });
- 
-    it('should not update offset when point is fully visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 400, // Fully visible
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // Should remain 0, no update needed
-    });
- 
-    it('should handle edge case when left gap is within item width', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 300,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 450, // Left gap = 150, which is < itemWidth (200)
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(250); // 450 - 200
-    });
- 
-    it('should handle edge case when right gap is within item width', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollLeft: 100,
-        clientWidth: 800,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 750, // Right gap = 150, which is < itemWidth (200)
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(550); // 750 - 200
-    });
-  });
- 
-  describe('Vertical Mode', () => {
-    it('should compute vertical offset when content is not visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 100,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 1000, // Far down, not visible
-        contentHeight: 200,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(800); // 1000 - 200 (nOffset)
-    });
- 
-    it('should compute vertical offset when content is partially visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 300,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 850, // Partially visible
-        contentHeight: 200,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(750); // 850 - 200 + 100 (half height)
-    });
- 
-    it('should handle vertical content that extends beyond visible area', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 100,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 800,
-        contentHeight: 300,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(500); // 800 - 300 (since nOffset + contentHeight >= contrBottom)
-    });
- 
-    it('should not update offset when content is fully visible', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 200,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 400, // Fully visible
-        contentHeight: 150,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // Should remain 0, no update needed
-    });
-  });
- 
-  describe('Vertical Alternating Mode', () => {
-    it('should work the same as vertical mode', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('VERTICAL_ALTERNATING')
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement({
-        scrollTop: 100,
-        clientHeight: 600,
-      });
-      
-      const scroll: Partial<Scroll> = {
-        contentOffset: 1000,
-        contentHeight: 200,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(800); // Same calculation as vertical mode
-    });
-  });
- 
-  describe('Edge Cases', () => {
-    it('should handle missing itemWidth for horizontal mode', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL') // No itemWidth provided
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement();
-      
-      const scroll: Partial<Scroll> = {
-        pointOffset: 1000,
-        pointWidth: 50,
-      };
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(0); // Should not update without itemWidth
-    });
- 
-    it('should handle undefined scroll values', () => {
-      const { result } = renderHook(() =>
-        useNewScrollPosition('HORIZONTAL', 200)
-      );
-      
-      const [, computeNewOffset] = result.current;
-      const mockElement = createMockElement();
-      
-      const scroll: Partial<Scroll> = {}; // Empty scroll object
- 
-      act(() => {
-        computeNewOffset(mockElement, scroll);
-      });
- 
-      const [updatedOffset] = result.current;
-      expect(updatedOffset).toBe(-200); // pointOffset = 0, so 0 - 200
-    });
- 
-    it('should memoize computeNewOffset function based on dependencies', () => {
-      const { result, rerender } = renderHook(
-        ({ mode, itemWidth }: { mode: TimelineMode; itemWidth?: number }) =>
-          useNewScrollPosition(mode, itemWidth),
-        {
-          initialProps: { mode: 'HORIZONTAL' as TimelineMode, itemWidth: 200 },
-        }
-      );
-      
-      const firstComputeFunction = result.current[1];
-      
-      // Re-render with same props
-      rerender({ mode: 'HORIZONTAL', itemWidth: 200 });
-      const secondComputeFunction = result.current[1];
-      
-      // Functions should be the same (memoized)
-      expect(firstComputeFunction).toBe(secondComputeFunction);
-      
-      // Re-render with different itemWidth
-      rerender({ mode: 'HORIZONTAL', itemWidth: 300 });
-      const thirdComputeFunction = result.current[1];
-      
-      // Function should be different now
-      expect(firstComputeFunction).not.toBe(thirdComputeFunction);
-    });
- 
-    it('should handle mode changes properly', () => {
-      const { result, rerender } = renderHook(
-        ({ mode }: { mode: TimelineMode }) => useNewScrollPosition(mode, 200),
-        {
-          initialProps: { mode: 'HORIZONTAL' as TimelineMode },
-        }
-      );
-      
-      const firstComputeFunction = result.current[1];
-      
-      // Change mode
-      rerender({ mode: 'VERTICAL' });
-      const secondComputeFunction = result.current[1];
-      
-      // Function should be different due to mode change
-      expect(firstComputeFunction).not.toBe(secondComputeFunction);
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/__tests__/useSlideshow.test.ts.html b/coverage/lcov-report/components/effects/__tests__/useSlideshow.test.ts.html deleted file mode 100644 index fdf505c09..000000000 --- a/coverage/lcov-report/components/effects/__tests__/useSlideshow.test.ts.html +++ /dev/null @@ -1,322 +0,0 @@ - - - - - - Code coverage report for components/effects/__tests__/useSlideshow.test.ts - - - - - - - - - -
-
-

All files / components/effects/__tests__ useSlideshow.test.ts

-
- -
- 100% - Statements - 66/66 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 66/66 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80  -1x -1x -1x -  -1x -1x -  -1x -  -1x -3x -3x -3x -  -1x -3x -3x -3x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -2x -2x -2x -2x -2x -2x -2x -2x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x - 
// Test setup
-import { act, renderHook } from '@testing-library/react';
-import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
-import { useSlideshow } from '../useSlideshow';
- 
-const slideItemDuration = 5000;
-const onElapsed = vi.fn();
- 
-let container = null;
- 
-beforeEach(() => {
-  container = document.createElement('div');
-  document.body.appendChild(container);
-});
- 
-afterEach(() => {
-  document.body.removeChild(container);
-  vi.clearAllMocks();
-});
- 
-describe('useSlideshow', () => {
-  it('should initialize properly', () => {
-    const { result } = renderHook(() =>
-      useSlideshow(
-        { current: container },
-        true,
-        true,
-        slideItemDuration,
-        '1',
-        onElapsed,
-      ),
-    );
- 
-    expect(result.current.paused).toBe(false);
-    expect(result.current.remainInterval).toBe(0);
-    expect(result.current.startWidth).toBe(0);
-  });
- 
-  it('should set up timer correctly', async () => {
-    const { result } = renderHook(() =>
-      useSlideshow(
-        { current: container },
-        true,
-        true,
-        slideItemDuration,
-        '1',
-        onElapsed,
-      ),
-    );
- 
-    expect(result.current.tryPause).toBeDefined();
-    expect(result.current.tryResume).toBeDefined();
-    expect(result.current.setStartWidth).toBeDefined();
-    expect(result.current.setupTimer).toBeDefined();
-    expect(result.current.startWidth).toBe(0);
-    expect(result.current.paused).toBe(false);
-  });
- 
-  it('should pause slideshow', () => {
-    const { result } = renderHook(() =>
-      useSlideshow(
-        { current: container },
-        true,
-        true,
-        slideItemDuration,
-        '1',
-        onElapsed,
-      ),
-    );
- 
-    expect(result.current.paused).toBe(false);
- 
-    act(() => {
-      result.current.tryPause();
-    });
- 
-    expect(result.current.paused).toBe(true);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/index.html b/coverage/lcov-report/components/effects/index.html deleted file mode 100644 index 7ed440b07..000000000 --- a/coverage/lcov-report/components/effects/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/effects - - - - - - - - - -
-
-

All files components/effects

-
- -
- 80.07% - Statements - 213/266 -
- - -
- 85.96% - Branches - 49/57 -
- - -
- 100% - Functions - 7/7 -
- - -
- 80.07% - Lines - 213/266 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useCloseClickOutside.ts -
-
100%9/9100%1/1100%1/1100%9/9
useMatchMedia.ts -
-
96.61%57/5982.35%14/17100%2/296.61%57/59
useNewScrollPosition.ts -
-
100%84/8496.29%26/27100%3/3100%84/84
useSlideshow.ts -
-
55.26%63/11466.66%8/12100%1/155.26%63/114
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/useCloseClickOutside.ts.html b/coverage/lcov-report/components/effects/useCloseClickOutside.ts.html deleted file mode 100644 index 94141c0c2..000000000 --- a/coverage/lcov-report/components/effects/useCloseClickOutside.ts.html +++ /dev/null @@ -1,133 +0,0 @@ - - - - - - Code coverage report for components/effects/useCloseClickOutside.ts - - - - - - - - - -
-
-

All files / components/effects useCloseClickOutside.ts

-
- -
- 100% - Statements - 9/9 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 9/9 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17  -1x -1x -  -  -  -  -  -  -42x -42x -42x -42x -42x -42x -42x - 
import { RefObject } from 'react';
-import useOutsideClick from '../../hooks/useOutsideClick';
-import useEscapeKey from '../../hooks/useEscapeKey';
- 
-/**
- * Custom hook that handles click outside and escape key events
- * @param el - Reference to the DOM element to watch for outside clicks
- * @param callback - Function to call when a click outside or escape key is detected
- */
-export default function useCloseClickOutside(
-  el: RefObject<HTMLElement | null>,
-  callback: () => void,
-) {
-  useOutsideClick(el, callback);
-  useEscapeKey(callback);
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/useMatchMedia.ts.html b/coverage/lcov-report/components/effects/useMatchMedia.ts.html deleted file mode 100644 index 31a0f0f83..000000000 --- a/coverage/lcov-report/components/effects/useMatchMedia.ts.html +++ /dev/null @@ -1,421 +0,0 @@ - - - - - - Code coverage report for components/effects/useMatchMedia.ts - - - - - - - - - -
-
-

All files / components/effects useMatchMedia.ts

-
- -
- 96.61% - Statements - 57/59 -
- - -
- 82.35% - Branches - 14/17 -
- - -
- 100% - Functions - 2/2 -
- - -
- 96.61% - Lines - 57/59 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -1131x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -23x -23x -23x -23x -23x -23x -  -  -23x -23x -9x -9x -9x -23x -23x -  -23x -23x -1x -  -1x -1x -1x -23x -23x -23x -  -  -23x -14x -1x -1x -  -13x -  -  -14x -  -  -  -13x -13x -  -14x -5x -5x -  -  -8x -  -  -8x -  -  -8x -8x -8x -8x -8x -8x -8x -8x -23x -  -  -23x -23x -  -23x -21x -1x -1x -23x -  -23x -23x - 
import { useCallback, useEffect, useRef, useState } from 'react';
-import { useDebouncedCallback } from 'use-debounce';
-import {
-  createMediaQuery,
-  addMediaListeners,
-  removeMediaListeners,
-} from '../../utils/mediaQueryUtils';
- 
-/**
- * Configuration options for the useMatchMedia hook
- */
-interface MatchMediaOptions {
-  /** Callback function to execute when media query matches */
-  onMatch?: () => void;
-  /** Whether the hook is enabled */
-  enabled?: boolean;
-  /** Debounce delay in milliseconds */
-  debounceDelay?: number;
-}
- 
-/**
- * Custom hook that tracks if a media query matches and executes a callback on matches
- *
- * @param query - The media query string to match against
- * @param options - Configuration options
- * @returns Boolean indicating if the media query currently matches
- *
- * @example
- * ```tsx
- * const isMobile = useMatchMedia('(max-width: 768px)', {
- *   onMatch: () => console.log('Mobile view detected'),
- *   debounceDelay: 200
- * });
- * ```
- */
-export const useMatchMedia = (
-  query: string,
-  { onMatch, enabled = true, debounceDelay = 100 }: MatchMediaOptions = {},
-): boolean => {
-  const [matches, setMatches] = useState<boolean>(false);
-  const mediaQuery = useRef<MediaQueryList | null>(null);
-  const isCleanedUp = useRef<boolean>(false);
- 
-  // Stable callback references to prevent unnecessary effect re-runs
-  const handleMediaChange = useCallback(
-    (event: MediaQueryListEvent | MediaQueryList) => {
-      if (isCleanedUp.current) return;
-      setMatches(event.matches);
-    },
-    [],
-  );
- 
-  const handleResize = useDebouncedCallback(
-    () => {
-      if (!mediaQuery.current || isCleanedUp.current) return;
- 
-      const currentMatches = mediaQuery.current.matches;
-      setMatches(currentMatches);
-    },
-    debounceDelay,
-    { maxWait: 1000 },
-  );
- 
-  // Setup media query listener
-  useEffect(() => {
-    if (!enabled || typeof window === 'undefined') {
-      return;
-    }
- 
-    isCleanedUp.current = false;
- 
-    // Cleanup previous mediaQuery if it exists
-    if (mediaQuery.current) {
-      removeMediaListeners(mediaQuery.current, handleMediaChange, handleResize);
-    }
- 
-    mediaQuery.current = createMediaQuery(query);
-    const currentMedia = mediaQuery.current;
- 
-    if (!currentMedia) {
-      return;
-    }
- 
-    // Initial check
-    handleMediaChange(currentMedia);
- 
-    // Add event listeners
-    addMediaListeners(currentMedia, handleMediaChange, handleResize);
- 
-    // Cleanup
-    return () => {
-      isCleanedUp.current = true;
-      if (currentMedia) {
-        removeMediaListeners(currentMedia, handleMediaChange, handleResize);
-      }
-      handleResize.cancel(); // Cancel any pending debounced calls
-      mediaQuery.current = null; // Clear the ref
-    };
-  }, [query, enabled, handleMediaChange, handleResize]); // Removed createMediaQuery dependency to avoid infinite loops
- 
-  // Execute callback when matches changes - use ref to avoid stale closure
-  const onMatchRef = useRef(onMatch);
-  onMatchRef.current = onMatch;
- 
-  useEffect(() => {
-    if (matches && onMatchRef.current) {
-      onMatchRef.current();
-    }
-  }, [matches]);
- 
-  return matches;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/useNewScrollPosition.ts.html b/coverage/lcov-report/components/effects/useNewScrollPosition.ts.html deleted file mode 100644 index 35ba66460..000000000 --- a/coverage/lcov-report/components/effects/useNewScrollPosition.ts.html +++ /dev/null @@ -1,412 +0,0 @@ - - - - - - Code coverage report for components/effects/useNewScrollPosition.ts - - - - - - - - - -
-
-

All files / components/effects useNewScrollPosition.ts

-
- -
- 100% - Statements - 84/84 -
- - -
- 96.29% - Branches - 26/27 -
- - -
- 100% - Functions - 3/3 -
- - -
- 100% - Lines - 84/84 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110  -  -1x -  -  -  -  -  -  -  -  -1x -36x -36x -36x -  -36x -  -36x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -7x -6x -  -7x -7x -  -7x -7x -6x -4x -7x -5x -5x -7x -  -36x -5x -5x -5x -5x -5x -5x -5x -5x -  -5x -5x -5x -5x -  -5x -5x -  -5x -1x -5x -3x -3x -5x -  -  -36x -36x -13x -13x -13x -13x -13x -13x -13x -  -13x -7x -7x -7x -7x -7x -7x -7x -7x -13x -5x -5x -5x -5x -5x -5x -5x -5x -13x -36x -36x -  -  -36x -36x -  -1x - 
import { Scroll } from '@models/TimelineHorizontalModel';
-import { TimelineMode } from '@models/TimelineModel';
-import { useMemo, useState } from 'react';
- 
-/**
- * Hook to calculate the new scroll position based on the given mode and item width.
- *
- * @param {TimelineMode} mode - The mode of the timeline (HORIZONTAL, VERTICAL, or VERTICAL_ALTERNATING).
- * @param {number} [itemWidth] - Optional item width for horizontal mode.
- * @returns {[number, (e: HTMLElement, s: Partial<Scroll>) => void]} - The new offset and a function to compute the new offset.
- */
-const useNewScrollPosition = (
-  mode: TimelineMode,
-  itemWidth?: number,
-): [number, (e: HTMLElement, s: Partial<Scroll>) => void] => {
-  // State to hold the new offset value
-  const [newOffset, setNewOffset] = useState(0);
- 
-  const computeHorizontalOffset = (
-    scrollLeft: number,
-    clientWidth: number,
-    pointOffset: number,
-    pointWidth: number,
-    itemWidth: number,
-    setNewOffset: (offset: number) => void,
-  ) => {
-    const contrRight = scrollLeft + clientWidth;
-    const circRight = pointOffset + pointWidth;
- 
-    const isVisible = pointOffset >= scrollLeft && circRight <= contrRight;
-    const isPartiallyVisible =
-      (pointOffset < scrollLeft && circRight > scrollLeft) ||
-      (circRight > contrRight && pointOffset < contrRight);
- 
-    const leftGap = pointOffset - scrollLeft;
-    const rightGap = contrRight - pointOffset;
- 
-    if (
-      !(isVisible || isPartiallyVisible) ||
-      (leftGap <= itemWidth && leftGap >= 0) ||
-      (rightGap <= itemWidth && rightGap >= 0)
-    ) {
-      setNewOffset(pointOffset - itemWidth);
-    }
-  };
- 
-  const computeVerticalOffset = (
-    scrollTop: number,
-    clientHeight: number,
-    contentOffset: number,
-    contentHeight: number,
-    setNewOffset: (offset: number) => void,
-  ) => {
-    const contrBottom = scrollTop + clientHeight;
-    const circBottom = contentOffset + contentHeight;
- 
-    const isVisible = contentOffset >= scrollTop && circBottom <= contrBottom;
-    const isPartiallyVisible =
-      (contentOffset < scrollTop && circBottom > scrollTop) ||
-      (circBottom > contrBottom && contentOffset < contrBottom);
- 
-    const nOffset = contentOffset - contentHeight;
-    const notVisible = !isVisible || isPartiallyVisible;
- 
-    if (notVisible && nOffset + contentHeight < contrBottom) {
-      setNewOffset(nOffset + Math.round(contentHeight / 2));
-    } else if (notVisible) {
-      setNewOffset(nOffset);
-    }
-  };
- 
-  // Memoized function to compute the new offset value
-  const computeNewOffset = useMemo(
-    () => (parent: HTMLElement, scroll: Partial<Scroll>) => {
-      const { clientWidth, scrollLeft, scrollTop, clientHeight } = parent;
-      const {
-        pointOffset = 0,
-        pointWidth = 0,
-        contentHeight = 0,
-        contentOffset = 0,
-      } = scroll;
- 
-      if (mode === 'HORIZONTAL' && itemWidth) {
-        computeHorizontalOffset(
-          scrollLeft,
-          clientWidth,
-          pointOffset,
-          pointWidth,
-          itemWidth,
-          setNewOffset,
-        );
-      } else if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        computeVerticalOffset(
-          scrollTop,
-          clientHeight,
-          contentOffset,
-          contentHeight,
-          setNewOffset,
-        );
-      }
-    },
-    [mode, itemWidth], // Dependencies for useMemo
-  );
- 
-  // Returning the new offset and the function to compute it
-  return [newOffset, computeNewOffset];
-};
- 
-export default useNewScrollPosition;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/effects/useSlideshow.ts.html b/coverage/lcov-report/components/effects/useSlideshow.ts.html deleted file mode 100644 index cd2a32617..000000000 --- a/coverage/lcov-report/components/effects/useSlideshow.ts.html +++ /dev/null @@ -1,634 +0,0 @@ - - - - - - Code coverage report for components/effects/useSlideshow.ts - - - - - - - - - -
-
-

All files / components/effects useSlideshow.ts

-
- -
- 55.26% - Statements - 63/114 -
- - -
- 66.66% - Branches - 8/12 -
- - -
- 100% - Functions - 1/1 -
- - -
- 55.26% - Lines - 63/114 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -1841x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -  -  -  -  -52x -  -137x -  -  -  -  -  -137x -  -  -  -  -137x -52x -  -  -  -  -  -52x -52x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -52x -52x -  -  -  -  -52x -  -  -  -  -  -  -  -52x -  -  -  -  -52x -1x -  -  -  -1x -1x -  -1x -  -  -  -  -1x -1x -1x -52x -  -  -  -  -52x -  -  -  -  -  -  -  -  -  -52x -  -  -52x -37x -34x -34x -37x -52x -  -  -52x -37x -28x -28x -37x -  -37x -37x -52x -  -52x -52x -52x -52x -52x -52x -52x -52x -52x -52x -  -  - 
import { RefObject, useCallback, useEffect, useRef, useState } from 'react';
- 
-type SlideshowHookReturn = {
-  paused: boolean;
-  remainInterval: number;
-  setStartWidth: (width: number) => void;
-  setupTimer: (interval: number) => void;
-  startWidth: number;
-  tryPause: () => void;
-  tryResume: () => void;
-};
- 
-/**
- * Custom hook to manage slideshow functionality with pause/resume capabilities
- * Uses requestAnimationFrame for smoother animation performance
- * @param ref - Reference to the HTML element containing the slideshow
- * @param active - Whether the current slide is active
- * @param slideShowActive - Whether the slideshow functionality is enabled
- * @param slideItemDuration - Duration in milliseconds for each slide
- * @param id - Unique identifier for the current slide
- * @param onElapsed - Callback function triggered when slide duration elapses
- * @returns Object containing slideshow control functions and state
- */
-const useSlideshow = (
-  ref: RefObject<HTMLElement>,
-  active: boolean,
-  slideShowActive: boolean,
-  slideItemDuration: number,
-  id: string,
-  onElapsed?: (id: string) => void,
-): SlideshowHookReturn => {
-  const startTime = useRef<number | null>(null);
-  const timerRef = useRef<number>(0);
-  const rafRef = useRef<number>(0);
-  const [startWidth, setStartWidth] = useState<number>(0);
-  const [paused, setPaused] = useState<boolean>(false);
-  const slideShowElapsed = useRef<number>(0);
-  const [remainInterval, setRemainInterval] = useState<number>(0);
-  const isRunning = useRef<boolean>(false);
- 
-  /**
-   * Cleans up timers and animation frames
-   */
-  const cleanupTimer = useCallback(() => {
-    // Clear timeout if exists
-    if (timerRef.current) {
-      window.clearTimeout(timerRef.current);
-      timerRef.current = 0;
-    }
- 
-    // Cancel animation frame if exists
-    if (rafRef.current) {
-      window.cancelAnimationFrame(rafRef.current);
-      rafRef.current = 0;
-    }
- 
-    isRunning.current = false;
-  }, []);
- 
-  /**
-   * Sets up a new timer for the slideshow using requestAnimationFrame for smoother animations
-   * @param interval - Duration in milliseconds for the timer
-   */
-  const setupTimer = useCallback(
-    (interval: number) => {
-      if (!slideItemDuration || interval <= 0 || !active || !slideShowActive) {
-        return;
-      }
- 
-      cleanupTimer();
-      setRemainInterval(interval);
-      startTime.current = performance.now();
-      setPaused(false);
-      isRunning.current = true;
- 
-      // For very short durations, use setTimeout as fallback
-      if (interval < 50) {
-        timerRef.current = window.setTimeout(() => {
-          handleTimerComplete();
-        }, interval);
-        return;
-      }
- 
-      // Use requestAnimationFrame for smoother animation
-      const endTime = startTime.current + interval;
- 
-      const animationStep = (timestamp: number) => {
-        if (!isRunning.current) return;
- 
-        if (timestamp >= endTime) {
-          handleTimerComplete();
-          return;
-        }
- 
-        // Continue animation loop
-        rafRef.current = window.requestAnimationFrame(animationStep);
-      };
- 
-      rafRef.current = window.requestAnimationFrame(animationStep);
-    },
-    [slideItemDuration, active, slideShowActive],
-  );
- 
-  /**
-   * Handles timer completion
-   */
-  const handleTimerComplete = useCallback(() => {
-    cleanupTimer();
-    setPaused(true);
-    setStartWidth(0);
-    setRemainInterval(slideItemDuration);
-    if (id && onElapsed) {
-      onElapsed(id);
-    }
-  }, [id, onElapsed, slideItemDuration, cleanupTimer]);
- 
-  /**
-   * Pauses the current slideshow if conditions are met
-   */
-  const tryPause = useCallback(() => {
-    if (!active || !slideShowActive) {
-      return;
-    }
- 
-    cleanupTimer();
-    setPaused(true);
- 
-    if (startTime.current !== null) {
-      const elapsed = performance.now() - startTime.current;
-      slideShowElapsed.current = elapsed;
-    }
- 
-    if (ref.current) {
-      setStartWidth(ref.current.clientWidth);
-    }
-  }, [active, slideShowActive, cleanupTimer]);
- 
-  /**
-   * Resumes the slideshow if conditions are met
-   */
-  const tryResume = useCallback(() => {
-    if (!active || !slideShowActive || !slideItemDuration) {
-      return;
-    }
- 
-    const remainingInterval = slideItemDuration - slideShowElapsed.current;
-    if (remainingInterval > 0) {
-      setPaused(false);
-      setupTimer(remainingInterval);
-    }
-  }, [active, slideShowActive, slideItemDuration, setupTimer]);
- 
-  // Cleanup effect when slideShowActive changes or component unmounts
-  useEffect(() => {
-    if (!slideShowActive) {
-      cleanupTimer();
-    }
-    return cleanupTimer;
-  }, [slideShowActive, cleanupTimer]);
- 
-  // Cleanup effect when active state changes
-  useEffect(() => {
-    if (!active) {
-      cleanupTimer();
-    }
-    return () => {
-      // Cleanup when component unmounts or dependencies change
-      cleanupTimer();
-    };
-  }, [active, cleanupTimer]);
- 
-  return {
-    paused,
-    remainInterval,
-    setStartWidth,
-    setupTimer,
-    startWidth,
-    tryPause,
-    tryResume,
-  };
-};
- 
-export { useSlideshow };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/__tests__/index.html b/coverage/lcov-report/components/elements/list/__tests__/index.html deleted file mode 100644 index 9ff66d196..000000000 --- a/coverage/lcov-report/components/elements/list/__tests__/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/elements/list/__tests__ - - - - - - - - - -
-
-

All files components/elements/list/__tests__

-
- -
- 100% - Statements - 134/134 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 134/134 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
list-item.test.tsx -
-
100%77/77100%6/6100%0/0100%77/77
list.test.tsx -
-
100%57/57100%7/7100%0/0100%57/57
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/__tests__/list-item.test.tsx.html b/coverage/lcov-report/components/elements/list/__tests__/list-item.test.tsx.html deleted file mode 100644 index 83a6e9c23..000000000 --- a/coverage/lcov-report/components/elements/list/__tests__/list-item.test.tsx.html +++ /dev/null @@ -1,337 +0,0 @@ - - - - - - Code coverage report for components/elements/list/__tests__/list-item.test.tsx - - - - - - - - - -
-
-

All files / components/elements/list/__tests__ list-item.test.tsx

-
- -
- 100% - Statements - 77/77 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 77/77 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -851x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import '@testing-library/jest-dom';
-import { fireEvent } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { vi } from 'vitest';
-import { ListItem } from '../list-item';
- 
-describe('ListItem', () => {
-  const defaultProps = {
-    description: 'Test Description',
-    id: 'test-id',
-    title: 'Test Title',
-  };
- 
-  const theme = getDefaultThemeOrDark();
- 
-  it('renders the component with correct title and description', () => {
-    const { getByText } = customRender(
-      <ListItem {...defaultProps} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(getByText('Test Title')).toBeInTheDocument();
-    expect(getByText('Test Description')).toBeInTheDocument();
-  });
- 
-  it('calls onClick when the item is clicked', () => {
-    const mockOnClick = vi.fn();
-    const { getByRole } = customRender(
-      <ListItem
-        {...defaultProps}
-        onClick={mockOnClick}
-        selectable
-        theme={theme}
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    fireEvent.click(getByRole('listitem'));
-    expect(mockOnClick).toHaveBeenCalledWith('test-id');
-  });
- 
-  it('renders the checkbox when selectable is true', () => {
-    const { getByRole } = customRender(
-      <ListItem {...defaultProps} selectable theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(getByRole('checkbox')).toBeInTheDocument();
-  });
- 
-  it('does not render the checkbox when selectable is false', () => {
-    const { queryByRole } = customRender(
-      <ListItem {...defaultProps} selectable={false} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(queryByRole('checkbox')).not.toBeInTheDocument();
-  });
- 
-  it('has the correct tab index when selectable is true', () => {
-    const { getByRole } = customRender(
-      <ListItem {...defaultProps} selectable theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    expect(getByRole('listitem')).toHaveAttribute('tabIndex', '0');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/__tests__/list.test.tsx.html b/coverage/lcov-report/components/elements/list/__tests__/list.test.tsx.html deleted file mode 100644 index 5c3754514..000000000 --- a/coverage/lcov-report/components/elements/list/__tests__/list.test.tsx.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - Code coverage report for components/elements/list/__tests__/list.test.tsx - - - - - - - - - -
-
-

All files / components/elements/list/__tests__ list.test.tsx

-
- -
- 100% - Statements - 57/57 -
- - -
- 100% - Branches - 7/7 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 57/57 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -651x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -3x -3x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x - 
import { describe, expect, it, vi } from 'vitest';
- 
-import { fireEvent } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { List } from '../list';
- 
-const items = [
-  { description: 'Description 1', id: '1', title: 'Item 1' },
-  { description: 'Description 2', id: '2', title: 'Item 2' },
-  { description: 'Description 3', id: '3', title: 'Item 3' },
-];
- 
-describe('List', () => {
-  const theme = getDefaultThemeOrDark(false);
- 
-  it('should render the correct number of list items', () => {
-    const { getAllByRole } = customRender(
-      <List items={items} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    const listItems = getAllByRole('listitem');
-    expect(listItems).toHaveLength(items.length);
-  });
- 
-  it('should call onClick when a list item is clicked', () => {
-    const onClick = vi.fn();
-    const { getByText } = customRender(
-      <List items={items} onClick={onClick} theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
-    const listItem = getByText('Item 1');
-    fireEvent.click(listItem);
-    expect(onClick).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should call onSelect when a list item is clicked and multiSelectable is true', () => {
-    const onSelectItem = vi.fn();
-    const itemsWithOnSelect = items.map((item, index) => ({
-      ...item,
-      onSelect: index === 0 ? onSelectItem : undefined,
-    }));
-    const { getByText } = customRender(
-      <List items={itemsWithOnSelect} multiSelectable theme={theme} />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const listItem = getByText('Item 1');
-    fireEvent.click(listItem);
-    expect(onSelectItem).toHaveBeenCalledTimes(1);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/index.html b/coverage/lcov-report/components/elements/list/index.html deleted file mode 100644 index 5b74b873a..000000000 --- a/coverage/lcov-report/components/elements/list/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/elements/list - - - - - - - - - -
-
-

All files components/elements/list

-
- -
- 97.74% - Statements - 130/133 -
- - -
- 87.8% - Branches - 36/41 -
- - -
- 80% - Functions - 4/5 -
- - -
- 97.74% - Lines - 130/133 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
list-item.tsx -
-
94.11%48/51100%6/650%1/294.11%48/51
list.model.ts -
-
0%0/00%1/10%1/10%0/0
list.styles.ts -
-
100%35/3580%20/25100%1/1100%35/35
list.tsx -
-
100%47/47100%9/9100%1/1100%47/47
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/list-item.tsx.html b/coverage/lcov-report/components/elements/list/list-item.tsx.html deleted file mode 100644 index 5478e8d69..000000000 --- a/coverage/lcov-report/components/elements/list/list-item.tsx.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list-item.tsx - - - - - - - - - -
-
-

All files / components/elements/list list-item.tsx

-
- -
- 94.11% - Statements - 48/51 -
- - -
- 100% - Branches - 6/6 -
- - -
- 50% - Functions - 1/2 -
- - -
- 94.11% - Lines - 48/51 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -921x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -  -  -  -18x -  -  -  -  -  -  -18x -  -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -10x -10x -10x -10x -10x -10x -  -10x -10x -10x -8x -18x -18x -18x -18x -18x -18x -18x -  -18x -1x -  -1x -  -  - 
import { FunctionComponent, KeyboardEvent, memo, useCallback } from 'react';
-import { CheckIcon } from 'src/components/icons';
-import { ListItemModel } from './list.model';
-import {
-  CheckboxStyle,
-  CheckboxWrapper,
-  ListItemStyle,
-  StyleAndDescription,
-  TitleDescriptionStyle,
-  TitleStyle,
-} from './list.styles';
- 
-/**
- * ListItem component displays a selectable/clickable item with title and description
- * @component
- * @param {Object} props - Component props
- * @param {string} props.title - The title text of the list item
- * @param {string} props.id - Unique identifier for the list item
- * @param {string} props.description - Optional description text below the title
- * @param {Theme} props.theme - Theme object for styling
- * @param {(id: string) => void} props.onClick - Click handler function
- * @param {boolean} props.active - Whether the item is in active state
- * @param {boolean} [props.selected=false] - Whether the item is selected (for checkbox mode)
- * @param {boolean} [props.selectable=false] - Whether the item shows a checkbox
- * @returns {JSX.Element} Rendered ListItem component
- */
-const ListItem: FunctionComponent<ListItemModel> = memo(
-  ({
-    title,
-    id,
-    description,
-    theme,
-    onClick,
-    active,
-    selected = false,
-    selectable = false,
-  }: ListItemModel) => {
-    /**
-     * Memoized click handler
-     * @param {string} id - Item identifier
-     */
-    const handleOnClick = useCallback((id: string) => onClick?.(id), [onClick]);
- 
-    /**
-     * Keyboard event handler for accessibility
-     * @param {KeyboardEvent} ev - Keyboard event
-     * @param {string} id - Item identifier
-     */
-    const handleKeyPress = useCallback((ev: KeyboardEvent, id: string) => {
-      if (ev.key === 'Enter') {
-        handleOnClick(id);
-      }
-    }, []);
- 
-    return (
-      <ListItemStyle
-        data-testid="list-item"
-        key={id}
-        $theme={theme}
-        onClick={() => handleOnClick(id)}
-        $active={active}
-        tabIndex={0}
-        $selectable={selectable}
-        onKeyUp={(ev) => handleKeyPress(ev, id)}
-      >
-        {selectable ? (
-          <CheckboxWrapper>
-            <CheckboxStyle
-              role="checkbox"
-              aria-checked={selected}
-              selected={selected}
-              theme={theme}
-            >
-              {selected && <CheckIcon />}
-            </CheckboxStyle>
-          </CheckboxWrapper>
-        ) : null}
-        <StyleAndDescription $selectable={selectable}>
-          <TitleStyle theme={theme}>{title}</TitleStyle>
-          <TitleDescriptionStyle theme={theme}>
-            {description}
-          </TitleDescriptionStyle>
-        </StyleAndDescription>
-      </ListItemStyle>
-    );
-  },
-);
- 
-ListItem.displayName = 'ListItem';
- 
-export { ListItem };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/list.model.ts.html b/coverage/lcov-report/components/elements/list/list.model.ts.html deleted file mode 100644 index 14a02f47b..000000000 --- a/coverage/lcov-report/components/elements/list/list.model.ts.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list.model.ts - - - - - - - - - -
-
-

All files / components/elements/list list.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { TimelineModel } from '@models/TimelineModel';
- 
-export type ListModel = {
-  activeItemIndex?: number;
-  items: ListItemModel[];
-  multiSelectable?: boolean;
-  onClick?: (id?: string) => void;
-} & Pick<TimelineModel, 'theme'>;
- 
-export type ListItemModel = {
-  active?: boolean;
-  description: string;
-  id: string;
-  onClick?: (id: string) => void;
-  onSelect?: () => void;
-  selectable?: boolean;
-  selected?: boolean;
-  title: string;
-} & Pick<TimelineModel, 'theme'>;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/list.styles.ts.html b/coverage/lcov-report/components/elements/list/list.styles.ts.html deleted file mode 100644 index ca338c928..000000000 --- a/coverage/lcov-report/components/elements/list/list.styles.ts.html +++ /dev/null @@ -1,508 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list.styles.ts - - - - - - - - - -
-
-

All files / components/elements/list list.styles.ts

-
- -
- 100% - Statements - 35/35 -
- - -
- 80% - Branches - 20/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 35/35 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142  -1x -  -  -1x -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -1x -1x -1x -  -1x -1x -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -  -1x -1x -  -  -  -  -1x -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -1x -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
- 
-// Theme-specific constants
-const themeStyles = {
-  border: (theme: Theme) => `1px solid ${theme.primary}`,
-  transparent: '1px solid transparent',
-};
- 
-// Reusable flex container mixin with fallbacks
-const flexContainer = css`
-  display: -webkit-box;
-  display: -ms-flexbox;
-  display: flex;
-  -webkit-box-align: center;
-  -ms-flex-align: center;
-  align-items: center;
-`;
- 
-// Base styles for list items and containers
-const baseStyles = css`
-  ${flexContainer}
-  margin: 0;
-  width: 100%;
-  -webkit-box-orient: vertical;
-  -webkit-box-direction: normal;
-  -ms-flex-direction: column;
-  flex-direction: column;
-`;
- 
-// Common styles with improved typing and vendor prefixes
-const commonStyles = css<{ $theme: Theme }>`
-  ${baseStyles}
-  background: ${(p) => p.$theme?.toolbarBtnBgColor || '#f5f5f5'};
-  border-radius: 4px;
-  -webkit-box-shadow: 0px 1px 1px ${(p) => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'};
-  box-shadow: 0px 1px 1px ${(p) => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'};
-  margin-bottom: 0.5rem;
- 
-  &:last-child {
-    margin-bottom: 0;
-  }
-`;
- 
-// Main list container with improved responsive layout
-export const ListStyle = styled.ul`
-  ${baseStyles}
-  -webkit-box-orient: vertical;
-  -webkit-box-direction: normal;
-  -ms-flex-direction: column;
-  flex-direction: column;
-  -webkit-box-pack: center;
-  -ms-flex-pack: center;
-  justify-content: center;
-  list-style: none;
-  padding: 0;
-  width: 100%;
-  max-width: 100%;
- 
-  @media screen and (max-width: 768px) {
-    padding: 0.5rem;
-  }
- 
-  @media screen and (max-width: 480px) {
-    padding: 0.25rem;
-  }
-`;
- 
-// Interactive list item with theme support
-export const ListItemStyle = styled.li<{
-  $active?: boolean;
-  $selectable?: boolean;
-  $theme: Theme;
-}>`
-  ${commonStyles}
-  border: ${(p) =>
-    p.$active ? themeStyles.border(p.$theme) : themeStyles.transparent};
-  flex-direction: ${(p) => (p.$selectable ? 'row' : 'column')};
-  background: ${(p) => p.$theme.toolbarBtnBgColor};
-  padding: 0.25rem;
-  width: calc(100% - 0.5rem);
-  user-select: none;
- 
-  &:hover {
-    border: ${(p) => themeStyles.border(p.$theme)};
-    cursor: pointer;
-  }
-`;
- 
-// Title styles
-export const TitleStyle = styled.h1<{ theme: Theme }>`
-  color: ${(p) => p.theme.iconColor || p.theme.primary};
-  font-size: 1rem;
-  font-weight: normal;
-  margin: 0.2rem 0;
-  text-align: left;
-  white-space: nowrap;
-  align-self: flex-start;
-`;
- 
-// Title description styles
-export const TitleDescriptionStyle = styled.p<{ theme: Theme }>`
-  font-size: 0.8rem;
-  font-weight: normal;
-  margin: 0;
-  padding: 0.1rem;
-  text-align: left;
-  width: 100%;
-  color: ${(p) => p.theme.cardSubtitleColor};
-`;
- 
-// Checkbox components with improved structure
-export const CheckboxWrapper = styled.span`
-  ${flexContainer}
-  width: 2rem;
-  justify-content: center;
-`;
- 
-export const CheckboxStyle = styled.span<{ selected?: boolean; theme: Theme }>`
-  ${flexContainer}
-  justify-content: center;
-  width: 1.25rem;
-  height: 1.25rem;
-  margin: 0 0.25rem 0 0.1rem;
-  border-radius: 50%;
-  background: ${(p) => (p.selected ? p.theme.primary : p.theme.toolbarBgColor)};
-  ${(p) => !p.selected && `box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1)`};
-  color: #ffffff;
- 
-  svg {
-    width: 80%;
-    height: 80%;
-  }
-`;
- 
-// Content wrapper with conditional width
-export const StyleAndDescription = styled.div<{ $selectable?: boolean }>`
-  ${flexContainer}
-  flex-direction: column;
-  width: ${(p) => (p.$selectable ? 'calc(100% - 2rem)' : '100%')};
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/list/list.tsx.html b/coverage/lcov-report/components/elements/list/list.tsx.html deleted file mode 100644 index 969ae7c05..000000000 --- a/coverage/lcov-report/components/elements/list/list.tsx.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - Code coverage report for components/elements/list/list.tsx - - - - - - - - - -
-
-

All files / components/elements/list list.tsx

-
- -
- 100% - Statements - 47/47 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 47/47 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -951x -1x -  -  -  -  -  -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -5x -5x -5x -5x -5x -5x -  -  -  -5x -5x -5x -5x -  -  -  -  -  -  -5x -5x -2x -1x -1x -1x -1x -1x -1x -2x -5x -5x -  -  -  -  -  -  -  -5x -5x -13x -13x -13x -13x -  -13x -13x -13x -13x -13x -13x -13x -13x -13x -  -13x -5x -5x -  -5x -5x -  -  - 
import { getUniqueID } from '@utils/index';
-import {
-  FunctionComponent,
-  startTransition,
-  useCallback,
-  useMemo,
-} from 'react';
-import { ListItem } from './list-item';
-import { ListModel } from './list.model';
-import { ListStyle } from './list.styles';
- 
-/**
- * Extends the base list item with a unique identifier
- * @typedef {Object} EnhancedListItem
- * @extends {ListModel['items'][0]}
- * @property {string} id - Unique identifier for the list item
- */
-type EnhancedListItem = ListModel['items'][0] & { id: string };
- 
-/**
- * List component that renders selectable items with optional multi-select capability
- * @component
- * @param {Object} props - Component props
- * @param {Array<ListModel['items'][0]>} props.items - Array of items to render in the list
- * @param {string} props.theme - Theme configuration for styling
- * @param {(id: string) => void} [props.onClick] - Callback function when an item is clicked
- * @param {number} [props.activeItemIndex] - Index of the currently active item
- * @param {boolean} [props.multiSelectable=false] - Enable multi-select functionality
- * @returns {JSX.Element} Rendered list component
- */
-const List: FunctionComponent<ListModel> = ({
-  items,
-  theme,
-  onClick,
-  activeItemIndex,
-  multiSelectable = false,
-}) => {
-  /**
-   * Memoized list items with generated unique IDs
-   */
-  const listItems = useMemo(
-    () => items.map((item) => ({ id: getUniqueID(), ...item })),
-    [items],
-  );
- 
-  /**
-   * Handles item selection and triggers appropriate callbacks
-   * @param {string} id - Item identifier
-   * @param {EnhancedListItem} item - Selected list item
-   */
-  const handleItemSelection = useCallback(
-    (id: string, item: EnhancedListItem) => {
-      if (multiSelectable && item.onSelect) {
-        startTransition(() => {
-          item.onSelect();
-        });
-      } else {
-        onClick?.(id);
-      }
-    },
-    [multiSelectable, onClick],
-  );
- 
-  /**
-   * Renders individual list items with proper props
-   * @param {EnhancedListItem} item - Item to render
-   * @param {number} index - Item index in the list
-   * @returns {JSX.Element} Rendered list item
-   */
-  const renderListItem = useCallback(
-    (item: EnhancedListItem, index: number) => {
-      const handleClick = useCallback(
-        () => handleItemSelection(item.id, item),
-        [item, handleItemSelection],
-      );
- 
-      return (
-        <ListItem
-          key={item.id}
-          {...item}
-          theme={theme}
-          onClick={handleClick}
-          selectable={multiSelectable}
-          active={activeItemIndex === index}
-        />
-      );
-    },
-    [theme, handleItemSelection, multiSelectable, activeItemIndex],
-  );
- 
-  return <ListStyle>{listItems.map(renderListItem)}</ListStyle>;
-};
- 
-export { List };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/popover/__tests__/index.html b/coverage/lcov-report/components/elements/popover/__tests__/index.html deleted file mode 100644 index 054adb227..000000000 --- a/coverage/lcov-report/components/elements/popover/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/__tests__ - - - - - - - - - -
-
-

All files components/elements/popover/__tests__

-
- -
- 100% - Statements - 85/85 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 85/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
popover.test.tsx -
-
100%85/85100%6/6100%0/0100%85/85
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/popover/__tests__/popover.test.tsx.html b/coverage/lcov-report/components/elements/popover/__tests__/popover.test.tsx.html deleted file mode 100644 index 0c21334b8..000000000 --- a/coverage/lcov-report/components/elements/popover/__tests__/popover.test.tsx.html +++ /dev/null @@ -1,403 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/__tests__/popover.test.tsx - - - - - - - - - -
-
-

All files / components/elements/popover/__tests__ popover.test.tsx

-
- -
- 100% - Statements - 85/85 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 85/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -1071x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -4x -4x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -  -1x -  -1x -1x -1x - 
import { fireEvent, screen } from '@testing-library/react';
-import { vi } from 'vitest';
- 
-import userEvent from '@testing-library/user-event';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import PopOver from '../index';
- 
-describe('PopOver', () => {
-  const mockClosePopover = vi.fn();
-  const mockToggleOpen = vi.fn();
- 
-  const theme = getDefaultThemeOrDark();
- 
-  beforeEach(() => {
-    mockClosePopover.mockReset();
-    mockToggleOpen.mockReset();
-  });
- 
-  it('should render the placeholder text', () => {
-    const placeholder = 'Select an option';
-    customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecterLabel = screen.getByText(placeholder);
-    expect(selecterLabel).toBeInTheDocument();
-  });
- 
-  it('should toggle open state when clicking on the selecter', async () => {
-    const placeholder = 'Select an option';
-    const { getByRole, getByText } = customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecter = getByRole('button');
-    expect(selecter).toBeInTheDocument();
- 
-    await fireEvent.click(selecter);
- 
-    expect(getByText('test')).toBeInTheDocument();
-  });
- 
-  it('should close the popover when clicking outside', async () => {
-    const placeholder = 'Select an option';
-    const { getByRole, queryByText } = customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecter = getByRole('button');
-    await fireEvent.click(selecter);
- 
-    expect(queryByText('test')).toBeInTheDocument();
- 
-    await fireEvent.click(document.body);
- 
-    expect(queryByText('test')).not.toBeInTheDocument();
-  });
- 
-  it('should close the popover when pressing the Escape key', async () => {
-    const user = userEvent.setup();
-    const placeholder = 'Select an option';
-    const { getByRole, queryByText, getByText } = customRender(
-      <PopOver placeholder={placeholder} position="top" theme={theme}>
-        <span>test</span>
-      </PopOver>,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    const selecter = getByRole('button');
-    await user.click(selecter);
- 
-    expect(queryByText('test')).toBeInTheDocument();
- 
-    getByText('test').focus();
- 
-    await user.keyboard('{Escape}');
- 
-    expect(queryByText('test')).not.toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/popover/index.html b/coverage/lcov-report/components/elements/popover/index.html deleted file mode 100644 index 62cada384..000000000 --- a/coverage/lcov-report/components/elements/popover/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Code coverage report for components/elements/popover - - - - - - - - - -
-
-

All files components/elements/popover

-
- -
- 97.2% - Statements - 139/143 -
- - -
- 79.31% - Branches - 46/58 -
- - -
- 100% - Functions - 19/19 -
- - -
- 97.2% - Lines - 139/143 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.tsx -
-
95.74%90/9485%17/20100%2/295.74%90/94
popover.model.ts -
-
0%0/00%1/10%1/10%0/0
popover.styles.ts -
-
100%49/4975.67%28/37100%16/16100%49/49
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/popover/index.tsx.html b/coverage/lcov-report/components/elements/popover/index.tsx.html deleted file mode 100644 index 15f446aed..000000000 --- a/coverage/lcov-report/components/elements/popover/index.tsx.html +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/index.tsx - - - - - - - - - -
-
-

All files / components/elements/popover index.tsx

-
- -
- 95.74% - Statements - 90/94 -
- - -
- 85% - Branches - 17/20 -
- - -
- 100% - Functions - 2/2 -
- - -
- 95.74% - Lines - 90/94 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -1391x -  -  -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -5x -1x -  -  -  -  -  -  -  -  -1x -22x -22x -5x -22x -3x -22x -14x -22x -  -22x -22x -  -  -  -  -  -  -1x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -  -35x -5x -35x -  -35x -3x -35x -  -35x -1x -  -  -35x -  -35x -  -  -35x -19x -5x -2x -5x -17x -14x -14x -35x -  -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -35x -  -35x -35x -35x -35x -35x -  -35x -35x -35x -5x -5x -5x -5x -5x -5x -  -5x -5x -5x -5x -5x -5x -5x -30x -35x -  -35x -  -1x - 
import React, {
-  FunctionComponent,
-  useCallback,
-  useEffect,
-  useReducer,
-  useRef,
-  memo,
-} from 'react';
-import useCloseClickOutside from 'src/components/effects/useCloseClickOutside';
-import { ChevronDown, CloseIcon } from 'src/components/icons';
-import { PopOverModel } from './popover.model';
-import {
-  CloseButton,
-  Content,
-  Header,
-  PopoverHolder,
-  PopoverWrapper,
-  Selecter,
-  SelecterIcon,
-  SelecterLabel,
-} from './popover.styles';
- 
-// Memoized Content component
-const MemoizedContent = memo(({ children }: { children: React.ReactNode }) => (
-  <Content>{children}</Content>
-));
- 
-// Reducer for state management
-type State = { open: boolean; isVisible: boolean };
-type Action =
-  | { type: 'TOGGLE' }
-  | { type: 'CLOSE' }
-  | { type: 'SET_VISIBLE'; payload: boolean };
- 
-const popoverReducer = (state: State, action: Action): State => {
-  switch (action.type) {
-    case 'TOGGLE':
-      return { ...state, open: !state.open };
-    case 'CLOSE':
-      return { ...state, open: false };
-    case 'SET_VISIBLE':
-      return { ...state, isVisible: action.payload };
-    default:
-      return state;
-  }
-};
- 
-/**
- * A customizable popover component that displays content in a floating panel
- * @param {PopOverModel} props - Component props
- * @returns {JSX.Element} PopOver component
- */
-const PopOver: FunctionComponent<PopOverModel> = ({
-  children,
-  position,
-  placeholder,
-  theme,
-  width = 350,
-  isDarkMode = false,
-  icon,
-  $isMobile = false,
-}) => {
-  const ref = useRef<HTMLDivElement>(null);
-  const [state, dispatch] = useReducer(popoverReducer, {
-    open: false,
-    isVisible: false,
-  });
- 
-  const toggleOpen = useCallback(() => {
-    dispatch({ type: 'TOGGLE' });
-  }, []);
- 
-  const closePopover = useCallback(() => {
-    dispatch({ type: 'CLOSE' });
-  }, []);
- 
-  const handleKeyPress = useCallback((ev: React.KeyboardEvent) => {
-    if (ev.key === 'Enter') {
-      dispatch({ type: 'TOGGLE' });
-    }
-  }, []);
- 
-  useCloseClickOutside(ref, closePopover);
- 
-  // Use CSS transition instead of setTimeout
-  useEffect(() => {
-    if (state.open) {
-      requestAnimationFrame(() => {
-        dispatch({ type: 'SET_VISIBLE', payload: true });
-      });
-    } else {
-      dispatch({ type: 'SET_VISIBLE', payload: false });
-    }
-  }, [state.open]);
- 
-  return (
-    <>
-      <PopoverWrapper ref={ref}>
-        <Selecter
-          role="button"
-          onClick={toggleOpen}
-          $theme={theme}
-          $open={state.open}
-          $isDarkMode={isDarkMode}
-          tabIndex={0}
-          onKeyUp={handleKeyPress}
-          $isMobile={$isMobile}
-          title={placeholder}
-        >
-          <SelecterIcon $theme={theme} $open={state.open}>
-            {icon || <ChevronDown />}
-          </SelecterIcon>
-          {placeholder && !$isMobile ? (
-            <SelecterLabel>{placeholder}</SelecterLabel>
-          ) : null}
-        </Selecter>
-      </PopoverWrapper>
-      {state.open ? (
-        <PopoverHolder
-          $position={position}
-          $width={width}
-          $theme={theme}
-          $isMobile={$isMobile}
-          $visible={state.isVisible}
-        >
-          <Header>
-            <CloseButton theme={theme} onClick={closePopover}>
-              <CloseIcon />
-            </CloseButton>
-          </Header>
-          <MemoizedContent>{children}</MemoizedContent>
-        </PopoverHolder>
-      ) : null}
-    </>
-  );
-};
- 
-export default memo(PopOver);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/popover/popover.model.ts.html b/coverage/lcov-report/components/elements/popover/popover.model.ts.html deleted file mode 100644 index c596667f7..000000000 --- a/coverage/lcov-report/components/elements/popover/popover.model.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/popover.model.ts - - - - - - - - - -
-
-

All files / components/elements/popover popover.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { ReactNode } from 'react';
- 
-export type PopOverModel = {
-  $isMobile?: boolean;
-  children: ReactNode | ReactNode[];
-  icon?: ReactNode;
-  isDarkMode?: boolean;
-  placeholder?: string;
-  position: 'top' | 'bottom';
-  theme?: Theme;
-  width?: number;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/elements/popover/popover.styles.ts.html b/coverage/lcov-report/components/elements/popover/popover.styles.ts.html deleted file mode 100644 index e502035dc..000000000 --- a/coverage/lcov-report/components/elements/popover/popover.styles.ts.html +++ /dev/null @@ -1,496 +0,0 @@ - - - - - - Code coverage report for components/elements/popover/popover.styles.ts - - - - - - - - - -
-
-

All files / components/elements/popover popover.styles.ts

-
- -
- 100% - Statements - 49/49 -
- - -
- 75.67% - Branches - 28/37 -
- - -
- 100% - Functions - 16/16 -
- - -
- 100% - Lines - 49/49 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138  -1x -1x -  -  -1x -  -  -  -  -  -  -1x -40x -26x -14x -  -1x -5x -  -1x -35x -30x -5x -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -  -1x -1x -1x -1x -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -1x -1x -1x -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -1x -1x -  -  -1x -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-// Utility mixin for centering content using flexbox
-const flexCenter = css`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`;
- 
-// Helper functions for shared styling logic
-const getBorderStyle = (theme: Theme) =>
-  theme.buttonBorderColor
-    ? `1px solid ${theme.buttonBorderColor}`
-    : '1px solid transparent';
- 
-const getElevatedShadow = (theme: Theme) =>
-  `0px 5px 16px ${theme.shadowColor || 'rgba(0, 0, 0, 0.5)'}`;
- 
-const getInteractiveShadow = (theme: Theme, isOpen?: boolean) =>
-  !isOpen
-    ? `0px 1px 3px ${theme.shadowColor || 'rgba(0, 0, 0, 0.2)'}`
-    : `inset 0 0 1px 1px ${theme.shadowColor || 'rgba(0, 0, 0, 0.2)'}`;
- 
-const BORDER_RADIUS = '6px';
- 
-// Base wrapper for the popover component
-export const PopoverWrapper = styled.div``;
- 
-// Main popover container with positioning and visibility controls
-export const PopoverHolder = styled.div<{
-  $isMobile?: boolean;
-  $position?: 'top' | 'bottom';
-  $theme?: Theme;
-  $visible?: boolean;
-  $width: number;
-}>`
-  ${flexCenter};
-  flex-direction: column;
-  background: ${({ $theme }) => $theme.toolbarBgColor};
-  border-radius: ${BORDER_RADIUS};
-  border: ${({ $theme }) => getBorderStyle($theme)};
-  box-shadow: ${({ $theme }) => getElevatedShadow($theme)};
-  max-height: 500px;
-  overflow-y: auto;
-  padding: 0.5rem;
-  position: absolute;
-  ${(p) => (p.$position === 'bottom' ? `bottom: 3.5rem` : `top: 4rem`)};
-  ${(p) => (p.$isMobile ? 'left: 4px;' : '')};
-  width: ${({ $isMobile, $width = 300 }) =>
-    $isMobile ? '90%' : `${$width}px`};
-  opacity: ${({ $visible }) => ($visible ? 1 : 0)};
-  transition:
-    opacity 0.2s ease-in-out,
-    transform 0.2s ease-in-out;
-  transform: ${(p) => (p.$visible ? 'translateY(0)' : 'translateY(-10px)')};
-  z-index: ${zIndex.popover}; /* Use standardized z-index for popovers */
-`;
- 
-// Clickable selector button that triggers the popover
-export const Selecter = styled.div<{
-  $isDarkMode: boolean;
-  $isMobile?: boolean;
-  $open?: boolean;
-  $theme: Theme;
-}>`
-  ${flexCenter};
-  background: ${({ $theme }) => $theme.toolbarBtnBgColor};
-  color: ${({ $theme }) => $theme.toolbarTextColor};
-  border-radius: ${BORDER_RADIUS};
-  border: ${({ $theme }) => getBorderStyle($theme)};
-  box-shadow: ${({ $open, $theme }) => getInteractiveShadow($theme, $open)};
-  cursor: pointer;
-  justify-content: space-between;
-  padding: ${(p) => (p.$isMobile ? '0.4rem' : `0.4rem 0.5rem`)};
-  user-select: none;
-  margin-right: 0.5rem;
-  transition:
-    background-color 0.2s ease-out,
-    border-color 0.2s ease-out,
-    box-shadow 0.2s ease-out;
- 
-  &:hover {
-    background: ${({ $theme }) =>
-      $theme.buttonHoverBgColor || $theme.toolbarBtnBgColor};
-    border-color: ${({ $theme }) =>
-      $theme.buttonHoverBorderColor || $theme.primary};
-  }
-`;
- 
-// Icon component within the selector with rotation animation
-export const SelecterIcon = styled.span<{ $open: boolean; $theme: Theme }>`
-  ${flexCenter};
-  color: ${({ $theme }) => $theme.iconColor || $theme.primary};
-  height: 1.25rem;
-  width: 1.25rem;
-  transition: transform 0.2s ease-in-out;
-  margin-right: 0.1rem;
- 
-  & svg {
-    height: 100%;
-    width: 100%;
-  }
-`;
- 
-// Text label for the selector button
-export const SelecterLabel = styled.span`
-  font-size: 0.9rem;
-  text-align: left;
-  white-space: nowrap;
-  font-weight: 500;
-`;
- 
-// Top section of the popover containing controls
-export const Header = styled.div`
-  height: 30px;
-  width: 100%;
-`;
- 
-// Scrollable content area of the popover
-export const Content = styled.div`
-  height: calc(100% - 30px);
-  overflow-y: auto;
-  width: 100%;
-`;
- 
-// Close button with icon for dismissing the popover
-export const CloseButton = styled.button<{ theme: Theme }>`
-  ${flexCenter};
-  background: transparent;
-  border: none;
-  color: ${({ theme }) => theme.iconColor || theme.primary};
-  cursor: pointer;
-  margin-bottom: 0.5rem;
-  margin-left: auto;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.html b/coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.html deleted file mode 100644 index 58c24416b..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/memoized/__tests__

-
- -
- 99.27% - Statements - 136/137 -
- - -
- 100% - Branches - 15/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 99.27% - Lines - 136/137 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.test.tsx -
-
99.27%136/137100%15/15100%0/099.27%136/137
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.test.tsx.html b/coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.test.tsx.html deleted file mode 100644 index 746a015f1..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/__tests__/index.test.tsx.html +++ /dev/null @@ -1,559 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/__tests__/index.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized/__tests__ index.test.tsx

-
- -
- 99.27% - Statements - 136/137 -
- - -
- 100% - Branches - 15/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 99.27% - Lines - 136/137 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -1591x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { forwardRef } from 'react';
-import { vi, describe, it, expect } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import { TextOrContentModel } from '../../timeline-card-content/text-or-content';
-import { DetailsTextMemo } from '../details-text-memo';
-import { SubTitleMemo } from '../subtitle-memo';
-import { TitleMemo } from '../title-memo';
- 
-describe('Title', () => {
-  it('should render title', () => {
-    const { getByText } = customRender(
-      <TitleMemo title="title" color="black" dir="rtl" active={false} />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-  });
- 
-  // should render title with url
-  it('should render title with url', () => {
-    const { getByText, getByRole } = customRender(
-      <TitleMemo
-        title="title"
-        url="https://www.google.com"
-        color="black"
-        dir="rtl"
-        active={false}
-      />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByRole('link')).toHaveAttribute('href', 'https://www.google.com');
-  });
- 
-  //should have the color and padding
-  it('should have the color and padding', () => {
-    const { getByText } = customRender(
-      <TitleMemo title="title" color="#ccc" dir="rtl" active={false} padding />,
-      { providerProps },
-    );
-    expect(getByText('title')).toHaveStyle('color: #ccc');
-    // expect(getByText('title')).toHaveStyle('padding: 0.25rem 0 0.25rem 0.5rem');
-  });
- 
-  //should accept custom class name
-  it('should accept custom class name', () => {
-    const { getByText } = customRender(
-      <TitleMemo
-        title="title"
-        color="black"
-        dir="rtl"
-        active={false}
-        padding
-        classString="custom-class"
-      />,
-      { providerProps },
-    );
-    expect(getByText('title')).toHaveClass('custom-class');
-  });
-});
- 
-describe('subtitle', () => {
-  it('should render CardSubTitle', () => {
-    const { getByText } = customRender(
-      <SubTitleMemo
-        color="red"
-        dir={'rtl'}
-        classString="card-sub-title"
-        content="card sub title"
-      ></SubTitleMemo>,
-      { providerProps },
-    );
-    expect(getByText('card sub title')).toBeInTheDocument();
-  });
- 
-  // should render the color and padding correctly
-  it('should render the color and padding correctly', () => {
-    const { getByText } = customRender(
-      <SubTitleMemo
-        color="#000"
-        dir={'rtl'}
-        classString="card-sub-title"
-        content="card sub title"
-        padding
-      ></SubTitleMemo>,
-      { providerProps },
-    );
-    expect(getByText('card sub title')).toHaveStyle('color: #000');
-    // expect(getByText('card sub title')).toHaveStyle(
-    //   'padding: 0.5rem 0 0.5rem 0.5rem',
-    // );
-  });
-});
- 
-describe('Details Text', () => {
-  // should render the details text
-  it('should render the details text', async () => {
-    const onRender = vi.fn();
-    const fn = forwardRef<HTMLSpanElement, TextOrContentModel>(() => (
-      <span>details text</span>
-    ));
-    fn.displayName = 'test';
- 
-    const { getByText } = customRender(
-      <DetailsTextMemo
-        show
-        expand
-        text={fn}
-        height={100}
-        onRender={onRender}
-        textOverlay
-      ></DetailsTextMemo>,
-      { providerProps },
-    );
-    const text = getByText('details text');
-    expect(text).toBeInTheDocument();
-    // expect(onRender).toHaveBeenCalled();
-  });
-});
- 
-describe('ShowOrHideTextButtonMemo', () => {
-  it('should not render if textOverlay is false', () => {
-    const TextComponent = forwardRef<HTMLSpanElement, TextOrContentModel>(
-      () => <span>details text</span>,
-    );
-    const { queryByRole } = customRender(
-      <DetailsTextMemo
-        show
-        expand
-        text={TextComponent}
-        height={100}
-        onRender={vi.fn()}
-        textOverlay={false}
-      ></DetailsTextMemo>,
-      { providerProps },
-    );
-    expect(queryByRole('button')).toBeNull();
-  });
-});
- 
-describe('ExpandButtonMemo', () => {
-  it('should not render if textOverlay is false', () => {
-    const { queryByRole } = customRender(
-      <DetailsTextMemo
-        show
-        expand
-        text={forwardRef(() => (
-          <span>details text</span>
-        ))}
-        height={100}
-        onRender={vi.fn()}
-        textOverlay={false}
-      ></DetailsTextMemo>,
-      { providerProps },
-    );
-    expect(queryByRole('button')).toBeNull();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/details-text-memo.tsx.html b/coverage/lcov-report/components/timeline-elements/memoized/details-text-memo.tsx.html deleted file mode 100644 index 4adc667bb..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/details-text-memo.tsx.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/details-text-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized details-text-memo.tsx

-
- -
- 71.87% - Statements - 23/32 -
- - -
- 100% - Branches - 4/4 -
- - -
- 0% - Functions - 0/1 -
- - -
- 71.87% - Lines - 23/32 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -441x -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -11x -11x -  -11x -  -3x -3x -3x -3x -3x -3x -3x -  -3x -3x -  -11x -1x -1x -  -1x -  -  - 
import { memo } from 'react';
-import { useBackground } from '../../../hooks/useBackground';
-import { useMeasureHeight } from '../../../hooks/useMeasureHeight';
-import { DetailsTextWrapper } from '../timeline-card-media/timeline-card-media.styles';
-import { DetailsTextMemoModel } from './memoized-model';
- 
-const arePropsEqual = (
-  prev: DetailsTextMemoModel,
-  next: DetailsTextMemoModel,
-): boolean => {
-  return (
-    prev.height === next.height &&
-    prev.show === next.show &&
-    prev.expand === next.expand &&
-    prev.theme?.cardDetailsBackGround === next.theme?.cardDetailsBackGround
-  );
-};
- 
-const DetailsTextMemo = memo<DetailsTextMemoModel>(
-  ({ theme, show, expand, textOverlay, text: Text, onRender }) => {
-    const background = useBackground(theme?.cardDetailsBackGround);
-    const measureRef = useMeasureHeight(onRender);
- 
-    if (!textOverlay) return null;
- 
-    return (
-      <DetailsTextWrapper
-        ref={measureRef}
-        $expandFull={expand}
-        theme={theme}
-        $show={show}
-        background={background}
-      >
-        <Text />
-      </DetailsTextWrapper>
-    );
-  },
-  arePropsEqual,
-);
- 
-DetailsTextMemo.displayName = 'DetailsText';
- 
-export { DetailsTextMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/expand-button-memo.tsx.html b/coverage/lcov-report/components/timeline-elements/memoized/expand-button-memo.tsx.html deleted file mode 100644 index 9fa38f59a..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/expand-button-memo.tsx.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/expand-button-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized expand-button-memo.tsx

-
- -
- 95.83% - Statements - 23/24 -
- - -
- 40% - Branches - 2/5 -
- - -
- 0% - Functions - 0/1 -
- - -
- 95.83% - Lines - 23/24 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -371x -1x -1x -  -  -  -  -  -  -  -1x -1x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -  -2x -1x -1x -  -1x -  -  - 
import { memo, useMemo } from 'react';
-import { MaximizeIcon, MinimizeIcon } from '../../icons';
-import { ExpandButton } from '../timeline-card-media/timeline-card-media-buttons';
-import { ExpandButtonModel } from './memoized-model';
- 
-/**
- * Renders a button to expand or collapse timeline card content.
- * @param {ExpandButtonModel} props - The expand button properties
- * @returns {JSX.Element | null} The expand/collapse button
- */
-const ExpandButtonMemo = memo<ExpandButtonModel>(
-  ({ theme, expanded, onExpand, textOverlay }: ExpandButtonModel) => {
-    const label = useMemo(() => {
-      return expanded ? 'Minimize' : 'Maximize';
-    }, [expanded]);
- 
-    return textOverlay ? (
-      <ExpandButton
-        onPointerDown={onExpand}
-        onKeyDown={(ev) => ev.key === 'Enter' && onExpand?.(ev)}
-        theme={theme}
-        aria-expanded={expanded}
-        tabIndex={0}
-        aria-label={label}
-        title={label}
-      >
-        {expanded ? <MinimizeIcon /> : <MaximizeIcon />}
-      </ExpandButton>
-    ) : null;
-  },
-  (prev, next) => prev.expanded === next.expanded,
-);
- 
-ExpandButtonMemo.displayName = 'Expand Button';
- 
-export { ExpandButtonMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/index.html b/coverage/lcov-report/components/timeline-elements/memoized/index.html deleted file mode 100644 index 7a45e64c9..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/index.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized - - - - - - - - - -
-
-

All files components/timeline-elements/memoized

-
- -
- 91.17% - Statements - 124/136 -
- - -
- 78.57% - Branches - 22/28 -
- - -
- 40% - Functions - 2/5 -
- - -
- 91.17% - Lines - 124/136 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
details-text-memo.tsx -
-
71.87%23/32100%4/40%0/171.87%23/32
expand-button-memo.tsx -
-
95.83%23/2440%2/50%0/195.83%23/24
memoized-model.ts -
-
0%0/00%1/10%1/10%0/0
show-hide-button.tsx -
-
95.45%21/2240%2/50%0/195.45%21/22
subtitle-memo.tsx -
-
95.83%23/24100%4/4100%0/095.83%23/24
title-memo.tsx -
-
100%34/34100%9/9100%1/1100%34/34
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/memoized-model.ts.html b/coverage/lcov-report/components/timeline-elements/memoized/memoized-model.ts.html deleted file mode 100644 index 334c215a4..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/memoized-model.ts.html +++ /dev/null @@ -1,313 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/memoized-model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized memoized-model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '../../../models/Theme';
-import React, { ReactNode } from 'react';
- 
-/**
- * Common properties shared by multiple interfaces.
- */
-type common = {
-  classString?: string; // CSS class string
-  color?: string; // Color value
-  dir?: string; // Text direction
-  fontSize?: string; // Font size
-  $padding?: boolean; // Whether to apply padding
-  theme?: Theme; // Theme object
-};
- 
-/**
- * Interface for the Title component.
- */
-export interface Title extends common {
-  active?: boolean; // Whether the title is active
-  title?: string | ReactNode; // Title text or ReactNode
-  url?: string; // URL for the title
-}
- 
-/**
- * Interface for the Content component.
- */
-export interface Content extends common {
-  content?: string | ReactNode; // Content text or ReactNode
-  padding?: boolean; // For backward compatibility
-}
- 
-/**
- * Type for the ExpandButtonModel.
- */
-export type ExpandButtonModel = {
-  expanded?: boolean; // Whether the button is expanded
-  onExpand?: (ev: React.PointerEvent | React.KeyboardEvent) => void; // Event handler for expand action
-  textOverlay?: boolean; // Whether to overlay text on the button
-} & Pick<common, 'theme'>;
- 
-/**
- * Type for the ShowHideTextButtonModel.
- */
-export type ShowHideTextButtonModel = {
-  onToggle: (ev: React.PointerEvent | React.KeyboardEvent) => void; // Event handler for toggle action
-  show?: boolean; // Whether to show the button
-  textOverlay?: boolean; // Whether to overlay text on the button
-} & Pick<common, 'theme'>;
- 
-/**
- * Type for the DetailsTextMemoModel.
- */
-export type DetailsTextMemoModel = {
-  theme?: Theme; // Theme object
-  show: boolean; // Whether to show the details text
-  expand: boolean; // Whether to expand the details text
-  textOverlay: boolean; // Whether to overlay text on the details text
-  text: React.FC; // Text component for the details text
-  height?: number; // Height of the details text
-  onRender?: (height: number) => void; // Callback function for rendering the details text
-};
- 
-/**
- * Type for the TextContentMemoModel.
- */
-export type TextContentMemoModel = Title &
-  Content &
-  ExpandButtonModel &
-  ShowHideTextButtonModel &
-  DetailsTextMemoModel;
- 
-/**
- * Type for the CardMediaHeaderMemoModel.
- */
-export type CardMediaHeaderMemoModel = Title & Content;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/show-hide-button.tsx.html b/coverage/lcov-report/components/timeline-elements/memoized/show-hide-button.tsx.html deleted file mode 100644 index 19e4ee5ff..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/show-hide-button.tsx.html +++ /dev/null @@ -1,187 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/show-hide-button.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized show-hide-button.tsx

-
- -
- 95.45% - Statements - 21/22 -
- - -
- 40% - Branches - 2/5 -
- - -
- 0% - Functions - 0/1 -
- - -
- 95.45% - Lines - 21/22 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -351x -1x -1x -  -  -  -  -  -  -  -1x -1x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -  -2x -1x -  -1x -  -  - 
import { memo, useMemo } from 'react';
-import { MinusIcon, PlusIcon } from '../../icons';
-import { ShowHideTextButton } from '../timeline-card-media/timeline-card-media-buttons';
-import { ShowHideTextButtonModel } from './memoized-model';
- 
-/**
- * Renders a button to toggle showing or hiding text content.
- * @param {ShowHideTextButtonModel} props - Button properties
- * @returns {JSX.Element | null} The toggle button
- */
-const ShowOrHideTextButtonMemo = memo<ShowHideTextButtonModel>(
-  ({ textOverlay, onToggle, theme, show }: ShowHideTextButtonModel) => {
-    const label = useMemo(() => {
-      return show ? 'Hide Text' : 'Show Text';
-    }, [show]);
- 
-    return textOverlay ? (
-      <ShowHideTextButton
-        onPointerDown={onToggle}
-        theme={theme}
-        tabIndex={0}
-        onKeyDown={(ev) => ev.key === 'Enter' && onToggle?.(ev)}
-        aria-label={label}
-        title={label}
-      >
-        {show ? <MinusIcon /> : <PlusIcon />}
-      </ShowHideTextButton>
-    ) : null;
-  },
-);
- 
-ShowOrHideTextButtonMemo.displayName = 'Show Hide Text Button';
- 
-export { ShowOrHideTextButtonMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/subtitle-memo.tsx.html b/coverage/lcov-report/components/timeline-elements/memoized/subtitle-memo.tsx.html deleted file mode 100644 index 7eaeb38f8..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/subtitle-memo.tsx.html +++ /dev/null @@ -1,193 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/subtitle-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized subtitle-memo.tsx

-
- -
- 95.83% - Statements - 23/24 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 0/0 -
- - -
- 95.83% - Lines - 23/24 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -371x -1x -1x -  -1x -  -  -  -  -  -  -1x -1x -43x -  -43x -37x -37x -37x -37x -37x -37x -37x -37x -  -37x -37x -6x -43x -1x -  -1x -  -1x -  -  - 
import cls from 'classnames';
-import React, { useContext } from 'react';
-import { CardSubTitleSemantic } from '../timeline-card-content/timeline-card-content.styles';
-import { Content } from './memoized-model';
-import { GlobalContext } from '../../GlobalContext';
- 
-/**
- * Renders the subtitle content for the timeline card using configurable semantic tags.
- * @param {Content} props - Subtitle properties
- * @returns {JSX.Element | null} The rendered subtitle
- */
-const SubTitleMemo = React.memo<Content>(
-  ({ content, color, dir, theme, fontSize, classString, padding }: Content) => {
-    const { semanticTags } = useContext(GlobalContext);
- 
-    return content ? (
-      <CardSubTitleSemantic
-        as={semanticTags?.cardSubtitle ?? 'span'}
-        style={{ color }}
-        dir={dir}
-        theme={theme}
-        $fontSize={fontSize}
-        className={cls('card-sub-title', classString)}
-        $padding={padding}
-      >
-        {content}
-      </CardSubTitleSemantic>
-    ) : null;
-  },
-  (prev, next) =>
-    prev.theme?.cardSubtitleColor === next.theme?.cardSubtitleColor,
-);
- 
-SubTitleMemo.displayName = 'Timeline Content';
- 
-export { SubTitleMemo };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/memoized/title-memo.tsx.html b/coverage/lcov-report/components/timeline-elements/memoized/title-memo.tsx.html deleted file mode 100644 index 12b77dc1f..000000000 --- a/coverage/lcov-report/components/timeline-elements/memoized/title-memo.tsx.html +++ /dev/null @@ -1,235 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/memoized/title-memo.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/memoized title-memo.tsx

-
- -
- 100% - Statements - 34/34 -
- - -
- 100% - Branches - 9/9 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 34/34 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -511x -1x -  -  -  -  -1x -1x -  -  -  -  -  -  -1x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -  -45x -37x -37x -37x -37x -37x -37x -37x -37x -  -37x -3x -3x -3x -  -34x -  -37x -8x -45x -  -1x -  -1x - 
import cls from 'classnames';
-import {
-  CardTitleAnchor,
-  CardTitleSemantic,
-} from '../timeline-card-content/timeline-card-content.styles';
-import { Title } from './memoized-model';
-import React, { useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
- 
-/**
- * Renders the timeline's title with optional link using configurable semantic tags.
- * @param {Title} props - Title properties
- * @returns {JSX.Element | null} The rendered title
- */
-const TitleMemoComponent = ({
-  title,
-  url,
-  theme,
-  color,
-  dir,
-  active,
-  fontSize = '1rem',
-  classString = '',
-}: Title) => {
-  const { semanticTags } = useContext(GlobalContext);
- 
-  return title ? (
-    <CardTitleSemantic
-      as={semanticTags?.cardTitle ?? 'span'}
-      className={cls(active ? 'active' : '', { [classString]: true })}
-      theme={theme}
-      style={{ color }}
-      dir={dir}
-      $fontSize={fontSize}
-      data-class={classString}
-    >
-      {url ? (
-        <CardTitleAnchor href={url} target="_blank" rel="noreferrer">
-          {title}
-        </CardTitleAnchor>
-      ) : (
-        title
-      )}
-    </CardTitleSemantic>
-  ) : null;
-};
- 
-export const TitleMemo = React.memo(TitleMemoComponent);
- 
-TitleMemo.displayName = 'Timeline Title';
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/index.html b/coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/index.html deleted file mode 100644 index 23148946b..000000000 --- a/coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/nested-timeline-renderer - - - - - - - - - -
-
-

All files components/timeline-elements/nested-timeline-renderer

-
- -
- 11.53% - Statements - 3/26 -
- - -
- 100% - Branches - 0/0 -
- - -
- 0% - Functions - 0/1 -
- - -
- 11.53% - Lines - 3/26 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
nested-timeline-renderer.tsx -
-
11.53%3/26100%0/00%0/111.53%3/26
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html b/coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html deleted file mode 100644 index a5a463cd1..000000000 --- a/coverage/lcov-report/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx.html +++ /dev/null @@ -1,214 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/nested-timeline-renderer nested-timeline-renderer.tsx

-
- -
- 11.53% - Statements - 3/26 -
- - -
- 100% - Branches - 0/0 -
- - -
- 0% - Functions - 0/1 -
- - -
- 11.53% - Lines - 3/26 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -441x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
import React from 'react';
-import { TimelineModel } from '@models/TimelineModel';
- 
-interface NestedTimelineRendererProps {
-  items: any[];
-  nestedCardHeight?: number;
-  mode?: string;
-  isChild?: boolean;
-}
- 
-// This component will be used to dynamically load the Timeline component
-// to avoid circular dependency issues
-const NestedTimelineRenderer: React.FC<NestedTimelineRendererProps> = ({
-  items,
-  nestedCardHeight,
-  mode = 'HORIZONTAL',
-  isChild,
-}) => {
-  const [TimelineComponent, setTimelineComponent] =
-    React.useState<React.ComponentType<TimelineModel> | null>(null);
- 
-  // Dynamically import the Timeline component only when needed
-  React.useEffect(() => {
-    import('../../timeline/timeline').then((module) => {
-      setTimelineComponent(() => module.default);
-    });
-  }, []);
- 
-  if (!TimelineComponent) {
-    return <div>Loading nested timeline...</div>;
-  }
- 
-  return (
-    <TimelineComponent
-      items={items}
-      mode={mode as any}
-      nestedCardHeight={nestedCardHeight}
-      isChild={isChild}
-    />
-  );
-};
- 
-export default NestedTimelineRenderer;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html deleted file mode 100644 index 0441378f8..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx.html +++ /dev/null @@ -1,364 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ content-footer.test.tsx

-
- -
- 100% - Statements - 78/78 -
- - -
- 100% - Branches - 5/5 -
- - -
- 0% - Functions - 0/1 -
- - -
- 100% - Lines - 78/78 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -941x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
import userEvent from '@testing-library/user-event';
-import { createRef } from 'react';
-import { describe, expect, it, vi } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import { ContentFooter } from '../content-footer';
-import { ContentFooterProps } from '../header-footer.model';
- 
-const commonProps: ContentFooterProps = {
-  canShow: false,
-  onExpand: () => {},
-  paused: false,
-  progressRef: createRef(),
-  remainInterval: 0,
-  showMore: false,
-  showReadMore: false,
-  startWidth: 0,
-  textContentIsLarge: false,
-  triangleDir: 'up',
-};
- 
-describe('ContentFooter', () => {
-  //should match snapshot
-  it('should match snapshot', () => {
-    const { container } = customRender(
-      <ContentFooter {...commonProps} startWidth={300} paused={false} />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  //should render read more button when text content is large
-  it('should render read more button when text content is large', () => {
-    const { getByText } = customRender(
-      <ContentFooter
-        {...commonProps}
-        showReadMore
-        textContentIsLarge
-        canShow
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('read more')).toBeInTheDocument();
-    expect(getByText('read more')).toBeVisible();
-  });
- 
-  //should render read less button when text content is large
-  it('should render read less button when text content is large', () => {
-    const { getByText } = customRender(
-      <ContentFooter
-        {...commonProps}
-        showReadMore
-        textContentIsLarge
-        canShow
-        showMore
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('read less')).toBeInTheDocument();
-    expect(getByText('read less')).toBeVisible();
-  });
- 
-  //should call onExpand when read more button is clicked
-  it('should call onExpand when read more button is clicked', async () => {
-    const onExpand = vi.fn();
-    const user = userEvent.setup();
- 
-    const { getByText } = customRender(
-      <ContentFooter
-        {...commonProps}
-        showReadMore
-        textContentIsLarge
-        canShow
-        onExpand={onExpand}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    await user.click(getByText('read more'));
-    expect(onExpand).toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html deleted file mode 100644 index 5744d2176..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx.html +++ /dev/null @@ -1,238 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ content-header.test.tsx

-
- -
- 100% - Statements - 42/42 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 42/42 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -521x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
import { describe } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import { ContentHeader } from '../content-header';
- 
-describe('Content Header', () => {
-  // should render the title and subtitle of the card
-  it('should render the title and subtitle of the card', () => {
-    const { getByText } = customRender(
-      <ContentHeader title="title" content="content" />,
-      {
-        providerProps: {
-          ...providerProps,
-          media: null,
-        },
-      },
-    );
- 
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByText('content')).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot', () => {
-    const { container } = customRender(
-      <ContentHeader title="title" content="content" />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render the link if url is provided
-  it('should render the link if url is provided', () => {
-    const { getByText, getByRole } = customRender(
-      <ContentHeader
-        title="title"
-        content="content"
-        url="http://www.google.com"
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByRole('link')).toHaveAttribute('href', 'http://www.google.com');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html deleted file mode 100644 index 890a77aa7..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx.html +++ /dev/null @@ -1,352 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ details-text.test.tsx

-
- -
- 100% - Statements - 76/76 -
- - -
- 100% - Branches - 12/12 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 76/76 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90  -1x -1x -  -1x -1x -  -1x -6x -6x -6x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
// test utils
-import { customRender, providerProps } from 'src/components/common/test';
-import { DetailsText } from '../details-text';
- 
-describe('DetailsText', () => {
-  let props;
- 
-  beforeEach(() => {
-    props = {
-      detailedText: 'Hello world',
-    };
-  });
- 
-  describe('rendering', () => {
-    test('renders without crashing', () => {
-      customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
-    });
- 
-    test('renders the TextContent component', () => {
-      const { getByText } = customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
-      expect(getByText('Hello world')).toBeInTheDocument();
-    });
-  });
- 
-  describe('props', () => {
-    test('passes showMore prop to TextContent', async () => {
-      const { getByText } = customRender(<DetailsText {...props} showMore />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
- 
-      expect(getByText('Hello world').parentElement).toHaveAttribute(
-        'aria-expanded',
-        'true',
-      );
-    });
- 
-    test('passes theme prop to TimelineContentDetailsWrapper', () => {
-      const { getByText } = customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
- 
-      expect(getByText('Hello world').parentElement).toHaveStyle({
-        'scrollbar-color': `${providerProps.theme.primary} default`,
-      });
-    });
-  });
- 
-  describe('context', () => {
-    test('uses context values', () => {
-      // mock GlobalContext
-      const { getByText } = customRender(<DetailsText {...props} />, {
-        providerProps: {
-          ...providerProps,
-          borderLessCards: true,
-        },
-      });
- 
-      expect(getByText('Hello world').parentElement).toHaveStyle({
-        width: 'calc(100% - 0.5rem)',
-      });
-    });
-  });
- 
-  describe('accessibility', () => {
-    test('content has aria-expanded attribute reflecting state', () => {
-      const { getByText } = customRender(<DetailsText {...props} showMore />, {
-        providerProps: {
-          ...providerProps,
-        },
-      });
-      expect(getByText('Hello world').parentElement).toHaveAttribute(
-        'aria-expanded',
-        'true',
-      );
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/index.html deleted file mode 100644 index 8da774aa2..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/index.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-content/__tests__

-
- -
- 98.31% - Statements - 351/357 -
- - -
- 100% - Branches - 37/37 -
- - -
- 66.66% - Functions - 2/3 -
- - -
- 98.31% - Lines - 351/357 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
content-footer.test.tsx -
-
100%78/78100%5/50%0/1100%78/78
content-header.test.tsx -
-
100%42/42100%4/4100%0/0100%42/42
details-text.test.tsx -
-
100%76/76100%12/12100%0/0100%76/76
text_or_content.test.tsx -
-
100%53/53100%5/5100%0/0100%53/53
timeline-card-content.test.tsx -
-
94.44%102/108100%11/11100%2/294.44%102/108
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html deleted file mode 100644 index 91fd42240..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ text_or_content.test.tsx

-
- -
- 100% - Statements - 53/53 -
- - -
- 100% - Branches - 5/5 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 53/53 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x - 
// Imports
-import { getDefaultClassNames } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { getTextOrContent } from '../text-or-content';
- 
-describe('getTextOrContent', () => {
-  const classNames = getDefaultClassNames();
- 
-  it('renders TimelineContentDetails when detailedText is string', () => {
-    const TextContent = getTextOrContent({
-      detailedText: 'Hello World',
-    });
- 
-    const { getByText } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-      },
-    });
-    expect(getByText('Hello World')).toBeInTheDocument();
-  });
- 
-  it('renders TimelineContentDetails with xss when parseDetailsAsHTML is true', () => {
-    const TextContent = getTextOrContent({
-      detailedText: '<b>Hello</b>',
-    });
- 
-    const { container } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-        parseDetailsAsHTML: true,
-      },
-    });
- 
-    expect(container.firstChild).toHaveTextContent('Hello'); // xss sanitized
-  });
- 
-  it('renders TimelineSubContent when detailedText is array', () => {
-    const TextContent = getTextOrContent({
-      detailedText: ['Line 1', 'Line 2'],
-    });
- 
-    const { getAllByText } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-      },
-    });
-    expect(getAllByText('Line 1')[0]).toBeInTheDocument();
-    expect(getAllByText('Line 2')[0]).toBeInTheDocument();
-  });
- 
-  it('passes showMore prop to TimelineContentDetails', () => {
-    const TextContent = getTextOrContent({
-      detailedText: 'Text',
-      showMore: true,
-    });
- 
-    const { getByText } = customRender(<TextContent />, {
-      providerProps: {
-        ...providerProps,
-      },
-    });
-    expect(getByText('Text')).toHaveClass('active');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html deleted file mode 100644 index 33ceecd15..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx.html +++ /dev/null @@ -1,478 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content/__tests__ timeline-card-content.test.tsx

-
- -
- 94.44% - Statements - 102/108 -
- - -
- 100% - Branches - 11/11 -
- - -
- 100% - Functions - 2/2 -
- - -
- 94.44% - Lines - 102/108 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -1321x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -  -1x -1x -1x -  -  -1x -  -1x -6x -1x -  -  -1x -1x -  -1x -  -1x -  -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { render, screen, waitFor } from '@testing-library/react';
-import GlobalContextProvider from 'src/components/GlobalContext';
-import { afterEach, beforeAll, describe, expect, it, vi } from 'vitest';
-import { customRender, providerProps } from '../../../common/test';
-import TimelineCardContent from '../timeline-card-content';
- 
-describe('TimelineCardContent', () => {
-  beforeAll(() => {
-    Object.defineProperty(window, 'matchMedia', {
-      value: vi.fn().mockImplementation((query) => ({
-        addEventListener: vi.fn(),
-        dispatchEvent: vi.fn(),
-        matches: false,
-        media: query,
-        onchange: null,
-        removeEventListener: vi.fn(),
-      })),
-      writable: true,
-    });
- 
-    // ResizeObserver is already mocked globally in common/test/index.tsx
-  });
- 
-  afterEach(() => {
-    vi.resetAllMocks();
-  });
- 
-  // should render the component successfully
-  it('should render the component successfully', () => {
-    const { getByTestId } = render(<TimelineCardContent />);
- 
-    expect(getByTestId('timeline-card-content')).toBeInTheDocument();
-    // expect(getByTestId('timeline-card-content')).toBeVisible();
-  });
- 
-  //should render the title
-  it('should render the title', () => {
-    render(<TimelineCardContent title="title" />);
- 
-    expect(screen.getByText('title')).toBeInTheDocument();
-    expect(screen.getByText('title')).toBeVisible();
-  });
- 
-  // should render the detailedText when a string is passed
-  it('should render the detailedText when a string is passed', () => {
-    render(
-      <GlobalContextProvider toolbarPosition="bottom" textDensity="HIGH">
-        <TimelineCardContent detailedText="detailedText" />
-      </GlobalContextProvider>,
-    );
- 
-    expect(screen.getByText('detailedText')).toBeInTheDocument();
-    expect(screen.getByText('detailedText')).toBeVisible();
-  });
- 
-  // should render the detailedText when a array of strings is passed
-  it('should render the detailedText when a array of strings is passed', () => {
-    render(
-      <GlobalContextProvider toolbarPosition="bottom" textDensity="HIGH">
-        <TimelineCardContent detailedText={['detailedText', 'text 2']} />
-      </GlobalContextProvider>,
-    );
- 
-    expect(screen.getByText('detailedText')).toBeInTheDocument();
-    expect(screen.getByText('text 2')).toBeInTheDocument();
-    expect(screen.getByText('detailedText')).toBeVisible();
-    expect(screen.getByText('text 2')).toBeVisible();
-  });
- 
-  // should render media as expected. check if a image is rendered as expected
-  it('should render media as expected. check if a image is rendered as expected', async () => {
-    const { getByTestId } = customRender(
-      <TimelineCardContent
-        media={{
-          source: {
-            type: 'IMAGE',
-            url: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
-          },
-          type: 'IMAGE',
-        }}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    await waitFor(
-      () => {
-        expect(getByTestId('timeline-card-content-image')).toBeInTheDocument();
-        expect(getByTestId('timeline-card-content-image')).toHaveAttribute(
-          'src',
-          'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
-        );
-      },
-      {
-        timeout: 2000,
-      },
-    );
-  });
- 
-  // should render the media as expected. check if a video is rendered as expected
-  it('should render the media as expected. check if a video is rendered as expected', async () => {
-    const { getByTestId } = customRender(
-      <TimelineCardContent
-        media={{
-          source: {
-            type: 'VIDEO',
-            url: 'https://www.youtube.com/embed/2G3x2-m9OOI',
-          },
-          type: 'VIDEO',
-        }}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    await waitFor(
-      () => {
-        expect(getByTestId('timeline-card-content-video')).toBeInTheDocument();
-        expect(getByTestId('timeline-card-content-video')).toHaveAttribute(
-          'src',
-          'https://www.youtube.com/embed/2G3x2-m9OOI?enablejsapi=1',
-        );
-      },
-      {
-        timeout: 2000,
-      },
-    );
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html deleted file mode 100644 index 5d0a96877..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/card-animations.styles.ts.html +++ /dev/null @@ -1,220 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/card-animations.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content card-animations.styles.ts

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -461x -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  - 
import { keyframes } from 'styled-components';
- 
-export const reveal = keyframes`
-  0% {
-    opacity: 0;
-    transform: scale(0.95);
-  }
-  100% {
-    opacity: 1;
-    transform: scale(1);
-  }
-`;
- 
-export const slideInFromTop = keyframes`
-  0% {
-    opacity: 0;
-    transform: translateY(-50%);
-  }
-  100% {
-    opacity: 1;
-    transform: translateY(0);
-  }
-`;
- 
-export const slideInFromLeft = keyframes`
-  0% {
-    opacity: 0;
-    transform: translateX(-50%);
-  }
-  100% {
-    opacity: 1;
-    transform: translateX(0);
-  }
-`;
- 
-export const slideFromRight = keyframes`
-  0% {
-    opacity: 0;
-    transform: translateX(50%);
-  }
-  100% {
-    opacity: 1;
-    transform: translateX(0);
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/content-footer.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/content-footer.tsx.html deleted file mode 100644 index 2a445da87..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/content-footer.tsx.html +++ /dev/null @@ -1,349 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/content-footer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content content-footer.tsx

-
- -
- 91.11% - Statements - 41/45 -
- - -
- 91.66% - Branches - 11/12 -
- - -
- 50% - Functions - 1/2 -
- - -
- 91.11% - Lines - 41/45 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -891x -  -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -36x -36x -36x -36x -36x -36x -36x -  -36x -36x -1x -1x -1x -1x -36x -36x -  -36x -  -  -  -  -32x -36x -  -36x -36x -36x -3x -3x -3x -3x -  -  -  -  -3x -3x -3x -  -3x -3x -3x -3x -3x -33x -36x -  -36x -  -  - 
import {
-  FunctionComponent,
-  PointerEvent,
-  useCallback,
-  useContext,
-  useMemo,
-} from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import ChevronIcon from '../../icons/chev-right';
-import { ContentFooterProps } from './header-footer.model';
-import { ChevronIconWrapper, ShowMore } from './timeline-card-content.styles';
- 
-/**
- * ContentFooter
- *
- * A functional component that renders the footer of the timeline card.
- * It displays the read more/less button, progress bar, and triangle icon.
- * The read more/less button appears only if the content is large.
- * The progress bar and triangle icon are displayed only if the card is in slideshow mode.
- *
- * @property {boolean} showProgressBar - Determines if progress bar should be displayed.
- * @property {Function} onExpand - Function called when expanding content.
- * @property {string} triangleDir - Direction of the triangle icon.
- * @property {boolean} showMore - Determines if 'read more' should be displayed.
- * @property {boolean} textContentIsLarge - Determines if text content is large.
- * @property {boolean} showReadMore - Determines if 'read more' button should be displayed.
- * @property {number} remainInterval - Remaining interval for progress bar.
- * @property {boolean} paused - Determines if progress is paused.
- * @property {number} startWidth - Starting width of progress bar.
- * @property {boolean} canShow - Determines if the element can be shown.
- * @property {React.RefObject} progressRef - Ref to the progress bar.
- * @property {boolean} isNested - Determines if component is nested.
- * @property {boolean} isResuming - Determines if slideshow is resuming.
- *
- * @returns {JSX.Element} ContentFooter component.
- */
-const ContentFooter: FunctionComponent<ContentFooterProps> = ({
-  onExpand,
-  showMore,
-  textContentIsLarge,
-  showReadMore,
-  canShow,
-}: ContentFooterProps) => {
-  const { theme } = useContext(GlobalContext);
- 
-  const handleClick = useCallback(
-    (ev: PointerEvent) => {
-      ev.stopPropagation();
-      ev.preventDefault();
-      onExpand();
-    },
-    [onExpand],
-  );
- 
-  const canShowMore = useMemo(() => {
-    // Only show read more when:
-    // 1. The feature is enabled (showReadMore)
-    // 2. The text is actually large enough to need expansion (textContentIsLarge)
-    // 3. The parent says it's valid to show (canShow) - this might indicate we have detailedText
-    return showReadMore && textContentIsLarge && canShow;
-  }, [showReadMore, textContentIsLarge, canShow]);
- 
-  return (
-    <>
-      {canShowMore ? (
-        <ShowMore
-          className="show-more"
-          onPointerDown={handleClick}
-          onKeyUp={(event) => {
-            if (event.key === 'Enter') {
-              onExpand();
-            }
-          }}
-          show={canShow ? 'true' : 'false'}
-          theme={theme}
-          tabIndex={0}
-        >
-          {<span>{showMore ? 'read less' : 'read more'}</span>}
-          <ChevronIconWrapper collapsed={showMore ? 'true' : 'false'}>
-            <ChevronIcon />
-          </ChevronIconWrapper>
-        </ShowMore>
-      ) : null}
-    </>
-  );
-};
- 
-export { ContentFooter };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/content-header.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/content-header.tsx.html deleted file mode 100644 index ac1b3732c..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/content-header.tsx.html +++ /dev/null @@ -1,304 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/content-header.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content content-header.tsx

-
- -
- 85.36% - Statements - 35/41 -
- - -
- 90.9% - Branches - 10/11 -
- - -
- 100% - Functions - 0/0 -
- - -
- 85.36% - Lines - 35/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -741x -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -37x -37x -  -37x -  -37x -37x -  -  -37x -  -  -  -  -  -  -  -37x -  -37x -27x -27x -27x -27x -27x -27x -27x -10x -  -  -  -37x -27x -27x -27x -27x -27x -27x -10x -37x -  -37x -1x -  -  -1x -  -  - 
import { FunctionComponent, memo, useContext, useMemo } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { SubTitleMemo } from '../memoized/subtitle-memo';
-import { TitleMemo } from '../memoized/title-memo';
-import { ContentHeaderProps } from './header-footer.model';
-import {
-  CardTitleSemantic,
-  TimelineCardHeader,
-} from './timeline-card-content.styles';
- 
-/**
- * ContentHeader component
- * This component renders the header of the timeline card including the title and subtitle.
- * It doesn't render the title and subtitle if the card has media.
- * The title and subtitle are memoized to prevent unnecessary re-renders.
- *
- * @property {string} title - The title of the card.
- * @property {string} url - The URL of the card.
- * @property {boolean} media - Indicates whether the card has media or not.
- * @property {string} content - The main content of the card.
- * @returns {JSX.Element} The ContentHeader component.
- */
-const ContentHeader: FunctionComponent<ContentHeaderProps> = memo(
-  ({ title, url, media, content, cardTitle }: ContentHeaderProps) => {
-    // Using context to get global values
-    const { fontSizes, classNames, theme, isMobile, semanticTags } =
-      useContext(GlobalContext);
- 
-    const isNotMedia = useMemo(() => !media, [media]);
- 
-    return (
-      <TimelineCardHeader>
-        {/* Render title if there is no media */}
- 
-        {isMobile ? (
-          <CardTitleSemantic
-            as={semanticTags?.cardTitle ?? 'span'}
-            $fontSize={'1.2rem'}
-            theme={theme}
-          >
-            {cardTitle}
-          </CardTitleSemantic>
-        ) : null}
- 
-        {isNotMedia ? (
-          <TitleMemo
-            title={title}
-            theme={theme}
-            url={url}
-            fontSize={fontSizes?.cardTitle}
-            classString={classNames?.cardTitle}
-          />
-        ) : null}
- 
-        {/* Render subtitle if there is no media */}
- 
-        {isNotMedia ? (
-          <SubTitleMemo
-            content={content}
-            theme={theme}
-            fontSize={fontSizes?.cardSubtitle}
-            classString={classNames?.cardSubTitle}
-          />
-        ) : null}
-      </TimelineCardHeader>
-    );
-  },
-);
- 
-// Setting display name for easier debugging
-ContentHeader.displayName = 'ContentHeader';
- 
-export { ContentHeader };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.model.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.model.ts.html deleted file mode 100644 index 176b56340..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.model.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/details-text.model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content details-text.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { TimelineContentModel } from '@models/TimelineContentModel';
-import { ReactNode } from 'react';
- 
-export type DetailsTextProps = {
-  cardActualHeight?: number;
-  contentDetailsClass?: string;
-  customContent?: ReactNode;
-  detailedText: TimelineContentModel['detailedText'];
-  detailsHeight?: number;
-  gradientColor?: string;
-  showMore?: boolean;
-  timelineContent: TimelineContentModel['timelineContent'];
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.tsx.html deleted file mode 100644 index a1c32831c..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/details-text.tsx.html +++ /dev/null @@ -1,283 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/details-text.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content details-text.tsx

-
- -
- 100% - Statements - 54/54 -
- - -
- 50% - Branches - 1/2 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 54/54 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -671x -1x -  -1x -1x -  -1x -1x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -  -38x -38x -38x -38x -38x -38x -38x -  -38x -38x -38x -38x -38x -38x -  -38x -38x -  -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -38x -  -38x -38x -38x -38x -  -38x -38x -  -38x -1x -  -1x -  -  - 
import { forwardRef, useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { DetailsTextProps } from './details-text.model';
-import { getTextOrContent } from './text-or-content';
-import { TimelineContentDetailsWrapper } from './timeline-card-content.styles';
- 
-const DetailsText = forwardRef<HTMLDivElement, DetailsTextProps>(
-  (prop, ref) => {
-    const {
-      showMore,
-      cardActualHeight,
-      detailsHeight,
-      gradientColor,
-      customContent,
-      timelineContent,
-      detailedText,
-      contentDetailsClass,
-    } = prop;
- 
-    const {
-      useReadMore,
-      borderLessCards,
-      contentDetailsHeight,
-      textOverlay,
-      theme,
-    } = useContext(GlobalContext);
- 
-    const TextContent = getTextOrContent({
-      detailedText,
-      showMore,
-      theme,
-      timelineContent,
-    });
- 
-    return (
-      <>
-        {/* detailed text */}
-        <TimelineContentDetailsWrapper
-          aria-expanded={showMore}
-          className={contentDetailsClass}
-          $customContent={!!customContent}
-          ref={ref}
-          theme={theme}
-          $useReadMore={useReadMore}
-          $borderLess={borderLessCards}
-          $showMore={showMore}
-          $cardHeight={!textOverlay ? cardActualHeight : null}
-          $contentHeight={detailsHeight}
-          height={contentDetailsHeight}
-          $textOverlay={textOverlay}
-          $gradientColor={gradientColor}
-        >
-          {customContent ?? (
-            <TextContent
-              {...{ detailedText, showMore, theme, timelineContent }}
-            />
-          )}
-        </TimelineContentDetailsWrapper>
-      </>
-    );
-  },
-);
- 
-DetailsText.displayName = 'Details Text';
- 
-export { DetailsText };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/header-footer.model.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/header-footer.model.ts.html deleted file mode 100644 index 854cc1bea..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/header-footer.model.ts.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/header-footer.model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content header-footer.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineContentModel } from '@models/TimelineContentModel';
- 
-export type ContentHeaderProps = Pick<
-  TimelineContentModel,
-  'theme' | 'url' | 'title' | 'media' | 'content' | 'cardTitle'
->;
- 
-export type ContentFooterProps = {
-  canShow: boolean;
-  isNested?: boolean;
-  onExpand: () => void;
-  remainInterval: number;
-  showMore: boolean;
-  showReadMore?: boolean | '';
-  startWidth: number;
-  textContentIsLarge: boolean;
-  theme?: Theme;
-  triangleDir?: string;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/index.html deleted file mode 100644 index a9eaacb15..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/index.html +++ /dev/null @@ -1,236 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-content

-
- -
- 76.04% - Statements - 638/839 -
- - -
- 76.41% - Branches - 162/212 -
- - -
- 75% - Functions - 30/40 -
- - -
- 76.04% - Lines - 638/839 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
card-animations.styles.ts -
-
100%5/5100%0/0100%0/0100%5/5
content-footer.tsx -
-
91.11%41/4591.66%11/1250%1/291.11%41/45
content-header.tsx -
-
85.36%35/4190.9%10/11100%0/085.36%35/41
details-text.model.ts -
-
0%0/00%1/10%1/10%0/0
details-text.tsx -
-
100%54/5450%1/2100%0/0100%54/54
header-footer.model.ts -
-
0%0/00%1/10%1/10%0/0
text-or-content.tsx -
-
92.63%88/9579.31%23/29100%6/692.63%88/95
timeline-card-content.styles.ts -
-
65.1%125/19275.36%52/6968.96%20/2965.1%125/192
timeline-card-content.tsx -
-
71.25%290/40772.41%63/87100%1/171.25%290/407
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/text-or-content.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/text-or-content.tsx.html deleted file mode 100644 index 2dc48270c..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/text-or-content.tsx.html +++ /dev/null @@ -1,514 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/text-or-content.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content text-or-content.tsx

-
- -
- 92.63% - Statements - 88/95 -
- - -
- 79.31% - Branches - 23/29 -
- - -
- 100% - Functions - 6/6 -
- - -
- 92.63% - Lines - 88/95 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144  -  -1x -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -2x -2x -2x -2x -2x -2x -2x -  -4x -4x -  -  -  -  -  -4x -4x -4x -4x -4x -4x -4x -4x -  -4x -4x -  -2x -2x -  -  -1x -  -1x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -  -42x -42x -42x -  -  -42x -42x -40x -1x -39x -40x -  -2x -2x -42x -42x -42x -42x -42x -42x -  -  -42x -42x -1x -1x -1x -1x -1x -1x -41x -42x -  -42x -42x -  -42x -42x -42x -42x -42x -42x -  -42x -42x -  -42x -  -42x -42x -  -  -  -42x -42x -42x -  -42x -42x -42x -  -42x -  -42x -42x -  -  - 
import { TimelineContentModel } from '@models/TimelineContentModel';
-import { TimelineProps } from '@models/TimelineModel';
-import {
-  ForwardRefExoticComponent,
-  ReactNode,
-  forwardRef,
-  useContext,
-  useMemo,
-} from 'react';
-import xss from 'xss';
-import { GlobalContext } from '../../GlobalContext';
-import {
-  TimelineContentDetails,
-  TimelineSubContent,
-} from './timeline-card-content.styles';
- 
-// Define the type for the TextOrContentModel
-export type TextOrContentModel = Pick<
-  TimelineContentModel,
-  'timelineContent' | 'theme' | 'detailedText'
-> & {
-  showMore?: boolean;
-};
- 
-// Function to render an array of text
-const renderTextArray: (
-  p: Pick<TimelineProps, 'parseDetailsAsHTML' | 'fontSizes' | 'theme'> & {
-    cardTextClassName: string;
-    detailedText: (string | ReactNode)[];
-  },
-) => ReactNode = ({
-  fontSizes,
-  parseDetailsAsHTML,
-  theme,
-  detailedText,
-  cardTextClassName,
-}) => {
-  return detailedText.map((text, index) => {
-    // Only apply xss if text is a string
-    const props =
-      parseDetailsAsHTML && typeof text === 'string'
-        ? {
-            dangerouslySetInnerHTML: {
-              __html: xss(text),
-            },
-          }
-        : null;
-    return (
-      <TimelineSubContent
-        key={`timeline-text-${typeof text === 'string' ? text.substring(0, 10) : ''}-${index}`}
-        fontSize={fontSizes?.cardText}
-        className={cardTextClassName}
-        theme={theme}
-        {...props}
-      >
-        {parseDetailsAsHTML ? null : text}
-      </TimelineSubContent>
-    );
-  });
-};
- 
-// Function to get the TextOrContent component
-const getTextOrContent: (
-  p: TextOrContentModel,
-) => ForwardRefExoticComponent<TextOrContentModel> = ({
-  timelineContent,
-  theme,
-  detailedText,
-  showMore,
-}) => {
-  const TextOrContent = forwardRef<HTMLParagraphElement, TextOrContentModel>(
-    (prop, ref) => {
-      const isTextArray = Array.isArray(detailedText);
-      const { fontSizes, classNames, parseDetailsAsHTML, textDensity } =
-        useContext(GlobalContext);
- 
-      const shouldNotShowText = useMemo(() => {
-        return (parseDetailsAsHTML && !isTextArray) || textDensity === 'LOW';
-      }, [isTextArray, parseDetailsAsHTML, textDensity]);
- 
-      // Generate the text content based on detailedText
-      const getTextContent = () => {
-        if (!isTextArray) {
-          return parseDetailsAsHTML && typeof detailedText === 'string'
-            ? xss(detailedText)
-            : detailedText;
-        }
- 
-        return renderTextArray({
-          cardTextClassName: classNames?.cardText,
-          detailedText: detailedText as (string | ReactNode)[],
-          fontSizes,
-          parseDetailsAsHTML,
-          theme,
-        });
-      };
- 
-      // Create props for HTML content if needed
-      const getTextContentProps = (textContent) => {
-        if (parseDetailsAsHTML && !isTextArray) {
-          return {
-            dangerouslySetInnerHTML: {
-              __html: xss(textContent),
-            },
-          };
-        }
-        return {};
-      };
- 
-      const renderDetailedContent = (textContent) => {
-        const textContentProps = getTextContentProps(textContent);
- 
-        return (
-          <TimelineContentDetails
-            className={showMore ? 'active' : ''}
-            ref={ref}
-            theme={theme}
-            {...textContentProps}
-          >
-            {shouldNotShowText ? null : textContent}
-          </TimelineContentDetails>
-        );
-      };
- 
-      const renderTimelineContent = () => {
-        if (timelineContent) {
-          return <div ref={ref}>{timelineContent}</div>;
-        }
- 
-        const textContent = getTextContent();
-        return textContent ? renderDetailedContent(textContent) : null;
-      };
- 
-      return renderTimelineContent();
-    },
-  );
- 
-  TextOrContent.displayName = 'Text Or Content';
- 
-  return TextOrContent;
-};
- 
-export { getTextOrContent };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html deleted file mode 100644 index 3c6dd1c75..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts.html +++ /dev/null @@ -1,1762 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content timeline-card-content.styles.ts

-
- -
- 65.1% - Statements - 125/192 -
- - -
- 75.36% - Branches - 52/69 -
- - -
- 68.96% - Functions - 20/29 -
- - -
- 65.1% - Lines - 125/192 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512 -513 -514 -515 -516 -517 -518 -519 -520 -521 -522 -523 -524 -525 -526 -527 -528 -529 -530 -531 -532 -533 -534 -535 -536 -537 -538 -539 -540 -541 -542 -543 -544 -545 -546 -547 -548 -549 -550 -551 -552 -553 -554 -555 -556 -557 -558 -559 -560  -  -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -38x -  -38x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -38x -  -38x -  -  -  -  -  -  -  -38x -  -  -  -  -  -38x -38x -  -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -1x -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -1x -  -  -  -  -1x -1x -  -1x -1x -  -  -  -1x -  -  -  -1x -38x -  -  -  -  -  -  -  -1x -  -  -1x -38x -  -  -  -1x -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -1x -  -  -1x -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -1x -1x -  -  -1x -  -  -  -1x -1x -148x -1x -  -  -  -  -  -  -1x -1x -  -  -1x -  -  -  -  -1x -1x -113x -1x -  -  -  -  -  -  -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -1x -  -  -1x -38x -36x -1x -  -1x -38x -38x -38x -38x -38x -38x -38x -2x -1x -  -1x -  -  -1x -38x -38x -38x -38x -38x -38x -38x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TextDensity, TimelineProps } from '@models/TimelineModel';
-import styled, { css, keyframes } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
-import { linearGradient } from '../timeline-card-media/timeline-card-media.styles';
-import {
-  reveal,
-  slideFromRight,
-  slideInFromLeft,
-  slideInFromTop,
-} from './card-animations.styles';
- 
-// Common types
-type ContentT = Pick<
-  TimelineProps,
-  'theme' | 'slideShow' | 'mode' | 'borderLessCards'
->;
- 
-// Reusable styles with vendor prefixes
-const baseFontStyles = css`
-  margin: 0;
-  width: 100%;
-  text-align: left;
-`;
- 
-const baseCardStyles = css<{ $theme?: Theme }>`
-  background: ${(p) => p.$theme?.cardBgColor};
-  border-radius: 8px;
-  -webkit-box-shadow: 
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  box-shadow:
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  -webkit-transition: 
-    -webkit-transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
-  transition:
-    transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
-`;
- 
-const scrollbarStyles = css<{ theme?: Theme }>`
-  scrollbar-color: ${(p) => p.theme?.primary} default;
-  scrollbar-width: thin;
- 
-  &::-webkit-scrollbar {
-    width: 0.3em;
-  }
- 
-  &::-webkit-scrollbar-track {
-    background-color: ${(p) => p.theme?.cardBgColor};
-  }
- 
-  &::-webkit-scrollbar-thumb {
-    background-color: ${(p) => p.theme?.primary};
-    border-radius: 3px;
-  }
-`;
- 
-// Animation helpers
-const getSlideShowAnimation = (props) => {
-  const { $slideShowActive, $active, $slideShowType, $branchDir } = props;
- 
-  if (!$slideShowActive || !$active) return '';
- 
-  if ($slideShowType === 'slide_in') {
-    return css`
-      animation: ${slideInFromTop} 0.5s ease-in-out;
-    `;
-  }
- 
-  if ($slideShowType === 'slide_from_sides') {
-    if ($branchDir === 'left') {
-      return css`
-        animation: ${slideInFromLeft} 0.5s ease-in-out;
-      `;
-    }
-    if ($branchDir === 'right') {
-      return css`
-        animation: ${slideFromRight} 0.5s ease-in-out;
-      `;
-    }
-  }
- 
-  return css`
-    animation: ${reveal} 0.5s ease-in-out;
-  `;
-};
- 
-const getSlideShowVisibility = (props) => {
-  const { $slideShowActive, $active } = props;
- 
-  if ($slideShowActive && $active) {
-    return css`
-      opacity: 1;
-      animation-timing-function: ease-in-out;
-      animation-duration: 0.5s;
-    `;
-  }
- 
-  if ($slideShowActive && !$active) {
-    return css`
-      opacity: 0;
-    `;
-  }
- 
-  return '';
-};
- 
-// Slide animation for progress bar
-const slideAnimation = (start?: number, end?: number) => keyframes`
-  0% {
-    width: ${start}px;
-  }
-  100% {
-    width: ${end}px;
-  }
-`;
- 
-// Extract shared styles into a utility function
-const sharedSemanticStyles = css<{
-  $fontSize?: string;
-  $padding?: boolean;
-  theme: Theme;
-}>`
-  ${baseFontStyles}
-  font-size: ${(p) => p.$fontSize || '1.1rem'};
-  font-weight: 600;
-  margin-bottom: 0.5rem;
-  padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')};
-  display: block;
-`;
- 
-// Card Components
-export const TimelineItemContentWrapper = styled.section<
-  {
-    $active?: boolean;
-    $borderLessCards?: TimelineProps['borderLessCards'];
-    $branchDir?: string;
-    $customContent?: boolean;
-    $highlight?: boolean;
-    $isNested?: boolean;
-    $maxWidth?: number;
-    $minHeight?: number;
-    $noMedia?: boolean;
-    $slideShow?: TimelineProps['slideShow'];
-    $slideShowActive?: boolean;
-    $slideShowType?: TimelineProps['slideShowType'];
-    $textDensity?: TextDensity;
-    $textOverlay?: boolean;
-    $theme?: Theme;
-  } & ContentT
->`
-  ${baseCardStyles}
-  align-items: flex-start;
-  display: flex;
-  flex-direction: column;
-  justify-content: flex-start;
-  line-height: 1.5;
-  margin: 0;
-  max-width: ${(p) => p.$maxWidth}px;
-  position: relative;
-  padding: 1rem;
-  z-index: ${zIndex.timelineCard};
-  overflow: hidden;
-  width: 100%;
- 
-  // Handle text density and height
-  ${({ $textDensity, $customContent, $minHeight }) =>
-    `${$customContent ? 'height' : 'min-height'}: ${$minHeight}px`};
- 
-  ${(p) => (p.$textOverlay ? `min-height: ${p.$minHeight}px` : '')};
-  ${(p) => (p.$textOverlay ? 'height: 0' : '')};
- 
-  // Focus state
-  &:focus {
-    outline: 1px solid ${(p) => p.$theme?.primary};
-  }
- 
-  // Highlight effect
-  ${(p) =>
-    p.$highlight &&
-    css`
-      &:hover {
-        transform: translateY(-2px);
-        box-shadow:
-          0 2px 5px ${p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.08)'},
-          0 8px 16px ${p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'};
-      }
-    `}
- 
-  // Nested card styling
-  ${(p) =>
-    p.$isNested &&
-    css`
-      background: ${p.$theme?.nestedCardBgColor};
-      box-shadow: 0 1px 2px ${p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.05)'};
-    `}
- 
-  // Animations
-  ${getSlideShowAnimation}
-  ${getSlideShowVisibility}
-`;
- 
-// Header Components
-export const TimelineCardHeader = styled.header`
-  width: 100%;
-  padding: 0;
-  margin-bottom: 0.5rem;
-`;
- 
-export const CardTitle = styled.h1<{
-  $fontSize: string;
-  $padding?: boolean;
-  dir?: string;
-  theme: Theme;
-}>`
-  ${baseFontStyles}
-  color: ${(p) => p.theme.cardTitleColor};
-  font-size: ${(p) => p.$fontSize && '1.1rem'};
-  font-weight: 600;
-  margin-bottom: 0.5rem;
-  padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')};
- 
-  &.active {
-    color: ${(p) => p.theme.primary};
-  }
-`;
- 
-export const CardSubTitle = styled.h2<{
-  $fontSize?: string;
-  $padding?: boolean;
-  dir?: string;
-  theme?: Theme;
-}>`
-  ${baseFontStyles}
-  color: ${(p) => p.theme.cardSubtitleColor};
-  font-size: ${(p) => p.$fontSize && '0.9rem'};
-  font-weight: 500;
-  margin-bottom: 0.25rem;
-  padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')};
-`;
- 
-// Refactor CardTitleSemantic to use shared styles
-export const CardTitleSemantic = styled.h1.withConfig({
-  shouldForwardProp: (prop) =>
-    !['$fontSize', '$padding', 'theme'].includes(prop),
-})<{
-  $fontSize: string;
-  $padding?: boolean;
-  dir?: string;
-  theme: Theme;
-  as?: string;
-}>`
-  ${sharedSemanticStyles}
-  color: ${(p) => p.theme.cardTitleColor};
- 
-  &.active {
-    color: ${(p) => p.theme.primary};
-  }
-`;
- 
-// Refactor CardSubTitleSemantic to use shared styles
-export const CardSubTitleSemantic = styled.span.withConfig({
-  shouldForwardProp: (prop) =>
-    !['$fontSize', '$padding', 'theme'].includes(prop),
-})<{
-  $fontSize?: string;
-  $padding?: boolean;
-  dir?: string;
-  theme: Theme;
-  as?: string;
-}>`
-  ${sharedSemanticStyles}
-  color: ${(p) => p.theme.cardSubtitleColor};
-  font-size: ${(p) => p.$fontSize || '0.9rem'};
-`;
- 
-export const CardTitleAnchor = styled.a`
-  color: inherit;
- 
-  &:active {
-    color: inherit;
-  }
-`;
- 
-// Content Components
-export const TimelineContentDetails = styled.p<{ theme?: Theme }>`
-  font-size: 0.85rem;
-  font-weight: 400;
-  margin: 0;
-  width: 100%;
-  color: ${(p) => p.theme.cardDetailsColor};
-  line-height: 1.5;
-`;
- 
-export const TimelineSubContent = styled.span<{
-  fontSize?: string;
-  theme?: Theme;
-}>`
-  margin-bottom: 0.5rem;
-  display: block;
-  font-size: ${(p) => p.fontSize && '0.8rem'};
-  color: ${(p) => p.theme.cardDetailsColor};
-`;
- 
-export const TimelineContentDetailsWrapper = styled.div<{
-  $borderLess?: boolean;
-  $cardHeight?: number | null;
-  $contentHeight?: number;
-  $customContent?: boolean;
-  $gradientColor?: string | null;
-  $showMore?: boolean;
-  $textOverlay?: boolean;
-  $useReadMore?: boolean;
-  branchDir?: string;
-  height?: number;
-  theme?: Theme;
-}>`
-  ${scrollbarStyles}
-  align-items: flex-start;
-  display: flex;
-  flex-direction: column;
-  margin: 0;
-  position: relative;
-  overflow-x: hidden;
-  overflow-y: auto;
-  transition: max-height 0.25s ease-in-out;
-  width: ${(p) => (p.$borderLess ? 'calc(100% - 0.5rem)' : '100%')};
-  padding: 0;
-  background: ${(p) => p.theme?.cardDetailsBackGround || p.theme?.cardBgColor};
- 
-  // Height handling based on different conditions
-  ${({ $useReadMore, $customContent, $showMore, height = 0, $textOverlay }) =>
-    $useReadMore && !$customContent && !$showMore && !$textOverlay
-      ? `max-height: ${height}px;`
-      : 'height: 100%'};
- 
-  ${({
-    $cardHeight = 0,
-    $contentHeight = 0,
-    height = 0,
-    $showMore,
-    $textOverlay,
-  }) =>
-    $showMore && !$textOverlay
-      ? `max-height: ${($cardHeight ?? 0) + ($contentHeight ?? 0) - height}px;`
-      : ''}
- 
-  ${(p) => (p.$customContent ? `height: 100%;` : '')}
- 
-  // Animation for show more
-  ${({
-    height = 0,
-    $cardHeight = 0,
-    $contentHeight = 0,
-    $showMore,
-    $useReadMore,
-  }) =>
-    $showMore && $useReadMore && $cardHeight
-      ? css`
-          animation: ${keyframes`
-            0% {
-              max-height: ${height}px;
-            }
-            100% {
-             max-height: ${$cardHeight + $contentHeight - height}px;
-            }
-          `} 0.25s ease-in-out;
-        `
-      : ''}
-      
-  &.show-less {
-    scrollbar-width: none;
-    &::-webkit-scrollbar {
-      width: 0;
-    }
-    overflow: hidden;
-  }
- 
-  // Gradient for "show more" functionality
-  --rc-gradient-color: ${(p) => p.$gradientColor};
-  ${linearGradient}
-`;
- 
-// Interactive Elements
-export const ShowMore = styled.button<{
-  show?: 'true' | 'false';
-  theme?: Theme;
-}>`
-  align-items: center;
-  align-self: flex-end;
-  border-radius: 4px;
-  cursor: pointer;
-  display: ${(p) => (p.show === 'true' ? 'flex' : 'none')};
-  font-size: 0.75rem;
-  justify-self: flex-end;
-  margin: auto 0.5em 0.5em auto;
-  padding: 0.25em;
-  color: ${(p) => p.theme.primary};
-  border: 0;
-  background: none;
- 
-  &:hover {
-    text-decoration: underline;
-  }
-`;
- 
-export const SlideShowProgressBar = styled.progress<{
-  $color?: string;
-  $duration?: number;
-  $resuming?: boolean;
-  $startWidth?: number;
-}>`
-  background: ${(p) => p.color};
-  bottom: -0.75em;
-  display: block;
-  height: 4px;
-  left: 50%;
-  transform: translateX(-50%);
-  position: absolute;
-  border-radius: 2px;
-  border: 0;
-  outline: none; /* Remove the outline/border */
- 
-  /* Remove the default styling from progress element */
-  &::-webkit-progress-bar {
-    background-color: transparent;
-    border: 0;
-  }
- 
-  &::-webkit-progress-value {
-    background-color: ${(p) => p.color || '#007bff'};
-    border-radius: 2px;
-  }
- 
-  &::-moz-progress-bar {
-    background-color: ${(p) => p.color || '#007bff'};
-    border-radius: 2px;
-  }
- 
-  // Animation control - simplified without pause
-  ${(p) => {
-    if (p.$startWidth && p.$startWidth > 0) {
-      return css`
-        animation: ${slideAnimation(p.$startWidth, 0)} ${p.$duration}ms ease-in;
-        animation-play-state: running;
-      `;
-    } else {
-      return css`
-        width: ${p.$startWidth}px;
-      `;
-    }
-  }}
- 
-  svg {
-    position: absolute;
-    left: 0;
-    top: 0;
-    width: 100%;
-  }
-`;
- 
-// Icon Wrappers
-export const ChevronIconWrapper = styled.span<{ collapsed?: 'true' | 'false' }>`
-  align-items: center;
-  display: flex;
-  height: 1.25em;
-  justify-content: center;
-  margin-left: 0.2em;
-  margin-top: 0.2em;
-  width: 1.25em;
-  transform: ${(p) =>
-    p.collapsed === 'false' ? 'rotate(90deg)' : 'rotate(-90deg)'};
- 
-  svg {
-    height: 100%;
-    width: 100%;
-  }
-`;
- 
-export const TriangleIconWrapper = styled.span<{
-  dir?: string;
-  offset?: number;
-  theme?: Theme;
-}>`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  width: 1.5rem;
-  height: 1.5rem;
-  position: absolute;
-  top: calc(50%);
-  background: ${(p) => p.theme.cardBgColor};
-  transform: translateY(-50%) rotate(225deg);
-  z-index: ${zIndex.timelineCard - 3}; /* Arrow tip should be below the card */
-  ${(p) =>
-    p.dir === 'left' ? `right: ${p.offset}px;` : `left: ${p.offset}px;`}
- 
-  & svg {
-    width: 100%;
-    height: 100%;
-    fill: #fff;
-  }
-`;
- 
-// Search highlighting
-export const Mark = styled.mark<{ theme: Theme }>`
-  background-color: ${(p) =>
-    p.theme?.searchHighlightColor ||
-    (p.theme?.primary ? `${p.theme.primary}30` : 'rgba(255, 217, 0, 0.3)')};
-  color: inherit;
-  font-weight: 600;
-  padding: 0.1em 0.25em;
-  margin: 0 -0.1em;
-  border-radius: 2px;
-  box-decoration-break: clone;
-  -webkit-box-decoration-break: clone;
-  transition:
-    background-color 0.2s ease-out,
-    box-shadow 0.15s ease-out;
- 
-  &[data-current-match='true'] {
-    background-color: ${(p) => {
-      if (p.theme?.searchHighlightColor) {
-        // If custom search highlight color is provided, make it more intense
-        const color = p.theme.searchHighlightColor;
-        // Extract opacity and increase it for current match
-        if (color.includes('rgba')) {
-          return color.replace(/0\.\d+\)$/, '0.6)');
-        }
-        return color;
-      }
- 
-      // Fallback logic
-      if (p.theme?.primary) {
-        return p.theme.cardBgColor === '#1f2937'
-          ? `rgba(96, 165, 250, 0.6)` // More intense for current match in dark mode
-          : `${p.theme.primary}50`; // Standard for light mode
-      }
-      return 'rgba(255, 217, 0, 0.5)';
-    }};
-    box-shadow: 0 0 0 1px
-      ${(p) => {
-        if (p.theme?.iconColor) {
-          return p.theme.iconColor;
-        }
- 
-        // Fallback logic
-        if (p.theme?.primary) {
-          return p.theme.cardBgColor === '#1f2937'
-            ? 'rgba(96, 165, 250, 0.8)'
-            : p.theme.primary;
-        }
-        return 'rgba(255, 217, 0, 0.5)';
-      }};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html deleted file mode 100644 index 43d808884..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-content/timeline-card-content.tsx.html +++ /dev/null @@ -1,1618 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-content/timeline-card-content.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-content timeline-card-content.tsx

-
- -
- 71.25% - Statements - 290/407 -
- - -
- 72.41% - Branches - 63/87 -
- - -
- 100% - Functions - 1/1 -
- - -
- 71.25% - Lines - 290/407 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -429 -430 -431 -432 -433 -434 -435 -436 -437 -438 -439 -440 -441 -442 -443 -444 -445 -446 -447 -448 -449 -450 -451 -452 -453 -454 -455 -456 -457 -458 -459 -460 -461 -462 -463 -464 -465 -466 -467 -468 -469 -470 -471 -472 -473 -474 -475 -476 -477 -478 -479 -480 -481 -482 -483 -484 -485 -486 -487 -488 -489 -490 -491 -492 -493 -494 -495 -496 -497 -498 -499 -500 -501 -502 -503 -504 -505 -506 -507 -508 -509 -510 -511 -512  -  -1x -1x -1x -  -  -  -  -  -  -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -4x -4x -4x -  -4x -  -  -4x -  -  -4x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -48x -48x -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -48x -48x -48x -48x -48x -48x -48x -  -  -48x -34x -48x -  -48x -34x -48x -  -48x -34x -34x -32x -28x -28x -  -48x -  -48x -34x -48x -  -48x -  -34x -34x -28x -28x -  -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -34x -34x -28x -28x -48x -  -  -48x -34x -6x -6x -48x -  -  -48x -38x -  -  -  -38x -  -  -  -38x -  -  -  -38x -38x -38x -48x -  -  -48x -38x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -48x -  -  -48x -34x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -48x -  -  -48x -34x -  -  -48x -  -  -48x -34x -  -  -34x -34x -34x -48x -  -  -48x -48x -  -  -  -  -  -  -  -  -  -  -  -48x -48x -  -48x -  -  -  -48x -  -48x -  -  -  -  -  -  -  -  -  -  -  -  -48x -  -  -48x -34x -32x -32x -2x -48x -  -48x -34x -48x -  -48x -34x -34x -34x -34x -34x -48x -  -  -48x -34x -34x -12x -5x -  -48x -  -  -48x -  -34x -  -  -  -  -  -  -  -34x -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -34x -  -34x -34x -34x -  -  -48x -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -48x -48x -48x -48x -48x -48x -48x -48x -  -  -48x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -16x -  -  -48x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -  -  -48x -  -  -  -  -  -  -  -  -48x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -42x -  -48x -  -48x -1x -1x -  -1x - 
import { TimelineContentModel } from '@models/TimelineContentModel';
-import { MediaState } from '@models/TimelineMediaModel';
-import { hexToRGBA } from '@utils/index';
-import cls from 'classnames';
-import React, {
-  useCallback,
-  useContext,
-  useEffect,
-  useMemo,
-  useRef,
-  useState,
-} from 'react';
-import { useSlideshow } from 'src/components/effects/useSlideshow';
-import { useCardSize } from '../../../hooks/useCardSize';
-import { GlobalContext } from '../../GlobalContext';
-// Remove the Timeline import to break the circular dependency
-// import Timeline from '../../timeline/timeline';
-import CardMedia from '../timeline-card-media/timeline-card-media';
-import { ContentFooter } from './content-footer';
-import { ContentHeader } from './content-header';
-import { DetailsText } from './details-text';
-import { getTextOrContent } from './text-or-content';
-import { TimelineItemContentWrapper } from './timeline-card-content.styles';
-import NestedTimelineRenderer from '../nested-timeline-renderer/nested-timeline-renderer';
- 
-// Custom equality function for React.memo to prevent unnecessary re-renders
-const arePropsEqual = (
-  prevProps: TimelineContentModel,
-  nextProps: TimelineContentModel,
-): boolean => {
-  // Always re-render if active state changes
-  if (prevProps.active !== nextProps.active) return false;
- 
-  // Re-render if slideshow state changes
-  if (prevProps.slideShowActive !== nextProps.slideShowActive) return false;
- 
-  // Re-render if hasFocus changes
-  if (prevProps.hasFocus !== nextProps.hasFocus) return false;
- 
-  // Only re-render content-related props if they actually change
-  if (prevProps.content !== nextProps.content) return false;
-  if (prevProps.detailedText !== nextProps.detailedText) return false;
-  if (prevProps.title !== nextProps.title) return false;
-  if (prevProps.cardTitle !== nextProps.cardTitle) return false;
- 
-  // Skip re-render if media props stay the same
-  if (JSON.stringify(prevProps.media) !== JSON.stringify(nextProps.media))
-    return false;
- 
-  // Skip re-render if theme stays the same
-  if (JSON.stringify(prevProps.theme) !== JSON.stringify(nextProps.theme))
-    return false;
- 
-  // Skip re-render if items (for nested timeline) stay the same
-  if (JSON.stringify(prevProps.items) !== JSON.stringify(nextProps.items))
-    return false;
- 
-  // Default to true - don't re-render
-  return true;
-};
- 
-const TimelineCardContent: React.FunctionComponent<TimelineContentModel> =
-  React.memo(
-    ({
-      active,
-      content,
-      detailedText,
-      id,
-      media,
-      onShowMore,
-      slideShowActive,
-      onElapsed,
-      theme,
-      onClick,
-      customContent,
-      hasFocus,
-      flip,
-      branchDir,
-      url,
-      timelineContent,
-      items,
-      isNested,
-      nestedCardHeight,
-      title,
-      cardTitle,
-    }: TimelineContentModel) => {
-      const [showMore, setShowMore] = useState(false);
-      const detailsRef = useRef<HTMLDivElement | null>(null);
-      const containerRef = useRef<HTMLDivElement | null>(null);
-      const progressRef = useRef<HTMLProgressElement | null>(null);
-      const isFirstRender = useRef(true);
- 
-      const [hasBeenActivated, setHasBeenActivated] = useState(false);
-      const [isResuming, setIsResuming] = useState(false);
- 
-      const {
-        mode,
-        cardHeight,
-        slideItemDuration = 2000,
-        useReadMore,
-        cardWidth,
-        borderLessCards,
-        disableAutoScrollOnClick,
-        classNames,
-        textOverlay,
-        slideShowType,
-        showProgressOnSlideshow,
-        disableInteraction,
-        highlightCardsOnHover,
-        textDensity,
-      } = useContext(GlobalContext);
- 
-      const {
-        paused,
-        remainInterval,
-        startWidth,
-        tryPause,
-        setupTimer,
-        setStartWidth,
-      } = useSlideshow(
-        progressRef,
-        active,
-        slideShowActive,
-        slideItemDuration,
-        id,
-        onElapsed,
-      );
- 
-      const { cardActualHeight, detailsHeight, textContentLarge } = useCardSize(
-        {
-          containerRef,
-          detailsRef,
-          setStartWidth,
-        },
-      );
- 
-      // Memoize all calculated values to prevent re-renders
-      const canShowProgressBar = useMemo(() => {
-        return active && slideShowActive && showProgressOnSlideshow;
-      }, [active, slideShowActive, showProgressOnSlideshow]);
- 
-      const canShowMore = useMemo(() => {
-        return !!detailedText;
-      }, [detailedText]);
- 
-      const canShowReadMore = useMemo(() => {
-        return (
-          useReadMore &&
-          detailedText &&
-          !customContent &&
-          textDensity === 'HIGH'
-        );
-      }, [useReadMore, detailedText, customContent, textDensity]);
- 
-      const canShowNestedTimeline = useMemo(() => {
-        return items && items.length > 0;
-      }, [items]);
- 
-      const canShowDetailsText = useMemo(() => {
-        // Hide details when using text overlay with media, when density is LOW, otherwise show if content exists
-        return (
-          (detailedText ?? customContent ?? timelineContent) &&
-          !(textOverlay && media) &&
-          textDensity !== 'LOW'
-        );
-      }, [
-        detailedText,
-        customContent,
-        timelineContent,
-        textOverlay,
-        media,
-        textDensity,
-      ]);
- 
-      // Reset details scroll position when toggling details
-      useEffect(() => {
-        const detailsEle = detailsRef.current;
-        if (detailsEle) {
-          detailsEle.scrollTop = 0;
-        }
-      }, [showMore]);
- 
-      // Handle card activation
-      useEffect(() => {
-        if (active && !hasBeenActivated) {
-          setHasBeenActivated(true);
-        }
-      }, [active, hasBeenActivated]);
- 
-      // Setup timer when card becomes active
-      useEffect(() => {
-        if (!slideItemDuration) {
-          return;
-        }
- 
-        if (active && slideShowActive) {
-          setupTimer(slideItemDuration);
-        }
- 
-        if (active && hasFocus && containerRef.current) {
-          containerRef.current.focus();
-        }
- 
-        if (!slideShowActive) {
-          setHasBeenActivated(false);
-        }
-      }, [active, slideShowActive, slideItemDuration, hasFocus, setupTimer]);
- 
-      // Set focus when needed and ensure entire card row is completely visible
-      useEffect(() => {
-        if (hasFocus && active && containerRef.current) {
-          containerRef.current.focus();
-          
-          // Ensure the entire vertical item row is completely visible when it receives focus
-          setTimeout(() => {
-            if (containerRef.current) {
-              const isVerticalMode = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-              
-              if (isVerticalMode) {
-                // In vertical mode, scroll the entire vertical-item-row into view
-                const verticalItemRow = containerRef.current.closest('[data-testid="vertical-item-row"]');
-                if (verticalItemRow) {
-                  verticalItemRow.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                } else {
-                  // Fallback to card content if row not found
-                  containerRef.current.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                }
-              } else {
-                // In horizontal mode, use 'nearest' for optimal positioning
-                containerRef.current.scrollIntoView({
-                  behavior: 'smooth',
-                  block: 'nearest',
-                  inline: 'nearest'
-                });
-              }
-            }
-          }, 0);
-        }
-      }, [hasFocus, active, mode]);
- 
-      // Ensure card alignment during slideshow, independent of hasFocus state
-      useEffect(() => {
-        if (active && slideShowActive && containerRef.current) {
-          // During slideshow, ensure the active card is properly aligned and visible
-          setTimeout(() => {
-            if (containerRef.current) {
-              const isVerticalMode = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-              
-              if (isVerticalMode) {
-                // In vertical mode, scroll the entire vertical-item-row into view
-                const verticalItemRow = containerRef.current.closest('[data-testid="vertical-item-row"]');
-                if (verticalItemRow) {
-                  verticalItemRow.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                } else {
-                  // Fallback to card content if row not found
-                  containerRef.current.scrollIntoView({
-                    behavior: 'smooth',
-                    block: 'center',
-                    inline: 'nearest'
-                  });
-                }
-              } else {
-                // In horizontal mode, use 'nearest' for optimal positioning
-                containerRef.current.scrollIntoView({
-                  behavior: 'smooth',
-                  block: 'nearest',
-                  inline: 'nearest'
-                });
-              }
-            }
-          }, 100); // Slightly longer delay for slideshow to ensure proper DOM updates
-        }
-      }, [active, slideShowActive, mode]);
- 
-      // Detect when resuming from pause
-      useEffect(() => {
-        if (!paused && !isFirstRender.current) {
-          setIsResuming(true);
-        }
-      }, [paused]);
- 
-      // Track first render
-      useEffect(() => {
-        isFirstRender.current = false;
- 
-        // Cleanup function
-        return () => {
-          isFirstRender.current = true;
-        };
-      }, []);
- 
-      // Memoize handler functions
-      const handleMediaState = useCallback(
-        (state: MediaState) => {
-          if (!slideShowActive) {
-            return;
-          }
-          if (state.playing) {
-            tryPause();
-          } else if (state.paused) {
-            if (paused && id && onElapsed) {
-              onElapsed(id);
-            }
-          }
-        },
-        [slideShowActive, tryPause, paused, id, onElapsed],
-      );
- 
-      const handleCardClick = useCallback(() => {
-        if (onClick && !disableInteraction && !disableAutoScrollOnClick) {
-          onClick(id);
-        }
-      }, [onClick, id, disableInteraction, disableAutoScrollOnClick]);
- 
-      const toggleShowMore = useCallback(() => {
-        if ((active && paused) || !slideShowActive) {
-          setShowMore((prev) => !prev);
-          onShowMore?.();
-          // Use setTimeout to ensure the DOM has updated before focusing
-          setTimeout(() => {
-            if (containerRef.current) {
-              containerRef.current.focus();
-              // Force focus styles to be visible
-              containerRef.current.classList.add('focus-visible');
-            }
-          }, 0);
-        }
-      }, [active, paused, slideShowActive, onShowMore]);
- 
-      // Memoize computed values to prevent re-renders
-      const triangleDir = useMemo(() => {
-        if (mode === 'VERTICAL_ALTERNATING') {
-          return flip ? 'right' : 'left';
-        }
-        return null;
-      }, [mode, flip]);
- 
-      const gradientColor = useMemo(() => {
-        return hexToRGBA(theme?.cardBgColor ?? '#fff', 0.4);
-      }, [theme?.cardBgColor]);
- 
-      const contentDetailsClass = useMemo(() => {
-        return cls(
-          'card-description',
-          classNames?.cardText ?? '',
-          borderLessCards ? 'no-border' : '',
-        );
-      }, [classNames?.cardText, borderLessCards]);
- 
-      // Get the accessible label for the card
-      const accessibleLabel = useMemo(() => {
-        return (
-          (typeof cardTitle === 'string' ? cardTitle : null) ??
-          (typeof title === 'string' ? title : null) ??
-          'Timeline card'
-        );
-      }, [cardTitle, title]);
- 
-      // Create the detailsText component for text overlay mode using the proper function
-      const detailsTextComponent = useMemo(() => {
-        // Only create the component if we need it for text overlay mode
-        if (textOverlay && (detailedText ?? customContent ?? timelineContent)) {
-          return getTextOrContent({
-            timelineContent,
-            theme,
-            detailedText,
-            showMore,
-          });
-        }
-        return null;
-      }, [
-        textOverlay,
-        detailedText,
-        customContent,
-        timelineContent,
-        theme,
-        showMore,
-      ]);
- 
-      // The card's minimum height
-      const cardMinHeight = useMemo(() => {
-        if (textOverlay && media) {
-          return cardHeight;
-        } else if (!isNested) {
-          return cardHeight;
-        } else {
-          return nestedCardHeight;
-        }
-      }, [textOverlay, media, isNested, cardHeight, nestedCardHeight]);
- 
-      return (
-        <TimelineItemContentWrapper
-          as="article"
-          aria-label={accessibleLabel}
-          ref={containerRef}
-          onClick={handleCardClick}
-          className={`timeline-card-content ${active ? 'active' : ''} ${
-            classNames?.card ?? ''
-          }`}
-          data-testid="timeline-card-content"
-          data-item-id={id}
-          $active={active}
-          $branchDir={branchDir}
-          $slideShowActive={slideShowActive}
-          $slideShowType={slideShowType}
-          tabIndex={active ? 0 : -1}
-          onDoubleClick={toggleShowMore}
-          $minHeight={cardMinHeight}
-          $maxWidth={cardWidth}
-          mode={mode}
-          $noMedia={!media}
-          $textOverlay={textOverlay}
-          $isNested={isNested}
-          $highlight={highlightCardsOnHover}
-          $borderLessCards={borderLessCards}
-          $textDensity={textDensity}
-          $customContent={!!customContent}
-          $theme={theme}
-        >
-          {/* Only show the content header if we're not using text overlay mode with media */}
-          {(!textOverlay || !media) && (
-            <ContentHeader
-              title={title}
-              url={url}
-              media={media}
-              content={content}
-              cardTitle={cardTitle}
-              theme={theme}
-            />
-          )}
- 
-          {media && (
-            <CardMedia
-              active={active}
-              cardHeight={cardHeight}
-              content={content}
-              hideMedia={showMore}
-              id={id}
-              media={media}
-              onMediaStateChange={handleMediaState}
-              slideshowActive={slideShowActive}
-              theme={theme}
-              title={typeof title === 'string' ? title : ''}
-              url={url}
-              startWidth={startWidth}
-              detailsText={detailsTextComponent}
-              paused={paused}
-              remainInterval={remainInterval}
-              showProgressBar={canShowProgressBar}
-              triangleDir={triangleDir}
-              resuming={isResuming}
-              progressRef={progressRef}
-            />
-          )}
- 
-          {canShowDetailsText && (
-            <DetailsText
-              showMore={showMore}
-              gradientColor={gradientColor}
-              detailedText={detailedText}
-              customContent={customContent}
-              timelineContent={timelineContent}
-              contentDetailsClass={contentDetailsClass}
-              cardActualHeight={cardActualHeight}
-              detailsHeight={detailsHeight}
-              ref={detailsRef}
-            />
-          )}
- 
-          {canShowNestedTimeline && (
-            <NestedTimelineRenderer
-              items={items}
-              mode={'VERTICAL'}
-              nestedCardHeight={nestedCardHeight}
-              isChild={true}
-            />
-          )}
- 
-          {canShowReadMore && canShowMore && !textOverlay && (
-            <ContentFooter
-              onExpand={toggleShowMore}
-              triangleDir={triangleDir}
-              showMore={showMore}
-              textContentIsLarge={textContentLarge}
-              showReadMore={canShowReadMore}
-              remainInterval={remainInterval}
-              startWidth={startWidth}
-              canShow={!!detailedText && !showMore}
-              isNested={isNested}
-              theme={theme}
-            />
-          )}
-        </TimelineItemContentWrapper>
-      );
-    },
-    arePropsEqual,
-  );
- 
-export default TimelineCardContent;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/index.html deleted file mode 100644 index bddb84914..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media/__tests__

-
- -
- 100% - Statements - 201/201 -
- - -
- 100% - Branches - 10/10 -
- - -
- 0% - Functions - 0/8 -
- - -
- 100% - Lines - 201/201 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-media.test.tsx -
-
100%201/201100%10/100%0/8100%201/201
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html deleted file mode 100644 index c946b2d61..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx.html +++ /dev/null @@ -1,763 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/__tests__ timeline-card-media.test.tsx

-
- -
- 100% - Statements - 201/201 -
- - -
- 100% - Branches - 10/10 -
- - -
- 0% - Functions - 0/8 -
- - -
- 100% - Lines - 201/201 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -2271x -1x -1x -1x -  -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe } from 'vitest';
-import { customRender, providerProps } from '../../../common/test';
-import TimelineCardMedia from '../timeline-card-media';
-import { forwardRef } from 'react';
-import { TextOrContentModel } from '../../timeline-card-content/text-or-content';
- 
-describe('Timeline Card media', () => {
-  // should render the component with all the props
-  const refComponent = forwardRef<HTMLDivElement, TextOrContentModel>(
-    (props, ref) => <div ref={ref}>ref component</div>,
-  );
- 
-  refComponent.displayName = 'ref component';
-  it('should render the component with all the props', async () => {
-    const { getByText, getByAltText, getByRole } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-        title="Image title"
-        content="This is another test"
-        cardHeight={300}
-        active
-      />,
-      {
-        providerProps: { ...providerProps, semanticTags: { cardTitle: 'h1' } },
-      },
-    );
- 
-    expect(getByText('Image title')).toBeInTheDocument();
-    expect(getByText('This is another test')).toBeInTheDocument();
-    expect(getByAltText('Image')).toBeInTheDocument();
-    expect(getByRole('heading', { level: 1 })).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot ( IMAGE )', () => {
-    const { container } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        content="This is another test"
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps },
-    );
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot ( VIDEO )', () => {
-    const { container } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Video',
-          source: {
-            type: 'URL',
-            url: 'https://www.youtube.com/watch?v=9bZkp7q19f0',
-          },
-          type: 'VIDEO',
-        }}
-        detailsText={refComponent}
-        content="This is another test"
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps },
-    );
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render video media when type is VIDEO
-  it('should render video media when type is VIDEO', () => {
-    const { getByTitle } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Video',
-          source: {
-            type: 'URL',
-            url: 'https://www.youtube.com/watch?v=9bZkp7q19f0',
-          },
-          type: 'VIDEO',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps },
-    );
-    expect(getByTitle('Video')).toBeInTheDocument();
-  });
- 
-  //should render the card media in text overlay mode
-  it('should render the card media in text overlay mode', () => {
-    const customProviderProps = {
-      ...providerProps,
-      textOverlay: true,
-      semanticTags: { cardTitle: 'h1' },
-    };
- 
-    const { getByRole, getByText, getByAltText } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        content="This is another test"
-        title="Image title"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps: customProviderProps },
-    );
- 
-    expect(getByText('Image title')).toBeInTheDocument();
-    expect(getByText('This is another test')).toBeInTheDocument();
-    expect(getByAltText('Image')).toBeInTheDocument();
-    expect(getByRole('heading', { level: 1 })).toBeInTheDocument();
-  });
- 
-  // should render custom content in the card media
-  it('should render custom content in the card media', () => {
-    const { getByText } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-        content={<div>Custom content</div>}
-      />,
-      { providerProps },
-    );
- 
-    expect(getByText('Custom content')).toBeInTheDocument();
-  });
- 
-  // generate large chunks of random text
- 
-  // should render detailsText as expected IN HORIZONTAL MODE
-  it('should render detailsText as expected', () => {
-    const { getByText, getByRole } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-        title="Image title"
-        content="This is another test"
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-          mode: 'HORIZONTAL',
-          semanticTags: { cardTitle: 'h1' },
-        },
-      },
-    );
- 
-    expect(getByRole('heading', { level: 1 })).toBeInTheDocument();
-    expect(getByText('Image title')).toBeInTheDocument();
-  });
- 
-  // should render the arrow (triangleDir) as expected
-  it('should render the arrow (triangleDir) as expected', () => {
-    const { getByTestId } = customRender(
-      <TimelineCardMedia
-        media={{
-          name: 'Image',
-          source: {
-            type: 'URL',
-            url: 'https://picsum.photos/200/300',
-          },
-          type: 'IMAGE',
-        }}
-        detailsText={refComponent}
-        id="1"
-        hideMedia={false}
-        onMediaStateChange={() => {}}
-      />,
-      { providerProps: { ...providerProps, textOverlay: true } },
-    );
-    expect(getByTestId('arrow-icon')).toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html deleted file mode 100644 index e0157237d..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx.html +++ /dev/null @@ -1,469 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components ContentDisplay.tsx

-
- -
- 100% - Statements - 90/90 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 90/90 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -1291x -1x -  -  -  -1x -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -14x -  -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -14x -8x -8x -8x -8x -8x -8x -8x -8x -  -14x -  -14x -  -  -1x -  -  -1x - 
import React, { useRef, ReactNode } from 'react';
-import {
-  CardMediaHeader,
-  MediaDetailsWrapper,
-} from '../timeline-card-media.styles';
-import { TitleMemo } from '../../memoized/title-memo';
-import { ButtonWrapper } from '../timeline-card-media-buttons';
-import { ShowOrHideTextButtonMemo } from '../../memoized/show-hide-button';
-import { ExpandButtonMemo } from '../../memoized/expand-button-memo';
-import { SubTitleMemo } from '../../memoized/subtitle-memo';
-import { DetailsTextMemo } from '../../memoized/details-text-memo';
-import { TimelineMode } from '@models/TimelineModel';
- 
-export interface ContentDisplayProps {
-  readonly mode: TimelineMode;
-  readonly textOverlay: boolean;
-  readonly theme: any;
-  readonly expandDetails: boolean;
-  readonly showText: boolean;
-  readonly canExpand: boolean;
-  readonly canShowGradient: boolean;
-  readonly gradientColor: string | null;
-  readonly title?: ReactNode;
-  readonly active: boolean;
-  readonly url?: string;
-  readonly fontSizes: any;
-  readonly classNames: any;
-  readonly toggleText: () => void;
-  readonly toggleExpand: () => void;
-  readonly content?: ReactNode;
-  readonly canShowTextMemo: boolean;
-  readonly detailsText?: any; // Use 'any' to bypass type checking temporarily
-  readonly onDetailsTextRef: (height?: number) => void;
-}
- 
-const ContentDisplayComponent: React.FunctionComponent<ContentDisplayProps> = (
-  props,
-) => {
-  const {
-    mode,
-    textOverlay,
-    theme,
-    expandDetails,
-    showText,
-    canExpand,
-    canShowGradient,
-    gradientColor,
-    title,
-    active,
-    url,
-    fontSizes,
-    classNames,
-    toggleText,
-    toggleExpand,
-    content,
-    canShowTextMemo,
-    detailsText,
-    onDetailsTextRef,
-  } = props;
- 
-  const moreRef = useRef(null);
- 
-  return (
-    <MediaDetailsWrapper
-      mode={mode}
-      $absolutePosition={textOverlay}
-      $textInMedia={textOverlay}
-      ref={moreRef}
-      theme={theme}
-      $expandFull={expandDetails}
-      $showText={showText}
-      $expandable={canExpand}
-      $gradientColor={canShowGradient ? gradientColor : null}
-    >
-      <CardMediaHeader>
-        <TitleMemo
-          title={title}
-          theme={theme}
-          active={active}
-          url={url}
-          fontSize={fontSizes?.cardTitle}
-          classString={classNames?.cardTitle}
-        />
-        {canExpand && (
-          <ButtonWrapper>
-            <ShowOrHideTextButtonMemo
-              onToggle={toggleText}
-              show={showText}
-              textOverlay
-              theme={theme}
-            />
-            <ExpandButtonMemo
-              theme={theme}
-              expanded={expandDetails}
-              onExpand={toggleExpand}
-              textOverlay
-            />
-          </ButtonWrapper>
-        )}
-      </CardMediaHeader>
-      {showText && (
-        <SubTitleMemo
-          content={content}
-          fontSize={fontSizes?.cardSubtitle}
-          classString={classNames?.cardSubTitle}
-          padding
-          theme={theme}
-        />
-      )}
-      {canShowTextMemo && detailsText && (
-        <DetailsTextMemo
-          theme={theme}
-          show={showText}
-          expand={expandDetails}
-          text={detailsText}
-          onRender={onDetailsTextRef}
-          textOverlay={textOverlay}
-        />
-      )}
-    </MediaDetailsWrapper>
-  ) as React.ReactElement;
-};
- 
-// Export the memoized component
-export const ContentDisplay = ContentDisplayComponent;
- 
-// Add display name for DevTools
-ContentDisplay.displayName = 'ContentDisplay';
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html deleted file mode 100644 index b64268bc1..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components ErrorMessage.tsx

-
- -
- 80% - Statements - 4/5 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 80% - Lines - 4/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -141x -1x -  -  -  -  -  -  -  -  -1x -  -1x - 
import { memo } from 'react';
-import { ErrorMessage as StyledErrorMessage } from '../timeline-card-media.styles';
- 
-interface ErrorMessageProps {
-  message: string;
-}
- 
-/**
- * Displays an error message when media fails to load
- */
-export const LazyErrorMessage = memo(({ message }: ErrorMessageProps) => (
-  <StyledErrorMessage>{message}</StyledErrorMessage>
-));
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html deleted file mode 100644 index fc9a70e61..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components ImageDisplay.tsx

-
- -
- 100% - Statements - 31/31 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 31/31 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -501x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -  -1x - 
import React, { memo } from 'react';
-import { CardImage, ImageWrapper } from '../timeline-card-media.styles';
-import { TimelineMode } from '@models/TimelineModel';
- 
-interface ImageDisplayProps {
-  url: string;
-  name: string;
-  mode: TimelineMode;
-  mediaLoaded: boolean;
-  borderLessCards: boolean;
-  mediaHeight: number;
-  imageFit?: string;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-}
- 
-/**
- * Renders an image with appropriate loading and error handling
- */
-export const ImageDisplay = memo(
-  ({
-    url,
-    name,
-    mode,
-    mediaLoaded,
-    borderLessCards,
-    mediaHeight,
-    imageFit,
-    handleMediaLoaded,
-    handleError,
-  }: ImageDisplayProps) => (
-    <ImageWrapper height={mediaHeight}>
-      <CardImage
-        src={url}
-        mode={mode}
-        onLoad={handleMediaLoaded}
-        onError={handleError}
-        $visible={mediaLoaded}
-        alt={name}
-        loading="lazy"
-        $enableBorderRadius={borderLessCards}
-        fit={imageFit}
-        data-testid="timeline-card-content-image"
-        width="100%"
-        height="auto"
-      />
-    </ImageWrapper>
-  ),
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html deleted file mode 100644 index 00f39832b..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/MediaContent.tsx.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/MediaContent.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components MediaContent.tsx

-
- -
- 78.33% - Statements - 47/60 -
- - -
- 50% - Branches - 5/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 78.33% - Lines - 47/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97  -  -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -3x -3x -3x -3x -3x -3x -3x -  -3x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -3x -  -15x -15x -  -  -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -15x -  -15x -  -  -18x -1x - 
import { MediaState } from '@models/TimelineMediaModel';
-import { TimelineMode } from '@models/TimelineModel';
-import React, { memo } from 'react';
-import { LazyErrorMessage } from './ErrorMessage';
-import { VideoPlayer } from './VideoPlayer';
-import { YoutubePlayer } from './YoutubePlayer';
-import { ImageDisplay } from './ImageDisplay';
- 
-interface MediaContentProps {
-  media: {
-    type: string;
-    source: {
-      url: string;
-    };
-    name?: string;
-  };
-  isYouTube: boolean;
-  loadFailed: boolean;
-  mediaLoaded: boolean;
-  active: boolean;
-  id: string;
-  mediaHeight: number;
-  mode: TimelineMode;
-  borderLessCards: boolean;
-  mediaSettings: any;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-  onMediaStateChange: (state: MediaState) => void;
-}
- 
-/**
- * Renders the appropriate media content based on type (video, YouTube, image)
- */
-export const MediaContent = memo(
-  ({
-    media,
-    isYouTube,
-    loadFailed,
-    mediaLoaded,
-    active,
-    id,
-    mediaHeight,
-    mode,
-    borderLessCards,
-    mediaSettings,
-    handleMediaLoaded,
-    handleError,
-    onMediaStateChange,
-  }: MediaContentProps) => {
-    if (media.type === 'VIDEO') {
-      if (isYouTube) {
-        return (
-          <YoutubePlayer
-            url={media.source.url}
-            active={active}
-            name={media.name ?? ''}
-          />
-        );
-      }
- 
-      return loadFailed ? (
-        <LazyErrorMessage message="Failed to load the video" />
-      ) : (
-        <VideoPlayer
-          url={media.source.url}
-          active={active}
-          id={id}
-          name={media.name ?? ''}
-          onMediaStateChange={onMediaStateChange}
-          handleMediaLoaded={handleMediaLoaded}
-          handleError={handleError}
-        />
-      );
-    }
- 
-    if (media.type === 'IMAGE') {
-      return loadFailed ? (
-        <LazyErrorMessage message="Failed to load the image." />
-      ) : (
-        <ImageDisplay
-          url={media.source.url}
-          name={media.name ?? ''}
-          mode={mode}
-          mediaLoaded={mediaLoaded}
-          borderLessCards={borderLessCards}
-          mediaHeight={mediaHeight}
-          imageFit={mediaSettings?.fit}
-          handleMediaLoaded={handleMediaLoaded}
-          handleError={handleError}
-        />
-      );
-    }
- 
-    return null;
-  },
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html deleted file mode 100644 index 8f175afe6..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components VideoPlayer.tsx

-
- -
- 9.43% - Statements - 5/53 -
- - -
- 100% - Branches - 0/0 -
- - -
- 100% - Functions - 0/0 -
- - -
- 9.43% - Lines - 5/53 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
import { MediaState } from '@models/TimelineMediaModel';
-import React, { memo, useEffect, useRef } from 'react';
-import { CardVideo } from '../timeline-card-media.styles';
- 
-interface VideoPlayerProps {
-  url: string;
-  active: boolean;
-  id: string;
-  name: string;
-  onMediaStateChange: (state: MediaState) => void;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-}
- 
-/**
- * Renders a standard video player
- */
-export const VideoPlayer = memo(
-  ({
-    url,
-    active,
-    id,
-    name,
-    onMediaStateChange,
-    handleMediaLoaded,
-    handleError,
-  }: VideoPlayerProps) => {
-    const videoRef = useRef<HTMLVideoElement>(null);
- 
-    useEffect(() => {
-      if (!videoRef.current) return;
- 
-      if (active) {
-        videoRef.current.play().catch(() => {
-          // Handle autoplay failure silently
-        });
-      } else {
-        videoRef.current.pause();
-      }
-    }, [active]);
- 
-    return (
-      <CardVideo
-        controls
-        autoPlay={active}
-        ref={videoRef}
-        onLoadedData={handleMediaLoaded}
-        data-testid="rc-video"
-        onPlay={() =>
-          onMediaStateChange({
-            id,
-            paused: false,
-            playing: true,
-          })
-        }
-        onPause={() =>
-          onMediaStateChange({
-            id,
-            paused: true,
-            playing: false,
-          })
-        }
-        onEnded={() =>
-          onMediaStateChange({
-            id,
-            paused: false,
-            playing: false,
-          })
-        }
-        onError={handleError}
-        preload="metadata"
-      >
-        <source src={url}></source>
-      </CardVideo>
-    );
-  },
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html deleted file mode 100644 index 039e8f5f4..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/components YoutubePlayer.tsx

-
- -
- 100% - Statements - 14/14 -
- - -
- 50% - Branches - 1/2 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 14/14 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -261x -1x -  -  -  -  -  -  -  -  -  -  -1x -1x -3x -3x -3x -3x -3x -3x -3x -3x -3x -  -1x - 
import React, { memo } from 'react';
-import { IFrameVideo } from '../timeline-card-media.styles';
- 
-interface YoutubePlayerProps {
-  url: string;
-  active: boolean;
-  name: string;
-}
- 
-/**
- * Renders a YouTube player iframe
- */
-export const YoutubePlayer = memo(
-  ({ url, active, name }: YoutubePlayerProps) => (
-    <IFrameVideo
-      style={{ border: 'none' }}
-      allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
-      allowFullScreen
-      src={`${url}${active ? '?autoplay=1&enablejsapi=1' : '?enablejsapi=1'}`}
-      title={name}
-      data-testid="timeline-card-content-video"
-      loading="lazy"
-    />
-  ),
-);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/index.html deleted file mode 100644 index 6d3a87bb4..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/components/index.html +++ /dev/null @@ -1,191 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/components - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media/components

-
- -
- 75.49% - Statements - 191/253 -
- - -
- 68.42% - Branches - 13/19 -
- - -
- 100% - Functions - 1/1 -
- - -
- 75.49% - Lines - 191/253 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
ContentDisplay.tsx -
-
100%90/90100%6/6100%1/1100%90/90
ErrorMessage.tsx -
-
80%4/5100%0/0100%0/080%4/5
ImageDisplay.tsx -
-
100%31/31100%1/1100%0/0100%31/31
MediaContent.tsx -
-
78.33%47/6050%5/10100%0/078.33%47/60
VideoPlayer.tsx -
-
9.43%5/53100%0/0100%0/09.43%5/53
YoutubePlayer.tsx -
-
100%14/1450%1/2100%0/0100%14/14
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/index.html deleted file mode 100644 index 44068ab67..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media/hooks

-
- -
- 88.65% - Statements - 86/97 -
- - -
- 94.11% - Branches - 16/17 -
- - -
- 100% - Functions - 4/4 -
- - -
- 88.65% - Lines - 86/97 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useMediaLoad.ts -
-
72%18/25100%1/1100%1/172%18/25
useToggleControls.ts -
-
78.94%15/19100%1/1100%1/178.94%15/19
useViewOptions.ts -
-
100%46/4692.3%12/13100%1/1100%46/46
useYouTubeDetection.ts -
-
100%7/7100%2/2100%1/1100%7/7
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html deleted file mode 100644 index cd5dd61b7..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts.html +++ /dev/null @@ -1,223 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useMediaLoad.ts

-
- -
- 72% - Statements - 18/25 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 72% - Lines - 18/25 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -18x -18x -18x -18x -18x -  -  -18x -  -18x -  -  -18x -  -  -  -  -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x - 
import { MediaState } from '@models/TimelineMediaModel';
-import { useState, useCallback } from 'react';
- 
-interface UseMediaLoadResult {
-  loadFailed: boolean;
-  mediaLoaded: boolean;
-  handleMediaLoaded: () => void;
-  handleError: () => void;
-}
- 
-/**
- * Custom hook to handle media loading state and error handling
- *
- * @param id - The ID of the media element
- * @param onMediaStateChange - Callback to notify parent component of media state changes
- * @returns Object with loading state and handler functions
- */
-export const useMediaLoad = (
-  id: string,
-  onMediaStateChange: (state: MediaState) => void,
-): UseMediaLoadResult => {
-  const [loadFailed, setLoadFailed] = useState(false);
-  const [mediaLoaded, setMediaLoaded] = useState(false);
- 
-  // This function will be invoked when the user has finished loading media
-  const handleMediaLoaded = useCallback(() => {
-    setMediaLoaded(true);
-  }, []);
- 
-  // This function handles errors when loading media
-  const handleError = useCallback(() => {
-    setLoadFailed(true);
-    onMediaStateChange({
-      id,
-      paused: false,
-      playing: false,
-    });
-  }, [onMediaStateChange, id]);
- 
-  return {
-    loadFailed,
-    mediaLoaded,
-    handleMediaLoaded,
-    handleError,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html deleted file mode 100644 index d2e95ffdc..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useToggleControls.ts

-
- -
- 78.94% - Statements - 15/19 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 78.94% - Lines - 15/19 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -281x -  -  -  -  -  -1x -18x -18x -  -18x -  -  -18x -  -18x -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x - 
import { useCallback, useState } from 'react';
- 
-/**
- * Custom hook to handle text display toggle functionality
- * @returns Object with toggle states and functions
- */
-export const useToggleControls = () => {
-  const [expandDetails, setExpandDetails] = useState(false);
-  const [showText, setShowText] = useState(true);
- 
-  const toggleExpand = useCallback(() => {
-    setExpandDetails((prev) => !prev);
-    setShowText(true);
-  }, []);
- 
-  const toggleText = useCallback(() => {
-    setExpandDetails(false);
-    setShowText((prev) => !prev);
-  }, []);
- 
-  return {
-    expandDetails,
-    showText,
-    toggleExpand,
-    toggleText,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html deleted file mode 100644 index d2f09de78..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts.html +++ /dev/null @@ -1,319 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useViewOptions.ts

-
- -
- 100% - Statements - 46/46 -
- - -
- 92.3% - Branches - 12/13 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 46/46 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -791x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x - 
import { ReactNode, useMemo, ForwardRefExoticComponent } from 'react';
-import { hexToRGBA } from '@utils/index';
-import { TextOrContentModel } from '../../timeline-card-content/text-or-content';
- 
-interface UseViewOptionsParams {
-  showText: boolean;
-  expandDetails: boolean;
-  textOverlay: boolean;
-  detailsText?: ForwardRefExoticComponent<TextOrContentModel>;
-  title?: ReactNode;
-  content?: ReactNode;
-  theme: any;
-  cardHeight: number;
-  mediaHeight: number;
-}
- 
-interface UseViewOptionsResult {
-  canShowTextMemo: boolean;
-  canShowTextContent: boolean;
-  canExpand: boolean;
-  gradientColor: string;
-  canShowGradient: boolean;
-  getCardHeight: number;
-}
- 
-/**
- * Custom hook for handling view options and memoized calculated values
- */
-export const useViewOptions = ({
-  showText,
-  expandDetails,
-  textOverlay,
-  detailsText,
-  title,
-  content,
-  theme,
-  cardHeight,
-  mediaHeight,
-}: UseViewOptionsParams): UseViewOptionsResult => {
-  const canShowTextMemo = useMemo(
-    () => showText && !!detailsText,
-    [showText, detailsText],
-  );
- 
-  const canShowTextContent = useMemo(
-    () => !!(title ?? content ?? detailsText),
-    [title, content, detailsText],
-  );
- 
-  const canExpand = useMemo(
-    () => textOverlay && !!detailsText,
-    [textOverlay, detailsText],
-  );
- 
-  const gradientColor = useMemo(
-    () => hexToRGBA(theme?.cardDetailsBackGround ?? '', 0.8),
-    [theme?.cardDetailsBackGround],
-  );
- 
-  const canShowGradient = useMemo(
-    () => !expandDetails && showText && textOverlay,
-    [expandDetails, showText, textOverlay],
-  );
- 
-  const getCardHeight = useMemo(
-    () => (textOverlay ? cardHeight : mediaHeight),
-    [textOverlay, cardHeight, mediaHeight],
-  );
- 
-  return {
-    canShowTextMemo,
-    canShowTextContent,
-    canExpand,
-    gradientColor,
-    canShowGradient,
-    getCardHeight,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html deleted file mode 100644 index 83db6a549..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media/hooks useYouTubeDetection.ts

-
- -
- 100% - Statements - 7/7 -
- - -
- 100% - Branches - 2/2 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 7/7 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -141x -  -  -  -  -  -  -1x -18x -18x -18x -18x -18x - 
import { useMemo } from 'react';
- 
-/**
- * Custom hook to detect YouTube URLs
- * @param url - The URL to check
- * @returns boolean indicating if the URL is a YouTube URL
- */
-export const useYouTubeDetection = (url: string) => {
-  return useMemo(
-    () => /^(https?:\/\/)?(www\.youtube\.com|youtu\.?be)\/.+$/.test(url),
-    [url],
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/index.html deleted file mode 100644 index 0f418c20d..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/index.html +++ /dev/null @@ -1,161 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card-media

-
- -
- 79.91% - Statements - 199/249 -
- - -
- 78.33% - Branches - 47/60 -
- - -
- 90% - Functions - 9/10 -
- - -
- 79.91% - Lines - 199/249 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-media-buttons.tsx -
-
100%8/8100%1/1100%0/0100%8/8
timeline-card-media.styles.ts -
-
91.66%77/8480%44/55100%9/991.66%77/84
timeline-card-media.tsx -
-
91.93%114/12466.66%2/3100%0/091.93%114/124
video.tsx -
-
0%0/330%0/10%0/10%0/33
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html deleted file mode 100644 index 0b981961a..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx.html +++ /dev/null @@ -1,229 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media timeline-card-media-buttons.tsx

-
- -
- 100% - Statements - 8/8 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 8/8 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49  -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -1x -  -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
- 
-const Button = css<{ theme: Theme }>`
-  align-items: center;
-  background: none;
-  // background: rgba(0, 0, 0, 0.1);
-  border-radius: 50%;
-  border: none;
-  cursor: pointer;
-  display: flex;
-  height: 1.5rem;
-  justify-content: center;
-  padding: 0;
-  width: 1.5rem;
-  margin: 0 0.25rem;
-  background: ${(p) => p.theme?.primary};
-  color: #fff;
- 
-  svg {
-    width: 70%;
-    height: 70%;
-  }
-`;
- 
-export const ExpandButton = styled.button<{
-  // expandFull?: boolean;
-  theme: Theme;
-}>`
-  ${Button}
-`;
- 
-export const ShowHideTextButton = styled.button<{
-  showText?: boolean;
-  theme: Theme;
-}>`
-  ${Button}
-`;
- 
-export const ButtonWrapper = styled.ul`
-  display: flex;
-  flex-direction: row;
-  justify-content: flex-end;
-  list-style: none;
-  margin: 0;
-  padding: 0;
-  margin-left: auto;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html deleted file mode 100644 index 9eb652761..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts.html +++ /dev/null @@ -1,850 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media timeline-card-media.styles.ts

-
- -
- 91.66% - Statements - 77/84 -
- - -
- 80% - Branches - 44/55 -
- - -
- 100% - Functions - 9/9 -
- - -
- 91.66% - Lines - 77/84 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256  -  -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -1x -  -1x -  -1x -  -  -1x -  -1x -1x -18x -1x -  -  -18x -17x -  -  -  -17x -17x -  -  -17x -17x -18x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -14x -14x -14x -14x -14x -14x -14x -  -  -  -  -1x -14x -  -  -  -  -  -  -  -14x -  -  -  -  -  -  -  -14x -2x -  -  -  -  -2x -14x -1x -1x -14x -2x -  -2x -  -2x -  -2x -2x -  -  -2x -  -  -1x -  -1x -14x -  -1x -1x -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -1x -  -1x -3x -1x -  -  -3x -2x -  -  -2x -3x -  -1x -3x -3x -  -  -  -1x -  -1x -  -  -1x -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
-import { ScrollBar } from '../../common/styles';
- 
-export const linearGradient = css`
-  &::after {
-    content: '';
-    position: absolute;
-    bottom: 0;
-    left: 0;
-    width: 100%;
-    height: 2rem;
-    background: linear-gradient(
-      0deg,
-      var(--rc-gradient-color) 0%,
-      rgba(255, 255, 255, 0) 100%
-    );
-  }
-`;
- 
-export const MediaWrapper = styled.div<{
-  $active?: boolean;
-  $cardHeight?: number;
-  $slideShowActive?: boolean;
-  $textOverlay?: boolean;
-  align?: 'left' | 'right' | 'center';
-  dir?: string;
-  mode?: TimelineMode;
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  align-self: center;
-  background: ${(p) => (!p.$textOverlay ? p.theme?.cardMediaBgColor : 'none')};
-  border-radius: 4px;
-  flex-direction: row;
-  height: ${(p) => (p.$textOverlay ? 'calc(100% - 1em)' : '0')};
-  padding: 0.5em;
-  // pointer-events: ${(p) => (!p.$active && p.$slideShowActive ? 'none' : '')};
-  position: relative;
-  text-align: ${(p) => p.align};
-  width: calc(100% - 1em);
-  overflow: hidden; /* Ensure content doesn't overflow */
-  z-index: ${zIndex.timelineCard + 1}; /* Place media above card content */
- 
-  ${(p) => (p.$cardHeight ? `min-height: ${p.$cardHeight}px;` : '')};
-  ${(p) => {
-    if (p.mode === 'HORIZONTAL') {
-      return `
-        justify-content: flex-start;
-      `;
-    } else {
-      if (p.dir === 'left') {
-        return `
-        justify-content: flex-start;
-      `;
-      } else {
-        return `
-        justify-content: flex-end;
-      `;
-      }
-    }
-  }}
-`;
- 
-export const ImageWrapper = styled.div<{ height?: number }>`
-  width: 100%;
-  height: 100%;
-  overflow: hidden;
-  border-radius: 6px;
-  position: relative;
- 
-  /* Ensure the image is contained within the card boundaries */
-  img {
-    max-width: 100%;
-    max-height: 100%;
-    object-fit: contain;
-  }
-`;
- 
-export const CardImage = styled.img<{
-  $enableBorderRadius?: boolean;
-  $visible?: boolean;
-  dir?: string;
-  fit?: string;
-  mode?: TimelineMode;
-}>`
-  flex: 4;
-  justify-self: center;
-  margin-left: auto;
-  margin-right: auto;
-  height: 100%;
-  width: 100%;
-  object-fit: ${(p) => p.fit ?? 'cover'};
-  object-position: center;
-  visibility: ${(p) => (p.$visible ? 'visible' : 'hidden')};
-  border-radius: ${(p) => (p.$enableBorderRadius ? '6px' : '0')};
-  position: absolute;
-  top: 0;
-  left: 0;
-  bottom: 0;
-  right: 0;
-`;
- 
-export const CardVideo = styled.video<{ height?: number }>`
-  max-width: 100%;
-  max-height: 100%;
-  margin-left: auto;
-  margin-right: auto;
-`;
- 
-export const MediaDetailsWrapper = styled.div<{
-  $absolutePosition?: boolean;
-  $borderLessCard?: boolean;
-  $expandFull?: boolean;
-  $expandable?: boolean;
-  $gradientColor?: string | null;
-  $showText?: boolean;
-  $textInMedia?: boolean;
-  mode?: TimelineMode;
-  theme?: Theme;
-}>`
-  bottom: 0;
-  left: 0;
-  right: 0;
-  margin-right: auto;
-  width: ${(p) => {
-    switch (p.mode) {
-      case 'HORIZONTAL':
-      case 'VERTICAL':
-      case 'VERTICAL_ALTERNATING':
-        return `calc(90% - 0rem)`;
-    }
-  }};
-  display: flex;
-  flex-direction: column;
-  flex: 1;
-  overflow: hidden;
-  ${(p) => {
-    if (p.$textInMedia && p.$expandFull) {
-      return css`
-        height: 100%;
-        width: 100%;
-        border: 0;
-      `;
-    }
- 
-    if (!p.$showText) {
-      return css`
-        height: 15%;
-        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
-        border-radius: 10px;
-      `;
-    }
- 
-    if (p.$textInMedia && p.$expandable) {
-      return css`
-        box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.2);
-        border-radius: 10px;
-        height: 50%;
-      `;
-    }
-  }}
-  position: ${(p) => (p.$absolutePosition ? 'absolute' : 'relative')};
-  ${(p) =>
-    p.$absolutePosition
-      ? `
-    left: 50%;
-    bottom: ${p.$expandFull ? '0%' : ' 5%'};
-    transform: translateX(-50%);
-    z-index: ${zIndex.timelineCard + 2};
-    background: ${
-      p.$showText ? p.theme?.cardDetailsBackGround : p.theme?.cardBgColor
-    };
-    // backdrop-filter: blur(1px);
-    padding: 0.25rem;
-    ${p.$showText ? `overflow: auto;` : `overflow: hidden;`}
-    transition: height 0.25s ease-out, width 0.25s ease-out, bottom 0.25s ease-out, background 0.25s ease-out;
-  `
-      : ``}
- 
-  ${({ $borderLessCard }) =>
-    $borderLessCard
-      ? `border-radius: 6px; box-shadow: 0 0 10px 0 rgba(0,0,0,0.2);`
-      : ``}
-  --rc-gradient-color: ${(p) => p.$gradientColor};
-  ${(p) => (p.$gradientColor ? linearGradient : null)}
-`;
- 
-export const ErrorMessage = styled.span`
-  color: #a3a3a3;
-  left: 50%;
-  position: absolute;
-  text-align: center;
-  top: 50%;
-  transform: translateY(-50%) translateX(-50%);
-`;
- 
-export const IFrameVideo = styled.iframe`
-  position: relative;
-  height: 100%;
-  width: 100%;
-`;
- 
-export const DetailsTextWrapper = styled.div<{
-  $expandFull?: boolean;
-  $show?: boolean;
-  background?: string;
-  theme?: Theme;
-}>`
-  align-self: center;
-  display: flex;
-  transition: height 0.5s ease;
-  width: calc(100%);
-  background: ${(p) => p.background};
-  color: ${(p) => p.theme?.cardDetailsColor};
-  padding: 0.5rem;
-  border-bottom-left-radius: 8px;
-  border-bottom-right-radius: 8px;
-  position: relative;
-  align-items: flex-start;
-  justify-content: center;
- 
-  ${ScrollBar}
- 
-  ${(p) => {
-    if (p.$expandFull) {
-      return `
-        overflow: auto;
-      `;
-    } else {
-      return `
-        overflow: hidden;
-      `;
-    }
-  }}
- 
-  ${(p) =>
-    p.$show
-      ? `
-    height: 100%;`
-      : `
-    height: 0;
-  `}
- 
-  ${(p) => !p.$expandFull && linearGradient}
-`;
- 
-export const CardMediaHeader = styled.div`
-  padding: 0.5rem 0 0.5rem 0.5rem;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html deleted file mode 100644 index 618601b72..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/timeline-card-media.tsx.html +++ /dev/null @@ -1,529 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/timeline-card-media.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media timeline-card-media.tsx

-
- -
- 91.93% - Statements - 114/124 -
- - -
- 66.66% - Branches - 2/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 91.93% - Lines - 114/124 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -1x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -18x -18x -18x -18x -  -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -  -18x -  -  -18x -  -  -  -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -18x -  -18x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -14x -  -18x -  -18x -1x -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -1x - 
import { CardMediaModel } from '@models/TimelineMediaModel';
-import cls from 'classnames';
-import React, { memo, useCallback, useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { MediaWrapper } from './timeline-card-media.styles';
-import { useMediaLoad } from './hooks/useMediaLoad';
-import { useYouTubeDetection } from './hooks/useYouTubeDetection';
-import { useToggleControls } from './hooks/useToggleControls';
-import { useViewOptions } from './hooks/useViewOptions';
-import { MediaContent } from './components/MediaContent';
-import { ContentDisplay } from './components/ContentDisplay';
- 
-/**
- * CardMedia component - A highly optimized component for media rendering in timeline cards
- */
-const CardMedia: React.FunctionComponent<CardMediaModel> = memo(
-  ({
-    active,
-    id,
-    onMediaStateChange,
-    title,
-    content,
-    media,
-    slideshowActive,
-    url,
-    detailsText,
-  }: CardMediaModel) => {
-    // Custom hooks for state management
-    const { loadFailed, mediaLoaded, handleMediaLoaded, handleError } =
-      useMediaLoad(id, onMediaStateChange);
-    const isYouTube = useYouTubeDetection(media.source.url);
-    const { expandDetails, showText, toggleExpand, toggleText } =
-      useToggleControls();
- 
-    // Get context
-    const {
-      mode,
-      fontSizes,
-      classNames,
-      mediaHeight,
-      borderLessCards,
-      textOverlay,
-      theme,
-      cardHeight,
-      mediaSettings,
-    } = useContext(GlobalContext);
- 
-    // Use view options hook for calculated values
-    const {
-      canShowTextMemo,
-      canShowTextContent,
-      canExpand,
-      gradientColor,
-      canShowGradient,
-      getCardHeight,
-    } = useViewOptions({
-      showText,
-      expandDetails,
-      textOverlay,
-      detailsText,
-      title,
-      content,
-      theme,
-      cardHeight,
-      mediaHeight,
-    });
- 
-    // Cast mode to TimelineMode
-    const timelineMode = mode;
- 
-    // Details text callback
-    const onDetailsTextRef = useCallback((height?: number) => {
-      if (height) {
-        // Do something with height if needed
-      }
-    }, []);
- 
-    return (
-      <>
-        <MediaWrapper
-          theme={theme}
-          $active={active}
-          mode={timelineMode}
-          $slideShowActive={slideshowActive}
-          className={cls('card-media-wrapper', classNames?.cardMedia)}
-          $cardHeight={getCardHeight}
-          align={mediaSettings?.align}
-          $textOverlay={textOverlay}
-        >
-          <MediaContent
-            media={media}
-            isYouTube={isYouTube}
-            loadFailed={loadFailed}
-            mediaLoaded={mediaLoaded}
-            active={active}
-            id={id}
-            mediaHeight={mediaHeight}
-            mode={timelineMode}
-            borderLessCards={borderLessCards}
-            mediaSettings={mediaSettings}
-            handleMediaLoaded={handleMediaLoaded}
-            handleError={handleError}
-            onMediaStateChange={onMediaStateChange}
-          />
-        </MediaWrapper>
- 
-        {canShowTextContent && (
-          <ContentDisplay
-            mode={timelineMode}
-            textOverlay={textOverlay}
-            theme={theme}
-            expandDetails={expandDetails}
-            showText={showText}
-            canExpand={canExpand}
-            canShowGradient={canShowGradient}
-            gradientColor={gradientColor}
-            title={title}
-            active={active}
-            url={url}
-            fontSizes={fontSizes}
-            classNames={classNames}
-            toggleText={toggleText}
-            toggleExpand={toggleExpand}
-            content={content}
-            canShowTextMemo={canShowTextMemo}
-            detailsText={detailsText}
-            onDetailsTextRef={onDetailsTextRef}
-          />
-        )}
-      </>
-    ) as React.ReactElement;
-  },
-  (prevProps, nextProps) => {
-    // Custom comparison function to avoid unnecessary re-renders
-    return (
-      prevProps.active === nextProps.active &&
-      prevProps.slideshowActive === nextProps.slideshowActive &&
-      prevProps.paused === nextProps.paused &&
-      prevProps.startWidth === nextProps.startWidth &&
-      prevProps.remainInterval === nextProps.remainInterval &&
-      JSON.stringify(prevProps.theme) === JSON.stringify(nextProps.theme)
-    );
-  },
-);
- 
-CardMedia.displayName = 'Card Media';
- 
-export default CardMedia;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card-media/video.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card-media/video.tsx.html deleted file mode 100644 index 3692ae128..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card-media/video.tsx.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card-media/video.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card-media video.tsx

-
- -
- 0% - Statements - 0/33 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/33 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import React, { useRef, useEffect } from 'react';
-import styled from 'styled-components';
- 
-interface VideoProps extends React.VideoHTMLAttributes<HTMLVideoElement> {
-  children: React.ReactNode;
-}
- 
-const VideoElement = styled.video`
-  width: 100%;
-  height: auto;
-  display: block;
-`;
- 
-/**
- * Accessible Video component
- * Wraps the native video element with improved accessibility features
- */
-const Video: React.FC<VideoProps> = ({
-  children,
-  autoPlay,
-  muted,
-  controls = true,
-  onEnded,
-  playsInline = true,
-  ...rest
-}) => {
-  const videoRef = useRef<HTMLVideoElement>(null);
- 
-  // Ensure video is properly muted when needed
-  useEffect(() => {
-    if (videoRef.current && autoPlay) {
-      videoRef.current.muted = true;
-    }
-  }, [autoPlay]);
- 
-  return (
-    <VideoElement
-      ref={videoRef}
-      autoPlay={autoPlay}
-      muted={muted}
-      controls={controls}
-      onEnded={onEnded}
-      playsInline={playsInline}
-      preload="metadata"
-      aria-label="Timeline media"
-      {...rest}
-    >
-      {children}
-    </VideoElement>
-  );
-};
- 
-export default Video;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/index.html deleted file mode 100644 index c073dcb0c..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/__tests__

-
- -
- 93.93% - Statements - 93/99 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 93.93% - Lines - 93/99 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal-card.test.tsx -
-
93.93%93/99100%10/10100%0/093.93%93/99
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html deleted file mode 100644 index 529108ae3..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx.html +++ /dev/null @@ -1,487 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/__tests__ timeline-horizontal-card.test.tsx

-
- -
- 93.93% - Statements - 93/99 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 93.93% - Lines - 93/99 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -1351x -  -  -  -  -  -  -  -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -  -1x -1x -1x -  -  -1x -  -1x -  -6x -6x -6x -1x -  -1x -  -6x -6x -6x -6x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import {
-  afterEach,
-  beforeAll,
-  beforeEach,
-  describe,
-  expect,
-  it,
-  vi,
-} from 'vitest';
-import { TimelineCardModel } from '../../../../models/TimelineItemModel';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import TimelineCard from '../timeline-horizontal-card';
- 
-const defaultProps: TimelineCardModel = {
-  active: true,
-  cardDetailedText: 'card detailed text',
-  cardSubtitle: 'card subtitle',
-  cardTitle: 'card title',
-  iconChild: 'icon child',
-  id: 'id-12345',
-  media: {
-    name: 'image_new',
-    source: {
-      type: 'IMAGE',
-      url: 'https://picsum.photos/200/300',
-    },
-    type: 'IMAGE',
-  },
-  onClick: vi.fn(),
-  onElapsed: vi.fn(),
-  wrapperId: 'wrapper-id-12345',
-};
- 
-describe('TimelineHorizontalCard', () => {
-  beforeAll(() => {
-    Object.defineProperty(window, 'matchMedia', {
-      value: vi.fn().mockImplementation((query) => ({
-        addEventListener: vi.fn(),
-        dispatchEvent: vi.fn(),
-        matches: false,
-        media: query,
-        onchange: null,
-        removeEventListener: vi.fn(),
-      })),
-      writable: true,
-    });
- 
-    // ResizeObserver is already mocked globally in common/test/index.tsx
-  });
- 
-  beforeEach(() => {
-    // create a div with id 'wrapper-id-12345' to render the component
-    const root = document.createElement('div');
-    root.setAttribute('id', 'wrapper-id-12345');
-    document.body.appendChild(root);
-  });
- 
-  afterEach(() => {
-    // remove the div with id 'wrapper-id-12345' after the tests
-    const root = document.getElementById('wrapper-id-12345');
-    if (root) {
-      document.body.removeChild(root);
-    }
-  });
- 
-  // should render timeline card
-  it('should render timeline card', () => {
-    const { container } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps: { ...providerProps, cardLess: false },
-    });
- 
-    expect(container).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot', () => {
-    const { container } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps: { ...providerProps, cardLess: false },
-    });
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render cardDetailedText, cardSubtitle, cardTitle, iconChild
-  it('should render cardDetailedText, cardSubtitle, cardTitle', () => {
-    const { getByText } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps,
-    });
- 
-    expect(getByText('card detailed text')).toBeInTheDocument();
-    expect(getByText('card subtitle')).toBeInTheDocument();
-    expect(getByText('card title')).toBeInTheDocument();
-  });
- 
-  // should support rendering a custom icon
-  it('should render a custom icon', () => {
-    const { getByText } = customRender(
-      <TimelineCard
-        {...defaultProps}
-        iconChild={<span role="img">icon</span>}
-      ></TimelineCard>,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('icon')).toBeInTheDocument();
-  });
- 
-  // should render media (image) if provided
-  it('should render media (image) if provided', () => {
-    const { getByAltText } = customRender(<TimelineCard {...defaultProps} />, {
-      providerProps,
-    });
- 
-    expect(getByAltText('image_new')).toBeInTheDocument();
-  });
- 
-  // should render media (video) if provided
-  it('should render media (video) if provided', () => {
-    const { getByText, getByRole } = customRender(
-      <TimelineCard {...defaultProps} url="http://www.google.com" />,
-      {
-        providerProps,
-      },
-    );
- 
-    expect(getByText('card title')).toBeInTheDocument();
-    expect(getByText('card subtitle')).toBeInTheDocument();
-    expect(getByRole('link')).toBeInTheDocument();
-    expect(getByRole('link')).toHaveAttribute('href', 'http://www.google.com');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/hooks/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card/hooks/index.html deleted file mode 100644 index 7918c10bb..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/hooks/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/hooks - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/hooks

-
- -
- 96.2% - Statements - 76/79 -
- - -
- 93.75% - Branches - 15/16 -
- - -
- 100% - Functions - 1/1 -
- - -
- 96.2% - Lines - 76/79 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useTimelineCard.ts -
-
96.2%76/7993.75%15/16100%1/196.2%76/79
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html deleted file mode 100644 index d6ed92222..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts.html +++ /dev/null @@ -1,358 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/hooks/useTimelineCard.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/hooks useTimelineCard.ts

-
- -
- 96.2% - Statements - 76/79 -
- - -
- 93.75% - Branches - 15/16 -
- - -
- 100% - Functions - 1/1 -
- - -
- 96.2% - Lines - 76/79 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -921x -1x -1x -  -1x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -  -67x -  -  -  -67x -  -67x -67x -25x -25x -  -25x -25x -25x -  -25x -19x -19x -19x -25x -25x -67x -  -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x - 
import { useCallback, useContext, useEffect, useMemo, useRef } from 'react';
-import cls from 'classnames';
-import { GlobalContext } from '../../../GlobalContext';
- 
-export const useTimelineCard = ({
-  active,
-  autoScroll,
-  slideShowRunning,
-  cardLess,
-  showAllCardsHorizontal,
-  id,
-  onClick,
-  mode,
-  position,
-  iconChild,
-}) => {
-  const circleRef = useRef<HTMLButtonElement>(null);
-  const wrapperRef = useRef<HTMLDivElement>(null);
-  const contentRef = useRef<HTMLDivElement>(null);
- 
-  const { disableClickOnCircle } = useContext(GlobalContext);
- 
-  const handleClick = useCallback(() => {
-    if (!disableClickOnCircle && onClick && !slideShowRunning) {
-      onClick(id);
-    }
-  }, [disableClickOnCircle, onClick, slideShowRunning, id]);
- 
-  useEffect(() => {
-    if (active) {
-      const circle = circleRef.current;
-      const wrapper = wrapperRef.current;
- 
-      if (circle && wrapper) {
-        const circleOffsetLeft = circle.offsetLeft;
-        const wrapperOffsetLeft = wrapper.offsetLeft;
- 
-        autoScroll?.({
-          pointOffset: circleOffsetLeft + wrapperOffsetLeft,
-          pointWidth: circle.clientWidth,
-        });
-      }
-    }
-  }, [active, autoScroll, mode]);
- 
-  const modeLower = useMemo(() => mode?.toLowerCase(), [mode]);
- 
-  const containerClass = useMemo(
-    () =>
-      cls(
-        'timeline-horz-card-wrapper',
-        modeLower,
-        position === 'TOP' ? 'bottom' : 'top',
-        showAllCardsHorizontal ? 'show-all' : '',
-      ),
-    [modeLower, position, showAllCardsHorizontal],
-  );
- 
-  const titleClass = useMemo(
-    () => cls(modeLower, position),
-    [modeLower, position],
-  );
- 
-  const circleClass = useMemo(
-    () =>
-      cls(
-        'timeline-circle',
-        { 'using-icon': !!iconChild },
-        modeLower,
-        active ? 'active' : 'in-active',
-      ),
-    [active, iconChild, modeLower],
-  );
- 
-  const canShowTimelineContent = useMemo(
-    () => (active && !cardLess) || showAllCardsHorizontal,
-    [active, cardLess, showAllCardsHorizontal],
-  );
- 
-  return {
-    circleRef,
-    wrapperRef,
-    contentRef,
-    handleClick,
-    modeLower,
-    containerClass,
-    titleClass,
-    circleClass,
-    canShowTimelineContent,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card/index.html deleted file mode 100644 index e8c44901c..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card

-
- -
- 94.17% - Statements - 178/189 -
- - -
- 72.22% - Branches - 39/54 -
- - -
- 100% - Functions - 3/3 -
- - -
- 94.17% - Lines - 178/189 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal-card.styles.ts -
-
90%54/6076.19%32/42100%1/190%54/60
timeline-horizontal-card.tsx -
-
96.12%124/12958.33%7/12100%2/296.12%124/129
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/index.html deleted file mode 100644 index b4b59e186..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-card-portal - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/timeline-card-portal

-
- -
- 100% - Statements - 96/96 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 96/96 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-portal.tsx -
-
100%96/96100%6/6100%1/1100%96/96
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html deleted file mode 100644 index 954816957..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx.html +++ /dev/null @@ -1,472 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/timeline-card-portal timeline-card-portal.tsx

-
- -
- 100% - Statements - 96/96 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 96/96 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -1301x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -27x -27x -27x -6x -6x -21x -27x -  -27x -27x -  -1x - 
import React, { useCallback, useMemo } from 'react';
-import ReactDOM from 'react-dom';
-import { TimelineContentContainer } from '../timeline-horizontal-card.styles';
-import TimelineCardContent from '../../timeline-card-content/timeline-card-content';
- 
-interface TimelineCardPortalProps {
-  containerClass: string;
-  contentRef: React.RefObject<HTMLDivElement>;
-  id: string;
-  theme?: any;
-  active: boolean;
-  disableInteraction: boolean;
-  showAllCardsHorizontal: boolean;
-  cardWidth?: number;
-  cardSubtitle?: string;
-  cardTitle?: string;
-  url?: string;
-  cardDetailedText?: string | string[];
-  slideShowRunning?: boolean;
-  media?: any;
-  onElapsed?: (id: string) => void;
-  customContent?: React.ReactNode;
-  hasFocus?: boolean;
-  onClick?: (id: string) => void;
-  timelineContent?: any;
-  isNested?: boolean;
-  nestedCardHeight?: number;
-  items?: any[];
-  wrapperId: string;
-}
- 
-const TimelineCardPortal: React.FC<TimelineCardPortalProps> = ({
-  containerClass,
-  contentRef,
-  id,
-  theme,
-  active,
-  disableInteraction,
-  showAllCardsHorizontal,
-  cardWidth,
-  cardSubtitle,
-  cardTitle,
-  url,
-  cardDetailedText,
-  slideShowRunning,
-  media,
-  onElapsed,
-  customContent,
-  hasFocus,
-  onClick,
-  timelineContent,
-  isNested,
-  nestedCardHeight,
-  items,
-  wrapperId,
-}) => {
-  const handleOnShowMore = useCallback(() => {}, []);
- 
-  const Content = useMemo(() => {
-    return (
-      <TimelineContentContainer
-        className={containerClass}
-        ref={contentRef}
-        id={`timeline-card-${id}`}
-        theme={theme}
-        $active={active && !disableInteraction}
-        $highlight={showAllCardsHorizontal}
-        tabIndex={0}
-        $cardWidth={cardWidth}
-      >
-        <TimelineCardContent
-          content={cardSubtitle}
-          active={active}
-          title={cardTitle}
-          url={url}
-          detailedText={cardDetailedText}
-          onShowMore={handleOnShowMore}
-          theme={theme}
-          slideShowActive={slideShowRunning}
-          media={media}
-          onElapsed={onElapsed}
-          id={id}
-          customContent={customContent}
-          hasFocus={hasFocus}
-          onClick={onClick}
-          timelineContent={timelineContent}
-          isNested={isNested}
-          nestedCardHeight={nestedCardHeight}
-          items={items}
-        />
-      </TimelineContentContainer>
-    );
-  }, [
-    containerClass,
-    contentRef,
-    id,
-    active,
-    disableInteraction,
-    showAllCardsHorizontal,
-    cardWidth,
-    cardSubtitle,
-    cardTitle,
-    url,
-    cardDetailedText,
-    slideShowRunning,
-    theme,
-    media,
-    onElapsed,
-    customContent,
-    hasFocus,
-    onClick,
-    timelineContent,
-    isNested,
-    nestedCardHeight,
-    items,
-  ]);
- 
-  const renderedPortal = useMemo(() => {
-    const ele = document.getElementById(wrapperId);
-    if (ele) {
-      return ReactDOM.createPortal(Content, ele);
-    }
-    return null;
-  }, [Content, wrapperId]);
- 
-  return <>{renderedPortal}</>;
-};
- 
-export default TimelineCardPortal;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html deleted file mode 100644 index 309bf32a6..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts.html +++ /dev/null @@ -1,925 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card timeline-horizontal-card.styles.ts

-
- -
- 90% - Statements - 54/60 -
- - -
- 76.19% - Branches - 32/42 -
- - -
- 100% - Functions - 1/1 -
- - -
- 90% - Lines - 54/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -180x -66x -180x -  -114x -  -  -180x -  -1x -1x -  -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -1x -90x -  -1x -  -  -  -  -1x -90x -  -1x -  -  -  -  -1x -90x -  -1x -1x -  -  -1x -1x -  -  -  -1x -  -  -1x -1x -  -  -  -  -1x -  -  -  -  -  -1x -  -  -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled, { keyframes } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-export const Wrapper = styled.div`
-  align-items: center;
-  border: 1px solid transparent;
-  display: flex;
-  justify-content: center;
-  position: relative;
-  width: 100%;
-  height: 100%;
- 
-  &.vertical {
-    justify-content: flex-start;
-  }
-`;
- 
-export const Item = styled.div``;
- 
-const show = keyframes`
-  from {
-    opacity: 0;
-  }
-  to {
-    opacity: 1;
-  }
-`;
- 
-const ripple = keyframes`
-  0% {
-    transform: scale(0);
-    opacity: 0.8;
-  }
-  100% {
-    transform: scale(4);
-    opacity: 0;
-  }
-`;
- 
-const pulse = keyframes`
-  0% {
-    box-shadow: 0 0 0 0 rgba(0, 123, 255, 0.4);
-  }
-  70% {
-    box-shadow: 0 0 0 10px rgba(0, 123, 255, 0);
-  }
-  100% {
-    box-shadow: 0 0 0 0 rgba(0, 123, 255, 0);
-  }
-`;
- 
-export const ShapeWrapper = styled.div`
-  /* height: 100%; */
-  align-items: center;
-  display: flex;
-  flex-direction: column;
-  justify-content: center;
-  width: 5em;
-`;
- 
-type ShapeModel = {
-  $timelinePointShape?: 'circle' | 'square' | 'diamond';
-  dimension?: number;
-  theme?: Theme;
-};
- 
-const ShapeBorderStyle = (p: Pick<ShapeModel, '$timelinePointShape'>) => {
-  if (p.$timelinePointShape === 'circle') {
-    return 'border-radius: 50%;';
-  } else if (p.$timelinePointShape === 'square') {
-    return 'border-radius: 2px;';
-  } else if (p.$timelinePointShape === 'diamond') {
-    return `border-radius: 0;`;
-  }
-};
- 
-export const Shape = styled.div<ShapeModel>`
-  ${ShapeBorderStyle}
-  cursor: pointer;
-  height: ${(p) => p.dimension}px;
-  width: ${(p) => p.dimension}px;
-  transform: ${(p) =>
-    p.$timelinePointShape === 'diamond' ? 'rotate(45deg)' : ''};
-  transition: all 0.2s ease-in-out;
-  position: relative;
-  overflow: hidden;
- 
-  /* Reset button styles when used as a button */
-  background: none;
-  border: none;
-  padding: 0;
- 
-  /* Ripple effect */
-  &::before {
-    content: '';
-    position: absolute;
-    top: 50%;
-    left: 50%;
-    width: ${(p) => (p.dimension ? Math.round(p.dimension * 0.5) : 10)}px;
-    height: ${(p) => (p.dimension ? Math.round(p.dimension * 0.5) : 10)}px;
-    background-color: rgba(255, 255, 255, 0.5);
-    border-radius: 50%;
-    transform: scale(0) translate(-50%, -50%);
-    transform-origin: top left;
-    pointer-events: none;
-    z-index: ${zIndex.timelinePoint + 1}; /* Above the timeline point */
-    opacity: 0;
-  }
- 
-  &:active::before {
-    animation: ${ripple} 0.6s ease-out;
-  }
- 
-  /* Improve focus styles for accessibility */
-  &:focus-visible {
-    outline: 3px solid ${(p) => p.theme?.primary ?? '#007bff'};
-    outline-offset: 2px;
-  }
- 
-  /* Add subtle hover effect */
-  &:hover:not(:disabled) {
-    transform: ${(p) =>
-      p.$timelinePointShape === 'diamond'
-        ? 'rotate(45deg) scale(1.08)'
-        : 'scale(1.08)'};
-    box-shadow: 0 0 0 3px rgba(0, 0, 0, 0.1);
-  }
- 
-  &:active:not(:disabled) {
-    transform: ${(p) =>
-      p.$timelinePointShape === 'diamond'
-        ? 'rotate(45deg) scale(0.95)'
-        : 'scale(0.95)'};
-  }
- 
-  &.active {
-    &.using-icon {
-      transform: ${(p) =>
-        p.$timelinePointShape === 'diamond'
-          ? 'rotate(45deg) scale(1.1)'
-          : 'scale(1.1)'};
-      animation: ${pulse} 1.5s infinite;
-    }
-    &:not(.using-icon) {
-      transform: ${(p) =>
-        p.$timelinePointShape === 'diamond' ? 'rotate(45deg)' : ''};
-    }
- 
-    &::after {
-      ${ShapeBorderStyle}
-      content: '';
-      display: block;
-      height: ${(p) => (p.dimension ? Math.round(p.dimension * 0.75) : 20)}px;
-      width: ${(p) => (p.dimension ? Math.round(p.dimension * 0.75) : 20)}px;
-      left: 50%;
-      position: absolute;
-      top: 50%;
-      transform: translateY(-50%) translateX(-50%);
-      z-index: ${zIndex.timelinePoint - 1}; /* Behind the timeline point */
-      transition: all 0.3s ease-in-out;
-    }
-  }
- 
-  &:not(.using-icon) {
-    background: ${(p: ShapeModel) => p.theme?.primary};
- 
-    &.active {
-      background: ${(p: ShapeModel) => p.theme?.secondary};
-      border: ${(p) => (p.dimension ? Math.round(p.dimension * 0.2) : '3')}px
-        solid ${(p: ShapeModel) => p.theme?.primary};
-      box-shadow: 0 0 8px rgba(0, 0, 0, 0.2);
-      animation: ${pulse} 1.5s infinite;
-    }
- 
-    &:disabled {
-      opacity: 0.6;
-      cursor: default;
-    }
-  }
- 
-  &.using-icon {
-    background: ${(p) => p.theme?.iconBackgroundColor};
-    display: flex;
-    align-items: center;
-    justify-content: center;
- 
-    img {
-      max-width: 90%;
-      max-height: 90%;
-    }
- 
-    &:disabled {
-      opacity: 0.6;
-      cursor: default;
-    }
-  }
-`;
- 
-export const TimelineTitleContainer = styled.div`
-  display: flex;
-  align-items: center;
-  justify-content: flex-start;
- 
-  &.vertical {
-    margin-bottom: 1em;
-  }
- 
-  &.horizontal {
-    position: absolute;
-    top: 0;
-  }
-`;
- 
-export const TimelineContentContainer = styled.div<{
-  $active?: boolean;
-  $cardWidth?: number;
-  $highlight?: boolean;
-  position?: string;
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  animation: ${show} 0.25s ease-in;
- 
-  outline: 2px solid
-    ${(p) => (p.$highlight && p.$active ? p.theme?.primary : 'transparent')};
- 
-  margin: 1rem;
- 
-  &.horizontal {
-    min-width: ${(p) => p.$cardWidth}px;
-  }
- 
-  &.vertical {
-    width: calc(100% - 5em);
-    margin-left: auto;
-    flex-direction: column;
-  }
-`;
- 
-// Card container with improved cross-browser support
-export const CardContainer = styled.div<{ theme: Theme }>`
-  position: relative;
-  display: -webkit-box;
-  display: -ms-flexbox;
-  display: flex;
-  -webkit-box-orient: vertical;
-  -webkit-box-direction: normal;
-  -ms-flex-direction: column;
-  flex-direction: column;
-  min-width: 250px;
-  max-width: 350px;
-  margin: 0.5rem;
-  padding: 1rem;
-  background: ${(p) => p.theme.cardBgColor};
-  border-radius: 8px;
-  -webkit-box-shadow: 
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  box-shadow:
-    0 1px 3px rgba(0, 0, 0, 0.06),
-    0 4px 10px rgba(0, 0, 0, 0.08);
-  -webkit-transition: 
-    -webkit-transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
-  transition:
-    transform 0.2s ease-out,
-    box-shadow 0.2s ease-out;
- 
-  &:hover {
-    -webkit-transform: translateY(-2px);
-    transform: translateY(-2px);
-    -webkit-box-shadow: 
-      0 2px 4px rgba(0, 0, 0, 0.08),
-      0 6px 12px rgba(0, 0, 0, 0.12);
-    box-shadow:
-      0 2px 4px rgba(0, 0, 0, 0.08),
-      0 6px 12px rgba(0, 0, 0, 0.12);
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html deleted file mode 100644 index 485c35c91..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx.html +++ /dev/null @@ -1,529 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-horizontal-card.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card timeline-horizontal-card.tsx

-
- -
- 96.12% - Statements - 124/129 -
- - -
- 58.33% - Branches - 7/12 -
- - -
- 100% - Functions - 2/2 -
- - -
- 96.12% - Lines - 124/129 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149  -1x -1x -1x -1x -  -  -  -1x -1x -1x -  -1x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -  -67x -27x -  -  -  -  -  -27x -27x -27x -  -27x -27x -  -67x -67x -67x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -  -27x -27x -  -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -27x -  -  -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -  -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -  -1x - 
import { TimelineCardModel } from '@models/TimelineItemModel';
-import React, { useContext } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import TimelineItemTitle from '../timeline-item-title/timeline-card-title';
-import {
-  TimelineTitleContainer,
-  Wrapper,
-} from './timeline-horizontal-card.styles';
-import { useTimelineCard } from './hooks/useTimelineCard';
-import TimelinePoint from './timeline-point/timeline-point';
-import TimelineCardPortal from './timeline-card-portal/timeline-card-portal';
- 
-const TimelineCard: React.FunctionComponent<TimelineCardModel> = ({
-  active,
-  autoScroll,
-  cardDetailedText,
-  cardSubtitle,
-  cardTitle,
-  url,
-  id,
-  media,
-  onClick,
-  onElapsed,
-  slideShowRunning,
-  title,
-  wrapperId,
-  customContent,
-  hasFocus,
-  iconChild,
-  timelineContent,
-  cardWidth,
-  isNested,
-  nestedCardHeight,
-  items,
-}: TimelineCardModel) => {
-  const {
-    mode,
-    cardPositionHorizontal: position,
-    timelinePointDimension,
-    cardLess,
-    showAllCardsHorizontal,
-    classNames,
-    theme,
-    timelinePointShape,
-    disableInteraction,
-  } = useContext(GlobalContext);
- 
-  const {
-    circleRef,
-    wrapperRef,
-    contentRef,
-    handleClick,
-    modeLower,
-    containerClass,
-    titleClass,
-    circleClass,
-    canShowTimelineContent,
-  } = useTimelineCard({
-    active,
-    autoScroll,
-    slideShowRunning,
-    cardLess,
-    showAllCardsHorizontal,
-    id,
-    onClick,
-    mode,
-    position,
-    iconChild,
-  });
- 
-  // Convert cardDetailedText to the expected string or string[] format
-  const formatDetailedText = () => {
-    if (Array.isArray(cardDetailedText)) {
-      return cardDetailedText.map((text) =>
-        typeof text === 'string' ? text : String(text ?? ''),
-      );
-    }
- 
-    if (typeof cardDetailedText === 'string') {
-      return cardDetailedText;
-    }
- 
-    return cardDetailedText ? String(cardDetailedText) : undefined;
-  };
- 
-  return (
-    <Wrapper ref={wrapperRef} className={modeLower} data-testid="timeline-item">
-      {canShowTimelineContent && (
-        <TimelineCardPortal
-          containerClass={containerClass}
-          contentRef={contentRef}
-          id={id}
-          theme={theme}
-          active={active}
-          disableInteraction={disableInteraction}
-          showAllCardsHorizontal={showAllCardsHorizontal}
-          cardWidth={cardWidth}
-          cardSubtitle={
-            typeof cardSubtitle === 'string'
-              ? cardSubtitle
-              : String(cardSubtitle ?? '')
-          }
-          cardTitle={
-            typeof cardTitle === 'string' ? cardTitle : String(cardTitle ?? '')
-          }
-          url={url}
-          cardDetailedText={formatDetailedText()}
-          slideShowRunning={slideShowRunning}
-          media={media}
-          onElapsed={onElapsed}
-          customContent={customContent}
-          hasFocus={hasFocus}
-          onClick={onClick}
-          timelineContent={timelineContent}
-          isNested={isNested}
-          nestedCardHeight={nestedCardHeight}
-          items={items}
-          wrapperId={wrapperId}
-        />
-      )}
- 
-      <TimelinePoint
-        circleClass={circleClass}
-        handleClick={handleClick}
-        circleRef={circleRef}
-        title={typeof title === 'string' ? title : String(title ?? '')}
-        theme={theme}
-        timelinePointDimension={timelinePointDimension}
-        timelinePointShape={timelinePointShape}
-        iconChild={iconChild}
-      />
- 
-      <TimelineTitleContainer
-        className={titleClass}
-        data-testid="timeline-title"
-      >
-        <TimelineItemTitle
-          title={title}
-          active={active && !disableInteraction}
-          theme={theme}
-          classString={classNames?.title}
-        />
-      </TimelineTitleContainer>
-    </Wrapper>
-  );
-};
- 
-export default TimelineCard;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/index.html b/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/index.html deleted file mode 100644 index 90f18f946..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-point - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-card/timeline-point

-
- -
- 100% - Statements - 35/35 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 35/35 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-point.tsx -
-
100%35/3550%2/4100%1/1100%35/35
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html deleted file mode 100644 index 35249c739..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-card/timeline-point timeline-point.tsx

-
- -
- 100% - Statements - 35/35 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 35/35 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -67x -  -67x -67x -67x -  -67x -  -1x - 
import React from 'react';
-import { Shape, ShapeWrapper } from '../timeline-horizontal-card.styles';
- 
-interface TimelinePointProps {
-  circleClass: string;
-  handleClick: () => void;
-  circleRef: React.RefObject<HTMLButtonElement>;
-  title?: string;
-  theme?: any;
-  timelinePointDimension?: number;
-  timelinePointShape?: 'circle' | 'square' | 'diamond';
-  iconChild?: React.ReactNode;
-  active?: boolean;
-  disabled?: boolean;
-}
- 
-const TimelinePoint: React.FC<TimelinePointProps> = ({
-  circleClass,
-  handleClick,
-  circleRef,
-  title,
-  theme,
-  timelinePointDimension,
-  timelinePointShape,
-  iconChild,
-  active = false,
-  disabled = false,
-}) => {
-  return (
-    <ShapeWrapper>
-      <Shape
-        as="button"
-        className={circleClass}
-        onClick={handleClick}
-        ref={circleRef}
-        data-testid="timeline-circle"
-        theme={theme}
-        aria-label={title ?? 'Timeline point'}
-        aria-selected={active}
-        aria-disabled={disabled}
-        disabled={disabled}
-        dimension={timelinePointDimension}
-        $timelinePointShape={timelinePointShape}
-        tabIndex={disabled ? -1 : 0}
-        type="button"
-      >
-        {iconChild ?? null}
-      </Shape>
-    </ShapeWrapper>
-  ) as React.ReactElement;
-};
- 
-export default TimelinePoint;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/index.html b/coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/index.html deleted file mode 100644 index 9ad94d616..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-control/__tests__

-
- -
- 100% - Statements - 67/67 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 67/67 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-control.test.tsx -
-
100%67/67100%6/6100%0/0100%67/67
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html deleted file mode 100644 index fa27a7ab1..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx.html +++ /dev/null @@ -1,316 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control/__tests__ timeline-control.test.tsx

-
- -
- 100% - Statements - 67/67 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 67/67 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -781x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import userEvent from '@testing-library/user-event';
-import { vi } from 'vitest';
-import { commonProps, customRender, providerProps } from '../../../common/test';
-import Controls from '../timeline-control';
- 
-describe('TimelineControl', () => {
-  it('should render', () => {
-    const { container } = customRender(<Controls {...commonProps} />, {
-      providerProps,
-    });
-    expect(container).toMatchSnapshot();
-  });
- 
-  // check if all the buttons are rendered
-  it('should render all the buttons', () => {
-    const { getByLabelText } = customRender(<Controls {...commonProps} />, {
-      providerProps: { ...providerProps, enableDarkToggle: true },
-    });
-    expect(getByLabelText('first')).toBeInTheDocument();
-    expect(getByLabelText('previous')).toBeInTheDocument();
-    expect(getByLabelText('next')).toBeInTheDocument();
-    expect(getByLabelText('last')).toBeInTheDocument();
-    expect(getByLabelText('dark')).toBeInTheDocument();
-  });
- 
-  // should render the play button when slideShowEnabled is true
-  it('should render the play button when slideShowEnabled is true', () => {
-    const { getByLabelText } = customRender(
-      <Controls {...commonProps} slideShowEnabled slideShowRunning={false} />,
-      { providerProps },
-    );
-    expect(getByLabelText('start slideshow')).toBeInTheDocument();
-  });
- 
-  // check if all the callbacks are executed as expected
-  it('should execute the callbacks as expected', async () => {
-    const onFirst = vi.fn();
-    const onPrevious = vi.fn();
-    const onNext = vi.fn();
-    const onLast = vi.fn();
-    const onToggleDarkMode = vi.fn();
-    const user = userEvent.setup();
- 
-    const { getByLabelText } = customRender(
-      <Controls
-        {...commonProps}
-        onFirst={onFirst}
-        onPrevious={onPrevious}
-        onNext={onNext}
-        onLast={onLast}
-        onToggleDarkMode={onToggleDarkMode}
-      />,
-      { providerProps: { ...providerProps, enableDarkToggle: true } },
-    );
-    await user.click(getByLabelText('first'));
-    expect(onFirst).toHaveBeenCalled();
-    await user.click(getByLabelText('previous'));
-    expect(onPrevious).toHaveBeenCalled();
-    await user.click(getByLabelText('next'));
-    expect(onNext).toHaveBeenCalled();
-    await user.click(getByLabelText('last'));
-    expect(onLast).toHaveBeenCalled();
-    await user.click(getByLabelText('dark'));
-    expect(onToggleDarkMode).toHaveBeenCalled();
-  });
- 
-  // check if the navigation controls to be hidden / not shown when disableInteraction is set to true
-  it('should hide the navigation controls when disableInteraction is set to true', () => {
-    const { queryByLabelText } = customRender(<Controls {...commonProps} />, {
-      providerProps: { ...providerProps, disableInteraction: true },
-    });
-    expect(queryByLabelText('first')).not.toBeInTheDocument();
-    expect(queryByLabelText('previous')).not.toBeInTheDocument();
-    expect(queryByLabelText('next')).not.toBeInTheDocument();
-    expect(queryByLabelText('last')).not.toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-control/index.html b/coverage/lcov-report/components/timeline-elements/timeline-control/index.html deleted file mode 100644 index 340f17f1f..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-control/index.html +++ /dev/null @@ -1,146 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-control

-
- -
- 91.46% - Statements - 225/246 -
- - -
- 62.65% - Branches - 52/83 -
- - -
- 50% - Functions - 1/2 -
- - -
- 91.46% - Lines - 225/246 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-control.styles.ts -
-
69.23%36/5291.66%22/24100%0/069.23%36/52
timeline-control.styles.tsx -
-
0%0/20%0/10%0/10%0/2
timeline-control.tsx -
-
98.43%189/19251.72%30/58100%1/198.43%189/192
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.ts.html deleted file mode 100644 index 7c312889a..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.ts.html +++ /dev/null @@ -1,625 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/timeline-control.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control timeline-control.styles.ts

-
- -
- 69.23% - Statements - 36/52 -
- - -
- 91.66% - Branches - 22/24 -
- - -
- 100% - Functions - 0/0 -
- - -
- 69.23% - Lines - 36/52 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -  -1x -1x -1x -1x -1x -  -  -  -  -1x -  -1x -  -1x -  -  -1x -64x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-export const ScreenReaderOnly = styled.div`
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  margin: -1px;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  white-space: nowrap;
-  border-width: 0;
-`;
- 
-export const TimelineNavWrapper = styled.div<{ theme?: Theme }>`
-  border-radius: 8px;
-  display: flex;
-  list-style: none;
-  padding: 0.25rem;
-  // box-shadow: 0 1px 2px rgba(0, 0, 0, 0.1);
-  background: ${(p) => p.theme.toolbarBgColor};
-  // border: 1px solid ${(p) => p.theme.toolbarBtnBgColor};
-  position: relative;
-  z-index: ${zIndex.controls};
- 
-  .nav-item {
-    padding: 0;
-    display: flex;
-    align-items: center;
-    justify-content: center;
-    cursor: pointer;
- 
-    &.disabled {
-      pointer-events: none;
-      filter: opacity(0.4);
-    }
-  }
-`;
- 
-export const TimelineNavItem = styled.li<{ $disable?: boolean }>`
-  padding: 0;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  ${(p) =>
-    p.$disable
-      ? 'pointer-events: none; filter: opacity(0.4);'
-      : 'cursor: pointer;'};
-`;
- 
-export const TimelineNavButton = styled.button<{
-  mode?: TimelineMode;
-  rotate?: 'TRUE' | 'FALSE';
-  theme?: Theme;
-  $active?: boolean;
-}>`
-  align-items: center;
-  background: ${(p) => p.theme.toolbarBtnBgColor};
-  border-radius: 6px;
-  border: 1px solid ${(p) => p.theme.buttonBorderColor ?? 'transparent'};
-  color: ${(p) => p.theme.toolbarTextColor ?? p.theme.secondary};
-  cursor: pointer;
-  display: flex;
-  height: 28px;
-  justify-content: center;
-  margin: 0 0.2rem;
-  padding: 0;
-  transition:
-    background-color 0.2s ease-out,
-    transform 0.15s ease-out,
-    box-shadow 0.2s ease-out,
-    border-color 0.2s ease-out;
-  width: 28px;
-  box-shadow: 0 1px 1px ${(p) => p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.08)'};
- 
-  transform: ${(p) => (p.rotate === 'TRUE' ? 'rotate(90deg)' : 'none')};
- 
-  &:hover {
-    background: ${(p) =>
-      p.theme.buttonHoverBgColor ?? p.theme.toolbarBtnBgColor};
-    border-color: ${(p) => p.theme.buttonHoverBorderColor ?? p.theme.primary};
-    box-shadow: 0 2px 4px ${(p) => p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.12)'};
-    transform: ${(p) => (p.rotate === 'TRUE' ? 'rotate(90deg)' : 'none')}
-      translateY(-1px);
-  }
- 
-  &:active {
-    transform: ${(p) => (p.rotate === 'TRUE' ? 'rotate(90deg)' : 'none')}
-      scale(0.95);
-    background: ${(p) => p.theme.toolbarBtnBgColor};
-    box-shadow: inset 0 1px 1px
-      ${(p) => p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.1)'};
-  }
- 
-  ${(p) =>
-    p.$active &&
-    css`
-      background: ${p.theme.darkToggleActiveBgColor ?? p.theme.secondary};
-      border-color: ${p.theme.darkToggleActiveBorderColor ?? p.theme.primary};
-      box-shadow: 0 0 0 2px
-        ${p.theme.darkToggleGlowColor ??
-        p.theme.glowColor ??
-        'rgba(59, 130, 246, 0.3)'};
- 
-      &:hover {
-        background: ${p.theme.buttonHoverBgColor ?? p.theme.secondary};
-        opacity: 0.9;
-        box-shadow:
-          0 2px 4px ${p.theme.shadowColor ?? 'rgba(0, 0, 0, 0.12)'},
-          0 0 0 2px
-            ${p.theme.darkToggleGlowColor ??
-            p.theme.glowColor ??
-            'rgba(59, 130, 246, 0.4)'};
-      }
- 
-      svg {
-        color: ${p.theme.darkToggleActiveIconColor ??
-        p.theme.buttonActiveIconColor ??
-        '#fff'};
-      }
-    `}
- 
-  svg {
-    width: 75%;
-    height: 75%;
-    color: ${(p) => p.theme.iconColor ?? p.theme.primary};
-    transition: color 0.2s ease-out;
-  }
-`;
- 
-// Control container with improved layout
-export const ControlContainer = styled.div<{ theme: Theme }>`
-  display: -webkit-box;
-  display: -ms-flexbox;
-  display: flex;
-  -webkit-box-align: center;
-  -ms-flex-align: center;
-  align-items: center;
-  gap: 0.5rem;
-  padding: 0.5rem;
-  background: ${(p) => p.theme.cardBgColor};
-  border-radius: 4px;
-  -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-  box-shadow: 0 1px 3px rgba(0, 0, 0, 0.1);
-`;
- 
-export const TimelineControlContainer = styled.div`
-  align-items: center;
-  display: flex;
-  justify-content: center;
-  margin: 0.5rem 0;
-  position: relative;
-  z-index: ${zIndex.controls};
-`;
- 
-export const ControlButton = styled.button<{ theme?: Theme }>`
-  align-items: center;
-  background: ${(p) => p.theme.primary};
-  border-radius: 50%;
-  cursor: pointer;
-  display: flex;
-  height: 3em;
-  justify-content: center;
-  margin-left: 0.5em;
-  width: 3em;
-  outline: 0;
-  color: #fff;
- 
-  svg {
-    width: 80%;
-    height: 80%;
-  }
-`;
- 
-export const MediaToggle = styled(ControlButton)``;
- 
-export const ReplayWrapper = styled(ControlButton)``;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html deleted file mode 100644 index 865dffd9e..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.styles.tsx.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/timeline-control.styles.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control timeline-control.styles.tsx

-
- -
- 0% - Statements - 0/2 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/2 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
import styled from 'styled-components';
- 
-export const ScreenReaderOnly = styled.div`
-  position: absolute;
-  width: 1px;
-  height: 1px;
-  padding: 0;
-  margin: -1px;
-  overflow: hidden;
-  clip: rect(0, 0, 0, 0);
-  white-space: nowrap;
-  border-width: 0;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.tsx.html deleted file mode 100644 index d1ba74425..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-control/timeline-control.tsx.html +++ /dev/null @@ -1,871 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-control/timeline-control.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-control timeline-control.tsx

-
- -
- 98.43% - Statements - 189/192 -
- - -
- 51.72% - Branches - 30/58 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.43% - Lines - 189/192 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -  -12x -  -  -12x -  -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -  -12x -  -12x -  -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -  -  -12x -11x -6x -12x -  -  -12x -11x -11x -12x -  -12x -12x -  -12x -12x -12x -12x -  -12x -12x -12x -12x -12x -  -  -12x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -  -  -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -  -  -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -  -  -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -11x -  -11x -11x -11x -11x -  -  -  -12x -12x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -  -12x -  -  -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -  -12x -12x -12x -  -12x -12x -  -12x -  -1x -  -1x - 
import { TimelineControlModel } from '@models/TimelineControlModel';
-import cls from 'classnames';
-import React, { useCallback, useMemo } from 'react';
-import { useStableContext, useDynamicContext } from '../../contexts';
-import { MoonIcon, StopIcon, SunIcon } from '../../icons';
-import ChevronLeft from '../../icons/chev-left';
-import ChevronRightIcon from '../../icons/chev-right';
-import ChevronsLeftIcon from '../../icons/chevs-left';
-import ChevronsRightIcon from '../../icons/chevs-right';
-import ReplayIcon from '../../icons/replay-icon';
-import {
-  TimelineControlContainer,
-  TimelineNavButton,
-  TimelineNavWrapper,
-  ScreenReaderOnly,
-} from './timeline-control.styles';
- 
-/**
- * TimelineControl component
- * Provides navigation controls for a timeline, including next, previous, first, last, and slideshow buttons.
- * Optionally supports flipping the layout and dark mode toggle.
- *
- * @property {function} onNext - Function to go to the next item.
- * @property {function} onPrevious - Function to go to the previous item.
- * @property {function} onFirst - Function to jump to the first item.
- * @property {function} onLast - Function to jump to the last item.
- * @property {boolean} disableLeft - Whether to disable the left navigation buttons.
- * @property {boolean} disableRight - Whether to disable the right navigation buttons.
- * @property {boolean} slideShowRunning - Whether the slideshow is currently running.
- * @property {function} onReplay - Function to restart the slideshow.
- * @property {boolean} slideShowEnabled - Whether the slideshow feature is enabled.
- * @property {function} onToggleDarkMode - Function to toggle dark mode (if enabled).
- * @property {boolean} isDark - Whether dark mode is currently active.
- * @property {function} onPaused - Function to pause the slideshow (if running).
- * @returns {JSX.Element} The TimelineControl component.
- */
-const Controls: React.FunctionComponent<TimelineControlModel> = ({
-  onNext,
-  onPrevious,
-  onFirst,
-  onLast,
-  disableLeft,
-  disableRight,
-  slideShowRunning,
-  onReplay,
-  slideShowEnabled,
-  onToggleDarkMode,
-  isDark,
-  onPaused,
-  activeTimelineItem = 0,
-  totalItems = 0,
-}: TimelineControlModel) => {
-  const {
-    mode,
-    flipLayout,
-    memoizedButtonTexts: buttonTexts,
-    memoizedClassNames: classNames,
-    disableInteraction,
-    staticDefaults,
-  } = useStableContext();
- 
-  const { memoizedTheme: theme } = useDynamicContext();
- 
-  // Get enableDarkToggle from the stable context
-  const enableDarkToggle = staticDefaults.enableDarkToggle;
- 
-  const rotate = useMemo(() => mode !== 'HORIZONTAL', [mode]);
- 
-  const flippedHorizontally = useMemo(
-    () => flipLayout && mode === 'HORIZONTAL',
-    [],
-  );
- 
-  const canDisableLeft = useMemo(
-    () => disableLeft || slideShowRunning,
-    [disableLeft, slideShowRunning],
-  );
- 
-  const canDisableRight = useMemo(
-    () => disableRight || slideShowRunning,
-    [disableRight, slideShowRunning],
-  );
- 
-  const handlePause = useCallback(() => {
-    onPaused?.();
-  }, [onPaused]);
- 
-  const handlePlay = useCallback(() => {
-    onReplay?.();
-  }, [onReplay]);
- 
-  const previousTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.next : buttonTexts?.previous),
-    [flipLayout],
-  );
- 
-  const nextTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.previous : buttonTexts?.next),
-    [flipLayout],
-  );
- 
-  const playOrPauseTile = useMemo(
-    () => (slideShowRunning ? buttonTexts?.stop : buttonTexts?.play),
-    [slideShowRunning],
-  );
- 
-  const jumpToLastTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.first : buttonTexts?.last),
-    [flipLayout],
-  );
- 
-  const jumpToFirstTitle = useMemo(
-    () => (flipLayout ? buttonTexts?.last : buttonTexts?.first),
-    [flipLayout],
-  );
- 
-  // Create a message about current position for screen readers
-  const positionStatus = useMemo(() => {
-    if (totalItems <= 0) return '';
-    return `Item ${activeTimelineItem + 1} of ${totalItems}`;
-  }, [activeTimelineItem, totalItems]);
- 
-  // Create a message about slideshow status for screen readers
-  const slideshowStatus = useMemo(() => {
-    if (!slideShowEnabled) return '';
-    return slideShowRunning ? 'Slideshow is playing' : 'Slideshow is paused';
-  }, [slideShowRunning, slideShowEnabled]);
- 
-  return (
-    <TimelineControlContainer key="control-wrapper">
-      {/* Visually hidden status information for screen readers */}
-      <ScreenReaderOnly as="output" aria-live="polite">
-        {positionStatus}
-        {slideshowStatus && ` ${slideshowStatus}`}
-      </ScreenReaderOnly>
- 
-      <TimelineNavWrapper
-        className={cls('timeline-controls', classNames?.controls)}
-        theme={theme}
-        aria-label="Timeline Navigation"
-        role="toolbar"
-      >
-        {/* jump to first */}
-        {disableInteraction ? null : (
-          <>
-            <div className={`nav-item ${canDisableLeft ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onLast : onFirst}
-                title={jumpToFirstTitle}
-                aria-label={jumpToFirstTitle}
-                aria-disabled={disableLeft}
-                aria-controls="timeline-main-wrapper"
-                tabIndex={!disableLeft ? 0 : -1}
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                data-test-id="jump-to-first"
-              >
-                <ChevronsLeftIcon />
-              </TimelineNavButton>
-            </div>
- 
-            {/* previous */}
-            <div className={`nav-item ${canDisableLeft ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onNext : onPrevious}
-                title={previousTitle}
-                aria-label={previousTitle}
-                aria-disabled={disableLeft}
-                aria-controls="timeline-main-wrapper"
-                tabIndex={!disableLeft ? 0 : -1}
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                data-test-id="previous"
-              >
-                <ChevronLeft />
-              </TimelineNavButton>
-            </div>
- 
-            {/* next */}
-            <div className={`nav-item ${canDisableRight ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onPrevious : onNext}
-                title={nextTitle}
-                aria-label={nextTitle}
-                aria-disabled={disableRight}
-                aria-controls="timeline-main-wrapper"
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                tabIndex={!disableRight ? 0 : -1}
-                data-test-id="next"
-              >
-                <ChevronRightIcon />
-              </TimelineNavButton>
-            </div>
- 
-            {/* jump to last */}
-            <div className={`nav-item ${canDisableRight ? 'disabled' : ''}`}>
-              <TimelineNavButton
-                mode={mode}
-                theme={theme}
-                onClick={flippedHorizontally ? onFirst : onLast}
-                title={jumpToLastTitle}
-                aria-label={jumpToLastTitle}
-                aria-disabled={disableRight}
-                aria-controls="timeline-main-wrapper"
-                tabIndex={!disableRight ? 0 : -1}
-                rotate={rotate ? 'TRUE' : 'FALSE'}
-                data-test-id="jump-to-last"
-              >
-                <ChevronsRightIcon />
-              </TimelineNavButton>
-            </div>
-          </>
-        )}
- 
-        {/* slideshow button */}
-        <div className="nav-item">
-          {slideShowEnabled && (
-            <TimelineNavButton
-              theme={theme}
-              onClick={slideShowRunning ? handlePause : handlePlay}
-              title={playOrPauseTile}
-              tabIndex={0}
-              aria-controls="timeline-main-wrapper"
-              aria-label={playOrPauseTile}
-              aria-pressed={slideShowRunning ? 'true' : 'false'}
-              data-test-id="play-pause"
-            >
-              {slideShowRunning ? <StopIcon /> : <ReplayIcon />}
-            </TimelineNavButton>
-          )}
-        </div>
- 
-        {/* dark toggle button */}
-        {enableDarkToggle ? (
-          <div className={`nav-item ${slideShowRunning ? 'disabled' : ''}`}>
-            <TimelineNavButton
-              theme={theme}
-              onClick={onToggleDarkMode}
-              title={isDark ? buttonTexts?.light : buttonTexts?.dark}
-              tabIndex={0}
-              aria-controls="timeline-main-wrapper"
-              aria-label={isDark ? buttonTexts?.light : buttonTexts?.dark}
-              aria-pressed={isDark ? 'true' : 'false'}
-              data-test-id="dark-toggle"
-              $active={isDark}
-            >
-              {isDark ? <SunIcon /> : <MoonIcon />}
-            </TimelineNavButton>
-          </div>
-        ) : null}
-      </TimelineNavWrapper>
-    </TimelineControlContainer>
-  );
-};
- 
-Controls.displayName = 'Timeline Control';
- 
-export default Controls;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/index.html b/coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/index.html deleted file mode 100644 index e4b8b9048..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-controls-wrapper - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-controls-wrapper

-
- -
- 0% - Statements - 0/8 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 0% - Lines - 0/8 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-controls-wrapper.tsx -
-
0%0/8100%1/1100%1/10%0/8
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html deleted file mode 100644 index 177f9b380..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-controls-wrapper timeline-controls-wrapper.tsx

-
- -
- 0% - Statements - 0/8 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 0% - Lines - 0/8 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import React from 'react';
-import styled from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
- 
-/**
- * Wraps timeline controls and provides proper z-index stacking context
- */
-const ControlsWrapper = styled.div`
-  position: relative;
-  z-index: ${zIndex.controls};
-`;
- 
-interface TimelineControlsWrapperProps {
-  children: React.ReactNode;
-}
- 
-/**
- * A wrapper component that ensures proper z-index stacking of timeline controls
- * This helps prevent z-index conflicts between timeline points and controls/menus
- */
-const TimelineControlsWrapper: React.FC<TimelineControlsWrapperProps> = ({ children }) => {
-  return <ControlsWrapper>{children}</ControlsWrapper>;
-};
- 
-export default TimelineControlsWrapper;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/index.html b/coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/index.html deleted file mode 100644 index 3c5d272a5..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-item-title/__tests__

-
- -
- 100% - Statements - 46/46 -
- - -
- 100% - Branches - 7/7 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 46/46 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-title.test.tsx -
-
100%46/46100%7/7100%0/0100%46/46
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html deleted file mode 100644 index d8d3b4fff..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-item-title/__tests__ timeline-card-title.test.tsx

-
- -
- 100% - Statements - 46/46 -
- - -
- 100% - Branches - 7/7 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 46/46 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -601x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x - 
import { waitFor } from '@testing-library/react';
-import { describe } from 'vitest';
-import { customRender } from '../../../common/test';
-import { providerProps } from '../../../common/test/index';
-import TimelineItemTitle from '../timeline-card-title';
- 
-describe('Timeline item title', () => {
-  //should render the title
-  it('should render the title', () => {
-    const { getByText } = customRender(<TimelineItemTitle title="title" />, {
-      providerProps,
-    });
-    expect(getByText('title')).toBeInTheDocument();
-  });
- 
-  // should match the snapshot
-  it('should match the snapshot', () => {
-    const { container } = customRender(<TimelineItemTitle title="title" />, {
-      providerProps,
-    });
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  // should render the title with active class
-  it('should render the title with active class', () => {
-    const { getByText } = customRender(
-      <TimelineItemTitle title="title" active />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByText('title')).toHaveClass('active');
-  });
- 
-  // should render the title with custom class
-  it('should render the title with custom class', () => {
-    const { getByText } = customRender(
-      <TimelineItemTitle title="title" classString="custom-class" />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
-    expect(getByText('title')).toHaveClass('custom-class');
-  });
- 
-  // should have a custom alignment
-  it('should have a custom alignment', async () => {
-    const { getByText } = customRender(
-      <TimelineItemTitle title="title" align="left" />,
-      { providerProps },
-    );
-    expect(getByText('title')).toBeInTheDocument();
- 
-    await waitFor(() => {
-      expect(getByText('title')).toHaveProperty('align');
-      expect(getByText('title')).toHaveProperty('align', 'left');
-      // expect(getByText('title')).toHaveStyle('text-align: left');
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-item-title/index.html b/coverage/lcov-report/components/timeline-elements/timeline-item-title/index.html deleted file mode 100644 index 1d0e5589c..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-item-title/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-item-title

-
- -
- 100% - Statements - 37/37 -
- - -
- 95% - Branches - 19/20 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 37/37 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-card-title.styles.ts -
-
100%9/993.33%14/15100%0/0100%9/9
timeline-card-title.tsx -
-
100%28/28100%5/5100%1/1100%28/28
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html deleted file mode 100644 index f86f9110b..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-item-title timeline-card-title.styles.ts

-
- -
- 100% - Statements - 9/9 -
- - -
- 93.33% - Branches - 14/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 9/9 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31  -1x -  -1x -  -  -  -  -  -  -1x -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -1x -1x -1x -  -  - 
import { Theme } from '@models/Theme';
-import styled from 'styled-components';
- 
-export const TitleWrapper = styled.div<{
-  $fontSize?: string;
-  $hide?: boolean;
-  align?: string;
-  theme?: Theme;
-}>`
-  border-radius: 0.2rem;
-  font-size: ${(p) => (p.$fontSize ? p.$fontSize : '1rem')};
-  font-weight: 600;
-  overflow: hidden;
-  padding: 0.25rem;
-  visibility: ${(p) => (p.$hide ? 'hidden' : 'visible')};
-  text-align: ${(p) => (p.align ? p.align : '')};
-  color: ${(p) => (p.theme ? p.theme.titleColor : '')};
- 
-  /* --- Prevent long text from affecting layout --- */
-  white-space: nowrap; /* Prevent text from wrapping to multiple lines */
-  text-overflow: ellipsis; /* Show ellipsis (...) for overflowing text */
-  min-width: 0; /* Allow the element to shrink below its content size */
-  max-width: 100%; /* Ensure it doesn't exceed its container */
- 
-  &.active {
-    background: ${(p) => p.theme?.secondary};
-    color: ${(p) =>
-      p.theme?.titleColorActive ? p.theme?.titleColorActive : p.theme?.primary};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html deleted file mode 100644 index 6f4034aab..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-item-title/timeline-card-title.tsx.html +++ /dev/null @@ -1,232 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-item-title/timeline-card-title.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-item-title timeline-card-title.tsx

-
- -
- 100% - Statements - 28/28 -
- - -
- 100% - Branches - 5/5 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 28/28 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50  -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -94x -94x -94x -94x -94x -94x -94x -  -  -94x -94x -94x -94x -  -  -94x -  -94x -94x -94x -94x -94x -94x -94x -  -94x -94x -  -94x -  -1x - 
import { TitleModel } from '@models/TimelineCardTitleModel';
-import cls from 'classnames';
-import React, { useContext, useMemo } from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import { TitleWrapper } from './timeline-card-title.styles';
- 
-/**
- * TimelineItemTitle component
- * This component renders the title of a timeline item and applies appropriate styling based on the given props.
- *
- * @property {string} title - The text of the title.
- * @property {boolean} active - Indicates whether the title is active or not.
- * @property {Theme} theme - The theme object, used for styling.
- * @property {string} align - The alignment of the title.
- * @property {string} classString - Additional CSS classes for the title.
- * @returns {JSX.Element} The TimelineItemTitle component.
- */
-const TimelineItemTitle: React.FunctionComponent<TitleModel> = ({
-  title,
-  active,
-  theme,
-  align,
-  classString,
-}: TitleModel) => {
-  const TITLE_CLASS = 'timeline-item-title'; // Base class name for the title
- 
-  // Computed class name for the title, combining base class, active state, and additional classes
-  const titleClass = useMemo(
-    () => cls(TITLE_CLASS, active ? 'active' : '', classString),
-    [active, classString],
-  );
- 
-  // Get font size from global context
-  const { fontSizes } = useContext(GlobalContext);
- 
-  return (
-    <TitleWrapper
-      className={titleClass}
-      theme={theme}
-      $hide={!title}
-      align={align}
-      $fontSize={fontSizes?.title}
-    >
-      {title}
-    </TitleWrapper>
-  );
-};
- 
-export default TimelineItemTitle;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/index.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/index.html deleted file mode 100644 index 41a36f1ef..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/__tests__ - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-outline/__tests__

-
- -
- 94.69% - Statements - 107/113 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 94.69% - Lines - 107/113 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-outline.test.tsx -
-
94.69%107/113100%13/13100%0/094.69%107/113
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html deleted file mode 100644 index 2e66577c1..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline/__tests__ timeline-outline.test.tsx

-
- -
- 94.69% - Statements - 107/113 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 94.69% - Lines - 107/113 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140  -1x -1x -  -1x -  -  -  -1x -  -  -  -  -  -  -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -6x -6x -6x -6x -6x -6x -6x -1x -  -1x -6x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import React from 'react';
-import { render, fireEvent, waitFor } from '@testing-library/react';
-import { TimelineOutline } from '../timeline-outline'; // Update import based on your actual file path
-import { Theme } from '@models/Theme';
-import { vi, Mock } from 'vitest';
-import { TimelineOutlineItem } from '../timeline-outline.model';
- 
-// Mock GlobalContext and icons
-vi.mock('../../GlobalContext', () => ({
-  GlobalContext: {
-    Consumer: ({ children }) =>
-      children({
-        theme: {},
-      }),
-  },
-}));
- 
-vi.mock('../../icons/close', () => () => 'CloseIcon');
-vi.mock('../../icons/menu', () => () => 'MenuIcon');
- 
-describe('<TimelineOutline />', () => {
-  let mockItems: TimelineOutlineItem[];
-  let mockTheme: Theme;
-  let mockOnSelect: Mock;
- 
-  beforeEach(() => {
-    mockItems = [
-      { id: '1', name: 'Item 1', selected: false },
-      { id: '2', name: 'Item 2', selected: true },
-      { id: '3', name: 'Item 3', selected: false },
-    ];
-    mockTheme = {}; // Add any specific theme details if needed
-    mockOnSelect = vi.fn();
-  });
- 
-  afterEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  // Test 1: Component rendering
-  it('should render correctly with initial state', () => {
-    const { getByRole, queryByText } = render(
-      <TimelineOutline
-        items={mockItems}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
-    expect(getByRole('button')).toBeInTheDocument();
-    expect(queryByText('Item 1')).not.toBeInTheDocument(); // List should be hidden initially
-  });
- 
-  // Test 2: Test component interactions (Toggle Pane)
-  it('should toggle pane on button click', async () => {
-    const { getByText, getByRole } = render(
-      <TimelineOutline
-        items={mockItems}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
- 
-    fireEvent.pointerDown(getByRole('button'));
- 
-    await waitFor(() => {
-      expect(getByText('Item 1')).toBeInTheDocument(); // List should be visible now
-    });
-  });
- 
-  // // Test 3: Test component state and props (Items and Selection)
-  it('should correctly handle item selection', async () => {
-    const { getByRole, getByText } = render(
-      <TimelineOutline
-        items={mockItems}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
- 
-    fireEvent.pointerDown(getByRole('button'));
- 
-    await waitFor(() => {
-      expect(getByText('Item 1')).toBeInTheDocument(); // List should be visible now
-      fireEvent.pointerDown(getByText('Item 1'));
-    });
- 
-    await waitFor(() => {
-      expect(mockOnSelect).toHaveBeenCalledWith(0); // The index of the clicked item should be 0
-    });
-  });
- 
-  // // Test 4: Test component state and props (Edge Cases)
-  it('should handle empty items array gracefully', async () => {
-    const { getByRole, queryByText } = render(
-      <TimelineOutline
-        items={[]}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
- 
-    fireEvent.pointerDown(getByRole('button'));
- 
-    await waitFor(() => {
-      expect(queryByText('Item 1')).not.toBeInTheDocument(); // No items should be displayed
-    });
-  });
- 
-  it('should show loading state', () => {
-    const { getByRole } = render(
-      <TimelineOutline
-        items={mockItems}
-        isLoading={true}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
-    expect(getByRole('status')).toHaveTextContent('Loading outline...');
-  });
- 
-  it('should show error state', () => {
-    const error = new Error('Test error');
-    const { getByRole } = render(
-      <TimelineOutline
-        items={mockItems}
-        error={error}
-        onSelect={mockOnSelect}
-        mode={'VERTICAL'}
-        theme={mockTheme}
-      />,
-    );
-    expect(getByRole('alert')).toHaveTextContent('Error: Test error');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/animations.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/animations.ts.html deleted file mode 100644 index c26b5e399..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/animations.ts.html +++ /dev/null @@ -1,172 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/animations.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline animations.ts

-
- -
- 0% - Statements - 0/3 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/3 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { keyframes } from 'styled-components';
- 
-export const open = keyframes`
-  from {
-    width: 30px;
-    height: 30px;
-    opacity: 0.5;
-  }
- 
-  to {
-    width: 200px;
-    height: 50%;
-    opacity: 1;
-  }
-`;
- 
-export const close = keyframes`
-  from {
-    width: 200px;
-    height: 50%;
-    opacity: 1;
-  }
- 
-  to {
-    width: 30px;
-    height: 30px;
-    opacity: 0.5;
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/index.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/index.html deleted file mode 100644 index d30f29e4e..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/hooks - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-outline/hooks

-
- -
- 90.9% - Statements - 10/11 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 90.9% - Lines - 10/11 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useOutlinePosition.ts -
-
90.9%10/1150%2/4100%1/190.9%10/11
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html deleted file mode 100644 index c87488046..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts.html +++ /dev/null @@ -1,142 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline/hooks useOutlinePosition.ts

-
- -
- 90.9% - Statements - 10/11 -
- - -
- 50% - Branches - 2/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 90.9% - Lines - 10/11 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -201x -  -1x -  -  -  -  -  -  -  -1x -12x -12x -6x -6x -  -12x -12x -12x - 
import { useMemo } from 'react';
-import { TimelineMode } from '@models/TimelineModel';
-import { OutlinePosition } from '../timeline-outline.model';
- 
-/**
- * Custom hook to determine the outline position based on timeline mode
- *
- * @param mode - The current timeline mode
- * @returns The position of the outline
- */
-export const useOutlinePosition = (mode?: TimelineMode): OutlinePosition => {
-  return useMemo(
-    () =>
-      mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING'
-        ? OutlinePosition.right
-        : OutlinePosition.left,
-    [mode],
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/index.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/index.html deleted file mode 100644 index 2305a00fd..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/index.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline - - - - - - - - - -
-
-

All files components/timeline-elements/timeline-outline

-
- -
- 92.06% - Statements - 174/189 -
- - -
- 85% - Branches - 51/60 -
- - -
- 71.42% - Functions - 5/7 -
- - -
- 92.06% - Lines - 174/189 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
animations.ts -
-
0%0/30%0/10%0/10%0/3
timeline-outline-item-list.tsx -
-
86.66%52/6055.55%5/9100%0/086.66%52/60
timeline-outline.model.ts -
-
100%3/3100%1/1100%0/0100%3/3
timeline-outline.styles.ts -
-
97.36%37/3889.65%26/29100%3/397.36%37/38
timeline-outline.tsx -
-
96.47%82/8595%19/2066.66%2/396.47%82/85
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html deleted file mode 100644 index c05033d05..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx.html +++ /dev/null @@ -1,394 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline-item-list.tsx

-
- -
- 86.66% - Statements - 52/60 -
- - -
- 55.55% - Branches - 5/9 -
- - -
- 100% - Functions - 0/0 -
- - -
- 86.66% - Lines - 52/60 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104  -1x -  -  -  -  -  -1x -  -1x -  -  -1x -1x -6x -6x -6x -6x -6x -  -  -  -  -6x -6x -6x -6x -6x -  -6x -6x -6x -6x -6x -6x -6x -  -6x -6x -6x -6x -6x -  -6x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -3x -  -  -  -3x -  -3x -  -  -  -  -  -  -  -3x -  -3x -3x -3x -6x -6x -6x -6x -6x -6x -6x -3x -3x -  -  -  -  -  -  -3x -  -3x -1x -  -1x -  -  - 
import { Theme } from '@models/Theme';
-import {
-  List,
-  ListItem,
-  ListItemBullet,
-  ListItemName,
-} from './timeline-outline.styles';
-import { memo, FunctionComponent, useCallback, useMemo } from 'react';
-import { TimelineOutlineItem } from './timeline-outline.model';
-import { useWindowSize } from '../../../hooks/useWindowSize';
- 
-// Extract item into its own component for better performance
-const OutlineItem = memo(
-  ({
-    item,
-    index,
-    handleSelection,
-    theme,
-  }: {
-    item: TimelineOutlineItem;
-    index: number;
-    handleSelection: (index: number, id?: string) => void;
-    theme: Theme;
-  }) => {
-    const onClick = useCallback(
-      () => handleSelection(index, item.id),
-      [handleSelection, index, item.id],
-    );
- 
-    return (
-      <ListItem
-        key={item.id ?? index}
-        onPointerDown={onClick}
-        aria-disabled={item.disabled}
-        aria-selected={item.selected}
-        aria-label={item.ariaLabel ?? item.name}
-      >
-        <ListItemBullet theme={theme} selected={item.selected}></ListItemBullet>
-        <ListItemName theme={theme} selected={item.selected}>
-          {item.name}
-        </ListItemName>
-      </ListItem>
-    );
-  },
-);
- 
-OutlineItem.displayName = 'OutlineItem';
- 
-interface OutlineItemListModel {
-  handleSelection: (index: number, id?: string) => void;
-  items: TimelineOutlineItem[];
-  theme: Theme;
-}
- 
-/**
- * OutlineItemList component
- * This component is responsible for rendering the outline list of items.
- * It uses virtualization for better performance with long lists.
- */
-const OutlineItemList: FunctionComponent<OutlineItemListModel> = memo(
-  ({ items, handleSelection, theme }) => {
-    const { height } = useWindowSize();
- 
-    // Only render the visible items based on window size
-    // In a real implementation, you'd use a proper virtualization library
-    const visibleItems = useMemo(() => {
-      // If list is small, render all items
-      if (items.length < 50) return items;
- 
-      const itemHeight = 30; // Approximate height of an item
-      const visibleCount = Math.ceil(height / itemHeight);
- 
-      // In a real virtualization implementation, you'd calculate visible range
-      // based on scroll position. This is a simplified version.
-      return items.slice(0, visibleCount * 2);
-    }, [items, height]);
- 
-    return (
-      <List>
-        {visibleItems.map((item, index) => (
-          <OutlineItem
-            key={item.id ?? index}
-            item={item}
-            index={index}
-            handleSelection={handleSelection}
-            theme={theme}
-          />
-        ))}
-        {items.length > visibleItems.length && (
-          <ListItem>
-            <ListItemName theme={theme}>
-              {`+ ${items.length - visibleItems.length} more items`}
-            </ListItemName>
-          </ListItem>
-        )}
-      </List>
-    );
-  },
-);
- 
-OutlineItemList.displayName = 'OutlineItemList';
- 
-export { OutlineItemList };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html deleted file mode 100644 index fa2737d1a..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.model.ts.html +++ /dev/null @@ -1,160 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline.model.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline.model.ts

-
- -
- 100% - Statements - 3/3 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 3/3 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
- 
-export enum OutlinePosition {
-  'left',
-  'right',
-}
- 
-export interface TimelineOutlineModel {
-  items?: TimelineOutlineItem[];
-  mode?: TimelineMode;
-  onSelect?: (index: number) => void;
-  theme?: Theme;
-  isLoading?: boolean;
-  error?: Error | null;
-  onError?: (error: Error) => void;
-}
- 
-export interface TimelineOutlineItem {
-  id?: string;
-  name?: string;
-  selected?: boolean;
-  disabled?: boolean;
-  ariaLabel?: string;
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html deleted file mode 100644 index 6d9bb64f5..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.styles.ts.html +++ /dev/null @@ -1,607 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline.styles.ts

-
- -
- 97.36% - Statements - 37/38 -
- - -
- 89.65% - Branches - 26/29 -
- - -
- 100% - Functions - 3/3 -
- - -
- 97.36% - Lines - 37/38 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175  -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -1x -  -  -1x -1x -1x -10x -6x -  -  -  -1x -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -10x -  -1x -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -1x -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -6x -2x -1x -  -  -1x -6x -2x -1x -  -  - 
import { Theme } from '@models/Theme';
-import styled, { keyframes } from 'styled-components';
-import { zIndex } from '../../../styles/z-index';
-import { OutlinePosition } from './timeline-outline.model';
- 
-const open = keyframes`
-  from {
-    width: 30px;
-    height: 30px;
-  }
- 
-  to: {
-    width: 200px;
-    height: 50%;
-  }
-  `;
- 
-const close = keyframes`
-  from {
-    width: 200px;
-    height: 50%;
-  }
- 
-  to: {
-    width: 30px;
-    height: 30px;
-  }
-`;
- 
-export const OutlineWrapper = styled.div<{
-  open?: boolean;
-  position?: OutlinePosition;
-}>`
-  animation: ${(p) => (p.open ? open : close)};
-  animation-duration: 0.2s;
-  animation-timing-function: ease-in;
-  background: rgba(255, 255, 255, 0.98);
-  border: 1px solid ${(p) => (p.open ? '#f5f5f5' : 'none')};
-  height: 50%;
-  width: 100%;
-  ${(p) =>
-    p.position === OutlinePosition.left ? `left: 1rem;` : `right: 3rem;`};
-  ${(p) =>
-    p.open
-      ? `
-    width: 200px;
-    height: 50%;
-    overflow-y: auto;`
-      : `width: 30px; height: 30px;`};
-`;
- 
-export const OutlinePane = styled.aside<{ open?: boolean; theme?: Theme }>`
-  align-items: center;
-  border-radius: 4px;
-  display: flex;
-  justify-content: center;
-  position: absolute;
-  z-index: ${zIndex.modal}; /* Use standardized z-index for outline panel */
-  box-shadow: 0 5px 10px 2px
-    rgba(
-      0,
-      0,
-      0,
-      ${({ theme }) => (theme?.toolbarBgColor === '#374151' ? '0.5' : '0.2')}
-    );
-  top: 1rem;
-`;
- 
-export const OutlineButton = styled.button<{
-  open?: boolean;
-  position?: OutlinePosition;
-  theme?: Theme;
-}>`
-  align-items: center;
-  align-self: flex-end;
-  background: #fff;
-  border-radius: 4px;
-  border: 0;
-  // box-shadow: ${(p) => (!p.open ? '0 0 10px 2px rgba(0,0,0,0.2)' : 'none')};
-  cursor: pointer;
-  display: flex;
-  height: 30px;
-  justify-content: center;
-  padding: 0;
-  width: 30px;
- 
-  ${(p) =>
-    p.position === OutlinePosition.left
-      ? 'margin-right: auto;'
-      : 'margin-left: auto;'};
- 
-  & svg {
-    width: 70%;
-    height: 70%;
-  }
- 
-  & svg path {
-    color: ${(p) => p.theme.iconColor || p.theme.primary};
-  }
-`;
- 
-export const List = styled.ul`
-  display: flex;
-  flex-direction: column;
-  height: 100%;
-  list-style: none;
-  margin: 0;
-  overflow-y: auto;
-  padding: 0;
-  width: 80%;
-`;
- 
-export const ListItem = styled.li`
-  align-items: center;
-  display: flex;
-  font-size: 0.9rem;
-  justify-content: flex-start;
-  margin: 0.75rem 0;
-  cursor: pointer;
-  position: relative;
- 
-  &:not(:last-child)::after {
-    content: '';
-    display: block;
-    width: 100%;
-    position: absolute;
-    height: 1px;
-    background: #ddd;
-    left: 0;
-    right: 0;
-    margin: 0 auto;
-    bottom: -50%;
-  }
-`;
- 
-export const ListItemName = styled.span<{ selected?: boolean; theme?: Theme }>`
-  font-size: 0.75rem;
-  color: ${(p) => (p.selected ? p.theme.iconColor || p.theme.primary : '')};
-  padding-left: 0.25rem;
- 
-  &:hover {
-    color: ${(p) => p.theme.iconColor || p.theme.primary};
-  }
-`;
- 
-export const ListItemBullet = styled.span<{
-  selected?: boolean;
-  theme?: Theme;
-}>`
-  align-items: center;
-  display: flex;
-  justify-content: center;
-  margin-right: 1rem;
-  position: relative;
- 
-  &::after {
-    content: '';
-    display: block;
-    position: absolute;
-    width: 8px;
-    height: 8px;
-    border-radius: 50%;
-    background: ${(p) =>
-      p.selected
-        ? `${p.theme.secondary}`
-        : p.theme.iconColor || `${p.theme.primary}`};
-    left: 0;
-    margin: 0 auto;
-    border: ${(p) =>
-      p.selected
-        ? `2px solid ${p.theme.secondary}`
-        : `2px solid ${p.theme.iconColor || p.theme.primary}`};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.tsx.html b/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.tsx.html deleted file mode 100644 index 2c1558a44..000000000 --- a/coverage/lcov-report/components/timeline-elements/timeline-outline/timeline-outline.tsx.html +++ /dev/null @@ -1,466 +0,0 @@ - - - - - - Code coverage report for components/timeline-elements/timeline-outline/timeline-outline.tsx - - - - - - - - - -
-
-

All files / components/timeline-elements/timeline-outline timeline-outline.tsx

-
- -
- 96.47% - Statements - 82/85 -
- - -
- 95% - Branches - 19/20 -
- - -
- 66.66% - Functions - 2/3 -
- - -
- 96.47% - Lines - 82/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -1281x -  -  -  -  -  -  -  -1x -1x -1x -1x -  -1x -  -  -  -  -1x -  -1x -  -1x -1x -  -  -  -1x -10x -10x -1x -  -  -1x -1x -1x -1x -  -  -  -  -  -  -  -1x -12x -12x -12x -12x -12x -12x -12x -12x -12x -12x -  -12x -12x -  -  -12x -  -12x -  -  -12x -  -9x -9x -3x -9x -6x -  -6x -6x -  -9x -9x -9x -12x -  -12x -12x -1x -1x -12x -12x -  -12x -1x -1x -  -12x -1x -1x -  -10x -10x -10x -10x -10x -10x -10x -  -10x -10x -10x -10x -10x -  -12x -12x -12x -12x -3x -3x -3x -3x -3x -  -12x -12x -12x -  -12x -  -  - 
import React, {
-  useCallback,
-  useContext,
-  useEffect,
-  useState,
-  PropsWithChildren,
-  memo,
-} from 'react';
-import { GlobalContext } from '../../GlobalContext';
-import CloseIcon from '../../icons/close';
-import MenuIcon from '../../icons/menu';
-import { OutlineItemList } from './timeline-outline-item-list';
-import { TimelineOutlineModel } from './timeline-outline.model';
-import {
-  OutlineButton,
-  OutlinePane,
-  OutlineWrapper,
-} from './timeline-outline.styles';
-import { useOutlinePosition } from './hooks/useOutlinePosition';
- 
-class TimelineOutlineError extends React.Component<
-  PropsWithChildren<{ onError?: (error: Error) => void }>
-> {
-  componentDidCatch(error: Error) {
-    this.props.onError?.(error);
-  }
- 
-  render() {
-    return this.props.children;
-  }
-}
- 
-// Separate loading and error components to improve code organization
-const OutlineLoading = memo(() => <div role="status">Loading outline...</div>);
-const OutlineError = memo(({ error }: { error: Error }) => (
-  <div role="alert">Error: {error.message}</div>
-));
- 
-/**
- * TimelineOutline component
- * This component renders the outline pane of a timeline, including a list of items and corresponding selection functionality.
- * It provides an interface to toggle the outline pane and select items within the timeline.
- * The component leverages memoization to prevent unnecessary re-renders and optimizes the rendering process.
- */
-const TimelineOutline: React.FC<TimelineOutlineModel> = ({
-  items = [],
-  onSelect,
-  mode,
-  theme,
-  isLoading,
-  error,
-  onError,
-}: TimelineOutlineModel) => {
-  const [openPane, setOpenPane] = useState(false);
-  const [showList, setShowList] = useState(false);
- 
-  const { theme: globalTheme } = useContext(GlobalContext);
-  const mergedTheme = theme || globalTheme;
- 
-  // Extract position logic to a custom hook
-  const position = useOutlinePosition(mode);
- 
-  const togglePane = useCallback(() => setOpenPane((prev) => !prev), []);
- 
-  // Optimize effect to only run when openPane changes
-  useEffect(() => {
-    // Use a timeout to create a smooth animation effect
-    let timer: number;
-    if (openPane) {
-      setShowList(true);
-    } else {
-      timer = window.setTimeout(() => {
-        setShowList(false);
-      }, 300); // Match this with CSS transition time
-    }
- 
-    return () => {
-      if (timer) window.clearTimeout(timer);
-    };
-  }, [openPane]);
- 
-  const handleSelection = useCallback(
-    (index: number, id?: string) => {
-      onSelect?.(index);
-    },
-    [onSelect],
-  );
- 
-  if (error) {
-    return <OutlineError error={error} />;
-  }
- 
-  if (isLoading) {
-    return <OutlineLoading />;
-  }
- 
-  return (
-    <TimelineOutlineError onError={onError}>
-      <OutlineWrapper
-        position={position}
-        open={openPane}
-        aria-expanded={openPane}
-        role="complementary"
-      >
-        <OutlineButton
-          onPointerDown={togglePane}
-          theme={mergedTheme}
-          open={openPane}
-          position={position}
-        >
-          {openPane ? <CloseIcon /> : <MenuIcon />}
-        </OutlineButton>
-        <OutlinePane open={openPane}>
-          {showList && (
-            <OutlineItemList
-              items={items}
-              handleSelection={handleSelection}
-              theme={mergedTheme}
-            />
-          )}
-        </OutlinePane>
-      </OutlineWrapper>
-    </TimelineOutlineError>
-  );
-};
- 
-export { TimelineOutline };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-horizontal/__tests__/index.html b/coverage/lcov-report/components/timeline-horizontal/__tests__/index.html deleted file mode 100644 index c358b0b66..000000000 --- a/coverage/lcov-report/components/timeline-horizontal/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/__tests__ - - - - - - - - - -
-
-

All files components/timeline-horizontal/__tests__

-
- -
- 98.3% - Statements - 232/236 -
- - -
- 92% - Branches - 23/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.3% - Lines - 232/236 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal.test.tsx -
-
98.3%232/23692%23/25100%1/198.3%232/236
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html b/coverage/lcov-report/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html deleted file mode 100644 index 04c4351f7..000000000 --- a/coverage/lcov-report/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx.html +++ /dev/null @@ -1,925 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-horizontal/__tests__ timeline-horizontal.test.tsx

-
- -
- 98.3% - Statements - 232/236 -
- - -
- 92% - Branches - 23/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.3% - Lines - 232/236 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -2811x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -20x -20x -20x -20x -20x -20x -20x -20x -20x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -  -1x -  -  -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -2x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x - 
import { render, screen } from '@testing-library/react';
-import { describe, expect, it, vi } from 'vitest';
-import { GlobalContext } from '../../GlobalContext';
-import { TimelineHorizontalModel } from '../../../models/TimelineHorizontalModel';
-import TimelineHorizontal from '../timeline-horizontal';
- 
-const mockItems = [
-  {
-    id: '1',
-    title: 'Test Item 1',
-    cardTitle: 'Card Title 1',
-    cardSubtitle: 'Card Subtitle 1',
-    cardDetailedText: 'Detailed text for item 1',
-    visible: true,
-    active: false,
-    wrapperId: 'timeline-wrapper',
-  },
-  {
-    id: '2',
-    title: 'Test Item 2',
-    cardTitle: 'Card Title 2',
-    cardSubtitle: 'Card Subtitle 2',
-    cardDetailedText: 'Detailed text for item 2',
-    visible: true,
-    active: true,
-    wrapperId: 'timeline-wrapper',
-  },
-  {
-    id: '3',
-    title: 'Test Item 3',
-    cardTitle: 'Card Title 3',
-    cardSubtitle: 'Card Subtitle 3',
-    cardDetailedText: 'Detailed text for item 3',
-    visible: false,
-    active: false,
-    wrapperId: 'timeline-wrapper',
-  },
-];
- 
-const defaultProps: TimelineHorizontalModel = {
-  items: mockItems,
-  handleItemClick: vi.fn(),
-  autoScroll: vi.fn(),
-  wrapperId: 'timeline-wrapper',
-  slideShowRunning: false,
-  onElapsed: vi.fn(),
-  contentDetailsChildren: undefined,
-  hasFocus: false,
-  iconChildren: undefined,
-  nestedCardHeight: 200,
-  isNested: false,
-};
- 
-const mockContextValue = {
-  mode: 'HORIZONTAL' as const,
-  itemWidth: 300,
-  cardHeight: 200,
-  flipLayout: false,
-  showAllCardsHorizontal: false,
-  theme: {
-    primary: '#0f172a',
-    secondary: '#64748b',
-    cardBgColor: '#ffffff',
-    cardForeColor: '#000000',
-    titleColor: '#0f172a',
-    titleColorActive: '#ffffff',
-  },
-  cardWidth: 400,
-};
- 
-const renderWithContext = (
-  props: Partial<TimelineHorizontalModel> = {},
-  contextValue: any = mockContextValue,
-) => {
-  return render(
-    <GlobalContext.Provider value={contextValue}>
-      <TimelineHorizontal {...defaultProps} {...props} />
-    </GlobalContext.Provider>,
-  );
-};
- 
-describe('TimelineHorizontal', () => {
-  it('should render without crashing', () => {
-    renderWithContext();
-    expect(screen.getByTestId('timeline-collection')).toBeInTheDocument();
-  });
- 
-  it('should render the correct number of timeline items', () => {
-    renderWithContext();
-    // Use querySelectorAll since getAllByRole might filter out hidden items
-    const container = screen.getByTestId('timeline-collection');
-    const allItems = container.querySelectorAll('li');
-    expect(allItems).toHaveLength(mockItems.length);
-  });
- 
-  it('should apply correct CSS classes based on mode', () => {
-    renderWithContext();
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toHaveClass('horizontal');
-    expect(container).toHaveClass('timeline-horizontal-container');
-  });
- 
-  it('should apply show-all-cards-horizontal class when showAllCardsHorizontal is true', () => {
-    const contextWithShowAll = {
-      ...mockContextValue,
-      showAllCardsHorizontal: true,
-    };
-    renderWithContext({}, contextWithShowAll);
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toHaveClass('show-all-cards-horizontal');
-  });
- 
-  it('should render with flipped layout when flipLayout is true', () => {
-    const contextWithFlipped = {
-      ...mockContextValue,
-      flipLayout: true,
-    };
-    renderWithContext({}, contextWithFlipped);
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should handle item click when timeline card is clicked', async () => {
-    const handleItemClick = vi.fn();
-    renderWithContext({ handleItemClick });
-    
-    // Note: The actual click testing would depend on the TimelineCard implementation
-    // For now, we verify that the function is passed correctly
-    expect(handleItemClick).toHaveBeenCalledTimes(0);
-  });
- 
-  it('should render visible items with visible class', () => {
-    renderWithContext();
-    const listItems = screen.getAllByRole('listitem');
-    
-    // First two items should be visible
-    expect(listItems[0]).toHaveClass('visible');
-    expect(listItems[1]).toHaveClass('visible');
-    // Third item should not have visible class (visible: false) if it exists
-    if (listItems[2]) {
-      expect(listItems[2]).not.toHaveClass('visible');
-    }
-  });
- 
-  it('should set aria-current="true" for active items', () => {
-    renderWithContext();
-    const listItems = screen.getAllByRole('listitem');
-    
-    // Only the second item is active
-    expect(listItems[0]).not.toHaveAttribute('aria-current');
-    expect(listItems[1]).toHaveAttribute('aria-current', 'true');
-    if (listItems[2]) {
-      expect(listItems[2]).not.toHaveAttribute('aria-current');
-    }
-  });
- 
-  it('should apply correct width to timeline items', () => {
-    const customItemWidth = 250;
-    const contextWithCustomWidth = {
-      ...mockContextValue,
-      itemWidth: customItemWidth,
-    };
-    renderWithContext({}, contextWithCustomWidth);
-    const listItems = screen.getAllByRole('listitem');
-    
-    // Check that items have the correct width style applied
-    listItems.forEach(item => {
-      expect(item).toHaveClass('timeline-horz-item-container');
-    });
-  });
- 
-  it('should handle slideshow properties correctly', () => {
-    renderWithContext({
-      slideShowRunning: true,
-      onElapsed: vi.fn(),
-    });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render with nested card properties', () => {
-    renderWithContext({
-      isNested: true,
-      nestedCardHeight: 150,
-    });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should pass icon children to timeline cards', () => {
-    const iconChildren = [
-      <div key="icon1">Icon 1</div>,
-      <div key="icon2">Icon 2</div>,
-      <div key="icon3">Icon 3</div>,
-    ];
-    
-    renderWithContext({ iconChildren });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should pass content details children to timeline cards', () => {
-    const contentDetailsChildren = [
-      <div key="content1">Content 1</div>,
-      <div key="content2">Content 2</div>,
-      <div key="content3">Content 3</div>,
-    ];
-    
-    renderWithContext({ contentDetailsChildren });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render with auto scroll enabled', () => {
-    renderWithContext({ autoScroll: vi.fn() });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render with hasFocus enabled', () => {
-    renderWithContext({ hasFocus: true });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-  });
- 
-  it('should render as semantic list with proper ARIA labels', () => {
-    renderWithContext();
-    const list = screen.getByRole('list', { name: 'Timeline' });
-    expect(list).toBeInTheDocument();
-    expect(list).toHaveAttribute('aria-label', 'Timeline');
-  });
- 
-  it('should handle empty items array', () => {
-    renderWithContext({ items: [] });
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toBeInTheDocument();
-    const listItems = screen.queryAllByRole('listitem');
-    expect(listItems).toHaveLength(0);
-  });
- 
-  it('should handle different timeline modes correctly', () => {
-    const contextVertical = {
-      ...mockContextValue,
-      mode: 'VERTICAL_ALTERNATING',
-    };
-    renderWithContext({}, contextVertical);
-    const container = screen.getByTestId('timeline-collection');
-    expect(container).toHaveClass('vertical_alternating');
-  });
- 
-  it('should memoize wrapper class to prevent unnecessary re-renders', () => {
-    const { rerender } = renderWithContext();
-    const container = screen.getByTestId('timeline-collection');
-    const initialClassName = container.className;
-    
-    // Re-render with same props
-    rerender(
-      <GlobalContext.Provider value={mockContextValue}>
-        <TimelineHorizontal {...defaultProps} />
-      </GlobalContext.Provider>,
-    );
-    
-    expect(container.className).toBe(initialClassName);
-  });
- 
-  it('should memoize timeline items to prevent unnecessary re-renders', () => {
-    const { rerender } = renderWithContext();
-    const initialItems = screen.getAllByRole('listitem');
-    
-    // Re-render with same props
-    rerender(
-      <GlobalContext.Provider value={mockContextValue}>
-        <TimelineHorizontal {...defaultProps} />
-      </GlobalContext.Provider>,
-    );
-    
-    const afterRerenderItems = screen.getAllByRole('listitem');
-    expect(afterRerenderItems).toHaveLength(initialItems.length);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-horizontal/index.html b/coverage/lcov-report/components/timeline-horizontal/index.html deleted file mode 100644 index e3ebb570c..000000000 --- a/coverage/lcov-report/components/timeline-horizontal/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal - - - - - - - - - -
-
-

All files components/timeline-horizontal

-
- -
- 100% - Statements - 103/103 -
- - -
- 100% - Branches - 17/17 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 103/103 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-horizontal.styles.ts -
-
100%5/5100%4/4100%0/0100%5/5
timeline-horizontal.tsx -
-
100%98/98100%13/13100%1/1100%98/98
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.styles.ts.html b/coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.styles.ts.html deleted file mode 100644 index de190fc89..000000000 --- a/coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.styles.ts.html +++ /dev/null @@ -1,190 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/timeline-horizontal.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-horizontal timeline-horizontal.styles.ts

-
- -
- 100% - Statements - 5/5 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 5/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -361x -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import styled from 'styled-components';
- 
-export const TimelineHorizontalWrapper = styled.ul<{ flipLayout?: boolean }>`
-  display: flex;
-  list-style: none;
-  margin: 0;
-  width: 100%;
-  direction: ${(p) => (p.flipLayout ? 'rtl' : 'ltr')};
- 
-  &.vertical {
-    flex-direction: column;
-  }
-  &.horizontal {
-    flex-direction: row;
-  }
-`;
- 
-export const TimelineItemWrapper = styled.li<{ width: number }>`
-  width: ${(p) => p.width}px;
-  visibility: hidden;
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  height: 150px;
-  flex-direction: column;
- 
-  &.vertical {
-    margin-bottom: 2rem;
-    width: 100%;
-  }
- 
-  &.visible {
-    visibility: visible;
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.tsx.html b/coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.tsx.html deleted file mode 100644 index 40ebd47bc..000000000 --- a/coverage/lcov-report/components/timeline-horizontal/timeline-horizontal.tsx.html +++ /dev/null @@ -1,472 +0,0 @@ - - - - - - Code coverage report for components/timeline-horizontal/timeline-horizontal.tsx - - - - - - - - - -
-
-

All files / components/timeline-horizontal timeline-horizontal.tsx

-
- -
- 100% - Statements - 98/98 -
- - -
- 100% - Branches - 13/13 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 98/98 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130  -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -23x -21x -21x -21x -21x -21x -23x -23x -  -23x -23x -23x -23x -  -  -23x -21x -61x -61x -61x -61x -61x -61x -61x -61x -61x -  -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -61x -21x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -23x -23x -23x -23x -23x -23x -23x -  -23x -23x -  -23x -  -1x - 
import { TimelineHorizontalModel } from '@models/TimelineHorizontalModel';
-import cls from 'classnames';
-import React, { ReactNode, useContext, useMemo } from 'react';
-import { GlobalContext } from '../GlobalContext';
-import TimelineCard from '../timeline-elements/timeline-card/timeline-horizontal-card';
-import {
-  TimelineHorizontalWrapper,
-  TimelineItemWrapper,
-} from './timeline-horizontal.styles';
- 
-/**
- * TimelineHorizontal
- * @property {TimelineHorizontalModel} items - The items to be displayed in the timeline.
- * @property {(item: TimelineItem) => void} handleItemClick - Function to handle item click.
- * @property {boolean} autoScroll - Whether to auto-scroll the timeline.
- * @property {string} wrapperId - The ID of the wrapper element.
- * @property {boolean} slideShowRunning - Whether the slideshow is running.
- * @property {() => void} onElapsed - Function to handle elapsed time.
- * @property {React.ReactNode} contentDetailsChildren - The children nodes for content details.
- * @property {boolean} hasFocus - Whether the timeline has focus.
- * @property {React.ReactNode} iconChildren - The children nodes for icons.
- * @property {number} nestedCardHeight - The height of the nested card.
- * @property {boolean} isNested - Whether the card is nested.
- * @returns {JSX.Element} The TimelineHorizontal component.
- */
- 
-const TimelineHorizontal: React.FunctionComponent<TimelineHorizontalModel> = ({
-  items,
-  handleItemClick,
-  autoScroll,
-  wrapperId,
-  slideShowRunning,
-  onElapsed,
-  contentDetailsChildren: children,
-  hasFocus,
-  iconChildren,
-  nestedCardHeight,
-  isNested,
-}: TimelineHorizontalModel) => {
-  const {
-    mode = 'HORIZONTAL',
-    itemWidth = 200,
-    cardHeight,
-    flipLayout,
-    showAllCardsHorizontal,
-    theme,
-    cardWidth,
-  } = useContext(GlobalContext);
- 
-  // Memoize the wrapper class to avoid unnecessary re-renders
-  const wrapperClass = useMemo(
-    () =>
-      cls(
-        mode.toLowerCase(),
-        'timeline-horizontal-container',
-        showAllCardsHorizontal ? 'show-all-cards-horizontal' : '',
-      ),
-    [mode, showAllCardsHorizontal],
-  );
- 
-  const iconChildColln = useMemo(
-    () => React.Children.toArray(iconChildren),
-    [iconChildren],
-  );
- 
-  // Memoize the timeline items to prevent unnecessary re-renders
-  const timelineItems = useMemo(() => {
-    return items.map((item, index) => (
-      <TimelineItemWrapper
-        key={item.id}
-        width={itemWidth}
-        className={cls(
-          item.visible ? 'visible' : '',
-          'timeline-horz-item-container',
-        )}
-        as="li"
-        aria-current={item.active ? 'true' : undefined}
-      >
-        <TimelineCard
-          {...item}
-          onClick={handleItemClick}
-          autoScroll={autoScroll}
-          wrapperId={wrapperId}
-          theme={theme}
-          slideShowRunning={slideShowRunning}
-          cardHeight={cardHeight}
-          onElapsed={onElapsed}
-          customContent={children ? (children as ReactNode[])[index] : null}
-          hasFocus={hasFocus}
-          iconChild={iconChildColln[index]}
-          active={item.active}
-          cardWidth={cardWidth}
-          isNested={isNested}
-          nestedCardHeight={nestedCardHeight}
-        />
-      </TimelineItemWrapper>
-    ));
-  }, [
-    items,
-    itemWidth,
-    handleItemClick,
-    autoScroll,
-    wrapperId,
-    theme,
-    slideShowRunning,
-    cardHeight,
-    onElapsed,
-    children,
-    hasFocus,
-    iconChildren,
-    cardWidth,
-    isNested,
-    nestedCardHeight,
-  ]);
- 
-  return (
-    <TimelineHorizontalWrapper
-      className={wrapperClass}
-      flipLayout={flipLayout}
-      data-testid="timeline-collection"
-      as="ul"
-      aria-label="Timeline"
-    >
-      {timelineItems}
-    </TimelineHorizontalWrapper>
-  );
-};
- 
-export default TimelineHorizontal;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/__tests__/index.html b/coverage/lcov-report/components/timeline-vertical/__tests__/index.html deleted file mode 100644 index 409b0aa09..000000000 --- a/coverage/lcov-report/components/timeline-vertical/__tests__/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/__tests__ - - - - - - - - - -
-
-

All files components/timeline-vertical/__tests__

-
- -
- 100% - Statements - 74/74 -
- - -
- 100% - Branches - 5/5 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 74/74 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-point.test.tsx -
-
100%26/26100%2/2100%0/0100%26/26
timeline-vertical-item.test.tsx -
-
100%48/48100%3/30%0/3100%48/48
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/__tests__/timeline-point.test.tsx.html b/coverage/lcov-report/components/timeline-vertical/__tests__/timeline-point.test.tsx.html deleted file mode 100644 index 98becd340..000000000 --- a/coverage/lcov-report/components/timeline-vertical/__tests__/timeline-point.test.tsx.html +++ /dev/null @@ -1,181 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/__tests__/timeline-point.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical/__tests__ timeline-point.test.tsx

-
- -
- 100% - Statements - 26/26 -
- - -
- 100% - Branches - 2/2 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 26/26 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -1x -1x -1x -  -1x -1x -1x - 
import { TimelinePointModel } from '@models/TimelineVerticalModel';
-import { describe, expect, it, vi } from 'vitest';
-import { customRender } from '../../common/test';
-import { providerProps } from '../../common/test/index';
-import { TimelinePoint } from '../timeline-point';
- 
-const commonProps: TimelinePointModel = {
-  active: false,
-  alternateCards: false,
-  cardLess: true,
-  className: 'test_class_name',
-  disableClickOnCircle: false,
-  iconChild: null,
-  id: '1',
-  lineWidth: 3,
-  onActive: vi.fn(),
-  onClick: vi.fn(),
-  slideShowRunning: false,
-  timelinePointDimension: 20,
-};
- 
-describe('Timeline point', () => {
-  // should match the snapshot
- 
-  it('Should match snapshot', () => {
-    const { asFragment } = customRender(<TimelinePoint {...commonProps} />, {
-      providerProps,
-    });
- 
-    expect(asFragment()).toMatchSnapshot();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html b/coverage/lcov-report/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html deleted file mode 100644 index 522f425a3..000000000 --- a/coverage/lcov-report/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx.html +++ /dev/null @@ -1,262 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical/__tests__ timeline-vertical-item.test.tsx

-
- -
- 100% - Statements - 48/48 -
- - -
- 100% - Branches - 3/3 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 48/48 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60  -1x -1x -1x -1x -  -  -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x - 
import { VerticalItemModel } from '@models/TimelineVerticalModel';
-import { describe, expect, it } from 'vitest';
-import { customRender } from '../../common/test';
-import { providerProps } from '../../common/test/index';
-import TimelineVerticalItem from '../timeline-vertical-item';
- 
-// ResizeObserver is already mocked globally in common/test/index.tsx
- 
-const commonProps: VerticalItemModel = {
-  // complete the rest of the properties
-  active: false,
-  alternateCards: false,
-  cardDetailedText: '',
-  cardSubtitle: '',
-  cardTitle: '',
-  className: '',
-  contentDetailsChildren: null,
-  hasFocus: false,
-  iconChild: null,
-  id: '',
-  index: 1,
-  media: {
-    source: {
-      type: 'IMAGE',
-      url: 'https://www.google.com/images/branding/googlelogo/2x/googlelogo_color_272x92dp.png',
-    },
-    type: 'IMAGE',
-  },
-  onActive: () => {},
-  onClick: () => {},
-  onElapsed: () => {},
-  slideShowRunning: false,
-  timelineContent: null,
-  title: 'vertical item title',
-  url: '',
-  visible: false,
-};
- 
-describe('Timeline vertical item', () => {
-  it('Should match snapshot', () => {
-    const { container } = customRender(
-      <TimelineVerticalItem {...commonProps} />,
-      { providerProps },
-    );
- 
-    expect(container).toMatchSnapshot();
-  });
- 
-  //should render the title
- 
-  it('Should render the title', () => {
-    const { getByText } = customRender(
-      <TimelineVerticalItem {...commonProps} />,
-      { providerProps },
-    );
- 
-    expect(getByText('vertical item title')).toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/index.html b/coverage/lcov-report/components/timeline-vertical/index.html deleted file mode 100644 index 2f70d09bd..000000000 --- a/coverage/lcov-report/components/timeline-vertical/index.html +++ /dev/null @@ -1,176 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical - - - - - - - - - -
-
-

All files components/timeline-vertical

-
- -
- 91.1% - Statements - 430/472 -
- - -
- 56.04% - Branches - 51/91 -
- - -
- 50% - Functions - 1/2 -
- - -
- 91.1% - Lines - 430/472 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
timeline-point.tsx -
-
88.99%97/10950%8/160%0/188.99%97/109
timeline-vertical-item.tsx -
-
93.8%197/21050%10/20100%1/193.8%197/210
timeline-vertical-shape.styles.ts -
-
100%16/1673.33%11/15100%0/0100%16/16
timeline-vertical.styles.ts -
-
86.66%39/4551.85%14/27100%0/086.66%39/45
timeline-vertical.tsx -
-
88.04%81/9261.53%8/13100%0/088.04%81/92
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/timeline-point.tsx.html b/coverage/lcov-report/components/timeline-vertical/timeline-point.tsx.html deleted file mode 100644 index dff66426d..000000000 --- a/coverage/lcov-report/components/timeline-vertical/timeline-point.tsx.html +++ /dev/null @@ -1,676 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-point.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-point.tsx

-
- -
- 88.99% - Statements - 97/109 -
- - -
- 50% - Branches - 8/16 -
- - -
- 0% - Functions - 0/1 -
- - -
- 88.99% - Lines - 97/109 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198  -1x -1x -  -  -  -  -  -  -  -1x -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -  -  -23x -23x -23x -23x -23x -23x -23x -23x -  -23x -23x -23x -  -  -23x -  -  -  -  -  -23x -  -23x -  -  -  -23x -23x -23x -23x -  -  -  -  -  -23x -23x -  -  -  -  -  -23x -  -  -  -  -  -23x -23x -23x -23x -23x -23x -23x -23x -  -  -  -  -  -23x -  -23x -  -  -  -  -23x -23x -  -  -  -  -  -  -23x -23x -  -  -  -  -23x -  -23x -23x -23x -23x -  -  -23x -23x -23x -  -  -23x -  -  -23x -23x -  -23x -23x -23x -23x -  -23x -23x -  -  -23x -  -23x -  -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -  -23x -23x -23x -  -23x -23x -  -23x -23x -23x -23x -  -23x -  -  -  -  -1x -  -  -1x -  -  - 
import { TimelinePointModel } from '@models/TimelineVerticalModel'; // Assuming model path
-import cls from 'classnames'; // Utility for conditionally joining classNames
-import React, {
-  memo, // Import memo for component optimization
-  useEffect,
-  useMemo,
-  useRef,
-  FunctionComponent, // Explicit import
-  MouseEvent,
-} from 'react';
-import { useStableContext, useDynamicContext } from '../contexts'; // Context for global theme/settings
-// Shape seems to be a shared styled component, potentially defined elsewhere
-import { Shape } from '../timeline-elements/timeline-card/timeline-horizontal-card.styles';
-import {
-  TimelinePointContainer,
-  TimelinePointWrapper,
-} from './timeline-vertical-shape.styles'; // Associated styled components
- 
-/**
- * Renders the circular point or icon on the timeline line for a vertical item.
- * Handles click events, active state highlighting, custom icons, and appearance
- * based on global theme and configuration settings. It uses React.memo for
- * performance optimization.
- *
- * @param {TimelinePointModel} props - The properties for the TimelinePoint component.
- * @returns {React.ReactElement} The rendered TimelinePoint component.
- */
-const TimelinePoint: FunctionComponent<TimelinePointModel> = memo(
-  (props: TimelinePointModel) => {
-    const {
-      className, // 'left' or 'right' - passed to styled components
-      id, // Unique ID of the timeline item
-      onClick, // Callback function when the point is clicked
-      active, // Is this point currently active/highlighted?
-      onActive, // Callback function when the point should trigger the 'active' state calculation
-      slideShowRunning, // Is a slideshow currently active? (disables onClick)
-      iconChild, // Custom React node to display inside the point (replaces default shape)
-      timelinePointDimension, // Size (width/height) of the point
-      lineWidth, // Width of the timeline line connecting points
-      disableClickOnCircle, // Should clicks on the point be ignored?
-      cardLess, // Is the timeline in 'cardLess' mode?
-      isMobile, // Is the view currently mobile?
-    } = props;
- 
-    // Ref to the button element representing the point
-    const circleRef = useRef<HTMLButtonElement>(null);
- 
-    // Access context settings
-    const {
-      staticDefaults: {
-        focusActiveItemOnLoad,
-        timelinePointShape,
-        disableTimelinePoint,
-      },
-      memoizedButtonTexts: buttonTexts, // Custom button text labels
-    } = useStableContext();
- 
-    const {
-      memoizedTheme: theme, // Theme object (primary color, etc.)
-    } = useDynamicContext();
- 
-    // Ref to track if this is the component's first render cycle
-    const isFirstRender = useRef(true);
- 
-    /**
-     * Determines if the onActive callback should be invoked based on the active state
-     * and whether it's the initial render (controlled by focusActiveItemOnLoad).
-     */
-    const canInvokeOnActive = useMemo(() => {
-      // If focusing on load is enabled, invoke if active.
-      if (focusActiveItemOnLoad) {
-        return active;
-      }
-      // Otherwise, invoke only if active AND it's not the first render.
-      else {
-        return active && !isFirstRender.current;
-      }
-    }, [active, focusActiveItemOnLoad]); // Dependencies: active state and global setting
- 
-    /**
-     * Effect to call the onActive callback when conditions are met.
-     * This usually happens when an item scrolls into view or is programmatically activated.
-     */
-    useEffect(() => {
-      if (canInvokeOnActive && onActive && circleRef.current) {
-        // Call the parent's onActive handler with the point's offsetTop
-        onActive(circleRef.current.offsetTop);
-      }
-      // Intentionally excluding onActive from dependencies if it's stable,
-      // otherwise, include it if it might change. Usually, it's stable.
-    }, [canInvokeOnActive, active]); // Re-run when activation condition or active state changes
- 
-    /**
-     * Memoized CSS classes for the inner Shape component.
-     * Applies 'active' class and 'using-icon' if a custom icon is provided.
-     */
-    const circleClass = useMemo(
-      () =>
-        cls({
-          active: active, // Apply 'active' class if the point is active
-          'using-icon': !!iconChild, // Apply class if a custom icon is used
-        }),
-      [active, iconChild], // Dependencies: active state and presence of iconChild
-    );
- 
-    /**
-     * Memoized click handler props for the TimelinePointContainer button.
-     * Only adds onClick if clicks are enabled and slideshow isn't running.
-     */
-    const clickHandlerProps = useMemo(() => {
-      // Return empty object (no click handler) if clicks are disabled
-      if (disableClickOnCircle) {
-        return {};
-      }
- 
-      // Return props containing the onClick handler
-      return {
-        onClick: (ev: MouseEvent) => {
-          ev.stopPropagation(); // Prevent event bubbling up
-          // Call the provided onClick handler if it exists, passing the item ID
-          if (id && onClick && !slideShowRunning) {
-            onClick(id);
-          }
-        },
-      };
-    }, [id, onClick, slideShowRunning, disableClickOnCircle]); // Dependencies for the click logic
- 
-    /**
-     * Effect to update the isFirstRender flag after the initial render is complete.
-     */
-    useEffect(() => {
-      // This effect runs only once after the initial mount
-      if (isFirstRender.current) {
-        isFirstRender.current = false;
-      }
-    }, []); // Empty dependency array ensures it runs only once
- 
-    // Create an accessible label for the timeline point
-    const timelinePointLabel = useMemo(() => {
-      return (
-        buttonTexts?.timelinePoint ??
-        (active ? 'Active timeline point' : 'Timeline point')
-      );
-    }, [active, buttonTexts]);
- 
-    // Render the timeline point structure
-    return (
-      <TimelinePointWrapper
-        // --- Props passed to styled-component ---
-        width={lineWidth} // Controls the width of the connecting lines (via ::before/::after)
-        bg={theme?.primary} // Background color for the connecting lines
-        $cardLess={cardLess} // Pass cardLess state
-        $isMobile={isMobile} // Pass mobile state
-        // --- Standard React props ---
-        className={className} // 'left' or 'right'
-        data-testid="tree-leaf" // Test ID for the wrapper
-      >
-        {/* Container is a button for accessibility and click handling */}
-        <TimelinePointContainer
-          // --- Props passed to styled-component ---
-          $hide={disableTimelinePoint} // Hide based on global setting
-          // --- Standard React props ---
-          className={`${className} timeline-vertical-circle`} // Combine classes
-          {...clickHandlerProps} // Spread the memoized click handler props
-          ref={circleRef} // Attach ref for position measurement
-          data-testid="tree-leaf-click" // Test ID for the clickable element
-          aria-label={timelinePointLabel} // Accessibility label
-          aria-disabled={disableClickOnCircle ?? disableTimelinePoint} // Disable button if needed
-          disabled={disableClickOnCircle || disableTimelinePoint} // Disable button if needed
-          tabIndex={disableClickOnCircle || disableTimelinePoint ? -1 : 0} // Manage tab order
-        >
-          {/* The visual shape (circle, square, or custom icon) */}
-          <Shape
-            // --- Props passed to styled-component ---
-            theme={theme}
-            dimension={timelinePointDimension} // Controls the size
-            $timelinePointShape={timelinePointShape} // Controls the shape ('circle', 'square')
-            // --- Standard React props ---
-            className={circleClass} // Apply 'active' and 'using-icon' classes
-            aria-hidden="true" // Hide from screen readers as it's decorative
-          >
-            {iconChild}
-          </Shape>
-        </TimelinePointContainer>
-      </TimelinePointWrapper>
-    ) as React.ReactElement;
-  },
-  // Use default shallow comparison for memoization.
-  // The previous custom comparison (prev.active === next.active && prev.isMobile === next.isMobile)
-  // was too restrictive and would prevent updates when other props like iconChild, theme, onClick, etc., changed.
-  // Default shallow comparison is generally safer unless profiling reveals a specific need for a custom function.
-);
- 
-// Set display name for React DevTools
-TimelinePoint.displayName = 'TimelinePoint';
- 
-export { TimelinePoint }; // Export the component
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/timeline-vertical-item.tsx.html b/coverage/lcov-report/components/timeline-vertical/timeline-vertical-item.tsx.html deleted file mode 100644 index f309685a4..000000000 --- a/coverage/lcov-report/components/timeline-vertical/timeline-vertical-item.tsx.html +++ /dev/null @@ -1,991 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical-item.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical-item.tsx

-
- -
- 93.8% - Statements - 197/210 -
- - -
- 50% - Branches - 10/20 -
- - -
- 100% - Functions - 1/1 -
- - -
- 93.8% - Lines - 197/210 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303  -1x -1x -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -26x -26x -  -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -  -  -  -  -26x -26x -  -  -  -  -  -  -26x -26x -  -  -  -  -  -  -26x -  -  -  -  -26x -  -  -  -  -  -26x -22x -22x -22x -22x -22x -22x -  -22x -  -22x -22x -22x -22x -  -22x -22x -22x -22x -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -  -  -  -26x -26x -22x -22x -22x -22x -22x -26x -26x -  -  -  -  -26x -26x -22x -22x -22x -22x -22x -26x -26x -  -  -  -  -  -26x -26x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -22x -  -26x -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -  -  -  -26x -  -22x -26x -  -  -26x -22x -22x -22x -  -  -  -  -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -  -26x -  -  -26x -  -26x -26x -  -26x -  -26x -26x -  -26x -  -  -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -26x -  -26x -26x -26x -26x -26x -26x -26x -26x -  -26x -  -  -26x -26x -  -26x -  -  -1x -  -1x - 
import { VerticalItemModel } from '@models/TimelineVerticalModel';
-import cls from 'classnames';
-import {
-  useCallback,
-  useContext,
-  useMemo,
-  useRef,
-  FunctionComponent,
-  ReactElement,
-} from 'react';
-import { GlobalContext } from '../GlobalContext';
-import TimelineCard from '../timeline-elements/timeline-card-content/timeline-card-content';
-import TimelineItemTitle from '../timeline-elements/timeline-item-title/timeline-card-title';
-import { TimelinePoint } from './timeline-point';
-import {
-  TimelineCardContentWrapper,
-  TimelineTitleWrapper,
-  VerticalItemWrapper,
-} from './timeline-vertical.styles';
- 
-/**
- * Represents a single item (row) in the vertical timeline.
- * It coordinates the display of the title, the central point/icon,
- * and the main content card based on the provided props and global context.
- *
- * @param {VerticalItemModel} props - The properties for the VerticalItem component.
- * @returns {JSX.Element} The rendered VerticalItem component.
- */
-const VerticalItem: FunctionComponent<VerticalItemModel> = (
-  props: VerticalItemModel,
-): ReactElement => {
-  // Ref to the main list item element for calculating position/dimensions
-  const contentRef = useRef<HTMLLIElement>(null);
- 
-  // Destructure all props for cleaner access
-  const {
-    active, // Is this item currently highlighted/active?
-    alternateCards, // Layout mode: alternate card sides?
-    cardDetailedText, // Detailed text content for the card
-    cardSubtitle, // Subtitle/main content for the card
-    cardTitle, // Title specifically for the card (distinct from the timeline item title)
-    url, // URL for navigation, potentially used by the card
-    className, // CSS class for the side ('left' or 'right')
-    contentDetailsChildren, // Custom React nodes for card details area
-    iconChild, // Custom React node for the timeline point/icon
-    hasFocus, // Does the card content have focus (e.g., for slideshow)?
-    id, // Unique ID for the item
-    media, // Media element (image/video) for the card
-    onActive, // Callback when item becomes active (e.g., scrolled into view)
-    onClick, // Callback when the item (or point) is clicked
-    onElapsed, // Callback when media finishes playing (if applicable)
-    slideShowRunning, // Is a slideshow currently active?
-    title, // Title for the timeline item itself (often a date or heading)
-    visible, // Is this item currently visible in the viewport?
-    timelineContent, // Custom React nodes for the main timeline content area
-    items, // Data for nested items (if any)
-    isNested, // Is this item part of a nested structure?
-    nestedCardHeight, // Specific height for nested cards
-  } = props;
- 
-  // Access global settings and theme from context
-  const {
-    cardHeight, // Default card height
-    mode, // Timeline mode (VERTICAL, VERTICAL_ALTERNATING)
-    flipLayout, // Reverse layout order (title/point/card)?
-    timelinePointDimension, // Size of the timeline point
-    lineWidth, // Width of the timeline central line
-    disableClickOnCircle, // Prevent clicks on the timeline point?
-    cardLess, // Mode without cards, only points/titles
-    theme, // Theme object
-    classNames, // Custom class names for sub-elements
-    textOverlay, // Style where text overlays media
-    mediaHeight, // Height for media elements
-    disableInteraction, // Disable all user interactions?
-    isMobile, // Is the view currently mobile?
-  } = useContext(GlobalContext);
- 
-  /**
-   * Callback handler triggered by the TimelinePoint when it becomes active.
-   * Calculates the item's position and notifies the parent.
-   * @param {number} offset - Vertical offset within the point element itself.
-   */
-  const handleOnActive = useCallback(
-    (offset: number) => {
-      if (contentRef.current && onActive) {
-        const { offsetTop, clientHeight } = contentRef.current;
-        // Call the parent's onActive with calculated position data
-        onActive(offsetTop + offset, offsetTop, clientHeight);
-      }
-    },
-    [onActive], // Dependency: only recreate if onActive changes
-  );
- 
-  /**
-   * Handler for the "Read More" action within the card.
-   * Uses a short timeout to likely ensure the DOM has updated (card expanded)
-   * before recalculating the active position.
-   */
-  const handleShowMore = useCallback(() => {
-    // Use timeout to defer execution, allowing potential layout shifts to settle
-    setTimeout(() => {
-      handleOnActive(0); // Recalculate position after content change
-    }, 100); // Small delay (adjust if needed)
-  }, [handleOnActive]); // Dependency: handleOnActive
- 
-  /**
-   * Memoized Timeline Item Title component.
-   * Avoids re-rendering the title if its specific props haven't changed.
-   */
-  const Title = useMemo(() => {
-    return (
-      <TimelineTitleWrapper
-        className={className} // 'left' or 'right'
-        $alternateCards={alternateCards} // Pass prop to styled-component
-        mode={mode}
-        $hide={!title} // Hide wrapper if no title text
-        // Flip title position only in non-alternating vertical mode
-        $flip={!alternateCards && flipLayout}
-      >
-        <TimelineItemTitle
-          title={title as string}
-          active={active && !disableInteraction} // Highlight if active and interaction enabled
-          theme={theme}
-          // Align text based on layout mode
-          align={flipLayout && !alternateCards ? 'left' : 'right'}
-          classString={classNames?.title} // Optional custom class
-        />
-      </TimelineTitleWrapper>
-    );
-  }, [
-    active,
-    title,
-    className,
-    alternateCards,
-    mode,
-    flipLayout,
-    theme,
-    classNames?.title, // Correct dependency
-    disableInteraction, // Added dependency
-  ]);
- 
-  /**
-   * Memoized CSS classes for the main VerticalItemWrapper.
-   * Includes the side ('left'/'right'), visibility, and base class.
-   */
-  const verticalItemClass = useMemo(
-    () =>
-      cls(
-        'vertical-item-row', // Base class
-        { [className]: !!className }, // Add 'left' or 'right' if className is present
-        { visible: visible }, // Add 'visible' class if visible prop is true
-      ),
-    [className, visible],
-  );
- 
-  /**
-   * Memoized CSS classes for the TimelineCardContentWrapper.
-   */
-  const contentClass = useMemo(
-    () =>
-      cls(
-        'card-content-wrapper', // Base class
-        { [className]: !!className }, // Add 'left' or 'right'
-        { visible: visible }, // Add 'visible' class
-      ),
-    [className, visible],
-  );
- 
-  /**
-   * Memoized Timeline Point component.
-   * Avoids re-rendering the point if its specific props haven't changed.
-   */
-  const TimelinePointMemo = useMemo(
-    () => (
-      <TimelinePoint
-        active={active}
-        alternateCards={alternateCards}
-        className={className} // 'left' or 'right'
-        id={id}
-        mode={mode}
-        onActive={handleOnActive} // Pass down the memoized handler
-        onClick={onClick}
-        slideShowRunning={slideShowRunning}
-        iconChild={iconChild} // Custom icon
-        timelinePointDimension={timelinePointDimension}
-        lineWidth={lineWidth}
-        disableClickOnCircle={disableClickOnCircle}
-        cardLess={cardLess}
-        isMobile={isMobile}
-      />
-    ),
-    [
-      // Comprehensive dependency list for memoization
-      active,
-      alternateCards,
-      className,
-      id,
-      mode,
-      handleOnActive, // Use the memoized callback
-      onClick,
-      slideShowRunning,
-      iconChild,
-      timelinePointDimension,
-      lineWidth,
-      disableClickOnCircle,
-      cardLess,
-      isMobile,
-    ],
-  );
- 
-  /**
-   * Determines if the title section should be rendered.
-   * Titles are typically hidden for nested items or on mobile for space.
-   */
-  const canShowTitle = useMemo(() => {
-    // Show title only if it's NOT nested AND NOT mobile view
-    return !isNested && !isMobile;
-  }, [isNested, isMobile]);
- 
-  // Get a readable title for screen readers
-  const accessibleTitle = useMemo(() => {
-    if (typeof title === 'string') {
-      return title;
-    } else if (typeof cardTitle === 'string') {
-      return cardTitle;
-    } else {
-      return 'Timeline item';
-    }
-  }, [title, cardTitle]);
- 
-  // Render the complete timeline item structure
-  return (
-    <VerticalItemWrapper
-      as="li"
-      $alternateCards={alternateCards}
-      $cardHeight={isNested ? nestedCardHeight : cardHeight}
-      $cardLess={cardLess}
-      $isNested={isNested}
-      className={verticalItemClass}
-      data-testid="vertical-item-row"
-      data-item-id={id}
-      key={id}
-      ref={contentRef}
-      theme={theme}
-      aria-current={active ? 'true' : undefined}
-      aria-label={accessibleTitle}
-    >
-      {/* Conditionally render the Title */}
-      {canShowTitle ? Title : null}
- 
-      {/* Wrapper for the card content */}
-      <TimelineCardContentWrapper
-        // --- Props passed to styled-component ---
-        $alternateCards={alternateCards}
-        $noTitle={!title} // Adjust width if title is absent
-        // Flip content position only in non-alternating vertical mode
-        $flip={!alternateCards && flipLayout}
-        // Use media height if text overlay is active, otherwise card height
-        height={textOverlay ? mediaHeight : cardHeight}
-        $isMobile={isMobile}
-        // --- Standard React props ---
-        className={contentClass} // Apply memoized classes
-      >
-        {/* Conditionally render the TimelineCard (only if not cardLess mode) */}
-        {!cardLess ? (
-          <TimelineCard
-            active={active}
-            branchDir={className} // Pass 'left' or 'right'
-            content={cardSubtitle}
-            customContent={contentDetailsChildren}
-            detailedText={cardDetailedText as string | string[]}
-            hasFocus={hasFocus}
-            id={id}
-            media={media}
-            onClick={onClick}
-            onElapsed={onElapsed}
-            onShowMore={handleShowMore} // Pass down the memoized handler
-            slideShowActive={slideShowRunning}
-            theme={theme}
-            url={url}
-            // Flip card content only in non-alternating vertical mode
-            flip={!alternateCards && flipLayout}
-            timelineContent={timelineContent}
-            items={items} // Pass nested items data
-            isNested={isNested}
-            nestedCardHeight={nestedCardHeight}
-            title={cardTitle as string} // Card-specific title
-            cardTitle={title as string} // Item title (might be redundant if cardTitle is used)
-          />
-        ) : null}
-      </TimelineCardContentWrapper>
- 
-      {/* Conditionally render the Timeline Point (hidden for nested items) */}
-      {!isNested ? TimelinePointMemo : null}
-    </VerticalItemWrapper>
-  );
-};
- 
-// Set display name for React DevTools
-VerticalItem.displayName = 'VerticalItem';
- 
-export default VerticalItem;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/timeline-vertical-shape.styles.ts.html b/coverage/lcov-report/components/timeline-vertical/timeline-vertical-shape.styles.ts.html deleted file mode 100644 index 8b3529079..000000000 --- a/coverage/lcov-report/components/timeline-vertical/timeline-vertical-shape.styles.ts.html +++ /dev/null @@ -1,439 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical-shape.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical-shape.styles.ts

-
- -
- 100% - Statements - 16/16 -
- - -
- 73.33% - Branches - 11/15 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 16/16 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import styled from 'styled-components';
-import { zIndex } from '../../styles/z-index';
- 
-/**
- * Props for the TimelinePointWrapper component.
- */
-interface TimelinePointWrapperProps {
-  /** Indicates if the timeline item has no card content, affecting layout. */
-  $cardLess?: boolean;
-  /** Flag for mobile-specific styling adjustments. */
-  $isMobile?: boolean;
-  /** Background color for the timeline line and point elements. */
-  bg?: string;
-  /** Width of the timeline line. Defaults to 4px. */
-  width?: number;
- 
-  theme?: Theme;
-}
- 
-/**
- * Wrapper for the central point/icon on the timeline branch.
- * Handles positioning and the vertical lines connecting points.
- */
-export const TimelinePointWrapper = styled.div<TimelinePointWrapperProps>`
-  /* Flexbox alignment */
-  align-items: center;
-  display: flex;
-  justify-content: center;
-  position: relative;
- 
-  /* Adjust width based on mobile view */
-  width: ${(p) => (p.$isMobile ? '25%' : '10%')};
- 
-  /* Control the horizontal order in VERTICAL_ALTERNATING mode */
-  &.left {
-    order: 2; /* Appears between title and content */
-  }
-  &.right {
-    order: 1; /* Appears first */
-  }
- 
-  /* Top vertical line segment (connecting to the previous item) */
-  &::before {
-    background: ${(p) =>
-      p.bg ?? p.theme?.primary}; /* Use theme primary as fallback */
-    width: ${(p) => (p.width ? `${p.width}px` : '4px')};
-    height: 2rem; /* Fixed height for the connector */
-    position: absolute;
-    content: '';
-    display: block;
-    left: 50%;
-    top: -1rem; /* Position above the point */
-    transform: translateY(-50%) translateX(-50%); /* Center horizontally */
-  }
- 
-  /* Main vertical line segment (extending downwards) */
-  &::after {
-    background: ${(p) =>
-      p.bg ?? p.theme?.primary}; /* Use theme primary as fallback */
-    content: '';
-    display: block;
-    height: 100%; /* Extend full height of the wrapper */
-    left: 50%;
-    position: absolute;
-    width: ${(p) => (p.width ? `${p.width}px` : '4px')};
-    z-index: ${zIndex.timelineLine}; /* Timeline line is at bottom layer */
-    transform: translateX(-50%); /* Center horizontally */
-  }
-`;
- 
-/**
- * Props for the TimelinePointContainer component.
- */
-interface TimelinePointContainerProps {
-  /** Hides the point visually if true. */
-  $hide?: boolean;
-  theme?: Theme;
-}
- 
-/**
- * Container for the actual timeline point/icon (e.g., a circle or custom icon).
- * This is often implemented as a button for accessibility/interactivity.
- */
-export const TimelinePointContainer = styled.button<TimelinePointContainerProps>`
-  position: relative; /* Ensure it's above the ::after pseudo-element */
-  z-index: ${zIndex.timelinePoint}; /* Timeline point sits above the lines but below popovers */
-  visibility: ${(p) =>
-    p.$hide ? 'hidden' : 'visible'}; /* Control visibility */
- 
-  /* Reset button styles */
-  background: none;
-  border: 0;
-  padding: 0; /* Remove default padding */
-  cursor: pointer; /* Indicate interactivity */
-  transition: transform 0.2s ease-in-out; /* Smooth transitions */
- 
-  /* Add subtle hover transform */
-  &:hover:not(:disabled) {
-    transform: scale(1.05);
-  }
- 
-  /* Add press effect */
-  &:active:not(:disabled) {
-    transform: scale(0.95);
-  }
- 
-  /* Add focus styles for accessibility */
-  &:focus-visible {
-    outline: 3px solid ${(p) => p.theme?.primary ?? '#007bff'}; /* Focus ring */
-    outline-offset: 3px;
-  }
- 
-  &:disabled {
-    cursor: default; /* Indicate non-interactive state */
-    opacity: 0.6; /* Visually show disabled state */
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/timeline-vertical.styles.ts.html b/coverage/lcov-report/components/timeline-vertical/timeline-vertical.styles.ts.html deleted file mode 100644 index cc1dce657..000000000 --- a/coverage/lcov-report/components/timeline-vertical/timeline-vertical.styles.ts.html +++ /dev/null @@ -1,757 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical.styles.ts - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical.styles.ts

-
- -
- 86.66% - Statements - 39/45 -
- - -
- 51.85% - Branches - 14/27 -
- - -
- 100% - Functions - 0/0 -
- - -
- 86.66% - Lines - 39/45 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225  -  -1x -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -26x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -1x -  -26x -16x -16x -  -10x -  -  -  -10x -10x -10x -26x -  -  -1x -26x -26x -  -  -  -  -  -  -  -  -1x -  -  -1x -26x -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -22x -  -1x -  -  -1x -22x -12x -1x -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -  -1x -  -1x -  -  - 
import { Theme } from '@models/Theme'; // Assuming Theme model path
-import { TimelineMode } from '@models/TimelineModel'; // Assuming TimelineModel path
-import styled, { css, keyframes } from 'styled-components';
-import { zIndex } from '../../styles/z-index';
- 
-/**
- * Main container for the entire vertical timeline component.
- */
-export const TimelineVerticalWrapper = styled.div`
-  display: flex;
-  flex-direction: column; /* Stack items vertically */
-  width: 100%;
-  padding: 0.25rem; /* Small padding around the timeline */
-  outline: 0; /* Remove default outline */
-  position: relative; /* Establish positioning context */
-`;
- 
-/**
- * Keyframes for the fade-in animation of timeline items.
- */
-const animateVisible = keyframes`
-  from {
-    opacity: 0;
-    visibility: hidden; /* Start hidden */
-  }
-  to {
-    opacity: 1;
-    visibility: visible; /* Fade to visible */
-  }
-`;
- 
-/**
- * Props for the VerticalItemWrapper component.
- */
-interface VerticalItemWrapperProps {
-  /** Controls layout for alternating cards mode. */
-  $alternateCards?: boolean;
-  /** Explicit height for the card content area. */
-  $cardHeight?: number; // Note: Consider if this prop is truly needed or if height should be intrinsic
-  /** Style adjustments for items without card content. */
-  $cardLess?: boolean;
-  /** Indicates if the item is part of a nested timeline structure. */
-  $isNested?: boolean;
-  /** Theme object for styling. */
-  theme?: Theme;
-}
- 
-/**
- * Wrapper for a single timeline item (row), containing title, point, and content.
- * Handles visibility animation and basic layout.
- */
-export const VerticalItemWrapper = styled.li<VerticalItemWrapperProps>`
-  display: flex;
-  position: relative;
-  visibility: hidden; /* Initially hidden for animation */
-  width: 100%;
-  align-items: stretch; /* Stretch children vertically */
-  justify-content: center; /* Center items horizontally */
-  z-index: ${zIndex.timelineCard - 1}; /* Just below the card but above the lines */
-  margin: 1rem 0; /* Vertical spacing between items */
-  list-style: none; /* Remove default list styling */
- 
-  /* Alignment adjustments based on side (used in non-alternating modes) */
-  &.left {
-    margin-right: auto; /* Align left */
-  }
-  &.right {
-    margin-left: auto; /* Align right */
-  }
- 
-  /* Class added when the item should become visible */
-  &.visible {
-    visibility: visible;
-    /* Consider adding animation here if needed, though content animates */
-  }
- 
-  /* Styling for nested timelines */
-  ${(p) =>
-    p.$isNested && // Apply only if $isNested is true
-    css`
-      position: relative;
- 
-      /* Vertical connector line for nested items */
-      &:not(:last-child)::after {
-        content: '';
-        position: absolute;
-        width: 2px; /* Line width */
-        height: 2rem; /* Connector height */
-        background: ${p.theme?.primary ?? '#007bff'};
-        left: 50%;
-        transform: translateX(-50%);
-        bottom: -2rem; /* Position below the item */
-      }
-    `}
-`;
- 
-/**
- * Props for the TimelineCardContentWrapper component.
- */
-interface TimelineCardContentWrapperProps {
-  /** Controls layout for alternating cards mode. */
-  $alternateCards?: boolean;
-  /** Style adjustments for items without card content. */
-  $cardLess?: boolean;
-  /** Reverses the order of elements (content/point/title). */
-  $flip?: boolean;
-  /** Flag for mobile-specific styling adjustments. */
-  $isMobile?: boolean;
-  /** Indicates if the timeline item has no title, affecting layout. */
-  $noTitle?: boolean;
-  /** Explicit height for the card content area. */
-  height?: number; // Consider if this should be min-height or if height is necessary
-}
- 
-/**
- * Wrapper for the main content card of a timeline item.
- * Handles width, alignment, order, and visibility animation based on props.
- */
-export const TimelineCardContentWrapper = styled.div<TimelineCardContentWrapperProps>`
-  visibility: hidden; /* Initially hidden for animation */
-  position: relative;
-  display: flex;
-  align-items: center; /* Vertically center content */
- 
-  /* --- Width Calculation --- */
-  ${(p) => {
-    // Alternating mode: Takes up ~half the space minus the point/title areas
-    if (p.$alternateCards) {
-      return `width: ${p.$isMobile ? '75%;' : '37.5%;'}`;
-    }
-    // No title mode: Takes up most of the space
-    else if (p.$noTitle) {
-      return `width: 95%;`;
-    }
-    // Default vertical mode: Takes up space minus the title area
-    else {
-      return `width: ${p.$isMobile ? '75%;' : '85%;'}`;
-    }
-  }}
- 
-  /* --- Order and Justification (Standard Layout) --- */
-  ${(p) =>
-    !p.$flip && // Apply only if NOT flipped
-    css`
-      &.left {
-        order: 1; /* Content first */
-        justify-content: flex-end; /* Align card content to the right (towards center) */
-      }
-      &.right {
-        order: 3; /* Content last */
-        justify-content: flex-start; /* Align card content to the left (towards center) */
-      }
-    `}
- 
-  /* --- Order and Justification (Flipped Layout) --- */
-  ${(p) =>
-    p.$flip && // Apply only if flipped
-    css`
-      justify-content: flex-end; /* Always align card content to the right */
-      &.left {
-        order: 3; /* Content last */
-      }
-      &.right {
-        order: 1; /* Content first */
-      }
-    `}
- 
-  /* --- Visibility Animation --- */
-  &.visible {
-    visibility: visible;
-    animation: ${animateVisible} 0.25s ease-in; /* Apply fade-in animation */
-  }
-`;
- 
-/**
- * Props for the TimelineTitleWrapper component.
- */
-interface TimelineTitleWrapperProps {
-  /** Controls layout for alternating cards mode. */
-  $alternateCards?: boolean;
-  /** Reverses the order of elements. */
-  $flip?: boolean;
-  /** Hides the title visually. */
-  $hide?: boolean;
-  /** Current timeline mode (e.g., VERTICAL, VERTICAL_ALTERNATING). */
-  mode?: TimelineMode;
-}
- 
-/**
- * Wrapper for the title/date section of a timeline item.
- * Handles width, alignment, and order based on props and mode.
- */
-export const TimelineTitleWrapper = styled.div<TimelineTitleWrapperProps>`
-  align-items: center; /* Vertically center title content */
-  display: ${(p) =>
-    p.$hide && p.mode === 'VERTICAL'
-      ? 'none'
-      : 'flex'}; /* Hide only if $hide and mode is VERTICAL */
- 
-  /* --- Width Calculation --- */
-  width: ${(p) =>
-    p.$alternateCards
-      ? '37.5%' /* Takes up space in alternating mode */
-      : '10%'}; /* Smaller width in standard vertical mode */
- 
-  /* --- Prevent text overflow from affecting layout --- */
-  min-width: 0; /* Allow flex items to shrink below their content size */
-  overflow: hidden; /* Hide overflowing content */
- 
-  /* --- Order and Justification --- */
-  &.left {
-    /* Justification depends on whether layout is flipped */
-    justify-content: ${(p) => (p.$flip ? 'flex-end' : 'flex-start')};
-    /* Order depends on flip status and mode */
-    order: ${(p) => (p.$flip && p.mode === 'VERTICAL_ALTERNATING' ? '1' : '3')};
-  }
- 
-  &.right {
-    /* Justification depends on whether layout is flipped */
-    justify-content: ${(p) => (p.$flip ? 'flex-start' : 'flex-end')};
-    /* Order depends on flip status and mode */
-    order: ${(p) => (p.$flip && p.mode === 'VERTICAL_ALTERNATING' ? '3' : '1')};
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline-vertical/timeline-vertical.tsx.html b/coverage/lcov-report/components/timeline-vertical/timeline-vertical.tsx.html deleted file mode 100644 index 3aafec94d..000000000 --- a/coverage/lcov-report/components/timeline-vertical/timeline-vertical.tsx.html +++ /dev/null @@ -1,523 +0,0 @@ - - - - - - Code coverage report for components/timeline-vertical/timeline-vertical.tsx - - - - - - - - - -
-
-

All files / components/timeline-vertical timeline-vertical.tsx

-
- -
- 88.04% - Statements - 81/92 -
- - -
- 61.53% - Branches - 8/13 -
- - -
- 100% - Functions - 0/0 -
- - -
- 88.04% - Lines - 81/92 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147  -1x -  -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -1x -1x -  -6x -  -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -  -6x -  -  -  -  -  -  -  -  -  -6x -6x -  -  -  -  -  -  -  -6x -6x -  -  -6x -6x -24x -  -  -  -24x -16x -16x -  -8x -8x -8x -  -  -24x -24x -  -  -24x -  -  -24x -24x -  -  -24x -  -  -  -  -  -24x -24x -24x -  -24x -24x -24x -24x -24x -24x -24x -24x -24x -24x -  -24x -24x -24x -24x -  -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -  -  -6x -6x -6x -6x -  -6x -1x -  -  -1x -  -1x - 
import { TimelineVerticalModel } from '@models/TimelineVerticalModel';
-import {
-  useCallback,
-  FunctionComponent,
-  ReactNode,
-  memo,
-  useMemo,
-  ReactElement,
-} from 'react';
-import { useDynamicContext } from '../contexts';
-import TimelineVerticalItem from './timeline-vertical-item';
-import { TimelineVerticalWrapper } from './timeline-vertical.styles';
- 
-/**
- * Renders the main vertical timeline structure.
- * It maps over the provided `items` array and renders a `TimelineVerticalItem`
- * for each, handling layout variations (like alternating cards) and distributing
- * props and callbacks appropriately.
- *
- * @param {TimelineVerticalModel} props - The properties for the TimelineVertical component.
- * @returns {JSX.Element} The rendered TimelineVertical component.
- */
-const TimelineVertical: FunctionComponent<TimelineVerticalModel> = memo(
-  ({
-    // Props with default values
-    alternateCards = true, // Default to alternating card layout on desktop
-    // Callbacks and data props
-    autoScroll, // Function to handle automatic scrolling when an item becomes active
-    contentDetailsChildren, // Optional array of custom nodes for each item's card details
-    hasFocus, // Does the timeline component itself have focus? (Passed down)
-    iconChildren, // Optional custom icon(s) for the timeline points
-    items, // Array of timeline item data objects
-    mode, // Timeline mode (e.g., VERTICAL, VERTICAL_ALTERNATING) - Used by children via context?
-    onClick, // Global click handler for items (passed down)
-    onElapsed, // Global handler for media elapsed events (passed down)
-    onOutlineSelection, // Handler for outline selection (potentially unused here, passed down?)
-    slideShowRunning, // Is a slideshow active? (Passed down)
-    theme, // Theme object (Used by children via context or styled-components)
-    cardLess, // Render without cards? (Passed down)
-    nestedCardHeight, // Specific height for nested cards (Passed down)
-  }: TimelineVerticalModel): ReactElement => {
-    // Access dynamic context for mobile view detection
-    const { isMobile } = useDynamicContext();
- 
-    /**
-     * Callback handler passed to each TimelineVerticalItem's onActive.
-     * When an item becomes active (e.g., scrolls into view), this triggers the autoScroll function
-     * provided via props, allowing the parent component to scroll the timeline if needed.
-     * @param {number} offset - Vertical offset within the active item's point element.
-     * @param {number} wrapperOffset - The offsetTop of the active item's wrapper relative to the scroll parent.
-     * @param {number} height - The clientHeight of the active item's wrapper.
-     */
-    const handleOnActive = useCallback(
-      (offset: number, wrapperOffset: number, height: number) => {
-        // Call the autoScroll prop function if it exists
-        autoScroll?.({
-          contentHeight: height,
-          contentOffset: wrapperOffset,
-          pointOffset: offset,
-        });
-      },
-      [autoScroll], // Dependency: only recreate if autoScroll function changes
-    );
- 
-    // Memoize the items rendering to avoid unnecessary recreations
-    const renderItems = useMemo(() => {
-      return items.map((item, index: number) => {
-        let itemClassName = ''; // CSS class for layout ('left' or 'right')
- 
-        // Determine layout class based on mode and index
-        // In alternating mode on non-mobile views, alternate 'left' and 'right'
-        if (alternateCards && !isMobile) {
-          itemClassName = index % 2 === 0 ? 'left' : 'right';
-        }
-        // Otherwise (non-alternating or mobile), default to 'right'
-        else {
-          itemClassName = 'right';
-        }
- 
-        // Extract specific content details node for this item, if provided
-        const contentDetails: ReactNode | null =
-          (contentDetailsChildren &&
-            Array.isArray(contentDetailsChildren) && // Ensure it's an array
-            contentDetailsChildren[index]) ?? // Get node at the current index
-          null;
- 
-        // Determine the custom icon for this item
-        let customIcon: ReactNode | null = null;
-        if (Array.isArray(iconChildren)) {
-          // If iconChildren is an array, map icon to item by index
-          customIcon = iconChildren[index] ?? null;
-        } else if (iconChildren) {
-          // If iconChildren is a single node, apply it to all items
-          customIcon = iconChildren;
-        }
- 
-        // Render the individual timeline item component
-        return (
-          <TimelineVerticalItem
-            {...item} // Spread all properties from the item data object
-            // --- Pass down calculated or specific props ---
-            alternateCards={alternateCards} // Pass down the alternating mode flag
-            className={itemClassName} // Pass down the calculated 'left'/'right' class
-            contentDetailsChildren={contentDetails} // Pass down the specific content details node
-            iconChild={customIcon} // Pass down the specific icon node
-            hasFocus={hasFocus} // Pass down the focus state
-            index={index} // Pass down the item's index
-            key={item.id ?? `timeline-item-${index}`} // Unique key for React rendering
-            onActive={handleOnActive} // Pass down the memoized active handler
-            onClick={onClick} // Pass down the global click handler
-            onElapsed={onElapsed} // Pass down the global elapsed handler
-            // Removed onShowMore as the handler was empty
-            slideShowRunning={slideShowRunning} // Pass down the slideshow state
-            cardLess={cardLess} // Pass down the cardLess flag
-            nestedCardHeight={nestedCardHeight} // Pass down the nested card height
-          />
-        );
-      });
-    }, [
-      items,
-      isMobile,
-      alternateCards,
-      contentDetailsChildren,
-      iconChildren,
-      hasFocus,
-      handleOnActive,
-      onClick,
-      onElapsed,
-      slideShowRunning,
-      cardLess,
-      nestedCardHeight,
-    ]);
- 
-    // Render the main timeline wrapper
-    return (
-      <TimelineVerticalWrapper as="ul" data-testid="tree-main">
-        {renderItems}
-      </TimelineVerticalWrapper>
-    );
-  },
-);
- 
-// Set display name for React DevTools
-TimelineVertical.displayName = 'TimelineVertical';
- 
-export default TimelineVertical;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/TimelineView.tsx.html b/coverage/lcov-report/components/timeline/TimelineView.tsx.html deleted file mode 100644 index 8c2c5682d..000000000 --- a/coverage/lcov-report/components/timeline/TimelineView.tsx.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - Code coverage report for components/timeline/TimelineView.tsx - - - - - - - - - -
-
-

All files / components/timeline TimelineView.tsx

-
- -
- 100% - Statements - 77/77 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 77/77 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -1081x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -7x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -  -4x -  -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -  -1x - 
import React from 'react';
-import { TimelineMode } from '@models/TimelineModel';
-import TimelineHorizontal from '../timeline-horizontal/timeline-horizontal';
-import TimelineVertical from '../timeline-vertical/timeline-vertical';
-import { Outline, TimelineMain } from './timeline.style';
-import { Scroll } from '@models/TimelineHorizontalModel';
- 
-interface TimelineViewProps {
-  timelineMode: string;
-  activeTimelineItem?: number;
-  autoScroll: (scroll: Partial<Scroll>) => void;
-  contentDetailsChildren?: React.ReactNode;
-  hasFocus: boolean;
-  iconChildren?: React.ReactNode;
-  items: any[]; // Using any to avoid type conflicts
-  handleTimelineItemClick: (itemId?: string) => void;
-  handleTimelineItemElapsed: (itemId?: string) => void;
-  slideShowRunning?: boolean;
-  id: string;
-  theme?: any;
-  lineWidth?: number;
-  onOutlineSelection?: (index: number) => void;
-  nestedCardHeight?: number;
-}
- 
-const TimelineView: React.FC<TimelineViewProps> = ({
-  timelineMode,
-  activeTimelineItem,
-  autoScroll,
-  contentDetailsChildren,
-  hasFocus,
-  iconChildren,
-  items,
-  handleTimelineItemClick,
-  handleTimelineItemElapsed,
-  slideShowRunning,
-  id,
-  theme,
-  lineWidth,
-  onOutlineSelection,
-  nestedCardHeight,
-}) => {
-  // Horizontal Timeline (regular or "all cards" mode)
-  if (timelineMode === 'HORIZONTAL' || timelineMode === 'HORIZONTAL_ALL') {
-    return (
-      <TimelineMain className={timelineMode.toLowerCase()}>
-        <Outline color={theme?.primary} height={lineWidth} />
-        <TimelineHorizontal
-          autoScroll={autoScroll}
-          contentDetailsChildren={contentDetailsChildren}
-          handleItemClick={handleTimelineItemClick}
-          hasFocus={hasFocus}
-          iconChildren={iconChildren}
-          items={items}
-          mode={timelineMode as TimelineMode}
-          onElapsed={handleTimelineItemElapsed}
-          slideShowRunning={slideShowRunning}
-          wrapperId={id}
-          nestedCardHeight={nestedCardHeight}
-        />
-      </TimelineMain>
-    );
-  }
- 
-  // Vertical Alternating Timeline
-  if (timelineMode === 'VERTICAL_ALTERNATING') {
-    return (
-      <TimelineVertical
-        activeTimelineItem={activeTimelineItem}
-        autoScroll={autoScroll}
-        contentDetailsChildren={contentDetailsChildren}
-        hasFocus={hasFocus}
-        iconChildren={iconChildren}
-        items={items}
-        mode={timelineMode as TimelineMode}
-        onClick={handleTimelineItemClick}
-        onElapsed={handleTimelineItemElapsed}
-        onOutlineSelection={onOutlineSelection}
-        slideShowRunning={slideShowRunning}
-        theme={theme}
-        nestedCardHeight={nestedCardHeight}
-      />
-    );
-  }
- 
-  // Vertical Timeline (default)
-  return (
-    <TimelineVertical
-      activeTimelineItem={activeTimelineItem}
-      alternateCards={false}
-      autoScroll={autoScroll}
-      contentDetailsChildren={contentDetailsChildren}
-      hasFocus={hasFocus}
-      iconChildren={iconChildren}
-      items={items}
-      mode={timelineMode as TimelineMode}
-      onClick={handleTimelineItemClick}
-      onElapsed={handleTimelineItemElapsed}
-      onOutlineSelection={onOutlineSelection}
-      slideShowRunning={slideShowRunning}
-      theme={theme}
-      nestedCardHeight={nestedCardHeight}
-    />
-  );
-};
- 
-export default React.memo(TimelineView);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/__tests__/index.html b/coverage/lcov-report/components/timeline/__tests__/index.html deleted file mode 100644 index ca273f5c8..000000000 --- a/coverage/lcov-report/components/timeline/__tests__/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/timeline/__tests__ - - - - - - - - - -
-
-

All files components/timeline/__tests__

-
- -
- 95.02% - Statements - 210/221 -
- - -
- 100% - Branches - 14/14 -
- - -
- 100% - Functions - 0/0 -
- - -
- 95.02% - Lines - 210/221 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
layout-switcher.test.tsx -
-
100%51/51100%3/3100%0/0100%51/51
timeline.test.tsx -
-
93.52%159/170100%11/11100%0/093.52%159/170
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/__tests__/layout-switcher.test.tsx.html b/coverage/lcov-report/components/timeline/__tests__/layout-switcher.test.tsx.html deleted file mode 100644 index 970fd9332..000000000 --- a/coverage/lcov-report/components/timeline/__tests__/layout-switcher.test.tsx.html +++ /dev/null @@ -1,571 +0,0 @@ - - - - - - Code coverage report for components/timeline/__tests__/layout-switcher.test.tsx - - - - - - - - - -
-
-

All files / components/timeline/__tests__ layout-switcher.test.tsx

-
- -
- 100% - Statements - 51/51 -
- - -
- 100% - Branches - 3/3 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 51/51 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -1631x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -1x -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x - 
import { fireEvent } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { customRender, providerProps } from 'src/components/common/test';
-import { vi } from 'vitest';
-import { LayoutSwitcher } from '../timeline-popover-elements';
- 
-describe('LayoutSwitcher Component', () => {
-  const onUpdateTimelineMode = vi.fn();
-  const theme = getDefaultThemeOrDark();
-  const isDarkMode = false;
-  const position = 'top';
- 
-  test('Renders correctly with vertical layout options', () => {
-    const { getByText } = customRender(
-      <LayoutSwitcher
-        onUpdateTimelineMode={onUpdateTimelineMode}
-        theme={theme}
-        mode="VERTICAL"
-        isDarkMode={isDarkMode}
-        position={position}
-        isMobile={false}
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    // Add your assertions here
-    expect(getByText('Change layout')).toBeInTheDocument();
- 
-    fireEvent.click(getByText('Change layout'));
- 
-    expect(getByText('Vertical')).toBeInTheDocument();
-    expect(getByText('Alternating')).toBeInTheDocument();
-  });
- 
-  test('Renders correctly with horizontal layout options', () => {
-    const { getByText } = customRender(
-      <LayoutSwitcher
-        onUpdateTimelineMode={onUpdateTimelineMode}
-        theme={theme}
-        mode="HORIZONTAL"
-        isDarkMode={isDarkMode}
-        position={position}
-        isMobile={false}
-      />,
-      {
-        providerProps: {
-          ...providerProps,
-        },
-      },
-    );
- 
-    // Add your assertions here
-    expect(getByText('Change layout')).toBeInTheDocument();
- 
-    fireEvent.click(getByText('Change layout'));
- 
-    // expect(getByText('Horizontal')).toBeInTheDocument();
-    // expect(getByText('Show all cards')).toBeInTheDocument();
-  });
- 
-  //   test('Handles mode selection correctly', async () => {
-  //     const { getByText } = customRender(
-  //       <LayoutSwitcher
-  //         onUpdateTimelineMode={onUpdateTimelineMode}
-  //         theme={theme}
-  //         mode="VERTICAL"
-  //         isDarkMode={isDarkMode}
-  //         position={position}
-  //         isMobile={false}
-  //       />,
-  //       {
-  //         providerProps: {
-  //           ...providerProps,
-  //         },
-  //       },
-  //     );
- 
-  //     expect(getByText('Change layout')).toBeInTheDocument();
- 
-  //     fireEvent.click(getByText('Change layout'));
- 
-  //     expect(getByText('Default')).toBeInTheDocument();
- 
-  //     // Simulate clicking on a mode option
-  //     fireEvent.click(getByText('Default'));
- 
-  //     await waitFor(() => {
-  //       expect(onUpdateTimelineMode).toHaveBeenCalledWith('VERTICAL');
-  //     });
-  //   });
-  // });
- 
-  // describe('QuickJump Component', () => {
-  //   const onActivateItem = vi.fn();
-  //   const theme = getDefaultThemeOrDark();
-  //   const isDarkMode = false;
-  //   const position = 'top';
-  //   const items = [
-  //     { description: 'Description 1', id: '1', title: 'Item 1' },
-  //     { description: 'Description 2', id: '2', title: 'Item 2' },
-  //   ];
- 
-  //   test('Renders correctly with provided items', () => {
-  //     const { getByText } = customRender(
-  //       <QuickJump
-  //         activeItem={0}
-  //         items={items}
-  //         theme={theme}
-  //         onActivateItem={onActivateItem}
-  //         isDarkMode={isDarkMode}
-  //         position={position}
-  //         isMobile={false}
-  //       />,
-  //       {
-  //         providerProps: {
-  //           ...providerProps,
-  //         },
-  //       },
-  //     );
- 
-  //     // Add your assertions here
- 
-  //     expect(getByText('Jump to')).toBeInTheDocument();
- 
-  //     fireEvent.click(getByText('Jump to'));
- 
-  //     expect(getByText('Item 1')).toBeInTheDocument();
-  //     expect(getByText('Item 2')).toBeInTheDocument();
-  //   });
- 
-  //   test('Handles item activation correctly', () => {
-  //     const { getByText } = customRender(
-  //       <QuickJump
-  //         activeItem={0}
-  //         items={items}
-  //         theme={theme}
-  //         onActivateItem={onActivateItem}
-  //         isDarkMode={isDarkMode}
-  //         position={position}
-  //         isMobile={false}
-  //       />,
-  //       {
-  //         providerProps: {
-  //           ...providerProps,
-  //         },
-  //       },
-  //     );
- 
-  //     expect(getByText('Jump to')).toBeInTheDocument();
- 
-  //     fireEvent.click(getByText('Jump to'));
- 
-  //     // Simulate clicking on an item
-  //     fireEvent.click(getByText('Item 1'));
- 
-  //     expect(onActivateItem).toHaveBeenCalledWith('1');
-  //   });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/__tests__/timeline.test.tsx.html b/coverage/lcov-report/components/timeline/__tests__/timeline.test.tsx.html deleted file mode 100644 index 55547e7c8..000000000 --- a/coverage/lcov-report/components/timeline/__tests__/timeline.test.tsx.html +++ /dev/null @@ -1,847 +0,0 @@ - - - - - - Code coverage report for components/timeline/__tests__/timeline.test.tsx - - - - - - - - - -
-
-

All files / components/timeline/__tests__ timeline.test.tsx

-
- -
- 93.52% - Statements - 159/170 -
- - -
- 100% - Branches - 11/11 -
- - -
- 100% - Functions - 0/0 -
- - -
- 93.52% - Lines - 159/170 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255  -1x -1x -1x -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -1x -5x -5x -5x -5x -  -5x -5x -5x -5x -5x -5x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -  -1x -3x -1x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { TimelineModel } from '@models/TimelineModel';
-import { waitFor } from '@testing-library/react';
-import userEvent from '@testing-library/user-event';
-import { describe, expect, it, vi } from 'vitest';
-import { customRender, providerProps } from '../../common/test';
-import Timeline from '../timeline';
- 
-window.matchMedia = vi.fn().mockImplementation((query) => {
-  return {
-    addEventListener: vi.fn(),
-    addListener: vi.fn(),
-    dispatchEvent: vi.fn(),
-    matches: false,
-    media: query,
-    onchange: null,
-    removeEventListener: vi.fn(),
-    removeListener: vi.fn(),
-  };
-});
- 
-window.IntersectionObserver = vi.fn().mockImplementation(() => {
-  return {
-    disconnect: vi.fn(),
-    observe: vi.fn(),
-    root: null,
- 
-    rootMargin: '',
-    takeRecords: vi.fn(),
-    thresholds: [],
-    unobserve: vi.fn(),
-  } as IntersectionObserver;
-});
- 
-describe('Timeline', () => {
-  const commonProps: TimelineModel = {
-    activeTimelineItem: 0,
-    contentDetailsChildren: null,
-    iconChildren: null,
-    isChild: false,
-    items: [
-      {
-        cardDetailedText: 'Detailed text 1',
-        cardSubtitle: 'Subtitle 1',
-        cardTitle: 'Card 1',
-        id: '1',
-        title: 'Item 1',
-      },
-      {
-        cardDetailedText: 'Detailed text 2',
-        cardSubtitle: 'Subtitle 2',
-        cardTitle: 'Card 2',
-        id: '2',
-        title: 'Item 2',
-      },
-      {
-        cardDetailedText: 'Detailed text 3',
-        cardSubtitle: 'Subtitle 3',
-        cardTitle: 'Card 3',
-        id: '3',
-        title: 'Item 3',
-      },
-      {
-        cardDetailedText: 'Detailed text 4',
-        cardSubtitle: 'Subtitle 4',
-        cardTitle: 'Card 4',
-        id: '4',
-        title: 'Item 4',
-      },
-    ],
-    mode: 'HORIZONTAL',
-    nestedCardHeight: 200,
-    noUniqueId: false,
-    onFirst: vi.fn(),
-    onItemSelected: vi.fn(),
-    onLast: vi.fn(),
-    onNext: vi.fn(),
-    onOutlineSelection: vi.fn(),
-    onPaused: vi.fn(),
-    onPrevious: vi.fn(),
-    onRestartSlideshow: vi.fn(),
-    onTimelineUpdated: vi.fn(),
-    slideShowEnabled: true,
-    slideShowRunning: false,
-    uniqueId: 'timeline-1',
-  };
- 
-  it('should render the timeline with correct items', () => {
-    const { getByText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const item1 = getByText('Item 1');
-    const item2 = getByText('Item 2');
- 
-    expect(item1).toBeInTheDocument();
-    expect(item2).toBeInTheDocument();
-  });
- 
-  //shoulkd render the timeline items correctly when the mode is HORIZONTAL
-  it('should render the timeline items correctly when the mode is HORIZONTAL', () => {
-    const { getByText } = customRender(
-      <Timeline {...commonProps} mode="HORIZONTAL" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const item1 = getByText('Item 1');
-    const item2 = getByText('Item 2');
- 
-    expect(item1).toBeInTheDocument();
-    expect(item2).toBeInTheDocument();
-  });
- 
-  // it('should call onNext', async () => {
-  //   const onNext = vi.fn();
- 
-  //   const { getByLabelText, getByText } = customRender(
-  //     <Timeline {...commonProps} mode="VERTICAL_ALTERNATING" onNext={onNext} />,
-  //     {
-  //       providerProps: {
-  //         ...providerProps,
-  //       },
-  //     },
-  //   );
- 
-  //   const nextButton = getByLabelText('next');
- 
-  //   expect(nextButton).toBeInTheDocument();
- 
-  //   fireEvent.click(nextButton);
- 
-  //   await waitFor(
-  //     () => {
-  //       expect(onNext).toHaveBeenCalled();
-  //       // expect(nextButton).toHaveAttribute('aria-disabled', 'false');
-  //     },
-  //     {
-  //       timeout: 2000,
-  //     },
-  //   );
-  // });
- 
-  //should call onPrevious after next button is clicked
-  it('should call onPrevious after next button is clicked', async () => {
-    const { getByLabelText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL_ALTERNATING" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const nextButton = getByLabelText('next');
-    const previousButton = getByLabelText('previous');
- 
-    expect(previousButton).toBeInTheDocument();
-    expect(nextButton).toBeInTheDocument();
- 
-    userEvent.click(nextButton);
- 
-    await waitFor(() => {
-      expect(nextButton).toHaveAttribute('aria-disabled', 'false');
-    });
-  });
- 
-  // should call onLast when last button is clicked
-  it('should call onLast and onFirst when last button is clicked', async () => {
-    const { getByLabelText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL_ALTERNATING" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const lastButton = getByLabelText('last');
-    const firstButton = getByLabelText('first');
- 
-    userEvent.click(lastButton);
- 
-    await waitFor(() => {
-      expect(commonProps.onLast).toHaveBeenCalled();
-    });
-  });
- 
-  //should call onFirst when first button is clicked
-  // it('should call onFirst when first button is clicked', async () => {
-  //   const { getByLabelText } = customRender(
-  //     <Timeline
-  //       {...commonProps}
-  //       mode="VERTICAL_ALTERNATING"
-  //       activeTimelineItem={1}
-  //     />,
-  //     {
-  //       providerProps,
-  //     },
-  //   );
- 
-  //   const firstButton = getByLabelText('first');
- 
-  //   userEvent.click(firstButton);
- 
-  //   await waitFor(() => {
-  //     expect(commonProps.onFirst).toHaveBeenCalled();
-  //   });
-  // });
- 
-  // //should call onLast when last button is clicked
-  it('should call onLast when last button is clicked', () => {
-    const { getByLabelText } = customRender(
-      <Timeline
-        {...commonProps}
-        mode="VERTICAL_ALTERNATING"
-        activeTimelineItem={0}
-      />,
-      {
-        providerProps,
-      },
-    );
- 
-    const lastButton = getByLabelText('last');
- 
-    expect(lastButton).toBeInTheDocument();
- 
-    userEvent.click(lastButton);
- 
-    expect(commonProps.onLast).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should call onItemSelected when an item is clicked', async () => {
-    const { getByText } = customRender(
-      <Timeline {...commonProps} mode="VERTICAL" />,
-      {
-        providerProps,
-      },
-    );
- 
-    const item1 = getByText('Item 1');
- 
-    userEvent.click(item1);
- 
-    await waitFor(() => {
-      expect(commonProps.onItemSelected).toHaveBeenCalledWith({
-        cardDetailedText: 'Detailed text 1',
-        cardSubtitle: 'Subtitle 1',
-        cardTitle: 'Card 1',
-        index: 0,
-        title: 'Item 1',
-      });
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/index.html b/coverage/lcov-report/components/timeline/index.html deleted file mode 100644 index 69c5eb92c..000000000 --- a/coverage/lcov-report/components/timeline/index.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - Code coverage report for components/timeline - - - - - - - - - -
-
-

All files components/timeline

-
- -
- 78.48% - Statements - 693/883 -
- - -
- 64.76% - Branches - 68/105 -
- - -
- 44.82% - Functions - 13/29 -
- - -
- 78.48% - Lines - 693/883 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
TimelineView.tsx -
-
100%77/77100%6/6100%1/1100%77/77
timeline-popover-elements.tsx -
-
77.43%127/164100%12/1222.22%2/977.43%127/164
timeline-popover.model.ts -
-
0%0/00%1/10%1/10%0/0
timeline-toolbar.model.ts -
-
0%0/00%1/10%1/10%0/0
timeline-toolbar.tsx -
-
64.94%176/27142.3%11/2622.22%2/964.94%176/271
timeline.style.ts -
-
89.09%49/5573.52%25/34100%4/489.09%49/55
timeline.style.tsx -
-
0%0/290%0/10%0/10%0/29
timeline.tsx -
-
91.98%264/28750%12/2466.66%2/391.98%264/287
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/timeline-popover-elements.tsx.html b/coverage/lcov-report/components/timeline/timeline-popover-elements.tsx.html deleted file mode 100644 index f3805006a..000000000 --- a/coverage/lcov-report/components/timeline/timeline-popover-elements.tsx.html +++ /dev/null @@ -1,664 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-popover-elements.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline-popover-elements.tsx

-
- -
- 77.43% - Statements - 127/164 -
- - -
- 100% - Branches - 12/12 -
- - -
- 22.22% - Functions - 2/9 -
- - -
- 77.43% - Lines - 127/164 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -1941x -1x -1x -1x -1x -  -  -  -  -  -  -1x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -  -2x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -2x -  -  -2x -2x -2x -2x -2x -2x -  -  -2x -2x -2x -2x -2x -2x -2x -  -  -2x -2x -2x -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -2x -  -2x -2x -2x -1x -1x -  -2x -2x -2x -2x -  -2x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -  -7x -7x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -7x -7x -  -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -  -7x -  -  - 
import { FunctionComponent, useMemo } from 'react';
-import { useStableContext, useDynamicContext } from '../contexts';
-import { List } from '../elements/list/list';
-import PopOver from '../elements/popover';
-import { ArrowDownIcon, LayoutIcon, ParaIcon } from '../icons';
-import {
-  ChangeDensityProp,
-  LayoutSwitcherProp,
-  QuickJumpProp,
-} from './timeline-popover.model';
- 
-const LayoutSwitcher: FunctionComponent<LayoutSwitcherProp> = ({
-  onUpdateTimelineMode,
-  theme,
-  mode,
-  isDarkMode,
-  position,
-  isMobile,
-}: LayoutSwitcherProp) => {
-  const { memoizedButtonTexts: buttonTexts } = useStableContext();
-  const { horizontalAll: showAllCardsHorizontal } = useDynamicContext();
- 
-  const LayoutIconMemo = useMemo(() => <LayoutIcon />, []);
- 
-  const activeTimelineMode = useMemo(
-    () => mode,
-    [showAllCardsHorizontal, mode],
-  );
- 
-  const layoutOptions = useMemo(
-    () => ({
-      alternating: buttonTexts?.changeLayoutOptions.alternating,
-      horizontal: buttonTexts?.changeLayoutOptions.horizontal,
-      horizontal_all: buttonTexts?.changeLayoutOptions.horizontal_all,
-      vertical: buttonTexts?.changeLayoutOptions.vertical,
-    }),
-    [],
-  );
- 
-  const verticalItems = useMemo(
-    () => [
-      {
-        description: layoutOptions.vertical.helpText,
-        id: 'VERTICAL',
-        onSelect: () => onUpdateTimelineMode('VERTICAL'),
-        selected: activeTimelineMode === 'VERTICAL',
-        title: layoutOptions.vertical.text,
-      },
-      {
-        description: layoutOptions.alternating.helpText,
-        id: 'VERTICAL_ALTERNATING',
-        onSelect: () => onUpdateTimelineMode('VERTICAL_ALTERNATING'),
-        selected: activeTimelineMode === 'VERTICAL_ALTERNATING',
-        title: layoutOptions.alternating.text,
-      },
-    ],
-    [activeTimelineMode],
-  );
- 
-  // horizontal list OF options when the mode is `HORIZONTAL`
-  const horizontalItems = useMemo(
-    () => [
-      {
-        description: layoutOptions.horizontal.helpText,
-        id: 'HORIZONTAL',
-        onSelect: () => {
-          onUpdateTimelineMode('HORIZONTAL');
-        },
-        selected: activeTimelineMode === 'HORIZONTAL',
-        title: layoutOptions.horizontal.text,
-      },
-      {
-        description: layoutOptions.horizontal_all.helpText,
-        id: 'HORIZONTAL_ALL',
-        onSelect: () => {
-          onUpdateTimelineMode('HORIZONTAL_ALL');
-        },
-        selected: activeTimelineMode === 'HORIZONTAL_ALL',
-        title: layoutOptions.horizontal.text,
-      },
-    ],
-    [activeTimelineMode],
-  );
- 
-  return (
-    <PopOver
-      placeholder={buttonTexts.changeLayout}
-      position={position}
-      theme={theme}
-      isDarkMode={isDarkMode}
-      icon={LayoutIconMemo}
-      $isMobile={isMobile}
-    >
-      <List
-        items={
-          mode === 'HORIZONTAL' || mode === 'HORIZONTAL_ALL'
-            ? horizontalItems
-            : verticalItems
-        }
-        theme={theme}
-        multiSelectable
-      />
-    </PopOver>
-  );
-};
- 
-const QuickJump: FunctionComponent<QuickJumpProp> = ({
-  activeItem,
-  items,
-  theme,
-  onActivateItem,
-  isDarkMode,
-  position,
-  isMobile,
-}: QuickJumpProp) => {
-  const { memoizedButtonTexts: buttonTexts } = useStableContext();
- 
-  const ArrowDownIconMemo = useMemo(() => <ArrowDownIcon />, []);
- 
-  return (
-    <PopOver
-      placeholder={buttonTexts.jumpTo}
-      position={position}
-      theme={theme}
-      width={400}
-      isDarkMode={isDarkMode}
-      $isMobile={isMobile}
-      icon={ArrowDownIconMemo}
-    >
-      <List
-        items={items.map((item, index) => ({
-          active: index === activeItem,
-          description: item.description,
-          id: item.id,
-          label: item.title,
-          onSelect: () => {},
-          title: item.title ?? `Item ${index + 1}`,
-        }))}
-        theme={theme}
-        onClick={onActivateItem}
-      />
-    </PopOver>
-  );
-};
- 
-const ChangeDensity: FunctionComponent<ChangeDensityProp> = ({
-  onChange,
-  selectedDensity,
-  theme,
-  isDarkMode,
-  position,
-  isMobile,
-}) => {
-  const { memoizedButtonTexts: buttonTexts } = useStableContext();
- 
-  const ParaIconMemo = useMemo(() => <ParaIcon />, []);
- 
-  const items = useMemo(
-    () => [
-      {
-        description: 'Show less text',
-        id: 'LOW',
-        onSelect: () => onChange('LOW'),
-        selected: selectedDensity === 'LOW',
-        title: 'Low',
-      },
-      {
-        description: 'Show more text',
-        id: 'HIGH',
-        onSelect: () => onChange('HIGH'),
-        selected: selectedDensity === 'HIGH',
-        title: 'High',
-      },
-    ],
-    [selectedDensity],
-  );
- 
-  return (
-    <PopOver
-      placeholder={buttonTexts.changeDensity}
-      theme={theme}
-      isDarkMode={isDarkMode}
-      position={position}
-      $isMobile={isMobile}
-      width={300}
-      icon={ParaIconMemo}
-    >
-      <List items={items} theme={theme} multiSelectable />
-    </PopOver>
-  );
-};
- 
-export { ChangeDensity, LayoutSwitcher, QuickJump };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/timeline-popover.model.ts.html b/coverage/lcov-report/components/timeline/timeline-popover.model.ts.html deleted file mode 100644 index 6774a9765..000000000 --- a/coverage/lcov-report/components/timeline/timeline-popover.model.ts.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-popover.model.ts - - - - - - - - - -
-
-

All files / components/timeline timeline-popover.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TextDensity, TimelineMode } from '@models/TimelineModel';
-import { ListItemModel } from '../elements/list/list.model';
- 
-export type CommonProps = {
-  isDarkMode: boolean;
-  isMobile: boolean;
-  position: 'top' | 'bottom';
-  theme: Theme;
-};
- 
-export type LayoutSwitcherProp = {
-  initialTimelineMode?: TimelineMode | 'HORIZONTAL_ALL';
-  mode?: TimelineMode;
-  onUpdateTimelineMode: (s: string) => void;
-} & CommonProps;
- 
-export type QuickJumpProp = {
-  activeItem: number;
-  items: ListItemModel[];
-  onActivateItem: (id: string) => void;
-} & CommonProps;
- 
-export type ChangeDensityProp = {
-  onChange: (value: TextDensity) => void;
-  selectedDensity: TextDensity;
-} & CommonProps;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/timeline-toolbar.model.ts.html b/coverage/lcov-report/components/timeline/timeline-toolbar.model.ts.html deleted file mode 100644 index 3ea794ad0..000000000 --- a/coverage/lcov-report/components/timeline/timeline-toolbar.model.ts.html +++ /dev/null @@ -1,205 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-toolbar.model.ts - - - - - - - - - -
-
-

All files / components/timeline timeline-toolbar.model.ts

-
- -
- 0% - Statements - 0/0 -
- - -
- 0% - Branches - 1/1 -
- - -
- 0% - Functions - 1/1 -
- - -
- 0% - Lines - 0/0 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import {
-  TextDensity,
-  TimelineMode,
-  TimelineModel,
-  TimelineProps,
-} from '@models/TimelineModel';
-import { RefObject } from 'react';
- 
-export type TimelineToolbarProps = Pick<
-  TimelineModel,
-  | 'activeTimelineItem'
-  | 'slideShowEnabled'
-  | 'slideShowRunning'
-  | 'onRestartSlideshow'
-  | 'onNext'
-  | 'onPrevious'
-  | 'onPaused'
-  | 'onFirst'
-  | 'onLast'
-  | 'items'
-  | 'mode'
-> & {
-  id: string;
-  onActivateTimelineItem: (id: string) => void;
-  onUpdateTextContentDensity: (value: TextDensity) => void;
-  onUpdateTimelineMode: (mode: TimelineMode) => void;
-  toggleDarkMode: () => void;
-  totalItems: number;
- 
-  // Search related props
-  searchQuery: string;
-  onSearchChange: (query: string) => void;
-  onClearSearch: () => void;
-  onNextMatch: () => void;
-  onPreviousMatch: () => void;
-  totalMatches: number;
-  currentMatchIndex: number; // 0-based index
-  onSearchKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
-  searchInputRef?: RefObject<HTMLInputElement>; // Ref for the search input
-} & Pick<TimelineProps, 'darkMode' | 'flipLayout'>;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/timeline-toolbar.tsx.html b/coverage/lcov-report/components/timeline/timeline-toolbar.tsx.html deleted file mode 100644 index 38ab29fd5..000000000 --- a/coverage/lcov-report/components/timeline/timeline-toolbar.tsx.html +++ /dev/null @@ -1,1087 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline-toolbar.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline-toolbar.tsx

-
- -
- 64.94% - Statements - 176/271 -
- - -
- 42.3% - Branches - 11/26 -
- - -
- 22.22% - Functions - 2/9 -
- - -
- 64.94% - Lines - 176/271 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -48x -48x -48x -  -  -48x -48x -48x -48x -  -  -  -  -  -  -  -1x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -7x -7x -7x -7x -7x -  -7x -7x -7x -7x -7x -7x -  -  -7x -6x -24x -24x -24x -24x -6x -7x -  -  -7x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -6x -7x -  -  -7x -6x -  -  -6x -7x -  -  -7x -6x -  -  -6x -7x -  -7x -6x -7x -  -7x -6x -7x -  -7x -  -  -  -  -7x -  -  -  -  -  -  -  -  -7x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -7x -7x -7x -7x -  -  -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -7x -  -  -  -  -7x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -7x -7x -7x -7x -7x -  -7x -7x -  -  -  -  -  -  -  -  -  -7x -7x -7x -7x -  -  -  -  -  -  -  -  -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -7x -  -7x -  -  -  - 
// Import necessary dependencies
-import React, { FunctionComponent, useMemo } from 'react';
-import { useStableContext, useDynamicContext } from '../contexts';
-import Controls from '../timeline-elements/timeline-control/timeline-control';
-import { TimelineNavButton } from '../timeline-elements/timeline-control/timeline-control.styles';
-import { ChevronLeft, ChevronRight, CloseIcon } from '../icons';
-import { Toolbar } from '../toolbar';
-import {
-  ChangeDensity,
-  LayoutSwitcher,
-  QuickJump,
-} from './timeline-popover-elements';
-import { TimelineToolbarProps } from './timeline-toolbar.model';
-import {
-  ExtraControls,
-  SearchInput,
-  SearchWrapper,
-  SearchInfo,
-} from './timeline.style';
- 
-// Helper function to convert ReactNode to string safely
-const getTextFromNode = (
-  content: React.ReactNode | string | undefined,
-): string => {
-  if (content === null || content === undefined) {
-    return '';
-  }
-  if (typeof content === 'string') {
-    return content;
-  }
-  if (typeof content === 'number' || typeof content === 'boolean') {
-    return String(content);
-  }
-  // For any other ReactNode, return empty string
-  return '';
-};
- 
-// Define the TimelineToolbar component
-const TimelineToolbar: FunctionComponent<TimelineToolbarProps> = ({
-  activeTimelineItem,
-  slideShowEnabled,
-  slideShowRunning,
-  flipLayout,
-  toggleDarkMode,
-  onPaused,
-  onFirst,
-  onLast,
-  onNext,
-  onPrevious,
-  onRestartSlideshow,
-  totalItems,
-  items = [],
-  id,
-  onActivateTimelineItem,
-  onUpdateTimelineMode,
-  onUpdateTextContentDensity,
-  mode,
-  searchQuery,
-  onSearchChange,
-  onClearSearch,
-  onNextMatch,
-  onPreviousMatch,
-  totalMatches,
-  currentMatchIndex,
-  onSearchKeyDown,
-  searchInputRef,
-}: TimelineToolbarProps) => {
-  // Access the stable and dynamic contexts
-  const {
-    cardLess,
-    enableQuickJump,
-    toolbarPosition,
-    enableLayoutSwitch,
-    memoizedButtonTexts: buttonTexts,
-  } = useStableContext();
- 
-  const {
-    memoizedTheme: theme,
-    isDarkMode: darkMode,
-    textContentDensity: textDensity,
-    isMobile,
-  } = useDynamicContext();
- 
-  // Prepare QuickJump items with proper string conversions
-  const quickJumpItems = useMemo(() => {
-    return items.map((item) => ({
-      id: item.id ?? '',
-      title: getTextFromNode(item.title),
-      description: getTextFromNode(item.cardSubtitle),
-      active: item.active,
-    }));
-  }, [items]);
- 
-  // Define the toolbar items
-  const toolbarItems = useMemo(() => {
-    return [
-      {
-        id: 'timeline-controls',
-        label: 'Timeline Controls',
-        name: 'timeline_control',
-        onSelect: () => {},
-      },
-      {
-        id: 'timeline-popover',
-        label: 'timeline_popover',
-        name: 'popover',
-        onSelect: () => {},
-      },
-      {
-        id: 'layout-popover',
-        label: 'layout_popover',
-        name: 'popover',
-        onSelect: () => {},
-      },
-      {
-        id: 'change-density',
-        label: 'change_density',
-        name: 'changeDensity',
-        onSelect: () => {},
-      },
-    ];
-  }, []);
- 
-  // Define methods to determine button state
-  const isLeftDisabled = useMemo(() => {
-    if (flipLayout) {
-      return activeTimelineItem === totalItems - 1;
-    }
-    return activeTimelineItem === 0;
-  }, [flipLayout, activeTimelineItem, totalItems]);
- 
-  // Determine if the right arrow should be disabled
-  const isRightDisabled = useMemo(() => {
-    if (flipLayout) {
-      return activeTimelineItem === 0;
-    }
-    return activeTimelineItem === totalItems - 1;
-  }, [flipLayout, activeTimelineItem, totalItems]);
- 
-  const hideExtraControls = useMemo(() => {
-    return cardLess || slideShowRunning;
-  }, [cardLess, slideShowRunning]);
- 
-  const canShowDensity = useMemo(() => {
-    return items.every((item) => item.cardDetailedText);
-  }, []);
- 
-  const handleInputChange = (event: React.ChangeEvent<HTMLInputElement>) => {
-    onSearchChange(event.target.value);
-  };
- 
-  // Handle clear search and focus the input
-  const handleClearSearch = () => {
-    onClearSearch();
-    // Focus the search input after clearing
-    setTimeout(() => {
-      searchInputRef?.current?.focus();
-    }, 0);
-  };
- 
-  // Add KeyDown handler for Enter key navigation
-  const handleSearchKeyDown = (
-    event: React.KeyboardEvent<HTMLInputElement>,
-  ) => {
-    if (event.key === 'Enter' && totalMatches > 0) {
-      event.preventDefault(); // Prevent potential form submission
- 
-      // Save the current search query before navigation
-      const currentQuery = searchQuery;
- 
-      // Navigate to next match
-      if (onSearchKeyDown) {
-        // Use the provided handler if available
-        onSearchKeyDown(event);
-      } else {
-        onNextMatch(); // Use default navigation
-      }
- 
-      // Re-focus the search input after a short delay
-      // This allows the navigation to complete first
-      setTimeout(() => {
-        if (searchInputRef?.current) {
-          searchInputRef.current.focus();
- 
-          // If the value has been cleared, restore it
-          if (searchInputRef.current.value === '' && currentQuery) {
-            // This is a backup to ensure the search query persists
-            // The main handling should be in the parent component
-            onSearchChange(currentQuery);
-          }
- 
-          // Ensure the cursor is at the end of the text
-          const length = searchInputRef.current.value.length;
-          searchInputRef.current.setSelectionRange(length, length);
-        }
-      }, 50);
-    }
-  };
- 
-  // Disable search navigation if no matches or slideshow running
-  const disableSearchNav = useMemo(
-    () => totalMatches === 0 || slideShowRunning,
-    [totalMatches, slideShowRunning],
-  );
- 
-  // Render the TimelineToolbar component
-  return (
-    <Toolbar items={toolbarItems} theme={theme}>
-      <Controls
-        disableLeft={isLeftDisabled}
-        disableRight={isRightDisabled}
-        id={id}
-        onFirst={onFirst}
-        onLast={onLast}
-        onNext={onNext}
-        onPrevious={onPrevious}
-        onReplay={onRestartSlideshow}
-        slideShowEnabled={slideShowEnabled}
-        slideShowRunning={slideShowRunning}
-        isDark={darkMode}
-        onToggleDarkMode={toggleDarkMode}
-        onPaused={onPaused}
-        activeTimelineItem={activeTimelineItem}
-        totalItems={totalItems}
-      />
-      <SearchWrapper theme={theme}>
-        <SearchInput
-          ref={searchInputRef}
-          type="search"
-          placeholder={buttonTexts?.searchPlaceholder ?? 'Search Timeline'}
-          value={searchQuery}
-          onChange={handleInputChange}
-          onKeyDown={handleSearchKeyDown}
-          aria-label={buttonTexts?.searchAriaLabel ?? 'Search timeline content'}
-          disabled={slideShowRunning}
-        />
-        {searchQuery && (
-          <TimelineNavButton
-            onClick={handleClearSearch}
-            title={buttonTexts?.clearSearch ?? 'Clear Search'}
-            aria-label={buttonTexts?.clearSearch ?? 'Clear Search'}
-            theme={theme}
-            style={{
-              height: '24px',
-              width: '24px',
-              marginRight: '0.5rem',
-            }}
-          >
-            <CloseIcon />
-          </TimelineNavButton>
-        )}
-        {totalMatches > 0 && (
-          <SearchInfo theme={theme}>
-            {`${currentMatchIndex + 1} / ${totalMatches}`}
-          </SearchInfo>
-        )}
-        {searchQuery && (
-          <>
-            <div className="timeline-nav-wrapper">
-              <TimelineNavButton
-                onClick={onPreviousMatch}
-                title={buttonTexts?.previousMatch ?? 'Previous Match'}
-                aria-label={buttonTexts?.previousMatch ?? 'Previous Match'}
-                disabled={disableSearchNav}
-                theme={theme}
-                style={{ height: '24px', width: '24px' }}
-              >
-                <ChevronLeft />
-              </TimelineNavButton>
-            </div>
-            <div className="timeline-nav-wrapper">
-              <TimelineNavButton
-                onClick={onNextMatch}
-                title={buttonTexts?.nextMatch ?? 'Next Match'}
-                aria-label={buttonTexts?.nextMatch ?? 'Next Match'}
-                disabled={disableSearchNav}
-                theme={theme}
-                style={{ height: '24px', width: '24px' }}
-              >
-                <ChevronRight />
-              </TimelineNavButton>
-            </div>
-          </>
-        )}
-      </SearchWrapper>
-      <ExtraControls
-        $hide={hideExtraControls}
-        $slideShowRunning={slideShowRunning}
-        key="timeline-extra-controls"
-      >
-        <div className="control-wrapper" key="quick-jump">
-          {enableQuickJump ? (
-            <QuickJump
-              activeItem={activeTimelineItem}
-              isDarkMode={darkMode}
-              items={quickJumpItems}
-              onActivateItem={onActivateTimelineItem}
-              theme={theme}
-              position={toolbarPosition}
-              isMobile={isMobile}
-            />
-          ) : null}
-        </div>
-        <div className="control-wrapper" key="layout-switcher">
-          {!cardLess && enableLayoutSwitch ? (
-            <LayoutSwitcher
-              isDarkMode={darkMode}
-              theme={theme}
-              onUpdateTimelineMode={onUpdateTimelineMode}
-              mode={mode}
-              position={toolbarPosition}
-              isMobile={isMobile}
-            />
-          ) : null}
-        </div>
-        {canShowDensity ? (
-          <div className="control-wrapper" key="change-density">
-            <ChangeDensity
-              isDarkMode={darkMode}
-              theme={theme}
-              onChange={onUpdateTextContentDensity}
-              position={toolbarPosition}
-              selectedDensity={textDensity}
-              isMobile={isMobile}
-            ></ChangeDensity>
-          </div>
-        ) : null}{' '}
-      </ExtraControls>
-    </Toolbar>
-  );
-};
- 
-// Export the TimelineToolbar component
-export { TimelineToolbar };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/timeline.style.ts.html b/coverage/lcov-report/components/timeline/timeline.style.ts.html deleted file mode 100644 index a1ff41493..000000000 --- a/coverage/lcov-report/components/timeline/timeline.style.ts.html +++ /dev/null @@ -1,805 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline.style.ts - - - - - - - - - -
-
-

All files / components/timeline timeline.style.ts

-
- -
- 89.09% - Statements - 49/55 -
- - -
- 73.52% - Branches - 25/34 -
- - -
- 100% - Functions - 4/4 -
- - -
- 89.09% - Lines - 49/55 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241  -  -1x -1x -1x -  -  -1x -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -1x -1x -1x -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -1x -1x -  -1x -  -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -  -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -1x -1x -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -  -  -  -1x -  -  -  -  -  -1x -  -  -1x -  -  -1x -  -  -  -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -1x -  -  -  -  -1x -  -  -  -  -  -  -  -  -1x -7x -  -7x -7x -1x -1x -  -  -  -  -  -  -  -  -1x -  -1x -  -  -  -  - 
import { Theme } from '@models/Theme';
-import { TimelineMode } from '@models/TimelineModel';
-import styled, { css } from 'styled-components';
-import { zIndex } from '../../styles/z-index';
-import { ScrollBar } from '../common/styles';
- 
-// CSS transform and animation fallbacks
-const getTransform = (transform?: string) => transform || 'none';
- 
-const transitionMixin = css`
-  -webkit-transition: all 0.2s ease;
-  -moz-transition: all 0.2s ease;
-  -ms-transition: all 0.2s ease;
-  -o-transition: all 0.2s ease;
-  transition: all 0.2s ease;
-`;
- 
-// Timeline wrapper with improved cross-browser support
-export const Wrapper = styled.div<{
-  cardPositionHorizontal?: 'TOP' | 'BOTTOM';
-  theme?: Theme;
-  $translate?: string;
-}>`
-  -webkit-transform: ${props => getTransform(props.$translate)};
-  -moz-transform: ${props => getTransform(props.$translate)};
-  -ms-transform: ${props => getTransform(props.$translate)};
-  transform: ${props => getTransform(props.$translate)};
-  ${transitionMixin}
-  display: flex;
-  flex-direction: column;
-  /* cannot remove this */
-  height: 100%;
-  z-index: ${zIndex.timelineCard - 2}; /* Base z-index for timeline */
- 
-  &:focus {
-    outline: 0;
-  }
- 
-  overflow: hidden;
-  position: relative;
-  width: 100%;
- 
-  &.horizontal {
-    justify-content: flex-start;
-  }
- 
-  &.js-focus-visible :focus:not(.focus-visible) {
-    /* outline: 0; */
-  }
- 
-  &.js-focus-visible .focus-visible {
-    outline: 2px solid #528deb;
-  }
-`;
- 
-export const TimelineMainWrapper = styled.div<{
-  $scrollable?: boolean | { scrollbar: boolean };
-  mode?: TimelineMode;
-  position?: 'top' | 'bottom';
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  display: flex;
-  justify-content: center;
-  overflow-y: auto;
-  overflow-x: hidden;
-  overscroll-behavior: contain;
-  ${(p) => (p.mode === 'HORIZONTAL' ? 'position: relative' : '')};
-  scroll-behavior: smooth;
-  width: 100%;
-  background-color: ${(p) => p.theme?.timelineBgColor || 'transparent'};
-  /* order: ${(p) => (p.position === 'top' ? 1 : 0)}; */
-  background: transparent;
-  F ${ScrollBar} &.horizontal {
-    min-height: 150px;
-  }
- 
-  padding: ${({ $scrollable }) => (!$scrollable ? '0 1rem 0' : '')};
-`;
- 
-export const TimelineMain = styled.div`
-  position: absolute;
-  top: 50%;
-  left: 0;
-  display: flex;
-  align-items: center;
-  transition: all 0.2s ease;
-  transform: translate(0, -50%);
- 
-  &.vertical {
-    align-items: flex-start;
-    justify-content: flex-start;
-    width: 100%;
-    height: 100%;
-  }
-`;
- 
-export const Outline = styled.div<{ color?: string; height?: number }>`
-  position: absolute;
-  right: 0;
-  left: 0;
-  width: 100%;
-  height: ${(p) => `${p.height}px`};
-  margin-right: auto;
-  margin-left: auto;
-  background: ${(p) => p.color};
-`;
- 
-export const TimelineControlContainer = styled.div<{
-  active?: boolean;
-  mode?: TimelineMode;
-}>`
-  display: flex;
-  align-items: center;
-  justify-content: center;
-  min-height: 3rem;
- 
-  filter: ${(p) => {
-    if (p.active) {
-      return `opacity(1);`;
-    } else {
-      return `opacity(0.9);`;
-    }
-  }};
- 
-  &.hide {
-    visibility: hidden;
-  }
- 
-  &.show {
-    visibility: visible;
-  }
-`;
- 
-export const TimelineContentRender = styled.div<{ $showAllCards?: boolean }>`
-  display: flex;
-  align-items: flex-start;
-  justify-content: ${(p) => (p.$showAllCards ? 'flex-start' : 'center')};
-  width: 98%;
-  margin-right: auto;
-  margin-left: auto;
-  overflow-x: hidden;
-`;
- 
-export const ToolbarWrapper = styled.div<{ position: 'top' | 'bottom' }>`
-  display: flex;
-  font-weight: bold;
-  text-align: center;
-  text-decoration: none;
-  border-radius: 6px;
-  width: 100%;
-  padding: 0;
-  margin: ${(p) => (p.position === 'top' ? '0 0 20px 0' : '20px 0 0 0')};
-  order: ${(p) => (p.position === 'top' ? 0 : 1)};
-  z-index: ${zIndex.controls - 1}; /* Below controls but above base timeline */
-  align-items: center;
-  justify-content: space-between;
-  gap: 1rem;
-`;
- 
-export const ExtraControls = styled.ul<{
-  $hide: boolean;
-  $slideShowRunning: boolean;
-}>`
-  display: flex;
-  align-items: center;
-  list-style: none;
-  margin: 0;
-  padding: 0.1rem;
-  visibility: ${(p) => (p.$hide ? 'hidden' : 'visible')};
-  flex-shrink: 0;
-`;
- 
-export const ExtraControlChild = styled.li`
-  display: flex;
-  margin: 0.5rem 0;
-  margin-right: 0.5rem;
-`;
- 
-export const SearchWrapper = styled.div<{ theme?: Theme }>`
-  display: flex;
-  align-items: center;
-  background-color: ${(p) => p.theme?.toolbarBtnBgColor};
-  padding: 0.1rem 0.5rem;
-  border-radius: 6px;
-  border: 1px solid ${(p) => p.theme?.buttonBorderColor};
-  flex-grow: 1;
-  max-width: 400px;
-  margin: 0 1rem;
-  transition:
-    border-color 0.2s ease,
-    box-shadow 0.2s ease;
- 
-  &:focus-within {
-    border-color: ${(p) => p.theme?.primary};
-    box-shadow: 0 0 0 2px ${(p) => p.theme?.glowColor};
-  }
-`;
- 
-export const SearchInput = styled.input<{ theme?: Theme }>`
-  flex-grow: 1;
-  border: none;
-  outline: none;
-  background: transparent;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  font-size: 0.9rem;
-  padding: 0.4rem 0.5rem;
- 
-  &::placeholder {
-    color: ${(p) => p.theme?.toolbarTextColor};
-    opacity: 0.6;
-  }
- 
-  &::-webkit-search-cancel-button {
-    appearance: none;
-    height: 10px;
-    width: 10px;
-    margin-left: 0.2rem;
-    background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 10 10" fill="%23${(
-      p,
-    ) =>
-      p.theme?.toolbarTextColor?.substring(
-        1,
-      )}"><path d=\"M.7.7l8.6 8.6M9.3.7L.7 9.3\" stroke=\"%23${(p) =>
-      p.theme?.toolbarTextColor?.substring(1)}\" stroke-width=\"1.5\"/></svg>');
-    cursor: pointer;
-    opacity: 0.6;
-    &:hover {
-      opacity: 1;
-    }
-  }
-`;
- 
-export const SearchInfo = styled.span<{ theme?: Theme }>`
-  font-size: 0.8rem;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  opacity: 0.8;
-  margin: 0 0.5rem;
-  white-space: nowrap;
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/timeline.style.tsx.html b/coverage/lcov-report/components/timeline/timeline.style.tsx.html deleted file mode 100644 index eb9d57b4b..000000000 --- a/coverage/lcov-report/components/timeline/timeline.style.tsx.html +++ /dev/null @@ -1,580 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline.style.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline.style.tsx

-
- -
- 0% - Statements - 0/29 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/29 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import styled from 'styled-components';
-import { Theme } from '../../models/Theme';
-import { TimelineMode } from '../../models/TimelineModel';
- 
-export const Wrapper = styled.div<{
-  cardPositionHorizontal?: 'TOP' | 'BOTTOM';
-  theme?: Theme;
-}>`
-  width: 100%;
-  height: 100%;
-  display: flex;
-  flex-direction: column;
-  font-family: 'Roboto Condensed', sans-serif;
-  position: relative;
-  z-index: 0;
- 
-  &:focus-visible {
-    outline: 2px solid ${(p) => p.theme?.primary || '#0066cc'};
-    outline-offset: 2px;
-  }
- 
-  button:focus-visible,
-  a:focus-visible,
-  input:focus-visible {
-    outline: 2px solid ${(p) => p.theme?.primary || '#0066cc'};
-    outline-offset: 2px;
-    box-shadow: 0 0 0 4px rgba(0, 102, 204, 0.2);
-  }
- 
-  overflow: hidden;
-  &.horizontal {
-    justify-content: flex-start;
-  }
-`;
- 
-export const TimelineMainWrapper = styled.div<{
-  $scrollable?: boolean | { scrollbar: boolean };
-  mode?: TimelineMode;
-  position?: 'top' | 'bottom';
-  theme?: Theme;
-}>`
-  align-items: flex-start;
-  display: flex;
-  justify-content: center;
-  overflow-y: auto;
-  overflow-x: hidden;
-  overscroll-behavior: contain;
-  ${(p) => (p.mode === 'HORIZONTAL' ? 'position: relative' : '')};
-  scroll-behavior: smooth;
-  width: 100%;
-  background-color: ${(p) => p.theme?.timelineBgColor || 'transparent'};
-  padding: ${({ $scrollable }) => (!$scrollable ? '0 1rem 0' : '')};
-`;
- 
-export const TimelineContentRender = styled.div<{ $showAllCards?: boolean }>`
-  display: flex;
-  align-items: flex-start;
-  justify-content: ${(p) => (p.$showAllCards ? 'flex-start' : 'center')};
-  width: 98%;
-  margin-right: auto;
-  margin-left: auto;
-  overflow-x: hidden;
-`;
- 
-export const ToolbarWrapper = styled.div<{ position: 'top' | 'bottom' }>`
-  display: flex;
-  font-weight: bold;
-  text-align: center;
-  text-decoration: none;
-  border-radius: 6px;
-  width: 100%;
-  padding: 0;
-  margin: ${(p) => (p.position === 'top' ? '0 0 4px 0' : '4px 0 0 0')};
-  order: ${(p) => (p.position === 'top' ? 0 : 1)};
-  z-index: 1;
-  align-items: center;
-  justify-content: space-between;
-  gap: 1rem;
-`;
- 
-export const ExtraControls = styled.ul<{
-  $hide: boolean;
-  $slideShowRunning: boolean;
-}>`
-  display: flex;
-  align-items: center;
-  list-style: none;
-  margin: 0;
-  padding: 0.1rem;
-  visibility: ${(p) => (p.$hide ? 'hidden' : 'visible')};
-  flex-shrink: 0;
-`;
- 
-export const SearchWrapper = styled.div<{ theme?: Theme }>`
-  display: flex;
-  align-items: center;
-  background-color: ${(p) => p.theme?.toolbarBtnBgColor};
-  padding: 0.1rem 0.5rem;
-  border-radius: 6px;
-  border: 1px solid ${(p) => p.theme?.buttonBorderColor};
-  flex-grow: 1;
-  max-width: 400px;
-  margin: 0 1rem;
-  transition:
-    border-color 0.2s ease,
-    box-shadow 0.2s ease;
- 
-  &:focus-within {
-    border-color: ${(p) => p.theme?.primary};
-    box-shadow: 0 0 0 2px ${(p) => p.theme?.glowColor};
-  }
-`;
- 
-export const SearchInput = styled.input<{ theme?: Theme }>`
-  flex-grow: 1;
-  border: none;
-  outline: none;
-  background: transparent;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  font-size: 0.9rem;
-  padding: 0.4rem 0.5rem;
- 
-  &::placeholder {
-    color: ${(p) => p.theme?.toolbarTextColor};
-    opacity: 0.6;
-  }
-`;
- 
-export const SearchInfo = styled.span<{ theme?: Theme }>`
-  font-size: 0.8rem;
-  color: ${(p) => p.theme?.toolbarTextColor};
-  opacity: 0.8;
-  margin: 0 0.5rem;
-  white-space: nowrap;
-`;
- 
-export const Outline = styled.div<{ color?: string; height?: number }>`
-  position: absolute;
-  right: 0;
-  left: 0;
-  width: 100%;
-  height: ${(p) => `${p.height}px`};
-  margin-right: auto;
-  margin-left: auto;
-  background: ${(p) => p.color};
-  z-index: 0;
-  border-radius: 4px;
-`;
- 
-export const TimelineMain = styled.div`
-  position: absolute;
-  top: 50%;
-  left: 0;
-  display: flex;
-  align-items: center;
-  transition: all 0.2s ease;
-  transform: translate(0, -50%);
- 
-  &.vertical {
-    align-items: flex-start;
-    justify-content: flex-start;
-    width: 100%;
-    height: 100%;
-  }
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/timeline/timeline.tsx.html b/coverage/lcov-report/components/timeline/timeline.tsx.html deleted file mode 100644 index 85d880fc8..000000000 --- a/coverage/lcov-report/components/timeline/timeline.tsx.html +++ /dev/null @@ -1,1147 +0,0 @@ - - - - - - Code coverage report for components/timeline/timeline.tsx - - - - - - - - - -
-
-

All files / components/timeline timeline.tsx

-
- -
- 91.98% - Statements - 264/287 -
- - -
- 50% - Branches - 12/24 -
- - -
- 66.66% - Functions - 2/3 -
- - -
- 91.98% - Lines - 264/287 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355  -1x -1x -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -  -1x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -  -  -8x -8x -8x -8x -  -  -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -  -  -8x -8x -6x -6x -6x -6x -8x -8x -  -8x -8x -8x -8x -  -  -8x -6x -  -6x -  -  -  -6x -8x -  -  -8x -8x -  -  -  -  -  -8x -8x -  -  -8x -6x -  -6x -  -  -  -6x -  -6x -6x -6x -6x -6x -6x -6x -6x -  -6x -1x -1x -1x -  -1x -1x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -8x -6x -6x -  -6x -1x -6x -5x -5x -8x -  -  -8x -8x -8x -8x -8x -8x -8x -8x -  -  -  -  -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -  -  -  -  -  -  -  -  -  -  -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -8x -  -8x -8x -8x -8x -8x -8x -  -8x -  -1x -  -1x - 
import { TimelineModel } from '@models/TimelineModel';
-import { getUniqueID } from '@utils/index';
-import cls from 'classnames';
-import React, { useEffect, useMemo, useState } from 'react';
-import { useStableContext, useDynamicContext } from '../contexts';
-import useNewScrollPosition from '../effects/useNewScrollPosition';
-import { useSlideshowProgress } from '../../hooks/useSlideshowProgress';
-import {
-  Wrapper,
-  TimelineMainWrapper,
-  TimelineContentRender,
-  ToolbarWrapper,
-} from './timeline.style';
-import { TimelineToolbar } from './timeline-toolbar';
-import { useTimelineSearch } from '../../hooks/useTimelineSearch';
-import { useTimelineNavigation } from '../../hooks/useTimelineNavigation';
-import { useTimelineMode } from '../../hooks/useTimelineMode';
-import { useTimelineScroll } from '../../hooks/useTimelineScroll';
-import { useTimelineMedia } from '../../hooks/useTimelineMedia';
-import TimelineView from './TimelineView';
- 
-// Disable TypeScript checking for the Timeline component
-// as we're addressing the type conflicts through our custom hooks
-const Timeline: React.FunctionComponent<TimelineModel> = (
-  props: TimelineModel,
-) => {
-  // de-structure the props
-  const {
-    activeTimelineItem,
-    contentDetailsChildren,
-    iconChildren,
-    items = [],
-    onFirst,
-    onLast,
-    onNext,
-    onPrevious,
-    onRestartSlideshow,
-    onTimelineUpdated,
-    onItemSelected,
-    onOutlineSelection,
-    slideShowEnabled,
-    slideShowRunning,
-    mode = 'HORIZONTAL',
-    nestedCardHeight,
-    isChild = false,
-    onPaused,
-    uniqueId,
-    noUniqueId,
-  } = props;
- 
-  const {
-    cardPositionHorizontal,
-    disableNavOnKey,
-    flipLayout,
-    itemWidth = 200,
-    lineWidth,
-    onScrollEnd,
-    scrollable = true,
-    toolbarPosition,
-    disableToolbar,
-    slideItemDuration = 2000,
-  } = useStableContext();
- 
-  const {
-    horizontalAll: showAllCardsHorizontal,
-    memoizedTheme: theme,
-    isDarkMode: darkMode,
-    toggleDarkMode,
-    updateHorizontalAllCards,
-    updateTextContentDensity,
-  } = useDynamicContext();
- 
-  const [newOffSet, setNewOffset] = useNewScrollPosition(mode, itemWidth);
-  const [hasFocus, setHasFocus] = useState(false);
- 
-  // Memoize ID generation to prevent unnecessary regeneration
-  const id = useMemo(
-    () => `react-chrono-timeline-${noUniqueId ? uniqueId : getUniqueID()}`,
-    [noUniqueId, uniqueId],
-  );
- 
-  // Use custom hooks
-  const { timelineMode, handleTimelineUpdate } = useTimelineMode({
-    initialMode: mode,
-    showAllCardsHorizontal,
-    updateHorizontalAllCards,
-  });
- 
-  const {
-    timelineMainRef,
-    horizontalContentRef,
-    handleScroll,
-    handleMainScroll,
-  } = useTimelineScroll({
-    mode,
-    onScrollEnd,
-    setNewOffset,
-  });
- 
-  const {
-    activeItemIndex,
-    handleTimelineItemClick,
-    handleTimelineItemElapsed,
-    handleNext,
-    handlePrevious,
-    handleFirst,
-    handleLast,
-    handleKeySelection,
-  } = useTimelineNavigation({
-    items,
-    mode: timelineMode,
-    timelineId: id,
-    hasFocus,
-    flipLayout,
-    slideShowRunning,
-    onTimelineUpdated,
-    onNext,
-    onPrevious,
-    onFirst,
-    onLast,
-  });
- 
-  const {
-    searchQuery,
-    searchResults,
-    currentMatchIndex,
-    searchInputRef,
-    handleSearchChange,
-    clearSearch,
-    handleNextMatch,
-    handlePreviousMatch,
-    handleSearchKeyDown,
-  } = useTimelineSearch({
-    items: items.map((item) => ({ ...item, wrapperId: id })),
-    onTimelineUpdated,
-    handleTimelineItemClick,
-  });
- 
-  // Overall slideshow progress hook
-  useSlideshowProgress({
-    slideShowRunning: slideShowRunning ?? false,
-    activeTimelineItem: activeTimelineItem ?? 0,
-    totalItems: items.length,
-    slideItemDuration,
-  });
- 
-  useTimelineMedia({
-    mode,
-    timelineMainRef,
-  });
- 
-  // Memoize classes and display flags
-  const wrapperClass = useMemo(
-    () =>
-      cls(mode.toLocaleLowerCase(), {
-        'focus-visible': !isChild,
-        'js-focus-visible': !isChild,
-      }),
-    [mode, isChild],
-  );
- 
-  const canShowToolbar = useMemo(
-    () => !disableToolbar && !isChild,
-    [isChild, disableToolbar],
-  );
- 
-  // Memoize scroll capability determination
-  const canScrollTimeline = useMemo(() => {
-    if (slideShowRunning) return false;
- 
-    if (typeof scrollable === 'boolean') {
-      return scrollable;
-    }
- 
-    return typeof scrollable === 'object' && scrollable.scrollbar;
-  }, [slideShowRunning, scrollable]);
- 
-  // Handle keyboard events
-  const handleKeyDown = React.useCallback(
-    (evt: React.KeyboardEvent<HTMLDivElement>) => {
-      if (!disableNavOnKey && !slideShowRunning) {
-        setHasFocus(true);
-        handleKeySelection(evt);
-      }
-    },
-    [disableNavOnKey, slideShowRunning, handleKeySelection],
-  );
- 
-  // Update active item information
-  useEffect(() => {
-    const activeItem = items[activeTimelineItem ?? 0];
- 
-    if (slideShowRunning) {
-      activeItemIndex.current = activeTimelineItem ?? 0;
-    }
- 
-    if (!items.length || !activeItem) return;
- 
-    const { title, cardTitle, cardSubtitle, cardDetailedText } = activeItem;
-    onItemSelected?.({
-      cardDetailedText,
-      cardSubtitle,
-      cardTitle,
-      index: activeItemIndex.current,
-      title,
-    });
- 
-    if (mode === 'HORIZONTAL') {
-      const card = horizontalContentRef.current?.querySelector(
-        `#timeline-card-${activeItem.id}`,
-      );
- 
-      const cardRect = card?.getBoundingClientRect();
-      const contentRect = horizontalContentRef.current?.getBoundingClientRect();
- 
-      if (cardRect && contentRect) {
-        const { width: cardWidth, left: cardLeft } = cardRect;
-        const { width: contentWidth, left: contentLeft } = contentRect;
- 
-        // Defer DOM manipulation to next tick
-        requestAnimationFrame(() => {
-          const ele = horizontalContentRef.current as HTMLElement;
-          if (!ele) return;
- 
-          ele.style.scrollBehavior = 'smooth';
-          ele.scrollLeft +=
-            cardLeft - contentLeft + cardWidth / 2 - contentWidth / 2;
-        });
-      }
-    }
-  }, [
-    activeTimelineItem,
-    items,
-    slideShowRunning,
-    mode,
-    onItemSelected,
-    activeItemIndex,
-    horizontalContentRef,
-  ]);
- 
-  // Update scroll position when offset changes
-  useEffect(() => {
-    const ele = timelineMainRef.current;
-    if (!ele) return;
- 
-    if (mode === 'HORIZONTAL') {
-      ele.scrollLeft = Math.max(newOffSet, 0);
-    } else {
-      ele.scrollTop = newOffSet;
-    }
-  }, [newOffSet, mode, timelineMainRef]);
- 
-  // Ensure all styled components are properly integrated
-  return (
-    <Wrapper
-      onKeyDown={handleKeyDown}
-      className={wrapperClass}
-      cardPositionHorizontal={cardPositionHorizontal}
-      theme={theme}
-      onMouseDown={() => setHasFocus(true)}
-      onKeyUp={(evt) => {
-        if (evt.key === 'Escape') {
-          onPaused?.();
-        }
-      }}
-    >
-      {canShowToolbar && (
-        <ToolbarWrapper position={toolbarPosition}>
-          <TimelineToolbar
-            activeTimelineItem={activeTimelineItem}
-            totalItems={items.length}
-            slideShowEnabled={slideShowEnabled}
-            slideShowRunning={slideShowRunning}
-            onFirst={handleFirst}
-            onLast={handleLast}
-            onNext={handleNext}
-            onPrevious={handlePrevious}
-            onRestartSlideshow={onRestartSlideshow}
-            darkMode={darkMode}
-            toggleDarkMode={toggleDarkMode}
-            onPaused={onPaused}
-            id={id}
-            flipLayout={flipLayout}
-            items={items}
-            onActivateTimelineItem={handleTimelineItemClick}
-            onUpdateTimelineMode={handleTimelineUpdate}
-            onUpdateTextContentDensity={updateTextContentDensity}
-            mode={timelineMode}
-            searchQuery={searchQuery}
-            onSearchChange={handleSearchChange}
-            onClearSearch={clearSearch}
-            onNextMatch={handleNextMatch}
-            onPreviousMatch={handlePreviousMatch}
-            totalMatches={searchResults.length}
-            currentMatchIndex={currentMatchIndex}
-            onSearchKeyDown={handleSearchKeyDown}
-            searchInputRef={searchInputRef}
-          />
-        </ToolbarWrapper>
-      )}
- 
-      {/* Overall slideshow progress bar - positioned below toolbar */}
-      {/* {slideShowRunning && showOverallSlideshowProgress && (
-        <SlideshowProgress
-          activeItemIndex={activeTimelineItem ?? 0}
-          totalItems={items.length}
-          isRunning={slideShowRunning}
-          slideItemDuration={slideItemDuration}
-          isPaused={isPaused}
-        />
-      )} */}
- 
-      <TimelineMainWrapper
-        ref={timelineMainRef}
-        $scrollable={canScrollTimeline}
-        className={`${mode.toLowerCase()} timeline-main-wrapper`}
-        id="timeline-main-wrapper"
-        data-testid="timeline-main-wrapper"
-        theme={theme}
-        mode={mode}
-        position={toolbarPosition}
-        onScroll={handleMainScroll}
-      >
-        <TimelineView
-          timelineMode={timelineMode}
-          activeTimelineItem={activeTimelineItem}
-          autoScroll={handleScroll}
-          contentDetailsChildren={contentDetailsChildren}
-          hasFocus={hasFocus}
-          iconChildren={iconChildren}
-          items={items}
-          handleTimelineItemClick={handleTimelineItemClick}
-          handleTimelineItemElapsed={handleTimelineItemElapsed}
-          slideShowRunning={slideShowRunning}
-          id={id}
-          theme={theme}
-          lineWidth={lineWidth}
-          onOutlineSelection={onOutlineSelection}
-          nestedCardHeight={nestedCardHeight}
-        />
-      </TimelineMainWrapper>
- 
-      <TimelineContentRender
-        id={id}
-        $showAllCards={showAllCardsHorizontal}
-        ref={horizontalContentRef}
-      />
-    </Wrapper>
-  );
-};
- 
-Timeline.displayName = 'Timeline';
- 
-export default React.memo(Timeline);
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toggle-button/index.html b/coverage/lcov-report/components/toggle-button/index.html deleted file mode 100644 index 71d6d3f83..000000000 --- a/coverage/lcov-report/components/toggle-button/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/toggle-button - - - - - - - - - -
-
-

All files components/toggle-button

-
- -
- 0% - Statements - 0/20 -
- - -
- 0% - Branches - 0/2 -
- - -
- 0% - Functions - 0/2 -
- - -
- 0% - Lines - 0/20 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.tsx -
-
0%0/170%0/10%0/10%0/17
toggle-button.styles.ts -
-
0%0/30%0/10%0/10%0/3
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toggle-button/index.tsx.html b/coverage/lcov-report/components/toggle-button/index.tsx.html deleted file mode 100644 index beda493d4..000000000 --- a/coverage/lcov-report/components/toggle-button/index.tsx.html +++ /dev/null @@ -1,178 +0,0 @@ - - - - - - Code coverage report for components/toggle-button/index.tsx - - - - - - - - - -
-
-

All files / components/toggle-button index.tsx

-
- -
- 0% - Statements - 0/17 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/17 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  - 
import { FunctionComponent, ReactNode, memo } from 'react';
-import { useUIState } from '../../hooks/useUIState';
-import { ButtonWrapper, ToggleSwitch } from './toggle-button.styles';
- 
-export interface ToggleButtonProps {
-  offIcon: ReactNode;
-  onIcon: ReactNode;
-  state: boolean;
-  onChange?: (state: boolean) => void;
-}
- 
-const ToggleButton: FunctionComponent<ToggleButtonProps> = memo(
-  ({ offIcon, onIcon, state, onChange }) => {
-    const { state: on, toggle } = useUIState(state ?? false);
- 
-    const handleToggle = () => {
-      toggle();
-      onChange?.(on);
-    };
- 
-    return (
-      <ButtonWrapper onClick={handleToggle}>
-        <ToggleSwitch>{on ? offIcon : onIcon}</ToggleSwitch>
-      </ButtonWrapper>
-    );
-  },
-);
- 
-ToggleButton.displayName = 'ToggleButton';
- 
-export { ToggleButton };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toggle-button/toggle-button.styles.ts.html b/coverage/lcov-report/components/toggle-button/toggle-button.styles.ts.html deleted file mode 100644 index 075e06600..000000000 --- a/coverage/lcov-report/components/toggle-button/toggle-button.styles.ts.html +++ /dev/null @@ -1,100 +0,0 @@ - - - - - - Code coverage report for components/toggle-button/toggle-button.styles.ts - - - - - - - - - -
-
-

All files / components/toggle-button toggle-button.styles.ts

-
- -
- 0% - Statements - 0/3 -
- - -
- 0% - Branches - 0/1 -
- - -
- 0% - Functions - 0/1 -
- - -
- 0% - Lines - 0/3 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6  -  -  -  -  - 
import styled from 'styled-components';
- 
-export const ButtonWrapper = styled.div``;
- 
-export const ToggleSwitch = styled.span``;
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toolbar/__tests__/index.html b/coverage/lcov-report/components/toolbar/__tests__/index.html deleted file mode 100644 index 600ad2035..000000000 --- a/coverage/lcov-report/components/toolbar/__tests__/index.html +++ /dev/null @@ -1,116 +0,0 @@ - - - - - - Code coverage report for components/toolbar/__tests__ - - - - - - - - - -
-
-

All files components/toolbar/__tests__

-
- -
- 100% - Statements - 41/41 -
- - -
- 100% - Branches - 4/4 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 41/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
toolbar.test.tsx -
-
100%41/41100%4/40%0/3100%41/41
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toolbar/__tests__/toolbar.test.tsx.html b/coverage/lcov-report/components/toolbar/__tests__/toolbar.test.tsx.html deleted file mode 100644 index 1dfd8f10c..000000000 --- a/coverage/lcov-report/components/toolbar/__tests__/toolbar.test.tsx.html +++ /dev/null @@ -1,241 +0,0 @@ - - - - - - Code coverage report for components/toolbar/__tests__/toolbar.test.tsx - - - - - - - - - -
-
-

All files / components/toolbar/__tests__ toolbar.test.tsx

-
- -
- 100% - Statements - 41/41 -
- - -
- 100% - Branches - 4/4 -
- - -
- 0% - Functions - 0/3 -
- - -
- 100% - Lines - 41/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53  -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -2x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x - 
// Toolbar.test.tsx
- 
-import { render } from '@testing-library/react';
-import { getDefaultThemeOrDark } from '@utils/index';
-import { ThemeProvider } from 'styled-components';
-import { Toolbar } from '../index';
-import { ToolbarItem } from '@models/ToolbarItem';
- 
-const items: ToolbarItem[] = [
-  { name: 'Item 1', onSelect: () => {}, id: '1' },
-  { name: 'Item 2', onSelect: () => {}, id: '2' },
-];
- 
-const theme = getDefaultThemeOrDark();
- 
-describe('Toolbar', () => {
-  it('renders toolbar items', () => {
-    const { getByText, baseElement } = render(
-      <ThemeProvider theme={theme}>
-        <Toolbar items={items} theme={theme}>
-          {items.map((item, index) => (
-            <div key={index}>{item.name}</div>
-          ))}
-        </Toolbar>
-      </ThemeProvider>,
-    );
- 
-    console.log(baseElement.innerHTML);
- 
-    expect(getByText(/Item 1/i)).toBeInTheDocument();
-    expect(getByText(/Item 2/i)).toBeInTheDocument();
-  });
- 
-  it('renders icons', () => {
-    const itemWithIcon = {
-      icon: <span>Icon</span>,
-      name: 'Icon Item',
-      id: '3',
-      onSelect: () => {},
-    };
- 
-    const { getByText } = render(
-      <ThemeProvider theme={theme}>
-        <Toolbar items={[itemWithIcon]} theme={theme}>
-          <div>Content</div>
-        </Toolbar>
-      </ThemeProvider>,
-    );
- 
-    expect(getByText(/Icon/i)).toBeInTheDocument();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toolbar/index.html b/coverage/lcov-report/components/toolbar/index.html deleted file mode 100644 index 8f56f7334..000000000 --- a/coverage/lcov-report/components/toolbar/index.html +++ /dev/null @@ -1,131 +0,0 @@ - - - - - - Code coverage report for components/toolbar - - - - - - - - - -
-
-

All files components/toolbar

-
- -
- 87.8% - Statements - 36/41 -
- - -
- 83.33% - Branches - 10/12 -
- - -
- 100% - Functions - 2/2 -
- - -
- 87.8% - Lines - 36/41 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.tsx -
-
82.14%23/2866.66%4/6100%0/082.14%23/28
toolbar.styles.ts -
-
100%13/13100%6/6100%2/2100%13/13
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toolbar/index.tsx.html b/coverage/lcov-report/components/toolbar/index.tsx.html deleted file mode 100644 index 983edaf4c..000000000 --- a/coverage/lcov-report/components/toolbar/index.tsx.html +++ /dev/null @@ -1,277 +0,0 @@ - - - - - - Code coverage report for components/toolbar/index.tsx - - - - - - - - - -
-
-

All files / components/toolbar index.tsx

-
- -
- 82.14% - Statements - 23/28 -
- - -
- 66.66% - Branches - 4/6 -
- - -
- 100% - Functions - 0/0 -
- - -
- 82.14% - Lines - 23/28 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -651x -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -9x -  -  -  -9x -9x -9x -31x -  -  -  -  -31x -31x -31x -31x -31x -  -  -31x -31x -23x -  -31x -  -9x -9x -  -9x -1x -  -1x -  -  - 
import { FunctionComponent, memo } from 'react';
-import { jsx as _jsx } from 'react/jsx-runtime';
-import {
-  ContentWrapper,
-  IconWrapper,
-  ToolbarListItem,
-  ToolbarWrapper,
-} from './toolbar.styles';
-import { ToolbarProps } from '@models/ToolbarProps';
- 
-/**
- * @description A reusable toolbar component that renders a list of items with icons and content
- * @component
- * @param {Object} props - Component properties
- * @param {Array} props.items - Array of toolbar items to render
- * @param {ReactNode[]} props.children - Child elements to render within each toolbar item
- * @param {Theme} props.theme - Theme configuration for styling
- *
- * @example
- * ```tsx
- * <Toolbar
- *   items={[{ id: '1', label: 'Action', icon: <Icon /> }]}
- *   theme={theme}
- * >
- *   <Content />
- * </Toolbar>
- * ```
- */
-const Toolbar: FunctionComponent<ToolbarProps> = memo(
-  ({ items = [], children = [], theme }) => {
-    if (!items.length) {
-      return null;
-    }
- 
-    return (
-      <ToolbarWrapper theme={theme} role="toolbar">
-        {items.map(({ label, id, icon }, index) => {
-          if (!id) {
-            console.warn('Toolbar item is missing required id property');
-            return null;
-          }
- 
-          return (
-            <ToolbarListItem
-              aria-label={label}
-              key={id}
-              role="button"
-              // tabIndex={0}
-            >
-              {icon && <IconWrapper>{icon}</IconWrapper>}
-              {children[index] && (
-                <ContentWrapper>{children[index]}</ContentWrapper>
-              )}
-            </ToolbarListItem>
-          );
-        })}
-      </ToolbarWrapper>
-    );
-  },
-);
- 
-Toolbar.displayName = 'Toolbar';
- 
-export { Toolbar };
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/components/toolbar/toolbar.styles.ts.html b/coverage/lcov-report/components/toolbar/toolbar.styles.ts.html deleted file mode 100644 index 6d12b9982..000000000 --- a/coverage/lcov-report/components/toolbar/toolbar.styles.ts.html +++ /dev/null @@ -1,226 +0,0 @@ - - - - - - Code coverage report for components/toolbar/toolbar.styles.ts - - - - - - - - - -
-
-

All files / components/toolbar toolbar.styles.ts

-
- -
- 100% - Statements - 13/13 -
- - -
- 100% - Branches - 6/6 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 13/13 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48  -1x -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -1x -  -  -  -  -  -  -1x -1x -  -  -  -1x -  -  -  -  -  -1x -1x -  -  -  -  -  -  -1x -1x -  - 
import { Theme } from '@models/Theme';
-import styled, { css } from 'styled-components';
- 
-// Base styles for flex containers - using memo to prevent recreation
-const flexContainer = css`
-  display: flex;
-  align-items: center;
-`;
- 
-// Use transform instead of box-shadow for better performance
-export const ToolbarWrapper = styled.div<{ theme: Theme }>`
-  ${flexContainer};
-  list-style: none;
-  margin: 0;
-  padding: 0.25rem;
-  background-color: ${({ theme }) => theme.toolbarBgColor};
-  transform: translateY(0);
-  filter: drop-shadow(
-    0 2px 4px ${({ theme }) => theme.shadowColor || 'rgba(0, 0, 0, 0.1)'}
-  );
-  width: 100%;
-  height: 100%;
-  border-radius: 6px;
-  flex-wrap: wrap;
-  will-change: transform;
-  border: ${({ theme }) =>
-    theme.buttonBorderColor ? `1px solid ${theme.buttonBorderColor}` : 'none'};
-`;
- 
-// Toolbar list item styles
-export const ToolbarListItem = styled.div`
-  padding: 0;
-  margin: 0 0.5rem;
-`;
- 
-// Icon wrapper styles
-export const IconWrapper = styled.span`
-  ${flexContainer};
-  justify-content: center;
-  width: 1rem;
-  height: 1rem;
-`;
- 
-// Content wrapper styles
-export const ContentWrapper = styled.span`
-  ${flexContainer};
-`;
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/favicon.png b/coverage/lcov-report/favicon.png deleted file mode 100644 index c1525b811a167671e9de1fa78aab9f5c0b61cef7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 445 zcmV;u0Yd(XP))rP{nL}Ln%S7`m{0DjX9TLF* zFCb$4Oi7vyLOydb!7n&^ItCzb-%BoB`=x@N2jll2Nj`kauio%aw_@fe&*}LqlFT43 z8doAAe))z_%=P%v^@JHp3Hjhj^6*Kr_h|g_Gr?ZAa&y>wxHE99Gk>A)2MplWz2xdG zy8VD2J|Uf#EAw*bo5O*PO_}X2Tob{%bUoO2G~T`@%S6qPyc}VkhV}UifBuRk>%5v( z)x7B{I~z*k<7dv#5tC+m{km(D087J4O%+<<;K|qwefb6@GSX45wCK}Sn*> - - - - Code coverage report for hooks/__tests__ - - - - - - - - - -
-
-

All files hooks/__tests__

-
- -
- 99.17% - Statements - 1562/1575 -
- - -
- 99.66% - Branches - 301/302 -
- - -
- 100% - Functions - 7/7 -
- - -
- 99.17% - Lines - 1562/1575 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
useBackground.test.ts -
-
100%54/54100%12/12100%1/1100%54/54
useCardSize.test.ts -
-
97.39%187/192100%23/23100%0/097.39%187/192
useEscapeKey.test.ts -
-
100%88/88100%25/25100%1/1100%88/88
useMediaState.test.ts -
-
100%91/91100%30/30100%0/0100%91/91
useOutsideClick.test.ts -
-
100%116/116100%20/20100%2/2100%116/116
useTimelineMedia.test.ts -
-
100%85/85100%15/15100%2/2100%85/85
useTimelineMode.test.ts -
-
100%101/101100%23/23100%0/0100%101/101
useTimelineNavigation.test.ts -
-
98.8%332/336100%58/58100%1/198.8%332/336
useTimelineScroll.test.ts -
-
100%152/152100%22/22100%0/0100%152/152
useTimelineSearch.test.ts -
-
100%219/219100%36/36100%0/0100%219/219
useUIState.test.ts -
-
100%48/48100%17/17100%0/0100%48/48
useWindowSize.test.ts -
-
95.69%89/9395.23%20/21100%0/095.69%89/93
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useBackground.test.ts.html b/coverage/lcov-report/hooks/__tests__/useBackground.test.ts.html deleted file mode 100644 index f337607e2..000000000 --- a/coverage/lcov-report/hooks/__tests__/useBackground.test.ts.html +++ /dev/null @@ -1,289 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useBackground.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useBackground.test.ts

-
- -
- 100% - Statements - 54/54 -
- - -
- 100% - Branches - 12/12 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 54/54 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -691x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -4x -4x -1x -  -1x -4x -4x -1x -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { useBackground } from '../useBackground';
-import { hexToRGBA } from '../../utils';
- 
-// Mock the hexToRGBA function
-vi.mock('../../utils', () => {
-  return {
-    hexToRGBA: vi.fn(() => 'rgba(0,0,0,0.8)'),
-  };
-});
- 
-describe('useBackground', () => {
-  const warnSpy = vi.spyOn(console, 'warn').mockImplementation(() => {});
- 
-  beforeEach(() => {
-    warnSpy.mockClear();
-    vi.mocked(hexToRGBA).mockClear();
-  });
- 
-  afterEach(() => {
-    warnSpy.mockReset();
-    vi.mocked(hexToRGBA).mockReset();
-  });
- 
-  it('returns empty string if no color is provided', () => {
-    const { result } = renderHook(() => useBackground());
-    expect(result.current).toBe('');
-    expect(hexToRGBA).not.toHaveBeenCalled();
-  });
- 
-  it('returns empty string and warns if color is invalid hex', () => {
-    // Mock NODE_ENV to be development for console warning
-    const originalEnv = process.env.NODE_ENV;
-    process.env.NODE_ENV = 'development';
-    
-    const { result } = renderHook(() => useBackground('not-a-hex'));
-    expect(result.current).toBe('');
-    expect(warnSpy).toHaveBeenCalledWith('Invalid hex color: not-a-hex');
-    expect(hexToRGBA).not.toHaveBeenCalled();
-    
-    // Restore original NODE_ENV
-    process.env.NODE_ENV = originalEnv;
-  });
- 
-  it('calls hexToRGBA and returns its value for valid hex', () => {
-    vi.mocked(hexToRGBA).mockReturnValue('rgba(255,255,255,0.8)');
-    const { result } = renderHook(() => useBackground('#ffffff'));
-    expect(hexToRGBA).toHaveBeenCalledWith('#ffffff', 0.8);
-    expect(result.current).toBe('rgba(255,255,255,0.8)');
-  });
- 
-  it('reacts to color and opacity changes', () => {
-    vi.mocked(hexToRGBA)
-      .mockReturnValueOnce('rgba(255,0,0,0.5)')
-      .mockReturnValueOnce('rgba(255,0,0,1)');
- 
-    const { result, rerender } = renderHook(
-      ({ color, opacity }) => useBackground(color, opacity),
-      {
-        initialProps: { color: '#ff0000', opacity: 0.5 },
-      },
-    );
-    expect(result.current).toBe('rgba(255,0,0,0.5)');
-    rerender({ color: '#ff0000', opacity: 1 });
-    expect(result.current).toBe('rgba(255,0,0,1)');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useCardSize.test.ts.html b/coverage/lcov-report/hooks/__tests__/useCardSize.test.ts.html deleted file mode 100644 index e5226a80e..000000000 --- a/coverage/lcov-report/hooks/__tests__/useCardSize.test.ts.html +++ /dev/null @@ -1,823 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useCardSize.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useCardSize.test.ts

-
- -
- 97.39% - Statements - 187/192 -
- - -
- 100% - Branches - 23/23 -
- - -
- 100% - Functions - 0/0 -
- - -
- 97.39% - Lines - 187/192 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -7x -7x -7x -7x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -2x -2x -2x -2x -2x -1x -  -  -1x -1x -  -  -  -  -  -1x -  -  -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -  -  -1x -  -1x -1x -1x - 
// Mock ResizeObserver before tests
-const mockResizeObserver = vi.fn().mockImplementation((callback) => ({
-  observe: vi.fn(),
-  unobserve: vi.fn(),
-  disconnect: vi.fn(),
-}));
- 
-global.ResizeObserver = mockResizeObserver;
- 
-import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useCardSize } from '../useCardSize';
- 
-describe('useCardSize', () => {
-  const mockContainerRef = { current: null as HTMLElement | null };
-  const mockDetailsRef = { current: null as HTMLElement | null };
-  const mockSetStartWidth = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-    mockContainerRef.current = null;
-    mockDetailsRef.current = null;
-    mockResizeObserver.mockClear();
-  });
- 
-  it('should initialize with default values', () => {
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    expect(result.current.cardActualHeight).toBe(0);
-    expect(result.current.detailsHeight).toBe(0);
-    expect(result.current.textContentLarge).toBe(false);
-  });
- 
-  it('should update card size when node is provided', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 300,
-      offsetHeight: 250,
-      offsetTop: 50,
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    expect(mockSetStartWidth).toHaveBeenCalledWith(500);
-    expect(result.current.cardActualHeight).toBe(300);
-    expect(result.current.detailsHeight).toBe(250);
-  });
- 
-  it('should not update card size when node is null', () => {
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(null);
-    });
- 
-    expect(mockSetStartWidth).not.toHaveBeenCalled();
-    expect(result.current.cardActualHeight).toBe(0);
-    expect(result.current.detailsHeight).toBe(0);
-  });
- 
-  it('should detect large text content when content overflows', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 500, // Large scroll height
-      offsetHeight: 200, // Small visible height
-      offsetTop: 50,
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    expect(result.current.textContentLarge).toBe(true);
-  });
- 
-  it('should detect large text content when total height exceeds container', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 300,
-      offsetHeight: 250,
-      offsetTop: 200, // Large offset
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    expect(result.current.textContentLarge).toBe(true);
-  });
- 
-  it('should handle ResizeObserver updates', () => {
-    const mockNode = {
-      clientWidth: 500,
-    } as HTMLElement;
- 
-    const mockDetailsElement = {
-      scrollHeight: 300,
-      offsetHeight: 250,
-      offsetTop: 50,
-      clientHeight: 200,
-    } as HTMLElement;
- 
-    mockContainerRef.current = {
-      clientHeight: 400,
-    } as HTMLElement;
- 
-    mockDetailsRef.current = mockDetailsElement;
- 
-    const { result } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    // Mock ResizeObserver callback
-    const resizeObserverCallback = vi.fn();
-    const mockResizeObserver = vi.fn().mockImplementation((callback) => {
-      resizeObserverCallback.mockImplementation(callback);
-      return {
-        observe: vi.fn(),
-        disconnect: vi.fn(),
-      };
-    });
- 
-    // Replace ResizeObserver with mock
-    const originalResizeObserver = window.ResizeObserver;
-    window.ResizeObserver = mockResizeObserver;
- 
-    act(() => {
-      result.current.updateCardSize(mockNode);
-    });
- 
-    // Simulate resize
-    act(() => {
-      resizeObserverCallback([
-        {
-          target: mockNode,
-          contentRect: { width: 600 },
-        },
-      ]);
-    });
- 
-    // Restore ResizeObserver
-    window.ResizeObserver = originalResizeObserver;
- 
-    expect(result.current.cardActualHeight).toBe(300);
-    expect(result.current.detailsHeight).toBe(250);
-  });
- 
-  it('should cleanup ResizeObserver on unmount', () => {
-    const mockDisconnect = vi.fn();
-    const mockResizeObserver = vi.fn().mockImplementation(() => ({
-      observe: vi.fn(),
-      disconnect: mockDisconnect,
-    }));
- 
-    // Replace ResizeObserver with mock
-    const originalResizeObserver = window.ResizeObserver;
-    window.ResizeObserver = mockResizeObserver;
- 
-    const { unmount } = renderHook(() =>
-      useCardSize({
-        containerRef: mockContainerRef,
-        detailsRef: mockDetailsRef,
-        setStartWidth: mockSetStartWidth,
-      }),
-    );
- 
-    unmount();
- 
-    // Restore ResizeObserver
-    window.ResizeObserver = originalResizeObserver;
- 
-    expect(mockDisconnect).toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useEscapeKey.test.ts.html b/coverage/lcov-report/hooks/__tests__/useEscapeKey.test.ts.html deleted file mode 100644 index 0c68db0cc..000000000 --- a/coverage/lcov-report/hooks/__tests__/useEscapeKey.test.ts.html +++ /dev/null @@ -1,436 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useEscapeKey.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useEscapeKey.test.ts

-
- -
- 100% - Statements - 88/88 -
- - -
- 100% - Branches - 25/25 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 88/88 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -1181x -1x -1x -1x -  -1x -1x -  -1x -8x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, beforeEach, vi } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { act } from 'react-dom/test-utils';
-import useEscapeKey from '../useEscapeKey';
- 
-describe('useEscapeKey', () => {
-  let mockCallback: ReturnType<typeof vi.fn>;
- 
-  beforeEach(() => {
-    mockCallback = vi.fn();
-  });
- 
-  it('should call callback when Escape key is pressed', () => {
-    renderHook(() => useEscapeKey(mockCallback));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Escape', keyCode: 27 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when a different key is pressed', () => {
-    renderHook(() => useEscapeKey(mockCallback));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Enter', keyCode: 13 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should work with custom key option', () => {
-    renderHook(() => useEscapeKey(mockCallback, { key: 'Enter' }));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Enter', keyCode: 13 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should work with custom keyCode option', () => {
-    renderHook(() => useEscapeKey(mockCallback, { keyCode: 13 }));
- 
-    act(() => {
-      // Create event with keyCode for fallback testing
-      const event = new KeyboardEvent('keyup', { 
-        key: 'Enter', 
-      });
-      // Manually set keyCode for testing fallback behavior
-      Object.defineProperty(event, 'keyCode', { value: 13 });
-      Object.defineProperty(event, 'key', { value: undefined });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should work with keydown event type', () => {
-    renderHook(() => useEscapeKey(mockCallback, { eventType: 'keydown' }));
- 
-    act(() => {
-      const event = new KeyboardEvent('keydown', {
-        key: 'Escape',
-        keyCode: 27,
-      });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when disabled', () => {
-    renderHook(() => useEscapeKey(mockCallback, { enabled: false }));
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Escape', keyCode: 27 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should update callback when it changes', () => {
-    const { rerender } = renderHook(({ callback }) => useEscapeKey(callback), {
-      initialProps: { callback: mockCallback },
-    });
- 
-    const newCallback = vi.fn();
-    rerender({ callback: newCallback });
- 
-    act(() => {
-      const event = new KeyboardEvent('keyup', { key: 'Escape', keyCode: 27 });
-      document.dispatchEvent(event);
-    });
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-    expect(newCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should clean up event listener on unmount', () => {
-    const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
-    const { unmount } = renderHook(() => useEscapeKey(mockCallback));
- 
-    unmount();
- 
-    expect(removeEventListenerSpy).toHaveBeenCalledWith(
-      'keyup',
-      expect.any(Function),
-    );
-    removeEventListenerSpy.mockRestore();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useMediaState.test.ts.html b/coverage/lcov-report/hooks/__tests__/useMediaState.test.ts.html deleted file mode 100644 index 46696c987..000000000 --- a/coverage/lcov-report/hooks/__tests__/useMediaState.test.ts.html +++ /dev/null @@ -1,424 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useMediaState.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useMediaState.test.ts

-
- -
- 100% - Statements - 91/91 -
- - -
- 100% - Branches - 30/30 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 91/91 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -1141x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -9x -1x -  -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, beforeEach, vi } from 'vitest';
-import { renderHook, act } from '@testing-library/react';
-import { useMediaState } from '../useMediaState';
-import { MediaState } from '../../models/TimelineMediaModel';
- 
-describe('useMediaState', () => {
-  const mockOnElapsed = vi.fn();
-  const defaultProps = {
-    slideShowActive: true,
-    paused: false,
-    id: 'test-id',
-    onElapsed: mockOnElapsed,
-  };
- 
-  beforeEach(() => {
-    mockOnElapsed.mockClear();
-  });
- 
-  it('should initialize with isPlaying as false', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
-    expect(result.current.isPlaying).toBe(false);
-  });
- 
-  it('should update isPlaying state when handleMediaState is called with playing true', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(true);
-  });
- 
-  it('should update isPlaying state when handleMediaState is called with playing false', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(true);
- 
-    act(() => {
-      result.current.handleMediaState({ playing: false } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(false);
-  });
- 
-  it('should not update state when slideShowActive is false', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, slideShowActive: false }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(false);
-  });
- 
-  it('should call onElapsed when media is paused and paused prop is true', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, paused: true }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).toHaveBeenCalledWith('test-id');
-  });
- 
-  it('should not call onElapsed when media is paused but paused prop is false', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).not.toHaveBeenCalled();
-  });
- 
-  it('should not call onElapsed when id is not provided', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, id: undefined }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).not.toHaveBeenCalled();
-  });
- 
-  it('should not call onElapsed when onElapsed is not provided', () => {
-    const { result } = renderHook(() =>
-      useMediaState({ ...defaultProps, onElapsed: undefined }),
-    );
- 
-    act(() => {
-      result.current.handleMediaState({ paused: true } as MediaState);
-    });
-    expect(mockOnElapsed).not.toHaveBeenCalled();
-  });
- 
-  it('should set isPlaying to false when cleanup is called', () => {
-    const { result } = renderHook(() => useMediaState(defaultProps));
- 
-    act(() => {
-      result.current.handleMediaState({ playing: true } as MediaState);
-    });
-    expect(result.current.isPlaying).toBe(true);
- 
-    act(() => {
-      result.current.cleanup();
-    });
-    expect(result.current.isPlaying).toBe(false);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useOutsideClick.test.ts.html b/coverage/lcov-report/hooks/__tests__/useOutsideClick.test.ts.html deleted file mode 100644 index 45cef684c..000000000 --- a/coverage/lcov-report/hooks/__tests__/useOutsideClick.test.ts.html +++ /dev/null @@ -1,583 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useOutsideClick.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useOutsideClick.test.ts

-
- -
- 100% - Statements - 116/116 -
- - -
- 100% - Branches - 20/20 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 116/116 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -1671x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -  -9x -9x -  -  -9x -9x -  -  -9x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { createRef, RefObject } from 'react';
-import useOutsideClick from '../useOutsideClick';
- 
-describe('useOutsideClick', () => {
-  let mockCallback: ReturnType<typeof vi.fn>;
-  let elementRef: RefObject<HTMLDivElement | null>;
-  let mockElement: HTMLDivElement;
-  let mockOutsideElement: HTMLDivElement;
- 
-  beforeEach(() => {
-    // Setup mocks
-    mockCallback = vi.fn();
-    elementRef = createRef();
- 
-    // Create mock elements
-    mockElement = document.createElement('div');
-    mockOutsideElement = document.createElement('div');
- 
-    // Setup ref
-    elementRef.current = mockElement;
-  });
- 
-  it('should call callback when clicking outside element', () => {
-    renderHook(() => useOutsideClick(elementRef, mockCallback));
- 
-    // Simulate click outside
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when clicking inside element', () => {
-    renderHook(() => useOutsideClick(elementRef, mockCallback));
- 
-    // Simulate click inside
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should work with mousedown event type', () => {
-    renderHook(() =>
-      useOutsideClick(elementRef, mockCallback, { eventType: 'mousedown' }),
-    );
- 
-    // Simulate mousedown outside
-    const event = new MouseEvent('mousedown');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should work with touchstart event type', () => {
-    renderHook(() =>
-      useOutsideClick(elementRef, mockCallback, { eventType: 'touchstart' }),
-    );
- 
-    // Simulate touchstart outside
-    const event = new TouchEvent('touchstart');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should not call callback when disabled', () => {
-    renderHook(() =>
-      useOutsideClick(elementRef, mockCallback, { enabled: false }),
-    );
- 
-    // Simulate click outside
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should update callback reference when callback changes', () => {
-    const { rerender } = renderHook(
-      ({ cb }) => useOutsideClick(elementRef, cb),
-      { initialProps: { cb: mockCallback } },
-    );
- 
-    // First click
-    const event1 = new MouseEvent('click');
-    Object.defineProperty(event1, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event1);
-    expect(mockCallback).toHaveBeenCalledTimes(1);
- 
-    // Change callback
-    const newCallback = vi.fn();
-    rerender({ cb: newCallback });
- 
-    // Second click should trigger new callback
-    const event2 = new MouseEvent('click');
-    Object.defineProperty(event2, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event2);
-    expect(newCallback).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should cleanup event listener on unmount', () => {
-    const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
-    const { unmount } = renderHook(() =>
-      useOutsideClick(elementRef, mockCallback),
-    );
- 
-    unmount();
- 
-    expect(removeEventListenerSpy).toHaveBeenCalledWith(
-      'click',
-      expect.any(Function),
-    );
-    removeEventListenerSpy.mockRestore();
-  });
- 
-  it('should handle null ref correctly', () => {
-    const nullRef = createRef<HTMLElement>();
-    renderHook(() => useOutsideClick(nullRef, mockCallback));
- 
-    // Simulate click
-    const event = new MouseEvent('click');
-    Object.defineProperty(event, 'target', { value: mockOutsideElement });
-    document.dispatchEvent(event);
- 
-    // Should not throw and should NOT call callback since ref is null
-    expect(mockCallback).not.toHaveBeenCalled();
-  });
- 
-  it('should remove and add listeners when enabled state changes', () => {
-    const addEventListenerSpy = vi.spyOn(document, 'addEventListener');
-    const removeEventListenerSpy = vi.spyOn(document, 'removeEventListener');
- 
-    const { rerender } = renderHook(
-      ({ enabled }) => useOutsideClick(elementRef, mockCallback, { enabled }),
-      { initialProps: { enabled: true } },
-    );
- 
-    expect(addEventListenerSpy).toHaveBeenCalledWith(
-      'click',
-      expect.any(Function),
-      undefined, // The optimized hook passes undefined for click events
-    );
- 
-    // Disable
-    rerender({ enabled: false });
-    expect(removeEventListenerSpy).toHaveBeenCalledWith(
-      'click',
-      expect.any(Function),
-    );
- 
-    // Re-enable
-    rerender({ enabled: true });
-    expect(addEventListenerSpy).toHaveBeenCalledTimes(2);
- 
-    addEventListenerSpy.mockRestore();
-    removeEventListenerSpy.mockRestore();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useTimelineMedia.test.ts.html b/coverage/lcov-report/hooks/__tests__/useTimelineMedia.test.ts.html deleted file mode 100644 index 46a2e24f2..000000000 --- a/coverage/lcov-report/hooks/__tests__/useTimelineMedia.test.ts.html +++ /dev/null @@ -1,427 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineMedia.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineMedia.test.ts

-
- -
- 100% - Statements - 85/85 -
- - -
- 100% - Branches - 15/15 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 85/85 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -1151x -1x -1x -  -  -1x -1x -1x -1x -1x -  -  -  -  -  -1x -1x -1x -  -1x -3x -3x -3x -3x -3x -3x -  -  -1x -  -1x -1x -1x -1x -1x -1x -  -1x -  -4x -4x -  -4x -4x -  -4x -4x -4x -4x -4x -4x -4x -  -4x -4x -4x -1x -  -1x -4x -4x -4x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import { renderHook } from '@testing-library/react';
-import { useTimelineMedia } from '../useTimelineMedia';
- 
-// Mock utility functions
-vi.mock('../../utils/timelineUtils', () => ({
-  toggleMediaVisibility: vi.fn(),
-  pauseVideoEmbeds: vi.fn(),
-}));
-import {
-  toggleMediaVisibility,
-  pauseVideoEmbeds,
-} from '../../utils/timelineUtils';
- 
-// Mock IntersectionObserver
-const observeSpy = vi.fn();
-const disconnectSpy = vi.fn();
-let intersectionCallback: (entries: any[]) => void;
- 
-class MockIntersectionObserver {
-  observe = observeSpy;
-  disconnect = disconnectSpy;
-  constructor(callback: (entries: any[]) => void) {
-    intersectionCallback = callback;
-  }
-}
- 
-// Mock requestAnimationFrame
-const rafSpy = vi.fn((cb) => cb());
- 
-describe('useTimelineMedia', () => {
-  let originalIntersectionObserver: any;
-  let originalRAF: any;
-  let timelineMainRef: any;
-  let verticalItem1: HTMLDivElement;
-  let verticalItem2: HTMLDivElement;
- 
-  beforeEach(() => {
-    // Save originals
-    originalIntersectionObserver = global.IntersectionObserver;
-    originalRAF = global.requestAnimationFrame;
-    // Mock
-    global.IntersectionObserver = MockIntersectionObserver as any;
-    global.requestAnimationFrame = rafSpy;
-    // Setup DOM
-    timelineMainRef = { current: document.createElement('div') };
-    verticalItem1 = document.createElement('div');
-    verticalItem2 = document.createElement('div');
-    verticalItem1.className = 'vertical-item-row';
-    verticalItem2.className = 'vertical-item-row';
-    timelineMainRef.current.appendChild(verticalItem1);
-    timelineMainRef.current.appendChild(verticalItem2);
-    // Clear mocks
-    vi.clearAllMocks();
-    observeSpy.mockClear();
-    disconnectSpy.mockClear();
-  });
- 
-  afterEach(() => {
-    global.IntersectionObserver = originalIntersectionObserver;
-    global.requestAnimationFrame = originalRAF;
-    vi.clearAllMocks();
-  });
- 
-  it('does not create observer if mode is HORIZONTAL', () => {
-    renderHook(() => useTimelineMedia({ mode: 'HORIZONTAL', timelineMainRef }));
-    expect(intersectionCallback).toBeUndefined();
-    expect(rafSpy).not.toHaveBeenCalled();
-  });
- 
-  it('creates observer and observes vertical-item-row children if mode is not HORIZONTAL', () => {
-    renderHook(() => useTimelineMedia({ mode: 'VERTICAL', timelineMainRef }));
-    expect(intersectionCallback).toBeTypeOf('function');
-    expect(rafSpy).toHaveBeenCalled();
-    expect(observeSpy).toHaveBeenCalledTimes(2);
-    expect(observeSpy).toHaveBeenCalledWith(verticalItem1);
-    expect(observeSpy).toHaveBeenCalledWith(verticalItem2);
-  });
- 
-  it('disconnects observer on unmount', () => {
-    const { unmount } = renderHook(() =>
-      useTimelineMedia({ mode: 'VERTICAL', timelineMainRef }),
-    );
-    unmount();
-    expect(disconnectSpy).toHaveBeenCalled();
-  });
- 
-  it('handles intersection changes correctly', () => {
-    renderHook(() => useTimelineMedia({ mode: 'VERTICAL', timelineMainRef }));
- 
-    // First simulate both items becoming visible
-    intersectionCallback([
-      { target: verticalItem1, isIntersecting: true },
-      { target: verticalItem2, isIntersecting: true },
-    ]);
- 
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem1, true);
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem2, true);
- 
-    // Clear the mocks for the next test
-    vi.clearAllMocks();
- 
-    // Then simulate items going out of view
-    intersectionCallback([
-      { target: verticalItem1, isIntersecting: false },
-      { target: verticalItem2, isIntersecting: false },
-    ]);
- 
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem1, false);
-    expect(toggleMediaVisibility).toHaveBeenCalledWith(verticalItem2, false);
-    expect(pauseVideoEmbeds).toHaveBeenCalledWith(verticalItem1);
-    expect(pauseVideoEmbeds).toHaveBeenCalledWith(verticalItem2);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useTimelineMode.test.ts.html b/coverage/lcov-report/hooks/__tests__/useTimelineMode.test.ts.html deleted file mode 100644 index c76dc4000..000000000 --- a/coverage/lcov-report/hooks/__tests__/useTimelineMode.test.ts.html +++ /dev/null @@ -1,466 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineMode.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineMode.test.ts

-
- -
- 100% - Statements - 101/101 -
- - -
- 100% - Branches - 23/23 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 101/101 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -1281x -1x -1x -  -1x -1x -  -1x -7x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -3x -3x -3x -1x -  -1x -1x -1x -  -1x -  -1x -  -1x -1x -  -1x -1x -2x -2x -2x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -4x -4x -4x -4x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -4x -4x -4x -  -4x -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineMode } from '../useTimelineMode';
- 
-describe('useTimelineMode', () => {
-  const mockUpdateHorizontalAllCards = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  it('should initialize with the provided mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-      }),
-    );
- 
-    expect(result.current.timelineMode).toBe('VERTICAL');
-  });
- 
-  it('should initialize with HORIZONTAL_ALL when showAllCardsHorizontal is true', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'HORIZONTAL',
-        showAllCardsHorizontal: true,
-      }),
-    );
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL_ALL');
-  });
- 
-  it('should handle mode updates', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-        updateHorizontalAllCards: mockUpdateHorizontalAllCards,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL');
-    expect(mockUpdateHorizontalAllCards).toHaveBeenCalledWith(false);
- 
-    act(() => {
-      result.current.handleTimelineUpdate('VERTICAL_ALTERNATING');
-    });
- 
-    expect(result.current.timelineMode).toBe('VERTICAL_ALTERNATING');
-  });
- 
-  it('should handle HORIZONTAL_ALL mode update', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'HORIZONTAL',
-        updateHorizontalAllCards: mockUpdateHorizontalAllCards,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL_ALL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL_ALL');
-    expect(mockUpdateHorizontalAllCards).toHaveBeenCalledWith(true);
-  });
- 
-  it('should maintain state between renders', () => {
-    const { result, rerender } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL');
- 
-    rerender();
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL');
-  });
- 
-  it('should not call updateHorizontalAllCards when not provided', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'HORIZONTAL',
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineUpdate('HORIZONTAL_ALL');
-    });
- 
-    expect(result.current.timelineMode).toBe('HORIZONTAL_ALL');
-    expect(mockUpdateHorizontalAllCards).not.toHaveBeenCalled();
-  });
- 
-  it('should handle all valid mode transitions', () => {
-    const { result } = renderHook(() =>
-      useTimelineMode({
-        initialMode: 'VERTICAL',
-        updateHorizontalAllCards: mockUpdateHorizontalAllCards,
-      }),
-    );
- 
-    const modes = [
-      'VERTICAL',
-      'HORIZONTAL',
-      'VERTICAL_ALTERNATING',
-      'HORIZONTAL_ALL',
-    ];
- 
-    modes.forEach((mode) => {
-      act(() => {
-        result.current.handleTimelineUpdate(mode);
-      });
- 
-      expect(result.current.timelineMode).toBe(mode);
-    });
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useTimelineNavigation.test.ts.html b/coverage/lcov-report/hooks/__tests__/useTimelineNavigation.test.ts.html deleted file mode 100644 index da0bbb776..000000000 --- a/coverage/lcov-report/hooks/__tests__/useTimelineNavigation.test.ts.html +++ /dev/null @@ -1,1369 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineNavigation.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineNavigation.test.ts

-
- -
- 98.8% - Statements - 332/336 -
- - -
- 100% - Branches - 58/58 -
- - -
- 100% - Functions - 1/1 -
- - -
- 98.8% - Lines - 332/336 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -325 -326 -327 -328 -329 -330 -331 -332 -333 -334 -335 -336 -337 -338 -339 -340 -341 -342 -343 -344 -345 -346 -347 -348 -349 -350 -351 -352 -353 -354 -355 -356 -357 -358 -359 -360 -361 -362 -363 -364 -365 -366 -367 -368 -369 -370 -371 -372 -373 -374 -375 -376 -377 -378 -379 -380 -381 -382 -383 -384 -385 -386 -387 -388 -389 -390 -391 -392 -393 -394 -395 -396 -397 -398 -399 -400 -401 -402 -403 -404 -405 -406 -407 -408 -409 -410 -411 -412 -413 -414 -415 -416 -417 -418 -419 -420 -421 -422 -423 -424 -425 -426 -427 -428 -4291x -1x -1x -  -  -1x -  -  -  -1x -  -  -1x -9x -9x -9x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -15x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -  -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -  -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineNavigation } from '../useTimelineNavigation';
- 
-// Mock the findTimelineElement utility
-vi.mock('../utils/timelineUtils', () => ({
-  findTimelineElement: vi.fn(() => ({
-    scrollIntoView: vi.fn(),
-  })),
-}));
- 
-// Helper function to create mock keyboard events
-const createMockKeyboardEvent = (key: string): React.KeyboardEvent<HTMLDivElement> => ({
-  key,
-  preventDefault: vi.fn(),
-} as unknown as React.KeyboardEvent<HTMLDivElement>);
- 
-describe('useTimelineNavigation', () => {
-  const mockItems = [
-    { id: '1', title: 'First Item' },
-    { id: '2', title: 'Second Item' },
-    { id: '3', title: 'Third Item' },
-  ];
- 
-  const mockOnTimelineUpdated = vi.fn();
-  const mockOnNext = vi.fn();
-  const mockOnPrevious = vi.fn();
-  const mockOnFirst = vi.fn();
-  const mockOnLast = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  it('should initialize with correct state', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-        onFirst: mockOnFirst,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-  });
- 
-  it('should handle timeline item click', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-  });
- 
-  it('should handle timeline item elapsed', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemElapsed('2');
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(2); // isSlideShow is true
-  });
- 
-  it('should handle next navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onNext: mockOnNext,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleNext();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
-  });
- 
-  it('should handle previous navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onPrevious: mockOnPrevious,
-      }),
-    );
- 
-    // First move to the second item
-    act(() => {
-      result.current.handleNext();
-    });
- 
-    // Then move back
-    act(() => {
-      result.current.handlePrevious();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
-  });
- 
-  it('should handle first navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onFirst: mockOnFirst,
-      }),
-    );
- 
-    // First move to the last item
-    act(() => {
-      result.current.handleLast();
-    });
- 
-    // Then move to first
-    act(() => {
-      result.current.handleFirst();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnFirst).toHaveBeenCalled();
-  });
- 
-  it('should handle last navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleLast();
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(2);
-    expect(mockOnLast).toHaveBeenCalled();
-  });
- 
-  it('should handle keyboard navigation in vertical mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-        onFirst: mockOnFirst,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    // Test arrow down
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowDown'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
- 
-    // Test arrow up
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowUp'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
- 
-    // Move to a different position first, then test Home key
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowDown'));
-    });
-    
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('Home'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnFirst).toHaveBeenCalled();
- 
-    // Test End key
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('End'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(mockItems.length - 1);
-    expect(mockOnLast).toHaveBeenCalled();
-  });
- 
-  it('should handle keyboard navigation in horizontal mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-      }),
-    );
- 
-    // Test arrow right
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowRight'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
- 
-    // Test arrow left
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowLeft'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
-  });
- 
-  it('should handle flipped layout in horizontal mode', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        flipLayout: true,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-      }),
-    );
- 
-    // Move to index 1 first to enable testing both directions
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowLeft'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnNext).toHaveBeenCalled();
- 
-    // Test arrow right (should go previous in flipped layout)
-    act(() => {
-      result.current.handleKeySelection(createMockKeyboardEvent('ArrowRight'));
-    });
- 
-    expect(result.current.activeItemIndex.current).toBe(0);
-    expect(mockOnPrevious).toHaveBeenCalled();
-  });
- 
-  it('should not handle navigation when hasFocus is false', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: false,
-        onNext: mockOnNext,
-        onPrevious: mockOnPrevious,
-        onFirst: mockOnFirst,
-        onLast: mockOnLast,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleNext();
-      result.current.handlePrevious();
-      result.current.handleFirst();
-      result.current.handleLast();
-    });
- 
-    expect(mockOnNext).not.toHaveBeenCalled();
-    expect(mockOnPrevious).not.toHaveBeenCalled();
-    expect(mockOnFirst).not.toHaveBeenCalled();
-    expect(mockOnLast).not.toHaveBeenCalled();
-  });
- 
-  it('should not handle invalid item clicks', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('invalid-id');
-    });
- 
-    expect(mockOnTimelineUpdated).not.toHaveBeenCalled();
-  });
- 
-  it('should disable card alignment scrolling in horizontal mode when slideshow is running', () => {
-    const mockScrollIntoView = vi.fn();
-    
-    // Mock document.getElementById to return an element with scrollIntoView method
-    const originalGetElementById = document.getElementById;
-    document.getElementById = vi.fn(() => ({
-      scrollIntoView: mockScrollIntoView,
-    })) as any;
- 
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        slideShowRunning: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    // Should update timeline position but not call scrollIntoView when slideshow is running
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockScrollIntoView).not.toHaveBeenCalled();
- 
-    // Restore original function
-    document.getElementById = originalGetElementById;
-  });
- 
-  it('should allow card alignment scrolling in horizontal mode when slideshow is not running', async () => {
-    const mockScrollIntoView = vi.fn();
-    
-    // Mock document.getElementById to return an element with scrollIntoView method and closest method
-    const originalGetElementById = document.getElementById;
-    document.getElementById = vi.fn(() => ({
-      scrollIntoView: mockScrollIntoView,
-      closest: vi.fn(() => null), // Mock closest method
-      parentElement: null,
-    })) as any;
- 
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'HORIZONTAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        slideShowRunning: false,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    // Wait for requestAnimationFrame to complete
-    await act(async () => {
-      await new Promise(resolve => requestAnimationFrame(resolve));
-    });
- 
-    // Should update timeline position and call scrollIntoView when slideshow is not running
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockScrollIntoView).toHaveBeenCalled();
- 
-    // Restore original function
-    document.getElementById = originalGetElementById;
-  });
- 
-  it('should allow card alignment scrolling in vertical mode even when slideshow is running', () => {
-    const { result } = renderHook(() =>
-      useTimelineNavigation({
-        items: mockItems,
-        mode: 'VERTICAL',
-        timelineId: 'test-timeline',
-        hasFocus: true,
-        slideShowRunning: true,
-        onTimelineUpdated: mockOnTimelineUpdated,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleTimelineItemClick('2');
-    });
- 
-    // Should update timeline position and the mocked scrollIntoView should be called
-    expect(result.current.activeItemIndex.current).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    // In vertical mode, slideshow running should not affect scrolling behavior
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useTimelineScroll.test.ts.html b/coverage/lcov-report/hooks/__tests__/useTimelineScroll.test.ts.html deleted file mode 100644 index 6d39a6e01..000000000 --- a/coverage/lcov-report/hooks/__tests__/useTimelineScroll.test.ts.html +++ /dev/null @@ -1,688 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineScroll.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineScroll.test.ts

-
- -
- 100% - Statements - 152/152 -
- - -
- 100% - Branches - 22/22 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 152/152 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -2021x -1x -1x -  -1x -1x -1x -  -1x -5x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -  -  -  -1x -  -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineScroll } from '../useTimelineScroll';
- 
-describe('useTimelineScroll', () => {
-  const mockSetNewOffset = vi.fn();
-  const mockOnScrollEnd = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-  });
- 
-  it('should initialize with correct refs', () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-      }),
-    );
- 
-    expect(result.current.timelineMainRef.current).toBeNull();
-    expect(result.current.horizontalContentRef.current).toBeNull();
-  });
- 
-  it('should handle scroll in vertical mode', async () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-        onScrollEnd: mockOnScrollEnd,
-      }),
-    );
- 
-    // Test scroll offset update
-    const mockElement = document.createElement('div');
- 
-    // Set necessary properties for scroll calculations
-    Object.defineProperties(mockElement, {
-      scrollTop: { value: 100, configurable: true, writable: true },
-      clientHeight: { value: 500, configurable: true, writable: true },
-      scrollHeight: { value: 1000, configurable: true, writable: true },
-    });
- 
-    // Set the ref
-    result.current.timelineMainRef.current = mockElement;
- 
-    // Test handleScroll
-    act(() => {
-      result.current.handleScroll({ scrollTop: 200 });
-    });
- 
-    // Verify setNewOffset was called
-    expect(mockSetNewOffset).toHaveBeenCalledWith(mockElement, {
-      scrollTop: 200,
-    });
- 
-    // IMPORTANT: Reset mocks before testing onScrollEnd
-    vi.clearAllMocks();
- 
-    // Change scroll position to exactly trigger the end condition
-    // For onScrollEnd to trigger: scrollTop + clientHeight must be very close to scrollHeight
-    mockElement.scrollTop = 499.5; // With clientHeight 500, this gives 999.5, which is within 1 of scrollHeight 1000
- 
-    // Trigger scroll event that should call onScrollEnd
-    act(() => {
-      result.current.handleMainScroll({
-        target: mockElement,
-        currentTarget: mockElement,
-        type: 'scroll',
-      } as unknown as React.UIEvent<HTMLDivElement>);
-    });
- 
-    // Wait for the throttled callback (100ms timeout)
-    await act(async () => {
-      await new Promise(resolve => setTimeout(resolve, 150));
-    });
- 
-    // Verify onScrollEnd was called
-    expect(mockOnScrollEnd).toHaveBeenCalledTimes(1);
-  });
- 
-  it('should handle scroll in horizontal mode', async () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'HORIZONTAL',
-        setNewOffset: mockSetNewOffset,
-        onScrollEnd: mockOnScrollEnd,
-      }),
-    );
- 
-    // Mock the ref element
-    const mockElement = {
-      scrollLeft: 100,
-      offsetWidth: 500,
-      scrollWidth: 1000,
-    } as HTMLDivElement;
- 
-    result.current.timelineMainRef.current = mockElement;
- 
-    act(() => {
-      result.current.handleMainScroll({
-        target: mockElement,
-        currentTarget: mockElement,
-        nativeEvent: new Event('scroll'),
-        detail: 0,
-        view: window,
-        bubbles: true,
-        cancelable: true,
-        defaultPrevented: false,
-        eventPhase: 0,
-        isTrusted: true,
-        timeStamp: Date.now(),
-        type: 'scroll',
-        isDefaultPrevented: vi.fn(),
-        isPropagationStopped: vi.fn(),
-        stopPropagation: vi.fn(),
-        preventDefault: vi.fn(),
-        persist: vi.fn(),
-      } as unknown as React.UIEvent<HTMLDivElement>);
-    });
- 
-    // Should not trigger onScrollEnd as we haven't reached the end
-    expect(mockOnScrollEnd).not.toHaveBeenCalled();
- 
-    // Mock reaching the end of scroll
-    Object.defineProperty(mockElement, 'scrollLeft', { value: 500 });
-    Object.defineProperty(mockElement, 'offsetWidth', { value: 500 });
-    Object.defineProperty(mockElement, 'scrollWidth', { value: 1000 });
- 
-    act(() => {
-      result.current.handleMainScroll({
-        target: mockElement,
-        currentTarget: mockElement,
-        nativeEvent: new Event('scroll'),
-        detail: 0,
-        view: window,
-        bubbles: true,
-        cancelable: true,
-        defaultPrevented: false,
-        eventPhase: 0,
-        isTrusted: true,
-        timeStamp: Date.now(),
-        type: 'scroll',
-        isDefaultPrevented: vi.fn(),
-        isPropagationStopped: vi.fn(),
-        stopPropagation: vi.fn(),
-        preventDefault: vi.fn(),
-        persist: vi.fn(),
-      } as unknown as React.UIEvent<HTMLDivElement>);
-    });
- 
-    // Wait for the throttled callback (100ms timeout)
-    await act(async () => {
-      await new Promise(resolve => setTimeout(resolve, 150));
-    });
- 
-    // Should trigger onScrollEnd when reaching the end
-    expect(mockOnScrollEnd).toHaveBeenCalled();
-  });
- 
-  it('should handle scroll with setNewOffset', () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-      }),
-    );
- 
-    // Mock the ref element
-    const mockElement = {
-      scrollTop: 100,
-      clientHeight: 500,
-      scrollHeight: 1000,
-    } as HTMLDivElement;
- 
-    result.current.timelineMainRef.current = mockElement;
- 
-    act(() => {
-      result.current.handleScroll({ scrollTop: 200 });
-    });
- 
-    expect(mockSetNewOffset).toHaveBeenCalledWith(mockElement, {
-      scrollTop: 200,
-    });
-  });
- 
-  it('should not call setNewOffset when element is null', () => {
-    const { result } = renderHook(() =>
-      useTimelineScroll({
-        mode: 'VERTICAL',
-        setNewOffset: mockSetNewOffset,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleScroll({ scrollTop: 200 });
-    });
- 
-    expect(mockSetNewOffset).not.toHaveBeenCalled();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useTimelineSearch.test.ts.html b/coverage/lcov-report/hooks/__tests__/useTimelineSearch.test.ts.html deleted file mode 100644 index 6e2b994aa..000000000 --- a/coverage/lcov-report/hooks/__tests__/useTimelineSearch.test.ts.html +++ /dev/null @@ -1,904 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useTimelineSearch.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useTimelineSearch.test.ts

-
- -
- 100% - Statements - 219/219 -
- - -
- 100% - Branches - 36/36 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 219/219 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -2741x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -1x -8x -8x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -3x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -3x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -5x -5x -5x -5x -5x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -4x -4x -4x -4x -4x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -2x -2x -2x -2x -2x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -3x -3x -3x -3x -3x -1x -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -4x -4x -4x -4x -4x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach } from 'vitest';
-import { useTimelineSearch } from '../useTimelineSearch';
- 
-describe('useTimelineSearch', () => {
-  const mockItems = [
-    {
-      id: '1',
-      title: 'First Item',
-      cardTitle: 'Card Title 1',
-      cardSubtitle: 'Subtitle 1',
-      cardDetailedText: 'Detailed text 1',
-    },
-    {
-      id: '2',
-      title: 'Second Item',
-      cardTitle: 'Card Title 2',
-      cardSubtitle: 'Subtitle 2',
-      cardDetailedText: 'Detailed text 2',
-    },
-    {
-      id: '3',
-      title: 'Third Item',
-      cardTitle: 'Card Title 3',
-      cardSubtitle: 'Subtitle 3',
-      cardDetailedText: 'Detailed text 3',
-    },
-  ];
- 
-  const mockOnTimelineUpdated = vi.fn();
-  const mockHandleTimelineItemClick = vi.fn();
- 
-  beforeEach(() => {
-    vi.clearAllMocks();
-    vi.useFakeTimers();
-  });
- 
-  it('should initialize with empty search state', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    expect(result.current.searchQuery).toBe('');
-    expect(result.current.searchResults).toEqual([]);
-    expect(result.current.currentMatchIndex).toBe(-1);
-  });
- 
-  it('should find matches in searchable text', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('Title 1');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0]);
-    expect(result.current.currentMatchIndex).toBe(0);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(0);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('1');
-  });
- 
-  it('should handle case-insensitive search', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('title 1');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0]);
-    expect(result.current.currentMatchIndex).toBe(0);
-  });
- 
-  it('should navigate between matches', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    // Search for "Title" which appears in all items
-    act(() => {
-      result.current.handleSearchChange('Title');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0, 1, 2]);
-    expect(result.current.currentMatchIndex).toBe(0);
- 
-    // Navigate to next match
-    act(() => {
-      result.current.handleNextMatch();
-    });
- 
-    expect(result.current.currentMatchIndex).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('2');
- 
-    // Navigate to previous match
-    act(() => {
-      result.current.handlePreviousMatch();
-    });
- 
-    expect(result.current.currentMatchIndex).toBe(0);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(0);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('1');
-  });
- 
-  it('should clear search results', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    // First perform a search
-    act(() => {
-      result.current.handleSearchChange('Title');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    // Then clear the search
-    act(() => {
-      result.current.clearSearch();
-    });
- 
-    expect(result.current.searchQuery).toBe('');
-    expect(result.current.searchResults).toEqual([]);
-    expect(result.current.currentMatchIndex).toBe(-1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(0);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('1');
-  });
- 
-  it('should handle empty search query', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([]);
-    expect(result.current.currentMatchIndex).toBe(-1);
-  });
- 
-  it('should handle search in array of detailed text', () => {
-    const itemsWithArrayText = [
-      {
-        ...mockItems[0],
-        cardDetailedText: ['First line', 'Second line'],
-      },
-    ];
- 
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: itemsWithArrayText,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    act(() => {
-      result.current.handleSearchChange('Second line');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    expect(result.current.searchResults).toEqual([0]);
-    expect(result.current.currentMatchIndex).toBe(0);
-  });
- 
-  it('should handle keyboard navigation', () => {
-    const { result } = renderHook(() =>
-      useTimelineSearch({
-        items: mockItems,
-        onTimelineUpdated: mockOnTimelineUpdated,
-        handleTimelineItemClick: mockHandleTimelineItemClick,
-      }),
-    );
- 
-    // First perform a search
-    act(() => {
-      result.current.handleSearchChange('Title');
-    });
- 
-    // Wait for debounce
-    act(() => {
-      vi.advanceTimersByTime(300);
-    });
- 
-    // Simulate Enter key press
-    act(() => {
-      result.current.handleSearchKeyDown({
-        key: 'Enter',
-        preventDefault: vi.fn(),
-        altKey: false,
-        charCode: 0,
-        ctrlKey: false,
-        code: 'Enter',
-        keyCode: 13,
-        metaKey: false,
-        shiftKey: false,
-        getModifierState: vi.fn(),
-        nativeEvent: new KeyboardEvent('keydown'),
-        currentTarget: document.createElement('input'),
-        target: document.createElement('input'),
-        bubbles: true,
-        cancelable: true,
-        defaultPrevented: false,
-        eventPhase: 0,
-        isTrusted: true,
-        timeStamp: Date.now(),
-        type: 'keydown',
-        isDefaultPrevented: vi.fn(),
-        isPropagationStopped: vi.fn(),
-        stopPropagation: vi.fn(),
-      } as unknown as React.KeyboardEvent);
-    });
- 
-    expect(result.current.currentMatchIndex).toBe(1);
-    expect(mockOnTimelineUpdated).toHaveBeenCalledWith(1);
-    expect(mockHandleTimelineItemClick).toHaveBeenCalledWith('2');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useUIState.test.ts.html b/coverage/lcov-report/hooks/__tests__/useUIState.test.ts.html deleted file mode 100644 index 7b71296c1..000000000 --- a/coverage/lcov-report/hooks/__tests__/useUIState.test.ts.html +++ /dev/null @@ -1,286 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useUIState.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useUIState.test.ts

-
- -
- 100% - Statements - 48/48 -
- - -
- 100% - Branches - 17/17 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 48/48 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -681x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -1x -1x -1x -  -1x -  -1x -  -1x -1x -1x - 
import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it } from 'vitest';
-import { useUIState } from '../useUIState';
- 
-describe('useUIState', () => {
-  it('should initialize with the provided state', () => {
-    const { result } = renderHook(() => useUIState<boolean>(true));
- 
-    expect(result.current.state).toBe(true);
-  });
- 
-  it('should toggle boolean state', () => {
-    const { result } = renderHook(() => useUIState<boolean>(true));
- 
-    act(() => {
-      result.current.toggle();
-    });
- 
-    expect(result.current.state).toBe(false);
- 
-    act(() => {
-      result.current.toggle();
-    });
- 
-    expect(result.current.state).toBe(true);
-  });
- 
-  it('should set state to a specific value', () => {
-    const { result } = renderHook(() => useUIState<boolean>(true));
- 
-    act(() => {
-      result.current.setState(false);
-    });
- 
-    expect(result.current.state).toBe(false);
- 
-    act(() => {
-      result.current.setState(true);
-    });
- 
-    expect(result.current.state).toBe(true);
-  });
- 
-  it('should work with different initial states', () => {
-    const { result: resultTrue } = renderHook(() => useUIState<boolean>(true));
-    const { result: resultFalse } = renderHook(() =>
-      useUIState<boolean>(false),
-    );
- 
-    expect(resultTrue.current.state).toBe(true);
-    expect(resultFalse.current.state).toBe(false);
-  });
- 
-  it('should maintain state between renders', () => {
-    const { result, rerender } = renderHook(() => useUIState<boolean>(true));
- 
-    act(() => {
-      result.current.toggle();
-    });
- 
-    expect(result.current.state).toBe(false);
- 
-    rerender();
- 
-    expect(result.current.state).toBe(false);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/__tests__/useWindowSize.test.ts.html b/coverage/lcov-report/hooks/__tests__/useWindowSize.test.ts.html deleted file mode 100644 index 16bb104be..000000000 --- a/coverage/lcov-report/hooks/__tests__/useWindowSize.test.ts.html +++ /dev/null @@ -1,499 +0,0 @@ - - - - - - Code coverage report for hooks/__tests__/useWindowSize.test.ts - - - - - - - - - -
-
-

All files / hooks/__tests__ useWindowSize.test.ts

-
- -
- 95.69% - Statements - 89/93 -
- - -
- 95.23% - Branches - 20/21 -
- - -
- 100% - Functions - 0/0 -
- - -
- 95.69% - Lines - 89/93 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -  -1x -1x -1x -  -1x -1x -  -1x -5x -  -5x -  -5x -5x -  -  -5x -5x -5x -5x -1x -  -1x -5x -  -5x -1x -  -1x -1x -  -1x -1x -1x -  -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x -  -1x -1x -  -  -1x -  -  -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -1x -1x -  -  -1x -  -  -1x -  -1x -1x -  -1x -  -1x -1x -1x -1x -1x -  -1x -1x -  -  -1x -1x -1x -1x -  -  -1x -1x -1x -1x -  -  -1x -1x -1x -  -1x -1x -1x - 
// Mock window before importing the hook
-const mockWindow = {
-  innerWidth: 1024,
-  innerHeight: 768,
-  addEventListener: vi.fn(),
-  removeEventListener: vi.fn(),
-  dispatchEvent: vi.fn(),
-  setTimeout: vi.fn(),
-  clearTimeout: vi.fn(),
-  requestAnimationFrame: vi.fn(),
-  cancelAnimationFrame: vi.fn(),
-};
- 
-// Set up global window for SSR test
-if (typeof window === 'undefined') {
-  global.window = mockWindow as any;
-}
- 
-import { renderHook, act } from '@testing-library/react';
-import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest';
-import { useWindowSize } from '../useWindowSize';
- 
-describe('useWindowSize', () => {
-  const originalWindow = global.window;
- 
-  beforeEach(() => {
-    vi.useFakeTimers();
-    // Mock window for all tests
-    global.window = mockWindow as any;
-    // Reset mock implementations
-    mockWindow.setTimeout.mockImplementation(vi.fn());
-    mockWindow.requestAnimationFrame.mockImplementation((cb) => {
-      cb();
-      return 456;
-    });
-    mockWindow.addEventListener.mockClear();
-    mockWindow.removeEventListener.mockClear();
-    mockWindow.dispatchEvent.mockClear();
-  });
- 
-  afterEach(() => {
-    vi.useRealTimers();
-    // Restore original window
-    global.window = originalWindow;
-  });
- 
-  it('should initialize with current window dimensions', () => {
-    const { result } = renderHook(() => useWindowSize());
- 
-    expect(result.current.width).toBe(mockWindow.innerWidth);
-    expect(result.current.height).toBe(mockWindow.innerHeight);
-  });
- 
-  it('should update dimensions on window resize', () => {
-    const { result } = renderHook(() => useWindowSize());
- 
-    // Mock window resize
-    mockWindow.innerWidth = 800;
-    mockWindow.innerHeight = 600;
- 
-    // Trigger resize event
-    act(() => {
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Wait for debounce and animation frame
-    act(() => {
-      vi.advanceTimersByTime(200); // Advance past debounce time
-    });
- 
-    expect(result.current.width).toBe(800);
-    expect(result.current.height).toBe(600);
-  });
- 
-  it('should debounce resize events', () => {
-    const { result } = renderHook(() => useWindowSize({ debounceMs: 200 }));
- 
-    // Mock window resize
-    mockWindow.innerWidth = 800;
- 
-    // Trigger multiple resize events
-    act(() => {
-      mockWindow.dispatchEvent(new Event('resize'));
-      mockWindow.dispatchEvent(new Event('resize'));
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Should not update immediately
-    expect(result.current.width).toBe(mockWindow.innerWidth);
- 
-    // Wait for debounce and animation frame
-    act(() => {
-      vi.advanceTimersByTime(250); // Advance past debounce time
-    });
- 
-    expect(result.current.width).toBe(800);
-  });
- 
-  // Skip test for SSR environment as it requires special setup
-  it.skip('should handle SSR environment', () => {
-    // Test is skipped - in a real SSR environment, the hook would
-    // initialize with width: 0, height: 0 when window is undefined
-  });
- 
-  it('should cleanup event listeners on unmount', () => {
-    const { unmount } = renderHook(() => useWindowSize());
- 
-    unmount();
- 
-    expect(mockWindow.removeEventListener).toHaveBeenCalledWith(
-      'resize',
-      expect.any(Function),
-    );
-  });
- 
-  it('should handle multiple resize events with different debounce times', () => {
-    const { result } = renderHook(() => useWindowSize({ debounceMs: 100 }));
- 
-    // First resize
-    act(() => {
-      mockWindow.innerWidth = 800;
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Second resize before debounce completes
-    act(() => {
-      mockWindow.innerWidth = 1024;
-      mockWindow.dispatchEvent(new Event('resize'));
-    });
- 
-    // Wait for debounce and animation frame
-    act(() => {
-      vi.advanceTimersByTime(250); // Advance past debounce time
-    });
- 
-    expect(result.current.width).toBe(1024);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/index.html b/coverage/lcov-report/hooks/index.html deleted file mode 100644 index d2654e5fe..000000000 --- a/coverage/lcov-report/hooks/index.html +++ /dev/null @@ -1,326 +0,0 @@ - - - - - - Code coverage report for hooks - - - - - - - - - -
-
-

All files hooks

-
- -
- 92.04% - Statements - 822/893 -
- - -
- 85.45% - Branches - 188/220 -
- - -
- 100% - Functions - 18/18 -
- - -
- 92.04% - Lines - 822/893 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
0%0/5100%1/1100%1/10%0/5
useBackground.ts -
-
100%16/16100%8/8100%2/2100%16/16
useCardSize.ts -
-
88.29%83/9491.66%11/12100%2/288.29%83/94
useEscapeKey.ts -
-
100%36/3692.3%12/13100%1/1100%36/36
useMeasureHeight.ts -
-
100%11/11100%4/4100%1/1100%11/11
useMediaState.ts -
-
100%38/3893.33%14/15100%1/1100%38/38
useOutsideClick.ts -
-
100%33/3391.66%11/12100%1/1100%33/33
useSlideshowProgress.ts -
-
73.33%33/4562.5%5/8100%1/173.33%33/45
useTimelineMedia.ts -
-
91.17%62/6888.88%16/18100%2/291.17%62/68
useTimelineMode.ts -
-
100%36/36100%8/8100%1/1100%36/36
useTimelineNavigation.ts -
-
89.83%212/23683.07%54/65100%1/189.83%212/236
useTimelineScroll.ts -
-
100%54/5490%9/10100%1/1100%54/54
useTimelineSearch.ts -
-
93.71%149/15980.76%21/26100%1/193.71%149/159
useUIState.ts -
-
100%13/13100%4/4100%1/1100%13/13
useWindowSize.ts -
-
93.87%46/4962.5%10/16100%1/193.87%46/49
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/index.ts.html b/coverage/lcov-report/hooks/index.ts.html deleted file mode 100644 index fa15d8473..000000000 --- a/coverage/lcov-report/hooks/index.ts.html +++ /dev/null @@ -1,124 +0,0 @@ - - - - - - Code coverage report for hooks/index.ts - - - - - - - - - -
-
-

All files / hooks index.ts

-
- -
- 0% - Statements - 0/5 -
- - -
- 100% - Branches - 1/1 -
- - -
- 100% - Functions - 1/1 -
- - -
- 0% - Lines - 0/5 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14  -  -  -  -  -  -  -  -  -  -  -  -  - 
/**
- * Centralized export file for all hooks
- * This makes it easier to import hooks across the application
- */
- 
-// Export all hooks from their individual files
-export * from './useBackground';
-export * from './useMeasureHeight';
-export * from './useOutsideClick';
-export * from './useTimelineNavigation';
-export * from './useWindowSize';
- 
-// Add new hooks to this file as they're created
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useBackground.ts.html b/coverage/lcov-report/hooks/useBackground.ts.html deleted file mode 100644 index cc754ce9c..000000000 --- a/coverage/lcov-report/hooks/useBackground.ts.html +++ /dev/null @@ -1,145 +0,0 @@ - - - - - - Code coverage report for hooks/useBackground.ts - - - - - - - - - -
-
-

All files / hooks useBackground.ts

-
- -
- 100% - Statements - 16/16 -
- - -
- 100% - Branches - 8/8 -
- - -
- 100% - Functions - 2/2 -
- - -
- 100% - Lines - 16/16 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -211x -1x -  -  -1x -  -1x -  -1x -16x -16x -13x -1x -1x -1x -1x -1x -11x -16x -16x - 
import { useMemo } from 'react';
-import { hexToRGBA } from '../utils';
- 
-// Pre-compiled regex for better performance
-const HEX_COLOR_REGEX = /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/;
- 
-const isValidHexColor = (color: string): boolean => HEX_COLOR_REGEX.test(color);
- 
-export const useBackground = (color?: string, opacity = 0.8): string => {
-  return useMemo(() => {
-    if (!color) return '';
-    if (!isValidHexColor(color)) {
-      if (process.env.NODE_ENV === 'development') {
-        console.warn(`Invalid hex color: ${color}`);
-      }
-      return '';
-    }
-    return hexToRGBA(color, opacity);
-  }, [color, opacity]);
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useCardSize.ts.html b/coverage/lcov-report/hooks/useCardSize.ts.html deleted file mode 100644 index 997f3c823..000000000 --- a/coverage/lcov-report/hooks/useCardSize.ts.html +++ /dev/null @@ -1,502 +0,0 @@ - - - - - - Code coverage report for hooks/useCardSize.ts - - - - - - - - - -
-
-

All files / hooks useCardSize.ts

-
- -
- 88.29% - Statements - 83/94 -
- - -
- 91.66% - Branches - 11/12 -
- - -
- 100% - Functions - 2/2 -
- - -
- 88.29% - Lines - 83/94 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -1401x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -45x -45x -45x -45x -45x -45x -  -45x -45x -45x -41x -  -45x -  -1x -59x -59x -59x -59x -59x -59x -59x -59x -59x -  -  -59x -  -  -  -  -59x -  -  -59x -41x -  -41x -  -  -  -  -  -  -  -  -  -  -  -  -  -41x -  -41x -38x -38x -  -41x -41x -41x -41x -59x -  -59x -59x -5x -  -4x -4x -4x -  -  -4x -4x -4x -4x -4x -4x -  -4x -4x -4x -4x -4x -4x -4x -5x -59x -59x -  -  -59x -59x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -45x -59x -59x -  -59x -59x -59x -59x -59x -59x -59x - 
import { RefObject, useCallback, useEffect, useMemo, useState, useRef } from 'react';
- 
-interface UseCardSizeProps {
-  containerRef: RefObject<HTMLElement | null>;
-  detailsRef: RefObject<HTMLElement | null>;
-  setStartWidth: (width: number) => void;
-}
- 
-interface UseCardSizeReturn {
-  cardActualHeight: number;
-  detailsHeight: number;
-  textContentLarge: boolean;
-  updateCardSize: (node: HTMLElement | null) => void;
-}
- 
-interface CardDimensions {
-  cardHeight: number;
-  detailsHeight: number;
-  containerWidth: number;
-}
- 
-// Memoized calculation function to prevent unnecessary recalculations
-const calculateTextContentSize = (
-  cardHeight: number,
-  containerHeight: number,
-  scrollHeight: number,
-  clientHeight: number,
-  detailsOffsetTop: number,
-): boolean => {
-  // Use cached values instead of DOM queries
-  const hasSignificantOverflow = scrollHeight > clientHeight + 20;
-  return (
-    cardHeight + detailsOffsetTop > containerHeight + 20 ||
-    hasSignificantOverflow
-  );
-};
- 
-export const useCardSize = ({
-  containerRef,
-  detailsRef,
-  setStartWidth,
-}: UseCardSizeProps): UseCardSizeReturn => {
-  const [dimensions, setDimensions] = useState<CardDimensions>({
-    cardHeight: 0,
-    detailsHeight: 0,
-    containerWidth: 0,
-  });
-  
-  // Cache DOM measurements to avoid repeated calculations
-  const measurementsCache = useRef<{
-    scrollHeight: number;
-    clientHeight: number;
-    offsetTop: number;
-    containerHeight: number;
-  }>({ scrollHeight: 0, clientHeight: 0, offsetTop: 0, containerHeight: 0 });
- 
-  // Throttled resize observer for better performance
-  useEffect(() => {
-    let rafId: number;
-    
-    const observer = new ResizeObserver((entries) => {
-      // Use RAF to batch DOM updates
-      if (rafId) cancelAnimationFrame(rafId);
-      
-      rafId = requestAnimationFrame(() => {
-        for (const entry of entries) {
-          if (entry.target === containerRef.current) {
-            setDimensions((prev) => ({
-              ...prev,
-              containerWidth: entry.contentRect.width,
-            }));
-          }
-        }
-      });
-    });
- 
-    if (containerRef.current) {
-      observer.observe(containerRef.current);
-    }
- 
-    return () => {
-      if (rafId) cancelAnimationFrame(rafId);
-      observer.disconnect();
-    };
-  }, [containerRef]);
- 
-  const updateCardSize = useCallback(
-    (node: HTMLElement | null) => {
-      if (!node || !detailsRef.current) return;
- 
-      const detailsEle = detailsRef.current;
-      const { scrollHeight, offsetHeight, offsetTop } = detailsEle;
-      const containerHeight = node.clientHeight;
- 
-      // Cache measurements
-      measurementsCache.current = {
-        scrollHeight,
-        clientHeight: offsetHeight,
-        offsetTop,
-        containerHeight,
-      };
- 
-      containerRef.current = node;
-      setStartWidth(node.clientWidth);
-      setDimensions({
-        cardHeight: scrollHeight,
-        detailsHeight: offsetHeight,
-        containerWidth: node.clientWidth,
-      });
-    },
-    [detailsRef, setStartWidth, containerRef],
-  );
- 
-  // Optimized memoization with cached measurements
-  const { cardActualHeight, detailsHeight, textContentLarge } = useMemo(
-    () => {
-      const cache = measurementsCache.current;
-      return {
-        cardActualHeight: dimensions.cardHeight,
-        detailsHeight: dimensions.detailsHeight,
-        textContentLarge: calculateTextContentSize(
-          dimensions.cardHeight,
-          dimensions.detailsHeight,
-          cache.containerHeight,
-          cache.scrollHeight,
-          cache.clientHeight,
-        ),
-      };
-    },
-    [dimensions],
-  );
- 
-  return {
-    cardActualHeight,
-    detailsHeight,
-    textContentLarge,
-    updateCardSize,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useEscapeKey.ts.html b/coverage/lcov-report/hooks/useEscapeKey.ts.html deleted file mode 100644 index 15d2e7d65..000000000 --- a/coverage/lcov-report/hooks/useEscapeKey.ts.html +++ /dev/null @@ -1,265 +0,0 @@ - - - - - - Code coverage report for hooks/useEscapeKey.ts - - - - - - - - - -
-
-

All files / hooks useEscapeKey.ts

-
- -
- 100% - Statements - 36/36 -
- - -
- 92.3% - Branches - 12/13 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 36/36 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -611x -  -  -  -  -  -  -  -  -  -  -  -  -44x -44x -44x -44x -44x -44x -44x -44x -44x -44x -  -44x -44x -  -  -44x -21x -44x -  -44x -44x -  -7x -  -  -7x -6x -6x -6x -7x -44x -44x -  -44x -20x -  -20x -  -  -20x -20x -  -20x -19x -19x -44x -44x - 
import { useEffect, useCallback, useRef } from 'react';
- 
-interface UseEscapeKeyOptions {
-  enabled?: boolean;
-  key?: string;
-  keyCode?: number;
-  eventType?: 'keyup' | 'keydown' | 'keypress';
-}
- 
-/**
- * Hook that triggers callback on escape key press
- * Optimized for performance with better event handling
- */
-export default function useEscapeKey(
-  callback: () => void,
-  options: UseEscapeKeyOptions = {},
-) {
-  const {
-    enabled = true,
-    key = 'Escape',
-    keyCode = 27,
-    eventType = 'keyup',
-  } = options;
- 
-  const savedCallback = useRef(callback);
-  const lastEnabled = useRef(enabled);
- 
-  // Update callback reference without causing re-renders
-  useEffect(() => {
-    savedCallback.current = callback;
-  }, [callback]);
- 
-  const handleKey = useCallback(
-    (e: KeyboardEvent) => {
-      // Early return for better performance
-      if (!lastEnabled.current) return;
-      
-      // Prefer modern 'key' property over deprecated keyCode
-      if (e.key === key || (e.key === undefined && e.keyCode === keyCode)) {
-        e.preventDefault();
-        savedCallback.current();
-      }
-    },
-    [key, keyCode],
-  );
- 
-  useEffect(() => {
-    lastEnabled.current = enabled;
-    
-    if (!enabled) return;
- 
-    // Use passive listeners where possible for better scroll performance
-    const options = eventType === 'keyup' ? { passive: false } : undefined;
-    document.addEventListener(eventType, handleKey, options);
-    
-    return () => {
-      document.removeEventListener(eventType, handleKey);
-    };
-  }, [eventType, handleKey, enabled]);
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useMeasureHeight.ts.html b/coverage/lcov-report/hooks/useMeasureHeight.ts.html deleted file mode 100644 index 8cda00fd9..000000000 --- a/coverage/lcov-report/hooks/useMeasureHeight.ts.html +++ /dev/null @@ -1,136 +0,0 @@ - - - - - - Code coverage report for hooks/useMeasureHeight.ts - - - - - - - - - -
-
-

All files / hooks useMeasureHeight.ts

-
- -
- 100% - Statements - 11/11 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 11/11 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -181x -  -  -  -  -  -  -1x -11x -11x -6x -3x -3x -6x -11x -11x -11x - 
import { useCallback } from 'react';
- 
-/**
- * Hook to measure the height of a DOM element
- * @param onRender - Callback function that receives the element height
- * @returns Callback ref to attach to the element to measure
- */
-export const useMeasureHeight = (onRender?: (height: number) => void) => {
-  return useCallback(
-    (node: HTMLDivElement | null) => {
-      if (node && onRender) {
-        requestAnimationFrame(() => onRender(node.clientHeight));
-      }
-    },
-    [onRender],
-  );
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useMediaState.ts.html b/coverage/lcov-report/hooks/useMediaState.ts.html deleted file mode 100644 index a9b6dedf5..000000000 --- a/coverage/lcov-report/hooks/useMediaState.ts.html +++ /dev/null @@ -1,280 +0,0 @@ - - - - - - Code coverage report for hooks/useMediaState.ts - - - - - - - - - -
-
-

All files / hooks useMediaState.ts

-
- -
- 100% - Statements - 38/38 -
- - -
- 93.33% - Branches - 14/15 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 38/38 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -661x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -14x -14x -14x -14x -14x -14x -14x -  -  -14x -9x -14x -  -14x -14x -  -9x -1x -1x -1x -  -  -9x -9x -4x -4x -  -  -9x -1x -1x -9x -14x -14x -  -14x -10x -14x -  -  -14x -  -14x -14x -14x -14x -14x -14x - 
import { useCallback, useEffect, useState, useRef } from 'react';
-import { MediaState } from '../models/TimelineMediaModel';
- 
-interface UseMediaStateProps {
-  slideShowActive: boolean;
-  paused: boolean;
-  id?: string;
-  onElapsed?: (id: string) => void;
-}
- 
-interface UseMediaStateReturn {
-  isPlaying: boolean;
-  handleMediaState: (state: MediaState) => void;
-  cleanup: () => void;
-}
- 
-export const useMediaState = ({
-  slideShowActive,
-  paused,
-  id,
-  onElapsed,
-}: UseMediaStateProps): UseMediaStateReturn => {
-  const [isPlaying, setIsPlaying] = useState(false);
-  const onElapsedRef = useRef(onElapsed);
- 
-  // Keep callback ref updated without triggering re-renders
-  useEffect(() => {
-    onElapsedRef.current = onElapsed;
-  }, [onElapsed]);
- 
-  const handleMediaState = useCallback(
-    (state: MediaState) => {
-      // Early return for inactive slideshow
-      if (!slideShowActive) {
-        if (isPlaying) setIsPlaying(false);
-        return;
-      }
- 
-      // Batch state updates when possible
-      const shouldSetPlaying = state.playing ?? false;
-      if (isPlaying !== shouldSetPlaying) {
-        setIsPlaying(shouldSetPlaying);
-      }
- 
-      // Handle elapsed callback with stable reference
-      if (state.paused && paused && id && onElapsedRef.current) {
-        onElapsedRef.current(id);
-      }
-    },
-    [slideShowActive, paused, id, isPlaying],
-  );
- 
-  const cleanup = useCallback(() => {
-    setIsPlaying(false);
-  }, []);
- 
-  // Clean up on unmount
-  useEffect(() => cleanup, [cleanup]);
- 
-  return {
-    isPlaying,
-    handleMediaState,
-    cleanup,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useOutsideClick.ts.html b/coverage/lcov-report/hooks/useOutsideClick.ts.html deleted file mode 100644 index b86d4a420..000000000 --- a/coverage/lcov-report/hooks/useOutsideClick.ts.html +++ /dev/null @@ -1,244 +0,0 @@ - - - - - - Code coverage report for hooks/useOutsideClick.ts - - - - - - - - - -
-
-

All files / hooks useOutsideClick.ts

-
- -
- 100% - Statements - 33/33 -
- - -
- 91.66% - Branches - 11/12 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 33/33 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -541x -  -  -  -  -  -  -  -  -  -  -47x -47x -47x -47x -47x -47x -47x -47x -  -  -47x -22x -47x -  -47x -47x -  -14x -  -14x -14x -7x -7x -7x -14x -47x -47x -  -47x -23x -  -23x -  -  -23x -23x -  -23x -21x -21x -47x -47x - 
import { RefObject, useEffect, useCallback, useRef } from 'react';
- 
-interface UseOutsideClickOptions {
-  eventType?: 'click' | 'mousedown' | 'touchstart';
-  enabled?: boolean;
-}
- 
-/**
- * Hook that triggers callback when clicking outside a referenced element
- * Optimized for performance with better event handling
- */
-export default function useOutsideClick(
-  el: RefObject<HTMLElement | null>,
-  callback: () => void,
-  options: UseOutsideClickOptions = {},
-) {
-  const { eventType = 'click', enabled = true } = options;
-  const savedCallback = useRef(callback);
-  const lastEnabled = useRef(enabled);
- 
-  // Update callback reference without causing re-renders
-  useEffect(() => {
-    savedCallback.current = callback;
-  }, [callback]);
- 
-  const handleClick = useCallback(
-    (e: MouseEvent | TouchEvent) => {
-      // Early return for better performance
-      if (!lastEnabled.current) return;
- 
-      const element = el.current;
-      if (element && !element.contains(e.target as Node)) {
-        e.preventDefault();
-        savedCallback.current();
-      }
-    },
-    [el],
-  );
- 
-  useEffect(() => {
-    lastEnabled.current = enabled;
-    
-    if (!enabled) return;
- 
-    // Use passive listeners for touch events for better scroll performance
-    const options = eventType === 'touchstart' ? { passive: false } : undefined;
-    document.addEventListener(eventType, handleClick, options);
-    
-    return () => {
-      document.removeEventListener(eventType, handleClick);
-    };
-  }, [eventType, handleClick, enabled]);
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useSlideshowProgress.ts.html b/coverage/lcov-report/hooks/useSlideshowProgress.ts.html deleted file mode 100644 index 28bcc0685..000000000 --- a/coverage/lcov-report/hooks/useSlideshowProgress.ts.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - Code coverage report for hooks/useSlideshowProgress.ts - - - - - - - - - -
-
-

All files / hooks useSlideshowProgress.ts

-
- -
- 73.33% - Statements - 33/45 -
- - -
- 62.5% - Branches - 5/8 -
- - -
- 100% - Functions - 1/1 -
- - -
- 73.33% - Lines - 33/45 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -841x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -8x -8x -8x -8x -8x -8x -8x -8x -  -  -8x -12x -  -  -  -8x -  -  -8x -6x -6x -6x -6x -8x -  -  -8x -6x -  -  -  -8x -  -  -8x -  -  -  -8x -  -  -8x -  -  -  -8x -  -  -8x -  -8x -8x -8x -8x -8x -8x - 
import { useCallback, useEffect, useState, useRef } from 'react';
- 
-interface UseSlideshowProgressProps {
-  /** Whether the slideshow is currently running */
-  slideShowRunning: boolean;
-  /** Current active timeline item index */
-  activeTimelineItem: number;
-  /** Total number of timeline items */
-  totalItems: number;
-  /** Duration of each slide in milliseconds */
-  slideItemDuration: number;
-}
- 
-interface SlideshowProgressState {
-  /** Whether the slideshow progress is paused */
-  isPaused: boolean;
-  /** Pause the slideshow progress */
-  pauseProgress: () => void;
-  /** Resume the slideshow progress */
-  resumeProgress: () => void;
-}
- 
-/**
- * Custom hook to manage overall slideshow progress state
- * Optimized for performance with better timeout management
- */
-export const useSlideshowProgress = ({
-  slideShowRunning,
-  activeTimelineItem,
-  totalItems,
-  slideItemDuration,
-}: UseSlideshowProgressProps): SlideshowProgressState => {
-  const [isPaused, setIsPaused] = useState(false);
-  const pauseTimeoutRef = useRef<NodeJS.Timeout | null>(null);
-  const lastActiveItem = useRef(activeTimelineItem);
- 
-  // Efficient cleanup function
-  const clearTimeouts = useCallback(() => {
-    if (pauseTimeoutRef.current) {
-      clearTimeout(pauseTimeoutRef.current);
-      pauseTimeoutRef.current = null;
-    }
-  }, []);
- 
-  // Clean up timeout when slideshow stops
-  useEffect(() => {
-    if (!slideShowRunning) {
-      setIsPaused(false);
-      clearTimeouts();
-    }
-  }, [slideShowRunning, clearTimeouts]);
- 
-  // Reset pause state when active item changes (optimized)
-  useEffect(() => {
-    if (slideShowRunning && lastActiveItem.current !== activeTimelineItem) {
-      lastActiveItem.current = activeTimelineItem;
-      if (isPaused) setIsPaused(false);
-    }
-  }, [activeTimelineItem, slideShowRunning, isPaused]);
- 
-  // Pause the progress
-  const pauseProgress = useCallback(() => {
-    if (slideShowRunning && !isPaused) {
-      setIsPaused(true);
-    }
-  }, [slideShowRunning, isPaused]);
- 
-  // Resume the progress
-  const resumeProgress = useCallback(() => {
-    if (slideShowRunning && isPaused) {
-      setIsPaused(false);
-    }
-  }, [slideShowRunning, isPaused]);
- 
-  // Cleanup on unmount
-  useEffect(() => clearTimeouts, [clearTimeouts]);
- 
-  return {
-    isPaused,
-    pauseProgress,
-    resumeProgress,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useTimelineMedia.ts.html b/coverage/lcov-report/hooks/useTimelineMedia.ts.html deleted file mode 100644 index bbf08f871..000000000 --- a/coverage/lcov-report/hooks/useTimelineMedia.ts.html +++ /dev/null @@ -1,373 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineMedia.ts - - - - - - - - - -
-
-

All files / hooks useTimelineMedia.ts

-
- -
- 91.17% - Statements - 62/68 -
- - -
- 88.88% - Branches - 16/18 -
- - -
- 100% - Functions - 2/2 -
- - -
- 91.17% - Lines - 62/68 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -971x -1x -  -  -  -  -  -  -  -  -  -1x -12x -12x -12x -12x -12x -  -  -12x -  -2x -2x -4x -4x -2x -2x -2x -2x -2x -2x -2x -12x -  -  -12x -8x -  -  -  -  -8x -8x -8x -8x -8x -  -8x -12x -  -  -12x -  -10x -  -8x -  -  -8x -8x -  -8x -8x -8x -8x -  -8x -8x -8x -  -6x -6x -18x -18x -18x -18x -6x -8x -  -8x -8x -8x -8x -12x -  -  -12x -  -  -12x -  -12x -12x -12x -12x -12x - 
import { useRef, useEffect, useCallback } from 'react';
-import {
-  toggleMediaVisibility,
-  pauseVideoEmbeds,
-} from '../utils/timelineUtils';
- 
-interface UseTimelineMediaProps {
-  mode: string;
-  timelineMainRef: React.RefObject<HTMLDivElement>;
-}
- 
-export const useTimelineMedia = ({
-  mode,
-  timelineMainRef,
-}: UseTimelineMediaProps) => {
-  const observer = useRef<IntersectionObserver | null>(null);
-  const observedElements = useRef<Set<Element>>(new Set());
- 
-  // Optimized intersection callback with batched operations
-  const handleIntersection = useCallback((entries: IntersectionObserverEntry[]) => {
-    // Use requestAnimationFrame to batch DOM operations
-    requestAnimationFrame(() => {
-      entries.forEach((entry) => {
-        const element = entry.target as HTMLDivElement;
-        if (entry.isIntersecting) {
-          toggleMediaVisibility(element, true);
-        } else {
-          toggleMediaVisibility(element, false);
-          pauseVideoEmbeds(element);
-        }
-      });
-    });
-  }, []);
- 
-  // Memoized observer creation
-  const createObserver = useCallback(() => {
-    if (observer.current) {
-      observer.current.disconnect();
-      observedElements.current.clear();
-    }
- 
-    observer.current = new IntersectionObserver(handleIntersection, {
-      root: timelineMainRef.current,
-      threshold: 0.1, // Slightly higher threshold for better performance
-      rootMargin: '50px', // Preload content slightly before it becomes visible
-    });
- 
-    return observer.current;
-  }, [handleIntersection, timelineMainRef]);
- 
-  // Setup IntersectionObserver for efficient media handling
-  useEffect(() => {
-    // Skip horizontal mode as before
-    if (mode === 'HORIZONTAL') return;
- 
-    const observerInstance = createObserver();
- 
-    // Use requestIdleCallback for better performance if available
-    const scheduleObservation = (callback: () => void) => {
-      if ('requestIdleCallback' in window) {
-        (window as any).requestIdleCallback(callback, { timeout: 100 });
-      } else {
-        requestAnimationFrame(callback);
-      }
-    };
- 
-    scheduleObservation(() => {
-      const element = timelineMainRef.current;
-      if (!element || !observerInstance) return;
- 
-      const childElements = element.querySelectorAll('.vertical-item-row');
-      childElements.forEach((elem) => {
-        if (!observedElements.current.has(elem)) {
-          observerInstance.observe(elem);
-          observedElements.current.add(elem);
-        }
-      });
-    });
- 
-    return () => {
-      observerInstance?.disconnect();
-      observedElements.current.clear();
-    };
-  }, [mode, createObserver, timelineMainRef]);
- 
-  // Cleanup function for external use
-  const cleanup = useCallback(() => {
-    observer.current?.disconnect();
-    observedElements.current.clear();
-  }, []);
- 
-  return {
-    observer,
-    cleanup,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useTimelineMode.ts.html b/coverage/lcov-report/hooks/useTimelineMode.ts.html deleted file mode 100644 index 1d946bd1e..000000000 --- a/coverage/lcov-report/hooks/useTimelineMode.ts.html +++ /dev/null @@ -1,253 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineMode.ts - - - - - - - - - -
-
-

All files / hooks useTimelineMode.ts

-
- -
- 100% - Statements - 36/36 -
- - -
- 100% - Branches - 8/8 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 36/36 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -571x -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -24x -24x -24x -24x -24x -24x -1x -23x -24x -  -24x -  -  -24x -  -24x -24x -9x -9x -  -8x -  -  -9x -6x -6x -6x -9x -24x -24x -  -24x -24x -24x -24x -24x - 
import { useState, useCallback, useRef } from 'react';
-import { TimelineMode } from '@models/TimelineModel';
- 
-type ExtendedTimelineMode = TimelineMode | 'HORIZONTAL_ALL';
- 
-interface UseTimelineModeProps {
-  initialMode: TimelineMode;
-  showAllCardsHorizontal?: boolean;
-  updateHorizontalAllCards?: (showAll: boolean) => void;
-}
- 
-// Optimized mode mapping for better performance
-const MODE_MAPPINGS: Record<string, ExtendedTimelineMode> = {
-  'VERTICAL': 'VERTICAL',
-  'HORIZONTAL': 'HORIZONTAL',
-  'VERTICAL_ALTERNATING': 'VERTICAL_ALTERNATING',
-  'HORIZONTAL_ALL': 'HORIZONTAL_ALL',
-} as const;
- 
-export const useTimelineMode = ({
-  initialMode,
-  showAllCardsHorizontal = false,
-  updateHorizontalAllCards,
-}: UseTimelineModeProps) => {
-  const [timelineMode, setTimelineMode] = useState<ExtendedTimelineMode>(
-    initialMode === 'HORIZONTAL' && showAllCardsHorizontal
-      ? 'HORIZONTAL_ALL'
-      : initialMode,
-  );
-  
-  const updateHorizontalAllCardsRef = useRef(updateHorizontalAllCards);
- 
-  // Keep callback ref updated without triggering re-renders
-  updateHorizontalAllCardsRef.current = updateHorizontalAllCards;
- 
-  const handleTimelineUpdate = useCallback(
-    (newMode: string) => {
-      const mappedMode = MODE_MAPPINGS[newMode];
-      if (!mappedMode || mappedMode === timelineMode) return;
- 
-      setTimelineMode(mappedMode);
- 
-      // Handle horizontal cards update with stable reference
-      if (updateHorizontalAllCardsRef.current) {
-        const shouldShowAll = mappedMode === 'HORIZONTAL_ALL';
-        updateHorizontalAllCardsRef.current(shouldShowAll);
-      }
-    },
-    [timelineMode],
-  );
- 
-  return {
-    timelineMode,
-    handleTimelineUpdate,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useTimelineNavigation.ts.html b/coverage/lcov-report/hooks/useTimelineNavigation.ts.html deleted file mode 100644 index a28c99570..000000000 --- a/coverage/lcov-report/hooks/useTimelineNavigation.ts.html +++ /dev/null @@ -1,1057 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineNavigation.ts - - - - - - - - - -
-
-

All files / hooks useTimelineNavigation.ts

-
- -
- 89.83% - Statements - 212/236 -
- - -
- 83.07% - Branches - 54/65 -
- - -
- 100% - Functions - 1/1 -
- - -
- 89.83% - Lines - 212/236 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -270 -271 -272 -273 -274 -275 -276 -277 -278 -279 -280 -281 -282 -283 -284 -285 -286 -287 -288 -289 -290 -291 -292 -293 -294 -295 -296 -297 -298 -299 -300 -301 -302 -303 -304 -305 -306 -307 -308 -309 -310 -311 -312 -313 -314 -315 -316 -317 -318 -319 -320 -321 -322 -323 -324 -3251x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -  -  -23x -23x -23x -23x -23x -23x -23x -  -  -23x -21x -21x -69x -69x -69x -21x -21x -23x -  -  -23x -23x -19x -  -  -15x -15x -1x -1x -  -  -14x -14x -  -  -  -  -  -15x -  -  -18x -19x -23x -23x -  -  -23x -23x -2x -  -  -2x -2x -  -  -2x -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -1x -1x -1x -2x -2x -23x -23x -  -  -23x -23x -5x -  -5x -5x -1x -4x -  -5x -5x -23x -23x -  -  -23x -23x -6x -  -  -6x -6x -  -  -5x -  -  -6x -  -  -6x -3x -3x -  -  -6x -  -1x -1x -1x -  -1x -1x -1x -  -  -  -1x -6x -23x -23x -  -  -23x -23x -23x -23x -  -  -23x -7x -  -6x -6x -6x -6x -  -  -6x -6x -  -6x -6x -6x -6x -23x -  -23x -5x -  -4x -4x -4x -4x -  -  -4x -4x -  -4x -4x -4x -4x -23x -  -23x -3x -2x -2x -2x -  -  -2x -2x -  -2x -2x -2x -2x -23x -  -23x -5x -4x -4x -4x -4x -  -  -4x -4x -  -4x -4x -4x -4x -23x -  -  -23x -23x -9x -  -9x -  -  -9x -9x -1x -1x -1x -9x -1x -1x -1x -9x -  -  -9x -4x -2x -2x -2x -2x -2x -2x -9x -3x -2x -2x -3x -1x -1x -1x -3x -9x -23x -23x -  -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x -23x - 
import { useCallback, useRef, useMemo } from 'react';
-import { findTimelineElement } from '../utils/timelineUtils';
-import { TimelineMode } from '@models/TimelineModel';
- 
-type ExtendedTimelineMode = TimelineMode | 'HORIZONTAL_ALL';
- 
-interface UseTimelineNavigationProps {
-  items: any[]; // Use any to avoid type conflicts
-  mode: string;
-  timelineId: string;
-  hasFocus: boolean;
-  flipLayout?: boolean;
-  slideShowRunning?: boolean;
-  onTimelineUpdated?: (index: number) => void;
-  onNext?: () => void;
-  onPrevious?: () => void;
-  onFirst?: () => void;
-  onLast?: () => void;
-}
- 
-// Optimized scroll options for different modes
-const SCROLL_OPTIONS = {
-  HORIZONTAL: {
-    behavior: 'smooth' as ScrollBehavior,
-    block: 'nearest' as ScrollLogicalPosition,
-    inline: 'center' as ScrollLogicalPosition,
-  },
-  VERTICAL: {
-    behavior: 'smooth' as ScrollBehavior,
-    block: 'center' as ScrollLogicalPosition,
-    inline: 'center' as ScrollLogicalPosition,
-  },
-} as const;
- 
-export const useTimelineNavigation = ({
-  items,
-  mode,
-  timelineId,
-  hasFocus,
-  flipLayout = false,
-  slideShowRunning = false,
-  onTimelineUpdated,
-  onNext,
-  onPrevious,
-  onFirst,
-  onLast,
-}: UseTimelineNavigationProps) => {
-  const activeItemIndex = useRef<number>(0);
-  const callbacksRef = useRef({
-    onTimelineUpdated,
-    onNext,
-    onPrevious,
-    onFirst,
-    onLast,
-  });
- 
-  // Keep callbacks ref updated without triggering re-renders
-  callbacksRef.current = {
-    onTimelineUpdated,
-    onNext,
-    onPrevious,
-    onFirst,
-    onLast,
-  };
- 
-  // Memoize items lookup map for O(1) access
-  const itemsMap = useMemo(() => {
-    const map = new Map<string, number>();
-    items.forEach((item, index) => {
-      if (item?.id) {
-        map.set(item.id, index);
-      }
-    });
-    return map;
-  }, [items]);
- 
-  // Find target element in the DOM (memoized)
-  const findTargetElement = useCallback(
-    (itemId: string) => {
-      if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        // For vertical modes, directly search for the vertical-item-row
-        // This is more reliable than using findTimelineElement and then looking for a parent
-        const verticalItemRow = document.querySelector(`[data-testid="vertical-item-row"][data-item-id="${itemId}"]`);
-        if (verticalItemRow) {
-          return verticalItemRow as HTMLElement;
-        }
-        
-        // Fallback: try to find the card content element and then get its parent row
-        const cardContent = document.querySelector(`.timeline-card-content[data-item-id="${itemId}"]`);
-        if (cardContent) {
-          const row = cardContent.closest('[data-testid="vertical-item-row"]');
-          if (row) {
-            return row as HTMLElement;
-          }
-        }
-      }
-      
-      // Default behavior for horizontal modes or fallback
-      return findTimelineElement(itemId, mode, timelineId);
-    },
-    [mode, timelineId],
-  );
- 
-  // Optimized scroll function - matches timeline card content behavior
-  const scrollToElement = useCallback(
-    (element: HTMLElement, mode: string) => {
-      if (!element) return;
-      
-      // Ensure we handle the scroll in the next animation frame for smoother transitions
-      requestAnimationFrame(() => {
-        const isVerticalMode = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-        
-        // Check if scrollIntoView is available (it may not be in test environments like JSDOM)
-        if (typeof element.scrollIntoView === 'function') {
-          if (isVerticalMode) {
-            // For vertical modes, ensure we fully center the element in the viewport
-            element.scrollIntoView({
-              behavior: 'smooth',
-              block: 'center', // Always center vertically
-              inline: 'nearest' // Nearest horizontal positioning
-            });
-            
-            // Add a second scroll with a slight delay to ensure proper centering
-            // This addresses issues with complex layouts and varying element heights
-            setTimeout(() => {
-              if (typeof element.scrollIntoView === 'function') {
-                element.scrollIntoView({
-                  behavior: 'smooth',
-                  block: 'center',
-                  inline: 'nearest'
-                });
-              }
-            }, 50);
-          } else {
-            // In horizontal mode, use horizontal centering
-            element.scrollIntoView(SCROLL_OPTIONS.HORIZONTAL);
-          }
-        }
-      });
-    },
-    [],
-  );
- 
-  // Update timeline position (optimized)
-  const updateTimelinePosition = useCallback(
-    (targetIndex: number, isSlideShow?: boolean) => {
-      activeItemIndex.current = targetIndex;
- 
-      const updateIndex =
-        isSlideShow && targetIndex < items.length - 1
-          ? targetIndex + 1
-          : targetIndex;
- 
-      callbacksRef.current.onTimelineUpdated?.(updateIndex);
-    },
-    [items.length],
-  );
- 
-  // Handle timeline item click (significantly optimized)
-  const handleTimelineItemClick = useCallback(
-    (itemId?: string, isSlideShow?: boolean) => {
-      if (!itemId) return;
- 
-      // Use memoized map for O(1) lookup
-      const targetIndex = itemsMap.get(itemId);
-      if (targetIndex === undefined) return;
- 
-      // Update timeline position
-      updateTimelinePosition(targetIndex, isSlideShow);
- 
-      // Skip scrolling in horizontal mode when slideshow is running to prevent toolbar hiding
-      if (mode === 'HORIZONTAL' && slideShowRunning) return;
- 
-      // For vertical modes, directly find and scroll to the vertical item row
-      if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        const targetElement = findTargetElement(itemId);
-        if (targetElement) {
-          scrollToElement(targetElement, mode);
-        }
-      } else {
-        // For horizontal modes, use the original approach
-        const timelinePointElement = document.getElementById(
-          `timeline-${mode.toLowerCase()}-item-${itemId}`
-        );
-        
-        if (timelinePointElement) {
-          scrollToElement(timelinePointElement, mode);
-        } else {
-          const targetElement = findTargetElement(itemId);
-          if (targetElement) scrollToElement(targetElement, mode);
-        }
-      }
-    },
-    [itemsMap, updateTimelinePosition, findTargetElement, mode, scrollToElement, slideShowRunning],
-  );
- 
-  // Handler for item elapsed (used in slideshow)
-  const handleTimelineItemElapsed = useCallback(
-    (itemId?: string) => handleTimelineItemClick(itemId, true),
-    [handleTimelineItemClick],
-  );
- 
-  // Navigation handlers (optimized with bounds checking and focus behavior)
-  const handleNext = useCallback(() => {
-    if (!hasFocus) return;
-    
-    const newIndex = Math.min(activeItemIndex.current + 1, items.length - 1);
-    if (newIndex !== activeItemIndex.current) {
-      activeItemIndex.current = newIndex;
-      callbacksRef.current.onNext?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[newIndex];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  const handlePrevious = useCallback(() => {
-    if (!hasFocus) return;
-    
-    const newIndex = Math.max(activeItemIndex.current - 1, 0);
-    if (newIndex !== activeItemIndex.current) {
-      activeItemIndex.current = newIndex;
-      callbacksRef.current.onPrevious?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[newIndex];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  const handleFirst = useCallback(() => {
-    if (!hasFocus) return;
-    if (activeItemIndex.current !== 0) {
-      activeItemIndex.current = 0;
-      callbacksRef.current.onFirst?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[0];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  const handleLast = useCallback(() => {
-    if (!hasFocus) return;
-    const lastIndex = items.length - 1;
-    if (activeItemIndex.current !== lastIndex) {
-      activeItemIndex.current = lastIndex;
-      callbacksRef.current.onLast?.();
-      
-      // Trigger the same focus behavior as clicking
-      const targetItem = items[lastIndex];
-      if (targetItem?.id) {
-        // Find and scroll to the target element
-        const targetElement = findTargetElement(targetItem.id);
-        if (targetElement) scrollToElement(targetElement, mode);
-      }
-    }
-  }, [hasFocus, items, findTargetElement, mode, scrollToElement]);
- 
-  // Keyboard navigation (optimized with key mapping)
-  const handleKeySelection = useCallback(
-    (event: React.KeyboardEvent<HTMLDivElement>) => {
-      if (!hasFocus) return; // Add hasFocus check here
-      
-      const { key } = event;
- 
-      // Common handlers
-      switch (key) {
-        case 'Home':
-          event.preventDefault();
-          handleFirst();
-          return;
-        case 'End':
-          event.preventDefault();
-          handleLast();
-          return;
-      }
- 
-      // Mode-specific handlers
-      if (mode === 'HORIZONTAL') {
-        if (key === 'ArrowRight') {
-          event.preventDefault();
-          flipLayout ? handlePrevious() : handleNext();
-        } else if (key === 'ArrowLeft') {
-          event.preventDefault();
-          flipLayout ? handleNext() : handlePrevious();
-        }
-      } else if (mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING') {
-        if (key === 'ArrowDown') {
-          event.preventDefault();
-          handleNext();
-        } else if (key === 'ArrowUp') {
-          event.preventDefault();
-          handlePrevious();
-        }
-      }
-    },
-    [mode, flipLayout, hasFocus, handleNext, handlePrevious, handleFirst, handleLast],
-  );
- 
-  return {
-    activeItemIndex,
-    handleTimelineItemClick,
-    handleTimelineItemElapsed,
-    handleNext,
-    handlePrevious,
-    handleFirst,
-    handleLast,
-    handleKeySelection,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useTimelineScroll.ts.html b/coverage/lcov-report/hooks/useTimelineScroll.ts.html deleted file mode 100644 index 7bc1f27bf..000000000 --- a/coverage/lcov-report/hooks/useTimelineScroll.ts.html +++ /dev/null @@ -1,307 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineScroll.ts - - - - - - - - - -
-
-

All files / hooks useTimelineScroll.ts

-
- -
- 100% - Statements - 54/54 -
- - -
- 90% - Branches - 9/10 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 54/54 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -751x -  -  -  -  -  -  -  -  -1x -13x -13x -13x -13x -13x -13x -13x -13x -13x -  -  -13x -13x -  -  -13x -13x -3x -3x -2x -2x -3x -13x -13x -  -  -13x -13x -3x -  -  -3x -1x -1x -  -3x -2x -  -2x -  -2x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -3x -3x -13x -13x -  -13x -13x -13x -13x -13x -13x -13x - 
import { useCallback, useRef } from 'react';
-import { Scroll } from '@models/TimelineHorizontalModel';
- 
-interface UseTimelineScrollProps {
-  mode: string;
-  onScrollEnd?: () => void;
-  setNewOffset: (element: HTMLDivElement, scroll: Partial<Scroll>) => void;
-}
- 
-export const useTimelineScroll = ({
-  mode,
-  onScrollEnd,
-  setNewOffset,
-}: UseTimelineScrollProps) => {
-  const timelineMainRef = useRef<HTMLDivElement>(null);
-  const horizontalContentRef = useRef<HTMLDivElement | null>(null);
-  const scrollTimeoutRef = useRef<NodeJS.Timeout | null>(null);
-  const setNewOffsetRef = useRef(setNewOffset);
-  const onScrollEndRef = useRef(onScrollEnd);
- 
-  // Keep refs updated without triggering re-renders
-  setNewOffsetRef.current = setNewOffset;
-  onScrollEndRef.current = onScrollEnd;
- 
-  // Handle scrolling (optimized with stable reference)
-  const handleScroll = useCallback(
-    (scroll: Partial<Scroll>) => {
-      const element = timelineMainRef.current;
-      if (element && setNewOffsetRef.current) {
-        setNewOffsetRef.current(element, scroll);
-      }
-    },
-    [],
-  );
- 
-  // Optimized scroll handler with throttling
-  const handleMainScroll = useCallback(
-    (ev: React.UIEvent<HTMLDivElement>) => {
-      const target = ev.target as HTMLElement;
-      
-      // Throttle scroll end detection for better performance
-      if (scrollTimeoutRef.current) {
-        clearTimeout(scrollTimeoutRef.current);
-      }
- 
-      scrollTimeoutRef.current = setTimeout(() => {
-        if (!onScrollEndRef.current) return;
- 
-        const isVertical = mode === 'VERTICAL' || mode === 'VERTICAL_ALTERNATING';
-        
-        if (isVertical) {
-          const scrolled = target.scrollTop + target.clientHeight;
-          const threshold = target.scrollHeight - 1;
-          if (scrolled >= threshold) {
-            onScrollEndRef.current();
-          }
-        } else {
-          const scrolled = target.scrollLeft + target.offsetWidth;
-          if (target.scrollWidth <= scrolled) {
-            onScrollEndRef.current();
-          }
-        }
-      }, 100); // Throttle to 100ms
-    },
-    [mode],
-  );
- 
-  return {
-    timelineMainRef,
-    horizontalContentRef,
-    handleScroll,
-    handleMainScroll,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useTimelineSearch.ts.html b/coverage/lcov-report/hooks/useTimelineSearch.ts.html deleted file mode 100644 index 8af2a4c63..000000000 --- a/coverage/lcov-report/hooks/useTimelineSearch.ts.html +++ /dev/null @@ -1,688 +0,0 @@ - - - - - - Code coverage report for hooks/useTimelineSearch.ts - - - - - - - - - -
-
-

All files / hooks useTimelineSearch.ts

-
- -
- 93.71% - Statements - 149/159 -
- - -
- 80.76% - Branches - 21/26 -
- - -
- 100% - Functions - 1/1 -
- - -
- 93.71% - Lines - 149/159 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -2021x -  -1x -1x -  -  -  -  -  -  -  -1x -33x -33x -33x -33x -33x -33x -33x -33x -33x -  -  -33x -33x -  -33x -33x -  -  -33x -16x -54x -54x -54x -54x -54x -1x -53x -54x -  -54x -54x -54x -54x -54x -16x -33x -  -  -33x -  -9x -8x -  -  -  -  -9x -33x -  -  -33x -33x -7x -7x -1x -1x -1x -1x -  -6x -6x -  -  -7x -16x -12x -12x -16x -  -6x -  -6x -6x -6x -6x -6x -6x -6x -6x -6x -7x -  -  -  -7x -33x -33x -  -  -33x -33x -33x -33x -33x -  -33x -33x -7x -7x -7x -33x -33x -  -33x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -33x -  -  -33x -33x -3x -  -3x -3x -2x -1x -  -3x -  -3x -3x -  -3x -3x -  -3x -  -3x -3x -3x -3x -3x -33x -33x -  -33x -33x -33x -33x -  -33x -33x -33x -33x -  -33x -33x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -  -1x -1x -33x -33x -  -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x -33x - 
import { useCallback, useState, useRef, useMemo } from 'react';
-import { TimelineCardModel } from '@models/TimelineItemModel';
-import { getSearchableText } from '../utils/timelineUtils';
-import { useDebouncedCallback } from 'use-debounce';
- 
-interface UseTimelineSearchProps {
-  items: TimelineCardModel[];
-  onTimelineUpdated?: (index: number) => void;
-  handleTimelineItemClick: (itemId?: string) => void;
-}
- 
-export const useTimelineSearch = ({
-  items,
-  onTimelineUpdated,
-  handleTimelineItemClick,
-}: UseTimelineSearchProps) => {
-  const [searchQuery, setSearchQuery] = useState('');
-  const [searchResults, setSearchResults] = useState<number[]>([]);
-  const [currentMatchIndex, setCurrentMatchIndex] = useState(-1);
-  const searchInputRef = useRef<HTMLInputElement>(null);
-  const activeItemIndex = useRef<number>(0);
-  
-  // Cache callback refs to prevent unnecessary re-renders
-  const onTimelineUpdatedRef = useRef(onTimelineUpdated);
-  const handleTimelineItemClickRef = useRef(handleTimelineItemClick);
-  
-  onTimelineUpdatedRef.current = onTimelineUpdated;
-  handleTimelineItemClickRef.current = handleTimelineItemClick;
- 
-  // Memoize searchable content with better caching strategy
-  const searchableContent = useMemo(() => {
-    return items.map((item, index) => {
-      const textParts = [
-        getSearchableText(item.title),
-        getSearchableText(item.cardTitle),
-        getSearchableText(item.cardSubtitle),
-        Array.isArray(item.cardDetailedText)
-          ? item.cardDetailedText.map(getSearchableText).join(' ')
-          : getSearchableText(item.cardDetailedText),
-      ];
- 
-      return {
-        index,
-        content: textParts.filter(Boolean).join(' ').toLowerCase(),
-        id: item.id,
-      };
-    });
-  }, [items]);
- 
-  // Optimized focus helper with reduced timeout
-  const focusSearchInput = useCallback(() => {
-    // Use requestAnimationFrame for better performance
-    requestAnimationFrame(() => {
-      if (searchInputRef.current) {
-        searchInputRef.current.focus();
-        const length = searchInputRef.current.value.length;
-        searchInputRef.current.setSelectionRange(length, length);
-      }
-    });
-  }, []);
- 
-  // Enhanced search with better performance
-  const findMatches = useCallback(
-    (query: string) => {
-      const trimmedQuery = query.trim();
-      if (!trimmedQuery) {
-        setSearchResults([]);
-        setCurrentMatchIndex(-1);
-        return;
-      }
- 
-      const queryLower = trimmedQuery.toLowerCase();
-      const results: number[] = [];
- 
-      // Use for-loop for better performance than array methods
-      for (let i = 0; i < searchableContent.length; i++) {
-        if (searchableContent[i].content.includes(queryLower)) {
-          results.push(i);
-        }
-      }
- 
-      setSearchResults(results);
- 
-      if (results.length > 0) {
-        setCurrentMatchIndex(0);
-        const firstMatchData = searchableContent[results[0]];
-        if (firstMatchData?.id) {
-          activeItemIndex.current = results[0];
-          onTimelineUpdatedRef.current?.(results[0]);
-          handleTimelineItemClickRef.current(firstMatchData.id);
-          focusSearchInput();
-        }
-      } else {
-        setCurrentMatchIndex(-1);
-        focusSearchInput();
-      }
-    },
-    [searchableContent, focusSearchInput],
-  );
- 
-  // Optimized debounced search with better performance
-  const debouncedSearch = useDebouncedCallback(findMatches, 150, {
-    maxWait: 500,
-    leading: false,
-    trailing: true,
-  });
- 
-  const handleSearchChange = useCallback(
-    (query: string) => {
-      setSearchQuery(query);
-      debouncedSearch(query);
-    },
-    [debouncedSearch],
-  );
- 
-  const clearSearch = useCallback(() => {
-    setSearchQuery('');
-    setSearchResults([]);
-    setCurrentMatchIndex(-1);
-    debouncedSearch.cancel();
- 
-    if (items.length > 0) {
-      activeItemIndex.current = 0;
-      onTimelineUpdatedRef.current?.(0);
- 
-      const firstItem = items[0];
-      if (firstItem?.id) {
-        handleTimelineItemClickRef.current(firstItem.id);
-      }
-    }
-  }, [items, debouncedSearch]);
- 
-  // Optimized navigation with bounds checking
-  const navigateMatches = useCallback(
-    (direction: 'next' | 'prev') => {
-      if (searchResults.length === 0) return;
- 
-      const nextIndex =
-        direction === 'next'
-          ? (currentMatchIndex + 1) % searchResults.length
-          : (currentMatchIndex - 1 + searchResults.length) % searchResults.length;
- 
-      if (nextIndex === currentMatchIndex) return;
- 
-      const newTimelineIndex = searchResults[nextIndex];
-      const matchData = searchableContent[newTimelineIndex];
-      
-      setCurrentMatchIndex(nextIndex);
-      activeItemIndex.current = newTimelineIndex;
-      
-      onTimelineUpdatedRef.current?.(newTimelineIndex);
- 
-      if (matchData?.id) {
-        handleTimelineItemClickRef.current(matchData.id);
-        focusSearchInput();
-      }
-    },
-    [searchResults, currentMatchIndex, searchableContent, focusSearchInput],
-  );
- 
-  const handleNextMatch = useCallback(
-    () => navigateMatches('next'),
-    [navigateMatches],
-  );
- 
-  const handlePreviousMatch = useCallback(
-    () => navigateMatches('prev'),
-    [navigateMatches],
-  );
- 
-  const handleSearchKeyDown = useCallback(
-    (e: React.KeyboardEvent) => {
-      switch (e.key) {
-        case 'Enter':
-          if (searchResults.length > 0) {
-            e.preventDefault();
-            handleNextMatch();
-          }
-          break;
-        case 'Escape':
-          e.preventDefault();
-          clearSearch();
-          break;
-      }
-    },
-    [searchResults.length, handleNextMatch, clearSearch],
-  );
- 
-  return {
-    searchQuery,
-    searchResults,
-    currentMatchIndex,
-    searchInputRef,
-    activeItemIndex,
-    handleSearchChange,
-    clearSearch,
-    handleNextMatch,
-    handlePreviousMatch,
-    handleSearchKeyDown,
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useUIState.ts.html b/coverage/lcov-report/hooks/useUIState.ts.html deleted file mode 100644 index 049d973f0..000000000 --- a/coverage/lcov-report/hooks/useUIState.ts.html +++ /dev/null @@ -1,166 +0,0 @@ - - - - - - Code coverage report for hooks/useUIState.ts - - - - - - - - - -
-
-

All files / hooks useUIState.ts

-
- -
- 100% - Statements - 13/13 -
- - -
- 100% - Branches - 4/4 -
- - -
- 100% - Functions - 1/1 -
- - -
- 100% - Lines - 13/13 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -281x -  -  -  -  -  -  -  -  -  -  -1x -12x -12x -12x -  -12x -3x -12x -  -  -12x -2x -12x -  -12x -12x - 
import { useState, useCallback } from 'react';
- 
-export interface UIStateHook<T> {
-  state: T;
-  toggle: () => void;
-  setState: (value: T) => void;
-}
- 
-/**
- * Optimized UI state hook with better type safety and performance
- */
-export const useUIState = <T extends boolean>(
-  initialState: T,
-): UIStateHook<T> => {
-  const [state, setState] = useState<T>(initialState);
- 
-  const toggle = useCallback(() => {
-    setState((prev) => !prev as T);
-  }, []);
- 
-  // Memoized setState to prevent unnecessary re-renders
-  const setStateCallback = useCallback((value: T) => {
-    setState(value);
-  }, []);
- 
-  return { state, toggle, setState: setStateCallback };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/hooks/useWindowSize.ts.html b/coverage/lcov-report/hooks/useWindowSize.ts.html deleted file mode 100644 index 89fa81d33..000000000 --- a/coverage/lcov-report/hooks/useWindowSize.ts.html +++ /dev/null @@ -1,334 +0,0 @@ - - - - - - Code coverage report for hooks/useWindowSize.ts - - - - - - - - - -
-
-

All files / hooks useWindowSize.ts

-
- -
- 93.87% - Statements - 46/49 -
- - -
- 62.5% - Branches - 10/16 -
- - -
- 100% - Functions - 1/1 -
- - -
- 93.87% - Lines - 46/49 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -841x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -10x -10x -10x -  -  -10x -8x -8x -10x -  -10x -10x -10x -  -10x -3x -3x -3x -3x -  -  -3x -3x -1x -3x -2x -2x -2x -10x -  -10x -  -8x -8x -  -8x -  -  -  -  -  -  -8x -3x -8x -10x -  -10x -8x -  -  -8x -8x -  -  -8x -  -8x -8x -8x -8x -8x -10x -  -10x -10x - 
import { useState, useEffect, useCallback, useRef } from 'react';
- 
-interface WindowSize {
-  width: number;
-  height: number;
-}
- 
-interface UseWindowSizeOptions {
-  debounceMs?: number;
-  enableThrottling?: boolean;
-}
- 
-/**
- * Hook that returns the current window dimensions
- * Optimized for performance with better resize handling
- */
-export const useWindowSize = (
-  options: UseWindowSizeOptions = {},
-): WindowSize => {
-  const { debounceMs = 100, enableThrottling = true } = options;
-  
-  // Initialize with current window size or fallback
-  const [windowSize, setWindowSize] = useState<WindowSize>(() => ({
-    width: typeof window !== 'undefined' ? window.innerWidth : 0,
-    height: typeof window !== 'undefined' ? window.innerHeight : 0,
-  }));
- 
-  const timeoutRef = useRef<NodeJS.Timeout | undefined>(undefined);
-  const frameRef = useRef<number | undefined>(undefined);
-  const lastSize = useRef<WindowSize>(windowSize);
- 
-  const updateSize = useCallback(() => {
-    const newSize = {
-      width: window.innerWidth,
-      height: window.innerHeight,
-    };
- 
-    // Only update if size actually changed to prevent unnecessary re-renders
-    if (
-      newSize.width !== lastSize.current.width ||
-      newSize.height !== lastSize.current.height
-    ) {
-      lastSize.current = newSize;
-      setWindowSize(newSize);
-    }
-  }, []);
- 
-  const handleResize = useCallback(() => {
-    // Clear existing timeouts and frames
-    if (timeoutRef.current) clearTimeout(timeoutRef.current);
-    if (frameRef.current) cancelAnimationFrame(frameRef.current);
- 
-    if (!enableThrottling) {
-      // Immediate update without throttling
-      frameRef.current = requestAnimationFrame(updateSize);
-      return;
-    }
- 
-    // Use debounced approach for better performance
-    timeoutRef.current = setTimeout(() => {
-      frameRef.current = requestAnimationFrame(updateSize);
-    }, debounceMs);
-  }, [debounceMs, enableThrottling, updateSize]);
- 
-  useEffect(() => {
-    if (typeof window === 'undefined') return;
- 
-    // Use passive listener for better scroll performance
-    const options = { passive: true };
-    window.addEventListener('resize', handleResize, options);
- 
-    // Initial measurement
-    handleResize();
- 
-    return () => {
-      window.removeEventListener('resize', handleResize);
-      if (timeoutRef.current) clearTimeout(timeoutRef.current);
-      if (frameRef.current) cancelAnimationFrame(frameRef.current);
-    };
-  }, [handleResize]);
- 
-  return windowSize;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/index.html b/coverage/lcov-report/index.html deleted file mode 100644 index 490e51f21..000000000 --- a/coverage/lcov-report/index.html +++ /dev/null @@ -1,776 +0,0 @@ - - - - - - Code coverage report for All files - - - - - - - - - -
-
-

All files

-
- -
- 91.81% - Statements - 10535/11474 -
- - -
- 84.41% - Branches - 1776/2104 -
- - -
- 75.69% - Functions - 190/251 -
- - -
- 91.81% - Lines - 10535/11474 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
__tests__ -
-
100%126/126100%9/9100%0/0100%126/126
components/__tests__ -
-
100%553/55398.8%83/84100%11/11100%553/553
components/common/styles -
-
100%5/5100%3/3100%0/0100%5/5
components/common/themes -
-
100%74/74100%0/0100%0/0100%74/74
components/contexts -
-
96.38%507/52670.96%44/6261.53%8/1396.38%507/526
components/effects -
-
80.07%213/26685.96%49/57100%7/780.07%213/266
components/effects/__tests__ -
-
100%545/545100%99/99100%6/6100%545/545
components/elements/list -
-
97.74%130/13387.8%36/4180%4/597.74%130/133
components/elements/list/__tests__ -
-
100%134/134100%13/13100%0/0100%134/134
components/elements/popover -
-
97.2%139/14379.31%46/58100%19/1997.2%139/143
components/elements/popover/__tests__ -
-
100%85/85100%6/6100%0/0100%85/85
components/timeline -
-
78.48%693/88364.76%68/10544.82%13/2978.48%693/883
components/timeline-elements/memoized -
-
91.17%124/13678.57%22/2840%2/591.17%124/136
components/timeline-elements/memoized/__tests__ -
-
99.27%136/137100%15/15100%0/099.27%136/137
components/timeline-elements/nested-timeline-renderer -
-
11.53%3/26100%0/00%0/111.53%3/26
components/timeline-elements/timeline-card -
-
94.17%178/18972.22%39/54100%3/394.17%178/189
components/timeline-elements/timeline-card-content -
-
76.04%638/83976.41%162/21275%30/4076.04%638/839
components/timeline-elements/timeline-card-content/__tests__ -
-
98.31%351/357100%37/3766.66%2/398.31%351/357
components/timeline-elements/timeline-card-media -
-
79.91%199/24978.33%47/6090%9/1079.91%199/249
components/timeline-elements/timeline-card-media/__tests__ -
-
100%201/201100%10/100%0/8100%201/201
components/timeline-elements/timeline-card-media/components -
-
75.49%191/25368.42%13/19100%1/175.49%191/253
components/timeline-elements/timeline-card-media/hooks -
-
88.65%86/9794.11%16/17100%4/488.65%86/97
components/timeline-elements/timeline-card/__tests__ -
-
93.93%93/99100%10/10100%0/093.93%93/99
components/timeline-elements/timeline-card/hooks -
-
96.2%76/7993.75%15/16100%1/196.2%76/79
components/timeline-elements/timeline-card/timeline-card-portal -
-
100%96/96100%6/6100%1/1100%96/96
components/timeline-elements/timeline-card/timeline-point -
-
100%35/3550%2/4100%1/1100%35/35
components/timeline-elements/timeline-control -
-
91.46%225/24662.65%52/8350%1/291.46%225/246
components/timeline-elements/timeline-control/__tests__ -
-
100%67/67100%6/6100%0/0100%67/67
components/timeline-elements/timeline-controls-wrapper -
-
0%0/8100%1/1100%1/10%0/8
components/timeline-elements/timeline-item-title -
-
100%37/3795%19/20100%1/1100%37/37
components/timeline-elements/timeline-item-title/__tests__ -
-
100%46/46100%7/7100%0/0100%46/46
components/timeline-elements/timeline-outline -
-
92.06%174/18985%51/6071.42%5/792.06%174/189
components/timeline-elements/timeline-outline/__tests__ -
-
94.69%107/113100%13/13100%0/094.69%107/113
components/timeline-elements/timeline-outline/hooks -
-
90.9%10/1150%2/4100%1/190.9%10/11
components/timeline-horizontal -
-
100%103/103100%17/17100%1/1100%103/103
components/timeline-horizontal/__tests__ -
-
98.3%232/23692%23/25100%1/198.3%232/236
components/timeline-vertical -
-
91.1%430/47256.04%51/9150%1/291.1%430/472
components/timeline-vertical/__tests__ -
-
100%74/74100%5/50%0/3100%74/74
components/timeline/__tests__ -
-
95.02%210/221100%14/14100%0/095.02%210/221
components/toggle-button -
-
0%0/200%0/20%0/20%0/20
components/toolbar -
-
87.8%36/4183.33%10/12100%2/287.8%36/41
components/toolbar/__tests__ -
-
100%41/41100%4/40%0/3100%41/41
hooks -
-
92.04%822/89385.45%188/220100%18/1892.04%822/893
hooks/__tests__ -
-
99.17%1562/157599.66%301/302100%7/799.17%1562/1575
utils -
-
91.77%748/81583.93%162/19390.62%29/3291.77%748/815
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/prettify.css b/coverage/lcov-report/prettify.css deleted file mode 100644 index b317a7cda..000000000 --- a/coverage/lcov-report/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/lcov-report/prettify.js b/coverage/lcov-report/prettify.js deleted file mode 100644 index b3225238f..000000000 --- a/coverage/lcov-report/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/lcov-report/sort-arrow-sprite.png b/coverage/lcov-report/sort-arrow-sprite.png deleted file mode 100644 index 6ed68316eb3f65dec9063332d2f69bf3093bbfab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc diff --git a/coverage/lcov-report/sorter.js b/coverage/lcov-report/sorter.js deleted file mode 100644 index 2bb296a8c..000000000 --- a/coverage/lcov-report/sorter.js +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - if ( - row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()) - ) { - row.style.display = ''; - } else { - row.style.display = 'none'; - } - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/coverage/lcov-report/utils/index.html b/coverage/lcov-report/utils/index.html deleted file mode 100644 index ab984a786..000000000 --- a/coverage/lcov-report/utils/index.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - Code coverage report for utils - - - - - - - - - -
-
-

All files utils

-
- -
- 91.77% - Statements - 748/815 -
- - -
- 83.93% - Branches - 162/193 -
- - -
- 90.62% - Functions - 29/32 -
- - -
- 91.77% - Lines - 748/815 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
81.06%107/13275%15/2075%6/881.06%107/132
mediaQueryUtils.test.ts -
-
100%61/61100%16/16100%0/0100%61/61
mediaQueryUtils.ts -
-
89.18%33/3766.66%8/12100%3/389.18%33/37
performance.test.ts -
-
98.75%79/80100%21/2150%1/298.75%79/80
performance.ts -
-
88.23%150/17070.27%26/37100%14/1488.23%150/170
timelineUtils.test.ts -
-
100%124/124100%26/26100%0/0100%124/124
timelineUtils.ts -
-
85.95%104/12178.43%40/51100%5/585.95%104/121
utils.test.ts -
-
100%90/90100%10/10100%0/0100%90/90
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/index.ts.html b/coverage/lcov-report/utils/index.ts.html deleted file mode 100644 index bac88d6c1..000000000 --- a/coverage/lcov-report/utils/index.ts.html +++ /dev/null @@ -1,715 +0,0 @@ - - - - - - Code coverage report for utils/index.ts - - - - - - - - - -
-
-

All files / utils index.ts

-
- -
- 81.06% - Statements - 107/132 -
- - -
- 75% - Branches - 15/20 -
- - -
- 75% - Functions - 6/8 -
- - -
- 81.06% - Lines - 107/132 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211  -  -  -  -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -  -  -  -  -  -  -1x -  -61x -  -  -  -  -61x -6x -6x -6x -  -  -55x -55x -55x -55x -  -  -55x -  -55x -55x -  -  -  -  -  -  -1x -10x -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -1x -6x -6x -3x -6x -6x -6x -3x -6x -6x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -20x -20x -20x -20x -  -20x -20x -20x -20x -20x -  -  -20x -  -  -  -  -  -  -  -  -  -  -  -  -20x -20x -  -  -  -  -  -  -20x -  -20x -20x - 
import {
-  ButtonTexts,
-  SlideShowType,
-  TimelineMode,
-} from '@models/TimelineModel';
-import xss from 'xss';
-import { darkTheme, defaultTheme } from '../components/common/themes';
- 
-// Constants to avoid creating new objects on every function call
-const DEFAULT_CLASS_NAMES = Object.freeze({
-  card: 'rc-card',
-  cardMedia: 'rc-card-media',
-  cardSubTitle: 'rc-card-subtitle',
-  cardText: 'rc-card-text',
-  cardTitle: 'rc-card-title',
-  controls: 'rc-controls',
-  title: 'rc-title',
-} as const);
- 
-const DEFAULT_BUTTON_TEXTS: Readonly<ButtonTexts> = Object.freeze({
-  changeDensity: 'Change density',
-  changeDensityOptions: Object.freeze({
-    high: Object.freeze({
-      helpText: 'Show more items at once',
-      text: 'High',
-    }),
-    low: Object.freeze({
-      helpText: 'Show fewer items at once',
-      text: 'Low',
-    }),
-  }),
-  changeLayout: 'Change layout',
-  changeLayoutOptions: Object.freeze({
-    alternating: Object.freeze({
-      helpText: 'Show cards in a vertical layout with alternating fashion',
-      text: 'Alternating',
-    }),
-    horizontal: Object.freeze({
-      helpText: 'Show cards in a horizontal layout',
-      text: 'Horizontal',
-    }),
-    horizontal_all: Object.freeze({
-      helpText: 'Show all cards in a horizontal layout',
-      text: 'Show all cards',
-    }),
-    vertical: Object.freeze({
-      helpText: 'Show cards in a vertical layout',
-      text: 'Vertical',
-    }),
-  }),
-  dark: 'Switch to Dark Mode',
-  first: 'Go to First',
-  jumpTo: 'Jump to',
-  last: 'Go to Last',
-  light: 'Switch to Light Mode',
-  next: 'Next',
-  play: 'Play Slideshow',
-  previous: 'Previous',
-  stop: 'Stop Slideshow',
-  searchPlaceholder: 'Search Timeline',
-  searchAriaLabel: 'Search timeline content',
-  clearSearch: 'Clear Search',
-  previousMatch: 'Previous Match',
-  nextMatch: 'Next Match',
-  timelinePoint: 'Timeline point',
-});
- 
-// Pre-compiled regex for hex validation
-const HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
- 
-// Character set for ID generation
-const ID_CHARS =
-  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-const ID_LENGTH = 7;
- 
-/**
- * Converts hex color to RGBA format
- * @param hex - Hex color code (e.g. #FFFFFF)
- * @param alpha - Opacity value between 0 and 1
- * @returns RGBA color string
- */
-export const hexToRGBA = (hex: string, alpha: number): string => {
-  // Input validation
-  if (typeof hex !== 'string' || typeof alpha !== 'number') {
-    return `rgba(0, 0, 0, ${Math.max(0, Math.min(1, alpha || 0))})`;
-  }
- 
-  // Validate hex format using regex (more efficient than manual checks)
-  if (!HEX_COLOR_REGEX.test(hex)) {
-    console.warn('Invalid hex color provided:', hex);
-    return `rgba(0, 0, 0, ${Math.max(0, Math.min(1, alpha))})`;
-  }
- 
-  // Extract RGB values directly with bit shifting (more efficient)
-  const hexValue = parseInt(hex.slice(1), 16);
-  const r = (hexValue >> 16) & 255;
-  const g = (hexValue >> 8) & 255;
-  const b = hexValue & 255;
- 
-  // Clamp alpha value between 0 and 1
-  const clampedAlpha = Math.max(0, Math.min(1, alpha));
- 
-  return `rgba(${r}, ${g}, ${b}, ${clampedAlpha})`;
-};
- 
-/**
- * Returns the appropriate theme based on dark mode preference
- * @param isDark - Whether dark mode is enabled
- * @returns Theme object
- */
-export const getDefaultThemeOrDark = (isDark?: boolean) =>
-  isDark ? darkTheme : defaultTheme;
- 
-/**
- * Returns default class names for timeline components
- * @returns Object of default CSS class names
- */
-export const getDefaultClassNames = () => DEFAULT_CLASS_NAMES;
- 
-/**
- * Returns default button text translations
- * @returns Object containing all button text strings
- */
-export const getDefaultButtonTexts = (): ButtonTexts => DEFAULT_BUTTON_TEXTS;
- 
-/**
- * Determines slideshow type based on timeline mode
- * @param mode - Timeline display mode
- * @returns Appropriate slideshow animation type
- */
-export const getSlideShowType = (mode: TimelineMode): SlideShowType => {
-  switch (mode) {
-    case 'VERTICAL_ALTERNATING':
-      return 'slide_from_sides';
-    case 'HORIZONTAL':
-    case 'VERTICAL':
-    default:
-      return 'reveal';
-  }
-};
- 
-/**
- * Type guard to check if text is an array of strings
- * @param text - Text string or array of strings
- * @returns Boolean indicating if input is string array
- */
-export const isTextArray = (text: string | string[]): text is string[] =>
-  Array.isArray(text);
- 
-/**
- * Sanitizes HTML text to prevent XSS attacks
- * @param text - Text string or array of strings to sanitize
- * @returns Sanitized text string or array
- */
-export const sanitizeHtmlText = (
-  text: string | string[],
-): string | string[] => {
-  if (!text) return '';
- 
-  try {
-    return isTextArray(text) ? text.map((t) => xss(t || '')) : xss(text);
-  } catch (error) {
-    console.error('Error sanitizing HTML text:', error);
-    return isTextArray(text) ? [] : '';
-  }
-};
- 
-/**
- * Generates a cryptographically secure random ID
- * @returns Unique string ID
- */
-export const getUniqueID = (): string => {
-  // Use crypto API if available (modern browsers)
-  if (typeof window !== 'undefined' && window.crypto?.getRandomValues) {
-    try {
-      const randomValues = new Uint8Array(ID_LENGTH);
-      window.crypto.getRandomValues(randomValues);
- 
-      return Array.from(
-        randomValues,
-        (byte) => ID_CHARS[byte % ID_CHARS.length],
-      ).join('');
-    } catch (error) {
-      console.error('Error generating unique ID:', error);
-    }
-  }
- 
-  // Fallback for environments without crypto API
-  // Using a combination of timestamp and a more robust random generation
-  const timestamp = Date.now().toString(36);
- 
-  // Use performance.now() for additional entropy if available
-  const performanceTime =
-    typeof performance !== 'undefined' && performance.now
-      ? performance.now().toString().replace('.', '')
-      : Date.now().toString();
- 
-  // Generate random part using timestamp-based seed for better distribution
-  const seed = parseInt(performanceTime.slice(-6), 10);
-  const randomPart = Array.from({ length: 8 }, (_, index) => {
-    // Simple LCG algorithm for better distribution than Math.random
-    const a = 1664525;
-    const c = 1013904223;
-    const m = Math.pow(2, 32);
-    const value = (a * (seed + index) + c) % m;
-    return ID_CHARS[value % ID_CHARS.length];
-  }).join('');
- 
-  return `id-${timestamp}-${randomPart}`;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/mediaQueryUtils.test.ts.html b/coverage/lcov-report/utils/mediaQueryUtils.test.ts.html deleted file mode 100644 index ce9c30f7f..000000000 --- a/coverage/lcov-report/utils/mediaQueryUtils.test.ts.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - Code coverage report for utils/mediaQueryUtils.test.ts - - - - - - - - - -
-
-

All files / utils mediaQueryUtils.test.ts

-
- -
- 100% - Statements - 61/61 -
- - -
- 100% - Branches - 16/16 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 61/61 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -721x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -  -1x -3x -3x -3x -3x -3x -2x -2x -2x -1x -1x -2x -2x -1x -1x -1x -1x -1x -2x -3x -3x -1x -1x -3x -3x -2x -1x -1x -3x -1x -  -1x -3x -3x -3x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import {
-  createMediaQuery,
-  addMediaListeners,
-  removeMediaListeners,
-} from './mediaQueryUtils';
- 
-describe('mediaQueryUtils', () => {
-  let originalMatchMedia: any;
-  let originalAddEventListener: any;
-  let originalRemoveEventListener: any;
-  let windowListeners: Record<string, Function[]> = {};
- 
-  beforeEach(() => {
-    originalMatchMedia = window.matchMedia;
-    originalAddEventListener = window.addEventListener;
-    originalRemoveEventListener = window.removeEventListener;
-    windowListeners = {};
-    window.matchMedia = vi.fn().mockImplementation((query) => ({
-      media: query,
-      matches: false,
-      addEventListener: vi.fn((event, cb) => {
-        windowListeners[event] = windowListeners[event] || [];
-        windowListeners[event].push(cb);
-      }),
-      removeEventListener: vi.fn((event, cb) => {
-        if (windowListeners[event]) {
-          windowListeners[event] = windowListeners[event].filter(
-            (f) => f !== cb,
-          );
-        }
-      }),
-    }));
-    window.addEventListener = vi.fn((event, cb) => {
-      windowListeners[event] = windowListeners[event] || [];
-      windowListeners[event].push(cb);
-    });
-    window.removeEventListener = vi.fn((event, cb) => {
-      if (windowListeners[event]) {
-        windowListeners[event] = windowListeners[event].filter((f) => f !== cb);
-      }
-    });
-  });
- 
-  afterEach(() => {
-    window.matchMedia = originalMatchMedia;
-    window.addEventListener = originalAddEventListener;
-    window.removeEventListener = originalRemoveEventListener;
-  });
- 
-  it('should create a media query', () => {
-    const mq = createMediaQuery('(max-width: 600px)');
-    expect(mq).toBeTruthy();
-    expect(mq?.media).toBe('(max-width: 600px)');
-  });
- 
-  it('should add and remove media listeners', () => {
-    const mq = createMediaQuery('(max-width: 600px)');
-    const handleMediaChange = vi.fn();
-    const handleResize = vi.fn();
-    addMediaListeners(mq, handleMediaChange, handleResize);
-    expect(windowListeners['resize']).toContain(handleResize);
-    removeMediaListeners(mq, handleMediaChange, handleResize);
-    expect(windowListeners['resize']).not.toContain(handleResize);
-  });
- 
-  it('should handle null media query gracefully', () => {
-    expect(() => addMediaListeners(null, vi.fn(), vi.fn())).not.toThrow();
-    expect(() => removeMediaListeners(null, vi.fn(), vi.fn())).not.toThrow();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/mediaQueryUtils.ts.html b/coverage/lcov-report/utils/mediaQueryUtils.ts.html deleted file mode 100644 index 2df2c89c0..000000000 --- a/coverage/lcov-report/utils/mediaQueryUtils.ts.html +++ /dev/null @@ -1,274 +0,0 @@ - - - - - - Code coverage report for utils/mediaQueryUtils.ts - - - - - - - - - -
-
-

All files / utils mediaQueryUtils.ts

-
- -
- 89.18% - Statements - 33/37 -
- - -
- 66.66% - Branches - 8/12 -
- - -
- 100% - Functions - 3/3 -
- - -
- 89.18% - Lines - 33/37 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64  -  -  -  -  -  -  -  -  -1x -15x -  -15x -15x -15x -1x -1x -1x -15x -  -  -  -  -  -  -  -1x -10x -10x -10x -10x -10x -  -9x -9x -9x -10x -  -  -10x -  -  -  -  -  -  -  -1x -10x -10x -10x -10x -10x -  -10x -10x -9x -9x -10x -10x -  -  -10x - 
/**
- * Media query utility functions for handling responsive behaviors
- */
- 
-/**
- * Creates and returns a MediaQueryList object
- * @param query - CSS media query string (e.g. '(max-width: 768px)')
- * @returns MediaQueryList object or null if browser doesn't support matchMedia
- */
-export function createMediaQuery(query: string): MediaQueryList | null {
-  if (typeof window === 'undefined') return null;
- 
-  try {
-    return window.matchMedia(query);
-  } catch (error) {
-    console.error('Error creating media query:', error);
-    return null;
-  }
-}
- 
-/**
- * Adds change and resize listeners for the provided media query
- * @param currentMedia - MediaQueryList object to attach listeners to
- * @param handleMediaChange - Callback function for media query changes
- * @param handleResize - Callback function for window resize events
- */
-export function addMediaListeners(
-  currentMedia: MediaQueryList | null,
-  handleMediaChange: (event: MediaQueryListEvent | MediaQueryList) => void,
-  handleResize: () => void,
-): void {
-  if (!currentMedia || typeof window === 'undefined') return;
- 
-  try {
-    currentMedia.addEventListener('change', handleMediaChange);
-    window.addEventListener('resize', handleResize);
-  } catch (error) {
-    console.error('Error adding media listeners:', error);
-  }
-}
- 
-/**
- * Removes change and resize listeners to prevent memory leaks
- * @param currentMedia - MediaQueryList object to detach listeners from
- * @param handleMediaChange - Callback function to remove from media query changes
- * @param handleResize - Callback function to remove from window resize events
- */
-export function removeMediaListeners(
-  currentMedia: MediaQueryList | null,
-  handleMediaChange: (event: MediaQueryListEvent | MediaQueryList) => void,
-  handleResize: () => void,
-): void {
-  if (typeof window === 'undefined') return;
- 
-  try {
-    if (currentMedia) {
-      currentMedia.removeEventListener('change', handleMediaChange);
-    }
-    window.removeEventListener('resize', handleResize);
-  } catch (error) {
-    console.error('Error removing media listeners:', error);
-  }
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/performance.test.ts.html b/coverage/lcov-report/utils/performance.test.ts.html deleted file mode 100644 index 92a6dbd9d..000000000 --- a/coverage/lcov-report/utils/performance.test.ts.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - Code coverage report for utils/performance.test.ts - - - - - - - - - -
-
-

All files / utils performance.test.ts

-
- -
- 98.75% - Statements - 79/80 -
- - -
- 100% - Branches - 21/21 -
- - -
- 50% - Functions - 1/2 -
- - -
- 98.75% - Lines - 79/80 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -981x -1x -1x -  -  -  -  -  -  -1x -  -  -1x -1x -7x -7x -7x -1x -7x -7x -7x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import React from 'react';
-import {
-  performanceMonitor,
-  usePerformanceMonitor,
-  withPerformanceMonitoring,
-  measureAsync,
-  createPerformantDebounce,
-} from './performance';
-import { renderHook, act } from '@testing-library/react';
- 
-// Mock performance.now
-const originalPerformanceNow = globalThis.performance.now;
-beforeEach(() => {
-  let now = 0;
-  globalThis.performance.now = () => (now += 10);
-});
-afterEach(() => {
-  globalThis.performance.now = originalPerformanceNow;
-  performanceMonitor.clear();
-});
- 
-describe('PerformanceMonitor', () => {
-  it('should log render times and generate report', () => {
-    performanceMonitor.setEnabled(true);
-    const end = performanceMonitor.startTiming('TestComponent');
-    end();
-    const stats = performanceMonitor.getStats('TestComponent');
-    expect(stats).toBeTruthy();
-    expect(stats?.totalRenders).toBe(1);
-    expect(performanceMonitor.getAllEntries().length).toBe(1);
-    expect(performanceMonitor.generateReport()).toContain('TestComponent');
-  });
- 
-  it('should clear all entries', () => {
-    performanceMonitor.setEnabled(true);
-    const end = performanceMonitor.startTiming('TestComponent');
-    end();
-    performanceMonitor.clear();
-    expect(performanceMonitor.getAllEntries().length).toBe(0);
-  });
-});
- 
-describe('usePerformanceMonitor', () => {
-  it('should call end timing on unmount', () => {
-    const { result, unmount } = renderHook(() =>
-      usePerformanceMonitor('HookComponent'),
-    );
-    expect(typeof result.current).toBe('function');
-    // Simulate unmount
-    act(() => {
-      unmount();
-    });
-    // Optionally, call the returned cleanup function
-    act(() => {
-      result.current();
-    });
-  });
-});
- 
-describe('withPerformanceMonitoring', () => {
-  it('should wrap a component and call usePerformanceMonitor', () => {
-    const Dummy = (props: { value: string }) =>
-      React.createElement('div', null, props.value);
-    const Wrapped = withPerformanceMonitoring(Dummy, 'Dummy');
-    const el = React.createElement(Wrapped, { value: 'test' });
-    expect(el).toBeTruthy();
-  });
-});
- 
-describe('measureAsync', () => {
-  it('should measure async operation duration', async () => {
-    const result = await measureAsync(async () => {
-      return 42;
-    }, 'TestOp');
-    expect(result).toBe(42);
-  });
- 
-  it('should throw and log on error', async () => {
-    await expect(
-      measureAsync(async () => {
-        throw new Error('fail');
-      }, 'TestOp'),
-    ).rejects.toThrow('fail');
-  });
-});
- 
-describe('createPerformantDebounce', () => {
-  it('should debounce a function and log duration', async () => {
-    const fn = vi.fn();
-    const debounced = createPerformantDebounce(fn, 10, 'debounceTest');
-    debounced();
-    debounced();
-    await new Promise((r) => setTimeout(r, 20));
-    expect(fn).toHaveBeenCalledTimes(1);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/performance.ts.html b/coverage/lcov-report/utils/performance.ts.html deleted file mode 100644 index 8cbf15866..000000000 --- a/coverage/lcov-report/utils/performance.ts.html +++ /dev/null @@ -1,892 +0,0 @@ - - - - - - Code coverage report for utils/performance.ts - - - - - - - - - -
-
-

All files / utils performance.ts

-
- -
- 88.23% - Statements - 150/170 -
- - -
- 70.27% - Branches - 26/37 -
- - -
- 100% - Functions - 14/14 -
- - -
- 88.23% - Lines - 150/170 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -2701x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -3x -  -3x -  -3x -4x -4x -  -4x -4x -3x -  -  -  -  -1x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -  -4x -  -  -4x -  -  -  -  -4x -3x -3x -  -4x -4x -  -  -4x -  -  -  -  -4x -2x -2x -2x -2x -2x -4x -  -  -  -  -1x -  -  -  -  -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -  -  -  -  -1x -2x -2x -  -  -  -  -1x -8x -8x -8x -  -  -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -  -  -1x -2x -2x -1x -  -1x -  -  -  -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -  -  -  -  -1x -  -1x -  -1x -1x -  -  -  -  -1x -2x -2x -2x -2x -  -2x -2x -1x -1x -  -2x -  -  -  -1x -1x -1x -1x -  -1x -  -  -  -  -  -  -1x -1x -2x -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -2x -1x -1x -  -2x -1x -1x -1x -  -1x -  -  -  -  -2x -2x -1x - 
import React, { useEffect, useRef } from 'react';
- 
-/**
- * Performance monitoring utilities for React Chrono
- * Helps track component render times and identify bottlenecks
- */
- 
-interface PerformanceEntry {
-  componentName: string;
-  renderTime: number;
-  timestamp: number;
-  props?: Record<string, any>;
-}
- 
-class PerformanceMonitor {
-  private static instance: PerformanceMonitor;
-  private entries: PerformanceEntry[] = [];
-  private readonly renderTimes = new Map<string, number[]>();
-  private isEnabled = process.env.NODE_ENV === 'development';
- 
-  static getInstance(): PerformanceMonitor {
-    if (!PerformanceMonitor.instance) {
-      PerformanceMonitor.instance = new PerformanceMonitor();
-    }
-    return PerformanceMonitor.instance;
-  }
- 
-  /**
-   * Start timing a component render
-   */
-  startTiming(componentName: string): () => void {
-    if (!this.isEnabled) return () => {};
- 
-    const startTime = performance.now();
- 
-    return () => {
-      const endTime = performance.now();
-      const renderTime = endTime - startTime;
- 
-      this.logRenderTime(componentName, renderTime);
-    };
-  }
- 
-  /**
-   * Log render time for a component
-   */
-  private logRenderTime(
-    componentName: string,
-    renderTime: number,
-    props?: Record<string, any>,
-  ): void {
-    const entry: PerformanceEntry = {
-      componentName,
-      renderTime,
-      timestamp: Date.now(),
-      props,
-    };
- 
-    this.entries.push(entry);
- 
-    // Keep only last 100 entries to prevent memory leaks
-    if (this.entries.length > 100) {
-      this.entries = this.entries.slice(-100);
-    }
- 
-    // Track render times per component
-    if (!this.renderTimes.has(componentName)) {
-      this.renderTimes.set(componentName, []);
-    }
- 
-    const times = this.renderTimes.get(componentName) ?? [];
-    times.push(renderTime);
- 
-    // Keep only last 20 render times per component
-    if (times.length > 20) {
-      times.splice(0, times.length - 20);
-    }
- 
-    // Log slow renders (>16ms for 60fps)
-    if (renderTime > 16) {
-      console.warn(
-        `🐌 Slow render detected: ${componentName} took ${renderTime.toFixed(2)}ms`,
-        { renderTime, props },
-      );
-    }
-  }
- 
-  /**
-   * Get performance statistics for a component
-   */
-  getStats(componentName: string): {
-    averageRenderTime: number;
-    maxRenderTime: number;
-    minRenderTime: number;
-    totalRenders: number;
-  } | null {
-    const times = this.renderTimes.get(componentName);
-    if (!times || times.length === 0) return null;
- 
-    return {
-      averageRenderTime: times.reduce((a, b) => a + b, 0) / times.length,
-      maxRenderTime: Math.max(...times),
-      minRenderTime: Math.min(...times),
-      totalRenders: times.length,
-    };
-  }
- 
-  /**
-   * Get all performance entries
-   */
-  getAllEntries(): PerformanceEntry[] {
-    return [...this.entries];
-  }
- 
-  /**
-   * Clear all performance data
-   */
-  clear(): void {
-    this.entries = [];
-    this.renderTimes.clear();
-  }
- 
-  /**
-   * Generate performance report
-   */
-  generateReport(): string {
-    const report = ['=== React Chrono Performance Report ===\n'];
- 
-    for (const [componentName] of this.renderTimes.entries()) {
-      const stats = this.getStats(componentName);
-      if (stats) {
-        report.push(
-          `📊 ${componentName}:`,
-          `  • Average: ${stats.averageRenderTime.toFixed(2)}ms`,
-          `  • Max: ${stats.maxRenderTime.toFixed(2)}ms`,
-          `  • Min: ${stats.minRenderTime.toFixed(2)}ms`,
-          `  • Total Renders: ${stats.totalRenders}`,
-          '',
-        );
-      }
-    }
- 
-    return report.join('\n');
-  }
- 
-  /**
-   * Enable/disable performance monitoring
-   */
-  setEnabled(enabled: boolean): void {
-    this.isEnabled = enabled;
-  }
-}
- 
-export const performanceMonitor = PerformanceMonitor.getInstance();
- 
-/**
- * React hook for performance monitoring
- * Use this hook to time component renders
- */
-export const usePerformanceMonitor = (componentName: string) => {
-  const endTimingRef = useRef<(() => void) | null>(null);
- 
-  // Start timing on mount and re-renders
-  useEffect(() => {
-    endTimingRef.current = performanceMonitor.startTiming(componentName);
- 
-    // Return cleanup function
-    return () => {
-      if (endTimingRef.current) {
-        endTimingRef.current();
-      }
-    };
-  });
- 
-  // Return cleanup function for manual usage if needed
-  return () => {
-    if (endTimingRef.current) {
-      endTimingRef.current();
-    }
-  };
-};
- 
-/**
- * Higher-order component for performance monitoring
- */
-export function withPerformanceMonitoring<P extends Record<string, any>>(
-  WrappedComponent: React.ComponentType<P>,
-  componentName?: string,
-): React.FC<P> {
-  const displayName =
-    componentName ??
-    WrappedComponent.displayName ??
-    WrappedComponent.name ??
-    'Component';
- 
-  const MemoizedComponent: React.FC<P> = React.memo((props: P) => {
-    // Use the performance monitoring hook
-    usePerformanceMonitor(displayName);
- 
-    return React.createElement(WrappedComponent, props);
-  });
- 
-  MemoizedComponent.displayName = `withPerformanceMonitoring(${displayName})`;
- 
-  return MemoizedComponent;
-}
- 
-/**
- * Utility to measure async operations
- */
-export const measureAsync = async <T>(
-  operation: () => Promise<T>,
-  operationName: string,
-): Promise<T> => {
-  const startTime = performance.now();
- 
-  try {
-    const result = await operation();
-    const endTime = performance.now();
-    const duration = endTime - startTime;
- 
-    if (process.env.NODE_ENV === 'development') {
-      console.log(`⏱️ ${operationName} completed in ${duration.toFixed(2)}ms`);
-    }
- 
-    return result;
-  } catch (error) {
-    const endTime = performance.now();
-    const duration = endTime - startTime;
- 
-    if (process.env.NODE_ENV === 'development') {
-      console.error(
-        `❌ ${operationName} failed after ${duration.toFixed(2)}ms`,
-        error,
-      );
-    }
- 
-    throw error;
-  }
-};
- 
-/**
- * Debounce utility with performance monitoring
- */
-export const createPerformantDebounce = <T extends (...args: any[]) => any>(
-  func: T,
-  delay: number,
-  operationName: string,
-): ((...args: Parameters<T>) => void) => {
-  let timeoutId: NodeJS.Timeout | undefined;
- 
-  return (...args: Parameters<T>) => {
-    if (timeoutId) {
-      clearTimeout(timeoutId);
-    }
- 
-    timeoutId = setTimeout(() => {
-      const startTime = performance.now();
-      func(...args);
-      const endTime = performance.now();
- 
-      if (process.env.NODE_ENV === 'development') {
-        console.log(
-          `🔄 Debounced ${operationName} executed in ${(endTime - startTime).toFixed(2)}ms`,
-        );
-      }
-    }, delay);
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/timelineUtils.test.ts.html b/coverage/lcov-report/utils/timelineUtils.test.ts.html deleted file mode 100644 index befdde995..000000000 --- a/coverage/lcov-report/utils/timelineUtils.test.ts.html +++ /dev/null @@ -1,484 +0,0 @@ - - - - - - Code coverage report for utils/timelineUtils.test.ts - - - - - - - - - -
-
-

All files / utils timelineUtils.test.ts

-
- -
- 100% - Statements - 124/124 -
- - -
- 100% - Branches - 26/26 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 124/124 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -1341x -1x -1x -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -4x -4x -1x -1x -4x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -4x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import React from 'react';
-import {
-  getSearchableText,
-  pauseVideoEmbeds,
-  toggleMediaVisibility,
-  findTimelineElement,
-} from './timelineUtils';
- 
-describe('getSearchableText', () => {
-  it('returns empty string for null/undefined', () => {
-    expect(getSearchableText(null)).toBe('');
-    expect(getSearchableText(undefined)).toBe('');
-  });
-  it('returns string as is', () => {
-    expect(getSearchableText('hello')).toBe('hello');
-  });
-  it('joins array of strings', () => {
-    expect(getSearchableText(['a', 'b', 'c'])).toBe('a b c');
-  });
-  it('recursively extracts text from nested arrays', () => {
-    expect(getSearchableText(['a', ['b', 'c'], 'd'])).toBe('a b c d');
-  });
-  it('extracts text from React elements', () => {
-    const el = React.createElement('span', null, 'foo');
-    expect(getSearchableText(el)).toBe('foo');
-  });
-  it('extracts text from nested React elements', () => {
-    const el = React.createElement('div', null, [
-      'a',
-      React.createElement('span', { key: 'span' }, 'b'),
-      ['c', React.createElement('em', { key: 'em' }, 'd')],
-    ]);
-    expect(getSearchableText(el)).toBe('a b c d');
-  });
-});
- 
-describe('pauseVideoEmbeds', () => {
-  let origConsoleError: any;
-  beforeEach(() => {
-    origConsoleError = console.error;
-    console.error = vi.fn();
-  });
-  afterEach(() => {
-    console.error = origConsoleError;
-  });
-  it('does nothing if element is null', () => {
-    expect(() => pauseVideoEmbeds(null)).not.toThrow();
-  });
-  it('sends postMessage to valid YouTube iframe', () => {
-    const postMessage = vi.fn();
-    const iframe = document.createElement('iframe');
-    iframe.setAttribute('src', 'https://www.youtube.com/embed/xyz');
-    Object.defineProperty(iframe, 'contentWindow', { value: { postMessage } });
-    const container = document.createElement('div');
-    container.appendChild(iframe);
-    pauseVideoEmbeds(container);
-    expect(postMessage).toHaveBeenCalledWith(
-      '{"event":"command","func":"stopVideo","args":""}',
-      'https://www.youtube.com',
-    );
-  });
-  it('sends postMessage to valid Vimeo iframe', () => {
-    const postMessage = vi.fn();
-    const iframe = document.createElement('iframe');
-    iframe.setAttribute('src', 'https://vimeo.com/video/xyz');
-    Object.defineProperty(iframe, 'contentWindow', { value: { postMessage } });
-    const container = document.createElement('div');
-    container.appendChild(iframe);
-    pauseVideoEmbeds(container);
-    expect(postMessage).toHaveBeenCalledWith(
-      '{"method":"pause"}',
-      'https://vimeo.com',
-    );
-  });
-  it('handles invalid iframe src gracefully', () => {
-    const iframe = document.createElement('iframe');
-    iframe.setAttribute('src', 'not-a-valid-url');
-    Object.defineProperty(iframe, 'contentWindow', {
-      value: { postMessage: vi.fn() },
-    });
-    const container = document.createElement('div');
-    container.appendChild(iframe);
-    expect(() => pauseVideoEmbeds(container)).not.toThrow();
-  });
-});
- 
-describe('toggleMediaVisibility', () => {
-  it('does nothing if element is null', () => {
-    expect(() => toggleMediaVisibility(null, true)).not.toThrow();
-  });
-  it('toggles visibility of images and videos', () => {
-    const img = document.createElement('img');
-    const video = document.createElement('video');
-    const div = document.createElement('div');
-    div.appendChild(img);
-    div.appendChild(video);
-    toggleMediaVisibility(div, false);
-    expect(img.style.visibility).toBe('hidden');
-    expect(video.style.visibility).toBe('hidden');
-    toggleMediaVisibility(div, true);
-    expect(img.style.visibility).toBe('visible');
-    expect(video.style.visibility).toBe('visible');
-  });
-});
- 
-describe('findTimelineElement', () => {
-  beforeEach(() => {
-    document.body.innerHTML = '';
-  });
-  it('returns null for missing itemId or timelineMode', () => {
-    expect(findTimelineElement('', 'VERTICAL', '')).toBeNull();
-    expect(findTimelineElement('id', '', '')).toBeNull();
-  });
-  it('finds element by id for vertical mode', () => {
-    const el = document.createElement('div');
-    el.id = 'timeline-vertical-item-foo';
-    document.body.appendChild(el);
-    expect(findTimelineElement('foo', 'VERTICAL', '')).toBe(el);
-  });
-  it('finds element in portal for horizontal mode', () => {
-    const portal = document.createElement('div');
-    portal.id = 'portal';
-    const card = document.createElement('div');
-    card.id = 'timeline-card-bar';
-    portal.appendChild(card);
-    document.body.appendChild(portal);
-    expect(findTimelineElement('bar', 'HORIZONTAL', 'portal')).toBe(card);
-  });
-  it('returns null if not found', () => {
-    expect(findTimelineElement('notfound', 'VERTICAL', '')).toBeNull();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/timelineUtils.ts.html b/coverage/lcov-report/utils/timelineUtils.ts.html deleted file mode 100644 index c7297bc34..000000000 --- a/coverage/lcov-report/utils/timelineUtils.ts.html +++ /dev/null @@ -1,616 +0,0 @@ - - - - - - Code coverage report for utils/timelineUtils.ts - - - - - - - - - -
-
-

All files / utils timelineUtils.ts

-
- -
- 85.95% - Statements - 104/121 -
- - -
- 78.43% - Branches - 40/51 -
- - -
- 100% - Functions - 5/5 -
- - -
- 85.95% - Lines - 104/121 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -1781x -  -  -  -  -  -  -  -  -  -  -  -1x -241x -2x -2x -241x -230x -230x -24x -5x -5x -5x -5x -5x -  -4x -4x -4x -4x -4x -4x -  -  -  -  -  -  -  -  -1x -3x -3x -3x -3x -3x -  -  -3x -3x -1x -1x -3x -1x -1x -1x -1x -1x -1x -  -  -3x -1x -1x -  -  -  -  -  -  -  -3x -1x -1x -3x -  -  -  -  -  -1x -4x -  -3x -3x -3x -3x -3x -  -3x -3x -  -3x -  -3x -  -3x -3x -1x -1x -1x -1x -  -  -  -  -2x -3x -  -  -3x -4x -  -  -4x -  -  -  -  -  -  -1x -3x -3x -3x -3x -  -2x -2x -2x -4x -4x -4x -2x -3x -  -  -3x -  -  -  -  -  -  -  -  -1x -23x -23x -23x -23x -23x -  -21x -21x -21x -  -  -21x -21x -20x -19x -23x -5x -5x -1x -1x -1x -1x -5x -  -21x -23x -  -  -  -23x - 
import React from 'react';
- 
-/**
- * Timeline utility functions for managing timeline functionality
- */
- 
-/**
- * Safely extracts searchable text from potentially complex React node content
- * Recursively processes React nodes into plain text for search operations
- * @param content - React node (string, array, or component) to extract text from
- * @returns Plain text string suitable for searching
- */
-export const getSearchableText = (content: React.ReactNode): string => {
-  if (content === null || content === undefined) {
-    return '';
-  }
-  if (typeof content === 'string') {
-    return content;
-  }
-  if (Array.isArray(content)) {
-    return content
-      .map((item) => getSearchableText(item))
-      .filter(Boolean)
-      .join(' ');
-  }
-  // Handle React elements with children or other complex node types
-  if (React.isValidElement(content)) {
-    const elementProps = content.props as { children?: React.ReactNode };
-    if (elementProps.children) {
-      return getSearchableText(elementProps.children);
-    }
-  }
-  return '';
-};
- 
-/**
- * Safely validates if a URL belongs to a trusted video platform
- * @param url - URL to validate
- * @returns Object with validation result and platform info
- */
-const validateVideoUrl = (
-  url: string,
-): { isValid: boolean; platform?: string; origin?: string } => {
-  try {
-    const parsedUrl = new URL(url);
-    const hostname = parsedUrl.hostname.toLowerCase();
- 
-    // YouTube domains
-    if (
-      hostname === 'www.youtube.com' ||
-      hostname === 'youtube.com' ||
-      hostname === 'youtu.be'
-    ) {
-      return {
-        isValid: true,
-        platform: 'youtube',
-        origin: 'https://www.youtube.com',
-      };
-    }
- 
-    // Vimeo domains
-    if (hostname === 'vimeo.com' || hostname === 'player.vimeo.com') {
-      return { isValid: true, platform: 'vimeo', origin: 'https://vimeo.com' };
-    }
- 
-    // For other HTTPS origins, return the actual origin
-    if (parsedUrl.protocol === 'https:') {
-      return { isValid: true, platform: 'other', origin: parsedUrl.origin };
-    }
- 
-    return { isValid: false };
-  } catch {
-    return { isValid: false };
-  }
-};
- 
-/**
- * Pauses video embeds (primarily YouTube) within an element
- * @param element - HTML element containing video iframes to pause
- */
-export const pauseVideoEmbeds = (element: HTMLElement | null): void => {
-  if (!element) return;
- 
-  try {
-    const iframes = element.querySelectorAll('iframe');
-    iframes.forEach((iframe) => {
-      const src = iframe.getAttribute('src') || '';
-      if (!src || !iframe.contentWindow) return;
- 
-      const validation = validateVideoUrl(src);
-      if (!validation.isValid) return;
- 
-      const targetOrigin = validation.origin || '*';
- 
-      try {
-        // Send appropriate pause command based on platform
-        let message = '';
-        if (validation.platform === 'youtube') {
-          message = '{"event":"command","func":"stopVideo","args":""}';
-        } else if (validation.platform === 'vimeo') {
-          message = '{"method":"pause"}';
-        } else {
-          // Generic pause attempt for other platforms
-          message = '{"event":"command","func":"pause","args":""}';
-        }
- 
-        iframe.contentWindow.postMessage(message, targetOrigin);
-      } catch (error) {
-        console.error('Error sending message to iframe:', error);
-      }
-    });
-  } catch (error) {
-    console.error('Error pausing video embeds:', error);
-  }
-};
- 
-/**
- * Toggles visibility of media elements (images and videos) within an element
- * @param element - HTML element containing media elements
- * @param isVisible - Whether media elements should be visible
- */
-export const toggleMediaVisibility = (
-  element: HTMLElement | null,
-  isVisible: boolean,
-): void => {
-  if (!element) return;
- 
-  try {
-    const mediaElements = element.querySelectorAll('img,video');
-    mediaElements.forEach((ele) => {
-      if (ele instanceof HTMLElement) {
-        ele.style.visibility = isVisible ? 'visible' : 'hidden';
-      }
-    });
-  } catch (error) {
-    console.error('Error toggling media visibility:', error);
-  }
-};
- 
-/**
- * Finds a timeline item element by its ID in either the main timeline or portal
- * @param itemId - ID of the timeline item to find
- * @param timelineMode - Current timeline mode (HORIZONTAL, VERTICAL, etc.)
- * @param portalId - ID of the portal container for horizontal timeline modes
- * @returns HTML element of the timeline item or null if not found
- */
-export const findTimelineElement = (
-  itemId: string,
-  timelineMode: string,
-  portalId: string,
-): HTMLElement | null => {
-  if (!itemId || !timelineMode) return null;
- 
-  try {
-    const elementId = `timeline-${timelineMode.toLowerCase()}-item-${itemId}`;
-    let targetElement = document.getElementById(elementId);
- 
-    // Check in portal for horizontal modes
-    if (
-      !targetElement &&
-      portalId &&
-      (timelineMode === 'HORIZONTAL' || timelineMode === 'HORIZONTAL_ALL')
-    ) {
-      const portalContainer = document.getElementById(portalId);
-      if (portalContainer) {
-        targetElement = portalContainer.querySelector(
-          `#timeline-card-${itemId}`,
-        );
-      }
-    }
- 
-    return targetElement;
-  } catch (error) {
-    console.error('Error finding timeline element:', error);
-    return null;
-  }
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov-report/utils/utils.test.ts.html b/coverage/lcov-report/utils/utils.test.ts.html deleted file mode 100644 index affaae218..000000000 --- a/coverage/lcov-report/utils/utils.test.ts.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - Code coverage report for utils/utils.test.ts - - - - - - - - - -
-
-

All files / utils utils.test.ts

-
- -
- 100% - Statements - 90/90 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 90/90 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108  -1x -1x -1x -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x - 
import { ButtonTexts, TimelineMode } from '@models/TimelineModel';
-import { describe, it, expect } from 'vitest';
-import { darkTheme, defaultTheme } from '../components/common/themes';
-import {
-  getDefaultButtonTexts,
-  getDefaultClassNames,
-  getDefaultThemeOrDark,
-  getSlideShowType,
-  getUniqueID,
-  hexToRGBA,
-} from './index'; // Update the path accordingly
- 
-describe('Utility Functions', () => {
-  it('uniqueID should generate a unique ID of length 7', () => {
-    const id = getUniqueID();
-    expect(id).toHaveLength(7);
-  });
- 
-  it('hexToRGBA should convert hex to rgba', () => {
-    const rgba = hexToRGBA('#FF5733', 0.5);
-    expect(rgba).toBe('rgba(255, 87, 51, 0.5)');
-  });
- 
-  it('getDefaultThemeOrDark should return dark theme if isDark is true', () => {
-    expect(getDefaultThemeOrDark(true)).toEqual(darkTheme);
-  });
- 
-  it('getDefaultThemeOrDark should return default theme if isDark is false or undefined', () => {
-    expect(getDefaultThemeOrDark(false)).toEqual(defaultTheme);
-    expect(getDefaultThemeOrDark()).toEqual(defaultTheme);
-  });
- 
-  it('getDefaultClassNames should return default class names', () => {
-    expect(getDefaultClassNames()).toEqual({
-      card: 'rc-card',
-      cardMedia: 'rc-card-media',
-      cardSubTitle: 'rc-card-subtitle',
-      cardText: 'rc-card-text',
-      cardTitle: 'rc-card-title',
-      controls: 'rc-controls',
-      title: 'rc-title',
-    });
-  });
- 
-  it('getDefaultButtonTexts should return default button texts', () => {
-    expect(getDefaultButtonTexts()).toEqual({
-      changeDensity: 'Change density',
-      changeDensityOptions: {
-        high: {
-          helpText: 'Show more items at once',
-          text: 'High',
-        },
-        low: {
-          helpText: 'Show fewer items at once',
-          text: 'Low',
-        },
-      },
-      changeLayout: 'Change layout',
-      changeLayoutOptions: {
-        alternating: {
-          helpText: 'Show cards in a vertical layout with alternating fashion',
-          text: 'Alternating',
-        },
-        horizontal: {
-          helpText: 'Show cards in a horizontal layout',
-          text: 'Horizontal',
-        },
-        horizontal_all: {
-          helpText: 'Show all cards in a horizontal layout',
-          text: 'Show all cards',
-        },
-        vertical: {
-          helpText: 'Show cards in a vertical layout',
-          text: 'Vertical',
-        },
-      },
-      dark: 'Switch to Dark Mode',
-      first: 'Go to First',
-      jumpTo: 'Jump to',
-      last: 'Go to Last',
-      light: 'Switch to Light Mode',
-      next: 'Next',
-      play: 'Play Slideshow',
-      previous: 'Previous',
-      stop: 'Stop Slideshow',
-      searchPlaceholder: 'Search Timeline',
-      searchAriaLabel: 'Search timeline content',
-      clearSearch: 'Clear Search',
-      previousMatch: 'Previous Match',
-      nextMatch: 'Next Match',
-      timelinePoint: 'Timeline point',
-    } as ButtonTexts);
-  });
- 
-  it('getSlideShowType should return reveal for HORIZONTAL and VERTICAL modes', () => {
-    expect(getSlideShowType('HORIZONTAL')).toBe('reveal');
-    expect(getSlideShowType('VERTICAL')).toBe('reveal');
-  });
- 
-  it('getSlideShowType should return slide_from_sides for VERTICAL_ALTERNATING mode', () => {
-    expect(getSlideShowType('VERTICAL_ALTERNATING')).toBe('slide_from_sides');
-  });
- 
-  it('getSlideShowType should return reveal for other modes', () => {
-    expect(getSlideShowType('OTHER_MODE' as TimelineMode)).toBe('reveal');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/lcov.info b/coverage/lcov.info deleted file mode 100644 index 080aa37c2..000000000 --- a/coverage/lcov.info +++ /dev/null @@ -1,15394 +0,0 @@ -TN: -SF:src/__tests__/react-chrono.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:10,1 -DA:12,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:34,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:64,1 -DA:66,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:141,1 -DA:143,1 -DA:144,1 -DA:145,1 -DA:146,1 -DA:147,1 -DA:148,1 -DA:149,1 -LF:126 -LH:126 -BRDA:5,0,0,1 -BRDA:6,1,0,1 -BRDA:12,2,0,1 -BRDA:28,3,0,1 -BRDA:34,4,0,1 -BRDA:64,5,0,1 -BRDA:72,6,0,1 -BRDA:97,7,0,1 -BRDA:133,8,0,1 -BRF:9 -BRH:9 -end_of_record -TN: -SF:src/components/__tests__/GlobalContext.test.tsx -FN:49,TestContextConsumer -FN:60,TestWrapper -FN:64,renderWithContext -FN:70,contextCapture -FN:83,getContext -FN:91,createMockButtonTexts -FN:108,createMockClassNames -FN:118,createMockTheme -FN:232,onContextValue -FN:272,onContextValue -FN:300,onContextValue -FNF:11 -FNH:11 -FNDA:48,TestContextConsumer -FNDA:43,TestWrapper -FNDA:39,renderWithContext -FNDA:45,contextCapture -FNDA:45,getContext -FNDA:41,createMockButtonTexts -FNDA:41,createMockClassNames -FNDA:41,createMockTheme -FNDA:1,onContextValue -FNDA:1,onContextValue -FNDA:1,onContextValue -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:49,1 -DA:50,48 -DA:51,48 -DA:52,48 -DA:53,48 -DA:60,1 -DA:61,43 -DA:64,1 -DA:65,39 -DA:66,39 -DA:67,39 -DA:68,39 -DA:70,39 -DA:71,45 -DA:72,45 -DA:73,45 -DA:75,39 -DA:76,39 -DA:77,39 -DA:78,39 -DA:79,39 -DA:81,39 -DA:82,39 -DA:83,39 -DA:84,39 -DA:85,39 -DA:91,1 -DA:92,41 -DA:93,41 -DA:94,41 -DA:95,41 -DA:96,41 -DA:97,41 -DA:98,41 -DA:99,41 -DA:100,41 -DA:101,41 -DA:102,41 -DA:103,41 -DA:104,41 -DA:105,41 -DA:106,41 -DA:108,1 -DA:109,41 -DA:110,41 -DA:111,41 -DA:112,41 -DA:113,41 -DA:114,41 -DA:115,41 -DA:116,41 -DA:118,1 -DA:119,41 -DA:120,41 -DA:121,41 -DA:122,41 -DA:123,41 -DA:124,41 -DA:125,41 -DA:126,41 -DA:127,41 -DA:128,41 -DA:129,41 -DA:130,41 -DA:131,41 -DA:132,41 -DA:133,41 -DA:134,41 -DA:135,41 -DA:136,41 -DA:137,41 -DA:138,41 -DA:139,41 -DA:140,41 -DA:146,1 -DA:147,1 -DA:148,40 -DA:149,40 -DA:150,40 -DA:151,40 -DA:152,40 -DA:153,1 -DA:155,1 -DA:156,40 -DA:157,1 -DA:163,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:167,1 -DA:168,1 -DA:169,1 -DA:171,1 -DA:172,1 -DA:174,1 -DA:175,1 -DA:176,1 -DA:178,1 -DA:179,1 -DA:180,1 -DA:181,1 -DA:182,1 -DA:183,1 -DA:185,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:190,1 -DA:191,1 -DA:192,1 -DA:194,1 -DA:195,1 -DA:197,1 -DA:198,1 -DA:199,1 -DA:200,1 -DA:201,1 -DA:202,1 -DA:203,1 -DA:209,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:213,1 -DA:214,1 -DA:216,1 -DA:217,1 -DA:218,1 -DA:219,1 -DA:220,1 -DA:221,1 -DA:223,1 -DA:224,1 -DA:226,1 -DA:227,1 -DA:228,1 -DA:230,1 -DA:231,1 -DA:232,1 -DA:233,1 -DA:234,1 -DA:236,1 -DA:237,1 -DA:239,1 -DA:240,1 -DA:242,1 -DA:243,1 -DA:244,1 -DA:245,1 -DA:246,1 -DA:247,1 -DA:248,1 -DA:250,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:254,1 -DA:255,1 -DA:256,1 -DA:258,1 -DA:259,1 -DA:260,1 -DA:261,1 -DA:263,1 -DA:264,1 -DA:266,1 -DA:267,1 -DA:268,1 -DA:270,1 -DA:271,1 -DA:272,1 -DA:273,1 -DA:274,1 -DA:276,1 -DA:277,1 -DA:278,1 -DA:280,1 -DA:281,1 -DA:282,1 -DA:283,1 -DA:284,1 -DA:286,1 -DA:287,1 -DA:288,1 -DA:289,1 -DA:291,1 -DA:292,1 -DA:294,1 -DA:295,1 -DA:296,1 -DA:298,1 -DA:299,1 -DA:300,1 -DA:301,1 -DA:302,1 -DA:304,1 -DA:305,1 -DA:306,1 -DA:307,1 -DA:313,1 -DA:314,1 -DA:315,1 -DA:316,1 -DA:317,1 -DA:318,1 -DA:319,1 -DA:320,1 -DA:321,1 -DA:323,1 -DA:324,1 -DA:325,1 -DA:326,1 -DA:327,1 -DA:328,1 -DA:329,1 -DA:331,1 -DA:332,1 -DA:333,1 -DA:334,1 -DA:335,1 -DA:337,1 -DA:338,1 -DA:339,1 -DA:341,1 -DA:342,1 -DA:343,1 -DA:347,1 -DA:348,1 -DA:350,1 -DA:351,1 -DA:352,1 -DA:353,1 -DA:354,1 -DA:355,1 -DA:359,1 -DA:360,1 -DA:362,1 -DA:363,1 -DA:364,1 -DA:365,1 -DA:366,1 -DA:367,1 -DA:371,1 -DA:372,1 -DA:373,1 -DA:375,1 -DA:376,1 -DA:377,1 -DA:378,1 -DA:379,1 -DA:380,1 -DA:381,1 -DA:382,1 -DA:383,1 -DA:384,1 -DA:385,1 -DA:386,1 -DA:388,1 -DA:389,1 -DA:390,1 -DA:391,1 -DA:392,1 -DA:393,1 -DA:394,1 -DA:395,1 -DA:396,1 -DA:397,1 -DA:398,1 -DA:399,1 -DA:401,1 -DA:402,1 -DA:403,1 -DA:404,1 -DA:405,1 -DA:406,1 -DA:407,1 -DA:408,1 -DA:410,1 -DA:411,1 -DA:412,1 -DA:413,1 -DA:414,1 -DA:415,1 -DA:416,1 -DA:418,1 -DA:419,1 -DA:420,1 -DA:421,1 -DA:422,1 -DA:423,1 -DA:424,1 -DA:425,1 -DA:426,1 -DA:432,1 -DA:433,1 -DA:434,3 -DA:435,1 -DA:437,1 -DA:438,1 -DA:439,1 -DA:440,1 -DA:441,1 -DA:443,1 -DA:444,1 -DA:445,1 -DA:446,1 -DA:447,1 -DA:448,1 -DA:449,1 -DA:450,1 -DA:451,1 -DA:453,1 -DA:454,1 -DA:455,1 -DA:456,1 -DA:458,1 -DA:459,1 -DA:460,1 -DA:461,1 -DA:462,1 -DA:464,1 -DA:465,1 -DA:466,1 -DA:468,1 -DA:469,6 -DA:470,3 -DA:471,3 -DA:472,3 -DA:473,3 -DA:474,6 -DA:475,1 -DA:478,1 -DA:479,1 -DA:482,1 -DA:483,1 -DA:484,1 -DA:487,1 -DA:490,1 -DA:491,1 -DA:492,1 -DA:495,1 -DA:498,1 -DA:499,1 -DA:500,1 -DA:501,1 -DA:502,1 -DA:503,1 -DA:504,1 -DA:505,1 -DA:506,1 -DA:507,1 -DA:513,1 -DA:514,1 -DA:515,1 -DA:516,1 -DA:517,1 -DA:518,1 -DA:519,1 -DA:520,1 -DA:521,1 -DA:522,1 -DA:523,1 -DA:525,1 -DA:526,1 -DA:527,1 -DA:528,1 -DA:529,1 -DA:531,1 -DA:532,1 -DA:533,1 -DA:534,1 -DA:535,1 -DA:537,1 -DA:538,1 -DA:539,1 -DA:540,1 -DA:541,1 -DA:543,1 -DA:544,1 -DA:545,1 -DA:546,1 -DA:547,1 -DA:549,1 -DA:550,1 -DA:551,1 -DA:552,1 -DA:553,1 -DA:555,1 -DA:556,1 -DA:557,1 -DA:558,1 -DA:559,1 -DA:561,1 -DA:562,1 -DA:563,1 -DA:564,1 -DA:565,1 -DA:566,1 -DA:568,1 -DA:569,1 -DA:571,1 -DA:572,1 -DA:573,1 -DA:574,1 -DA:575,1 -DA:576,1 -DA:578,1 -DA:579,1 -DA:580,1 -DA:581,1 -DA:582,1 -DA:583,1 -DA:589,1 -DA:590,1 -DA:591,1 -DA:592,1 -DA:594,1 -DA:595,1 -DA:596,1 -DA:597,1 -DA:598,1 -DA:599,1 -DA:600,1 -DA:601,1 -DA:602,1 -DA:603,1 -DA:604,1 -DA:605,1 -DA:606,1 -DA:607,1 -DA:608,1 -DA:609,1 -DA:610,1 -DA:611,1 -DA:612,1 -DA:614,1 -DA:615,1 -DA:616,1 -DA:617,1 -DA:618,1 -DA:619,1 -DA:620,1 -DA:622,1 -DA:623,1 -DA:624,1 -DA:625,1 -DA:626,1 -DA:627,1 -DA:628,1 -DA:634,1 -DA:635,1 -DA:636,1 -DA:638,1 -DA:639,1 -DA:640,1 -DA:641,1 -DA:643,1 -DA:644,1 -DA:645,1 -DA:646,1 -DA:648,1 -DA:649,1 -DA:650,1 -DA:652,1 -DA:653,1 -DA:654,1 -DA:655,1 -DA:657,1 -DA:658,1 -DA:659,1 -DA:660,1 -DA:661,1 -DA:662,1 -DA:668,1 -DA:669,1 -DA:670,1 -DA:671,1 -DA:672,1 -DA:673,1 -DA:675,1 -DA:676,1 -DA:677,1 -DA:678,1 -DA:679,1 -DA:681,1 -DA:682,1 -DA:683,1 -DA:685,1 -DA:686,1 -DA:688,1 -DA:690,1 -DA:691,1 -DA:692,1 -DA:693,1 -DA:699,1 -DA:700,1 -DA:701,1 -DA:702,1 -DA:703,1 -DA:704,1 -DA:705,1 -DA:706,1 -DA:708,1 -DA:709,1 -DA:710,1 -DA:711,1 -DA:712,1 -DA:713,1 -DA:714,1 -DA:716,1 -DA:717,1 -DA:718,1 -DA:719,1 -DA:720,1 -DA:721,1 -DA:723,1 -DA:724,1 -DA:726,1 -DA:727,1 -DA:728,1 -DA:730,1 -DA:731,1 -DA:732,1 -DA:733,1 -DA:734,1 -DA:735,1 -LF:553 -LH:553 -BRDA:22,0,0,1 -BRDA:30,1,0,1 -BRDA:37,2,0,1 -BRDA:49,3,0,48 -BRDA:60,4,0,43 -BRDA:64,5,0,39 -BRDA:70,6,0,45 -BRDA:72,7,0,0 -BRDA:83,8,0,45 -BRDA:91,9,0,41 -BRDA:108,10,0,41 -BRDA:118,11,0,41 -BRDA:146,12,0,1 -BRDA:147,13,0,40 -BRDA:155,14,0,40 -BRDA:163,15,0,1 -BRDA:164,16,0,1 -BRDA:174,17,0,1 -BRDA:185,18,0,1 -BRDA:209,19,0,1 -BRDA:210,20,0,1 -BRDA:211,21,0,1 -BRDA:216,22,0,1 -BRDA:226,23,0,1 -BRDA:232,24,0,1 -BRDA:239,25,0,1 -BRDA:242,26,0,1 -BRDA:243,27,0,1 -BRDA:250,28,0,1 -BRDA:251,29,0,1 -BRDA:258,30,0,1 -BRDA:266,31,0,1 -BRDA:272,32,0,1 -BRDA:280,33,0,1 -BRDA:281,34,0,1 -BRDA:286,35,0,1 -BRDA:294,36,0,1 -BRDA:300,37,0,1 -BRDA:313,38,0,1 -BRDA:314,39,0,1 -BRDA:315,40,0,1 -BRDA:323,41,0,1 -BRDA:331,42,0,1 -BRDA:341,43,0,1 -BRDA:342,44,0,1 -BRDA:350,45,0,1 -BRDA:362,46,0,1 -BRDA:375,47,0,1 -BRDA:376,48,0,1 -BRDA:388,49,0,1 -BRDA:401,50,0,1 -BRDA:402,51,0,1 -BRDA:410,52,0,1 -BRDA:418,53,0,1 -BRDA:432,54,0,1 -BRDA:433,55,0,3 -BRDA:437,56,0,1 -BRDA:453,57,0,1 -BRDA:464,58,0,1 -BRDA:468,59,0,6 -BRDA:469,60,0,3 -BRDA:482,61,0,1 -BRDA:490,62,0,1 -BRDA:513,63,0,1 -BRDA:514,64,0,1 -BRDA:531,65,0,1 -BRDA:543,66,0,1 -BRDA:555,67,0,1 -BRDA:571,68,0,1 -BRDA:589,69,0,1 -BRDA:590,70,0,1 -BRDA:614,71,0,1 -BRDA:634,72,0,1 -BRDA:635,73,0,1 -BRDA:643,74,0,1 -BRDA:652,75,0,1 -BRDA:668,76,0,1 -BRDA:669,77,0,1 -BRDA:681,78,0,1 -BRDA:699,79,0,1 -BRDA:700,80,0,1 -BRDA:708,81,0,1 -BRDA:716,82,0,1 -BRDA:726,83,0,1 -BRF:84 -BRH:83 -end_of_record -TN: -SF:src/components/common/styles/index.ts -FNF:0 -FNH:0 -DA:2,1 -DA:4,1 -DA:5,1 -DA:17,1 -DA:18,1 -LF:5 -LH:5 -BRDA:5,0,0,10 -BRDA:17,1,0,10 -BRDA:18,2,0,10 -BRF:3 -BRH:3 -end_of_record -TN: -SF:src/components/common/themes/index.ts -FNF:0 -FNH:0 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -LF:74 -LH:74 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/contexts/DynamicContext.tsx -FN:54,toggleDarkMode -FN:55,updateHorizontalAllCards -FN:56,updateTextContentDensity -FNF:3 -FNH:0 -FNDA:0,toggleDarkMode -FNDA:0,updateHorizontalAllCards -FNDA:0,updateTextContentDensity -DA:5,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -LF:33 -LH:33 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/contexts/OptimizedContextProvider.tsx -FN:37,OptimizedContextProvider -FN:90,onMatch -FN:95,onMatch -FNF:3 -FNH:3 -FNDA:51,OptimizedContextProvider -FNDA:1,onMatch -FNDA:1,onMatch -DA:4,1 -DA:14,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:35,1 -DA:37,1 -DA:38,51 -DA:39,51 -DA:40,51 -DA:41,51 -DA:42,51 -DA:43,51 -DA:44,51 -DA:45,51 -DA:46,51 -DA:47,51 -DA:48,51 -DA:49,51 -DA:50,51 -DA:51,51 -DA:52,51 -DA:53,51 -DA:54,51 -DA:55,51 -DA:56,51 -DA:57,51 -DA:58,51 -DA:59,51 -DA:60,51 -DA:61,51 -DA:66,51 -DA:67,51 -DA:68,51 -DA:69,51 -DA:70,51 -DA:71,51 -DA:72,51 -DA:75,51 -DA:76,2 -DA:77,2 -DA:78,51 -DA:80,51 -DA:81,1 -DA:82,51 -DA:84,51 -DA:85,1 -DA:86,51 -DA:89,51 -DA:90,51 -DA:91,51 -DA:92,51 -DA:94,51 -DA:95,51 -DA:96,51 -DA:97,51 -DA:102,51 -DA:103,51 -DA:104,42 -DA:105,42 -DA:106,42 -DA:107,42 -DA:108,42 -DA:109,42 -DA:110,42 -DA:111,42 -DA:112,42 -DA:113,42 -DA:114,42 -DA:115,42 -DA:116,42 -DA:117,42 -DA:118,42 -DA:119,42 -DA:120,42 -DA:121,42 -DA:122,42 -DA:123,42 -DA:124,42 -DA:125,42 -DA:126,42 -DA:127,42 -DA:128,42 -DA:129,42 -DA:130,51 -DA:131,51 -DA:132,51 -DA:133,51 -DA:134,51 -DA:135,51 -DA:136,51 -DA:137,51 -DA:138,51 -DA:139,51 -DA:140,51 -DA:141,51 -DA:142,51 -DA:143,51 -DA:144,51 -DA:145,51 -DA:146,51 -DA:147,51 -DA:148,51 -DA:149,51 -DA:150,51 -DA:151,51 -DA:152,51 -DA:153,51 -DA:154,51 -DA:155,51 -DA:157,51 -DA:158,51 -DA:159,42 -DA:160,51 -DA:161,51 -DA:163,51 -DA:164,42 -DA:165,42 -DA:166,42 -DA:167,0 -DA:168,42 -DA:169,51 -DA:171,51 -DA:172,51 -DA:173,51 -DA:174,51 -DA:176,51 -DA:177,51 -DA:178,51 -DA:179,51 -DA:181,51 -DA:183,51 -DA:184,51 -DA:185,51 -DA:186,51 -DA:188,51 -DA:189,51 -DA:190,42 -DA:191,42 -DA:192,42 -DA:193,51 -DA:194,51 -DA:196,51 -DA:197,51 -DA:198,42 -DA:199,42 -DA:200,42 -DA:201,51 -DA:202,51 -DA:204,51 -DA:205,51 -DA:206,42 -DA:207,42 -DA:208,42 -DA:209,42 -DA:210,42 -DA:211,42 -DA:212,51 -DA:213,51 -DA:215,51 -DA:216,51 -DA:217,42 -DA:218,42 -DA:219,42 -DA:220,42 -DA:221,51 -DA:222,51 -DA:224,51 -DA:225,51 -DA:226,42 -DA:227,42 -DA:228,42 -DA:229,42 -DA:230,51 -DA:231,51 -DA:236,51 -DA:237,51 -DA:238,51 -DA:239,51 -DA:240,51 -DA:241,51 -DA:242,51 -DA:243,51 -DA:244,51 -DA:245,51 -DA:246,51 -DA:247,51 -DA:248,51 -DA:251,51 -DA:252,51 -DA:253,51 -DA:254,51 -DA:255,51 -DA:256,51 -DA:257,51 -DA:258,51 -DA:259,51 -DA:260,51 -DA:261,51 -DA:262,51 -DA:263,51 -DA:264,51 -DA:265,51 -DA:266,51 -DA:267,51 -DA:268,51 -DA:269,51 -DA:270,51 -DA:271,51 -DA:272,51 -DA:273,51 -DA:274,51 -DA:275,51 -DA:276,51 -DA:277,51 -DA:278,51 -DA:279,51 -DA:280,51 -DA:281,51 -DA:282,51 -DA:283,51 -DA:284,51 -DA:285,51 -DA:286,51 -DA:287,51 -DA:288,51 -DA:289,51 -DA:290,51 -DA:291,51 -DA:292,51 -DA:293,51 -DA:294,51 -DA:295,51 -DA:296,51 -DA:297,51 -DA:298,51 -DA:299,51 -DA:300,51 -DA:301,51 -DA:302,51 -DA:303,51 -DA:304,51 -DA:305,51 -DA:306,51 -DA:307,51 -DA:308,51 -DA:309,51 -DA:310,51 -DA:311,51 -DA:312,51 -DA:313,51 -DA:314,51 -DA:315,51 -DA:316,51 -DA:317,51 -DA:318,51 -DA:319,51 -DA:320,51 -DA:321,51 -DA:322,51 -DA:323,51 -DA:324,51 -DA:325,51 -DA:326,51 -DA:331,51 -DA:332,51 -DA:333,44 -DA:334,44 -DA:335,44 -DA:336,51 -DA:337,51 -DA:339,51 -DA:340,51 -DA:341,48 -DA:342,48 -DA:343,48 -DA:344,48 -DA:345,48 -DA:346,48 -DA:347,48 -DA:348,48 -DA:349,48 -DA:350,51 -DA:351,51 -DA:352,51 -DA:353,51 -DA:354,51 -DA:355,51 -DA:356,51 -DA:357,51 -DA:358,51 -DA:359,51 -DA:360,51 -DA:362,51 -DA:363,51 -DA:364,51 -DA:365,51 -DA:366,51 -DA:367,51 -DA:369,51 -LF:300 -LH:299 -BRDA:37,0,0,51 -BRDA:68,1,0,47 -BRDA:75,2,0,2 -BRDA:77,3,0,1 -BRDA:80,4,0,1 -BRDA:84,5,0,1 -BRDA:90,6,0,1 -BRDA:95,7,0,1 -BRDA:103,8,0,42 -BRDA:104,9,0,41 -BRDA:107,10,0,39 -BRDA:113,11,0,41 -BRDA:121,12,0,41 -BRDA:123,13,0,40 -BRDA:124,14,0,41 -BRDA:158,15,0,42 -BRDA:159,16,0,0 -BRDA:159,17,0,0 -BRDA:163,18,0,42 -BRDA:165,19,0,0 -BRDA:166,20,0,0 -BRDA:172,21,0,42 -BRDA:172,22,0,3 -BRDA:172,23,0,0 -BRDA:172,24,0,39 -BRDA:177,25,0,42 -BRDA:177,26,0,3 -BRDA:177,27,0,39 -BRDA:181,28,0,42 -BRDA:184,29,0,42 -BRDA:184,30,0,3 -BRDA:184,31,0,2 -BRDA:184,32,0,40 -BRDA:189,33,0,42 -BRDA:197,34,0,42 -BRDA:205,35,0,42 -BRDA:216,36,0,42 -BRDA:225,37,0,42 -BRDA:237,38,0,51 -BRDA:265,39,0,50 -BRDA:267,40,0,0 -BRDA:269,41,0,49 -BRDA:272,42,0,50 -BRDA:332,43,0,44 -BRDA:340,44,0,48 -BRF:45 -BRH:39 -end_of_record -TN: -SF:src/components/contexts/StableContext.tsx -FNF:0 -FNH:0 -DA:5,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:141,1 -LF:55 -LH:55 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/contexts/hooks.tsx -FN:19,useLegacyGlobalContext -FN:26,convertLegacyToStable -FN:108,convertLegacyToDynamic -FN:127,useStableContext -FN:148,useDynamicContext -FN:171,useGlobalContext -FN:185,useTimelineContext -FNF:7 -FNH:5 -FNDA:59,useLegacyGlobalContext -FNDA:59,convertLegacyToStable -FNDA:0,convertLegacyToDynamic -FNDA:59,useStableContext -FNDA:58,useDynamicContext -FNDA:51,useGlobalContext -FNDA:0,useTimelineContext -DA:5,1 -DA:6,1 -DA:7,1 -DA:10,1 -DA:11,1 -DA:19,1 -DA:20,59 -DA:21,59 -DA:26,1 -DA:27,59 -DA:28,59 -DA:29,59 -DA:30,59 -DA:31,59 -DA:32,59 -DA:33,59 -DA:34,59 -DA:35,59 -DA:36,59 -DA:37,59 -DA:38,59 -DA:39,59 -DA:40,59 -DA:41,59 -DA:42,59 -DA:43,59 -DA:44,59 -DA:45,59 -DA:46,59 -DA:47,59 -DA:48,59 -DA:49,59 -DA:50,59 -DA:51,59 -DA:52,59 -DA:53,59 -DA:54,59 -DA:55,59 -DA:56,59 -DA:57,59 -DA:58,59 -DA:59,59 -DA:60,59 -DA:61,59 -DA:62,59 -DA:63,59 -DA:64,59 -DA:65,59 -DA:66,59 -DA:67,59 -DA:68,59 -DA:69,59 -DA:70,59 -DA:71,59 -DA:72,59 -DA:73,59 -DA:74,59 -DA:75,59 -DA:76,59 -DA:77,59 -DA:78,59 -DA:79,59 -DA:80,59 -DA:81,59 -DA:82,59 -DA:83,59 -DA:84,59 -DA:85,59 -DA:86,59 -DA:87,59 -DA:88,59 -DA:89,59 -DA:90,59 -DA:91,59 -DA:92,59 -DA:93,59 -DA:94,59 -DA:95,59 -DA:96,59 -DA:97,59 -DA:98,59 -DA:99,59 -DA:100,59 -DA:101,59 -DA:102,59 -DA:103,59 -DA:108,1 -DA:109,0 -DA:110,0 -DA:111,0 -DA:112,0 -DA:113,0 -DA:114,0 -DA:115,0 -DA:116,0 -DA:117,0 -DA:118,0 -DA:119,0 -DA:120,0 -DA:121,0 -DA:127,1 -DA:128,59 -DA:132,59 -DA:133,59 -DA:134,59 -DA:135,59 -DA:136,0 -DA:137,0 -DA:140,59 -DA:141,59 -DA:142,59 -DA:148,1 -DA:149,58 -DA:153,58 -DA:154,58 -DA:155,58 -DA:156,58 -DA:157,58 -DA:158,58 -DA:159,58 -DA:162,0 -DA:163,0 -DA:164,0 -DA:171,1 -DA:172,51 -DA:173,51 -DA:175,51 -DA:176,51 -DA:177,51 -DA:178,51 -DA:179,51 -DA:185,1 -LF:132 -LH:114 -BRDA:19,0,0,59 -BRDA:26,1,0,59 -BRDA:34,2,0,0 -BRDA:41,3,0,0 -BRDA:45,4,0,0 -BRDA:46,5,0,0 -BRDA:47,6,0,0 -BRDA:48,7,0,0 -BRDA:49,8,0,0 -BRDA:51,9,0,0 -BRDA:55,10,0,0 -BRDA:66,11,0,0 -BRDA:127,12,0,59 -BRDA:135,13,0,0 -BRDA:148,14,0,58 -BRDA:159,15,0,0 -BRDA:171,16,0,51 -BRF:17 -BRH:5 -end_of_record -TN: -SF:src/components/contexts/index.tsx -FNF:0 -FNH:0 -DA:4,1 -DA:5,1 -DA:6,1 -DA:15,1 -LF:4 -LH:4 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/contexts/legacy-types.tsx -FNF:0 -FNH:0 -DA:5,1 -DA:36,1 -LF:2 -LH:2 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/effects/useCloseClickOutside.ts -FN:10,useCloseClickOutside -FNF:1 -FNH:1 -FNDA:42,useCloseClickOutside -DA:2,1 -DA:3,1 -DA:10,42 -DA:11,42 -DA:12,42 -DA:13,42 -DA:14,42 -DA:15,42 -DA:16,42 -LF:9 -LH:9 -BRDA:10,0,0,42 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/effects/useMatchMedia.ts -FN:36,useMatchMedia -FN:54,handleResize.maxWait -FNF:2 -FNH:2 -FNDA:23,useMatchMedia -FNDA:1,handleResize.maxWait -DA:1,1 -DA:2,1 -DA:3,1 -DA:36,1 -DA:37,23 -DA:38,23 -DA:39,23 -DA:40,23 -DA:41,23 -DA:42,23 -DA:45,23 -DA:46,23 -DA:47,9 -DA:48,9 -DA:49,9 -DA:50,23 -DA:51,23 -DA:53,23 -DA:54,23 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,23 -DA:61,23 -DA:62,23 -DA:65,23 -DA:66,14 -DA:67,1 -DA:68,1 -DA:70,13 -DA:73,14 -DA:74,0 -DA:75,0 -DA:77,13 -DA:78,13 -DA:80,14 -DA:81,5 -DA:82,5 -DA:85,8 -DA:88,8 -DA:91,8 -DA:92,8 -DA:93,8 -DA:94,8 -DA:95,8 -DA:96,8 -DA:97,8 -DA:98,8 -DA:99,23 -DA:102,23 -DA:103,23 -DA:105,23 -DA:106,21 -DA:107,1 -DA:108,1 -DA:109,23 -DA:111,23 -DA:112,23 -LF:59 -LH:57 -BRDA:36,0,0,23 -BRDA:46,1,0,9 -BRDA:47,2,0,0 -BRDA:54,3,0,1 -BRDA:55,4,0,0 -BRDA:65,5,0,14 -BRDA:66,6,0,13 -BRDA:66,7,0,1 -BRDA:68,8,0,13 -BRDA:73,9,0,0 -BRDA:75,10,0,13 -BRDA:80,11,0,5 -BRDA:82,12,0,8 -BRDA:91,13,0,8 -BRDA:105,14,0,21 -BRDA:106,15,0,6 -BRDA:106,16,0,1 -BRF:17 -BRH:14 -end_of_record -TN: -SF:src/components/effects/useNewScrollPosition.ts -FN:12,useNewScrollPosition -FN:19,computeHorizontalOffset -FN:47,computeVerticalOffset -FNF:3 -FNH:3 -FNDA:36,useNewScrollPosition -FNDA:7,computeHorizontalOffset -FNDA:5,computeVerticalOffset -DA:3,1 -DA:12,1 -DA:13,36 -DA:14,36 -DA:15,36 -DA:17,36 -DA:19,36 -DA:20,7 -DA:21,7 -DA:22,7 -DA:23,7 -DA:24,7 -DA:25,7 -DA:26,7 -DA:27,7 -DA:28,7 -DA:30,7 -DA:31,7 -DA:32,7 -DA:33,6 -DA:35,7 -DA:36,7 -DA:38,7 -DA:39,7 -DA:40,6 -DA:41,4 -DA:42,7 -DA:43,5 -DA:44,5 -DA:45,7 -DA:47,36 -DA:48,5 -DA:49,5 -DA:50,5 -DA:51,5 -DA:52,5 -DA:53,5 -DA:54,5 -DA:55,5 -DA:57,5 -DA:58,5 -DA:59,5 -DA:60,5 -DA:62,5 -DA:63,5 -DA:65,5 -DA:66,1 -DA:67,5 -DA:68,3 -DA:69,3 -DA:70,5 -DA:73,36 -DA:74,36 -DA:75,13 -DA:76,13 -DA:77,13 -DA:78,13 -DA:79,13 -DA:80,13 -DA:81,13 -DA:83,13 -DA:84,7 -DA:85,7 -DA:86,7 -DA:87,7 -DA:88,7 -DA:89,7 -DA:90,7 -DA:91,7 -DA:92,13 -DA:93,5 -DA:94,5 -DA:95,5 -DA:96,5 -DA:97,5 -DA:98,5 -DA:99,5 -DA:100,5 -DA:101,13 -DA:102,36 -DA:103,36 -DA:106,36 -DA:107,36 -DA:109,1 -LF:84 -LH:84 -BRDA:12,0,0,36 -BRDA:19,1,0,7 -BRDA:30,2,0,6 -BRDA:32,3,0,1 -BRDA:32,4,0,6 -BRDA:33,5,0,2 -BRDA:39,6,0,3 -BRDA:39,7,0,6 -BRDA:40,8,0,3 -BRDA:40,9,0,4 -BRDA:41,10,0,2 -BRDA:42,11,0,5 -BRDA:47,12,0,5 -BRDA:59,13,0,0 -BRDA:60,14,0,4 -BRDA:63,15,0,1 -BRDA:65,16,0,4 -BRDA:65,17,0,1 -BRDA:67,18,0,4 -BRDA:67,19,0,3 -BRDA:74,20,0,24 -BRDA:74,21,0,13 -BRDA:83,22,0,8 -BRDA:83,23,0,7 -BRDA:92,24,0,6 -BRDA:92,25,0,2 -BRDA:92,26,0,5 -BRF:27 -BRH:26 -end_of_record -TN: -SF:src/components/effects/useSlideshow.ts -FN:24,useSlideshow -FNF:1 -FNH:1 -FNDA:52,useSlideshow -DA:1,1 -DA:24,1 -DA:25,52 -DA:26,52 -DA:27,52 -DA:28,52 -DA:29,52 -DA:30,52 -DA:31,52 -DA:32,52 -DA:33,52 -DA:34,52 -DA:35,52 -DA:36,52 -DA:37,52 -DA:38,52 -DA:39,52 -DA:44,52 -DA:46,137 -DA:47,0 -DA:48,0 -DA:49,0 -DA:52,137 -DA:53,0 -DA:54,0 -DA:55,0 -DA:57,137 -DA:58,52 -DA:64,52 -DA:65,52 -DA:66,0 -DA:67,0 -DA:68,0 -DA:70,0 -DA:71,0 -DA:72,0 -DA:73,0 -DA:74,0 -DA:77,0 -DA:78,0 -DA:79,0 -DA:80,0 -DA:81,0 -DA:82,0 -DA:85,0 -DA:87,0 -DA:88,0 -DA:90,0 -DA:91,0 -DA:92,0 -DA:93,0 -DA:96,0 -DA:97,0 -DA:99,0 -DA:100,0 -DA:101,52 -DA:102,52 -DA:107,52 -DA:108,0 -DA:109,0 -DA:110,0 -DA:111,0 -DA:112,0 -DA:113,0 -DA:114,0 -DA:115,52 -DA:120,52 -DA:121,1 -DA:122,0 -DA:123,0 -DA:125,1 -DA:126,1 -DA:128,1 -DA:129,0 -DA:130,0 -DA:131,0 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,52 -DA:141,52 -DA:142,0 -DA:143,0 -DA:144,0 -DA:146,0 -DA:147,0 -DA:148,0 -DA:149,0 -DA:150,0 -DA:151,52 -DA:154,52 -DA:155,37 -DA:156,34 -DA:157,34 -DA:158,37 -DA:159,52 -DA:162,52 -DA:163,37 -DA:164,28 -DA:165,28 -DA:166,37 -DA:168,37 -DA:169,37 -DA:170,52 -DA:172,52 -DA:173,52 -DA:174,52 -DA:175,52 -DA:176,52 -DA:177,52 -DA:178,52 -DA:179,52 -DA:180,52 -DA:181,52 -LF:114 -LH:63 -BRDA:24,0,0,52 -BRDA:44,1,0,137 -BRDA:46,2,0,0 -BRDA:52,3,0,0 -BRDA:120,4,0,1 -BRDA:121,5,0,0 -BRDA:128,6,0,0 -BRDA:154,7,0,37 -BRDA:155,8,0,34 -BRDA:162,9,0,37 -BRDA:163,10,0,28 -BRDA:166,11,0,37 -BRF:12 -BRH:8 -end_of_record -TN: -SF:src/components/effects/__tests__/useClickOutside.test.tsx -FN:34,__vi_import_0__.renderHook.initialProps.cb -FN:53,__vi_import_0__.renderHook.initialProps.r -FNF:2 -FNH:2 -FNDA:2,__vi_import_0__.renderHook.initialProps.cb -FNDA:2,__vi_import_0__.renderHook.initialProps.r -DA:1,1 -DA:2,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:9,1 -DA:10,1 -DA:12,1 -DA:13,1 -DA:14,5 -DA:15,5 -DA:16,5 -DA:17,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:23,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:38,1 -DA:39,1 -DA:41,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:59,1 -DA:61,1 -DA:62,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:68,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:78,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -LF:60 -LH:60 -BRDA:12,0,0,1 -BRDA:13,1,0,5 -BRDA:15,2,0,7 -BRDA:16,3,0,7 -BRDA:19,4,0,1 -BRDA:23,5,0,1 -BRDA:29,6,0,1 -BRDA:34,7,0,2 -BRDA:47,8,0,1 -BRDA:53,9,0,2 -BRDA:64,10,0,1 -BRDA:68,11,0,1 -BRDA:74,12,0,1 -BRDA:78,13,0,1 -BRF:14 -BRH:14 -end_of_record -TN: -SF:src/components/effects/__tests__/useMatchMedia.test.tsx -FN:6,TestComponent -FNF:1 -FNH:1 -FNDA:19,TestComponent -DA:1,1 -DA:2,1 -DA:3,1 -DA:6,19 -DA:7,19 -DA:8,19 -DA:9,19 -DA:16,19 -DA:17,19 -DA:18,19 -DA:19,19 -DA:21,19 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:28,1 -DA:29,9 -DA:30,9 -DA:32,9 -DA:33,8 -DA:34,8 -DA:35,8 -DA:36,9 -DA:38,9 -DA:39,1 -DA:41,1 -DA:42,9 -DA:43,9 -DA:44,9 -DA:45,9 -DA:46,9 -DA:47,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:76,1 -DA:77,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:91,1 -DA:92,1 -DA:94,1 -DA:95,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:112,1 -DA:114,1 -DA:115,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:131,1 -DA:132,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:139,1 -DA:140,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:145,1 -DA:146,1 -DA:147,1 -DA:149,1 -DA:150,1 -DA:151,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:158,1 -DA:160,1 -DA:161,1 -DA:163,1 -DA:164,1 -DA:166,1 -DA:168,1 -DA:169,1 -DA:170,1 -LF:126 -LH:126 -BRDA:6,0,0,19 -BRDA:19,1,0,8 -BRDA:19,2,0,11 -BRDA:23,3,0,1 -BRDA:28,4,0,9 -BRDA:32,5,0,8 -BRDA:41,6,0,9 -BRDA:49,7,0,1 -BRDA:56,8,0,1 -BRDA:63,9,0,1 -BRDA:70,10,0,1 -BRDA:76,11,0,1 -BRDA:79,12,0,1 -BRDA:87,13,0,1 -BRDA:94,14,0,1 -BRDA:104,15,0,1 -BRDA:108,16,0,1 -BRDA:117,17,0,1 -BRDA:121,18,0,1 -BRDA:123,19,0,1 -BRDA:139,20,0,1 -BRDA:149,21,0,1 -BRDA:154,22,0,1 -BRDA:163,23,0,1 -BRF:24 -BRH:24 -end_of_record -TN: -SF:src/components/effects/__tests__/useNewScrollPosition.test.ts -FN:8,createMockElement -FN:339,initialProps.mode -FN:365,initialProps.mode -FNF:3 -FNH:3 -FNDA:13,createMockElement -FNDA:3,initialProps.mode -FNDA:2,initialProps.mode -DA:1,1 -DA:2,1 -DA:3,1 -DA:8,1 -DA:9,13 -DA:10,13 -DA:11,13 -DA:12,13 -DA:13,13 -DA:14,13 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:27,1 -DA:28,1 -DA:29,2 -DA:30,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:76,1 -DA:77,1 -DA:78,2 -DA:79,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:124,1 -DA:125,1 -DA:126,2 -DA:127,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:140,1 -DA:141,1 -DA:142,1 -DA:144,1 -DA:145,1 -DA:146,1 -DA:148,1 -DA:149,1 -DA:150,2 -DA:151,1 -DA:153,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:157,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:162,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:168,1 -DA:169,1 -DA:170,1 -DA:171,1 -DA:173,1 -DA:174,1 -DA:175,1 -DA:176,2 -DA:177,1 -DA:179,1 -DA:180,1 -DA:181,1 -DA:182,1 -DA:183,1 -DA:185,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:190,1 -DA:191,1 -DA:192,1 -DA:194,1 -DA:195,1 -DA:196,1 -DA:198,1 -DA:199,1 -DA:200,2 -DA:201,1 -DA:203,1 -DA:204,1 -DA:205,1 -DA:206,1 -DA:207,1 -DA:209,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:214,1 -DA:215,1 -DA:216,1 -DA:218,1 -DA:219,1 -DA:220,1 -DA:222,1 -DA:223,1 -DA:224,2 -DA:225,1 -DA:227,1 -DA:228,1 -DA:229,1 -DA:230,1 -DA:231,1 -DA:233,1 -DA:234,1 -DA:235,1 -DA:236,1 -DA:238,1 -DA:239,1 -DA:240,1 -DA:242,1 -DA:243,1 -DA:244,1 -DA:246,1 -DA:247,1 -DA:248,1 -DA:249,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:254,1 -DA:255,1 -DA:257,1 -DA:258,1 -DA:259,1 -DA:260,1 -DA:262,1 -DA:263,1 -DA:264,1 -DA:266,1 -DA:267,1 -DA:268,1 -DA:269,1 -DA:271,1 -DA:272,1 -DA:273,1 -DA:274,2 -DA:275,1 -DA:277,1 -DA:278,1 -DA:279,1 -DA:280,1 -DA:281,1 -DA:283,1 -DA:284,1 -DA:285,1 -DA:286,1 -DA:288,1 -DA:289,1 -DA:290,1 -DA:292,1 -DA:293,1 -DA:294,1 -DA:295,1 -DA:297,1 -DA:298,1 -DA:299,1 -DA:300,1 -DA:301,1 -DA:303,1 -DA:304,1 -DA:306,1 -DA:307,1 -DA:308,1 -DA:309,1 -DA:311,1 -DA:312,1 -DA:313,1 -DA:315,1 -DA:316,1 -DA:317,1 -DA:319,1 -DA:320,1 -DA:321,2 -DA:322,1 -DA:324,1 -DA:325,1 -DA:327,1 -DA:329,1 -DA:330,1 -DA:331,1 -DA:333,1 -DA:334,1 -DA:335,1 -DA:337,1 -DA:338,1 -DA:339,1 -DA:340,3 -DA:341,1 -DA:342,1 -DA:343,1 -DA:344,1 -DA:346,1 -DA:349,1 -DA:350,1 -DA:353,1 -DA:356,1 -DA:357,1 -DA:360,1 -DA:361,1 -DA:363,1 -DA:364,1 -DA:365,1 -DA:366,1 -DA:367,1 -DA:368,1 -DA:369,1 -DA:371,1 -DA:374,1 -DA:375,1 -DA:378,1 -DA:379,1 -DA:380,1 -DA:381,1 -LF:293 -LH:293 -BRDA:8,0,0,13 -BRDA:16,1,0,1 -BRDA:17,2,0,1 -BRDA:18,3,0,1 -BRDA:19,4,0,1 -BRDA:27,5,0,1 -BRDA:28,6,0,2 -BRDA:43,7,0,1 -BRDA:52,8,0,1 -BRDA:53,9,0,1 -BRDA:68,10,0,1 -BRDA:76,11,0,1 -BRDA:77,12,0,2 -BRDA:92,13,0,1 -BRDA:100,14,0,1 -BRDA:101,15,0,1 -BRDA:116,16,0,1 -BRDA:124,17,0,1 -BRDA:125,18,0,2 -BRDA:140,19,0,1 -BRDA:148,20,0,1 -BRDA:149,21,0,2 -BRDA:164,22,0,1 -BRDA:173,23,0,1 -BRDA:174,24,0,1 -BRDA:175,25,0,2 -BRDA:190,26,0,1 -BRDA:198,27,0,1 -BRDA:199,28,0,2 -BRDA:214,29,0,1 -BRDA:222,30,0,1 -BRDA:223,31,0,2 -BRDA:238,32,0,1 -BRDA:246,33,0,1 -BRDA:247,34,0,1 -BRDA:262,35,0,1 -BRDA:271,36,0,1 -BRDA:272,37,0,1 -BRDA:273,38,0,2 -BRDA:288,39,0,1 -BRDA:297,40,0,1 -BRDA:298,41,0,1 -BRDA:299,42,0,1 -BRDA:311,43,0,1 -BRDA:319,44,0,1 -BRDA:320,45,0,2 -BRDA:329,46,0,1 -BRDA:337,47,0,1 -BRDA:339,48,0,3 -BRDA:363,49,0,1 -BRDA:365,50,0,2 -BRF:51 -BRH:51 -end_of_record -TN: -SF:src/components/effects/__tests__/useSlideshow.test.ts -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:11,1 -DA:12,3 -DA:13,3 -DA:14,3 -DA:16,1 -DA:17,3 -DA:18,3 -DA:19,3 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:59,1 -DA:60,1 -DA:61,2 -DA:62,2 -DA:63,2 -DA:64,2 -DA:65,2 -DA:66,2 -DA:67,2 -DA:68,2 -DA:69,1 -DA:71,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:77,1 -DA:78,1 -DA:79,1 -LF:66 -LH:66 -BRDA:11,0,0,3 -BRDA:16,1,0,3 -BRDA:21,2,0,1 -BRDA:22,3,0,1 -BRDA:23,4,0,1 -BRDA:39,5,0,1 -BRDA:40,6,0,1 -BRDA:59,7,0,1 -BRDA:60,8,0,2 -BRDA:73,9,0,1 -BRF:10 -BRH:10 -end_of_record -TN: -SF:src/components/elements/list/list-item.tsx -FN:60,onClick -FN:64,onKeyUp -FNF:2 -FNH:1 -FNDA:3,onClick -FNDA:0,onKeyUp -DA:1,1 -DA:2,1 -DA:4,1 -DA:27,1 -DA:28,1 -DA:29,18 -DA:30,18 -DA:31,18 -DA:32,18 -DA:33,18 -DA:34,18 -DA:35,18 -DA:36,18 -DA:37,18 -DA:42,18 -DA:49,18 -DA:50,0 -DA:51,0 -DA:52,0 -DA:53,18 -DA:55,18 -DA:56,18 -DA:57,18 -DA:58,18 -DA:59,18 -DA:60,18 -DA:61,18 -DA:62,18 -DA:63,18 -DA:64,18 -DA:66,18 -DA:67,10 -DA:68,10 -DA:69,10 -DA:70,10 -DA:71,10 -DA:72,10 -DA:74,10 -DA:75,10 -DA:76,10 -DA:77,8 -DA:78,18 -DA:79,18 -DA:80,18 -DA:81,18 -DA:82,18 -DA:83,18 -DA:84,18 -DA:86,18 -DA:87,1 -DA:89,1 -LF:51 -LH:48 -BRDA:28,0,0,18 -BRDA:66,1,0,10 -BRDA:74,2,0,2 -BRDA:76,3,0,8 -BRDA:42,4,0,3 -BRDA:60,5,0,3 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/elements/list/list.model.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -LF:0 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/elements/list/list.styles.ts -FN:6,border -FNF:1 -FNH:1 -FNDA:18,border -DA:2,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:11,1 -DA:21,1 -DA:22,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:36,1 -DA:37,1 -DA:46,1 -DA:47,1 -DA:70,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:85,1 -DA:91,1 -DA:92,1 -DA:102,1 -DA:109,1 -DA:113,1 -DA:114,1 -DA:119,1 -DA:120,1 -DA:126,1 -DA:127,1 -DA:137,1 -DA:138,1 -DA:140,1 -LF:35 -LH:35 -BRDA:6,0,0,18 -BRDA:34,1,0,18 -BRDA:34,2,0,0 -BRDA:36,3,0,18 -BRDA:36,4,0,0 -BRDA:37,5,0,18 -BRDA:37,6,0,0 -BRDA:76,7,0,18 -BRDA:77,8,0,0 -BRDA:78,9,0,18 -BRDA:78,10,0,10 -BRDA:78,11,0,8 -BRDA:79,12,0,18 -BRDA:85,13,0,18 -BRDA:92,14,0,18 -BRDA:92,15,0,0 -BRDA:109,16,0,18 -BRDA:126,17,0,10 -BRDA:126,18,0,2 -BRDA:126,19,0,8 -BRDA:127,20,0,10 -BRDA:127,21,0,8 -BRDA:140,22,0,18 -BRDA:140,23,0,10 -BRDA:140,24,0,8 -BRF:25 -BRH:20 -end_of_record -TN: -SF:src/components/elements/list/list.tsx -FN:31,List -FNF:1 -FNH:1 -FNDA:5,List -DA:1,1 -DA:2,1 -DA:8,1 -DA:10,1 -DA:31,1 -DA:32,5 -DA:33,5 -DA:34,5 -DA:35,5 -DA:36,5 -DA:37,5 -DA:41,5 -DA:42,5 -DA:43,5 -DA:44,5 -DA:51,5 -DA:52,5 -DA:53,2 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,2 -DA:61,5 -DA:62,5 -DA:70,5 -DA:71,5 -DA:72,13 -DA:73,13 -DA:74,13 -DA:75,13 -DA:77,13 -DA:78,13 -DA:79,13 -DA:80,13 -DA:81,13 -DA:82,13 -DA:83,13 -DA:84,13 -DA:85,13 -DA:87,13 -DA:88,5 -DA:89,5 -DA:91,5 -DA:92,5 -LF:47 -LH:47 -BRDA:31,0,0,5 -BRDA:42,1,0,5 -BRDA:42,2,0,13 -BRDA:52,3,0,2 -BRDA:53,4,0,1 -BRDA:53,5,0,1 -BRDA:54,6,0,1 -BRDA:71,7,0,13 -BRDA:73,8,0,2 -BRF:9 -BRH:9 -end_of_record -TN: -SF:src/components/elements/list/__tests__/list-item.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:15,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -LF:77 -LH:77 -BRDA:8,0,0,1 -BRDA:17,1,0,1 -BRDA:30,2,0,1 -BRDA:49,3,0,1 -BRDA:61,4,0,1 -BRDA:73,5,0,1 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/elements/list/__tests__/list.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:14,1 -DA:15,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,3 -DA:49,3 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -LF:57 -LH:57 -BRDA:14,0,0,1 -BRDA:17,1,0,1 -BRDA:30,2,0,1 -BRDA:45,3,0,1 -BRDA:47,4,0,3 -BRDA:49,5,0,1 -BRDA:49,6,0,2 -BRF:7 -BRH:7 -end_of_record -TN: -SF:src/components/elements/popover/index.tsx -FN:35,popoverReducer -FN:53,PopOver -FNF:2 -FNH:2 -FNDA:22,popoverReducer -FNDA:35,PopOver -DA:1,1 -DA:9,1 -DA:10,1 -DA:12,1 -DA:24,1 -DA:25,5 -DA:26,1 -DA:35,1 -DA:36,22 -DA:37,22 -DA:38,5 -DA:39,22 -DA:40,3 -DA:41,22 -DA:42,14 -DA:43,22 -DA:44,0 -DA:45,22 -DA:46,22 -DA:53,1 -DA:54,35 -DA:55,35 -DA:56,35 -DA:57,35 -DA:58,35 -DA:59,35 -DA:60,35 -DA:61,35 -DA:62,35 -DA:63,35 -DA:64,35 -DA:65,35 -DA:66,35 -DA:67,35 -DA:69,35 -DA:70,5 -DA:71,35 -DA:73,35 -DA:74,3 -DA:75,35 -DA:77,35 -DA:78,1 -DA:79,0 -DA:80,0 -DA:81,35 -DA:83,35 -DA:86,35 -DA:87,19 -DA:88,5 -DA:89,2 -DA:90,5 -DA:91,17 -DA:92,14 -DA:93,14 -DA:94,35 -DA:96,35 -DA:97,35 -DA:98,35 -DA:99,35 -DA:100,35 -DA:101,35 -DA:102,35 -DA:103,35 -DA:104,35 -DA:105,35 -DA:106,35 -DA:107,35 -DA:108,35 -DA:110,35 -DA:111,35 -DA:112,35 -DA:113,35 -DA:114,35 -DA:115,0 -DA:116,35 -DA:117,35 -DA:118,35 -DA:119,5 -DA:120,5 -DA:121,5 -DA:122,5 -DA:123,5 -DA:124,5 -DA:126,5 -DA:127,5 -DA:128,5 -DA:129,5 -DA:130,5 -DA:131,5 -DA:132,5 -DA:133,30 -DA:134,35 -DA:136,35 -DA:138,1 -LF:94 -LH:90 -BRDA:24,0,0,5 -BRDA:35,1,0,22 -BRDA:37,2,0,5 -BRDA:39,3,0,3 -BRDA:41,4,0,14 -BRDA:43,5,0,0 -BRDA:53,6,0,35 -BRDA:111,7,0,15 -BRDA:114,8,0,0 -BRDA:118,9,0,5 -BRDA:132,10,0,30 -BRDA:69,11,0,5 -BRDA:73,12,0,3 -BRDA:77,13,0,1 -BRDA:78,14,0,0 -BRDA:86,15,0,19 -BRDA:87,16,0,17 -BRDA:87,17,0,5 -BRDA:91,18,0,14 -BRDA:88,19,0,2 -BRF:20 -BRH:17 -end_of_record -TN: -SF:src/components/elements/popover/popover.model.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -LF:0 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/elements/popover/popover.styles.ts -FN:13,getBorderStyle -FN:18,getElevatedShadow -FN:21,getInteractiveShadow -FN:41,__vite_ssr_import_0__.default.div.$theme.$theme -FN:43,__vite_ssr_import_0__.default.div.$theme.$theme -FN:44,__vite_ssr_import_0__.default.div.$isMobile.$isMobile -FN:49,__vite_ssr_import_0__.default.div.$isMobile.$isMobile -FN:50,__vite_ssr_import_0__.default.div.$isMobile.$isMobile -FN:51,__vite_ssr_import_0__.default.div.$visible.$visible -FN:53,__vite_ssr_import_0__.default.div.$theme.$theme -FN:69,__vite_ssr_import_0__.default.div.$theme.$theme -FN:70,__vite_ssr_import_0__.default.div.$theme.$theme -FN:72,__vite_ssr_import_0__.default.div.$open.$open -FN:73,__vite_ssr_import_0__.default.div.$theme.$theme -FN:76,__vite_ssr_import_0__.default.div.$theme.$theme -FN:85,__vite_ssr_import_0__.default.div.$theme.$theme -FNF:16 -FNH:16 -FNDA:40,getBorderStyle -FNDA:5,getElevatedShadow -FNDA:35,getInteractiveShadow -FNDA:5,__vite_ssr_import_0__.default.div.$theme.$theme -FNDA:5,__vite_ssr_import_0__.default.div.$theme.$theme -FNDA:5,__vite_ssr_import_0__.default.div.$isMobile.$isMobile -FNDA:5,__vite_ssr_import_0__.default.div.$isMobile.$isMobile -FNDA:5,__vite_ssr_import_0__.default.div.$isMobile.$isMobile -FNDA:5,__vite_ssr_import_0__.default.div.$visible.$visible -FNDA:5,__vite_ssr_import_0__.default.div.$theme.$theme -FNDA:35,__vite_ssr_import_0__.default.div.$theme.$theme -FNDA:35,__vite_ssr_import_0__.default.div.$theme.$theme -FNDA:35,__vite_ssr_import_0__.default.div.$open.$open -FNDA:35,__vite_ssr_import_0__.default.div.$theme.$theme -FNDA:35,__vite_ssr_import_0__.default.div.$theme.$theme -FNDA:35,__vite_ssr_import_0__.default.div.$theme.$theme -DA:2,1 -DA:3,1 -DA:6,1 -DA:13,1 -DA:14,40 -DA:15,26 -DA:16,14 -DA:18,1 -DA:19,5 -DA:21,1 -DA:22,35 -DA:23,30 -DA:24,5 -DA:26,1 -DA:29,1 -DA:32,1 -DA:39,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:57,1 -DA:58,1 -DA:62,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:76,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:108,1 -DA:116,1 -DA:122,1 -DA:129,1 -DA:130,1 -DA:133,1 -LF:49 -LH:49 -BRDA:13,0,0,40 -BRDA:14,1,0,26 -BRDA:15,2,0,14 -BRDA:18,3,0,5 -BRDA:19,4,0,0 -BRDA:21,5,0,35 -BRDA:22,6,0,30 -BRDA:23,7,0,14 -BRDA:23,8,0,5 -BRDA:24,9,0,0 -BRDA:41,10,0,5 -BRDA:43,11,0,5 -BRDA:44,12,0,5 -BRDA:49,13,0,5 -BRDA:49,14,0,0 -BRDA:50,15,0,5 -BRDA:50,16,0,0 -BRDA:51,17,0,5 -BRDA:52,18,0,0 -BRDA:53,19,0,5 -BRDA:53,20,0,0 -BRDA:57,21,0,5 -BRDA:57,22,0,0 -BRDA:69,23,0,35 -BRDA:70,24,0,35 -BRDA:72,25,0,35 -BRDA:73,26,0,35 -BRDA:76,27,0,35 -BRDA:76,28,0,0 -BRDA:85,29,0,35 -BRDA:86,30,0,14 -BRDA:87,31,0,35 -BRDA:88,32,0,14 -BRDA:95,33,0,35 -BRDA:95,34,0,14 -BRDA:133,35,0,5 -BRDA:133,36,0,0 -BRF:37 -BRH:28 -end_of_record -TN: -SF:src/components/elements/popover/__tests__/popover.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:13,1 -DA:15,1 -DA:16,4 -DA:17,4 -DA:18,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:50,1 -DA:51,1 -DA:53,1 -DA:55,1 -DA:56,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,1 -DA:74,1 -DA:76,1 -DA:78,1 -DA:79,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:95,1 -DA:96,1 -DA:98,1 -DA:100,1 -DA:102,1 -DA:104,1 -DA:105,1 -DA:106,1 -LF:85 -LH:85 -BRDA:9,0,0,1 -BRDA:15,1,0,4 -BRDA:20,2,0,1 -BRDA:37,3,0,1 -BRDA:58,4,0,1 -BRDA:81,5,0,1 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/timeline/TimelineView.tsx -FN:26,TimelineView -FNF:1 -FNH:1 -FNDA:7,TimelineView -DA:1,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:26,1 -DA:27,7 -DA:28,7 -DA:29,7 -DA:30,7 -DA:31,7 -DA:32,7 -DA:33,7 -DA:34,7 -DA:35,7 -DA:36,7 -DA:37,7 -DA:38,7 -DA:39,7 -DA:40,7 -DA:41,7 -DA:42,7 -DA:44,7 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:66,7 -DA:67,4 -DA:68,4 -DA:69,4 -DA:70,4 -DA:71,4 -DA:72,4 -DA:73,4 -DA:74,4 -DA:75,4 -DA:76,4 -DA:77,4 -DA:78,4 -DA:79,4 -DA:80,4 -DA:81,4 -DA:82,4 -DA:84,4 -DA:87,2 -DA:88,2 -DA:89,2 -DA:90,2 -DA:91,2 -DA:92,2 -DA:93,2 -DA:94,2 -DA:95,2 -DA:96,2 -DA:97,2 -DA:98,2 -DA:99,2 -DA:100,2 -DA:101,2 -DA:102,2 -DA:103,2 -DA:105,2 -DA:107,1 -LF:77 -LH:77 -BRDA:26,0,0,7 -BRDA:44,1,0,6 -BRDA:44,2,0,1 -BRDA:63,3,0,6 -BRDA:66,4,0,4 -BRDA:84,5,0,2 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/timeline/timeline-popover-elements.tsx -FN:12,LayoutSwitcher -FN:45,onSelect -FN:52,onSelect -FN:66,onSelect -FN:75,onSelect -FN:107,QuickJump -FN:146,ChangeDensity -FN:163,onSelect -FN:170,onSelect -FNF:9 -FNH:2 -FNDA:2,LayoutSwitcher -FNDA:0,onSelect -FNDA:0,onSelect -FNDA:0,onSelect -FNDA:0,onSelect -FNDA:0,QuickJump -FNDA:7,ChangeDensity -FNDA:0,onSelect -FNDA:0,onSelect -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:12,1 -DA:13,2 -DA:14,2 -DA:15,2 -DA:16,2 -DA:17,2 -DA:18,2 -DA:19,2 -DA:20,2 -DA:21,2 -DA:23,2 -DA:25,2 -DA:26,2 -DA:27,2 -DA:28,2 -DA:30,2 -DA:31,2 -DA:32,2 -DA:33,2 -DA:34,2 -DA:35,2 -DA:36,2 -DA:37,2 -DA:38,2 -DA:40,2 -DA:41,2 -DA:42,2 -DA:43,2 -DA:44,2 -DA:45,2 -DA:46,2 -DA:47,2 -DA:48,2 -DA:49,2 -DA:50,2 -DA:51,2 -DA:52,2 -DA:53,2 -DA:54,2 -DA:55,2 -DA:56,2 -DA:57,2 -DA:58,2 -DA:61,2 -DA:62,2 -DA:63,2 -DA:64,2 -DA:65,2 -DA:66,2 -DA:67,0 -DA:68,0 -DA:69,2 -DA:70,2 -DA:71,2 -DA:72,2 -DA:73,2 -DA:74,2 -DA:75,2 -DA:76,0 -DA:77,0 -DA:78,2 -DA:79,2 -DA:80,2 -DA:81,2 -DA:82,2 -DA:83,2 -DA:85,2 -DA:86,2 -DA:87,2 -DA:88,2 -DA:89,2 -DA:90,2 -DA:91,2 -DA:92,2 -DA:94,2 -DA:95,2 -DA:96,2 -DA:97,1 -DA:98,1 -DA:100,2 -DA:101,2 -DA:102,2 -DA:103,2 -DA:105,2 -DA:107,1 -DA:108,0 -DA:109,0 -DA:110,0 -DA:111,0 -DA:112,0 -DA:113,0 -DA:114,0 -DA:115,0 -DA:116,0 -DA:118,0 -DA:120,0 -DA:121,0 -DA:122,0 -DA:123,0 -DA:124,0 -DA:125,0 -DA:126,0 -DA:127,0 -DA:128,0 -DA:130,0 -DA:131,0 -DA:132,0 -DA:133,0 -DA:134,0 -DA:135,0 -DA:136,0 -DA:137,0 -DA:138,0 -DA:139,0 -DA:140,0 -DA:141,0 -DA:142,0 -DA:144,0 -DA:146,1 -DA:147,7 -DA:148,7 -DA:149,7 -DA:150,7 -DA:151,7 -DA:152,7 -DA:153,7 -DA:154,7 -DA:156,7 -DA:158,7 -DA:159,7 -DA:160,6 -DA:161,6 -DA:162,6 -DA:163,6 -DA:164,6 -DA:165,6 -DA:166,6 -DA:167,6 -DA:168,6 -DA:169,6 -DA:170,6 -DA:171,6 -DA:172,6 -DA:173,6 -DA:174,6 -DA:175,7 -DA:176,7 -DA:178,7 -DA:179,7 -DA:180,7 -DA:181,7 -DA:182,7 -DA:183,7 -DA:184,7 -DA:185,7 -DA:186,7 -DA:188,7 -DA:189,7 -DA:191,7 -LF:164 -LH:127 -BRDA:12,0,0,2 -BRDA:96,1,0,1 -BRDA:96,2,0,1 -BRDA:97,3,0,1 -BRDA:23,4,0,2 -BRDA:26,5,0,2 -BRDA:31,6,0,2 -BRDA:41,7,0,2 -BRDA:62,8,0,2 -BRDA:146,9,0,7 -BRDA:156,10,0,6 -BRDA:159,11,0,6 -BRF:12 -BRH:12 -end_of_record -TN: -SF:src/components/timeline/timeline-popover.model.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -LF:0 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline/timeline-toolbar.model.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -LF:0 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline/timeline-toolbar.tsx -FN:22,getTextFromNode -FN:39,TimelineToolbar -FN:101,onSelect -FN:107,onSelect -FN:113,onSelect -FN:119,onSelect -FN:148,handleInputChange -FN:153,handleClearSearch -FN:162,handleSearchKeyDown -FNF:9 -FNH:2 -FNDA:48,getTextFromNode -FNDA:7,TimelineToolbar -FNDA:0,onSelect -FNDA:0,onSelect -FNDA:0,onSelect -FNDA:0,onSelect -FNDA:0,handleInputChange -FNDA:0,handleClearSearch -FNDA:0,handleSearchKeyDown -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:14,1 -DA:22,1 -DA:23,48 -DA:24,48 -DA:25,48 -DA:26,0 -DA:27,0 -DA:28,48 -DA:29,48 -DA:30,48 -DA:31,48 -DA:32,0 -DA:33,0 -DA:35,0 -DA:36,0 -DA:39,1 -DA:40,7 -DA:41,7 -DA:42,7 -DA:43,7 -DA:44,7 -DA:45,7 -DA:46,7 -DA:47,7 -DA:48,7 -DA:49,7 -DA:50,7 -DA:51,7 -DA:52,7 -DA:53,7 -DA:54,7 -DA:55,7 -DA:56,7 -DA:57,7 -DA:58,7 -DA:59,7 -DA:60,7 -DA:61,7 -DA:62,7 -DA:63,7 -DA:64,7 -DA:65,7 -DA:66,7 -DA:67,7 -DA:69,7 -DA:70,7 -DA:71,7 -DA:72,7 -DA:73,7 -DA:74,7 -DA:75,7 -DA:77,7 -DA:78,7 -DA:79,7 -DA:80,7 -DA:81,7 -DA:82,7 -DA:85,7 -DA:86,6 -DA:87,24 -DA:88,24 -DA:89,24 -DA:90,24 -DA:91,6 -DA:92,7 -DA:95,7 -DA:96,6 -DA:97,6 -DA:98,6 -DA:99,6 -DA:100,6 -DA:101,6 -DA:102,6 -DA:103,6 -DA:104,6 -DA:105,6 -DA:106,6 -DA:107,6 -DA:108,6 -DA:109,6 -DA:110,6 -DA:111,6 -DA:112,6 -DA:113,6 -DA:114,6 -DA:115,6 -DA:116,6 -DA:117,6 -DA:118,6 -DA:119,6 -DA:120,6 -DA:121,6 -DA:122,7 -DA:125,7 -DA:126,6 -DA:127,0 -DA:128,0 -DA:129,6 -DA:130,7 -DA:133,7 -DA:134,6 -DA:135,0 -DA:136,0 -DA:137,6 -DA:138,7 -DA:140,7 -DA:141,6 -DA:142,7 -DA:144,7 -DA:145,6 -DA:146,7 -DA:148,7 -DA:149,0 -DA:150,0 -DA:153,7 -DA:154,0 -DA:156,0 -DA:157,0 -DA:158,0 -DA:159,0 -DA:162,7 -DA:163,0 -DA:164,0 -DA:165,0 -DA:166,0 -DA:169,0 -DA:172,0 -DA:174,0 -DA:175,0 -DA:176,0 -DA:177,0 -DA:181,0 -DA:182,0 -DA:183,0 -DA:186,0 -DA:189,0 -DA:190,0 -DA:193,0 -DA:194,0 -DA:195,0 -DA:196,0 -DA:197,0 -DA:198,0 -DA:201,7 -DA:202,7 -DA:203,7 -DA:204,7 -DA:207,7 -DA:208,7 -DA:209,7 -DA:210,7 -DA:211,7 -DA:212,7 -DA:213,7 -DA:214,7 -DA:215,7 -DA:216,7 -DA:217,7 -DA:218,7 -DA:219,7 -DA:220,7 -DA:221,7 -DA:222,7 -DA:223,7 -DA:224,7 -DA:225,7 -DA:226,7 -DA:227,7 -DA:228,7 -DA:229,7 -DA:230,7 -DA:231,7 -DA:232,7 -DA:233,7 -DA:234,7 -DA:235,7 -DA:236,7 -DA:237,7 -DA:238,0 -DA:239,0 -DA:240,0 -DA:241,0 -DA:242,0 -DA:243,0 -DA:244,0 -DA:245,0 -DA:246,0 -DA:247,0 -DA:249,0 -DA:250,0 -DA:252,7 -DA:253,0 -DA:254,0 -DA:255,0 -DA:257,7 -DA:258,0 -DA:259,0 -DA:260,0 -DA:261,0 -DA:262,0 -DA:263,0 -DA:264,0 -DA:265,0 -DA:266,0 -DA:268,0 -DA:269,0 -DA:270,0 -DA:271,0 -DA:272,0 -DA:273,0 -DA:274,0 -DA:275,0 -DA:276,0 -DA:277,0 -DA:278,0 -DA:280,0 -DA:281,0 -DA:282,0 -DA:283,0 -DA:285,7 -DA:286,7 -DA:287,7 -DA:288,7 -DA:289,7 -DA:291,7 -DA:292,7 -DA:293,0 -DA:294,0 -DA:295,0 -DA:296,0 -DA:297,0 -DA:298,0 -DA:299,0 -DA:300,0 -DA:301,0 -DA:302,7 -DA:303,7 -DA:304,7 -DA:305,7 -DA:306,0 -DA:307,0 -DA:308,0 -DA:309,0 -DA:310,0 -DA:311,0 -DA:312,0 -DA:313,0 -DA:314,7 -DA:315,7 -DA:316,7 -DA:317,7 -DA:318,7 -DA:319,7 -DA:320,7 -DA:321,7 -DA:322,7 -DA:323,7 -DA:324,7 -DA:325,7 -DA:326,7 -DA:327,7 -DA:328,7 -DA:329,7 -DA:331,7 -LF:271 -LH:176 -BRDA:22,0,0,48 -BRDA:25,1,0,0 -BRDA:30,2,0,0 -BRDA:31,3,0,0 -BRDA:39,4,0,7 -BRDA:230,5,0,0 -BRDA:234,6,0,0 -BRDA:237,7,0,0 -BRDA:252,8,0,0 -BRDA:257,9,0,0 -BRDA:292,10,0,0 -BRDA:305,11,0,0 -BRDA:326,12,0,0 -BRDA:85,13,0,6 -BRDA:86,14,0,24 -BRDA:87,15,0,0 -BRDA:95,16,0,6 -BRDA:125,17,0,6 -BRDA:126,18,0,0 -BRDA:133,19,0,6 -BRDA:134,20,0,0 -BRDA:140,21,0,6 -BRDA:144,22,0,6 -BRDA:145,23,0,24 -BRDA:202,24,0,6 -BRDA:202,25,0,0 -BRF:26 -BRH:11 -end_of_record -TN: -SF:src/components/timeline/timeline.style.ts -FN:8,getTransform -FN:68,__vite_ssr_import_0__.default.div.$scrollable.$scrollable -FN:71,__vite_ssr_import_0__.default.div.$scrollable.$scrollable -FN:72,__vite_ssr_import_0__.default.div.$scrollable.$scrollable -FNF:4 -FNH:4 -FNDA:28,getTransform -FNDA:7,__vite_ssr_import_0__.default.div.$scrollable.$scrollable -FNDA:7,__vite_ssr_import_0__.default.div.$scrollable.$scrollable -FNDA:7,__vite_ssr_import_0__.default.div.$scrollable.$scrollable -DA:3,1 -DA:4,1 -DA:5,1 -DA:8,1 -DA:10,1 -DA:19,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:33,1 -DA:56,1 -DA:68,1 -DA:71,1 -DA:72,1 -DA:74,1 -DA:78,1 -DA:81,1 -DA:98,1 -DA:103,1 -DA:106,1 -DA:109,1 -DA:118,1 -DA:119,0 -DA:120,0 -DA:121,0 -DA:122,0 -DA:123,0 -DA:124,0 -DA:135,1 -DA:138,1 -DA:145,1 -DA:153,1 -DA:154,1 -DA:155,1 -DA:161,1 -DA:170,1 -DA:174,1 -DA:180,1 -DA:183,1 -DA:186,1 -DA:195,1 -DA:196,1 -DA:200,1 -DA:205,1 -DA:210,1 -DA:219,1 -DA:220,7 -DA:222,7 -DA:223,7 -DA:224,1 -DA:225,1 -DA:234,1 -DA:236,1 -LF:55 -LH:49 -BRDA:8,0,0,28 -BRDA:24,1,0,7 -BRDA:25,2,0,7 -BRDA:26,3,0,7 -BRDA:27,4,0,7 -BRDA:68,5,0,7 -BRDA:68,6,0,1 -BRDA:68,7,0,6 -BRDA:71,8,0,7 -BRDA:71,9,0,0 -BRDA:72,10,0,7 -BRDA:72,11,0,0 -BRDA:78,12,0,7 -BRDA:78,13,0,0 -BRDA:103,14,0,1 -BRDA:106,15,0,1 -BRDA:138,16,0,7 -BRDA:138,17,0,0 -BRDA:153,18,0,7 -BRDA:153,19,0,0 -BRDA:154,20,0,7 -BRDA:154,21,0,0 -BRDA:170,22,0,7 -BRDA:170,23,0,0 -BRDA:183,24,0,7 -BRDA:186,25,0,7 -BRDA:195,26,0,7 -BRDA:196,27,0,7 -BRDA:205,28,0,7 -BRDA:210,29,0,7 -BRDA:219,30,0,7 -BRDA:222,31,0,0 -BRDA:224,32,0,7 -BRDA:225,33,0,0 -BRF:34 -BRH:25 -end_of_record -TN: -SF:src/components/timeline/timeline.style.tsx -FN:1,(empty-report) -FNF:1 -FNH:0 -FNDA:0,(empty-report) -DA:1,0 -DA:5,0 -DA:18,0 -DA:25,0 -DA:36,0 -DA:48,0 -DA:51,0 -DA:52,0 -DA:55,0 -DA:58,0 -DA:65,0 -DA:73,0 -DA:74,0 -DA:81,0 -DA:90,0 -DA:94,0 -DA:97,0 -DA:100,0 -DA:109,0 -DA:110,0 -DA:114,0 -DA:119,0 -DA:124,0 -DA:129,0 -DA:131,0 -DA:137,0 -DA:142,0 -DA:145,0 -DA:150,0 -LF:29 -LH:0 -BRDA:1,0,0,0 -BRF:1 -BRH:0 -end_of_record -TN: -SF:src/components/timeline/timeline.tsx -FN:24,Timeline -FN:260,onMouseDown -FN:261,onKeyUp -FNF:3 -FNH:2 -FNDA:8,Timeline -FNDA:1,onMouseDown -FNDA:0,onKeyUp -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:24,1 -DA:25,8 -DA:26,8 -DA:28,8 -DA:29,8 -DA:30,8 -DA:31,8 -DA:32,8 -DA:33,8 -DA:34,8 -DA:35,8 -DA:36,8 -DA:37,8 -DA:38,8 -DA:39,8 -DA:40,8 -DA:41,8 -DA:42,8 -DA:43,8 -DA:44,8 -DA:45,8 -DA:46,8 -DA:47,8 -DA:48,8 -DA:49,8 -DA:51,8 -DA:52,8 -DA:53,8 -DA:54,8 -DA:55,8 -DA:56,8 -DA:57,8 -DA:58,8 -DA:59,8 -DA:60,8 -DA:61,8 -DA:62,8 -DA:64,8 -DA:65,8 -DA:66,8 -DA:67,8 -DA:68,8 -DA:69,8 -DA:70,8 -DA:71,8 -DA:73,8 -DA:74,8 -DA:77,8 -DA:78,8 -DA:79,8 -DA:80,8 -DA:83,8 -DA:84,8 -DA:85,8 -DA:86,8 -DA:87,8 -DA:89,8 -DA:90,8 -DA:91,8 -DA:92,8 -DA:93,8 -DA:94,8 -DA:95,8 -DA:96,8 -DA:97,8 -DA:98,8 -DA:100,8 -DA:101,8 -DA:102,8 -DA:103,8 -DA:104,8 -DA:105,8 -DA:106,8 -DA:107,8 -DA:108,8 -DA:109,8 -DA:110,8 -DA:111,8 -DA:112,8 -DA:113,8 -DA:114,8 -DA:115,8 -DA:116,8 -DA:117,8 -DA:118,8 -DA:119,8 -DA:120,8 -DA:121,8 -DA:123,8 -DA:124,8 -DA:125,8 -DA:126,8 -DA:127,8 -DA:128,8 -DA:129,8 -DA:130,8 -DA:131,8 -DA:132,8 -DA:133,8 -DA:134,8 -DA:135,8 -DA:136,8 -DA:137,8 -DA:140,8 -DA:141,8 -DA:142,8 -DA:143,8 -DA:144,8 -DA:145,8 -DA:147,8 -DA:148,8 -DA:149,8 -DA:150,8 -DA:153,8 -DA:154,8 -DA:155,6 -DA:156,6 -DA:157,6 -DA:158,6 -DA:159,8 -DA:160,8 -DA:162,8 -DA:163,8 -DA:164,8 -DA:165,8 -DA:168,8 -DA:169,6 -DA:171,6 -DA:172,0 -DA:173,0 -DA:175,6 -DA:176,8 -DA:179,8 -DA:180,8 -DA:181,0 -DA:182,0 -DA:183,0 -DA:184,0 -DA:185,0 -DA:186,8 -DA:187,8 -DA:190,8 -DA:191,6 -DA:193,6 -DA:194,0 -DA:195,0 -DA:197,6 -DA:199,6 -DA:200,6 -DA:201,6 -DA:202,6 -DA:203,6 -DA:204,6 -DA:205,6 -DA:206,6 -DA:208,6 -DA:209,1 -DA:210,1 -DA:211,1 -DA:213,1 -DA:214,1 -DA:216,1 -DA:217,0 -DA:218,0 -DA:221,0 -DA:222,0 -DA:223,0 -DA:225,0 -DA:226,0 -DA:227,0 -DA:228,0 -DA:229,0 -DA:230,1 -DA:231,8 -DA:232,8 -DA:233,8 -DA:234,8 -DA:235,8 -DA:236,8 -DA:237,8 -DA:238,8 -DA:239,8 -DA:242,8 -DA:243,6 -DA:244,6 -DA:246,6 -DA:247,1 -DA:248,6 -DA:249,5 -DA:250,5 -DA:251,8 -DA:254,8 -DA:255,8 -DA:256,8 -DA:257,8 -DA:258,8 -DA:259,8 -DA:260,8 -DA:261,8 -DA:262,0 -DA:263,0 -DA:264,0 -DA:265,0 -DA:267,8 -DA:268,8 -DA:269,8 -DA:270,8 -DA:271,8 -DA:272,8 -DA:273,8 -DA:274,8 -DA:275,8 -DA:276,8 -DA:277,8 -DA:278,8 -DA:279,8 -DA:280,8 -DA:281,8 -DA:282,8 -DA:283,8 -DA:284,8 -DA:285,8 -DA:286,8 -DA:287,8 -DA:288,8 -DA:289,8 -DA:290,8 -DA:291,8 -DA:292,8 -DA:293,8 -DA:294,8 -DA:295,8 -DA:296,8 -DA:297,8 -DA:298,8 -DA:299,8 -DA:313,8 -DA:314,8 -DA:315,8 -DA:316,8 -DA:317,8 -DA:318,8 -DA:319,8 -DA:320,8 -DA:321,8 -DA:322,8 -DA:324,8 -DA:325,8 -DA:326,8 -DA:327,8 -DA:328,8 -DA:329,8 -DA:330,8 -DA:331,8 -DA:332,8 -DA:333,8 -DA:334,8 -DA:335,8 -DA:336,8 -DA:337,8 -DA:338,8 -DA:339,8 -DA:340,8 -DA:341,8 -DA:343,8 -DA:344,8 -DA:345,8 -DA:346,8 -DA:347,8 -DA:348,8 -DA:350,8 -DA:352,1 -DA:354,1 -LF:287 -LH:264 -BRDA:24,0,0,8 -BRDA:141,1,0,0 -BRDA:142,2,0,0 -BRDA:78,3,0,6 -BRDA:78,4,0,0 -BRDA:134,5,0,32 -BRDA:154,6,0,6 -BRDA:163,7,0,6 -BRDA:168,8,0,6 -BRDA:169,9,0,0 -BRDA:171,10,0,0 -BRDA:190,11,0,6 -BRDA:191,12,0,0 -BRDA:193,13,0,0 -BRDA:197,14,0,0 -BRDA:208,15,0,1 -BRDA:213,16,0,0 -BRDA:216,17,0,0 -BRDA:216,18,0,0 -BRDA:242,19,0,6 -BRDA:244,20,0,0 -BRDA:246,21,0,1 -BRDA:248,22,0,5 -BRDA:260,23,0,1 -BRF:24 -BRH:12 -end_of_record -TN: -SF:src/components/timeline-elements/memoized/details-text-memo.tsx -FN:7,arePropsEqual -FNF:1 -FNH:0 -FNDA:0,arePropsEqual -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:7,1 -DA:8,0 -DA:9,0 -DA:10,0 -DA:11,0 -DA:12,0 -DA:13,0 -DA:14,0 -DA:15,0 -DA:17,0 -DA:19,1 -DA:20,1 -DA:21,11 -DA:22,11 -DA:24,11 -DA:26,3 -DA:27,3 -DA:28,3 -DA:29,3 -DA:30,3 -DA:31,3 -DA:32,3 -DA:34,3 -DA:35,3 -DA:37,11 -DA:38,1 -DA:39,1 -DA:41,1 -LF:32 -LH:23 -BRDA:20,0,0,11 -BRDA:21,1,0,8 -BRDA:24,2,0,8 -BRDA:24,3,0,3 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/components/timeline-elements/memoized/expand-button-memo.tsx -FN:20,onKeyDown -FNF:1 -FNH:0 -FNDA:0,onKeyDown -DA:1,1 -DA:2,1 -DA:3,1 -DA:11,1 -DA:12,1 -DA:13,2 -DA:14,2 -DA:15,2 -DA:17,2 -DA:18,2 -DA:19,2 -DA:20,2 -DA:21,2 -DA:22,2 -DA:23,2 -DA:24,2 -DA:25,2 -DA:27,2 -DA:28,2 -DA:29,0 -DA:30,2 -DA:31,1 -DA:32,1 -DA:34,1 -LF:24 -LH:23 -BRDA:12,0,0,2 -BRDA:27,1,0,0 -BRDA:28,2,0,0 -BRDA:13,3,0,2 -BRDA:14,4,0,0 -BRF:5 -BRH:2 -end_of_record -TN: -SF:src/components/timeline-elements/memoized/memoized-model.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -LF:0 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/memoized/show-hide-button.tsx -FN:22,onKeyDown -FNF:1 -FNH:0 -FNDA:0,onKeyDown -DA:1,1 -DA:2,1 -DA:3,1 -DA:11,1 -DA:12,1 -DA:13,2 -DA:14,2 -DA:15,2 -DA:17,2 -DA:18,2 -DA:19,2 -DA:20,2 -DA:21,2 -DA:22,2 -DA:23,2 -DA:24,2 -DA:26,2 -DA:27,2 -DA:28,0 -DA:29,2 -DA:30,1 -DA:32,1 -LF:22 -LH:21 -BRDA:12,0,0,2 -BRDA:26,1,0,0 -BRDA:27,2,0,0 -BRDA:13,3,0,2 -BRDA:14,4,0,0 -BRF:5 -BRH:2 -end_of_record -TN: -SF:src/components/timeline-elements/memoized/subtitle-memo.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:12,1 -DA:13,1 -DA:14,43 -DA:16,43 -DA:17,37 -DA:18,37 -DA:19,37 -DA:20,37 -DA:21,37 -DA:22,37 -DA:23,37 -DA:24,37 -DA:26,37 -DA:27,37 -DA:28,6 -DA:29,43 -DA:30,1 -DA:31,0 -DA:32,1 -DA:34,1 -LF:24 -LH:23 -BRDA:13,0,0,43 -BRDA:16,1,0,37 -BRDA:18,2,0,3 -BRDA:27,3,0,6 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/components/timeline-elements/memoized/title-memo.tsx -FN:15,TitleMemoComponent -FNF:1 -FNH:1 -FNDA:45,TitleMemoComponent -DA:1,1 -DA:2,1 -DA:7,1 -DA:8,1 -DA:15,1 -DA:16,45 -DA:17,45 -DA:18,45 -DA:19,45 -DA:20,45 -DA:21,45 -DA:22,45 -DA:23,45 -DA:24,45 -DA:25,45 -DA:27,45 -DA:28,37 -DA:29,37 -DA:30,37 -DA:31,37 -DA:32,37 -DA:33,37 -DA:34,37 -DA:35,37 -DA:37,37 -DA:38,3 -DA:39,3 -DA:40,3 -DA:42,34 -DA:44,37 -DA:45,8 -DA:46,45 -DA:48,1 -DA:50,1 -LF:34 -LH:34 -BRDA:15,0,0,45 -BRDA:27,1,0,37 -BRDA:29,2,0,3 -BRDA:29,3,0,34 -BRDA:30,4,0,7 -BRDA:30,5,0,30 -BRDA:37,6,0,3 -BRDA:40,7,0,34 -BRDA:44,8,0,8 -BRF:9 -BRH:9 -end_of_record -TN: -SF:src/components/timeline-elements/memoized/__tests__/index.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:43,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:92,1 -DA:93,1 -DA:95,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:118,1 -DA:119,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:141,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:145,1 -DA:146,1 -DA:147,1 -DA:148,0 -DA:149,1 -DA:150,1 -DA:151,1 -DA:152,1 -DA:153,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:157,1 -DA:158,1 -LF:137 -LH:136 -BRDA:10,0,0,1 -BRDA:11,1,0,1 -BRDA:20,2,0,1 -BRDA:36,3,0,1 -BRDA:46,4,0,1 -BRDA:62,5,0,1 -BRDA:63,6,0,1 -BRDA:77,7,0,1 -BRDA:95,8,0,1 -BRDA:97,9,0,1 -BRDA:99,10,0,1 -BRDA:121,11,0,1 -BRDA:122,12,0,1 -BRDA:141,13,0,1 -BRDA:142,14,0,1 -BRF:15 -BRH:15 -end_of_record -TN: -SF:src/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx -FN:13,NestedTimelineRenderer -FNF:1 -FNH:0 -FNDA:0,NestedTimelineRenderer -DA:1,1 -DA:13,1 -DA:14,0 -DA:15,0 -DA:16,0 -DA:17,0 -DA:18,0 -DA:19,0 -DA:20,0 -DA:23,0 -DA:24,0 -DA:25,0 -DA:26,0 -DA:27,0 -DA:29,0 -DA:30,0 -DA:31,0 -DA:33,0 -DA:34,0 -DA:35,0 -DA:36,0 -DA:37,0 -DA:38,0 -DA:39,0 -DA:41,0 -DA:43,1 -LF:26 -LH:3 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card/timeline-horizontal-card.styles.ts -FN:68,ShapeBorderStyle -FNF:1 -FNH:1 -FNDA:180,ShapeBorderStyle -DA:2,1 -DA:3,1 -DA:5,1 -DA:19,1 -DA:21,1 -DA:30,1 -DA:41,1 -DA:53,1 -DA:68,1 -DA:69,180 -DA:70,66 -DA:71,180 -DA:72,0 -DA:73,114 -DA:74,0 -DA:75,0 -DA:76,180 -DA:78,1 -DA:79,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:100,1 -DA:101,1 -DA:107,1 -DA:112,1 -DA:117,1 -DA:123,1 -DA:124,90 -DA:125,0 -DA:126,1 -DA:131,1 -DA:132,90 -DA:133,0 -DA:134,1 -DA:139,1 -DA:140,90 -DA:141,0 -DA:142,1 -DA:143,1 -DA:146,1 -DA:147,1 -DA:151,1 -DA:154,1 -DA:155,1 -DA:160,1 -DA:166,1 -DA:169,1 -DA:170,1 -DA:171,1 -DA:173,1 -DA:183,1 -DA:200,1 -DA:215,1 -DA:223,1 -DA:226,1 -DA:231,1 -DA:242,1 -DA:255,1 -LF:60 -LH:54 -BRDA:68,0,0,180 -BRDA:69,1,0,66 -BRDA:71,2,0,114 -BRDA:71,3,0,0 -BRDA:73,4,0,0 -BRDA:81,5,0,90 -BRDA:82,6,0,90 -BRDA:83,7,0,90 -BRDA:84,8,0,0 -BRDA:100,9,0,90 -BRDA:100,10,0,33 -BRDA:100,11,0,57 -BRDA:101,12,0,90 -BRDA:101,13,0,33 -BRDA:101,14,0,57 -BRDA:117,15,0,90 -BRDA:117,16,0,0 -BRDA:123,17,0,90 -BRDA:124,18,0,0 -BRDA:131,19,0,90 -BRDA:132,20,0,0 -BRDA:139,21,0,90 -BRDA:140,22,0,0 -BRDA:146,23,0,90 -BRDA:147,24,0,0 -BRDA:154,25,0,90 -BRDA:154,26,0,33 -BRDA:154,27,0,57 -BRDA:155,28,0,90 -BRDA:155,29,0,33 -BRDA:155,30,0,57 -BRDA:166,31,0,90 -BRDA:169,32,0,90 -BRDA:170,33,0,90 -BRDA:170,34,0,33 -BRDA:170,35,0,57 -BRDA:171,36,0,90 -BRDA:183,37,0,90 -BRDA:226,38,0,6 -BRDA:226,39,0,0 -BRDA:226,40,0,0 -BRDA:231,41,0,6 -BRF:42 -BRH:32 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card/timeline-horizontal-card.tsx -FN:13,TimelineCard -FN:72,formatDetailedText -FNF:2 -FNH:2 -FNDA:67,TimelineCard -FNDA:27,formatDetailedText -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:13,1 -DA:14,67 -DA:15,67 -DA:16,67 -DA:17,67 -DA:18,67 -DA:19,67 -DA:20,67 -DA:21,67 -DA:22,67 -DA:23,67 -DA:24,67 -DA:25,67 -DA:26,67 -DA:27,67 -DA:28,67 -DA:29,67 -DA:30,67 -DA:31,67 -DA:32,67 -DA:33,67 -DA:34,67 -DA:35,67 -DA:36,67 -DA:37,67 -DA:38,67 -DA:39,67 -DA:40,67 -DA:41,67 -DA:42,67 -DA:43,67 -DA:44,67 -DA:45,67 -DA:46,67 -DA:48,67 -DA:49,67 -DA:50,67 -DA:51,67 -DA:52,67 -DA:53,67 -DA:54,67 -DA:55,67 -DA:56,67 -DA:57,67 -DA:58,67 -DA:59,67 -DA:60,67 -DA:61,67 -DA:62,67 -DA:63,67 -DA:64,67 -DA:65,67 -DA:66,67 -DA:67,67 -DA:68,67 -DA:69,67 -DA:72,67 -DA:73,27 -DA:74,0 -DA:75,0 -DA:76,0 -DA:77,0 -DA:79,27 -DA:80,27 -DA:81,27 -DA:83,27 -DA:84,27 -DA:86,67 -DA:87,67 -DA:88,67 -DA:89,27 -DA:90,27 -DA:91,27 -DA:92,27 -DA:93,27 -DA:94,27 -DA:95,27 -DA:96,27 -DA:97,27 -DA:98,27 -DA:99,27 -DA:100,27 -DA:101,0 -DA:103,27 -DA:104,27 -DA:106,27 -DA:107,27 -DA:108,27 -DA:109,27 -DA:110,27 -DA:111,27 -DA:112,27 -DA:113,27 -DA:114,27 -DA:115,27 -DA:116,27 -DA:117,27 -DA:118,27 -DA:119,27 -DA:122,67 -DA:123,67 -DA:124,67 -DA:125,67 -DA:126,67 -DA:127,67 -DA:128,67 -DA:129,67 -DA:130,67 -DA:131,67 -DA:133,67 -DA:134,67 -DA:135,67 -DA:137,67 -DA:138,67 -DA:139,67 -DA:140,67 -DA:141,67 -DA:142,67 -DA:143,67 -DA:144,67 -DA:146,67 -DA:148,1 -LF:129 -LH:124 -BRDA:13,0,0,67 -BRDA:88,1,0,27 -BRDA:100,2,0,0 -BRDA:104,3,0,0 -BRDA:126,4,0,61 -BRDA:126,5,0,6 -BRDA:139,6,0,25 -BRDA:141,7,0,10 -BRDA:72,8,0,27 -BRDA:73,9,0,0 -BRDA:81,10,0,0 -BRDA:83,11,0,0 -BRF:12 -BRH:7 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/card-animations.styles.ts -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -DA:14,1 -DA:25,1 -DA:36,1 -LF:5 -LH:5 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/content-footer.tsx -FN:37,ContentFooter -FN:69,onKeyUp -FNF:2 -FNH:1 -FNDA:36,ContentFooter -FNDA:0,onKeyUp -DA:1,1 -DA:8,1 -DA:9,1 -DA:11,1 -DA:37,1 -DA:38,36 -DA:39,36 -DA:40,36 -DA:41,36 -DA:42,36 -DA:43,36 -DA:44,36 -DA:46,36 -DA:47,36 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,36 -DA:53,36 -DA:55,36 -DA:60,32 -DA:61,36 -DA:63,36 -DA:64,36 -DA:65,36 -DA:66,3 -DA:67,3 -DA:68,3 -DA:69,3 -DA:70,0 -DA:71,0 -DA:72,0 -DA:73,0 -DA:74,3 -DA:75,3 -DA:76,3 -DA:78,3 -DA:79,3 -DA:80,3 -DA:81,3 -DA:82,3 -DA:83,33 -DA:84,36 -DA:86,36 -LF:45 -LH:41 -BRDA:37,0,0,36 -BRDA:65,1,0,3 -BRDA:74,2,0,0 -BRDA:78,3,0,1 -BRDA:78,4,0,2 -BRDA:79,5,0,1 -BRDA:79,6,0,2 -BRDA:82,7,0,33 -BRDA:47,8,0,1 -BRDA:55,9,0,32 -BRDA:60,10,0,31 -BRDA:60,11,0,3 -BRF:12 -BRH:11 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/content-header.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:23,1 -DA:24,1 -DA:26,37 -DA:27,37 -DA:29,37 -DA:31,37 -DA:32,37 -DA:35,37 -DA:36,0 -DA:37,0 -DA:38,0 -DA:39,0 -DA:41,0 -DA:42,0 -DA:43,37 -DA:45,37 -DA:46,27 -DA:47,27 -DA:48,27 -DA:49,27 -DA:50,27 -DA:51,27 -DA:52,27 -DA:53,10 -DA:57,37 -DA:58,27 -DA:59,27 -DA:60,27 -DA:61,27 -DA:62,27 -DA:63,27 -DA:64,10 -DA:65,37 -DA:67,37 -DA:68,1 -DA:71,1 -LF:41 -LH:35 -BRDA:24,0,0,37 -BRDA:35,1,0,0 -BRDA:45,2,0,27 -BRDA:50,3,0,25 -BRDA:51,4,0,25 -BRDA:52,5,0,10 -BRDA:57,6,0,27 -BRDA:61,7,0,25 -BRDA:62,8,0,25 -BRDA:63,9,0,10 -BRDA:29,10,0,37 -BRF:11 -BRH:10 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/details-text.model.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -LF:0 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/details-text.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:4,1 -DA:5,1 -DA:7,1 -DA:8,1 -DA:9,38 -DA:10,38 -DA:11,38 -DA:12,38 -DA:13,38 -DA:14,38 -DA:15,38 -DA:16,38 -DA:17,38 -DA:18,38 -DA:20,38 -DA:21,38 -DA:22,38 -DA:23,38 -DA:24,38 -DA:25,38 -DA:26,38 -DA:28,38 -DA:29,38 -DA:30,38 -DA:31,38 -DA:32,38 -DA:33,38 -DA:35,38 -DA:36,38 -DA:38,38 -DA:39,38 -DA:40,38 -DA:41,38 -DA:42,38 -DA:43,38 -DA:44,38 -DA:45,38 -DA:46,38 -DA:47,38 -DA:48,38 -DA:49,38 -DA:50,38 -DA:51,38 -DA:53,38 -DA:54,38 -DA:55,38 -DA:56,38 -DA:58,38 -DA:59,38 -DA:61,38 -DA:62,1 -DA:64,1 -LF:54 -LH:54 -BRDA:8,0,0,38 -BRDA:47,1,0,0 -BRF:2 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/header-footer.model.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -LF:0 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/text-or-content.tsx -FN:31,renderTextArray -FN:65,getTextOrContent -FN:82,getTextContent -FN:99,getTextContentProps -FN:110,renderDetailedContent -FN:125,renderTimelineContent -FNF:6 -FNH:6 -FNDA:2,renderTextArray -FNDA:42,getTextOrContent -FNDA:42,getTextContent -FNDA:42,getTextContentProps -FNDA:42,renderDetailedContent -FNDA:42,renderTimelineContent -DA:3,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:26,1 -DA:31,1 -DA:32,2 -DA:33,2 -DA:34,2 -DA:35,2 -DA:36,2 -DA:37,2 -DA:38,2 -DA:40,4 -DA:41,4 -DA:42,0 -DA:43,0 -DA:44,0 -DA:45,0 -DA:46,0 -DA:47,4 -DA:48,4 -DA:49,4 -DA:50,4 -DA:51,4 -DA:52,4 -DA:53,4 -DA:54,4 -DA:56,4 -DA:57,4 -DA:59,2 -DA:60,2 -DA:63,1 -DA:65,1 -DA:66,42 -DA:67,42 -DA:68,42 -DA:69,42 -DA:70,42 -DA:71,42 -DA:72,42 -DA:73,42 -DA:74,42 -DA:75,42 -DA:77,42 -DA:78,42 -DA:79,42 -DA:82,42 -DA:83,42 -DA:84,40 -DA:85,1 -DA:86,39 -DA:87,40 -DA:89,2 -DA:90,2 -DA:91,42 -DA:92,42 -DA:93,42 -DA:94,42 -DA:95,42 -DA:96,42 -DA:99,42 -DA:100,42 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,41 -DA:108,42 -DA:110,42 -DA:111,42 -DA:113,42 -DA:114,42 -DA:115,42 -DA:116,42 -DA:117,42 -DA:118,42 -DA:120,42 -DA:121,42 -DA:123,42 -DA:125,42 -DA:126,42 -DA:127,0 -DA:128,0 -DA:130,42 -DA:131,42 -DA:132,42 -DA:134,42 -DA:135,42 -DA:136,42 -DA:138,42 -DA:140,42 -DA:141,42 -LF:95 -LH:88 -BRDA:31,0,0,2 -BRDA:38,1,0,4 -BRDA:41,2,0,0 -BRDA:41,3,0,0 -BRDA:56,4,0,0 -BRDA:56,5,0,0 -BRDA:65,6,0,42 -BRDA:72,7,0,42 -BRDA:77,8,0,42 -BRDA:78,9,0,1 -BRDA:78,10,0,41 -BRDA:82,11,0,42 -BRDA:83,12,0,40 -BRDA:84,13,0,1 -BRDA:84,14,0,1 -BRDA:85,15,0,39 -BRDA:87,16,0,2 -BRDA:99,17,0,42 -BRDA:100,18,0,1 -BRDA:100,19,0,1 -BRDA:106,20,0,41 -BRDA:110,21,0,42 -BRDA:115,22,0,3 -BRDA:115,23,0,39 -BRDA:120,24,0,1 -BRDA:120,25,0,41 -BRDA:125,26,0,42 -BRDA:126,27,0,0 -BRDA:131,28,0,0 -BRF:29 -BRH:23 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts -FN:44,getSlideShowAnimation.$slideShowActive.$slideShowActive -FN:52,getSlideShowAnimation.$slideShowActive.$slideShowActive -FN:62,getSlideShowAnimation -FN:91,getSlideShowVisibility -FN:112,slideAnimation -FN:128,__vite_ssr_import_0__.default.section.$textDensity.$textDensity -FN:162,__vite_ssr_import_0__.default.section.$textDensity.$textDensity -FN:170,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:173,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:174,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:178,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:220,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:221,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:224,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:238,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FN:247,shouldForwardProp -FN:266,shouldForwardProp -FN:304,__vite_ssr_import_0__.default.div.$useReadMore.$useReadMore -FN:330,__vite_ssr_import_0__.default.div.$useReadMore.$useReadMore -FN:332,__vite_ssr_import_0__.default.div.$useReadMore.$useReadMore -FN:335,__vite_ssr_import_0__.default.div.$cardHeight.$cardHeight -FN:340,__vite_ssr_import_0__.default.div.height.height -FN:351,__vite_ssr_import_0__.default.div.height.height -FN:354,__vite_ssr_import_0__.default.mark.color -FN:396,__vite_ssr_import_0__.default.mark.color -FN:416,__vite_ssr_import_0__.default.mark.color -FN:434,__vite_ssr_import_0__.default.mark.color -FN:495,__vite_ssr_import_0__.default.mark.color -FN:510,__vite_ssr_import_0__.default.mark.color -FNF:29 -FNH:20 -FNDA:38,getSlideShowAnimation.$slideShowActive.$slideShowActive -FNDA:38,getSlideShowAnimation.$slideShowActive.$slideShowActive -FNDA:38,getSlideShowAnimation -FNDA:38,getSlideShowVisibility -FNDA:0,slideAnimation -FNDA:74,__vite_ssr_import_0__.default.section.$textDensity.$textDensity -FNDA:38,__vite_ssr_import_0__.default.section.$textDensity.$textDensity -FNDA:38,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:38,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:38,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:38,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:0,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:0,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:0,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:0,__vite_ssr_import_0__.default.h1.withConfig.shouldForwardProp -FNDA:148,shouldForwardProp -FNDA:113,shouldForwardProp -FNDA:4,__vite_ssr_import_0__.default.div.$useReadMore.$useReadMore -FNDA:38,__vite_ssr_import_0__.default.div.$useReadMore.$useReadMore -FNDA:38,__vite_ssr_import_0__.default.div.$useReadMore.$useReadMore -FNDA:38,__vite_ssr_import_0__.default.div.$cardHeight.$cardHeight -FNDA:38,__vite_ssr_import_0__.default.div.height.height -FNDA:38,__vite_ssr_import_0__.default.div.height.height -FNDA:38,__vite_ssr_import_0__.default.mark.color -FNDA:3,__vite_ssr_import_0__.default.mark.color -FNDA:0,__vite_ssr_import_0__.default.mark.color -FNDA:0,__vite_ssr_import_0__.default.mark.color -FNDA:0,__vite_ssr_import_0__.default.mark.color -FNDA:0,__vite_ssr_import_0__.default.mark.color -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:20,1 -DA:26,1 -DA:27,1 -DA:43,1 -DA:44,1 -DA:52,1 -DA:56,1 -DA:62,1 -DA:63,38 -DA:65,38 -DA:67,0 -DA:68,0 -DA:69,0 -DA:71,0 -DA:73,0 -DA:74,0 -DA:75,0 -DA:76,0 -DA:78,0 -DA:79,0 -DA:80,0 -DA:81,0 -DA:83,0 -DA:84,0 -DA:86,0 -DA:87,0 -DA:89,0 -DA:91,1 -DA:92,38 -DA:94,38 -DA:95,0 -DA:100,0 -DA:102,38 -DA:103,0 -DA:106,0 -DA:108,38 -DA:109,38 -DA:112,1 -DA:114,0 -DA:117,0 -DA:122,1 -DA:127,1 -DA:128,1 -DA:131,1 -DA:136,1 -DA:155,1 -DA:162,1 -DA:165,1 -DA:170,1 -DA:171,1 -DA:173,1 -DA:174,1 -DA:178,1 -DA:182,1 -DA:183,38 -DA:184,0 -DA:188,0 -DA:189,0 -DA:191,1 -DA:194,1 -DA:195,38 -DA:196,0 -DA:197,0 -DA:198,0 -DA:199,1 -DA:202,1 -DA:203,1 -DA:207,1 -DA:213,1 -DA:219,1 -DA:220,1 -DA:221,1 -DA:224,1 -DA:227,1 -DA:231,1 -DA:237,1 -DA:238,1 -DA:239,1 -DA:242,1 -DA:246,1 -DA:247,1 -DA:248,148 -DA:249,1 -DA:256,1 -DA:257,1 -DA:260,1 -DA:265,1 -DA:266,1 -DA:267,113 -DA:268,1 -DA:275,1 -DA:276,1 -DA:277,1 -DA:280,1 -DA:289,1 -DA:294,1 -DA:298,1 -DA:304,1 -DA:305,1 -DA:308,1 -DA:321,1 -DA:330,1 -DA:332,1 -DA:335,1 -DA:336,38 -DA:337,36 -DA:338,1 -DA:340,1 -DA:341,38 -DA:342,38 -DA:343,38 -DA:344,38 -DA:345,38 -DA:346,38 -DA:347,38 -DA:348,2 -DA:349,1 -DA:351,1 -DA:354,1 -DA:355,38 -DA:356,38 -DA:357,38 -DA:358,38 -DA:359,38 -DA:360,38 -DA:361,38 -DA:362,0 -DA:363,0 -DA:365,0 -DA:368,0 -DA:370,0 -DA:372,1 -DA:383,1 -DA:384,1 -DA:388,1 -DA:396,1 -DA:401,1 -DA:410,1 -DA:416,1 -DA:434,1 -DA:439,1 -DA:444,1 -DA:445,0 -DA:446,0 -DA:447,0 -DA:450,0 -DA:451,0 -DA:452,0 -DA:454,0 -DA:455,0 -DA:466,1 -DA:474,1 -DA:475,1 -DA:483,1 -DA:495,1 -DA:497,1 -DA:498,1 -DA:499,1 -DA:509,1 -DA:510,1 -DA:511,0 -DA:512,1 -DA:525,1 -DA:526,0 -DA:528,0 -DA:530,0 -DA:531,0 -DA:532,0 -DA:533,0 -DA:534,0 -DA:537,0 -DA:538,0 -DA:539,0 -DA:540,0 -DA:541,0 -DA:542,0 -DA:543,0 -DA:545,1 -DA:546,0 -DA:547,0 -DA:548,0 -DA:551,0 -DA:552,0 -DA:553,0 -DA:554,0 -DA:555,0 -DA:556,0 -DA:557,0 -LF:192 -LH:125 -BRDA:27,0,0,38 -BRDA:27,1,0,32 -BRDA:44,2,0,38 -BRDA:52,3,0,38 -BRDA:56,4,0,38 -BRDA:62,5,0,38 -BRDA:65,6,0,0 -BRDA:65,7,0,0 -BRDA:91,8,0,38 -BRDA:94,9,0,0 -BRDA:94,10,0,0 -BRDA:102,11,0,0 -BRDA:102,12,0,0 -BRDA:128,13,0,74 -BRDA:128,14,0,2 -BRDA:131,15,0,74 -BRDA:131,16,0,13 -BRDA:131,17,0,61 -BRDA:162,18,0,38 -BRDA:170,19,0,38 -BRDA:171,20,0,0 -BRDA:173,21,0,38 -BRDA:173,22,0,0 -BRDA:174,23,0,38 -BRDA:174,24,0,0 -BRDA:178,25,0,38 -BRDA:178,26,0,32 -BRDA:182,27,0,38 -BRDA:183,28,0,0 -BRDA:194,29,0,38 -BRDA:195,30,0,0 -BRDA:247,31,0,148 -BRDA:257,32,0,37 -BRDA:260,33,0,37 -BRDA:266,34,0,113 -BRDA:276,35,0,37 -BRDA:277,36,0,37 -BRDA:277,37,0,2 -BRDA:294,38,0,42 -BRDA:304,39,0,4 -BRDA:305,40,0,4 -BRDA:330,41,0,38 -BRDA:330,42,0,1 -BRDA:330,43,0,37 -BRDA:332,44,0,38 -BRDA:332,45,0,0 -BRDA:335,46,0,38 -BRDA:336,47,0,36 -BRDA:336,48,0,36 -BRDA:337,49,0,2 -BRDA:340,50,0,38 -BRDA:347,51,0,2 -BRDA:347,52,0,2 -BRDA:348,53,0,0 -BRDA:348,54,0,0 -BRDA:348,55,0,36 -BRDA:351,56,0,38 -BRDA:351,57,0,0 -BRDA:354,58,0,38 -BRDA:361,59,0,2 -BRDA:361,60,0,2 -BRDA:361,61,0,0 -BRDA:383,62,0,38 -BRDA:396,63,0,3 -BRDA:396,64,0,0 -BRDA:401,65,0,3 -BRDA:474,66,0,3 -BRDA:475,67,0,2 -BRDA:475,68,0,1 -BRF:69 -BRH:52 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/timeline-card-content.tsx -FN:27,arePropsEqual -FNF:1 -FNH:1 -FNDA:4,arePropsEqual -DA:3,1 -DA:4,1 -DA:5,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:27,1 -DA:28,4 -DA:29,4 -DA:30,4 -DA:32,4 -DA:35,4 -DA:38,4 -DA:41,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:47,0 -DA:48,0 -DA:51,0 -DA:52,0 -DA:55,0 -DA:56,0 -DA:59,0 -DA:60,0 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,48 -DA:66,48 -DA:67,48 -DA:68,48 -DA:69,48 -DA:70,48 -DA:71,48 -DA:72,48 -DA:73,48 -DA:74,48 -DA:75,48 -DA:76,48 -DA:77,48 -DA:78,48 -DA:79,48 -DA:80,48 -DA:81,48 -DA:82,48 -DA:83,48 -DA:84,48 -DA:85,48 -DA:86,48 -DA:87,48 -DA:88,48 -DA:89,48 -DA:90,48 -DA:91,48 -DA:93,48 -DA:94,48 -DA:96,48 -DA:97,48 -DA:98,48 -DA:99,48 -DA:100,48 -DA:101,48 -DA:102,48 -DA:103,48 -DA:104,48 -DA:105,48 -DA:106,48 -DA:107,48 -DA:108,48 -DA:109,48 -DA:110,48 -DA:111,48 -DA:113,48 -DA:114,48 -DA:115,48 -DA:116,48 -DA:117,48 -DA:118,48 -DA:119,48 -DA:120,48 -DA:121,48 -DA:122,48 -DA:123,48 -DA:124,48 -DA:125,48 -DA:126,48 -DA:127,48 -DA:129,48 -DA:130,48 -DA:131,48 -DA:132,48 -DA:133,48 -DA:134,48 -DA:135,48 -DA:138,48 -DA:139,34 -DA:140,48 -DA:142,48 -DA:143,34 -DA:144,48 -DA:146,48 -DA:147,34 -DA:148,34 -DA:149,32 -DA:150,28 -DA:151,28 -DA:153,48 -DA:155,48 -DA:156,34 -DA:157,48 -DA:159,48 -DA:161,34 -DA:162,34 -DA:163,28 -DA:164,28 -DA:166,48 -DA:167,48 -DA:168,48 -DA:169,48 -DA:170,48 -DA:171,48 -DA:172,48 -DA:173,48 -DA:176,48 -DA:177,34 -DA:178,34 -DA:179,28 -DA:180,28 -DA:181,48 -DA:184,48 -DA:185,34 -DA:186,6 -DA:187,6 -DA:188,48 -DA:191,48 -DA:192,38 -DA:193,0 -DA:194,0 -DA:196,38 -DA:197,0 -DA:198,0 -DA:200,38 -DA:201,0 -DA:202,0 -DA:204,38 -DA:205,38 -DA:206,38 -DA:207,48 -DA:210,48 -DA:211,38 -DA:212,0 -DA:215,0 -DA:216,0 -DA:217,0 -DA:219,0 -DA:221,0 -DA:222,0 -DA:223,0 -DA:224,0 -DA:225,0 -DA:226,0 -DA:227,0 -DA:228,0 -DA:230,0 -DA:231,0 -DA:232,0 -DA:233,0 -DA:234,0 -DA:235,0 -DA:236,0 -DA:238,0 -DA:239,0 -DA:240,0 -DA:241,0 -DA:242,0 -DA:243,0 -DA:244,0 -DA:245,0 -DA:246,0 -DA:247,48 -DA:250,48 -DA:251,34 -DA:253,0 -DA:254,0 -DA:255,0 -DA:257,0 -DA:259,0 -DA:260,0 -DA:261,0 -DA:262,0 -DA:263,0 -DA:264,0 -DA:265,0 -DA:266,0 -DA:268,0 -DA:269,0 -DA:270,0 -DA:271,0 -DA:272,0 -DA:273,0 -DA:274,0 -DA:276,0 -DA:277,0 -DA:278,0 -DA:279,0 -DA:280,0 -DA:281,0 -DA:282,0 -DA:283,0 -DA:284,0 -DA:285,48 -DA:288,48 -DA:289,34 -DA:290,0 -DA:291,0 -DA:292,48 -DA:295,48 -DA:296,34 -DA:299,34 -DA:300,34 -DA:301,34 -DA:302,48 -DA:305,48 -DA:306,48 -DA:307,0 -DA:308,0 -DA:309,0 -DA:310,0 -DA:311,0 -DA:312,0 -DA:313,0 -DA:314,0 -DA:315,0 -DA:316,0 -DA:317,0 -DA:318,48 -DA:319,48 -DA:321,48 -DA:322,0 -DA:323,0 -DA:324,0 -DA:325,48 -DA:327,48 -DA:328,0 -DA:329,0 -DA:330,0 -DA:332,0 -DA:333,0 -DA:334,0 -DA:336,0 -DA:337,0 -DA:338,0 -DA:339,0 -DA:340,48 -DA:343,48 -DA:344,34 -DA:345,32 -DA:346,32 -DA:347,2 -DA:348,48 -DA:350,48 -DA:351,34 -DA:352,48 -DA:354,48 -DA:355,34 -DA:356,34 -DA:357,34 -DA:358,34 -DA:359,34 -DA:360,48 -DA:363,48 -DA:364,34 -DA:365,34 -DA:366,12 -DA:367,5 -DA:369,48 -DA:372,48 -DA:374,34 -DA:375,0 -DA:376,0 -DA:377,0 -DA:378,0 -DA:379,0 -DA:380,0 -DA:381,0 -DA:382,34 -DA:383,48 -DA:384,48 -DA:385,48 -DA:386,48 -DA:387,48 -DA:388,48 -DA:389,48 -DA:390,48 -DA:393,48 -DA:394,34 -DA:395,0 -DA:396,34 -DA:397,34 -DA:398,34 -DA:399,0 -DA:400,0 -DA:401,48 -DA:403,48 -DA:404,48 -DA:405,48 -DA:406,48 -DA:407,48 -DA:408,48 -DA:409,48 -DA:410,48 -DA:411,48 -DA:412,48 -DA:413,48 -DA:414,48 -DA:415,48 -DA:416,48 -DA:417,48 -DA:418,48 -DA:419,48 -DA:420,48 -DA:421,48 -DA:422,48 -DA:423,48 -DA:424,48 -DA:425,48 -DA:426,48 -DA:427,48 -DA:428,48 -DA:429,48 -DA:430,48 -DA:433,48 -DA:434,48 -DA:435,48 -DA:436,48 -DA:437,48 -DA:438,48 -DA:439,48 -DA:440,48 -DA:441,48 -DA:444,48 -DA:445,16 -DA:446,16 -DA:447,16 -DA:448,16 -DA:449,16 -DA:450,16 -DA:451,16 -DA:452,16 -DA:453,16 -DA:454,16 -DA:455,16 -DA:456,16 -DA:457,16 -DA:458,16 -DA:459,16 -DA:460,16 -DA:461,16 -DA:462,16 -DA:463,16 -DA:464,16 -DA:465,16 -DA:468,48 -DA:469,42 -DA:470,42 -DA:471,42 -DA:472,42 -DA:473,42 -DA:474,42 -DA:475,42 -DA:476,42 -DA:477,42 -DA:478,42 -DA:479,42 -DA:482,48 -DA:483,0 -DA:484,0 -DA:485,0 -DA:486,0 -DA:487,0 -DA:488,0 -DA:491,48 -DA:492,42 -DA:493,42 -DA:494,42 -DA:495,42 -DA:496,42 -DA:497,42 -DA:498,42 -DA:499,42 -DA:500,42 -DA:501,42 -DA:502,42 -DA:503,42 -DA:505,48 -DA:507,48 -DA:508,1 -DA:509,1 -DA:511,1 -LF:407 -LH:290 -BRDA:27,0,0,4 -BRDA:32,1,0,0 -BRDA:35,2,0,0 -BRDA:38,3,0,0 -BRDA:64,4,0,48 -BRDA:352,5,0,42 -BRDA:360,6,0,46 -BRDA:409,7,0,12 -BRDA:409,8,0,36 -BRDA:410,9,0,46 -BRDA:410,10,0,2 -BRDA:418,11,0,12 -BRDA:418,12,0,36 -BRDA:433,13,0,0 -BRDA:444,14,0,16 -BRDA:455,15,0,14 -BRDA:455,16,0,2 -BRDA:468,17,0,42 -BRDA:482,18,0,0 -BRDA:491,19,0,42 -BRDA:491,20,0,42 -BRDA:491,21,0,42 -BRDA:138,22,0,34 -BRDA:139,23,0,6 -BRDA:139,24,0,0 -BRDA:142,25,0,34 -BRDA:146,26,0,34 -BRDA:148,27,0,32 -BRDA:149,28,0,28 -BRDA:150,29,0,28 -BRDA:155,30,0,34 -BRDA:156,31,0,0 -BRDA:159,32,0,34 -BRDA:162,33,0,4 -BRDA:162,34,0,4 -BRDA:162,35,0,28 -BRDA:163,36,0,0 -BRDA:163,37,0,28 -BRDA:176,38,0,34 -BRDA:178,39,0,28 -BRDA:184,40,0,34 -BRDA:185,41,0,6 -BRDA:185,42,0,6 -BRDA:191,43,0,38 -BRDA:192,44,0,0 -BRDA:196,45,0,6 -BRDA:196,46,0,0 -BRDA:200,47,0,6 -BRDA:200,48,0,0 -BRDA:200,49,0,0 -BRDA:210,50,0,38 -BRDA:211,51,0,4 -BRDA:211,52,0,0 -BRDA:211,53,0,0 -BRDA:250,54,0,34 -BRDA:251,55,0,6 -BRDA:251,56,0,0 -BRDA:251,57,0,0 -BRDA:288,58,0,34 -BRDA:289,59,0,0 -BRDA:295,60,0,34 -BRDA:299,61,0,34 -BRDA:343,62,0,34 -BRDA:344,63,0,32 -BRDA:345,64,0,0 -BRDA:346,65,0,2 -BRDA:350,66,0,34 -BRDA:351,67,0,28 -BRDA:351,68,0,6 -BRDA:354,69,0,34 -BRDA:357,70,0,32 -BRDA:357,71,0,2 -BRDA:358,72,0,0 -BRDA:363,73,0,34 -BRDA:365,74,0,22 -BRDA:365,75,0,12 -BRDA:365,76,0,12 -BRDA:366,77,0,7 -BRDA:366,78,0,5 -BRDA:366,79,0,5 -BRDA:372,80,0,34 -BRDA:374,81,0,0 -BRDA:374,82,0,0 -BRDA:393,83,0,34 -BRDA:394,84,0,0 -BRDA:394,85,0,0 -BRDA:398,86,0,0 -BRF:87 -BRH:63 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/__tests__/content-footer.test.tsx -FN:11,onExpand -FNF:1 -FNH:0 -FNDA:0,onExpand -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:22,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:32,1 -DA:33,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -LF:78 -LH:78 -BRDA:22,0,0,1 -BRDA:24,1,0,1 -BRDA:36,2,0,1 -BRDA:54,3,0,1 -BRDA:73,4,0,1 -BRF:5 -BRH:5 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:32,1 -DA:33,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -LF:42 -LH:42 -BRDA:6,0,0,1 -BRDA:8,1,0,1 -BRDA:24,2,0,1 -BRDA:36,3,0,1 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/__tests__/details-text.test.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:5,1 -DA:6,1 -DA:8,1 -DA:9,6 -DA:10,6 -DA:11,6 -DA:12,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -LF:76 -LH:76 -BRDA:5,0,0,1 -BRDA:8,1,0,6 -BRDA:14,2,0,1 -BRDA:15,3,0,1 -BRDA:23,4,0,1 -BRDA:33,5,0,1 -BRDA:34,6,0,1 -BRDA:47,7,0,1 -BRDA:60,8,0,1 -BRDA:61,9,0,1 -BRDA:76,10,0,1 -BRDA:77,11,0,1 -BRF:12 -BRH:12 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/__tests__/text_or_content.test.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:34,1 -DA:35,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -LF:53 -LH:53 -BRDA:6,0,0,1 -BRDA:9,1,0,1 -BRDA:22,2,0,1 -BRDA:37,3,0,1 -BRDA:51,4,0,1 -BRF:5 -BRH:5 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx -FN:88,timeout -FN:119,timeout -FNF:2 -FNH:2 -FNDA:1,timeout -FNDA:1,timeout -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,0 -DA:12,0 -DA:13,0 -DA:14,0 -DA:15,0 -DA:16,0 -DA:17,1 -DA:18,1 -DA:19,1 -DA:22,1 -DA:24,1 -DA:25,6 -DA:26,1 -DA:29,1 -DA:30,1 -DA:32,1 -DA:34,1 -DA:37,1 -DA:38,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 -LF:108 -LH:102 -BRDA:7,0,0,1 -BRDA:8,1,0,1 -BRDA:24,2,0,6 -BRDA:29,3,0,1 -BRDA:37,4,0,1 -BRDA:45,5,0,1 -BRDA:57,6,0,1 -BRDA:71,7,0,1 -BRDA:88,8,0,1 -BRDA:102,9,0,1 -BRDA:119,10,0,1 -BRF:11 -BRH:11 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/timeline-card-media-buttons.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:4,1 -DA:17,1 -DA:26,1 -DA:30,1 -DA:33,1 -DA:37,1 -DA:40,1 -LF:8 -LH:8 -BRDA:17,0,0,4 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/timeline-card-media.styles.ts -FN:35,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:38,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:40,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:42,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:95,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:128,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:140,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:165,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FN:166,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNF:9 -FNH:9 -FNDA:18,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:18,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:18,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:18,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:15,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:14,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:14,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:14,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -FNDA:14,__vite_ssr_import_0__.default.div.$borderLessCard.$borderLessCard -DA:3,1 -DA:4,1 -DA:5,1 -DA:7,1 -DA:23,1 -DA:35,1 -DA:38,1 -DA:40,1 -DA:42,1 -DA:45,1 -DA:47,1 -DA:48,1 -DA:49,18 -DA:50,1 -DA:53,18 -DA:54,17 -DA:55,0 -DA:58,17 -DA:59,17 -DA:62,17 -DA:63,17 -DA:64,18 -DA:67,1 -DA:82,1 -DA:95,1 -DA:97,1 -DA:98,1 -DA:106,1 -DA:113,1 -DA:128,1 -DA:129,14 -DA:130,14 -DA:131,14 -DA:132,14 -DA:133,14 -DA:134,14 -DA:135,14 -DA:140,1 -DA:141,14 -DA:142,0 -DA:147,0 -DA:149,14 -DA:150,0 -DA:155,0 -DA:157,14 -DA:158,2 -DA:163,2 -DA:164,14 -DA:165,1 -DA:166,1 -DA:167,14 -DA:168,2 -DA:170,2 -DA:172,2 -DA:174,2 -DA:175,2 -DA:178,2 -DA:181,1 -DA:183,1 -DA:184,14 -DA:185,0 -DA:186,1 -DA:187,1 -DA:188,1 -DA:191,1 -DA:200,1 -DA:206,1 -DA:216,1 -DA:217,1 -DA:225,1 -DA:227,1 -DA:228,3 -DA:229,1 -DA:232,3 -DA:233,2 -DA:236,2 -DA:237,3 -DA:239,1 -DA:240,3 -DA:241,3 -DA:243,0 -DA:245,1 -DA:247,1 -DA:250,1 -LF:84 -LH:77 -BRDA:35,0,0,18 -BRDA:35,1,0,16 -BRDA:35,2,0,2 -BRDA:38,3,0,18 -BRDA:38,4,0,2 -BRDA:38,5,0,16 -BRDA:40,6,0,18 -BRDA:40,7,0,11 -BRDA:40,8,0,0 -BRDA:42,9,0,18 -BRDA:47,10,0,18 -BRDA:47,11,0,16 -BRDA:47,12,0,2 -BRDA:48,13,0,18 -BRDA:49,14,0,1 -BRDA:53,15,0,17 -BRDA:54,16,0,0 -BRDA:95,17,0,15 -BRDA:97,18,0,15 -BRDA:97,19,0,0 -BRDA:98,20,0,15 -BRDA:98,21,0,0 -BRDA:128,22,0,14 -BRDA:130,23,0,1 -BRDA:131,24,0,1 -BRDA:140,25,0,14 -BRDA:141,26,0,2 -BRDA:141,27,0,0 -BRDA:149,28,0,0 -BRDA:157,29,0,2 -BRDA:157,30,0,2 -BRDA:165,31,0,14 -BRDA:165,32,0,2 -BRDA:165,33,0,12 -BRDA:166,34,0,14 -BRDA:167,35,0,2 -BRDA:170,36,0,0 -BRDA:174,37,0,0 -BRDA:178,38,0,0 -BRDA:178,39,0,12 -BRDA:183,40,0,14 -BRDA:184,41,0,0 -BRDA:187,42,0,14 -BRDA:188,43,0,14 -BRDA:188,44,0,2 -BRDA:188,45,0,12 -BRDA:216,46,0,3 -BRDA:217,47,0,3 -BRDA:227,48,0,3 -BRDA:228,49,0,1 -BRDA:232,50,0,2 -BRDA:239,51,0,3 -BRDA:241,52,0,0 -BRDA:247,53,0,3 -BRDA:247,54,0,2 -BRF:55 -BRH:44 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/timeline-card-media.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:16,1 -DA:17,1 -DA:18,18 -DA:19,18 -DA:20,18 -DA:21,18 -DA:22,18 -DA:23,18 -DA:24,18 -DA:25,18 -DA:26,18 -DA:27,18 -DA:29,18 -DA:30,18 -DA:31,18 -DA:32,18 -DA:33,18 -DA:36,18 -DA:37,18 -DA:38,18 -DA:39,18 -DA:40,18 -DA:41,18 -DA:42,18 -DA:43,18 -DA:44,18 -DA:45,18 -DA:46,18 -DA:49,18 -DA:50,18 -DA:51,18 -DA:52,18 -DA:53,18 -DA:54,18 -DA:55,18 -DA:56,18 -DA:57,18 -DA:58,18 -DA:59,18 -DA:60,18 -DA:61,18 -DA:62,18 -DA:63,18 -DA:64,18 -DA:65,18 -DA:66,18 -DA:69,18 -DA:72,18 -DA:73,0 -DA:75,0 -DA:76,18 -DA:78,18 -DA:79,18 -DA:80,18 -DA:81,18 -DA:82,18 -DA:83,18 -DA:84,18 -DA:85,18 -DA:86,18 -DA:87,18 -DA:88,18 -DA:90,18 -DA:91,18 -DA:92,18 -DA:93,18 -DA:94,18 -DA:95,18 -DA:96,18 -DA:97,18 -DA:98,18 -DA:99,18 -DA:100,18 -DA:101,18 -DA:102,18 -DA:103,18 -DA:104,18 -DA:105,18 -DA:107,18 -DA:108,14 -DA:109,14 -DA:110,14 -DA:111,14 -DA:112,14 -DA:113,14 -DA:114,14 -DA:115,14 -DA:116,14 -DA:117,14 -DA:118,14 -DA:119,14 -DA:120,14 -DA:121,14 -DA:122,14 -DA:123,14 -DA:124,14 -DA:125,14 -DA:126,14 -DA:127,14 -DA:128,14 -DA:130,18 -DA:132,18 -DA:133,1 -DA:135,0 -DA:136,0 -DA:137,0 -DA:138,0 -DA:139,0 -DA:140,0 -DA:141,0 -DA:143,0 -DA:144,1 -DA:146,1 -DA:148,1 -LF:124 -LH:114 -BRDA:17,0,0,18 -BRDA:87,1,0,0 -BRDA:107,2,0,14 -BRF:3 -BRH:2 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/video.tsx -FN:1,(empty-report) -FNF:1 -FNH:0 -FNDA:0,(empty-report) -DA:1,0 -DA:2,0 -DA:8,0 -DA:18,0 -DA:19,0 -DA:20,0 -DA:21,0 -DA:22,0 -DA:23,0 -DA:24,0 -DA:25,0 -DA:26,0 -DA:27,0 -DA:30,0 -DA:31,0 -DA:32,0 -DA:33,0 -DA:34,0 -DA:36,0 -DA:37,0 -DA:38,0 -DA:39,0 -DA:40,0 -DA:41,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:45,0 -DA:46,0 -DA:48,0 -DA:49,0 -DA:51,0 -DA:53,0 -LF:33 -LH:0 -BRDA:1,0,0,0 -BRF:1 -BRH:0 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/__tests__/timeline-card-media.test.tsx -FN:28,onMediaStateChange -FN:61,onMediaStateChange -FN:84,onMediaStateChange -FN:106,onMediaStateChange -FN:136,onMediaStateChange -FN:162,onMediaStateChange -FN:188,onMediaStateChange -FN:220,onMediaStateChange -FNF:8 -FNH:0 -FNDA:0,onMediaStateChange -FNDA:0,onMediaStateChange -FNDA:0,onMediaStateChange -FNDA:0,onMediaStateChange -FNDA:0,onMediaStateChange -FNDA:0,onMediaStateChange -FNDA:0,onMediaStateChange -FNDA:0,onMediaStateChange -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:7,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:141,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:145,1 -DA:148,1 -DA:149,1 -DA:150,1 -DA:151,1 -DA:152,1 -DA:153,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:157,1 -DA:158,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:162,1 -DA:163,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:168,1 -DA:169,1 -DA:174,1 -DA:175,1 -DA:176,1 -DA:177,1 -DA:178,1 -DA:179,1 -DA:180,1 -DA:181,1 -DA:182,1 -DA:183,1 -DA:184,1 -DA:185,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:190,1 -DA:191,1 -DA:192,1 -DA:193,1 -DA:194,1 -DA:195,1 -DA:196,1 -DA:197,1 -DA:198,1 -DA:199,1 -DA:201,1 -DA:202,1 -DA:203,1 -DA:206,1 -DA:207,1 -DA:208,1 -DA:209,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:213,1 -DA:214,1 -DA:215,1 -DA:216,1 -DA:217,1 -DA:218,1 -DA:219,1 -DA:220,1 -DA:221,1 -DA:222,1 -DA:223,1 -DA:224,1 -DA:225,1 -DA:226,1 -LF:201 -LH:201 -BRDA:7,0,0,1 -BRDA:10,1,0,2 -BRDA:14,2,0,1 -BRDA:46,3,0,1 -BRDA:69,4,0,1 -BRDA:92,5,0,1 -BRDA:114,6,0,1 -BRDA:148,7,0,1 -BRDA:174,8,0,1 -BRDA:206,9,0,1 -BRF:10 -BRH:10 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/components/ContentDisplay.tsx -FN:36,ContentDisplayComponent -FNF:1 -FNH:1 -FNDA:14,ContentDisplayComponent -DA:1,1 -DA:2,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:36,1 -DA:37,14 -DA:38,14 -DA:39,14 -DA:40,14 -DA:41,14 -DA:42,14 -DA:43,14 -DA:44,14 -DA:45,14 -DA:46,14 -DA:47,14 -DA:48,14 -DA:49,14 -DA:50,14 -DA:51,14 -DA:52,14 -DA:53,14 -DA:54,14 -DA:55,14 -DA:56,14 -DA:57,14 -DA:58,14 -DA:59,14 -DA:61,14 -DA:63,14 -DA:64,14 -DA:65,14 -DA:66,14 -DA:67,14 -DA:68,14 -DA:69,14 -DA:70,14 -DA:71,14 -DA:72,14 -DA:73,14 -DA:75,14 -DA:76,14 -DA:77,14 -DA:78,14 -DA:79,14 -DA:80,14 -DA:81,14 -DA:82,14 -DA:83,14 -DA:84,14 -DA:85,2 -DA:86,2 -DA:87,2 -DA:88,2 -DA:89,2 -DA:90,2 -DA:91,2 -DA:92,2 -DA:93,2 -DA:94,2 -DA:95,2 -DA:96,2 -DA:97,2 -DA:98,2 -DA:100,14 -DA:101,14 -DA:102,14 -DA:103,14 -DA:104,14 -DA:105,14 -DA:106,14 -DA:107,14 -DA:108,14 -DA:110,14 -DA:111,8 -DA:112,8 -DA:113,8 -DA:114,8 -DA:115,8 -DA:116,8 -DA:117,8 -DA:118,8 -DA:120,14 -DA:122,14 -DA:125,1 -DA:128,1 -LF:90 -LH:90 -BRDA:36,0,0,14 -BRDA:73,1,0,2 -BRDA:73,2,0,12 -BRDA:84,3,0,2 -BRDA:110,4,0,8 -BRDA:110,5,0,8 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/components/ErrorMessage.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:11,1 -DA:12,0 -DA:13,1 -LF:5 -LH:4 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/components/ImageDisplay.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:20,1 -DA:21,1 -DA:22,15 -DA:23,15 -DA:24,15 -DA:25,15 -DA:26,15 -DA:27,15 -DA:28,15 -DA:29,15 -DA:30,15 -DA:31,15 -DA:32,15 -DA:33,15 -DA:34,15 -DA:35,15 -DA:36,15 -DA:37,15 -DA:38,15 -DA:39,15 -DA:40,15 -DA:41,15 -DA:42,15 -DA:43,15 -DA:44,15 -DA:45,15 -DA:46,15 -DA:47,15 -DA:49,1 -LF:31 -LH:31 -BRDA:21,0,0,15 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/components/MediaContent.tsx -FNF:0 -FNH:0 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:34,1 -DA:35,1 -DA:36,18 -DA:37,18 -DA:38,18 -DA:39,18 -DA:40,18 -DA:41,18 -DA:42,18 -DA:43,18 -DA:44,18 -DA:45,18 -DA:46,18 -DA:47,18 -DA:48,18 -DA:49,18 -DA:50,18 -DA:51,3 -DA:52,3 -DA:53,3 -DA:54,3 -DA:55,3 -DA:56,3 -DA:57,3 -DA:59,3 -DA:61,0 -DA:62,0 -DA:64,0 -DA:65,0 -DA:66,0 -DA:67,0 -DA:68,0 -DA:69,0 -DA:70,0 -DA:71,0 -DA:72,0 -DA:74,3 -DA:76,15 -DA:77,15 -DA:78,0 -DA:80,15 -DA:81,15 -DA:82,15 -DA:83,15 -DA:84,15 -DA:85,15 -DA:86,15 -DA:87,15 -DA:88,15 -DA:89,15 -DA:90,15 -DA:92,15 -DA:94,0 -DA:95,18 -DA:96,1 -LF:60 -LH:47 -BRDA:35,0,0,18 -BRDA:50,1,0,3 -BRDA:56,2,0,1 -BRDA:59,3,0,0 -BRDA:62,4,0,0 -BRDA:74,5,0,15 -BRDA:77,6,0,0 -BRDA:82,7,0,3 -BRDA:87,8,0,0 -BRDA:92,9,0,0 -BRF:10 -BRH:5 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/components/VideoPlayer.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:18,1 -DA:19,1 -DA:20,0 -DA:21,0 -DA:22,0 -DA:23,0 -DA:24,0 -DA:25,0 -DA:26,0 -DA:27,0 -DA:28,0 -DA:30,0 -DA:31,0 -DA:33,0 -DA:34,0 -DA:36,0 -DA:37,0 -DA:38,0 -DA:39,0 -DA:40,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:45,0 -DA:46,0 -DA:47,0 -DA:48,0 -DA:49,0 -DA:50,0 -DA:51,0 -DA:52,0 -DA:53,0 -DA:54,0 -DA:56,0 -DA:57,0 -DA:58,0 -DA:59,0 -DA:60,0 -DA:61,0 -DA:63,0 -DA:64,0 -DA:65,0 -DA:66,0 -DA:67,0 -DA:68,0 -DA:70,0 -DA:71,0 -DA:73,0 -DA:74,0 -DA:76,0 -DA:77,1 -LF:53 -LH:5 -BRF:0 -BRH:0 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/components/YoutubePlayer.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:13,1 -DA:14,1 -DA:15,3 -DA:16,3 -DA:17,3 -DA:18,3 -DA:19,3 -DA:20,3 -DA:21,3 -DA:22,3 -DA:23,3 -DA:25,1 -LF:14 -LH:14 -BRDA:14,0,0,3 -BRDA:19,1,0,0 -BRF:2 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/hooks/useMediaLoad.ts -FN:18,useMediaLoad -FNF:1 -FNH:1 -FNDA:18,useMediaLoad -DA:2,1 -DA:18,1 -DA:19,18 -DA:20,18 -DA:21,18 -DA:22,18 -DA:23,18 -DA:26,18 -DA:27,0 -DA:28,18 -DA:31,18 -DA:32,0 -DA:33,0 -DA:34,0 -DA:35,0 -DA:36,0 -DA:37,0 -DA:38,18 -DA:40,18 -DA:41,18 -DA:42,18 -DA:43,18 -DA:44,18 -DA:45,18 -DA:46,18 -LF:25 -LH:18 -BRDA:18,0,0,18 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/hooks/useToggleControls.ts -FN:7,useToggleControls -FNF:1 -FNH:1 -FNDA:18,useToggleControls -DA:1,1 -DA:7,1 -DA:8,18 -DA:9,18 -DA:11,18 -DA:12,0 -DA:13,0 -DA:14,18 -DA:16,18 -DA:17,0 -DA:18,0 -DA:19,18 -DA:21,18 -DA:22,18 -DA:23,18 -DA:24,18 -DA:25,18 -DA:26,18 -DA:27,18 -LF:19 -LH:15 -BRDA:7,0,0,18 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/hooks/useViewOptions.ts -FN:29,useViewOptions -FNF:1 -FNH:1 -FNDA:18,useViewOptions -DA:1,1 -DA:2,1 -DA:29,1 -DA:30,18 -DA:31,18 -DA:32,18 -DA:33,18 -DA:34,18 -DA:35,18 -DA:36,18 -DA:37,18 -DA:38,18 -DA:39,18 -DA:40,18 -DA:41,18 -DA:42,18 -DA:43,18 -DA:45,18 -DA:46,18 -DA:47,18 -DA:48,18 -DA:50,18 -DA:51,18 -DA:52,18 -DA:53,18 -DA:55,18 -DA:56,18 -DA:57,18 -DA:58,18 -DA:60,18 -DA:61,18 -DA:62,18 -DA:63,18 -DA:65,18 -DA:66,18 -DA:67,18 -DA:68,18 -DA:70,18 -DA:71,18 -DA:72,18 -DA:73,18 -DA:74,18 -DA:75,18 -DA:76,18 -DA:77,18 -DA:78,18 -LF:46 -LH:46 -BRDA:29,0,0,18 -BRDA:41,1,0,18 -BRDA:46,2,0,18 -BRDA:46,3,0,5 -BRDA:46,4,0,2 -BRDA:51,5,0,18 -BRDA:51,6,0,2 -BRDA:56,7,0,18 -BRDA:56,8,0,0 -BRDA:61,9,0,18 -BRDA:66,10,0,18 -BRDA:66,11,0,2 -BRDA:66,12,0,16 -BRF:13 -BRH:12 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card-media/hooks/useYouTubeDetection.ts -FN:8,useYouTubeDetection -FNF:1 -FNH:1 -FNDA:18,useYouTubeDetection -DA:1,1 -DA:8,1 -DA:9,18 -DA:10,18 -DA:11,18 -DA:12,18 -DA:13,18 -LF:7 -LH:7 -BRDA:8,0,0,18 -BRDA:10,1,0,18 -BRF:2 -BRH:2 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card/__tests__/timeline-horizontal-card.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,0 -DA:40,0 -DA:41,0 -DA:42,0 -DA:43,0 -DA:44,0 -DA:45,1 -DA:46,1 -DA:47,1 -DA:50,1 -DA:52,1 -DA:54,6 -DA:55,6 -DA:56,6 -DA:57,1 -DA:59,1 -DA:61,6 -DA:62,6 -DA:63,6 -DA:64,6 -DA:65,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:73,1 -DA:74,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:82,1 -DA:83,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:117,1 -DA:118,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:127,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -LF:99 -LH:93 -BRDA:35,0,0,1 -BRDA:36,1,0,1 -BRDA:52,2,0,6 -BRDA:59,3,0,6 -BRDA:68,4,0,1 -BRDA:77,5,0,1 -BRDA:86,6,0,1 -BRDA:97,7,0,1 -BRDA:112,8,0,1 -BRDA:121,9,0,1 -BRF:10 -BRH:10 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card/hooks/useTimelineCard.ts -FN:5,useTimelineCard -FNF:1 -FNH:1 -FNDA:67,useTimelineCard -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:6,67 -DA:7,67 -DA:8,67 -DA:9,67 -DA:10,67 -DA:11,67 -DA:12,67 -DA:13,67 -DA:14,67 -DA:15,67 -DA:16,67 -DA:17,67 -DA:18,67 -DA:19,67 -DA:21,67 -DA:23,67 -DA:24,0 -DA:25,0 -DA:26,0 -DA:27,67 -DA:29,67 -DA:30,67 -DA:31,25 -DA:32,25 -DA:34,25 -DA:35,25 -DA:36,25 -DA:38,25 -DA:39,19 -DA:40,19 -DA:41,19 -DA:42,25 -DA:43,25 -DA:44,67 -DA:46,67 -DA:48,67 -DA:49,67 -DA:50,67 -DA:51,67 -DA:52,67 -DA:53,67 -DA:54,67 -DA:55,67 -DA:56,67 -DA:57,67 -DA:59,67 -DA:60,67 -DA:61,67 -DA:62,67 -DA:64,67 -DA:65,67 -DA:66,67 -DA:67,67 -DA:68,67 -DA:69,67 -DA:70,67 -DA:71,67 -DA:72,67 -DA:73,67 -DA:75,67 -DA:76,67 -DA:77,67 -DA:78,67 -DA:80,67 -DA:81,67 -DA:82,67 -DA:83,67 -DA:84,67 -DA:85,67 -DA:86,67 -DA:87,67 -DA:88,67 -DA:89,67 -DA:90,67 -DA:91,67 -LF:79 -LH:76 -BRDA:5,0,0,67 -BRDA:29,1,0,67 -BRDA:30,2,0,25 -BRDA:38,3,0,19 -BRDA:46,4,0,67 -BRDA:49,5,0,67 -BRDA:53,6,0,0 -BRDA:54,7,0,3 -BRDA:54,8,0,64 -BRDA:60,9,0,67 -BRDA:65,10,0,67 -BRDA:70,11,0,25 -BRDA:70,12,0,42 -BRDA:76,13,0,67 -BRDA:76,14,0,25 -BRDA:76,15,0,42 -BRF:16 -BRH:15 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card/timeline-card-portal/timeline-card-portal.tsx -FN:32,TimelineCardPortal -FNF:1 -FNH:1 -FNDA:27,TimelineCardPortal -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:32,1 -DA:33,27 -DA:34,27 -DA:35,27 -DA:36,27 -DA:37,27 -DA:38,27 -DA:39,27 -DA:40,27 -DA:41,27 -DA:42,27 -DA:43,27 -DA:44,27 -DA:45,27 -DA:46,27 -DA:47,27 -DA:48,27 -DA:49,27 -DA:50,27 -DA:51,27 -DA:52,27 -DA:53,27 -DA:54,27 -DA:55,27 -DA:56,27 -DA:57,27 -DA:59,27 -DA:60,27 -DA:61,27 -DA:62,27 -DA:63,27 -DA:64,27 -DA:65,27 -DA:66,27 -DA:67,27 -DA:68,27 -DA:69,27 -DA:71,27 -DA:72,27 -DA:73,27 -DA:74,27 -DA:75,27 -DA:76,27 -DA:77,27 -DA:78,27 -DA:79,27 -DA:80,27 -DA:81,27 -DA:82,27 -DA:83,27 -DA:84,27 -DA:85,27 -DA:86,27 -DA:87,27 -DA:88,27 -DA:89,27 -DA:90,27 -DA:91,27 -DA:93,27 -DA:94,27 -DA:95,27 -DA:96,27 -DA:97,27 -DA:98,27 -DA:99,27 -DA:100,27 -DA:101,27 -DA:102,27 -DA:103,27 -DA:104,27 -DA:105,27 -DA:106,27 -DA:107,27 -DA:108,27 -DA:109,27 -DA:110,27 -DA:111,27 -DA:112,27 -DA:113,27 -DA:114,27 -DA:115,27 -DA:116,27 -DA:118,27 -DA:119,27 -DA:120,27 -DA:121,6 -DA:122,6 -DA:123,21 -DA:124,27 -DA:126,27 -DA:127,27 -DA:129,1 -LF:96 -LH:96 -BRDA:32,0,0,27 -BRDA:59,1,0,27 -BRDA:66,2,0,25 -BRDA:118,3,0,27 -BRDA:120,4,0,6 -BRDA:122,5,0,21 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-card/timeline-point/timeline-point.tsx -FN:17,TimelinePoint -FNF:1 -FNH:1 -FNDA:67,TimelinePoint -DA:2,1 -DA:17,1 -DA:18,67 -DA:19,67 -DA:20,67 -DA:21,67 -DA:22,67 -DA:23,67 -DA:24,67 -DA:25,67 -DA:26,67 -DA:27,67 -DA:28,67 -DA:29,67 -DA:30,67 -DA:31,67 -DA:32,67 -DA:33,67 -DA:34,67 -DA:35,67 -DA:36,67 -DA:37,67 -DA:38,67 -DA:39,67 -DA:40,67 -DA:41,67 -DA:42,67 -DA:43,67 -DA:44,67 -DA:45,67 -DA:47,67 -DA:48,67 -DA:49,67 -DA:51,67 -DA:53,1 -LF:35 -LH:35 -BRDA:17,0,0,67 -BRDA:38,1,0,0 -BRDA:44,2,0,0 -BRDA:47,3,0,58 -BRF:4 -BRH:2 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-control/timeline-control.styles.ts -FNF:0 -FNH:0 -DA:3,1 -DA:4,1 -DA:6,1 -DA:18,1 -DA:24,1 -DA:25,1 -DA:27,1 -DA:43,1 -DA:48,1 -DA:49,0 -DA:50,0 -DA:51,1 -DA:54,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:77,1 -DA:79,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:91,1 -DA:93,1 -DA:95,1 -DA:98,1 -DA:99,64 -DA:100,0 -DA:101,0 -DA:102,0 -DA:104,0 -DA:105,0 -DA:106,0 -DA:109,0 -DA:112,0 -DA:114,0 -DA:115,0 -DA:116,0 -DA:120,0 -DA:121,0 -DA:122,0 -DA:124,1 -DA:129,1 -DA:135,1 -DA:144,1 -DA:150,1 -DA:156,1 -DA:159,1 -DA:161,1 -DA:178,1 -DA:180,1 -LF:52 -LH:36 -BRDA:24,0,0,12 -BRDA:25,1,0,12 -BRDA:61,2,0,64 -BRDA:63,3,0,64 -BRDA:64,4,0,64 -BRDA:64,5,0,0 -BRDA:77,6,0,64 -BRDA:79,7,0,64 -BRDA:79,8,0,44 -BRDA:79,9,0,20 -BRDA:82,10,0,64 -BRDA:84,11,0,64 -BRDA:85,12,0,64 -BRDA:86,13,0,64 -BRDA:86,14,0,44 -BRDA:86,15,0,20 -BRDA:91,16,0,64 -BRDA:91,17,0,44 -BRDA:91,18,0,20 -BRDA:93,19,0,64 -BRDA:95,20,0,64 -BRDA:98,21,0,64 -BRDA:99,22,0,0 -BRDA:129,23,0,64 -BRF:24 -BRH:22 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-control/timeline-control.styles.tsx -FN:1,(empty-report) -FNF:1 -FNH:0 -FNDA:0,(empty-report) -DA:1,0 -DA:3,0 -LF:2 -LH:0 -BRDA:1,0,0,0 -BRF:1 -BRH:0 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-control/timeline-control.tsx -FN:37,Controls -FNF:1 -FNH:1 -FNDA:12,Controls -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:37,1 -DA:38,12 -DA:39,12 -DA:40,12 -DA:41,12 -DA:42,12 -DA:43,12 -DA:44,12 -DA:45,12 -DA:46,12 -DA:47,12 -DA:48,12 -DA:49,12 -DA:50,12 -DA:51,12 -DA:52,12 -DA:53,12 -DA:54,12 -DA:55,12 -DA:56,12 -DA:57,12 -DA:58,12 -DA:59,12 -DA:60,12 -DA:62,12 -DA:65,12 -DA:67,12 -DA:69,12 -DA:70,12 -DA:71,12 -DA:72,12 -DA:74,12 -DA:75,12 -DA:76,12 -DA:77,12 -DA:79,12 -DA:80,12 -DA:81,12 -DA:82,12 -DA:84,12 -DA:85,0 -DA:86,12 -DA:88,12 -DA:89,0 -DA:90,12 -DA:92,12 -DA:93,12 -DA:94,12 -DA:95,12 -DA:97,12 -DA:98,12 -DA:99,12 -DA:100,12 -DA:102,12 -DA:103,12 -DA:104,12 -DA:105,12 -DA:107,12 -DA:108,12 -DA:109,12 -DA:110,12 -DA:112,12 -DA:113,12 -DA:114,12 -DA:115,12 -DA:118,12 -DA:119,11 -DA:120,6 -DA:121,12 -DA:124,12 -DA:125,11 -DA:126,11 -DA:127,12 -DA:129,12 -DA:130,12 -DA:132,12 -DA:133,12 -DA:134,12 -DA:135,12 -DA:137,12 -DA:138,12 -DA:139,12 -DA:140,12 -DA:141,12 -DA:144,12 -DA:145,11 -DA:146,11 -DA:147,11 -DA:148,11 -DA:149,11 -DA:150,11 -DA:151,11 -DA:152,11 -DA:153,11 -DA:154,11 -DA:155,11 -DA:156,11 -DA:157,11 -DA:159,11 -DA:160,11 -DA:161,11 -DA:164,11 -DA:165,11 -DA:166,11 -DA:167,11 -DA:168,11 -DA:169,11 -DA:170,11 -DA:171,11 -DA:172,11 -DA:173,11 -DA:174,11 -DA:175,11 -DA:177,11 -DA:178,11 -DA:179,11 -DA:182,11 -DA:183,11 -DA:184,11 -DA:185,11 -DA:186,11 -DA:187,11 -DA:188,11 -DA:189,11 -DA:190,11 -DA:191,11 -DA:192,11 -DA:193,11 -DA:195,11 -DA:196,11 -DA:197,11 -DA:200,11 -DA:201,11 -DA:202,11 -DA:203,11 -DA:204,11 -DA:205,11 -DA:206,11 -DA:207,11 -DA:208,11 -DA:209,11 -DA:210,11 -DA:211,11 -DA:213,11 -DA:214,11 -DA:215,11 -DA:216,11 -DA:220,12 -DA:221,12 -DA:222,8 -DA:223,8 -DA:224,8 -DA:225,8 -DA:226,8 -DA:227,8 -DA:228,8 -DA:229,8 -DA:230,8 -DA:232,8 -DA:233,8 -DA:235,12 -DA:238,12 -DA:239,12 -DA:240,12 -DA:241,12 -DA:242,12 -DA:243,12 -DA:244,12 -DA:245,12 -DA:246,12 -DA:247,12 -DA:248,12 -DA:249,12 -DA:251,12 -DA:252,12 -DA:253,12 -DA:254,0 -DA:255,12 -DA:256,12 -DA:258,12 -DA:260,1 -DA:262,1 -LF:192 -LH:189 -BRDA:37,0,0,12 -BRDA:134,1,0,8 -BRDA:144,2,0,1 -BRDA:144,3,0,11 -BRDA:146,4,0,7 -BRDA:146,5,0,4 -BRDA:150,6,0,0 -BRDA:155,7,0,4 -BRDA:155,8,0,7 -BRDA:156,9,0,0 -BRDA:164,10,0,7 -BRDA:164,11,0,4 -BRDA:168,12,0,0 -BRDA:173,13,0,4 -BRDA:173,14,0,7 -BRDA:174,15,0,0 -BRDA:182,16,0,0 -BRDA:186,17,0,0 -BRDA:191,18,0,0 -BRDA:192,19,0,0 -BRDA:200,20,0,0 -BRDA:204,21,0,0 -BRDA:209,22,0,0 -BRDA:210,23,0,0 -BRDA:221,24,0,8 -BRDA:224,25,0,0 -BRDA:229,26,0,0 -BRDA:232,27,0,0 -BRDA:239,28,0,0 -BRDA:243,29,0,0 -BRDA:246,30,0,0 -BRDA:247,31,0,0 -BRDA:251,32,0,0 -BRDA:253,33,0,0 -BRDA:67,34,0,11 -BRDA:70,35,0,11 -BRDA:70,36,0,0 -BRDA:75,37,0,11 -BRDA:75,38,0,5 -BRDA:80,39,0,11 -BRDA:93,40,0,11 -BRDA:93,41,0,0 -BRDA:98,42,0,11 -BRDA:98,43,0,0 -BRDA:103,44,0,11 -BRDA:103,45,0,0 -BRDA:108,46,0,11 -BRDA:108,47,0,0 -BRDA:113,48,0,11 -BRDA:113,49,0,0 -BRDA:118,50,0,11 -BRDA:119,51,0,5 -BRDA:119,52,0,6 -BRDA:124,53,0,11 -BRDA:125,54,0,4 -BRDA:125,55,0,7 -BRDA:126,56,0,0 -BRDA:126,57,0,7 -BRF:58 -BRH:30 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-control/__tests__/timeline-control.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -LF:67 -LH:67 -BRDA:6,0,0,1 -BRDA:7,1,0,1 -BRDA:15,2,0,1 -BRDA:27,3,0,1 -BRDA:36,4,0,1 -BRDA:68,5,0,1 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-controls-wrapper/timeline-controls-wrapper.tsx -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -DA:2,0 -DA:3,0 -DA:8,0 -DA:10,0 -DA:21,0 -DA:22,0 -DA:23,0 -DA:25,0 -LF:8 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-item-title/timeline-card-title.styles.ts -FNF:0 -FNH:0 -DA:2,1 -DA:4,1 -DA:11,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:26,1 -DA:27,1 -DA:28,1 -LF:9 -LH:9 -BRDA:11,0,0,94 -BRDA:11,1,0,37 -BRDA:11,2,0,57 -BRDA:15,3,0,94 -BRDA:15,4,0,6 -BRDA:15,5,0,88 -BRDA:16,6,0,94 -BRDA:16,7,0,23 -BRDA:16,8,0,71 -BRDA:17,9,0,94 -BRDA:17,10,0,0 -BRDA:26,11,0,94 -BRDA:27,12,0,94 -BRDA:28,13,0,89 -BRDA:28,14,0,5 -BRF:15 -BRH:14 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-item-title/timeline-card-title.tsx -FN:18,TimelineItemTitle -FNF:1 -FNH:1 -FNDA:94,TimelineItemTitle -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:18,1 -DA:19,94 -DA:20,94 -DA:21,94 -DA:22,94 -DA:23,94 -DA:24,94 -DA:25,94 -DA:28,94 -DA:29,94 -DA:30,94 -DA:31,94 -DA:34,94 -DA:36,94 -DA:37,94 -DA:38,94 -DA:39,94 -DA:40,94 -DA:41,94 -DA:42,94 -DA:44,94 -DA:45,94 -DA:47,94 -DA:49,1 -LF:28 -LH:28 -BRDA:18,0,0,94 -BRDA:42,1,0,37 -BRDA:29,2,0,94 -BRDA:29,3,0,26 -BRDA:29,4,0,68 -BRF:5 -BRH:5 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-item-title/__tests__/timeline-card-title.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:7,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:22,1 -DA:23,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -LF:46 -LH:46 -BRDA:7,0,0,1 -BRDA:9,1,0,1 -BRDA:17,2,0,1 -BRDA:26,3,0,1 -BRDA:36,4,0,1 -BRDA:46,5,0,1 -BRDA:53,6,0,1 -BRF:7 -BRH:7 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-outline/animations.ts -FN:1,(empty-report) -FNF:1 -FNH:0 -FNDA:0,(empty-report) -DA:1,0 -DA:3,0 -DA:17,0 -LF:3 -LH:0 -BRDA:1,0,0,0 -BRF:1 -BRH:0 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-outline/timeline-outline-item-list.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:8,1 -DA:10,1 -DA:13,1 -DA:14,1 -DA:15,6 -DA:16,6 -DA:17,6 -DA:18,6 -DA:19,6 -DA:24,6 -DA:25,6 -DA:26,6 -DA:27,6 -DA:28,6 -DA:30,6 -DA:31,6 -DA:32,6 -DA:33,6 -DA:34,6 -DA:35,6 -DA:36,6 -DA:38,6 -DA:39,6 -DA:40,6 -DA:41,6 -DA:42,6 -DA:44,6 -DA:45,1 -DA:47,1 -DA:60,1 -DA:61,1 -DA:62,3 -DA:66,3 -DA:68,3 -DA:70,0 -DA:71,0 -DA:75,0 -DA:76,3 -DA:78,3 -DA:79,3 -DA:80,3 -DA:81,6 -DA:82,6 -DA:83,6 -DA:84,6 -DA:85,6 -DA:86,6 -DA:87,6 -DA:88,3 -DA:89,3 -DA:90,0 -DA:91,0 -DA:92,0 -DA:93,0 -DA:94,0 -DA:96,3 -DA:98,3 -DA:99,1 -DA:101,1 -LF:60 -LH:52 -BRDA:14,0,0,6 -BRDA:41,1,0,0 -BRDA:26,2,0,1 -BRDA:61,3,0,3 -BRDA:89,4,0,0 -BRDA:66,5,0,3 -BRDA:68,6,0,0 -BRDA:80,7,0,6 -BRDA:86,8,0,0 -BRF:9 -BRH:5 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-outline/timeline-outline.model.ts -FNF:0 -FNH:0 -DA:4,1 -DA:5,1 -DA:6,1 -LF:3 -LH:3 -BRDA:4,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-outline/timeline-outline.styles.ts -FN:34,__vite_ssr_import_0__.default.aside.theme.theme -FN:38,__vite_ssr_import_0__.default.aside.theme.theme -FN:41,__vite_ssr_import_0__.default.aside.theme.theme -FNF:3 -FNH:3 -FNDA:10,__vite_ssr_import_0__.default.aside.theme.theme -FNDA:10,__vite_ssr_import_0__.default.aside.theme.theme -FNDA:10,__vite_ssr_import_0__.default.aside.theme.theme -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:18,1 -DA:30,1 -DA:34,1 -DA:38,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,10 -DA:45,6 -DA:49,1 -DA:52,1 -DA:58,1 -DA:64,1 -DA:69,1 -DA:79,1 -DA:87,1 -DA:88,10 -DA:89,0 -DA:90,1 -DA:98,1 -DA:102,1 -DA:113,1 -DA:136,1 -DA:138,1 -DA:142,1 -DA:146,1 -DA:163,1 -DA:164,6 -DA:165,2 -DA:166,1 -DA:169,1 -DA:170,6 -DA:171,2 -DA:172,1 -LF:38 -LH:37 -BRDA:34,0,0,10 -BRDA:34,1,0,6 -BRDA:34,2,0,4 -BRDA:38,3,0,10 -BRDA:38,4,0,6 -BRDA:38,5,0,4 -BRDA:41,6,0,10 -BRDA:42,7,0,0 -BRDA:43,8,0,10 -BRDA:44,9,0,6 -BRDA:45,10,0,4 -BRDA:64,11,0,10 -BRDA:64,12,0,0 -BRDA:79,13,0,10 -BRDA:79,14,0,4 -BRDA:79,15,0,6 -BRDA:87,16,0,10 -BRDA:88,17,0,0 -BRDA:98,18,0,10 -BRDA:138,19,0,6 -BRDA:138,20,0,2 -BRDA:138,21,0,4 -BRDA:142,22,0,6 -BRDA:163,23,0,6 -BRDA:164,24,0,2 -BRDA:165,25,0,4 -BRDA:169,26,0,6 -BRDA:170,27,0,2 -BRDA:171,28,0,4 -BRF:29 -BRH:26 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-outline/timeline-outline.tsx -FN:24,componentDidCatch -FN:28,render -FN:45,TimelineOutline -FNF:3 -FNH:2 -FNDA:0,componentDidCatch -FNDA:10,render -FNDA:12,TimelineOutline -DA:1,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:14,1 -DA:19,1 -DA:21,1 -DA:23,1 -DA:24,1 -DA:25,0 -DA:26,0 -DA:28,1 -DA:29,10 -DA:30,10 -DA:31,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:45,1 -DA:46,12 -DA:47,12 -DA:48,12 -DA:49,12 -DA:50,12 -DA:51,12 -DA:52,12 -DA:53,12 -DA:54,12 -DA:55,12 -DA:57,12 -DA:58,12 -DA:61,12 -DA:63,12 -DA:66,12 -DA:68,9 -DA:69,9 -DA:70,3 -DA:71,9 -DA:72,6 -DA:73,0 -DA:74,6 -DA:75,6 -DA:77,9 -DA:78,9 -DA:79,9 -DA:80,12 -DA:82,12 -DA:83,12 -DA:84,1 -DA:85,1 -DA:86,12 -DA:87,12 -DA:89,12 -DA:90,1 -DA:91,1 -DA:93,12 -DA:94,1 -DA:95,1 -DA:97,10 -DA:98,10 -DA:99,10 -DA:100,10 -DA:101,10 -DA:102,10 -DA:103,10 -DA:105,10 -DA:106,10 -DA:107,10 -DA:108,10 -DA:109,10 -DA:111,12 -DA:112,12 -DA:113,12 -DA:114,12 -DA:115,3 -DA:116,3 -DA:117,3 -DA:118,3 -DA:119,3 -DA:121,12 -DA:122,12 -DA:123,12 -DA:125,12 -LF:85 -LH:82 -BRDA:28,0,0,10 -BRDA:34,1,0,1 -BRDA:35,2,0,1 -BRDA:45,3,0,12 -BRDA:58,4,0,0 -BRDA:89,5,0,1 -BRDA:91,6,0,11 -BRDA:93,7,0,1 -BRDA:95,8,0,10 -BRDA:111,9,0,6 -BRDA:111,10,0,4 -BRDA:114,11,0,3 -BRDA:63,12,0,3 -BRDA:63,13,0,3 -BRDA:66,14,0,9 -BRDA:69,15,0,3 -BRDA:71,16,0,6 -BRDA:77,17,0,9 -BRDA:78,18,0,6 -BRDA:83,19,0,1 -BRF:20 -BRH:19 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-outline/__tests__/timeline-outline.test.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:5,1 -DA:9,1 -DA:10,0 -DA:11,0 -DA:12,0 -DA:13,0 -DA:14,0 -DA:15,0 -DA:16,1 -DA:18,1 -DA:19,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:26,1 -DA:27,6 -DA:28,6 -DA:29,6 -DA:30,6 -DA:31,6 -DA:32,6 -DA:33,6 -DA:34,1 -DA:36,1 -DA:37,6 -DA:38,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:65,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:83,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -LF:113 -LH:107 -BRDA:21,0,0,1 -BRDA:26,1,0,6 -BRDA:36,2,0,6 -BRDA:41,3,0,1 -BRDA:55,4,0,1 -BRDA:67,5,0,1 -BRDA:73,6,0,1 -BRDA:85,7,0,1 -BRDA:90,8,0,1 -BRDA:96,9,0,1 -BRDA:108,10,0,1 -BRDA:113,11,0,1 -BRDA:126,12,0,1 -BRF:13 -BRH:13 -end_of_record -TN: -SF:src/components/timeline-elements/timeline-outline/hooks/useOutlinePosition.ts -FN:11,useOutlinePosition -FNF:1 -FNH:1 -FNDA:12,useOutlinePosition -DA:1,1 -DA:3,1 -DA:11,1 -DA:12,12 -DA:13,12 -DA:14,6 -DA:15,6 -DA:16,0 -DA:17,12 -DA:18,12 -DA:19,12 -LF:11 -LH:10 -BRDA:11,0,0,12 -BRDA:13,1,0,6 -BRDA:14,2,0,0 -BRDA:15,3,0,0 -BRF:4 -BRH:2 -end_of_record -TN: -SF:src/components/timeline-horizontal/timeline-horizontal.styles.ts -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -DA:8,1 -DA:18,1 -DA:19,1 -LF:5 -LH:5 -BRDA:8,0,0,23 -BRDA:8,1,0,1 -BRDA:8,2,0,22 -BRDA:19,3,0,61 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/components/timeline-horizontal/timeline-horizontal.tsx -FN:27,TimelineHorizontal -FNF:1 -FNH:1 -FNDA:23,TimelineHorizontal -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:27,1 -DA:28,23 -DA:29,23 -DA:30,23 -DA:31,23 -DA:32,23 -DA:33,23 -DA:34,23 -DA:35,23 -DA:36,23 -DA:37,23 -DA:38,23 -DA:39,23 -DA:40,23 -DA:41,23 -DA:42,23 -DA:43,23 -DA:44,23 -DA:45,23 -DA:46,23 -DA:47,23 -DA:48,23 -DA:51,23 -DA:52,23 -DA:53,21 -DA:54,21 -DA:55,21 -DA:56,21 -DA:57,21 -DA:58,23 -DA:59,23 -DA:61,23 -DA:62,23 -DA:63,23 -DA:64,23 -DA:67,23 -DA:68,21 -DA:69,61 -DA:70,61 -DA:71,61 -DA:72,61 -DA:73,61 -DA:74,61 -DA:75,61 -DA:76,61 -DA:77,61 -DA:79,61 -DA:80,61 -DA:81,61 -DA:82,61 -DA:83,61 -DA:84,61 -DA:85,61 -DA:86,61 -DA:87,61 -DA:88,61 -DA:89,61 -DA:90,61 -DA:91,61 -DA:92,61 -DA:93,61 -DA:94,61 -DA:95,61 -DA:96,61 -DA:97,21 -DA:98,23 -DA:99,23 -DA:100,23 -DA:101,23 -DA:102,23 -DA:103,23 -DA:104,23 -DA:105,23 -DA:106,23 -DA:107,23 -DA:108,23 -DA:109,23 -DA:110,23 -DA:111,23 -DA:112,23 -DA:113,23 -DA:114,23 -DA:116,23 -DA:117,23 -DA:118,23 -DA:119,23 -DA:120,23 -DA:121,23 -DA:122,23 -DA:124,23 -DA:125,23 -DA:127,23 -DA:129,1 -LF:98 -LH:98 -BRDA:27,0,0,23 -BRDA:52,1,0,21 -BRDA:56,2,0,1 -BRDA:56,3,0,20 -BRDA:62,4,0,21 -BRDA:67,5,0,21 -BRDA:68,6,0,61 -BRDA:73,7,0,38 -BRDA:73,8,0,23 -BRDA:77,9,0,19 -BRDA:77,10,0,42 -BRDA:88,11,0,3 -BRDA:88,12,0,58 -BRF:13 -BRH:13 -end_of_record -TN: -SF:src/components/timeline-horizontal/__tests__/timeline-horizontal.test.tsx -FN:71,renderWithContext -FNF:1 -FNH:1 -FNDA:20,renderWithContext -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,20 -DA:73,20 -DA:74,20 -DA:75,20 -DA:76,20 -DA:77,20 -DA:78,20 -DA:79,20 -DA:80,20 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:88,1 -DA:89,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:129,1 -DA:130,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:137,1 -DA:138,1 -DA:140,1 -DA:141,0 -DA:142,0 -DA:143,1 -DA:145,1 -DA:146,1 -DA:147,1 -DA:150,1 -DA:151,1 -DA:152,1 -DA:153,0 -DA:154,0 -DA:155,1 -DA:157,1 -DA:158,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:162,1 -DA:163,1 -DA:164,1 -DA:167,1 -DA:168,2 -DA:169,1 -DA:170,1 -DA:172,1 -DA:173,1 -DA:174,1 -DA:175,1 -DA:176,1 -DA:177,1 -DA:178,1 -DA:179,1 -DA:181,1 -DA:182,1 -DA:183,1 -DA:184,1 -DA:185,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:190,1 -DA:191,1 -DA:192,1 -DA:193,1 -DA:194,1 -DA:195,1 -DA:197,1 -DA:198,1 -DA:199,1 -DA:200,1 -DA:202,1 -DA:203,1 -DA:204,1 -DA:205,1 -DA:206,1 -DA:207,1 -DA:209,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:214,1 -DA:215,1 -DA:216,1 -DA:217,1 -DA:218,1 -DA:220,1 -DA:221,1 -DA:222,1 -DA:223,1 -DA:224,1 -DA:226,1 -DA:227,1 -DA:228,1 -DA:229,1 -DA:230,1 -DA:231,1 -DA:233,1 -DA:234,1 -DA:235,1 -DA:236,1 -DA:237,1 -DA:238,1 -DA:239,1 -DA:241,1 -DA:242,1 -DA:243,1 -DA:244,1 -DA:245,1 -DA:246,1 -DA:247,1 -DA:248,1 -DA:249,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:254,1 -DA:257,1 -DA:258,1 -DA:259,1 -DA:260,1 -DA:261,1 -DA:263,1 -DA:264,1 -DA:266,1 -DA:267,1 -DA:268,1 -DA:271,1 -DA:272,1 -DA:273,1 -DA:274,1 -DA:275,1 -DA:277,1 -DA:278,1 -DA:279,1 -DA:280,1 -LF:236 -LH:232 -BRDA:71,0,0,20 -BRDA:82,1,0,1 -BRDA:83,2,0,1 -BRDA:88,3,0,1 -BRDA:96,4,0,1 -BRDA:103,5,0,1 -BRDA:113,6,0,1 -BRDA:123,7,0,1 -BRDA:132,8,0,1 -BRDA:140,9,0,0 -BRDA:145,10,0,1 -BRDA:152,11,0,0 -BRDA:157,12,0,1 -BRDA:167,13,0,2 -BRDA:172,14,0,1 -BRDA:181,15,0,1 -BRDA:190,16,0,1 -BRDA:202,17,0,1 -BRDA:214,18,0,1 -BRDA:220,19,0,1 -BRDA:226,20,0,1 -BRDA:233,21,0,1 -BRDA:241,22,0,1 -BRDA:251,23,0,1 -BRDA:266,24,0,1 -BRF:25 -BRH:23 -end_of_record -TN: -SF:src/components/timeline-vertical/timeline-point.tsx -FN:118,onClick -FNF:1 -FNH:0 -FNDA:0,onClick -DA:2,1 -DA:3,1 -DA:11,1 -DA:13,1 -DA:14,1 -DA:28,1 -DA:29,1 -DA:30,23 -DA:31,23 -DA:32,23 -DA:33,23 -DA:34,23 -DA:35,23 -DA:36,23 -DA:37,23 -DA:38,23 -DA:39,23 -DA:40,23 -DA:41,23 -DA:42,23 -DA:43,23 -DA:46,23 -DA:49,23 -DA:50,23 -DA:51,23 -DA:52,23 -DA:53,23 -DA:54,23 -DA:55,23 -DA:56,23 -DA:58,23 -DA:59,23 -DA:60,23 -DA:63,23 -DA:69,23 -DA:71,23 -DA:72,0 -DA:73,0 -DA:75,23 -DA:76,23 -DA:77,23 -DA:78,23 -DA:84,23 -DA:85,23 -DA:87,0 -DA:88,0 -DA:91,23 -DA:97,23 -DA:98,23 -DA:99,23 -DA:100,23 -DA:101,23 -DA:102,23 -DA:103,23 -DA:104,23 -DA:110,23 -DA:112,23 -DA:113,0 -DA:114,0 -DA:117,23 -DA:118,23 -DA:119,0 -DA:121,0 -DA:122,0 -DA:123,0 -DA:124,0 -DA:125,23 -DA:126,23 -DA:131,23 -DA:133,23 -DA:134,23 -DA:135,23 -DA:136,23 -DA:139,23 -DA:140,23 -DA:141,23 -DA:142,0 -DA:144,23 -DA:147,23 -DA:148,23 -DA:150,23 -DA:151,23 -DA:152,23 -DA:153,23 -DA:155,23 -DA:156,23 -DA:159,23 -DA:161,23 -DA:163,23 -DA:164,23 -DA:165,23 -DA:166,23 -DA:167,23 -DA:168,23 -DA:169,23 -DA:170,23 -DA:173,23 -DA:175,23 -DA:176,23 -DA:177,23 -DA:179,23 -DA:180,23 -DA:182,23 -DA:183,23 -DA:184,23 -DA:185,23 -DA:187,23 -DA:192,1 -DA:195,1 -LF:109 -LH:97 -BRDA:29,0,0,23 -BRDA:168,1,0,22 -BRDA:170,2,0,0 -BRDA:69,3,0,23 -BRDA:71,4,0,0 -BRDA:76,5,0,0 -BRDA:84,6,0,23 -BRDA:85,7,0,0 -BRDA:85,8,0,0 -BRDA:85,9,0,0 -BRDA:98,10,0,23 -BRDA:110,11,0,23 -BRDA:112,12,0,0 -BRDA:131,13,0,23 -BRDA:139,14,0,23 -BRDA:141,15,0,0 -BRF:16 -BRH:8 -end_of_record -TN: -SF:src/components/timeline-vertical/timeline-vertical-item.tsx -FN:29,VerticalItem -FNF:1 -FNH:1 -FNDA:26,VerticalItem -DA:2,1 -DA:3,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:29,1 -DA:30,26 -DA:31,26 -DA:33,26 -DA:36,26 -DA:37,26 -DA:38,26 -DA:39,26 -DA:40,26 -DA:41,26 -DA:42,26 -DA:43,26 -DA:44,26 -DA:45,26 -DA:46,26 -DA:47,26 -DA:48,26 -DA:49,26 -DA:50,26 -DA:51,26 -DA:52,26 -DA:53,26 -DA:54,26 -DA:55,26 -DA:56,26 -DA:57,26 -DA:58,26 -DA:59,26 -DA:62,26 -DA:63,26 -DA:64,26 -DA:65,26 -DA:66,26 -DA:67,26 -DA:68,26 -DA:69,26 -DA:70,26 -DA:71,26 -DA:72,26 -DA:73,26 -DA:74,26 -DA:75,26 -DA:76,26 -DA:83,26 -DA:84,26 -DA:85,0 -DA:86,0 -DA:88,0 -DA:89,0 -DA:90,0 -DA:91,26 -DA:92,26 -DA:99,26 -DA:101,0 -DA:102,0 -DA:103,0 -DA:104,26 -DA:110,26 -DA:111,22 -DA:112,22 -DA:113,22 -DA:114,22 -DA:115,22 -DA:116,22 -DA:118,22 -DA:120,22 -DA:121,22 -DA:122,22 -DA:123,22 -DA:125,22 -DA:126,22 -DA:127,22 -DA:128,22 -DA:130,26 -DA:131,26 -DA:132,26 -DA:133,26 -DA:134,26 -DA:135,26 -DA:136,26 -DA:137,26 -DA:138,26 -DA:139,26 -DA:140,26 -DA:146,26 -DA:147,26 -DA:148,22 -DA:149,22 -DA:150,22 -DA:151,22 -DA:152,22 -DA:153,26 -DA:154,26 -DA:159,26 -DA:160,26 -DA:161,22 -DA:162,22 -DA:163,22 -DA:164,22 -DA:165,22 -DA:166,26 -DA:167,26 -DA:173,26 -DA:174,26 -DA:175,22 -DA:176,22 -DA:177,22 -DA:178,22 -DA:179,22 -DA:180,22 -DA:181,22 -DA:182,22 -DA:183,22 -DA:184,22 -DA:185,22 -DA:186,22 -DA:187,22 -DA:188,22 -DA:189,22 -DA:190,22 -DA:192,26 -DA:194,26 -DA:195,26 -DA:196,26 -DA:197,26 -DA:198,26 -DA:199,26 -DA:200,26 -DA:201,26 -DA:202,26 -DA:203,26 -DA:204,26 -DA:205,26 -DA:206,26 -DA:207,26 -DA:208,26 -DA:209,26 -DA:215,26 -DA:217,22 -DA:218,26 -DA:221,26 -DA:222,22 -DA:223,22 -DA:224,22 -DA:225,0 -DA:226,0 -DA:227,0 -DA:228,0 -DA:229,26 -DA:232,26 -DA:233,26 -DA:234,26 -DA:235,26 -DA:236,26 -DA:237,26 -DA:238,26 -DA:239,26 -DA:240,26 -DA:241,26 -DA:242,26 -DA:243,26 -DA:244,26 -DA:245,26 -DA:246,26 -DA:249,26 -DA:252,26 -DA:254,26 -DA:255,26 -DA:257,26 -DA:259,26 -DA:260,26 -DA:262,26 -DA:265,26 -DA:266,26 -DA:267,26 -DA:268,26 -DA:269,26 -DA:270,26 -DA:271,26 -DA:272,26 -DA:273,26 -DA:274,26 -DA:275,26 -DA:276,26 -DA:277,26 -DA:278,26 -DA:279,26 -DA:280,26 -DA:282,26 -DA:283,26 -DA:284,26 -DA:285,26 -DA:286,26 -DA:287,26 -DA:288,26 -DA:289,26 -DA:290,0 -DA:291,26 -DA:294,26 -DA:295,26 -DA:297,26 -DA:300,1 -DA:302,1 -LF:210 -LH:197 -BRDA:29,0,0,26 -BRDA:236,1,0,0 -BRDA:245,2,0,0 -BRDA:249,3,0,0 -BRDA:257,4,0,10 -BRDA:259,5,0,0 -BRDA:282,6,0,10 -BRDA:289,7,0,0 -BRDA:294,8,0,0 -BRDA:110,9,0,22 -BRDA:118,10,0,10 -BRDA:122,11,0,0 -BRDA:125,12,0,0 -BRDA:125,13,0,0 -BRDA:147,14,0,22 -BRDA:160,15,0,22 -BRDA:174,16,0,22 -BRDA:215,17,0,22 -BRDA:221,18,0,22 -BRDA:224,19,0,0 -BRF:20 -BRH:10 -end_of_record -TN: -SF:src/components/timeline-vertical/timeline-vertical-shape.styles.ts -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:25,1 -DA:33,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:59,1 -DA:60,1 -DA:66,1 -DA:67,1 -DA:85,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:110,1 -LF:16 -LH:16 -BRDA:33,0,0,23 -BRDA:33,1,0,0 -BRDA:45,2,0,23 -BRDA:46,3,0,0 -BRDA:47,4,0,23 -BRDA:47,5,0,1 -BRDA:47,6,0,22 -BRDA:59,7,0,23 -BRDA:60,8,0,0 -BRDA:66,9,0,23 -BRDA:66,10,0,1 -BRDA:66,11,0,22 -BRDA:88,12,0,23 -BRDA:89,13,0,0 -BRDA:110,14,0,23 -BRF:15 -BRH:11 -end_of_record -TN: -SF:src/components/timeline-vertical/timeline-vertical.styles.ts -FNF:0 -FNH:0 -DA:3,1 -DA:4,1 -DA:9,1 -DA:21,1 -DA:52,1 -DA:59,1 -DA:78,1 -DA:79,26 -DA:80,0 -DA:89,0 -DA:94,1 -DA:119,1 -DA:126,1 -DA:128,26 -DA:129,16 -DA:130,16 -DA:132,10 -DA:133,0 -DA:134,0 -DA:136,10 -DA:137,10 -DA:138,10 -DA:139,26 -DA:142,1 -DA:143,26 -DA:144,26 -DA:153,1 -DA:156,1 -DA:157,26 -DA:158,0 -DA:166,1 -DA:171,1 -DA:193,1 -DA:195,1 -DA:196,22 -DA:197,0 -DA:198,1 -DA:201,1 -DA:202,22 -DA:203,12 -DA:204,1 -DA:213,1 -DA:215,1 -DA:220,1 -DA:222,1 -LF:45 -LH:39 -BRDA:78,0,0,26 -BRDA:79,1,0,0 -BRDA:126,2,0,26 -BRDA:128,3,0,16 -BRDA:129,4,0,0 -BRDA:130,5,0,10 -BRDA:132,6,0,0 -BRDA:137,7,0,0 -BRDA:142,8,0,26 -BRDA:156,9,0,26 -BRDA:157,10,0,0 -BRDA:195,11,0,22 -BRDA:196,12,0,0 -BRDA:196,13,0,0 -BRDA:201,14,0,22 -BRDA:202,15,0,12 -BRDA:203,16,0,10 -BRDA:213,17,0,22 -BRDA:213,18,0,0 -BRDA:215,19,0,22 -BRDA:215,20,0,0 -BRDA:215,21,0,0 -BRDA:220,22,0,22 -BRDA:220,23,0,0 -BRDA:222,24,0,22 -BRDA:222,25,0,0 -BRDA:222,26,0,0 -BRF:27 -BRH:14 -end_of_record -TN: -SF:src/components/timeline-vertical/timeline-vertical.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:23,1 -DA:24,1 -DA:26,6 -DA:28,6 -DA:29,6 -DA:30,6 -DA:31,6 -DA:32,6 -DA:33,6 -DA:34,6 -DA:35,6 -DA:36,6 -DA:37,6 -DA:38,6 -DA:39,6 -DA:40,6 -DA:41,6 -DA:43,6 -DA:53,6 -DA:54,6 -DA:56,0 -DA:57,0 -DA:58,0 -DA:59,0 -DA:60,0 -DA:61,0 -DA:62,6 -DA:63,6 -DA:66,6 -DA:67,6 -DA:68,24 -DA:72,24 -DA:73,16 -DA:74,16 -DA:76,8 -DA:77,8 -DA:78,8 -DA:81,24 -DA:82,24 -DA:83,0 -DA:84,0 -DA:85,24 -DA:88,24 -DA:89,24 -DA:91,0 -DA:92,24 -DA:94,0 -DA:95,0 -DA:98,24 -DA:99,24 -DA:100,24 -DA:102,24 -DA:103,24 -DA:104,24 -DA:105,24 -DA:106,24 -DA:107,24 -DA:108,24 -DA:109,24 -DA:110,24 -DA:111,24 -DA:113,24 -DA:114,24 -DA:115,24 -DA:116,24 -DA:118,6 -DA:119,6 -DA:120,6 -DA:121,6 -DA:122,6 -DA:123,6 -DA:124,6 -DA:125,6 -DA:126,6 -DA:127,6 -DA:128,6 -DA:129,6 -DA:130,6 -DA:131,6 -DA:132,6 -DA:135,6 -DA:136,6 -DA:137,6 -DA:138,6 -DA:140,6 -DA:141,1 -DA:144,1 -DA:146,1 -LF:92 -LH:81 -BRDA:24,0,0,6 -BRDA:66,1,0,6 -BRDA:67,2,0,24 -BRDA:72,3,0,16 -BRDA:72,4,0,16 -BRDA:73,5,0,8 -BRDA:73,6,0,8 -BRDA:74,7,0,8 -BRDA:82,8,0,0 -BRDA:83,9,0,0 -BRDA:89,10,0,0 -BRDA:92,11,0,0 -BRDA:108,12,0,0 -BRF:13 -BRH:8 -end_of_record -TN: -SF:src/components/timeline-vertical/__tests__/timeline-point.test.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:22,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:32,1 -LF:26 -LH:26 -BRDA:22,0,0,1 -BRDA:25,1,0,1 -BRF:2 -BRH:2 -end_of_record -TN: -SF:src/components/timeline-vertical/__tests__/timeline-vertical-item.test.tsx -FN:29,onActive -FN:30,onClick -FN:31,onElapsed -FNF:3 -FNH:0 -FNDA:0,onActive -FNDA:0,onClick -FNDA:0,onElapsed -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:9,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:46,1 -DA:47,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -LF:48 -LH:48 -BRDA:39,0,0,1 -BRDA:40,1,0,1 -BRDA:51,2,0,1 -BRF:3 -BRH:3 -end_of_record -TN: -SF:src/components/timeline/__tests__/layout-switcher.test.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:31,1 -DA:33,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:57,1 -DA:59,1 -DA:63,1 -DA:162,1 -LF:51 -LH:51 -BRDA:7,0,0,1 -BRDA:13,1,0,1 -BRDA:39,2,0,1 -BRF:3 -BRH:3 -end_of_record -TN: -SF:src/components/timeline/__tests__/timeline.test.tsx -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:8,1 -DA:9,0 -DA:10,0 -DA:11,0 -DA:12,0 -DA:13,0 -DA:14,0 -DA:15,0 -DA:16,0 -DA:17,0 -DA:18,0 -DA:19,0 -DA:21,1 -DA:22,5 -DA:23,5 -DA:24,5 -DA:25,5 -DA:27,5 -DA:28,5 -DA:29,5 -DA:30,5 -DA:31,5 -DA:32,5 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:95,1 -DA:96,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:111,1 -DA:112,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:148,1 -DA:149,1 -DA:150,1 -DA:151,1 -DA:152,1 -DA:153,1 -DA:154,1 -DA:156,1 -DA:157,1 -DA:159,1 -DA:160,1 -DA:162,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:167,1 -DA:170,1 -DA:171,1 -DA:172,1 -DA:173,1 -DA:174,1 -DA:175,1 -DA:176,1 -DA:178,1 -DA:179,1 -DA:181,1 -DA:183,1 -DA:184,3 -DA:185,1 -DA:186,1 -DA:211,1 -DA:212,1 -DA:213,1 -DA:214,1 -DA:215,1 -DA:216,1 -DA:217,1 -DA:218,1 -DA:219,1 -DA:220,1 -DA:221,1 -DA:223,1 -DA:225,1 -DA:227,1 -DA:229,1 -DA:230,1 -DA:232,1 -DA:233,1 -DA:234,1 -DA:235,1 -DA:236,1 -DA:237,1 -DA:238,1 -DA:240,1 -DA:242,1 -DA:244,1 -DA:245,1 -DA:246,1 -DA:247,1 -DA:248,1 -DA:249,1 -DA:250,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:254,1 -LF:170 -LH:159 -BRDA:21,0,0,5 -BRDA:34,1,0,1 -BRDA:87,2,0,1 -BRDA:103,3,0,1 -BRDA:148,4,0,1 -BRDA:164,5,0,1 -BRDA:170,6,0,1 -BRDA:183,7,0,3 -BRDA:211,8,0,1 -BRDA:232,9,0,1 -BRDA:244,10,0,1 -BRF:11 -BRH:11 -end_of_record -TN: -SF:src/components/toggle-button/index.tsx -FN:1,(empty-report) -FNF:1 -FNH:0 -FNDA:0,(empty-report) -DA:1,0 -DA:2,0 -DA:3,0 -DA:12,0 -DA:13,0 -DA:14,0 -DA:16,0 -DA:17,0 -DA:18,0 -DA:19,0 -DA:21,0 -DA:22,0 -DA:23,0 -DA:24,0 -DA:26,0 -DA:27,0 -DA:29,0 -LF:17 -LH:0 -BRDA:1,0,0,0 -BRF:1 -BRH:0 -end_of_record -TN: -SF:src/components/toggle-button/toggle-button.styles.ts -FN:1,(empty-report) -FNF:1 -FNH:0 -FNDA:0,(empty-report) -DA:1,0 -DA:3,0 -DA:5,0 -LF:3 -LH:0 -BRDA:1,0,0,0 -BRF:1 -BRH:0 -end_of_record -TN: -SF:src/components/toolbar/index.tsx -FNF:0 -FNH:0 -DA:1,1 -DA:3,1 -DA:29,1 -DA:30,1 -DA:31,9 -DA:32,0 -DA:33,0 -DA:35,9 -DA:36,9 -DA:37,9 -DA:38,31 -DA:39,0 -DA:40,0 -DA:41,0 -DA:43,31 -DA:44,31 -DA:45,31 -DA:46,31 -DA:47,31 -DA:50,31 -DA:51,31 -DA:52,23 -DA:54,31 -DA:56,9 -DA:57,9 -DA:59,9 -DA:60,1 -DA:62,1 -LF:28 -LH:23 -BRDA:30,0,0,9 -BRDA:31,1,0,0 -BRDA:37,2,0,31 -BRDA:38,3,0,0 -BRDA:50,4,0,1 -BRDA:51,5,0,23 -BRF:6 -BRH:4 -end_of_record -TN: -SF:src/components/toolbar/toolbar.styles.ts -FN:16,__vite_ssr_import_0__.default.div.theme.theme -FN:19,__vite_ssr_import_0__.default.div.theme.theme -FNF:2 -FNH:2 -FNDA:9,__vite_ssr_import_0__.default.div.theme.theme -FNDA:9,__vite_ssr_import_0__.default.div.theme.theme -DA:2,1 -DA:5,1 -DA:11,1 -DA:12,1 -DA:16,1 -DA:19,1 -DA:26,1 -DA:27,1 -DA:31,1 -DA:37,1 -DA:38,1 -DA:45,1 -DA:46,1 -LF:13 -LH:13 -BRDA:16,0,0,9 -BRDA:19,1,0,9 -BRDA:19,2,0,7 -BRDA:26,3,0,9 -BRDA:27,4,0,2 -BRDA:27,5,0,7 -BRF:6 -BRH:6 -end_of_record -TN: -SF:src/components/toolbar/__tests__/toolbar.test.tsx -FN:10,onSelect -FN:11,onSelect -FN:39,onSelect -FNF:3 -FNH:0 -FNDA:0,onSelect -FNDA:0,onSelect -FNDA:0,onSelect -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:14,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,2 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:50,1 -DA:51,1 -DA:52,1 -LF:41 -LH:41 -BRDA:16,0,0,1 -BRDA:17,1,0,1 -BRDA:21,2,0,2 -BRDA:34,3,0,1 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/hooks/index.ts -FN:1,(empty-report) -FNF:1 -FNH:1 -FNDA:1,(empty-report) -DA:7,0 -DA:8,0 -DA:9,0 -DA:10,0 -DA:11,0 -LF:5 -LH:0 -BRDA:1,0,0,1 -BRF:1 -BRH:1 -end_of_record -TN: -SF:src/hooks/useBackground.ts -FN:7,isValidHexColor -FN:9,useBackground -FNF:2 -FNH:2 -FNDA:12,isValidHexColor -FNDA:16,useBackground -DA:1,1 -DA:2,1 -DA:5,1 -DA:7,1 -DA:9,1 -DA:10,16 -DA:11,16 -DA:12,13 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,11 -DA:19,16 -DA:20,16 -LF:16 -LH:16 -BRDA:7,0,0,12 -BRDA:9,1,0,16 -BRDA:10,2,0,16 -BRDA:11,3,0,4 -BRDA:11,4,0,13 -BRDA:11,5,0,12 -BRDA:12,6,0,1 -BRDA:17,7,0,11 -BRF:8 -BRH:8 -end_of_record -TN: -SF:src/hooks/useCardSize.ts -FN:23,calculateTextContentSize -FN:38,useCardSize -FNF:2 -FNH:2 -FNDA:45,calculateTextContentSize -FNDA:59,useCardSize -DA:1,1 -DA:23,1 -DA:24,45 -DA:25,45 -DA:26,45 -DA:27,45 -DA:28,45 -DA:29,45 -DA:31,45 -DA:32,45 -DA:33,45 -DA:34,41 -DA:36,45 -DA:38,1 -DA:39,59 -DA:40,59 -DA:41,59 -DA:42,59 -DA:43,59 -DA:44,59 -DA:45,59 -DA:46,59 -DA:47,59 -DA:50,59 -DA:55,59 -DA:58,59 -DA:59,41 -DA:61,41 -DA:63,0 -DA:65,0 -DA:66,0 -DA:67,0 -DA:68,0 -DA:69,0 -DA:70,0 -DA:71,0 -DA:72,0 -DA:73,0 -DA:74,0 -DA:75,41 -DA:77,41 -DA:78,38 -DA:79,38 -DA:81,41 -DA:82,41 -DA:83,41 -DA:84,41 -DA:85,59 -DA:87,59 -DA:88,59 -DA:89,5 -DA:91,4 -DA:92,4 -DA:93,4 -DA:96,4 -DA:97,4 -DA:98,4 -DA:99,4 -DA:100,4 -DA:101,4 -DA:103,4 -DA:104,4 -DA:105,4 -DA:106,4 -DA:107,4 -DA:108,4 -DA:109,4 -DA:110,5 -DA:111,59 -DA:112,59 -DA:115,59 -DA:116,59 -DA:117,45 -DA:118,45 -DA:119,45 -DA:120,45 -DA:121,45 -DA:122,45 -DA:123,45 -DA:124,45 -DA:125,45 -DA:126,45 -DA:127,45 -DA:128,45 -DA:129,45 -DA:130,59 -DA:131,59 -DA:133,59 -DA:134,59 -DA:135,59 -DA:136,59 -DA:137,59 -DA:138,59 -DA:139,59 -LF:94 -LH:83 -BRDA:23,0,0,45 -BRDA:33,1,0,41 -BRDA:38,2,0,59 -BRDA:58,3,0,41 -BRDA:77,4,0,38 -BRDA:81,5,0,41 -BRDA:82,6,0,0 -BRDA:88,7,0,5 -BRDA:89,8,0,4 -BRDA:89,9,0,1 -BRDA:89,10,0,4 -BRDA:116,11,0,45 -BRF:12 -BRH:11 -end_of_record -TN: -SF:src/hooks/useEscapeKey.ts -FN:14,useEscapeKey -FNF:1 -FNH:1 -FNDA:44,useEscapeKey -DA:1,1 -DA:14,44 -DA:15,44 -DA:16,44 -DA:17,44 -DA:18,44 -DA:19,44 -DA:20,44 -DA:21,44 -DA:22,44 -DA:23,44 -DA:25,44 -DA:26,44 -DA:29,44 -DA:30,21 -DA:31,44 -DA:33,44 -DA:34,44 -DA:36,7 -DA:39,7 -DA:40,6 -DA:41,6 -DA:42,6 -DA:43,7 -DA:44,44 -DA:45,44 -DA:47,44 -DA:48,20 -DA:50,20 -DA:53,20 -DA:54,20 -DA:56,20 -DA:57,19 -DA:58,19 -DA:59,44 -DA:60,44 -LF:36 -LH:36 -BRDA:14,0,0,44 -BRDA:29,1,0,21 -BRDA:34,2,0,7 -BRDA:36,3,0,0 -BRDA:39,4,0,2 -BRDA:39,5,0,1 -BRDA:39,6,0,6 -BRDA:47,7,0,20 -BRDA:50,8,0,1 -BRDA:50,9,0,19 -BRDA:53,10,0,18 -BRDA:53,11,0,1 -BRDA:56,12,0,19 -BRF:13 -BRH:12 -end_of_record -TN: -SF:src/hooks/useMeasureHeight.ts -FN:8,useMeasureHeight -FNF:1 -FNH:1 -FNDA:11,useMeasureHeight -DA:1,1 -DA:8,1 -DA:9,11 -DA:10,11 -DA:11,6 -DA:12,3 -DA:13,3 -DA:14,6 -DA:15,11 -DA:16,11 -DA:17,11 -LF:11 -LH:11 -BRDA:8,0,0,11 -BRDA:10,1,0,6 -BRDA:11,2,0,3 -BRDA:11,3,0,3 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/hooks/useMediaState.ts -FN:17,useMediaState -FNF:1 -FNH:1 -FNDA:14,useMediaState -DA:1,1 -DA:17,1 -DA:18,14 -DA:19,14 -DA:20,14 -DA:21,14 -DA:22,14 -DA:23,14 -DA:24,14 -DA:27,14 -DA:28,9 -DA:29,14 -DA:31,14 -DA:32,14 -DA:34,9 -DA:35,1 -DA:36,1 -DA:37,1 -DA:40,9 -DA:41,9 -DA:42,4 -DA:43,4 -DA:46,9 -DA:47,1 -DA:48,1 -DA:49,9 -DA:50,14 -DA:51,14 -DA:53,14 -DA:54,10 -DA:55,14 -DA:58,14 -DA:60,14 -DA:61,14 -DA:62,14 -DA:63,14 -DA:64,14 -DA:65,14 -LF:38 -LH:38 -BRDA:17,0,0,14 -BRDA:27,1,0,9 -BRDA:32,2,0,9 -BRDA:34,3,0,1 -BRDA:35,4,0,0 -BRDA:37,5,0,8 -BRDA:40,6,0,4 -BRDA:41,7,0,4 -BRDA:43,8,0,8 -BRDA:46,9,0,4 -BRDA:46,10,0,1 -BRDA:46,11,0,1 -BRDA:46,12,0,1 -BRDA:53,13,0,10 -BRDA:58,14,0,9 -BRF:15 -BRH:14 -end_of_record -TN: -SF:src/hooks/useOutsideClick.ts -FN:12,useOutsideClick -FNF:1 -FNH:1 -FNDA:47,useOutsideClick -DA:1,1 -DA:12,47 -DA:13,47 -DA:14,47 -DA:15,47 -DA:16,47 -DA:17,47 -DA:18,47 -DA:19,47 -DA:22,47 -DA:23,22 -DA:24,47 -DA:26,47 -DA:27,47 -DA:29,14 -DA:31,14 -DA:32,14 -DA:33,7 -DA:34,7 -DA:35,7 -DA:36,14 -DA:37,47 -DA:38,47 -DA:40,47 -DA:41,23 -DA:43,23 -DA:46,23 -DA:47,23 -DA:49,23 -DA:50,21 -DA:51,21 -DA:52,47 -DA:53,47 -LF:33 -LH:33 -BRDA:12,0,0,47 -BRDA:22,1,0,22 -BRDA:27,2,0,14 -BRDA:29,3,0,0 -BRDA:32,4,0,13 -BRDA:32,5,0,7 -BRDA:40,6,0,23 -BRDA:43,7,0,2 -BRDA:43,8,0,21 -BRDA:46,9,0,1 -BRDA:46,10,0,20 -BRDA:49,11,0,21 -BRF:12 -BRH:11 -end_of_record -TN: -SF:src/hooks/useSlideshowProgress.ts -FN:27,useSlideshowProgress -FNF:1 -FNH:1 -FNDA:8,useSlideshowProgress -DA:1,1 -DA:27,1 -DA:28,8 -DA:29,8 -DA:30,8 -DA:31,8 -DA:32,8 -DA:33,8 -DA:34,8 -DA:35,8 -DA:38,8 -DA:39,12 -DA:40,0 -DA:41,0 -DA:42,0 -DA:43,8 -DA:46,8 -DA:47,6 -DA:48,6 -DA:49,6 -DA:50,6 -DA:51,8 -DA:54,8 -DA:55,6 -DA:56,0 -DA:57,0 -DA:58,0 -DA:59,8 -DA:62,8 -DA:63,0 -DA:64,0 -DA:65,0 -DA:66,8 -DA:69,8 -DA:70,0 -DA:71,0 -DA:72,0 -DA:73,8 -DA:76,8 -DA:78,8 -DA:79,8 -DA:80,8 -DA:81,8 -DA:82,8 -DA:83,8 -LF:45 -LH:33 -BRDA:27,0,0,8 -BRDA:38,1,0,12 -BRDA:39,2,0,0 -BRDA:46,3,0,6 -BRDA:54,4,0,6 -BRDA:55,5,0,0 -BRDA:55,6,0,0 -BRDA:76,7,0,6 -BRF:8 -BRH:5 -end_of_record -TN: -SF:src/hooks/useTimelineMedia.ts -FN:12,useTimelineMedia -FN:59,scheduleObservation -FNF:2 -FNH:2 -FNDA:12,useTimelineMedia -FNDA:8,scheduleObservation -DA:1,1 -DA:2,1 -DA:12,1 -DA:13,12 -DA:14,12 -DA:15,12 -DA:16,12 -DA:17,12 -DA:20,12 -DA:22,2 -DA:23,2 -DA:24,4 -DA:25,4 -DA:26,2 -DA:27,2 -DA:28,2 -DA:29,2 -DA:30,2 -DA:31,2 -DA:32,2 -DA:33,12 -DA:36,12 -DA:37,8 -DA:38,0 -DA:39,0 -DA:40,0 -DA:42,8 -DA:43,8 -DA:44,8 -DA:45,8 -DA:46,8 -DA:48,8 -DA:49,12 -DA:52,12 -DA:54,10 -DA:56,8 -DA:59,8 -DA:60,8 -DA:61,0 -DA:62,8 -DA:63,8 -DA:64,8 -DA:65,8 -DA:67,8 -DA:68,8 -DA:69,8 -DA:71,6 -DA:72,6 -DA:73,18 -DA:74,18 -DA:75,18 -DA:76,18 -DA:77,6 -DA:78,8 -DA:80,8 -DA:81,8 -DA:82,8 -DA:83,8 -DA:84,12 -DA:87,12 -DA:88,0 -DA:89,0 -DA:90,12 -DA:92,12 -DA:93,12 -DA:94,12 -DA:95,12 -DA:96,12 -LF:68 -LH:62 -BRDA:12,0,0,12 -BRDA:20,1,0,2 -BRDA:22,2,0,2 -BRDA:23,3,0,4 -BRDA:25,4,0,2 -BRDA:36,5,0,8 -BRDA:37,6,0,0 -BRDA:52,7,0,10 -BRDA:54,8,0,2 -BRDA:54,9,0,8 -BRDA:59,10,0,8 -BRDA:60,11,0,0 -BRDA:67,12,0,8 -BRDA:69,13,0,6 -BRDA:69,14,0,2 -BRDA:69,15,0,6 -BRDA:72,16,0,18 -BRDA:80,17,0,8 -BRF:18 -BRH:16 -end_of_record -TN: -SF:src/hooks/useTimelineMode.ts -FN:20,useTimelineMode -FNF:1 -FNH:1 -FNDA:24,useTimelineMode -DA:1,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:20,1 -DA:21,24 -DA:22,24 -DA:23,24 -DA:24,24 -DA:25,24 -DA:26,24 -DA:27,1 -DA:28,23 -DA:29,24 -DA:31,24 -DA:34,24 -DA:36,24 -DA:37,24 -DA:38,9 -DA:39,9 -DA:41,8 -DA:44,9 -DA:45,6 -DA:46,6 -DA:47,6 -DA:48,9 -DA:49,24 -DA:50,24 -DA:52,24 -DA:53,24 -DA:54,24 -DA:55,24 -DA:56,24 -LF:36 -LH:36 -BRDA:20,0,0,24 -BRDA:26,1,0,6 -BRDA:26,2,0,1 -BRDA:27,3,0,23 -BRDA:37,4,0,9 -BRDA:39,5,0,1 -BRDA:39,6,0,8 -BRDA:44,7,0,6 -BRF:8 -BRH:8 -end_of_record -TN: -SF:src/hooks/useTimelineNavigation.ts -FN:35,useTimelineNavigation -FNF:1 -FNH:1 -FNDA:23,useTimelineNavigation -DA:1,1 -DA:2,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:35,1 -DA:36,23 -DA:37,23 -DA:38,23 -DA:39,23 -DA:40,23 -DA:41,23 -DA:42,23 -DA:43,23 -DA:44,23 -DA:45,23 -DA:46,23 -DA:47,23 -DA:48,23 -DA:49,23 -DA:50,23 -DA:51,23 -DA:52,23 -DA:53,23 -DA:54,23 -DA:55,23 -DA:58,23 -DA:59,23 -DA:60,23 -DA:61,23 -DA:62,23 -DA:63,23 -DA:64,23 -DA:67,23 -DA:68,21 -DA:69,21 -DA:70,69 -DA:71,69 -DA:72,69 -DA:73,21 -DA:74,21 -DA:75,23 -DA:78,23 -DA:79,23 -DA:80,19 -DA:83,15 -DA:84,15 -DA:85,1 -DA:86,1 -DA:89,14 -DA:90,14 -DA:91,0 -DA:92,0 -DA:93,0 -DA:94,0 -DA:95,0 -DA:96,15 -DA:99,18 -DA:100,19 -DA:101,23 -DA:102,23 -DA:105,23 -DA:106,23 -DA:107,2 -DA:110,2 -DA:111,2 -DA:114,2 -DA:115,1 -DA:117,0 -DA:118,0 -DA:119,0 -DA:120,0 -DA:121,0 -DA:125,0 -DA:126,0 -DA:127,0 -DA:128,0 -DA:129,0 -DA:130,0 -DA:131,0 -DA:132,0 -DA:133,0 -DA:134,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,2 -DA:140,2 -DA:141,23 -DA:142,23 -DA:145,23 -DA:146,23 -DA:147,5 -DA:149,5 -DA:150,5 -DA:151,1 -DA:152,4 -DA:154,5 -DA:155,5 -DA:156,23 -DA:157,23 -DA:160,23 -DA:161,23 -DA:162,6 -DA:165,6 -DA:166,6 -DA:169,5 -DA:172,6 -DA:175,6 -DA:176,3 -DA:177,3 -DA:178,0 -DA:179,0 -DA:180,6 -DA:182,1 -DA:183,1 -DA:184,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:189,0 -DA:190,0 -DA:191,0 -DA:192,1 -DA:193,6 -DA:194,23 -DA:195,23 -DA:198,23 -DA:199,23 -DA:200,23 -DA:201,23 -DA:204,23 -DA:205,7 -DA:207,6 -DA:208,6 -DA:209,6 -DA:210,6 -DA:213,6 -DA:214,6 -DA:216,6 -DA:217,6 -DA:218,6 -DA:219,6 -DA:220,23 -DA:222,23 -DA:223,5 -DA:225,4 -DA:226,4 -DA:227,4 -DA:228,4 -DA:231,4 -DA:232,4 -DA:234,4 -DA:235,4 -DA:236,4 -DA:237,4 -DA:238,23 -DA:240,23 -DA:241,3 -DA:242,2 -DA:243,2 -DA:244,2 -DA:247,2 -DA:248,2 -DA:250,2 -DA:251,2 -DA:252,2 -DA:253,2 -DA:254,23 -DA:256,23 -DA:257,5 -DA:258,4 -DA:259,4 -DA:260,4 -DA:261,4 -DA:264,4 -DA:265,4 -DA:267,4 -DA:268,4 -DA:269,4 -DA:270,4 -DA:271,23 -DA:274,23 -DA:275,23 -DA:276,9 -DA:278,9 -DA:281,9 -DA:282,9 -DA:283,1 -DA:284,1 -DA:285,1 -DA:286,9 -DA:287,1 -DA:288,1 -DA:289,1 -DA:290,9 -DA:293,9 -DA:294,4 -DA:295,2 -DA:296,2 -DA:297,2 -DA:298,2 -DA:299,2 -DA:300,2 -DA:301,9 -DA:302,3 -DA:303,2 -DA:304,2 -DA:305,3 -DA:306,1 -DA:307,1 -DA:308,1 -DA:309,3 -DA:310,9 -DA:311,23 -DA:312,23 -DA:314,23 -DA:315,23 -DA:316,23 -DA:317,23 -DA:318,23 -DA:319,23 -DA:320,23 -DA:321,23 -DA:322,23 -DA:323,23 -DA:324,23 -LF:236 -LH:212 -BRDA:35,0,0,23 -BRDA:67,1,0,21 -BRDA:69,2,0,69 -BRDA:79,3,0,19 -BRDA:80,4,0,5 -BRDA:80,5,0,15 -BRDA:84,6,0,1 -BRDA:86,7,0,14 -BRDA:90,8,0,0 -BRDA:96,9,0,18 -BRDA:106,10,0,2 -BRDA:107,11,0,0 -BRDA:110,12,0,2 -BRDA:114,13,0,1 -BRDA:115,14,0,0 -BRDA:146,15,0,5 -BRDA:150,16,0,1 -BRDA:150,17,0,1 -BRDA:151,18,0,4 -BRDA:161,19,0,6 -BRDA:162,20,0,0 -BRDA:166,21,0,1 -BRDA:166,22,0,5 -BRDA:172,23,0,2 -BRDA:172,24,0,1 -BRDA:172,25,0,4 -BRDA:175,26,0,1 -BRDA:175,27,0,3 -BRDA:177,28,0,0 -BRDA:180,29,0,1 -BRDA:188,30,0,0 -BRDA:199,31,0,1 -BRDA:204,32,0,7 -BRDA:205,33,0,1 -BRDA:205,34,0,6 -BRDA:210,35,0,5 -BRDA:217,36,0,0 -BRDA:222,37,0,5 -BRDA:223,38,0,1 -BRDA:223,39,0,4 -BRDA:235,40,0,0 -BRDA:240,41,0,3 -BRDA:241,42,0,1 -BRDA:241,43,0,2 -BRDA:251,44,0,0 -BRDA:256,45,0,5 -BRDA:257,46,0,1 -BRDA:257,47,0,4 -BRDA:261,48,0,3 -BRDA:268,49,0,1 -BRDA:275,50,0,9 -BRDA:276,51,0,0 -BRDA:282,52,0,1 -BRDA:286,53,0,1 -BRDA:290,54,0,7 -BRDA:293,55,0,4 -BRDA:294,56,0,2 -BRDA:296,57,0,1 -BRDA:296,58,0,1 -BRDA:299,59,0,1 -BRDA:299,60,0,1 -BRDA:301,61,0,3 -BRDA:301,62,0,0 -BRDA:302,63,0,2 -BRDA:305,64,0,1 -BRF:65 -BRH:54 -end_of_record -TN: -SF:src/hooks/useTimelineScroll.ts -FN:10,useTimelineScroll -FNF:1 -FNH:1 -FNDA:13,useTimelineScroll -DA:1,1 -DA:10,1 -DA:11,13 -DA:12,13 -DA:13,13 -DA:14,13 -DA:15,13 -DA:16,13 -DA:17,13 -DA:18,13 -DA:19,13 -DA:22,13 -DA:23,13 -DA:26,13 -DA:27,13 -DA:28,3 -DA:29,3 -DA:30,2 -DA:31,2 -DA:32,3 -DA:33,13 -DA:34,13 -DA:37,13 -DA:38,13 -DA:39,3 -DA:42,3 -DA:43,1 -DA:44,1 -DA:46,3 -DA:47,2 -DA:49,2 -DA:51,2 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,3 -DA:64,3 -DA:65,13 -DA:66,13 -DA:68,13 -DA:69,13 -DA:70,13 -DA:71,13 -DA:72,13 -DA:73,13 -DA:74,13 -LF:54 -LH:54 -BRDA:10,0,0,13 -BRDA:27,1,0,3 -BRDA:29,2,0,2 -BRDA:29,3,0,2 -BRDA:38,4,0,3 -BRDA:42,5,0,1 -BRDA:46,6,0,2 -BRDA:47,7,0,0 -BRDA:49,8,0,1 -BRDA:51,9,0,1 -BRF:10 -BRH:9 -end_of_record -TN: -SF:src/hooks/useTimelineSearch.ts -FN:12,useTimelineSearch -FNF:1 -FNH:1 -FNDA:33,useTimelineSearch -DA:1,1 -DA:3,1 -DA:4,1 -DA:12,1 -DA:13,33 -DA:14,33 -DA:15,33 -DA:16,33 -DA:17,33 -DA:18,33 -DA:19,33 -DA:20,33 -DA:21,33 -DA:24,33 -DA:25,33 -DA:27,33 -DA:28,33 -DA:31,33 -DA:32,16 -DA:33,54 -DA:34,54 -DA:35,54 -DA:36,54 -DA:37,54 -DA:38,1 -DA:39,53 -DA:40,54 -DA:42,54 -DA:43,54 -DA:44,54 -DA:45,54 -DA:46,54 -DA:47,16 -DA:48,33 -DA:51,33 -DA:53,9 -DA:54,8 -DA:55,0 -DA:56,0 -DA:57,0 -DA:58,0 -DA:59,9 -DA:60,33 -DA:63,33 -DA:64,33 -DA:65,7 -DA:66,7 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:72,6 -DA:73,6 -DA:76,7 -DA:77,16 -DA:78,12 -DA:79,12 -DA:80,16 -DA:82,6 -DA:84,6 -DA:85,6 -DA:86,6 -DA:87,6 -DA:88,6 -DA:89,6 -DA:90,6 -DA:91,6 -DA:92,6 -DA:93,7 -DA:94,0 -DA:95,0 -DA:96,0 -DA:97,7 -DA:98,33 -DA:99,33 -DA:102,33 -DA:103,33 -DA:104,33 -DA:105,33 -DA:106,33 -DA:108,33 -DA:109,33 -DA:110,7 -DA:111,7 -DA:112,7 -DA:113,33 -DA:114,33 -DA:116,33 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,33 -DA:134,33 -DA:135,33 -DA:136,3 -DA:138,3 -DA:139,3 -DA:140,2 -DA:141,1 -DA:143,3 -DA:145,3 -DA:146,3 -DA:148,3 -DA:149,3 -DA:151,3 -DA:153,3 -DA:154,3 -DA:155,3 -DA:156,3 -DA:157,3 -DA:158,33 -DA:159,33 -DA:161,33 -DA:162,33 -DA:163,33 -DA:164,33 -DA:166,33 -DA:167,33 -DA:168,33 -DA:169,33 -DA:171,33 -DA:172,33 -DA:173,1 -DA:174,1 -DA:175,1 -DA:176,1 -DA:177,1 -DA:178,1 -DA:179,1 -DA:180,1 -DA:181,0 -DA:182,0 -DA:183,0 -DA:184,1 -DA:185,1 -DA:186,33 -DA:187,33 -DA:189,33 -DA:190,33 -DA:191,33 -DA:192,33 -DA:193,33 -DA:194,33 -DA:195,33 -DA:196,33 -DA:197,33 -DA:198,33 -DA:199,33 -DA:200,33 -DA:201,33 -LF:159 -LH:149 -BRDA:12,0,0,33 -BRDA:31,1,0,16 -BRDA:32,2,0,54 -BRDA:37,3,0,1 -BRDA:38,4,0,53 -BRDA:51,5,0,9 -BRDA:53,6,0,8 -BRDA:54,7,0,0 -BRDA:64,8,0,7 -BRDA:66,9,0,1 -BRDA:70,10,0,6 -BRDA:76,11,0,16 -BRDA:77,12,0,12 -BRDA:80,13,0,6 -BRDA:93,14,0,0 -BRDA:109,15,0,7 -BRDA:116,16,0,1 -BRDA:135,17,0,3 -BRDA:136,18,0,0 -BRDA:139,19,0,2 -BRDA:140,20,0,1 -BRDA:143,21,0,0 -BRDA:162,22,0,2 -BRDA:167,23,0,1 -BRDA:172,24,0,1 -BRDA:180,25,0,0 -BRF:26 -BRH:21 -end_of_record -TN: -SF:src/hooks/useUIState.ts -FN:12,useUIState -FNF:1 -FNH:1 -FNDA:12,useUIState -DA:1,1 -DA:12,1 -DA:13,12 -DA:14,12 -DA:15,12 -DA:17,12 -DA:18,3 -DA:19,12 -DA:22,12 -DA:23,2 -DA:24,12 -DA:26,12 -DA:27,12 -LF:13 -LH:13 -BRDA:12,0,0,12 -BRDA:17,1,0,3 -BRDA:18,2,0,3 -BRDA:22,3,0,2 -BRF:4 -BRH:4 -end_of_record -TN: -SF:src/hooks/useWindowSize.ts -FN:17,useWindowSize -FNF:1 -FNH:1 -FNDA:10,useWindowSize -DA:1,1 -DA:17,1 -DA:18,10 -DA:19,10 -DA:20,10 -DA:23,10 -DA:24,8 -DA:25,8 -DA:26,10 -DA:28,10 -DA:29,10 -DA:30,10 -DA:32,10 -DA:33,3 -DA:34,3 -DA:35,3 -DA:36,3 -DA:39,3 -DA:40,3 -DA:41,1 -DA:42,3 -DA:43,2 -DA:44,2 -DA:45,2 -DA:46,10 -DA:48,10 -DA:50,8 -DA:51,8 -DA:53,8 -DA:55,0 -DA:56,0 -DA:57,0 -DA:60,8 -DA:61,3 -DA:62,8 -DA:63,10 -DA:65,10 -DA:66,8 -DA:69,8 -DA:70,8 -DA:73,8 -DA:75,8 -DA:76,8 -DA:77,8 -DA:78,8 -DA:79,8 -DA:80,10 -DA:82,10 -DA:83,10 -LF:49 -LH:46 -BRDA:17,0,0,10 -BRDA:23,1,0,8 -BRDA:24,2,0,0 -BRDA:25,3,0,0 -BRDA:32,4,0,3 -BRDA:40,5,0,1 -BRDA:42,6,0,2 -BRDA:48,7,0,8 -BRDA:50,8,0,0 -BRDA:51,9,0,0 -BRDA:53,10,0,0 -BRDA:60,11,0,3 -BRDA:65,12,0,8 -BRDA:66,13,0,0 -BRDA:75,14,0,8 -BRDA:78,15,0,3 -BRF:16 -BRH:10 -end_of_record -TN: -SF:src/hooks/__tests__/useBackground.test.ts -FN:59,__vi_import_0__.renderHook.initialProps.color -FNF:1 -FNH:1 -FNDA:2,__vi_import_0__.renderHook.initialProps.color -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:13,1 -DA:14,1 -DA:16,1 -DA:17,4 -DA:18,4 -DA:19,1 -DA:21,1 -DA:22,4 -DA:23,4 -DA:24,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:32,1 -DA:34,1 -DA:35,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:43,1 -DA:44,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -LF:54 -LH:54 -BRDA:7,0,0,1 -BRDA:13,1,0,1 -BRDA:16,2,0,4 -BRDA:21,3,0,4 -BRDA:26,4,0,1 -BRDA:27,5,0,1 -BRDA:32,6,0,1 -BRDA:37,7,0,1 -BRDA:46,8,0,1 -BRDA:48,9,0,1 -BRDA:53,10,0,1 -BRDA:59,11,0,2 -BRF:12 -BRH:12 -end_of_record -TN: -SF:src/hooks/__tests__/useCardSize.test.ts -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:8,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:19,1 -DA:20,7 -DA:21,7 -DA:22,7 -DA:23,7 -DA:24,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:56,1 -DA:58,1 -DA:59,2 -DA:60,2 -DA:61,2 -DA:62,2 -DA:63,2 -DA:64,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:109,1 -DA:111,1 -DA:112,2 -DA:113,2 -DA:114,2 -DA:115,2 -DA:116,2 -DA:117,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:123,1 -DA:124,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:142,1 -DA:144,1 -DA:145,2 -DA:146,2 -DA:147,2 -DA:148,2 -DA:149,2 -DA:150,1 -DA:152,1 -DA:153,1 -DA:154,1 -DA:156,1 -DA:157,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:162,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:167,1 -DA:168,1 -DA:169,1 -DA:171,1 -DA:172,1 -DA:173,1 -DA:175,1 -DA:177,1 -DA:178,2 -DA:179,2 -DA:180,2 -DA:181,2 -DA:182,2 -DA:183,1 -DA:186,1 -DA:187,1 -DA:188,0 -DA:189,0 -DA:190,0 -DA:191,0 -DA:192,0 -DA:193,1 -DA:196,1 -DA:197,1 -DA:199,1 -DA:200,1 -DA:201,1 -DA:204,1 -DA:205,1 -DA:206,1 -DA:207,1 -DA:208,1 -DA:209,1 -DA:210,1 -DA:211,1 -DA:214,1 -DA:216,1 -DA:217,1 -DA:218,1 -DA:220,1 -DA:221,1 -DA:222,1 -DA:223,1 -DA:224,1 -DA:225,1 -DA:228,1 -DA:229,1 -DA:231,1 -DA:232,1 -DA:233,1 -DA:234,1 -DA:235,1 -DA:236,1 -DA:237,1 -DA:239,1 -DA:242,1 -DA:244,1 -DA:245,1 -DA:246,1 -LF:192 -LH:187 -BRDA:14,0,0,1 -BRDA:19,1,0,7 -BRDA:26,2,0,1 -BRDA:27,3,0,1 -BRDA:40,4,0,1 -BRDA:58,5,0,2 -BRDA:66,6,0,1 -BRDA:75,7,0,1 -BRDA:76,8,0,1 -BRDA:84,9,0,1 -BRDA:93,10,0,1 -BRDA:111,11,0,2 -BRDA:119,12,0,1 -BRDA:126,13,0,1 -BRDA:144,14,0,2 -BRDA:152,15,0,1 -BRDA:159,16,0,1 -BRDA:177,17,0,2 -BRDA:199,18,0,1 -BRDA:204,19,0,1 -BRDA:220,20,0,1 -BRDA:222,21,0,1 -BRDA:231,22,0,1 -BRF:23 -BRH:23 -end_of_record -TN: -SF:src/hooks/__tests__/useEscapeKey.test.ts -FN:89,initialProps.callback -FNF:1 -FNH:1 -FNDA:2,initialProps.callback -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:10,8 -DA:11,1 -DA:13,1 -DA:14,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:21,1 -DA:22,1 -DA:24,1 -DA:25,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:32,1 -DA:33,1 -DA:35,1 -DA:36,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:43,1 -DA:44,1 -DA:46,1 -DA:47,1 -DA:49,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:74,1 -DA:75,1 -DA:77,1 -DA:78,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:85,1 -DA:86,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:93,1 -DA:94,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:109,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -LF:88 -LH:88 -BRDA:6,0,0,1 -BRDA:9,1,0,8 -BRDA:13,2,0,1 -BRDA:14,3,0,1 -BRDA:16,4,0,1 -BRDA:24,5,0,1 -BRDA:25,6,0,1 -BRDA:27,7,0,1 -BRDA:35,8,0,1 -BRDA:36,9,0,1 -BRDA:38,10,0,1 -BRDA:46,11,0,1 -BRDA:47,12,0,1 -BRDA:49,13,0,1 -BRDA:63,14,0,1 -BRDA:64,15,0,1 -BRDA:66,16,0,1 -BRDA:77,17,0,1 -BRDA:78,18,0,1 -BRDA:80,19,0,1 -BRDA:88,20,0,1 -BRDA:89,21,0,2 -BRDA:96,22,0,1 -BRDA:105,23,0,1 -BRDA:107,24,0,1 -BRF:25 -BRH:25 -end_of_record -TN: -SF:src/hooks/__tests__/useMediaState.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:15,1 -DA:16,9 -DA:17,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:24,1 -DA:25,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:33,1 -DA:34,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:100,1 -DA:101,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -LF:91 -LH:91 -BRDA:6,0,0,1 -BRDA:15,1,0,9 -BRDA:19,2,0,1 -BRDA:20,3,0,1 -BRDA:24,4,0,1 -BRDA:25,5,0,2 -BRDA:27,6,0,1 -BRDA:33,7,0,1 -BRDA:34,8,0,3 -BRDA:36,9,0,1 -BRDA:41,10,0,1 -BRDA:47,11,0,1 -BRDA:48,12,0,1 -BRDA:52,13,0,1 -BRDA:58,14,0,1 -BRDA:59,15,0,1 -BRDA:63,16,0,1 -BRDA:69,17,0,1 -BRDA:70,18,0,1 -BRDA:72,19,0,1 -BRDA:78,20,0,1 -BRDA:79,21,0,1 -BRDA:83,22,0,1 -BRDA:89,23,0,1 -BRDA:90,24,0,1 -BRDA:94,25,0,1 -BRDA:100,26,0,1 -BRDA:101,27,0,3 -BRDA:103,28,0,1 -BRDA:108,29,0,1 -BRF:30 -BRH:30 -end_of_record -TN: -SF:src/hooks/__tests__/useOutsideClick.test.ts -FN:88,initialProps.cb -FN:142,initialProps.enabled -FNF:2 -FNH:2 -FNDA:2,initialProps.cb -FNDA:3,initialProps.enabled -DA:1,1 -DA:2,1 -DA:3,1 -DA:4,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:12,1 -DA:14,9 -DA:15,9 -DA:18,9 -DA:19,9 -DA:22,9 -DA:23,1 -DA:25,1 -DA:26,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:33,1 -DA:34,1 -DA:36,1 -DA:37,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:70,1 -DA:71,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:83,1 -DA:84,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:99,1 -DA:100,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:115,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:134,1 -DA:135,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:141,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:146,1 -DA:147,1 -DA:148,1 -DA:149,1 -DA:150,1 -DA:153,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:157,1 -DA:160,1 -DA:161,1 -DA:163,1 -DA:164,1 -DA:165,1 -DA:166,1 -LF:116 -LH:116 -BRDA:6,0,0,1 -BRDA:12,1,0,9 -BRDA:25,2,0,1 -BRDA:26,3,0,1 -BRDA:36,4,0,1 -BRDA:37,5,0,1 -BRDA:47,6,0,1 -BRDA:48,7,0,1 -BRDA:60,8,0,1 -BRDA:61,9,0,1 -BRDA:73,10,0,1 -BRDA:74,11,0,1 -BRDA:86,12,0,1 -BRDA:88,13,0,2 -BRDA:109,14,0,1 -BRDA:111,15,0,1 -BRDA:124,16,0,1 -BRDA:126,17,0,1 -BRDA:137,18,0,1 -BRDA:142,19,0,3 -BRF:20 -BRH:20 -end_of_record -TN: -SF:src/hooks/__tests__/useTimelineMedia.test.ts -FN:20, -FN:23,MockIntersectionObserver -FNF:2 -FNH:2 -FNDA:3, -FNDA:3,MockIntersectionObserver -DA:1,1 -DA:2,1 -DA:3,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:20,1 -DA:21,3 -DA:22,3 -DA:23,3 -DA:24,3 -DA:25,3 -DA:26,3 -DA:29,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:38,1 -DA:40,4 -DA:41,4 -DA:43,4 -DA:44,4 -DA:46,4 -DA:47,4 -DA:48,4 -DA:49,4 -DA:50,4 -DA:51,4 -DA:52,4 -DA:54,4 -DA:55,4 -DA:56,4 -DA:57,1 -DA:59,1 -DA:60,4 -DA:61,4 -DA:62,4 -DA:63,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:88,1 -DA:89,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:97,1 -DA:98,1 -DA:101,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -LF:85 -LH:85 -BRDA:6,0,0,1 -BRDA:20,1,0,3 -BRDA:23,2,0,3 -BRDA:29,3,0,5 -BRDA:31,4,0,1 -BRDA:38,5,0,4 -BRDA:59,6,0,4 -BRDA:65,7,0,1 -BRDA:66,8,0,1 -BRDA:71,9,0,1 -BRDA:72,10,0,1 -BRDA:80,11,0,1 -BRDA:81,12,0,1 -BRDA:88,13,0,1 -BRDA:89,14,0,1 -BRF:15 -BRH:15 -end_of_record -TN: -SF:src/hooks/__tests__/useTimelineMode.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:6,1 -DA:8,1 -DA:9,7 -DA:10,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:19,1 -DA:20,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:33,1 -DA:34,1 -DA:35,3 -DA:36,3 -DA:37,3 -DA:38,3 -DA:39,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:45,1 -DA:46,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:55,1 -DA:56,1 -DA:57,2 -DA:58,2 -DA:59,2 -DA:60,2 -DA:61,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,1 -DA:73,3 -DA:74,3 -DA:75,3 -DA:76,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:82,1 -DA:84,1 -DA:86,1 -DA:87,1 -DA:89,1 -DA:90,1 -DA:91,2 -DA:92,2 -DA:93,2 -DA:94,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:104,1 -DA:105,1 -DA:106,4 -DA:107,4 -DA:108,4 -DA:109,4 -DA:110,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:119,1 -DA:120,4 -DA:121,4 -DA:122,4 -DA:124,4 -DA:125,1 -DA:126,1 -DA:127,1 -LF:101 -LH:101 -BRDA:5,0,0,1 -BRDA:8,1,0,7 -BRDA:12,2,0,1 -BRDA:13,3,0,1 -BRDA:22,4,0,1 -BRDA:23,5,0,1 -BRDA:33,6,0,1 -BRDA:34,7,0,3 -BRDA:41,8,0,1 -BRDA:48,9,0,1 -BRDA:55,10,0,1 -BRDA:56,11,0,2 -BRDA:63,12,0,1 -BRDA:71,13,0,1 -BRDA:72,14,0,3 -BRDA:78,15,0,1 -BRDA:89,16,0,1 -BRDA:90,17,0,2 -BRDA:96,18,0,1 -BRDA:104,19,0,1 -BRDA:105,20,0,4 -BRDA:119,21,0,4 -BRDA:120,22,0,4 -BRF:23 -BRH:23 -end_of_record -TN: -SF:src/hooks/__tests__/useTimelineNavigation.test.ts -FN:13,createMockKeyboardEvent -FNF:1 -FNH:1 -FNDA:9,createMockKeyboardEvent -DA:1,1 -DA:2,1 -DA:3,1 -DA:6,1 -DA:7,0 -DA:8,0 -DA:9,0 -DA:10,1 -DA:13,1 -DA:14,9 -DA:15,9 -DA:16,9 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:31,1 -DA:32,15 -DA:33,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:50,1 -DA:51,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:141,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:147,1 -DA:148,1 -DA:149,1 -DA:152,1 -DA:153,1 -DA:154,1 -DA:156,1 -DA:157,1 -DA:158,1 -DA:160,1 -DA:161,1 -DA:162,1 -DA:163,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:167,1 -DA:168,1 -DA:169,1 -DA:171,1 -DA:172,1 -DA:173,1 -DA:175,1 -DA:176,1 -DA:177,1 -DA:179,1 -DA:180,1 -DA:181,1 -DA:182,1 -DA:183,1 -DA:184,1 -DA:185,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:190,1 -DA:191,1 -DA:194,1 -DA:195,1 -DA:196,1 -DA:198,1 -DA:199,1 -DA:202,1 -DA:203,1 -DA:204,1 -DA:206,1 -DA:207,1 -DA:210,1 -DA:211,1 -DA:212,1 -DA:214,1 -DA:215,1 -DA:216,1 -DA:218,1 -DA:219,1 -DA:222,1 -DA:223,1 -DA:224,1 -DA:226,1 -DA:227,1 -DA:228,1 -DA:230,1 -DA:231,1 -DA:232,1 -DA:233,1 -DA:234,1 -DA:235,1 -DA:236,1 -DA:237,1 -DA:238,1 -DA:239,1 -DA:240,1 -DA:243,1 -DA:244,1 -DA:245,1 -DA:247,1 -DA:248,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:255,1 -DA:256,1 -DA:257,1 -DA:259,1 -DA:260,1 -DA:261,1 -DA:262,1 -DA:263,1 -DA:264,1 -DA:265,1 -DA:266,1 -DA:267,1 -DA:268,1 -DA:269,1 -DA:270,1 -DA:273,1 -DA:274,1 -DA:275,1 -DA:277,1 -DA:278,1 -DA:281,1 -DA:282,1 -DA:283,1 -DA:285,1 -DA:286,1 -DA:287,1 -DA:289,1 -DA:290,1 -DA:291,1 -DA:292,1 -DA:293,1 -DA:294,1 -DA:295,1 -DA:296,1 -DA:297,1 -DA:298,1 -DA:299,1 -DA:300,1 -DA:301,1 -DA:303,1 -DA:304,1 -DA:305,1 -DA:306,1 -DA:307,1 -DA:308,1 -DA:310,1 -DA:311,1 -DA:312,1 -DA:313,1 -DA:314,1 -DA:316,1 -DA:317,1 -DA:318,1 -DA:319,1 -DA:320,1 -DA:321,1 -DA:322,1 -DA:323,1 -DA:324,1 -DA:325,1 -DA:327,1 -DA:328,1 -DA:329,1 -DA:331,1 -DA:332,1 -DA:334,1 -DA:335,1 -DA:338,1 -DA:339,1 -DA:340,0 -DA:341,1 -DA:343,1 -DA:344,1 -DA:345,1 -DA:346,1 -DA:347,1 -DA:348,1 -DA:349,1 -DA:350,1 -DA:351,1 -DA:352,1 -DA:354,1 -DA:355,1 -DA:356,1 -DA:359,1 -DA:360,1 -DA:361,1 -DA:364,1 -DA:365,1 -DA:367,1 -DA:368,1 -DA:371,1 -DA:372,1 -DA:373,1 -DA:374,1 -DA:375,1 -DA:376,1 -DA:378,1 -DA:379,1 -DA:380,1 -DA:381,1 -DA:382,1 -DA:383,1 -DA:384,1 -DA:385,1 -DA:386,1 -DA:387,1 -DA:389,1 -DA:390,1 -DA:391,1 -DA:394,1 -DA:395,1 -DA:396,1 -DA:399,1 -DA:400,1 -DA:401,1 -DA:404,1 -DA:405,1 -DA:407,1 -DA:408,1 -DA:409,1 -DA:410,1 -DA:411,1 -DA:412,1 -DA:413,1 -DA:414,1 -DA:415,1 -DA:416,1 -DA:417,1 -DA:419,1 -DA:420,1 -DA:421,1 -DA:424,1 -DA:425,1 -DA:427,1 -DA:428,1 -LF:336 -LH:332 -BRDA:13,0,0,9 -BRDA:18,1,0,1 -BRDA:31,2,0,15 -BRDA:35,3,0,1 -BRDA:36,4,0,1 -BRDA:53,5,0,1 -BRDA:54,6,0,1 -BRDA:64,7,0,1 -BRDA:72,8,0,1 -BRDA:73,9,0,1 -BRDA:83,10,0,1 -BRDA:91,11,0,1 -BRDA:92,12,0,1 -BRDA:102,13,0,1 -BRDA:110,14,0,1 -BRDA:111,15,0,1 -BRDA:122,16,0,1 -BRDA:127,17,0,1 -BRDA:135,18,0,1 -BRDA:136,19,0,1 -BRDA:147,20,0,1 -BRDA:152,21,0,1 -BRDA:160,22,0,1 -BRDA:161,23,0,1 -BRDA:171,24,0,1 -BRDA:179,25,0,1 -BRDA:180,26,0,1 -BRDA:194,27,0,1 -BRDA:202,28,0,1 -BRDA:210,29,0,1 -BRDA:214,30,0,1 -BRDA:222,31,0,1 -BRDA:230,32,0,1 -BRDA:231,33,0,1 -BRDA:243,34,0,1 -BRDA:251,35,0,1 -BRDA:259,36,0,1 -BRDA:260,37,0,1 -BRDA:273,38,0,1 -BRDA:281,39,0,1 -BRDA:289,40,0,1 -BRDA:290,41,0,1 -BRDA:303,42,0,1 -BRDA:316,43,0,1 -BRDA:317,44,0,1 -BRDA:327,45,0,1 -BRDA:334,46,0,1 -BRDA:343,47,0,1 -BRDA:354,48,0,1 -BRDA:367,49,0,1 -BRDA:372,50,0,1 -BRDA:378,51,0,1 -BRDA:389,52,0,1 -BRDA:394,53,0,1 -BRDA:395,54,0,1 -BRDA:407,55,0,1 -BRDA:408,56,0,1 -BRDA:419,57,0,1 -BRF:58 -BRH:58 -end_of_record -TN: -SF:src/hooks/__tests__/useTimelineScroll.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:10,5 -DA:11,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:35,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:45,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:58,1 -DA:62,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:79,1 -DA:80,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:98,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:123,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:141,1 -DA:142,1 -DA:143,1 -DA:144,1 -DA:145,1 -DA:146,1 -DA:147,1 -DA:148,1 -DA:149,1 -DA:150,1 -DA:153,1 -DA:154,1 -DA:155,1 -DA:158,1 -DA:159,1 -DA:161,1 -DA:162,1 -DA:163,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:167,1 -DA:170,1 -DA:171,1 -DA:172,1 -DA:173,1 -DA:174,1 -DA:176,1 -DA:178,1 -DA:179,1 -DA:180,1 -DA:182,1 -DA:183,1 -DA:184,1 -DA:185,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:190,1 -DA:191,1 -DA:192,1 -DA:193,1 -DA:195,1 -DA:196,1 -DA:197,1 -DA:199,1 -DA:200,1 -DA:201,1 -LF:152 -LH:152 -BRDA:5,0,0,1 -BRDA:9,1,0,5 -BRDA:13,2,0,1 -BRDA:14,3,0,1 -BRDA:25,4,0,1 -BRDA:26,5,0,1 -BRDA:48,6,0,1 -BRDA:65,7,0,1 -BRDA:74,8,0,1 -BRDA:75,9,0,1 -BRDA:82,10,0,1 -BRDA:83,11,0,1 -BRDA:100,12,0,1 -BRDA:130,13,0,1 -BRDA:153,14,0,1 -BRDA:154,15,0,1 -BRDA:161,16,0,1 -BRDA:162,17,0,1 -BRDA:178,18,0,1 -BRDA:187,19,0,1 -BRDA:188,20,0,1 -BRDA:195,21,0,1 -BRF:22 -BRH:22 -end_of_record -TN: -SF:src/hooks/__tests__/useTimelineSearch.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:30,1 -DA:31,1 -DA:33,1 -DA:34,8 -DA:35,8 -DA:36,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:52,1 -DA:53,1 -DA:54,3 -DA:55,3 -DA:56,3 -DA:57,3 -DA:58,3 -DA:59,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:76,1 -DA:77,1 -DA:78,3 -DA:79,3 -DA:80,3 -DA:81,3 -DA:82,3 -DA:83,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:98,1 -DA:99,1 -DA:100,5 -DA:101,5 -DA:102,5 -DA:103,5 -DA:104,5 -DA:105,1 -DA:108,1 -DA:109,1 -DA:110,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:117,1 -DA:118,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:125,1 -DA:126,1 -DA:127,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:139,1 -DA:140,1 -DA:141,4 -DA:142,4 -DA:143,4 -DA:144,4 -DA:145,4 -DA:146,1 -DA:149,1 -DA:150,1 -DA:151,1 -DA:154,1 -DA:155,1 -DA:156,1 -DA:159,1 -DA:160,1 -DA:161,1 -DA:163,1 -DA:164,1 -DA:165,1 -DA:166,1 -DA:167,1 -DA:168,1 -DA:170,1 -DA:171,1 -DA:172,2 -DA:173,2 -DA:174,2 -DA:175,2 -DA:176,2 -DA:177,1 -DA:179,1 -DA:180,1 -DA:181,1 -DA:184,1 -DA:185,1 -DA:186,1 -DA:188,1 -DA:189,1 -DA:190,1 -DA:192,1 -DA:193,1 -DA:194,1 -DA:195,1 -DA:196,1 -DA:197,1 -DA:198,1 -DA:200,1 -DA:201,3 -DA:202,3 -DA:203,3 -DA:204,3 -DA:205,3 -DA:206,1 -DA:208,1 -DA:209,1 -DA:210,1 -DA:213,1 -DA:214,1 -DA:215,1 -DA:217,1 -DA:218,1 -DA:219,1 -DA:221,1 -DA:222,1 -DA:223,4 -DA:224,4 -DA:225,4 -DA:226,4 -DA:227,4 -DA:228,1 -DA:231,1 -DA:232,1 -DA:233,1 -DA:236,1 -DA:237,1 -DA:238,1 -DA:241,1 -DA:242,1 -DA:243,1 -DA:244,1 -DA:245,1 -DA:246,1 -DA:247,1 -DA:248,1 -DA:249,1 -DA:250,1 -DA:251,1 -DA:252,1 -DA:253,1 -DA:254,1 -DA:255,1 -DA:256,1 -DA:257,1 -DA:258,1 -DA:259,1 -DA:260,1 -DA:261,1 -DA:262,1 -DA:263,1 -DA:264,1 -DA:265,1 -DA:266,1 -DA:267,1 -DA:269,1 -DA:270,1 -DA:271,1 -DA:272,1 -DA:273,1 -LF:219 -LH:219 -BRDA:5,0,0,1 -BRDA:33,1,0,8 -BRDA:38,2,0,1 -BRDA:39,3,0,1 -BRDA:52,4,0,1 -BRDA:53,5,0,3 -BRDA:61,6,0,1 -BRDA:66,7,0,1 -BRDA:76,8,0,1 -BRDA:77,9,0,3 -BRDA:85,10,0,1 -BRDA:90,11,0,1 -BRDA:98,12,0,1 -BRDA:99,13,0,5 -BRDA:108,14,0,1 -BRDA:113,15,0,1 -BRDA:121,16,0,1 -BRDA:130,17,0,1 -BRDA:139,18,0,1 -BRDA:140,19,0,4 -BRDA:149,20,0,1 -BRDA:154,21,0,1 -BRDA:159,22,0,1 -BRDA:170,23,0,1 -BRDA:171,24,0,2 -BRDA:179,25,0,1 -BRDA:184,26,0,1 -BRDA:192,27,0,1 -BRDA:200,28,0,3 -BRDA:208,29,0,1 -BRDA:213,30,0,1 -BRDA:221,31,0,1 -BRDA:222,32,0,4 -BRDA:231,33,0,1 -BRDA:236,34,0,1 -BRDA:241,35,0,1 -BRF:36 -BRH:36 -end_of_record -TN: -SF:src/hooks/__tests__/useUIState.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:9,1 -DA:10,1 -DA:12,1 -DA:13,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:19,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:25,1 -DA:26,1 -DA:28,1 -DA:29,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:35,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:41,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:61,1 -DA:63,1 -DA:65,1 -DA:66,1 -DA:67,1 -LF:48 -LH:48 -BRDA:5,0,0,1 -BRDA:6,1,0,1 -BRDA:7,2,0,1 -BRDA:12,3,0,1 -BRDA:13,4,0,3 -BRDA:15,5,0,1 -BRDA:21,6,0,1 -BRDA:28,7,0,1 -BRDA:29,8,0,3 -BRDA:31,9,0,1 -BRDA:37,10,0,1 -BRDA:44,11,0,1 -BRDA:45,12,0,1 -BRDA:46,13,0,1 -BRDA:54,14,0,1 -BRDA:55,15,0,3 -BRDA:57,16,0,1 -BRF:17 -BRH:17 -end_of_record -TN: -SF:src/hooks/__tests__/useWindowSize.test.ts -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:5,1 -DA:6,1 -DA:7,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:15,1 -DA:16,0 -DA:17,0 -DA:19,1 -DA:20,1 -DA:21,1 -DA:23,1 -DA:24,1 -DA:26,1 -DA:27,5 -DA:29,5 -DA:31,5 -DA:32,5 -DA:33,0 -DA:34,0 -DA:35,5 -DA:36,5 -DA:37,5 -DA:38,5 -DA:39,1 -DA:41,1 -DA:42,5 -DA:44,5 -DA:45,1 -DA:47,1 -DA:48,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:54,1 -DA:55,1 -DA:58,1 -DA:59,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:75,1 -DA:76,1 -DA:79,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:89,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:96,1 -DA:97,1 -DA:100,1 -DA:103,1 -DA:105,1 -DA:106,1 -DA:108,1 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:116,1 -DA:117,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:136,1 -DA:137,1 -DA:138,1 -LF:93 -LH:89 -BRDA:15,0,0,0 -BRDA:23,1,0,1 -BRDA:26,2,0,5 -BRDA:41,3,0,5 -BRDA:47,4,0,1 -BRDA:48,5,0,1 -BRDA:54,6,0,1 -BRDA:55,7,0,2 -BRDA:62,8,0,1 -BRDA:67,9,0,1 -BRDA:75,10,0,1 -BRDA:76,11,0,1 -BRDA:82,12,0,1 -BRDA:92,13,0,1 -BRDA:105,14,0,1 -BRDA:106,15,0,1 -BRDA:116,16,0,1 -BRDA:117,17,0,2 -BRDA:120,18,0,1 -BRDA:126,19,0,1 -BRDA:132,20,0,1 -BRF:21 -BRH:20 -end_of_record -TN: -SF:src/utils/index.ts -FN:82,hexToRGBA -FN:111,getDefaultThemeOrDark -FN:118,getDefaultClassNames -FN:124,getDefaultButtonTexts -FN:131,getSlideShowType -FN:147,isTextArray -FN:155,sanitizeHtmlText -FN:172,getUniqueID -FNF:8 -FNH:6 -FNDA:61,hexToRGBA -FNDA:10,getDefaultThemeOrDark -FNDA:63,getDefaultClassNames -FNDA:62,getDefaultButtonTexts -FNDA:6,getSlideShowType -FNDA:0,isTextArray -FNDA:0,sanitizeHtmlText -FNDA:20,getUniqueID -DA:6,1 -DA:7,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:69,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:82,1 -DA:84,61 -DA:85,0 -DA:86,0 -DA:89,61 -DA:90,6 -DA:91,6 -DA:92,6 -DA:95,55 -DA:96,55 -DA:97,55 -DA:98,55 -DA:101,55 -DA:103,55 -DA:104,55 -DA:111,1 -DA:112,10 -DA:118,1 -DA:124,1 -DA:131,1 -DA:132,6 -DA:133,6 -DA:134,3 -DA:135,6 -DA:136,6 -DA:137,6 -DA:138,3 -DA:139,6 -DA:140,6 -DA:147,1 -DA:148,0 -DA:155,1 -DA:156,0 -DA:157,0 -DA:158,0 -DA:160,0 -DA:161,0 -DA:162,0 -DA:163,0 -DA:164,0 -DA:165,0 -DA:166,0 -DA:172,1 -DA:174,20 -DA:175,20 -DA:176,20 -DA:177,20 -DA:179,20 -DA:180,20 -DA:181,20 -DA:182,20 -DA:183,20 -DA:184,0 -DA:185,0 -DA:186,20 -DA:190,0 -DA:193,0 -DA:194,0 -DA:195,0 -DA:196,0 -DA:199,20 -DA:200,20 -DA:202,0 -DA:203,0 -DA:204,0 -DA:205,0 -DA:206,0 -DA:207,20 -DA:209,20 -DA:210,20 -LF:132 -LH:107 -BRDA:82,0,0,61 -BRDA:84,1,0,0 -BRDA:89,2,0,6 -BRDA:92,3,0,55 -BRDA:111,4,0,10 -BRDA:112,5,0,1 -BRDA:112,6,0,9 -BRDA:118,7,0,63 -BRDA:124,8,0,62 -BRDA:131,9,0,6 -BRDA:133,10,0,3 -BRDA:135,11,0,1 -BRDA:136,12,0,2 -BRDA:137,13,0,3 -BRDA:172,14,0,20 -BRDA:183,15,0,0 -BRDA:186,16,0,0 -BRDA:194,17,0,0 -BRDA:195,18,0,0 -BRDA:181,19,0,140 -BRF:20 -BRH:15 -end_of_record -TN: -SF:src/utils/mediaQueryUtils.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:8,1 -DA:9,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:14,1 -DA:15,3 -DA:16,3 -DA:17,3 -DA:18,3 -DA:19,3 -DA:20,2 -DA:21,2 -DA:22,2 -DA:23,1 -DA:24,1 -DA:25,2 -DA:26,2 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,2 -DA:33,3 -DA:34,3 -DA:35,1 -DA:36,1 -DA:37,3 -DA:38,3 -DA:39,2 -DA:40,1 -DA:41,1 -DA:42,3 -DA:43,1 -DA:45,1 -DA:46,3 -DA:47,3 -DA:48,3 -DA:49,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -LF:61 -LH:61 -BRDA:8,0,0,1 -BRDA:14,1,0,3 -BRDA:19,2,0,2 -BRDA:22,3,0,1 -BRDA:26,4,0,1 -BRDA:29,5,0,1 -BRDA:34,6,0,1 -BRDA:38,7,0,2 -BRDA:39,8,0,1 -BRDA:40,9,0,1 -BRDA:45,10,0,3 -BRDA:51,11,0,1 -BRDA:57,12,0,1 -BRDA:67,13,0,1 -BRDA:68,14,0,1 -BRDA:69,15,0,1 -BRF:16 -BRH:16 -end_of_record -TN: -SF:src/utils/mediaQueryUtils.ts -FN:10,createMediaQuery -FN:27,addMediaListeners -FN:48,removeMediaListeners -FNF:3 -FNH:3 -FNDA:15,createMediaQuery -FNDA:10,addMediaListeners -FNDA:10,removeMediaListeners -DA:10,1 -DA:11,15 -DA:13,15 -DA:14,15 -DA:15,15 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,15 -DA:27,1 -DA:28,10 -DA:29,10 -DA:30,10 -DA:31,10 -DA:32,10 -DA:34,9 -DA:35,9 -DA:36,9 -DA:37,10 -DA:38,0 -DA:39,0 -DA:40,10 -DA:48,1 -DA:49,10 -DA:50,10 -DA:51,10 -DA:52,10 -DA:53,10 -DA:55,10 -DA:56,10 -DA:57,9 -DA:58,9 -DA:59,10 -DA:60,10 -DA:61,0 -DA:62,0 -DA:63,10 -LF:37 -LH:33 -BRDA:10,0,0,15 -BRDA:11,1,0,0 -BRDA:15,2,0,1 -BRDA:27,3,0,10 -BRDA:32,4,0,9 -BRDA:32,5,0,9 -BRDA:32,6,0,1 -BRDA:37,7,0,0 -BRDA:48,8,0,10 -BRDA:53,9,0,0 -BRDA:56,10,0,9 -BRDA:60,11,0,0 -BRF:12 -BRH:8 -end_of_record -TN: -SF:src/utils/performance.test.ts -FN:16,globalThis.performance.now -FN:63,Dummy -FNF:2 -FNH:1 -FNDA:27,globalThis.performance.now -FNDA:0,Dummy -DA:1,1 -DA:2,1 -DA:3,1 -DA:10,1 -DA:13,1 -DA:14,1 -DA:15,7 -DA:16,7 -DA:17,7 -DA:18,1 -DA:19,7 -DA:20,7 -DA:21,7 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:44,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,0 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -LF:80 -LH:79 -BRDA:14,0,0,7 -BRDA:16,1,0,27 -BRDA:18,2,0,7 -BRDA:23,3,0,1 -BRDA:24,4,0,1 -BRDA:35,5,0,1 -BRDA:44,6,0,1 -BRDA:45,7,0,1 -BRDA:46,8,0,1 -BRDA:51,9,0,1 -BRDA:55,10,0,1 -BRDA:61,11,0,1 -BRDA:62,12,0,1 -BRDA:71,13,0,1 -BRDA:72,14,0,1 -BRDA:73,15,0,1 -BRDA:79,16,0,1 -BRDA:81,17,0,1 -BRDA:88,18,0,1 -BRDA:89,19,0,1 -BRDA:94,20,0,1 -BRF:21 -BRH:21 -end_of_record -TN: -SF:src/utils/performance.ts -FN:15, -FN:15, -FN:21,getInstance -FN:31,startTiming -FN:47,logRenderTime -FN:91,getStats -FN:111,getAllEntries -FN:118,clear -FN:126,generateReport -FN:149,setEnabled -FN:160,usePerformanceMonitor -FN:186,withPerformanceMonitoring -FN:211,measureAsync -FN:245,createPerformantDebounce -FNF:14 -FNH:14 -FNDA:1, -FNDA:1, -FNDA:1,getInstance -FNDA:3,startTiming -FNDA:4,logRenderTime -FNDA:2,getStats -FNDA:2,getAllEntries -FNDA:8,clear -FNDA:1,generateReport -FNDA:2,setEnabled -FNDA:1,usePerformanceMonitor -FNDA:1,withPerformanceMonitoring -FNDA:2,measureAsync -FNDA:1,createPerformantDebounce -DA:1,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:31,1 -DA:32,3 -DA:34,3 -DA:36,3 -DA:37,4 -DA:38,4 -DA:40,4 -DA:41,4 -DA:42,3 -DA:47,1 -DA:48,4 -DA:49,4 -DA:50,4 -DA:51,4 -DA:52,4 -DA:53,4 -DA:54,4 -DA:55,4 -DA:56,4 -DA:57,4 -DA:59,4 -DA:62,4 -DA:63,0 -DA:64,0 -DA:67,4 -DA:68,3 -DA:69,3 -DA:71,4 -DA:72,4 -DA:75,4 -DA:76,0 -DA:77,0 -DA:80,4 -DA:81,2 -DA:82,2 -DA:83,2 -DA:84,2 -DA:85,2 -DA:86,4 -DA:91,1 -DA:96,2 -DA:97,2 -DA:98,2 -DA:100,2 -DA:101,2 -DA:102,2 -DA:103,2 -DA:104,2 -DA:105,2 -DA:106,2 -DA:111,1 -DA:112,2 -DA:113,2 -DA:118,1 -DA:119,8 -DA:120,8 -DA:121,8 -DA:126,1 -DA:127,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -DA:134,1 -DA:135,1 -DA:136,1 -DA:137,1 -DA:138,1 -DA:139,1 -DA:140,1 -DA:141,1 -DA:143,1 -DA:144,1 -DA:149,1 -DA:150,2 -DA:151,2 -DA:152,1 -DA:154,1 -DA:160,1 -DA:161,1 -DA:164,1 -DA:165,1 -DA:168,1 -DA:169,1 -DA:170,1 -DA:171,1 -DA:172,1 -DA:173,1 -DA:176,1 -DA:177,1 -DA:178,1 -DA:179,1 -DA:180,1 -DA:181,1 -DA:186,1 -DA:187,1 -DA:188,1 -DA:189,1 -DA:190,1 -DA:191,1 -DA:192,0 -DA:193,0 -DA:194,0 -DA:196,1 -DA:198,0 -DA:200,0 -DA:201,1 -DA:203,1 -DA:205,1 -DA:206,1 -DA:211,1 -DA:212,2 -DA:213,2 -DA:214,2 -DA:215,2 -DA:217,2 -DA:218,2 -DA:219,1 -DA:220,1 -DA:222,2 -DA:223,0 -DA:224,0 -DA:226,1 -DA:227,1 -DA:228,1 -DA:229,1 -DA:231,1 -DA:232,0 -DA:233,0 -DA:234,0 -DA:235,0 -DA:236,0 -DA:238,1 -DA:239,1 -DA:240,2 -DA:245,1 -DA:246,1 -DA:247,1 -DA:248,1 -DA:249,1 -DA:250,1 -DA:252,1 -DA:253,2 -DA:254,1 -DA:255,1 -DA:257,2 -DA:258,1 -DA:259,1 -DA:260,1 -DA:262,1 -DA:263,0 -DA:264,0 -DA:265,0 -DA:266,0 -DA:267,2 -DA:268,2 -DA:269,1 -LF:170 -LH:150 -BRDA:15,0,0,1 -BRDA:15,1,0,1 -BRDA:21,2,0,1 -BRDA:31,3,0,3 -BRDA:32,4,0,0 -BRDA:36,5,0,4 -BRDA:47,6,0,4 -BRDA:62,7,0,0 -BRDA:67,8,0,3 -BRDA:71,9,0,0 -BRDA:75,10,0,0 -BRDA:80,11,0,2 -BRDA:91,12,0,2 -BRDA:98,13,0,0 -BRDA:101,14,0,2 -BRDA:111,15,0,2 -BRDA:118,16,0,8 -BRDA:126,17,0,1 -BRDA:149,18,0,2 -BRDA:160,19,0,1 -BRDA:164,20,0,1 -BRDA:168,21,0,1 -BRDA:176,22,0,1 -BRDA:186,23,0,1 -BRDA:191,24,0,0 -BRDA:192,25,0,0 -BRDA:193,26,0,0 -BRDA:211,27,0,2 -BRDA:218,28,0,1 -BRDA:222,29,0,0 -BRDA:224,30,0,1 -BRDA:231,31,0,0 -BRDA:245,32,0,1 -BRDA:252,33,0,2 -BRDA:253,34,0,1 -BRDA:257,35,0,1 -BRDA:262,36,0,0 -BRF:37 -BRH:26 -end_of_record -TN: -SF:src/utils/timelineUtils.test.ts -FNF:0 -FNH:0 -DA:1,1 -DA:2,1 -DA:3,1 -DA:10,1 -DA:11,1 -DA:12,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:18,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:23,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:27,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:32,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,4 -DA:42,4 -DA:43,1 -DA:44,1 -DA:45,4 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:94,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:103,1 -DA:104,1 -DA:105,1 -DA:107,1 -DA:108,1 -DA:109,4 -DA:110,1 -DA:111,1 -DA:112,1 -DA:113,1 -DA:114,1 -DA:115,1 -DA:116,1 -DA:117,1 -DA:118,1 -DA:119,1 -DA:120,1 -DA:121,1 -DA:122,1 -DA:123,1 -DA:124,1 -DA:125,1 -DA:126,1 -DA:127,1 -DA:128,1 -DA:129,1 -DA:130,1 -DA:131,1 -DA:132,1 -DA:133,1 -LF:124 -LH:124 -BRDA:10,0,0,1 -BRDA:11,1,0,1 -BRDA:15,2,0,1 -BRDA:18,3,0,1 -BRDA:21,4,0,1 -BRDA:24,5,0,1 -BRDA:28,6,0,1 -BRDA:38,7,0,1 -BRDA:40,8,0,4 -BRDA:44,9,0,4 -BRDA:47,10,0,1 -BRDA:48,11,0,1 -BRDA:50,12,0,1 -BRDA:63,13,0,1 -BRDA:76,14,0,1 -BRDA:84,15,0,1 -BRDA:88,16,0,1 -BRDA:89,17,0,1 -BRDA:90,18,0,1 -BRDA:92,19,0,1 -BRDA:107,20,0,1 -BRDA:108,21,0,4 -BRDA:111,22,0,1 -BRDA:115,23,0,1 -BRDA:121,24,0,1 -BRDA:130,25,0,1 -BRF:26 -BRH:26 -end_of_record -TN: -SF:src/utils/timelineUtils.ts -FN:13,getSearchableText -FN:41,validateVideoUrl -FN:81,pauseVideoEmbeds -FN:122,toggleMediaVisibility -FN:147,findTimelineElement -FNF:5 -FNH:5 -FNDA:241,getSearchableText -FNDA:3,validateVideoUrl -FNDA:4,pauseVideoEmbeds -FNDA:3,toggleMediaVisibility -FNDA:23,findTimelineElement -DA:1,1 -DA:13,1 -DA:14,241 -DA:15,2 -DA:16,2 -DA:17,241 -DA:18,230 -DA:19,230 -DA:20,24 -DA:21,5 -DA:22,5 -DA:23,5 -DA:24,5 -DA:25,5 -DA:27,4 -DA:28,4 -DA:29,4 -DA:30,4 -DA:31,4 -DA:32,4 -DA:33,0 -DA:34,0 -DA:41,1 -DA:42,3 -DA:43,3 -DA:44,3 -DA:45,3 -DA:46,3 -DA:49,3 -DA:50,3 -DA:51,1 -DA:52,1 -DA:53,3 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:62,3 -DA:63,1 -DA:64,1 -DA:67,0 -DA:68,0 -DA:69,0 -DA:71,0 -DA:72,3 -DA:73,1 -DA:74,1 -DA:75,3 -DA:81,1 -DA:82,4 -DA:84,3 -DA:85,3 -DA:86,3 -DA:87,3 -DA:88,3 -DA:90,3 -DA:91,3 -DA:93,3 -DA:95,3 -DA:97,3 -DA:98,3 -DA:99,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:104,0 -DA:105,0 -DA:107,2 -DA:108,3 -DA:109,0 -DA:110,0 -DA:111,3 -DA:112,4 -DA:113,0 -DA:114,0 -DA:115,4 -DA:122,1 -DA:123,3 -DA:124,3 -DA:125,3 -DA:126,3 -DA:128,2 -DA:129,2 -DA:130,2 -DA:131,4 -DA:132,4 -DA:133,4 -DA:134,2 -DA:135,3 -DA:136,0 -DA:137,0 -DA:138,3 -DA:147,1 -DA:148,23 -DA:149,23 -DA:150,23 -DA:151,23 -DA:152,23 -DA:154,21 -DA:155,21 -DA:156,21 -DA:159,21 -DA:160,21 -DA:161,20 -DA:162,19 -DA:163,23 -DA:164,5 -DA:165,5 -DA:166,1 -DA:167,1 -DA:168,1 -DA:169,1 -DA:170,5 -DA:172,21 -DA:173,23 -DA:174,0 -DA:175,0 -DA:176,0 -DA:177,23 -LF:121 -LH:104 -BRDA:13,0,0,241 -BRDA:14,1,0,240 -BRDA:14,2,0,2 -BRDA:16,3,0,239 -BRDA:17,4,0,230 -BRDA:19,5,0,24 -BRDA:19,6,0,9 -BRDA:20,7,0,5 -BRDA:25,8,0,4 -BRDA:32,9,0,0 -BRDA:22,10,0,13 -BRDA:41,11,0,3 -BRDA:50,12,0,1 -BRDA:51,13,0,1 -BRDA:53,14,0,1 -BRDA:62,15,0,0 -BRDA:62,16,0,1 -BRDA:64,17,0,0 -BRDA:72,18,0,1 -BRDA:81,19,0,4 -BRDA:82,20,0,1 -BRDA:82,21,0,3 -BRDA:112,22,0,0 -BRDA:86,23,0,3 -BRDA:87,24,0,0 -BRDA:88,25,0,0 -BRDA:91,26,0,1 -BRDA:91,27,0,2 -BRDA:93,28,0,0 -BRDA:98,29,0,1 -BRDA:102,30,0,0 -BRDA:105,31,0,2 -BRDA:108,32,0,0 -BRDA:122,33,0,3 -BRDA:126,34,0,1 -BRDA:126,35,0,2 -BRDA:135,36,0,0 -BRDA:130,37,0,4 -BRDA:132,38,0,2 -BRDA:132,39,0,2 -BRDA:147,40,0,23 -BRDA:152,41,0,22 -BRDA:152,42,0,2 -BRDA:152,43,0,21 -BRDA:160,44,0,20 -BRDA:161,45,0,19 -BRDA:162,46,0,14 -BRDA:163,47,0,5 -BRDA:165,48,0,1 -BRDA:170,49,0,21 -BRDA:173,50,0,0 -BRF:51 -BRH:40 -end_of_record -TN: -SF:src/utils/utils.test.ts -FNF:0 -FNH:0 -DA:2,1 -DA:3,1 -DA:4,1 -DA:13,1 -DA:14,1 -DA:15,1 -DA:16,1 -DA:17,1 -DA:19,1 -DA:20,1 -DA:21,1 -DA:22,1 -DA:24,1 -DA:25,1 -DA:26,1 -DA:28,1 -DA:29,1 -DA:30,1 -DA:31,1 -DA:33,1 -DA:34,1 -DA:35,1 -DA:36,1 -DA:37,1 -DA:38,1 -DA:39,1 -DA:40,1 -DA:41,1 -DA:42,1 -DA:43,1 -DA:45,1 -DA:46,1 -DA:47,1 -DA:48,1 -DA:49,1 -DA:50,1 -DA:51,1 -DA:52,1 -DA:53,1 -DA:54,1 -DA:55,1 -DA:56,1 -DA:57,1 -DA:58,1 -DA:59,1 -DA:60,1 -DA:61,1 -DA:62,1 -DA:63,1 -DA:64,1 -DA:65,1 -DA:66,1 -DA:67,1 -DA:68,1 -DA:69,1 -DA:70,1 -DA:71,1 -DA:72,1 -DA:73,1 -DA:74,1 -DA:75,1 -DA:76,1 -DA:77,1 -DA:78,1 -DA:79,1 -DA:80,1 -DA:81,1 -DA:82,1 -DA:83,1 -DA:84,1 -DA:85,1 -DA:86,1 -DA:87,1 -DA:88,1 -DA:89,1 -DA:90,1 -DA:91,1 -DA:92,1 -DA:93,1 -DA:95,1 -DA:96,1 -DA:97,1 -DA:98,1 -DA:100,1 -DA:101,1 -DA:102,1 -DA:104,1 -DA:105,1 -DA:106,1 -DA:107,1 -LF:90 -LH:90 -BRDA:13,0,0,1 -BRDA:14,1,0,1 -BRDA:19,2,0,1 -BRDA:24,3,0,1 -BRDA:28,4,0,1 -BRDA:33,5,0,1 -BRDA:45,6,0,1 -BRDA:95,7,0,1 -BRDA:100,8,0,1 -BRDA:104,9,0,1 -BRF:10 -BRH:10 -end_of_record diff --git a/coverage/prettify.css b/coverage/prettify.css deleted file mode 100644 index b317a7cda..000000000 --- a/coverage/prettify.css +++ /dev/null @@ -1 +0,0 @@ -.pln{color:#000}@media screen{.str{color:#080}.kwd{color:#008}.com{color:#800}.typ{color:#606}.lit{color:#066}.pun,.opn,.clo{color:#660}.tag{color:#008}.atn{color:#606}.atv{color:#080}.dec,.var{color:#606}.fun{color:red}}@media print,projection{.str{color:#060}.kwd{color:#006;font-weight:bold}.com{color:#600;font-style:italic}.typ{color:#404;font-weight:bold}.lit{color:#044}.pun,.opn,.clo{color:#440}.tag{color:#006;font-weight:bold}.atn{color:#404}.atv{color:#060}}pre.prettyprint{padding:2px;border:1px solid #888}ol.linenums{margin-top:0;margin-bottom:0}li.L0,li.L1,li.L2,li.L3,li.L5,li.L6,li.L7,li.L8{list-style-type:none}li.L1,li.L3,li.L5,li.L7,li.L9{background:#eee} diff --git a/coverage/prettify.js b/coverage/prettify.js deleted file mode 100644 index b3225238f..000000000 --- a/coverage/prettify.js +++ /dev/null @@ -1,2 +0,0 @@ -/* eslint-disable */ -window.PR_SHOULD_USE_CONTINUATION=true;(function(){var h=["break,continue,do,else,for,if,return,while"];var u=[h,"auto,case,char,const,default,double,enum,extern,float,goto,int,long,register,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"];var p=[u,"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"];var l=[p,"alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,dynamic_cast,explicit,export,friend,inline,late_check,mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"];var x=[p,"abstract,boolean,byte,extends,final,finally,implements,import,instanceof,null,native,package,strictfp,super,synchronized,throws,transient"];var R=[x,"as,base,by,checked,decimal,delegate,descending,dynamic,event,fixed,foreach,from,group,implicit,in,interface,internal,into,is,lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,var"];var r="all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,true,try,unless,until,when,while,yes";var w=[p,"debugger,eval,export,function,get,null,set,undefined,var,with,Infinity,NaN"];var s="caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END";var I=[h,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"];var f=[h,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"];var H=[h,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"];var A=[l,R,w,s+I,f,H];var e=/^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\d*)/;var C="str";var z="kwd";var j="com";var O="typ";var G="lit";var L="pun";var F="pln";var m="tag";var E="dec";var J="src";var P="atn";var n="atv";var N="nocode";var M="(?:^^\\.?|[+-]|\\!|\\!=|\\!==|\\#|\\%|\\%=|&|&&|&&=|&=|\\(|\\*|\\*=|\\+=|\\,|\\-=|\\->|\\/|\\/=|:|::|\\;|<|<<|<<=|<=|=|==|===|>|>=|>>|>>=|>>>|>>>=|\\?|\\@|\\[|\\^|\\^=|\\^\\^|\\^\\^=|\\{|\\||\\|=|\\|\\||\\|\\|=|\\~|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";function k(Z){var ad=0;var S=false;var ac=false;for(var V=0,U=Z.length;V122)){if(!(al<65||ag>90)){af.push([Math.max(65,ag)|32,Math.min(al,90)|32])}if(!(al<97||ag>122)){af.push([Math.max(97,ag)&~32,Math.min(al,122)&~32])}}}}af.sort(function(av,au){return(av[0]-au[0])||(au[1]-av[1])});var ai=[];var ap=[NaN,NaN];for(var ar=0;arat[0]){if(at[1]+1>at[0]){an.push("-")}an.push(T(at[1]))}}an.push("]");return an.join("")}function W(al){var aj=al.source.match(new RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)","g"));var ah=aj.length;var an=[];for(var ak=0,am=0;ak=2&&ai==="["){aj[ak]=X(ag)}else{if(ai!=="\\"){aj[ak]=ag.replace(/[a-zA-Z]/g,function(ao){var ap=ao.charCodeAt(0);return"["+String.fromCharCode(ap&~32,ap|32)+"]"})}}}}return aj.join("")}var aa=[];for(var V=0,U=Z.length;V=0;){S[ac.charAt(ae)]=Y}}var af=Y[1];var aa=""+af;if(!ag.hasOwnProperty(aa)){ah.push(af);ag[aa]=null}}ah.push(/[\0-\uffff]/);V=k(ah)})();var X=T.length;var W=function(ah){var Z=ah.sourceCode,Y=ah.basePos;var ad=[Y,F];var af=0;var an=Z.match(V)||[];var aj={};for(var ae=0,aq=an.length;ae=5&&"lang-"===ap.substring(0,5);if(am&&!(ai&&typeof ai[1]==="string")){am=false;ap=J}if(!am){aj[ag]=ap}}var ab=af;af+=ag.length;if(!am){ad.push(Y+ab,ap)}else{var al=ai[1];var ak=ag.indexOf(al);var ac=ak+al.length;if(ai[2]){ac=ag.length-ai[2].length;ak=ac-al.length}var ar=ap.substring(5);B(Y+ab,ag.substring(0,ak),W,ad);B(Y+ab+ak,al,q(ar,al),ad);B(Y+ab+ac,ag.substring(ac),W,ad)}}ah.decorations=ad};return W}function i(T){var W=[],S=[];if(T.tripleQuotedStrings){W.push([C,/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""])}else{if(T.multiLineStrings){W.push([C,/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"])}else{W.push([C,/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"])}}if(T.verbatimStrings){S.push([C,/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null])}var Y=T.hashComments;if(Y){if(T.cStyleComments){if(Y>1){W.push([j,/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"])}else{W.push([j,/^#(?:(?:define|elif|else|endif|error|ifdef|include|ifndef|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"])}S.push([C,/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h|[a-z]\w*)>/,null])}else{W.push([j,/^#[^\r\n]*/,null,"#"])}}if(T.cStyleComments){S.push([j,/^\/\/[^\r\n]*/,null]);S.push([j,/^\/\*[\s\S]*?(?:\*\/|$)/,null])}if(T.regexLiterals){var X=("/(?=[^/*])(?:[^/\\x5B\\x5C]|\\x5C[\\s\\S]|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+/");S.push(["lang-regex",new RegExp("^"+M+"("+X+")")])}var V=T.types;if(V){S.push([O,V])}var U=(""+T.keywords).replace(/^ | $/g,"");if(U.length){S.push([z,new RegExp("^(?:"+U.replace(/[\s,]+/g,"|")+")\\b"),null])}W.push([F,/^\s+/,null," \r\n\t\xA0"]);S.push([G,/^@[a-z_$][a-z_$@0-9]*/i,null],[O,/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],[F,/^[a-z_$][a-z_$@0-9]*/i,null],[G,new RegExp("^(?:0x[a-f0-9]+|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)(?:e[+\\-]?\\d+)?)[a-z]*","i"),null,"0123456789"],[F,/^\\[\s\S]?/,null],[L,/^.[^\s\w\.$@\'\"\`\/\#\\]*/,null]);return g(W,S)}var K=i({keywords:A,hashComments:true,cStyleComments:true,multiLineStrings:true,regexLiterals:true});function Q(V,ag){var U=/(?:^|\s)nocode(?:\s|$)/;var ab=/\r\n?|\n/;var ac=V.ownerDocument;var S;if(V.currentStyle){S=V.currentStyle.whiteSpace}else{if(window.getComputedStyle){S=ac.defaultView.getComputedStyle(V,null).getPropertyValue("white-space")}}var Z=S&&"pre"===S.substring(0,3);var af=ac.createElement("LI");while(V.firstChild){af.appendChild(V.firstChild)}var W=[af];function ae(al){switch(al.nodeType){case 1:if(U.test(al.className)){break}if("BR"===al.nodeName){ad(al);if(al.parentNode){al.parentNode.removeChild(al)}}else{for(var an=al.firstChild;an;an=an.nextSibling){ae(an)}}break;case 3:case 4:if(Z){var am=al.nodeValue;var aj=am.match(ab);if(aj){var ai=am.substring(0,aj.index);al.nodeValue=ai;var ah=am.substring(aj.index+aj[0].length);if(ah){var ak=al.parentNode;ak.insertBefore(ac.createTextNode(ah),al.nextSibling)}ad(al);if(!ai){al.parentNode.removeChild(al)}}}break}}function ad(ak){while(!ak.nextSibling){ak=ak.parentNode;if(!ak){return}}function ai(al,ar){var aq=ar?al.cloneNode(false):al;var ao=al.parentNode;if(ao){var ap=ai(ao,1);var an=al.nextSibling;ap.appendChild(aq);for(var am=an;am;am=an){an=am.nextSibling;ap.appendChild(am)}}return aq}var ah=ai(ak.nextSibling,0);for(var aj;(aj=ah.parentNode)&&aj.nodeType===1;){ah=aj}W.push(ah)}for(var Y=0;Y=S){ah+=2}if(V>=ap){Z+=2}}}var t={};function c(U,V){for(var S=V.length;--S>=0;){var T=V[S];if(!t.hasOwnProperty(T)){t[T]=U}else{if(window.console){console.warn("cannot override language handler %s",T)}}}}function q(T,S){if(!(T&&t.hasOwnProperty(T))){T=/^\s*]*(?:>|$)/],[j,/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],[L,/^(?:<[%?]|[%?]>)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),["default-markup","htm","html","mxml","xhtml","xml","xsl"]);c(g([[F,/^[\s]+/,null," \t\r\n"],[n,/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[[m,/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],[P,/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],[L,/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);c(g([],[[n,/^[\s\S]+/]]),["uq.val"]);c(i({keywords:l,hashComments:true,cStyleComments:true,types:e}),["c","cc","cpp","cxx","cyc","m"]);c(i({keywords:"null,true,false"}),["json"]);c(i({keywords:R,hashComments:true,cStyleComments:true,verbatimStrings:true,types:e}),["cs"]);c(i({keywords:x,cStyleComments:true}),["java"]);c(i({keywords:H,hashComments:true,multiLineStrings:true}),["bsh","csh","sh"]);c(i({keywords:I,hashComments:true,multiLineStrings:true,tripleQuotedStrings:true}),["cv","py"]);c(i({keywords:s,hashComments:true,multiLineStrings:true,regexLiterals:true}),["perl","pl","pm"]);c(i({keywords:f,hashComments:true,multiLineStrings:true,regexLiterals:true}),["rb"]);c(i({keywords:w,cStyleComments:true,regexLiterals:true}),["js"]);c(i({keywords:r,hashComments:3,cStyleComments:true,multilineStrings:true,tripleQuotedStrings:true,regexLiterals:true}),["coffee"]);c(g([],[[C,/^[\s\S]+/]]),["regex"]);function d(V){var U=V.langExtension;try{var S=a(V.sourceNode);var T=S.sourceCode;V.sourceCode=T;V.spans=S.spans;V.basePos=0;q(U,T)(V);D(V)}catch(W){if("console" in window){console.log(W&&W.stack?W.stack:W)}}}function y(W,V,U){var S=document.createElement("PRE");S.innerHTML=W;if(U){Q(S,U)}var T={langExtension:V,numberLines:U,sourceNode:S};d(T);return S.innerHTML}function b(ad){function Y(af){return document.getElementsByTagName(af)}var ac=[Y("pre"),Y("code"),Y("xmp")];var T=[];for(var aa=0;aa=0){var ah=ai.match(ab);var am;if(!ah&&(am=o(aj))&&"CODE"===am.tagName){ah=am.className.match(ab)}if(ah){ah=ah[1]}var al=false;for(var ak=aj.parentNode;ak;ak=ak.parentNode){if((ak.tagName==="pre"||ak.tagName==="code"||ak.tagName==="xmp")&&ak.className&&ak.className.indexOf("prettyprint")>=0){al=true;break}}if(!al){var af=aj.className.match(/\blinenums\b(?::(\d+))?/);af=af?af[1]&&af[1].length?+af[1]:true:false;if(af){Q(aj,af)}S={langExtension:ah,sourceNode:aj,numberLines:af};d(S)}}}if(X]*(?:>|$)/],[PR.PR_COMMENT,/^<\!--[\s\S]*?(?:-\->|$)/],[PR.PR_PUNCTUATION,/^(?:<[%?]|[%?]>)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["lang-",/^]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-handlebars",/^]*type\s*=\s*['"]?text\/x-handlebars-template['"]?\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-js",/^]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i],[PR.PR_DECLARATION,/^{{[#^>/]?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{&?\s*[\w.][^}]*}}/],[PR.PR_DECLARATION,/^{{{>?\s*[\w.][^}]*}}}/],[PR.PR_COMMENT,/^{{![^}]*}}/]]),["handlebars","hbs"]);PR.registerLangHandler(PR.createSimpleLexer([[PR.PR_PLAIN,/^[ \t\r\n\f]+/,null," \t\r\n\f"]],[[PR.PR_STRING,/^\"(?:[^\n\r\f\\\"]|\\(?:\r\n?|\n|\f)|\\[\s\S])*\"/,null],[PR.PR_STRING,/^\'(?:[^\n\r\f\\\']|\\(?:\r\n?|\n|\f)|\\[\s\S])*\'/,null],["lang-css-str",/^url\(([^\)\"\']*)\)/i],[PR.PR_KEYWORD,/^(?:url|rgb|\!important|@import|@page|@media|@charset|inherit)(?=[^\-\w]|$)/i,null],["lang-css-kw",/^(-?(?:[_a-z]|(?:\\[0-9a-f]+ ?))(?:[_a-z0-9\-]|\\(?:\\[0-9a-f]+ ?))*)\s*:/i],[PR.PR_COMMENT,/^\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\//],[PR.PR_COMMENT,/^(?:)/],[PR.PR_LITERAL,/^(?:\d+|\d*\.\d+)(?:%|[a-z]+)?/i],[PR.PR_LITERAL,/^#(?:[0-9a-f]{3}){1,2}/i],[PR.PR_PLAIN,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i],[PR.PR_PUNCTUATION,/^[^\s\w\'\"]+/]]),["css"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_KEYWORD,/^-?(?:[_a-z]|(?:\\[\da-f]+ ?))(?:[_a-z\d\-]|\\(?:\\[\da-f]+ ?))*/i]]),["css-kw"]);PR.registerLangHandler(PR.createSimpleLexer([],[[PR.PR_STRING,/^[^\)\"\']+/]]),["css-str"]); diff --git a/coverage/sort-arrow-sprite.png b/coverage/sort-arrow-sprite.png deleted file mode 100644 index 6ed68316eb3f65dec9063332d2f69bf3093bbfab..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^>_9Bd!3HEZxJ@+%Qh}Z>jv*C{$p!i!8j}?a+@3A= zIAGwzjijN=FBi!|L1t?LM;Q;gkwn>2cAy-KV{dn nf0J1DIvEHQu*n~6U}x}qyky7vi4|9XhBJ7&`njxgN@xNA8m%nc diff --git a/coverage/sorter.js b/coverage/sorter.js deleted file mode 100644 index 2bb296a8c..000000000 --- a/coverage/sorter.js +++ /dev/null @@ -1,196 +0,0 @@ -/* eslint-disable */ -var addSorting = (function() { - 'use strict'; - var cols, - currentSort = { - index: 0, - desc: false - }; - - // returns the summary table element - function getTable() { - return document.querySelector('.coverage-summary'); - } - // returns the thead element of the summary table - function getTableHeader() { - return getTable().querySelector('thead tr'); - } - // returns the tbody element of the summary table - function getTableBody() { - return getTable().querySelector('tbody'); - } - // returns the th element for nth column - function getNthColumn(n) { - return getTableHeader().querySelectorAll('th')[n]; - } - - function onFilterInput() { - const searchValue = document.getElementById('fileSearch').value; - const rows = document.getElementsByTagName('tbody')[0].children; - for (let i = 0; i < rows.length; i++) { - const row = rows[i]; - if ( - row.textContent - .toLowerCase() - .includes(searchValue.toLowerCase()) - ) { - row.style.display = ''; - } else { - row.style.display = 'none'; - } - } - } - - // loads the search box - function addSearchBox() { - var template = document.getElementById('filterTemplate'); - var templateClone = template.content.cloneNode(true); - templateClone.getElementById('fileSearch').oninput = onFilterInput; - template.parentElement.appendChild(templateClone); - } - - // loads all columns - function loadColumns() { - var colNodes = getTableHeader().querySelectorAll('th'), - colNode, - cols = [], - col, - i; - - for (i = 0; i < colNodes.length; i += 1) { - colNode = colNodes[i]; - col = { - key: colNode.getAttribute('data-col'), - sortable: !colNode.getAttribute('data-nosort'), - type: colNode.getAttribute('data-type') || 'string' - }; - cols.push(col); - if (col.sortable) { - col.defaultDescSort = col.type === 'number'; - colNode.innerHTML = - colNode.innerHTML + ''; - } - } - return cols; - } - // attaches a data attribute to every tr element with an object - // of data values keyed by column name - function loadRowData(tableRow) { - var tableCols = tableRow.querySelectorAll('td'), - colNode, - col, - data = {}, - i, - val; - for (i = 0; i < tableCols.length; i += 1) { - colNode = tableCols[i]; - col = cols[i]; - val = colNode.getAttribute('data-value'); - if (col.type === 'number') { - val = Number(val); - } - data[col.key] = val; - } - return data; - } - // loads all row data - function loadData() { - var rows = getTableBody().querySelectorAll('tr'), - i; - - for (i = 0; i < rows.length; i += 1) { - rows[i].data = loadRowData(rows[i]); - } - } - // sorts the table using the data for the ith column - function sortByIndex(index, desc) { - var key = cols[index].key, - sorter = function(a, b) { - a = a.data[key]; - b = b.data[key]; - return a < b ? -1 : a > b ? 1 : 0; - }, - finalSorter = sorter, - tableBody = document.querySelector('.coverage-summary tbody'), - rowNodes = tableBody.querySelectorAll('tr'), - rows = [], - i; - - if (desc) { - finalSorter = function(a, b) { - return -1 * sorter(a, b); - }; - } - - for (i = 0; i < rowNodes.length; i += 1) { - rows.push(rowNodes[i]); - tableBody.removeChild(rowNodes[i]); - } - - rows.sort(finalSorter); - - for (i = 0; i < rows.length; i += 1) { - tableBody.appendChild(rows[i]); - } - } - // removes sort indicators for current column being sorted - function removeSortIndicators() { - var col = getNthColumn(currentSort.index), - cls = col.className; - - cls = cls.replace(/ sorted$/, '').replace(/ sorted-desc$/, ''); - col.className = cls; - } - // adds sort indicators for current column being sorted - function addSortIndicators() { - getNthColumn(currentSort.index).className += currentSort.desc - ? ' sorted-desc' - : ' sorted'; - } - // adds event listeners for all sorter widgets - function enableUI() { - var i, - el, - ithSorter = function ithSorter(i) { - var col = cols[i]; - - return function() { - var desc = col.defaultDescSort; - - if (currentSort.index === i) { - desc = !currentSort.desc; - } - sortByIndex(i, desc); - removeSortIndicators(); - currentSort.index = i; - currentSort.desc = desc; - addSortIndicators(); - }; - }; - for (i = 0; i < cols.length; i += 1) { - if (cols[i].sortable) { - // add the click event handler on the th so users - // dont have to click on those tiny arrows - el = getNthColumn(i).querySelector('.sorter').parentElement; - if (el.addEventListener) { - el.addEventListener('click', ithSorter(i)); - } else { - el.attachEvent('onclick', ithSorter(i)); - } - } - } - } - // adds sorting functionality to the UI - return function() { - if (!getTable()) { - return; - } - cols = loadColumns(); - loadData(); - addSearchBox(); - addSortIndicators(); - enableUI(); - }; -})(); - -window.addEventListener('load', addSorting); diff --git a/coverage/utils/index.html b/coverage/utils/index.html deleted file mode 100644 index 8afdca4b3..000000000 --- a/coverage/utils/index.html +++ /dev/null @@ -1,221 +0,0 @@ - - - - - - Code coverage report for utils - - - - - - - - - -
-
-

All files utils

-
- -
- 91.77% - Statements - 748/815 -
- - -
- 83.93% - Branches - 162/193 -
- - -
- 90.62% - Functions - 29/32 -
- - -
- 91.77% - Lines - 748/815 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
FileStatementsBranchesFunctionsLines
index.ts -
-
81.06%107/13275%15/2075%6/881.06%107/132
mediaQueryUtils.test.ts -
-
100%61/61100%16/16100%0/0100%61/61
mediaQueryUtils.ts -
-
89.18%33/3766.66%8/12100%3/389.18%33/37
performance.test.ts -
-
98.75%79/80100%21/2150%1/298.75%79/80
performance.ts -
-
88.23%150/17070.27%26/37100%14/1488.23%150/170
timelineUtils.test.ts -
-
100%124/124100%26/26100%0/0100%124/124
timelineUtils.ts -
-
85.95%104/12178.43%40/51100%5/585.95%104/121
utils.test.ts -
-
100%90/90100%10/10100%0/0100%90/90
-
-
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/index.ts.html b/coverage/utils/index.ts.html deleted file mode 100644 index 98c6e4e98..000000000 --- a/coverage/utils/index.ts.html +++ /dev/null @@ -1,715 +0,0 @@ - - - - - - Code coverage report for utils/index.ts - - - - - - - - - -
-
-

All files / utils index.ts

-
- -
- 81.06% - Statements - 107/132 -
- - -
- 75% - Branches - 15/20 -
- - -
- 75% - Functions - 6/8 -
- - -
- 81.06% - Lines - 107/132 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211  -  -  -  -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -  -1x -  -  -1x -1x -1x -  -  -  -  -  -  -  -1x -  -61x -  -  -  -  -61x -6x -6x -6x -  -  -55x -55x -55x -55x -  -  -55x -  -55x -55x -  -  -  -  -  -  -1x -10x -  -  -  -  -  -1x -  -  -  -  -  -1x -  -  -  -  -  -  -1x -6x -6x -3x -6x -6x -6x -3x -6x -6x -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -1x -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -  -20x -20x -20x -20x -  -20x -20x -20x -20x -20x -  -  -20x -  -  -  -  -  -  -  -  -  -  -  -  -20x -20x -  -  -  -  -  -  -20x -  -20x -20x - 
import {
-  ButtonTexts,
-  SlideShowType,
-  TimelineMode,
-} from '@models/TimelineModel';
-import xss from 'xss';
-import { darkTheme, defaultTheme } from '../components/common/themes';
- 
-// Constants to avoid creating new objects on every function call
-const DEFAULT_CLASS_NAMES = Object.freeze({
-  card: 'rc-card',
-  cardMedia: 'rc-card-media',
-  cardSubTitle: 'rc-card-subtitle',
-  cardText: 'rc-card-text',
-  cardTitle: 'rc-card-title',
-  controls: 'rc-controls',
-  title: 'rc-title',
-} as const);
- 
-const DEFAULT_BUTTON_TEXTS: Readonly<ButtonTexts> = Object.freeze({
-  changeDensity: 'Change density',
-  changeDensityOptions: Object.freeze({
-    high: Object.freeze({
-      helpText: 'Show more items at once',
-      text: 'High',
-    }),
-    low: Object.freeze({
-      helpText: 'Show fewer items at once',
-      text: 'Low',
-    }),
-  }),
-  changeLayout: 'Change layout',
-  changeLayoutOptions: Object.freeze({
-    alternating: Object.freeze({
-      helpText: 'Show cards in a vertical layout with alternating fashion',
-      text: 'Alternating',
-    }),
-    horizontal: Object.freeze({
-      helpText: 'Show cards in a horizontal layout',
-      text: 'Horizontal',
-    }),
-    horizontal_all: Object.freeze({
-      helpText: 'Show all cards in a horizontal layout',
-      text: 'Show all cards',
-    }),
-    vertical: Object.freeze({
-      helpText: 'Show cards in a vertical layout',
-      text: 'Vertical',
-    }),
-  }),
-  dark: 'Switch to Dark Mode',
-  first: 'Go to First',
-  jumpTo: 'Jump to',
-  last: 'Go to Last',
-  light: 'Switch to Light Mode',
-  next: 'Next',
-  play: 'Play Slideshow',
-  previous: 'Previous',
-  stop: 'Stop Slideshow',
-  searchPlaceholder: 'Search Timeline',
-  searchAriaLabel: 'Search timeline content',
-  clearSearch: 'Clear Search',
-  previousMatch: 'Previous Match',
-  nextMatch: 'Next Match',
-  timelinePoint: 'Timeline point',
-});
- 
-// Pre-compiled regex for hex validation
-const HEX_COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
- 
-// Character set for ID generation
-const ID_CHARS =
-  'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-const ID_LENGTH = 7;
- 
-/**
- * Converts hex color to RGBA format
- * @param hex - Hex color code (e.g. #FFFFFF)
- * @param alpha - Opacity value between 0 and 1
- * @returns RGBA color string
- */
-export const hexToRGBA = (hex: string, alpha: number): string => {
-  // Input validation
-  if (typeof hex !== 'string' || typeof alpha !== 'number') {
-    return `rgba(0, 0, 0, ${Math.max(0, Math.min(1, alpha || 0))})`;
-  }
- 
-  // Validate hex format using regex (more efficient than manual checks)
-  if (!HEX_COLOR_REGEX.test(hex)) {
-    console.warn('Invalid hex color provided:', hex);
-    return `rgba(0, 0, 0, ${Math.max(0, Math.min(1, alpha))})`;
-  }
- 
-  // Extract RGB values directly with bit shifting (more efficient)
-  const hexValue = parseInt(hex.slice(1), 16);
-  const r = (hexValue >> 16) & 255;
-  const g = (hexValue >> 8) & 255;
-  const b = hexValue & 255;
- 
-  // Clamp alpha value between 0 and 1
-  const clampedAlpha = Math.max(0, Math.min(1, alpha));
- 
-  return `rgba(${r}, ${g}, ${b}, ${clampedAlpha})`;
-};
- 
-/**
- * Returns the appropriate theme based on dark mode preference
- * @param isDark - Whether dark mode is enabled
- * @returns Theme object
- */
-export const getDefaultThemeOrDark = (isDark?: boolean) =>
-  isDark ? darkTheme : defaultTheme;
- 
-/**
- * Returns default class names for timeline components
- * @returns Object of default CSS class names
- */
-export const getDefaultClassNames = () => DEFAULT_CLASS_NAMES;
- 
-/**
- * Returns default button text translations
- * @returns Object containing all button text strings
- */
-export const getDefaultButtonTexts = (): ButtonTexts => DEFAULT_BUTTON_TEXTS;
- 
-/**
- * Determines slideshow type based on timeline mode
- * @param mode - Timeline display mode
- * @returns Appropriate slideshow animation type
- */
-export const getSlideShowType = (mode: TimelineMode): SlideShowType => {
-  switch (mode) {
-    case 'VERTICAL_ALTERNATING':
-      return 'slide_from_sides';
-    case 'HORIZONTAL':
-    case 'VERTICAL':
-    default:
-      return 'reveal';
-  }
-};
- 
-/**
- * Type guard to check if text is an array of strings
- * @param text - Text string or array of strings
- * @returns Boolean indicating if input is string array
- */
-export const isTextArray = (text: string | string[]): text is string[] =>
-  Array.isArray(text);
- 
-/**
- * Sanitizes HTML text to prevent XSS attacks
- * @param text - Text string or array of strings to sanitize
- * @returns Sanitized text string or array
- */
-export const sanitizeHtmlText = (
-  text: string | string[],
-): string | string[] => {
-  if (!text) return '';
- 
-  try {
-    return isTextArray(text) ? text.map((t) => xss(t || '')) : xss(text);
-  } catch (error) {
-    console.error('Error sanitizing HTML text:', error);
-    return isTextArray(text) ? [] : '';
-  }
-};
- 
-/**
- * Generates a cryptographically secure random ID
- * @returns Unique string ID
- */
-export const getUniqueID = (): string => {
-  // Use crypto API if available (modern browsers)
-  if (typeof window !== 'undefined' && window.crypto?.getRandomValues) {
-    try {
-      const randomValues = new Uint8Array(ID_LENGTH);
-      window.crypto.getRandomValues(randomValues);
- 
-      return Array.from(
-        randomValues,
-        (byte) => ID_CHARS[byte % ID_CHARS.length],
-      ).join('');
-    } catch (error) {
-      console.error('Error generating unique ID:', error);
-    }
-  }
- 
-  // Fallback for environments without crypto API
-  // Using a combination of timestamp and a more robust random generation
-  const timestamp = Date.now().toString(36);
- 
-  // Use performance.now() for additional entropy if available
-  const performanceTime =
-    typeof performance !== 'undefined' && performance.now
-      ? performance.now().toString().replace('.', '')
-      : Date.now().toString();
- 
-  // Generate random part using timestamp-based seed for better distribution
-  const seed = parseInt(performanceTime.slice(-6), 10);
-  const randomPart = Array.from({ length: 8 }, (_, index) => {
-    // Simple LCG algorithm for better distribution than Math.random
-    const a = 1664525;
-    const c = 1013904223;
-    const m = Math.pow(2, 32);
-    const value = (a * (seed + index) + c) % m;
-    return ID_CHARS[value % ID_CHARS.length];
-  }).join('');
- 
-  return `id-${timestamp}-${randomPart}`;
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/mediaQueryUtils.test.ts.html b/coverage/utils/mediaQueryUtils.test.ts.html deleted file mode 100644 index e9d9547f6..000000000 --- a/coverage/utils/mediaQueryUtils.test.ts.html +++ /dev/null @@ -1,298 +0,0 @@ - - - - - - Code coverage report for utils/mediaQueryUtils.test.ts - - - - - - - - - -
-
-

All files / utils mediaQueryUtils.test.ts

-
- -
- 100% - Statements - 61/61 -
- - -
- 100% - Branches - 16/16 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 61/61 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -721x -1x -  -  -  -  -  -1x -1x -1x -1x -1x -  -1x -3x -3x -3x -3x -3x -2x -2x -2x -1x -1x -2x -2x -1x -1x -1x -1x -1x -2x -3x -3x -1x -1x -3x -3x -2x -1x -1x -3x -1x -  -1x -3x -3x -3x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import {
-  createMediaQuery,
-  addMediaListeners,
-  removeMediaListeners,
-} from './mediaQueryUtils';
- 
-describe('mediaQueryUtils', () => {
-  let originalMatchMedia: any;
-  let originalAddEventListener: any;
-  let originalRemoveEventListener: any;
-  let windowListeners: Record<string, Function[]> = {};
- 
-  beforeEach(() => {
-    originalMatchMedia = window.matchMedia;
-    originalAddEventListener = window.addEventListener;
-    originalRemoveEventListener = window.removeEventListener;
-    windowListeners = {};
-    window.matchMedia = vi.fn().mockImplementation((query) => ({
-      media: query,
-      matches: false,
-      addEventListener: vi.fn((event, cb) => {
-        windowListeners[event] = windowListeners[event] || [];
-        windowListeners[event].push(cb);
-      }),
-      removeEventListener: vi.fn((event, cb) => {
-        if (windowListeners[event]) {
-          windowListeners[event] = windowListeners[event].filter(
-            (f) => f !== cb,
-          );
-        }
-      }),
-    }));
-    window.addEventListener = vi.fn((event, cb) => {
-      windowListeners[event] = windowListeners[event] || [];
-      windowListeners[event].push(cb);
-    });
-    window.removeEventListener = vi.fn((event, cb) => {
-      if (windowListeners[event]) {
-        windowListeners[event] = windowListeners[event].filter((f) => f !== cb);
-      }
-    });
-  });
- 
-  afterEach(() => {
-    window.matchMedia = originalMatchMedia;
-    window.addEventListener = originalAddEventListener;
-    window.removeEventListener = originalRemoveEventListener;
-  });
- 
-  it('should create a media query', () => {
-    const mq = createMediaQuery('(max-width: 600px)');
-    expect(mq).toBeTruthy();
-    expect(mq?.media).toBe('(max-width: 600px)');
-  });
- 
-  it('should add and remove media listeners', () => {
-    const mq = createMediaQuery('(max-width: 600px)');
-    const handleMediaChange = vi.fn();
-    const handleResize = vi.fn();
-    addMediaListeners(mq, handleMediaChange, handleResize);
-    expect(windowListeners['resize']).toContain(handleResize);
-    removeMediaListeners(mq, handleMediaChange, handleResize);
-    expect(windowListeners['resize']).not.toContain(handleResize);
-  });
- 
-  it('should handle null media query gracefully', () => {
-    expect(() => addMediaListeners(null, vi.fn(), vi.fn())).not.toThrow();
-    expect(() => removeMediaListeners(null, vi.fn(), vi.fn())).not.toThrow();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/mediaQueryUtils.ts.html b/coverage/utils/mediaQueryUtils.ts.html deleted file mode 100644 index fcfc6d7c8..000000000 --- a/coverage/utils/mediaQueryUtils.ts.html +++ /dev/null @@ -1,274 +0,0 @@ - - - - - - Code coverage report for utils/mediaQueryUtils.ts - - - - - - - - - -
-
-

All files / utils mediaQueryUtils.ts

-
- -
- 89.18% - Statements - 33/37 -
- - -
- 66.66% - Branches - 8/12 -
- - -
- 100% - Functions - 3/3 -
- - -
- 89.18% - Lines - 33/37 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64  -  -  -  -  -  -  -  -  -1x -15x -  -15x -15x -15x -1x -1x -1x -15x -  -  -  -  -  -  -  -1x -10x -10x -10x -10x -10x -  -9x -9x -9x -10x -  -  -10x -  -  -  -  -  -  -  -1x -10x -10x -10x -10x -10x -  -10x -10x -9x -9x -10x -10x -  -  -10x - 
/**
- * Media query utility functions for handling responsive behaviors
- */
- 
-/**
- * Creates and returns a MediaQueryList object
- * @param query - CSS media query string (e.g. '(max-width: 768px)')
- * @returns MediaQueryList object or null if browser doesn't support matchMedia
- */
-export function createMediaQuery(query: string): MediaQueryList | null {
-  if (typeof window === 'undefined') return null;
- 
-  try {
-    return window.matchMedia(query);
-  } catch (error) {
-    console.error('Error creating media query:', error);
-    return null;
-  }
-}
- 
-/**
- * Adds change and resize listeners for the provided media query
- * @param currentMedia - MediaQueryList object to attach listeners to
- * @param handleMediaChange - Callback function for media query changes
- * @param handleResize - Callback function for window resize events
- */
-export function addMediaListeners(
-  currentMedia: MediaQueryList | null,
-  handleMediaChange: (event: MediaQueryListEvent | MediaQueryList) => void,
-  handleResize: () => void,
-): void {
-  if (!currentMedia || typeof window === 'undefined') return;
- 
-  try {
-    currentMedia.addEventListener('change', handleMediaChange);
-    window.addEventListener('resize', handleResize);
-  } catch (error) {
-    console.error('Error adding media listeners:', error);
-  }
-}
- 
-/**
- * Removes change and resize listeners to prevent memory leaks
- * @param currentMedia - MediaQueryList object to detach listeners from
- * @param handleMediaChange - Callback function to remove from media query changes
- * @param handleResize - Callback function to remove from window resize events
- */
-export function removeMediaListeners(
-  currentMedia: MediaQueryList | null,
-  handleMediaChange: (event: MediaQueryListEvent | MediaQueryList) => void,
-  handleResize: () => void,
-): void {
-  if (typeof window === 'undefined') return;
- 
-  try {
-    if (currentMedia) {
-      currentMedia.removeEventListener('change', handleMediaChange);
-    }
-    window.removeEventListener('resize', handleResize);
-  } catch (error) {
-    console.error('Error removing media listeners:', error);
-  }
-}
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/performance.test.ts.html b/coverage/utils/performance.test.ts.html deleted file mode 100644 index b6cd5f3b6..000000000 --- a/coverage/utils/performance.test.ts.html +++ /dev/null @@ -1,376 +0,0 @@ - - - - - - Code coverage report for utils/performance.test.ts - - - - - - - - - -
-
-

All files / utils performance.test.ts

-
- -
- 98.75% - Statements - 79/80 -
- - -
- 100% - Branches - 21/21 -
- - -
- 50% - Functions - 1/2 -
- - -
- 98.75% - Lines - 79/80 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -981x -1x -1x -  -  -  -  -  -  -1x -  -  -1x -1x -7x -7x -7x -1x -7x -7x -7x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import React from 'react';
-import {
-  performanceMonitor,
-  usePerformanceMonitor,
-  withPerformanceMonitoring,
-  measureAsync,
-  createPerformantDebounce,
-} from './performance';
-import { renderHook, act } from '@testing-library/react';
- 
-// Mock performance.now
-const originalPerformanceNow = globalThis.performance.now;
-beforeEach(() => {
-  let now = 0;
-  globalThis.performance.now = () => (now += 10);
-});
-afterEach(() => {
-  globalThis.performance.now = originalPerformanceNow;
-  performanceMonitor.clear();
-});
- 
-describe('PerformanceMonitor', () => {
-  it('should log render times and generate report', () => {
-    performanceMonitor.setEnabled(true);
-    const end = performanceMonitor.startTiming('TestComponent');
-    end();
-    const stats = performanceMonitor.getStats('TestComponent');
-    expect(stats).toBeTruthy();
-    expect(stats?.totalRenders).toBe(1);
-    expect(performanceMonitor.getAllEntries().length).toBe(1);
-    expect(performanceMonitor.generateReport()).toContain('TestComponent');
-  });
- 
-  it('should clear all entries', () => {
-    performanceMonitor.setEnabled(true);
-    const end = performanceMonitor.startTiming('TestComponent');
-    end();
-    performanceMonitor.clear();
-    expect(performanceMonitor.getAllEntries().length).toBe(0);
-  });
-});
- 
-describe('usePerformanceMonitor', () => {
-  it('should call end timing on unmount', () => {
-    const { result, unmount } = renderHook(() =>
-      usePerformanceMonitor('HookComponent'),
-    );
-    expect(typeof result.current).toBe('function');
-    // Simulate unmount
-    act(() => {
-      unmount();
-    });
-    // Optionally, call the returned cleanup function
-    act(() => {
-      result.current();
-    });
-  });
-});
- 
-describe('withPerformanceMonitoring', () => {
-  it('should wrap a component and call usePerformanceMonitor', () => {
-    const Dummy = (props: { value: string }) =>
-      React.createElement('div', null, props.value);
-    const Wrapped = withPerformanceMonitoring(Dummy, 'Dummy');
-    const el = React.createElement(Wrapped, { value: 'test' });
-    expect(el).toBeTruthy();
-  });
-});
- 
-describe('measureAsync', () => {
-  it('should measure async operation duration', async () => {
-    const result = await measureAsync(async () => {
-      return 42;
-    }, 'TestOp');
-    expect(result).toBe(42);
-  });
- 
-  it('should throw and log on error', async () => {
-    await expect(
-      measureAsync(async () => {
-        throw new Error('fail');
-      }, 'TestOp'),
-    ).rejects.toThrow('fail');
-  });
-});
- 
-describe('createPerformantDebounce', () => {
-  it('should debounce a function and log duration', async () => {
-    const fn = vi.fn();
-    const debounced = createPerformantDebounce(fn, 10, 'debounceTest');
-    debounced();
-    debounced();
-    await new Promise((r) => setTimeout(r, 20));
-    expect(fn).toHaveBeenCalledTimes(1);
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/performance.ts.html b/coverage/utils/performance.ts.html deleted file mode 100644 index 174c2b0b2..000000000 --- a/coverage/utils/performance.ts.html +++ /dev/null @@ -1,892 +0,0 @@ - - - - - - Code coverage report for utils/performance.ts - - - - - - - - - -
-
-

All files / utils performance.ts

-
- -
- 88.23% - Statements - 150/170 -
- - -
- 70.27% - Branches - 26/37 -
- - -
- 100% - Functions - 14/14 -
- - -
- 88.23% - Lines - 150/170 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -178 -179 -180 -181 -182 -183 -184 -185 -186 -187 -188 -189 -190 -191 -192 -193 -194 -195 -196 -197 -198 -199 -200 -201 -202 -203 -204 -205 -206 -207 -208 -209 -210 -211 -212 -213 -214 -215 -216 -217 -218 -219 -220 -221 -222 -223 -224 -225 -226 -227 -228 -229 -230 -231 -232 -233 -234 -235 -236 -237 -238 -239 -240 -241 -242 -243 -244 -245 -246 -247 -248 -249 -250 -251 -252 -253 -254 -255 -256 -257 -258 -259 -260 -261 -262 -263 -264 -265 -266 -267 -268 -269 -2701x -  -  -  -  -  -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -3x -  -3x -  -3x -4x -4x -  -4x -4x -3x -  -  -  -  -1x -4x -4x -4x -4x -4x -4x -4x -4x -4x -4x -  -4x -  -  -4x -  -  -  -  -4x -3x -3x -  -4x -4x -  -  -4x -  -  -  -  -4x -2x -2x -2x -2x -2x -4x -  -  -  -  -1x -  -  -  -  -2x -2x -2x -  -2x -2x -2x -2x -2x -2x -2x -  -  -  -  -1x -2x -2x -  -  -  -  -1x -8x -8x -8x -  -  -  -  -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -  -  -  -  -1x -2x -2x -1x -  -1x -  -  -  -  -  -1x -1x -  -  -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -  -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -1x -1x -1x -1x -1x -  -  -  -  -1x -  -  -  -  -1x -  -1x -  -1x -1x -  -  -  -  -1x -2x -2x -2x -2x -  -2x -2x -1x -1x -  -2x -  -  -  -1x -1x -1x -1x -  -1x -  -  -  -  -  -  -1x -1x -2x -  -  -  -  -1x -1x -1x -1x -1x -1x -  -1x -2x -1x -1x -  -2x -1x -1x -1x -  -1x -  -  -  -  -2x -2x -1x - 
import React, { useEffect, useRef } from 'react';
- 
-/**
- * Performance monitoring utilities for React Chrono
- * Helps track component render times and identify bottlenecks
- */
- 
-interface PerformanceEntry {
-  componentName: string;
-  renderTime: number;
-  timestamp: number;
-  props?: Record<string, any>;
-}
- 
-class PerformanceMonitor {
-  private static instance: PerformanceMonitor;
-  private entries: PerformanceEntry[] = [];
-  private readonly renderTimes = new Map<string, number[]>();
-  private isEnabled = process.env.NODE_ENV === 'development';
- 
-  static getInstance(): PerformanceMonitor {
-    if (!PerformanceMonitor.instance) {
-      PerformanceMonitor.instance = new PerformanceMonitor();
-    }
-    return PerformanceMonitor.instance;
-  }
- 
-  /**
-   * Start timing a component render
-   */
-  startTiming(componentName: string): () => void {
-    if (!this.isEnabled) return () => {};
- 
-    const startTime = performance.now();
- 
-    return () => {
-      const endTime = performance.now();
-      const renderTime = endTime - startTime;
- 
-      this.logRenderTime(componentName, renderTime);
-    };
-  }
- 
-  /**
-   * Log render time for a component
-   */
-  private logRenderTime(
-    componentName: string,
-    renderTime: number,
-    props?: Record<string, any>,
-  ): void {
-    const entry: PerformanceEntry = {
-      componentName,
-      renderTime,
-      timestamp: Date.now(),
-      props,
-    };
- 
-    this.entries.push(entry);
- 
-    // Keep only last 100 entries to prevent memory leaks
-    if (this.entries.length > 100) {
-      this.entries = this.entries.slice(-100);
-    }
- 
-    // Track render times per component
-    if (!this.renderTimes.has(componentName)) {
-      this.renderTimes.set(componentName, []);
-    }
- 
-    const times = this.renderTimes.get(componentName) ?? [];
-    times.push(renderTime);
- 
-    // Keep only last 20 render times per component
-    if (times.length > 20) {
-      times.splice(0, times.length - 20);
-    }
- 
-    // Log slow renders (>16ms for 60fps)
-    if (renderTime > 16) {
-      console.warn(
-        `🐌 Slow render detected: ${componentName} took ${renderTime.toFixed(2)}ms`,
-        { renderTime, props },
-      );
-    }
-  }
- 
-  /**
-   * Get performance statistics for a component
-   */
-  getStats(componentName: string): {
-    averageRenderTime: number;
-    maxRenderTime: number;
-    minRenderTime: number;
-    totalRenders: number;
-  } | null {
-    const times = this.renderTimes.get(componentName);
-    if (!times || times.length === 0) return null;
- 
-    return {
-      averageRenderTime: times.reduce((a, b) => a + b, 0) / times.length,
-      maxRenderTime: Math.max(...times),
-      minRenderTime: Math.min(...times),
-      totalRenders: times.length,
-    };
-  }
- 
-  /**
-   * Get all performance entries
-   */
-  getAllEntries(): PerformanceEntry[] {
-    return [...this.entries];
-  }
- 
-  /**
-   * Clear all performance data
-   */
-  clear(): void {
-    this.entries = [];
-    this.renderTimes.clear();
-  }
- 
-  /**
-   * Generate performance report
-   */
-  generateReport(): string {
-    const report = ['=== React Chrono Performance Report ===\n'];
- 
-    for (const [componentName] of this.renderTimes.entries()) {
-      const stats = this.getStats(componentName);
-      if (stats) {
-        report.push(
-          `📊 ${componentName}:`,
-          `  • Average: ${stats.averageRenderTime.toFixed(2)}ms`,
-          `  • Max: ${stats.maxRenderTime.toFixed(2)}ms`,
-          `  • Min: ${stats.minRenderTime.toFixed(2)}ms`,
-          `  • Total Renders: ${stats.totalRenders}`,
-          '',
-        );
-      }
-    }
- 
-    return report.join('\n');
-  }
- 
-  /**
-   * Enable/disable performance monitoring
-   */
-  setEnabled(enabled: boolean): void {
-    this.isEnabled = enabled;
-  }
-}
- 
-export const performanceMonitor = PerformanceMonitor.getInstance();
- 
-/**
- * React hook for performance monitoring
- * Use this hook to time component renders
- */
-export const usePerformanceMonitor = (componentName: string) => {
-  const endTimingRef = useRef<(() => void) | null>(null);
- 
-  // Start timing on mount and re-renders
-  useEffect(() => {
-    endTimingRef.current = performanceMonitor.startTiming(componentName);
- 
-    // Return cleanup function
-    return () => {
-      if (endTimingRef.current) {
-        endTimingRef.current();
-      }
-    };
-  });
- 
-  // Return cleanup function for manual usage if needed
-  return () => {
-    if (endTimingRef.current) {
-      endTimingRef.current();
-    }
-  };
-};
- 
-/**
- * Higher-order component for performance monitoring
- */
-export function withPerformanceMonitoring<P extends Record<string, any>>(
-  WrappedComponent: React.ComponentType<P>,
-  componentName?: string,
-): React.FC<P> {
-  const displayName =
-    componentName ??
-    WrappedComponent.displayName ??
-    WrappedComponent.name ??
-    'Component';
- 
-  const MemoizedComponent: React.FC<P> = React.memo((props: P) => {
-    // Use the performance monitoring hook
-    usePerformanceMonitor(displayName);
- 
-    return React.createElement(WrappedComponent, props);
-  });
- 
-  MemoizedComponent.displayName = `withPerformanceMonitoring(${displayName})`;
- 
-  return MemoizedComponent;
-}
- 
-/**
- * Utility to measure async operations
- */
-export const measureAsync = async <T>(
-  operation: () => Promise<T>,
-  operationName: string,
-): Promise<T> => {
-  const startTime = performance.now();
- 
-  try {
-    const result = await operation();
-    const endTime = performance.now();
-    const duration = endTime - startTime;
- 
-    if (process.env.NODE_ENV === 'development') {
-      console.log(`⏱️ ${operationName} completed in ${duration.toFixed(2)}ms`);
-    }
- 
-    return result;
-  } catch (error) {
-    const endTime = performance.now();
-    const duration = endTime - startTime;
- 
-    if (process.env.NODE_ENV === 'development') {
-      console.error(
-        `❌ ${operationName} failed after ${duration.toFixed(2)}ms`,
-        error,
-      );
-    }
- 
-    throw error;
-  }
-};
- 
-/**
- * Debounce utility with performance monitoring
- */
-export const createPerformantDebounce = <T extends (...args: any[]) => any>(
-  func: T,
-  delay: number,
-  operationName: string,
-): ((...args: Parameters<T>) => void) => {
-  let timeoutId: NodeJS.Timeout | undefined;
- 
-  return (...args: Parameters<T>) => {
-    if (timeoutId) {
-      clearTimeout(timeoutId);
-    }
- 
-    timeoutId = setTimeout(() => {
-      const startTime = performance.now();
-      func(...args);
-      const endTime = performance.now();
- 
-      if (process.env.NODE_ENV === 'development') {
-        console.log(
-          `🔄 Debounced ${operationName} executed in ${(endTime - startTime).toFixed(2)}ms`,
-        );
-      }
-    }, delay);
-  };
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/timelineUtils.test.ts.html b/coverage/utils/timelineUtils.test.ts.html deleted file mode 100644 index da681bfc9..000000000 --- a/coverage/utils/timelineUtils.test.ts.html +++ /dev/null @@ -1,484 +0,0 @@ - - - - - - Code coverage report for utils/timelineUtils.test.ts - - - - - - - - - -
-
-

All files / utils timelineUtils.test.ts

-
- -
- 100% - Statements - 124/124 -
- - -
- 100% - Branches - 26/26 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 124/124 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -1341x -1x -1x -  -  -  -  -  -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -4x -4x -1x -1x -4x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -4x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x - 
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
-import React from 'react';
-import {
-  getSearchableText,
-  pauseVideoEmbeds,
-  toggleMediaVisibility,
-  findTimelineElement,
-} from './timelineUtils';
- 
-describe('getSearchableText', () => {
-  it('returns empty string for null/undefined', () => {
-    expect(getSearchableText(null)).toBe('');
-    expect(getSearchableText(undefined)).toBe('');
-  });
-  it('returns string as is', () => {
-    expect(getSearchableText('hello')).toBe('hello');
-  });
-  it('joins array of strings', () => {
-    expect(getSearchableText(['a', 'b', 'c'])).toBe('a b c');
-  });
-  it('recursively extracts text from nested arrays', () => {
-    expect(getSearchableText(['a', ['b', 'c'], 'd'])).toBe('a b c d');
-  });
-  it('extracts text from React elements', () => {
-    const el = React.createElement('span', null, 'foo');
-    expect(getSearchableText(el)).toBe('foo');
-  });
-  it('extracts text from nested React elements', () => {
-    const el = React.createElement('div', null, [
-      'a',
-      React.createElement('span', { key: 'span' }, 'b'),
-      ['c', React.createElement('em', { key: 'em' }, 'd')],
-    ]);
-    expect(getSearchableText(el)).toBe('a b c d');
-  });
-});
- 
-describe('pauseVideoEmbeds', () => {
-  let origConsoleError: any;
-  beforeEach(() => {
-    origConsoleError = console.error;
-    console.error = vi.fn();
-  });
-  afterEach(() => {
-    console.error = origConsoleError;
-  });
-  it('does nothing if element is null', () => {
-    expect(() => pauseVideoEmbeds(null)).not.toThrow();
-  });
-  it('sends postMessage to valid YouTube iframe', () => {
-    const postMessage = vi.fn();
-    const iframe = document.createElement('iframe');
-    iframe.setAttribute('src', 'https://www.youtube.com/embed/xyz');
-    Object.defineProperty(iframe, 'contentWindow', { value: { postMessage } });
-    const container = document.createElement('div');
-    container.appendChild(iframe);
-    pauseVideoEmbeds(container);
-    expect(postMessage).toHaveBeenCalledWith(
-      '{"event":"command","func":"stopVideo","args":""}',
-      'https://www.youtube.com',
-    );
-  });
-  it('sends postMessage to valid Vimeo iframe', () => {
-    const postMessage = vi.fn();
-    const iframe = document.createElement('iframe');
-    iframe.setAttribute('src', 'https://vimeo.com/video/xyz');
-    Object.defineProperty(iframe, 'contentWindow', { value: { postMessage } });
-    const container = document.createElement('div');
-    container.appendChild(iframe);
-    pauseVideoEmbeds(container);
-    expect(postMessage).toHaveBeenCalledWith(
-      '{"method":"pause"}',
-      'https://vimeo.com',
-    );
-  });
-  it('handles invalid iframe src gracefully', () => {
-    const iframe = document.createElement('iframe');
-    iframe.setAttribute('src', 'not-a-valid-url');
-    Object.defineProperty(iframe, 'contentWindow', {
-      value: { postMessage: vi.fn() },
-    });
-    const container = document.createElement('div');
-    container.appendChild(iframe);
-    expect(() => pauseVideoEmbeds(container)).not.toThrow();
-  });
-});
- 
-describe('toggleMediaVisibility', () => {
-  it('does nothing if element is null', () => {
-    expect(() => toggleMediaVisibility(null, true)).not.toThrow();
-  });
-  it('toggles visibility of images and videos', () => {
-    const img = document.createElement('img');
-    const video = document.createElement('video');
-    const div = document.createElement('div');
-    div.appendChild(img);
-    div.appendChild(video);
-    toggleMediaVisibility(div, false);
-    expect(img.style.visibility).toBe('hidden');
-    expect(video.style.visibility).toBe('hidden');
-    toggleMediaVisibility(div, true);
-    expect(img.style.visibility).toBe('visible');
-    expect(video.style.visibility).toBe('visible');
-  });
-});
- 
-describe('findTimelineElement', () => {
-  beforeEach(() => {
-    document.body.innerHTML = '';
-  });
-  it('returns null for missing itemId or timelineMode', () => {
-    expect(findTimelineElement('', 'VERTICAL', '')).toBeNull();
-    expect(findTimelineElement('id', '', '')).toBeNull();
-  });
-  it('finds element by id for vertical mode', () => {
-    const el = document.createElement('div');
-    el.id = 'timeline-vertical-item-foo';
-    document.body.appendChild(el);
-    expect(findTimelineElement('foo', 'VERTICAL', '')).toBe(el);
-  });
-  it('finds element in portal for horizontal mode', () => {
-    const portal = document.createElement('div');
-    portal.id = 'portal';
-    const card = document.createElement('div');
-    card.id = 'timeline-card-bar';
-    portal.appendChild(card);
-    document.body.appendChild(portal);
-    expect(findTimelineElement('bar', 'HORIZONTAL', 'portal')).toBe(card);
-  });
-  it('returns null if not found', () => {
-    expect(findTimelineElement('notfound', 'VERTICAL', '')).toBeNull();
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/timelineUtils.ts.html b/coverage/utils/timelineUtils.ts.html deleted file mode 100644 index fc59fb33e..000000000 --- a/coverage/utils/timelineUtils.ts.html +++ /dev/null @@ -1,616 +0,0 @@ - - - - - - Code coverage report for utils/timelineUtils.ts - - - - - - - - - -
-
-

All files / utils timelineUtils.ts

-
- -
- 85.95% - Statements - 104/121 -
- - -
- 78.43% - Branches - 40/51 -
- - -
- 100% - Functions - 5/5 -
- - -
- 85.95% - Lines - 104/121 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108 -109 -110 -111 -112 -113 -114 -115 -116 -117 -118 -119 -120 -121 -122 -123 -124 -125 -126 -127 -128 -129 -130 -131 -132 -133 -134 -135 -136 -137 -138 -139 -140 -141 -142 -143 -144 -145 -146 -147 -148 -149 -150 -151 -152 -153 -154 -155 -156 -157 -158 -159 -160 -161 -162 -163 -164 -165 -166 -167 -168 -169 -170 -171 -172 -173 -174 -175 -176 -177 -1781x -  -  -  -  -  -  -  -  -  -  -  -1x -241x -2x -2x -241x -230x -230x -24x -5x -5x -5x -5x -5x -  -4x -4x -4x -4x -4x -4x -  -  -  -  -  -  -  -  -1x -3x -3x -3x -3x -3x -  -  -3x -3x -1x -1x -3x -1x -1x -1x -1x -1x -1x -  -  -3x -1x -1x -  -  -  -  -  -  -  -3x -1x -1x -3x -  -  -  -  -  -1x -4x -  -3x -3x -3x -3x -3x -  -3x -3x -  -3x -  -3x -  -3x -3x -1x -1x -1x -1x -  -  -  -  -2x -3x -  -  -3x -4x -  -  -4x -  -  -  -  -  -  -1x -3x -3x -3x -3x -  -2x -2x -2x -4x -4x -4x -2x -3x -  -  -3x -  -  -  -  -  -  -  -  -1x -23x -23x -23x -23x -23x -  -21x -21x -21x -  -  -21x -21x -20x -19x -23x -5x -5x -1x -1x -1x -1x -5x -  -21x -23x -  -  -  -23x - 
import React from 'react';
- 
-/**
- * Timeline utility functions for managing timeline functionality
- */
- 
-/**
- * Safely extracts searchable text from potentially complex React node content
- * Recursively processes React nodes into plain text for search operations
- * @param content - React node (string, array, or component) to extract text from
- * @returns Plain text string suitable for searching
- */
-export const getSearchableText = (content: React.ReactNode): string => {
-  if (content === null || content === undefined) {
-    return '';
-  }
-  if (typeof content === 'string') {
-    return content;
-  }
-  if (Array.isArray(content)) {
-    return content
-      .map((item) => getSearchableText(item))
-      .filter(Boolean)
-      .join(' ');
-  }
-  // Handle React elements with children or other complex node types
-  if (React.isValidElement(content)) {
-    const elementProps = content.props as { children?: React.ReactNode };
-    if (elementProps.children) {
-      return getSearchableText(elementProps.children);
-    }
-  }
-  return '';
-};
- 
-/**
- * Safely validates if a URL belongs to a trusted video platform
- * @param url - URL to validate
- * @returns Object with validation result and platform info
- */
-const validateVideoUrl = (
-  url: string,
-): { isValid: boolean; platform?: string; origin?: string } => {
-  try {
-    const parsedUrl = new URL(url);
-    const hostname = parsedUrl.hostname.toLowerCase();
- 
-    // YouTube domains
-    if (
-      hostname === 'www.youtube.com' ||
-      hostname === 'youtube.com' ||
-      hostname === 'youtu.be'
-    ) {
-      return {
-        isValid: true,
-        platform: 'youtube',
-        origin: 'https://www.youtube.com',
-      };
-    }
- 
-    // Vimeo domains
-    if (hostname === 'vimeo.com' || hostname === 'player.vimeo.com') {
-      return { isValid: true, platform: 'vimeo', origin: 'https://vimeo.com' };
-    }
- 
-    // For other HTTPS origins, return the actual origin
-    if (parsedUrl.protocol === 'https:') {
-      return { isValid: true, platform: 'other', origin: parsedUrl.origin };
-    }
- 
-    return { isValid: false };
-  } catch {
-    return { isValid: false };
-  }
-};
- 
-/**
- * Pauses video embeds (primarily YouTube) within an element
- * @param element - HTML element containing video iframes to pause
- */
-export const pauseVideoEmbeds = (element: HTMLElement | null): void => {
-  if (!element) return;
- 
-  try {
-    const iframes = element.querySelectorAll('iframe');
-    iframes.forEach((iframe) => {
-      const src = iframe.getAttribute('src') || '';
-      if (!src || !iframe.contentWindow) return;
- 
-      const validation = validateVideoUrl(src);
-      if (!validation.isValid) return;
- 
-      const targetOrigin = validation.origin || '*';
- 
-      try {
-        // Send appropriate pause command based on platform
-        let message = '';
-        if (validation.platform === 'youtube') {
-          message = '{"event":"command","func":"stopVideo","args":""}';
-        } else if (validation.platform === 'vimeo') {
-          message = '{"method":"pause"}';
-        } else {
-          // Generic pause attempt for other platforms
-          message = '{"event":"command","func":"pause","args":""}';
-        }
- 
-        iframe.contentWindow.postMessage(message, targetOrigin);
-      } catch (error) {
-        console.error('Error sending message to iframe:', error);
-      }
-    });
-  } catch (error) {
-    console.error('Error pausing video embeds:', error);
-  }
-};
- 
-/**
- * Toggles visibility of media elements (images and videos) within an element
- * @param element - HTML element containing media elements
- * @param isVisible - Whether media elements should be visible
- */
-export const toggleMediaVisibility = (
-  element: HTMLElement | null,
-  isVisible: boolean,
-): void => {
-  if (!element) return;
- 
-  try {
-    const mediaElements = element.querySelectorAll('img,video');
-    mediaElements.forEach((ele) => {
-      if (ele instanceof HTMLElement) {
-        ele.style.visibility = isVisible ? 'visible' : 'hidden';
-      }
-    });
-  } catch (error) {
-    console.error('Error toggling media visibility:', error);
-  }
-};
- 
-/**
- * Finds a timeline item element by its ID in either the main timeline or portal
- * @param itemId - ID of the timeline item to find
- * @param timelineMode - Current timeline mode (HORIZONTAL, VERTICAL, etc.)
- * @param portalId - ID of the portal container for horizontal timeline modes
- * @returns HTML element of the timeline item or null if not found
- */
-export const findTimelineElement = (
-  itemId: string,
-  timelineMode: string,
-  portalId: string,
-): HTMLElement | null => {
-  if (!itemId || !timelineMode) return null;
- 
-  try {
-    const elementId = `timeline-${timelineMode.toLowerCase()}-item-${itemId}`;
-    let targetElement = document.getElementById(elementId);
- 
-    // Check in portal for horizontal modes
-    if (
-      !targetElement &&
-      portalId &&
-      (timelineMode === 'HORIZONTAL' || timelineMode === 'HORIZONTAL_ALL')
-    ) {
-      const portalContainer = document.getElementById(portalId);
-      if (portalContainer) {
-        targetElement = portalContainer.querySelector(
-          `#timeline-card-${itemId}`,
-        );
-      }
-    }
- 
-    return targetElement;
-  } catch (error) {
-    console.error('Error finding timeline element:', error);
-    return null;
-  }
-};
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/coverage/utils/utils.test.ts.html b/coverage/utils/utils.test.ts.html deleted file mode 100644 index e975ae8d5..000000000 --- a/coverage/utils/utils.test.ts.html +++ /dev/null @@ -1,406 +0,0 @@ - - - - - - Code coverage report for utils/utils.test.ts - - - - - - - - - -
-
-

All files / utils utils.test.ts

-
- -
- 100% - Statements - 90/90 -
- - -
- 100% - Branches - 10/10 -
- - -
- 100% - Functions - 0/0 -
- - -
- 100% - Lines - 90/90 -
- - -
-

- Press n or j to go to the next uncovered block, b, p or k for the previous block. -

- -
-
-

-
1 -2 -3 -4 -5 -6 -7 -8 -9 -10 -11 -12 -13 -14 -15 -16 -17 -18 -19 -20 -21 -22 -23 -24 -25 -26 -27 -28 -29 -30 -31 -32 -33 -34 -35 -36 -37 -38 -39 -40 -41 -42 -43 -44 -45 -46 -47 -48 -49 -50 -51 -52 -53 -54 -55 -56 -57 -58 -59 -60 -61 -62 -63 -64 -65 -66 -67 -68 -69 -70 -71 -72 -73 -74 -75 -76 -77 -78 -79 -80 -81 -82 -83 -84 -85 -86 -87 -88 -89 -90 -91 -92 -93 -94 -95 -96 -97 -98 -99 -100 -101 -102 -103 -104 -105 -106 -107 -108  -1x -1x -1x -  -  -  -  -  -  -  -  -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -1x -  -1x -1x -1x -1x -  -1x -1x -1x -  -1x -1x -1x -1x - 
import { ButtonTexts, TimelineMode } from '@models/TimelineModel';
-import { describe, it, expect } from 'vitest';
-import { darkTheme, defaultTheme } from '../components/common/themes';
-import {
-  getDefaultButtonTexts,
-  getDefaultClassNames,
-  getDefaultThemeOrDark,
-  getSlideShowType,
-  getUniqueID,
-  hexToRGBA,
-} from './index'; // Update the path accordingly
- 
-describe('Utility Functions', () => {
-  it('uniqueID should generate a unique ID of length 7', () => {
-    const id = getUniqueID();
-    expect(id).toHaveLength(7);
-  });
- 
-  it('hexToRGBA should convert hex to rgba', () => {
-    const rgba = hexToRGBA('#FF5733', 0.5);
-    expect(rgba).toBe('rgba(255, 87, 51, 0.5)');
-  });
- 
-  it('getDefaultThemeOrDark should return dark theme if isDark is true', () => {
-    expect(getDefaultThemeOrDark(true)).toEqual(darkTheme);
-  });
- 
-  it('getDefaultThemeOrDark should return default theme if isDark is false or undefined', () => {
-    expect(getDefaultThemeOrDark(false)).toEqual(defaultTheme);
-    expect(getDefaultThemeOrDark()).toEqual(defaultTheme);
-  });
- 
-  it('getDefaultClassNames should return default class names', () => {
-    expect(getDefaultClassNames()).toEqual({
-      card: 'rc-card',
-      cardMedia: 'rc-card-media',
-      cardSubTitle: 'rc-card-subtitle',
-      cardText: 'rc-card-text',
-      cardTitle: 'rc-card-title',
-      controls: 'rc-controls',
-      title: 'rc-title',
-    });
-  });
- 
-  it('getDefaultButtonTexts should return default button texts', () => {
-    expect(getDefaultButtonTexts()).toEqual({
-      changeDensity: 'Change density',
-      changeDensityOptions: {
-        high: {
-          helpText: 'Show more items at once',
-          text: 'High',
-        },
-        low: {
-          helpText: 'Show fewer items at once',
-          text: 'Low',
-        },
-      },
-      changeLayout: 'Change layout',
-      changeLayoutOptions: {
-        alternating: {
-          helpText: 'Show cards in a vertical layout with alternating fashion',
-          text: 'Alternating',
-        },
-        horizontal: {
-          helpText: 'Show cards in a horizontal layout',
-          text: 'Horizontal',
-        },
-        horizontal_all: {
-          helpText: 'Show all cards in a horizontal layout',
-          text: 'Show all cards',
-        },
-        vertical: {
-          helpText: 'Show cards in a vertical layout',
-          text: 'Vertical',
-        },
-      },
-      dark: 'Switch to Dark Mode',
-      first: 'Go to First',
-      jumpTo: 'Jump to',
-      last: 'Go to Last',
-      light: 'Switch to Light Mode',
-      next: 'Next',
-      play: 'Play Slideshow',
-      previous: 'Previous',
-      stop: 'Stop Slideshow',
-      searchPlaceholder: 'Search Timeline',
-      searchAriaLabel: 'Search timeline content',
-      clearSearch: 'Clear Search',
-      previousMatch: 'Previous Match',
-      nextMatch: 'Next Match',
-      timelinePoint: 'Timeline point',
-    } as ButtonTexts);
-  });
- 
-  it('getSlideShowType should return reveal for HORIZONTAL and VERTICAL modes', () => {
-    expect(getSlideShowType('HORIZONTAL')).toBe('reveal');
-    expect(getSlideShowType('VERTICAL')).toBe('reveal');
-  });
- 
-  it('getSlideShowType should return slide_from_sides for VERTICAL_ALTERNATING mode', () => {
-    expect(getSlideShowType('VERTICAL_ALTERNATING')).toBe('slide_from_sides');
-  });
- 
-  it('getSlideShowType should return reveal for other modes', () => {
-    expect(getSlideShowType('OTHER_MODE' as TimelineMode)).toBe('reveal');
-  });
-});
- 
- -
-
- - - - - - - - \ No newline at end of file diff --git a/cypress/tsconfig.json b/cypress/tsconfig.json index 1b48cfd52..978619b9f 100644 --- a/cypress/tsconfig.json +++ b/cypress/tsconfig.json @@ -1,6 +1,7 @@ { "extends": "../tsconfig.json", "compilerOptions": { + // Cypress-specific overrides "types": [ "cypress", "node" @@ -8,14 +9,28 @@ "target": "ES2022", "lib": ["ES2022", "DOM"], "module": "ESNext", - "moduleResolution": "node", + "moduleResolution": "bundler", "resolveJsonModule": true, "esModuleInterop": true, "allowSyntheticDefaultImports": true, "forceConsistentCasingInFileNames": true, "strict": true, "skipLibCheck": true, - "rootDir": ".." + + // Cypress-specific paths + "baseUrl": "..", + "paths": { + "@/*": ["../src/*"], + "@components/*": ["../src/components/*"], + "@models/*": ["../src/models/*"], + "@utils/*": ["../src/utils/*"], + "@hooks/*": ["../src/hooks/*"], + "@effects/*": ["../src/effects/*"], + "@styles/*": ["../src/styles/*"], + "@types/*": ["../src/types/*"], + "@demo/*": ["../src/demo/*"], + "@examples/*": ["../src/examples/*"] + } }, "include": [ "../node_modules/cypress", @@ -27,6 +42,8 @@ ], "exclude": [ "../node_modules", - "../dist" + "../dist", + "../coverage", + "../build" ] } \ No newline at end of file diff --git a/eslint.config.mjs b/eslint.config.mjs index 365640119..36b86e404 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -22,30 +22,47 @@ const compat = new FlatCompat({ export default [ { - ignores: ['src/demo/*', 'src/assets/*', 'src/examples/*', 'coverage/**', 'dist/**', 'build/**'], + ignores: [ + 'src/demo/*', + 'src/assets/*', + 'src/examples/*', + 'coverage/**', + 'dist/**', + 'build/**', + 'node_modules/**', + '*.config.js', + '*.config.mjs', + '*.config.ts', + 'vite.config.*', + 'vitest.config.*', + 'rollup.config.*', + 'cypress/**', + ], }, ...fixupConfigRules( compat.extends( 'plugin:import/typescript', 'plugin:react/recommended', - 'prettier', 'plugin:react/jsx-runtime', + 'plugin:jsx-a11y/recommended', + 'prettier', ), ), { languageOptions: { - ecmaVersion: 12, - + ecmaVersion: 2022, globals: { ...globals.browser, + ...globals.es2021, }, parser: tsParser, parserOptions: { ecmaFeatures: { jsx: true, }, + project: './tsconfig.json', + tsconfigRootDir: __dirname, }, - sourceType: 'module', }, @@ -59,6 +76,121 @@ export default [ }, rules: { + // TypeScript specific rules + '@typescript-eslint/no-unused-vars': [ + 'error', + { + argsIgnorePattern: '^_', + varsIgnorePattern: '^_', + caughtErrorsIgnorePattern: '^_', + }, + ], + '@typescript-eslint/no-explicit-any': 'warn', + '@typescript-eslint/prefer-const': 'error', + '@typescript-eslint/no-var-requires': 'error', + '@typescript-eslint/explicit-function-return-type': 'off', + '@typescript-eslint/explicit-module-boundary-types': 'off', + '@typescript-eslint/no-non-null-assertion': 'warn', + '@typescript-eslint/consistent-type-imports': [ + 'error', + { + prefer: 'type-imports', + disallowTypeAnnotations: false, + }, + ], + + // Import rules + 'import/order': [ + 'error', + { + groups: [ + 'builtin', + 'external', + 'internal', + 'parent', + 'sibling', + 'index', + 'object', + 'type', + ], + 'newlines-between': 'always', + alphabetize: { + order: 'asc', + caseInsensitive: true, + }, + }, + ], + 'import/no-unresolved': 'error', + 'import/no-duplicates': 'error', + 'import/no-unused-modules': 'off', + + // React rules + 'react/prop-types': 'off', + 'react/react-in-jsx-scope': 'off', + 'react/jsx-uses-react': 'off', + 'react/jsx-uses-vars': 'error', + 'react/jsx-no-undef': 'error', + 'react/jsx-no-duplicate-props': 'error', + 'react/jsx-key': 'error', + 'react/jsx-no-bind': [ + 'error', + { + allowArrowFunctions: true, + allowBind: false, + ignoreRefs: true, + }, + ], + 'react/jsx-no-target-blank': 'error', + 'react/jsx-pascal-case': 'error', + 'react/jsx-sort-props': [ + 'error', + { + callbacksLast: true, + shorthandFirst: true, + ignoreCase: true, + reservedFirst: true, + }, + ], + + // Accessibility rules + 'jsx-a11y/anchor-is-valid': [ + 'error', + { + components: ['Link'], + specialLink: ['hrefLeft', 'hrefRight'], + aspects: ['invalidHref', 'preferButton'], + }, + ], + + // General rules + 'no-console': 'warn', + 'no-debugger': 'error', + 'no-alert': 'warn', + 'no-var': 'error', + 'prefer-const': 'error', + 'prefer-arrow-callback': 'error', + 'arrow-spacing': 'error', + 'no-duplicate-imports': 'error', + 'no-unused-expressions': 'error', + 'no-unreachable': 'error', + 'no-constant-condition': 'error', + 'no-empty': 'error', + 'no-extra-semi': 'error', + 'no-irregular-whitespace': 'error', + 'no-multiple-empty-lines': [ + 'error', + { + max: 1, + maxEOF: 1, + }, + ], + 'no-trailing-spaces': 'error', + 'eol-last': 'error', + 'comma-dangle': ['error', 'always-multiline'], + 'semi': ['error', 'always'], + 'quotes': ['error', 'single', { avoidEscape: true }], + + // Sorting rules 'sort-keys-fix/sort-keys-fix': 'error', 'typescript-sort-keys/interface': 'error', 'typescript-sort-keys/string-enum': 'error', @@ -66,7 +198,13 @@ export default [ settings: { react: { - version: '18.1.0', + version: 'detect', + }, + 'import/resolver': { + typescript: { + alwaysTryTypes: true, + project: './tsconfig.json', + }, }, }, }, diff --git a/package.json b/package.json index 39ba52e38..d8003c53a 100644 --- a/package.json +++ b/package.json @@ -29,10 +29,12 @@ "cypress:ci": "cypress run --config video=false,screenshotOnRunFailure=true", "eslint": "eslint src/**/*.{tsx,ts} --no-warn-ignored", "fix-js": "eslint src/**/*.{tsx,ts} --fix --no-warn-ignored", - "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx}\"", - "lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx}\"", + "format": "prettier --write \"src/**/*.{js,jsx,ts,tsx,json,md}\"", + "lint": "prettier --check \"src/**/*.{js,jsx,ts,tsx,json,md}\"", "lint:all": "pnpm eslint && pnpm lint:css && pnpm lint", - "lint:css": "stylelint src/**/*style.ts", + "lint:css": "stylelint \"src/**/*.{css,scss,ts}\"", + "fix-css": "stylelint \"src/**/*.{css,scss,ts}\" --fix", + "lint:fix": "pnpm fix-js && pnpm fix-css && pnpm format", "find-bugs": "npx tsc --noEmit && pnpm lint:all && pnpm test", "find-bugs:full": "./scripts/find-bugs.sh", "rollup": "rollup -c rollup.config.mjs", @@ -46,8 +48,7 @@ "coveralls": "pnpx coveralls < coverage/lcov.info", "size-limit": "pnpm rollup && pnpm size-limit", "build": "rollup -c", - "build:analyze": "ANALYZE=true rollup -c", - "fix-css": "stylelint src/**/*style.ts --fix" + "build:analyze": "ANALYZE=true rollup -c" }, "dependencies": { "classnames": "^2.5.1", @@ -149,6 +150,7 @@ "stylelint": "^16.21.0", "stylelint-config-recess-order": "^7.1.0", "stylelint-config-recommended": "^16.0.0", + "stylelint-config-styled-components": "^0.1.1", "stylelint-order": "^7.0.0", "typescript": "^5.8.3", "typescript-plugin-styled-components": "^3.0.0", @@ -180,11 +182,15 @@ } ], "lint-staged": { - "src/components/**/*.{ts,tsx}": [ + "src/**/*.{js,jsx,ts,tsx}": [ "prettier --write", - "stylelint ./src/**/*style.ts", - "eslint ./src/**/*.tsx", - "git add" + "eslint --fix" + ], + "src/**/*.{css,scss,ts}": [ + "stylelint --fix" + ], + "*.{json,md}": [ + "prettier --write" ] }, "browserslist": [ diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f90579b2b..10f5ba558 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -284,6 +284,9 @@ importers: stylelint-config-recommended: specifier: ^16.0.0 version: 16.0.0(stylelint@16.21.0(typescript@5.8.3)) + stylelint-config-styled-components: + specifier: ^0.1.1 + version: 0.1.1 stylelint-order: specifier: ^7.0.0 version: 7.0.0(stylelint@16.21.0(typescript@5.8.3)) @@ -6128,6 +6131,9 @@ packages: peerDependencies: stylelint: ^16.16.0 + stylelint-config-styled-components@0.1.1: + resolution: {integrity: sha512-z5Xz/9GmvxO6e/DLzBMwkB85zHxEEjN6K7Cj80Bi+o/9vR9eS3GX3E9VuMnX9WLFYulqbqLtTapGGY28JBiy9Q==} + stylelint-order@7.0.0: resolution: {integrity: sha512-rSWxx0KscYfxU02wEskKXES9lkRzuuONMMNkZ7SUc6uiF3tDKm7e+sE0Ax/SBlG4TUf1sp1R6f3/SlsPGmzthg==} engines: {node: '>=20.19.0'} @@ -13414,6 +13420,8 @@ snapshots: dependencies: stylelint: 16.21.0(typescript@5.8.3) + stylelint-config-styled-components@0.1.1: {} + stylelint-order@7.0.0(stylelint@16.21.0(typescript@5.8.3)): dependencies: postcss: 8.5.6 diff --git a/postcss.config.js b/postcss.config.js index a47ef4f95..9d7c33297 100644 --- a/postcss.config.js +++ b/postcss.config.js @@ -1,5 +1,49 @@ module.exports = { - plugins: { - autoprefixer: {}, - }, -}; + plugins: [ + // Autoprefixer for cross-browser compatibility + require('autoprefixer')({ + flexbox: 'no-2009', + grid: 'autoplace', + }), + + // PostCSS Preset Env for modern CSS features + require('postcss-preset-env')({ + stage: 3, + features: { + 'nesting-rules': true, + 'custom-media-queries': true, + 'media-query-ranges': true, + 'custom-properties': true, + 'color-functional-notation': true, + 'logical-properties-and-values': true, + 'overflow-property': true, + 'place-properties': true, + 'focus-visible-pseudo-class': true, + 'focus-within-pseudo-class': true, + 'color-mix': true, + }, + }), + + // CSS Nano for production optimization (only in production) + ...(process.env.NODE_ENV === 'production' ? [require('cssnano')({ + preset: ['default', { + discardComments: { + removeAll: true, + }, + normalizeWhitespace: true, + colormin: true, + minifyFontValues: true, + minifyGradients: true, + minifyParams: true, + minifySelectors: true, + mergeLonghand: true, + mergeRules: true, + reduceIdents: false, + reduceInitial: true, + reduceTransforms: true, + uniqueSelectors: true, + zindex: false, + }], + })] : []), + ], +}; \ No newline at end of file diff --git a/postcss.config.mjs b/postcss.config.mjs new file mode 100644 index 000000000..b194a0be1 --- /dev/null +++ b/postcss.config.mjs @@ -0,0 +1,53 @@ +import autoprefixer from 'autoprefixer'; +import postcssPresetEnv from 'postcss-preset-env'; +import cssnano from 'cssnano'; + +export default { + plugins: [ + // Autoprefixer for cross-browser compatibility + autoprefixer({ + flexbox: 'no-2009', + grid: 'autoplace', + }), + + // PostCSS Preset Env for modern CSS features + postcssPresetEnv({ + stage: 3, + features: { + 'nesting-rules': true, + 'custom-media-queries': true, + 'media-query-ranges': true, + 'custom-properties': true, + 'color-functional-notation': true, + 'logical-properties-and-values': true, + 'overflow-property': true, + 'place-properties': true, + 'focus-visible-pseudo-class': true, + 'focus-within-pseudo-class': true, + 'color-mix': true, + }, + }), + + // CSS Nano for production optimization (only in production) + ...(process.env.NODE_ENV === 'production' ? [cssnano({ + preset: ['default', { + discardComments: { + removeAll: true, + }, + normalizeWhitespace: true, + colormin: true, + minifyFontValues: true, + minifyGradients: true, + minifyParams: true, + minifySelectors: true, + mergeLonghand: true, + mergeRules: true, + reduceIdents: false, + reduceInitial: true, + reduceTransforms: true, + uniqueSelectors: true, + zindex: false, + }], + })] : []), + ], +}; diff --git a/src/components/GlobalContext.tsx b/src/components/GlobalContext.tsx index 9314e4425..43ccebe3d 100644 --- a/src/components/GlobalContext.tsx +++ b/src/components/GlobalContext.tsx @@ -25,7 +25,7 @@ export const GlobalContext = LegacyGlobalContext; * Legacy GlobalContextProvider - wraps the new optimized provider * @deprecated Use OptimizedContextProvider directly */ -const GlobalContextProvider: FunctionComponent = (props) => { +const GlobalContextProvider: FunctionComponent = props => { return ( {props.children} diff --git a/src/components/__tests__/GlobalContext.test.tsx b/src/components/__tests__/GlobalContext.test.tsx index 1791b0e82..4cce2be84 100644 --- a/src/components/__tests__/GlobalContext.test.tsx +++ b/src/components/__tests__/GlobalContext.test.tsx @@ -49,7 +49,7 @@ interface TestContextConsumerProps { const TestContextConsumer = ({ onContextValue }: TestContextConsumerProps) => { const contextValue = useContext(GlobalContext); onContextValue(contextValue); - return
Context Consumer
; + return
Context Consumer
; }; interface TestWrapperProps { @@ -164,7 +164,7 @@ describe('GlobalContext', () => { it('should render provider and children without errors', () => { render( -
Test Child
+
Test Child
, ); diff --git a/src/components/common/styles/index.ts b/src/components/common/styles/index.ts index 5e09f1acf..3a38d30bb 100644 --- a/src/components/common/styles/index.ts +++ b/src/components/common/styles/index.ts @@ -2,7 +2,7 @@ import { Theme } from '@models/Theme'; import { css } from 'styled-components'; export const ScrollBar = css<{ theme: Theme }>` - scrollbar-color: ${(p) => p.theme?.primary} default; + scrollbar-color: ${p => p.theme?.primary} default; scrollbar-width: thin; &::-webkit-scrollbar { @@ -14,7 +14,7 @@ export const ScrollBar = css<{ theme: Theme }>` } &::-webkit-scrollbar-thumb { - background-color: ${(p) => p.theme?.primary}; - outline: 1px solid ${(p) => p.theme?.primary}; + background-color: ${p => p.theme?.primary}; + outline: 1px solid ${p => p.theme?.primary}; } `; diff --git a/src/components/contexts/OptimizedContextProvider.tsx b/src/components/contexts/OptimizedContextProvider.tsx index 1b6b55876..1ee2d34c9 100644 --- a/src/components/contexts/OptimizedContextProvider.tsx +++ b/src/components/contexts/OptimizedContextProvider.tsx @@ -34,7 +34,7 @@ interface OptimizedContextProviderProps extends Omit { export const OptimizedContextProvider: FunctionComponent< OptimizedContextProviderProps -> = (props) => { +> = props => { const { cardHeight = 200, cardLess = false, diff --git a/src/components/effects/__tests__/useMatchMedia.test.tsx b/src/components/effects/__tests__/useMatchMedia.test.tsx index 713325d32..aa35e956f 100644 --- a/src/components/effects/__tests__/useMatchMedia.test.tsx +++ b/src/components/effects/__tests__/useMatchMedia.test.tsx @@ -16,7 +16,7 @@ function TestComponent({ }) { const matches = useMatchMedia(query, options); return ( -
{matches ? 'Matches' : 'Does not match'}
+
{matches ? 'Matches' : 'Does not match'}
); } @@ -29,7 +29,7 @@ describe('useMatchMedia', () => { addEventListenerSpy = vi.fn(); removeEventListenerSpy = vi.fn(); - matchMediaMock = vi.fn().mockImplementation((query) => ({ + matchMediaMock = vi.fn().mockImplementation(query => ({ matches: query === '(min-width: 800px)', addEventListener: addEventListenerSpy, removeEventListener: removeEventListenerSpy, @@ -48,28 +48,28 @@ describe('useMatchMedia', () => { it('returns true if the query matches', () => { const { getByTestId } = render( - , + , ); expect(getByTestId('result')).toHaveTextContent('Matches'); }); it('returns false if the query does not match', () => { const { getByTestId } = render( - , + , ); expect(getByTestId('result')).toHaveTextContent('Does not match'); }); it('returns false if the hook is disabled', () => { const { getByTestId } = render( - , + , ); expect(getByTestId('result')).toHaveTextContent('Does not match'); }); it('calls onMatch callback when query matches', () => { const onMatch = vi.fn(); - render(); + render(); expect(onMatch).toHaveBeenCalledTimes(1); }); @@ -81,7 +81,7 @@ describe('useMatchMedia', () => { }); const { getByTestId } = render( - , + , ); act(() => { @@ -96,7 +96,7 @@ describe('useMatchMedia', () => { const { getByTestId } = render( , ); @@ -125,7 +125,7 @@ describe('useMatchMedia', () => { }); const { getByTestId, unmount } = render( - , + , ); expect(getByTestId('result')).toHaveTextContent('Does not match'); @@ -141,7 +141,7 @@ describe('useMatchMedia', () => { const { getByTestId } = render( , ); @@ -161,9 +161,9 @@ describe('useMatchMedia', () => { }); it('handles cleanup on query change', () => { - const { rerender } = render(); + const { rerender } = render(); - rerender(); + rerender(); expect(removeEventListenerSpy).toHaveBeenCalled(); }); diff --git a/src/components/elements/list/list-item.tsx b/src/components/elements/list/list-item.tsx index 9b707f9a9..bcc6e874b 100644 --- a/src/components/elements/list/list-item.tsx +++ b/src/components/elements/list/list-item.tsx @@ -54,19 +54,19 @@ const ListItem: FunctionComponent = memo( return ( handleOnClick(id)} $active={active} tabIndex={0} $selectable={selectable} - onKeyUp={(ev) => handleKeyPress(ev, id)} + onKeyUp={ev => handleKeyPress(ev, id)} > {selectable ? ( ` ${baseStyles} - background: ${(p) => p.$theme?.toolbarBtnBgColor || '#f5f5f5'}; + background: ${p => p.$theme?.toolbarBtnBgColor || '#f5f5f5'}; border-radius: 4px; -webkit-box-shadow: 0px 1px 1px - ${(p) => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'}; - box-shadow: 0px 1px 1px - ${(p) => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'}; + ${p => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'}; + box-shadow: 0px 1px 1px ${p => p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.1)'}; margin-bottom: 0.5rem; &:last-child { @@ -75,23 +74,23 @@ export const ListItemStyle = styled.li<{ $theme: Theme; }>` ${commonStyles} - border: ${(p) => + border: ${p => p.$active ? themeStyles.border(p.$theme) : themeStyles.transparent}; - flex-direction: ${(p) => (p.$selectable ? 'row' : 'column')}; - background: ${(p) => p.$theme.toolbarBtnBgColor}; + flex-direction: ${p => (p.$selectable ? 'row' : 'column')}; + background: ${p => p.$theme.toolbarBtnBgColor}; padding: 0.25rem; width: calc(100% - 0.5rem); user-select: none; &:hover { - border: ${(p) => themeStyles.border(p.$theme)}; + border: ${p => themeStyles.border(p.$theme)}; cursor: pointer; } `; // Title styles export const TitleStyle = styled.h1<{ theme: Theme }>` - color: ${(p) => p.theme.iconColor || p.theme.primary}; + color: ${p => p.theme.iconColor || p.theme.primary}; font-size: 1rem; font-weight: normal; margin: 0.2rem 0; @@ -108,7 +107,7 @@ export const TitleDescriptionStyle = styled.p<{ theme: Theme }>` padding: 0.1rem; text-align: left; width: 100%; - color: ${(p) => p.theme.cardSubtitleColor}; + color: ${p => p.theme.cardSubtitleColor}; `; // Checkbox components with improved structure @@ -125,8 +124,8 @@ export const CheckboxStyle = styled.span<{ selected?: boolean; theme: Theme }>` height: 1.25rem; margin: 0 0.25rem 0 0.1rem; border-radius: 50%; - background: ${(p) => (p.selected ? p.theme.primary : p.theme.toolbarBgColor)}; - ${(p) => !p.selected && `box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1)`}; + background: ${p => (p.selected ? p.theme.primary : p.theme.toolbarBgColor)}; + ${p => !p.selected && `box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 0.1)`}; color: #ffffff; svg { @@ -139,5 +138,5 @@ export const CheckboxStyle = styled.span<{ selected?: boolean; theme: Theme }>` export const StyleAndDescription = styled.div<{ $selectable?: boolean }>` ${flexContainer} flex-direction: column; - width: ${(p) => (p.$selectable ? 'calc(100% - 2rem)' : '100%')}; + width: ${p => (p.$selectable ? 'calc(100% - 2rem)' : '100%')}; `; diff --git a/src/components/elements/list/list.tsx b/src/components/elements/list/list.tsx index c272302fc..d9d33060a 100644 --- a/src/components/elements/list/list.tsx +++ b/src/components/elements/list/list.tsx @@ -39,7 +39,7 @@ const List: FunctionComponent = ({ * Memoized list items with generated unique IDs */ const listItems = useMemo( - () => items.map((item) => ({ id: getUniqueID(), ...item })), + () => items.map(item => ({ id: getUniqueID(), ...item })), [items], ); diff --git a/src/components/elements/popover/__tests__/popover.test.tsx b/src/components/elements/popover/__tests__/popover.test.tsx index 117da1cc8..e81ea6b0c 100644 --- a/src/components/elements/popover/__tests__/popover.test.tsx +++ b/src/components/elements/popover/__tests__/popover.test.tsx @@ -20,7 +20,7 @@ describe('PopOver', () => { it('should render the placeholder text', () => { const placeholder = 'Select an option'; customRender( - + test , { @@ -37,7 +37,7 @@ describe('PopOver', () => { it('should toggle open state when clicking on the selecter', async () => { const placeholder = 'Select an option'; const { getByRole, getByText } = customRender( - + test , { @@ -58,7 +58,7 @@ describe('PopOver', () => { it('should close the popover when clicking outside', async () => { const placeholder = 'Select an option'; const { getByRole, queryByText } = customRender( - + test , { @@ -82,7 +82,7 @@ describe('PopOver', () => { const user = userEvent.setup(); const placeholder = 'Select an option'; const { getByRole, queryByText, getByText } = customRender( - + test , { diff --git a/src/components/elements/popover/index.tsx b/src/components/elements/popover/index.tsx index af08d45fc..4d5f0a42c 100644 --- a/src/components/elements/popover/index.tsx +++ b/src/components/elements/popover/index.tsx @@ -97,7 +97,7 @@ const PopOver: FunctionComponent = ({ <> (p.$position === 'bottom' ? `bottom: 3.5rem` : `top: 4rem`)}; - ${(p) => (p.$isMobile ? 'left: 4px;' : '')}; + ${p => (p.$position === 'bottom' ? `bottom: 3.5rem` : `top: 4rem`)}; + ${p => (p.$isMobile ? 'left: 4px;' : '')}; width: ${({ $isMobile, $width = 300 }) => $isMobile ? '90%' : `${$width}px`}; opacity: ${({ $visible }) => ($visible ? 1 : 0)}; transition: opacity 0.2s ease-in-out, transform 0.2s ease-in-out; - transform: ${(p) => (p.$visible ? 'translateY(0)' : 'translateY(-10px)')}; + transform: ${p => (p.$visible ? 'translateY(0)' : 'translateY(-10px)')}; z-index: ${zIndex.popover}; /* Use standardized z-index for popovers */ `; @@ -73,7 +73,7 @@ export const Selecter = styled.div<{ box-shadow: ${({ $open, $theme }) => getInteractiveShadow($theme, $open)}; cursor: pointer; justify-content: space-between; - padding: ${(p) => (p.$isMobile ? '0.4rem' : `0.4rem 0.5rem`)}; + padding: ${p => (p.$isMobile ? '0.4rem' : `0.4rem 0.5rem`)}; user-select: none; margin-right: 0.5rem; transition: diff --git a/src/components/index.tsx b/src/components/index.tsx index 63d2211f8..a326e29a7 100644 --- a/src/components/index.tsx +++ b/src/components/index.tsx @@ -51,7 +51,7 @@ const Chrono: React.FunctionComponent> = ( active: index === activeItemIndex, id, hasNestedItems, - items: item.items?.map((subItem) => ({ + items: item.items?.map(subItem => ({ ...subItem, _dayjs: dayjs(subItem.date), id: getUniqueID(), @@ -67,7 +67,7 @@ const Chrono: React.FunctionComponent> = ( } const itemLength = React.Children.toArray(children).filter( - (item) => + item => (item as React.ReactElement).props.className !== 'chrono-icons', ).length; @@ -104,7 +104,7 @@ const Chrono: React.FunctionComponent> = ( // Only extract the needed properties and create a single string return items - .map((item) => { + .map(item => { // Use simple string concatenation which is more efficient than JSON.stringify const id = item.id || ''; const date = item.date || ''; @@ -116,7 +116,7 @@ const Chrono: React.FunctionComponent> = ( }, []); useEffect(() => { - const _items = items?.filter((item) => item); + const _items = items?.filter(item => item); let newItems: TimelineItemModel[] = []; if (!_items?.length) { @@ -157,7 +157,7 @@ const Chrono: React.FunctionComponent> = ( const handleTimelineUpdate = useCallback( (actvTimelineIndex: number) => { - setTimeLineItems((lineItems) => + setTimeLineItems(lineItems => lineItems.map((item, index) => ({ ...item, active: index === actvTimelineIndex, @@ -199,7 +199,7 @@ const Chrono: React.FunctionComponent> = ( // Skip timeline update (which triggers scrolling) in horizontal mode during slideshow if (mode === 'HORIZONTAL' && slideShowActive) { // Only update the timeline items state and active item, skip scroll triggering updates - setTimeLineItems((lineItems) => + setTimeLineItems(lineItems => lineItems.map((item, index) => ({ ...item, active: index === newTimeLineItem, @@ -232,7 +232,7 @@ const Chrono: React.FunctionComponent> = ( // Skip timeline update (which triggers scrolling) in horizontal mode during slideshow if (mode === 'HORIZONTAL' && slideShowActive) { // Only update the timeline items state and active item, skip scroll triggering updates - setTimeLineItems((lineItems) => + setTimeLineItems(lineItems => lineItems.map((item, index) => ({ ...item, active: index === newTimeLineItem, @@ -277,7 +277,7 @@ const Chrono: React.FunctionComponent> = ( // Memoize icon children processing const iconChildren = useMemo(() => { let iconChildArray = toReactArray(children).filter( - (item) => + item => item && (item as any).props && (item as any).props.className === 'chrono-icons', @@ -292,7 +292,7 @@ const Chrono: React.FunctionComponent> = ( // Memoize content details children const contentDetailsChildren = useMemo(() => { return toReactArray(children).filter( - (item) => + item => item && (item as any).props && (item as any).props.className !== 'chrono-icons', diff --git a/src/components/timeline-elements/memoized/__tests__/index.test.tsx b/src/components/timeline-elements/memoized/__tests__/index.test.tsx index 13cdd1e7a..587cb2ad4 100644 --- a/src/components/timeline-elements/memoized/__tests__/index.test.tsx +++ b/src/components/timeline-elements/memoized/__tests__/index.test.tsx @@ -10,7 +10,7 @@ import { TitleMemo } from '../title-memo'; describe('Title', () => { it('should render title', () => { const { getByText } = customRender( - , + , { providerProps }, ); expect(getByText('title')).toBeInTheDocument(); @@ -20,10 +20,10 @@ describe('Title', () => { it('should render title with url', () => { const { getByText, getByRole } = customRender( , { providerProps }, @@ -35,7 +35,7 @@ describe('Title', () => { //should have the color and padding it('should have the color and padding', () => { const { getByText } = customRender( - , + , { providerProps }, ); expect(getByText('title')).toHaveStyle('color: #ccc'); @@ -46,12 +46,12 @@ describe('Title', () => { it('should accept custom class name', () => { const { getByText } = customRender( , { providerProps }, ); @@ -63,10 +63,10 @@ describe('subtitle', () => { it('should render CardSubTitle', () => { const { getByText } = customRender( , { providerProps }, ); @@ -77,10 +77,10 @@ describe('subtitle', () => { it('should render the color and padding correctly', () => { const { getByText } = customRender( , { providerProps }, diff --git a/src/components/timeline-elements/memoized/expand-button-memo.tsx b/src/components/timeline-elements/memoized/expand-button-memo.tsx index c03f2d7a4..72a785aee 100644 --- a/src/components/timeline-elements/memoized/expand-button-memo.tsx +++ b/src/components/timeline-elements/memoized/expand-button-memo.tsx @@ -17,7 +17,7 @@ const ExpandButtonMemo = memo( return textOverlay ? ( ev.key === 'Enter' && onExpand?.(ev)} + onKeyDown={ev => ev.key === 'Enter' && onExpand?.(ev)} theme={theme} aria-expanded={expanded} tabIndex={0} diff --git a/src/components/timeline-elements/memoized/show-hide-button.tsx b/src/components/timeline-elements/memoized/show-hide-button.tsx index 6ff397eaa..2e134c848 100644 --- a/src/components/timeline-elements/memoized/show-hide-button.tsx +++ b/src/components/timeline-elements/memoized/show-hide-button.tsx @@ -19,7 +19,7 @@ const ShowOrHideTextButtonMemo = memo( onPointerDown={onToggle} theme={theme} tabIndex={0} - onKeyDown={(ev) => ev.key === 'Enter' && onToggle?.(ev)} + onKeyDown={ev => ev.key === 'Enter' && onToggle?.(ev)} aria-label={label} title={label} > diff --git a/src/components/timeline-elements/memoized/title-memo.tsx b/src/components/timeline-elements/memoized/title-memo.tsx index ae0dbd963..9893dc49e 100644 --- a/src/components/timeline-elements/memoized/title-memo.tsx +++ b/src/components/timeline-elements/memoized/title-memo.tsx @@ -35,7 +35,7 @@ const TitleMemoComponent = ({ data-class={classString} > {url ? ( - + {title} ) : ( diff --git a/src/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx b/src/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx index ec0416484..d846e91d3 100644 --- a/src/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx +++ b/src/components/timeline-elements/nested-timeline-renderer/nested-timeline-renderer.tsx @@ -21,7 +21,7 @@ const NestedTimelineRenderer: React.FC = ({ // Dynamically import the Timeline component only when needed React.useEffect(() => { - import('../../timeline/timeline').then((module) => { + import('../../timeline/timeline').then(module => { setTimelineComponent(() => module.default); }); }, []); diff --git a/src/components/timeline-elements/timeline-card-content/__tests__/__snapshots__/content-header.test.tsx.snap b/src/components/timeline-elements/timeline-card-content/__tests__/__snapshots__/content-header.test.tsx.snap index 7a95d4716..9fd235c94 100644 --- a/src/components/timeline-elements/timeline-card-content/__tests__/__snapshots__/content-header.test.tsx.snap +++ b/src/components/timeline-elements/timeline-card-content/__tests__/__snapshots__/content-header.test.tsx.snap @@ -3,16 +3,16 @@ exports[`Content Header > should match the snapshot 1`] = `
title content diff --git a/src/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx b/src/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx index 078340926..9d5b3f69d 100644 --- a/src/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx +++ b/src/components/timeline-elements/timeline-card-content/__tests__/content-header.test.tsx @@ -7,7 +7,7 @@ describe('Content Header', () => { // should render the title and subtitle of the card it('should render the title and subtitle of the card', () => { const { getByText } = customRender( - , + , { providerProps: { ...providerProps, @@ -23,7 +23,7 @@ describe('Content Header', () => { // should match the snapshot it('should match the snapshot', () => { const { container } = customRender( - , + , { providerProps, }, @@ -36,9 +36,9 @@ describe('Content Header', () => { it('should render the link if url is provided', () => { const { getByText, getByRole } = customRender( , { providerProps, diff --git a/src/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx b/src/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx index 43099897d..f91f67352 100644 --- a/src/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx +++ b/src/components/timeline-elements/timeline-card-content/__tests__/timeline-card-content.test.tsx @@ -7,7 +7,7 @@ import TimelineCardContent from '../timeline-card-content'; describe('TimelineCardContent', () => { beforeAll(() => { Object.defineProperty(window, 'matchMedia', { - value: vi.fn().mockImplementation((query) => ({ + value: vi.fn().mockImplementation(query => ({ addEventListener: vi.fn(), dispatchEvent: vi.fn(), matches: false, @@ -35,7 +35,7 @@ describe('TimelineCardContent', () => { //should render the title it('should render the title', () => { - render(); + render(); expect(screen.getByText('title')).toBeInTheDocument(); expect(screen.getByText('title')).toBeVisible(); @@ -44,8 +44,8 @@ describe('TimelineCardContent', () => { // should render the detailedText when a string is passed it('should render the detailedText when a string is passed', () => { render( - - + + , ); @@ -56,7 +56,7 @@ describe('TimelineCardContent', () => { // should render the detailedText when a array of strings is passed it('should render the detailedText when a array of strings is passed', () => { render( - + , ); diff --git a/src/components/timeline-elements/timeline-card-content/content-footer.tsx b/src/components/timeline-elements/timeline-card-content/content-footer.tsx index fe3696bd4..42c63f6b3 100644 --- a/src/components/timeline-elements/timeline-card-content/content-footer.tsx +++ b/src/components/timeline-elements/timeline-card-content/content-footer.tsx @@ -64,9 +64,9 @@ const ContentFooter: FunctionComponent = ({ <> {canShowMore ? ( { + onKeyUp={event => { if (event.key === 'Enter') { onExpand(); } diff --git a/src/components/timeline-elements/timeline-card-content/text-or-content.tsx b/src/components/timeline-elements/timeline-card-content/text-or-content.tsx index d89ecfb60..684207fe3 100644 --- a/src/components/timeline-elements/timeline-card-content/text-or-content.tsx +++ b/src/components/timeline-elements/timeline-card-content/text-or-content.tsx @@ -96,7 +96,7 @@ const getTextOrContent: ( }; // Create props for HTML content if needed - const getTextContentProps = (textContent) => { + const getTextContentProps = textContent => { if (parseDetailsAsHTML && !isTextArray) { return { dangerouslySetInnerHTML: { @@ -107,7 +107,7 @@ const getTextOrContent: ( return {}; }; - const renderDetailedContent = (textContent) => { + const renderDetailedContent = textContent => { const textContentProps = getTextContentProps(textContent); return ( diff --git a/src/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts b/src/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts index 172702f08..5e2a3733f 100644 --- a/src/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts +++ b/src/components/timeline-elements/timeline-card-content/timeline-card-content.styles.ts @@ -24,7 +24,7 @@ const baseFontStyles = css` `; const baseCardStyles = css<{ $theme?: Theme }>` - background: ${(p) => p.$theme?.cardBgColor}; + background: ${p => p.$theme?.cardBgColor}; border-radius: 8px; -webkit-box-shadow: 0 1px 3px rgba(0, 0, 0, 0.06), @@ -41,7 +41,7 @@ const baseCardStyles = css<{ $theme?: Theme }>` `; const scrollbarStyles = css<{ theme?: Theme }>` - scrollbar-color: ${(p) => p.theme?.primary} default; + scrollbar-color: ${p => p.theme?.primary} default; scrollbar-width: thin; &::-webkit-scrollbar { @@ -49,17 +49,17 @@ const scrollbarStyles = css<{ theme?: Theme }>` } &::-webkit-scrollbar-track { - background-color: ${(p) => p.theme?.cardBgColor}; + background-color: ${p => p.theme?.cardBgColor}; } &::-webkit-scrollbar-thumb { - background-color: ${(p) => p.theme?.primary}; + background-color: ${p => p.theme?.primary}; border-radius: 3px; } `; // Animation helpers -const getSlideShowAnimation = (props) => { +const getSlideShowAnimation = props => { const { $slideShowActive, $active, $slideShowType, $branchDir } = props; if (!$slideShowActive || !$active) return ''; @@ -88,7 +88,7 @@ const getSlideShowAnimation = (props) => { `; }; -const getSlideShowVisibility = (props) => { +const getSlideShowVisibility = props => { const { $slideShowActive, $active } = props; if ($slideShowActive && $active) { @@ -125,10 +125,10 @@ const sharedSemanticStyles = css<{ theme: Theme; }>` ${baseFontStyles} - font-size: ${(p) => p.$fontSize || '1.1rem'}; + font-size: ${p => p.$fontSize || '1.1rem'}; font-weight: 600; margin-bottom: 0.5rem; - padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')}; + padding: ${p => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')}; display: block; `; @@ -159,27 +159,27 @@ export const TimelineItemContentWrapper = styled.section< justify-content: flex-start; line-height: 1.5; margin: 0; - max-width: ${(p) => p.$maxWidth}px; + max-width: ${p => p.$maxWidth}px; position: relative; padding: 1rem; z-index: ${zIndex.timelineCard}; overflow: hidden; width: 100%; - // Handle text density and height + /* Handle text density and height */ ${({ $textDensity, $customContent, $minHeight }) => `${$customContent ? 'height' : 'min-height'}: ${$minHeight}px`}; - ${(p) => (p.$textOverlay ? `min-height: ${p.$minHeight}px` : '')}; - ${(p) => (p.$textOverlay ? 'height: 0' : '')}; + ${p => (p.$textOverlay ? `min-height: ${p.$minHeight}px` : '')}; + ${p => (p.$textOverlay ? 'height: 0' : '')}; - // Focus state + /* Focus state */ &:focus { - outline: 1px solid ${(p) => p.$theme?.primary}; + outline: 1px solid ${p => p.$theme?.primary}; } - // Highlight effect - ${(p) => + /* Highlight effect */ + ${p => p.$highlight && css` &:hover { @@ -190,15 +190,15 @@ export const TimelineItemContentWrapper = styled.section< } `} - // Nested card styling - ${(p) => + /* Nested card styling */ + ${p => p.$isNested && css` background: ${p.$theme?.nestedCardBgColor}; box-shadow: 0 1px 2px ${p.$theme?.shadowColor || 'rgba(0, 0, 0, 0.05)'}; `} - // Animations + /* Animations */ ${getSlideShowAnimation} ${getSlideShowVisibility} `; @@ -217,14 +217,14 @@ export const CardTitle = styled.h1<{ theme: Theme; }>` ${baseFontStyles} - color: ${(p) => p.theme.cardTitleColor}; - font-size: ${(p) => p.$fontSize && '1.1rem'}; + color: ${p => p.theme.cardTitleColor}; + font-size: ${p => p.$fontSize && '1.1rem'}; font-weight: 600; margin-bottom: 0.5rem; - padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')}; + padding: ${p => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')}; &.active { - color: ${(p) => p.theme.primary}; + color: ${p => p.theme.primary}; } `; @@ -235,17 +235,16 @@ export const CardSubTitle = styled.h2<{ theme?: Theme; }>` ${baseFontStyles} - color: ${(p) => p.theme.cardSubtitleColor}; - font-size: ${(p) => p.$fontSize && '0.9rem'}; + color: ${p => p.theme.cardSubtitleColor}; + font-size: ${p => p.$fontSize && '0.9rem'}; font-weight: 500; margin-bottom: 0.25rem; - padding: ${(p) => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')}; + padding: ${p => (p.$padding ? '0.5rem 0 0.5rem 0.5rem' : '0')}; `; // Refactor CardTitleSemantic to use shared styles export const CardTitleSemantic = styled.h1.withConfig({ - shouldForwardProp: (prop) => - !['$fontSize', '$padding', 'theme'].includes(prop), + shouldForwardProp: prop => !['$fontSize', '$padding', 'theme'].includes(prop), })<{ $fontSize: string; $padding?: boolean; @@ -254,17 +253,16 @@ export const CardTitleSemantic = styled.h1.withConfig({ as?: string; }>` ${sharedSemanticStyles} - color: ${(p) => p.theme.cardTitleColor}; + color: ${p => p.theme.cardTitleColor}; &.active { - color: ${(p) => p.theme.primary}; + color: ${p => p.theme.primary}; } `; // Refactor CardSubTitleSemantic to use shared styles export const CardSubTitleSemantic = styled.span.withConfig({ - shouldForwardProp: (prop) => - !['$fontSize', '$padding', 'theme'].includes(prop), + shouldForwardProp: prop => !['$fontSize', '$padding', 'theme'].includes(prop), })<{ $fontSize?: string; $padding?: boolean; @@ -273,8 +271,8 @@ export const CardSubTitleSemantic = styled.span.withConfig({ as?: string; }>` ${sharedSemanticStyles} - color: ${(p) => p.theme.cardSubtitleColor}; - font-size: ${(p) => p.$fontSize || '0.9rem'}; + color: ${p => p.theme.cardSubtitleColor}; + font-size: ${p => p.$fontSize || '0.9rem'}; `; export const CardTitleAnchor = styled.a` @@ -291,7 +289,7 @@ export const TimelineContentDetails = styled.p<{ theme?: Theme }>` font-weight: 400; margin: 0; width: 100%; - color: ${(p) => p.theme.cardDetailsColor}; + color: ${p => p.theme.cardDetailsColor}; line-height: 1.5; `; @@ -301,8 +299,8 @@ export const TimelineSubContent = styled.span<{ }>` margin-bottom: 0.5rem; display: block; - font-size: ${(p) => p.fontSize && '0.8rem'}; - color: ${(p) => p.theme.cardDetailsColor}; + font-size: ${p => p.fontSize && '0.8rem'}; + color: ${p => p.theme.cardDetailsColor}; `; export const TimelineContentDetailsWrapper = styled.div<{ @@ -327,11 +325,11 @@ export const TimelineContentDetailsWrapper = styled.div<{ overflow-x: hidden; overflow-y: auto; transition: max-height 0.25s ease-in-out; - width: ${(p) => (p.$borderLess ? 'calc(100% - 0.5rem)' : '100%')}; + width: ${p => (p.$borderLess ? 'calc(100% - 0.5rem)' : '100%')}; padding: 0; - background: ${(p) => p.theme?.cardDetailsBackGround || p.theme?.cardBgColor}; + background: ${p => p.theme?.cardDetailsBackGround || p.theme?.cardBgColor}; - // Height handling based on different conditions + /* Height handling based on different conditions */ ${({ $useReadMore, $customContent, $showMore, height = 0, $textOverlay }) => $useReadMore && !$customContent && !$showMore && !$textOverlay ? `max-height: ${height}px;` @@ -348,9 +346,9 @@ export const TimelineContentDetailsWrapper = styled.div<{ ? `max-height: ${($cardHeight ?? 0) + ($contentHeight ?? 0) - height}px;` : ''} - ${(p) => (p.$customContent ? `height: 100%;` : '')} + ${p => (p.$customContent ? `height: 100%;` : '')} - // Animation for show more + /* Animation for show more */ ${({ height = 0, $cardHeight = 0, @@ -379,8 +377,8 @@ export const TimelineContentDetailsWrapper = styled.div<{ overflow: hidden; } - // Gradient for "show more" functionality - --rc-gradient-color: ${(p) => p.$gradientColor}; + /* Gradient for "show more" functionality */ + --rc-gradient-color: ${p => p.$gradientColor}; ${linearGradient} `; @@ -393,12 +391,12 @@ export const ShowMore = styled.button<{ align-self: flex-end; border-radius: 4px; cursor: pointer; - display: ${(p) => (p.show === 'true' ? 'flex' : 'none')}; + display: ${p => (p.show === 'true' ? 'flex' : 'none')}; font-size: 0.75rem; justify-self: flex-end; margin: auto 0.5em 0.5em auto; padding: 0.25em; - color: ${(p) => p.theme.primary}; + color: ${p => p.theme.primary}; border: 0; background: none; @@ -413,7 +411,7 @@ export const SlideShowProgressBar = styled.progress<{ $resuming?: boolean; $startWidth?: number; }>` - background: ${(p) => p.color}; + background: ${p => p.color}; bottom: -0.75em; display: block; height: 4px; @@ -431,17 +429,17 @@ export const SlideShowProgressBar = styled.progress<{ } &::-webkit-progress-value { - background-color: ${(p) => p.color || '#007bff'}; + background-color: ${p => p.color || '#007bff'}; border-radius: 2px; } &::-moz-progress-bar { - background-color: ${(p) => p.color || '#007bff'}; + background-color: ${p => p.color || '#007bff'}; border-radius: 2px; } - // Animation control - simplified without pause - ${(p) => { + /* Animation control - simplified without pause */ + ${p => { if (p.$startWidth && p.$startWidth > 0) { return css` animation: ${slideAnimation(p.$startWidth, 0)} ${p.$duration}ms ease-in; @@ -471,7 +469,7 @@ export const ChevronIconWrapper = styled.span<{ collapsed?: 'true' | 'false' }>` margin-left: 0.2em; margin-top: 0.2em; width: 1.25em; - transform: ${(p) => + transform: ${p => p.collapsed === 'false' ? 'rotate(90deg)' : 'rotate(-90deg)'}; svg { @@ -492,11 +490,10 @@ export const TriangleIconWrapper = styled.span<{ height: 1.5rem; position: absolute; top: calc(50%); - background: ${(p) => p.theme.cardBgColor}; + background: ${p => p.theme.cardBgColor}; transform: translateY(-50%) rotate(225deg); z-index: ${zIndex.timelineCard - 3}; /* Arrow tip should be below the card */ - ${(p) => - p.dir === 'left' ? `right: ${p.offset}px;` : `left: ${p.offset}px;`} + ${p => (p.dir === 'left' ? `right: ${p.offset}px;` : `left: ${p.offset}px;`)} & svg { width: 100%; @@ -507,7 +504,7 @@ export const TriangleIconWrapper = styled.span<{ // Search highlighting export const Mark = styled.mark<{ theme: Theme }>` - background-color: ${(p) => + background-color: ${p => p.theme?.searchHighlightColor || (p.theme?.primary ? `${p.theme.primary}30` : 'rgba(255, 217, 0, 0.3)')}; color: inherit; @@ -522,7 +519,7 @@ export const Mark = styled.mark<{ theme: Theme }>` box-shadow 0.15s ease-out; &[data-current-match='true'] { - background-color: ${(p) => { + background-color: ${p => { if (p.theme?.searchHighlightColor) { // If custom search highlight color is provided, make it more intense const color = p.theme.searchHighlightColor; @@ -542,7 +539,7 @@ export const Mark = styled.mark<{ theme: Theme }>` return 'rgba(255, 217, 0, 0.5)'; }}; box-shadow: 0 0 0 1px - ${(p) => { + ${p => { if (p.theme?.iconColor) { return p.theme.iconColor; } diff --git a/src/components/timeline-elements/timeline-card-content/timeline-card-content.tsx b/src/components/timeline-elements/timeline-card-content/timeline-card-content.tsx index 188f9cc5f..0a66f9ec5 100644 --- a/src/components/timeline-elements/timeline-card-content/timeline-card-content.tsx +++ b/src/components/timeline-elements/timeline-card-content/timeline-card-content.tsx @@ -332,7 +332,7 @@ const TimelineCardContent: React.FunctionComponent = const toggleShowMore = useCallback(() => { if ((active && paused) || !slideShowActive) { - setShowMore((prev) => !prev); + setShowMore(prev => !prev); onShowMore?.(); // Use setTimeout to ensure the DOM has updated before focusing setTimeout(() => { @@ -408,14 +408,14 @@ const TimelineCardContent: React.FunctionComponent = return ( should match the snapshot ( IMAGE ) 1`] = `
Image should match the snapshot ( IMAGE ) 1`] = `
This is another test @@ -41,13 +41,13 @@ exports[`Timeline Card media > should match the snapshot ( IMAGE ) 1`] = ` exports[`Timeline Card media > should match the snapshot ( VIDEO ) 1`] = `