From 0a8671653614c3e54dbfcb40cc4cb1f8f35bae80 Mon Sep 17 00:00:00 2001 From: prabhuignoto Date: Tue, 5 Mar 2024 23:57:06 +0530 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Refactor=20memoized=20timeline=20ca?= =?UTF-8?q?rd=20elements?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 6 + .../memoized/__tests__/index.test.tsx | 6 +- .../memoized/details-text-memo.tsx | 55 ++++++ .../memoized/expand-button-memo.tsx | 31 ++++ .../timeline-elements/memoized/index.tsx | 174 ------------------ .../memoized/memoized-model.ts | 56 +++--- .../memoized/show-hide-button.tsx | 29 +++ .../memoized/subtitle-memo.tsx | 26 +++ .../timeline-elements/memoized/title-memo.tsx | 42 +++++ .../timeline-card-content/content-header.tsx | 3 +- .../timeline-card-media.test.tsx.snap | 4 +- .../timeline-card-media.tsx | 12 +- .../timeline-vertical-item.test.tsx.snap | 6 +- 13 files changed, 237 insertions(+), 213 deletions(-) create mode 100644 src/components/timeline-elements/memoized/details-text-memo.tsx create mode 100644 src/components/timeline-elements/memoized/expand-button-memo.tsx delete mode 100644 src/components/timeline-elements/memoized/index.tsx create mode 100644 src/components/timeline-elements/memoized/show-hide-button.tsx create mode 100644 src/components/timeline-elements/memoized/subtitle-memo.tsx create mode 100644 src/components/timeline-elements/memoized/title-memo.tsx diff --git a/README.md b/README.md index d7e7e214..87bfbd28 100644 --- a/README.md +++ b/README.md @@ -645,6 +645,12 @@ pnpm rollup # run cypress tests pnpm cypress:test + + # run cypress tests in headless mode + pnpm cypress:headless + + # run cypress tests in quiet mode + pnpm cypress:quiet ``` ## šŸ¤Contributing diff --git a/src/components/timeline-elements/memoized/__tests__/index.test.tsx b/src/components/timeline-elements/memoized/__tests__/index.test.tsx index 144fcc79..25875f34 100644 --- a/src/components/timeline-elements/memoized/__tests__/index.test.tsx +++ b/src/components/timeline-elements/memoized/__tests__/index.test.tsx @@ -1,9 +1,11 @@ +import { forwardRef } from 'react'; import { vi } from 'vitest'; -import { DetailsTextMemo, SubTitleMemo, TitleMemo } from '../'; import { customRender } from '../../../common/test'; import { providerProps } from '../../../common/test/index'; -import { forwardRef } from 'react'; 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', () => { diff --git a/src/components/timeline-elements/memoized/details-text-memo.tsx b/src/components/timeline-elements/memoized/details-text-memo.tsx new file mode 100644 index 00000000..21bcde95 --- /dev/null +++ b/src/components/timeline-elements/memoized/details-text-memo.tsx @@ -0,0 +1,55 @@ +import { memo, useCallback, useMemo } from 'react'; +import { hexToRGBA } from '../../../utils'; +import { DetailsTextWrapper } from './../timeline-card-media/timeline-card-media.styles'; +import { DetailsTextMemoModel } from './memoized-model'; + +const DetailsTextMemo = memo( + ({ + theme, + show, + expand, + textOverlay, + text, + height, + onRender, + }: DetailsTextMemoModel) => { + const onTextRef = useCallback((node: HTMLDivElement) => { + if (node) { + onRender?.(node.clientHeight); + } + }, []); + + const Text = text; + + const background = useMemo(() => { + const bg = theme?.cardDetailsBackGround || ''; + if (bg) { + return hexToRGBA(bg, 0.8); + } else { + return bg; + } + }, [theme?.cardDetailsBackGround]); + + return textOverlay ? ( + + + + ) : null; + }, + (prev, next) => + prev.height === next.height && + prev.show === next.show && + prev.expand === next.expand && + JSON.stringify(prev.theme) === JSON.stringify(next.theme), +); + +DetailsTextMemo.displayName = 'Details Text'; + +export { DetailsTextMemo }; diff --git a/src/components/timeline-elements/memoized/expand-button-memo.tsx b/src/components/timeline-elements/memoized/expand-button-memo.tsx new file mode 100644 index 00000000..97a09ba2 --- /dev/null +++ b/src/components/timeline-elements/memoized/expand-button-memo.tsx @@ -0,0 +1,31 @@ +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'; + +const ExpandButtonMemo = memo( + ({ theme, expanded, onExpand, textOverlay }: ExpandButtonModel) => { + const label = useMemo(() => { + return expanded ? 'Minimize' : 'Maximize'; + }, [expanded]); + + return textOverlay ? ( + ev.key === 'Enter' && onExpand?.(ev)} + theme={theme} + aria-expanded={expanded} + tabIndex={0} + aria-label={label} + title={label} + > + {expanded ? : } + + ) : null; + }, + (prev, next) => prev.expanded === next.expanded, +); + +ExpandButtonMemo.displayName = 'Expand Button'; + +export { ExpandButtonMemo }; diff --git a/src/components/timeline-elements/memoized/index.tsx b/src/components/timeline-elements/memoized/index.tsx deleted file mode 100644 index b333f1df..00000000 --- a/src/components/timeline-elements/memoized/index.tsx +++ /dev/null @@ -1,174 +0,0 @@ -import cls from 'classnames'; -import React, { memo, useCallback, useMemo } from 'react'; -import { hexToRGBA } from '../../../utils'; -import { MaximizeIcon, MinimizeIcon, MinusIcon, PlusIcon } from '../../icons'; -import { - CardSubTitle, - CardTitle, - CardTitleAnchor, -} from '../timeline-card-content/timeline-card-content.styles'; -import { - ExpandButton, - ShowHideTextButton, -} from '../timeline-card-media/timeline-card-media-buttons'; -import { DetailsTextWrapper } from './../timeline-card-media/timeline-card-media.styles'; -import { - Content, - DetailsTextMemoModel, - ExpandButtonModel, - ShowHideTextButtonModel, - Title, -} from './memoized-model'; - -const TitleMemo = ({ - title, - url, - theme, - color, - dir, - active, - fontSize = '1rem', - classString = '', - padding = false, -}: Title) => { - return title ? ( - - {url ? ( - - {title} - - ) : ( - title - )} - - ) : null; -}; - -TitleMemo.displayName = 'Timeline Title'; - -const SubTitleMemo = React.memo( - ({ content, color, dir, theme, fontSize, classString, padding }: Content) => - content ? ( - - {content} - - ) : null, - (prev, next) => - prev.theme?.cardSubtitleColor === next.theme?.cardSubtitleColor, -); - -SubTitleMemo.displayName = 'Timeline Content'; - -export const ExpandButtonMemo = memo( - ({ theme, expanded, onExpand, textOverlay }: ExpandButtonModel) => { - const label = useMemo(() => { - return expanded ? 'Minimize' : 'Maximize'; - }, [expanded]); - - return textOverlay ? ( - ev.key === 'Enter' && onExpand?.(ev)} - theme={theme} - aria-expanded={expanded} - tabIndex={0} - aria-label={label} - title={label} - > - {expanded ? : } - - ) : null; - }, - (prev, next) => prev.expanded === next.expanded, -); - -ExpandButtonMemo.displayName = 'Expand Button'; - -export const ShowOrHideTextButtonMemo = memo( - ({ textOverlay, onToggle, theme, show }: ShowHideTextButtonModel) => { - const label = useMemo(() => { - return show ? 'Hide Text' : 'Show Text'; - }, [show]); - - return textOverlay ? ( - ev.key === 'Enter' && onToggle?.(ev)} - aria-label={label} - title={label} - > - {show ? : } - - ) : null; - }, -); - -ShowOrHideTextButtonMemo.displayName = 'Show Hide Text Button'; - -const DetailsTextMemo = memo( - ({ - theme, - show, - expand, - textOverlay, - text, - height, - onRender, - }: DetailsTextMemoModel) => { - const onTextRef = useCallback((node: HTMLDivElement) => { - if (node) { - onRender?.(node.clientHeight); - } - }, []); - - const Text = text; - - const background = useMemo(() => { - const bg = theme?.cardDetailsBackGround || ''; - if (bg) { - return hexToRGBA(bg, 0.8); - } else { - return bg; - } - }, [theme?.cardDetailsBackGround]); - - return textOverlay ? ( - - - - ) : null; - }, - (prev, next) => - prev.height === next.height && - prev.show === next.show && - prev.expand === next.expand && - JSON.stringify(prev.theme) === JSON.stringify(next.theme), -); - -DetailsTextMemo.displayName = 'Details Text'; - -export { TitleMemo, SubTitleMemo, DetailsTextMemo }; diff --git a/src/components/timeline-elements/memoized/memoized-model.ts b/src/components/timeline-elements/memoized/memoized-model.ts index 2b0f491e..80d54bc1 100644 --- a/src/components/timeline-elements/memoized/memoized-model.ts +++ b/src/components/timeline-elements/memoized/memoized-model.ts @@ -2,52 +2,60 @@ import { Theme } from '@models/Theme'; import React, { ForwardRefExoticComponent, ReactNode } from 'react'; import { TextOrContentModel } from '../timeline-card-content/text-or-content'; +// Common properties shared by multiple interfaces type common = { - classString?: string; - color?: string; - dir?: string; - fontSize?: string; - padding?: boolean; - theme?: Theme; + 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; - padding?: boolean; - title?: string; - url?: string; + active?: boolean; // Whether the title is active + padding?: boolean; // Whether to apply padding + title?: string; // Title text + url?: string; // URL for the title } +// Interface for the Content component export interface Content extends common { - content?: string | ReactNode; + content?: string | ReactNode; // Content text or ReactNode } +// Type for the ExpandButtonModel export type ExpandButtonModel = { - expanded?: boolean; - onExpand?: (ev: React.PointerEvent | React.KeyboardEvent) => void; - textOverlay?: boolean; + 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; +// Type for the ShowHideTextButtonModel export type ShowHideTextButtonModel = { - onToggle: (ev: React.PointerEvent | React.KeyboardEvent) => void; - show?: boolean; - textOverlay?: boolean; + 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; +// Type for the DetailsTextMemoModel export type DetailsTextMemoModel = { - expand?: boolean; - height?: number; - onRender?: (height?: number) => void; - show?: boolean; - text: ForwardRefExoticComponent; - textOverlay?: boolean; - theme?: Theme; + expand?: boolean; // Whether to expand the details text + height?: number; // Height of the details text + onRender?: (height?: number) => void; // Callback function for rendering the details text + show?: boolean; // Whether to show the details text + text: ForwardRefExoticComponent; // Text component for the details text + textOverlay?: boolean; // Whether to overlay text on the details text + theme?: Theme; // Theme object }; +// Type for the TextContentMemoModel export type TextContentMemoModel = Title & Content & ExpandButtonModel & ShowHideTextButtonModel & DetailsTextMemoModel; +// Type for the CardMediaHeaderMemoModel export type CardMediaHeaderMemoModel = Title & Content; diff --git a/src/components/timeline-elements/memoized/show-hide-button.tsx b/src/components/timeline-elements/memoized/show-hide-button.tsx new file mode 100644 index 00000000..3beb3fd8 --- /dev/null +++ b/src/components/timeline-elements/memoized/show-hide-button.tsx @@ -0,0 +1,29 @@ +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'; + +const ShowOrHideTextButtonMemo = memo( + ({ textOverlay, onToggle, theme, show }: ShowHideTextButtonModel) => { + const label = useMemo(() => { + return show ? 'Hide Text' : 'Show Text'; + }, [show]); + + return textOverlay ? ( + ev.key === 'Enter' && onToggle?.(ev)} + aria-label={label} + title={label} + > + {show ? : } + + ) : null; + }, +); + +ShowOrHideTextButtonMemo.displayName = 'Show Hide Text Button'; + +export { ShowOrHideTextButtonMemo }; diff --git a/src/components/timeline-elements/memoized/subtitle-memo.tsx b/src/components/timeline-elements/memoized/subtitle-memo.tsx new file mode 100644 index 00000000..2d5cf465 --- /dev/null +++ b/src/components/timeline-elements/memoized/subtitle-memo.tsx @@ -0,0 +1,26 @@ +import cls from 'classnames'; +import React from 'react'; +import { CardSubTitle } from '../timeline-card-content/timeline-card-content.styles'; +import { Content } from './memoized-model'; + +const SubTitleMemo = React.memo( + ({ content, color, dir, theme, fontSize, classString, padding }: Content) => + content ? ( + + {content} + + ) : null, + (prev, next) => + prev.theme?.cardSubtitleColor === next.theme?.cardSubtitleColor, +); + +SubTitleMemo.displayName = 'Timeline Content'; + +export { SubTitleMemo }; diff --git a/src/components/timeline-elements/memoized/title-memo.tsx b/src/components/timeline-elements/memoized/title-memo.tsx new file mode 100644 index 00000000..be0a33e1 --- /dev/null +++ b/src/components/timeline-elements/memoized/title-memo.tsx @@ -0,0 +1,42 @@ +import cls from 'classnames'; +import { + CardTitle, + CardTitleAnchor, +} from '../timeline-card-content/timeline-card-content.styles'; +import { Title } from './memoized-model'; + +const TitleMemo = ({ + title, + url, + theme, + color, + dir, + active, + fontSize = '1rem', + classString = '', + padding = false, +}: Title) => { + return title ? ( + + {url ? ( + + {title} + + ) : ( + title + )} + + ) : null; +}; + +TitleMemo.displayName = 'Timeline Title'; + +export { TitleMemo }; diff --git a/src/components/timeline-elements/timeline-card-content/content-header.tsx b/src/components/timeline-elements/timeline-card-content/content-header.tsx index 81d737c3..f10a010e 100644 --- a/src/components/timeline-elements/timeline-card-content/content-header.tsx +++ b/src/components/timeline-elements/timeline-card-content/content-header.tsx @@ -1,6 +1,7 @@ import { FunctionComponent, memo, useContext, useMemo } from 'react'; import { GlobalContext } from '../../GlobalContext'; -import { SubTitleMemo, TitleMemo } from '../memoized'; +import { SubTitleMemo } from '../memoized/subtitle-memo'; +import { TitleMemo } from '../memoized/title-memo'; import { ContentHeaderProps } from './header-footer.model'; import { CardTitle, TimelineCardHeader } from './timeline-card-content.styles'; diff --git a/src/components/timeline-elements/timeline-card-media/__tests__/__snapshots__/timeline-card-media.test.tsx.snap b/src/components/timeline-elements/timeline-card-media/__tests__/__snapshots__/timeline-card-media.test.tsx.snap index 4b11ee1c..e2829e01 100644 --- a/src/components/timeline-elements/timeline-card-media/__tests__/__snapshots__/timeline-card-media.test.tsx.snap +++ b/src/components/timeline-elements/timeline-card-media/__tests__/__snapshots__/timeline-card-media.test.tsx.snap @@ -28,7 +28,7 @@ exports[`Timeline Card media > should match the snapshot ( IMAGE ) 1`] = ` class="sc-iBdnpw bYRNiQ" />

This is another test

@@ -60,7 +60,7 @@ exports[`Timeline Card media > should match the snapshot ( VIDEO ) 1`] = ` class="sc-iBdnpw bYRNiQ" />

This is another test

diff --git a/src/components/timeline-elements/timeline-card-media/timeline-card-media.tsx b/src/components/timeline-elements/timeline-card-media/timeline-card-media.tsx index f71d03ca..3e72bd70 100644 --- a/src/components/timeline-elements/timeline-card-media/timeline-card-media.tsx +++ b/src/components/timeline-elements/timeline-card-media/timeline-card-media.tsx @@ -12,13 +12,11 @@ import React, { useState, } from 'react'; import { GlobalContext } from '../../GlobalContext'; -import { - DetailsTextMemo, - ExpandButtonMemo, - ShowOrHideTextButtonMemo, - SubTitleMemo, - TitleMemo, -} from '../memoized'; +import { DetailsTextMemo } from '../memoized/details-text-memo'; +import { ExpandButtonMemo } from '../memoized/expand-button-memo'; +import { ShowOrHideTextButtonMemo } from '../memoized/show-hide-button'; +import { SubTitleMemo } from '../memoized/subtitle-memo'; +import { TitleMemo } from '../memoized/title-memo'; import { SlideShowProgressBar, TriangleIconWrapper, diff --git a/src/components/timeline-vertical/__tests__/__snapshots__/timeline-vertical-item.test.tsx.snap b/src/components/timeline-vertical/__tests__/__snapshots__/timeline-vertical-item.test.tsx.snap index 05967d50..6f4a12ed 100644 --- a/src/components/timeline-vertical/__tests__/__snapshots__/timeline-vertical-item.test.tsx.snap +++ b/src/components/timeline-vertical/__tests__/__snapshots__/timeline-vertical-item.test.tsx.snap @@ -22,7 +22,7 @@ exports[`Timeline vertical item > Should match snapshot 1`] = ` class="sc-kFCroH kDetXN card-content-wrapper" >
Should match snapshot 1`] = `